Skip to content

Commit 8c06cb6

Browse files
authored
Merge pull request #4871 from MicrosoftEdge/api-dragstarting-draft
Add Spec: DragStarting API
2 parents 0ba6096 + 042c2b4 commit 8c06cb6

File tree

1 file changed

+199
-0
lines changed

1 file changed

+199
-0
lines changed

specs/DragStarting.md

Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
DragStarting
2+
===
3+
4+
# Background
5+
The WebView2 team has been asked to provide a way to override the default drag
6+
drop behavior when running in visual hosting mode. This event allows you to know
7+
when a drag is initiated in WebView2 and provides the state necessary to override
8+
the default WebView2 drag operation with your own logic.
9+
10+
## Note about .NET/WinRT projection
11+
The work to project this API to .NET and WinRT are yet to be completed. Overall
12+
usage of this API is expected to be uncommon. There are no known public asks for
13+
this. Further, this API is exposed on the CompositionController which is very
14+
rarely used in .NET apps.
15+
16+
# Examples
17+
## DragStarting
18+
Users can use `add_DragStarting` on the CompositionController to add an event
19+
handler that is invoked when drag is starting. They can use the the event args
20+
to start their own drag. Notably the `Deferral` can be used to execute any async
21+
drag logic and call back into the WebView at a later time. The `Handled`
22+
property lets the WebView2 know whether to exercise its own drag logic or not.
23+
24+
## Override drag and drop
25+
```C++
26+
// Using DragStarting to simply make a synchronous DoDragDrop call instead of
27+
// having WebView2 do it.
28+
CHECK_FAILURE(m_compController5->add_DragStarting(
29+
Callback<ICoreWebView2DragStartingEventHandler>(
30+
[this](ICoreWebView2CompositionController5* sender,
31+
ICoreWebView2DragStartingEventArgs* args)
32+
{
33+
COREWEBVIEW2_DRAG_EFFECTS allowedEffects =
34+
COREWEBVIEW2_DRAG_EFFECTS_NONE;
35+
POINT dragPosition = {0, 0};
36+
wil::com_ptr<IDataObject> dragData;
37+
38+
CHECK_FAILURE(args->get_AllowedOperations(&allowedEffects));
39+
CHECK_FAILURE(args->get_Position(&dragPosition));
40+
CHECK_FAILURE(args->get_Data(&dragData));
41+
42+
if (!m_dropSource)
43+
{
44+
m_dropSource = Make<ScenarioDragDropOverrideDropSource>();
45+
}
46+
47+
DWORD effect;
48+
DWORD okEffects = DROPEFFECT_NONE;
49+
if (allowedEffects & COREWEBVIEW2_DRAG_EFFECTS_COPY)
50+
{
51+
okEffects |= DROPEFFECT_COPY;
52+
}
53+
if (allowedEffects & COREWEBVIEW2_DRAG_EFFECTS_MOVE)
54+
{
55+
okEffects |= DROPEFFECT_MOVE;
56+
}
57+
if (allowedEffects & COREWEBVIEW2_DRAG_EFFECTS_LINK)
58+
{
59+
okEffects |= DROPEFFECT_LINK;
60+
}
61+
62+
HRESULT hr = DoDragDrop(
63+
dragData.get(), m_dropSource.get(), okEffects, &effect);
64+
65+
args->put_Handled(SUCCEEDED(hr));
66+
67+
return hr;
68+
})
69+
.Get(),
70+
&m_dragStartingToken));
71+
```
72+
73+
## Disable drag and drop
74+
```C++
75+
// Using DragStarting to no-op a drag operation.
76+
CHECK_FAILURE(m_compController5->add_DragStarting(
77+
Callback<ICoreWebView2DragStartingEventHandler>(
78+
[this](ICoreWebView2CompositionController5* sender,
79+
ICoreWebView2DragStartingEventArgs* args)
80+
{
81+
// If the event is marked handled, WebView2 will not execute its
82+
// drag logic.
83+
args->put_Handled(TRUE);
84+
return S_OK;
85+
})
86+
.Get(),
87+
&m_dragStartingToken));
88+
```
89+
90+
# API Details
91+
```C++
92+
/// Flags enum that represents the effects that a given WebView2 drag drop
93+
/// operation can have. The values of this enum align with the ole DROPEFFECT
94+
/// constant with the exception of DROPEFFECT_SCROLL which is only relevant for
95+
/// drop and therefore unsupported.
96+
[v1_enum]
97+
typedef enum COREWEBVIEW2_DRAG_EFFECTS {
98+
/// Drag operation supports no effect.
99+
COREWEBVIEW2_DRAG_EFFECTS_NONE = 0x0,
100+
/// Drag operation supports copying data.
101+
COREWEBVIEW2_DRAG_EFFECTS_COPY = 0x1,
102+
/// Drag operation supports moving data.
103+
COREWEBVIEW2_DRAG_EFFECTS_MOVE = 0x2,
104+
/// Drag operation supports linking data.
105+
COREWEBVIEW2_DRAG_EFFECTS_LINK = 0x4,
106+
} COREWEBVIEW2_DRAG_EFFECTS;
107+
cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(COREWEBVIEW2_DRAG_EFFECTS)")
108+
109+
/// Event args for the `DragStarting` event.
110+
[uuid(edb6b243-334f-59d0-b3b3-de87dd401adc), object, pointer_default(unique)]
111+
interface ICoreWebView2DragStartingEventArgs : IUnknown {
112+
/// The operations this drag data supports.
113+
[propget] HRESULT AllowedOperations(
114+
[out, retval] COREWEBVIEW2_DRAG_EFFECTS* value);
115+
116+
117+
/// The data being dragged.
118+
[propget] HRESULT Data([out, retval] IDataObject** value);
119+
120+
/// The position at which drag was detected. This position is given in
121+
/// screen pixel coordinates as opposed to WebView2 relative coordinates.
122+
[propget] HRESULT Position([out, retval] POINT* value);
123+
124+
125+
/// Gets the `Handled` property.
126+
[propget] HRESULT Handled([out, retval] BOOL* value);
127+
128+
129+
/// Indicates whether this event has been handled by the app. If the
130+
/// app handles this event, WebView2 will not initiate drag drop. If
131+
/// the app does not handle the event, WebView2 will initiate its own
132+
/// drag drop logic. The default value is FALSE.
133+
[propput] HRESULT Handled([in] BOOL value);
134+
135+
136+
137+
/// Returns an `ICoreWebView2Deferral` object. Use this operation to complete
138+
/// the CoreWebView2DragStartingEventArgs.
139+
///
140+
/// Until the deferral is completed, subsequent attempts to initiate drag
141+
/// in the WebView2 will fail and if the cursor was changed as part of
142+
/// drag it will not restore.
143+
HRESULT GetDeferral(
144+
[out, retval] ICoreWebView2Deferral** value);
145+
146+
147+
}
148+
149+
/// Receives `DragStarting` events.
150+
[uuid(3b149321-83c3-5d1f-b03f-a42899bc1c15), object, pointer_default(unique)]
151+
interface ICoreWebView2DragStartingEventHandler : IUnknown {
152+
/// Provides the event args for the corresponding event.
153+
HRESULT Invoke(
154+
[in] ICoreWebView2CompositionController5* sender,
155+
[in] ICoreWebView2DragStartingEventArgs* args);
156+
}
157+
158+
/// A continuation of the ICoreWebView2CompositionController4 interface.
159+
/// This interface includes an API which exposes the DragStarting event.
160+
[uuid(975d6824-6a02-5e98-ab7c-e4679d5357f4), object, pointer_default(unique)]
161+
interface ICoreWebView2CompositionController5 : IUnknown {
162+
/// Adds an event handler for the `DragStarting` event. `DragStarting` is
163+
/// raised when the WebView2 detects a drag started within the WebView2.
164+
/// WebView2's default drag behavior is to synchronously call DoDragDrop when
165+
/// it detects drag. This event's args expose the data WebView2 uses to call
166+
/// DoDragDrop to allow users to implement their own drag logic and override
167+
/// WebView2's.
168+
HRESULT add_DragStarting(
169+
[in] ICoreWebView2DragStartingEventHandler* eventHandler,
170+
[out] EventRegistrationToken* token);
171+
172+
/// Removes an event handler previously added with `add_DragStarting`.
173+
HRESULT remove_DragStarting(
174+
[in] EventRegistrationToken token);
175+
176+
177+
}
178+
179+
/// Interop interface for the CoreWebView2CompositionController WinRT object to
180+
/// allow WinRT end developers to be able to access the COM interface arguments.
181+
/// This interface is implemented by the
182+
/// Microsoft.Web.WebView2.Core.CoreWebView2CompositionController runtime class.
183+
[uuid(7a4daef9-1701-463f-992d-2136460cf76e), object, pointer_default(unique)]
184+
interface ICoreWebView2StagingCompositionControllerInterop : IUnknown {
185+
/// Adds an event handler for the `DragStarting` event. `DragStarting` is
186+
/// raised when the WebView2 detects a drag started within the WebView2.
187+
/// This event can be used to override WebView2's default drag starting
188+
/// logic.
189+
HRESULT add_DragStarting(
190+
[in] ICoreWebView2StagingDragStartingEventHandler* eventHandler,
191+
[out] EventRegistrationToken* token);
192+
193+
/// Removes an event handler previously added with `add_DragStarting`.
194+
HRESULT remove_DragStarting(
195+
[in] EventRegistrationToken token);
196+
197+
198+
}
199+
```

0 commit comments

Comments
 (0)