neko icon indicating copy to clipboard operation
neko copied to clipboard

Implicit control multiple modes

Open gbrian opened this issue 2 years ago • 2 comments

When enabling "implicit control" mouse events are mixed on remote causing other members mouse events interfeer with current user action (like drag, hightlight,...)

What if we move to a click and control mode? In this way user must "click" first to take control. Working on a demo

gbrian avatar Mar 28 '22 05:03 gbrian

We could have multiple modes of NEKO_IMPLICIT_CONTROL:

  • disabled (default)
  • on_move (as today)
  • on_click

And current implementation should deny control takeover when dragging something, or maybe actively moving or when typing.

m1k1o avatar Mar 28 '22 17:03 m1k1o

Back to this topic as is a bit annoying, sharing a basic approach to keep the beauty of multi-control but avoiding the mess when dragging on pointing on the screen when other is on control.

Add hasControl to SessionManager so we know which host's events reac to

type SessionManager struct {
	mu            sync.Mutex
	logger        zerolog.Logger
	host          string
	capture       types.CaptureManager
	members       map[string]*Session
	eventsChannel chan types.SessionEvent
	// TODO: Handle locks in sessions as flags.
	controlLocked bool
	// host having control when IMPLICIT_CONTROL is active
	hasControl    string
}

Later check hasControl to ignore events coming from user not having control and switch control on click event.

func (manager *WebRTCManager) handle(id string, msg webrtc.DataChannelMessage) error {
	isHost := manager.sessions.IsHost(id)
	if (!manager.config.ImplicitControl && !isHost) || (manager.config.ImplicitControl && !manager.sessions.CanControl(id)) {
		return nil
	}
        ... 
        buffer = bytes.NewBuffer(msg.Data)

	hasControl := manager.sessions.IsHasControl(id)
	if (!hasControl && handler.Event != OP_KEY_DOWN) {
		// Ignore event as user don't have control and is not a "possible" click
		return nil
	}
        ....
        if payload.Key < 8 {
			err := manager.desktop.ButtonDown(uint32(payload.Key))
			if err != nil {
				manager.logger.Warn().Err(err).Msg("button down failed")
				return nil
			}

			manager.logger.Debug().Msgf("button down %d", payload.Key)

			if (!isHost) {
				// Switch control
				manager.SetHasControl(id)
			}
		} else if (hasControl) {
			err := manager.desktop.KeyDown(uint32(payload.Key))
         ....

I think in this way you must "click" to take control. Comments?

gbrian avatar Jul 17 '23 17:07 gbrian