Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support changing the mouse pointer #37882

Merged
merged 15 commits into from Feb 25, 2024
Merged

Support changing the mouse pointer #37882

merged 15 commits into from Feb 25, 2024

Conversation

probakowski
Copy link
Contributor

@probakowski probakowski commented Feb 7, 2024

This change allows server to send mouse pointer updates to properly indicate e.g. resizing with arrows.

Closes #29964

changelog: Implemented dynamic mouse pointer updates to reflect context-specific actions, e.g. window resizing.

Copy link

github-actions bot commented Feb 7, 2024

The PR changelog entry failed validation: Changelog entry not found in the PR body. Please add a "no-changelog" label to the PR, or changelog lines starting with changelog: followed by the changelog entries for the PR.

@kimlisa kimlisa removed their request for review February 8, 2024 03:22
Copy link
Contributor

@ibeckermayer ibeckermayer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion for changelog:

Implemented dynamic mouse pointer updates to reflect context-specific actions, e.g. window resizing.

@zmb3
Copy link
Collaborator

zmb3 commented Feb 9, 2024

Are we software rendering the pointer on canvas now? I thought you mentioned that this was just using the CSS cursor property which seems like it would be more efficient.

probakowski and others added 3 commits February 10, 2024 01:00
…Canvas.tsx

Co-authored-by: Isaiah Becker-Mayer <isaiah@goteleport.com>
Co-authored-by: Isaiah Becker-Mayer <isaiah@goteleport.com>
…Canvas.tsx

Co-authored-by: Isaiah Becker-Mayer <isaiah@goteleport.com>
@probakowski
Copy link
Contributor Author

@zmb3 we do render it to temp canvas once, to convert raw pixels received from RDP to png - only format widely supported by browsers as cursor. We then set it as cursor for the canvas we render the whole desktop on.
We don't have to manually render cursor on each mouse move, only on cursor change. Could be probably improved by hashing cursor data from RDP and using it as caching key for png data we generate.

web/packages/teleport/src/ironrdp/src/lib.rs Show resolved Hide resolved
@@ -97,6 +97,47 @@ function TdpClientCanvas(props: Props) {
}
}, [client, clientOnPngFrame]);

let previousCursor = 'auto';
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you need useRef here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It won't hurt for sure, I've added it

Comment on lines 124 to 130
'url(' +
cursor.toDataURL() +
') ' +
pointer.hotspot_x +
' ' +
pointer.hotspot_y +
', auto';
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can rewrite this with string interpoloation:

canvas.style.cursor = `url('${cursor.toDataURL()') ${pointer.hotspot_x} ${pointer.hotspot_y} auto`

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, you can, changed

} ${pointer.hotspot_y}, auto`;
};

client.on(TdpClientEvent.POINTER, updatePointer);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: for consistency, I'd use client.addListenter (or client.off in line 133).

const cursor = document.createElement('canvas');
cursor.width = pointer.data.width;
cursor.height = pointer.data.height;
cursor.getContext('2d').putImageData(pointer.data, 0, 0);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This probably doesn't change much in this case, but pointer.data returns a color space that we can pass to the canvas:

        cursor
          .getContext('2d', { colorSpace: pointer.data.colorSpace })
          .putImageData(pointer.data, 0, 0);

if (client && updatePointer) {
const canvas = canvasRef.current;
const updatePointer = (pointer: {
data: ImageData | boolean;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd add a short JSDoc comment explaining that if data is boolean then true means that we want to show a cursor and false means we want to hide it.

@@ -401,6 +438,7 @@ export type Props = {
canvasOnMouseWheelScroll?: (cli: TdpClient, e: WheelEvent) => void;
canvasOnContextMenu?: () => boolean;
style?: CSSProperties;
updatePointer: boolean;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can make this property optional, you won't have to pass false to DesktopPlayer.

Suggested change
updatePointer: boolean;
updatePointer?: boolean;

@@ -184,6 +184,7 @@ impl FastPathProcessor {
cb_context: &JsValue,
draw_cb: &js_sys::Function,
respond_cb: &js_sys::Function,
update_pointer_cb: &js_sys::Function,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's document the signature of this function like we do for the others

/// `tdp_fast_path_frame: Uint8Array`
///
/// `cb_context: tdp.Client`
///
/// `draw_cb: (bitmapFrame: BitmapFrame) => void`
///
/// `respond_cb: (responseFrame: ArrayBuffer) => void`

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might also be worth documenting the meanings of the different options for the data param.

@probakowski probakowski added this pull request to the merge queue Feb 25, 2024
Merged via the queue into master with commit 4ded67e Feb 25, 2024
39 checks passed
@probakowski probakowski deleted the probakowski/pointer branch February 25, 2024 23:58
@public-teleport-github-review-bot

@probakowski See the table below for backport results.

Branch Result
branch/v15 Create PR

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

Successfully merging this pull request may close these issues.

Desktop Access: change mouse pointer when e.g. resizing a window
4 participants