Bug 212605 - Use OptionSet<DragOperation> for mask values
Summary: Use OptionSet<DragOperation> for mask values
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: WebKit2 (show other bugs)
Version: Other
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: David Kilzer (:ddkilzer)
URL:
Keywords: InRadar
Depends on:
Blocks: 211988 212870
  Show dependency treegraph
 
Reported: 2020-06-01 13:11 PDT by David Kilzer (:ddkilzer)
Modified: 2020-06-07 13:02 PDT (History)
13 users (show)

See Also:


Attachments
Patch v1 (82.01 KB, patch)
2020-06-01 22:09 PDT, David Kilzer (:ddkilzer)
no flags Details | Formatted Diff | Diff
Patch v2 (82.58 KB, patch)
2020-06-01 22:18 PDT, David Kilzer (:ddkilzer)
no flags Details | Formatted Diff | Diff
Patch v3 (87.20 KB, patch)
2020-06-02 10:03 PDT, David Kilzer (:ddkilzer)
no flags Details | Formatted Diff | Diff
Patch v4 (115.88 KB, patch)
2020-06-02 21:39 PDT, David Kilzer (:ddkilzer)
no flags Details | Formatted Diff | Diff
Patch v5 (115.83 KB, patch)
2020-06-02 22:14 PDT, David Kilzer (:ddkilzer)
no flags Details | Formatted Diff | Diff
Patch v6 (118.80 KB, patch)
2020-06-03 11:56 PDT, David Kilzer (:ddkilzer)
no flags Details | Formatted Diff | Diff
Patch v7 (119.77 KB, patch)
2020-06-03 12:18 PDT, David Kilzer (:ddkilzer)
no flags Details | Formatted Diff | Diff
Patch v8 (120.42 KB, patch)
2020-06-03 14:38 PDT, David Kilzer (:ddkilzer)
no flags Details | Formatted Diff | Diff
Patch v9 (123.83 KB, patch)
2020-06-03 15:30 PDT, David Kilzer (:ddkilzer)
no flags Details | Formatted Diff | Diff
Patch v10 (123.84 KB, patch)
2020-06-03 16:03 PDT, David Kilzer (:ddkilzer)
no flags Details | Formatted Diff | Diff
Patch v11 (136.15 KB, patch)
2020-06-03 22:17 PDT, David Kilzer (:ddkilzer)
no flags Details | Formatted Diff | Diff
Patch v12 (136.16 KB, patch)
2020-06-03 22:23 PDT, David Kilzer (:ddkilzer)
no flags Details | Formatted Diff | Diff
Patch v13 (136.16 KB, patch)
2020-06-04 10:15 PDT, David Kilzer (:ddkilzer)
darin: review+
Details | Formatted Diff | Diff
Patch for landing (134.71 KB, patch)
2020-06-05 17:38 PDT, David Kilzer (:ddkilzer)
no flags Details | Formatted Diff | Diff
Patch for landing v2 (134.92 KB, patch)
2020-06-05 18:42 PDT, David Kilzer (:ddkilzer)
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description David Kilzer (:ddkilzer) 2020-06-01 13:11:22 PDT
Use OptionSet<DragOperation> for mask values.
Comment 1 David Kilzer (:ddkilzer) 2020-06-01 22:09:15 PDT
Created attachment 400783 [details]
Patch v1

Let EWS chew on the patch as there will probably be Win/WPE/GTK build failures and maybe some test failures.
Comment 2 David Kilzer (:ddkilzer) 2020-06-01 22:18:01 PDT
Created attachment 400784 [details]
Patch v2

More EWS testing.  Corrected dumb mistakes for GTK and Win/WinCairo.
Comment 3 Darin Adler 2020-06-02 09:14:57 PDT
Comment on attachment 400784 [details]
Patch v2

View in context: https://bugs.webkit.org/attachment.cgi?id=400784&action=review

> Source/WebCore/page/DragActions.h:64
>  typedef enum {

Can we make this an enum class?

> Source/WebCore/page/DragActions.h:65
>      DragOperationNone    = 0,

Should remove this.
Comment 4 David Kilzer (:ddkilzer) 2020-06-02 10:03:06 PDT
Created attachment 400833 [details]
Patch v3

Try to fix GTk/Win/WinCairo build failures.

May still need to fix failing layout test for mac-wk1 and mac-debug-wk1.
Comment 5 Darin Adler 2020-06-02 10:07:19 PDT
Comment on attachment 400833 [details]
Patch v3

View in context: https://bugs.webkit.org/attachment.cgi?id=400833&action=review

> Source/WebCore/dom/DataTransfer.cpp:603
> +        return { DragOperationNone };

This should just be:

    return { };

We don’t want a set with the value "0", we want a set with no values.

> Source/WebCore/page/DragController.cpp:696
> +static DragOperation defaultOperationForDrag(OptionSet<DragOperation> sourceOperationMask)

This should return Optional<DragOperation>, since it can return "no operation at all".

> Source/WebCore/page/EventHandler.h:166
> +        Optional<OptionSet<DragOperation>> operationMask;

Why does this need to be optional? How is nullopt different from an empty set here?
Comment 6 David Kilzer (:ddkilzer) 2020-06-02 11:47:01 PDT
Comment on attachment 400833 [details]
Patch v3

View in context: https://bugs.webkit.org/attachment.cgi?id=400833&action=review

>> Source/WebCore/dom/DataTransfer.cpp:603
>> +        return { DragOperationNone };
> 
> This should just be:
> 
>     return { };
> 
> We don’t want a set with the value "0", we want a set with no values.

I'll change this, but there's no material difference when the OptionSet<DragOperation> is created.

>> Source/WebCore/page/DragController.cpp:696
>> +static DragOperation defaultOperationForDrag(OptionSet<DragOperation> sourceOperationMask)
> 
> This should return Optional<DragOperation>, since it can return "no operation at all".

This seems like more complexity for little value since DragOperationNone is equivalent to an empty Optional<DragOperation>.

Is the goal here to remove all uses of DragOperationNone so it can be removed?  That seems to be the only reason to do this.

>> Source/WebCore/page/EventHandler.h:166
>> +        Optional<OptionSet<DragOperation>> operationMask;
> 
> Why does this need to be optional? How is nullopt different from an empty set here?

I was making a mechanical change here to use OptionSet<DragOperation> in place of just DragOperation>.

I will change it from Optional<OptionSet<DragOperation>> to OptionSet<DragOperation> since nullopt doesn't seem different from the empty set.
Comment 7 Darin Adler 2020-06-02 11:59:26 PDT
Comment on attachment 400833 [details]
Patch v3

View in context: https://bugs.webkit.org/attachment.cgi?id=400833&action=review

>>> Source/WebCore/page/DragController.cpp:696
>>> +static DragOperation defaultOperationForDrag(OptionSet<DragOperation> sourceOperationMask)
>> 
>> This should return Optional<DragOperation>, since it can return "no operation at all".
> 
> This seems like more complexity for little value since DragOperationNone is equivalent to an empty Optional<DragOperation>.
> 
> Is the goal here to remove all uses of DragOperationNone so it can be removed?  That seems to be the only reason to do this.

Yes, enumerations used with OptionSet should not have 0 values.
Comment 8 David Kilzer (:ddkilzer) 2020-06-02 12:20:22 PDT
Comment on attachment 400833 [details]
Patch v3

View in context: https://bugs.webkit.org/attachment.cgi?id=400833&action=review

>>> Source/WebCore/page/EventHandler.h:166
>>> +        Optional<OptionSet<DragOperation>> operationMask;
>> 
>> Why does this need to be optional? How is nullopt different from an empty set here?
> 
> I was making a mechanical change here to use OptionSet<DragOperation> in place of just DragOperation>.
> 
> I will change it from Optional<OptionSet<DragOperation>> to OptionSet<DragOperation> since nullopt doesn't seem different from the empty set.

Actually, nullopt may be significant.  Need to study the code a bit more.  (I"d prefer not to change the behavior in this patch, though.)
Comment 9 David Kilzer (:ddkilzer) 2020-06-02 21:39:53 PDT
Created attachment 400892 [details]
Patch v4

Patch v4 addresses Darin's comment about defaultOperationForDrag() returning Optional<DragOperation>.  Pulling that thread (and then removing all uses of DragOperationNone basically converted every DragOperation return type into Optional<DragOperation> to replace the ability to use DragOperationNone.

I haven't addressed the issue of Optional<OptionSet<DragOperation>> as the above was more than enough to work through today.

This patch builds with macOS Debug.  I expect build failures for other platforms as I made a lot of changes to get rid of DragOperationNone.  (ChangeLogs are not up-to-date, so please ignore them.)
Comment 10 David Kilzer (:ddkilzer) 2020-06-02 21:48:45 PDT
Comment on attachment 400892 [details]
Patch v4

Need to rebase the patch after Wenson's changes to DragController that he warned me about on Slack.  :)
Comment 11 David Kilzer (:ddkilzer) 2020-06-02 22:14:52 PDT
Created attachment 400897 [details]
Patch v5

Same as Patch v4 but rebased past DragController.{cpp,h} changes in r262469.
Comment 12 EWS Watchlist 2020-06-03 03:34:49 PDT
Thanks for the patch. If this patch contains new public API please make sure it follows the guidelines for new WebKit2 GTK+ API. See http://trac.webkit.org/wiki/WebKitGTK/AddingNewWebKit2API
Comment 13 David Kilzer (:ddkilzer) 2020-06-03 11:56:52 PDT
Created attachment 400952 [details]
Patch v6

Try to make GTK and Win/WinCairo ports build.

Still haven't fixed Optional<OptionSet<DragOperation>> yet.  Looking into that while EWS bots chew on this patch.
Comment 14 David Kilzer (:ddkilzer) 2020-06-03 12:18:35 PDT
Created attachment 400957 [details]
Patch v7

Still trying to fix style, GTK and Win/WinCairo build failures.
Comment 15 David Kilzer (:ddkilzer) 2020-06-03 14:38:57 PDT
Created attachment 400969 [details]
Patch v8

Try to fix GTK build.  WinCairo build looks good.
Comment 16 David Kilzer (:ddkilzer) 2020-06-03 15:30:50 PDT
Created attachment 400971 [details]
Patch v9

Hopefully the last build fix for GTK.  WinCairo is building.
Comment 17 David Kilzer (:ddkilzer) 2020-06-03 16:03:01 PDT
Created attachment 400977 [details]
Patch v10

Same as Patch v9, but changed Optional<OptionSet<DragOperation>> to OptionSet<DragOperation> in struct EventHandler::DragTargetResponse.
Comment 18 David Kilzer (:ddkilzer) 2020-06-03 18:36:40 PDT
(In reply to David Kilzer (:ddkilzer) from comment #17)
> Created attachment 400977 [details]
> Patch v10
> 
> Same as Patch v9, but changed Optional<OptionSet<DragOperation>> to
> OptionSet<DragOperation> in struct EventHandler::DragTargetResponse.

Turns out the Optional<> is significant as two mac-wk1 tests fail when I removed it:

fast/events/drag-and-drop.html
fast/events/prevent-drag-to-navigate.html

So we have to keep Optional<OptionSet<DragOperation>> for now.

Patch v9 seems like a winner (other than fast/css/user-drag-none.html crashing).  Need to figure out what I broke between Patch v7 and Patch v9.  Sigh.
Comment 19 David Kilzer (:ddkilzer) 2020-06-03 18:42:13 PDT
(In reply to David Kilzer (:ddkilzer) from comment #18)
> Patch v9 seems like a winner (other than fast/css/user-drag-none.html
> crashing).  Need to figure out what I broke between Patch v7 and Patch v9. 
> Sigh.

No changes to Windows code (only GTK code) between Patch v7 and Patch v9.
Comment 20 David Kilzer (:ddkilzer) 2020-06-03 22:15:20 PDT
(In reply to David Kilzer (:ddkilzer) from comment #19)
> (In reply to David Kilzer (:ddkilzer) from comment #18)
> > Patch v9 seems like a winner (other than fast/css/user-drag-none.html
> > crashing).  Need to figure out what I broke between Patch v7 and Patch v9. 
> > Sigh.
> 
> No changes to Windows code (only GTK code) between Patch v7 and Patch v9.

The crash was in code outside of WebKit, and it didn't reproduce, so I'm sure if this patch caused it.

Run: <https://ews-build.webkit.org/#/builders/10/builds/20183>
First results:  <https://ews-build.webkit.org/results/Windows-EWS/r400971-20183/results.html>
Comment 21 David Kilzer (:ddkilzer) 2020-06-03 22:17:21 PDT
Created attachment 400998 [details]
Patch v11
Comment 22 David Kilzer (:ddkilzer) 2020-06-03 22:18:26 PDT
(In reply to David Kilzer (:ddkilzer) from comment #21)
> Created attachment 400998 [details]
> Patch v11

Same as Patch v9 but with updated ChangeLogs.

Ready for review.
Comment 23 David Kilzer (:ddkilzer) 2020-06-03 22:19:21 PDT
Comment on attachment 400998 [details]
Patch v11

Well, except for the typo I made.
Comment 24 David Kilzer (:ddkilzer) 2020-06-03 22:23:00 PDT
Created attachment 400999 [details]
Patch v12
Comment 25 David Kilzer (:ddkilzer) 2020-06-04 10:15:57 PDT
Created attachment 401035 [details]
Patch v13

Identical to Patch v12, but re-posting to avoid a revision with 120+ failing WPT tests.
Comment 26 David Kilzer (:ddkilzer) 2020-06-04 10:16:31 PDT
(In reply to David Kilzer (:ddkilzer) from comment #25)
> Created attachment 401035 [details]
> Patch v13
> 
> Identical to Patch v12, but re-posting to avoid a revision with 120+ failing
> WPT tests.

This patch is still ready for review.
Comment 27 Alex Christensen 2020-06-04 10:39:50 PDT
Comment on attachment 401035 [details]
Patch v13

Why do we have both EnumTraits and OptionSetTraits for this enum?
Why didn't you make DragOperation an enum class?
Comment 28 David Kilzer (:ddkilzer) 2020-06-04 11:47:36 PDT
(In reply to Alex Christensen from comment #27)
> Comment on attachment 401035 [details]
> Patch v13
> 
> Why do we have both EnumTraits and OptionSetTraits for this enum?

Because CoreIPC transmits both Optional<DragOperation> and OptionSet<DragOperation> types.

> Why didn't you make DragOperation an enum class?

Because this patch was already over 100 KB, and I didn't want to complicate it further.  I was going to fix that in a follow-up patch.  I can make the change here if you'd l;ke.
Comment 29 David Kilzer (:ddkilzer) 2020-06-04 12:03:08 PDT
(In reply to David Kilzer (:ddkilzer) from comment #28)
> (In reply to Alex Christensen from comment #27)
> > Comment on attachment 401035 [details]
> > Patch v13
> > 
> > Why do we have both EnumTraits and OptionSetTraits for this enum?
> 
> Because CoreIPC transmits both Optional<DragOperation> and
> OptionSet<DragOperation> types.

Trying to anticipate your next question:  "Why are you using both Optional<DragOperation> and OptionSet<DragOperation>?"

The reason I'm using both is that I let the code tell me which one it needed as I did the refactoring.

Optional<DragOperation> means the code wants a single DragOperation value (not multiple values), but it may or may not be set (since we removed DragOperationNone).

OptionSet<DragOperation> means the code wants one or more DragOperation values.

This is my second attempt at this refactoring.  The first attempt used OptionSet<DragOperation> everywhere, and it didn't feel correct since there were places where I wanted to know if a single DragOperation value was being used, so it didn't make sense to pass an OptionSet<DragOperation> into that code.
Comment 30 David Kilzer (:ddkilzer) 2020-06-05 10:43:10 PDT
Still ready for review:
<https://bugs.webkit.org/attachment.cgi?id=401035&action=review>
Comment 31 Darin Adler 2020-06-05 11:20:57 PDT
Comment on attachment 401035 [details]
Patch v13

View in context: https://bugs.webkit.org/attachment.cgi?id=401035&action=review

> Source/WebCore/dom/DataTransfer.cpp:626
> +    if ((isGenericMove && operationMask.containsAll({ DragOperationCopy, DragOperationLink })) || operationMask == anyDragOperation())
>          return "all";

Seems like we should refine and write this differently; doesn’t seem like we literally want to be checking "== any" although we do want to preserve behavior. Maybe a containsAll call with the appropriate operations.

> Source/WebCore/page/DragActions.h:64
>  typedef enum {

Even if not converting to enum class, should really change typedef enum { } <name> to just enum <name>.

> Source/WebCore/page/DragController.cpp:701
> +    if (sourceOperationMask == anyDragOperation())
>          return DragOperationCopy;

While this does preserve behavior, this is peculiar. There must be a better way to preserve this behavior that doesn’t involve literally checking against "any". Can refine later, I guess.

> Source/WebCore/page/EventHandler.cpp:2353
> +        case DragOperationCopy:
> +            return "copy"_s;

If the default is "copy", maybe leave this case out.

> Source/WebCore/page/EventHandler.cpp:2385
> +            auto operationFromKeyword = convertDropZoneOperationToDragOperation(keywords[i]);
> +            if (operationFromKeyword) {

Put the declaration inside the if?

> Source/WebCore/page/win/DragControllerWin.cpp:47
> +    // FIXME: to match the macos behaviour we should return WTF::nullopt.

Capitalize "to"? Change "macos" to "macOS"?

> Source/WebCore/platform/gtk/GtkUtilities.cpp:159
> -    // We have no good way to detect DragOperationEvery other than
> +    // We have no good way to detect anyDragOperation() other than
>      // to use it when all applicable flags are on.
>      if (gdkAction & GDK_ACTION_COPY
>          && gdkAction & GDK_ACTION_MOVE
>          && gdkAction & GDK_ACTION_LINK)
> -        return DragOperationEvery;
> +        return anyDragOperation();

Unclear why this code is helpful. We should remove it unless there is some benefit.

> Source/WebCore/platform/gtk/GtkUtilities.cpp:176
> -    if (coreAction == DragOperationNone)
> +    if (coreAction.isEmpty())
>          return static_cast<GdkDragAction>(gdkAction);

This is unneeded. Code below will already do this without adding a special case for empty.

> Source/WebCore/platform/gtk/GtkUtilities.cpp:190
> +    if (coreAction == anyDragOperation() || coreAction.contains(DragOperationCopy))

This is redundant. No need to check against anyDragOperation(). Just checking contains(Copy) will do the same thing.

> Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm:7312
> +        if (*operation & WebCore::DragOperationMove)
> +            return UIDropOperationMove;
> +        if (*operation & WebCore::DragOperationCopy)
> +            return UIDropOperationCopy;

This should be ==, not &, since it is an operation, not an OptionSet of operations.

> Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm:7317
> +static OptionSet<WebCore::DragOperation> coreDragOperationForUIDropOperation(UIDropOperation dropOperation)

Why does this return a set? It seems like it’s translating a single operation into a set. Doesn’t make sense to me.

> Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm:7446
> +    _page->dragEnded(WebCore::roundedIntPoint(client), WebCore::roundedIntPoint(global), currentDragOperation ? *currentDragOperation : OptionSet<WebCore::DragOperation>({ }));

We should teach OptionSet to construct from an Optional, so we don’t need to write this out, since it’s true for any Optional/OptionSet. Maybe as a cleanup pass after this patch, or in the patch would be OK too.

> Source/WebKitLegacy/mac/WebView/WebHTMLView.mm:4236
> +    if (operationMask == WebCore::anyDragOperation())
> +        return NSDragOperationEvery;

I suggest leaving this out. Should be fine to not literally have it be NSDragOperationEvery, but only include the actual operations.

> Source/WebKitLegacy/mac/WebView/WebViewInternal.h:95
> +typedef NSDragOperation CocoaDragOperation;

How about using instead of typedef? This is for C++ only, so we don’t need something C understands.

> Source/WebKitLegacy/mac/WebView/WebViewInternal.h:97
> +typedef uint64_t CocoaDragOperation;

Ditto.

> Source/WebKitLegacy/mac/WebView/WebViewInternal.h:98
> +#endif // USE(APPKIT)

On such a small #if/#endif pair the comment on #endif feels like nonhelpful clutter.

> Source/WebKitLegacy/win/WebCoreSupport/WebDragClient.cpp:174
>              if (effect & DROPEFFECT_COPY)
> -                operation = DragOperationCopy;
> +                operationMask = DragOperationCopy;
>              else if (effect & DROPEFFECT_LINK)
> -                operation = DragOperationLink;
> +                operationMask = DragOperationLink;
>              else if (effect & DROPEFFECT_MOVE)
> -                operation = DragOperationMove;
> +                operationMask = DragOperationMove;

Seems like this should not have else, and this should be adding instead of assigning. But that would be a behavior change. But otherwise this is not really an operation mask, it’s just pretending to be.

> Source/WebKitLegacy/win/WebView.cpp:5845
> +static DWORD dragOperationToDragCursor(Optional<DragOperation> operationMask)

An Optional<DragOperation> is not a "mask"; that would be an OptionSet.

> Source/WebKitLegacy/win/WebView.cpp:5851
> +    if (*operationMask & DragOperationCopy)

This should be ==, not &, since this is a value, not a mask.
Comment 32 David Kilzer (:ddkilzer) 2020-06-05 17:24:20 PDT
Comment on attachment 401035 [details]
Patch v13

View in context: https://bugs.webkit.org/attachment.cgi?id=401035&action=review

If I made the suggested change, I did _not_ note it below for brevity.

>> Source/WebCore/dom/DataTransfer.cpp:626
>>          return "all";
> 
> Seems like we should refine and write this differently; doesn’t seem like we literally want to be checking "== any" although we do want to preserve behavior. Maybe a containsAll call with the appropriate operations.

I could change this to operationMask.containsAll(anyDragOperation()).  Is that better?

I don't think it makes sense to list out every operation _again_ since we already do it for WTF::OptionSetTraits<>() and anyDragOperation() in DragActions.h.

I could add a method on OptionSet<DragOperation> that would do this check without having to list out all the operations (assuming an OptionSetTraits<> exists for the enum), but I'm not sure what to call it.  Maybe OptionSet<>::hasAll() or ::hasAllBitsSet()?

>> Source/WebCore/page/DragController.cpp:701
>>          return DragOperationCopy;
> 
> While this does preserve behavior, this is peculiar. There must be a better way to preserve this behavior that doesn’t involve literally checking against "any". Can refine later, I guess.

Using sourceOperationMask.containsAll(anyDragOperation()) as above for consistency.

>> Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm:7317
>> +static OptionSet<WebCore::DragOperation> coreDragOperationForUIDropOperation(UIDropOperation dropOperation)
> 
> Why does this return a set? It seems like it’s translating a single operation into a set. Doesn’t make sense to me.

Will change to return Optional<DragOperation> and use the new OptionSet(Optional) constructor.
Comment 33 David Kilzer (:ddkilzer) 2020-06-05 17:38:45 PDT
Created attachment 401219 [details]
Patch for landing
Comment 34 Darin Adler 2020-06-05 18:00:23 PDT
Comment on attachment 401035 [details]
Patch v13

View in context: https://bugs.webkit.org/attachment.cgi?id=401035&action=review

>>> Source/WebCore/dom/DataTransfer.cpp:626
>>>          return "all";
>> 
>> Seems like we should refine and write this differently; doesn’t seem like we literally want to be checking "== any" although we do want to preserve behavior. Maybe a containsAll call with the appropriate operations.
> 
> I could change this to operationMask.containsAll(anyDragOperation()).  Is that better?
> 
> I don't think it makes sense to list out every operation _again_ since we already do it for WTF::OptionSetTraits<>() and anyDragOperation() in DragActions.h.
> 
> I could add a method on OptionSet<DragOperation> that would do this check without having to list out all the operations (assuming an OptionSetTraits<> exists for the enum), but I'm not sure what to call it.  Maybe OptionSet<>::hasAll() or ::hasAllBitsSet()?

I do think that a containsAll that lists all the current values is better. There’s no reason to assume that if we add another in the future that the behavior of this code should implicitly change.

I don’t think we really want to be checking for anyDragOperation here. It’s likely just sloppy programming. Do we really mean all of "copy, link, generic, private, move, and delete"? Seems highly unlikely.

It’s inappropriate for this to include all the bits in the OptionSet. If we added a new bit, it's highly unlikely that it would be meaningful on Windows. For example, seems almost certain that "delete" doesn’t matter one way or the other.

>>> Source/WebCore/page/DragController.cpp:701
>>>          return DragOperationCopy;
>> 
>> While this does preserve behavior, this is peculiar. There must be a better way to preserve this behavior that doesn’t involve literally checking against "any". Can refine later, I guess.
> 
> Using sourceOperationMask.containsAll(anyDragOperation()) as above for consistency.

Same comment as above. I’m almost certain that a mask that includes everything except for "Private", for example, or everything except for "Delete" should not cause this to function return DragOperationMove instead of DragOperationCopy.

It’s fine to preserve behavior, but it’s really nonsense logic.
Comment 35 Darin Adler 2020-06-05 18:01:59 PDT
Comment on attachment 401035 [details]
Patch v13

View in context: https://bugs.webkit.org/attachment.cgi?id=401035&action=review

>>>> Source/WebCore/dom/DataTransfer.cpp:626
>>>>          return "all";
>>> 
>>> Seems like we should refine and write this differently; doesn’t seem like we literally want to be checking "== any" although we do want to preserve behavior. Maybe a containsAll call with the appropriate operations.
>> 
>> I could change this to operationMask.containsAll(anyDragOperation()).  Is that better?
>> 
>> I don't think it makes sense to list out every operation _again_ since we already do it for WTF::OptionSetTraits<>() and anyDragOperation() in DragActions.h.
>> 
>> I could add a method on OptionSet<DragOperation> that would do this check without having to list out all the operations (assuming an OptionSetTraits<> exists for the enum), but I'm not sure what to call it.  Maybe OptionSet<>::hasAll() or ::hasAllBitsSet()?
> 
> I do think that a containsAll that lists all the current values is better. There’s no reason to assume that if we add another in the future that the behavior of this code should implicitly change.
> 
> I don’t think we really want to be checking for anyDragOperation here. It’s likely just sloppy programming. Do we really mean all of "copy, link, generic, private, move, and delete"? Seems highly unlikely.
> 
> It’s inappropriate for this to include all the bits in the OptionSet. If we added a new bit, it's highly unlikely that it would be meaningful on Windows. For example, seems almost certain that "delete" doesn’t matter one way or the other.

Basically: Using a form of "any" makes code that is doing what is likely an incorrect operation look logical, but falsely.
Comment 36 Darin Adler 2020-06-05 18:02:00 PDT
Comment on attachment 401035 [details]
Patch v13

View in context: https://bugs.webkit.org/attachment.cgi?id=401035&action=review

>>>> Source/WebCore/dom/DataTransfer.cpp:626
>>>>          return "all";
>>> 
>>> Seems like we should refine and write this differently; doesn’t seem like we literally want to be checking "== any" although we do want to preserve behavior. Maybe a containsAll call with the appropriate operations.
>> 
>> I could change this to operationMask.containsAll(anyDragOperation()).  Is that better?
>> 
>> I don't think it makes sense to list out every operation _again_ since we already do it for WTF::OptionSetTraits<>() and anyDragOperation() in DragActions.h.
>> 
>> I could add a method on OptionSet<DragOperation> that would do this check without having to list out all the operations (assuming an OptionSetTraits<> exists for the enum), but I'm not sure what to call it.  Maybe OptionSet<>::hasAll() or ::hasAllBitsSet()?
> 
> I do think that a containsAll that lists all the current values is better. There’s no reason to assume that if we add another in the future that the behavior of this code should implicitly change.
> 
> I don’t think we really want to be checking for anyDragOperation here. It’s likely just sloppy programming. Do we really mean all of "copy, link, generic, private, move, and delete"? Seems highly unlikely.
> 
> It’s inappropriate for this to include all the bits in the OptionSet. If we added a new bit, it's highly unlikely that it would be meaningful on Windows. For example, seems almost certain that "delete" doesn’t matter one way or the other.

Basically: Using a form of "any" makes code that is doing what is likely an incorrect operation look logical, but falsely.
Comment 37 David Kilzer (:ddkilzer) 2020-06-05 18:42:19 PDT
Comment on attachment 401035 [details]
Patch v13

View in context: https://bugs.webkit.org/attachment.cgi?id=401035&action=review

>>>>>> Source/WebCore/dom/DataTransfer.cpp:626
>>>>>>          return "all";
>>>>> 
>>>>> Seems like we should refine and write this differently; doesn’t seem like we literally want to be checking "== any" although we do want to preserve behavior. Maybe a containsAll call with the appropriate operations.
>>>> 
>>>> I could change this to operationMask.containsAll(anyDragOperation()).  Is that better?
>>>> 
>>>> I don't think it makes sense to list out every operation _again_ since we already do it for WTF::OptionSetTraits<>() and anyDragOperation() in DragActions.h.
>>>> 
>>>> I could add a method on OptionSet<DragOperation> that would do this check without having to list out all the operations (assuming an OptionSetTraits<> exists for the enum), but I'm not sure what to call it.  Maybe OptionSet<>::hasAll() or ::hasAllBitsSet()?
>>> 
>>> I do think that a containsAll that lists all the current values is better. There’s no reason to assume that if we add another in the future that the behavior of this code should implicitly change.
>>> 
>>> I don’t think we really want to be checking for anyDragOperation here. It’s likely just sloppy programming. Do we really mean all of "copy, link, generic, private, move, and delete"? Seems highly unlikely.
>>> 
>>> It’s inappropriate for this to include all the bits in the OptionSet. If we added a new bit, it's highly unlikely that it would be meaningful on Windows. For example, seems almost certain that "delete" doesn’t matter one way or the other.
>> 
>> Basically: Using a form of "any" makes code that is doing what is likely an incorrect operation look logical, but falsely.
> 
> Basically: Using a form of "any" makes code that is doing what is likely an incorrect operation look logical, but falsely.

Okay, I'll add the individual values in both places.

>>>> Source/WebCore/page/DragController.cpp:701
>>>>          return DragOperationCopy;
>>> 
>>> While this does preserve behavior, this is peculiar. There must be a better way to preserve this behavior that doesn’t involve literally checking against "any". Can refine later, I guess.
>> 
>> Using sourceOperationMask.containsAll(anyDragOperation()) as above for consistency.
> 
> Same comment as above. I’m almost certain that a mask that includes everything except for "Private", for example, or everything except for "Delete" should not cause this to function return DragOperationMove instead of DragOperationCopy.
> 
> It’s fine to preserve behavior, but it’s really nonsense logic.

Ditto.
Comment 38 David Kilzer (:ddkilzer) 2020-06-05 18:42:38 PDT
Created attachment 401222 [details]
Patch for landing v2
Comment 39 EWS 2020-06-06 08:17:36 PDT
Committed r262680: <https://trac.webkit.org/changeset/262680>

All reviewed patches have been landed. Closing bug and clearing flags on attachment 401222 [details].
Comment 40 Radar WebKit Bug Importer 2020-06-06 08:18:18 PDT
<rdar://problem/64069089>
Comment 41 Radar WebKit Bug Importer 2020-06-06 08:18:19 PDT
<rdar://problem/64069091>
Comment 42 David Kilzer (:ddkilzer) 2020-06-06 09:13:24 PDT
(In reply to EWS from comment #39)
> Committed r262680: <https://trac.webkit.org/changeset/262680>
> 
> All reviewed patches have been landed. Closing bug and clearing flags on
> attachment 401222 [details].

Follow-up fix (to address two missed "== anyDragOperation()" uses):
Committed r262681: <https://trac.webkit.org/changeset/262681>