diff options
author | bruvzg <7645683+bruvzg@users.noreply.github.com> | 2023-06-15 10:53:31 +0300 |
---|---|---|
committer | bruvzg <7645683+bruvzg@users.noreply.github.com> | 2023-06-16 10:27:52 +0300 |
commit | 28db3c715862cd25e92a4063d95ef115255cf604 (patch) | |
tree | bb1ed3f826cf2c5b7b00f4a381b683f13d4bd735 | |
parent | 9c41c4ecb6d122792fae2060e2a411ecf6812add (diff) | |
download | redot-engine-28db3c715862cd25e92a4063d95ef115255cf604.tar.gz |
[DisplayServer] Add method to check if native window is focused.
-rw-r--r-- | doc/classes/DisplayServer.xml | 7 | ||||
-rw-r--r-- | platform/android/display_server_android.cpp | 4 | ||||
-rw-r--r-- | platform/android/display_server_android.h | 1 | ||||
-rw-r--r-- | platform/ios/display_server_ios.h | 1 | ||||
-rw-r--r-- | platform/ios/display_server_ios.mm | 4 | ||||
-rw-r--r-- | platform/linuxbsd/x11/display_server_x11.cpp | 9 | ||||
-rw-r--r-- | platform/linuxbsd/x11/display_server_x11.h | 1 | ||||
-rw-r--r-- | platform/macos/display_server_macos.h | 2 | ||||
-rw-r--r-- | platform/macos/display_server_macos.mm | 9 | ||||
-rw-r--r-- | platform/macos/godot_window_delegate.mm | 11 | ||||
-rw-r--r-- | platform/web/display_server_web.cpp | 4 | ||||
-rw-r--r-- | platform/web/display_server_web.h | 1 | ||||
-rw-r--r-- | platform/windows/display_server_windows.cpp | 9 | ||||
-rw-r--r-- | platform/windows/display_server_windows.h | 1 | ||||
-rw-r--r-- | scene/main/window.cpp | 8 | ||||
-rw-r--r-- | servers/display_server.cpp | 1 | ||||
-rw-r--r-- | servers/display_server.h | 1 | ||||
-rw-r--r-- | servers/display_server_headless.h | 1 |
18 files changed, 71 insertions, 4 deletions
diff --git a/doc/classes/DisplayServer.xml b/doc/classes/DisplayServer.xml index cd39543c45..194fc8a503 100644 --- a/doc/classes/DisplayServer.xml +++ b/doc/classes/DisplayServer.xml @@ -1258,6 +1258,13 @@ Returns the V-Sync mode of the given window. </description> </method> + <method name="window_is_focused" qualifiers="const"> + <return type="bool" /> + <param index="0" name="window_id" type="int" default="0" /> + <description> + Returns [code]true[/code] if the window specified by [param window_id] is focused. + </description> + </method> <method name="window_is_maximize_allowed" qualifiers="const"> <return type="bool" /> <param index="0" name="window_id" type="int" default="0" /> diff --git a/platform/android/display_server_android.cpp b/platform/android/display_server_android.cpp index 4d9a49c35c..f02b292868 100644 --- a/platform/android/display_server_android.cpp +++ b/platform/android/display_server_android.cpp @@ -453,6 +453,10 @@ void DisplayServerAndroid::window_move_to_foreground(DisplayServer::WindowID p_w // Not supported on Android. } +bool DisplayServerAndroid::window_is_focused(WindowID p_window) const { + return true; +} + bool DisplayServerAndroid::window_can_draw(DisplayServer::WindowID p_window) const { return true; } diff --git a/platform/android/display_server_android.h b/platform/android/display_server_android.h index ad1cbddb08..e0ad2cb916 100644 --- a/platform/android/display_server_android.h +++ b/platform/android/display_server_android.h @@ -178,6 +178,7 @@ public: virtual void window_request_attention(WindowID p_window = MAIN_WINDOW_ID) override; virtual void window_move_to_foreground(WindowID p_window = MAIN_WINDOW_ID) override; + virtual bool window_is_focused(WindowID p_window = MAIN_WINDOW_ID) const override; virtual bool window_can_draw(WindowID p_window = MAIN_WINDOW_ID) const override; diff --git a/platform/ios/display_server_ios.h b/platform/ios/display_server_ios.h index b29bdeec62..da16449c61 100644 --- a/platform/ios/display_server_ios.h +++ b/platform/ios/display_server_ios.h @@ -193,6 +193,7 @@ public: virtual void window_request_attention(WindowID p_window = MAIN_WINDOW_ID) override; virtual void window_move_to_foreground(WindowID p_window = MAIN_WINDOW_ID) override; + virtual bool window_is_focused(WindowID p_window = MAIN_WINDOW_ID) const override; virtual float screen_get_max_scale() const override; diff --git a/platform/ios/display_server_ios.mm b/platform/ios/display_server_ios.mm index bfb09b6861..7d91274a0c 100644 --- a/platform/ios/display_server_ios.mm +++ b/platform/ios/display_server_ios.mm @@ -562,6 +562,10 @@ void DisplayServerIOS::window_move_to_foreground(WindowID p_window) { // Probably not supported for iOS } +bool DisplayServerIOS::window_is_focused(WindowID p_window) const { + return true; +} + float DisplayServerIOS::screen_get_max_scale() const { return screen_get_scale(SCREEN_OF_MAIN_WINDOW); } diff --git a/platform/linuxbsd/x11/display_server_x11.cpp b/platform/linuxbsd/x11/display_server_x11.cpp index 83b6fb7628..a607e26ac5 100644 --- a/platform/linuxbsd/x11/display_server_x11.cpp +++ b/platform/linuxbsd/x11/display_server_x11.cpp @@ -2626,6 +2626,15 @@ void DisplayServerX11::window_move_to_foreground(WindowID p_window) { XFlush(x11_display); } +bool DisplayServerX11::window_is_focused(WindowID p_window) const { + _THREAD_SAFE_METHOD_ + + ERR_FAIL_COND_V(!windows.has(p_window), false); + const WindowData &wd = windows[p_window]; + + return wd.focused; +} + bool DisplayServerX11::window_can_draw(WindowID p_window) const { //this seems to be all that is provided by X11 return window_get_mode(p_window) != WINDOW_MODE_MINIMIZED; diff --git a/platform/linuxbsd/x11/display_server_x11.h b/platform/linuxbsd/x11/display_server_x11.h index 176a1ffb9a..180362923b 100644 --- a/platform/linuxbsd/x11/display_server_x11.h +++ b/platform/linuxbsd/x11/display_server_x11.h @@ -477,6 +477,7 @@ public: virtual void window_request_attention(WindowID p_window = MAIN_WINDOW_ID) override; virtual void window_move_to_foreground(WindowID p_window = MAIN_WINDOW_ID) override; + virtual bool window_is_focused(WindowID p_window = MAIN_WINDOW_ID) const override; virtual bool window_can_draw(WindowID p_window = MAIN_WINDOW_ID) const override; diff --git a/platform/macos/display_server_macos.h b/platform/macos/display_server_macos.h index 5944cc8abd..93fa93b259 100644 --- a/platform/macos/display_server_macos.h +++ b/platform/macos/display_server_macos.h @@ -117,6 +117,7 @@ public: bool no_focus = false; bool is_popup = false; bool mpass = false; + bool focused = false; Rect2i parent_safe_rect; }; @@ -390,6 +391,7 @@ public: virtual void window_request_attention(WindowID p_window = MAIN_WINDOW_ID) override; virtual void window_move_to_foreground(WindowID p_window = MAIN_WINDOW_ID) override; + virtual bool window_is_focused(WindowID p_window = MAIN_WINDOW_ID) const override; virtual bool window_can_draw(WindowID p_window = MAIN_WINDOW_ID) const override; diff --git a/platform/macos/display_server_macos.mm b/platform/macos/display_server_macos.mm index b77715d648..a0a851b7dc 100644 --- a/platform/macos/display_server_macos.mm +++ b/platform/macos/display_server_macos.mm @@ -3075,6 +3075,15 @@ void DisplayServerMacOS::window_move_to_foreground(WindowID p_window) { } } +bool DisplayServerMacOS::window_is_focused(WindowID p_window) const { + _THREAD_SAFE_METHOD_ + + ERR_FAIL_COND_V(!windows.has(p_window), false); + const WindowData &wd = windows[p_window]; + + return wd.focused; +} + bool DisplayServerMacOS::window_can_draw(WindowID p_window) const { return window_get_mode(p_window) != WINDOW_MODE_MINIMIZED; } diff --git a/platform/macos/godot_window_delegate.mm b/platform/macos/godot_window_delegate.mm index df971c5139..1c6dbb1981 100644 --- a/platform/macos/godot_window_delegate.mm +++ b/platform/macos/godot_window_delegate.mm @@ -314,6 +314,7 @@ [self windowDidResize:notification]; // Emit resize event, to ensure content is resized if the window was resized while it was hidden. + wd.focused = true; ds->set_last_focused_window(window_id); ds->send_window_event(wd, DisplayServerMacOS::WINDOW_EVENT_FOCUS_IN); } @@ -330,6 +331,7 @@ [(GodotButtonView *)wd.window_button_view displayButtons]; } + wd.focused = false; ds->release_pressed_events(); ds->send_window_event(wd, DisplayServerMacOS::WINDOW_EVENT_FOCUS_OUT); } @@ -342,6 +344,7 @@ DisplayServerMacOS::WindowData &wd = ds->get_window(window_id); + wd.focused = false; ds->release_pressed_events(); ds->send_window_event(wd, DisplayServerMacOS::WINDOW_EVENT_FOCUS_OUT); } @@ -353,9 +356,11 @@ } DisplayServerMacOS::WindowData &wd = ds->get_window(window_id); - - ds->set_last_focused_window(window_id); - ds->send_window_event(wd, DisplayServerMacOS::WINDOW_EVENT_FOCUS_IN); + if ([wd.window_object isKeyWindow]) { + wd.focused = true; + ds->set_last_focused_window(window_id); + ds->send_window_event(wd, DisplayServerMacOS::WINDOW_EVENT_FOCUS_IN); + } } @end diff --git a/platform/web/display_server_web.cpp b/platform/web/display_server_web.cpp index 6cb56b404f..951ce110e0 100644 --- a/platform/web/display_server_web.cpp +++ b/platform/web/display_server_web.cpp @@ -1073,6 +1073,10 @@ void DisplayServerWeb::window_move_to_foreground(WindowID p_window) { // Not supported. } +bool DisplayServerWeb::window_is_focused(WindowID p_window) const { + return true; +} + bool DisplayServerWeb::window_can_draw(WindowID p_window) const { return true; } diff --git a/platform/web/display_server_web.h b/platform/web/display_server_web.h index 3b03b102cd..a4fd75f33b 100644 --- a/platform/web/display_server_web.h +++ b/platform/web/display_server_web.h @@ -211,6 +211,7 @@ public: virtual void window_request_attention(WindowID p_window = MAIN_WINDOW_ID) override; virtual void window_move_to_foreground(WindowID p_window = MAIN_WINDOW_ID) override; + virtual bool window_is_focused(WindowID p_window = MAIN_WINDOW_ID) const override; virtual bool window_can_draw(WindowID p_window = MAIN_WINDOW_ID) const override; diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp index fc208eb4bb..ea93c47ec5 100644 --- a/platform/windows/display_server_windows.cpp +++ b/platform/windows/display_server_windows.cpp @@ -1615,6 +1615,15 @@ void DisplayServerWindows::window_move_to_foreground(WindowID p_window) { } } +bool DisplayServerWindows::window_is_focused(WindowID p_window) const { + _THREAD_SAFE_METHOD_ + + ERR_FAIL_COND_V(!windows.has(p_window), false); + const WindowData &wd = windows[p_window]; + + return wd.window_focused; +} + bool DisplayServerWindows::window_can_draw(WindowID p_window) const { _THREAD_SAFE_METHOD_ diff --git a/platform/windows/display_server_windows.h b/platform/windows/display_server_windows.h index ae2cd4e8b5..7228de7d31 100644 --- a/platform/windows/display_server_windows.h +++ b/platform/windows/display_server_windows.h @@ -594,6 +594,7 @@ public: virtual void window_request_attention(WindowID p_window = MAIN_WINDOW_ID) override; virtual void window_move_to_foreground(WindowID p_window = MAIN_WINDOW_ID) override; + virtual bool window_is_focused(WindowID p_window = MAIN_WINDOW_ID) const override; virtual bool window_can_draw(WindowID p_window = MAIN_WINDOW_ID) const override; diff --git a/scene/main/window.cpp b/scene/main/window.cpp index b82b215e54..e8395f59c9 100644 --- a/scene/main/window.cpp +++ b/scene/main/window.cpp @@ -616,6 +616,8 @@ void Window::_update_from_window() { void Window::_clear_window() { ERR_FAIL_COND(window_id == DisplayServer::INVALID_WINDOW_ID); + bool had_focus = has_focus(); + DisplayServer::get_singleton()->window_set_rect_changed_callback(Callable(), window_id); DisplayServer::get_singleton()->window_set_window_event_callback(Callable(), window_id); DisplayServer::get_singleton()->window_set_input_event_callback(Callable(), window_id); @@ -638,7 +640,7 @@ void Window::_clear_window() { window_id = DisplayServer::INVALID_WINDOW_ID; // If closing window was focused and has a parent, return focus. - if (focused && transient_parent) { + if (had_focus && transient_parent) { transient_parent->grab_focus(); } @@ -1185,6 +1187,7 @@ void Window::_notification(int p_what) { { position = DisplayServer::get_singleton()->window_get_position(window_id); size = DisplayServer::get_singleton()->window_get_size(window_id); + focused = DisplayServer::get_singleton()->window_is_focused(window_id); } _update_window_size(); // Inform DisplayServer of minimum and maximum size. _update_viewport_size(); // Then feed back to the viewport. @@ -1762,6 +1765,9 @@ void Window::grab_focus() { bool Window::has_focus() const { ERR_READ_THREAD_GUARD_V(false); + if (window_id != DisplayServer::INVALID_WINDOW_ID) { + return DisplayServer::get_singleton()->window_is_focused(window_id); + } return focused; } diff --git a/servers/display_server.cpp b/servers/display_server.cpp index 516f2f1be6..41fa0d2d47 100644 --- a/servers/display_server.cpp +++ b/servers/display_server.cpp @@ -716,6 +716,7 @@ void DisplayServer::_bind_methods() { ClassDB::bind_method(D_METHOD("window_request_attention", "window_id"), &DisplayServer::window_request_attention, DEFVAL(MAIN_WINDOW_ID)); ClassDB::bind_method(D_METHOD("window_move_to_foreground", "window_id"), &DisplayServer::window_move_to_foreground, DEFVAL(MAIN_WINDOW_ID)); + ClassDB::bind_method(D_METHOD("window_is_focused", "window_id"), &DisplayServer::window_is_focused, DEFVAL(MAIN_WINDOW_ID)); ClassDB::bind_method(D_METHOD("window_can_draw", "window_id"), &DisplayServer::window_can_draw, DEFVAL(MAIN_WINDOW_ID)); ClassDB::bind_method(D_METHOD("window_set_transient", "window_id", "parent_window_id"), &DisplayServer::window_set_transient); diff --git a/servers/display_server.h b/servers/display_server.h index d8e67b4f92..fc8207f2d3 100644 --- a/servers/display_server.h +++ b/servers/display_server.h @@ -424,6 +424,7 @@ public: virtual void window_request_attention(WindowID p_window = MAIN_WINDOW_ID) = 0; virtual void window_move_to_foreground(WindowID p_window = MAIN_WINDOW_ID) = 0; + virtual bool window_is_focused(WindowID p_window = MAIN_WINDOW_ID) const = 0; virtual void window_set_window_buttons_offset(const Vector2i &p_offset, WindowID p_window = MAIN_WINDOW_ID) {} virtual Vector3i window_get_safe_title_margins(WindowID p_window = MAIN_WINDOW_ID) const { return Vector3i(); } diff --git a/servers/display_server_headless.h b/servers/display_server_headless.h index 0c43b84f2e..af13f8db21 100644 --- a/servers/display_server_headless.h +++ b/servers/display_server_headless.h @@ -119,6 +119,7 @@ public: void window_request_attention(WindowID p_window = MAIN_WINDOW_ID) override {} void window_move_to_foreground(WindowID p_window = MAIN_WINDOW_ID) override {} + bool window_is_focused(WindowID p_window = MAIN_WINDOW_ID) const override { return true; }; bool window_can_draw(WindowID p_window = MAIN_WINDOW_ID) const override { return false; } |