1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-10 23:44:24 +00:00

X11: Use the _NET_WM_STATE_HIDDEN property to determine whether peers are visible on-screen

Running under Gnome, calling ComponentPeer::forceSetBounds immediately
after creating a new peer causes the peer to emit a visibility-changed
event because the window manager sometimes reports that the new window
is in IconicState.

_NET_WM_STATE_HIDDEN seems to more accurately reflect whether the window
is really minimised or off-screen.
This commit is contained in:
reuk 2023-07-20 13:42:56 +01:00
parent 6694160fab
commit f8d38edcd4
No known key found for this signature in database
GPG key ID: FCB43929F012EE5C
3 changed files with 41 additions and 43 deletions

View file

@ -464,8 +464,7 @@ private:
// This issue only occurs right after peer creation, when the image is
// null. Updating when only the width or height is changed would lead to
// incorrect behaviour.
peer.forceSetBounds (detail::ScalingHelpers::scaledScreenPosToUnscaled (peer.component,
peer.component.getBoundsInParent()),
peer.forceSetBounds (detail::ScalingHelpers::scaledScreenPosToUnscaled (peer.component, peer.component.getBoundsInParent()),
peer.isFullScreen());
}
}

View file

@ -1932,23 +1932,9 @@ void XWindowSystem::setMinimised (::Window windowH, bool shouldBeMinimised) cons
}
}
bool XWindowSystem::isMinimised (::Window windowH) const
bool XWindowSystem::isMinimised (::Window w) const
{
jassert (windowH != 0);
XWindowSystemUtilities::ScopedXLock xLock;
XWindowSystemUtilities::GetXProperty prop (display, windowH, atoms.state, 0, 64, false, atoms.state);
if (prop.success && prop.actualType == atoms.state
&& prop.actualFormat == 32 && prop.numItems > 0)
{
unsigned long state;
memcpy (&state, prop.data, sizeof (unsigned long));
return state == IconicState;
}
return false;
return isHidden (w);
}
void XWindowSystem::setMaximised (::Window windowH, bool shouldBeMaximised) const
@ -3732,35 +3718,46 @@ void XWindowSystem::handleGravityNotify (LinuxComponentPeer* peer) const
peer->handleMovedOrResized();
}
bool XWindowSystem::isIconic (Window w) const
{
jassert (w != 0);
XWindowSystemUtilities::ScopedXLock xLock;
XWindowSystemUtilities::GetXProperty prop (display, w, atoms.state, 0, 64, false, atoms.state);
if (prop.success && prop.actualType == atoms.state
&& prop.actualFormat == 32 && prop.numItems > 0)
{
unsigned long state;
memcpy (&state, prop.data, sizeof (unsigned long));
return state == IconicState;
}
return false;
}
bool XWindowSystem::isHidden (Window w) const
{
XWindowSystemUtilities::ScopedXLock xLock;
XWindowSystemUtilities::GetXProperty prop (display, w, atoms.windowState, 0, 128, false, XA_ATOM);
if (! (prop.success && prop.actualFormat == 32 && prop.actualType == XA_ATOM))
return false;
const auto* data = unalignedPointerCast<const long*> (prop.data);
const auto end = data + prop.numItems;
return std::find (data, end, atoms.windowStateHidden) != end;
}
void XWindowSystem::propertyNotifyEvent (LinuxComponentPeer* peer, const XPropertyEvent& event) const
{
const auto isStateChangeEvent = [&]
if ((event.atom == atoms.state && isIconic (event.window))
|| (event.atom == atoms.windowState && isHidden (event.window)))
{
if (event.atom != atoms.state)
return false;
return isMinimised (event.window);
};
const auto isHidden = [&]
{
if (event.atom != atoms.windowState)
return false;
XWindowSystemUtilities::ScopedXLock xLock;
XWindowSystemUtilities::GetXProperty prop (display, event.window, atoms.windowState, 0, 128, false, XA_ATOM);
if (! (prop.success && prop.actualFormat == 32 && prop.actualType == XA_ATOM))
return false;
const auto* data = unalignedPointerCast<const long*> (prop.data);
const auto end = data + prop.numItems;
return std::find (data, end, atoms.windowStateHidden) != end;
};
if (isStateChangeEvent() || isHidden())
dismissBlockingModals (peer);
}
if (event.atom == XWindowSystemUtilities::Atoms::getIfExists (display, "_NET_FRAME_EXTENTS"))
peer->updateBorderSize();

View file

@ -294,6 +294,8 @@ private:
void updateModifierMappings() const;
long getUserTime (::Window) const;
bool isHidden (Window) const;
bool isIconic (Window) const;
void initialiseXSettings();