@@ -122,6 +122,8 @@ namespace juce | |||||
{ | { | ||||
return Process::isForegroundProcess() || isEmbeddedInForegroundProcess (viewComponent); | return Process::isForegroundProcess() || isEmbeddedInForegroundProcess (viewComponent); | ||||
} | } | ||||
bool isWindowOnCurrentVirtualDesktop (void*); | |||||
} | } | ||||
#include "accessibility/juce_AccessibilityHandler.cpp" | #include "accessibility/juce_AccessibilityHandler.cpp" | ||||
@@ -373,7 +375,56 @@ namespace juce | |||||
} | } | ||||
//============================================================================== | //============================================================================== | ||||
#if ! JUCE_WINDOWS | |||||
#if JUCE_WINDOWS | |||||
bool juce::isWindowOnCurrentVirtualDesktop (void* x) | |||||
{ | |||||
if (x == nullptr) | |||||
return false; | |||||
static auto* desktopManager = [] | |||||
{ | |||||
// IVirtualDesktopManager Copied from ShObjdl_core.h, because it may not be defined | |||||
MIDL_INTERFACE ("a5cd92ff-29be-454c-8d04-d82879fb3f1b") | |||||
juce_IVirtualDesktopManager : public IUnknown | |||||
{ | |||||
public: | |||||
virtual HRESULT STDMETHODCALLTYPE IsWindowOnCurrentVirtualDesktop( | |||||
__RPC__in HWND topLevelWindow, | |||||
__RPC__out BOOL * onCurrentDesktop) = 0; | |||||
virtual HRESULT STDMETHODCALLTYPE GetWindowDesktopId( | |||||
__RPC__in HWND topLevelWindow, | |||||
__RPC__out GUID * desktopId) = 0; | |||||
virtual HRESULT STDMETHODCALLTYPE MoveWindowToDesktop( | |||||
__RPC__in HWND topLevelWindow, | |||||
__RPC__in REFGUID desktopId) = 0; | |||||
}; | |||||
juce_IVirtualDesktopManager* result = nullptr; | |||||
JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wlanguage-extension-token") | |||||
class DECLSPEC_UUID("aa509086-5ca9-4c25-8f95-589d3c07b48a") juce_VirtualDesktopManager; | |||||
if (SUCCEEDED (CoCreateInstance (__uuidof (juce_VirtualDesktopManager), nullptr, CLSCTX_ALL, IID_PPV_ARGS (&result)))) | |||||
return result; | |||||
JUCE_END_IGNORE_WARNINGS_GCC_LIKE | |||||
return static_cast<juce_IVirtualDesktopManager*> (nullptr); | |||||
}(); | |||||
BOOL current = false; | |||||
if (auto* dm = desktopManager) | |||||
if (SUCCEEDED (dm->IsWindowOnCurrentVirtualDesktop (static_cast<HWND> (x), ¤t))) | |||||
return current != false; | |||||
return true; | |||||
} | |||||
#else | |||||
bool juce::isWindowOnCurrentVirtualDesktop (void*) { return true; } | |||||
juce::ScopedDPIAwarenessDisabler::ScopedDPIAwarenessDisabler() { ignoreUnused (previousContext); } | juce::ScopedDPIAwarenessDisabler::ScopedDPIAwarenessDisabler() { ignoreUnused (previousContext); } | ||||
juce::ScopedDPIAwarenessDisabler::~ScopedDPIAwarenessDisabler() {} | juce::ScopedDPIAwarenessDisabler::~ScopedDPIAwarenessDisabler() {} | ||||
#endif | #endif |
@@ -75,7 +75,8 @@ private: | |||||
JUCE_DECLARE_NON_COPYABLE (ShadowWindow) | JUCE_DECLARE_NON_COPYABLE (ShadowWindow) | ||||
}; | }; | ||||
class ParentVisibilityChangedListener : public ComponentListener | |||||
class ParentVisibilityChangedListener : public ComponentListener, | |||||
private Timer | |||||
{ | { | ||||
public: | public: | ||||
ParentVisibilityChangedListener (Component& r, ComponentListener& l) | ParentVisibilityChangedListener (Component& r, ComponentListener& l) | ||||
@@ -83,6 +84,9 @@ public: | |||||
{ | { | ||||
if (auto* firstParent = root->getParentComponent()) | if (auto* firstParent = root->getParentComponent()) | ||||
updateParentHierarchy (firstParent); | updateParentHierarchy (firstParent); | ||||
if ((SystemStats::getOperatingSystemType() & SystemStats::Windows) != 0) | |||||
startTimerHz (20); | |||||
} | } | ||||
~ParentVisibilityChangedListener() override | ~ParentVisibilityChangedListener() override | ||||
@@ -146,6 +150,11 @@ private: | |||||
withDifference (observedComponents, lastSeenComponents, [this] (auto& comp) { comp.addComponentListener (this); }); | withDifference (observedComponents, lastSeenComponents, [this] (auto& comp) { comp.addComponentListener (this); }); | ||||
} | } | ||||
void timerCallback() override | |||||
{ | |||||
listener->componentVisibilityChanged (*root); | |||||
} | |||||
Component* root = nullptr; | Component* root = nullptr; | ||||
ComponentListener* listener = nullptr; | ComponentListener* listener = nullptr; | ||||
std::set<ComponentWithWeakReference> observedComponents; | std::set<ComponentWithWeakReference> observedComponents; | ||||
@@ -246,15 +255,11 @@ void DropShadower::updateShadows() | |||||
const ScopedValueSetter<bool> setter (reentrant, true); | const ScopedValueSetter<bool> setter (reentrant, true); | ||||
if (owner == nullptr) | |||||
{ | |||||
shadowWindows.clear(); | |||||
return; | |||||
} | |||||
if (owner->isShowing() | |||||
&& owner->getWidth() > 0 && owner->getHeight() > 0 | |||||
&& (Desktop::canUseSemiTransparentWindows() || owner->getParentComponent() != nullptr)) | |||||
if (owner != nullptr | |||||
&& owner->isShowing() | |||||
&& owner->getWidth() > 0 && owner->getHeight() > 0 | |||||
&& (Desktop::canUseSemiTransparentWindows() || owner->getParentComponent() != nullptr) | |||||
&& isWindowOnCurrentVirtualDesktop (owner->getWindowHandle())) | |||||
{ | { | ||||
while (shadowWindows.size() < 4) | while (shadowWindows.size() < 4) | ||||
shadowWindows.add (new ShadowWindow (owner, shadow)); | shadowWindows.add (new ShadowWindow (owner, shadow)); | ||||