summaryrefslogtreecommitdiff
path: root/platform/javascript
diff options
context:
space:
mode:
Diffstat (limited to 'platform/javascript')
-rw-r--r--platform/javascript/detect.py18
-rw-r--r--platform/javascript/display_server_javascript.cpp69
-rw-r--r--platform/javascript/display_server_javascript.h5
-rw-r--r--platform/javascript/emscripten_helpers.py6
-rw-r--r--platform/javascript/export/export.cpp2
-rw-r--r--platform/javascript/godot_js.h7
-rw-r--r--platform/javascript/js/engine/config.js17
-rw-r--r--platform/javascript/js/engine/engine.js2
-rw-r--r--platform/javascript/js/libs/library_godot_display.js201
-rw-r--r--platform/javascript/js/libs/library_godot_os.js6
10 files changed, 279 insertions, 54 deletions
diff --git a/platform/javascript/detect.py b/platform/javascript/detect.py
index e80ef374ec..ac8d8de7e0 100644
--- a/platform/javascript/detect.py
+++ b/platform/javascript/detect.py
@@ -64,21 +64,21 @@ def configure(env):
sys.exit(255)
## Build type
- if env["target"] == "release":
+ if env["target"].startswith("release"):
# Use -Os to prioritize optimizing for reduced file size. This is
# particularly valuable for the web platform because it directly
# decreases download time.
# -Os reduces file size by around 5 MiB over -O3. -Oz only saves about
# 100 KiB over -Os, which does not justify the negative impact on
# run-time performance.
- env.Append(CCFLAGS=["-Os"])
- env.Append(LINKFLAGS=["-Os"])
- elif env["target"] == "release_debug":
- env.Append(CCFLAGS=["-Os"])
- env.Append(LINKFLAGS=["-Os"])
- env.Append(CPPDEFINES=["DEBUG_ENABLED"])
- # Retain function names for backtraces at the cost of file size.
- env.Append(LINKFLAGS=["--profiling-funcs"])
+ if env["optimize"] != "none":
+ env.Append(CCFLAGS=["-Os"])
+ env.Append(LINKFLAGS=["-Os"])
+
+ if env["target"] == "release_debug":
+ env.Append(CPPDEFINES=["DEBUG_ENABLED"])
+ # Retain function names for backtraces at the cost of file size.
+ env.Append(LINKFLAGS=["--profiling-funcs"])
else: # "debug"
env.Append(CPPDEFINES=["DEBUG_ENABLED"])
env.Append(CCFLAGS=["-O1", "-g"])
diff --git a/platform/javascript/display_server_javascript.cpp b/platform/javascript/display_server_javascript.cpp
index 12e06e24dc..fa6f5c1e9e 100644
--- a/platform/javascript/display_server_javascript.cpp
+++ b/platform/javascript/display_server_javascript.cpp
@@ -189,19 +189,19 @@ EM_BOOL DisplayServerJavaScript::mouse_button_callback(int p_event_type, const E
switch (p_event->button) {
case DOM_BUTTON_LEFT:
- ev->set_button_index(BUTTON_LEFT);
+ ev->set_button_index(MOUSE_BUTTON_LEFT);
break;
case DOM_BUTTON_MIDDLE:
- ev->set_button_index(BUTTON_MIDDLE);
+ ev->set_button_index(MOUSE_BUTTON_MIDDLE);
break;
case DOM_BUTTON_RIGHT:
- ev->set_button_index(BUTTON_RIGHT);
+ ev->set_button_index(MOUSE_BUTTON_RIGHT);
break;
case DOM_BUTTON_XBUTTON1:
- ev->set_button_index(BUTTON_XBUTTON1);
+ ev->set_button_index(MOUSE_BUTTON_XBUTTON1);
break;
case DOM_BUTTON_XBUTTON2:
- ev->set_button_index(BUTTON_XBUTTON2);
+ ev->set_button_index(MOUSE_BUTTON_XBUTTON2);
break;
default:
return false;
@@ -341,7 +341,7 @@ void DisplayServerJavaScript::cursor_set_custom_image(const RES &p_cursor, Curso
Rect2 atlas_rect;
if (texture.is_valid()) {
- image = texture->get_data();
+ image = texture->get_image();
}
if (!image.is_valid() && atlas_texture.is_valid()) {
@@ -364,7 +364,7 @@ void DisplayServerJavaScript::cursor_set_custom_image(const RES &p_cursor, Curso
ERR_FAIL_COND(texture_size.width > 256 || texture_size.height > 256);
ERR_FAIL_COND(p_hotspot.x > texture_size.width || p_hotspot.y > texture_size.height);
- image = texture->get_data();
+ image = texture->get_image();
ERR_FAIL_COND(!image.is_valid());
@@ -461,13 +461,13 @@ EM_BOOL DisplayServerJavaScript::wheel_callback(int p_event_type, const Emscript
ev->set_metakey(input->is_key_pressed(KEY_META));
if (p_event->deltaY < 0)
- ev->set_button_index(BUTTON_WHEEL_UP);
+ ev->set_button_index(MOUSE_BUTTON_WHEEL_UP);
else if (p_event->deltaY > 0)
- ev->set_button_index(BUTTON_WHEEL_DOWN);
+ ev->set_button_index(MOUSE_BUTTON_WHEEL_DOWN);
else if (p_event->deltaX > 0)
- ev->set_button_index(BUTTON_WHEEL_LEFT);
+ ev->set_button_index(MOUSE_BUTTON_WHEEL_LEFT);
else if (p_event->deltaX < 0)
- ev->set_button_index(BUTTON_WHEEL_RIGHT);
+ ev->set_button_index(MOUSE_BUTTON_WHEEL_RIGHT);
else
return false;
@@ -536,6 +536,43 @@ bool DisplayServerJavaScript::screen_is_touchscreen(int p_screen) const {
return godot_js_display_touchscreen_is_available();
}
+// Virtual Keybaord
+void DisplayServerJavaScript::vk_input_text_callback(const char *p_text, int p_cursor) {
+ DisplayServerJavaScript *ds = DisplayServerJavaScript::get_singleton();
+ if (!ds || ds->input_text_callback.is_null()) {
+ return;
+ }
+ // Call input_text
+ Variant event = String(p_text);
+ Variant *eventp = &event;
+ Variant ret;
+ Callable::CallError ce;
+ ds->input_text_callback.call((const Variant **)&eventp, 1, ret, ce);
+ // Insert key right to reach position.
+ Input *input = Input::get_singleton();
+ Ref<InputEventKey> k;
+ for (int i = 0; i < p_cursor; i++) {
+ k.instance();
+ k->set_pressed(true);
+ k->set_echo(false);
+ k->set_keycode(KEY_RIGHT);
+ input->parse_input_event(k);
+ k.instance();
+ k->set_pressed(false);
+ k->set_echo(false);
+ k->set_keycode(KEY_RIGHT);
+ input->parse_input_event(k);
+ }
+}
+
+void DisplayServerJavaScript::virtual_keyboard_show(const String &p_existing_text, const Rect2 &p_screen_rect, bool p_multiline, int p_max_input_length, int p_cursor_start, int p_cursor_end) {
+ godot_js_display_vk_show(p_existing_text.utf8().get_data(), p_multiline, p_cursor_start, p_cursor_end);
+}
+
+void DisplayServerJavaScript::virtual_keyboard_hide() {
+ godot_js_display_vk_hide();
+}
+
// Gamepad
void DisplayServerJavaScript::gamepad_callback(int p_index, int p_connected, const char *p_id, const char *p_guid) {
Input *input = Input::get_singleton();
@@ -564,7 +601,7 @@ void DisplayServerJavaScript::process_joypads() {
// Buttons 6 and 7 in the standard mapping need to be
// axis to be handled as JOY_AXIS_TRIGGER by Godot.
if (s_standard && (b == 6 || b == 7)) {
- Input::JoyAxis joy_axis;
+ Input::JoyAxisValue joy_axis;
joy_axis.min = 0;
joy_axis.value = value;
int a = b == 6 ? JOY_AXIS_TRIGGER_LEFT : JOY_AXIS_TRIGGER_RIGHT;
@@ -574,7 +611,7 @@ void DisplayServerJavaScript::process_joypads() {
}
}
for (int a = 0; a < s_axes_num; a++) {
- Input::JoyAxis joy_axis;
+ Input::JoyAxisValue joy_axis;
joy_axis.min = -1;
joy_axis.value = s_axes[a];
input->joy_axis(idx, a, joy_axis);
@@ -764,6 +801,7 @@ DisplayServerJavaScript::DisplayServerJavaScript(const String &p_rendering_drive
godot_js_display_paste_cb(update_clipboard_callback);
godot_js_display_drop_files_cb(drop_files_js_callback);
godot_js_display_gamepad_cb(&DisplayServerJavaScript::gamepad_callback);
+ godot_js_display_vk_cb(&vk_input_text_callback);
Input::get_singleton()->set_event_dispatch_function(_dispatch_input_event);
}
@@ -793,7 +831,8 @@ bool DisplayServerJavaScript::has_feature(Feature p_feature) const {
//case FEATURE_WINDOW_TRANSPARENCY:
//case FEATURE_KEEP_SCREEN_ON:
//case FEATURE_ORIENTATION:
- //case FEATURE_VIRTUAL_KEYBOARD:
+ case FEATURE_VIRTUAL_KEYBOARD:
+ return godot_js_display_vk_available() != 0;
default:
return false;
}
@@ -866,7 +905,7 @@ void DisplayServerJavaScript::window_set_input_event_callback(const Callable &p_
}
void DisplayServerJavaScript::window_set_input_text_callback(const Callable &p_callable, WindowID p_window) {
- input_text_callback = p_callable; // TODO unused... do I need this?
+ input_text_callback = p_callable;
}
void DisplayServerJavaScript::window_set_drop_files_callback(const Callable &p_callable, WindowID p_window) {
diff --git a/platform/javascript/display_server_javascript.h b/platform/javascript/display_server_javascript.h
index 47e25ab2a0..ece38f1a95 100644
--- a/platform/javascript/display_server_javascript.h
+++ b/platform/javascript/display_server_javascript.h
@@ -75,6 +75,8 @@ private:
static EM_BOOL keypress_callback(int p_event_type, const EmscriptenKeyboardEvent *p_event, void *p_user_data);
static EM_BOOL keyup_callback(int p_event_type, const EmscriptenKeyboardEvent *p_event, void *p_user_data);
+ static void vk_input_text_callback(const char *p_text, int p_cursor);
+
static EM_BOOL mousemove_callback(int p_event_type, const EmscriptenMouseEvent *p_event, void *p_user_data);
static EM_BOOL mouse_button_callback(int p_event_type, const EmscriptenMouseEvent *p_event, void *p_user_data);
@@ -135,6 +137,9 @@ public:
int screen_get_dpi(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
float screen_get_scale(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
+ void virtual_keyboard_show(const String &p_existing_text, const Rect2 &p_screen_rect = Rect2(), bool p_multiline = false, int p_max_input_length = -1, int p_cursor_start = -1, int p_cursor_end = -1) override;
+ void virtual_keyboard_hide() override;
+
// windows
Vector<DisplayServer::WindowID> get_window_list() const override;
WindowID get_window_at_screen_position(const Point2i &p_position) const override;
diff --git a/platform/javascript/emscripten_helpers.py b/platform/javascript/emscripten_helpers.py
index 04fbba8a41..b3b15a1574 100644
--- a/platform/javascript/emscripten_helpers.py
+++ b/platform/javascript/emscripten_helpers.py
@@ -21,7 +21,11 @@ def get_build_version():
name = "custom_build"
if os.getenv("BUILD_NAME") != None:
name = os.getenv("BUILD_NAME")
- return "%d.%d.%d.%s.%s" % (version.major, version.minor, version.patch, version.status, name)
+ v = "%d.%d" % (version.major, version.minor)
+ if version.patch > 0:
+ v += ".%d" % version.patch
+ v += ".%s.%s" % (version.status, name)
+ return v
def create_engine_file(env, target, source, externs):
diff --git a/platform/javascript/export/export.cpp b/platform/javascript/export/export.cpp
index 46d0458ca1..1e89e144cc 100644
--- a/platform/javascript/export/export.cpp
+++ b/platform/javascript/export/export.cpp
@@ -297,6 +297,7 @@ void EditorExportPlatformJavaScript::_fix_html(Vector<uint8_t> &p_html, const Re
}
Dictionary config;
config["canvasResizePolicy"] = p_preset->get("html/canvas_resize_policy");
+ config["experimentalVK"] = p_preset->get("html/experimental_virtual_keyboard");
config["gdnativeLibs"] = libs;
config["executable"] = p_name;
config["args"] = args;
@@ -352,6 +353,7 @@ void EditorExportPlatformJavaScript::get_export_options(List<ExportOption> *r_op
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "html/custom_html_shell", PROPERTY_HINT_FILE, "*.html"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "html/head_include", PROPERTY_HINT_MULTILINE_TEXT), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "html/canvas_resize_policy", PROPERTY_HINT_ENUM, "None,Project,Adaptive"), 2));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "html/experimental_virtual_keyboard"), false));
}
String EditorExportPlatformJavaScript::get_name() const {
diff --git a/platform/javascript/godot_js.h b/platform/javascript/godot_js.h
index f86aadd2c2..4448a35670 100644
--- a/platform/javascript/godot_js.h
+++ b/platform/javascript/godot_js.h
@@ -93,6 +93,13 @@ extern void godot_js_display_notification_cb(void (*p_callback)(int p_notificati
extern void godot_js_display_paste_cb(void (*p_callback)(const char *p_text));
extern void godot_js_display_drop_files_cb(void (*p_callback)(char **p_filev, int p_filec));
extern void godot_js_display_setup_canvas(int p_width, int p_height, int p_fullscreen, int p_hidpi);
+
+// Display Virtual Keyboard
+extern int godot_js_display_vk_available();
+extern void godot_js_display_vk_cb(void (*p_input)(const char *p_text, int p_cursor));
+extern void godot_js_display_vk_show(const char *p_text, int p_multiline, int p_start, int p_end);
+extern void godot_js_display_vk_hide();
+
#ifdef __cplusplus
}
#endif
diff --git a/platform/javascript/js/engine/config.js b/platform/javascript/js/engine/config.js
index 82ff273ecf..6072782875 100644
--- a/platform/javascript/js/engine/config.js
+++ b/platform/javascript/js/engine/config.js
@@ -91,12 +91,25 @@ const InternalConfig = function (initConfig) { // eslint-disable-line no-unused-
*/
args: [],
/**
+ * When enabled, this will turn on experimental virtual keyboard support on mobile.
+ *
+ * @memberof EngineConfig
+ * @type {boolean}
+ * @default
+ */
+ experimentalVK: false,
+ /**
* @ignore
* @type {Array.<string>}
*/
persistentPaths: ['/userfs'],
/**
* @ignore
+ * @type {boolean}
+ */
+ persistentDrops: false,
+ /**
+ * @ignore
* @type {Array.<string>}
*/
gdnativeLibs: [],
@@ -223,6 +236,8 @@ const InternalConfig = function (initConfig) { // eslint-disable-line no-unused-
this.locale = parse('locale', this.locale);
this.canvasResizePolicy = parse('canvasResizePolicy', this.canvasResizePolicy);
this.persistentPaths = parse('persistentPaths', this.persistentPaths);
+ this.persistentDrops = parse('persistentDrops', this.persistentDrops);
+ this.experimentalVK = parse('experimentalVK', this.experimentalVK);
this.gdnativeLibs = parse('gdnativeLibs', this.gdnativeLibs);
this.fileSizes = parse('fileSizes', this.fileSizes);
this.args = parse('args', this.args);
@@ -307,6 +322,8 @@ const InternalConfig = function (initConfig) { // eslint-disable-line no-unused-
'canvas': this.canvas,
'canvasResizePolicy': this.canvasResizePolicy,
'locale': locale,
+ 'persistentDrops': this.persistentDrops,
+ 'virtualKeyboard': this.experimentalVK,
'onExecute': this.onExecute,
'onExit': function (p_code) {
cleanup(); // We always need to call the cleanup callback to free memory.
diff --git a/platform/javascript/js/engine/engine.js b/platform/javascript/js/engine/engine.js
index 19a0552c8c..7211ebbfd8 100644
--- a/platform/javascript/js/engine/engine.js
+++ b/platform/javascript/js/engine/engine.js
@@ -102,7 +102,7 @@ const Engine = (function () {
const me = this;
function doInit(promise) {
return promise.then(function (response) {
- return Godot(me.config.getModuleConfig(loadPath, response.clone()));
+ return Godot(me.config.getModuleConfig(loadPath, new Response(response.clone().body, { 'headers': [['content-type', 'application/wasm']] })));
}).then(function (module) {
const paths = me.config.persistentPaths;
return module['initFS'](paths).then(function (err) {
diff --git a/platform/javascript/js/libs/library_godot_display.js b/platform/javascript/js/libs/library_godot_display.js
index b4f1fee4ed..99aa4793d9 100644
--- a/platform/javascript/js/libs/library_godot_display.js
+++ b/platform/javascript/js/libs/library_godot_display.js
@@ -192,33 +192,45 @@ const GodotDisplayDragDrop = {
GodotDisplayDragDrop.promises = [];
GodotDisplayDragDrop.pending_files = [];
callback(drops);
- const dirs = [DROP.substr(0, DROP.length - 1)];
- // Remove temporary files
- files.forEach(function (file) {
- FS.unlink(file);
- let dir = file.replace(DROP, '');
- let idx = dir.lastIndexOf('/');
- while (idx > 0) {
- dir = dir.substr(0, idx);
- if (dirs.indexOf(DROP + dir) === -1) {
- dirs.push(DROP + dir);
- }
- idx = dir.lastIndexOf('/');
- }
- });
- // Remove dirs.
- dirs.sort(function (a, b) {
- const al = (a.match(/\//g) || []).length;
- const bl = (b.match(/\//g) || []).length;
- if (al > bl) {
- return -1;
- } else if (al < bl) {
- return 1;
+ if (GodotConfig.persistent_drops) {
+ // Delay removal at exit.
+ GodotOS.atexit(function (resolve, reject) {
+ GodotDisplayDragDrop.remove_drop(files, DROP);
+ resolve();
+ });
+ } else {
+ GodotDisplayDragDrop.remove_drop(files, DROP);
+ }
+ });
+ },
+
+ remove_drop: function (files, drop_path) {
+ const dirs = [drop_path.substr(0, drop_path.length - 1)];
+ // Remove temporary files
+ files.forEach(function (file) {
+ FS.unlink(file);
+ let dir = file.replace(drop_path, '');
+ let idx = dir.lastIndexOf('/');
+ while (idx > 0) {
+ dir = dir.substr(0, idx);
+ if (dirs.indexOf(drop_path + dir) === -1) {
+ dirs.push(drop_path + dir);
}
- return 0;
- }).forEach(function (dir) {
- FS.rmdir(dir);
- });
+ idx = dir.lastIndexOf('/');
+ }
+ });
+ // Remove dirs.
+ dirs.sort(function (a, b) {
+ const al = (a.match(/\//g) || []).length;
+ const bl = (b.match(/\//g) || []).length;
+ if (al > bl) {
+ return -1;
+ } else if (al < bl) {
+ return 1;
+ }
+ return 0;
+ }).forEach(function (dir) {
+ FS.rmdir(dir);
});
},
@@ -231,6 +243,105 @@ const GodotDisplayDragDrop = {
};
mergeInto(LibraryManager.library, GodotDisplayDragDrop);
+const GodotDisplayVK = {
+
+ $GodotDisplayVK__deps: ['$GodotRuntime', '$GodotConfig', '$GodotDisplayListeners'],
+ $GodotDisplayVK__postset: 'GodotOS.atexit(function(resolve, reject) { GodotDisplayVK.clear(); resolve(); });',
+ $GodotDisplayVK: {
+ textinput: null,
+ textarea: null,
+
+ available: function () {
+ return GodotConfig.virtual_keyboard && 'ontouchstart' in window;
+ },
+
+ init: function (input_cb) {
+ function create(what) {
+ const elem = document.createElement(what);
+ elem.style.display = 'none';
+ elem.style.position = 'absolute';
+ elem.style.zIndex = '-1';
+ elem.style.background = 'transparent';
+ elem.style.padding = '0px';
+ elem.style.margin = '0px';
+ elem.style.overflow = 'hidden';
+ elem.style.width = '0px';
+ elem.style.height = '0px';
+ elem.style.border = '0px';
+ elem.style.outline = 'none';
+ elem.readonly = true;
+ elem.disabled = true;
+ GodotDisplayListeners.add(elem, 'input', function (evt) {
+ const c_str = GodotRuntime.allocString(elem.value);
+ input_cb(c_str, elem.selectionEnd);
+ GodotRuntime.free(c_str);
+ }, false);
+ GodotDisplayListeners.add(elem, 'blur', function (evt) {
+ elem.style.display = 'none';
+ elem.readonly = true;
+ elem.disabled = true;
+ }, false);
+ GodotConfig.canvas.insertAdjacentElement('beforebegin', elem);
+ return elem;
+ }
+ GodotDisplayVK.textinput = create('input');
+ GodotDisplayVK.textarea = create('textarea');
+ GodotDisplayVK.updateSize();
+ },
+ show: function (text, multiline, start, end) {
+ if (!GodotDisplayVK.textinput || !GodotDisplayVK.textarea) {
+ return;
+ }
+ if (GodotDisplayVK.textinput.style.display !== '' || GodotDisplayVK.textarea.style.display !== '') {
+ GodotDisplayVK.hide();
+ }
+ GodotDisplayVK.updateSize();
+ const elem = multiline ? GodotDisplayVK.textarea : GodotDisplayVK.textinput;
+ elem.readonly = false;
+ elem.disabled = false;
+ elem.value = text;
+ elem.style.display = 'block';
+ elem.focus();
+ elem.setSelectionRange(start, end);
+ },
+ hide: function () {
+ if (!GodotDisplayVK.textinput || !GodotDisplayVK.textarea) {
+ return;
+ }
+ [GodotDisplayVK.textinput, GodotDisplayVK.textarea].forEach(function (elem) {
+ elem.blur();
+ elem.style.display = 'none';
+ elem.value = '';
+ });
+ },
+ updateSize: function () {
+ if (!GodotDisplayVK.textinput || !GodotDisplayVK.textarea) {
+ return;
+ }
+ const rect = GodotConfig.canvas.getBoundingClientRect();
+ function update(elem) {
+ elem.style.left = `${rect.left}px`;
+ elem.style.top = `${rect.top}px`;
+ elem.style.width = `${rect.width}px`;
+ elem.style.height = `${rect.height}px`;
+ }
+ update(GodotDisplayVK.textinput);
+ update(GodotDisplayVK.textarea);
+ },
+ clear: function () {
+ if (GodotDisplayVK.textinput) {
+ GodotDisplayVK.textinput.remove();
+ GodotDisplayVK.textinput = null;
+ }
+ if (GodotDisplayVK.textarea) {
+ GodotDisplayVK.textarea.remove();
+ GodotDisplayVK.textarea = null;
+ }
+ },
+ },
+};
+mergeInto(LibraryManager.library, GodotDisplayVK);
+
/*
* Display server cursor helper.
* Keeps track of cursor status and custom shapes.
@@ -511,7 +622,7 @@ mergeInto(LibraryManager.library, GodotDisplayScreen);
* Exposes all the functions needed by DisplayServer implementation.
*/
const GodotDisplay = {
- $GodotDisplay__deps: ['$GodotConfig', '$GodotRuntime', '$GodotDisplayCursor', '$GodotDisplayListeners', '$GodotDisplayDragDrop', '$GodotDisplayGamepads', '$GodotDisplayScreen'],
+ $GodotDisplay__deps: ['$GodotConfig', '$GodotRuntime', '$GodotDisplayCursor', '$GodotDisplayListeners', '$GodotDisplayDragDrop', '$GodotDisplayGamepads', '$GodotDisplayScreen', '$GodotDisplayVK'],
$GodotDisplay: {
window_icon: '',
findDPI: function () {
@@ -580,7 +691,11 @@ const GodotDisplay = {
godot_js_display_size_update__sig: 'i',
godot_js_display_size_update: function () {
- return GodotDisplayScreen.updateSize();
+ const updated = GodotDisplayScreen.updateSize();
+ if (updated) {
+ GodotDisplayVK.updateSize();
+ }
+ return updated;
},
godot_js_display_screen_size_get__sig: 'vii',
@@ -805,12 +920,42 @@ const GodotDisplay = {
canvas.style.left = 0;
break;
}
+ GodotDisplayScreen.updateSize();
if (p_fullscreen) {
GodotDisplayScreen.requestFullscreen();
}
},
/*
+ * Virtual Keyboard
+ */
+ godot_js_display_vk_show__sig: 'viiii',
+ godot_js_display_vk_show: function (p_text, p_multiline, p_start, p_end) {
+ const text = GodotRuntime.parseString(p_text);
+ const start = p_start > 0 ? p_start : 0;
+ const end = p_end > 0 ? p_end : start;
+ GodotDisplayVK.show(text, p_multiline, start, end);
+ },
+
+ godot_js_display_vk_hide__sig: 'v',
+ godot_js_display_vk_hide: function () {
+ GodotDisplayVK.hide();
+ },
+
+ godot_js_display_vk_available__sig: 'i',
+ godot_js_display_vk_available: function () {
+ return GodotDisplayVK.available();
+ },
+
+ godot_js_display_vk_cb__sig: 'vi',
+ godot_js_display_vk_cb: function (p_input_cb) {
+ const input_cb = GodotRuntime.get_func(p_input_cb);
+ if (GodotDisplayVK.available()) {
+ GodotDisplayVK.init(input_cb);
+ }
+ },
+
+ /*
* Gamepads
*/
godot_js_display_gamepad_cb__sig: 'vi',
diff --git a/platform/javascript/js/libs/library_godot_os.js b/platform/javascript/js/libs/library_godot_os.js
index 0f189b013c..1d9f889bce 100644
--- a/platform/javascript/js/libs/library_godot_os.js
+++ b/platform/javascript/js/libs/library_godot_os.js
@@ -59,6 +59,8 @@ const GodotConfig = {
canvas: null,
locale: 'en',
canvas_resize_policy: 2, // Adaptive
+ virtual_keyboard: false,
+ persistent_drops: false,
on_execute: null,
on_exit: null,
@@ -66,6 +68,8 @@ const GodotConfig = {
GodotConfig.canvas_resize_policy = p_opts['canvasResizePolicy'];
GodotConfig.canvas = p_opts['canvas'];
GodotConfig.locale = p_opts['locale'] || GodotConfig.locale;
+ GodotConfig.virtual_keyboard = p_opts['virtualKeyboard'];
+ GodotConfig.persistent_drops = !!p_opts['persistentDrops'];
GodotConfig.on_execute = p_opts['onExecute'];
GodotConfig.on_exit = p_opts['onExit'];
},
@@ -77,6 +81,8 @@ const GodotConfig = {
GodotConfig.canvas = null;
GodotConfig.locale = 'en';
GodotConfig.canvas_resize_policy = 2;
+ GodotConfig.virtual_keyboard = false;
+ GodotConfig.persistent_drops = false;
GodotConfig.on_execute = null;
GodotConfig.on_exit = null;
},