Compare commits

..

9 Commits

Author SHA1 Message Date
Emmanuele Bassi
2855ea43a3 trashmonitor: Replace internal 1-bit fields with bool
Single bit fields cannot be used by address, and will overflow when
set to values that are bigger than one bit; the behaviour (if not the
size) of the C99 bool type is better defined.
2023-06-28 15:28:38 +01:00
Emmanuele Bassi
2a9296f54e calendar: Replace internal 1-bit fields with bool
Single bit fields cannot be used by address, and will overflow when
set to values that are bigger than one bit; the behaviour (if not the
size) of the C99 bool type is better defined.
2023-06-28 15:28:22 +01:00
Emmanuele Bassi
4c77a466af calendar: Remove unused field and translatable string
Since the switch to child widgets, GtkCalendar has stopped using the
"year_before" field, and does not need to compute whether the year
should be displayed before the month depending on the locale.
2023-06-28 15:27:10 +01:00
Emmanuele Bassi
91c7fc9cc5 colorswatch: Replace internal 1-bit fields with bool
Single bit fields cannot be used by address, and will overflow when
set to values that are bigger than one bit; the behaviour (if not the
size) of the C99 bool type is better defined.
2023-06-28 15:26:45 +01:00
Emmanuele Bassi
595e2e6001 coloreditor: Replace internal 1-bit fields with bool
Single bit fields cannot be used by address, and will overflow when
set to values that are bigger than one bit; the behaviour (if not the
size) of the C99 bool type is better defined.
2023-06-28 15:26:18 +01:00
Emmanuele Bassi
31e16ed7ba checkbutton: Replace internal 1-bit fields with bool
Single bit fields cannot be used by address, and will overflow when
set to values that are bigger than one bit; the behaviour (if not the
size) of the C99 bool type is better defined.
2023-06-28 15:25:59 +01:00
Emmanuele Bassi
2925ba2228 button: Replace internal 1-bit fields with bool
Single bit fields cannot be used by address, and will overflow when
set to values that are bigger than one bit; the behaviour (if not the
size) of the C99 bool type is better defined.
2023-06-28 15:25:37 +01:00
Emmanuele Bassi
40f6f11cae box: Replace internal 1-bit fields with bool
Single bit fields cannot be used by address, and will overflow when
set to values that are bigger than one bit; the behaviour (if not the
size) of the C99 bool type is better defined.
2023-06-28 15:25:06 +01:00
Emmanuele Bassi
f92dd63401 aboutdialog: Replace internal 1-bit fields with bool
Single bit fields cannot be used by address, and will overflow when
set to values that are bigger than one bit; the behaviour (if not the
size) of the C99 bool type is better defined.
2023-06-28 15:22:07 +01:00
93 changed files with 1072 additions and 2390 deletions

38
NEWS
View File

@@ -1,7 +1,4 @@
Overview of Changes in 4.11.5, xx-xx-xxxx
=========================================
Overview of Changes in 4.11.4, 03-07-2023
Overview of Changes in 4.11.4, xx-xx-xxxx
=========================================
* GtkFileChooser:
@@ -23,31 +20,16 @@ Overview of Changes in 4.11.4, 03-07-2023
* 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,
GtkStackSwitcher, GtkMediaControls, GtkColorDialogButton, GtkDropDown,
GtkInfoBar, GtkNotebook, GtkPrintUnixDialog, GtkModelButton
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
@@ -60,31 +42,19 @@ Overview of Changes in 4.11.4, 03-07-2023
- 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

View File

@@ -162,39 +162,27 @@ 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);
dark = prefer_dark || has_dark_suffix (theme);
if ((strcmp (theme, "Adwaita") == 0 && prefer_dark) || strcmp (theme, "HighContrastInverse") == 0)
dark = TRUE;
else
dark = FALSE;
g_free (theme);
return dark;
}

View File

@@ -158,7 +158,17 @@ demos_h = custom_target('gtk4 demo header',
command: [ find_program('geninclude.py'), '@OUTPUT@', '@INPUT@' ],
)
if can_use_objcopy_for_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 = 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')
# Create the resource blob
gtkdemo_gresource = custom_target('gtkdemo.gresource',
input : 'demo.gresource.xml',

View File

@@ -1,6 +1,16 @@
# demos/widget-factory
if can_use_objcopy_for_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 = 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')
# Create the resource blob
widgetfactory_gresource = custom_target('widgetfactory.gresource',
input : 'widget-factory.gresource.xml',

View File

@@ -16,7 +16,6 @@ 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
@@ -70,11 +69,12 @@ file to use.
Load style information from the given CSS file.
Render
^^^^^^
Screenshot
^^^^^^^^^^
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.
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.
This command accepts options to specify the ID of the toplevel object and a CSS
file to use.
@@ -96,11 +96,6 @@ file to use.
Overwrite an existing file.
Screenshot
^^^^^^^^^^
The ``screenshot`` command is an alias for ``render``.
Simplification
^^^^^^^^^^^^^^

View File

@@ -100,10 +100,6 @@ 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 */

View File

@@ -1552,7 +1552,7 @@ gdk_gl_context_check_extensions (GdkGLContext *context)
priv->has_sync = gdk_gl_context_check_version (context, "3.2", "3.0") ||
epoxy_has_gl_extension ("GL_ARB_sync") ||
epoxy_has_gl_extension ("GL_APPLE_sync");
epoxy_has_gl_extension ("GK_APPLE_sync");
#ifdef G_ENABLE_DEBUG
{

View File

@@ -931,216 +931,6 @@ 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`
@@ -1591,8 +1381,6 @@ gdk_display_create_vulkan_instance (GdkDisplay *display,
return FALSE;
}
gdk_display_create_pipeline_cache (display);
return TRUE;
}
@@ -1621,16 +1409,6 @@ 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)

View File

@@ -73,9 +73,6 @@ 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);

View File

@@ -139,6 +139,7 @@ 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;
@@ -1521,15 +1522,14 @@ 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);
x = (double) GET_X_LPARAM (msg->lParam) / impl->surface_scale;
y = (double) GET_Y_LPARAM (msg->lParam) / impl->surface_scale;
current_x = (gint16) GET_X_LPARAM (msg->lParam) / impl->surface_scale;
current_y = (gint16) 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,
x,
y,
current_x,
current_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 == current_root_x &&
msg->pt.y == current_root_y)
if (msg->pt.x / impl->surface_scale == current_root_x &&
msg->pt.y / impl->surface_scale == current_root_y)
break;
current_root_x = msg->pt.x;
current_root_y = msg->pt.y;
current_root_x = msg->pt.x / impl->surface_scale;
current_root_y = msg->pt.y / impl->surface_scale;
if (impl->drag_move_resize_context.op != GDK_WIN32_DRAGOP_NONE)
gdk_win32_surface_do_move_resize_drag (window, msg->pt.x, msg->pt.y);
gdk_win32_surface_do_move_resize_drag (window, current_root_x, current_root_y);
else if (_gdk_input_ignore_core == 0)
{
double x = (double) GET_X_LPARAM (msg->lParam) / impl->surface_scale;
double y = (double) GET_Y_LPARAM (msg->lParam) / impl->surface_scale;
current_x = (gint16) GET_X_LPARAM (msg->lParam) / impl->surface_scale;
current_y = (gint16) 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),
x,
y,
current_x,
current_y,
NULL);
_gdk_win32_append_event (event);

View File

@@ -271,10 +271,9 @@ winpointer_make_event (GdkDeviceWinpointer *device,
y /= impl->surface_scale;
state = 0;
/* Note that info->dwKeyStates is not reliable, use GetKeyState() */
if (GetKeyState (VK_CONTROL) < 0)
if (info->dwKeyStates & POINTER_MOD_CTRL)
state |= GDK_CONTROL_MASK;
if (GetKeyState (VK_SHIFT) < 0)
if (info->dwKeyStates & POINTER_MOD_SHIFT)
state |= GDK_SHIFT_MASK;
if (GetKeyState (VK_MENU) < 0)
state |= GDK_ALT_MASK;

View File

@@ -3535,8 +3535,6 @@ 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;
@@ -3652,16 +3650,6 @@ 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;

View File

@@ -137,12 +137,6 @@ 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_*).
*/

View File

@@ -165,7 +165,7 @@ void half_to_float4 (const guint16 h[4], float f[4]) __attribute__((ifunc ("reso
void float_to_half (const float *f, guint16 *h, int n) __attribute__((ifunc ("resolve_float_to_half")));
void half_to_float (const guint16 *h, float *f, int n) __attribute__((ifunc ("resolve_half_to_float")));
static void * __attribute__ ((no_sanitize_address))
static void *
resolve_float_to_half4 (void)
{
__builtin_cpu_init ();
@@ -175,7 +175,7 @@ resolve_float_to_half4 (void)
return float_to_half4_c;
}
static void * __attribute__ ((no_sanitize_address))
static void *
resolve_half_to_float4 (void)
{
__builtin_cpu_init ();
@@ -185,7 +185,7 @@ resolve_half_to_float4 (void)
return half_to_float4_c;
}
static void * __attribute__ ((no_sanitize_address))
static void *
resolve_float_to_half (void)
{
__builtin_cpu_init ();
@@ -195,7 +195,7 @@ resolve_float_to_half (void)
return float_to_half_c;
}
static void * __attribute__ ((no_sanitize_address))
static void *
resolve_half_to_float (void)
{
__builtin_cpu_init ();

View File

@@ -686,21 +686,17 @@ 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)));
if (!g_hash_table_contains (self->key_to_texture_id, key))
{
GskTextureKey *k;
k = g_memdup (key, sizeof *key);
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);
}
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);
}
/**

View File

@@ -803,8 +803,6 @@ 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

View File

@@ -13,12 +13,6 @@ 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);
@@ -29,9 +23,9 @@ void main() {
else if (u_mode == 1)
mask_value = 1.0 - mask.a;
else if (u_mode == 2)
mask_value = luminance (mask.rgb);
mask_value = (0.2126 * mask.r + 0.7152 * mask.g + 0.0722 * mask.b) * mask.a;
else if (u_mode == 3)
mask_value = mask.a - luminance (mask.rgb);
mask_value = 1.0 - (0.2126 * mask.r + 0.7152 * mask.g + 0.0722 * mask.b) * mask.a;
else
mask_value = 0.0;

View File

@@ -2421,7 +2421,6 @@ 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;
@@ -2697,7 +2696,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;
@@ -2735,7 +2734,6 @@ 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;
@@ -3702,7 +3700,8 @@ 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)
const graphene_vec4_t *color_offset,
gboolean multiply_alpha)
{
cairo_surface_t *surface, *image_surface;
guchar *data;
@@ -3740,6 +3739,13 @@ 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);
@@ -3762,8 +3768,6 @@ 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
@@ -3785,7 +3789,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);
apply_color_matrix_to_pattern (pattern, &self->color_matrix, &self->color_offset, FALSE);
cairo_set_source (cr, pattern);
cairo_paint (cr);
@@ -5646,50 +5650,6 @@ 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)
@@ -5712,18 +5672,28 @@ 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[]){ 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);
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);
break;
case GSK_MASK_MODE_LUMINANCE:
apply_luminance_to_pattern (mask_pattern, FALSE);
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);
break;
case GSK_MASK_MODE_INVERTED_LUMINANCE:
apply_luminance_to_pattern (mask_pattern, TRUE);
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);
break;
default:
g_assert_not_reached ();
@@ -5733,8 +5703,6 @@ gsk_mask_node_draw (GskRenderNode *node,
cairo_clip (cr);
cairo_mask (cr, mask_pattern);
cairo_pattern_destroy (mask_pattern);
}
static void
@@ -5745,12 +5713,6 @@ 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);
}

View File

@@ -453,21 +453,6 @@ 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,
@@ -1257,10 +1242,10 @@ parse_radial_gradient_node_internal (GtkCssParser *parser,
const Declaration declarations[] = {
{ "bounds", parse_rect, NULL, &bounds },
{ "center", parse_point, NULL, &center },
{ "hradius", parse_positive_double, NULL, &hradius },
{ "vradius", parse_positive_double, NULL, &vradius },
{ "start", parse_positive_double, NULL, &start },
{ "end", parse_positive_double, NULL, &end },
{ "hradius", parse_double, NULL, &hradius },
{ "vradius", parse_double, NULL, &vradius },
{ "start", parse_double, NULL, &start },
{ "end", parse_double, NULL, &end },
{ "stops", parse_stops, clear_stops, &stops },
};
GskRenderNode *result;
@@ -1350,7 +1335,7 @@ parse_inset_shadow_node (GtkCssParser *parser,
{ "dx", parse_double, NULL, &dx },
{ "dy", parse_double, NULL, &dy },
{ "spread", parse_double, NULL, &spread },
{ "blur", parse_positive_double, NULL, &blur }
{ "blur", parse_double, NULL, &blur }
};
parse_declarations (parser, context, declarations, G_N_ELEMENTS (declarations));
@@ -1752,7 +1737,7 @@ parse_outset_shadow_node (GtkCssParser *parser,
{ "dx", parse_double, NULL, &dx },
{ "dy", parse_double, NULL, &dy },
{ "spread", parse_double, NULL, &spread },
{ "blur", parse_positive_double, NULL, &blur }
{ "blur", parse_double, NULL, &blur }
};
parse_declarations (parser, context, declarations, G_N_ELEMENTS (declarations));
@@ -2032,7 +2017,7 @@ parse_blur_node (GtkCssParser *parser,
GskRenderNode *child = NULL;
double blur_radius = 1.0;
const Declaration declarations[] = {
{ "blur", parse_positive_double, NULL, &blur_radius },
{ "blur", parse_double, NULL, &blur_radius },
{ "child", parse_node, clear_node, &child },
};
GskRenderNode *result;
@@ -2492,15 +2477,6 @@ 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)
@@ -3710,7 +3686,6 @@ GBytes *
gsk_render_node_serialize (GskRenderNode *node)
{
Printer p;
GBytes *res;
printer_init (&p, node);
@@ -3730,9 +3705,5 @@ gsk_render_node_serialize (GskRenderNode *node)
render_node_print (&p, node);
}
res = g_string_free_to_bytes (g_steal_pointer (&p.str));
printer_clear (&p);
return res;
return g_string_free_to_bytes (p.str);
}

View File

@@ -103,7 +103,6 @@ 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([
@@ -198,7 +197,6 @@ libgsk = static_library('gsk',
gsk_private_sources,
gsk_enums,
gskresources,
gsk_private_vulkan_shader_headers,
],
dependencies: gsk_deps,
include_directories: [ confinc, ],

View File

@@ -2,8 +2,6 @@
#include "gskvulkanblendmodepipelineprivate.h"
#include "vulkan/resources/blend-mode.vert.h"
struct _GskVulkanBlendModePipeline
{
GObject parent_instance;
@@ -11,12 +9,89 @@ 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)
{
return &gsk_vulkan_blend_mode_info;
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;
}
static void

View File

@@ -2,19 +2,68 @@
#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)
{
return &gsk_vulkan_blur_info;
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;
}
static void
@@ -56,7 +105,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 radius)
double blur_radius)
{
GskVulkanBlurInstance *instance = (GskVulkanBlurInstance *) data;
@@ -68,7 +117,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->radius = radius;
instance->blur_radius = blur_radius;
instance->tex_id[0] = tex_id[0];
instance->tex_id[1] = tex_id[1];
}

View File

@@ -4,19 +4,91 @@
#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)
{
return &gsk_vulkan_border_info;
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;
}
static void
@@ -65,11 +137,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->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;
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;
}
}

View File

@@ -2,8 +2,6 @@
#include "gskvulkanboxshadowpipelineprivate.h"
#include "vulkan/resources/inset-shadow.vert.h"
#include "gskroundedrectprivate.h"
struct _GskVulkanBoxShadowPipeline
@@ -11,12 +9,82 @@ 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)
{
return &gsk_vulkan_inset_shadow_info;
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;
}
static void
@@ -62,7 +130,7 @@ gsk_vulkan_box_shadow_pipeline_collect_vertex_data (GskVulkanBoxShadowPipeline *
float spread,
float blur_radius)
{
GskVulkanInsetShadowInstance *instance = (GskVulkanInsetShadowInstance *) data;
GskVulkanBoxShadowInstance *instance = (GskVulkanBoxShadowInstance *) data;
gsk_rounded_rect_to_float (outline, offset, instance->outline);
instance->color[0] = color->red;

View File

@@ -2,19 +2,54 @@
#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)
{
return &gsk_vulkan_color_info;
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;
}
static void

View File

@@ -2,19 +2,61 @@
#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)
{
return &gsk_vulkan_texture_info;
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;
}
static void
@@ -63,7 +105,7 @@ gsk_vulkan_color_text_pipeline_collect_vertex_data (GskVulkanColorTextPipeline *
guint num_glyphs,
float scale)
{
GskVulkanTextureInstance *instances = (GskVulkanTextureInstance *) data;
GskVulkanColorTextInstance *instances = (GskVulkanColorTextInstance *) data;
int i;
int count = 0;
int x_position = 0;
@@ -79,7 +121,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;
GskVulkanTextureInstance *instance = &instances[count];
GskVulkanColorTextInstance *instance = &instances[count];
GskVulkanCachedGlyph *glyph;
glyph = gsk_vulkan_renderer_get_cached_glyph (renderer,

View File

@@ -2,19 +2,96 @@
#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)
{
return &gsk_vulkan_cross_fade_info;
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;
}
static void

View File

@@ -2,19 +2,93 @@
#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)
{
return &gsk_vulkan_color_matrix_info;
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;
}
static void
@@ -59,7 +133,7 @@ gsk_vulkan_effect_pipeline_collect_vertex_data (GskVulkanEffectPipeline *pipelin
const graphene_matrix_t *color_matrix,
const graphene_vec4_t *color_offset)
{
GskVulkanColorMatrixInstance *instance = (GskVulkanColorMatrixInstance *) data;
GskVulkanEffectInstance *instance = (GskVulkanEffectInstance *) data;
instance->rect[0] = rect->origin.x + offset->x;
instance->rect[1] = rect->origin.y + offset->y;

View File

@@ -2,19 +2,82 @@
#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)
{
return &gsk_vulkan_linear_info;
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;
}
static void
@@ -60,7 +123,7 @@ gsk_vulkan_linear_gradient_pipeline_collect_vertex_data (GskVulkanLinearGradient
gsize gradient_offset,
gsize n_stops)
{
GskVulkanLinearInstance *instance = (GskVulkanLinearInstance *) data;
GskVulkanLinearGradientInstance *instance = (GskVulkanLinearGradientInstance *) data;
instance->rect[0] = rect->origin.x + offset->x;
instance->rect[1] = rect->origin.y + offset->y;
@@ -71,7 +134,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->stop_offset = gradient_offset;
instance->offset = gradient_offset;
instance->stop_count = n_stops;
}

View File

@@ -5,8 +5,6 @@
#include "gskvulkanpushconstantsprivate.h"
#include "gskvulkanshaderprivate.h"
#include "gdk/gdkvulkancontextprivate.h"
#include <graphene.h>
typedef struct _GskVulkanPipelinePrivate GskVulkanPipelinePrivate;
@@ -89,7 +87,7 @@ gsk_vulkan_pipeline_new (GType pipeline_type,
priv->vertex_stride = vertex_input_state->pVertexBindingDescriptions[0].stride;
GSK_VK_CHECK (vkCreateGraphicsPipelines, device,
gdk_vulkan_context_get_pipeline_cache (context),
VK_NULL_HANDLE,
1,
&(VkGraphicsPipelineCreateInfo) {
.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
@@ -162,8 +160,6 @@ gsk_vulkan_pipeline_new (GType pipeline_type,
NULL,
&priv->pipeline);
gdk_vulkan_context_pipeline_cache_updated (context);
return self;
}

View File

@@ -418,12 +418,12 @@ gsk_vulkan_render_get_pipeline (GskVulkanRender *self,
{ "texture", 1, gsk_vulkan_color_text_pipeline_new },
{ "texture-clip", 1, gsk_vulkan_color_text_pipeline_new },
{ "texture-clip-rounded", 1, gsk_vulkan_color_text_pipeline_new },
{ "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 },
{ "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 },
};
g_return_val_if_fail (type < GSK_VULKAN_N_PIPELINES, NULL);

View File

@@ -2,19 +2,68 @@
#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)
{
return &gsk_vulkan_mask_info;
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;
}
static void
@@ -64,7 +113,7 @@ gsk_vulkan_text_pipeline_collect_vertex_data (GskVulkanTextPipeline *pipeline,
guint num_glyphs,
float scale)
{
GskVulkanMaskInstance *instances = (GskVulkanMaskInstance *) data;
GskVulkanTextInstance *instances = (GskVulkanTextInstance *) data;
int i;
int count = 0;
int x_position = 0;
@@ -80,7 +129,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;
GskVulkanMaskInstance *instance = &instances[count];
GskVulkanTextInstance *instance = &instances[count];
GskVulkanCachedGlyph *glyph;
glyph = gsk_vulkan_renderer_get_cached_glyph (renderer,

View File

@@ -2,19 +2,61 @@
#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)
{
return &gsk_vulkan_texture_info;
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;
}
static void

View File

@@ -3,7 +3,9 @@
#include "clip.vert.glsl"
#include "rounded-rect.glsl"
layout(location = 0) in mat3x4 inRect;
layout(location = 0) in vec4 inRect;
layout(location = 1) in vec4 inCornerWidths;
layout(location = 2) in vec4 inCornerHeights;
layout(location = 3) in vec4 inBorderWidths;
layout(location = 4) in mat4 inBorderColors;
@@ -42,47 +44,47 @@ void main() {
int slice_index = gl_VertexIndex / 6;
int vert_index = gl_VertexIndex % 6;
vec4 corner_widths = max (inRect[1], inBorderWidths.wyyw);
vec4 corner_heights = max (inRect[2], inBorderWidths.xxzz);
vec4 corner_widths = max (inCornerWidths, inBorderWidths.wyyw);
vec4 corner_heights = max (inCornerHeights, inBorderWidths.xxzz);
Rect rect;
switch (slice_index)
{
case SLICE_TOP_LEFT:
rect = rect_from_gsk (vec4(inRect[0].xy, corner_widths[TOP_LEFT], corner_heights[TOP_LEFT]));
rect = rect_from_gsk (vec4(inRect.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[0].x + corner_widths[TOP_LEFT], inRect[0].y, inRect[0].z - corner_widths[TOP_LEFT] - corner_widths[TOP_RIGHT], inBorderWidths[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_round_smaller_larger (rect);
outColor = inBorderColors[TOP];
break;
case SLICE_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_from_gsk (vec4(inRect.x + inRect.z - corner_widths[TOP_RIGHT], inRect.y, corner_widths[TOP_RIGHT], corner_heights[TOP_RIGHT]));
rect = rect_round_larger (rect);
break;
case SLICE_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_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_round_larger_smaller (rect);
outColor = inBorderColors[RIGHT];
break;
case SLICE_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_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_round_larger (rect);
break;
case SLICE_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_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_round_smaller_larger (rect);
break;
case SLICE_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]));
rect = rect_from_gsk (vec4(inRect.x, inRect.y + inRect.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[0].x, inRect[0].y + corner_heights[TOP_LEFT], inBorderWidths[LEFT], inRect[0].w - corner_heights[TOP_LEFT] - corner_heights[BOTTOM_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_round_larger_smaller (rect);
break;
}
@@ -97,7 +99,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[0].xyxy + vec4(0,0,inRect[0].zw), inRect[1], inRect[2]);
outRect = RoundedRect(inRect.xyxy + vec4(0,0,inRect.zw), inCornerWidths, inCornerHeights);
outRect = rounded_rect_scale (outRect, push.scale);
outBorderWidths = inBorderWidths * push.scale.yxyx;
}

View File

@@ -1,192 +0,0 @@
#!/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"
lines = open (sys.argv[1]).readlines()
matches = []
for line in lines:
match = re.search("^layout\(location = ([0-9]+)\) in ([a-z0-9]+) ([a-zA-Z0-9]+);$", line)
if not match:
if re.search("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'''#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']}")
match match['type']:
case "float":
print(f" float {match['name']};")
expected += 1
case "int":
print(f" gint32 {match['name']};")
expected += 1
case "uint":
print(f" guint32 {match['name']};")
expected += 1
case "uvec2":
print(f" guint32 {match['name']}[2];")
expected += 1
case "vec2":
print(f" float {match['name']}[2];")
expected += 1
case "vec4":
print(f" float {match['name']}[4];")
expected += 1
case "mat3x4":
print(f" float {match['name']}[12];")
expected += 3
case "mat4":
print(f" float {match['name']}[16];")
expected += 4
case _:
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:
match match['type']:
case "float":
print(
f''' {{
.location = {match['location']},
.binding = 0,
.format = VK_FORMAT_R32_SFLOAT,
.offset = G_STRUCT_OFFSET({struct_name}, {match['name']}),
}},''')
case "int":
print(
f''' {{
.location = {match['location']},
.binding = 0,
.format = VK_FORMAT_R32_SINT,
.offset = G_STRUCT_OFFSET({struct_name}, {match['name']}),
}},''')
case "uint":
print(
f''' {{
.location = {match['location']},
.binding = 0,
.format = VK_FORMAT_R32_UINT,
.offset = G_STRUCT_OFFSET({struct_name}, {match['name']}),
}},''')
case "uvec2":
print(
f''' {{
.location = {match['location']},
.binding = 0,
.format = VK_FORMAT_R32G32_UINT,
.offset = G_STRUCT_OFFSET({struct_name}, {match['name']}),
}},''')
case "vec2":
print(
f''' {{
.location = {match['location']},
.binding = 0,
.format = VK_FORMAT_R32G32_SFLOAT,
.offset = G_STRUCT_OFFSET({struct_name}, {match['name']}),
}},''')
case "vec4":
print(
f''' {{
.location = {match['location']},
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET({struct_name}, {match['name']}),
}},''')
case "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,
}},''')
case "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,
}},''')
case _:
raise Exception(f"Don't know what a {match['type']} is")
print(" },")
print("};")

View File

@@ -2,7 +2,9 @@
#include "clip.vert.glsl"
layout(location = 0) in mat3x4 inOutline;
layout(location = 0) in vec4 inOutline;
layout(location = 1) in vec4 inOutlineCornerWidths;
layout(location = 2) in vec4 inOutlineCornerHeights;
layout(location = 3) in vec4 inColor;
layout(location = 4) in vec2 inOffset;
layout(location = 5) in float inSpread;
@@ -24,15 +26,15 @@ vec2 offsets[6] = { vec2(0.0, 0.0),
vec2(1.0, 1.0) };
void main() {
vec4 rect = clip (inOutline[0]);
vec4 rect = clip (inOutline);
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[0];
outOutlineCornerWidths = inOutline[1];
outOutlineCornerHeights = inOutline[2];
outOutline = inOutline;
outOutlineCornerWidths = inOutlineCornerWidths;
outOutlineCornerHeights = inOutlineCornerHeights;
outColor = inColor;
outOffset = inOffset;
outSpread = inSpread;

View File

@@ -12,12 +12,12 @@ gsk_private_vulkan_include_shaders = [
]
gsk_private_vulkan_fragment_shaders = [
'blend-mode.frag',
'blendmode.frag',
'blur.frag',
'border.frag',
'color.frag',
'color-matrix.frag',
'cross-fade.frag',
'crossfade.frag',
'inset-shadow.frag',
'linear.frag',
'mask.frag',
@@ -26,12 +26,12 @@ gsk_private_vulkan_fragment_shaders = [
]
gsk_private_vulkan_vertex_shaders = [
'blend-mode.vert',
'blendmode.vert',
'blur.vert',
'border.vert',
'color.vert',
'color-matrix.vert',
'cross-fade.vert',
'crossfade.vert',
'inset-shadow.vert',
'linear.vert',
'mask.vert',
@@ -87,19 +87,6 @@ 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
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
gsk_private_vulkan_compiled_shaders += files(spv_shader, clip_spv_shader, clip_rounded_spv_shader)
endforeach

View File

@@ -2,7 +2,9 @@
#include "clip.vert.glsl"
layout(location = 0) in mat3x4 inOutline;
layout(location = 0) in vec4 inOutline;
layout(location = 1) in vec4 inOutlineCornerWidths;
layout(location = 2) in vec4 inOutlineCornerHeights;
layout(location = 3) in vec4 inColor;
layout(location = 4) in vec2 inOffset;
layout(location = 5) in float inSpread;
@@ -29,19 +31,19 @@ float radius_pixels(float radius) {
}
void main() {
vec4 rect = inOutline[0];
vec4 rect = inOutline;
float spread = inSpread + radius_pixels(inBlurRadius);
rect += vec4(inOffset - spread, vec2(2 * spread));
clip (inOutline[0]);
clip (inOutline);
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[0];
outOutlineCornerWidths = inOutline[1];
outOutlineCornerHeights = inOutline[2];
outOutline = inOutline;
outOutlineCornerWidths = inOutlineCornerWidths;
outOutlineCornerHeights = inOutlineCornerHeights;
outColor = inColor;
outOffset = inOffset;
outSpread = inSpread;

View File

@@ -263,7 +263,6 @@
#include <gtk/gtkstyleprovider.h>
#include <gtk/gtkswitch.h>
#include <gtk/gtksymbolicpaintable.h>
#include <gtk/gtktabbar.h>
#include <gtk/gtktext.h>
#include <gtk/gtktextbuffer.h>
#include <gtk/gtktextchild.h>

View File

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

View File

@@ -1333,8 +1333,6 @@ 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)

View File

@@ -86,10 +86,12 @@ enum {
typedef struct
{
gint16 spacing;
gint16 spacing;
guint homogeneous : 1;
guint baseline_pos : 2;
bool homogeneous;
/* GtkBaselinePosition */
guint baseline_pos : 2;
} GtkBoxPrivate;
static GParamSpec *props[LAST_PROP] = { NULL, };
@@ -369,14 +371,13 @@ void
gtk_box_set_homogeneous (GtkBox *box,
gboolean homogeneous)
{
bool is_homogeneous = !!homogeneous;
GtkBoxLayout *box_layout;
g_return_if_fail (GTK_IS_BOX (box));
homogeneous = !!homogeneous;
box_layout = GTK_BOX_LAYOUT (gtk_widget_get_layout_manager (GTK_WIDGET (box)));
if (homogeneous == gtk_box_layout_get_homogeneous (box_layout))
if (is_homogeneous == gtk_box_layout_get_homogeneous (box_layout))
return;
gtk_box_layout_set_homogeneous (box_layout, homogeneous);

View File

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

View File

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

View File

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

View File

@@ -76,8 +76,8 @@ struct _GtkColorEditor
int popup_position;
guint text_changed : 1;
guint use_alpha : 1;
bool text_changed;
bool use_alpha;
};
struct _GtkColorEditorClass
@@ -118,7 +118,7 @@ entry_set_rgba (GtkColorEditor *editor,
scale_round (color->green, 255),
scale_round (color->blue, 255));
gtk_editable_set_text (GTK_EDITABLE (editor->entry), text);
editor->text_changed = FALSE;
editor->text_changed = false;
g_free (text);
}
@@ -139,7 +139,7 @@ entry_apply (GtkWidget *entry,
gtk_color_chooser_set_rgba (GTK_COLOR_CHOOSER (editor), &color);
}
editor->text_changed = FALSE;
editor->text_changed = false;
g_free (text);
}
@@ -158,7 +158,7 @@ entry_text_changed (GtkWidget *entry,
GParamSpec *pspec,
GtkColorEditor *editor)
{
editor->text_changed = TRUE;
editor->text_changed = true;
}
static void
@@ -409,7 +409,7 @@ gtk_color_editor_init (GtkColorEditor *editor)
{
GtkEventController *controller;
editor->use_alpha = TRUE;
editor->use_alpha = true;
g_type_ensure (GTK_TYPE_COLOR_SCALE);
g_type_ensure (GTK_TYPE_COLOR_PLANE);
@@ -489,7 +489,7 @@ gtk_color_editor_get_property (GObject *object,
static void
gtk_color_editor_set_use_alpha (GtkColorEditor *editor,
gboolean use_alpha)
bool use_alpha)
{
if (editor->use_alpha != use_alpha)
{
@@ -573,7 +573,7 @@ gtk_color_editor_class_init (GtkColorEditorClass *class)
* @component: the component to edit, "h", "sv" or "a"
*
* Opens the edit popup for one of the color components.
*/
*/
gtk_widget_class_install_action (widget_class, "color.edit", "s", popup_edit);
}

View File

@@ -55,10 +55,11 @@ struct _GtkColorSwatch
GdkRGBA color;
char *icon;
guint has_color : 1;
guint use_alpha : 1;
guint selectable : 1;
guint has_menu : 1;
bool has_color;
bool use_alpha;
bool has_menu;
bool selectable;
GtkWidget *overlay_widget;
@@ -549,9 +550,9 @@ gtk_color_swatch_init (GtkColorSwatch *swatch)
GtkEventController *controller;
GtkGesture *gesture;
swatch->use_alpha = TRUE;
swatch->selectable = TRUE;
swatch->has_menu = TRUE;
swatch->use_alpha = true;
swatch->selectable = true;
swatch->has_menu = true;
swatch->color.red = 0.75;
swatch->color.green = 0.25;
swatch->color.blue = 0.25;
@@ -610,7 +611,7 @@ void
gtk_color_swatch_set_rgba (GtkColorSwatch *swatch,
const GdkRGBA *color)
{
swatch->has_color = TRUE;
swatch->has_color = true;
swatch->color = *color;
if (swatch->source)
gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (swatch->source), GTK_PHASE_CAPTURE);
@@ -711,21 +712,27 @@ gtk_color_swatch_set_can_drag (GtkColorSwatch *swatch,
void
gtk_color_swatch_set_use_alpha (GtkColorSwatch *swatch,
gboolean use_alpha)
gboolean value)
{
bool use_alpha = !!value;
if (use_alpha == swatch->use_alpha)
return;
swatch->use_alpha = use_alpha;
gtk_widget_queue_draw (GTK_WIDGET (swatch));
}
void
gtk_color_swatch_set_selectable (GtkColorSwatch *swatch,
gboolean selectable)
gboolean value)
{
bool selectable = !!value;
if (selectable == swatch->selectable)
return;
swatch->selectable = selectable;
update_accessible_properties (swatch);
g_object_notify (G_OBJECT (swatch), "selectable");
}

View File

@@ -44,7 +44,6 @@
#include "gtkbuilderprivate.h"
#include "gtkstringlist.h"
#include "gtkbox.h"
#include "gtktypebuiltins.h"
/**
* GtkDropDown:
@@ -105,8 +104,6 @@ struct _GtkDropDown
{
GtkWidget parent_instance;
gboolean uses_default_factory;
gboolean uses_default_list_factory;
GtkListItemFactory *factory;
GtkListItemFactory *list_factory;
GtkListItemFactory *header_factory;
@@ -127,8 +124,6 @@ struct _GtkDropDown
GtkWidget *search_entry;
GtkExpression *expression;
GtkStringFilterMatchMode search_match_mode;
guint enable_search : 1;
guint show_arrow : 1;
@@ -151,7 +146,6 @@ enum
PROP_ENABLE_SEARCH,
PROP_EXPRESSION,
PROP_SHOW_ARROW,
PROP_SEARCH_MATCH_MODE,
N_PROPS
};
@@ -285,7 +279,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), self->search_match_mode);
gtk_string_filter_set_match_mode (GTK_STRING_FILTER (filter), GTK_STRING_FILTER_MATCH_MODE_PREFIX);
}
else
filter = GTK_FILTER (gtk_every_filter_new ());
@@ -394,10 +388,6 @@ 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);
@@ -446,11 +436,6 @@ 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);
@@ -656,20 +641,7 @@ 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);
/**
@@ -822,10 +794,6 @@ 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);
}
@@ -841,8 +809,6 @@ 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;
}
/**
@@ -1006,12 +972,7 @@ 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);
self->uses_default_list_factory = TRUE;
}
self->uses_default_factory = factory != NULL;
gtk_list_view_set_factory (GTK_LIST_VIEW (self->popup_list), factory);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_FACTORY]);
}
@@ -1096,8 +1057,6 @@ 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]);
}
@@ -1235,9 +1194,6 @@ 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]);
@@ -1304,46 +1260,3 @@ 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;
}

View File

@@ -21,7 +21,6 @@
#include <gtk/gtkwidget.h>
#include <gtk/gtkexpression.h>
#include "gtk/gtkstringfilter.h"
G_BEGIN_DECLS
@@ -84,19 +83,11 @@ 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

View File

@@ -507,19 +507,13 @@ gtk_drop_target_handle_crossing (GtkEventController *controller,
graphene_point_init (&self->coords, x, y);
gtk_drop_target_start_drop (self, crossing->drop);
/* 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);
}
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);
}
if (preferred &&
gtk_drop_status (self->drop, self->actions, preferred))
{
@@ -539,7 +533,6 @@ 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);
}
}

View File

@@ -181,7 +181,7 @@ gtk_image_class_init (GtkImageClass *class)
/**
* GtkImage:file: (attributes org.gtk.Property.set=gtk_image_set_from_file)
*
* The `GFile` to display.
* The `GFile to display.
*/
image_props[PROP_FILE] =
g_param_spec_string ("file", NULL, NULL,

View File

@@ -22,7 +22,6 @@
#include "gtkmaplistmodel.h"
#include "gtkrbtreeprivate.h"
#include "gtksectionmodel.h"
#include "gtkprivate.h"
/**
@@ -55,8 +54,6 @@
*
* `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 {
@@ -210,43 +207,8 @@ 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 (GTK_TYPE_SECTION_MODEL, gtk_map_list_model_section_model_init))
G_IMPLEMENT_INTERFACE (G_TYPE_LIST_MODEL, gtk_map_list_model_model_init))
static void
gtk_map_list_model_items_changed_cb (GListModel *model,
@@ -375,7 +337,6 @@ 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);
}
@@ -647,9 +608,6 @@ 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
{

View File

@@ -1,571 +0,0 @@
#include "config.h"
#include "gtktabbar.h"
#include "gtkboxlayout.h"
#include "gtkenums.h"
#include "gtklabel.h"
#include "gtkorientable.h"
#include "gtkprivate.h"
#include "gtkselectionmodel.h"
#include "gtkstack.h"
#include "gtktabwidgetprivate.h"
#include "gtktypebuiltins.h"
#include "gtkwidgetprivate.h"
/**
* GtkTabBar:
*
* `GtkTabBar` is a stack switcher that can be used with `GtkStack`
* to prove an user experience similar to `GtkNotebook`.
*
* Since: 4.12
*/
struct _GtkTabBar {
GtkWidget parent_instance;
GtkStack *stack;
GtkSelectionModel *pages;
GPtrArray *tabs;
GtkPositionType position;
};
struct _GtkTabBarClass {
GtkWidget parent_class;
};
enum {
PROP_POSITION = 1,
PROP_STACK,
NUM_PROPERTIES,
PROP_ORIENTATION = NUM_PROPERTIES
};
static GParamSpec *properties[NUM_PROPERTIES] = { 0, };
G_DEFINE_TYPE_WITH_CODE (GtkTabBar, gtk_tab_bar, GTK_TYPE_WIDGET,
G_IMPLEMENT_INTERFACE (GTK_TYPE_ORIENTABLE, NULL))
static void
create_tabs (GtkTabBar *self)
{
for (unsigned int i = 0; i < g_list_model_get_n_items (G_LIST_MODEL (self->pages)); i++)
{
GtkStackPage *page;
GtkWidget *tab;
page = g_list_model_get_item (G_LIST_MODEL (self->pages), i);
tab = gtk_tab_widget_new (page, i);
gtk_widget_set_parent (tab, GTK_WIDGET (self));
/* Note: self->tabs matches pages for order, not tabs */
g_ptr_array_add (self->tabs, tab);
g_object_unref (page);
}
}
static void
clear_tabs (GtkTabBar *self)
{
for (unsigned int i = 0; i < self->tabs->len; i++)
{
GtkWidget *tab = g_ptr_array_index (self->tabs, i);
gtk_widget_unparent (tab);
}
g_ptr_array_set_size (self->tabs, 0);
}
static void
items_changed_cb (GListModel *model,
guint position,
guint removed,
guint added,
GtkTabBar *self)
{
clear_tabs (self);
create_tabs (self);
}
static void
selection_changed_cb (GtkSelectionModel *model,
guint position,
guint n_items,
GtkTabBar *self)
{
for (unsigned int i = position; i < position + n_items; i++)
{
GtkStackPage *page;
GtkWidget *tab;
gboolean selected;
page = g_list_model_get_item (G_LIST_MODEL (self->pages), i);
tab = g_ptr_array_index (self->tabs, i);
selected = gtk_selection_model_is_selected (self->pages, i);
if (selected)
gtk_widget_set_state_flags (tab, GTK_STATE_FLAG_SELECTED, FALSE);
else
gtk_widget_unset_state_flags (tab, GTK_STATE_FLAG_SELECTED);
gtk_accessible_update_state (GTK_ACCESSIBLE (tab),
GTK_ACCESSIBLE_STATE_SELECTED, selected,
-1);
g_object_unref (page);
}
}
static void
set_stack (GtkTabBar *self,
GtkStack *stack)
{
g_assert (self->stack == NULL);
if (stack)
{
self->stack = g_object_ref (stack);
self->pages = gtk_stack_get_pages (stack);
create_tabs (self);
selection_changed_cb (self->pages,
0, g_list_model_get_n_items (G_LIST_MODEL (self->pages)),
self);
g_signal_connect (self->pages,
"items-changed", G_CALLBACK (items_changed_cb), self);
g_signal_connect (self->pages,
"selection-changed", G_CALLBACK (selection_changed_cb), self);
}
}
static void
unset_stack (GtkTabBar *self)
{
if (self->stack)
{
g_signal_handlers_disconnect_by_func (self->pages, items_changed_cb, self);
g_signal_handlers_disconnect_by_func (self->pages, selection_changed_cb, self);
clear_tabs (self);
g_clear_object (&self->pages);
g_clear_object (&self->stack);
}
}
static void
gtk_tab_bar_init (GtkTabBar *self)
{
self->position = GTK_POS_TOP;
self->tabs = g_ptr_array_new ();
gtk_widget_add_css_class (GTK_WIDGET (self), "top");
}
static void
gtk_tab_bar_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GtkTabBar *self = GTK_TAB_BAR (object);
GtkLayoutManager *box_layout = gtk_widget_get_layout_manager (GTK_WIDGET (self));
switch (prop_id)
{
case PROP_ORIENTATION:
g_value_set_enum (value, gtk_orientable_get_orientation (GTK_ORIENTABLE (box_layout)));
break;
case PROP_POSITION:
g_value_set_enum (value, self->position);
break;
case PROP_STACK:
g_value_set_object (value, self->stack);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gtk_tab_bar_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
GtkTabBar *self = GTK_TAB_BAR (object);
GtkLayoutManager *box_layout = gtk_widget_get_layout_manager (GTK_WIDGET (self));
switch (prop_id)
{
case PROP_ORIENTATION:
{
GtkOrientation orientation = g_value_get_enum (value);
if (gtk_orientable_get_orientation (GTK_ORIENTABLE (box_layout)) != orientation)
{
gtk_orientable_set_orientation (GTK_ORIENTABLE (box_layout), orientation);
gtk_widget_update_orientation (GTK_WIDGET (self), orientation);
g_object_notify_by_pspec (object, pspec);
}
}
break;
case PROP_POSITION:
gtk_tab_bar_set_position (self, g_value_get_enum (value));
break;
case PROP_STACK:
gtk_tab_bar_set_stack (self, g_value_get_object (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gtk_tab_bar_dispose (GObject *object)
{
GtkTabBar *self = GTK_TAB_BAR (object);
unset_stack (self);
G_OBJECT_CLASS (gtk_tab_bar_parent_class)->dispose (object);
}
static void
gtk_tab_bar_finalize (GObject *object)
{
GtkTabBar *self = GTK_TAB_BAR (object);
g_assert (self->tabs->len == 0);
g_ptr_array_unref (self->tabs);
G_OBJECT_CLASS (gtk_tab_bar_parent_class)->finalize (object);
}
static void
gtk_tab_bar_switch_tab (GtkWidget *widget,
const char *action_name,
GVariant *parameters)
{
GtkTabBar *self = GTK_TAB_BAR (widget);
unsigned int position;
if (!self->stack)
return;
g_variant_get (parameters, "u", &position);
gtk_selection_model_select_item (self->pages, position, TRUE);
}
static GtkDirectionType
get_effective_direction (GtkTabBar *self,
GtkDirectionType direction)
{
/* Remap the directions into the effective direction it would be for a
* ltr-and-top tabbar.
*/
#define D(rest) GTK_DIR_##rest
static const GtkDirectionType translate_direction[2][4][6] = {
/* LEFT */ {{ D(TAB_FORWARD), D(TAB_BACKWARD), D(LEFT), D(RIGHT), D(UP), D(DOWN) },
/* RIGHT */ { D(TAB_BACKWARD), D(TAB_FORWARD), D(LEFT), D(RIGHT), D(DOWN), D(UP) },
/* TOP */ { D(TAB_FORWARD), D(TAB_BACKWARD), D(UP), D(DOWN), D(LEFT), D(RIGHT) },
/* BOTTOM */ { D(TAB_BACKWARD), D(TAB_FORWARD), D(DOWN), D(UP), D(LEFT), D(RIGHT) }},
/* LEFT */ {{ D(TAB_BACKWARD), D(TAB_FORWARD), D(LEFT), D(RIGHT), D(DOWN), D(UP) },
/* RIGHT */ { D(TAB_FORWARD), D(TAB_BACKWARD), D(LEFT), D(RIGHT), D(UP), D(DOWN) },
/* TOP */ { D(TAB_FORWARD), D(TAB_BACKWARD), D(UP), D(DOWN), D(RIGHT), D(LEFT) },
/* BOTTOM */ { D(TAB_BACKWARD), D(TAB_FORWARD), D(DOWN), D(UP), D(RIGHT), D(LEFT) }},
};
#undef D
int text_dir = gtk_widget_get_direction (GTK_WIDGET (self)) == GTK_TEXT_DIR_RTL ? 1 : 0;
return translate_direction[text_dir][self->position][direction];
}
static GtkPositionType
get_effective_position (GtkTabBar *self)
{
if (gtk_widget_get_direction (GTK_WIDGET (self)) == GTK_TEXT_DIR_RTL)
{
switch ((int)self->position)
{
case GTK_POS_LEFT:
return GTK_POS_RIGHT;
case GTK_POS_RIGHT:
return GTK_POS_LEFT;
default: ;
}
}
return self->position;
}
static gboolean
gtk_tab_bar_focus (GtkWidget *widget,
GtkDirectionType dir)
{
GtkTabBar *self = GTK_TAB_BAR (widget);
GtkWidget *old_focus_child;
unsigned int n_items;
GtkDirectionType direction;
direction = get_effective_direction (self, dir);
n_items = g_list_model_get_n_items (G_LIST_MODEL (self->pages));
old_focus_child = gtk_widget_get_focus_child (widget);
if (old_focus_child)
{
unsigned int position;
g_object_get (old_focus_child, "position", &position, NULL);
if (direction == GTK_DIR_TAB_FORWARD ||
direction == GTK_DIR_TAB_BACKWARD)
return FALSE;
if (direction == GTK_DIR_LEFT ||
direction == GTK_DIR_RIGHT)
{
GtkWidget *tab;
if (direction == GTK_DIR_LEFT)
position = (position + n_items - 1) % n_items;
else
position = (position + 1) % n_items;
tab = g_ptr_array_index (self->tabs, position);
gtk_widget_grab_focus (tab);
gtk_selection_model_select_item (self->pages, position, TRUE);
return TRUE;
}
if (gtk_widget_child_focus (old_focus_child, direction))
{
return TRUE;
}
}
else
{
for (unsigned int i = 0; i < n_items; i++)
{
if (gtk_selection_model_is_selected (self->pages, i))
{
GtkWidget *tab;
tab = g_ptr_array_index (self->tabs, i);
gtk_widget_grab_focus (tab);
return TRUE;
}
}
}
return gtk_widget_focus_child (widget, direction);
}
static void
gtk_tab_bar_class_init (GtkTabBarClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
object_class->get_property = gtk_tab_bar_get_property;
object_class->set_property = gtk_tab_bar_set_property;
object_class->dispose = gtk_tab_bar_dispose;
object_class->finalize = gtk_tab_bar_finalize;
widget_class->focus = gtk_tab_bar_focus;
/**
* GtkTabBar:position: (attributes org.gtk.Property.get=gtk_tab_bar_get_position org.gtk.Property.set=gtk_tab_bar_set_position)
*
* The position of the tab bar relative to the stack it controls.
*
* This information is used in keynav and tab rendering.
*/
properties[PROP_POSITION] =
g_param_spec_enum ("position", NULL, NULL,
GTK_TYPE_POSITION_TYPE,
GTK_POS_TOP,
GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
/**
* GtkTabBar:stack: (attributes org.gtk.Property.get=gtk_tab_bar_get_stack org.gtk.Property.set=gtk_tab_bar_set_stack)
*
* The stack that is controlled by this tab bar.
*/
properties[PROP_STACK] =
g_param_spec_object ("stack", NULL, NULL,
GTK_TYPE_STACK,
GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
g_object_class_install_properties (object_class, NUM_PROPERTIES, properties);
g_object_class_override_property (object_class, PROP_ORIENTATION, "orientation");
gtk_widget_class_install_action (widget_class, "tab.switch", "u",
gtk_tab_bar_switch_tab);
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BOX_LAYOUT);
gtk_widget_class_set_css_name (widget_class, I_("tabbar"));
gtk_widget_class_set_accessible_role (widget_class, GTK_ACCESSIBLE_ROLE_TAB_LIST);
}
/**
* gtk_tab_bar_new:
*
* Creates a new `GtkTabBar`.
*
* Returns: the newly created widget
*
* Since: 4.12
*/
GtkTabBar *
gtk_tab_bar_new (void)
{
return g_object_new (GTK_TYPE_TAB_BAR, NULL);
}
/**
* gtk_stack_bar_set_stack:
* @self: a `GtkTabBar`
* @stack: (nullable): a `GtkStack`
*
* Sets the stack that is controlled by this tab bar.
*
* Since: 4.12
*/
void
gtk_tab_bar_set_stack (GtkTabBar *self,
GtkStack *stack)
{
g_return_if_fail (GTK_IS_TAB_BAR (self));
g_return_if_fail (stack == NULL || GTK_IS_STACK (stack));
if (self->stack == stack)
return;
unset_stack (self);
set_stack (self, stack);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_STACK]);
}
/**
* gtk_tab_bar_get_stack:
* @self: a `GtkStack`
*
* Returns the stack that is controlled by this tab bar.
*
* Returns: (nullable): the stack
*
* Since: 4.12
*/
GtkStack *
gtk_tab_bar_get_stack (GtkTabBar *self)
{
g_return_val_if_fail (GTK_IS_TAB_BAR (self), NULL);
return self->stack;
}
static void
update_css_class_for_position (GtkTabBar *self)
{
GtkWidget *widget = GTK_WIDGET (self);
gtk_widget_remove_css_class (widget, "top");
gtk_widget_remove_css_class (widget, "bottom");
gtk_widget_remove_css_class (widget, "left");
gtk_widget_remove_css_class (widget, "right");
switch (get_effective_position (self))
{
case GTK_POS_TOP:
gtk_widget_add_css_class (widget, "top");
break;
case GTK_POS_BOTTOM:
gtk_widget_add_css_class (widget, "bottom");
break;
case GTK_POS_LEFT:
gtk_widget_add_css_class (widget, "left");
break;
case GTK_POS_RIGHT:
gtk_widget_add_css_class (widget, "right");
break;
default:
g_assert_not_reached ();
}
}
/**
* gtk_tab_bar_set_position:
* @self: a `GtkTabBar`
* @position: the position of the tabs
*
* Sets the position of the tab bar relative to
* the stack that it controls.
*
* This information is used in keynav and for
* drawing the tabs. Setting the position also
* updates the orientation accordingly.
*
* Since: 4.12
*/
void
gtk_tab_bar_set_position (GtkTabBar *self,
GtkPositionType position)
{
g_return_if_fail (GTK_IS_TAB_BAR (self));
if (self->position == position)
return;
self->position = position;
if (position == GTK_POS_LEFT || position == GTK_POS_RIGHT)
gtk_orientable_set_orientation (GTK_ORIENTABLE (self), GTK_ORIENTATION_VERTICAL);
else
gtk_orientable_set_orientation (GTK_ORIENTABLE (self), GTK_ORIENTATION_HORIZONTAL);
update_css_class_for_position (self);
gtk_widget_queue_resize (GTK_WIDGET (self));
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_POSITION]);
}
/**
* gtk_tab_bar_get_position:
* @self: a `GtkTabBar`
*
* Gets the position of the tab bar relative to
* the stack that it controls.
*
* Returns: the position of the tabss
*
* Since: 4.12
*/
GtkPositionType
gtk_tab_bar_get_position (GtkTabBar *self)
{
g_return_val_if_fail (GTK_IS_TAB_BAR (self), GTK_POS_TOP);
return self->position;
}

View File

@@ -1,24 +0,0 @@
#pragma once
#include <gtk/gtkstack.h>
#include <gtk/gtkwidget.h>
#define GTK_TYPE_TAB_BAR (gtk_tab_bar_get_type ())
G_DECLARE_FINAL_TYPE (GtkTabBar, gtk_tab_bar, GTK, TAB_BAR, GtkWidget)
GDK_AVAILABLE_IN_4_12
GtkTabBar * gtk_tab_bar_new (void);
GDK_AVAILABLE_IN_4_12
void gtk_tab_bar_set_stack (GtkTabBar *self,
GtkStack *stack);
GDK_AVAILABLE_IN_4_12
GtkStack * gtk_tab_bar_get_stack (GtkTabBar *self);
GDK_AVAILABLE_IN_4_12
void gtk_tab_bar_set_position (GtkTabBar *self,
GtkPositionType position);
GDK_AVAILABLE_IN_4_12
GtkPositionType gtk_tab_bar_get_position (GtkTabBar *self);

View File

@@ -1,277 +0,0 @@
#include "config.h"
#include "gtktabwidgetprivate.h"
#include "gtkaccessible.h"
#include "gtkbinlayout.h"
#include "gtkdropcontrollermotion.h"
#include "gtkgestureclick.h"
#include "gtklabel.h"
#include "gtkprivate.h"
#include "gtkstack.h"
#include "gtkwidget.h"
#define TIMEOUT_EXPAND 500
struct _GtkTabWidget {
GtkWidget parent_instance;
GtkStackPage *page;
GtkWidget *label;
unsigned int position;
unsigned int switch_timeout;
};
struct _GtkTabWidgetClass {
GtkWidget parent_class;
};
enum {
PROP_PAGE = 1,
PROP_POSITION,
NUM_PROPERTIES,
};
static GParamSpec *properties[NUM_PROPERTIES] = { 0, };
G_DEFINE_TYPE (GtkTabWidget, gtk_tab_widget, GTK_TYPE_WIDGET)
static void
pressed_cb (GtkGestureClick *gesture,
unsigned int n_press,
double x,
double y,
GtkTabWidget *self)
{
gtk_widget_activate_action (GTK_WIDGET (self), "tab.switch", "u", self->position);
}
static void
update_tab (GtkStackPage *page,
GParamSpec *pspec,
GtkTabWidget *self)
{
char *title;
char *icon_name;
gboolean needs_attention;
gboolean visible;
gboolean use_underline;
g_object_get (page,
"title", &title,
"icon-name", &icon_name,
"needs-attention", &needs_attention,
"visible", &visible,
"use-underline", &use_underline,
NULL);
gtk_label_set_label (GTK_LABEL (self->label), title);
gtk_accessible_update_property (GTK_ACCESSIBLE (self),
GTK_ACCESSIBLE_PROPERTY_LABEL, title,
-1);
gtk_widget_set_visible (GTK_WIDGET (self), visible && (title != NULL || icon_name != NULL));
if (needs_attention)
gtk_widget_add_css_class (GTK_WIDGET (self), "needs-attention");
else
gtk_widget_remove_css_class (GTK_WIDGET (self), "needs-attention");
g_free (title);
g_free (icon_name);
}
static void
unset_page (GtkTabWidget *self)
{
if (!self->page)
return;
g_signal_handlers_disconnect_by_func (self->page, update_tab, self);
g_clear_object (&self->page);
}
static void
set_page (GtkTabWidget *self,
GtkStackPage *page)
{
if (self->page == page)
return;
unset_page (self);
g_set_object (&self->page, page);
g_signal_connect (self->page, "notify", G_CALLBACK (update_tab), self);
update_tab (page, NULL, self);
}
static gboolean
gtk_tab_widget_switch_timeout (gpointer data)
{
GtkTabWidget *self = data;
gtk_widget_activate_action (GTK_WIDGET (self), "tab.switch", "u", self->position);
self->switch_timeout = 0;
return G_SOURCE_REMOVE;
}
static void
gtk_tab_widget_drag_enter (GtkDropControllerMotion *motion,
double x,
double y,
GtkTabWidget *self)
{
if ((gtk_widget_get_state_flags (GTK_WIDGET (self)) & GTK_STATE_FLAG_SELECTED) == 0)
{
self->switch_timeout = g_timeout_add (TIMEOUT_EXPAND,
gtk_tab_widget_switch_timeout,
self);
gdk_source_set_static_name_by_id (self->switch_timeout,
"[gtk] gtk_tab_widget_switch_timeout");
}
}
static void
gtk_tab_widget_drag_leave (GtkDropControllerMotion *motion,
GtkTabWidget *self)
{
if (self->switch_timeout)
{
g_source_remove (self->switch_timeout);
self->switch_timeout = 0;
}
}
static void
gtk_tab_widget_init (GtkTabWidget *self)
{
GtkEventController *controller;
gtk_widget_set_can_focus (GTK_WIDGET (self), TRUE);
gtk_widget_set_focusable (GTK_WIDGET (self), TRUE);
self->label = gtk_label_new ("");
gtk_widget_set_parent (self->label, GTK_WIDGET (self));
controller = GTK_EVENT_CONTROLLER (gtk_gesture_click_new ());
g_signal_connect (controller, "pressed", G_CALLBACK (pressed_cb), self);
gtk_widget_add_controller (GTK_WIDGET (self), controller);
controller = gtk_drop_controller_motion_new ();
g_signal_connect (controller, "enter", G_CALLBACK (gtk_tab_widget_drag_enter), self);
g_signal_connect (controller, "leave", G_CALLBACK (gtk_tab_widget_drag_leave), self);
gtk_widget_add_controller (GTK_WIDGET (self), controller);
}
static void
gtk_tab_widget_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GtkTabWidget *self = GTK_TAB_WIDGET (object);
switch (prop_id)
{
case PROP_PAGE:
g_value_set_object (value, self->page);
break;
case PROP_POSITION:
g_value_set_uint (value, self->position);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gtk_tab_widget_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
GtkTabWidget *self = GTK_TAB_WIDGET (object);
switch (prop_id)
{
case PROP_PAGE:
set_page (self, g_value_get_object (value));
break;
case PROP_POSITION:
self->position = g_value_get_uint (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gtk_tab_widget_dispose (GObject *object)
{
GtkTabWidget *self = GTK_TAB_WIDGET (object);
unset_page (self);
g_clear_pointer (&self->label, gtk_widget_unparent);
if (self->switch_timeout)
{
g_source_remove (self->switch_timeout);
self->switch_timeout = 0;
}
G_OBJECT_CLASS (gtk_tab_widget_parent_class)->dispose (object);
}
static void
gtk_tab_widget_finalize (GObject *object)
{
G_OBJECT_CLASS (gtk_tab_widget_parent_class)->finalize (object);
}
static void
gtk_tab_widget_class_init (GtkTabWidgetClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
object_class->get_property = gtk_tab_widget_get_property;
object_class->set_property = gtk_tab_widget_set_property;
object_class->dispose = gtk_tab_widget_dispose;
object_class->finalize = gtk_tab_widget_finalize;
properties[PROP_PAGE] =
g_param_spec_object ("page", NULL, NULL,
GTK_TYPE_STACK_PAGE,
GTK_PARAM_READWRITE);
properties[PROP_POSITION] =
g_param_spec_uint ("position", NULL, NULL,
0, G_MAXUINT, 0,
GTK_PARAM_READWRITE);
g_object_class_install_properties (object_class, NUM_PROPERTIES, properties);
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
gtk_widget_class_set_css_name (widget_class, I_("tab"));
gtk_widget_class_set_accessible_role (widget_class, GTK_ACCESSIBLE_ROLE_TAB);
}
GtkWidget *
gtk_tab_widget_new (GtkStackPage *page,
unsigned int position)
{
return g_object_new (GTK_TYPE_TAB_WIDGET,
"page", page,
"position", position,
NULL);
}

View File

@@ -1,10 +0,0 @@
#pragma once
#include <gtk/gtkwidget.h>
#include <gtk/gtkstack.h>
#define GTK_TYPE_TAB_WIDGET (gtk_tab_widget_get_type ())
G_DECLARE_FINAL_TYPE (GtkTabWidget, gtk_tab_widget, GTK, TAB_WIDGET, GtkWidget)
GtkWidget * gtk_tab_widget_new (GtkStackPage *page,
unsigned int position);

View File

@@ -33,10 +33,10 @@ struct _GtkTrashMonitor
GFileMonitor *file_monitor;
gulong file_monitor_changed_id;
gboolean pending;
bool pending;
int timeout_id;
guint has_trash : 1;
bool has_trash;
};
struct _GtkTrashMonitorClass
@@ -104,14 +104,14 @@ _gtk_trash_monitor_class_init (GtkTrashMonitorClass *class)
/* Updates the internal has_trash flag and emits the "trash-state-changed" signal */
static void
update_has_trash_and_notify (GtkTrashMonitor *monitor,
gboolean has_trash)
bool has_trash)
{
if (monitor->has_trash == !!has_trash)
if (monitor->has_trash == has_trash)
return;
monitor->has_trash = !!has_trash;
monitor->has_trash = has_trash;
g_signal_emit (monitor, signals[TRASH_STATE_CHANGED], 0);
g_signal_emit (monitor, signals[TRASH_STATE_CHANGED], 0);
}
/* Use G_FILE_ATTRIBUTE_TRASH_ITEM_COUNT since we only want to know whether the
@@ -127,7 +127,7 @@ trash_query_info_cb (GObject *source,
GtkTrashMonitor *monitor = GTK_TRASH_MONITOR (user_data);
GFileInfo *info;
guint32 item_count;
gboolean has_trash = FALSE;
bool has_trash = false;
info = g_file_query_info_finish (G_FILE (source), result, NULL);
@@ -155,7 +155,7 @@ recompute_trash_state_cb (gpointer data)
monitor->timeout_id = 0;
if (monitor->pending)
{
monitor->pending = FALSE;
monitor->pending = false;
recompute_trash_state (monitor);
}
@@ -173,7 +173,7 @@ recompute_trash_state (GtkTrashMonitor *monitor)
*/
if (monitor->timeout_id > 0)
{
monitor->pending = TRUE;
monitor->pending = true;
return;
}
@@ -213,7 +213,7 @@ _gtk_trash_monitor_init (GtkTrashMonitor *monitor)
file = g_file_new_for_uri ("trash:///");
monitor->file_monitor = g_file_monitor_file (file, G_FILE_MONITOR_NONE, NULL, NULL);
monitor->pending = FALSE;
monitor->pending = false;
monitor->timeout_id = 0;
g_object_unref (file);

View File

@@ -36,7 +36,7 @@
extern IMAGE_DOS_HEADER __ImageBase;
static inline HMODULE
this_module (void)
this_module ()
{
return (HMODULE) &__ImageBase;
}

View File

@@ -243,8 +243,6 @@ 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
@@ -259,8 +257,6 @@ 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

View File

@@ -110,11 +110,12 @@ static struct {
};
static FixSeverity
check_accessibility_errors (GtkATContext *context,
GtkAccessibleRole role,
GArray *context_elements,
char **hint)
check_accessibility_errors (GtkWidget *widget,
GArray *context_elements,
char **hint)
{
GtkAccessibleRole role;
GtkATContext *context;
gboolean label_set;
const char *role_name;
GEnumClass *states;
@@ -123,8 +124,11 @@ check_accessibility_errors (GtkATContext *context,
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);
@@ -310,23 +314,6 @@ check_accessibility_errors (GtkATContext *context,
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,
@@ -340,7 +327,7 @@ recurse_child_widgets (GtkA11yOverlay *self,
if (!gtk_widget_get_mapped (widget))
return;
severity = check_widget_accessibility_errors (widget, self->context, &hint);
severity = check_accessibility_errors (widget, self->context, &hint);
if (severity != SEVERITY_GOOD)
{

View File

@@ -95,7 +95,6 @@ gtk_private_sources = files([
'gtkcssstylechange.c',
'gtkcssstyleproperty.c',
'gtkcssstylepropertyimpl.c',
'gtktabwidget.c',
'gtkcsstransformvalue.c',
'gtkcsstransientnode.c',
'gtkcsstransition.c',
@@ -366,7 +365,6 @@ gtk_public_sources = files([
'gtkstyleprovider.c',
'gtkswitch.c',
'gtksymbolicpaintable.c',
'gtktabbar.c',
'gtktestatcontext.c',
'gtktestutils.c',
'gtktext.c',
@@ -596,7 +594,6 @@ gtk_public_headers = files([
'gtkstyleprovider.h',
'gtkswitch.h',
'gtksymbolicpaintable.h',
'gtktabbar.h',
'gtktestatcontext.h',
'gtktestutils.h',
'gtktext.h',
@@ -761,7 +758,17 @@ if not fs.exists('theme/Default/Default-light.css')
endif
if can_use_objcopy_for_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 = 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')
# Create the resource blob
gtk_gresource = custom_target('gtk.gresource',
input : gtk_gresources_xml,

View File

@@ -2103,94 +2103,6 @@ menubar {
}
/************
* Tabbar *
************/
tabbar {
padding: 1px;
border-color: $borders_color;
border-width: 1px;
background-color: $dark_fill;
margin: -1px;
&.top {
border-bottom-style: solid;
margin-bottom: -2px;
> tab {
&:hover { box-shadow: inset 0 -4px $borders_color; }
&:selected { box-shadow: inset 0 -4px $selected_bg_color; }
}
}
&.bottom {
border-top-style: solid;
margin-top: -2px;
> tab {
&:hover { box-shadow: inset 0 4px $borders_color; }
&:selected { box-shadow: inset 0 4px $selected_bg_color; }
}
}
&.left {
border-right-style: solid;
margin-right: -2px;
> tab {
&:hover { box-shadow: inset -4px 0 $borders_color; }
&:selected { box-shadow: inset -4px 0 $selected_bg_color; }
}
}
&.right {
border-left-style: solid;
margin-left: -2px;
> tab {
&:hover { box-shadow: inset 4px 0 $borders_color; }
&:selected { box-shadow: inset 4px 0 $selected_bg_color; }
}
}
> tab {
transition: $focus_transition;
min-height: 30px;
min-width: 30px;
padding: 3px 12px;
color: $fg_color;
font-weight: normal;
border-width: 1px; // for reorderable tabs
border-color: transparent; //
&:hover {
color: $fg_color;
background-color: darken($dark_fill,4%);
&.reorderable-page {
border-color: transparentize($borders_color, 0.7);
background-color: transparentize($bg_color, 0.8);
}
}
&:not(:selected) {
outline-color: transparent;
}
&:selected {
color: $fg_color;
&.reorderable-page {
border-color: transparentize($borders_color, 0.5);
background-color: transparentize($bg_color, 0.5);
&:hover { background-color: transparentize($bg_color, 0.3); }
}
}
}
&.top > tab { padding-bottom: 4px; }
&.bottom > tab { padding-top: 4px; }
}
/*************
* Notebooks *
*************/

View File

@@ -8,4 +8,3 @@ leak:libgio-2.0.so
leak:libcairo.so
leak:libpixman-1.so
leak:librsvg-2.so
leak:libxkbcommon.so

View File

@@ -1,5 +1,5 @@
project('gtk', 'c',
version: '4.11.5',
version: '4.11.4',
default_options: [
'buildtype=debugoptimized',
'warning_level=1',
@@ -737,27 +737,6 @@ 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')

View File

@@ -6,7 +6,6 @@ static void
test_name_content (void)
{
GtkWidget *window, *label1, *label2, *box, *button;
GtkATContext *context;
char *name;
label1 = gtk_label_new ("a");
@@ -22,32 +21,24 @@ test_name_content (void)
gtk_window_set_child (GTK_WINDOW (window), button);
gtk_window_present (GTK_WINDOW (window));
context = gtk_accessible_get_at_context (GTK_ACCESSIBLE (label1));
name = gtk_at_context_get_name (context);
name = gtk_at_context_get_name (gtk_accessible_get_at_context (GTK_ACCESSIBLE (label1)));
g_assert_cmpstr (name, ==, "a");
g_free (name);
g_object_unref (context);
/* this is because generic doesn't allow naming */
context = gtk_accessible_get_at_context (GTK_ACCESSIBLE (box));
name = gtk_at_context_get_name (context);
name = gtk_at_context_get_name (gtk_accessible_get_at_context (GTK_ACCESSIBLE (box)));
g_assert_cmpstr (name, ==, "");
g_free (name);
g_object_unref (context);
context = gtk_accessible_get_at_context (GTK_ACCESSIBLE (button));
name = gtk_at_context_get_name (context);
name = gtk_at_context_get_name (gtk_accessible_get_at_context (GTK_ACCESSIBLE (button)));
g_assert_cmpstr (name, ==, "a b");
g_free (name);
g_object_unref (context);
gtk_widget_set_visible (label2, FALSE);
context = gtk_accessible_get_at_context (GTK_ACCESSIBLE (button));
name = gtk_at_context_get_name (context);
name = gtk_at_context_get_name (gtk_accessible_get_at_context (GTK_ACCESSIBLE (button)));
g_assert_cmpstr (name, ==, "a");
g_free (name);
g_object_unref (context);
gtk_window_destroy (GTK_WINDOW (window));
}
@@ -56,7 +47,6 @@ static void
test_name_tooltip (void)
{
GtkWidget *window, *image;
GtkATContext *context;
char *name;
image = gtk_image_new ();
@@ -67,14 +57,10 @@ test_name_tooltip (void)
gtk_widget_set_tooltip_text (image, "tooltip");
context = gtk_accessible_get_at_context (GTK_ACCESSIBLE (image));
name = gtk_at_context_get_name (context);
name = gtk_at_context_get_name (gtk_accessible_get_at_context (GTK_ACCESSIBLE (image)));
g_assert_cmpstr (name, ==, "tooltip");
g_free (name);
g_object_unref (context);
gtk_window_destroy (GTK_WINDOW (window));
}
@@ -82,7 +68,6 @@ static void
test_name_menubutton (void)
{
GtkWidget *window, *widget;
GtkATContext *context;
char *name;
widget = gtk_menu_button_new ();
@@ -94,14 +79,10 @@ test_name_menubutton (void)
gtk_widget_set_tooltip_text (widget, "tooltip");
context = gtk_accessible_get_at_context (GTK_ACCESSIBLE (widget));
name = gtk_at_context_get_name (context);
name = gtk_at_context_get_name (gtk_accessible_get_at_context (GTK_ACCESSIBLE (widget)));
g_assert_cmpstr (name, ==, "tooltip");
g_free (name);
g_object_unref (context);
gtk_window_destroy (GTK_WINDOW (window));
}
@@ -109,7 +90,6 @@ static void
test_name_label (void)
{
GtkWidget *window, *image;
GtkATContext *context;
char *name;
char *desc;
@@ -128,10 +108,8 @@ test_name_label (void)
GTK_ACCESSIBLE_PROPERTY_LABEL, "label",
-1);
context = gtk_accessible_get_at_context (GTK_ACCESSIBLE (image));
name = gtk_at_context_get_name (context);
desc = gtk_at_context_get_description (context);
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)));
g_assert_cmpstr (name, ==, "label");
g_assert_cmpstr (desc, ==, "tooltip");
@@ -139,8 +117,6 @@ test_name_label (void)
g_free (name);
g_free (desc);
g_object_unref (context);
gtk_window_destroy (GTK_WINDOW (window));
}
@@ -148,7 +124,6 @@ static void
test_name_prohibited (void)
{
GtkWidget *window, *widget;
GtkATContext *context;
char *name;
char *desc;
@@ -161,10 +136,8 @@ test_name_prohibited (void)
gtk_window_set_child (GTK_WINDOW (window), widget);
gtk_window_present (GTK_WINDOW (window));
context = gtk_accessible_get_at_context (GTK_ACCESSIBLE (widget));
name = gtk_at_context_get_name (context);
desc = gtk_at_context_get_description (context);
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)));
g_assert_cmpstr (name, ==, "");
g_assert_cmpstr (desc, ==, "");
@@ -172,8 +145,6 @@ test_name_prohibited (void)
g_free (name);
g_free (desc);
g_object_unref (context);
gtk_window_destroy (GTK_WINDOW (window));
}
@@ -181,7 +152,6 @@ 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);
@@ -190,20 +160,16 @@ 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 (context) == 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);
gtk_range_set_value (GTK_RANGE (scale), 50);
name = gtk_at_context_get_name (context);
name = gtk_at_context_get_name (gtk_accessible_get_at_context (GTK_ACCESSIBLE (scale)));
g_assert_cmpstr (name, ==, "50");
g_free (name);
g_object_unref (context);
gtk_window_destroy (GTK_WINDOW (window));
}

View File

@@ -298,12 +298,8 @@ 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);
@@ -408,12 +404,8 @@ 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);

View File

@@ -1,14 +0,0 @@
clip {
clip: 0 0 40 40;
child: mask {
mode: inverted-alpha;
source: color {
bounds: 0 0 100 100;
color: rebeccapurple;
}
mask: color {
bounds: 40 40 60 60;
color: black;
}
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 129 B

View File

@@ -1,43 +0,0 @@
mask {
source: color {
bounds: 0 0 50 50;
color: rgb(255,0,0);
}
mask: color {
bounds: 0 0 50 50;
color: rgba(204,204,204,0.666667);
}
}
mask {
mode: luminance;
source: color {
bounds: 50 0 50 50;
color: rgb(255,0,0);
}
mask: color {
bounds: 50 0 50 50;
color: rgba(204,204,204,0.666667);
}
}
mask {
mode: inverted-alpha;
source: color {
bounds: 0 50 50 50;
color: rgb(255,0,0);
}
mask: color {
bounds: 0 50 50 50;
color: rgba(204,204,204,0.666667);
}
}
mask {
mode: inverted-luminance;
source: color {
bounds: 50 50 50 50;
color: rgb(255,0,0);
}
mask: color {
bounds: 50 50 50 50;
color: rgba(204,204,204,0.666667);
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 337 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 223 B

After

Width:  |  Height:  |  Size: 255 B

View File

@@ -65,9 +65,7 @@ compare_render_tests = [
'invalid-transform',
'issue-3615',
'mask',
'mask-clipped-inverted-alpha',
'mask-modes',
'mask-modes-with-alpha',
'nested-rounded-clips',
'opacity_clip',
'opacity-overdraw',

View File

@@ -52,41 +52,6 @@ model_to_string (GListModel *model)
return g_string_free (string, FALSE);
}
static char *
section_model_to_string (GListModel *model)
{
GString *string = g_string_new (NULL);
guint i, s, e;
if (!GTK_IS_SECTION_MODEL (model))
return model_to_string (model);
i = 0;
while (i < g_list_model_get_n_items (model))
{
gtk_section_model_get_section (GTK_SECTION_MODEL (model), i, &s, &e);
g_assert (s == i);
if (i > 0)
g_string_append (string, " ");
g_string_append (string, "[");
for (; i < e; i++)
{
if (i > s)
g_string_append (string, " ");
g_string_append_printf (string, "%u", get (model, i));
}
g_string_append (string, "]");
i = e;
}
return g_string_free (string, FALSE);
}
static GListStore *
new_store (guint start,
guint end,
@@ -141,14 +106,6 @@ add (GListStore *store,
g_free (s); \
}G_STMT_END
#define assert_section_model(model, expected) G_STMT_START{ \
char *s = section_model_to_string (G_LIST_MODEL (model)); \
if (!g_str_equal (s, expected)) \
g_assertion_message_cmpstr (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \
#model " == " #expected, s, "==", expected); \
g_free (s); \
}G_STMT_END
#define assert_changes(model, expected) G_STMT_START{ \
GString *changes = g_object_get_qdata (G_OBJECT (model), changes_quark); \
if (!g_str_equal (changes->str, expected)) \
@@ -207,21 +164,6 @@ items_changed (GListModel *model,
}
}
static void
sections_changed (GListModel *model,
guint position,
guint n_items,
GString *changes)
{
g_assert_true (n_items != 0);
if (changes->len)
g_string_append (changes, ", ");
g_string_append_printf (changes, "s%u:%u", position, n_items);
}
static void
notify_n_items (GObject *object,
GParamSpec *pspec,
@@ -257,18 +199,17 @@ map_multiply (gpointer item,
}
static GtkMapListModel *
new_model (GListModel *store)
new_model (GListStore *store)
{
GtkMapListModel *result;
GString *changes;
if (store)
g_object_ref (store);
result = gtk_map_list_model_new (store, map_multiply, GUINT_TO_POINTER (2), NULL);
result = gtk_map_list_model_new (G_LIST_MODEL (store), map_multiply, GUINT_TO_POINTER (2), NULL);
changes = g_string_new ("");
g_object_set_qdata_full (G_OBJECT(result), changes_quark, changes, free_changes);
g_signal_connect (result, "items-changed", G_CALLBACK (items_changed), changes);
g_signal_connect (result, "sections-changed", G_CALLBACK (sections_changed), changes);
g_signal_connect (result, "notify::n-items", G_CALLBACK (notify_n_items), changes);
return result;
@@ -293,7 +234,7 @@ test_create (void)
GListStore *store;
store = new_store (1, 5, 1);
map = new_model (G_LIST_MODEL (store));
map = new_model (store);
assert_model (map, "2 4 6 8 10");
assert_changes (map, "");
@@ -334,7 +275,7 @@ test_set_map_func (void)
GListStore *store;
store = new_store (1, 5, 1);
map = new_model (G_LIST_MODEL (store));
map = new_model (store);
assert_model (map, "2 4 6 8 10");
assert_changes (map, "");
@@ -361,7 +302,7 @@ test_add_items (void)
GListStore *store;
store = new_store (1, 5, 1);
map = new_model (G_LIST_MODEL (store));
map = new_model (store);
assert_model (map, "2 4 6 8 10");
assert_changes (map, "");
@@ -377,7 +318,7 @@ test_remove_items (void)
GListStore *store;
store = new_store (1, 5, 1);
map = new_model (G_LIST_MODEL (store));
map = new_model (store);
assert_model (map, "2 4 6 8 10");
assert_changes (map, "");
@@ -393,7 +334,7 @@ test_splice (void)
GListStore *store;
store = new_store (1, 5, 1);
map = new_model (G_LIST_MODEL (store));
map = new_model (store);
assert_model (map, "2 4 6 8 10");
assert_changes (map, "");
@@ -402,61 +343,6 @@ test_splice (void)
assert_changes (map, "2-2+2");
}
static int
by_n (gconstpointer p1,
gconstpointer p2,
gpointer data)
{
guint n1 = GPOINTER_TO_UINT (g_object_get_qdata (G_OBJECT (p1), number_quark));
guint n2 = GPOINTER_TO_UINT (g_object_get_qdata (G_OBJECT (p2), number_quark));
unsigned int n = GPOINTER_TO_UINT (data);
n1 = n1 / n;
n2 = n2 / n;
if (n1 < n2)
return -1;
else if (n1 > n2)
return 1;
else
return 0;
}
static int
compare (gconstpointer first,
gconstpointer second,
gpointer unused)
{
return GPOINTER_TO_UINT (g_object_get_qdata (G_OBJECT (first), number_quark))
- GPOINTER_TO_UINT (g_object_get_qdata (G_OBJECT (second), number_quark));
}
static void
test_sections (void)
{
GtkMapListModel *map;
GListStore *store;
GtkSortListModel *sorted;
GtkSorter *sorter;
store = new_store (1, 10, 1);
sorted = gtk_sort_list_model_new (G_LIST_MODEL (store),
GTK_SORTER (gtk_custom_sorter_new (compare, NULL, NULL)));
map = new_model (G_LIST_MODEL (sorted));
assert_model (map, "2 4 6 8 10 12 14 16 18 20");
assert_section_model (map, "[2 4 6 8 10 12 14 16 18 20]");
assert_changes (map, "");
sorter = GTK_SORTER (gtk_custom_sorter_new (by_n, GUINT_TO_POINTER (3), NULL));
gtk_sort_list_model_set_section_sorter (sorted, sorter);
g_object_unref (sorter);
assert_section_model (map, "[2 4] [6 8 10] [12 14 16] [18 20]");
assert_changes (map, "s0:10");
g_object_unref (map);
}
int
main (int argc, char *argv[])
{
@@ -473,7 +359,6 @@ main (int argc, char *argv[])
g_test_add_func ("/maplistmodel/add_items", test_add_items);
g_test_add_func ("/maplistmodel/remove_items", test_remove_items);
g_test_add_func ("/maplistmodel/splice", test_splice);
g_test_add_func ("/maplistmodel/sections", test_sections);
return g_test_run ();
}

View File

@@ -1,10 +1,4 @@
#!/usr/bin/env python3
#
# Copyright © 2021 Chun-wei Fan.
#
# SPDX-License-Identifier: LGPL-2.1-or-later
#
# Original author: Chun-wei Fan <fanc999@yahoo.com.tw>
"""
This script generates a Windows manifest file and optionally a resource file to
@@ -14,99 +8,82 @@ determine whether a specified program requires UAC elevation
import os
import argparse
DOMAIN_NAME = "gnome"
DOMAIN_NAME='gnome'
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument(
"-p", "--package", required=True, help="package name of the executable"
)
parser.add_argument("-n", "--name", required=True, help="name of executable")
parser.add_argument(
"--pkg-version", required=True, dest="version", help="version of package"
)
parser.add_argument(
"--require-admin",
action="store_true",
dest="admin",
default=False,
help="require admin access to application",
)
parser.add_argument(
"--input-resource-file",
dest="resource",
default=None,
help="existing .rc file to embed UAC manifest (do not generate a new .rc file), must have included windows.h in it",
)
parser.add_argument(
"--output-dir",
dest="outdir",
default=None,
help="directory to output resulting files",
)
parser = argparse.ArgumentParser(
description=__doc__)
parser.add_argument('-p', '--package', required=True,
help='package name of the executable')
parser.add_argument('-n', '--name', required=True,
help='name of executable')
parser.add_argument('--pkg-version', required=True, dest='version',
help='version of package')
parser.add_argument('--require-admin', action='store_true', dest='admin',
default=False,
help='require admin access to application')
parser.add_argument('--input-resource-file', dest='resource',
default=None,
help='existing .rc file to embed UAC manifest (do not generate a new .rc file), must have included windows.h in it')
parser.add_argument('--output-dir', dest='outdir',
default=None,
help='directory to output resulting files')
args = parser.parse_args()
if args.resource is not None:
if not os.path.isfile(args.resource):
raise FileNotFoundError(
"Specified resource file '%s' does not exist" % args.resource
)
raise FileNotFoundError("Specified resource file '%s' does not exist" % args.resource)
generate_manifest(args.package, args.name, args.version, args.admin, args.outdir)
write_rc_file(args.name, args.resource, args.outdir)
def generate_manifest(package, name, version, admin, outdir):
if version.count(".") == 0:
manifest_package_version = version + ".0.0.0"
elif version.count(".") == 1:
manifest_package_version = version + ".0.0"
elif version.count(".") == 2:
manifest_package_version = version + ".0"
elif version.count(".") == 3:
if version.count('.') == 0:
manifest_package_version = version + '.0.0.0'
elif version.count('.') == 1:
manifest_package_version = version + '.0.0'
elif version.count('.') == 2:
manifest_package_version = version + '.0'
elif version.count('.') == 3:
manifest_package_version = version
else:
parts = version.split(".")
manifest_package_version = ""
parts = version.split('.')
manifest_package_version = ''
for x in (0, 1, 2, 3):
if x == 0:
manifest_package_version += parts[x]
else:
manifest_package_version += "." + parts[x]
manifest_package_version += '.' + parts[x]
if outdir is not None:
output_file_base_name = os.path.join(outdir, name)
else:
output_file_base_name = name
outfile = open(output_file_base_name + ".exe.manifest", "w+")
outfile.write("<?xml version='1.0' encoding='UTF-8' standalone='yes'?>\n")
outfile.write(
"<assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'>\n"
)
outfile.write(" <assemblyIdentity version='%s'\n" % manifest_package_version)
outfile.write(" processorArchitecture='*'\n")
outfile.write(" name='%s.%s.%s.exe'\n" % (DOMAIN_NAME, package, name))
outfile.write(" type='win32' />\n")
outfile.write(" <trustInfo xmlns='urn:schemas-microsoft-com:asm.v3'>\n")
outfile.write(" <security>\n")
outfile.write(" <requestedPrivileges>\n")
outfile.write(" <requestedExecutionLevel\n")
outfile = open(output_file_base_name + '.exe.manifest', 'w+')
outfile.write('<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n')
outfile.write('<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">\n')
outfile.write(' <assemblyIdentity version="%s"\n' % manifest_package_version)
outfile.write(' processorArchitecture="*"\n')
outfile.write(' name="%s.%s.%s.exe"\n' % (DOMAIN_NAME, package, name))
outfile.write(' type="win32" />\n')
outfile.write(' <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">\n')
outfile.write(' <security>\n')
outfile.write(' <requestedPrivileges>\n')
outfile.write(' <requestedExecutionLevel\n')
if admin:
outfile.write(" level='requireAdministrator'\n")
outfile.write(' level="requireAdministrator"\n')
else:
outfile.write(" level='asInvoker'\n")
outfile.write(' level="asInvoker"\n')
outfile.write(" uiAccess='false' />\n")
outfile.write(" </requestedPrivileges>\n")
outfile.write(" </security>\n")
outfile.write(" </trustInfo>\n")
outfile.write("</assembly>\n")
outfile.write(' uiAccess="false" />\n')
outfile.write(' </requestedPrivileges>\n')
outfile.write(' </security>\n')
outfile.write(' </trustInfo>\n')
outfile.write('</assembly>\n')
outfile.close()
def write_rc_file(name, resource, outdir):
if outdir is not None:
output_file_base_name = os.path.join(outdir, name)
@@ -114,24 +91,21 @@ def write_rc_file(name, resource, outdir):
output_file_base_name = name
if resource is None:
outfile = open(output_file_base_name + ".rc", "w+")
outfile.write("#define WIN32_LEAN_AND_MEAN\n")
outfile.write("#include <windows.h>\n")
outfile = open(output_file_base_name + '.rc', 'w+')
outfile.write('#define WIN32_LEAN_AND_MEAN\n')
outfile.write('#include <windows.h>\n')
else:
if resource != output_file_base_name + ".rc":
outfile = open(output_file_base_name + ".rc", "w+")
if resource != output_file_base_name + '.rc':
outfile = open(output_file_base_name + '.rc', 'w+')
else:
outfile = open(output_file_base_name + ".final.rc", "w+")
srcfile = open(resource, "r")
outfile = open(output_file_base_name + '.final.rc', 'w+')
srcfile = open(resource, 'r')
outfile.write(srcfile.read())
srcfile.close()
outfile.write("\n")
outfile.write(
'CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "%s.exe.manifest"' % name
)
outfile.write('\n')
outfile.write('CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "%s.exe.manifest"' % name)
outfile.close()
if __name__ == "__main__":
if __name__ == '__main__':
main()

View File

@@ -371,11 +371,11 @@ do_screenshot (int *argc,
exit (1);
}
g_set_prgname ("gtk4-builder-tool render");
g_set_prgname ("gtk4-builder-tool screenshot");
context = g_option_context_new (NULL);
g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);
g_option_context_add_main_entries (context, entries, NULL);
g_option_context_set_summary (context, _("Render a .ui file to an image."));
g_option_context_set_summary (context, _("Take a screenshot of the file."));
if (!g_option_context_parse (context, argc, (char ***)argv, &error))
{
@@ -394,7 +394,7 @@ do_screenshot (int *argc,
if (g_strv_length (filenames) > 2)
{
g_printerr (_("Can only render a single .ui file to a single output file\n"));
g_printerr (_("Can only screenshot a single .ui file and a single output file\n"));
exit (1);
}

View File

@@ -34,7 +34,7 @@ static void G_GNUC_NORETURN
usage (void)
{
g_print (_("Usage:\n"
" gtk4-builder-tool [COMMAND] [OPTION…] FILE\n"
" gtk-builder-tool [COMMAND] [OPTION…] FILE\n"
"\n"
"Perform various tasks on GtkBuilder .ui files.\n"
"\n"
@@ -43,7 +43,6 @@ usage (void)
" simplify Simplify the file\n"
" enumerate List all named objects\n"
" preview Preview the file\n"
" render Take a screenshot of the file\n"
" screenshot Take a screenshot of the file\n"
"\n"));
exit (1);
@@ -135,8 +134,7 @@ main (int argc, const char *argv[])
do_enumerate (&argc, &argv);
else if (strcmp (argv[0], "preview") == 0)
do_preview (&argc, &argv);
else if (strcmp (argv[0], "render") == 0 ||
strcmp (argv[0], "screenshot") == 0)
else if (strcmp (argv[0], "screenshot") == 0)
do_screenshot (&argc, &argv);
else
usage ();