Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a42ef80a39 |
No files matched your search
@@ -64,6 +64,7 @@
|
|||||||
442E26DB1F7DA80AF794CCB6 /* Pods_unit_tests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C7E6F409CA442F83B7BE71AD /* Pods_unit_tests.framework */; };
|
442E26DB1F7DA80AF794CCB6 /* Pods_unit_tests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C7E6F409CA442F83B7BE71AD /* Pods_unit_tests.framework */; };
|
||||||
4807A6C623A9CD190052A53E /* SkyLight.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4807A6C523A9CD190052A53E /* SkyLight.framework */; };
|
4807A6C623A9CD190052A53E /* SkyLight.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4807A6C523A9CD190052A53E /* SkyLight.framework */; };
|
||||||
48F3E16224EC0D8800A1C64B /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = D04BABDA79F8EF76E3ACDD5F /* Localizable.strings */; };
|
48F3E16224EC0D8800A1C64B /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = D04BABDA79F8EF76E3ACDD5F /* Localizable.strings */; };
|
||||||
|
5883F0A829A5182C0071DB65 /* TrackpadEvents.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5883F0A729A5182C0071DB65 /* TrackpadEvents.swift */; };
|
||||||
5F21C9E02C6E94240091F72F /* ShortcutsWhenActiveSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F21C9DF2C6E94240091F72F /* ShortcutsWhenActiveSheet.swift */; };
|
5F21C9E02C6E94240091F72F /* ShortcutsWhenActiveSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F21C9DF2C6E94240091F72F /* ShortcutsWhenActiveSheet.swift */; };
|
||||||
5F21C9E22C6E94410091F72F /* AdditionalControlsSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F21C9E12C6E94410091F72F /* AdditionalControlsSheet.swift */; };
|
5F21C9E22C6E94410091F72F /* AdditionalControlsSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F21C9E12C6E94410091F72F /* AdditionalControlsSheet.swift */; };
|
||||||
5F21C9E42C6E94700091F72F /* CustomizeStyleSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F21C9E32C6E94700091F72F /* CustomizeStyleSheet.swift */; };
|
5F21C9E42C6E94700091F72F /* CustomizeStyleSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F21C9E32C6E94700091F72F /* CustomizeStyleSheet.swift */; };
|
||||||
@@ -324,6 +325,7 @@
|
|||||||
1C961FB3DCF4906FEEF4A23D /* TableGroupView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TableGroupView.swift; sourceTree = "<group>"; };
|
1C961FB3DCF4906FEEF4A23D /* TableGroupView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TableGroupView.swift; sourceTree = "<group>"; };
|
||||||
4807A6C523A9CD190052A53E /* SkyLight.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SkyLight.framework; path = ../../../../System/Library/PrivateFrameworks/SkyLight.framework; sourceTree = "<group>"; };
|
4807A6C523A9CD190052A53E /* SkyLight.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SkyLight.framework; path = ../../../../System/Library/PrivateFrameworks/SkyLight.framework; sourceTree = "<group>"; };
|
||||||
481FE54624D2D387001032F1 /* alt-tab-macos-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "alt-tab-macos-Bridging-Header.h"; sourceTree = "<group>"; };
|
481FE54624D2D387001032F1 /* alt-tab-macos-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "alt-tab-macos-Bridging-Header.h"; sourceTree = "<group>"; };
|
||||||
|
5883F0A729A5182C0071DB65 /* TrackpadEvents.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrackpadEvents.swift; sourceTree = "<group>"; };
|
||||||
59DD4BE63D42EEFF1182BA7F /* Pods-alt-tab-macos.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-alt-tab-macos.release.xcconfig"; path = "Target Support Files/Pods-alt-tab-macos/Pods-alt-tab-macos.release.xcconfig"; sourceTree = "<group>"; };
|
59DD4BE63D42EEFF1182BA7F /* Pods-alt-tab-macos.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-alt-tab-macos.release.xcconfig"; path = "Target Support Files/Pods-alt-tab-macos/Pods-alt-tab-macos.release.xcconfig"; sourceTree = "<group>"; };
|
||||||
5F21C9DF2C6E94240091F72F /* ShortcutsWhenActiveSheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShortcutsWhenActiveSheet.swift; sourceTree = "<group>"; };
|
5F21C9DF2C6E94240091F72F /* ShortcutsWhenActiveSheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShortcutsWhenActiveSheet.swift; sourceTree = "<group>"; };
|
||||||
5F21C9E12C6E94410091F72F /* AdditionalControlsSheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdditionalControlsSheet.swift; sourceTree = "<group>"; };
|
5F21C9E12C6E94410091F72F /* AdditionalControlsSheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdditionalControlsSheet.swift; sourceTree = "<group>"; };
|
||||||
@@ -1709,6 +1711,7 @@
|
|||||||
D04BA76AEE37D6656EB80126 /* RunningApplicationsEvents.swift */,
|
D04BA76AEE37D6656EB80126 /* RunningApplicationsEvents.swift */,
|
||||||
D04BA5D9B4EBEB9E4333AE39 /* UserDefaultsEvents.swift */,
|
D04BA5D9B4EBEB9E4333AE39 /* UserDefaultsEvents.swift */,
|
||||||
D04BAF320F4D43F0DDFE063E /* MouseEvents.swift */,
|
D04BAF320F4D43F0DDFE063E /* MouseEvents.swift */,
|
||||||
|
5883F0A729A5182C0071DB65 /* TrackpadEvents.swift */,
|
||||||
BF0C870C14C20C936BA4AF40 /* DockEvents.swift */,
|
BF0C870C14C20C936BA4AF40 /* DockEvents.swift */,
|
||||||
BF0C8DF008F1EB5F23291A13 /* SpacesEvents.swift */,
|
BF0C8DF008F1EB5F23291A13 /* SpacesEvents.swift */,
|
||||||
BF0C822D3BEDAB1F1C9F775E /* ScreensEvents.swift */,
|
BF0C822D3BEDAB1F1C9F775E /* ScreensEvents.swift */,
|
||||||
@@ -2226,6 +2229,7 @@
|
|||||||
D04BA8757C9F20F25EB50785 /* TextField.swift in Sources */,
|
D04BA8757C9F20F25EB50785 /* TextField.swift in Sources */,
|
||||||
5F21C9E02C6E94240091F72F /* ShortcutsWhenActiveSheet.swift in Sources */,
|
5F21C9E02C6E94240091F72F /* ShortcutsWhenActiveSheet.swift in Sources */,
|
||||||
D04BAE8B16A06A10E2FA94DE /* AccessibilityEvents.swift in Sources */,
|
D04BAE8B16A06A10E2FA94DE /* AccessibilityEvents.swift in Sources */,
|
||||||
|
5883F0A829A5182C0071DB65 /* TrackpadEvents.swift in Sources */,
|
||||||
D04BAAAF5CFA991D3B078DB8 /* KeyboardEvents.swift in Sources */,
|
D04BAAAF5CFA991D3B078DB8 /* KeyboardEvents.swift in Sources */,
|
||||||
D04BA1766FBCB2E941D081A5 /* RunningApplicationsEvents.swift in Sources */,
|
D04BA1766FBCB2E941D081A5 /* RunningApplicationsEvents.swift in Sources */,
|
||||||
D04BA0AE9865276FF8EF5DEB /* UserDefaultsEvents.swift in Sources */,
|
D04BA0AE9865276FF8EF5DEB /* UserDefaultsEvents.swift in Sources */,
|
||||||
|
|||||||
@@ -166,6 +166,9 @@
|
|||||||
/* No comment provided by engineer. */
|
/* No comment provided by engineer. */
|
||||||
"Dark" = "Dark";
|
"Dark" = "Dark";
|
||||||
|
|
||||||
|
/* No comment provided by engineer. */
|
||||||
|
"Disabled" = "Disabled";
|
||||||
|
|
||||||
/* No comment provided by engineer. */
|
/* No comment provided by engineer. */
|
||||||
"Do nothing" = "Do nothing";
|
"Do nothing" = "Do nothing";
|
||||||
|
|
||||||
@@ -193,6 +196,9 @@
|
|||||||
/* No comment provided by engineer. */
|
/* No comment provided by engineer. */
|
||||||
"General" = "General";
|
"General" = "General";
|
||||||
|
|
||||||
|
/* No comment provided by engineer. */
|
||||||
|
"Gesture" = "Gesture";
|
||||||
|
|
||||||
/* Menubar callout button */
|
/* Menubar callout button */
|
||||||
"Grant permission" = "Grant permission";
|
"Grant permission" = "Grant permission";
|
||||||
|
|
||||||
@@ -289,6 +295,9 @@
|
|||||||
/* No comment provided by engineer. */
|
/* No comment provided by engineer. */
|
||||||
"Open Screen Recording Preferences…" = "Open Screen Recording Preferences…";
|
"Open Screen Recording Preferences…" = "Open Screen Recording Preferences…";
|
||||||
|
|
||||||
|
/* No comment provided by engineer. */
|
||||||
|
"Open Trackpad Preferences…" = "Open Trackpad Preferences…";
|
||||||
|
|
||||||
/* No comment provided by engineer. */
|
/* No comment provided by engineer. */
|
||||||
"Optional: email (if you want a reply)" = "Optional: email (if you want a reply)";
|
"Optional: email (if you want a reply)" = "Optional: email (if you want a reply)";
|
||||||
|
|
||||||
@@ -475,6 +484,15 @@
|
|||||||
/* Menubar option */
|
/* Menubar option */
|
||||||
"Support this project ❤️" = "Support this project ❤️";
|
"Support this project ❤️" = "Support this project ❤️";
|
||||||
|
|
||||||
|
/* No comment provided by engineer. */
|
||||||
|
"Swipe may conflict with system shortcuts" = "Swipe may conflict with system shortcuts";
|
||||||
|
|
||||||
|
/* No comment provided by engineer. */
|
||||||
|
"Swipe with Four Fingers" = "Swipe with Four Fingers";
|
||||||
|
|
||||||
|
/* No comment provided by engineer. */
|
||||||
|
"Swipe with Three Fingers" = "Swipe with Three Fingers";
|
||||||
|
|
||||||
/* No comment provided by engineer. */
|
/* No comment provided by engineer. */
|
||||||
"Switch between 3 different styles. You can customize them." = "Switch between 3 different styles. You can customize them.";
|
"Switch between 3 different styles. You can customize them." = "Switch between 3 different styles. You can customize them.";
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ class Preferences {
|
|||||||
"nextWindowShortcut3": "",
|
"nextWindowShortcut3": "",
|
||||||
"nextWindowShortcut4": "",
|
"nextWindowShortcut4": "",
|
||||||
"nextWindowShortcut5": "",
|
"nextWindowShortcut5": "",
|
||||||
|
"nextWindowGesture": GesturePreference.disabled.indexAsString,
|
||||||
"focusWindowShortcut": "Space",
|
"focusWindowShortcut": "Space",
|
||||||
"previousWindowShortcut": "⇧",
|
"previousWindowShortcut": "⇧",
|
||||||
"cancelShortcut": "⎋",
|
"cancelShortcut": "⎋",
|
||||||
@@ -32,21 +33,25 @@ class Preferences {
|
|||||||
"showMinimizedWindows3": ShowHowPreference.show.indexAsString,
|
"showMinimizedWindows3": ShowHowPreference.show.indexAsString,
|
||||||
"showMinimizedWindows4": ShowHowPreference.show.indexAsString,
|
"showMinimizedWindows4": ShowHowPreference.show.indexAsString,
|
||||||
"showMinimizedWindows5": ShowHowPreference.show.indexAsString,
|
"showMinimizedWindows5": ShowHowPreference.show.indexAsString,
|
||||||
|
"showMinimizedWindows6": ShowHowPreference.show.indexAsString,
|
||||||
"showHiddenWindows": ShowHowPreference.show.indexAsString,
|
"showHiddenWindows": ShowHowPreference.show.indexAsString,
|
||||||
"showHiddenWindows2": ShowHowPreference.show.indexAsString,
|
"showHiddenWindows2": ShowHowPreference.show.indexAsString,
|
||||||
"showHiddenWindows3": ShowHowPreference.show.indexAsString,
|
"showHiddenWindows3": ShowHowPreference.show.indexAsString,
|
||||||
"showHiddenWindows4": ShowHowPreference.show.indexAsString,
|
"showHiddenWindows4": ShowHowPreference.show.indexAsString,
|
||||||
"showHiddenWindows5": ShowHowPreference.show.indexAsString,
|
"showHiddenWindows5": ShowHowPreference.show.indexAsString,
|
||||||
|
"showHiddenWindows6": ShowHowPreference.show.indexAsString,
|
||||||
"showFullscreenWindows": ShowHowPreference.show.indexAsString,
|
"showFullscreenWindows": ShowHowPreference.show.indexAsString,
|
||||||
"showFullscreenWindows2": ShowHowPreference.show.indexAsString,
|
"showFullscreenWindows2": ShowHowPreference.show.indexAsString,
|
||||||
"showFullscreenWindows3": ShowHowPreference.show.indexAsString,
|
"showFullscreenWindows3": ShowHowPreference.show.indexAsString,
|
||||||
"showFullscreenWindows4": ShowHowPreference.show.indexAsString,
|
"showFullscreenWindows4": ShowHowPreference.show.indexAsString,
|
||||||
"showFullscreenWindows5": ShowHowPreference.show.indexAsString,
|
"showFullscreenWindows5": ShowHowPreference.show.indexAsString,
|
||||||
|
"showFullscreenWindows6": ShowHowPreference.show.indexAsString,
|
||||||
"windowOrder": WindowOrderPreference.recentlyFocused.indexAsString,
|
"windowOrder": WindowOrderPreference.recentlyFocused.indexAsString,
|
||||||
"windowOrder2": WindowOrderPreference.recentlyFocused.indexAsString,
|
"windowOrder2": WindowOrderPreference.recentlyFocused.indexAsString,
|
||||||
"windowOrder3": WindowOrderPreference.recentlyFocused.indexAsString,
|
"windowOrder3": WindowOrderPreference.recentlyFocused.indexAsString,
|
||||||
"windowOrder4": WindowOrderPreference.recentlyFocused.indexAsString,
|
"windowOrder4": WindowOrderPreference.recentlyFocused.indexAsString,
|
||||||
"windowOrder5": WindowOrderPreference.recentlyFocused.indexAsString,
|
"windowOrder5": WindowOrderPreference.recentlyFocused.indexAsString,
|
||||||
|
"windowOrder6": WindowOrderPreference.recentlyFocused.indexAsString,
|
||||||
"showTabsAsWindows": "false",
|
"showTabsAsWindows": "false",
|
||||||
"hideColoredCircles": "false",
|
"hideColoredCircles": "false",
|
||||||
"windowDisplayDelay": "100",
|
"windowDisplayDelay": "100",
|
||||||
@@ -65,16 +70,19 @@ class Preferences {
|
|||||||
"appsToShow3": AppsToShowPreference.all.indexAsString,
|
"appsToShow3": AppsToShowPreference.all.indexAsString,
|
||||||
"appsToShow4": AppsToShowPreference.all.indexAsString,
|
"appsToShow4": AppsToShowPreference.all.indexAsString,
|
||||||
"appsToShow5": AppsToShowPreference.all.indexAsString,
|
"appsToShow5": AppsToShowPreference.all.indexAsString,
|
||||||
|
"appsToShow6": AppsToShowPreference.all.indexAsString,
|
||||||
"spacesToShow": SpacesToShowPreference.all.indexAsString,
|
"spacesToShow": SpacesToShowPreference.all.indexAsString,
|
||||||
"spacesToShow2": SpacesToShowPreference.all.indexAsString,
|
"spacesToShow2": SpacesToShowPreference.all.indexAsString,
|
||||||
"spacesToShow3": SpacesToShowPreference.all.indexAsString,
|
"spacesToShow3": SpacesToShowPreference.all.indexAsString,
|
||||||
"spacesToShow4": SpacesToShowPreference.all.indexAsString,
|
"spacesToShow4": SpacesToShowPreference.all.indexAsString,
|
||||||
"spacesToShow5": SpacesToShowPreference.all.indexAsString,
|
"spacesToShow5": SpacesToShowPreference.all.indexAsString,
|
||||||
|
"spacesToShow6": SpacesToShowPreference.all.indexAsString,
|
||||||
"screensToShow": ScreensToShowPreference.all.indexAsString,
|
"screensToShow": ScreensToShowPreference.all.indexAsString,
|
||||||
"screensToShow2": ScreensToShowPreference.all.indexAsString,
|
"screensToShow2": ScreensToShowPreference.all.indexAsString,
|
||||||
"screensToShow3": ScreensToShowPreference.all.indexAsString,
|
"screensToShow3": ScreensToShowPreference.all.indexAsString,
|
||||||
"screensToShow4": ScreensToShowPreference.all.indexAsString,
|
"screensToShow4": ScreensToShowPreference.all.indexAsString,
|
||||||
"screensToShow5": ScreensToShowPreference.all.indexAsString,
|
"screensToShow5": ScreensToShowPreference.all.indexAsString,
|
||||||
|
"screensToShow6": ScreensToShowPreference.all.indexAsString,
|
||||||
"fadeOutAnimation": "false",
|
"fadeOutAnimation": "false",
|
||||||
"hideSpaceNumberLabels": "false",
|
"hideSpaceNumberLabels": "false",
|
||||||
"hideStatusIcons": "false",
|
"hideStatusIcons": "false",
|
||||||
@@ -90,6 +98,7 @@ class Preferences {
|
|||||||
"shortcutStyle3": ShortcutStylePreference.focusOnRelease.indexAsString,
|
"shortcutStyle3": ShortcutStylePreference.focusOnRelease.indexAsString,
|
||||||
"shortcutStyle4": ShortcutStylePreference.focusOnRelease.indexAsString,
|
"shortcutStyle4": ShortcutStylePreference.focusOnRelease.indexAsString,
|
||||||
"shortcutStyle5": ShortcutStylePreference.focusOnRelease.indexAsString,
|
"shortcutStyle5": ShortcutStylePreference.focusOnRelease.indexAsString,
|
||||||
|
"shortcutStyle6": ShortcutStylePreference.focusOnRelease.indexAsString,
|
||||||
"hideAppBadges": "false",
|
"hideAppBadges": "false",
|
||||||
"hideWindowlessApps": "false",
|
"hideWindowlessApps": "false",
|
||||||
"hideThumbnails": "false",
|
"hideThumbnails": "false",
|
||||||
@@ -106,6 +115,7 @@ class Preferences {
|
|||||||
// persisted values
|
// persisted values
|
||||||
static var holdShortcut: [String] { ["holdShortcut", "holdShortcut2", "holdShortcut3", "holdShortcut4", "holdShortcut5"].map { UserDefaults.standard.string($0) } }
|
static var holdShortcut: [String] { ["holdShortcut", "holdShortcut2", "holdShortcut3", "holdShortcut4", "holdShortcut5"].map { UserDefaults.standard.string($0) } }
|
||||||
static var nextWindowShortcut: [String] { ["nextWindowShortcut", "nextWindowShortcut2", "nextWindowShortcut3", "nextWindowShortcut4", "nextWindowShortcut5"].map { UserDefaults.standard.string($0) } }
|
static var nextWindowShortcut: [String] { ["nextWindowShortcut", "nextWindowShortcut2", "nextWindowShortcut3", "nextWindowShortcut4", "nextWindowShortcut5"].map { UserDefaults.standard.string($0) } }
|
||||||
|
static var nextWindowGesture: GesturePreference { UserDefaults.standard.macroPref("nextWindowGesture", GesturePreference.allCases) }
|
||||||
static var focusWindowShortcut: String { UserDefaults.standard.string("focusWindowShortcut") }
|
static var focusWindowShortcut: String { UserDefaults.standard.string("focusWindowShortcut") }
|
||||||
static var previousWindowShortcut: String { UserDefaults.standard.string("previousWindowShortcut") }
|
static var previousWindowShortcut: String { UserDefaults.standard.string("previousWindowShortcut") }
|
||||||
static var cancelShortcut: String { UserDefaults.standard.string("cancelShortcut") }
|
static var cancelShortcut: String { UserDefaults.standard.string("cancelShortcut") }
|
||||||
@@ -148,14 +158,14 @@ class Preferences {
|
|||||||
static var showTitles: ShowTitlesPreference { UserDefaults.standard.macroPref("showTitles", ShowTitlesPreference.allCases) }
|
static var showTitles: ShowTitlesPreference { UserDefaults.standard.macroPref("showTitles", ShowTitlesPreference.allCases) }
|
||||||
static var updatePolicy: UpdatePolicyPreference { UserDefaults.standard.macroPref("updatePolicy", UpdatePolicyPreference.allCases) }
|
static var updatePolicy: UpdatePolicyPreference { UserDefaults.standard.macroPref("updatePolicy", UpdatePolicyPreference.allCases) }
|
||||||
static var crashPolicy: CrashPolicyPreference { UserDefaults.standard.macroPref("crashPolicy", CrashPolicyPreference.allCases) }
|
static var crashPolicy: CrashPolicyPreference { UserDefaults.standard.macroPref("crashPolicy", CrashPolicyPreference.allCases) }
|
||||||
static var appsToShow: [AppsToShowPreference] { ["appsToShow", "appsToShow2", "appsToShow3", "appsToShow4", "appsToShow5"].map { UserDefaults.standard.macroPref($0, AppsToShowPreference.allCases) } }
|
static var appsToShow: [AppsToShowPreference] { ["appsToShow", "appsToShow2", "appsToShow3", "appsToShow4", "appsToShow5", "appsToShow6"].map { UserDefaults.standard.macroPref($0, AppsToShowPreference.allCases) } }
|
||||||
static var spacesToShow: [SpacesToShowPreference] { ["spacesToShow", "spacesToShow2", "spacesToShow3", "spacesToShow4", "spacesToShow5"].map { UserDefaults.standard.macroPref($0, SpacesToShowPreference.allCases) } }
|
static var spacesToShow: [SpacesToShowPreference] { ["spacesToShow", "spacesToShow2", "spacesToShow3", "spacesToShow4", "spacesToShow5", "spacesToShow6"].map { UserDefaults.standard.macroPref($0, SpacesToShowPreference.allCases) } }
|
||||||
static var screensToShow: [ScreensToShowPreference] { ["screensToShow", "screensToShow2", "screensToShow3", "screensToShow4", "screensToShow5"].map { UserDefaults.standard.macroPref($0, ScreensToShowPreference.allCases) } }
|
static var screensToShow: [ScreensToShowPreference] { ["screensToShow", "screensToShow2", "screensToShow3", "screensToShow4", "screensToShow5", "screensToShow6"].map { UserDefaults.standard.macroPref($0, ScreensToShowPreference.allCases) } }
|
||||||
static var showMinimizedWindows: [ShowHowPreference] { ["showMinimizedWindows", "showMinimizedWindows2", "showMinimizedWindows3", "showMinimizedWindows4", "showMinimizedWindows5"].map { UserDefaults.standard.macroPref($0, ShowHowPreference.allCases) } }
|
static var showMinimizedWindows: [ShowHowPreference] { ["showMinimizedWindows", "showMinimizedWindows2", "showMinimizedWindows3", "showMinimizedWindows4", "showMinimizedWindows5", "showMinimizedWindows6"].map { UserDefaults.standard.macroPref($0, ShowHowPreference.allCases) } }
|
||||||
static var showHiddenWindows: [ShowHowPreference] { ["showHiddenWindows", "showHiddenWindows2", "showHiddenWindows3", "showHiddenWindows4", "showHiddenWindows5"].map { UserDefaults.standard.macroPref($0, ShowHowPreference.allCases) } }
|
static var showHiddenWindows: [ShowHowPreference] { ["showHiddenWindows", "showHiddenWindows2", "showHiddenWindows3", "showHiddenWindows4", "showHiddenWindows5", "showHiddenWindows6"].map { UserDefaults.standard.macroPref($0, ShowHowPreference.allCases) } }
|
||||||
static var showFullscreenWindows: [ShowHowPreference] { ["showFullscreenWindows", "showFullscreenWindows2", "showFullscreenWindows3", "showFullscreenWindows4", "showFullscreenWindows5"].map { UserDefaults.standard.macroPref($0, ShowHowPreference.allCases) } }
|
static var showFullscreenWindows: [ShowHowPreference] { ["showFullscreenWindows", "showFullscreenWindows2", "showFullscreenWindows3", "showFullscreenWindows4", "showFullscreenWindows5", "showFullscreenWindows6"].map { UserDefaults.standard.macroPref($0, ShowHowPreference.allCases) } }
|
||||||
static var windowOrder: [WindowOrderPreference] { ["windowOrder", "windowOrder2", "windowOrder3", "windowOrder4", "windowOrder5"].map { UserDefaults.standard.macroPref($0, WindowOrderPreference.allCases) } }
|
static var windowOrder: [WindowOrderPreference] { ["windowOrder", "windowOrder2", "windowOrder3", "windowOrder4", "windowOrder5", "windowOrder6"].map { UserDefaults.standard.macroPref($0, WindowOrderPreference.allCases) } }
|
||||||
static var shortcutStyle: [ShortcutStylePreference] { ["shortcutStyle", "shortcutStyle2", "shortcutStyle3", "shortcutStyle4", "shortcutStyle5"].map { UserDefaults.standard.macroPref($0, ShortcutStylePreference.allCases) } }
|
static var shortcutStyle: [ShortcutStylePreference] { ["shortcutStyle", "shortcutStyle2", "shortcutStyle3", "shortcutStyle4", "shortcutStyle5", "shortcutStyle6"].map { UserDefaults.standard.macroPref($0, ShortcutStylePreference.allCases) } }
|
||||||
static var menubarIcon: MenubarIconPreference { UserDefaults.standard.macroPref("menubarIcon", MenubarIconPreference.allCases) }
|
static var menubarIcon: MenubarIconPreference { UserDefaults.standard.macroPref("menubarIcon", MenubarIconPreference.allCases) }
|
||||||
static var menubarIconShown: Bool { UserDefaults.standard.bool("menubarIconShown") }
|
static var menubarIconShown: Bool { UserDefaults.standard.bool("menubarIconShown") }
|
||||||
static var language: LanguagePreference { UserDefaults.standard.macroPref("language", LanguagePreference.allCases) }
|
static var language: LanguagePreference { UserDefaults.standard.macroPref("language", LanguagePreference.allCases) }
|
||||||
@@ -512,6 +522,20 @@ enum MenubarIconPreference: CaseIterable, MacroPreference {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum GesturePreference: CaseIterable, MacroPreference {
|
||||||
|
case disabled
|
||||||
|
case threeFingerSwipe
|
||||||
|
case fourFingerSwipe
|
||||||
|
|
||||||
|
var localizedString: LocalizedString {
|
||||||
|
switch self {
|
||||||
|
case .disabled: return NSLocalizedString("Disabled", comment: "")
|
||||||
|
case .threeFingerSwipe: return NSLocalizedString("Swipe with Three Fingers", comment: "")
|
||||||
|
case .fourFingerSwipe: return NSLocalizedString("Swipe with Four Fingers", comment: "")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
enum LanguagePreference: CaseIterable, MacroPreference {
|
enum LanguagePreference: CaseIterable, MacroPreference {
|
||||||
case systemDefault
|
case systemDefault
|
||||||
case indonesian
|
case indonesian
|
||||||
|
|||||||
@@ -182,10 +182,10 @@ class Windows {
|
|||||||
return list.count > focusedWindowIndex ? list[focusedWindowIndex] : nil
|
return list.count > focusedWindowIndex ? list[focusedWindowIndex] : nil
|
||||||
}
|
}
|
||||||
|
|
||||||
static func cycleFocusedWindowIndex(_ step: Int) {
|
static func cycleFocusedWindowIndex(_ step: Int, allowWrap: Bool = true) {
|
||||||
let nextIndex = windowIndexAfterCycling(step)
|
let nextIndex = windowIndexAfterCycling(step)
|
||||||
if ((step > 0 && nextIndex < focusedWindowIndex) || (step < 0 && nextIndex > focusedWindowIndex)) &&
|
if ((step > 0 && nextIndex < focusedWindowIndex) || (step < 0 && nextIndex > focusedWindowIndex)) &&
|
||||||
(ATShortcut.lastEventIsARepeat || KeyRepeatTimer.timer?.isValid ?? false) {
|
(!allowWrap || ATShortcut.lastEventIsARepeat || KeyRepeatTimer.timer?.isValid ?? false) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
updateFocusedAndHoveredWindowIndex(nextIndex)
|
updateFocusedAndHoveredWindowIndex(nextIndex)
|
||||||
|
|||||||
@@ -0,0 +1,168 @@
|
|||||||
|
import Cocoa
|
||||||
|
|
||||||
|
fileprivate var eventTap: CFMachPort!
|
||||||
|
fileprivate var shouldBeEnabled: Bool!
|
||||||
|
|
||||||
|
//TODO: Should we add a sensitivity setting instead of these magic numbers?
|
||||||
|
fileprivate let SHOW_UI_THRESHOLD: Float = 0.003
|
||||||
|
fileprivate let CYCLE_THRESHOLD: Float = 0.04
|
||||||
|
|
||||||
|
// gesture tracking state
|
||||||
|
fileprivate var prevTouchPositions: [String: NSPoint] = [:]
|
||||||
|
fileprivate var totalDisplacement = (x: Float(0), y: Float(0))
|
||||||
|
fileprivate var extendNextXThreshold = false
|
||||||
|
|
||||||
|
//TODO: underlying content scrolls if both Mission Control and App Expose use 4-finger swipes or are off in Trackpad settings. It doesn't scroll if any of them use 3-finger swipe though.
|
||||||
|
class TrackpadEvents {
|
||||||
|
static func observe() {
|
||||||
|
observe_()
|
||||||
|
TrackpadEvents.toggle(Preferences.nextWindowGesture != .disabled)
|
||||||
|
}
|
||||||
|
|
||||||
|
static func toggle(_ enabled: Bool) {
|
||||||
|
shouldBeEnabled = enabled
|
||||||
|
if let eventTap = eventTap {
|
||||||
|
CGEvent.tapEnable(tap: eventTap, enable: enabled)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func observe_() {
|
||||||
|
// CGEvent.tapCreate returns null if ensureAccessibilityCheckboxIsChecked() didn't pass
|
||||||
|
eventTap = CGEvent.tapCreate(
|
||||||
|
tap: .cghidEventTap, // we need raw data
|
||||||
|
place: .headInsertEventTap,
|
||||||
|
options: .defaultTap,
|
||||||
|
eventsOfInterest: NSEvent.EventTypeMask.gesture.rawValue,
|
||||||
|
callback: handleEvent,
|
||||||
|
userInfo: nil)
|
||||||
|
if let eventTap = eventTap {
|
||||||
|
let runLoopSource = CFMachPortCreateRunLoopSource(nil, eventTap, 0)
|
||||||
|
CFRunLoopAddSource(BackgroundWork.keyboardEventsThread.runLoop, runLoopSource, .commonModes)
|
||||||
|
} else {
|
||||||
|
App.app.restart()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private let handleEvent: CGEventTapCallBack = { _, type, cgEvent, _ in
|
||||||
|
if type.rawValue == NSEvent.EventType.gesture.rawValue {
|
||||||
|
if touchEventHandler(cgEvent) {
|
||||||
|
return nil // focused app won't receive the event
|
||||||
|
}
|
||||||
|
} else if (type == .tapDisabledByUserInput || type == .tapDisabledByTimeout) && shouldBeEnabled {
|
||||||
|
CGEvent.tapEnable(tap: eventTap!, enable: true)
|
||||||
|
}
|
||||||
|
return Unmanaged.passUnretained(cgEvent) // focused app will receive the event
|
||||||
|
}
|
||||||
|
|
||||||
|
private func touchEventHandler(_ cgEvent: CGEvent) -> Bool {
|
||||||
|
var nsEvent: NSEvent?
|
||||||
|
DispatchQueue.main.sync {
|
||||||
|
nsEvent = NSEvent(cgEvent: cgEvent)
|
||||||
|
}
|
||||||
|
guard let nsEvent = nsEvent else { return false }
|
||||||
|
let touches = nsEvent.allTouches()
|
||||||
|
// Sometimes there are empty touch events that we have to skip. There are no empty touch events if Mission Control or App Expose use 3-finger swipes though.
|
||||||
|
if touches.isEmpty { return false }
|
||||||
|
let requiredFingers = Preferences.nextWindowGesture == .fourFingerSwipe ? 4 : 3
|
||||||
|
if touches.allSatisfy({ $0.phase == .ended }) || touches.count != requiredFingers {
|
||||||
|
clearState()
|
||||||
|
if App.app.appIsBeingUsed && touches.count < requiredFingers && App.app.shortcutIndex == 5
|
||||||
|
&& Preferences.shortcutStyle[App.app.shortcutIndex] == .focusOnRelease {
|
||||||
|
DispatchQueue.main.async { App.app.focusTarget() }
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
guard let delta = calculateTouchDelta(touches) else { return false }
|
||||||
|
let displacement = (x: totalDisplacement.x + delta.x, y: totalDisplacement.y + delta.y)
|
||||||
|
totalDisplacement = displacement
|
||||||
|
|
||||||
|
// handle showing the app initially
|
||||||
|
if !App.app.appIsBeingUsed {
|
||||||
|
if abs(displacement.x) > SHOW_UI_THRESHOLD && abs(displacement.y) < SHOW_UI_THRESHOLD {
|
||||||
|
resetDisplacement(x: true, y: false)
|
||||||
|
// the SHOW_UI_THRESHOLD is much less then the CYCLE_THRESHOLD
|
||||||
|
// so for consistency when swiping, extend the threshold for the next horizontal swipe
|
||||||
|
extendNextXThreshold = true
|
||||||
|
DispatchQueue.main.async { App.app.showUiOrCycleSelection(5) }
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// handle swipes when the app is open
|
||||||
|
if abs(displacement.x) > CYCLE_THRESHOLD {
|
||||||
|
// if extendNextXThreshold is set, extend the threshold for a right swipe to account for the show ui swipe
|
||||||
|
if !extendNextXThreshold || displacement.x < 0
|
||||||
|
|| displacement.x > 2 * CYCLE_THRESHOLD - SHOW_UI_THRESHOLD
|
||||||
|
{
|
||||||
|
let direction: Direction = displacement.x < 0 ? .left : .right
|
||||||
|
resetDisplacement(x: true, y: false)
|
||||||
|
extendNextXThreshold = false
|
||||||
|
DispatchQueue.main.async { App.app.cycleSelection(direction, allowWrap: false) }
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if abs(displacement.y) > CYCLE_THRESHOLD {
|
||||||
|
let direction: Direction = displacement.y < 0 ? .down : .up
|
||||||
|
resetDisplacement(x: false, y: true)
|
||||||
|
DispatchQueue.main.async { App.app.cycleSelection(direction, allowWrap: false) }
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
private func calculateTouchDelta(_ touches: Set<NSTouch>) -> (x: Float, y: Float)? {
|
||||||
|
var allRight = true
|
||||||
|
var allLeft = true
|
||||||
|
var allUp = true
|
||||||
|
var allDown = true
|
||||||
|
var sumDelta = (x: Float(0), y: Float(0))
|
||||||
|
var count = 0
|
||||||
|
|
||||||
|
for touch in touches {
|
||||||
|
let prevPosition = prevTouchPositions["\(touch.identity)"]
|
||||||
|
let position = touch.normalizedPosition
|
||||||
|
if touch.phase == .ended {
|
||||||
|
prevTouchPositions.removeValue(forKey: "\(touch.identity)")
|
||||||
|
} else {
|
||||||
|
prevTouchPositions["\(touch.identity)"] = position
|
||||||
|
}
|
||||||
|
if prevPosition == nil { continue }
|
||||||
|
|
||||||
|
let delta = (
|
||||||
|
x: Float(position.x - prevPosition!.x), y: Float(position.y - prevPosition!.y)
|
||||||
|
)
|
||||||
|
|
||||||
|
allRight = allRight && delta.x > 0
|
||||||
|
allLeft = allLeft && delta.x < 0
|
||||||
|
allUp = allUp && delta.y > 0
|
||||||
|
allDown = allDown && delta.y < 0
|
||||||
|
|
||||||
|
sumDelta.x += delta.x
|
||||||
|
sumDelta.y += delta.y
|
||||||
|
count += 1
|
||||||
|
}
|
||||||
|
|
||||||
|
// All fingers should move in the same direction.
|
||||||
|
if count == 0 || (!allRight && !allLeft && !allUp && !allDown) { return nil }
|
||||||
|
return (x: sumDelta.x / Float(count), y: sumDelta.y / Float(count))
|
||||||
|
}
|
||||||
|
|
||||||
|
private func clearState() {
|
||||||
|
prevTouchPositions.removeAll()
|
||||||
|
resetDisplacement()
|
||||||
|
extendNextXThreshold = false
|
||||||
|
}
|
||||||
|
|
||||||
|
private func resetDisplacement(x: Bool = true, y: Bool = true) {
|
||||||
|
if x && y {
|
||||||
|
totalDisplacement = (0, 0)
|
||||||
|
} else if x {
|
||||||
|
totalDisplacement.x = 0
|
||||||
|
} else if y {
|
||||||
|
totalDisplacement.y = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
+4
-3
@@ -74,6 +74,7 @@ class App: AppCenterApplication, NSApplicationDelegate {
|
|||||||
self.feedbackWindow = FeedbackWindow()
|
self.feedbackWindow = FeedbackWindow()
|
||||||
KeyboardEvents.addEventHandlers()
|
KeyboardEvents.addEventHandlers()
|
||||||
MouseEvents.observe()
|
MouseEvents.observe()
|
||||||
|
TrackpadEvents.observe()
|
||||||
// TODO: undeterministic; events in the queue may still be processing; good enough for now
|
// TODO: undeterministic; events in the queue may still be processing; good enough for now
|
||||||
DispatchQueue.main.async { () -> () in Windows.sortByLevel() }
|
DispatchQueue.main.async { () -> () in Windows.sortByLevel() }
|
||||||
self.preloadWindows()
|
self.preloadWindows()
|
||||||
@@ -216,11 +217,11 @@ class App: AppCenterApplication, NSApplicationDelegate {
|
|||||||
showPreferencesWindow()
|
showPreferencesWindow()
|
||||||
}
|
}
|
||||||
|
|
||||||
func cycleSelection(_ direction: Direction) {
|
func cycleSelection(_ direction: Direction, allowWrap: Bool = true) {
|
||||||
if direction == .up || direction == .down {
|
if direction == .up || direction == .down {
|
||||||
thumbnailsPanel.thumbnailsView.navigateUpOrDown(direction)
|
thumbnailsPanel.thumbnailsView.navigateUpOrDown(direction, allowWrap: allowWrap)
|
||||||
} else {
|
} else {
|
||||||
Windows.cycleFocusedWindowIndex(direction.step())
|
Windows.cycleFocusedWindowIndex(direction.step(), allowWrap: allowWrap)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -57,24 +57,32 @@ class ThumbnailsView: NSVisualEffectView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func nextRow(_ direction: Direction) -> [ThumbnailView]? {
|
func nextRow(_ direction: Direction, allowWrap: Bool = true) -> [ThumbnailView]? {
|
||||||
let step = direction == .down ? 1 : -1
|
let step = direction == .down ? 1 : -1
|
||||||
if let currentRow = Windows.focusedWindow()?.rowIndex {
|
if let currentRow = Windows.focusedWindow()?.rowIndex {
|
||||||
let nextRow = (currentRow + step) % rows.count
|
var nextRow = currentRow + step
|
||||||
let nextRow_ = nextRow < 0 ? rows.count + nextRow : nextRow
|
if nextRow >= rows.count {
|
||||||
if ((step > 0 && nextRow_ < currentRow) || (step < 0 && nextRow_ > currentRow)) &&
|
if allowWrap {
|
||||||
|
nextRow = nextRow % rows.count
|
||||||
|
} else { return nil }
|
||||||
|
} else if nextRow < 0 {
|
||||||
|
if allowWrap {
|
||||||
|
nextRow = rows.count + nextRow
|
||||||
|
} else { return nil }
|
||||||
|
}
|
||||||
|
if ((step > 0 && nextRow < currentRow) || (step < 0 && nextRow > currentRow)) &&
|
||||||
(ATShortcut.lastEventIsARepeat || KeyRepeatTimer.timer?.isValid ?? false) {
|
(ATShortcut.lastEventIsARepeat || KeyRepeatTimer.timer?.isValid ?? false) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return rows[nextRow_]
|
return rows[nextRow]
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func navigateUpOrDown(_ direction: Direction) {
|
func navigateUpOrDown(_ direction: Direction, allowWrap: Bool = true) {
|
||||||
let focusedViewFrame = ThumbnailsView.recycledViews[Windows.focusedWindowIndex].frame
|
let focusedViewFrame = ThumbnailsView.recycledViews[Windows.focusedWindowIndex].frame
|
||||||
let originCenter = NSMidX(focusedViewFrame)
|
let originCenter = NSMidX(focusedViewFrame)
|
||||||
if let targetRow = nextRow(direction) {
|
if let targetRow = nextRow(direction, allowWrap: allowWrap) {
|
||||||
let leftSide = originCenter < NSMidX(frame)
|
let leftSide = originCenter < NSMidX(frame)
|
||||||
let leadingSide = App.shared.userInterfaceLayoutDirection == .leftToRight ? leftSide : !leftSide
|
let leadingSide = App.shared.userInterfaceLayoutDirection == .leftToRight ? leftSide : !leftSide
|
||||||
let iterable = leadingSide ? targetRow : targetRow.reversed()
|
let iterable = leadingSide ? targetRow : targetRow.reversed()
|
||||||
|
|||||||
@@ -41,12 +41,13 @@ class ControlsTab {
|
|||||||
static var additionalControlsSheet: AdditionalControlsSheet!
|
static var additionalControlsSheet: AdditionalControlsSheet!
|
||||||
|
|
||||||
static func initTab() -> NSView {
|
static func initTab() -> NSView {
|
||||||
let (holdShortcut, nextWindowShortcut, tab1View) = toShowSection(0)
|
let (holdShortcut, nextWindowShortcut, tab1View) = shortcutTab(0)
|
||||||
let (holdShortcut2, nextWindowShortcut2, tab2View) = toShowSection(1)
|
let (holdShortcut2, nextWindowShortcut2, tab2View) = shortcutTab(1)
|
||||||
let (holdShortcut3, nextWindowShortcut3, tab3View) = toShowSection(2)
|
let (holdShortcut3, nextWindowShortcut3, tab3View) = shortcutTab(2)
|
||||||
let (holdShortcut4, nextWindowShortcut4, tab4View) = toShowSection(3)
|
let (holdShortcut4, nextWindowShortcut4, tab4View) = shortcutTab(3)
|
||||||
let (holdShortcut5, nextWindowShortcut5, tab5View) = toShowSection(4)
|
let (holdShortcut5, nextWindowShortcut5, tab5View) = shortcutTab(4)
|
||||||
tableGroupViews = [tab1View, tab2View, tab3View, tab4View, tab5View]
|
let tab6View = gestureTab(5)
|
||||||
|
tableGroupViews = [tab1View, tab2View, tab3View, tab4View, tab5View, tab6View]
|
||||||
// trigger shortcutChanged for these shortcuts to trigger .restrictModifiers
|
// trigger shortcutChanged for these shortcuts to trigger .restrictModifiers
|
||||||
[holdShortcut, holdShortcut2, holdShortcut3, holdShortcut4, holdShortcut5].forEach { ControlsTab.shortcutChangedCallback($0[1] as! NSControl) }
|
[holdShortcut, holdShortcut2, holdShortcut3, holdShortcut4, holdShortcut5].forEach { ControlsTab.shortcutChangedCallback($0[1] as! NSControl) }
|
||||||
[nextWindowShortcut, nextWindowShortcut2, nextWindowShortcut3, nextWindowShortcut4, nextWindowShortcut5].forEach { ControlsTab.shortcutChangedCallback($0[0] as! NSControl) }
|
[nextWindowShortcut, nextWindowShortcut2, nextWindowShortcut3, nextWindowShortcut4, nextWindowShortcut5].forEach { ControlsTab.shortcutChangedCallback($0[0] as! NSControl) }
|
||||||
@@ -62,6 +63,7 @@ class ControlsTab {
|
|||||||
NSLocalizedString("Shortcut 3", comment: ""),
|
NSLocalizedString("Shortcut 3", comment: ""),
|
||||||
NSLocalizedString("Shortcut 4", comment: ""),
|
NSLocalizedString("Shortcut 4", comment: ""),
|
||||||
NSLocalizedString("Shortcut 5", comment: ""),
|
NSLocalizedString("Shortcut 5", comment: ""),
|
||||||
|
NSLocalizedString("Gesture", comment: ""),
|
||||||
], trackingMode: .selectOne, target: self, action: #selector(switchTab(_:)))
|
], trackingMode: .selectOne, target: self, action: #selector(switchTab(_:)))
|
||||||
tab.selectedSegment = 0
|
tab.selectedSegment = 0
|
||||||
tab.segmentStyle = .automatic
|
tab.segmentStyle = .automatic
|
||||||
@@ -71,7 +73,7 @@ class ControlsTab {
|
|||||||
let additionalControlsButton = NSButton(title: NSLocalizedString("Additional controls…", comment: ""), target: self, action: #selector(ControlsTab.showAdditionalControlsSettings))
|
let additionalControlsButton = NSButton(title: NSLocalizedString("Additional controls…", comment: ""), target: self, action: #selector(ControlsTab.showAdditionalControlsSettings))
|
||||||
let shortcutsButton = NSButton(title: NSLocalizedString("Shortcuts when active…", comment: ""), target: self, action: #selector(ControlsTab.showShortcutsSettings))
|
let shortcutsButton = NSButton(title: NSLocalizedString("Shortcuts when active…", comment: ""), target: self, action: #selector(ControlsTab.showShortcutsSettings))
|
||||||
let tools = StackView([additionalControlsButton, shortcutsButton], .horizontal)
|
let tools = StackView([additionalControlsButton, shortcutsButton], .horizontal)
|
||||||
let view = TableGroupSetView(originalViews: [table, tab1View, tab2View, tab3View, tab4View, tab5View], toolsViews: [tools], toolsAlignment: .trailing)
|
let view = TableGroupSetView(originalViews: [table, tab1View, tab2View, tab3View, tab4View, tab5View, tab6View], toolsViews: [tools], toolsAlignment: .trailing)
|
||||||
view.translatesAutoresizingMaskIntoConstraints = false
|
view.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
|
||||||
shortcutsWhenActiveSheet = ShortcutsWhenActiveSheet()
|
shortcutsWhenActiveSheet = ShortcutsWhenActiveSheet()
|
||||||
@@ -82,7 +84,28 @@ class ControlsTab {
|
|||||||
return view
|
return view
|
||||||
}
|
}
|
||||||
|
|
||||||
private static func toShowSection(_ index: Int) -> ([NSView], [NSView], TableGroupView) {
|
private static func shortcutTab(_ index: Int) -> ([NSView], [NSView], TableGroupView) {
|
||||||
|
var holdShortcut = LabelAndControl.makeLabelWithRecorder(NSLocalizedString("Hold", comment: ""), Preferences.indexToName("holdShortcut", index), Preferences.holdShortcut[index], false, labelPosition: .leftWithoutSeparator)
|
||||||
|
holdShortcut.append(LabelAndControl.makeLabel(NSLocalizedString("and press", comment: "")))
|
||||||
|
let nextWindowShortcut = LabelAndControl.makeLabelWithRecorder(NSLocalizedString("Select next window", comment: ""), Preferences.indexToName("nextWindowShortcut", index), Preferences.nextWindowShortcut[index], labelPosition: .right)
|
||||||
|
let tab = controlTab(index, holdShortcut + [nextWindowShortcut[0]])
|
||||||
|
return (holdShortcut, nextWindowShortcut, tab)
|
||||||
|
}
|
||||||
|
|
||||||
|
private static func gestureTab(_ index: Int) -> TableGroupView {
|
||||||
|
let label = NSLocalizedString("Swipe may conflict with system shortcuts", comment: "")
|
||||||
|
let button = NSButton(title: NSLocalizedString("Open Trackpad Preferences…", comment: ""), target: self, action: #selector(openSystemGestures(_:)))
|
||||||
|
let infoBtn = LabelAndControl.makeInfoButton(onMouseEntered: { event, view in
|
||||||
|
Popover.shared.show(event: event, positioningView: view, message: label, extraView: button)
|
||||||
|
})
|
||||||
|
let gesture = LabelAndControl.makeDropdown("nextWindowGesture", GesturePreference.allCases, extraAction: ControlsTab.gestureChangedCallback)
|
||||||
|
let gestureWithTooltip = StackView([infoBtn, gesture], .horizontal)
|
||||||
|
gestureWithTooltip.spacing = 8
|
||||||
|
gestureWithTooltip.alignment = .centerY
|
||||||
|
return controlTab(index, [gestureWithTooltip])
|
||||||
|
}
|
||||||
|
|
||||||
|
private static func controlTab(_ index: Int, _ trigger: [NSView]) -> TableGroupView {
|
||||||
let appsToShow = LabelAndControl.makeDropdown(Preferences.indexToName("appsToShow", index), AppsToShowPreference.allCases)
|
let appsToShow = LabelAndControl.makeDropdown(Preferences.indexToName("appsToShow", index), AppsToShowPreference.allCases)
|
||||||
let spacesToShow = LabelAndControl.makeDropdown(Preferences.indexToName("spacesToShow", index), SpacesToShowPreference.allCases)
|
let spacesToShow = LabelAndControl.makeDropdown(Preferences.indexToName("spacesToShow", index), SpacesToShowPreference.allCases)
|
||||||
let screensToShow = LabelAndControl.makeDropdown(Preferences.indexToName("screensToShow", index), ScreensToShowPreference.allCases)
|
let screensToShow = LabelAndControl.makeDropdown(Preferences.indexToName("screensToShow", index), ScreensToShowPreference.allCases)
|
||||||
@@ -90,14 +113,10 @@ class ControlsTab {
|
|||||||
let showHiddenWindows = LabelAndControl.makeDropdown(Preferences.indexToName("showHiddenWindows", index), ShowHowPreference.allCases)
|
let showHiddenWindows = LabelAndControl.makeDropdown(Preferences.indexToName("showHiddenWindows", index), ShowHowPreference.allCases)
|
||||||
let showFullscreenWindows = LabelAndControl.makeDropdown(Preferences.indexToName("showFullscreenWindows", index), ShowHowPreference.allCases.filter { $0 != .showAtTheEnd })
|
let showFullscreenWindows = LabelAndControl.makeDropdown(Preferences.indexToName("showFullscreenWindows", index), ShowHowPreference.allCases.filter { $0 != .showAtTheEnd })
|
||||||
let windowOrder = LabelAndControl.makeDropdown(Preferences.indexToName("windowOrder", index), WindowOrderPreference.allCases)
|
let windowOrder = LabelAndControl.makeDropdown(Preferences.indexToName("windowOrder", index), WindowOrderPreference.allCases)
|
||||||
|
|
||||||
var holdShortcut = LabelAndControl.makeLabelWithRecorder(NSLocalizedString("Hold", comment: ""), Preferences.indexToName("holdShortcut", index), Preferences.holdShortcut[index], false, labelPosition: .leftWithoutSeparator)
|
|
||||||
holdShortcut.append(LabelAndControl.makeLabel(NSLocalizedString("and press", comment: "")))
|
|
||||||
let nextWindowShortcut = LabelAndControl.makeLabelWithRecorder(NSLocalizedString("Select next window", comment: ""), Preferences.indexToName("nextWindowShortcut", index), Preferences.nextWindowShortcut[index], labelPosition: .right)
|
|
||||||
let shortcutStyle = LabelAndControl.makeDropdown(Preferences.indexToName("shortcutStyle", index), ShortcutStylePreference.allCases)
|
let shortcutStyle = LabelAndControl.makeDropdown(Preferences.indexToName("shortcutStyle", index), ShortcutStylePreference.allCases)
|
||||||
|
|
||||||
let table = TableGroupView(width: PreferencesWindow.width)
|
let table = TableGroupView(width: PreferencesWindow.width)
|
||||||
table.addRow(TableGroupView.Row(leftTitle: NSLocalizedString("Trigger shortcut", comment: ""), rightViews: holdShortcut + [nextWindowShortcut[0]]))
|
table.addRow(TableGroupView.Row(leftTitle: NSLocalizedString("Trigger shortcut", comment: ""), rightViews: trigger))
|
||||||
table.addRow(TableGroupView.Row(leftTitle: NSLocalizedString("After release", comment: ""), rightViews: [shortcutStyle]))
|
table.addRow(TableGroupView.Row(leftTitle: NSLocalizedString("After release", comment: ""), rightViews: [shortcutStyle]))
|
||||||
|
|
||||||
table.addNewTable()
|
table.addNewTable()
|
||||||
@@ -109,7 +128,7 @@ class ControlsTab {
|
|||||||
table.addRow(TableGroupView.Row(leftTitle: NSLocalizedString("Show fullscreen windows", comment: ""), rightViews: [showFullscreenWindows]))
|
table.addRow(TableGroupView.Row(leftTitle: NSLocalizedString("Show fullscreen windows", comment: ""), rightViews: [showFullscreenWindows]))
|
||||||
table.addRow(TableGroupView.Row(leftTitle: NSLocalizedString("Order windows by", comment: ""), rightViews: [windowOrder]))
|
table.addRow(TableGroupView.Row(leftTitle: NSLocalizedString("Order windows by", comment: ""), rightViews: [windowOrder]))
|
||||||
table.fit()
|
table.fit()
|
||||||
return (holdShortcut, nextWindowShortcut, table)
|
return table
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc static func switchTab(_ sender: NSSegmentedControl) {
|
@objc static func switchTab(_ sender: NSSegmentedControl) {
|
||||||
@@ -293,6 +312,15 @@ class ControlsTab {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@objc static func gestureChangedCallback(_ sender: NSControl) {
|
||||||
|
TrackpadEvents.toggle(Preferences.nextWindowGesture != .disabled)
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc private static func openSystemGestures(_ sender: NSButton) {
|
||||||
|
// Apple doesn't expose the More Gestures tab directly
|
||||||
|
NSWorkspace.shared.open(URL(string: "x-apple.systempreferences:com.apple.Trackpad-Settings.extension")!)
|
||||||
|
}
|
||||||
|
|
||||||
static func executeAction(_ action: String) {
|
static func executeAction(_ action: String) {
|
||||||
shortcutsActions[action]!()
|
shortcutsActions[action]!()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user