1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-30 02:50:05 +00:00

macOS: Forward key events from WKWebView correctly

Also added support for selectAll: selector forwarding in NSViewComponentPeer
This commit is contained in:
ed 2020-11-13 16:39:20 +00:00
parent 5ae32084a7
commit 36f1197536
2 changed files with 63 additions and 38 deletions

View file

@ -710,9 +710,10 @@ public:
handleMagnifyGesture (MouseInputSource::InputSourceType::mouse, getMousePos (ev, view), getMouseTime (ev), 1.0f / invScale);
}
void redirectCopy (NSObject*) { handleKeyPress (KeyPress ('c', ModifierKeys (ModifierKeys::commandModifier), 'c')); }
void redirectPaste (NSObject*) { handleKeyPress (KeyPress ('v', ModifierKeys (ModifierKeys::commandModifier), 'v')); }
void redirectCut (NSObject*) { handleKeyPress (KeyPress ('x', ModifierKeys (ModifierKeys::commandModifier), 'x')); }
void redirectCopy (NSObject*) { handleKeyPress (KeyPress ('c', ModifierKeys (ModifierKeys::commandModifier), 'c')); }
void redirectPaste (NSObject*) { handleKeyPress (KeyPress ('v', ModifierKeys (ModifierKeys::commandModifier), 'v')); }
void redirectCut (NSObject*) { handleKeyPress (KeyPress ('x', ModifierKeys (ModifierKeys::commandModifier), 'x')); }
void redirectSelectAll (NSObject*) { handleKeyPress (KeyPress ('a', ModifierKeys (ModifierKeys::commandModifier), 'a')); }
void redirectWillMoveToWindow (NSWindow* newWindow)
{
@ -1665,6 +1666,7 @@ struct JuceNSViewClass : public ObjCClass<NSView>
addMethod (@selector (paste:), paste, "v@:@");
addMethod (@selector (copy:), copy, "v@:@");
addMethod (@selector (cut:), cut, "v@:@");
addMethod (@selector (selectAll:), selectAll, "v@:@");
addMethod (@selector (viewWillMoveToWindow:), willMoveToWindow, "v@:@");
@ -1716,6 +1718,7 @@ private:
static void copy (id self, SEL, NSObject* s) { if (auto* p = getOwner (self)) p->redirectCopy (s); }
static void paste (id self, SEL, NSObject* s) { if (auto* p = getOwner (self)) p->redirectPaste (s); }
static void cut (id self, SEL, NSObject* s) { if (auto* p = getOwner (self)) p->redirectCut (s); }
static void selectAll (id self, SEL, NSObject* s) { if (auto* p = getOwner (self)) p->redirectSelectAll (s); }
static void willMoveToWindow (id self, SEL, NSWindow* w) { if (auto* p = getOwner (self)) p->redirectWillMoveToWindow (w); }
static BOOL acceptsFirstMouse (id, SEL, NSEvent*) { return YES; }

View file

@ -78,6 +78,55 @@ static NSMutableURLRequest* getRequestForURL (const String& url, const StringArr
return nullptr;
}
#if JUCE_MAC
#if JUCE_USE_WKWEBVIEW
using WebViewBase = ObjCClass<WKWebView>;
#else
using WebViewBase = ObjCClass<WebView>;
#endif
struct WebViewKeyEquivalentResponder : public WebViewBase
{
WebViewKeyEquivalentResponder()
: WebViewBase ("WebViewKeyEquivalentResponder_")
{
addIvar<WebViewKeyEquivalentResponder*> ("owner");
addMethod (@selector (performKeyEquivalent:), performKeyEquivalent, @encode (BOOL), "@:@");
registerClass();
}
private:
static WebViewKeyEquivalentResponder* getOwner (id self)
{
return getIvar<WebViewKeyEquivalentResponder*> (self, "owner");
}
static BOOL performKeyEquivalent (id self, SEL selector, NSEvent* event)
{
NSResponder* first = [[self window] firstResponder];
if (([event modifierFlags] & NSDeviceIndependentModifierFlagsMask) == NSCommandKeyMask)
{
auto sendAction = [&] (SEL actionSelector) -> BOOL
{
return [NSApp sendAction: actionSelector
to: first
from: self];
};
if ([[event charactersIgnoringModifiers] isEqualToString: @"x"]) return sendAction (@selector (cut:));
if ([[event charactersIgnoringModifiers] isEqualToString: @"c"]) return sendAction (@selector (copy:));
if ([[event charactersIgnoringModifiers] isEqualToString: @"v"]) return sendAction (@selector (paste:));
if ([[event charactersIgnoringModifiers] isEqualToString: @"a"]) return sendAction (@selector (selectAll:));
}
return sendSuperclassMessage<BOOL> (self, selector, event);
}
};
#endif
#if JUCE_USE_WKWEBVIEW
struct WebViewDelegateClass : public ObjCClass<NSObject>
@ -96,8 +145,7 @@ struct WebViewDelegateClass : public ObjCClass<NSObject>
windowFeatures:), createWebView, "@@:@@@@");
#if WKWEBVIEW_OPENPANEL_SUPPORTED
addMethod (@selector (webView:runOpenPanelWithParameters:
initiatedByFrame:completionHandler:), runOpenPanel, "v@:@@@@");
addMethod (@selector (webView:runOpenPanelWithParameters:initiatedByFrame:completionHandler:), runOpenPanel, "v@:@@@@");
#endif
registerClass();
@ -211,12 +259,17 @@ public:
#if JUCE_MAC
auto frame = NSMakeRect (0, 0, 100.0f, 100.0f);
static WebViewKeyEquivalentResponder webviewClass;
webView = (WKWebView*) webviewClass.createInstance();
webView = [webView initWithFrame: frame
configuration: config];
#else
auto frame = CGRectMake (0, 0, 100.0f, 100.0f);
#endif
webView = [[WKWebView alloc] initWithFrame: frame
configuration: config];
#endif
static WebViewDelegateClass cls;
webViewDelegate = [cls.createInstance() init];
@ -270,37 +323,6 @@ private:
#if JUCE_MAC
struct WebViewKeyEquivalentResponder : public ObjCClass<WebView>
{
WebViewKeyEquivalentResponder() : ObjCClass<WebView> ("WebViewKeyEquivalentResponder_")
{
addIvar<WebViewKeyEquivalentResponder*> ("owner");
addMethod (@selector (performKeyEquivalent:), performKeyEquivalent, @encode (BOOL), "@:@");
registerClass();
}
private:
static WebViewKeyEquivalentResponder* getOwner (id self)
{
return getIvar<WebViewKeyEquivalentResponder*> (self, "owner");
}
static BOOL performKeyEquivalent (id self, SEL selector, NSEvent* event)
{
NSResponder* first = [[self window] firstResponder];
if (([event modifierFlags] & NSDeviceIndependentModifierFlagsMask) == NSCommandKeyMask)
{
if ([[event charactersIgnoringModifiers] isEqualToString:@"x"]) return [NSApp sendAction:@selector(cut:) to:first from:self];
if ([[event charactersIgnoringModifiers] isEqualToString:@"c"]) return [NSApp sendAction:@selector(copy:) to:first from:self];
if ([[event charactersIgnoringModifiers] isEqualToString:@"v"]) return [NSApp sendAction:@selector(paste:) to:first from:self];
if ([[event charactersIgnoringModifiers] isEqualToString:@"a"]) return [NSApp sendAction:@selector(selectAll:) to:first from:self];
}
return sendSuperclassMessage<BOOL> (self, selector, event);
}
};
struct DownloadClickDetectorClass : public ObjCClass<NSObject>
{
DownloadClickDetectorClass() : ObjCClass<NSObject> ("JUCEWebClickDetector_")