GNOME Bugzilla – Bug 599248
Add no_focus_windows preference to list windows that shouldn't be focused
Last modified: 2020-11-06 20:05:06 UTC
I'm expecting some howls of protest on this patch (if nobody is howling, nobody is listening.) The basic justification for adding functionality here is that legacy apps that steal focus can cause users to tie themselves into Metacity configuration knots: - There is some legacy app that is stealing focus away from my terminal: let me use focus_new_windows=strict - Now when I launch windows from the terminal, they pop behind and flash in the taskbar. I need more config options to fix this! So the idea here is to short-circuit the chain at the beginning and provide a means for site-adminstrators to fix troublesome applications without having to configure and hack-out all the focus-stealing-prevention goodness. So, the second second of howls will likely be about the way I did it - arbitrary boolean expressions? s-exps? 400 lines of parsing code? So, let me provide some background to my thinking here. * Since we're dealing by hypothesis with a legacy app that can't be modified, we need a fair bit of matching power - we can't just expect the app to be modified to export a suitable WM_ROLE; this is why I wanted to allow matching on boolean combinations of WM_NAME and WM_CLASS. * I decided against some g_strsplit()-parsable syntax of 'class:Mylegacyapp,name:New mail;...' or something because it was going to be a) horrible and b) not extensible. * I went with s-exps for the standard reason: I wanted something that was expressive without having to invent a syntax and provide a yacc grammar or complicated hand-built parser. * The use of globs rather than regular expressions for pattern matching has no real justification other than I wanted a patch I could backport to glib-2.12, which doesn't have GRegex. The syntax is extensible to allow regular expressions to be added with a few more lines, if there was really a reason. * Those familiar devilspie may notice that the expressions are incompatible with the sxpressions it uses - where devilspie has: (is (window-class) "Mylegacyapp") I have: (eq class "Mylegacyapp") Basically the reasoning was that I couldn't be 100% compatible with devilspie (needed boolean operators, couldn't use regular expressions), so I decided to just do what made sense to me and kept the parsing code simple. * So why not just make this a devilspie functionality? Make devilspie set _NET_WM_USER_TIME? Doesn't work - because we are dealing with new windows and trying to change their props out of devilspie would be inherently racy. * The patch isn't quite as big as it looks - about a third of the code in window-matcher.c is unit tests that are #ifdef'ed out. Clearly this patch isn't in "the spirit of Metacity", but the basic idea is, as described above, to workaround broken apps and keep focus handling working as designed.
Created attachment 145999 [details] [review] Add no_focus_windows preference to list windows that shouldn't be focused Notification windows from legacy software that don't set _NET_WM_USER_TIME can be a huge annoyance for users, since they will pop up and steal focus. Add: /apps/metacity/general/no_focus_windows which is a list of expressions identifying new windows that shouldn't ever be focused. For example: (and (eq class 'Mylegacyapp') (glob name 'New mail*'))
Created attachment 164443 [details] [review] Exclude the current application from no_focus_windows setting Here's a small add-on on top of the previous patch which changes the behavior slightly - this change was found to be desirable with experience with the patch in the field. ==== The idea of the no_focus_windows setting is to allow identifying legacy application windows that are stealing focus from other applications and suppress that behavior. Sometimes its not possible to identify specific problem windows of an application and its necessary to blanket add all windows of the application. In this case no_focus_windows can disrupt the internal flow of focus within the application. On the assumption that apps internally handle focus correctly and have been tested not to steal focus from themselves at annoying times, we exclude windows of the the current application from no_focus_windows.
Note that the last patch depends on bug 567528 for meta_window_same_client() - much as in the original case for bug 567528, when dealing with legacy app workarounds, we want to broaden "application" and not count on group leaders being properly present. The patch could be committed without the meta_window_same_client() test and still make sense, however.
bugzilla.gnome.org is being replaced by gitlab.gnome.org. We are closing all old bug reports in Bugzilla which have not seen updates for many years. If you can still reproduce this issue in a currently supported version of GNOME (currently that would be 3.38), then please feel free to report it at https://gitlab.gnome.org/GNOME/metacity/-/issues/ Thank you for reporting this issue and we are sorry it could not be fixed.