It is worth noting that FIFO only holds for messages coming from a single thread. If you have one thread posting keyboard events and another mouse events it is very possible that the reader will get them in the "wrong" order, even with tens of milliseconds separating them from the user's POV.
Now it seems obvious when I say it, but it is easy to forget that when you develop the reader side, especially since most of the times the ordering will hold. This leads to intermittent and non-obvious bugs down the line.
On the other hands, if you fully acknowledge the lack of ordering guarantee, you can use that to make a more efficient queue by using one-buffer-and-lock-per-thread. Each producer fills its own lock-protected queue, and the reader just needs to find a non-empty queue, lock it and pop an item, without any penalty for the other threads.
Of course, the inter-thread ordering will be even worse but you keep the ordering of events from one producer, which was the only actual guarantee you had to begin with in the naive version.