diff options
author | bruvzg <7645683+bruvzg@users.noreply.github.com> | 2020-03-26 23:22:04 +0200 |
---|---|---|
committer | bruvzg <7645683+bruvzg@users.noreply.github.com> | 2020-03-26 23:22:04 +0200 |
commit | e1c1bb03ea604f3ef15bcac0cd3aa330acb2f4a8 (patch) | |
tree | 45a92db636baeec353d1995f74fd156509c2f804 /platform/osx | |
parent | 5f1107aa30295e686be6f41cb6d17fc2cff1e036 (diff) |
Prevent recursive `_dispatch_input_event` calls, improve focus regain on window deletion.
Diffstat (limited to 'platform/osx')
-rw-r--r-- | platform/osx/display_server_osx.h | 2 | ||||
-rw-r--r-- | platform/osx/display_server_osx.mm | 88 |
2 files changed, 50 insertions, 40 deletions
diff --git a/platform/osx/display_server_osx.h b/platform/osx/display_server_osx.h index d0e2babd06..33f483bd0e 100644 --- a/platform/osx/display_server_osx.h +++ b/platform/osx/display_server_osx.h @@ -148,6 +148,7 @@ public: void _push_input(const Ref<InputEvent> &p_event); void _process_key_events(); + void _release_pressed_events(); String rendering_driver; @@ -165,6 +166,7 @@ public: bool window_focused; bool drop_events; + bool in_dispatch_input_event = false; public: virtual bool has_feature(Feature p_feature) const; diff --git a/platform/osx/display_server_osx.mm b/platform/osx/display_server_osx.mm index a7099c1207..3bdd12ec9d 100644 --- a/platform/osx/display_server_osx.mm +++ b/platform/osx/display_server_osx.mm @@ -286,8 +286,15 @@ static NSCursor *_cursorFromSelector(SEL selector, SEL fallback = nil) { DS_OSX->window_set_transient(wd.transient_children.front()->get(), DisplayServerOSX::INVALID_WINDOW_ID); } + DS_OSX->windows.erase(window_id); + if (wd.transient_parent != DisplayServerOSX::INVALID_WINDOW_ID) { + DisplayServerOSX::WindowData &pwd = DS_OSX->windows[wd.transient_parent]; + [pwd.window_object makeKeyAndOrderFront:nil]; // Move focus back to parent. DS_OSX->window_set_transient(window_id, DisplayServerOSX::INVALID_WINDOW_ID); + } else if ((window_id != DisplayServerOSX::MAIN_WINDOW_ID) && (DS_OSX->windows.size() == 1)) { + DisplayServerOSX::WindowData &pwd = DS_OSX->windows[DisplayServerOSX::MAIN_WINDOW_ID]; + [pwd.window_object makeKeyAndOrderFront:nil]; // Move focus back to main window if there is no parent or other windows left. } #ifdef VULKAN_ENABLED @@ -295,7 +302,6 @@ static NSCursor *_cursorFromSelector(SEL selector, SEL fallback = nil) { DS_OSX->context_vulkan->window_destroy(window_id); } #endif - DS_OSX->windows.erase(window_id); } - (void)windowDidEnterFullScreen:(NSNotification *)notification { @@ -414,9 +420,7 @@ static NSCursor *_cursorFromSelector(SEL selector, SEL fallback = nil) { } - (void)windowDidMove:(NSNotification *)notification { - if (InputFilter::get_singleton()) { - InputFilter::get_singleton()->release_pressed_events(); - } + DS_OSX->_release_pressed_events(); } - (void)windowDidBecomeKey:(NSNotification *)notification { @@ -437,7 +441,7 @@ static NSCursor *_cursorFromSelector(SEL selector, SEL fallback = nil) { DS_OSX->window_focused = false; - InputFilter::get_singleton()->release_pressed_events(); + DS_OSX->_release_pressed_events(); DS_OSX->_send_window_event(wd, DisplayServerOSX::WINDOW_EVENT_FOCUS_OUT); } @@ -447,7 +451,7 @@ static NSCursor *_cursorFromSelector(SEL selector, SEL fallback = nil) { DS_OSX->window_focused = false; - InputFilter::get_singleton()->release_pressed_events(); + DS_OSX->_release_pressed_events(); DS_OSX->_send_window_event(wd, DisplayServerOSX::WINDOW_EVENT_FOCUS_OUT); } @@ -2139,7 +2143,7 @@ Rect2i DisplayServerOSX::screen_get_usable_rect(int p_screen) const { Point2i position = Point2i(nsrect.origin.x, nsrect.origin.y + nsrect.size.height) * displayScale - _get_screens_origin(); position.y *= -1; - Size2i size = Size2i(nsrect.size.width, nsrect.size.height) * displayScale; + Size2i size = Size2i(nsrect.size.width, nsrect.size.height) / displayScale; return Rect2i(position, size); } @@ -2172,6 +2176,8 @@ DisplayServer::WindowID DisplayServerOSX::create_sub_window(WindowMode p_mode, u } void DisplayServerOSX::_send_window_event(const WindowData &wd, WindowEvent p_event) { + _THREAD_SAFE_METHOD_ + if (!wd.event_callback.is_null()) { Variant event = int(p_event); Variant *eventp = &event; @@ -2222,20 +2228,8 @@ void DisplayServerOSX::delete_sub_window(WindowID p_id) { WindowData &wd = windows[p_id]; - while (wd.transient_children.size()) { - window_set_transient(wd.transient_children.front()->get(), INVALID_WINDOW_ID); - } - - if (wd.transient_parent != INVALID_WINDOW_ID) { - WindowData &pwd = windows[wd.transient_parent]; - [pwd.window_object makeKeyAndOrderFront:nil]; // Move focus back to parent. - window_set_transient(p_id, INVALID_WINDOW_ID); - } - [wd.window_object setContentView:nil]; [wd.window_object close]; - - windows.erase(p_id); } void DisplayServerOSX::window_set_title(const String &p_title, WindowID p_window) { @@ -3011,6 +3005,13 @@ void DisplayServerOSX::_push_input(const Ref<InputEvent> &p_event) { InputFilter::get_singleton()->accumulate_input_event(ev); } +void DisplayServerOSX::_release_pressed_events() { + _THREAD_SAFE_METHOD_ + if (InputFilter::get_singleton()) { + InputFilter::get_singleton()->release_pressed_events(); + } +} + void DisplayServerOSX::_process_key_events() { Ref<InputEventKey> k; for (int i = 0; i < key_event_pos; i++) { @@ -3337,30 +3338,37 @@ void DisplayServerOSX::_dispatch_input_events(const Ref<InputEvent> &p_event) { } void DisplayServerOSX::_dispatch_input_event(const Ref<InputEvent> &p_event) { - Variant ev = p_event; - Variant *evp = &ev; - Variant ret; - Callable::CallError ce; - - Ref<InputEventFromWindow> event_from_window = p_event; - if (event_from_window.is_valid() && event_from_window->get_window_id() != INVALID_WINDOW_ID) { - //send to a window - if (windows.has(event_from_window->get_window_id())) { - Callable callable = windows[event_from_window->get_window_id()].input_event_callback; - if (callable.is_null()) { - return; + _THREAD_SAFE_METHOD_ + if (!in_dispatch_input_event) { + in_dispatch_input_event = true; + + Variant ev = p_event; + Variant *evp = &ev; + Variant ret; + Callable::CallError ce; + + Ref<InputEventFromWindow> event_from_window = p_event; + if (event_from_window.is_valid() && event_from_window->get_window_id() != INVALID_WINDOW_ID) { + //send to a window + if (windows.has(event_from_window->get_window_id())) { + Callable callable = windows[event_from_window->get_window_id()].input_event_callback; + if (callable.is_null()) { + return; + } + callable.call((const Variant **)&evp, 1, ret, ce); } - callable.call((const Variant **)&evp, 1, ret, ce); - } - } else { - //send to all windows - for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) { - Callable callable = E->get().input_event_callback; - if (callable.is_null()) { - continue; + } else { + //send to all windows + for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) { + Callable callable = E->get().input_event_callback; + if (callable.is_null()) { + continue; + } + callable.call((const Variant **)&evp, 1, ret, ce); } - callable.call((const Variant **)&evp, 1, ret, ce); } + + in_dispatch_input_event = false; } } |