19

How can I use Autohotkey to focus on an existing Google Chrome tab, not a "container" window?

Details

Google Chrome seems to represent each window with a container window handle, which contains one or more tabs. The tabs (at least the current one), has its own window handle. The tab window handles have window titles (which currently all end in " - Google Chrome"), whereas the container window handle itself does not. The following autohotkey code does not work as intended for Google Chrome:

^+i::
if WinExist("ahk_class Chrome_WidgetWin_0")
    WinActivate
else
    Run "C:\Users\vleeshue\AppData\Local\Google\Chrome\Application\chrome.exe"
return

This binding will focus on a Google Chrome window if it exists or will run Google Chrome. However, it will often target the container window (in Window Spy, the window title is blank). Activating the container window disallows the use of Google Chrome keyboard shortcuts. The inaccessible keyboard shortcuts include the all important ctrl+l to access the omnibar. Since I have not yet found a way to consistently activate the tab window instead of the container window, my workaround is to use the mouse, but I'd prefer to avoid that if possible.

Window Spy Screenshots

Container Window Handle

Tab Window Handle

Background

Current Google Chrome Version: 5.0.317.2 dev

A common autohotkey binding I use is a keyboard shortcut to focus a specific application if it's already running or to run the application if it isn't running.

For example, I use this for foobar2000

^+m::
If WinExist("foobar2000")
    WinActivate
else
    Run "C:\Program Files (x86)\foobar2000\foobar2000.exe"
return

9 Answers 9

6
^+i::
if WinExist("ahk_class Chrome_WindowImpl_0")
  {
  WinActivate
  ControlFocus, Chrome_AutocompleteEditView1
  }
else
  Run "C:\Users\vleeshue\AppData\Local\Google\Chrome\Application\chrome.exe"
return

Should do the trick

("Chrome_AutocompleteEditView1" is the name of the omnibar control, so you could add Send ^a to select all)

Note: To get the ahk_class for your version of Chrome, e.g., ahk_class Chrome_WindowImp1-0, use the AU3_Spy.exe inside the autohotkey directory. This will allow you to find the correct ahk class for your chrome browser if the example one doesn't work.

Update: I can't reproduce, maybe it will be better with another control... To have a list of a window controls I use this code:

#Persistent
SetTimer, WatchCursor, 100
return

WatchCursor:
  MouseGetPos, , , id, control
  WinGetTitle, title, ahk_id %id%
  WinGetClass, class, ahk_id %id%
  WinGet, ControlList, ControlList, A
  ToolTip, Under Cursor:`nahk_id: %id%`nahk_class: %class%`nTitle:%title%`nControl: %control%`n`nWindow Control List:`n%ControlList%
return

So the controls of my google chrome 4.0.249.78 beta (36714) are:

  • ViewsTextfieldEdit1
  • Chrome_RenderWidgetHostWND1
  • Chrome_AutocompleteEditView1
  • Chrome_WindowImpl_01
  • Chrome_WindowImpl_02
7
  • Thank you very much. This seems to work much more often than my previous function (had to change ahk_class Chrome_WindowImpl_0 to ahk_class Chrome_WidgetWin_0, but that may just be due to different versions of Google Chrome). Unfortunately, it still doesn't work some of the time and that case is hard to reproduce. Once I get locked onto a container window (see screenshot in question post), I have to still resort to the mouse.
    – vleeshue
    Feb 10, 2010 at 22:23
  • How would I get a list of Google Chrome controls? After using this a bit, I would prefer focusing on the "content" window. For example, if the active tab is Google Reader or gmail, I would like access to their keyboard shortcuts, which only apply when focusing on the "content" window. Furthermore, focusing on the "content" window allows faster page searching. Also, to get to the omnibar from the "content" window, I can always use ctrl+l.
    – vleeshue
    Feb 10, 2010 at 22:50
  • 1
    Yes it could be better with another control, see my update
    – fluxtendu
    Feb 10, 2010 at 22:59
  • Hmm... I get: Chrome_WidgetWin_01, Chrome_WidgetWin_02, Chrome_RenderWidgetHostHWND1, ViewsTextfieldEdit1, Chrome_AutocompleteEditView1. Time to deduce which control I want. Thanks! Update1: some quick testing reveals Chrome_WidgetWin_01 does what I want. My guess is the additional ones are spawned based on the page content. Update2: a google reader tab definitely has at least one more control than this superuser edit tab.
    – vleeshue
    Feb 10, 2010 at 23:14
  • Unfortunately, I'm running into the "container" window again (blank window title in window spy) and had to undo the accepted answer tag. You have been a great help though.
    – vleeshue
    Feb 10, 2010 at 23:26
4

You may want to look at using a Chrome extension instead of AutoHotkey. Extensions can get access to all the open tabs, including the URL and the ability to change tab focus. Otherwise you probably would need to use the Accessibility features in Chrome to query the active window. I believe that is how programs like RescueTime track what the active URL is. For example, using the Accessible Event Watcher (AccEvent) from the Windows 7 SDK shows the following events when changing tabs in Chrome:

Google Chrome AccEvent

2
  • I did not know about this. Thanks for the heads up.
    – vleeshue
    Feb 10, 2010 at 22:24
  • It looks like AutoHotkey has some support for working with the iAccessible interface. Might want to try this and see if it helps: autohotkey.com/forum/viewtopic.php?t=48629
    – Greg Bray
    Feb 11, 2010 at 22:40
3

Workaround using Alt+Tab:

; Activates the window identified with wintitle if it's active,
; else opens a new one
OpenWindow(wintitle, runCommand)
{
    if WinExist(wintitle)
        WinActivate ; activates the window found above. Sweet.
    else
        Run %runCommand%
}

#g::
AppsKey & g::
    prevKeyDelay := A_KeyDelay
    SetKeyDelay, 100
    OpenWindow("ahk_class Chrome_WidgetWin_0", A_AppData
                . "\Local\Google\Chrome\Application\chrome.exe")
    SendEvent {Alt down}{Tab}
    SendEvent +{Tab}
    SendEvent {Alt up}
    SetKeyDelay, prevKeyDelay
return

Adjust arguments as needed. SetKeyDelay used because sending too fast does not work.

1

if you want to find a tab of chrome you can use this

SetTitleMatchMode, 2
If WinExist("your title ahk_exe chrome.exe")

     .... do your stuff ... 

else {
     .... do your other stuff ...
}

return

since in chrome everything is a process, your tabs are also processes.

0

Window Spy returns the tab title in the "Visible Window Text" field.

You could loop in the tabs until you find the desired text. To switch from tab to tab, send the CTRL+TAB keys. The problem would be to stop at some point but if you know you don't use more than X tabs at most, you can include a counter in the loop to break at some point if the desired tab is not found.

1
0

There seems to be a bug with the WinActivate function in AutoHotkey. (http://productivegeek.com/forums/topic/autohotkey-problem-restoring-minimized-window-and-giving-keyboard-focus)

So instead of the WinActivate line, use

WinGet, winid, ID, 
DllCall("SwitchToThisWindow", "UInt", winid, "UInt", 1)
0
!f::
    IfWinExist ahk_class Chrome_WidgetWin_0
    {   IfWinActive ahk_class Chrome_WidgetWin_0
        {   Loop, 60
            {   GetKeyState, state, C
                if state = D
                {   KeyWait, c

                    KeyWait, LAlt
                    Sleep 10

                    ;must send RCtrl!!!
                    Send {RCtrl down}
                    Send {w down}
                    Sleep 10
                    Send {w up}
                    Send {RCtrl up}

                    break
                }
                Sleep 1
            }

        }

        else
        {   KeyWait,f
            KeyWait,LAlt
            ;don't hijack other apps
            Send f
        }
    }

    return
1
  • 2
    Care to explain a little what this does?
    – slhck
    May 15, 2012 at 21:30
0

See if this helps or gives you more ideas. I am not using any of the above.

!z::
WinWait, Yahoo,
IfWinNotActive, Yahoo, , WinActivate,Yahoo,
WinWaitActive, Yahoo, 
Sleep, 100
return
1
  • 1
    While this may answer the question, it would be a better answer if you could provide some explanation why it does so.
    – DavidPostill
    Apr 7, 2016 at 17:53
0

This AHK function will activate a Google Chrome tab if it exists and return true. Otherwise, it will return false.

; Activates tab in Google Chrome if it exists
; Returns true if exists, false if does not exist
; Leaves original tab activated if sought tab does not exist
; Known issue: will stop searching tabs if two tabs have same name
ActivateChromeTab(soughtTab)
{
  SetTitleMatchMode 2 ; Allows for partial matches in window titles

  IfWinNotExist Google Chrome
  {
    return false
  }

  WinActivate Google Chrome
  WinWaitActive Google Chrome
  WinGetTitle, currentTab, A
  firstTab := currentTab

  if (InStr(currentTab, soughtTab) > 0)
  {
    return true
  }

  Loop
  {
    Send {CtrlDown}{Tab}{CtrlUp}
    Sleep 50 ; Requires some time to update the window titles
    WinGetTitle, currentTab, A
    foundTab := InStr(currentTab, soughtTab) > 0
  }
  Until (foundTab || currentTab == firstTab)

  return foundTab
}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .