diff options
-rw-r--r-- | src/library_html5.js | 18 | ||||
-rw-r--r-- | src/struct_info.json | 6 | ||||
-rw-r--r-- | system/include/emscripten/html5.h | 7 | ||||
-rw-r--r-- | tests/test_browser.py | 3 | ||||
-rw-r--r-- | tests/test_html5.c | 4 | ||||
-rw-r--r-- | tests/test_html5_fullscreen.c | 107 | ||||
-rw-r--r-- | tools/shared.py | 2 |
7 files changed, 141 insertions, 6 deletions
diff --git a/src/library_html5.js b/src/library_html5.js index 63a4dff7..b17a0d4d 100644 --- a/src/library_html5.js +++ b/src/library_html5.js @@ -13,6 +13,10 @@ var LibraryJSEvents = { visibilityChangeEvent: 0, touchEvent: 0, + // When we transition from fullscreen to windowed mode, we remember here the element that was just in fullscreen mode + // so that we can report information about that element in the event message. + previousFullscreenElement: null, + // When the C runtime exits via exit(), we unregister all event handlers added by this library to be nice and clean. // Track in this field whether we have yet registered that __ATEXIT__ handler. removeEventListenersRegistered: false, @@ -484,10 +488,20 @@ var LibraryJSEvents = { var isFullscreen = !!fullscreenElement; {{{ makeSetValue('eventStruct', C_STRUCTS.EmscriptenFullscreenChangeEvent.isFullscreen, 'isFullscreen', 'i32') }}}; {{{ makeSetValue('eventStruct', C_STRUCTS.EmscriptenFullscreenChangeEvent.fullscreenEnabled, 'JSEvents.fullscreenEnabled()', 'i32') }}}; - var nodeName = JSEvents.getNodeNameForTarget(fullscreenElement); - var id = (fullscreenElement && fullscreenElement.id) ? fullscreenElement.id : ''; + // If transitioning to fullscreen, report info about the element that is now fullscreen. + // If transitioning to windowed mode, report info about the element that just was fullscreen. + var reportedElement = isFullscreen ? fullscreenElement : JSEvents.previousFullscreenElement; + var nodeName = JSEvents.getNodeNameForTarget(reportedElement); + var id = (reportedElement && reportedElement.id) ? reportedElement.id : ''; writeStringToMemory(nodeName, eventStruct + {{{ C_STRUCTS.EmscriptenFullscreenChangeEvent.nodeName }}} ); writeStringToMemory(id, eventStruct + {{{ C_STRUCTS.EmscriptenFullscreenChangeEvent.id }}} ); + {{{ makeSetValue('eventStruct', C_STRUCTS.EmscriptenFullscreenChangeEvent.elementWidth, 'reportedElement ? reportedElement.clientWidth : 0', 'i32') }}}; + {{{ makeSetValue('eventStruct', C_STRUCTS.EmscriptenFullscreenChangeEvent.elementHeight, 'reportedElement ? reportedElement.clientHeight : 0', 'i32') }}}; + {{{ makeSetValue('eventStruct', C_STRUCTS.EmscriptenFullscreenChangeEvent.screenWidth, 'screen.width', 'i32') }}}; + {{{ makeSetValue('eventStruct', C_STRUCTS.EmscriptenFullscreenChangeEvent.screenHeight, 'screen.height', 'i32') }}}; + if (isFullscreen) { + JSEvents.previousFullscreenElement = fullscreenElement; + } }, registerFullscreenChangeEventCallback: function(target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString) { diff --git a/src/struct_info.json b/src/struct_info.json index 2aeffc9c..2a2b4c64 100644 --- a/src/struct_info.json +++ b/src/struct_info.json @@ -1207,7 +1207,11 @@ "isFullscreen", "fullscreenEnabled", "nodeName", - "id" + "id", + "elementWidth", + "elementHeight", + "screenWidth", + "screenHeight" ], "EmscriptenPointerlockChangeEvent": [ "isActive", diff --git a/system/include/emscripten/html5.h b/system/include/emscripten/html5.h index 06c647bf..6109d87f 100644 --- a/system/include/emscripten/html5.h +++ b/system/include/emscripten/html5.h @@ -388,9 +388,16 @@ typedef struct EmscriptenFullscreenChangeEvent { // Specifies if the current page has the ability to display elements fullscreen. EM_BOOL fullscreenEnabled; // The nodeName of the target HTML Element that is in full screen mode. See https://developer.mozilla.org/en-US/docs/Web/API/Node.nodeName + // If isFullscreen is false, then nodeName, id and elementWidth/Height specify information about the element that just exited fullscreen mode. EM_UTF8 nodeName[128]; // The HTML Element ID of the target HTML element that is in full screen mode. EM_UTF8 id[128]; + // The new pixel size of the element that changed fullscreen status. + int elementWidth; + int elementHeight; + // The size of the whole screen, in pixels. + int screenWidth; + int screenHeight; } EmscriptenFullscreenChangeEvent; /* diff --git a/tests/test_browser.py b/tests/test_browser.py index f2e17ea0..62d3f257 100644 --- a/tests/test_browser.py +++ b/tests/test_browser.py @@ -1846,6 +1846,9 @@ Module["preRun"].push(function () { def test_html5(self): self.btest(path_from_root('tests', 'test_html5.c'), expected='0') + def test_html5_fullscreen(self): + self.btest(path_from_root('tests', 'test_html5_fullscreen.c'), expected='0') + def test_codemods(self): for opt_level in [0, 2]: print 'opt level', opt_level diff --git a/tests/test_html5.c b/tests/test_html5.c index 77ddea98..fec46035 100644 --- a/tests/test_html5.c +++ b/tests/test_html5.c @@ -145,8 +145,8 @@ EM_BOOL orientationchange_callback(int eventType, const EmscriptenOrientationCha EM_BOOL fullscreenchange_callback(int eventType, const EmscriptenFullscreenChangeEvent *e, void *userData) { - printf("%s, isFullscreen: %d, fullscreenEnabled: %d, fs element nodeName: \"%s\", fs element id: \"%s\"\n", - emscripten_event_type_to_string(eventType), e->isFullscreen, e->fullscreenEnabled, e->nodeName, e->id); + printf("%s, isFullscreen: %d, fullscreenEnabled: %d, fs element nodeName: \"%s\", fs element id: \"%s\". New size: %dx%d pixels. Screen size: %dx%d pixels.\n", + emscripten_event_type_to_string(eventType), e->isFullscreen, e->fullscreenEnabled, e->nodeName, e->id, e->elementWidth, e->elementHeight, e->screenWidth, e->screenHeight); return 0; } diff --git a/tests/test_html5_fullscreen.c b/tests/test_html5_fullscreen.c new file mode 100644 index 00000000..9a284b09 --- /dev/null +++ b/tests/test_html5_fullscreen.c @@ -0,0 +1,107 @@ +#include <stdio.h> +#include <emscripten.h> +#include <string.h> +#include <emscripten/html5.h> + +#ifdef REPORT_RESULT +void report_result(int result) +{ + if (result == 0) { + printf("Test successful!\n"); + } else { + printf("Test failed!\n"); + } + REPORT_RESULT(); +} +#endif + +static inline const char *emscripten_event_type_to_string(int eventType) { + const char *events[] = { "(invalid)", "(none)", "keypress", "keydown", "keyup", "click", "mousedown", "mouseup", "dblclick", "mousemove", "wheel", "resize", + "scroll", "blur", "focus", "focusin", "focusout", "deviceorientation", "devicemotion", "orientationchange", "fullscreenchange", "pointerlockchange", + "visibilitychange", "touchstart", "touchend", "touchmove", "touchcancel", "gamepadconnected", "gamepaddisconnected", "beforeunload", + "batterychargingchange", "batterylevelchange", "webglcontextlost", "webglcontextrestored", "(invalid)" }; + ++eventType; + if (eventType < 0) eventType = 0; + if (eventType >= sizeof(events)/sizeof(events[0])) eventType = sizeof(events)/sizeof(events[0])-1; + return events[eventType]; +} + +const char *emscripten_result_to_string(EMSCRIPTEN_RESULT result) { + if (result == EMSCRIPTEN_RESULT_SUCCESS) return "EMSCRIPTEN_RESULT_SUCCESS"; + if (result == EMSCRIPTEN_RESULT_DEFERRED) return "EMSCRIPTEN_RESULT_DEFERRED"; + if (result == EMSCRIPTEN_RESULT_NOT_SUPPORTED) return "EMSCRIPTEN_RESULT_NOT_SUPPORTED"; + if (result == EMSCRIPTEN_RESULT_FAILED_NOT_DEFERRED) return "EMSCRIPTEN_RESULT_FAILED_NOT_DEFERRED"; + if (result == EMSCRIPTEN_RESULT_INVALID_TARGET) return "EMSCRIPTEN_RESULT_INVALID_TARGET"; + if (result == EMSCRIPTEN_RESULT_UNKNOWN_TARGET) return "EMSCRIPTEN_RESULT_UNKNOWN_TARGET"; + if (result == EMSCRIPTEN_RESULT_INVALID_PARAM) return "EMSCRIPTEN_RESULT_INVALID_PARAM"; + if (result == EMSCRIPTEN_RESULT_FAILED) return "EMSCRIPTEN_RESULT_FAILED"; + if (result == EMSCRIPTEN_RESULT_NO_DATA) return "EMSCRIPTEN_RESULT_NO_DATA"; + return "Unknown EMSCRIPTEN_RESULT!"; +} + +#define TEST_RESULT(x) if (ret != EMSCRIPTEN_RESULT_SUCCESS) printf("%s returned %s.\n", #x, emscripten_result_to_string(ret)); + +// The event handler functions can return 1 to suppress the event and disable the default action. That calls event.preventDefault(); +// Returning 0 signals that the event was not consumed by the code, and will allow the event to pass on and bubble up normally. +EM_BOOL key_callback(int eventType, const EmscriptenKeyboardEvent *e, void *userData) +{ + if (eventType == EMSCRIPTEN_EVENT_KEYPRESS && (!strcmp(e->key, "f") || e->which == 102)) { + EmscriptenFullscreenChangeEvent fsce; + EMSCRIPTEN_RESULT ret = emscripten_get_fullscreen_status(&fsce); + TEST_RESULT(emscripten_get_fullscreen_status); + if (!fsce.isFullscreen) { + printf("Requesting fullscreen..\n"); + ret = emscripten_request_fullscreen(0, 1); + TEST_RESULT(emscripten_request_fullscreen); + } else { + printf("Exiting fullscreen..\n"); + ret = emscripten_exit_fullscreen(); + TEST_RESULT(emscripten_exit_fullscreen); + ret = emscripten_get_fullscreen_status(&fsce); + TEST_RESULT(emscripten_get_fullscreen_status); + if (fsce.isFullscreen) { + fprintf(stderr, "Fullscreen exit did not work!\n"); + } + } + } + + return 0; +} + +int callCount = 0; + +EM_BOOL fullscreenchange_callback(int eventType, const EmscriptenFullscreenChangeEvent *e, void *userData) +{ + printf("%s, isFullscreen: %d, fullscreenEnabled: %d, fs element nodeName: \"%s\", fs element id: \"%s\". New size: %dx%d pixels. Screen size: %dx%d pixels.\n", + emscripten_event_type_to_string(eventType), e->isFullscreen, e->fullscreenEnabled, e->nodeName, e->id, e->elementWidth, e->elementHeight, e->screenWidth, e->screenHeight); + + ++callCount; + if (callCount == 1) { // Transitioned to fullscreen. + if (!e->isFullscreen) { + report_result(1); + } + } else if (callCount == 2) { // Transitioned to windowed, we must be back to the default pixel size 300x150. + if (e->isFullscreen || e->elementWidth != 300 || e->elementHeight != 150) { + report_result(1); + } else { + report_result(0); + } + } + return 0; +} + +int main() +{ + EMSCRIPTEN_RESULT ret = emscripten_set_keypress_callback(0, 0, 1, key_callback); + TEST_RESULT(emscripten_set_keypress_callback); + + ret = emscripten_set_fullscreenchange_callback(0, 0, 1, fullscreenchange_callback); + TEST_RESULT(emscripten_set_fullscreenchange_callback); + + printf("To finish this test, press f to enter fullscreen mode, and then exit it.\n"); + + /* For the events to function, one must either call emscripten_set_main_loop or enable Module.noExitRuntime by some other means. + Otherwise the application will exit after leaving main(), and the atexit handlers will clean up all event hooks (by design). */ + EM_ASM(Module['noExitRuntime'] = true); + return 0; +} diff --git a/tools/shared.py b/tools/shared.py index b7a186fc..a413a932 100644 --- a/tools/shared.py +++ b/tools/shared.py @@ -361,7 +361,7 @@ def find_temp_directory(): # we re-check sanity when the settings are changed) # We also re-check sanity and clear the cache when the version changes -EMSCRIPTEN_VERSION = '1.12.2' +EMSCRIPTEN_VERSION = '1.12.3' def generate_sanity(): return EMSCRIPTEN_VERSION + '|' + get_llvm_target() + '|' + LLVM_ROOT + '|' + get_clang_version() |