Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Viewport::get_mouse_position for SubViewports #71768

Merged
merged 1 commit into from
Feb 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 13 additions & 4 deletions scene/main/viewport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1172,11 +1172,16 @@ Ref<InputEvent> Viewport::_make_input_local(const Ref<InputEvent> &ev) {
}

Vector2 Viewport::get_mouse_position() const {
return gui.last_mouse_pos;
if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_MOUSE)) {
return get_screen_transform_internal(true).affine_inverse().xform(DisplayServer::get_singleton()->mouse_get_position());
} else {
// Fallback to Input for getting mouse position in case of emulated mouse.
return get_screen_transform_internal().affine_inverse().xform(Input::get_singleton()->get_mouse_position());
}
}

void Viewport::warp_mouse(const Vector2 &p_position) {
Transform2D xform = get_screen_transform();
Transform2D xform = get_screen_transform_internal();
Vector2 gpos = xform.xform(p_position);
Input::get_singleton()->warp_mouse(gpos);
}
Expand Down Expand Up @@ -3288,6 +3293,10 @@ Viewport::SDFScale Viewport::get_sdf_scale() const {
}

Transform2D Viewport::get_screen_transform() const {
return get_screen_transform_internal();
}

Transform2D Viewport::get_screen_transform_internal(bool p_absolute_position) const {
return get_final_transform();
}

Expand Down Expand Up @@ -4226,14 +4235,14 @@ DisplayServer::WindowID SubViewport::get_window_id() const {
return DisplayServer::INVALID_WINDOW_ID;
}

Transform2D SubViewport::get_screen_transform() const {
Transform2D SubViewport::get_screen_transform_internal(bool p_absolute_position) const {
Transform2D container_transform;
SubViewportContainer *c = Object::cast_to<SubViewportContainer>(get_parent());
if (c) {
if (c->is_stretch_enabled()) {
container_transform.scale(Vector2(c->get_stretch_shrink(), c->get_stretch_shrink()));
}
container_transform = c->get_viewport()->get_screen_transform() * c->get_global_transform_with_canvas() * container_transform;
container_transform = c->get_viewport()->get_screen_transform_internal(p_absolute_position) * c->get_global_transform_with_canvas() * container_transform;
} else {
WARN_PRINT_ONCE("SubViewport is not a child of a SubViewportContainer. get_screen_transform doesn't return the actual screen position.");
}
Expand Down
5 changes: 3 additions & 2 deletions scene/main/viewport.h
Original file line number Diff line number Diff line change
Expand Up @@ -651,7 +651,8 @@ class Viewport : public Node {

virtual bool is_size_2d_override_stretch_enabled() const { return true; }

virtual Transform2D get_screen_transform() const;
Transform2D get_screen_transform() const;
virtual Transform2D get_screen_transform_internal(bool p_absolute_position = false) const;
virtual Transform2D get_popup_base_transform() const { return Transform2D(); }

#ifndef _3D_DISABLED
Expand Down Expand Up @@ -780,7 +781,7 @@ class SubViewport : public Viewport {
void set_clear_mode(ClearMode p_mode);
ClearMode get_clear_mode() const;

virtual Transform2D get_screen_transform() const override;
virtual Transform2D get_screen_transform_internal(bool p_absolute_position = false) const override;
virtual Transform2D get_popup_base_transform() const override;

SubViewport();
Expand Down
6 changes: 4 additions & 2 deletions scene/main/window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2120,11 +2120,13 @@ Transform2D Window::get_final_transform() const {
return window_transform * stretch_transform * global_canvas_transform;
}

Transform2D Window::get_screen_transform() const {
Transform2D Window::get_screen_transform_internal(bool p_absolute_position) const {
Transform2D embedder_transform;
if (_get_embedder()) {
embedder_transform.translate_local(get_position());
embedder_transform = _get_embedder()->get_screen_transform() * embedder_transform;
embedder_transform = _get_embedder()->get_screen_transform_internal(p_absolute_position) * embedder_transform;
} else if (p_absolute_position) {
embedder_transform.translate_local(get_position());
}
return embedder_transform * get_final_transform();
}
Expand Down
2 changes: 1 addition & 1 deletion scene/main/window.h
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,7 @@ class Window : public Viewport {
//

virtual Transform2D get_final_transform() const override;
virtual Transform2D get_screen_transform() const override;
virtual Transform2D get_screen_transform_internal(bool p_absolute_position = false) const override;
virtual Transform2D get_popup_base_transform() const override;

Rect2i get_parent_rect() const;
Expand Down