This way we can monitor both appmenu and window menu simultaneously and (theoretically)
switch between one and the other on the fly.
The Menu class is now Window as it encapsulates an entire window with everything that belongs to it.
All DBusMenu-specific code is in Window whereas GMenu-stuff is in Menu and so it's less entangled
CanConvert also happily converts a string to a bool, so explicitly check for type
and for radio buttons we get a string telling us which is the currently checked action
When switching from LibreOffice splash to e.g. Writer, it creates an entirely new
section for us and then replaces the "root" menu with an alias to that new section.
Since we couldn't create new sections in this fashion we would get an alias to a
non-existing menu and break. This addresses this.
appmenu-gtk-module always claims to have a menu even if there is none, so we need to
check that in advance and only write the window property announcing global menu support
if we successfully managed to acquire a menu
appmenu-gtk-module always announces a menu bar even if there is none, so we always
request a menu bar and when it turns out to be empty and have actually have an app menu
to fall back to we'll use that instead.
The original code resolved them when the menu was requested as I thought that made constructing the dbus menu
easier as in dbus menu it's just a contiguous list of actions. However, this also changed the mapping from
dbus action to GTK action (the latter does not have a unique ID system), so when a GTK app signalled a change
(e.g. a menu item got added/removed), the signal was for the original position of the item and not the
resolved one we were using internally.
By resolving everything on the fly, the IDs stay correct, and updating the menu mostly works now.
There's still something funky going on when moving from e.g. LibreOffice splash to LibreOffice Writer
but that needs to be investigated now.
The code assumes being enabled is the default, which is true, however
when we signal an action change from disabled to enabled, we would not send
along the enabled property and thus it never updated.
For simplicity, just always send it along.
Also init after having connected to signals, this might fix issues where the menu won't show up the first time
an application window shows as the menu might have requested setting the window properties before we connected
to that (unlikely, but who knows).
This is in preparation for being able to fall back from window menu to application menu should the former be empty.
It's perfectly fine for a window to have a menu only consisting of application actions.
Also improve update logic by signalling individual item changes rather than having it rebuild
the menu every time. Also optimize the menu change handler to just update items when the same
number of items is inserted and removed at once
* Cleanup code and use categorized logging
* Monitor action changes (e.g. toggled state of checkbox)
* Monitor menu changes (e.g. menu label changed)
* Handle when app has no menu on startup but gets one later
* Disable GTK menu bar when we're running
When the window goes away there's no x window to remove properties from and also the
DBus interface for the menu seems to go away before we could unsubscribe
* Send delayed reply when we aren't subscribed yet in GetLayout
* Show keyboard shortcuts (crude)
* Add some icons for known actions (even more crude)
* Support GTK actions stuff, including action enabled/visible/checkable
* Action invocation
This will mediate between applications using GMenu (like LibreOffice) and expose their menus
using our DBusMenu protocol so that no changes on our global menu side is needed.
WIP: So far all it can do is detect windows with GMenus attached to it, register a DBus service
and then announce the corresponding DBusMenu paths.