Skip to content

Commit

Permalink
MacOS: Disable window controls for windows created by JUCE when a Com…
Browse files Browse the repository at this point in the history
…ponent is modal

The change does not affect plugin windows, which are created by the
host.
  • Loading branch information
szarvas committed Jan 17, 2024
1 parent cc60286 commit fb14118
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,10 @@ JUCE_IMPLEMENT_SINGLETON (ModalComponentManager)
void ModalComponentManager::startModal (Component* component, bool autoDelete)
{
if (component != nullptr)
{
stack.add (new ModalItem (component, autoDelete));
detail::ComponentHelpers::ModalComponentManagerChangeNotifier::getInstance().modalComponentManagerChanged();
}
}

void ModalComponentManager::attachCallback (Component* component, Callback* callback)
Expand Down Expand Up @@ -210,6 +213,8 @@ void ModalComponentManager::handleAsyncUpdate()
item->callbacks.getUnchecked (j)->modalStateFinished (item->returnValue);

compToDelete.deleteAndZero();

detail::ComponentHelpers::ModalComponentManagerChangeNotifier::getInstance().modalComponentManagerChanged();
}
}
}
Expand Down
25 changes: 25 additions & 0 deletions modules/juce_gui_basics/detail/juce_ComponentHelpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,31 @@ struct ComponentHelpers
if (modalWouldBlockComponent (*c, &modal))
(c->*function) (ms, SH::screenPosToLocalPos (*c, ms.getScreenPosition()), Time::getCurrentTime());
}

class ModalComponentManagerChangeNotifier
{
public:
static auto& getInstance()
{
static ModalComponentManagerChangeNotifier instance;
return instance;
}

ErasedScopeGuard addListener (std::function<void()> l)
{
return listeners.addListener (std::move (l));
}

void modalComponentManagerChanged()
{
listeners.call();
}

private:
ModalComponentManagerChangeNotifier() = default;

detail::CallbackListenerList<> listeners;
};
};

} // namespace juce::detail
31 changes: 30 additions & 1 deletion modules/juce_gui_basics/native/juce_NSViewComponentPeer_mac.mm
Original file line number Diff line number Diff line change
Expand Up @@ -1712,7 +1712,7 @@ auto tie() const
NSWindow* window = nil;
NSView* view = nil;
WeakReference<Component> safeComponent;
bool isSharedWindow = false;
const bool isSharedWindow = false;
#if USE_COREGRAPHICS_RENDERING
bool usingCoreGraphics = true;
#else
Expand Down Expand Up @@ -1998,10 +1998,39 @@ void displayLayer ([[maybe_unused]] CALayer* layer) override
#endif
}

void modalComponentManagerChanged()
{
if (isSharedWindow)
return;

auto style = [window styleMask];

if (ModalComponentManager::getInstance()->getNumModalComponents() > 0)
{
style &= ~NSWindowStyleMaskMiniaturizable;
style &= ~NSWindowStyleMaskClosable;
}
else
{
const auto flags = getStyleFlags();

if ((flags & windowHasMinimiseButton) != 0) style |= NSWindowStyleMaskMiniaturizable;
if ((flags & windowHasCloseButton) != 0) style |= NSWindowStyleMaskClosable;
}

[window setStyleMask: style];
}

//==============================================================================
std::vector<ScopedNotificationCenterObserver> scopedObservers;
std::vector<ScopedNotificationCenterObserver> windowObservers;

ErasedScopeGuard modalChangeListenerScope =
detail::ComponentHelpers::ModalComponentManagerChangeNotifier::getInstance().addListener ([this]
{
modalComponentManagerChanged();
});

JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (NSViewComponentPeer)
};

Expand Down

0 comments on commit fb14118

Please sign in to comment.