mirror of
https://github.com/godotengine/godot.git
synced 2025-10-19 16:03:29 +00:00
MacOS: Additional improvements and fixes for embedded window support
This commit is contained in:
parent
6a6a1168a5
commit
9290adee38
5 changed files with 50 additions and 13 deletions
|
@ -515,11 +515,9 @@ GameView::EmbedAvailability GameView::_get_embed_available() {
|
||||||
if (!DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_WINDOW_EMBEDDING)) {
|
if (!DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_WINDOW_EMBEDDING)) {
|
||||||
return EMBED_NOT_AVAILABLE_FEATURE_NOT_SUPPORTED;
|
return EMBED_NOT_AVAILABLE_FEATURE_NOT_SUPPORTED;
|
||||||
}
|
}
|
||||||
#ifndef MACOS_ENABLED
|
|
||||||
if (get_tree()->get_root()->is_embedding_subwindows()) {
|
if (get_tree()->get_root()->is_embedding_subwindows()) {
|
||||||
return EMBED_NOT_AVAILABLE_SINGLE_WINDOW_MODE;
|
return EMBED_NOT_AVAILABLE_SINGLE_WINDOW_MODE;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
String display_driver = GLOBAL_GET("display/display_server/driver");
|
String display_driver = GLOBAL_GET("display/display_server/driver");
|
||||||
if (display_driver == "headless" || display_driver == "wayland") {
|
if (display_driver == "headless" || display_driver == "wayland") {
|
||||||
return EMBED_NOT_AVAILABLE_PROJECT_DISPLAY_DRIVER;
|
return EMBED_NOT_AVAILABLE_PROJECT_DISPLAY_DRIVER;
|
||||||
|
@ -835,11 +833,16 @@ void GameView::_update_arguments_for_instance(int p_idx, List<String> &r_argumen
|
||||||
// Remove duplicates/unwanted parameters.
|
// Remove duplicates/unwanted parameters.
|
||||||
List<String>::Element *E = r_arguments.front();
|
List<String>::Element *E = r_arguments.front();
|
||||||
List<String>::Element *user_args_element = nullptr;
|
List<String>::Element *user_args_element = nullptr;
|
||||||
|
HashSet<String> remove_args({ "--position", "--resolution", "--screen" });
|
||||||
|
#ifdef MACOS_ENABLED
|
||||||
|
// macOS requires the embedded display driver.
|
||||||
|
remove_args.insert("--display-driver");
|
||||||
|
#endif
|
||||||
while (E) {
|
while (E) {
|
||||||
List<String>::Element *N = E->next();
|
List<String>::Element *N = E->next();
|
||||||
|
|
||||||
//For these parameters, we need to also renove the value.
|
// For these parameters, we need to also remove the value.
|
||||||
if (E->get() == "--position" || E->get() == "--resolution" || E->get() == "--screen") {
|
if (remove_args.has(E->get())) {
|
||||||
r_arguments.erase(E);
|
r_arguments.erase(E);
|
||||||
if (N) {
|
if (N) {
|
||||||
List<String>::Element *V = N->next();
|
List<String>::Element *V = N->next();
|
||||||
|
@ -861,8 +864,6 @@ void GameView::_update_arguments_for_instance(int p_idx, List<String> &r_argumen
|
||||||
N = r_arguments.insert_after(N, itos(DisplayServer::get_singleton()->window_get_native_handle(DisplayServer::WINDOW_HANDLE, get_window()->get_window_id())));
|
N = r_arguments.insert_after(N, itos(DisplayServer::get_singleton()->window_get_native_handle(DisplayServer::WINDOW_HANDLE, get_window()->get_window_id())));
|
||||||
|
|
||||||
#if MACOS_ENABLED
|
#if MACOS_ENABLED
|
||||||
r_arguments.push_back("--display-driver");
|
|
||||||
r_arguments.push_back("embedded");
|
|
||||||
r_arguments.push_back("--embedded");
|
r_arguments.push_back("--embedded");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -287,6 +287,7 @@ bool profile_gpu = false;
|
||||||
// Constants.
|
// Constants.
|
||||||
|
|
||||||
static const String NULL_DISPLAY_DRIVER("headless");
|
static const String NULL_DISPLAY_DRIVER("headless");
|
||||||
|
static const String EMBEDDED_DISPLAY_DRIVER("embedded");
|
||||||
static const String NULL_AUDIO_DRIVER("Dummy");
|
static const String NULL_AUDIO_DRIVER("Dummy");
|
||||||
|
|
||||||
// The length of the longest column in the command-line help we should align to
|
// The length of the longest column in the command-line help we should align to
|
||||||
|
@ -1397,6 +1398,10 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
|
||||||
audio_driver = NULL_AUDIO_DRIVER;
|
audio_driver = NULL_AUDIO_DRIVER;
|
||||||
display_driver = NULL_DISPLAY_DRIVER;
|
display_driver = NULL_DISPLAY_DRIVER;
|
||||||
|
|
||||||
|
} else if (arg == "--embedded") { // Enable embedded mode.
|
||||||
|
|
||||||
|
display_driver = EMBEDDED_DISPLAY_DRIVER;
|
||||||
|
|
||||||
} else if (arg == "--log-file") { // write to log file
|
} else if (arg == "--log-file") { // write to log file
|
||||||
|
|
||||||
if (N) {
|
if (N) {
|
||||||
|
|
|
@ -33,11 +33,13 @@
|
||||||
#include "editor/plugins/embedded_process.h"
|
#include "editor/plugins/embedded_process.h"
|
||||||
|
|
||||||
class DisplayServerMacOS;
|
class DisplayServerMacOS;
|
||||||
|
class EmbeddedProcessMacOS;
|
||||||
|
|
||||||
class LayerHost : public Control {
|
class LayerHost final : public Control {
|
||||||
GDCLASS(LayerHost, Control);
|
GDCLASS(LayerHost, Control);
|
||||||
|
|
||||||
ScriptEditorDebugger *script_debugger = nullptr;
|
ScriptEditorDebugger *script_debugger = nullptr;
|
||||||
|
EmbeddedProcessMacOS *process = nullptr;
|
||||||
|
|
||||||
virtual void gui_input(const Ref<InputEvent> &p_event) override;
|
virtual void gui_input(const Ref<InputEvent> &p_event) override;
|
||||||
|
|
||||||
|
@ -48,6 +50,8 @@ public:
|
||||||
void set_script_debugger(ScriptEditorDebugger *p_debugger) {
|
void set_script_debugger(ScriptEditorDebugger *p_debugger) {
|
||||||
script_debugger = p_debugger;
|
script_debugger = p_debugger;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LayerHost(EmbeddedProcessMacOS *p_process);
|
||||||
};
|
};
|
||||||
|
|
||||||
class EmbeddedProcessMacOS final : public EmbeddedProcessBase {
|
class EmbeddedProcessMacOS final : public EmbeddedProcessBase {
|
||||||
|
@ -69,9 +73,11 @@ class EmbeddedProcessMacOS final : public EmbeddedProcessBase {
|
||||||
|
|
||||||
// Embedded process state.
|
// Embedded process state.
|
||||||
|
|
||||||
/// @brief The current mouse mode of the embedded process.
|
// The last mouse mode sent by the embedded process.
|
||||||
DisplayServer::MouseMode mouse_mode = DisplayServer::MOUSE_MODE_VISIBLE;
|
DisplayServer::MouseMode mouse_mode = DisplayServer::MOUSE_MODE_VISIBLE;
|
||||||
|
|
||||||
|
// Helper functions.
|
||||||
|
|
||||||
void _try_embed_process();
|
void _try_embed_process();
|
||||||
void update_embedded_process() const;
|
void update_embedded_process() const;
|
||||||
void _joy_connection_changed(int p_index, bool p_connected) const;
|
void _joy_connection_changed(int p_index, bool p_connected) const;
|
||||||
|
@ -81,7 +87,9 @@ protected:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// MARK: - Message Handlers
|
// MARK: - Message Handlers
|
||||||
|
|
||||||
void set_context_id(uint32_t p_context_id);
|
void set_context_id(uint32_t p_context_id);
|
||||||
|
void mouse_set_mode(DisplayServer::MouseMode p_mode);
|
||||||
|
|
||||||
uint32_t get_context_id() const { return context_id; }
|
uint32_t get_context_id() const { return context_id; }
|
||||||
void set_script_debugger(ScriptEditorDebugger *p_debugger) override;
|
void set_script_debugger(ScriptEditorDebugger *p_debugger) override;
|
||||||
|
@ -90,7 +98,7 @@ public:
|
||||||
return embedding_state == EmbeddingState::IN_PROGRESS;
|
return embedding_state == EmbeddingState::IN_PROGRESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_embedding_completed() const override {
|
_FORCE_INLINE_ bool is_embedding_completed() const override {
|
||||||
return embedding_state == EmbeddingState::COMPLETED;
|
return embedding_state == EmbeddingState::COMPLETED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,8 +111,10 @@ public:
|
||||||
|
|
||||||
Rect2i get_adjusted_embedded_window_rect(const Rect2i &p_rect) const override;
|
Rect2i get_adjusted_embedded_window_rect(const Rect2i &p_rect) const override;
|
||||||
|
|
||||||
void mouse_set_mode(DisplayServer::MouseMode p_mode);
|
|
||||||
_FORCE_INLINE_ LayerHost *get_layer_host() const { return layer_host; }
|
_FORCE_INLINE_ LayerHost *get_layer_host() const { return layer_host; }
|
||||||
|
|
||||||
|
// MARK: - Embedded process state
|
||||||
|
_FORCE_INLINE_ DisplayServer::MouseMode get_mouse_mode() const { return mouse_mode; }
|
||||||
|
|
||||||
EmbeddedProcessMacOS();
|
EmbeddedProcessMacOS();
|
||||||
};
|
};
|
||||||
|
|
|
@ -34,6 +34,8 @@
|
||||||
|
|
||||||
#include "core/input/input_event_codec.h"
|
#include "core/input/input_event_codec.h"
|
||||||
#include "editor/debugger/script_editor_debugger.h"
|
#include "editor/debugger/script_editor_debugger.h"
|
||||||
|
#include "editor/editor_main_screen.h"
|
||||||
|
#include "editor/editor_node.h"
|
||||||
#include "editor/editor_settings.h"
|
#include "editor/editor_settings.h"
|
||||||
#include "scene/gui/control.h"
|
#include "scene/gui/control.h"
|
||||||
#include "scene/main/window.h"
|
#include "scene/main/window.h"
|
||||||
|
@ -182,12 +184,18 @@ Rect2i EmbeddedProcessMacOS::get_adjusted_embedded_window_rect(const Rect2i &p_r
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmbeddedProcessMacOS::mouse_set_mode(DisplayServer::MouseMode p_mode) {
|
void EmbeddedProcessMacOS::mouse_set_mode(DisplayServer::MouseMode p_mode) {
|
||||||
|
mouse_mode = p_mode;
|
||||||
|
// If the mouse is anything other than visible, we must ensure the Game view is active and the layer focused.
|
||||||
|
if (mouse_mode != DisplayServer::MOUSE_MODE_VISIBLE) {
|
||||||
|
EditorNode::get_singleton()->get_editor_main_screen()->select(EditorMainScreen::EDITOR_GAME);
|
||||||
|
layer_host->grab_focus();
|
||||||
|
}
|
||||||
DisplayServer::get_singleton()->mouse_set_mode(p_mode);
|
DisplayServer::get_singleton()->mouse_set_mode(p_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
EmbeddedProcessMacOS::EmbeddedProcessMacOS() :
|
EmbeddedProcessMacOS::EmbeddedProcessMacOS() :
|
||||||
EmbeddedProcessBase() {
|
EmbeddedProcessBase() {
|
||||||
layer_host = memnew(LayerHost);
|
layer_host = memnew(LayerHost(this));
|
||||||
add_child(layer_host);
|
add_child(layer_host);
|
||||||
layer_host->set_focus_mode(FOCUS_ALL);
|
layer_host->set_focus_mode(FOCUS_ALL);
|
||||||
layer_host->set_anchors_and_offsets_preset(PRESET_FULL_RECT);
|
layer_host->set_anchors_and_offsets_preset(PRESET_FULL_RECT);
|
||||||
|
@ -207,11 +215,22 @@ void LayerHost::_notification(int p_what) {
|
||||||
if (script_debugger) {
|
if (script_debugger) {
|
||||||
script_debugger->send_message("embed:win_event", { DisplayServer::WINDOW_EVENT_MOUSE_ENTER });
|
script_debugger->send_message("embed:win_event", { DisplayServer::WINDOW_EVENT_MOUSE_ENTER });
|
||||||
}
|
}
|
||||||
|
// Temporarily release mouse capture, so we can interact with the editor.
|
||||||
|
DisplayServer *ds = DisplayServer::get_singleton();
|
||||||
|
if (process->get_mouse_mode() != ds->mouse_get_mode()) {
|
||||||
|
// Restore embedded process mouse mode.
|
||||||
|
ds->mouse_set_mode(process->get_mouse_mode());
|
||||||
|
}
|
||||||
} break;
|
} break;
|
||||||
case NOTIFICATION_FOCUS_EXIT: {
|
case NOTIFICATION_FOCUS_EXIT: {
|
||||||
if (script_debugger) {
|
if (script_debugger) {
|
||||||
script_debugger->send_message("embed:win_event", { DisplayServer::WINDOW_EVENT_MOUSE_EXIT });
|
script_debugger->send_message("embed:win_event", { DisplayServer::WINDOW_EVENT_MOUSE_EXIT });
|
||||||
}
|
}
|
||||||
|
// Temporarily set mouse state back to visible, so the user can interact with the editor.
|
||||||
|
DisplayServer *ds = DisplayServer::get_singleton();
|
||||||
|
if (ds->mouse_get_mode() != DisplayServer::MOUSE_MODE_VISIBLE) {
|
||||||
|
ds->mouse_set_mode(DisplayServer::MOUSE_MODE_VISIBLE);
|
||||||
|
}
|
||||||
} break;
|
} break;
|
||||||
case MainLoop::NOTIFICATION_OS_IME_UPDATE: {
|
case MainLoop::NOTIFICATION_OS_IME_UPDATE: {
|
||||||
if (script_debugger && has_focus()) {
|
if (script_debugger && has_focus()) {
|
||||||
|
@ -224,7 +243,7 @@ void LayerHost::_notification(int p_what) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void LayerHost::gui_input(const Ref<InputEvent> &p_event) {
|
void LayerHost::gui_input(const Ref<InputEvent> &p_event) {
|
||||||
if (!script_debugger) {
|
if (!process->is_embedding_completed()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -246,3 +265,6 @@ void LayerHost::gui_input(const Ref<InputEvent> &p_event) {
|
||||||
accept_event();
|
accept_event();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LayerHost::LayerHost(EmbeddedProcessMacOS *p_process) :
|
||||||
|
process(p_process) {}
|
||||||
|
|
|
@ -74,7 +74,6 @@ int main(int argc, char **argv) {
|
||||||
|
|
||||||
if (strcmp("--embedded", argv[i]) == 0) {
|
if (strcmp("--embedded", argv[i]) == 0) {
|
||||||
is_embedded = true;
|
is_embedded = true;
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
args.ptr()[argsc] = argv[i];
|
args.ptr()[argsc] = argv[i];
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue