Skip to content

Commit a853031

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 cb7cd81 commit a853031

22 files changed

+843
-325
lines changed

core/config/engine.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,15 @@ bool Engine::is_embedded_in_editor() const {
430430
return embedded_in_editor;
431431
}
432432

433+
void Engine::add_embedded_subwindow(const String &p_subwindow_title, int64_t p_parent_id) {
434+
embedded_subwindows[p_subwindow_title] = p_parent_id;
435+
}
436+
437+
int64_t Engine::get_embedded_subwindow(const String &p_subwindow_title) {
438+
const int64_t *ret = embedded_subwindows.getptr(p_subwindow_title);
439+
return ret ? *ret : 0;
440+
}
441+
433442
Engine::Engine() {
434443
singleton = this;
435444
}

core/config/engine.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ class Engine {
9393
bool project_manager_hint = false;
9494
bool extension_reloading = false;
9595
bool embedded_in_editor = false;
96+
HashMap<String, int64_t> embedded_subwindows;
9697
bool recovery_mode_hint = false;
9798

9899
bool _print_header = true;
@@ -159,6 +160,8 @@ class Engine {
159160
void set_frame_delay(uint32_t p_msec);
160161
uint32_t get_frame_delay() const;
161162

163+
void add_embedded_subwindow(const String &p_subwindow_title, int64_t p_parent_id);
164+
int64_t get_embedded_subwindow(const String &p_subwindow_title);
162165
void add_singleton(const Singleton &p_singleton);
163166
void get_singletons(List<Singleton> *p_singletons);
164167
bool has_singleton(const StringName &p_name) const;

editor/run/embedded_process.cpp

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

189-
void EmbeddedProcess::embed_process(OS::ProcessID p_pid) {
189+
void EmbeddedProcess::embed_process(OS::ProcessID p_pid, const String &p_embedded_window) {
190190
if (!window) {
191191
return;
192192
}
@@ -201,6 +201,7 @@ void EmbeddedProcess::embed_process(OS::ProcessID p_pid) {
201201
reset();
202202

203203
current_process_id = p_pid;
204+
current_embedded_window = p_embedded_window;
204205
start_embedding_time = OS::get_singleton()->get_ticks_msec();
205206
embedding_grab_focus = has_focus();
206207
timer_update_embedded_process->start();
@@ -214,7 +215,7 @@ void EmbeddedProcess::embed_process(OS::ProcessID p_pid) {
214215

215216
void EmbeddedProcess::reset() {
216217
if (current_process_id != 0 && embedding_completed) {
217-
DisplayServer::get_singleton()->remove_embedded_process(current_process_id);
218+
DisplayServer::get_singleton()->remove_embedded_process(current_process_id, current_embedded_window);
218219
}
219220
current_process_id = 0;
220221
embedding_completed = false;
@@ -235,7 +236,7 @@ void EmbeddedProcess::request_close() {
235236

236237
void EmbeddedProcess::_try_embed_process() {
237238
bool is_visible = is_visible_in_tree();
238-
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);
239+
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);
239240
if (err == OK) {
240241
embedding_completed = true;
241242
queue_redraw();
@@ -294,7 +295,7 @@ void EmbeddedProcess::_update_embedded_process() {
294295
last_updated_embedded_process_focused = focus;
295296
}
296297

297-
DisplayServer::get_singleton()->embed_process(window->get_window_id(), current_process_id, get_screen_embedded_window_rect(), is_visible_in_tree(), must_grab_focus);
298+
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);
298299
emit_signal(SNAME("embedded_process_updated"));
299300
}
300301

editor/run/embedded_process.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ class EmbeddedProcessBase : public Control {
6363
virtual bool is_embedding_completed() const = 0;
6464
virtual bool is_embedding_in_progress() const = 0;
6565
virtual bool is_process_focused() const = 0;
66-
virtual void embed_process(OS::ProcessID p_pid) = 0;
66+
virtual void embed_process(OS::ProcessID p_pid, const String &p_embedded_window) = 0;
6767
virtual int get_embedded_pid() const = 0;
6868
virtual void reset() = 0;
6969
virtual void request_close() = 0;
@@ -87,6 +87,7 @@ class EmbeddedProcess : public EmbeddedProcessBase {
8787
uint64_t last_application_focus_time = 0;
8888
OS::ProcessID focused_process_id = 0;
8989
OS::ProcessID current_process_id = 0;
90+
String current_embedded_window;
9091
bool embedding_grab_focus = false;
9192
bool embedding_completed = false;
9293
uint64_t start_embedding_time = 0;
@@ -116,8 +117,8 @@ class EmbeddedProcess : public EmbeddedProcessBase {
116117
bool is_embedding_in_progress() const override;
117118
bool is_embedding_completed() const override;
118119
bool is_process_focused() const override;
119-
void embed_process(OS::ProcessID p_pid) override;
120120
int get_embedded_pid() const override;
121+
void embed_process(OS::ProcessID p_pid, const String &p_embedded_window) override;
121122
void reset() override;
122123
void request_close() override;
123124
void queue_update_embedded_process() override;

0 commit comments

Comments
 (0)