working window sorting + some intresting stuff

This commit is contained in:
MeexReay 2025-05-24 20:07:07 +03:00
parent 8448d5d20a
commit 7c76fa25ed
5 changed files with 229 additions and 81 deletions

View File

@ -6,13 +6,27 @@ async function drawScreen(ctx) {
ctx.fillStyle = "darkcyan" ctx.fillStyle = "darkcyan"
ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height) ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height)
ctx.fillStyle = "cyan";
ctx.font = "bold 14px comic-sans";
ctx.textBaseline = "middle";
ctx.textAlign = "left";
ctx.fillText(`Alt+Shift+Q - выключить оконный менеджер | Alt+Enter - включить zterm | Alt+Shift+C - закрыть окно`, 10, 16);
for (const win of window.mxwm_windows) { for (const win of window.mxwm_windows) {
drawWindowDecorations(ctx, win.x, win.y, win.width, win.height, win.title) drawWindowDecorations(
ctx,
win.wid == selected_window,
win.x,
win.y,
win.width,
win.height,
win.title
)
ctx.drawImage(win.canvas, win.x, win.y); ctx.drawImage(win.canvas, win.x, win.y);
} }
} }
async function drawWindowDecorations(ctx, x, y, width, height, title) { async function drawWindowDecorations(ctx, is_selected, x, y, width, height, title) {
const borderRadius = 8; const borderRadius = 8;
const borderWidth = 1; const borderWidth = 1;
const buttonRadius = 6; const buttonRadius = 6;
@ -23,7 +37,7 @@ async function drawWindowDecorations(ctx, x, y, width, height, title) {
const outerWidth = width + borderWidth * 2 + 2; const outerWidth = width + borderWidth * 2 + 2;
const outerHeight = height + headerHeight + borderWidth * 2 + 3; const outerHeight = height + headerHeight + borderWidth * 2 + 3;
ctx.fillStyle = "#f4f4f4"; ctx.fillStyle = is_selected ? "#f4f4f4" : "#d3f4d3";
ctx.fillRect(outerX, outerY, outerWidth, outerHeight) ctx.fillRect(outerX, outerY, outerWidth, outerHeight)
ctx.fillStyle = "#222"; ctx.fillStyle = "#222";
@ -34,17 +48,56 @@ async function drawWindowDecorations(ctx, x, y, width, height, title) {
} }
async function onStart(screen_ctx) { async function onStart(screen_ctx) {
executeCommand(["/app/zterm.js"])
} }
async function onKeyDown(ctx, key) { function moveWindowToTop(wid) {
if (key == "Escape") { let my_win
disableGraphics() let windows = []
for (let win of window.mxwm_windows) {
if (win.wid == wid) {
my_win = win
continue
} }
windows.push(win)
}
windows.push(my_win)
window.mxwm_windows = windows
}
let altKey = false
let shiftKey = false
let ctrlKey = false
async function onKeyDown(ctx, key) {
if (key == "Control") ctrlKey = true
if (key == "Alt") altKey = true
if (key == "Shift") shiftKey = true
if (altKey && shiftKey && key == "Q") {
disableGraphics()
return
}
if (altKey && shiftKey && key == "C") {
signalWindow(selected_window, 9)
closeWindow(selected_window)
return
}
if (altKey && key == "Enter") {
executeCommand(["/app/zterm.js"])
return
}
if (selected_window != null) getWindow(selected_window).onkeydown(key) if (selected_window != null) getWindow(selected_window).onkeydown(key)
} }
async function onKeyUp(ctx, key) { async function onKeyUp(ctx, key) {
if (key == "Control") ctrlKey = false
if (key == "Alt") altKey = false
if (key == "Shift") shiftKey = false
if (selected_window != null) getWindow(selected_window).onkeyup(key) if (selected_window != null) getWindow(selected_window).onkeyup(key)
} }
@ -69,9 +122,11 @@ async function onMouseDown(ctx, button) {
dragging_window = window["wid"] dragging_window = window["wid"]
selected_window = window["wid"] selected_window = window["wid"]
setGraphicsCursor("grabbing") setGraphicsCursor("grabbing")
moveWindowToTop(window.wid)
} }
if (isMouseInside(window)) { if (isMouseInside(window)) {
selected_window = window["wid"] selected_window = window["wid"]
moveWindowToTop(window.wid)
window.onmousedown(button) window.onmousedown(button)
} }
} }

View File

@ -4,6 +4,8 @@ function hasGraphicsImplementation() {
/** returns wid and context */ /** returns wid and context */
function createWindow(options) { function createWindow(options) {
console.log("create", options)
let canvas = document.createElement("canvas") let canvas = document.createElement("canvas")
let wid = Date.now().toString() + Math.round(Math.random() * 100).toString() let wid = Date.now().toString() + Math.round(Math.random() * 100).toString()
@ -37,7 +39,7 @@ function createWindow(options) {
window.mxwm_windows = [ win ] window.mxwm_windows = [ win ]
} }
return (wid, context) return [wid, context]
} }
function moveWindow(wid, x, y, w, h) { function moveWindow(wid, x, y, w, h) {
@ -68,6 +70,8 @@ function signalWindow(wid, signal) {
} }
function closeWindow(wid) { function closeWindow(wid) {
console.log("remove", wid)
if (!("mxwm_windows" in window)) { if (!("mxwm_windows" in window)) {
window.mxwm_windows = [ ] window.mxwm_windows = [ ]
} }

View File

@ -4,8 +4,10 @@ let text = ""
let stdin_text = "" let stdin_text = ""
let stdin_visible = true let stdin_visible = true
let stdin_disable = true let stdin_disable = true
let ctx = null
let wid = null
async function draw(ctx) { async function draw() {
ctx.fillStyle = "black" ctx.fillStyle = "black"
ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height) ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height)
@ -19,6 +21,7 @@ async function draw(ctx) {
y -= 18 y -= 18
} }
} }
function setStdinFlag(flag) { function setStdinFlag(flag) {
if (flag == SILENT_STDIN) { if (flag == SILENT_STDIN) {
stdin_visible = false stdin_visible = false
@ -42,6 +45,101 @@ async function readStdin() {
async function writeStdout(wh) { async function writeStdout(wh) {
text += wh text += wh
draw()
}
async function readLine(on_key=(key, ctrl, alt, shift, content, pos) => [content, pos]) {
setStdinFlag(ENABLE_STDIN)
let start_terminal = text
// let start_cursor_pos = getCursor()
let pos = 0
let content = ""
while (true) {
let event = await pollStdinEvent()
if (event.type == "key") {
if (event.key == "Backspace") {
if (pos >= 1) {
content = content.slice(0, pos - 1) + content.slice(pos)
pos -= 1
text = start_terminal + content
// let cursor = getCursor()
// setCursor(cursor[0]-1, cursor[1])
// updateTerminalWOCursor()
}
} else if (event.key == "Delete") {
content = content.slice(0, pos) + content.slice(pos + 1)
text = start_terminal + content
// updateTerminalWOCursor()
// } else if (event.key == "ArrowLeft") {
// let cursor = getCursor()
// if (cursor[0] > start_cursor_pos[0]) {
// setCursor(cursor[0]-1, cursor[1])
// pos -= 1
// }
// } else if (event.key == "ArrowRight") {
// let cursor = getCursor()
// if (cursor[0] < start_cursor_pos[0] + content.length) {
// setCursor(cursor[0]+1, cursor[1])
// pos += 1
// }
} else {
let res = on_key(event.key, event.ctrl, event.alt, event.shift, content, pos)
text = text.slice(0, text.length - content.length) + res[0]
// updateTerminal()
// setCursor(start_cursor_pos[0] + res[1], start_cursor_pos[1])
content = res[0]
pos = res[1]
}
} else if (event.type == "char") {
if (event.char == "\n") break
if (event.char == "\0") continue
content = content.slice(0, pos) + event.char + content.slice(pos)
pos += 1
}
draw()
}
setStdinFlag(DISABLE_STDIN)
return content
}
async function pollStdinEvent() {
let char = await readStdin()
if (char == "\r") {
let key = ""
char = await readStdin()
while (char != "\r") {
key += char
char = await readStdin()
}
let is_ctrl = key.charAt(0) == "1"
let is_alt = key.charAt(1) == "1"
let is_shift = key.charAt(2) == "1"
key = key.slice(3)
return {
"type": "key",
"ctrl": is_ctrl,
"alt": is_alt,
"shift": is_shift,
"key": key
}
}
return {
"type": "char",
"char": char
}
} }
let altKey = false let altKey = false
@ -49,7 +147,6 @@ let ctrlKey = false
let shiftKey = false let shiftKey = false
async function onKeyDown(key) { async function onKeyDown(key) {
console.log(key)
if (!stdin_disable) { if (!stdin_disable) {
if (key == "Enter") { if (key == "Enter") {
stdin_text += "\n" stdin_text += "\n"
@ -72,6 +169,7 @@ async function onKeyDown(key) {
stdin_text += "\r"+(ctrlKey ? "1" : "0")+(altKey ? "1" : "0")+(shiftKey ? "1" : "0")+key+"\r" stdin_text += "\r"+(ctrlKey ? "1" : "0")+(altKey ? "1" : "0")+(shiftKey ? "1" : "0")+key+"\r"
} }
} }
draw()
} }
async function onKeyUp(key) { async function onKeyUp(key) {
@ -85,7 +183,7 @@ async function onKeyUp(key) {
} }
async function main(args) { async function main(args) {
let wid, ctx = createWindow({ [wid, ctx] = createWindow({
"title": "zterm", "title": "zterm",
"width": 500, "width": 500,
"height": 500, "height": 500,
@ -95,12 +193,20 @@ async function main(args) {
"onkeyup": onKeyUp "onkeyup": onKeyUp
}) })
setTimeout(() => { draw()
executeCommand(["/app/posh.js"], readStdin, writeStdout, setStdinFlag)
})
while (graphics_canvas != null) { await executeCommand(
draw(ctx) ["/app/posh.js"],
await new Promise(res => setTimeout(res, 100)); readStdin,
} writeStdout,
setStdinFlag,
readLine,
pollStdinEvent
).promise
ctx = null
console.log("posh exit")
closeWindow(wid)
} }

View File

@ -13,7 +13,45 @@ const SILENT_STDIN = 2
const DISABLE_STDIN = 3 const DISABLE_STDIN = 3
const ENABLE_STDIN = 4 const ENABLE_STDIN = 4
const READ_FUNCTIONS_CODE = `async function readLine(on_key=(key, ctrl, alt, shift, content, pos) => [content, pos]) { const EXECUTE_COMMAND_CODE = `
function executeCommand(
args,
read=readStdin,
write=writeStdout,
set_flag=setStdinFlag,
read_line=readLine,
poll_stdin=pollStdinEvent,
inject=""
) {
let id = new Date().getMilliseconds().toString()+(Math.random()*100)
let func_content = readFile(args[0])
if (func_content == null || !func_content.includes("function main")) return
let func = new Function(
"args", "readStdin", "writeStdout", "setStdinFlag", "readLine", "pollStdinEvent",
EXECUTE_COMMAND_CODE+"\\n"+inject+"\\n"+func_content+"\\nreturn main(args)"
)
let process = {
"id": id,
"name": args.join(" "),
"promise": new Promise((resolve, reject) => {
setTimeout(() => {
try {
resolve(func(args, read, write, set_flag, read_line, poll_stdin))
} catch (e) {
reject(e)
}
}, 0)
}).then(o => {
processes = processes.filter(x => x.id != id)
return o
})
}
processes.push(process)
return process
}`
async function readLine(on_key=(key, ctrl, alt, shift, content, pos) => [content, pos]) {
setStdinFlag(ENABLE_STDIN) setStdinFlag(ENABLE_STDIN)
let start_terminal = getTerminal() let start_terminal = getTerminal()
@ -63,8 +101,8 @@ const READ_FUNCTIONS_CODE = `async function readLine(on_key=(key, ctrl, alt, shi
continue continue
} else if (event.type == "char") { } else if (event.type == "char") {
if (event.char == "\\n") break if (event.char == "\n") break
if (event.char == "\\0") continue if (event.char == "\0") continue
content = content.slice(0, pos) + event.char + content.slice(pos) content = content.slice(0, pos) + event.char + content.slice(pos)
pos += 1 pos += 1
@ -79,10 +117,10 @@ const READ_FUNCTIONS_CODE = `async function readLine(on_key=(key, ctrl, alt, shi
async function pollStdinEvent() { async function pollStdinEvent() {
let char = await readStdin() let char = await readStdin()
if (char == "\\r") { if (char == "\r") {
let key = "" let key = ""
char = await readStdin() char = await readStdin()
while (char != "\\r") { while (char != "\r") {
key += char key += char
char = await readStdin() char = await readStdin()
} }
@ -107,34 +145,6 @@ async function pollStdinEvent() {
} }
} }
function executeCommand(args, read=readStdin, write=writeStdout, set_flag=setStdinFlag, inject="") {
let id = new Date().getMilliseconds().toString()+(Math.random()*100)
let func_content = readFile(args[0])
if (func_content == null || !func_content.includes("function main")) return
let func = new Function(
"args", "readStdin", "writeStdout", "setStdinFlag",
READ_FUNCTIONS_CODE+"\\n\\n\\n"+func_content+"\\n"+inject+"\\nreturn main(args)"
)
let process = {
"id": id,
"name": args.join(" "),
"promise": new Promise((resolve, reject) => {
setTimeout(() => {
try {
resolve(func(args, read, write, set_flag))
} catch (e) {
reject(e)
}
}, 0)
}).then(o => {
processes = processes.filter(x => x.id != id)
return o
})
}
processes.push(process)
return process
}`
async function readStdin() { async function readStdin() {
while (stdin.length == 0) { while (stdin.length == 0) {
await new Promise(resolve => setTimeout(resolve, 10)) await new Promise(resolve => setTimeout(resolve, 10))
@ -161,34 +171,6 @@ function setStdinFlag(flag) {
} }
} }
function executeCommand(args, read=readStdin, write=writeStdout, set_flag=setStdinFlag, inject="") {
let id = new Date().getMilliseconds().toString()+(Math.random()*100)
let func_content = readFile(args[0])
if (func_content == null || !func_content.includes("function main")) return
let func = new Function(
"args", "readStdin", "writeStdout", "setStdinFlag",
READ_FUNCTIONS_CODE+"\n\n\n"+func_content+"\n"+inject+"\nreturn main(args)"
)
let process = {
"id": id,
"name": args.join(" "),
"promise": new Promise((resolve, reject) => {
setTimeout(() => {
try {
resolve(func(args, read, write, set_flag))
} catch (e) {
reject(e)
}
}, 0)
}).then(o => {
processes = processes.filter(x => x.id != id)
return o
})
}
processes.push(process)
return process
}
async function resetSystem() { async function resetSystem() {
clearFileSystem() clearFileSystem()
@ -204,6 +186,8 @@ async function resetSystem() {
} }
} }
eval(EXECUTE_COMMAND_CODE)
if (Object.keys(fs_mapping).length == 0) { if (Object.keys(fs_mapping).length == 0) {
resetSystem() resetSystem()
} }

View File

@ -157,7 +157,6 @@ var clipboard_collect = document.getElementById("clipboard-collect")
document.onkeydown = (e) => { document.onkeydown = (e) => {
let key = e.key; let key = e.key;
if (!disable_stdin) { if (!disable_stdin) {
console.log(e.key)
if (key == "Enter") { if (key == "Enter") {
stdin += "\n" stdin += "\n"
if (!silent_stdin) { if (!silent_stdin) {