Merge branch 'main' into ccook/doc-spelling-fixes

This commit is contained in:
Cam Cook 2022-11-16 23:23:42 -05:00
commit 2a14753739
6 changed files with 76 additions and 75 deletions

View File

@ -24,10 +24,10 @@ you should be aware of what they refer to. These are often generic terms that
have a specific meaning in this context. have a specific meaning in this context.
**_Views_** or **_list widgets_** are the widgets that hold and manage the lists. **_Views_** or **_list widgets_** are the widgets that hold and manage the lists.
Examples of these widgets would be `GtkListView` or `GtkGridView`. Examples of these widgets would be [`class@Gtk.ListView`] or [`class@Gtk.GridView`].
Views display data from a **_model_**. A model is a `GListModel` and models can Views display data from a **_model_**. A model is a [`iface@Gio.ListModel`] and
be provided in 3 ways or combinations thereof: models can be provided in 3 ways or combinations thereof:
* Many list models implementations already exist. There are models that provide * Many list models implementations already exist. There are models that provide
specific data, like `GtkDirectoryList`. And there are models like `GListStore` specific data, like `GtkDirectoryList`. And there are models like `GListStore`
@ -42,7 +42,8 @@ be provided in 3 ways or combinations thereof:
The same model can be used in multiple different views and wrapped with The same model can be used in multiple different views and wrapped with
multiple different models at once. multiple different models at once.
The elements in a model are called **_items_**. All items are `GObjects`. The elements in a model are called **_items_**. All items are
[`class@GObject.Object`] instances.
Every item in a model has a **_position_** which is the unsigned integer that Every item in a model has a **_position_** which is the unsigned integer that
describes where in the model the item is located. The first item in a model is describes where in the model the item is located. The first item in a model is
@ -56,13 +57,13 @@ with models. Oftentimes some things are really hard to do one way but very easy
the other way. the other way.
The other important part of a view is a **_factory_**. Each factory is The other important part of a view is a **_factory_**. Each factory is
a `GtkListItemFactory` implementation that takes care of mapping the items a [`class@Gtk.ListItemFactory`] implementation that takes care of mapping the
of the model to widgets that can be shown in the view. items of the model to widgets that can be shown in the view.
The way factories do this is by creating a **_listitem_** for each item that The way factories do this is by creating a **_listitem_** for each item that
is currently in use. Listitems are always `GtkListItem` objects. They are only is currently in use. List items are always [`class@Gtk.ListItem`] instances.
ever created by GTK and provide information about what item they are meant They are only ever created by GTK and provide information about what item they
to display. are meant to display.
Different factory implementations use various different methods to allow Different factory implementations use various different methods to allow
developers to add the right widgets to listitems and to link those widgets developers to add the right widgets to listitems and to link those widgets
@ -71,29 +72,30 @@ for the data displayed, the programming language and development environment
is an important task that can simplify setting up the view tremendously. is an important task that can simplify setting up the view tremendously.
Views support selections via a **_selection model_**. A selection model is an Views support selections via a **_selection model_**. A selection model is an
implementation of the `GtkSelectionModel` interface on top of the `GListModel` implementation of the [`iface@Gtk.SelectionModel`] interface on top of the
interface that allows marking each item in a model as either selected or not [`iface@Gio.ListModel`] interface that allows marking each item in a model as either
selected. Just like regular models, this can be implemented either by selected or not selected. Just like regular models, this can be implemented
implementing `GtkSelectionModel` directly or by wrapping a model with one of either by implementing `GtkSelectionModel` directly or by wrapping a model with
the GTK models provided for this purposes, such as `GtkNoSelection` one of the GTK models provided for this purposes, such as [`class@Gtk.NoSelection`]
or `GtkSingleSelection`. or [`class@Gtk.SingleSelection`].
The behavior of selection models - ie which items they allow selecting and The behavior of selection models - ie which items they allow selecting and
what effect this has on other items - is completely up to the selection model. what effect this has on other items - is completely up to the selection model.
As such, single-selections, multi-selections or sharing selection state between As such, single-selections, multi-selections or sharing selection state between
different selection models and/or views is possible. The selection state of an different selection models and/or views is possible. The selection state of an
item is exposed in the listitem via the `GtkListItem:selected` property. item is exposed in the listitem via the [`property@Gtk.ListItem:selected`] property.
Views and listitems also support activation. Activation means that double Views and listitems also support activation. Activation means that double
clicking or pressing enter while inside a focused row will cause the view clicking or pressing enter while inside a focused row will cause the view
to emit and activation signal such as `GtkListView::activate`. This provides to emit and activation signal such as [`signal@Gtk.ListView::activate`]. This
an easy way to set up lists, but can also be turned off on listitems if undesired. provides an easy way to set up lists, but can also be turned off on listitems
if undesired.
Both selections and activation are supported among other things via widget Both selections and activation are supported among other things via widget
[actions](#actions-overview). This allows developers to add widgets to their [actions](#actions-overview). This allows developers to add widgets to their
lists that cause selections to change or to trigger activation via lists that cause selections to change or to trigger activation via
the `GtkActionable` interface. For a list of all supported actions see the the [`iface@Gtk.Actionable`] interface. For a list of all supported actions see
relevant documentation. the relevant documentation.
## Behind the scenes ## Behind the scenes
@ -101,12 +103,14 @@ While for short lists it is not a problem to instantiate widgets for every
item in the model, once lists grow to thousands or millions of elements, this item in the model, once lists grow to thousands or millions of elements, this
gets less feasible. Because of this, the views only create a limited amount of gets less feasible. Because of this, the views only create a limited amount of
listitems and recycle them by binding them to new items. In general, views try listitems and recycle them by binding them to new items. In general, views try
to keep listitems available only for the items that can actually be seen on screen. to keep listitems available only for the items that can actually be seen on
screen.
While this behavior allows views to scale effortlessly to huge lists, it has a While this behavior allows views to scale effortlessly to huge lists, it has a
few implication on what can be done with views. For example, it is not possible few implication on what can be done with views. For example, it is not possible
to query a view for a listitem used for a certain position - there might not be to query a view for a listitem used for a certain position - there might not be
one and even if there is, that listitem might soon be recycled for a new position. one and even if there is, that listitem might soon be recycled for a new
position.
It is also important that developers save state they care about in the item and It is also important that developers save state they care about in the item and
do not rely on the widgets they created as those widgets can be recycled for a do not rely on the widgets they created as those widgets can be recycled for a
@ -114,13 +118,13 @@ new position at any time causing any state to be lost.
Another important requirement for views is that they need to know which items Another important requirement for views is that they need to know which items
are not visible so they can be recycled. Views achieve that by implementing are not visible so they can be recycled. Views achieve that by implementing
the `GtkScrollable` interface and expecting to be placed directly into the [`iface@Gtk.Scrollable`] interface and expecting to be placed directly into
a `GtkScrolledWindow`. a [`class@Gtk.ScrolledWindow`].
Of course, if you are only using models with few items, this is not important Of course, if you are only using models with few items, this is not important
and you can treat views like any other widget. But if you use large lists and and you can treat views like any other widget. But if you use large lists and
your performance suffers, you should be aware of this. Views also allow tuning your performance suffers, you should be aware of this. Views also allow tuning
the number of listitems they create such as with gtk_grid_view_set_max_columns(), the number of listitems they create such as with [`method@Gtk.GridView.set_max_columns`],
and developers running into performance problems should definitely study the and developers running into performance problems should definitely study the
tradeoffs of those and experiment with them. tradeoffs of those and experiment with them.
@ -128,23 +132,23 @@ tradeoffs of those and experiment with them.
GTK offers a wide variety of wrapping models which change or supplement an GTK offers a wide variety of wrapping models which change or supplement an
existing model (or models) in some way. But when it comes to storing your existing model (or models) in some way. But when it comes to storing your
actual data, there are only a few ready-made choices available: `GListStore` actual data, there are only a few ready-made choices available: [`class@Gio.ListStore`]
and `GtkStringList`. and [`class@Gtk.StringList`].
GListStore is backed by a balanced tree and has performance characteristics `GListStore` is backed by a balanced tree and has performance characteristics
that are expected for that data structure. It works reasonably well for dataset that are expected for that data structure. It works reasonably well for dataset
sizes in the 1,000,000 range, and can handle insertions and deletions. It uses sizes in the 1,000,000 range, and can handle insertions and deletions. It uses
a cached iter to make linear access to the items fast. a cached iter to make linear access to the items fast.
GtkStringList is not a general store - it can only handle strings. It is `GtkStringList` is not a general store - it can only handle strings. It is
backed by an dynamically allocated array and has performance characteristics backed by an dynamically allocated array and has performance characteristics
that are expected for that data structure. GtkStringList is a good fit for any that are expected for that data structure. `GtkStringList` is a good fit for any
place where you would otherwise use `char*[]` and works best if the dataset place where you would otherwise use `char*[]` and works best if the dataset
is not very dynamic. is not very dynamic.
If these models don't fit your use case or scalability requirements, you If these models don't fit your use case or scalability requirements, you
should make a custom `GListModel`. It is a small interface and not very hard should make a custom `GListModel` implementation. It is a small interface and
to implement. not very hard to implement.
For asymptotic performance comparisons between tree- and array-based For asymptotic performance comparisons between tree- and array-based
implementations, see this implementations, see this
@ -159,16 +163,17 @@ interface provided.
However, GTK provides functionality to make trees look and behave like lists However, GTK provides functionality to make trees look and behave like lists
for the people who still want to display lists. This is achieved by using for the people who still want to display lists. This is achieved by using
the `GtkTreeListModel` model to flatten a tree into a list. The `GtkTreeExpander` the [`class@Gtk.TreeListModel`] model to flatten a tree into a list. The
widget can then be used inside a listitem to allow users to expand and collapse [`class@Gtk.TreeExpander`] widget can then be used inside a listitem to allow
rows and provide a similar experience to `GtkTreeView`. users to expand and collapse rows and provide a similar experience to
`GtkTreeView`.
Developers should refer to those objects' API reference for more discussion Developers should refer to those objects' API reference for more discussion
on the topic. on the topic.
## List styles ## List styles
One of the advantages of the new list widgets over `GtkTreeViews` and cell One of the advantages of the new list widgets over `GtkTreeView` and cell
renderers is that they are fully themable using GTK CSS. This provides a renderers is that they are fully themable using GTK CSS. This provides a
lot of flexibility. The themes that ship with GTK provide a few predefined lot of flexibility. The themes that ship with GTK provide a few predefined
list styles that can be used in many situations: list styles that can be used in many situations:
@ -177,17 +182,17 @@ list styles that can be used in many situations:
This style of list is low density, spacious and uses an outline focus ring. This style of list is low density, spacious and uses an outline focus ring.
It is suitable for lists of controls, e.g. in preference dialogs or It is suitable for lists of controls, e.g. in preference dialogs or
settings panels. Use the .rich-list style class. settings panels. Use the `.rich-list` style class.
![Navigation sidebar](navigation-sidebar.png) ![Navigation sidebar](navigation-sidebar.png)
This style of list is medium density, using a full background to indicate This style of list is medium density, using a full background to indicate
focus and selection. Use the .navigation-sidebar style class. focus and selection. Use the `.navigation-sidebar` style class.
![Data table](data-table.png) ![Data table](data-table.png)
This style of list is a high density table, similar in style to a traditional This style of list is a high density table, similar in style to a traditional
treeview. Individual cells can be selectable and editable. Use the .data-table treeview. Individual cells can be selectable and editable. Use the `.data-table`
style class. style class.
## Comparison to GtkTreeView ## Comparison to GtkTreeView
@ -210,7 +215,7 @@ was a rather complex interface for a tree data structure and `GListModel` was
deliberately designed to be a simple data structure for lists only. (See deliberately designed to be a simple data structure for lists only. (See
[above](#displaying-trees)) for how to still do trees with this new model.) [above](#displaying-trees)) for how to still do trees with this new model.)
Another big change is that the new model allows for bulk changes via Another big change is that the new model allows for bulk changes via
the `GListModel:items-changed` signal while `GtkTreeModel` only allows a single the `GListModel::items-changed` signal while `GtkTreeModel` only allows a single
item to change at once. The goal here is of course to encourage implementation item to change at once. The goal here is of course to encourage implementation
of custom list models. of custom list models.
@ -230,23 +235,23 @@ Finally here's a quick list of equivalent functionality to look for when
transitioning code for easy lookup: transitioning code for easy lookup:
| Old | New | | Old | New |
| -------------------- | ------------------------------------ | | -------------------- | ------------------------------------------------------- |
| `GtkTreeModel` | `GListModel` | | `GtkTreeModel` | [`iface@Gio.ListModel`] |
| `GtkTreePath` | `guint` position, `GtkTreeListRow` | | `GtkTreePath` | `guint` position, [`class@Gtk.TreeListRow`] |
| `GtkTreeIter` | `guint` position | | `GtkTreeIter` | `guint` position |
| `GtkTreeRowReference`| `GObject` item | | `GtkTreeRowReference`| [`class@GObject.Object`] item |
| `GtkListStore` | `GListStore` | | `GtkListStore` | [`class@Gio.ListStore`] |
| `GtkTreeStore` | `GtkTreeListModel`, `GtkTreeExpander`| | `GtkTreeStore` | [`class@Gtk.TreeListModel`], [`class@Gtk.TreeExpander`] |
| `GtkTreeSelection` | `GtkSelectionModel` | | `GtkTreeSelection` | [`iface@Gtk.SelectionModel`] |
| `GtkTreeViewColumn` | `GtkColumnView` | | `GtkTreeViewColumn` | [`class@Gtk.ColumnView`] |
| `GtkTreeView` | `GtkListView`, `GtkColumnView` | | `GtkTreeView` | [`class@Gtk.ListView`], [`class@Gtk.ColumnView`] |
| `GtkCellView` | `GtkListItemWidget` | | `GtkCellView` | [`class@Gtk.ListItem`] |
| `GtkComboBox` | `GtkDropDown` | | `GtkComboBox` | [`class@Gtk.DropDown`] |
| `GtkIconView` | `GtkGridView` | | `GtkIconView` | [`class@Gtk.GridView`] |
| `GtkTreeSortable` | `GtkColumnView` | | `GtkTreeSortable` | [`class@Gtk.ColumnView`] |
| `GtkTreeModelSort` | `GtkSortListModel` | | `GtkTreeModelSort` | [`class@Gtk.SortListModel`] |
| `GtkTreeModelFilter` | `GtkFilterListModel` | | `GtkTreeModelFilter` | [`class@Gtk.FilterListModel`] |
| `GtkCellLayout` | `GtkListItemFactory` | | `GtkCellLayout` | [`class@Gtk.ListItemFactory`] |
| `GtkCellArea` | `GtkWidget` | | `GtkCellArea` | [`class@Gtk.Widget`] |
| `GtkCellRenderer` | `GtkWidget` | | `GtkCellRenderer` | [`class@Gtk.Widget`] |

View File

@ -612,7 +612,6 @@ gdk_event_queue_handle_scroll_compression (GdkDisplay *display)
GList *l; GList *l;
GdkSurface *surface = NULL; GdkSurface *surface = NULL;
GdkDevice *device = NULL; GdkDevice *device = NULL;
GdkEvent *last_event = NULL;
GList *scrolls = NULL; GList *scrolls = NULL;
GArray *history = NULL; GArray *history = NULL;
GdkScrollUnit scroll_unit = GDK_SCROLL_UNIT_WHEEL; GdkScrollUnit scroll_unit = GDK_SCROLL_UNIT_WHEEL;
@ -645,9 +644,6 @@ gdk_event_queue_handle_scroll_compression (GdkDisplay *display)
scroll_unit != scroll_event->unit) scroll_unit != scroll_event->unit)
break; break;
if (!last_event)
last_event = event;
surface = event->surface; surface = event->surface;
device = event->device; device = event->device;
scroll_unit = scroll_event->unit; scroll_unit = scroll_event->unit;

View File

@ -7360,20 +7360,17 @@ gtk_file_chooser_widget_set_choice (GtkFileChooser *chooser,
widget = (GtkWidget *)g_hash_table_lookup (impl->choices, id); widget = (GtkWidget *)g_hash_table_lookup (impl->choices, id);
if (GTK_IS_BOX (widget)) if (GTK_IS_DROP_DOWN (widget))
{ {
guint i; guint i;
const char **options; const char **options;
GtkWidget *dropdown;
dropdown = gtk_widget_get_last_child (widget); options = (const char **) g_object_get_data (G_OBJECT (widget), "options");
options = (const char **) g_object_get_data (G_OBJECT (dropdown), "options");
for (i = 0; options[i]; i++) for (i = 0; options[i]; i++)
{ {
if (strcmp (option, options[i]) == 0) if (strcmp (option, options[i]) == 0)
{ {
gtk_drop_down_set_selected (GTK_DROP_DOWN (dropdown), i); gtk_drop_down_set_selected (GTK_DROP_DOWN (widget), i);
break; break;
} }
} }

View File

@ -232,8 +232,8 @@
* *
* ```c * ```c
* const char *text = * const char *text =
* "Go to the" * "Go to the "
* "<a href=\"http://www.gtk.org title=\"&lt;i&gt;Our&lt;/i&gt; website\">" * "<a href=\"https://www.gtk.org\" title=\"&lt;i&gt;Our&lt;/i&gt; website\">"
* "GTK website</a> for more..."; * "GTK website</a> for more...";
* GtkWidget *label = gtk_label_new (NULL); * GtkWidget *label = gtk_label_new (NULL);
* gtk_label_set_markup (GTK_LABEL (label), text); * gtk_label_set_markup (GTK_LABEL (label), text);

View File

@ -1443,9 +1443,12 @@ event_type_name (GdkEventType type)
"Pad Button Release", "Pad Button Release",
"Pad Rind", "Pad Rind",
"Pad Strip", "Pad Strip",
"Pad Group Mode" "Pad Group Mode",
"Touchpad Hold",
}; };
G_STATIC_ASSERT (G_N_ELEMENTS (event_name) == GDK_EVENT_LAST);
return event_name[type]; return event_name[type];
} }