You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-04 12:00:25 +00:00
macOS: Embedded window can be dismissed by clicking close
- Installed a SIGINT handler to terminate the application gracefully. - Handle varying display scaling
This commit is contained in:
@@ -131,6 +131,8 @@ static void _setup_clock() {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
struct sigaction old_action;
|
||||||
|
|
||||||
static void handle_interrupt(int sig) {
|
static void handle_interrupt(int sig) {
|
||||||
if (!EngineDebugger::is_active()) {
|
if (!EngineDebugger::is_active()) {
|
||||||
return;
|
return;
|
||||||
@@ -138,6 +140,11 @@ static void handle_interrupt(int sig) {
|
|||||||
|
|
||||||
EngineDebugger::get_script_debugger()->set_depth(-1);
|
EngineDebugger::get_script_debugger()->set_depth(-1);
|
||||||
EngineDebugger::get_script_debugger()->set_lines_left(1);
|
EngineDebugger::get_script_debugger()->set_lines_left(1);
|
||||||
|
|
||||||
|
// Ensure we call the old action if it was configured.
|
||||||
|
if (old_action.sa_handler && old_action.sa_handler != SIG_IGN && old_action.sa_handler != SIG_DFL) {
|
||||||
|
old_action.sa_handler(sig);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OS_Unix::initialize_debugging() {
|
void OS_Unix::initialize_debugging() {
|
||||||
@@ -145,7 +152,7 @@ void OS_Unix::initialize_debugging() {
|
|||||||
struct sigaction action;
|
struct sigaction action;
|
||||||
memset(&action, 0, sizeof(action));
|
memset(&action, 0, sizeof(action));
|
||||||
action.sa_handler = handle_interrupt;
|
action.sa_handler = handle_interrupt;
|
||||||
sigaction(SIGINT, &action, nullptr);
|
sigaction(SIGINT, &action, &old_action);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -864,7 +864,7 @@ 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("--embedded");
|
N = r_arguments.insert_after(N, "--embedded");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Be sure to have the correct window size in the embedded_process control.
|
// Be sure to have the correct window size in the embedded_process control.
|
||||||
|
|||||||
@@ -1399,9 +1399,12 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
|
|||||||
display_driver = NULL_DISPLAY_DRIVER;
|
display_driver = NULL_DISPLAY_DRIVER;
|
||||||
|
|
||||||
} else if (arg == "--embedded") { // Enable embedded mode.
|
} else if (arg == "--embedded") { // Enable embedded mode.
|
||||||
|
#ifdef MACOS_ENABLED
|
||||||
display_driver = EMBEDDED_DISPLAY_DRIVER;
|
display_driver = EMBEDDED_DISPLAY_DRIVER;
|
||||||
|
#else
|
||||||
|
OS::get_singleton()->print("--embedded is only supported on macOS, aborting.\n");
|
||||||
|
goto error;
|
||||||
|
#endif
|
||||||
} else if (arg == "--log-file") { // write to log file
|
} else if (arg == "--log-file") { // write to log file
|
||||||
|
|
||||||
if (N) {
|
if (N) {
|
||||||
|
|||||||
@@ -33,33 +33,27 @@
|
|||||||
#include "core/input/input.h"
|
#include "core/input/input.h"
|
||||||
#include "servers/display_server.h"
|
#include "servers/display_server.h"
|
||||||
|
|
||||||
#if defined(GLES3_ENABLED)
|
|
||||||
#include "embedded_gl_manager.h"
|
|
||||||
#include "platform_gl.h"
|
|
||||||
#endif // GLES3_ENABLED
|
|
||||||
|
|
||||||
#if defined(RD_ENABLED)
|
|
||||||
#include "servers/rendering/rendering_device.h"
|
|
||||||
|
|
||||||
#if defined(VULKAN_ENABLED)
|
|
||||||
#import "rendering_context_driver_vulkan_macos.h"
|
|
||||||
#endif // VULKAN_ENABLED
|
|
||||||
#if defined(METAL_ENABLED)
|
|
||||||
#import "drivers/metal/rendering_context_driver_metal.h"
|
|
||||||
#endif
|
|
||||||
#endif // RD_ENABLED
|
|
||||||
|
|
||||||
@class CAContext;
|
@class CAContext;
|
||||||
|
@class CALayer;
|
||||||
|
class GLManagerEmbedded;
|
||||||
|
class RenderingContextDriver;
|
||||||
|
class RenderingDevice;
|
||||||
|
|
||||||
|
struct DisplayServerEmbeddedState {
|
||||||
|
/// Default to a scale of 2.0, which is the most common.
|
||||||
|
float screen_max_scale = 2.0f;
|
||||||
|
float screen_dpi = 96.0f;
|
||||||
|
|
||||||
|
void serialize(PackedByteArray &r_data);
|
||||||
|
Error deserialize(const PackedByteArray &p_data);
|
||||||
|
};
|
||||||
|
|
||||||
class DisplayServerEmbedded : public DisplayServer {
|
class DisplayServerEmbedded : public DisplayServer {
|
||||||
GDCLASS(DisplayServerEmbedded, DisplayServer)
|
GDCLASS(DisplayServerEmbedded, DisplayServer)
|
||||||
|
|
||||||
_THREAD_SAFE_CLASS_
|
_THREAD_SAFE_CLASS_
|
||||||
|
|
||||||
struct {
|
DisplayServerEmbeddedState state;
|
||||||
float screen_max_scale = 1.0f;
|
|
||||||
float screen_dpi = 96.0f;
|
|
||||||
} state;
|
|
||||||
|
|
||||||
NativeMenu *native_menu = nullptr;
|
NativeMenu *native_menu = nullptr;
|
||||||
|
|
||||||
@@ -70,13 +64,11 @@ class DisplayServerEmbedded : public DisplayServer {
|
|||||||
HashMap<WindowID, Callable> input_event_callbacks;
|
HashMap<WindowID, Callable> input_event_callbacks;
|
||||||
HashMap<WindowID, Callable> input_text_callbacks;
|
HashMap<WindowID, Callable> input_text_callbacks;
|
||||||
|
|
||||||
float content_scale = 1.0f;
|
|
||||||
|
|
||||||
WindowID window_id_counter = MAIN_WINDOW_ID;
|
WindowID window_id_counter = MAIN_WINDOW_ID;
|
||||||
|
|
||||||
CAContext *ca_context = nil;
|
CAContext *ca_context = nullptr;
|
||||||
// Either be a CAMetalLayer or a CALayer depending on the rendering driver.
|
// Either be a CAMetalLayer or a CALayer depending on the rendering driver.
|
||||||
CALayer *layer = nil;
|
CALayer *layer = nullptr;
|
||||||
#ifdef GLES3_ENABLED
|
#ifdef GLES3_ENABLED
|
||||||
GLManagerEmbedded *gl_manager = nullptr;
|
GLManagerEmbedded *gl_manager = nullptr;
|
||||||
#endif
|
#endif
|
||||||
@@ -222,8 +214,7 @@ public:
|
|||||||
virtual CursorShape cursor_get_shape() const override;
|
virtual CursorShape cursor_get_shape() const override;
|
||||||
virtual void cursor_set_custom_image(const Ref<Resource> &p_cursor, CursorShape p_shape = CURSOR_ARROW, const Vector2 &p_hotspot = Vector2()) override;
|
virtual void cursor_set_custom_image(const Ref<Resource> &p_cursor, CursorShape p_shape = CURSOR_ARROW, const Vector2 &p_hotspot = Vector2()) override;
|
||||||
|
|
||||||
void update_state(const Dictionary &p_state);
|
void set_state(const DisplayServerEmbeddedState &p_state);
|
||||||
void set_content_scale(float p_scale);
|
|
||||||
virtual void swap_buffers() override;
|
virtual void swap_buffers() override;
|
||||||
|
|
||||||
DisplayServerEmbedded(const String &p_rendering_driver, DisplayServer::WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Context p_context, Error &r_error);
|
DisplayServerEmbedded(const String &p_rendering_driver, DisplayServer::WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Context p_context, Error &r_error);
|
||||||
|
|||||||
@@ -30,19 +30,31 @@
|
|||||||
|
|
||||||
#import "display_server_embedded.h"
|
#import "display_server_embedded.h"
|
||||||
|
|
||||||
|
#if defined(GLES3_ENABLED)
|
||||||
|
#import "embedded_gl_manager.h"
|
||||||
|
#import "platform_gl.h"
|
||||||
|
|
||||||
|
#import "drivers/gles3/rasterizer_gles3.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(RD_ENABLED)
|
||||||
|
#import "servers/rendering/renderer_rd/renderer_compositor_rd.h"
|
||||||
|
#import "servers/rendering/rendering_device.h"
|
||||||
|
|
||||||
|
#if defined(VULKAN_ENABLED)
|
||||||
|
#import "rendering_context_driver_vulkan_macos.h"
|
||||||
|
#endif // VULKAN_ENABLED
|
||||||
|
#if defined(METAL_ENABLED)
|
||||||
|
#import "drivers/metal/rendering_context_driver_metal.h"
|
||||||
|
#endif
|
||||||
|
#endif // RD_ENABLED
|
||||||
|
|
||||||
#import "embedded_debugger.h"
|
#import "embedded_debugger.h"
|
||||||
#import "macos_quartz_core_spi.h"
|
#import "macos_quartz_core_spi.h"
|
||||||
|
|
||||||
#import "core/config/project_settings.h"
|
#import "core/config/project_settings.h"
|
||||||
#import "core/debugger/engine_debugger.h"
|
#import "core/debugger/engine_debugger.h"
|
||||||
|
#import "core/io/marshalls.h"
|
||||||
#if defined(GLES3_ENABLED)
|
|
||||||
#include "drivers/gles3/rasterizer_gles3.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(RD_ENABLED)
|
|
||||||
#import "servers/rendering/renderer_rd/renderer_compositor_rd.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
DisplayServerEmbedded::DisplayServerEmbedded(const String &p_rendering_driver, WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Context p_context, Error &r_error) {
|
DisplayServerEmbedded::DisplayServerEmbedded(const String &p_rendering_driver, WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Context p_context, Error &r_error) {
|
||||||
EmbeddedDebugger::initialize(this);
|
EmbeddedDebugger::initialize(this);
|
||||||
@@ -176,15 +188,15 @@ DisplayServerEmbedded::DisplayServerEmbedded(const String &p_rendering_driver, W
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
constexpr CGFloat CONTENT_SCALE = 2.0;
|
CGFloat scale = screen_get_max_scale();
|
||||||
layer.contentsScale = CONTENT_SCALE;
|
layer.contentsScale = scale;
|
||||||
layer.magnificationFilter = kCAFilterNearest;
|
layer.magnificationFilter = kCAFilterNearest;
|
||||||
layer.minificationFilter = kCAFilterNearest;
|
layer.minificationFilter = kCAFilterNearest;
|
||||||
layer.opaque = NO; // Never opaque when embedded.
|
layer.opaque = YES; // Always opaque when embedded.
|
||||||
layer.actions = @{ @"contents" : [NSNull null] }; // Disable implicit animations for contents.
|
layer.actions = @{ @"contents" : [NSNull null] }; // Disable implicit animations for contents.
|
||||||
// AppKit frames, bounds and positions are always in points.
|
// AppKit frames, bounds and positions are always in points.
|
||||||
CGRect bounds = CGRectMake(0, 0, p_resolution.width, p_resolution.height);
|
CGRect bounds = CGRectMake(0, 0, p_resolution.width, p_resolution.height);
|
||||||
bounds = CGRectApplyAffineTransform(bounds, CGAffineTransformMakeScale(1.0 / CONTENT_SCALE, 1.0 / CONTENT_SCALE));
|
bounds = CGRectApplyAffineTransform(bounds, CGAffineTransformInvert(CGAffineTransformMakeScale(scale, scale)));
|
||||||
layer.bounds = bounds;
|
layer.bounds = bounds;
|
||||||
|
|
||||||
CGSConnectionID connection_id = CGSMainConnectionID();
|
CGSConnectionID connection_id = CGSMainConnectionID();
|
||||||
@@ -582,11 +594,11 @@ void DisplayServerEmbedded::window_set_size(const Size2i p_size, WindowID p_wind
|
|||||||
[CATransaction begin];
|
[CATransaction begin];
|
||||||
[CATransaction setDisableActions:YES];
|
[CATransaction setDisableActions:YES];
|
||||||
|
|
||||||
// TODO(sgc): Pass scale as argument from parent process.
|
CGFloat scale = screen_get_max_scale();
|
||||||
constexpr CGFloat CONTENT_SCALE = 2.0;
|
|
||||||
CGRect bounds = CGRectMake(0, 0, p_size.width, p_size.height);
|
CGRect bounds = CGRectMake(0, 0, p_size.width, p_size.height);
|
||||||
bounds = CGRectApplyAffineTransform(bounds, CGAffineTransformMakeScale(1.0 / CONTENT_SCALE, 1.0 / CONTENT_SCALE));
|
bounds = CGRectApplyAffineTransform(bounds, CGAffineTransformInvert(CGAffineTransformMakeScale(scale, scale)));
|
||||||
layer.bounds = bounds;
|
layer.bounds = bounds;
|
||||||
|
layer.contentsScale = scale;
|
||||||
|
|
||||||
#if defined(RD_ENABLED)
|
#if defined(RD_ENABLED)
|
||||||
if (rendering_context) {
|
if (rendering_context) {
|
||||||
@@ -685,12 +697,8 @@ void DisplayServerEmbedded::window_set_ime_position(const Point2i &p_pos, Window
|
|||||||
ime_last_position = p_pos;
|
ime_last_position = p_pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DisplayServerEmbedded::update_state(const Dictionary &p_state) {
|
void DisplayServerEmbedded::set_state(const DisplayServerEmbeddedState &p_state) {
|
||||||
state.screen_max_scale = p_state["screen_get_max_scale"];
|
state = p_state;
|
||||||
}
|
|
||||||
|
|
||||||
void DisplayServerEmbedded::set_content_scale(float p_scale) {
|
|
||||||
content_scale = p_scale;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DisplayServerEmbedded::window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window) {
|
void DisplayServerEmbedded::window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window) {
|
||||||
@@ -742,3 +750,24 @@ void DisplayServerEmbedded::swap_buffers() {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DisplayServerEmbeddedState::serialize(PackedByteArray &r_data) {
|
||||||
|
r_data.resize(8);
|
||||||
|
|
||||||
|
uint8_t *data = r_data.ptrw();
|
||||||
|
data += encode_float(screen_max_scale, data);
|
||||||
|
data += encode_float(screen_dpi, data);
|
||||||
|
|
||||||
|
// Assert we had enough space.
|
||||||
|
DEV_ASSERT(data - r_data.ptrw() >= r_data.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
Error DisplayServerEmbeddedState::deserialize(const PackedByteArray &p_data) {
|
||||||
|
const uint8_t *data = p_data.ptr();
|
||||||
|
|
||||||
|
screen_max_scale = decode_float(data);
|
||||||
|
data += sizeof(float);
|
||||||
|
screen_dpi = decode_float(data);
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|||||||
@@ -3297,6 +3297,7 @@ Error DisplayServerMacOS::embed_process_update(WindowID p_window, const Embedded
|
|||||||
[CATransaction setDisableActions:YES];
|
[CATransaction setDisableActions:YES];
|
||||||
|
|
||||||
EmbeddedProcessData *ed = embedded_processes.getptr(p_pid);
|
EmbeddedProcessData *ed = embedded_processes.getptr(p_pid);
|
||||||
|
CGFloat scale = screen_get_max_scale();
|
||||||
if (ed == nil) {
|
if (ed == nil) {
|
||||||
ed = &embedded_processes.insert(p_pid, EmbeddedProcessData())->value;
|
ed = &embedded_processes.insert(p_pid, EmbeddedProcessData())->value;
|
||||||
|
|
||||||
@@ -3305,7 +3306,7 @@ Error DisplayServerMacOS::embed_process_update(WindowID p_window, const Embedded
|
|||||||
CALayerHost *host = [CALayerHost new];
|
CALayerHost *host = [CALayerHost new];
|
||||||
uint32_t p_context_id = p_process->get_context_id();
|
uint32_t p_context_id = p_process->get_context_id();
|
||||||
host.contextId = static_cast<CAContextID>(p_context_id);
|
host.contextId = static_cast<CAContextID>(p_context_id);
|
||||||
host.contentsScale = wd->window_object.backingScaleFactor;
|
host.contentsScale = scale;
|
||||||
host.contentsGravity = kCAGravityCenter;
|
host.contentsGravity = kCAGravityCenter;
|
||||||
ed->layer_host = host;
|
ed->layer_host = host;
|
||||||
[wd->window_view.layer addSublayer:host];
|
[wd->window_view.layer addSublayer:host];
|
||||||
@@ -3313,7 +3314,7 @@ Error DisplayServerMacOS::embed_process_update(WindowID p_window, const Embedded
|
|||||||
|
|
||||||
Rect2i p_rect = p_process->get_screen_embedded_window_rect();
|
Rect2i p_rect = p_process->get_screen_embedded_window_rect();
|
||||||
CGRect rect = CGRectMake(p_rect.position.x, p_rect.position.y, p_rect.size.x, p_rect.size.y);
|
CGRect rect = CGRectMake(p_rect.position.x, p_rect.position.y, p_rect.size.x, p_rect.size.y);
|
||||||
rect = CGRectApplyAffineTransform(rect, CGAffineTransformMakeScale(0.5, 0.5));
|
rect = CGRectApplyAffineTransform(rect, CGAffineTransformInvert(CGAffineTransformMakeScale(scale, scale)));
|
||||||
|
|
||||||
CGFloat height = wd->window_view.frame.size.height;
|
CGFloat height = wd->window_view.frame.size.height;
|
||||||
CGFloat x = rect.origin.x;
|
CGFloat x = rect.origin.x;
|
||||||
|
|||||||
@@ -102,12 +102,12 @@ public:
|
|||||||
return embedding_state == EmbeddingState::COMPLETED;
|
return embedding_state == EmbeddingState::COMPLETED;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool is_process_focused() const override { return layer_host->has_focus(); }
|
bool is_process_focused() const override { return layer_host->has_focus(); }
|
||||||
virtual void embed_process(OS::ProcessID p_pid) override;
|
void embed_process(OS::ProcessID p_pid) override;
|
||||||
virtual int get_embedded_pid() const override { return current_process_id; }
|
int get_embedded_pid() const override { return current_process_id; }
|
||||||
virtual void reset() override;
|
void reset() override;
|
||||||
virtual void request_close() override;
|
void request_close() override;
|
||||||
virtual void queue_update_embedded_process() override { update_embedded_process(); }
|
void queue_update_embedded_process() override { update_embedded_process(); }
|
||||||
|
|
||||||
Rect2i get_adjusted_embedded_window_rect(const Rect2i &p_rect) const override;
|
Rect2i get_adjusted_embedded_window_rect(const Rect2i &p_rect) const override;
|
||||||
|
|
||||||
@@ -117,4 +117,5 @@ public:
|
|||||||
_FORCE_INLINE_ DisplayServer::MouseMode get_mouse_mode() const { return mouse_mode; }
|
_FORCE_INLINE_ DisplayServer::MouseMode get_mouse_mode() const { return mouse_mode; }
|
||||||
|
|
||||||
EmbeddedProcessMacOS();
|
EmbeddedProcessMacOS();
|
||||||
|
~EmbeddedProcessMacOS() override;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -30,6 +30,7 @@
|
|||||||
|
|
||||||
#include "embedded_process_macos.h"
|
#include "embedded_process_macos.h"
|
||||||
|
|
||||||
|
#include "platform/macos/display_server_embedded.h"
|
||||||
#include "platform/macos/display_server_macos.h"
|
#include "platform/macos/display_server_macos.h"
|
||||||
|
|
||||||
#include "core/input/input_event_codec.h"
|
#include "core/input/input_event_codec.h"
|
||||||
@@ -122,7 +123,7 @@ void EmbeddedProcessMacOS::reset() {
|
|||||||
|
|
||||||
void EmbeddedProcessMacOS::request_close() {
|
void EmbeddedProcessMacOS::request_close() {
|
||||||
if (current_process_id != 0 && is_embedding_completed()) {
|
if (current_process_id != 0 && is_embedding_completed()) {
|
||||||
ds->request_close_embedded_process(current_process_id);
|
script_debugger->send_message("embed:win_event", { DisplayServer::WINDOW_EVENT_CLOSE_REQUEST });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -133,19 +134,22 @@ void EmbeddedProcessMacOS::_try_embed_process() {
|
|||||||
|
|
||||||
Error err = ds->embed_process_update(window->get_window_id(), this);
|
Error err = ds->embed_process_update(window->get_window_id(), this);
|
||||||
if (err == OK) {
|
if (err == OK) {
|
||||||
|
// Replicate some of the DisplayServer state.
|
||||||
|
{
|
||||||
|
DisplayServerEmbeddedState state;
|
||||||
|
state.screen_max_scale = ds->screen_get_max_scale();
|
||||||
|
state.screen_dpi = ds->screen_get_dpi();
|
||||||
|
PackedByteArray data;
|
||||||
|
state.serialize(data);
|
||||||
|
script_debugger->send_message("embed:ds_state", { data });
|
||||||
|
}
|
||||||
|
|
||||||
Rect2i rect = get_screen_embedded_window_rect();
|
Rect2i rect = get_screen_embedded_window_rect();
|
||||||
script_debugger->send_message("embed:window_size", { rect.size });
|
script_debugger->send_message("embed:window_size", { rect.size });
|
||||||
embedding_state = EmbeddingState::COMPLETED;
|
embedding_state = EmbeddingState::COMPLETED;
|
||||||
queue_redraw();
|
queue_redraw();
|
||||||
emit_signal(SNAME("embedding_completed"));
|
emit_signal(SNAME("embedding_completed"));
|
||||||
|
|
||||||
// Replicate some of the DisplayServer state.
|
|
||||||
{
|
|
||||||
Dictionary state;
|
|
||||||
state["screen_get_max_scale"] = ds->screen_get_max_scale();
|
|
||||||
// script_debugger->send_message("embed:ds_state", { state });
|
|
||||||
}
|
|
||||||
|
|
||||||
// Send initial joystick state.
|
// Send initial joystick state.
|
||||||
{
|
{
|
||||||
Input *input = Input::get_singleton();
|
Input *input = Input::get_singleton();
|
||||||
@@ -209,13 +213,21 @@ EmbeddedProcessMacOS::EmbeddedProcessMacOS() :
|
|||||||
ED_SHORTCUT("game_view/release_mouse", TTRC("Release Mouse"), KeyModifierMask::ALT | Key::ESCAPE);
|
ED_SHORTCUT("game_view/release_mouse", TTRC("Release Mouse"), KeyModifierMask::ALT | Key::ESCAPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EmbeddedProcessMacOS::~EmbeddedProcessMacOS() {
|
||||||
|
if (current_process_id != 0) {
|
||||||
|
// Stop embedding the last process.
|
||||||
|
OS::get_singleton()->kill(current_process_id);
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void LayerHost::_notification(int p_what) {
|
void LayerHost::_notification(int p_what) {
|
||||||
switch (p_what) {
|
switch (p_what) {
|
||||||
case NOTIFICATION_FOCUS_ENTER: {
|
case NOTIFICATION_FOCUS_ENTER: {
|
||||||
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.
|
// Restore mouse capture, if necessary.
|
||||||
DisplayServer *ds = DisplayServer::get_singleton();
|
DisplayServer *ds = DisplayServer::get_singleton();
|
||||||
if (process->get_mouse_mode() != ds->mouse_get_mode()) {
|
if (process->get_mouse_mode() != ds->mouse_get_mode()) {
|
||||||
// Restore embedded process mouse mode.
|
// Restore embedded process mouse mode.
|
||||||
|
|||||||
@@ -63,6 +63,7 @@ private:
|
|||||||
Error _msg_ime_update(const Array &p_args);
|
Error _msg_ime_update(const Array &p_args);
|
||||||
Error _msg_joy_add(const Array &p_args);
|
Error _msg_joy_add(const Array &p_args);
|
||||||
Error _msg_joy_del(const Array &p_args);
|
Error _msg_joy_del(const Array &p_args);
|
||||||
|
Error _msg_ds_state(const Array &p_args);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static Error parse_message(void *p_user, const String &p_msg, const Array &p_args, bool &r_captured);
|
static Error parse_message(void *p_user, const String &p_msg, const Array &p_args, bool &r_captured);
|
||||||
|
|||||||
@@ -76,21 +76,25 @@ void EmbeddedDebugger::_init_parse_message_handlers() {
|
|||||||
parse_message_handlers["ime_update"] = &EmbeddedDebugger::_msg_ime_update;
|
parse_message_handlers["ime_update"] = &EmbeddedDebugger::_msg_ime_update;
|
||||||
parse_message_handlers["joy_add"] = &EmbeddedDebugger::_msg_joy_add;
|
parse_message_handlers["joy_add"] = &EmbeddedDebugger::_msg_joy_add;
|
||||||
parse_message_handlers["joy_del"] = &EmbeddedDebugger::_msg_joy_del;
|
parse_message_handlers["joy_del"] = &EmbeddedDebugger::_msg_joy_del;
|
||||||
|
parse_message_handlers["ds_state"] = &EmbeddedDebugger::_msg_ds_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
Error EmbeddedDebugger::_msg_window_size(const Array &p_args) {
|
Error EmbeddedDebugger::_msg_window_size(const Array &p_args) {
|
||||||
|
ERR_FAIL_COND_V_MSG(p_args.size() != 1, ERR_INVALID_PARAMETER, "Invalid number of arguments for 'window_size' message.");
|
||||||
Size2i size = p_args[0];
|
Size2i size = p_args[0];
|
||||||
ds->window_set_size(size);
|
ds->window_set_size(size);
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
Error EmbeddedDebugger::_msg_mouse_set_mode(const Array &p_args) {
|
Error EmbeddedDebugger::_msg_mouse_set_mode(const Array &p_args) {
|
||||||
|
ERR_FAIL_COND_V_MSG(p_args.size() != 1, ERR_INVALID_PARAMETER, "Invalid number of arguments for 'mouse_set_mode' message.");
|
||||||
DisplayServer::MouseMode mode = p_args[0];
|
DisplayServer::MouseMode mode = p_args[0];
|
||||||
ds->mouse_set_mode(mode);
|
ds->mouse_set_mode(mode);
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
Error EmbeddedDebugger::_msg_event(const Array &p_args) {
|
Error EmbeddedDebugger::_msg_event(const Array &p_args) {
|
||||||
|
ERR_FAIL_COND_V_MSG(p_args.size() != 1, ERR_INVALID_PARAMETER, "Invalid number of arguments for 'event' message.");
|
||||||
Input *input = Input::get_singleton();
|
Input *input = Input::get_singleton();
|
||||||
if (!input) {
|
if (!input) {
|
||||||
// Ignore if we've received an event before the process has initialized.
|
// Ignore if we've received an event before the process has initialized.
|
||||||
@@ -130,6 +134,7 @@ Error EmbeddedDebugger::_msg_event(const Array &p_args) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Error EmbeddedDebugger::_msg_win_event(const Array &p_args) {
|
Error EmbeddedDebugger::_msg_win_event(const Array &p_args) {
|
||||||
|
ERR_FAIL_COND_V_MSG(p_args.size() != 1, ERR_INVALID_PARAMETER, "Invalid number of arguments for 'win_event' message.");
|
||||||
DisplayServer::WindowEvent win_event = p_args[0];
|
DisplayServer::WindowEvent win_event = p_args[0];
|
||||||
ds->send_window_event(win_event, DisplayServer::MAIN_WINDOW_ID);
|
ds->send_window_event(win_event, DisplayServer::MAIN_WINDOW_ID);
|
||||||
if (win_event == DisplayServer::WindowEvent::WINDOW_EVENT_MOUSE_EXIT) {
|
if (win_event == DisplayServer::WindowEvent::WINDOW_EVENT_MOUSE_EXIT) {
|
||||||
@@ -161,6 +166,15 @@ Error EmbeddedDebugger::_msg_joy_del(const Array &p_args) {
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Error EmbeddedDebugger::_msg_ds_state(const Array &p_args) {
|
||||||
|
ERR_FAIL_COND_V_MSG(p_args.size() != 1, ERR_INVALID_PARAMETER, "Invalid number of arguments for 'ds_state' message.");
|
||||||
|
PackedByteArray data = p_args[0];
|
||||||
|
DisplayServerEmbeddedState state;
|
||||||
|
state.deserialize(data);
|
||||||
|
ds->set_state(state);
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
Error EmbeddedDebugger::parse_message(void *p_user, const String &p_msg, const Array &p_args, bool &r_captured) {
|
Error EmbeddedDebugger::parse_message(void *p_user, const String &p_msg, const Array &p_args, bool &r_captured) {
|
||||||
EmbeddedDebugger *self = static_cast<EmbeddedDebugger *>(p_user);
|
EmbeddedDebugger *self = static_cast<EmbeddedDebugger *>(p_user);
|
||||||
r_captured = true;
|
r_captured = true;
|
||||||
|
|||||||
@@ -116,7 +116,9 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
os->run();
|
os->run();
|
||||||
|
|
||||||
|
int exit_code = os->get_exit_code();
|
||||||
|
|
||||||
memdelete(os);
|
memdelete(os);
|
||||||
|
|
||||||
return os->get_exit_code();
|
return exit_code;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -923,6 +923,14 @@ void OS_MacOS_NSApp::run() {
|
|||||||
[NSApp run];
|
[NSApp run];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool sig_received = false;
|
||||||
|
|
||||||
|
static void handle_interrupt(int sig) {
|
||||||
|
if (sig == SIGINT) {
|
||||||
|
sig_received = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void OS_MacOS_NSApp::start_main() {
|
void OS_MacOS_NSApp::start_main() {
|
||||||
Error err;
|
Error err;
|
||||||
@autoreleasepool {
|
@autoreleasepool {
|
||||||
@@ -954,7 +962,7 @@ void OS_MacOS_NSApp::start_main() {
|
|||||||
}
|
}
|
||||||
joypad_apple->process_joypads();
|
joypad_apple->process_joypads();
|
||||||
|
|
||||||
if (Main::iteration()) {
|
if (Main::iteration() || sig_received) {
|
||||||
terminate();
|
terminate();
|
||||||
}
|
}
|
||||||
} @catch (NSException *exception) {
|
} @catch (NSException *exception) {
|
||||||
@@ -1020,6 +1028,11 @@ OS_MacOS_NSApp::OS_MacOS_NSApp(const char *p_execpath, int p_argc, char **p_argv
|
|||||||
ERR_FAIL_NULL(delegate);
|
ERR_FAIL_NULL(delegate);
|
||||||
[NSApp setDelegate:delegate];
|
[NSApp setDelegate:delegate];
|
||||||
[NSApp registerUserInterfaceItemSearchHandler:delegate];
|
[NSApp registerUserInterfaceItemSearchHandler:delegate];
|
||||||
|
|
||||||
|
struct sigaction action;
|
||||||
|
memset(&action, 0, sizeof(action));
|
||||||
|
action.sa_handler = handle_interrupt;
|
||||||
|
sigaction(SIGINT, &action, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - OS_MacOS_Embedded
|
// MARK: - OS_MacOS_Embedded
|
||||||
|
|||||||
Reference in New Issue
Block a user