Perfectly synchronized input event delivery across all applications was one of the strong and important guarantees that the NeWS window system was designed from the ground up to provide (from since it was originally called "SunDew" in 1985).
But ever since then, no other window system really gave a flying fuck about that, and just blithely drops events on the floor or delivers them to the wrong place, gaslighting and training the users to make up for it by clicking slowly and watching the screen carefully and waiting patiently until it's safe to click or type again, before proceeding.
This kind of loosey-goosey race condition input handling problem that's intrinsic to every "modern" window system and web browser and UI toolkit is exactly why bugs like this tooltip bug appear across all platforms, and go unfixed for 22 years, because everybody is gaslighted into thinking that's just the way it has to be, and they're the only one with the problem, and it's unfixable anyway, and even if it were fixable, they deserve it, etc...
What's could ever go wrong with the occasional indestructible floating randomly worded tooltip blocking your desktop or video player or game? It's "Tooltip Roulette"! Just hope you don't accidentally screen share a naughty tooltip with your mom during a zoom meeting.
(Not that NeWS was without its own embarrassingly stuck popup windows, but NeWS had an essential utility for removing embarrassing windows called "pam", named after the sound you made when you used it, or maybe the original easy cleanup canola oil spray ideal for use in cooking and baking.)
Failing to properly support synchronous event distribution makes it impossible for window managers (ESPECIALLY asynchronous outboard X11 window managers running in a different process than the window system) to properly and reliably support "type ahead" and "mouse ahead".
For example, when a mouse click on a window or function key press changes the input focus, or switches applications, or moves a different window to the top, or pops up a dialog, or opens a new window, the subsequent keyboard and mouse events might not be delivered to the right window, because they are not synchronously blocked until the results of the first input event are handled (changing where the next keyboard or mouse events should be delivered to), so clicking and typing quickly delivers the keystrokes to the wrong window.
I find it extremely annoying to still be forced to use flakey leaky "modern" window systems for 37 years after getting used to NeWS's perfect event distribution model, which is especially important on slow computers or networks (i.e. dial-up modems), or due to paging or thrashing because of low memory (NeWS competing with Emacs), or any other system activity, and especially for games and complex real time applications.
There are still to this day many AAA games that force you to hold a key down for at least one screen update, because they're only lazily checking for key state changes on each draw or simulation tick, instead of actually tracking input events, otherwise they don't register sometimes if you just tap the key, and you have to slowly mash and wait, especially when the game gets slow because there's a lot of stuff on the screen, or has a hiccough because of garbage collection or autosave or networking or disk io or...
James Gosling first wrote the importance of safe synchronous event distribution in 1985 in "SunDew - A Distributed and Extensible Window System":
>The key word in the design of the user interaction facilities is flexibility. Almost anything done by the window system preempts a decision about user interaction that a client might want to decide differently. The window system therefore defines almost nothing concrete. It is just a loose collection of facilities bound together by the extension mechanism.
>Each possible input action is an event. Events are a general notion that includes buttons going up and down (where buttons can be on keyboards, mice, tablets, or whatever else) and locator motion.
>Events are distinguished by where they occur, what happened, and to what. The objects spoken about here are physical, they are the things that a person can manipulate. An example of an event is the E key going down while window 3 is current. This might trigger the transmission of the ASCII code for E to the process that created the window. These bindings between events and actions are very loose, they are easy to change.
>The actions to be executed when an event occurs can be specified in a general way, via PostScript. The triggering of an action by the striking of the E key in the previous example invokes a PostScript routine which is responsible for deciding what to do with it. It can do something as simple as sending it in a message to a Unix process, or as complicated as inserting it into a locally maintained document. PostScript procedures control much more than just the interpretation of keystrokes: they can be involved in cursor tracking, constructing the borders around windows, doing window layout, and implementing menus.
>Synchronization of input events: we believe that it is necessary to synchronize input events within a user process, and to a certain extent across user processes. For example, the user ought to be able to invoke an operation that causes a window on top to disappear, then begin typing, and be confident about the identity of the recipient of the keystrokes. By having a centralized arbitration point, many of these problems disappear.
[...]
>Hopgood:
>How do you handle input?
>Gosling:
>Input is also handled completely within PostScript. There are data objects which can provide you with connections to the input devices and what comes along are streams of events and these events can be sent to PostScript processes. A PostScript process can register its interest in an event and specify which canvas (a data object on which a client can draw) and what the region within the canvas is (and that region is specified by a path which is one of these arbitrarily curve-bounded regions) so you can grab events that just cover one circle, for example. In the registration of interest is the event that you are interested in and also a magic tag which is passed in and not interpreted by PostScript, but can be used by the application that handles the event. So you can have processes all over the place handling input events for different windows. There are strong synchronization guarantees for the delivery of events even among multiple processes. There is nothing at all specified about what the protocol is that the client program sees. The idea being that these PostScript processes are responsible for providing whatever the application wants to see. So one set of protocol conversion procedures that you can provide are ones that simply emulate the keyboard and all you will ever get is keyboard events and you will never see the mouse. Quite often mouse events can be handled within PostScript processes for things like moving a window.
>Like the view system in most GUIs, NeWS included the concept of a tree of embedded views along which events were passed. For instance, a mouse click would generate an event that would be passed to the object directly under the mouse pointer, say a button. If this object did not respond to the event, the object "under" the button would then receive the message, and so on. NeWS included a complete model for these events, including timers and other automatic events, input queues for devices such as mice and keyboards, and other functionality required for full interaction. The input handling system was designed to provide strong event synchronization guarantees that were not possible with asynchronous protocols like X.
>Processing of input events is synchronized at the NeWS process level inside the
NeWS server. This means that all events are distributed from a single queue,
ordered by the time of occurrence of the event, and that when an event is taken
from the head of the queue, all processes to which it is delivered are given a
chance to run before the next event is taken from the queue. When an event is
passed to redistributeevent, the event at the head of the event queue is not
distributed until processes that receive the event in its redistribution have had a chance
to process it. No event will be distributed before the time indicated in its
TimeStamp.
>In some cases, a stricter guarantee of synchronization than this is required. For
instance, suppose one process sees a mouse button go down and forks a new process to display and handle the menu until the corresponding button-up. The new
process must be given a chance to express its interest before the button-up is
distributed, even if the user releases the button immediately. In general,
event processing of one event may affect the distribution policy, distribution of
the next event must be delayed until the policy change has been completed.
This is done with the blockinputqueue primitive.
>Execution of blockinputqueue prevents processing of any further events from
the event queue until a corresponding unblockinputqueue is executed, or a
timeout has expired. The blockinputqueue primitive takes a numeric argument
for the timeout; this is the fraction of a minute to wait before breaking the lock.
This argument may also be null, in which case the default value is used
(currently 0.0083333 == .5 second). Block/unblock pairs may nest; the queue is
not released until the outermost unblock. When nested invocations of
blockinputqueue are in effect, there is one timeout (the latest of the set associated with current blocks).
>Distribution of events returned to the system via redistributeevent is not
affected by blockinputqueue, since those events are never returned to the event
queue.
>The ICCCM is unbelievably dense, it must be followed to the last letter, and it still doesn’t work. ICCCM compliance is one of the most complex ordeals of implementing X toolkits, window managers, and even simple applications. It’s so difficult, that many of the benefits just aren’t worth the hassle of compliance. And when one program doesn’t comply, it screws up other programs. This is the reason cut-and-paste never works properly with X (unless you are cutting and pasting straight ASCII text), drag-and-drop locks up the system, colormaps flash wildly and are never installed at the right time, keyboard focus lags behind the cursor, keys go to the wrong window, and deleting a popup window can quit the whole application. If you want to write an interoperable ICCCM compliant application, you have to crossbar test it with every other application, and with all possible window managers, and then plead with the vendors to fix their problems in the next release.
>Why wrap X windows in NeWS frames? Because NeWS is much better at window management than X. On the surface, it was easy to implement lots of cool features. But deeper, NeWS is capable of synchronizing input events much more reliably than X11, so it can manage the input focus perfectly, where asynchronous X11 window managers fall flat on their face by definition. [...]
>If NeWS alone manages the input focus, it can manage it perfectly. An X window manager alone cannot, because it runs in a foreign address space, and is not in a position to synchronously block the input queue and directly effect the distribution of events the way NeWS is. But even worse is when an X window manager and NeWS both try to manage the input focus at once, which is the situation we are in today. The input focus problem could be solved in several ways: OWM solves the problem elegantly, as PSWM did in the past; OLWM could be made NeWS aware, so that when our own customers run our own external X window manager on our own server that we ship preinstalled on the disks of our own computers, OLWM could download some PostScript and let NeWS handle the focus management the way it was designed.
>It's criminally negligent to ship a product that is incapable of keeping the input focus up to date with the cursor position, when you have the technology to do so. Your xtrek has paged the window manager out of core, and the console beeps and you suddenly need to move the cursor into the terminal emulator and type the command to keep the reactor from melting down, but the input focus stays in the xtrek for three seconds while the window manager pages in, but you keep on typing, and the keys slip right through to xtrek, and you accidentally fire off your last photon torpedo and beam twelve red shirt engineers into deep space!
I think about what could have been, how it should work, whether we could fix this, every time I go to click or touch or type and the system I’m using directs my input to somewhere other than I intended.
But ever since then, no other window system really gave a flying fuck about that, and just blithely drops events on the floor or delivers them to the wrong place, gaslighting and training the users to make up for it by clicking slowly and watching the screen carefully and waiting patiently until it's safe to click or type again, before proceeding.
This kind of loosey-goosey race condition input handling problem that's intrinsic to every "modern" window system and web browser and UI toolkit is exactly why bugs like this tooltip bug appear across all platforms, and go unfixed for 22 years, because everybody is gaslighted into thinking that's just the way it has to be, and they're the only one with the problem, and it's unfixable anyway, and even if it were fixable, they deserve it, etc...
What's could ever go wrong with the occasional indestructible floating randomly worded tooltip blocking your desktop or video player or game? It's "Tooltip Roulette"! Just hope you don't accidentally screen share a naughty tooltip with your mom during a zoom meeting.
(Not that NeWS was without its own embarrassingly stuck popup windows, but NeWS had an essential utility for removing embarrassing windows called "pam", named after the sound you made when you used it, or maybe the original easy cleanup canola oil spray ideal for use in cooking and baking.)
Failing to properly support synchronous event distribution makes it impossible for window managers (ESPECIALLY asynchronous outboard X11 window managers running in a different process than the window system) to properly and reliably support "type ahead" and "mouse ahead".
For example, when a mouse click on a window or function key press changes the input focus, or switches applications, or moves a different window to the top, or pops up a dialog, or opens a new window, the subsequent keyboard and mouse events might not be delivered to the right window, because they are not synchronously blocked until the results of the first input event are handled (changing where the next keyboard or mouse events should be delivered to), so clicking and typing quickly delivers the keystrokes to the wrong window.
I find it extremely annoying to still be forced to use flakey leaky "modern" window systems for 37 years after getting used to NeWS's perfect event distribution model, which is especially important on slow computers or networks (i.e. dial-up modems), or due to paging or thrashing because of low memory (NeWS competing with Emacs), or any other system activity, and especially for games and complex real time applications.
There are still to this day many AAA games that force you to hold a key down for at least one screen update, because they're only lazily checking for key state changes on each draw or simulation tick, instead of actually tracking input events, otherwise they don't register sometimes if you just tap the key, and you have to slowly mash and wait, especially when the game gets slow because there's a lot of stuff on the screen, or has a hiccough because of garbage collection or autosave or networking or disk io or...
James Gosling first wrote the importance of safe synchronous event distribution in 1985 in "SunDew - A Distributed and Extensible Window System":
http://www.chilton-computing.org.uk/inf/literature/books/wm/...
>5.3.3 User Interaction - Input
>The key word in the design of the user interaction facilities is flexibility. Almost anything done by the window system preempts a decision about user interaction that a client might want to decide differently. The window system therefore defines almost nothing concrete. It is just a loose collection of facilities bound together by the extension mechanism.
>Each possible input action is an event. Events are a general notion that includes buttons going up and down (where buttons can be on keyboards, mice, tablets, or whatever else) and locator motion.
>Events are distinguished by where they occur, what happened, and to what. The objects spoken about here are physical, they are the things that a person can manipulate. An example of an event is the E key going down while window 3 is current. This might trigger the transmission of the ASCII code for E to the process that created the window. These bindings between events and actions are very loose, they are easy to change.
>The actions to be executed when an event occurs can be specified in a general way, via PostScript. The triggering of an action by the striking of the E key in the previous example invokes a PostScript routine which is responsible for deciding what to do with it. It can do something as simple as sending it in a message to a Unix process, or as complicated as inserting it into a locally maintained document. PostScript procedures control much more than just the interpretation of keystrokes: they can be involved in cursor tracking, constructing the borders around windows, doing window layout, and implementing menus.
>Synchronization of input events: we believe that it is necessary to synchronize input events within a user process, and to a certain extent across user processes. For example, the user ought to be able to invoke an operation that causes a window on top to disappear, then begin typing, and be confident about the identity of the recipient of the keystrokes. By having a centralized arbitration point, many of these problems disappear.
[...]
>Hopgood:
>How do you handle input?
>Gosling:
>Input is also handled completely within PostScript. There are data objects which can provide you with connections to the input devices and what comes along are streams of events and these events can be sent to PostScript processes. A PostScript process can register its interest in an event and specify which canvas (a data object on which a client can draw) and what the region within the canvas is (and that region is specified by a path which is one of these arbitrarily curve-bounded regions) so you can grab events that just cover one circle, for example. In the registration of interest is the event that you are interested in and also a magic tag which is passed in and not interpreted by PostScript, but can be used by the application that handles the event. So you can have processes all over the place handling input events for different windows. There are strong synchronization guarantees for the delivery of events even among multiple processes. There is nothing at all specified about what the protocol is that the client program sees. The idea being that these PostScript processes are responsible for providing whatever the application wants to see. So one set of protocol conversion procedures that you can provide are ones that simply emulate the keyboard and all you will ever get is keyboard events and you will never see the mouse. Quite often mouse events can be handled within PostScript processes for things like moving a window.
NeWS Window System:
https://en.wikipedia.org/wiki/NeWS
>Design [...]
>Like the view system in most GUIs, NeWS included the concept of a tree of embedded views along which events were passed. For instance, a mouse click would generate an event that would be passed to the object directly under the mouse pointer, say a button. If this object did not respond to the event, the object "under" the button would then receive the message, and so on. NeWS included a complete model for these events, including timers and other automatic events, input queues for devices such as mice and keyboards, and other functionality required for full interaction. The input handling system was designed to provide strong event synchronization guarantees that were not possible with asynchronous protocols like X.
NeWS 1.1 Manual, section 3.6, p. 25:
http://www.bitsavers.org/pdf/sun/NeWS/NeWS_1.1_Manual_198801...
>Processing of input events is synchronized at the NeWS process level inside the NeWS server. This means that all events are distributed from a single queue, ordered by the time of occurrence of the event, and that when an event is taken from the head of the queue, all processes to which it is delivered are given a chance to run before the next event is taken from the queue. When an event is passed to redistributeevent, the event at the head of the event queue is not distributed until processes that receive the event in its redistribution have had a chance to process it. No event will be distributed before the time indicated in its TimeStamp.
>In some cases, a stricter guarantee of synchronization than this is required. For instance, suppose one process sees a mouse button go down and forks a new process to display and handle the menu until the corresponding button-up. The new process must be given a chance to express its interest before the button-up is distributed, even if the user releases the button immediately. In general, event processing of one event may affect the distribution policy, distribution of the next event must be delayed until the policy change has been completed. This is done with the blockinputqueue primitive.
>Execution of blockinputqueue prevents processing of any further events from the event queue until a corresponding unblockinputqueue is executed, or a timeout has expired. The blockinputqueue primitive takes a numeric argument for the timeout; this is the fraction of a minute to wait before breaking the lock. This argument may also be null, in which case the default value is used (currently 0.0083333 == .5 second). Block/unblock pairs may nest; the queue is not released until the outermost unblock. When nested invocations of blockinputqueue are in effect, there is one timeout (the latest of the set associated with current blocks).
>Distribution of events returned to the system via redistributeevent is not affected by blockinputqueue, since those events are never returned to the event queue.
The X-Windows Disaster:
https://donhopkins.medium.com/the-x-windows-disaster-128d398...
>Ice Cube: The Lethal Weapon [...]
>The ICCCM is unbelievably dense, it must be followed to the last letter, and it still doesn’t work. ICCCM compliance is one of the most complex ordeals of implementing X toolkits, window managers, and even simple applications. It’s so difficult, that many of the benefits just aren’t worth the hassle of compliance. And when one program doesn’t comply, it screws up other programs. This is the reason cut-and-paste never works properly with X (unless you are cutting and pasting straight ASCII text), drag-and-drop locks up the system, colormaps flash wildly and are never installed at the right time, keyboard focus lags behind the cursor, keys go to the wrong window, and deleting a popup window can quit the whole application. If you want to write an interoperable ICCCM compliant application, you have to crossbar test it with every other application, and with all possible window managers, and then plead with the vendors to fix their problems in the next release.
Window Manager Flames:
http://www.art.net/~hopkins/Don/unix-haters/x-windows/i39l.h...
>Why wrap X windows in NeWS frames? Because NeWS is much better at window management than X. On the surface, it was easy to implement lots of cool features. But deeper, NeWS is capable of synchronizing input events much more reliably than X11, so it can manage the input focus perfectly, where asynchronous X11 window managers fall flat on their face by definition. [...]
>If NeWS alone manages the input focus, it can manage it perfectly. An X window manager alone cannot, because it runs in a foreign address space, and is not in a position to synchronously block the input queue and directly effect the distribution of events the way NeWS is. But even worse is when an X window manager and NeWS both try to manage the input focus at once, which is the situation we are in today. The input focus problem could be solved in several ways: OWM solves the problem elegantly, as PSWM did in the past; OLWM could be made NeWS aware, so that when our own customers run our own external X window manager on our own server that we ship preinstalled on the disks of our own computers, OLWM could download some PostScript and let NeWS handle the focus management the way it was designed.
>It's criminally negligent to ship a product that is incapable of keeping the input focus up to date with the cursor position, when you have the technology to do so. Your xtrek has paged the window manager out of core, and the console beeps and you suddenly need to move the cursor into the terminal emulator and type the command to keep the reactor from melting down, but the input focus stays in the xtrek for three seconds while the window manager pages in, but you keep on typing, and the keys slip right through to xtrek, and you accidentally fire off your last photon torpedo and beam twelve red shirt engineers into deep space!