2025-08-09 05:25:35 +02:00
|
|
|
var embeddedApps = {
|
|
|
|
|
calc: `data:text/html;charset=utf-8;base64,PCFET0NUWVBFIGh0bWw+PGh0bWwgbGFuZz0iZW4iPjxoZWFkPjxtZXRhIGNoYXJzZXQ9IlVURi04Ij48dGl0bGU+Q2FsY3VsYXRvcjwvdGl0bGU+PHN0eWxlPmJvZHl7bWFyZ2luOjA7Zm9udC1mYW1pbHk6bW9ub3NwYWNlLG1vbm9zcGFjZTtkaXNwbGF5OmZsZXg7anVzdGlmeS1jb250ZW50OmNlbnRlcjthbGlnbi1pdGVtczpjZW50ZXI7aGVpZ2h0OjEwMHZoO2JhY2tncm91bmQ6IzIyMjtjb2xvcjojZWVlfSNjYWxjdWxhdG9ye2JhY2tncm91bmQ6IzMzMztwYWRkaW5nOjFyZW07Ym9yZGVyLXJhZGl1czo4cHg7d2lkdGg6MjIwcHg7Ym94LXNoYWRvdzowIDAgMTBweCAjMDAwfSNkaXNwbGF5e3dpZHRoOjEwMCU7aGVpZ2h0OjQwcHg7Zm9udC1zaXplOjEuMnJlbTtiYWNrZ3JvdW5kOiMxMTE7Ym9yZGVyOm5vbmU7Y29sb3I6I2VlZTtwYWRkaW5nOjAgMDttYXJnaW4tYm90dG9tOjEwcHg7dGV4dC1hbGlnbjpyaWdodH1idXR0b257d2lkdGg6NDhweDtoZWlnaHQ6NDhweDttYXJnaW46MnB4O2ZvbnQtc2l6ZToxLjJyZW07Ym9yZGVyOm5vbmU7Ym9yZGVyLXJhZGl1czo0cHg7Y3Vyc29yOnBvaW50ZXI7YmFja2dyb3VuZDojNTU1O2NvbG9yOiNlZWU7dHJhbnNpdGlvbjpiYWNrZ3JvdW5kIC4ycyBlYXNlfWJ1dHRvbjpob3ZlcntiYWNrZ3JvdW5kOiM3Nzd9Lm9wZXJhdG9ye2JhY2tncm91bmQ6I2Y1N2MwMDtjb2xvcjojZmZmfS5vcGVyYXRvcjpob3ZlcntiYWNrZ3JvdW5kOiNmYjhjMDB9LmVxdWFsc3tiYWNrZ3JvdW5kOiMxOTc2ZDI7Y29sb3I6I2ZmZjt3aWR0aDoxMDAlO21hcmdpbi10b3A6NnB4fS5lcXVhbHM6aG92ZXJ7YmFja2dyb3VuZDojMjE5NmYzfTwvc3R5bGU+PC9oZWFkPjxib2R5PjxkaXYgaWQ9ImNhbGN1bGF0b3IiPjxpbnB1dCBpZD0iZGlzcGxheSIgdHlwZT0idGV4dCIgcmVhZG9ubHk9InJlYWRvbmx5Ij48ZGl2PjxidXR0b24gZGF0YS12YWw9IjciPjc8L2J1dHRvbj48YnV0dG9uIGRhdGEtdmFsPSI4Ij44PC9idXR0b24+PGJ1dHRvbiBkYXRhLXZhbD0iOSI+OTwvYnV0dG9uPjxidXR0b24gZGF0YS12YWw9Ii8iIGNsYXNzPSJvcGVyYXRvciI+w7c8L2J1dHRvbj48L2Rpdj48ZGl2PjxidXR0b24gZGF0YS12YWw9IjQiPjQ8L2J1dHRvbj48YnV0dG9uIGRhdGEtdmFsPSI1Ij41PC9idXR0b24+PGJ1dHRvbiBkYXRhLXZhbD0iNiI+NjwvYnV0dG9uPjxidXR0b24gZGF0YS12YWw9IioiIGNsYXNzPSJvcGVyYXRvciI+w5c8L2J1dHRvbj48L2Rpdj48ZGl2PjxidXR0b24gZGF0YS12YWw9IjEiPjE8L2J1dHRvbj48YnV0dG9uIGRhdGEtdmFsPSIyIj4yPC9idXR0b24+PGJ1dHRvbiBkYXRhLXZhbD0iMyI+MzwvYnV0dG9uPjxidXR0b24gZGF0YS12YWw9Ii0iIGNsYXNzPSJvcGVyYXRvciI+4oiSPC9idXR0b24+PC9kaXY+PGRpdj48YnV0dG9uIGRhdGEtdmFsPSIwIj4wPC9idXR0b24+PGJ1dHRvbiBkYXRhLXZhbD0iLiI+LjwvYnV0dG9uPjxidXR0b24gaWQ9ImNsZWFyIj5DPC9idXR0b24+PGJ1dHRvbiBkYXRhLXZhbD0iKyIgY2xhc3M9Im9wZXJhdG9yIj4rPC9idXR0b24+PC9kaXY+PGJ1dHRvbiBpZD0iZXF1YWxzIiBjbGFzcz0iZXF1YWxzIj49PC9idXR0b24+PC9kaXY+PHNjcmlwdD5jb25zdCBkaXNwbGF5ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2Rpc3BsYXknKTsNCiAgY29uc3QgYnV0dG9ucyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJyNjYWxjdWxhdG9yIGJ1dHRvbltkYXRhLXZhbF0nKTsNCiAgY29uc3QgY2xlYXJCdG4gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnY2xlYXInKTsNCiAgY29uc3QgZXF1YWxzQnRuID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2VxdWFscycpOw0KDQogIGJ1dHRvbnMuZm9yRWFjaChidG4gPT4gew0KICAgIGJ0bi5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsICgpID0+IHsNCiAgICAgIGRpc3BsYXkudmFsdWUgKz0gYnRuLmdldEF0dHJpYnV0ZSgnZGF0YS12YWwnKTsNCiAgICB9KTsNCiAgfSk7DQoNCiAgY2xlYXJCdG4uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoKSA9PiB7DQogICAgZGlzcGxheS52YWx1ZSA9ICcnOw0KICB9KTsNCg0KICBlcXVhbHNCdG4uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoKSA9PiB7DQogICAgdHJ5IHsNCiAgICAgIC8vIEV2YWx1YXRlIGV4cHJlc3Npb24gc2FmZWx5DQogICAgICAvLyBSZXBsYWNlIG11bHRpcGxpY2F0aW9uIGFuZCBkaXZpc2lvbiBzeW1ib2xzIGZpcnN0IChpbiBjYXNlIHlvdSB3YW50IHRvIHN1cHBvcnQgw7cgYW5kIMOXIGluIGRpc3BsYXkpDQogICAgICBjb25zdCBleHByID0gZGlzcGxheS52YWx1ZS5yZXBsYWNlKC/Dty9nLCAnLycpLnJlcGxhY2UoL8OXL2csICcqJyk7DQogICAgICBjb25zdCByZXN1bHQgPSBGdW5jdGlvbignInVzZSBzdHJpY3QiO3JldHVybiAoJyArIGV4cHIgKyAnKScpKCk7DQogICAgICBkaXNwbGF5LnZhbHVlID0gcmVzdWx0Ow0KICAgIH0gY2F0Y2ggew0KICAgICAgZGlzcGxheS52YWx1ZSA9ICdFcnJvcic7DQogICAgfQ0KICB9KTs8L3NjcmlwdD48L2JvZHk+PC9odG1sPg==`,
|
|
|
|
|
notepad: "data:text/html;charset=utf-8;base64,PGh0bWw+PGhlYWQ+PHRpdGxlPm5vdGVwYWQ8L3RpdGxlPjxzdHlsZSB0eXBlPSJ0ZXh0L2NzcyI+Ym9keXttYXJnaW46MH10ZXh0YXJlYXtyZXNpemU6bm9uZTt3aWR0aDo5OCU7aGVpZ2h0Ojk4JTtwb3NpdGlvbjphYnNvbHV0ZTt0b3A6MDtib3JkZXI6bm9uZTttYXJnaW46MSU7Zm9udC1mYW1pbHk6bW9ub3NwYWNlO2ZvbnQtc2l6ZToxZW07b3ZlcmZsb3c6aGlkZGVufXRleHRhcmVhOmZvY3Vze291dGxpbmU6MH08L3N0eWxlPjwvaGVhZD48Ym9keT48dGV4dGFyZWE+PC90ZXh0YXJlYT48L2JvZHk+PC9odG1sPg=="
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-11 04:09:20 +02:00
|
|
|
function download(filename, text) {
|
|
|
|
|
var element = document.createElement('a');
|
|
|
|
|
element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
|
|
|
|
|
element.setAttribute('download', filename);
|
|
|
|
|
|
|
|
|
|
element.style.display = 'none';
|
|
|
|
|
document.body.appendChild(element);
|
|
|
|
|
|
|
|
|
|
element.click();
|
|
|
|
|
|
|
|
|
|
document.body.removeChild(element);
|
|
|
|
|
}
|
|
|
|
|
function openJsonFilePrompt(callback) {
|
|
|
|
|
const input = document.createElement('input');
|
|
|
|
|
input.type = 'file';
|
|
|
|
|
input.accept = '.json,application/json';
|
|
|
|
|
|
|
|
|
|
input.onchange = (event) => {
|
|
|
|
|
const file = event.target.files[0];
|
|
|
|
|
if (!file) return;
|
|
|
|
|
|
|
|
|
|
const reader = new FileReader();
|
|
|
|
|
reader.onload = () => {
|
|
|
|
|
try {
|
|
|
|
|
const json = JSON.parse(reader.result);
|
|
|
|
|
callback(null, json);
|
|
|
|
|
} catch (err) {
|
|
|
|
|
callback(err);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
reader.readAsText(file);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
input.click();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2025-08-09 05:25:35 +02:00
|
|
|
var shell = {
|
|
|
|
|
taskbar_wind: null,
|
|
|
|
|
taskbar_size: 25,
|
|
|
|
|
startmenuWidth: 400,
|
|
|
|
|
startmenuHeight: 300
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
function doTheBullshitByShellBruh() {
|
|
|
|
|
const taskbarWind = shell.taskbar_wind;
|
|
|
|
|
const taskbarSize = shell.taskbar_size;
|
|
|
|
|
const desktopRect = desktop.getBoundingClientRect();
|
|
|
|
|
transformWindow(taskbarWind.windID,
|
|
|
|
|
desktopRect.width,
|
|
|
|
|
taskbarSize,
|
|
|
|
|
0,
|
|
|
|
|
desktopRect.height - taskbarSize
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-11 04:09:20 +02:00
|
|
|
shell.launch = function (app) {
|
|
|
|
|
switch (app) {
|
|
|
|
|
case "Notepad":
|
2025-08-09 05:25:35 +02:00
|
|
|
createWindow(embeddedApps.notepad, {
|
|
|
|
|
resizable: true,
|
|
|
|
|
name: "Notepad"
|
|
|
|
|
}); // Launch notepad
|
2025-08-11 04:09:20 +02:00
|
|
|
break;
|
|
|
|
|
case "Calculator":
|
2025-08-09 05:25:35 +02:00
|
|
|
const calc = createWindow(embeddedApps.calc, {
|
|
|
|
|
resizable: true,
|
|
|
|
|
name: "Calculator"
|
|
|
|
|
}); // Launch ZE CALCULATOR
|
|
|
|
|
calc.minSizeX = 500;
|
|
|
|
|
calc.minSizeY = 444;
|
|
|
|
|
updateWindowMin(calc.windID);
|
2025-08-11 04:09:20 +02:00
|
|
|
break;
|
|
|
|
|
case "laminax":
|
|
|
|
|
createWindow("https://www.youtube.com/embed/6uN3dxJRnss", { name: "You found the easter egg!" });
|
|
|
|
|
break;
|
|
|
|
|
case "lamver": {
|
|
|
|
|
const wind = createWindow("about:blank", {
|
|
|
|
|
name: "About LaminaxOS"
|
|
|
|
|
});
|
|
|
|
|
const smDoc = wind.iframe.contentDocument || wind.iframe.contentWindow.document;
|
|
|
|
|
smDoc.open();
|
|
|
|
|
smDoc.write(`
|
|
|
|
|
<!DOCTYPE html>
|
|
|
|
|
<html>
|
|
|
|
|
<head>
|
|
|
|
|
<style>
|
|
|
|
|
body {
|
|
|
|
|
margin: 0;
|
|
|
|
|
background: #222;
|
|
|
|
|
color: white;
|
|
|
|
|
font-family: sans-serif;
|
|
|
|
|
height: 100%;
|
|
|
|
|
overflow: auto;
|
|
|
|
|
padding: 10px;
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
}
|
|
|
|
|
h2 {
|
|
|
|
|
margin-top: 0;
|
|
|
|
|
font-size: 1.2em;
|
|
|
|
|
|
|
|
|
|
padding-bottom: 6px;
|
|
|
|
|
}
|
|
|
|
|
ul {
|
|
|
|
|
list-style: none;
|
|
|
|
|
padding: 0;
|
|
|
|
|
}
|
|
|
|
|
li {
|
|
|
|
|
padding: 6px 10px;
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
border-radius: 4px;
|
|
|
|
|
}
|
|
|
|
|
li:hover {
|
|
|
|
|
background: #444;
|
|
|
|
|
}
|
|
|
|
|
</style>
|
|
|
|
|
</head>
|
|
|
|
|
<body>
|
|
|
|
|
<h2>LaminaxOS 8 Enterprise</h2>
|
|
|
|
|
<hr>
|
|
|
|
|
<p>LaminaxOS</p>
|
|
|
|
|
<p>Version 7.6 (Build 17503: Service Pack 2)</p>
|
|
|
|
|
<p>"Copyright" 2040 LAMINAX Corporation; Some Rights Reserved</p>
|
|
|
|
|
</body>
|
|
|
|
|
</html>
|
|
|
|
|
`);
|
|
|
|
|
smDoc.close();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case "Settings":
|
|
|
|
|
{
|
|
|
|
|
const wind = createWindow("about:blank", {
|
|
|
|
|
name: "LaminaxOS Settings"
|
|
|
|
|
});
|
|
|
|
|
const smDoc = wind.iframe.contentDocument || wind.iframe.contentWindow.document;
|
|
|
|
|
smDoc.open();
|
|
|
|
|
smDoc.write(`
|
|
|
|
|
<!DOCTYPE html>
|
|
|
|
|
<html>
|
|
|
|
|
<head>
|
|
|
|
|
<style>
|
|
|
|
|
body {
|
|
|
|
|
margin: 0;
|
|
|
|
|
background: #222;
|
|
|
|
|
color: white;
|
|
|
|
|
font-family: sans-serif;
|
|
|
|
|
height: 100%;
|
|
|
|
|
overflow: auto;
|
|
|
|
|
padding: 10px;
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
}
|
|
|
|
|
h2 {
|
|
|
|
|
margin-top: 0;
|
|
|
|
|
font-size: 1.2em;
|
|
|
|
|
border-bottom: 1px solid #555;
|
|
|
|
|
padding-bottom: 6px;
|
|
|
|
|
}
|
|
|
|
|
ul {
|
|
|
|
|
list-style: none;
|
|
|
|
|
padding: 0;
|
|
|
|
|
}
|
|
|
|
|
li {
|
|
|
|
|
padding: 6px 10px;
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
border-radius: 4px;
|
|
|
|
|
color: lightblue;
|
|
|
|
|
}
|
|
|
|
|
li:hover {
|
|
|
|
|
background: #444;
|
|
|
|
|
}
|
|
|
|
|
</style>
|
|
|
|
|
</head>
|
|
|
|
|
<body>
|
|
|
|
|
<h2>Adjust your computer's settings</h2>
|
|
|
|
|
<ul>
|
|
|
|
|
<li onclick="parent.postMessage({type:'startItem', action:'openApp', app:'lamver'}, '*')">About This OS</li>
|
|
|
|
|
<ul>
|
|
|
|
|
<hr>
|
|
|
|
|
<ul>
|
|
|
|
|
<li onclick="parent.postMessage({type:'saveExport'}, '*')">Save User</li>
|
|
|
|
|
<li onclick="parent.postMessage({type:'loadExport'}, '*')">Load User</li>
|
|
|
|
|
<ul>
|
|
|
|
|
</body>
|
|
|
|
|
</html>
|
|
|
|
|
`);
|
|
|
|
|
smDoc.close();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
console.log("%c" + "You Silly goober!", "color: #7289DA; -webkit-text-stroke: 2px black; font-size: 32px; font-weight: bold;");
|
|
|
|
|
console.log("This app doesnt exist! :3c");
|
2025-08-09 05:25:35 +02:00
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
shell.updateTaskbar = doTheBullshitByShellBruh;
|
|
|
|
|
|
|
|
|
|
shell.init = function () {
|
|
|
|
|
// Create wind for shell using API
|
|
|
|
|
const taskbarWind = createWindow("about:blank", {
|
|
|
|
|
headerless: true,
|
|
|
|
|
resizable: false,
|
|
|
|
|
indent: false
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
shell.taskbar_wind = taskbarWind;
|
|
|
|
|
taskbarWind.minSizeX = 0;
|
|
|
|
|
taskbarWind.minSizeY = 0;
|
|
|
|
|
taskbarWind.alwaysOnTop = true;
|
|
|
|
|
taskbarWind.hideInTaskbar = true;
|
|
|
|
|
|
|
|
|
|
// Inject base HTML for taskbar
|
|
|
|
|
const tbDoc = taskbarWind.iframe.contentDocument || taskbarWind.iframe.contentWindow.document;
|
|
|
|
|
tbDoc.open();
|
|
|
|
|
tbDoc.write(`
|
|
|
|
|
<!DOCTYPE html>
|
|
|
|
|
<html>
|
|
|
|
|
<head>
|
|
|
|
|
<style>
|
|
|
|
|
body {
|
|
|
|
|
margin: 0;
|
|
|
|
|
background: #333;
|
|
|
|
|
color: white;
|
|
|
|
|
font-family: sans-serif;
|
|
|
|
|
height: 100%;
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
}
|
|
|
|
|
.start-btn {
|
|
|
|
|
padding: 4px 8px;
|
|
|
|
|
background: #555;
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
margin: 0 4px;
|
|
|
|
|
border-radius: 3px;
|
|
|
|
|
user-select: none;
|
|
|
|
|
}
|
|
|
|
|
.start-btn:hover {
|
|
|
|
|
background: #777;
|
|
|
|
|
}
|
|
|
|
|
.task-list {
|
|
|
|
|
flex: 1;
|
|
|
|
|
display: flex;
|
|
|
|
|
gap: 4px;
|
|
|
|
|
overflow-x: auto;
|
|
|
|
|
}
|
|
|
|
|
.task-item {
|
|
|
|
|
padding: 4px 8px;
|
|
|
|
|
background: #444;
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
border-radius: 3px;
|
|
|
|
|
white-space: nowrap;
|
|
|
|
|
}
|
|
|
|
|
.task-item:hover {
|
|
|
|
|
background: #666;
|
|
|
|
|
}
|
|
|
|
|
.clock {
|
|
|
|
|
padding: 0 8px;
|
|
|
|
|
}
|
|
|
|
|
</style>
|
|
|
|
|
</head>
|
|
|
|
|
<body>
|
|
|
|
|
<div class="start-btn" id="startBtn">Start</div>
|
|
|
|
|
<div class="task-list" id="taskList"></div>
|
|
|
|
|
<div class="clock" id="clock"></div>
|
|
|
|
|
<script>
|
|
|
|
|
function updateClock() {
|
|
|
|
|
const now = new Date();
|
|
|
|
|
document.getElementById('clock').textContent =
|
|
|
|
|
now.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
|
|
|
|
|
}
|
|
|
|
|
setInterval(updateClock, 1000);
|
|
|
|
|
updateClock();
|
|
|
|
|
</script>
|
|
|
|
|
</body>
|
|
|
|
|
</html>
|
|
|
|
|
`);
|
|
|
|
|
tbDoc.close();
|
|
|
|
|
|
|
|
|
|
shell.updateTaskbar();
|
|
|
|
|
shell.updateTaskbarContents();
|
|
|
|
|
|
|
|
|
|
window.addEventListener('resize', function () {
|
|
|
|
|
shell.updateTaskbar();
|
|
|
|
|
}, true);
|
|
|
|
|
// Add hook
|
|
|
|
|
windowHooks.push(shell.updateTaskbarContents);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Create start menu window
|
|
|
|
|
const startMenu = createWindow("about:blank", {
|
|
|
|
|
headerless: true,
|
|
|
|
|
resizable: false,
|
|
|
|
|
indent: false,
|
|
|
|
|
layer: "foreground",
|
|
|
|
|
name: "Start Menu"
|
|
|
|
|
});
|
|
|
|
|
shell.startMenu = startMenu;
|
|
|
|
|
startMenu.hideInTaskbar = true;
|
|
|
|
|
shell.updateTaskbarContents();
|
|
|
|
|
|
|
|
|
|
// Inject start menu HTML into its iframe
|
|
|
|
|
const smDoc = startMenu.iframe.contentDocument || startMenu.iframe.contentWindow.document;
|
|
|
|
|
smDoc.open();
|
|
|
|
|
smDoc.write(`
|
|
|
|
|
<!DOCTYPE html>
|
|
|
|
|
<html>
|
|
|
|
|
<head>
|
|
|
|
|
<style>
|
|
|
|
|
body {
|
|
|
|
|
margin: 0;
|
|
|
|
|
background: #222;
|
|
|
|
|
color: white;
|
|
|
|
|
font-family: sans-serif;
|
|
|
|
|
height: 100%;
|
|
|
|
|
overflow: auto;
|
|
|
|
|
padding: 10px;
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
}
|
|
|
|
|
h2 {
|
|
|
|
|
margin-top: 0;
|
|
|
|
|
font-size: 1.2em;
|
|
|
|
|
border-bottom: 1px solid #555;
|
|
|
|
|
padding-bottom: 6px;
|
|
|
|
|
}
|
|
|
|
|
ul {
|
|
|
|
|
list-style: none;
|
|
|
|
|
padding: 0;
|
|
|
|
|
}
|
|
|
|
|
li {
|
|
|
|
|
padding: 6px 10px;
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
border-radius: 4px;
|
|
|
|
|
}
|
|
|
|
|
li:hover {
|
|
|
|
|
background: #444;
|
|
|
|
|
}
|
|
|
|
|
</style>
|
|
|
|
|
</head>
|
|
|
|
|
<body>
|
|
|
|
|
<h2>Start Menu</h2>
|
|
|
|
|
<ul id="startItems">
|
|
|
|
|
<li onclick="parent.postMessage({type:'startItem', action:'openApp', app:'Calculator'}, '*')">Calculator</li>
|
|
|
|
|
<li onclick="parent.postMessage({type:'startItem', action:'openApp', app:'Notepad'}, '*')">Notepad</li>
|
|
|
|
|
<li onclick="parent.postMessage({type:'startItem', action:'openApp', app:'Settings'}, '*')">Settings</li>
|
|
|
|
|
</ul>
|
|
|
|
|
</body>
|
|
|
|
|
</html>
|
|
|
|
|
`);
|
|
|
|
|
smDoc.close();
|
|
|
|
|
|
|
|
|
|
// Initially hide the start menu by sizing it to zero and positioning it off-screen
|
|
|
|
|
transformWindow(startMenu.windID, 0, 0, 0, window.innerHeight);
|
|
|
|
|
|
|
|
|
|
// Helper function to show start menu
|
|
|
|
|
function showStartMenu() {
|
|
|
|
|
const desktopRect = desktop.getBoundingClientRect();
|
|
|
|
|
const taskbarHeight = shell.taskbar_size || 40;
|
|
|
|
|
const width = shell.startmenuWidth;
|
|
|
|
|
const height = shell.startmenuHeight;
|
|
|
|
|
const x = 0;
|
|
|
|
|
const y = desktopRect.height - taskbarHeight - height;
|
2025-08-11 04:09:20 +02:00
|
|
|
transformWindow(startMenu.windID, width, height, x, y, true);
|
2025-08-09 05:25:35 +02:00
|
|
|
focusWindow(startMenu.windID);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Helper function to hide start menu
|
|
|
|
|
function hideStartMenu() {
|
2025-08-11 04:09:20 +02:00
|
|
|
transformWindow(startMenu.windID, 0, 0, 0, window.innerHeight + shell.startmenuHeight, true);
|
2025-08-09 05:25:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let startMenuVisible = false;
|
|
|
|
|
|
|
|
|
|
// Hook start button to toggle start menu
|
|
|
|
|
const startBtn = tbDoc.getElementById('startBtn');
|
|
|
|
|
startBtn.addEventListener('click', () => {
|
|
|
|
|
if (startMenuVisible) {
|
|
|
|
|
hideStartMenu();
|
|
|
|
|
startMenuVisible = false;
|
|
|
|
|
} else {
|
|
|
|
|
showStartMenu();
|
|
|
|
|
startMenuVisible = true;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Close start menu when clicking outside (optional)
|
|
|
|
|
window.addEventListener('mousedown', (e) => {
|
|
|
|
|
if (!startMenuVisible) return;
|
|
|
|
|
const smElem = startMenu.windElems.windowDiv;
|
|
|
|
|
if (!smElem.contains(e.target)) {
|
|
|
|
|
hideStartMenu();
|
|
|
|
|
startMenuVisible = false;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Optionally, listen for start menu item clicks
|
|
|
|
|
window.addEventListener('message', (event) => {
|
|
|
|
|
if (event.data?.type === 'startItem' && event.data.action === 'openApp') {
|
|
|
|
|
console.log('Open app:', event.data.app);
|
|
|
|
|
// Close start menu on selection
|
|
|
|
|
hideStartMenu();
|
|
|
|
|
startMenuVisible = false;
|
|
|
|
|
shell.launch(event.data.app);
|
|
|
|
|
}
|
2025-08-11 04:09:20 +02:00
|
|
|
if (event.data?.type === "saveExport") {
|
|
|
|
|
download("savefile.json", JSON.stringify(yourFuckingSavefile));
|
|
|
|
|
}
|
|
|
|
|
if (event.data?.type === "loadExport") {
|
|
|
|
|
openJsonFilePrompt((err, data) => {
|
|
|
|
|
if (err) {
|
|
|
|
|
console.error('Invalid JSON file:', err);
|
|
|
|
|
} else {
|
|
|
|
|
yourFuckingSavefile = data;
|
|
|
|
|
save(globalSaveid);
|
|
|
|
|
window.location.reload();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
}
|
2025-08-09 05:25:35 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
hideStartMenu();
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
shell.updateTaskbarContents = function () {
|
|
|
|
|
const taskbarWind = shell.taskbar_wind;
|
|
|
|
|
if (!taskbarWind) return;
|
|
|
|
|
|
|
|
|
|
const tbDoc = taskbarWind.iframe.contentDocument || taskbarWind.iframe.contentWindow.document;
|
|
|
|
|
const taskList = tbDoc.getElementById('taskList');
|
|
|
|
|
if (!taskList) return;
|
|
|
|
|
|
|
|
|
|
// Clear old tasks
|
|
|
|
|
taskList.innerHTML = '';
|
|
|
|
|
|
|
|
|
|
// Add a button for each open window except the taskbar
|
|
|
|
|
for (const id in windows) {
|
|
|
|
|
const winObj = windows[id];
|
|
|
|
|
if (!winObj || id === taskbarWind.windID) continue;
|
|
|
|
|
if (winObj.hideInTaskbar) continue;
|
|
|
|
|
|
|
|
|
|
const btn = tbDoc.createElement('div');
|
|
|
|
|
btn.className = 'task-item';
|
|
|
|
|
btn.textContent = winObj.windElems.title.textContent || 'Window';
|
|
|
|
|
|
|
|
|
|
btn.addEventListener('click', () => {
|
|
|
|
|
// Focus the clicked window
|
|
|
|
|
winObj.windElems.windowDiv.style.zIndex = ++zIndexCounter;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
taskList.appendChild(btn);
|
|
|
|
|
}
|
|
|
|
|
};
|