SpinWin is an open source menu bar app to visually rotate any individual window. You can rotate / spin as many as you want one by one.
I was scrolling reels when one came on where the content creator suggested "turning the phone upside down" for a portion. I was sitting at my mac, and decided to see if I could find something that did this. To my surprise, nothing exists, so I decided to build it.
Turns out macOS doesn't provide any public API to do anything like this, so I wound up using the Accessibility API to move the target window offscreen, where it keeps rendering. Then we capture it's contents with ScreenCaptureKit, and display that on a transparent, borderless overlay window which has a CALayer to rotate it.
It's written in Swift, open source, MIT license, and signed/notarized.
Have fun - would love to hear your comments.
This reminds me of when wobbly windows were the big thing in linux. It was good plain fun back then, it seems fun again with this.
Drawing apps do regularly allow for canvas rotation, so I’m sure this’ll turn out to be useful for some class of application that I’m not considering.
Oh, like Sun's Project Looking Glass. https://www.youtube.com/watch?v=JXv8VlpoK_g
I think it’s apps that don’t implement the JPEG orientation tag correctly.
I’ve been building a window manger for macOS that involves hiding windows offscreen, but I’ve found AccessibilityKit clamps position writes at the screen edge, so I’ve had to settle for allowing a 1px-wide sliver (plus shadow) in the corner. Is that what you’re doing too, or did you find an alternative?
Same issue — I never found a way around the clamp. I park the window's top-left at (maxX - 1, maxY - 1) of the union of all displays' CGDisplayBounds, i.e. just inside the bottom-right corner of the whole arrangement. The clamp is much looser going off the bottom/right than up/left — pushing to something like (-30000, -30000) gets snapped back near the top-left and leaves a full-height sliver, whereas bottom-right leaves just the corner pixel (plus its shadow, which I also haven't beaten).
Since the target is derived from the union, a display disconnect or resolution change shrinks the desktop and the parked window pops back into view. I listen for display-config changes and re-apply the position.
Thanks for the corroboration. Something that apparently might be possible is using the private framework for Spaces to offload windows to a "holding Space"; I haven't tried it because it felt just a little too hacky for something I'm ideally hoping to turn into a commercial product, but it might be worth investigating depending on your use case.
Very handy.
For what?