aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/library_html5.js18
-rw-r--r--src/struct_info.json6
-rw-r--r--system/include/emscripten/html5.h7
-rw-r--r--tests/test_browser.py3
-rw-r--r--tests/test_html5.c4
-rw-r--r--tests/test_html5_fullscreen.c107
-rw-r--r--tools/shared.py2
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 f7c3919c..f2f90398 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()