CmdPal: Add drag & drop support (#44165)

## Summary of the Pull Request

This PR adds basic drag-and-drop support for items in list and grid
views.

It introduces two new properties on `ListItem`, backed by
`IExtendedAttributesProvider`: `DataPackage` and `DataPackageView`.
These properties are mutually exclusive.
`DataPackage` serves as a convenience property allowing the item to
retain the underlying object without risk of losing it. Across the
extension boundary, only the immutable `DataPackageView` snapshot is
transferred. When `DataPackage` is set, `DataPackageView` is derived
from it.

This PR includes initial concrete drag-and-drop implementations for:
- File Indexer  
- Clipboard History  

**Todo / Missing pieces** 
- [x] Extend `DataPackage` support to top-level command items, enabling
scenarios such as index fallback ~
- [x] Provide automatic drag-and-drop for unconfigured list items (e.g.,
copying title and subtitle as text)
- [x] Keep CmdPal open
- [ ] ~Clipboard commands (since we have the DataPackage...)~
- [ ] ~Improve logging~

## Pictures? Moving ones!


https://github.com/user-attachments/assets/13eb9a71-e760-43ea-8c2d-cd41cf377905




<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist

- [x] Closes: #38289 
<!-- - [ ] Closes: #yyy (add separate lines for additional resolved
issues) -->
- [ ] **Communication:** I've discussed this with core contributors
already. If the work hasn't been agreed, this work might be rejected
- [ ] **Tests:** Added/updated and all pass
- [ ] **Localization:** All end-user-facing strings can be localized
- [ ] **Dev docs:** Added/updated
- [ ] **New binaries:** Added on the required places
- [ ] [JSON for
signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json)
for new binaries
- [ ] [WXS for
installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs)
for new binaries and localization folder
- [ ] [YML for CI
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml)
for new test projects
- [ ] [YML for signed
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml)
- [ ] **Documentation updated:** If checked, please file a pull request
on [our docs
repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys)
and link it here: #xxx

<!-- Provide a more detailed description of the PR, other things fixed,
or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments

<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
This commit is contained in:
Jiří Polášek
2025-12-11 15:05:48 +01:00
committed by GitHub
parent 4de4d5f310
commit 73786cd2be
19 changed files with 611 additions and 11 deletions

View File

@@ -2,14 +2,23 @@
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Windows.ApplicationModel.DataTransfer;
using Windows.Foundation.Collections;
using WinRT;
namespace Microsoft.CommandPalette.Extensions.Toolkit;
public partial class CommandItem : BaseObservable, ICommandItem
public partial class CommandItem : BaseObservable, ICommandItem, IExtendedAttributesProvider
{
private readonly PropertySet _extendedAttributes = new();
private ICommand? _command;
private WeakEventListener<CommandItem, object, IPropChangedEventArgs>? _commandListener;
private string _title = string.Empty;
private DataPackage? _dataPackage;
private DataPackageView? _dataPackageView;
public virtual IIconInfo? Icon
{
get => field;
@@ -91,6 +100,32 @@ public partial class CommandItem : BaseObservable, ICommandItem
= [];
public DataPackage? DataPackage
{
get => _dataPackage;
set
{
_dataPackage = value;
_dataPackageView = null;
_extendedAttributes[WellKnownExtensionAttributes.DataPackage] = value?.AsAgile().Get()?.GetView()!;
OnPropertyChanged(nameof(DataPackage));
OnPropertyChanged(nameof(DataPackageView));
}
}
public DataPackageView? DataPackageView
{
get => _dataPackageView;
set
{
_dataPackage = null;
_dataPackageView = value;
_extendedAttributes[WellKnownExtensionAttributes.DataPackage] = value?.AsAgile().Get()!;
OnPropertyChanged(nameof(DataPackage));
OnPropertyChanged(nameof(DataPackageView));
}
}
public CommandItem()
: this(new NoOpCommand())
{
@@ -132,4 +167,9 @@ public partial class CommandItem : BaseObservable, ICommandItem
Title = title;
Subtitle = subtitle;
}
public IDictionary<string, object> GetProperties()
{
return _extendedAttributes;
}
}

View File

@@ -27,6 +27,6 @@ public partial class FontIconData : IconData, IExtendedAttributesProvider
public IDictionary<string, object>? GetProperties() => new ValueSet()
{
{ "FontFamily", FontFamily },
{ WellKnownExtensionAttributes.FontFamily, FontFamily },
};
}

View File

@@ -0,0 +1,12 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace Microsoft.CommandPalette.Extensions.Toolkit;
public static class WellKnownExtensionAttributes
{
public const string DataPackage = "Microsoft.CommandPalette.DataPackage";
public const string FontFamily = "FontFamily";
}