Compare commits

...

102 Commits

Author SHA1 Message Date
Nelson Benítez León bab2bf2596 widget-factory: add example on styling tooltip window
by using new api:
  gtk_tooltip_set_css_class()
  GtkWidget signals 'tooltip-show' and 'tooltip-hide'

Part of #5925
2023-07-09 17:07:09 -04:00
Nelson Benítez León 11b4e4a467 GtkWidget: add new signals 'tooltip-show' and 'tooltip-hide'
which are emitted when a tooltip window is about to be shown
on a widget, and when a tooltip window stopped being shown
on a widget.

These signals provide two convenient moments for where to style
our tooltip window in case we want to do so by adding a css
class to it.

The existant signal 'query-tooltip' could not be used for that
as it's triggered on motion events and we cannot distinguish
from that when the tooltip window gets shown or hidden.

Part of issue #5925
2023-07-09 17:07:09 -04:00
Nelson Benítez León 1cae0cd54c GtkToolTip: new API to add css classes to GtkTooltipWindow
we add a simple API to allow styling GtkTooltip's window
by setting a css class on it:

void gtk_tooltip_set_css_class (GtkTooltip *tooltip,
                                const char *css_class);

By passing NULL it will remove any previously set css class
by this function.

Issue #5925
2023-07-09 17:07:09 -04:00
Matthias Clasen 1f3db35271 Merge branch 'dboles/image-notify-storage-type' into 'main'
Image—Notify when :storage-type changes from EMPTY

See merge request GNOME/gtk!6170
2023-07-07 01:15:56 +00:00
Emmanuele Bassi 18cce46ed2 Merge branch 'wip/corey/listitemleak' into 'main'
gtklistitemmanager: Stop leaking item

Closes #5940

See merge request GNOME/gtk!6171
2023-07-06 23:57:16 +00:00
Corey Berla e78148bae5 gtklistitemmanager: Stop leaking item
Fixes: https://gitlab.gnome.org/GNOME/gtk/-/issues/5940
2023-07-06 16:24:29 -07:00
Daniel Boles 41237509ad Image—Notify when :storage-type changes from EMPTY
PROP_STORAGE_TYPE was only notified if it was changing *to* EMPTY, in
gtk_image_clear_internal(). We did not notify when it changes *from*
EMPTY to something non-empty. We should as not doing so is confusing,
e.g. if a user wants to bind :storage-type to :visible if non-empty,
which I just did! So, in functions that apply an ImageType, now notify.

Also do so in gtk_image_set_from_definition, declared in imageprivate.h,
even though none of the function there are currently used anywhere.
(Should they be removed?)
2023-07-06 23:08:20 +01:00
Yosef Or Boczko 576e8a2090 Update Hebrew translation 2023-07-06 09:38:02 +00:00
Matthias Clasen d0f77c1db4 Merge branch 'wip/carlosg/switch-stylus-buttons' into 'main'
gdk/wayland: Switch behavior of BTN_STYLUS/STYLUS2 as middle/right click

Closes #5935

See merge request GNOME/gtk!6168
2023-07-05 23:38:38 +00:00
Carlos Garnacho e28ff79bec gdk/wayland: Switch behavior of BTN_STYLUS/STYLUS2 as middle/right click
This mapping of stylus evdev input event codes into GDK button numbers
makes gdk/wayland inconsistent with gdk/x11, so depending on the backend
the same button middle-click pastes or right-click pops up menus.

Make the wayland backend consistent with X11, so that a GNOME wayland
session gets these buttons consistently mapped across all kinds of
clients.

Closes: https://gitlab.gnome.org/GNOME/gtk/-/issues/5935
2023-07-05 16:54:54 +02:00
Daniel Boles dccf6b55bd GdkTexture: Don't mention private new_from_surface
The stuff about Cairo Surfaces is in gdktextureprivate.h, & so end users
will not be able to use them; we shouldn't confuse by implying they can.
2023-07-05 12:07:33 +01:00
Daniel Boles d5ea376e7b docs/list-widget: links, DirList, correct Sections
* Add links to various symbols.
* Mention DirectoryList in the "ready-made choices available" section.
* Don't say that GridView can display headers: it makes no attempt to.
2023-07-05 12:02:08 +01:00
Matthias Clasen 40707a6af0 Merge branch 'ebassi/issue-5934' into 'main'
Lower the Python requirement

Closes #5934

See merge request GNOME/gtk!6167
2023-07-05 10:57:45 +00:00
Emmanuele Bassi 9b71c9dfc6 Do not use bleeding edge Python
The match operator was added in Python 3.10, which is a bit too new for
some downstreams.

While at it, let's fix the flake8 errors and warnings.

Fixes: #5934
2023-07-05 10:19:18 +01:00
Emmanuele Bassi 64308317f8 Add flake8 configuration file
Ignore long lines; most of our Python scripts generate code or other
types of files, which makes long lines a necessity.

We should validate all our Python script in our CI as well.
2023-07-05 10:12:20 +01:00
Daniel Boles f920723eae AlertDialog: Remove spurious/unmatched backtick 2023-07-04 22:42:50 +01:00
Daniel Boles c581f4c96f ListBase: Fix a typo 2023-07-04 19:44:56 +01:00
Matthias Clasen 4998c90b10 Merge branch 'update-uac-script-format' into 'main'
tools/generate-uac-manifest.py: Fix formatting (unify with copy in GLib)

See merge request GNOME/gtk!6164
2023-07-03 23:37:36 +00:00
Benjamin Otte 412b23a146 Merge branch 'wip/otte/for-main' into 'main'
gsk: Catch values < 0 before bad things happen

See merge request GNOME/gtk!6165
2023-07-03 20:40:30 +00:00
Benjamin Otte c179013790 testsuite: Add a test for mask out of bounds effects
Inverted alpha masks have an effect on the source, even if the mask
doesn't cover the source at all - or worse, is completely clipped out.

The GL renderer handles this fine, but Cairo and Vulkan had
optimizations that got this wrong.
2023-07-03 22:02:44 +02:00
Benjamin Otte c6eb7fd483 gsk: Fix luminance in Cairo and GL renderer
In particular, fix the combination of luminance and alpha. We want to do
  mask = luminance * alpha
and for inverted
  mask = (1.0 - luminance) * alpha
so add a test that makes sure we do that and then fix the code and
existing tests to conform to it.
2023-07-03 22:02:44 +02:00
Benjamin Otte 7c58370673 rendernode: Work around a Cairo bug
When color-matrix modifying a clear surface, the surface would remain
clear according to Cairo.

That's very unfortunate when we prepare a mask for inverted-alpha
masking.
2023-07-03 22:02:44 +02:00
Benjamin Otte 84737a5159 build: Include the right things
If we build our own targets, we need to include those.

This is only relevant when adding new shaders because meson will
complain that the (unused) sources don't exist as it tries to include
those.
And that will make the build.ninja file not be generated which would
have build those shaders and would have allowed to copy them into the
sources.

Note that this makes builds with glslc not care about all the shader
files being included with the sources, but we have CI to check that.
2023-07-03 22:02:44 +02:00
Benjamin Otte 48804c81f3 rendernode: Mask nodes with different modes are different
So treat them as such.

Fixes the node editor not updating when I edit the mask mode.
2023-07-03 22:02:44 +02:00
Benjamin Otte c79ec355af gsk: Catch values < 0 before bad things happen
In particular, catch radius values being < 0 by return_if_fail()ing in
the rendernode creation code, and by erroring out in the rendernode
parser.

I try too much dumb stuff in the node editor.
2023-07-03 22:02:44 +02:00
Benjamin Otte ce5d74d7df glcontext: Fix typo in Apple extension name 2023-07-03 22:02:44 +02:00
Matthias Clasen 5bcc943ec3 Post-release version bump 2023-07-03 14:56:49 -04:00
Matthias Clasen f5d68bb586 4.11.4 2023-07-03 14:12:53 -04:00
Chun-wei Fan 6d1537647c tools/generate-uac-manifest.py: Fix formatting
As this script is now also used in GLib, unify the formatting between
GLib and GTK. Make the formatting of the script conformant to the
Black[1] tool, as GLib requires, and add a copyright header to this
script.

[1]: https://black.readthedocs.io/en/stable/, see also
$(glibsrcroot)/.gitlab-ci/run-bash.sh
2023-07-03 12:50:55 +08:00
Matthias Clasen ae2c10996a Merge branch 'fix_atcontext_refleaks' into 'main'
a11y: Fix some GtkATContext reference leaks

See merge request GNOME/gtk!6160
2023-07-01 18:06:19 +00:00
Barnabás Pőcze 81e9de3778 a11y: Fix some GtkATContext reference leaks
`gtk_accessible_get_at_context()` is transfer-full, so the returned
reference needs to be dropped. This was missing in a couple places.
2023-07-01 16:40:11 +02:00
Chun-wei Fan 42a704fefb Merge branch 'gdk-win32-input-fixes' into 'main'
GdkWin32 input fixes

Closes #5877

See merge request GNOME/gtk!6131
2023-06-30 04:33:08 +00:00
Matthias Clasen e57eaf16b4 Merge branch 'wip/chergert/map-as-sectionmodel' into 'main'
maplistmodel: implement GtkSectionModel

See merge request GNOME/gtk!6154
2023-06-30 01:50:07 +00:00
Matthias Clasen 9aabb0e98d Add section model tests for GtkMapListModel 2023-06-29 21:30:11 -04:00
Matthias Clasen 9590a5f45e maplistmodel: Handle the ::sections-changed signal
Wrapper section models need to listen to and pass
on the ::sections-changed signal from the underlying
model.
2023-06-29 21:29:11 -04:00
Daniel Boles 7bee50c4f6 Image: Fix missing closing backtick 2023-06-29 14:33:29 +01:00
Matthias Clasen bad2324318 Merge branch 'dboles/gtk-demo_dnd_dark' into 'main'
gtk-demo/dnd: Fix, generalise detecting dark theme

See merge request GNOME/gtk!6157
2023-06-29 10:26:41 +00:00
Matthias Clasen dd15accb79 Merge branch 'matthiasc/for-main' into 'main'
build: Try harder to work with nongnu ld

See merge request GNOME/gtk!6159
2023-06-28 23:31:41 +00:00
Matthias Clasen 1d1f35576a build: Try harder to work with nongnu ld
Only try to be fast with gnu ld.
2023-06-28 16:54:34 -04:00
Daniel Boles 15458b5af3 gtk-demo/dnd: Fix, generalise detecting dark theme
Our default theme is now Default, not Adwaita, & HighContrastInverse was
renamed to Default-hc. So these checks did not work anymore. Rather than
hard-coding the new names, & possibly running into the same issue again,
we can just look for the convention of appending -dark to the theme name
and/or the Settings:prefer-dark-theme prop. The latter, we can & likely
SHOULD also apply to all themes - not just ours as before. We also check
for the :dark suffix as that means the theme variant - & before checking
GtkSettings check the GTK_THEME env var, just as GtkSettings itself does
2023-06-28 14:40:06 +01:00
Matthias Clasen 5ffe9a68ed Merge branch 'matthiasc/for-main' into 'main'
build: Move objcopy checks to one place

Closes #5672

See merge request GNOME/gtk!6156
2023-06-28 12:06:49 +00:00
Matthias Clasen f341bd563b build: Look for ld.bfd
The objcopy+ld approach to fast resource building
relies on behavior that is specific to the binutils
linker, and does not work with the llvm one.

Therefore, check for ld.bfd. We still fall back
to trying with just ld, since I'm not 100% sure
if binutils unconditionally installs ld.bfd.

Fixes: #5672
2023-06-28 07:12:07 -04:00
Matthias Clasen 70edacc68d build: Move objcopy checks to one place
We were doing the same thing in three places.
Move it to the toplevel meson.build, so we
can change it in one place.
2023-06-28 07:11:51 -04:00
Matthias Clasen 091176ae48 Updates 2023-06-28 06:47:32 -04:00
Matthias Clasen d9cfb94a80 Merge branch 'fix_dropdown_set_expression' into 'main'
GtkDropDown: Force redisplay of the drop-down items after expression change

See merge request GNOME/gtk!6145
2023-06-28 09:57:04 +00:00
Lukáš Tyrychtr 3c7ca28f1f dropdown: Handle expression changes
The expression is used by the default factory, so we
need to track whether we are using the default factory
and recreate it if the expression changes.
2023-06-28 08:18:01 +02:00
Matthias Clasen 25e518326c Merge branch 'matthiasc/for-main' into 'main'
Plug a memory leak in gsk_render_node_serialize

See merge request GNOME/gtk!6155
2023-06-28 02:42:47 +00:00
Matthias Clasen a853307fb7 ci: Ignore more leaks in dependencies
libxkbcommon shows up quite a bit in leak sanitizer
reports. Ignore it.
2023-06-27 22:08:22 -04:00
Matthias Clasen 0ae541671d gsk: Plug a memory leak in mask node fallback
We were forgetting to free the mask pattern.
Found by asan.
2023-06-27 21:54:15 -04:00
Matthias Clasen ef0d6c7290 gsk: Plug a memory leak in the gl renderer
Found by asan.
2023-06-27 21:52:08 -04:00
Matthias Clasen 2217509701 Plug a memory leak in gsk tests
Pointed out by asan.
2023-06-27 21:48:12 -04:00
Matthias Clasen 16e46a73f3 Plug a memory leak in gsk_render_node_serialize
This was introduced in 0d6a6a5997 with named
textures.
2023-06-27 21:43:17 -04:00
Christian Hergert 32a3690a3c maplistmodel: implement GtkSectionModel
This just wraps the underlying GListModel if it is a GtkSectionModel.
2023-06-27 18:08:20 -07:00
Benjamin Otte 526771751f Merge branch 'dboles/issue5922-DropTarget-reject-enter-critical' into 'main'
DropTarget: Fix critical if `reject()` drop before `::enter`

Closes #5922

See merge request GNOME/gtk!6152
2023-06-27 21:30:03 +00:00
Daniel Boles dfa6591675 DropTarget: Fix critical if reject drop pre-enter
Fixes https://gitlab.gnome.org/GNOME/gtk/-/issues/5922

The docs of `Gtk.DropTarget::accept` say this:
> If the decision whether the drop will be accepted or rejected depends
> on the data, [`::accept`] should return `TRUE`, [`:preload`] should be
> set and the value should be inspected via the `::notify:value` signal,
> calling `gtk_drop_target_reject()` if required.

But this pattern causes a CRITICAL, given these steps:
* Create a `DragSource` and `DropTarget`
* Keep the default `::accept` handler and set `:preload` to `TRUE`
* Connect to `notify::value` and therein call `DropTarget.reject()`
* CRITICAL at `DropTarget.enter()`→`Drop.get_actions()` on NULL instance

We should let the documented case work without a CRITICAL or worse, null
deref. And per @otte on the bug, we should bail earlier before `::enter`
& setting `GTK_STATE_FLAG_DROP_ACTIVE`; neither should occur if rejected

This fixes that, by checking after `start_drop()` when notifications are
thawed, whether any handler has `reject()`ed & set our `drop` to `NULL`.
2023-06-27 21:37:32 +01:00
Daniel Boles 6252517aac DropTarget: Fix if block indented 1 step too far 2023-06-27 21:37:20 +01:00
Matthias Clasen 51e440fa03 Merge branch 'fix-asan-ifunc' into 'main'
Fix fp16 with asan

See merge request GNOME/gtk!6153
2023-06-27 19:55:28 +00:00
Matthias Clasen d82fb6f20a Fix fp16 with asan
The IFUNC resolvers that we are using here get
run early, before asan had a chance to set up its
plumbing, and therefore things go badly if they
are compiled with asan. Turning it off makes things
work again.

The gcc bug tracking this problem:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110442

Thanks to Jakub Jelinek and Florian Weimer for
analyzing this and recommending the workaround.
2023-06-27 15:17:56 -04:00
Matthias Clasen 44de6a6cbe Merge branch 'wip/sadiq/fix-use-after-free' into 'main'
gldriver: Fix a possible use-after-free

See merge request GNOME/gtk!6151
2023-06-27 18:46:28 +00:00
Mohammed Sadiq 64e27cd87d gldriver: Fix a possible use-after-free
g_hash_table_insert() frees the given key if it already exists
in the hashtable.  But since we use the same pointer in the
following line, it will result in use-after-free.

So instead, insert the key only if it doesn't exist.
2023-06-27 22:45:07 +05:30
Benjamin Otte 60e75f8a2a Merge branch 'wip/otte/for-vulkan' into 'main'
vulkan: Generate vertex array headers from shaders

See merge request GNOME/gtk!6149
2023-06-27 16:20:29 +00:00
Matthias Clasen 57eda94dde Merge branch 'matthiasc/for-main' into 'main'
gtk4-builder-tool: Fix naming

See merge request GNOME/gtk!6150
2023-06-27 11:24:08 +00:00
Matthias Clasen 723fb6c8be gtk4-builder-tool: Fix naming
We install the tool as gtk4-builder-tool, so that
is what it should call itself.

String change.
2023-06-27 07:09:04 -04:00
Benjamin Otte 6c85ed1ba1 vulkan: Generate vertex array headers from shaders
The script is pretty dumb but it does its job.
2023-06-27 07:11:48 +02:00
Benjamin Otte 2e58274f23 vulkan: Rename crossfade => cross-fade
Preparation for the future.
2023-06-27 06:46:57 +02:00
Benjamin Otte 4ade0afe03 vulkan: Rename blendmode to blend-mode
Preparation for future changes, nothing to see here.
2023-06-27 06:46:57 +02:00
Benjamin Otte 93fb45c689 Merge branch 'wip/otte/vulkan-for-main' into 'main'
vulkan: Add a pipeline cache

See merge request GNOME/gtk!6148
2023-06-26 18:52:48 +00:00
Benjamin Otte 684a015c98 vulkan: Add a pipeline cache
Make the display handle the cache, because we only need one.

We store the cache in
  $CACHE_DIR/gtk-4.0/vulkan-pipeline-cache/$UUID.$VERSION
so we regenerate caches for each different device (different UUID) and
each different driver version.

We also keep track of the etag of the cache file, so if 2 different
applications update the cache, we can detect that.
Vulkan allows merging caches, so the 2nd app reloads the new cache file
and merges it into its cache before saving.
2023-06-26 20:28:11 +02:00
Matthias Clasen f7fcd2e425 Merge branch 'main' into 'main'
Add settable search match mode in dropdown

See merge request GNOME/gtk!6146
2023-06-26 18:18:14 +00:00
Matthias Clasen c6c637fe21 Merge branch 'matthiasc/for-main' into 'main'
buildertool: Make render an alias for screenshot

See merge request GNOME/gtk!6147
2023-06-26 15:38:32 +00:00
Matthias Clasen 33fc4d6495 buildertool: Make render an alias for screenshot
Its a more neutral name and will align better with
other tools.
2023-06-26 10:58:35 -04:00
al_SeveR 33ff927522 Add settable search match mode in dropdown 2023-06-26 14:14:39 +00: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
Luca Bacci 43af0ee514 Define this_module with (void) argument
Fixes a compiler warning about K&R (old-style) function definition
2023-06-21 16:18:40 +02:00
Luca Bacci 3912d6aba9 GdkWin32: Fix keyboard state for WinPointer input
The dwKeyStates field of the POINTER_INFO structure
is always set to 0, no matter what. Use GetKeyState
instead.

Forward-port of !4327 to GTK4
2023-06-21 16:18:01 +02:00
Luca Bacci 871685e271 GdkWin32: Use double coordinates for mouse events
Mouse coordinates reported by the system are still integers,
but go sub-pixel when dividing by the window scale factor.
2023-06-21 16:07:55 +02:00
Luca Bacci 5e9daa9728 GdkWin32: Unscaled coordinates in current_root_x, current_root_y
Also modify gdk_win32_surface_do_move_resize_drag() to take
unscaled root coordinates.

Fixes #5877
2023-06-21 16:01:42 +02:00
Luca Bacci 412bc1713a GdkWin32: Keep track of the last cursor position in move / resize contexts
...and avoid doing any work if the position hasn't changed.
2023-06-21 15:31:48 +02:00
110 changed files with 4262 additions and 3329 deletions
+2
View File
@@ -0,0 +1,2 @@
[flake8]
ignore = E501
+34 -4
View File
@@ -1,4 +1,7 @@
Overview of Changes in 4.11.4, xx-xx-xxxx
Overview of Changes in 4.11.5, xx-xx-xxxx
=========================================
Overview of Changes in 4.11.4, 03-07-2023
=========================================
* GtkFileChooser:
@@ -20,16 +23,31 @@ Overview of Changes in 4.11.4, xx-xx-xxxx
* GtkWindow:
- Clear the resize cursors to avoid artifacts
* GtkFileDialog:
- Always set initial-folder
* GtkDropDown:
- Update on expression changes
* GtkMapListModel:
- Implement GtkSectionModel
* Accessibility:
- Improvements all over the place: GtkButton, GtkPasswordEntry,
GtkFontChooserDialog, GtkColorChooserDialog, GtkShortcutsWindow,
GtkMenuButton, GtkAboutDialog, GtkFileChooserDialog, GtkStackSidebar,
GtkMediaControls, GtkColorDialogButton, GtkDropDown, GtkInfoBar,
GtkNotebook, GtkPrintUnixDialog, GtkModelButton
GtkStackSwitcher, GtkMediaControls, GtkColorDialogButton, GtkDropDown,
GtkInfoBar, GtkNotebook, GtkPrintUnixDialog, GtkModelButton
- Make name computation follow the ARIA spec more closely
- Adapt name computation for the common 'nested button' scenario
- Change many containers to use `generic` instead of `group`
- Use `generic` as the default role
- Use `application` instead of `window` for windows
- Add properties for accessible names of not directly exposed
widgets in GtkListView, GtkGridView and GtkColumnView
* DND:
- Fix criticals when drops are rejected
* X11:
- Fix regressions in GLX setup
@@ -42,19 +60,31 @@ Overview of Changes in 4.11.4, xx-xx-xxxx
- Do less work on clipped away nodes
- Redo image uploading
- Support different image depths and formats
- Add a pipeline cache
* Demos:
- gtk4-demo: Improve window sizing
- gtk4-demo: Improve focus behavior
- gtk4-demo: Add many missing a11y properties
`
* Tools:
- gtk4-builder-tool: Make render an alias screenshot
* Inspector:
- Show more information in the a11y tab
- Add an accessibility overlay with warnings and recommendations
- Limit the width of the a11y tab
* Build:
- Require GLib 2.76
- Make asan builds work again
- Fix the build if ld is not ld.bdf
* Translation updates:
Brazilian Portuguese
Catalan
Czech
Georgian
Overview of Changes in 4.11.3, 05-06-2023
+19 -7
View File
@@ -162,27 +162,39 @@ click_done (GtkGesture *gesture)
gtk_widget_insert_after (item, canvas, last_child);
}
/* GtkSettings treats `GTK_THEME=foo:dark` as theme name `foo`, variant `dark`,
* and our embedded CSS files let `foo-dark` work as an alias for `foo:dark`. */
static gboolean
has_dark_suffix (const char *theme)
{
return g_str_has_suffix (theme, ":dark") ||
g_str_has_suffix (theme, "-dark");
}
/* So we can make a good guess whether the current theme is dark by checking for
* either: it is suffixed `[:-]dark`, or Settings:…prefer-dark-theme is TRUE. */
static gboolean
theme_is_dark (void)
{
const char *env_theme;
GtkSettings *settings;
char *theme;
gboolean prefer_dark;
gboolean dark;
/* Like GtkSettings, 1st see if theme is overridden by environment variable */
env_theme = g_getenv ("GTK_THEME");
if (env_theme != NULL)
return has_dark_suffix (env_theme);
/* If not, test Settings:…theme-name in the same way OR :…prefer-dark-theme */
settings = gtk_settings_get_default ();
g_object_get (settings,
"gtk-theme-name", &theme,
"gtk-application-prefer-dark-theme", &prefer_dark,
NULL);
if ((strcmp (theme, "Adwaita") == 0 && prefer_dark) || strcmp (theme, "HighContrastInverse") == 0)
dark = TRUE;
else
dark = FALSE;
dark = prefer_dark || has_dark_suffix (theme);
g_free (theme);
return dark;
}
+1 -11
View File
@@ -158,17 +158,7 @@ demos_h = custom_target('gtk4 demo header',
command: [ find_program('geninclude.py'), '@OUTPUT@', '@INPUT@' ],
)
objcopy_supports_add_symbol = false
objcopy = find_program('objcopy', required : false)
if objcopy.found()
objcopy_supports_add_symbol = run_command(objcopy, '--help', check: false).stdout().contains('--add-symbol')
endif
ld = find_program('ld', required : false)
if not meson.is_cross_build() and build_machine.cpu_family() != 'arm' and build_machine.system() == 'linux' and objcopy.found() and objcopy_supports_add_symbol and ld.found()
glib_compile_resources = find_program('glib-compile-resources')
if can_use_objcopy_for_resources
# Create the resource blob
gtkdemo_gresource = custom_target('gtkdemo.gresource',
input : 'demo.gresource.xml',
+1 -11
View File
@@ -1,16 +1,6 @@
# demos/widget-factory
objcopy_supports_add_symbol = false
objcopy = find_program('objcopy', required : false)
if objcopy.found()
objcopy_supports_add_symbol = run_command(objcopy, '--help', check: false).stdout().contains('--add-symbol')
endif
ld = find_program('ld', required : false)
if not meson.is_cross_build() and build_machine.cpu_family() != 'arm' and build_machine.system() == 'linux' and objcopy.found() and objcopy_supports_add_symbol and ld.found()
glib_compile_resources = find_program('glib-compile-resources')
if can_use_objcopy_for_resources
# Create the resource blob
widgetfactory_gresource = custom_target('widgetfactory.gresource',
input : 'widget-factory.gresource.xml',
+31
View File
@@ -153,6 +153,35 @@ get_busy (GSimpleAction *action,
gtk_widget_set_sensitive (window, FALSE);
}
static void
search_button_tooltip_show (GtkWidget *self,
GtkTooltip *tooltip)
{
static int style = 0;
if (style == 0)
{
gtk_tooltip_set_css_class (tooltip, "red-tooltip");
style++;
}
else if (style == 1)
{
gtk_tooltip_set_css_class (tooltip, "yellow-tooltip");
style++;
}
else
{
style = 0;
}
}
static void
search_button_tooltip_hide (GtkWidget *self,
GtkTooltip *tooltip)
{
gtk_tooltip_set_css_class (tooltip, NULL);
}
static int current_page = 0;
static gboolean
on_page (int i)
@@ -2221,6 +2250,8 @@ activate (GApplication *app)
gtk_builder_cscope_add_callback (scope, level_scale_value_changed);
gtk_builder_cscope_add_callback (scope, transition_speed_changed);
gtk_builder_cscope_add_callback (scope, reset_icon_size);
gtk_builder_cscope_add_callback (scope, search_button_tooltip_show);
gtk_builder_cscope_add_callback (scope, search_button_tooltip_hide);
gtk_builder_set_scope (builder, scope);
g_object_unref (scope);
if (!gtk_builder_add_from_resource (builder, "/org/gtk/WidgetFactory4/widget-factory.ui", &error))
+9
View File
@@ -6,3 +6,12 @@
.toolbar {
-gtk-icon-style: symbolic;
}
.red-tooltip {
background-color: red;
}
.yellow-tooltip {
background-color: yellow;
color: black;
}
+11 -1
View File
@@ -257,7 +257,9 @@
</object>
<object class="GtkTextBuffer" id="textbuffer1">
<property name="tag-table">tags</property>
<property name="text">Lorem ipsum dolor sit amet, consectetur adipiscing elit.
<property name="text">Search button above will display its tooltip in an alternating red, yellow and default style.
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Nullam fringilla, est ut feugiat ultrices, elit lacus ultricies nibh, id commodo tortor nisi id elit.
Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.
Morbi vel elit erat. Maecenas dignissim, dui et pharetra rutrum, tellus lectus rutrum mi, a convallis libero nisi quis tellus.
@@ -1572,6 +1574,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 +1589,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
@@ -1915,6 +1923,8 @@ microphone-sensitivity-medium-symbolic</property>
<property name="icon-name">edit-find</property>
<property name="action-name">win.search</property>
<property name="tooltip-text" translatable="1">Search for it</property>
<signal name="tooltip-show" handler="search_button_tooltip_show"/>
<signal name="tooltip-hide" handler="search_button_tooltip_hide"/>
</object>
</child>
<child>
+10 -5
View File
@@ -16,6 +16,7 @@ SYNOPSIS
| **gtk4-builder-tool** enumerate [OPTIONS...] <FILE>
| **gtk4-builder-tool** simplify [OPTIONS...] <FILE>
| **gtk4-builder-tool** preview [OPTIONS...] <FILE>
| **gtk4-builder-tool** render [OPTIONS...] <FILE>
| **gtk4-builder-tool** screenshot [OPTIONS...] <FILE>
DESCRIPTION
@@ -69,12 +70,11 @@ file to use.
Load style information from the given CSS file.
Screenshot
^^^^^^^^^^
Render
^^^^^^
The ``screenshot`` command saves a rendering of the UI definition file
as a png image or node file. The name of the file to write can be specified as
a second FILE argument.
The ``render`` command saves a rendering of the UI definition file as a png image
or node file. The name of the file to write can be specified as a second FILE argument.
This command accepts options to specify the ID of the toplevel object and a CSS
file to use.
@@ -96,6 +96,11 @@ file to use.
Overwrite an existing file.
Screenshot
^^^^^^^^^^
The ``screenshot`` command is an alias for ``render``.
Simplification
^^^^^^^^^^^^^^
+3
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
@@ -382,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.
+10 -6
View File
@@ -30,12 +30,12 @@ Views display data from a **_model_**. Models implement the [`iface@Gio.ListMode
interface and can be provided in a variety of ways:
* List model implementations for many specific types of data already exist, for
example `GtkDirectoryList` or `GtkStringList`.
example [`class@Gtk.DirectoryList`] or [`class@Gtk.StringList`].
* There are generic list model implementations like`GListStore` that allow building
* There are generic list model implementations like [`class@Gio.ListStore`] that allow building
lists of arbitrary objects.
* Wrapping list models like `GtkFilterListModel` or `GtkSortListModel`
* Wrapping list models like [`class@Gtk.FilterListModel`] or [`class@Gtk.SortListModel`]
modify, adapt or combine other models.
* Last but not least, developers are encouraged to create their own `GListModel`
@@ -133,8 +133,8 @@ tradeoffs of those and experiment with them.
GTK offers a wide variety of wrapping models which change or supplement an
existing model (or models) in some way. But when it comes to storing your
actual data, there are only a few ready-made choices available: [`class@Gio.ListStore`]
and [`class@Gtk.StringList`].
actual data, there are only a few ready-made choices available:
[`class@Gio.ListStore`], [`class@Gtk.StringList`], and [`class@Gtk.DirectoryList`].
`GListStore` is backed by a balanced tree and has performance characteristics
that are expected for that data structure. It works reasonably well for dataset
@@ -147,6 +147,10 @@ that are expected for that data structure. `GtkStringList` is a good fit for any
place where you would otherwise use `char*[]` and works best if the dataset
is not very dynamic.
`GtkDirectoryList` is a list model that wraps [`method@Gio.File.enumerate_children_async`].
It presents a `GListModel` and fills it asynchronously with the [`iface@Gio.File`]s
returned from that function.
If these models don't fit your use case or scalability requirements, you
should make a custom `GListModel` implementation. It is a small interface and
not very hard to implement.
@@ -199,7 +203,7 @@ the `.data-table` style class.
## Sections
List models can optionally group their items into **_sections_**, by implementing
the `GtkSectionModel` interface. Both `GtkListView` and `GtkGridView` can
the `GtkSectionModel` interface. `GtkListView` can
display headers for sections, by installing a separate **_header factory_**.
Many GTK list models support section inherently, or they pass through the
+4
View File
@@ -100,6 +100,10 @@ struct _GdkDisplay
VkDevice vk_device;
VkQueue vk_queue;
uint32_t vk_queue_family_index;
VkPipelineCache vk_pipeline_cache;
gsize vk_pipeline_cache_size;
char *vk_pipeline_cache_etag;
guint vk_save_pipeline_cache_source;
guint vulkan_refcount;
#endif /* GDK_RENDERING_VULKAN */
+1 -1
View File
@@ -1552,7 +1552,7 @@ gdk_gl_context_check_extensions (GdkGLContext *context)
priv->has_sync = gdk_gl_context_check_version (context, "3.2", "3.0") ||
epoxy_has_gl_extension ("GL_ARB_sync") ||
epoxy_has_gl_extension ("GK_APPLE_sync");
epoxy_has_gl_extension ("GL_APPLE_sync");
#ifdef G_ENABLE_DEBUG
{
+2 -1
View File
@@ -25,7 +25,8 @@
* multiple frames, and will be used for a long time.
*
* There are various ways to create `GdkTexture` objects from a
* [class@GdkPixbuf.Pixbuf], or a Cairo surface, or other pixel data.
* [class@GdkPixbuf.Pixbuf], or from bytes stored in memory, a file, or a
* [struct@Gio.Resource].
*
* The ownership of the pixel data is transferred to the `GdkTexture`
* instance; you can only make a copy of it, via [method@Gdk.Texture.download].
+222
View File
@@ -931,6 +931,216 @@ gdk_vulkan_context_get_queue_family_index (GdkVulkanContext *context)
return gdk_draw_context_get_display (GDK_DRAW_CONTEXT (context))->vk_queue_family_index;
}
static char *
gdk_vulkan_get_pipeline_cache_dirname (void)
{
return g_build_filename (g_get_user_cache_dir (), "gtk-4.0", "vulkan-pipeline-cache", NULL);
}
static GFile *
gdk_vulkan_get_pipeline_cache_file (GdkDisplay *display)
{
VkPhysicalDeviceProperties props;
char *dirname, *basename, *path;
GFile *result;
vkGetPhysicalDeviceProperties (display->vk_physical_device, &props);
dirname = gdk_vulkan_get_pipeline_cache_dirname ();
basename = g_strdup_printf ("%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x"
"-%02x%02x%02x%02x%02x%02x.%u",
props.pipelineCacheUUID[0], props.pipelineCacheUUID[1],
props.pipelineCacheUUID[2], props.pipelineCacheUUID[3],
props.pipelineCacheUUID[4], props.pipelineCacheUUID[5],
props.pipelineCacheUUID[6], props.pipelineCacheUUID[7],
props.pipelineCacheUUID[8], props.pipelineCacheUUID[9],
props.pipelineCacheUUID[10], props.pipelineCacheUUID[11],
props.pipelineCacheUUID[12], props.pipelineCacheUUID[13],
props.pipelineCacheUUID[14], props.pipelineCacheUUID[15],
props.driverVersion);
path = g_build_filename (dirname, basename, NULL);
result = g_file_new_for_path (path);
g_free (path);
g_free (basename);
g_free (dirname);
return result;
}
static VkPipelineCache
gdk_display_load_pipeline_cache (GdkDisplay *display)
{
GError *error = NULL;
VkPipelineCache result;
GFile *cache_file;
char *etag, *data;
gsize size;
cache_file = gdk_vulkan_get_pipeline_cache_file (display);
if (!g_file_load_contents (cache_file, NULL, &data, &size, &etag, &error))
{
GDK_DEBUG (VULKAN, "failed to load Vulkan pipeline cache file '%s': %s\n",
g_file_peek_path (cache_file), error->message);
g_object_unref (cache_file);
g_clear_error (&error);
return VK_NULL_HANDLE;
}
if (GDK_VK_CHECK (vkCreatePipelineCache, display->vk_device,
&(VkPipelineCacheCreateInfo) {
.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO,
.initialDataSize = size,
.pInitialData = data,
},
NULL,
&result) != VK_SUCCESS)
result = VK_NULL_HANDLE;
g_free (data);
g_free (display->vk_pipeline_cache_etag);
display->vk_pipeline_cache_etag = etag;
display->vk_pipeline_cache_size = size;
return result;
}
static gboolean
gdk_vulkan_save_pipeline_cache (GdkDisplay *display)
{
GError *error = NULL;
VkDevice device;
VkPipelineCache cache;
GFile *file;
char *path;
size_t size;
char *data, *etag;
device = display->vk_device;
cache = display->vk_pipeline_cache;
GDK_VK_CHECK (vkGetPipelineCacheData, device, cache, &size, NULL);
if (size == 0)
return TRUE;
if (size == display->vk_pipeline_cache_size)
{
GDK_DEBUG (VULKAN, "pipeline cache size (%zu bytes) unchanged, skipping save", size);
return TRUE;
}
data = g_malloc (size);
if (GDK_VK_CHECK (vkGetPipelineCacheData, device, cache, &size, data) != VK_SUCCESS)
{
g_free (data);
return FALSE;
}
path = gdk_vulkan_get_pipeline_cache_dirname ();
if (g_mkdir_with_parents (path, 0755) != 0)
{
g_warning_once ("Failed to create pipeline cache directory");
g_free (path);
return FALSE;
}
g_free (path);
file = gdk_vulkan_get_pipeline_cache_file (display);
GDK_DEBUG (VULKAN, "Saving pipeline cache to %s", g_file_peek_path (file));
if (!g_file_replace_contents (file,
data,
size,
display->vk_pipeline_cache_etag,
FALSE,
0,
&etag,
NULL,
&error))
{
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_WRONG_ETAG))
{
VkPipelineCache new_cache;
GDK_DEBUG (VULKAN, "Pipeline cache file modified, merging into current");
new_cache = gdk_display_load_pipeline_cache (display);
if (new_cache)
{
GDK_VK_CHECK (vkMergePipelineCaches, device, cache, 1, &new_cache);
vkDestroyPipelineCache (device, new_cache, NULL);
}
else
{
g_clear_pointer (&display->vk_pipeline_cache_etag, g_free);
}
g_clear_error (&error);
g_object_unref (file);
/* try again */
return gdk_vulkan_save_pipeline_cache (display);
}
g_warning ("Failed to save pipeline cache: %s", error->message);
g_clear_error (&error);
g_object_unref (file);
return FALSE;
}
g_object_unref (file);
g_free (display->vk_pipeline_cache_etag);
display->vk_pipeline_cache_etag = etag;
return TRUE;
}
static gboolean
gdk_vulkan_save_pipeline_cache_cb (gpointer data)
{
GdkDisplay *display = data;
gdk_vulkan_save_pipeline_cache (display);
display->vk_save_pipeline_cache_source = 0;
return G_SOURCE_REMOVE;
}
void
gdk_vulkan_context_pipeline_cache_updated (GdkVulkanContext *self)
{
GdkDisplay *display = gdk_draw_context_get_display (GDK_DRAW_CONTEXT (self));
g_clear_handle_id (&display->vk_save_pipeline_cache_source, g_source_remove);
display->vk_save_pipeline_cache_source = g_timeout_add_seconds_full (G_PRIORITY_DEFAULT_IDLE - 10,
10, /* random choice that is not now */
gdk_vulkan_save_pipeline_cache_cb,
display,
NULL);
}
static void
gdk_display_create_pipeline_cache (GdkDisplay *display)
{
display->vk_pipeline_cache = gdk_display_load_pipeline_cache (display);
GDK_VK_CHECK (vkCreatePipelineCache, display->vk_device,
&(VkPipelineCacheCreateInfo) {
.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO,
},
NULL,
&display->vk_pipeline_cache);
}
VkPipelineCache
gdk_vulkan_context_get_pipeline_cache (GdkVulkanContext *self)
{
g_return_val_if_fail (GDK_IS_VULKAN_CONTEXT (self), NULL);
return gdk_draw_context_get_display (GDK_DRAW_CONTEXT (self))->vk_pipeline_cache;
}
/**
* gdk_vulkan_context_get_image_format:
* @context: a `GdkVulkanContext`
@@ -1381,6 +1591,8 @@ gdk_display_create_vulkan_instance (GdkDisplay *display,
return FALSE;
}
gdk_display_create_pipeline_cache (display);
return TRUE;
}
@@ -1409,6 +1621,16 @@ gdk_display_unref_vulkan (GdkDisplay *display)
if (display->vulkan_refcount > 0)
return;
if (display->vk_save_pipeline_cache_source)
{
gdk_vulkan_save_pipeline_cache_cb (display);
g_assert (display->vk_save_pipeline_cache_source == 0);
}
vkDestroyPipelineCache (display->vk_device, display->vk_pipeline_cache, NULL);
display->vk_device = VK_NULL_HANDLE;
g_clear_pointer (&display->vk_pipeline_cache_etag, g_free);
display->vk_pipeline_cache_size = 0;
vkDestroyDevice (display->vk_device, NULL);
display->vk_device = VK_NULL_HANDLE;
if (display->vk_debug_callback != VK_NULL_HANDLE)
+3
View File
@@ -73,6 +73,9 @@ gboolean gdk_display_ref_vulkan (GdkDisp
GError **error);
void gdk_display_unref_vulkan (GdkDisplay *display);
VkPipelineCache gdk_vulkan_context_get_pipeline_cache (GdkVulkanContext *self);
void gdk_vulkan_context_pipeline_cache_updated (GdkVulkanContext *self);
GdkMemoryFormat gdk_vulkan_context_get_offscreen_format (GdkVulkanContext *context,
GdkMemoryDepth depth);
+2 -2
View File
@@ -3064,9 +3064,9 @@ tablet_tool_handle_button (void *data,
tablet->pointer_info.press_serial = serial;
if (button == BTN_STYLUS)
n_button = GDK_BUTTON_SECONDARY;
else if (button == BTN_STYLUS2)
n_button = GDK_BUTTON_MIDDLE;
else if (button == BTN_STYLUS2)
n_button = GDK_BUTTON_SECONDARY;
else if (button == BTN_STYLUS3)
n_button = 8; /* Back */
else
+15 -15
View File
@@ -139,7 +139,6 @@ static GSourceFuncs event_funcs = {
static GdkSurface *mouse_window = NULL;
static GdkSurface *mouse_window_ignored_leave = NULL;
static int current_x, current_y;
static int current_root_x, current_root_y;
static UINT got_gdk_events_message;
@@ -1522,14 +1521,15 @@ generate_button_event (GdkEventType type,
GdkEvent *event;
GdkDeviceManagerWin32 *device_manager;
GdkWin32Surface *impl = GDK_WIN32_SURFACE (window);
double x, y;
if (_gdk_input_ignore_core > 0)
return;
device_manager = GDK_DEVICE_MANAGER_WIN32 (_gdk_device_manager);
current_x = (gint16) GET_X_LPARAM (msg->lParam) / impl->surface_scale;
current_y = (gint16) GET_Y_LPARAM (msg->lParam) / impl->surface_scale;
x = (double) GET_X_LPARAM (msg->lParam) / impl->surface_scale;
y = (double) GET_Y_LPARAM (msg->lParam) / impl->surface_scale;
_gdk_device_virtual_set_active (_gdk_device_manager->core_pointer,
_gdk_device_manager->system_pointer);
@@ -1541,10 +1541,10 @@ generate_button_event (GdkEventType type,
_gdk_win32_get_next_tick (msg->time),
build_pointer_event_state (msg),
button,
current_x,
current_y,
x,
y,
NULL);
_gdk_win32_append_event (event);
}
@@ -2350,19 +2350,19 @@ gdk_event_translate (MSG *msg,
* sends WM_MOUSEMOVE messages after a new window is shown under
* the mouse, even if the mouse hasn't moved. This disturbs gtk.
*/
if (msg->pt.x / impl->surface_scale == current_root_x &&
msg->pt.y / impl->surface_scale == current_root_y)
if (msg->pt.x == current_root_x &&
msg->pt.y == current_root_y)
break;
current_root_x = msg->pt.x / impl->surface_scale;
current_root_y = msg->pt.y / impl->surface_scale;
current_root_x = msg->pt.x;
current_root_y = msg->pt.y;
if (impl->drag_move_resize_context.op != GDK_WIN32_DRAGOP_NONE)
gdk_win32_surface_do_move_resize_drag (window, current_root_x, current_root_y);
gdk_win32_surface_do_move_resize_drag (window, msg->pt.x, msg->pt.y);
else if (_gdk_input_ignore_core == 0)
{
current_x = (gint16) GET_X_LPARAM (msg->lParam) / impl->surface_scale;
current_y = (gint16) GET_Y_LPARAM (msg->lParam) / impl->surface_scale;
double x = (double) GET_X_LPARAM (msg->lParam) / impl->surface_scale;
double y = (double) GET_Y_LPARAM (msg->lParam) / impl->surface_scale;
_gdk_device_virtual_set_active (_gdk_device_manager->core_pointer,
_gdk_device_manager->system_pointer);
@@ -2372,8 +2372,8 @@ gdk_event_translate (MSG *msg,
NULL,
_gdk_win32_get_next_tick (msg->time),
build_pointer_event_state (msg),
current_x,
current_y,
x,
y,
NULL);
_gdk_win32_append_event (event);
+3 -2
View File
@@ -271,9 +271,10 @@ winpointer_make_event (GdkDeviceWinpointer *device,
y /= impl->surface_scale;
state = 0;
if (info->dwKeyStates & POINTER_MOD_CTRL)
/* Note that info->dwKeyStates is not reliable, use GetKeyState() */
if (GetKeyState (VK_CONTROL) < 0)
state |= GDK_CONTROL_MASK;
if (info->dwKeyStates & POINTER_MOD_SHIFT)
if (GetKeyState (VK_SHIFT) < 0)
state |= GDK_SHIFT_MASK;
if (GetKeyState (VK_MENU) < 0)
state |= GDK_ALT_MASK;
+12
View File
@@ -3535,6 +3535,8 @@ setup_drag_move_resize_context (GdkSurface *surface,
context->button = button;
context->start_root_x = root_x;
context->start_root_y = root_y;
context->current_root_x = root_x;
context->current_root_y = root_y;
context->timestamp = timestamp;
context->start_rect = rect;
@@ -3650,6 +3652,16 @@ gdk_win32_surface_do_move_resize_drag (GdkSurface *window,
if (!_gdk_win32_get_window_rect (window, &rect))
return;
x /= impl->surface_scale;
y /= impl->surface_scale;
if (context->current_root_x == x &&
context->current_root_y == y)
return;
context->current_root_x = x;
context->current_root_y = y;
new_rect = context->start_rect;
diffx = (x - context->start_root_x) * impl->surface_scale;
diffy = (y - context->start_root_y) * impl->surface_scale;
+6
View File
@@ -137,6 +137,12 @@ struct _GdkW32DragMoveResizeContext
int start_root_x;
int start_root_y;
/* Last processed cursor position. Values are divided by the window
* scale.
*/
int current_root_x;
int current_root_y;
/* Initial window rectangle (position and size).
* The window is resized/moved relative to this (see start_root_*).
*/
+4 -4
View File
@@ -165,7 +165,7 @@ void half_to_float4 (const guint16 h[4], float f[4]) __attribute__((ifunc ("reso
void float_to_half (const float *f, guint16 *h, int n) __attribute__((ifunc ("resolve_float_to_half")));
void half_to_float (const guint16 *h, float *f, int n) __attribute__((ifunc ("resolve_half_to_float")));
static void *
static void * __attribute__ ((no_sanitize_address))
resolve_float_to_half4 (void)
{
__builtin_cpu_init ();
@@ -175,7 +175,7 @@ resolve_float_to_half4 (void)
return float_to_half4_c;
}
static void *
static void * __attribute__ ((no_sanitize_address))
resolve_half_to_float4 (void)
{
__builtin_cpu_init ();
@@ -185,7 +185,7 @@ resolve_half_to_float4 (void)
return half_to_float4_c;
}
static void *
static void * __attribute__ ((no_sanitize_address))
resolve_float_to_half (void)
{
__builtin_cpu_init ();
@@ -195,7 +195,7 @@ resolve_float_to_half (void)
return float_to_half_c;
}
static void *
static void * __attribute__ ((no_sanitize_address))
resolve_half_to_float (void)
{
__builtin_cpu_init ();
+9 -5
View File
@@ -686,17 +686,21 @@ gsk_gl_driver_cache_texture (GskGLDriver *self,
const GskTextureKey *key,
guint texture_id)
{
GskTextureKey *k;
g_assert (GSK_IS_GL_DRIVER (self));
g_assert (key != NULL);
g_assert (texture_id > 0);
g_assert (g_hash_table_contains (self->textures, GUINT_TO_POINTER (texture_id)));
k = g_memdup (key, sizeof *key);
if (!g_hash_table_contains (self->key_to_texture_id, key))
{
GskTextureKey *k;
g_hash_table_insert (self->key_to_texture_id, k, GUINT_TO_POINTER (texture_id));
g_hash_table_insert (self->texture_id_to_key, GUINT_TO_POINTER (texture_id), k);
k = g_memdup (key, sizeof *key);
g_assert (!g_hash_table_contains (self->texture_id_to_key, GUINT_TO_POINTER (texture_id)));
g_hash_table_insert (self->key_to_texture_id, k, GUINT_TO_POINTER (texture_id));
g_hash_table_insert (self->texture_id_to_key, GUINT_TO_POINTER (texture_id), k);
}
}
/**
+2
View File
@@ -803,6 +803,8 @@ gsk_gl_render_job_untransform_bounds (GskGLRenderJob *job,
out_rect->origin.x -= job->offset_x;
out_rect->origin.y -= job->offset_y;
gsk_transform_unref (transform);
}
static inline void
+8 -2
View File
@@ -13,6 +13,12 @@ void main() {
uniform int u_mode;
uniform sampler2D u_mask;
float
luminance (vec3 color)
{
return dot (vec3 (0.2126, 0.7152, 0.0722), color);
}
void main() {
vec4 source = GskTexture(u_source, vUv);
vec4 mask = GskTexture(u_mask, vUv);
@@ -23,9 +29,9 @@ void main() {
else if (u_mode == 1)
mask_value = 1.0 - mask.a;
else if (u_mode == 2)
mask_value = (0.2126 * mask.r + 0.7152 * mask.g + 0.0722 * mask.b) * mask.a;
mask_value = luminance (mask.rgb);
else if (u_mode == 3)
mask_value = 1.0 - (0.2126 * mask.r + 0.7152 * mask.g + 0.0722 * mask.b) * mask.a;
mask_value = mask.a - luminance (mask.rgb);
else
mask_value = 0.0;
+67 -29
View File
@@ -2421,6 +2421,7 @@ gsk_inset_shadow_node_new (const GskRoundedRect *outline,
g_return_val_if_fail (outline != NULL, NULL);
g_return_val_if_fail (color != NULL, NULL);
g_return_val_if_fail (blur_radius >= 0, NULL);
self = gsk_render_node_alloc (GSK_INSET_SHADOW_NODE);
node = (GskRenderNode *) self;
@@ -2696,7 +2697,7 @@ gsk_outset_shadow_node_diff (GskRenderNode *node1,
static void
gsk_outset_shadow_node_class_init (gpointer g_class,
gpointer class_data)
gpointer class_data)
{
GskRenderNodeClass *node_class = g_class;
@@ -2734,6 +2735,7 @@ gsk_outset_shadow_node_new (const GskRoundedRect *outline,
g_return_val_if_fail (outline != NULL, NULL);
g_return_val_if_fail (color != NULL, NULL);
g_return_val_if_fail (blur_radius >= 0, NULL);
self = gsk_render_node_alloc (GSK_OUTSET_SHADOW_NODE);
node = (GskRenderNode *) self;
@@ -3700,8 +3702,7 @@ gsk_color_matrix_node_finalize (GskRenderNode *node)
static void
apply_color_matrix_to_pattern (cairo_pattern_t *pattern,
const graphene_matrix_t *color_matrix,
const graphene_vec4_t *color_offset,
gboolean multiply_alpha)
const graphene_vec4_t *color_offset)
{
cairo_surface_t *surface, *image_surface;
guchar *data;
@@ -3739,13 +3740,6 @@ apply_color_matrix_to_pattern (cairo_pattern_t *pattern,
graphene_matrix_transform_vec4 (color_matrix, &pixel, &pixel);
}
if (multiply_alpha)
graphene_vec4_init (&pixel,
graphene_vec4_get_x (&pixel),
graphene_vec4_get_y (&pixel),
graphene_vec4_get_z (&pixel),
alpha * graphene_vec4_get_w (&pixel));
graphene_vec4_add (&pixel, color_offset, &pixel);
alpha = graphene_vec4_get_w (&pixel);
@@ -3768,6 +3762,8 @@ apply_color_matrix_to_pattern (cairo_pattern_t *pattern,
cairo_surface_mark_dirty (image_surface);
cairo_surface_unmap_image (surface, image_surface);
/* https://gitlab.freedesktop.org/cairo/cairo/-/merge_requests/487 */
cairo_surface_mark_dirty (surface);
}
static void
@@ -3789,7 +3785,7 @@ gsk_color_matrix_node_draw (GskRenderNode *node,
pattern = cairo_pop_group (cr);
apply_color_matrix_to_pattern (pattern, &self->color_matrix, &self->color_offset, FALSE);
apply_color_matrix_to_pattern (pattern, &self->color_matrix, &self->color_offset);
cairo_set_source (cr, pattern);
cairo_paint (cr);
@@ -5650,6 +5646,50 @@ gsk_mask_node_finalize (GskRenderNode *node)
parent_class->finalize (node);
}
static void
apply_luminance_to_pattern (cairo_pattern_t *pattern,
gboolean invert_luminance)
{
cairo_surface_t *surface, *image_surface;
guchar *data;
gsize x, y, width, height, stride;
int red, green, blue, alpha, luminance;
guint32* pixel_data;
cairo_pattern_get_surface (pattern, &surface);
image_surface = cairo_surface_map_to_image (surface, NULL);
data = cairo_image_surface_get_data (image_surface);
width = cairo_image_surface_get_width (image_surface);
height = cairo_image_surface_get_height (image_surface);
stride = cairo_image_surface_get_stride (image_surface);
for (y = 0; y < height; y++)
{
pixel_data = (guint32 *) data;
for (x = 0; x < width; x++)
{
alpha = (pixel_data[x] >> 24) & 0xFF;
red = (pixel_data[x] >> 16) & 0xFF;
green = (pixel_data[x] >> 8) & 0xFF;
blue = (pixel_data[x] >> 0) & 0xFF;
luminance = 2126 * red + 7152 * green + 722 * blue;
if (invert_luminance)
luminance = 10000 * alpha - luminance;
luminance = (luminance + 5000) / 10000;
pixel_data[x] = luminance * 0x1010101;
}
data += stride;
}
cairo_surface_mark_dirty (image_surface);
cairo_surface_unmap_image (surface, image_surface);
/* https://gitlab.freedesktop.org/cairo/cairo/-/merge_requests/487 */
cairo_surface_mark_dirty (surface);
}
static void
gsk_mask_node_draw (GskRenderNode *node,
cairo_t *cr)
@@ -5672,28 +5712,18 @@ gsk_mask_node_draw (GskRenderNode *node,
case GSK_MASK_MODE_ALPHA:
break;
case GSK_MASK_MODE_INVERTED_ALPHA:
graphene_matrix_init_from_float (&color_matrix, (float[]){ 1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, -1 });
graphene_vec4_init (&color_offset, 0, 0, 0, 1);
apply_color_matrix_to_pattern (mask_pattern, &color_matrix, &color_offset, FALSE);
graphene_matrix_init_from_float (&color_matrix, (float[]){ 0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
-1, -1, -1, -1 });
graphene_vec4_init (&color_offset, 1, 1, 1, 1);
apply_color_matrix_to_pattern (mask_pattern, &color_matrix, &color_offset);
break;
case GSK_MASK_MODE_LUMINANCE:
graphene_matrix_init_from_float (&color_matrix, (float[]){ 1, 0, 0, 0.2126,
0, 1, 0, 0.7152,
0, 0, 1, 0.0722,
0, 0, 0, 0 });
graphene_vec4_init (&color_offset, 0, 0, 0, 0);
apply_color_matrix_to_pattern (mask_pattern, &color_matrix, &color_offset, TRUE);
apply_luminance_to_pattern (mask_pattern, FALSE);
break;
case GSK_MASK_MODE_INVERTED_LUMINANCE:
graphene_matrix_init_from_float (&color_matrix, (float[]){ 1, 0, 0, -0.2126,
0, 1, 0, -0.7152,
0, 0, 1, -0.0722,
0, 0, 0, 0 });
graphene_vec4_init (&color_offset, 0, 0, 0, 1);
apply_color_matrix_to_pattern (mask_pattern, &color_matrix, &color_offset, TRUE);
apply_luminance_to_pattern (mask_pattern, TRUE);
break;
default:
g_assert_not_reached ();
@@ -5703,6 +5733,8 @@ gsk_mask_node_draw (GskRenderNode *node,
cairo_clip (cr);
cairo_mask (cr, mask_pattern);
cairo_pattern_destroy (mask_pattern);
}
static void
@@ -5713,6 +5745,12 @@ gsk_mask_node_diff (GskRenderNode *node1,
GskMaskNode *self1 = (GskMaskNode *) node1;
GskMaskNode *self2 = (GskMaskNode *) node2;
if (self1->mask_mode != self2->mask_mode)
{
gsk_render_node_diff_impossible (node1, node2, region);
return;
}
gsk_render_node_diff (self1->source, self2->source, region);
gsk_render_node_diff (self1->mask, self2->mask, region);
}
+37 -8
View File
@@ -453,6 +453,21 @@ parse_double (GtkCssParser *parser,
return gtk_css_parser_consume_number (parser, out_double);
}
static gboolean
parse_positive_double (GtkCssParser *parser,
Context *context,
gpointer out_double)
{
if (gtk_css_parser_has_token (parser, GTK_CSS_TOKEN_SIGNED_NUMBER)
|| gtk_css_parser_has_token (parser, GTK_CSS_TOKEN_SIGNED_INTEGER))
{
gtk_css_parser_error_syntax (parser, "Expected a positive number");
return FALSE;
}
return gtk_css_parser_consume_number (parser, out_double);
}
static gboolean
parse_point (GtkCssParser *parser,
Context *context,
@@ -1242,10 +1257,10 @@ parse_radial_gradient_node_internal (GtkCssParser *parser,
const Declaration declarations[] = {
{ "bounds", parse_rect, NULL, &bounds },
{ "center", parse_point, NULL, &center },
{ "hradius", parse_double, NULL, &hradius },
{ "vradius", parse_double, NULL, &vradius },
{ "start", parse_double, NULL, &start },
{ "end", parse_double, NULL, &end },
{ "hradius", parse_positive_double, NULL, &hradius },
{ "vradius", parse_positive_double, NULL, &vradius },
{ "start", parse_positive_double, NULL, &start },
{ "end", parse_positive_double, NULL, &end },
{ "stops", parse_stops, clear_stops, &stops },
};
GskRenderNode *result;
@@ -1335,7 +1350,7 @@ parse_inset_shadow_node (GtkCssParser *parser,
{ "dx", parse_double, NULL, &dx },
{ "dy", parse_double, NULL, &dy },
{ "spread", parse_double, NULL, &spread },
{ "blur", parse_double, NULL, &blur }
{ "blur", parse_positive_double, NULL, &blur }
};
parse_declarations (parser, context, declarations, G_N_ELEMENTS (declarations));
@@ -1737,7 +1752,7 @@ parse_outset_shadow_node (GtkCssParser *parser,
{ "dx", parse_double, NULL, &dx },
{ "dy", parse_double, NULL, &dy },
{ "spread", parse_double, NULL, &spread },
{ "blur", parse_double, NULL, &blur }
{ "blur", parse_positive_double, NULL, &blur }
};
parse_declarations (parser, context, declarations, G_N_ELEMENTS (declarations));
@@ -2017,7 +2032,7 @@ parse_blur_node (GtkCssParser *parser,
GskRenderNode *child = NULL;
double blur_radius = 1.0;
const Declaration declarations[] = {
{ "blur", parse_double, NULL, &blur_radius },
{ "blur", parse_positive_double, NULL, &blur_radius },
{ "child", parse_node, clear_node, &child },
};
GskRenderNode *result;
@@ -2477,6 +2492,15 @@ printer_init (Printer *self,
printer_init_duplicates_for_node (self, node);
}
static void
printer_clear (Printer *self)
{
if (self->str)
g_string_free (self->str, TRUE);
g_hash_table_unref (self->named_nodes);
g_hash_table_unref (self->named_textures);
}
#define IDENT_LEVEL 2 /* Spaces per level */
static void
_indent (Printer *self)
@@ -3686,6 +3710,7 @@ GBytes *
gsk_render_node_serialize (GskRenderNode *node)
{
Printer p;
GBytes *res;
printer_init (&p, node);
@@ -3705,5 +3730,9 @@ gsk_render_node_serialize (GskRenderNode *node)
render_node_print (&p, node);
}
return g_string_free_to_bytes (p.str);
res = g_string_free_to_bytes (g_steal_pointer (&p.str));
printer_clear (&p);
return res;
}
+2
View File
@@ -103,6 +103,7 @@ gsk_private_vulkan_shaders = []
# on constantly regenerated files.
gsk_private_vulkan_compiled_shaders = []
gsk_private_vulkan_compiled_shaders_deps = []
gsk_private_vulkan_shader_headers = []
if have_vulkan
gsk_private_sources += files([
@@ -197,6 +198,7 @@ libgsk = static_library('gsk',
gsk_private_sources,
gsk_enums,
gskresources,
gsk_private_vulkan_shader_headers,
],
dependencies: gsk_deps,
include_directories: [ confinc, ],
+3 -78
View File
@@ -2,6 +2,8 @@
#include "gskvulkanblendmodepipelineprivate.h"
#include "vulkan/resources/blend-mode.vert.h"
struct _GskVulkanBlendModePipeline
{
GObject parent_instance;
@@ -9,89 +11,12 @@ struct _GskVulkanBlendModePipeline
typedef struct _GskVulkanBlendModeInstance GskVulkanBlendModeInstance;
struct _GskVulkanBlendModeInstance
{
float rect[4];
float top_rect[4];
float bottom_rect[4];
float top_tex_rect[4];
float bottom_tex_rect[4];
guint32 top_tex_id[2];
guint32 bottom_tex_id[2];
guint32 blend_mode;
};
G_DEFINE_TYPE (GskVulkanBlendModePipeline, gsk_vulkan_blend_mode_pipeline, GSK_TYPE_VULKAN_PIPELINE)
static const VkPipelineVertexInputStateCreateInfo *
gsk_vulkan_blend_mode_pipeline_get_input_state_create_info (GskVulkanPipeline *self)
{
static const VkVertexInputBindingDescription vertexBindingDescriptions[] = {
{
.binding = 0,
.stride = sizeof (GskVulkanBlendModeInstance),
.inputRate = VK_VERTEX_INPUT_RATE_INSTANCE
}
};
static const VkVertexInputAttributeDescription vertexInputAttributeDescription[] = {
{
.location = 0,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = 0,
},
{
.location = 1,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanBlendModeInstance, top_rect),
},
{
.location = 2,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanBlendModeInstance, bottom_rect),
},
{
.location = 3,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanBlendModeInstance, top_tex_rect),
},
{
.location = 4,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanBlendModeInstance, bottom_tex_rect),
},
{
.location = 5,
.binding = 0,
.format = VK_FORMAT_R32_UINT,
.offset = G_STRUCT_OFFSET (GskVulkanBlendModeInstance, top_tex_id),
},
{
.location = 6,
.binding = 0,
.format = VK_FORMAT_R32G32_UINT,
.offset = G_STRUCT_OFFSET (GskVulkanBlendModeInstance, bottom_tex_id),
},
{
.location = 7,
.binding = 0,
.format = VK_FORMAT_R32G32_UINT,
.offset = G_STRUCT_OFFSET (GskVulkanBlendModeInstance, blend_mode),
}
};
static const VkPipelineVertexInputStateCreateInfo info = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
.vertexBindingDescriptionCount = G_N_ELEMENTS (vertexBindingDescriptions),
.pVertexBindingDescriptions = vertexBindingDescriptions,
.vertexAttributeDescriptionCount = G_N_ELEMENTS (vertexInputAttributeDescription),
.pVertexAttributeDescriptions = vertexInputAttributeDescription
};
return &info;
return &gsk_vulkan_blend_mode_info;
}
static void
+5 -54
View File
@@ -2,68 +2,19 @@
#include "gskvulkanblurpipelineprivate.h"
#include "vulkan/resources/blur.vert.h"
struct _GskVulkanBlurPipeline
{
GObject parent_instance;
};
typedef struct _GskVulkanBlurInstance GskVulkanBlurInstance;
struct _GskVulkanBlurInstance
{
float rect[4];
float tex_rect[4];
float blur_radius;
guint32 tex_id[2];
};
G_DEFINE_TYPE (GskVulkanBlurPipeline, gsk_vulkan_blur_pipeline, GSK_TYPE_VULKAN_PIPELINE)
static const VkPipelineVertexInputStateCreateInfo *
gsk_vulkan_blur_pipeline_get_input_state_create_info (GskVulkanPipeline *self)
{
static const VkVertexInputBindingDescription vertexBindingDescriptions[] = {
{
.binding = 0,
.stride = sizeof (GskVulkanBlurInstance),
.inputRate = VK_VERTEX_INPUT_RATE_INSTANCE
}
};
static const VkVertexInputAttributeDescription vertexInputAttributeDescription[] = {
{
.location = 0,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = 0,
},
{
.location = 1,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanBlurInstance, tex_rect),
},
{
.location = 2,
.binding = 0,
.format = VK_FORMAT_R32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanBlurInstance, blur_radius),
},
{
.location = 3,
.binding = 0,
.format = VK_FORMAT_R32G32_UINT,
.offset = G_STRUCT_OFFSET (GskVulkanBlurInstance, tex_id),
}
};
static const VkPipelineVertexInputStateCreateInfo info = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
.vertexBindingDescriptionCount = G_N_ELEMENTS (vertexBindingDescriptions),
.pVertexBindingDescriptions = vertexBindingDescriptions,
.vertexAttributeDescriptionCount = G_N_ELEMENTS (vertexInputAttributeDescription),
.pVertexAttributeDescriptions = vertexInputAttributeDescription
};
return &info;
return &gsk_vulkan_blur_info;
}
static void
@@ -105,7 +56,7 @@ gsk_vulkan_blur_pipeline_collect_vertex_data (GskVulkanBlurPipeline *pipeline,
const graphene_point_t *offset,
const graphene_rect_t *rect,
const graphene_rect_t *tex_rect,
double blur_radius)
double radius)
{
GskVulkanBlurInstance *instance = (GskVulkanBlurInstance *) data;
@@ -117,7 +68,7 @@ gsk_vulkan_blur_pipeline_collect_vertex_data (GskVulkanBlurPipeline *pipeline,
instance->tex_rect[1] = tex_rect->origin.y;
instance->tex_rect[2] = tex_rect->size.width;
instance->tex_rect[3] = tex_rect->size.height;
instance->blur_radius = blur_radius;
instance->radius = radius;
instance->tex_id[0] = tex_id[0];
instance->tex_id[1] = tex_id[1];
}
+8 -80
View File
@@ -4,91 +4,19 @@
#include "gskroundedrectprivate.h"
#include "vulkan/resources/border.vert.h"
struct _GskVulkanBorderPipeline
{
GObject parent_instance;
};
typedef struct _GskVulkanBorderInstance GskVulkanBorderInstance;
struct _GskVulkanBorderInstance
{
float rect[12];
float widths[4];
float colors[16];
};
G_DEFINE_TYPE (GskVulkanBorderPipeline, gsk_vulkan_border_pipeline, GSK_TYPE_VULKAN_PIPELINE)
static const VkPipelineVertexInputStateCreateInfo *
gsk_vulkan_border_pipeline_get_input_state_create_info (GskVulkanPipeline *self)
{
static const VkVertexInputBindingDescription vertexBindingDescriptions[] = {
{
.binding = 0,
.stride = sizeof (GskVulkanBorderInstance),
.inputRate = VK_VERTEX_INPUT_RATE_INSTANCE
}
};
static const VkVertexInputAttributeDescription vertexInputAttributeDescription[] = {
{
.location = 0,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanBorderInstance, rect),
},
{
.location = 1,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanBorderInstance, rect) + 4 * sizeof (float),
},
{
.location = 2,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanBorderInstance, rect) + 8 * sizeof (float),
},
{
.location = 3,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanBorderInstance, widths),
},
{
.location = 4,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanBorderInstance, colors),
},
{
.location = 5,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanBorderInstance, colors) + 4 * sizeof (float),
},
{
.location = 6,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanBorderInstance, colors) + 8 * sizeof (float),
},
{
.location = 7,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanBorderInstance, colors) + 12 * sizeof (float),
}
};
static const VkPipelineVertexInputStateCreateInfo info = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
.vertexBindingDescriptionCount = G_N_ELEMENTS (vertexBindingDescriptions),
.pVertexBindingDescriptions = vertexBindingDescriptions,
.vertexAttributeDescriptionCount = G_N_ELEMENTS (vertexInputAttributeDescription),
.pVertexAttributeDescriptions = vertexInputAttributeDescription
};
return &info;
return &gsk_vulkan_border_info;
}
static void
@@ -137,11 +65,11 @@ gsk_vulkan_border_pipeline_collect_vertex_data (GskVulkanBorderPipeline *pipelin
gsk_rounded_rect_to_float (rect, offset, instance->rect);
for (i = 0; i < 4; i++)
{
instance->widths[i] = widths[i];
instance->colors[4 * i + 0] = colors[i].red;
instance->colors[4 * i + 1] = colors[i].green;
instance->colors[4 * i + 2] = colors[i].blue;
instance->colors[4 * i + 3] = colors[i].alpha;
instance->border_widths[i] = widths[i];
instance->border_colors[4 * i + 0] = colors[i].red;
instance->border_colors[4 * i + 1] = colors[i].green;
instance->border_colors[4 * i + 2] = colors[i].blue;
instance->border_colors[4 * i + 3] = colors[i].alpha;
}
}
+4 -72
View File
@@ -2,6 +2,8 @@
#include "gskvulkanboxshadowpipelineprivate.h"
#include "vulkan/resources/inset-shadow.vert.h"
#include "gskroundedrectprivate.h"
struct _GskVulkanBoxShadowPipeline
@@ -9,82 +11,12 @@ struct _GskVulkanBoxShadowPipeline
GObject parent_instance;
};
typedef struct _GskVulkanBoxShadowInstance GskVulkanBoxShadowInstance;
struct _GskVulkanBoxShadowInstance
{
float outline[12];
float color[4];
float offset[2];
float spread;
float blur_radius;
};
G_DEFINE_TYPE (GskVulkanBoxShadowPipeline, gsk_vulkan_box_shadow_pipeline, GSK_TYPE_VULKAN_PIPELINE)
static const VkPipelineVertexInputStateCreateInfo *
gsk_vulkan_box_shadow_pipeline_get_input_state_create_info (GskVulkanPipeline *self)
{
static const VkVertexInputBindingDescription vertexBindingDescriptions[] = {
{
.binding = 0,
.stride = sizeof (GskVulkanBoxShadowInstance),
.inputRate = VK_VERTEX_INPUT_RATE_INSTANCE
}
};
static const VkVertexInputAttributeDescription vertexInputAttributeDescription[] = {
{
.location = 0,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanBoxShadowInstance, outline),
},
{
.location = 1,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanBoxShadowInstance, outline) + 4 * sizeof (float),
},
{
.location = 2,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanBoxShadowInstance, outline) + 8 * sizeof (float),
},
{
.location = 3,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanBoxShadowInstance, color),
},
{
.location = 4,
.binding = 0,
.format = VK_FORMAT_R32G32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanBoxShadowInstance, offset),
},
{
.location = 5,
.binding = 0,
.format = VK_FORMAT_R32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanBoxShadowInstance, spread),
},
{
.location = 6,
.binding = 0,
.format = VK_FORMAT_R32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanBoxShadowInstance, blur_radius),
}
};
static const VkPipelineVertexInputStateCreateInfo info = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
.vertexBindingDescriptionCount = G_N_ELEMENTS (vertexBindingDescriptions),
.pVertexBindingDescriptions = vertexBindingDescriptions,
.vertexAttributeDescriptionCount = G_N_ELEMENTS (vertexInputAttributeDescription),
.pVertexAttributeDescriptions = vertexInputAttributeDescription
};
return &info;
return &gsk_vulkan_inset_shadow_info;
}
static void
@@ -130,7 +62,7 @@ gsk_vulkan_box_shadow_pipeline_collect_vertex_data (GskVulkanBoxShadowPipeline *
float spread,
float blur_radius)
{
GskVulkanBoxShadowInstance *instance = (GskVulkanBoxShadowInstance *) data;
GskVulkanInsetShadowInstance *instance = (GskVulkanInsetShadowInstance *) data;
gsk_rounded_rect_to_float (outline, offset, instance->outline);
instance->color[0] = color->red;
+3 -38
View File
@@ -2,54 +2,19 @@
#include "gskvulkancolorpipelineprivate.h"
#include "vulkan/resources/color.vert.h"
struct _GskVulkanColorPipeline
{
GObject parent_instance;
};
typedef struct _GskVulkanColorInstance GskVulkanColorInstance;
struct _GskVulkanColorInstance
{
float rect[4];
float color[4];
};
G_DEFINE_TYPE (GskVulkanColorPipeline, gsk_vulkan_color_pipeline, GSK_TYPE_VULKAN_PIPELINE)
static const VkPipelineVertexInputStateCreateInfo *
gsk_vulkan_color_pipeline_get_input_state_create_info (GskVulkanPipeline *self)
{
static const VkVertexInputBindingDescription vertexBindingDescriptions[] = {
{
.binding = 0,
.stride = sizeof (GskVulkanColorInstance),
.inputRate = VK_VERTEX_INPUT_RATE_INSTANCE
}
};
static const VkVertexInputAttributeDescription vertexInputAttributeDescription[] = {
{
.location = 0,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = 0,
},
{
.location = 1,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanColorInstance, color),
}
};
static const VkPipelineVertexInputStateCreateInfo info = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
.vertexBindingDescriptionCount = G_N_ELEMENTS (vertexBindingDescriptions),
.pVertexBindingDescriptions = vertexBindingDescriptions,
.vertexAttributeDescriptionCount = G_N_ELEMENTS (vertexInputAttributeDescription),
.pVertexAttributeDescriptions = vertexInputAttributeDescription
};
return &info;
return &gsk_vulkan_color_info;
}
static void
+5 -47
View File
@@ -2,61 +2,19 @@
#include "gskvulkancolortextpipelineprivate.h"
#include "vulkan/resources/texture.vert.h"
struct _GskVulkanColorTextPipeline
{
GObject parent_instance;
};
typedef struct _GskVulkanColorTextInstance GskVulkanColorTextInstance;
struct _GskVulkanColorTextInstance
{
float rect[4];
float tex_rect[4];
guint32 tex_id[2];
};
G_DEFINE_TYPE (GskVulkanColorTextPipeline, gsk_vulkan_color_text_pipeline, GSK_TYPE_VULKAN_PIPELINE)
static const VkPipelineVertexInputStateCreateInfo *
gsk_vulkan_color_text_pipeline_get_input_state_create_info (GskVulkanPipeline *self)
{
static const VkVertexInputBindingDescription vertexBindingDescriptions[] = {
{
.binding = 0,
.stride = sizeof (GskVulkanColorTextInstance),
.inputRate = VK_VERTEX_INPUT_RATE_INSTANCE
}
};
static const VkVertexInputAttributeDescription vertexInputAttributeDescription[] = {
{
.location = 0,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanColorTextInstance, rect),
},
{
.location = 1,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanColorTextInstance, tex_rect),
},
{
.location = 2,
.binding = 0,
.format = VK_FORMAT_R32G32_UINT,
.offset = G_STRUCT_OFFSET (GskVulkanColorTextInstance, tex_id),
}
};
static const VkPipelineVertexInputStateCreateInfo info = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
.vertexBindingDescriptionCount = G_N_ELEMENTS (vertexBindingDescriptions),
.pVertexBindingDescriptions = vertexBindingDescriptions,
.vertexAttributeDescriptionCount = G_N_ELEMENTS (vertexInputAttributeDescription),
.pVertexAttributeDescriptions = vertexInputAttributeDescription
};
return &info;
return &gsk_vulkan_texture_info;
}
static void
@@ -105,7 +63,7 @@ gsk_vulkan_color_text_pipeline_collect_vertex_data (GskVulkanColorTextPipeline *
guint num_glyphs,
float scale)
{
GskVulkanColorTextInstance *instances = (GskVulkanColorTextInstance *) data;
GskVulkanTextureInstance *instances = (GskVulkanTextureInstance *) data;
int i;
int count = 0;
int x_position = 0;
@@ -121,7 +79,7 @@ gsk_vulkan_color_text_pipeline_collect_vertex_data (GskVulkanColorTextPipeline *
{
double cx = (x_position + gi->geometry.x_offset) / PANGO_SCALE;
double cy = gi->geometry.y_offset / PANGO_SCALE;
GskVulkanColorTextInstance *instance = &instances[count];
GskVulkanTextureInstance *instance = &instances[count];
GskVulkanCachedGlyph *glyph;
glyph = gsk_vulkan_renderer_get_cached_glyph (renderer,
+3 -80
View File
@@ -2,96 +2,19 @@
#include "gskvulkancrossfadepipelineprivate.h"
#include "vulkan/resources/cross-fade.vert.h"
struct _GskVulkanCrossFadePipeline
{
GObject parent_instance;
};
typedef struct _GskVulkanCrossFadeInstance GskVulkanCrossFadeInstance;
struct _GskVulkanCrossFadeInstance
{
float rect[4];
float start_rect[4];
float end_rect[4];
float start_tex_rect[4];
float end_tex_rect[4];
guint32 start_tex_id[2];
guint32 end_tex_id[2];
float progress;
};
G_DEFINE_TYPE (GskVulkanCrossFadePipeline, gsk_vulkan_cross_fade_pipeline, GSK_TYPE_VULKAN_PIPELINE)
static const VkPipelineVertexInputStateCreateInfo *
gsk_vulkan_cross_fade_pipeline_get_input_state_create_info (GskVulkanPipeline *self)
{
static const VkVertexInputBindingDescription vertexBindingDescriptions[] = {
{
.binding = 0,
.stride = sizeof (GskVulkanCrossFadeInstance),
.inputRate = VK_VERTEX_INPUT_RATE_INSTANCE
}
};
static const VkVertexInputAttributeDescription vertexInputAttributeDescription[] = {
{
.location = 0,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = 0,
},
{
.location = 1,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanCrossFadeInstance, start_rect),
},
{
.location = 2,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanCrossFadeInstance, end_rect),
},
{
.location = 3,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanCrossFadeInstance, start_tex_rect),
},
{
.location = 4,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanCrossFadeInstance, end_tex_rect),
},
{
.location = 5,
.binding = 0,
.format = VK_FORMAT_R32G32_UINT,
.offset = G_STRUCT_OFFSET (GskVulkanCrossFadeInstance, start_tex_id),
},
{
.location = 6,
.binding = 0,
.format = VK_FORMAT_R32G32_UINT,
.offset = G_STRUCT_OFFSET (GskVulkanCrossFadeInstance, end_tex_id),
},
{
.location = 7,
.binding = 0,
.format = VK_FORMAT_R32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanCrossFadeInstance, progress),
}
};
static const VkPipelineVertexInputStateCreateInfo info = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
.vertexBindingDescriptionCount = G_N_ELEMENTS (vertexBindingDescriptions),
.pVertexBindingDescriptions = vertexBindingDescriptions,
.vertexAttributeDescriptionCount = G_N_ELEMENTS (vertexInputAttributeDescription),
.pVertexAttributeDescriptions = vertexInputAttributeDescription
};
return &info;
return &gsk_vulkan_cross_fade_info;
}
static void
+4 -78
View File
@@ -2,93 +2,19 @@
#include "gskvulkaneffectpipelineprivate.h"
#include "vulkan/resources/color-matrix.vert.h"
struct _GskVulkanEffectPipeline
{
GObject parent_instance;
};
typedef struct _GskVulkanEffectInstance GskVulkanEffectInstance;
struct _GskVulkanEffectInstance
{
float rect[4];
float tex_rect[4];
float color_matrix[16];
float color_offset[4];
guint32 tex_id[2];
};
G_DEFINE_TYPE (GskVulkanEffectPipeline, gsk_vulkan_effect_pipeline, GSK_TYPE_VULKAN_PIPELINE)
static const VkPipelineVertexInputStateCreateInfo *
gsk_vulkan_effect_pipeline_get_input_state_create_info (GskVulkanPipeline *self)
{
static const VkVertexInputBindingDescription vertexBindingDescriptions[] = {
{
.binding = 0,
.stride = sizeof (GskVulkanEffectInstance),
.inputRate = VK_VERTEX_INPUT_RATE_INSTANCE
}
};
static const VkVertexInputAttributeDescription vertexInputAttributeDescription[] = {
{
.location = 0,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = 0,
},
{
.location = 1,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanEffectInstance, tex_rect),
},
{
.location = 2,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanEffectInstance, color_matrix),
},
{
.location = 3,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanEffectInstance, color_matrix) + sizeof (float) * 4,
},
{
.location = 4,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanEffectInstance, color_matrix) + sizeof (float) * 8,
},
{
.location = 5,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanEffectInstance, color_matrix) + sizeof (float) * 12,
},
{
.location = 6,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanEffectInstance, color_offset),
},
{
.location = 7,
.binding = 0,
.format = VK_FORMAT_R32G32_UINT,
.offset = G_STRUCT_OFFSET (GskVulkanEffectInstance, tex_id),
}
};
static const VkPipelineVertexInputStateCreateInfo info = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
.vertexBindingDescriptionCount = G_N_ELEMENTS (vertexBindingDescriptions),
.pVertexBindingDescriptions = vertexBindingDescriptions,
.vertexAttributeDescriptionCount = G_N_ELEMENTS (vertexInputAttributeDescription),
.pVertexAttributeDescriptions = vertexInputAttributeDescription
};
return &info;
return &gsk_vulkan_color_matrix_info;
}
static void
@@ -133,7 +59,7 @@ gsk_vulkan_effect_pipeline_collect_vertex_data (GskVulkanEffectPipeline *pipelin
const graphene_matrix_t *color_matrix,
const graphene_vec4_t *color_offset)
{
GskVulkanEffectInstance *instance = (GskVulkanEffectInstance *) data;
GskVulkanColorMatrixInstance *instance = (GskVulkanColorMatrixInstance *) data;
instance->rect[0] = rect->origin.x + offset->x;
instance->rect[1] = rect->origin.y + offset->y;
+5 -68
View File
@@ -2,82 +2,19 @@
#include "gskvulkanlineargradientpipelineprivate.h"
#include "vulkan/resources/linear.vert.h"
struct _GskVulkanLinearGradientPipeline
{
GObject parent_instance;
};
typedef struct _GskVulkanLinearGradientInstance GskVulkanLinearGradientInstance;
struct _GskVulkanLinearGradientInstance
{
float rect[4];
float start[2];
float end[2];
gint32 repeating;
gint32 offset;
gint32 stop_count;
};
G_DEFINE_TYPE (GskVulkanLinearGradientPipeline, gsk_vulkan_linear_gradient_pipeline, GSK_TYPE_VULKAN_PIPELINE)
static const VkPipelineVertexInputStateCreateInfo *
gsk_vulkan_linear_gradient_pipeline_get_input_state_create_info (GskVulkanPipeline *self)
{
static const VkVertexInputBindingDescription vertexBindingDescriptions[] = {
{
.binding = 0,
.stride = sizeof (GskVulkanLinearGradientInstance),
.inputRate = VK_VERTEX_INPUT_RATE_INSTANCE
}
};
static const VkVertexInputAttributeDescription vertexInputAttributeDescription[] = {
{
.location = 0,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = 0,
},
{
.location = 1,
.binding = 0,
.format = VK_FORMAT_R32G32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanLinearGradientInstance, start),
},
{
.location = 2,
.binding = 0,
.format = VK_FORMAT_R32G32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanLinearGradientInstance, end),
},
{
.location = 3,
.binding = 0,
.format = VK_FORMAT_R32_SINT,
.offset = G_STRUCT_OFFSET (GskVulkanLinearGradientInstance, repeating),
},
{
.location = 4,
.binding = 0,
.format = VK_FORMAT_R32_SINT,
.offset = G_STRUCT_OFFSET (GskVulkanLinearGradientInstance, offset),
},
{
.location = 5,
.binding = 0,
.format = VK_FORMAT_R32_SINT,
.offset = G_STRUCT_OFFSET (GskVulkanLinearGradientInstance, stop_count),
}
};
static const VkPipelineVertexInputStateCreateInfo info = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
.vertexBindingDescriptionCount = G_N_ELEMENTS (vertexBindingDescriptions),
.pVertexBindingDescriptions = vertexBindingDescriptions,
.vertexAttributeDescriptionCount = G_N_ELEMENTS (vertexInputAttributeDescription),
.pVertexAttributeDescriptions = vertexInputAttributeDescription
};
return &info;
return &gsk_vulkan_linear_info;
}
static void
@@ -123,7 +60,7 @@ gsk_vulkan_linear_gradient_pipeline_collect_vertex_data (GskVulkanLinearGradient
gsize gradient_offset,
gsize n_stops)
{
GskVulkanLinearGradientInstance *instance = (GskVulkanLinearGradientInstance *) data;
GskVulkanLinearInstance *instance = (GskVulkanLinearInstance *) data;
instance->rect[0] = rect->origin.x + offset->x;
instance->rect[1] = rect->origin.y + offset->y;
@@ -134,7 +71,7 @@ gsk_vulkan_linear_gradient_pipeline_collect_vertex_data (GskVulkanLinearGradient
instance->end[0] = end->x + offset->x;
instance->end[1] = end->y + offset->y;
instance->repeating = repeating;
instance->offset = gradient_offset;
instance->stop_offset = gradient_offset;
instance->stop_count = n_stops;
}
+5 -1
View File
@@ -5,6 +5,8 @@
#include "gskvulkanpushconstantsprivate.h"
#include "gskvulkanshaderprivate.h"
#include "gdk/gdkvulkancontextprivate.h"
#include <graphene.h>
typedef struct _GskVulkanPipelinePrivate GskVulkanPipelinePrivate;
@@ -87,7 +89,7 @@ gsk_vulkan_pipeline_new (GType pipeline_type,
priv->vertex_stride = vertex_input_state->pVertexBindingDescriptions[0].stride;
GSK_VK_CHECK (vkCreateGraphicsPipelines, device,
VK_NULL_HANDLE,
gdk_vulkan_context_get_pipeline_cache (context),
1,
&(VkGraphicsPipelineCreateInfo) {
.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
@@ -160,6 +162,8 @@ gsk_vulkan_pipeline_new (GType pipeline_type,
NULL,
&priv->pipeline);
gdk_vulkan_context_pipeline_cache_updated (context);
return self;
}
+6 -6
View File
@@ -418,12 +418,12 @@ gsk_vulkan_render_get_pipeline (GskVulkanRender *self,
{ "texture", 1, gsk_vulkan_color_text_pipeline_new },
{ "texture-clip", 1, gsk_vulkan_color_text_pipeline_new },
{ "texture-clip-rounded", 1, gsk_vulkan_color_text_pipeline_new },
{ "crossfade", 2, gsk_vulkan_cross_fade_pipeline_new },
{ "crossfade-clip", 2, gsk_vulkan_cross_fade_pipeline_new },
{ "crossfade-clip-rounded", 2, gsk_vulkan_cross_fade_pipeline_new },
{ "blendmode", 2, gsk_vulkan_blend_mode_pipeline_new },
{ "blendmode-clip", 2, gsk_vulkan_blend_mode_pipeline_new },
{ "blendmode-clip-rounded", 2, gsk_vulkan_blend_mode_pipeline_new },
{ "cross-fade", 2, gsk_vulkan_cross_fade_pipeline_new },
{ "cross-fade-clip", 2, gsk_vulkan_cross_fade_pipeline_new },
{ "cross-fade-clip-rounded", 2, gsk_vulkan_cross_fade_pipeline_new },
{ "blend-mode", 2, gsk_vulkan_blend_mode_pipeline_new },
{ "blend-mode-clip", 2, gsk_vulkan_blend_mode_pipeline_new },
{ "blend-mode-clip-rounded", 2, gsk_vulkan_blend_mode_pipeline_new },
};
g_return_val_if_fail (type < GSK_VULKAN_N_PIPELINES, NULL);
+5 -54
View File
@@ -2,68 +2,19 @@
#include "gskvulkantextpipelineprivate.h"
#include "vulkan/resources/mask.vert.h"
struct _GskVulkanTextPipeline
{
GObject parent_instance;
};
typedef struct _GskVulkanTextInstance GskVulkanTextInstance;
struct _GskVulkanTextInstance
{
float rect[4];
float tex_rect[4];
float color[4];
guint32 tex_id[2];
};
G_DEFINE_TYPE (GskVulkanTextPipeline, gsk_vulkan_text_pipeline, GSK_TYPE_VULKAN_PIPELINE)
static const VkPipelineVertexInputStateCreateInfo *
gsk_vulkan_text_pipeline_get_input_state_create_info (GskVulkanPipeline *self)
{
static const VkVertexInputBindingDescription vertexBindingDescriptions[] = {
{
.binding = 0,
.stride = sizeof (GskVulkanTextInstance),
.inputRate = VK_VERTEX_INPUT_RATE_INSTANCE
}
};
static const VkVertexInputAttributeDescription vertexInputAttributeDescription[] = {
{
.location = 0,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanTextInstance, rect),
},
{
.location = 1,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanTextInstance, tex_rect),
},
{
.location = 2,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanTextInstance, color),
},
{
.location = 3,
.binding = 0,
.format = VK_FORMAT_R32G32_UINT,
.offset = G_STRUCT_OFFSET (GskVulkanTextInstance, tex_id),
}
};
static const VkPipelineVertexInputStateCreateInfo info = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
.vertexBindingDescriptionCount = G_N_ELEMENTS (vertexBindingDescriptions),
.pVertexBindingDescriptions = vertexBindingDescriptions,
.vertexAttributeDescriptionCount = G_N_ELEMENTS (vertexInputAttributeDescription),
.pVertexAttributeDescriptions = vertexInputAttributeDescription
};
return &info;
return &gsk_vulkan_mask_info;
}
static void
@@ -113,7 +64,7 @@ gsk_vulkan_text_pipeline_collect_vertex_data (GskVulkanTextPipeline *pipeline,
guint num_glyphs,
float scale)
{
GskVulkanTextInstance *instances = (GskVulkanTextInstance *) data;
GskVulkanMaskInstance *instances = (GskVulkanMaskInstance *) data;
int i;
int count = 0;
int x_position = 0;
@@ -129,7 +80,7 @@ gsk_vulkan_text_pipeline_collect_vertex_data (GskVulkanTextPipeline *pipeline,
{
double cx = (x_position + gi->geometry.x_offset) / PANGO_SCALE;
double cy = gi->geometry.y_offset / PANGO_SCALE;
GskVulkanTextInstance *instance = &instances[count];
GskVulkanMaskInstance *instance = &instances[count];
GskVulkanCachedGlyph *glyph;
glyph = gsk_vulkan_renderer_get_cached_glyph (renderer,
+3 -45
View File
@@ -2,61 +2,19 @@
#include "gskvulkantexturepipelineprivate.h"
#include "vulkan/resources/texture.vert.h"
struct _GskVulkanTexturePipeline
{
GObject parent_instance;
};
typedef struct _GskVulkanTextureInstance GskVulkanTextureInstance;
struct _GskVulkanTextureInstance
{
float rect[4];
float tex_rect[4];
guint32 tex_id[2];
};
G_DEFINE_TYPE (GskVulkanTexturePipeline, gsk_vulkan_texture_pipeline, GSK_TYPE_VULKAN_PIPELINE)
static const VkPipelineVertexInputStateCreateInfo *
gsk_vulkan_texture_pipeline_get_input_state_create_info (GskVulkanPipeline *self)
{
static const VkVertexInputBindingDescription vertexBindingDescriptions[] = {
{
.binding = 0,
.stride = sizeof (GskVulkanTextureInstance),
.inputRate = VK_VERTEX_INPUT_RATE_INSTANCE
}
};
static const VkVertexInputAttributeDescription vertexInputAttributeDescription[] = {
{
.location = 0,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanTextureInstance, rect),
},
{
.location = 1,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanTextureInstance, tex_rect),
},
{
.location = 2,
.binding = 0,
.format = VK_FORMAT_R32G32_UINT,
.offset = G_STRUCT_OFFSET (GskVulkanTextureInstance, tex_id),
}
};
static const VkPipelineVertexInputStateCreateInfo info = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
.vertexBindingDescriptionCount = G_N_ELEMENTS (vertexBindingDescriptions),
.pVertexBindingDescriptions = vertexBindingDescriptions,
.vertexAttributeDescriptionCount = G_N_ELEMENTS (vertexInputAttributeDescription),
.pVertexAttributeDescriptions = vertexInputAttributeDescription
};
return &info;
return &gsk_vulkan_texture_info;
}
static void
+12 -14
View File
@@ -3,9 +3,7 @@
#include "clip.vert.glsl"
#include "rounded-rect.glsl"
layout(location = 0) in vec4 inRect;
layout(location = 1) in vec4 inCornerWidths;
layout(location = 2) in vec4 inCornerHeights;
layout(location = 0) in mat3x4 inRect;
layout(location = 3) in vec4 inBorderWidths;
layout(location = 4) in mat4 inBorderColors;
@@ -44,47 +42,47 @@ void main() {
int slice_index = gl_VertexIndex / 6;
int vert_index = gl_VertexIndex % 6;
vec4 corner_widths = max (inCornerWidths, inBorderWidths.wyyw);
vec4 corner_heights = max (inCornerHeights, inBorderWidths.xxzz);
vec4 corner_widths = max (inRect[1], inBorderWidths.wyyw);
vec4 corner_heights = max (inRect[2], inBorderWidths.xxzz);
Rect rect;
switch (slice_index)
{
case SLICE_TOP_LEFT:
rect = rect_from_gsk (vec4(inRect.xy, corner_widths[TOP_LEFT], corner_heights[TOP_LEFT]));
rect = rect_from_gsk (vec4(inRect[0].xy, corner_widths[TOP_LEFT], corner_heights[TOP_LEFT]));
rect = rect_round_larger (rect);
vert_index = (vert_index + 3) % 6;
break;
case SLICE_TOP:
rect = rect_from_gsk (vec4(inRect.x + corner_widths[TOP_LEFT], inRect.y, inRect.z - corner_widths[TOP_LEFT] - corner_widths[TOP_RIGHT], inBorderWidths[TOP]));
rect = rect_from_gsk (vec4(inRect[0].x + corner_widths[TOP_LEFT], inRect[0].y, inRect[0].z - corner_widths[TOP_LEFT] - corner_widths[TOP_RIGHT], inBorderWidths[TOP]));
rect = rect_round_smaller_larger (rect);
outColor = inBorderColors[TOP];
break;
case SLICE_TOP_RIGHT:
rect = rect_from_gsk (vec4(inRect.x + inRect.z - corner_widths[TOP_RIGHT], inRect.y, corner_widths[TOP_RIGHT], corner_heights[TOP_RIGHT]));
rect = rect_from_gsk (vec4(inRect[0].x + inRect[0].z - corner_widths[TOP_RIGHT], inRect[0].y, corner_widths[TOP_RIGHT], corner_heights[TOP_RIGHT]));
rect = rect_round_larger (rect);
break;
case SLICE_RIGHT:
rect = rect_from_gsk (vec4(inRect.x + inRect.z - inBorderWidths[RIGHT], inRect.y + corner_heights[TOP_RIGHT], inBorderWidths[RIGHT], inRect.w - corner_heights[TOP_RIGHT] - corner_heights[BOTTOM_RIGHT]));
rect = rect_from_gsk (vec4(inRect[0].x + inRect[0].z - inBorderWidths[RIGHT], inRect[0].y + corner_heights[TOP_RIGHT], inBorderWidths[RIGHT], inRect[0].w - corner_heights[TOP_RIGHT] - corner_heights[BOTTOM_RIGHT]));
rect = rect_round_larger_smaller (rect);
outColor = inBorderColors[RIGHT];
break;
case SLICE_BOTTOM_RIGHT:
rect = rect_from_gsk (vec4(inRect.x + inRect.z - corner_widths[BOTTOM_RIGHT], inRect.y + inRect.w - corner_heights[BOTTOM_RIGHT], corner_widths[BOTTOM_RIGHT], corner_heights[BOTTOM_RIGHT]));
rect = rect_from_gsk (vec4(inRect[0].x + inRect[0].z - corner_widths[BOTTOM_RIGHT], inRect[0].y + inRect[0].w - corner_heights[BOTTOM_RIGHT], corner_widths[BOTTOM_RIGHT], corner_heights[BOTTOM_RIGHT]));
rect = rect_round_larger (rect);
break;
case SLICE_BOTTOM:
rect = rect_from_gsk (vec4(inRect.x + corner_widths[BOTTOM_LEFT], inRect.y + inRect.w - inBorderWidths[BOTTOM], inRect.z - corner_widths[BOTTOM_LEFT] - corner_widths[BOTTOM_RIGHT], inBorderWidths[BOTTOM]));
rect = rect_from_gsk (vec4(inRect[0].x + corner_widths[BOTTOM_LEFT], inRect[0].y + inRect[0].w - inBorderWidths[BOTTOM], inRect[0].z - corner_widths[BOTTOM_LEFT] - corner_widths[BOTTOM_RIGHT], inBorderWidths[BOTTOM]));
rect = rect_round_smaller_larger (rect);
break;
case SLICE_BOTTOM_LEFT:
rect = rect_from_gsk (vec4(inRect.x, inRect.y + inRect.w - corner_heights[BOTTOM_LEFT], corner_widths[BOTTOM_LEFT], corner_heights[BOTTOM_LEFT]));
rect = rect_from_gsk (vec4(inRect[0].x, inRect[0].y + inRect[0].w - corner_heights[BOTTOM_LEFT], corner_widths[BOTTOM_LEFT], corner_heights[BOTTOM_LEFT]));
vert_index = (vert_index + 3) % 6;
rect = rect_round_larger (rect);
break;
case SLICE_LEFT:
rect = rect_from_gsk (vec4(inRect.x, inRect.y + corner_heights[TOP_LEFT], inBorderWidths[LEFT], inRect.w - corner_heights[TOP_LEFT] - corner_heights[BOTTOM_LEFT]));
rect = rect_from_gsk (vec4(inRect[0].x, inRect[0].y + corner_heights[TOP_LEFT], inBorderWidths[LEFT], inRect[0].w - corner_heights[TOP_LEFT] - corner_heights[BOTTOM_LEFT]));
rect = rect_round_larger_smaller (rect);
break;
}
@@ -99,7 +97,7 @@ void main() {
gl_Position = push.mvp * vec4 (pos, 0.0, 1.0);
outColor = inBorderColors[((gl_VertexIndex / 3 + 15) / 4) % 4];
outPos = pos;
outRect = RoundedRect(inRect.xyxy + vec4(0,0,inRect.zw), inCornerWidths, inCornerHeights);
outRect = RoundedRect(inRect[0].xyxy + vec4(0,0,inRect[0].zw), inRect[1], inRect[2]);
outRect = rounded_rect_scale (outRect, push.scale);
outBorderWidths = inBorderWidths * push.scale.yxyx;
}
+174
View File
@@ -0,0 +1,174 @@
#!/usr/bin/env python3
import sys
import re
import os
name = os.path.splitext(os.path.basename(sys.argv[1]))[0]
var_name = "gsk_vulkan_" + name.replace('-', '_')
struct_name = "GskVulkan" + name.title().replace('-', '') + "Instance"
with open(sys.argv[1]) as f:
lines = f.readlines()
matches = []
for line in lines:
match = re.search(r"^layout\(location = ([0-9]+)\) in ([a-z0-9]+) ([a-zA-Z0-9]+);$", line)
if not match:
if re.search(r"layout.*\sin\s.*", line):
raise Exception("Failed to parse file")
continue
if not match.group(3).startswith('in'):
raise Exception("Variable doesn't start with 'in'")
matches.append({'name': ''.join('_' + char.lower() if char.isupper() else char for char in match.group(3))[3:],
'location': int(match.group(1)),
'type': match.group(2)})
print(f'''/* This file is auto-generated; any change will not be preserved */
#pragma once
typedef struct _{struct_name} {struct_name};
struct _{struct_name} {{''')
expected = 0
for match in matches:
if expected != int(match['location']):
raise Exception(f"Should be layout location {expected} but is {match['location']}") # noqa
if match['type'] == 'float':
print(f" float {match['name']};")
expected += 1
elif match['type'] == 'int':
print(f" gint32 {match['name']};")
expected += 1
elif match['type'] == 'uint':
print(f" guint32 {match['name']};")
expected += 1
elif match['type'] == 'uvec2':
print(f" guint32 {match['name']}[2];")
expected += 1
elif match['type'] == 'vec2':
print(f" float {match['name']}[2];")
expected += 1
elif match['type'] == 'vec4':
print(f" float {match['name']}[4];")
expected += 1
elif match['type'] == 'mat3x4':
print(f" float {match['name']}[12];")
expected += 3
elif match['type'] == 'mat4':
print(f" float {match['name']}[16];")
expected += 4
else:
raise Exception(f"Don't know what a {match['type']} is")
print('''};
''')
print(f'''static const VkPipelineVertexInputStateCreateInfo {var_name}_info = {{
.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
.vertexBindingDescriptionCount = 1,
.pVertexBindingDescriptions = (VkVertexInputBindingDescription[1]) {{
{{
.binding = 0,
.stride = sizeof ({struct_name}),
.inputRate = VK_VERTEX_INPUT_RATE_INSTANCE
}}
}},
.vertexAttributeDescriptionCount = {expected},
.pVertexAttributeDescriptions = (VkVertexInputAttributeDescription[{expected}]) {{''')
for match in matches:
if match['type'] == 'float':
print(f''' {{
.location = {match['location']},
.binding = 0,
.format = VK_FORMAT_R32_SFLOAT,
.offset = G_STRUCT_OFFSET({struct_name}, {match['name']}),
}},''')
elif match['type'] == 'int':
print(f''' {{
.location = {match['location']},
.binding = 0,
.format = VK_FORMAT_R32_SINT,
.offset = G_STRUCT_OFFSET({struct_name}, {match['name']}),
}},''')
elif match['type'] == 'uint':
print(f''' {{
.location = {match['location']},
.binding = 0,
.format = VK_FORMAT_R32_UINT,
.offset = G_STRUCT_OFFSET({struct_name}, {match['name']}),
}},''')
elif match['type'] == 'uvec2':
print(f''' {{
.location = {match['location']},
.binding = 0,
.format = VK_FORMAT_R32G32_UINT,
.offset = G_STRUCT_OFFSET({struct_name}, {match['name']}),
}},''')
elif match['type'] == 'vec2':
print(f''' {{
.location = {match['location']},
.binding = 0,
.format = VK_FORMAT_R32G32_SFLOAT,
.offset = G_STRUCT_OFFSET({struct_name}, {match['name']}),
}},''')
elif match['type'] == 'vec4':
print(f''' {{
.location = {match['location']},
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET({struct_name}, {match['name']}),
}},''')
elif match['type'] == 'mat3x4':
print(f''' {{
.location = {match['location']},
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET({struct_name}, {match['name']}),
}},
{{
.location = {int(match['location']) + 1},
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET({struct_name}, {match['name']}) + sizeof (float) * 4,
}},
{{
.location = {int(match['location']) + 2},
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET({struct_name}, {match['name']}) + sizeof (float) * 8,
}},''')
elif match['type'] == 'mat4':
print(f''' {{
.location = {match['location']},
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET({struct_name}, {match['name']}),
}},
{{
.location = {int(match['location']) + 1},
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET({struct_name}, {match['name']}) + sizeof (float) * 4,
}},
{{
.location = {int(match['location']) + 2},
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET({struct_name}, {match['name']}) + sizeof (float) * 8,
}},
{{
.location = {int(match['location']) + 3},
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET({struct_name}, {match['name']}) + sizeof (float) * 12,
}},''')
else:
raise Exception(f"Don't know what a {match['type']} is")
print(" },")
print("};")
+5 -7
View File
@@ -2,9 +2,7 @@
#include "clip.vert.glsl"
layout(location = 0) in vec4 inOutline;
layout(location = 1) in vec4 inOutlineCornerWidths;
layout(location = 2) in vec4 inOutlineCornerHeights;
layout(location = 0) in mat3x4 inOutline;
layout(location = 3) in vec4 inColor;
layout(location = 4) in vec2 inOffset;
layout(location = 5) in float inSpread;
@@ -26,15 +24,15 @@ vec2 offsets[6] = { vec2(0.0, 0.0),
vec2(1.0, 1.0) };
void main() {
vec4 rect = clip (inOutline);
vec4 rect = clip (inOutline[0]);
vec2 pos = rect.xy + rect.zw * offsets[gl_VertexIndex];
gl_Position = push.mvp * vec4 (push.scale * pos, 0.0, 1.0);
outPos = pos;
outOutline = inOutline;
outOutlineCornerWidths = inOutlineCornerWidths;
outOutlineCornerHeights = inOutlineCornerHeights;
outOutline = inOutline[0];
outOutlineCornerWidths = inOutline[1];
outOutlineCornerHeights = inOutline[2];
outColor = inColor;
outOffset = inOffset;
outSpread = inSpread;
+18 -5
View File
@@ -12,12 +12,12 @@ gsk_private_vulkan_include_shaders = [
]
gsk_private_vulkan_fragment_shaders = [
'blendmode.frag',
'blend-mode.frag',
'blur.frag',
'border.frag',
'color.frag',
'color-matrix.frag',
'crossfade.frag',
'cross-fade.frag',
'inset-shadow.frag',
'linear.frag',
'mask.frag',
@@ -26,12 +26,12 @@ gsk_private_vulkan_fragment_shaders = [
]
gsk_private_vulkan_vertex_shaders = [
'blendmode.vert',
'blend-mode.vert',
'blur.vert',
'border.vert',
'color.vert',
'color-matrix.vert',
'crossfade.vert',
'cross-fade.vert',
'inset-shadow.vert',
'linear.vert',
'mask.vert',
@@ -87,6 +87,19 @@ foreach shader: gsk_private_vulkan_shaders
'-o', '@OUTPUT@'
])
gsk_private_vulkan_compiled_shaders_deps += [compiled_shader, compiled_clip_shader, compiled_clip_rounded_shader]
gsk_private_vulkan_compiled_shaders += [spv_shader, clip_spv_shader, clip_rounded_spv_shader]
else
gsk_private_vulkan_compiled_shaders += files(spv_shader, clip_spv_shader, clip_rounded_spv_shader)
endif
gsk_private_vulkan_compiled_shaders += files(spv_shader, clip_spv_shader, clip_rounded_spv_shader)
endforeach
foreach shader: gsk_private_vulkan_vertex_shaders
shader_header = configure_file(output: '@0@.h'.format(shader),
input: shader,
command: [
find_program('generate-header.py'),
'@INPUT@',
],
capture: true)
gsk_private_vulkan_shader_headers += shader_header
endforeach
+6 -8
View File
@@ -2,9 +2,7 @@
#include "clip.vert.glsl"
layout(location = 0) in vec4 inOutline;
layout(location = 1) in vec4 inOutlineCornerWidths;
layout(location = 2) in vec4 inOutlineCornerHeights;
layout(location = 0) in mat3x4 inOutline;
layout(location = 3) in vec4 inColor;
layout(location = 4) in vec2 inOffset;
layout(location = 5) in float inSpread;
@@ -31,19 +29,19 @@ float radius_pixels(float radius) {
}
void main() {
vec4 rect = inOutline;
vec4 rect = inOutline[0];
float spread = inSpread + radius_pixels(inBlurRadius);
rect += vec4(inOffset - spread, vec2(2 * spread));
clip (inOutline);
clip (inOutline[0]);
vec2 pos = rect.xy + rect.zw * offsets[gl_VertexIndex];
gl_Position = push.mvp * vec4 (push.scale * pos, 0.0, 1.0);
outPos = pos;
outOutline = inOutline;
outOutlineCornerWidths = inOutlineCornerWidths;
outOutlineCornerHeights = inOutlineCornerHeights;
outOutline = inOutline[0];
outOutlineCornerWidths = inOutline[1];
outOutlineCornerHeights = inOutline[2];
outColor = inColor;
outOffset = inOffset;
outSpread = inSpread;
+1 -1
View File
@@ -733,7 +733,7 @@ gtk_alert_dialog_choose (GtkAlertDialog *self,
* and returns the index of the button that was clicked.
*
* Returns: the index of the button that was clicked, or -1 if
* the dialog was cancelled and `[property@Gtk.AlertDialog:cancel-button]
* the dialog was cancelled and [property@Gtk.AlertDialog:cancel-button]
* is not set
*
* Since: 4.10
+5 -1
View File
@@ -46,6 +46,7 @@
#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)
@@ -1166,7 +1167,8 @@ 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) ||
@@ -1331,6 +1333,8 @@ gtk_at_context_get_text_accumulate (GtkATContext *self,
GtkATContext *rel_context = gtk_accessible_get_at_context (rel);
gtk_at_context_get_text_accumulate (rel_context, nodes, s, property, relation, FALSE, TRUE);
g_object_unref (rel_context);
}
if (s->len > 0)
+173 -47
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,
+1
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);
}
/* }}} */
+90 -3
View File
@@ -44,6 +44,7 @@
#include "gtkbuilderprivate.h"
#include "gtkstringlist.h"
#include "gtkbox.h"
#include "gtktypebuiltins.h"
/**
* GtkDropDown:
@@ -104,6 +105,8 @@ struct _GtkDropDown
{
GtkWidget parent_instance;
gboolean uses_default_factory;
gboolean uses_default_list_factory;
GtkListItemFactory *factory;
GtkListItemFactory *list_factory;
GtkListItemFactory *header_factory;
@@ -124,6 +127,8 @@ struct _GtkDropDown
GtkWidget *search_entry;
GtkExpression *expression;
GtkStringFilterMatchMode search_match_mode;
guint enable_search : 1;
guint show_arrow : 1;
@@ -146,6 +151,7 @@ enum
PROP_ENABLE_SEARCH,
PROP_EXPRESSION,
PROP_SHOW_ARROW,
PROP_SEARCH_MATCH_MODE,
N_PROPS
};
@@ -279,7 +285,7 @@ update_filter (GtkDropDown *self)
if (self->expression)
{
filter = GTK_FILTER (gtk_string_filter_new (gtk_expression_ref (self->expression)));
gtk_string_filter_set_match_mode (GTK_STRING_FILTER (filter), GTK_STRING_FILTER_MATCH_MODE_PREFIX);
gtk_string_filter_set_match_mode (GTK_STRING_FILTER (filter), self->search_match_mode);
}
else
filter = GTK_FILTER (gtk_every_filter_new ());
@@ -388,6 +394,10 @@ gtk_drop_down_get_property (GObject *object,
case PROP_SHOW_ARROW:
g_value_set_boolean (value, gtk_drop_down_get_show_arrow (self));
break;
case PROP_SEARCH_MATCH_MODE:
g_value_set_enum (value, gtk_drop_down_get_search_match_mode (self));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -436,6 +446,11 @@ gtk_drop_down_set_property (GObject *object,
case PROP_SHOW_ARROW:
gtk_drop_down_set_show_arrow (self, g_value_get_boolean (value));
break;
case PROP_SEARCH_MATCH_MODE:
gtk_drop_down_set_search_match_mode (self, g_value_get_enum (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -641,7 +656,20 @@ gtk_drop_down_class_init (GtkDropDownClass *klass)
g_param_spec_boolean ("show-arrow", NULL, NULL,
TRUE,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
/**
* GtkDropDown:search-match-mode: (attributes org.gtk.Property.get=gtk_drop_down_get_search_match_mode org.gtk.Property.set=gtk_drop_down_set_search_match_mode)
*
* The match mode for the search filter.
*
* Since: 4.12
*/
properties[PROP_SEARCH_MATCH_MODE] =
g_param_spec_enum ("search-match-mode", NULL, NULL,
GTK_TYPE_STRING_FILTER_MATCH_MODE,
GTK_STRING_FILTER_MATCH_MODE_PREFIX,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (gobject_class, N_PROPS, properties);
/**
@@ -794,6 +822,10 @@ set_default_factory (GtkDropDown *self)
g_signal_connect (factory, "unbind", G_CALLBACK (unbind_item), self);
gtk_drop_down_set_factory (self, factory);
self->uses_default_factory = TRUE;
if (self->uses_default_list_factory)
gtk_drop_down_set_list_factory (self, NULL);
g_object_unref (factory);
}
@@ -809,6 +841,8 @@ gtk_drop_down_init (GtkDropDown *self)
self->show_arrow = gtk_widget_get_visible (self->arrow);
set_default_factory (self);
self->search_match_mode = GTK_STRING_FILTER_MATCH_MODE_PREFIX;
}
/**
@@ -972,7 +1006,12 @@ gtk_drop_down_set_factory (GtkDropDown *self,
gtk_list_factory_widget_set_factory (GTK_LIST_FACTORY_WIDGET (self->button_item), factory);
if (self->list_factory == NULL)
gtk_list_view_set_factory (GTK_LIST_VIEW (self->popup_list), factory);
{
gtk_list_view_set_factory (GTK_LIST_VIEW (self->popup_list), factory);
self->uses_default_list_factory = TRUE;
}
self->uses_default_factory = factory != NULL;
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_FACTORY]);
}
@@ -1057,6 +1096,8 @@ gtk_drop_down_set_list_factory (GtkDropDown *self,
else
gtk_list_view_set_factory (GTK_LIST_VIEW (self->popup_list), self->factory);
self->uses_default_list_factory = factory != NULL;
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_LIST_FACTORY]);
}
@@ -1194,6 +1235,9 @@ gtk_drop_down_set_expression (GtkDropDown *self,
if (self->expression)
gtk_expression_ref (self->expression);
if (self->uses_default_factory)
set_default_factory (self);
update_filter (self);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_EXPRESSION]);
@@ -1260,3 +1304,46 @@ gtk_drop_down_get_show_arrow (GtkDropDown *self)
return self->show_arrow;
}
/**
* gtk_drop_down_set_search_match_mode: (attributes org.gtk.Method.set_property=search-match-mode)
* @self: a `GtkDropDown`
* @search_match_mode: the new match mode
*
* Sets the match mode for the search filter.
*
* Since: 4.12
*/
void
gtk_drop_down_set_search_match_mode (GtkDropDown *self,
GtkStringFilterMatchMode search_match_mode)
{
g_return_if_fail (GTK_IS_DROP_DOWN (self));
if (self->search_match_mode == search_match_mode)
return;
self->search_match_mode = search_match_mode;
update_filter (self);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SEARCH_MATCH_MODE]);
}
/**
* gtk_drop_down_get_search_match_mode: (attributes org.gtk.Method.get_property=search-match-mode)
* @self: a `GtkDropDown`
*
* Returns the match mode that the search filter is using.
*
* Returns: the match mode of the search filter
*
* Since: 4.12
*/
GtkStringFilterMatchMode
gtk_drop_down_get_search_match_mode (GtkDropDown *self)
{
g_return_val_if_fail (GTK_IS_DROP_DOWN (self), GTK_STRING_FILTER_MATCH_MODE_PREFIX);
return self->search_match_mode;
}
+9
View File
@@ -21,6 +21,7 @@
#include <gtk/gtkwidget.h>
#include <gtk/gtkexpression.h>
#include "gtk/gtkstringfilter.h"
G_BEGIN_DECLS
@@ -83,11 +84,19 @@ void gtk_drop_down_set_enable_search (GtkDropDown
gboolean enable_search);
GDK_AVAILABLE_IN_ALL
gboolean gtk_drop_down_get_enable_search (GtkDropDown *self);
GDK_AVAILABLE_IN_4_6
void gtk_drop_down_set_show_arrow (GtkDropDown *self,
gboolean show_arrow);
GDK_AVAILABLE_IN_4_6
gboolean gtk_drop_down_get_show_arrow (GtkDropDown *self);
GDK_AVAILABLE_IN_4_12
void gtk_drop_down_set_search_match_mode (GtkDropDown *self,
GtkStringFilterMatchMode search_match_mode);
GDK_AVAILABLE_IN_4_12
GtkStringFilterMatchMode
gtk_drop_down_get_search_match_mode (GtkDropDown *self);
G_END_DECLS
+14 -7
View File
@@ -507,13 +507,19 @@ gtk_drop_target_handle_crossing (GtkEventController *controller,
graphene_point_init (&self->coords, x, y);
gtk_drop_target_start_drop (self, crossing->drop);
g_signal_emit (self, signals[ENTER], 0, x, y, &preferred);
if (!gdk_drag_action_is_unique (preferred))
{
g_critical ("Handler for GtkDropTarget::enter on %s %p did not return a unique preferred action",
G_OBJECT_TYPE_NAME (widget), widget);
preferred = make_action_unique (preferred);
}
/* start_drop ends w/ thaw_notify, where handler may reject, so recheck */
if (self->drop != NULL)
g_signal_emit (self, signals[ENTER], 0, x, y, &preferred);
else
preferred = 0;
if (!gdk_drag_action_is_unique (preferred))
{
g_critical ("Handler for GtkDropTarget::enter on %s %p did not return a unique preferred action",
G_OBJECT_TYPE_NAME (widget), widget);
preferred = make_action_unique (preferred);
}
if (preferred &&
gtk_drop_status (self->drop, self->actions, preferred))
{
@@ -533,6 +539,7 @@ gtk_drop_target_handle_crossing (GtkEventController *controller,
g_signal_emit (self, signals[LEAVE], 0);
if (!self->dropping)
gtk_drop_target_end_drop (self);
gtk_widget_unset_state_flags (widget, GTK_STATE_FLAG_DROP_ACTIVE);
}
}
+1 -1
View File
@@ -4573,7 +4573,7 @@ gtk_file_chooser_widget_unselect_all (GtkFileChooser *chooser)
/* Checks whether the filename entry for Save modes contains a well-formed filename.
*
* is_well_formed_ret - whether what the user typed passes gkt_file_system_make_path()
* is_well_formed_ret - whether what the user typed passes gtk_file_system_make_path()
*
* is_empty_ret - whether the file entry is totally empty
*
+4 -4
View File
@@ -268,7 +268,7 @@ gtk_file_dialog_class_init (GtkFileDialogClass *class)
/**
* GtkFileDialog:initial-file: (attributes org.gtk.Property.get=gtk_file_dialog_get_initial_file org.gtk.Property.set=gtk_file_dialog_set_initial_file)
*
* The inital file, that is, the file that is initially selected
* The initial file, that is, the file that is initially selected
* in the file chooser dialog
*
* This is a utility property that sets both [property@Gtk.FileDialog:initial-folder] and
@@ -284,7 +284,7 @@ gtk_file_dialog_class_init (GtkFileDialogClass *class)
/**
* GtkFileDialog:initial-folder: (attributes org.gtk.Property.get=gtk_file_dialog_get_initial_folder org.gtk.Property.set=gtk_file_dialog_set_initial_folder)
*
* The inital folder, that is, the directory that is initially
* The initial folder, that is, the directory that is initially
* opened in the file chooser dialog
*
* Since: 4.10
@@ -297,7 +297,7 @@ gtk_file_dialog_class_init (GtkFileDialogClass *class)
/**
* GtkFileDialog:initial-name: (attributes org.gtk.Property.get=gtk_file_dialog_get_initial_name org.gtk.Property.set=gtk_file_dialog_set_initial_name)
*
* The inital name, that is, the filename that is initially
* The initial name, that is, the filename that is initially
* selected in the file chooser dialog.
*
* Since: 4.10
@@ -703,7 +703,7 @@ gtk_file_dialog_set_initial_file (GtkFileDialog *self,
if (folder == NULL)
goto invalid_file;
if (g_set_object (&self->initial_folder, NULL))
if (g_set_object (&self->initial_folder, folder))
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_INITIAL_FOLDER]);
info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_EDIT_NAME, 0, NULL, NULL);
+1
View File
@@ -385,6 +385,7 @@ gtk_font_dialog_button_class_init (GtkFontDialogButtonClass *class)
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
gtk_widget_class_set_css_name (widget_class, "fontbutton");
gtk_widget_class_set_accessible_role (widget_class, GTK_ACCESSIBLE_ROLE_GROUP);
}
/* }}} */
+6 -1
View File
@@ -181,7 +181,7 @@ gtk_image_class_init (GtkImageClass *class)
/**
* GtkImage:file: (attributes org.gtk.Property.set=gtk_image_set_from_file)
*
* The `GFile to display.
* The `GFile` to display.
*/
image_props[PROP_FILE] =
g_param_spec_string ("file", NULL, NULL,
@@ -762,6 +762,7 @@ gtk_image_set_from_icon_name (GtkImage *image,
_gtk_icon_helper_set_icon_name (image->icon_helper, icon_name);
g_object_notify_by_pspec (G_OBJECT (image), image_props[PROP_ICON_NAME]);
g_object_notify_by_pspec (G_OBJECT (image), image_props[PROP_STORAGE_TYPE]);
g_object_thaw_notify (G_OBJECT (image));
}
@@ -795,6 +796,7 @@ gtk_image_set_from_gicon (GtkImage *image,
}
g_object_notify_by_pspec (G_OBJECT (image), image_props[PROP_GICON]);
g_object_notify_by_pspec (G_OBJECT (image), image_props[PROP_STORAGE_TYPE]);
g_object_thaw_notify (G_OBJECT (image));
}
@@ -857,6 +859,7 @@ gtk_image_set_from_paintable (GtkImage *image,
}
g_object_notify_by_pspec (G_OBJECT (image), image_props[PROP_PAINTABLE]);
g_object_notify_by_pspec (G_OBJECT (image), image_props[PROP_STORAGE_TYPE]);
g_object_thaw_notify (G_OBJECT (image));
}
@@ -1079,6 +1082,8 @@ gtk_image_set_from_definition (GtkImage *image,
gtk_image_notify_for_storage_type (image, gtk_image_definition_get_storage_type (def));
}
g_object_notify_by_pspec (G_OBJECT (image), image_props[PROP_STORAGE_TYPE]);
g_object_thaw_notify (G_OBJECT (image));
}
+1 -1
View File
@@ -2249,7 +2249,7 @@ gtk_list_base_set_anchor (GtkListBase *self,
* in front of it.
*
* Addditionally, there will be @above_below widgets allocated both
* before and after the sencter widgets, so the total number of
* before and after the center widgets, so the total number of
* widgets kept alive is 2 * above_below + center + 1.
**/
void
+1
View File
@@ -1356,6 +1356,7 @@ gtk_list_item_manager_ensure_items (GtkListItemManager *self,
position + i,
item,
gtk_selection_model_is_selected (self->model, position + i));
g_object_unref (item);
gtk_widget_insert_after (tile->widget, self->widget, insert_after);
}
else
+43 -1
View File
@@ -22,6 +22,7 @@
#include "gtkmaplistmodel.h"
#include "gtkrbtreeprivate.h"
#include "gtksectionmodel.h"
#include "gtkprivate.h"
/**
@@ -54,6 +55,8 @@
*
* `GtkMapListModel` will attempt to discard the mapped objects as soon as
* they are no longer needed and recreate them if necessary.
*
* `GtkMapListModel` passes through sections from the underlying model.
*/
enum {
@@ -207,8 +210,43 @@ gtk_map_list_model_model_init (GListModelInterface *iface)
iface->get_item = gtk_map_list_model_get_item;
}
static void
gtk_map_list_model_get_section (GtkSectionModel *model,
guint position,
guint *out_start,
guint *out_end)
{
GtkMapListModel *self = GTK_MAP_LIST_MODEL (model);
if (GTK_IS_SECTION_MODEL (self->model))
{
gtk_section_model_get_section (GTK_SECTION_MODEL (self->model), position, out_start, out_end);
return;
}
*out_start = 0;
*out_end = self->model ? g_list_model_get_n_items (self->model) : 0;
}
static void
gtk_map_list_model_sections_changed_cb (GtkSectionModel *model,
unsigned int position,
unsigned int n_items,
gpointer user_data)
{
gtk_section_model_sections_changed (GTK_SECTION_MODEL (user_data), position, n_items);
}
static void
gtk_map_list_model_section_model_init (GtkSectionModelInterface *iface)
{
iface->get_section = gtk_map_list_model_get_section;
}
G_DEFINE_TYPE_WITH_CODE (GtkMapListModel, gtk_map_list_model, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (G_TYPE_LIST_MODEL, gtk_map_list_model_model_init))
G_IMPLEMENT_INTERFACE (G_TYPE_LIST_MODEL, gtk_map_list_model_model_init)
G_IMPLEMENT_INTERFACE (GTK_TYPE_SECTION_MODEL, gtk_map_list_model_section_model_init))
static void
gtk_map_list_model_items_changed_cb (GListModel *model,
@@ -337,6 +375,7 @@ gtk_map_list_model_clear_model (GtkMapListModel *self)
if (self->model == NULL)
return;
g_signal_handlers_disconnect_by_func (self->model, gtk_map_list_model_sections_changed_cb, self);
g_signal_handlers_disconnect_by_func (self->model, gtk_map_list_model_items_changed_cb, self);
g_clear_object (&self->model);
}
@@ -608,6 +647,9 @@ gtk_map_list_model_set_model (GtkMapListModel *self,
self->model = g_object_ref (model);
g_signal_connect (model, "items-changed", G_CALLBACK (gtk_map_list_model_items_changed_cb), self);
added = g_list_model_get_n_items (model);
if (GTK_IS_SECTION_MODEL (model))
g_signal_connect (model, "sections-changed", G_CALLBACK (gtk_map_list_model_sections_changed_cb), self);
}
else
{
+1
View File
@@ -374,6 +374,7 @@ gtk_scale_button_class_init (GtkScaleButtonClass *klass)
gtk_widget_class_bind_template_callback (widget_class, cb_popup_mapped);
gtk_widget_class_set_css_name (widget_class, I_("scalebutton"));
gtk_widget_class_set_accessible_role (widget_class, GTK_ACCESSIBLE_ROLE_GROUP);
}
static gboolean
+6 -4
View File
@@ -617,8 +617,7 @@ gtk_stack_pages_get_item (GListModel *model,
GtkStackPrivate *priv = gtk_stack_get_instance_private (pages->stack);
GtkStackPage *page;
if (position > priv->children->len - 1)
if (position >= priv->children->len)
return NULL;
page = g_ptr_array_index (priv->children, position);
@@ -642,7 +641,7 @@ gtk_stack_pages_is_selected (GtkSelectionModel *model,
GtkStackPrivate *priv = gtk_stack_get_instance_private (pages->stack);
GtkStackPage *page;
if (position > priv->children->len - 1)
if (position >= priv->children->len)
return FALSE;
page = g_ptr_array_index (priv->children, position);
@@ -664,6 +663,9 @@ gtk_stack_pages_select_item (GtkSelectionModel *model,
GtkStackPrivate *priv = gtk_stack_get_instance_private (pages->stack);
GtkStackPage *page;
if (position >= priv->children->len)
return FALSE;
page = g_ptr_array_index (priv->children, position);
set_visible_child (pages->stack, page, priv->transition_type, priv->transition_duration);
@@ -813,7 +815,7 @@ gtk_stack_accessible_get_first_accessible_child (GtkAccessible *accessible)
if (priv->children->len > 0)
page_accessible = GTK_ACCESSIBLE (g_object_ref (g_ptr_array_index (priv->children, 0)));
return page_accessible;
}
+17 -17
View File
@@ -79,9 +79,9 @@
* The `GtkText` widget is a single-line text entry widget.
*
* `GtkText` is the common implementation of single-line text editing
* that is shared between `GtkEntry`, `GtkPasswordEntry`, `GtkSpinButton`
* and other widgets. In all of these, `GtkText` is used as the delegate
* for the [iface@Gtk.Editable] implementation.
* that is shared between [class@Gtk.Entry], [class@Gtk.PasswordEntry],
* [class@Gtk.SpinButton], and other widgets. In all of these, `GtkText` is
* used as the delegate for the [iface@Gtk.Editable] implementation.
*
* A fairly large set of key bindings are supported by default. If the
* entered text is longer than the allocation of the widget, the widget
@@ -95,10 +95,10 @@
* [method@Gtk.Text.set_invisible_char].
*
* If you are looking to add icons or progress display in an entry, look
* at `GtkEntry`. There other alternatives for more specialized use cases,
* such as `GtkSearchEntry`.
* at [class@Gtk.Entry]. There other alternatives for more specialized use
* cases, such as [class@Gtk.SearchEntry].
*
* If you need multi-line editable text, look at `GtkTextView`.
* If you need multi-line editable text, look at [class@Gtk.TextView].
*
* # CSS nodes
*
@@ -112,25 +112,25 @@
* [window.popup]
* ```
*
* `GtkText` has a main node with the name text. Depending on the properties
* of the widget, the .read-only style class may appear.
* `GtkText` has a main node with the name `text`. Depending on the properties
* of the widget, the `.read-only` style class may appear.
*
* When the entry has a selection, it adds a subnode with the name selection.
* When the entry has a selection, it adds a subnode with the name `selection`.
*
* When the entry is in overwrite mode, it adds a subnode with the name
* block-cursor that determines how the block cursor is drawn.
* `block-cursor` that determines how the block cursor is drawn.
*
* The CSS node for a context menu is added as a subnode below text as well.
* The CSS node for a context menu is added as a subnode with the name `popup`.
*
* The undershoot nodes are used to draw the underflow indication when content
* is scrolled out of view. These nodes get the .left and .right style classes
* The `undershoot` nodes are used to draw the underflow indication when content
* is scrolled out of view. These nodes get the `.left` or `.right` style class
* added depending on where the indication is drawn.
*
* When touch is used and touch selection handles are shown, they are using
* CSS nodes with name cursor-handle. They get the .top or .bottom style class
* depending on where they are shown in relation to the selection. If there is
* just a single handle for the text cursor, it gets the style class
* .insertion-cursor.
* CSS nodes with name `cursor-handle`. They get the `.top` or `.bottom` style
* class depending on where they are shown in relation to the selection. If
* there is just a single handle for the text cursor, it gets the style class
* `.insertion-cursor`.
*
* # Accessibility
*
+32 -1
View File
@@ -755,6 +755,8 @@ gtk_tooltip_show_tooltip (GdkDisplay *display)
gtk_tooltip_position (tooltip, display, tooltip_widget, device);
g_signal_emit_by_name (tooltip_widget, "tooltip-show", tooltip);
gtk_widget_set_visible (GTK_WIDGET (tooltip->window), TRUE);
/* Now a tooltip is visible again on the display, make sure browse
@@ -771,6 +773,8 @@ gtk_tooltip_show_tooltip (GdkDisplay *display)
static void
gtk_tooltip_hide_tooltip (GtkTooltip *tooltip)
{
GtkWidget *tooltip_widget;
guint timeout = BROWSE_DISABLE_TIMEOUT;
if (!tooltip)
@@ -785,6 +789,7 @@ gtk_tooltip_hide_tooltip (GtkTooltip *tooltip)
if (!GTK_TOOLTIP_VISIBLE (tooltip))
return;
tooltip_widget = tooltip->tooltip_widget;
tooltip->tooltip_widget = NULL;
/* The tooltip is gone, after (by default, should be configurable) 500ms
@@ -801,7 +806,10 @@ gtk_tooltip_hide_tooltip (GtkTooltip *tooltip)
}
if (tooltip->window)
gtk_widget_set_visible (tooltip->window, FALSE);
{
gtk_widget_set_visible (tooltip->window, FALSE);
g_signal_emit_by_name (tooltip_widget, "tooltip-hide", tooltip);
}
}
static int
@@ -1065,3 +1073,26 @@ gtk_tooltip_unset_surface (GtkNative *native)
gtk_tooltip_set_surface (tooltip, NULL);
}
/**
* gtk_tooltip_set_css_class:
* @tooltip: a #GtkTooltip
* @css_class: (allow-none): a css class name, or %NULL
*
* This function allows to add a single css class
* to @tooltip window, that means it will remove any
* css class previously added by this function before
* adding @css_class as the currently active one.
*
* if %NULL is passed then any active css class (which
* was added by this function) will be cleared.
*
* Since: 4.12
*/
void
gtk_tooltip_set_css_class (GtkTooltip *tooltip,
const char *css_class)
{
g_return_if_fail (GTK_IS_TOOLTIP (tooltip));
gtk_tooltip_window_set_css_class (GTK_TOOLTIP_WINDOW (tooltip->window), css_class);
}
+3
View File
@@ -56,6 +56,9 @@ void gtk_tooltip_set_custom (GtkTooltip *tooltip,
GDK_AVAILABLE_IN_ALL
void gtk_tooltip_set_tip_area (GtkTooltip *tooltip,
const GdkRectangle *rect);
GDK_AVAILABLE_IN_4_12
void gtk_tooltip_set_css_class (GtkTooltip *tooltip,
const char *css_class);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkTooltip, g_object_unref)
+29
View File
@@ -59,6 +59,7 @@ struct _GtkTooltipWindow
GtkWidget *image;
GtkWidget *label;
GtkWidget *custom_widget;
char *css_class;
};
struct _GtkTooltipWindowClass
@@ -392,6 +393,7 @@ static void
gtk_tooltip_window_init (GtkTooltipWindow *self)
{
gtk_widget_init_template (GTK_WIDGET (self));
self->css_class = NULL;
}
GtkWidget *
@@ -520,3 +522,30 @@ gtk_tooltip_window_position (GtkTooltipWindow *window,
gtk_tooltip_window_relayout (window);
}
/* See gtk_tooltip_set_css_class() description */
void
gtk_tooltip_window_set_css_class (GtkTooltipWindow *window,
const char *css_class)
{
GtkWidget *wid = GTK_WIDGET (window);
if (g_strcmp0 (window->css_class, css_class) == 0)
return;
if (css_class)
{
if (window->css_class)
{
gtk_widget_remove_css_class (wid, window->css_class);
g_free (window->css_class);
}
window->css_class = g_strdup (css_class);
gtk_widget_add_css_class (wid, css_class);
}
else
{
gtk_widget_remove_css_class (wid, window->css_class);
g_clear_pointer (&window->css_class, g_free);
}
}
+2
View File
@@ -59,6 +59,8 @@ void gtk_tooltip_window_position (GtkTooltipWindo
GdkAnchorHints anchor_hints,
int dx,
int dy);
void gtk_tooltip_window_set_css_class (GtkTooltipWindow *window,
const char *css_class);
G_END_DECLS
+36
View File
@@ -502,6 +502,8 @@ enum {
MOVE_FOCUS,
KEYNAV_FAILED,
QUERY_TOOLTIP,
TOOLTIP_SHOW,
TOOLTIP_HIDE,
LAST_SIGNAL
};
@@ -1926,6 +1928,38 @@ gtk_widget_class_init (GtkWidgetClass *klass)
gtk_widget_class_set_css_name (klass, I_("widget"));
klass->priv->accessible_role = GTK_ACCESSIBLE_ROLE_WIDGET;
/**
* GtkWidget::tooltip-show:
* @widget: the object which received the signal.
*
* Emitted when a tooltip is about to be shown on @widget.
*/
widget_signals[TOOLTIP_SHOW] =
g_signal_new (I_("tooltip-show"),
G_TYPE_FROM_CLASS (gobject_class),
G_SIGNAL_RUN_FIRST,
0,
NULL, NULL,
NULL,
G_TYPE_NONE, 1,
GTK_TYPE_TOOLTIP);
/**
* GtkWidget::tooltip-hide:
* @widget: the object which received the signal.
*
* Emitted when a tooltip on @widget has just been hidden.
*/
widget_signals[TOOLTIP_HIDE] =
g_signal_new (I_("tooltip-hide"),
G_TYPE_FROM_CLASS (gobject_class),
G_SIGNAL_RUN_FIRST,
0,
NULL, NULL,
NULL,
G_TYPE_NONE, 1,
GTK_TYPE_TOOLTIP);
}
static void
@@ -2401,6 +2435,8 @@ gtk_widget_root_at_context (GtkWidget *self)
/* Reset the accessible role to its current value */
if (role == GTK_ACCESSIBLE_ROLE_WIDGET)
role = GTK_WIDGET_GET_CLASS (self)->priv->accessible_role;
if (role == GTK_ACCESSIBLE_ROLE_WIDGET)
role = GTK_ACCESSIBLE_ROLE_GENERIC;
gtk_at_context_set_accessible_role (priv->at_context, role);
if (priv->root)
+1 -1
View File
@@ -36,7 +36,7 @@
extern IMAGE_DOS_HEADER __ImageBase;
static inline HMODULE
this_module ()
this_module (void)
{
return (HMODULE) &__ImageBase;
}
+4
View File
@@ -243,6 +243,8 @@ update_name (GtkInspectorA11y *sl)
name = gtk_at_context_get_name (context);
gtk_label_set_label (GTK_LABEL (sl->name), name);
g_object_unref (context);
}
static void
@@ -257,6 +259,8 @@ update_description (GtkInspectorA11y *sl)
description = gtk_at_context_get_description (context);
gtk_label_set_label (GTK_LABEL (sl->description), description);
g_object_unref (context);
}
static void
+22 -9
View File
@@ -110,12 +110,11 @@ static struct {
};
static FixSeverity
check_accessibility_errors (GtkWidget *widget,
GArray *context_elements,
char **hint)
check_accessibility_errors (GtkATContext *context,
GtkAccessibleRole role,
GArray *context_elements,
char **hint)
{
GtkAccessibleRole role;
GtkATContext *context;
gboolean label_set;
const char *role_name;
GEnumClass *states;
@@ -124,11 +123,8 @@ check_accessibility_errors (GtkWidget *widget,
gboolean has_context;
*hint = NULL;
role = gtk_accessible_get_accessible_role (GTK_ACCESSIBLE (widget));
role_name = gtk_accessible_role_to_name (role, NULL);
context = gtk_accessible_get_at_context (GTK_ACCESSIBLE (widget));
if (!gtk_at_context_is_realized (context))
gtk_at_context_realize (context);
@@ -314,6 +310,23 @@ check_accessibility_errors (GtkWidget *widget,
return SEVERITY_GOOD;
}
static FixSeverity
check_widget_accessibility_errors (GtkWidget *widget,
GArray *context_elements,
char **hint)
{
GtkAccessibleRole role;
GtkATContext *context;
FixSeverity ret;
role = gtk_accessible_get_accessible_role (GTK_ACCESSIBLE (widget));
context = gtk_accessible_get_at_context (GTK_ACCESSIBLE (widget));
ret = check_accessibility_errors (context, role, context_elements, hint);
g_object_unref (context);
return ret;
}
static void
recurse_child_widgets (GtkA11yOverlay *self,
GtkWidget *widget,
@@ -327,7 +340,7 @@ recurse_child_widgets (GtkA11yOverlay *self,
if (!gtk_widget_get_mapped (widget))
return;
severity = check_accessibility_errors (widget, self->context, &hint);
severity = check_widget_accessibility_errors (widget, self->context, &hint);
if (severity != SEVERITY_GOOD)
{
+1 -11
View File
@@ -758,17 +758,7 @@ if not fs.exists('theme/Default/Default-light.css')
endif
objcopy_supports_add_symbol = false
objcopy = find_program('objcopy', required : false)
if objcopy.found()
objcopy_supports_add_symbol = run_command(objcopy, '--help', check: false).stdout().contains('--add-symbol')
endif
ld = find_program('ld', required : false)
if not meson.is_cross_build() and build_machine.cpu_family() == 'x86_64' and build_machine.system() == 'linux' and objcopy.found() and objcopy_supports_add_symbol and ld.found()
glib_compile_resources = find_program('glib-compile-resources')
if can_use_objcopy_for_resources
# Create the resource blob
gtk_gresource = custom_target('gtk.gresource',
input : gtk_gresources_xml,
+1
View File
@@ -8,3 +8,4 @@ leak:libgio-2.0.so
leak:libcairo.so
leak:libpixman-1.so
leak:librsvg-2.so
leak:libxkbcommon.so
+22 -1
View File
@@ -1,5 +1,5 @@
project('gtk', 'c',
version: '4.11.4',
version: '4.11.5',
default_options: [
'buildtype=debugoptimized',
'warning_level=1',
@@ -737,6 +737,27 @@ endif
build_gir = gir.found() and (get_option('introspection').enabled() or
(get_option('introspection').allowed() and get_option('gtk_doc')))
# Resource building
glib_compile_resources = find_program('glib-compile-resources')
objcopy_supports_add_symbol = false
objcopy = find_program('objcopy', required : false)
if objcopy.found()
objcopy_supports_add_symbol = run_command(objcopy, '--help', check: false).stdout().contains('--add-symbol')
endif
ld_is_bfd = false
ld = find_program('ld', required : false)
if ld.found()
ld_is_bfd = run_command(ld, '--version', check: false).stdout().contains('GNU ld')
endif
if not meson.is_cross_build() and build_machine.cpu_family() == 'x86_64' and build_machine.system() == 'linux' and objcopy.found() and objcopy_supports_add_symbol and ld.found() and ld_is_bfd
can_use_objcopy_for_resources = true
else
can_use_objcopy_for_resources = false
endif
project_build_root = meson.current_build_dir()
gen_visibility_macros = find_program('build-aux/meson/gen-visibility-macros.py')
+2 -2
View File
@@ -35,7 +35,7 @@ msgstr ""
"Project-Id-Version: gtk+ 2.8.2\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gtk/-/issues/\n"
"POT-Creation-Date: 2023-05-12 13:13+0000\n"
"PO-Revision-Date: 2023-05-30 11:18+0100\n"
"PO-Revision-Date: 2023-06-22 11:18+0100\n"
"Last-Translator: Jordi Mas i Hernàndez <jmas@softcatala.org>\n"
"Language-Team: Catalan <tradgnome@softcatala.org>\n"
"Language: ca\n"
@@ -3595,7 +3595,7 @@ msgstr "Resultats de cerca"
#. window
#: gtk/gtkshortcutswindow.c:909
msgid "Search Shortcuts"
msgstr "Dreceres de cerca"
msgstr "Cerca les dreceres"
#: gtk/gtkshortcutswindow.c:968 gtk/ui/gtkemojichooser.ui:349
#: gtk/ui/gtkfilechooserwidget.ui:502
+782 -716
View File
File diff suppressed because it is too large Load Diff
+605 -551
View File
File diff suppressed because it is too large Load Diff
+1182 -1017
View File
File diff suppressed because it is too large Load Diff
+29
View File
@@ -0,0 +1,29 @@
#include <gtk/gtk.h>
static void
color_dialog_button_role (void)
{
GtkWidget *window, *widget;
widget = gtk_color_dialog_button_new (NULL);
window = gtk_window_new ();
gtk_window_set_child (GTK_WINDOW (window), widget);
gtk_window_present (GTK_WINDOW (window));
while (!gtk_widget_get_realized (widget))
g_main_context_iteration (NULL, FALSE);
gtk_test_accessible_assert_role (widget, GTK_ACCESSIBLE_ROLE_GROUP);
gtk_window_destroy (GTK_WINDOW (window));
}
int
main (int argc, char *argv[])
{
gtk_test_init (&argc, &argv, NULL);
g_test_add_func ("/a11y/color-dialog-button/role", color_dialog_button_role);
return g_test_run ();
}
+1
View File
@@ -11,6 +11,7 @@ tests = [
{ 'name': 'box' },
{ 'name': 'button' },
{ 'name': 'checkbutton' },
{ 'name': 'colordialogbutton' },
{ 'name': 'custom' },
{ 'name': 'dialog' },
{ 'name': 'entry' },
+46 -12
View File
@@ -6,6 +6,7 @@ static void
test_name_content (void)
{
GtkWidget *window, *label1, *label2, *box, *button;
GtkATContext *context;
char *name;
label1 = gtk_label_new ("a");
@@ -21,24 +22,32 @@ test_name_content (void)
gtk_window_set_child (GTK_WINDOW (window), button);
gtk_window_present (GTK_WINDOW (window));
name = gtk_at_context_get_name (gtk_accessible_get_at_context (GTK_ACCESSIBLE (label1)));
context = gtk_accessible_get_at_context (GTK_ACCESSIBLE (label1));
name = gtk_at_context_get_name (context);
g_assert_cmpstr (name, ==, "a");
g_free (name);
g_object_unref (context);
/* this is because generic doesn't allow naming */
name = gtk_at_context_get_name (gtk_accessible_get_at_context (GTK_ACCESSIBLE (box)));
context = gtk_accessible_get_at_context (GTK_ACCESSIBLE (box));
name = gtk_at_context_get_name (context);
g_assert_cmpstr (name, ==, "");
g_free (name);
g_object_unref (context);
name = gtk_at_context_get_name (gtk_accessible_get_at_context (GTK_ACCESSIBLE (button)));
context = gtk_accessible_get_at_context (GTK_ACCESSIBLE (button));
name = gtk_at_context_get_name (context);
g_assert_cmpstr (name, ==, "a b");
g_free (name);
g_object_unref (context);
gtk_widget_set_visible (label2, FALSE);
name = gtk_at_context_get_name (gtk_accessible_get_at_context (GTK_ACCESSIBLE (button)));
context = gtk_accessible_get_at_context (GTK_ACCESSIBLE (button));
name = gtk_at_context_get_name (context);
g_assert_cmpstr (name, ==, "a");
g_free (name);
g_object_unref (context);
gtk_window_destroy (GTK_WINDOW (window));
}
@@ -47,6 +56,7 @@ static void
test_name_tooltip (void)
{
GtkWidget *window, *image;
GtkATContext *context;
char *name;
image = gtk_image_new ();
@@ -57,10 +67,14 @@ test_name_tooltip (void)
gtk_widget_set_tooltip_text (image, "tooltip");
name = gtk_at_context_get_name (gtk_accessible_get_at_context (GTK_ACCESSIBLE (image)));
context = gtk_accessible_get_at_context (GTK_ACCESSIBLE (image));
name = gtk_at_context_get_name (context);
g_assert_cmpstr (name, ==, "tooltip");
g_free (name);
g_object_unref (context);
gtk_window_destroy (GTK_WINDOW (window));
}
@@ -68,6 +82,7 @@ static void
test_name_menubutton (void)
{
GtkWidget *window, *widget;
GtkATContext *context;
char *name;
widget = gtk_menu_button_new ();
@@ -79,10 +94,14 @@ test_name_menubutton (void)
gtk_widget_set_tooltip_text (widget, "tooltip");
name = gtk_at_context_get_name (gtk_accessible_get_at_context (GTK_ACCESSIBLE (widget)));
context = gtk_accessible_get_at_context (GTK_ACCESSIBLE (widget));
name = gtk_at_context_get_name (context);
g_assert_cmpstr (name, ==, "tooltip");
g_free (name);
g_object_unref (context);
gtk_window_destroy (GTK_WINDOW (window));
}
@@ -90,6 +109,7 @@ static void
test_name_label (void)
{
GtkWidget *window, *image;
GtkATContext *context;
char *name;
char *desc;
@@ -108,8 +128,10 @@ test_name_label (void)
GTK_ACCESSIBLE_PROPERTY_LABEL, "label",
-1);
name = gtk_at_context_get_name (gtk_accessible_get_at_context (GTK_ACCESSIBLE (image)));
desc = gtk_at_context_get_description (gtk_accessible_get_at_context (GTK_ACCESSIBLE (image)));
context = gtk_accessible_get_at_context (GTK_ACCESSIBLE (image));
name = gtk_at_context_get_name (context);
desc = gtk_at_context_get_description (context);
g_assert_cmpstr (name, ==, "label");
g_assert_cmpstr (desc, ==, "tooltip");
@@ -117,6 +139,8 @@ test_name_label (void)
g_free (name);
g_free (desc);
g_object_unref (context);
gtk_window_destroy (GTK_WINDOW (window));
}
@@ -124,6 +148,7 @@ static void
test_name_prohibited (void)
{
GtkWidget *window, *widget;
GtkATContext *context;
char *name;
char *desc;
@@ -136,8 +161,10 @@ test_name_prohibited (void)
gtk_window_set_child (GTK_WINDOW (window), widget);
gtk_window_present (GTK_WINDOW (window));
name = gtk_at_context_get_name (gtk_accessible_get_at_context (GTK_ACCESSIBLE (widget)));
desc = gtk_at_context_get_description (gtk_accessible_get_at_context (GTK_ACCESSIBLE (widget)));
context = gtk_accessible_get_at_context (GTK_ACCESSIBLE (widget));
name = gtk_at_context_get_name (context);
desc = gtk_at_context_get_description (context);
g_assert_cmpstr (name, ==, "");
g_assert_cmpstr (desc, ==, "");
@@ -145,6 +172,8 @@ test_name_prohibited (void)
g_free (name);
g_free (desc);
g_object_unref (context);
gtk_window_destroy (GTK_WINDOW (window));
}
@@ -152,6 +181,7 @@ static void
test_name_range (void)
{
GtkWidget *window, *scale;
GtkATContext *context;
char *name;
scale = gtk_scale_new_with_range (GTK_ORIENTATION_HORIZONTAL, 0, 100, 10);
@@ -160,16 +190,20 @@ test_name_range (void)
gtk_window_set_child (GTK_WINDOW (window), scale);
gtk_window_present (GTK_WINDOW (window));
context = gtk_accessible_get_at_context (GTK_ACCESSIBLE (scale));
g_assert_true (gtk_accessible_get_accessible_role (GTK_ACCESSIBLE (scale)) == GTK_ACCESSIBLE_ROLE_SLIDER);
g_assert_true (gtk_at_context_get_accessible_role (gtk_accessible_get_at_context (GTK_ACCESSIBLE (scale))) == GTK_ACCESSIBLE_ROLE_SLIDER);
g_assert_true (gtk_at_context_get_accessible_role (context) == GTK_ACCESSIBLE_ROLE_SLIDER);
gtk_range_set_value (GTK_RANGE (scale), 50);
name = gtk_at_context_get_name (gtk_accessible_get_at_context (GTK_ACCESSIBLE (scale)));
name = gtk_at_context_get_name (context);
g_assert_cmpstr (name, ==, "50");
g_free (name);
g_object_unref (context);
gtk_window_destroy (GTK_WINDOW (window));
}
+10 -2
View File
@@ -298,8 +298,12 @@ main (int argc, char **argv)
{
GskRenderNode *node2;
GdkPixbuf *pixbuf, *pixbuf2;
GskTransform *transform;
transform = gsk_transform_scale (NULL, -1, 1);
node2 = gsk_transform_node_new (node, transform);
gsk_transform_unref (transform);
node2 = gsk_transform_node_new (node, gsk_transform_scale (NULL, -1, 1));
save_node (node2, node_file, "-flipped.node");
rendered_texture = gsk_renderer_render_texture (renderer, node2, NULL);
@@ -404,8 +408,12 @@ main (int argc, char **argv)
{
GskRenderNode *node2;
GdkPixbuf *pixbuf, *pixbuf2;
GskTransform *transform;
transform = gsk_transform_rotate (NULL, 90);
node2 = gsk_transform_node_new (node, transform);
gsk_transform_unref (transform);
node2 = gsk_transform_node_new (node, gsk_transform_rotate (NULL, 90));
save_node (node2, node_file, "-rotated.node");
rendered_texture = gsk_renderer_render_texture (renderer, node2, NULL);

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