Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Standalone Monocle Layout #2050

Open
eadwu opened this issue Apr 14, 2023 · 30 comments
Open

Standalone Monocle Layout #2050

eadwu opened this issue Apr 14, 2023 · 30 comments
Labels
enhancement New feature or request

Comments

@eadwu
Copy link

eadwu commented Apr 14, 2023

Main reason is to view status bars. Fullscreen provides a monocle experience but in the process takes over the space for status bars.

Moving eww over to the overlay layer keeps it shown everywhere, but it no longer reserves any space even with :exclusive.

I do not think any window rule allows this to happen (preserve reserved space by other windows in fullscreen).

@eadwu eadwu added the enhancement New feature or request label Apr 14, 2023
@kcrmson
Copy link

kcrmson commented Apr 14, 2023

You'll want to try using "hyprctl dispatch fullscreen 1" on a floating window and it should keep the status bar visible while remaining in fullscreen mode. I just verified it now using qutebrowser (once made floating) but it didn't seem to affect it when tiled.

@eadwu
Copy link
Author

eadwu commented Apr 14, 2023

Nice, that gets it closer. Introduces a problem when you actually try to enter fullscreen though, i.e. on a video player.

I rather think that is actually a bug instead of actually working like that.

I'll eventually look at the codebase to give it a stab at implementing myself since this is a layout I do quite need to go about... just a couple few windows of a browser but just sticking it out there in case it is easy to implement (though I'm not sure how intertwined layouts are in wayland given that there are only 2 still).

@vaxerski
Copy link
Member

vaxerski commented Apr 14, 2023

no_gaps_when_only + one group?

Moving eww over to the overlay layer keeps it shown everywhere, but it no longer reserves any space even with :exclusive.

set custom reserved area?

@eadwu
Copy link
Author

eadwu commented Apr 15, 2023

One group will provide a standalone monocle layout. It is not compatible with cyclenext and swapnext (with changegroupactive being a replacement for cyclenext and swapnext not having any equivalent from the dispatchers).

If I am interpreting the custom reserved area correctly, that will mean it will still be reserved when I really want fullscreen, i.e. watching a movie.

For my intents togglegroup will be enough to mimic my daily workflow from Xorg tiling managers (should be covered by monocle and dwindle), I will not be mixing groups with non-monocle layouts so binding changegroupactive to the same action I have for cyclenext should work without issue.

I'm still looking into the docs to figure out the best way to move all windows in the workspace into or out of a group but it should be possible whether I have to define a plugin or invoke hyprctl (looks like I found #1994 which I can either use as a reference).

@vaxerski
Copy link
Member

If I am interpreting the custom reserved area correctly, that will mean it will still be reserved when I really want fullscreen, i.e. watching a movie.

No. It works like a bar, but for bars that don't do that by themselves.

I will not be mixing groups with non-monocle layouts so binding changegroupactive to the same action I have for cyclenext should work without issue.

You can write a simple script for this

@misuzu
Copy link

misuzu commented Jul 26, 2023

This is the only feature that I'm using on dwm that's missing, everything else is there. fullscreen, 1 is not the same.

@charbelnicolas
Copy link

This is the only feature that is keeping me from switching from awesome wm. I'd love to have a native hyprland monocle implementation.

@KunaPrime
Copy link

absolutely, this is feature that is essential for most of my workflows

@adwaymalhotra
Copy link

I miss the different margin values for monocle mode from my BSPWM days. I want a larger margin for monocle mode

Also, if we're doing feature requests, I would also like something like the Stage Manager feature from MacOS where the non-visible windows are "minimized" to the side or bottom when we're in this monocle mode with small thumbnails. It is sort of like a master layout with the master centered but the slave windows don't resize (resizing messes up the content rendering within the window).

@zelfroster
Copy link

zelfroster commented Feb 16, 2024

@vaxerski sorry for pinging, any thoughts about implementing this?

Edit: Actually hyprctl dispatch fullscreen 1 works for my usecase, still a standard monocle layout would be much cooler.

@vaxerski
Copy link
Member

my thoughts? "No, write a plugin?"

@neuromagus
Copy link

neuromagus commented Feb 19, 2024

my thoughts? “No, should I write a plugin?”

all tiled WMs I worked with before using DWL (DWM, Xmonad) have Monocle mode (in Haskell's full screen mode). IMHO, this behavior should be added to the main mode and given the opportunity to choose.

I use many monitors every day, one in the center is always in Monocle, the rest switch to the Tile layout.
At home, I use one large 60-inch monitor with customizable workspaces set to Monocle or Tile mode (if I need to see more than one window). And this workplace is widespread among my friends...

@vaxerski
Copy link
Member

why not make a windowrule to maximize every tiled window? would behave the same I believe

@neuromagus
Copy link

neuromagus commented Feb 19, 2024

why not make a windowrule to maximize every tiled window? would behave the same I believe

Do you have an example of these settings? I'll try to compare the user experience with Hypr and, for example, DWM with Monocle.

this code from dwm.c

#define ISVISIBLE(C)            ((C->tags & C->mon->tagset[C->mon->seltags]))

void
monocle(Monitor *m)
{
    unsigned int n = 0;
    Client *c;

    for (c = m->clients; c; c = c->next)
        if (ISVISIBLE(c))
            n++;
    if (n > 0) /* override layout symbol */
        snprintf(m->ltsymbol, sizeof m->ltsymbol, "[%d]", n);
    for (c = nexttiled(m->clients); c; c = nexttiled(c->next))
        resize(c, m->wx, m->wy, m->ww - 2 * c->bw, m->wh - 2 * c->bw, 0);
}

@luravoid
Copy link

luravoid commented Apr 2, 2024

It would be nice to have monocle tabbed orientation for master layout

@eadwu
Copy link
Author

eadwu commented Apr 7, 2024

Just realized I never posted what I use, I'm not sure if this all the configuration but it looks right by this comment I left there, the following works in 99% of cases - the most glaring issue is that it is still virtually tiled, so switching windows always imposes a resize operation - which is an sometimes an annoying delay to wait for.

Full screen should be able to take over any reserved space.

# Reset the layouts on the current workspace to default (monocle-ish)
bind = $mainMod SHIFT, space, exec, hyprctl dispatch fullscreen 1
bind = $mainMod SHIFT, space, exec, togglegroup

@Ferk
Copy link

Ferk commented Apr 16, 2024

the most glaring issue is that it is still virtually tiled, so switching windows always imposes a resize operation - which is an sometimes an annoying delay to wait for.

Yes... the animation when switching windows after setting "fullscreen 1" is annoying, specially because it actually does make some windows change the content/internal layout as they are being resized, it adds delays and the repositioning can be confusing.

I was expecting to be able to get rid of this form of animation tweaking the Animations configuration, but I did not manage to find which setting would I need to set to disable this. Does anybody know?

This is all a very awkward workaround. A monocle style layout being properly supported would be best.

@zakk4223
Copy link
Contributor

zakk4223 commented May 1, 2024

I made a monocle layout: https://github.com/zakk4223/hyprlandMonocle

The layout sets all windows to the monitor/workspace size, honoring reserved space.
The currently focused window is set to maximized. This is to work around the fact you cannot have overlapping tiled windows in Hyprland without introducing focus issues.

Setting the window sizes to the maximized size should prevent resizing apps on window switching.

You can navigate between windows using Hyprland's standard cyclenext or movefocus dispatchers.

If you want to run monocle only on one workspace/monitor, see: https://github.com/zakk4223/hyprWorkspaceLayouts

@luravoid
Copy link

luravoid commented May 2, 2024

@zakk4223 Thanks for the plugin, but I think one of the biggest advantages of the monocle layout in other window managers is the ability to toggle the layout between a tile layout and a monocle layout that mirrors the position of the windows. So unfortunately your plugin has no usecase for me.

Check out this video on how it works in xmonad. Imo this is the perfect implementation of the monocle layout, it mirrors the window position and has tabs as well. The monocle layout also works in a similar way in AwesomeWM and DWM.

2024-05-02.15-41-42.mp4

I think in Hyprland it would be preferable to implement it as another master layout orientation, but I don't have idea how to make it work also with dwindle layout.

@vaxerski
Copy link
Member

vaxerski commented May 2, 2024

looks like a fullscreen group with extra steps

@zakk4223
Copy link
Contributor

zakk4223 commented May 2, 2024

Using a group for this has issues:

  1. windows in groups cannot be navigated with the normal dispatchers (cyclenext, etc). You have to switch to the group navigation ones. I guess you could do some submap twiddling, but now you have to track which layout is active, you have to deal with the active workspace being changed etc.

  2. if you want to gather all windows on the current workspace into a group you have to...I guess write a shell script?

Either of these are probably manageable if you're using stock Hyprland, but if you're using extra layouts, per workspace/monitor layouts etc it's not going to be as easy to do.

You can dynamically switch to this monocle layout if you use my workspacelayout plugin and bind a key to send the 'layoutmsg setlayout monocle' dispatch. (I think I have some ideas to make layout switching better in that plugin too...). However you still have the window order issue...

I don't think the 'preserving window order' thing is doable in Hyprland without each individual layout being forced to implement monocle themselves. Layouts can have an internal concept of window order. They can manipulate hyprland's window order to some degree but none of them currently do this.

@luravoid
Copy link

luravoid commented May 2, 2024

I thought so that preserving window order for each separate layout is not doable, so that's why I proposed that maybe the monocle layout should be the orientation for the master layout, just like the centeredmaster layout is called orientation center in hyprland.

And as for the replicating monocle layout with groups. Someone created a script that gathers all the windows in the workspace into a group. It does it in a kinda hacky way because in the current moment there is no possibility to add windows to group by address so they are added with directional dispatchers.
https://gist.github.com/Atrate/b08c5b67172abafa5e7286f4a952ca4d#file-hyprtabs-sh

Of course the biggest weakness of this script is that it doesn't preserve the window order when toggling and untoggling the group.

@TAforever
Copy link

I also want the monocle layout to be implemented in hyprland, but since configuration options such as new_window_takes_over_fullscreen and exit_window_retains_fullscreen have been added, the behavior of monocle can be easily emulated with a simple script. The disadvantage of this is that the windows change size when switching

#!/bin/bash

fullscreenstatus=$(hyprctl activewindow | grep fullscreenClient | awk '{print $2}')
if [ $fullscreenstatus != 1 ]; then
    hyprctl keyword misc:new_window_takes_over_fullscreen 1
    hyprctl keyword misc:exit_window_retains_fullscreen true
    hyprctl dispatch fullscreen 1
else
    hyprctl keyword misc:new_window_takes_over_fullscreen 2
    hyprctl keyword misc:exit_window_retains_fullscreen false
    hyprctl dispatch fullscreen 1
fi

@saipavanc
Copy link

Just adding a comment to bump up this request. Monocle mode is really useful for my workflow as well, and has several use cases when it makes things a lot more efficient. I did see some options where one can use things like pypr to change into monocle mode, but it is not easy to get back to a neatly tiled form. Can anyone mention if there is any technical difficulty in storing the tiled layout and applying it again when switching out of monocle mode? I am not sure I understand what makes this challenging here, as it is implemented in many other tiling managers.

@vaxerski
Copy link
Member

You can use fullscreen,1 and cyclenext for a more-or-less monocle mode. For more advanced, you can write your own script or plugin.

@zakk4223
Copy link
Contributor

The fullscreen thing works ok but it causes resize events when windows swap in and out of focus, which some people would like to avoid.

I've tried to do it with a layout that keeps all the windows the same size, but hyprland reacts poorly to tiled layouts with overlapping windows. I think that's probably fixable with hooking a few functions but I hate maintaining plugins that hook really deep+important functions because now that's one more thing I have to pay attention to.

Even with a plugin you probably need an additional plugin for per monitor/workspace layouts. But even then there's no sane way to have a workflow where you have a tiled workspace, then switch it to monocle and then switch back to the tiled workspace with all state preserved. Switching layouts 'removes' windows from the existing layout and thus destroys any state.

If you're ok with windows getting resized on focus change, then just do the fullscreen+cyclenext thing. Otherwise there's no real solution at the moment.

@vaxerski
Copy link
Member

the resizing is a separate issue that some people want "fixed" anyways.

Why not ->setHidden() for windows not visible? I think that would fix most of the problems.

@zakk4223
Copy link
Contributor

hidden windows get skipped by cycleNext etc.

@vaxerski
Copy link
Member

vaxerski commented Dec 30, 2024

myMonoclePlugin:cycleNext

There is also the hypr way, move them to narnia (-69420, -69420) and just instantly snap them on focus change to the right pos

@zakk4223
Copy link
Contributor

Oh hmm, I'll try the narnia thing.

Eh, custom dispatchers for layout window management are annoying, I'd rather use the global one and have it work sanely everywhere if possible. I actually use multiple layouts so having different binds is bleh.

Could it just be changed so layouts get the ability to override get(Prev|Next)WindowOnWorkspace? Like just move that from the compositor to IHyprLayout? It looks like the only things that use those functions are cycle and swap anyways.

That or make g_pCompositor:m_vWindows exclusively for rendering and have another window list for swap/cycle window stack manipulation. Right now anything that uses changeWindowZOrder completely messes up window cycle order

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests