Skip to content

Commit 3a4b249

Browse files
Add embedded window selector & dual game view
This commit allows the `GameView` to select either the "Main Window" (default view of the running game) or a subwindow to become embedded when running the project. This information is communicated to the built game via a new `--swid` (subwindow ID) command line parameter which matches the `--wid` implementation created for the original embedding feature. The subwindow is chosen by matching the name of the window to a user provided name which is given in a text box in the `GameView`. This is implemented only for Windows and a follow up PR should be able to match the functionality for Linux easily. Additionally, to utilize this new behavior, there is now the option to enable a second `GameView` that sits above the main one. The second view can embed a different window and has its own embedding controls to improve user debugging. For now, in order to keep the PR smaller, the secondary `GameView` does not utilize its own SceneDebugger, so only the main view can use the runtime selection options. A future PR can open up more functionality for parity with the main view. @jaydensipe also contributed an alternate layout option for the split game view in this commit. Co-Authored-By: Jayden Sipe <[email protected]>
1 parent 46c495c commit 3a4b249

22 files changed

+839
-325
lines changed

core/config/engine.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,17 @@ bool Engine::is_embedded_in_editor() const {
404404
return embedded_in_editor;
405405
}
406406

407+
void Engine::add_embedded_subwindow(const String &p_subwindow_title, int64_t p_parent_id) {
408+
embedded_subwindows[p_subwindow_title] = p_parent_id;
409+
}
410+
411+
int64_t Engine::get_embedded_subwindow(const String &p_subwindow_title) {
412+
if (embedded_subwindows.has(p_subwindow_title)) {
413+
return embedded_subwindows[p_subwindow_title];
414+
}
415+
return 0;
416+
}
417+
407418
Engine::Engine() {
408419
singleton = this;
409420
}

core/config/engine.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ class Engine {
8686
bool project_manager_hint = false;
8787
bool extension_reloading = false;
8888
bool embedded_in_editor = false;
89+
HashMap<String, int64_t> embedded_subwindows;
8990
bool recovery_mode_hint = false;
9091

9192
bool _print_header = true;
@@ -145,6 +146,8 @@ class Engine {
145146
void set_frame_delay(uint32_t p_msec);
146147
uint32_t get_frame_delay() const;
147148

149+
void add_embedded_subwindow(const String &p_subwindow_title, int64_t p_parent_id);
150+
int64_t get_embedded_subwindow(const String &p_subwindow_title);
148151
void add_singleton(const Singleton &p_singleton);
149152
void get_singletons(List<Singleton> *p_singletons);
150153
bool has_singleton(const StringName &p_name) const;

editor/plugins/embedded_process.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ int EmbeddedProcess::get_embedded_pid() const {
185185
return current_process_id;
186186
}
187187

188-
void EmbeddedProcess::embed_process(OS::ProcessID p_pid) {
188+
void EmbeddedProcess::embed_process(OS::ProcessID p_pid, const String &p_embedded_window) {
189189
if (!window) {
190190
return;
191191
}
@@ -200,6 +200,7 @@ void EmbeddedProcess::embed_process(OS::ProcessID p_pid) {
200200
reset();
201201

202202
current_process_id = p_pid;
203+
current_embedded_window = p_embedded_window;
203204
start_embedding_time = OS::get_singleton()->get_ticks_msec();
204205
embedding_grab_focus = has_focus();
205206
timer_update_embedded_process->start();
@@ -213,7 +214,7 @@ void EmbeddedProcess::embed_process(OS::ProcessID p_pid) {
213214

214215
void EmbeddedProcess::reset() {
215216
if (current_process_id != 0 && embedding_completed) {
216-
DisplayServer::get_singleton()->remove_embedded_process(current_process_id);
217+
DisplayServer::get_singleton()->remove_embedded_process(current_process_id, current_embedded_window);
217218
}
218219
current_process_id = 0;
219220
embedding_completed = false;
@@ -234,7 +235,7 @@ void EmbeddedProcess::request_close() {
234235

235236
void EmbeddedProcess::_try_embed_process() {
236237
bool is_visible = is_visible_in_tree();
237-
Error err = DisplayServer::get_singleton()->embed_process(window->get_window_id(), current_process_id, get_screen_embedded_window_rect(), is_visible, is_visible && application_has_focus && embedding_grab_focus);
238+
Error err = DisplayServer::get_singleton()->embed_process(window->get_window_id(), current_process_id, current_embedded_window, get_screen_embedded_window_rect(), is_visible, is_visible && application_has_focus && embedding_grab_focus);
238239
if (err == OK) {
239240
embedding_completed = true;
240241
queue_redraw();
@@ -293,7 +294,7 @@ void EmbeddedProcess::_update_embedded_process() {
293294
last_updated_embedded_process_focused = focus;
294295
}
295296

296-
DisplayServer::get_singleton()->embed_process(window->get_window_id(), current_process_id, get_screen_embedded_window_rect(), is_visible_in_tree(), must_grab_focus);
297+
DisplayServer::get_singleton()->embed_process(window->get_window_id(), current_process_id, current_embedded_window, get_screen_embedded_window_rect(), is_visible_in_tree(), must_grab_focus);
297298
emit_signal(SNAME("embedded_process_updated"));
298299
}
299300

editor/plugins/embedded_process.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ class EmbeddedProcessBase : public Control {
6262
virtual bool is_embedding_completed() const = 0;
6363
virtual bool is_embedding_in_progress() const = 0;
6464
virtual bool is_process_focused() const = 0;
65-
virtual void embed_process(OS::ProcessID p_pid) = 0;
65+
virtual void embed_process(OS::ProcessID p_pid, const String &p_embedded_window) = 0;
6666
virtual int get_embedded_pid() const = 0;
6767
virtual void reset() = 0;
6868
virtual void request_close() = 0;
@@ -86,6 +86,7 @@ class EmbeddedProcess : public EmbeddedProcessBase {
8686
uint64_t last_application_focus_time = 0;
8787
OS::ProcessID focused_process_id = 0;
8888
OS::ProcessID current_process_id = 0;
89+
String current_embedded_window;
8990
bool embedding_grab_focus = false;
9091
bool embedding_completed = false;
9192
uint64_t start_embedding_time = 0;
@@ -115,8 +116,8 @@ class EmbeddedProcess : public EmbeddedProcessBase {
115116
bool is_embedding_in_progress() const override;
116117
bool is_embedding_completed() const override;
117118
bool is_process_focused() const override;
118-
void embed_process(OS::ProcessID p_pid) override;
119119
int get_embedded_pid() const override;
120+
void embed_process(OS::ProcessID p_pid, const String &p_embedded_window) override;
120121
void reset() override;
121122
void request_close() override;
122123
void queue_update_embedded_process() override;

0 commit comments

Comments
 (0)