dwn examples.
Some checks are pending
WrenCI / linux (push) Waiting to run
WrenCI / mac (push) Waiting to run
WrenCI / windows (push) Waiting to run

This commit is contained in:
retoor 2026-01-24 21:15:13 +01:00
parent 236d69c2d7
commit 1a0f7f51a1
3 changed files with 918 additions and 0 deletions

124
example/dwn_browser_demo.wren vendored Normal file
View File

@ -0,0 +1,124 @@
// retoor <retoor@molodetz.nl>
import "websocket" for WebSocket
import "json" for Json
import "timer" for Timer
System.print("Browser Automation OCR Demo")
System.print("=" * 50)
var host = "ws://127.0.0.1:8777/ws"
System.print("")
System.print("Connecting to DWN API at %(host)...")
var ws = WebSocket.connect(host)
System.print("Connected")
var sendCommand = Fn.new { |command|
ws.send(Json.stringify(command))
var msg = ws.receive()
if (msg == null || !msg.isText) return null
return Json.parse(msg.text)
}
System.print("")
System.print("1. Opening default browser with google.nl...")
sendCommand.call({"command": "run_command", "exec": "xdg-open https://www.google.nl"})
System.print("2. Waiting for browser to open...")
Timer.sleep(5000)
var result = sendCommand.call({"command": "get_focused_client"})
var client = result["client"]
if (client == null) {
System.print(" Error: No focused window found")
ws.close()
Fiber.abort("No focused window")
}
var windowId = client["window"]
var toHex = Fn.new { |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
}
System.print(" Browser window found: 0x%(toHex.call(windowId))")
System.print("3. Waiting for page to load...")
Timer.sleep(2000)
System.print("4. Searching for 'ponies'...")
sendCommand.call({"command": "key_type", "text": "ponies"})
Timer.sleep(300)
sendCommand.call({"command": "key_tap", "keysym": "Return"})
System.print("5. Waiting for search results...")
Timer.sleep(4000)
var scrollCount = 4
var allText = []
for (i in 0...scrollCount) {
System.print("")
System.print("6.%(i + 1). Taking screenshot (page %(i + 1)/%(scrollCount))...")
var screenshotResult = sendCommand.call({"command": "screenshot", "mode": "active"})
if (screenshotResult["status"] != "ok") {
System.print(" Screenshot error: %(screenshotResult["message"])")
continue
}
var width = screenshotResult["width"]
var height = screenshotResult["height"]
System.print(" Screenshot captured: %(width)x%(height)")
var imageData = screenshotResult["data"]
System.print(" Running OCR...")
var ocrResult = sendCommand.call({"command": "ocr", "image": imageData})
if (ocrResult["status"] != "ok") {
System.print(" OCR error: %(ocrResult["message"])")
continue
}
var confidence = (ocrResult["confidence"] * 100).floor
var text = ocrResult["text"]
System.print(" OCR Confidence: %(confidence) percent")
if (text != null && text.count > 0) {
allText.add("--- Page %(i + 1) ---\n%(text)")
}
if (i < scrollCount - 1) {
System.print(" Scrolling down...")
sendCommand.call({"command": "mouse_scroll", "direction": "down", "amount": 5})
Timer.sleep(1500)
}
}
System.print("")
System.print("=" * 50)
System.print("COMBINED EXTRACTED TEXT:")
System.print("=" * 50)
if (allText.count > 0) {
for (text in allText) {
System.print("")
System.print(text)
}
} else {
System.print("(No text detected)")
}
System.print("")
System.print("=" * 50)
System.print("Demo complete - extracted text from %(allText.count) pages")
ws.close()

318
example/dwn_client.wren vendored Normal file
View File

@ -0,0 +1,318 @@
// retoor <retoor@molodetz.nl>
import "websocket" for WebSocket
import "json" for Json
class DWNClient {
construct new(host, port) {
_host = host
_port = port
_ws = null
}
construct new() {
_host = "localhost"
_port = 8777
_ws = null
}
connect() {
var url = "ws://%(_host):%(_port)/ws"
_ws = WebSocket.connect(url)
}
disconnect() {
if (_ws != null) {
_ws.close()
_ws = null
}
}
isConnected { _ws != null && _ws.isOpen }
sendCommand(command) {
if (_ws == null) Fiber.abort("Not connected")
_ws.send(Json.stringify(command))
var msg = _ws.receive()
if (msg == null || !msg.isText) return null
return Json.parse(msg.text)
}
getStatus() {
return sendCommand({"command": "get_status"})
}
getWorkspaces() {
return sendCommand({"command": "get_workspaces"})
}
getClients() {
return sendCommand({"command": "get_clients"})
}
findClients(title, wmClass, workspace) {
var cmd = {"command": "find_clients"}
if (title != null) cmd["title"] = title
if (wmClass != null) cmd["class"] = wmClass
if (workspace != null) cmd["workspace"] = workspace
return sendCommand(cmd)
}
getFocusedClient() {
return sendCommand({"command": "get_focused_client"})
}
switchWorkspace(workspace) {
return sendCommand({"command": "switch_workspace", "workspace": workspace})
}
runCommand(exec) {
return sendCommand({"command": "run_command", "exec": exec})
}
focusClient(windowId) {
return sendCommand({"command": "focus_client", "window": windowId})
}
keyPress(keysym) {
var cmd = {"command": "key_press"}
if (keysym != null) cmd["keysym"] = keysym
return sendCommand(cmd)
}
keyRelease(keysym) {
var cmd = {"command": "key_release"}
if (keysym != null) cmd["keysym"] = keysym
return sendCommand(cmd)
}
keyTap(keysym) { keyTap(keysym, null) }
keyTap(keysym, modifiers) {
var cmd = {"command": "key_tap"}
if (keysym != null) cmd["keysym"] = keysym
if (modifiers != null) cmd["modifiers"] = modifiers
return sendCommand(cmd)
}
keyType(text) {
return sendCommand({"command": "key_type", "text": text})
}
mouseMove(x, y) {
return sendCommand({"command": "mouse_move", "x": x, "y": y})
}
mouseMoveRelative(dx, dy) {
return sendCommand({"command": "mouse_move_relative", "dx": dx, "dy": dy})
}
mouseClick(button) { mouseClick(button, null, null) }
mouseClick(button, x, y) {
var cmd = {"command": "mouse_click", "button": button}
if (x != null && y != null) {
cmd["x"] = x
cmd["y"] = y
}
return sendCommand(cmd)
}
mousePress(button) {
return sendCommand({"command": "mouse_press", "button": button})
}
mouseRelease(button) {
return sendCommand({"command": "mouse_release", "button": button})
}
mouseScroll(direction, amount) {
return sendCommand({"command": "mouse_scroll", "direction": direction, "amount": amount})
}
getMousePosition() {
return sendCommand({"command": "get_mouse_position"})
}
closeClient(windowId) {
return sendCommand({"command": "close_client", "window": windowId})
}
killClient(windowId) {
return sendCommand({"command": "kill_client", "window": windowId})
}
minimizeClient(windowId) {
return sendCommand({"command": "minimize_client", "window": windowId})
}
restoreClient(windowId) {
return sendCommand({"command": "restore_client", "window": windowId})
}
maximizeClient(windowId) { maximizeClient(windowId, null) }
maximizeClient(windowId, state) {
var cmd = {"command": "maximize_client", "window": windowId}
if (state != null) cmd["state"] = state
return sendCommand(cmd)
}
fullscreenClient(windowId) { fullscreenClient(windowId, null) }
fullscreenClient(windowId, state) {
var cmd = {"command": "fullscreen_client", "window": windowId}
if (state != null) cmd["state"] = state
return sendCommand(cmd)
}
floatClient(windowId) { floatClient(windowId, null) }
floatClient(windowId, state) {
var cmd = {"command": "float_client", "window": windowId}
if (state != null) cmd["state"] = state
return sendCommand(cmd)
}
moveClient(windowId, x, y) {
return sendCommand({"command": "move_client", "window": windowId, "x": x, "y": y})
}
resizeClient(windowId, width, height) {
return sendCommand({"command": "resize_client", "window": windowId, "width": width, "height": height})
}
moveClientToWorkspace(windowId, workspace) {
return sendCommand({"command": "move_client_to_workspace", "window": windowId, "workspace": workspace})
}
raiseClient(windowId) {
return sendCommand({"command": "raise_client", "window": windowId})
}
lowerClient(windowId) {
return sendCommand({"command": "lower_client", "window": windowId})
}
setLayout(layout) { setLayout(layout, null) }
setLayout(layout, workspace) {
var cmd = {"command": "set_layout", "layout": layout}
if (workspace != null) cmd["workspace"] = workspace
return sendCommand(cmd)
}
cycleLayout() { cycleLayout(null) }
cycleLayout(workspace) {
var cmd = {"command": "cycle_layout"}
if (workspace != null) cmd["workspace"] = workspace
return sendCommand(cmd)
}
getScreenInfo() {
return sendCommand({"command": "get_screen_info"})
}
showDesktop() { showDesktop(null) }
showDesktop(state) {
var cmd = {"command": "show_desktop"}
if (state != null) cmd["state"] = state
return sendCommand(cmd)
}
screenshot(mode) { screenshot(mode, null, null, null, null, null) }
screenshot(mode, window, x, y, width, height) {
var cmd = {"command": "screenshot", "mode": mode}
if (mode == "window" && window != null) {
cmd["window"] = window
} else if (mode == "area") {
if (x != null) cmd["x"] = x
if (y != null) cmd["y"] = y
if (width != null) cmd["width"] = width
if (height != null) cmd["height"] = height
}
return sendCommand(cmd)
}
ocr(imageBase64) { ocr(imageBase64, "eng") }
ocr(imageBase64, language) {
return sendCommand({"command": "ocr", "image": imageBase64, "language": language})
}
listEvents() {
return sendCommand({"command": "list_events"})
}
subscribe(events) {
var cmd = {"command": "subscribe"}
if (events != null) {
cmd["events"] = events
} else {
cmd["all"] = true
}
return sendCommand(cmd)
}
unsubscribe(events) {
var cmd = {"command": "unsubscribe"}
if (events != null) {
cmd["events"] = events
} else {
cmd["all"] = true
}
return sendCommand(cmd)
}
static formatLayout(layoutId) {
if (layoutId == 0) return "tiling"
if (layoutId == 1) return "floating"
if (layoutId == 2) return "monocle"
return "unknown"
}
static 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
}
}
if (Fiber.current.isDone != true) {
System.print("=== DWN Client Module ===")
System.print("")
System.print("This module provides DWNClient class for DWN window manager API.")
System.print("")
System.print("Usage:")
System.print(" import \"dwn_client\" for DWNClient")
System.print(" var client = DWNClient.new()")
System.print(" client.connect()")
System.print(" var status = client.getStatus()")
System.print(" client.disconnect()")
System.print("")
System.print("Quick test - connecting to DWN API...")
var client = DWNClient.new()
client.connect()
System.print("Connected")
var status = client.getStatus()
System.print("")
System.print("Status:")
System.print(" Version: %(status["version"])")
System.print(" Workspace: %(status["current_workspace"] + 1)")
System.print(" Clients: %(status["client_count"])")
System.print(" Status: %(status["status"])")
client.disconnect()
System.print("")
System.print("Disconnected")
}

476
example/dwn_demo.wren vendored Normal file
View File

@ -0,0 +1,476 @@
// 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")