How to fix: RubyMine / IntelliJ "find file" dialog losing focus on awesome wm

Updated . Posted . Visible to the public.

Many of our developers love to use the "awesome" window manager on Linux. However, RubyMine dialogs occasionally defocus while typing.

Here is a fix for that, tested on awesome 3.4, 3.5 and 4.0 (Ubuntu 14.04 and 16.04).

Problem

Consider the following:

  1. Press Ctrl+Shift+N
  2. "Find file" dialog opens
  3. Type to search, file list appears
  4. Type more, file list is being replaced

If your mouse pointer hovers the file list, the main window is focused when the list is being replaced (or simply when it shrinks and your mouse pointer is then outside of the result list).
When focusing the main window, the "find file" dialog closes.

That would usually be fine, but we don't want to focus the main window in the first place.

The problem appears for all dialogs such as "find file", "find class", "find action", etc.

Solution A

First, try setting a registry flag Show archive.org snapshot in IntelliJ.

  1. Open "Find Action" (Ctrl+Shift+A)
  2. Search for "Registry..." and open that
  3. Set the "focus.follows.mouse.workarounds" flag
  4. Restart IntelliJ

This reportedly works for some users. If it does not, see solution B.

Solution B

Looking into your rc.lua (usually inside ~/.config/awesome/), you will find a section like this:

-- Enable sloppy focus
c:connect_signal("mouse::enter", function(c)
    if awful.layout.get(c.screen) ~= awful.layout.suit.magnifier
        and awful.client.focus.filter(c) then
        client.focus = c
    end
end)

Note that connect_signal was add_signal in earlier versions of awesome (e.g. on Ubuntu 14.04).

Replace it with the following (i.e. paste the 8 lines starting from local focused = client.focus).

-- Enable sloppy focus (without defocusing IntelliJ dialogs)
c:connect_signal("mouse::enter", function(c)
    local focused = client.focus
    if focused 
        and focused.class == c.class
        and focused.instance == "sun-awt-X11-XDialogPeer"
        and c.instance == "sun-awt-X11-XFramePeer"
        then
            return
    end

    if awful.layout.get(c.screen) ~= awful.layout.suit.magnifier
        and awful.client.focus.filter(c) then
        client.focus = c
    end
end)

Restart your awesome afterwards.

If this solution helps, but still does not work all the time, try combining A and B. We've received reports that this does the trick.

Explanation of Solution B

When entering a window (a "client" in awesome-speak), we check the following:

  • Is the new window the same application as the currently focused one? (by comparing X window classes)
  • Are we currently focusing a Java Dialog?
  • Are we entering a Java Frame?

If that's the case, abort.

If not, run the "default" code that decides if a window should be entered (we did not change that one).

Known issues

  • This will not affect "find anything" as IntelliJ uses a sun-awt-X11-XFramePeer for it. There are no properties which allow distinguishing the "find anything" window from the main window.
Arne Hartherz
Last edit
Arne Hartherz
License
Source code in this card is licensed under the MIT License.
Posted by Arne Hartherz to makandra dev (2016-05-31 12:20)