garage_auth, garage_entitlements, garage_iap and garage_ui, moved out of Garage-Services and Metro-Map-Maker into one public repo. MIT, one readme, docs under docs/. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013F4NWNvYcdeSgqbWMT1VQ7
59 lines
2.1 KiB
Swift
59 lines
2.1 KiB
Swift
import Cocoa
|
|
import FlutterMacOS
|
|
|
|
// Entry point Flutter calls into via RegisterGeneratedPlugins - this is what
|
|
// makes CursorLock and the eyedropper "just work" for any app that depends
|
|
// on garage_ui, without that app having to hand-wire the channels itself in
|
|
// its own MainFlutterWindow.swift. Used to be duplicated per-app, which is
|
|
// exactly how it silently went stale (renamed channel on one side, not the
|
|
// other) and why a brand new app (no Runner wiring at all) got a
|
|
// MissingPluginException out of the box.
|
|
public class GarageUiPlugin: NSObject, FlutterPlugin {
|
|
public static func register(with registrar: FlutterPluginRegistrar) {
|
|
let instance = GarageUiPlugin()
|
|
|
|
let cursorLockChannel = FlutterMethodChannel(
|
|
name: "garage/cursor_lock",
|
|
binaryMessenger: registrar.messenger
|
|
)
|
|
// CursorLock needs to hang on to the channel itself so it can push
|
|
// scrubDelta calls back to dart - see its own header for why a plain
|
|
// local var here isnt enough (it needs a home that outlives this fn)
|
|
CursorLock.shared.attach(channel: cursorLockChannel)
|
|
registrar.addMethodCallDelegate(instance, channel: cursorLockChannel)
|
|
|
|
let eyedropperChannel = FlutterMethodChannel(
|
|
name: "garage/eyedropper",
|
|
binaryMessenger: registrar.messenger
|
|
)
|
|
registrar.addMethodCallDelegate(instance, channel: eyedropperChannel)
|
|
}
|
|
|
|
public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
|
|
switch call.method {
|
|
case "lock":
|
|
CursorLock.shared.lock()
|
|
result(nil)
|
|
case "unlock":
|
|
CursorLock.shared.unlock()
|
|
result(nil)
|
|
case "isAvailable":
|
|
if #available(macOS 10.15, *) {
|
|
result(true)
|
|
} else {
|
|
result(false)
|
|
}
|
|
case "pick":
|
|
if #available(macOS 10.15, *) {
|
|
ScreenColorSampler.shared.show(result: result)
|
|
} else {
|
|
// dart reads nil as a cancel, which is close enough - it only ever
|
|
// asks for a pick after isAvailable said yes anyway
|
|
result(nil)
|
|
}
|
|
default:
|
|
result(FlutterMethodNotImplemented)
|
|
}
|
|
}
|
|
}
|