Skip to content

Commit 34e9207

Browse files
v1.94.2/v7.23.0.2: add applescript commands: countAllWindowsStats & countWindowsStats
1 parent 51b6909 commit 34e9207

File tree

6 files changed

+192
-3
lines changed

6 files changed

+192
-3
lines changed

AltTab.sdef

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,17 @@
3939
<cocoa key="appBID"/>
4040
</parameter>
4141
</command>
42+
<command name="countWindowStats" code="atssCntW">
43+
<cocoa class="AltTab.countWindowStatsScriptCommand"/>
44+
<direct-parameter type="text" name="appBID"/>
45+
<result type="any"/>
46+
</command>
47+
48+
<command name="countAllWindowStats" code="atssCntA">
49+
<cocoa class="AltTab.countAllWindowStatsScriptCommand"/>
50+
<result type="any"/>
51+
</command>
52+
4253
<command name="countWindowsCurrentSpace" code="atssCWCS" description="The number of windows for an app (in the current space, especially useful for counting hidden windows (otherwise especially hard to do for the current space)).">
4354
<cocoa class="AltTab.countWindowsCurrentSpaceScriptCommand"/>
4455
<parameter name="appBID" code="arg1" type="text" optional="no" description="The bundle identifier of the app whose windows you want to count.">

Info.plist

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@
2323
<key>CFBundlePackageType</key>
2424
<string>APPL</string>
2525
<key>CFBundleShortVersionString</key>
26-
<string>7.23.0.1</string>
26+
<string>7.23.0.2</string>
2727
<key>CFBundleVersion</key>
28-
<string>7.23.0.1</string>
28+
<string>7.23.0.2</string>
2929
<key>FeedbackToken</key>
3030
<string>#FEEDBACK_TOKEN#</string>
3131
<key>LSApplicationCategoryType</key>

alt-tab-macos.xcodeproj/project.pbxproj

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,8 @@
181181
BF0C8F3526BC393290D5BE59 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = BF0C81EC1C5F3052A75C7D7B /* InfoPlist.strings */; };
182182
BF0C8F9B8014AD21E68B1349 /* HelperExtensionsTestable.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF0C810FA0F6BC70E5886E11 /* HelperExtensionsTestable.swift */; };
183183
BF0C8FF2A4B00D409494EA80 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = BF0C88D79FA0C773D94F351A /* InfoPlist.strings */; };
184+
BF1B815D2EFE758500A175CE /* countWindowsStatsScriptCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF1B815C2EFE758500A175CE /* countWindowsStatsScriptCommand.swift */; };
185+
BF1B815F2EFE7D0800A175CE /* countAllWindowsStatsScriptCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF1B815E2EFE7D0800A175CE /* countAllWindowsStatsScriptCommand.swift */; };
184186
BF42BC82283552B400F5D5E7 /* HideScriptCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF42BC7E283552B400F5D5E7 /* HideScriptCommand.swift */; };
185187
BF42BC83283552B400F5D5E7 /* showAppScriptCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF42BC7F283552B400F5D5E7 /* showAppScriptCommand.swift */; };
186188
BF42BC84283552B400F5D5E7 /* ShowScriptCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF42BC80283552B400F5D5E7 /* ShowScriptCommand.swift */; };
@@ -519,6 +521,8 @@
519521
BF0C8EE17F3ABD7A6D44BFFE /* pl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = pl; path = Localizable.strings; sourceTree = "<group>"; };
520522
BF0C8F58B38F29B2662E6C2D /* PreferencesMigrations.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PreferencesMigrations.swift; sourceTree = "<group>"; };
521523
BF0C8FC083A2443F3EAF5DB7 /* preferences-blacklist.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = "preferences-blacklist.jpg"; sourceTree = "<group>"; };
524+
BF1B815C2EFE758500A175CE /* countWindowsStatsScriptCommand.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = countWindowsStatsScriptCommand.swift; sourceTree = "<group>"; };
525+
BF1B815E2EFE7D0800A175CE /* countAllWindowsStatsScriptCommand.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = countAllWindowsStatsScriptCommand.swift; sourceTree = "<group>"; };
522526
BF42BC7E283552B400F5D5E7 /* HideScriptCommand.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HideScriptCommand.swift; sourceTree = "<group>"; };
523527
BF42BC7F283552B400F5D5E7 /* showAppScriptCommand.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = showAppScriptCommand.swift; sourceTree = "<group>"; };
524528
BF42BC80283552B400F5D5E7 /* ShowScriptCommand.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ShowScriptCommand.swift; sourceTree = "<group>"; };
@@ -1261,8 +1265,10 @@
12611265
isa = PBXGroup;
12621266
children = (
12631267
BFFEABC02ABE6F8F00399DA5 /* countMinimizedWindowsCurrentSpaceScriptCommand.swift */,
1264-
BF73FE482A8EEFBC00AB9D0A /* countWindowsCurrentSpaceScriptCommand.swift */,
12651268
BF49DF3128355340004517BD /* countWindowsScriptCommand.swift */,
1269+
BF73FE482A8EEFBC00AB9D0A /* countWindowsCurrentSpaceScriptCommand.swift */,
1270+
BF1B815E2EFE7D0800A175CE /* countAllWindowsStatsScriptCommand.swift */,
1271+
BF1B815C2EFE758500A175CE /* countWindowsStatsScriptCommand.swift */,
12661272
BFEA01162ABE84740000F1AE /* deminimizeFirstMinimizedWindowFromCurrentSpace.swift */,
12671273
BF42BC7E283552B400F5D5E7 /* HideScriptCommand.swift */,
12681274
BF42BC7F283552B400F5D5E7 /* showAppScriptCommand.swift */,
@@ -2434,6 +2440,7 @@
24342440
D04BA4A11F821548EE3C5E95 /* Bash.swift in Sources */,
24352441
5F21C9E62C6E94920091F72F /* AnimationsSheet.swift in Sources */,
24362442
D04BAFB90E00AA5D662EAF24 /* PermissionsWindow.swift in Sources */,
2443+
BF1B815D2EFE758500A175CE /* countWindowsStatsScriptCommand.swift in Sources */,
24372444
D04BA7E39FA539DD8316447A /* PermissionView.swift in Sources */,
24382445
D04BA446D702C5E252AF2319 /* TitleLabel.swift in Sources */,
24392446
D04BAD43C122A1C7E88B0362 /* MouseEvents.swift in Sources */,
@@ -2462,6 +2469,7 @@
24622469
BF0C8249228867A3188E13F3 /* SystemAppearanceEvents.swift in Sources */,
24632470
BF0C827A169F0DE86C8F12AD /* SystemScrollerStyleEvents.swift in Sources */,
24642471
BF0C8846AFEE2FFF93FAB36F /* AppearanceTestable.swift in Sources */,
2472+
BF1B815F2EFE7D0800A175CE /* countAllWindowsStatsScriptCommand.swift in Sources */,
24652473
BF0C88449007A09F1D175029 /* KeyboardEventsTestable.swift in Sources */,
24662474
BF0C85DA2D285400801C514A /* Logger.swift in Sources */,
24672475
BF0C89B4B17D7843C32A102E /* Markdown.swift in Sources */,
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import Foundation
2+
import Cocoa
3+
4+
class countAllWindowStatsScriptCommand: NSScriptCommand {
5+
6+
override func performDefaultImplementation() -> Any? {
7+
8+
let list = NSAppleEventDescriptor.list()
9+
10+
for app in Applications.list {
11+
let pid = app.pid
12+
13+
var all = 0
14+
var cur = 0
15+
var minCur = 0
16+
17+
for window in Windows.list {
18+
guard window.application.runningApplication.processIdentifier == pid else { continue }
19+
20+
all += 1
21+
22+
let inVisibleSpace =
23+
window.spaceIds.contains { Spaces.visibleSpaces.contains($0) }
24+
25+
if inVisibleSpace {
26+
cur += 1
27+
if window.isMinimized {
28+
minCur += 1
29+
}
30+
}
31+
}
32+
33+
if all == 0 { continue }
34+
35+
let record = NSAppleEventDescriptor.record()
36+
37+
record.setDescriptor(
38+
NSAppleEventDescriptor(int32: Int32(pid)),
39+
forKeyword: kPID
40+
)
41+
record.setDescriptor(
42+
NSAppleEventDescriptor(int32: Int32(all)),
43+
forKeyword: kWin
44+
)
45+
record.setDescriptor(
46+
NSAppleEventDescriptor(int32: Int32(cur)),
47+
forKeyword: kCur
48+
)
49+
record.setDescriptor(
50+
NSAppleEventDescriptor(int32: Int32(minCur)),
51+
forKeyword: kMin
52+
)
53+
54+
list.insert(record, at: list.numberOfItems + 1)
55+
}
56+
57+
return list
58+
}
59+
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import Foundation
2+
import Cocoa
3+
4+
let kPID: FourCharCode = 0x70504944 // 'pPID'
5+
let kWin: FourCharCode = 0x6357696E // 'cWin'
6+
let kCur: FourCharCode = 0x63437572 // 'cCur'
7+
let kMin: FourCharCode = 0x634D696E // 'cMin'
8+
9+
10+
func makeStatsRecord(
11+
countWindows: Int,
12+
countWindowsCurrentSpace: Int,
13+
countMinimizedWindowsCurrentSpace: Int
14+
) -> NSAppleEventDescriptor {
15+
16+
let record = NSAppleEventDescriptor.record()
17+
18+
record.setDescriptor(
19+
NSAppleEventDescriptor(int32: Int32(countWindows)),
20+
forKeyword: kWin
21+
)
22+
23+
record.setDescriptor(
24+
NSAppleEventDescriptor(int32: Int32(countWindowsCurrentSpace)),
25+
forKeyword: kCur
26+
)
27+
28+
record.setDescriptor(
29+
NSAppleEventDescriptor(int32: Int32(countMinimizedWindowsCurrentSpace)),
30+
forKeyword: kMin
31+
)
32+
33+
return record
34+
}
35+
36+
37+
class countWindowStatsScriptCommand: NSScriptCommand {
38+
39+
override func performDefaultImplementation() -> Any? {
40+
41+
guard
42+
let tarBID = (self.directParameter as? String),
43+
let tarApp = NSRunningApplication
44+
.runningApplications(withBundleIdentifier: tarBID)
45+
.first
46+
else {
47+
return makeStatsRecord(
48+
countWindows: 0,
49+
countWindowsCurrentSpace: 0,
50+
countMinimizedWindowsCurrentSpace: 0
51+
)
52+
}
53+
54+
let pid = tarApp.processIdentifier
55+
56+
var all = 0
57+
var cur = 0
58+
var minCur = 0
59+
60+
for window in Windows.list {
61+
guard window.application.runningApplication.processIdentifier == pid else { continue }
62+
63+
all += 1
64+
65+
let inVisibleSpace =
66+
window.spaceIds.contains { Spaces.visibleSpaces.contains($0) }
67+
68+
if inVisibleSpace {
69+
cur += 1
70+
if window.isMinimized {
71+
minCur += 1
72+
}
73+
}
74+
}
75+
76+
return makeStatsRecord(
77+
countWindows: all,
78+
countWindowsCurrentSpace: cur,
79+
countMinimizedWindowsCurrentSpace: minCur
80+
)
81+
}
82+
}

src/logic/events/RunningApplicationsEvents.swift

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,38 @@ class RunningApplicationsEvents {
77
static func observe() {
88
previousValueOfRunningApps = Set(NSWorkspace.shared.runningApplications)
99
appsObserver = NSWorkspace.shared.observe(\.runningApplications, options: [.old, .new], changeHandler: handleEvent)
10+
11+
// let timer = Timer.scheduledTimer(withTimeInterval: 2.0, repeats: true) { _ in
12+
// for i in 0..<18 { print("") }
13+
// let x = Windows.list.enumerated().map({ (i, w) in
14+
// return [i+1, w.cgWindowId ?? 0,
15+
// w.application.localizedName != nil ? w.application.localizedName! : "",
16+
// w.title != nil ? w.title! : "",
17+
// w.isTabbed,
18+
// w.referenceWindowForTabbedWindow() ?? 0,
19+
// w.position ?? 0,
20+
// w.size ?? 0,
21+
// w.spaceIndexes,
22+
// w.spaceIds,
23+
// w.dockLabel != nil ? w.dockLabel! : "",
24+
// w.isAppMainWindow(),
25+
// w.isMinimized,
26+
// w.isHidden,
27+
// w.isFullscreen,
28+
// w.isOnAllSpaces,
29+
// w.lastFocusOrder,
30+
// w.creationOrder,
31+
// w.shouldShowTheUser,
32+
// w.canBeClosed(),
33+
// w.canBeMinDeminOrFullscreened()]
34+
// });
35+
// x.forEach { print($0) }
36+
// }
37+
// RunLoop.main.add(timer, forMode: .common)
1038
}
1139

1240
// TODO: handle this on a separate thread?
41+
@Sendable
1342
private static func handleEvent<A>(_: NSWorkspace, _ change: NSKeyValueObservedChange<A>) {
1443
let workspaceApps = Set(NSWorkspace.shared.runningApplications)
1544
// TODO: symmetricDifference has bad performance

0 commit comments

Comments
 (0)