Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

Incrementally switch between windows


  • Please log in to reply
153 replies to this topic
keyboardfreak
  • Members
  • 217 posts
  • Last active: Sep 27 2010 07:21 PM
  • Joined: 09 Oct 2004

And after I think about it, that is the point eh? Not to use the mouse?

Yes, you're not supposed to use the mouse to select a window, since typing a few characters and/or using the up/down keys are much quicker.

So, never mind.

I'll take a look. Although, you're not supposed to use the mouse, it should not cause problems if you do.

  • Guests
  • Last active:
  • Joined: --

I was kind of confused at first, because I clicked the edit control. After that, I couldn't use the up/down key to switch between entries.

In the new version the Tab key is also enabled to allow switching keyboard focus back to the list box if the user clicks the input line before typing the search string.
;
; iswitchw - Incrementally switch between windows using substrings
;
;
; When this script is triggered via its hotkey the list of titles of
; all visible windows appears. The list can be narrowed quickly to a
; particular window by typing a substring of a window title.
;
; When the list is narrowed the desired window can be selected using
; the cursor keys and Enter. If the substring matches exactly one
; window that window is activated immediately (configurable, see the
; "autoactivateifonlyone" variable).
;
; The window selection can be cancelled with Esc.
;
;
; For the idea the credit goes to the creators of the iswitchb
; package for the Emacs editor
;
;
; TODO:
;
;    - Relying on generated control names (e.g. Static1) is not robust
;      Can we specify them?
;
;    - Handle doubleclick selection on the listbox
;
;----------------------------------------------------------------------
;
; User configuration 
;

; set this to blank if you don't want to select the only matching window
; automatically
autoactivateifonlyone = yes

; path to sound file played when the user types a substring which
; does not match any of the windows
;
; set this to blank if you don't want a sound
;
nomatchsound = %windir%\Media\ding.wav

if nomatchsound <>
    ifnotexist, %nomatchsound%
        msgbox, Sound file %nomatchsound% not found. No sound will be played.

;----------------------------------------------------------------------

SetTitleMatchMode, 2
wintitle = Window Switcher

Gui, Add, ListBox, vWindow x6 y11 w270 h250,
Gui, Add, Text, x6 y264 w50 h20, Search`:
Gui, Add, Edit, x66 y261 w210 h20, 

;----------------------------------------------------------------------
;
; I never use the CapsLock key, that's why I chose it.
;
CapsLock::

GuiControl,, Edit1
GoSub, RefreshWindowList

Gui, Show, x428 y215 h294 w285, %wintitle%

Loop
{
    Input, input, L1, {enter}{esc}{backspace}{up}{down}{pgup}{pgdn}{tab}

    if ErrorLevel = EndKey:enter
    {
        Gui, submit
        WinActivate, %window%
        break
    }

    if ErrorLevel = EndKey:escape
    {
        Gui, cancel
        break
    }

    if ErrorLevel = EndKey:backspace
    {
        GoSub, DeleteSearchChar
        continue
    }

    ; pass these keys to the selector window

    if ErrorLevel = EndKey:tab
    {
        Send, {tab}
        continue
    }

    if ErrorLevel = EndKey:up
    {
        Send, {up}
        continue
    }

    if ErrorLevel = EndKey:down
    {
        Send, {down}
        continue
    }

    if ErrorLevel = EndKey:pgup
    {
        Send, {pgup}
        continue
    }

    if ErrorLevel = EndKey:pgdn
    {
        Send, {pgdn}
        continue
    }

    ; FIXME: probably other error level cases
    ; should be handled here (interruption?)

    GuiControlGet, search,, Edit1
    GuiControl,, Edit1, %search%%input%
    GoSub, RefreshWindowList
}

return

;----------------------------------------------------------------------
;
; Refresh the list of windows according to the search criteria
;
RefreshWindowList:
    GuiControlGet, search,, Edit1

    winlist = |
    numwin = 0

    WinGet, id, list, , , Program Manager
    Loop, %id%
    {
        StringTrimRight, this_id, id%a_index%, 0
        WinGetTitle, title, ahk_id %this_id%

        ; don't add windows with empty titles
        if title =
            continue

        ; don't add the switcher window
        if title contains %wintitle%
            continue

        ; don't add the windows not matching the search string
        ; if there is a search string
        if title not contains %search%,
            continue

        winlist = %winlist%%title%|
        numwin += 1
    }

    ; if the pattern didn't match any window
    if numwin = 0
        ; if the search string is empty then we can't do much
        if search = 
        {
            msgbox, There are no windows on the screen.
            exit
        }
        ; delete the last character
        else
        {
            if nomatchsound <>
                SoundPlay, %nomatchsound%

            GoSub, DeleteSearchChar
            return
        }

    ; show the list
    Sort, winlist, D|
    GuiControl,, ListBox1, %winlist%
    GuiControl, Choose, ListBox1, 1

    if numwin = 1
        if autoactivateifonlyone <>
        {
            Gui, submit
            WinActivate, %window%
            exit
        }

return

;----------------------------------------------------------------------
;
; Delete last search char and update the window list
;
DeleteSearchChar:

GuiControlGet, search,, Edit1

if search =
    return

StringTrimRight, search, search, 1
GuiControl,, Edit1, %search%
GoSub, RefreshWindowList

return


keyboardfreak
  • Members
  • 217 posts
  • Last active: Sep 27 2010 07:21 PM
  • Joined: 09 Oct 2004
Again I forgot to login. I'm not used to forums which allow guest logins.

Chris
  • Administrators
  • 10727 posts
  • Last active:
  • Joined: 02 Mar 2004
If your system allows cookies, you shouldn't have to login on subsequent visits. But maybe the cookies get messed up sometimes...

  • Guests
  • Last active:
  • Joined: --
This is freakin' AWESOME. It is unbelievable how much time is saved, and more important, how often it prevents me from losing my train of thought because I had to spend 5-10 seconds alt-tabbing thru 30 windows to get the one I need.

If you have ideas how to improve the script I'm interested.


How about this to save even more keystrokes: once the list has been narrowed down to less than 10 items, put a number in front of each one, then you just have to type that digit to activate it. This way, you don't have to use the arrow keys, or think of which characters you need to type to make a unique subtring - just one keystroke and you're done. I think you wouldn't even need to hit TAB first to change the focus to the list, as the script can catch the digits 0-9 and not pass them through to the search field - sure, you sacrifice the ability to use numbers in your search string, but I don't know that this is a problem - I've been keeping an eye on my window titles over the last few hours and even when there are 30-40 windows open, it is very rare for there to be a number in the title string.

keyboardfreak
  • Members
  • 217 posts
  • Last active: Sep 27 2010 07:21 PM
  • Joined: 09 Oct 2004

How about this to save even more keystrokes: once the list has been narrowed down to less than 10 items, put a number in front of each one, then you just have to type that digit to activate it. This way, you don't have to use the arrow keys, or think of which characters you need to type to make a unique subtring - just one keystroke and you're done.

Interesting idea, although I'd only add it as an option. I think mapping the items of the narrowed list to numbers takes more time mentally, than quickly selecting an item with the up/down keys.

Soapspoon
  • Members
  • 8 posts
  • Last active: Jan 19 2006 07:18 PM
  • Joined: 23 Nov 2004
This is awesome. I have been spending some time lately looking for good scriptable hotkey programs, and this script + AutoHotkey just blew me away.

Great work, similar to Quicksilver on OSX... completely changes how one deals with tasks. Now of course I have to spend some time poring over this and figuring out how it works. Very cool, dude.


Possible (really minor) improvement: Since your left pinky is already on the CapsLock key when you're doing this operation, would it be possible to make CapsLock function like Enter to select an entry in the list?

Completely 100% bonkers improvement: Quicksilver does some kind of magical incremental matching where the letters don't need to be adjacent, and it picks the closest match. Then you can do things like type "vssa" to find "Visual Sourcesafe Explorer - Apps". Like I said, insane... but it sure would be cool.

jonny
  • Members
  • 2951 posts
  • Last active: Feb 24 2008 04:22 AM
  • Joined: 13 Nov 2004

would it be possible to make CapsLock function like Enter to select an entry in the list?


Only problem with that is CapsLock is the most useless, redundant key ever that just happens to be a centimeter away from the home row. It's used for lots of things in scripts. When I make scripts, I almost always include CapsLock for something, and when I'm using my "big script" that has all the scripts I use, it's mapped to the most used key on my keyboard: Backspace :lol: (Ctrl+Z is a close second) But the point is, that would cause a lot of compatibility issues, that is if everything remaps CapsLock like I do.

Soapspoon
  • Members
  • 8 posts
  • Last active: Jan 19 2006 07:18 PM
  • Joined: 23 Nov 2004
Ahh, I meant as an optional setting thing, like the other parameters at the top - I can see how that would cause trouble though.

keyboardfreak
  • Members
  • 217 posts
  • Last active: Sep 27 2010 07:21 PM
  • Joined: 09 Oct 2004

Possible (really minor) improvement: Since your left pinky is already on the CapsLock key when you're doing this operation, would it be possible to make CapsLock function like Enter to select an entry in the list?

There were some concerns about my choosing CapsLock as the activation key for the script. Now it can be changed easily at the beginning of the script, so I'd avoid hardcoding it in more than one places.

But your suggestion should not be hard to implement. You can also do it for yourself as practice.

Quicksilver does some kind of magical incremental matching where the letters don't need to be adjacent, and it picks the closest match. Then you can do things like type "vssa" to find "Visual Sourcesafe Explorer - Apps". Like I said, insane... but it sure would be cool.

I used a similar feature of the TCSH shell for file completion. There it works similarly to your description: if there is a file called test.tar.gz, you can complete it as "ttg" and so on.

In my experience in most of the cases it gets in your way, slows you down (you have to stop and think), instead of speeding things up. Maybe it's only me, but I'm not entirely convinced about the usefulness of this feature.

keyboardfreak
  • Members
  • 217 posts
  • Last active: Sep 27 2010 07:21 PM
  • Joined: 09 Oct 2004
An improvement to spare even more keyboard presses.

Changes:

[*:3qe4eq2b]autoactiveifonlyone is disabled by default. It takes a bit of time to get used to, so it is disabled for novice users.
[*:3qe4eq2b]If enabled possible completions are offered when the same unique substring is found in the title of more than one window.

For example, the user typed the string "co" and the list is narrowed to two windows: "Windows Commander" and "Command Prompt". In this case the "command" substring can be completed automatically, so the script offers this completion in square brackets which the user can accept with the TAB key:

co[mmand]

This feature can be confusing for novice users, so it is disabled by default.Edit: See the latest version of the script in the first post.

  • Guests
  • Last active:
  • Joined: --
Oh man, nice upgrade with the tab completion. I've completely stopped using alt-tab and AutoHotkey is taking over my brain. Thanks.

jonny
  • Members
  • 2951 posts
  • Last active: Feb 24 2008 04:22 AM
  • Joined: 13 Nov 2004
Whoa... I figured after I posted here I should at least try this out, and I was taken aback by this script's resemblance to SlickSwitch. (Separated at birth? :D) I used SlickSwitch very frequently, as I hated alt+tab and all the good mod software for it was shareware. Now I'm torn between these two. I'm leaning more towards this, though, because I can configure it, it has more features, and it looks better too. :wink:

Chris
  • Administrators
  • 10727 posts
  • Last active:
  • Joined: 02 Mar 2004
This useful script is going in the showcase one of these days.

jonny
  • Members
  • 2951 posts
  • Last active: Feb 24 2008 04:22 AM
  • Joined: 13 Nov 2004
I just had a (maybe) great idea. If anyone here's used a Linux system, you're probably familiar with the Kasbar. It would be really neato to have window thumbnails, like the kind you get when you hover a kasbar item. I know this is a real long shot, but is that possible? Possibly using PrintScreen and the clipboard? That would also be something cool to make using the taskbar. (i.e. on hover a taskbar item, show a screenshot of the window)

I can only think of two ways that would ever be possible, and that's with PixelGetColor or PrintScreen/GUI image (the latter wouldn't grab a single window, so itd be a little harder).