# Setting a Linux Window Always on Top Without Re-creating the Peer

**URL:** <https://forum.juce.com/t/setting-a-linux-window-always-on-top-without-re-creating-the-peer/23489>\
**Category:** Linux\
**Created:** [July 27, 2017, 8:56pm UTC](https://forum.juce.com/t/setting-a-linux-window-always-on-top-without-re-creating-the-peer/23489 "2017-07-27T20:56:50Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![dave96](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/dave96/32/8487_2.png) [@dave96](https://forum.juce.com/u/dave96)\
**Post date:** [July 27, 2017, 8:56pm UTC](https://forum.juce.com/t/setting-a-linux-window-always-on-top-without-re-creating-the-peer/23489/1 "2017-07-27T20:56:50Z")

</div>

Is there any way to set a Linux window to be alwaysOnTop _without_ having to re-create the peer?  
I’ve spent three days trying different ways to get plugin windows on Linux to behave correctly but they either disappear leaving a transparent, blocked, region on the screen, fall to the back when they should be always on top, open with a tiny size or the plugin UI fails to open and I’m left with just the window decorations. I can avoid one or the other of these problems but not all of then at once.

I have a feeling that if I can _open_ the window as always on top, or at the very least set it without re-creating the peer, my resizing problems will go away. Is there any chance this can be implemented? Is this even possible on Linux?

```
bool setAlwaysOnTop (bool /* alwaysOnTop */) override
{
    return false;
}
```

---

<div class="post-metadata">

**Author:** ![jrlanglois](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/jrlanglois/32/21372_2.png) [@jrlanglois](https://forum.juce.com/u/jrlanglois)\
**Post date:** [July 28, 2017, 12:15am UTC](https://forum.juce.com/t/setting-a-linux-window-always-on-top-without-re-creating-the-peer/23489/2 "2017-07-28T00:15:04Z")

</div>

This should be feasible by setting the `_NET_WM_STATE_ABOVE` flag on the window (as suggested by [https://stackoverflow.com/a/4347486](https://stackoverflow.com/a/4347486)).

Off hand I’m not sure how this translates into JUCE, so can’t help there…

---

<div class="post-metadata">

**Author:** ![fr810](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/fr810/32/841_2.png) [@fr810](https://forum.juce.com/u/fr810)\
**Post date:** [July 31, 2017, 11:31am UTC](https://forum.juce.com/t/setting-a-linux-window-always-on-top-without-re-creating-the-peer/23489/3 "2017-07-31T11:31:23Z")

</div>

Hi @dave96,

In addition to my answer on this post:

> [@Setting "alwaysOnTop (true)" for Linux Plugin Windows](https://forum.juce.com/t/setting-alwaysontop-true-for-linux-plugin-windows/23371):
>
> I have a problem setting plugin windows to be always on top after construction. At first I thought this was a problem with the way we handle plugin windows but now I’ve been able to replicate it in the JUCE plugin host demo. If you add the following code to the end of the PluginWindow constructor you’ll see after 5 seconds the plugin UI get incorrectly positioned and ence covers the title bar and any buttons that may be living there etc. Component::SafePointer\<Component\> sp (this); Timer::call…

the following diff should stop the peer from re-creating itself when you use `setAlwaysOnTop`. Can you confirm that this works for you? If yes, then I’ll push it to develop:

```
--- a/modules/juce_gui_basics/native/juce_linux_X11_Windowing.cpp
+++ b/modules/juce_gui_basics/native/juce_linux_X11_Windowing.cpp
@@ -1818,9 +1818,18 @@ public:
		 return {};
	 }

- bool setAlwaysOnTop (bool /* alwaysOnTop */) override
+ bool setAlwaysOnTop (bool alwaysOnTop) override
	 {
- return false;
+ if (alwaysOnTop != isAlwaysOnTop)
+ {
+ numAlwaysOnTopPeers += (alwaysOnTop ? 1 : -1);
+ jassert (numAlwaysOnTopPeers >= 0);
+
+ ScopedXLock xlock (display);
+ setWindowType();
+ }
+
+ return true;
	 }

	 void toFront (bool makeActive) override

```

---

<div class="post-metadata">

**Author:** ![dave96](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/dave96/32/8487_2.png) [@dave96](https://forum.juce.com/u/dave96)\
**Post date:** [August 1, 2017, 10:30am UTC](https://forum.juce.com/t/setting-a-linux-window-always-on-top-without-re-creating-the-peer/23489/4 "2017-08-01T10:30:11Z")

</div>

Hmm, I don’t think this quite works (I think I tried something similar in the past).  
It seems to bring the window to the front but not keep it always on top.

Does this work for you?  
If you add the following lines to the bottom of the plugin host `PluginWindow` constructor:

```
SafePointer<PluginWindow> pw (this);
Timer::callAfterDelay (5000, [pw] () mutable { if (pw != nullptr) pw->setAlwaysOnTop (true); });

```

Then I open the host, open a plugin UI and click the graph panel to send the UI to the back. After 5 seconds the window jumps to the front but if I click on the graph window, it slips to the back again.

* * *

It looks like the the `_NET_WM_STATE_ABOVE` is a hint which the window manager can ignore? Perhaps this is what’s happening? Looking over Google it might be that the Urgency flag needs to be set instead? [https://specifications.freedesktop.org/wm-spec/1.3/ar01s07.html#URGENCY](https://specifications.freedesktop.org/wm-spec/1.3/ar01s07.html#URGENCY)

---

<div class="post-metadata">

**Author:** ![original-picture](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/original-picture/32/22157_2.png) [@original-picture](https://forum.juce.com/u/original-picture)\
**Post date:** [August 2, 2025, 8:25pm UTC](https://forum.juce.com/t/setting-a-linux-window-always-on-top-without-re-creating-the-peer/23489/5 "2025-08-02T20:25:32Z")

</div>

Heya

I ended up getting this working on my fork

Here’s the code I used:

```cpp
bool XWindowSystem::setAlwaysOnTop (::Window windowH, bool shouldBeAlwaysOnTop)
{
    jassert (windowH != 0);

    if (atoms.windowStateAbove)
    {
        auto root = X11Symbols::getInstance()->xRootWindow (display, X11Symbols::getInstance()->xDefaultScreen (display));

        XClientMessageEvent clientMsg;
        clientMsg.display = display;
        clientMsg.window = windowH;
        clientMsg.type = ClientMessage;
        clientMsg.format = 32;
        clientMsg.message_type = atoms.windowState;
        clientMsg.data.l[0] = shouldBeAlwaysOnTop;
        clientMsg.data.l[1] = (long) atoms.windowStateAbove;
        clientMsg.data.l[2] = 0; // must be zero, because we're only setting one property
        clientMsg.data.l[3] = 1; // source is normal application

        XWindowSystemUtilities::ScopedXLock xLock;
        X11Symbols::getInstance()->xSendEvent (display,
                                               root,
                                               false,
                                               SubstructureRedirectMask | SubstructureNotifyMask,
                                               (XEvent*) &clientMsg);

        return true;
    }

    return false;
}

```

This has only been tested on ubuntu, but it seemed to work perfectly there

Edit: In my code, I added `atoms.windowStateAbove` to the `Atoms` struct in juce\_XWindowSystem\_linux.h

And in the `Atoms` constructor in juce\_XWindowSystem\_linux.cpp, this is how I construct it:

```cpp
windowStateAbove = getIfExists (display, "_NET_WM_STATE_ABOVE");

```
