...since the generateErrorResponse() in UiDispatcher already adds some
explanatory boilerplate to the message; and we can not do anything beyond
publishing the message into the UI message box
now this highlights the unsettled decision still the more,
as can be seen by all that unnecessary copying. Basically we move the
Diff into the lambda-closure, from there into an anonymous instance,
from there into the embedded Buffer in MutationMessage, which again
just happens to sit in the closure storage when the action is invoked.
And all of this copying just to move the DiffMessage for consumption
into the TreeMutator...
thus by #1066 we should really get rid of the MutationMessage class altogether!
basically we want a non-modal notification box in the UI,
which normally stays out of the way. A good example of how such
can be accomplished can be found in the Ardour UI.
This leads to the conclusion that we want to differentiate between
varoius degees of severity; some error conditions just can not be
ignored, and must be indicated in an obvious way, e.g. a prominent
nonmodal pop-up to appear for some seconds, while others just warant
an unobstrusive warning sign
- concept for a first preliminary implementation of dispatch into the UI thread
- define an integration effort to build a complete working communication chain
This change was caused by investigation of UI event loop dispatch;
since the GTK UI is designed to run single threaded, any invocation
from other threads need to be diepatched explicitly.
A possible way to achieve this is to use Glib::Dispatcher, which
in turn requires that the current thread (which is in this case the UI thread)
already holds a Glib::MainContext
This prompted me to create a tight link between the external facade interfaces
of the UI and the event loop itself. What remains to be settled is how
to hand over arguments to the action in the main loop
This plugin is essentially an implementation detail, and there is no
mechanism yet to use several different implementations of the interface.
Thus it is pointless to expose the lifecycle methods on a public interface,
while there is no way to obtain an instance of this interface, since the
latter is confined to the internals of the UI subsystem lifecycle
After investigation of current GTK and GIO code, I came to the conclusion
that we do *not* want to rely on the shiny new Gtk::Application, which
provides a lot of additional "convenience" functionality we do neither
need nor want. Most notably, we do not want extended desktop integration
like automatically connecting to D-Bus or exposing application actions
as desktop events.
After stripping away all those optional functions and extensions, it turns
out the basic code to operate the GTK main event loop is quite simple.
This changeset extracts this code from the (deprecated) Gtk::Main and
integrates it directly in Lumiera's UI framework object (UiManager).
this is just a tiny change to make things more othogonal.
Now the unwinding and calls to any GTK / Widget dtors happen *after*
emitting the term signal from UI shutdown. Which means, the other subsystems
are shutting down (in their dedicated threads) as well, thus lowering
the probability of some action still using the UI and triggering an exception
as it turned out, the former functionality was deactivated in 2009
with changeset 6151415
The whole concept seems to be unfinished, and needs to be reworked
and integrated with "Views and Perspectives" (whatever that is...)
See also #1097
Gtk::Main is deprecated, but the new solution, instantiating a
Gtk::Application object does not match our use case, since we handle
all application concerns already and just need a Gtk main loop to run.
Anyway, it became clear that the "main object" will be the new UiManager.
As a first step, I've now moved the (deprecated) Gtk::Main object
down there. Next step (planned) will be to inherit from Gio::Application
and clone some functionality from Gtk::Application
as a result of the preceding refactorings, we have created a
top level UI context, and most actions are now just forwarede
to a dedicated entity within this globalCtx, mostly to the
InteractionDirector.
Thus we're able to get rid of the one-liner functions in
the Actions class by directly delegating to the respective
entity from within the menu definition lambda.
Is this safe?
Under the assumption that the global context outlives the
GTK main loop, this is safe.
...which opens more questions than it solves at the moment.
Especially note #1096, the question how to refer to object-IDs
Maybe we need to enable sending EntryIDs via GenNode?
Anyway, the magic spell is broken now: we have a way how to
establish commands and how to issue them from the UI, with full integration
of UI-Bus, layer separation facade, instance management and ProcDispatcher
Looks like a stepping stone
after extended analysis, it turned out to be a "placeholder concept"
and introduces an indirection, which can be removed altogether
- simple command invocation happens at gui::model::Tangible
- it is based on the command (definition) ID
- instance management happens automatically and transparently
- the extended case of context-bound commands will be treated later,
and is entirely self-contained
as it turns out, we can always trigger commands right away,
the moment all arguments are known. Thus it is sufficient to
send a single argument binding message, which allows us to
get rid of a lot or ugly complexities (payload visitor).
This changeset fixes a huge pile of problems, as indicated in the
error log of the Doxygen run after merging all the recent Doxygen improvements
unfortunately, auto-linking does still not work at various places.
There is no clear indication what might be the problem.
Possibly the rather unstable Sqlite support in this Doxygen version
is the cause. Anyway, needs to be investigated further.
...because this topic serves as a vehicle to elaborate various core concepts
of the UI backbone, especially how to access, bind and invoke Proc-Layer commands