As the application grows, this unstructured style of event handling and passing easily becomes a nightmare that you cannot easily reason through. Components that handle and issue events start to interact in unexpected ways and your events have lost containment. They are no longer helping you keep your application components uncoupled, instead you are likely to be triggering events on specific components in order to avoid unintended side-effects. What was supposed to help you keep an application uncoupled has now turned into a nightmare of coupling and spaghetti code that's hard to follow and reason about.
This shows the basic idea we introduced in Gradient.
We have an Application object which handles the integration of the rest of the application with a semantic message model. This fulfils the same role as semantic events, but is more explicit. The coupling between components is somewhat more verbose, but it ensures that our hierarchy remains as a tree, rather than a web, which we personally feel is easier to reason about in our application. The individual components keep containment on the base events and transform them into appropriate semantic events.