Compare commits
102 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| bab2bf2596 | |||
| 11b4e4a467 | |||
| 1cae0cd54c | |||
| 1f3db35271 | |||
| 18cce46ed2 | |||
| e78148bae5 | |||
| 41237509ad | |||
| 576e8a2090 | |||
| d0f77c1db4 | |||
| e28ff79bec | |||
| dccf6b55bd | |||
| d5ea376e7b | |||
| 40707a6af0 | |||
| 9b71c9dfc6 | |||
| 64308317f8 | |||
| f920723eae | |||
| c581f4c96f | |||
| 4998c90b10 | |||
| 412b23a146 | |||
| c179013790 | |||
| c6eb7fd483 | |||
| 7c58370673 | |||
| 84737a5159 | |||
| 48804c81f3 | |||
| c79ec355af | |||
| ce5d74d7df | |||
| 5bcc943ec3 | |||
| f5d68bb586 | |||
| 6d1537647c | |||
| ae2c10996a | |||
| 81e9de3778 | |||
| 42a704fefb | |||
| e57eaf16b4 | |||
| 9aabb0e98d | |||
| 9590a5f45e | |||
| 7bee50c4f6 | |||
| bad2324318 | |||
| dd15accb79 | |||
| 1d1f35576a | |||
| 15458b5af3 | |||
| 5ffe9a68ed | |||
| f341bd563b | |||
| 70edacc68d | |||
| 091176ae48 | |||
| d9cfb94a80 | |||
| 3c7ca28f1f | |||
| 25e518326c | |||
| a853307fb7 | |||
| 0ae541671d | |||
| ef0d6c7290 | |||
| 2217509701 | |||
| 16e46a73f3 | |||
| 32a3690a3c | |||
| 526771751f | |||
| dfa6591675 | |||
| 6252517aac | |||
| 51e440fa03 | |||
| d82fb6f20a | |||
| 44de6a6cbe | |||
| 64e27cd87d | |||
| 60e75f8a2a | |||
| 57eda94dde | |||
| 723fb6c8be | |||
| 6c85ed1ba1 | |||
| 2e58274f23 | |||
| 4ade0afe03 | |||
| 93fb45c689 | |||
| 684a015c98 | |||
| f7fcd2e425 | |||
| c6c637fe21 | |||
| 33fc4d6495 | |||
| 33ff927522 | |||
| 2d39cdbff8 | |||
| 8d675810e8 | |||
| 8b25481c26 | |||
| 5fdf96f496 | |||
| b61991a023 | |||
| 91d302a201 | |||
| 35a1a62d50 | |||
| ac7a4cb94c | |||
| bacd7ef92f | |||
| 980dc44f4a | |||
| 2d648f84a9 | |||
| aef0943f61 | |||
| 3e146171cb | |||
| 24bbaceaa4 | |||
| 318cf132e9 | |||
| 8bbc143ed1 | |||
| 220d130c0f | |||
| e28a32a7c7 | |||
| 88f8b77d77 | |||
| 1066374909 | |||
| 34a2595dfb | |||
| 76fcd5cf25 | |||
| 32e6ed4eca | |||
| 2983c0be70 | |||
| e0bf6585de | |||
| 43af0ee514 | |||
| 3912d6aba9 | |||
| 871685e271 | |||
| 5e9daa9728 | |||
| 412bc1713a |
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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,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',
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -6,3 +6,12 @@
|
||||
.toolbar {
|
||||
-gtk-icon-style: symbolic;
|
||||
}
|
||||
|
||||
.red-tooltip {
|
||||
background-color: red;
|
||||
}
|
||||
|
||||
.yellow-tooltip {
|
||||
background-color: yellow;
|
||||
color: black;
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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].
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
@@ -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 ();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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, ¢er },
|
||||
{ "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;
|
||||
}
|
||||
|
||||
@@ -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, ],
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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("};")
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
@@ -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
@@ -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
|
||||
* doesn’t 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 class’s 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,
|
||||
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
@@ -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);
|
||||
|
||||
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
@@ -36,7 +36,7 @@
|
||||
extern IMAGE_DOS_HEADER __ImageBase;
|
||||
|
||||
static inline HMODULE
|
||||
this_module ()
|
||||
this_module (void)
|
||||
{
|
||||
return (HMODULE) &__ImageBase;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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,
|
||||
|
||||
@@ -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
@@ -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')
|
||||
|
||||
@@ -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
|
||||
|
||||
+1182
-1017
File diff suppressed because it is too large
Load Diff
@@ -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 ();
|
||||
}
|
||||
@@ -11,6 +11,7 @@ tests = [
|
||||
{ 'name': 'box' },
|
||||
{ 'name': 'button' },
|
||||
{ 'name': 'checkbutton' },
|
||||
{ 'name': 'colordialogbutton' },
|
||||
{ 'name': 'custom' },
|
||||
{ 'name': 'dialog' },
|
||||
{ 'name': 'entry' },
|
||||
|
||||
+46
-12
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user