Hi,
it seems that openbox is handling multiple STRUTS cropping the workaread to the maximum of the STRUTS rather than by adding them. This results in wrong application behaviour e.g. in case of an on-display keyboard.
The whole issue is described in:
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=551807 which also includes a testcase. From what I understand this bug report is correct and this is indeed a bug in openbox.
Cheers
IMO the wm-spec doesn't specify what to do if two windows specify a strut for the same edge. Besides, how are apps supposed to coordinate which app goes where, and should they monitor each other so they can move themselves when the app between them and the screen edge disappears? If two apps happen to inspect the state at the same time, they would appear on top of each other too, since neither of them mapped yet, so none of them can see the other. In the worst case they will both keep jumping around forever?
Hi,
It's not just a matter of multiple struts for the same edge. Two orthogonal struts currently lead to an overlap in the corner. Try for instance with two xfce4-panel. This use case alone advocates handling struts in a cumulative way.
It could reasonably be handled on a first-come first-served basis.
Say win1 defines strut1, then win2 defines strut2, and so on:
* strutN is set against the workarea resulting from strutN-1
* each time strutN redefines its strut properties, strutN+1 is updated by the wm regarding the new workarea resulting from strutN
* the latter occurs in a descending way: update strutN -> update strutN+1 -> update strutN+2 -> ...
This way apps wouldn't have to monitor each other.
Does it make sense to you?
Thanks
Ignoring the race conditions, yes, it's true that they don't need to monitor anything to keep their struts correct, but they still have to move their _window_ to the right place. And it's my understanding that partial struts solve overlap issues for orthogonal struts?
I'm not sure if you're implying the wm should change the strut property on client windows, but that definitely sounds like the wrong thing to do.
The window manager shown in the pictures at the original debian bug isn't even Openbox. It is Metacity from the looks of it. I'm not sure this is a bug that Openbox has at all then... you'll need to provide an example of Openbox doing something wrong, rather than Metacity, in order for us to consider what would be the right behaviour.
Openbox takes the union of all struts as the workable area, which seems sane in all regards. Adding them together would always make the strut space larger, which may or may not be why Metacity is creating that gap seen in the debian bug reporter's "both" image.
If this is Openbox does wrong I'd love to fix it, but it appears to be a different WM, and the user only believes they are running Openbox.
Please, trust your users ;)
This *is* openbox running on my FreeRunner. But the images are VNC snapshots taken via my laptop. Hence the metacity decorations.
Thanks.
Ok I understand the bug report now.
Adding together the struts, however, is not a good solution. I understand why it might be nicer in some cases, but the whole idea of multiple windows placing themselves above each others' struts is full of race conditions, as Mikachu pointed out.
A quick workaround for you would be to set Openbox's margins to be large enough to hold both the keyboard and the panel. Then windows won't cover them.
The EWMH spec is not designed with putting more than one strut on an edge at all, and so the behaviour for this case is completely undefined, and left (almost?) impossible to always satisfy completely.
My idea is to take over placing windows which set a STRUT property, instead of letting them place themselves and try move according to other windows with struts. Thus avoiding the race condition, and allowing the WM to know how much space to reserve and STRUT windows to move automatically as new ones are added and old ones removed. I will see about adding this to the EWMH spec.
Notes for myself:
Assume the window strut is for the bottom edge of the screen. If its another edge then have the same behaviour in relation to that edge.
A strut window is placed so that its bottom is placed the closest possible to the edge of the screen.
Algorithm: Let y = screen's bottom edge. Starting from the bottom-most strut window. Take y -= MIN(windowheight, strutheight) to be position for the top of that window. Repeat for the next window above it. (Branch off for partial struts that are above it and beside each other.)
At the end, y = the bottom edge of the screen's work area.
(In reply to comment #7)
> Ok I understand the bug report now.
Thanks for you patience :)
> Adding together the struts, however, is not a good solution. I understand why
> it might be nicer in some cases, but the whole idea of multiple windows placing
> themselves above each others' struts is full of race conditions, as Mikachu
> pointed out.
I assume that a window defining a strut should be placed relative to its strut area. That's how I understand the EWMH specification:
"The purpose of struts is to reserve space at the borders of the desktop. This is very useful for a docking area, a taskbar or a panel, for instance."
This way would allow multiple struts without the race conditions you mention.
> A quick workaround for you would be to set Openbox's margins to be large enough
> to hold both the keyboard and the panel. Then windows won't cover them.
Won't work since the keyboard isn't always visible: it appears on demand, and the desktop workarea have to be dynamically resized accordingly.
The best workaround I've found so far is to replace the bottom panel with a top one. :/
> The EWMH spec is not designed with putting more than one strut on an edge at
> all, and so the behaviour for this case is completely undefined, and left
> (almost?) impossible to always satisfy completely.
While I understand your concern about the undefined behavior in the EWMH spec, my take is that a wm should have a consistent behavior anyway regarding multiple struts.
> My idea is to take over placing windows which set a STRUT property, instead of
> letting them place themselves and try move according to other windows with
> struts. Thus avoiding the race condition, and allowing the WM to know how much
> space to reserve and STRUT windows to move automatically as new ones are added
> and old ones removed. I will see about adding this to the EWMH spec.
Seconded, modulo IMHO windows should be able to place themselves *into* (relative to) their strut area.
Thanks.
(In reply to comment #9)
> (In reply to comment #7)
> > Ok I understand the bug report now.
>
> Thanks for you patience :)
>
> > Adding together the struts, however, is not a good solution. I understand why
> > it might be nicer in some cases, but the whole idea of multiple windows placing
> > themselves above each others' struts is full of race conditions, as Mikachu
> > pointed out.
>
> I assume that a window defining a strut should be placed relative to its strut
> area. That's how I understand the EWMH specification:
>
> "The purpose of struts is to reserve space at the borders of the desktop. This
> is very useful for a docking area, a taskbar or a panel, for instance."
>
> This way would allow multiple struts without the race conditions you mention.
What way? You didn't say anything that counteracts the race conditions. A window can reserve less strut than the size of its window, or more. It might not even place a window there at all.
> > The EWMH spec is not designed with putting more than one strut on an edge at
> > all, and so the behaviour for this case is completely undefined, and left
> > (almost?) impossible to always satisfy completely.
>
> While I understand your concern about the undefined behavior in the EWMH spec,
> my take is that a wm should have a consistent behavior anyway regarding
> multiple struts.
It's hard to be consistent with anything else, since it is completely undefined in the spec. Adding the values break partial struts, ie two panels that aren't fullwidth that appear next to eachother.
If you move the panel while the keyboard is up, does the keyboard leave a hole? If it does and the wm adds the values of the visible struts, the window will _still_ extend under the keyboard, ie your other wm is also "inconsistent" with your definition :).
Comment 11Gilles Filippini
2009-11-05 17:40:48 EST
(In reply to comment #10)
> > > Adding together the struts, however, is not a good solution. I understand why
> > > it might be nicer in some cases, but the whole idea of multiple windows placing
> > > themselves above each others' struts is full of race conditions, as Mikachu
> > > pointed out.
> >
> > I assume that a window defining a strut should be placed relative to its strut
> > area. That's how I understand the EWMH specification:
> >
> > "The purpose of struts is to reserve space at the borders of the desktop. This
> > is very useful for a docking area, a taskbar or a panel, for instance."
> >
> > This way would allow multiple struts without the race conditions you mention.
>
> What way? You didn't say anything that counteracts the race conditions. A
> window can reserve less strut than the size of its window, or more. It might
> not even place a window there at all.
The way you define below: windows with strut are constrained into their own strut instead of placing themselves.
> > > The EWMH spec is not designed with putting more than one strut on an edge at
> > > all, and so the behaviour for this case is completely undefined, and left
> > > (almost?) impossible to always satisfy completely.
> >
> > While I understand your concern about the undefined behavior in the EWMH spec,
> > my take is that a wm should have a consistent behavior anyway regarding
> > multiple struts.
>
> It's hard to be consistent with anything else, since it is completely undefined
> in the spec. Adding the values break partial struts, ie two panels that aren't
> fullwidth that appear next to eachother.
>
> If you move the panel while the keyboard is up, does the keyboard leave a hole?
You can't move the panel *outside* the strut (see below). The strut becames a kind of dedicated workarea for the window which defines it.
> If it does and the wm adds the values of the visible struts, the window will
> _still_ extend under the keyboard, ie your other wm is also "inconsistent" with
> your definition :).
To sum it up, my - humble - definition would be:
* each strut is attached to the window which defines it, because it's set as a window's property (XChangeProperty).
* a window's strut - if any - becames this window's workarea: the positional properties of the window should then be read relative - and constrained inside - its own strut area
* the window may move freely - depending on its properties of course - inside - and only inside - its own strut
Thanks.
Comment 12Gilles Filippini
2009-11-05 17:49:05 EST
> To sum it up, my - humble - definition would be:
> * each strut is attached to the window which defines it, because it's set as a
> window's property (XChangeProperty).
> * a window's strut - if any - becames this window's workarea: the positional
> properties of the window should then be read relative - and constrained inside
> - its own strut area
> * the window may move freely - depending on its properties of course - inside -
> and only inside - its own strut
I forgot:
* struts are allocated on the desktop on a first-come first-served basis
* a new strut is allocated relative to the current workarea's geometry
* a strut change (XChangeProperty or dropped window) implies a cascading update of the struts created after this one
Comment 13Gilles Filippini
2009-11-05 20:27:11 EST
More thoughts about it...
I've missed an obvious use case from EWMH specification: auto-hide panels. Hence a window defining a strut can't be constrained to its strut's area.
Let's try again to sum it up:
* struts are allocated on the desktop on a first-come first-served basis
* in the context of one strut, three workareas exist:
- original_workarea: the workarea resulting from the previous struts
- resulting_workarea: the workarea resulting from *this* strut
- desktop_workarea: last defined strut's resulting_workarea
* a window defining a strut evolves inside its strut's original_workarea
* windows with no strut evolve inside the desktop_workarea
* a new strut is allocated relative to the previous strut's resulting_workarea
* a strut's geometry change or drop triggers a cascading update of the struts created after this one
* a strut's edge change is like dropping this strut and creating a new one (YMMV)
* a window defining a strut doesn't have any decoration (can't find a use case for decorations - YMMV).
Thanks.
I am attempting to solve this problem through the wm-spec, which will require changes on both the application side and the WM side in this case, but will be a functional solution rather than a buggy problem waiting to resurface.
http://mail.gnome.org/archives/wm-spec-list/2009-November/msg00005.html
I have the similar problem.
I'm using 3.4.7.2 verion of Openbox in Debian Lenny. Screen has been configured
to be 1280x1024. I have two panels on the desktop - at the top of the screen
(80 pixels height) and at the bottom (96 pixels height). Both panels are DOCKs
and use STRUTs. According to fd.o,
"The Window Manager SHOULD calculate this space by taking the current page
minus space occupied by dock and panel windows, as indicated by the
_NET_WM_STRUT or _NET_WM_STRUT_PARTIAL properties set on client windows."
As a result, NET_WORKAREA must have the following geometry: x=0, y=80 w=1280,
h=848 (1024-80-96). But it has wrong geometry: x=0, y=80 w=1280, h=944
(1024-80). As you can see, the size of bottom panel is not counted. It blocks
getting right geometry of the desktop, which blocks using my own window as a desktop application, since it's impossible to get right desktop geometry.
I'd like to bump this 6 year old bug with a certain variation of it I've been noticing ever since I had to use non-gtk2 programs on my desktop.
It seems that having one strut per monitor (I have one tint2 on the top of each of them, and the monitors are not aligned at the top, so the panel on the left monitor is lower than the other) breaks the behaviour of gtk3 and qt programs, namely the positioning of tooltips and dropdown menus. It also screws up with window creation in Wine, resulting in windows that spawn near the top of the screen being squashed down.
All of this is constricted to the height of the panel on the left monitor, even if the windows themselves are on the right one. It does NOT affect window maximization in any way, though.
> To sum it up, my - humble - definition would be: > * each strut is attached to the window which defines it, because it's set as a > window's property (XChangeProperty). > * a window's strut - if any - becames this window's workarea: the positional > properties of the window should then be read relative - and constrained inside > - its own strut area > * the window may move freely - depending on its properties of course - inside - > and only inside - its own strut I forgot: * struts are allocated on the desktop on a first-come first-served basis * a new strut is allocated relative to the current workarea's geometry * a strut change (XChangeProperty or dropped window) implies a cascading update of the struts created after this one