From 2718a7b7d39962100e59b8616077603034d77f8e Mon Sep 17 00:00:00 2001 From: bruvzg <7645683+bruvzg@users.noreply.github.com> Date: Thu, 5 Jan 2023 00:00:02 +0200 Subject: Add support for the custom initial screen for the main window, fix primary screen detection. --- platform/android/display_server_android.cpp | 10 +- platform/android/display_server_android.h | 5 +- platform/ios/display_server_ios.h | 5 +- platform/ios/display_server_ios.mm | 10 +- platform/linuxbsd/x11/display_server_x11.cpp | 118 ++++++++++------ platform/linuxbsd/x11/display_server_x11.h | 9 +- platform/macos/display_server_macos.h | 9 +- platform/macos/display_server_macos.mm | 133 +++++++++++++------ platform/web/display_server_web.cpp | 10 +- platform/web/display_server_web.h | 5 +- platform/windows/display_server_windows.cpp | 192 ++++++++++++++++++++------- platform/windows/display_server_windows.h | 10 +- 12 files changed, 357 insertions(+), 159 deletions(-) (limited to 'platform') 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 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(&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 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 &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 &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 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 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 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 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 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 &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 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 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 &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 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 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 &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 &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 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 &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 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 &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::Element *C = nullptr; List::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 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 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 windows; @@ -476,6 +476,7 @@ class DisplayServerWindows : public DisplayServer { void _dispatch_input_event(const Ref &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 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 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(); }; -- cgit v1.2.3