ai-startup-skills
创业公司做 AI 产品的 7 步 Agent Skill 合集:验证 → BP → 政策 → 路演 → 获客 → 定价 → 注册。
Translation pending
Use Figma on iPad as on a computer: Space + drag, ⌘ + scroll, right-click and keyboard shortcuts. Also GeForce NOW with mouse-look.
OtherSwift · JavaScriptGitHub @mattonikOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
iPad browser that adds the Pointer Lock API: a real mouse in Figma and GeForce NOW
Taken from the repository README
Loading the full README. The saved excerpt is shown below.
An iPad browser, built on the system WKWebView, that gives web pages a working
Pointer Lock API, so a mouse works the way it does on a computer. Safari and
WebKit on iPadOS don't implement pointer lock. Two kinds of service use it:Read the full README ↗An iPad browser, built on the system WKWebView, that gives web pages a working Pointer Lock API, so a mouse works the way it does on a computer. Safari and WebKit on iPadOS don't implement pointer lock. Two kinds of service use it:
play.geforcenow.com), for
mouse-look: aiming and looking around. Other browser-based services that
use pointer lock, such as Xbox Cloud Gaming, should work through ⋯ ▸ Open
URL, but haven't been tested and don't have a service profile yet.Website: icebear.digital/mouselook. The app is free to build from this repository, and is coming to the App Store as a €9.99 one-time purchase. To join the TestFlight beta, see the website.
Found a problem, or want another web app supported? Open an issue; ⋯ ▸ Settings ▸ Copy diagnostics gives the details that help most.
You can sideload it with Xcode; to build it under your own Apple ID, change
DEVELOPMENT_TEAM and PRODUCT_BUNDLE_IDENTIFIER in project.yml. The bundle
ID is sk.icebear.mouselook; the Xcode project and target are still called
PointerLocker. Copies installed before the bundle ID change are a separate app
with their own settings and sign-ins.
The original plan was to fork WebKit and enable its dormant pointer-lock code for iOS. That is months of work: builds that take hours, IPC plumbing, and losing JIT. This repo takes a shorter path that needs no WebKit changes. It connects three stock iPadOS APIs:
| Layer | How |
|---|---|
| Hide and freeze the system cursor | UIViewController.prefersPointerLocked (iPadOS 14+, the API native games use) |
| Raw, unbounded mouse deltas and buttons | GCMouse from GameController, which is what MouseLockPrototype validates |
| Pointer Lock API for the page | pointerlock-polyfill.js, injected at document start |
page: canvas.requestPointerLock()
└─► polyfill ──postMessage("lock")──► BrowserViewController
├─ prefersPointerLocked = true (cursor hidden)
└─ MouseBridge.isActive = true
GCMouse deltas/buttons/scroll ─► MouseBridge ─(1 batch per display frame)─►
evaluateJavaScript("__pointerLocker.batch([...])")
└─► polyfill dispatches pointermove/mousemove (movementX/Y),
pointerdown/mousedown/…/click, contextmenu, wheel on the locked element
What the polyfill provides:
Element.requestPointerLock(), which returns a Promise and accepts
options.document.exitPointerLock() and document.pointerLockElement.pointerlockchange and pointerlockerror, including the
document.onpointerlockchange = … form.movementX and movementY on events, and getCoalescedEvents().buttons bitmask and chording.navigator.platform. GeForce NOW checks it
there, so they need it too.It also reports navigator.maxTouchPoints = 0 and uses a Mac Safari 26.4 user
agent. From 26.4 on, GeForce NOW treats Safari as fully supported: it skips
the "partially supported on Safari" dialog and passes Esc straight to the
game. Without that, GeForce NOW detects the iPad and serves its touch/PWA
client, which never requests pointer lock. You can turn this off in the menu.
On a keyboard without Esc, use ⌘ + Delete to send Esc to the game (for menus). GeForce NOW maps that combination on Safari. You can also remap Caps Lock to Escape under Settings ▸ General ▸ Keyboard ▸ Hardware Keyboard ▸ Modifier Keys.
The lock is also released automatically when the page navigates or the app stops being full screen (Slide Over, Split View, a Stage Manager window). Switching apps, opening Control Center or a system alert only pauses the mouse: held buttons and keys are let go, and the lock is back when you return, without a click. If the page dropped the lock while the app was away, the app takes it back for the same element.
You need a Mac with Xcode 26 (the version CI uses) and XcodeGen.
brew install xcodegen
xcodegen # generates PointerLocker.xcodeproj
open PointerLocker.xcodeproj
project.yml signs with the IceBear s.r.o. team and sk.icebear.* bundle
IDs. To build with another account, change DEVELOPMENT_TEAM and the bundle
IDs there (or under Signing & Capabilities in Xcode) to your own.The ⋯ button in the bottom-left corner lists the services first (GeForce NOW, Figma): pick one to switch straight to it. Each service reopens the page you were last on, such as the open Figma file; a running game asks before you leave. Below that are Back, Reload, Home, Open URL and Settings…: switch service (with the setup guide), show the setup guide again, mouse sensitivity, invert Y-axis, microphone, browser identity, the debug overlay, service checks, and About (version, links to the website and this repository). The button hides while the pointer is locked.
Switching apps mid-game. iPadOS suspends an app within seconds of leaving it, which drops the stream, so leaving Mouselook mid-game can end the session. Mouselook pauses media when you leave. Earlier builds kept the app running in the background by playing silence; App Review doesn't allow that (guideline 2.5.4), so it was removed. docs/background-keep-alive.md has how it worked, in case it comes back in an allowed form.
Volume won't go to zero? If you allowed the microphone, WebKit uses the voice-call audio mode, in which iPadOS keeps a minimum volume. Set ⋯ ▸ Settings… ▸ Microphone ▸ Don't Allow if you don't need voice chat.
Stream resolution. On iPad, GeForce NOW defaults to 4:3 sizes such as 1112×834. Some games then fail to find a free server and report "at capacity" or "not available". Set GeForce NOW ▸ Settings ▸ Gameplay ▸ Streaming quality ▸ Custom ▸ Resolution to 1920×1080. The setting is saved with your account.
Figma. Pick Figma in onboarding (or ⋯ ▸ Settings… ▸ Switch service…) to use its design editor. Dragging a number's label scrubs the value without stopping at the screen edge, and Space + drag pans the canvas. The Figma profile presents as Chrome on a Mac, not Safari: Figma turns pointer lock off for scrubbing in Safari. Sign in with email and password.
The MouseLockPrototype scheme is milestone 1 from the brief. It's a bare GCMouse delta viewer. Run it first to confirm that your mouse gives smooth, unbounded deltas. Also check the sign of dY when you move the mouse up. Mouselook assumes up is positive, as GameController reports it. If vertical look comes out inverted, toggle Invert Y-axis.
Service checks. Mouselook watches for signs that a service changed how it treats this browser (GeForce NOW loading its iPad version, a game never asking for the mouse, Figma not locking while you scrub) and says so once per session. ⋯ ▸ Settings… ▸ Service checks shows the results; Copy diagnostics puts a report with the app, iPadOS and WebKit versions, the lock path and the last 200 events on the clipboard. Nothing leaves the iPad unless you paste it somewhere.
Turn on Debug overlay in ⋯ ▸ Settings…. The page reloads, and a small panel in the bottom right shows:
If page ● shows but system ○ doesn't, iPadOS refused the pointer lock. On
iPadOS 26 the app can open as a resizable window. Maximize it, because only a
full-screen app gets the lock.
isInspectable is on. On a Mac, open Safari ▸ Develop ▸ your iPad ▸
Mouselook to get the Web Inspector for the page. There you can check
window.__pointerLocker.isLocked and watch events arrive.
In the simulator, Debug builds also run a small remote console
(DebugBridge.swift), so you can script
the page from the Mac's terminal:
python3 tools/debug-bridge.py &
curl -s --data-binary 'return document.pointerLockElement?.id' localhost:8766/eval
Run everything CI runs on your Mac before pushing:
npm install # once
tools/test.sh # Swift unit tests on an iPad simulator + polyfill tests
tools/test.sh swift # or: js; extra arguments go to xcodebuild
Builds are incremental (derived data in build/), so repeat runs take
seconds. The Swift suite covers mouse batching, the mouse hub, service
profiles and categories, onboarding logic, page recovery and settings; the
polyfill is tested in headless Chromium by driving the same batch protocol
the native side uses.
CI (.github/workflows/build.yml) runs on every pull request, on merges to
main and on demand, as one Linux job for the polyfill and one macOS job that
builds and tests the app.
| Piece | What it does |
|---|---|
Services/ServiceProfile.swift | What's specific to one streaming service: home page, the browser identity the pages see, and how to tell that a session is running. |
Services/GeForceNowProfile.swift, Services/FigmaProfile.swift | One file per service: its profile and why it looks the way it does. Add another service as another file like these. |
Onboarding/ | Welcome, Choose your service and Get ready, shown on first launch and from Settings. |
Health/ | Service checks, the diagnostics log and the Copy diagnostics report. |
SettingsView.swift, Settings.swift | The Settings sheet and the values it saves. |
Resources/pointerlock-polyfill.js | Pointer Lock and Fullscreen APIs in the page. It applies the profile's identity, including inside Web Workers, and turns native input into DOM events. |
MouseBridge.swift | Raw GCMouse input to the page, one batch per frame, never more than one in flight. |
BrowserViewController*.swift | The web view and lock state (+Menu, +WebUI for popups, dialogs and permissions). |
PageRecovery.swift, StatusOverlayView.swift | Crashes, failed loads and going offline. |
DebugHUDFeeder.swift, Resources/debug-hud.js, DebugBridge.swift | The debug overlay, and the Mac-side JavaScript console (Debug builds only). |
PublicKeyCredential so sign-in pages offer another
method, and turns any WebAuthn request that still comes into an immediate
NotAllowedError plus a toast that says to choose another way, such as a
code from an authenticator app. The real fix would be the
com.apple.developer.web-browser entitlement, which requires Mouselook to
qualify as a default-browser app.event.isTrusted. Synthetic events have isTrusted === false. Tested
in the simulator (Sept 2026): GeForce NOW doesn't filter on it. Each
__pointerLocker.batch([["m",dx,dy]]) while locked becomes one message on
its input_channel_v1 data channel. If that ever changes, the fallback is the
WebKit-fork plan in docs/webkit-fork-plan.md,
which produces trusted events.Settings.swift.MouseBridge.wheelScale is a first guess and may need
tuning.Pull requests are welcome. Run tools/test.sh before pushing (CI runs the same
suites on every pull request). Contributions are accepted under the same
Apache 2.0 license as the rest of the code. For security problems, see
SECURITY.md.
The code is licensed under the Apache License 2.0. The name "Mouselook" and the app icon are not covered by the license: if you publish your own build, give it a different name and icon.