== Modern X Windows can be a very complicated environment I mentioned [[Corebird, the GTK+ Twitter client ../linux/CorebirdViews]] the other day, and generally positive. That was on a logical weekend. The next day I went in to the office, set up Corebird there, and promptly ran into a problem: I couldn't click on links in Tweets, or rather I could but it didn't activate the link (it would often do other things). Corebird wasn't ignoring left mouse clicks in general, it's just that they wouldn't activate links. I had not had this problem at home (or my views would not have been [[so positive ../linux/CorebirdViews]]. I use basically the same [[fvwm-based window manager environment ../sysadmin/MyDesktopTour]] at home and at work, but since Corebird is a GTK+ application and GTK+ applications can be influenced by all sorts of magic settings and (Gnome) setting daemons, I assumed that it was something subtle that was different in my work GTK+/Gnome environment and filed [[a Fedora bug https://bugzilla.redhat.com/show_bug.cgi?id=1425611]] in vague hopes. To my surprise, it turned out to be not merely specific to [[fvwm http://fvwm.org/]], but specific to one aspect of [[my particular fvwm mouse configuration ../sysadmin/MyFvwmButtonBindings]]. The full version is in [[the thread in the fvwm mailing list https://www.mail-archive.com/fvwm@fvwm.org/msg03139.html]], but normally when you click and release a button, the X server generates two events, a ButtonPress and then a ButtonRelease. However, if fvwm was configured in a way such that it might need to do something with a left button press, a different set of events was generated: * a LeaveNotify with mode NotifyGrab, to tell Corebird that the mouse pointer had been grabbed away from it (by fvwm). * an EnterNotify with mode NotifyUngrab, to tell Corebird 'here is your mouse pointer back because the grab has been released' (because fvwm was passing the button press through to Corebird). * the ButtonPress for the mouse button. The root issue appears to be that something in the depths of GTK+ takes the LeaveNotify to mean that the link has lost focus. Since GTK+ doesn't think the link is focused, when it receives the mouse click it doesn't activate the link, but it does take other action, since it apparently still understands that the mouse is being clinked in the text of the GtkLabel involved. (There's a test program that uses a simple GtkLabel to demonstrate this, see [[this https://www.mail-archive.com/fvwm@fvwm.org/msg03150.html]], and apparently there are [[other anomalies https://www.mail-archive.com/fvwm@fvwm.org/msg03153.html]] in GtkLabel's input processing in this area.) If you think that this all sounds very complex, yes, exactly. It is. X has a complicated event model to start with, and then interactions with the window manager add extra peculiarities on top. The GTK+ libraries are probably strictly speaking in the wrong here, but I also rather suspect that this is a corner case that the GTK+ programmers never imagined, much less encountered. In a complex environment, some possibilities will drop through the cracks. (If you want to read a high level overview of passive and active (mouse button) grabs, see eg [[this 2010 writeup by Peter Hutter https://who-t.blogspot.ca/2010/11/high-level-overview-of-grabs.html]]. Having read it, I feel like I understand a bit more about what fvwm is doing here.) By the way, some of this complexity is an artifact of the state of computing when X was created, specifically that both computers and networking were slow. Life would be simpler for everyone if all X events were routed through the window manager and then the window manager passed them on to client programs as appropriate. However, this would require all events to pass through an extra process (and possibly an extra one or two network hops), and in the days when X was young this could have had a real impact on overall responsiveness. So X goes to a great deal of effort to deliver events directly to programs whenever possible while still allowing the window manager to step in. (My understanding is that in [[Wayland https://en.wikipedia.org/wiki/Wayland_(display_server_protocol)]], the compositor handles all events and passes them to clients as it decides. The Wayland compositor is a lot more than just the equivalent of an X window manager, but it fills that role, and so in Wayland this issue wouldn't come up.)