Title: [293340] trunk/Source/WebKit
Revision
293340
Author
[email protected]
Date
2022-04-25 13:00:23 -0700 (Mon, 25 Apr 2022)

Log Message

[macOS] Only show a context menu action to "Copy Cropped Image" when appropriate
https://bugs.webkit.org/show_bug.cgi?id=239712
rdar://92239384

Reviewed by Darin Adler.

Implement gating for the "Copy Cropped Image" context menu item. This is similar to the current gating mechanism
used for visual look up, wherein the Look Up menu item is asynchronously appended to the context menu.

In this case, we only append the "Copy Cropped Image" menu item in the case where `requestImageAnalysisMarkup`
completes with a non-null result.

* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::close):
(WebKit::WebPageProxy::showContextMenu):
(WebKit::WebPageProxy::contextMenuItemSelected):
* UIProcess/WebPageProxy.h:

Cache the image analysis results for "Copy Cropped Image" in a member variable, `m_croppedImageForContextMenu`.

* UIProcess/mac/WebContextMenuProxyMac.mm:
(WebKit::WebContextMenuProxyMac::getContextMenuFromItems):
* UIProcess/mac/WebPageProxyMac.mm:
(WebKit::WebPageProxy::setCroppedImageForContextMenu):
(WebKit::WebPageProxy::handleContextMenuCopyCroppedImage):

Modified Paths

Diff

Modified: trunk/Source/WebKit/ChangeLog (293339 => 293340)


--- trunk/Source/WebKit/ChangeLog	2022-04-25 19:58:27 UTC (rev 293339)
+++ trunk/Source/WebKit/ChangeLog	2022-04-25 20:00:23 UTC (rev 293340)
@@ -1,3 +1,31 @@
+2022-04-25  Wenson Hsieh  <[email protected]>
+
+        [macOS] Only show a context menu action to "Copy Cropped Image" when appropriate
+        https://bugs.webkit.org/show_bug.cgi?id=239712
+        rdar://92239384
+
+        Reviewed by Darin Adler.
+
+        Implement gating for the "Copy Cropped Image" context menu item. This is similar to the current gating mechanism
+        used for visual look up, wherein the Look Up menu item is asynchronously appended to the context menu.
+
+        In this case, we only append the "Copy Cropped Image" menu item in the case where `requestImageAnalysisMarkup`
+        completes with a non-null result.
+
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::close):
+        (WebKit::WebPageProxy::showContextMenu):
+        (WebKit::WebPageProxy::contextMenuItemSelected):
+        * UIProcess/WebPageProxy.h:
+
+        Cache the image analysis results for "Copy Cropped Image" in a member variable, `m_croppedImageForContextMenu`.
+
+        * UIProcess/mac/WebContextMenuProxyMac.mm:
+        (WebKit::WebContextMenuProxyMac::getContextMenuFromItems):
+        * UIProcess/mac/WebPageProxyMac.mm:
+        (WebKit::WebPageProxy::setCroppedImageForContextMenu):
+        (WebKit::WebPageProxy::handleContextMenuCopyCroppedImage):
+
 2022-04-25  Aditya Keerthi  <[email protected]>
 
         Fix the tvOS and watchOS builds after r293231

Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.cpp (293339 => 293340)


--- trunk/Source/WebKit/UIProcess/WebPageProxy.cpp	2022-04-25 19:58:27 UTC (rev 293339)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.cpp	2022-04-25 20:00:23 UTC (rev 293340)
@@ -1190,6 +1190,10 @@
     m_activeContextMenu = nullptr;
 #endif
 
+#if ENABLE(CONTEXT_MENUS) && ENABLE(IMAGE_ANALYSIS_ENHANCEMENTS)
+    m_croppedImageForContextMenu = nullptr;
+#endif
+
     m_provisionalPage = nullptr;
 
     m_inspector->invalidate();
@@ -7083,6 +7087,10 @@
     // MouseDown event that triggered this ShowContextMenu message. This can happen if we take too long to enter the nested runloop.
     discardQueuedMouseEvents();
 
+#if ENABLE(IMAGE_ANALYSIS_ENHANCEMENTS)
+    m_croppedImageForContextMenu = nullptr;
+#endif
+
     m_activeContextMenuContextData = contextMenuContextData;
 
     m_activeContextMenu = pageClient().createContextMenuProxy(*this, WTFMove(contextMenuContextData), userData);
@@ -7213,8 +7221,7 @@
 
     case ContextMenuItemTagCopyCroppedImage:
 #if ENABLE(IMAGE_ANALYSIS_ENHANCEMENTS)
-        if (hitTestData.imageBitmap)
-            handleContextMenuCopyCroppedImage(*hitTestData.imageBitmap, hitTestData.sourceImageMIMEType);
+        handleContextMenuCopyCroppedImage(hitTestData.sourceImageMIMEType);
 #endif
         return;
 

Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.h (293339 => 293340)


--- trunk/Source/WebKit/UIProcess/WebPageProxy.h	2022-04-25 19:58:27 UTC (rev 293339)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.h	2022-04-25 20:00:23 UTC (rev 293340)
@@ -2035,7 +2035,7 @@
     void handleContextMenuLookUpImage();
 #endif
 #if ENABLE(IMAGE_ANALYSIS_ENHANCEMENTS)
-    void handleContextMenuCopyCroppedImage(ShareableBitmap&, const String& preferredMIMEType);
+    void handleContextMenuCopyCroppedImage(const String& preferredMIMEType);
 #endif
 #endif // ENABLE(CONTEXT_MENUS)
 
@@ -2102,6 +2102,10 @@
     void extractVideoInElementFullScreen(WebCore::MediaPlayerIdentifier, WebCore::FloatRect videoBounds);
     void cancelVideoExtractionInElementFullScreen();
 
+#if ENABLE(CONTEXT_MENUS) && ENABLE(IMAGE_ANALYSIS_ENHANCEMENTS)
+    void setCroppedImageForContextMenu(CGImageRef);
+#endif
+
 private:
     WebPageProxy(PageClient&, WebProcessProxy&, Ref<API::PageConfiguration>&&);
     void platformInitialize();
@@ -2791,6 +2795,11 @@
     RefPtr<WebContextMenuProxy> m_activeContextMenu;
     ContextMenuContextData m_activeContextMenuContextData;
 #endif
+
+#if ENABLE(CONTEXT_MENUS) && ENABLE(IMAGE_ANALYSIS_ENHANCEMENTS)
+    RetainPtr<CGImageRef> m_croppedImageForContextMenu;
+#endif
+
     RefPtr<API::HitTestResult> m_lastMouseMoveHitTestResult;
 
     RefPtr<WebOpenPanelResultListenerProxy> m_openPanelResultListener;

Modified: trunk/Source/WebKit/UIProcess/mac/WebContextMenuProxyMac.mm (293339 => 293340)


--- trunk/Source/WebKit/UIProcess/mac/WebContextMenuProxyMac.mm	2022-04-25 19:58:27 UTC (rev 293339)
+++ trunk/Source/WebKit/UIProcess/mac/WebContextMenuProxyMac.mm	2022-04-25 20:00:23 UTC (rev 293340)
@@ -601,17 +601,26 @@
         });
     }
 
+    std::optional<WebContextMenuItemData> copyCroppedImageItem;
     std::optional<WebContextMenuItemData> lookUpImageItem;
 
 #if ENABLE(IMAGE_ANALYSIS)
-    filteredItems.removeFirstMatching([&] (auto& item) {
-        if (item.action() != WebCore::ContextMenuItemTagLookUpImage)
-            return false;
-
-        lookUpImageItem = { item };
-        return true;
+    filteredItems.removeAllMatching([&] (auto& item) {
+        switch (item.action()) {
+        case ContextMenuItemTagLookUpImage:
+            ASSERT(!lookUpImageItem);
+            lookUpImageItem = { item };
+            return true;
+        case ContextMenuItemTagCopyCroppedImage:
+            ASSERT(!copyCroppedImageItem);
+            copyCroppedImageItem = { item };
+            return true;
+        default:
+            break;
+        }
+        return false;
     });
-#endif
+#endif // ENABLE(IMAGE_ANALYSIS)
 
 #if HAVE(TRANSLATION_UI_SERVICES)
     if (!page()->canHandleContextMenuTranslation() || isPopover) {
@@ -628,7 +637,7 @@
     auto imageBitmap = hitTestData.imageBitmap;
 
     RetainPtr sparseMenuItems = [NSPointerArray strongObjectsPointerArray];
-    auto insertMenuItem = makeBlockPtr([protectedThis = Ref { *this }, weakPage = WeakPtr { page() }, imageURL = WTFMove(imageURL), imageBitmap = WTFMove(imageBitmap), lookUpImageItem = WTFMove(lookUpImageItem), completionHandler = WTFMove(completionHandler), itemsRemaining = filteredItems.size(), menu = WTFMove(menu), sparseMenuItems](NSMenuItem *item, NSUInteger index) mutable {
+    auto insertMenuItem = makeBlockPtr([protectedThis = Ref { *this }, weakPage = WeakPtr { page() }, imageURL = WTFMove(imageURL), imageBitmap = WTFMove(imageBitmap), lookUpImageItem = WTFMove(lookUpImageItem), copyCroppedImageItem = WTFMove(copyCroppedImageItem), completionHandler = WTFMove(completionHandler), itemsRemaining = filteredItems.size(), menu = WTFMove(menu), sparseMenuItems](NSMenuItem *item, NSUInteger index) mutable {
         ASSERT(index < [sparseMenuItems count]);
         ASSERT(![sparseMenuItems pointerAtIndex:index]);
         [sparseMenuItems replacePointerAtIndex:index withPointer:item];
@@ -638,12 +647,31 @@
         [menu setItemArray:[sparseMenuItems allObjects]];
 
         RefPtr page = weakPage.get();
-        if (lookUpImageItem && page && imageBitmap) {
+        if (page && imageBitmap) {
 #if ENABLE(IMAGE_ANALYSIS)
-            page->computeHasVisualSearchResults(imageURL, *imageBitmap, [protectedThis = WTFMove(protectedThis), lookUpImageItem = WTFMove(*lookUpImageItem)] (bool hasVisualSearchResults) mutable {
-                if (hasVisualSearchResults)
-                    [protectedThis->m_menu addItem:createMenuActionItem(lookUpImageItem).get()];
-            });
+            if (lookUpImageItem) {
+                page->computeHasVisualSearchResults(imageURL, *imageBitmap, [protectedThis, lookUpImageItem = WTFMove(*lookUpImageItem)] (bool hasVisualSearchResults) mutable {
+                    if (hasVisualSearchResults)
+                        [protectedThis->m_menu addItem:createMenuActionItem(lookUpImageItem).get()];
+                });
+            }
+
+            if (copyCroppedImageItem) {
+                if (auto image = imageBitmap->makeCGImageCopy()) {
+                    page->setCroppedImageForContextMenu(nullptr);
+                    requestImageAnalysisMarkup(image.get(), [weakPage, protectedThis, copyCroppedImageItem = WTFMove(*copyCroppedImageItem)](auto result, auto) {
+                        if (!result)
+                            return;
+
+                        RefPtr page = weakPage.get();
+                        if (!page)
+                            return;
+
+                        page->setCroppedImageForContextMenu(result);
+                        [protectedThis->m_menu addItem:createMenuActionItem(copyCroppedImageItem).get()];
+                    });
+                }
+            }
 #else
             UNUSED_PARAM(imageURL);
 #endif

Modified: trunk/Source/WebKit/UIProcess/mac/WebPageProxyMac.mm (293339 => 293340)


--- trunk/Source/WebKit/UIProcess/mac/WebPageProxyMac.mm	2022-04-25 19:58:27 UTC (rev 293339)
+++ trunk/Source/WebKit/UIProcess/mac/WebPageProxyMac.mm	2022-04-25 20:00:23 UTC (rev 293340)
@@ -781,29 +781,24 @@
 
 #if ENABLE(IMAGE_ANALYSIS_ENHANCEMENTS)
 
-void WebPageProxy::handleContextMenuCopyCroppedImage(ShareableBitmap& imageBitmap, const String& preferredMIMEType)
+void WebPageProxy::setCroppedImageForContextMenu(CGImageRef image)
 {
-    auto changeCount = NSPasteboard.generalPasteboard.changeCount;
-    auto performCopy = [changeCount, preferredMIMEType](CGImageRef resultImage) {
-        auto pasteboard = NSPasteboard.generalPasteboard;
-        if (changeCount != pasteboard.changeCount || !resultImage)
-            return;
+    m_croppedImageForContextMenu = image;
+}
 
-        auto [data, type] = transcodeWithPreferredMIMEType(resultImage, preferredMIMEType.createCFString().get(), (__bridge CFStringRef)UTTypeTIFF.identifier);
-        if (!data)
-            return;
+void WebPageProxy::handleContextMenuCopyCroppedImage(const String& preferredMIMEType)
+{
+    if (!m_croppedImageForContextMenu)
+        return;
 
-        [pasteboard declareTypes:@[(__bridge NSString *)type.get()] owner:nil];
-        [pasteboard setData:data.get() forType:(__bridge NSString *)type.get()];
-    };
-
-    auto originalImage = imageBitmap.makeCGImageCopy();
-    if (!originalImage)
+    auto [data, type] = transcodeWithPreferredMIMEType(m_croppedImageForContextMenu.get(), preferredMIMEType.createCFString().get(), (__bridge CFStringRef)UTTypeTIFF.identifier);
+    if (!data)
         return;
 
-    requestImageAnalysisMarkup(originalImage.get(), [performCopy = WTFMove(performCopy)](auto image, auto) {
-        performCopy(image);
-    });
+    auto pasteboard = NSPasteboard.generalPasteboard;
+    auto pasteboardType = (__bridge NSString *)type.get();
+    [pasteboard declareTypes:@[pasteboardType] owner:nil];
+    [pasteboard setData:data.get() forType:pasteboardType];
 }
 
 #endif // ENABLE(IMAGE_ANALYSIS_ENHANCEMENTS)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to