Skip to content

Commit

Permalink
Remove some DisplayServer::mouse_get_position calls
Browse files Browse the repository at this point in the history
These functions can get called in situations, where relying on
DisplayServer make no sense (e.g. XR or Gui-in-3D Demo).
This PR introduces `Viewport::get_embedder_mouse_position()` and adds
checks to verify if `DisplayServer::mouse_get_position` can get called.
  • Loading branch information
Sauermann committed Jan 26, 2024
1 parent 17e7f85 commit fddf02b
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 16 deletions.
4 changes: 2 additions & 2 deletions editor/gui/editor_title_bar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ void EditorTitleBar::gui_input(const Ref<InputEvent> &p_event) {
if (mm->get_button_mask().has_flag(MouseButtonMask::LEFT)) {
Window *w = Object::cast_to<Window>(get_viewport());
if (w) {
Point2 mouse = DisplayServer::get_singleton()->mouse_get_position();
Point2 mouse = get_viewport()->get_embedder_mouse_position();
w->set_position(mouse - click_pos);
}
} else {
Expand All @@ -54,7 +54,7 @@ void EditorTitleBar::gui_input(const Ref<InputEvent> &p_event) {
if (w) {
if (mb->get_button_index() == MouseButton::LEFT) {
if (mb->is_pressed()) {
click_pos = DisplayServer::get_singleton()->mouse_get_position() - w->get_position();
click_pos = get_viewport()->get_embedder_mouse_position() - w->get_position();
moving = true;
} else {
moving = false;
Expand Down
1 change: 1 addition & 0 deletions scene/gui/color_picker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ void ColorPicker::_notification(int p_what) {
if (!is_picking_color) {
return;
}
// This is only executed if previously is was checked, that the DisplayServer supports these functions.
set_pick_color(DisplayServer::get_singleton()->screen_get_pixel(DisplayServer::get_singleton()->mouse_get_position()));
}
}
Expand Down
16 changes: 2 additions & 14 deletions scene/gui/popup_menu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -398,20 +398,8 @@ void PopupMenu::_activate_submenu(int p_over, bool p_by_keyboard) {

void PopupMenu::_parent_focused() {
if (is_embedded()) {
Point2 mouse_pos_adjusted;
Window *window_parent = Object::cast_to<Window>(get_parent()->get_viewport());
while (window_parent) {
if (!window_parent->is_embedded()) {
mouse_pos_adjusted += window_parent->get_position();
break;
}

window_parent = Object::cast_to<Window>(window_parent->get_parent()->get_viewport());
}

Rect2 safe_area = get_embedder()->subwindow_get_popup_safe_rect(this);
Point2 pos = DisplayServer::get_singleton()->mouse_get_position() - mouse_pos_adjusted;
if (safe_area == Rect2i() || !safe_area.has_point(pos)) {
if (safe_area == Rect2i() || !safe_area.has_point(get_embedder_mouse_position())) {
Popup::_parent_focused();
} else {
grab_focus();
Expand Down Expand Up @@ -1127,7 +1115,7 @@ void PopupMenu::_notification(int p_what) {

// Only used when using operating system windows.
if (!activated_by_keyboard && !is_embedded() && autohide_areas.size()) {
Point2 mouse_pos = DisplayServer::get_singleton()->mouse_get_position();
Point2 mouse_pos = get_embedder_mouse_position();
mouse_pos -= get_position();

for (const Rect2 &E : autohide_areas) {
Expand Down
35 changes: 35 additions & 0 deletions scene/main/viewport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1398,10 +1398,41 @@ Vector2 Viewport::get_mouse_position() const {
return xform.affine_inverse().xform(DisplayServer::get_singleton()->mouse_get_position());
} else {
// Fallback to Input for getting mouse position in case of emulated mouse.
// Reports wrong coordinates, when used in an unfocused native Window.
return get_screen_transform_internal().affine_inverse().xform(Input::get_singleton()->get_mouse_position());
}
}

Vector2 Viewport::get_embedder_mouse_position() const {
// Return the mouse position in the coordinate system of the Viewport, where this is embedded.
// If this is a non-embedded Window, return the mouse position of the DisplayServer, if it supports it.
ERR_READ_THREAD_GUARD_V(Vector2());

const Window *w = Object::cast_to<Window>(this);
if (w) {
Viewport *e = w->get_embedder();
if (e) {
return e->get_mouse_position();
}
// Viewport is a native Window.
if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_MOUSE)) {
return DisplayServer::get_singleton()->mouse_get_position();
}
// Fallback to Input for getting mouse position in case of emulated mouse.
// Reports wrong coordinates, when used in an unfocused native Window.
return Input::get_singleton()->get_mouse_position();
}

// This is a SubViewport.
Window *b = get_base_window();
if (b) {
return b->get_embedder_mouse_position();
}

// Case that SubViewport is not directly attached to screen.
return gui.last_mouse_pos;
}

void Viewport::warp_mouse(const Vector2 &p_position) {
ERR_MAIN_THREAD_GUARD;
Transform2D xform = get_screen_transform_internal();
Expand Down Expand Up @@ -2556,6 +2587,10 @@ Window *Viewport::get_base_window() const {
Viewport *v = const_cast<Viewport *>(this);
Window *w = Object::cast_to<Window>(v);
while (!w) {
if (!Object::cast_to<SubViewportContainer>(v->get_parent())) {
// In this case there is no meaningful Window to return.
return nullptr;
}
v = v->get_parent_viewport();
w = Object::cast_to<Window>(v);
}
Expand Down
1 change: 1 addition & 0 deletions scene/main/viewport.h
Original file line number Diff line number Diff line change
Expand Up @@ -595,6 +595,7 @@ class Viewport : public Node {
bool is_input_disabled() const;

Vector2 get_mouse_position() const;
Vector2 get_embedder_mouse_position() const;
void warp_mouse(const Vector2 &p_position);
virtual void update_mouse_cursor_state();

Expand Down

0 comments on commit fddf02b

Please sign in to comment.