feat: refine footer key badges and uninstall shortcuts

This commit is contained in:
2026-10-12 23:47:41 +02:00
parent 47aa757526
commit f0ab87e797
3 changed files with 62 additions and 16 deletions
+29 -10
View File
@@ -256,6 +256,7 @@ final class LauncherWindowController: NSWindowController, NSWindowDelegate, NSSe
openButton.action = #selector(openSelection)
openButton.isEnabled = false
actionsButton.isBordered = false
actionsButton.title = "Actions"
actionsButton.font = .systemFont(ofSize: 14, weight: .medium)
actionsButton.contentTintColor = SunsetPalette.text
actionsButton.keyEquivalent = "k"
@@ -266,14 +267,9 @@ final class LauncherWindowController: NSWindowController, NSWindowDelegate, NSSe
actionsButton.toolTip = "Actions for the selected application (Command-K)"
actionsButton.isEnabled = false
openButton.toolTip = "Open the selected application (Return). Use ↑ and ↓ to select."
let returnKey = NSTextField(labelWithString: "↵")
returnKey.font = .systemFont(ofSize: 14)
returnKey.textColor = SunsetPalette.secondaryText
returnKey.alignment = .center
returnKey.wantsLayer = true
returnKey.layer?.cornerRadius = 5
returnKey.layer?.borderWidth = 1
returnKey.setAccessibilityElement(false)
let returnKey = shortcutBadge("↵")
let commandKey = shortcutBadge("⌘")
let kKey = shortcutBadge("K")
let actionPill = NSVisualEffectView()
actionPill.material = .popover
@@ -281,7 +277,7 @@ final class LauncherWindowController: NSWindowController, NSWindowDelegate, NSSe
actionPill.state = .active
roundMaterialCorners(actionPill, radius: 18)
actionPill.layer?.borderWidth = 0.5
for view in [openButton, returnKey, actionsButton] {
for view in [openButton, returnKey, actionsButton, commandKey, kKey] {
view.translatesAutoresizingMaskIntoConstraints = false
actionPill.addSubview(view)
}
@@ -320,7 +316,11 @@ final class LauncherWindowController: NSWindowController, NSWindowDelegate, NSSe
openButton.centerYAnchor.constraint(equalTo: actionPill.centerYAnchor),
returnKey.leadingAnchor.constraint(equalTo: openButton.trailingAnchor, constant: 8),
actionsButton.leadingAnchor.constraint(equalTo: returnKey.trailingAnchor, constant: 14),
actionsButton.trailingAnchor.constraint(equalTo: actionPill.trailingAnchor, constant: -14),
commandKey.leadingAnchor.constraint(equalTo: actionsButton.trailingAnchor, constant: 8),
commandKey.centerYAnchor.constraint(equalTo: actionPill.centerYAnchor),
kKey.leadingAnchor.constraint(equalTo: commandKey.trailingAnchor, constant: 4),
kKey.centerYAnchor.constraint(equalTo: actionPill.centerYAnchor),
kKey.trailingAnchor.constraint(equalTo: actionPill.trailingAnchor, constant: -12),
actionsButton.centerYAnchor.constraint(equalTo: actionPill.centerYAnchor),
returnKey.centerYAnchor.constraint(equalTo: actionPill.centerYAnchor),
returnKey.widthAnchor.constraint(equalToConstant: 18),
@@ -699,3 +699,22 @@ func roundMaterialCorners(_ view: NSVisualEffectView, radius: CGFloat) {
view.layer?.masksToBounds = true
view.maskImage = mask
}
@MainActor
func shortcutBadge(_ title: String) -> NSTextField {
let badge = NSTextField(labelWithString: title)
badge.font = .systemFont(ofSize: 14)
badge.textColor = SunsetPalette.secondaryText
badge.alignment = .center
badge.wantsLayer = true
badge.layer?.cornerRadius = 5
badge.layer?.borderWidth = 1
badge.layer?.borderColor = SunsetPalette.secondaryText.withAlphaComponent(0.35).cgColor
badge.setAccessibilityElement(false)
badge.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
badge.widthAnchor.constraint(equalToConstant: 18),
badge.heightAnchor.constraint(equalToConstant: 18)
])
return badge
}
@@ -86,8 +86,11 @@ final class UninstallReviewController: NSViewController, NSSearchFieldDelegate,
remove.target = self
remove.action = #selector(confirmUninstall)
remove.contentTintColor = .systemRed
remove.bezelStyle = .rounded
remove.isBordered = false
remove.font = .systemFont(ofSize: 14, weight: .medium)
remove.keyEquivalent = "\r"
remove.keyEquivalentModifierMask = .command
remove.toolTip = "Confirm uninstall (Command-Return). Return toggles the highlighted file."
remove.isEnabled = false
table.addTableColumn(NSTableColumn(identifier: NSUserInterfaceItemIdentifier("file")))
table.headerView = nil
@@ -107,7 +110,31 @@ final class UninstallReviewController: NSViewController, NSSearchFieldDelegate,
scroll.autohidesScrollers = true
scroll.drawsBackground = false
scroll.contentView.drawsBackground = false
let footer = NSStackView(views: [NSView(), remove])
let pill = NSVisualEffectView()
pill.material = .popover
pill.blendingMode = .withinWindow
pill.state = .active
roundMaterialCorners(pill, radius: 18)
pill.layer?.borderWidth = 0.5
pill.layer?.borderColor = SunsetPalette.accent.withAlphaComponent(0.35).cgColor
pill.layer?.backgroundColor = SunsetPalette.accent.withAlphaComponent(0.08).cgColor
let commandKey = shortcutBadge("⌘")
let returnKey = shortcutBadge("↵")
for child in [remove, commandKey, returnKey] {
child.translatesAutoresizingMaskIntoConstraints = false
pill.addSubview(child)
}
NSLayoutConstraint.activate([
pill.heightAnchor.constraint(equalToConstant: 36),
remove.leadingAnchor.constraint(equalTo: pill.leadingAnchor, constant: 14),
remove.centerYAnchor.constraint(equalTo: pill.centerYAnchor),
commandKey.leadingAnchor.constraint(equalTo: remove.trailingAnchor, constant: 8),
commandKey.centerYAnchor.constraint(equalTo: pill.centerYAnchor),
returnKey.leadingAnchor.constraint(equalTo: commandKey.trailingAnchor, constant: 4),
returnKey.centerYAnchor.constraint(equalTo: pill.centerYAnchor),
returnKey.trailingAnchor.constraint(equalTo: pill.trailingAnchor, constant: -12)
])
let footer = NSStackView(views: [NSView(), pill])
footer.orientation = .horizontal
footer.spacing = 12
for view in [header, status, scroll, footer] {
@@ -132,7 +159,7 @@ final class UninstallReviewController: NSViewController, NSSearchFieldDelegate,
footer.leadingAnchor.constraint(equalTo: search.leadingAnchor),
footer.trailingAnchor.constraint(equalTo: search.trailingAnchor),
footer.bottomAnchor.constraint(equalTo: content.bottomAnchor, constant: -16),
footer.heightAnchor.constraint(equalToConstant: 32)
footer.heightAnchor.constraint(equalToConstant: 36)
])
}
@@ -159,7 +186,7 @@ final class UninstallReviewController: NSViewController, NSSearchFieldDelegate,
switch selector {
case #selector(NSResponder.moveDown(_:)): moveSelection(1)
case #selector(NSResponder.moveUp(_:)): moveSelection(-1)
case #selector(NSResponder.insertNewline(_:)): confirmUninstall()
case #selector(NSResponder.insertNewline(_:)): toggleHighlighted()
case #selector(NSResponder.cancelOperation(_:)): goBack()
default: return false
}
@@ -390,7 +417,7 @@ private final class UninstallFilesTable: NSTableView {
var toggle: (() -> Void)?
var dismiss: (() -> Void)?
override func keyDown(with event: NSEvent) {
if event.keyCode == 49 { toggle?() }
if [36, 76, 49].contains(event.keyCode), event.modifierFlags.intersection([.command, .option, .control]).isEmpty { toggle?() }
else if event.keyCode == 53 { dismiss?() }
else { super.keyDown(with: event) }
}