Show a 'grab' cursor on picture-in-picture view (#33079)

* Remove unused 'draggable' prop from PictureInPictureDragger

* Show a 'grab' cursor on picture-in-picture view

To give it a proper affordance for dragging.
This commit is contained in:
Robin 2026-04-09 14:25:14 +02:00 committed by GitHub
parent 70e40009a3
commit 253dcb44dd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 32 additions and 51 deletions

View File

@ -70,6 +70,7 @@
@import "./structures/_MatrixChat.pcss";
@import "./structures/_MessagePanel.pcss";
@import "./structures/_NonUrgentToastContainer.pcss";
@import "./structures/_PictureInPictureDragger.pcss";
@import "./structures/_QuickSettingsButton.pcss";
@import "./structures/_RightPanel.pcss";
@import "./structures/_RoomSearch.pcss";
@ -375,7 +376,6 @@
@import "./views/voip/_DialPad.pcss";
@import "./views/voip/_DialPadContextMenu.pcss";
@import "./views/voip/_DialPadModal.pcss";
@import "./views/voip/_LegacyCallPreview.pcss";
@import "./views/voip/_LegacyCallView.pcss";
@import "./views/voip/_LegacyCallViewForRoom.pcss";
@import "./views/voip/_LegacyCallViewHeader.pcss";

View File

@ -0,0 +1,20 @@
/*
Copyright 2026 Element Creations Ltd.
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
Please see LICENSE files in the repository root for full details.
*/
.mx_PictureInPictureDragger {
cursor: grab;
user-select: none;
left: 0;
position: fixed;
top: 0;
/* Display above any widget elements */
z-index: 102;
}
.mx_PictureInPictureDragger:active {
cursor: grabbing;
}

View File

@ -1,28 +0,0 @@
/*
Copyright 2024 New Vector Ltd.
Copyright 2021 Šimon Brandner <simon.bra.ag@gmail.com>
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
Please see LICENSE files in the repository root for full details.
*/
.mx_LegacyCallPreview {
align-items: flex-end;
display: flex;
flex-direction: column;
gap: $spacing-16;
left: 0;
position: fixed;
top: 0;
/* Display above any widget elements */
z-index: 102;
.mx_VideoFeed_remote.mx_VideoFeed_voice {
min-height: 150px;
}
.mx_VideoFeed_local {
border-radius: 8px;
overflow: hidden;
}
}

View File

@ -37,9 +37,7 @@ interface IChildrenOptions {
}
interface IProps {
className?: string;
children: Array<CreatePipChildren>;
draggable: boolean;
onDoubleClick?: () => void;
onMove?: () => void;
}
@ -181,9 +179,6 @@ export default class PictureInPictureDragger extends React.Component<IProps> {
};
private onStartMoving = (event: React.MouseEvent | MouseEvent): void => {
event.preventDefault();
event.stopPropagation();
this.mouseHeld = true;
this.startingPositionX = event.clientX;
this.startingPositionY = event.clientY;
@ -217,9 +212,6 @@ export default class PictureInPictureDragger extends React.Component<IProps> {
private onEndMoving = (event: MouseEvent): void => {
if (!this.mouseHeld) return;
event.preventDefault();
event.stopPropagation();
this.mouseHeld = false;
// Delaying this to the next event loop tick is necessary for click
// event cancellation to work
@ -250,7 +242,7 @@ export default class PictureInPictureDragger extends React.Component<IProps> {
return (
<aside
className={this.props.className}
className="mx_PictureInPictureDragger"
style={style}
ref={this.callViewWrapper}
onClickCapture={this.onClickCapture}

View File

@ -266,12 +266,7 @@ class PipContainerInner extends React.Component<IProps, IState> {
if (pipContent.length) {
return (
<PictureInPictureDragger
className="mx_LegacyCallPreview"
draggable={pipMode}
onDoubleClick={this.onDoubleClick}
onMove={this.onMove}
>
<PictureInPictureDragger onDoubleClick={this.onDoubleClick} onMove={this.onMove}>
{pipContent}
</PictureInPictureDragger>
);

View File

@ -36,7 +36,7 @@ describe("PictureInPictureDragger", () => {
describe("when rendering the dragger with PiP content 1", () => {
beforeEach(() => {
renderResult = render(<PictureInPictureDragger draggable={true}>{mkContent1}</PictureInPictureDragger>);
renderResult = render(<PictureInPictureDragger>{mkContent1}</PictureInPictureDragger>);
});
it("should render the PiP content", () => {
@ -45,7 +45,7 @@ describe("PictureInPictureDragger", () => {
describe("and rerendering PiP content 1", () => {
beforeEach(() => {
renderResult.rerender(<PictureInPictureDragger draggable={true}>{mkContent1}</PictureInPictureDragger>);
renderResult.rerender(<PictureInPictureDragger>{mkContent1}</PictureInPictureDragger>);
});
it("should not change the PiP content", () => {
@ -55,7 +55,7 @@ describe("PictureInPictureDragger", () => {
describe("and rendering PiP content 2", () => {
beforeEach(() => {
renderResult.rerender(<PictureInPictureDragger draggable={true}>{mkContent2}</PictureInPictureDragger>);
renderResult.rerender(<PictureInPictureDragger>{mkContent2}</PictureInPictureDragger>);
});
it("should update the PiP content", () => {
@ -66,9 +66,7 @@ describe("PictureInPictureDragger", () => {
describe("when rendering the dragger with PiP content 1 and 2", () => {
beforeEach(() => {
renderResult = render(
<PictureInPictureDragger draggable={true}>{[...mkContent1, ...mkContent2]}</PictureInPictureDragger>,
);
renderResult = render(<PictureInPictureDragger>{[...mkContent1, ...mkContent2]}</PictureInPictureDragger>);
});
it("should render both contents", () => {
@ -83,7 +81,7 @@ describe("PictureInPictureDragger", () => {
beforeEach(() => {
clickSpy = jest.fn();
render(
<PictureInPictureDragger draggable={true}>
<PictureInPictureDragger>
{[
({ onStartMoving }) => (
// eslint-disable-next-line jsx-a11y/click-events-have-key-events

View File

@ -3,6 +3,7 @@
exports[`PictureInPictureDragger when rendering the dragger with PiP content 1 and 2 should render both contents 1`] = `
<div>
<aside
class="mx_PictureInPictureDragger"
style="transform: translateX(672px) translateY(80px);"
>
<div>
@ -20,6 +21,7 @@ exports[`PictureInPictureDragger when rendering the dragger with PiP content 1 a
exports[`PictureInPictureDragger when rendering the dragger with PiP content 1 and rendering PiP content 2 should update the PiP content 1`] = `
<div>
<aside
class="mx_PictureInPictureDragger"
style="transform: translateX(672px) translateY(80px);"
>
<div>
@ -34,6 +36,7 @@ exports[`PictureInPictureDragger when rendering the dragger with PiP content 1 a
exports[`PictureInPictureDragger when rendering the dragger with PiP content 1 and rerendering PiP content 1 should not change the PiP content: pip-content-1 1`] = `
<div>
<aside
class="mx_PictureInPictureDragger"
style="transform: translateX(672px) translateY(80px);"
>
<div>
@ -46,6 +49,7 @@ exports[`PictureInPictureDragger when rendering the dragger with PiP content 1 a
exports[`PictureInPictureDragger when rendering the dragger with PiP content 1 should render the PiP content: pip-content-1 1`] = `
<div>
<aside
class="mx_PictureInPictureDragger"
style="transform: translateX(672px) translateY(80px);"
>
<div>