Compare commits

..

2 Commits

Author SHA1 Message Date
Matthias Clasen
865cab3cc6 Add a test for changing content
This is meant to produce lots of widget that all share the
same CSS and size, and frequently change content.
2023-04-30 08:08:31 -04:00
Matthias Clasen
bc47cc5970 docs: Migration guide updates
Mention various widget size apis going away.
2023-04-29 16:17:51 -04:00
13 changed files with 205 additions and 20 deletions

View File

@@ -64,8 +64,6 @@
</child>
<child>
<object class="GtkLabel" id="short_time_label">
<property name="hexpand">1</property>
<property name="xalign">1</property>
<property name="valign">baseline</property>
<property name="label" translatable="yes">38m</property>
<style>

View File

@@ -875,10 +875,10 @@ reference.
### Adapt to coordinate API changes
A number of APIs that are accepting or returning coordinates have
been changed from `int`s to `double`s: `gtk_widget_translate_coordinates()`,
been changed from ints to doubles: `gtk_widget_translate_coordinates()`,
`gtk_fixed_put()`, `gtk_fixed_move()`. This change is mostly transparent,
except for cases where out parameters are involved: you need to
pass `double*` now, instead of `int*`.
pass double* now, instead of int*.
### Adapt to GtkStyleContext API changes

View File

@@ -132,4 +132,6 @@ use `gtk_widget_compute_bounds (widget, widget, &bounds)` instead.
The function gtk_widget_get_allocation() is also going away. It does not have a direct
replacement, but the previously mentioned alternatives can be used for it too.
gtk_widget_translate_coordinates90 has been replaced by [method@Gtk.Widget.compute_point].
The function gtk_widget_get_allocated_baseline() has been renamed to [method@Gtk.Widget.get_baseline].

View File

@@ -437,7 +437,7 @@ gdk_display_manager_open_display (GdkDisplayManager *manager,
}
}
if (!found && !any && !display)
if (!found && !display)
g_warning ("No such backend: %s", backend);
}

View File

@@ -223,7 +223,7 @@ gdk_vulkan_strerror (VkResult result)
#if VK_HEADER_VERSION < 140
case VK_RESULT_RANGE_SIZE:
#endif
#if VK_HEADER_VERSION >= 238
#if VK_HEADER_VERSION >= 218
case VK_ERROR_IMAGE_USAGE_NOT_SUPPORTED_KHR:
return "The requested VkImageUsageFlags are not supported. (VK_ERROR_IMAGE_USAGE_NOT_SUPPORTED_KHR)";
case VK_ERROR_VIDEO_PICTURE_LAYOUT_NOT_SUPPORTED_KHR:

View File

@@ -4145,7 +4145,6 @@ gsk_gl_render_job_visit_node_with_offscreen (GskGLRenderJob *job,
flipped_x ? -1 : 1,
flipped_y ? -1 : 1);
gsk_gl_render_job_push_modelview (job, transform);
gsk_transform_unref (transform);
}
gsk_gl_render_job_transform_bounds (job, offscreen->bounds, &viewport);
@@ -4183,7 +4182,6 @@ gsk_gl_render_job_visit_node_with_offscreen (GskGLRenderJob *job,
{
GskTransform *transform = gsk_transform_scale (NULL, downscale_x, downscale_y);
gsk_gl_render_job_push_modelview (job, transform);
gsk_transform_unref (transform);
gsk_gl_render_job_transform_bounds (job, offscreen->bounds, &viewport);
}

View File

@@ -51,7 +51,7 @@ G_GNUC_BEGIN_IGNORE_DEPRECATIONS
/**
* GtkInfoBar:
*
* `GtkInfoBar` can be used to show messages to the user without a dialog.
* `GtkInfoBar` can be show messages to the user without a dialog.
*
* ![An example GtkInfoBar](info-bar.png)
*

View File

@@ -563,11 +563,12 @@ add_emoji (GtkWidget *box,
int i;
PangoLayout *layout;
PangoRectangle rect;
gunichar code = 0;
codes = g_variant_get_child_value (item, 0);
for (i = 0; i < g_variant_n_children (codes); i++)
{
gunichar code;
g_variant_get_child (codes, i, "u", &code);
if (code == 0)
code = modifier;
@@ -575,10 +576,7 @@ add_emoji (GtkWidget *box,
p += g_unichar_to_utf8 (code, p);
}
g_variant_unref (codes);
if (code != 0xFE0F && code != 0xFE0E)
p += g_unichar_to_utf8 (0xFE0F, p); /* Append a variation selector, if there isn't one already */
p += g_unichar_to_utf8 (0xFE0F, p); /* U+FE0F is the Emoji variation selector */
p[0] = 0;
label = gtk_label_new (text);

View File

@@ -106,10 +106,9 @@
* ╰── <child>
* ```
*
* `GtkExpander` has a main node `expander-widget`, and subnode `box` containing
* the title and child widget. The box subnode `title` contains node `expander`,
* i.e. the expand/collapse arrow; then the label widget if any. The arrow of an
* expander that is showing its child gets the `:checked` pseudoclass set on it.
* `GtkExpander` has three CSS nodes, the main node with the name expander-widget,
* a subnode with name title and node below it with name expander. The arrow of an
* expander that is showing its child gets the :checked pseudoclass added to it.
*
* # Accessibility
*

View File

@@ -43,7 +43,7 @@
* space as well as it can.
*
* Users of this widget should take care to plan behaviour for the common case
* where the text doesn't fit exactly in the allocated space.
* where the text doesn't fit exactly in the allocated space, .
*
* Since: 4.8
*/

View File

@@ -935,7 +935,6 @@ _gtk_path_bar_set_file (GtkPathBar *path_bar,
info->cancellable = g_cancellable_new ();
path_bar->get_info_cancellable = info->cancellable;
add_cancellable (path_bar, info->cancellable);
if (g_file_is_native (info->file))
{
@@ -960,6 +959,7 @@ _gtk_path_bar_set_file (GtkPathBar *path_bar,
gtk_path_bar_get_mount_callback,
info);
}
add_cancellable (path_bar, info->cancellable);
}
/**

View File

@@ -1,5 +1,6 @@
gtk_tests = [
# testname, optional extra sources
['testgridchanges'],
['input'],
['testpopup'],
['testupload'],

189
tests/testgridchanges.c Normal file
View File

@@ -0,0 +1,189 @@
#include <gtk/gtk.h>
#define CONTENT_TYPE_WIDGET (content_widget_get_type ())
G_DECLARE_FINAL_TYPE (ContentWidget, content_widget, CONTENT, WIDGET, GtkWidget)
struct _ContentWidget
{
GtkWidget parent_instance;
int pos;
GskRenderNode *content[10];
int width, height;
};
struct _ContentWidgetClass
{
GtkWidgetClass parent_class;
};
G_DEFINE_TYPE (ContentWidget, content_widget, GTK_TYPE_WIDGET)
static void
content_widget_init (ContentWidget *self)
{
}
static void
content_widget_measure (GtkWidget *widget,
GtkOrientation orientation,
int for_size,
int *minimum,
int *natural,
int *minimum_content,
int *natural_content)
{
ContentWidget *self = CONTENT_WIDGET (widget);
*minimum_content = *natural_content = -1;
if (orientation == GTK_ORIENTATION_VERTICAL)
*minimum = *natural = self->height;
else
*minimum = *natural = self->width;
}
static void
content_widget_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot)
{
ContentWidget *self = CONTENT_WIDGET (widget);
gtk_snapshot_append_node (snapshot, self->content[self->pos]);
}
static void
content_widget_realize (GtkWidget *widget)
{
ContentWidget *self = CONTENT_WIDGET (widget);
PangoLayout *layout;
GTK_WIDGET_CLASS (content_widget_parent_class)->realize (widget);
layout = gtk_widget_create_pango_layout (widget, "");
self->width = self->height = 0;
for (unsigned int i = 0; i < 10; i++)
{
char text[20];
GtkSnapshot *snapshot;
graphene_rect_t bounds;
g_snprintf (text, sizeof (text), "%u", i);
pango_layout_set_text (layout, text, -1);
snapshot = gtk_snapshot_new ();
gtk_snapshot_append_layout (snapshot, layout, &(GdkRGBA){ 0., 0., 0., 1. });
self->content[i] = gtk_snapshot_free_to_node (snapshot);
gsk_render_node_get_bounds (self->content[i], &bounds);
self->width = MAX (self->width, ceilf (bounds.origin.x + bounds.size.width));
self->height = MAX (self->height, ceilf (bounds.origin.y + bounds.size.height));
}
g_object_unref (layout);
}
static void
content_widget_unrealize (GtkWidget *widget)
{
ContentWidget *self = CONTENT_WIDGET (widget);
for (unsigned int i =0; i < 10; i++)
g_clear_pointer (&self->content[i], gsk_render_node_unref);
GTK_WIDGET_CLASS (content_widget_parent_class)->unrealize (widget);
}
static void
content_widget_class_init (ContentWidgetClass *class)
{
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
widget_class->snapshot = content_widget_snapshot;
widget_class->measure = content_widget_measure;
widget_class->realize = content_widget_realize;
widget_class->unrealize = content_widget_unrealize;
gtk_widget_class_set_css_name (widget_class, "content");
}
static GtkWidget *
content_widget_new (void)
{
return g_object_new (CONTENT_TYPE_WIDGET, NULL);
}
static void
content_widget_set_pos (ContentWidget *self,
int pos)
{
g_return_if_fail (CONTENT_IS_WIDGET (self));
g_return_if_fail (0 <= pos && pos < 10);
self->pos = pos;
gtk_widget_queue_draw (GTK_WIDGET (self));
}
static GtkWidget *cells[100][100];
static gboolean
change_content (GtkWidget *widget,
GdkFrameClock *clock,
gpointer user_data)
{
for (unsigned int i = 0; i < 100; i++)
for (unsigned int j = 0; j < 100; j++)
content_widget_set_pos (CONTENT_WIDGET (cells[i][j]), g_random_int_range (0, 9));
return G_SOURCE_CONTINUE;
}
static const char css[] =
"content {\n"
" background: pink;\n"
" border: 1px solid black;\n"
"}";
int
main (int argc, char *argv[])
{
GtkWidget *window, *sw, *grid;
GtkCssProvider *provider;
gtk_init ();
provider = gtk_css_provider_new ();
gtk_css_provider_load_from_data (provider, css, -1);
gtk_style_context_add_provider_for_display (gdk_display_get_default (),
GTK_STYLE_PROVIDER (provider),
1000);
window = gtk_window_new ();
sw = gtk_scrolled_window_new ();
gtk_window_set_child (GTK_WINDOW (window), sw);
grid = gtk_grid_new ();
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), grid);
for (unsigned int i = 0; i < 100; i++)
for (unsigned int j = 0; j < 100; j++)
{
GtkWidget *child;
child = content_widget_new ();
gtk_grid_attach (GTK_GRID (grid), child, i, j, 1, 1);
cells[i][j] = child;
}
gtk_widget_add_tick_callback (window, change_content, NULL, NULL);
gtk_window_present (GTK_WINDOW (window));
while (g_list_model_get_n_items (gtk_window_get_toplevels ()) > 0)
g_main_context_iteration (NULL, FALSE);
return 0;
}