Skip to content

Support changing the mouse pointer#37882

Merged
probakowski merged 15 commits intomasterfrom
probakowski/pointer
Feb 25, 2024
Merged

Support changing the mouse pointer#37882
probakowski merged 15 commits intomasterfrom
probakowski/pointer

Conversation

@probakowski
Copy link
Copy Markdown
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.

@github-actions
Copy link
Copy Markdown
Contributor

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
Copy Markdown
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.

Comment thread web/packages/teleport/src/components/TdpClientCanvas/TdpClientCanvas.tsx Outdated
Comment thread web/packages/teleport/src/ironrdp/src/lib.rs
Comment thread web/packages/teleport/src/lib/tdp/client.ts Outdated
Comment thread web/packages/teleport/src/components/TdpClientCanvas/TdpClientCanvas.tsx Outdated
@zmb3
Copy link
Copy Markdown
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
Copy Markdown
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.

Comment thread web/packages/teleport/src/ironrdp/src/lib.rs
}
}, [client, clientOnPngFrame]);

let previousCursor = 'auto';
Copy link
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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

@probakowski probakowski requested a review from zmb3 February 21, 2024 19:55
} ${pointer.hotspot_y}, auto`;
};

client.on(TdpClientEvent.POINTER, updatePointer);
Copy link
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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.

canvasOnMouseWheelScroll?: (cli: TdpClient, e: WheelEvent) => void;
canvasOnContextMenu?: () => boolean;
style?: CSSProperties;
updatePointer: boolean;
Copy link
Copy Markdown
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;

cb_context: &JsValue,
draw_cb: &js_sys::Function,
respond_cb: &js_sys::Function,
update_pointer_cb: &js_sys::Function,
Copy link
Copy Markdown
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
Copy Markdown
Contributor

@ibeckermayer ibeckermayer Feb 25, 2024

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
@probakowski probakowski deleted the probakowski/pointer branch February 25, 2024 23:58
@public-teleport-github-review-bot
Copy link
Copy Markdown

@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