feat: new cli commands: --show, --detailed-list (closes #4489)
This commit is contained in:
1 parent
bd162a9e08
commit
b0ce899a71
7 files changed
+88
-30
No files matched your search
@@ -57,7 +57,7 @@ class ATShortcut {
|
|||||||
if triggerPhase == .down && (!App.app.appIsBeingUsed || index == nil || index == App.app.shortcutIndex) {
|
if triggerPhase == .down && (!App.app.appIsBeingUsed || index == nil || index == App.app.shortcutIndex) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if triggerPhase == .up && App.app.appIsBeingUsed && (index == nil || index == App.app.shortcutIndex) && Preferences.shortcutStyle[App.app.shortcutIndex] == .focusOnRelease {
|
if triggerPhase == .up && App.app.appIsBeingUsed && (index == nil || index == App.app.shortcutIndex) && !App.app.forceDoNothingOnRelease && Preferences.shortcutStyle[App.app.shortcutIndex] == .focusOnRelease {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -83,7 +83,7 @@ class ATShortcut {
|
|||||||
// Another issue is events being dropped by macOS, which we never receive
|
// Another issue is events being dropped by macOS, which we never receive
|
||||||
// Knowing this, we handle these edge-cases by double checking if holdShortcut is UP, when any shortcut state is UP
|
// Knowing this, we handle these edge-cases by double checking if holdShortcut is UP, when any shortcut state is UP
|
||||||
// If it is, then we trigger the holdShortcut action
|
// If it is, then we trigger the holdShortcut action
|
||||||
if App.app.appIsBeingUsed && Preferences.shortcutStyle[App.app.shortcutIndex] == .focusOnRelease {
|
if App.app.appIsBeingUsed && !App.app.forceDoNothingOnRelease && Preferences.shortcutStyle[App.app.shortcutIndex] == .focusOnRelease {
|
||||||
if let currentHoldShortcut = ControlsTab.shortcuts[Preferences.indexToName("holdShortcut", App.app.shortcutIndex)],
|
if let currentHoldShortcut = ControlsTab.shortcuts[Preferences.indexToName("holdShortcut", App.app.shortcutIndex)],
|
||||||
id == currentHoldShortcut.id {
|
id == currentHoldShortcut.id {
|
||||||
let currentModifiers = cocoaToCarbonFlags(ModifierFlags.current)
|
let currentModifiers = cocoaToCarbonFlags(ModifierFlags.current)
|
||||||
|
|||||||
@@ -38,28 +38,56 @@ class CliServer {
|
|||||||
static func executeCommandAndSendReponse(_ rawValue: String) -> Codable {
|
static func executeCommandAndSendReponse(_ rawValue: String) -> Codable {
|
||||||
var output: Codable = ""
|
var output: Codable = ""
|
||||||
DispatchQueue.main.sync {
|
DispatchQueue.main.sync {
|
||||||
if rawValue == "--list" {
|
output = executeCommandAndSendReponse_(rawValue)
|
||||||
output = JsonOutput(windows: Windows.list
|
|
||||||
.filter { !$0.isWindowlessApp }
|
|
||||||
.map { JsonWindow(id: $0.cgWindowId, title: $0.title) }
|
|
||||||
)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if rawValue.hasPrefix("--focus=") {
|
|
||||||
if let id = CGWindowID(rawValue.dropFirst("--focus=".count)),
|
|
||||||
let window = (Windows.list.first { $0.cgWindowId == id }) {
|
|
||||||
window.focus()
|
|
||||||
output = noOutput
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
output = error
|
|
||||||
}
|
}
|
||||||
return output
|
return output
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static func executeCommandAndSendReponse_(_ rawValue: String) -> Codable {
|
||||||
|
if rawValue == "--list" {
|
||||||
|
return JsonWindowList(windows: Windows.list
|
||||||
|
.filter { !$0.isWindowlessApp }
|
||||||
|
.map { JsonWindow(id: $0.cgWindowId, title: $0.title) }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if rawValue == "--detailed-list" {
|
||||||
|
return JsonWindowFullList(windows: Windows.list
|
||||||
|
.filter { !$0.isWindowlessApp }
|
||||||
|
.map {
|
||||||
|
JsonWindowFull(
|
||||||
|
id: $0.cgWindowId,
|
||||||
|
title: $0.title,
|
||||||
|
appName: $0.application.localizedName,
|
||||||
|
appBundleId: $0.application.bundleIdentifier,
|
||||||
|
spaceIndexes: $0.spaceIndexes,
|
||||||
|
lastFocusOrder: $0.lastFocusOrder,
|
||||||
|
creationOrder: $0.creationOrder,
|
||||||
|
isTabbed: $0.isTabbed,
|
||||||
|
isHidden: $0.isHidden,
|
||||||
|
isFullscreen: $0.isFullscreen,
|
||||||
|
isMinimized: $0.isMinimized,
|
||||||
|
isOnAllSpaces: $0.isOnAllSpaces,
|
||||||
|
position: $0.position,
|
||||||
|
size: $0.size
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if rawValue.hasPrefix("--focus="),
|
||||||
|
let id = CGWindowID(rawValue.dropFirst("--focus=".count)), let window = (Windows.list.first { $0.cgWindowId == id }) {
|
||||||
|
window.focus()
|
||||||
|
return noOutput
|
||||||
|
}
|
||||||
|
if rawValue.hasPrefix("--show="),
|
||||||
|
let shortcutIndex = Int(rawValue.dropFirst("--show=".count)), (0...3).contains(shortcutIndex) {
|
||||||
|
App.app.showUi(shortcutIndex)
|
||||||
|
return noOutput
|
||||||
|
}
|
||||||
|
return error
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct JsonOutput: Codable {
|
struct JsonWindowList: Codable {
|
||||||
var windows: [JsonWindow]
|
var windows: [JsonWindow]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,11 +96,33 @@ struct JsonWindow: Codable {
|
|||||||
var title: String
|
var title: String
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct JsonWindowFullList: Codable {
|
||||||
|
var windows: [JsonWindowFull]
|
||||||
|
}
|
||||||
|
|
||||||
|
struct JsonWindowFull: Codable {
|
||||||
|
var id: CGWindowID?
|
||||||
|
var title: String
|
||||||
|
// -- additional properties
|
||||||
|
var appName: String?
|
||||||
|
var appBundleId: String?
|
||||||
|
var spaceIndexes: [SpaceIndex]
|
||||||
|
var lastFocusOrder: Int
|
||||||
|
var creationOrder: Int
|
||||||
|
var isTabbed: Bool
|
||||||
|
var isHidden: Bool
|
||||||
|
var isFullscreen: Bool
|
||||||
|
var isMinimized: Bool
|
||||||
|
var isOnAllSpaces: Bool
|
||||||
|
var position: CGPoint?
|
||||||
|
var size: CGSize?
|
||||||
|
}
|
||||||
|
|
||||||
class CliClient {
|
class CliClient {
|
||||||
static func detectCommand() -> String? {
|
static func detectCommand() -> String? {
|
||||||
let args = CommandLine.arguments
|
let args = CommandLine.arguments
|
||||||
if args.count == 2 && !args[1].starts(with: "--logs=") {
|
if args.count == 2 && !args[1].starts(with: "--logs=") {
|
||||||
if args[1] == "--list" || args[1].hasPrefix("--focus=") {
|
if args[1] == "--list" || args[1] == "--detailed-list" || args[1].hasPrefix("--focus=") || args[1].hasPrefix("--show=") {
|
||||||
return args[1]
|
return args[1]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ class GestureDetector {
|
|||||||
|
|
||||||
static func checkForFingersUp(_ touches: Set<NSTouch>, _ requiredFingers: Int) -> Bool {
|
static func checkForFingersUp(_ touches: Set<NSTouch>, _ requiredFingers: Int) -> Bool {
|
||||||
if App.app.appIsBeingUsed && touches.count < requiredFingers && App.app.shortcutIndex == Preferences.gestureIndex
|
if App.app.appIsBeingUsed && touches.count < requiredFingers && App.app.shortcutIndex == Preferences.gestureIndex
|
||||||
&& Preferences.shortcutStyle[App.app.shortcutIndex] == .focusOnRelease {
|
&& !App.app.forceDoNothingOnRelease && Preferences.shortcutStyle[App.app.shortcutIndex] == .focusOnRelease {
|
||||||
DispatchQueue.main.async { App.app.focusTarget() }
|
DispatchQueue.main.async { App.app.focusTarget() }
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@@ -140,7 +140,7 @@ class TriggerSwipeDetector {
|
|||||||
let horizontal = Preferences.nextWindowGesture.isHorizontal()
|
let horizontal = Preferences.nextWindowGesture.isHorizontal()
|
||||||
if (updateSwipeStillPossible(horizontal ? absY : absX) && (horizontal ? absX : absY) >= MIN_SWIPE_DISTANCE) {
|
if (updateSwipeStillPossible(horizontal ? absY : absX) && (horizontal ? absX : absY) >= MIN_SWIPE_DISTANCE) {
|
||||||
reset()
|
reset()
|
||||||
DispatchQueue.main.async { App.app.showUiOrCycleSelection(Preferences.gestureIndex) }
|
DispatchQueue.main.async { App.app.showUiOrCycleSelection(Preferences.gestureIndex, false) }
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
|
|||||||
+10
-3
@@ -23,6 +23,7 @@ class App: AppCenterApplication {
|
|||||||
var permissionsWindow: PermissionsWindow!
|
var permissionsWindow: PermissionsWindow!
|
||||||
var appIsBeingUsed = false
|
var appIsBeingUsed = false
|
||||||
var shortcutIndex = 0
|
var shortcutIndex = 0
|
||||||
|
var forceDoNothingOnRelease = false
|
||||||
private var feedbackWindow: FeedbackWindow!
|
private var feedbackWindow: FeedbackWindow!
|
||||||
private var isFirstSummon = true
|
private var isFirstSummon = true
|
||||||
private var isVeryFirstSummon = true
|
private var isVeryFirstSummon = true
|
||||||
@@ -73,6 +74,7 @@ class App: AppCenterApplication {
|
|||||||
guard appIsBeingUsed else { return } // already hidden
|
guard appIsBeingUsed else { return } // already hidden
|
||||||
appIsBeingUsed = false
|
appIsBeingUsed = false
|
||||||
isFirstSummon = true
|
isFirstSummon = true
|
||||||
|
forceDoNothingOnRelease = false
|
||||||
MouseEvents.toggle(false)
|
MouseEvents.toggle(false)
|
||||||
hideThumbnailPanelWithoutChangingKeyWindow()
|
hideThumbnailPanelWithoutChangingKeyWindow()
|
||||||
if !keepPreview {
|
if !keepPreview {
|
||||||
@@ -156,8 +158,12 @@ class App: AppCenterApplication {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc func showUi() {
|
func showUi(_ shortcutIndex: Int) {
|
||||||
showUiOrCycleSelection(0)
|
showUiOrCycleSelection(shortcutIndex, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc func showUiFromShortcut0() {
|
||||||
|
showUi(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc func showAboutTab() {
|
@objc func showAboutTab() {
|
||||||
@@ -226,7 +232,8 @@ class App: AppCenterApplication {
|
|||||||
Applications.refreshBadgesAsync()
|
Applications.refreshBadgesAsync()
|
||||||
}
|
}
|
||||||
|
|
||||||
func showUiOrCycleSelection(_ shortcutIndex: Int) {
|
func showUiOrCycleSelection(_ shortcutIndex: Int, _ forceDoNothingOnRelease_: Bool) {
|
||||||
|
forceDoNothingOnRelease = forceDoNothingOnRelease_
|
||||||
Logger.debug(shortcutIndex, self.shortcutIndex, isFirstSummon)
|
Logger.debug(shortcutIndex, self.shortcutIndex, isFirstSummon)
|
||||||
App.app.appIsBeingUsed = true
|
App.app.appIsBeingUsed = true
|
||||||
if isFirstSummon || shortcutIndex != self.shortcutIndex {
|
if isFirstSummon || shortcutIndex != self.shortcutIndex {
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ class Menubar {
|
|||||||
menu.addItem(NSMenuItem.separator())
|
menu.addItem(NSMenuItem.separator())
|
||||||
menu.addItem(
|
menu.addItem(
|
||||||
withTitle: NSLocalizedString("Show", comment: "Menubar option"),
|
withTitle: NSLocalizedString("Show", comment: "Menubar option"),
|
||||||
action: #selector(App.app.showUi),
|
action: #selector(App.app.showUiFromShortcut0),
|
||||||
keyEquivalent: "")
|
keyEquivalent: "")
|
||||||
menu.addItem(
|
menu.addItem(
|
||||||
withTitle: NSLocalizedString("Preferences…", comment: "Menubar option"),
|
withTitle: NSLocalizedString("Preferences…", comment: "Menubar option"),
|
||||||
@@ -67,7 +67,7 @@ class Menubar {
|
|||||||
@objc static func statusItemOnClick() {
|
@objc static func statusItemOnClick() {
|
||||||
// NSApp.currentEvent == nil if the icon is "clicked" through VoiceOver
|
// NSApp.currentEvent == nil if the icon is "clicked" through VoiceOver
|
||||||
if let type = NSApp.currentEvent?.type, type != .leftMouseDown {
|
if let type = NSApp.currentEvent?.type, type != .leftMouseDown {
|
||||||
App.app.showUi()
|
App.app.showUiFromShortcut0()
|
||||||
} else {
|
} else {
|
||||||
statusItem.popUpMenu(Menubar.menu)
|
statusItem.popUpMenu(Menubar.menu)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,9 +9,9 @@ class ControlsTab {
|
|||||||
"holdShortcut2": { App.app.focusTarget() },
|
"holdShortcut2": { App.app.focusTarget() },
|
||||||
"holdShortcut3": { App.app.focusTarget() },
|
"holdShortcut3": { App.app.focusTarget() },
|
||||||
"focusWindowShortcut": { App.app.focusTarget() },
|
"focusWindowShortcut": { App.app.focusTarget() },
|
||||||
"nextWindowShortcut": { App.app.showUiOrCycleSelection(0) },
|
"nextWindowShortcut": { App.app.showUiOrCycleSelection(0, false) },
|
||||||
"nextWindowShortcut2": { App.app.showUiOrCycleSelection(1) },
|
"nextWindowShortcut2": { App.app.showUiOrCycleSelection(1, false) },
|
||||||
"nextWindowShortcut3": { App.app.showUiOrCycleSelection(2) },
|
"nextWindowShortcut3": { App.app.showUiOrCycleSelection(2, false) },
|
||||||
"previousWindowShortcut": { App.app.previousWindowShortcutWithRepeatingKey() },
|
"previousWindowShortcut": { App.app.previousWindowShortcutWithRepeatingKey() },
|
||||||
"→": { App.app.cycleSelection(.right) },
|
"→": { App.app.cycleSelection(.right) },
|
||||||
"←": { App.app.cycleSelection(.left) },
|
"←": { App.app.cycleSelection(.left) },
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ class App {
|
|||||||
class AppMock {
|
class AppMock {
|
||||||
var appIsBeingUsed = false
|
var appIsBeingUsed = false
|
||||||
var shortcutIndex = 0
|
var shortcutIndex = 0
|
||||||
|
var forceDoNothingOnRelease = false
|
||||||
}
|
}
|
||||||
static let app = AppMock()
|
static let app = AppMock()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user