In Gtk3 the progress bar height is fixed and defined by the CSS theme in
use. Changing the widget allocation size does nothing, it is always
rendered the same way.
In many themes, including Adwaita, the progressbar is very, very thin.
Provide custom CSS to specify a height of 8 pixels.
The CSS source string has to be differentiated for Gtk pre and post
3.20, because Gtk 3.20 introduced some breaking changes in the way CSS
is handled.
References:
[1] Migrating from GTK+ 2.x to GTK+ 3 - Parsing of custom resources
https://developer.gnome.org/gtk3/stable/gtk-migrating-GtkStyleContext-parsing.html
[2] Gtk3 Reference Documentation - Changes in GTK+ 3.20
https://developer.gnome.org/gtk3/stable/ch32s10.html
[3] Gnome/HowDoI - Custom Style
https://wiki.gnome.org/HowDoI/CustomStyleCloses#7 - Port to Gtk3
The pulsebar looks very small and needs to be widened. The pulsebar is
packed inside the statusbar so that it displays activity text on the
left side and the pulsebar on the right side. Ideally we want the space
to be evenly divided for the textual messages and for the pulsebar
activity indicator.
For this we just have to set the 'homogeneous' property to TRUE for the
statusbar (note that GtkStatusBar inherits from GtkBox).
Also vertically align the pulsebar to the center of the statusbar. This
is achieved setting the 'valign' property to Gtk::ALIGN_CENTER for the
pulsebar widget.
Closes#7 - Port to Gtk3
There is a bug affecting Gtk+ 3.22.8 to 3.22.30 in which destroying a
GtkComboBox when it is not hidden results in this message:
Gtk-CRITICAL **: gtk_widget_is_drawable: assertion 'GTK_IS_WIDGET (widget)' failed
This happens in GParted when some dialogs are closed, for example the
Create New Partition and Create Partition Table dialogs. To work around
the issue we call Gtk::Dialog::hide() in the destructors of our dialog
classes.
The issue was fixed in Gtk 3.24.0.
* Gtk 3.22.8 was released in February 2017.
* Gtk 3.24.0 was released in September 2018.
References:
[1] Gtk Issue - GtkComboBox::private::popup_window can be NULL
https://gitlab.gnome.org/GNOME/gtk/issues/125
[2] Gtk commit - combobox: popdown() the menu during unmap()
7401794de6
[3] Gtk commit - Check for NULL priv->popup_window in
gtk_combo_box_popdown()
aa5d926c84Closes#7 - Port to Gtk3
There is a bug in Gtkmm3 when setting accelerator keys on a
Gtk::MenuItem, the accelerator keys work but are not displayed when the
menu is drawn. This happens for Gtk::MenuItems, including derived
objects, that are constructed with a non-default constructor.
All non-default constructors of Gtk::MenuItem, and subclasses, work by
creating themselves a Gtk::AccelLabel and packing it inside the menu
item. But in Gtk3 GtkMenuItem are created with a GtkAccelLabel already
packed in as a child and that accel label should be used instead.
To workaround the issue we only use the default constructor for
Gtk::MenuItem and subclasses. This is easy to do because we only have
to change the wrappers in MenuHelpers.cc.
This bug affects Gtkmm version 3.0.0 to 3.22.2 and was fixed in
Gtkmm 3.22.3.
* Gtkmm 3.0.0 was released in April 2011
* Gtkmm 3.22.3 was released in November 2018
References:
[1] Bug Report on the Gtkmm mailing list
https://mail.gnome.org/archives/gtkmm-list/2018-February/msg00006.html
[2] Commit - Gtk::MenuItem: Fix add_accel_label()
e5c8c2df67Closes#7 - Port to Gtk3
Now GParted compiles with Gtkmm3, but we get a failed assertion doing
the following:
* Select a device with more than 1 partition
* Select a partition
* Activate 'Refresh Devices' (or do any operation that causes it, like
mount/unmount etc.)
This is the failed assertion:
**
ERROR:Win_GParted.cc:1152:void GParted::Win_GParted::set_valid_operations(): assertion failed: (valid_display_partition_ptr( selected_partition_ptr ))
Aborted (core dumped)
Where is the problem?
Win_GParted::Refresh_Visual() calls TreeView_Detail::load_partitions()
to clear and refill the treeview.
The problem is in GParted::TreeView_Detail::load_partitions() at
TreeView_Detail.cc:91:
treestore_detail->clear();
This activates TreeView_Detail::on_selection_changed() which in turn
activates Win_GParted::on_partition_selected() passing an old, stale
pointer as an argument. This triggers the failed assertion.
Why does this happen with Gtk3 and not with Gtk2?
First a bit of background of GtkTreeView:
What happens to the selection in a GtkTreeView when the selected row
is removed?
With Gtk2 the selection simply becomes empty, so nothing is selected
afterwards. With Gtk3 this was changed [1] and selection moves to an
adjacent row.
gtk_tree_store_clear() removes rows one by one. While removing rows the
selection changed signal is emitted. With Gtk2 it is emitted only one
time, to indicate that selection has become empty. With Gtk3 it is
instead emitted several times, each time indicating that selection has
moved to the adjacent row.
The handler TreeView_Detail::on_selection_changed() only takes action
when the selection is not empty. So with Gtk3 it really takes action
and activates Win_GParted::on_partition_selected() with a pointer to old
data.
What's the purpose of TreeView_Detail::on_selection_changed()?
Its task is to update the selection in the drawing area above the
TreeViewDetail, the DrawingAreaVisualDisk, so that the selected
partition stays in sync on the two widgets.
Fix by blocking the signal handler during the treeview clear.
Reference:
[1] Commit - treeview: Handle the case where the cursor row gets deleted
1a2932ba29Closes#7 - Port to Gtk3
gdk_spawn_command_line_on_screen() is not present in Gtk3. The
documentation from Gtkmm 2.24 states [1]:
gdk_spawn_command_line_on_screen has been deprecated since version
2.24 and should not be used in newly-written code. This function is
being removed in 3.0. Use either g_spawn_command_line_sync(),
g_spawn_command_line_async() or GdkAppLaunchContext instead.
g_spawn_command_line_sync() and g_spawn_command_line_async() are screen
/ display agnostic, as such we would loose functionality. There is a
workaround, which involves setting the DISPLAY environment variable [2],
but it's a weak solution (and I don't know if it works on backends
other than X11).
GdkAppLaunchContext is an implementation of GIO's GAppLaunchContext that
handles launching an application in a graphical context [3]. Therefore
use GdkAppLaunchContext and GIO's GAppInfo.
GdkAppLaunchContext was introduced in Gtk2 version 2.14. The C++
wrapper Gdk::AppLaunchContext was introduced only in Gtkmm3 version 3.4
[4]. Bump the minimum required version of Gtkmm to 3.4.0 for this
requirement.
GAppInfo was introduced in GLib version 2.16. The C++ wrapper
Gio::AppInfo was introduced in Giomm version 2.16. Note that the
minimum required version for glibmm is already 2.32.
[1] GDK 2 Reference Manual, GdkScreen, gdk_spawn_on_screen()
https://developer.gnome.org/gdk2/2.24/GdkScreen.html#gdk-spawn-on-screen
[2] Migrating from GTK+ 2.x to GTK+ 3 - "Use GIO for launching applications"
https://developer.gnome.org/gtk3/stable/gtk-migrating-2-to-3.html#id-1.6.3.3.7
[3] GDK 3 Reference Manual - "Application launching"
https://developer.gnome.org/gdk3/stable/gdk3-Application-launching.html
[4] Gtkmm 3.4 Gdk::AppLaunchContext Class Reference, Detailed Description
https://developer.gnome.org/gtkmm/3.4/classGdk_1_1AppLaunchContext.html#detailsCloses#7 - Port to Gtk3
GParted uses Gtk::TreeViewColumn::get_cell_renderers(). This is not
present in Gtkmm3. Now Gtk::TreeViewColumn inherits from
Gtk::CellLayout and we have to use Gtk::CellLayout::get_cells() instead.
GtkCellLayout was introduced in Gtk2 version 2.18 as the common
interface for containers of cell renderers.
The C++ wrapper Gtk::CellLayout was introduced in Gtkmm2 version 2.18,
but Gtk::TreeViewColumn was never made to inherit from Gtk::CellLayout
to avoid breaking the API / ABI. That change was made for Gtkmm3.
This is an excerpt from gtkmm/treeviewcolumn.h header in Gtkmm2:
// TODO: Should be deprecated, but we cannot derive from CellLayout
// without breaking API and ABI.
/** Returns a list of all the cell renderers in the column,
* in no particular order.
*
* @return A list of Gtk::CellRenderers.
*/
Glib::ListHandle<CellRenderer*> get_cell_renderers();
Replace Gtk::TreeViewColumn::get_cell_renderers() with base class
method Gtk::CellLayout::get_cells().
Reference:
[1] Commit - "Deprecate get_cell_renderers implementations"
6abc52a29dCloses#7 - Port to Gtk3
In Gtk2 widgets draw themselves in response to the expose event signal.
In Gtk3 widgets draw themselves in response to the GtkWidget::draw
signal, and the signal handler gets a Cairo context as an argument.
Convert Gtk::DrawingArea rendering code to respond to the
GtkWidget::draw signal.
This commit is specific to the drawing area in the Create new Partition
dialog and the Resize/Move dialog.
Reference:
[1] Migrating from GTK+ 2.x to GTK+ 3 - "The GtkWidget::draw signal":
https://developer.gnome.org/gtk3/stable/ch26s02.html#id-1.6.3.4.11Closes#7 - Port to Gtk3
In Gtk2 widgets draw themselves in response to the expose event signal.
In Gtk3 widgets draw themselves in response to the GtkWidget::draw
signal, and the signal handler gets a Cairo context as an argument.
Convert Gtk::DrawingArea rendering code to respond to the
GtkWidget::draw signal.
This commit is specific to the drawing area contained in the main
application window (also called the DrawingAreaVisualDisk).
Reference:
[1] Migrating from GTK+ 2.x to GTK+ 3 - "The GtkWidget::draw signal":
https://developer.gnome.org/gtk3/stable/ch26s02.html#id-1.6.3.4.11Closes#7 - Port to Gtk3
In Gtk2 widgets draw themselves in response to the expose event signal.
In Gtk3 widgets draw themselves in response to the GtkWidget::draw
signal, and the signal handler gets a Cairo context as an argument.
Convert Gtk::DrawingArea rendering code to respond to the
GtkWidget::draw signal.
This commit is specific to the drawing area in the Partition Info
dialog.
Reference:
[1] Migrating from GTK+ 2.x to GTK+ 3 - "The GtkWidget::draw signal":
https://developer.gnome.org/gtk3/stable/ch26s02.html#id-1.6.3.4.11Closes#7 - Port to Gtk3
Starting from Gtkmm3 Gdk::Cursor objects cannot be constructed directly,
but instead you have to get a smart pointer to an instance by calling
the static member function Gdk::Cursor::create().
Gdk::Cursor::create() returns a Glib::RefPtr<Gdk::Cursor> object.
Gtkmm3 always uses Glib::RefPtr<Gdk::Cursor> in its interface and never
plain Gdk::Cursor.
Reference:
[1] Programming with gtkmm3, Changes in gtkmm3:
https://developer.gnome.org/gtkmm-tutorial/3.24/changes-gtkmm3.html.en
"... Gdk::Cursor are now used via Glib::RefPtr."
Closes#7 - Port to Gtk3
In Gtk3 individual headers cannot be included directly in application
code, only the header <gtk/gtk.h> can be included (with a few exceptions
for some platform specific headers).
This has always been considered good practice even for Gtk2, though was
not a hard requirement.
In Gtk3 this is enforced by preprocessor checks. Failure to do so
yields a preprocessor error and compilation fails:
"error: Only <gtk/gtk.h> can be included directly."
Change specific Gtk header includes to:
#include <gtk/gtk.h>
References:
[1] Migrating from GTK+ 2.x to GTK+ 3 - "Do not include individual headers"
https://developer.gnome.org/gtk3/stable/gtk-migrating-2-to-3.html#id-1.6.3.3.3
[2] Commit - "Remove all traces of GDK_PIXBUF/GTK_DISABLE_SINGLE_INCLUDES"
5e29973773Closes#7 - Port to Gtk3
Now that we are compiling against Gtkmm3 there are missing declarations
of Gtkmm identifiers due to changes in Gtkmm internal header structure.
All we have to do is bring back the declarations by including the
appropriate headers where needed.
Add necessary Gtkmm header includes.
Closes#7 - Port to Gtk3
Now that we are compiling against Gtkmm3 there are missing declarations
of Glibmm identifiers due to changes in Gtkmm internal header structure.
All we have to do is bring back the declarations by including the
appropriate headers where needed.
Add necessary Glibmm header includes.
Closes#7 - Port to Gtk3
The Gtk::Widget::modify_fs() API was removed in Gtkmm3 [1] and also
there is no direct replacement. GParted uses this in one place. So
instead use the C gtk_widget_modify_fg() version that is still present
in Gtk3.
This is just a temporary change to port GParted to Gtk3. In future this
will be replaced as part of the switch from Gdk::Color to Gtk::RGBA,
since Gdk::Color was deprecated in Gtkmm 3.10 [2].
Reference:
[1] ee432e2190
commit message "... Remove the modify_*() methods, ..."
[2] Gtkmm 3.10 Gdk::Color Class Reference
https://developer.gnome.org/gtkmm/3.10/classGdk_1_1Color.html#details
Deprecated:
Use Gdk::RGBA instead.
Closes#7 - Port to Gtk3
GParted uses Gtk::Menu_Helpers::MenuList helper class to access
individual menu items. This helper class made it easy to navigate menu
items by index.
Gtk::Menu_Helpers::MenuList was removed in the switch from Gtkmm2 to
Gtkmm3 [1]. Instead, use a separate std::map<Gtk::MenuItem*> to keep
track of individual Gtk::MenuItem objects.
Reference:
[1] Gtkmm 3 commit "MenuShell: Remove items()." removed the code
c8e47b0db5Closes#7 - Port to Gtk3
Gtk::Menu_Helpers::Element class and subclasses help in Gtk::MenuItem
widgets and also automate tasks like registering keyboard accelerators
when parented to a top-level window [1][2].
Gtk::Menu_Helpers::Element class and subclasses were removed in Gtkmm3
[3]. Provide compatible implementations under the namespace
GParted::Menu_Helpers.
References:
[1] gtkmm: Gtk::Menu_Helpers Namespace Reference
https://developer.gnome.org/gtkmm/2.24/namespaceGtk_1_1Menu__Helpers.html
[2] gtkmm: Gtk::Menu_Helpers::Element Class Reference
https://developer.gnome.org/gtkmm/2.24/classGtk_1_1Menu__Helpers_1_1Element.html
[3] Gtkmm 3 commit "MenuShell: Remove items()." removed the code
c8e47b0db5Closes#7 - Port to Gtk3
During the switch from Gtk2 to Gtk3 keyname constants were renamed from
GDK_<KeyName> to GDK_KEY_<KeyName> [1]. This was done to avoid name
clashes in gobject-introspection and language bindings. The new
constant names were also backported to Gtk 2.22 [2].
Make use of the new constant names.
References:
[1] Migrating from GTK+ 2.x to GTK+ 3 - "Replace GDK_<keyname> with GDK_KEY_<keyname>"
https://developer.gnome.org/gtk3/stable/gtk-migrating-2-to-3.html#id-1.6.3.3.6
[2] Commit - "gdk: Prefix keys with _KEY by default"
750c81f43dCloses#7 - Port to Gtk3
Originally in Gtk2, by default, dialogs showed a horizontal separator
between the content area and the action area (buttons). GParted
explicitly called Gtk::Dialog::set_has_separator(false) for all it's
dialogs to remove the separator.
In Gtk2/Gtkmm2 2.22, separators were deprecated [1]. In Gtk3/Gtkmm3
separators in dialogs were removed altogether, including all the related
APIs [2][3][4]. Therefore remove all calls.
References:
[1] Commit - "Document separator-related api in GtkDialog as deprecated"
6f6650e6cf
[2] Commit - "Remove separators from dialogs"
d433a60611
[3] GTK+ 3.0.0 NEWS file
https://gitlab.gnome.org/GNOME/gtk/blob/3.0.0/NEWS#L779
"
Overview of Changed from GTK+ 2.90.6 to 2.90.7
==============================================
* Various deprecated APIs have been removed:
...
- GtkDialog separators, including the GtkDialog::has-separator
property, including setter/getter, the GTK_DIALOG_NO_SEPARATOR
flag and the GtkMessageDialog::use-separator style property
"
[4] Gtkmm 3.0.0 NEWS file
https://gitlab.gnome.org/GNOME/gtkmm/blob/3.0.0/NEWS#406
"
* Dialog:
- Remove get/set_has_separator() and property.
- Constructors: Remove use_separator parameters.
"
Closes#7 - Port to Gtk3
Update to Google Test C++ test framework from release 1.8.0 to 1.8.1.
Replace the following files and directories from Google Test 1.8.1:
LICENSE
README.md
include/
src/
Note the LICENSE file is identical, where as the other files changed.
Also see commit which initially added Google Test:
87f7170a55
Add Google Test 1.8.0 files (#781978)
Use of Glib::thread_init() was deprecated in glibmm 2.32 [1]. The
oldest supported distributions have these versions:
Debian 8 glibmm 2.42.0
RHEL / CentOS 7 glibmm 2.56.0
SLES 12 glibmm 2.38.1
Ubuntu 14.04 LTS glibmm 2.39.93
Checking further the glibmm 2.32 reference manual says this about
Glib::thread_init() [2]:
Initializes the GLib thread system.
Deprecated:
Calling thread_init() is no longer necessary and no longer has any
effect.
However only some of the glibmm example programs had Glib::thread_init()
removed, others had it replaced by Glib::init() [3]. Again the glibmm
2.32 reference manual says this about Glib::init() [4]:
Initialize glibmm.
You may call this more than once. You do not need to call this if
you are using Glib::MainLoop or Gtk::Main, because they call it for
you.
GParted does call Gtk::Main and test_PipeCapture does call
Glib::MainLoop. Therefore just raise the minimum version to glibmm 2.32
and remove both calls to Glib::thread_init().
[1] Glibmm 2.32 NEWS file
https://gitlab.gnome.org/GNOME/glibmm/blob/2.32.0/NEWS#L207
[2] glibmm 2.32, glibmm: Glib Namespace Reference, Glib::thread_init()
https://developer.gnome.org/glibmm/2.32/namespaceGlib.html#ab26d01c776801f1fff00753e97af4fc7
[3] glibmm commit "Avoid use of deprecates API in tests and examples."
3e0fbb22c0
[4] glibmm 2.32, glibmm: Glib Namespace Reference, Glib::init()
https://developer.gnome.org/glibmm/2.32/namespaceGlib.html#ac90aee10d0b90e3d8a96a86b5394f87bCloses!22 - Increase minimums to libparted 2.2 and glibmm 2.32
Raise the minimum required version of GNU Parted from 1.7.1 to 2.2,
released 2010-02-16 [1][2]. The oldest supported distributions, also
with gtkmm >= 2.24, since commit [3], are:
Debian 8 parted 3.2
RHEL / CentOS 7 parted 3.1
SLES 12 parted 3.1
Ubuntu 14.04 LTS parted 2.3
Raising the minimum required version allows removal of optional code
associated with these definitions:
* USE_LIBPARTED_LARGE_SECTOR_SUPPORT
Fallback code reporting ignored device with logical sector size
other than 512 bytes.
* ENABLE_PT_REREAD_WORKAROUND
Fallback code re-attempting to inform the kernel of partition
changes.
[1] GNU Parted 2.2 release announcement
http://lists.gnu.org/archive/html/info-gnu/2010-02/msg00016.html
[2] NEWS file from GNU Parted 2.2
http://git.savannah.gnu.org/cgit/parted.git/tree/NEWS?h=v2.2
[3] 8b42bab1ee
modern-gtk2: Require Gtkmm version 2.24 (!17)
Closes!22 - Increase minimums to libparted 2.2 and glibmm 2.32
The code inconsistently uses GParted:: scope in front of STAT_*.
$ fgrep 'GParted::STAT_' src/*.cc | wc -l
3
$ egrep '[^:]STAT_' src/*.cc | wc -l
41
GParted:: scope resolution is unnecessary as all the code is inside the
GParted scope, except for main(). So remove it.
Closes!20 - Minor namespace and scope operator tidy-ups
The code inconsistently uses GParted:: scope in front of TYPE_*.
$ fgrep 'GParted::TYPE_' src/*.cc | wc -l
35
$ egrep '[^:]TYPE_' src/*.cc | wc -l
83
GParted:: scope resolution is unnecessary as all the code is inside the
GParted scope, except for main(). So remove it.
Closes!20 - Minor namespace and scope operator tidy-ups
The code inconsistently uses GParted:: scope in front of FS_*.
$ fgrep 'GParted::FS_' src/*.cc | wc -l
41
$ egrep '[^:]FS_' src/*.cc | wc -l
441
GParted:: scope resolution is unnecessary as all the code is inside the
GParted namespace, except for main(). So remove it.
Closes!20 - Minor namespace and scope operator tidy-ups
The code inconsistency uses GParted::FS::* and FS::*.
$ fgrep 'GParted::FS::' src/*.cc | wc -l
97
$ egrep '[^:]FS::' src/*.cc | wc -l
152
GParted:: scope resolution is unnecessary as all the code is inside the
GParted namespace, except for main(). So remove it.
Closes!20 - Minor namespace and scope operator tidy-ups
All the other modules are in the GParted namespace, except for main()
which has to be in the global namespace, so put these in the GParted
namespace too.
Closes!20 - Minor namespace and scope operator tidy-ups
Create an active Linux Software RAID member which is larger than /dev
virtual file system and GParted will report the usage figure of the /dev
virtual file system for the SWRAID member.
# df -h /dev
Filesystem Size Used Avail Use% Mounted on
devtmpfs 732M 0 732M 0% /dev
# sgdisk -n 1:1M:+1G /dev/sdb
# mdadm --create --verbose /dev/md1 --level=linear --raid-devices=1 --force /dev/sdb1
mdadm: Defaulting to version 1.2 metadata
mdadm: array /dev/md1 started.
GParted reports the usage of /dev/sdb1 as:
Partition Mount Point Size Used Unused Unallocated
/dev/sdb1 /dev/md1 1.00GiB 0.00B 731.04MiB 292.96MiB
However GParted should have reported the usage as "---" for unknown
because it isn't coded to query the size of the SWRAID member within a
partition.
The fault has been bisected to this commit:
Extend un/mounting and usage reporting to unsupported file systems (!13)
95903efb1f
What happens for busy Linux Software RAID array members:
* GParted_Core::is_busy()
has custom code to identify busy members.
* GParted_Core::set_mountpoints()
has custom code to add the array device name as the "mount point" of
the member.
* GParted_Core::set_used_sectors()
falls into the else not a supported file system (because SWRAID
doesn't have a derived FileSystem implementation class).
* GParted_Core::mounted_set_used_sectors()
is called to get the file system usage of mounted, but unsupported
file systems, such as UFS and any others.
* Utils::get_mounted_filesystem_usage()
is called which queries the kernel using statvfs() and gets the file
system usage of the /dev virtual file system because the array
device name will always start /dev.
Fix by ensuring that GParted only asks the kernel for the usage of paths
which it knows are mount points of mounted file systems. (As read from
/proc/mounts and cached in the Mount_Info module). Also rename the
method, by inserting "_fs", to mounted_fs_set_used_sectors() to remind
us that it is for mounted *file systems* only.
Closes#27 - GParted may report incorrect usage for SWRAID partitions
instead of unknown
S
Third commit in a series to convert Gdk::GC based drawing to Cairo based
drawing. This specific commit makes the transition for the graphical
partition visualizer widget that is used in the main application window.
Closed!17 - Gtk2 modernisation
Second commit in a series to convert Gdk::GC based drawing to Cairo
based drawing. This specific commit makes the transition for the
graphical partition info widget that is used in the "Information about"
dialog.
Closes!17 - Gtk2 modernisation
C++ initialises static member variables before main() is called.
Therefore the static members of:
struct Slots
{
static Gtk::TreeModelColumn<Glib::ustring> text;
static Gtk::TreeModelColumn<bool> sensitive;
private:
static Gtk::TreeModel::ColumnRecord record_;
};
are constructed before Gtk::Main() is called in main(). However the
Gtkmm documentation specifically says that they must be constructed
afterwards [1].
Resolve this by using the Construct On First Use Idiom [2] to delay
initialisation until the slots are first used. Normally this idiom uses
static local objects, however it is being applied to class static
objects here because the objects are accessed in many methods. The
downside of this approach is that the objects are never destructed,
which memory analysers like Valgrind could see as a memory leak, but
that is actually deliberate. That leak can be removed once we can use
C++11 and std::unique_ptr.
[1] gtkmm: Gtk::TreeModelColumnRecord Class Reference
https://developer.gnome.org/gtkmm/2.24/classGtk_1_1TreeModelColumnRecord.html#details
"Neither TreeModel::ColumnRecord nor the TreeModelColumns contain
any real data - they merely describe what C++ type is stored in
which column of a TreeModel, and save you from having to repeat that
type information in several places.
Thus TreeModel::ColumnRecord can be made a singleton (as long as you
make sure it's instantiated after Gtk::Main), even when creating
multiple models from it.
"
[2] C++ FAQ / How do I prevent the "static initialization order
problem"?
https://isocpp.org/wiki/faq/ctors#static-init-order-on-first-useCloses!17 - Gtk2 modernisation