I failed to reply to all. I hope copying and pasting hasn't messed up anything.
On Thu, Nov 7, 2013 at 3:32 AM, Rafael Antognolli <[email protected]> wrote: > Hello all, > > Following is the same description as in my previous wrong email, but with the > correct patch attached. > > I'm trying to summarize part of the discussion in this new patch, but it's not > the final one. > > As far as I understood, the goal is to end up with something like this for > keyboard focus: > > W = compositor > A, Z = client surfaces > > Viewport change: > W to Z: You are deactivated. > W to A: You are activated. > A to W: Do these things. > > So, I added "activated" and "deactivated" events, that the compositor can use > to inform clients what they are. And there's a take_focus request that can be > used by a client to ask for activation, but it's up to the compositor to > decide. That's only part of it. When I wrote about W, A, and Z, the discussion had been narrowed to a subset of reasons for changing focus that included things like viewport changes. The name "take_focus" sounds like it's about something different from "activated" and "deactivated". It's is also similar to a request on X which window managers make of clients, "WM_TAKE_FOCUS", and this invites confusion. It also sounds more like a request to deactivate, as in, "Please take focus away from me." The obvious name for the request, "activate", is only one letter different from the name of the event "activated", so perhaps that should be avoided. I think "set_active" is in line with other names. If that's not suitable, only "please_activate" and "make_active" come to my mind. I will use "set_active" for the remainder of this message. I described the need for signatures allowing the compositor to validate requests. I believe the simplest suitable signature is a timestamp as provided by some events. This allows the compositor to associate the request with an event and to invalidate requests which have been superseded by later requests. The timestamp of wl_pointer::button and other user-generated events seems to be the thing to use. The "activated" event must provide a valid timestamp which the client can use as a signature to make a "set_active" request. This allows the client to activate the correct surface (such as a modal dialog) when the compositor has activated the wrong surface. The "deactivated" event does not really need a timestamp, because merely being deactivated is no reason to request activation, but clients could use such a timestamp to avoid making requests which will fail because their timestamps came before the deactivation. The name and type of the timestamp should be "time" and "uint", just like the user-generated wl_pointer::button, wl_keyboard::key, and wl_touch::down events. The "set_active" request should have a "time" argument of type "uint", just like the aforementioned events. These events, requests, and timestamps do not suffice to make a good system; a good division of responsibilities is also needed. The only division of responsibilities which allows for all of the expected features of modern GUIs is as follows. Clients: 1. Must request activation when they need it, as indicated by user-generated events or other sources of timestamps. 2. Must expect activation from the compositor, which will happen for events of which clients cannot be aware. Compositors: 3. Must not activate surfaces when clients could request activation but have not done so. 4. May activate surfaces in response to requests or events of which clients are not aware. You may note that this is different from what MS Windows and all extant X11 window managers do; it is at least similar to what MacOS does. Why this division? I'll go through each. 1. A. When the user presses a button over a client surface, only that client is aware of the contents of the surface and thus whether the surface should remain inactive or be activated. If the button press is on something in the surface that might be dragged to another surface, such as file icon, a client would remain inactive so as not to be raised and obscure the drop target. If the button press is on a control that could be used without changing keyboard focus, like a tool palette or a scroll bar, a client would remain inactive to allow other work to proceed without moving keyboard focus back and forth. B. Events may occur in other clients, and not the compositor, which provide a client with a reason to request activation. The most obvious is when one client starts another client, as a file manager might start a text editor to open a document. The starting client should provide to the started client the timestamp of the event which is the reason for starting it, and then the started client should request activation using that timestamp when it is ready to do so. This allows for a smooth flow of work between applications. Because clients can only request activation, the compositor, checking timestamps, can prevent a client which took too long to start from stealing activation from a client that was activated during the delay. C. Clients may need to request activation when they already have it. Using the file manager example again, if the user decides to not to wait on a slow loading application and instead does something else with the file manager, the file manager, even though active, should again request activation so the compositor will have a last activation timestamp more recent than the one the slow app will use. Such a technique may be used in terminal emulators so that applications opened from a command line do not steal activation from the terminal if the user continues to use the terminal. If the pointer leaves an activated surface, enters it again, and a button is pressed, the client should again request activation of the still active surface, so that slow clients, seeking activation from when the active client lost pointer focus, do not steal activation. (Perhaps I should write an essay, "Has your activation gone stale? Preventing activation stealing.") 2. The compositor is the final arbiter of activation and may deem it necessary despite the expectations of a client. Clients cannot refuse activation, but they are not without options in response to it. They may: a) request another of their surfaces be activated, using the timestamp from the "activated" event; b) destroy the surface; or c) ignore activation by not repainting their windows, processing keystrokes, etc. (This last option is not recommended.) Clients should not delay their responses in an attempt to second-guess the compositor. 3. If a compositor activates a surface when a client could just as well request activation, it will prevent more sophisticated interactions such as raise-less drag-and-drop, fluid palette use, and churn-free scrolling. I may also cause focus stealing by errantly activating new surfaces. Clients creating new surfaces, even new clients, should be requesting activation with timestamps provided by events or other clients. A new client without a timestamp to activate its surfaces should use "demands_attention" instead. 4. There are events which clients do not receive but nonetheless are a reason for client surfaces to be activated. The destruction of another client's surface, a viewport change, and window switching by keystroke (Alt+Tab), are examples of such events. For these, if a surface is to be activated, it must be the compositor which does so despite no request from the client. Because the compositor is not aware of the internal state of the client, it may choose to activate the wrong surface. For this reason, the "activated" event must have a timestamp, like a user-generated event, which allows the client to activate the correct surface. It should be recognized that in the absence of sophisticated interactions like drag-and-drop a client receiving a button press event already has been or is about to be activated; the crossing events preceded button events, so point-to-focus policies activate earlier than click-to-focus polices would. Clients can support both point-to-focus policies and click-to-focus polices by using both crossing events and button events to request activation. A surface using a button event in addition to a crossing event will not create a problem for point-to-focus users, because the surface, compositor permitting, will already be active when the button event occurs. It will not create a problem for click-to-focus users because they can instruct the compositor to ignore requests from crossing events, but this is not without cost because otherwise silent clients will be chattering with requests which will be denied. Conversely, clients not using crossing events to request activation may appear to be non-responsive or slowly responsive to point-to-focus users. The compositor could force a point-to-focus policy, but would do so at the cost of the aforementioned sophisticated interactions. I believe a flag of some sort from the compositor to indicate the user's preference is a good way to reduce chatter, support both kinds of policies, and allow for sophistication. I recommend a signed integer value, perhaps "crossing_activation_timeout", interpreted as follows: n = -1: Clients should not expect crossing event activation requests will be honored. n >= 0: Clients should expect crossing event activation request to be honored n milliseconds after the timestamp, if at all. In the latter case, clients should expect the compositor to handle the timing and so not delay their requests. I imagine clients may be able to make use of the timing information, but if that is not so, then a simple boolean like "crossing_activation_accepted" should suffice. The compositor should be able to handle deactivation for the PointerRoot focus policy, if anybody even uses that. I have neglected to mention pointer warping because I hope nobody does that anymore. > Regarding the surface fullscreen, maximized, etc, I added surface states as > enum's, that can be set/unset, and events from the compositor to request that > a > given state should be set/unset. > > For those states that take parameters, I added separate requests for setting > the parameters before setting the state. It should all take place after commit > anyway, so that shouldn't matter much. Take a look at the docs and say what > you > think. > > I didn't change transient/popup surface types yet, but from what has been said > in the ML thread, I think they also should be surface states now. Correct me > if > I'm wrong. Otherwise I'm going to send an updated version with those changes > tomorrow. > > I also talked to jekstrand (I think) about stacking, will send an updated > version with what I understood from that tomorrow. Should be simple. I have of course assumed that surfaces would not normally be raised in the absence of activation. I believe stacking can and should be left to clients within constraints imposed by the compositor except for those special cases, like window switching, where it makes sense for the compositor to shuffle windows around. Because a new surface may remain not activated, I believe compositors should initially place them beneath the active surface and possible below all the normal surfaces. (Not below a desktop window, obviously, for that would forever obscure it.) > Any feedback is appreciated, and thank you guys for the input so far and the > patience. > > > Rafael Antognolli (1): > xdg_shell: Add a new shell protocol. > > protocol/Makefile.am | 2 +- > protocol/xdg-surface.xml | 381 > +++++++++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 382 insertions(+), 1 deletion(-) > create mode 100644 protocol/xdg-surface.xml > > -- > 1.8.3.1 > > _______________________________________________ > wayland-devel mailing list > [email protected] > http://lists.freedesktop.org/mailman/listinfo/wayland-devel One of these days I shall learn brevity. _______________________________________________ wayland-devel mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/wayland-devel
