diff --git a/modules/juce_gui_basics/detail/juce_AlertWindowHelpers.h b/modules/juce_gui_basics/detail/juce_AlertWindowHelpers.h index c9a4fa4feb..298a983fd6 100644 --- a/modules/juce_gui_basics/detail/juce_AlertWindowHelpers.h +++ b/modules/juce_gui_basics/detail/juce_AlertWindowHelpers.h @@ -97,7 +97,7 @@ struct AlertWindowHelpers alert->setCentrePosition (parent->getLocalBounds().getCentre()); } - alert->setAlwaysOnTop (detail::WindowingHelpers::areThereAnyAlwaysOnTopWindows()); + alert->setAlwaysOnTop (WindowUtils::areThereAnyAlwaysOnTopWindows()); return alert; } diff --git a/modules/juce_gui_basics/detail/juce_WindowingHelpers.h b/modules/juce_gui_basics/detail/juce_WindowingHelpers.h index 93f9dd8c0c..1947392d2e 100644 --- a/modules/juce_gui_basics/detail/juce_WindowingHelpers.h +++ b/modules/juce_gui_basics/detail/juce_WindowingHelpers.h @@ -32,8 +32,6 @@ struct WindowingHelpers static Image createIconForFile (const File& file); - static bool areThereAnyAlwaysOnTopWindows(); - #if JUCE_WINDOWS static bool isEmbeddedInForegroundProcess (Component* c); static bool isWindowOnCurrentVirtualDesktop (void*); diff --git a/modules/juce_gui_basics/filebrowser/juce_FileChooserDialogBox.cpp b/modules/juce_gui_basics/filebrowser/juce_FileChooserDialogBox.cpp index 4e62b1519f..8ec77d0b85 100644 --- a/modules/juce_gui_basics/filebrowser/juce_FileChooserDialogBox.cpp +++ b/modules/juce_gui_basics/filebrowser/juce_FileChooserDialogBox.cpp @@ -115,7 +115,7 @@ FileChooserDialogBox::FileChooserDialogBox (const String& name, if (parentComp != nullptr) parentComp->addAndMakeVisible (this); else - setAlwaysOnTop (detail::WindowingHelpers::areThereAnyAlwaysOnTopWindows()); + setAlwaysOnTop (WindowUtils::areThereAnyAlwaysOnTopWindows()); } FileChooserDialogBox::~FileChooserDialogBox() diff --git a/modules/juce_gui_basics/juce_gui_basics.cpp b/modules/juce_gui_basics/juce_gui_basics.cpp index e053d102ef..05a13aa636 100644 --- a/modules/juce_gui_basics/juce_gui_basics.cpp +++ b/modules/juce_gui_basics/juce_gui_basics.cpp @@ -143,6 +143,7 @@ #if JUCE_IOS #include "native/juce_UIViewComponentPeer_ios.mm" #include "native/accessibility/juce_Accessibility_ios.mm" + #include "native/juce_WindowUtils_ios.mm" #include "native/juce_Windowing_ios.mm" #include "native/juce_NativeMessageBox_ios.mm" #include "native/juce_NativeModalWrapperComponent_ios.h" @@ -156,6 +157,7 @@ #include "native/accessibility/juce_Accessibility_mac.mm" #include "native/juce_PerScreenDisplayLinks_mac.h" #include "native/juce_NSViewComponentPeer_mac.mm" + #include "native/juce_WindowUtils_mac.mm" #include "native/juce_Windowing_mac.mm" #include "native/juce_NativeMessageBox_mac.mm" #include "native/juce_MainMenu_mac.mm" @@ -172,6 +174,7 @@ #include "native/accessibility/juce_UIAProviders_windows.h" #include "native/accessibility/juce_AccessibilityElement_windows.cpp" #include "native/accessibility/juce_Accessibility_windows.cpp" + #include "native/juce_WindowUtils_windows.cpp" #include "native/juce_Windowing_windows.cpp" #include "native/juce_NativeMessageBox_windows.cpp" #include "native/juce_DragAndDrop_windows.cpp" @@ -184,6 +187,7 @@ JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wzero-as-null-pointer-constant") #include "native/juce_ScopedWindowAssociation_linux.h" + #include "native/juce_WindowUtils_linux.cpp" #include "native/juce_Windowing_linux.cpp" #include "native/juce_NativeMessageBox_linux.cpp" #include "native/juce_XWindowSystem_linux.cpp" @@ -196,6 +200,7 @@ #include "juce_core/files/juce_common_MimeTypes.h" #include "native/accessibility/juce_Accessibility_android.cpp" + #include "native/juce_WindowUtils_android.cpp" #include "native/juce_Windowing_android.cpp" #include "native/juce_NativeMessageBox_android.cpp" #include "native/juce_FileChooser_android.cpp" diff --git a/modules/juce_gui_basics/juce_gui_basics.h b/modules/juce_gui_basics/juce_gui_basics.h index ab791c1db3..f421760781 100644 --- a/modules/juce_gui_basics/juce_gui_basics.h +++ b/modules/juce_gui_basics/juce_gui_basics.h @@ -290,6 +290,7 @@ namespace juce #include "windows/juce_ThreadWithProgressWindow.h" #include "windows/juce_TooltipWindow.h" #include "windows/juce_VBlankAttachement.h" +#include "windows/juce_WindowUtils.h" #include "layout/juce_MultiDocumentPanel.h" #include "layout/juce_SidePanel.h" #include "filebrowser/juce_FileBrowserListener.h" diff --git a/modules/juce_gui_basics/native/juce_FileChooser_mac.mm b/modules/juce_gui_basics/native/juce_FileChooser_mac.mm index 55e087054c..5dc5c941fd 100644 --- a/modules/juce_gui_basics/native/juce_FileChooser_mac.mm +++ b/modules/juce_gui_basics/native/juce_FileChooser_mac.mm @@ -179,7 +179,7 @@ public: { if (panel != nil) { - setAlwaysOnTop (detail::WindowingHelpers::areThereAnyAlwaysOnTopWindows()); + setAlwaysOnTop (WindowUtils::areThereAnyAlwaysOnTopWindows()); addToDesktop (0); enterModalState (true); diff --git a/modules/juce_gui_basics/native/juce_FileChooser_windows.cpp b/modules/juce_gui_basics/native/juce_FileChooser_windows.cpp index 6a6a53196d..f3fdaeb47b 100644 --- a/modules/juce_gui_basics/native/juce_FileChooser_windows.cpp +++ b/modules/juce_gui_basics/native/juce_FileChooser_windows.cpp @@ -828,7 +828,7 @@ public: 0, 0); setOpaque (true); - setAlwaysOnTop (detail::WindowingHelpers::areThereAnyAlwaysOnTopWindows()); + setAlwaysOnTop (WindowUtils::areThereAnyAlwaysOnTopWindows()); addToDesktop (0); } diff --git a/modules/juce_gui_basics/native/juce_NativeMessageBox_windows.cpp b/modules/juce_gui_basics/native/juce_NativeMessageBox_windows.cpp index 574905cc93..a96c9b877f 100644 --- a/modules/juce_gui_basics/native/juce_NativeMessageBox_windows.cpp +++ b/modules/juce_gui_basics/native/juce_NativeMessageBox_windows.cpp @@ -175,7 +175,7 @@ std::unique_ptr ScopedMessageBoxInterface::create (co { // this window can get lost behind JUCE windows which are set to be alwaysOnTop // so if there are any set it to be topmost - const auto topmostFlag = detail::WindowingHelpers::areThereAnyAlwaysOnTopWindows() ? MB_TOPMOST : 0; + const auto topmostFlag = WindowUtils::areThereAnyAlwaysOnTopWindows() ? MB_TOPMOST : 0; const auto iconFlags = [&]() -> decltype (topmostFlag) { diff --git a/modules/juce_gui_basics/native/juce_WindowUtils_android.cpp b/modules/juce_gui_basics/native/juce_WindowUtils_android.cpp new file mode 100644 index 0000000000..95914809f2 --- /dev/null +++ b/modules/juce_gui_basics/native/juce_WindowUtils_android.cpp @@ -0,0 +1,34 @@ +/* + ============================================================================== + + 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 +{ + +bool WindowUtils::areThereAnyAlwaysOnTopWindows() +{ + return false; +} + +} // namespace juce diff --git a/modules/juce_gui_basics/native/juce_WindowUtils_ios.mm b/modules/juce_gui_basics/native/juce_WindowUtils_ios.mm new file mode 100644 index 0000000000..95914809f2 --- /dev/null +++ b/modules/juce_gui_basics/native/juce_WindowUtils_ios.mm @@ -0,0 +1,34 @@ +/* + ============================================================================== + + 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 +{ + +bool WindowUtils::areThereAnyAlwaysOnTopWindows() +{ + return false; +} + +} // namespace juce diff --git a/modules/juce_gui_basics/native/juce_WindowUtils_linux.cpp b/modules/juce_gui_basics/native/juce_WindowUtils_linux.cpp new file mode 100644 index 0000000000..005c569b65 --- /dev/null +++ b/modules/juce_gui_basics/native/juce_WindowUtils_linux.cpp @@ -0,0 +1,39 @@ +/* + ============================================================================== + + 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 +{ + +struct WindowUtilsInternal +{ + inline static int numAlwaysOnTopPeers = 0; +}; + +bool WindowUtils::areThereAnyAlwaysOnTopWindows() +{ + return WindowUtilsInternal::numAlwaysOnTopPeers > 0; +} + +} // namespace juce diff --git a/modules/juce_gui_basics/native/juce_WindowUtils_mac.mm b/modules/juce_gui_basics/native/juce_WindowUtils_mac.mm new file mode 100644 index 0000000000..ceb1af17df --- /dev/null +++ b/modules/juce_gui_basics/native/juce_WindowUtils_mac.mm @@ -0,0 +1,38 @@ +/* + ============================================================================== + + 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 +{ + +bool WindowUtils::areThereAnyAlwaysOnTopWindows() +{ + for (NSWindow* window in [NSApp windows]) + if ([window level] > NSNormalWindowLevel) + return true; + + return false; +} + +} // namespace juce diff --git a/modules/juce_gui_basics/native/juce_WindowUtils_windows.cpp b/modules/juce_gui_basics/native/juce_WindowUtils_windows.cpp new file mode 100644 index 0000000000..da376eb6c5 --- /dev/null +++ b/modules/juce_gui_basics/native/juce_WindowUtils_windows.cpp @@ -0,0 +1,59 @@ +/* + ============================================================================== + + 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 +{ + +static BOOL CALLBACK enumAlwaysOnTopWindows (HWND hwnd, LPARAM lParam) +{ + if (IsWindowVisible (hwnd)) + { + DWORD processID = 0; + GetWindowThreadProcessId (hwnd, &processID); + + if (processID == GetCurrentProcessId()) + { + WINDOWINFO info{}; + + if (GetWindowInfo (hwnd, &info) + && (info.dwExStyle & WS_EX_TOPMOST) != 0) + { + *reinterpret_cast (lParam) = true; + return FALSE; + } + } + } + + return TRUE; +} + +bool WindowUtils::areThereAnyAlwaysOnTopWindows() +{ + bool anyAlwaysOnTopFound = false; + EnumWindows (&enumAlwaysOnTopWindows, (LPARAM) &anyAlwaysOnTopFound); + return anyAlwaysOnTopFound; +} + +} // namespace juce diff --git a/modules/juce_gui_basics/native/juce_Windowing_android.cpp b/modules/juce_gui_basics/native/juce_Windowing_android.cpp index f5bb33c451..875fb2a5fc 100644 --- a/modules/juce_gui_basics/native/juce_Windowing_android.cpp +++ b/modules/juce_gui_basics/native/juce_Windowing_android.cpp @@ -2443,12 +2443,6 @@ void Desktop::allowedOrientationsChanged() getEnv()->CallVoidMethod (activity.get(), AndroidActivity.setRequestedOrientation, getAndroidOrientationFlag (allowedOrientations)); } -//============================================================================== -bool detail::WindowingHelpers::areThereAnyAlwaysOnTopWindows() -{ - return false; -} - //============================================================================== #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ METHOD (create, "", "()V") \ diff --git a/modules/juce_gui_basics/native/juce_Windowing_ios.mm b/modules/juce_gui_basics/native/juce_Windowing_ios.mm index 2fe0069dfa..fabe167bea 100644 --- a/modules/juce_gui_basics/native/juce_Windowing_ios.mm +++ b/modules/juce_gui_basics/native/juce_Windowing_ios.mm @@ -498,12 +498,6 @@ bool Desktop::isScreenSaverEnabled() return ! [[UIApplication sharedApplication] isIdleTimerDisabled]; } -//============================================================================== -bool detail::WindowingHelpers::areThereAnyAlwaysOnTopWindows() -{ - return false; -} - //============================================================================== Image detail::WindowingHelpers::createIconForFile (const File&) { diff --git a/modules/juce_gui_basics/native/juce_Windowing_linux.cpp b/modules/juce_gui_basics/native/juce_Windowing_linux.cpp index a386fc8931..c73b07dd02 100644 --- a/modules/juce_gui_basics/native/juce_Windowing_linux.cpp +++ b/modules/juce_gui_basics/native/juce_Windowing_linux.cpp @@ -26,10 +26,6 @@ namespace juce { -//============================================================================== -static int numAlwaysOnTopPeers = 0; -bool detail::WindowingHelpers::areThereAnyAlwaysOnTopWindows() { return numAlwaysOnTopPeers > 0; } - //============================================================================== class LinuxComponentPeer : public ComponentPeer, private XWindowSystemUtilities::XSettings::Listener @@ -48,7 +44,7 @@ public: return; if (isAlwaysOnTop) - ++numAlwaysOnTopPeers; + ++WindowUtilsInternal::numAlwaysOnTopPeers; repainter = std::make_unique (*this); @@ -79,7 +75,7 @@ public: xSettings->removeListener (this); if (isAlwaysOnTop) - --numAlwaysOnTopPeers; + --WindowUtilsInternal::numAlwaysOnTopPeers; } ::Window getWindowHandle() const noexcept diff --git a/modules/juce_gui_basics/native/juce_Windowing_mac.mm b/modules/juce_gui_basics/native/juce_Windowing_mac.mm index 828bc4421c..3f87859cfe 100644 --- a/modules/juce_gui_basics/native/juce_Windowing_mac.mm +++ b/modules/juce_gui_basics/native/juce_Windowing_mac.mm @@ -464,16 +464,6 @@ void Displays::findDisplays (const float masterScale) } } -//============================================================================== -bool detail::WindowingHelpers::areThereAnyAlwaysOnTopWindows() -{ - for (NSWindow* window in [NSApp windows]) - if ([window level] > NSNormalWindowLevel) - return true; - - return false; -} - //============================================================================== static void selectImageForDrawing (const Image& image) { diff --git a/modules/juce_gui_basics/native/juce_Windowing_windows.cpp b/modules/juce_gui_basics/native/juce_Windowing_windows.cpp index 38240fa02f..3ea7128f31 100644 --- a/modules/juce_gui_basics/native/juce_Windowing_windows.cpp +++ b/modules/juce_gui_basics/native/juce_Windowing_windows.cpp @@ -4775,37 +4775,6 @@ bool JUCE_CALLTYPE Process::isForegroundProcess() void JUCE_CALLTYPE Process::makeForegroundProcess() {} void JUCE_CALLTYPE Process::hide() {} -//============================================================================== -static BOOL CALLBACK enumAlwaysOnTopWindows (HWND hwnd, LPARAM lParam) -{ - if (IsWindowVisible (hwnd)) - { - DWORD processID = 0; - GetWindowThreadProcessId (hwnd, &processID); - - if (processID == GetCurrentProcessId()) - { - WINDOWINFO info{}; - - if (GetWindowInfo (hwnd, &info) - && (info.dwExStyle & WS_EX_TOPMOST) != 0) - { - *reinterpret_cast (lParam) = true; - return FALSE; - } - } - } - - return TRUE; -} - -bool detail::WindowingHelpers::areThereAnyAlwaysOnTopWindows() -{ - bool anyAlwaysOnTopFound = false; - EnumWindows (&enumAlwaysOnTopWindows, (LPARAM) &anyAlwaysOnTopFound); - return anyAlwaysOnTopFound; -} - //============================================================================== bool detail::MouseInputSourceList::addSource() { diff --git a/modules/juce_gui_basics/windows/juce_AlertWindow.cpp b/modules/juce_gui_basics/windows/juce_AlertWindow.cpp index 380ce4125b..6d756df7f4 100644 --- a/modules/juce_gui_basics/windows/juce_AlertWindow.cpp +++ b/modules/juce_gui_basics/windows/juce_AlertWindow.cpp @@ -50,7 +50,7 @@ AlertWindow::AlertWindow (const String& title, associatedComponent (comp), desktopScale (comp != nullptr ? Component::getApproximateScaleFactorForComponent (comp) : 1.0f) { - setAlwaysOnTop (detail::WindowingHelpers::areThereAnyAlwaysOnTopWindows()); + setAlwaysOnTop (WindowUtils::areThereAnyAlwaysOnTopWindows()); accessibleMessageLabel.setColour (Label::textColourId, Colours::transparentBlack); accessibleMessageLabel.setColour (Label::backgroundColourId, Colours::transparentBlack); diff --git a/modules/juce_gui_basics/windows/juce_CallOutBox.cpp b/modules/juce_gui_basics/windows/juce_CallOutBox.cpp index 357101d286..a7075c231c 100644 --- a/modules/juce_gui_basics/windows/juce_CallOutBox.cpp +++ b/modules/juce_gui_basics/windows/juce_CallOutBox.cpp @@ -39,7 +39,7 @@ CallOutBox::CallOutBox (Component& c, Rectangle area, Component* const pare } else { - setAlwaysOnTop (detail::WindowingHelpers::areThereAnyAlwaysOnTopWindows()); + setAlwaysOnTop (WindowUtils::areThereAnyAlwaysOnTopWindows()); updatePosition (area, Desktop::getInstance().getDisplays().getDisplayForRect (area)->userArea); addToDesktop (ComponentPeer::windowIsTemporary); diff --git a/modules/juce_gui_basics/windows/juce_DialogWindow.cpp b/modules/juce_gui_basics/windows/juce_DialogWindow.cpp index 561041f320..dfd8266819 100644 --- a/modules/juce_gui_basics/windows/juce_DialogWindow.cpp +++ b/modules/juce_gui_basics/windows/juce_DialogWindow.cpp @@ -92,7 +92,7 @@ public: setResizable (options.resizable, options.useBottomRightCornerResizer); setUsingNativeTitleBar (options.useNativeTitleBar); - setAlwaysOnTop (detail::WindowingHelpers::areThereAnyAlwaysOnTopWindows()); + setAlwaysOnTop (WindowUtils::areThereAnyAlwaysOnTopWindows()); } void closeButtonPressed() override diff --git a/modules/juce_gui_basics/windows/juce_WindowUtils.h b/modules/juce_gui_basics/windows/juce_WindowUtils.h new file mode 100644 index 0000000000..d2849fb6e7 --- /dev/null +++ b/modules/juce_gui_basics/windows/juce_WindowUtils.h @@ -0,0 +1,37 @@ +/* + ============================================================================== + + 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 +{ + +struct WindowUtils +{ + WindowUtils() = delete; + + /** Returns true if any windows have a z order that is higher than normal. */ + static bool areThereAnyAlwaysOnTopWindows(); +}; + +} // namespace juce