Skip to content

Commit

Permalink
Redirect mouse events to the window under cursor, simplify popup menu…
Browse files Browse the repository at this point in the history
… input processing.
  • Loading branch information
bruvzg committed Feb 17, 2024
1 parent 907db8e commit 4ea196d
Show file tree
Hide file tree
Showing 5 changed files with 142 additions and 91 deletions.
58 changes: 23 additions & 35 deletions platform/linuxbsd/x11/display_server_x11.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1813,8 +1813,7 @@ DisplayServerX11::WindowID DisplayServerX11::get_window_at_screen_position(const
for (const KeyValue<WindowID, WindowData> &E : windows) {
const WindowData &wd = E.value;

// Discard windows with no focus.
if (wd.focus_order == 0) {
if (wd.mpass) {
continue;
}

Expand Down Expand Up @@ -4759,10 +4758,15 @@ void DisplayServerX11::process_events() {
event.xbutton.y = last_mouse_pos.y;
}

DisplayServer::WindowID receiving_window_id = get_window_at_screen_position(mouse_get_position());
if (receiving_window_id == DisplayServer::INVALID_WINDOW_ID) {
receiving_window_id = window_id;
}

Ref<InputEventMouseButton> mb;
mb.instantiate();

mb->set_window_id(window_id);
mb->set_window_id(receiving_window_id);
_get_key_modifier_state(event.xbutton.state, mb);
mb->set_button_index((MouseButton)event.xbutton.button);
if (mb->get_button_index() == MouseButton::RIGHT) {
Expand Down Expand Up @@ -4846,6 +4850,11 @@ void DisplayServerX11::process_events() {
}
}

if (receiving_window_id != window_id) {
// Adjust event position relative to window distance when event is sent to a different window.
mb->set_position(mb->get_position() - window_get_position(receiving_window_id) + window_get_position(window_id));
mb->set_global_position(mb->get_position());
}
Input::get_singleton()->parse_input_event(mb);

} break;
Expand Down Expand Up @@ -4941,10 +4950,15 @@ void DisplayServerX11::process_events() {
pos = Point2i(windows[focused_window_id].size.width / 2, windows[focused_window_id].size.height / 2);
}

DisplayServer::WindowID receiving_window_id = get_window_at_screen_position(mouse_get_position());
if (receiving_window_id == DisplayServer::INVALID_WINDOW_ID) {
receiving_window_id = window_id;
}

Ref<InputEventMouseMotion> mm;
mm.instantiate();

mm->set_window_id(window_id);
mm->set_window_id(receiving_window_id);
if (xi.pressure_supported) {
mm->set_pressure(xi.pressure);
} else {
Expand All @@ -4965,38 +4979,12 @@ void DisplayServerX11::process_events() {

last_mouse_pos = pos;

// printf("rel: %d,%d\n", rel.x, rel.y );
// Don't propagate the motion event unless we have focus
// this is so that the relative motion doesn't get messed up
// after we regain focus.
if (focused) {
Input::get_singleton()->parse_input_event(mm);
} else {
// Propagate the event to the focused window,
// because it's received only on the topmost window.
// Note: This is needed for drag & drop to work between windows,
// because the engine expects events to keep being processed
// on the same window dragging started.
for (const KeyValue<WindowID, WindowData> &E : windows) {
const WindowData &wd_other = E.value;
if (wd_other.focused) {
int x, y;
Window child;
XTranslateCoordinates(x11_display, wd.x11_window, wd_other.x11_window, event.xmotion.x, event.xmotion.y, &x, &y, &child);

Point2i pos_focused(x, y);

mm->set_window_id(E.key);
mm->set_position(pos_focused);
mm->set_global_position(pos_focused);
mm->set_velocity(Input::get_singleton()->get_last_mouse_velocity());
Input::get_singleton()->parse_input_event(mm);

break;
}
}
if (receiving_window_id != window_id) {
// Adjust event position relative to window distance when event is sent to a different window.
mm->set_position(mm->get_position() - window_get_position(receiving_window_id) + window_get_position(window_id));
mm->set_global_position(mm->get_position());
}

Input::get_singleton()->parse_input_event(mm);
} break;
case KeyPress:
case KeyRelease: {
Expand Down
47 changes: 35 additions & 12 deletions platform/macos/godot_content_view.mm
Original file line number Diff line number Diff line change
Expand Up @@ -374,9 +374,14 @@ - (void)processMouseEvent:(NSEvent *)event index:(MouseButton)index pressed:(boo
}
ds->mouse_set_button_state(last_button_state);

DisplayServer::WindowID receiving_window_id = ds->get_window_at_screen_position(ds->mouse_get_position());
if (receiving_window_id == DisplayServer::INVALID_WINDOW_ID) {
receiving_window_id = window_id;
}

Ref<InputEventMouseButton> mb;
mb.instantiate();
mb->set_window_id(window_id);
mb->set_window_id(receiving_window_id);
if (outofstream) {
ds->update_mouse_pos(wd, [wd.window_object mouseLocationOutsideOfEventStream]);
} else {
Expand All @@ -392,6 +397,11 @@ - (void)processMouseEvent:(NSEvent *)event index:(MouseButton)index pressed:(boo
mb->set_double_click([event clickCount] == 2);
}

if (receiving_window_id != window_id) {
// Adjust event position relative to window distance when event is sent to a different window.
mb->set_position(mb->get_position() - ds->window_get_position(receiving_window_id) + ds->window_get_position(window_id));
mb->set_global_position(mb->get_position());
}
Input::get_singleton()->parse_input_event(mb);
}

Expand Down Expand Up @@ -432,10 +442,15 @@ - (void)mouseMoved:(NSEvent *)event {
return;
}

DisplayServer::WindowID receiving_window_id = ds->get_window_at_screen_position(ds->mouse_get_position());
if (receiving_window_id == DisplayServer::INVALID_WINDOW_ID) {
receiving_window_id = window_id;
}

Ref<InputEventMouseMotion> mm;
mm.instantiate();

mm->set_window_id(window_id);
mm->set_window_id(receiving_window_id);
mm->set_button_mask(ds->mouse_get_button_state());
ds->update_mouse_pos(wd, mpos);
mm->set_position(wd.mouse_pos);
Expand All @@ -458,6 +473,11 @@ - (void)mouseMoved:(NSEvent *)event {
mm->set_relative_screen_position(relativeMotion);
ds->get_key_modifier_state([event modifierFlags], mm);

if (receiving_window_id != window_id) {
// Adjust event position relative to window distance when event is sent to a different window.
mm->set_position(mm->get_position() - ds->window_get_position(receiving_window_id) + ds->window_get_position(window_id));
mm->set_global_position(mm->get_position());
}
Input::get_singleton()->parse_input_event(mm);
}

Expand Down Expand Up @@ -740,10 +760,15 @@ - (void)processScrollEvent:(NSEvent *)event button:(MouseButton)button factor:(d
MouseButtonMask mask = mouse_button_to_mask(button);
BitField<MouseButtonMask> last_button_state = ds->mouse_get_button_state();

DisplayServer::WindowID receiving_window_id = ds->get_window_at_screen_position(ds->mouse_get_position());
if (receiving_window_id == DisplayServer::INVALID_WINDOW_ID) {
receiving_window_id = window_id;
}

Ref<InputEventMouseButton> sc;
sc.instantiate();

sc->set_window_id(window_id);
sc->set_window_id(receiving_window_id);
ds->get_key_modifier_state([event modifierFlags], sc);
sc->set_button_index(button);
sc->set_factor(factor);
Expand All @@ -754,18 +779,16 @@ - (void)processScrollEvent:(NSEvent *)event button:(MouseButton)button factor:(d
sc->set_button_mask(last_button_state);
ds->mouse_set_button_state(last_button_state);

if (receiving_window_id != window_id) {
// Adjust event position relative to window distance when event is sent to a different window.
sc->set_position(sc->get_position() - ds->window_get_position(receiving_window_id) + ds->window_get_position(window_id));
sc->set_global_position(sc->get_position());
}

Input::get_singleton()->parse_input_event(sc);

sc.instantiate();
sc->set_window_id(window_id);
sc->set_button_index(button);
sc->set_factor(factor);
sc = sc->duplicate();
sc->set_pressed(false);
sc->set_position(wd.mouse_pos);
sc->set_global_position(wd.mouse_pos);
last_button_state.clear_flag(mask);
sc->set_button_mask(last_button_state);
ds->mouse_set_button_state(last_button_state);

Input::get_singleton()->parse_input_event(sc);
}
Expand Down
59 changes: 48 additions & 11 deletions platform/windows/display_server_windows.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3616,10 +3616,15 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
}
}
} else if (mouse_mode == MOUSE_MODE_CAPTURED && raw->header.dwType == RIM_TYPEMOUSE) {
DisplayServer::WindowID receiving_window_id = get_window_at_screen_position(mouse_get_position());
if (receiving_window_id == DisplayServer::INVALID_WINDOW_ID) {
receiving_window_id = window_id;
}

Ref<InputEventMouseMotion> mm;
mm.instantiate();

mm->set_window_id(window_id);
mm->set_window_id(receiving_window_id);
mm->set_ctrl_pressed(control_mem);
mm->set_shift_pressed(shift_mem);
mm->set_alt_pressed(alt_mem);
Expand Down Expand Up @@ -3665,7 +3670,12 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
}
mm->set_relative_screen_position(mm->get_relative());

if ((windows[window_id].window_has_focus || windows[window_id].is_popup) && mm->get_relative() != Vector2()) {
if (mm->get_relative() != Vector2()) {
if (receiving_window_id != window_id) {
// Adjust event position relative to window distance when event is sent to a different window.
mm->set_position(mm->get_position() - window_get_position(receiving_window_id) + window_get_position(window_id));
mm->set_global_position(mm->get_position());
}
Input::get_singleton()->parse_input_event(mm);
}
}
Expand Down Expand Up @@ -3717,9 +3727,14 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
break;
}

DisplayServer::WindowID receiving_window_id = get_window_at_screen_position(mouse_get_position());
if (receiving_window_id == DisplayServer::INVALID_WINDOW_ID) {
receiving_window_id = window_id;
}

Ref<InputEventMouseMotion> mm;
mm.instantiate();
mm->set_window_id(window_id);
mm->set_window_id(receiving_window_id);
mm->set_ctrl_pressed(GetKeyState(VK_CONTROL) < 0);
mm->set_shift_pressed(GetKeyState(VK_SHIFT) < 0);
mm->set_alt_pressed(alt_mem);
Expand Down Expand Up @@ -3763,9 +3778,13 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
mm->set_relative_screen_position(mm->get_relative());
old_x = mm->get_position().x;
old_y = mm->get_position().y;
if (windows[window_id].window_has_focus || window_get_active_popup() == window_id) {
Input::get_singleton()->parse_input_event(mm);

if (receiving_window_id != window_id) {
// Adjust event position relative to window distance when event is sent to a different window.
mm->set_position(mm->get_position() - window_get_position(receiving_window_id) + window_get_position(window_id));
mm->set_global_position(mm->get_position());
}
Input::get_singleton()->parse_input_event(mm);
}
return 0;
}
Expand Down Expand Up @@ -3853,10 +3872,15 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
break;
}

DisplayServer::WindowID receiving_window_id = get_window_at_screen_position(mouse_get_position());
if (receiving_window_id == DisplayServer::INVALID_WINDOW_ID) {
receiving_window_id = window_id;
}

Ref<InputEventMouseMotion> mm;
mm.instantiate();

mm->set_window_id(window_id);
mm->set_window_id(receiving_window_id);
if (pen_info.penMask & PEN_MASK_PRESSURE) {
mm->set_pressure((float)pen_info.pressure / 1024);
} else {
Expand Down Expand Up @@ -3912,9 +3936,13 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
mm->set_relative_screen_position(mm->get_relative());
old_x = mm->get_position().x;
old_y = mm->get_position().y;
if (windows[window_id].window_has_focus || window_get_active_popup() == window_id) {
Input::get_singleton()->parse_input_event(mm);

if (receiving_window_id != window_id) {
// Adjust event position relative to window distance when event is sent to a different window.
mm->set_position(mm->get_position() - window_get_position(receiving_window_id) + window_get_position(window_id));
mm->set_global_position(mm->get_position());
}
Input::get_singleton()->parse_input_event(mm);

return 0; // Pointer event handled return 0 to avoid duplicate WM_MOUSEMOVE event.
} break;
Expand Down Expand Up @@ -3968,7 +3996,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
break;
}

DisplayServer::WindowID receiving_window_id = _get_focused_window_or_popup();
DisplayServer::WindowID receiving_window_id = get_window_at_screen_position(mouse_get_position());
if (receiving_window_id == INVALID_WINDOW_ID) {
receiving_window_id = window_id;
}
Expand Down Expand Up @@ -4064,9 +4092,14 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
case WM_XBUTTONDBLCLK:
case WM_XBUTTONDOWN:
case WM_XBUTTONUP: {
DisplayServer::WindowID receiving_window_id = get_window_at_screen_position(mouse_get_position());
if (receiving_window_id == DisplayServer::INVALID_WINDOW_ID) {
receiving_window_id = window_id;
}

Ref<InputEventMouseButton> mb;
mb.instantiate();
mb->set_window_id(window_id);
mb->set_window_id(receiving_window_id);

switch (uMsg) {
case WM_LBUTTONDOWN: {
Expand Down Expand Up @@ -4209,11 +4242,15 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA

mb->set_global_position(mb->get_position());

if (receiving_window_id != window_id) {
// Adjust event position relative to window distance when event is sent to a different window.
mb->set_position(mb->get_position() - window_get_position(receiving_window_id) + window_get_position(window_id));
mb->set_global_position(mb->get_position());
}
Input::get_singleton()->parse_input_event(mb);
if (mb->is_pressed() && mb->get_button_index() >= MouseButton::WHEEL_UP && mb->get_button_index() <= MouseButton::WHEEL_RIGHT) {
// Send release for mouse wheel.
Ref<InputEventMouseButton> mbd = mb->duplicate();
mbd->set_window_id(window_id);
last_button_state.clear_flag(mouse_button_to_mask(mbd->get_button_index()));
mbd->set_button_mask(last_button_state);
mbd->set_pressed(false);
Expand Down
Loading

0 comments on commit 4ea196d

Please sign in to comment.