fix: load app badges asynchronously to avoid system lag (closes #563)

This commit is contained in:
Louis Pontoise authored and lwouis committed 2020-09-08 19:44:35 +09:00
1 parent 4fea9431cd
commit 29eff03e70
4 files changed
+44 -22

No files matched your search

+27 -10
View File
@@ -66,21 +66,38 @@ class Applications {
} }
static func refreshBadges() { static func refreshBadges() {
let group = DispatchGroup() if !App.app.appIsBeingUsed || Preferences.hideAppBadges { return }
retryAxCallUntilTimeout(group) { retryAxCallUntilTimeout {
if let dockPid = (Applications.list.first { $0.runningApplication.bundleIdentifier == "com.apple.dock" }?.pid), if let dockPid = (list.first { $0.runningApplication.bundleIdentifier == "com.apple.dock" }?.pid),
let axList = (try AXUIElementCreateApplication(dockPid).children()?.first { try $0.role() == "AXList" }), let axList = (try AXUIElementCreateApplication(dockPid).children()?.first { try $0.role() == "AXList" }),
let axAppDockItem = (try axList.children()?.filter { try $0.subrole() == "AXApplicationDockItem" && ($0.appIsRunning() ?? false) }) { let axAppDockItem = (try axList.children()?.filter { try $0.subrole() == "AXApplicationDockItem" && ($0.appIsRunning() ?? false) }) {
try Applications.list.forEach { app in let axAppDockItemUrlAndLabel = try axAppDockItem.map { try ($0.attribute(kAXURLAttribute, URL.self), $0.attribute(kAXStatusLabelAttribute, String.self)) }
if app.runningApplication.activationPolicy == .regular, DispatchQueue.main.async {
let bundleId = app.runningApplication.bundleIdentifier, refreshBadges_(axAppDockItemUrlAndLabel)
let url = NSWorkspace.shared.urlForApplication(withBundleIdentifier: bundleId) { }
app.dockLabel = try axAppDockItem.first { try $0.attribute(kAXURLAttribute, URL.self) == url }?.attribute(kAXStatusLabelAttribute, String.self) }
} }
}
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 { private static func isActualApplication(_ app: NSRunningApplication) -> Bool {
+1 -2
View File
@@ -153,8 +153,7 @@ class Windows {
} }
static func refreshThumbnailsAsync(_ screen: NSScreen, _ currentIndex: Int = criticalFirstThumbnails) { static func refreshThumbnailsAsync(_ screen: NSScreen, _ currentIndex: Int = criticalFirstThumbnails) {
guard App.app.appIsBeingUsed else { return } if !App.app.appIsBeingUsed || Preferences.hideThumbnails { return }
if Preferences.hideThumbnails { return }
BackgroundWork.mainQueueConcurrentWorkQueue.async { BackgroundWork.mainQueueConcurrentWorkQueue.async {
if currentIndex < list.count { if currentIndex < list.count {
let window = list[currentIndex] let window = list[currentIndex]
+2
View File
@@ -264,5 +264,7 @@ class App: AppCenterApplication, NSApplicationDelegate {
thumbnailsPanel.show() thumbnailsPanel.show()
guard appIsBeingUsed else { return } guard appIsBeingUsed else { return }
Windows.refreshThumbnailsAsync(screen) Windows.refreshThumbnailsAsync(screen)
guard appIsBeingUsed else { return }
Applications.refreshBadges()
} }
} }
+14 -10
View File
@@ -135,16 +135,7 @@ class ThumbnailView: NSStackView {
spaceIcon.setNumber(element.spaceIndex, false) spaceIcon.setNumber(element.spaceIndex, false)
} }
} }
assignIfDifferent(&dockLabelIcon.isHidden, element.dockLabel == nil || Preferences.hideAppBadges || Preferences.iconSize == 0) updateDockLabelIcon(element.dockLabel)
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))
}
assignIfDifferent(&frame.size.width, max((Preferences.hideThumbnails ? hStackView.fittingSize.width : thumbnail.frame.size.width) + Preferences.intraCellPadding * 2, ThumbnailView.widthMin(screen)).rounded()) 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) assignIfDifferent(&frame.size.height, newHeight)
let fontIconWidth = CGFloat([fullscreenIcon, minimizedIcon, hiddenIcon, spaceIcon].filter { !$0.isHidden }.count) * (Preferences.fontHeight + Preferences.intraCellPadding) 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() { private func observeDragAndDrop() {
// NSImageView instances are registered to drag-and-drop by default // NSImageView instances are registered to drag-and-drop by default
thumbnail.unregisterDraggedTypes() thumbnail.unregisterDraggedTypes()