Compare commits

...

48 Commits

Author SHA1 Message Date
Matthias Clasen ed851504f0 imwayland: Pass cursor region via attributes
Use the new Pango attribute to communicate
the cursor region to the widgets.

Fixes: #5035
2022-07-13 17:08:59 -04:00
Matthias Clasen f9c2b70812 text: Use the im context highlight attribute
Extract the highlighted region from the preedit
attributes, and style it like we style the regular
selection.
2022-07-13 17:04:18 -04:00
Matthias Clasen e09d2a676c imcontext: Define a pango attribute for highlight
Define our own PangoAttribute type for IM Context
properties. Currently, the only defined property
is for marking the highlighted region.
2022-07-13 17:00:59 -04:00
Matthias Clasen 24f31b6797 Merge branch 'empty_list_adjustment' into 'main'
listviews: Reset scrollbar adjustment when list is empty

Closes #4370

See merge request GNOME/gtk!4865
2022-07-13 11:17:07 +00:00
Matthias Clasen 45f69d2fbe Merge branch 'main' into 'main'
textview: Include gutter while computing child allocations

Closes #5016

See merge request GNOME/gtk!4849
2022-07-13 11:02:02 +00:00
JCWasmx86 af5f75aa77 textview: Include gutter while computing child allocations
The width of the left gutter and the height of the top gutter
are now used while computing the child allocations for e.g.
anchors, otherwise - if such a gutter is present - the
widget would be at the wrong position.

Closes #5016
2022-07-13 07:02:55 +02:00
Matthias Clasen 74494b0b3a 4.7.1 2022-07-12 22:55:33 -04:00
Corey Berla 94673707e6 listviews: Reset scrollbar adjustment when list is empty
In a list with a visible scrollbar, the scrollbar usually becomes
invisible when the numbers of items is less than the required amount
to scroll.  If, however, the list is emptied all at once,
the scrollbar remains.  This happens because when there's an empty
list gtk_list_view_size_allocate() returns early before the scrollbar
adjustment is updated.

Given that the list is empty, simply reset the adjustment values
to zero.

Fixes: https://gitlab.gnome.org/GNOME/gtk/-/issues/4370
2022-07-12 12:54:35 -07:00
Matthias Clasen afe476c2e3 Merge branch 'matthiasc/for-main' into 'main'
search-entry: Add getter/setter annotation

See merge request GNOME/gtk!4862
2022-07-11 19:32:55 +00:00
Matthias Clasen dfe8eb37ce search-entry: Add getter/setter annotation
This was suggested in !4823.
2022-07-11 15:08:39 -04:00
Matthias Clasen 88e8837587 Merge branch 'wip/otte/for-main' into 'main'
frameclock: Run paint idle from flush idle

Closes #4941

See merge request GNOME/gtk!4858
2022-07-11 18:44:01 +00:00
Matthias Clasen f218a4e2d2 Merge branch 'free-print-backends' into 'main'
print: Free print backends after use

Closes #5019

See merge request GNOME/gtk!4860
2022-07-11 18:04:46 +00:00
Matthias Clasen 685961a8c6 Merge branch 'ebassi/finish-template' into 'main'
Add gtk_widget_clear_template()

See merge request GNOME/gtk!4735
2022-07-11 18:02:28 +00:00
Matthias Clasen dced70a8d0 Merge branch 'fix_flatpak' into 'main'
Fix flatpak

See merge request GNOME/gtk!4861
2022-07-11 17:35:45 +00:00
Emmanuele Bassi f4f683a469 Rename clear_template to dispose_template
Make it more clear that the function is supposed to be called during the
dispose sequence of a widget.
2022-07-11 18:24:37 +01:00
Emmanuele Bassi 63fe3345a7 fontchooserdialog: Use gtk_widget_clear_template() 2022-07-11 18:24:37 +01:00
Emmanuele Bassi 01e99fad1e statusbar: Use gtk_widget_clear_template() 2022-07-11 18:24:37 +01:00
Emmanuele Bassi 0074ee3149 filechooserwidget: Use gtk_widget_clear_template() 2022-07-11 18:24:37 +01:00
Emmanuele Bassi ad361abc4c filechooserdialog: Use gtk_widget_clear_template() 2022-07-11 18:24:37 +01:00
Emmanuele Bassi 103f52bb8a Port the inspector to gtk_widget_clear_template()
Use clear_template() instead of unparenting widgets manually.
2022-07-11 18:24:37 +01:00
Emmanuele Bassi c2ec244b84 docs: Include clear_template() in the templates overview
Make sure that it's clear how to use it in idiomatic code, by tying it
to gtk_widget_init_template().
2022-07-11 18:24:37 +01:00
Emmanuele Bassi e71f9bb79f Port gtk-demo widgets to gtk_widget_clear_template() 2022-07-11 18:24:37 +01:00
Emmanuele Bassi bf75a21deb Port node editor to gtk_widget_clear_template() 2022-07-11 18:24:37 +01:00
Emmanuele Bassi 1bba874895 Port icon browser to gtk_widget_clear_template() 2022-07-11 18:24:37 +01:00
Emmanuele Bassi 01f5142b00 Port constraint editor to gtk_widget_clear_template() 2022-07-11 18:24:37 +01:00
Emmanuele Bassi 620d48ca0c docs: Clarify scope of gtk_widget_clear_template()
The clear_template() method only clears the template children.
2022-07-11 18:24:37 +01:00
Emmanuele Bassi e8c5c2f648 emojichooser: Use gtk_widget_clear_template() 2022-07-11 18:24:37 +01:00
Emmanuele Bassi 71eb19bf51 mediacontrols: Use gtk_widget_clear_template() 2022-07-11 18:24:37 +01:00
Emmanuele Bassi 7857c1a66b Add gtk_widget_clear_template()
The dual of gtk_widget_init_template(), which should be used to clear
the template data associated with a specific GtkWidget type.
2022-07-11 18:24:37 +01:00
Corey Berla 1e3ae95b7e flatpak: Bump boost to 1.79 2022-07-11 09:11:59 -07:00
Corey Berla 1ff38cdf6a flatpak: Remove benchmarks build option for graphene
benchmarks was removed in
https://github.com/ebassi/graphene/commit/419edb99f0a314f51157b04d645cd24a959598d2
2022-07-11 09:11:24 -07:00
Corey Berla 4147dd218d flatpak: Change option enable_vulkan=no to vulkan=disabled
Syntax was modified in c4d350c260
2022-07-11 09:08:47 -07:00
Marek Kasik e68a3a6123 print: Free print backends after use
Print backends loaded in GtkPrintUnixDialog's load_print_backends()
are not freed later as done in e.g. GtkPageSetupUnixDialog.
This commit destroys and unref those print backends.

Closes #5019
2022-07-11 16:54:36 +02:00
Matthias Clasen 6368278005 NEWS: Updates 2022-07-10 18:52:01 -04:00
Matthias Clasen edb61cc434 Merge branch 'matthiasc/for-main' into 'main'
inspector: Hide measure graphs by default

See merge request GNOME/gtk!4859
2022-07-10 20:38:29 +00:00
Matthias Clasen 743406998c inspector: Hide measure graphs by default
It is much more valuable to have a responsive inspector,
than to have these graphs.
2022-07-10 16:25:55 -04:00
Matthias Clasen f56c0bc034 Merge branch 'fix-fractional-letterspacing' into 'main'
css: Allow fractional letterspacing

Closes #5034

See merge request GNOME/gtk!4857
2022-07-10 19:42:25 +00:00
Benjamin Otte 988e20cd53 frameclock: Run paint idle from flush idle
Don't return to the main loop, instead force a run of the paint idle.
The paint idle will know to skip all the phases that aren't requested.

This is critically important becuase gdksurface.c assumes the
FLUSH_EVENTS and RESUME_EVENTS phases are matched, and we cannot
guarantee that if we return to the main loop and let various reentrant
code change the frame clock state.

This would lead to bugs with events being paused and never unpaused
again or even crashes.

Fixes #4941
2022-07-10 21:33:32 +02:00
Matthias Clasen 726c9e83d2 css: Allow fractional letterspacing
Something like letter-spacing: -0.5px make a lot of
sense. But we were handling the number as integer
somewhere, loosing the fractional part.

Fixes: #5034
2022-07-10 15:22:18 -04:00
Matthias Clasen e7af42c758 Merge branch 'matthiasc/for-main' into 'main'
widget-factory: Fix a missing export

See merge request GNOME/gtk!4855
2022-07-08 02:00:11 +00:00
Matthias Clasen 7c5d71ebf6 widget-factory: Fix a missing export
This broke when we started using a scope.
2022-07-07 21:44:57 -04:00
Matthias Clasen d659bc8762 Merge branch 'wip/cdavis/use-password-input-purpose' into 'main'
passwordentry: Use password input purpose

See merge request GNOME/gtk!4854
2022-07-06 19:48:57 +00:00
Christopher Davis 9f2a621328 passwordentry: Use password input purpose
Per discussion in #gtk on Matrix
2022-07-06 13:48:25 -04:00
Matthias Clasen fae2dd9885 Merge branch 'matthiasc/for-main' into 'main'
fontchooser work

See merge request GNOME/gtk!4850
2022-07-05 15:13:20 +00:00
Benjamin Otte c673d7cd9b Merge branch 'fix-ffmpeg-decoding' into 'main'
ffmpeg: Fix crash on some media files

See merge request GNOME/gtk!4851
2022-07-04 21:27:11 +00:00
Stephan Vedder 1c8bddf3ca ffmpeg: Fix crash on some media files
Return code EAGAIN expects the user to feed more packets into the decoder
2022-07-04 13:29:09 +02:00
Matthias Clasen ab1cf67432 fontchooser: Make size level effective
We were not hiding the size controls on the tweaks
page, which is arguably what should happen when
the size level is disabled.
2022-07-03 12:50:40 -04:00
Matthias Clasen 1097003f6f Beef up testfontchooserdialog
Allow testing levels.
2022-07-03 12:50:30 -04:00
50 changed files with 608 additions and 137 deletions
+81
View File
@@ -1,3 +1,84 @@
Overview of Changes in 4.7.1, 12-07-2022
========================================
* GtkInscription:
- A new label-like widget for use in list views
* GtkColorChooser:
- Style improvements
* GtkFontChooser:
- Improve support for OpenType features a bit
* GtkLabel:
- Allow selectable labels to be activated via mnemonic
* GtkTextView:
- Implement GetCharacterExtents for accessibility
* GtkStack:
- Fix a poblem with stack page accessibility
* GtkListView:
- Cull listitems that are out of view
- Make all our list models implement ::n-items and
::item-type properties
* Translations:
- Stop translating property nicks and blurbs
- Fix extracting translations from ui files
* Debugging:
- Support GTK_DEBUG=invert-text-dir
- Allow inspecting inspectors
- Replace GTK_USE_PORTAL with GDK_DEBUG=portals
- Improve responsiveness of the inspector
* CSS:
- Allow fractional letterspacing
* Theme:
- Improve legibility of selectable labels
* Demos:
- Improve the font features demo
- Add demos for GtkInscription
* Wayland:
- Freeze popups when hidden
- Only send smooth scroll events for tablet tools
- Make scaled cursor image have the right size
- Fix problems with the activation protocol
- Don't force the HighContrast icon theme
- Support xdg_toplevel.bounds
* X11:
- Always update the shadoe size
* Windows:
- Improve touchpad support by using DirectManipulation
- Add more directories to the builtin hicolor icon theme
* Translation updates:
Basque
Catalan
Chinese (China)
Galician
German
Lithuanian
Nepali
Occitan
Persian
Polish
Portuguese
Russian
Serbian
Spanish
Swedish
Turkish
Ukrainian
Overview of Changes in 4.7.0, 07-05-2022
========================================
+4 -5
View File
@@ -54,8 +54,7 @@
"builddir" : true,
"config-opts" : [
"--libdir=/app/lib",
"-Dtests=false",
"-Dbenchmarks=false"
"-Dtests=false"
],
"sources" : [
{
@@ -105,8 +104,8 @@
"sources": [
{
"type": "archive",
"url": "https://boostorg.jfrog.io/artifactory/main/release/1.69.0/source/boost_1_69_0.tar.bz2",
"sha256": "8f32d4617390d1c2d16f26a27ab60d97807b35440d45891fa340fc2648b04406"
"url": "https://boostorg.jfrog.io/artifactory/main/release/1.79.0/source/boost_1_79_0.tar.bz2",
"sha256": "475d589d51a7f8b3ba2ba4eda022b170e562ca3b760ee922c146b6c65856ef39"
}
]
},
@@ -186,7 +185,7 @@
"builddir" : true,
"config-opts" : [
"--libdir=/app/lib",
"-Denable_vulkan=no",
"-Dvulkan=disabled",
"-Dbuildtype=debugoptimized",
"-Dprofile=devel"
],
+2 -3
View File
@@ -54,8 +54,7 @@
"builddir" : true,
"config-opts" : [
"--libdir=/app/lib",
"-Dtests=false",
"-Dbenchmarks=false"
"-Dtests=false"
],
"sources" : [
{
@@ -115,7 +114,7 @@
"builddir" : true,
"config-opts" : [
"--libdir=/app/lib",
"-Denable_vulkan=no",
"-Dvulkan=disabled",
"-Dbuildtype=debugoptimized",
"-Dprofile=devel"
],
@@ -54,8 +54,7 @@
"builddir" : true,
"config-opts" : [
"--libdir=/app/lib",
"-Dtests=false",
"-Dbenchmarks=false"
"-Dtests=false"
],
"sources" : [
{
@@ -115,7 +114,7 @@
"builddir" : true,
"config-opts" : [
"--libdir=/app/lib",
"-Denable_vulkan=no",
"-Dvulkan=disabled",
"-Dbuildtype=debugoptimized",
"-Dprofile=devel"
],
@@ -361,11 +361,11 @@ save_cb (GtkWidget *button,
}
static void
constraint_editor_window_finalize (GObject *object)
constraint_editor_window_dispose (GObject *object)
{
//ConstraintEditorWindow *self = (ConstraintEditorWindow *)object;
gtk_widget_dispose_template (GTK_WIDGET (object), CONSTRAINT_EDITOR_WINDOW_TYPE);
G_OBJECT_CLASS (constraint_editor_window_parent_class)->finalize (object);
G_OBJECT_CLASS (constraint_editor_window_parent_class)->dispose (object);
}
static int child_counter;
@@ -497,7 +497,7 @@ constraint_editor_window_class_init (ConstraintEditorWindowClass *class)
GObjectClass *object_class = G_OBJECT_CLASS (class);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
object_class->finalize = constraint_editor_window_finalize;
object_class->dispose = constraint_editor_window_dispose;
gtk_widget_class_set_template_from_resource (widget_class,
"/org/gtk/gtk4/constraint-editor/constraint-editor-window.ui");
+2 -1
View File
@@ -607,10 +607,11 @@ constraint_editor_dispose (GObject *object)
{
ConstraintEditor *self = (ConstraintEditor *)object;
g_clear_pointer (&self->grid, gtk_widget_unparent);
g_clear_object (&self->model);
g_clear_object (&self->constraint);
gtk_widget_dispose_template (GTK_WIDGET (object), CONSTRAINT_EDITOR_TYPE);
G_OBJECT_CLASS (constraint_editor_parent_class)->dispose (object);
}
+2 -1
View File
@@ -294,9 +294,10 @@ guide_editor_dispose (GObject *object)
{
GuideEditor *self = (GuideEditor *)object;
g_clear_pointer (&self->grid, gtk_widget_unparent);
g_clear_object (&self->guide);
gtk_widget_dispose_template (GTK_WIDGET (self), GUIDE_EDITOR_TYPE);
G_OBJECT_CLASS (guide_editor_parent_class)->dispose (object);
}
+2
View File
@@ -504,6 +504,8 @@ demo_application_window_dispose (GObject *object)
demo_application_window_store_state (window);
gtk_widget_dispose_template (GTK_WIDGET (window), demo_application_window_get_type ());
G_OBJECT_CLASS (demo_application_window_parent_class)->dispose (object);
}
+2 -1
View File
@@ -37,7 +37,8 @@ demo3_widget_dispose (GObject *object)
Demo3Widget *self = DEMO3_WIDGET (object);
g_clear_object (&self->paintable);
g_clear_pointer (&self->menu, gtk_widget_unparent);
gtk_widget_dispose_template (GTK_WIDGET (self), DEMO3_TYPE_WIDGET);
G_OBJECT_CLASS (demo3_widget_parent_class)->dispose (object);
}
+9 -1
View File
@@ -260,12 +260,19 @@ gtk_message_row_state_flags_changed (GtkWidget *widget,
GTK_WIDGET_CLASS (gtk_message_row_parent_class)->state_flags_changed (widget, previous_state_flags);
}
static void
gtk_message_row_dispose (GObject *obj)
{
gtk_widget_dispose_template (GTK_WIDGET (obj), GTK_TYPE_MESSAGE_ROW);
G_OBJECT_CLASS (gtk_message_row_parent_class)->dispose (obj);
}
static void
gtk_message_row_finalize (GObject *obj)
{
GtkMessageRowPrivate *priv = GTK_MESSAGE_ROW (obj)->priv;
g_object_unref (priv->message);
G_OBJECT_CLASS (gtk_message_row_parent_class)->finalize(obj);
G_OBJECT_CLASS (gtk_message_row_parent_class)->finalize (obj);
}
static void
@@ -274,6 +281,7 @@ gtk_message_row_class_init (GtkMessageRowClass *klass)
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->dispose = gtk_message_row_dispose;
object_class->finalize = gtk_message_row_finalize;
gtk_widget_class_set_template_from_resource (widget_class, "/listbox/listbox.ui");
+9
View File
@@ -409,6 +409,14 @@ icon_browser_window_init (IconBrowserWindow *win)
g_signal_connect (win->context_model, "notify::selected", G_CALLBACK (selected_name_changed), win);
}
static void
icon_browser_window_dispose (GObject *object)
{
gtk_widget_dispose_template (GTK_WIDGET (object), ICON_BROWSER_WINDOW_TYPE);
G_OBJECT_CLASS (icon_browser_window_parent_class)->dispose (object);
}
static void
icon_browser_window_finalize (GObject *object)
{
@@ -424,6 +432,7 @@ icon_browser_window_class_init (IconBrowserWindowClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
object_class->dispose = icon_browser_window_dispose;
object_class->finalize = icon_browser_window_finalize;
g_type_ensure (IB_TYPE_ICON);
+9
View File
@@ -873,6 +873,14 @@ dark_mode_cb (GtkToggleButton *button,
NULL);
}
static void
node_editor_window_dispose (GObject *object)
{
gtk_widget_dispose_template (GTK_WIDGET (object), NODE_EDITOR_WINDOW_TYPE);
G_OBJECT_CLASS (node_editor_window_parent_class)->dispose (object);
}
static void
node_editor_window_finalize (GObject *object)
{
@@ -967,6 +975,7 @@ node_editor_window_class_init (NodeEditorWindowClass *class)
GObjectClass *object_class = G_OBJECT_CLASS (class);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
object_class->dispose = node_editor_window_dispose;
object_class->finalize = node_editor_window_finalize;
gtk_widget_class_set_template_from_resource (widget_class,
+1
View File
@@ -2098,6 +2098,7 @@ activate (GApplication *app)
gtk_builder_cscope_add_callback (scope, mode_switch_state_set);
gtk_builder_cscope_add_callback (scope, level_scale_value_changed);
gtk_builder_cscope_add_callback (scope, transition_speed_changed);
gtk_builder_cscope_add_callback (scope, reset_icon_size);
gtk_builder_set_scope (builder, scope);
g_object_unref (scope);
if (!gtk_builder_add_from_resource (builder, "/org/gtk/WidgetFactory4/widget-factory.ui", &error))
+3
View File
@@ -373,6 +373,9 @@ gdk_frame_clock_flush_idle (void *data)
else
priv->phase = GDK_FRAME_CLOCK_PHASE_NONE;
g_clear_handle_id (&priv->paint_idle_id, g_source_remove);
gdk_frame_clock_paint_idle (data);
return FALSE;
}
+1 -1
View File
@@ -596,7 +596,7 @@ gtk_css_style_get_pango_attributes (GtkCssStyle *style)
GtkTextDecorationStyle decoration_style;
const GdkRGBA *color;
const GdkRGBA *decoration_color;
int letter_spacing;
double letter_spacing;
/* text-decoration */
decoration_line = _gtk_css_text_decoration_line_value_get (style->font_variant->text_decoration_line);
+11 -2
View File
@@ -249,6 +249,14 @@ gtk_emoji_chooser_finalize (GObject *object)
G_OBJECT_CLASS (gtk_emoji_chooser_parent_class)->finalize (object);
}
static void
gtk_emoji_chooser_dispose (GObject *object)
{
gtk_widget_dispose_template (GTK_WIDGET (object), GTK_TYPE_EMOJI_CHOOSER);
G_OBJECT_CLASS (gtk_emoji_chooser_parent_class)->dispose (object);
}
static void
scroll_to_section (EmojiSection *section)
{
@@ -866,7 +874,7 @@ filter_func (GtkFlowBoxChild *child,
goto out;
term_tokens = g_str_tokenize_and_fold (text, "en", NULL);
g_variant_get_child (emoji_data, 1, "&s", &name);
name_tokens = g_str_tokenize_and_fold (name, "en", NULL);
g_variant_get_child (emoji_data, 2, "^a&s", &keywords);
@@ -1203,6 +1211,7 @@ gtk_emoji_chooser_class_init (GtkEmojiChooserClass *klass)
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
object_class->finalize = gtk_emoji_chooser_finalize;
object_class->dispose = gtk_emoji_chooser_dispose;
widget_class->show = gtk_emoji_chooser_show;
widget_class->map = gtk_emoji_chooser_map;
@@ -1278,7 +1287,7 @@ gtk_emoji_chooser_class_init (GtkEmojiChooserClass *klass)
* @direction: 1 to scroll forward, -1 to scroll back
*
* Scrolls to the next or previous section.
*/
*/
gtk_widget_class_install_action (widget_class, "scroll.section", "i",
gtk_emoji_chooser_scroll_section);
+1 -3
View File
@@ -380,9 +380,7 @@ gtk_file_chooser_dialog_activate_response (GtkWidget *widget,
static void
gtk_file_chooser_dialog_dispose (GObject *object)
{
GtkFileChooserDialogPrivate *priv = gtk_file_chooser_dialog_get_instance_private (GTK_FILE_CHOOSER_DIALOG (object));
g_clear_pointer ((GtkWidget **)&priv->widget, gtk_widget_unparent);
gtk_widget_dispose_template (GTK_WIDGET (object), GTK_TYPE_FILE_CHOOSER_DIALOG);
G_OBJECT_CLASS (gtk_file_chooser_dialog_parent_class)->dispose (object);
}
+9 -7
View File
@@ -515,7 +515,7 @@ static GSList *get_selected_infos (GtkFileChooserWidget *impl);
static void search_setup_widgets (GtkFileChooserWidget *impl);
static void search_stop_searching (GtkFileChooserWidget *impl,
gboolean remove_query);
static void search_clear_model (GtkFileChooserWidget *impl,
static void search_clear_model (GtkFileChooserWidget *impl,
gboolean remove_from_treeview);
static void search_entry_activate_cb (GtkFileChooserWidget *impl);
static void search_entry_stop_cb (GtkFileChooserWidget *impl);
@@ -720,8 +720,8 @@ error_creating_folder_dialog (GtkFileChooserWidget *impl,
GFile *file,
GError *error)
{
error_dialog (impl,
_("The folder could not be created"),
error_dialog (impl,
_("The folder could not be created"),
error);
}
@@ -3122,10 +3122,11 @@ gtk_file_chooser_widget_dispose (GObject *object)
GtkFileChooserWidget *impl = (GtkFileChooserWidget *) object;
cancel_all_operations (impl);
g_clear_pointer (&impl->rename_file_popover, gtk_widget_unparent);
/* browse_files_popover is not a template child */
g_clear_pointer (&impl->browse_files_popover, gtk_widget_unparent);
g_clear_object (&impl->extra_widget);
g_clear_pointer (&impl->bookmarks_manager, _gtk_bookmarks_manager_free);
g_clear_object (&impl->extra_widget);
if (impl->external_entry && impl->location_entry == impl->external_entry)
{
@@ -3133,9 +3134,10 @@ gtk_file_chooser_widget_dispose (GObject *object)
location_entry_disconnect (impl);
impl->external_entry = NULL;
}
remove_settings_signal (impl);
g_clear_pointer (&impl->box, gtk_widget_unparent);
gtk_widget_dispose_template (GTK_WIDGET (impl), GTK_TYPE_FILE_CHOOSER_WIDGET);
G_OBJECT_CLASS (gtk_file_chooser_widget_parent_class)->dispose (object);
}
@@ -6258,7 +6260,7 @@ gtk_file_chooser_widget_should_respond (GtkFileChooserWidget *impl)
case SAVE_ENTRY:
goto save_entry;
case NOT_REACHED:
case NOT_REACHED:
default:
g_assert_not_reached ();
}
+3 -3
View File
@@ -229,10 +229,10 @@ gtk_font_chooser_dialog_dispose (GObject *object)
dialog);
}
g_clear_pointer (&dialog->select_button, gtk_widget_unparent);
g_clear_pointer (&dialog->cancel_button, gtk_widget_unparent);
/* tweak_button is not a template child */
g_clear_pointer (&dialog->tweak_button, gtk_widget_unparent);
g_clear_pointer (&dialog->fontchooser, gtk_widget_unparent);
gtk_widget_dispose_template (GTK_WIDGET (dialog), GTK_TYPE_FONT_CHOOSER_DIALOG);
G_OBJECT_CLASS (gtk_font_chooser_dialog_parent_class)->dispose (object);
}
+10
View File
@@ -116,6 +116,8 @@ struct _GtkFontChooserWidget
GtkWidget *size_label;
GtkWidget *size_spin;
GtkWidget *size_slider;
GtkWidget *size_label2;
GtkWidget *size_spin2;
GtkWidget *size_slider2;
GtkWidget *axis_grid;
@@ -913,6 +915,8 @@ gtk_font_chooser_widget_class_init (GtkFontChooserWidgetClass *klass)
gtk_widget_class_bind_template_child (widget_class, GtkFontChooserWidget, size_label);
gtk_widget_class_bind_template_child (widget_class, GtkFontChooserWidget, size_spin);
gtk_widget_class_bind_template_child (widget_class, GtkFontChooserWidget, size_slider);
gtk_widget_class_bind_template_child (widget_class, GtkFontChooserWidget, size_label2);
gtk_widget_class_bind_template_child (widget_class, GtkFontChooserWidget, size_spin2);
gtk_widget_class_bind_template_child (widget_class, GtkFontChooserWidget, size_slider2);
gtk_widget_class_bind_template_child (widget_class, GtkFontChooserWidget, stack);
gtk_widget_class_bind_template_child (widget_class, GtkFontChooserWidget, grid);
@@ -2637,12 +2641,18 @@ gtk_font_chooser_widget_set_level (GtkFontChooserWidget *fontchooser,
gtk_widget_show (fontchooser->size_label);
gtk_widget_show (fontchooser->size_slider);
gtk_widget_show (fontchooser->size_spin);
gtk_widget_show (fontchooser->size_label2);
gtk_widget_show (fontchooser->size_slider2);
gtk_widget_show (fontchooser->size_spin2);
}
else
{
gtk_widget_hide (fontchooser->size_label);
gtk_widget_hide (fontchooser->size_slider);
gtk_widget_hide (fontchooser->size_spin);
gtk_widget_hide (fontchooser->size_label2);
gtk_widget_hide (fontchooser->size_slider2);
gtk_widget_hide (fontchooser->size_spin2);
}
update_fontlist (fontchooser);
+4 -1
View File
@@ -758,7 +758,10 @@ gtk_grid_view_size_allocate (GtkWidget *widget,
/* step 0: exit early if list is empty */
if (gtk_list_item_manager_get_root (self->item_manager) == NULL)
return;
{
gtk_list_base_update_adjustments (GTK_LIST_BASE (self), 0, 0, 0, 0, &x, &y);
return;
}
/* step 1: determine width of the list */
gtk_grid_view_measure_column_size (self, &col_min, &col_nat);
+47
View File
@@ -1005,3 +1005,50 @@ gtk_im_context_set_property (GObject *obj,
break;
}
}
static PangoAttribute *
attr_preedit_properties_copy (const PangoAttribute *attr)
{
const PangoAttrInt *int_attr = (PangoAttrInt *)attr;
return gtk_im_context_preedit_attr_new (int_attr->value);
}
static void
attr_preedit_properties_destroy (PangoAttribute *attr)
{
PangoAttrInt *iattr = (PangoAttrInt *)attr;
g_slice_free (PangoAttrInt, iattr);
}
static gboolean
attr_preedit_properties_equal (const PangoAttribute *attr1,
const PangoAttribute *attr2)
{
const PangoAttrInt *int_attr1 = (const PangoAttrInt *)attr1;
const PangoAttrInt *int_attr2 = (const PangoAttrInt *)attr2;
return (int_attr1->value == int_attr2->value);
}
PangoAttribute *
gtk_im_context_preedit_attr_new (GtkIMContextPreeditProperties value)
{
PangoAttrInt *result = g_slice_new (PangoAttrInt);
static PangoAttrClass klass = {
0,
attr_preedit_properties_copy,
attr_preedit_properties_destroy,
attr_preedit_properties_equal
};
if (!klass.type)
klass.type = pango_attr_type_register ("GtkIMContextPreeditProperties");
pango_attribute_init (&result->attr, &klass);
result->value = value;
return (PangoAttribute *)result;
}
+10
View File
@@ -168,6 +168,16 @@ gboolean gtk_im_context_delete_surrounding (GtkIMContext *context,
int offset,
int n_chars);
typedef enum
{
GTK_IM_CONTEXT_PREEDIT_CURSOR,
} GtkIMContextPreeditProperties;
GDK_AVAILABLE_IN_4_8
PangoAttribute * gtk_im_context_preedit_attr_new (GtkIMContextPreeditProperties value);
G_END_DECLS
#endif /* __GTK_IM_CONTEXT_H__ */
+4 -5
View File
@@ -656,11 +656,10 @@ gtk_im_context_wayland_get_preedit_string (GtkIMContext *context,
if (context_wayland->current_preedit.cursor_begin
!= context_wayland->current_preedit.cursor_end)
{
/* FIXME: Oh noes, how to highlight while taking into account user preferences? */
PangoAttribute *cursor = pango_attr_weight_new (PANGO_WEIGHT_BOLD);
cursor->start_index = context_wayland->current_preedit.cursor_begin;
cursor->end_index = context_wayland->current_preedit.cursor_end;
pango_attr_list_insert (*attrs, cursor);
attr = gtk_im_context_preedit_attr_new (GTK_IM_CONTEXT_PREEDIT_CURSOR);
attr->start_index = context_wayland->current_preedit.cursor_begin;
attr->end_index = context_wayland->current_preedit.cursor_end;
pango_attr_list_insert (*attrs, attr);
}
}
}
+4 -1
View File
@@ -596,7 +596,10 @@ gtk_list_view_size_allocate (GtkWidget *widget,
/* step 0: exit early if list is empty */
if (gtk_list_item_manager_get_root (self->item_manager) == NULL)
return;
{
gtk_list_base_update_adjustments (GTK_LIST_BASE (self), 0, 0, 0, 0, &x, &y);
return;
}
/* step 1: determine width of the list */
gtk_widget_measure (widget, opposite_orientation,
+2 -2
View File
@@ -138,7 +138,7 @@ time_adjustment_changed (GtkAdjustment *adjustment,
if (gtk_adjustment_get_value (adjustment) == (double) gtk_media_stream_get_timestamp (controls->stream) / G_USEC_PER_SEC)
return;
gtk_media_stream_seek (controls->stream,
gtk_media_stream_seek (controls->stream,
gtk_adjustment_get_value (adjustment) * G_USEC_PER_SEC + 0.5);
}
@@ -208,7 +208,7 @@ gtk_media_controls_dispose (GObject *object)
gtk_media_controls_set_media_stream (controls, NULL);
g_clear_pointer (&controls->box, gtk_widget_unparent);
gtk_widget_dispose_template (GTK_WIDGET (object), GTK_TYPE_MEDIA_CONTROLS);
G_OBJECT_CLASS (gtk_media_controls_parent_class)->dispose (object);
}
+1
View File
@@ -207,6 +207,7 @@ gtk_password_entry_init (GtkPasswordEntry *entry)
entry->entry = gtk_text_new ();
gtk_text_set_buffer (GTK_TEXT (entry->entry), buffer);
gtk_text_set_visibility (GTK_TEXT (entry->entry), FALSE);
gtk_text_set_input_purpose (GTK_TEXT (entry->entry), GTK_INPUT_PURPOSE_PASSWORD);
gtk_widget_set_parent (entry->entry, GTK_WIDGET (entry));
gtk_editable_init_delegate (GTK_EDITABLE (entry));
g_signal_connect_swapped (entry->entry, "notify::has-focus", G_CALLBACK (focus_changed), entry);
+4 -1
View File
@@ -942,6 +942,7 @@ static void
gtk_print_unix_dialog_finalize (GObject *object)
{
GtkPrintUnixDialog *dialog = GTK_PRINT_UNIX_DIALOG (object);
GList *iter;
unschedule_idle_mark_conflicts (dialog);
disconnect_printer_details_request (dialog, FALSE);
@@ -967,7 +968,9 @@ gtk_print_unix_dialog_finalize (GObject *object)
g_clear_pointer (&dialog->waiting_for_printer, (GDestroyNotify)g_free);
g_clear_pointer (&dialog->format_for_printer, (GDestroyNotify)g_free);
g_list_free (dialog->print_backends);
for (iter = dialog->print_backends; iter != NULL; iter = iter->next)
gtk_print_backend_destroy (GTK_PRINT_BACKEND (iter->data));
g_list_free_full (dialog->print_backends, g_object_unref);
dialog->print_backends = NULL;
g_clear_object (&dialog->page_setup_list);
+2 -2
View File
@@ -794,7 +794,7 @@ gtk_search_entry_get_key_capture_widget (GtkSearchEntry *entry)
}
/**
* gtk_search_entry_set_search_delay:
* gtk_search_entry_set_search_delay: (attributes org.gtk.Property.set_property=search-delay)
* @entry: a `GtkSearchEntry`
* @delay: a delay in milliseconds
*
@@ -821,7 +821,7 @@ gtk_search_entry_set_search_delay (GtkSearchEntry *entry,
}
/**
* gtk_search_entry_get_search_delay
* gtk_search_entry_get_search_delay: (attributes org.gtk.Property.get_property=search-delay)
* @entry: a `GtkSearchEntry`
*
* Get the delay to be used between the last keypress and the
+6 -6
View File
@@ -143,7 +143,7 @@ gtk_statusbar_dispose (GObject *object)
g_slist_free_full (self->keys, g_free);
self->keys = NULL;
g_clear_pointer (&self->message_area, gtk_widget_unparent);
gtk_widget_dispose_template (GTK_WIDGET (self), GTK_TYPE_STATUSBAR);
G_OBJECT_CLASS (gtk_statusbar_parent_class)->dispose (object);
}
@@ -225,7 +225,7 @@ gtk_statusbar_init (GtkStatusbar *statusbar)
*
* Returns: the new `GtkStatusbar`
*/
GtkWidget*
GtkWidget*
gtk_statusbar_new (void)
{
return g_object_new (GTK_TYPE_STATUSBAR, NULL);
@@ -263,7 +263,7 @@ gtk_statusbar_get_context_id (GtkStatusbar *statusbar,
{
char *string;
guint id;
g_return_val_if_fail (GTK_IS_STATUSBAR (statusbar), 0);
g_return_val_if_fail (context_description != NULL, 0);
@@ -417,18 +417,18 @@ gtk_statusbar_remove (GtkStatusbar *statusbar,
gtk_statusbar_pop (statusbar, context_id);
return;
}
for (list = statusbar->messages; list; list = list->next)
{
msg = list->data;
if (msg->context_id == context_id &&
msg->message_id == message_id)
{
statusbar->messages = g_slist_remove_link (statusbar->messages, list);
gtk_statusbar_msg_free (msg);
g_slist_free_1 (list);
break;
}
}
+87 -25
View File
@@ -217,6 +217,8 @@ struct _GtkTextPrivate
guint16 preedit_length; /* length of preedit string, in bytes */
guint16 preedit_cursor; /* offset of cursor within preedit string, in chars */
guint16 preedit_highlight_start;
guint16 preedit_highlight_end;
gint64 handle_place_time;
@@ -4234,6 +4236,32 @@ gtk_text_commit_cb (GtkIMContext *context,
}
}
static void
get_preedit_highlight (PangoAttrList *attrs,
guint16 *start,
guint16 *end)
{
GSList *l, *list = pango_attr_list_get_attributes (attrs);
*start = *end = 0;
for (l = list; l; l = l->next)
{
PangoAttribute *attr = l->data;
if (pango_attr_type_get_name (attr->klass->type) == g_intern_static_string ("GtkIMContextPreeditProperties"))
{
*start = attr->start_index;
*end = attr->end_index;
break;
}
}
g_slist_free_full (list, (GDestroyNotify) pango_attribute_destroy);
}
static void update_selection_node (GtkText *self);
static void
gtk_text_preedit_changed_cb (GtkIMContext *context,
GtkText *self)
@@ -4243,18 +4271,26 @@ gtk_text_preedit_changed_cb (GtkIMContext *context,
if (priv->editable)
{
char *preedit_string;
PangoAttrList *preedit_attrs;
int cursor_pos;
gtk_text_obscure_mouse_cursor (self);
gtk_im_context_get_preedit_string (priv->im_context,
&preedit_string, NULL,
&preedit_string,
&preedit_attrs,
&cursor_pos);
g_signal_emit (self, signals[PREEDIT_CHANGED], 0, preedit_string);
priv->preedit_length = strlen (preedit_string);
cursor_pos = CLAMP (cursor_pos, 0, g_utf8_strlen (preedit_string, -1));
priv->preedit_cursor = cursor_pos;
if (priv->preedit_length > 0)
get_preedit_highlight (preedit_attrs, &priv->preedit_highlight_start, &priv->preedit_highlight_end);
update_selection_node (self);
g_free (preedit_string);
pango_attr_list_unref (preedit_attrs);
gtk_text_recompute (self);
update_placeholder_visibility (self);
@@ -4329,6 +4365,35 @@ gtk_text_enter_text (GtkText *self,
priv->need_im_reset = old_need_im_reset;
}
static void
update_selection_node (GtkText *self)
{
GtkTextPrivate *priv = gtk_text_get_instance_private (self);
if ((priv->current_pos != priv->selection_bound) ||
(priv->preedit_length > 0 && priv->preedit_highlight_start != priv->preedit_highlight_end))
{
if (!priv->selection_node)
{
GtkCssNode *widget_node = gtk_widget_get_css_node (GTK_WIDGET (self));
priv->selection_node = gtk_css_node_new ();
gtk_css_node_set_name (priv->selection_node, g_quark_from_static_string ("selection"));
gtk_css_node_set_parent (priv->selection_node, widget_node);
gtk_css_node_set_state (priv->selection_node, gtk_css_node_get_state (widget_node));
g_object_unref (priv->selection_node);
}
}
else
{
if (priv->selection_node)
{
gtk_css_node_set_parent (priv->selection_node, NULL);
priv->selection_node = NULL;
}
}
}
/* All changes to priv->current_pos and priv->selection_bound
* should go through this function.
*/
@@ -4362,27 +4427,7 @@ gtk_text_set_positions (GtkText *self,
g_object_thaw_notify (G_OBJECT (self));
if (priv->current_pos != priv->selection_bound)
{
if (!priv->selection_node)
{
GtkCssNode *widget_node = gtk_widget_get_css_node (GTK_WIDGET (self));
priv->selection_node = gtk_css_node_new ();
gtk_css_node_set_name (priv->selection_node, g_quark_from_static_string ("selection"));
gtk_css_node_set_parent (priv->selection_node, widget_node);
gtk_css_node_set_state (priv->selection_node, gtk_css_node_get_state (widget_node));
g_object_unref (priv->selection_node);
}
}
else
{
if (priv->selection_node)
{
gtk_css_node_set_parent (priv->selection_node, NULL);
priv->selection_node = NULL;
}
}
update_selection_node (self);
if (changed)
{
@@ -4595,6 +4640,8 @@ gtk_text_draw_text (GtkText *self,
GtkStyleContext *context;
PangoLayout *layout;
int x, y;
int start_index, end_index;
const char *text;
/* Nothing to display at all */
if (gtk_text_get_display_mode (self) == DISPLAY_BLANK)
@@ -4602,6 +4649,7 @@ gtk_text_draw_text (GtkText *self,
context = gtk_widget_get_style_context (widget);
layout = gtk_text_ensure_layout (self, TRUE);
text = pango_layout_get_text (layout);
gtk_text_get_layout_offsets (self, &x, &y);
@@ -4609,9 +4657,23 @@ gtk_text_draw_text (GtkText *self,
if (priv->selection_bound != priv->current_pos)
{
const char *text = pango_layout_get_text (layout);
int start_index = g_utf8_offset_to_pointer (text, priv->selection_bound) - text;
int end_index = g_utf8_offset_to_pointer (text, priv->current_pos) - text;
start_index = g_utf8_offset_to_pointer (text, priv->selection_bound) - text;
end_index = g_utf8_offset_to_pointer (text, priv->current_pos) - text;
}
else if (priv->preedit_length > 0)
{
start_index = end_index = g_utf8_offset_to_pointer (text, priv->selection_bound) - text;
start_index += priv->preedit_highlight_start;
end_index += priv->preedit_highlight_end;
}
else
{
start_index = 0;
end_index = 0;
}
if (start_index != end_index)
{
cairo_region_t *clip;
cairo_rectangle_int_t clip_extents;
int range[2];
+57 -7
View File
@@ -4291,7 +4291,9 @@ gtk_text_view_measure (GtkWidget *widget,
static void
gtk_text_view_compute_child_allocation (GtkTextView *text_view,
const AnchoredChild *vc,
GtkAllocation *allocation)
GtkAllocation *allocation,
int gutter_width,
int gutter_height)
{
int buffer_y;
GtkTextIter iter;
@@ -4306,8 +4308,8 @@ gtk_text_view_compute_child_allocation (GtkTextView *text_view,
buffer_y += vc->from_top_of_line;
allocation->x = vc->from_left_of_buffer - text_view->priv->xoffset;
allocation->y = buffer_y - text_view->priv->yoffset;
allocation->x = vc->from_left_of_buffer - text_view->priv->xoffset + gutter_width;
allocation->y = buffer_y - text_view->priv->yoffset + gutter_height;
gtk_widget_get_preferred_size (vc->widget, &req, NULL);
allocation->width = req.width;
@@ -4316,11 +4318,13 @@ gtk_text_view_compute_child_allocation (GtkTextView *text_view,
static void
gtk_text_view_update_child_allocation (GtkTextView *text_view,
const AnchoredChild *vc)
const AnchoredChild *vc,
int gutter_width,
int gutter_height)
{
GtkAllocation allocation;
gtk_text_view_compute_child_allocation (text_view, vc, &allocation);
gtk_text_view_compute_child_allocation (text_view, vc, &allocation, gutter_width, gutter_height);
gtk_widget_size_allocate (vc->widget, &allocation, -1);
@@ -4333,6 +4337,44 @@ gtk_text_view_update_child_allocation (GtkTextView *text_view,
#endif
}
static void
calculate_gutter_offsets (GtkTextView *text_view,
int *width,
int *height)
{
GtkWidget *x_gutter;
GtkWidget *y_gutter;
g_return_if_fail (GTK_IS_TEXT_VIEW (text_view));
g_return_if_fail (width != NULL && height != NULL);
x_gutter = gtk_text_view_get_gutter (text_view, GTK_TEXT_WINDOW_LEFT);
if (x_gutter != NULL)
{
GtkRequisition x_req = {0};
gtk_widget_get_preferred_size (x_gutter, &x_req, NULL);
*width = x_req.width;
}
else
{
*width = 0;
}
y_gutter = gtk_text_view_get_gutter (text_view, GTK_TEXT_WINDOW_TOP);
if (y_gutter != NULL)
{
GtkRequisition y_req = {0};
gtk_widget_get_preferred_size (y_gutter, &y_req, NULL);
*height = y_req.height;
}
else
{
*height = 0;
}
}
static void
gtk_anchored_child_allocated (GtkTextLayout *layout,
GtkWidget *child,
@@ -4342,6 +4384,10 @@ gtk_anchored_child_allocated (GtkTextLayout *layout,
{
AnchoredChild *vc = NULL;
GtkTextView *text_view = data;
int x_offset = 0;
int y_offset = 0;
calculate_gutter_offsets (text_view, &x_offset, &y_offset);
/* x,y is the position of the child from the top of the line, and
* from the left of the buffer. We have to translate that into text
@@ -4357,7 +4403,7 @@ gtk_anchored_child_allocated (GtkTextLayout *layout,
vc->from_left_of_buffer = x;
vc->from_top_of_line = y;
gtk_text_view_update_child_allocation (text_view, vc);
gtk_text_view_update_child_allocation (text_view, vc, x_offset, y_offset);
}
static void
@@ -4858,6 +4904,10 @@ changed_handler (GtkTextLayout *layout,
GtkTextIter first;
int new_first_para_top;
int old_first_para_top;
int x_offset = 0;
int y_offset = 0;
calculate_gutter_offsets (text_view, &x_offset, &y_offset);
/* If the bottom of the old area was above the top of the
* screen, we need to scroll to keep the current top of the
@@ -4887,7 +4937,7 @@ changed_handler (GtkTextLayout *layout,
for (iter = priv->anchored_children.head; iter; iter = iter->next)
{
const AnchoredChild *ac = iter->data;
gtk_text_view_update_child_allocation (text_view, ac);
gtk_text_view_update_child_allocation (text_view, ac, x_offset, y_offset);
}
gtk_widget_queue_resize (widget);
+106 -12
View File
@@ -386,11 +386,29 @@
* static void
* foo_widget_init (FooWidget *self)
* {
* // ...
* gtk_widget_init_template (GTK_WIDGET (self));
*
* // Initialize the rest of the widget...
* }
* ```
*
* as well as calling [method@Gtk.Widget.dispose_template] from the dispose
* function:
*
* ```c
* static void
* foo_widget_dispose (GObject *gobject)
* {
* FooWidget *self = FOO_WIDGET (gobject);
*
* // Dispose objects for which you have a reference...
*
* // Clear the template children for this widget type
* gtk_widget_dispose_template (GTK_WIDGET (self), FOO_TYPE_WIDGET);
*
* G_OBJECT_CLASS (foo_widget_parent_class)->dispose (gobject);
* }
*
* You can access widgets defined in the template using the
* [id@gtk_widget_get_template_child] function, but you will typically declare
* a pointer in the instance private data structure of your type using the same
@@ -408,9 +426,19 @@
* G_DEFINE_TYPE_WITH_PRIVATE (FooWidget, foo_widget, GTK_TYPE_BOX)
*
* static void
* foo_widget_dispose (GObject *gobject)
* {
* gtk_widget_dispose_template (GTK_WIDGET (gobject), FOO_TYPE_WIDGET);
*
* G_OBJECT_CLASS (foo_widget_parent_class)->dispose (gobject);
* }
*
* static void
* foo_widget_class_init (FooWidgetClass *klass)
* {
* // ...
* G_OBJECT_CLASS (klass)->dispose = foo_widget_dispose;
*
* gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (klass),
* "/com/example/ui/foowidget.ui");
* gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass),
@@ -422,7 +450,7 @@
* static void
* foo_widget_init (FooWidget *widget)
* {
*
* gtk_widget_init_template (GTK_WIDGET (widget));
* }
* ```
*
@@ -7437,16 +7465,7 @@ gtk_widget_real_destroy (GtkWidget *object)
GObject *child_object = gtk_widget_get_template_child (widget,
class_type,
child_class->name);
g_assert (child_object);
if (!G_IS_OBJECT (child_object))
{
g_critical ("Automated component '%s' of class '%s' seems to"
" have been prematurely finalized",
child_class->name, g_type_name (class_type));
}
else
if (G_IS_OBJECT (child_object))
{
FinalizeAssertion *assertion = g_slice_new0 (FinalizeAssertion);
assertion->child_class = child_class;
@@ -10978,6 +10997,81 @@ out:
g_object_unref (builder);
}
/**
* gtk_widget_dispose_template:
* @widget: the widget with a template
* @widget_type: the type of the widget to finalize the template for
*
* Clears the template children for the given widget.
*
* This function is the opposite of [method@Gtk.Widget.init_template], and
* it is used to clear all the template children from a widget instance.
* If you bound a template child to a field in the instance structure, or
* in the instance private data structure, the field will be set to `NULL`
* after this function returns.
*
* You should call this function inside the `GObjectClass.dispose()`
* implementation of any widget that called `gtk_widget_init_template()`.
* Typically, you will want to call this function last, right before
* chaining up to the parent type's dispose implementation, e.g.
*
* ```c
* static void
* some_widget_dispose (GObject *gobject)
* {
* SomeWidget *self = SOME_WIDGET (gobject);
*
* // Clear the template data for SomeWidget
* gtk_widget_dispose_template (GTK_WIDGET (self), SOME_TYPE_WIDGET);
*
* G_OBJECT_CLASS (some_widget_parent_class)->dispose (gobject);
* }
* ```
*
* Since: 4.8
*/
void
gtk_widget_dispose_template (GtkWidget *widget,
GType widget_type)
{
g_return_if_fail (GTK_IS_WIDGET (widget));
g_return_if_fail (g_type_name (widget_type) != NULL);
GtkWidgetTemplate *template = GTK_WIDGET_GET_CLASS (widget)->priv->template;
g_return_if_fail (template != NULL);
/* Tear down the automatic child data */
GHashTable *auto_child_hash = get_auto_child_hash (widget, widget_type, FALSE);
for (GSList *l = template->children; l != NULL; l = l->next)
{
AutomaticChildClass *child_class = l->data;
/* This will drop the reference on the template children */
if (auto_child_hash != NULL)
{
gpointer child = g_hash_table_lookup (auto_child_hash, child_class->name);
g_assert (child != NULL);
/* We have to explicitly unparent direct children of this widget */
if (GTK_IS_WIDGET (child) && _gtk_widget_get_parent (child) == widget)
gtk_widget_unparent (child);
g_hash_table_remove (auto_child_hash, child_class->name);
}
/* Nullify the field last, to avoid re-entrancy issues */
if (child_class->offset != 0)
{
gpointer field_p;
field_p = G_STRUCT_MEMBER_P (widget, child_class->offset);
(* (gpointer *) field_p) = NULL;
}
}
}
/**
* gtk_widget_class_set_template:
* @widget_class: A `GtkWidgetClass`
+3
View File
@@ -833,6 +833,9 @@ GDK_AVAILABLE_IN_ALL
GObject *gtk_widget_get_template_child (GtkWidget *widget,
GType widget_type,
const char *name);
GDK_AVAILABLE_IN_4_8
void gtk_widget_dispose_template (GtkWidget *widget,
GType widget_type);
GDK_AVAILABLE_IN_ALL
void gtk_widget_class_set_template (GtkWidgetClass *widget_class,
GBytes *template_bytes);
+1 -1
View File
@@ -462,7 +462,7 @@ dispose (GObject *o)
g_clear_object (&sl->object);
g_clear_pointer (&sl->box, gtk_widget_unparent);
gtk_widget_dispose_template (GTK_WIDGET (o), GTK_TYPE_INSPECTOR_A11Y);
G_OBJECT_CLASS (gtk_inspector_a11y_parent_class)->dispose (o);
}
+1 -3
View File
@@ -420,14 +420,12 @@ static void
dispose (GObject *object)
{
GtkInspectorActions *sl = GTK_INSPECTOR_ACTIONS (object);
GtkWidget *child;
g_clear_object (&sl->sorted);
g_clear_object (&sl->actions);
g_clear_object (&sl->object);
while ((child = gtk_widget_get_first_child (GTK_WIDGET (sl))))
gtk_widget_unparent (child);
gtk_widget_dispose_template (GTK_WIDGET (sl), GTK_TYPE_INSPECTOR_ACTIONS);
G_OBJECT_CLASS (gtk_inspector_actions_parent_class)->dispose (object);
}
+2 -2
View File
@@ -221,7 +221,7 @@ add_content_type_row (GtkInspectorClipboard *self,
{
GtkEventController *controller = gtk_drop_controller_motion_new ();
g_signal_connect (controller, "enter", G_CALLBACK (on_drop_row_enter), viewer);
gtk_widget_add_controller (vbox, controller);
gtk_widget_add_controller (vbox, controller);
gtk_widget_set_visible (viewer, FALSE);
@@ -355,7 +355,7 @@ gtk_inspector_clipboard_dispose (GObject *object)
gtk_inspector_clipboard_unset_display (self);
g_clear_pointer (&self->swin, gtk_widget_unparent);
gtk_widget_dispose_template (GTK_WIDGET (self), GTK_TYPE_INSPECTOR_CLIPBOARD);
G_OBJECT_CLASS (gtk_inspector_clipboard_parent_class)->dispose (object);
}
+2 -2
View File
@@ -1087,8 +1087,6 @@ gtk_inspector_general_dispose (GObject *object)
GtkInspectorGeneral *gen = GTK_INSPECTOR_GENERAL (object);
GList *list, *l;
g_clear_pointer (&gen->swin, gtk_widget_unparent);
g_signal_handlers_disconnect_by_func (gen->display, G_CALLBACK (seat_added), gen);
g_signal_handlers_disconnect_by_func (gen->display, G_CALLBACK (seat_removed), gen);
g_signal_handlers_disconnect_by_func (gen->display, G_CALLBACK (populate_display_notify_cb), gen);
@@ -1099,6 +1097,8 @@ gtk_inspector_general_dispose (GObject *object)
disconnect_seat (gen, GDK_SEAT (l->data));
g_list_free (list);
gtk_widget_dispose_template (GTK_WIDGET (gen), GTK_TYPE_INSPECTOR_GENERAL);
G_OBJECT_CLASS (gtk_inspector_general_parent_class)->dispose (object);
}
+1 -3
View File
@@ -190,10 +190,8 @@ static void
dispose (GObject *object)
{
GtkInspectorListData *sl = GTK_INSPECTOR_LIST_DATA (object);
GtkWidget *child;
while ((child = gtk_widget_get_first_child (GTK_WIDGET (sl))))
gtk_widget_unparent (child);
gtk_widget_dispose_template (GTK_WIDGET (sl), GTK_TYPE_INSPECTOR_LIST_DATA);
G_OBJECT_CLASS (gtk_inspector_list_data_parent_class)->dispose (object);
}
+1 -4
View File
@@ -99,10 +99,7 @@ gtk_inspector_logs_init (GtkInspectorLogs *logs)
static void
dispose (GObject *object)
{
GtkWidget *child;
while ((child = gtk_widget_get_first_child (GTK_WIDGET (object))))
gtk_widget_unparent (child);
gtk_widget_dispose_template (GTK_WIDGET (object), GTK_TYPE_INSPECTOR_LOGS);
G_OBJECT_CLASS (gtk_inspector_logs_parent_class)->dispose (object);
}
+12 -4
View File
@@ -120,7 +120,7 @@ format_state_flags (GtkStateFlags state)
g_string_append (str, " | ");
g_string_append (str, fclass->values[i].value_nick);
}
}
}
g_type_class_unref (fclass);
}
else
@@ -165,7 +165,15 @@ update_allocation (GtkWidget *w,
gtk_label_set_label (GTK_LABEL (sl->request_mode), value->value_nick);
g_type_class_unref (class);
gtk_inspector_measure_graph_measure (GTK_INSPECTOR_MEASURE_GRAPH (sl->measure_graph), w);
if (gtk_widget_get_visible (sl->measure_row))
gtk_inspector_measure_graph_measure (GTK_INSPECTOR_MEASURE_GRAPH (sl->measure_graph), w);
}
static void
measure_graph_measure (GtkWidget *button,
GtkInspectorMiscInfo *sl)
{
gtk_inspector_measure_graph_measure (GTK_INSPECTOR_MEASURE_GRAPH (sl->measure_graph), GTK_WIDGET (sl->object));
}
static void
@@ -500,7 +508,6 @@ gtk_inspector_misc_info_set_object (GtkInspectorMiscInfo *sl,
gtk_widget_show (sl->state_row);
gtk_widget_show (sl->direction_row);
gtk_widget_show (sl->request_mode_row);
gtk_widget_show (sl->measure_row);
gtk_widget_show (sl->allocated_size_row);
gtk_widget_show (sl->baseline_row);
gtk_widget_show (sl->mnemonic_label_row);
@@ -596,7 +603,7 @@ dispose (GObject *o)
{
GtkInspectorMiscInfo *sl = GTK_INSPECTOR_MISC_INFO (o);
g_clear_pointer (&sl->swin, gtk_widget_unparent);
gtk_widget_dispose_template (GTK_WIDGET (sl), GTK_TYPE_INSPECTOR_MISC_INFO);
G_OBJECT_CLASS (gtk_inspector_misc_info_parent_class)->dispose (o);
}
@@ -662,6 +669,7 @@ gtk_inspector_misc_info_class_init (GtkInspectorMiscInfoClass *klass)
gtk_widget_class_bind_template_callback (widget_class, update_measure_picture);
gtk_widget_class_bind_template_callback (widget_class, measure_picture_drag_prepare);
gtk_widget_class_bind_template_callback (widget_class, measure_graph_measure);
gtk_widget_class_bind_template_callback (widget_class, show_surface);
gtk_widget_class_bind_template_callback (widget_class, show_renderer);
gtk_widget_class_bind_template_callback (widget_class, show_frame_clock);
+10
View File
@@ -273,6 +273,15 @@
<property name="hexpand">1</property>
</object>
</child>
<child>
<object class="GtkToggleButton" id="measure_show">
<property name="label" translatable="yes">Show</property>
<property name="halign">end</property>
<property name="valign">baseline</property>
<signal name="clicked" handler="update_measure_picture" swapped="yes" after="1" object="measure_picture"/>
<signal name="clicked" handler="measure_graph_measure" after="1"/>
</object>
</child>
<child>
<object class="GtkToggleButton" id="measure_expand_toggle">
<property name="label" translatable="yes">Expand</property>
@@ -288,6 +297,7 @@
<child>
<object class="GtkListBoxRow" id="measure_row">
<property name="activatable">0</property>
<property name="visible" bind-source="measure_show" bind-property="active" bind-flags="sync-create"/>
<child>
<object class="GtkBox">
<property name="margin-start">10</property>
+2 -1
View File
@@ -2039,11 +2039,12 @@ gtk_inspector_recorder_dispose (GObject *object)
{
GtkInspectorRecorder *recorder = GTK_INSPECTOR_RECORDER (object);
g_clear_pointer (&recorder->box, gtk_widget_unparent);
g_clear_object (&recorder->render_node_model);
g_clear_object (&recorder->render_node_root_model);
g_clear_object (&recorder->render_node_selection);
gtk_widget_dispose_template (GTK_WIDGET (recorder), GTK_TYPE_INSPECTOR_RECORDER);
G_OBJECT_CLASS (gtk_inspector_recorder_parent_class)->dispose (object);
}
+5 -4
View File
@@ -695,12 +695,12 @@ constructed (GObject *object)
GListModel *sort_model;
GtkSorter *column_sorter;
GtkSorter *sorter;
g_signal_connect (rl->open_details_button, "clicked",
G_CALLBACK (open_details), rl);
g_signal_connect (rl->close_details_button, "clicked",
G_CALLBACK (close_details), rl);
rl->tree_model = gtk_tree_list_model_new (load_resources (),
FALSE,
FALSE,
@@ -745,7 +745,7 @@ set_property (GObject *object,
GParamSpec *pspec)
{
GtkInspectorResourceList *rl = GTK_INSPECTOR_RESOURCE_LIST (object);
switch (param_id)
{
case PROP_BUTTONS:
@@ -765,10 +765,11 @@ dispose (GObject *object)
{
GtkInspectorResourceList *rl = GTK_INSPECTOR_RESOURCE_LIST (object);
g_clear_pointer (&rl->stack, gtk_widget_unparent);
g_clear_object (&rl->selection);
g_clear_object (&rl->tree_model);
gtk_widget_dispose_template (GTK_WIDGET (rl), GTK_TYPE_INSPECTOR_RESOURCE_LIST);
G_OBJECT_CLASS (gtk_inspector_resource_list_parent_class)->dispose (object);
}
+2 -4
View File
@@ -100,7 +100,7 @@ add_columns (GtkInspectorTreeData *sl)
gtk_tree_view_column_set_cell_data_func (col, cell, cell_data_func, sl, NULL);
gtk_tree_view_append_column (sl->view, col);
g_free (title);
}
}
}
static void
@@ -175,10 +175,8 @@ static void
dispose (GObject *object)
{
GtkInspectorTreeData *sl = GTK_INSPECTOR_TREE_DATA (object);
GtkWidget *child;
while ((child = gtk_widget_get_first_child (GTK_WIDGET (sl))))
gtk_widget_unparent (child);
gtk_widget_dispose_template (GTK_WIDGET (sl), GTK_TYPE_INSPECTOR_TREE_DATA);
G_OBJECT_CLASS (gtk_inspector_tree_data_parent_class)->dispose (object);
}
+8 -8
View File
@@ -1077,7 +1077,7 @@ inspect_inspector (GtkButton *button,
inspector_window = gtk_inspector_window_get (gtk_widget_get_display (GTK_WIDGET (button)));
gtk_window_present (GTK_WINDOW (inspector_window));
}
static void
gtk_inspector_visual_init (GtkInspectorVisual *vis)
{
@@ -1091,12 +1091,12 @@ gtk_inspector_visual_constructed (GObject *object)
G_OBJECT_CLASS (gtk_inspector_visual_parent_class)->constructed (object);
g_signal_connect (vis->visual_box, "keynav-failed", G_CALLBACK (keynav_failed), vis);
g_signal_connect (vis->debug_box, "keynav-failed", G_CALLBACK (keynav_failed), vis);
g_signal_connect (vis->misc_box, "keynav-failed", G_CALLBACK (keynav_failed), vis);
g_signal_connect (vis->visual_box, "row-activated", G_CALLBACK (row_activated), vis);
g_signal_connect (vis->debug_box, "row-activated", G_CALLBACK (row_activated), vis);
g_signal_connect (vis->misc_box, "row-activated", G_CALLBACK (row_activated), vis);
g_signal_connect (vis->visual_box, "keynav-failed", G_CALLBACK (keynav_failed), vis);
g_signal_connect (vis->debug_box, "keynav-failed", G_CALLBACK (keynav_failed), vis);
g_signal_connect (vis->misc_box, "keynav-failed", G_CALLBACK (keynav_failed), vis);
g_signal_connect (vis->visual_box, "row-activated", G_CALLBACK (row_activated), vis);
g_signal_connect (vis->debug_box, "row-activated", G_CALLBACK (row_activated), vis);
g_signal_connect (vis->misc_box, "row-activated", G_CALLBACK (row_activated), vis);
}
static void
@@ -1134,7 +1134,7 @@ gtk_inspector_visual_dispose (GObject *object)
{
GtkInspectorVisual *vis = GTK_INSPECTOR_VISUAL (object);
g_clear_pointer (&vis->swin, gtk_widget_unparent);
gtk_widget_dispose_template (GTK_WIDGET (vis), GTK_TYPE_INSPECTOR_VISUAL);
G_OBJECT_CLASS (gtk_inspector_visual_parent_class)->dispose (object);
}
+2 -1
View File
@@ -311,10 +311,11 @@ gtk_inspector_window_dispose (GObject *object)
g_object_set_data (G_OBJECT (iw->inspected_display), "-gtk-inspector", NULL);
g_clear_pointer (&iw->top_stack, gtk_widget_unparent);
g_clear_object (&iw->flash_overlay);
g_clear_pointer (&iw->objects, g_array_unref);
gtk_widget_dispose_template (GTK_WIDGET (iw), GTK_TYPE_INSPECTOR_WINDOW);
G_OBJECT_CLASS (gtk_inspector_window_parent_class)->dispose (object);
}
+1 -1
View File
@@ -1,5 +1,5 @@
project('gtk', 'c',
version: '4.7.0',
version: '4.7.1',
default_options: [
'buildtype=debugoptimized',
'warning_level=1',
+7 -1
View File
@@ -292,9 +292,15 @@ gtk_ff_media_file_decode_frame (GtkFfMediaFile *video,
if (errnum >= 0)
{
errnum = avcodec_receive_frame (video->codec_ctx, frame);
if (errnum == AVERROR (EAGAIN))
{
// Just retry with the next packet
errnum = 0;
continue;
}
if (errnum < 0)
G_BREAKPOINT();
if (errnum >= 0)
else
{
av_packet_unref (&packet);
break;
+47 -1
View File
@@ -80,11 +80,33 @@ quit_cb (GtkWidget *widget,
g_main_context_wakeup (NULL);
}
static void
level_changed (GtkCheckButton *button,
GParamSpec *pspec,
gpointer data)
{
GtkFontChooser *chooser = data;
GtkFontChooserLevel flags;
GtkFontChooserLevel flag;
flags = gtk_font_chooser_get_level (chooser);
flag = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (button), "flag"));
if (gtk_check_button_get_active (button))
flags |= flag;
else
flags &= ~flag;
gtk_font_chooser_set_level (chooser, flags);
}
int
main (int argc, char *argv[])
{
GtkWidget *window;
GtkWidget *font_button;
GtkWidget *box;
GtkWidget *toggle;
gboolean done = FALSE;
gtk_init ();
@@ -114,7 +136,31 @@ main (int argc, char *argv[])
gtk_font_button_set_use_font (GTK_FONT_BUTTON (font_button), TRUE);
window = gtk_window_new ();
gtk_window_set_child (GTK_WINDOW (window), font_button);
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10);
gtk_window_set_child (GTK_WINDOW (window), box);
gtk_box_append (GTK_BOX (box), font_button);
toggle = gtk_check_button_new_with_label ("Style");
gtk_check_button_set_active (GTK_CHECK_BUTTON (toggle), TRUE);
g_object_set_data (G_OBJECT (toggle), "flag", GUINT_TO_POINTER (GTK_FONT_CHOOSER_LEVEL_STYLE));
g_signal_connect (toggle, "notify::active", G_CALLBACK (level_changed), font_button);
gtk_box_append (GTK_BOX (box), toggle);
toggle = gtk_check_button_new_with_label ("Size");
gtk_check_button_set_active (GTK_CHECK_BUTTON (toggle), TRUE);
g_object_set_data (G_OBJECT (toggle), "flag", GUINT_TO_POINTER (GTK_FONT_CHOOSER_LEVEL_SIZE));
g_signal_connect (toggle, "notify::active", G_CALLBACK (level_changed), font_button);
gtk_box_append (GTK_BOX (box), toggle);
toggle = gtk_check_button_new_with_label ("Variations");
g_object_set_data (G_OBJECT (toggle), "flag", GUINT_TO_POINTER (GTK_FONT_CHOOSER_LEVEL_VARIATIONS));
g_signal_connect (toggle, "notify::active", G_CALLBACK (level_changed), font_button);
gtk_box_append (GTK_BOX (box), toggle);
toggle = gtk_check_button_new_with_label ("Features");
g_object_set_data (G_OBJECT (toggle), "flag", GUINT_TO_POINTER (GTK_FONT_CHOOSER_LEVEL_FEATURES));
g_signal_connect (toggle, "notify::active", G_CALLBACK (level_changed), font_button);
gtk_box_append (GTK_BOX (box), toggle);
gtk_widget_show (window);
g_signal_connect (font_button, "notify::font",