[PATCH 2/2] protocol: add state set functions for maximized and fullscreen.
gregory.merchan at gmail.com
Sat Nov 2 02:36:04 CET 2013
On Thu, Oct 31, 2013 at 8:28 PM, Jason Ekstrand <jason at jlekstrand.net> wrote:
> On Thu, Oct 31, 2013 at 3:37 PM, Bill Spitzak <spitzak at gmail.com> wrote:
>> Jason Ekstrand wrote:
>>> Yes, in theory they could read the configuration of the compositor.
>>> I really don't want to build this kind of inconsistency into the system
>>> and I don't see why it's justified.
>> I think I see what you are getting at. I think a scheme that allows simple
>> applications to obey the global setting without thinking, but still allows
>> applications that have a good reason to do tricks with the focus, and also
>> matches the raise proposal, is this:
>> - The compositor sends an "I want you to activate" event, as you propose.
>> - The client can respond to this with an "activate" request. Or it could
>> send an "activate" request at other times if it wants.
>> - The compositor responds to the "activate" request by either ignoring it
>> or actually doing the activation.
>> - The compositor sends an "activated" event that the client can respond to
>> by redrawing to show the fact that they are activated.
>> If a client just echoes the "I want you to activate" event then it will
>> work as you expect. A client could also wait after the event until the mouse
>> enters a correct location or clicks on the right thing. It could also try to
>> generate spurious activates but the compositor may ignore them.
> I still don't understand why a client would want to not activate. I can see
> not wanting to raise, but why not activate?
As Bill mentioned in a follow-up, drag sources would want to not activate.
This can be handled more simply than described above, without a
special "activate" system. I assume "activation" applies to a window,
not a client.
First, clients are responsible for requesting activation when it is appropriate.
Second, the compositor always activates when it is appropriate.
The complicated part is determining what is appropriate.
There are 5 activation policies. For each policy, the compositor
activates windows as needed for key traversal (e.g. Alt+Tab), task bar
actions, when an active window goes away, viewport changes, etc. The
compositor also activates windows when a request for activation has
the correct signature. The policies are distinguished by special cases
for activation or deactivation:
1. PointerRoot: Activates a window when the pointer enters it and
deactivates it when the pointer leaves.
2. Sloppy: Activates a window when the pointer enters it.
3. Delayed sloppy: Activates a window when the pointer has been within
for a short time.
4. Click-to-focus: Activates a window when it is clicked.
5. Windows/MacOS-style: Does not activate a window, except as it does
for all policies.
(I suppose a "Delayed PointerRoot" policy is possible, but I've never
seen any discussion of it.)
For each of these policies, another distinction may be made according
to signature required to honor an activation request. The strictest
form is to deny all requests, which is not possible on X11 because
there is no redirection for focus changes. An often desired form for
the correct signature, among X11 users, is that the request must come
from a client which is already activated. For example, this allows an
active program to activate a dialog, but prevents other programs from
activating any windows. Unless I am mistaken, most attempts at "focus
stealing prevention" have aimed at such a policy. I'm pretty sure I've
seen at least one window manager that will fight with bad programs to
enforce such a policy. On X11, the correct signature is always only
that the timestamp is later than the last focus change timestamp, and
this may be achieved by using CURRENT_TIME. Convention is relied upon
to avoid chaos, that convention is that clients must always use a
valid timestamp to set focus, and there are 4 sources of valid
timestamps: 1) button events, 2) key events, 3) property change
events, and 4) a window manager message. This last source exists to
address the lack of a timestamp in the focus change event of the X
protocol. I will refer to this as the "valid event" signature.
Wayland is a different system and there are more options for the
signature requirement. If I understand the protocol correctly, the
serial field of pointer, keyboard, and touch events could be used as a
signature. (Like X, wl_keyboard::enter does not have a time argument,
so that is not an option.) The strictest form of these
policies--denying all requests--can be achieved because the compositor
is in control; it's like a window manager and an X server combined in
that sense. The "must be active" signature can be implemented by
checking that the serial number came from an event sent to an active
client. The valid event signature can be implemented by checking that
the serial number came from a wl_pointer::button event, a
wl_keyboard::key event, a wl_keyboard::enter event, or wl_touch::down
The compositor is always in control, so clients can request activation
as much as they like without messing things up. Clients cannot prevent
the compositor from implementing any of the five activation policies.
The first four policies require nothing from clients to work as
expected; they are what we've had on X forever. The last policy does
not work unless clients request activation as needed when they have a
valid event. To my knowledge, both Windows and MacOS already require
applications to request activation in this way, so cross-platform
toolkits don't have to make a special case. This is the first
requirement that was stated before: clients are responsible for
requesting activation when it is appropriate.
I have said nothing about stacking. Handling activation as I have
described allows for every kind of stacking behavior I've seen, except
for one: raise on frame clicks, but not on clicks within the frame.
This exception exists when the compositor is not responsible for
drawing the window frame, because nothing I have described allows the
compositor to distinguish between parts of the client window. Make
that distinction and the problem is solved; choose whichever stacking
policy you would like. If the distinction between the frame and the
rest of the window is included in the request for activation, you can
even have clicks in the client raise, but only clicks on the frame
activate, though I can think of no reason beyond sadism why anyone
would make things work that way.
I believe a simple stacking policy would be to allow a client with an
active window to do anything it wants with its windows within the
bounds set by other features; basically it can do anything as long as
it doesn't put windows below stay-on-bottom features, like the
desktop, or above stay-on-top features, like task bars and menus. I
believe it would be sensible to keep the active window on top within
its bounds, excepting for secondary windows, like tool palettes, which
should stay above the primary window. This is the stacking behavior
familiar to users of Windows and MacOS. I emphasize that the stacking
policy is independent of the activation policy, so long as the
compositor can distinguish between frames and their contents.
The guides I gave before--clients request activation responsibly,
compositors activate appropriately--allow all users to use their
chosen compositors with any application targeted at Wayland.
The combination of Windows/MacOS-style activation policy with an
active-window-on-top stacking policy is the behavior familiar to
Windows and MacOS users, including the allowance for beginning a
drag-and-drop operation without raising the drag source window. Much
the same system is possible on X11 if window managers will not grab
buttons without modifiers and regular clients will use the globally
active input model, requesting input focus when appropriate. Perhaps
most important to many reading this list is that the all the
activation policies familiar from X are compatible with the client
behavior I have described.
When I'm done with my current project at work, I'll be able to see
about writing code for what I have described, but that's weeks or
months away and then I'll need time to reacquaint myself with pretty
much everything. I hope that this has been a useful message. I
apologize for the lengthy lack of code.
More information about the wayland-devel