|
- /*
- ==============================================================================
-
- This file is part of the JUCE library.
- Copyright (c) 2022 - Raw Material Software Limited
-
- JUCE is an open source library subject to commercial or open-source
- licensing.
-
- By using JUCE, you agree to the terms of both the JUCE 7 End-User License
- Agreement and JUCE Privacy Policy.
-
- End User License Agreement: www.juce.com/juce-7-licence
- Privacy Policy: www.juce.com/juce-privacy-policy
-
- Or: You may also use this code under the terms of the GPL v3 (see
- www.gnu.org/licenses).
-
- JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
- EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
- DISCLAIMED.
-
- ==============================================================================
- */
-
- namespace juce::detail
- {
-
- /** Keeps track of the active top level window. */
- class TopLevelWindowManager : private Timer,
- private DeletedAtShutdown
- {
- public:
- TopLevelWindowManager() = default;
-
- ~TopLevelWindowManager() override
- {
- clearSingletonInstance();
- }
-
- JUCE_DECLARE_SINGLETON_SINGLETHREADED_MINIMAL (TopLevelWindowManager)
-
- static void checkCurrentlyFocusedTopLevelWindow()
- {
- if (auto* wm = TopLevelWindowManager::getInstanceWithoutCreating())
- wm->checkFocusAsync();
- }
-
- void checkFocusAsync()
- {
- startTimer (10);
- }
-
- void checkFocus()
- {
- startTimer (jmin (1731, getTimerInterval() * 2));
-
- auto* newActive = findCurrentlyActiveWindow();
-
- if (newActive != currentActive)
- {
- currentActive = newActive;
-
- for (int i = windows.size(); --i >= 0;)
- if (auto* tlw = windows[i])
- tlw->setWindowActive (isWindowActive (tlw));
-
- Desktop::getInstance().triggerFocusCallback();
- }
- }
-
- bool addWindow (TopLevelWindow* const w)
- {
- windows.add (w);
- checkFocusAsync();
-
- return isWindowActive (w);
- }
-
- void removeWindow (TopLevelWindow* const w)
- {
- checkFocusAsync();
-
- if (currentActive == w)
- currentActive = nullptr;
-
- windows.removeFirstMatchingValue (w);
-
- if (windows.isEmpty())
- deleteInstance();
- }
-
- Array<TopLevelWindow*> windows;
-
- private:
- TopLevelWindow* currentActive = nullptr;
-
- void timerCallback() override
- {
- checkFocus();
- }
-
- bool isWindowActive (TopLevelWindow* const tlw) const
- {
- return (tlw == currentActive
- || tlw->isParentOf (currentActive)
- || tlw->hasKeyboardFocus (true))
- && tlw->isShowing();
- }
-
- TopLevelWindow* findCurrentlyActiveWindow() const
- {
- if (Process::isForegroundProcess())
- {
- auto* focusedComp = Component::getCurrentlyFocusedComponent();
- auto* w = dynamic_cast<TopLevelWindow*> (focusedComp);
-
- if (w == nullptr && focusedComp != nullptr)
- w = focusedComp->findParentComponentOfClass<TopLevelWindow>();
-
- if (w == nullptr)
- w = currentActive;
-
- if (w != nullptr && w->isShowing())
- return w;
- }
-
- return nullptr;
- }
-
- JUCE_DECLARE_NON_COPYABLE (TopLevelWindowManager)
- };
-
- JUCE_IMPLEMENT_SINGLETON (TopLevelWindowManager)
-
- } // namespace juce::detail
|