Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Embedded Game Size #101807

Merged
merged 1 commit into from
Jan 22, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
191 changes: 100 additions & 91 deletions editor/editor_run.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,99 +104,16 @@ Error EditorRun::run(const String &p_scene, const String &p_write_movie, const V
}
}

int screen = EDITOR_GET("run/window_placement/screen");
if (screen == -5) {
// Same as editor
screen = DisplayServer::get_singleton()->window_get_current_screen();
} else if (screen == -4) {
// Previous monitor (wrap to the other end if needed)
screen = Math::wrapi(
DisplayServer::get_singleton()->window_get_current_screen() - 1,
0,
DisplayServer::get_singleton()->get_screen_count());
} else if (screen == -3) {
// Next monitor (wrap to the other end if needed)
screen = Math::wrapi(
DisplayServer::get_singleton()->window_get_current_screen() + 1,
0,
DisplayServer::get_singleton()->get_screen_count());
WindowPlacement window_placement = get_window_placement();
if (window_placement.position != Point2i(INT_MAX, INT_MAX)) {
args.push_back("--position");
args.push_back(itos(window_placement.position.x) + "," + itos(window_placement.position.y));
}

Rect2 screen_rect = DisplayServer::get_singleton()->screen_get_usable_rect(screen);

int window_placement = EDITOR_GET("run/window_placement/rect");
if (screen_rect != Rect2()) {
Size2 window_size;
window_size.x = GLOBAL_GET("display/window/size/viewport_width");
window_size.y = GLOBAL_GET("display/window/size/viewport_height");

Size2 desired_size;
desired_size.x = GLOBAL_GET("display/window/size/window_width_override");
desired_size.y = GLOBAL_GET("display/window/size/window_height_override");
if (desired_size.x > 0 && desired_size.y > 0) {
window_size = desired_size;
}

if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_HIDPI)) {
bool hidpi_proj = GLOBAL_GET("display/window/dpi/allow_hidpi");
int display_scale = 1;

if (OS::get_singleton()->is_hidpi_allowed()) {
if (hidpi_proj) {
display_scale = 1; // Both editor and project runs in hiDPI mode, do not scale.
} else {
display_scale = DisplayServer::get_singleton()->screen_get_max_scale(); // Editor is in hiDPI mode, project is not, scale down.
}
} else {
if (hidpi_proj) {
display_scale = (1.f / DisplayServer::get_singleton()->screen_get_max_scale()); // Editor is not in hiDPI mode, project is, scale up.
} else {
display_scale = 1; // Both editor and project runs in lowDPI mode, do not scale.
}
}
screen_rect.position /= display_scale;
screen_rect.size /= display_scale;
}

switch (window_placement) {
case 0: { // top left
args.push_back("--position");
args.push_back(itos(screen_rect.position.x) + "," + itos(screen_rect.position.y));
} break;
case 1: { // centered
Vector2 pos = (screen_rect.position) + ((screen_rect.size - window_size) / 2).floor();
args.push_back("--position");
args.push_back(itos(pos.x) + "," + itos(pos.y));
} break;
case 2: { // custom pos
Vector2 pos = EDITOR_GET("run/window_placement/rect_custom_position");
pos += screen_rect.position;
args.push_back("--position");
args.push_back(itos(pos.x) + "," + itos(pos.y));
} break;
case 3: { // force maximized
Vector2 pos = screen_rect.position + screen_rect.size / 2;
args.push_back("--position");
args.push_back(itos(pos.x) + "," + itos(pos.y));
args.push_back("--maximized");
} break;
case 4: { // force fullscreen
Vector2 pos = screen_rect.position + screen_rect.size / 2;
args.push_back("--position");
args.push_back(itos(pos.x) + "," + itos(pos.y));
args.push_back("--fullscreen");
} break;
}
} else {
// Unable to get screen info, skip setting position.
switch (window_placement) {
case 3: { // force maximized
args.push_back("--maximized");
} break;
case 4: { // force fullscreen
args.push_back("--fullscreen");
} break;
}
if (window_placement.force_maximized) {
args.push_back("--maximized");
} else if (window_placement.force_fullscreen) {
args.push_back("--fullscreen");
}

List<String> breakpoints;
Expand Down Expand Up @@ -297,6 +214,98 @@ OS::ProcessID EditorRun::get_current_process() const {
return pids.front()->get();
}

EditorRun::WindowPlacement EditorRun::get_window_placement() {
WindowPlacement placement = WindowPlacement();
placement.screen = EDITOR_GET("run/window_placement/screen");
if (placement.screen == -5) {
// Same as editor
placement.screen = DisplayServer::get_singleton()->window_get_current_screen();
} else if (placement.screen == -4) {
// Previous monitor (wrap to the other end if needed)
placement.screen = Math::wrapi(
DisplayServer::get_singleton()->window_get_current_screen() - 1,
0,
DisplayServer::get_singleton()->get_screen_count());
} else if (placement.screen == -3) {
// Next monitor (wrap to the other end if needed)
placement.screen = Math::wrapi(
DisplayServer::get_singleton()->window_get_current_screen() + 1,
0,
DisplayServer::get_singleton()->get_screen_count());
} else if (placement.screen == -2) {
// Primary screen
placement.screen = DisplayServer::get_singleton()->get_primary_screen();
}

placement.size.x = GLOBAL_GET("display/window/size/viewport_width");
placement.size.y = GLOBAL_GET("display/window/size/viewport_height");

Size2 desired_size;
desired_size.x = GLOBAL_GET("display/window/size/window_width_override");
desired_size.y = GLOBAL_GET("display/window/size/window_height_override");
if (desired_size.x > 0 && desired_size.y > 0) {
placement.size = desired_size;
}

Rect2 screen_rect = DisplayServer::get_singleton()->screen_get_usable_rect(placement.screen);

int window_placement = EDITOR_GET("run/window_placement/rect");
if (screen_rect != Rect2()) {
if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_HIDPI)) {
bool hidpi_proj = GLOBAL_GET("display/window/dpi/allow_hidpi");
int display_scale = 1;

if (OS::get_singleton()->is_hidpi_allowed()) {
if (hidpi_proj) {
display_scale = 1; // Both editor and project runs in hiDPI mode, do not scale.
} else {
display_scale = DisplayServer::get_singleton()->screen_get_max_scale(); // Editor is in hiDPI mode, project is not, scale down.
}
} else {
if (hidpi_proj) {
display_scale = (1.f / DisplayServer::get_singleton()->screen_get_max_scale()); // Editor is not in hiDPI mode, project is, scale up.
} else {
display_scale = 1; // Both editor and project runs in lowDPI mode, do not scale.
}
}
screen_rect.position /= display_scale;
screen_rect.size /= display_scale;
}

switch (window_placement) {
case 0: { // top left
placement.position = screen_rect.position;
} break;
case 1: { // centered
placement.position = (screen_rect.position) + ((screen_rect.size - placement.size) / 2).floor();
} break;
case 2: { // custom pos
Vector2 pos = EDITOR_GET("run/window_placement/rect_custom_position");
pos += screen_rect.position;
placement.position = pos;
} break;
case 3: { // force maximized
placement.force_maximized = true;
} break;
case 4: { // force fullscreen
placement.force_fullscreen = true;
} break;
}
} else {
// Unable to get screen info, skip setting position.
switch (window_placement) {
case 3: { // force maximized
placement.force_maximized = true;
} break;
case 4: { // force fullscreen
placement.force_fullscreen = true;
} break;
}
}

return placement;
}

EditorRun::EditorRun() {
status = STATUS_STOP;
running_scene = "";
Expand Down
10 changes: 10 additions & 0 deletions editor/editor_run.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,14 @@ class EditorRun {

List<OS::ProcessID> pids;

struct WindowPlacement {
int screen = 0;
Point2i position = Point2i(INT_MAX, INT_MAX);
Size2i size;
bool force_maximized = false;
bool force_fullscreen = false;
};

private:
Status status;
String running_scene;
Expand All @@ -64,6 +72,8 @@ class EditorRun {
int get_child_process_count() const { return pids.size(); }
OS::ProcessID get_current_process() const;

static WindowPlacement get_window_placement();

EditorRun();
};

Expand Down
1 change: 1 addition & 0 deletions editor/icons/FixedSize.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion editor/icons/KeepAspect.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions editor/icons/Stretch.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
56 changes: 41 additions & 15 deletions editor/plugins/embedded_process.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ void EmbeddedProcess::_notification(int p_what) {
Rect2i new_global_rect = get_global_rect();
if (last_global_rect != new_global_rect) {
last_global_rect = new_global_rect;
_queue_update_embedded_process();
queue_update_embedded_process();
}

} break;
Expand All @@ -60,7 +60,7 @@ void EmbeddedProcess::_notification(int p_what) {
case NOTIFICATION_RESIZED:
case NOTIFICATION_VISIBILITY_CHANGED:
case NOTIFICATION_WM_POSITION_CHANGED: {
_queue_update_embedded_process();
queue_update_embedded_process();
} break;
case NOTIFICATION_THEME_CHANGED: {
focus_style_box = get_theme_stylebox(SNAME("FocusViewport"), EditorStringName(EditorStyles));
Expand All @@ -77,7 +77,7 @@ void EmbeddedProcess::_notification(int p_what) {
}
} break;
case NOTIFICATION_FOCUS_ENTER: {
_queue_update_embedded_process();
queue_update_embedded_process();
} break;
case NOTIFICATION_APPLICATION_FOCUS_IN: {
application_has_focus = true;
Expand All @@ -88,7 +88,7 @@ void EmbeddedProcess::_notification(int p_what) {
// or if the current window is a different popup or secondary window.
if (embedding_completed && current_process_id != focused_process_id && window && window->has_focus()) {
grab_focus();
_queue_update_embedded_process();
queue_update_embedded_process();
}
}
} break;
Expand All @@ -102,27 +102,33 @@ void EmbeddedProcess::_notification(int p_what) {
void EmbeddedProcess::set_window_size(const Size2i p_window_size) {
if (window_size != p_window_size) {
window_size = p_window_size;
_queue_update_embedded_process();
queue_update_embedded_process();
}
}

void EmbeddedProcess::set_keep_aspect(bool p_keep_aspect) {
if (keep_aspect != p_keep_aspect) {
keep_aspect = p_keep_aspect;
_queue_update_embedded_process();
queue_update_embedded_process();
}
}

Rect2i EmbeddedProcess::_get_global_embedded_window_rect() {
Rect2i control_rect = get_global_rect();
control_rect = Rect2i(control_rect.position, control_rect.size.maxi(1));
if (keep_aspect) {
Rect2i desired_rect = control_rect;
float ratio = MIN((float)control_rect.size.x / window_size.x, (float)control_rect.size.y / window_size.y);
desired_rect.size = Size2i(window_size.x * ratio, window_size.y * ratio).maxi(1);
control_rect = Rect2i(control_rect.position + margin_top_left, (control_rect.size - get_margins_size()).maxi(1));
if (window_size != Size2i()) {
Rect2i desired_rect = Rect2i();
if (!keep_aspect && control_rect.size.x >= window_size.x && control_rect.size.y >= window_size.y) {
// Fixed at the desired size.
desired_rect.size = window_size;
} else {
float ratio = MIN((float)control_rect.size.x / window_size.x, (float)control_rect.size.y / window_size.y);
desired_rect.size = Size2i(window_size.x * ratio, window_size.y * ratio).maxi(1);
}
desired_rect.position = Size2i(control_rect.position.x + ((control_rect.size.x - desired_rect.size.x) / 2), control_rect.position.y + ((control_rect.size.y - desired_rect.size.y) / 2));
return desired_rect;
} else {
// Stretch, use all the control area.
return control_rect;
}
}
Expand All @@ -133,8 +139,28 @@ Rect2i EmbeddedProcess::get_screen_embedded_window_rect() {
rect.position += window->get_position();
}

// Removing margins to make space for the focus border style.
return Rect2i(rect.position.x + margin_top_left.x, rect.position.y + margin_top_left.y, MAX(rect.size.x - (margin_top_left.x + margin_bottom_right.x), 1), MAX(rect.size.y - (margin_top_left.y + margin_bottom_right.y), 1));
return rect;
}

int EmbeddedProcess::get_margin_size(Side p_side) const {
ERR_FAIL_INDEX_V((int)p_side, 4, 0);

switch (p_side) {
case SIDE_LEFT:
return margin_top_left.x;
case SIDE_RIGHT:
return margin_bottom_right.x;
case SIDE_TOP:
return margin_top_left.y;
case SIDE_BOTTOM:
return margin_bottom_right.y;
}

return 0;
}

Size2 EmbeddedProcess::get_margins_size() {
return margin_top_left + margin_bottom_right;
}

bool EmbeddedProcess::is_embedding_in_progress() {
Expand Down Expand Up @@ -215,7 +241,7 @@ bool EmbeddedProcess::_is_embedded_process_updatable() {
return window && current_process_id != 0 && embedding_completed;
}

void EmbeddedProcess::_queue_update_embedded_process() {
void EmbeddedProcess::queue_update_embedded_process() {
if (updated_embedded_process_queued || !_is_embedded_process_updatable()) {
return;
}
Expand Down Expand Up @@ -287,7 +313,7 @@ void EmbeddedProcess::_check_mouse_over() {
// When we already have the focus and the user moves the mouse over the embedded process,
// we just need to refocus the process.
if (focused) {
_queue_update_embedded_process();
queue_update_embedded_process();
} else {
grab_focus();
queue_redraw();
Expand Down
4 changes: 3 additions & 1 deletion editor/plugins/embedded_process.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ class EmbeddedProcess : public Control {
Rect2i last_global_rect;

void _try_embed_process();
void _queue_update_embedded_process();
void _update_embedded_process();
void _timer_embedding_timeout();
void _draw();
Expand All @@ -78,8 +77,11 @@ class EmbeddedProcess : public Control {

void set_window_size(const Size2i p_window_size);
void set_keep_aspect(bool p_keep_aspect);
void queue_update_embedded_process();

Rect2i get_screen_embedded_window_rect();
int get_margin_size(Side p_side) const;
Size2 get_margins_size();
bool is_embedding_in_progress();
bool is_embedding_completed();
int get_embedded_pid() const;
Expand Down
Loading