Title: [231510] trunk/Source/WebKit
Revision
231510
Author
[email protected]
Date
2018-05-08 13:34:05 -0700 (Tue, 08 May 2018)

Log Message

The PDF context menu should not be created in the WebContent process.
https://bugs.webkit.org/show_bug.cgi?id=185401

Reviewed by Tim Horton.

Send a sync IPC message from the WebContent process to the UI process with the necessary context
menu information when the menu is requested. The NSMenu will then be created and shown in the
UI process. The reply will contain the selected menu item index.

* Shared/mac/PDFContextMenu.h: Added.
(WebKit::PDFContextMenuItem::encode const):
(WebKit::PDFContextMenuItem::decode):
(WebKit::PDFContextMenu::encode const):
(WebKit::PDFContextMenu::decode):
* UIProcess/WebPageProxy.h:
* UIProcess/WebPageProxy.messages.in:
* UIProcess/mac/WebPageProxyMac.mm:
(-[WKPDFMenuTarget menuItem]):
(-[WKPDFMenuTarget contextMenuAction:]):
(WebKit::WebPageProxy::showPDFContextMenu):
* WebKit.xcodeproj/project.pbxproj:
* WebProcess/Plugins/PDF/PDFPlugin.mm:
(WebKit::PDFPlugin::handleContextMenuEvent):

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebKit/ChangeLog (231509 => 231510)


--- trunk/Source/WebKit/ChangeLog	2018-05-08 20:29:13 UTC (rev 231509)
+++ trunk/Source/WebKit/ChangeLog	2018-05-08 20:34:05 UTC (rev 231510)
@@ -1,3 +1,29 @@
+2018-05-08  Per Arne Vollan  <[email protected]>
+
+        The PDF context menu should not be created in the WebContent process.
+        https://bugs.webkit.org/show_bug.cgi?id=185401
+
+        Reviewed by Tim Horton.
+
+        Send a sync IPC message from the WebContent process to the UI process with the necessary context
+        menu information when the menu is requested. The NSMenu will then be created and shown in the
+        UI process. The reply will contain the selected menu item index.
+
+        * Shared/mac/PDFContextMenu.h: Added.
+        (WebKit::PDFContextMenuItem::encode const):
+        (WebKit::PDFContextMenuItem::decode):
+        (WebKit::PDFContextMenu::encode const):
+        (WebKit::PDFContextMenu::decode):
+        * UIProcess/WebPageProxy.h:
+        * UIProcess/WebPageProxy.messages.in:
+        * UIProcess/mac/WebPageProxyMac.mm:
+        (-[WKPDFMenuTarget menuItem]):
+        (-[WKPDFMenuTarget contextMenuAction:]):
+        (WebKit::WebPageProxy::showPDFContextMenu):
+        * WebKit.xcodeproj/project.pbxproj:
+        * WebProcess/Plugins/PDF/PDFPlugin.mm:
+        (WebKit::PDFPlugin::handleContextMenuEvent):
+
 2018-05-08  Dean Jackson  <[email protected]>
 
         System Preview links should trigger a download

Added: trunk/Source/WebKit/Shared/mac/PDFContextMenu.h (0 => 231510)


--- trunk/Source/WebKit/Shared/mac/PDFContextMenu.h	                        (rev 0)
+++ trunk/Source/WebKit/Shared/mac/PDFContextMenu.h	2018-05-08 20:34:05 UTC (rev 231510)
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(PDFKIT_PLUGIN)
+namespace WebKit {
+    
+struct PDFContextMenuItem {
+    String title;
+    bool enabled;
+    bool separator;
+    int state;
+    bool hasAction;
+    int tag;
+
+    template<class Encoder> void encode(Encoder& encoder) const
+    {
+        encoder << title << enabled << separator << state << hasAction << tag;
+    }
+    
+    template<class Decoder> static std::optional<PDFContextMenuItem> decode(Decoder& decoder)
+    {
+        std::optional<String> title;
+        decoder >> title;
+        if (!title)
+            return std::nullopt;
+
+        std::optional<bool> enabled;
+        decoder >> enabled;
+        if (!enabled)
+            return std::nullopt;
+
+        std::optional<bool> separator;
+        decoder >> separator;
+        if (!separator)
+            return std::nullopt;
+
+        std::optional<int> state;
+        decoder >> state;
+        if (!state)
+            return std::nullopt;
+
+        std::optional<bool> hasAction;
+        decoder >> hasAction;
+        if (!hasAction)
+            return std::nullopt;
+
+        std::optional<int> tag;
+        decoder >> tag;
+        if (!tag)
+            return std::nullopt;
+
+        return { { WTFMove(*title), WTFMove(*enabled), WTFMove(*separator), WTFMove(*state), WTFMove(*hasAction), WTFMove(*tag) } };
+    }
+};
+
+struct PDFContextMenu {
+    WebCore::IntPoint m_point;
+    Vector<PDFContextMenuItem> m_items;
+    
+    template<class Encoder> void encode(Encoder& encoder) const
+    {
+        encoder << m_point << m_items;
+    }
+    
+    template<class Decoder> static std::optional<PDFContextMenu> decode(Decoder& decoder)
+    {
+        std::optional<WebCore::IntPoint> point;
+        decoder >> point;
+        if (!point)
+            return std::nullopt;
+
+        std::optional<Vector<PDFContextMenuItem>> items;
+        decoder >> items;
+        if (!items)
+            return std::nullopt;
+        
+        return { { WTFMove(*point), WTFMove(*items) } };
+    }
+
+};
+    
+};
+#endif
+

Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.h (231509 => 231510)


--- trunk/Source/WebKit/UIProcess/WebPageProxy.h	2018-05-08 20:29:13 UTC (rev 231509)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.h	2018-05-08 20:34:05 UTC (rev 231510)
@@ -1026,6 +1026,9 @@
     void openPDFFromTemporaryFolderWithNativeApplication(const String& pdfUUID);
 #endif
 
+#if ENABLE(PDFKIT_PLUGIN)
+    void showPDFContextMenu(const WebKit::PDFContextMenu&, int32_t& selectedIndex);
+#endif
     WebCore::IntRect visibleScrollerThumbRect() const { return m_visibleScrollerThumbRect; }
 
     uint64_t renderTreeSize() const { return m_renderTreeSize; }

Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.messages.in (231509 => 231510)


--- trunk/Source/WebKit/UIProcess/WebPageProxy.messages.in	2018-05-08 20:29:13 UTC (rev 231509)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.messages.in	2018-05-08 20:34:05 UTC (rev 231510)
@@ -423,6 +423,10 @@
     OpenPDFFromTemporaryFolderWithNativeApplication(String pdfUUID)
 #endif
 
+#if ENABLE(PDFKIT_PLUGIN)
+    ShowPDFContextMenu(struct WebKit::PDFContextMenu contextMenu) -> (int32_t selectedItem)
+#endif
+
 #if ENABLE(NETSCAPE_PLUGIN_API)
     FindPlugin(String mimeType, uint32_t processType, String urlString, String frameURLString, String pageURLString, bool allowOnlyApplicationPlugins) -> (uint64_t pluginProcessToken, String newMIMEType, uint32_t pluginLoadPolicy, String unavailabilityDescription, bool isUnsupported)
 #endif

Modified: trunk/Source/WebKit/UIProcess/mac/WebPageProxyMac.mm (231509 => 231510)


--- trunk/Source/WebKit/UIProcess/mac/WebPageProxyMac.mm	2018-05-08 20:29:13 UTC (rev 231509)
+++ trunk/Source/WebKit/UIProcess/mac/WebPageProxyMac.mm	2018-05-08 20:34:05 UTC (rev 231510)
@@ -36,6 +36,7 @@
 #import "EditorState.h"
 #import "MenuUtilities.h"
 #import "NativeWebKeyboardEvent.h"
+#import "PDFContextMenu.h"
 #import "PageClient.h"
 #import "PageClientImplMac.h"
 #import "PluginComplexTextInputState.h"
@@ -58,6 +59,7 @@
 #import <WebCore/ValidationBubble.h>
 #import <mach-o/dyld.h>
 #import <pal/spi/mac/NSApplicationSPI.h>
+#import <pal/spi/mac/NSMenuSPI.h>
 #import <wtf/ProcessPrivilege.h>
 #import <wtf/text/StringConcatenate.h>
 
@@ -72,6 +74,37 @@
 - (void)stopSpeaking:(id)sender;
 @end
 
+#if ENABLE(PDFKIT_PLUGIN)
+@interface WKPDFMenuTarget : NSObject {
+    id _selectedMenuItem;
+}
+- (id)selectedMenuItem;
+- (void)contextMenuAction:(id)sender;
+@end
+
+@implementation WKPDFMenuTarget
+- (instancetype)init
+{
+    self = [super init];
+    if (!self)
+        return nil;
+    
+    _selectedMenuItem = nil;
+    return self;
+}
+
+- (id)selectedMenuItem
+{
+    return _selectedMenuItem;
+}
+
+- (void)contextMenuAction:(id)sender
+{
+    _selectedMenuItem = sender;
+}
+@end // implementation WKPDFMenuTarget
+#endif
+
 namespace WebKit {
 
 static inline bool expectsLegacyImplicitRubberBandControl()
@@ -529,6 +562,45 @@
     [[NSWorkspace sharedWorkspace] openFile:pdfFilename];
 }
 
+#if ENABLE(PDFKIT_PLUGIN)
+void WebPageProxy::showPDFContextMenu(const WebKit::PDFContextMenu& contextMenu, int32_t& selectedIndex)
+{
+    if (!contextMenu.m_items.size())
+        return;
+    
+    RetainPtr<WKPDFMenuTarget> menuTarget = adoptNS([[WKPDFMenuTarget alloc] init]);
+    RetainPtr<NSMenu> nsMenu = adoptNS([[NSMenu alloc] init]);
+    [nsMenu setAllowsContextMenuPlugIns:false];
+    for (unsigned i = 0; i < contextMenu.m_items.size(); i++) {
+        auto& item = contextMenu.m_items[i];
+        
+        if (item.separator) {
+            [nsMenu insertItem:[NSMenuItem separatorItem] atIndex:i];
+            continue;
+        }
+        
+        RetainPtr<NSMenuItem> nsItem = adoptNS([[NSMenuItem alloc] init]);
+        [nsItem setTitle:item.title];
+        [nsItem setEnabled:item.enabled];
+        [nsItem setState:item.state];
+        if (item.hasAction) {
+            [nsItem setTarget:menuTarget.get()];
+            [nsItem setAction:@selector(contextMenuAction:)];
+        }
+        [nsItem setTag:item.tag];
+        [nsMenu insertItem:nsItem.get() atIndex:i];
+    }
+    NSWindow *window = m_pageClient.platformWindow();
+    auto windowNumber = [window windowNumber];
+    auto location = [window convertRectFromScreen: { contextMenu.m_point, NSZeroSize }].origin;
+    NSEvent* event = [NSEvent mouseEventWithType:NSEventTypeRightMouseDown location:location modifierFlags:0 timestamp:0 windowNumber:windowNumber context:0 eventNumber:0 clickCount:1 pressure:1];
+
+    auto view = [m_pageClient.platformWindow() contentView];
+    [NSMenu popUpContextMenu:nsMenu.get() withEvent:event forView:view];
+    selectedIndex = [[menuTarget selectedMenuItem] tag];
+}
+#endif
+
 #if ENABLE(TELEPHONE_NUMBER_DETECTION)
 void WebPageProxy::showTelephoneNumberMenu(const String& telephoneNumber, const WebCore::IntPoint& point)
 {

Modified: trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj (231509 => 231510)


--- trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj	2018-05-08 20:29:13 UTC (rev 231509)
+++ trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj	2018-05-08 20:34:05 UTC (rev 231510)
@@ -1992,6 +1992,7 @@
 		C181735F205839F600DFDA65 /* DrawingAreaMac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C181735E205839F600DFDA65 /* DrawingAreaMac.cpp */; };
 		C18173612058424700DFDA65 /* DisplayLink.h in Headers */ = {isa = PBXBuildFile; fileRef = C18173602058424700DFDA65 /* DisplayLink.h */; };
 		C1817363205844A900DFDA65 /* DisplayLink.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C1817362205844A900DFDA65 /* DisplayLink.cpp */; };
+		C1E123BA20A11573002646F4 /* PDFContextMenu.h in Headers */ = {isa = PBXBuildFile; fileRef = C1E123B920A11572002646F4 /* PDFContextMenu.h */; };
 		C517388112DF8F4F00EE3F47 /* DragControllerAction.h in Headers */ = {isa = PBXBuildFile; fileRef = C517388012DF8F4F00EE3F47 /* DragControllerAction.h */; };
 		C5237F6012441CA300780472 /* WebEditorClientMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = C5237F5F12441CA300780472 /* WebEditorClientMac.mm */; };
 		C54256B518BEC18C00DE4179 /* WKFormInputControl.h in Headers */ = {isa = PBXBuildFile; fileRef = C54256AF18BEC18B00DE4179 /* WKFormInputControl.h */; };
@@ -4521,6 +4522,7 @@
 		C181735E205839F600DFDA65 /* DrawingAreaMac.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = DrawingAreaMac.cpp; sourceTree = "<group>"; };
 		C18173602058424700DFDA65 /* DisplayLink.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DisplayLink.h; sourceTree = "<group>"; };
 		C1817362205844A900DFDA65 /* DisplayLink.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = DisplayLink.cpp; sourceTree = "<group>"; };
+		C1E123B920A11572002646F4 /* PDFContextMenu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PDFContextMenu.h; sourceTree = "<group>"; };
 		C517388012DF8F4F00EE3F47 /* DragControllerAction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DragControllerAction.h; sourceTree = "<group>"; };
 		C5237F5F12441CA300780472 /* WebEditorClientMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebEditorClientMac.mm; sourceTree = "<group>"; };
 		C54256AF18BEC18B00DE4179 /* WKFormInputControl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WKFormInputControl.h; path = ios/forms/WKFormInputControl.h; sourceTree = "<group>"; };
@@ -7678,6 +7680,7 @@
 				BC8ACA1016670D7B004C1941 /* ObjCObjectGraph.mm */,
 				C574A57F12E66681002DFE98 /* PasteboardTypes.h */,
 				C574A58012E66681002DFE98 /* PasteboardTypes.mm */,
+				C1E123B920A11572002646F4 /* PDFContextMenu.h */,
 				E19582D2153CBFD700B60875 /* PDFKitImports.h */,
 				E19582D4153CC05300B60875 /* PDFKitImports.mm */,
 				E1CC1B8F12D7EADF00625838 /* PrintInfoMac.mm */,
@@ -9069,6 +9072,7 @@
 				1AC7537C183A9FDB0072CB15 /* PageLoadState.h in Headers */,
 				1A8B66B01BC43C860082DF77 /* PageLoadStateObserver.h in Headers */,
 				C574A58112E66681002DFE98 /* PasteboardTypes.h in Headers */,
+				C1E123BA20A11573002646F4 /* PDFContextMenu.h in Headers */,
 				E19582D3153CBFD700B60875 /* PDFKitImports.h in Headers */,
 				5C298DA01C3DF02100470AFE /* PendingDownload.h in Headers */,
 				832ED18C1E2FE157006BA64A /* PerActivityStateCPUUsageSampler.h in Headers */,

Modified: trunk/Source/WebKit/WebProcess/Plugins/PDF/PDFPlugin.mm (231509 => 231510)


--- trunk/Source/WebKit/WebProcess/Plugins/PDF/PDFPlugin.mm	2018-05-08 20:29:13 UTC (rev 231509)
+++ trunk/Source/WebKit/WebProcess/Plugins/PDF/PDFPlugin.mm	2018-05-08 20:34:05 UTC (rev 231510)
@@ -31,6 +31,7 @@
 #import "ArgumentCoders.h"
 #import "DataReference.h"
 #import "PDFAnnotationTextWidgetDetails.h"
+#import "PDFContextMenu.h"
 #import "PDFLayerControllerSPI.h"
 #import "PDFPluginAnnotation.h"
 #import "PDFPluginPasswordField.h"
@@ -1572,9 +1573,27 @@
 {
     FrameView* frameView = webFrame()->coreFrame()->view();
     IntPoint point = frameView->contentsToScreen(IntRect(frameView->windowToContents(event.position()), IntSize())).location();
-    
+
     if (NSMenu *nsMenu = [m_pdfLayerController menuForEvent:nsEventForWebMouseEvent(event)]) {
-        _NSPopUpCarbonMenu3(nsMenu, nil, nil, point, -1, nil, 0, nil, NSPopUpMenuTypeContext, nil);
+        Vector<PDFContextMenuItem> items;
+        auto itemCount = [nsMenu numberOfItems];
+        for (int i = 0; i < itemCount; i++) {
+            auto item = [nsMenu itemAtIndex:i];
+            if ([item submenu])
+                continue;
+            PDFContextMenuItem menuItem { String([item title]), !![item isEnabled], !![item isSeparatorItem], static_cast<int>([item state]), [item action], i };
+            items.append(WTFMove(menuItem));
+        }
+        PDFContextMenu contextMenu { point, WTFMove(items) };
+
+        if (!webFrame()->page())
+            return false;
+
+        int selectedIndex = -1;
+        webFrame()->page()->sendSync(Messages::WebPageProxy::ShowPDFContextMenu(contextMenu), Messages::WebPageProxy::ShowPDFContextMenu::Reply(selectedIndex));
+        if (selectedIndex >= 0 && selectedIndex < itemCount)
+            [nsMenu performActionForItemAtIndex:selectedIndex];
+
         return true;
     }
     
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to