Merge branch 'matthiasc/for-master' into 'master'

Matthiasc/for master

See merge request GNOME/gtk!2729
This commit is contained in:
Matthias Clasen 2020-10-21 11:43:58 +00:00
commit 8880e3bd2e
14 changed files with 157 additions and 16 deletions

View File

@ -239,6 +239,31 @@ you get to the point that you actually build your application against
GTK 4. Making it possible to prepare for these in GTK 3 would
have been either impossible or impractical.
### Larger changes
Some of the larger themes of GTK 4 development are hard to cover in the form
of checklist items, so we mention them separately up-front.
#### Subclassing
Compared to previous versions, GTK 4 emphasizes composition and delegation
over subclassing. As a consequence, many widgets can no longer be subclassed.
In most cases, you should look deriving your widget directly from GtkWidget
and use complex widgets as child widgets instead of deriving from them.
#### Life-cycle handling
Widgets in GTK 4 are treated like any other objects - their parent widget
holds a reference on them, and GTK holds a reference on toplevel windows.
gtk_window_destroy() will drop the reference on the toplevel window, and
cause the whole widget hierarchy to be finalized unless there are other
references that keep widgets alive.
The #GtkWidget::destroy signal is emitted when a widget is disposed, and
therefore can no longer be used to break reference cycles. A typical sign
of a reference cycle involving a toplevel window is when closing the window
does not make the application quit.
### Stop using GdkScreen
The GdkScreen object has been removed in GTK 4. Most of its APIs already

View File

@ -729,14 +729,24 @@ emit_text_selection_changed (GtkAtSpiContext *self,
const char *kind,
int cursor_position)
{
g_dbus_connection_emit_signal (self->connection,
NULL,
self->context_path,
"org.a11y.atspi.Event.Object",
"TextChanged",
g_variant_new ("(siiva{sv})",
kind, cursor_position, 0, g_variant_new_string (""), NULL),
if (strcmp (kind, "text-caret-moved") == 0)
g_dbus_connection_emit_signal (self->connection,
NULL,
self->context_path,
"org.a11y.atspi.Event.Object",
"TextCaretMoved",
g_variant_new ("(siiva{sv})",
"", cursor_position, 0, g_variant_new_string (""), NULL),
NULL);
else
g_dbus_connection_emit_signal (self->connection,
NULL,
self->context_path,
"org.a11y.atspi.Event.Object",
"TextSelectionChanged",
g_variant_new ("(siiva{sv})",
"", 0, 0, g_variant_new_string (""), NULL),
NULL);
}
static void

View File

@ -760,7 +760,7 @@ gtk_at_context_get_name_accumulate (GtkATContext *self,
GList *list = gtk_reference_list_accessible_value_get (value);
for (GList *l = list; l != NULL; l = l->data)
for (GList *l = list; l != NULL; l = l->next)
{
GtkAccessible *rel = GTK_ACCESSIBLE (l->data);
GtkATContext *rel_context = gtk_accessible_get_at_context (rel);

View File

@ -105,6 +105,13 @@
* The main columnview node may also carry style classes to select
* the style of [list presentation](ListContainers.html#list-styles):
* .rich-list, .navigation-sidebar or .data-table.
*
* # Accessibility
*
* GtkColumnView uses the #GTK_ACCESSIBLE_ROLE_TREE_GRID role, header title
* widgets are using the #GTK_ACCESSIBLE_ROLE_COLUMN_HEADER role. The row widgets
* are using the #GTK_ACCESSIBLE_ROLE_ROW role, and individual cells are using
* the #GTK_ACCESSIBLE_ROLE_GRID_CELL role
*/
/* We create a subclass of GtkListView for the sole purpose of overriding

View File

@ -69,6 +69,11 @@
* GtkFlowBox uses a single CSS node with name flowbox. GtkFlowBoxChild
* uses a single CSS node with name flowboxchild.
* For rubberband selection, a subnode with name rubberband is used.
*
* # Accessibility
*
* GtkFlowBox uses the #GTK_ACCESSIBLE_ROLE_GRID role, and GtkFlowBoxChild
* uses the #GTK_ACCESSIBLE_ROLE_GRID_CELL role.
*/
#include <config.h>

View File

@ -77,6 +77,11 @@
* GtkGridView uses a single CSS node with name gridview. Each child
* uses a single CSS node with name child. For rubberband selection,
* a subnode with name rubberband is used.
*
* # Accessibility
*
* GtkGridView uses the #GTK_ACCESSIBLE_ROLE_GRID role, and the items
* use the #GTK_ACCESSIBLE_ROLE_GRID_CELL role.
*/
typedef struct _Cell Cell;

View File

@ -50,7 +50,7 @@
*
* # Accessibility
*
* GtkLinkButton uses the #GTK_ACCESSIBKE_ROLE_BUTTON role.
* GtkLinkButton uses the #GTK_ACCESSIBLE_ROLE_BUTTON role.
*/
#include "config.h"

View File

@ -85,6 +85,11 @@
* The main list node may also carry style classes to select
* the style of [list presentation](ListContainers.html#list-styles):
* .rich-list, .navigation-sidebar or .data-table.
*
* # Accessibility
*
* GtkListBox uses the #GTK_ACCESSIBLE_ROLE_LIST role and GtkListBoxRow uses
* the #GTK_ACCESSIBLE_ROLE_LIST_ITEM role.
*/
typedef struct _GtkListBoxClass GtkListBoxClass;

View File

@ -135,6 +135,11 @@
* The main listview node may also carry style classes to select
* the style of [list presentation](ListContainers.html#list-styles):
* .rich-list, .navigation-sidebar or .data-table.
*
* # Accessibility
*
* GtkListView uses the #GTK_ACCESSIBLE_ROLE_LIST role, and the list
* items use the #GTK_ACCESSIBLE_ROLE_LIST_ITEM role.
*/
typedef struct _ListRow ListRow;

View File

@ -122,6 +122,12 @@
* CSS nodes with name cursor-handle. They get the .top or .bottom style class
* depending on where they are shown in relation to the selection. If there is
* just a single handle for the text cursor, it gets the style class .insertion-cursor.
*
* # Accessibility
*
* GtkText uses the #GTK_ACCESSIBLE_ROLE_NONE role, which causes it to be skipped
* for accessibility. This is because GtkText is expected to be used as a delegate
* for a #GtkEditable implementation that will be represented to accessibility.
*/
#define NAT_ENTRY_WIDTH 150

View File

@ -8973,6 +8973,7 @@ gtk_widget_add_mnemonic_label (GtkWidget *widget,
GtkWidget *label)
{
GSList *old_list, *new_list;
GList *list;
g_return_if_fail (GTK_IS_WIDGET (widget));
g_return_if_fail (GTK_IS_WIDGET (label));
@ -8983,8 +8984,9 @@ gtk_widget_add_mnemonic_label (GtkWidget *widget,
g_object_set_qdata_full (G_OBJECT (widget), quark_mnemonic_labels,
new_list, (GDestroyNotify) g_slist_free);
list = gtk_widget_list_mnemonic_labels (widget);
gtk_accessible_update_relation (GTK_ACCESSIBLE (widget),
GTK_ACCESSIBLE_RELATION_LABELLED_BY, new_list,
GTK_ACCESSIBLE_RELATION_LABELLED_BY, list,
-1);
}
@ -9017,15 +9019,17 @@ gtk_widget_remove_mnemonic_label (GtkWidget *widget,
if (new_list != NULL && new_list->data != NULL)
{
GList *list;
list = gtk_widget_list_mnemonic_labels (widget);
gtk_accessible_update_relation (GTK_ACCESSIBLE (widget),
GTK_ACCESSIBLE_RELATION_LABELLED_BY, new_list,
GTK_ACCESSIBLE_RELATION_LABELLED_BY, list,
-1);
}
else
{
gtk_accessible_update_relation (GTK_ACCESSIBLE (widget),
GTK_ACCESSIBLE_RELATION_LABELLED_BY, NULL,
-1);
gtk_accessible_reset_relation (GTK_ACCESSIBLE (widget),
GTK_ACCESSIBLE_RELATION_LABELLED_BY);
}
}

View File

@ -34,6 +34,9 @@
#include "gtknoselection.h"
#include "gtkfilterlistmodel.h"
#include "gtkboolfilter.h"
#ifdef G_OS_UNIX
#include "a11y/gtkatspicontextprivate.h"
#endif
typedef enum {
STATE,
@ -198,6 +201,7 @@ struct _GtkInspectorA11y
GtkWidget *box;
GtkWidget *role;
GtkWidget *path;
GtkWidget *attributes;
};
@ -223,6 +227,21 @@ update_role (GtkInspectorA11y *sl)
g_type_class_unref (eclass);
}
static void
update_path (GtkInspectorA11y *sl)
{
const char *path = "";
#ifdef G_OS_UNIX
GtkATContext *context;
context = gtk_accessible_get_at_context (GTK_ACCESSIBLE (sl->object));
if (GTK_IS_AT_SPI_CONTEXT (context))
path = gtk_at_spi_context_get_context_path (GTK_AT_SPI_CONTEXT (context));
#endif
gtk_label_set_label (GTK_LABEL (sl->path), path);
}
extern GType gtk_string_pair_get_type (void);
static void
@ -244,6 +263,8 @@ update_attributes (GtkInspectorA11y *sl)
gboolean has_value;
context = gtk_accessible_get_at_context (GTK_ACCESSIBLE (sl->object));
if (!context)
return;
store = g_list_store_new (G_TYPE_OBJECT);
@ -380,6 +401,7 @@ static void
refresh_all (GtkInspectorA11y *sl)
{
update_role (sl);
update_path (sl);
update_attributes (sl);
}
@ -394,7 +416,8 @@ gtk_inspector_a11y_set_object (GtkInspectorA11y *sl,
if (sl->object && GTK_IS_ACCESSIBLE (sl->object))
{
context = gtk_accessible_get_at_context (GTK_ACCESSIBLE (sl->object));
g_signal_handlers_disconnect_by_func (context, refresh_all, sl);
if (context)
g_signal_handlers_disconnect_by_func (context, refresh_all, sl);
}
g_set_object (&sl->object, object);
@ -405,9 +428,11 @@ gtk_inspector_a11y_set_object (GtkInspectorA11y *sl,
if (GTK_IS_ACCESSIBLE (object))
{
context = gtk_accessible_get_at_context (GTK_ACCESSIBLE (sl->object));
g_signal_connect_swapped (context, "state-change", G_CALLBACK (refresh_all), sl);
if (context)
g_signal_connect_swapped (context, "state-change", G_CALLBACK (refresh_all), sl);
gtk_stack_page_set_visible (page, TRUE);
update_role (sl);
update_path (sl);
update_attributes (sl);
}
else
@ -453,6 +478,7 @@ gtk_inspector_a11y_class_init (GtkInspectorA11yClass *klass)
gtk_widget_class_set_template_from_resource (widget_class, "/org/gtk/libgtk/inspector/a11y.ui");
gtk_widget_class_bind_template_child (widget_class, GtkInspectorA11y, box);
gtk_widget_class_bind_template_child (widget_class, GtkInspectorA11y, role);
gtk_widget_class_bind_template_child (widget_class, GtkInspectorA11y, path);
gtk_widget_class_bind_template_child (widget_class, GtkInspectorA11y, attributes);
gtk_widget_class_bind_template_callback (widget_class, setup_cell_cb);

View File

@ -28,6 +28,30 @@
</child>
</object>
</child>
<child>
<object class="GtkBox">
<property name="margin-start">10</property>
<property name="margin-end">10</property>
<property name="margin-top">10</property>
<property name="margin-bottom">10</property>
<property name="spacing">40</property>
<child>
<object class="GtkLabel">
<property name="label" translatable="yes">Object path</property>
<property name="halign">start</property>
<property name="valign">baseline</property>
<property name="xalign">0.0</property>
</object>
</child>
<child>
<object class="GtkLabel" id="path">
<property name="selectable">1</property>
<property name="halign">end</property>
<property name="valign">baseline</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkSeparator"/>
</child>

View File

@ -25,6 +25,24 @@ button_label (void)
g_object_unref (button);
}
/* Check that we set up a labelled_by relationship between a button
* and its label.
*/
static void
button_relation (void)
{
GtkWidget *button = gtk_button_new_with_mnemonic ("_Hello");
GList *list;
g_object_ref_sink (button);
list = g_list_append (NULL, gtk_widget_get_first_child (button));
gtk_test_accessible_assert_relation (GTK_ACCESSIBLE (button), GTK_ACCESSIBLE_RELATION_LABELLED_BY, list);
g_list_free (list);
g_object_unref (button);
}
static void
linkbutton_role (void)
{
@ -54,6 +72,7 @@ main (int argc, char *argv[])
g_test_add_func ("/a11y/button/role", button_role);
g_test_add_func ("/a11y/button/label", button_label);
g_test_add_func ("/a11y/button/relation", button_relation);
g_test_add_func ("/a11y/linkbutton/role", linkbutton_role);
g_test_add_func ("/a11y/linkbutton/label", linkbutton_label);