Moving the (real) mouse cursor using a gamepad works but triggers wrong events

I’m looking to make a simple shim that allows users to interact with my main menus (yes, it’s because my app isn’t passing the steam build review). I can’t find an InputManager based method to move the cursor, so I just linked to the user32.dll since my app is windows only (for now). This works great in that the cursor moves and I can trigger clicks with my gamepad. BUT: this approach badly breaks something in the unity event system, and sometimes clicks and mouse cursor location can be disassociated, as tho the event system thinks the cursor is somewhere FAR behind where it’s currently being displayed by Windows. I tried moving the cursor using setpos/getpos or using mouse_event and both have this flaw. Does anybody have a fix for this, or some other shim code that uses a different method to move a cursor to an arbitrary location on the screen and dispatch click events to any UI object under that location?

Here’s my code, showing both approaches I tried:

using System.Runtime.InteropServices;
using UnityEngine;

public class MouseController : MonoBehaviour
{
   [DllImport("user32.dll")]
    static extern bool SetCursorPos(int x, int y);


     [StructLayout(LayoutKind.Sequential)]
    public struct POINT
    {
        public int x;
        public int y;

        public static implicit operator Vector2(POINT p)
        {
            return new Vector2(p.x, p.y);
        }
    }

    [DllImport("user32.dll")]
    private static extern bool GetCursorPos(out POINT lpPoint);

    [DllImport("user32.dll")]
    static extern void mouse_event(uint dwFlags, int dx, int dy, uint cButtons, uint dwExtraInfo);

    // Mouse event flags
    const uint MOUSEEVENTF_LEFTDOWN = 0x02;
    const uint MOUSEEVENTF_LEFTUP = 0x04;
    const uint MOUSEEVENTF_MOVE = 0x0001;

    public string buttonName = "Jump"; // The name of the button in Input Manager

    public float cursorSpeed = .5f;

    public void MoveMouse(Vector2 delta) // move mouse cursor relative to current location (set + getpos version)
        {
        POINT p;
        GetCursorPos(out p);
        SetCursorPos((int)(delta.x + p.x), (int)(delta.y + p.y));
        } 

/* 
    public void MoveMouse(Vector2 delta) // move mouse cursor relative to current location (mouse event version)
        {
            mouse_event(MOUSEEVENTF_MOVE, (int)delta.x, (int)delta.y, 0, 0);
        }
*/
 

    void Update()
    {

    float horizontal = Input.GetAxis("Horizontal");
    float vertical = Input.GetAxis("Vertical");

    Vector2 delta = new Vector2(horizontal * cursorSpeed, vertical * -cursorSpeed); // invert y maps more intuitively

    MoveMouse(delta);

    // Simulate mouse down on button press
    if (Input.GetButtonDown(buttonName))
        {
            mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
            print ("clicked");
        }

        // Simulate mouse up on button release
    if (Input.GetButtonUp(buttonName))
        {
            mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
            print ("released");
        }
    }
}

I also tried using SendInput to synthesize the button press event but this fails in the same way as using mouse_event

   private void SimulateMouseClick(int x, int y, uint flag)
    {
        INPUT[] input = new INPUT[1];
        input[0].type = 0; // INPUT_MOUSE
        input[0].mi.dx = y;
        input[0].mi.dy = x;
        input[0].mi.mouseData = 0;
        input[0].mi.dwFlags = flag;
        input[0].mi.time = 0;
        input[0].mi.dwExtraInfo = 0;

        print(SendInput(1, input, Marshal.SizeOf(typeof(INPUT))));
    }
 ///....
 SimulateMouseClick(p.x, p.y, MOUSEEVENTF_LEFTDOWN);

I think you are responsible for bridging input from whatever input system you’re using over to an InputModule-derived object of your own, probably that replaces the StandardInputModule that arrives on the EventSystem GameObject.

https://docs.unity3d.com/Packages/com.unity.ugui@1.0/manual/InputModules.html

Hmm I’m really confused by your response - is it possible you meant to respond to the question I explicitly asked about StandardInputModule? It was admittedly related to what’s happening here - just an entirely different method of making synthetic clicks. Here I’m solely using the win32 API in an attempt to sidestep all of Unity’s own input event handling code complexity.

This is at least HALF the problem with my code (any of the above versions)

once I managed to select any UI object, pressing the Joystick1Button0 caused a “submit” event to fire.
Just so happens that Joy0 was also what I using to simulate button presses in my code. So I was getting double events. Switching my code to use Joystick1Button1 and (so far) it’s working perfectly.

The submit event is a default/example event in the input manger so you likely have one too, if you are still stuck in the old-world method of handling input.