Merge pull request #56825 from bruvzg/macos_fix_fullscr_multiwindow
This commit is contained in:
commit
74b110a736
9 changed files with 59 additions and 55 deletions
|
@ -321,11 +321,6 @@
|
||||||
[b]Note:[/b] This method is implemented on Linux, macOS and Windows.
|
[b]Note:[/b] This method is implemented on Linux, macOS and Windows.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="mouse_get_absolute_position" qualifiers="const">
|
|
||||||
<return type="Vector2i" />
|
|
||||||
<description>
|
|
||||||
</description>
|
|
||||||
</method>
|
|
||||||
<method name="mouse_get_button_state" qualifiers="const">
|
<method name="mouse_get_button_state" qualifiers="const">
|
||||||
<return type="int" enum="MouseButton" />
|
<return type="int" enum="MouseButton" />
|
||||||
<description>
|
<description>
|
||||||
|
|
|
@ -365,21 +365,6 @@ void DisplayServerX11::mouse_warp_to_position(const Point2i &p_to) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Point2i DisplayServerX11::mouse_get_position() const {
|
Point2i DisplayServerX11::mouse_get_position() const {
|
||||||
int root_x, root_y;
|
|
||||||
int win_x, win_y;
|
|
||||||
unsigned int mask_return;
|
|
||||||
Window window_returned;
|
|
||||||
|
|
||||||
Bool result = XQueryPointer(x11_display, RootWindow(x11_display, DefaultScreen(x11_display)), &window_returned,
|
|
||||||
&window_returned, &root_x, &root_y, &win_x, &win_y,
|
|
||||||
&mask_return);
|
|
||||||
if (result == True) {
|
|
||||||
return Point2i(root_x, root_y);
|
|
||||||
}
|
|
||||||
return Point2i();
|
|
||||||
}
|
|
||||||
|
|
||||||
Point2i DisplayServerX11::mouse_get_absolute_position() const {
|
|
||||||
int number_of_screens = XScreenCount(x11_display);
|
int number_of_screens = XScreenCount(x11_display);
|
||||||
for (int i = 0; i < number_of_screens; i++) {
|
for (int i = 0; i < number_of_screens; i++) {
|
||||||
Window root, child;
|
Window root, child;
|
||||||
|
|
|
@ -289,7 +289,6 @@ public:
|
||||||
|
|
||||||
virtual void mouse_warp_to_position(const Point2i &p_to) override;
|
virtual void mouse_warp_to_position(const Point2i &p_to) override;
|
||||||
virtual Point2i mouse_get_position() const override;
|
virtual Point2i mouse_get_position() const override;
|
||||||
virtual Point2i mouse_get_absolute_position() const override;
|
|
||||||
virtual MouseButton mouse_get_button_state() const override;
|
virtual MouseButton mouse_get_button_state() const override;
|
||||||
|
|
||||||
virtual void clipboard_set(const String &p_text) override;
|
virtual void clipboard_set(const String &p_text) override;
|
||||||
|
|
|
@ -98,6 +98,8 @@ public:
|
||||||
NSTimeInterval last_warp = 0;
|
NSTimeInterval last_warp = 0;
|
||||||
bool ignore_warp = false;
|
bool ignore_warp = false;
|
||||||
|
|
||||||
|
float display_max_scale = 1.f;
|
||||||
|
|
||||||
Vector<KeyEvent> key_event_buffer;
|
Vector<KeyEvent> key_event_buffer;
|
||||||
int key_event_pos;
|
int key_event_pos;
|
||||||
|
|
||||||
|
@ -214,7 +216,6 @@ public:
|
||||||
|
|
||||||
virtual void mouse_warp_to_position(const Point2i &p_to) override;
|
virtual void mouse_warp_to_position(const Point2i &p_to) override;
|
||||||
virtual Point2i mouse_get_position() const override;
|
virtual Point2i mouse_get_position() const override;
|
||||||
virtual Point2i mouse_get_absolute_position() const override;
|
|
||||||
virtual MouseButton mouse_get_button_state() const override;
|
virtual MouseButton mouse_get_button_state() const override;
|
||||||
|
|
||||||
virtual void clipboard_set(const String &p_text) override;
|
virtual void clipboard_set(const String &p_text) override;
|
||||||
|
|
|
@ -158,12 +158,7 @@ static NSCursor *_cursorFromSelector(SEL selector, SEL fallback = nil) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wd.transient_parent != DisplayServerOSX::INVALID_WINDOW_ID) {
|
if (wd.transient_parent != DisplayServerOSX::INVALID_WINDOW_ID) {
|
||||||
DisplayServerOSX::WindowData &pwd = DS_OSX->windows[wd.transient_parent];
|
|
||||||
[pwd.window_object makeKeyAndOrderFront:nil]; // Move focus back to parent.
|
|
||||||
DS_OSX->window_set_transient(window_id, DisplayServerOSX::INVALID_WINDOW_ID);
|
DS_OSX->window_set_transient(window_id, DisplayServerOSX::INVALID_WINDOW_ID);
|
||||||
} else if ((window_id != DisplayServerOSX::MAIN_WINDOW_ID) && (DS_OSX->windows.size() == 1)) {
|
|
||||||
DisplayServerOSX::WindowData &pwd = DS_OSX->windows[DisplayServerOSX::MAIN_WINDOW_ID];
|
|
||||||
[pwd.window_object makeKeyAndOrderFront:nil]; // Move focus back to main window if there is no parent or other windows left.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(GLES3_ENABLED)
|
#if defined(GLES3_ENABLED)
|
||||||
|
@ -2001,10 +1996,6 @@ void DisplayServerOSX::mouse_warp_to_position(const Point2i &p_to) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Point2i DisplayServerOSX::mouse_get_position() const {
|
Point2i DisplayServerOSX::mouse_get_position() const {
|
||||||
return last_mouse_pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
Point2i DisplayServerOSX::mouse_get_absolute_position() const {
|
|
||||||
_THREAD_SAFE_METHOD_
|
_THREAD_SAFE_METHOD_
|
||||||
|
|
||||||
const NSPoint mouse_pos = [NSEvent mouseLocation];
|
const NSPoint mouse_pos = [NSEvent mouseLocation];
|
||||||
|
@ -2071,10 +2062,8 @@ int DisplayServerOSX::get_screen_count() const {
|
||||||
// to convert between OS X native screen coordinates and the ones expected by Godot
|
// to convert between OS X native screen coordinates and the ones expected by Godot
|
||||||
|
|
||||||
static bool displays_arrangement_dirty = true;
|
static bool displays_arrangement_dirty = true;
|
||||||
static bool displays_scale_dirty = true;
|
|
||||||
static void displays_arrangement_changed(CGDirectDisplayID display_id, CGDisplayChangeSummaryFlags flags, void *user_info) {
|
static void displays_arrangement_changed(CGDirectDisplayID display_id, CGDisplayChangeSummaryFlags flags, void *user_info) {
|
||||||
displays_arrangement_dirty = true;
|
displays_arrangement_dirty = true;
|
||||||
displays_scale_dirty = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Point2i DisplayServerOSX::_get_screens_origin() const {
|
Point2i DisplayServerOSX::_get_screens_origin() const {
|
||||||
|
@ -2185,15 +2174,8 @@ float DisplayServerOSX::screen_get_scale(int p_screen) const {
|
||||||
float DisplayServerOSX::screen_get_max_scale() const {
|
float DisplayServerOSX::screen_get_max_scale() const {
|
||||||
_THREAD_SAFE_METHOD_
|
_THREAD_SAFE_METHOD_
|
||||||
|
|
||||||
static float scale = 1.f;
|
// Note: Do not update max display scale on screen configuration change, existing editor windows can't be rescaled on the fly.
|
||||||
if (displays_scale_dirty) {
|
return display_max_scale;
|
||||||
int screen_count = get_screen_count();
|
|
||||||
for (int i = 0; i < screen_count; i++) {
|
|
||||||
scale = fmax(scale, screen_get_scale(i));
|
|
||||||
}
|
|
||||||
displays_scale_dirty = false;
|
|
||||||
}
|
|
||||||
return scale;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Rect2i DisplayServerOSX::screen_get_usable_rect(int p_screen) const {
|
Rect2i DisplayServerOSX::screen_get_usable_rect(int p_screen) const {
|
||||||
|
@ -2380,8 +2362,24 @@ int DisplayServerOSX::window_get_current_screen(WindowID p_window) const {
|
||||||
|
|
||||||
void DisplayServerOSX::window_set_current_screen(int p_screen, WindowID p_window) {
|
void DisplayServerOSX::window_set_current_screen(int p_screen, WindowID p_window) {
|
||||||
_THREAD_SAFE_METHOD_
|
_THREAD_SAFE_METHOD_
|
||||||
|
|
||||||
|
ERR_FAIL_COND(!windows.has(p_window));
|
||||||
|
WindowData &wd = windows[p_window];
|
||||||
|
|
||||||
|
bool was_fullscreen = false;
|
||||||
|
if (wd.fullscreen) {
|
||||||
|
// Temporary exit fullscreen mode to move window.
|
||||||
|
[wd.window_object toggleFullScreen:nil];
|
||||||
|
was_fullscreen = true;
|
||||||
|
}
|
||||||
|
|
||||||
Point2i wpos = window_get_position(p_window) - screen_get_position(window_get_current_screen(p_window));
|
Point2i wpos = window_get_position(p_window) - screen_get_position(window_get_current_screen(p_window));
|
||||||
window_set_position(wpos + screen_get_position(p_screen), p_window);
|
window_set_position(wpos + screen_get_position(p_screen), p_window);
|
||||||
|
|
||||||
|
if (was_fullscreen) {
|
||||||
|
// Re-enter fullscreen mode.
|
||||||
|
[wd.window_object toggleFullScreen:nil];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DisplayServerOSX::window_set_transient(WindowID p_window, WindowID p_parent) {
|
void DisplayServerOSX::window_set_transient(WindowID p_window, WindowID p_parent) {
|
||||||
|
@ -2404,7 +2402,7 @@ void DisplayServerOSX::window_set_transient(WindowID p_window, WindowID p_parent
|
||||||
wd_window.transient_parent = INVALID_WINDOW_ID;
|
wd_window.transient_parent = INVALID_WINDOW_ID;
|
||||||
wd_parent.transient_children.erase(p_window);
|
wd_parent.transient_children.erase(p_window);
|
||||||
|
|
||||||
[wd_parent.window_object removeChildWindow:wd_window.window_object];
|
[wd_window.window_object setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary];
|
||||||
} else {
|
} else {
|
||||||
ERR_FAIL_COND(!windows.has(p_parent));
|
ERR_FAIL_COND(!windows.has(p_parent));
|
||||||
ERR_FAIL_COND_MSG(wd_window.transient_parent != INVALID_WINDOW_ID, "Window already has a transient parent");
|
ERR_FAIL_COND_MSG(wd_window.transient_parent != INVALID_WINDOW_ID, "Window already has a transient parent");
|
||||||
|
@ -2413,7 +2411,7 @@ void DisplayServerOSX::window_set_transient(WindowID p_window, WindowID p_parent
|
||||||
wd_window.transient_parent = p_parent;
|
wd_window.transient_parent = p_parent;
|
||||||
wd_parent.transient_children.insert(p_window);
|
wd_parent.transient_children.insert(p_window);
|
||||||
|
|
||||||
[wd_parent.window_object addChildWindow:wd_window.window_object ordered:NSWindowAbove];
|
[wd_window.window_object setCollectionBehavior:NSWindowCollectionBehaviorFullScreenAuxiliary];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2423,7 +2421,9 @@ Point2i DisplayServerOSX::window_get_position(WindowID p_window) const {
|
||||||
ERR_FAIL_COND_V(!windows.has(p_window), Point2i());
|
ERR_FAIL_COND_V(!windows.has(p_window), Point2i());
|
||||||
const WindowData &wd = windows[p_window];
|
const WindowData &wd = windows[p_window];
|
||||||
|
|
||||||
NSRect nsrect = [wd.window_object frame];
|
// Use content rect position (without titlebar / window border).
|
||||||
|
const NSRect contentRect = [wd.window_view frame];
|
||||||
|
const NSRect nsrect = [wd.window_object convertRectToScreen:contentRect];
|
||||||
Point2i pos;
|
Point2i pos;
|
||||||
|
|
||||||
// Return the position of the top-left corner, for OS X the y starts at the bottom
|
// Return the position of the top-left corner, for OS X the y starts at the bottom
|
||||||
|
@ -2451,7 +2451,16 @@ void DisplayServerOSX::window_set_position(const Point2i &p_position, WindowID p
|
||||||
position += _get_screens_origin();
|
position += _get_screens_origin();
|
||||||
position /= screen_get_max_scale();
|
position /= screen_get_max_scale();
|
||||||
|
|
||||||
[wd.window_object setFrameTopLeftPoint:NSMakePoint(position.x, position.y)];
|
// Remove titlebar / window border size.
|
||||||
|
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(position.x - offset.x, position.y - offset.y)];
|
||||||
|
|
||||||
_update_window(wd);
|
_update_window(wd);
|
||||||
_get_mouse_pos(wd, [wd.window_object mouseLocationOutsideOfEventStream]);
|
_get_mouse_pos(wd, [wd.window_object mouseLocationOutsideOfEventStream]);
|
||||||
|
@ -3699,7 +3708,11 @@ DisplayServerOSX::DisplayServerOSX(const String &p_rendering_driver, WindowMode
|
||||||
|
|
||||||
keyboard_layout_dirty = true;
|
keyboard_layout_dirty = true;
|
||||||
displays_arrangement_dirty = true;
|
displays_arrangement_dirty = true;
|
||||||
displays_scale_dirty = true;
|
|
||||||
|
int screen_count = get_screen_count();
|
||||||
|
for (int i = 0; i < screen_count; i++) {
|
||||||
|
display_max_scale = fmax(display_max_scale, screen_get_scale(i));
|
||||||
|
}
|
||||||
|
|
||||||
// Register to be notified on keyboard layout changes
|
// Register to be notified on keyboard layout changes
|
||||||
CFNotificationCenterAddObserver(CFNotificationCenterGetDistributedCenter(),
|
CFNotificationCenterAddObserver(CFNotificationCenterGetDistributedCenter(),
|
||||||
|
|
|
@ -674,8 +674,20 @@ void DisplayServerWindows::window_set_current_screen(int p_screen, WindowID p_wi
|
||||||
ERR_FAIL_COND(!windows.has(p_window));
|
ERR_FAIL_COND(!windows.has(p_window));
|
||||||
ERR_FAIL_INDEX(p_screen, get_screen_count());
|
ERR_FAIL_INDEX(p_screen, get_screen_count());
|
||||||
|
|
||||||
Vector2 ofs = window_get_position(p_window) - screen_get_position(window_get_current_screen(p_window));
|
const WindowData &wd = windows[p_window];
|
||||||
window_set_position(ofs + screen_get_position(p_screen), p_window);
|
if (wd.fullscreen) {
|
||||||
|
int cs = window_get_current_screen(p_window);
|
||||||
|
if (cs == p_screen) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Point2 pos = screen_get_position(p_screen);
|
||||||
|
Size2 size = screen_get_size(p_screen);
|
||||||
|
|
||||||
|
MoveWindow(wd.hWnd, pos.x, pos.y, size.width, size.height, TRUE);
|
||||||
|
} else {
|
||||||
|
Vector2 ofs = window_get_position(p_window) - screen_get_position(window_get_current_screen(p_window));
|
||||||
|
window_set_position(ofs + screen_get_position(p_screen), p_window);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Point2i DisplayServerWindows::window_get_position(WindowID p_window) const {
|
Point2i DisplayServerWindows::window_get_position(WindowID p_window) const {
|
||||||
|
|
|
@ -281,6 +281,11 @@ void Window::_clear_window() {
|
||||||
DisplayServer::get_singleton()->delete_sub_window(window_id);
|
DisplayServer::get_singleton()->delete_sub_window(window_id);
|
||||||
window_id = DisplayServer::INVALID_WINDOW_ID;
|
window_id = DisplayServer::INVALID_WINDOW_ID;
|
||||||
|
|
||||||
|
// If closing window was focused and has a parent, return focus.
|
||||||
|
if (focused && transient_parent) {
|
||||||
|
transient_parent->grab_focus();
|
||||||
|
}
|
||||||
|
|
||||||
_update_viewport_size();
|
_update_viewport_size();
|
||||||
RS::get_singleton()->viewport_set_update_mode(get_viewport_rid(), RS::VIEWPORT_UPDATE_DISABLED);
|
RS::get_singleton()->viewport_set_update_mode(get_viewport_rid(), RS::VIEWPORT_UPDATE_DISABLED);
|
||||||
}
|
}
|
||||||
|
|
|
@ -139,10 +139,6 @@ void DisplayServer::mouse_warp_to_position(const Point2i &p_to) {
|
||||||
WARN_PRINT("Mouse warping is not supported by this display server.");
|
WARN_PRINT("Mouse warping is not supported by this display server.");
|
||||||
}
|
}
|
||||||
|
|
||||||
Point2i DisplayServer::mouse_get_absolute_position() const {
|
|
||||||
ERR_FAIL_V_MSG(Point2i(), "Mouse is not supported by this display server.");
|
|
||||||
}
|
|
||||||
|
|
||||||
Point2i DisplayServer::mouse_get_position() const {
|
Point2i DisplayServer::mouse_get_position() const {
|
||||||
ERR_FAIL_V_MSG(Point2i(), "Mouse is not supported by this display server.");
|
ERR_FAIL_V_MSG(Point2i(), "Mouse is not supported by this display server.");
|
||||||
}
|
}
|
||||||
|
@ -359,7 +355,6 @@ void DisplayServer::_bind_methods() {
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("mouse_warp_to_position", "position"), &DisplayServer::mouse_warp_to_position);
|
ClassDB::bind_method(D_METHOD("mouse_warp_to_position", "position"), &DisplayServer::mouse_warp_to_position);
|
||||||
ClassDB::bind_method(D_METHOD("mouse_get_position"), &DisplayServer::mouse_get_position);
|
ClassDB::bind_method(D_METHOD("mouse_get_position"), &DisplayServer::mouse_get_position);
|
||||||
ClassDB::bind_method(D_METHOD("mouse_get_absolute_position"), &DisplayServer::mouse_get_absolute_position);
|
|
||||||
ClassDB::bind_method(D_METHOD("mouse_get_button_state"), &DisplayServer::mouse_get_button_state);
|
ClassDB::bind_method(D_METHOD("mouse_get_button_state"), &DisplayServer::mouse_get_button_state);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("clipboard_set", "clipboard"), &DisplayServer::clipboard_set);
|
ClassDB::bind_method(D_METHOD("clipboard_set", "clipboard"), &DisplayServer::clipboard_set);
|
||||||
|
|
|
@ -156,7 +156,6 @@ public:
|
||||||
|
|
||||||
virtual void mouse_warp_to_position(const Point2i &p_to);
|
virtual void mouse_warp_to_position(const Point2i &p_to);
|
||||||
virtual Point2i mouse_get_position() const;
|
virtual Point2i mouse_get_position() const;
|
||||||
virtual Point2i mouse_get_absolute_position() const;
|
|
||||||
virtual MouseButton mouse_get_button_state() const;
|
virtual MouseButton mouse_get_button_state() const;
|
||||||
|
|
||||||
virtual void clipboard_set(const String &p_text);
|
virtual void clipboard_set(const String &p_text);
|
||||||
|
|
Loading…
Reference in a new issue