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;
}