fix: load app badges asynchronously to avoid system lag (closes #563)
This commit is contained in:
1 parent
4fea9431cd
commit
29eff03e70
4 files changed
+44
-22
No files matched your search
@@ -66,21 +66,38 @@ class Applications {
|
||||
}
|
||||
|
||||
static func refreshBadges() {
|
||||
let group = DispatchGroup()
|
||||
retryAxCallUntilTimeout(group) {
|
||||
if let dockPid = (Applications.list.first { $0.runningApplication.bundleIdentifier == "com.apple.dock" }?.pid),
|
||||
if !App.app.appIsBeingUsed || Preferences.hideAppBadges { return }
|
||||
retryAxCallUntilTimeout {
|
||||
if let dockPid = (list.first { $0.runningApplication.bundleIdentifier == "com.apple.dock" }?.pid),
|
||||
let axList = (try AXUIElementCreateApplication(dockPid).children()?.first { try $0.role() == "AXList" }),
|
||||
let axAppDockItem = (try axList.children()?.filter { try $0.subrole() == "AXApplicationDockItem" && ($0.appIsRunning() ?? false) }) {
|
||||
try Applications.list.forEach { app in
|
||||
if app.runningApplication.activationPolicy == .regular,
|
||||
let bundleId = app.runningApplication.bundleIdentifier,
|
||||
let url = NSWorkspace.shared.urlForApplication(withBundleIdentifier: bundleId) {
|
||||
app.dockLabel = try axAppDockItem.first { try $0.attribute(kAXURLAttribute, URL.self) == url }?.attribute(kAXStatusLabelAttribute, String.self)
|
||||
}
|
||||
let axAppDockItemUrlAndLabel = try axAppDockItem.map { try ($0.attribute(kAXURLAttribute, URL.self), $0.attribute(kAXStatusLabelAttribute, String.self)) }
|
||||
DispatchQueue.main.async {
|
||||
refreshBadges_(axAppDockItemUrlAndLabel)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static func refreshBadges_(_ items: [(URL?, String?)], _ currentIndex: Int = 0) {
|
||||
Windows.list.enumerated().forEach { (i, window) in
|
||||
let view = ThumbnailsView.recycledViews[i]
|
||||
if let app = (Applications.list.first { window.application.pid == $0.pid }) {
|
||||
if App.app.appIsBeingUsed,
|
||||
app.runningApplication.activationPolicy == .regular,
|
||||
let bundleId = app.runningApplication.bundleIdentifier,
|
||||
let url = NSWorkspace.shared.urlForApplication(withBundleIdentifier: bundleId),
|
||||
let matchingItem = (items.first { $0.0 == url }),
|
||||
let label = matchingItem.1,
|
||||
let labelInt = Int(label) {
|
||||
app.dockLabel = label
|
||||
view.updateDockLabelIcon(labelInt)
|
||||
} else {
|
||||
app.dockLabel = nil
|
||||
assignIfDifferent(&view.dockLabelIcon.isHidden, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
_ = group.wait(wallTimeout: .now() + .seconds(1))
|
||||
}
|
||||
|
||||
private static func isActualApplication(_ app: NSRunningApplication) -> Bool {
|
||||
|
||||
@@ -153,8 +153,7 @@ class Windows {
|
||||
}
|
||||
|
||||
static func refreshThumbnailsAsync(_ screen: NSScreen, _ currentIndex: Int = criticalFirstThumbnails) {
|
||||
guard App.app.appIsBeingUsed else { return }
|
||||
if Preferences.hideThumbnails { return }
|
||||
if !App.app.appIsBeingUsed || Preferences.hideThumbnails { return }
|
||||
BackgroundWork.mainQueueConcurrentWorkQueue.async {
|
||||
if currentIndex < list.count {
|
||||
let window = list[currentIndex]
|
||||
|
||||
@@ -264,5 +264,7 @@ class App: AppCenterApplication, NSApplicationDelegate {
|
||||
thumbnailsPanel.show()
|
||||
guard appIsBeingUsed else { return }
|
||||
Windows.refreshThumbnailsAsync(screen)
|
||||
guard appIsBeingUsed else { return }
|
||||
Applications.refreshBadges()
|
||||
}
|
||||
}
|
||||
@@ -135,16 +135,7 @@ class ThumbnailView: NSStackView {
|
||||
spaceIcon.setNumber(element.spaceIndex, false)
|
||||
}
|
||||
}
|
||||
assignIfDifferent(&dockLabelIcon.isHidden, element.dockLabel == nil || Preferences.hideAppBadges || Preferences.iconSize == 0)
|
||||
if !dockLabelIcon.isHidden, let dockLabel = element.dockLabel {
|
||||
let view = dockLabelIcon.subviews[1] as! ThumbnailFontIconView
|
||||
if dockLabel > 30 {
|
||||
view.setFilledStar()
|
||||
} else {
|
||||
view.setNumber(dockLabel, true)
|
||||
}
|
||||
dockLabelIcon.setFrameOrigin(NSPoint(x: appIcon.frame.maxX - dockLabelIcon.fittingSize.width - 1, y: appIcon.frame.maxY - dockLabelIcon.fittingSize.height + 4))
|
||||
}
|
||||
updateDockLabelIcon(element.dockLabel)
|
||||
assignIfDifferent(&frame.size.width, max((Preferences.hideThumbnails ? hStackView.fittingSize.width : thumbnail.frame.size.width) + Preferences.intraCellPadding * 2, ThumbnailView.widthMin(screen)).rounded())
|
||||
assignIfDifferent(&frame.size.height, newHeight)
|
||||
let fontIconWidth = CGFloat([fullscreenIcon, minimizedIcon, hiddenIcon, spaceIcon].filter { !$0.isHidden }.count) * (Preferences.fontHeight + Preferences.intraCellPadding)
|
||||
@@ -170,6 +161,19 @@ class ThumbnailView: NSStackView {
|
||||
}
|
||||
}
|
||||
|
||||
func updateDockLabelIcon(_ dockLabel: Int?) {
|
||||
assignIfDifferent(&dockLabelIcon.isHidden, dockLabel == nil || Preferences.hideAppBadges || Preferences.iconSize == 0)
|
||||
if !dockLabelIcon.isHidden, let dockLabel = dockLabel {
|
||||
let view = dockLabelIcon.subviews[1] as! ThumbnailFontIconView
|
||||
if dockLabel > 30 {
|
||||
view.setFilledStar()
|
||||
} else {
|
||||
view.setNumber(dockLabel, true)
|
||||
}
|
||||
dockLabelIcon.setFrameOrigin(NSPoint(x: appIcon.frame.maxX - dockLabelIcon.fittingSize.width - 1, y: appIcon.frame.maxY - dockLabelIcon.fittingSize.height + 4))
|
||||
}
|
||||
}
|
||||
|
||||
private func observeDragAndDrop() {
|
||||
// NSImageView instances are registered to drag-and-drop by default
|
||||
thumbnail.unregisterDraggedTypes()
|
||||
|
||||
Reference in new issue
Block a user