Repository navigation
Conversation
…— hover, touch, scroll pass-through, the pointer on LumosCanvasFrame; LumosInputPreview and the desktop recording - `Modifier.lumosPointer(tiltDegrees, onInput)` in :phosphor-lumos-compose: a Modifier.Node over SuspendingPointerInputModifierNode that reads the Final pass and never consumes. Mouse and stylus report on Enter/Move, NONE on Exit, pressed follows the button; touch reports Press/Move pressed and NONE on Release. A consumed change reports NONE and waits for every pointer to lift. The handler's finally reports NONE. A new lambda never restarts it. - The mapping inverts PixelLattice: x = 2px/w − 1, y = 1 − 2py/h, then un-tilted onto the front of the unit sphere. - `LumosCanvasFrame.pointer` (@transient, canvas px). `PixelLattice.project` takes an optional pointer, defaulting to the frame's input, and `canvasPointer` is the forward mapping, re-tilted and placed in the viewport. - `OrbStepper.setInput` hands the pointer to the source and lays the latest one over every frame projected after it, live, still or recorded; NONE clears a stale live pointer. `LumosDriver.setInput` / `onInput` wrap it. - `LumosOrb` carries the modifier on its Box and tells the source NONE when the driver is disposed (orb gone or source replaced). - `LumosInputPreview`: three interactive THINKING orbs — alone, centre, upper right. `LumosInputPreviewTest` writes the strip and a 3 s, 30 fps GIF of a scripted pointer sweep driven through LumosOrb with real pointer events. - `SteppedScene` gains `sendPointerEvent` and `sendTouch`. - README: the pointer section with a compiled `PointedCanvas` snippet. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
wow-miley
deleted the
miley/pho-83-t12-d-modifierlumospointer-and-the-lumosorb-plumbing-hover
branch
October 17, 2026 10:22
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Closes #153 (PHO-83). Builds on #175 (PHO-82, T12 · C).
What
Modifier.lumosPointer(tiltDegrees = 0f, onInput)in:phosphor-lumos-compose, for a consumer drawingLumosCanvasdirectly. AModifier.NodeoverSuspendingPointerInputModifierNode, so it is common to all six targets (onPointerEventis skiko-only). It readsPointerEventPass.Finaland never consumes.Enter/Moveset the pointer,ExitsendsNONE; a button press keeps the hover andpressedfollows the button.Press/Moveset the pointer withpressed = true,ReleasesendsNONE.NONE, then the handler waits for every pointer to lift.finallysendsNONE. A newonInputon recomposition updates the node without restarting the handler.x = 2·px/w − 1,y = 1 − 2·py/h, theny = sy·cos t + √(max(0, 1 − x² − sy²))·sin tfor a tilt.LumosCanvasFrame.pointer: Vector2?(@Transient, canvas px, Y down) for a material's light.PixelLattice.project(frame, pointer = frame.input?.pointer)carries it;PixelLattice.canvasPointeris the forward mapping, re-tilted and placed in the viewport, so the light lands on the voxel under the pointer.OrbStepper.setInputhands the pointer to the source and lays the latest one over every frame projected after it, live, still or recorded.NONEclears a stale pointer even on a live frame built before it left. A stepper never handed input leaves the frame's own pointer alone, so:phosphor-lumos-surfaceis unchanged.LumosDriver.setInputand a once-allocatedonInputwrap it.LumosOrbcarries the modifier on itsBoxwithconfig.tiltDegrees, and aDisposableEffect(driver)tells the sourceNONEwhen the orb leaves composition or its source is replaced. No frame is published for a pointer move alone, so a paused or reduced-motion orb draws nothing extra.LumosInputPreview: threeinteractiveTHINKING orbs — alone, pointed at the centre, pointed upper right — each settled under its pointer.PointedCanvassnippet, held to the quick start's rule byReadmeLumosQuickStartTest.Tests
./gradlew ktlintFormat :phosphor-lumos:jvmTest :phosphor-lumos-compose:jvmTest --offlineis green locally; goldens unchanged.PixelLatticePointerTest(lumos commonTest): the frame's pointer in px, override and clear, tilt matches the front voxel and keeps the rim on the rim, past-the-rim on the equatorial plane, viewport, aspect.OrbStepperTest:setInputgoes to the source and projects nothing by itself; the latest pointer lights live, still and recorded frames;NONEclears a stale live pointer; a stepper never handed input leaves the frame's own.LumosPointerMappingTest(compose commonTest): centre, corner, past the node, 30° tilt, and round trips throughPixelLattice.canvasPointertilted and untilted.LumosDriverTest:onInputreaches the source and lights the next frame in px.LumosOrbPointerTest(jvmTest, throughSteppedScene.sendPointerEvent/sendTouch): hover at the centre(0, 0)and top-left(−1, 1),Exit→NONE; a mouse button followspressedwithout ending the hover; touch press/release; an orb insideColumn(Modifier.verticalScroll(state))lets a touch drag scroll the column and reportsNONEonce the scroll takes over; removal reportsNONE; a 30° tilt maps the front centre toy = sin 30°.LumosInputPreviewTest: the strip tobuild/lumos-previews/lumos-input-strip.png, and the desktop recording — a scripted pointer sweep driven throughLumosOrbwith real pointer events on desktop Skia, 90 frames at 30 fps — tobuild/lumos-previews/lumos-input-repel.gif, written through a smalljavax.imageioGifWriter(test-only).Calls to review
OrbStepperkeeps the pointer rather thanLumosDriver, so the rule lives framework-free with the other time rules, and the pointer wins over the frame's own once set. The ticket put it on the driver.DisposableEffect(driver)inLumosOrbrather than by restarting the pointer handler on a key: the handler keeps running with the new lambda, and the old source getsNONE.Not done here
.context/.🤖 Generated with Claude Code