mirror of
https://github.com/bitsycore/Allofit.git
synced 2026-10-06 21:07:27 +00:00
- Status bar: last search time, memory footprint, CPU use (highlighted when busy) and role, with a tooltip for peak memory, threads, index age, cache size and roots. Sampled every 2 s, redraws only the status bar; match count and search time live in a separate object so the table isn't re-rendered. - Background throttling: file changes are collected longer and open results refresh less often when Allofit isn't focused or no window is visible; sampling pauses when hidden. Showing a window applies pending changes at once. - Settings > Performance: the update delays (focused / another app focused / no window) and result refresh intervals, with an estimate of how soon a changed file appears and Restore Defaults. Defaults 2 s / 15 s / 1 min and 1 s / 5 s. - Drag rows as file URLs (like Finder) instead of a plain link, so browsers upload the file instead of navigating to it. - Canonicalize roots with realpath: roots under /tmp, /var or /etc never matched their own entries because Foundation strips /private.
84 lines
2.4 KiB
Swift
84 lines
2.4 KiB
Swift
import AppKit
|
|
import Combine
|
|
|
|
// AppActivity tracks how visible Allofit currently is, so background work
|
|
// can slow down when nobody is looking:
|
|
// - foreground: the app is frontmost and one of its windows is on screen
|
|
// - background: a window is on screen but another app has focus
|
|
// - hidden: no window is on screen (closed, minimized, fully covered,
|
|
// or the app is hidden)
|
|
// Windows report their own visibility through WindowVisibilityReporter.
|
|
@MainActor
|
|
final class AppActivity: ObservableObject {
|
|
|
|
// shared tracker for the whole app
|
|
static let shared = AppActivity()
|
|
|
|
// how visible the app is, from least to most
|
|
enum Level: Int, Comparable {
|
|
case hidden = 0
|
|
case background = 1
|
|
case foreground = 2
|
|
|
|
// ordering by visibility
|
|
static func < (inLhs: Level, inRhs: Level) -> Bool {
|
|
return inLhs.rawValue < inRhs.rawValue
|
|
}
|
|
}
|
|
|
|
// current visibility level
|
|
@Published private(set) var level: Level = .foreground
|
|
|
|
// windows (by reporter identity) currently on screen
|
|
private var visibleWindows = Set<ObjectIdentifier>()
|
|
// true while Allofit is the frontmost app
|
|
private var isAppActive = true
|
|
// app activation observers
|
|
private var cancellables: Set<AnyCancellable> = []
|
|
|
|
// starts following app activation / hiding
|
|
private init() {
|
|
isAppActive = NSApplication.shared.isActive
|
|
let vCenter = NotificationCenter.default
|
|
for vName in [NSApplication.didBecomeActiveNotification,
|
|
NSApplication.didResignActiveNotification,
|
|
NSApplication.didHideNotification,
|
|
NSApplication.didUnhideNotification] {
|
|
vCenter.publisher(for: vName)
|
|
.sink { [weak self] _ in
|
|
MainActor.assumeIsolated {
|
|
guard let vSelf = self else { return }
|
|
vSelf.isAppActive = NSApplication.shared.isActive && !NSApplication.shared.isHidden
|
|
vSelf.recompute()
|
|
}
|
|
}
|
|
.store(in: &cancellables)
|
|
}
|
|
}
|
|
|
|
// records whether the window identified by inId is on screen
|
|
func setWindow(_ inId: ObjectIdentifier, visible inVisible: Bool) {
|
|
if inVisible {
|
|
visibleWindows.insert(inId)
|
|
} else {
|
|
visibleWindows.remove(inId)
|
|
}
|
|
recompute()
|
|
}
|
|
|
|
// derives the level from the window set and the app's active state
|
|
private func recompute() {
|
|
let vLevel: Level
|
|
if visibleWindows.isEmpty || NSApplication.shared.isHidden {
|
|
vLevel = .hidden
|
|
} else if isAppActive {
|
|
vLevel = .foreground
|
|
} else {
|
|
vLevel = .background
|
|
}
|
|
if level != vLevel {
|
|
level = vLevel
|
|
}
|
|
}
|
|
}
|