KZDKM / Hyprspace

Workspace overview plugin for Hyprland
GNU General Public License v2.0
285 stars 9 forks source link

Exclusivity: Add option to draw-on-top - without exclusivity (would not resize hyprland clients). #19

Closed nine7nine closed 4 weeks ago

nine7nine commented 1 month ago

First off: love the plugin! very cool.

That said: it would be nice if there was an option to make hyprspace/overview non-exclusive, meaning it would draw-on-top, but not resize apps / hyprland clients.

  1. switching workspaces would be smoother, without the resizing happening
  2. the preview wouldn't include the offset in the active worksapce

you can see what i am talking about in this video:

https://github.com/KZDKM/Hyprspace/assets/20159346/054c6902-6a7c-4344-8efd-3a5a40d44b93

  1. you can also see the case where I show the overview, but close it - then return to the previous workspace, which then resizes the windows/clients, and also slows down animations.

it would be nice to have a more static mode, where it draws-on-top and doesn't touch / resize hyprland clients. (I guess more like a conventional overview/workspace switcher)

KZDKM commented 1 month ago

Thanks for the suggestion, I've been trying to implement this feature for quite a while now, but it would require rework on the rendering routine so that the panel renders above all windows while the dragged window could still render above the panel. It is certainly possible though.

nine7nine commented 1 month ago

ah, that makes sense -- and I assumed this had to be on your radar!

question: is there a quick and dirty way to do this, if one doesn't care about dragged windows appearing on top?

i did poke around your plugin code, but I'm fairly unfamiliar with hyprland code / it's been a while since I touched any C++ (more C, Python, Typescript, etc). I am aware Layer Shell does allow changing exclusivity though, but It wasn't immediately obvious how I might set it to be non-exclusive...

and yeah, I noticed if I was using floating windows -- Hyprspace would render behind. expected though, given how it currently works.

KZDKM commented 1 month ago

This is not a layer shell, a layer shell from a external program would not have any proper way of rendering windows / layers from the compositor that is hosting it (hyprland). To do that one have to interface with the compositor and hence this is a plugin and not something you would launch like waybar or ags. I had to explicitly rearrange the layout in code.

For a quick and dirty hack, change the currentHeight in Layout.cpp to 0 and change the RENDER_STAGE_PRE_WINDOWS to RENDER_STAGE_POST_WINDOWS and delete the other RENDER_STAGE_POST_WINDOWS if case and comment out the setValueAndWarp line in the onRender function in main.cpp

Implementing this feature properly is quite trivial though and I will get on it when I have time.

nine7nine commented 1 month ago

Thanks for taking the time to explain. It's appreciated.

So I've been playing around with this quick hack (it works!). That said; there is a gotcha or two (at least with my setup!), but probably things to consider for a proper feature...

--- a/src/Layout.cpp
+++ b/src/Layout.cpp
@@ -3,7 +3,7 @@

 // FIXME: preserve original workspace rules
 void CHyprspaceWidget::updateLayout() {
-    const auto currentHeight = Config::panelHeight + Config::reservedArea;
+    const auto currentHeight = 36;
     const auto pMonitor = getOwner();
     // reset reserved areas
     g_pHyprRenderer->arrangeLayersForMonitor(ownerID);
@@ -17,14 +17,6 @@ void CHyprspaceWidget::updateLayout() {
     if (active) {
         const auto oActiveWorkspace = pMonitor->activeWorkspace;

-        for (auto& ws : g_pCompositor->m_vWorkspaces) { // HACK: recalculate other workspaces without reserved area
-            if (ws->m_iMonitorID == ownerID && ws->m_iID != oActiveWorkspace->m_iID) {
-                pMonitor->activeWorkspace = ws;
-                const auto curRules = std::to_string(pMonitor->activeWorkspaceID()) + ", gapsin:" + PGAPSIN->toString() + ", gapsout:" + PGAPSOUT->toString();
-                if (Config::overrideGaps) g_pConfigManager->handleWorkspaceRules("", curRules);
-                g_pLayoutManager->getCurrentLayout()->recalculateMonitor(ownerID);
-            }
-        }
         pMonitor->activeWorkspace = oActiveWorkspace;
         pMonitor->vecReservedTopLeft.y = currentHeight;
         const auto curRules = std::to_string(pMonitor->activeWorkspaceID()) + ", gapsin:" + std::to_string(Config::gapsIn) + ", gapsout:" + std::to_string(Config::gapsOut);

I needed to do a couple of extra things to actually have static windows, when using hyprspace:

After that, it works perfectly... no resizing or shifting of apps/client windows... So it may be that you want some kind of plugin / hyprland.conf setting for handling the case where there is a panel or reserved space like that; setting the currentHeight as that...?

....

Side note: I'm also playing with more tight integration: showing the layers in my shell, while using hyprspace's overview: (obviously, this does add a minor input issue you are trying to avoid!)

hyprspace-ags

I just had to make use of that reservedArea setting, to account for my panel - but it integrates very well. super cool! This is the kind of thing I'm going for, when using your plugin... The only downside (atm), it seems to slow down workspace switching slightly. not sure why yet.

EDIT: AGS and some of it's layerrule / batch settings on startup cause the slowdowns - nothing to do with your plugin! working laser fast now. ;-)

KZDKM commented 4 weeks ago

Resolved with https://github.com/KZDKM/Hyprspace/commit/26b9b648b798b8f69a29a5f230333f319c61ca54.

nine7nine commented 4 weeks ago

@KZDKM - Just gave this a whirl; works great. I can actually click on a workspace (with autoDrag enabled) and it is no longer grabbing the windows/clients below. Perfect. Thanks!