diff options
Diffstat (limited to 'platform')
-rw-r--r-- | platform/android/export/export.cpp | 2 | ||||
-rw-r--r-- | platform/iphone/export/export.cpp | 2 | ||||
-rw-r--r-- | platform/iphone/icloud.mm | 2 | ||||
-rw-r--r-- | platform/javascript/os_javascript.cpp | 48 | ||||
-rw-r--r-- | platform/javascript/os_javascript.h | 3 | ||||
-rw-r--r-- | platform/osx/os_osx.h | 1 | ||||
-rw-r--r-- | platform/osx/os_osx.mm | 128 | ||||
-rw-r--r-- | platform/server/detect.py | 6 | ||||
-rw-r--r-- | platform/uwp/export/export.cpp | 4 | ||||
-rw-r--r-- | platform/x11/detect.py | 6 | ||||
-rw-r--r-- | platform/x11/os_x11.cpp | 29 |
11 files changed, 176 insertions, 55 deletions
diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp index b987b3aebd..30267aa968 100644 --- a/platform/android/export/export.cpp +++ b/platform/android/export/export.cpp @@ -790,7 +790,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { if (tname == "manifest" && attrname == "versionName") { if (attr_value == 0xFFFFFFFF) { - WARN_PRINT("Version name in a resource, should be plaintext") + WARN_PRINT("Version name in a resource, should be plain text"); } else string_table.write[attr_value] = version_name; } diff --git a/platform/iphone/export/export.cpp b/platform/iphone/export/export.cpp index ba405ab7ae..7ca83320d0 100644 --- a/platform/iphone/export/export.cpp +++ b/platform/iphone/export/export.cpp @@ -914,7 +914,7 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p }; DirAccess *tmp_app_path = DirAccess::create_for_path(dest_dir); - ERR_FAIL_COND_V(!tmp_app_path, ERR_CANT_CREATE) + ERR_FAIL_COND_V(!tmp_app_path, ERR_CANT_CREATE); print_line("Unzipping..."); FileAccess *src_f = NULL; diff --git a/platform/iphone/icloud.mm b/platform/iphone/icloud.mm index e32618e8f6..c60db3d661 100644 --- a/platform/iphone/icloud.mm +++ b/platform/iphone/icloud.mm @@ -138,7 +138,7 @@ Variant nsobject_to_variant(NSObject *object) { //this is a type that icloud supports...but how did you submit it in the first place? //I guess this is a type that *might* show up, if you were, say, trying to make your game //compatible with existing cloud data written by another engine's version of your game - WARN_PRINT("NSDate unsupported, returning null Variant") + WARN_PRINT("NSDate unsupported, returning null Variant"); return Variant(); } else if ([object isKindOfClass:[NSNull class]] or object == nil) { return Variant(); diff --git a/platform/javascript/os_javascript.cpp b/platform/javascript/os_javascript.cpp index c69e6f0cb8..e7981bf576 100644 --- a/platform/javascript/os_javascript.cpp +++ b/platform/javascript/os_javascript.cpp @@ -795,6 +795,47 @@ const char *OS_JavaScript::get_audio_driver_name(int p_driver) const { return "JavaScript"; } +// Clipboard +extern "C" EMSCRIPTEN_KEEPALIVE void update_clipboard(const char *p_text) { + // Only call set_clipboard from OS (sets local clipboard) + OS::get_singleton()->OS::set_clipboard(p_text); +} + +void OS_JavaScript::set_clipboard(const String &p_text) { + OS::set_clipboard(p_text); + /* clang-format off */ + int err = EM_ASM_INT({ + var text = UTF8ToString($0); + if (!navigator.clipboard || !navigator.clipboard.writeText) + return 1; + navigator.clipboard.writeText(text).catch(e => { + // Setting OS clipboard is only possible from an input callback. + console.error("Setting OS clipboard is only possible from an input callback for the HTML5 plafrom. Exception:", e); + }); + return 0; + }, p_text.utf8().get_data()); + /* clang-format on */ + ERR_EXPLAIN("Clipboard API is not supported."); + ERR_FAIL_COND(err); +} + +String OS_JavaScript::get_clipboard() const { + /* clang-format off */ + EM_ASM({ + try { + navigator.clipboard.readText().then(function (result) { + ccall('update_clipboard', 'void', ['string'], [result]); + }).catch(function (e) { + // Fail graciously. + }); + } catch (e) { + // Fail graciously. + } + }); + /* clang-format on */ + return this->OS::get_clipboard(); +} + // Lifecycle int OS_JavaScript::get_current_video_driver() const { return video_driver_index; @@ -939,6 +980,11 @@ Error OS_JavaScript::initialize(const VideoMode &p_desired, int p_video_driver, (['mouseover', 'mouseleave', 'focus', 'blur']).forEach(function(event, index) { Module.canvas.addEventListener(event, send_notification.bind(null, notifications[index])); }); + // Clipboard + const update_clipboard = cwrap('update_clipboard', null, ['string']); + window.addEventListener('paste', function(evt) { + update_clipboard(evt.clipboardData.getData('text')); + }, true); }, MainLoop::NOTIFICATION_WM_MOUSE_ENTER, MainLoop::NOTIFICATION_WM_MOUSE_EXIT, @@ -1098,7 +1144,7 @@ void OS_JavaScript::set_icon(const Ref<Image> &p_icon) { Ref<Image> icon = p_icon; if (icon->is_compressed()) { icon = icon->duplicate(); - ERR_FAIL_COND(icon->decompress() != OK) + ERR_FAIL_COND(icon->decompress() != OK); } if (icon->get_format() != Image::FORMAT_RGBA8) { if (icon == p_icon) diff --git a/platform/javascript/os_javascript.h b/platform/javascript/os_javascript.h index a0c7c31f2d..27b23a4673 100644 --- a/platform/javascript/os_javascript.h +++ b/platform/javascript/os_javascript.h @@ -133,6 +133,9 @@ public: virtual int get_audio_driver_count() const; virtual const char *get_audio_driver_name(int p_driver) const; + virtual void set_clipboard(const String &p_text); + virtual String get_clipboard() const; + virtual MainLoop *get_main_loop() const; void run_async(); bool main_loop_iterate(); diff --git a/platform/osx/os_osx.h b/platform/osx/os_osx.h index 212966af11..eed230ba89 100644 --- a/platform/osx/os_osx.h +++ b/platform/osx/os_osx.h @@ -60,6 +60,7 @@ public: unsigned int osx_state; bool pressed; bool echo; + bool raw; uint32_t scancode; uint32_t unicode; }; diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm index 113c6636f0..567d24de3e 100644 --- a/platform/osx/os_osx.mm +++ b/platform/osx/os_osx.mm @@ -392,7 +392,7 @@ static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeSt @interface GodotContentView : NSView <NSTextInputClient> { NSTrackingArea *trackingArea; NSMutableAttributedString *markedText; - bool imeMode; + bool imeInputEventInProgress; } - (void)cancelComposition; - (BOOL)wantsUpdateLayer; @@ -418,7 +418,7 @@ static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeSt - (id)init { self = [super init]; trackingArea = nil; - imeMode = false; + imeInputEventInProgress = false; [self updateTrackingAreas]; [self registerForDraggedTypes:[NSArray arrayWithObject:NSFilenamesPboardType]]; markedText = [[NSMutableAttributedString alloc] init]; @@ -452,7 +452,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 }; [markedText initWithString:aString]; } if (OS_OSX::singleton->im_active) { - imeMode = true; + imeInputEventInProgress = true; OS_OSX::singleton->im_text.parse_utf8([[markedText mutableString] UTF8String]); OS_OSX::singleton->im_selection = Point2(selectedRange.location, selectedRange.length); @@ -467,7 +467,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 }; } - (void)unmarkText { - imeMode = false; + imeInputEventInProgress = false; [[markedText mutableString] setString:@""]; if (OS_OSX::singleton->im_active) { OS_OSX::singleton->im_text = String(); @@ -540,6 +540,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 }; ke.osx_state = [event modifierFlags]; ke.pressed = true; ke.echo = false; + ke.raw = false; // IME input event ke.scancode = 0; ke.unicode = codepoint; @@ -1045,29 +1046,52 @@ static int remapKey(unsigned int key) { - (void)keyDown:(NSEvent *)event { - //disable raw input in IME mode - if (!imeMode) { - OS_OSX::KeyEvent ke; + // Ignore all input if IME input is in progress + if (!imeInputEventInProgress) { + NSString *characters = [event characters]; + NSUInteger length = [characters length]; - ke.osx_state = [event modifierFlags]; - ke.pressed = true; - ke.echo = [event isARepeat]; - ke.scancode = remapKey([event keyCode]); - ke.unicode = 0; + if (!OS_OSX::singleton->im_active && length > 0 && keycode_has_unicode(remapKey([event keyCode]))) { + // Fallback unicode character handler used if IME is not active + for (NSUInteger i = 0; i < length; i++) { + OS_OSX::KeyEvent ke; - push_to_key_event_buffer(ke); + ke.osx_state = [event modifierFlags]; + ke.pressed = true; + ke.echo = [event isARepeat]; + ke.scancode = remapKey([event keyCode]); + ke.raw = true; + ke.unicode = [characters characterAtIndex:i]; + + push_to_key_event_buffer(ke); + } + } else { + OS_OSX::KeyEvent ke; + + ke.osx_state = [event modifierFlags]; + ke.pressed = true; + ke.echo = [event isARepeat]; + ke.scancode = remapKey([event keyCode]); + ke.raw = false; + ke.unicode = 0; + + push_to_key_event_buffer(ke); + } } - if (OS_OSX::singleton->im_active == true) + // Pass events to IME handler + if (OS_OSX::singleton->im_active) [self interpretKeyEvents:[NSArray arrayWithObject:event]]; } - (void)flagsChanged:(NSEvent *)event { - if (!imeMode) { + // Ignore all input if IME input is in progress + if (!imeInputEventInProgress) { OS_OSX::KeyEvent ke; ke.echo = false; + ke.raw = true; int key = [event keyCode]; int mod = [event modifierFlags]; @@ -1114,17 +1138,37 @@ static int remapKey(unsigned int key) { - (void)keyUp:(NSEvent *)event { - if (!imeMode) { + // Ignore all input if IME input is in progress + if (!imeInputEventInProgress) { + NSString *characters = [event characters]; + NSUInteger length = [characters length]; - OS_OSX::KeyEvent ke; + // Fallback unicode character handler used if IME is not active + if (!OS_OSX::singleton->im_active && length > 0 && keycode_has_unicode(remapKey([event keyCode]))) { + for (NSUInteger i = 0; i < length; i++) { + OS_OSX::KeyEvent ke; - ke.osx_state = [event modifierFlags]; - ke.pressed = false; - ke.echo = false; - ke.scancode = remapKey([event keyCode]); - ke.unicode = 0; + ke.osx_state = [event modifierFlags]; + ke.pressed = false; + ke.echo = [event isARepeat]; + ke.scancode = remapKey([event keyCode]); + ke.raw = true; + ke.unicode = [characters characterAtIndex:i]; - push_to_key_event_buffer(ke); + push_to_key_event_buffer(ke); + } + } else { + OS_OSX::KeyEvent ke; + + ke.osx_state = [event modifierFlags]; + ke.pressed = false; + ke.echo = [event isARepeat]; + ke.scancode = remapKey([event keyCode]); + ke.raw = true; + ke.unicode = 0; + + push_to_key_event_buffer(ke); + } } } @@ -2612,30 +2656,44 @@ void OS_OSX::process_key_events() { const KeyEvent &ke = key_event_buffer[i]; - if ((i == 0 && ke.scancode == 0) || (i > 0 && key_event_buffer[i - 1].scancode == 0)) { + if (ke.raw) { + // Non IME input - no composite characters, pass events as is k.instance(); get_key_modifier_state(ke.osx_state, k); k->set_pressed(ke.pressed); k->set_echo(ke.echo); - k->set_scancode(0); + k->set_scancode(ke.scancode); k->set_unicode(ke.unicode); push_input(k); - } - if (ke.scancode != 0) { - k.instance(); + } else { + // IME input + if ((i == 0 && ke.scancode == 0) || (i > 0 && key_event_buffer[i - 1].scancode == 0)) { + k.instance(); - get_key_modifier_state(ke.osx_state, k); - k->set_pressed(ke.pressed); - k->set_echo(ke.echo); - k->set_scancode(ke.scancode); + get_key_modifier_state(ke.osx_state, k); + k->set_pressed(ke.pressed); + k->set_echo(ke.echo); + k->set_scancode(0); + k->set_unicode(ke.unicode); - if (i + 1 < key_event_pos && key_event_buffer[i + 1].scancode == 0) { - k->set_unicode(key_event_buffer[i + 1].unicode); + push_input(k); } + if (ke.scancode != 0) { + k.instance(); - push_input(k); + get_key_modifier_state(ke.osx_state, k); + k->set_pressed(ke.pressed); + k->set_echo(ke.echo); + k->set_scancode(ke.scancode); + + if (i + 1 < key_event_pos && key_event_buffer[i + 1].scancode == 0) { + k->set_unicode(key_event_buffer[i + 1].unicode); + } + + push_input(k); + } } } diff --git a/platform/server/detect.py b/platform/server/detect.py index 08c2eb6aaf..a5648d8d9d 100644 --- a/platform/server/detect.py +++ b/platform/server/detect.py @@ -145,12 +145,12 @@ def configure(env): env.ParseConfig('pkg-config libpng --cflags --libs') if not env['builtin_bullet']: - # We need at least version 2.88 + # We need at least version 2.89 import subprocess bullet_version = subprocess.check_output(['pkg-config', 'bullet', '--modversion']).strip() - if str(bullet_version) < "2.88": + if str(bullet_version) < "2.89": # Abort as system bullet was requested but too old - print("Bullet: System version {0} does not match minimal requirements ({1}). Aborting.".format(bullet_version, "2.88")) + print("Bullet: System version {0} does not match minimal requirements ({1}). Aborting.".format(bullet_version, "2.89")) sys.exit(255) env.ParseConfig('pkg-config bullet --cflags --libs') diff --git a/platform/uwp/export/export.cpp b/platform/uwp/export/export.cpp index cdcad33f6d..ec43a4c26f 100644 --- a/platform/uwp/export/export.cpp +++ b/platform/uwp/export/export.cpp @@ -241,7 +241,6 @@ void AppxPackager::make_block_map() { tmp_file->close(); memdelete(tmp_file); - tmp_file = NULL; } String AppxPackager::content_type(String p_extension) { @@ -291,7 +290,6 @@ void AppxPackager::make_content_types() { tmp_file->close(); memdelete(tmp_file); - tmp_file = NULL; } Vector<uint8_t> AppxPackager::make_file_header(FileMeta p_file_meta) { @@ -606,7 +604,6 @@ void AppxPackager::finish() { blockmap_file->close(); memdelete(blockmap_file); - blockmap_file = NULL; // Add content types EditorNode::progress_task_step("export", "Setting content types...", 5); @@ -622,7 +619,6 @@ void AppxPackager::finish() { types_file->close(); memdelete(types_file); - types_file = NULL; // Pre-process central directory before signing for (int i = 0; i < file_metadata.size(); i++) { diff --git a/platform/x11/detect.py b/platform/x11/detect.py index 933ee6b72e..a502308eee 100644 --- a/platform/x11/detect.py +++ b/platform/x11/detect.py @@ -219,12 +219,12 @@ def configure(env): env.ParseConfig('pkg-config libpng --cflags --libs') if not env['builtin_bullet']: - # We need at least version 2.88 + # We need at least version 2.89 import subprocess bullet_version = subprocess.check_output(['pkg-config', 'bullet', '--modversion']).strip() - if str(bullet_version) < "2.88": + if str(bullet_version) < "2.89": # Abort as system bullet was requested but too old - print("Bullet: System version {0} does not match minimal requirements ({1}). Aborting.".format(bullet_version, "2.88")) + print("Bullet: System version {0} does not match minimal requirements ({1}). Aborting.".format(bullet_version, "2.89")) sys.exit(255) env.ParseConfig('pkg-config bullet --cflags --libs') diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index f034b2389b..494ae41220 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -1017,12 +1017,12 @@ void OS_X11::set_wm_fullscreen(bool p_enabled) { XFree(xsh); } - if (!p_enabled && !get_borderless_window()) { - // put decorations back if the window wasn't suppoesed to be borderless + if (!p_enabled) { + // put back or remove decorations according to the last set borderless state Hints hints; Atom property; hints.flags = 2; - hints.decorations = 1; + hints.decorations = current_videomode.borderless_window ? 0 : 1; property = XInternAtom(x11_display, "_MOTIF_WM_HINTS", True); XChangeProperty(x11_display, x11_window, property, property, 32, PropModeReplace, (unsigned char *)&hints, 5); } @@ -1531,7 +1531,7 @@ bool OS_X11::is_window_always_on_top() const { void OS_X11::set_borderless_window(bool p_borderless) { - if (current_videomode.borderless_window == p_borderless) + if (get_borderless_window() == p_borderless) return; if (!p_borderless && layered_window) @@ -1551,7 +1551,24 @@ void OS_X11::set_borderless_window(bool p_borderless) { } bool OS_X11::get_borderless_window() { - return current_videomode.borderless_window; + + bool borderless = current_videomode.borderless_window; + Atom prop = XInternAtom(x11_display, "_MOTIF_WM_HINTS", True); + if (prop != None) { + + Atom type; + int format; + unsigned long len; + unsigned long remaining; + unsigned char *data = NULL; + if (XGetWindowProperty(x11_display, x11_window, prop, 0, sizeof(Hints), False, AnyPropertyType, &type, &format, &len, &remaining, &data) == Success) { + if (data && (format == 32) && (len >= 5)) { + borderless = !((Hints *)data)->decorations; + } + XFree(data); + } + } + return borderless; } void OS_X11::request_attention() { @@ -2378,7 +2395,7 @@ void OS_X11::process_xevents() { Vector<String> files = String((char *)p.data).split("\n", false); for (int i = 0; i < files.size(); i++) { - files.write[i] = files[i].replace("file://", "").http_unescape().strip_escapes(); + files.write[i] = files[i].replace("file://", "").http_unescape().strip_edges(); } main_loop->drop_files(files); |