Repository navigation
Add optional snapping animations and a blurred snap preview - #1849
Conversation
| } | ||
| } | ||
|
|
||
| class FootprintAlphaDefault: Default { |
There was a problem hiding this comment.
Rather than making a new default subclass, you'll want to use the DoubleDefault class, which allows an explicit zero.
|
Thanks! This is great :) Looks like a merge conflict arose from another PR that I merged. Let me know if you need help resolving it. Also, if you don't mind, can you clean up some of the comments that are added in here, as it looks like some of them are more for train of thought understanding than necessary communication in the codebase? |
|
On this note, I've given this a lot of thought prior to the PR, and one of the ideas I had for mitigating the limitations from the Accessibility API is to overlay a blurred window owned by Rectangle, move the actual window off the screen via Accessibility, resize the blurred window with native animation, then place the window at its destination as the animation concludes. This has its own set of usability issues, and doesn't work great for windows that don't fit the destination rect, but it might be worth exploring. Figured I'd mention it if you feel inclined to explore that route as well - no worries if not. |
6e276b8 to
3575417
Compare
|
@rxhanson Hi, Ryan, Thanks for quick response@ |
|
One edge case that's not working right is when |
Yep, will look into this! |
0a7e457 to
a59cea0
Compare
|
@rxhanson Hi Ryan, the right/bottom size cycling issue is fixed. I also tried your blurred-window approach, so there are now two options: Direct Resize (default) and a blur preview. I’ve tested both across AppKit and browser windows comprehensively, including repeated commands, restore, size constraints, cross-display moves, and cancellation. Some edge cases like fast cross-display preview dragging still has some lag, so it remains experimental. Thanks for reviewing it! |
|
@rxhanson This PR is finalized. Please take a look. Thanks! |
|
This is pretty awesome to see. Thanks for fixing the cycle resize issue and for implementing the blur preview approach. I'll give the updated code one more look through tomorrow, but the experience is good and don't think there are any additional feature changes that need to be made. I might play around with the blur preview a little bit after merging, as I'm wondering if there might be some adjustments that could make it a little distracting. It would technically be possible to determine the window type based on where the stoplight buttons are, so as to match the corner radius and "copy" having the correct stoplight buttons present in a matching location. It also might be better to use a solid color window background instead of blur, but I'm not sure. I'm excited to merge this change in. Update: In using with the blur preview animation more, I think some acceleration would also help, on both moving the blur window and fading it out. Again, no pressure to make further changes, just some thoughts as I'm using it. Also, looks like another merged PR caused a conflict, but I don't mind resolving it. I'll hold off on merging anything else until this one goes in. |
Interpolate same-display resizing with a settling curve, preserve pending destinations for shortcut history, and let native dragging own position during size restoration. Respect Reduce Motion and keep existing mover fallbacks.
Use native blur with optional tint, a subtle outline, and an exterior shadow aligned at screen edges. Share the animation curve, respect reduced motion and transparency, and configure authored layers for SDR.
Add the two opt-in controls and their translations, and move haptic feedback into the left column.
Use Device Control and Data Access on macOS 27 and retain the earlier permission wording on older releases.
Only finish drag restoration on mouse-up when a window was actually being dragged. This prevents the drag monitor from prematurely settling a title-bar maximize or restore animation started by the same release event. Document that title-bar double-click uses the existing snap animation setting. Release build passed; live event ordering has not been reproduced.
Detect movement from current displayed bounds, preserve the original grab reference, and let restoration finish after mouse release. Add regression coverage and document the remaining far-right drag jumps.
Add native drag handoff, preview rendering, verified parking and recovery, and constrained cross-display placement. Preserve animated title-bar and command restoration while applying drag restoration immediately. Default new animation selections to Direct Resize, move Animate footprint to the left settings column, and expose the Blue preview label. Keep the existing repository tests compatible with the updated interfaces. New animation tests, native harnesses, visual fixtures and historical evidence are maintained only in the local rectangle-animation-tests skill, outside the repository. Rebase integration preserves upstream row/column tiling and alignment tolerance, shares its forceRefresh window-list API, and adapts its test fixture to position-aware frame writes. Validation: 395 repository tests and 810 isolated local-skill tests pass; universal Release builds successfully.
Correct final alignment of constrained windows and retry native restore sizes that overshoot. Resize IINA once and align after its aspect correction, falling back when saved-size restoration is not achieved. Validation: 844 tests, 33 final native layout cases, 16 repeated IINA transitions, and 6 installed-app checks. New tests and evidence remain in the local animation-test skill.
a440a9b to
9cce804
Compare
|
@rxhanson Just resolved the conflicts. Let's keep this version for now, and I'll keep an eye on the further optimization like acceleration as well! |
9cce804 to
ad16e87
Compare
This reverts commit b0b9dab.
40d33e0 to
723c135
Compare
|
I've been continuing to test the blur preview animation out and hit a snag where windows that show the window size warning have a lot of lag with their positioning (thanks for making that warning look nicer, by the way). The lag is painful enough, and it's a common enough scenario that I was thinking through a couple of options:
Since this PR is already pretty big, I'm leaning toward option 2, just so I can keep things moving forward, but am open to either path. Still working my way through the code. |
|
@rxhanson Hey, Ryan. Agree that we can split blur preview into another branch, removing from this PR, while keeping other changes. I can go ahead to do the split. Thanks for testing! |
729b786 to
edfd474
Compare
|
Thanks! I removed the markdown and the main.swift entry point, and added back in the @main entry point to the AppDelegate. I'm going to go back through the WindowManager changes with fresh eyes tomorrow morning and will merge then as long as I don't have anything I want to change there 👍 |
The test double overrides setFrame(_:adjustSizeFirst:), but AccessibilityElement.setFrame gained an adjustPosition parameter in "Add optional snapping animations and a blurred snap preview" (rxhanson#1849), so the override no longer matches and the test target does not compile: RectangleTests.swift:6153:23: error: method does not override any method from its superclass This is not related to the rest of the branch - it reproduces on a clean checkout - but the test target has to build before any of the tests can run.
* Keep a window's position when moving it to another display Moving a window to the next, previous or a specific display centered it on the destination, which loses the spot the user had put it in. DisplayTransfer works out each axis on its own from whether the window was against a screen edge: against both edges it follows both and spans the destination, against one it keeps its size and stays against that edge, against neither it keeps its size and its center keeps the same relative spot. The distance from an edge is carried over rather than flattened, so a window snapped with gaps arrives with the same gaps. This is now the default for next/previous and specific display moves. The old centering is available as centerOnDisplayChange, and attemptMatchOnNextPrevDisplay still replays the last Rectangle action where there is one. Closes #1666 * RectangleTests: match the current setFrame signature The test double overrides setFrame(_:adjustSizeFirst:), but AccessibilityElement.setFrame gained an adjustPosition parameter in "Add optional snapping animations and a blurred snap preview" (#1849), so the override no longer matches and the test target does not compile: RectangleTests.swift:6153:23: error: method does not override any method from its superclass This is not related to the rest of the branch - it reproduces on a clean checkout - but the test target has to build before any of the tests can run. * Center three-edge windows along the middle edge across orientations A window against three screen edges - spanning one axis and against one edge of the other, like a left half or a top half - was stretched along the whole of the spanning axis when it moved between a landscape and a portrait display, turning a left half into a tall sliver. It now keeps its size and is centered along the middle one of its three edges. Picking a corner instead would mean guessing from how the displays are arranged; centering makes no assumption. Keeping a window's position is now a setting, "Keep window position when moving across displays" in the Behavior tab, backed by keepWindowPositionOnDisplayChange. It is on by default. Turned off, display moves behave as they did before this branch: the window is centered, or with attemptMatchOnNextPrevDisplay on and no action to replay, mapped proportionally as in #1809. relativePositionedRect and its tests are restored for that path, and the centerOnDisplayChange terminal command is gone, since the setting replaces it.
This adds two options in Snap Areas, both off by default: Animate windows (experimental) and Blur footprint.
Snapping and restoring use smooth transitions, and the existing footprint animation follows the same easing curve. The blurred preview adapts to light and dark mode, with a subtle outline and outer shadow. Its tint uses the existing color and alpha preferences, defaulting to zero.
Animation remains experimental because repeatedly updating size and position may cause issues in some edge cases. Animations respect Reduce Motion, and blur respects Reduce Transparency.
This also balances the checkbox layout and updates the permission wording for macOS 27.