Skip to content

Commit c0ebba6

Browse files
authored
Merge pull request #106166 from stuartcarnie/macos_embed_fixes
macOS: Embedded window fixes
2 parents db66343 + f658161 commit c0ebba6

File tree

12 files changed

+143
-69
lines changed

12 files changed

+143
-69
lines changed

drivers/unix/os_unix.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,21 +131,28 @@ static void _setup_clock() {
131131
}
132132
#endif
133133

134+
struct sigaction old_action;
135+
134136
static void handle_interrupt(int sig) {
135137
if (!EngineDebugger::is_active()) {
136138
return;
137139
}
138140

139141
EngineDebugger::get_script_debugger()->set_depth(-1);
140142
EngineDebugger::get_script_debugger()->set_lines_left(1);
143+
144+
// Ensure we call the old action if it was configured.
145+
if (old_action.sa_handler && old_action.sa_handler != SIG_IGN && old_action.sa_handler != SIG_DFL) {
146+
old_action.sa_handler(sig);
147+
}
141148
}
142149

143150
void OS_Unix::initialize_debugging() {
144151
if (EngineDebugger::is_active()) {
145152
struct sigaction action;
146153
memset(&action, 0, sizeof(action));
147154
action.sa_handler = handle_interrupt;
148-
sigaction(SIGINT, &action, nullptr);
155+
sigaction(SIGINT, &action, &old_action);
149156
}
150157
}
151158

editor/plugins/game_view_plugin.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -864,7 +864,7 @@ void GameView::_update_arguments_for_instance(int p_idx, List<String> &r_argumen
864864
N = r_arguments.insert_after(N, itos(DisplayServer::get_singleton()->window_get_native_handle(DisplayServer::WINDOW_HANDLE, get_window()->get_window_id())));
865865

866866
#if MACOS_ENABLED
867-
r_arguments.push_back("--embedded");
867+
N = r_arguments.insert_after(N, "--embedded");
868868
#endif
869869

870870
// Be sure to have the correct window size in the embedded_process control.

main/main.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1399,9 +1399,12 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
13991399
display_driver = NULL_DISPLAY_DRIVER;
14001400

14011401
} else if (arg == "--embedded") { // Enable embedded mode.
1402-
1402+
#ifdef MACOS_ENABLED
14031403
display_driver = EMBEDDED_DISPLAY_DRIVER;
1404-
1404+
#else
1405+
OS::get_singleton()->print("--embedded is only supported on macOS, aborting.\n");
1406+
goto error;
1407+
#endif
14051408
} else if (arg == "--log-file") { // write to log file
14061409

14071410
if (N) {

platform/macos/display_server_embedded.h

Lines changed: 17 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -33,33 +33,27 @@
3333
#include "core/input/input.h"
3434
#include "servers/display_server.h"
3535

36-
#if defined(GLES3_ENABLED)
37-
#include "embedded_gl_manager.h"
38-
#include "platform_gl.h"
39-
#endif // GLES3_ENABLED
40-
41-
#if defined(RD_ENABLED)
42-
#include "servers/rendering/rendering_device.h"
43-
44-
#if defined(VULKAN_ENABLED)
45-
#import "rendering_context_driver_vulkan_macos.h"
46-
#endif // VULKAN_ENABLED
47-
#if defined(METAL_ENABLED)
48-
#import "drivers/metal/rendering_context_driver_metal.h"
49-
#endif
50-
#endif // RD_ENABLED
51-
5236
@class CAContext;
37+
@class CALayer;
38+
class GLManagerEmbedded;
39+
class RenderingContextDriver;
40+
class RenderingDevice;
41+
42+
struct DisplayServerEmbeddedState {
43+
/// Default to a scale of 2.0, which is the most common.
44+
float screen_max_scale = 2.0f;
45+
float screen_dpi = 96.0f;
46+
47+
void serialize(PackedByteArray &r_data);
48+
Error deserialize(const PackedByteArray &p_data);
49+
};
5350

5451
class DisplayServerEmbedded : public DisplayServer {
5552
GDCLASS(DisplayServerEmbedded, DisplayServer)
5653

5754
_THREAD_SAFE_CLASS_
5855

59-
struct {
60-
float screen_max_scale = 1.0f;
61-
float screen_dpi = 96.0f;
62-
} state;
56+
DisplayServerEmbeddedState state;
6357

6458
NativeMenu *native_menu = nullptr;
6559

@@ -70,13 +64,11 @@ class DisplayServerEmbedded : public DisplayServer {
7064
HashMap<WindowID, Callable> input_event_callbacks;
7165
HashMap<WindowID, Callable> input_text_callbacks;
7266

73-
float content_scale = 1.0f;
74-
7567
WindowID window_id_counter = MAIN_WINDOW_ID;
7668

77-
CAContext *ca_context = nil;
69+
CAContext *ca_context = nullptr;
7870
// Either be a CAMetalLayer or a CALayer depending on the rendering driver.
79-
CALayer *layer = nil;
71+
CALayer *layer = nullptr;
8072
#ifdef GLES3_ENABLED
8173
GLManagerEmbedded *gl_manager = nullptr;
8274
#endif
@@ -222,8 +214,7 @@ class DisplayServerEmbedded : public DisplayServer {
222214
virtual CursorShape cursor_get_shape() const override;
223215
virtual void cursor_set_custom_image(const Ref<Resource> &p_cursor, CursorShape p_shape = CURSOR_ARROW, const Vector2 &p_hotspot = Vector2()) override;
224216

225-
void update_state(const Dictionary &p_state);
226-
void set_content_scale(float p_scale);
217+
void set_state(const DisplayServerEmbeddedState &p_state);
227218
virtual void swap_buffers() override;
228219

229220
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);

platform/macos/display_server_embedded.mm

Lines changed: 49 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -30,19 +30,31 @@
3030

3131
#import "display_server_embedded.h"
3232

33-
#import "embedded_debugger.h"
34-
#import "macos_quartz_core_spi.h"
35-
36-
#import "core/config/project_settings.h"
37-
#import "core/debugger/engine_debugger.h"
38-
3933
#if defined(GLES3_ENABLED)
40-
#include "drivers/gles3/rasterizer_gles3.h"
34+
#import "embedded_gl_manager.h"
35+
#import "platform_gl.h"
36+
37+
#import "drivers/gles3/rasterizer_gles3.h"
4138
#endif
4239

4340
#if defined(RD_ENABLED)
4441
#import "servers/rendering/renderer_rd/renderer_compositor_rd.h"
42+
#import "servers/rendering/rendering_device.h"
43+
44+
#if defined(VULKAN_ENABLED)
45+
#import "rendering_context_driver_vulkan_macos.h"
46+
#endif // VULKAN_ENABLED
47+
#if defined(METAL_ENABLED)
48+
#import "drivers/metal/rendering_context_driver_metal.h"
4549
#endif
50+
#endif // RD_ENABLED
51+
52+
#import "embedded_debugger.h"
53+
#import "macos_quartz_core_spi.h"
54+
55+
#import "core/config/project_settings.h"
56+
#import "core/debugger/engine_debugger.h"
57+
#import "core/io/marshalls.h"
4658

4759
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) {
4860
EmbeddedDebugger::initialize(this);
@@ -176,15 +188,15 @@
176188
}
177189
#endif
178190

179-
constexpr CGFloat CONTENT_SCALE = 2.0;
180-
layer.contentsScale = CONTENT_SCALE;
191+
CGFloat scale = screen_get_max_scale();
192+
layer.contentsScale = scale;
181193
layer.magnificationFilter = kCAFilterNearest;
182194
layer.minificationFilter = kCAFilterNearest;
183-
layer.opaque = NO; // Never opaque when embedded.
195+
layer.opaque = YES; // Always opaque when embedded.
184196
layer.actions = @{ @"contents" : [NSNull null] }; // Disable implicit animations for contents.
185197
// AppKit frames, bounds and positions are always in points.
186198
CGRect bounds = CGRectMake(0, 0, p_resolution.width, p_resolution.height);
187-
bounds = CGRectApplyAffineTransform(bounds, CGAffineTransformMakeScale(1.0 / CONTENT_SCALE, 1.0 / CONTENT_SCALE));
199+
bounds = CGRectApplyAffineTransform(bounds, CGAffineTransformInvert(CGAffineTransformMakeScale(scale, scale)));
188200
layer.bounds = bounds;
189201

190202
CGSConnectionID connection_id = CGSMainConnectionID();
@@ -582,11 +594,11 @@
582594
[CATransaction begin];
583595
[CATransaction setDisableActions:YES];
584596

585-
// TODO(sgc): Pass scale as argument from parent process.
586-
constexpr CGFloat CONTENT_SCALE = 2.0;
597+
CGFloat scale = screen_get_max_scale();
587598
CGRect bounds = CGRectMake(0, 0, p_size.width, p_size.height);
588-
bounds = CGRectApplyAffineTransform(bounds, CGAffineTransformMakeScale(1.0 / CONTENT_SCALE, 1.0 / CONTENT_SCALE));
599+
bounds = CGRectApplyAffineTransform(bounds, CGAffineTransformInvert(CGAffineTransformMakeScale(scale, scale)));
589600
layer.bounds = bounds;
601+
layer.contentsScale = scale;
590602

591603
#if defined(RD_ENABLED)
592604
if (rendering_context) {
@@ -685,12 +697,8 @@
685697
ime_last_position = p_pos;
686698
}
687699

688-
void DisplayServerEmbedded::update_state(const Dictionary &p_state) {
689-
state.screen_max_scale = p_state["screen_get_max_scale"];
690-
}
691-
692-
void DisplayServerEmbedded::set_content_scale(float p_scale) {
693-
content_scale = p_scale;
700+
void DisplayServerEmbedded::set_state(const DisplayServerEmbeddedState &p_state) {
701+
state = p_state;
694702
}
695703

696704
void DisplayServerEmbedded::window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window) {
@@ -742,3 +750,24 @@
742750
}
743751
#endif
744752
}
753+
754+
void DisplayServerEmbeddedState::serialize(PackedByteArray &r_data) {
755+
r_data.resize(8);
756+
757+
uint8_t *data = r_data.ptrw();
758+
data += encode_float(screen_max_scale, data);
759+
data += encode_float(screen_dpi, data);
760+
761+
// Assert we had enough space.
762+
DEV_ASSERT(data - r_data.ptrw() >= r_data.size());
763+
}
764+
765+
Error DisplayServerEmbeddedState::deserialize(const PackedByteArray &p_data) {
766+
const uint8_t *data = p_data.ptr();
767+
768+
screen_max_scale = decode_float(data);
769+
data += sizeof(float);
770+
screen_dpi = decode_float(data);
771+
772+
return OK;
773+
}

platform/macos/display_server_macos.mm

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3297,6 +3297,7 @@
32973297
[CATransaction setDisableActions:YES];
32983298

32993299
EmbeddedProcessData *ed = embedded_processes.getptr(p_pid);
3300+
CGFloat scale = screen_get_max_scale();
33003301
if (ed == nil) {
33013302
ed = &embedded_processes.insert(p_pid, EmbeddedProcessData())->value;
33023303

@@ -3305,15 +3306,15 @@
33053306
CALayerHost *host = [CALayerHost new];
33063307
uint32_t p_context_id = p_process->get_context_id();
33073308
host.contextId = static_cast<CAContextID>(p_context_id);
3308-
host.contentsScale = wd->window_object.backingScaleFactor;
3309+
host.contentsScale = scale;
33093310
host.contentsGravity = kCAGravityCenter;
33103311
ed->layer_host = host;
33113312
[wd->window_view.layer addSublayer:host];
33123313
}
33133314

33143315
Rect2i p_rect = p_process->get_screen_embedded_window_rect();
33153316
CGRect rect = CGRectMake(p_rect.position.x, p_rect.position.y, p_rect.size.x, p_rect.size.y);
3316-
rect = CGRectApplyAffineTransform(rect, CGAffineTransformMakeScale(0.5, 0.5));
3317+
rect = CGRectApplyAffineTransform(rect, CGAffineTransformInvert(CGAffineTransformMakeScale(scale, scale)));
33173318

33183319
CGFloat height = wd->window_view.frame.size.height;
33193320
CGFloat x = rect.origin.x;

platform/macos/editor/embedded_process_macos.h

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -102,12 +102,12 @@ class EmbeddedProcessMacOS final : public EmbeddedProcessBase {
102102
return embedding_state == EmbeddingState::COMPLETED;
103103
}
104104

105-
virtual bool is_process_focused() const override { return layer_host->has_focus(); }
106-
virtual void embed_process(OS::ProcessID p_pid) override;
107-
virtual int get_embedded_pid() const override { return current_process_id; }
108-
virtual void reset() override;
109-
virtual void request_close() override;
110-
virtual void queue_update_embedded_process() override { update_embedded_process(); }
105+
bool is_process_focused() const override { return layer_host->has_focus(); }
106+
void embed_process(OS::ProcessID p_pid) override;
107+
int get_embedded_pid() const override { return current_process_id; }
108+
void reset() override;
109+
void request_close() override;
110+
void queue_update_embedded_process() override { update_embedded_process(); }
111111

112112
Rect2i get_adjusted_embedded_window_rect(const Rect2i &p_rect) const override;
113113

@@ -117,4 +117,5 @@ class EmbeddedProcessMacOS final : public EmbeddedProcessBase {
117117
_FORCE_INLINE_ DisplayServer::MouseMode get_mouse_mode() const { return mouse_mode; }
118118

119119
EmbeddedProcessMacOS();
120+
~EmbeddedProcessMacOS() override;
120121
};

platform/macos/editor/embedded_process_macos.mm

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030

3131
#include "embedded_process_macos.h"
3232

33+
#include "platform/macos/display_server_embedded.h"
3334
#include "platform/macos/display_server_macos.h"
3435

3536
#include "core/input/input_event_codec.h"
@@ -122,7 +123,7 @@
122123

123124
void EmbeddedProcessMacOS::request_close() {
124125
if (current_process_id != 0 && is_embedding_completed()) {
125-
ds->request_close_embedded_process(current_process_id);
126+
script_debugger->send_message("embed:win_event", { DisplayServer::WINDOW_EVENT_CLOSE_REQUEST });
126127
}
127128
}
128129

@@ -133,19 +134,22 @@
133134

134135
Error err = ds->embed_process_update(window->get_window_id(), this);
135136
if (err == OK) {
137+
// Replicate some of the DisplayServer state.
138+
{
139+
DisplayServerEmbeddedState state;
140+
state.screen_max_scale = ds->screen_get_max_scale();
141+
state.screen_dpi = ds->screen_get_dpi();
142+
PackedByteArray data;
143+
state.serialize(data);
144+
script_debugger->send_message("embed:ds_state", { data });
145+
}
146+
136147
Rect2i rect = get_screen_embedded_window_rect();
137148
script_debugger->send_message("embed:window_size", { rect.size });
138149
embedding_state = EmbeddingState::COMPLETED;
139150
queue_redraw();
140151
emit_signal(SNAME("embedding_completed"));
141152

142-
// Replicate some of the DisplayServer state.
143-
{
144-
Dictionary state;
145-
state["screen_get_max_scale"] = ds->screen_get_max_scale();
146-
// script_debugger->send_message("embed:ds_state", { state });
147-
}
148-
149153
// Send initial joystick state.
150154
{
151155
Input *input = Input::get_singleton();
@@ -209,13 +213,21 @@
209213
ED_SHORTCUT("game_view/release_mouse", TTRC("Release Mouse"), KeyModifierMask::ALT | Key::ESCAPE);
210214
}
211215

216+
EmbeddedProcessMacOS::~EmbeddedProcessMacOS() {
217+
if (current_process_id != 0) {
218+
// Stop embedding the last process.
219+
OS::get_singleton()->kill(current_process_id);
220+
reset();
221+
}
222+
}
223+
212224
void LayerHost::_notification(int p_what) {
213225
switch (p_what) {
214226
case NOTIFICATION_FOCUS_ENTER: {
215227
if (script_debugger) {
216228
script_debugger->send_message("embed:win_event", { DisplayServer::WINDOW_EVENT_MOUSE_ENTER });
217229
}
218-
// Temporarily release mouse capture, so we can interact with the editor.
230+
// Restore mouse capture, if necessary.
219231
DisplayServer *ds = DisplayServer::get_singleton();
220232
if (process->get_mouse_mode() != ds->mouse_get_mode()) {
221233
// Restore embedded process mouse mode.

platform/macos/embedded_debugger.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ class EmbeddedDebugger {
6363
Error _msg_ime_update(const Array &p_args);
6464
Error _msg_joy_add(const Array &p_args);
6565
Error _msg_joy_del(const Array &p_args);
66+
Error _msg_ds_state(const Array &p_args);
6667

6768
public:
6869
static Error parse_message(void *p_user, const String &p_msg, const Array &p_args, bool &r_captured);

0 commit comments

Comments
 (0)