Skip to content

Conversation

@AryanRogye
Copy link
Owner

No description provided.

@AryanRogye AryanRogye requested a review from Copilot September 12, 2025 20:25
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR enhances the screenshot functionality with screen-under-mouse detection and cropping support, creating a more "native screenshot feel" for multi-screen setups.

Key changes:

  • Modified screenshot provider protocol to support cropping rectangles
  • Moved cropping logic from AppCoordinator to ScreenshotService
  • Added comprehensive test coverage for screenshot functionality

Reviewed Changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
ComfyMarkTests/Screenshot/ScreenshotProviderTests.swift Comprehensive test suite covering basic functionality, edge cases, and concurrency scenarios
ComfyMarkTests/Screenshot/MockScreenshotProvider.swift Mock implementation with configurable behavior for testing
ComfyMarkTests/ComfyMarkTests.swift Removed old test file to consolidate testing structure
ComfyMark/Services/ScreenshotService.swift Added cropping parameter to protocol and moved pixel crop calculation logic
ComfyMark/Coordinators/SelectionOverlayCoordinator.swift Added screen detection and overlay recreation for different screens
ComfyMark/App/AppCoordinator.swift Refactored to use new cropping API and extracted coordinator configuration
ComfyMark.xcodeproj/project.pbxproj Updated project structure to include new test files

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Comment on lines +129 to +139
let image = await mockProvider.takeScreenshot()

XCTAssertNotNil(image)

// Test that we can create NSImage from CGImage
let nsImage = NSImage(cgImage: image!, size: NSSize(width: image!.width, height: image!.height))
XCTAssertNotNil(nsImage, "Should be able to create NSImage from CGImage")

// Test image data exists and has expected size
let expectedDataSize = image!.width * image!.height * 4 // 4 bytes per pixel (RGBA)
if let dataProvider = image!.dataProvider,
Copy link

Copilot AI Sep 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Force unwrapping is used multiple times on the same optional image. Consider using a guard statement or if-let binding to safely unwrap once and improve readability.

Suggested change
let image = await mockProvider.takeScreenshot()
XCTAssertNotNil(image)
// Test that we can create NSImage from CGImage
let nsImage = NSImage(cgImage: image!, size: NSSize(width: image!.width, height: image!.height))
XCTAssertNotNil(nsImage, "Should be able to create NSImage from CGImage")
// Test image data exists and has expected size
let expectedDataSize = image!.width * image!.height * 4 // 4 bytes per pixel (RGBA)
if let dataProvider = image!.dataProvider,
let imageOpt = await mockProvider.takeScreenshot()
guard let image = imageOpt else {
XCTFail("Image should not be nil")
return
}
// Test that we can create NSImage from CGImage
let nsImage = NSImage(cgImage: image, size: NSSize(width: image.width, height: image.height))
XCTAssertNotNil(nsImage, "Should be able to create NSImage from CGImage")
// Test image data exists and has expected size
let expectedDataSize = image.width * image.height * 4 // 4 bytes per pixel (RGBA)
if let dataProvider = image.dataProvider,

Copilot uses AI. Check for mistakes.
Comment on lines +129 to +139
let image = await mockProvider.takeScreenshot()

XCTAssertNotNil(image)

// Test that we can create NSImage from CGImage
let nsImage = NSImage(cgImage: image!, size: NSSize(width: image!.width, height: image!.height))
XCTAssertNotNil(nsImage, "Should be able to create NSImage from CGImage")

// Test image data exists and has expected size
let expectedDataSize = image!.width * image!.height * 4 // 4 bytes per pixel (RGBA)
if let dataProvider = image!.dataProvider,
Copy link

Copilot AI Sep 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Force unwrapping is used multiple times on the same optional image. Consider using a guard statement or if-let binding to safely unwrap once and improve readability.

Suggested change
let image = await mockProvider.takeScreenshot()
XCTAssertNotNil(image)
// Test that we can create NSImage from CGImage
let nsImage = NSImage(cgImage: image!, size: NSSize(width: image!.width, height: image!.height))
XCTAssertNotNil(nsImage, "Should be able to create NSImage from CGImage")
// Test image data exists and has expected size
let expectedDataSize = image!.width * image!.height * 4 // 4 bytes per pixel (RGBA)
if let dataProvider = image!.dataProvider,
let imageOpt = await mockProvider.takeScreenshot()
guard let image = imageOpt else {
XCTFail("Image should not be nil")
return
}
// Test that we can create NSImage from CGImage
let nsImage = NSImage(cgImage: image, size: NSSize(width: image.width, height: image.height))
XCTAssertNotNil(nsImage, "Should be able to create NSImage from CGImage")
// Test image data exists and has expected size
let expectedDataSize = image.width * image.height * 4 // 4 bytes per pixel (RGBA)
if let dataProvider = image.dataProvider,

Copilot uses AI. Check for mistakes.
Comment on lines +131 to +139
XCTAssertNotNil(image)

// Test that we can create NSImage from CGImage
let nsImage = NSImage(cgImage: image!, size: NSSize(width: image!.width, height: image!.height))
XCTAssertNotNil(nsImage, "Should be able to create NSImage from CGImage")

// Test image data exists and has expected size
let expectedDataSize = image!.width * image!.height * 4 // 4 bytes per pixel (RGBA)
if let dataProvider = image!.dataProvider,
Copy link

Copilot AI Sep 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Force unwrapping is used multiple times on the same optional image. Consider using a guard statement or if-let binding to safely unwrap once and improve readability.

Suggested change
XCTAssertNotNil(image)
// Test that we can create NSImage from CGImage
let nsImage = NSImage(cgImage: image!, size: NSSize(width: image!.width, height: image!.height))
XCTAssertNotNil(nsImage, "Should be able to create NSImage from CGImage")
// Test image data exists and has expected size
let expectedDataSize = image!.width * image!.height * 4 // 4 bytes per pixel (RGBA)
if let dataProvider = image!.dataProvider,
guard let image = image else {
XCTFail("Image should not be nil")
return
}
// Test that we can create NSImage from CGImage
let nsImage = NSImage(cgImage: image, size: NSSize(width: image.width, height: image.height))
XCTAssertNotNil(nsImage, "Should be able to create NSImage from CGImage")
// Test image data exists and has expected size
let expectedDataSize = image.width * image.height * 4 // 4 bytes per pixel (RGBA)
if let dataProvider = image.dataProvider,

Copilot uses AI. Check for mistakes.
Comment on lines +40 to +70
let width = max(0, Int(rect.width))
let height = max(0, Int(rect.height))

// Return nil for zero dimensions if that's your expected behavior
guard width > 0 && height > 0 else { return nil }

return makeTestImage(w: width, h: height)
}

private func makeTestImage(w: Int, h: Int) -> CGImage? {
// Handle zero or negative dimensions
guard w > 0 && h > 0 else { return nil }

let colorSpace = CGColorSpaceCreateDeviceRGB()
guard let ctx = CGContext(
data: nil,
width: w,
height: h,
bitsPerComponent: 8,
bytesPerRow: w * 4,
space: colorSpace,
bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue
) else { return nil }

// Create a more interesting test pattern instead of solid color
ctx.setFillColor(NSColor.systemBlue.cgColor)
ctx.fill(CGRect(x: 0, y: 0, width: w, height: h))

// Add some pattern to make images more distinguishable
ctx.setFillColor(NSColor.white.cgColor)
ctx.fill(CGRect(x: 0, y: 0, width: min(w, 10), height: min(h, 10)))
Copy link

Copilot AI Sep 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test case testZeroDimensionsCrop expects zero dimensions to potentially return an image with width/height of 0 or 1, but this guard statement always returns nil for zero dimensions, making the test assertions inconsistent with the implementation.

Suggested change
let width = max(0, Int(rect.width))
let height = max(0, Int(rect.height))
// Return nil for zero dimensions if that's your expected behavior
guard width > 0 && height > 0 else { return nil }
return makeTestImage(w: width, h: height)
}
private func makeTestImage(w: Int, h: Int) -> CGImage? {
// Handle zero or negative dimensions
guard w > 0 && h > 0 else { return nil }
let colorSpace = CGColorSpaceCreateDeviceRGB()
guard let ctx = CGContext(
data: nil,
width: w,
height: h,
bitsPerComponent: 8,
bytesPerRow: w * 4,
space: colorSpace,
bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue
) else { return nil }
// Create a more interesting test pattern instead of solid color
ctx.setFillColor(NSColor.systemBlue.cgColor)
ctx.fill(CGRect(x: 0, y: 0, width: w, height: h))
// Add some pattern to make images more distinguishable
ctx.setFillColor(NSColor.white.cgColor)
ctx.fill(CGRect(x: 0, y: 0, width: min(w, 10), height: min(h, 10)))
let width = Int(rect.width)
let height = Int(rect.height)
// Allow zero or one dimensions for test purposes
let safeWidth = max(0, width)
let safeHeight = max(0, height)
return makeTestImage(w: safeWidth, h: safeHeight)
}
private func makeTestImage(w: Int, h: Int) -> CGImage? {
// Allow zero or one dimensions for test purposes
let width = max(0, w)
let height = max(0, h)
// If both dimensions are zero, return nil (CGContext cannot create 0x0 images)
if width == 0 && height == 0 { return nil }
let colorSpace = CGColorSpaceCreateDeviceRGB()
guard let ctx = CGContext(
data: nil,
width: width,
height: height,
bitsPerComponent: 8,
bytesPerRow: max(1, width) * 4,
space: colorSpace,
bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue
) else { return nil }
// Create a more interesting test pattern instead of solid color
ctx.setFillColor(NSColor.systemBlue.cgColor)
ctx.fill(CGRect(x: 0, y: 0, width: width, height: height))
// Add some pattern to make images more distinguishable
ctx.setFillColor(NSColor.white.cgColor)
ctx.fill(CGRect(x: 0, y: 0, width: min(width, 10), height: min(height, 10)))

Copilot uses AI. Check for mistakes.
return try await captureScreen(screen, content: content, excludedApps: excludedApps)
let image = try await captureScreen(screen, content: content, excludedApps: excludedApps)

/// Get Clamped Pixel Rect
Copy link

Copilot AI Sep 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment uses incorrect grammar. Should be 'Get clamped pixel rect' (lowercase 'clamped').

Suggested change
/// Get Clamped Pixel Rect
/// Get clamped pixel rect

Copilot uses AI. Check for mistakes.
@AryanRogye AryanRogye requested a review from Copilot September 13, 2025 03:21
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Copilot reviewed 11 out of 11 changed files in this pull request and generated 1 comment.


Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Comment on lines +134 to +146
let nsImage = NSImage(cgImage: image!, size: NSSize(width: image!.width, height: image!.height))
XCTAssertNotNil(nsImage, "Should be able to create NSImage from CGImage")

// Test image data exists and has expected size
let expectedDataSize = image!.width * image!.height * 4 // 4 bytes per pixel (RGBA)
if let dataProvider = image!.dataProvider,
let data = dataProvider.data {
let actualDataSize = CFDataGetLength(data)
XCTAssertEqual(actualDataSize, expectedDataSize, "Image data size should match expected size")
} else {
XCTFail("Image should have valid data provider and data")
}
}
Copy link

Copilot AI Sep 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoid using force unwrapping with !. The image has already been verified as non-nil in the guard statement above, so this should use safe unwrapping.

Suggested change
let nsImage = NSImage(cgImage: image!, size: NSSize(width: image!.width, height: image!.height))
XCTAssertNotNil(nsImage, "Should be able to create NSImage from CGImage")
// Test image data exists and has expected size
let expectedDataSize = image!.width * image!.height * 4 // 4 bytes per pixel (RGBA)
if let dataProvider = image!.dataProvider,
let data = dataProvider.data {
let actualDataSize = CFDataGetLength(data)
XCTAssertEqual(actualDataSize, expectedDataSize, "Image data size should match expected size")
} else {
XCTFail("Image should have valid data provider and data")
}
}
if let image = image {
let nsImage = NSImage(cgImage: image, size: NSSize(width: image.width, height: image.height))
XCTAssertNotNil(nsImage, "Should be able to create NSImage from CGImage")
// Test image data exists and has expected size
let expectedDataSize = image.width * image.height * 4 // 4 bytes per pixel (RGBA)
if let dataProvider = image.dataProvider,
let data = dataProvider.data {
let actualDataSize = CFDataGetLength(data)
XCTAssertEqual(actualDataSize, expectedDataSize, "Image data size should match expected size")
} else {
XCTFail("Image should have valid data provider and data")
}
}

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants