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 mouse position with screen transform #77923

Conversation

Sauermann
Copy link
Contributor

@Sauermann Sauermann commented Jun 6, 2023

When a Viewport is not in the scene tree or not a child of a SubViewportContainer, the function Viewport::get_mouse_position can't rely on get_screen_transform, because that function is ambiguous in these situations.
In these cases it is necessary to use the mouse position from the most recent mouse InputEvent.

resolve #74868

@Sauermann Sauermann requested a review from a team as a code owner June 6, 2023 18:49
@akien-mga akien-mga added this to the 4.1 milestone Jun 6, 2023
@akien-mga akien-mga requested a review from RandomShaper June 6, 2023 20:24
@@ -1351,7 +1351,12 @@ Ref<InputEvent> Viewport::_make_input_local(const Ref<InputEvent> &ev) {

Vector2 Viewport::get_mouse_position() const {
ERR_READ_THREAD_GUARD_V(Vector2());
if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_MOUSE)) {
if (!is_inside_tree() || (Object::cast_to<SubViewport>(this) && !Object::cast_to<SubViewportContainer>(get_parent()))) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm wondering if this condition can be rewritten based on some already existing is-attached-to-screen functionality or at least should be put in a new virtual bool is_attached_to_screen(), or the like.

Maybe not. It's that checking the type of this seems a bit odd.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not aware of any existing functionality, that covers this.

is_attached_to_screen could be something like:

bool SubViewport::is_attached_to_screen() const {
   return Object::cast_to<SubViewportContainer>(get_parent()) && get_parent()->get_viewport() && get_parent()->get_viewport()->is_attached_to_screen();
}
bool Window::is_attached_to_screen() const {
    if (get_embedder()) {
        return get_embedder()->is_attached_to_screen();
    }
    return is_inside_tree();
}

Alternatively we could introduce a virtual function:

bool Viewport::is_window() const {
    return true;
}
bool SubViewport::is_window() const {
    return false;
}

And replace Object::cast_to<SubViewport>(this) by !_is_window().

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have updated the PR and introduced a is_directly_attached_to_screen method.

When a Viewport is not directly attached to the screen, the
function `Viewport::get_mouse_position` can't rely on
`get_screen_transform`, because that function is ambiguous in
these situations.
In these cases it is necessary to use the mouse position from
the most recent mouse IputEvent.
@Sauermann Sauermann force-pushed the fix-mouse-position-with-screen-transform branch from 90db2cf to d1fa284 Compare June 9, 2023 09:30
@akien-mga akien-mga merged commit 0cee1e0 into godotengine:master Jun 9, 2023
@Sauermann Sauermann deleted the fix-mouse-position-with-screen-transform branch June 9, 2023 11:48
@akien-mga
Copy link
Member

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

TreeItem buttons do not function in a SubViewport using the push_input method.
3 participants