-
-
Notifications
You must be signed in to change notification settings - Fork 21.3k
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
Handle potential platform-specific Window
mouse-enter/exit bugs gracefully
#80187
Handle potential platform-specific Window
mouse-enter/exit bugs gracefully
#80187
Conversation
After giving it some thought, I'm no longer sure, if ERR_FAIL is needed, because with this change, |
scene/main/window.cpp
Outdated
} break; | ||
case DisplayServer::WINDOW_EVENT_MOUSE_EXIT: { | ||
Window *root = get_tree()->get_root(); | ||
DEV_ASSERT(root->gui.windowmanager_window_over); // Exiting a window, while no window is hovered should never happen. | ||
ERR_FAIL_NULL_MSG(root->gui.windowmanager_window_over, "Exiting a window, while no window is hovered should never happen."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ERR_FAIL_NULL_MSG(root->gui.windowmanager_window_over, "Exiting a window, while no window is hovered should never happen."); | |
ERR_FAIL_NULL_MSG(root->gui.windowmanager_window_over, "Exiting a window while no window is hovered should never happen."); |
But "should never happen" is still the kind of message that one would use for a DEV_ASSERT
.
If it can be triggered by user code, and thus require an ERR_FAIL
for graceful handling, then it does actually happen and the message should clarify what went wrong so that the user can fix it on their side.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Though I guess here the "user" can be a platform port that does things wrong in its window handling? So I guess it makes sense as is.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is the question, that I try to wrap my head around.
If "user" is a engine-developer of platform code, then the error-message helps identifying an engine-problem.
if "user" is a game-developer, then the error-message has no benefit, because the game-developer can not address the problem.
In any case, I have accepted your code-change suggestion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After giving it some thought, I'm no longer sure, if ERR_FAIL is needed, because with this change, Window handles all possible cases.
Probably not, I'm sure, if arrival of system move event messages is always guaranteed, and error won't be useful for users. It should be OK to simply ignore duplicate mouse enter/exit events.
scene/main/window.cpp
Outdated
@@ -672,16 +672,21 @@ void Window::_event_callback(DisplayServer::WindowEvent p_event) { | |||
case DisplayServer::WINDOW_EVENT_MOUSE_ENTER: { | |||
_propagate_window_notification(this, NOTIFICATION_WM_MOUSE_ENTER); | |||
Window *root = get_tree()->get_root(); | |||
DEV_ASSERT(!root->gui.windowmanager_window_over); // Entering a window while a window is hovered should never happen. | |||
Window *previous_over = root->gui.windowmanager_window_over; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If mouse exit
was not received, windowmanager_window_over
might be an invalid pointer to the deleted Window
(the same might happen in Viewport._update_mouse_over()
). Maybe ObjectID
should be stored instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed I haven't thought about stale gui.windowmanager_window_over
. Thanks for pointing me to this. I will investigate this and try to check situations, where this happens.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have tried multiple ways to cause a crash on X11 based on stale gui.windowmanager_window_over
- situations, that crashed without this fix
- explicitly freeing (queue_free and free)
But I wasn't able to cause a crash. However I can't rule out, that it is possible to cause a crash this way.
81d2126
to
b35f9de
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably not, I'm sure, if arrival of system move event messages is always guaranteed, and error won't be useful for users. It should be OK to simply ignore duplicate mouse enter/exit events.
So for me this boils down to the following question:
- Should platform-implementations be forced to adhere to the same behavior regarding send mouse-enter window-events or
- should platform-implementations be allowed to be vague about mouse-enter window-events and catch all possible cases in the
Window
-class?
Personally I believe that the goal should be to align the behavior of all platform-implementations.
scene/main/window.cpp
Outdated
@@ -672,16 +672,21 @@ void Window::_event_callback(DisplayServer::WindowEvent p_event) { | |||
case DisplayServer::WINDOW_EVENT_MOUSE_ENTER: { | |||
_propagate_window_notification(this, NOTIFICATION_WM_MOUSE_ENTER); | |||
Window *root = get_tree()->get_root(); | |||
DEV_ASSERT(!root->gui.windowmanager_window_over); // Entering a window while a window is hovered should never happen. | |||
Window *previous_over = root->gui.windowmanager_window_over; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed I haven't thought about stale gui.windowmanager_window_over
. Thanks for pointing me to this. I will investigate this and try to check situations, where this happens.
scene/main/window.cpp
Outdated
} break; | ||
case DisplayServer::WINDOW_EVENT_MOUSE_EXIT: { | ||
Window *root = get_tree()->get_root(); | ||
DEV_ASSERT(root->gui.windowmanager_window_over); // Exiting a window, while no window is hovered should never happen. | ||
ERR_FAIL_NULL_MSG(root->gui.windowmanager_window_over, "Exiting a window, while no window is hovered should never happen."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is the question, that I try to wrap my head around.
If "user" is a engine-developer of platform code, then the error-message helps identifying an engine-problem.
if "user" is a game-developer, then the error-message has no benefit, because the game-developer can not address the problem.
In any case, I have accepted your code-change suggestion.
b35f9de
to
a81a6aa
Compare
Testing this locally. It fixes the crash caused by the dev assert. But every single time I navigate within the 3D viewport (RMB + mouse move for example) I get the "Entering a window while hovering it should never happen." error. |
Maybe a |
Had the same idea about |
…cefully Also replace `DEV_ASSERT` by `WARN_PRINT_ONCE`.
a81a6aa
to
2f8673d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems good as a stopgap solution.
Thanks! |
Also replace
DEV_ASSERT
byERR_FAIL
.followup to #67791
implement comment #67791 (comment)
based on #80156
fix #80335