Mir

Comment 4 for bug 1398852

Revision history for this message
Allison Karlitskaya (desrt) wrote : Re: need a mechanism to create/map surface with timestamp/cookie

I've read the document and was able to find the proposed approach (around page 46), quoted here for convenience:

"""
For example, suppose that you click on a PDF attachment in a mail window. The mail program saves the attachment in a temporary directory, then asks Ubuntu to open it. Ubuntu launches the default PDF viewer, which opens a window to display the document. Ideally, if you did nothing else after the click, the PDF viewer should be focused. But if you did something else, in the same window or another window, the PDF viewer should not be focused.

Unfortunately, in this example, there is no part of the system that “knows” that the reason the PDF viewer window opened was your clicking in the mail window. The mail program doesn’t know that the attachment opened in a PDF viewer. The PDF viewer doesn’t know that the file it’s opening is a mail attachment. And if neither of them know, there’s no way for the window manager to know whether to focus the window. Previously window managers have tackled this using heuristics, guessing based on how recently you did anything in any window. But the faster a program launches, the worse this works.

To minimise this problem, Mir introduces the idea of a focus grant. This is a flag that can be set by the focused application, to say “the next application that requests focus for a surface should be given it”. In the previous example, when you click on the attachment in the mail window, the mail application would set the focus grant: it knows that the attachment is likely to open in another application’s window, even if it doesn’t know which application. So when the PDF viewer opens and implicitly requests focus, Mir focuses it.

But if you interact with any surface while the focus grant is set, Mir should revoke the grant. For example, if you click on the attachment, but then do anything else before the PDF viewer opens — navigate to the next message, click Reply to open a composition window, or launch a different application — the PDF viewer should not be focused when it opens.

This means that there is only ever one focus grant set at a time. If any other surface is focused, it is either because it was granted focus, or because you focused it yourself.
It is still possible for the wrong application to sneak in and take focus before the right one does. But this system should make focus stealing much less common.
"""

The proposed solution is workable, but as noted in the document itself, it can sometimes focus the wrong window.

It also suffers from some possible races, depending on how exactly the "grant" is set. Unless the setting of the grant is a synchronous call (with the application waiting for a reply from Mir to confirm that the grant was successfully set) then there is no guarantee that the grant request was received by Mir before the second application pops up its window. It could easily happen in a multi-tasking environment (particularly in the case that the second application was already running) that the request to open a new window is handled before Mir has a chance to process the grant request. We could try to work around that by saying things like "on receiving a request from an application to open a window Mir will process the queue for all other existing applications to check for grant requests" but this seems exceedingly unreasonable.

The text discusses what happens between two applications but fails to detail how focus requests within an application are handled. Presumably an app is allowed to focus new windows of its own without going through the grant mechanism, but at the same time, this could be subject to focus stealing problems. Consider the case that the user makes a request to the application to open a window but that request takes a while (during which time the user continues to interact with another window of the app). There are many examples of existing applications that pop up windows after a delay (such as Nautilus file operation dialogs). Consider also the case that I click to open a PDF file in my email client and instead of reading another email while I wait, I read another PDF that I had already opened. Since the PDF viewer is the focus application at the time that the new PDF is open, I can only assume that the focus will be stolen by the new PDF.

The most worrying thing about the linked text is that it claims "there is no part of the system that “knows” that the reason" and "window managers have tackled this using heuristics, guessing based on how recently you did anything in any window", both of which are false premises.

Today, under X, "the system" absolutely does know the reason that a window was mapped. It is told the timestamp of the input event that was the ultimate source of that window appearing. This is the mechanism that is used for deciding if focus should be granted or not. There are heuristics for dealing with older programs, but they are not part of this core mechanism.

The long-established X scheme of using input timestamps to map windows is simple to understand, works extremely well, and is completely reliable. The approach is very simple:

 - any time a window opens it tells the display server the timestamp associated with the input event that caused the window to open

 - if this was the most recent input event, the window is given focus.

There are a number of reasons that this sometimes falls over in practice in Ubuntu right now, all of which can be addressed:

 - people expect applications launched from terminal emulators to pop up over the terminal program which has led many applications to "cheat the system" by requesting the current timestamp from the X server and passing it off as the one for the input event that caused the app to open

 - some older applications (think: using Athena, not Gtk or Qt) don't support passing this information, leading to heuristics in some window managers to deal with them

 - compiz has a long history of bugs relating to reliably determining and enforcing the stacking order of windows. This is a problem with compiz -- not with the timestamp-based approach. The system worked well under Metacity and it works well on gnome-shell.

As to the first issue, I proposed (at our face to face meeting) that we could use cookies instead of timestamps. The solution I proposed at the time was simple enough. A cookie would be a 128bit value generated thus:

 - first 64 bits: timestamp
 - second 64 bits: encrypted copy of timestamp

where the encrypted copy of the timestamp is encrypted with an ephemeral key kept in the Mir server, generated on startup, shared with nobody. This would prevent people from faking timestamps while allowing the server to recognise its own cookies without ever having to keep state for remembering which cookies it handed out.

The second issue is mostly a non-issue since whichever mechanism we choose will be a part of Mir from the start. This means that focus passing may not work properly with X emulation, of course, but this is not something the grant system would address either.