fix: disable animations when opening Conjure windows

This commit is contained in:
2026-10-17 00:44:31 +02:00
parent 8766584fe3
commit 0f49209d95
4 changed files with 41 additions and 11 deletions
+1 -1
View File
@@ -44,7 +44,7 @@ Conjure searches the system and user Applications folders. Hover over a result t
Conjure runs without a Dock icon. Dismissing the launcher leaves it running; reopen it from Finder or use your configured global shortcut.
The launcher opens without a window animation; Settings is constructed only when needed, not before the launcher appears.
The launcher, emoji picker, and translation tool open immediately without window animations or content fades, including from global shortcuts. Shortcut destinations are prepared before the window appears. Settings is constructed only when needed, not before the launcher appears.
### Controls
@@ -132,6 +132,10 @@ final class LauncherWindowController: NSWindowController, NSWindowDelegate, NSSe
searchField.stringValue = ""
restorePosition()
updateResults()
if let command {
showCommand(command)
history.recordLaunch(of: Application(command: command))
}
window?.deminiaturize(nil)
showWindow(nil)
NSApp.activate()
@@ -140,10 +144,6 @@ final class LauncherWindowController: NSWindowController, NSWindowDelegate, NSSe
(window as? LauncherPanel)?.sampleNumberHints()
(searchField.currentEditor() as? NSTextView)?.insertionPointColor = SunsetPalette.accent
refreshApplications()
if let command {
showCommand(command)
history.recordLaunch(of: Application(command: command))
}
}
func toggle(command: Application.Command? = nil) {
@@ -869,7 +869,6 @@ final class LauncherWindowController: NSWindowController, NSWindowDelegate, NSSe
view.setAccessibilityHidden(true)
}
controller.view.translatesAutoresizingMaskIntoConstraints = false
controller.view.alphaValue = 0
content.addSubview(controller.view)
NSLayoutConstraint.activate([
controller.view.leadingAnchor.constraint(equalTo: content.leadingAnchor),
@@ -877,10 +876,6 @@ final class LauncherWindowController: NSWindowController, NSWindowDelegate, NSSe
controller.view.topAnchor.constraint(equalTo: searchField.bottomAnchor, constant: 16),
controller.view.bottomAnchor.constraint(equalTo: content.bottomAnchor),
])
NSAnimationContext.runAnimationGroup { context in
context.duration = NSWorkspace.shared.accessibilityDisplayShouldReduceMotion ? 0 : 0.18
controller.view.animator().alphaValue = 1
}
window?.makeFirstResponder(searchField)
}
}
+1 -1
View File
@@ -2,7 +2,7 @@
- the window should scroll with the current selection
- [x] make escape close the window that was opened, be it the application launcher, the emoji picker, or something else.
- clicking the "back" chevron should still take you back to the application launcher view though (as it does today).
- [ ] remove window open/fade in/transition animation when opening conjure from keybindings
- [x] remove window open/fade in/transition animation when opening conjure from keybindings
- this is already the case for the application launcher window.
- evidently not the case for the emoji picker (though it should be ubiquitous)
- [ ] add a notes app inspired by raycast notes
@@ -32,3 +32,38 @@ import Testing
#expect(!descendants(content).contains { $0 is NSCollectionView })
#expect(search.accessibilityLabel() == "Search applications, calculate, or convert units and currencies")
}
@Test(arguments: Application.Command.allCases, [true, false])
@MainActor func commandsAreFullyVisibleImmediately(_ command: Application.Command, _ fromShortcut: Bool) throws {
_ = NSApplication.shared
let suite = "ConjurePresentation.\(UUID().uuidString)"
let defaults = UserDefaults(suiteName: suite)!
defer { defaults.removePersistentDomain(forName: suite) }
let launcher = LauncherWindowController(
history: LaunchHistory(defaults: defaults, now: { Date(timeIntervalSinceReferenceDate: 12_000) }),
defaults: defaults)
let window = try #require(launcher.window)
defer { window.orderOut(nil) }
let content = try #require(window.contentView)
func descendants(_ view: NSView) -> [NSView] { [view] + view.subviews.flatMap(descendants) }
if fromShortcut {
launcher.toggle(command: command)
} else {
launcher.present()
let search = try #require(descendants(content).compactMap { $0 as? NSSearchField }.first)
search.stringValue = command.rawValue
launcher.controlTextDidChange(Notification(name: NSControl.textDidChangeNotification, object: search))
_ = launcher.control(search, textView: NSTextView(), doCommandBy: #selector(NSResponder.insertNewline(_:)))
}
let tool = try #require(content.subviews.first { view in
descendants(view).contains {
switch command {
case .emoji: $0 is NSCollectionView
case .translate: $0.accessibilityLabel() == "Japanese translation"
}
}
})
#expect(window.isVisible)
#expect(!tool.isHidden)
#expect(tool.alphaValue == 1)
}