Subject: Client display configuration notification

From: Christopher James Halse Rogers <[email-masked]>
Date: Wed, 30 Sep 2015 14:04:00 +1000

Forked from review¹.

I think we're currently handling display configuration events 
incorrectly, or at least in a way that will be surprising to clients.

When the hardware configuration changes we send the new configuration 
to all clients. However, if a client has specified a different display 
configuration then we *don't* change it. The upshot is that 
mir_connection_create_display_configuration() will *not* return the 
currently active display configuration.

Furthermore, we clear the session's configuration cache, so if a 
session with custom configuration loses focus and then gains focus 
again it will *not* have its previous configuration applied.

This seems like confusing behaviour, which becomes even more confusing 
when the shell gets to change the default display configuration.

I'm not entirely sure what our behaviour *should* be, though I think 
that we should at least:

a) When hardware configuration changes we should verify that any 
session-set config remains valid (for example: was the only display 
that session had enabled removed?), update the session-set config, and 
submit that to the client so that create_display_configuration() will 
report the *actual* display configuration.

b) Have a way for a client to revert to default display configuration.

Hmmm.

¹: 
https://code.launchpad.net/~raof/mir/display-configuration-for-the-shell/+merge/272692/comments/687576

---

From: Alan Griffiths <[email-masked]>
Date: Wed, 30 Sep 2015 09:16:45 +0100

> incorrectly, or at least in a way that will be surprising to clients.

I totally agree that the existing behaviour is "surprising"; what isn't
clear to me either is what behaviour would be "unsurprising".

I think the problems arise because we conflate three distinct
configurations:

/1/ the "base configuration" as set by the server;
/2/ the "session configuration" as set by the client itself; and,
/3/ and the "current configuration" as set by the active session.

We do make a distinction between "hardware" and "user" options, but that
is simplistic.

I think we should allow the client to query each of the above (unless
/3/ is a security concern?). We also need better tracking of consistency
and differences between the base configuration and the session
configuration. (E.g. currently the session configuration "locks in" the
original values from the base configuration when not set by a client
that "doesn't care", it may be better to only hold the values explicitly
set.)

---

From: Alexandros Frantzis <[email-masked]>
Date: Wed, 30 Sep 2015 12:50:14 +0300

On Wed, Sep 30, 2015 at 02:04:00PM +1000, Christopher James Halse Rogers wrote:
> Forked from review¹.
> 
> I think we're currently handling display configuration events incorrectly,
> or at least in a way that will be surprising to clients.

For a bit of background, the current scheme is:

1. User changes the hardware config (e.g. adds/removes a monitor)
2. Update base config
3.1 If base config was applied before then apply the new base config
3.2 If per-session config was applied, do nothing, expect the client
    to respond to the configuration_changed event by setting a new session
    config based on the updated base config.

The reason for "do nothing" in 3.2 is to avoid applying the base
configuration before the client has applied its own new client config,
in order to avoid extra flickering.

> When the hardware configuration changes we send the new configuration to all
> clients. However, if a client has specified a different display
> Furthermore, we clear the session's configuration cache, so if a session
> with custom configuration loses focus and then gains focus again it will
> *not* have its previous configuration applied.
>
> This seems like confusing behaviour, which becomes even more confusing when
> the shell gets to change the default display configuration.
> 
> I'm not entirely sure what our behaviour *should* be, though I think that we
> should at least:
> 
> a) When hardware configuration changes we should verify that any session-set
> config remains valid (for example: was the only display that session had
> enabled removed?), update the session-set config, and submit that to the
> client so that create_display_configuration() will report the *actual*
> display configuration.

Sounds reasonable, and probably easy to implement (all added and removed
outputs are disabled). We just need to ensure we don't introduce any
unnecessary configuration changes so that we don't get extra flickering.

> b) Have a way for a client to revert to default display configuration.

Also reasonable, given that with (a) the client will no longer get the
base config.

Thanks,
Alexandros

---

From: Gerry Boland <[email-masked]>
Date: Thu, 1 Oct 2015 17:20:58 +0100

> that "doesn't care", it may be better to only hold the values explicitly

Hey
I had to write down the typical use-cases for this feature, in order to
make it clearer to me what we actually need.

== USC - Unity8 ==

1. User changes the hardware config (e.g. adds/removes a monitor)
2. Update base config in USC, notify clients (i.e. Unity8) of updated
base config
3. Unity8 respond to the configuration_changed event by setting a new
session config based on the updated base config.

This would indeed avoid flicker when USC applies policy, and then Unity8
applies policy after.

== USC - Unity8 - Display Settings (passive consumer of display config
change) ==

1. User changes the hardware config (e.g. adds/removes a monitor)
2. Update base config in USC, notify clients (i.e. Unity8) of updated
base config
3. Unity8 respond to the configuration_changed event by setting a new
session config based on the updated base config.
4. Display Settings notified of the configuration_changed event, and can
visualize current config. It should not try to automatically apply a
policy on hardware config change - that is Unity8's job.

But Display Settings will issue config changes at other times, that
Unity8 should always act upon.

== USC - Unity8 - Game/App which cares about hardware config  (active
consumer of display config change) ==

1. User changes the hardware config (e.g. adds/removes a monitor)
2. Update base config in USC, notify clients (i.e. Unity8) of updated
base config
3. Unity8 respond to the configuration_changed event by setting a new
session config based on the updated base config.
4. App notified of the configuration_changed event, and tries to set a
new session config. Unity8 must vet this config before allowing it to be
applied.
4.1 Unity8 applies the new client-designed config while app focused.
4.2 Unity8 rejects the client-designed config, decides a config itself.

Doing 4.1 while avoiding flickering requires Unity8 to know the client
will want to change the display config if hardware state changes.

One easy way is if client ever tries to change the config, server
assumes it will react to every base config change, and so wait for that.
But that's not an obvious contract when looking at the API? How to deal
with non-responsive client, we wait for its decision, then timeout? And
how does client drop that privilege, and allow server to take control again?

Also that easy way is not really compatible with the passive consumer
case above however.

I'm still processing this, so I'm avoiding stating any opinions yet. But
does anyone see any problems with my use-cases above? Or have I
forgotten anything?

/me suspecting we'll need a doc.
-G

---

From: Alan Griffiths <[email-masked]>
Date: Thu, 1 Oct 2015 17:55:21 +0100

> /me suspecting we'll need a doc.

We will, but at the moment we're still brainstorming requirements.

BTW IIRC at the pocket desktop sprint you were interested in additional
information in the config (e.g. EDID for monitors).

---

From: Gerry Boland <[email-masked]>
Date: Thu, 1 Oct 2015 22:00:26 +0100

> information in the config (e.g. EDID for monitors).

Right. Some unique identifier for the monitor would be good. EDID would do.
-G

---

From: Christopher James Halse Rogers <[email-masked]>
Date: Fri, 02 Oct 2015 09:25:36 +1000

> Right. Some unique identifier for the monitor would be good. EDID 

Hah! Such adorable trust in the hardware!

We should certainly send along any information we can slurp out, but 
the only identifiers we can *guarantee* you are “VGA-1, HDMI-2”, 
etc.

---

From: Alexandros Frantzis <[email-masked]>
Date: Mon, 12 Oct 2015 14:53:46 +0300

> > currently active display configuration.

A few additional thoughts and realizations after investigating LP
#1498021 ([1]) and pondering on the current code some more.

mir_connection_create_display_configuration() was originally created
with a single purpose in mind, which was to allow clients to get a valid
configuration on which to base their own custom configurations. It was
not intended to give back either the current session config or the
active config. The only guarantee was that it accurately represented
the hardware state (connected monitors and available modes). The base config
was used for this purpose although we could have used the more bare
configuration as returned by the mg::Display class.

Until recently, MediatingDisplayChanger honored this purpose by sending
new configurations to clients only as a response to hardware changes.
This was enough (sans bugs) for the use cases we had until then, which
involved clients responding to configuration changes from the server.

However, since then we have made changes that try to turn the value
returned by mir_connection_create_display_configuration() to something
it wasn't designed to be, i.e., an accurate representation of the
current state.  These changes, as Alan mentioned in an previous email,
have conflated the various types of display configurations we have
in Mir (base, active, session). 

A few questions and my take on them:

1. Which configuration types and changes to them does a normal
   (non-modesetting) client need to know about?

None of the types are particularly useful.

Perhaps it would be useful for the client to know about the active
config (e.g. when another session with a custom config has the focus),
but I can't think of any interesting use cases for this. I am all ears,
though.

2. Which configuration types and changes to them does a
   modesetting client need to know about?

In order for a client to set a custom config it needs at least a config
that accurately represents the hardware state. The base config is useful
if we want to allow clients to take it into account when setting a
custom config, e.g., don't turn a screen on if it's off in the base
config.

Again I don't see an interesting use case for following the active config.

3. Which configuration types and changes does the display
   settings app need to know about
   modesetting) client need to know about?

It needs to be able to get and set the current base configuration.

So, my take is that the only config that clients need to be notified
about is the base one. Clients also need to be able to set the session
and base configs (subject to permission restrictions):

// The same as the current mir_connection_create_display_configuration
// with a more accurate name and guaranteed to always return the base config,
// not just a valid hardware config
mir_connection_create_base_display_config() 

// Set base configuration, used only be display settings app
mir_connection_apply_base_display_config()

// Set session configuration
mir_connection_apply_display_config()

The display config change notification callback will notify only about
base config changes (like it did before the recent changes).

If we decide we also want active configs too, we need to
differentiate between the two kinds in notifications and add
mir_connection_create_active_display_config().

Thanks,
Alexandros

---

From: Alan Griffiths <[email-masked]>
Date: Mon, 12 Oct 2015 14:14:17 +0100

> and base configs (subject to permission restrictions):

I know the current scheme also has issues, but how would a settings
application work with this approach (of not being able to read the
current settings)?

---

From: Alexandros Frantzis <[email-masked]>
Date: Mon, 12 Oct 2015 17:16:42 +0300

> application work with this approach (of not being able to read the

The settings app only cares about the current base configuration, which
it will be able to get with mir_connection_create_base_config() and set
with mir_connection_apply_base_config().

A separate active config concept is not really interesting for a GUI
setting app because when the settings app has the focus (i.e., when the
user interacts with it) the active config will be the base config (since
the settings app won't set a session config). So, what is shown by the
settings app will be in sync with reality when it matters.

If we want for the settings app to always be in sync with the active
config, even when another app with a session config has the focus, then
we indeed need a separate active config change notification and way to
get it. However, as soon as the user tries to interact with the settings
app the config displayed by the app will change back to the base config.
This could be a bit confusing for users, but in any case could be added
later.

For a command line application that gets/sets the base config, being
able to report the active config is more reasonable, since no focus is
involved. However, I fear that it also may be misleading because perhaps
users will expect that they can force a particular change to the active
config, but this is not true if a session config is active (they can
only change the base config and then the focused session will react to
this change any way it wants, possibly ignoring it).

Having session configs (instead of a single global config) constitutes a
slight paradigm shift in the world of display configuration in Linux,
and it will take some time for both users and us to get used to it and
find a proper way to communicate the semantics. Having proper names for
functions and tools would be a good start (e.g.
mir_set_base_display_config for a command line tool instead of
mir_set_display_config).

Thanks,
Alexandros

---

From: Christopher James Halse Rogers <[email-masked]>
Date: Tue, 13 Oct 2015 11:33:43 +1100

On Mon, Oct 12, 2015 at 10:53 PM, Alexandros Frantzis 
<[email-masked]> wrote:
>> incorrectly,

I'd go the other way; we want unfocused, non-modesetting applications 
to *not* receive notifications about the active config changing. 
Otherwise, they'll react to the config change only to have to undo that 
reaction when they receive focus.

These clients may want to receive notifications for base config 
changes; for example, presentation applications which want to put their 
presentation on the newly-available projector.

>    modesetting) client need to know about?

3-𝜀: Can we get away with not supporting display settings apps? For 
example: GNOME Shell has no display configuration application interface.

> mir_connection_apply_base_display_config()

I remain sceptical about adding API that should only be used by exactly 
one client, that we control, and ship with Unity :).

> mir_connection_apply_display_config()

I think we additionally want mir_connection_unapply_display_config(), 
for an application that no longer needs its own display config.

---

From: Gerry Boland <[email-masked]>
Date: Tue, 20 Oct 2015 13:16:45 +0100

Hey folks,
it appears this topic has gone stale, without any consensus being reached. A core issue impacting this discussion which remains undecided is the following:

- Is it in Mir's scope as a display server to provide a client api for configuring mir server settings like those for displays & input devices? Or should Mir expose a mirserver API for these settings, and require the shell to implement its own API via an alternative channel (e.g. DBus) for a settings client to use?

If we clarify this point, then hopefully the path ahead will be more clear.
What say all?
-Gerry

On 13/10/15 01:33, Christopher James Halse Rogers wrote:
> I'd go the other way; we want unfocused, non-modesetting applications to
> *not* receive notifications about the active config changing. Otherwise,
> they'll react to the config change only to have to undo that reaction
> when they receive focus.
>
> These clients may want to receive notifications for base config changes;
> for example, presentation applications which want to put their

---

From: Alan Griffiths <[email-masked]>
Date: Tue, 20 Oct 2015 13:57:02 +0100

> - Is it in Mir's scope as a display server to provide a client api for configuring mir server settings like those for displays & input devices? Or should Mir expose a mirserver API for these settin…

When asking a question like this it is important to consider what such
an API means in the context of a system Mir and (possibly multiple)
session Mir.

We currently provide both a client and server APIs for configuring
displays - and (ignoring a mass of bugs) the display config set by the
active session Mir is applied by the system Mir. And the display config
set by the current client is applied to the session Mir and recursively
to the system Mir.

That model makes sense to me. (Although as discussed in this thread the
current implementation of that model is somewhat lacking.)

I don't think there's a need for an API to change the "base"
configuration of the system Mir which suggests that such an API might
not be core to Mir. OTOH it isn't a costly thing to provide or support.

---

From: [email-masked]
Date: Wed, 21 Oct 2015 21:21:46 +1100

On Tue, Oct 20, 2015 at 11:16 PM, Gerry Boland 
<[email-masked]> wrote:
> Hey folks,
> it appears this topic has gone stale, without any consensus being 
> reached. A core issue impacting this discussion which remains 
> undecided is the following:
> 
> - Is it in Mir's scope as a display server to provide a client api 
> for configuring mir server settings like those for displays & input 
> devices? Or should Mir expose a mirserver API for these settings, and 
> require the shell to implement its own API via an alternative channel 
> (e.g. DBus) for a settings client to use?

I have a well-known aversion to shipping API that is useful for exactly 
one client which is always shipped with the shell and is harmful if 
used by any other client. Both the set-base-display-config and 
set-input-configuration APIs fall under this concern.

Now, that said, this *is* something that every shell is going to need 
to handle in some fashion, and it's perfectly reasonable for Mir to 
provide support for it. In the Wayland world this is just done with 
ad-hoc protocol, because that's easy. For us, I think that having a 
separate libmirclient-shell¹ that contained these APIs would satisfy 
my paranoia and also be useful for Unity8.

For bonus fun points this will be another capability check needed on 
the MirConnection. Can we add a create_privileged_session_for(socket) 
API, or is it still not possible for Unity8 to hand sockets off to 
clients?

¹: Name to be exhaustively bikeshedded.

---

From: Thomas Voß <[email-masked]>
Date: Wed, 21 Oct 2015 12:38:34 +0200

On Wed, Oct 21, 2015 at 12:21 PM,  <[email-masked]> wrote:
> On Tue, Oct 20, 2015 at 11:16 PM, Gerry Boland <[email-masked]>
> wrote:
>>
>> Hey folks,
>> it appears this topic has gone stale, without any consensus being reached.
>> A core issue impacting this discussion which remains undecided is the
>> following:
>>
>> - Is it in Mir's scope as a display server to provide a client api for
>> configuring mir server settings like those for displays & input devices? Or
>> should Mir expose a mirserver API for these settings, and require the shell
>> to implement its own API via an alternative channel (e.g. DBus) for a
>> settings client to use?
>
>
> I have a well-known aversion to shipping API that is useful for exactly one
> client which is always shipped with the shell and is harmful if used by any
> other client. Both the set-base-display-config and set-input-configuration
> APIs fall under this concern.
>

Well, we always need to satisfy the case of handing configuration up & down a
nested shell scene. If we don't add the respective functionality to
the client api, we end up in
the situation of Unity8 being unable to speak to its parent Mir
instance. With that, configuration API
should live in the client API from my POV.

> Now, that said, this *is* something that every shell is going to need to
> handle in some fashion, and it's perfectly reasonable for Mir to provide
> support for it. In the Wayland world this is just done with ad-hoc protocol,
> because that's easy. For us, I think that having a separate
> libmirclient-shell¹ that contained these APIs would satisfy my paranoia and
> also be useful for Unity8.
>
> For bonus fun points this will be another capability check needed on the
> MirConnection. Can we add a create_privileged_session_for(socket) API, or is
> it still not possible for Unity8 to hand sockets off to clients?
>

Either that, or we borrow ideas from Macaroons, requiring clients to
pass in a "cookie" to privileged functions.
One additional benefit would be easier reading of the API as the
arguments make it immediately clear which functions require a prior
negotiation of permissions.

> --
> Mir-devel mailing list
> [email-masked]
> Modify settings or unsubscribe at:
> https://lists.ubuntu.com/mailman/listinfo/mir-devel

---

From: Alan Griffiths <[email-masked]>
Date: Wed, 21 Oct 2015 15:38:44 +0100

> should live in the client API from my POV.

I'm not sure what /you/ are referring to here. The existing APIs and
design deals with handing configuration up & down a nested
configuration. The discussion is about adding an API to change the
Unity8 "base configuration" - the one used when the current client (if
any) hasn't selected a configuration itself.
> negotiation of permissions.

We could do the same as we have with prompt providers and simply connect
the configuration client via a "trusted" socket.

---

From: Thomas Voß <[email-masked]>
Date: Wed, 21 Oct 2015 20:15:28 +0200

> any) hasn't selected a configuration itself.

Hmmm, I fail to see the difference, even having re-read the thread.
Would you mind
summarizing where the difference arises?

> the configuration client via a "trusted" socket.

Well, the prompt provider solution was introduced as a first step
towards a more
generic mechanism for handling "privileged" API. I'm not saying we
have to come up with
a full-featured solution right now, but we should keep in mind that a
"trusted" socket only allows
for very coarse-grained authentication of clients.

Cheers,

  T

> Modify settings or unsubscribe at: https://lists.ubuntu.com/mailman/listinfo/mir-devel

---

From: Alan Griffiths <[email-masked]>
Date: Thu, 22 Oct 2015 09:18:16 +0100

> summarizing where the difference arises?

https://docs.google.com/a/canonical.com/document/d/1wpoHVYdPZGthN2WS8oDvhRlpyuUqrizK1C4quE4XwMk/edit?usp=sharing

---

From: Christopher James Halse Rogers <[email-masked]>
Date: Fri, 23 Oct 2015 11:51:26 +1100

> summarizing where the difference arises?

The “base configuration” is the shell's default configuration, 
applied when no client-specific configuration is applied.

At the interface between layers (kms ← USC or USC ← Unity8) there 
is no concept of “default configuration” - USC *has* to set *some* 
KMS configuration, and likewise, Unity8 has to set *some* configuration 
on USC.

The default configuration lives entirely inside a single layer; it only 
has influence on what configuration is requested of the lower layer.

> for very coarse-grained authentication of clients.

I'm rather partial to the capsicum method of delegating capabilities - 
if you've got a thing, you can use the thing.

In this case you could quite easily have a get_capability() RPC call 
that returns a socket you can talk that privileged protocol over. This 
also has the pleasant property of easily allowing us to split the 
client library into various bits - mirclient for all the API that 
regular clients need, mirclient-prompt for clients that need the prompt 
API, mirclient-testing for test-only APIs¹, mirclient-shell, and so on.

¹: This also lets us resolve a longstanding TODO in libmirclient-debug