summaryrefslogtreecommitdiff
path: root/platform
diff options
context:
space:
mode:
Diffstat (limited to 'platform')
-rw-r--r--platform/android/android_input_handler.cpp40
-rw-r--r--platform/android/android_input_handler.h12
-rw-r--r--platform/android/display_server_android.cpp14
-rw-r--r--platform/android/display_server_android.h7
-rw-r--r--platform/android/java_godot_lib_jni.cpp10
-rw-r--r--platform/ios/device_metrics.m242
-rw-r--r--platform/ios/display_server_ios.h5
-rw-r--r--platform/ios/display_server_ios.mm10
-rw-r--r--platform/linuxbsd/joypad_linux.cpp24
-rw-r--r--platform/linuxbsd/joypad_linux.h2
-rw-r--r--platform/linuxbsd/x11/display_server_x11.cpp132
-rw-r--r--platform/linuxbsd/x11/display_server_x11.h15
-rw-r--r--platform/macos/display_server_macos.h15
-rw-r--r--platform/macos/display_server_macos.mm137
-rw-r--r--platform/macos/godot_content_view.h2
-rw-r--r--platform/macos/godot_content_view.mm41
-rw-r--r--platform/macos/joypad_macos.cpp27
-rw-r--r--platform/web/api/api.cpp3
-rw-r--r--platform/web/api/javascript_bridge_singleton.h1
-rw-r--r--platform/web/display_server_web.cpp32
-rw-r--r--platform/web/display_server_web.h5
-rw-r--r--platform/web/javascript_bridge_singleton.cpp5
-rw-r--r--platform/web/os_web.cpp6
-rw-r--r--platform/web/os_web.h1
-rw-r--r--platform/web/package-lock.json12
-rw-r--r--platform/windows/display_server_windows.cpp198
-rw-r--r--platform/windows/display_server_windows.h14
-rw-r--r--platform/windows/joypad_windows.cpp25
28 files changed, 655 insertions, 382 deletions
diff --git a/platform/android/android_input_handler.cpp b/platform/android/android_input_handler.cpp
index cfa1046bb3..e3f93086dc 100644
--- a/platform/android/android_input_handler.cpp
+++ b/platform/android/android_input_handler.cpp
@@ -225,7 +225,7 @@ void AndroidInputHandler::process_touch_event(int p_event, int p_pointer, const
}
}
-void AndroidInputHandler::_parse_mouse_event_info(MouseButton event_buttons_mask, bool p_pressed, bool p_double_click, bool p_source_mouse_relative) {
+void AndroidInputHandler::_parse_mouse_event_info(BitField<MouseButtonMask> event_buttons_mask, bool p_pressed, bool p_double_click, bool p_source_mouse_relative) {
if (!mouse_event_info.valid) {
return;
}
@@ -242,7 +242,7 @@ void AndroidInputHandler::_parse_mouse_event_info(MouseButton event_buttons_mask
hover_prev_pos = mouse_event_info.pos;
}
ev->set_pressed(p_pressed);
- MouseButton changed_button_mask = MouseButton(buttons_state ^ event_buttons_mask);
+ BitField<MouseButtonMask> changed_button_mask = BitField<MouseButtonMask>(buttons_state.operator int64_t() ^ event_buttons_mask.operator int64_t());
buttons_state = event_buttons_mask;
@@ -253,12 +253,12 @@ void AndroidInputHandler::_parse_mouse_event_info(MouseButton event_buttons_mask
}
void AndroidInputHandler::_release_mouse_event_info(bool p_source_mouse_relative) {
- _parse_mouse_event_info(MouseButton::NONE, false, false, p_source_mouse_relative);
+ _parse_mouse_event_info(BitField<MouseButtonMask>(), false, false, p_source_mouse_relative);
mouse_event_info.valid = false;
}
void AndroidInputHandler::process_mouse_event(int p_event_action, int p_event_android_buttons_mask, Point2 p_event_pos, Vector2 p_delta, bool p_double_click, bool p_source_mouse_relative) {
- MouseButton event_buttons_mask = _android_button_mask_to_godot_button_mask(p_event_android_buttons_mask);
+ BitField<MouseButtonMask> event_buttons_mask = _android_button_mask_to_godot_button_mask(p_event_android_buttons_mask);
switch (p_event_action) {
case AMOTION_EVENT_ACTION_HOVER_MOVE: // hover move
case AMOTION_EVENT_ACTION_HOVER_ENTER: // hover enter
@@ -342,11 +342,11 @@ void AndroidInputHandler::process_mouse_event(int p_event_action, int p_event_an
}
}
-void AndroidInputHandler::_wheel_button_click(MouseButton event_buttons_mask, const Ref<InputEventMouseButton> &ev, MouseButton wheel_button, float factor) {
+void AndroidInputHandler::_wheel_button_click(BitField<MouseButtonMask> event_buttons_mask, const Ref<InputEventMouseButton> &ev, MouseButton wheel_button, float factor) {
Ref<InputEventMouseButton> evd = ev->duplicate();
_set_key_modifier_state(evd);
evd->set_button_index(wheel_button);
- evd->set_button_mask(MouseButton(event_buttons_mask ^ mouse_button_to_mask(wheel_button)));
+ evd->set_button_mask(BitField<MouseButtonMask>(event_buttons_mask.operator int64_t() ^ int64_t(mouse_button_to_mask(wheel_button))));
evd->set_factor(factor);
Input::get_singleton()->parse_input_event(evd);
Ref<InputEventMouseButton> evdd = evd->duplicate();
@@ -373,39 +373,39 @@ void AndroidInputHandler::process_pan(Point2 p_pos, Vector2 p_delta) {
Input::get_singleton()->parse_input_event(pan_event);
}
-MouseButton AndroidInputHandler::_button_index_from_mask(MouseButton button_mask) {
- switch (button_mask) {
- case MouseButton::MASK_LEFT:
+MouseButton AndroidInputHandler::_button_index_from_mask(BitField<MouseButtonMask> button_mask) {
+ switch (MouseButtonMask(button_mask.operator int64_t())) {
+ case MouseButtonMask::LEFT:
return MouseButton::LEFT;
- case MouseButton::MASK_RIGHT:
+ case MouseButtonMask::RIGHT:
return MouseButton::RIGHT;
- case MouseButton::MASK_MIDDLE:
+ case MouseButtonMask::MIDDLE:
return MouseButton::MIDDLE;
- case MouseButton::MASK_XBUTTON1:
+ case MouseButtonMask::MB_XBUTTON1:
return MouseButton::MB_XBUTTON1;
- case MouseButton::MASK_XBUTTON2:
+ case MouseButtonMask::MB_XBUTTON2:
return MouseButton::MB_XBUTTON2;
default:
return MouseButton::NONE;
}
}
-MouseButton AndroidInputHandler::_android_button_mask_to_godot_button_mask(int android_button_mask) {
- MouseButton godot_button_mask = MouseButton::NONE;
+BitField<MouseButtonMask> AndroidInputHandler::_android_button_mask_to_godot_button_mask(int android_button_mask) {
+ BitField<MouseButtonMask> godot_button_mask;
if (android_button_mask & AMOTION_EVENT_BUTTON_PRIMARY) {
- godot_button_mask |= MouseButton::MASK_LEFT;
+ godot_button_mask.set_flag(MouseButtonMask::LEFT);
}
if (android_button_mask & AMOTION_EVENT_BUTTON_SECONDARY) {
- godot_button_mask |= MouseButton::MASK_RIGHT;
+ godot_button_mask.set_flag(MouseButtonMask::RIGHT);
}
if (android_button_mask & AMOTION_EVENT_BUTTON_TERTIARY) {
- godot_button_mask |= MouseButton::MASK_MIDDLE;
+ godot_button_mask.set_flag(MouseButtonMask::MIDDLE);
}
if (android_button_mask & AMOTION_EVENT_BUTTON_BACK) {
- godot_button_mask |= MouseButton::MASK_XBUTTON1;
+ godot_button_mask.set_flag(MouseButtonMask::MB_XBUTTON1);
}
if (android_button_mask & AMOTION_EVENT_BUTTON_FORWARD) {
- godot_button_mask |= MouseButton::MASK_XBUTTON2;
+ godot_button_mask.set_flag(MouseButtonMask::MB_XBUTTON2);
}
return godot_button_mask;
diff --git a/platform/android/android_input_handler.h b/platform/android/android_input_handler.h
index 1b89096057..34259efd81 100644
--- a/platform/android/android_input_handler.h
+++ b/platform/android/android_input_handler.h
@@ -61,7 +61,7 @@ public:
int index = 0; // Can be either JoyAxis or JoyButton.
bool pressed = false;
float value = 0;
- HatMask hat = HatMask::CENTER;
+ BitField<HatMask> hat;
};
private:
@@ -70,7 +70,7 @@ private:
bool control_mem = false;
bool meta_mem = false;
- MouseButton buttons_state = MouseButton::NONE;
+ BitField<MouseButtonMask> buttons_state;
Vector<TouchPos> touch;
MouseEventInfo mouse_event_info;
@@ -78,12 +78,12 @@ private:
void _set_key_modifier_state(Ref<InputEventWithModifiers> ev);
- static MouseButton _button_index_from_mask(MouseButton button_mask);
- static MouseButton _android_button_mask_to_godot_button_mask(int android_button_mask);
+ static MouseButton _button_index_from_mask(BitField<MouseButtonMask> button_mask);
+ static BitField<MouseButtonMask> _android_button_mask_to_godot_button_mask(int android_button_mask);
- void _wheel_button_click(MouseButton event_buttons_mask, const Ref<InputEventMouseButton> &ev, MouseButton wheel_button, float factor);
+ void _wheel_button_click(BitField<MouseButtonMask> event_buttons_mask, const Ref<InputEventMouseButton> &ev, MouseButton wheel_button, float factor);
- void _parse_mouse_event_info(MouseButton event_buttons_mask, bool p_pressed, bool p_double_click, bool p_source_mouse_relative);
+ void _parse_mouse_event_info(BitField<MouseButtonMask> event_buttons_mask, bool p_pressed, bool p_double_click, bool p_source_mouse_relative);
void _release_mouse_event_info(bool p_source_mouse_relative = false);
diff --git a/platform/android/display_server_android.cpp b/platform/android/display_server_android.cpp
index f8865cc563..780ad4334e 100644
--- a/platform/android/display_server_android.cpp
+++ b/platform/android/display_server_android.cpp
@@ -184,6 +184,10 @@ int DisplayServerAndroid::get_screen_count() const {
return 1;
}
+int DisplayServerAndroid::get_primary_screen() const {
+ return 0;
+}
+
Point2i DisplayServerAndroid::screen_get_position(int p_screen) const {
return Point2i(0, 0);
}
@@ -459,8 +463,8 @@ Vector<String> DisplayServerAndroid::get_rendering_drivers_func() {
return drivers;
}
-DisplayServer *DisplayServerAndroid::create_func(const String &p_rendering_driver, DisplayServer::WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, Error &r_error) {
- DisplayServer *ds = memnew(DisplayServerAndroid(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_position, p_resolution, r_error));
+DisplayServer *DisplayServerAndroid::create_func(const String &p_rendering_driver, DisplayServer::WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Error &r_error) {
+ DisplayServer *ds = memnew(DisplayServerAndroid(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_position, p_resolution, p_screen, r_error));
if (r_error != OK) {
OS::get_singleton()->alert("Your video card driver does not support any of the supported Vulkan versions.", "Unable to initialize Video driver");
if (p_rendering_driver == "vulkan") {
@@ -512,7 +516,7 @@ void DisplayServerAndroid::notify_surface_changed(int p_width, int p_height) {
rect_changed_callback.callp(reinterpret_cast<const Variant **>(&sizep), 1, ret, ce);
}
-DisplayServerAndroid::DisplayServerAndroid(const String &p_rendering_driver, DisplayServer::WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, Error &r_error) {
+DisplayServerAndroid::DisplayServerAndroid(const String &p_rendering_driver, DisplayServer::WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Error &r_error) {
rendering_driver = p_rendering_driver;
keep_screen_on = GLOBAL_GET("display/window/energy_saving/keep_screen_on");
@@ -620,8 +624,8 @@ Point2i DisplayServerAndroid::mouse_get_position() const {
return Input::get_singleton()->get_mouse_position();
}
-MouseButton DisplayServerAndroid::mouse_get_button_state() const {
- return (MouseButton)Input::get_singleton()->get_mouse_button_mask();
+BitField<MouseButtonMask> DisplayServerAndroid::mouse_get_button_state() const {
+ return Input::get_singleton()->get_mouse_button_mask();
}
void DisplayServerAndroid::_cursor_set_shape_helper(CursorShape p_shape, bool force) {
diff --git a/platform/android/display_server_android.h b/platform/android/display_server_android.h
index ec3ff9af49..b2400d81dc 100644
--- a/platform/android/display_server_android.h
+++ b/platform/android/display_server_android.h
@@ -115,6 +115,7 @@ public:
virtual ScreenOrientation screen_get_orientation(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
virtual int get_screen_count() const override;
+ virtual int get_primary_screen() const override;
virtual Point2i screen_get_position(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
virtual Size2i screen_get_size(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
virtual Rect2i screen_get_usable_rect(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
@@ -198,7 +199,7 @@ public:
virtual void mouse_set_mode(MouseMode p_mode) override;
virtual MouseMode mouse_get_mode() const override;
- static DisplayServer *create_func(const String &p_rendering_driver, WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, Error &r_error);
+ static DisplayServer *create_func(const String &p_rendering_driver, WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Error &r_error);
static Vector<String> get_rendering_drivers_func();
static void register_android_driver();
@@ -206,7 +207,7 @@ public:
void notify_surface_changed(int p_width, int p_height);
virtual Point2i mouse_get_position() const override;
- virtual MouseButton mouse_get_button_state() const override;
+ virtual BitField<MouseButtonMask> mouse_get_button_state() const override;
void reset_swap_buffers_flag();
bool should_swap_buffers() const;
@@ -215,7 +216,7 @@ public:
virtual void set_native_icon(const String &p_filename) override;
virtual void set_icon(const Ref<Image> &p_icon) override;
- DisplayServerAndroid(const String &p_rendering_driver, WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, Error &r_error);
+ DisplayServerAndroid(const String &p_rendering_driver, WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Error &r_error);
~DisplayServerAndroid();
};
diff --git a/platform/android/java_godot_lib_jni.cpp b/platform/android/java_godot_lib_jni.cpp
index b502e587a7..e6cdd7932a 100644
--- a/platform/android/java_godot_lib_jni.cpp
+++ b/platform/android/java_godot_lib_jni.cpp
@@ -353,19 +353,19 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyhat(JNIEnv *env, j
AndroidInputHandler::JoypadEvent jevent;
jevent.device = p_device;
jevent.type = AndroidInputHandler::JOY_EVENT_HAT;
- HatMask hat = HatMask::CENTER;
+ BitField<HatMask> hat;
if (p_hat_x != 0) {
if (p_hat_x < 0) {
- hat |= HatMask::LEFT;
+ hat.set_flag(HatMask::LEFT);
} else {
- hat |= HatMask::RIGHT;
+ hat.set_flag(HatMask::RIGHT);
}
}
if (p_hat_y != 0) {
if (p_hat_y < 0) {
- hat |= HatMask::UP;
+ hat.set_flag(HatMask::UP);
} else {
- hat |= HatMask::DOWN;
+ hat.set_flag(HatMask::DOWN);
}
}
jevent.hat = hat;
diff --git a/platform/ios/device_metrics.m b/platform/ios/device_metrics.m
index b51f45c602..d6f5ec8e42 100644
--- a/platform/ios/device_metrics.m
+++ b/platform/ios/device_metrics.m
@@ -35,117 +35,159 @@
+ (NSDictionary *)dpiList {
return @{
@[
- @"iPad1,1",
- @"iPad2,1",
- @"iPad2,2",
- @"iPad2,3",
- @"iPad2,4",
+ @"iPad1,1", // iPad 1th Gen
+ @"iPad1,2", // iPad 1th Gen (3G)
+ @"iPad2,1", // iPad 2nd Gen
+ @"iPad2,2", // iPad 2nd Gen (GSM)
+ @"iPad2,3", // iPad 2nd Gen (CDMA)
+ @"iPad2,4", // iPad 2nd Gen
] : @132,
@[
- @"iPhone1,1",
- @"iPhone1,2",
- @"iPhone2,1",
- @"iPad2,5",
- @"iPad2,6",
- @"iPad2,7",
- @"iPod1,1",
- @"iPod2,1",
- @"iPod3,1",
+ @"iPhone1,1", // iPhone 1st Gen
+ @"iPhone1,2", // iPhone 3G
+ @"iPhone2,1", // iPhone 3GS
+ @"iPad2,5", // iPad mini
+ @"iPad2,6", // iPad mini (GSM+LTE)
+ @"iPad2,7", // iPad mini (CDMA+LTE)
+ @"iPod1,1", // iPod 1st Gen
+ @"iPod2,1", // iPod 2nd Gen
+ @"iPod3,1", // iPod 3rd Gen
] : @163,
@[
- @"iPad3,1",
- @"iPad3,2",
- @"iPad3,3",
- @"iPad3,4",
- @"iPad3,5",
- @"iPad3,6",
- @"iPad4,1",
- @"iPad4,2",
- @"iPad4,3",
- @"iPad5,3",
- @"iPad5,4",
- @"iPad6,3",
- @"iPad6,4",
- @"iPad6,7",
- @"iPad6,8",
- @"iPad6,11",
- @"iPad6,12",
- @"iPad7,1",
- @"iPad7,2",
- @"iPad7,3",
- @"iPad7,4",
- @"iPad7,5",
- @"iPad7,6",
- @"iPad7,11",
- @"iPad7,12",
- @"iPad8,1",
- @"iPad8,2",
- @"iPad8,3",
- @"iPad8,4",
- @"iPad8,5",
- @"iPad8,6",
- @"iPad8,7",
- @"iPad8,8",
- @"iPad8,9",
- @"iPad8,10",
- @"iPad8,11",
- @"iPad8,12",
- @"iPad11,3",
- @"iPad11,4",
+ @"iPad3,1", // iPad 3rd Gen
+ @"iPad3,2", // iPad 3rd Gen (CDMA)
+ @"iPad3,3", // iPad 3rd Gen (GSM)
+ @"iPad3,4", // iPad 4th Gen
+ @"iPad3,5", // iPad 4th Gen (GSM+LTE)
+ @"iPad3,6", // iPad 4th Gen (CDMA+LTE)
+ @"iPad4,1", // iPad Air (WiFi)
+ @"iPad4,2", // iPad Air (GSM+CDMA)
+ @"iPad4,3", // iPad Air (China)
+ @"iPad4,7", // iPad mini 3 (WiFi)
+ @"iPad4,8", // iPad mini 3 (GSM+CDMA)
+ @"iPad4,9", // iPad Mini 3 (China)
+ @"iPad6,3", // iPad Pro (9.7 inch, WiFi)
+ @"iPad6,4", // iPad Pro (9.7 inch, WiFi+LTE)
+ @"iPad6,7", // iPad Pro (12.9 inch, WiFi)
+ @"iPad6,8", // iPad Pro (12.9 inch, WiFi+LTE)
+ @"iPad6,11", // iPad 5th Gen (2017)
+ @"iPad6,12", // iPad 5th Gen (2017)
+ @"iPad7,1", // iPad Pro 2nd Gen (WiFi)
+ @"iPad7,2", // iPad Pro 2nd Gen (WiFi+Cellular)
+ @"iPad7,3", // iPad Pro 10.5-inch 2nd Gen
+ @"iPad7,4", // iPad Pro 10.5-inch 2nd Gen
+ @"iPad7,5", // iPad 6th Gen (WiFi)
+ @"iPad7,6", // iPad 6th Gen (WiFi+Cellular)
+ @"iPad7,11", // iPad 7th Gen 10.2-inch (WiFi)
+ @"iPad7,12", // iPad 7th Gen 10.2-inch (WiFi+Cellular)
+ @"iPad8,1", // iPad Pro 11 inch 3rd Gen (WiFi)
+ @"iPad8,2", // iPad Pro 11 inch 3rd Gen (1TB, WiFi)
+ @"iPad8,3", // iPad Pro 11 inch 3rd Gen (WiFi+Cellular)
+ @"iPad8,4", // iPad Pro 11 inch 3rd Gen (1TB, WiFi+Cellular)
+ @"iPad8,5", // iPad Pro 12.9 inch 3rd Gen (WiFi)
+ @"iPad8,6", // iPad Pro 12.9 inch 3rd Gen (1TB, WiFi)
+ @"iPad8,7", // iPad Pro 12.9 inch 3rd Gen (WiFi+Cellular)
+ @"iPad8,8", // iPad Pro 12.9 inch 3rd Gen (1TB, WiFi+Cellular)
+ @"iPad8,9", // iPad Pro 11 inch 4th Gen (WiFi)
+ @"iPad8,10", // iPad Pro 11 inch 4th Gen (WiFi+Cellular)
+ @"iPad8,11", // iPad Pro 12.9 inch 4th Gen (WiFi)
+ @"iPad8,12", // iPad Pro 12.9 inch 4th Gen (WiFi+Cellular)
+ @"iPad11,3", // iPad Air 3rd Gen (WiFi)
+ @"iPad11,4", // iPad Air 3rd Gen
+ @"iPad11,6", // iPad 8th Gen (WiFi)
+ @"iPad11,7", // iPad 8th Gen (WiFi+Cellular)
+ @"iPad12,1", // iPad 9th Gen (WiFi)
+ @"iPad12,2", // iPad 9th Gen (WiFi+Cellular)
+ @"iPad13,1", // iPad Air 4th Gen (WiFi)
+ @"iPad13,2", // iPad Air 4th Gen (WiFi+Cellular)
+ @"iPad13,4", // iPad Pro 11 inch 5th Gen
+ @"iPad13,5", // iPad Pro 11 inch 5th Gen
+ @"iPad13,6", // iPad Pro 11 inch 5th Gen
+ @"iPad13,7", // iPad Pro 11 inch 5th Gen
+ @"iPad13,8", // iPad Pro 12.9 inch 5th Gen
+ @"iPad13,9", // iPad Pro 12.9 inch 5th Gen
+ @"iPad13,10", // iPad Pro 12.9 inch 5th Gen
+ @"iPad13,11", // iPad Pro 12.9 inch 5th Gen
+ @"iPad13,16", // iPad Air 5th Gen (WiFi)
+ @"iPad13,17", // iPad Air 5th Gen (WiFi+Cellular)
+ @"iPad13,18", // iPad 10th Gen
+ @"iPad13,19", // iPad 10th Gen
+ @"iPad14,3", // iPad Pro 11 inch 6th Gen
+ @"iPad14,4", // iPad Pro 11 inch 6th Gen
+ @"iPad14,5", // iPad Pro 12.9 inch 6th Gen
+ @"iPad14,6", // iPad Pro 12.9 inch 6th Gen
] : @264,
@[
- @"iPhone3,1",
- @"iPhone3,2",
- @"iPhone3,3",
- @"iPhone4,1",
- @"iPhone5,1",
- @"iPhone5,2",
- @"iPhone5,3",
- @"iPhone5,4",
- @"iPhone6,1",
- @"iPhone6,2",
- @"iPhone7,2",
- @"iPhone8,1",
- @"iPhone8,4",
- @"iPhone9,1",
- @"iPhone9,3",
- @"iPhone10,1",
- @"iPhone10,4",
- @"iPhone11,8",
- @"iPhone12,1",
- @"iPhone12,8",
- @"iPad4,4",
- @"iPad4,5",
- @"iPad4,6",
- @"iPad4,7",
- @"iPad4,8",
- @"iPad4,9",
- @"iPad5,1",
- @"iPad5,2",
- @"iPad11,1",
- @"iPad11,2",
- @"iPod4,1",
- @"iPod5,1",
- @"iPod7,1",
- @"iPod9,1",
+ @"iPhone3,1", // iPhone 4
+ @"iPhone3,2", // iPhone 4 (GSM)
+ @"iPhone3,3", // iPhone 4 (CDMA)
+ @"iPhone4,1", // iPhone 4S
+ @"iPhone5,1", // iPhone 5 (GSM)
+ @"iPhone5,2", // iPhone 5 (GSM+CDMA)
+ @"iPhone5,3", // iPhone 5C (GSM)
+ @"iPhone5,4", // iPhone 5C (Global)
+ @"iPhone6,1", // iPhone 5S (GSM)
+ @"iPhone6,2", // iPhone 5S (Global)
+ @"iPhone7,2", // iPhone 6
+ @"iPhone8,1", // iPhone 6s
+ @"iPhone8,4", // iPhone SE (GSM)
+ @"iPhone9,1", // iPhone 7
+ @"iPhone9,3", // iPhone 7
+ @"iPhone10,1", // iPhone 8
+ @"iPhone10,4", // iPhone 8
+ @"iPhone11,8", // iPhone XR
+ @"iPhone12,1", // iPhone 11
+ @"iPhone12,8", // iPhone SE 2nd gen
+ @"iPhone14,6", // iPhone SE 3rd gen
+ @"iPad4,4", // iPad mini Retina (WiFi)
+ @"iPad4,5", // iPad mini Retina (GSM+CDMA)
+ @"iPad4,6", // iPad mini Retina (China)
+ @"iPad5,1", // iPad mini 4th Gen (WiFi)
+ @"iPad5,2", // iPad mini 4th Gen
+ @"iPad5,3", // iPad Air 2 (WiFi)
+ @"iPad5,4", // iPad Air 2
+ @"iPad11,1", // iPad mini 5th Gen (WiFi)
+ @"iPad11,2", // iPad mini 5th Gen
+ @"iPad14,1", // iPad mini 6th Gen (WiFi)
+ @"iPad14,2", // iPad mini 6th Gen
+ @"iPod4,1", // iPod 4th Gen
+ @"iPod5,1", // iPod 5th Gen
+ @"iPod7,1", // iPod 6th Gen
+ @"iPod9,1", // iPod 7th Gen
] : @326,
@[
- @"iPhone7,1",
- @"iPhone8,2",
- @"iPhone9,2",
- @"iPhone9,4",
- @"iPhone10,2",
- @"iPhone10,5",
+ @"iPhone7,1", // iPhone 6 Plus
+ @"iPhone8,2", // iPhone 6s Plus
+ @"iPhone9,2", // iPhone 7 Plus
+ @"iPhone9,4", // iPhone 7 Plus
+ @"iPhone10,2", // iPhone 8 Plus
+ @"iPhone10,5", // iPhone 8 Plus
] : @401,
@[
- @"iPhone10,3",
- @"iPhone10,6",
- @"iPhone11,2",
- @"iPhone11,4",
- @"iPhone11,6",
- @"iPhone12,3",
- @"iPhone12,5",
+ @"iPhone10,3", // iPhone X Global
+ @"iPhone10,6", // iPhone X GSM
+ @"iPhone11,2", // iPhone XS
+ @"iPhone11,4", // iPhone XS Max
+ @"iPhone11,6", // iPhone XS Max Global
+ @"iPhone12,3", // iPhone 11 Pro
+ @"iPhone12,5", // iPhone 11 Pro Max
+ @"iPhone13,4", // iPhone 12 Pro Max
+ @"iPhone14,3", // iPhone 13 Pro Max
+ @"iPhone14,8", // iPhone 14 Plus
] : @458,
+ @[
+ @"iPhone13,2", // iPhone 12
+ @"iPhone13,3", // iPhone 12 Pro
+ @"iPhone14,2", // iPhone 13 Pro
+ @"iPhone14,5", // iPhone 13
+ @"iPhone14,7", // iPhone 14
+ @"iPhone15,2", // iPhone 14 Pro
+ @"iPhone15,3", // iPhone 14 Pro Max
+ ] : @460,
+ @[
+ @"iPhone13,1", // iPhone 12 Mini
+ @"iPhone14,4", // iPhone 13 Mini
+ ] : @476
};
}
diff --git a/platform/ios/display_server_ios.h b/platform/ios/display_server_ios.h
index 3f167acc94..dd1157f668 100644
--- a/platform/ios/display_server_ios.h
+++ b/platform/ios/display_server_ios.h
@@ -75,7 +75,7 @@ class DisplayServerIOS : public DisplayServer {
void perform_event(const Ref<InputEvent> &p_event);
- DisplayServerIOS(const String &p_rendering_driver, DisplayServer::WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, Error &r_error);
+ DisplayServerIOS(const String &p_rendering_driver, DisplayServer::WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Error &r_error);
~DisplayServerIOS();
public:
@@ -84,7 +84,7 @@ public:
static DisplayServerIOS *get_singleton();
static void register_ios_driver();
- static DisplayServer *create_func(const String &p_rendering_driver, WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, Error &r_error);
+ static DisplayServer *create_func(const String &p_rendering_driver, WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Error &r_error);
static Vector<String> get_rendering_drivers_func();
// MARK: - Events
@@ -139,6 +139,7 @@ public:
virtual Rect2i get_display_safe_area() const override;
virtual int get_screen_count() const override;
+ virtual int get_primary_screen() const override;
virtual Point2i screen_get_position(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
virtual Size2i screen_get_size(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
virtual Rect2i screen_get_usable_rect(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
diff --git a/platform/ios/display_server_ios.mm b/platform/ios/display_server_ios.mm
index f383ba5bee..bea88a7f9b 100644
--- a/platform/ios/display_server_ios.mm
+++ b/platform/ios/display_server_ios.mm
@@ -49,7 +49,7 @@ DisplayServerIOS *DisplayServerIOS::get_singleton() {
return (DisplayServerIOS *)DisplayServer::get_singleton();
}
-DisplayServerIOS::DisplayServerIOS(const String &p_rendering_driver, WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, Error &r_error) {
+DisplayServerIOS::DisplayServerIOS(const String &p_rendering_driver, WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Error &r_error) {
rendering_driver = p_rendering_driver;
// Init TTS
@@ -151,8 +151,8 @@ DisplayServerIOS::~DisplayServerIOS() {
#endif
}
-DisplayServer *DisplayServerIOS::create_func(const String &p_rendering_driver, WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, Error &r_error) {
- return memnew(DisplayServerIOS(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_position, p_resolution, r_error));
+DisplayServer *DisplayServerIOS::create_func(const String &p_rendering_driver, WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Error &r_error) {
+ return memnew(DisplayServerIOS(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_position, p_resolution, p_screen, r_error));
}
Vector<String> DisplayServerIOS::get_rendering_drivers_func() {
@@ -379,6 +379,10 @@ int DisplayServerIOS::get_screen_count() const {
return 1;
}
+int DisplayServerIOS::get_primary_screen() const {
+ return 0;
+}
+
Point2i DisplayServerIOS::screen_get_position(int p_screen) const {
return Size2i();
}
diff --git a/platform/linuxbsd/joypad_linux.cpp b/platform/linuxbsd/joypad_linux.cpp
index 672c48addc..b77f989677 100644
--- a/platform/linuxbsd/joypad_linux.cpp
+++ b/platform/linuxbsd/joypad_linux.cpp
@@ -59,7 +59,7 @@ JoypadLinux::Joypad::~Joypad() {
}
void JoypadLinux::Joypad::reset() {
- dpad = HatMask::CENTER;
+ dpad = 0;
fd = -1;
for (int i = 0; i < MAX_ABS; i++) {
abs_map[i] = -1;
@@ -485,27 +485,33 @@ void JoypadLinux::process_joypads() {
case ABS_HAT0X:
if (joypad_event.value != 0) {
if (joypad_event.value < 0) {
- joypad.dpad = (HatMask)((joypad.dpad | HatMask::LEFT) & ~HatMask::RIGHT);
+ joypad.dpad.set_flag(HatMask::LEFT);
+ joypad.dpad.clear_flag(HatMask::RIGHT);
} else {
- joypad.dpad = (HatMask)((joypad.dpad | HatMask::RIGHT) & ~HatMask::LEFT);
+ joypad.dpad.set_flag(HatMask::RIGHT);
+ joypad.dpad.clear_flag(HatMask::LEFT);
}
} else {
- joypad.dpad &= ~(HatMask::LEFT | HatMask::RIGHT);
+ joypad.dpad.clear_flag(HatMask::LEFT);
+ joypad.dpad.clear_flag(HatMask::RIGHT);
}
- input->joy_hat(i, (HatMask)joypad.dpad);
+ input->joy_hat(i, joypad.dpad);
break;
case ABS_HAT0Y:
if (joypad_event.value != 0) {
if (joypad_event.value < 0) {
- joypad.dpad = (HatMask)((joypad.dpad | HatMask::UP) & ~HatMask::DOWN);
+ joypad.dpad.set_flag(HatMask::UP);
+ joypad.dpad.clear_flag(HatMask::DOWN);
} else {
- joypad.dpad = (HatMask)((joypad.dpad | HatMask::DOWN) & ~HatMask::UP);
+ joypad.dpad.set_flag(HatMask::DOWN);
+ joypad.dpad.clear_flag(HatMask::UP);
}
} else {
- joypad.dpad &= ~(HatMask::UP | HatMask::DOWN);
+ joypad.dpad.clear_flag(HatMask::UP);
+ joypad.dpad.clear_flag(HatMask::DOWN);
}
- input->joy_hat(i, (HatMask)joypad.dpad);
+ input->joy_hat(i, joypad.dpad);
break;
default:
diff --git a/platform/linuxbsd/joypad_linux.h b/platform/linuxbsd/joypad_linux.h
index 7926756cbe..6661abdb37 100644
--- a/platform/linuxbsd/joypad_linux.h
+++ b/platform/linuxbsd/joypad_linux.h
@@ -62,7 +62,7 @@ private:
float curr_axis[MAX_ABS];
int key_map[MAX_KEY];
int abs_map[MAX_ABS];
- HatMask dpad = HatMask::CENTER;
+ BitField<HatMask> dpad;
int fd = -1;
String devpath;
diff --git a/platform/linuxbsd/x11/display_server_x11.cpp b/platform/linuxbsd/x11/display_server_x11.cpp
index a9561ababb..10fd9972e3 100644
--- a/platform/linuxbsd/x11/display_server_x11.cpp
+++ b/platform/linuxbsd/x11/display_server_x11.cpp
@@ -458,7 +458,7 @@ Point2i DisplayServerX11::mouse_get_position() const {
return Vector2i();
}
-MouseButton DisplayServerX11::mouse_get_button_state() const {
+BitField<MouseButtonMask> DisplayServerX11::mouse_get_button_state() const {
return last_button_state;
}
@@ -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);
}
}
@@ -2803,13 +2843,13 @@ void DisplayServerX11::_get_key_modifier_state(unsigned int p_x11_state, Ref<Inp
state->set_meta_pressed((p_x11_state & Mod4Mask));
}
-MouseButton DisplayServerX11::_get_mouse_button_state(MouseButton p_x11_button, int p_x11_type) {
- MouseButton mask = mouse_button_to_mask(p_x11_button);
+BitField<MouseButtonMask> DisplayServerX11::_get_mouse_button_state(MouseButton p_x11_button, int p_x11_type) {
+ MouseButtonMask mask = mouse_button_to_mask(p_x11_button);
if (p_x11_type == ButtonPress) {
- last_button_state |= mask;
+ last_button_state.set_flag(mask);
} else {
- last_button_state &= ~mask;
+ last_button_state.clear_flag(mask);
}
return last_button_state;
@@ -4131,13 +4171,13 @@ void DisplayServerX11::process_events() {
if (xi.pressure_supported) {
mm->set_pressure(xi.pressure);
} else {
- mm->set_pressure(bool(mouse_get_button_state() & MouseButton::MASK_LEFT) ? 1.0f : 0.0f);
+ mm->set_pressure(bool(mouse_get_button_state().has_flag(MouseButtonMask::LEFT)) ? 1.0f : 0.0f);
}
mm->set_tilt(xi.tilt);
mm->set_pen_inverted(xi.pen_inverted);
_get_key_modifier_state(event.xmotion.state, mm);
- mm->set_button_mask((MouseButton)mouse_get_button_state());
+ mm->set_button_mask(mouse_get_button_state());
mm->set_position(pos);
mm->set_global_position(pos);
mm->set_velocity(Input::get_singleton()->get_last_mouse_velocity());
@@ -4519,8 +4559,8 @@ Vector<String> DisplayServerX11::get_rendering_drivers_func() {
return drivers;
}
-DisplayServer *DisplayServerX11::create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, Error &r_error) {
- DisplayServer *ds = memnew(DisplayServerX11(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_position, p_resolution, r_error));
+DisplayServer *DisplayServerX11::create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Error &r_error) {
+ DisplayServer *ds = memnew(DisplayServerX11(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_position, p_resolution, p_screen, r_error));
if (r_error != OK) {
if (p_rendering_driver == "vulkan") {
String executable_name = OS::get_singleton()->get_executable_path().get_file();
@@ -4541,7 +4581,7 @@ DisplayServer *DisplayServerX11::create_func(const String &p_rendering_driver, W
return ds;
}
-DisplayServerX11::WindowID DisplayServerX11::_create_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect, int p_screen) {
+DisplayServerX11::WindowID DisplayServerX11::_create_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect) {
//Create window
XVisualInfo visualInfo;
@@ -4617,30 +4657,19 @@ DisplayServerX11::WindowID DisplayServerX11::_create_window(WindowMode p_mode, V
valuemask |= CWOverrideRedirect | CWSaveUnder;
}
+ int rq_screen = get_screen_from_rect(p_rect);
+ if (rq_screen < 0) {
+ rq_screen = get_primary_screen(); // Requested window rect is outside any screen bounds.
+ }
+
Rect2i win_rect = p_rect;
if (p_mode == WINDOW_MODE_FULLSCREEN || p_mode == WINDOW_MODE_EXCLUSIVE_FULLSCREEN) {
- Rect2i screen_rect = Rect2i(screen_get_position(p_screen), screen_get_size(p_screen));
+ Rect2i screen_rect = Rect2i(screen_get_position(rq_screen), screen_get_size(rq_screen));
win_rect = screen_rect;
} else {
- int nearest_area = 0;
- int pos_screen = -1;
- for (int i = 0; i < get_screen_count(); i++) {
- Rect2i r;
- r.position = screen_get_position(i);
- r.size = screen_get_size(i);
- Rect2 inters = r.intersection(p_rect);
-
- int area = inters.size.width * inters.size.height;
- if (area > nearest_area) {
- pos_screen = i;
- nearest_area = area;
- }
- }
-
- Rect2i srect = screen_get_usable_rect(p_screen);
- Point2i wpos = p_rect.position - ((pos_screen >= 0) ? screen_get_position(pos_screen) : Vector2i());
- wpos += srect.position;
+ Rect2i srect = screen_get_usable_rect(rq_screen);
+ Point2i wpos = p_rect.position;
wpos.x = CLAMP(wpos.x, srect.position.x, srect.position.x + srect.size.width - p_rect.size.width / 3);
wpos.y = CLAMP(wpos.y, srect.position.y, srect.position.y + srect.size.height - p_rect.size.height / 3);
@@ -4811,7 +4840,7 @@ DisplayServerX11::WindowID DisplayServerX11::_create_window(WindowMode p_mode, V
return id;
}
-DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, Error &r_error) {
+DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Error &r_error) {
#ifdef DEBUG_ENABLED
int dylibloader_verbose = 1;
#else
@@ -5075,16 +5104,17 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode
ERR_FAIL_MSG("Video driver not found");
}
- Point2i window_position(
- (screen_get_size(0).width - p_resolution.width) / 2,
- (screen_get_size(0).height - p_resolution.height) / 2);
- window_position += screen_get_position(0);
-
+ Point2i window_position;
if (p_position != nullptr) {
window_position = *p_position;
+ } else {
+ if (p_screen == SCREEN_OF_MAIN_WINDOW) {
+ p_screen = SCREEN_PRIMARY;
+ }
+ window_position = screen_get_position(p_screen) + (screen_get_size(p_screen) - p_resolution) / 2;
}
- WindowID main_window = _create_window(p_mode, p_vsync_mode, p_flags, Rect2i(window_position, p_resolution), 0);
+ WindowID main_window = _create_window(p_mode, p_vsync_mode, p_flags, Rect2i(window_position, p_resolution));
if (main_window == INVALID_WINDOW_ID) {
r_error = ERR_CANT_CREATE;
return;
diff --git a/platform/linuxbsd/x11/display_server_x11.h b/platform/linuxbsd/x11/display_server_x11.h
index b8820c843b..43a66f95b2 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;
@@ -205,7 +205,7 @@ class DisplayServerX11 : public DisplayServer {
Point2i last_click_pos = Point2i(-100, -100);
uint64_t last_click_ms = 0;
MouseButton last_click_button_index = MouseButton::NONE;
- MouseButton last_button_state = MouseButton::NONE;
+ BitField<MouseButtonMask> last_button_state;
bool app_focused = false;
uint64_t time_since_no_focus = 0;
@@ -234,7 +234,7 @@ class DisplayServerX11 : public DisplayServer {
Rect2i _screen_get_rect(int p_screen) const;
- MouseButton _get_mouse_button_state(MouseButton p_x11_button, int p_x11_type);
+ BitField<MouseButtonMask> _get_mouse_button_state(MouseButton p_x11_button, int p_x11_type);
void _get_key_modifier_state(unsigned int p_x11_state, Ref<InputEventWithModifiers> state);
void _flush_mouse_motion();
@@ -344,7 +344,7 @@ public:
virtual void warp_mouse(const Point2i &p_position) override;
virtual Point2i mouse_get_position() const override;
- virtual MouseButton mouse_get_button_state() const override;
+ virtual BitField<MouseButtonMask> mouse_get_button_state() const override;
virtual void clipboard_set(const String &p_text) override;
virtual String clipboard_get() const override;
@@ -352,6 +352,7 @@ public:
virtual String clipboard_get_primary() const override;
virtual int get_screen_count() const override;
+ virtual int get_primary_screen() const override;
virtual Point2i screen_get_position(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
virtual Size2i screen_get_size(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
virtual Rect2i screen_get_usable_rect(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
@@ -365,7 +366,7 @@ public:
virtual Vector<DisplayServer::WindowID> get_window_list() const override;
- virtual WindowID create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect = Rect2i(), int p_screen = 0) override;
+ virtual WindowID create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect = Rect2i()) override;
virtual void show_window(WindowID p_id) override;
virtual void delete_sub_window(WindowID p_id) override;
@@ -453,12 +454,12 @@ public:
virtual void set_native_icon(const String &p_filename) override;
virtual void set_icon(const Ref<Image> &p_icon) override;
- static DisplayServer *create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, Error &r_error);
+ static DisplayServer *create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Error &r_error);
static Vector<String> get_rendering_drivers_func();
static void register_x11_driver();
- DisplayServerX11(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, Error &r_error);
+ DisplayServerX11(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Error &r_error);
~DisplayServerX11();
};
diff --git a/platform/macos/display_server_macos.h b/platform/macos/display_server_macos.h
index 5c4267c0e9..7f57644a4c 100644
--- a/platform/macos/display_server_macos.h
+++ b/platform/macos/display_server_macos.h
@@ -154,7 +154,7 @@ private:
CGEventSourceRef event_source;
MouseMode mouse_mode = MOUSE_MODE_VISIBLE;
- MouseButton last_button_state = MouseButton::NONE;
+ BitField<MouseButtonMask> last_button_state;
bool drop_events = false;
bool in_dispatch_input_event = false;
@@ -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);
@@ -317,13 +317,14 @@ public:
bool update_mouse_wrap(WindowData &p_wd, NSPoint &r_delta, NSPoint &r_mpos, NSTimeInterval p_timestamp);
virtual void warp_mouse(const Point2i &p_position) override;
virtual Point2i mouse_get_position() const override;
- void mouse_set_button_state(MouseButton p_state);
- virtual MouseButton mouse_get_button_state() const override;
+ void mouse_set_button_state(BitField<MouseButtonMask> p_state);
+ virtual BitField<MouseButtonMask> mouse_get_button_state() const override;
virtual void clipboard_set(const String &p_text) override;
virtual String clipboard_get() const override;
virtual int get_screen_count() const override;
+ virtual int get_primary_screen() const override;
virtual Point2i screen_get_position(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
virtual Size2i screen_get_size(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
virtual int screen_get_dpi(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
@@ -336,7 +337,7 @@ public:
virtual Vector<int> get_window_list() const override;
- virtual WindowID create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect = Rect2i(), int p_screen = 0) override;
+ virtual WindowID create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect = Rect2i()) override;
virtual void show_window(WindowID p_id) override;
virtual void delete_sub_window(WindowID p_id) override;
@@ -435,12 +436,12 @@ public:
virtual void set_native_icon(const String &p_filename) override;
virtual void set_icon(const Ref<Image> &p_icon) override;
- static DisplayServer *create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, Error &r_error);
+ static DisplayServer *create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Error &r_error);
static Vector<String> get_rendering_drivers_func();
static void register_macos_driver();
- DisplayServerMacOS(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, Error &r_error);
+ DisplayServerMacOS(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Error &r_error);
~DisplayServerMacOS();
};
diff --git a/platform/macos/display_server_macos.mm b/platform/macos/display_server_macos.mm
index 2fc63ea5d4..759ae03d95 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;
}
@@ -2030,11 +2034,11 @@ Point2i DisplayServerMacOS::mouse_get_position() const {
return Vector2i();
}
-void DisplayServerMacOS::mouse_set_button_state(MouseButton p_state) {
+void DisplayServerMacOS::mouse_set_button_state(BitField<MouseButtonMask> p_state) {
last_button_state = p_state;
}
-MouseButton DisplayServerMacOS::mouse_get_button_state() const {
+BitField<MouseButtonMask> DisplayServerMacOS::mouse_get_button_state() const {
return last_button_state;
}
@@ -2077,11 +2081,22 @@ int DisplayServerMacOS::get_screen_count() const {
return [screenArray count];
}
+int DisplayServerMacOS::get_primary_screen() const {
+ return 0;
+}
+
Point2i DisplayServerMacOS::screen_get_position(int p_screen) const {
_THREAD_SAFE_METHOD_
- if (p_screen == SCREEN_OF_MAIN_WINDOW) {
- p_screen = window_get_current_screen();
+ switch (p_screen) {
+ case SCREEN_PRIMARY: {
+ p_screen = get_primary_screen();
+ } break;
+ case SCREEN_OF_MAIN_WINDOW: {
+ p_screen = window_get_current_screen(MAIN_WINDOW_ID);
+ } break;
+ default:
+ break;
}
Point2i position = _get_native_screen_position(p_screen) - _get_screens_origin();
@@ -2094,8 +2109,15 @@ Point2i DisplayServerMacOS::screen_get_position(int p_screen) const {
Size2i DisplayServerMacOS::screen_get_size(int p_screen) const {
_THREAD_SAFE_METHOD_
- if (p_screen == SCREEN_OF_MAIN_WINDOW) {
- p_screen = window_get_current_screen();
+ switch (p_screen) {
+ case SCREEN_PRIMARY: {
+ p_screen = get_primary_screen();
+ } break;
+ case SCREEN_OF_MAIN_WINDOW: {
+ p_screen = window_get_current_screen(MAIN_WINDOW_ID);
+ } break;
+ default:
+ break;
}
NSArray *screenArray = [NSScreen screens];
@@ -2111,8 +2133,15 @@ Size2i DisplayServerMacOS::screen_get_size(int p_screen) const {
int DisplayServerMacOS::screen_get_dpi(int p_screen) const {
_THREAD_SAFE_METHOD_
- if (p_screen == SCREEN_OF_MAIN_WINDOW) {
- p_screen = window_get_current_screen();
+ switch (p_screen) {
+ case SCREEN_PRIMARY: {
+ p_screen = get_primary_screen();
+ } break;
+ case SCREEN_OF_MAIN_WINDOW: {
+ p_screen = window_get_current_screen(MAIN_WINDOW_ID);
+ } break;
+ default:
+ break;
}
NSArray *screenArray = [NSScreen screens];
@@ -2135,9 +2164,17 @@ int DisplayServerMacOS::screen_get_dpi(int p_screen) const {
float DisplayServerMacOS::screen_get_scale(int p_screen) const {
_THREAD_SAFE_METHOD_
- if (p_screen == SCREEN_OF_MAIN_WINDOW) {
- p_screen = window_get_current_screen();
+ switch (p_screen) {
+ case SCREEN_PRIMARY: {
+ p_screen = get_primary_screen();
+ } break;
+ case SCREEN_OF_MAIN_WINDOW: {
+ p_screen = window_get_current_screen(MAIN_WINDOW_ID);
+ } break;
+ default:
+ break;
}
+
if (OS::get_singleton()->is_hidpi_allowed()) {
NSArray *screenArray = [NSScreen screens];
if ((NSUInteger)p_screen < [screenArray count]) {
@@ -2160,8 +2197,15 @@ float DisplayServerMacOS::screen_get_max_scale() const {
Rect2i DisplayServerMacOS::screen_get_usable_rect(int p_screen) const {
_THREAD_SAFE_METHOD_
- if (p_screen == SCREEN_OF_MAIN_WINDOW) {
- p_screen = window_get_current_screen();
+ switch (p_screen) {
+ case SCREEN_PRIMARY: {
+ p_screen = get_primary_screen();
+ } break;
+ case SCREEN_OF_MAIN_WINDOW: {
+ p_screen = window_get_current_screen(MAIN_WINDOW_ID);
+ } break;
+ default:
+ break;
}
NSArray *screenArray = [NSScreen screens];
@@ -2182,8 +2226,15 @@ Rect2i DisplayServerMacOS::screen_get_usable_rect(int p_screen) const {
float DisplayServerMacOS::screen_get_refresh_rate(int p_screen) const {
_THREAD_SAFE_METHOD_
- if (p_screen == SCREEN_OF_MAIN_WINDOW) {
- p_screen = window_get_current_screen();
+ switch (p_screen) {
+ case SCREEN_PRIMARY: {
+ p_screen = get_primary_screen();
+ } break;
+ case SCREEN_OF_MAIN_WINDOW: {
+ p_screen = window_get_current_screen(MAIN_WINDOW_ID);
+ } break;
+ default:
+ break;
}
NSArray *screenArray = [NSScreen screens];
@@ -2225,10 +2276,10 @@ Vector<DisplayServer::WindowID> DisplayServerMacOS::get_window_list() const {
return ret;
}
-DisplayServer::WindowID DisplayServerMacOS::create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect, int p_screen) {
+DisplayServer::WindowID DisplayServerMacOS::create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect) {
_THREAD_SAFE_METHOD_
- WindowID id = _create_window(p_mode, p_vsync_mode, p_rect, p_screen);
+ WindowID id = _create_window(p_mode, p_vsync_mode, p_rect);
for (int i = 0; i < WINDOW_FLAG_MAX; i++) {
if (p_flags & (1 << i)) {
window_set_flag(WindowFlags(i), true, id);
@@ -3520,8 +3571,8 @@ void DisplayServerMacOS::set_icon(const Ref<Image> &p_icon) {
[NSApp setApplicationIconImage:nsimg];
}
-DisplayServer *DisplayServerMacOS::create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, Error &r_error) {
- DisplayServer *ds = memnew(DisplayServerMacOS(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_position, p_resolution, r_error));
+DisplayServer *DisplayServerMacOS::create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Error &r_error) {
+ DisplayServer *ds = memnew(DisplayServerMacOS(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_position, p_resolution, p_screen, r_error));
if (r_error != OK) {
if (p_rendering_driver == "vulkan") {
String executable_command;
@@ -3690,7 +3741,7 @@ bool DisplayServerMacOS::mouse_process_popups(bool p_close) {
return closed;
}
-DisplayServerMacOS::DisplayServerMacOS(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, Error &r_error) {
+DisplayServerMacOS::DisplayServerMacOS(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Error &r_error) {
Input::get_singleton()->set_event_dispatch_function(_dispatch_input_events);
r_error = OK;
@@ -3796,15 +3847,17 @@ DisplayServerMacOS::DisplayServerMacOS(const String &p_rendering_driver, WindowM
}
#endif
- Point2i window_position(
- screen_get_position(0).x + (screen_get_size(0).width - p_resolution.width) / 2,
- screen_get_position(0).y + (screen_get_size(0).height - p_resolution.height) / 2);
-
+ Point2i window_position;
if (p_position != nullptr) {
window_position = *p_position;
+ } else {
+ if (p_screen == SCREEN_OF_MAIN_WINDOW) {
+ p_screen = SCREEN_PRIMARY;
+ }
+ window_position = screen_get_position(p_screen) + (screen_get_size(p_screen) - p_resolution) / 2;
}
- WindowID main_window = _create_window(p_mode, p_vsync_mode, Rect2i(window_position, p_resolution), 0);
+ WindowID main_window = _create_window(p_mode, p_vsync_mode, Rect2i(window_position, p_resolution));
ERR_FAIL_COND(main_window == INVALID_WINDOW_ID);
for (int i = 0; i < WINDOW_FLAG_MAX; i++) {
if (p_flags & (1 << i)) {
diff --git a/platform/macos/godot_content_view.h b/platform/macos/godot_content_view.h
index c0fde4d765..ba7f15c32b 100644
--- a/platform/macos/godot_content_view.h
+++ b/platform/macos/godot_content_view.h
@@ -66,7 +66,7 @@
- (void)processScrollEvent:(NSEvent *)event button:(MouseButton)button factor:(double)factor;
- (void)processPanEvent:(NSEvent *)event dx:(double)dx dy:(double)dy;
-- (void)processMouseEvent:(NSEvent *)event index:(MouseButton)index mask:(MouseButton)mask pressed:(bool)pressed;
+- (void)processMouseEvent:(NSEvent *)event index:(MouseButton)index pressed:(bool)pressed;
- (void)setWindowID:(DisplayServer::WindowID)wid;
- (void)updateLayerDelegate;
- (void)cancelComposition;
diff --git a/platform/macos/godot_content_view.mm b/platform/macos/godot_content_view.mm
index 50befc997d..337aa59a5e 100644
--- a/platform/macos/godot_content_view.mm
+++ b/platform/macos/godot_content_view.mm
@@ -371,19 +371,21 @@
ds->cursor_update_shape();
}
-- (void)processMouseEvent:(NSEvent *)event index:(MouseButton)index mask:(MouseButton)mask pressed:(bool)pressed {
+- (void)processMouseEvent:(NSEvent *)event index:(MouseButton)index pressed:(bool)pressed {
DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (!ds || !ds->has_window(window_id)) {
return;
}
DisplayServerMacOS::WindowData &wd = ds->get_window(window_id);
- MouseButton last_button_state = ds->mouse_get_button_state();
+ BitField<MouseButtonMask> last_button_state = ds->mouse_get_button_state();
+
+ MouseButtonMask mask = mouse_button_to_mask(index);
if (pressed) {
- last_button_state |= mask;
+ last_button_state.set_flag(mask);
} else {
- last_button_state &= (MouseButton)~mask;
+ last_button_state.clear_flag(mask);
}
ds->mouse_set_button_state(last_button_state);
@@ -407,10 +409,10 @@
- (void)mouseDown:(NSEvent *)event {
if (([event modifierFlags] & NSEventModifierFlagControl)) {
mouse_down_control = true;
- [self processMouseEvent:event index:MouseButton::RIGHT mask:MouseButton::MASK_RIGHT pressed:true];
+ [self processMouseEvent:event index:MouseButton::RIGHT pressed:true];
} else {
mouse_down_control = false;
- [self processMouseEvent:event index:MouseButton::LEFT mask:MouseButton::MASK_LEFT pressed:true];
+ [self processMouseEvent:event index:MouseButton::LEFT pressed:true];
}
}
@@ -420,9 +422,9 @@
- (void)mouseUp:(NSEvent *)event {
if (mouse_down_control) {
- [self processMouseEvent:event index:MouseButton::RIGHT mask:MouseButton::MASK_RIGHT pressed:false];
+ [self processMouseEvent:event index:MouseButton::RIGHT pressed:false];
} else {
- [self processMouseEvent:event index:MouseButton::LEFT mask:MouseButton::MASK_LEFT pressed:false];
+ [self processMouseEvent:event index:MouseButton::LEFT pressed:false];
}
}
@@ -469,7 +471,7 @@
}
- (void)rightMouseDown:(NSEvent *)event {
- [self processMouseEvent:event index:MouseButton::RIGHT mask:MouseButton::MASK_RIGHT pressed:true];
+ [self processMouseEvent:event index:MouseButton::RIGHT pressed:true];
}
- (void)rightMouseDragged:(NSEvent *)event {
@@ -477,16 +479,16 @@
}
- (void)rightMouseUp:(NSEvent *)event {
- [self processMouseEvent:event index:MouseButton::RIGHT mask:MouseButton::MASK_RIGHT pressed:false];
+ [self processMouseEvent:event index:MouseButton::RIGHT pressed:false];
}
- (void)otherMouseDown:(NSEvent *)event {
if ((int)[event buttonNumber] == 2) {
- [self processMouseEvent:event index:MouseButton::MIDDLE mask:MouseButton::MASK_MIDDLE pressed:true];
+ [self processMouseEvent:event index:MouseButton::MIDDLE pressed:true];
} else if ((int)[event buttonNumber] == 3) {
- [self processMouseEvent:event index:MouseButton::MB_XBUTTON1 mask:MouseButton::MASK_XBUTTON1 pressed:true];
+ [self processMouseEvent:event index:MouseButton::MB_XBUTTON1 pressed:true];
} else if ((int)[event buttonNumber] == 4) {
- [self processMouseEvent:event index:MouseButton::MB_XBUTTON2 mask:MouseButton::MASK_XBUTTON2 pressed:true];
+ [self processMouseEvent:event index:MouseButton::MB_XBUTTON2 pressed:true];
} else {
return;
}
@@ -498,11 +500,11 @@
- (void)otherMouseUp:(NSEvent *)event {
if ((int)[event buttonNumber] == 2) {
- [self processMouseEvent:event index:MouseButton::MIDDLE mask:MouseButton::MASK_MIDDLE pressed:false];
+ [self processMouseEvent:event index:MouseButton::MIDDLE pressed:false];
} else if ((int)[event buttonNumber] == 3) {
- [self processMouseEvent:event index:MouseButton::MB_XBUTTON1 mask:MouseButton::MASK_XBUTTON1 pressed:false];
+ [self processMouseEvent:event index:MouseButton::MB_XBUTTON1 pressed:false];
} else if ((int)[event buttonNumber] == 4) {
- [self processMouseEvent:event index:MouseButton::MB_XBUTTON2 mask:MouseButton::MASK_XBUTTON2 pressed:false];
+ [self processMouseEvent:event index:MouseButton::MB_XBUTTON2 pressed:false];
} else {
return;
}
@@ -751,7 +753,8 @@
}
DisplayServerMacOS::WindowData &wd = ds->get_window(window_id);
- MouseButton mask = mouse_button_to_mask(button);
+ MouseButtonMask mask = mouse_button_to_mask(button);
+ BitField<MouseButtonMask> last_button_state = ds->mouse_get_button_state();
Ref<InputEventMouseButton> sc;
sc.instantiate();
@@ -763,7 +766,7 @@
sc->set_pressed(true);
sc->set_position(wd.mouse_pos);
sc->set_global_position(wd.mouse_pos);
- MouseButton last_button_state = ds->mouse_get_button_state() | (MouseButton)mask;
+ last_button_state.set_flag(mask);
sc->set_button_mask(last_button_state);
ds->mouse_set_button_state(last_button_state);
@@ -776,7 +779,7 @@
sc->set_pressed(false);
sc->set_position(wd.mouse_pos);
sc->set_global_position(wd.mouse_pos);
- last_button_state &= (MouseButton)~mask;
+ last_button_state.clear_flag(mask);
sc->set_button_mask(last_button_state);
ds->mouse_set_button_state(last_button_state);
diff --git a/platform/macos/joypad_macos.cpp b/platform/macos/joypad_macos.cpp
index 4ea18916fe..b7b8e0604c 100644
--- a/platform/macos/joypad_macos.cpp
+++ b/platform/macos/joypad_macos.cpp
@@ -402,10 +402,10 @@ bool joypad::check_ff_features() {
return false;
}
-static HatMask process_hat_value(int p_min, int p_max, int p_value, bool p_offset_hat) {
+static BitField<HatMask> process_hat_value(int p_min, int p_max, int p_value, bool p_offset_hat) {
int range = (p_max - p_min + 1);
int value = p_value - p_min;
- HatMask hat_value = HatMask::CENTER;
+ BitField<HatMask> hat_value;
if (range == 4) {
value *= 2;
}
@@ -415,31 +415,34 @@ static HatMask process_hat_value(int p_min, int p_max, int p_value, bool p_offse
switch (value) {
case 0:
- hat_value = HatMask::UP;
+ hat_value.set_flag(HatMask::UP);
break;
case 1:
- hat_value = (HatMask::UP | HatMask::RIGHT);
+ hat_value.set_flag(HatMask::UP);
+ hat_value.set_flag(HatMask::RIGHT);
break;
case 2:
- hat_value = HatMask::RIGHT;
+ hat_value.set_flag(HatMask::RIGHT);
break;
case 3:
- hat_value = (HatMask::DOWN | HatMask::RIGHT);
+ hat_value.set_flag(HatMask::DOWN);
+ hat_value.set_flag(HatMask::RIGHT);
break;
case 4:
- hat_value = HatMask::DOWN;
+ hat_value.set_flag(HatMask::DOWN);
break;
case 5:
- hat_value = (HatMask::DOWN | HatMask::LEFT);
+ hat_value.set_flag(HatMask::DOWN);
+ hat_value.set_flag(HatMask::LEFT);
break;
case 6:
- hat_value = HatMask::LEFT;
+ hat_value.set_flag(HatMask::LEFT);
break;
case 7:
- hat_value = (HatMask::UP | HatMask::LEFT);
+ hat_value.set_flag(HatMask::UP);
+ hat_value.set_flag(HatMask::LEFT);
break;
default:
- hat_value = HatMask::CENTER;
break;
}
return hat_value;
@@ -474,7 +477,7 @@ void JoypadMacOS::process_joypads() {
for (int j = 0; j < joy.hat_elements.size(); j++) {
rec_element &elem = joy.hat_elements.write[j];
int value = joy.get_hid_element_state(&elem);
- HatMask hat_value = process_hat_value(elem.min, elem.max, value, joy.offset_hat);
+ BitField<HatMask> hat_value = process_hat_value(elem.min, elem.max, value, joy.offset_hat);
input->joy_hat(joy.id, hat_value);
}
diff --git a/platform/web/api/api.cpp b/platform/web/api/api.cpp
index eb3a199ae1..a630e3d866 100644
--- a/platform/web/api/api.cpp
+++ b/platform/web/api/api.cpp
@@ -73,6 +73,7 @@ void JavaScriptBridge::_bind_methods() {
ClassDB::bind_method(D_METHOD("download_buffer", "buffer", "name", "mime"), &JavaScriptBridge::download_buffer, DEFVAL("application/octet-stream"));
ClassDB::bind_method(D_METHOD("pwa_needs_update"), &JavaScriptBridge::pwa_needs_update);
ClassDB::bind_method(D_METHOD("pwa_update"), &JavaScriptBridge::pwa_update);
+ ClassDB::bind_method(D_METHOD("force_fs_sync"), &JavaScriptBridge::force_fs_sync);
ADD_SIGNAL(MethodInfo("pwa_update_available"));
}
@@ -111,6 +112,8 @@ bool JavaScriptBridge::pwa_needs_update() const {
Error JavaScriptBridge::pwa_update() {
return ERR_UNAVAILABLE;
}
+void JavaScriptBridge::force_fs_sync() {
+}
void JavaScriptBridge::download_buffer(Vector<uint8_t> p_arr, const String &p_name, const String &p_mime) {
}
#endif
diff --git a/platform/web/api/javascript_bridge_singleton.h b/platform/web/api/javascript_bridge_singleton.h
index bcf1ed653a..456fa6b313 100644
--- a/platform/web/api/javascript_bridge_singleton.h
+++ b/platform/web/api/javascript_bridge_singleton.h
@@ -61,6 +61,7 @@ public:
void download_buffer(Vector<uint8_t> p_arr, const String &p_name, const String &p_mime = "application/octet-stream");
bool pwa_needs_update() const;
Error pwa_update();
+ void force_fs_sync();
static JavaScriptBridge *get_singleton();
JavaScriptBridge();
diff --git a/platform/web/display_server_web.cpp b/platform/web/display_server_web.cpp
index c41e64d8f3..7dd0515d3f 100644
--- a/platform/web/display_server_web.cpp
+++ b/platform/web/display_server_web.cpp
@@ -193,12 +193,12 @@ int DisplayServerWeb::mouse_button_callback(int p_pressed, int p_button, double
}
}
- MouseButton mask = Input::get_singleton()->get_mouse_button_mask();
- MouseButton button_flag = mouse_button_to_mask(ev->get_button_index());
+ BitField<MouseButtonMask> mask = Input::get_singleton()->get_mouse_button_mask();
+ MouseButtonMask button_flag = mouse_button_to_mask(ev->get_button_index());
if (ev->is_pressed()) {
- mask |= button_flag;
- } else if ((mask & button_flag) != MouseButton::NONE) {
- mask &= ~button_flag;
+ mask.set_flag(button_flag);
+ } else if (mask.has_flag(button_flag)) {
+ mask.clear_flag(button_flag);
} else {
// Received release event, but press was outside the canvas, so ignore.
return false;
@@ -218,10 +218,10 @@ int DisplayServerWeb::mouse_button_callback(int p_pressed, int p_button, double
}
void DisplayServerWeb::mouse_move_callback(double p_x, double p_y, double p_rel_x, double p_rel_y, int p_modifiers) {
- MouseButton input_mask = Input::get_singleton()->get_mouse_button_mask();
+ BitField<MouseButtonMask> input_mask = Input::get_singleton()->get_mouse_button_mask();
// For motion outside the canvas, only read mouse movement if dragging
// started inside the canvas; imitating desktop app behavior.
- if (!get_singleton()->cursor_inside_canvas && input_mask == MouseButton::NONE) {
+ if (!get_singleton()->cursor_inside_canvas && input_mask.is_empty()) {
return;
}
@@ -525,15 +525,17 @@ int DisplayServerWeb::mouse_wheel_callback(double p_delta_x, double p_delta_y) {
// Different browsers give wildly different delta values, and we can't
// interpret deltaMode, so use default value for wheel events' factor.
- MouseButton button_flag = mouse_button_to_mask(ev->get_button_index());
+ MouseButtonMask button_flag = mouse_button_to_mask(ev->get_button_index());
+ BitField<MouseButtonMask> button_mask = input->get_mouse_button_mask();
+ button_mask.set_flag(button_flag);
ev->set_pressed(true);
- ev->set_button_mask(input->get_mouse_button_mask() | button_flag);
+ ev->set_button_mask(button_mask);
input->parse_input_event(ev);
Ref<InputEventMouseButton> release = ev->duplicate();
release->set_pressed(false);
- release->set_button_mask(MouseButton(input->get_mouse_button_mask() & ~button_flag));
+ release->set_button_mask(input->get_mouse_button_mask());
input->parse_input_event(release);
return true;
@@ -746,11 +748,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 +866,10 @@ int DisplayServerWeb::get_screen_count() const {
return 1;
}
+int DisplayServerWeb::get_primary_screen() const {
+ return 0;
+}
+
Point2i DisplayServerWeb::screen_get_position(int p_screen) const {
return Point2i(); // TODO offsetX/Y?
}
diff --git a/platform/web/display_server_web.h b/platform/web/display_server_web.h
index ab393c6b67..6d76af4e56 100644
--- a/platform/web/display_server_web.h
+++ b/platform/web/display_server_web.h
@@ -97,7 +97,7 @@ private:
static void _js_utterance_callback(int p_event, int p_id, int p_pos);
static Vector<String> get_rendering_drivers_func();
- static DisplayServer *create_func(const String &p_rendering_driver, WindowMode p_window_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, Error &r_error);
+ static DisplayServer *create_func(const String &p_rendering_driver, WindowMode p_window_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Error &r_error);
static void _dispatch_input_event(const Ref<InputEvent> &p_event);
@@ -151,6 +151,7 @@ public:
// screen
virtual int get_screen_count() const override;
+ virtual int get_primary_screen() const override;
virtual Point2i screen_get_position(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
virtual Size2i screen_get_size(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
virtual Rect2i screen_get_usable_rect(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
@@ -223,7 +224,7 @@ public:
virtual void swap_buffers() override;
static void register_web_driver();
- DisplayServerWeb(const String &p_rendering_driver, WindowMode p_window_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Point2i *p_position, const Size2i &p_resolution, Error &r_error);
+ DisplayServerWeb(const String &p_rendering_driver, WindowMode p_window_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Point2i *p_position, const Size2i &p_resolution, int p_screen, Error &r_error);
~DisplayServerWeb();
};
diff --git a/platform/web/javascript_bridge_singleton.cpp b/platform/web/javascript_bridge_singleton.cpp
index 308ca2d5de..dba630404f 100644
--- a/platform/web/javascript_bridge_singleton.cpp
+++ b/platform/web/javascript_bridge_singleton.cpp
@@ -361,6 +361,11 @@ void JavaScriptBridge::download_buffer(Vector<uint8_t> p_arr, const String &p_na
bool JavaScriptBridge::pwa_needs_update() const {
return OS_Web::get_singleton()->pwa_needs_update();
}
+
Error JavaScriptBridge::pwa_update() {
return OS_Web::get_singleton()->pwa_update();
}
+
+void JavaScriptBridge::force_fs_sync() {
+ OS_Web::get_singleton()->force_fs_sync();
+}
diff --git a/platform/web/os_web.cpp b/platform/web/os_web.cpp
index cb304ce7ac..e12f62f4ad 100644
--- a/platform/web/os_web.cpp
+++ b/platform/web/os_web.cpp
@@ -196,6 +196,12 @@ void OS_Web::update_pwa_state_callback() {
}
}
+void OS_Web::force_fs_sync() {
+ if (is_userfs_persistent()) {
+ idb_needs_sync = true;
+ }
+}
+
Error OS_Web::pwa_update() {
return godot_js_pwa_update() ? FAILED : OK;
}
diff --git a/platform/web/os_web.h b/platform/web/os_web.h
index c8fdea2ee0..70d8af9db9 100644
--- a/platform/web/os_web.h
+++ b/platform/web/os_web.h
@@ -69,6 +69,7 @@ public:
bool pwa_needs_update() const { return pwa_is_waiting; }
Error pwa_update();
+ void force_fs_sync();
void initialize_joypads() override;
diff --git a/platform/web/package-lock.json b/platform/web/package-lock.json
index e1428546c6..4399e8243c 100644
--- a/platform/web/package-lock.json
+++ b/platform/web/package-lock.json
@@ -1529,9 +1529,9 @@
"dev": true
},
"node_modules/json5": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
- "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
+ "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
"dev": true,
"dependencies": {
"minimist": "^1.2.0"
@@ -3662,9 +3662,9 @@
"dev": true
},
"json5": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
- "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
+ "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
"dev": true,
"requires": {
"minimist": "^1.2.0"
diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp
index c203f17232..99b80c2e2a 100644
--- a/platform/windows/display_server_windows.cpp
+++ b/platform/windows/display_server_windows.cpp
@@ -254,10 +254,10 @@ 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 {
+BitField<MouseButtonMask> DisplayServerWindows::mouse_get_button_state() const {
return last_button_state;
}
@@ -346,6 +346,17 @@ typedef struct {
HMONITOR monitor;
} EnumScreenData;
+static BOOL CALLBACK _MonitorEnumProcPrim(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) {
+ EnumScreenData *data = (EnumScreenData *)dwData;
+ 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 +381,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 +404,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 +471,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 +528,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 +616,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 +701,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 +715,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 +960,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 +1001,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 +1016,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 +1046,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 +1388,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 +2369,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.
@@ -3070,9 +3162,9 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
mb->set_alt_pressed(alt_mem);
// mb->is_alt_pressed()=(wParam&MK_MENU)!=0;
if (mb->is_pressed()) {
- last_button_state |= mouse_button_to_mask(mb->get_button_index());
+ last_button_state.set_flag(mouse_button_to_mask(mb->get_button_index()));
} else {
- last_button_state &= ~mouse_button_to_mask(mb->get_button_index());
+ last_button_state.clear_flag(mouse_button_to_mask(mb->get_button_index()));
}
mb->set_button_mask(last_button_state);
@@ -3113,7 +3205,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
// Send release for mouse wheel.
Ref<InputEventMouseButton> mbd = mb->duplicate();
mbd->set_window_id(window_id);
- last_button_state &= ~mouse_button_to_mask(mbd->get_button_index());
+ last_button_state.clear_flag(mouse_button_to_mask(mbd->get_button_index()));
mbd->set_button_mask(last_button_state);
mbd->set_pressed(false);
Input::get_singleton()->parse_input_event(mbd);
@@ -3130,10 +3222,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 +3633,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 +3646,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 +3886,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 +4033,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 +4106,8 @@ Vector<String> DisplayServerWindows::get_rendering_drivers_func() {
return drivers;
}
-DisplayServer *DisplayServerWindows::create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, Error &r_error) {
- DisplayServer *ds = memnew(DisplayServerWindows(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_position, p_resolution, r_error));
+DisplayServer *DisplayServerWindows::create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Error &r_error) {
+ DisplayServer *ds = memnew(DisplayServerWindows(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_position, p_resolution, p_screen, r_error));
if (r_error != OK) {
if (p_rendering_driver == "vulkan") {
String executable_name = OS::get_singleton()->get_executable_path().get_file();
diff --git a/platform/windows/display_server_windows.h b/platform/windows/display_server_windows.h
index f0171d50ad..e9f30024b2 100644
--- a/platform/windows/display_server_windows.h
+++ b/platform/windows/display_server_windows.h
@@ -426,7 +426,7 @@ class DisplayServerWindows : public DisplayServer {
uint64_t time_since_popup = 0;
Ref<Image> icon;
- WindowID _create_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect, int p_screen);
+ WindowID _create_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect);
WindowID window_id_counter = MAIN_WINDOW_ID;
RBMap<WindowID, WindowData> windows;
@@ -446,7 +446,7 @@ class DisplayServerWindows : public DisplayServer {
bool shift_mem = false;
bool control_mem = false;
bool meta_mem = false;
- MouseButton last_button_state = MouseButton::NONE;
+ BitField<MouseButtonMask> last_button_state;
bool use_raw_input = false;
bool drop_events = false;
bool in_dispatch_input_event = false;
@@ -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);
@@ -505,12 +506,13 @@ public:
virtual void warp_mouse(const Point2i &p_position) override;
virtual Point2i mouse_get_position() const override;
- virtual MouseButton mouse_get_button_state() const override;
+ virtual BitField<MouseButtonMask> mouse_get_button_state() const override;
virtual void clipboard_set(const String &p_text) override;
virtual String clipboard_get() const override;
virtual int get_screen_count() const override;
+ virtual int get_primary_screen() const override;
virtual Point2i screen_get_position(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
virtual Size2i screen_get_size(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
virtual Rect2i screen_get_usable_rect(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
@@ -522,7 +524,7 @@ public:
virtual Vector<DisplayServer::WindowID> get_window_list() const override;
- virtual WindowID create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect = Rect2i(), int p_screen = 0) override;
+ virtual WindowID create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect = Rect2i()) override;
virtual void show_window(WindowID p_window) override;
virtual void delete_sub_window(WindowID p_window) override;
@@ -623,11 +625,11 @@ public:
virtual void set_context(Context p_context) override;
- static DisplayServer *create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, Error &r_error);
+ static DisplayServer *create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Error &r_error);
static Vector<String> get_rendering_drivers_func();
static void register_windows_driver();
- DisplayServerWindows(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, Error &r_error);
+ DisplayServerWindows(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Error &r_error);
~DisplayServerWindows();
};
diff --git a/platform/windows/joypad_windows.cpp b/platform/windows/joypad_windows.cpp
index aed5f5b8dc..183958cf40 100644
--- a/platform/windows/joypad_windows.cpp
+++ b/platform/windows/joypad_windows.cpp
@@ -420,38 +420,43 @@ void JoypadWindows::process_joypads() {
}
void JoypadWindows::post_hat(int p_device, DWORD p_dpad) {
- HatMask dpad_val = (HatMask)0;
+ BitField<HatMask> dpad_val;
// Should be -1 when centered, but according to docs:
// "Some drivers report the centered position of the POV indicator as 65,535. Determine whether the indicator is centered as follows:
// BOOL POVCentered = (LOWORD(dwPOV) == 0xFFFF);"
// https://docs.microsoft.com/en-us/previous-versions/windows/desktop/ee416628(v%3Dvs.85)#remarks
if (LOWORD(p_dpad) == 0xFFFF) {
- dpad_val = (HatMask)HatMask::CENTER;
+ // Do nothing.
+ // dpad_val.set_flag(HatMask::CENTER);
}
if (p_dpad == 0) {
- dpad_val = (HatMask)HatMask::UP;
+ dpad_val.set_flag(HatMask::UP);
} else if (p_dpad == 4500) {
- dpad_val = (HatMask)(HatMask::UP | HatMask::RIGHT);
+ dpad_val.set_flag(HatMask::UP);
+ dpad_val.set_flag(HatMask::RIGHT);
} else if (p_dpad == 9000) {
- dpad_val = (HatMask)HatMask::RIGHT;
+ dpad_val.set_flag(HatMask::RIGHT);
} else if (p_dpad == 13500) {
- dpad_val = (HatMask)(HatMask::RIGHT | HatMask::DOWN);
+ dpad_val.set_flag(HatMask::RIGHT);
+ dpad_val.set_flag(HatMask::DOWN);
} else if (p_dpad == 18000) {
- dpad_val = (HatMask)HatMask::DOWN;
+ dpad_val.set_flag(HatMask::DOWN);
} else if (p_dpad == 22500) {
- dpad_val = (HatMask)(HatMask::DOWN | HatMask::LEFT);
+ dpad_val.set_flag(HatMask::DOWN);
+ dpad_val.set_flag(HatMask::LEFT);
} else if (p_dpad == 27000) {
- dpad_val = (HatMask)HatMask::LEFT;
+ dpad_val.set_flag(HatMask::LEFT);
} else if (p_dpad == 31500) {
- dpad_val = (HatMask)(HatMask::LEFT | HatMask::UP);
+ dpad_val.set_flag(HatMask::LEFT);
+ dpad_val.set_flag(HatMask::UP);
}
input->joy_hat(p_device, dpad_val);
}