当应用程序释放鼠标时,如何避免使用xinput坐标变换矩阵时鼠标光标跳跃

当应用程序释放鼠标时,如何避免使用xinput坐标变换矩阵时鼠标光标跳跃

我有一些高灵敏度的小鼠,我需要降低它们的灵敏度。对此的一般解决方案似乎是将坐标变换矩阵设置为可接受的值。所以我使用以下值:

xinput --set-prop 19 'Coordinate Transformation Matrix' 0.25 0 0  0 0.25 0  0 0 1

这工作得很好,除了我终于意识到它在玩《我的世界》时给我带来了问题。发生的情况是,当我按下任何让我返回光标的键时,只要我移动鼠标,光标就会跳到屏幕的左上象限。确切的位置与我使用的缩放数字成正比,因此 0.25 比 0.45 使光标更靠近角落。此外,如果我使用大于 1 的值,光标将移动到显示器的不同象限。当然,如果值为 1,则光标将按预期留在屏幕中央。这仅发生在第一次鼠标输入时,此后鼠标行为正常。

我需要有关如何避免这种光标移动的建议。真是令人抓狂。我也不认为这严格来说是一个 Minecraft 问题,而且我怀疑其他获取和释放鼠标光标的 java 应用程序也会发生这种情况。

更多信息,我的机器正在运行 Kubuntu 18.04 和 openJDK 10.0.2。

编辑:添加更多信息。在正常工作流程中,我开始在其他地方注意到这种行为。目前尚不清楚何时发生,但可能与 KDE 如何处理鼠标事件和窗口焦点有关。我使用跟随鼠标 - 鼠标优先。

答案1

我的“解决方案”是选择一个变换矩阵,使光标在居中时保持在适当的位置。

您要使用的矩阵是:

3 x 3 矩阵 s 0 (1-s)x 0 s (1-s)y 0 0 1

其中 s 是您想要的鼠标缩放系数,例如 0.5 表示半速。 x 和 y 是屏幕中心的坐标。

获取 x,y 值的一个简单方法是xdotool getmouselocation在跳转之前使用。

例子

我希望我的灵敏度 s = 0.4

在 Minecraft 中打开我的库存后,xdotool getmouseloation报告我的 x = 960 和 y = 1729。计算我的偏移量 (1-s)*x = 0.6*960 = 576 和 (1-s)*y = 0.6*1729 = 1037.4

然后我相应地改变了坐标变换矩阵

xinput set-prop 8 'Coordinate Transformation Matrix' 0.4 0 576 0 0.4 1037.4 0 0 1

(我的鼠标是设备 8,您可能会有所不同。)

缺陷

这仅解决了特定坐标的问题。对于像 Minecraft 这样的东西,你通常将窗口保持在相同的位置,这个修复已经足够好了,当你进入你的库存时,你的鼠标将不再跳跃。

在其他用例中,您仍然会遇到跳跃,但当鼠标靠近您选择的 x,y 时,跳跃会更小。

数学细节

有关数学的更多详细信息,请参阅https://math.stackexchange.com/questions/2954781/calculated-the-translation-of-an-affine-matrix-so-that-it-centres-during-scalin

答案2

请改用加速。对于我的 HyperX Pulsefire Surge 上的 16000 DPI,正常值为 -0.935。此错误也适用于自动隐藏、鼠标传送的面板。

答案3

尝试使用 XIWarpPointer 到您自己的 XWarpPointer 版本。就像是:

#include <X11/extensions/XInput2.h>
int XWarpPointer(Display *display, Window src_w, Window dest_w, int src_x, int
            src_y, unsigned int src_width, unsigned int src_height, int dest_x, int
            dest_y){
    static int isnew=1;
    static int device=0;
    int dev_temp;
    if(XIGetClientPointer(display,dest_w,&dev_temp)){
        isnew=0;
        device=dev_temp;
    }
    if(isnew) return 1;
    return XIWarpPointer(display,device,src_w,dest_w,src_x,src_y,src_width,src_height,dest_x,dest_y);
}

使用 gcc xwarp.c --shared -o xwarp.so -lXi 编译它,然后使用 LD_PRELOAD

相关内容