KasmVNC icon indicating copy to clipboard operation
KasmVNC copied to clipboard

Relative Mode (with or without Pointer Lock)

Open hochbit opened this issue 11 months ago • 3 comments

Is your feature request related to a problem? Please describe. I want to use UnrealEditor when using VNC inside a Pod of a Kubernetes Cluster... to get access to better GPU then on my Laptop. Performance in KasmVNC is amazing, but there is a slight 3D Navigation issue - like my Minetest one #310, but instead of the one on Minetest, it can be mostly resolved with GameMode. But in GameMode, my cursor is locked to the center of the screen. Well not the pointer, it is moving around and can be used to click everything I want. But without seeing the cursor on the right spot, that is not much editing fun.

Describe the solution you'd like I could assume multiple solutions:

  1. Make another mode (or default behavior) which uses relative mouse movement as a default
  • with lock the pointer in browser window like game mode
  • (optional) without lock and only using absolute pointer movement when entering or exiting the browser window with the mouse pointer
    • Configurable as default with environment variable
  1. Make Gamemode use OS cursor (solves issues when having Game Menus I additionally had in Minetest)

Describe alternatives you've considered Testing around with SDL settings, xinput other tools to write a mitigation (before I saw GameMode would work... except for the pointer).

Additional context Currently trying to resolve this for now for me by editing the source manually for GameMode ...

Are there any pointers from your side maybe?

Can I force the OS pointer somehow?

hochbit avatar Jan 17 '25 08:01 hochbit

Similar issue #276

BlahajFromIkea avatar Jan 24 '25 14:01 BlahajFromIkea

@Myzomi Um not exactly. Unreal Engine 5 (Unreal Editor) "works" with Game Mode as expected. Except for the mouse pointer representation in the Browser JS Client to move where the actual mouse is on the system.


I have hacked the main script now so far that I have the mouse pointer moving. Problem is it gets out of sync when it is grabbed. I noticed that in KasmWorkspace the update mouse position function is actually called regularly.

This function:

...
{
    key: "_handleVMwareCursorPosition",
    value: function _handleVMwareCursorPosition() {
      var x = this._FBU.x;
      var y = this._FBU.y;

      if (this._pointerLock) {
        // Only attempt to match the server's pointer position if we are in
        // pointer lock mode.
        this._mousePos = {
          x: x,
          y: y
        };
      }

      return true;
    }
  },

But it actually isn't called on KasmVNC. Question @kasmtech ... can I ask the XVnc to give me the cursor position?

I tried using the xdotool to update the position on the container - then XVnc actually calls this function. But for doing that I have to set the cursor position with xdotool and that creates a fuzz when moving the cursor around -- well as far I tried.

I add the patch for the code I have so far. It would not let me upload the whole file. I used chrome developer tools to edit the code while trying around and stored the file locally - so its not the cleanest code... 😉

--- main.bundle.js	2025-01-31 12:48:16.176411000 +0100
+++ "kasm/localhost/vnc/dist/main.bundle.js"	2025-01-31 12:51:37.855617465 +0100
@@ -17494,17 +17494,8 @@
       this._pointerRelativeEnabled = value;
 
       if (value) {
-        var max_w = this._display.scale === 1 ? this._fbWidth : this._fbWidth * this._display.scale;
-        var max_h = this._display.scale === 1 ? this._fbHeight : this._fbHeight * this._display.scale;
-        this._pointerLockPos.x = Math.floor(max_w / 2);
-        this._pointerLockPos.y = Math.floor(max_h / 2); // reset the cursor position to center
-
-        this._mousePos = {
-          x: this._pointerLockPos.x,
-          y: this._pointerLockPos.y
-        };
-
-        this._cursor.move(this._pointerLockPos.x, this._pointerLockPos.y);
+        this._pointerLockPos.x = this._mousePos.x;
+        this._pointerLockPos.y = this._mousePos.y;
       }
     }
   }, {
@@ -19854,12 +19845,45 @@
         var rel_16_y = toSignedRelative16bit(y - this._pointerLockPos.y);
         RFB.messages.pointerEvent(this._sock, rel_16_x, rel_16_y, mask); // reset the cursor position to center
 
+        console.log("PURE", x, y)
+
+        console.log("SCALE", this._display.scale)
+        
+        
+		this._pointerLockPos.x += (x - this._pointerLockPos.x) * this._display.scale;
+		this._pointerLockPos.y += (y - this._pointerLockPos.y) * this._display.scale;
+
+        console.log(this._pointerLockPos);
+        if(this._pointerLockPos.x < 0) {
+          this._pointerLockPos.x = 0;
+        } 
+        if(this._pointerLockPos.y < 0) {
+          this._pointerLockPos.y = 0;
+        } 
+
+        var max_w = this._display.scale === 1 ? this._fbWidth : this._fbWidth * this._display.scale;
+        var max_h = this._display.scale === 1 ? this._fbHeight : this._fbHeight * this._display.scale;
+
+        if(this._pointerLockPos.x > max_w) {
+          this._pointerLockPos.x = max_w;
+        } 
+        if(this._pointerLockPos.y > max_h) {
+          this._pointerLockPos.y = max_h;
+        } 
+
+
+        
         this._mousePos = {
-          x: this._pointerLockPos.x,
+          x: this._pointerLockPos.x
+          ,
           y: this._pointerLockPos.y
         };
 
-        this._cursor.move(this._pointerLockPos.x, this._pointerLockPos.y);
+        this._cursor.move(
+          this._pointerLockPos.x
+          , 
+          this._pointerLockPos.y
+        );
       } else {
         RFB.messages.pointerEvent(this._sock, this._display.absX(x), this._display.absY(y), mask);
       }
@@ -21886,20 +21910,25 @@
   }, {
     key: "_handleVMwareCursorPosition",
     value: function _handleVMwareCursorPosition() {
-      var x = this._FBU.x;
-      var y = this._FBU.y;
+
 
       if (this._pointerLock) {
+        var x = this._FBU.x;
+        var y = this._FBU.y;
         // Only attempt to match the server's pointer position if we are in
         // pointer lock mode.
-        this._mousePos = {
-          x: x,
-          y: y
-        };
-      }
 
+        console.log("U", x,y);
+
+        
+        this._pointerLockPos.x = x * this._display.scale;
+        this._pointerLockPos.y = y * this._display.scale;
+
+        this._cursor.move(x, y);
+      }
+          
       return true;
-    }
+      }
   }, {
     key: "_handleCursor",
     value: function _handleCursor() {
@@ -25878,6 +25907,8 @@
       UI.sendMessage('enable_pointer_lock', true);
       UI.closeControlbar();
       UI.showStatus('Press Esc Key to Exit Pointer Lock Mode', 'warn', 5000, true);
+      this._pointerLockPos.x = this._mousePos.x;
+      this._pointerLockPos.y = this._mousePos.y;
     } else {
       //If in game mode 
       if (UI.rfb.pointerRelative) {

hochbit avatar Jan 31 '25 12:01 hochbit

This is really the same issue as #276, however, this ticket has more detail. I will keep this one open and link to to our internal ticket as well so our devs have more info.

mmcclaskey avatar May 20 '25 10:05 mmcclaskey