Xmir -rootless: Firefox menus pop up then close right away

Bug #1625846 reported by Brandon Schaefer on 2016-09-20
40
This bug affects 7 people
Affects Status Importance Assigned to Milestone
Canonical System Image
High
Stephen M. Webb
Mir
Triaged
High
Unassigned
MirAL
High
Unassigned
mir (Ubuntu)
High
Unassigned
xorg-server (Ubuntu)
High
Daniel van Vugt

Bug Description

To reproduce:
1) Open firefox on a rootless Xmir
2) Right click or attempt to open the menu on the top right

Expected:
Menu to open

Result:
Menu pops up then closes right away.

I think this is an expected bug, but dont remember the bug# soo figure would make one here :)

*NOTE*: similar cause, but different usecase to lp:1662733

Alan Griffiths (alan-griffiths) wrote :

I see too

Changed in miral:
status: New → Triaged
status: Triaged → Confirmed
importance: Undecided → Medium
Alan Griffiths (alan-griffiths) wrote :
Download full text (14.5 KiB)

Xmir creates, modifies and draws a window:

[2016-09-26 10:30:15.715480] miral::Window Management: place_new_surface app_info={application=XMIR, windows={}}, requested_specification={name=Mozilla Firefox, type=normal, top_left=(656, 27), size=(1248, 1360), output_id=0, state=restored, top_left=(656, 27)} -> {name=Mozilla Firefox, type=normal, top_left=(656, 37), size=(1248, 1360), output_id=0, state=restored, top_left=(656, 37)}
[2016-09-26 10:30:15.715579] miral::Window Management: advise_new_window window_info={name=Mozilla Firefox, type=normal, state=restored, restore_rect=((656, 37), (1248, 1360)), children={}, min_width=0, min_height=0, max_width=2147483647, max_height=2147483647, width_inc=1, height_inc=1, min_aspect={0, 4294967295}, max_aspect={4294967295, 0}, preferred_orientation=15, confine_pointer=0, output_id=0}
[2016-09-26 10:30:15.715682] miral::Window Management: info_for -> Mozilla Firefox
[2016-09-26 10:30:15.715711] miral::Window Management: place_new_surface app_info={application=decorations, windows={0x7fa0d4009ed0}}, requested_specification={name=0x7fa0d4009870, type=gloss, top_left=(923, 338), size=(1248, 10), output_id=0, state=restored, top_left=(923, 338)} -> {name=0x7fa0d4009870, type=gloss, top_left=(656, 27), size=(1248, 10), output_id=0, state=restored, parent=Mozilla Firefox, top_left=(656, 27)}
[2016-09-26 10:30:15.715765] miral::Window Management: advise_new_window window_info={name=0x7fa0d4009870, type=gloss, state=restored, restore_rect=((656, 27), (1248, 10)), parent=Mozilla Firefox, children={}, min_width=0, min_height=0, max_width=2147483647, max_height=2147483647, width_inc=1, height_inc=1, min_aspect={0, 4294967295}, max_aspect={4294967295, 0}, preferred_orientation=15, confine_pointer=0, output_id=0}
[2016-09-26 10:30:15.715778] miral::Window Management: raise_tree root=Mozilla Firefox
[2016-09-26 10:30:15.715790] miral::Window Management: advise_raise window_info={Mozilla Firefox, 0x7fa0d4009870}
[2016-09-26 10:30:15.715802] miral::Window Management: ====
[2016-09-26 10:30:15.738600] miral::Window Management: handle_modify_window window_info={name=Mozilla Firefox, type=normal, state=restored, restore_rect=((656, 37), (1248, 1360)), children={0x7fa0d4009870}, min_width=0, min_height=0, max_width=2147483647, max_height=2147483647, width_inc=1, height_inc=1, min_aspect={0, 4294967295}, max_aspect={4294967295, 0}, preferred_orientation=15, confine_pointer=0, output_id=0}, modifications={name=Mozilla Firefox}
[2016-09-26 10:30:15.738654] miral::Window Management: modify_window window_info={name=Mozilla Firefox, type=normal, state=restored, restore_rect=((656, 37), (1248, 1360)), children={0x7fa0d4009870}, min_width=0, min_height=0, max_width=2147483647, max_height=2147483647, width_inc=1, height_inc=1, min_aspect={0, 4294967295}, max_aspect={4294967295, 0}, preferred_orientation=15, confine_pointer=0, output_id=0}, modifications={name=Mozilla Firefox}
[2016-09-26 10:30:15.738677] miral::Window Management: ====
[2016-09-26 10:30:15.739896] miral::Window Management: handle_window_ready window_info={name=Mozilla Firefox, type=normal, state=restored, restore_rect=((656, 37), (1248, 1360)), children={0x7fa0d4009...

Daniel van Vugt (vanvugt) wrote :

I thought I already fixed this, but you're the second person to suggest otherwise...

affects: miral → xorg-server (Ubuntu)
tags: added: xmir
summary: - [Xmir] Firefox menus pop up then close right away
+ Xmir -rootless: Firefox menus pop up then close right away
Daniel van Vugt (vanvugt) wrote :

Previously reported in bug 1590553

Changed in xorg-server (Ubuntu):
importance: Medium → High
status: Confirmed → Triaged
Christopher Townsend (townsend) wrote :

Yeah, this is going to become more of an issue since we are enabling rootless by default for Libertine apps.

Daniel van Vugt (vanvugt) wrote :

Interesting. It appears this might be a shell/Mir/MirAL bug.

The problem is that Mir shells are sending focus events to surfaces that never receive focus events on normal X desktops. Sending a focus event to a menu that has specified never to receive focus (or is override redirect) is not directly a problem. However it creates a big problem indirectly because an unfocus of the app window happens before a focus of the menu. It's actually the unfocus of the main app window that makes Firefox think that it should then close its menu (or utility bar) immediately. So menus pop up and then vanish instantly, because the app window has lost focus (same kind of issue as recent Unity8 bug 1662733).

The only way to work around this in Xmir is to remove the focus logic we did for the OSK. Then the app window never receives unfocus events and it won't close the menu prematurely. I may write a workaround to let you do that but it's not a solution...

A proper solution requires that Mir surfaces (like some menus) should be able to flag never to send them focus events. And thus when menus open, the app window never receives an unfocus event. This could also solve Unity8 bug 1662733.

Seems like we need some client API work done on the Mir side before the Xmir side can be fixed.

no longer affects: miral (Ubuntu)
Daniel van Vugt (vanvugt) wrote :

Basically it's the old problem of "the focused window is not always the top-most window". Other windowing systems don't assume they're the same and if existing apps are to work with Mir then Mir needs to understand that on-top and focused are not always the same thing. Utility windows like menus are often on top but do not possess the keyboard focus. Focus stays with the app window.

Changed in mir:
importance: Undecided → High
Changed in miral:
importance: Undecided → High
Daniel van Vugt (vanvugt) wrote :

Workaround:
   Xmir -rootless -flatten ...

This will stop the Mir shell from creating separate windows for the menus (or for anything), which in turn prevents the Mir shell from sending unwanted focus events.

tags: added: clientapi
Alan Griffiths (alan-griffiths) wrote :

I briefly wondered if this were related to lp:1660691 - but empirically not:

   $ miral-xrun firefox

creates (and immediately destroys a menu)...

[2017-02-14 09:21:08.828425] miral::Window Management: place_new_window app_info={application=XMIR, windows={Merge into trunk : miral-toolkit-dev : Code : MirAL - Mozilla Firefox}}, requested_specification={name=Firefox, type=menu, top_left=(737, 71), size=(326, 512), output_id=0, state=restored, aux_rect=((605, 59), (0, 0)), placement_hints=3, window_placement_gravity=5, aux_rect_placement_gravity=6, parent=Merge into trunk : miral-toolkit-dev : Code : MirAL - Mozilla Firefox} -> {name=Firefox, type=menu, top_left=(737, 71), size=(326, 512), output_id=0, state=restored, aux_rect=((605, 59), (0, 0)), placement_hints=3, window_placement_gravity=5, aux_rect_placement_gravity=6, parent=Merge into trunk : miral-toolkit-dev : Code : MirAL - Mozilla Firefox}
...
[2017-02-14 09:21:09.094497] miral::Window Management: advise_focus_lost window_info={name=Merge into trunk : miral-toolkit-dev : Code : MirAL - Mozilla Firefox, type=normal, state=restored, restore_rect=((132, 12), (936, 800)), children={0x7f1238006520, Firefox}, min_width=0, min_height=0, max_width=2147483647, max_height=2147483647, width_inc=1, height_inc=1, min_aspect={0, 4294967295}, max_aspect={4294967295, 0}, preferred_orientation=15, confine_pointer=0, output_id=0}
[2017-02-14 09:21:09.094525] miral::Window Management: advise_focus_gained window_info={name=Firefox, type=menu, state=restored, restore_rect=((737, 71), (326, 512)), parent=Merge into trunk : miral-toolkit-dev : Code : MirAL - Mozilla Firefox, children={}, min_width=0, min_height=0, max_width=2147483647, max_height=2147483647, width_inc=1, height_inc=1, min_aspect={0, 4294967295}, max_aspect={4294967295, 0}, preferred_orientation=15, confine_pointer=0, output_id=0}
[2017-02-14 09:21:09.094535] miral::Window Management: raise_tree root=Firefox
[2017-02-14 09:21:09.094548] miral::Window Management: advise_raise window_info={Merge into trunk : miral-toolkit-dev : Code : MirAL - Mozilla Firefox, 0x7f1238006520, Firefox}
[2017-02-14 09:21:09.094564] miral::Window Management: advise_raise window_info={Firefox}
[2017-02-14 09:21:09.094574] miral::Window Management: select_active_window hint=Firefox -> Firefox
[2017-02-14 09:21:09.094579] miral::Window Management: ====
...
[2017-02-14 09:21:09.133042] miral::Window Management: advise_delete_window window_info={name=Firefox, type=menu, state=restored, restore_rect=((737, 71), (326, 512)), parent=Merge into trunk : miral-toolkit-dev : Code : MirAL - Mozilla Firefox, children={}, min_width=0, min_height=0, max_width=2147483647, max_height=2147483647, width_inc=1, height_inc=1, min_aspect={0, 4294967295}, max_aspect={4294967295, 0}, preferred_orientation=15, confine_pointer=0, output_id=0}

Larry Price (larryprice) wrote :

Similar behavior can be seen in Xterm.

1) Open Xterm with rootless Xmir
2) Ctrl+Right-Click very briefly opens menu and then immediately closes menu

Expected behavior: Menu stays open

It seems that Daniel's analysis is correct.

With Mir a newly opened menu surface gets focus. This takes place in msh::AbstractShell::set_focus_to_locked() and the sequence is:

/1/ reconfigure the existing focus window to mir_window_focus_state_unfocused
/2/ reconfigure the new window to mir_window_focus_state_focused

Unfortunately, when it receive the notification for /1/ firefox (or Xterm) reacts by closing the window.

tags: added: rootless
Daniel van Vugt (vanvugt) wrote :

Incomplete for Xmir. We can't fix this in Xmir directly, but are waiting on a fix and/or new client-API from Mir itself to limit automatic focus assignment.

Changed in xorg-server (Ubuntu):
status: Triaged → Incomplete

Incomplete for miral, we can't fix this in miral directly. The way focus works in Mir does seem odd and I'm surprised that the workarounds (ignoring focus loss) in the Qt and Gtk toolkits are "good enough". When we have a plan, then will reassess how miral is affected.

Changed in miral:
status: New → Incomplete
Changed in mir:
status: New → Triaged
status: Triaged → Confirmed
description: updated
tags: added: unity8-desktop
Stephen M. Webb (bregma) on 2017-03-07
Changed in canonical-devices-system-image:
assignee: nobody → Stephen M. Webb (bregma)
status: New → Confirmed
Daniel van Vugt (vanvugt) wrote :

If MirAL can't be fixed right now, that suggests we need to modify libmirserver first, to separate input focus from the stacking order.

kevin gunn (kgunn72) on 2017-03-08
Changed in canonical-devices-system-image:
importance: Undecided → High
Daniel van Vugt (vanvugt) wrote :

Hmm, I could do a semi-permanent workaround in Xmir along the lines of:
   Xmir -flattenOverrideRedirects

That might be adequate to fix this for Firefox and others. Although I dread having to make Xmir lookup a blacklist of broken apps and apply workarounds on the fly. It would be better in the long run to fix the Mir architecture (separate on-top from keyboard focus).

Daniel van Vugt (vanvugt) wrote :

Or I can just try this...

<duflu> mpt: (sorry, I haven't seen or found design docs in a long time) is there any surface type that never gets keyboard focus?

<mpt> duflu, yes, the “gloss” and “tip” types are unfocusable, and an app/toolkit should be able to specify whether a particular “freestyle” window is unfocusable. <https://goo.gl/VWvXTA>

Changed in xorg-server (Ubuntu):
status: Incomplete → Triaged
assignee: nobody → Daniel van Vugt (vanvugt)
Daniel van Vugt (vanvugt) wrote :

OK, I think that "Freestyle" is the appropriate solution here. And that X11 overrideRedirect windows should equate to Freestyle surfaces which never receive input focus.

Mir 0.27/1.0 appears to have a new function for creating freestyle surfaces but I can't find any way to flag that they should not receive keyboard focus (note: I mean keyboard focus only as these still need to receive mouse events).

So a correct solution requires more API work in Mir 0.27/1.0 and possibly related WM logic in MirAL to enforce the "never receives keyboard focus" flag if set (see comment #16).

Changed in mir:
status: Confirmed → Triaged
Changed in miral:
status: Incomplete → Confirmed
Daniel van Vugt (vanvugt) wrote :

Blocked on bug 1671771 now.

Chris Halse Rogers (raof) wrote :

I think bug 1671771 is fundamentally the wrong solution (to this problem; it does need to be fixed).

The problem here is that XMir is not behaving like a spec-compliant X11 window manager. Unless we want to require Mir servers to implement X11 window management, this is not something that we can do with extra Mir support.

One relevant section of one of the relevant X11 protocols is https://tronche.com/gui/x/icccm/sec-4.html#s-4.1.7

Specifically - Firefox is using the Locally Active focus model. It has the focus attribute set to “true” in the WM_HINTS, and has set WM_TAKE_FOCUS on its window.

This means that it (a) expects to receive focus (and receives focus in/focus out events) but (b) only ever expects to be given focus to its top-level window, and will manually manage the focus of its subwindows itself.

XMir is in a position to do this - it doesn't matter which of the client's windows Mir thinks has input focus. As long as *any* of the client's windows have input focus XMir will receive input events and can set the X11 focus as appropriate.

Chris Halse Rogers (raof) wrote :

(The reason why bug 1671771 is not going to fix this is that Firefox¹ *may* set input focus to one of its subwindows, and will behave weirdly if that doesn't work. You can't just set “no focus” on the Mir surface corresponding to Firefox's subwindow and then delegate to Mir's input focus.)

¹: And, if not Firefox, then there'll definitely be *some* X11 app which does this ☺

Chris, although I agree with a lot of what you say, I'm not sure Xmir has all the information it needs at the right time.

As mentioned in comment #11 Mir is unfocussing the one window before focussing the other. When Xmir receives the focus loss it cannot know whether the focus is moving to a related window. It may not even be any window it knows about, so it can't simply defer until receiving the focus gain event.

A the "Locally Active focus model" is a thing, it meets a need. Maybe we should consider supporting it directly in Mir?

Chris Halse Rogers (raof) wrote :

Hm, that's correct. XMir *could* defer acting on focus lost until a timeout or focus-gained event, but that would be a heuristic.

The “Locally Active focus model” is a fairly X11-specific thing. It's from a time when applications were built in a one-X11-window-per-widget fashion, and so a textbox was an individual window that could be focused. I don't think it's going to be useful to Mir clients.

What might be useful - and would give XMir enough information here - is to augment the focus-lost event with the new focus window, if they're from the same session.

Alternatively, a “Session-focus” concept would also solve this. I seem to recall us talking about such a mechanism in the past...

Daniel van Vugt (vanvugt) wrote :

I am aware of the above ICCCM spec and that Xmir doesn't follow it fully, but that's also possibly not the issue here. The issue with supporting the Locally Active focus model is that apps want the ability to either focus their popups explicitly or not at all:

https://tronche.com/gui/x/icccm/sec-4.html#s-4.1.10

In both cases the shell must not implicitly change the focus while the user is interacting with Firefox, but Mir/Unity8 is doing just that. And the unfocus event on the Firefox main window is tricking Firefox into closing the popup (and menus) immediately.

So we apparently have no way out other than to ensure that the SHELL does not ever focus certain popups (as chosen by the toolkit). Xmir already has all the information it needs to make this decision and is only lacking a Mir client API to communicate it to the shell.

Fortunately our Unity8 WM design already provides means for us to do this, and we have not yet implemented it in Mir (comments 16-17).

Also remember that Xmir ignoring focus/unfocus events to work around such bugs is unacceptable, because that leads to the OSK either not appearing or never disappearing.

Chris Halse Rogers (raof) wrote :

I'm clearly communicating poorly, so I'll try again:

The X11 focus, and the Mir focus, do *not* need to be the same.

In fact, a stronger claim holds: X11 focus and Mir focus *cannot* be the same unless we want to implement pieces of X11 window management in Mir.

This does not mean simply ignoring focus events; it means translating Mir focus semantics into X11 focus semantics.

Chris Halse Rogers (raof) wrote :

So, specifically, in this paragraph:

In both cases the shell must not implicitly change the focus while the user is interacting with Firefox, but Mir/Unity8 is doing just that. And the unfocus event on the Firefox main window is tricking Firefox into closing the popup (and menus) immediately.

The phrase “the shell” is wrong. The *X11 window manager* must not implicitly change the focus. Unity8 is not the X11 window manager; XMir is.

Daniel van Vugt (vanvugt) wrote :

I know they don't need to be the same - that's how the workaround 'Xmir -flatten' works. However if they are not the same then the OSK will not function correctly, which is unacceptable. Only acceptable as a temporary workaround...

And we don't need to make the choice to implement X11 window management in Mir, because the Unity8 WM design already requires that we do (indirectly by the missing designed features we haven't implemented yet).

The phrase "the shell" is correct, because that is what is deciding to change the focus to the popup (in the absence of any hint not to). It's also not correct for you to say that "Unity8 is not the X11 window manager". Although I have indeed implemented WM things in Xmir, that is only so much as to pass responsibility for window management on to the shell. Admittedly it's a hybrid approach to attempt to suit Mir's design as well as possible. However in the sense of who owns responsibility for the WM decisions, that is the shell.

We have a Unity8/Mir design document that details a fix, and if we just implement our intended design then this bug will go away.

Chris Halse Rogers (raof) wrote :

Ah, OK. We've been arguing with different assumptions.

Symptom: Firefox's menus don't work
Bug: XMir's focus behaviour differs from a spec-compliant X11 window manager.

One solution here, which is what I've been suggesting, is to implement spec-compliant focus behaviour in XMir.

But you're correct that simply making the popups non-focusable Mir surfaces will make XMir behave more like a spec-compliant X11 window manager, should make it behave *enough* like a spec-compliant WM to resolve the symptom and may well be simpler to implement. This could be an expedient solution for the short term.

Daniel van Vugt (vanvugt) wrote :

Prototyped another workaround:

https://git.launchpad.net/~xmir-team/xorg-server/+git/xmir/commit/?id=0e421f3165501e87349bcd5832c07f172517c3ef

I'm considering turning it on by default, which would allow this bug to be closed on the Xmir task at least, until Mir gets a proper fix (LP: #1671771)

Daniel van Vugt (vanvugt) wrote :
Changed in xorg-server (Ubuntu):
status: Triaged → Fix Committed
Changed in canonical-devices-system-image:
status: Confirmed → Fix Committed
Michał Sawicz (saviq) wrote :

Syncing task from Mir.

Changed in mir (Ubuntu):
importance: Undecided → High
status: New → Triaged
To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Duplicates of this bug

Other bug subscribers