Global keyboard shortcut to open a tab in Chrome on Mac OS X

7

4

What is the best way to configure a global keyboard shortcut to open a tab in Chrome on Mac OS X?

Caveats

  • It should be as simple as possible, so I don't want to <alt><tab> + <cmd><t> every time.
  • This must be global, so if I press my shortcut (which happens to be <cmd><return>) while I'm in Mail.app, it needs to bring Chrome to the front and open a new tab
  • It needs to open the new tab page, i.e. chrome://newtab, not a website like http://www.google.com
  • The highest priority is that it opens fast fast fast, the next priority is ease of configuration

Current Solution

Right now I've got Quicksilver.app configured to execute the following AppleScript (or osascript to be precise) whenever I press <cmd><return>:

#!/usr/bin/osascript

tell application "Google Chrome Canary"
    activate
end tell

tell application "System Events"
    tell process "Google Chrome Canary"
        tell menu bar 1
            tell menu bar item "File"
                tell menu "File"
                    click menu item "New Tab"
                end tell
            end tell
        end tell
    end tell
end tell

The problem with this is that it can take up to 5 seconds if it has been a while since I ran it last. I had complied this into a *.app, but that was slower than making it an executable osascript. I'm not afraid to try developing a compiled version of the above script, but I'm a UNIX/web developer, not OS X, and I'm not familiar with the system.

aaron

Posted 2011-06-01T14:10:37.300

Reputation: 481

Place that script in ~/Library/Scripts and enable the Scripts menu item in AppleScript Editor's preferences. Don't use it for a while, then invoke using that menu. I'm afraid the delay is inherent to AppleScript needing to load up, and this is the "purest" solution I can think of (except invoking the script application directly from Finder) to try to narrow down the causes. – Daniel Beck – 2011-06-01T14:30:10.527

Answers

6

You can run the following Terminal command (e.g. in a bash script):

open -a "Google Chrome" chrome://newtab

This will cause the application Google Chrome to open the URL chrome://newtab, thereby opening a new tab.

Unfortunately, Google Chrome doesn't register the chrome:// URL type with Launch Services, and it will think that's a file path.

To fix this, right-click Google Chrome's application bundle, select Show Package Contents, open the Contents directory and edit Info.plist in a text editor.

Search for CFBundleURLTypes. Edit the following few lines to add the lines indicated by a +:

<key>CFBundleURLTypes</key>
<array>
+   <dict>
+       <key>CFBundleURLName</key>
+       <string>Chrome Internal URLs</string>
+       <key>CFBundleURLSchemes</key>
+       <array>
+           <string>chrome</string>
+       </array>
+   </dict>
    <dict>
        <key>CFBundleURLName</key>
        <string>Web site URL</string>

Save and close. Move Google Chrome's application bundle to a different directory, and back again, to make Launch Services pick up the change (if it doesn't work, log out and back in).

Then, run open like described at the beginning.


Once this works, your best option is to run a shell script that performs the open command, which in turn is invoked e.g. by your launcher. Since I believe the delay is caused by osascript loading, pretty much any solution you choose here should be fast enough.


To semi-automate the editing of the Info.plist file (you have to repeat this for all Chrome updates), you can use PlistBuddy in Terminal. First, create a file e.g. named chrome-url.plist with the following content:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<array>
  <dict>
    <key>CFBundleURLName</key>
    <string>Chrome Internal URLs</string>
    <key>CFBundleURLSchemes</key>
    <array>
        <string>chrome</string>
    </array>
    </dict>
</array>
</plist>

Then, you can use the following to patch Chrome's Info.plist:

/usr/libexec/PlistBuddy -c "Merge '/path/to/chrome-url.plist' :CFBundleURLTypes" /Applications/Google\ Chrome.app/Contents/Info.plist

Daniel Beck

Posted 2011-06-01T14:10:37.300

Reputation: 98 421

You will need to repeat editing the Info.plist file for every Chrome version. – Daniel Beck – 2011-06-01T14:42:50.193

Chrome keeps overwriting the Info.plist file with the original, so it throws away the additions to the URLTypes. Any ideas how I could make this more permanent? Thanks. – aaron – 2011-06-02T14:27:30.133

@aaron Lock that file and/or remove permissions to edit from your user. – Daniel Beck – 2011-06-02T14:31:56.387

Do you have any idea whether that will cause other problems (like not saving preferences)? – aaron – 2011-06-02T14:39:43.257

@aaron Preferences are not saved in the application bundle, since they are private to each user and Mac OS X is a multi-user system. I assume this is the result of a periodic integrity check of the actual Chrome application itself, similar to how Windows requests (requested?) you insert the disk for repairing the system when you delete files you shouldn't have deleted. It is quite common for users on Mac OS X to not have permission to write to applications in /Applications. – Daniel Beck – 2011-06-02T14:53:01.353

5

Chrome now has support for global shortcuts built in, and I created the Global New Tab Shortcut extension to leverage it.

Install it, assign a shortcut and set the scope to Global, and you get super-fast access to the OmniBar.

w00t

Posted 2011-06-01T14:10:37.300

Reputation: 811

1

You won't have to keep modifying Chrome if you send it a "get url" AppleEvent directly. Use this:

tell application "Google Chrome"
    open location "chrome://newtab"
end tell

LaC

Posted 2011-06-01T14:10:37.300

Reputation: 2 263

this is good, although the performance problem seemed to be largely caused by using AppleScript/osascript in the first place. I appreciate the tip though! – aaron – 2011-06-01T21:34:07.923

Then use python with appscript. – LaC – 2011-06-01T23:28:29.610

python just wraps applescript, right? i don't see how this would improve performance – aaron – 2011-06-02T14:23:58.073

@aaron It doesn't. Both py-appscript and rb-appscript also suffer from that delay when run for the first time. Selecting menu items (and other System Events calls) can even be slower than in AppleScript. – Lri – 2011-06-02T14:47:09.483

0

One way to do this is via an Automator Service:

  1. Create a new "Service" Automator document.
  2. Change the input type to "no input." ("Service receives no input")
  3. Drag the "Run AppleScript" action to the Automator script.
  4. Paste in the script below.
  5. Save the script as e.g. "Focus New Chrome Tab".
  6. Open the "Keyboard" pane in System Preferences.
  7. Choose the "Shortcuts" tab, and then select "Services".
  8. In the list of services, find "Focus New Chrome Tab".
  9. Enable it, and add a keybinding for "Focus New Chrome Tab".

Test by switching to e.g. iTunes, opening the "iTunes | Services" menu. "Focus New Chrome Tab" should be listed, along with the keybinding you selected. Hit the keybinding, and you should get a new Chrome tab.

[Note that there's a bug in that before the "global" keybinding works in a given application, you need to open its Services menu, which makes it somewhat annoying to use for the moment.]

Script to add in step (4):

tell application "Google Chrome"
    open location "chrome://newtab"
    activate
end tell

mjs

Posted 2011-06-01T14:10:37.300

Reputation: 100