Currently Wayland clients have no way of knowing if their menus/subwindows are going to be placed offscreen. If they are near the bottom of the screen, currently the menus go offscreen. In other environments, applications will place the menu going up the top of the window instead if it doesn't fit. Rob Bradford had a protocol to probe a given reigon, and an implementation, but it was never merged http://lists.freedesktop.org/archives/wayland-devel/2013-April/008836.html http://lists.freedesktop.org/archives/wayland-devel/2013-April/008666.html http://lists.freedesktop.org/archives/wayland-devel/2013-April/008667.html For desktop usability, a similar protocol should be added to XDG_Shell, for the clients to be able to use
*** Bug 48998 has been marked as a duplicate of this bug. ***
Seeing the window is open for Wayland 1.8, should the possibility of wl_probe be looked at again?
I prefer just being able to give the compositor a hint of what it should do if it does not fit. Something like flip-x, flip-y, resize-w, resize-h, nothing, scale parent surface. Though I think compositors will already automatically do some of this depending on if it is a popup or child/transient surface. Probing does not make sense as if your surface is full-screen on one output and normal on another output you would have to place the sub-surface inside the main surface on all outputs even if it would be fine in the correct position on the non full-screen output. If you give the compositor a hint and let it take care of it then it can place it differently on different outputs.
(In reply to x414e54 from comment #3) > I prefer just being able to give the compositor a hint of what it should do > if it does not fit. Something like flip-x, flip-y, resize-w, resize-h, > nothing, scale parent surface. > > Though I think compositors will already automatically do some of this > depending on if it is a popup or child/transient surface. > > Probing does not make sense as if your surface is full-screen on one output > and normal on another output you would have to place the sub-surface inside > the main surface on all outputs even if it would be fine in the correct > position on the non full-screen output. > > If you give the compositor a hint and let it take care of it then it can > place it differently on different outputs. Sorry, but I don't think any of that makes sense. Menus usually want to be aligned somehow to some widget (of which the compositor has no knowledge of at all) like a menu-bar "button". The compositor does not have the knowledge to reposition the surface to keep the GUI aligments that the application toolkit wants to have. I suppose you could remedy that by giving the compositor the rect around which the popup should be aligned, but that's getting comlicated and moves some of the popup placement policy into the compositor, away from the toolkit. Resize would be basically the same as probe, except you'd probably get visual flicker. Probing is simpler. Scaling wouldn't work at all, because it would mess up the GUI scale and visual appearance. Menus are of type xdg_popup. Child or transient surface are not xdg_popups, because xdg_popup implies that the GUI needs a grab to operate as expected. If you don't want or need a grab, it's not a xdg_popup. Grabs can also be denied, so it's always possible the xdg_popup will be dismissed before it gets shown, but that just normal race avoidance. You cannot have a wl_surface fullscreen on one output and normal on another output. A wl_surface can have just one xdg_surface, and so it cannot be fullscreen and normal at the same time, even if the visual appearance of the surface allowed both, which it usually doesn't. If the compositor is showing the wl_surface in several places, it also knows what it is doing with those places, and will know how the probe needs to behave. The client will always assume the window is in one place, and I believe it also needs to know where the popup surface is wrt. the parent surface. Also, nothing here is about sub-surfaces. They are a completely different thing. You do not implement menus as sub-surfaces, because you can't get the grab behaviour you need.
(In reply to Pekka Paalanen from comment #4) > (In reply to x414e54 from comment #3) > > I prefer just being able to give the compositor a hint of what it should do > > if it does not fit. Something like flip-x, flip-y, resize-w, resize-h, > > nothing, scale parent surface. > > > > Though I think compositors will already automatically do some of this > > depending on if it is a popup or child/transient surface. > > > > Probing does not make sense as if your surface is full-screen on one output > > and normal on another output you would have to place the sub-surface inside > > the main surface on all outputs even if it would be fine in the correct > > position on the non full-screen output. > > > > If you give the compositor a hint and let it take care of it then it can > > place it differently on different outputs. > > Sorry, but I don't think any of that makes sense. > > Menus usually want to be aligned somehow to some widget (of which the > compositor has no knowledge of at all) like a menu-bar "button". The > compositor does not have the knowledge to reposition the surface to keep the > GUI aligments that the application toolkit wants to have. I suppose you > could remedy that by giving the compositor the rect around which the popup > should be aligned, but that's getting comlicated and moves some of the popup > placement policy into the compositor, away from the toolkit. > > Resize would be basically the same as probe, except you'd probably get > visual flicker. Probing is simpler. Scaling wouldn't work at all, because it > would mess up the GUI scale and visual appearance. The popup placement should be up to the compositor. Otherwise you have situations where the compositor resizes/moves the parent, or popup or even the display is resized and the popup has not moved/closed/changed, which looks really stupid. You would have to constantly call these probe events in a loop and update the popup position. This is what the configure events are for. To tell you the compositor has resized your surface and to resize the content to fit. So scaling and aspect ratio would not be an issue. There would be no flicker because you would not have committed/swapped the initial buffer or set the opaque region. Until that point the popup would be transparent. If you do not mind about the x, y placement (e.g. in the case of right click style menu popups) but want the width/height obeyed you can use something like the flip-x, flip-y hints. The compositor can then align to the bottom left instead of top left, etc. If you mind where the x,y placement is but do not mind the height (e.g. in the case of combo box style popups) you can use the resize-h hint and then you get a configure event and resize the content before committing the buffer. > You cannot have a wl_surface fullscreen on one output and normal on another > output. A wl_surface can have just one xdg_surface, and so it cannot be > fullscreen and normal at the same time, even if the visual appearance of the > surface allowed both, which it usually doesn't. From the compositors point of view it can do whatever it wants with the surface. It has nothing to do with the application's interface to xdg_surface. Take "mirrored" desktops for example, the surface will appear on two or more outputs with possibly with different dimensions. Neither of them is "primary". Calling set_fullscreen can be passed an output. It is undefined what happens to the surface on the other output. Does it fullscreen also? Does it stay non-fullscreen? Does it disappear? It is up to the compositor's implementation of a "mirrored" desktop. > > If the compositor is showing the wl_surface in several places, it also knows > what it is doing with those places, and will know how the probe needs to > behave. The client will always assume the window is in one place, and I > believe it also needs to know where the popup surface is wrt. the parent > surface. It is not safe for a client to assume that a window is on one output at a time. Probing will lead to a hack way for clients to attempt to guess the parent window position on an output. Also there is no way to know where the popup was actually placed in-relation to the parent, you just have to trust the compositor was not stupid. Which is why it is better to give hints about what to-do rather than to attempt to place it EXACTLY somewhere and have it moved by the compositor. > Menus are of type xdg_popup. Child or transient surface are not xdg_popups, > because xdg_popup implies that the GUI needs a grab to operate as expected. > If you don't want or need a grab, it's not a xdg_popup. Grabs can also be > denied, so it's always possible the xdg_popup will be dismissed before it > gets shown, but that just normal race avoidance. > > > Also, nothing here is about sub-surfaces. They are a completely different > thing. You do not implement menus as sub-surfaces, because you can't get the > grab behaviour you need. No but there are plenty of other situations where you do not want a grab but still want the child surface positioned in the same way. Tooltips for example. Also some tool-kits (GTK) or browsers (Chrome) which currently do not have (or is being deprecated) a way to use an implicit grab for popups and use normal child/transient surfaces instead.
Sorry for the weird lines breaks. First hand experience of what happens if you try to be clever and position something exactly the way you want it.
(In reply to x414e54 from comment #5) > (In reply to Pekka Paalanen from comment #4) > > (In reply to x414e54 from comment #3) > > > I prefer just being able to give the compositor a hint of what it should do > > > if it does not fit. Something like flip-x, flip-y, resize-w, resize-h, > > > nothing, scale parent surface. > > > > > > Though I think compositors will already automatically do some of this > > > depending on if it is a popup or child/transient surface. > > > > > > Probing does not make sense as if your surface is full-screen on one output > > > and normal on another output you would have to place the sub-surface inside > > > the main surface on all outputs even if it would be fine in the correct > > > position on the non full-screen output. > > > > > > If you give the compositor a hint and let it take care of it then it can > > > place it differently on different outputs. > > > > Sorry, but I don't think any of that makes sense. > > > > Menus usually want to be aligned somehow to some widget (of which the > > compositor has no knowledge of at all) like a menu-bar "button". The > > compositor does not have the knowledge to reposition the surface to keep the > > GUI aligments that the application toolkit wants to have. I suppose you > > could remedy that by giving the compositor the rect around which the popup > > should be aligned, but that's getting comlicated and moves some of the popup > > placement policy into the compositor, away from the toolkit. > > > > Resize would be basically the same as probe, except you'd probably get > > visual flicker. Probing is simpler. Scaling wouldn't work at all, because it > > would mess up the GUI scale and visual appearance. > > > The popup placement should be up to the compositor. > Otherwise you have situations where the compositor resizes/moves the parent, > or popup or even the display is resized > and the popup has not moved/closed/changed, which looks really stupid. > You would have to constantly call these probe events in a loop and update > the popup position. The compositor cannot resize a clients surface, it can only suggest a new size. It is completely up to the client to attach a buffer and window geometry with appropriate size. A parent surface of a popup, be it a xdg_surface or another xdg_popup, cannot be removed/unmapped before the child popup. If a client tries to do that, it will be terminated with an error for breaking the protocol. A compositor is responsible for implementing the same semantics regarding map/unmap order of popups. If I understand your concerns correctly, you think that, while a popup is showing, moving the parent window might potentially make the popup end up partly or fully off screen. I'm not sure this can happen, since a move would take the grab and implicitly dismiss the previous grab i.e. unmap all the popups. If it is true that one may initiate an interactive move without unmapping the popups we'd have to decide whether it is more important to support reliable positioning of popups (so that client can draw UI which content in the popup and parent surface align), or that moving a surface with mapped popups attached should implicitly reposition them given whatever constraints the compositor wants. I'd say the first option which wl_probe allows is more desirable. > > > This is what the configure events are for. To tell you the compositor has > resized your > surface and to resize the content to fit. So scaling and aspect ratio would > not be an issue. A compositor may not resize a clients surface, it may only suggest that the client resizes its own surface. This is what the configure event is for. > > There would be no flicker because you would not have committed/swapped the > initial buffer > or set the opaque region. Until that point the popup would be transparent. > > > If you do not mind about the x, y placement (e.g. in the case of right click > style menu popups) > but want the width/height obeyed you can use something like the flip-x, > flip-y hints. > The compositor can then align to the bottom left instead of top left, etc. > > If you mind where the x,y placement is but do not mind the height (e.g. in > the case of combo box style popups) > you can use the resize-h hint and then you get a configure event and resize > the content before committing the buffer. > > > > You cannot have a wl_surface fullscreen on one output and normal on another > > output. A wl_surface can have just one xdg_surface, and so it cannot be > > fullscreen and normal at the same time, even if the visual appearance of the > > surface allowed both, which it usually doesn't. > > From the compositors point of view it can do whatever it wants with the > surface. > It has nothing to do with the application's interface to xdg_surface. > > Take "mirrored" desktops for example, the surface will appear on two or more > outputs with possibly with different dimensions. Neither of them is > "primary". > > Calling set_fullscreen can be passed an output. > > It is undefined what happens to the surface on the other output. > Does it fullscreen also? Does it stay non-fullscreen? Does it disappear? > It is up to the compositor's implementation of a "mirrored" desktop. The client will render the surface as if it would be fullscreen, probably with the same dimensions as the output it fullscreened on. Of course the compositor can render it however it wants, but the content would still be as if it was fullscreen, and a client should assume so is also the case. This seems completely unrelated to wl_prope or popups. > > > > > > If the compositor is showing the wl_surface in several places, it also knows > > what it is doing with those places, and will know how the probe needs to > > behave. The client will always assume the window is in one place, and I > > believe it also needs to know where the popup surface is wrt. the parent > > surface. > > It is not safe for a client to assume that a window is on one output at a > time. > > Probing will lead to a hack way for clients to attempt to guess the parent > window position > on an output. It can also expand its buffer size while keeping the same input region and buffer content making the expansion transparent, until it receives a "wl_surface.enter", and then calculate its position. That doesn't mean wl_surface.enter is the wrong thing to do. > > Also there is no way to know where the popup was actually placed in-relation > to the parent, > you just have to trust the compositor was not stupid. Which is why it is > better to give hints > about what to-do rather than to attempt to place it EXACTLY somewhere and > have it moved by the compositor. If we specify a protocol which, similar to subsurfaces, mandate the compositor to place popups relative to its parents in a reliable way, why wouldn't one know exactly where it is placed? > > > Menus are of type xdg_popup. Child or transient surface are not xdg_popups, > > because xdg_popup implies that the GUI needs a grab to operate as expected. > > If you don't want or need a grab, it's not a xdg_popup. Grabs can also be > > denied, so it's always possible the xdg_popup will be dismissed before it > > gets shown, but that just normal race avoidance. > > > > > > Also, nothing here is about sub-surfaces. They are a completely different > > thing. You do not implement menus as sub-surfaces, because you can't get the > > grab behaviour you need. > > No but there are plenty of other situations where you do not want a grab but > still want the > child surface positioned in the same way. Tooltips for example. Tooltips should be and mostly are (toytoolkit, GTK+) implemented using subsurfaces. > > Also some tool-kits (GTK) or browsers (Chrome) which currently do not have > (or is being deprecated) > a way to use an implicit grab for popups and use normal child/transient > surfaces instead.
> The compositor cannot resize a clients surface, it can only suggest a new > size. It is completely up to the client to attach a buffer and window > geometry with appropriate size. This is irrelevant to the point that configure events could be used inplace of a wl_probe. The Compositor would suggest the new size based on the hints. Also this is not how the (current) wording of xdg_shell.xml implies configure events: "The surface is maximized. The window geometry specified in the configure event must be obeyed by the client." "The surface is fullscreen. The window geometry specified in the configure event must be obeyed by the client." "The surface is being resized. The window geometry specified in the configure event is a maximum; the client cannot resize beyond it. Clients that have aspect ratio or cell sizing configuration can use a smaller size, however." "Obey" and "Maximum" are certainly not "suggest". > If I understand your concerns correctly, you think that, while a popup is > showing, moving the parent window might potentially make the popup end up > partly or fully off screen. I'm not sure this can happen, since a move would > take the grab and implicitly dismiss the previous grab i.e. unmap all the > popups. If it is true that one may initiate an interactive move without > unmapping the popups we'd have to decide whether it is more important to > support reliable positioning of popups (so that client can draw UI which > content in the popup and parent surface align), or that moving a surface > with mapped popups attached should implicitly reposition them given whatever > constraints the compositor wants. I'd say the first option which wl_probe > allows is more desirable. Yes but it is not just about moving the parent window. It *could* mean other events like hotswapping monitors/display mode change will have to dismiss all grabs and close all popups. Some toolkits and applications do want grab-free "popups" that are either child windows or subsurfaces. They may still want to be notified when the subsurface is clipping the display without having to poll wl_probe. Even the parent surface may want to know when it will clip a display. Some kind of accordion style UI. Chrome when dragging/moving tabs currently forces them to be constrained to the display area. > The client will render the surface as if it would be fullscreen, probably > with the same dimensions as the output it fullscreened on. Of course the > compositor can render it however it wants, but the content would still be as > if it was fullscreen, and a client should assume so is also the case. This > seems completely unrelated to wl_prope or popups. Okay maybe not fullscreen but two monitors with the same window in different positions. One at the bottom of the screen and one at the top. The compositor will be able to work where to put the popup on based on seat and serial. But wl_probe would be a worse case and have to return the minimum size always. > > It can also expand its buffer size while keeping the same input region and > buffer content making the expansion transparent, until it receives a > "wl_surface.enter", and then calculate its position. That doesn't mean > wl_surface.enter is the wrong thing to do. This would not work if there was only one display or they were not stitched together. But it is a fair point.
(In reply to x414e54 from comment #8) > > > > It can also expand its buffer size while keeping the same input region and > > buffer content making the expansion transparent, until it receives a > > "wl_surface.enter", and then calculate its position. That doesn't mean > > wl_surface.enter is the wrong thing to do. > > This would not work if there was only one display or they were not stitched > together. > But it is a fair point. If you would like an example of one of the reasons why I am worried about this please see how chrome is working on XWayland here: https://youtu.be/PTu7-hBwZ1o
I have done a bit more thinking about the idea. I propose something along the lines of: set_window_constraints(enum x, enum y) move_x - The window will be able to be moved along the x direction up to a maximum of its width. move_y - The window will be able to be moved along the y direction up to a maximum of its height. rotate - The window can be rotated safely around the x and y co-ordinates. Both x and y must be rotate or this is an error. flip_x - The window can be mirrored along the x axis. Non-mirror-able content such as text should be sub-surfaces which will be positioned as if mirrored first along the parent x axis and then along their width mid point. - If the compositor is unable to mirror buffers then this will become resize_w. flip_y - The window can be mirrored along the x axis. Non-mirror-able content such as text should be sub-surfaces which will be positioned as if mirrored first along the parent y axis and then along their height mid point. - If the compositor is unable to mirror buffers then this will become resize_y. scale_parent_to_fit_w - The root parent surface width will be scaled so the total bounding area will fit on the screen. - If the compositor is unable to scale buffers then this will become resize_parent_to_fit_w. scale_parent_to_fit_h - The root parent surface height will be scaled so the total bounding area will fit on the screen. - If the compositor is unable to scale buffers then this will become resize_parent_to_fit_y. resize_parent_to_fit_w - The root parent surface width will receive configure events to state its maximum width so the total bounding area will fit on the screen. resize_parent_to_fit_h - The root parent surface height will receive configure events to state its maximum height so the total bounding area will fit on the screen. resize_w - The x co-ordinate is guaranteed and the surface will receive configure events to state its maximum width to fit on the screen. resize_h - The y co-ordinate is guaranteed and the surface will receive configure events to state its maximum height to fit on the screen. You can use a combination of either for example have a popup movable along the x axis but fixed y position. The application is then free to move the y position if the height becomes to small. This also allows a user on a tabletop style display to rotate a pop-up separately of the parent window without the application having to be involved. Also tabletop/multi-touch where you do not want a menu popup on one surface to block the entire surface. And the window may get knocked about due to collision/physics. So in your example for an application creating a menu based on a widget shape. It can either: set_window_constraints(resize_w, resize_h) It will then receive configure events which if it is not happy about it could move/resize the popup. Exactly the same as wl_probe except it would allow resizing or moving the popup if the parent window moved without polling. Or: set_window_constraints(flip_x, flip_y) Attach the popup window decoration buffer offset by the center point of the widget and then attach the Text/Content buffer as a subsurface/child to the popup. The compositor can then flip the decoration buffer and due to the center based offset it would be in the correct position. It would then position the Text buffer in the correct place for the decoration. In this case the decoration buffer or original widget need not be a rectangular shape but just the text/content buffer needs to be able to be correctly overlayed on top. This means the compositor could display the popup differently on two different outputs, and also could move the popup itself when the parent window is moved.
Created attachment 114977 [details] [review] Window Constraints Example I have created a quick example patch of my set_window_constraints idea. It is far from complete but at least the general idea is there. I have only implemented this for xdg_surface as I am currently unsure where Wayland is going with xdg_popup and I would not intend to ever use the xdg_popup in its current implementation in an application. Especially with multi touch and alternative input interfaces I am not sure it is good idea to force every client and compositor into requiring grabs and probe polling.
This effort has been resurrected: http://lists.freedesktop.org/archives/wayland-devel/2015-September/024547.html The thread continues in October.
This did eventually land in wayland-protocols.
Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.