1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-10 23:44:24 +00:00

NSViewComponentPeer: Allow key equivalents to propagate to inner views if they are not handled by outer views

This commit is contained in:
reuk 2023-02-27 17:05:46 +00:00
parent 3a893b5853
commit 55d1585445
No known key found for this signature in database
GPG key ID: FCB43929F012EE5C

View file

@ -1579,6 +1579,14 @@ public:
bool sendEventToInputContextOrComponent (NSEvent* ev)
{
// In the case that an event was processed unsuccessfully in performKeyEquivalent and then
// posted back to keyDown by the system, this check will ensure that we don't attempt to
// process the same event a second time.
const auto newEvent = KeyEventAttributes::make (ev);
if (std::exchange (lastSeenKeyEvent, newEvent) == newEvent)
return false;
// We assume that the event will be handled by the IME.
// Occasionally, the inputContext may be sent key events like cmd+Q, which it will turn
// into a noop: call and forward to doCommandBySelector:.
@ -1611,6 +1619,73 @@ public:
}
//==============================================================================
class KeyEventAttributes
{
auto tie() const
{
return std::tie (type,
modifierFlags,
timestamp,
windowNumber,
characters,
charactersIgnoringModifiers,
keyCode,
isRepeat);
}
public:
static std::optional<KeyEventAttributes> make (NSEvent* event)
{
const auto type = [event type];
if (type != NSEventTypeKeyDown && type != NSEventTypeKeyUp)
return {};
return KeyEventAttributes
{
type,
[event modifierFlags],
[event timestamp],
[event windowNumber],
nsStringToJuce ([event characters]),
nsStringToJuce ([event charactersIgnoringModifiers]),
[event keyCode],
static_cast<bool> ([event isARepeat])
};
}
bool operator== (const KeyEventAttributes& other) const { return tie() == other.tie(); }
bool operator!= (const KeyEventAttributes& other) const { return tie() != other.tie(); }
private:
KeyEventAttributes (NSEventType typeIn,
NSEventModifierFlags flagsIn,
NSTimeInterval timestampIn,
NSInteger windowNumberIn,
String charactersIn,
String charactersIgnoringModifiersIn,
unsigned short keyCodeIn,
bool isRepeatIn)
: type (typeIn),
modifierFlags (flagsIn),
timestamp (timestampIn),
windowNumber (windowNumberIn),
characters (charactersIn),
charactersIgnoringModifiers (charactersIgnoringModifiersIn),
keyCode (keyCodeIn),
isRepeat (isRepeatIn)
{}
NSEventType type;
NSEventModifierFlags modifierFlags;
NSTimeInterval timestamp;
NSInteger windowNumber;
String characters;
String charactersIgnoringModifiers;
unsigned short keyCode;
bool isRepeat;
};
NSWindow* window = nil;
NSView* view = nil;
WeakReference<Component> safeComponent;
@ -1632,6 +1707,8 @@ public:
RectangleList<float> deferredRepaints;
uint32 lastRepaintTime;
std::optional<KeyEventAttributes> lastSeenKeyEvent;
static ComponentPeer* currentlyFocusedPeer;
static std::set<int> keysCurrentlyDown;
static int insideToFrontCall;
@ -2087,7 +2164,8 @@ struct JuceNSViewClass : public NSViewComponentPeerWrapper<ObjCClass<NSView>>
addMethod (@selector (performKeyEquivalent:), [] (id self, SEL s, NSEvent* ev) -> BOOL
{
if (auto* owner = getOwner (self))
return owner->sendEventToInputContextOrComponent (ev);
if (owner->sendEventToInputContextOrComponent (ev))
return YES;
return sendSuperclassMessage<BOOL> (self, s, ev);
});