146 lines
3.6 KiB
Go
146 lines
3.6 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"log"
|
|
"os"
|
|
"slices"
|
|
"strconv"
|
|
"syscall"
|
|
|
|
// _ "embed"
|
|
"fyne.io/systray"
|
|
hook "github.com/robotn/gohook"
|
|
)
|
|
|
|
var (
|
|
us32 = syscall.MustLoadDLL("user32.dll")
|
|
SetForegroundWindow = us32.MustFindProc("SetForegroundWindow")
|
|
GetForegroundWindow = us32.MustFindProc("GetForegroundWindow")
|
|
)
|
|
|
|
// //go:embed duck2.jpg
|
|
// var icon []byte
|
|
var Error *log.Logger
|
|
var Warning *log.Logger
|
|
|
|
func init() {
|
|
log.SetFlags(log.Lmicroseconds | log.Lshortfile)
|
|
logFile, err := os.Create("main.log")
|
|
if err != nil {
|
|
log.Printf("Error creating log file: %v", err)
|
|
os.Exit(1)
|
|
}
|
|
logger := io.MultiWriter(os.Stdout, logFile)
|
|
log.SetOutput(logger)
|
|
|
|
Error = log.New(io.MultiWriter(logFile, os.Stderr, os.Stdout),
|
|
fmt.Sprintf("%sERROR:%s ", "\033[0;101m", "\033[0m"),
|
|
log.Lmicroseconds|log.Lshortfile)
|
|
Warning = log.New(io.MultiWriter(logFile, os.Stdout),
|
|
fmt.Sprintf("%sWarning:%s ", "\033[0;93m", "\033[0m"),
|
|
log.Lmicroseconds|log.Lshortfile)
|
|
}
|
|
|
|
var windows = make([]uintptr, 10, 10)
|
|
|
|
func main() {
|
|
go systray.Run(onReady, nil)
|
|
|
|
hook.Register(hook.KeyDown, []string{"alt", "-"}, func(e hook.Event) {
|
|
hwnd, _, _ := GetForegroundWindow.Call()
|
|
TrackWindow(hwnd)
|
|
})
|
|
|
|
for i := 1; i <= 9; i++ {
|
|
tabIndex := i - 1
|
|
log.Printf("Registering tab %d", tabIndex)
|
|
hook.Register(hook.KeyDown, []string{"alt", strconv.Itoa(i)}, func(e hook.Event) {
|
|
TabTo(tabIndex)
|
|
})
|
|
hook.Register(hook.KeyDown, []string{"alt", "shift", strconv.Itoa(i)}, func(e hook.Event) {
|
|
Swap(tabIndex)
|
|
})
|
|
}
|
|
|
|
s := hook.Start()
|
|
<-hook.Process(s)
|
|
}
|
|
func TabTo(idx int) {
|
|
log.Printf("TabTo: %d", idx)
|
|
log.Printf("%+v", windows)
|
|
if idx > cap(windows)-1 {
|
|
Warning.Printf("idx %d is greater than length of windows %d", idx, cap(windows))
|
|
return
|
|
}
|
|
hwnd := windows[idx]
|
|
if hwnd == 0 {
|
|
Warning.Printf("hwnd for idx %d is 0", idx)
|
|
return
|
|
}
|
|
SetForegroundWindow.Call(hwnd)
|
|
}
|
|
func Swap(idx int) {
|
|
log.Printf("Swap: %d", idx)
|
|
if idx > cap(windows)-1 {
|
|
Warning.Printf("idx %d is greater than length of windows %d", idx, cap(windows))
|
|
return
|
|
}
|
|
hwnd, _, _ := GetForegroundWindow.Call()
|
|
if !IsTracked(hwnd) {
|
|
TrackWindow(hwnd)
|
|
}
|
|
log.Printf("Swapping %d to %d", hwnd, idx)
|
|
for i := 0; i < cap(windows); i++ {
|
|
if windows[i] == hwnd {
|
|
windows[i] = windows[idx]
|
|
windows[idx] = hwnd
|
|
log.Printf("Swapped %d to %d at index %d", hwnd, idx, i)
|
|
break
|
|
}
|
|
}
|
|
log.Printf("windows swapped: %+v", windows)
|
|
}
|
|
|
|
func TrackWindow(hwnd uintptr) {
|
|
if IsTracked(hwnd) {
|
|
log.Printf("Untracking window: %d", hwnd)
|
|
windows = slices.DeleteFunc(windows, func(i uintptr) bool {
|
|
return i == hwnd
|
|
})
|
|
} else {
|
|
log.Printf("Tracking window: %d", hwnd)
|
|
for i := 0; i < cap(windows); i++ {
|
|
if windows[i] == 0 {
|
|
windows[i] = hwnd
|
|
log.Printf("Tracked window: %d at index %d", hwnd, i)
|
|
return
|
|
}
|
|
}
|
|
}
|
|
}
|
|
func IsTracked(hwnd uintptr) bool {
|
|
return slices.Contains(windows, hwnd)
|
|
}
|
|
|
|
func onReady() {
|
|
// Icons no workey... idk why...
|
|
// systray error: unable to set icon: The operation completed successfully.
|
|
//systray.SetIcon(icon)
|
|
systray.SetTitle("Awesome App")
|
|
systray.SetTooltip("Pretty awesome超级棒")
|
|
mQuit := systray.AddMenuItem("Quit", "Quit the whole app")
|
|
go func() {
|
|
<-mQuit.ClickedCh
|
|
fmt.Println("Requesting quit")
|
|
systray.Quit()
|
|
os.Exit(0)
|
|
// TODO: Quit properly, not this exit bullshit
|
|
fmt.Println("Finished quitting")
|
|
}()
|
|
|
|
// Sets the icon of a menu item. Only available on Mac and Windows.
|
|
//mQuit.SetIcon(icon)
|
|
}
|