Chrome App Shortcuts and AppleScript

I’ve been struggling a bit with the syntax for an AppleScript where I close all of the open Chrome Windows that I have at the end of each day. The trick to this, though, is that I also have a few Chrome “App Shortcuts”[^0] for things like Gmail and Google Calendar that I don’t want to close.

App Shortcuts show up both as its “own app” (tell application "Gmail" to …) but also as a window in the list of open Chrome windows (e.g. tell application "Google Chrome" to return its windows). So I’m trying to find a way to filter down to only the ones that aren’t shortcuts.

Today, my solution is kind of hacky (only show me windows where either the tab count is greater than one or the active tab’s URL doesn’t start with [a site in a manual list of single site apps]). But it doesn’t seem to work very well. I’ve tried a few iterations of this:

property AppSites : {"", ""}

on isProtected(theWindow)
  tell application "Google Chrome"
    -- App Shortcuts can't have more than one tab. So if it has more than one tab, it's not protected.
    if (count of theWindow's tabs) is not 1 then
      return false
    end if

    -- The window only has one tab. So check to see if it's a "protected site"
    repeat with theURL in AppSites
      if theWindow's active tab's URL starts with theURL
        return true
      end if
    end repeat

    -- It has one tab, but it's not a protected site.
    return false
  end tell
end isProtected

tell application "Google Chrome"
  set theWindowsToClose to {}
  repeat with theWindow in its windows
    if my isProtected(theWindow) then
      copy theWindow to the end of theWindowsToClose
    end if
  end repeat

  repeat with theWindowToClose in theWindowsToClose
    close theWindowToClose
  end repeat
end tell

This actually seems like it returns the right list of windows, but calling close on this list sometimes leaves a few windows open and I’m not totally sure why. Some things to note:

  • These windows often have more than one tab and aren’t “protected sites”, so they should get closed.
  • On subsequent runs of the script, they do get closed.

So I guess, I have a few questions:

  1. Does anyone know why close theWindowToClose doesn’t always close everything? I was wondering if this was doing something index-based, maybe. And so it closes the first item, which would remove it from the list—making the second item the new first item. And then it tries to close the “second item”—which was previously the third item. Kinda confusing, maybe. Not sure if that makes sense? But it might explain why subsequent runs close more windows.

  2. Is there a better way to represent theWindowsToClose here? I tried with something like set theWindowsToClose to its windows whose …, but I’m not sure if I can call methods on the window object in the whose clause.

  3. Is there a better way to determine Chrome AppShortcuts in general? Like… maybe some specific property on the window I should be looking for? Or some way to match up window IDs across apps? (e.g. match the window ID of the “Gmail” app with some window ID in the Chrome app?)

[^0]: What’s a Chrome “App Shortcut”? You can turn basically into site into a “single site app” via “More ToolsCreate Shortcut…

I think I may have at least solved problem one here, and it did indeed appear to be an index issue.

I swapped the final repeat loop with this:

repeat with i from (count of theWindowsToClose) to 1 by -1
  close item i of theWindowsToClose
end repeat

Basically, start closing windows from the end of the list. That way AppleScript doesn’t remove the items from the list (and shift the index of the remaining items) while we’re trying to move forward through the list.