New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hard/impossible to give keyboard focus to override_redirect window opened while another VM was focused #2311

Open
rustybird opened this Issue Sep 13, 2016 · 7 comments

Comments

Projects
None yet
4 participants
@rustybird

Qubes OS version:

  • R3.1 with KDE (every "focus stealing prevention" level)
  • R3.2-rc3 with Xfce4

If an undecorated window (i.e., using override_redirect) is opened from a VM while a window from a different VM is focused, clicking on the undecorated window is not enough to give it keyboard focus:

  • Case A, the undecorated window is reading keyboard input by grabbing the VM's keyboard. In this case, the user has to focus another (non override_redirect) window in that VM to make keyboard input arrive. This can e.g. break dmenu.
  • Case B, the undecorated window is reading keyboard input by requesting focus explicitly. In this case, there does not seem to be any way the user can give it focus at all.

Steps to reproduce the behavior:

For testing, I've used a Python script that opens an override_redirect window and prints all X11 events to the terminal: https://gist.github.com/rustybird/6dd826a990c643609519e63c61482e63

  1. Minimize all windows belonging to the VM, except for one terminal.
  2. Run sleep 10; ./window.py in the terminal.
  3. Focus a window from another VM before the popup appears.
  4. Move the pointer to the popup without traveling through the terminal.
  5. Click on the popup.

The popup window will receive mouse clicks, but no keyboard input.

@marmarek

This comment has been minimized.

Show comment
Hide comment
@marmarek

marmarek Sep 13, 2016

Member

I see how does it break usability, but not giving direct way to steal
focus is one of our design goals for GUI virtualization... Any idea how
to handle it, without compromising this goal?

Best Regards,
Marek Marczykowski-Górecki
Invisible Things Lab
A: Because it messes up the order in which people normally read text.
Q: Why is top-posting such a bad thing?

Member

marmarek commented Sep 13, 2016

I see how does it break usability, but not giving direct way to steal
focus is one of our design goals for GUI virtualization... Any idea how
to handle it, without compromising this goal?

Best Regards,
Marek Marczykowski-Górecki
Invisible Things Lab
A: Because it messes up the order in which people normally read text.
Q: Why is top-posting such a bad thing?

@rustybird

This comment has been minimized.

Show comment
Hide comment
@rustybird

rustybird Sep 13, 2016

I totally agree that the window should not be able to just steal the keyboard focus without user interaction, i.e. clicking on it. (Although xfwm currently doesn't seem to have any such inter-VM focus stealing prevention? If I run sleep 5; xev and focus another VM, the xev popup receives my keyboard input...)

Is it maybe just that when you click on the VM's window, xfwm (probably like other window managers) sees that it has override_redirect set and does not call XSetInputFocus() on it -- there's no FocusInEvent when window.py is run in dom0 --, and that doing so if the window belongs to a VM would be enough to fix this issue?

rustybird commented Sep 13, 2016

I totally agree that the window should not be able to just steal the keyboard focus without user interaction, i.e. clicking on it. (Although xfwm currently doesn't seem to have any such inter-VM focus stealing prevention? If I run sleep 5; xev and focus another VM, the xev popup receives my keyboard input...)

Is it maybe just that when you click on the VM's window, xfwm (probably like other window managers) sees that it has override_redirect set and does not call XSetInputFocus() on it -- there's no FocusInEvent when window.py is run in dom0 --, and that doing so if the window belongs to a VM would be enough to fix this issue?

@rustybird

This comment has been minimized.

Show comment
Hide comment
@rustybird

rustybird Sep 14, 2016

Ah, the window manager is totally out of the loop for override_redirect windows. I thought it was possible to "override the override".

So my second attempt was to modify xside.c to call XSetInputFocus() not only on windows with is_docked, but also on those with override_redirect. That fixes the issue, but has the side effect of making a main window lose focus (and not get it back automatically) if you click on one of its menu dropdowns; it also breaks the Firefox menu for some reason. And window type hints seem to be used too inconsistently for blacklisting to be viable.

What do you think of this approach:

  1. Keep track of
    • windows requesting focus, and
    • X11 clients grabbing the keyboard (but how to detect this?)
  2. When the user clicks on an override_redirect window, focus it if
    • it previously requested focus, or
    • any X11 client in the same VM is currently grabbing the keyboard

Ah, the window manager is totally out of the loop for override_redirect windows. I thought it was possible to "override the override".

So my second attempt was to modify xside.c to call XSetInputFocus() not only on windows with is_docked, but also on those with override_redirect. That fixes the issue, but has the side effect of making a main window lose focus (and not get it back automatically) if you click on one of its menu dropdowns; it also breaks the Firefox menu for some reason. And window type hints seem to be used too inconsistently for blacklisting to be viable.

What do you think of this approach:

  1. Keep track of
    • windows requesting focus, and
    • X11 clients grabbing the keyboard (but how to detect this?)
  2. When the user clicks on an override_redirect window, focus it if
    • it previously requested focus, or
    • any X11 client in the same VM is currently grabbing the keyboard
@marmarek

This comment has been minimized.

Show comment
Hide comment
@marmarek

marmarek Sep 15, 2016

Member

This may work, but may also have some unwanted side effects. Generally I'm quite reluctant to make any change in GUI code in those two areas:

  • input focus
  • order of windows (back/front)

There are so many corner cases, so many different toolkits (and applications behaving differently - take Firefox as an example), that it's really hard to not break anything.

That said, it may be good idea to add new flag to MSG_WINDOW_FLAGS to signal that given override_redirect window wants focus. When user clicks on that window and the flag is set, give it a focus. Then implement some heuristic in gui-agent for setting this flag. The one you've given may be good enough (especially the first one, not sure about the later one).

Member

marmarek commented Sep 15, 2016

This may work, but may also have some unwanted side effects. Generally I'm quite reluctant to make any change in GUI code in those two areas:

  • input focus
  • order of windows (back/front)

There are so many corner cases, so many different toolkits (and applications behaving differently - take Firefox as an example), that it's really hard to not break anything.

That said, it may be good idea to add new flag to MSG_WINDOW_FLAGS to signal that given override_redirect window wants focus. When user clicks on that window and the flag is set, give it a focus. Then implement some heuristic in gui-agent for setting this flag. The one you've given may be good enough (especially the first one, not sure about the later one).

@JeramyNS

This comment has been minimized.

Show comment
Hide comment
@JeramyNS

JeramyNS Oct 21, 2016

I'm getting a similar issue however the apps I'm switching between are on the same VM.

Basically on workspace 2 I have my ide (phpstorm) and I am constantly switching to workspace 1 where chrome lives.
I find that most times (not every time) I switch from phpstorm to chrome, the mouse will be attached to chrome but the keyboard will still be attached to the ide. Unfortunately causing me to break the code before I can even test it 😞

Switching from chrome by clicking on either the desktop or another app before re-focusing fixes the problem.

Really keen to get this one fixed before I break someone 👊

JeramyNS commented Oct 21, 2016

I'm getting a similar issue however the apps I'm switching between are on the same VM.

Basically on workspace 2 I have my ide (phpstorm) and I am constantly switching to workspace 1 where chrome lives.
I find that most times (not every time) I switch from phpstorm to chrome, the mouse will be attached to chrome but the keyboard will still be attached to the ide. Unfortunately causing me to break the code before I can even test it 😞

Switching from chrome by clicking on either the desktop or another app before re-focusing fixes the problem.

Really keen to get this one fixed before I break someone 👊

@JeramyNS

This comment has been minimized.

Show comment
Hide comment
@JeramyNS

JeramyNS Oct 21, 2016

Actually I'm thinking mine might be a different issue. Just had it happen again without realizing it and then clicked one of the tabs in chrome. Instead of opening the tab, it brought up the ide drop down menu from the other workspace.
What do you think? Should I move this to a separate issue?

Actually I'm thinking mine might be a different issue. Just had it happen again without realizing it and then clicked one of the tabs in chrome. Instead of opening the tab, it brought up the ide drop down menu from the other workspace.
What do you think? Should I move this to a separate issue?

@andrewdavidwong

This comment has been minimized.

Show comment
Hide comment
@andrewdavidwong

andrewdavidwong Oct 23, 2016

Member

@JeramyNS: Is it possible your issue is actually #1455?

Member

andrewdavidwong commented Oct 23, 2016

@JeramyNS: Is it possible your issue is actually #1455?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment