diff --git a/include/SDL3/SDL_hints.h b/include/SDL3/SDL_hints.h index 9c8ad3f828..2793d09421 100644 --- a/include/SDL3/SDL_hints.h +++ b/include/SDL3/SDL_hints.h @@ -711,8 +711,6 @@ extern "C" { * * This hint only applies to the emscripten platform. * - * The default value is "#canvas" - * * This hint should be set before creating a window. * * \since This hint is available since SDL 3.2.0. @@ -726,7 +724,7 @@ extern "C" { * * The variable can be one of: * - * - "#window": the javascript window object (default) + * - "#window": the javascript window object * - "#document": the javascript document object * - "#screen": the javascript window.screen object * - "#canvas": the WebGL canvas element diff --git a/include/SDL3/SDL_video.h b/include/SDL3/SDL_video.h index a7afc3267b..aa46d8aac6 100644 --- a/include/SDL3/SDL_video.h +++ b/include/SDL3/SDL_video.h @@ -1280,6 +1280,19 @@ extern SDL_DECLSPEC SDL_Window * SDLCALL SDL_CreatePopupWindow(SDL_Window *paren * * The window is implicitly shown if the "hidden" property is not set. * + * These are additional supported properties with Emscripten: + * + * - `SDL_PROP_WINDOW_CREATE_EMSCRIPTEN_CANVAS_ID`: the id given to the canvas element. + * This should start with a '#' sign + * - `SDL_PROP_WINDOW_CREATE_EMSCRIPTEN_KEYBOARD_ELEMENT`: override the binding element + * for keyboard inputs for this canvas. The variable can be one of: + * - "#window": the javascript window object (default) + * - "#document": the javascript document object + * - "#screen": the javascript window.screen object + * - "#canvas": the WebGL canvas element + * - "#none": Don't bind anything at all + * - any other string without a leading # sign applies to the element on the + * page with that ID. * Windows with the "tooltip" and "menu" properties are popup windows and have * the behaviors and guidelines outlined in SDL_CreatePopupWindow(). * @@ -1341,6 +1354,8 @@ extern SDL_DECLSPEC SDL_Window * SDLCALL SDL_CreateWindowWithProperties(SDL_Prop #define SDL_PROP_WINDOW_CREATE_WIN32_HWND_POINTER "SDL.window.create.win32.hwnd" #define SDL_PROP_WINDOW_CREATE_WIN32_PIXEL_FORMAT_HWND_POINTER "SDL.window.create.win32.pixel_format_hwnd" #define SDL_PROP_WINDOW_CREATE_X11_WINDOW_NUMBER "SDL.window.create.x11.window" +#define SDL_PROP_WINDOW_CREATE_EMSCRIPTEN_CANVAS_ID "SDL.window.create.emscripten.canvas_id" +#define SDL_PROP_WINDOW_CREATE_EMSCRIPTEN_KEYBOARD_ELEMENT "SDL.window.create.emscripten.keyboard_element" /** * Get the numeric ID of a window. diff --git a/src/video/emscripten/SDL_emscriptenevents.c b/src/video/emscripten/SDL_emscriptenevents.c index d9fa3c8fa3..fbea4416ec 100644 --- a/src/video/emscripten/SDL_emscriptenevents.c +++ b/src/video/emscripten/SDL_emscriptenevents.c @@ -1005,14 +1005,8 @@ static void Emscripten_unset_drag_event_callbacks(SDL_WindowData *data) }, data->canvas_id); } -static const char *Emscripten_GetKeyboardTargetElement() +static const char *Emscripten_GetKeyboardTargetElement(const char *target) { - const char *target = SDL_GetHint(SDL_HINT_EMSCRIPTEN_KEYBOARD_ELEMENT); - - if (!target || !*target) { - return EMSCRIPTEN_EVENT_TARGET_WINDOW; - } - if (SDL_strcmp(target, "#none") == 0) { return NULL; } else if (SDL_strcmp(target, "#window") == 0) { @@ -1053,8 +1047,7 @@ void Emscripten_RegisterEventHandlers(SDL_WindowData *data) emscripten_set_pointerlockchange_callback(EMSCRIPTEN_EVENT_TARGET_DOCUMENT, data, 0, Emscripten_HandlePointerLockChange); - // Keyboard events are awkward - keyElement = Emscripten_GetKeyboardTargetElement(); + keyElement = Emscripten_GetKeyboardTargetElement(data->keyboard_element); if (keyElement) { emscripten_set_keydown_callback(keyElement, data, 0, Emscripten_HandleKey); emscripten_set_keyup_callback(keyElement, data, 0, Emscripten_HandleKey); @@ -1079,7 +1072,7 @@ void Emscripten_RegisterEventHandlers(SDL_WindowData *data) void Emscripten_UnregisterEventHandlers(SDL_WindowData *data) { - const char *target; + const char *keyElement; // !!! FIXME: currently Emscripten doesn't have a Drop Events functions like emscripten_set_*_callback, but we should use those when they do: Emscripten_unset_drag_event_callbacks(data); @@ -1111,11 +1104,11 @@ void Emscripten_UnregisterEventHandlers(SDL_WindowData *data) emscripten_set_pointerlockchange_callback(EMSCRIPTEN_EVENT_TARGET_DOCUMENT, NULL, 0, NULL); - target = Emscripten_GetKeyboardTargetElement(); - if (target) { - emscripten_set_keydown_callback(target, NULL, 0, NULL); - emscripten_set_keyup_callback(target, NULL, 0, NULL); - emscripten_set_keypress_callback(target, NULL, 0, NULL); + keyElement = Emscripten_GetKeyboardTargetElement(data->keyboard_element); + if (keyElement) { + emscripten_set_keydown_callback(keyElement, NULL, 0, NULL); + emscripten_set_keyup_callback(keyElement, NULL, 0, NULL); + emscripten_set_keypress_callback(keyElement, NULL, 0, NULL); } emscripten_set_fullscreenchange_callback(EMSCRIPTEN_EVENT_TARGET_DOCUMENT, NULL, 0, NULL); diff --git a/src/video/emscripten/SDL_emscriptenvideo.c b/src/video/emscripten/SDL_emscriptenvideo.c index 1496268610..ad49e2fa1a 100644 --- a/src/video/emscripten/SDL_emscriptenvideo.c +++ b/src/video/emscripten/SDL_emscriptenvideo.c @@ -293,12 +293,17 @@ static bool Emscripten_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window, } selector = SDL_GetHint(SDL_HINT_EMSCRIPTEN_CANVAS_SELECTOR); - if (!selector) { - selector = "#canvas"; + if (!selector || !*selector) { + selector = SDL_GetStringProperty(props, SDL_PROP_WINDOW_CREATE_EMSCRIPTEN_CANVAS_ID, "#canvas"); } - wdata->canvas_id = SDL_strdup(selector); + selector = SDL_GetHint(SDL_HINT_EMSCRIPTEN_KEYBOARD_ELEMENT); + if (!selector || !*selector) { + selector = SDL_GetStringProperty(props, SDL_PROP_WINDOW_CREATE_EMSCRIPTEN_KEYBOARD_ELEMENT, "#window"); + } + wdata->keyboard_element = SDL_strdup(selector); + if (window->flags & SDL_WINDOW_HIGH_PIXEL_DENSITY) { wdata->pixel_ratio = emscripten_get_device_pixel_ratio(); } else { @@ -397,6 +402,8 @@ static void Emscripten_DestroyWindow(SDL_VideoDevice *_this, SDL_Window *window) emscripten_set_canvas_element_size(data->canvas_id, 0, 0); SDL_free(data->canvas_id); + SDL_free(data->keyboard_element); + SDL_free(window->internal); window->internal = NULL; } diff --git a/src/video/emscripten/SDL_emscriptenvideo.h b/src/video/emscripten/SDL_emscriptenvideo.h index 892d074475..db4751ce88 100644 --- a/src/video/emscripten/SDL_emscriptenvideo.h +++ b/src/video/emscripten/SDL_emscriptenvideo.h @@ -36,6 +36,7 @@ struct SDL_WindowData SDL_GLContext gl_context; char *canvas_id; + char *keyboard_element; float pixel_ratio;