baskerville / bspwm

A tiling window manager based on binary space partitioning
BSD 2-Clause "Simplified" License
7.72k stars 415 forks source link

Sticky fullscreen windows #298

Closed rr- closed 8 years ago

rr- commented 8 years ago

My use case looks like this:

  1. Have an empty workspace.
  2. Open a fullscreen window, let's call it A.
  3. Open a floating window, let's call it B.
  4. A goes from fullscreen back to its tiled state.

My problems with 4. are as follows:

  1. I see the gaps from the desktop + panel, which is a bit distracting (especially if the contrast is high)
  2. It causes A to rerender itself, which sometimes causes flicker (especially with ncurses based programs residing inside terminals)
  3. If there are other tiled windows, they get rearranged due to layout change, which distracts me even more.

Is there any chance to make A stay in fullscreen mode, while having B rendered on top of it (like it is when displaying on top of regular tiled windows)?

baskerville commented 8 years ago

My plan is to provide stacking layers (below, normal and above).

And to let the user decide how she wants to deal with fullscreen windows.

baskerville commented 8 years ago

It should be fixed by 40cdd64.

rr- commented 8 years ago

It works almost perfectly, but my panel (written in Qt) is now rendered on top of fullscreen windows. To illustrate this behavior - they overlap each other like this:

+--------------------+
| + - - - - - - - - -+-+ overlap, and panel is rendered on top of the window
+--------------------+ |
  |                    |
  |                    |
  |                    |
  |                    |
  |                    |
  +--------------------+

What doesn't happen:

+--------------------+
|                    | panel is recognized as a part of screen working area
+--------------------+-+
  |                    |
  |                    |
  |                    |
  |                    |
  |                    |
  +--------------------+

(sorry for lame ASCII.)

I tried creating window with Qt.WindowStaysOnBottomHint to no avail. I also tried to create a rule that would set the layer to below, but I seem to be unable to affect the panel's properties in any way...

Here are my panel's concrete characteristics:

_NET_WM_SYNC_REQUEST_COUNTER(CARDINAL) = 31457290
_MOTIF_WM_HINTS(_MOTIF_WM_HINTS) = 0x3, 0x3c, 0x7a, 0x0, 0x0
WM_TRANSIENT_FOR(WINDOW): window id # 0x1e00004
XdndAware(ATOM) = BITMAP
_MOTIF_DRAG_RECEIVER_INFO(_MOTIF_DRAG_RECEIVER_INFO) = 0x6c, 0x0, 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0
WM_CLIENT_LEADER(WINDOW): window id # 0x1e00004
_NET_WM_PID(CARDINAL) = 3442
_NET_WM_WINDOW_TYPE(ATOM) = _NET_WM_WINDOW_TYPE_SPLASH, _KDE_NET_WM_WINDOW_TYPE_OVERRIDE, _NET_WM_WINDOW_TYPE_NORMAL
WM_PROTOCOLS(ATOM): protocols  WM_DELETE_WINDOW, WM_TAKE_FOCUS, _NET_WM_PING, _NET_WM_SYNC_REQUEST
WM_NAME(STRING) = "panel"
WM_LOCALE_NAME(STRING) = "en_US.UTF-8"
WM_CLASS(STRING) = "panel", "Panel"
WM_HINTS(WM_HINTS):
        Client accepts input or input focus: True
        Initial state is Normal State.
        window id # of group leader: 0x1e00004
WM_NORMAL_HINTS(WM_SIZE_HINTS):
        user specified location: 0, 0
        program specified location: 0, 0
        user specified size: 3840 by 20
        program specified size: 3840 by 20
        program specified minimum size: 3840 by 20
        program specified maximum size: 3840 by 20
        window gravity: NorthWest
WM_CLIENT_MACHINE(STRING) = "tornado"
WM_COMMAND(STRING) = { "/home/rr-/.config/bspwm/panel" }

Note that I use _NET_WM_WINDOW_TYPE_SPLASH (Qt.SplashScreen) since anything else lets me resize the window, make it fullscreen etc which is obviously unwanted for panel.

EDIT: it seems that this atom type is equivalent to manage=off which makes it impossible to change window size, position etc. in regular ways, but it also seems to ignore layers altogether. I'm not sure if this is the correct behavior.

EDIT 2: I resolved this issue by creating a custom fullscreen script, that looks like this:

#!/bin/sh
# check if there are any fullscreen windows
bspc query -T | grep '[f-][d-][F][u-][l-][s-][i-][p-]' > /dev/null 2>&1
if [ "$?" == '0' ]; then
    bspc window -t fullscreen -l normal
    xdotool search --title panel windowmap # hide panel
else
    bspc window -t fullscreen -l above
    xdotool search --title panel windowunmap # restore panel
fi

Note that this doesn't restore panel if the fullscreen window is closed before restoring it to its tiled state, and it's suboptimal in multihead environments where the panel is hidden from all the screens.

rr- commented 8 years ago

Additionally, having a fullscreen window causes it to be included in tiling layout like this:

   +-fullscreen--------------+
   | +-tiled1--+ +-tiled2--+ |
   | |         | |         | |
   | |         | |         | |
   | |         | +---------+ |
   | |         |             |
   | |         |      !      |
   | |         |             |
   | +---------+             |
   +-------------------------+

EDIT: replacing bspc window -t fullscreen with bspc window -t fullscreen -l above in favorite shortcut manager mostly resolves this issue.

EDIT 2: having option to cycle between layers of choice would save a lot of scripting; I don't see any way to tell the window's current layer. Right now I'm using something like this to toggle fullscreen and layer:

#!/bin/sh
# check if there any fullscreen windows
bspc query -T | grep '[f-][d-][F][u-][l-][s-][i-][p-]' > /dev/null 2>&1
if [ "$?" == '0' ]; then
    bspc window -t fullscreen -l normal
else
    bspc window -t fullscreen -l above
fi
rr- commented 8 years ago

Most of the problems were solved with external scripts. :3 I'd close the issue, but maybe something in my comments catches your eye?

baskerville commented 8 years ago

As the commit message says fullscreen windows are no longer special.

The issue you're experiencing is linked to the fact that bspwm doesn't manage, and in particular doesn't stack unmanaged windows (like panels).

The previous solution was to raise the fullscreen windows above every other windows (including unmanaged windows).

If you want to emulate this behavior, the proper way to do it is to read from bspc control --subscribe window_state (I'll post a script).

rr- commented 8 years ago

But won't having fullscreen windows rendered on top of all other windows nullify all of the benefits of the layers - will one be able to still have floating windows render above such fullscreen windows?

Also... what do you think about splitting the manage flag into several smaller flags: manage_stack, manage_layout, manage_focus etc.?

baskerville commented 8 years ago

Right, so lowering the panel (xdo lower ...) would be better.

Regarding _managestack: the problem is that there's no such thing as a partially managed window: either it's in one of the trees or it isn't.

baskerville commented 8 years ago

I'm thinking of adding modifiers: .samelayer and .otherlayer or .normal, .above and .below?

Chrysostomus commented 8 years ago

Latter seems more intuitive option

baskerville commented 8 years ago

@rr- in fact the best option is to put the panel below the fullscreen window with xdo below -t FULLSCREEN_WID PANEL_WID.

baskerville commented 8 years ago

@Chrysostomus the new modifiers are available as of 65bc79f.

baskerville commented 8 years ago

@rr- Here's my script:

#! /bin/sh

panel_wid=$(xdo id -a lemonpanel)

bspc control --subscribe window_state | while read msg name state wid ; do
    [ $name = "fullscreen" -a $state = "on" ] && xdo below -t $wid $panel_wid
done

It will work, for example, with lemonboy's bar launched with -n lemonpanel.

rr- commented 8 years ago

@baskerville thanks, I used slightly different approach with wrapper script for fullscreen toggling, but essentially it does the same thing.

Didn't know of xdo below -t before I created #299, #299 now seems pointless...