JosiahJack / Citadel

The System Shock Fan Remake Project
138 stars 16 forks source link

BUG: Cursor Behavior on Linux #328

Open JosiahJack opened 1 year ago

JosiahJack commented 1 year ago

Describe the bug When changing from Shoot Mode to Inventory Mode, the system cursor is unhidden and revealed to have never actually been locked and is thus in some strange position usually near an edge of the screen.

Attempted to use native xlib call but the system fights it and this only seems to work if I am not actively moving my mouse:

using System.Runtime.InteropServices;
using System;

public class MouseCursor : MonoBehaviour {

...

    #if UNITY_STANDALONE_LINUX
        [DllImport("libX11")]
        static extern IntPtr XOpenDisplay(string display);

        [DllImport("libX11")]
        static extern int XCloseDisplay(IntPtr display);

        [DllImport("libX11")]
        static extern int XWarpPointer(IntPtr display, IntPtr src_w, 
                                       IntPtr dest_w, int src_x, int src_y,
                                       uint src_width, uint src_height, 
                                       int dest_x, int dest_y);
    #elif UNITY_STANDALONE_WIN
        [DllImport("user32.dll")]
        public static extern bool SetCursorPos(int X, int Y);
    #endif

    public static void SetCursorPosInternal(int x, int y) {
        return; // Still experiencing issues, best to live with this bug a while yet.

        #if UNITY_STANDALONE_LINUX
            IntPtr display = XOpenDisplay(null);
            if (display == IntPtr.Zero) {
                throw new Exception("Failed to open display");
            }

            Debug.Log("warping pointer to " + x.ToString() + ", " + y.ToString());
            XWarpPointer(display, IntPtr.Zero, IntPtr.Zero, 0, 0, 0, 0, x, y);
            XCloseDisplay(display);
        #elif UNITY_STANDALONE_WIN
            SetCursorPos((int)(Screen.width * 0.5f),(int)(Screen.height * 0.5f));
        #endif
    }

...