|
@@ -998,6 +998,87 @@
|
|
To prevent individual events from bubbling, call sapp_consume_event() from within
|
|
To prevent individual events from bubbling, call sapp_consume_event() from within
|
|
the sokol_app.h event callback when that specific event is reported.
|
|
the sokol_app.h event callback when that specific event is reported.
|
|
|
|
|
|
|
|
+
|
|
|
|
+ SETTING THE CANVAS OBJECT ON THE WEB PLATFORM
|
|
|
|
+ =============================================
|
|
|
|
+ On the web, sokol_app.h and the Emscripten SDK functions need to find
|
|
|
|
+ the WebGL/WebGPU canvas intended for rendering and attaching event
|
|
|
|
+ handlers. This can happen in four ways:
|
|
|
|
+
|
|
|
|
+ 1. do nothing and just set the id of the canvas object to 'canvas' (preferred)
|
|
|
|
+ 2. via a CSS Selector string (preferred)
|
|
|
|
+ 3. by setting the `Module.canvas` property to the canvas object
|
|
|
|
+ 4. by adding the canvas object to the global variable `specialHTMLTargets[]`
|
|
|
|
+ (this is a special variable used by the Emscripten runtime to lookup
|
|
|
|
+ event target objects for which document.querySelector() cannot be used)
|
|
|
|
+
|
|
|
|
+ The easiest way is to just name your canvas object 'canvas':
|
|
|
|
+
|
|
|
|
+ <canvas id="canvas" ...></canvas>
|
|
|
|
+
|
|
|
|
+ This works because the default css selector string used by sokol_app.h
|
|
|
|
+ is '#canvas'.
|
|
|
|
+
|
|
|
|
+ If you name your canvas differently, you need to communicate that name to
|
|
|
|
+ sokol_app.h via `sapp_desc.html5_canvas_selector` as a regular css selector
|
|
|
|
+ string that's compatible with `document.querySelector()`. E.g. if your canvas
|
|
|
|
+ object looks like this:
|
|
|
|
+
|
|
|
|
+ <canvas id="bla" ...></canvas>
|
|
|
|
+
|
|
|
|
+ The `sapp_desc.html5_canvas_selector` string must be set to '#bla':
|
|
|
|
+
|
|
|
|
+ .html5_canvas_selector = "#bla"
|
|
|
|
+
|
|
|
|
+ If the canvas object cannot be looked up via `document.querySelector()` you
|
|
|
|
+ need to use one of the alternative methods, both involve the special
|
|
|
|
+ Emscripten runtime `Module` object which is usually setup in the index.html
|
|
|
|
+ like this before the WASM blob is loaded and instantiated:
|
|
|
|
+
|
|
|
|
+ <script type='text/javascript'>
|
|
|
|
+ var Module = {
|
|
|
|
+ // ...
|
|
|
|
+ };
|
|
|
|
+ </script>
|
|
|
|
+
|
|
|
|
+ The first option is to set the `Module.canvas` property to your canvas object:
|
|
|
|
+
|
|
|
|
+ <script type='text/javascript'>
|
|
|
|
+ var Module = {
|
|
|
|
+ canvas: my_canvas_object,
|
|
|
|
+ };
|
|
|
|
+ </script>
|
|
|
|
+
|
|
|
|
+ When sokol_app.h initializes, it will check the global Module object whether
|
|
|
|
+ a `Module.canvas` property exists and is an object. This method will add
|
|
|
|
+ a new entry to the `specialHTMLTargets[]` object
|
|
|
|
+
|
|
|
|
+ The other option is to add the canvas under a name chosen by you to the
|
|
|
|
+ special `specialHTMLTargets[]` map, which is used by the Emscripten runtime
|
|
|
|
+ to lookup 'event target objects' which are not visible to `document.querySelector()`.
|
|
|
|
+ Note that `specialHTMLTargets[]` must be updated after the Emscripten runtime
|
|
|
|
+ has started but before the WASM code is running. A good place for this is
|
|
|
|
+ the special `Module.preRun` array in index.html:
|
|
|
|
+
|
|
|
|
+ <script type='text/javascript'>
|
|
|
|
+ var Module = {
|
|
|
|
+ preRun: [
|
|
|
|
+ () => {
|
|
|
|
+ specialHTMLTargets['my_canvas'] = my_canvas_object;
|
|
|
|
+ }
|
|
|
|
+ ],
|
|
|
|
+ };
|
|
|
|
+ </script>
|
|
|
|
+
|
|
|
|
+ In that case, pass the same string to sokol_app.h which is used as key
|
|
|
|
+ in the specialHTMLTargets[] map:
|
|
|
|
+
|
|
|
|
+ .html5_canvas_selector = "my_canvas"
|
|
|
|
+
|
|
|
|
+ If sokol_app.h can't find your canvas for some reason check for warning
|
|
|
|
+ messages on the browser console.
|
|
|
|
+
|
|
|
|
+
|
|
OPTIONAL: DON'T HIJACK main() (#define SOKOL_NO_ENTRY)
|
|
OPTIONAL: DON'T HIJACK main() (#define SOKOL_NO_ENTRY)
|
|
======================================================
|
|
======================================================
|
|
NOTE: SOKOL_NO_ENTRY and sapp_run() is currently not supported on Android.
|
|
NOTE: SOKOL_NO_ENTRY and sapp_run() is currently not supported on Android.
|
|
@@ -1147,7 +1228,6 @@
|
|
the standard logger in sokol_log.h instead, otherwise you won't see any warnings or
|
|
the standard logger in sokol_log.h instead, otherwise you won't see any warnings or
|
|
errors.
|
|
errors.
|
|
|
|
|
|
-
|
|
|
|
TEMP NOTE DUMP
|
|
TEMP NOTE DUMP
|
|
==============
|
|
==============
|
|
- sapp_desc needs a bool whether to initialize depth-stencil surface
|
|
- sapp_desc needs a bool whether to initialize depth-stencil surface
|
|
@@ -1717,7 +1797,7 @@ typedef struct sapp_desc {
|
|
bool win32_console_utf8; // if true, set the output console codepage to UTF-8
|
|
bool win32_console_utf8; // if true, set the output console codepage to UTF-8
|
|
bool win32_console_create; // if true, attach stdout/stderr to a new console window
|
|
bool win32_console_create; // if true, attach stdout/stderr to a new console window
|
|
bool win32_console_attach; // if true, attach stdout/stderr to parent process
|
|
bool win32_console_attach; // if true, attach stdout/stderr to parent process
|
|
- const char* html5_canvas_name; // the name (id) of the HTML5 canvas element, default is "canvas"
|
|
|
|
|
|
+ const char* html5_canvas_selector; // css selector of the HTML5 canvas element, default is "#canvas"
|
|
bool html5_canvas_resize; // if true, the HTML5 canvas size is set to sapp_desc.width/height, otherwise canvas size is tracked
|
|
bool html5_canvas_resize; // if true, the HTML5 canvas size is set to sapp_desc.width/height, otherwise canvas size is tracked
|
|
bool html5_preserve_drawing_buffer; // HTML5 only: whether to preserve default framebuffer content between frames
|
|
bool html5_preserve_drawing_buffer; // HTML5 only: whether to preserve default framebuffer content between frames
|
|
bool html5_premultiplied_alpha; // HTML5 only: whether the rendered pixels use premultiplied alpha convention
|
|
bool html5_premultiplied_alpha; // HTML5 only: whether the rendered pixels use premultiplied alpha convention
|
|
@@ -3115,7 +3195,7 @@ _SOKOL_PRIVATE sapp_desc _sapp_desc_defaults(const sapp_desc* desc) {
|
|
res.gl_minor_version = 3;
|
|
res.gl_minor_version = 3;
|
|
#endif
|
|
#endif
|
|
}
|
|
}
|
|
- res.html5_canvas_name = _sapp_def(res.html5_canvas_name, "canvas");
|
|
|
|
|
|
+ res.html5_canvas_selector = _sapp_def(res.html5_canvas_selector, "#canvas");
|
|
res.clipboard_size = _sapp_def(res.clipboard_size, 8192);
|
|
res.clipboard_size = _sapp_def(res.clipboard_size, 8192);
|
|
res.max_dropped_files = _sapp_def(res.max_dropped_files, 1);
|
|
res.max_dropped_files = _sapp_def(res.max_dropped_files, 1);
|
|
res.max_dropped_file_path_length = _sapp_def(res.max_dropped_file_path_length, 2048);
|
|
res.max_dropped_file_path_length = _sapp_def(res.max_dropped_file_path_length, 2048);
|
|
@@ -3142,9 +3222,8 @@ _SOKOL_PRIVATE void _sapp_init_state(const sapp_desc* desc) {
|
|
_sapp.framebuffer_height = _sapp.window_height;
|
|
_sapp.framebuffer_height = _sapp.window_height;
|
|
_sapp.sample_count = _sapp.desc.sample_count;
|
|
_sapp.sample_count = _sapp.desc.sample_count;
|
|
_sapp.swap_interval = _sapp.desc.swap_interval;
|
|
_sapp.swap_interval = _sapp.desc.swap_interval;
|
|
- _sapp.html5_canvas_selector[0] = '#';
|
|
|
|
- _sapp_strcpy(_sapp.desc.html5_canvas_name, &_sapp.html5_canvas_selector[1], sizeof(_sapp.html5_canvas_selector) - 1);
|
|
|
|
- _sapp.desc.html5_canvas_name = &_sapp.html5_canvas_selector[1];
|
|
|
|
|
|
+ _sapp_strcpy(_sapp.desc.html5_canvas_selector, _sapp.html5_canvas_selector, sizeof(_sapp.html5_canvas_selector));
|
|
|
|
+ _sapp.desc.html5_canvas_selector = _sapp.html5_canvas_selector;
|
|
_sapp.html5_ask_leave_site = _sapp.desc.html5_ask_leave_site;
|
|
_sapp.html5_ask_leave_site = _sapp.desc.html5_ask_leave_site;
|
|
_sapp.clipboard.enabled = _sapp.desc.enable_clipboard;
|
|
_sapp.clipboard.enabled = _sapp.desc.enable_clipboard;
|
|
if (_sapp.clipboard.enabled) {
|
|
if (_sapp.clipboard.enabled) {
|
|
@@ -4780,7 +4859,7 @@ _SOKOL_PRIVATE void _sapp_ios_show_keyboard(bool shown) {
|
|
#if defined(_SAPP_EMSCRIPTEN)
|
|
#if defined(_SAPP_EMSCRIPTEN)
|
|
|
|
|
|
#if defined(EM_JS_DEPS)
|
|
#if defined(EM_JS_DEPS)
|
|
-EM_JS_DEPS(sokol_app, "$withStackSave,$stringToUTF8OnStack");
|
|
|
|
|
|
+EM_JS_DEPS(sokol_app, "$withStackSave,$stringToUTF8OnStack,$findCanvasEventTarget");
|
|
#endif
|
|
#endif
|
|
|
|
|
|
#ifdef __cplusplus
|
|
#ifdef __cplusplus
|
|
@@ -4930,10 +5009,8 @@ _SOKOL_PRIVATE void _sapp_emsc_set_clipboard_string(const char* str) {
|
|
sapp_js_write_clipboard(str);
|
|
sapp_js_write_clipboard(str);
|
|
}
|
|
}
|
|
|
|
|
|
-EM_JS(void, sapp_js_add_dragndrop_listeners, (const char* canvas_name_cstr), {
|
|
|
|
|
|
+EM_JS(void, sapp_js_add_dragndrop_listeners, (void), {
|
|
Module.sokol_drop_files = [];
|
|
Module.sokol_drop_files = [];
|
|
- const canvas_name = UTF8ToString(canvas_name_cstr);
|
|
|
|
- const canvas = document.getElementById(canvas_name);
|
|
|
|
Module.sokol_dragenter = (event) => {
|
|
Module.sokol_dragenter = (event) => {
|
|
event.stopPropagation();
|
|
event.stopPropagation();
|
|
event.preventDefault();
|
|
event.preventDefault();
|
|
@@ -4966,6 +5043,8 @@ EM_JS(void, sapp_js_add_dragndrop_listeners, (const char* canvas_name_cstr), {
|
|
// FIXME? see computation of targetX/targetY in emscripten via getClientBoundingRect
|
|
// FIXME? see computation of targetX/targetY in emscripten via getClientBoundingRect
|
|
__sapp_emsc_end_drop(event.clientX, event.clientY, mods);
|
|
__sapp_emsc_end_drop(event.clientX, event.clientY, mods);
|
|
};
|
|
};
|
|
|
|
+ \x2F\x2A\x2A @suppress {missingProperties} \x2A\x2F
|
|
|
|
+ const canvas = Module.sapp_emsc_target;
|
|
canvas.addEventListener('dragenter', Module.sokol_dragenter, false);
|
|
canvas.addEventListener('dragenter', Module.sokol_dragenter, false);
|
|
canvas.addEventListener('dragleave', Module.sokol_dragleave, false);
|
|
canvas.addEventListener('dragleave', Module.sokol_dragleave, false);
|
|
canvas.addEventListener('dragover', Module.sokol_dragover, false);
|
|
canvas.addEventListener('dragover', Module.sokol_dragover, false);
|
|
@@ -5005,24 +5084,30 @@ EM_JS(void, sapp_js_fetch_dropped_file, (int index, _sapp_html5_fetch_callback c
|
|
reader.readAsArrayBuffer(files[index]);
|
|
reader.readAsArrayBuffer(files[index]);
|
|
});
|
|
});
|
|
|
|
|
|
-EM_JS(void, sapp_js_remove_dragndrop_listeners, (const char* canvas_name_cstr), {
|
|
|
|
- const canvas_name = UTF8ToString(canvas_name_cstr);
|
|
|
|
- const canvas = document.getElementById(canvas_name);
|
|
|
|
|
|
+EM_JS(void, sapp_js_remove_dragndrop_listeners, (void), {
|
|
|
|
+ \x2F\x2A\x2A @suppress {missingProperties} \x2A\x2F
|
|
|
|
+ const canvas = Module.sapp_emsc_target;
|
|
canvas.removeEventListener('dragenter', Module.sokol_dragenter);
|
|
canvas.removeEventListener('dragenter', Module.sokol_dragenter);
|
|
canvas.removeEventListener('dragleave', Module.sokol_dragleave);
|
|
canvas.removeEventListener('dragleave', Module.sokol_dragleave);
|
|
canvas.removeEventListener('dragover', Module.sokol_dragover);
|
|
canvas.removeEventListener('dragover', Module.sokol_dragover);
|
|
canvas.removeEventListener('drop', Module.sokol_drop);
|
|
canvas.removeEventListener('drop', Module.sokol_drop);
|
|
});
|
|
});
|
|
|
|
|
|
-EM_JS(void, sapp_js_init, (const char* c_str_target), {
|
|
|
|
- // lookup and store canvas object by name
|
|
|
|
- const target_str = UTF8ToString(c_str_target);
|
|
|
|
- Module.sapp_emsc_target = document.getElementById(target_str);
|
|
|
|
|
|
+EM_JS(void, sapp_js_init, (const char* c_str_target_selector), {
|
|
|
|
+ const target_selector_str = UTF8ToString(c_str_target_selector);
|
|
|
|
+ if (Module['canvas'] !== undefined) {
|
|
|
|
+ if (typeof Module['canvas'] === 'object') {
|
|
|
|
+ specialHTMLTargets[target_selector_str] = Module['canvas'];
|
|
|
|
+ } else {
|
|
|
|
+ console.warn("sokol_app.h: Module['canvas'] is set but is not an object");
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ Module.sapp_emsc_target = findCanvasEventTarget(target_selector_str);
|
|
if (!Module.sapp_emsc_target) {
|
|
if (!Module.sapp_emsc_target) {
|
|
- console.log("sokol_app.h: invalid target:" + target_str);
|
|
|
|
|
|
+ console.warn("sokol_app.h: can't find html5_canvas_selector ", target_selector_str);
|
|
}
|
|
}
|
|
if (!Module.sapp_emsc_target.requestPointerLock) {
|
|
if (!Module.sapp_emsc_target.requestPointerLock) {
|
|
- console.log("sokol_app.h: target doesn't support requestPointerLock:" + target_str);
|
|
|
|
|
|
+ console.warn("sokol_app.h: target doesn't support requestPointerLock: ", target_selector_str);
|
|
}
|
|
}
|
|
});
|
|
});
|
|
|
|
|
|
@@ -5853,7 +5938,7 @@ _SOKOL_PRIVATE void _sapp_emsc_register_eventhandlers(void) {
|
|
sapp_js_add_clipboard_listener();
|
|
sapp_js_add_clipboard_listener();
|
|
}
|
|
}
|
|
if (_sapp.drop.enabled) {
|
|
if (_sapp.drop.enabled) {
|
|
- sapp_js_add_dragndrop_listeners(&_sapp.html5_canvas_selector[1]);
|
|
|
|
|
|
+ sapp_js_add_dragndrop_listeners();
|
|
}
|
|
}
|
|
#if defined(SOKOL_GLES3)
|
|
#if defined(SOKOL_GLES3)
|
|
emscripten_set_webglcontextlost_callback(_sapp.html5_canvas_selector, 0, true, _sapp_emsc_webgl_context_cb);
|
|
emscripten_set_webglcontextlost_callback(_sapp.html5_canvas_selector, 0, true, _sapp_emsc_webgl_context_cb);
|
|
@@ -5887,7 +5972,7 @@ _SOKOL_PRIVATE void _sapp_emsc_unregister_eventhandlers(void) {
|
|
sapp_js_remove_clipboard_listener();
|
|
sapp_js_remove_clipboard_listener();
|
|
}
|
|
}
|
|
if (_sapp.drop.enabled) {
|
|
if (_sapp.drop.enabled) {
|
|
- sapp_js_remove_dragndrop_listeners(&_sapp.html5_canvas_selector[1]);
|
|
|
|
|
|
+ sapp_js_remove_dragndrop_listeners();
|
|
}
|
|
}
|
|
#if defined(SOKOL_GLES3)
|
|
#if defined(SOKOL_GLES3)
|
|
emscripten_set_webglcontextlost_callback(_sapp.html5_canvas_selector, 0, true, 0);
|
|
emscripten_set_webglcontextlost_callback(_sapp.html5_canvas_selector, 0, true, 0);
|
|
@@ -5931,7 +6016,7 @@ _SOKOL_PRIVATE void _sapp_emsc_frame_main_loop(void) {
|
|
|
|
|
|
_SOKOL_PRIVATE void _sapp_emsc_run(const sapp_desc* desc) {
|
|
_SOKOL_PRIVATE void _sapp_emsc_run(const sapp_desc* desc) {
|
|
_sapp_init_state(desc);
|
|
_sapp_init_state(desc);
|
|
- sapp_js_init(&_sapp.html5_canvas_selector[1]);
|
|
|
|
|
|
+ sapp_js_init(_sapp.html5_canvas_selector);
|
|
double w, h;
|
|
double w, h;
|
|
if (_sapp.desc.html5_canvas_resize) {
|
|
if (_sapp.desc.html5_canvas_resize) {
|
|
w = (double) _sapp_def(_sapp.desc.width, _SAPP_FALLBACK_DEFAULT_WINDOW_WIDTH);
|
|
w = (double) _sapp_def(_sapp.desc.width, _SAPP_FALLBACK_DEFAULT_WINDOW_WIDTH);
|