(DOC) GTK start-up internals and design of Lumiera's UI-Layer
This commit is contained in:
parent
7db8bf4c0c
commit
4306e47930
3 changed files with 226 additions and 77 deletions
|
|
@ -7,3 +7,72 @@ GTK -- UI toolkit and framework
|
|||
Within this subsection we collect some random bits of information related to our
|
||||
use of the GTK windowing toolkit for building Lumiera's user interface.
|
||||
|
||||
Concepts
|
||||
--------
|
||||
|
||||
A facility like GTK can be seen to serve various needs. It can be used to simplify
|
||||
the arduous task of building a graphical user interface, but it can also be seen as
|
||||
a one-stop solution for just creating a (``damn modern cool'') application, which
|
||||
all ``reasonable'' people today expect to have a shiny GUI. In fact, we can identify
|
||||
these two different levels of support, which inevitably create conflicting goals.
|
||||
|
||||
- GTK-the-framework shall be easy to use and cover everything I never wanted to know
|
||||
about user interfaces. Ideally, I just inherit from a base class, implement two or
|
||||
three abstract methods and fill in my actual working logic.
|
||||
- GTK-the-toolkit is a collection of prefabricated building blocks, ready to be used
|
||||
and put into action, by people with a clear conception about what is required for
|
||||
a productive UI and how to achieve that in detail.
|
||||
|
||||
Needless to say that Lumiera's use of GTK falls into the second category. Even more so,
|
||||
as the GTK UI is just a plug-in, loaded optionally, and not identical with the application
|
||||
as such. Which often places us into a tricky situation -- obviously GTK-the-framework is
|
||||
what attracts most attention, both from the users and the developers.
|
||||
|
||||
The Gtk::Application
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
*In short*: we do not use it, we do not want it, we do not need it, it's just obnoxious.
|
||||
|
||||
In the _good old days(TM)_ there used to be a singleton class `GTK::Main`. You'd activate
|
||||
your application by invoking the blocking function `Main::run()`. This design was sweet
|
||||
and simple, but turned out to be too rigid once people started to expect lots of things
|
||||
to ``just work''. Consequently, `Gtk::Main` was deprecated by the GTK-developers and
|
||||
``replaced'' by `Gtk::Application`. Unfortunately, this move reflects a paradigm shift
|
||||
from _toolkit_ towards an _application building framework._ This framework includes
|
||||
|
||||
- a well defined global application lifecycle
|
||||
- command line parsing with extension points for custom argument handling
|
||||
- a ready-made framework of _actions_, to be arranged into menus and toolbars
|
||||
- management of ``the application instance'', with inter process communication
|
||||
in case the deaf user double clicks the application icon a second time
|
||||
- the notion of a ``associated document type'' and ``desktop actions''
|
||||
to be forwarded to the implementing application, which thus needs to
|
||||
be invocable in service-style.
|
||||
- registration with the desktop, interconnection with the D-Bus
|
||||
|
||||
None of the above is _evil_ in any sense, much is even useful. However, there is a notion
|
||||
of a working style, underlying the vision for Lumiera: work is considered a long-term
|
||||
undertaking, organised into a project and carried out in a fixed and controlled environment
|
||||
over the course of an extended time period. Basically we envision the user to make some
|
||||
_footage_ available to an _editing workstation_, and then to return to this very setup over
|
||||
the course of weeks, or months, or years, expecting everything to remain reliably the same,
|
||||
just as configured initially.
|
||||
|
||||
Based on this model, we basically want to shape all application global concerns in a
|
||||
very specific way -- and almost all the standard solutions offered by GTK-the-framework
|
||||
tend to get into our way of working. For this reason
|
||||
|
||||
- we have our own framework of subsystems
|
||||
- we build our own approach towards command line handling
|
||||
- we rely on the notion of a project to define a specific work environment
|
||||
- we want menus and toolbars to be configurable based on both the project and user preference,
|
||||
goverened by rules and with persistent interface state
|
||||
- we deliberately allow for various ways to launch the application, even without UI
|
||||
- we build our own system to navigate within the UI, spanning several top-level windows and desktops.
|
||||
|
||||
Consequently, none of the services offered by `Gtk::Application` is of much use for us. After reading
|
||||
the source code, we came to the conclusion that it is perfectly valid to sidestep all those aspects
|
||||
of GTK, and just perform those small number of toolkit initialisation steps -- previously invoked
|
||||
by `Gtk::Main` -- directly from our application code. Basically Lumiera's `gui::ctrl::UiManager`
|
||||
replaces `Gtk::Main`, invokes `gtk_init` and enters the blocking event loop by calling `gtk_main`.
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -2,68 +2,145 @@ GTK start-up
|
|||
============
|
||||
:Date: 2018
|
||||
|
||||
//Menu: label start-up
|
||||
|
||||
_some insights regarding the start-up of GTK and related framework aspects_
|
||||
|
||||
A facility like GTK can be seen to serve various needs. It can be used to simplify
|
||||
the arduous task of building a graphical user interface, but it can also be seen as
|
||||
a one-stop solution for just creating a (``damn modern cool'') application, which
|
||||
all ``reasonable'' people today expect to have a shiny GUI. In fact, we can identify
|
||||
these two different levels of support, which inevitably create conflicting goals.
|
||||
As outlined on the link:{ldoc}/technical/code/gtk/index.html[overview page], we need to discern between
|
||||
toolkit aspects, and GTK-the-framework. Moreover, we use GTK though the C++ bindings (`gtkmm`), which also
|
||||
add a thin layer of software abstractions.
|
||||
|
||||
- GTK-the-framework shall be easy to use and cover everything I never wanted to know
|
||||
about user interfaces. Ideally, I just inherit from a base class, implement two or
|
||||
three abstract methods and fill in my actual working logic.
|
||||
- GTK-the-toolkit is a collection of prefabricated building blocks, ready to be used
|
||||
and put into action, by people with a clear conception about what is required for
|
||||
a productive UI and how to achieve that in detail.
|
||||
Initialisation
|
||||
--------------
|
||||
So in order to ``use GTK'' ...
|
||||
|
||||
Needless to say that Lumiera's use of GTK falls into the second category. Even more so,
|
||||
as the GTK UI is just a plug-in, loaded optionally, and not identical with the application
|
||||
as such. Which often places us into a tricky situation -- obviously GTK-the-framework is
|
||||
what attracts most attention, both from the users and the developers.
|
||||
- we need to build our application against the appropriate headers of GTK\--, which also implies to
|
||||
install the corresponding development packages (or a source tree) of the libraries involved.
|
||||
- when our main application decides to use the GTK-UI, it loads the GUI plug-in -- at this point
|
||||
the dynamic loader also requires and loads the runtime libraries of GTK, Glib, GDL, Cairo, Pango,
|
||||
plus the runtime libraries of the C++ wrappers (Gtkmm, Glibmm, Gdlmm)
|
||||
- at this point, the various layers of software comprising ``the GTK'' will require some very
|
||||
specific initialisation hooks to be invoked. Especially
|
||||
|
||||
The Gtk::Application
|
||||
--------------------
|
||||
*In short*: we do not use it, we do not want it, we do not need it, it's just obnoxious.
|
||||
** GTK itself requires the invocation of `gtk_init()` in order to attach to the windowing system.
|
||||
This might also parse additional framework specific command lines and react on some environment
|
||||
variables, init the gettext library and maybe activate interactive UI debugging. But nothing
|
||||
beyond that
|
||||
|
||||
In the _good old days(TM)_ there used to be a singleton class `GTK::Main`. You'd activate
|
||||
your application by invoking the blocking function `Main::run()`. This design was simple
|
||||
and sweet, but turned out to be too rigid once people started to expect lots of things
|
||||
to ``just work''. Consequently, `Gtk::Main` was deprecated by the GTK-developers and
|
||||
``replaced'' by `Gtk::Application`. Unfortunately, this move reflects a paradigm shift
|
||||
from _toolkit_ towards an _application building framework._ This framework includes
|
||||
** the `gtkmm` C\++ wrappers deal with a lot of additional ceremony, required by the plain-C
|
||||
implementation of the GTK core. Especially, they automatically register any ``object type''
|
||||
with the GObject-system of Glib. Moreover, some virtual function tables will be populated
|
||||
and several ``object functions'' and signals need to be wrapped, so client code can invoke
|
||||
the more convenient C++ equivalents. All of this additional initialisation is effected
|
||||
by invoking `Gtk::Main::init_gtkmm_internals()` or the (equivalent) static function within
|
||||
`Gtk::Application`
|
||||
|
||||
- command line parsing with extension points for custom argument handling
|
||||
- a ready-made framework of _actions_, to be arranged into menus and toolbars
|
||||
- management of ``the application instance'', with inter process communication
|
||||
in case the deaf user double clicks the application icon a second time
|
||||
- registration with the desktop, interconnection with the D-Bus
|
||||
- the notion of a ``associated document type'' and ``desktop actions''
|
||||
to be forwarded to the implementing application, which thus needs to
|
||||
be invocable in service-style.
|
||||
** finally, any features of GTK-the-framework need to be initialised and prepared for use:
|
||||
|
||||
None of the above is _evil_ in any sense, much is even useful. However, there is a notion
|
||||
of a working style, underlying the vision for Lumiera: work is a long-term undertaking,
|
||||
organised into a project and carried out in a fixed and controlled environment over the
|
||||
course of an extended time period. Basically we envision the user to make some _footage_
|
||||
available to a _editing workstation_, and then to return to this very setup over the
|
||||
course of weeks, or months, or years, expecting everything to remain reliably the same
|
||||
as configured initially.
|
||||
*** lifecycle events need to be issued. GTK uses ``signals'' for this purpose
|
||||
footnote:[not to be confused with the signals on operating system level]
|
||||
*** registration of document types with the desktop environment
|
||||
*** the application instance will connect to the D-bus and install the necessary callbacks,
|
||||
possibly even waiting for an ``activation event''
|
||||
*** depending on the specific way of _activation_, behaviour and error response of the
|
||||
application instance need to be controlled in distinct ways -- maybe just rendering
|
||||
content or even silently terminating altogether after a timeout has passed
|
||||
|
||||
Based on this model, we basically want to shape all application global concerns in a
|
||||
very specific way -- and almost all the standard solutions offered by GTK-the-framework
|
||||
tend to get into our way of working. For this reason
|
||||
For reasons outlined link:{ldoc}/technical/code/gtk/index.html#_the_gtk_application[above],
|
||||
Lumiera does not need nor use a `Gtk::Application`.footnote:[In fact, most of the framework
|
||||
functionality is actually handled within the base class `Gio::Application`, which corresponds
|
||||
to the plain-C type `GApplication`.] Thus, we leave out the third stage and deal with all those
|
||||
application global aspects through means appropriate to our specific purpose.
|
||||
|
||||
- we have our own framework of subsystems
|
||||
- we build our own approach towards command line handling
|
||||
- we rely on the notion of a project to define a specific work environment
|
||||
- we want menus and toolbars to be configurable based on both the project and user preference
|
||||
- we deliberately allow for various ways to launch the application, possibly in multiple instances
|
||||
- we build our own system to navigate within the UI, spanning several top-level windows and desktops.
|
||||
- our link:{ldoc}/design/architecture/Subsystems.html[Subsystem runner] boots the UI subsystem
|
||||
(`gui::GuiFacade`), which in turn loads the UI-plug-in ('target/modules/gtk_gui.lum').
|
||||
- within this plug-in, the class `gui::GtkLumiera` governs the complete UI lifecycle.
|
||||
- this class holds a member `gui::ctl::UiManager` -- which is our ``UI main object'' and mimics
|
||||
the design of the late `Gtk::Main`.
|
||||
- we inherit from our own `gui::ctrl::ApplicationBase` class, to ensure invocation of all the
|
||||
initialisation and clean-up functions required by GTK
|
||||
- we instantiate a class `gui::ctrl::GlobalCtx` to hold and provide all global services used
|
||||
throughout the UI layer, including population of the menu and global actions
|
||||
- within the global context, there is also `gui::ctrl::WindowLocator`, to keep track of all
|
||||
top-level application windows, and to support direct navigation to relevant entities within
|
||||
the UI, based on _abstracted UI-coordinates_.
|
||||
- finally, `GtkLumiera` invokes the functions
|
||||
|
||||
** `UiManager::createApplicationWindow()` to create the visible interface frame
|
||||
** `UiManager::performMainLoop()` to activate `gtk_main()` -- the blocking GTK event loop
|
||||
|
||||
Consequently, none of the services offered by `Gtk::Application` is of any use for us. After reading
|
||||
the source code, we came to the conclusion that it is perfectly valid to sidestep all those aspects
|
||||
of GTK, and just perform those small number of toolkit initialisation steps -- previously invoked
|
||||
by `Gtk::Main` -- directly from our application code. Basically Lumiera's `gui::ctrl::UiManager`
|
||||
replaces `Gtk::Main`, invokes `gtk_init` and enters the blocking event loop by calling `gtk_main`.
|
||||
|
||||
Running a GTK application
|
||||
-------------------------
|
||||
The _event processing_ is what makes an UI application ``live''. However, event processing must
|
||||
not be confused with graphical presentation. In GTK, it is perfectly valid to create and even
|
||||
show a widget prior to entering the event loop. Yet it is a very fundamental design decision
|
||||
within GTK to operate all of the UI concerns *synchronously*, from within a single dedicated
|
||||
*UI thread*. We consider this a very wise design decision, and expand it to all of Lumiera's
|
||||
UI concerns, including the UI-Bus; any ``interaction mechanics'' has to happen within this
|
||||
single thread, and is completely decoupled from all other application functionality like
|
||||
editing actions and rendering, which happen in separate threads and respond asynchronously
|
||||
by _dispatching_ their reactions back into the UI event thread.
|
||||
|
||||
Due to the shifted scope between the old-style `Gtk::Main` and the corresponding `gtk_main()`
|
||||
C-function on one side, and the newer, more framework-centric `Gtk::Application`, it might seem
|
||||
on first sight, that both will perform different tasks. However, a closer look reveals that
|
||||
during the redesign for GTK-3, the old ``main'' functionality has been _retrofitted_ to rely
|
||||
on the newer, more generic GIO-Framework. More specifically
|
||||
|
||||
- the classical `gtk_main()` without much ado invokes `g_main_loop_run()`, which in turn
|
||||
immediately starts to ``pull'' the GIO main context by repeatedly invoking `g_main_context_iterate()`
|
||||
|
||||
- whereas the `Gtk::Application::run()` invokes `Gio::Application::run()` and from there the new
|
||||
application-level _main function_ `g_application_run(gobj(), argc, argv)`. Which in turn handles
|
||||
all the above mentioned framework concerns (e.g. D-Bus registration / activation). Then it
|
||||
enters `g_main_context_iteration()` which -- similar to `g_main_loop_run()` -- starts ``pulling''
|
||||
the GIO main context by repeatedly invoking `g_main_context_iterate()`
|
||||
|
||||
Thus, once we reach the actual operative state, both paths of activating a GTK application behave
|
||||
essentially the same.footnote:[This is the state of affairs during the GTK-3 lifetime cycle,
|
||||
as verified in 8/2018 based on the source code of `GTK 3.22`. Note though that GTK-4 is ``around
|
||||
the corner'' -- let's see what awesome innovations we have to face then...]
|
||||
|
||||
|
||||
The application activation signal
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
However, the old-style approach seems to lack a feature offered by `Gio::Application`:
|
||||
the *activation* signal, which is a feature solely present at the ``application-framework'' level
|
||||
and used internally for the convenience function to ``run an ApplicationWindow object''
|
||||
(-> `Gtk::Application::run(Gtk::Window&)`). In fact, this happens to be a lifecycle event,
|
||||
and can be used by connecting a SigC++ slot to the application object's `signal_activation()`.
|
||||
Outside the realm of GTK-the-framework this feature turns out to be not so useful; especially, the
|
||||
signal is emitted _shortly before_ entering the event loop, and not from within (as you'd might expect).
|
||||
|
||||
A better alternative is to rely on the `Glib::signal_idle()` rsp. `Glib::signal_timeout()`. Both allow
|
||||
to invoke a slot only once, and both ensure the invocation really happens from within the event loop.
|
||||
|
||||
SigC++ trackable
|
||||
~~~~~~~~~~~~~~~~
|
||||
Any closure or callback based system of wiring and activation suffers from the inherent danger of invoking
|
||||
a dangling reference. Within an interactive UI environment, this problem becomes quite acid, since widgets
|
||||
will be created and destroyed through arbitrary interactions, yet still need to be connected to ``live state''.
|
||||
When building UI applications with Gtkmm (the C\++ wrapper of GTK), this problem is dealt with by inheriting
|
||||
all widget classes from the `sigc::trackable` mix-in. This mechanism automatically detaches a signal slot
|
||||
when the corresponding target widget goes out of scope. However, this solution only works reliably when
|
||||
all slots are created and connected from within a single thread (the UI event thread!). Moreover, we
|
||||
can not possibly ``track'' a slot created from a C\++ language lambda or functor -- which sometimes
|
||||
is even the only option, unless we want to incur a dependency on the SigC++ library. In Lumiera,
|
||||
we have a strict policy to prohibit any dependency on GTK libraries outside the UI layer.
|
||||
|
||||
|
||||
Shutdown
|
||||
--------
|
||||
The GTK main loop terminates after invocation of `gtk_main_quit()` (or in case of serious internal errors).
|
||||
Typically, this function is somehow bound to a widget interaction, like clicking on the ``close'' button.
|
||||
In Lumiera, this concern is managed by the `gui::ctrl::WindowLocator`, which keeps track of all top-level
|
||||
windows and terminates the UI when the last one is closed. Moreover, the UI can deliberately be closed
|
||||
by sending an event over the `GuiNotification::triggerGuiShutdown(message)' call.
|
||||
|
||||
After leaving the main loop, the external façade interfaces are closed. By general architectonic reasoning,
|
||||
no event can be processed and no signal can be invoked any more -- and thus we're free to destroy all widgets,
|
||||
services and the backbone of the UI. After that, the UI subsystem signals termination, which causes all other
|
||||
subsystems to shut down as well.footnote:[We are aware that there is a race between closing the façade and actually
|
||||
ceasing other subsystem's activities, which might cause those other activities to fail with an exception]
|
||||
|
||||
|
|
|
|||
|
|
@ -1659,7 +1659,7 @@
|
|||
</html></richcontent>
|
||||
<arrowlink COLOR="#851358" DESTINATION="ID_548720270" ENDARROW="Default" ENDINCLINATION="-663;-614;" ID="Arrow_ID_325703166" STARTARROW="None" STARTINCLINATION="1110;608;"/>
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
<node COLOR="#338800" CREATED="1485118623744" HGAP="23" ID="ID_392996871" MODIFIED="1518487921055" TEXT="#1032 use gtk::Application instead of gtk::Main" VSHIFT="11">
|
||||
<node COLOR="#338800" CREATED="1485118623744" FOLDED="true" HGAP="23" ID="ID_392996871" MODIFIED="1533325801383" TEXT="#1032 use gtk::Application instead of gtk::Main" VSHIFT="11">
|
||||
<arrowlink COLOR="#ae1856" DESTINATION="ID_206480879" ENDARROW="Default" ENDINCLINATION="715;0;" ID="Arrow_ID_926482654" STARTARROW="Default" STARTINCLINATION="134;383;"/>
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1485118668802" ID="ID_575152579" MODIFIED="1518487921055" TEXT="WindowManager verwendet gtk::Main"/>
|
||||
|
|
@ -1798,7 +1798,11 @@
|
|||
<node COLOR="#2f1d56" CREATED="1495218684994" ID="ID_101574501" MODIFIED="1518487921056" TEXT="vorerst defensiv vorgehen">
|
||||
<font ITALIC="true" NAME="SansSerif" SIZE="12"/>
|
||||
</node>
|
||||
<node CREATED="1495218699712" ID="ID_1332523704" MODIFIED="1518487921056" TEXT="den Code aus Gtk::Main in unsere Codebasis übernehmen">
|
||||
<node COLOR="#338800" CREATED="1533325503372" ID="ID_1815764983" MODIFIED="1533325787563" TEXT="nochmal gründlich überprüft und dokumentiert">
|
||||
<arrowlink COLOR="#70dcb9" DESTINATION="ID_889790361" ENDARROW="Default" ENDINCLINATION="1308;0;" ID="Arrow_ID_1988524020" STARTARROW="Default" STARTINCLINATION="-2084;0;"/>
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1495218699712" ID="ID_1332523704" MODIFIED="1533325519569" TEXT="den Code aus Gtk::Main in unsere Codebasis übernehmen">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node CREATED="1495218714230" FOLDED="true" ID="ID_1371091843" MODIFIED="1531584014122" TEXT="Vorsicht mit Action / ActionGroup">
|
||||
|
|
@ -15890,8 +15894,8 @@
|
|||
<font ITALIC="true" NAME="SansSerif" SIZE="12"/>
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1532788645307" ID="ID_254810710" MODIFIED="1532788655288" TEXT="Trigger-Technik klären">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node COLOR="#338800" CREATED="1532788645307" ID="ID_254810710" MODIFIED="1533325370427" TEXT="Trigger-Technik klären">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1532788681197" FOLDED="true" HGAP="336" ID="ID_32192034" MODIFIED="1533310206546" TEXT="bei GTK selber abschauen" VSHIFT="-52">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
|
@ -16112,9 +16116,9 @@
|
|||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1532788727680" HGAP="57" ID="ID_889790361" MODIFIED="1533310405367" TEXT="Gtk::Main auf aktuellem Stand" VSHIFT="8">
|
||||
<arrowlink COLOR="#f3396a" DESTINATION="ID_1283695968" ENDARROW="Default" ENDINCLINATION="-81;-236;" ID="Arrow_ID_1530325920" STARTARROW="None" STARTINCLINATION="119;-5;"/>
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node COLOR="#338800" CREATED="1532788727680" FOLDED="true" HGAP="69" ID="ID_889790361" MODIFIED="1533325857935" TEXT="Gtk::Main auf aktuellem Stand" VSHIFT="12">
|
||||
<linktarget COLOR="#70dcb9" DESTINATION="ID_889790361" ENDARROW="Default" ENDINCLINATION="1308;0;" ID="Arrow_ID_1988524020" SOURCE="ID_1815764983" STARTARROW="Default" STARTINCLINATION="-2084;0;"/>
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#338800" CREATED="1532788737366" ID="ID_1527913663" MODIFIED="1532788745870" TEXT="aktuellen Code bereitlegen in Eclipse">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
|
|
@ -16269,18 +16273,17 @@
|
|||
<icon BUILTIN="info"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1532797168836" ID="ID_1283695968" MODIFIED="1533218227864" TEXT="TODO: diesen Stand dokumentieren">
|
||||
<linktarget COLOR="#f3396a" DESTINATION="ID_1283695968" ENDARROW="Default" ENDINCLINATION="-81;-236;" ID="Arrow_ID_1530325920" SOURCE="ID_889790361" STARTARROW="None" STARTINCLINATION="119;-5;"/>
|
||||
<icon BUILTIN="flag-pink"/>
|
||||
<node COLOR="#338800" CREATED="1532797168836" ID="ID_1283695968" MODIFIED="1533325339452" TEXT="diesen Stand dokumentieren...">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1532797180066" ID="ID_687615166" MODIFIED="1532797192496" TEXT="siehe Ticket #1032">
|
||||
<icon BUILTIN="info"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1533218052308" ID="ID_1734927969" MODIFIED="1533218091117" TEXT="neue Kategorie: technical/code base/ GTK">
|
||||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1533218096245" ID="ID_1901487140" MODIFIED="1533218296183" TEXT="dort Seite startup">
|
||||
<node COLOR="#338800" CREATED="1533218096245" ID="ID_1901487140" MODIFIED="1533325344852" TEXT="dort Seite startup">
|
||||
<arrowlink COLOR="#dc217a" DESTINATION="ID_539459561" ENDARROW="Default" ENDINCLINATION="33;201;" ID="Arrow_ID_601982135" STARTARROW="None" STARTINCLINATION="-55;-186;"/>
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1533218137447" ID="ID_59387223" MODIFIED="1533218142874" TEXT="lose Notizen dorthin"/>
|
||||
<node CREATED="1533218147981" ID="ID_1385133985" MODIFIED="1533218153417" TEXT="Main vs Application"/>
|
||||
<node CREATED="1533218154141" ID="ID_511849124" MODIFIED="1533218165327" TEXT="unser Ansatz"/>
|
||||
|
|
@ -16466,12 +16469,12 @@
|
|||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1533311818120" ID="ID_413505030" MODIFIED="1533311824592" TEXT="Forschung: wie machbar?">
|
||||
<icon BUILTIN="flag-pink"/>
|
||||
<node COLOR="#338800" CREATED="1533311818120" ID="ID_413505030" MODIFIED="1533325891506" TEXT="Forschung: wie machbar?">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1533311849484" ID="ID_741726269" MODIFIED="1533311856167" TEXT="Problem: gtk_main blockt"/>
|
||||
<node CREATED="1533311863586" ID="ID_1275401100" MODIFIED="1533311895161" TEXT="jeder Aufruf davor könnte zum Race führen"/>
|
||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1533311922114" ID="ID_542781128" MODIFIED="1533311941004" TEXT="gibt es dazu irgendwelche Doku?">
|
||||
<icon BUILTIN="flag-pink"/>
|
||||
<node CREATED="1533311922114" ID="ID_542781128" MODIFIED="1533325883642" TEXT="gibt es dazu irgendwelche Doku?">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#435e98" CREATED="1533311999743" ID="ID_159524494" LINK="https://developer.gnome.org/gtkmm-tutorial/stable/sec-the-constraints.html.de" MODIFIED="1533312023736" TEXT="GTKmm-Tutorial: multithreaded">
|
||||
<font NAME="SansSerif" SIZE="12"/>
|
||||
<icon BUILTIN="info"/>
|
||||
|
|
@ -32300,7 +32303,7 @@
|
|||
<linktarget COLOR="#677ab7" DESTINATION="ID_782313223" ENDARROW="Default" ENDINCLINATION="-1088;-39;" ID="Arrow_ID_234165792" SOURCE="ID_433225506" STARTARROW="None" STARTINCLINATION="-2111;0;"/>
|
||||
<linktarget COLOR="#677ab7" DESTINATION="ID_782313223" ENDARROW="Default" ENDINCLINATION="-981;-106;" ID="Arrow_ID_1912776282" SOURCE="ID_1636078216" STARTARROW="None" STARTINCLINATION="-2111;0;"/>
|
||||
<node CREATED="1495221242285" ID="ID_185528211" MODIFIED="1518487921099" TEXT="Applikation">
|
||||
<node CREATED="1495221272545" ID="ID_624250153" MODIFIED="1518487921099" TEXT="Gtk::Application">
|
||||
<node CREATED="1495221272545" FOLDED="true" ID="ID_624250153" MODIFIED="1533325443038" TEXT="Gtk::Application">
|
||||
<node CREATED="1495222327564" ID="ID_175461027" MODIFIED="1518487921099" TEXT="initialisiert Gio::Application"/>
|
||||
<node CREATED="1495222337235" ID="ID_348472460" MODIFIED="1518487921099" TEXT="setzt ggfs. die Applikations-ID"/>
|
||||
<node CREATED="1495223436241" ID="ID_1015366549" MODIFIED="1518487921099" TEXT="Application::run">
|
||||
|
|
@ -32341,7 +32344,7 @@
|
|||
</node>
|
||||
<node CREATED="1495221537366" ID="ID_381245884" MODIFIED="1518487921099" TEXT="stellt eine dBus-Verbindung bereit"/>
|
||||
<node CREATED="1495221546252" ID="ID_771692992" MODIFIED="1518487921099" TEXT="erbt von Gio::ActionGroup und ActionMap"/>
|
||||
<node CREATED="1533307013028" HGAP="32" ID="ID_1511454400" MODIFIED="1533307028207" TEXT="on activation" VSHIFT="16">
|
||||
<node CREATED="1533307013028" FOLDED="true" HGAP="32" ID="ID_1511454400" MODIFIED="1533325409236" TEXT="on activation" VSHIFT="16">
|
||||
<node CREATED="1533307054478" ID="ID_1200897297" MODIFIED="1533307059929" TEXT="g_application_activate">
|
||||
<node CREATED="1533307252691" ID="ID_11609503" MODIFIED="1533307276116" TEXT="gapplication.c (ca line 2220)"/>
|
||||
<node CREATED="1533307297630" ID="ID_312502406" MODIFIED="1533307298225" TEXT="g_signal_emit (application, g_application_signals[SIGNAL_ACTIVATE], 0)"/>
|
||||
|
|
@ -32461,7 +32464,7 @@
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1495223467588" HGAP="27" ID="ID_666842762" MODIFIED="1533307038494" TEXT="run" VSHIFT="12">
|
||||
<node CREATED="1495223467588" FOLDED="true" HGAP="27" ID="ID_666842762" MODIFIED="1533325417082" TEXT="run" VSHIFT="12">
|
||||
<icon BUILTIN="back"/>
|
||||
<node CREATED="1533306448070" ID="ID_1602611708" MODIFIED="1533307626966" TEXT="g_application_run(gobj(), argc, argv)">
|
||||
<linktarget COLOR="#a9b4c1" DESTINATION="ID_1602611708" ENDARROW="Default" ENDINCLINATION="262;0;" ID="Arrow_ID_1688106140" SOURCE="ID_1228966939" STARTARROW="None" STARTINCLINATION="-50;95;"/>
|
||||
|
|
@ -32500,7 +32503,7 @@
|
|||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1495224595638" ID="ID_1774384379" MODIFIED="1518487921099" TEXT="@deprecated">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
</node>
|
||||
<node CREATED="1495224609188" ID="ID_1615155508" MODIFIED="1533306146656">
|
||||
<node CREATED="1495224609188" FOLDED="true" ID="ID_1615155508" MODIFIED="1533325432144">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
|
|
@ -32517,7 +32520,7 @@
|
|||
<linktarget COLOR="#a9b4c1" DESTINATION="ID_1615155508" ENDARROW="Default" ENDINCLINATION="-27;-158;" ID="Arrow_ID_152226640" SOURCE="ID_1085605910" STARTARROW="None" STARTINCLINATION="-209;0;"/>
|
||||
<node CREATED="1495224862227" ID="ID_762530588" MODIFIED="1518487921099" TEXT="init_gtkmm_internals"/>
|
||||
<node CREATED="1495224890119" ID="ID_137730290" MODIFIED="1518487921099" TEXT="statische funktion"/>
|
||||
<node CREATED="1532795620784" FOLDED="true" ID="ID_1850885017" MODIFIED="1533306139169" TEXT="gtk_init">
|
||||
<node CREATED="1532795620784" FOLDED="true" ID="ID_1850885017" MODIFIED="1533319255913" TEXT="gtk_init">
|
||||
<linktarget COLOR="#87a8bf" DESTINATION="ID_1850885017" ENDARROW="Default" ENDINCLINATION="-195;-45;" ID="Arrow_ID_960670945" SOURCE="ID_377749143" STARTARROW="None" STARTINCLINATION="416;0;"/>
|
||||
<icon BUILTIN="back"/>
|
||||
<node CREATED="1532796724776" ID="ID_685469322" MODIFIED="1532796729971" TEXT="bleibt weiterhin bestehen"/>
|
||||
|
|
@ -32593,7 +32596,7 @@
|
|||
<icon BUILTIN="messagebox_warning"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1532795594468" FOLDED="true" ID="ID_681479502" MODIFIED="1533306019466" TEXT="Main::init_gtkmm_internals">
|
||||
<node CREATED="1532795594468" FOLDED="true" ID="ID_681479502" MODIFIED="1533320812539" TEXT="Main::init_gtkmm_internals">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
|
|
@ -32699,8 +32702,8 @@
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1495224625466" ID="ID_668309036" MODIFIED="1518487921099" TEXT="run">
|
||||
<node CREATED="1495224647071" ID="ID_660577000" MODIFIED="1518487921099" TEXT="gtk_main">
|
||||
<node CREATED="1495224625466" ID="ID_668309036" MODIFIED="1533325422859" TEXT="run">
|
||||
<node CREATED="1495224647071" FOLDED="true" ID="ID_660577000" MODIFIED="1533325424496" TEXT="gtk_main">
|
||||
<font BOLD="true" NAME="SansSerif" SIZE="12"/>
|
||||
<node CREATED="1495224649943" ID="ID_1753452940" MODIFIED="1518487921099" TEXT="g_main_loop_run">
|
||||
<node CREATED="1495224690714" ID="ID_355427981" MODIFIED="1518487921099" TEXT="g_main_context_iterate">
|
||||
|
|
|
|||
Loading…
Reference in a new issue