Compare commits

...

115 Commits

Author SHA1 Message Date
Emmanuele Bassi
2855ea43a3 trashmonitor: Replace internal 1-bit fields with bool
Single bit fields cannot be used by address, and will overflow when
set to values that are bigger than one bit; the behaviour (if not the
size) of the C99 bool type is better defined.
2023-06-28 15:28:38 +01:00
Emmanuele Bassi
2a9296f54e calendar: Replace internal 1-bit fields with bool
Single bit fields cannot be used by address, and will overflow when
set to values that are bigger than one bit; the behaviour (if not the
size) of the C99 bool type is better defined.
2023-06-28 15:28:22 +01:00
Emmanuele Bassi
4c77a466af calendar: Remove unused field and translatable string
Since the switch to child widgets, GtkCalendar has stopped using the
"year_before" field, and does not need to compute whether the year
should be displayed before the month depending on the locale.
2023-06-28 15:27:10 +01:00
Emmanuele Bassi
91c7fc9cc5 colorswatch: Replace internal 1-bit fields with bool
Single bit fields cannot be used by address, and will overflow when
set to values that are bigger than one bit; the behaviour (if not the
size) of the C99 bool type is better defined.
2023-06-28 15:26:45 +01:00
Emmanuele Bassi
595e2e6001 coloreditor: Replace internal 1-bit fields with bool
Single bit fields cannot be used by address, and will overflow when
set to values that are bigger than one bit; the behaviour (if not the
size) of the C99 bool type is better defined.
2023-06-28 15:26:18 +01:00
Emmanuele Bassi
31e16ed7ba checkbutton: Replace internal 1-bit fields with bool
Single bit fields cannot be used by address, and will overflow when
set to values that are bigger than one bit; the behaviour (if not the
size) of the C99 bool type is better defined.
2023-06-28 15:25:59 +01:00
Emmanuele Bassi
2925ba2228 button: Replace internal 1-bit fields with bool
Single bit fields cannot be used by address, and will overflow when
set to values that are bigger than one bit; the behaviour (if not the
size) of the C99 bool type is better defined.
2023-06-28 15:25:37 +01:00
Emmanuele Bassi
40f6f11cae box: Replace internal 1-bit fields with bool
Single bit fields cannot be used by address, and will overflow when
set to values that are bigger than one bit; the behaviour (if not the
size) of the C99 bool type is better defined.
2023-06-28 15:25:06 +01:00
Emmanuele Bassi
f92dd63401 aboutdialog: Replace internal 1-bit fields with bool
Single bit fields cannot be used by address, and will overflow when
set to values that are bigger than one bit; the behaviour (if not the
size) of the C99 bool type is better defined.
2023-06-28 15:22:07 +01:00
Leônidas Araújo
2d39cdbff8 Update Brazilian Portuguese translation
(cherry picked from commit 98a2aae5ac)
2023-06-26 13:08:53 +00:00
Daniel Boles
8d675810e8 GtkText: Link to descendents/monospace CSS nodes
Change the descendent classes from `monospace`-without-links to links.
Add `monospace` around the names of CSS nodes and classes for clarity.
2023-06-26 13:05:39 +01:00
Matthias Clasen
8b25481c26 widget-factory: Set a11y labels on scale buttons
Just to check that this works now.
2023-06-25 22:28:23 -04:00
Ekaterine Papava
5fdf96f496 Update Georgian translation 2023-06-25 13:39:03 +00:00
Matthias Clasen
b61991a023 Merge branch 'gtkstack_fix_pages_param_check' into 'main'
stack: fix pages list bounds check

See merge request GNOME/gtk!6141
2023-06-24 12:08:18 +00:00
G.Willems
91d302a201 stack: fix pages list bounds check
Fix integer underflow when children->len is 0.
Add missing bounds check in select_item()
2023-06-24 03:05:37 +02:00
Matthias Clasen
35a1a62d50 Merge branch 'ebassi/builder-docs' into 'main'
docs: Clean up section on UI definitions

See merge request GNOME/gtk!6139
2023-06-23 23:45:05 +00:00
Matthias Clasen
ac7a4cb94c Merge branch 'wip/chergert/gdatetime-from-gtkbuilder' into 'main'
builder: add support for parsing GDateTime

See merge request GNOME/gtk!6140
2023-06-23 23:43:28 +00:00
Christian Hergert
bacd7ef92f builder: add support for parsing GDateTime
This will parse a <property/> containing the ISO 8601 format for a date
for use in GDateTime properties. For example:

  <property name="sampled-at">2023-06-23T00:00:00.00</property>
2023-06-23 14:11:37 -07:00
Emmanuele Bassi
980dc44f4a docs: Clean up section on UI definitions
The current documentation is narrative, but it lacks examples and proper
formatting, which makes it harder to read and visually scan.

Let's split off paragraphs and sections, so they can be easily linkend,
and add a few examples for each description.
2023-06-23 14:31:57 +01:00
Daniel Boles
2d648f84a9 docs/ref/gtk/running: Mention GDK_DEBUG=no-portals
It was omitted from !5336
2023-06-23 14:24:47 +01:00
Daniel Boles
aef0943f61 FileDialog: Fix typos of "inital" to "initial" 2023-06-23 13:50:53 +01:00
Matthias Clasen
3e146171cb Merge branch 'dboles/FileDialog_initial-folder_from_initial-file' into 'main'
Fix FileDialog: initial-file doesnʼt set initial-folder

See merge request GNOME/gtk!6137
2023-06-23 01:14:15 +00:00
Matthias Clasen
24bbaceaa4 Merge branch 'always-more-a11y-fixes' into 'main'
scalebutton: Use the group role

See merge request GNOME/gtk!6138
2023-06-23 01:06:57 +00:00
Matthias Clasen
318cf132e9 a11y: Extend the nested button hack to volume buttons 2023-06-22 18:37:10 -04:00
Matthias Clasen
8bbc143ed1 scalebutton: Use the group role
This is needed for accessible labels to work.
2023-06-22 18:36:39 -04:00
Daniel Boles
220d130c0f FileDialog: initial-file didnʼt set initial-folder
We always set :initial-folder to NULL and then notified about that,
instead of setting it to the folder of the :initial-file as we say.
2023-06-22 22:33:14 +01:00
Jordi Mas
e28a32a7c7 Update Catalan translation 2023-06-22 21:00:28 +02:00
Matthias Clasen
88f8b77d77 Merge branch 'matthiasc/for-main' into 'main'
docs: Mention GtkAccessibleRange

See merge request GNOME/gtk!6136
2023-06-22 02:40:08 +00:00
Matthias Clasen
1066374909 docs: Mention GtkAccessibleRange
In the accessibility docs about custom widgets,
mention GtkAccessibleRange as the best way to
implement custom range widgets.
2023-06-21 22:15:59 -04:00
Matthias Clasen
34a2595dfb Merge branch 'more-a11y-fixes' into 'main'
widget: Don't let abstract role slip through

See merge request GNOME/gtk!6135
2023-06-22 00:47:03 +00:00
Matthias Clasen
76fcd5cf25 Add another a11y test
This one catches the lingering 'widget' role
that only happens when widgets are realized
and rooted.
2023-06-21 19:55:46 -04:00
Matthias Clasen
32e6ed4eca a11y: Use group role for color and font buttons
This is needed since generic does not allow naming.
2023-06-21 19:55:46 -04:00
Matthias Clasen
2983c0be70 widget: Don't let abstract role slip through
When there isn't an accessible role set on the
instance or in class_init, we want to default
to 'generic'. There was one place where we
failed to do so.
2023-06-21 16:18:33 -04:00
Matthias Clasen
e0bf6585de Cosmetics: typo fix 2023-06-21 16:18:33 -04:00
Daniel Boles
c045b0be4c Settings: prop typo => "No description available."
Fix the typo so that we'll actually get documentation for
gtk-entry-select-on-focus.
2023-06-21 20:48:17 +01:00
Matthias Clasen
d8c094944a Merge branch 'more-a11y-fixes' into 'main'
a11y: Don't forget to space-separate computed names

See merge request GNOME/gtk!6134
2023-06-21 18:52:35 +00:00
Matthias Clasen
510bf86268 Add another a11y test
Test that roles come out right for custom widgets.
2023-06-21 14:24:52 -04:00
Matthias Clasen
f3bea027a0 Dropdown: Explicitly set a role
For some reason I haven't been able to track down,
the listitemwidget comes up wit the abstract widget
role otherwise.
2023-06-21 14:17:52 -04:00
Matthias Clasen
bce3b6f34a aboutdialog: Fix roles one more time
We are more picky about generic, so use group.
2023-06-21 13:47:59 -04:00
Matthias Clasen
01274dfbb9 shortcutswindow: Fix up roles and labels again 2023-06-21 13:18:58 -04:00
Matthias Clasen
533a2cf9ec a11y: Don't forget to space-separate computed names
This was overlooked in one place.
2023-06-21 13:18:07 -04:00
Matthias Clasen
5dbc5bbf22 Merge branch 'wip/antoniof/my-mistake' into 'main'
Fix my a mistake

See merge request GNOME/gtk!6130
2023-06-21 12:01:00 +00:00
António Fernandes
79c999cf76 columnviewrowwidget: Reset roles on teardown
This was added to the wrong file in e245883f91

Fix the mistake.
2023-06-21 12:23:39 +01:00
Matthias Clasen
e375bc8838 Merge branch 'wip/antoniof/columnviewrow-accessible-label' into 'main'
columnviewrow: Add accessible-label and -description

Closes #5903

See merge request GNOME/gtk!6129
2023-06-21 10:22:41 +00:00
Matthias Clasen
79505f940b Merge branch 'always-more-a11y-fixes' into 'main'
range: Don't use an abstract role

See merge request GNOME/gtk!6127
2023-06-21 10:07:57 +00:00
Matthias Clasen
0f087deb2a Merge branch 'bump-glib' into 'main'
Bump GLib requirement to 2.76.0

See merge request GNOME/gtk!6128
2023-06-21 10:07:40 +00:00
António Fernandes
e245883f91 columnviewrow: Add accessible-label and -description
Echoing the same changes introduced for GtkListItem by these commits:
* df8d28f5fe
* f2b682dd9c

Resolves https://gitlab.gnome.org/GNOME/gtk/-/issues/5903
2023-06-21 10:27:39 +01:00
Chun-wei Fan
4e9bd13892 Visual Studio: Remove workarounds for <= glib-2.74.x
We now need glib-2.76.0 or later, which removes our needs for the workarounds
that we need to build the media backends against GLib-2.74.x or earlier, so
clean up things a bit.
2023-06-21 12:29:38 +08:00
Chun-wei Fan
65e9b8fe66 glib.wrap: Use 2.76.0
We are now using APIs that were introduced in 2.75.x, so let's use glib-2.76.0
here for our glib subproject.

Update the build and gobject-introspection items accordingly
2023-06-21 12:27:41 +08:00
Matthias Clasen
e9f870fee6 Make generic really the default role
If nothing else has been set for the instance
or the class, return GTK_ACCESSIBLE_ROLE_GENERIC.
2023-06-20 22:02:37 -04:00
Matthias Clasen
e5e5966934 frame: Use the group role 2023-06-20 21:58:55 -04:00
Matthias Clasen
5c407365e3 ci: Use the current build options for flatpaks
These were changed a while ago.
2023-06-20 20:49:29 -04:00
Matthias Clasen
7e251d81c2 a11y: Fix the stack switcher selection implementation
This was listening for signals on the wrong object.
2023-06-20 20:49:29 -04:00
Matthias Clasen
92d1d52c59 NEWS: updates 2023-06-20 20:49:29 -04:00
Matthias Clasen
ef436e4dce range: Don't use an abstract role
This snuck through, because the range wasn't
setting any role at all, it just ends up using
the initial, abstract role of widget.
2023-06-20 20:49:29 -04:00
Benjamin Otte
1a07e336bf Merge branch 'wip/otte/for-vulkan' into 'main'
vulkan: Fix a bunch of validation-layer complaints

See merge request GNOME/gtk!6126
2023-06-20 18:38:41 +00:00
Benjamin Otte
169355f771 vulkan: Rebuild the precompiled shaders
We forgot that with all the changes.
2023-06-20 20:17:06 +02:00
Benjamin Otte
299c6a3d6f vulkan: Take offscreen fromat from context
We want to create offscreens in compatible formats, and in particular we
want to ideally use the same format as rendering would use.
2023-06-20 20:15:12 +02:00
Benjamin Otte
17698bfd2e vulkan: Use 3 descriptor sets, not 3 bindings
It turns out variable length is only supported for the last binding in
a set, not for every binding.
So we need to create one set for each of our arrays.

[ VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-pBindingFlags-03004 ] Object 0: handle = 0x33a9f10, type = VK_OBJECT_TYPE_DEVICE; | MessageID = 0xd3f353a | vkCreateDescriptorSetLayout(): pBindings[0] has VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT but 0 is the largest value of all the bindings. The Vulkan spec states: If an element of pBindingFlags includes VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT, then all other elements of VkDescriptorSetLayoutCreateInfo::pBindings must have a smaller value of binding (https://www.khronos.org/registry/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-pBindingFlags-03004)
2023-06-20 20:15:12 +02:00
Benjamin Otte
377592cb62 vulkan: Use the right flags
Somebody (me) had flipped the 2 flags in commit ba28971a18:

[ VUID-vkCmdCopyBufferToImage-srcBuffer-00174 ] Object 0: handle = 0x3cfaac0, type = VK_OBJECT_TYPE_COMMAND_BUFFER; Object 1: handle = 0x430000000043, type = VK_OBJECT_TYPE_BUFFER; | MessageID = 0xe1b276a1 | Invalid usage flag for VkBuffer 0x430000000043[] used by vkCmdCopyBufferToImage. In this case, VkBuffer should have VK_BUFFER_USAGE_TRANSFER_SRC_BIT set during creation. The Vulkan spec states: srcBuffer must have been created with VK_BUFFER_USAGE_TRANSFER_SRC_BIT usage flag (https://www.khronos.org/registry/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-vkCmdCopyBufferToImage-srcBuffer-00174)
2023-06-20 20:15:12 +02:00
Benjamin Otte
015cebc046 vulkan: Set descriptorBindingStorageBufferUpdateAfterBind
It's necessary now that we use storage buffers for gradients:

[ VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-descriptorBindingStorageBufferUpdateAfterBind-03008 ] Object 0: handle = 0x1e72d70, type = VK_OBJECT_TYPE_DEVICE; | MessageID = 0x943cc552 | vkCreateDescriptorSetLayout(): pBindings[0] can't have VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT for VK_DESCRIPTOR_TYPE_STORAGE_BUFFER since descriptorBindingStorageBufferUpdateAfterBind is not enabled. The Vulkan spec states: If VkPhysicalDeviceDescriptorIndexingFeatures::descriptorBindingStorageBufferUpdateAfterBind is not enabled, all bindings with descriptor type VK_DESCRIPTOR_TYPE_STORAGE_BUFFER must not use VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT (https://www.khronos.org/registry/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-descriptorBindingStorageBufferUpdateAfterBind-03008)
2023-06-20 20:15:12 +02:00
Benjamin Otte
0a5e5023a8 vulkan: Remove unused declaration from shader 2023-06-20 20:15:12 +02:00
Matthias Clasen
a9b8ad6181 Merge branch 'always-more-a11y-fixes' into 'main'
Add a comment about accessible naming

See merge request GNOME/gtk!6125
2023-06-20 17:13:51 +00:00
Matthias Clasen
7331683c01 a11y: Improve name computation
We only want to settle on subtree content
if it provides nonempty text. Otherwise,
the tooltip should still win.

This was clarified in the current Editor Draft
of the accessible name computation spec.
2023-06-20 12:34:51 -04:00
Matthias Clasen
cca6a66518 a11y: Fix tests
The change to make hidden follow mappedness
means that we now need to arrange for our
test cases to be mapped.
2023-06-20 12:33:02 -04:00
Matthias Clasen
891462e5af Add some more a11y tests
Check that the hidden state is as it should be.
2023-06-20 11:05:22 -04:00
Matthias Clasen
95cd6fe206 menubutton: Remove all the labelled-by relations
This was a bit much, and should not be necessary anymore,
now that our name computation handles nested buttons.
2023-06-20 10:58:18 -04:00
Matthias Clasen
63534fd9eb widget: Fix accessible hidden state
Make this track the widgets' mapped state
instead of visible. Also, set hidden to FALSE
initially, since the accessible name computation
checks for hidden==FALSE.
2023-06-20 10:40:12 -04:00
Matthias Clasen
e836e3380e Add a comment about accessible naming
Put a note on why there are a few differences
to ARIA.
2023-06-20 06:54:59 -04:00
Matthias Clasen
f693beab57 NEWS: Updates 2023-06-20 06:54:40 -04:00
Matthias Clasen
2d2df42a94 Merge branch 'listitem-a11y' into 'main'
listitem: Add accessible-label and -description

See merge request GNOME/gtk!6123
2023-06-20 09:55:58 +00:00
Matthias Clasen
fb0a4fa457 a11y: Stop recommending tab list labels
There is no good way to set an explicit label
on the tab list of a GtkNotebook, so showing
a blue overlay on it is annoying more than
helpful.

This is another little deviation from the ARIA
authoring guidelines.
2023-06-19 22:20:05 -04:00
Matthias Clasen
be0003c108 a11y: Stop recommending against listitem labels
Due to the way listviews are set up, there is not
much of an alternative to setting labels on the
listitems, so don't recommend against doing it.

This is a little deviation from the ARIA authoring
guidelines.
2023-06-19 22:20:05 -04:00
Matthias Clasen
eb1e24a5bf gizmo: Stop using abstract roles
This was overlooked.
2023-06-19 22:20:05 -04:00
Matthias Clasen
a3e98558d3 gtk-demo: Some a11y improvements
Add missing labels to the applauncher demo
and the clocks demo.
2023-06-19 22:19:54 -04:00
Matthias Clasen
f2b682dd9c listitemwidget: Clean up in teardown 2023-06-19 21:50:45 -04:00
Matthias Clasen
b826ef4f4d Merge branch 'a11y-work' into 'main'
A11y role changes

See merge request GNOME/gtk!6101
2023-06-20 01:23:13 +00:00
Matthias Clasen
a2fdeb99e0 gtk-demo: Improve a11y for applauncher
Use the new listitem properties to make
orca read the selected item in the applauncher
demo.
2023-06-19 21:21:55 -04:00
Matthias Clasen
df8d28f5fe listitem: Add accessible-label and -description
Add properties to GtkListItem to set the accessible
label and description of the listitem widget. This
is important, since orca will read these if the
listitem widget ends up with the focus.
2023-06-19 21:21:55 -04:00
Matthias Clasen
838c51cc92 a11y: Add the ARIA ontology
Add a helper function to find out which roles are
superclasses of each other.

This isn't used yet (apart from the existing use for
ranges), but it might be in the future.
2023-06-19 18:38:58 -04:00
Matthias Clasen
315ded687c Docs: update 2023-06-19 18:38:58 -04:00
Matthias Clasen
6855346269 a11y: Treat widget and window as abstract roles
We no longer use these, so we can enforce
that they are abstract.
2023-06-19 18:38:58 -04:00
Matthias Clasen
c2d6f900d9 window: Use application as accessible role
ARIA deems the window role to be abstract,
so lets use the application role instead.

Update affected tests.
2023-06-19 18:38:58 -04:00
Matthias Clasen
85c2d5f14e Add the application role
ARIA has this role. We left it out initially, but
it is an ok fit for toplevel windows, and better
than window, since that is meant to be abstract.
2023-06-19 18:38:58 -04:00
Matthias Clasen
b3eb912cf3 Use generic as default accessible role
The ARIA specs want widget to be abstract role.
We should respect that and use 'generic' instead.
2023-06-19 18:38:58 -04:00
Matthias Clasen
81d9205369 widget: Warn for abstract accessible roles
These should not be used for widgets, so warn if
they are passed to gtk_widget_set_accessible_role()
or gtk_widget_class_set_accessible_role().
2023-06-19 18:38:32 -04:00
Matthias Clasen
152a335cee Add gtk_accessible_role_is_abstract
Move this code from the a11y overlay in the inspector.
It will be used more widely, going forward.
2023-06-19 18:30:41 -04:00
Matthias Clasen
b84650c2a3 Add another a11y test 2023-06-19 18:30:41 -04:00
Matthias Clasen
722bea2943 Merge branch 'a11y-defeat' into 'main'
Give up on warning ATs into submission

See merge request GNOME/gtk!6121
2023-06-19 21:06:13 +00:00
Matthias Clasen
6c337b949d Merge branch 'fix-issue-5899' into 'main'
GtkFileChooserWidget: Fix condition on visit action

Closes #5899

See merge request GNOME/gtk!6103
2023-06-19 20:52:15 +00:00
Matthias Clasen
db97a35dc7 a11y: Remove the unrealized warning
This warning triggers quite a lot when opening
a window while orca is running, which clearly
shows that what it warns about happens in
practice. But fixing it is reentry hell, and
not a battle I'm up for today.
2023-06-19 16:41:39 -04:00
Matthias Clasen
c2fda63b0d Give up on warning ATs into submission
Its been more than a decade since Wayland
has not supported screen coordinates. Clearly
spamming every apps stderr with warnings is
never going to make ATs stop asking for screen
coordinates.

Just give up. Go home
2023-06-19 16:41:20 -04:00
Benjamin Otte
5da64e9e34 Merge branch 'unaligned-access' into 'main'
gtk: Align key_size up to key_align

Closes #5907

See merge request GNOME/gtk!6120
2023-06-19 20:26:18 +00:00
Matt Turner
3f360aa883 gtk: Align key_size up to key_align
Avoids unaligned accesses when e.g. the key_size is 12 and key_align is
8. We need to round the key size up to 16 to ensure that all keys are
appropriately aligned.

This manifested as a failure in the `gtk:gtk / sorter` unit test on
sparc.

Closes: https://gitlab.gnome.org/GNOME/gtk/-/issues/5907
2023-06-19 15:55:09 -04:00
Matt Turner
a444045386 gtk: Pass G_ALIGNOF (...) to gtk_sort_keys_new
The sizeof and G_ALIGNOF are often, but not always, identical.
2023-06-19 15:54:51 -04:00
Daniel Boles
584a807ed6 Widget: Also mention get_height in get_alloc depʼn
The deprecation notice seems to have been copied from
get_allocated_width(), but for get_allocation() height is also relevant.
2023-06-19 20:29:23 +01:00
Matthias Clasen
72e5697804 Merge branch 'redo-a11y-name-computation' into 'main'
Reimplement a11y name computation

See merge request GNOME/gtk!6119
2023-06-19 17:49:22 +00:00
Matthias Clasen
93aff8a129 Add more name computation tests
Test the fallback for range values.

This was not working at all before
the previous commit.
2023-06-19 12:40:33 -04:00
Matthias Clasen
c3cfaab479 a11y: Fix name computation for ranges
There were two problems here:

First, the code was checking for the abstract
range role, instead of its subclasses.

Second, the code was calling a string value
getter on a number value. Oops.
2023-06-19 12:40:32 -04:00
Matthias Clasen
663e3d0811 Add tests for accessible name computation 2023-06-19 12:38:51 -04:00
Matthias Clasen
2dc35ec0c1 a11y: Quietly allow realizing unrooted at context
We can't set the display if we don't have a root,
but the default display is more than good enough
for the tests which otherwise would need to do
quite a bit more setup work to make their test
widgets rooted.
2023-06-19 12:38:51 -04:00
Matthias Clasen
a791f235e6 a11y: Only allow get_name/description when realized
These functions rely on self->accessible_role
being set, and that is only the case for realized
contexts.

In practice, this is not a problem. Contexts are
realized before ATs can get their names or descriptions,
and the inspector realizes contexts too, nowadays.

The only place where this caused a hickup is the
testsuite.
2023-06-19 12:38:51 -04:00
Matthias Clasen
7df9cc1b47 label: Stop overriding accessible label
There's no need to, the accessible name computation
picks the content up where it is allowed (and not
overridden by explicit attributes).
2023-06-19 12:38:51 -04:00
Matthias Clasen
4449344fad a11y: Reimplement name computation
Reimplement the name computation to follow the spec
(https://www.w3.org/TR/accname-1.2) more closely.

Also, unify the functions for name and description,
since their only difference is which property/relation
they use.
2023-06-19 12:38:51 -04:00
Matthias Clasen
e1c9f50d26 a11y: Cosmetics
No need to have two code paths doing the same.
2023-06-19 12:38:51 -04:00
Matthias Clasen
1f029229dc Merge branch 'a11y-inspector-tweaks' into 'main'
Move the a11y naming data into gtk proper

See merge request GNOME/gtk!6118
2023-06-19 16:21:31 +00:00
Matthias Clasen
a80dd28e35 a11y: Move naming data to gtkatcontext.c
This is in preparation for using this information
in the name computation.
2023-06-19 11:17:47 -04:00
Matthias Clasen
16077fbdac inspector: Tweak the a11y overlay
Shorten the warnings, and lower some of the
errors to 'not recommended' (where the authoring
guidelines say 'do not label', but aria doesn't
prohibit labels outright).
2023-06-19 11:17:47 -04:00
Matthias Clasen
1906bb5263 a11y: Update the name-prohibited list
ARIA has the time role in this as well.

It does not matter in practice since we don't
have a widget with this role, but lets match
the specs.
2023-06-19 11:17:47 -04:00
Matthias Clasen
a8b907a33c a11y: Cover the printer option widget case too
This is another case of nested control, in this
case it goes two levels deep. Since we already
have this hack, lets use it for all the cases.
This avoids some more complicated workaround.
2023-06-19 11:17:47 -04:00
Matthias Clasen
f2a2e97004 docs: Add guidance on container roles
Provide some guidance on whether group or generic
is a more suitable role for containers.
2023-06-19 11:17:47 -04:00
Matthias Clasen
a86923de94 a11y: Change the role for many containers
The group role that we've used before has some
implications of semantic grouping, whereas these
containers are mainly about layout, so use the
generic role instead.

This should not affect the translation to AT-SPI
at all.

The affected containers are: box, grid, centerbox,
scrolledwindow, viewport, windowhandle, aspectframe.

The role of GtkTreeExpander has been changed to
button instead, since it acts as a button.
2023-06-19 11:15:48 -04:00
Matthias Clasen
4412f25c9f a11y: Treat none and presentation the same
ARIA says these roles are aliases, so treat them
the same.
2023-06-19 11:15:48 -04:00
Luca Bacci
16bdaa11ce GtkFileChooserWidget: Use GTK_INVALID_LIST_POSITION
...instead of G_MAXUINT
2023-06-17 15:51:22 +02:00
Luca Bacci
46afb4a9a4 GtkFileChooserWidget: Fix condition on visit action
Fixes #5899
2023-06-17 15:50:50 +02:00
163 changed files with 3882 additions and 2483 deletions

View File

@@ -23,8 +23,8 @@ flatpak build ${builddir} meson \
-Dbuild-testsuite=false \
-Dbuild-examples=false \
-Dintrospection=disabled \
-Ddemos=true \
-Dprofile=devel \
-Dbuild-demos=true \
-Ddemo-profile=devel \
_flatpak_build
flatpak build ${builddir} ninja -C _flatpak_build install

56
NEWS
View File

@@ -1,6 +1,62 @@
Overview of Changes in 4.11.4, xx-xx-xxxx
=========================================
* GtkFileChooser:
- Default to sorting folders first
- Fix a crash when visiting recent files
* GtkTextView:
- Fix corner cases in word navigation
* GtkMenuButton:
- Normalize label layout
* GtkDropDown:
- Add support for sections
* GtkVideo:
- Make the overlay icon clickable
* GtkWindow:
- Clear the resize cursors to avoid artifacts
* Accessibility:
- Improvements all over the place: GtkButton, GtkPasswordEntry,
GtkFontChooserDialog, GtkColorChooserDialog, GtkShortcutsWindow,
GtkMenuButton, GtkAboutDialog, GtkFileChooserDialog, GtkStackSidebar,
GtkMediaControls, GtkColorDialogButton, GtkDropDown, GtkInfoBar,
GtkNotebook, GtkPrintUnixDialog, GtkModelButton
- Make name computation follow the ARIA spec more closely
- Change many containers to use `generic` instead of `group`
- Use `generic` as the default role
- Use `application` instead of `window` for windows
* X11:
- Fix regressions in GLX setup
* Windows:
- Center newly created transient windows
* Vulkan:
- Add antialising for gradients
- Do less work on clipped away nodes
- Redo image uploading
- Support different image depths and formats
* Demos:
- gtk4-demo: Improve window sizing
- gtk4-demo: Improve focus behavior
- gtk4-demo: Add many missing a11y properties
`
* Inspector:
- Show more information in the a11y tab
- Add an accessibility overlay with warnings and recommendations
- Limit the width of the a11y tab
* Translation updates:
Czech
Overview of Changes in 4.11.3, 05-06-2023
=========================================

View File

@@ -52,6 +52,10 @@ setup_listitem_cb (GtkListItemFactory *factory,
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
image = gtk_image_new ();
gtk_accessible_update_property (GTK_ACCESSIBLE (image),
GTK_ACCESSIBLE_PROPERTY_LABEL,
"App icon",
-1);
gtk_image_set_icon_size (GTK_IMAGE (image), GTK_ICON_SIZE_LARGE);
gtk_box_append (GTK_BOX (box), image);
label = gtk_label_new ("");
@@ -79,6 +83,7 @@ bind_listitem_cb (GtkListItemFactory *factory,
gtk_image_set_from_gicon (GTK_IMAGE (image), g_app_info_get_icon (app_info));
gtk_label_set_label (GTK_LABEL (label), g_app_info_get_display_name (app_info));
gtk_list_item_set_accessible_label (list_item, g_app_info_get_display_name (app_info));
}
/* In more complex code, we would also need functions to unbind and teardown

View File

@@ -431,6 +431,9 @@ setup_listitem_cb (GtkListItemFactory *factory,
picture = gtk_picture_new ();
gtk_expression_bind (expression, picture, "paintable", picture);
gtk_box_append (GTK_BOX (box), picture);
gtk_accessible_update_relation (GTK_ACCESSIBLE (picture),
GTK_ACCESSIBLE_RELATION_LABELLED_BY, location_label, NULL,
-1);
/* And finally, everything comes together.
@@ -487,6 +490,9 @@ do_listview_clocks (GtkWidget *do_widget)
model = GTK_SELECTION_MODEL (gtk_no_selection_new (create_clocks_model ()));
gridview = gtk_grid_view_new (model, factory);
gtk_accessible_update_property (GTK_ACCESSIBLE (gridview),
GTK_ACCESSIBLE_PROPERTY_LABEL, "Clocks",
-1);
gtk_scrollable_set_hscroll_policy (GTK_SCROLLABLE (gridview), GTK_SCROLL_NATURAL);
gtk_scrollable_set_vscroll_policy (GTK_SCROLLABLE (gridview), GTK_SCROLL_NATURAL);

View File

@@ -1572,6 +1572,9 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
<property name="valign">3</property>
<child>
<object class="GtkVolumeButton">
<accessibility>
<property name="label" translatable="1">Volume</property>
</accessibility>
<property name="orientation">1</property>
<property name="valign">3</property>
<property name="value">.5</property>
@@ -1584,6 +1587,9 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
</child>
<child>
<object class="GtkScaleButton" id="mic-button">
<accessibility>
<property name="label" translatable="1">Microphone gain</property>
</accessibility>
<property name="has-tooltip">1</property>
<property name="icons">microphone-sensitivity-muted-symbolic
microphone-sensitivity-high-symbolic

View File

@@ -211,6 +211,9 @@ A number of options affect behavior instead of logging:
`portals`
: Force the use of [portals](https://docs.flatpak.org/en/latest/portals.html)
`no-portals`
: Disable use of [portals](https://docs.flatpak.org/en/latest/portals.html)
`gl-disable`
: Disable OpenGL support

View File

@@ -31,7 +31,7 @@ described by a set of *attributes*.
Roles define the taxonomy and semantics of a UI control to any assistive
technology application; for instance, a button will have a role of
`GTK_ACCESSIBLE_ROLE_BUTTON`; an entry will have a role of
`GTK_ACCESSIBLE_ROLE_TEXTBOX`; a toggle button will have a role of
`GTK_ACCESSIBLE_ROLE_TEXTBOX`; a check button will have a role of
`GTK_ACCESSIBLE_ROLE_CHECKBOX`; etc.
Each role is part of the widget's instance, and **cannot** be changed over
@@ -46,6 +46,7 @@ Each role name is part of the #GtkAccessibleRole enumeration.
| Role name | Description | Related GTK widget |
|-----------|-------------|--------------------|
| `APPLICATION` | An application window | [class@Gtk.Window] |
| `BUTTON` | A control that performs an action when pressed | [class@Gtk.Button], [class@Gtk.LinkButton], [class@Gtk.Expander] |
| `CHECKBOX` | A control that has three possible value: `true`, `false`, or `undefined` | [class@Gtk.CheckButton] |
| `COMBOBOX` | A control that can be expanded to show a list of possible values to select | [class@Gtk.ComboBox] |
@@ -78,7 +79,6 @@ Each role name is part of the #GtkAccessibleRole enumeration.
| `TAB_PANEL` | A page in a notebook or stack | [class@Gtk.Stack] |
| `TEXT_BOX` | A type of input that allows free-form text as its value. | [class@Gtk.Entry], [class@Gtk.PasswordEntry], [class@Gtk.TextView] |
| `TREE_GRID` | A treeview-like columned list | [class@Gtk.ColumnView] |
| `WINDOW` | An application window | [class@Gtk.Window] |
| `...` | … |
See the [WAI-ARIA](https://www.w3.org/WAI/PF/aria/appendices#quickref) list
@@ -216,6 +216,16 @@ are accessible as part of the development process. The GTK Inspector shows
the accessible attributes of each widget, and also provides an overlay that
can highlight accessibility issues.
It is possible to set accessible attributes in UI files as well:
```xml
<object class="GtkButton" id="button1">
<accessibility>
<property name="label">Download</property>
<relation name="labelled-by">label1</relation>
/accessibility>
</object>
```
## Implementations
Each UI control implements the `GtkAccessible` interface to allow widget and
@@ -257,6 +267,13 @@ turn automatically any widget into a `GtkButton`; but if your widget behaves
like a button, using the %GTK_ACCESSIBLE_ROLE_BUTTON will allow any
assistive technology to handle it like they would a `GtkButton`.
For widgets that act as containers of other widgets, you should use
%GTK_ACCESSIBLE_ROLE_GROUP if the grouping of the children is semantic
in nature; for instance, the children of a [class@Gtk.HeaderBar] are
grouped together on the header of a window. For generic containers that
only impose a layout on their children, you should use
%GTK_ACCESSIBLE_ROLE_GENERIC instead.
### Attributes can both hide and enhance
Accessible attributes can be used to override the content of a UI element,
@@ -365,3 +382,6 @@ To allow changing the value via accessible technologies, you can export
actions. Since the accessibility interfaces only support actions
without parameters, you should provide actions such as `increase-value`
and `decrease-value`.
Since GTK 4.10, the best way to suppose changing the value is by implementing
the [iface@Gtk.AccessibleRange] interface.

View File

@@ -52,6 +52,7 @@ struct _GdkVulkanContextPrivate {
GdkMemoryFormat gdk_format;
} formats[4];
GdkMemoryDepth current_format;
GdkMemoryFormat offscreen_formats[4];
VkSwapchainKHR swapchain;
VkSemaphore draw_semaphore;
@@ -693,6 +694,11 @@ gdk_vulkan_context_real_init (GInitable *initable,
if (!priv->vulkan_ref)
return FALSE;
priv->offscreen_formats[GDK_MEMORY_U8] = GDK_MEMORY_B8G8R8A8_PREMULTIPLIED;
priv->offscreen_formats[GDK_MEMORY_U16] = GDK_MEMORY_R16G16B16A16_PREMULTIPLIED;
priv->offscreen_formats[GDK_MEMORY_FLOAT16] = GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED;
priv->offscreen_formats[GDK_MEMORY_FLOAT32] = GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED;
if (surface == NULL)
{
for (i = 0; i < G_N_ELEMENTS (priv->formats); i++)
@@ -748,6 +754,7 @@ gdk_vulkan_context_real_init (GInitable *initable,
{
priv->formats[GDK_MEMORY_U8].vk_format = formats[i];
priv->formats[GDK_MEMORY_U8].gdk_format = GDK_MEMORY_B8G8R8A8_PREMULTIPLIED;
priv->offscreen_formats[GDK_MEMORY_U8] = GDK_MEMORY_B8G8R8A8_PREMULTIPLIED;
};
break;
@@ -827,6 +834,15 @@ out_surface:
return FALSE;
}
GdkMemoryFormat
gdk_vulkan_context_get_offscreen_format (GdkVulkanContext *context,
GdkMemoryDepth depth)
{
GdkVulkanContextPrivate *priv = gdk_vulkan_context_get_instance_private (context);
return priv->offscreen_formats[depth];
}
static void
gdk_vulkan_context_initable_init (GInitableIface *iface)
{
@@ -1168,6 +1184,7 @@ gdk_display_create_vulkan_device (GdkDisplay *display,
.descriptorBindingPartiallyBound = VK_TRUE,
.descriptorBindingVariableDescriptorCount = VK_TRUE,
.descriptorBindingSampledImageUpdateAfterBind = VK_TRUE,
.descriptorBindingStorageBufferUpdateAfterBind = VK_TRUE,
}
},
NULL,

View File

@@ -69,9 +69,12 @@ gdk_vulkan_handle_result (VkResult res,
#define GDK_VK_CHECK(func, ...) gdk_vulkan_handle_result (func (__VA_ARGS__), G_STRINGIFY (func))
gboolean gdk_display_ref_vulkan (GdkDisplay *display,
GError **error);
void gdk_display_unref_vulkan (GdkDisplay *display);
gboolean gdk_display_ref_vulkan (GdkDisplay *display,
GError **error);
void gdk_display_unref_vulkan (GdkDisplay *display);
GdkMemoryFormat gdk_vulkan_context_get_offscreen_format (GdkVulkanContext *context,
GdkMemoryDepth depth);
#else /* !GDK_RENDERING_VULKAN */

View File

@@ -78,8 +78,8 @@ gsk_vulkan_buffer_new_map (GdkVulkanContext *context,
{
return gsk_vulkan_buffer_new_internal (context,
size,
(mode & GSK_VULKAN_READ ? VK_BUFFER_USAGE_TRANSFER_SRC_BIT : 0) |
(mode & GSK_VULKAN_WRITE ? VK_BUFFER_USAGE_TRANSFER_DST_BIT : 0));
(mode & GSK_VULKAN_READ ? VK_BUFFER_USAGE_TRANSFER_DST_BIT : 0) |
(mode & GSK_VULKAN_WRITE ? VK_BUFFER_USAGE_TRANSFER_SRC_BIT : 0));
}
void

View File

@@ -488,24 +488,6 @@ gsk_memory_format_get_fallback (GdkMemoryFormat format)
}
}
GdkMemoryFormat
gsk_render_node_get_preferred_vulkan_format (GskRenderNode *node)
{
switch (gsk_render_node_get_preferred_depth (node))
{
case GDK_MEMORY_U8:
return GDK_MEMORY_R8G8B8A8_PREMULTIPLIED;
case GDK_MEMORY_U16:
return GDK_MEMORY_R16G16B16A16_PREMULTIPLIED;
case GDK_MEMORY_FLOAT16:
return GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED;
case GDK_MEMORY_FLOAT32:
return GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED;
default:
g_return_val_if_reached (GDK_MEMORY_R8G8B8A8_PREMULTIPLIED);
}
}
static gboolean
gsk_vulkan_context_supports_format (GdkVulkanContext *context,
VkFormat format)

View File

@@ -1,7 +1,6 @@
#pragma once
#include <gdk/gdk.h>
#include <gsk/gskrendernode.h>
#include "gskvulkanbufferprivate.h"
#include "gskvulkancommandpoolprivate.h"
@@ -22,8 +21,6 @@ void gsk_vulkan_uploader_free (GskVulk
void gsk_vulkan_uploader_reset (GskVulkanUploader *self);
void gsk_vulkan_uploader_upload (GskVulkanUploader *self);
GdkMemoryFormat gsk_render_node_get_preferred_vulkan_format (GskRenderNode *node);
GskVulkanImage * gsk_vulkan_image_new_for_swapchain (GdkVulkanContext *context,
VkImage image,
VkFormat format,

View File

@@ -41,6 +41,8 @@
#define GDK_ARRAY_NO_MEMSET 1
#include "gdk/gdkarrayimpl.c"
#define N_DESCRIPTOR_SETS 3
struct _GskVulkanRender
{
GskRenderer *renderer;
@@ -52,7 +54,7 @@ struct _GskVulkanRender
GskVulkanCommandPool *command_pool;
VkFence fence;
VkDescriptorSetLayout descriptor_set_layout;
VkDescriptorSetLayout descriptor_set_layouts[N_DESCRIPTOR_SETS];
VkPipelineLayout pipeline_layout;
GskVulkanUploader *uploader;
@@ -60,7 +62,7 @@ struct _GskVulkanRender
GskDescriptorImageInfos descriptor_samplers;
GskDescriptorBufferInfos descriptor_buffers;
VkDescriptorPool descriptor_pool;
VkDescriptorSet descriptor_set;
VkDescriptorSet descriptor_sets[N_DESCRIPTOR_SETS];
GskVulkanPipeline *pipelines[GSK_VULKAN_N_PIPELINES];
GskVulkanImage *target;
@@ -148,9 +150,9 @@ gsk_vulkan_render_new (GskRenderer *renderer,
&(VkDescriptorPoolCreateInfo) {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
.flags = VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT,
.maxSets = 1,
.poolSizeCount = 3,
.pPoolSizes = (VkDescriptorPoolSize[3]) {
.maxSets = N_DESCRIPTOR_SETS,
.poolSizeCount = N_DESCRIPTOR_SETS,
.pPoolSizes = (VkDescriptorPoolSize[N_DESCRIPTOR_SETS]) {
{
.type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
.descriptorCount = DESCRIPTOR_POOL_MAXITEMS
@@ -171,7 +173,7 @@ gsk_vulkan_render_new (GskRenderer *renderer,
GSK_VK_CHECK (vkCreateDescriptorSetLayout, device,
&(VkDescriptorSetLayoutCreateInfo) {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
.bindingCount = 3,
.bindingCount = 1,
.flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT,
.pBindings = (VkDescriptorSetLayoutBinding[3]) {
{
@@ -179,30 +181,12 @@ gsk_vulkan_render_new (GskRenderer *renderer,
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
.descriptorCount = DESCRIPTOR_POOL_MAXITEMS,
.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT
},
{
.binding = 1,
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER,
.descriptorCount = DESCRIPTOR_POOL_MAXITEMS,
.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT
},
{
.binding = 2,
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
.descriptorCount = DESCRIPTOR_POOL_MAXITEMS,
.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT
},
}
},
.pNext = &(VkDescriptorSetLayoutBindingFlagsCreateInfo) {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO,
.bindingCount = 3,
.pBindingFlags = (VkDescriptorBindingFlags[3]) {
VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT
| VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT
| VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT,
VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT
| VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT
| VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT,
.bindingCount = 1,
.pBindingFlags = (VkDescriptorBindingFlags[1]) {
VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT
| VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT
| VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT,
@@ -210,15 +194,65 @@ gsk_vulkan_render_new (GskRenderer *renderer,
}
},
NULL,
&self->descriptor_set_layout);
&self->descriptor_set_layouts[0]);
GSK_VK_CHECK (vkCreateDescriptorSetLayout, device,
&(VkDescriptorSetLayoutCreateInfo) {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
.bindingCount = 1,
.flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT,
.pBindings = (VkDescriptorSetLayoutBinding[1]) {
{
.binding = 0,
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER,
.descriptorCount = DESCRIPTOR_POOL_MAXITEMS,
.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT
}
},
.pNext = &(VkDescriptorSetLayoutBindingFlagsCreateInfo) {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO,
.bindingCount = 1,
.pBindingFlags = (VkDescriptorBindingFlags[1]) {
VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT
| VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT
| VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT,
},
}
},
NULL,
&self->descriptor_set_layouts[1]);
GSK_VK_CHECK (vkCreateDescriptorSetLayout, device,
&(VkDescriptorSetLayoutCreateInfo) {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
.bindingCount = 1,
.flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT,
.pBindings = (VkDescriptorSetLayoutBinding[1]) {
{
.binding = 0,
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
.descriptorCount = DESCRIPTOR_POOL_MAXITEMS,
.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT
},
},
.pNext = &(VkDescriptorSetLayoutBindingFlagsCreateInfo) {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO,
.bindingCount = 1,
.pBindingFlags = (VkDescriptorBindingFlags[1]) {
VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT
| VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT
| VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT,
},
}
},
NULL,
&self->descriptor_set_layouts[2]);
GSK_VK_CHECK (vkCreatePipelineLayout, device,
&(VkPipelineLayoutCreateInfo) {
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
.setLayoutCount = 1,
.pSetLayouts = (VkDescriptorSetLayout[1]) {
self->descriptor_set_layout
},
.setLayoutCount = G_N_ELEMENTS (self->descriptor_set_layouts),
.pSetLayouts = self->descriptor_set_layouts,
.pushConstantRangeCount = gsk_vulkan_push_constants_get_range_count (),
.pPushConstantRanges = gsk_vulkan_push_constants_get_ranges ()
},
@@ -403,10 +437,18 @@ gsk_vulkan_render_get_pipeline (GskVulkanRender *self,
return self->pipelines[type];
}
VkDescriptorSet
gsk_vulkan_render_get_descriptor_set (GskVulkanRender *self)
void
gsk_vulkan_render_bind_descriptor_sets (GskVulkanRender *self,
VkCommandBuffer command_buffer)
{
return self->descriptor_set;
vkCmdBindDescriptorSets (command_buffer,
VK_PIPELINE_BIND_POINT_GRAPHICS,
self->pipeline_layout,
0,
3,
self->descriptor_sets,
0,
NULL);
}
gsize
@@ -537,11 +579,6 @@ gsk_vulkan_render_prepare_descriptor_sets (GskVulkanRender *self)
gsk_vulkan_render_pass_reserve_descriptor_sets (pass, self);
}
if (gsk_descriptor_image_infos_get_size (&self->descriptor_samplers) == 0 &&
gsk_descriptor_image_infos_get_size (&self->descriptor_images) == 0 &&
gsk_descriptor_buffer_infos_get_size (&self->descriptor_buffers) == 0)
return;
if (self->storage_buffer_memory)
{
gsk_vulkan_buffer_unmap (self->storage_buffer);
@@ -553,26 +590,26 @@ gsk_vulkan_render_prepare_descriptor_sets (GskVulkanRender *self)
&(VkDescriptorSetAllocateInfo) {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
.descriptorPool = self->descriptor_pool,
.descriptorSetCount = 1,
.pSetLayouts = &self->descriptor_set_layout,
.descriptorSetCount = N_DESCRIPTOR_SETS,
.pSetLayouts = self->descriptor_set_layouts,
.pNext = &(VkDescriptorSetVariableDescriptorCountAllocateInfo) {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO,
.descriptorSetCount = 1,
.pDescriptorCounts = (uint32_t[1]) {
gsk_descriptor_image_infos_get_size (&self->descriptor_images)
+ gsk_descriptor_image_infos_get_size (&self->descriptor_samplers)
+ gsk_descriptor_buffer_infos_get_size (&self->descriptor_buffers)
.descriptorSetCount = N_DESCRIPTOR_SETS,
.pDescriptorCounts = (uint32_t[N_DESCRIPTOR_SETS]) {
MAX (1, gsk_descriptor_image_infos_get_size (&self->descriptor_images)),
MAX (1, gsk_descriptor_image_infos_get_size (&self->descriptor_samplers)),
MAX (1, gsk_descriptor_buffer_infos_get_size (&self->descriptor_buffers))
}
}
},
&self->descriptor_set);
self->descriptor_sets);
n_descriptor_sets = 0;
if (gsk_descriptor_image_infos_get_size (&self->descriptor_images) > 0)
{
descriptor_sets[n_descriptor_sets++] = (VkWriteDescriptorSet) {
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
.dstSet = self->descriptor_set,
.dstSet = self->descriptor_sets[0],
.dstBinding = 0,
.dstArrayElement = 0,
.descriptorCount = gsk_descriptor_image_infos_get_size (&self->descriptor_images),
@@ -584,8 +621,8 @@ gsk_vulkan_render_prepare_descriptor_sets (GskVulkanRender *self)
{
descriptor_sets[n_descriptor_sets++] = (VkWriteDescriptorSet) {
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
.dstSet = self->descriptor_set,
.dstBinding = 1,
.dstSet = self->descriptor_sets[1],
.dstBinding = 0,
.dstArrayElement = 0,
.descriptorCount = gsk_descriptor_image_infos_get_size (&self->descriptor_samplers),
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER,
@@ -596,8 +633,8 @@ gsk_vulkan_render_prepare_descriptor_sets (GskVulkanRender *self)
{
descriptor_sets[n_descriptor_sets++] = (VkWriteDescriptorSet) {
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
.dstSet = self->descriptor_set,
.dstBinding = 2,
.dstSet = self->descriptor_sets[2],
.dstBinding = 0,
.dstArrayElement = 0,
.descriptorCount = gsk_descriptor_buffer_infos_get_size (&self->descriptor_buffers),
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
@@ -741,9 +778,10 @@ gsk_vulkan_render_free (GskVulkanRender *self)
gsk_descriptor_image_infos_clear (&self->descriptor_samplers);
gsk_descriptor_buffer_infos_clear (&self->descriptor_buffers);
vkDestroyDescriptorSetLayout (device,
self->descriptor_set_layout,
NULL);
for (i = 0; i < N_DESCRIPTOR_SETS; i++)
vkDestroyDescriptorSetLayout (device,
self->descriptor_set_layouts[i],
NULL);
vkDestroyFence (device,
self->fence,

View File

@@ -14,8 +14,9 @@
#include "gdk/gdkdisplayprivate.h"
#include "gdk/gdkdrawcontextprivate.h"
#include "gdk/gdktextureprivate.h"
#include "gdk/gdkprofilerprivate.h"
#include "gdk/gdktextureprivate.h"
#include "gdk/gdkvulkancontextprivate.h"
#include <graphene.h>
@@ -286,7 +287,8 @@ gsk_vulkan_renderer_render_texture (GskRenderer *renderer,
ceil (viewport->size.width),
ceil (viewport->size.height));
image = gsk_vulkan_image_new_for_offscreen (self->vulkan,
gsk_render_node_get_preferred_vulkan_format (root),
gdk_vulkan_context_get_offscreen_format (self->vulkan,
gsk_render_node_get_preferred_depth (root)),
rounded_viewport.size.width,
rounded_viewport.size.height);

View File

@@ -26,6 +26,8 @@
#include "gskvulkanrendererprivate.h"
#include "gskprivate.h"
#include "gdk/gdkvulkancontextprivate.h"
#define ORTHO_NEAR_PLANE -10000
#define ORTHO_FAR_PLANE 10000
@@ -1275,7 +1277,8 @@ gsk_vulkan_render_pass_render_offscreen (GdkVulkanContext *vulkan,
ceil (scale_y * viewport->size.height));
result = gsk_vulkan_image_new_for_offscreen (vulkan,
gsk_render_node_get_preferred_vulkan_format (node),
gdk_vulkan_context_get_offscreen_format (vulkan,
gsk_render_node_get_preferred_depth (node)),
view.size.width, view.size.height);
#ifdef G_ENABLE_DEBUG
@@ -2436,7 +2439,6 @@ gsk_vulkan_render_pass_draw (GskVulkanRenderPass *self,
VkPipelineLayout pipeline_layout,
VkCommandBuffer command_buffer)
{
VkDescriptorSet descriptor_set;
cairo_rectangle_int_t rect;
vkCmdSetViewport (command_buffer,
@@ -2469,16 +2471,7 @@ gsk_vulkan_render_pass_draw (GskVulkanRenderPass *self,
},
VK_SUBPASS_CONTENTS_INLINE);
descriptor_set = gsk_vulkan_render_get_descriptor_set (render);
if (descriptor_set)
vkCmdBindDescriptorSets (command_buffer,
VK_PIPELINE_BIND_POINT_GRAPHICS,
pipeline_layout,
0,
1,
&descriptor_set,
0,
NULL);
gsk_vulkan_render_bind_descriptor_sets (render, command_buffer);
gsk_vulkan_render_pass_draw_rect (self, render, pipeline_layout, command_buffer);

View File

@@ -93,7 +93,8 @@ guchar * gsk_vulkan_render_get_buffer_memory (GskVulk
gsize size,
gsize alignment,
gsize *out_offset);
VkDescriptorSet gsk_vulkan_render_get_descriptor_set (GskVulkanRender *self);
void gsk_vulkan_render_bind_descriptor_sets (GskVulkanRender *self,
VkCommandBuffer command_buffer);
void gsk_vulkan_render_draw (GskVulkanRender *self);

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,6 +1,6 @@
layout(set = 0, binding = 0) uniform texture2D textures[50000];
layout(set = 0, binding = 1) uniform sampler samplers[50000];
layout(set = 0, binding = 2) readonly buffer FloatBuffers {
layout(set = 1, binding = 0) uniform sampler samplers[50000];
layout(set = 2, binding = 0) readonly buffer FloatBuffers {
float floats[];
} buffers[50000];

Binary file not shown.

View File

@@ -3,11 +3,6 @@
#include "common.vert.glsl"
#include "rect.vert.glsl"
struct ColorStop {
float offset;
vec4 color;
};
layout(location = 0) in vec4 inRect;
layout(location = 1) in vec2 inStart;
layout(location = 2) in vec2 inEnd;

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -50,7 +50,8 @@ translate_coordinates_to_widget (GtkWidget *widget,
switch (coordtype)
{
case ATSPI_COORD_TYPE_SCREEN:
g_warning ("Screen coordinates not supported, reported positions will be wrong");
*xo = 0;
*yo = 0;
return;
case ATSPI_COORD_TYPE_WINDOW:
@@ -86,7 +87,6 @@ translate_coordinates_from_widget (GtkWidget *widget,
switch (coordtype)
{
case ATSPI_COORD_TYPE_SCREEN:
g_warning ("Screen coordinates not supported, reported positions will be wrong");
*xo = 0;
*yo = 0;
return;

View File

@@ -144,7 +144,7 @@ collect_states (GtkAtSpiContext *self,
set_atspi_state (&states, ATSPI_STATE_VISIBLE);
set_atspi_state (&states, ATSPI_STATE_SHOWING);
if (ctx->accessible_role == GTK_ACCESSIBLE_ROLE_WINDOW)
if (ctx->accessible_role == GTK_ACCESSIBLE_ROLE_APPLICATION)
{
if (gtk_accessible_get_platform_state (accessible, GTK_ACCESSIBLE_PLATFORM_STATE_ACTIVE))
set_atspi_state (&states, ATSPI_STATE_ACTIVE);
@@ -1170,7 +1170,7 @@ gtk_at_spi_context_platform_change (GtkATContext *ctx,
/* Orca tracks the window:activate and window:deactivate events on top
* levels to decide whether to track other AT-SPI events
*/
if (gtk_accessible_get_accessible_role (accessible) == GTK_ACCESSIBLE_ROLE_WINDOW)
if (gtk_accessible_get_accessible_role (accessible) == GTK_ACCESSIBLE_ROLE_APPLICATION)
{
if (state)
emit_window_event (self, "activate");

View File

@@ -1003,13 +1003,13 @@ gtk_atspi_get_selection_vtable (GtkAccessible *accessible,
return NULL;
}
/* {{{ GtkListView notification */
typedef struct {
GtkAtspiSelectionCallback *changed;
gpointer data;
} SelectionChanged;
/* {{{ GtkListView notification */
typedef struct {
GtkSelectionModel *model;
GtkAtspiSelectionCallback *changed;
@@ -1048,6 +1048,47 @@ model_changed (GtkListBase *list,
update_model (data, gtk_list_base_get_model (list));
}
/* }}} */
/* {{{ Stackswitcher notification */
typedef struct {
GtkStack *stack;
GtkAtspiSelectionCallback *changed;
gpointer data;
} StackSwitcherData;
static void
update_stack (StackSwitcherData *data,
GtkStack *stack)
{
if (data->stack)
g_signal_handlers_disconnect_by_func (data->stack, data->changed, data->data);
g_set_object (&data->stack, stack);
if (data->stack)
g_signal_connect_swapped (data->stack, "notify::visible-child", G_CALLBACK (data->changed), data->data);
}
static void
stack_switcher_data_free (gpointer user_data)
{
StackSwitcherData *data = user_data;
update_stack (data, NULL);
g_free (data);
}
static void
stack_changed (GtkStackSwitcher *self,
GParamSpec *pspec,
gpointer unused)
{
StackSwitcherData *data;
data = (StackSwitcherData *) g_object_get_data (G_OBJECT (self), "accessible-selection-data");
update_stack (data, gtk_stack_switcher_get_stack (self));
}
/* }}} */
void
@@ -1059,7 +1100,7 @@ gtk_atspi_connect_selection_signals (GtkAccessible *accessible,
{
SelectionChanged *changed;
changed = g_new (SelectionChanged, 1);
changed = g_new0 (SelectionChanged, 1);
changed->changed = selection_changed;
changed->data = data;
@@ -1071,7 +1112,7 @@ gtk_atspi_connect_selection_signals (GtkAccessible *accessible,
{
SelectionChanged *changed;
changed = g_new (SelectionChanged, 1);
changed = g_new0 (SelectionChanged, 1);
changed->changed = selection_changed;
changed->data = data;
@@ -1083,7 +1124,7 @@ gtk_atspi_connect_selection_signals (GtkAccessible *accessible,
{
SelectionChanged *changed;
changed = g_new (SelectionChanged, 1);
changed = g_new0 (SelectionChanged, 1);
changed->changed = selection_changed;
changed->data = data;
@@ -1093,22 +1134,23 @@ gtk_atspi_connect_selection_signals (GtkAccessible *accessible,
}
else if (GTK_IS_STACK_SWITCHER (accessible))
{
SelectionChanged *changed;
StackSwitcherData *changed;
changed = g_new (SelectionChanged, 1);
changed = g_new0 (StackSwitcherData, 1);
changed->changed = selection_changed;
changed->data = data;
g_object_set_data_full (G_OBJECT (accessible), "accessible-selection-data", changed, g_free);
g_object_set_data_full (G_OBJECT (accessible), "accessible-selection-data", changed, stack_switcher_data_free);
g_signal_connect_swapped (accessible, "notify::visible-child", G_CALLBACK (selection_changed), data);
g_signal_connect (accessible, "notify::stack", G_CALLBACK (stack_changed), NULL);
stack_changed (GTK_STACK_SWITCHER (accessible), NULL, NULL);
}
else if (IS_NOTEBOOK_TAB_LIST (accessible, GTK_AT_CONTEXT (data)->accessible_role))
{
GtkWidget *notebook = gtk_widget_get_parent (gtk_widget_get_parent (GTK_WIDGET (accessible)));
SelectionChanged *changed;
changed = g_new (SelectionChanged, 1);
changed = g_new0 (SelectionChanged, 1);
changed->changed = selection_changed;
changed->data = data;
@@ -1137,8 +1179,7 @@ gtk_atspi_disconnect_selection_signals (GtkAccessible *accessible)
{
if (GTK_IS_LIST_BOX (accessible) ||
GTK_IS_FLOW_BOX (accessible) ||
GTK_IS_COMBO_BOX (accessible) ||
GTK_IS_STACK_SWITCHER (accessible))
GTK_IS_COMBO_BOX (accessible))
{
SelectionChanged *changed;
@@ -1148,6 +1189,12 @@ gtk_atspi_disconnect_selection_signals (GtkAccessible *accessible)
g_signal_handlers_disconnect_by_func (accessible, changed->changed, changed->data);
g_object_set_data (G_OBJECT (accessible), "accessible-selection-data", NULL);
}
else if (GTK_IS_STACK_SWITCHER (accessible))
{
g_signal_handlers_disconnect_by_func (accessible, stack_changed, NULL);
g_object_set_data (G_OBJECT (accessible), "accessible-selection-data", NULL);
}
else if (IS_NOTEBOOK_TAB_LIST (accessible, gtk_accessible_get_accessible_role (accessible)))

View File

@@ -45,6 +45,9 @@ gtk_accessible_role_to_atspi_role (GtkAccessibleRole role)
case GTK_ACCESSIBLE_ROLE_ALERT_DIALOG:
return ATSPI_ROLE_ALERT;
case GTK_ACCESSIBLE_ROLE_APPLICATION:
return ATSPI_ROLE_FRAME;
case GTK_ACCESSIBLE_ROLE_BANNER:
break;
@@ -85,7 +88,7 @@ gtk_accessible_role_to_atspi_role (GtkAccessibleRole role)
return ATSPI_ROLE_FORM;
case GTK_ACCESSIBLE_ROLE_GENERIC:
break;
return ATSPI_ROLE_FILLER;
case GTK_ACCESSIBLE_ROLE_GRID:
return ATSPI_ROLE_TABLE;
@@ -169,7 +172,7 @@ gtk_accessible_role_to_atspi_role (GtkAccessibleRole role)
return ATSPI_ROLE_OPTION_PANE;
case GTK_ACCESSIBLE_ROLE_PRESENTATION:
return ATSPI_ROLE_FILLER;
return ATSPI_ROLE_INVALID;
case GTK_ACCESSIBLE_ROLE_PROGRESS_BAR:
return ATSPI_ROLE_PROGRESS_BAR;
@@ -275,6 +278,7 @@ gtk_accessible_role_to_atspi_role (GtkAccessibleRole role)
case GTK_ACCESSIBLE_ROLE_TOGGLE_BUTTON:
return ATSPI_ROLE_TOGGLE_BUTTON;
default:
break;
}

View File

@@ -197,9 +197,8 @@ struct _GtkAboutDialog
GtkLicense license_type;
guint hovering_over_link : 1;
guint wrap_license : 1;
guint in_child_changed : 1;
bool hovering_over_link;
bool wrap_license;
};
struct _GtkAboutDialogClass
@@ -724,8 +723,8 @@ gtk_about_dialog_init (GtkAboutDialog *about)
about->documenters = NULL;
about->artists = NULL;
about->hovering_over_link = FALSE;
about->wrap_license = FALSE;
about->hovering_over_link = false;
about->wrap_license = false;
about->license_type = GTK_LICENSE_UNKNOWN;
@@ -1305,11 +1304,11 @@ gtk_about_dialog_set_wrap_license (GtkAboutDialog *about,
{
g_return_if_fail (GTK_IS_ABOUT_DIALOG (about));
wrap_license = wrap_license != FALSE;
bool wrap = !!wrap_license;
if (about->wrap_license != wrap_license)
if (about->wrap_license != wrap)
{
about->wrap_license = wrap_license;
about->wrap_license = wrap;
g_object_notify_by_pspec (G_OBJECT (about), props[PROP_WRAP_LICENSE]);
}
@@ -1780,7 +1779,7 @@ set_cursor_if_appropriate (GtkAboutDialog *about,
{
GSList *tags = NULL, *tagp = NULL;
GtkTextIter iter;
gboolean hovering_over_link = FALSE;
bool hovering_over_link = false;
gtk_text_view_get_iter_at_location (text_view, &iter, x, y);
@@ -1792,7 +1791,7 @@ set_cursor_if_appropriate (GtkAboutDialog *about,
if (uri != NULL)
{
hovering_over_link = TRUE;
hovering_over_link = true;
break;
}
}
@@ -2273,7 +2272,7 @@ gtk_about_dialog_set_license_type (GtkAboutDialog *about,
g_free (about->license);
about->license = g_string_free (str, FALSE);
about->wrap_license = TRUE;
about->wrap_license = true;
license_string = g_strdup_printf ("<span size=\"small\">%s</span>",
about->license);

View File

@@ -831,6 +831,7 @@ static const char *role_names[] = {
[GTK_ACCESSIBLE_ROLE_WIDGET] = NC_("accessibility", "widget"),
[GTK_ACCESSIBLE_ROLE_WINDOW] = NC_("accessibility", "window"),
[GTK_ACCESSIBLE_ROLE_TOGGLE_BUTTON] = NC_("accessibility", "toggle button"),
[GTK_ACCESSIBLE_ROLE_APPLICATION] = NC_("accessibility", "application"),
};
/*< private >
@@ -854,6 +855,113 @@ gtk_accessible_role_to_name (GtkAccessibleRole role,
return role_names[role];
}
static struct {
GtkAccessibleRole superclass;
GtkAccessibleRole role;
} superclasses[] = {
{ GTK_ACCESSIBLE_ROLE_COMMAND, GTK_ACCESSIBLE_ROLE_BUTTON },
{ GTK_ACCESSIBLE_ROLE_COMMAND, GTK_ACCESSIBLE_ROLE_LINK },
{ GTK_ACCESSIBLE_ROLE_COMMAND, GTK_ACCESSIBLE_ROLE_MENU_ITEM },
{ GTK_ACCESSIBLE_ROLE_COMPOSITE, GTK_ACCESSIBLE_ROLE_GRID },
{ GTK_ACCESSIBLE_ROLE_COMPOSITE, GTK_ACCESSIBLE_ROLE_SELECT },
{ GTK_ACCESSIBLE_ROLE_COMPOSITE, GTK_ACCESSIBLE_ROLE_SPIN_BUTTON },
{ GTK_ACCESSIBLE_ROLE_COMPOSITE, GTK_ACCESSIBLE_ROLE_TAB_LIST },
{ GTK_ACCESSIBLE_ROLE_INPUT, GTK_ACCESSIBLE_ROLE_CHECKBOX },
{ GTK_ACCESSIBLE_ROLE_INPUT, GTK_ACCESSIBLE_ROLE_COMBO_BOX },
{ GTK_ACCESSIBLE_ROLE_INPUT, GTK_ACCESSIBLE_ROLE_OPTION },
{ GTK_ACCESSIBLE_ROLE_INPUT, GTK_ACCESSIBLE_ROLE_RADIO },
{ GTK_ACCESSIBLE_ROLE_INPUT, GTK_ACCESSIBLE_ROLE_SLIDER },
{ GTK_ACCESSIBLE_ROLE_INPUT, GTK_ACCESSIBLE_ROLE_SPIN_BUTTON },
{ GTK_ACCESSIBLE_ROLE_INPUT, GTK_ACCESSIBLE_ROLE_TEXT_BOX },
{ GTK_ACCESSIBLE_ROLE_LANDMARK, GTK_ACCESSIBLE_ROLE_BANNER },
{ GTK_ACCESSIBLE_ROLE_LANDMARK, GTK_ACCESSIBLE_ROLE_FORM },
{ GTK_ACCESSIBLE_ROLE_LANDMARK, GTK_ACCESSIBLE_ROLE_MAIN },
{ GTK_ACCESSIBLE_ROLE_LANDMARK, GTK_ACCESSIBLE_ROLE_NAVIGATION },
{ GTK_ACCESSIBLE_ROLE_LANDMARK, GTK_ACCESSIBLE_ROLE_REGION },
{ GTK_ACCESSIBLE_ROLE_LANDMARK, GTK_ACCESSIBLE_ROLE_SEARCH },
{ GTK_ACCESSIBLE_ROLE_RANGE, GTK_ACCESSIBLE_ROLE_METER },
{ GTK_ACCESSIBLE_ROLE_RANGE, GTK_ACCESSIBLE_ROLE_PROGRESS_BAR },
{ GTK_ACCESSIBLE_ROLE_RANGE, GTK_ACCESSIBLE_ROLE_SCROLLBAR },
{ GTK_ACCESSIBLE_ROLE_RANGE, GTK_ACCESSIBLE_ROLE_SLIDER },
{ GTK_ACCESSIBLE_ROLE_RANGE, GTK_ACCESSIBLE_ROLE_SPIN_BUTTON },
{ GTK_ACCESSIBLE_ROLE_SECTION, GTK_ACCESSIBLE_ROLE_ALERT },
{ GTK_ACCESSIBLE_ROLE_SECTION, GTK_ACCESSIBLE_ROLE_CAPTION },
{ GTK_ACCESSIBLE_ROLE_SECTION, GTK_ACCESSIBLE_ROLE_CELL },
{ GTK_ACCESSIBLE_ROLE_SECTION, GTK_ACCESSIBLE_ROLE_GROUP },
{ GTK_ACCESSIBLE_ROLE_SECTION, GTK_ACCESSIBLE_ROLE_IMG },
{ GTK_ACCESSIBLE_ROLE_SECTION, GTK_ACCESSIBLE_ROLE_LANDMARK },
{ GTK_ACCESSIBLE_ROLE_SECTION, GTK_ACCESSIBLE_ROLE_LIST },
{ GTK_ACCESSIBLE_ROLE_SECTION, GTK_ACCESSIBLE_ROLE_LIST_ITEM },
{ GTK_ACCESSIBLE_ROLE_SECTION, GTK_ACCESSIBLE_ROLE_LOG },
{ GTK_ACCESSIBLE_ROLE_SECTION, GTK_ACCESSIBLE_ROLE_MARQUEE },
{ GTK_ACCESSIBLE_ROLE_SECTION, GTK_ACCESSIBLE_ROLE_MATH },
{ GTK_ACCESSIBLE_ROLE_SECTION, GTK_ACCESSIBLE_ROLE_NOTE },
{ GTK_ACCESSIBLE_ROLE_SECTION, GTK_ACCESSIBLE_ROLE_STATUS },
{ GTK_ACCESSIBLE_ROLE_SECTION, GTK_ACCESSIBLE_ROLE_TABLE },
{ GTK_ACCESSIBLE_ROLE_SECTION, GTK_ACCESSIBLE_ROLE_TAB_PANEL },
{ GTK_ACCESSIBLE_ROLE_SECTION, GTK_ACCESSIBLE_ROLE_TIME },
{ GTK_ACCESSIBLE_ROLE_SECTION, GTK_ACCESSIBLE_ROLE_TOOLTIP },
{ GTK_ACCESSIBLE_ROLE_SECTION_HEAD, GTK_ACCESSIBLE_ROLE_COLUMN_HEADER },
{ GTK_ACCESSIBLE_ROLE_SECTION_HEAD, GTK_ACCESSIBLE_ROLE_HEADING },
{ GTK_ACCESSIBLE_ROLE_SECTION_HEAD, GTK_ACCESSIBLE_ROLE_ROW_HEADER },
{ GTK_ACCESSIBLE_ROLE_SECTION_HEAD, GTK_ACCESSIBLE_ROLE_TAB },
{ GTK_ACCESSIBLE_ROLE_SELECT, GTK_ACCESSIBLE_ROLE_LIST_BOX },
{ GTK_ACCESSIBLE_ROLE_SELECT, GTK_ACCESSIBLE_ROLE_MENU },
{ GTK_ACCESSIBLE_ROLE_SELECT, GTK_ACCESSIBLE_ROLE_RADIO_GROUP },
{ GTK_ACCESSIBLE_ROLE_SELECT, GTK_ACCESSIBLE_ROLE_TREE },
{ GTK_ACCESSIBLE_ROLE_STRUCTURE, GTK_ACCESSIBLE_ROLE_APPLICATION },
{ GTK_ACCESSIBLE_ROLE_STRUCTURE, GTK_ACCESSIBLE_ROLE_DOCUMENT },
{ GTK_ACCESSIBLE_ROLE_STRUCTURE, GTK_ACCESSIBLE_ROLE_GENERIC },
{ GTK_ACCESSIBLE_ROLE_STRUCTURE, GTK_ACCESSIBLE_ROLE_PRESENTATION },
{ GTK_ACCESSIBLE_ROLE_STRUCTURE, GTK_ACCESSIBLE_ROLE_RANGE },
{ GTK_ACCESSIBLE_ROLE_STRUCTURE, GTK_ACCESSIBLE_ROLE_ROW_GROUP },
{ GTK_ACCESSIBLE_ROLE_STRUCTURE, GTK_ACCESSIBLE_ROLE_SECTION },
{ GTK_ACCESSIBLE_ROLE_STRUCTURE, GTK_ACCESSIBLE_ROLE_SECTION_HEAD },
{ GTK_ACCESSIBLE_ROLE_STRUCTURE, GTK_ACCESSIBLE_ROLE_SEPARATOR },
{ GTK_ACCESSIBLE_ROLE_WIDGET, GTK_ACCESSIBLE_ROLE_COMMAND },
{ GTK_ACCESSIBLE_ROLE_WIDGET, GTK_ACCESSIBLE_ROLE_COMPOSITE },
{ GTK_ACCESSIBLE_ROLE_WIDGET, GTK_ACCESSIBLE_ROLE_GRID_CELL },
{ GTK_ACCESSIBLE_ROLE_WIDGET, GTK_ACCESSIBLE_ROLE_INPUT },
{ GTK_ACCESSIBLE_ROLE_WIDGET, GTK_ACCESSIBLE_ROLE_PROGRESS_BAR },
{ GTK_ACCESSIBLE_ROLE_WIDGET, GTK_ACCESSIBLE_ROLE_ROW },
{ GTK_ACCESSIBLE_ROLE_WIDGET, GTK_ACCESSIBLE_ROLE_SCROLLBAR },
{ GTK_ACCESSIBLE_ROLE_WIDGET, GTK_ACCESSIBLE_ROLE_SEPARATOR },
{ GTK_ACCESSIBLE_ROLE_WIDGET, GTK_ACCESSIBLE_ROLE_TAB },
{ GTK_ACCESSIBLE_ROLE_WINDOW, GTK_ACCESSIBLE_ROLE_DIALOG },
{ GTK_ACCESSIBLE_ROLE_CHECKBOX, GTK_ACCESSIBLE_ROLE_SWITCH },
{ GTK_ACCESSIBLE_ROLE_GRID_CELL, GTK_ACCESSIBLE_ROLE_COLUMN_HEADER },
{ GTK_ACCESSIBLE_ROLE_GRID_CELL, GTK_ACCESSIBLE_ROLE_ROW_HEADER },
{ GTK_ACCESSIBLE_ROLE_MENU_ITEM, GTK_ACCESSIBLE_ROLE_MENU_ITEM_CHECKBOX },
{ GTK_ACCESSIBLE_ROLE_MENU_ITEM_CHECKBOX, GTK_ACCESSIBLE_ROLE_MENU_ITEM_RADIO },
{ GTK_ACCESSIBLE_ROLE_TREE, GTK_ACCESSIBLE_ROLE_TREE_GRID },
{ GTK_ACCESSIBLE_ROLE_CELL, GTK_ACCESSIBLE_ROLE_COLUMN_HEADER },
{ GTK_ACCESSIBLE_ROLE_CELL, GTK_ACCESSIBLE_ROLE_GRID_CELL },
{ GTK_ACCESSIBLE_ROLE_CELL, GTK_ACCESSIBLE_ROLE_ROW_HEADER },
{ GTK_ACCESSIBLE_ROLE_GROUP, GTK_ACCESSIBLE_ROLE_ROW },
{ GTK_ACCESSIBLE_ROLE_GROUP, GTK_ACCESSIBLE_ROLE_SELECT },
{ GTK_ACCESSIBLE_ROLE_GROUP, GTK_ACCESSIBLE_ROLE_TOOLBAR },
{ GTK_ACCESSIBLE_ROLE_LIST, GTK_ACCESSIBLE_ROLE_FEED },
{ GTK_ACCESSIBLE_ROLE_LIST_ITEM, GTK_ACCESSIBLE_ROLE_TREE_ITEM },
{ GTK_ACCESSIBLE_ROLE_TABLE, GTK_ACCESSIBLE_ROLE_GRID },
{ GTK_ACCESSIBLE_ROLE_ALERT, GTK_ACCESSIBLE_ROLE_ALERT_DIALOG },
{ GTK_ACCESSIBLE_ROLE_STATUS, GTK_ACCESSIBLE_ROLE_TIMER },
{ GTK_ACCESSIBLE_ROLE_DIALOG, GTK_ACCESSIBLE_ROLE_ALERT_DIALOG },
};
gboolean
gtk_accessible_role_is_subclass (GtkAccessibleRole role,
GtkAccessibleRole superclass)
{
for (unsigned int i = 0; i < G_N_ELEMENTS (superclasses); i++)
{
if (superclasses[i].role == role &&
superclasses[i].superclass == superclass)
return TRUE;
}
return FALSE;
}
/*< private >
* gtk_accessible_role_is_range_subclass:
* @role: a `GtkAccessibleRole`
@@ -866,19 +974,38 @@ gtk_accessible_role_to_name (GtkAccessibleRole role,
gboolean
gtk_accessible_role_is_range_subclass (GtkAccessibleRole role)
{
/* Same trick as in gtkatcontext.c */
return gtk_accessible_role_is_subclass (role, GTK_ACCESSIBLE_ROLE_RANGE);
}
/* < private >
* gtk_accessible_role_is_abstract:
* @role: a `GtkAccessibleRole`
*
* Checks if @role is considered abstract and should not be used
* for concrete widgets.
*
* Returns: whether the role is abstract
*/
gboolean
gtk_accessible_role_is_abstract (GtkAccessibleRole role)
{
switch ((int) role)
{
case GTK_ACCESSIBLE_ROLE_METER:
case GTK_ACCESSIBLE_ROLE_PROGRESS_BAR:
case GTK_ACCESSIBLE_ROLE_SCROLLBAR:
case GTK_ACCESSIBLE_ROLE_SLIDER:
case GTK_ACCESSIBLE_ROLE_SPIN_BUTTON:
case GTK_ACCESSIBLE_ROLE_COMMAND:
case GTK_ACCESSIBLE_ROLE_COMPOSITE:
case GTK_ACCESSIBLE_ROLE_INPUT:
case GTK_ACCESSIBLE_ROLE_LANDMARK:
case GTK_ACCESSIBLE_ROLE_RANGE:
case GTK_ACCESSIBLE_ROLE_SECTION:
case GTK_ACCESSIBLE_ROLE_SECTION_HEAD:
case GTK_ACCESSIBLE_ROLE_SELECT:
case GTK_ACCESSIBLE_ROLE_STRUCTURE:
case GTK_ACCESSIBLE_ROLE_WIDGET:
case GTK_ACCESSIBLE_ROLE_WINDOW:
return TRUE;
default:
break;
return FALSE;
}
return FALSE;
}
/*< private >

View File

@@ -55,7 +55,41 @@ typedef enum {
const char * gtk_accessible_role_to_name (GtkAccessibleRole role,
const char *domain);
gboolean gtk_accessible_role_is_range_subclass (GtkAccessibleRole role);
gboolean gtk_accessible_role_is_range_subclass (GtkAccessibleRole role);
gboolean gtk_accessible_role_is_subclass (GtkAccessibleRole role,
GtkAccessibleRole superclass);
gboolean gtk_accessible_role_is_abstract (GtkAccessibleRole role);
/* < private >
* GtkAccessibleNaming:
* @GTK_ACCESSIBLE_NAME_ALLOWED:
* The role allows an accessible name and description
* @GTK_ACCESSIBLE_NAME_PROHIBITED:
* The role does not allow an accessible name and descirption
* @GTK_ACCESSIBLE_NAME_REQUIRED:
* The role requires an accessible name and description
* @GTK_ACCESSIBLE_NAME_RECOMMENDED:
* It is recommended to set the label property or labelled-by relation
* for this role
* @GTK_ACCESSIBLE_NAME_NOT_RECOMMENDED:
* It is recommended not to set the label property or labelled-by relation
* for this role
*
* Information about naming requirements for accessible roles.
*/
typedef enum {
GTK_ACCESSIBLE_NAME_ALLOWED,
GTK_ACCESSIBLE_NAME_PROHIBITED,
GTK_ACCESSIBLE_NAME_REQUIRED,
GTK_ACCESSIBLE_NAME_RECOMMENDED,
GTK_ACCESSIBLE_NAME_NOT_RECOMMENDED,
} GtkAccessibleNaming;
gboolean gtk_accessible_role_supports_name_from_author (GtkAccessibleRole role);
gboolean gtk_accessible_role_supports_name_from_content (GtkAccessibleRole role);
GtkAccessibleNaming gtk_accessible_role_get_naming (GtkAccessibleRole role);
gboolean gtk_accessible_should_present (GtkAccessible *self);

View File

@@ -38,6 +38,13 @@
* # CSS nodes
*
* `GtkAspectFrame` uses a CSS node with name `frame`.
*
* # Accessibility
*
* Until GTK 4.10, `GtkAspectFrame` used the `GTK_ACCESSIBLE_ROLE_GROUP` role.
*
* Starting from GTK 4.12, `GtkAspectFrame` uses the `GTK_ACCESSIBLE_ROLE_GENERIC` role.
*/
#include "config.h"
@@ -187,7 +194,7 @@ gtk_aspect_frame_class_init (GtkAspectFrameClass *class)
GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
gtk_widget_class_set_css_name (GTK_WIDGET_CLASS (class), I_("aspectframe"));
gtk_widget_class_set_accessible_role (GTK_WIDGET_CLASS (class), GTK_ACCESSIBLE_ROLE_GROUP);
gtk_widget_class_set_accessible_role (GTK_WIDGET_CLASS (class), GTK_ACCESSIBLE_ROLE_GENERIC);
}
static void

View File

@@ -46,6 +46,8 @@
#include "gtkdropdown.h"
#include "gtkcolordialogbutton.h"
#include "gtkfontdialogbutton.h"
#include "gtkscalebutton.h"
#include "print/gtkprinteroptionwidgetprivate.h"
#if defined(GDK_WINDOWING_X11) || defined(GDK_WINDOWING_WAYLAND)
#include "a11y/gtkatspicontextprivate.h"
@@ -120,10 +122,7 @@ gtk_at_context_set_property (GObject *gobject,
switch (prop_id)
{
case PROP_ACCESSIBLE_ROLE:
if (!self->realized)
self->accessible_role = g_value_get_enum (value);
else
g_critical ("The accessible role cannot be set on a realized AT context");
gtk_at_context_set_accessible_role (self, g_value_get_enum (value));
break;
case PROP_ACCESSIBLE:
@@ -1009,180 +1008,148 @@ gtk_at_context_get_accessible_relation (GtkATContext *self,
return gtk_accessible_attribute_set_get_value (self->relations, relation);
}
/* See the WAI-ARIA § 4.3, "Accessible Name and Description Computation" */
static void
gtk_at_context_get_name_accumulate (GtkATContext *self,
GPtrArray *names,
gboolean recurse)
{
GtkAccessibleValue *value = NULL;
/* See ARIA 5.2.8.4, 5.2.8.5 and 5.2.8.6 for the prohibited, from author
* and from content parts, and the table in
* https://www.w3.org/WAI/ARIA/apg/practices/names-and-descriptions/
* for the recommended / not recommended parts. We've made a few changes
* to the recommendations:
* - We don't recommend against labelling listitems, sincd GtkListView
* will put the focus on listitems sometimes.
* - We don't recommend tab lists being labelled, since GtkNotebook does
* not have a practical way of doing that.
*/
if (gtk_accessible_attribute_set_contains (self->properties, GTK_ACCESSIBLE_PROPERTY_LABEL))
{
value = gtk_accessible_attribute_set_get_value (self->properties, GTK_ACCESSIBLE_PROPERTY_LABEL);
#define NAME_FROM_AUTHOR (1 << 6)
#define NAME_FROM_CONTENT (1 << 7)
g_ptr_array_add (names, (char *) gtk_string_accessible_value_get (value));
}
if (recurse && gtk_accessible_attribute_set_contains (self->relations, GTK_ACCESSIBLE_RELATION_LABELLED_BY))
{
value = gtk_accessible_attribute_set_get_value (self->relations, GTK_ACCESSIBLE_RELATION_LABELLED_BY);
GList *list = gtk_reference_list_accessible_value_get (value);
for (GList *l = list; l != NULL; l = l->next)
{
GtkAccessible *rel = GTK_ACCESSIBLE (l->data);
GtkATContext *rel_context = gtk_accessible_get_at_context (rel);
gtk_at_context_get_name_accumulate (rel_context, names, FALSE);
g_object_unref (rel_context);
}
}
GtkAccessibleRole role = gtk_at_context_get_accessible_role (self);
switch ((int) role)
{
case GTK_ACCESSIBLE_ROLE_RANGE:
{
int range_attrs[] = {
GTK_ACCESSIBLE_PROPERTY_VALUE_TEXT,
GTK_ACCESSIBLE_PROPERTY_VALUE_NOW,
};
value = NULL;
for (int i = 0; i < G_N_ELEMENTS (range_attrs); i++)
{
if (gtk_accessible_attribute_set_contains (self->properties, range_attrs[i]))
{
value = gtk_accessible_attribute_set_get_value (self->properties, range_attrs[i]);
break;
}
}
if (value != NULL)
g_ptr_array_add (names, (char *) gtk_string_accessible_value_get (value));
}
break;
default:
break;
}
/* If there is no label or labelled-by attribute, hidden elements
* have no name
*/
if (gtk_accessible_attribute_set_contains (self->states, GTK_ACCESSIBLE_STATE_HIDDEN))
{
value = gtk_accessible_attribute_set_get_value (self->states, GTK_ACCESSIBLE_STATE_HIDDEN);
if (gtk_boolean_accessible_value_get (value))
return;
}
if (names->len == 0)
{
if (GTK_IS_WIDGET (self->accessible))
{
const char *tooltip = gtk_widget_get_tooltip_text (GTK_WIDGET (self->accessible));
if (tooltip)
g_ptr_array_add (names, (char *) tooltip);
}
}
}
static void
gtk_at_context_get_description_accumulate (GtkATContext *self,
GPtrArray *labels,
gboolean recurse)
{
GtkAccessibleValue *value = NULL;
if (gtk_accessible_attribute_set_contains (self->properties, GTK_ACCESSIBLE_PROPERTY_DESCRIPTION))
{
value = gtk_accessible_attribute_set_get_value (self->properties, GTK_ACCESSIBLE_PROPERTY_DESCRIPTION);
g_ptr_array_add (labels, (char *) gtk_string_accessible_value_get (value));
}
if (recurse && gtk_accessible_attribute_set_contains (self->relations, GTK_ACCESSIBLE_RELATION_DESCRIBED_BY))
{
value = gtk_accessible_attribute_set_get_value (self->relations, GTK_ACCESSIBLE_RELATION_DESCRIBED_BY);
GList *list = gtk_reference_list_accessible_value_get (value);
for (GList *l = list; l != NULL; l = l->next)
{
GtkAccessible *rel = GTK_ACCESSIBLE (l->data);
GtkATContext *rel_context = gtk_accessible_get_at_context (rel);
gtk_at_context_get_description_accumulate (rel_context, labels, FALSE);
g_object_unref (rel_context);
}
}
GtkAccessibleRole role = gtk_at_context_get_accessible_role (self);
switch ((int) role)
{
case GTK_ACCESSIBLE_ROLE_RANGE:
{
int range_attrs[] = {
GTK_ACCESSIBLE_PROPERTY_VALUE_TEXT,
GTK_ACCESSIBLE_PROPERTY_VALUE_NOW,
};
value = NULL;
for (int i = 0; i < G_N_ELEMENTS (range_attrs); i++)
{
if (gtk_accessible_attribute_set_contains (self->properties, range_attrs[i]))
{
value = gtk_accessible_attribute_set_get_value (self->properties, range_attrs[i]);
break;
}
}
if (value != NULL)
g_ptr_array_add (labels, (char *) gtk_string_accessible_value_get (value));
}
break;
default:
break;
}
/* If there is no description or described-by attribute, hidden elements
* have no description
*/
if (gtk_accessible_attribute_set_contains (self->states, GTK_ACCESSIBLE_STATE_HIDDEN))
{
value = gtk_accessible_attribute_set_get_value (self->states, GTK_ACCESSIBLE_STATE_HIDDEN);
if (gtk_boolean_accessible_value_get (value))
return;
}
if (labels->len == 0)
{
if (GTK_IS_WIDGET (self->accessible))
{
const char *tooltip = gtk_widget_get_tooltip_text (GTK_WIDGET (self->accessible));
if (tooltip)
g_ptr_array_add (labels, (char *) tooltip);
}
}
}
static GtkAccessibleRole name_forbidden[] = {
GTK_ACCESSIBLE_ROLE_CAPTION,
GTK_ACCESSIBLE_ROLE_GENERIC,
GTK_ACCESSIBLE_ROLE_PRESENTATION,
GTK_ACCESSIBLE_ROLE_NONE,
static guint8 naming[] = {
[GTK_ACCESSIBLE_ROLE_ALERT] = NAME_FROM_AUTHOR,
[GTK_ACCESSIBLE_ROLE_ALERT_DIALOG] = NAME_FROM_AUTHOR|GTK_ACCESSIBLE_NAME_REQUIRED,
[GTK_ACCESSIBLE_ROLE_BANNER] = GTK_ACCESSIBLE_NAME_PROHIBITED,
[GTK_ACCESSIBLE_ROLE_BUTTON] = NAME_FROM_AUTHOR|NAME_FROM_CONTENT|GTK_ACCESSIBLE_NAME_REQUIRED,
[GTK_ACCESSIBLE_ROLE_CAPTION] = GTK_ACCESSIBLE_NAME_PROHIBITED,
[GTK_ACCESSIBLE_ROLE_CELL] = NAME_FROM_AUTHOR|NAME_FROM_CONTENT,
[GTK_ACCESSIBLE_ROLE_CHECKBOX] = NAME_FROM_AUTHOR|NAME_FROM_CONTENT|GTK_ACCESSIBLE_NAME_REQUIRED,
[GTK_ACCESSIBLE_ROLE_COLUMN_HEADER] = NAME_FROM_AUTHOR|NAME_FROM_CONTENT|GTK_ACCESSIBLE_NAME_REQUIRED,
[GTK_ACCESSIBLE_ROLE_COMBO_BOX] = NAME_FROM_AUTHOR|GTK_ACCESSIBLE_NAME_REQUIRED,
[GTK_ACCESSIBLE_ROLE_COMMAND] = GTK_ACCESSIBLE_NAME_PROHIBITED,
[GTK_ACCESSIBLE_ROLE_COMPOSITE] = GTK_ACCESSIBLE_NAME_PROHIBITED,
[GTK_ACCESSIBLE_ROLE_DIALOG] = NAME_FROM_AUTHOR|GTK_ACCESSIBLE_NAME_REQUIRED,
[GTK_ACCESSIBLE_ROLE_DOCUMENT] = NAME_FROM_AUTHOR,
[GTK_ACCESSIBLE_ROLE_FEED] = NAME_FROM_AUTHOR|GTK_ACCESSIBLE_NAME_RECOMMENDED,
[GTK_ACCESSIBLE_ROLE_FORM] = NAME_FROM_AUTHOR|GTK_ACCESSIBLE_NAME_REQUIRED,
[GTK_ACCESSIBLE_ROLE_GENERIC] = GTK_ACCESSIBLE_NAME_PROHIBITED,
[GTK_ACCESSIBLE_ROLE_GRID] = NAME_FROM_AUTHOR|GTK_ACCESSIBLE_NAME_REQUIRED,
[GTK_ACCESSIBLE_ROLE_GRID_CELL] = NAME_FROM_AUTHOR|NAME_FROM_CONTENT,
[GTK_ACCESSIBLE_ROLE_GROUP] = NAME_FROM_AUTHOR,
[GTK_ACCESSIBLE_ROLE_HEADING] = NAME_FROM_AUTHOR|NAME_FROM_CONTENT|GTK_ACCESSIBLE_NAME_REQUIRED,
[GTK_ACCESSIBLE_ROLE_IMG] = NAME_FROM_AUTHOR|GTK_ACCESSIBLE_NAME_REQUIRED,
[GTK_ACCESSIBLE_ROLE_INPUT] = GTK_ACCESSIBLE_NAME_PROHIBITED,
[GTK_ACCESSIBLE_ROLE_LABEL] = NAME_FROM_AUTHOR|NAME_FROM_CONTENT,
[GTK_ACCESSIBLE_ROLE_LANDMARK] = GTK_ACCESSIBLE_NAME_PROHIBITED,
[GTK_ACCESSIBLE_ROLE_LEGEND] = GTK_ACCESSIBLE_NAME_PROHIBITED,
[GTK_ACCESSIBLE_ROLE_LINK] = NAME_FROM_AUTHOR|NAME_FROM_CONTENT|GTK_ACCESSIBLE_NAME_REQUIRED,
[GTK_ACCESSIBLE_ROLE_LIST] = NAME_FROM_AUTHOR,
[GTK_ACCESSIBLE_ROLE_LIST_BOX] = NAME_FROM_AUTHOR|GTK_ACCESSIBLE_NAME_REQUIRED,
[GTK_ACCESSIBLE_ROLE_LIST_ITEM] = NAME_FROM_AUTHOR,
[GTK_ACCESSIBLE_ROLE_LOG] = NAME_FROM_AUTHOR,
[GTK_ACCESSIBLE_ROLE_MAIN] = NAME_FROM_AUTHOR,
[GTK_ACCESSIBLE_ROLE_MARQUEE] = NAME_FROM_AUTHOR,
[GTK_ACCESSIBLE_ROLE_MATH] = NAME_FROM_AUTHOR|GTK_ACCESSIBLE_NAME_RECOMMENDED,
[GTK_ACCESSIBLE_ROLE_METER] = NAME_FROM_AUTHOR|GTK_ACCESSIBLE_NAME_REQUIRED,
[GTK_ACCESSIBLE_ROLE_MENU] = NAME_FROM_AUTHOR|GTK_ACCESSIBLE_NAME_RECOMMENDED,
[GTK_ACCESSIBLE_ROLE_MENU_BAR] = NAME_FROM_AUTHOR|GTK_ACCESSIBLE_NAME_RECOMMENDED,
[GTK_ACCESSIBLE_ROLE_MENU_ITEM] = NAME_FROM_AUTHOR|NAME_FROM_CONTENT|GTK_ACCESSIBLE_NAME_REQUIRED,
[GTK_ACCESSIBLE_ROLE_MENU_ITEM_CHECKBOX] = NAME_FROM_AUTHOR|NAME_FROM_CONTENT|GTK_ACCESSIBLE_NAME_REQUIRED,
[GTK_ACCESSIBLE_ROLE_MENU_ITEM_RADIO] = NAME_FROM_AUTHOR|NAME_FROM_CONTENT|GTK_ACCESSIBLE_NAME_REQUIRED,
[GTK_ACCESSIBLE_ROLE_NAVIGATION] = NAME_FROM_AUTHOR|GTK_ACCESSIBLE_NAME_RECOMMENDED,
[GTK_ACCESSIBLE_ROLE_NONE] = GTK_ACCESSIBLE_NAME_PROHIBITED,
[GTK_ACCESSIBLE_ROLE_NOTE] = NAME_FROM_AUTHOR,
[GTK_ACCESSIBLE_ROLE_OPTION] = NAME_FROM_AUTHOR|NAME_FROM_CONTENT|GTK_ACCESSIBLE_NAME_REQUIRED,
[GTK_ACCESSIBLE_ROLE_PRESENTATION] = GTK_ACCESSIBLE_NAME_PROHIBITED,
[GTK_ACCESSIBLE_ROLE_PROGRESS_BAR] = NAME_FROM_AUTHOR|GTK_ACCESSIBLE_NAME_REQUIRED,
[GTK_ACCESSIBLE_ROLE_RADIO] = NAME_FROM_AUTHOR|NAME_FROM_CONTENT|GTK_ACCESSIBLE_NAME_REQUIRED,
[GTK_ACCESSIBLE_ROLE_RADIO_GROUP] = NAME_FROM_AUTHOR|GTK_ACCESSIBLE_NAME_REQUIRED,
[GTK_ACCESSIBLE_ROLE_RANGE] = GTK_ACCESSIBLE_NAME_PROHIBITED,
[GTK_ACCESSIBLE_ROLE_REGION] = NAME_FROM_AUTHOR|GTK_ACCESSIBLE_NAME_REQUIRED,
[GTK_ACCESSIBLE_ROLE_ROW] = NAME_FROM_AUTHOR|NAME_FROM_CONTENT,
[GTK_ACCESSIBLE_ROLE_ROW_GROUP] = NAME_FROM_AUTHOR|GTK_ACCESSIBLE_NAME_NOT_RECOMMENDED,
[GTK_ACCESSIBLE_ROLE_ROW_HEADER] = NAME_FROM_AUTHOR|NAME_FROM_CONTENT|GTK_ACCESSIBLE_NAME_REQUIRED,
[GTK_ACCESSIBLE_ROLE_SCROLLBAR] = NAME_FROM_AUTHOR,
[GTK_ACCESSIBLE_ROLE_SEARCH] = NAME_FROM_AUTHOR|GTK_ACCESSIBLE_NAME_RECOMMENDED,
[GTK_ACCESSIBLE_ROLE_SEARCH_BOX] = NAME_FROM_AUTHOR|GTK_ACCESSIBLE_NAME_REQUIRED,
[GTK_ACCESSIBLE_ROLE_SECTION] = GTK_ACCESSIBLE_NAME_PROHIBITED,
[GTK_ACCESSIBLE_ROLE_SECTION_HEAD] = GTK_ACCESSIBLE_NAME_PROHIBITED,
[GTK_ACCESSIBLE_ROLE_SELECT] = GTK_ACCESSIBLE_NAME_PROHIBITED,
[GTK_ACCESSIBLE_ROLE_SEPARATOR] = NAME_FROM_AUTHOR,
[GTK_ACCESSIBLE_ROLE_SLIDER] = NAME_FROM_AUTHOR|GTK_ACCESSIBLE_NAME_REQUIRED,
[GTK_ACCESSIBLE_ROLE_SPIN_BUTTON] = NAME_FROM_AUTHOR|GTK_ACCESSIBLE_NAME_REQUIRED,
[GTK_ACCESSIBLE_ROLE_STATUS] = GTK_ACCESSIBLE_NAME_PROHIBITED,
[GTK_ACCESSIBLE_ROLE_STRUCTURE] = GTK_ACCESSIBLE_NAME_PROHIBITED,
[GTK_ACCESSIBLE_ROLE_SWITCH] = NAME_FROM_AUTHOR|NAME_FROM_CONTENT|GTK_ACCESSIBLE_NAME_REQUIRED,
[GTK_ACCESSIBLE_ROLE_TAB] = NAME_FROM_AUTHOR|NAME_FROM_CONTENT|GTK_ACCESSIBLE_NAME_REQUIRED,
[GTK_ACCESSIBLE_ROLE_TABLE] = NAME_FROM_AUTHOR|GTK_ACCESSIBLE_NAME_REQUIRED,
[GTK_ACCESSIBLE_ROLE_TAB_LIST] = NAME_FROM_AUTHOR,
[GTK_ACCESSIBLE_ROLE_TAB_PANEL] = NAME_FROM_AUTHOR|GTK_ACCESSIBLE_NAME_REQUIRED,
[GTK_ACCESSIBLE_ROLE_TEXT_BOX] = NAME_FROM_AUTHOR|GTK_ACCESSIBLE_NAME_REQUIRED,
[GTK_ACCESSIBLE_ROLE_TIME] = GTK_ACCESSIBLE_NAME_PROHIBITED,
[GTK_ACCESSIBLE_ROLE_TIMER] = NAME_FROM_AUTHOR,
[GTK_ACCESSIBLE_ROLE_TOOLBAR] = NAME_FROM_AUTHOR|GTK_ACCESSIBLE_NAME_RECOMMENDED,
[GTK_ACCESSIBLE_ROLE_TOOLTIP] = NAME_FROM_AUTHOR|NAME_FROM_CONTENT,
[GTK_ACCESSIBLE_ROLE_TREE] = NAME_FROM_AUTHOR|GTK_ACCESSIBLE_NAME_REQUIRED,
[GTK_ACCESSIBLE_ROLE_TREE_GRID] = NAME_FROM_AUTHOR|GTK_ACCESSIBLE_NAME_REQUIRED,
[GTK_ACCESSIBLE_ROLE_TREE_ITEM] = NAME_FROM_AUTHOR|NAME_FROM_CONTENT|GTK_ACCESSIBLE_NAME_REQUIRED,
[GTK_ACCESSIBLE_ROLE_WIDGET] = NAME_FROM_AUTHOR|NAME_FROM_CONTENT,
[GTK_ACCESSIBLE_ROLE_WINDOW] = NAME_FROM_AUTHOR,
[GTK_ACCESSIBLE_ROLE_TOGGLE_BUTTON] = NAME_FROM_AUTHOR|GTK_ACCESSIBLE_NAME_REQUIRED,
[GTK_ACCESSIBLE_ROLE_APPLICATION] = NAME_FROM_AUTHOR|GTK_ACCESSIBLE_NAME_REQUIRED,
};
/* < private >
* gtk_accessible_role_supports_name_from_author:
* @role: a `GtkAccessibleRole`
*
* Returns whether this role supports setting the label and description
* properties or the labelled-by and described-by relations.
*
* Returns: %TRUE if the role allows labelling
*/
gboolean
gtk_accessible_role_supports_name_from_author (GtkAccessibleRole role)
{
return (naming[role] & NAME_FROM_AUTHOR) != 0;
}
/* < private >
* gtk_accessible_role_supports_name_from_content:
* @role: a `GtkAccessibleRole`
*
* Returns whether this role will use content of child widgets such
* as labels for its accessible name and description if no explicit
* labels are provided.
*
* Returns: %TRUE if the role content naming
*/
gboolean
gtk_accessible_role_supports_name_from_content (GtkAccessibleRole role)
{
return (naming[role] & NAME_FROM_CONTENT) != 0;
}
/* < private >
* gtk_accessible_role_get_nameing:
* @role: a `GtkAccessibleRole`
*
* Returns naming information for this role.
*
* Returns: information about naming requirements for the role
*/
GtkAccessibleNaming
gtk_accessible_role_get_naming (GtkAccessibleRole role)
{
return (GtkAccessibleNaming) (naming[role] & ~(NAME_FROM_AUTHOR|NAME_FROM_CONTENT));
}
static gboolean
is_nested_button (GtkATContext *self)
{
@@ -1200,7 +1167,18 @@ is_nested_button (GtkATContext *self)
if ((GTK_IS_TOGGLE_BUTTON (widget) && GTK_IS_DROP_DOWN (parent)) ||
(GTK_IS_TOGGLE_BUTTON (widget) && GTK_IS_MENU_BUTTON (parent)) ||
(GTK_IS_BUTTON (widget) && GTK_IS_COLOR_DIALOG_BUTTON (parent)) ||
(GTK_IS_BUTTON (widget) && GTK_IS_FONT_DIALOG_BUTTON (parent)))
(GTK_IS_BUTTON (widget) && GTK_IS_FONT_DIALOG_BUTTON (parent)) ||
(GTK_IS_BUTTON (widget) && GTK_IS_SCALE_BUTTON (parent))
#ifdef G_OS_UNIX
|| (GTK_IS_PRINTER_OPTION_WIDGET (parent) &&
(GTK_IS_CHECK_BUTTON (widget) ||
GTK_IS_DROP_DOWN (widget) ||
GTK_IS_ENTRY (widget) ||
GTK_IS_IMAGE (widget) ||
GTK_IS_LABEL (widget) ||
GTK_IS_BUTTON (widget)))
#endif
)
return TRUE;
return FALSE;
@@ -1223,6 +1201,219 @@ get_parent_context (GtkATContext *self)
return g_object_ref (self);
}
static inline gboolean
not_just_space (const char *text)
{
for (const char *p = text; *p; p = g_utf8_next_char (p))
{
if (!g_unichar_isspace (g_utf8_get_char (p)))
return TRUE;
}
return FALSE;
}
static inline void
append_with_space (GString *str,
const char *text)
{
if (str->len > 0)
g_string_append (str, " ");
g_string_append (str, text);
}
/* See the WAI-ARIA § 4.3, "Accessible Name and Description Computation",
* and https://www.w3.org/TR/accname-1.2/
*/
static void
gtk_at_context_get_text_accumulate (GtkATContext *self,
GPtrArray *nodes,
GString *res,
GtkAccessibleProperty property,
GtkAccessibleRelation relation,
gboolean is_ref,
gboolean is_child)
{
GtkAccessibleValue *value = NULL;
/* Step 2.A */
if (!is_ref)
{
if (gtk_accessible_attribute_set_contains (self->states, GTK_ACCESSIBLE_STATE_HIDDEN))
{
value = gtk_accessible_attribute_set_get_value (self->states, GTK_ACCESSIBLE_STATE_HIDDEN);
if (gtk_boolean_accessible_value_get (value))
return;
}
}
if (gtk_accessible_role_supports_name_from_author (self->accessible_role))
{
/* Step 2.B */
if (!is_ref && gtk_accessible_attribute_set_contains (self->relations, relation))
{
value = gtk_accessible_attribute_set_get_value (self->relations, relation);
GList *list = gtk_reference_list_accessible_value_get (value);
for (GList *l = list; l != NULL; l = l->next)
{
GtkAccessible *rel = GTK_ACCESSIBLE (l->data);
if (!g_ptr_array_find (nodes, rel, NULL))
{
GtkATContext *rel_context = gtk_accessible_get_at_context (rel);
g_ptr_array_add (nodes, rel);
gtk_at_context_get_text_accumulate (rel_context, nodes, res, property, relation, TRUE, FALSE);
g_object_unref (rel_context);
}
}
return;
}
/* Step 2.C */
if (gtk_accessible_attribute_set_contains (self->properties, property))
{
value = gtk_accessible_attribute_set_get_value (self->properties, property);
char *str = (char *) gtk_string_accessible_value_get (value);
if (str[0] != '\0')
{
append_with_space (res, gtk_string_accessible_value_get (value));
return;
}
}
}
/* Step 2.E */
if (self->accessible_role == GTK_ACCESSIBLE_ROLE_TEXT_BOX)
{
if (GTK_IS_EDITABLE (self->accessible))
{
const char *text = gtk_editable_get_text (GTK_EDITABLE (self->accessible));
if (text && not_just_space (text))
append_with_space (res, text);
}
return;
}
else if (gtk_accessible_role_is_range_subclass (self->accessible_role))
{
if (gtk_accessible_attribute_set_contains (self->properties, GTK_ACCESSIBLE_PROPERTY_VALUE_TEXT))
{
value = gtk_accessible_attribute_set_get_value (self->properties, GTK_ACCESSIBLE_PROPERTY_VALUE_TEXT);
append_with_space (res, gtk_string_accessible_value_get (value));
}
else if (gtk_accessible_attribute_set_contains (self->properties, GTK_ACCESSIBLE_PROPERTY_VALUE_NOW))
{
value = gtk_accessible_attribute_set_get_value (self->properties, GTK_ACCESSIBLE_PROPERTY_VALUE_NOW);
if (res->len > 0)
g_string_append (res, " ");
g_string_append_printf (res, "%g", gtk_number_accessible_value_get (value));
}
return;
}
/* Step 2.F */
if (gtk_accessible_role_supports_name_from_content (self->accessible_role) || is_ref || is_child)
{
if (GTK_IS_WIDGET (self->accessible))
{
GString *s = g_string_new ("");
for (GtkWidget *child = gtk_widget_get_first_child (GTK_WIDGET (self->accessible));
child != NULL;
child = gtk_widget_get_next_sibling (child))
{
GtkAccessible *rel = GTK_ACCESSIBLE (child);
GtkATContext *rel_context = gtk_accessible_get_at_context (rel);
gtk_at_context_get_text_accumulate (rel_context, nodes, s, property, relation, FALSE, TRUE);
}
if (s->len > 0)
{
append_with_space (res, s->str);
g_string_free (s, TRUE);
return;
}
g_string_free (s, TRUE);
}
}
/* Step 2.G */
if (GTK_IS_LABEL (self->accessible))
{
const char *text = gtk_label_get_text (GTK_LABEL (self->accessible));
if (text && not_just_space (text))
append_with_space (res, text);
return;
}
else if (GTK_IS_INSCRIPTION (self->accessible))
{
const char *text = gtk_inscription_get_text (GTK_INSCRIPTION (self->accessible));
if (text && not_just_space (text))
append_with_space (res, text);
return;
}
/* Step 2.I */
if (GTK_IS_WIDGET (self->accessible))
{
const char *text = gtk_widget_get_tooltip_text (GTK_WIDGET (self->accessible));
if (text && not_just_space (text))
append_with_space (res, text);
}
}
static char *
gtk_at_context_get_text (GtkATContext *self,
GtkAccessibleProperty property,
GtkAccessibleRelation relation)
{
GtkATContext *parent = NULL;
g_return_val_if_fail (GTK_IS_AT_CONTEXT (self), NULL);
/* Step 1 */
if (gtk_accessible_role_get_naming (self->accessible_role) == GTK_ACCESSIBLE_NAME_PROHIBITED)
return g_strdup ("");
/* We special case this here since it is a common pattern:
* We have a 'wrapper' object, like a GtkDropdown which
* contains a toggle button. The dropdown appears in the
* ui file and carries all the a11y attributes, but the
* focus ends up on the toggle button.
*/
if (is_nested_button (self))
{
parent = get_parent_context (self);
self = parent;
if (is_nested_button (self))
{
parent = get_parent_context (parent);
g_object_unref (self);
self = parent;
}
}
GPtrArray *nodes = g_ptr_array_new ();
GString *res = g_string_new ("");
/* Step 2 */
gtk_at_context_get_text_accumulate (self, nodes, res, property, relation, FALSE, FALSE);
g_ptr_array_unref (nodes);
g_clear_object (&parent);
return g_string_free (res, FALSE);
}
/*< private >
* gtk_at_context_get_name:
@@ -1237,53 +1428,7 @@ get_parent_context (GtkATContext *self)
char *
gtk_at_context_get_name (GtkATContext *self)
{
GtkATContext *parent = NULL;
g_return_val_if_fail (GTK_IS_AT_CONTEXT (self), NULL);
for (unsigned int i = 0; i < G_N_ELEMENTS (name_forbidden); i++)
{
if (self->accessible_role == name_forbidden[i])
return g_strdup ("");
}
/* We special case this here since it is a common pattern:
* We have a 'wrapper' object, like a GtkDropdown which
* contains a toggle button. The dropdown appears in the
* ui file and carries all the a11y attributes, but the
* focus ends up on the toggle button.
*/
if (is_nested_button (self))
{
parent = get_parent_context (self);
self = parent;
}
GPtrArray *names = g_ptr_array_new ();
gtk_at_context_get_name_accumulate (self, names, TRUE);
if (names->len == 0)
{
g_ptr_array_unref (names);
g_clear_object (&parent);
return g_strdup ("");
}
GString *res = g_string_new ("");
g_string_append (res, g_ptr_array_index (names, 0));
for (guint i = 1; i < names->len; i++)
{
g_string_append (res, " ");
g_string_append (res, g_ptr_array_index (names, i));
}
g_ptr_array_unref (names);
g_clear_object (&parent);
return g_string_free (res, FALSE);
return gtk_at_context_get_text (self, GTK_ACCESSIBLE_PROPERTY_LABEL, GTK_ACCESSIBLE_RELATION_LABELLED_BY);
}
/*< private >
@@ -1299,52 +1444,7 @@ gtk_at_context_get_name (GtkATContext *self)
char *
gtk_at_context_get_description (GtkATContext *self)
{
GtkATContext *parent = NULL;
g_return_val_if_fail (GTK_IS_AT_CONTEXT (self), NULL);
for (unsigned int i = 0; i < G_N_ELEMENTS (name_forbidden); i++)
{
if (self->accessible_role == name_forbidden[i])
return g_strdup ("");
}
/* We special case this here since it is a common pattern:
* We have a 'wrapper' object, like a GtkDropdown which
* contains a toggle button. The dropdown appears in the
* ui file and carries all the a11y attributes, but the
* focus ends up on the toggle button.
*/
if (is_nested_button (self))
{
parent = get_parent_context (self);
self = parent;
}
GPtrArray *names = g_ptr_array_new ();
gtk_at_context_get_description_accumulate (self, names, TRUE);
if (names->len == 0)
{
g_ptr_array_unref (names);
g_clear_object (&parent);
return g_strdup ("");
}
GString *res = g_string_new ("");
g_string_append (res, g_ptr_array_index (names, 0));
for (guint i = 1; i < names->len; i++)
{
g_string_append (res, " ");
g_string_append (res, g_ptr_array_index (names, i));
}
g_ptr_array_unref (names);
g_clear_object (&parent);
return g_string_free (res, FALSE);
return gtk_at_context_get_text (self, GTK_ACCESSIBLE_PROPERTY_DESCRIPTION, GTK_ACCESSIBLE_RELATION_DESCRIBED_BY);
}
void

View File

@@ -56,7 +56,9 @@
*
* # Accessibility
*
* `GtkBox` uses the %GTK_ACCESSIBLE_ROLE_GROUP role.
* Until GTK 4.10, `GtkBox` used the `GTK_ACCESSIBLE_ROLE_GROUP` role.
*
* Starting from GTK 4.12, `GtkBox` uses the `GTK_ACCESSIBLE_ROLE_GENERIC` role.
*/
#include "config.h"
@@ -84,10 +86,12 @@ enum {
typedef struct
{
gint16 spacing;
gint16 spacing;
guint homogeneous : 1;
guint baseline_pos : 2;
bool homogeneous;
/* GtkBaselinePosition */
guint baseline_pos : 2;
} GtkBoxPrivate;
static GParamSpec *props[LAST_PROP] = { NULL, };
@@ -304,8 +308,9 @@ gtk_box_class_init (GtkBoxClass *class)
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BOX_LAYOUT);
gtk_widget_class_set_css_name (widget_class, I_("box"));
gtk_widget_class_set_accessible_role (widget_class, GTK_ACCESSIBLE_ROLE_GROUP);
gtk_widget_class_set_accessible_role (widget_class, GTK_ACCESSIBLE_ROLE_GENERIC);
}
static void
gtk_box_init (GtkBox *box)
{
@@ -366,14 +371,13 @@ void
gtk_box_set_homogeneous (GtkBox *box,
gboolean homogeneous)
{
bool is_homogeneous = !!homogeneous;
GtkBoxLayout *box_layout;
g_return_if_fail (GTK_IS_BOX (box));
homogeneous = !!homogeneous;
box_layout = GTK_BOX_LAYOUT (gtk_widget_get_layout_manager (GTK_WIDGET (box)));
if (homogeneous == gtk_box_layout_get_homogeneous (box_layout))
if (is_homogeneous == gtk_box_layout_get_homogeneous (box_layout))
return;
gtk_box_layout_set_homogeneous (box_layout, homogeneous);

View File

@@ -54,16 +54,47 @@
* to make use of them. Non-widget objects need to be reffed with
* g_object_ref() to keep them beyond the lifespan of the builder.
*
* # GtkBuilder UI Definitions
* ## GtkBuilder UI Definitions
*
* `GtkBuilder` parses textual descriptions of user interfaces which are
* specified in XML format. We refer to these descriptions as “GtkBuilder
* UI definitions” or just “UI definitions” if the context is clear.
*
* ### Structure of UI definitions
*
* UI definition files are always encoded in UTF-8.
*
* The toplevel element is `<interface>`. It optionally takes a “domain”
* attribute, which will make the builder look for translated strings
* using `dgettext()` in the domain specified. This can also be done by
* calling [method@Gtk.Builder.set_translation_domain] on the builder.
* For example:
*
* ```xml
* <?xml version="1.0" encoding="UTF-8">
* <interface domain="your-app">
* ...
* </interface>
* ```
*
* ### Requirements
*
* The target toolkit version(s) are described by `<requires>` elements,
* the “lib” attribute specifies the widget library in question (currently
* the only supported value is “gtk”) and the “version” attribute specifies
* the target version in the form “`<major>`.`<minor>`”. `GtkBuilder` will
* error out if the version requirements are not met. For example:
*
* ```xml
* <?xml version="1.0" encoding="UTF-8">
* <interface domain="your-app">
* <requires lib="gtk" version="4.0" />
* </interface>
* ```
*
* ### Objects
*
* Objects are defined as children of the `<interface>` element.
*
* Objects are described by `<object>` elements, which can contain
* `<property>` elements to set properties, `<signal>` elements which
@@ -72,18 +103,14 @@
* actions in an action group, or columns in a tree model). A `<child>`
* element contains an `<object>` element which describes the child object.
*
* The target toolkit version(s) are described by `<requires>` elements,
* the “lib” attribute specifies the widget library in question (currently
* the only supported value is “gtk”) and the “version” attribute specifies
* the target version in the form “`<major>`.`<minor>`”. `GtkBuilder` will
* error out if the version requirements are not met.
*
* Typically, the specific kind of object represented by an `<object>`
* element is specified by the “class” attribute. If the type has not
* been loaded yet, GTK tries to find the `get_type()` function from the
* class name by applying heuristics. This works in most cases, but if
* necessary, it is possible to specify the name of the `get_type()`
* function explicitly with the "type-func" attribute.
* function explicitly with the "type-func" attribute. If your UI definition
* is referencing internal types, you should make sure to call
* `g_type_ensure()` for each object type before parsing the UI definition.
*
* Objects may be given a name with the “id” attribute, which allows the
* application to retrieve them from the builder with
@@ -92,45 +119,96 @@
* reserves ids starting and ending with `___` (three consecutive
* underscores) for its own purposes.
*
* ### Properties
*
* Setting properties of objects is pretty straightforward with the
* `<property>` element: the “name” attribute specifies the name of the
* property, and the content of the element specifies the value.
* property, and the content of the element specifies the value:
*
* ```xml
* <object class="GtkButton">
* <property name="label">Hello, world</property>
* </object>
* ```
*
* If the “translatable” attribute is set to a true value, GTK uses
* `gettext()` (or `dgettext()` if the builder has a translation domain set)
* to find a translation for the value. This happens before the value
* is parsed, so it can be used for properties of any type, but it is
* probably most useful for string properties. It is also possible to
* specify a context to disambiguate short strings, and comments which
* may help the translators.
* may help the translators:
*
* ```xml
* <object class="GtkButton">
* <property name="label" translatable="yes" context="button">Hello, world</property>
* </object>
* ```
*
* `GtkBuilder` can parse textual representations for the most common
* property types: characters, strings, integers, floating-point numbers,
* booleans (strings like “TRUE”, “t”, “yes”, “y”, “1” are interpreted
* as %TRUE, strings like “FALSE”, “f”, “no”, “n”, “0” are interpreted
* as %FALSE), enumerations (can be specified by their name, nick or
* integer value), flags (can be specified by their name, nick, integer
* value, optionally combined with “|”, e.g.
* “GTK_INPUT_HINT_EMOJI|GTK_INPUT_HINT_LOWERCASE”)
* and colors (in a format understood by [method@Gdk.RGBA.parse]).
* property types:
*
* `GVariant`s can be specified in the format understood by
* g_variant_parse(), and pixbufs can be specified as a filename of an
* image file to load.
* - characters
* - strings
* - integers
* - floating-point numbers
* - booleans (strings like “TRUE”, “t”, “yes”, “y”, “1” are interpreted
* as true values, strings like “FALSE”, “f”, “no”, “n”, “0” are interpreted
* as false values)
* - enumeration types (can be specified by their full C identifier their short
* name used when registering the enumeration type, or their integer value)
* - flag types (can be specified by their C identifier, short name, integer
* value, and optionally combined with “|” for bitwise OR, e.g.
* “GTK_INPUT_HINT_EMOJI|GTK_INPUT_HINT_LOWERCASE”, or “emoji|lowercase”)
* - colors (in a format understood by [method@Gdk.RGBA.parse])
* - `GVariant` (can be specified in the format understood by
* [func@GLib.Variant.parse])
* - pixbufs (can be specified as a filename of an image file to load)
*
* Objects can be referred to by their name and by default refer to
* objects declared in the local XML fragment and objects exposed via
* [method@Gtk.Builder.expose_object]. In general, `GtkBuilder` allows
* forward references to objects declared in the local XML; an object
* forward references to objects declared in the local XML; an object
* doesnt have to be constructed before it can be referred to. The
* exception to this rule is that an object has to be constructed before
* it can be used as the value of a construct-only property.
*
* ### Property bindings
*
* It is also possible to bind a property value to another object's
* property value using the attributes "bind-source" to specify the
* source object of the binding, and optionally, "bind-property" and
* "bind-flags" to specify the source property and source binding flags
* respectively. Internally, `GtkBuilder` implements this using `GBinding`
* objects. For more information see g_object_bind_property().
* respectively. Internally, `GtkBuilder` implements this using
* [class@GObject.Binding] objects.
*
* For instance, in the example below the “label” property of the
* `bottom_label` widget is bound to the “label” property of the
* `top_button` widget:
*
* ```xml
* <object class="GtkBox">
* <property name="orientation">vertical</property>
* <child>
* <object class="GtkButton" id="top_button">
* <property name="label">Hello, world</property>
* </object>
* </child>
* <child>
* <object class="GtkLabel" id="bottom_label">
* <property name="label"
* bind-source="top_button"
* bind-property="label"
* bind-flags="sync-create" />
* </object>
* </child>
* </object>
* ```
*
* For more information, see the documentation of the
* [method@GObject.Object.bind_property] method.
*
* ### Internal children
*
* Sometimes it is necessary to refer to widgets which have implicitly
* been constructed by GTK as part of a composite widget, to set
@@ -140,42 +218,68 @@
* still requires an `<object>` element for the internal child, even if it
* has already been constructed.
*
* ### Specialized children
*
* A number of widgets have different places where a child can be added
* (e.g. tabs vs. page content in notebooks). This can be reflected in
* a UI definition by specifying the “type” attribute on a `<child>`
* The possible values for the “type” attribute are described in the
* sections describing the widget-specific portions of UI definitions.
*
* # Signal handlers and function pointers
* ### Signal handlers and function pointers
*
* Signal handlers are set up with the `<signal>` element. The “name”
* attribute specifies the name of the signal, and the “handler” attribute
* specifies the function to connect to the signal.
*
* ```xml
* <object class="GtkButton" id="hello_button">
* <signal name="clicked" handler="hello_button__clicked" />
* </object>
* ```
*
* The remaining attributes, “after”, “swapped” and “object”, have the
* same meaning as the corresponding parameters of the
* g_signal_connect_object() or g_signal_connect_data() functions. By
* default "swapped" will be set to "yes" if not specified otherwise, in the
* case where "object" is set, for convenience. A “last_modification_time”
* [func@GObject.signal_connect_object] or [func@GObject.signal_connect_data]
* functions:
*
* - “after” matches the `G_CONNECT_AFTER` flag, and will ensure that the
* handler is called after the default class closure for the signal
* - “swapped” matches the `G_CONNECT_SWAPPED` flag, and will swap the
* instance and closure arguments when invoking the signal handler
* - “object” will bind the signal handler to the lifetime of the object
* referenced by the attribute
*
* By default "swapped" will be set to "yes" if not specified otherwise, in
* the case where "object" is set, for convenience. A “last_modification_time”
* attribute is also allowed, but it does not have a meaning to the builder.
*
* If you rely on `GModule` support to lookup callbacks in the symbol table,
* the following details should be noted:
*
* When compiling applications for Windows, you must declare signal callbacks
* with %G_MODULE_EXPORT, or they will not be put in the symbol table.
* On Linux and Unix, this is not necessary; applications should instead
* be compiled with the -Wl,--export-dynamic `CFLAGS`, and linked against
* `gmodule-export-2.0`.
* with the `G_MODULE_EXPORT` decorator, or they will not be put in the symbol
* table:
*
* # A GtkBuilder UI Definition
* ```c
* G_MODULE_EXPORT void
* hello_button__clicked (GtkButton *button,
* gpointer data)
* {
* // ...
* }
* ```
*
* On Linux and Unix, this is not necessary; applications should instead
* be compiled with the `-Wl,--export-dynamic` argument inside their compiler
* flags, and linked against `gmodule-export-2.0`.
*
* ## Example UI Definition
*
* ```xml
* <interface>
* <object class="GtkDialog" id="dialog1">
* <child internal-child="content_area">
* <object class="GtkBox" id="vbox1">
* <object class="GtkBox">
* <child internal-child="action_area">
* <object class="GtkBox" id="hbuttonbox1">
* <object class="GtkBox">
* <child>
* <object class="GtkButton" id="ok_button">
* <property name="label" translatable="yes">_Ok</property>
@@ -191,17 +295,21 @@
* </interface>
* ```
*
* Beyond this general structure, several object classes define their
* own XML DTD fragments for filling in the ANY placeholders in the DTD
* above. Note that a custom element in a `<child>` element gets parsed by
* the custom tag handler of the parent object, while a custom element in
* an `<object>` element gets parsed by the custom tag handler of the object.
* ## Using GtkBuildable for extending UI definitions
*
* These XML fragments are explained in the documentation of the
* respective objects.
* Objects can implement the [iface@Gtk.Buildable] interface to add custom
* elements and attributes to the XML. Typically, any extension will be
* documented in each type that implements the interface.
*
* A `<template>` tag can be used to define a widget classs components.
* See the [GtkWidget documentation](class.Widget.html#building-composite-widgets-from-template-xml) for details.
* ## Templates
*
* When describing a [class@Gtk.Widget], you can use the `<template>` tag to
* describe a UI bound to a specific widget type. GTK will automatically load
* the UI definition when instantiating the type, and bind children and
* signal handlers to instance fields and function symbols.
*
* For more information, see the [`GtkWidget` documentation](class.Widget.html#building-composite-widgets-from-template-xml)
* for details.
*/
#include "config.h"
@@ -2362,6 +2470,24 @@ gtk_builder_value_from_string_type (GtkBuilder *builder,
ret = FALSE;
}
}
else if (G_VALUE_HOLDS (value, G_TYPE_DATE_TIME))
{
GDateTime *date_time;
date_time = g_date_time_new_from_iso8601 (string, NULL);
if (date_time)
g_value_take_boxed (value, date_time);
else
{
g_set_error (error,
GTK_BUILDER_ERROR,
GTK_BUILDER_ERROR_INVALID_VALUE,
"Could not parse GDateTime '%s'",
string);
ret = FALSE;
}
}
else
{
g_set_error (error,

View File

@@ -83,18 +83,19 @@
struct _GtkButtonPrivate
{
GtkWidget *child;
GtkWidget *child;
GtkActionHelper *action_helper;
GtkActionHelper *action_helper;
GtkGesture *gesture;
GtkGesture *gesture;
guint activate_timeout;
guint activate_timeout;
guint button_down : 1;
guint use_underline : 1;
guint child_type : 2;
guint can_shrink : 1;
bool button_down;
bool use_underline;
bool can_shrink;
guint child_type : 2;
};
enum {
@@ -353,7 +354,7 @@ click_pressed_cb (GtkGestureClick *gesture,
gtk_widget_grab_focus (widget);
if (!priv->activate_timeout)
priv->button_down = TRUE;
priv->button_down = true;
}
static void
@@ -444,8 +445,8 @@ gtk_button_init (GtkButton *button)
gtk_widget_set_focusable (GTK_WIDGET (button), TRUE);
gtk_widget_set_receives_default (GTK_WIDGET (button), TRUE);
priv->button_down = FALSE;
priv->use_underline = FALSE;
priv->button_down = false;
priv->use_underline = false;
priv->child_type = WIDGET_CHILD;
priv->gesture = gtk_gesture_click_new ();
@@ -772,7 +773,7 @@ gtk_button_do_release (GtkButton *button,
if (priv->button_down)
{
priv->button_down = FALSE;
priv->button_down = false;
if (priv->activate_timeout)
return;
@@ -811,7 +812,7 @@ gtk_real_button_activate (GtkButton *button)
gdk_source_set_static_name_by_id (priv->activate_timeout, "[gtk] button_activate_timeout");
gtk_widget_add_css_class (GTK_WIDGET (button), "keyboard-activating");
priv->button_down = TRUE;
priv->button_down = true;
}
}
@@ -826,7 +827,7 @@ gtk_button_finish_activate (GtkButton *button,
g_source_remove (priv->activate_timeout);
priv->activate_timeout = 0;
priv->button_down = FALSE;
priv->button_down = false;
if (do_it)
g_signal_emit (button, button_signals[CLICKED], 0);
@@ -918,20 +919,19 @@ gtk_button_set_use_underline (GtkButton *button,
gboolean use_underline)
{
GtkButtonPrivate *priv = gtk_button_get_instance_private (button);
bool underline = !!use_underline;
g_return_if_fail (GTK_IS_BUTTON (button));
use_underline = use_underline != FALSE;
if (use_underline != priv->use_underline)
if (underline != priv->use_underline)
{
if (priv->child_type == LABEL_CHILD)
{
gtk_label_set_use_underline (GTK_LABEL (priv->child), use_underline);
gtk_label_set_use_underline (GTK_LABEL (priv->child), underline);
gtk_label_set_mnemonic_widget (GTK_LABEL (priv->child), GTK_WIDGET (button));
}
priv->use_underline = use_underline;
priv->use_underline = underline;
g_object_notify_by_pspec (G_OBJECT (button), props[PROP_USE_UNDERLINE]);
}
}
@@ -1118,14 +1118,13 @@ gtk_button_set_can_shrink (GtkButton *button,
gboolean can_shrink)
{
GtkButtonPrivate *priv = gtk_button_get_instance_private (button);
bool shrink = !!can_shrink;
g_return_if_fail (GTK_IS_BUTTON (button));
can_shrink = !!can_shrink;
if (priv->can_shrink != can_shrink)
if (priv->can_shrink != shrink)
{
priv->can_shrink = can_shrink;
priv->can_shrink = shrink;
switch (priv->child_type)
{

View File

@@ -202,10 +202,9 @@ struct _GtkCalendar
{
GtkWidget widget;
guint show_week_numbers : 1;
guint show_heading : 1;
guint show_day_names : 1;
guint year_before : 1;
bool show_week_numbers;
bool show_heading;
bool show_day_names;
GtkWidget *header_box;
GtkWidget *year_label;
@@ -219,14 +218,14 @@ struct _GtkCalendar
GDateTime *date;
int day_month[6][7];
int day[6][7];
int day_month[6][7];
int day[6][7];
int num_marked_dates;
int marked_date[31];
int num_marked_dates;
int marked_date[31];
int focus_row;
int focus_col;
int focus_row;
int focus_col;
int week_start;
};
@@ -547,7 +546,6 @@ gtk_calendar_init (GtkCalendar *calendar)
char buffer[255];
time_t tmp_time;
#endif
char *year_before;
#ifdef HAVE__NL_TIME_FIRST_WEEKDAY
union { unsigned int word; char *string; } langinfo;
int week_1stday = 0;
@@ -775,12 +773,12 @@ gtk_calendar_init (GtkCalendar *calendar)
gtk_widget_set_vexpand (calendar->grid, TRUE);
gtk_widget_set_parent (calendar->grid, GTK_WIDGET (calendar));
for (i=0;i<31;i++)
for (i = 0; i < 31; i++)
calendar->marked_date[i] = FALSE;
calendar->num_marked_dates = 0;
calendar->show_heading = TRUE;
calendar->show_day_names = TRUE;
calendar->show_heading = true;
calendar->show_day_names = true;
calendar->focus_row = -1;
calendar->focus_col = -1;
@@ -791,24 +789,6 @@ gtk_calendar_init (GtkCalendar *calendar)
g_signal_connect (target, "drop", G_CALLBACK (gtk_calendar_drag_drop), calendar);
gtk_widget_add_controller (widget, GTK_EVENT_CONTROLLER (target));
calendar->year_before = 0;
/* Translate to calendar:YM if you want years to be displayed
* before months; otherwise translate to calendar:MY.
* Do *not* translate it to anything else, if it
* it isn't calendar:YM or calendar:MY it will not work.
*
* Note that the ordering described here is logical order, which is
* further influenced by BIDI ordering. Thus, if you have a default
* text direction of RTL and specify "calendar:YM", then the year
* will appear to the right of the month.
*/
year_before = _("calendar:MY");
if (strcmp (year_before, "calendar:YM") == 0)
calendar->year_before = 1;
else if (strcmp (year_before, "calendar:MY") != 0)
g_warning ("Whoever translated calendar:MY did so wrongly.");
gtk_orientable_set_orientation (GTK_ORIENTABLE (gtk_widget_get_layout_manager (GTK_WIDGET (calendar))),
GTK_ORIENTATION_VERTICAL);
@@ -1657,17 +1637,18 @@ void
gtk_calendar_set_show_week_numbers (GtkCalendar *self,
gboolean value)
{
bool show_week_numbers = !!value;
int i;
g_return_if_fail (GTK_IS_CALENDAR (self));
if (self->show_week_numbers == value)
if (self->show_week_numbers == show_week_numbers)
return;
self->show_week_numbers = value;
self->show_week_numbers = show_week_numbers;
for (i = 0; i < 6; i ++)
gtk_widget_set_visible (self->week_number_labels[i], value);
gtk_widget_set_visible (self->week_number_labels[i], show_week_numbers);
g_object_notify (G_OBJECT (self), "show-week-numbers");
}
@@ -1706,14 +1687,16 @@ void
gtk_calendar_set_show_heading (GtkCalendar *self,
gboolean value)
{
bool show_heading = !!value;
g_return_if_fail (GTK_IS_CALENDAR (self));
if (self->show_heading == value)
if (self->show_heading == show_heading)
return;
self->show_heading = value;
self->show_heading = show_heading;
gtk_widget_set_visible (self->header_box, value);
gtk_widget_set_visible (self->header_box, show_heading);
g_object_notify (G_OBJECT (self), "show-heading");
}
@@ -1748,17 +1731,18 @@ void
gtk_calendar_set_show_day_names (GtkCalendar *self,
gboolean value)
{
bool show_day_names = !!value;
int i;
g_return_if_fail (GTK_IS_CALENDAR (self));
if (self->show_day_names == value)
if (self->show_day_names == show_day_names)
return;
self->show_day_names = value;
self->show_day_names = show_day_names;
for (i = 0; i < 7; i ++)
gtk_widget_set_visible (self->day_name_labels[i], value);
gtk_widget_set_visible (self->day_name_labels[i], show_day_names);
g_object_notify (G_OBJECT (self), "show-day-names");
}

View File

@@ -52,7 +52,9 @@
*
* # Accessibility
*
* `GtkCenterBox` uses the %GTK_ACCESSIBLE_ROLE_GROUP role.
* Until GTK 4.10, `GtkCenterBox` used the `GTK_ACCESSIBLE_ROLE_GROUP` role.
*
* Starting from GTK 4.12, `GtkCenterBox` uses the `GTK_ACCESSIBLE_ROLE_GENERIC` role.
*/
#include "config.h"
@@ -321,7 +323,7 @@ gtk_center_box_class_init (GtkCenterBoxClass *klass)
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_CENTER_LAYOUT);
gtk_widget_class_set_css_name (widget_class, I_("box"));
gtk_widget_class_set_accessible_role (widget_class, GTK_ACCESSIBLE_ROLE_GROUP);
gtk_widget_class_set_accessible_role (widget_class, GTK_ACCESSIBLE_ROLE_GENERIC);
}
static void

View File

@@ -103,10 +103,11 @@ typedef struct {
GtkWidget *indicator_widget;
GtkWidget *child;
guint inconsistent: 1;
guint active: 1;
guint use_underline: 1;
guint child_type: 1;
bool inconsistent;
bool active;
bool use_underline;
guint child_type : 1;
GtkCheckButton *group_next;
GtkCheckButton *group_prev;
@@ -790,13 +791,13 @@ gtk_check_button_set_inconsistent (GtkCheckButton *check_button,
gboolean inconsistent)
{
GtkCheckButtonPrivate *priv = gtk_check_button_get_instance_private (check_button);
bool is_inconsistent = !!inconsistent;
g_return_if_fail (GTK_IS_CHECK_BUTTON (check_button));
inconsistent = !!inconsistent;
if (priv->inconsistent != inconsistent)
if (priv->inconsistent != is_inconsistent)
{
priv->inconsistent = inconsistent;
priv->inconsistent = is_inconsistent;
if (inconsistent)
{
@@ -863,15 +864,14 @@ gtk_check_button_set_active (GtkCheckButton *self,
gboolean setting)
{
GtkCheckButtonPrivate *priv = gtk_check_button_get_instance_private (self);
bool is_active = !!setting;
g_return_if_fail (GTK_IS_CHECK_BUTTON (self));
setting = !!setting;
if (setting == priv->active)
if (is_active == priv->active)
return;
if (setting)
if (is_active)
{
gtk_widget_set_state_flags (GTK_WIDGET (self), GTK_STATE_FLAG_CHECKED, FALSE);
gtk_widget_set_state_flags (priv->indicator_widget, GTK_STATE_FLAG_CHECKED, FALSE);
@@ -882,7 +882,7 @@ gtk_check_button_set_active (GtkCheckButton *self,
gtk_widget_unset_state_flags (priv->indicator_widget, GTK_STATE_FLAG_CHECKED);
}
if (setting && (priv->group_prev || priv->group_next))
if (is_active && (priv->group_prev || priv->group_next))
{
GtkCheckButton *group_first = NULL;
GtkCheckButton *iter;
@@ -897,7 +897,7 @@ gtk_check_button_set_active (GtkCheckButton *self,
/* ... and the next code block will set this one to active */
}
priv->active = setting;
priv->active = is_active;
update_accessible_state (self);
g_object_notify_by_pspec (G_OBJECT (self), props[PROP_ACTIVE]);
g_signal_emit (self, signals[TOGGLED], 0);
@@ -1095,15 +1095,14 @@ gtk_check_button_set_use_underline (GtkCheckButton *self,
gboolean setting)
{
GtkCheckButtonPrivate *priv = gtk_check_button_get_instance_private (self);
bool use_underline = !!setting;
g_return_if_fail (GTK_IS_CHECK_BUTTON (self));
setting = !!setting;
if (setting == priv->use_underline)
if (use_underline == priv->use_underline)
return;
priv->use_underline = setting;
priv->use_underline = use_underline;
if (priv->child_type == LABEL_CHILD && priv->child != NULL)
gtk_label_set_use_underline (GTK_LABEL (priv->child), priv->use_underline);

View File

@@ -280,6 +280,7 @@ gtk_color_dialog_button_class_init (GtkColorDialogButtonClass *class)
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
gtk_widget_class_set_css_name (widget_class, "colorbutton");
gtk_widget_class_set_accessible_role (widget_class, GTK_ACCESSIBLE_ROLE_GROUP);
}
/* }}} */

Some files were not shown because too many files have changed in this diff Show More