mirror of
https://github.com/samsonjs/Peekaboo.git
synced 2026-03-25 09:25:47 +00:00
🐛 Fix window capture to properly clip to app windows
Previously, window capture was falling back to fullscreen because it couldn't get window IDs. Now using window bounds (position + size) with screencapture's -R flag to properly capture only the app window content. Changes: - Use System Events to get window position and size - Build screencapture -R command with x,y,width,height - Added captureWindowByIndex for multi-window scenarios - Proper error handling with fallback to fullscreen This ensures AI analysis and screenshots only show the targeted app, not the entire desktop. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
e1da1b7319
commit
3515285897
1 changed files with 94 additions and 10 deletions
104
peekaboo.scpt
104
peekaboo.scpt
|
|
@ -804,16 +804,29 @@ on captureScreenshot(outputPath, captureMode, appName)
|
|||
-- Build screencapture command based on mode
|
||||
set screencaptureCmd to "screencapture -x"
|
||||
|
||||
if captureMode is "window" then
|
||||
if captureMode is "window" and appName is not "fullscreen" then
|
||||
-- IMPORTANT: Do NOT use -o -W flags as they require user interaction!
|
||||
-- Instead, get the window ID of the frontmost window programmatically
|
||||
-- Instead, capture the window using its bounds (position and size)
|
||||
try
|
||||
-- Get the window ID of the frontmost window of the frontmost app
|
||||
set windowID to do shell script "osascript -e 'tell application \"System Events\" to get the id of the first window of (first process whose frontmost is true)' 2>/dev/null"
|
||||
set screencaptureCmd to screencaptureCmd & " -l" & windowID
|
||||
on error
|
||||
-- Fallback to full screen if we can't get window ID
|
||||
my logVerbose("Could not get window ID, falling back to full screen capture")
|
||||
tell application "System Events"
|
||||
tell process appName
|
||||
set winPosition to position of window 1
|
||||
set winSize to size of window 1
|
||||
end tell
|
||||
end tell
|
||||
|
||||
set x to item 1 of winPosition
|
||||
set y to item 2 of winPosition
|
||||
set w to item 1 of winSize
|
||||
set h to item 2 of winSize
|
||||
|
||||
-- Use -R flag to capture a specific rectangle
|
||||
set screencaptureCmd to screencaptureCmd & " -R" & x & "," & y & "," & w & "," & h
|
||||
my logVerbose("Capturing window bounds for " & appName & ": " & x & "," & y & "," & w & "," & h)
|
||||
on error errMsg
|
||||
-- Fallback to full screen if we can't get window bounds
|
||||
my logVerbose("Could not get window bounds for " & appName & ", error: " & errMsg)
|
||||
my logVerbose("Falling back to full screen capture")
|
||||
end try
|
||||
end if
|
||||
|
||||
|
|
@ -852,6 +865,77 @@ on captureScreenshot(outputPath, captureMode, appName)
|
|||
end try
|
||||
end captureScreenshot
|
||||
|
||||
on captureWindowByIndex(outputPath, appName, winIndex)
|
||||
my logVerbose("Capturing window " & winIndex & " of " & appName & " to: " & outputPath)
|
||||
|
||||
-- Ensure output directory exists
|
||||
set outputDir to do shell script "dirname " & quoted form of outputPath
|
||||
if not my ensureDirectoryExists(outputDir) then
|
||||
return my formatErrorMessage("Directory Error", "Could not create output directory: " & outputDir, "directory creation")
|
||||
end if
|
||||
|
||||
-- Wait for capture delay
|
||||
delay captureDelay
|
||||
|
||||
-- Determine screenshot format
|
||||
set fileExt to my getFileExtension(outputPath)
|
||||
if fileExt is "" then
|
||||
set fileExt to defaultScreenshotFormat
|
||||
set outputPath to outputPath & "." & fileExt
|
||||
end if
|
||||
|
||||
-- Build screencapture command
|
||||
set screencaptureCmd to "screencapture -x"
|
||||
|
||||
-- Get window bounds for specific window
|
||||
try
|
||||
tell application "System Events"
|
||||
tell process appName
|
||||
set winPosition to position of window winIndex
|
||||
set winSize to size of window winIndex
|
||||
end tell
|
||||
end tell
|
||||
|
||||
set x to item 1 of winPosition
|
||||
set y to item 2 of winPosition
|
||||
set w to item 1 of winSize
|
||||
set h to item 2 of winSize
|
||||
|
||||
-- Use -R flag to capture a specific rectangle
|
||||
set screencaptureCmd to screencaptureCmd & " -R" & x & "," & y & "," & w & "," & h
|
||||
my logVerbose("Capturing window " & winIndex & " bounds: " & x & "," & y & "," & w & "," & h)
|
||||
on error errMsg
|
||||
-- Fallback to full screen if we can't get window bounds
|
||||
my logVerbose("Could not get bounds for window " & winIndex & ", error: " & errMsg)
|
||||
return my formatErrorMessage("Window Error", "Could not get bounds for window " & winIndex & " of " & appName, "window bounds")
|
||||
end try
|
||||
|
||||
-- Add format flag if not PNG (default)
|
||||
if fileExt is not "png" then
|
||||
set screencaptureCmd to screencaptureCmd & " -t " & fileExt
|
||||
end if
|
||||
|
||||
-- Add output path
|
||||
set screencaptureCmd to screencaptureCmd & " " & quoted form of outputPath
|
||||
|
||||
-- Capture screenshot
|
||||
try
|
||||
my logVerbose("Running: " & screencaptureCmd)
|
||||
do shell script screencaptureCmd
|
||||
|
||||
-- Verify file was created
|
||||
try
|
||||
do shell script "test -f " & quoted form of outputPath
|
||||
return outputPath
|
||||
on error
|
||||
return my formatErrorMessage("Capture Error", "Screenshot file was not created at: " & outputPath, "file verification")
|
||||
end try
|
||||
|
||||
on error errMsg
|
||||
return my formatErrorMessage("Capture Error", "Failed to capture window: " & errMsg, "screencapture")
|
||||
end try
|
||||
end captureWindowByIndex
|
||||
|
||||
on captureMultipleWindows(appName, baseOutputPath)
|
||||
-- Get detailed window status first
|
||||
set windowStatus to my getAppWindowStatus(appName)
|
||||
|
|
@ -915,8 +999,8 @@ on captureMultipleWindows(appName, baseOutputPath)
|
|||
my logVerbose("Could not focus window " & winIndex & ", continuing anyway")
|
||||
end try
|
||||
|
||||
-- Capture the frontmost window
|
||||
set captureResult to my captureScreenshot(windowOutputPath, "window", appName)
|
||||
-- Capture the specific window using a custom method
|
||||
set captureResult to my captureWindowByIndex(windowOutputPath, appName, winIndex)
|
||||
if captureResult starts with scriptInfoPrefix then
|
||||
-- Error occurred, but continue with other windows
|
||||
my logVerbose("Failed to capture window " & winIndex & ": " & captureResult)
|
||||
|
|
|
|||
Loading…
Reference in a new issue