Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Recomputing Thumbnails is slow and expensive #45

Closed
galli-leo opened this issue Oct 20, 2019 · 37 comments · Fixed by #91
Closed

Recomputing Thumbnails is slow and expensive #45

galli-leo opened this issue Oct 20, 2019 · 37 comments · Fixed by #91
Labels
enhancement New feature or request

Comments

@galli-leo
Copy link

First of all, thank you for this great app, I really like it!

However, on my 2016 MacBook Pro, getting the UI to show up feels very sluggish, even though I set the delay to 0ms. After investigating the code a bit and running some tests, it seems like recomputing the thumbnails every time the UI shows up is quite expensive.

In my testing I had around 10 windows open and the following lines of code resulted in around 200ms of time:

collectionView_!.setFrameSize(maxSize)
collectionView_!.collectionViewLayout!.invalidateLayout()
collectionView_!.reloadData()
collectionView_!.layoutSubtreeIfNeeded()

Most of that time was spent in the thumbnail function of OpenWindow. A few suggestions on how this could be fixed:

  • Use multithreading for capturing the thumbnails.
  • Capture thumbnails on background thread, then when done update the UI. This would really help getting the UI to show instantly. However, to be able to show something for each window initially I would also:
  • Cache the previously captured thumbnails.
  • Figure out how Mission Control does it and replicate that. If it's similar to iOS multitasking, it's probably taking spontaneous snapshots and storing them somewhere on disk. If we could figure out where, then those could be used.
  • Have a continuously running background task that captures thumbnails every few seconds / minutes and caches them. (Maybe even checks if anything changed and if not increase the time for that specific window?)
@lwouis
Copy link
Owner

lwouis commented Oct 20, 2019

Thanks for the improvement suggestions! Here is some feedback:

Cache the previously captured thumbnails.
Have a continuously running background task that captures thumbnails every few seconds / minutes and caches them. (Maybe even checks if anything changed and if not increase the time for that specific window?)

I really dislike the idea that the UI is shown to the user not up-to-date, then gets update while the user is interacting with it. I think it's bad UX, and I observe that neither Windows nor macOS built-in thumbnail systems do that. On Windows 10 the thumbnails are even live videos. They may have access to higher performance private APIs though; or they may have been done by C/C++ engineers who know how to code actual performant software, which is not my expertise unfortunately.

FYI, I had originally my own downscaling for the thumbnails, and it was too slow. I then offloaded that task to NSImageView which performed way better.

Capture thumbnails on background thread, then when done update the UI. This would really help getting the UI to show instantly. However, to be able to show something for each window initially I would also:

This is a bit tricky because you are not too interested in the 200ms delay before showing the UI, but I personally like it so I would like to keep it in. Keeping it in means that

After pressing the shortcut, we start computing the thumbnails, and after 200ms-if-they-are-ready-or-until-they-are-ready, we show them

It's clearly a better approach than currently which is:

After pressing the shortcut, we wait 200ms, then compute the thumbnails and show them

So yes it's great, just that concurrency on macOS is surprisingly difficult without third-party libraries. I'm used to nice APIs like observers RxJS/RxJava, but GCD on macOS is not the simplest API... So here waiting 200ms or more depending on if thumbnails are ready + handling the case where the user releases before that, and we switch focus to the window before showing the UI, while also cancelling the concurrent tasks so that the UI doesn't show up afterwards, confusing the user; well it's a bit of a challenge.

Use multithreading for capturing the thumbnails.

This is my favorite suggestion out of the bunch. I will look into it when I have time. It shouldn't be too hard, hopefully. Of course you can open a PR ;p

@lwouis lwouis added enhancement New feature or request L size labels Oct 20, 2019
@mfn
Copy link

mfn commented Oct 20, 2019

HyperSwitch does the caching, it works this way (from memory and years of using it):

  • You bring it up (with 0ms) delay, and you see the old thumbs.
  • If you wait "long enough" eventually in the background they were recreated.
  • If you "never wait long enough" and always quickly switch between the windows, then they will never update

As in: CPU cycles are only always "wasted" in case HyperSwitch is interactively used by the user, not otherwise.

It annoys me the thumbs are not up2date (being accustomed it "just works" on windows) but I put higher value the software does not perform tasks not obvious to me. I use it daily on a Late 2013 MacBook Pro and, in terms of resources, it never gets in my way.

@lwouis
Copy link
Owner

lwouis commented Oct 20, 2019

I think there is no need to compromise by caching.

Looking at modern games, it is clear that resizing thumbnails in real-time is doable on modern hardware. The solution involves better code; that's it. We discussed above CPU multi-threading, but I think the target goal should be to downscale on the GPU where it is basically free. I'm not sure how to do that through Cocoa though. NSImageView seems to perform poorly because it is downscaling using the CPU. There may be some lower level API like CALayer that can be drawn to and resize via the GPU for cheap.

@jdheyburn
Copy link

jdheyburn commented Oct 21, 2019

Could there be an option to remove thumbnails and just have the App icons and title? This would remove any element of recalculating thumbnails and speed up use.

I say this because I experience a huge delay in waiting for the UI to appear (> 1s) - I'd rather have no thumbnails if they'll cause this.

@lwouis
Copy link
Owner

lwouis commented Oct 21, 2019

Could there be an option to remove thumbnails

This was discussed in #4 for additional context. I'm open to the idea of a preference to remove thumbnails, however, you may just want to checkout the apps mentioned in the ticket I linked in that case because text-only opens new perspectives that these apps take full advantage of (e.g. fuzzy text search)

@galli-leo
Copy link
Author

galli-leo commented Oct 21, 2019

@lwouis Thanks for your input! I would love to help here, but I am very limited in time.

I am pretty confident that the bottleneck isn’t resizing the images, but rather the way they are retrieved. The CGImageList function call does an IPC call to the WindowServer which then captures the window. Then the WindowServer does another IPC call back with the image. From the disassembly it also looks like there is some locking going on, so that would incur even more overhead.

However, I also found some interesting private APIs inside WindowServer. One function seems to give you access to the raw framebuffer pointer. That could be an option, since the IPC calls would not have to transfer each image anymore, just a pointer.

@lwouis
Copy link
Owner

lwouis commented Oct 22, 2019

@galli-leo very interesting analysis! If what you say is true, and the expensive operation is getting the full-size images from the WindowServer, and not resizing them for thumbnails (like I thought), then the problem is going to be harder to solve.

A cheap test you could do is check the performance of HyperSwitch. Unless they pulled some private API trick, they should experience the same issue on your laptop. Could you run a quick test to compare?

On another note, I'm working on the Preferences UI at the moment, and while trying to add a dropdown for image quality, I read this documentation from Apple:

An NSPopUpButton object uses an NSPopUpButtonCell object to implement its user interface.
Note that while a menu is tracking user input, programmatic changes to the menu such as adding, removing, or changing items on the menu is not reflected

Looks like they share my vision about not updating UI while the user is interacting with it ;p

@lwouis
Copy link
Owner

lwouis commented Oct 26, 2019

@galli-leo I just ran Instruments to profile and see what I get. I did not get the picture you painted (i.e. getting the pictures from the WindowServer being the bottleneck). What I got was something like this:

87ms total
44ms collectionview.layout
14ms get app icon
Rest of the time spent in OS functions like CFRunLoop and NSView layouts

image

I'm don't have enough knowledge to push the performance investigation further. I wish I could though

@galli-leo
Copy link
Author

@lwouis When I tested with Instruments I saw a lot of waiting inside the Run loop but not much in the actual drawing methods (which seems to be similar to your result). I highly suspect this is due to the way the XPC calls work, where the app waits inside the main run loop until it gets a response.

Regarding HyperSwitch: They use a ton of Private APIs, (I would guesstimate about 200 Private Functions, haven't had the time to fully look at all of them yet). And looking closer at HyperSwitch, it seems clear that you can actually get access to the raw window data (well at least you don't have to use XPC calls to transfer the images).

If I have some free time, I will try to get a Proof of Concept working, using what I learn from HyperSwitch :)

@lwouis
Copy link
Owner

lwouis commented Nov 19, 2019

Very interesting @galli-leo! I did a more in-depth exploration of performance on the discord channel. You may want to have a quick look to see what I believe the offenders are.

Regarding HyperSwitch, 200 private APIs is a shocking number! I can't picture in my head why they would need so many. Btw I integrated 1 private API to get screenshots of minimized windows. If you're curious you can see that in action in #78.

Regarding private APIs in general, my position is the following: if there is no choice to use one to implement a feature, then we should do it. However there is a steep cost in maintenance, maintainability, and portability. We discussed here how there is no compat table available online. That means that using a private API is not guaranteed to work on other OS versions than the author's local machine where the change was tested locally. Basically it's a can of worms so its usage should be minimized to limit impact

@koekeishiya
Copy link

koekeishiya commented Nov 20, 2019

@galli-leo @lwouis

highly suspect this is due to the way the XPC calls work, where the app waits inside the main run loop until it gets a response.

Regarding HyperSwitch: They use a ton of Private APIs, (I would guesstimate about 200 Private Functions, haven't had the time to fully look at all of them yet). And looking closer at HyperSwitch, it seems clear that you can actually get access to the raw window data (well at least you don't have to use XPC calls to transfer the images).

The private functions are also part of a client API that communicate with the WindowServer using mach messages (MIG IPC), triggering a corresponding server-side function invocation. IIRC the XPC mechanism is an abstraction that is built on top of mach.

Out of interest, could either of you post a symbols dump of HyperSwitch?

gingerr added a commit to gingerr/alt-tab-macos that referenced this issue Nov 26, 2019
One performance issue we had is related how layers are handled. This commit allows subviews of Cell to be drawn into its layer and the layer be drawn asynchronously. In my test use-case with 16 windows with 3440x1417 sizing this brought the required time from key event reaction to ThumbnailPanel orderOut from 650ms down to 250ms. There is eventually more performance to gain by explicit control of .layerContentsRedrawPolicy. This commit also adds two NSLog statements for easy timing observations in the Run console.

Related to lwouis#45
@galli-leo
Copy link
Author

@koekeishiya Symbol dump, below. However, I don't know which ones of these were really used.

_CGSDefaultConnection
CGSMainConnectionID
CGSSetUniversalOwner
CGSSetOtherUniversalConnection
CGSNewConnection
CGSGetConnectionIDForPSN
CGSDisableUpdate
CGSReenableUpdate
CGSGetWindowCount
CGSGetWindowList
CGSGetOnScreenWindowCount
CGSGetOnScreenWindowList
CGSGetWorkspaceWindowCount
CGSGetWorkspaceWindowList
CGSGetWorkspaceWindowCountWithOptionsAndTags
CGSGetWorkspaceWindowListWithOptionsAndTags
CGSGetWorkspaceWindowGroup
CGSSessionCopyPreferencesForWorkspaces
CGSGetSpaceManagementMode
CGSGetParentWindowList
CGSGetWindowLevel
CGSSetWindowLevel
CGSCycleWindows
CGSOrderWindow
CGSWindowIsOrderedIn
CGSWindowIsVisible
CGSFlushWindow
CGSGetWindowBounds
CGSGetScreenRectForWindow
CGSMoveWindow
CGSSetWindowTransform
CGSGetWindowTransform
CGSSetWindowTransforms
CGSSetWindowAlpha
CGSSetWindowListAlpha
CGSGetWindowAlpha
CGSSetWindowListBrightness
CGSMoveWorkspaceWindows
CGSMoveWorkspaceWindowList
CGSSetWindowShadowAndRimParameters
CGSGetWindowShadowAndRimParameters
CGSInvalidateWindowShadow
CGSCopyWindowProperty
CGSSetWindowProperty
CGSGetWindowOwner
CGSConnectionGetPID
CGSSetWindowOriginRelativeToWindow
CGSGetWindowType
CGSSetActiveWindow
CGSGetWindowTags
CGSSetWindowTags
CGSClearWindowTags
CGSGetWindowEventMask
CGSSetWindowEventMask
CGSSetWindowWarp
CGSNewCIFilterByName
CGSAddWindowFilter
CGSRemoveWindowFilter
CGSReleaseCIFilter
CGSSetCIFilterValuesFromDictionary
CGSSetWindowBackgroundBlurRadius
CGSNewTransition
CGSInvokeTransition
CGSReleaseTransition
CGSGetWorkspace
CGSGetWindowWorkspace
CGSGetWindowWorkspaceIgnoringVisibility
CGSSetWorkspace
CGSSetWindowListWorkspace
CGSSetWindowListWorkspaceIgnoringConsistency
CGSRegisterNotifyProc
CGSRemoveNotifyProc
CGSRegisterConnectionNotifyProc
CGSRequestNotificationsForWindows
CGSSessionSetNotificationConnectionForWorkspaces
CGSNewRegionWithRect
CGSNewEmptyRegion
CGSReleaseRegion
CGSNewWindowWithOpaqueShape
CGSReleaseWindow
CGWindowContextCreate
CGContextCopyWindowCaptureContentsToRect
CGContextCopyWindowCaptureContentsToRectWithOptions
CGSCaptureWindowsContentsToRect
CGSCaptureWindowsContentsToRectWithOptions
CGImageSetCachingFlags
CGImageGetCachingFlags
CGSSetConnectionProperty
CGSHWCaptureWindowList
CGSFindWindowAndOwner
CGSSetWorkspaceForWindow
CGSSetFrontWindow
CGSCreateWindowDebugInfo
CGSPackagesCopyWorkspaceIdentifierForWorkspace
CGSPackagesGetWorkspaceType
CGSPackagesCopyWorkspaces
CGSSpaceGetCompatID
CGSSpaceGetType
CGSSpaceCreate
CGSSpaceCopyOwners
CGSSpaceCopyValues
CGSCopySpaces
CGSCopySpacesForWindows
CGSSpaceDestroy
CGSSpaceCopyName
CGSAddWindowsToSpaces
CGSRemoveWindowsFromSpaces
CGSCopyManagedDisplaySpaces
CGSGetActiveSpace
CGSCopyManagedDisplays
CGSCopyManagedDisplayForSpace
CGSCopyManagedDisplayForWindow
CGSCopyBestManagedDisplayForPoint
CGSCopyBestManagedDisplayForRect
CGSGetDisplaysWithUUID
CGSSetActiveMenuBarDisplayIdentifier
CGSCopyActiveMenuBarDisplayIdentifier
CGSReassociateWindowsSpacesByGeometry
CGSManagedDisplayCurrentSpaceAllowsWindow
CGSManagedDisplayGetCurrentSpace
CGSManagedDisplayIsAnimating
CGSCopyWindowsWithOptionsAndTags
_AXUIElementGetWindow
CoreCursorSet
CGSSetWindowToReleaseBackingOnOrderOut
CGSSetWindowAccelerationState
CGSGetWindowAccelerationState
CGSSynchronizeWindow
CGSWindowUpdateIsPending
CGSGetZoomParameters
CGSSetZoomParameters
CGSDisplayIsZoomed
CGSZoomPoint
CGSUnzoomPoint
CGSGetCurrentCursorLocation
CGSCurrentInputPointerPosition
CGSGetDisplayBounds
CGSGetSurfaceCount
CGPixelAccessCreateWithWindow
CGPixelAccessLock
CGPixelAccessUnlock
CGPixelAccessRelease
CGPixelAccessCreateImageFromRectNoCopy
_LSCopyAllApplicationURLs
CPSGetKeyFocusProcess
CGSEventIsAppUnresponsive
CGSSetWindowCornerMask
CGSWindowSetBackdropBackgroundBleed
CABackingStoreGetTypeID
CABackingStoreIsVolatile
CABackingStoreSetVolatile
CoreDockGetTileSize
CoreDockSetTileSize
CoreDockGetOrientationAndPinning
CoreDockSetOrientationAndPinning
CoreDockGetEffect
CoreDockSetEffect
CoreDockGetAutoHideEnabled
CoreDockSetAutoHideEnabled
CoreDockIsMagnificationEnabled
CoreDockSetMagnificationEnabled
CoreDockGetMagnificationSize
CoreDockSetMagnificationSize
CoreDockGetWorkspacesEnabled
CoreDockSetWorkspacesEnabled
CoreDockGetWorkspacesCount
CoreDockSetWorkspacesCount
CoreDockSetPreferences
CoreDockSendNotification
CoreDockGetRect
CoreDockGetContainerRect
CoreDockUpdateWindow
CoreDockAddFileToDock
CGEventGetEventRecordSize
CGEventGetEventRecord
CGEventGetWindowLocation
CGEventGetUnflippedLocation
CGEventGetUnflippedWindowLocation
CGEventRecordPointer
CGEventCreateWithEventRecord
CGEventCopyIOHIDEvent
CGEventSetIOHIDEvent
IOHIDEventCreateData
IOHIDEventGetType
IOHIDEventGetTypeID
IOHIDEventGetPhase
IOHIDEventGetFloatValue
IOHIDEventGetIntegerValue
IOHIDEventGetPosition
IOHIDEventGetChildren
_mthid_isPathCollection
_mthid_pathCollectionCopyAllPaths
_mthid_pathCollectionCopyTouchingPaths
_mthid_pathCollectionGetPosition
_mthid_pathGetPosition
_mthid_isPath
_mthid_pathGetIndex
_mthid_pathIsResting
_mthid_pathIsTouching
_mthid_pathIsStationary
_mthid_pathWasRejected
_mthid_pathGetVelocity

@galli-leo
Copy link
Author

@lwouis After experimenting a bit, I came to the following conclusions:

  1. Seems like accessing the raw frame buffer is not possible without either patching WindowServer or CoreGraphics.
  2. HyperSwitch seems to be using a similar API to the one alt-tab is currently using, but they then also use another private API to get the window image a second time? (not really sure how that works yet)
  3. Either Apple fixed something in the latest beta or my testing method was flawed (from the initial post), since it seems like getting the images from WindowServer is actually very fast now. The problem now seems to be the pure rendering of the images. It might be good to either figure out how to render them more quickly or scaling them down.
  4. HyperSwitch basically does everything I proposed in the original post :):
    a. Updates Thumbnails in background.
    b. Continuously updates Thumbnails (e.g. you can see them change when the switcher is up)
    c. Multithreading and background using GCD

@lwouis
Copy link
Owner

lwouis commented Nov 26, 2019

On my system, I'm pretty sure now that getting the images from the WindowServer is the bottleneck. See discussion in that PR. What do you see in Instruments? I'm guessing you see little time spent in alt-tab-mac, and lots of time spent in WindowServer, if you use the Thread State Trace view.

HyperSwitch has a terrible UX I think. Try opening a video and pressing the shortcut multiple time. You'll see the thumbnail is super late to get updated.

Very interesting discussion here, although the solution discussed seems to only cover screen area capture, not windows capture. Also here, where the person explain the locking you mentioned.

@galli-leo
Copy link
Author

@lwouis Hmm interesting, I will take another look.

I did the above testing with a small POC application though, maybe there is something alt-tab that slows down the WindowServer?

@lwouis
Copy link
Owner

lwouis commented Nov 26, 2019

I was reading online about how to deal with CGWindowListCreateImage being slow, and someone mentioned that Zoom is doing this. I realized "yeah zoom has screen share but also window only share, as a video stream". Then I checked my Accessibility settings and noticed I never authorized Zoom. It clearly means they are using a private API to grab screenshots/video-stream of other windows as the official CG API is too slow for video and requires the Accessibility permission, and the AV API is after compositing, so can't capture a window behind another window

@lwouis
Copy link
Owner

lwouis commented Nov 26, 2019

maybe there is something alt-tab that slows down the WindowServer?

It's possible. Maybe it's all the bridges between Swift/ObjC/C that create memory copy and destroy the performance of the CGWindowListCreateImage? But maybe it's just that this API is slow, and everybody else is using a faster private API

@galli-leo
Copy link
Author

@lwouis You don't need Accessibility settings for screen recording. Also even with private APIs you still need to be allowed to record screen in the settings. I think it might fast enough if you only capture one window, but probably too slow once you start capturing multiple.

@koekeishiya
Copy link

@galli-leo @lwouis

I somehow stumbled upon a nicely written blogpost with quite some detailed information into how macOS Graphics work (under the hood) and figured it might be of interest to you:

https://avaidyam.github.io/2019/02/19/DIY-Core-Animation.html

@lwouis
Copy link
Owner

lwouis commented Dec 13, 2019

I've been exploring this topic again. I think this screenshot really shows the story:

image

Notice how the app is blocked most of the time when the shortcut is pressed. I'm not sure about thread preemption and other low-level mechanism of macOS, but basically how I read this is that the app is waiting on the WindowServer to get the windows screenshot. This is time we can't reduce. This time can be increased by the user having a 4k display, having other work loads on their computer when they press the shortcut, having integrated GPU, etc.

I read many interesting low-level posts from @avaidyam (referenced by @koekeishiya above).
I discussed through email with him, and he suggested I use the CAPluginLayer demonstrated in the Diorama repo. This technique allows to integrate rendering of a user app into the OS rendering pipeline, making it possible to get high FPS "video" of all windows. That sounded like the perfect tech to use in alt-tab-macos.

However, that technique has been patched in 10.15 and can only render the app windows, not other apps windows. It was also unstable in previous macOS versions resulting in user session crashes on my 10.14 laptop for instance.

Going forward I have no lead on a tech we could use to address the bad performance of the current CGWindowListCreateImage call to the WindowServer. To recap:

  • Current CGWindowListCreateImage API is slow and can't be optimized because the slowness is in the OS implementation
  • Private API CGSCaptureWindowsContentsToRectWithOptions I experienced with to get minimized windows screenshots has the same low performance (it must go through the same internals as CGWindowListCreateImage).
  • Private API CAPluginLayer has excellent performance but crashes the whole user session frequently up to 10.14, and is downright unable to render other windows starting from 10.15
  • OS-bundled binary /usr/sbin/screencapture (the bundled Capture utility) is too slow

The only thing I can think of would be to pre-render/cache the thumbnails. But then we trade off responsiveness with showing the user incorrect data when they press the shortcut. Ok they see the list fast, and the list has the correct number of items with correct titles, but the screenshot will then change. We could put a spinner on each thumbnail so the user knows that we are now fetching the freshest image and showing them an old one in the meanwhile. To be honest I'm not sure this is a better experience.

I would love other people opinion here on how to move forward

@mfn
Copy link

mfn commented Dec 13, 2019

The only thing I can think of would be to pre-render/cache the thumbnails. But then we trade off responsiveness with showing the user incorrect data when they press the shortcut

I bet this is what HyperSwitch also realized, hence it works that way there.

As a daily user of this feature, to me:: responsiveness is king than accurateness for this use case.

@koekeishiya
Copy link

koekeishiya commented Dec 13, 2019

@lwouis

My immediate thoughts for how to speed up this process would be to look for ways to perform a batch operation when communicating with the WindowServer, instead of initiating a new request for every single window. The private function CGSHWCaptureWindowList comes to mind, although I have not verified that it still works.

@lwouis
Copy link
Owner

lwouis commented Dec 16, 2019

I tried using the CGSHWCaptureWindowList function in batch mode without success. It's supposed to input and output multiple windows at the same time. Indeed here is the signature I was able to find on the internet:

extern CFArrayRef CGSHWCaptureWindowList(CGSConnectionID cid, CGSWindowID *windowList, CGSWindowCount windowCount, CGSWindowCaptureOptions options);

Here is how I call it:

func windowScreenshots(_ windowId: [CGSWindowID]) -> Array<CGImage> {
        return CGSHWCaptureWindowList(
                CGSMainConnectionID(),
                UnsafeMutablePointer(mutating: windowId),
                CGSWindowCount(windowId.count),
                CGSWindowCaptureOptions(kCGSCaptureIgnoreGlobalClipShape | kCGSWindowCaptureNominalResolution)
        )!.takeRetainedValue() as! Array<CGImage>
}

However the CGSHWCaptureWindowList always returns an array of 1 element: the window from the first ID in the array of 5 IDs.

I checked in the debugger, and I correctly send an array of 5 IDs for instance in UnsafeMutablePointer(mutating: windowId), and the size is 5 in CGSWindowCount(windowId.count).

@koekeishiya I looked at all results from Google, and all results from Github, but basically I see only 1 project on the web that seems to be using that function, and it's Webkit. The good news is that they still reference it on master today, so it seems like a safe private SPI to use. The bad news is that they call it with a hardcoded CGSWindowCount of 1. Do you know if I'm calling it incorrectly, or if perhaps they changed the spec and it only returns 1 window now.

@gingerr could you please test the performance on this branch? Somehow for a few days I haven't been able to have the app be slow on my laptop. I tried opening hundreds of windows like I used to, but still it doesn't slow down much. Could you test with your 4k windows on your system? Maybe you'll see a difference on that branch as it uses CGSHWCaptureWindowList (The HW in the name is hardware so potentially this stuff performs better)

@gingerr
Copy link
Contributor

gingerr commented Dec 17, 2019

@lwouis quick feedback on performance:
Tested it on my MacBook (Catalina) and my desktop Hackintosh (High Sierra) with external monitor. Same test as the last time, 16x windows maximised on a display running 3440x1440 and measuring the time between Application.showUiOrCycleSelection and ThumbnailsPanel.orderOut.

The performance is great (150ms - 250ms) and the performance issue I attempted to fix with #87 (which I could only reproduce on Hackintosh running High Sierra) is also gone! ThumbnailPanel summon feels instant on both systems.

I think you got a winner here for both performance and access to minimised windows. 🥇

lwouis pushed a commit that referenced this issue Dec 27, 2019
Also closes #11 closes #45 closes #62

BREAKING CHANGE: this brings huge changes to core parts of the codebase. It introduces the use of private APIs that hopefully are should be compatible from macOS 10.12+, but I couldn't test them. I reviewed the whole codebase to clean and improve on performance and readability
lwouis pushed a commit that referenced this issue Dec 27, 2019
Also closes #11 closes #45 closes #62

BREAKING CHANGE: this brings huge changes to core parts of the codebase. It introduces the use of private APIs that hopefully are should be compatible from macOS 10.12+, but I couldn't test them. I reviewed the whole codebase to clean and improve on performance and readability
lwouis pushed a commit that referenced this issue Dec 27, 2019
# [2.0.0](v1.14.4...v2.0.0) (2019-12-27)

### Features

* display other spaces/minimized windows (closes [#14](#14)) ([3f5ea25](3f5ea25)), closes [#11](#11) [#45](#45) [#62](#62)

### BREAKING CHANGES

* this brings huge changes to core parts of the codebase. It introduces the use of private APIs that hopefully are should be compatible from macOS 10.12+, but I couldn't test them. I reviewed the whole codebase to clean and improve on performance and readability
@lwouis
Copy link
Owner

lwouis commented Dec 27, 2019

This ticket and a bunch of others are closed in v2 released today. Feel free to test that new version out and give feedback here! Hopefully you experience better performance, can interact with minimized windows, and interact with windows from other spaces and displays. Cheers!

@zxti
Copy link

zxti commented Jan 8, 2020

I was super excited to come across this project! Unfortunately I find the v2 lag before the switcher shows up when pressing alt-tab to still be quite high (vs HyperSwitch). It feels probably close to 2x HS's lag, and HS's lag I was already quite sensitive to (compared to the instantaneous native alt-tab and Windows alt-tab I'm most used to). I know it sounds super sensitive, and I may just be in the minority, but this is one of the biggest hurdles against being comfortable with this type of switcher (HS is not exempt but its lag is noticeably faster). Just my 2c!

@lwouis
Copy link
Owner

lwouis commented Jan 8, 2020

Hi @zxti! Thanks for the feedback. I got 2 main points from your comment:

  1. You want more performance

I want it too. Every contributor here wants it. I think we can all agree that for such a tool, snappy UX is priority number 2 (number 1 being "it actually shows the thumbnails and I can switch to them").

  1. HyperSwitch is faster

The reason HyperSwitch is faster is because it shows you wrong information. It displays something as fast as it can, then it update the UI asynchronously. Open a youtube video, and trigger HS many times and see how it takes a few seconds to be correct. They are basically refreshing thumbnails on a scheduled timer like 4s. If you alt-tab right after the tick, it will be accurate and be a fast UX. If you trigger right before the tick, you will see a different window that could make it hard to locate the visual image you are looking for (e.g. you are looking for a big dominant color like big red background but it's not there on the thumbnail), or worse mislead you (it will show you the how it looked 4s ago and will make you select the wrong thumbnail).

My point is that they trade-off accuracy for speed. We could do that too in this project and cache thumbnails on a timer too. If we go that road I clearly want this to be a preference as some of us will prefer the opposite trade-off and would rather wait a few more ms and get accurate visuals.

But that's not all! I actually have good news for you! I'm currently working on v3 which is a total rework of the app. Instead of asking the OS about the state of the whole system on trigger (what we do today; hard to do fast), or asking the state of the whole system on a timer (what HyperSwitch does today; inaccurate) - instead of one of 2 approaches, v3 observes the Accessibility events such as "an app was launched", "a window was closed". This means we build a cache as we receive these events in the background, and when the user trigger the app, we can show accurate state of the windows instantly.

Of course there is no free lunch, so this approach has its own issues. However from my work on it from the past week, I'm very optimistic! The thing I'm the most excited about actually is not the perf (because on my machine even v2 is instant; I have a recent macbook and no 4k displays), but the fact that we will finally have the thumbnails in order of recently-used to least-recently-used, instead of the order of their stack (z-index) on the desktop. It's a big difference! There are many more limitations that are no longer applying also with this approach.

I hope to be able to release v3 either this week or the next one

lwouis pushed a commit that referenced this issue Jan 8, 2020
closes #93 closes #24

BREAKING CHANGE: Instead of asking the OS about the state of the whole system on trigger (what we do today; hard to do fast), or asking the state of the whole system on a timer (what HyperSwitch does today; inaccurate) - instead of one of 2 approaches, v3 observes the Accessibility events such as "an app was launched", "a window was closed". This means we build a cache as we receive these events in the background, and when the user trigger the app, we can show accurate state of the windows instantly.

Of course there is no free lunch, so this approach has its own issues. However from my work on it from the past week, I'm very optimistic! The thing I'm the most excited about actually is not the perf (because on my machine even v2 is instant; I have a recent macbook and no 4k displays), but the fact that we will finally have the thumbnails in order of recently-used to least-recently-used, instead of the order of their stack (z-index) on the desktop. It's a big difference! There are many more limitations that are no longer applying also with this approach.

More context: #45 (comment)
@lwouis lwouis mentioned this issue Jan 8, 2020
@lwouis
Copy link
Owner

lwouis commented Jan 8, 2020

@zxti I opened a PR for v3. It's think it's ready but I'm afraid I didn't test enough. I tested very tricky cases but still I could be missing some. The issue with the new approach is that we maintain state, so if there are cases that we don't take into account, we can drift away from the actual state of the windows. However the benefits are many, as I hinted at in my previous comment.

Could you test this on your side and tell me if it performs better for you? :) Also if it's functioning correctly ;p

lwouis pushed a commit that referenced this issue Jan 9, 2020
closes #93 closes #24

BREAKING CHANGE: Instead of asking the OS about the state of the whole system on trigger (what we do today; hard to do fast), or asking the state of the whole system on a timer (what HyperSwitch does today; inaccurate) - instead of one of 2 approaches, v3 observes the Accessibility events such as "an app was launched", "a window was closed". This means we build a cache as we receive these events in the background, and when the user trigger the app, we can show accurate state of the windows instantly.

Of course there is no free lunch, so this approach has its own issues. However from my work on it from the past week, I'm very optimistic! The thing I'm the most excited about actually is not the perf (because on my machine even v2 is instant; I have a recent macbook and no 4k displays), but the fact that we will finally have the thumbnails in order of recently-used to least-recently-used, instead of the order of their stack (z-index) on the desktop. It's a big difference! There are many more limitations that are no longer applying also with this approach.

More context: #45 (comment)
lwouis pushed a commit that referenced this issue Jan 9, 2020
closes #93 closes #24

BREAKING CHANGE: Instead of asking the OS about the state of the whole system on trigger (what we do today; hard to do fast), or asking the state of the whole system on a timer (what HyperSwitch does today; inaccurate) - instead of one of 2 approaches, v3 observes the Accessibility events such as "an app was launched", "a window was closed". This means we build a cache as we receive these events in the background, and when the user trigger the app, we can show accurate state of the windows instantly.

Of course there is no free lunch, so this approach has its own issues. However from my work on it from the past week, I'm very optimistic! The thing I'm the most excited about actually is not the perf (because on my machine even v2 is instant; I have a recent macbook and no 4k displays), but the fact that we will finally have the thumbnails in order of recently-used to least-recently-used, instead of the order of their stack (z-index) on the desktop. It's a big difference! There are many more limitations that are no longer applying also with this approach.

More context: #45 (comment)
@kawtharmonki
Copy link

Any chance you'd be able to add a build to that branch? Would be happy to test it out :]

@lwouis
Copy link
Owner

lwouis commented Jan 20, 2020

@kawtharmonki
sorry I was working on fixing a layout issue I introduced while reworking the layout code. I think layout works good now. Here is a build of the latest v3 PR code: alt-tab-macos.app.zip

lwouis pushed a commit that referenced this issue Jan 23, 2020
closes #93 closes #24 closes #117

BREAKING CHANGE: Instead of asking the OS about the state of the whole system on trigger (what we do today; hard to do fast), or asking the state of the whole system on a timer (what HyperSwitch does today; inaccurate) - instead of one of 2 approaches, v3 observes the Accessibility events such as "an app was launched", "a window was closed". This means we build a cache as we receive these events in the background, and when the user trigger the app, we can show accurate state of the windows instantly.

Of course there is no free lunch, so this approach has its own issues. However from my work on it from the past week, I'm very optimistic! The thing I'm the most excited about actually is not the perf (because on my machine even v2 is instant; I have a recent macbook and no 4k displays), but the fact that we will finally have the thumbnails in order of recently-used to least-recently-used, instead of the order of their stack (z-index) on the desktop. It's a big difference! There are many more limitations that are no longer applying also with this approach.

More context: #45 (comment)
@kawtharrr
Copy link

Heya, sorry for the late response to this. V3 has massive speed improvements, great work! A couple of bugs:

  • While the alt-tab 'window' is open, the focused window keeps jumping around (seems to be to the 2nd window), resulting in a difficult to use experience

  • The app seems to capture X+hotkeys, when more typical behaviour is only to respond to hotkeys only. e.g. if I've set ALT+TAB as the hotkey for this, and I've SHIFT+ALT+TAB as a hotkey to play/pause Spotify, alt-tab (the app) still gets invoked in the second scenario. This behaviour is in contrast to most other apps including e.g. HyperSwitch

Happy to open separate Issues - but not sure if they've already been addressed since it's been a while and you're making rapid progress + changes :)

@lwouis
Copy link
Owner

lwouis commented Feb 5, 2020

Thanks for the feedback @kawtharrr!

  • While the alt-tab 'window' is open, the focused window keeps jumping around (seems to be to the 2nd window), resulting in a difficult to use experience

The description you make is a bit weird. I have trouble imagining what this looks like exactly. I would say most likely this issue is gone, but if you want to confirm, let me attach the latest v3 branch build here: alt-tab-macos.app.zip

The app seems to capture X+hotkeys, when more typical behaviour is only to respond to hotkeys only. e.g. if I've set ALT+TAB as the hotkey for this, and I've SHIFT+ALT+TAB as a hotkey to play/pause Spotify, alt-tab (the app) still gets invoked in the second scenario. This behaviour is in contrast to most other apps including e.g. HyperSwitch

This behavior has been there from day 1 I believe. The keyboard events checks we do are "at least these keys are pressed", not "exactly these keys are pressed". I'll open a ticket to track that issue. As soon as ShortcutRecorder implements the ticket I opened, I will work on #72. ShortcutRecorder has exact matching so it will close this issue as well.

lwouis pushed a commit that referenced this issue Mar 10, 2020
closes #93 closes #24 closes #117

BREAKING CHANGE: Instead of asking the OS about the state of the whole system on trigger (what we do today; hard to do fast), or asking the state of the whole system on a timer (what HyperSwitch does today; inaccurate) - instead of one of 2 approaches, v3 observes the Accessibility events such as "an app was launched", "a window was closed". This means we build a cache as we receive these events in the background, and when the user trigger the app, we can show accurate state of the windows instantly.

Of course there is no free lunch, so this approach has its own issues. However from my work on it from the past week, I'm very optimistic! The thing I'm the most excited about actually is not the perf (because on my machine even v2 is instant; I have a recent macbook and no 4k displays), but the fact that we will finally have the thumbnails in order of recently-used to least-recently-used, instead of the order of their stack (z-index) on the desktop. It's a big difference! There are many more limitations that are no longer applying also with this approach.

More context: #45 (comment)
lwouis pushed a commit that referenced this issue Mar 10, 2020
# [2.4.0](v2.3.4...v2.4.0) (2020-03-10)

### Bug Fixes

* a title change often means the content has change ([b8d6bc9](b8d6bc9))
* add rough downscaling when there are many windows (closes [#69](#69)) ([ced5ee6](ced5ee6))
* added releases link and aligned layout left on tab 3 ([6bb73dc](6bb73dc))
* also codesign debug builds ([a5f9911](a5f9911))
* app launched while in fullscreen shows first window ([c5cbcdb](c5cbcdb)), closes [/github.com//pull/114#issuecomment-576384795](https://github.com//github.com/lwouis/alt-tab-macos/pull/114/issues/issuecomment-576384795)
* auto-update preferences sync with os from launch ([b3fb222](b3fb222))
* avoid rendering if app is not used ([fdddb0f](fdddb0f))
* better float rounding = sharper cell contents ([9a96e49](9a96e49))
* better focus/order for preferences (closes [#80](#80)) ([4a8bdeb](4a8bdeb))
* better textareas ([efc9bd3](efc9bd3))
* bring back the window delay that regressed with v2 ([bb95e55](bb95e55))
* compare correctly since pid can go away when an app dies ([4ded030](4ded030))
* compiler warnings ([1faa74c](1faa74c))
* cpu and memory leaks (see discussion in [#117](#117)) ([52626aa](52626aa))
* dock being shown was blocking alt-tab ([2826a1b](2826a1b))
* don't show floating windows + efficiencies ([3f8e3ea](3f8e3ea))
* don't show ui on fast trigger ([f8e1b00](f8e1b00))
* don't trigger ui refreshes if the app is not active ([b9a0152](b9a0152))
* don't upscale thumbnails of small windows ([0bc7472](0bc7472))
* feedback token injected during ci ([effdc5f](effdc5f))
* getting sparkle ready for release ([9f1f522](9f1f522))
* handle on-all-spaces windows better ([4abe9f3](4abe9f3))
* ignore build folder ([a2bb19f](a2bb19f))
* ignore trigger shortcuts if mission control is active ([b03b0aa](b03b0aa))
* initial discovery when single space was glitching the os ([3cd4b6d](3cd4b6d))
* keyboard shortcuts didn't work without a menu ([cf92dc1](cf92dc1))
* layout is now correct; also removed layout preferences for now ([a1b5266](a1b5266))
* layout regression introduced by eed0353 ([bdc41be](bdc41be))
* layout was incorrect resulting in thumbnails clipping ([fd906f4](fd906f4))
* letsmove was not active on release builds ([6ac0658](6ac0658))
* list temporary AXDialog windows like activity monitor ([51a8838](51a8838))
* more robust screen-recording permission check ([ce574a2](ce574a2))
* notarization issues ([d125dd3](d125dd3))
* observer leak would throw and crash the app sometimes ([9ca28eb](9ca28eb))
* only test permissions on the correct os versions ([4612e37](4612e37))
* open alt-tab during space transitions (closes [#92](#92)) ([141562d](141562d))
* prevent visual flickering (closes [#115](#115)) ([9a8c83e](9a8c83e))
* quitting apps was not properly removing apps from the list ([10b2c71](10b2c71))
* quitting multiple apps would refresh the ui multiple times ([bfc2700](bfc2700))
* regression on collectionviewitem titles (not showing) ([8cb6d86](8cb6d86))
* remove debug colors ([e588d55](e588d55))
* remove unnecessary/wrong layout code ([9e719e6](9e719e6))
* sharper images on non-retina displays ([1bb4d2a](1bb4d2a))
* smaller payload for the icons ([bddb6fa](bddb6fa))
* some apps have messy launch behavior ([7eb216d](7eb216d)), closes [/github.com//issues/117#issuecomment-583868046](https://github.com//github.com/lwouis/alt-tab-macos/issues/117/issues/issuecomment-583868046)
* some apps should retry observing until it works ([0c731f4](0c731f4))
* using floor() everywhere to avoid blurry rendering ([2a36196](2a36196))

### Code Refactoring

* complete rework of the internals ([547311e](547311e)), closes [#93](#93) [#24](#24) [#117](#117) [/github.com//issues/45#issuecomment-571898826](https://github.com//github.com/lwouis/alt-tab-macos/issues/45/issues/issuecomment-571898826)

### Features

* add an app icon and menubar icon (closes [#38](#38)) ([a345dae](a345dae))
* add back the preferences for the new layout algo ([d52eb6d](d52eb6d))
* add debug profile to feedback message ([a14f965](a14f965))
* add feedback button on about window ([4046136](4046136))
* add in-app feedback form (closes [#145](#145)) ([725a030](725a030))
* add licence to about page ([cb66b79](cb66b79))
* add preference to start at login (closes [#159](#159)) ([982fe6c](982fe6c))
* adding cocoapods and letsmove/sparkle ([606bae7](606bae7))
* better packing; tall thumbnails are 1/2 the width of wide ones ([e34e3b1](e34e3b1))
* cleaner layout and explanation text ([fd3e768](fd3e768))
* debug build has code-signing to preserve permissions ([34a32f3](34a32f3))
* divide preferences by topic (closes [#130](#130)) ([291f872](291f872))
* drag-and-drop files on the ui (closes [#74](#74)) ([e1e3633](e1e3633))
* german and spanish localization ([6c440a7](6c440a7))
* improved translations ([debd3ae](debd3ae))
* integrate sparkle for auto-updates (closes [#131](#131)) ([069382c](069382c))
* localization (closes [#134](#134)) ([36e4bb0](36e4bb0))
* make system calls more parallel (closes [#160](#160)) ([a29b39f](a29b39f))
* migrate to standard os-backed preferences (closes [#161](#161)) ([e28c43f](e28c43f))
* more appealing presentation + minor refac ([67f291d](67f291d))
* nicer layout for about preferences ([03a5f77](03a5f77))
* quit button is clearer with explicit mention of the name ([6b6d748](6b6d748))
* replace default copyright with correct licence ([60b49ea](60b49ea))
* separating the quit button as it is a special case ([9fa0c06](9fa0c06))
* slightly increase contrast (mitigates [#82](#82)) ([291770e](291770e))
* support macos "sudden termination" ([671fdab](671fdab)), closes [/developer.apple.com/documentation/foundation/processinfo#1651129](https://github.com//developer.apple.com/documentation/foundation/processinfo/issues/1651129)

### BREAKING CHANGES

* Instead of asking the OS about the state of the whole system on trigger (what we do today; hard to do fast), or asking the state of the whole system on a timer (what HyperSwitch does today; inaccurate) - instead of one of 2 approaches, v3 observes the Accessibility events such as "an app was launched", "a window was closed". This means we build a cache as we receive these events in the background, and when the user trigger the app, we can show accurate state of the windows instantly.

Of course there is no free lunch, so this approach has its own issues. However from my work on it from the past week, I'm very optimistic! The thing I'm the most excited about actually is not the perf (because on my machine even v2 is instant; I have a recent macbook and no 4k displays), but the fact that we will finally have the thumbnails in order of recently-used to least-recently-used, instead of the order of their stack (z-index) on the desktop. It's a big difference! There are many more limitations that are no longer applying also with this approach.
lwouis pushed a commit that referenced this issue Mar 10, 2020
# [3.0.0](v2.3.4...v3.0.0) (2020-03-10)

### Bug Fixes

* a title change often means the content has change ([b8d6bc9](b8d6bc9))
* add rough downscaling when there are many windows (closes [#69](#69)) ([ced5ee6](ced5ee6))
* added releases link and aligned layout left on tab 3 ([6bb73dc](6bb73dc))
* also codesign debug builds ([a5f9911](a5f9911))
* app launched while in fullscreen shows first window ([c5cbcdb](c5cbcdb)), closes [/github.com//pull/114#issuecomment-576384795](https://github.com//github.com/lwouis/alt-tab-macos/pull/114/issues/issuecomment-576384795)
* auto-update preferences sync with os from launch ([b3fb222](b3fb222))
* avoid rendering if app is not used ([fdddb0f](fdddb0f))
* better float rounding = sharper cell contents ([9a96e49](9a96e49))
* better focus/order for preferences (closes [#80](#80)) ([4a8bdeb](4a8bdeb))
* better textareas ([efc9bd3](efc9bd3))
* bring back the window delay that regressed with v2 ([bb95e55](bb95e55))
* compare correctly since pid can go away when an app dies ([4ded030](4ded030))
* compiler warnings ([1faa74c](1faa74c))
* cpu and memory leaks (see discussion in [#117](#117)) ([52626aa](52626aa))
* dock being shown was blocking alt-tab ([2826a1b](2826a1b))
* don't show floating windows + efficiencies ([3f8e3ea](3f8e3ea))
* don't show ui on fast trigger ([f8e1b00](f8e1b00))
* don't trigger ui refreshes if the app is not active ([b9a0152](b9a0152))
* don't upscale thumbnails of small windows ([0bc7472](0bc7472))
* feedback token injected during ci ([effdc5f](effdc5f))
* getting sparkle ready for release ([9f1f522](9f1f522))
* handle on-all-spaces windows better ([4abe9f3](4abe9f3))
* ignore build folder ([a2bb19f](a2bb19f))
* ignore trigger shortcuts if mission control is active ([b03b0aa](b03b0aa))
* initial discovery when single space was glitching the os ([3cd4b6d](3cd4b6d))
* keyboard shortcuts didn't work without a menu ([cf92dc1](cf92dc1))
* layout is now correct; also removed layout preferences for now ([a1b5266](a1b5266))
* layout regression introduced by eed0353 ([bdc41be](bdc41be))
* layout was incorrect resulting in thumbnails clipping ([fd906f4](fd906f4))
* letsmove was not active on release builds ([6ac0658](6ac0658))
* list temporary AXDialog windows like activity monitor ([51a8838](51a8838))
* more robust screen-recording permission check ([ce574a2](ce574a2))
* notarization issues ([d125dd3](d125dd3))
* observer leak would throw and crash the app sometimes ([9ca28eb](9ca28eb))
* only test permissions on the correct os versions ([4612e37](4612e37))
* open alt-tab during space transitions (closes [#92](#92)) ([141562d](141562d))
* prevent visual flickering (closes [#115](#115)) ([9a8c83e](9a8c83e))
* quitting apps was not properly removing apps from the list ([10b2c71](10b2c71))
* quitting multiple apps would refresh the ui multiple times ([bfc2700](bfc2700))
* regression on collectionviewitem titles (not showing) ([8cb6d86](8cb6d86))
* remove debug colors ([e588d55](e588d55))
* remove unnecessary/wrong layout code ([9e719e6](9e719e6))
* sharper images on non-retina displays ([1bb4d2a](1bb4d2a))
* smaller payload for the icons ([bddb6fa](bddb6fa))
* some apps have messy launch behavior ([7eb216d](7eb216d)), closes [/github.com//issues/117#issuecomment-583868046](https://github.com//github.com/lwouis/alt-tab-macos/issues/117/issues/issuecomment-583868046)
* some apps should retry observing until it works ([0c731f4](0c731f4))
* using floor() everywhere to avoid blurry rendering ([2a36196](2a36196))

### Code Refactoring

* complete rework of the internals ([547311e](547311e)), closes [#93](#93) [#24](#24) [#117](#117) [/github.com//issues/45#issuecomment-571898826](https://github.com//github.com/lwouis/alt-tab-macos/issues/45/issues/issuecomment-571898826)

### Features

* add an app icon and menubar icon (closes [#38](#38)) ([a345dae](a345dae))
* add back the preferences for the new layout algo ([d52eb6d](d52eb6d))
* add debug profile to feedback message ([a14f965](a14f965))
* add feedback button on about window ([4046136](4046136))
* add in-app feedback form (closes [#145](#145)) ([725a030](725a030))
* add licence to about page ([cb66b79](cb66b79))
* add preference to start at login (closes [#159](#159)) ([982fe6c](982fe6c))
* adding cocoapods and letsmove/sparkle ([606bae7](606bae7))
* better packing; tall thumbnails are 1/2 the width of wide ones ([e34e3b1](e34e3b1))
* bump major version ([3c3b18c](3c3b18c))
* cleaner layout and explanation text ([fd3e768](fd3e768))
* debug build has code-signing to preserve permissions ([34a32f3](34a32f3))
* divide preferences by topic (closes [#130](#130)) ([291f872](291f872))
* drag-and-drop files on the ui (closes [#74](#74)) ([e1e3633](e1e3633))
* german and spanish localization ([6c440a7](6c440a7))
* improved translations ([debd3ae](debd3ae))
* integrate sparkle for auto-updates (closes [#131](#131)) ([069382c](069382c))
* localization (closes [#134](#134)) ([36e4bb0](36e4bb0))
* make system calls more parallel (closes [#160](#160)) ([a29b39f](a29b39f))
* migrate to standard os-backed preferences (closes [#161](#161)) ([e28c43f](e28c43f))
* more appealing presentation + minor refac ([67f291d](67f291d))
* nicer layout for about preferences ([03a5f77](03a5f77))
* quit button is clearer with explicit mention of the name ([6b6d748](6b6d748))
* replace default copyright with correct licence ([60b49ea](60b49ea))
* separating the quit button as it is a special case ([9fa0c06](9fa0c06))
* slightly increase contrast (mitigates [#82](#82)) ([291770e](291770e))
* support macos "sudden termination" ([671fdab](671fdab)), closes [/developer.apple.com/documentation/foundation/processinfo#1651129](https://github.com//developer.apple.com/documentation/foundation/processinfo/issues/1651129)

### BREAKING CHANGES

* bump major version
* Instead of asking the OS about the state of the whole system on trigger (what we do today; hard to do fast), or asking the state of the whole system on a timer (what HyperSwitch does today; inaccurate) - instead of one of 2 approaches, v3 observes the Accessibility events such as "an app was launched", "a window was closed". This means we build a cache as we receive these events in the background, and when the user trigger the app, we can show accurate state of the windows instantly.

Of course there is no free lunch, so this approach has its own issues. However from my work on it from the past week, I'm very optimistic! The thing I'm the most excited about actually is not the perf (because on my machine even v2 is instant; I have a recent macbook and no 4k displays), but the fact that we will finally have the thumbnails in order of recently-used to least-recently-used, instead of the order of their stack (z-index) on the desktop. It's a big difference! There are many more limitations that are no longer applying also with this approach.
lwouis pushed a commit that referenced this issue Mar 10, 2020
# [3.0.0](v2.3.4...v3.0.0) (2020-03-10)

### Bug Fixes

* a title change often means the content has change ([b8d6bc9](b8d6bc9))
* add rough downscaling when there are many windows (closes [#69](#69)) ([ced5ee6](ced5ee6))
* added releases link and aligned layout left on tab 3 ([6bb73dc](6bb73dc))
* also codesign debug builds ([a5f9911](a5f9911))
* app launched while in fullscreen shows first window ([c5cbcdb](c5cbcdb)), closes [/github.com//pull/114#issuecomment-576384795](https://github.com//github.com/lwouis/alt-tab-macos/pull/114/issues/issuecomment-576384795)
* auto-update preferences sync with os from launch ([b3fb222](b3fb222))
* avoid rendering if app is not used ([fdddb0f](fdddb0f))
* better float rounding = sharper cell contents ([9a96e49](9a96e49))
* better focus/order for preferences (closes [#80](#80)) ([4a8bdeb](4a8bdeb))
* better textareas ([efc9bd3](efc9bd3))
* bring back the window delay that regressed with v2 ([bb95e55](bb95e55))
* compare correctly since pid can go away when an app dies ([4ded030](4ded030))
* compiler warnings ([1faa74c](1faa74c))
* cpu and memory leaks (see discussion in [#117](#117)) ([52626aa](52626aa))
* dock being shown was blocking alt-tab ([2826a1b](2826a1b))
* don't show floating windows + efficiencies ([3f8e3ea](3f8e3ea))
* don't show ui on fast trigger ([f8e1b00](f8e1b00))
* don't trigger ui refreshes if the app is not active ([b9a0152](b9a0152))
* don't upscale thumbnails of small windows ([0bc7472](0bc7472))
* feedback token injected during ci ([effdc5f](effdc5f))
* getting sparkle ready for release ([9f1f522](9f1f522))
* handle on-all-spaces windows better ([4abe9f3](4abe9f3))
* ignore build folder ([a2bb19f](a2bb19f))
* ignore trigger shortcuts if mission control is active ([b03b0aa](b03b0aa))
* initial discovery when single space was glitching the os ([3cd4b6d](3cd4b6d))
* keyboard shortcuts didn't work without a menu ([cf92dc1](cf92dc1))
* layout is now correct; also removed layout preferences for now ([a1b5266](a1b5266))
* layout regression introduced by eed0353 ([bdc41be](bdc41be))
* layout was incorrect resulting in thumbnails clipping ([fd906f4](fd906f4))
* letsmove was not active on release builds ([6ac0658](6ac0658))
* list temporary AXDialog windows like activity monitor ([51a8838](51a8838))
* more robust screen-recording permission check ([ce574a2](ce574a2))
* notarization issues ([d125dd3](d125dd3))
* observer leak would throw and crash the app sometimes ([9ca28eb](9ca28eb))
* only test permissions on the correct os versions ([4612e37](4612e37))
* open alt-tab during space transitions (closes [#92](#92)) ([141562d](141562d))
* prevent visual flickering (closes [#115](#115)) ([9a8c83e](9a8c83e))
* quitting apps was not properly removing apps from the list ([10b2c71](10b2c71))
* quitting multiple apps would refresh the ui multiple times ([bfc2700](bfc2700))
* regression on collectionviewitem titles (not showing) ([8cb6d86](8cb6d86))
* remove debug colors ([e588d55](e588d55))
* remove unnecessary/wrong layout code ([9e719e6](9e719e6))
* sharper images on non-retina displays ([1bb4d2a](1bb4d2a))
* smaller payload for the icons ([bddb6fa](bddb6fa))
* some apps have messy launch behavior ([7eb216d](7eb216d)), closes [/github.com//issues/117#issuecomment-583868046](https://github.com//github.com/lwouis/alt-tab-macos/issues/117/issues/issuecomment-583868046)
* some apps should retry observing until it works ([0c731f4](0c731f4))
* using floor() everywhere to avoid blurry rendering ([2a36196](2a36196))

### Code Refactoring

* complete rework of the internals ([547311e](547311e)), closes [#93](#93) [#24](#24) [#117](#117) [/github.com//issues/45#issuecomment-571898826](https://github.com//github.com/lwouis/alt-tab-macos/issues/45/issues/issuecomment-571898826)

### Features

* add an app icon and menubar icon (closes [#38](#38)) ([a345dae](a345dae))
* add back the preferences for the new layout algo ([d52eb6d](d52eb6d))
* add debug profile to feedback message ([a14f965](a14f965))
* add feedback button on about window ([4046136](4046136))
* add in-app feedback form (closes [#145](#145)) ([725a030](725a030))
* add licence to about page ([cb66b79](cb66b79))
* add preference to start at login (closes [#159](#159)) ([982fe6c](982fe6c))
* adding cocoapods and letsmove/sparkle ([606bae7](606bae7))
* better packing; tall thumbnails are 1/2 the width of wide ones ([e34e3b1](e34e3b1))
* bump major version ([3c3b18c](3c3b18c))
* cleaner layout and explanation text ([fd3e768](fd3e768))
* debug build has code-signing to preserve permissions ([34a32f3](34a32f3))
* divide preferences by topic (closes [#130](#130)) ([291f872](291f872))
* drag-and-drop files on the ui (closes [#74](#74)) ([e1e3633](e1e3633))
* german and spanish localization ([6c440a7](6c440a7))
* improved translations ([debd3ae](debd3ae))
* integrate sparkle for auto-updates (closes [#131](#131)) ([069382c](069382c))
* localization (closes [#134](#134)) ([36e4bb0](36e4bb0))
* make system calls more parallel (closes [#160](#160)) ([a29b39f](a29b39f))
* migrate to standard os-backed preferences (closes [#161](#161)) ([e28c43f](e28c43f))
* more appealing presentation + minor refac ([67f291d](67f291d))
* nicer layout for about preferences ([03a5f77](03a5f77))
* quit button is clearer with explicit mention of the name ([6b6d748](6b6d748))
* replace default copyright with correct licence ([60b49ea](60b49ea))
* separating the quit button as it is a special case ([9fa0c06](9fa0c06))
* slightly increase contrast (mitigates [#82](#82)) ([291770e](291770e))
* support macos "sudden termination" ([671fdab](671fdab)), closes [/developer.apple.com/documentation/foundation/processinfo#1651129](https://github.com//developer.apple.com/documentation/foundation/processinfo/issues/1651129)

### BREAKING CHANGES

* bump major version
* Instead of asking the OS about the state of the whole system on trigger (what we do today; hard to do fast), or asking the state of the whole system on a timer (what HyperSwitch does today; inaccurate) - instead of one of 2 approaches, v3 observes the Accessibility events such as "an app was launched", "a window was closed". This means we build a cache as we receive these events in the background, and when the user trigger the app, we can show accurate state of the windows instantly.

Of course there is no free lunch, so this approach has its own issues. However from my work on it from the past week, I'm very optimistic! The thing I'm the most excited about actually is not the perf (because on my machine even v2 is instant; I have a recent macbook and no 4k displays), but the fact that we will finally have the thumbnails in order of recently-used to least-recently-used, instead of the order of their stack (z-index) on the desktop. It's a big difference! There are many more limitations that are no longer applying also with this approach.
lwouis pushed a commit that referenced this issue Mar 10, 2020
# [3.0.0](v2.3.4...v3.0.0) (2020-03-10)

### Bug Fixes

* a title change often means the content has change ([b8d6bc9](b8d6bc9))
* add rough downscaling when there are many windows (closes [#69](#69)) ([ced5ee6](ced5ee6))
* added releases link and aligned layout left on tab 3 ([6bb73dc](6bb73dc))
* also codesign debug builds ([a5f9911](a5f9911))
* app launched while in fullscreen shows first window ([c5cbcdb](c5cbcdb)), closes [/github.com//pull/114#issuecomment-576384795](https://github.com//github.com/lwouis/alt-tab-macos/pull/114/issues/issuecomment-576384795)
* auto-update preferences sync with os from launch ([b3fb222](b3fb222))
* avoid rendering if app is not used ([fdddb0f](fdddb0f))
* better float rounding = sharper cell contents ([9a96e49](9a96e49))
* better focus/order for preferences (closes [#80](#80)) ([4a8bdeb](4a8bdeb))
* better textareas ([efc9bd3](efc9bd3))
* bring back the window delay that regressed with v2 ([bb95e55](bb95e55))
* compare correctly since pid can go away when an app dies ([4ded030](4ded030))
* compiler warnings ([1faa74c](1faa74c))
* cpu and memory leaks (see discussion in [#117](#117)) ([52626aa](52626aa))
* dock being shown was blocking alt-tab ([2826a1b](2826a1b))
* don't show floating windows + efficiencies ([3f8e3ea](3f8e3ea))
* don't show ui on fast trigger ([f8e1b00](f8e1b00))
* don't trigger ui refreshes if the app is not active ([b9a0152](b9a0152))
* don't upscale thumbnails of small windows ([0bc7472](0bc7472))
* feedback token injected during ci ([effdc5f](effdc5f))
* getting sparkle ready for release ([9f1f522](9f1f522))
* handle on-all-spaces windows better ([4abe9f3](4abe9f3))
* ignore build folder ([a2bb19f](a2bb19f))
* ignore trigger shortcuts if mission control is active ([b03b0aa](b03b0aa))
* initial discovery when single space was glitching the os ([3cd4b6d](3cd4b6d))
* keyboard shortcuts didn't work without a menu ([cf92dc1](cf92dc1))
* layout is now correct; also removed layout preferences for now ([a1b5266](a1b5266))
* layout regression introduced by eed0353 ([bdc41be](bdc41be))
* layout was incorrect resulting in thumbnails clipping ([fd906f4](fd906f4))
* letsmove was not active on release builds ([6ac0658](6ac0658))
* list temporary AXDialog windows like activity monitor ([51a8838](51a8838))
* more robust screen-recording permission check ([ce574a2](ce574a2))
* notarization issues ([d125dd3](d125dd3))
* observer leak would throw and crash the app sometimes ([9ca28eb](9ca28eb))
* only test permissions on the correct os versions ([4612e37](4612e37))
* open alt-tab during space transitions (closes [#92](#92)) ([141562d](141562d))
* prevent visual flickering (closes [#115](#115)) ([9a8c83e](9a8c83e))
* quitting apps was not properly removing apps from the list ([10b2c71](10b2c71))
* quitting multiple apps would refresh the ui multiple times ([bfc2700](bfc2700))
* regression on collectionviewitem titles (not showing) ([8cb6d86](8cb6d86))
* remove debug colors ([e588d55](e588d55))
* remove unnecessary/wrong layout code ([9e719e6](9e719e6))
* sharper images on non-retina displays ([1bb4d2a](1bb4d2a))
* smaller payload for the icons ([bddb6fa](bddb6fa))
* some apps have messy launch behavior ([7eb216d](7eb216d)), closes [/github.com//issues/117#issuecomment-583868046](https://github.com//github.com/lwouis/alt-tab-macos/issues/117/issues/issuecomment-583868046)
* some apps should retry observing until it works ([0c731f4](0c731f4))
* using floor() everywhere to avoid blurry rendering ([2a36196](2a36196))

### Code Refactoring

* complete rework of the internals ([547311e](547311e)), closes [#93](#93) [#24](#24) [#117](#117) [/github.com//issues/45#issuecomment-571898826](https://github.com//github.com/lwouis/alt-tab-macos/issues/45/issues/issuecomment-571898826)

### Features

* add an app icon and menubar icon (closes [#38](#38)) ([a345dae](a345dae))
* add back the preferences for the new layout algo ([d52eb6d](d52eb6d))
* add debug profile to feedback message ([a14f965](a14f965))
* add feedback button on about window ([4046136](4046136))
* add in-app feedback form (closes [#145](#145)) ([725a030](725a030))
* add licence to about page ([cb66b79](cb66b79))
* add preference to start at login (closes [#159](#159)) ([982fe6c](982fe6c))
* adding cocoapods and letsmove/sparkle ([606bae7](606bae7))
* better packing; tall thumbnails are 1/2 the width of wide ones ([e34e3b1](e34e3b1))
* bump major version ([3c3b18c](3c3b18c))
* cleaner layout and explanation text ([fd3e768](fd3e768))
* debug build has code-signing to preserve permissions ([34a32f3](34a32f3))
* divide preferences by topic (closes [#130](#130)) ([291f872](291f872))
* drag-and-drop files on the ui (closes [#74](#74)) ([e1e3633](e1e3633))
* german and spanish localization ([6c440a7](6c440a7))
* improved translations ([debd3ae](debd3ae))
* integrate sparkle for auto-updates (closes [#131](#131)) ([069382c](069382c))
* localization (closes [#134](#134)) ([36e4bb0](36e4bb0))
* make system calls more parallel (closes [#160](#160)) ([a29b39f](a29b39f))
* migrate to standard os-backed preferences (closes [#161](#161)) ([e28c43f](e28c43f))
* more appealing presentation + minor refac ([67f291d](67f291d))
* nicer layout for about preferences ([03a5f77](03a5f77))
* quit button is clearer with explicit mention of the name ([6b6d748](6b6d748))
* replace default copyright with correct licence ([60b49ea](60b49ea))
* separating the quit button as it is a special case ([9fa0c06](9fa0c06))
* slightly increase contrast (mitigates [#82](#82)) ([291770e](291770e))
* support macos "sudden termination" ([671fdab](671fdab)), closes [/developer.apple.com/documentation/foundation/processinfo#1651129](https://github.com//developer.apple.com/documentation/foundation/processinfo/issues/1651129)

### BREAKING CHANGES

* bump major version
* Instead of asking the OS about the state of the whole system on trigger (what we do today; hard to do fast), or asking the state of the whole system on a timer (what HyperSwitch does today; inaccurate) - instead of one of 2 approaches, v3 observes the Accessibility events such as "an app was launched", "a window was closed". This means we build a cache as we receive these events in the background, and when the user trigger the app, we can show accurate state of the windows instantly.

Of course there is no free lunch, so this approach has its own issues. However from my work on it from the past week, I'm very optimistic! The thing I'm the most excited about actually is not the perf (because on my machine even v2 is instant; I have a recent macbook and no 4k displays), but the fact that we will finally have the thumbnails in order of recently-used to least-recently-used, instead of the order of their stack (z-index) on the desktop. It's a big difference! There are many more limitations that are no longer applying also with this approach.
lwouis pushed a commit that referenced this issue Mar 10, 2020
# [3.0.0](v2.3.4...v3.0.0) (2020-03-10)

### Bug Fixes

* a title change often means the content has change ([b8d6bc9](b8d6bc9))
* add rough downscaling when there are many windows (closes [#69](#69)) ([ced5ee6](ced5ee6))
* added releases link and aligned layout left on tab 3 ([6bb73dc](6bb73dc))
* also codesign debug builds ([a5f9911](a5f9911))
* app launched while in fullscreen shows first window ([c5cbcdb](c5cbcdb)), closes [/github.com//pull/114#issuecomment-576384795](https://github.com//github.com/lwouis/alt-tab-macos/pull/114/issues/issuecomment-576384795)
* auto-update preferences sync with os from launch ([b3fb222](b3fb222))
* avoid rendering if app is not used ([fdddb0f](fdddb0f))
* better float rounding = sharper cell contents ([9a96e49](9a96e49))
* better focus/order for preferences (closes [#80](#80)) ([4a8bdeb](4a8bdeb))
* better textareas ([efc9bd3](efc9bd3))
* bring back the window delay that regressed with v2 ([bb95e55](bb95e55))
* compare correctly since pid can go away when an app dies ([4ded030](4ded030))
* compiler warnings ([1faa74c](1faa74c))
* cpu and memory leaks (see discussion in [#117](#117)) ([52626aa](52626aa))
* dock being shown was blocking alt-tab ([2826a1b](2826a1b))
* don't show floating windows + efficiencies ([3f8e3ea](3f8e3ea))
* don't show ui on fast trigger ([f8e1b00](f8e1b00))
* don't trigger ui refreshes if the app is not active ([b9a0152](b9a0152))
* don't upscale thumbnails of small windows ([0bc7472](0bc7472))
* feedback token injected during ci ([effdc5f](effdc5f))
* getting sparkle ready for release ([9f1f522](9f1f522))
* handle on-all-spaces windows better ([4abe9f3](4abe9f3))
* ignore build folder ([a2bb19f](a2bb19f))
* ignore trigger shortcuts if mission control is active ([b03b0aa](b03b0aa))
* initial discovery when single space was glitching the os ([3cd4b6d](3cd4b6d))
* keyboard shortcuts didn't work without a menu ([cf92dc1](cf92dc1))
* layout is now correct; also removed layout preferences for now ([a1b5266](a1b5266))
* layout regression introduced by eed0353 ([bdc41be](bdc41be))
* layout was incorrect resulting in thumbnails clipping ([fd906f4](fd906f4))
* letsmove was not active on release builds ([6ac0658](6ac0658))
* list temporary AXDialog windows like activity monitor ([51a8838](51a8838))
* more robust screen-recording permission check ([ce574a2](ce574a2))
* notarization issues ([d125dd3](d125dd3))
* observer leak would throw and crash the app sometimes ([9ca28eb](9ca28eb))
* only test permissions on the correct os versions ([4612e37](4612e37))
* open alt-tab during space transitions (closes [#92](#92)) ([141562d](141562d))
* prevent visual flickering (closes [#115](#115)) ([9a8c83e](9a8c83e))
* quitting apps was not properly removing apps from the list ([10b2c71](10b2c71))
* quitting multiple apps would refresh the ui multiple times ([bfc2700](bfc2700))
* regression on collectionviewitem titles (not showing) ([8cb6d86](8cb6d86))
* remove debug colors ([e588d55](e588d55))
* remove unnecessary/wrong layout code ([9e719e6](9e719e6))
* sharper images on non-retina displays ([1bb4d2a](1bb4d2a))
* smaller payload for the icons ([bddb6fa](bddb6fa))
* some apps have messy launch behavior ([7eb216d](7eb216d)), closes [/github.com//issues/117#issuecomment-583868046](https://github.com//github.com/lwouis/alt-tab-macos/issues/117/issues/issuecomment-583868046)
* some apps should retry observing until it works ([0c731f4](0c731f4))
* using floor() everywhere to avoid blurry rendering ([2a36196](2a36196))

### Code Refactoring

* complete rework of the internals ([547311e](547311e)), closes [#93](#93) [#24](#24) [#117](#117) [/github.com//issues/45#issuecomment-571898826](https://github.com//github.com/lwouis/alt-tab-macos/issues/45/issues/issuecomment-571898826)

### Features

* add an app icon and menubar icon (closes [#38](#38)) ([a345dae](a345dae))
* add back the preferences for the new layout algo ([d52eb6d](d52eb6d))
* add debug profile to feedback message ([a14f965](a14f965))
* add feedback button on about window ([4046136](4046136))
* add in-app feedback form (closes [#145](#145)) ([725a030](725a030))
* add licence to about page ([cb66b79](cb66b79))
* add preference to start at login (closes [#159](#159)) ([982fe6c](982fe6c))
* adding cocoapods and letsmove/sparkle ([606bae7](606bae7))
* better packing; tall thumbnails are 1/2 the width of wide ones ([e34e3b1](e34e3b1))
* bump major version ([3c3b18c](3c3b18c))
* cleaner layout and explanation text ([fd3e768](fd3e768))
* debug build has code-signing to preserve permissions ([34a32f3](34a32f3))
* divide preferences by topic (closes [#130](#130)) ([291f872](291f872))
* drag-and-drop files on the ui (closes [#74](#74)) ([e1e3633](e1e3633))
* german and spanish localization ([6c440a7](6c440a7))
* improved translations ([debd3ae](debd3ae))
* integrate sparkle for auto-updates (closes [#131](#131)) ([069382c](069382c))
* localization (closes [#134](#134)) ([36e4bb0](36e4bb0))
* make system calls more parallel (closes [#160](#160)) ([a29b39f](a29b39f))
* migrate to standard os-backed preferences (closes [#161](#161)) ([e28c43f](e28c43f))
* more appealing presentation + minor refac ([67f291d](67f291d))
* nicer layout for about preferences ([03a5f77](03a5f77))
* quit button is clearer with explicit mention of the name ([6b6d748](6b6d748))
* replace default copyright with correct licence ([60b49ea](60b49ea))
* separating the quit button as it is a special case ([9fa0c06](9fa0c06))
* slightly increase contrast (mitigates [#82](#82)) ([291770e](291770e))
* support macos "sudden termination" ([671fdab](671fdab)), closes [/developer.apple.com/documentation/foundation/processinfo#1651129](https://github.com//developer.apple.com/documentation/foundation/processinfo/issues/1651129)

### BREAKING CHANGES

* bump major version
* Instead of asking the OS about the state of the whole system on trigger (what we do today; hard to do fast), or asking the state of the whole system on a timer (what HyperSwitch does today; inaccurate) - instead of one of 2 approaches, v3 observes the Accessibility events such as "an app was launched", "a window was closed". This means we build a cache as we receive these events in the background, and when the user trigger the app, we can show accurate state of the windows instantly.

Of course there is no free lunch, so this approach has its own issues. However from my work on it from the past week, I'm very optimistic! The thing I'm the most excited about actually is not the perf (because on my machine even v2 is instant; I have a recent macbook and no 4k displays), but the fact that we will finally have the thumbnails in order of recently-used to least-recently-used, instead of the order of their stack (z-index) on the desktop. It's a big difference! There are many more limitations that are no longer applying also with this approach.
lwouis pushed a commit that referenced this issue Mar 10, 2020
# [3.0.0](v2.3.4...v3.0.0) (2020-03-10)

### Bug Fixes

* a title change often means the content has change ([b8d6bc9](b8d6bc9))
* add rough downscaling when there are many windows (closes [#69](#69)) ([ced5ee6](ced5ee6))
* added releases link and aligned layout left on tab 3 ([6bb73dc](6bb73dc))
* also codesign debug builds ([a5f9911](a5f9911))
* app launched while in fullscreen shows first window ([c5cbcdb](c5cbcdb)), closes [/github.com//pull/114#issuecomment-576384795](https://github.com//github.com/lwouis/alt-tab-macos/pull/114/issues/issuecomment-576384795)
* auto-update preferences sync with os from launch ([b3fb222](b3fb222))
* avoid rendering if app is not used ([fdddb0f](fdddb0f))
* better float rounding = sharper cell contents ([9a96e49](9a96e49))
* better focus/order for preferences (closes [#80](#80)) ([4a8bdeb](4a8bdeb))
* better textareas ([efc9bd3](efc9bd3))
* bring back the window delay that regressed with v2 ([bb95e55](bb95e55))
* compare correctly since pid can go away when an app dies ([4ded030](4ded030))
* compiler warnings ([1faa74c](1faa74c))
* cpu and memory leaks (see discussion in [#117](#117)) ([52626aa](52626aa))
* dock being shown was blocking alt-tab ([2826a1b](2826a1b))
* don't show floating windows + efficiencies ([3f8e3ea](3f8e3ea))
* don't show ui on fast trigger ([f8e1b00](f8e1b00))
* don't trigger ui refreshes if the app is not active ([b9a0152](b9a0152))
* don't upscale thumbnails of small windows ([0bc7472](0bc7472))
* feedback token injected during ci ([effdc5f](effdc5f))
* getting sparkle ready for release ([9f1f522](9f1f522))
* handle on-all-spaces windows better ([4abe9f3](4abe9f3))
* ignore build folder ([a2bb19f](a2bb19f))
* ignore trigger shortcuts if mission control is active ([b03b0aa](b03b0aa))
* initial discovery when single space was glitching the os ([3cd4b6d](3cd4b6d))
* keyboard shortcuts didn't work without a menu ([cf92dc1](cf92dc1))
* layout is now correct; also removed layout preferences for now ([a1b5266](a1b5266))
* layout regression introduced by eed0353 ([bdc41be](bdc41be))
* layout was incorrect resulting in thumbnails clipping ([fd906f4](fd906f4))
* letsmove was not active on release builds ([6ac0658](6ac0658))
* list temporary AXDialog windows like activity monitor ([51a8838](51a8838))
* more robust screen-recording permission check ([ce574a2](ce574a2))
* notarization issues ([d125dd3](d125dd3))
* observer leak would throw and crash the app sometimes ([9ca28eb](9ca28eb))
* only test permissions on the correct os versions ([4612e37](4612e37))
* open alt-tab during space transitions (closes [#92](#92)) ([141562d](141562d))
* prevent visual flickering (closes [#115](#115)) ([9a8c83e](9a8c83e))
* quitting apps was not properly removing apps from the list ([10b2c71](10b2c71))
* quitting multiple apps would refresh the ui multiple times ([bfc2700](bfc2700))
* regression on collectionviewitem titles (not showing) ([8cb6d86](8cb6d86))
* remove debug colors ([e588d55](e588d55))
* remove unnecessary/wrong layout code ([9e719e6](9e719e6))
* sharper images on non-retina displays ([1bb4d2a](1bb4d2a))
* smaller payload for the icons ([bddb6fa](bddb6fa))
* some apps have messy launch behavior ([7eb216d](7eb216d)), closes [/github.com//issues/117#issuecomment-583868046](https://github.com//github.com/lwouis/alt-tab-macos/issues/117/issues/issuecomment-583868046)
* some apps should retry observing until it works ([0c731f4](0c731f4))
* using floor() everywhere to avoid blurry rendering ([2a36196](2a36196))

### Code Refactoring

* complete rework of the internals ([547311e](547311e)), closes [#93](#93) [#24](#24) [#117](#117) [/github.com//issues/45#issuecomment-571898826](https://github.com//github.com/lwouis/alt-tab-macos/issues/45/issues/issuecomment-571898826)

### Features

* add an app icon and menubar icon (closes [#38](#38)) ([a345dae](a345dae))
* add back the preferences for the new layout algo ([d52eb6d](d52eb6d))
* add debug profile to feedback message ([a14f965](a14f965))
* add feedback button on about window ([4046136](4046136))
* add in-app feedback form (closes [#145](#145)) ([725a030](725a030))
* add licence to about page ([cb66b79](cb66b79))
* add preference to start at login (closes [#159](#159)) ([982fe6c](982fe6c))
* adding cocoapods and letsmove/sparkle ([606bae7](606bae7))
* better packing; tall thumbnails are 1/2 the width of wide ones ([e34e3b1](e34e3b1))
* bump major version ([3c3b18c](3c3b18c))
* cleaner layout and explanation text ([fd3e768](fd3e768))
* debug build has code-signing to preserve permissions ([34a32f3](34a32f3))
* divide preferences by topic (closes [#130](#130)) ([291f872](291f872))
* drag-and-drop files on the ui (closes [#74](#74)) ([e1e3633](e1e3633))
* german and spanish localization ([6c440a7](6c440a7))
* improved translations ([debd3ae](debd3ae))
* integrate sparkle for auto-updates (closes [#131](#131)) ([069382c](069382c))
* localization (closes [#134](#134)) ([36e4bb0](36e4bb0))
* make system calls more parallel (closes [#160](#160)) ([a29b39f](a29b39f))
* migrate to standard os-backed preferences (closes [#161](#161)) ([e28c43f](e28c43f))
* more appealing presentation + minor refac ([67f291d](67f291d))
* nicer layout for about preferences ([03a5f77](03a5f77))
* quit button is clearer with explicit mention of the name ([6b6d748](6b6d748))
* replace default copyright with correct licence ([60b49ea](60b49ea))
* separating the quit button as it is a special case ([9fa0c06](9fa0c06))
* slightly increase contrast (mitigates [#82](#82)) ([291770e](291770e))
* support macos "sudden termination" ([671fdab](671fdab)), closes [/developer.apple.com/documentation/foundation/processinfo#1651129](https://github.com//developer.apple.com/documentation/foundation/processinfo/issues/1651129)

### BREAKING CHANGES

* bump major version
* Instead of asking the OS about the state of the whole system on trigger (what we do today; hard to do fast), or asking the state of the whole system on a timer (what HyperSwitch does today; inaccurate) - instead of one of 2 approaches, v3 observes the Accessibility events such as "an app was launched", "a window was closed". This means we build a cache as we receive these events in the background, and when the user trigger the app, we can show accurate state of the windows instantly.

Of course there is no free lunch, so this approach has its own issues. However from my work on it from the past week, I'm very optimistic! The thing I'm the most excited about actually is not the perf (because on my machine even v2 is instant; I have a recent macbook and no 4k displays), but the fact that we will finally have the thumbnails in order of recently-used to least-recently-used, instead of the order of their stack (z-index) on the desktop. It's a big difference! There are many more limitations that are no longer applying also with this approach.
lwouis pushed a commit that referenced this issue Mar 10, 2020
# [3.0.0](v2.3.4...v3.0.0) (2020-03-10)

### Bug Fixes

* a title change often means the content has change ([b8d6bc9](b8d6bc9))
* add rough downscaling when there are many windows (closes [#69](#69)) ([ced5ee6](ced5ee6))
* added releases link and aligned layout left on tab 3 ([6bb73dc](6bb73dc))
* also codesign debug builds ([a5f9911](a5f9911))
* app launched while in fullscreen shows first window ([c5cbcdb](c5cbcdb)), closes [/github.com//pull/114#issuecomment-576384795](https://github.com//github.com/lwouis/alt-tab-macos/pull/114/issues/issuecomment-576384795)
* auto-update preferences sync with os from launch ([b3fb222](b3fb222))
* avoid rendering if app is not used ([fdddb0f](fdddb0f))
* better float rounding = sharper cell contents ([9a96e49](9a96e49))
* better focus/order for preferences (closes [#80](#80)) ([4a8bdeb](4a8bdeb))
* better textareas ([efc9bd3](efc9bd3))
* bring back the window delay that regressed with v2 ([bb95e55](bb95e55))
* compare correctly since pid can go away when an app dies ([4ded030](4ded030))
* compiler warnings ([1faa74c](1faa74c))
* cpu and memory leaks (see discussion in [#117](#117)) ([52626aa](52626aa))
* dock being shown was blocking alt-tab ([2826a1b](2826a1b))
* don't show floating windows + efficiencies ([3f8e3ea](3f8e3ea))
* don't show ui on fast trigger ([f8e1b00](f8e1b00))
* don't trigger ui refreshes if the app is not active ([b9a0152](b9a0152))
* don't upscale thumbnails of small windows ([0bc7472](0bc7472))
* feedback token injected during ci ([effdc5f](effdc5f))
* getting sparkle ready for release ([9f1f522](9f1f522))
* handle on-all-spaces windows better ([4abe9f3](4abe9f3))
* ignore build folder ([a2bb19f](a2bb19f))
* ignore trigger shortcuts if mission control is active ([b03b0aa](b03b0aa))
* initial discovery when single space was glitching the os ([3cd4b6d](3cd4b6d))
* keyboard shortcuts didn't work without a menu ([cf92dc1](cf92dc1))
* layout is now correct; also removed layout preferences for now ([a1b5266](a1b5266))
* layout regression introduced by eed0353 ([bdc41be](bdc41be))
* layout was incorrect resulting in thumbnails clipping ([fd906f4](fd906f4))
* letsmove was not active on release builds ([6ac0658](6ac0658))
* list temporary AXDialog windows like activity monitor ([51a8838](51a8838))
* more robust screen-recording permission check ([ce574a2](ce574a2))
* notarization issues ([d125dd3](d125dd3))
* observer leak would throw and crash the app sometimes ([9ca28eb](9ca28eb))
* only test permissions on the correct os versions ([4612e37](4612e37))
* open alt-tab during space transitions (closes [#92](#92)) ([141562d](141562d))
* prevent visual flickering (closes [#115](#115)) ([9a8c83e](9a8c83e))
* quitting apps was not properly removing apps from the list ([10b2c71](10b2c71))
* quitting multiple apps would refresh the ui multiple times ([bfc2700](bfc2700))
* regression on collectionviewitem titles (not showing) ([8cb6d86](8cb6d86))
* remove debug colors ([e588d55](e588d55))
* remove unnecessary/wrong layout code ([9e719e6](9e719e6))
* sharper images on non-retina displays ([1bb4d2a](1bb4d2a))
* smaller payload for the icons ([bddb6fa](bddb6fa))
* some apps have messy launch behavior ([7eb216d](7eb216d)), closes [/github.com//issues/117#issuecomment-583868046](https://github.com//github.com/lwouis/alt-tab-macos/issues/117/issues/issuecomment-583868046)
* some apps should retry observing until it works ([0c731f4](0c731f4))
* using floor() everywhere to avoid blurry rendering ([2a36196](2a36196))

### Code Refactoring

* complete rework of the internals ([547311e](547311e)), closes [#93](#93) [#24](#24) [#117](#117) [/github.com//issues/45#issuecomment-571898826](https://github.com//github.com/lwouis/alt-tab-macos/issues/45/issues/issuecomment-571898826)

### Features

* add an app icon and menubar icon (closes [#38](#38)) ([a345dae](a345dae))
* add back the preferences for the new layout algo ([d52eb6d](d52eb6d))
* add debug profile to feedback message ([a14f965](a14f965))
* add feedback button on about window ([4046136](4046136))
* add in-app feedback form (closes [#145](#145)) ([725a030](725a030))
* add licence to about page ([cb66b79](cb66b79))
* add preference to start at login (closes [#159](#159)) ([982fe6c](982fe6c))
* adding cocoapods and letsmove/sparkle ([606bae7](606bae7))
* better packing; tall thumbnails are 1/2 the width of wide ones ([e34e3b1](e34e3b1))
* bump major version ([3c3b18c](3c3b18c))
* cleaner layout and explanation text ([fd3e768](fd3e768))
* debug build has code-signing to preserve permissions ([34a32f3](34a32f3))
* divide preferences by topic (closes [#130](#130)) ([291f872](291f872))
* drag-and-drop files on the ui (closes [#74](#74)) ([e1e3633](e1e3633))
* german and spanish localization ([6c440a7](6c440a7))
* improved translations ([debd3ae](debd3ae))
* integrate sparkle for auto-updates (closes [#131](#131)) ([069382c](069382c))
* localization (closes [#134](#134)) ([36e4bb0](36e4bb0))
* make system calls more parallel (closes [#160](#160)) ([a29b39f](a29b39f))
* migrate to standard os-backed preferences (closes [#161](#161)) ([e28c43f](e28c43f))
* more appealing presentation + minor refac ([67f291d](67f291d))
* nicer layout for about preferences ([03a5f77](03a5f77))
* quit button is clearer with explicit mention of the name ([6b6d748](6b6d748))
* replace default copyright with correct licence ([60b49ea](60b49ea))
* separating the quit button as it is a special case ([9fa0c06](9fa0c06))
* slightly increase contrast (mitigates [#82](#82)) ([291770e](291770e))
* support macos "sudden termination" ([671fdab](671fdab)), closes [/developer.apple.com/documentation/foundation/processinfo#1651129](https://github.com//developer.apple.com/documentation/foundation/processinfo/issues/1651129)

### BREAKING CHANGES

* bump major version
* Instead of asking the OS about the state of the whole system on trigger (what we do today; hard to do fast), or asking the state of the whole system on a timer (what HyperSwitch does today; inaccurate) - instead of one of 2 approaches, v3 observes the Accessibility events such as "an app was launched", "a window was closed". This means we build a cache as we receive these events in the background, and when the user trigger the app, we can show accurate state of the windows instantly.

Of course there is no free lunch, so this approach has its own issues. However from my work on it from the past week, I'm very optimistic! The thing I'm the most excited about actually is not the perf (because on my machine even v2 is instant; I have a recent macbook and no 4k displays), but the fact that we will finally have the thumbnails in order of recently-used to least-recently-used, instead of the order of their stack (z-index) on the desktop. It's a big difference! There are many more limitations that are no longer applying also with this approach.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

9 participants