Skip to content

Instantly share code, notes, and snippets.

@vfmatzkin
Last active November 3, 2024 23:37
Show Gist options
  • Save vfmatzkin/e3e3941b45e784ae9d6b074659985eb9 to your computer and use it in GitHub Desktop.
Save vfmatzkin/e3e3941b45e784ae9d6b074659985eb9 to your computer and use it in GitHub Desktop.
Same app window switcher for Win11.
/*
Window Switcher Script
---------------------
Description:
This script allows you to switch between different windows of the same application,
similar to how Alt+Tab works but only for the current application's windows.
For example, if you have multiple Chrome windows open, this will cycle through
only Chrome windows, ignoring other applications.
Shortcut:
Alt + º (the key above Tab in Spanish keyboard layout)
Features:
- Works with any application that can have multiple windows
- Special handling for File Explorer to only switch between actual folder windows
- Resets window order when switching between different applications
Date: 2024
*/
#NoEnv
#SingleInstance Force
SetWorkingDir %A_ScriptDir%
; Global variable to store the window order
global windowOrder := []
global lastIndex := 0
global lastProcess := ""
!º:: ; Alt + º
{
; Get the process name and class of the active window
WinGet, active_process, ProcessName, A
WinGet, active_id, ID, A
; Special handling for Explorer windows
if (active_process = "explorer.exe") {
; Only look for Explorer windows with CabinetWClass (file browser windows)
WinGet, window_list, List, ahk_class CabinetWClass
; Reset window order if we switched processes
if (lastProcess != "explorer.exe") {
windowOrder := []
lastProcess := "explorer.exe"
}
} else {
; For other processes, get all windows of the same process
WinGet, window_list, List, ahk_exe %active_process%
; Reset window order if we switched processes
if (lastProcess != active_process) {
windowOrder := []
lastProcess := active_process
}
}
; If window count changed, rebuild the window order
if (windowOrder.Length() != window_list) {
windowOrder := []
Loop, %window_list%
{
this_id := window_list%A_Index%
; For Explorer, only add windows that are actual file browsers
if (active_process = "explorer.exe") {
WinGetClass, this_class, ahk_id %this_id%
WinGetTitle, this_title, ahk_id %this_id%
if (this_class = "CabinetWClass" && this_title != "") {
windowOrder.Push(this_id)
}
} else {
WinGetTitle, this_title, ahk_id %this_id%
if (this_title != "") {
windowOrder.Push(this_id)
}
}
}
; Sort the window IDs to maintain consistent order
windowOrder := SortArray(windowOrder)
lastIndex := 0
}
windowCount := windowOrder.Length()
; If there's only one window, do nothing
if (windowCount <= 1)
return
; Find current window index
currentIndex := 0
Loop, % windowOrder.Length() {
if (windowOrder[A_Index] = active_id) {
currentIndex := A_Index
break
}
}
; If current window not found in list, start from beginning
if (currentIndex = 0) {
nextIndex := 1
} else {
; Move to next window
nextIndex := currentIndex + 1
if (nextIndex > windowCount)
nextIndex := 1
}
; Activate the next window
nextWindow := windowOrder[nextIndex]
WinActivate, ahk_id %nextWindow%
lastIndex := nextIndex
}
; Function to sort array (bubble sort for simplicity)
SortArray(arr) {
Loop, % arr.Length() - 1 {
i := A_Index
Loop, % arr.Length() - i {
j := A_Index
if (arr[j] > arr[j + 1]) {
temp := arr[j]
arr[j] := arr[j + 1]
arr[j + 1] := temp
}
}
}
return arr
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment