Last active
March 2, 2023 07:08
-
-
Save niski84/2dbcc188823872f37c234b6db578a1d0 to your computer and use it in GitHub Desktop.
switch windows focus and fullscreen app using best guess at window title
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"flag" | |
"fmt" | |
"os" | |
"unsafe" | |
"github.com/AllenDang/w32" | |
) | |
func main() { | |
windowTitlePtr := flag.String("title", "", "window title") | |
flag.Parse() | |
if *windowTitlePtr == "" { | |
fmt.Println("Window title is required") | |
os.Exit(1) | |
} | |
// Get all windows and their titles | |
var titles []string | |
w32.EnumWindows(w32.NewEnumProc(func(hwnd w32.HWND, lParam w32.LPARAM) bool { | |
if w32.IsWindowVisible(hwnd) { | |
title, _ := w32.GetWindowText(hwnd) | |
titles = append(titles, title) | |
} | |
return true | |
}), 0) | |
// Find the closest matching window title | |
closestMatch := "" | |
closestDistance := len(*windowTitlePtr) | |
for _, title := range titles { | |
distance := levenshteinDistance(*windowTitlePtr, title) | |
if distance < closestDistance { | |
closestMatch = title | |
closestDistance = distance | |
} | |
} | |
if closestMatch == "" { | |
fmt.Printf("Could not find window title that matches '%s'\n", *windowTitlePtr) | |
os.Exit(1) | |
} | |
fmt.Printf("Found window title '%s' (distance %d)\n", closestMatch, closestDistance) | |
hwnd := w32.FindWindow(nil, closestMatch) | |
if hwnd == 0 { | |
fmt.Printf("Could not find window with title '%s'\n", closestMatch) | |
os.Exit(1) | |
} | |
w32.SetForegroundWindow(hwnd) | |
w32.ShowWindow(hwnd, w32.SW_MAXIMIZE) | |
} | |
// Calculates the Levenshtein distance between two strings | |
func levenshteinDistance(a, b string) int { | |
m := len(a) | |
n := len(b) | |
if m == 0 { | |
return n | |
} | |
if n == 0 { | |
return m | |
} | |
if a == b { | |
return 0 | |
} | |
v0 := make([]int, n+1) | |
v1 := make([]int, n+1) | |
for i := 0; i <= n; i++ { | |
v0[i] = i | |
} | |
for i := 0; i < m; i++ { | |
v1[0] = i + 1 | |
for j := 0; j < n; j++ { | |
cost := 1 | |
if a[i] == b[j] { | |
cost = 0 | |
} | |
v1[j+1] = min(v1[j]+1, v0[j+1]+1, v0[j]+cost) | |
} | |
for j := 0; j <= n; j++ { | |
v0[j] = v1[j] | |
} | |
} | |
return v1[n] | |
} | |
// Returns the minimum of three integers | |
func min(a, b, c int) int { | |
if a < b { | |
if a < c { | |
return a | |
} | |
return c | |
} | |
if b < c { | |
return b | |
} | |
return c | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment