macgitver/libMacGitverCore — pull request #17 by scunz (2014-03-08 21:25:11+00:00)
Title: Weired bugs need weired solutions to unwire them!!!

This obviously fixes the not-appearing menu on Mac OS X. Well, it's at
least obvious if you read the documentation carefully and manage to
connect all the tiny little concepts in libHeaven. Damn, I've been
thinking every now and then about this issue for about half a year!
Yet, the solution is so plain simple and stupid. So, let's have a
look at what the foo was happening here:

We create a MgvPrimaryWindow, which sets its menu bar to a menu bar
obtained from the hic file associated. This menu bar is associated
with a NULL-parent (actually _all_ menu bars from heaven have that
property on Mac OS X). Then it shows itself.

In order to avoid endless loops and wasted cpu cycles, heaven caches
requests to fill the real QMenu, QMenuBar and QToolBar through Qt's
event loop. Any menu changes are accumulated and run in the next loop.
Though, the object itself exists, but initially is totally empty.

He, who know the Qt source by heart, will realise that this empty-ness
is not different from the menu bar that you get, if you just call a
QMainWindow::menuBar() and then bluntly ignore that bar. So, an
all-empty menubar imposes something special, qt internally on Mac OS X.

Now, the qt documentation states, that the _first_ menu bar created
with a NULL-parent will become the so called _default_ menu bar. If
one doesn't create such a default bar, Qt has its very own one (which
actually just contains the "Quit" item on Mac OS X and is empty
everywhere else).

So far for the docs. But since an all-empty menu bar can not be
distinguished from no menu bar at all, Qt might actually exchange the
default menu bar not before it has any content...

Farther down the line, the docs also explain how a window's menu bar
is found: The focused widget is checked for a menu bar, if it has one
this will be used. If it has no parent, the _default_ bar is used. If
it has no menu bar but a parent, the logic goes up the parent hierarchy.
This will eventually land at the window-widget and use either that one's
or the default.

What the documentation does not say, is: _when_ this logic will be
applied. But honestly, it's pretty obvious that it can only be done
while the focus changes. So, we realise that at the moment we _show_
the MgvPrimaryWindow, this logic will be executed.

Finally, at the moment we show the MgvPrimaryWindow, it (of course)
has no parent and a menu bar that looks like it is empty. Qt has not
yet set the default menu bar to our heaven created one. The code to
trigger that is still in the queue in the main event loop.

This at least explains all the strange behaviour we were seeing with
opening a dialog and closing it again. At the time the dialog is opened,
the boot up queue of heaven's internal setup has been run. So, now the
default menu bar is _the right one_. And the menu-bar-finding-logic
will actually find the right one.

After all, what can we do to prove that and to avoid the issue? Simple:
Let's defer the showing of our MgvPrimaryWindow until the method
MenuBarPrivate::reemergeGuiElement() has actually been executed...

And pooof. It works :)

cf.: http://qt-project.org/doc/qt-5.0/qtdoc/mac-differences.html

@antis81 can you verify this really is a :rocket: and merge? :8ball: