diff options
Diffstat (limited to 'platform')
| -rw-r--r-- | platform/android/audio_driver_jandroid.cpp | 2 | ||||
| -rw-r--r-- | platform/android/godot_android.cpp | 2 | ||||
| -rw-r--r-- | platform/android/java_glue.cpp | 2 | ||||
| -rw-r--r-- | platform/javascript/SCsub | 2 | ||||
| -rw-r--r-- | platform/javascript/godot_shell.html | 6 | ||||
| -rw-r--r-- | platform/javascript/os_javascript.cpp | 117 | ||||
| -rw-r--r-- | platform/osx/audio_driver_osx.cpp | 7 | ||||
| -rw-r--r-- | platform/osx/os_osx.mm | 104 | ||||
| -rw-r--r-- | platform/x11/os_x11.cpp | 16 |
9 files changed, 146 insertions, 112 deletions
diff --git a/platform/android/audio_driver_jandroid.cpp b/platform/android/audio_driver_jandroid.cpp index cf1ea169b3..d293f3ed30 100644 --- a/platform/android/audio_driver_jandroid.cpp +++ b/platform/android/audio_driver_jandroid.cpp @@ -29,8 +29,8 @@ /*************************************************************************/ #include "audio_driver_jandroid.h" -#include "project_settings.h" #include "os/os.h" +#include "project_settings.h" #include "thread_jandroid.h" #ifndef ANDROID_NATIVE_ACTIVITY diff --git a/platform/android/godot_android.cpp b/platform/android/godot_android.cpp index 4e4fd8074c..71db03049a 100644 --- a/platform/android/godot_android.cpp +++ b/platform/android/godot_android.cpp @@ -36,9 +36,9 @@ #include <GLES2/gl2.h> #include "file_access_android.h" -#include "project_settings.h" #include "main/main.h" #include "os_android.h" +#include "project_settings.h" #include <android/log.h> #include <android/sensor.h> #include <android/window.h> diff --git a/platform/android/java_glue.cpp b/platform/android/java_glue.cpp index bd234fa4a2..0508989d2f 100644 --- a/platform/android/java_glue.cpp +++ b/platform/android/java_glue.cpp @@ -36,11 +36,11 @@ #include "dir_access_jandroid.h" #include "file_access_android.h" #include "file_access_jandroid.h" -#include "project_settings.h" #include "java_class_wrapper.h" #include "main/input_default.h" #include "main/main.h" #include "os_android.h" +#include "project_settings.h" #include "thread_jandroid.h" #include <unistd.h> diff --git a/platform/javascript/SCsub b/platform/javascript/SCsub index ca9fcb54e4..b804863ee1 100644 --- a/platform/javascript/SCsub +++ b/platform/javascript/SCsub @@ -19,7 +19,7 @@ javascript_objects = [] for x in javascript_files: javascript_objects.append(env_javascript.Object(x)) -env.Append(LINKFLAGS=["-s", "EXPORTED_FUNCTIONS=\"['_main','_audio_server_mix_function','_main_after_fs_sync']\""]) +env.Append(LINKFLAGS=["-s", "EXPORTED_FUNCTIONS=\"['_main','_audio_server_mix_function','_main_after_fs_sync','_send_notification']\""]) env.Append(LINKFLAGS=["--shell-file", '"platform/javascript/godot_shell.html"']) # output file name without file extension diff --git a/platform/javascript/godot_shell.html b/platform/javascript/godot_shell.html index 6c7069a8f0..ee7399a129 100644 --- a/platform/javascript/godot_shell.html +++ b/platform/javascript/godot_shell.html @@ -83,6 +83,10 @@ color: white; } + #canvas:focus { + outline: none; + } + /* Status display * ============== */ @@ -147,7 +151,7 @@ $GODOT_HEAD_INCLUDE </head> <body> <div id="container"> - <canvas id="canvas" width="640" height="480" onclick="canvas.ownerDocument.defaultView.focus();" oncontextmenu="event.preventDefault();"> + <canvas id="canvas" width="640" height="480" tabindex="0" oncontextmenu="event.preventDefault();"> HTML5 canvas appears to be unsupported in the current browser.<br /> Please try updating or use a different browser. </canvas> diff --git a/platform/javascript/os_javascript.cpp b/platform/javascript/os_javascript.cpp index 7dbc178c60..0708d46196 100644 --- a/platform/javascript/os_javascript.cpp +++ b/platform/javascript/os_javascript.cpp @@ -145,6 +145,31 @@ static EM_BOOL _fullscreen_change_callback(int event_type, const EmscriptenFulls static InputDefault *_input; +static bool is_canvas_focused() { + + /* clang-format off */ + return EM_ASM_INT_V( + return document.activeElement == Module.canvas; + ); + /* clang-format on */ +} + +static void focus_canvas() { + + /* clang-format off */ + EM_ASM( + Module.canvas.focus(); + ); + /* clang-format on */ +} + +static bool _cursor_inside_canvas = true; + +static bool is_cursor_inside_canvas() { + + return _cursor_inside_canvas; +} + static EM_BOOL _mousebutton_callback(int event_type, const EmscriptenMouseEvent *mouse_event, void *user_data) { ERR_FAIL_COND_V(event_type != EMSCRIPTEN_EVENT_MOUSEDOWN && event_type != EMSCRIPTEN_EVENT_MOUSEUP, false); @@ -164,26 +189,42 @@ static EM_BOOL _mousebutton_callback(int event_type, const EmscriptenMouseEvent } int mask = _input->get_mouse_button_mask(); - if (ev->is_pressed()) + if (ev->is_pressed()) { + // since the event is consumed, focus manually + if (!is_canvas_focused()) { + focus_canvas(); + } mask |= 1 << ev->get_button_index(); - else + } else if (mask & (1 << ev->get_button_index())) { mask &= ~(1 << ev->get_button_index()); + } else { + // release event, but press was outside the canvas, so ignore + return false; + } ev->set_button_mask(mask >> 1); _input->parse_input_event(ev); + // prevent selection dragging return true; } static EM_BOOL _mousemove_callback(int event_type, const EmscriptenMouseEvent *mouse_event, void *user_data) { ERR_FAIL_COND_V(event_type != EMSCRIPTEN_EVENT_MOUSEMOVE, false); + OS_JavaScript *os = static_cast<OS_JavaScript *>(user_data); + int input_mask = _input->get_mouse_button_mask(); + Point2 pos = Point2(mouse_event->canvasX, mouse_event->canvasY); + // outside the canvas, only read mouse movement if dragging started inside + // the canvas; imitating desktop app behaviour + if (!is_cursor_inside_canvas() && !input_mask) + return false; Ref<InputEventMouseMotion> ev; ev.instance(); dom2godot_mod(mouse_event, ev); - ev->set_button_mask(_input->get_mouse_button_mask() >> 1); + ev->set_button_mask(input_mask >> 1); - ev->set_position(Point2(mouse_event->canvasX, mouse_event->canvasY)); + ev->set_position(pos); ev->set_global_position(ev->get_position()); ev->set_relative(_input->get_mouse_position() - ev->get_position()); @@ -191,12 +232,20 @@ static EM_BOOL _mousemove_callback(int event_type, const EmscriptenMouseEvent *m ev->set_speed(_input->get_last_mouse_speed()); _input->parse_input_event(ev); - return true; + // don't suppress mouseover/leave events + return false; } static EM_BOOL _wheel_callback(int event_type, const EmscriptenWheelEvent *wheel_event, void *user_data) { ERR_FAIL_COND_V(event_type != EMSCRIPTEN_EVENT_WHEEL, false); + if (!is_canvas_focused()) { + if (is_cursor_inside_canvas()) { + focus_canvas(); + } else { + return false; + } + } Ref<InputEventMouseButton> ev; ev.instance(); @@ -387,6 +436,15 @@ static EM_BOOL joy_callback_func(int p_type, const EmscriptenGamepadEvent *p_eve return false; } +extern "C" { +void send_notification(int notif) { + if (notif == MainLoop::NOTIFICATION_WM_MOUSE_ENTER || notif == MainLoop::NOTIFICATION_WM_MOUSE_EXIT) { + _cursor_inside_canvas = notif == MainLoop::NOTIFICATION_WM_MOUSE_ENTER; + } + OS_JavaScript::get_singleton()->get_main_loop()->notification(notif); +} +} + void OS_JavaScript::initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) { print_line("Init OS"); @@ -465,17 +523,17 @@ void OS_JavaScript::initialize(const VideoMode &p_desired, int p_video_driver, i EM_CHECK(ev) EMSCRIPTEN_RESULT result; - SET_EM_CALLBACK("#canvas", mousemove, _mousemove_callback) + SET_EM_CALLBACK("#window", mousemove, _mousemove_callback) SET_EM_CALLBACK("#canvas", mousedown, _mousebutton_callback) - SET_EM_CALLBACK("#canvas", mouseup, _mousebutton_callback) - SET_EM_CALLBACK("#canvas", wheel, _wheel_callback) - SET_EM_CALLBACK("#canvas", touchstart, _touchpress_callback) - SET_EM_CALLBACK("#canvas", touchmove, _touchmove_callback) - SET_EM_CALLBACK("#canvas", touchend, _touchpress_callback) - SET_EM_CALLBACK("#canvas", touchcancel, _touchpress_callback) - SET_EM_CALLBACK(NULL, keydown, _keydown_callback) - SET_EM_CALLBACK(NULL, keypress, _keypress_callback) - SET_EM_CALLBACK(NULL, keyup, _keyup_callback) + SET_EM_CALLBACK("#window", mouseup, _mousebutton_callback) + SET_EM_CALLBACK("#window", wheel, _wheel_callback) + SET_EM_CALLBACK("#window", touchstart, _touchpress_callback) + SET_EM_CALLBACK("#window", touchmove, _touchmove_callback) + SET_EM_CALLBACK("#window", touchend, _touchpress_callback) + SET_EM_CALLBACK("#window", touchcancel, _touchpress_callback) + SET_EM_CALLBACK("#canvas", keydown, _keydown_callback) + SET_EM_CALLBACK("#canvas", keypress, _keypress_callback) + SET_EM_CALLBACK("#canvas", keyup, _keyup_callback) SET_EM_CALLBACK(NULL, resize, _browser_resize_callback) SET_EM_CALLBACK(NULL, fullscreenchange, _fullscreen_change_callback) SET_EM_CALLBACK_NODATA(gamepadconnected, joy_callback_func) @@ -485,6 +543,21 @@ void OS_JavaScript::initialize(const VideoMode &p_desired, int p_video_driver, i #undef SET_EM_CALLBACK #undef EM_CHECK + /* clang-format off */ + EM_ASM_ARGS({ + const send_notification = Module.cwrap('send_notification', null, ['number']); + const notifs = arguments; + (['mouseover', 'mouseleave', 'focus', 'blur']).forEach(function(event, i) { + Module.canvas.addEventListener(event, send_notification.bind(this, notifs[i])); + }); + }, + MainLoop::NOTIFICATION_WM_MOUSE_ENTER, + MainLoop::NOTIFICATION_WM_MOUSE_EXIT, + MainLoop::NOTIFICATION_WM_FOCUS_IN, + MainLoop::NOTIFICATION_WM_FOCUS_OUT + ); +/* clang-format on */ + #ifdef JAVASCRIPT_EVAL_ENABLED javascript_eval = memnew(JavaScript); ProjectSettings::get_singleton()->add_singleton(ProjectSettings::Singleton("JavaScript", javascript_eval)); @@ -777,20 +850,6 @@ void OS_JavaScript::main_loop_end() { main_loop->finish(); } -void OS_JavaScript::main_loop_focusout() { - - if (main_loop) - main_loop->notification(MainLoop::NOTIFICATION_WM_FOCUS_OUT); - //audio_driver_javascript.set_pause(true); -} - -void OS_JavaScript::main_loop_focusin() { - - if (main_loop) - main_loop->notification(MainLoop::NOTIFICATION_WM_FOCUS_IN); - //audio_driver_javascript.set_pause(false); -} - void OS_JavaScript::process_accelerometer(const Vector3 &p_accelerometer) { input->set_accelerometer(p_accelerometer); diff --git a/platform/osx/audio_driver_osx.cpp b/platform/osx/audio_driver_osx.cpp index a4233b5264..dabc7989c0 100644 --- a/platform/osx/audio_driver_osx.cpp +++ b/platform/osx/audio_driver_osx.cpp @@ -60,13 +60,14 @@ Error AudioDriverOSX::initDevice() { zeromem(&desc, sizeof(desc)); desc.componentType = kAudioUnitType_Output; - desc.componentSubType = 0; /* !!! FIXME: ? */ - comp = AudioComponentFindNext(NULL, &desc); + desc.componentSubType = kAudioUnitSubType_HALOutput; desc.componentManufacturer = kAudioUnitManufacturer_Apple; + comp = AudioComponentFindNext(NULL, &desc); + ERR_FAIL_COND_V(comp == NULL, FAILED); + result = AudioComponentInstanceNew(comp, &audio_unit); ERR_FAIL_COND_V(result != noErr, FAILED); - ERR_FAIL_COND_V(comp == NULL, FAILED); result = AudioUnitSetProperty(audio_unit, kAudioUnitProperty_StreamFormat, scope, bus, &strdesc, sizeof(strdesc)); ERR_FAIL_COND_V(result != noErr, FAILED); diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm index 9f9c785a2a..82c1313326 100644 --- a/platform/osx/os_osx.mm +++ b/platform/osx/os_osx.mm @@ -80,6 +80,7 @@ static int mouse_y = 0; static int prev_mouse_x = 0; static int prev_mouse_y = 0; static int button_mask = 0; +static bool mouse_down_control = false; @interface GodotApplication : NSApplication @end @@ -285,41 +286,48 @@ static int button_mask = 0; //setModeCursor(window, window->cursorMode); } -- (void)mouseDown:(NSEvent *)event { - - button_mask |= BUTTON_MASK_LEFT; +static void _mouseDownEvent(NSEvent *event, int index, int mask, bool pressed) { + if (pressed) { + button_mask |= mask; + } else { + button_mask &= ~mask; + } Ref<InputEventMouseButton> mb; mb.instance(); get_key_modifier_state([event modifierFlags], mb); - mb->set_button_index(BUTTON_LEFT); - mb->set_pressed(true); + mb->set_button_index(index); + mb->set_pressed(pressed); mb->set_position(Vector2(mouse_x, mouse_y)); mb->set_global_position(Vector2(mouse_x, mouse_y)); mb->set_button_mask(button_mask); - mb->set_doubleclick([event clickCount] == 2); + if (index == BUTTON_LEFT && pressed) { + mb->set_doubleclick([event clickCount] == 2); + } OS_OSX::singleton->push_input(mb); } +- (void)mouseDown:(NSEvent *)event { + if (([event modifierFlags] & NSControlKeyMask)) { + mouse_down_control = true; + _mouseDownEvent(event, BUTTON_RIGHT, BUTTON_MASK_RIGHT, true); + } else { + mouse_down_control = false; + _mouseDownEvent(event, BUTTON_LEFT, BUTTON_MASK_LEFT, true); + } +} + - (void)mouseDragged:(NSEvent *)event { [self mouseMoved:event]; } - (void)mouseUp:(NSEvent *)event { - - button_mask &= ~BUTTON_MASK_LEFT; - Ref<InputEventMouseButton> mb; - mb.instance(); - - get_key_modifier_state([event modifierFlags], mb); - mb->set_button_index(BUTTON_LEFT); - mb->set_pressed(false); - mb->set_position(Vector2(mouse_x, mouse_y)); - mb->set_global_position(Vector2(mouse_x, mouse_y)); - mb->set_button_mask(button_mask); - mb->set_doubleclick([event clickCount] == 2); - OS_OSX::singleton->push_input(mb); + if (mouse_down_control) { + _mouseDownEvent(event, BUTTON_RIGHT, BUTTON_MASK_RIGHT, false); + } else { + _mouseDownEvent(event, BUTTON_LEFT, BUTTON_MASK_LEFT, false); + } } - (void)mouseMoved:(NSEvent *)event { @@ -347,20 +355,7 @@ static int button_mask = 0; } - (void)rightMouseDown:(NSEvent *)event { - - button_mask |= BUTTON_MASK_RIGHT; - - Ref<InputEventMouseButton> mb; - mb.instance(); - - get_key_modifier_state([event modifierFlags], mb); - mb->set_button_index(BUTTON_RIGHT); - mb->set_pressed(true); - mb->set_position(Vector2(mouse_x, mouse_y)); - mb->set_global_position(Vector2(mouse_x, mouse_y)); - mb->set_button_mask(button_mask); - mb->set_doubleclick([event clickCount] == 2); - OS_OSX::singleton->push_input(mb); + _mouseDownEvent(event, BUTTON_RIGHT, BUTTON_MASK_RIGHT, true); } - (void)rightMouseDragged:(NSEvent *)event { @@ -368,20 +363,7 @@ static int button_mask = 0; } - (void)rightMouseUp:(NSEvent *)event { - - button_mask &= ~BUTTON_MASK_RIGHT; - - Ref<InputEventMouseButton> mb; - mb.instance(); - - get_key_modifier_state([event modifierFlags], mb); - mb->set_button_index(BUTTON_RIGHT); - mb->set_pressed(false); - mb->set_position(Vector2(mouse_x, mouse_y)); - mb->set_global_position(Vector2(mouse_x, mouse_y)); - mb->set_button_mask(button_mask); - mb->set_doubleclick([event clickCount] == 2); - OS_OSX::singleton->push_input(mb); + _mouseDownEvent(event, BUTTON_RIGHT, BUTTON_MASK_RIGHT, false); } - (void)otherMouseDown:(NSEvent *)event { @@ -389,19 +371,7 @@ static int button_mask = 0; if ((int)[event buttonNumber] != 2) return; - button_mask |= BUTTON_MASK_MIDDLE; - - Ref<InputEventMouseButton> mb; - mb.instance(); - - get_key_modifier_state([event modifierFlags], mb); - mb->set_button_index(BUTTON_MIDDLE); - mb->set_pressed(true); - mb->set_position(Vector2(mouse_x, mouse_y)); - mb->set_global_position(Vector2(mouse_x, mouse_y)); - mb->set_button_mask(button_mask); - mb->set_doubleclick([event clickCount] == 2); - OS_OSX::singleton->push_input(mb); + _mouseDownEvent(event, BUTTON_MIDDLE, BUTTON_MASK_MIDDLE, true); } - (void)otherMouseDragged:(NSEvent *)event { @@ -413,19 +383,7 @@ static int button_mask = 0; if ((int)[event buttonNumber] != 2) return; - button_mask &= ~BUTTON_MASK_MIDDLE; - - Ref<InputEventMouseButton> mb; - mb.instance(); - - get_key_modifier_state([event modifierFlags], mb); - mb->set_button_index(BUTTON_MIDDLE); - mb->set_pressed(false); - mb->set_position(Vector2(mouse_x, mouse_y)); - mb->set_global_position(Vector2(mouse_x, mouse_y)); - mb->set_button_mask(button_mask); - mb->set_doubleclick([event clickCount] == 2); - OS_OSX::singleton->push_input(mb); + _mouseDownEvent(event, BUTTON_MIDDLE, BUTTON_MASK_MIDDLE, false); } - (void)mouseExited:(NSEvent *)event { diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index 3143f30f77..5bfe31b8c2 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -1858,7 +1858,7 @@ void OS_X11::set_clipboard(const String &p_text) { XSetSelectionOwner(x11_display, XInternAtom(x11_display, "CLIPBOARD", 0), x11_window, CurrentTime); }; -static String _get_clipboard(Atom p_source, Window x11_window, ::Display *x11_display, String p_internal_clipboard) { +static String _get_clipboard_impl(Atom p_source, Window x11_window, ::Display *x11_display, String p_internal_clipboard, Atom target) { String ret; @@ -1875,7 +1875,7 @@ static String _get_clipboard(Atom p_source, Window x11_window, ::Display *x11_di }; if (Sown != None) { - XConvertSelection(x11_display, p_source, XA_STRING, selection, + XConvertSelection(x11_display, p_source, target, selection, x11_window, CurrentTime); XFlush(x11_display); while (true) { @@ -1915,6 +1915,18 @@ static String _get_clipboard(Atom p_source, Window x11_window, ::Display *x11_di return ret; } +static String _get_clipboard(Atom p_source, Window x11_window, ::Display *x11_display, String p_internal_clipboard) { + String ret; + Atom utf8_atom = XInternAtom(x11_display, "UTF8_STRING", True); + if (utf8_atom != None) { + ret = _get_clipboard_impl(p_source, x11_window, x11_display, p_internal_clipboard, utf8_atom); + } + if (ret == "") { + ret = _get_clipboard_impl(p_source, x11_window, x11_display, p_internal_clipboard, XA_STRING); + } + return ret; +} + String OS_X11::get_clipboard() const { String ret; |