GSConnect / gnome-shell-extension-gsconnect

KDE Connect implementation for GNOME
GNU General Public License v2.0
3.17k stars 254 forks source link

Presentation Control on Wayland unreliable #1836

Open tedzards509 opened 3 months ago

tedzards509 commented 3 months ago

Describe the bug

On Wayland, GSConnect has to request access to perform input actions. This is accepted automatically. However, I assume that it is accepted after receiving a request, so the first request is disregarded. When using GSConnect as a presentation control, sometimes you have to press twice to get a reaction in the presentation.

I assume this also applies to remote keyboard input, but I cannot test that right now.

Steps to reproduce

  1. Start a presentation
  2. Hit next on presentation remote in KDE Connect app

Expected behavior

Presentation should go to next slide whenever the next button is hit.

GSConnect version

57

Installed from

GitHub releases (zip file)

GNOME Shell version

46

Linux distribution/release

Fedora 40

Paired device(s)

No response

KDE Connect app version

No response

Plugin(s)

No response

Support log

No response

Screenshots

No response

Notes

No response

ferdnyc commented 2 months ago

@tedzards509

On Wayland, GSConnect has to request access to perform input actions. This is accepted automatically.

It's not really as complicated as all that. We're not using the desktop portal, which would require user confirmation.

What happens when GSConnect receives a remote input request (which is used by both the presentation and remote input plugins) is:

  1. It makes a CreateSession request to org.gnome.Mutter.RemoteDesktop over dbus. Mutter replies with a dbus session bus address which the caller (GSConnect) and only the caller can use to create input events.
  2. GSConnect sends a Start request to that new session address, beginning a remote input session. That's when this icon appears in the Shell top bar, indicating the desktop is being remotely controlled: image
  3. GSConnect then sends Notify{Keyboard,Pointer}* events to the session address to create input events.

However, I assume that it is accepted after receiving a request, so the first request is disregarded. When using GSConnect as a presentation control, sometimes you have to press twice to get a reaction in the presentation.

I don't know if the first request is discarded, but it does appear that when the remote input connection has to be reset, the first input event that triggers a reconnect is lost. And the timeout for dropping the session is surprisingly short, set by GSConnect at 15 seconds.

There's no reason for it to time out that quickly, Mutter is happy to keep the remote input session open indefinitely. It's entirely GSConnect that's cutting the connection off so early.

So, as a first step towards fixing this, I propose to simply raise the timeout significantly, to something like 300 seconds. That should make this problem much less common, without keeping the remote input session alive for so long that it possibly interferes with powersave timeouts and the like.

Regarding the first input event on "wakeup" being lost, though... that's trickier.

Internally,y every input event first makes a call to _ensureAdapter(), which establishes that the remote input connection is live, or creates a new one if it is not. Then a function matching the input event type (movePointer, pressKeysym, what have you) is called on the _session object, to perform the input.

All of those session input functions use _call() to send the appropriate d-bus message to execute the input. And the first two lines of _call are this:

if (!this._started)
    return;

So, if the connection isn't up by the time _call is... well... called, the event will indeed be lost.

_ensureAdapter is supposed to prevent that, but _ensureAdapter is also an async JavaScript function, as is the session's start() function that it calls. I'm not a JS expert by any means, but my vague understanding is, that means that the new connection isn't guaranteed to have been completely established before the input functions attempt to send events over it. I suspect that may be why the "activating" event is getting lost.

But I suspect the issue is entirely within GSConnect, and probably affects X11 equally (since they both use Mutter's RemoteDesktop d-bus service).

ferdnyc commented 2 months ago

@tedzards509

If you're interested in testing a 300-second-timeout version of the remote input service, you can download a build of the extension with that fix applied here: https://github.com/GSConnect/gnome-shell-extension-gsconnect/actions/runs/10020858062/artifacts/1721913828