1. 27
  1. 4

    I use Hammerspoon to customize my Mac app switching in a lot of similar ways. I mapped “hyper” key to caps lock using Karabiner Elements. Hyper+B is browser, Hyper+T is text editor, Hyper+S is my shell. Hyper+0 is “previous window” instead of previous app. I have fuzzy finders built with Hammerspoon that let me fuzzy find among all open windows or open windows per app. Hyper+N moves the current window to the next monitor, Hyper+1-9 sizes windows in various ways (1/2s, 1/3s, etc.). Hammerspoon is super useful!

    If anyone cares, here’s my config: https://github.com/kbd/setup/blob/master/HOME/.hammerspoon/init.fnl (in Fennel lisp :)

    1. 1

      I had no idea this is possible.

      fennel = require("fennel")
      table.insert(package.loaders or package.searchers, fennel.searcher)
      fennel.dofile("init.fnl") -- exports into global namespace
      

      I wonder if Python would also be possible.

      1. 2

        Fennel is great! But it specifically integrates with Lua, Python wouldn’t work the same way.

    2. 3

      I don’t suppose CGWindowListCreate() and CGWindowListCreateDescriptionFromArray() is available in the sandbox and give enough info?

      1. 2

        CGWindowListCreate() doesn’t seem to be available in Swift: Xcode screenshot

        CGWindowListCreateDescriptionFromArray() returns an empty array no matter what I use as arguments.

        But curiously, CGWindowListCopyWindowInfo(.optionAll, 0) seems to work.

        I’ll take a look at that, thanks for pointing me in another direction! Although I’m pretty sure the App Store reviewer will point out that I’m linking to _CGWindowListCopyWindowInfo which is a deprecated symbol or something. That’s how it usually goes.

        1. 1

          I added a tiny Obj-C file that calls these functions and returns a list to Swift.

          -(NSArray*)windows {
              CFArrayRef windowListArray = CGWindowListCreate(kCGWindowListOptionOnScreenOnly|kCGWindowListExcludeDesktopElements, kCGNullWindowID);
              NSArray *windows = CFBridgingRelease(CGWindowListCreateDescriptionFromArray(windowListArray));
              CFRelease(windowListArray);
              
              return windows;
          }
          
          1. 1

            Wow ok! It works.

            I guess I’ll try to find a non-deprecated way to focus a window by its ID :)

      2. 2

        Holey moley.

        Install Hammerspoon which only shows text instructions on how to download and install the app manually

        Is this via the app store or external? If it’s external then I wonder how this route compares with releasing two versions of rcmd (one app-store without window switching, the other external with window switching). I don’t have any experience with this ecosystem so maybe this could make things worse.

        It passed App Review without a single rejection.

        Clearly you’re not trying hard enough!

        1. 4

          Is this via the app store or external?

          rcmd is strictly on the App Store.

          Releasing an app outside the App Store is a much harder endeavour as you need to do your own payment processing, license verification and server, crash/traceback reporting, automatic updates logic, reviews and privacy-focused analytics.

          I was forced to do that for Lunar because that app uses a lot of low-level and private APIs that are forbidden on the App Store. But I really did not enjoy that part.

          I’d rather focus on the app logic code which is why I’m going to so great lengths to keep apps on the App Store.

          It passed App Review without a single rejection.

          Clearly you’re not trying hard enough!

          I’m fighting with App Review constantly 😅 this was a surprising exception