pinnacle icon indicating copy to clipboard operation
pinnacle copied to clipboard

Better window layering manipulation/always-on-top

Open anriha opened this issue 3 months ago • 11 comments

The current rendering of fullscreen windows cause few issues when using tiling mode. When a window is fullscreen, and you spawn a new one, it is drawn over it. For example, with MasterStack currently this happens:

  1. Open two windows in one workspace
  2. Make one of the windows fullscreen
  3. Spawn a third window

The newly spawned third window is rendered on top of the fullscreen window, obscuring it.

I propose to make it so that windows are rendered in explicit layers to solve this:

  1. Tiled windows (bottom)
  2. Fullscreen window (middle)
  3. Floating windows

I think this makes sense, as this would work correctly with fullscreen window in tiled mode. Whilst still having the ability to interact with floating windows, like file dialogs etc. that could open up when you are using fullscreen application.

If this model does make sense I am happy to start working on the PR to implement it.

anriha avatar Sep 22 '25 01:09 anriha

I wouldn't put floating window 'higher' than fullscreen ones. The usual behavior is to have them highest in the stack.

I think this makes sense, as this would work correctly with fullscreen window in tiled mode. Whilst still having the ability to interact with floating windows, like file dialogs etc. that could open up when you are using fullscreen application.

For these specific usecase, wayland client are supposed to use popups surfaces, not new windows. Popups could then have their z-index set higher than the others.

That being said, maybe a solution would be to have the ability to set an arbitrary z-level from the config.

Ph4ntomas avatar Sep 22 '25 07:09 Ph4ntomas

The current behavior is intended. Any defined ordering of windows would annoy one person or another:

  • Tiled -> Fullscreen -> Floating makes it impossible to view a fullscreen window in full if there's a floating window
  • Tiled -> Floating -> Fullscreen forces people to move floating windows out of the way if they want to see the tiles underneath
  • Any other ordering is pretty unusable imo

Plus it's how Awesome works. And personally if I'm opening a window while something is fullscreen it's probably because I want to use it immediately.

That being said, maybe a solution would be to have the ability to set an arbitrary z-level from the config.

Agreed, this is the best solution to force specific layering. Either as a normal API call or as a window rule like always-on-top.

Also,

I think this makes sense, as this would work correctly with fullscreen window in tiled mode. Whilst still having the ability to interact with floating windows, like file dialogs etc. that could open up when you are using fullscreen application.

For these specific usecase, wayland client are supposed to use popups surfaces, not new windows. Popups could then have their z-index set higher than the others.

Stuff like file dialogs definitely shouldn't be popups. Usually in this case the client sets the root window as the parent of the dialog with set_parent, in which case the compositor should stack it above (uh, we don't currently do this haha). There's also xdg-dialog but idk who's actually using that.

Ottatop avatar Sep 23 '25 22:09 Ottatop

Plus it's how Awesome works. And personally if I'm opening a window while something is fullscreen it's probably because I want to use it immediately.

This does make sense. But in that case, the current model is still not great. For example, we could unfullscreen the window if a new window spawns, that is what some WMs do, so that only one window can be fullscreen at the time.

I was considering that maybe the best way would be to add new signals for Window::Fullscreen and Window::Spawned (or possibly just use window rules). With that, it would be possible to get any of the specified behaviors, and then it would be up to the user to set what they would want.

I would also mention that, if we want to follow the xdg-shell protocol:

If the surface doesn't cover the whole output, the compositor will position the surface in the center of the output and compensate with with border fill covering the rest of the output. The content of the border fill is undefined, but should be assumed to be in some way that attempts to blend into the surrounding area (e.g. solid black). If the fullscreened surface is not opaque, the compositor must make sure that other screen content not part of the same surface tree (made up of subsurfaces, popups or similarly coupled surfaces) are not visible below the fullscreened surface.

I would argue that the current implementation doesn't follow that. But of course we don't have to follow it, just pointing it out.

anriha avatar Sep 23 '25 22:09 anriha

re Z-Layer: This is something I was planning on working on eventually, glad you're open to the idea

Re always on top: This is its own can of worm, because you need to track which window is the highest, so I guess that should be done at the same time/after the arbitrary z-layer.

Stuff like file dialogs definitely shouldn't be popups. [...]

Woops, you're right. I've confused the popups and xdg-dialogs

Ph4ntomas avatar Sep 23 '25 22:09 Ph4ntomas

For example, we could unfullscreen the window if a new window spawns, that is what some WMs do, so that only one window can be fullscreen at the time.

I would very much prefer this handled from the config (through window rules & signals) than a hardcoded behavior. The reason I chose to go with WM like awesome or Pinnacle is that I can customize the behavior as I see fit and stuff don't happen automagically - unless I want them to. Removing fullscreen without my intervention would kinda go against that.

I would also mention that, if we want to follow the xdg-shell protocol: [...] But of course we don't have to follow it, just pointing it out.

I'm pretty sure the goal is to implement the protocols as best as possible, but I fail to see how it relates to this issue.

The first paragraph mentions padding the surface itself (not sure if implemented, but that's unrelated to stacking, and a transparent fill is technically valid). The second only mention surface below the fullscreened one, and basically mandate stripping the transparency, but says nothing about the stacking order

Ph4ntomas avatar Sep 23 '25 23:09 Ph4ntomas

I would very much prefer this handled from the config (through window rules & signals) than a hardcoded behavior. The reason I chose to go with WM like awesome or Pinnacle is that I can customize the behavior as I see fit and stuff don't happen automagically - unless I want them to. Removing fullscreen without my intervention would kinda go against that.

I definitely agree, that is what I really like about pinnacle. I think that the approach with the fullscreen signal and spawn, would be ideal as that would give all the tools necessary to make all the proposed solutions here in your config. There already window raise that should bring the window to the front. With that I think that should support all the use cases described here.

The second only mention surface below the fullscreened one, and basically mandate stripping the transparency, but says nothing about the stacking order

I was reading the second part as that nothing that is not part of the same surface tree should be visible. Meaning that other windows not connected to the fullscreen one should be visible. But maybe I am misreading this.

anriha avatar Sep 23 '25 23:09 anriha

I was reading the second part as that nothing that is not part of the same surface tree should be visible.

"other screen content not part of the same surface tree (made up of subsurfaces, popups or similarly coupled surfaces) are not visible below the fullscreened surface."

I think this just means the fullscreen window should obscure everything beneath it except for its own subsurfaces/child windows/popups. Which is something we're totally violating btw, honestly not a fan of that bit of the protocol. Whether I decide to become conformant remains to be seen

Ottatop avatar Sep 24 '25 00:09 Ottatop

I understood it as, everything apart from the surface tree, should not be visible and below the fullscreen surface. But honestly, not really sure which reading is correct. I would say that for something like pinnacle where users are supposed to be making these choices it doesn't matter much, if we have tools to support all options.

anriha avatar Sep 24 '25 00:09 anriha

Uh @Ottatop can we re-open this one ? The PR doesn't address the layering of window, and I was planning to work on that & always-on-top at some point.

Or do you want me to open a new one when I plan to work on it ? (Likely not before 0.2 is released anyway

Ph4ntomas avatar Oct 22 '25 19:10 Ph4ntomas

Oh wasn't paying attention to which issue that pr closed

Ottatop avatar Oct 22 '25 19:10 Ottatop

Thanks !

Ph4ntomas avatar Oct 22 '25 20:10 Ph4ntomas