windowjs / windowjs Goto Github PK
View Code? Open in Web Editor NEWWindow.js is an open-source Javascript runtime for desktop graphics programming.
Home Page: https://windowjs.org
License: MIT License
Window.js is an open-source Javascript runtime for desktop graphics programming.
Home Page: https://windowjs.org
License: MIT License
6a09576 enabled running the tests in workflows but they fail to start on all VMs.
The Windows builder hangs on test startup:
https://github.com/windowjs/windowjs/runs/4834049064
The macOS builder crashes in glfwInit:
https://github.com/windowjs/windowjs/runs/4834049290
The Linux builder asserts on glfwInit failing:
https://github.com/windowjs/windowjs/runs/4834077103
Also tried using Xvfb on the Linux builder but got the same result.
Apparently GitHub actions don't support applications that open native windows. This needs further investigation, and possibly an alternative to run tests in PRs.
Configure and build on Linux without setting up the build env (which sets CC and CXX to clang) to build with GCC.
It currently fails with multiple warnings.
The parent process should be able to restrict the permissions and privileges of the child process:
The prebuilt binaries are blocked by Windows and macOS by default, and the security checks must be bypassed manually by the user.
Figure how to sign the binaries for distribution to avoid these warnings.
Likewise, avoid the malware warning in Chrome when the binaries are downloaded.
Each subprocess handle gets its own pipe, thread and uv_loop. The thread and the uv_loop could be shared for the same parent process though.
This might only make a difference in programs that spawn a large number of subprocesses, like the test runner.
I noticed that setInterval is not a thing in windowjs, so I decided to write my own implementation:
function* getIntervalIdgen() {
var i = 0;
yield i++;
}
const intervalIdGenerator = getIntervalIdgen();
function getId() {
return intervalIdGenerator.next.value;
}
{
var g;
if (typeof window !== "undefined") {
g = window;
} else if (typeof global !== "undefined") {
g = global;
} else if (typeof self !== "undefined") {
g = self;
} else {
g = this;
}
g.setInterval = function (callback, timer) {
let id = getId();
g.intervalState.intervals.push({
callback,
timer,
timeDelta: Date.now(),
id,
});
return id;
};
g.clearInterval = function (id) {
g.intervalState.intervals = g.intervalState.intervals.filter(function (
item
) {
return item.id != id;
});
};
g.intervalState = {};
g.intervalState.intervals = [];
function fireIntervals() {
requestAnimationFrame(fireIntervals);
for (const interval of g.intervalState.intervals) {
if (Date.now() - interval.timeDelta >= interval.timer) {
interval.callback();
interval.timeDelta = Date.now();
}
}
}
requestAnimationFrame(fireIntervals);
}
Would be nice if I could contribute that to the repo, but I don't want to mess with c.
See this TODO:
Line 209 in 2c1cc2b
The framebuffer should be cleared with glClear(GL_COLOR_BUFFER_BIT).
However, that doesn't seem to clear anything in an older iMac with a Radean R9 M390 GPU.
This is probably a syncing issue between the GL contexts, or GL state that needs to be reset.
GitHub has updated "windows-latest" from "windows-2019" to "windows-2022":
The v8 build fails to start with that change:
Building v8 in libraries/v8/out/Release"
1 file(s) copied.
Traceback (most recent call last):
File "D:/a/windowjs/windowjs/libraries/v8/build/vs_toolchain.py", line 573, in <module>
sys.exit(main())
File "D:/a/windowjs/windowjs/libraries/v8/build/vs_toolchain.py", line 569, in main
return commands[sys.argv[1]](*sys.argv[2:])
File "D:/a/windowjs/windowjs/libraries/v8/build/vs_toolchain.py", line 546, in GetToolchainDir
runtime_dll_dirs = SetEnvironmentAndGetRuntimeDllDirs()
File "D:/a/windowjs/windowjs/libraries/v8/build/vs_toolchain.py", line 106, in SetEnvironmentAndGetRuntimeDllDirs
os.environ['GYP_MSVS_OVERRIDE_PATH'] = DetectVisualStudioPath()
File "D:/a/windowjs/windowjs/libraries/v8/build/vs_toolchain.py", line 197, in DetectVisualStudioPath
version_as_year = GetVisualStudioVersion()
File "D:/a/windowjs/windowjs/libraries/v8/build/vs_toolchain.py", line 186, in GetVisualStudioVersion
raise Exception('No supported Visual Studio can be found.'
Exception: No supported Visual Studio can be found. Supported versions are: 16.0 (2019), 15.0 (2017).
ERROR at //build/config/win/visual_studio_version.gni:27:7: Script returned non-zero exit code.
exec_script("../../vs_toolchain.py", [ "get_toolchain_dir" ], "scope")
^----------
Current dir: D:/a/windowjs/windowjs/libraries/v8/out/Release/
Command: D:/a/windowjs/windowjs/libraries/depot_tools/bootstrap-2@3_8_10_chromium_23_bin/python3/bin/python3.exe D:/a/windowjs/windowjs/libraries/v8/build/vs_toolchain.py get_toolchain_dir
Returned 1.
See //build/toolchain/win/BUILD.gn:9:1: whence it was imported.
import("//build/config/win/visual_studio_version.gni")
^----------------------------------------------------
See //BUILD.gn:1516:1: which caused the file to be included.
action("postmortem-metadata") {
^------------------------------
GN failed!
The window sizes reported by glfwGetWindowSize are not the same as the framebuffer sizes on macOS with retina displays.
The devicePixelRatio is 2, but the window has also been already scaled.
Fix this by looking for the actual framebuffer size and using the pixel dimensions, instead of the screen dimensions, for OpenGL calls.
The console (opens with F1) is just another Window.js program, running in a separate process and communicating with the main window. The source file is src/console.js
and can be executed directly for development:
$ out/src/windowjs.exe src/console.js
It's also possible to get a console for the console during development.
It tries to give some common controls like Home key and Delete key support, history, etc. but there's still a lot missing to make it more useful:
Some of these can be done now, others (like mouse support) will take more effort.
Add the possibility of import export js file
export function hello(){
console.log("hello world")
}
import {hello} from "./imported.js"
hello()
Repro: new CanvasGradient()
Expected output:
Uncaught TypeError: Illegal constructor
at <anonymous>:1:1
Actual output: crash, Assertion failed on ..\src\js_api_canvas.cc:1961: false
How does all of this work?
Window.js should implement the fetch API:
https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API
This enables programs to make HTTP and HTTPS requests.
Window.js should support a WebSockets client as well.
A separate issue is to support networking and TCP/UDP sockets in general, also for server sockets.
Window.js already includes libuv but it's scoped to supporting subprocesses, and there's a uv_loop_t per subprocess. The first part of this work would be to refactor that and have a single uv_loop_t to be used for all file, networking and IPC for the current process. It should be completely reset on reloads.
Another initial decision to make is which library to use to have an HTTP client, as libuv only gives sockets support. Some candidates to look into would be libcurl and libwebsockets, and maybe cronet.
See the documentation at MDN:
https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/createPattern
Would be great if the app shows the content behind if the color of the canvas is transparent.
The program in attachment crashes after 10 to 100 runs on debug builds with MSVC on Windows.
This seems to come from a destructor running at shutdown, possibly reaching for memory from an object that has already been destroyed. The issue only reproes on early exits via std::exit, which is often used in child processes (and in tests).
Window.js doesn't have any destructors at shutdown, and this is likely coming from one of the libraries used. It's quite tricky to pin this down.
The temporary fix at in commit f56ae2f uses std::quick_exit instead, to bypass the atexit callbacks. This isn't great; this bug is to change that back to std::exit and fix the shutdown issue.
https://gist.github.com/joaodasilva/f5fe471c7b27a2606689c6aeeb7398ed
Build links to all the APIs at https://windowjs.org/doc/api.
Ideally, this would collect the list of APIs from the front-matter YAML in each API page.
See the MDN docs:
https://developer.mozilla.org/en-US/docs/Web/API/Path2D
Some of the canvas APIs should be extended to accept Path2D objects as parameters, like fill
and clip
.
Properties like canvas.fillStyle
can be set to CSS color values:
https://windowjs.org/doc/canvas#canvas.fillStyle
However, a lot of the valid CSS color values aren't supported:
https://developer.mozilla.org/en-US/docs/Web/CSS/color_value
For example: HSL, lab, using system color names, etc.
This should be added to src/css.cc
in CSSColorToSkColor
.
Window.js should have a sound API.
I'm not sure whether adopting the entire HTML5 Web Audio API is the way to go:
https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API
This has a lot of APIs to support sound synthesis, which is nice but the more common use case is to load .wav, .mp3, .ogg files and the like, and to play them out / mix them / etc.
The first part of solving this issue is to determine what is to be built, and to find an adequate support library.
The initial checkout and the first build involve many steps and are somewhat fragile, especially around setting up depot_tools, gn and PATH correctly.
Automate more of these steps:
glfwWaitEvents / glfwPollEvents block during resizing gestures, and the window contents don't get refreshed until the mouse button is released.
Windows has a similar issue that was fixed by patching glfw/glfw#1426, which uses Win32 fibers to keep pumping the main loop during resizes (and do it in the main thread).
Another approach is to render in a separate thread, but that complicates a lot threading and state synchronization for JS API calls.
Currently, only JSON objects can be passed.
Every subprocess created with Process.spawn() also gets its own window.
It can set window.visible = false
to prevent it from showing up.
But ideally, it should be possible to pass --headless
to make the subprocess never create its native window and just run code. In those cases, window
and window.canvas
wouldn't exist in the global object.
Most of the work to support that involves adapting the main loop to "wait for events" without using GLFW; the main event source would be libuv instead (e.g. wake-up whenever more bytes are received from the parent process or from a subprocess).
Repro console commands:
ImageBitmap.prototype.width
ImageBitmap.prototype.encode()
ImageData.prototype.width
CanvasRenderingContext2D.prototype.getTransform()
etc.
Expected output: Something like
TypeError: Method get ArrayBuffer.prototype.byteLength called on incompatible receiver #<ArrayBuffer>
at ArrayBuffer.get byteLength [as byteLength] (<anonymous>)
Actual output: crash.
(This is presumably because the API wrapper functions don't yet check the result of info.This()
)
Window.js should have convenient APIs to encode and decode data:
Use methods as in HTML5 where available; for example:
https://developer.mozilla.org/en-US/docs/Web/API/btoa
https://developer.mozilla.org/en-US/docs/Web/API/atob
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURI
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent
Gzip support could have a similar global function, like ztob
and btoz
or so.
The btoa/atob APIs encode and decode from/to strings; Window.js could have a variant that also supports encoding ArrayBuffers and decoding into an ArrayBuffer.
The project doesn't have any test coverage so far, other than checking out the examples.
Issues like #34 require changing a large number of places, and this only scales when test coverage to confirm that everything is still working as expected.
The idea is to build a test runner that runs on Window.js itself:
Hello, @joaodasilva , I am improving the website of windowjs, If any feature you want, inform me, I will try to Implement that. This will be my first contribution.
This should work in the console:
s = await File.readText('README.md')
But fails with a SyntaxError:
Uncaught SyntaxError: await is only valid in async functions and the top level bodies of modules
Window.js applications run like so:
$ windowjs.exe main.js
And then the main.js
script can load assets, usually in the same directory and subdirectories.
To make distribution easier, Window.js should support bundling all of the relevant assets into a single .zip file and then executing that directly:
$ windowjs.exe app.zip
APIs like File.readText
and so on would need to support looking up files both in the filesystem, and also in the zip bundle if there was one.
Same as Chocolatey or Homebrew
https://scoop.sh/
See this Twitter thread:
https://twitter.com/youtoy/status/1481653823295062019
Seems like Window.js is rendering with the wrong pixel ratio for the framebuffer and/or the viewport.
Chrome SafeBrowsing flags the download of the prebuilt binaries because they are uncommon downloads.
Figure out how to fix this, and fix it.
See description in this discussion:
The prebuilt binaries are blocked by macOS by default, and the security checks must be bypassed manually by the user.
Figure how to sign the binaries for distribution to avoid these warnings.
The console is another Window.js process, running as a subprocess with some extra messaging internally.
So it doesn't support the usual text editing capabilities that a <textarea> or a text would give: no mouse selection, no copy/paste, etc.
This makes reporting issues and copying errors much harder.
However, a solution for this may well involve building a complete text editing, text layout and widgets library.
The documentation in the doc/ directory was developed to be statically built into HTML for the windowjs.org site.
However, it doesn't display well on Github:
Ideally, the documentation should be readable and links should work both on github and on windowjs.org.
Some newer canvas features like text modifiers could be implemented in window.js.
This doesn't happen very often but is very annoying in the GitHub workflows.
It's also very hard to reproduce locally, but happens after hundreds of runs like this:
$ while xvfb-run out-debug/windowjs tests/run_tests.js; do sleep 1; done
Super unclear why this happens though. It's likely a race or some indeterminism in the subprocess spawning code, or in child/parent event dispatching.
Similar to issue #59, this issue is about having networking support but at a lower level, by exposing support for TCP and UDP sockets directly.
Add APIs to open native file open/save dialogs:
File.openFileDialog()
File.openFilesDialog()
File.saveFileDialog()
etc.
Libraries to consider:
https://github.com/mlabbe/nativefiledialog
https://github.com/btzy/nativefiledialog-extended
https://github.com/samhocevar/portable-file-dialogs
https://github.com/AndrewBelt/osdialog
TinyFileDialogs
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.