From ece8a3e701218361f61c6e3053b394e623dd7b64 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sat, 13 Dec 2025 22:38:10 +0000 Subject: [PATCH] fix(macos): clamp web chat to visible frame --- apps/macos/Sources/Clawdis/WebChatSwiftUI.swift | 15 +++++++++++---- apps/macos/Sources/Clawdis/WebChatWindow.swift | 13 +++++++++---- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/apps/macos/Sources/Clawdis/WebChatSwiftUI.swift b/apps/macos/Sources/Clawdis/WebChatSwiftUI.swift index fedad318c..aee774eff 100644 --- a/apps/macos/Sources/Clawdis/WebChatSwiftUI.swift +++ b/apps/macos/Sources/Clawdis/WebChatSwiftUI.swift @@ -1113,11 +1113,18 @@ final class WebChatSwiftUIWindowController { } ?? NSScreen.main var frame = window.frame if let screen { - let minX = screen.frame.minX + WebChatSwiftUILayout.anchorPadding - let maxX = screen.frame.maxX - frame.width - WebChatSwiftUILayout.anchorPadding - frame.origin.x = min(max(round(anchor.midX - frame.width / 2), minX), maxX) + let bounds = screen.visibleFrame.insetBy( + dx: WebChatSwiftUILayout.anchorPadding, + dy: WebChatSwiftUILayout.anchorPadding) + + let desiredX = round(anchor.midX - frame.width / 2) let desiredY = anchor.minY - frame.height - WebChatSwiftUILayout.anchorPadding - frame.origin.y = max(desiredY, screen.frame.minY + WebChatSwiftUILayout.anchorPadding) + + let maxX = bounds.maxX - frame.width + let maxY = bounds.maxY - frame.height + + frame.origin.x = maxX >= bounds.minX ? min(max(desiredX, bounds.minX), maxX) : bounds.minX + frame.origin.y = maxY >= bounds.minY ? min(max(desiredY, bounds.minY), maxY) : bounds.minY } else { frame.origin.x = round(anchor.midX - frame.width / 2) frame.origin.y = anchor.minY - frame.height diff --git a/apps/macos/Sources/Clawdis/WebChatWindow.swift b/apps/macos/Sources/Clawdis/WebChatWindow.swift index b3c0a5ec5..48c377745 100644 --- a/apps/macos/Sources/Clawdis/WebChatWindow.swift +++ b/apps/macos/Sources/Clawdis/WebChatWindow.swift @@ -347,11 +347,16 @@ final class WebChatWindowController: NSWindowController, WKNavigationDelegate, N } ?? NSScreen.main if let screen { - let minX = screen.frame.minX + WebChatLayout.anchorPadding - let maxX = screen.frame.maxX - frame.width - WebChatLayout.anchorPadding - frame.origin.x = min(max(round(anchor.midX - frame.width / 2), minX), maxX) + let bounds = screen.visibleFrame.insetBy(dx: WebChatLayout.anchorPadding, dy: WebChatLayout.anchorPadding) + + let desiredX = round(anchor.midX - frame.width / 2) let desiredY = anchor.minY - frame.height - WebChatLayout.anchorPadding - frame.origin.y = max(desiredY, screen.frame.minY + WebChatLayout.anchorPadding) + + let maxX = bounds.maxX - frame.width + let maxY = bounds.maxY - frame.height + + frame.origin.x = maxX >= bounds.minX ? min(max(desiredX, bounds.minX), maxX) : bounds.minX + frame.origin.y = maxY >= bounds.minY ? min(max(desiredY, bounds.minY), maxY) : bounds.minY } else { frame.origin.x = round(anchor.midX - frame.width / 2) frame.origin.y = anchor.minY - frame.height