user:geek:streamdeck

Stream Deck Ideas

#Include <Socket2>
 
Persistent
 
; From WebViewToo
ParseUri(Uri) {
    static Pattern := "^(?:(?<Scheme>\w+):)?(?://(?:(?<UserInfo>[^@]+)@)?(?<Host>[^:/?#]+)(?::(?<Port>\d+))?)?(?<Path>[^?#]*)?(?:\?(?<Query>[^#]*))?(?:#(?<Fragment>.*))?$"
    if (!RegExMatch(String(Uri), Pattern, &Match)) {
        return
    }
    Parsed := {}
    Parsed.Scheme := Match["Scheme"], Parsed.UserInfo := Match["UserInfo"], Parsed.Host := Match["Host"]
    Parsed.Port := Match["Port"], Parsed.Path := Match["Path"], Parsed.Query := Match["Query"]
    Parsed.Fragment := Match["Fragment"], Parsed.Authority := (Parsed.UserInfo != "" ? Parsed.UserInfo "@" : "") . Parsed.Host . (Parsed.Port != "" ? ":" Parsed.Port : "")
    return Parsed
}
 
; From https://www.autohotkey.com/boards/viewtopic.php?p=372262
UrlUnescape(url) {
    if r := DllCall("Shlwapi.dll\UrlUnescape", "Str", url, "Ptr", 0, "UInt", 0, "UInt", 0x100000, "UInt")
        throw OsError(r)
    return url
}
 
RecvLine(this, encoding:='UTF-8', keepEnd:=false) {
    newlinePos := 0
    ; MsgSize should block until some size is available. If there is
    ; an error, it returns early with zero.
    while size := this.MsgSize() {
        ; Peek at what's in the buffer and only break when a
        ; full line is available
        this._recv(buf := Buffer(size), size, Socket.MSG.PEEK)
        if newlinePos := InStr(StrGet(buf, 'cp0'), '`n')
            break
        Sleep 1
    }
    this._recv(buf := Buffer(newlinePos), newlinePos)
    data := StrGet(buf, encoding)
    return keepEnd ? data : RTrim(data, '`r`n')
}
 
class DeckServer extends Socket.Server {
    onACCEPT(err) {
        client := this.AcceptAsClient()
        request := StrSplit(RecvLine(client), ' ')
 
        if request[1] != 'GET' {
            client.SendText('HTTP/1.0 501 Not Implemented`r`n`r`n')
            Sleep 50
            return
        }
 
        uri := ParseUri(request[2])
        fname := LTrim(UrlUnescape(uri.Path), "/")
 
        if !(Buttons.HasOwnProp(fname)) {
            client.SendText('HTTP/1.0 404 Not Found`r`n`r`n')
            Sleep 50
            return
        }
 
        args := Map()
        for pair in StrSplit(uri.Query, '&') {
            pair := StrSplit(pair, "=",, 2)
            args[UrlUnescape(pair[1])] := UrlUnescape(pair[2])
        }
 
        SetTimer () => Buttons.%fname%(args), -1
        client.SendText('HTTP/1.0 200 OK`r`n`r`n')
        Sleep 50
        return
    }
}
 
server := DeckServer(1337, '127.0.0.1')
 
; --- User Functions ---
 
class Buttons {
    static Example(args)
    {
        MsgBox args['text']
    }
}

Window Management:

  • Full screen on left monitor
  • Full screen across both monitors (useful for VS Code)
  • Full screen on right monitor
  • Toggle AlwaysOnTop

Shape tools:

  • Set point 1
  • Set point 2
  • Trace line between points (useful for snipping tool highlights)
  • Trace rectangle with points as corners (useful for drawing boxes in snipping tool)
  • Trace circle?

Clipboard tools:

  • Send Clipboard (with special sequences)
  • Send Clipboard raw
  • Find and replace in clipboard
  • Convert formats in clipboard
    • Capitalization
    • Line endings
    • CSV/TSV
    • JSON pretty print / JSON as treeview
    • Base64 encode/decode
  • Load image from file into clipboard (useful for memes or reference images to be pasted into Teams)

Launcher:

  • Open Command Prompt, PowerShell, Git Bash (stream deck can do this on its own)
    • Open those programs using the *RunAsUser verb so you can run them with administrative privileges
  • Run maintenance tasks on a remote server using SSH, PsExec, or some other remote access tool.

Snippets! The stream deck can send blocks of text but with AHK you can paste them for better performance.

Open script in default editor

Reload script