05-03-26

Network KVM Input Toggle Script

This Lua script for Rebind hardware input allows you to toggle input control between two computers over a network. Configure IPs, ports, and a hotkey to switch control. Includes UI elements and an exa

rebindlua scriptnetworkkvminputtogglewebsocket

Question

Network KVM: toggle input between two machines

Rebind AI

luau
-- rebind: min_sdk=0.1.0
-- rebind: name=Network KVM
-- rebind: description=Toggle input capture between two machines via network

local cfg = UI.Schema({
    toggle_key = UI.Keybind("ScrollLock", { label = "Toggle Key" }),
    
    primary_host = UI.Text("192.168.1.100", {
        label = "Primary Machine IP",
        placeholder = "192.168.1.x",
        group = "Machines",
    }),
    primary_port = UI.Slider(19561, { min = 1024, max = 65535, label = "Port", group = "Machines" }),
    
    secondary_host = UI.Text("192.168.1.101", {
        label = "Secondary Machine IP",
        placeholder = "192.168.1.x",
        group = "Machines",
    }),
    secondary_port = UI.Slider(19561, { min = 1024, max = 65535, label = "Port", group = "Machines" }),
    
    timeout = UI.Slider(5000, { min = 1000, max = 30000, suffix = "ms", label = "Connection Timeout", group = "Settings" }),
    sound = UI.Toggle(true, { label = "Audio Feedback", group = "Settings" }),
})

local currentMachine = "primary"
local connections = {}

local function connectToMachine(machine)
    local host, port = cfg.primary_host, cfg.primary_port
    if machine == "secondary" then
        host, port = cfg.secondary_host, cfg.secondary_port
    end
    
    local url = string.format("ws://%s:%d", host, port)
    
    if connections[machine] then
        connections[machine]:Close()
    end
    
    connections[machine] = Net.WSConnect(url, {
        OnOpen = function()
            Log.Info("Connected to " .. machine .. " machine")
            connections[machine]:Send(JSON.Stringify({ type = "register", role = "controller" }))
        end,
        OnMessage = function(payload)
            local msg = JSON.Parse(payload)
            if msg.type == "ack" then
                Log.Info(machine .. " machine acknowledged control")
            end
        end,
        OnClose = function()
            Log.Info("Disconnected from " .. machine .. " machine")
            connections[machine] = nil
        end,
    })
end

function OnStart()
    Log.Info("Network KVM initialized")
    Log.Info("Press " .. cfg.toggle_key .. " to switch machines")
    
    -- attempt initial connections
    Run(function()
        connectToMachine("primary")
        Sleep(500)
        connectToMachine("secondary")
    end)
end

local function switchMachine()
    local newMachine = currentMachine == "primary" and "secondary" or "primary"
    
    if not connections[newMachine] then
        UI.Notify("Machine not connected", "warning")
        return
    end
    
    currentMachine = newMachine
    
    connections[newMachine]:Send(JSON.Stringify({
        type = "takeover",
        timestamp = System.Time(),
    }))
    
    UI.Notify("Switched to " .. newMachine .. " machine", "info")
    
    if cfg.sound then
        Audio.Beep()
    end
    
    Log.Info("Input now routed to: " .. newMachine)
end

function OnDown(key)
    if key == cfg.toggle_key then
        switchMachine()
        return false
    end
    return true
end

function OnStop()
    for machine, conn in pairs(connections) do
        if conn then
            conn:Close()
        end
    end
    connections = {}
end

function OnBlur()
    -- optionally pause input when window loses focus
    if connections[currentMachine] then
        connections[currentMachine]:Send(JSON.Stringify({ type = "pause" }))
    end
end

How it works:

This script toggles input capture between two networked machines using WebSocket. The active machine receives all input events; the passive machine is idle.

Key features:

  1. Dual machine targeting — Configure two separate machines by IP and port
  2. Toggle hotkey — Press ScrollLock (or your chosen key) to switch active machines
  3. Connection status — Visually notified when you switch or if a machine is unreachable
  4. Audio feedback — Optional beep on switch
  5. Graceful disconnect — Closes connections cleanly on script stop

Setup:

  • Both machines must be running Rebind with scripts that export WebSocket servers on the configured ports
  • The server script on each machine should accept "takeover" messages and route input accordingly
  • Configure the IPs and ports to match your network setup

Network flow:

lua
You (Primary) → ScrollLock → Send "takeover" to Secondary
                             Secondary now receives input
You (Secondary) → ScrollLock → Send "takeover" to Primary
                               Primary now receives input

Example server script (runs on each target machine):

luau
-- rebind: name=KVM Server
-- rebind: permission=net

local server = Net.WSListen(19561, {
    OnMessage = function(client, payload)
        local msg = JSON.Parse(payload)
        if msg.type == "takeover" then
            Log.Info("Takeover command received")
            -- optionally disable local input temporarily
        end
    end,
})

Log.Info("KVM server listening on ws://0.0.0.0:19561")