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