Skip to content

feat(client): add --prevent-session-lock CLI option#1207

Open
Mariusz Białończyk (manio) wants to merge 4 commits intoDevolutions:masterfrom
manio:prevent-session-lock
Open

feat(client): add --prevent-session-lock CLI option#1207
Mariusz Białończyk (manio) wants to merge 4 commits intoDevolutions:masterfrom
manio:prevent-session-lock

Conversation

@manio
Copy link
Copy Markdown
Contributor

Adds a new CLI flag to prevent remote session locking by injecting fake mouse movement events when the connection is idle, similarly to FreeRDP's equivalent option.

--
Hi,
another important piece of the puzzle when moving away from FreeRDP: the --prevent-session-lock option I was missing.
FreeRDP PR:
FreeRDP/FreeRDP#9482

Adds a new CLI flag to prevent remote session locking by injecting
fake mouse movement events when the connection is idle, similarly
to FreeRDP's equivalent option.
@glamberson
Copy link
Copy Markdown
Contributor

Useful feature. A couple of architectural thoughts though.

IronRDP and FreeRDP are fundamentally different in design. FreeRDP is a monolithic C application where client behaviors are woven into the protocol core. IronRDP is a modular library that provides clean protocol building blocks for any client to compose as it sees fit. This is one of IronRDP's real strengths, and it's worth being deliberate about preserving it. Not every feature that lives in FreeRDP's core should live in IronRDP's library layer, even when the end-user functionality is the same.

I think this is one of those cases. Database in ironrdp-input is currently a pure stateful encoder: it tracks input state and produces PDUs, with no application-level concerns at all. Adding force_sending_same_position would be the first client-specific behavior to leak into it, and once that door opens it's hard to close.

The keepalive is really a synthetic packet rather than real user input, so the client can own it entirely. ironrdp-client already has access to the input channel, so it could construct the MouseEvent PDU directly (with PointerFlags::MOVE and the current position) and send it as a FastPathInputEvent, bypassing Database::apply() altogether. That way the timer, the interval config, and the synthetic event construction all live together at the application layer where they belong, and ironrdp-input stays focused on what it does well.

One other thing: with the default ControlFlow::Wait, about_to_wait won't fire again when the session is truly idle since nothing is waking the event loop. You'd likely need a ControlFlow::WaitUntil(next_keepalive_deadline) to make sure the timer actually triggers during the idle periods where it matters most.

That's my to cents' worth anyway...

@manio
Copy link
Copy Markdown
Contributor Author

Useful feature. A couple of architectural thoughts though.

Thanks for review

IronRDP and FreeRDP are fundamentally different in design. FreeRDP is a monolithic C application where client behaviors are woven into the protocol core. IronRDP is a modular library that provides clean protocol building blocks for any client to compose as it sees fit. This is one of IronRDP's real strengths, and it's worth being deliberate about preserving it. Not every feature that lives in FreeRDP's core should live in IronRDP's library layer, even when the end-user functionality is the same.

Yes I am aware, it's one of the reason I want to migrate :)

I think this is one of those cases. Database in ironrdp-input is currently a pure stateful encoder: it tracks input state and produces PDUs, with no application-level concerns at all. Adding force_sending_same_position would be the first client-specific behavior to leak into it, and once that door opens it's hard to close.

The keepalive is really a synthetic packet rather than real user input, so the client can own it entirely. ironrdp-client already has access to the input channel, so it could construct the MouseEvent PDU directly (with PointerFlags::MOVE and the current position) and send it as a FastPathInputEvent, bypassing Database::apply() altogether. That way the timer, the interval config, and the synthetic event construction all live together at the application layer where they belong, and ironrdp-input stays focused on what it does well.

I see... I followed this method and now testing it...

One other thing: with the default ControlFlow::Wait, about_to_wait won't fire again when the session is truly idle since nothing is waking the event loop. You'd likely need a ControlFlow::WaitUntil(next_keepalive_deadline) to make sure the timer actually triggers during the idle periods where it matters most.

In my case when the window is hidden (not a foreground) the about_to_wait() is called in exactly one minute intervals, that's also why I did the CLI setting defined in minutes...

@glamberson
Copy link
Copy Markdown
Contributor

Great changes, thanks for reworking this per my suggestions. The keepalive PDU construction sitting entirely in the client layer is exactly the right separation.

Small thing on CI: the failure is clippy::as_conversions at config.rs:464. IronRDP denies bare as casts. u64::from(v) instead of v as u64 should clear it.

Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants