Skip to content

Conversation

@willibrandon
Copy link
Contributor

@willibrandon willibrandon commented Nov 16, 2023

Fixes #8903

Proposed changes

  • Fix the tracking of the last drop target window in DragLeaveTarget.
  • Notify the drag-image manager during DragLeaveTarget that the cursor has left the target window only if it is in-process.
  • Check if the target window is in-process and if not, prevent the drag image from being updated during GiveFeeback.
  • Add and check for additional drag and drop data formats used to detect when the data object is in a drag loop.

Customer Impact

  • Fixes a drag image flicker and artefact that occurs when dragging and dropping cross-process.

Regression?

  • No.

Risk

Screenshots

Before

Drag-image-cross-process-before.mp4

After

Drag-image-cross-process-after.mp4

Test methodology

  • Manual

Test environment(s)

  • 9.0.100-alpha.1.23511.2
Microsoft Reviewers: Open in CodeFlow

   * Fix the tracking of the last drop target window in DragLeaveTarget.
   * Exclude the Effect property from the check for if the drag image has been updated.
   * Prevent the drag image from being updated during GiveFeedback when the image is updated from another process.
   * Only notify the drag-image manager that the cursor has left the drop target if the window is in-process.
@ghost ghost assigned willibrandon Nov 16, 2023
@willibrandon
Copy link
Contributor Author

@weltkante - Thoughts?

@ghost ghost added the draft draft PR label Nov 16, 2023
@willibrandon willibrandon marked this pull request as ready for review November 16, 2023 07:35
@willibrandon willibrandon requested a review from a team as a code owner November 16, 2023 07:35
@ghost ghost removed the draft draft PR label Nov 16, 2023
Copy link
Member

@JeremyKuhne JeremyKuhne left a comment

Choose a reason for hiding this comment

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

Added a few minor comments.

internal const string CF_DRAGSOURCEHELPERFLAGS = "DragSourceHelperFlags";
internal const string CF_DRAGWINDOW = "DragWindow";
internal const string CF_DROPDESCRIPTION = "DropDescription";
internal const string CF_INSHELLDRAGLOOP = "InShellDragLoop";
Copy link
Member

Choose a reason for hiding this comment

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

This one can come from CsWin32 with CFSTR_INDRAGLOOP.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That is cool. First time I've seen that.

internal const string CF_DRAGIMAGEBITS = "DragImageBits";
internal const string CF_DRAGSOURCEHELPERFLAGS = "DragSourceHelperFlags";
internal const string CF_DRAGWINDOW = "DragWindow";
internal const string CF_DROPDESCRIPTION = "DropDescription";
Copy link
Member

Choose a reason for hiding this comment

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

This can be replaced with CFSTR_DROPDESCRIPTION using CsWin32.

/// </summary>
internal static class DragDropHelper
{
private const int DSH_ALLOWDROPDESCRIPTIONTEXT = 0x0001;
Copy link
Member

Choose a reason for hiding this comment

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

This can come from DSH_FLAGS in CsWin32.

internal static class DragDropHelper
{
private const int DSH_ALLOWDROPDESCRIPTIONTEXT = 0x0001;
internal const string CF_COMPUTEDIMAGE = "ComputedImage";
Copy link
Member

Choose a reason for hiding this comment

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

It would be nice to document where these formats come from in the comments here.

Copy link
Contributor Author

@willibrandon willibrandon Nov 17, 2023

Choose a reason for hiding this comment

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

I believe a couple of these formats are unnecessary, but I'll document what I know about the ones that are needed.

}

private bool IsDropTargetWindowInCurrentThread() => !_lastHwndTarget.IsNull
&& PInvoke.GetWindowThreadProcessId(_lastHwndTarget, out _) == PInvoke.GetCurrentThreadId();
Copy link
Member

Choose a reason for hiding this comment

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

Maybe we should stash the window's thread to avoid the repeated call? It would also be slightly faster if you also use the unsafe overload and pass null for the process id.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good idea. Thank you for your help.

@ghost ghost added the waiting-author-feedback The team requires more information from the author label Nov 16, 2023
@weltkante
Copy link
Contributor

@weltkante - Thoughts?

from just looking at the changes it looks good to me, can't see any problems with it. won't have time to tests it myself at the moment.

@ghost ghost removed the waiting-author-feedback The team requires more information from the author label Nov 17, 2023
Copy link
Member

@lonitra lonitra left a comment

Choose a reason for hiding this comment

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

mainly some small stylistic comments, otherwise LGTM!

@lonitra lonitra added the waiting-author-feedback The team requires more information from the author label Nov 29, 2023
@ghost ghost removed the waiting-author-feedback The team requires more information from the author label Dec 1, 2023
@willibrandon willibrandon requested a review from lonitra December 1, 2023 04:45
Copy link
Member

@lonitra lonitra left a comment

Choose a reason for hiding this comment

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

🚀

@lonitra lonitra added the ready-to-merge PRs that are ready to merge but worth notifying the internal team. label Dec 1, 2023
@lonitra lonitra dismissed JeremyKuhne’s stale review December 2, 2023 04:31

Feedback addressed

@lonitra lonitra merged commit 858bddb into dotnet:main Dec 2, 2023
@ghost ghost added this to the 9.0 Preview1 milestone Dec 2, 2023
@ghost ghost removed the ready-to-merge PRs that are ready to merge but worth notifying the internal team. label Dec 2, 2023
@willibrandon willibrandon deleted the fix-cross-process-drag-image-artefact branch December 2, 2023 21:35
@github-actions github-actions bot locked and limited conversation to collaborators Jan 2, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

A drag image remnant remains when dragging between different application instances

4 participants