[PATCH 2/2] protocol: add state set functions for maximized and fullscreen.

Gregory Merchan gregory.merchan at gmail.com
Sat Nov 2 07:14:41 CET 2013


On Fri, Nov 1, 2013 at 10:58 PM, Jason Ekstrand <jason at jlekstrand.net> wrote:
> On Fri, Nov 1, 2013 at 8:36 PM, Gregory Merchan <gregory.merchan at gmail.com>
> wrote:
>>
>> 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
>> event.
>>
>> 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.
>
>
> Gregory,
> Thank you very much for your e-mail.  I think that helps a lot.  The lack of
> code is ok because I think Rafael is planning to start implementing as soon
> as things settle a bit.  Sometimes protocol discussions can end up with a
> whole lot of hypotheticals and what you gave was a very clear concise
> discussion of the topic.
>
> If I am understanding you correctly, what we need are an "activate" request
> and "notify_active" and "notify_inactive" events.  To support sloppy focus,
> clients should just always try to activate on wl_pointer.enter and let the
> compositor sort it out unless they have a good reason to do otherwise.  For
> cases such as alt-tab, or another window closing, the compositor simply
> sends a notify_active.  I think I'm ok with this.

The only difference I understand between the active state and having
the keyboard focus is that a keyboard grab may take away the focus but
should not deactivate the window. In the code I was writing for X over
a year ago, I made use of the mode field in XFocusChangeEvent to
decide whether to treat a window as deactivated; as I recall, there is
always a NotifyNormal focus change mode when focus really goes away. I
don't know how grabs work in Wayland, but I was under the impression
that the activate request would be a request for the keyboard focus,
that wl_keyboard::enter would serve as notify_active, and that
wl_keyboard::leave would serve as notify_inactive. If there are grabs
something like in X, then either a new field in wl_keyboard::enter and
wl_keyboard::leave is needed (like X's mode field), or a separate
active state and events are needed. Between the two, I prefer what you
suggest, a separate state and events; the semantics seem to be
clearer.

Sloppy focus, as a system-wide policy, can be handled by the
compositor without the assistance of client. It would activate the
window whenever the window would receive a wl_pointer::enter event. Am
I misunderstanding how events are handled? I was under the impression
the compositor would be aware of crossing and other events. I believe
it would have to be in order to determine the validity of a request
signature. A compositor not using sloppy focus could indeed ignore
signatures from crossing events, so it would be OK for clients to make
the request in any environment, but if it is not necessary then I
think it should not be done. This allows toolkits and applications to
use very much the same logic whether they are targeted at Wayland, X,
MacOS, or Windows.

Yes, for alt-tab and so forth, the compositor just sends a
notify_active. If the client needs to activate another window instead,
such as a modal dialog which should receive events instead of the
parent window, it would use the signature of the notify_active event
in the request. A a compositor with a strict PointerRoot policy could
ignore the request or honor it with something like XWarpPointer.
(Sorry, I have no idea what the Wayland equivalent would be, if it
exists.)

> Two more questions that come to mind:
>
> 1) Will we ever need a deactivate request?  Under the given scheme, no need
> comes immediately to mind.

I don't believe it is needed. I haven't seen anything of the sort on
any other system, though, admittedly, I wasn't looking for it either.

> 2) Should the activate be associated with a particular seat.  If you have
> multiple cursors, you can easily have multiple active windows so this seems
> perfectly reasonable.  If this is the case, should this be part of wl_seat
> or should we keep it in xdg_shell?  I'm a little afraid to clutter wl_seat
> unnecessarily but this is very quickly starting to look like a seat focus.

As I understand it, activation should be associated with a particular
seat. I had in mind that the signature of an activation request would
somehow indicate the seat making the request. The serial field of the
relevant events seemed suitable as a signature, and I thought the
compositor would be able to associate the value with a seat. It has
been a while since I looked at Wayland code and example clients, so
I'm very uncertain of my understanding.

> Once again, Gregory, Thanks for the explanation.  I hope I'm following ok.
> --Jason Ekstrand

I believe you are, so I'll throw something else at you. The signature
should be something that can be passed from one program to another
either as an execution argument or in the environment. The reason for
this is to allow one program to execute another program and, in the
absence of any other activity, allow the new program to make a valid
request for activation. For example, if a user double-clicks a file
icon in a file manager to open a file, then the file manager pass the
signature of one of the button events to whichever program opens the
file, so that if the user just waits, activation of the window with
the open file will happen automatically. Task bar, dock, panel, etc.
launchers could do the same. By leaving the initial activation of a
new window to a client, the case of the wrong new window getting focus
can be avoided. The compositor must of course ensure that it only
honors the right request: if a signature from a later event was used
for activation, the request of the newly opened window with the old
signature should be denied. Since the signature on X is a timestamp,
this is handled automatically by the server; the window manager just
needs to take care not to map the window above the active window.

I just remembered another reason for activation to be distinct from
keyboard focus: a desktop environment may want to regard a toplevel
window as still active when one of its secondary windows (e.g. a modal
dialog) has keyboard focus. In a sense it would be a branch of a tree
that is active, though only one node at a time has keyboard focus. If
that is possible, is it necessary to have a request to move the
keyboard focus?

Thank you for receiving this so well. I feared I would be sent to the
dustbin for offering no code.


More information about the wayland-devel mailing list