// retoor <retoor@molodetz.nl>
import "websocket" for WebSocket
import "json" for Json
import "timer" for Timer
class DWNDemo {
construct new(host, port) {
_host = host
_port = port
_ws = null
}
connect() {
var url = "ws://%(_host):%(_port)/ws"
_ws = WebSocket.connect(url)
}
disconnect() {
if (_ws != null) {
_ws.close()
_ws = null
}
}
sendCommand(command) {
_ws.send(Json.stringify(command))
var msg = _ws.receive()
if (msg == null || !msg.isText) return null
return Json.parse(msg.text)
}
toHex(num) {
var digits = "0123456789abcdef"
var result = ""
var n = num
while (n > 0) {
result = digits[n % 16] + result
n = (n / 16).floor
}
return result.count == 0 ? "0" : result
}
formatLayout(layoutId) {
if (layoutId == 0) return "tiling"
if (layoutId == 1) return "floating"
if (layoutId == 2) return "monocle"
return "unknown"
}
showDashboard() {
var status = sendCommand({"command": "get_status"})
var workspacesResult = sendCommand({"command": "get_workspaces"})
var clientsResult = sendCommand({"command": "get_clients"})
var workspaces = workspacesResult["workspaces"]
var clients = clientsResult["clients"]
var currentWs = status["current_workspace"]
System.print("=" * 60)
System.print("DWN DASHBOARD")
System.print("=" * 60)
System.print("Version: %(status["version"])")
System.print("Status: %(status["status"])")
System.print("Clients: %(status["client_count"])")
System.print("-" * 60)
System.print("")
System.print("Workspaces:")
for (ws in workspaces) {
var wsId = ws["id"]
var name = ws["name"]
if (name == null) name = (wsId + 1).toString
var count = ws["client_count"]
var layout = formatLayout(ws["layout"])
var marker = wsId == currentWs ? " *" : " "
System.print(" %(marker)[%(wsId + 1)] %(name) %(layout) %(count) windows")
}
System.print("")
System.print("Windows:")
if (clients == null || clients.count == 0) {
System.print(" No managed windows")
} else {
for (c in clients) {
var title = c["title"]
if (title == null) title = "Untitled"
if (title.count > 45) title = title[0...45]
var ws = c["workspace"] + 1
var focused = c["focused"] ? "[FOCUSED] " : ""
System.print(" %(focused)%(title) WS:%(ws)")
}
}
}
demoKeyboard() {
System.print("Keyboard Automation Demo")
System.print("-" * 40)
System.print("1. Typing text...")
sendCommand({"command": "key_type", "text": "Hello from DWN automation!"})
Timer.sleep(1000)
System.print("2. Pressing Enter...")
sendCommand({"command": "key_tap", "keysym": "Return"})
Timer.sleep(500)
System.print("3. Key combination (Ctrl+A)...")
sendCommand({"command": "key_tap", "keysym": "a", "modifiers": ["Control_L"]})
Timer.sleep(500)
System.print("Keyboard demo complete")
}
demoMouse() {
var screen = sendCommand({"command": "get_screen_info"})
var width = screen["screen_width"]
var height = screen["screen_height"]
var centerX = (width / 2).floor
var centerY = (height / 2).floor
System.print("Mouse Automation Demo")
System.print("-" * 40)
System.print("1. Moving to center (%(centerX), %(centerY))...")
sendCommand({"command": "mouse_move", "x": centerX, "y": centerY})
Timer.sleep(500)
System.print("2. Moving in a square pattern...")
var positions = [
[centerX - 100, centerY - 100],
[centerX + 100, centerY - 100],
[centerX + 100, centerY + 100],
[centerX - 100, centerY + 100],
[centerX, centerY]
]
for (pos in positions) {
sendCommand({"command": "mouse_move", "x": pos[0], "y": pos[1]})
Timer.sleep(200)
}
System.print("3. Scrolling up...")
sendCommand({"command": "mouse_scroll", "direction": "up", "amount": 3})
Timer.sleep(500)
System.print("4. Scrolling down...")
sendCommand({"command": "mouse_scroll", "direction": "down", "amount": 3})
Timer.sleep(500)
var pos = sendCommand({"command": "get_mouse_position"})
System.print("Current position: (%(pos["x"]), %(pos["y"]))")
System.print("Mouse demo complete")
}
demoWindowOps() {
var focused = sendCommand({"command": "get_focused_client"})
var client = focused["client"]
if (client == null) {
System.print("No focused window for demo")
return
}
var wid = client["window"]
System.print("Window Operations Demo (0x%(toHex(wid)))")
System.print("-" * 40)
System.print("1. Setting floating...")
sendCommand({"command": "float_client", "window": wid, "state": true})
Timer.sleep(1000)
System.print("2. Moving to (100, 100)...")
sendCommand({"command": "move_client", "window": wid, "x": 100, "y": 100})
Timer.sleep(500)
System.print("3. Resizing to 800x600...")
sendCommand({"command": "resize_client", "window": wid, "width": 800, "height": 600})
Timer.sleep(500)
System.print("4. Maximizing...")
sendCommand({"command": "maximize_client", "window": wid, "state": true})
Timer.sleep(1000)
System.print("5. Restoring...")
sendCommand({"command": "maximize_client", "window": wid, "state": false})
Timer.sleep(500)
System.print("6. Returning to tiling...")
sendCommand({"command": "float_client", "window": wid, "state": false})
Timer.sleep(500)
System.print("Window operations demo complete")
}
demoLayouts() {
System.print("Layout Cycling Demo")
System.print("-" * 40)
var layouts = ["tiling", "floating", "monocle"]
for (layout in layouts) {
System.print("Setting layout: %(layout)")
sendCommand({"command": "set_layout", "layout": layout})
Timer.sleep(1500)
}
System.print("Returning to tiling...")
sendCommand({"command": "set_layout", "layout": "tiling"})
System.print("Layout demo complete")
}
demoWorkspaces() {
System.print("Workspace Navigation Demo")
System.print("-" * 40)
var status = sendCommand({"command": "get_status"})
var originalWs = status["current_workspace"]
for (ws in 0...3) {
System.print("Switching to workspace %(ws + 1)...")
sendCommand({"command": "switch_workspace", "workspace": ws})
Timer.sleep(500)
}
System.print("Returning to workspace %(originalWs + 1)...")
sendCommand({"command": "switch_workspace", "workspace": originalWs})
System.print("Workspace demo complete")
}
demoScreenshot() {
System.print("Screenshot Demo")
System.print("-" * 40)
System.print("1. Capturing fullscreen...")
var result = sendCommand({"command": "screenshot", "mode": "fullscreen"})
if (result["status"] == "ok") {
System.print(" Captured %(result["width"])x%(result["height"])")
} else {
System.print(" Error: %(result["message"])")
}
Timer.sleep(500)
System.print("2. Capturing active window...")
result = sendCommand({"command": "screenshot", "mode": "active"})
if (result["status"] == "ok") {
System.print(" Captured %(result["width"])x%(result["height"])")
} else {
System.print(" Error: %(result["message"])")
}
Timer.sleep(500)
System.print("3. Capturing area (200x200 at 100,100)...")
result = sendCommand({"command": "screenshot", "mode": "area", "x": 100, "y": 100, "width": 200, "height": 200})
if (result["status"] == "ok") {
System.print(" Captured %(result["width"])x%(result["height"])")
} else {
System.print(" Error: %(result["message"])")
}
System.print("Screenshot demo complete")
}
demoOcr() {
System.print("OCR Demo")
System.print("-" * 40)
System.print("1. Capturing active window...")
var result = sendCommand({"command": "screenshot", "mode": "active"})
if (result["status"] != "ok") {
System.print(" Screenshot error: %(result["message"])")
return
}
System.print(" Captured %(result["width"])x%(result["height"])")
var imageData = result["data"]
System.print("2. Extracting text with OCR...")
var ocrResult = sendCommand({"command": "ocr", "image": imageData})
if (ocrResult["status"] == "ok") {
var confidence = (ocrResult["confidence"] * 100).floor
var text = ocrResult["text"]
System.print(" Confidence: %(confidence) percent")
if (text != null && text.count > 0) {
var lines = splitLines(text)
var count = lines.count < 5 ? lines.count : 5
System.print(" Preview (first %(count) lines):")
for (i in 0...count) {
var line = lines[i]
if (line.count > 60) line = line[0...60]
System.print(" %(line)")
}
if (lines.count > 5) {
System.print(" ...")
}
} else {
System.print(" (No text detected)")
}
} else {
System.print(" OCR error: %(ocrResult["message"])")
}
System.print("OCR demo complete")
}
splitLines(text) {
var lines = []
var start = 0
var i = 0
while (i < text.count) {
if (text[i] == "\n") {
lines.add(text[start...i])
start = i + 1
}
i = i + 1
}
if (start < text.count) {
lines.add(text[start..-1])
}
return lines
}
demoEvents() {
System.print("Event Subscription Demo")
System.print("-" * 40)
System.print("1. Listing available events...")
var result = sendCommand({"command": "list_events"})
if (result["status"] == "ok") {
var events = result["events"]
System.print(" Available events (%(events.count)):")
var count = events.count < 10 ? events.count : 10
for (i in 0...count) {
System.print(" - %(events[i])")
}
if (events.count > 10) {
System.print(" ... and %(events.count - 10) more")
}
} else {
System.print(" Error: %(result["message"])")
return
}
System.print("")
System.print("2. Subscribing to window and workspace events...")
var subscribeEvents = [
"window_created",
"window_destroyed",
"window_focused",
"window_unfocused",
"workspace_switched"
]
result = sendCommand({"command": "subscribe", "events": subscribeEvents})
if (result["status"] == "ok") {
var subscribed = result["subscribed"]
System.print(" Subscribed to %(subscribed.count) events")
} else {
System.print(" Error: %(result["message"])")
return
}
System.print("")
System.print("3. Unsubscribing from all events...")
result = sendCommand({"command": "unsubscribe", "all": true})
if (result["status"] == "ok") {
System.print(" Unsubscribed from all events")
}
System.print("Event demo complete")
}
runFullDemo() {
System.print("=" * 60)
System.print("DWN FULL AUTOMATION DEMO")
System.print("=" * 60)
System.print("")
showDashboard()
System.print("")
Timer.sleep(2000)
demoWorkspaces()
System.print("")
Timer.sleep(1000)
demoLayouts()
System.print("")
Timer.sleep(1000)
demoMouse()
System.print("")
Timer.sleep(1000)
demoWindowOps()
System.print("")
Timer.sleep(1000)
demoScreenshot()
System.print("")
Timer.sleep(1000)
demoOcr()
System.print("")
Timer.sleep(1000)
demoEvents()
System.print("")
System.print("=" * 60)
System.print("DEMO COMPLETE")
System.print("=" * 60)
}
autoTidy() {
var clientsResult = sendCommand({"command": "get_clients"})
var clients = clientsResult["clients"]
if (clients == null || clients.count == 0) {
System.print("No windows to organize")
return
}
var classGroups = {}
for (c in clients) {
var wmClass = c["class"]
if (wmClass == null) wmClass = "unknown"
if (!classGroups.containsKey(wmClass)) {
classGroups[wmClass] = []
}
classGroups[wmClass].add(c)
}
System.print("Organizing windows by class...")
var wsIndex = 0
for (wmClass in classGroups.keys) {
if (wsIndex >= 9) break
var windows = classGroups[wmClass]
System.print(" Moving %(windows.count) %(wmClass) window(s) to workspace %(wsIndex + 1)")
for (c in windows) {
var wid = c["window"]
sendCommand({"command": "move_client_to_workspace", "window": wid, "workspace": wsIndex})
Timer.sleep(100)
}
wsIndex = wsIndex + 1
}
System.print("Windows organized")
}
}
System.print("=== DWN Automation Demo ===")
System.print("")
System.print("Connecting to DWN API...")
var demo = DWNDemo.new("localhost", 8777)
demo.connect()
System.print("Connected")
System.print("")
System.print("Available demos:")
System.print(" 1. Dashboard - Show current state")
System.print(" 2. Keyboard - Keyboard automation")
System.print(" 3. Mouse - Mouse automation")
System.print(" 4. Windows - Window operations")
System.print(" 5. Layouts - Layout cycling")
System.print(" 6. Workspaces - Workspace navigation")
System.print(" 7. Screenshot - Screenshot capture")
System.print(" 8. OCR - Text extraction")
System.print(" 9. Events - Event subscription")
System.print(" 0. Full Demo - Run all demos")
System.print(" T. Auto Tidy - Organize windows by class")
System.print("")
demo.runFullDemo()
demo.disconnect()
System.print("")
System.print("Disconnected")