-
Notifications
You must be signed in to change notification settings - Fork 0
Enable LMM selection in Lite code #16
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
jsonify
merged 6 commits into
main
from
claude/lmm-selection-ready-011CUzkdREDFVSEoUiw7pzXw
Nov 10, 2025
Merged
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
047b11e
feat: add custom target cursor for ClickIt Lite
claude 4697753
debug: add enhanced diagnostics for custom cursor loading
claude 708c88e
fix: locate resources in SPM bundle for custom cursor
claude 432b652
fix: copy SPM resource bundles to app bundle for custom cursor
claude a7999b8
fix: maintain custom cursor with continuous refresh timer
claude 97eec00
debug: add logging for click type in SimpleClickEngine
claude File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,166 @@ | ||
| // | ||
| // SimpleCursorManager.swift | ||
| // ClickIt Lite | ||
| // | ||
| // Manages custom cursor for ClickIt Lite application. | ||
| // | ||
|
|
||
| import AppKit | ||
| import SwiftUI | ||
|
|
||
| class SimpleCursorManager { | ||
|
|
||
| // MARK: - Singleton | ||
|
|
||
| static let shared = SimpleCursorManager() | ||
|
|
||
| // MARK: - Properties | ||
|
|
||
| private var customCursor: NSCursor? | ||
| private var originalCursor: NSCursor? | ||
| private var cursorUpdateTimer: Timer? | ||
| private var isCursorActive = false | ||
|
|
||
| // MARK: - Initialization | ||
|
|
||
| private init() { | ||
| setupCustomCursor() | ||
| } | ||
|
|
||
| // MARK: - Public Methods | ||
|
|
||
| /// Activates the custom target cursor system-wide | ||
| func activateCustomCursor() { | ||
| guard let customCursor = customCursor else { | ||
| print("❌ Custom cursor not available") | ||
| showDebugAlert("Cursor Failed", "Custom cursor could not be loaded. Check console for details.") | ||
| return | ||
| } | ||
|
|
||
| // Prevent double activation | ||
| if isCursorActive { | ||
| print("ℹ️ Custom cursor already active") | ||
| return | ||
| } | ||
|
|
||
| isCursorActive = true | ||
|
|
||
| // Store original cursor for potential restoration | ||
| originalCursor = NSCursor.current | ||
|
|
||
| // Set custom cursor immediately | ||
| customCursor.set() | ||
|
|
||
| // Keep re-setting the cursor on a timer to ensure it stays active | ||
| // This is needed because macOS resets cursor on window focus changes and other events | ||
| cursorUpdateTimer = Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { [weak self] _ in | ||
| guard let self = self, self.isCursorActive else { return } | ||
| self.customCursor?.set() | ||
| } | ||
|
|
||
| print("✅ Custom target cursor activated with continuous refresh") | ||
| // Optional: Uncomment to show success alert | ||
| // showDebugAlert("Cursor Active", "Custom target cursor has been activated") | ||
| } | ||
|
|
||
| /// Shows a debug alert (for development/debugging) | ||
| private func showDebugAlert(_ title: String, _ message: String) { | ||
| DispatchQueue.main.async { | ||
| let alert = NSAlert() | ||
| alert.messageText = title | ||
| alert.informativeText = message | ||
| alert.alertStyle = .informational | ||
| alert.addButton(withTitle: "OK") | ||
| alert.runModal() | ||
| } | ||
| } | ||
|
|
||
| /// Restores the default system cursor | ||
| func restoreDefaultCursor() { | ||
| isCursorActive = false | ||
|
|
||
| // Stop the cursor update timer | ||
| cursorUpdateTimer?.invalidate() | ||
| cursorUpdateTimer = nil | ||
|
|
||
| // Restore arrow cursor | ||
| NSCursor.arrow.set() | ||
|
|
||
| print("✅ Default cursor restored") | ||
| } | ||
|
|
||
| // MARK: - Private Methods | ||
|
|
||
| /// Finds the correct resource bundle for Swift Package Manager | ||
| private func findResourceBundle() -> Bundle { | ||
| // Strategy 1: Look for SPM resource bundle (swift run / debug builds) | ||
| if let bundleURL = Bundle.main.url(forResource: "ClickIt_ClickItLite", withExtension: "bundle"), | ||
| let resourceBundle = Bundle(url: bundleURL) { | ||
| print("✅ Found SPM resource bundle at: \(bundleURL.path)") | ||
| return resourceBundle | ||
| } | ||
|
|
||
| // Strategy 2: Look in Contents/Resources for packaged .app builds | ||
| if let resourcePath = Bundle.main.resourcePath, | ||
| let bundlePath = Bundle(path: resourcePath + "/ClickIt_ClickItLite.bundle") { | ||
| print("✅ Found resource bundle in app Resources: \(resourcePath)/ClickIt_ClickItLite.bundle") | ||
| return bundlePath | ||
| } | ||
|
|
||
| // Strategy 3: Try Module.bundle (for Xcode builds) | ||
| if let bundleURL = Bundle.main.url(forResource: "ClickItLite_ClickItLite", withExtension: "bundle"), | ||
| let resourceBundle = Bundle(url: bundleURL) { | ||
| print("✅ Found module resource bundle at: \(bundleURL.path)") | ||
| return resourceBundle | ||
| } | ||
|
|
||
| // Fallback to Bundle.main (resources might be directly in app bundle) | ||
| print("⚠️ Using Bundle.main as fallback") | ||
| return Bundle.main | ||
| } | ||
jsonify marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| private func setupCustomCursor() { | ||
| // Debug: Print bundle path | ||
| print("🔍 Bundle path: \(Bundle.main.bundlePath)") | ||
| print("🔍 Resource path: \(Bundle.main.resourcePath ?? "nil")") | ||
|
|
||
| // Find the correct resource bundle for Swift Package Manager | ||
| let bundle = findResourceBundle() | ||
| print("🔍 Using bundle: \(bundle.bundlePath)") | ||
|
|
||
| // Try to load the target image from resources | ||
| guard let imageURL = bundle.url(forResource: "target-64", withExtension: "png") else { | ||
| print("❌ Failed to find target-64.png in bundle") | ||
| print("🔍 Searched in: \(bundle.bundleURL)") | ||
|
|
||
| // Try to list all resources | ||
| if let resourcePath = bundle.resourcePath { | ||
| do { | ||
| let items = try FileManager.default.contentsOfDirectory(atPath: resourcePath) | ||
| print("📁 Available resources in bundle: \(items)") | ||
| } catch { | ||
| print("❌ Could not list resources: \(error)") | ||
| } | ||
| } | ||
| return | ||
jsonify marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| print("✅ Found image at: \(imageURL.path)") | ||
|
|
||
| guard let image = NSImage(contentsOf: imageURL) else { | ||
| print("❌ Failed to load NSImage from: \(imageURL.path)") | ||
| return | ||
| } | ||
|
|
||
| print("✅ NSImage loaded, original size: \(image.size)") | ||
|
|
||
| // Set the cursor size (64x64 pixels) | ||
| image.size = NSSize(width: 64, height: 64) | ||
|
|
||
| // Create cursor with hotspot at center (32, 32) | ||
| let hotspot = NSPoint(x: 32, y: 32) | ||
| customCursor = NSCursor(image: image, hotSpot: hotspot) | ||
jsonify marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| print("✅ Custom cursor created successfully") | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.