|
// 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")
|