lwouis / alt-tab-macos

Windows alt-tab on macOS
https://alt-tab-macos.netlify.app
GNU General Public License v3.0
10.59k stars 322 forks source link

Thumbnails are tilted/skewed with Stage Manager enabled #1731

Open Tnixc opened 2 years ago

Tnixc commented 2 years ago

Describe the bug The window preview is warped, as it is taking it from stage manager.

Screenshots / video SCR-20220624-lvh

SCR-20220624-lst SCR-20220624-lzu

Add screenshots to help explain your problem. You can also use Loom to easily record your screen to show the bug in action. That is really helpful!

Steps to reproduce the bug

  1. Turn on stage manager
  2. Open a few windows
  3. See the previews

Selecting windows with that preview works and interacts with stage manager to switch to that scene, it is just the preview that isn't working.

lwouis commented 2 years ago

Hi,

I haven't played with macOS 13 yet. I have no idea how Stage Manager works and interacts with the OS in general.

AltTab's behavior seems correct on your screenshots. If macOS is actually warping and miniaturizing the windows to the left of the screen, then it's very possible that the screenshots we get from the system API is of a warped window. There may be nothing we can do about this.

I'll investigate further in the future when I look at macOS 13.

Tnixc commented 2 years ago

I believe nothing much can be done here, as it is still in very early stages and other window managers like yabai think that the window is still there, and repositions other windows as such even though you can't see the windows. Maybe a feature which hides the windows in stage manager can be implemented in the future.

XInTheDark commented 2 years ago

I haven't played with macOS 13 yet. I have no idea how Stage Manager works and interacts with the OS in general.

TBH, a lot of macOS 13's features are either useless or broken; that's why I have not upgraded yet. Despite everyone praising Stage Manager so much, I have no idea why Mission Control and AltTab cannot do the same job.

Tnixc commented 2 years ago

I haven't played with macOS 13 yet. I have no idea how Stage Manager works and interacts with the OS in general.

TBH, a lot of macOS 13's features are either useless or broken; that's why I have not upgraded yet. Despite everyone praising Stage Manager so much, I have no idea why Mission Control and AltTab cannot do the same job.

I totally agree. It seems like stage manager is really useless because you can just create more spaces for windows.

No too significant changes

XInTheDark commented 2 years ago

No too significant changes

The most important change for me is the Clock and Weather apps 🤣🤣

CBDAN commented 1 year ago

is there any update about the possibility to fix this issue?

GP2P commented 1 year ago

Suggestion for a potential fix: detect when the screenshot from system API became small, display the last screenshot retrieved. If, there is no way, to tell if Stage Manager is enabled && a window switch happened, which I believe there's a way to do.

lwouis commented 1 year ago

I was able to play with Ventura today for the first time. The window is actually transformed to be small and titled. So the OS gives us a small and tilted screenshot when we request it. Nothing we can do about that. I'll also note that when you stack many windows in the Stage Manager stacks, after 3, they become invisible visually in the stack (you only see the top 3, with decreasing opacity). That is, the OS returns us no screenshot at all.

We could indeed cache screenshots, and show old screenshots of minimized windows. This has limitations though, like what if AltTab is launched after the window has been minimized, or the window starts minimized, or there is an update on the window, etc. Breaking the sync between the OS and AltTab has downsides, like showing a titled miniature.

I think we can just keep things as they are to be honest. Stage Manager users can disable it and get the old "minimized-in-the-Dock" behavior. Which itself had limitations already as sometimes macOS doesn't render dock-minimized windows, and thus AltTab can't. And other details that would be too long to list.

I'm closing this ticket as I don't see any good solution there. Feel free to add one if you have a breakthrough, and I'll re-open the ticket.

ElhemEnohpi commented 1 year ago

I'd encourage you to report the problem to Apple, if possible. AltTab is quite popular, and Stage Manager breaking it is a shame. Maybe they'll listen to you, as a developer, and make some adjustments, since it's still a very new feature. I don't want to have to choose between the two!

lwouis commented 1 year ago

I've reported issues to Apple in the past, and they never replied. I know of several macos developers who also don't believe it's worth the effort to file a ticket. It's unfortunate. Feel free to report the issue on your side. If many people do it, they may notice.

CBDAN commented 1 year ago

I am afraid that Apple couldn’t care less about an app distributed outside the App Store and that competes with a macOS feature.

A possible fix could be writing the app such that - when the user presses alt-tab or the equivalent shortcut - it:

1) detects whether or not Stage Manager is on 2) turns off Stage Manager if it is on 3) requests screenshots of all windows to the OS 4) opens Alt Tab switcher 5) turns on Stage Manager again

I was able to reproduce steps 2,4,5 with an automation and the process runs smoothly, but not step 3, so previews were still broken.

I don't know if it is worth the effort but it is an idea.

lwouis commented 1 year ago

I don't think toggling Stage Manager is possible without disrupting the user. First there is probably a delay, with animations, and it's visible to the user. Second, it would probably break things, one way or another, to toggle it. I can't imagine it happens transparently and seamlessly.

what i can imagine is a dialog that we would open to inform the user that thumbnails are skewed if they keep it activated, and recommend to turn it off for normal thumbnails.

lwouis commented 1 year ago

I observed that if there is a window overlapping the Stage Manager area, Stage Manager's thumbnails will be displayed straight (i.e. not tilted/skewed):

https://user-images.githubusercontent.com/106195/198880231-426f706a-79e2-446d-ac8b-42e5c3e75eae.mov

We could thus imagine a workaround where AltTab creates an invisible window, and moves it to the side of the screen, to force that behavior. There would be lots to consider:

Furthermore, it may confuse the user that Space Manager is not tilted, thus takes more screen real estate.

I think it would be pretty intrusive, like toggling it every time.

I'm re-opening this ticket, so that we can discuss and try to think of workarounds, because Space Manager will be with us for a while, and its presence is really damaging to AltTab's users. They get terrible thumbnails, or no thumbnail at all when an app has more than 3 windows.

ElhemEnohpi commented 1 year ago

Also if you click on the app's icon in the Stage Manager, you see all the windows, and they're not tilted. If you then invoke AltTab, you get non-tilted thumbnails, and for all the windows. However, it's not only that they're tilted, but they're small and distorted, so un-tilting them is not that big of an improvement, maybe not really worth the effort. I think for me, some kind of caching might be better, though I understand there are limitations of that. Mostly I use it with Firefox. I wouldn't care if the window changed somehow, and the thumbnail wasn't updated. But ideally, Apple will eventually provide a way to get a normal screenshot.

I'll keep using AltTab, even if the thumbnails aren't really discernable, for now I'll probably just hide them. I can still see the window titles, and it lets me use keyboard commands, especially switching between the two most recent windows with one keystroke.

GP2P commented 1 year ago

I observed that if there is a window overlapping the Stage Manager area, Stage Manager's thumbnails will be displayed straight (i.e. not tilted/skewed):

Stage.Manager.thumbnails.tilting.mov We could thus imagine a workaround where AltTab creates an invisible window, and moves it to the side of the screen, to force that behavior. There would be lots to consider:

As a sidenote, this behavior happens only when a window is covering Stage Manager && you have mouse over Stage Manager. So, to do this you'll need to move the mouse position which, although you can move back, might distort some applications that listens to the mouse position

Having the Stage Manager un-tilt while user is holding alt+tab doesn't sound too bad to me though

GP2P commented 1 year ago

https://user-images.githubusercontent.com/73323107/198887677-bc321f9c-db37-4b6d-83a5-df70df36137b.mp4

Another recommendation is to check out what OBS is doing - Steps:

  1. create a macOS Screen Capture source
  2. Select window capture
  3. Select a window that's currently in Stage Manager
  4. OBS will show nothing
  5. Switch to that window
  6. OBS will be minimized to the side, but you still can see it update: It is able to capture the window
  7. Switch back to OBS
  8. The window will be minimized to the side, but OBS still keeps a shot of it while it was last in focus

The Cache in point 8 could be an macOS Screen Capture feature, or an OBS feature. If I remember correctly Apple went into OBS's code and created the whole macOS Screen Capture thing, so looking at how they did it there might be helpful.

(iirc, before their 28.0 update OBS mac was using screenshots to record the screen, now they use this new ScreenCaptureKit Framework thing)

Using this method would mean:

  1. Minimized windows contents don't update in preview from they were last opened
  2. Windows that were never opened/in focus would show up being empty, which can be ignored or prevented by taking a screenshot of the window
lwouis commented 1 year ago

@GP2P I tried OBS. It has a deprecated window capture source, and the new one you mention:

So yes, they are caching. It has the downside of not showing the latest state of the window, which can be an issue in some scenarios. It has the very large downside of not showing anything, if there was no opportunity to screenshot/cache yet. You wrote:

Windows that were never opened/in focus would show up being empty, which can be ignored or prevented by taking a screenshot of the window

I don't understand what you mean here. What API/technique would you use here to "take a screenshot". AltTab already uses a private API to "take a screenshot". That's how we get all the thumbnails. We take a full-size screenshot, then resize it down to a thumbnail. I've spend 2 years exploring all possible ways to capture window screenshots. I don't see a better way than what we are doing currently.

As far as I understand macOS, the windows being minimized is not a trick. The OS is actually resizing the window to a small size, and tilting it. It's not a clone or a widget or some trick. The actual window exists as a small tilted window. So no API would be able to provide a screenshot of it that's not small and tilted. That's my guess, but I would love to be wrong.

See also #122 regarding ScreenCaptureKit. Unfortunately, it's not useful to us.

XInTheDark commented 1 year ago

I'm re-opening this ticket, so that we can discuss and try to think of workarounds, because Space Manager will be with us for a while, and its presence is really damaging to AltTab's users. They get terrible thumbnails, or no thumbnail at all when an app has more than 3 windows.

Agreed! Adding Stage Manager support to AltTab is a necessity. Although from what I've heard online, most macOS Ventura users do not use the Stage Manager feature :)

XInTheDark commented 1 year ago

As far as I understand macOS, the windows being minimized is not a trick. The OS is actually resizing the window to a small size, and tilting it. It's not a clone or a widget or some trick. The actual window exists as a small tilted window. So no API would be able to provide a screenshot of it that's not small and tilted.

Currently for 'normal' minimized windows, does the thumbnail exist as a clone? So the original window still exists, and that is how AltTab captures the screenshot?

XInTheDark commented 1 year ago

We could thus imagine a workaround where AltTab creates an invisible window, and moves it to the side of the screen, to force that behavior.

That could possibly be an option in the Preferences, exclusive to macOS Ventura users. At least it's a temporary workaround to the problem 😄

lwouis commented 1 year ago

Currently for 'normal' minimized windows, does the thumbnail exist as a clone? So the original window still exists, and that is how AltTab captures the screenshot?

No i think it's also the window being resized. But somehow the OS API returns the full size screenshot. With Stage Manager, the APIs return a small screenshot, in addition to it being tilted.

That could possibly be an option in the Preferences, exclusive to macOS Ventura users. At least it's a temporary workaround to the problem 😄

It would be too complex, and it wouldn't solve:

I thought we could show some big dialog offering the user to disable Stage Manager, when they launch AltTab. Then they could decide to either do that, or launch AltTab regardless and deal with the bad thumbnails. Maybe that's the best UX? It's also the less hacky approach, and is being straight-forward with the user with the issue.

XInTheDark commented 1 year ago

I thought we could show some big dialog offering the user to disable Stage Manager, when they launch AltTab. Then they could decide to either do that, or launch AltTab regardless and deal with the bad thumbnails.

Yes, I agree. This issue is quite annoying though. It seems that Apple did not make the new API properly.

ElhemEnohpi commented 1 year ago

If you turn off the display of the tilted thumbnails in Stage Manager settings, by toggling the "Recent applications" switch off, then you get normal, full-sized thumbnails in AltTab. But they don't appear until you switch to the window at least once. It's very similar to the caching described above. But you have to make sure you don't hit alt-tab while you have the mouse over the Stage Manager area and the tilted thumbnails showing.

XInTheDark commented 1 year ago

If you turn off the display of the tilted thumbnails in Stage Manager settings, by toggling the "Recent applications" switch off, then you get normal, full-sized thumbnails in AltTab. But they don't appear until you switch to the window at least once.

That's an interesting observation. It seems that the API we use caches the thumbnails then...?

lwouis commented 1 year ago

I don't think there is caching going on. I think the OS decides to draw the windows, or not, and we get the pixels, or not.

I tried to turn off "Recent applications" and indeed the thumbnails on the right-side are not skewed. However, they are no longer drawn when not visible. This means AltTab shows the latest version. I think it's the not the latest version cached, but simply that the OS hasn't updated the window yet. Then showing the window or its thumbnail resumes drawing at the monitor's refresh rate. It would be interesting to make a test app, override the draw method on the NSView, and log everytime its called. It might give us the bottomline on what the OS is doing.

In any case, Stage Manager, in any state you can configure it in, is degrading the experience of using AltTab.

At the moment I can only imagine a workaround of showing some kind of UI to the user, to let them know this issue, and to explain that they could turn either SM off.

It would be nice if someone wants to test the other screenshot API to see if they also return the skewed/small screenshots like the private API AltTab currently use. I would bet that they return the same screenshots, but we never know until we confirm through experimentation.

decodism commented 1 year ago

Rotation can be disabled with the EnableStrip3DTransform hidden default but the resolution remains low.

List of defaults ``` defaults write com.apple.WindowManager AbsoluteMinimumItemHeight -float defaults write com.apple.WindowManager AnimationSpeed -float defaults write com.apple.WindowManager AppIconHoverScaleDistance -float defaults write com.apple.WindowManager AppIconShadowBlurRadius -float defaults write com.apple.WindowManager AppIconSize -float defaults write com.apple.WindowManager AppIconVariantSize -float defaults write com.apple.WindowManager AppWindowGroupingBehavior -int <0:single-window-with-promotion/1:all-windows> defaults write com.apple.WindowManager AutoHide -bool defaults write com.apple.WindowManager AutoHideDelay -float defaults write com.apple.WindowManager AutoHideOverlapThreshold -float defaults write com.apple.WindowManager AutoHideWhenOccluded -bool defaults write com.apple.WindowManager CAContextPoolLimit -int defaults write com.apple.WindowManager EnableAppStickyHotKey -bool defaults write com.apple.WindowManager EnableAutohideHotKey -bool defaults write com.apple.WindowManager EnableAutomaticNewWindowAddToWindowSet -bool defaults write com.apple.WindowManager EnableInlineAppExpose -bool defaults write com.apple.WindowManager EnablePromoteToSingleAppHotKey -bool defaults write com.apple.WindowManager EnableStageManagerHotKey -bool defaults write com.apple.WindowManager EnableStrip3DTransform -bool defaults write com.apple.WindowManager EnableStripCornerRadius -bool defaults write com.apple.WindowManager EnableStripMostlyOccludedFlag -bool defaults write com.apple.WindowManager EnableStripShadows -bool defaults write com.apple.WindowManager EnableStripShadowsInnerRimRadiusScaling -bool defaults write com.apple.WindowManager EnableStripShadowsOuterRimRadiusScaling -bool defaults write com.apple.WindowManager EnableStripShadowsRadiiScaling -bool defaults write com.apple.WindowManager EnableStripSourceAtopBlending -bool defaults write com.apple.WindowManager EnableSystemStickyHotKey -bool defaults write com.apple.WindowManager GloballyEnabled -bool defaults write com.apple.WindowManager GloballyEnabledEver -bool defaults write com.apple.WindowManager HiddenStripPeekWidth -float defaults write com.apple.WindowManager HideDesktop -bool defaults write com.apple.WindowManager HorizontalInsetFromStrip -float defaults write com.apple.WindowManager InlineAppExposeIconSize -float defaults write com.apple.WindowManager InlineAppExposeMaximumColumnCount -int defaults write com.apple.WindowManager InlineAppExposeMaximumItemHeight -float defaults write com.apple.WindowManager InlineAppExposeStageMinimumHorizontalDistance -float defaults write com.apple.WindowManager InlineAppExposeStripEdgeHorizontalInset -float defaults write com.apple.WindowManager InlineAppExposeStripPileHorizontalSpacing -float defaults write com.apple.WindowManager InlineAppExposeStripPileVerticalSpacing -float defaults write com.apple.WindowManager InterItemHorizontalSpacing -float defaults write com.apple.WindowManager InterItemVerticalSpacing -float defaults write com.apple.WindowManager ItemHeight -float defaults write com.apple.WindowManager ItemWidth -float defaults write com.apple.WindowManager LeftChameleonLeftBaseAlpha -float defaults write com.apple.WindowManager LeftChameleonLeftStepValue -float defaults write com.apple.WindowManager LeftChameleonRightBaseAlpha -float defaults write com.apple.WindowManager LeftChameleonRightStepValue -float defaults write com.apple.WindowManager LeftStripAppIconBottomOffset -float defaults write com.apple.WindowManager LeftStripAppIconLeftOffset -float defaults write com.apple.WindowManager LeftStripAppIconThreeIconHorizontalSpacing -float defaults write com.apple.WindowManager LeftStripAppIconTwoIconHorizontalSpacing -float defaults write com.apple.WindowManager LeftStripEdgeHorizontalInset -float defaults write com.apple.WindowManager LeftStripMaximumRowCount -int defaults write com.apple.WindowManager LeftStripMinimumRowCount -int defaults write com.apple.WindowManager LeftStripPileInterItemHorizontalSpacing -float defaults write com.apple.WindowManager LeftStripPileMaximumWindowCount -int defaults write com.apple.WindowManager LeftStripPileVerticalSpacing -float defaults write com.apple.WindowManager LeftStripReplacementOrder -int <0:top> defaults write com.apple.WindowManager LeftStripStackDepthStepValue -float defaults write com.apple.WindowManager LeftStripTiltLeftBaseAlpha -float defaults write com.apple.WindowManager LeftStripTiltLeftStepValue -float defaults write com.apple.WindowManager LeftStripTiltRightBaseAlpha -float defaults write com.apple.WindowManager LeftStripTiltRightStepValue -float defaults write com.apple.WindowManager MaximumItemHeight -float defaults write com.apple.WindowManager PilePerspectiveDistance -float defaults write com.apple.WindowManager PilePerspectiveDistanceOverride -bool defaults write com.apple.WindowManager PileRotation -float defaults write com.apple.WindowManager PileShouldIgnoreHDR -bool defaults write com.apple.WindowManager PreferredMinimumItemHeight -float defaults write com.apple.WindowManager ShiftClickToAddToSet -bool defaults write com.apple.WindowManager ShouldPersistLeftStripOrdering -bool defaults write com.apple.WindowManager StageFrameMinimumHorizontalInset -float defaults write com.apple.WindowManager StageManagerMinimizationBehavior -int <0:strip-bottom/1:dock> defaults write com.apple.WindowManager StripClickDownScaleDistance -float defaults write com.apple.WindowManager StripClickSessionTimeout -float defaults write com.apple.WindowManager StripCornerRadius -float defaults write com.apple.WindowManager StripHoverScaleDistance -float defaults write com.apple.WindowManager StripWindowShadowDensityMultiplier -float defaults write com.apple.WindowManager ToggleAppStickyHotKey -data defaults write com.apple.WindowManager ToggleAutohideHotKey -data defaults write com.apple.WindowManager TogglePromoteToSingleAppHotKey -data defaults write com.apple.WindowManager ToggleStageManagerHotKey -data defaults write com.apple.WindowManager ToggleSystemStickyHotKey -data defaults write com.apple.WindowManager VerticalInset -float ```
lwouis commented 1 year ago

@decodism thanks for finding this! I note however that regardless what we can technically do, if wouldn't be polite to just toy with the user setup without consent or at least information. So we are back to thinking about an UI that would let the user know AltTab doesn't work well with Stage Manager.

ElhemEnohpi commented 1 year ago

What about putting something on the home page of the website, in the "configuration" section? I see that #1025 (More documenation) was closed, but I wouldn't mind a few more details about a couple of things in general, especially since I've never used Windows, so I don't know how it works. Another option could be to enable the wiki here on GitHub.

I'm actually finding that AltTab works quite well with Stage Manager for me, in the configuration I'm using. As mentioned, I have "Recent applications" turned off, so the list of "stages" auto-hides, and so the thumbnails in AltTab look fine to me. I use it a lot with Firefox, so I have command-tab for the native application switcher, option/alt-tab for the window switcher, and control-tab for Firefox's tab switcher set to "recently used order". I've got AltTab set up to look pretty close to the FF tab switcher. Both of them have the issue that the thumbnail is blank unless you've switched to that window/tab at least once, but I don't find that a big problem really, since mainly I'm switching between a few active tabs/windows, and the text title is there anyway. So maybe mention that work-around, wherever you decide to mention Stage Manager.

lwouis commented 1 year ago

What about putting something on the home page of the website, in the "configuration" section? I see that https://github.com/lwouis/alt-tab-macos/issues/1025 (More documenation) was closed, but I wouldn't mind a few more details about a couple of things in general, especially since I've never used Windows, so I don't know how it works. Another option could be to enable the wiki here on GitHub.

I think the website is the right place to showcase what AltTab does. You're correct that we could improve the presentation of the app. It's barebone today, because I assume that most people find AltTab looking for Windows's alt-tab functionality. We could definitely improve by adding more visuals, more text, maybe a video. I've opened the Wiki on this project. Do you think you could work on documeting the app? If you and others do a good job there, I can either port that into the website, or simply link there from the website.

Regarding Stage Manager specifically, I think the app itself would need to report the issue to the user. It shouldn't be a footnote on the website when you download. Some users update to Ventura and will do it without going through the website. Other users may miss it. It's at runtime that AltTab may notice it's running on Ventura+ and that SM is activated, and tell the user about the issues it creates. See for example what the Contexts app is doing when the user activate Secure Input, an OS feature which impacts usage of their app.

ElhemEnohpi commented 1 year ago

I've opened the Wiki on this project. Do you think you could work on documeting the app?

I started a basic Wiki page for usage and configuration, and a note about Stage Manager. Hopefully it's helpful. I will add a couple of comments to #1025 .

ADTC commented 1 year ago

Glad this discussion is already going on. Just got my new MacBook, and updated to Ventura. LOVING Stage Manager though it's a bit buggy. I hope Apple fixes the bugs in it soon.

@lwouis I hope AltTab can have a way to avoid those 3D skewed screenshots from Stage Manager appear in the AltTab window. For now, I'm turning off "Recent applications" in Stage Manager Settings, and that seems to help resolve the issue temporarily (making sure I don't open AltTab while Stage Manager is showing thumbnails).

Suggestion: What if your app will do (optionally, by turning on a setting) an image processing on the screenshots, to detect whether they are Stage Manager screenshots or full window screenshots? Then ignore Stage Manager screenshots (which are often 3D skewed, and also smaller in dimensions) and use the earlier cached screenshots. Yes, this could be processor intensive, and that's why it's off by default, but I think M1/M2 chips should be able to handle it easily.

The very minimal and easiest amount of image processing would be to simply check the size of the screenshot returned by the API. If it's very small (the sizes usually returned due to Stage Manager), you could safely ignore it and use the earlier cached thumbnail (from full-size window) instead. (I think actual windows having such a small size would be very rare.)

You can also do heavier processing by checking for signs of 3D skewing in the image data itself, by looking at the transparent areas and checking if they enclose a proper rectangle or a 3D skewed rectangle.

@XInTheDark @Tnixc as a person who can't handle more than one "desktop space" on my screen, I've taken a liking to Stage Manager, as I can focus better with just one desktop space. What I love the most about it is that small windows appear front and center on the wallpaper instead of being drawn on top of full screen windows. It's so much cleaner, and the OS functions more like a smartphone or tablet OS by only showing one app or window at a time.

Update

I eventually turned off Stage Manager because it's not a polished feature yet (so many things left wanting - I feel it wouldn't even be released this year if Steve Jobs was alive 😄) and I find myself more productive without it. Solves this problem by avoiding it. 😂

zenangst commented 1 year ago

@decodism off topic but how did you find these values in the first place? 🤔

decodism commented 1 year ago

@zenangst by looking at the strings in WindowManager.framework.

zenangst commented 1 year ago

@decodism how would you go about doing that? 🤔🤔 Some third-party software that exposes these strings?

decodism commented 1 year ago

@zenangst it was a guess work with Hopper and its ability to disassemble frameworks from the DYLD cache.

lawand commented 1 year ago

@decodism thanks for finding this! I note however that regardless what we can technically do, if wouldn't be polite to just toy with the user setup without consent or at least information. So we are back to thinking about an UI that would let the user know AltTab doesn't work well with Stage Manager.

@lwouis One idea to detect whether stage manager is on is to check the current thumbnails returned and if one of them is not a rectangle but a trapezoid, that means it is on. What do you think?