Repository navigation
Conversation
Member
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
Contributor
|
🤖 Your WebAssembly Sample App stage site is ready! Visit it here: |
Contributor
|
The build 242763 found UI Test snapshots differences: Details
|
Contributor
|
|
Contributor
|
Tick the box to add this pull request to the merge queue (same as
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
GitHub Issue: closes #25873
PR Type:
🐞 Bugfix
What changed? 🚀
On Desktop (Windows), an external drag now shows the source app's own drag image over the window, as in WinUI, instead of a preview that Uno built from the dragged data.
Before. The Win32 drop target didn't use the shell's drag-image manager, so the source's drag image (Explorer's thumbnail, a browser's picture of the dragged image) disappeared over the window.
CreateDragUIForExternalDragbuilt a preview instead:BitmapImage.SetSource;That cost a second
GetDatacopy of the bitmap at everyDragEnter, and file reads or icon extraction on the UI thread.After.
CoCreateInstance(CLSID_DragDropHelper),IDropTargetHelper) atDragEnter. The manager is apartment-threaded; it's created, used and released on the UI thread, where OLE calls the drop target.DragEnter(with the window handle, the data object and the point) andDragOver, each with the effect the drop target returns;DragLeaveandDrop, first, before Uno processes them, as Chromium and WinForms do (WinForms only when the app setsDropImageType).Dropgets the effects the source allows, as in Chromium. The processing that follows can't freeze the source's image then (an asynchronous file drop can wait up to a second), and an exception in it can't keep the manager alive.DragEnterfails (DV_E_FORMATETC), but the manager still keeps a reference to the data object untilDragLeaveorDrop. So the drop target ignoresDragEnter's result and forwards the rest anyway, as Chromium and WinForms do.DragEntertoDragLeaveorDrop, as Chromium's drop target does, to enter the manager again in the middle of a drag (see below).DragLeaveorDrop, or at aDragEnterthat comes without either.CreateDragUIForExternalDragand the image, icon and PNG helpers it used are removed;NativeMethods.txtentries that only they used, andDragUI's internal external-content members along with the image sizing thatDragViewapplied to them.DragUI, as the macOS, X11 and WebAssembly hosts already do.What happens to #21759's scenario. An image file dragged from Explorer still shows a thumbnail, now Explorer's own. A source that sets no drag image (WPF and WinForms apps by default, and many classic Win32 apps) now shows only the glyph and caption. For a file drag from such a source, Uno 6.8 drew the file's icon or thumbnail; on
master, nothing showed, since the drag visual's image doesn't show there at the moment (#25869). WinUI builds no visual from the dragged data (see the issue), so it should show only the glyph and caption too; I haven't checked that in a WinUI app.DragUIOverride. WinUI only changes the drag visual when the drop target sets something throughDragUIOverride. The content it sets replaces the source's visual, andIsContentVisible = falsehides the content. Here:DragView) still draws them near the pointer, as before.SetContentFromBitmapImage, orIsContentVisible = false: the drop target forwards aDragLeaveto the manager, which removes the source's image from the window, as when the pointer leaves it.DragViewdraws the app's content, as before, or nothing but the glyph and caption. If the drop target already does this in theDragOverthat Uno raises within the window'sDragEnter, the manager isn't entered at all.DragEnteragain, with the data object, the current point and the current effect, and goes on forwardingDragOver. It uses the same manager, as when the pointer leaves the window and comes back.DragLeaveandDropare only forwarded while the manager is entered.IDropTargetHelper::Showisn't used. The docs only describe it for hiding the image while a window repaints, and it didn't hide the image in a manual test.DragEnterreturnedS_OK, and the source's image came back.Depends on #25872 (issue #25871). On
master, an override that replaces or hides the content can outlive the drop target that set it.CoreDragUIOverride.Clear()resetsIsContentVisiblebut notContent, and a drop target that the drag goes straight back to gets its saved override again, without aClear(). So without #25872:#25872 resets the override per drop target, as WinUI does.
Related: #25870 (issue #25869). On
master, the drag visual is never loaded, so content that the drop target sets withSetContentFromBitmapImage(like the sample's custom content area) doesn't show there. #25870 fixes that; it doesn't change what this PR does with the source's image.Two things are still different from WinUI:
DragEnteron it (see fix(dragdrop): Reset the drag UI override per drop target #25872's follow-up). So a drop target that sets the override inDragOvershows the source's image for one more OLE callback, with no accepted operation, before it's removed. The accepted operation has the same delay.Platforms: Desktop (Windows) only. The macOS, X11 and WebAssembly hosts pass no
DragUIeither, and all three show the source's drag image.Tests:
Given_Win32ExternalDragcalls the window's realIDropTargetthrough its COM interface, asDoDragDropdoes. It uses a shell data object (SHCreateDataObject) that offers a CF_DIB, with a drag image set throughIDragSourceHelper::InitializeFromBitmap, as a drag source sets it, or without one. On Skia Desktop (Windows), onmasterat 1f2fc30:master's Win32 hostWhen_Bitmap_Dragged_Over_Then_No_Preview_Is_GeneratedWhen_Drop_Target_Overrides_DragUI_Then_Drag_Visual_Shows_It, no content overrideDragEnterand stays enteredSetContentFromBitmapImageWin32DragDropExtension has no field _dropTargetHelper; the app's content shows)IsContentVisible = falseWhen_Content_Hidden_Then_Shown_Again_Then_Shell_Drag_Image_Manager_Is_Left_Then_Entered_Again, ended byDragLeaveand byDrop(2 rows)Win32DragDropExtension has no field _isDropTargetHelperEntered)DragOverwhere the content is hidden (and still left on the next one), entered again at the one where it's shown, then released at the end, along with the data objectWhen_External_Drag_Ends_Then_Shell_Drag_Image_Manager_And_Data_Object_Are_Released, ended byDragLeaveand byDrop, with and without a drag image (4 rows)Win32DragDropExtension has no field _dropTargetHelper)DragEnter, kept throughDragOver, released atDragLeaveorDrop, the data object's reference count is back to what it was beforeDragEnter, and the drop still reaches the drop targetThe
mastercolumn ismaster's Win32 host,DragUIandDragView, with this PR's tests and the new internalDragDropManager.IsContentReplacedOrHidden, which the tests call. These tests can't check what the shell draws, only what Uno does. I also ranGiven_Win32DragDrop,Given_DragView, and the drag-and-drop tests ofGiven_UIElement,Given_ListViewBaseandGiven_TreeView: 34 tests, the 10 new ones included, all passing, after a build with the analyzers on.Manual test: the new sample
DragDrop_ExternalDragVisual(Drag and drop) has four drop areas: default, custom caption without glyph, custom content, and hidden content. A drop lists the formats and the data.Results, on Desktop (Windows), with a build of this PR plus #25872 and #25870:
Assets/test_image_100_100.png) replaces the source's image;Backport: please consider backporting this to
servicing/6.8. A Mergify cherry-pick will conflict, but only mechanically: the three deleted files are in another folder on 6.8 (and one of them differs a little), and the new sample and test files go in other folders too. We can open the backport ourselves if you prefer. We ran the port's tests on our own 6.8-based branch. In the files this change touches, it differs fromservicing/6.8only in the asynchronous file drop code ofWin32DragDropExtension.cs(the backport in #25865), which this change doesn't touch. There,Given_ListViewBase.When_UpdateLayout_In_DragDroppingfails intermittently, with and without this change, and passes when run again; the other 33 tests pass. As onmaster, it needs #25872 there too, which asks for the same backport.PR Checklist ✅
Screenshots Compare Test Runresults.