1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-08 12:40:44 +00:00

Merge pull request #102006 from Hilderin/fix-embedded-game-paused

Fix flickering in embedded game when paused
This commit is contained in:
Thaddeus Crews
2025-01-28 09:03:19 -06:00
2 changed files with 47 additions and 11 deletions

View File

@@ -301,6 +301,7 @@ void GameView::_stop_pressed() {
} }
_detach_script_debugger(); _detach_script_debugger();
paused = false;
EditorNode::get_singleton()->set_unfocused_low_processor_usage_mode_enabled(true); EditorNode::get_singleton()->set_unfocused_low_processor_usage_mode_enabled(true);
embedded_process->reset(); embedded_process->reset();
@@ -516,15 +517,26 @@ void GameView::_update_embed_menu_options() {
} }
void GameView::_update_embed_window_size() { void GameView::_update_embed_window_size() {
if (paused) {
// When paused, Godot does not re-render. As a result, resizing the game window to a larger size
// causes artifacts and flickering. However, resizing to a smaller size seems fine.
// To prevent artifacts and flickering, we will force the game window to maintain its size.
// Using the same technique as SIZE_MODE_FIXED, the embedded process control will
// prevent resizing the game to a larger size while maintaining the aspect ratio.
embedded_process->set_window_size(size_paused);
embedded_process->set_keep_aspect(false);
} else {
if (embed_size_mode == SIZE_MODE_FIXED || embed_size_mode == SIZE_MODE_KEEP_ASPECT) { if (embed_size_mode == SIZE_MODE_FIXED || embed_size_mode == SIZE_MODE_KEEP_ASPECT) {
//The embedded process control will need the desired window size. // The embedded process control will need the desired window size.
EditorRun::WindowPlacement placement = EditorRun::get_window_placement(); EditorRun::WindowPlacement placement = EditorRun::get_window_placement();
embedded_process->set_window_size(placement.size); embedded_process->set_window_size(placement.size);
} else { } else {
//Stretch... No need for the window size. // Stretch... No need for the window size.
embedded_process->set_window_size(Size2i()); embedded_process->set_window_size(Size2i());
} }
embedded_process->set_keep_aspect(embed_size_mode == SIZE_MODE_KEEP_ASPECT); embedded_process->set_keep_aspect(embed_size_mode == SIZE_MODE_KEEP_ASPECT);
}
} }
void GameView::_hide_selection_toggled(bool p_pressed) { void GameView::_hide_selection_toggled(bool p_pressed) {
@@ -788,7 +800,8 @@ void GameView::_window_close_request() {
embedded_process->reset(); embedded_process->reset();
// When the embedding is not complete, we need to kill the process. // When the embedding is not complete, we need to kill the process.
if (embedded_process->is_embedding_in_progress()) { // If the game is paused, the close request will not be processed by the game, so it's better to kill the process.
if (paused || embedded_process->is_embedding_in_progress()) {
// Call deferred to prevent the _stop_pressed callback to be executed before the wrapper window // Call deferred to prevent the _stop_pressed callback to be executed before the wrapper window
// actually closes. // actually closes.
callable_mp(EditorRunBar::get_singleton(), &EditorRunBar::stop_playing).call_deferred(); callable_mp(EditorRunBar::get_singleton(), &EditorRunBar::stop_playing).call_deferred();
@@ -796,6 +809,20 @@ void GameView::_window_close_request() {
} }
} }
void GameView::_debugger_breaked(bool p_breaked, bool p_can_debug) {
if (p_breaked == paused) {
return;
}
paused = p_breaked;
if (paused) {
size_paused = embedded_process->get_screen_embedded_window_rect().size;
}
_update_embed_window_size();
}
GameView::GameView(Ref<GameViewDebugger> p_debugger, WindowWrapper *p_wrapper) { GameView::GameView(Ref<GameViewDebugger> p_debugger, WindowWrapper *p_wrapper) {
singleton = this; singleton = this;
@@ -985,6 +1012,8 @@ GameView::GameView(Ref<GameViewDebugger> p_debugger, WindowWrapper *p_wrapper) {
p_wrapper->set_override_close_request(true); p_wrapper->set_override_close_request(true);
p_wrapper->connect("window_close_requested", callable_mp(this, &GameView::_window_close_request)); p_wrapper->connect("window_close_requested", callable_mp(this, &GameView::_window_close_request));
p_wrapper->connect("window_size_changed", callable_mp(this, &GameView::_update_floating_window_settings)); p_wrapper->connect("window_size_changed", callable_mp(this, &GameView::_update_floating_window_settings));
EditorDebuggerNode::get_singleton()->connect("breaked", callable_mp(this, &GameView::_debugger_breaked));
} }
/////// ///////
@@ -1054,16 +1083,19 @@ void GameViewPlugin::_window_visibility_changed(bool p_visible) {
} }
void GameViewPlugin::_save_last_editor(const String &p_editor) { void GameViewPlugin::_save_last_editor(const String &p_editor) {
if (p_editor != get_name()) { if (p_editor != get_plugin_name()) {
last_editor = p_editor; last_editor = p_editor;
} }
} }
void GameViewPlugin::_focus_another_editor() { void GameViewPlugin::_focus_another_editor() {
if (window_wrapper->get_window_enabled()) { if (window_wrapper->get_window_enabled()) {
ERR_FAIL_COND(last_editor.is_empty()); if (last_editor.is_empty()) {
EditorNode::get_singleton()->get_editor_main_screen()->select(EditorMainScreen::EDITOR_2D);
} else {
EditorInterface::get_singleton()->set_main_screen_editor(last_editor); EditorInterface::get_singleton()->set_main_screen_editor(last_editor);
} }
}
} }
GameViewPlugin::GameViewPlugin() { GameViewPlugin::GameViewPlugin() {

View File

@@ -122,6 +122,8 @@ class GameView : public VBoxContainer {
bool embed_on_play = true; bool embed_on_play = true;
bool make_floating_on_play = true; bool make_floating_on_play = true;
EmbedSizeMode embed_size_mode = SIZE_MODE_FIXED; EmbedSizeMode embed_size_mode = SIZE_MODE_FIXED;
bool paused = false;
Size2 size_paused;
Rect2i floating_window_rect; Rect2i floating_window_rect;
int floating_window_screen = -1; int floating_window_screen = -1;
@@ -186,6 +188,8 @@ class GameView : public VBoxContainer {
void _detach_script_debugger(); void _detach_script_debugger();
void _remote_window_title_changed(String title); void _remote_window_title_changed(String title);
void _debugger_breaked(bool p_breaked, bool p_can_debug);
protected: protected:
void _notification(int p_what); void _notification(int p_what);