mirror of
https://github.com/bitsycore/Allofit.git
synced 2026-10-06 21:07:27 +00:00
- Resting the pointer 0.5 s on a cut-off name or path shows its full text (with highlights) in a click-through panel over the cell. It stays while hovered, updates in place when the list refreshes, and hides on move, exit, scroll, click or key press. Replaces AppKit's expansion tooltip, whose timing can't be set and which vanished when touched. - Holding Option alone freezes the results: background refreshes are held back (the index keeps updating) and applied once on release, keeping the scroll position. Typing, sorting and filtering still apply. Released automatically when the app deactivates. "Frozen" shows in the status bar. - README: current keyboard shortcuts, hover and Finder action. CHANGELOG: freeze key and hover overlay in 1.0.9.
59 lines
1.9 KiB
Swift
59 lines
1.9 KiB
Swift
import AppKit
|
|
|
|
// FreezeKey reports whether the "freeze" key (⌥ Option) is held down while
|
|
// Allofit is active. Holding it pauses the background refreshes of the
|
|
// results, so rows don't move while the user reads or selects them; typing,
|
|
// sorting and filtering still apply. Released (or the app deactivated), the
|
|
// lists catch up once.
|
|
@MainActor
|
|
final class FreezeKey: ObservableObject {
|
|
|
|
// shared state for every window
|
|
static let shared = FreezeKey()
|
|
|
|
// true while ⌥ Option is held in Allofit
|
|
@Published private(set) var isHeld = false
|
|
|
|
// modifier-change monitor, alive for the app's lifetime
|
|
private var monitor: Any?
|
|
// app activation observers
|
|
private var observers: [NSObjectProtocol] = []
|
|
|
|
// starts following the modifier keys
|
|
private init() {
|
|
monitor = NSEvent.addLocalMonitorForEvents(matching: .flagsChanged) { [weak self] vEvent in
|
|
MainActor.assumeIsolated {
|
|
self?.update(inFlags: vEvent.modifierFlags)
|
|
}
|
|
return vEvent
|
|
}
|
|
// a key released while another app was frontmost never reaches the
|
|
// local monitor: re-read the state on (de)activation
|
|
for vName in [NSApplication.didResignActiveNotification, NSApplication.didBecomeActiveNotification] {
|
|
observers.append(NotificationCenter.default.addObserver(forName: vName, object: nil, queue: .main) { [weak self] vNote in
|
|
MainActor.assumeIsolated {
|
|
if vNote.name == NSApplication.didResignActiveNotification {
|
|
self?.setHeld(false)
|
|
} else {
|
|
self?.update(inFlags: NSEvent.modifierFlags)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// held when Option is down on its own (shortcuts such as ⌥⌘C don't
|
|
// freeze the list)
|
|
private func update(inFlags: NSEvent.ModifierFlags) {
|
|
let vMods = inFlags.intersection([.command, .option, .control, .shift])
|
|
setHeld(vMods == [.option])
|
|
}
|
|
|
|
// publishes a change of state
|
|
private func setHeld(_ inHeld: Bool) {
|
|
if isHeld != inHeld {
|
|
isHeld = inHeld
|
|
}
|
|
}
|
|
}
|