mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-28 17:31:19 +00:00
* feat(mac): Quick Chat v2 — enable toggle, agent avatars and switching, zoom entrance, window screenshots - Settings toggle (openclaw.quickChatEnabled) gating hotkey, menu item, recorder - agent chip renders avatar image (data URIs only; remote URLs deliberately not fetched to avoid SSRF), emoji, or tinted monogram; native NSMenu agent picker routes via canonical agent:<id>:<mainKey> or global+agentId per server contract - 'main session' capsule removed; placeholder carries the identity - fade+zoom presentation (96% scale in, 97% out) via frame+alpha animators - window screenshot picker: labeled overlays on renderable windows (Peekaboo filtering + z-order hit tests), overlays torn down pre-capture, SCK window capture, ChatImageProcessor JPEG, auto-send as chat.send attachment with the draft or a default caption; ownership-token pipeline bound to presentation and route; user-initiated Screen Recording alert; cancellable bounded discovery - ⌘Return opens the accepted route's session; global-scope agent threading is a filed follow-up; locale artifacts refreshed for new strings * chore(mac): regenerate i18n inventory after rebase onto main
29 lines
1.2 KiB
Swift
29 lines
1.2 KiB
Swift
import AppKit
|
|
|
|
enum QuickChatPlacement {
|
|
static func scaledRect(_ rect: NSRect, factor: CGFloat) -> NSRect {
|
|
let size = NSSize(width: rect.width * factor, height: rect.height * factor)
|
|
return NSRect(
|
|
x: rect.midX - (size.width / 2),
|
|
y: rect.midY - (size.height / 2),
|
|
width: size.width,
|
|
height: size.height)
|
|
}
|
|
|
|
static func barFrame(contentSize: NSSize, visibleFrame: NSRect) -> NSRect {
|
|
guard visibleFrame.width > 0, visibleFrame.height > 0 else { return .zero }
|
|
|
|
let size = NSSize(
|
|
width: min(max(0, contentSize.width), visibleFrame.width),
|
|
height: min(max(0, contentSize.height), visibleFrame.height))
|
|
let desiredTop = visibleFrame.maxY - (0.22 * visibleFrame.height)
|
|
let desiredOrigin = NSPoint(
|
|
x: visibleFrame.midX - (size.width / 2),
|
|
y: desiredTop - size.height)
|
|
let origin = NSPoint(
|
|
x: min(max(desiredOrigin.x, visibleFrame.minX), visibleFrame.maxX - size.width),
|
|
y: min(max(desiredOrigin.y, visibleFrame.minY), visibleFrame.maxY - size.height))
|
|
return NSRect(origin: origin, size: size)
|
|
}
|
|
}
|