diff options
-rw-r--r-- | doc/classes/RenderingServer.xml | 7 | ||||
-rw-r--r-- | editor/plugins/editor_preview_plugins.cpp | 24 | ||||
-rw-r--r-- | editor/plugins/editor_preview_plugins.h | 20 | ||||
-rw-r--r-- | editor/plugins/tiles/tiles_editor_plugin.cpp | 8 | ||||
-rw-r--r-- | editor/plugins/tiles/tiles_editor_plugin.h | 3 | ||||
-rw-r--r-- | platform/linuxbsd/display_server_x11.cpp | 23 | ||||
-rw-r--r-- | servers/rendering/rendering_server_default.cpp | 26 | ||||
-rw-r--r-- | servers/rendering/rendering_server_default.h | 10 | ||||
-rw-r--r-- | servers/rendering_server.cpp | 2 | ||||
-rw-r--r-- | servers/rendering_server.h | 4 |
10 files changed, 50 insertions, 77 deletions
diff --git a/doc/classes/RenderingServer.xml b/doc/classes/RenderingServer.xml index 86e66a5738..68b79ff749 100644 --- a/doc/classes/RenderingServer.xml +++ b/doc/classes/RenderingServer.xml @@ -2575,12 +2575,9 @@ </method> <method name="request_frame_drawn_callback"> <return type="void" /> - <argument index="0" name="where" type="Object" /> - <argument index="1" name="method" type="StringName" /> - <argument index="2" name="userdata" type="Variant" /> + <argument index="0" name="callable" type="Callable" /> <description> - Schedules a callback to the corresponding named [code]method[/code] on [code]where[/code] after a frame has been drawn. - The callback method must use only 1 argument which will be called with [code]userdata[/code]. + Schedules a callback to the given callable after a frame has been drawn. </description> </method> <method name="scenario_create"> diff --git a/editor/plugins/editor_preview_plugins.cpp b/editor/plugins/editor_preview_plugins.cpp index 4cb2c0a76b..15c15ae6b2 100644 --- a/editor/plugins/editor_preview_plugins.cpp +++ b/editor/plugins/editor_preview_plugins.cpp @@ -297,14 +297,10 @@ EditorPackedScenePreviewPlugin::EditorPackedScenePreviewPlugin() { ////////////////////////////////////////////////////////////////// -void EditorMaterialPreviewPlugin::_preview_done(const Variant &p_udata) { +void EditorMaterialPreviewPlugin::_preview_done() { preview_done.set(); } -void EditorMaterialPreviewPlugin::_bind_methods() { - ClassDB::bind_method("_preview_done", &EditorMaterialPreviewPlugin::_preview_done); -} - bool EditorMaterialPreviewPlugin::handles(const String &p_type) const { return ClassDB::is_parent_class(p_type, "Material"); //any material } @@ -323,7 +319,7 @@ Ref<Texture2D> EditorMaterialPreviewPlugin::generate(const RES &p_from, const Si RS::get_singleton()->viewport_set_update_mode(viewport, RS::VIEWPORT_UPDATE_ONCE); //once used for capture preview_done.clear(); - RS::get_singleton()->request_frame_drawn_callback(const_cast<EditorMaterialPreviewPlugin *>(this), "_preview_done", Variant()); + RS::get_singleton()->request_frame_drawn_callback(callable_mp(const_cast<EditorMaterialPreviewPlugin *>(this), &EditorMaterialPreviewPlugin::_preview_done)); while (!preview_done.is_set()) { OS::get_singleton()->delay_usec(10); @@ -699,14 +695,10 @@ EditorAudioStreamPreviewPlugin::EditorAudioStreamPreviewPlugin() { /////////////////////////////////////////////////////////////////////////// -void EditorMeshPreviewPlugin::_preview_done(const Variant &p_udata) { +void EditorMeshPreviewPlugin::_preview_done() { preview_done.set(); } -void EditorMeshPreviewPlugin::_bind_methods() { - ClassDB::bind_method("_preview_done", &EditorMeshPreviewPlugin::_preview_done); -} - bool EditorMeshPreviewPlugin::handles(const String &p_type) const { return ClassDB::is_parent_class(p_type, "Mesh"); //any Mesh } @@ -738,7 +730,7 @@ Ref<Texture2D> EditorMeshPreviewPlugin::generate(const RES &p_from, const Size2 RS::get_singleton()->viewport_set_update_mode(viewport, RS::VIEWPORT_UPDATE_ONCE); //once used for capture preview_done.clear(); - RS::get_singleton()->request_frame_drawn_callback(const_cast<EditorMeshPreviewPlugin *>(this), "_preview_done", Variant()); + RS::get_singleton()->request_frame_drawn_callback(callable_mp(const_cast<EditorMeshPreviewPlugin *>(this), &EditorMeshPreviewPlugin::_preview_done)); while (!preview_done.is_set()) { OS::get_singleton()->delay_usec(10); @@ -814,14 +806,10 @@ EditorMeshPreviewPlugin::~EditorMeshPreviewPlugin() { /////////////////////////////////////////////////////////////////////////// -void EditorFontPreviewPlugin::_preview_done(const Variant &p_udata) { +void EditorFontPreviewPlugin::_preview_done() { preview_done.set(); } -void EditorFontPreviewPlugin::_bind_methods() { - ClassDB::bind_method("_preview_done", &EditorFontPreviewPlugin::_preview_done); -} - bool EditorFontPreviewPlugin::handles(const String &p_type) const { return ClassDB::is_parent_class(p_type, "FontData") || ClassDB::is_parent_class(p_type, "Font"); } @@ -859,7 +847,7 @@ Ref<Texture2D> EditorFontPreviewPlugin::generate_from_path(const String &p_path, preview_done.clear(); RS::get_singleton()->viewport_set_update_mode(viewport, RS::VIEWPORT_UPDATE_ONCE); //once used for capture - RS::get_singleton()->request_frame_drawn_callback(const_cast<EditorFontPreviewPlugin *>(this), "_preview_done", Variant()); + RS::get_singleton()->request_frame_drawn_callback(callable_mp(const_cast<EditorFontPreviewPlugin *>(this), &EditorFontPreviewPlugin::_preview_done)); while (!preview_done.is_set()) { OS::get_singleton()->delay_usec(10); diff --git a/editor/plugins/editor_preview_plugins.h b/editor/plugins/editor_preview_plugins.h index 091feae5fb..c24dabf679 100644 --- a/editor/plugins/editor_preview_plugins.h +++ b/editor/plugins/editor_preview_plugins.h @@ -94,10 +94,7 @@ class EditorMaterialPreviewPlugin : public EditorResourcePreviewGenerator { RID camera; mutable SafeFlag preview_done; - void _preview_done(const Variant &p_udata); - -protected: - static void _bind_methods(); + void _preview_done(); public: virtual bool handles(const String &p_type) const override; @@ -138,10 +135,7 @@ class EditorMeshPreviewPlugin : public EditorResourcePreviewGenerator { RID camera; mutable SafeFlag preview_done; - void _preview_done(const Variant &p_udata); - -protected: - static void _bind_methods(); + void _preview_done(); public: virtual bool handles(const String &p_type) const override; @@ -160,10 +154,7 @@ class EditorFontPreviewPlugin : public EditorResourcePreviewGenerator { RID canvas_item; mutable SafeFlag preview_done; - void _preview_done(const Variant &p_udata); - -protected: - static void _bind_methods(); + void _preview_done(); public: virtual bool handles(const String &p_type) const override; @@ -179,10 +170,7 @@ class EditorTileMapPatternPreviewPlugin : public EditorResourcePreviewGenerator mutable SafeFlag preview_done; - void _preview_done(const Variant &p_udata); - -protected: - static void _bind_methods(); + void _preview_done(); public: virtual bool handles(const String &p_type) const override; diff --git a/editor/plugins/tiles/tiles_editor_plugin.cpp b/editor/plugins/tiles/tiles_editor_plugin.cpp index f1918073fb..8e2c16906d 100644 --- a/editor/plugins/tiles/tiles_editor_plugin.cpp +++ b/editor/plugins/tiles/tiles_editor_plugin.cpp @@ -47,7 +47,7 @@ TilesEditorPlugin *TilesEditorPlugin::singleton = nullptr; -void TilesEditorPlugin::_pattern_preview_done(const Variant &p_udata) { +void TilesEditorPlugin::_pattern_preview_done() { pattern_preview_done.set(); } @@ -113,7 +113,7 @@ void TilesEditorPlugin::_thread() { EditorNode::get_singleton()->add_child(viewport); pattern_preview_done.clear(); - RS::get_singleton()->request_frame_drawn_callback(const_cast<TilesEditorPlugin *>(this), "_pattern_preview_done", Variant()); + RS::get_singleton()->request_frame_drawn_callback(callable_mp(const_cast<TilesEditorPlugin *>(this), &TilesEditorPlugin::_pattern_preview_done)); while (!pattern_preview_done.is_set()) { OS::get_singleton()->delay_usec(10); @@ -274,10 +274,6 @@ bool TilesEditorPlugin::handles(Object *p_object) const { return p_object->is_class("TileMap") || p_object->is_class("TileSet"); } -void TilesEditorPlugin::_bind_methods() { - ClassDB::bind_method(D_METHOD("_pattern_preview_done", "pattern"), &TilesEditorPlugin::_pattern_preview_done); -} - TilesEditorPlugin::TilesEditorPlugin(EditorNode *p_node) { set_process_internal(true); diff --git a/editor/plugins/tiles/tiles_editor_plugin.h b/editor/plugins/tiles/tiles_editor_plugin.h index dd52bdc31a..34feee965f 100644 --- a/editor/plugins/tiles/tiles_editor_plugin.h +++ b/editor/plugins/tiles/tiles_editor_plugin.h @@ -78,13 +78,12 @@ private: SafeFlag pattern_thread_exit; SafeFlag pattern_thread_exited; mutable SafeFlag pattern_preview_done; - void _pattern_preview_done(const Variant &p_udata); + void _pattern_preview_done(); static void _thread_func(void *ud); void _thread(); protected: void _notification(int p_what); - static void _bind_methods(); public: _FORCE_INLINE_ static TilesEditorPlugin *get_singleton() { return singleton; } diff --git a/platform/linuxbsd/display_server_x11.cpp b/platform/linuxbsd/display_server_x11.cpp index e98d114267..c4e828bdb2 100644 --- a/platform/linuxbsd/display_server_x11.cpp +++ b/platform/linuxbsd/display_server_x11.cpp @@ -733,6 +733,16 @@ Size2i DisplayServerX11::screen_get_size(int p_screen) const { return _screen_get_rect(p_screen).size; } +bool g_bad_window = false; +int bad_window_error_handler(Display *display, XErrorEvent *error) { + if (error->error_code == BadWindow) { + g_bad_window = true; + } else { + ERR_PRINT("Unhandled XServer error code: " + itos(error->error_code)); + } + return 0; +} + Rect2i DisplayServerX11::screen_get_usable_rect(int p_screen) const { _THREAD_SAFE_METHOD_ @@ -869,7 +879,13 @@ Rect2i DisplayServerX11::screen_get_usable_rect(int p_screen) const { if (desktop_valid) { use_simple_method = false; + // Handle bad window errors silently because there's no other way to check + // that one of the windows has been destroyed in the meantime. + int (*oldHandler)(Display *, XErrorEvent *) = XSetErrorHandler(&bad_window_error_handler); + for (unsigned long win_index = 0; win_index < clients_len; ++win_index) { + g_bad_window = false; + // Remove strut size from desktop size to get a more accurate result. bool strut_found = false; unsigned long strut_len = 0; @@ -881,7 +897,7 @@ Rect2i DisplayServerX11::screen_get_usable_rect(int p_screen) const { } } // Fallback to older strut property. - if (!strut_found) { + if (!g_bad_window && !strut_found) { Atom strut_prop = XInternAtom(x11_display, "_NET_WM_STRUT", True); if (strut_prop != None) { if (XGetWindowProperty(x11_display, windows_data[win_index], strut_prop, 0, LONG_MAX, False, XA_CARDINAL, &type, &format, &strut_len, &remaining, &strut_data) == Success) { @@ -889,7 +905,7 @@ Rect2i DisplayServerX11::screen_get_usable_rect(int p_screen) const { } } } - if (strut_found && (format == 32) && (strut_len >= 4) && strut_data) { + if (!g_bad_window && strut_found && (format == 32) && (strut_len >= 4) && strut_data) { long *struts = (long *)strut_data; long left = struts[0]; @@ -961,6 +977,9 @@ Rect2i DisplayServerX11::screen_get_usable_rect(int p_screen) const { XFree(strut_data); } } + + // Restore default error handler. + XSetErrorHandler(oldHandler); } } } diff --git a/servers/rendering/rendering_server_default.cpp b/servers/rendering/rendering_server_default.cpp index 107c9f8040..2ce9a20b6b 100644 --- a/servers/rendering/rendering_server_default.cpp +++ b/servers/rendering/rendering_server_default.cpp @@ -64,14 +64,8 @@ void RenderingServerDefault::_free(RID p_rid) { /* EVENT QUEUING */ -void RenderingServerDefault::request_frame_drawn_callback(Object *p_where, const StringName &p_method, const Variant &p_userdata) { - ERR_FAIL_NULL(p_where); - FrameDrawnCallbacks fdc; - fdc.object = p_where->get_instance_id(); - fdc.method = p_method; - fdc.param = p_userdata; - - frame_drawn_callbacks.push_back(fdc); +void RenderingServerDefault::request_frame_drawn_callback(const Callable &p_callable) { + frame_drawn_callbacks.push_back(p_callable); } void RenderingServerDefault::_draw(bool p_swap_buffers, double frame_step) { @@ -103,15 +97,13 @@ void RenderingServerDefault::_draw(bool p_swap_buffers, double frame_step) { RSG::scene->update_visibility_notifiers(); while (frame_drawn_callbacks.front()) { - Object *obj = ObjectDB::get_instance(frame_drawn_callbacks.front()->get().object); - if (obj) { - Callable::CallError ce; - const Variant *v = &frame_drawn_callbacks.front()->get().param; - obj->call(frame_drawn_callbacks.front()->get().method, &v, 1, ce); - if (ce.error != Callable::CallError::CALL_OK) { - String err = Variant::get_call_error_text(obj, frame_drawn_callbacks.front()->get().method, &v, 1, ce); - ERR_PRINT("Error calling frame drawn function: " + err); - } + Callable c = frame_drawn_callbacks.front()->get(); + Variant result; + Callable::CallError ce; + c.call(nullptr, 0, result, ce); + if (ce.error != Callable::CallError::CALL_OK) { + String err = Variant::get_callable_error_text(c, nullptr, 0, ce); + ERR_PRINT("Error calling frame drawn function: " + err); } frame_drawn_callbacks.pop_front(); diff --git a/servers/rendering/rendering_server_default.h b/servers/rendering/rendering_server_default.h index a25bd3dae5..9a592a9265 100644 --- a/servers/rendering/rendering_server_default.h +++ b/servers/rendering/rendering_server_default.h @@ -58,13 +58,7 @@ class RenderingServerDefault : public RenderingServer { static int changes; RID test_cube; - struct FrameDrawnCallbacks { - ObjectID object; - StringName method; - Variant param; - }; - - List<FrameDrawnCallbacks> frame_drawn_callbacks; + List<Callable> frame_drawn_callbacks; static void _changes_changed() {} @@ -880,7 +874,7 @@ public: /* EVENT QUEUING */ - virtual void request_frame_drawn_callback(Object *p_where, const StringName &p_method, const Variant &p_userdata) override; + virtual void request_frame_drawn_callback(const Callable &p_callable) override; virtual void draw(bool p_swap_buffers, double frame_step) override; virtual void sync() override; diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp index 1b16949768..cdf7fa530e 100644 --- a/servers/rendering_server.cpp +++ b/servers/rendering_server.cpp @@ -2701,7 +2701,7 @@ void RenderingServer::_bind_methods() { /* Misc */ - ClassDB::bind_method(D_METHOD("request_frame_drawn_callback", "where", "method", "userdata"), &RenderingServer::request_frame_drawn_callback); + ClassDB::bind_method(D_METHOD("request_frame_drawn_callback", "callable"), &RenderingServer::request_frame_drawn_callback); ClassDB::bind_method(D_METHOD("has_changed"), &RenderingServer::has_changed); ClassDB::bind_method(D_METHOD("get_rendering_info", "info"), &RenderingServer::get_rendering_info); ClassDB::bind_method(D_METHOD("get_video_adapter_name"), &RenderingServer::get_video_adapter_name); diff --git a/servers/rendering_server.h b/servers/rendering_server.h index 3125268e1c..f35a633bf3 100644 --- a/servers/rendering_server.h +++ b/servers/rendering_server.h @@ -1435,10 +1435,10 @@ public: virtual void free(RID p_rid) = 0; ///< free RIDs associated with the rendering server - virtual void request_frame_drawn_callback(Object *p_where, const StringName &p_method, const Variant &p_userdata) = 0; - /* EVENT QUEUING */ + virtual void request_frame_drawn_callback(const Callable &p_callable) = 0; + virtual void draw(bool p_swap_buffers = true, double frame_step = 0.0) = 0; virtual void sync() = 0; virtual bool has_changed() const = 0; |