summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRémi Verschelde <rverschelde@gmail.com>2023-01-07 13:21:36 +0100
committerRémi Verschelde <rverschelde@gmail.com>2023-01-07 13:21:36 +0100
commitd642274f75fb8ca6d3b9d4c314269e6f559051c7 (patch)
tree7dbf61077d234d636dfd33f85007bcc06f66fb69
parent3579d7a9f74e3f1eda88826897feb4b866d75ec9 (diff)
parent2718a7b7d39962100e59b8616077603034d77f8e (diff)
Merge pull request #70939 from bruvzg/win_screen_2
Add support for the custom initial screen for the main window, fix primary screen detection.
-rw-r--r--core/config/project_settings.cpp8
-rw-r--r--doc/classes/DisplayServer.xml16
-rw-r--r--doc/classes/ProjectSettings.xml3
-rw-r--r--doc/classes/Window.xml8
-rw-r--r--editor/editor_run.cpp18
-rw-r--r--editor/editor_settings.cpp7
-rw-r--r--editor/project_manager.cpp9
-rw-r--r--main/main.cpp28
-rw-r--r--platform/android/display_server_android.cpp10
-rw-r--r--platform/android/display_server_android.h5
-rw-r--r--platform/ios/display_server_ios.h5
-rw-r--r--platform/ios/display_server_ios.mm10
-rw-r--r--platform/linuxbsd/x11/display_server_x11.cpp118
-rw-r--r--platform/linuxbsd/x11/display_server_x11.h9
-rw-r--r--platform/macos/display_server_macos.h9
-rw-r--r--platform/macos/display_server_macos.mm133
-rw-r--r--platform/web/display_server_web.cpp10
-rw-r--r--platform/web/display_server_web.h5
-rw-r--r--platform/windows/display_server_windows.cpp192
-rw-r--r--platform/windows/display_server_windows.h10
-rw-r--r--scene/main/viewport.cpp1
-rw-r--r--scene/main/window.cpp40
-rw-r--r--scene/main/window.h12
-rw-r--r--servers/display_server.cpp27
-rw-r--r--servers/display_server.h11
-rw-r--r--servers/display_server_headless.h5
-rw-r--r--tests/test_main.cpp2
27 files changed, 506 insertions, 205 deletions
diff --git a/core/config/project_settings.cpp b/core/config/project_settings.cpp
index 2ce3ce2678..0bf7430d84 100644
--- a/core/config/project_settings.cpp
+++ b/core/config/project_settings.cpp
@@ -1240,6 +1240,14 @@ ProjectSettings::ProjectSettings() {
GLOBAL_DEF_BASIC("display/window/size/mode", 0);
custom_prop_info["display/window/size/mode"] = PropertyInfo(Variant::INT, "display/window/size/mode", PROPERTY_HINT_ENUM, "Windowed,Minimized,Maximized,Fullscreen,Exclusive Fullscreen");
+ // Keep the enum values in sync with the `DisplayServer::SCREEN_` enum.
+ GLOBAL_DEF_BASIC("display/window/size/initial_screen", -2);
+ String screen_hints = "Primary Monitor:-2"; // Note: Main Window Monitor:-1 is not used for the main window, skip it.
+ for (int i = 0; i < 64; i++) {
+ screen_hints += ",Monitor " + itos(i + 1) + ":" + itos(i);
+ }
+ custom_prop_info["display/window/size/initial_screen"] = PropertyInfo(Variant::INT, "display/window/size/initial_screen", PROPERTY_HINT_ENUM, screen_hints);
+
GLOBAL_DEF_BASIC("display/window/size/resizable", true);
GLOBAL_DEF_BASIC("display/window/size/borderless", false);
GLOBAL_DEF("display/window/size/always_on_top", false);
diff --git a/doc/classes/DisplayServer.xml b/doc/classes/DisplayServer.xml
index 29135376c5..98e53b86f9 100644
--- a/doc/classes/DisplayServer.xml
+++ b/doc/classes/DisplayServer.xml
@@ -130,12 +130,25 @@
The names of built-in display servers are [code]Windows[/code], [code]macOS[/code], [code]X11[/code] (Linux), [code]Android[/code], [code]iOS[/code], [code]web[/code] (HTML5) and [code]headless[/code] (when started with the [code]--headless[/code] [url=$DOCS_URL/tutorials/editor/command_line_tutorial.html]command line argument[/url]).
</description>
</method>
+ <method name="get_primary_screen" qualifiers="const">
+ <return type="int" />
+ <description>
+ Returns index of the primary screen.
+ </description>
+ </method>
<method name="get_screen_count" qualifiers="const">
<return type="int" />
<description>
Returns the number of displays available.
</description>
</method>
+ <method name="get_screen_from_rect" qualifiers="const">
+ <return type="int" />
+ <param index="0" name="rect" type="Rect2" />
+ <description>
+ Returns index of the screen which contains specified rectangle.
+ </description>
+ </method>
<method name="get_swap_cancel_ok">
<return type="bool" />
<description>
@@ -1521,6 +1534,9 @@
<constant name="MOUSE_MODE_CONFINED_HIDDEN" value="4" enum="MouseMode">
Confines the mouse cursor to the game window, and make it hidden.
</constant>
+ <constant name="SCREEN_PRIMARY" value="-2">
+ Represents the primary screen.
+ </constant>
<constant name="SCREEN_OF_MAIN_WINDOW" value="-1">
Represents the screen where the main window is located. This is usually the default value in functions that allow specifying one of several screens.
</constant>
diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml
index d4c42e36eb..cfcfca9880 100644
--- a/doc/classes/ProjectSettings.xml
+++ b/doc/classes/ProjectSettings.xml
@@ -596,6 +596,9 @@
Main window content is expanded to the full size of the window. Unlike a borderless window, the frame is left intact and can be used to resize the window, and the title bar is transparent, but has minimize/maximize/close buttons.
[b]Note:[/b] This setting is implemented only on macOS.
</member>
+ <member name="display/window/size/initial_screen" type="int" setter="" getter="" default="-2">
+ Main window initial screen.
+ </member>
<member name="display/window/size/mode" type="int" setter="" getter="" default="0">
Main window mode. See [enum DisplayServer.WindowMode] for possible values and how each mode behaves.
</member>
diff --git a/doc/classes/Window.xml b/doc/classes/Window.xml
index 16ca486e4a..4cd6cf41da 100644
--- a/doc/classes/Window.xml
+++ b/doc/classes/Window.xml
@@ -503,7 +503,7 @@
<member name="content_scale_size" type="Vector2i" setter="set_content_scale_size" getter="get_content_scale_size" default="Vector2i(0, 0)">
Base size of the content (i.e. nodes that are drawn inside the window). If non-zero, [Window]'s content will be scaled when the window is resized to a different size.
</member>
- <member name="current_screen" type="int" setter="set_current_screen" getter="get_current_screen" default="0">
+ <member name="current_screen" type="int" setter="set_current_screen" getter="get_current_screen">
The screen the window is currently on.
</member>
<member name="exclusive" type="bool" setter="set_exclusive" getter="is_exclusive" default="false">
@@ -513,6 +513,8 @@
<member name="extend_to_title" type="bool" setter="set_flag" getter="get_flag" default="false">
If [code]true[/code], the [Window] contents is expanded to the full size of the window, window title bar is transparent.
</member>
+ <member name="initial_position" type="int" setter="set_initial_position" getter="get_initial_position" enum="Window.WindowInitialPosition" default="0">
+ </member>
<member name="max_size" type="Vector2i" setter="set_max_size" getter="get_max_size" default="Vector2i(0, 0)">
If non-zero, the [Window] can't be resized to be bigger than this size.
[b]Note:[/b] This property will be ignored if the value is lower than [member min_size].
@@ -732,6 +734,10 @@
<constant name="LAYOUT_DIRECTION_RTL" value="3" enum="LayoutDirection">
Right-to-left layout direction.
</constant>
+ <constant name="WINDOW_INITIAL_POSITION_ABSOLUTE" value="0" enum="WindowInitialPosition">
+ </constant>
+ <constant name="WINDOW_INITIAL_POSITION_CENTER_SCREEN" value="1" enum="WindowInitialPosition">
+ </constant>
</constants>
<theme_items>
<theme_item name="title_color" data_type="color" type="Color" default="Color(0.875, 0.875, 0.875, 1)">
diff --git a/editor/editor_run.cpp b/editor/editor_run.cpp
index 853b685851..4bcd91376a 100644
--- a/editor/editor_run.cpp
+++ b/editor/editor_run.cpp
@@ -93,30 +93,24 @@ Error EditorRun::run(const String &p_scene, const String &p_write_movie) {
}
int screen = EDITOR_GET("run/window_placement/screen");
- if (screen == 0) {
+ if (screen == -5) {
// Same as editor
screen = DisplayServer::get_singleton()->window_get_current_screen();
- } else if (screen == 1) {
+ } 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 == 2) {
+ } 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());
- } else {
- // Fixed monitor ID
- // There are 3 special options, so decrement the option ID by 3 to get the monitor ID
- screen -= 3;
}
- Rect2 screen_rect;
- screen_rect.position = DisplayServer::get_singleton()->screen_get_position(screen);
- screen_rect.size = DisplayServer::get_singleton()->screen_get_size(screen);
+ Rect2 screen_rect = DisplayServer::get_singleton()->screen_get_usable_rect(screen);
int window_placement = EDITOR_GET("run/window_placement/rect");
if (screen_rect != Rect2()) {
@@ -169,13 +163,13 @@ Error EditorRun::run(const String &p_scene, const String &p_write_movie) {
args.push_back(itos(pos.x) + "," + itos(pos.y));
} break;
case 3: { // force maximized
- Vector2 pos = screen_rect.position;
+ 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;
+ 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");
diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp
index 5561597c70..8ca98e6f76 100644
--- a/editor/editor_settings.cpp
+++ b/editor/editor_settings.cpp
@@ -697,12 +697,13 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
// Window placement
EDITOR_SETTING(Variant::INT, PROPERTY_HINT_ENUM, "run/window_placement/rect", 1, "Top Left,Centered,Custom Position,Force Maximized,Force Fullscreen")
- String screen_hints = "Same as Editor,Previous Monitor,Next Monitor";
+ // Keep the enum values in sync with the `DisplayServer::SCREEN_` enum.
+ String screen_hints = "Same as Editor:-5,Previous Monitor:-4,Next Monitor:-3,Primary Monitor:-2"; // Note: Main Window Screen:-1 is not used for the main window.
for (int i = 0; i < DisplayServer::get_singleton()->get_screen_count(); i++) {
- screen_hints += ",Monitor " + itos(i + 1);
+ screen_hints += ",Monitor " + itos(i + 1) + ":" + itos(i);
}
_initial_set("run/window_placement/rect_custom_position", Vector2());
- EDITOR_SETTING(Variant::INT, PROPERTY_HINT_ENUM, "run/window_placement/screen", 0, screen_hints)
+ EDITOR_SETTING(Variant::INT, PROPERTY_HINT_ENUM, "run/window_placement/screen", -5, screen_hints)
// Auto save
_initial_set("run/auto_save/save_before_running", true);
diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp
index f8bea5f6e8..dc755cab41 100644
--- a/editor/project_manager.cpp
+++ b/editor/project_manager.cpp
@@ -3014,16 +3014,15 @@ ProjectManager::ProjectManager() {
float scale_factor = MAX(1, EDSCALE);
if (scale_factor > 1.0) {
Vector2i window_size = DisplayServer::get_singleton()->window_get_size();
- Vector2i screen_size = DisplayServer::get_singleton()->screen_get_size();
- Vector2i screen_position = DisplayServer::get_singleton()->screen_get_position();
+ Rect2i screen_rect = DisplayServer::get_singleton()->screen_get_usable_rect(DisplayServer::get_singleton()->window_get_current_screen());
window_size *= scale_factor;
DisplayServer::get_singleton()->window_set_size(window_size);
- if (screen_size != Vector2i()) {
+ if (screen_rect.size != Vector2i()) {
Vector2i window_position;
- window_position.x = screen_position.x + (screen_size.x - window_size.x) / 2;
- window_position.y = screen_position.y + (screen_size.y - window_size.y) / 2;
+ window_position.x = screen_rect.position.x + (screen_rect.size.x - window_size.x) / 2;
+ window_position.y = screen_rect.position.y + (screen_rect.size.y - window_size.y) / 2;
DisplayServer::get_singleton()->window_set_position(window_position);
}
}
diff --git a/main/main.cpp b/main/main.cpp
index dd7809af8e..4cab469672 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -179,7 +179,7 @@ static DisplayServer::VSyncMode window_vsync_mode = DisplayServer::VSYNC_ENABLED
static uint32_t window_flags = 0;
static Size2i window_size = Size2i(1152, 648);
-static int init_screen = -1;
+static int init_screen = DisplayServer::SCREEN_PRIMARY;
static bool init_fullscreen = false;
static bool init_maximized = false;
static bool init_windowed = false;
@@ -377,7 +377,8 @@ void Main::print_help(const char *p_binary) {
OS::get_singleton()->print(" -w, --windowed Request windowed mode.\n");
OS::get_singleton()->print(" -t, --always-on-top Request an always-on-top window.\n");
OS::get_singleton()->print(" --resolution <W>x<H> Request window resolution.\n");
- OS::get_singleton()->print(" --position <X>,<Y> Request window position.\n");
+ OS::get_singleton()->print(" --position <X>,<Y> Request window position (if set, screen argument is ignored).\n");
+ OS::get_singleton()->print(" --screen <N> Request window screen.\n");
OS::get_singleton()->print(" --single-window Use a single window (no separate subwindows).\n");
OS::get_singleton()->print(" --xr-mode <mode> Select XR (Extended Reality) mode ['default', 'off', 'on'].\n");
OS::get_singleton()->print("\n");
@@ -959,6 +960,17 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
goto error;
}
+ } else if (I->get() == "--screen") { // set window screen
+
+ if (I->next()) {
+ init_screen = I->next()->get().to_int();
+
+ N = I->next()->next();
+ } else {
+ OS::get_singleton()->print("Missing screen argument, aborting.\n");
+ goto error;
+ }
+
} else if (I->get() == "--position") { // set window position
if (I->next()) {
@@ -1658,6 +1670,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
window_flags |= DisplayServer::WINDOW_FLAG_NO_FOCUS_BIT;
}
window_mode = (DisplayServer::WindowMode)(GLOBAL_GET("display/window/size/mode").operator int());
+ init_screen = GLOBAL_GET("display/window/size/initial_screen").operator int();
}
GLOBAL_DEF("internationalization/locale/include_text_server_data", false);
@@ -1909,7 +1922,7 @@ Error Main::setup2(Thread::ID p_main_tid_override) {
// rendering_driver now held in static global String in main and initialized in setup()
Error err;
- display_server = DisplayServer::create(display_driver_idx, rendering_driver, window_mode, window_vsync_mode, window_flags, window_position, window_size, err);
+ display_server = DisplayServer::create(display_driver_idx, rendering_driver, window_mode, window_vsync_mode, window_flags, window_position, window_size, init_screen, err);
if (err != OK || display_server == nullptr) {
// We can't use this display server, try other ones as fallback.
// Skip headless (always last registered) because that's not what users
@@ -1918,7 +1931,7 @@ Error Main::setup2(Thread::ID p_main_tid_override) {
if (i == display_driver_idx) {
continue; // Don't try the same twice.
}
- display_server = DisplayServer::create(i, rendering_driver, window_mode, window_vsync_mode, window_flags, window_position, window_size, err);
+ display_server = DisplayServer::create(i, rendering_driver, window_mode, window_vsync_mode, window_flags, window_position, window_size, init_screen, err);
if (err == OK && display_server != nullptr) {
break;
}
@@ -2015,10 +2028,6 @@ Error Main::setup2(Thread::ID p_main_tid_override) {
print_line(" "); //add a blank line for readability
- if (init_use_custom_pos) {
- display_server->window_set_position(init_custom_pos);
- }
-
// right moment to create and initialize the audio server
audio_server = memnew(AudioServer);
@@ -2037,9 +2046,6 @@ Error Main::setup2(Thread::ID p_main_tid_override) {
bool show_logo = true;
#endif
- if (init_screen != -1) {
- DisplayServer::get_singleton()->window_set_current_screen(init_screen);
- }
if (init_windowed) {
//do none..
} else if (init_maximized) {
diff --git a/platform/android/display_server_android.cpp b/platform/android/display_server_android.cpp
index f8865cc563..70370764e2 100644
--- a/platform/android/display_server_android.cpp
+++ b/platform/android/display_server_android.cpp
@@ -184,6 +184,10 @@ int DisplayServerAndroid::get_screen_count() const {
return 1;
}
+int DisplayServerAndroid::get_primary_screen() const {
+ return 0;
+}
+
Point2i DisplayServerAndroid::screen_get_position(int p_screen) const {
return Point2i(0, 0);
}
@@ -459,8 +463,8 @@ Vector<String> DisplayServerAndroid::get_rendering_drivers_func() {
return drivers;
}
-DisplayServer *DisplayServerAndroid::create_func(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, Error &r_error) {
- DisplayServer *ds = memnew(DisplayServerAndroid(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_position, p_resolution, r_error));
+DisplayServer *DisplayServerAndroid::create_func(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, Error &r_error) {
+ DisplayServer *ds = memnew(DisplayServerAndroid(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_position, p_resolution, p_screen, r_error));
if (r_error != OK) {
OS::get_singleton()->alert("Your video card driver does not support any of the supported Vulkan versions.", "Unable to initialize Video driver");
if (p_rendering_driver == "vulkan") {
@@ -512,7 +516,7 @@ void DisplayServerAndroid::notify_surface_changed(int p_width, int p_height) {
rect_changed_callback.callp(reinterpret_cast<const Variant **>(&sizep), 1, ret, ce);
}
-DisplayServerAndroid::DisplayServerAndroid(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, Error &r_error) {
+DisplayServerAndroid::DisplayServerAndroid(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, Error &r_error) {
rendering_driver = p_rendering_driver;
keep_screen_on = GLOBAL_GET("display/window/energy_saving/keep_screen_on");
diff --git a/platform/android/display_server_android.h b/platform/android/display_server_android.h
index ec3ff9af49..faaa3dbd9c 100644
--- a/platform/android/display_server_android.h
+++ b/platform/android/display_server_android.h
@@ -115,6 +115,7 @@ public:
virtual ScreenOrientation screen_get_orientation(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
virtual int get_screen_count() const override;
+ virtual int get_primary_screen() const override;
virtual Point2i screen_get_position(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
virtual Size2i screen_get_size(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
virtual Rect2i screen_get_usable_rect(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
@@ -198,7 +199,7 @@ public:
virtual void mouse_set_mode(MouseMode p_mode) override;
virtual MouseMode mouse_get_mode() const override;
- static DisplayServer *create_func(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, Error &r_error);
+ static DisplayServer *create_func(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, Error &r_error);
static Vector<String> get_rendering_drivers_func();
static void register_android_driver();
@@ -215,7 +216,7 @@ public:
virtual void set_native_icon(const String &p_filename) override;
virtual void set_icon(const Ref<Image> &p_icon) override;
- DisplayServerAndroid(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, Error &r_error);
+ DisplayServerAndroid(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, Error &r_error);
~DisplayServerAndroid();
};
diff --git a/platform/ios/display_server_ios.h b/platform/ios/display_server_ios.h
index 3f167acc94..dd1157f668 100644
--- a/platform/ios/display_server_ios.h
+++ b/platform/ios/display_server_ios.h
@@ -75,7 +75,7 @@ class DisplayServerIOS : public DisplayServer {
void perform_event(const Ref<InputEvent> &p_event);
- DisplayServerIOS(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, Error &r_error);
+ DisplayServerIOS(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, Error &r_error);
~DisplayServerIOS();
public:
@@ -84,7 +84,7 @@ public:
static DisplayServerIOS *get_singleton();
static void register_ios_driver();
- static DisplayServer *create_func(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, Error &r_error);
+ static DisplayServer *create_func(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, Error &r_error);
static Vector<String> get_rendering_drivers_func();
// MARK: - Events
@@ -139,6 +139,7 @@ public:
virtual Rect2i get_display_safe_area() const override;
virtual int get_screen_count() const override;
+ virtual int get_primary_screen() const override;
virtual Point2i screen_get_position(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
virtual Size2i screen_get_size(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
virtual Rect2i screen_get_usable_rect(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
diff --git a/platform/ios/display_server_ios.mm b/platform/ios/display_server_ios.mm
index f383ba5bee..bea88a7f9b 100644
--- a/platform/ios/display_server_ios.mm
+++ b/platform/ios/display_server_ios.mm
@@ -49,7 +49,7 @@ DisplayServerIOS *DisplayServerIOS::get_singleton() {
return (DisplayServerIOS *)DisplayServer::get_singleton();
}
-DisplayServerIOS::DisplayServerIOS(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, Error &r_error) {
+DisplayServerIOS::DisplayServerIOS(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, Error &r_error) {
rendering_driver = p_rendering_driver;
// Init TTS
@@ -151,8 +151,8 @@ DisplayServerIOS::~DisplayServerIOS() {
#endif
}
-DisplayServer *DisplayServerIOS::create_func(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, Error &r_error) {
- return memnew(DisplayServerIOS(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_position, p_resolution, r_error));
+DisplayServer *DisplayServerIOS::create_func(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, Error &r_error) {
+ return memnew(DisplayServerIOS(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_position, p_resolution, p_screen, r_error));
}
Vector<String> DisplayServerIOS::get_rendering_drivers_func() {
@@ -379,6 +379,10 @@ int DisplayServerIOS::get_screen_count() const {
return 1;
}
+int DisplayServerIOS::get_primary_screen() const {
+ return 0;
+}
+
Point2i DisplayServerIOS::screen_get_position(int p_screen) const {
return Size2i();
}
diff --git a/platform/linuxbsd/x11/display_server_x11.cpp b/platform/linuxbsd/x11/display_server_x11.cpp
index a9561ababb..ea109a8816 100644
--- a/platform/linuxbsd/x11/display_server_x11.cpp
+++ b/platform/linuxbsd/x11/display_server_x11.cpp
@@ -751,11 +751,22 @@ int DisplayServerX11::get_screen_count() const {
return count;
}
+int DisplayServerX11::get_primary_screen() const {
+ return XDefaultScreen(x11_display);
+}
+
Rect2i DisplayServerX11::_screen_get_rect(int p_screen) const {
Rect2i rect(0, 0, 0, 0);
- if (p_screen == SCREEN_OF_MAIN_WINDOW) {
- p_screen = window_get_current_screen();
+ switch (p_screen) {
+ case SCREEN_PRIMARY: {
+ p_screen = get_primary_screen();
+ } break;
+ case SCREEN_OF_MAIN_WINDOW: {
+ p_screen = window_get_current_screen(MAIN_WINDOW_ID);
+ } break;
+ default:
+ break;
}
ERR_FAIL_COND_V(p_screen < 0, rect);
@@ -822,8 +833,15 @@ int bad_window_error_handler(Display *display, XErrorEvent *error) {
Rect2i DisplayServerX11::screen_get_usable_rect(int p_screen) const {
_THREAD_SAFE_METHOD_
- if (p_screen == SCREEN_OF_MAIN_WINDOW) {
- p_screen = window_get_current_screen();
+ switch (p_screen) {
+ case SCREEN_PRIMARY: {
+ p_screen = get_primary_screen();
+ } break;
+ case SCREEN_OF_MAIN_WINDOW: {
+ p_screen = window_get_current_screen(MAIN_WINDOW_ID);
+ } break;
+ default:
+ break;
}
int screen_count = get_screen_count();
@@ -1102,8 +1120,15 @@ Rect2i DisplayServerX11::screen_get_usable_rect(int p_screen) const {
int DisplayServerX11::screen_get_dpi(int p_screen) const {
_THREAD_SAFE_METHOD_
- if (p_screen == SCREEN_OF_MAIN_WINDOW) {
- p_screen = window_get_current_screen();
+ switch (p_screen) {
+ case SCREEN_PRIMARY: {
+ p_screen = get_primary_screen();
+ } break;
+ case SCREEN_OF_MAIN_WINDOW: {
+ p_screen = window_get_current_screen(MAIN_WINDOW_ID);
+ } break;
+ default:
+ break;
}
//invalid screen?
@@ -1147,8 +1172,15 @@ int DisplayServerX11::screen_get_dpi(int p_screen) const {
float DisplayServerX11::screen_get_refresh_rate(int p_screen) const {
_THREAD_SAFE_METHOD_
- if (p_screen == SCREEN_OF_MAIN_WINDOW) {
- p_screen = window_get_current_screen();
+ switch (p_screen) {
+ case SCREEN_PRIMARY: {
+ p_screen = get_primary_screen();
+ } break;
+ case SCREEN_OF_MAIN_WINDOW: {
+ p_screen = window_get_current_screen(MAIN_WINDOW_ID);
+ } break;
+ default:
+ break;
}
//invalid screen?
@@ -1235,10 +1267,10 @@ Vector<DisplayServer::WindowID> DisplayServerX11::get_window_list() const {
return ret;
}
-DisplayServer::WindowID DisplayServerX11::create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect, int p_screen) {
+DisplayServer::WindowID DisplayServerX11::create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect) {
_THREAD_SAFE_METHOD_
- WindowID id = _create_window(p_mode, p_vsync_mode, p_flags, p_rect, p_screen);
+ WindowID id = _create_window(p_mode, p_vsync_mode, p_flags, p_rect);
for (int i = 0; i < WINDOW_FLAG_MAX; i++) {
if (p_flags & (1 << i)) {
window_set_flag(WindowFlags(i), true, id);
@@ -1500,8 +1532,15 @@ void DisplayServerX11::window_set_current_screen(int p_screen, WindowID p_window
ERR_FAIL_COND(!windows.has(p_window));
WindowData &wd = windows[p_window];
- if (p_screen == SCREEN_OF_MAIN_WINDOW) {
- p_screen = window_get_current_screen();
+ switch (p_screen) {
+ case SCREEN_PRIMARY: {
+ p_screen = get_primary_screen();
+ } break;
+ case SCREEN_OF_MAIN_WINDOW: {
+ p_screen = window_get_current_screen(MAIN_WINDOW_ID);
+ } break;
+ default:
+ break;
}
// Check if screen is valid
@@ -1521,9 +1560,10 @@ void DisplayServerX11::window_set_current_screen(int p_screen, WindowID p_window
Point2i wpos = window_get_position(p_window) - screen_get_position(window_get_current_screen(p_window));
Size2i wsize = window_get_size(p_window);
wpos += srect.position;
-
- wpos.x = CLAMP(wpos.x, srect.position.x, srect.position.x + srect.size.width - wsize.width / 3);
- wpos.y = CLAMP(wpos.y, srect.position.y, srect.position.y + srect.size.height - wsize.height / 3);
+ if (srect != Rect2i()) {
+ wpos.x = CLAMP(wpos.x, srect.position.x, srect.position.x + srect.size.width - wsize.width / 3);
+ wpos.y = CLAMP(wpos.y, srect.position.y, srect.position.y + srect.size.height - wsize.height / 3);
+ }
window_set_position(wpos, p_window);
}
}
@@ -4519,8 +4559,8 @@ Vector<String> DisplayServerX11::get_rendering_drivers_func() {
return drivers;
}
-DisplayServer *DisplayServerX11::create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, Error &r_error) {
- DisplayServer *ds = memnew(DisplayServerX11(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_position, p_resolution, r_error));
+DisplayServer *DisplayServerX11::create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Error &r_error) {
+ DisplayServer *ds = memnew(DisplayServerX11(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_position, p_resolution, p_screen, r_error));
if (r_error != OK) {
if (p_rendering_driver == "vulkan") {
String executable_name = OS::get_singleton()->get_executable_path().get_file();
@@ -4541,7 +4581,7 @@ DisplayServer *DisplayServerX11::create_func(const String &p_rendering_driver, W
return ds;
}
-DisplayServerX11::WindowID DisplayServerX11::_create_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect, int p_screen) {
+DisplayServerX11::WindowID DisplayServerX11::_create_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect) {
//Create window
XVisualInfo visualInfo;
@@ -4617,30 +4657,19 @@ DisplayServerX11::WindowID DisplayServerX11::_create_window(WindowMode p_mode, V
valuemask |= CWOverrideRedirect | CWSaveUnder;
}
+ int rq_screen = get_screen_from_rect(p_rect);
+ if (rq_screen < 0) {
+ rq_screen = get_primary_screen(); // Requested window rect is outside any screen bounds.
+ }
+
Rect2i win_rect = p_rect;
if (p_mode == WINDOW_MODE_FULLSCREEN || p_mode == WINDOW_MODE_EXCLUSIVE_FULLSCREEN) {
- Rect2i screen_rect = Rect2i(screen_get_position(p_screen), screen_get_size(p_screen));
+ Rect2i screen_rect = Rect2i(screen_get_position(rq_screen), screen_get_size(rq_screen));
win_rect = screen_rect;
} else {
- int nearest_area = 0;
- int pos_screen = -1;
- for (int i = 0; i < get_screen_count(); i++) {
- Rect2i r;
- r.position = screen_get_position(i);
- r.size = screen_get_size(i);
- Rect2 inters = r.intersection(p_rect);
-
- int area = inters.size.width * inters.size.height;
- if (area > nearest_area) {
- pos_screen = i;
- nearest_area = area;
- }
- }
-
- Rect2i srect = screen_get_usable_rect(p_screen);
- Point2i wpos = p_rect.position - ((pos_screen >= 0) ? screen_get_position(pos_screen) : Vector2i());
- wpos += srect.position;
+ Rect2i srect = screen_get_usable_rect(rq_screen);
+ Point2i wpos = p_rect.position;
wpos.x = CLAMP(wpos.x, srect.position.x, srect.position.x + srect.size.width - p_rect.size.width / 3);
wpos.y = CLAMP(wpos.y, srect.position.y, srect.position.y + srect.size.height - p_rect.size.height / 3);
@@ -4811,7 +4840,7 @@ DisplayServerX11::WindowID DisplayServerX11::_create_window(WindowMode p_mode, V
return id;
}
-DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, Error &r_error) {
+DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Error &r_error) {
#ifdef DEBUG_ENABLED
int dylibloader_verbose = 1;
#else
@@ -5075,16 +5104,17 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode
ERR_FAIL_MSG("Video driver not found");
}
- Point2i window_position(
- (screen_get_size(0).width - p_resolution.width) / 2,
- (screen_get_size(0).height - p_resolution.height) / 2);
- window_position += screen_get_position(0);
-
+ Point2i window_position;
if (p_position != nullptr) {
window_position = *p_position;
+ } else {
+ if (p_screen == SCREEN_OF_MAIN_WINDOW) {
+ p_screen = SCREEN_PRIMARY;
+ }
+ window_position = screen_get_position(p_screen) + (screen_get_size(p_screen) - p_resolution) / 2;
}
- WindowID main_window = _create_window(p_mode, p_vsync_mode, p_flags, Rect2i(window_position, p_resolution), 0);
+ WindowID main_window = _create_window(p_mode, p_vsync_mode, p_flags, Rect2i(window_position, p_resolution));
if (main_window == INVALID_WINDOW_ID) {
r_error = ERR_CANT_CREATE;
return;
diff --git a/platform/linuxbsd/x11/display_server_x11.h b/platform/linuxbsd/x11/display_server_x11.h
index b8820c843b..2fac446fcf 100644
--- a/platform/linuxbsd/x11/display_server_x11.h
+++ b/platform/linuxbsd/x11/display_server_x11.h
@@ -185,7 +185,7 @@ class DisplayServerX11 : public DisplayServer {
WindowID last_focused_window = INVALID_WINDOW_ID;
WindowID window_id_counter = MAIN_WINDOW_ID;
- WindowID _create_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect, int p_screen);
+ WindowID _create_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect);
String internal_clipboard;
String internal_clipboard_primary;
@@ -352,6 +352,7 @@ public:
virtual String clipboard_get_primary() const override;
virtual int get_screen_count() const override;
+ virtual int get_primary_screen() const override;
virtual Point2i screen_get_position(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
virtual Size2i screen_get_size(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
virtual Rect2i screen_get_usable_rect(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
@@ -365,7 +366,7 @@ public:
virtual Vector<DisplayServer::WindowID> get_window_list() const override;
- virtual WindowID create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect = Rect2i(), int p_screen = 0) override;
+ virtual WindowID create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect = Rect2i()) override;
virtual void show_window(WindowID p_id) override;
virtual void delete_sub_window(WindowID p_id) override;
@@ -453,12 +454,12 @@ public:
virtual void set_native_icon(const String &p_filename) override;
virtual void set_icon(const Ref<Image> &p_icon) override;
- static DisplayServer *create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, Error &r_error);
+ static DisplayServer *create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Error &r_error);
static Vector<String> get_rendering_drivers_func();
static void register_x11_driver();
- DisplayServerX11(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, Error &r_error);
+ DisplayServerX11(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Error &r_error);
~DisplayServerX11();
};
diff --git a/platform/macos/display_server_macos.h b/platform/macos/display_server_macos.h
index 5c4267c0e9..2927c67890 100644
--- a/platform/macos/display_server_macos.h
+++ b/platform/macos/display_server_macos.h
@@ -191,7 +191,7 @@ private:
const NSMenu *_get_menu_root(const String &p_menu_root) const;
NSMenu *_get_menu_root(const String &p_menu_root);
- WindowID _create_window(WindowMode p_mode, VSyncMode p_vsync_mode, const Rect2i &p_rect, int p_screen);
+ WindowID _create_window(WindowMode p_mode, VSyncMode p_vsync_mode, const Rect2i &p_rect);
void _update_window_style(WindowData p_wd);
void _set_window_per_pixel_transparency_enabled(bool p_enabled, WindowID p_window);
@@ -324,6 +324,7 @@ public:
virtual String clipboard_get() const override;
virtual int get_screen_count() const override;
+ virtual int get_primary_screen() const override;
virtual Point2i screen_get_position(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
virtual Size2i screen_get_size(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
virtual int screen_get_dpi(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
@@ -336,7 +337,7 @@ public:
virtual Vector<int> get_window_list() const override;
- virtual WindowID create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect = Rect2i(), int p_screen = 0) override;
+ virtual WindowID create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect = Rect2i()) override;
virtual void show_window(WindowID p_id) override;
virtual void delete_sub_window(WindowID p_id) override;
@@ -435,12 +436,12 @@ public:
virtual void set_native_icon(const String &p_filename) override;
virtual void set_icon(const Ref<Image> &p_icon) override;
- static DisplayServer *create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, Error &r_error);
+ static DisplayServer *create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Error &r_error);
static Vector<String> get_rendering_drivers_func();
static void register_macos_driver();
- DisplayServerMacOS(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, Error &r_error);
+ DisplayServerMacOS(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Error &r_error);
~DisplayServerMacOS();
};
diff --git a/platform/macos/display_server_macos.mm b/platform/macos/display_server_macos.mm
index 2fc63ea5d4..3bbb3e35fb 100644
--- a/platform/macos/display_server_macos.mm
+++ b/platform/macos/display_server_macos.mm
@@ -109,7 +109,7 @@ NSMenu *DisplayServerMacOS::_get_menu_root(const String &p_menu_root) {
return menu;
}
-DisplayServerMacOS::WindowID DisplayServerMacOS::_create_window(WindowMode p_mode, VSyncMode p_vsync_mode, const Rect2i &p_rect, int p_screen) {
+DisplayServerMacOS::WindowID DisplayServerMacOS::_create_window(WindowMode p_mode, VSyncMode p_vsync_mode, const Rect2i &p_rect) {
WindowID id;
const float scale = screen_get_max_scale();
{
@@ -119,36 +119,30 @@ DisplayServerMacOS::WindowID DisplayServerMacOS::_create_window(WindowMode p_mod
ERR_FAIL_COND_V_MSG(wd.window_delegate == nil, INVALID_WINDOW_ID, "Can't create a window delegate");
[wd.window_delegate setWindowID:window_id_counter];
- int nearest_area = 0;
- int pos_screen = -1;
- for (int i = 0; i < get_screen_count(); i++) {
- Rect2i r = screen_get_usable_rect(i);
- Rect2 inters = r.intersection(p_rect);
- int area = inters.size.width * inters.size.height;
- if (area > nearest_area && area > 0) {
- pos_screen = i;
- nearest_area = area;
- }
+ int rq_screen = get_screen_from_rect(p_rect);
+ if (rq_screen < 0) {
+ rq_screen = get_primary_screen(); // Requested window rect is outside any screen bounds.
}
- Rect2i srect = screen_get_usable_rect(p_screen);
- Point2i wpos = p_rect.position - ((pos_screen >= 0) ? screen_get_position(pos_screen) : Vector2i());
- wpos += srect.position;
- wpos.x = CLAMP(wpos.x, srect.position.x, srect.position.x + srect.size.width - p_rect.size.width / 3);
- wpos.y = CLAMP(wpos.y, srect.position.y, srect.position.y + srect.size.height - p_rect.size.height / 3);
+ Rect2i srect = screen_get_usable_rect(rq_screen);
+ Point2i wpos = p_rect.position;
+ if (srect != Rect2i()) {
+ wpos.x = CLAMP(wpos.x, srect.position.x, srect.position.x + srect.size.width - p_rect.size.width / 3);
+ wpos.y = CLAMP(wpos.y, srect.position.y, srect.position.y + srect.size.height - p_rect.size.height / 3);
+ }
// OS X native y-coordinate relative to _get_screens_origin() is negative,
// Godot passes a positive value.
wpos.y *= -1;
wpos += _get_screens_origin();
+ wpos /= scale;
// initWithContentRect uses bottom-left corner of the window’s frame as origin.
wd.window_object = [[GodotWindow alloc]
- initWithContentRect:NSMakeRect(0, 0, p_rect.size.width / scale, p_rect.size.height / scale)
+ initWithContentRect:NSMakeRect(100, 100, p_rect.size.width / scale, p_rect.size.height / scale)
styleMask:NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable | NSWindowStyleMaskResizable
backing:NSBackingStoreBuffered
defer:NO];
ERR_FAIL_COND_V_MSG(wd.window_object == nil, INVALID_WINDOW_ID, "Can't create a window");
- [wd.window_object setFrameTopLeftPoint:NSMakePoint(wpos.x / scale, wpos.y / scale)];
[wd.window_object setWindowID:window_id_counter];
wd.window_view = [[GodotContentView alloc] init];
@@ -186,6 +180,16 @@ DisplayServerMacOS::WindowID DisplayServerMacOS::_create_window(WindowMode p_mod
window_set_vsync_mode(p_vsync_mode, window_id_counter);
#endif
[wd.window_view updateLayerDelegate];
+
+ const NSRect contentRect = [wd.window_view frame];
+ const NSRect windowRect = [wd.window_object frame];
+ const NSRect nsrect = [wd.window_object convertRectToScreen:contentRect];
+ Point2i offset;
+ offset.x = (nsrect.origin.x - windowRect.origin.x);
+ offset.y = (nsrect.origin.y + nsrect.size.height);
+ offset.y -= (windowRect.origin.y + windowRect.size.height);
+ [wd.window_object setFrameTopLeftPoint:NSMakePoint(wpos.x - offset.x, wpos.y - offset.y)];
+
id = window_id_counter++;
windows[id] = wd;
}
@@ -2077,11 +2081,22 @@ int DisplayServerMacOS::get_screen_count() const {
return [screenArray count];
}
+int DisplayServerMacOS::get_primary_screen() const {
+ return 0;
+}
+
Point2i DisplayServerMacOS::screen_get_position(int p_screen) const {
_THREAD_SAFE_METHOD_
- if (p_screen == SCREEN_OF_MAIN_WINDOW) {
- p_screen = window_get_current_screen();
+ switch (p_screen) {
+ case SCREEN_PRIMARY: {
+ p_screen = get_primary_screen();
+ } break;
+ case SCREEN_OF_MAIN_WINDOW: {
+ p_screen = window_get_current_screen(MAIN_WINDOW_ID);
+ } break;
+ default:
+ break;
}
Point2i position = _get_native_screen_position(p_screen) - _get_screens_origin();
@@ -2094,8 +2109,15 @@ Point2i DisplayServerMacOS::screen_get_position(int p_screen) const {
Size2i DisplayServerMacOS::screen_get_size(int p_screen) const {
_THREAD_SAFE_METHOD_
- if (p_screen == SCREEN_OF_MAIN_WINDOW) {
- p_screen = window_get_current_screen();
+ switch (p_screen) {
+ case SCREEN_PRIMARY: {
+ p_screen = get_primary_screen();
+ } break;
+ case SCREEN_OF_MAIN_WINDOW: {
+ p_screen = window_get_current_screen(MAIN_WINDOW_ID);
+ } break;
+ default:
+ break;
}
NSArray *screenArray = [NSScreen screens];
@@ -2111,8 +2133,15 @@ Size2i DisplayServerMacOS::screen_get_size(int p_screen) const {
int DisplayServerMacOS::screen_get_dpi(int p_screen) const {
_THREAD_SAFE_METHOD_
- if (p_screen == SCREEN_OF_MAIN_WINDOW) {
- p_screen = window_get_current_screen();
+ switch (p_screen) {
+ case SCREEN_PRIMARY: {
+ p_screen = get_primary_screen();
+ } break;
+ case SCREEN_OF_MAIN_WINDOW: {
+ p_screen = window_get_current_screen(MAIN_WINDOW_ID);
+ } break;
+ default:
+ break;
}
NSArray *screenArray = [NSScreen screens];
@@ -2135,9 +2164,17 @@ int DisplayServerMacOS::screen_get_dpi(int p_screen) const {
float DisplayServerMacOS::screen_get_scale(int p_screen) const {
_THREAD_SAFE_METHOD_
- if (p_screen == SCREEN_OF_MAIN_WINDOW) {
- p_screen = window_get_current_screen();
+ switch (p_screen) {
+ case SCREEN_PRIMARY: {
+ p_screen = get_primary_screen();
+ } break;
+ case SCREEN_OF_MAIN_WINDOW: {
+ p_screen = window_get_current_screen(MAIN_WINDOW_ID);
+ } break;
+ default:
+ break;
}
+
if (OS::get_singleton()->is_hidpi_allowed()) {
NSArray *screenArray = [NSScreen screens];
if ((NSUInteger)p_screen < [screenArray count]) {
@@ -2160,8 +2197,15 @@ float DisplayServerMacOS::screen_get_max_scale() const {
Rect2i DisplayServerMacOS::screen_get_usable_rect(int p_screen) const {
_THREAD_SAFE_METHOD_
- if (p_screen == SCREEN_OF_MAIN_WINDOW) {
- p_screen = window_get_current_screen();
+ switch (p_screen) {
+ case SCREEN_PRIMARY: {
+ p_screen = get_primary_screen();
+ } break;
+ case SCREEN_OF_MAIN_WINDOW: {
+ p_screen = window_get_current_screen(MAIN_WINDOW_ID);
+ } break;
+ default:
+ break;
}
NSArray *screenArray = [NSScreen screens];
@@ -2182,8 +2226,15 @@ Rect2i DisplayServerMacOS::screen_get_usable_rect(int p_screen) const {
float DisplayServerMacOS::screen_get_refresh_rate(int p_screen) const {
_THREAD_SAFE_METHOD_
- if (p_screen == SCREEN_OF_MAIN_WINDOW) {
- p_screen = window_get_current_screen();
+ switch (p_screen) {
+ case SCREEN_PRIMARY: {
+ p_screen = get_primary_screen();
+ } break;
+ case SCREEN_OF_MAIN_WINDOW: {
+ p_screen = window_get_current_screen(MAIN_WINDOW_ID);
+ } break;
+ default:
+ break;
}
NSArray *screenArray = [NSScreen screens];
@@ -2225,10 +2276,10 @@ Vector<DisplayServer::WindowID> DisplayServerMacOS::get_window_list() const {
return ret;
}
-DisplayServer::WindowID DisplayServerMacOS::create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect, int p_screen) {
+DisplayServer::WindowID DisplayServerMacOS::create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect) {
_THREAD_SAFE_METHOD_
- WindowID id = _create_window(p_mode, p_vsync_mode, p_rect, p_screen);
+ WindowID id = _create_window(p_mode, p_vsync_mode, p_rect);
for (int i = 0; i < WINDOW_FLAG_MAX; i++) {
if (p_flags & (1 << i)) {
window_set_flag(WindowFlags(i), true, id);
@@ -3520,8 +3571,8 @@ void DisplayServerMacOS::set_icon(const Ref<Image> &p_icon) {
[NSApp setApplicationIconImage:nsimg];
}
-DisplayServer *DisplayServerMacOS::create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, Error &r_error) {
- DisplayServer *ds = memnew(DisplayServerMacOS(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_position, p_resolution, r_error));
+DisplayServer *DisplayServerMacOS::create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Error &r_error) {
+ DisplayServer *ds = memnew(DisplayServerMacOS(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_position, p_resolution, p_screen, r_error));
if (r_error != OK) {
if (p_rendering_driver == "vulkan") {
String executable_command;
@@ -3690,7 +3741,7 @@ bool DisplayServerMacOS::mouse_process_popups(bool p_close) {
return closed;
}
-DisplayServerMacOS::DisplayServerMacOS(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, Error &r_error) {
+DisplayServerMacOS::DisplayServerMacOS(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Error &r_error) {
Input::get_singleton()->set_event_dispatch_function(_dispatch_input_events);
r_error = OK;
@@ -3796,15 +3847,17 @@ DisplayServerMacOS::DisplayServerMacOS(const String &p_rendering_driver, WindowM
}
#endif
- Point2i window_position(
- screen_get_position(0).x + (screen_get_size(0).width - p_resolution.width) / 2,
- screen_get_position(0).y + (screen_get_size(0).height - p_resolution.height) / 2);
-
+ Point2i window_position;
if (p_position != nullptr) {
window_position = *p_position;
+ } else {
+ if (p_screen == SCREEN_OF_MAIN_WINDOW) {
+ p_screen = SCREEN_PRIMARY;
+ }
+ window_position = screen_get_position(p_screen) + (screen_get_size(p_screen) - p_resolution) / 2;
}
- WindowID main_window = _create_window(p_mode, p_vsync_mode, Rect2i(window_position, p_resolution), 0);
+ WindowID main_window = _create_window(p_mode, p_vsync_mode, Rect2i(window_position, p_resolution));
ERR_FAIL_COND(main_window == INVALID_WINDOW_ID);
for (int i = 0; i < WINDOW_FLAG_MAX; i++) {
if (p_flags & (1 << i)) {
diff --git a/platform/web/display_server_web.cpp b/platform/web/display_server_web.cpp
index c41e64d8f3..2c69c0873d 100644
--- a/platform/web/display_server_web.cpp
+++ b/platform/web/display_server_web.cpp
@@ -746,11 +746,11 @@ void DisplayServerWeb::_dispatch_input_event(const Ref<InputEvent> &p_event) {
}
}
-DisplayServer *DisplayServerWeb::create_func(const String &p_rendering_driver, WindowMode p_window_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Point2i *p_position, const Size2i &p_resolution, Error &r_error) {
- return memnew(DisplayServerWeb(p_rendering_driver, p_window_mode, p_vsync_mode, p_flags, p_position, p_resolution, r_error));
+DisplayServer *DisplayServerWeb::create_func(const String &p_rendering_driver, WindowMode p_window_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Point2i *p_position, const Size2i &p_resolution, int p_screen, Error &r_error) {
+ return memnew(DisplayServerWeb(p_rendering_driver, p_window_mode, p_vsync_mode, p_flags, p_position, p_resolution, p_screen, r_error));
}
-DisplayServerWeb::DisplayServerWeb(const String &p_rendering_driver, WindowMode p_window_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Point2i *p_position, const Size2i &p_resolution, Error &r_error) {
+DisplayServerWeb::DisplayServerWeb(const String &p_rendering_driver, WindowMode p_window_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Point2i *p_position, const Size2i &p_resolution, int p_screen, Error &r_error) {
r_error = OK; // Always succeeds for now.
// Ensure the canvas ID.
@@ -864,6 +864,10 @@ int DisplayServerWeb::get_screen_count() const {
return 1;
}
+int DisplayServerWeb::get_primary_screen() const {
+ return 0;
+}
+
Point2i DisplayServerWeb::screen_get_position(int p_screen) const {
return Point2i(); // TODO offsetX/Y?
}
diff --git a/platform/web/display_server_web.h b/platform/web/display_server_web.h
index ab393c6b67..6d76af4e56 100644
--- a/platform/web/display_server_web.h
+++ b/platform/web/display_server_web.h
@@ -97,7 +97,7 @@ private:
static void _js_utterance_callback(int p_event, int p_id, int p_pos);
static Vector<String> get_rendering_drivers_func();
- static DisplayServer *create_func(const String &p_rendering_driver, WindowMode p_window_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, Error &r_error);
+ static DisplayServer *create_func(const String &p_rendering_driver, WindowMode p_window_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Error &r_error);
static void _dispatch_input_event(const Ref<InputEvent> &p_event);
@@ -151,6 +151,7 @@ public:
// screen
virtual int get_screen_count() const override;
+ virtual int get_primary_screen() const override;
virtual Point2i screen_get_position(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
virtual Size2i screen_get_size(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
virtual Rect2i screen_get_usable_rect(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
@@ -223,7 +224,7 @@ public:
virtual void swap_buffers() override;
static void register_web_driver();
- DisplayServerWeb(const String &p_rendering_driver, WindowMode p_window_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Point2i *p_position, const Size2i &p_resolution, Error &r_error);
+ DisplayServerWeb(const String &p_rendering_driver, WindowMode p_window_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Point2i *p_position, const Size2i &p_resolution, int p_screen, Error &r_error);
~DisplayServerWeb();
};
diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp
index c203f17232..114bfcb6f8 100644
--- a/platform/windows/display_server_windows.cpp
+++ b/platform/windows/display_server_windows.cpp
@@ -254,7 +254,7 @@ void DisplayServerWindows::warp_mouse(const Point2i &p_position) {
Point2i DisplayServerWindows::mouse_get_position() const {
POINT p;
GetCursorPos(&p);
- return Point2i(p.x, p.y);
+ return Point2i(p.x, p.y) - _get_screens_origin();
}
MouseButton DisplayServerWindows::mouse_get_button_state() const {
@@ -346,6 +346,19 @@ typedef struct {
HMONITOR monitor;
} EnumScreenData;
+static BOOL CALLBACK _MonitorEnumProcPrim(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) {
+ EnumScreenData *data = (EnumScreenData *)dwData;
+ if (data->monitor == hMonitor) {
+ if ((lprcMonitor->left == 0) && (lprcMonitor->top == 0)) {
+ data->screen = data->count;
+ return FALSE;
+ }
+ }
+
+ data->count++;
+ return TRUE;
+}
+
static BOOL CALLBACK _MonitorEnumProcScreen(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) {
EnumScreenData *data = (EnumScreenData *)dwData;
if (data->monitor == hMonitor) {
@@ -370,6 +383,12 @@ int DisplayServerWindows::get_screen_count() const {
return data;
}
+int DisplayServerWindows::get_primary_screen() const {
+ EnumScreenData data = { 0, 0, 0 };
+ EnumDisplayMonitors(nullptr, nullptr, _MonitorEnumProcPrim, (LPARAM)&data);
+ return data.screen;
+}
+
typedef struct {
int count;
int screen;
@@ -387,12 +406,39 @@ static BOOL CALLBACK _MonitorEnumProcPos(HMONITOR hMonitor, HDC hdcMonitor, LPRE
return TRUE;
}
+static BOOL CALLBACK _MonitorEnumProcOrigin(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) {
+ EnumPosData *data = (EnumPosData *)dwData;
+ data->pos.x = MIN(data->pos.x, lprcMonitor->left);
+ data->pos.y = MIN(data->pos.y, lprcMonitor->top);
+
+ return TRUE;
+}
+
+Point2i DisplayServerWindows::_get_screens_origin() const {
+ _THREAD_SAFE_METHOD_
+
+ EnumPosData data = { 0, 0, Point2() };
+ EnumDisplayMonitors(nullptr, nullptr, _MonitorEnumProcOrigin, (LPARAM)&data);
+ return data.pos;
+}
+
Point2i DisplayServerWindows::screen_get_position(int p_screen) const {
_THREAD_SAFE_METHOD_
- EnumPosData data = { 0, p_screen == SCREEN_OF_MAIN_WINDOW ? window_get_current_screen() : p_screen, Point2() };
+ switch (p_screen) {
+ case SCREEN_PRIMARY: {
+ p_screen = get_primary_screen();
+ } break;
+ case SCREEN_OF_MAIN_WINDOW: {
+ p_screen = window_get_current_screen(MAIN_WINDOW_ID);
+ } break;
+ default:
+ break;
+ }
+
+ EnumPosData data = { 0, p_screen, Point2() };
EnumDisplayMonitors(nullptr, nullptr, _MonitorEnumProcPos, (LPARAM)&data);
- return data.pos;
+ return data.pos - _get_screens_origin();
}
typedef struct {
@@ -427,7 +473,18 @@ static BOOL CALLBACK _MonitorEnumProcSize(HMONITOR hMonitor, HDC hdcMonitor, LPR
Size2i DisplayServerWindows::screen_get_size(int p_screen) const {
_THREAD_SAFE_METHOD_
- EnumSizeData data = { 0, p_screen == SCREEN_OF_MAIN_WINDOW ? window_get_current_screen() : p_screen, Size2() };
+ switch (p_screen) {
+ case SCREEN_PRIMARY: {
+ p_screen = get_primary_screen();
+ } break;
+ case SCREEN_OF_MAIN_WINDOW: {
+ p_screen = window_get_current_screen(MAIN_WINDOW_ID);
+ } break;
+ default:
+ break;
+ }
+
+ EnumSizeData data = { 0, p_screen, Size2() };
EnumDisplayMonitors(nullptr, nullptr, _MonitorEnumProcSize, (LPARAM)&data);
return data.size;
}
@@ -473,8 +530,20 @@ static BOOL CALLBACK _MonitorEnumProcRefreshRate(HMONITOR hMonitor, HDC hdcMonit
Rect2i DisplayServerWindows::screen_get_usable_rect(int p_screen) const {
_THREAD_SAFE_METHOD_
- EnumRectData data = { 0, p_screen == SCREEN_OF_MAIN_WINDOW ? window_get_current_screen() : p_screen, Rect2i() };
+ switch (p_screen) {
+ case SCREEN_PRIMARY: {
+ p_screen = get_primary_screen();
+ } break;
+ case SCREEN_OF_MAIN_WINDOW: {
+ p_screen = window_get_current_screen(MAIN_WINDOW_ID);
+ } break;
+ default:
+ break;
+ }
+
+ EnumRectData data = { 0, p_screen, Rect2i() };
EnumDisplayMonitors(nullptr, nullptr, _MonitorEnumProcUsableSize, (LPARAM)&data);
+ data.rect.position -= _get_screens_origin();
return data.rect;
}
@@ -549,14 +618,36 @@ static BOOL CALLBACK _MonitorEnumProcDpi(HMONITOR hMonitor, HDC hdcMonitor, LPRE
int DisplayServerWindows::screen_get_dpi(int p_screen) const {
_THREAD_SAFE_METHOD_
- EnumDpiData data = { 0, p_screen == SCREEN_OF_MAIN_WINDOW ? window_get_current_screen() : p_screen, 72 };
+ switch (p_screen) {
+ case SCREEN_PRIMARY: {
+ p_screen = get_primary_screen();
+ } break;
+ case SCREEN_OF_MAIN_WINDOW: {
+ p_screen = window_get_current_screen(MAIN_WINDOW_ID);
+ } break;
+ default:
+ break;
+ }
+
+ EnumDpiData data = { 0, p_screen, 72 };
EnumDisplayMonitors(nullptr, nullptr, _MonitorEnumProcDpi, (LPARAM)&data);
return data.dpi;
}
float DisplayServerWindows::screen_get_refresh_rate(int p_screen) const {
_THREAD_SAFE_METHOD_
- EnumRefreshRateData data = { 0, p_screen == SCREEN_OF_MAIN_WINDOW ? window_get_current_screen() : p_screen, SCREEN_REFRESH_RATE_FALLBACK };
+ switch (p_screen) {
+ case SCREEN_PRIMARY: {
+ p_screen = get_primary_screen();
+ } break;
+ case SCREEN_OF_MAIN_WINDOW: {
+ p_screen = window_get_current_screen(MAIN_WINDOW_ID);
+ } break;
+ default:
+ break;
+ }
+
+ EnumRefreshRateData data = { 0, p_screen, SCREEN_REFRESH_RATE_FALLBACK };
EnumDisplayMonitors(nullptr, nullptr, _MonitorEnumProcRefreshRate, (LPARAM)&data);
return data.rate;
}
@@ -612,9 +703,10 @@ Vector<DisplayServer::WindowID> DisplayServerWindows::get_window_list() const {
}
DisplayServer::WindowID DisplayServerWindows::get_window_at_screen_position(const Point2i &p_position) const {
+ Point2i offset = _get_screens_origin();
POINT p;
- p.x = p_position.x;
- p.y = p_position.y;
+ p.x = p_position.x + offset.x;
+ p.y = p_position.y + offset.y;
HWND hwnd = WindowFromPoint(p);
for (const KeyValue<WindowID, WindowData> &E : windows) {
if (E.value.hWnd == hwnd) {
@@ -625,10 +717,10 @@ DisplayServer::WindowID DisplayServerWindows::get_window_at_screen_position(cons
return INVALID_WINDOW_ID;
}
-DisplayServer::WindowID DisplayServerWindows::create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect, int p_screen) {
+DisplayServer::WindowID DisplayServerWindows::create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect) {
_THREAD_SAFE_METHOD_
- WindowID window_id = _create_window(p_mode, p_vsync_mode, p_flags, p_rect, p_screen);
+ WindowID window_id = _create_window(p_mode, p_vsync_mode, p_flags, p_rect);
ERR_FAIL_COND_V_MSG(window_id == INVALID_WINDOW_ID, INVALID_WINDOW_ID, "Failed to create sub window.");
WindowData &wd = windows[window_id];
@@ -870,7 +962,7 @@ void DisplayServerWindows::window_set_current_screen(int p_screen, WindowID p_wi
}
const WindowData &wd = windows[p_window];
if (wd.fullscreen) {
- Point2 pos = screen_get_position(p_screen);
+ Point2 pos = screen_get_position(p_screen) + _get_screens_origin();
Size2 size = screen_get_size(p_screen);
MoveWindow(wd.hWnd, pos.x, pos.y, size.width, size.height, TRUE);
@@ -911,7 +1003,7 @@ Point2i DisplayServerWindows::window_get_position(WindowID p_window) const {
ClientToScreen(wd.hWnd, &point);
- return Point2i(point.x, point.y);
+ return Point2i(point.x, point.y) - _get_screens_origin();
}
Point2i DisplayServerWindows::window_get_position_with_decorations(WindowID p_window) const {
@@ -926,7 +1018,7 @@ Point2i DisplayServerWindows::window_get_position_with_decorations(WindowID p_wi
RECT r;
if (GetWindowRect(wd.hWnd, &r)) {
- return Point2i(r.left, r.top);
+ return Point2i(r.left, r.top) - _get_screens_origin();
}
return Point2i();
@@ -956,11 +1048,13 @@ void DisplayServerWindows::window_set_position(const Point2i &p_position, Window
return;
}
+ Point2i offset = _get_screens_origin();
+
RECT rc;
- rc.left = p_position.x;
- rc.right = p_position.x + wd.width;
- rc.bottom = p_position.y + wd.height;
- rc.top = p_position.y;
+ rc.left = p_position.x + offset.x;
+ rc.right = p_position.x + wd.width + offset.x;
+ rc.bottom = p_position.y + wd.height + offset.y;
+ rc.top = p_position.y + offset.y;
const DWORD style = GetWindowLongPtr(wd.hWnd, GWL_STYLE);
const DWORD exStyle = GetWindowLongPtr(wd.hWnd, GWL_EXSTYLE);
@@ -1296,7 +1390,7 @@ void DisplayServerWindows::window_set_mode(WindowMode p_mode, WindowID p_window)
}
int cs = window_get_current_screen(p_window);
- Point2 pos = screen_get_position(cs);
+ Point2 pos = screen_get_position(cs) + _get_screens_origin();
Size2 size = screen_get_size(cs);
wd.fullscreen = true;
@@ -2277,7 +2371,7 @@ LRESULT DisplayServerWindows::MouseProc(int code, WPARAM wParam, LPARAM lParam)
case WM_RBUTTONDOWN:
case WM_MBUTTONDOWN: {
MOUSEHOOKSTRUCT *ms = (MOUSEHOOKSTRUCT *)lParam;
- Point2i pos = Point2i(ms->pt.x, ms->pt.y);
+ Point2i pos = Point2i(ms->pt.x, ms->pt.y) - _get_screens_origin();
List<WindowID>::Element *C = nullptr;
List<WindowID>::Element *E = popup_list.back();
// Find top popup to close.
@@ -3130,10 +3224,12 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
ClientToScreen(hWnd, (POINT *)&rect.left);
ClientToScreen(hWnd, (POINT *)&rect.right);
window_client_rect = Rect2i(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top);
+ window_client_rect.position -= _get_screens_origin();
RECT wrect;
GetWindowRect(hWnd, &wrect);
window_rect = Rect2i(wrect.left, wrect.top, wrect.right - wrect.left, wrect.bottom - wrect.top);
+ window_rect.position -= _get_screens_origin();
}
WINDOWPOS *window_pos_params = (WINDOWPOS *)lParam;
@@ -3539,7 +3635,7 @@ void DisplayServerWindows::_update_tablet_ctx(const String &p_old_driver, const
}
}
-DisplayServer::WindowID DisplayServerWindows::_create_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect, int p_screen) {
+DisplayServer::WindowID DisplayServerWindows::_create_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect) {
DWORD dwExStyle;
DWORD dwStyle;
@@ -3552,40 +3648,38 @@ DisplayServer::WindowID DisplayServerWindows::_create_window(WindowMode p_mode,
WindowRect.top = p_rect.position.y;
WindowRect.bottom = p_rect.position.y + p_rect.size.y;
+ int rq_screen = get_screen_from_rect(p_rect);
+ if (rq_screen < 0) {
+ rq_screen = get_primary_screen(); // Requested window rect is outside any screen bounds.
+ }
+
if (p_mode == WINDOW_MODE_FULLSCREEN || p_mode == WINDOW_MODE_EXCLUSIVE_FULLSCREEN) {
- Rect2i screen_rect = Rect2i(screen_get_position(p_screen), screen_get_size(p_screen));
+ Rect2i screen_rect = Rect2i(screen_get_position(rq_screen), screen_get_size(rq_screen));
WindowRect.left = screen_rect.position.x;
WindowRect.right = screen_rect.position.x + screen_rect.size.x;
WindowRect.top = screen_rect.position.y;
WindowRect.bottom = screen_rect.position.y + screen_rect.size.y;
} else {
- int nearest_area = 0;
- int pos_screen = -1;
- for (int i = 0; i < get_screen_count(); i++) {
- Rect2i r;
- r.position = screen_get_position(i);
- r.size = screen_get_size(i);
- Rect2 inters = r.intersection(p_rect);
- int area = inters.size.width * inters.size.height;
- if (area > nearest_area) {
- pos_screen = i;
- nearest_area = area;
- }
+ Rect2i srect = screen_get_usable_rect(rq_screen);
+ Point2i wpos = p_rect.position;
+ if (srect != Rect2i()) {
+ wpos.x = CLAMP(wpos.x, srect.position.x, srect.position.x + srect.size.width - p_rect.size.width / 3);
+ wpos.y = CLAMP(wpos.y, srect.position.y, srect.position.y + srect.size.height - p_rect.size.height / 3);
}
- Rect2i srect = screen_get_usable_rect(p_screen);
- Point2i wpos = p_rect.position - ((pos_screen >= 0) ? screen_get_position(pos_screen) : Vector2i());
- wpos += srect.position;
- wpos.x = CLAMP(wpos.x, srect.position.x, srect.position.x + srect.size.width - p_rect.size.width / 3);
- wpos.y = CLAMP(wpos.y, srect.position.y, srect.position.y + srect.size.height - p_rect.size.height / 3);
-
WindowRect.left = wpos.x;
WindowRect.right = wpos.x + p_rect.size.x;
WindowRect.top = wpos.y;
WindowRect.bottom = wpos.y + p_rect.size.y;
}
+ Point2i offset = _get_screens_origin();
+ WindowRect.left += offset.x;
+ WindowRect.right += offset.x;
+ WindowRect.top += offset.y;
+ WindowRect.bottom += offset.y;
+
AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle);
WindowID id = window_id_counter;
@@ -3794,7 +3888,7 @@ void DisplayServerWindows::tablet_set_current_driver(const String &p_driver) {
}
}
-DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, Error &r_error) {
+DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Error &r_error) {
drop_events = false;
key_event_pos = 0;
@@ -3941,15 +4035,17 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win
mouse_monitor = SetWindowsHookEx(WH_MOUSE, ::MouseProc, nullptr, GetCurrentThreadId());
- Point2i window_position(
- (screen_get_size(0).width - p_resolution.width) / 2,
- (screen_get_size(0).height - p_resolution.height) / 2);
-
+ Point2i window_position;
if (p_position != nullptr) {
window_position = *p_position;
+ } else {
+ if (p_screen == SCREEN_OF_MAIN_WINDOW) {
+ p_screen = SCREEN_PRIMARY;
+ }
+ window_position = screen_get_position(p_screen) + (screen_get_size(p_screen) - p_resolution) / 2;
}
- WindowID main_window = _create_window(p_mode, p_vsync_mode, 0, Rect2i(window_position, p_resolution), 0);
+ WindowID main_window = _create_window(p_mode, p_vsync_mode, 0, Rect2i(window_position, p_resolution));
ERR_FAIL_COND_MSG(main_window == INVALID_WINDOW_ID, "Failed to create main window.");
joypad = new JoypadWindows(&windows[MAIN_WINDOW_ID].hWnd);
@@ -4012,8 +4108,8 @@ Vector<String> DisplayServerWindows::get_rendering_drivers_func() {
return drivers;
}
-DisplayServer *DisplayServerWindows::create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, Error &r_error) {
- DisplayServer *ds = memnew(DisplayServerWindows(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_position, p_resolution, r_error));
+DisplayServer *DisplayServerWindows::create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Error &r_error) {
+ DisplayServer *ds = memnew(DisplayServerWindows(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_position, p_resolution, p_screen, r_error));
if (r_error != OK) {
if (p_rendering_driver == "vulkan") {
String executable_name = OS::get_singleton()->get_executable_path().get_file();
diff --git a/platform/windows/display_server_windows.h b/platform/windows/display_server_windows.h
index f0171d50ad..feed9f35ed 100644
--- a/platform/windows/display_server_windows.h
+++ b/platform/windows/display_server_windows.h
@@ -426,7 +426,7 @@ class DisplayServerWindows : public DisplayServer {
uint64_t time_since_popup = 0;
Ref<Image> icon;
- WindowID _create_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect, int p_screen);
+ WindowID _create_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect);
WindowID window_id_counter = MAIN_WINDOW_ID;
RBMap<WindowID, WindowData> windows;
@@ -476,6 +476,7 @@ class DisplayServerWindows : public DisplayServer {
void _dispatch_input_event(const Ref<InputEvent> &p_event);
LRESULT _handle_early_window_message(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
+ Point2i _get_screens_origin() const;
public:
LRESULT WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
@@ -511,6 +512,7 @@ public:
virtual String clipboard_get() const override;
virtual int get_screen_count() const override;
+ virtual int get_primary_screen() const override;
virtual Point2i screen_get_position(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
virtual Size2i screen_get_size(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
virtual Rect2i screen_get_usable_rect(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
@@ -522,7 +524,7 @@ public:
virtual Vector<DisplayServer::WindowID> get_window_list() const override;
- virtual WindowID create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect = Rect2i(), int p_screen = 0) override;
+ virtual WindowID create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect = Rect2i()) override;
virtual void show_window(WindowID p_window) override;
virtual void delete_sub_window(WindowID p_window) override;
@@ -623,11 +625,11 @@ public:
virtual void set_context(Context p_context) override;
- static DisplayServer *create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, Error &r_error);
+ static DisplayServer *create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Error &r_error);
static Vector<String> get_rendering_drivers_func();
static void register_windows_driver();
- DisplayServerWindows(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, Error &r_error);
+ DisplayServerWindows(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Error &r_error);
~DisplayServerWindows();
};
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index 46d8c7df89..1287f69bef 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -1298,7 +1298,6 @@ void Viewport::_gui_show_tooltip() {
r.position.y = vr.position.y;
}
- gui.tooltip_popup->set_current_screen(window->get_current_screen());
gui.tooltip_popup->set_position(r.position);
gui.tooltip_popup->set_size(r.size);
diff --git a/scene/main/window.cpp b/scene/main/window.cpp
index d3fcf29927..c5dbfffd7b 100644
--- a/scene/main/window.cpp
+++ b/scene/main/window.cpp
@@ -223,6 +223,14 @@ void Window::_get_property_list(List<PropertyInfo> *p_list) const {
}
void Window::_validate_property(PropertyInfo &p_property) const {
+ if (p_property.name == "position" && initial_position != WINDOW_INITIAL_POSITION_ABSOLUTE) {
+ p_property.usage = PROPERTY_USAGE_NONE;
+ }
+
+ if (p_property.name == "current_screen" && initial_position != WINDOW_INITIAL_POSITION_CENTER_SCREEN) {
+ p_property.usage = PROPERTY_USAGE_NONE;
+ }
+
if (p_property.name == "theme_type_variation") {
List<StringName> names;
@@ -275,6 +283,15 @@ String Window::get_title() const {
return title;
}
+void Window::set_initial_position(Window::WindowInitialPosition p_initial_position) {
+ initial_position = p_initial_position;
+ notify_property_list_changed();
+}
+
+Window::WindowInitialPosition Window::get_initial_position() const {
+ return initial_position;
+}
+
void Window::set_current_screen(int p_screen) {
current_screen = p_screen;
if (window_id == DisplayServer::INVALID_WINDOW_ID) {
@@ -462,7 +479,13 @@ void Window::_make_window() {
}
DisplayServer::VSyncMode vsync_mode = DisplayServer::get_singleton()->window_get_vsync_mode(DisplayServer::MAIN_WINDOW_ID);
- window_id = DisplayServer::get_singleton()->create_sub_window(DisplayServer::WindowMode(mode), vsync_mode, f, Rect2i(position, size), current_screen);
+ Rect2i window_rect;
+ if (initial_position == WINDOW_INITIAL_POSITION_ABSOLUTE) {
+ window_rect = Rect2i(position, size);
+ } else if (initial_position == WINDOW_INITIAL_POSITION_CENTER_SCREEN) {
+ window_rect = Rect2i(DisplayServer::get_singleton()->screen_get_position(current_screen) + (DisplayServer::get_singleton()->screen_get_size(current_screen) - size) / 2, size);
+ }
+ window_id = DisplayServer::get_singleton()->create_sub_window(DisplayServer::WindowMode(mode), vsync_mode, f, window_rect);
ERR_FAIL_COND(window_id == DisplayServer::INVALID_WINDOW_ID);
DisplayServer::get_singleton()->window_set_max_size(Size2i(), window_id);
DisplayServer::get_singleton()->window_set_min_size(Size2i(), window_id);
@@ -2068,6 +2091,9 @@ void Window::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_title", "title"), &Window::set_title);
ClassDB::bind_method(D_METHOD("get_title"), &Window::get_title);
+ ClassDB::bind_method(D_METHOD("set_initial_position", "initial_position"), &Window::set_initial_position);
+ ClassDB::bind_method(D_METHOD("get_initial_position"), &Window::get_initial_position);
+
ClassDB::bind_method(D_METHOD("set_current_screen", "index"), &Window::set_current_screen);
ClassDB::bind_method(D_METHOD("get_current_screen"), &Window::get_current_screen);
@@ -2204,11 +2230,18 @@ void Window::_bind_methods() {
ClassDB::bind_method(D_METHOD("popup_centered", "minsize"), &Window::popup_centered, DEFVAL(Size2i()));
ClassDB::bind_method(D_METHOD("popup_centered_clamped", "minsize", "fallback_ratio"), &Window::popup_centered_clamped, DEFVAL(Size2i()), DEFVAL(0.75));
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "initial_position", PROPERTY_HINT_ENUM, "Absolute,Screen Center"), "set_initial_position", "get_initial_position");
ADD_PROPERTY(PropertyInfo(Variant::STRING, "title"), "set_title", "get_title");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2I, "position", PROPERTY_HINT_NONE, "suffix:px"), "set_position", "get_position");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2I, "size", PROPERTY_HINT_NONE, "suffix:px"), "set_size", "get_size");
ADD_PROPERTY(PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "Windowed,Minimized,Maximized,Fullscreen"), "set_mode", "get_mode");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "current_screen"), "set_current_screen", "get_current_screen");
+
+ // Keep the enum values in sync with the `DisplayServer::SCREEN_` enum.
+ String screen_hints = "Primary Monitor:-2,Main Window Monitor:-1";
+ for (int i = 0; i < 64; i++) {
+ screen_hints += ",Monitor " + itos(i + 1) + ":" + itos(i);
+ }
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "current_screen", PROPERTY_HINT_ENUM, screen_hints), "set_current_screen", "get_current_screen");
ADD_GROUP("Flags", "");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "visible"), "set_visible", "is_visible");
@@ -2285,6 +2318,9 @@ void Window::_bind_methods() {
BIND_ENUM_CONSTANT(LAYOUT_DIRECTION_LOCALE);
BIND_ENUM_CONSTANT(LAYOUT_DIRECTION_LTR);
BIND_ENUM_CONSTANT(LAYOUT_DIRECTION_RTL);
+
+ BIND_ENUM_CONSTANT(WINDOW_INITIAL_POSITION_ABSOLUTE);
+ BIND_ENUM_CONSTANT(WINDOW_INITIAL_POSITION_CENTER_SCREEN);
}
Window::Window() {
diff --git a/scene/main/window.h b/scene/main/window.h
index 9a16a24e57..97f8450628 100644
--- a/scene/main/window.h
+++ b/scene/main/window.h
@@ -87,11 +87,16 @@ public:
DEFAULT_WINDOW_SIZE = 100,
};
+ enum WindowInitialPosition {
+ WINDOW_INITIAL_POSITION_ABSOLUTE,
+ WINDOW_INITIAL_POSITION_CENTER_SCREEN,
+ };
+
private:
DisplayServer::WindowID window_id = DisplayServer::INVALID_WINDOW_ID;
String title;
- mutable int current_screen = 0;
+ mutable int current_screen = DisplayServer::SCREEN_PRIMARY;
mutable Vector2i position;
mutable Size2i size = Size2i(DEFAULT_WINDOW_SIZE, DEFAULT_WINDOW_SIZE);
mutable Size2i min_size;
@@ -100,6 +105,7 @@ private:
mutable bool flags[FLAG_MAX] = {};
bool visible = true;
bool focused = false;
+ WindowInitialPosition initial_position = WINDOW_INITIAL_POSITION_ABSOLUTE;
bool use_font_oversampling = false;
bool transient = false;
@@ -201,6 +207,9 @@ public:
void set_title(const String &p_title);
String get_title() const;
+ void set_initial_position(WindowInitialPosition p_initial_position);
+ WindowInitialPosition get_initial_position() const;
+
void set_current_screen(int p_screen);
int get_current_screen() const;
@@ -369,5 +378,6 @@ VARIANT_ENUM_CAST(Window::Flags);
VARIANT_ENUM_CAST(Window::ContentScaleMode);
VARIANT_ENUM_CAST(Window::ContentScaleAspect);
VARIANT_ENUM_CAST(Window::LayoutDirection);
+VARIANT_ENUM_CAST(Window::WindowInitialPosition);
#endif // WINDOW_H
diff --git a/servers/display_server.cpp b/servers/display_server.cpp
index 734b4d0f1f..07e0b8057e 100644
--- a/servers/display_server.cpp
+++ b/servers/display_server.cpp
@@ -379,7 +379,24 @@ bool DisplayServer::screen_is_kept_on() const {
return false;
}
-DisplayServer::WindowID DisplayServer::create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect, int p_screen) {
+int DisplayServer::get_screen_from_rect(const Rect2 &p_rect) const {
+ int nearest_area = 0;
+ int pos_screen = -1;
+ for (int i = 0; i < get_screen_count(); i++) {
+ Rect2i r;
+ r.position = screen_get_position(i);
+ r.size = screen_get_size(i);
+ Rect2 inters = r.intersection(p_rect);
+ int area = inters.size.width * inters.size.height;
+ if (area > nearest_area) {
+ pos_screen = i;
+ nearest_area = area;
+ }
+ }
+ return pos_screen;
+}
+
+DisplayServer::WindowID DisplayServer::create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect) {
ERR_FAIL_V_MSG(INVALID_WINDOW_ID, "Sub-windows not supported by this display server.");
}
@@ -612,6 +629,8 @@ void DisplayServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_display_safe_area"), &DisplayServer::get_display_safe_area);
ClassDB::bind_method(D_METHOD("get_screen_count"), &DisplayServer::get_screen_count);
+ ClassDB::bind_method(D_METHOD("get_primary_screen"), &DisplayServer::get_primary_screen);
+ ClassDB::bind_method(D_METHOD("get_screen_from_rect", "rect"), &DisplayServer::get_screen_from_rect);
ClassDB::bind_method(D_METHOD("screen_get_position", "screen"), &DisplayServer::screen_get_position, DEFVAL(SCREEN_OF_MAIN_WINDOW));
ClassDB::bind_method(D_METHOD("screen_get_size", "screen"), &DisplayServer::screen_get_size, DEFVAL(SCREEN_OF_MAIN_WINDOW));
ClassDB::bind_method(D_METHOD("screen_get_usable_rect", "screen"), &DisplayServer::screen_get_usable_rect, DEFVAL(SCREEN_OF_MAIN_WINDOW));
@@ -754,7 +773,9 @@ void DisplayServer::_bind_methods() {
BIND_ENUM_CONSTANT(MOUSE_MODE_CONFINED);
BIND_ENUM_CONSTANT(MOUSE_MODE_CONFINED_HIDDEN);
+ BIND_CONSTANT(SCREEN_PRIMARY);
BIND_CONSTANT(SCREEN_OF_MAIN_WINDOW);
+
BIND_CONSTANT(MAIN_WINDOW_ID);
BIND_CONSTANT(INVALID_WINDOW_ID);
@@ -858,9 +879,9 @@ Vector<String> DisplayServer::get_create_function_rendering_drivers(int p_index)
return server_create_functions[p_index].get_rendering_drivers_function();
}
-DisplayServer *DisplayServer::create(int p_index, const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, Error &r_error) {
+DisplayServer *DisplayServer::create(int p_index, const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Error &r_error) {
ERR_FAIL_INDEX_V(p_index, server_create_count, nullptr);
- return server_create_functions[p_index].create_function(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_position, p_resolution, r_error);
+ return server_create_functions[p_index].create_function(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_position, p_resolution, p_screen, r_error);
}
void DisplayServer::_input_set_mouse_mode(Input::MouseMode p_mode) {
diff --git a/servers/display_server.h b/servers/display_server.h
index 5bc7085564..ee53ec1ca0 100644
--- a/servers/display_server.h
+++ b/servers/display_server.h
@@ -73,7 +73,7 @@ public:
OPENGL_CONTEXT,
};
- typedef DisplayServer *(*CreateFunction)(const String &, WindowMode, VSyncMode, uint32_t, const Point2i *, const Size2i &, Error &r_error);
+ typedef DisplayServer *(*CreateFunction)(const String &, WindowMode, VSyncMode, uint32_t, const Point2i *, const Size2i &, int p_screen, Error &r_error);
typedef Vector<String> (*GetRenderingDriversFunction)();
private:
@@ -242,12 +242,15 @@ public:
virtual Rect2i get_display_safe_area() const { return screen_get_usable_rect(); }
enum {
- SCREEN_OF_MAIN_WINDOW = -1
+ SCREEN_PRIMARY = -2,
+ SCREEN_OF_MAIN_WINDOW = -1, // Note: for the main window, determine screen from position.
};
const float SCREEN_REFRESH_RATE_FALLBACK = -1.0; // Returned by screen_get_refresh_rate if the method fails.
virtual int get_screen_count() const = 0;
+ virtual int get_primary_screen() const = 0;
+ virtual int get_screen_from_rect(const Rect2 &p_rect) const;
virtual Point2i screen_get_position(int p_screen = SCREEN_OF_MAIN_WINDOW) const = 0;
virtual Size2i screen_get_size(int p_screen = SCREEN_OF_MAIN_WINDOW) const = 0;
virtual Rect2i screen_get_usable_rect(int p_screen = SCREEN_OF_MAIN_WINDOW) const = 0;
@@ -312,7 +315,7 @@ public:
WINDOW_FLAG_EXTEND_TO_TITLE_BIT = (1 << WINDOW_FLAG_EXTEND_TO_TITLE),
};
- virtual WindowID create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect = Rect2i(), int p_screen = 0);
+ virtual WindowID create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect = Rect2i());
virtual void show_window(WindowID p_id);
virtual void delete_sub_window(WindowID p_id);
@@ -485,7 +488,7 @@ public:
static int get_create_function_count();
static const char *get_create_function_name(int p_index);
static Vector<String> get_create_function_rendering_drivers(int p_index);
- static DisplayServer *create(int p_index, const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, Error &r_error);
+ static DisplayServer *create(int p_index, const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Error &r_error);
DisplayServer();
~DisplayServer();
diff --git a/servers/display_server_headless.h b/servers/display_server_headless.h
index 09853a237e..0c43b84f2e 100644
--- a/servers/display_server_headless.h
+++ b/servers/display_server_headless.h
@@ -45,7 +45,7 @@ private:
return drivers;
}
- static DisplayServer *create_func(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, Error &r_error) {
+ static DisplayServer *create_func(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, Error &r_error) {
r_error = OK;
RasterizerDummy::make_current();
return memnew(DisplayServerHeadless());
@@ -56,6 +56,7 @@ public:
String get_name() const override { return "headless"; }
int get_screen_count() const override { return 0; }
+ int get_primary_screen() const override { return 0; };
Point2i screen_get_position(int p_screen = SCREEN_OF_MAIN_WINDOW) const override { return Point2i(); }
Size2i screen_get_size(int p_screen = SCREEN_OF_MAIN_WINDOW) const override { return Size2i(); }
Rect2i screen_get_usable_rect(int p_screen = SCREEN_OF_MAIN_WINDOW) const override { return Rect2i(); }
@@ -66,7 +67,7 @@ public:
Vector<DisplayServer::WindowID> get_window_list() const override { return Vector<DisplayServer::WindowID>(); }
- WindowID create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect = Rect2i(), int p_screen = 0) override { return 0; }
+ WindowID create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect = Rect2i()) override { return 0; }
void show_window(WindowID p_id) override {}
void delete_sub_window(WindowID p_id) override {}
diff --git a/tests/test_main.cpp b/tests/test_main.cpp
index 235ad8a70d..85a271fc9c 100644
--- a/tests/test_main.cpp
+++ b/tests/test_main.cpp
@@ -203,7 +203,7 @@ struct GodotTestCaseListener : public doctest::IReporter {
OS::get_singleton()->set_has_server_feature_callback(nullptr);
for (int i = 0; i < DisplayServer::get_create_function_count(); i++) {
if (String("headless") == DisplayServer::get_create_function_name(i)) {
- DisplayServer::create(i, "", DisplayServer::WindowMode::WINDOW_MODE_MINIMIZED, DisplayServer::VSyncMode::VSYNC_ENABLED, 0, nullptr, Vector2i(0, 0), err);
+ DisplayServer::create(i, "", DisplayServer::WindowMode::WINDOW_MODE_MINIMIZED, DisplayServer::VSyncMode::VSYNC_ENABLED, 0, nullptr, Vector2i(0, 0), DisplayServer::SCREEN_PRIMARY, err);
break;
}
}