Skip to content

Commit 628d091

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.
1 parent 701505e commit 628d091

17 files changed

+689
-275
lines changed

core/config/engine.cpp

+11
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,17 @@ bool Engine::is_embedded_in_editor() const {
423423
return embedded_in_editor;
424424
}
425425

426+
void Engine::add_embedded_subwindow(String p_subwindow_title, int64_t p_parent_id) {
427+
embedded_subwindows[p_subwindow_title] = p_parent_id;
428+
}
429+
430+
int64_t Engine::get_embedded_subwindow(String p_subwindow_title) {
431+
if (embedded_subwindows.has(p_subwindow_title)) {
432+
return embedded_subwindows[p_subwindow_title];
433+
}
434+
return 0;
435+
}
436+
426437
Engine::Engine() {
427438
singleton = this;
428439
}

core/config/engine.h

+3
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(String p_subwindow_title, int64_t p_parent_id);
150+
int64_t get_embedded_subwindow(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

+5-4
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ int EmbeddedProcess::get_embedded_pid() const {
154154
return current_process_id;
155155
}
156156

157-
void EmbeddedProcess::embed_process(OS::ProcessID p_pid) {
157+
void EmbeddedProcess::embed_process(OS::ProcessID p_pid, String p_embedded_window) {
158158
if (!window) {
159159
return;
160160
}
@@ -169,6 +169,7 @@ void EmbeddedProcess::embed_process(OS::ProcessID p_pid) {
169169
reset();
170170

171171
current_process_id = p_pid;
172+
current_embedded_window = p_embedded_window;
172173
start_embedding_time = OS::get_singleton()->get_ticks_msec();
173174
embedding_grab_focus = has_focus();
174175
timer_update_embedded_process->start();
@@ -182,7 +183,7 @@ void EmbeddedProcess::embed_process(OS::ProcessID p_pid) {
182183

183184
void EmbeddedProcess::reset() {
184185
if (current_process_id != 0 && embedding_completed) {
185-
DisplayServer::get_singleton()->remove_embedded_process(current_process_id);
186+
DisplayServer::get_singleton()->remove_embedded_process(current_process_id, current_embedded_window);
186187
}
187188
current_process_id = 0;
188189
embedding_completed = false;
@@ -203,7 +204,7 @@ void EmbeddedProcess::request_close() {
203204

204205
void EmbeddedProcess::_try_embed_process() {
205206
bool is_visible = is_visible_in_tree();
206-
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);
207+
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);
207208
if (err == OK) {
208209
embedding_completed = true;
209210
queue_redraw();
@@ -262,7 +263,7 @@ void EmbeddedProcess::_update_embedded_process() {
262263
last_updated_embedded_process_focused = focus;
263264
}
264265

265-
DisplayServer::get_singleton()->embed_process(window->get_window_id(), current_process_id, get_screen_embedded_window_rect(), is_visible_in_tree(), must_grab_focus);
266+
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);
266267
emit_signal(SNAME("embedded_process_updated"));
267268
}
268269

editor/plugins/embedded_process.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ class EmbeddedProcess : public Control {
3939
uint64_t last_application_focus_time = 0;
4040
OS::ProcessID focused_process_id = 0;
4141
OS::ProcessID current_process_id = 0;
42+
String current_embedded_window = "";
4243
bool embedding_grab_focus = false;
4344
bool embedding_completed = false;
4445
uint64_t start_embedding_time = 0;
@@ -74,7 +75,7 @@ class EmbeddedProcess : public Control {
7475
void _notification(int p_what);
7576

7677
public:
77-
void embed_process(OS::ProcessID p_pid);
78+
void embed_process(OS::ProcessID p_pid, String p_embedded_window);
7879
void reset();
7980
void request_close();
8081

0 commit comments

Comments
 (0)