mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
ObjC: Add scoped notification observer
This commit is contained in:
parent
921d86e586
commit
869760cb2a
3 changed files with 79 additions and 90 deletions
|
|
@ -520,4 +520,57 @@ private:
|
|||
BlockType block;
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
class ScopedNotificationCenterObserver
|
||||
{
|
||||
public:
|
||||
ScopedNotificationCenterObserver() = default;
|
||||
|
||||
ScopedNotificationCenterObserver (id observerIn, SEL selector, NSNotificationName nameIn, id objectIn)
|
||||
: observer (observerIn), name (nameIn), object (objectIn)
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] addObserver: observer
|
||||
selector: selector
|
||||
name: name
|
||||
object: object];
|
||||
}
|
||||
|
||||
~ScopedNotificationCenterObserver()
|
||||
{
|
||||
if (observer != nullptr && name != nullptr)
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] removeObserver: observer
|
||||
name: name
|
||||
object: object];
|
||||
}
|
||||
}
|
||||
|
||||
ScopedNotificationCenterObserver (ScopedNotificationCenterObserver&& other) noexcept
|
||||
{
|
||||
swap (other);
|
||||
}
|
||||
|
||||
ScopedNotificationCenterObserver& operator= (ScopedNotificationCenterObserver&& other) noexcept
|
||||
{
|
||||
auto moved = std::move (other);
|
||||
swap (moved);
|
||||
return *this;
|
||||
}
|
||||
|
||||
ScopedNotificationCenterObserver (const ScopedNotificationCenterObserver&) = delete;
|
||||
ScopedNotificationCenterObserver& operator= (const ScopedNotificationCenterObserver&) = delete;
|
||||
|
||||
private:
|
||||
void swap (ScopedNotificationCenterObserver& other) noexcept
|
||||
{
|
||||
std::swap (other.observer, observer);
|
||||
std::swap (other.name, name);
|
||||
std::swap (other.object, object);
|
||||
}
|
||||
|
||||
id observer = nullptr;
|
||||
NSNotificationName name = nullptr;
|
||||
id object = nullptr;
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
|
|
|
|||
|
|
@ -710,24 +710,14 @@ public:
|
|||
{
|
||||
static DelegateClass delegateClass;
|
||||
|
||||
delegate = [delegateClass.createInstance() init];
|
||||
object_setInstanceVariable (delegate, "owner", this);
|
||||
delegate.reset ([delegateClass.createInstance() init]);
|
||||
object_setInstanceVariable (delegate.get(), "owner", this);
|
||||
|
||||
JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wundeclared-selector")
|
||||
[[NSNotificationCenter defaultCenter] addObserver: delegate
|
||||
selector: @selector (darkModeChanged:)
|
||||
name: UIViewComponentPeer::getDarkModeNotificationName()
|
||||
object: nil];
|
||||
observer.emplace (delegate.get(), @selector (darkModeChanged:), UIViewComponentPeer::getDarkModeNotificationName(), nil);
|
||||
JUCE_END_IGNORE_WARNINGS_GCC_LIKE
|
||||
}
|
||||
|
||||
~NativeDarkModeChangeDetectorImpl()
|
||||
{
|
||||
object_setInstanceVariable (delegate, "owner", nullptr);
|
||||
[[NSNotificationCenter defaultCenter] removeObserver: delegate];
|
||||
[delegate release];
|
||||
}
|
||||
|
||||
void darkModeChanged()
|
||||
{
|
||||
Desktop::getInstance().darkModeChanged();
|
||||
|
|
@ -741,20 +731,19 @@ private:
|
|||
addIvar<NativeDarkModeChangeDetectorImpl*> ("owner");
|
||||
|
||||
JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wundeclared-selector")
|
||||
addMethod (@selector (darkModeChanged:), darkModeChanged);
|
||||
addMethod (@selector (darkModeChanged:), [] (id self, SEL, NSNotification*)
|
||||
{
|
||||
if (auto* owner = getIvar<NativeDarkModeChangeDetectorImpl*> (self, "owner"))
|
||||
owner->darkModeChanged();
|
||||
});
|
||||
JUCE_END_IGNORE_WARNINGS_GCC_LIKE
|
||||
|
||||
registerClass();
|
||||
}
|
||||
|
||||
static void darkModeChanged (id self, SEL, NSNotification*)
|
||||
{
|
||||
if (auto* owner = getIvar<NativeDarkModeChangeDetectorImpl*> (self, "owner"))
|
||||
owner->darkModeChanged();
|
||||
}
|
||||
};
|
||||
|
||||
id delegate = nil;
|
||||
NSUniquePtr<NSObject> delegate;
|
||||
Optional<ScopedNotificationCenterObserver> observer;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (NativeDarkModeChangeDetectorImpl)
|
||||
};
|
||||
|
|
|
|||
|
|
@ -144,12 +144,7 @@ public:
|
|||
|
||||
resetTrackingArea (view);
|
||||
|
||||
notificationCenter = [NSNotificationCenter defaultCenter];
|
||||
|
||||
[notificationCenter addObserver: view
|
||||
selector: frameChangedSelector
|
||||
name: NSViewFrameDidChangeNotification
|
||||
object: view];
|
||||
scopedObservers.emplace_back (view, frameChangedSelector, NSViewFrameDidChangeNotification, view);
|
||||
|
||||
[view setPostsFrameChangedNotifications: YES];
|
||||
|
||||
|
|
@ -225,25 +220,10 @@ public:
|
|||
[window setTabbingMode: NSWindowTabbingModeDisallowed];
|
||||
#endif
|
||||
|
||||
[notificationCenter addObserver: view
|
||||
selector: frameChangedSelector
|
||||
name: NSWindowDidMoveNotification
|
||||
object: window];
|
||||
|
||||
[notificationCenter addObserver: view
|
||||
selector: frameChangedSelector
|
||||
name: NSWindowDidMiniaturizeNotification
|
||||
object: window];
|
||||
|
||||
[notificationCenter addObserver: view
|
||||
selector: @selector (windowWillMiniaturize:)
|
||||
name: NSWindowWillMiniaturizeNotification
|
||||
object: window];
|
||||
|
||||
[notificationCenter addObserver: view
|
||||
selector: @selector (windowDidDeminiaturize:)
|
||||
name: NSWindowDidDeminiaturizeNotification
|
||||
object: window];
|
||||
scopedObservers.emplace_back (view, frameChangedSelector, NSWindowDidMoveNotification, window);
|
||||
scopedObservers.emplace_back (view, frameChangedSelector, NSWindowDidMiniaturizeNotification, window);
|
||||
scopedObservers.emplace_back (view, @selector (windowWillMiniaturize:), NSWindowWillMiniaturizeNotification, window);
|
||||
scopedObservers.emplace_back (view, @selector (windowDidMiniaturize:), NSWindowDidMiniaturizeNotification, window);
|
||||
}
|
||||
|
||||
auto alpha = component.getAlpha();
|
||||
|
|
@ -267,7 +247,8 @@ public:
|
|||
CVDisplayLinkStop (displayLink);
|
||||
dispatch_source_cancel (displaySource);
|
||||
|
||||
[notificationCenter removeObserver: view];
|
||||
scopedObservers.clear();
|
||||
|
||||
setOwner (view, nullptr);
|
||||
|
||||
if ([view superview] != nil)
|
||||
|
|
@ -797,24 +778,7 @@ public:
|
|||
|
||||
void redirectWillMoveToWindow (NSWindow* newWindow)
|
||||
{
|
||||
if (auto* currentWindow = [view window])
|
||||
{
|
||||
[notificationCenter removeObserver: view
|
||||
name: NSWindowDidMoveNotification
|
||||
object: currentWindow];
|
||||
|
||||
[notificationCenter removeObserver: view
|
||||
name: NSWindowWillMiniaturizeNotification
|
||||
object: currentWindow];
|
||||
|
||||
[notificationCenter removeObserver: view
|
||||
name: NSWindowDidBecomeKeyNotification
|
||||
object: currentWindow];
|
||||
|
||||
[notificationCenter removeObserver: view
|
||||
name: NSWindowDidChangeScreenNotification
|
||||
object: currentWindow];
|
||||
}
|
||||
windowObservers.clear();
|
||||
|
||||
if (isSharedWindow && [view window] == window && newWindow == nullptr)
|
||||
{
|
||||
|
|
@ -1256,30 +1220,11 @@ public:
|
|||
|
||||
if (auto* currentWindow = [view window])
|
||||
{
|
||||
[notificationCenter addObserver: view
|
||||
selector: dismissModalsSelector
|
||||
name: NSWindowWillMoveNotification
|
||||
object: currentWindow];
|
||||
|
||||
[notificationCenter addObserver: view
|
||||
selector: dismissModalsSelector
|
||||
name: NSWindowWillMiniaturizeNotification
|
||||
object: currentWindow];
|
||||
|
||||
[notificationCenter addObserver: view
|
||||
selector: becomeKeySelector
|
||||
name: NSWindowDidBecomeKeyNotification
|
||||
object: currentWindow];
|
||||
|
||||
[notificationCenter addObserver: view
|
||||
selector: resignKeySelector
|
||||
name: NSWindowDidResignKeyNotification
|
||||
object: currentWindow];
|
||||
|
||||
[notificationCenter addObserver: view
|
||||
selector: @selector (windowDidChangeScreen:)
|
||||
name: NSWindowDidChangeScreenNotification
|
||||
object: currentWindow];
|
||||
windowObservers.emplace_back (view, dismissModalsSelector, NSWindowWillMoveNotification, currentWindow);
|
||||
windowObservers.emplace_back (view, dismissModalsSelector, NSWindowWillMiniaturizeNotification, currentWindow);
|
||||
windowObservers.emplace_back (view, becomeKeySelector, NSWindowDidBecomeKeyNotification, currentWindow);
|
||||
windowObservers.emplace_back (view, resignKeySelector, NSWindowDidResignKeyNotification, currentWindow);
|
||||
windowObservers.emplace_back (view, @selector (windowDidChangeScreen:), NSWindowDidChangeScreenNotification, currentWindow);
|
||||
|
||||
updateCVDisplayLinkScreen();
|
||||
}
|
||||
|
|
@ -1659,7 +1604,6 @@ public:
|
|||
bool windowRepresentsFile = false;
|
||||
bool isAlwaysOnTop = false, wasAlwaysOnTop = false;
|
||||
String stringBeingComposed;
|
||||
NSNotificationCenter* notificationCenter = nil;
|
||||
|
||||
Rectangle<float> lastSizeBeforeZoom;
|
||||
RectangleList<float> deferredRepaints;
|
||||
|
|
@ -1892,6 +1836,9 @@ private:
|
|||
int numFramesToSkipMetalRenderer = 0;
|
||||
std::unique_ptr<CoreGraphicsMetalLayerRenderer<NSView>> metalRenderer;
|
||||
|
||||
std::vector<ScopedNotificationCenterObserver> scopedObservers;
|
||||
std::vector<ScopedNotificationCenterObserver> windowObservers;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (NSViewComponentPeer)
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue