mirror of
https://github.com/godotengine/godot.git
synced 2024-11-21 19:42:43 +00:00
Add support for the custom initial screen for the main window, fix primary screen detection.
This commit is contained in:
parent
163f6f5fe8
commit
2718a7b7d3
@ -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);
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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)">
|
||||
|
@ -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");
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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");
|
||||
|
@ -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();
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
};
|
||||
|
||||
|
@ -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();
|
||||
};
|
||||
|
||||
|
@ -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)) {
|
||||
|
@ -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?
|
||||
}
|
||||
|
@ -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();
|
||||
};
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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() {
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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();
|
||||
|
@ -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 {}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user