Compare commits

..

189 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
Matthias Clasen d0894b2786 fontchooser: Some OpenType improvements
Work harder to find examples for char variation
features, and pull the feature labels out of
the font if possible. This lets us show
meaningful names like "Localised @ and & symbols"
instead of "Stylistic Set 7" or even "ss07".
2022-07-03 07:38:24 -04:00
Matthias Clasen 5ba8fc8f10 Font features demo improvements
Use font-provided names for ssNN and cvNN features.

But good luck finding a font that has these!
2022-07-03 01:19:19 -04:00
Matthias Clasen 5d05daaed0 Font features demo improvements
Add buttons to cycle through samples.
2022-07-02 23:37:34 -04:00
Matthias Clasen 86dd72fad6 Fix up font features demo
The conversion to a textview was incomplete.
2022-07-02 22:46:27 -04:00
Мирослав Николић b0766a62ec Update Serbian translation
(cherry picked from commit 7c0cf9e0c9)
2022-07-03 02:18:58 +00:00
Emmanuele Bassi a664d06c2f Merge branch 'wip/exalm/actionbar' into 'main'
actionbar: Document GtkBuildable child types

See merge request GNOME/gtk!4848
2022-07-02 22:46:40 +00:00
Alexander Mikhaylenko d42c51e27d actionbar: Document GtkBuildable child types 2022-07-03 02:26:18 +04:00
Aleksandr Melman 63af01f7c9 Update Russian translation 2022-07-02 18:50:32 +00:00
Matthias Clasen 12f7929f44 Merge branch 'matthiasc/for-main' into 'main'
gtk4-demo: Add color to font features

See merge request GNOME/gtk!4847
2022-07-02 18:17:04 +00:00
Matthias Clasen 9c4490b7ad gtk4-demo: Add color to font features 2022-07-02 11:35:24 -04:00
Matthias Clasen f0d329cf5e Merge branch 'wip/chergert/fix-menutracker' into 'main'
menutrackeritem: protect against use-after-free

Closes #5009

See merge request GNOME/gtk!4832
2022-07-01 11:17:32 +00:00
Matthias Clasen 58d79e87ea Merge branch 'matthiasc/for-main' into 'main'
gtk4-demo: Cosmetics

See merge request GNOME/gtk!4846
2022-07-01 04:37:07 +00:00
Matthias Clasen cd40cd145f gtk4-demo: Cosmetics 2022-07-01 00:10:16 -04:00
Matthias Clasen 4f6b5b0fac Merge branch 'matthiasc/for-main' into 'main'
Matthiasc/for main

See merge request GNOME/gtk!4845
2022-07-01 04:08:03 +00:00
Matthias Clasen 88bbb933a1 gtk4-demo: Add a waterfall to font features 2022-06-30 23:52:37 -04:00
Matthias Clasen 4070e794d2 gtk4-demo: Fix font features animation 2022-06-30 21:11:49 -04:00
Matthias Clasen 3b6ec027d3 Merge branch 'matthiasc/for-main' into 'main'
demos: Use gtk_builder_cscope_add_callback

See merge request GNOME/gtk!4844
2022-07-01 01:03:04 +00:00
Matthias Clasen a284dc9f31 demos: Use gtk_builder_cscope_add_callback
This is C convenience API, lets use it for
our convenience.
2022-06-30 20:10:06 -04:00
Matthias Clasen 091daf4cff Merge branch 'matthiasc/for-main' into 'main'
Add gtk_builder_cscope_add_callback

See merge request GNOME/gtk!4843
2022-06-30 23:23:04 +00:00
Matthias Clasen 64f3ac6760 gtk3-demo: Add animation to font features 2022-06-30 19:02:02 -04:00
Matthias Clasen 508ceccb66 gtk4-demo: Polish the font features demo 2022-06-30 19:02:02 -04:00
Matthias Clasen d6dde63074 gtk4-demo: Restructure the font features demo 2022-06-30 19:02:02 -04:00
Matthias Clasen bdb1886fc9 gtk4-demo: Cosmetics
Rename the ui file to match the C source, to preserve sanity.
2022-06-30 19:02:02 -04:00
Matthias Clasen faa9ef2dc0 Add gtk_builder_cscope_add_callback
This is a convenience method for the common case
that symbols are used under their own name.
2022-06-30 19:02:02 -04:00
Matthias Clasen 21b9667f08 Merge branch 'matthiasc/for-main' into 'main'
gtk-demo: Beef up font features demo

See merge request GNOME/gtk!4841
2022-06-30 14:12:20 +00:00
Matthias Clasen e4781e393c gtk-demo: Beef up font features demo
Some work on making this demo better.
2022-06-30 09:42:32 -04:00
Matthias Clasen 7536513ef8 Merge branch 'wip/jimmac/selectable-labels' into 'main'
theme: selectable labels legibility

Closes #5017

See merge request GNOME/gtk!4840
2022-06-29 20:05:44 +00:00
Jakub Steiner 6776c21350 theme: selectable labels legibility
- don't set fg color for selections

Fixes https://gitlab.gnome.org/GNOME/gtk/-/issues/5017
2022-06-29 21:40:30 +02:00
Matthias Clasen 9f4ef77663 Merge branch 'matthiasc/for-main' into 'main'
gtk-demo: Cosmetics

See merge request GNOME/gtk!4839
2022-06-29 19:16:32 +00:00
Benjamin Otte a64bb67ef7 Merge branch 'testdatatable' into 'main'
tests: Add testdatatable

See merge request GNOME/gtk!4838
2022-06-29 13:00:53 +00:00
Ivan Molodetskikh 53f3b4b9d9 tests: Add testdatatable
Add a GtkColumnView scrolling performance test similar to the one used
previously in https://gitlab.gnome.org/GNOME/gtk/-/issues/3334.

The test creates a table with 20 columns and 10,000 rows and scrolls it
to a random position every frame, while measuring the frame times.

There is a commandline flag to pick the cell widget between none (for
benchmarking raw column view scrolling) and various label types. There
is also a commandline switch to disable automatic scrolling in case a
manual assessment is desired. Finally, there's an argument for
controlling the number of columns.
2022-06-28 21:52:49 -07:00
Emmanuele Bassi 5bb4d69720 Merge branch 'ebassi/ci-publish-doc-fix' into 'main'
ci: Force the fedora image for the publish-docs job

See merge request GNOME/gtk!4837
2022-06-28 21:02:46 +00:00
Emmanuele Bassi 35808a918d ci: Force the fedora image for the publish-docs job
Otherwise every CI runner might decide to use a different default
image, and we'll end up on one that doesn't have curl.
2022-06-28 21:32:08 +01:00
Benjamin Otte 672618e560 Merge branch 'wip/otte/for-main' into 'main'
Rework listitemfactory

See merge request GNOME/gtk!4835
2022-06-28 19:30:17 +00:00
Emmanuele Bassi e28516d189 Merge branch 'template-signals' into 'main'
Force quark creation for templates

See merge request GNOME/gtk!4836
2022-06-28 17:59:31 +00:00
Maximiliano Sandoval R dfe9460240 Force quark creation for templates 2022-06-28 18:48:38 +02:00
Sabri Ünal 01820d8524 Update Turkish translation 2022-06-28 15:52:12 +00:00
Benjamin Otte be1729b316 signallistitemfactory: Update signal prototype
I'm not sure this is API safe, but it is necessary if we want to support
section items and canvas items.

If it's deemed API-unstable, we have to copy this object and deprecate
this one.
2022-06-28 16:37:38 +02:00
Benjamin Otte 57f2b5d2e6 listitemfactory: Make this callback-based
This way, we no longer prescribe the use of either GtkListItem or
GtkListItemWidget.

This means we can use it in other places, such as for custom section
header objects or with my Canvas ideas.
2022-06-28 16:37:38 +02:00
Benjamin Otte c00b234440 picture: Clear the paintable properly
Add a clear() function and call it from dispose() instead of using
set_paintable().
2022-06-28 16:37:11 +02:00
Danial Behzadi 8d803e8615 Update Persian translation 2022-06-28 10:31:16 +00:00
Aleksandr Melman 9477ecbc92 Update Russian translation 2022-06-25 18:36:18 +00:00
Quentin PAGÈS 1e686ee535 Update Occitan translation 2022-06-25 08:56:48 +00:00
Christian Hergert 4d883861b1 menutrackeritem: protect against use-after-free
With recent updates to GLib, I now see cases where we can hit a state that
has finalized before notify (which will bump the ref count back up). This
is evident in GNOME Text Editor when showing a language submenu from a
popover, and then dismissing the popover and subsequently the tab.

With the previous commit, we at least get a warning like this, which helped
track down the issue.

 Gtk-CRITICAL **: gtk_action_observable_unregister_observer: assertion 'GTK_IS_ACTION_OBSERVABLE (observable)' failed
 GLib-GObject-CRITICAL **: g_object_ref: assertion '!object_already_finalized' failed

This patch fixes both of those criticals.

Fixes #5009
2022-06-24 14:30:45 -07:00
Christian Hergert f9c0fc4fdd menutrackeritem: be defensive during finalize
The menu/action system tends to be incredibly re-entrant, and while fixing
the misuse during finalization cycles should be a priority, this can help
protect just a bit more.

Related #5009
2022-06-24 14:30:31 -07:00
Benjamin Otte 354f1a783a Merge branch 'wip/otte/for-main' into 'main'
gdk: Replace GTK_USE_PORTAL env var with GDK_DEBUG flag

See merge request GNOME/gtk!4829
2022-06-24 03:39:16 +00:00
Benjamin Otte 813dd0a674 gdk: Replace GTK_USE_PORTAL env var with GDK_DEBUG flag
It's a debug flag, so make it clear that it is one.

Related: Clowns on the Arch wiki on
https://wiki.archlinux.org/title/Uniform_look_for_Qt_and_GTK_applications#Consistent_file_dialog
2022-06-24 03:14:50 +02:00
Matthias Clasen bbfacb4d22 Merge branch 'alatiera/doc-type' into 'main'
shortcutcontroller: fix typo in property docs

See merge request GNOME/gtk!4827
2022-06-23 21:46:45 +00:00
Hugo Carvalho 086f2324a3 Update Portuguese translation 2022-06-23 21:41:23 +00:00
Jordan Petridis c378eacb5d shortcutcontroller: fix typo in property docs
followup of d7dae84af2
2022-06-23 22:35:48 +03:00
Matthias Clasen 0660bb834e Merge branch 'bad-popup-extents' into 'main'
[x11] Fix coordinate space of rect in gdk_x11_surface_get_frame_extents when called on popups.

See merge request GNOME/gtk!4820
2022-06-23 11:59:55 +00:00
Matthias Clasen 092fe2f712 gtk-demo: Cosmetics
Tweak the complicated textview demo a bit.
2022-06-23 07:40:55 -04:00
Matthias Clasen 5be54fad82 Merge branch 'wip/jtojnar/demo-pickers-no-dirs' into 'main'
gtk-demo: Remove mention of directories in picker examples

See merge request GNOME/gtk!4825
2022-06-23 11:39:33 +00:00
Jan Tojnar d91e669d98 gtk-demo: Remove mention of directories in picker examples
Those were removed in https://gitlab.gnome.org/GNOME/gtk/-/merge_requests/2909.
2022-06-22 23:07:28 +02:00
Asier Sarasua Garmendia 9a22577e34 Update Basque translation 2022-06-22 19:17:51 +00:00
Yuri Chornoivan 88366c5e13 Update Ukrainian translation 2022-06-22 19:06:56 +00:00
Matthias Clasen 287ed99130 Merge branch 'wip/otte/inspector-inspector' into 'main'
inspector: Inspect

See merge request GNOME/gtk!4822
2022-06-22 18:25:13 +00:00
Matthias Clasen 40e09cf2bb Merge branch 'wip/xdg-toplevel-bounds' into 'main'
wayland: Add supports for xdg_toplevel.bounds

See merge request GNOME/gtk!4261
2022-06-22 14:24:41 +00:00
Matthias Clasen 5a3ca064ea Merge branch 'gtk-window-export-handle-win32' into 'main'
Implement gtk_window_export_handle for other backends

See merge request GNOME/gtk!4824
2022-06-22 14:20:11 +00:00
Daniel Mustieles edc991dafd Updated Spanish translation 2022-06-22 10:45:59 +02:00
Luca Bacci a1d03e69a4 Add stub gtk_window_export_handle implementation for some backends 2022-06-21 22:56:33 +02:00
Benjamin Otte 18c2ba9b71 inspector: Add an "inspect inspector" button
And launch a new inspector.

The location of that button is rather random - I had no idea where to
put it.
2022-06-21 02:35:02 +02:00
Benjamin Otte 3da3cb35a6 object-tree: Allow inspecting inspectors
We filter by display, so the inspector window should show up only when
inspecting the inspector.
2022-06-21 02:35:02 +02:00
Benjamin Otte e54567611b inspector: Don't use global variable here
When inspecting the inspector, we want to create mutiple displays here.

If we need this to be global, we should store it per-inspected-display.
2022-06-21 02:35:02 +02:00
Aurimas Černius ce88d19015 Updated Lithuanian translation 2022-06-20 22:18:16 +03:00
Emilio Cobos Álvarez 5301a74bd3 [x11] Fix coordinate space of rect in gdk_x11_surface_get_frame_extents when called on popups.
If we take the early return we don't unscale this at the bottom of the
function, causing wrong coordinates in HiDPI screens.

This bug also affects GTK3 (I noticed this running Firefox tests on X).
2022-06-20 10:13:21 +02:00
Matthias Clasen 381c34783d Merge branch 'alatiera/inscription-since' into 'main'
inscription: Add missing Since annotations

See merge request GNOME/gtk!4815
2022-06-17 22:38:16 +00:00
Luca Bacci 3ea8dc02a3 Merge branch 'gdk-win32-gtk-overlay-scrolling' into 'main'
GdkWin32: Add code for gtk-overlay-scrolling setting

Closes #4899

See merge request GNOME/gtk!4816
2022-06-17 09:37:14 +00:00
Luca Bacci 83c780cfad GdkWin32: Add code for gtk-overlay-scrolling setting
Fixes https://gitlab.gnome.org/GNOME/gtk/-/issues/4899
2022-06-17 11:06:43 +02:00
Jordan Petridis 4b5d218067 inscription: Add missing Since annotations 2022-06-17 00:15:46 +03:00
Matthias Clasen 8944493eca Merge branch 'wip/jimmac/hc-sidebar-borders' into 'main'
HC: make selected items better visible

Closes #4984

See merge request GNOME/gtk!4813
2022-06-15 13:40:17 +00:00
Jakub Steiner dd9f26c492 HC: make selected items better visible
- follow libadwaita's example and outline selected items for better visibility
  in high contrast variant

Fixes https://gitlab.gnome.org/GNOME/gtk/-/issues/4984
2022-06-15 14:47:47 +02:00
Jordi Mas 3c038dc239 Update Catalan translation 2022-06-14 19:41:12 +02:00
Matthias Clasen 9ee555719e Merge branch 'matthiasc/for-main' into 'main'
gtk-demo: Add some keywords

See merge request GNOME/gtk!4812
2022-06-14 12:25:02 +00:00
Benjamin Otte 7953092059 Merge branch 'wip/antoniof/dont-rubberband-on-drag-end' into 'main'
listbase: Don't start rubberband on ::drag-end

See merge request GNOME/gtk!4793
2022-06-14 03:45:55 +00:00
Jonas Ådahl de1a8c8d89 wayland: Add support for xdg_toplevel.bounds
The GdkToplevelSize struct already has the concept of "bounds", which
means the largest size a window should reasonably have. It's practically
the equivalent of the monitor the window is intended to be mapped on,
with the "struts" (e.g. panels) cut out. It's used by GTK to use this
information to calculate a default window size that is "lagom" (swedish;
not too large, not too small).
2022-06-13 22:12:55 +02:00
Jordi Mas 98e000beb7 Update Catalan translation 2022-06-13 20:01:17 +02:00
Matthias Clasen 8b3a38779b gtk-demo: Add some keywords
Make it so that the right demos show up when
you search for GtkInscription.
2022-06-13 11:16:51 -04:00
Aleksandr Melman 8d72c8ee5f Update Russian translation 2022-06-13 13:26:30 +00:00
Benjamin Otte f9b0866415 Merge branch 'wip/otte/inscription' into 'main'
Inscription: Derive row alignment from xalign

See merge request GNOME/gtk!4811
2022-06-13 12:08:16 +00:00
Danial Behzadi dbe06357ec Update Persian translation 2022-06-13 06:44:53 +00:00
Danial Behzadi 9e03c3f6cd Update Persian translation 2022-06-13 05:48:56 +00:00
Benjamin Otte 2d14372142 reftests: Add an inscription xalign RTL test
This checks mainly that we do the right thing wrt PangoAlignment
weirdness.

0.25 and 0.75 are set to 0.0 and 1.0 currently because of Pango
limitations (and no desire to manually move lines).
But if that were to be fixed, both the ref and the test should update in
the same way and things should just keep working.
2022-06-13 06:49:22 +02:00
Benjamin Otte 0a4c08a7be inscription: Multiparagraph text is always multiline
Wrap this text and clip towards the bottom, no matter how high the
inscription is.
2022-06-13 06:49:12 +02:00
Benjamin Otte 883011f252 inscription: Do not try to align layouts that have a proper width set
Pango knows where to put the text.
2022-06-13 06:49:12 +02:00
Benjamin Otte 4927b6e625 reftests: Add inscription reftest for xalign
Compare with labels again.
2022-06-13 06:49:11 +02:00
Georges Basile Stavracas Neto c93a01d627 Inscription: Derive row alignment from xalign
Texts usually want the alignment of each row to match the xalign of
the text itself.

Derive the alignment of the PangoLayout from the xalign property of
the inscription. Because Pango doesn't provide float row alignment,
map left, center and right from the xalign in 1 / 3 steps.
2022-06-13 05:35:47 +02:00
Piotr Drąg 221a18704b Update POTFILES.skip 2022-06-12 14:52:37 +02:00
Matthias Clasen 62984d091a Merge branch 'wip/otte/inscription' into 'main'
More inscription work

See merge request GNOME/gtk!4808
2022-06-12 01:38:40 +00:00
Benjamin Otte 6d15549f51 inscription: Add ::wrap-mode
We use a different wrap-mode than GtkLabel, because we cannot just
resize the widget to make long words fit, we have to fit the size we are
given.
2022-06-12 03:10:50 +02:00
Benjamin Otte 4c1fc4f5d7 reftests: Test inscription multiline overflow 2022-06-12 02:42:00 +02:00
Benjamin Otte 98e0ca7477 gtk-demo: Add a "Read More" label demo. 2022-06-11 22:19:17 +02:00
Benjamin Otte 4809efd630 reftests: Test overflowing inscription yalign
Overflowing inscriptions should always align to the top, even when half
an extra line is available.
2022-06-11 22:19:17 +02:00
Matthias Clasen d88e935398 Merge branch 'wip/otte/listmodels' into 'main'
19 listmodels: Add ::item-type and ::n-items

See merge request GNOME/gtk!4807
2022-06-11 15:15:53 +00:00
Benjamin Otte 393ef4d0a2 inscription: Fixate layout at top when it doesn't fit
Ellipsized and clipped layouts shouldn't reposition themselves according
to yalign when they don't fully fit.
2022-06-11 16:28:27 +02:00
Benjamin Otte efd9aac3fa assistant: Add ::item-type and ::n-items to the pages list 2022-06-11 16:08:37 +02:00
Matthias Clasen c7c8b37e4c Merge branch 'wip/otte/inscription' into 'main'
Add GtkInscription

See merge request GNOME/gtk!4800
2022-06-11 13:47:20 +00:00
Benjamin Otte 11aef91fa5 bookmarklist: Add ::item-type and ::n-items 2022-06-11 08:25:23 +02:00
Benjamin Otte f48c9b8388 directorylist: Add ::item-type and ::n-items 2022-06-11 08:25:22 +02:00
Benjamin Otte 62096ebd16 filterlistmodel: Add ::item-type and ::n-items
With tests!
2022-06-11 08:25:22 +02:00
Benjamin Otte f7b8184b00 fattenlistmodel: Add ::item-type and ::n-items
With tests!
2022-06-11 08:25:21 +02:00
Benjamin Otte b91f60b4f9 listlistmodel: Add ::item-type and ::n-items 2022-06-11 08:25:21 +02:00
Benjamin Otte b6ba8ecbd0 maplistmodel: Add ::item-type and ::n-items
With tests!
2022-06-11 08:25:20 +02:00
Benjamin Otte 02ee10639d multifilter: Add ::item-type and ::n-items 2022-06-11 08:25:20 +02:00
Benjamin Otte 0e42fa95b1 multiselection: Add ::item-type and ::n-items
With tests!
2022-06-11 08:25:19 +02:00
Benjamin Otte 7a36632afc multisorter: Add ::item-type and ::n-items 2022-06-11 08:25:19 +02:00
Benjamin Otte 301f1a577d noselection: Add ::item-type and ::n-items 2022-06-11 08:25:18 +02:00
Benjamin Otte 67e336992f propertylookuplistmodel: Add ::item-type and ::n-items
With tests!
2022-06-11 08:25:18 +02:00
Benjamin Otte e1845f5e90 selectionfiltermodel: Add ::item-type and ::n-items 2022-06-11 08:25:17 +02:00
Benjamin Otte d7dae84af2 shortcutcontroller: Add ::item-type and ::n-items 2022-06-11 08:25:17 +02:00
Benjamin Otte 0f829c4599 singleselection: Add ::item-type and ::n-items
With tests!
2022-06-11 08:25:16 +02:00
Benjamin Otte 3fca865625 slicelistmodel: Add ::item-type and ::n-items
With tests!
2022-06-11 08:25:16 +02:00
Benjamin Otte bf8b26aa27 sortlistmodel: Add ::item-type and ::n-items
With tests!
2022-06-11 08:25:15 +02:00
Benjamin Otte cbc3d3f3ec stack: Add ::item-type and ::n-items to the pages list 2022-06-11 08:25:15 +02:00
Benjamin Otte fd4562aac9 treelistmodel: Add ::item-type and ::n-items
With tests!
2022-06-11 08:25:14 +02:00
Benjamin Otte c26962c4b1 multifilter: Actually emit ::items-changed when items change 2022-06-11 08:25:14 +02:00
Benjamin Otte 46ce19d22a multisorter: Actually emit ::items-changed when items change 2022-06-11 08:25:14 +02:00
Benjamin Otte 303bc3bb1b inspector: Use inscriptions for the rendernodes list 2022-06-11 02:15:08 +02:00
Benjamin Otte bf5edc6b7c reftests: Add test for the overflow methods
Reference is using labels again
2022-06-11 02:15:08 +02:00
Benjamin Otte 7c034cc283 inscription: Set css name
We use "label" just like GtkLabel as the two widgets differ in the way
they are measured, but they should be styled the same.

If it turns out we change our opinion on this for specific cases, we
can add style classes later.
2022-06-11 02:15:08 +02:00
Benjamin Otte e437a9c348 inscription: Add a11y support for text interface
This is entirely untested.
2022-06-11 02:15:08 +02:00
Benjamin Otte 1517c1813c inscription: Add ::text-overflow
Can't name it ::overflow, because that's taken by GtkWidget already
2022-06-11 02:15:08 +02:00
Benjamin Otte 9973a7173f reftests: Add test for inscription markup parsing
Compare with label markup parsing as the reference.
2022-06-11 02:15:08 +02:00
Benjamin Otte 01fcfc5c2a inscription: Add ::markup
Utility property that sets both the ::text and ::attributes properties,
mainly intended for use in ui files to ease translation support and bindings.
2022-06-11 02:15:08 +02:00
Benjamin Otte 3f4c88aad1 inscription: Add ::attributes property 2022-06-11 02:15:08 +02:00
Emin Tufan Çetin 8a0d6da187 Update Turkish translation 2022-06-10 06:06:14 +00:00
Benjamin Otte b8199bcc1f gtkpango: Add G_GNUC_WARN_UNUSED_RESULT
Guess who just spent 10 minutes in gdb and doesn't want to do that
again.
2022-06-10 04:34:23 +02:00
Benjamin Otte abdbef1b5e inspector: Add inscription support
Allow searching for inscription text and show it in the label column.
2022-06-10 04:34:23 +02:00
Benjamin Otte 6ac7f0562b inspector: Use inscriptions in the object tree 2022-06-10 04:34:23 +02:00
Benjamin Otte c796b30136 testcolumnview: Use GtkInscription
This test is suddenly MASSIVELY faster.

I wonder why.
Could it be because inscription does exactly what it was made for?
2022-06-10 04:34:23 +02:00
Benjamin Otte 61bc38cd61 gtk-demo: Use GtkInscription in the wordlist demo 2022-06-10 04:34:23 +02:00
Benjamin Otte b56b5ed81b gtk-demo: Use GtkInscription in the main list 2022-06-10 04:34:23 +02:00
Benjamin Otte b6a8080b2f Add GtkInscription
A label alternative that renders itself into a given rectangle.

The main use case is cells in column view.

Related: #3334
2022-06-09 05:58:27 +02:00
Matthias Clasen 0400607102 Merge branch 'symbolic-hc' into 'main'
Wayland/display: Don't force HighContrast icon theme

See merge request GNOME/gtk!4802
2022-06-08 10:36:46 +00:00
Matthias Clasen 5089fa3ecc Merge branch 'node-editor-scale' into 'main'
node-editor: Add a zoom button

See merge request GNOME/gtk!4804
2022-06-07 18:57:53 +00:00
Benjamin Otte dec6a93510 Merge branch 'wip/otte/for-main' into 'main'
inspector: Allow searching for editable text

See merge request GNOME/gtk!4801
2022-06-07 18:20:43 +00:00
Florian Müllner c3706ea9ec wayland/display: Don't force HighContrast icon theme
The theme is considered deprecated in favor of symbolic icons from
the regular theme.
2022-06-07 19:34:50 +02:00
Benjamin Otte e4869938b7 listview: Fix clipping for horizontal listviews
Fixes a bug introduced with
commit 39645d3258
2022-06-07 19:21:46 +02:00
Benjamin Otte fa1dca29b6 inspector: Allow searching for editable text
... and display it in the label column.
2022-06-07 17:33:04 +02:00
Benjamin Otte 9de027df65 video: Fix typo in docs 2022-06-07 05:56:15 +02:00
António Fernandes dc4540fae9 listbase: Don't start rubberband on ::drag-end
GtkGestrureDrag::drag-end can be emitted when the pointer has just
crossed the drag threshold and we have not started the rubberband yet.
This happens if another gesture has claimed the event sequence earlier
in the current event propagation chain.

In such situation, our ::drag-end calls gtk_list_base_drag_update(), 
which proceeds to start the rubberband. That's obviously wrong.
Additionally, it also tries to get modifiers from an event it we are 
already denied,  which obviously fails with criticals:

`gdk_event_get_modifier_state: assertion 'GDK_IS_EVENT (event)' failed`

Thus, if there is no rubberband when we receive ::drag-end, do nothing.
2022-06-04 17:30:10 +00:00
160 changed files with 12564 additions and 6486 deletions
+1
View File
@@ -346,6 +346,7 @@ reference:
- _reference
publish-docs:
image: fedora:latest
stage: publish
needs: ['reference']
script:
+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);
}
+7 -10
View File
@@ -341,16 +341,13 @@ do_clipboard (GtkWidget *do_widget)
GtkWidget *button;
scope = gtk_builder_cscope_new ();
gtk_builder_cscope_add_callback_symbols (GTK_BUILDER_CSCOPE (scope),
"copy_button_clicked", G_CALLBACK (copy_button_clicked),
"paste_button_clicked", G_CALLBACK (paste_button_clicked),
"source_changed_cb", G_CALLBACK (source_changed_cb),
"text_changed_cb", G_CALLBACK (text_changed_cb),
"open_file_cb", G_CALLBACK (open_file_cb),
"on_drop", G_CALLBACK (on_drop),
"drag_prepare", G_CALLBACK (drag_prepare),
NULL);
gtk_builder_cscope_add_callback (scope, copy_button_clicked);
gtk_builder_cscope_add_callback (scope, paste_button_clicked);
gtk_builder_cscope_add_callback (scope, source_changed_cb);
gtk_builder_cscope_add_callback (scope, text_changed_cb);
gtk_builder_cscope_add_callback (scope, open_file_cb);
gtk_builder_cscope_add_callback (scope, on_drop);
gtk_builder_cscope_add_callback (scope, drag_prepare);
builder = gtk_builder_new ();
gtk_builder_set_scope (builder, scope);
gtk_builder_add_from_resource (builder, "/clipboard/clipboard.ui", NULL);
+2 -1
View File
@@ -329,6 +329,7 @@
<file>pickers.c</file>
<file>printing.c</file>
<file>revealer.c</file>
<file>read_more.c</file>
<file>rotated_text.c</file>
<file>scale.c</file>
<file>search_entry.c</file>
@@ -375,7 +376,7 @@
<file>glarea-gles.vs.glsl</file>
</gresource>
<gresource prefix="/font_features">
<file>font-features.ui</file>
<file>font_features.ui</file>
<file>fontplane.c</file>
</gresource>
<gresource prefix="/spinbutton">
+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);
}
+3 -6
View File
@@ -90,12 +90,9 @@ do_errorstates (GtkWidget *do_widget)
toplevel = GTK_WIDGET (gtk_widget_get_root (do_widget));
scope = gtk_builder_cscope_new ();
gtk_builder_cscope_add_callback_symbols (GTK_BUILDER_CSCOPE (scope),
"validate_more_details", G_CALLBACK (validate_more_details),
"mode_switch_state_set", G_CALLBACK (mode_switch_state_set),
"level_scale_value_changed", G_CALLBACK (level_scale_value_changed),
NULL);
gtk_builder_cscope_add_callback (scope, validate_more_details);
gtk_builder_cscope_add_callback (scope, mode_switch_state_set);
gtk_builder_cscope_add_callback (scope, level_scale_value_changed);
builder = gtk_builder_new ();
gtk_builder_set_scope (builder, scope);
gtk_builder_expose_object (builder, "toplevel", G_OBJECT (toplevel));
-190
View File
@@ -1,190 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkWindow" id="window">
<property name="default-width">600</property>
<property name="default-height">500</property>
<property name="title">Font Explorer</property>
<child type="titlebar">
<object class="GtkHeaderBar">
<child>
<object class="GtkButton" id="reset">
<property name="receives-default">1</property>
<property name="tooltip-text">Reset</property>
<property name="icon-name">view-refresh-symbolic</property>
<signal name="clicked" handler="font_features_reset_features" swapped="no"/>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox">
<child>
<object class="GtkScrolledWindow">
<property name="hscrollbar-policy">never</property>
<child>
<object class="GtkViewport">
<child>
<object class="GtkBox">
<property name="margin-start">10</property>
<property name="margin-end">10</property>
<property name="margin-top">10</property>
<property name="margin-bottom">10</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
<object class="GtkFontButton" id="font">
<property name="receives-default">1</property>
<property name="font">Sans 12</property>
<property name="level">family|style|size|variations|features</property>
<signal name="font-set" handler="font_features_font_changed" swapped="no"/>
</object>
</child>
<child>
<object class="GtkExpander">
<child type="label">
<object class="GtkLabel">
<property name="xalign">0</property>
<property name="label" translatable="yes">Font Features</property>
<attributes>
<attribute name="weight" value="bold"></attribute>
</attributes>
</object>
</child>
<child>
<object class="GtkBox" id="feature_list">
<property name="orientation">vertical</property>
<child>
<object class="GtkComboBox" id="script_lang">
<property name="margin-top">10</property>
<signal name="changed" handler="font_features_script_changed" swapped="no"/>
<child>
<object class="GtkCellRendererText"/>
<attributes>
<attribute name="text">0</attribute>
</attributes>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkExpander">
<child type="label">
<object class="GtkLabel" id="variations_heading">
<property name="label" translatable="yes">Font Variations</property>
<property name="xalign">0</property>
<attributes>
<attribute name="weight" value="bold"></attribute>
</attributes>
</object>
</child>
<child>
<object class="GtkGrid" id="variations_grid">
<property name="column-spacing">10</property>
<property name="row-spacing">10</property>
</object>
</child>
</object>
</child>
</object>
</child>
<style>
<class name="view"/>
</style>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<property name="hexpand">1</property>
<property name="vexpand">1</property>
<property name="margin-start">20</property>
<property name="margin-end">20</property>
<property name="margin-top">20</property>
<property name="margin-bottom">20</property>
<property name="spacing">20</property>
<child>
<object class="GtkStack" id="stack">
<child>
<object class="GtkStackPage">
<property name="name">label</property>
<property name="child">
<object class="GtkLabel" id="label">
<property name="wrap">1</property>
<property name="xalign">0</property>
<property name="yalign">0</property>
<property name="valign">start</property>
<property name="selectable">1</property>
</object>
</property>
</object>
</child>
<child>
<object class="GtkStackPage">
<property name="name">entry</property>
<property name="child">
<object class="GtkEntry" id="entry">
<property name="text">Grumpy wizards make toxic brew for the evil Queen and Jack. A quick movement of the enemy will jeopardize six gunboats. The job of waxing linoleum frequently peeves chintzy kids. My girl wove six dozen plaid jackets before she quit. Twelve ziggurats quickly jumped a finch box.
Разъяренный чтец эгоистично бьёт пятью жердями шустрого фехтовальщика. Наш банк вчера же выплатил Ф.Я. Эйхгольду комиссию за ценные вещи. Эх, чужак, общий съём цен шляп (юфть) – вдрызг! В чащах юга жил бы цитрус? Да, но фальшивый экземпляр!
Τάχιστη αλώπηξ βαφής ψημένη γη, δρασκελίζει υπέρ νωθρού κυνός</property>
<signal name="activate" handler="font_features_stop_edit"/>
<property name="valign">start</property>
<property name="width-chars">50</property>
</object>
</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkLabel" id="settings">
<property name="wrap">1</property>
<property name="xalign">0</property>
<property name="valign">end</property>
<property name="width-chars">50</property>
<property name="max-width-chars">50</property>
<property name="hexpand">1</property>
<property name="vexpand">1</property>
<style>
<class name="monospace"/>
</style>
</object>
</child>
<child>
<object class="GtkBox">
<property name="spacing">10</property>
<child>
<object class="GtkLabel" id="description">
<property name="wrap">1</property>
<property name="xalign">0</property>
<property name="valign">end</property>
<property name="width-chars">50</property>
<property name="max-width-chars">50</property>
<property name="hexpand">1</property>
<style>
<class name="monospace"/>
</style>
</object>
</child>
<child>
<object class="GtkToggleButton" id="edit_toggle">
<property name="icon-name">document-edit-symbolic</property>
<property name="halign">end</property>
<property name="valign">end</property>
<signal name="toggled" handler="font_features_toggle_edit"/>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</interface>
File diff suppressed because it is too large Load Diff
+65
View File
@@ -0,0 +1,65 @@
--- demos/gtk-demo/font_features.c
+++ demos/gtk-demo/font_features.c
@@ -434,7 +434,7 @@ static void
update_display (void)
{
GString *s;
- const char *text;
+ char *text;
gboolean has_feature;
GtkTreeIter iter;
GtkTreeModel *model;
@@ -452,8 +452,12 @@ update_display (void)
gboolean do_waterfall;
GString *waterfall;
char *palette;
+ GtkTextBuffer *buffer;
+ GtkTextIter start_iter, end_iter;
- text = gtk_editable_get_text (GTK_EDITABLE (demo->the_entry));
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (demo->the_entry));
+ gtk_text_buffer_get_bounds (buffer, &start_iter, &end_iter);
+ text = gtk_text_buffer_get_text (buffer, &start_iter, &end_iter, FALSE);
text_len = strlen (text);
do_waterfall = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (demo->waterfall_toggle));
@@ -631,6 +635,8 @@ update_display (void)
pango2_font_description_free (desc);
g_free (features);
pango2_attr_list_unref (attrs);
+
+ g_free (text);
}
static Pango2Font *
@@ -1603,8 +1609,12 @@ font_features_toggle_edit (void)
{
if (strcmp (gtk_stack_get_visible_child_name (GTK_STACK (demo->stack)), "entry") != 0)
{
+ GtkTextBuffer *buffer;
+ GtkTextIter start, end;
g_free (demo->text);
- demo->text = g_strdup (gtk_editable_get_text (GTK_EDITABLE (demo->the_entry)));
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (demo->the_entry));
+ gtk_text_buffer_get_bounds (buffer, &start, &end);
+ demo->text = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
gtk_stack_set_visible_child_name (GTK_STACK (demo->stack), "entry");
gtk_widget_grab_focus (demo->the_entry);
gtk_adjustment_set_value (gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (demo->swin)), 0);
@@ -1632,7 +1642,7 @@ entry_key_press (GtkEventController *controller,
{
if (keyval == GDK_KEY_Escape)
{
- gtk_editable_set_text (GTK_EDITABLE (entry), demo->text);
+ gtk_text_buffer_set_text (gtk_text_view_get_buffer (GTK_TEXT_VIEW (demo->the_entry)), demo->text, -1);
return GDK_EVENT_STOP;
}
@@ -1701,7 +1711,6 @@ do_font_features (GtkWidget *do_widget)
basic_value_changed (demo->line_height_adjustment, demo->line_height_entry);
controller = gtk_event_controller_key_new ();
- g_object_set_data_full (G_OBJECT (demo->the_entry), "controller", g_object_ref (controller), g_object_unref);
g_signal_connect (controller, "key-pressed", G_CALLBACK (entry_key_press), demo->the_entry);
gtk_widget_add_controller (demo->the_entry, controller);
+454
View File
@@ -0,0 +1,454 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkAdjustment" id="size_adjustment">
<property name="lower">7</property>
<property name="upper">100</property>
<property name="value">14</property>
<property name="step_increment">0.5</property>
<property name="page_increment">10</property>
<signal name="value-changed" handler="basic_value_changed" object="size_entry" swapped="false"/>
</object>
<object class="GtkAdjustment" id="letterspacing_adjustment">
<property name="lower">-1024</property>
<property name="upper">8192</property>
<property name="value">0</property>
<property name="step_increment">1</property>
<property name="page_increment">512</property>
<signal name="value-changed" handler="basic_value_changed" object="letterspacing_entry" swapped="false"/>
</object>
<object class="GtkAdjustment" id="line_height_adjustment">
<property name="lower">0.75</property>
<property name="upper">2.5</property>
<property name="value">1.0</property>
<property name="step_increment">0.1</property>
<property name="page_increment">1</property>
<signal name="value-changed" handler="basic_value_changed" object="line_height_entry" swapped="false"/>
</object>
<object class="GtkWindow" id="window">
<property name="default-width">600</property>
<property name="default-height">500</property>
<property name="title">Font Explorer</property>
<child type="titlebar">
<object class="GtkHeaderBar">
<child>
<object class="GtkButton" id="reset">
<property name="receives-default">1</property>
<property name="tooltip-text">Reset</property>
<property name="icon-name">view-refresh-symbolic</property>
<signal name="clicked" handler="font_features_reset_basic" swapped="no"/>
<signal name="clicked" handler="font_features_reset_features" swapped="no"/>
<signal name="clicked" handler="font_features_reset_variations" swapped="no"/>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox">
<child>
<object class="GtkScrolledWindow">
<property name="hscrollbar-policy">never</property>
<child>
<object class="GtkViewport">
<child>
<object class="GtkBox">
<property name="margin-start">10</property>
<property name="margin-end">10</property>
<property name="margin-top">10</property>
<property name="margin-bottom">10</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
<object class="GtkFontButton" id="font">
<property name="receives-default">1</property>
<property name="font">Sans 12</property>
<property name="level">family|style</property>
<signal name="font-set" handler="font_features_font_changed" swapped="no"/>
</object>
</child>
<child>
<object class="GtkGrid">
<property name="column-spacing">10</property>
<property name="row-spacing">10</property>
<child>
<object class="GtkLabel">
<property name="label">Size</property>
<property name="xalign">0</property>
<property name="valign">baseline</property>
<layout>
<property name="column">0</property>
<property name="row">0</property>
</layout>
</object>
</child>
<child>
<object class="GtkScale" id="size_scale">
<property name="hexpand">1</property>
<property name="width-request">100</property>
<property name="valign">baseline</property>
<property name="adjustment">size_adjustment</property>
<layout>
<property name="column">1</property>
<property name="row">0</property>
</layout>
</object>
</child>
<child>
<object class="GtkEntry" id="size_entry">
<property name="width-chars">4</property>
<property name="max-width-chars">4</property>
<property name="hexpand">0</property>
<property name="valign">baseline</property>
<signal name="activate" handler="basic_entry_activated"
object="size_adjustment" swapped="false"/>
<layout>
<property name="column">2</property>
<property name="row">0</property>
</layout>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label">Letterspacing</property>
<property name="xalign">0</property>
<property name="valign">baseline</property>
<layout>
<property name="column">0</property>
<property name="row">1</property>
</layout>
</object>
</child>
<child>
<object class="GtkScale">
<property name="hexpand">1</property>
<property name="width-request">100</property>
<property name="valign">baseline</property>
<property name="adjustment">letterspacing_adjustment</property>
<layout>
<property name="column">1</property>
<property name="row">1</property>
</layout>
</object>
</child>
<child>
<object class="GtkEntry" id="letterspacing_entry">
<property name="width-chars">4</property>
<property name="max-width-chars">4</property>
<property name="hexpand">0</property>
<property name="valign">baseline</property>
<signal name="activate" handler="basic_entry_activated"
object="letterspacing_adjustment" swapped="false"/>
<layout>
<property name="column">2</property>
<property name="row">1</property>
</layout>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label">Line Height</property>
<property name="xalign">0</property>
<property name="valign">baseline</property>
<layout>
<property name="column">0</property>
<property name="row">2</property>
</layout>
</object>
</child>
<child>
<object class="GtkScale">
<property name="hexpand">1</property>
<property name="width-request">100</property>
<property name="valign">baseline</property>
<property name="adjustment">line_height_adjustment</property>
<layout>
<property name="column">1</property>
<property name="row">2</property>
</layout>
</object>
</child>
<child>
<object class="GtkEntry" id="line_height_entry">
<property name="width-chars">4</property>
<property name="max-width-chars">4</property>
<property name="hexpand">0</property>
<property name="valign">baseline</property>
<signal name="activate" handler="basic_entry_activated"
object="line_height_adjustment" swapped="false"/>
<layout>
<property name="column">2</property>
<property name="row">2</property>
</layout>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label">Foreground</property>
<property name="xalign">0</property>
<property name="valign">baseline</property>
<layout>
<property name="column">0</property>
<property name="row">3</property>
</layout>
</object>
</child>
<child>
<object class="GtkColorButton" id="foreground">
<property name="valign">baseline</property>
<property name="rgba">black</property>
<signal name="notify::rgba" handler="color_set_cb"/>
<layout>
<property name="column">1</property>
<property name="row">3</property>
</layout>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label">Background</property>
<property name="xalign">0</property>
<property name="valign">baseline</property>
<layout>
<property name="column">0</property>
<property name="row">4</property>
</layout>
</object>
</child>
<child>
<object class="GtkColorButton" id="background">
<property name="valign">baseline</property>
<property name="rgba">white</property>
<signal name="notify::rgba" handler="color_set_cb"/>
<layout>
<property name="column">1</property>
<property name="row">4</property>
</layout>
</object>
</child>
<child>
<object class="GtkButton">
<property name="icon-name">object-flip-vertical-symbolic</property>
<property name="halign">start</property>
<property name="valign">center</property>
<style>
<class name="circular"/>
</style>
<signal name="clicked" handler="swap_colors"/>
<layout>
<property name="column">2</property>
<property name="row">3</property>
<property name="row-span">2</property>
</layout>
</object>
</child>
</object>
</child>
<child>
<object class="GtkExpander">
<child type="label">
<object class="GtkLabel">
<property name="xalign">0</property>
<property name="label" translatable="yes">OpenType Features</property>
<property name="margin-top">10</property>
<property name="margin-bottom">10</property>
<style>
<class name="title-4"/>
</style>
</object>
</child>
<child>
<object class="GtkBox" id="feature_list">
<property name="orientation">vertical</property>
<child>
<object class="GtkComboBox" id="script_lang">
<property name="tooltip-text" translatable="yes">Language System</property>
<property name="margin-top">10</property>
<signal name="changed" handler="font_features_script_changed" swapped="no"/>
<child>
<object class="GtkCellRendererText"/>
<attributes>
<attribute name="text">0</attribute>
</attributes>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkExpander">
<child type="label">
<object class="GtkLabel" id="variations_heading">
<property name="label" translatable="yes">Variation Axes</property>
<property name="xalign">0</property>
<property name="margin-top">10</property>
<property name="margin-bottom">10</property>
<style>
<class name="title-4"/>
</style>
</object>
</child>
<child>
<object class="GtkGrid" id="variations_grid">
<property name="column-spacing">10</property>
<property name="row-spacing">10</property>
</object>
</child>
</object>
</child>
</object>
</child>
<style>
<class name="view"/>
</style>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<property name="hexpand">1</property>
<property name="vexpand">1</property>
<property name="margin-start">20</property>
<property name="margin-end">20</property>
<property name="margin-top">20</property>
<property name="margin-bottom">20</property>
<property name="spacing">20</property>
<child>
<object class="GtkScrolledWindow" id="swin">
<property name="hscrollbar-policy">automatic</property>
<property name="vscrollbar-policy">automatic</property>
<property name="propagate-natural-height">1</property>
<property name="vexpand">1</property>
<style>
<class name="font_features_background"/>
</style>
<child>
<object class="GtkStack" id="stack">
<child>
<object class="GtkStackPage">
<property name="name">label</property>
<property name="child">
<object class="GtkLabel" id="label">
<property name="wrap">1</property>
<property name="xalign">0</property>
<property name="yalign">0</property>
<property name="valign">start</property>
<property name="selectable">1</property>
</object>
</property>
</object>
</child>
<child>
<object class="GtkStackPage">
<property name="name">entry</property>
<property name="child">
<object class="GtkTextView" id="entry">
<property name="buffer">
<object class="GtkTextBuffer">
<property name="text">Grumpy wizards make toxic brew for the evil Queen and Jack. A quick movement of the enemy will jeopardize six gunboats. The job of waxing linoleum frequently peeves chintzy kids. My girl wove six dozen plaid jackets before she quit. Twelve ziggurats quickly jumped a finch box.
Разъяренный чтец эгоистично бьёт пятью жердями шустрого фехтовальщика. Наш банк вчера же выплатил Ф.Я. Эйхгольду комиссию за ценные вещи. Эх, чужак, общий съём цен шляп (юфть) – вдрызг! В чащах юга жил бы цитрус? Да, но фальшивый экземпляр!
Τάχιστη αλώπηξ βαφής ψημένη γη, δρασκελίζει υπέρ νωθρού κυνός</property>
</object>
</property>
<property name="valign">fill</property>
</object>
</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox">
<property name="spacing">10</property>
<child>
<object class="GtkLabel" id="settings">
<property name="wrap">1</property>
<property name="xalign">0</property>
<property name="valign">end</property>
<property name="width-chars">50</property>
<property name="max-width-chars">50</property>
<property name="hexpand">1</property>
<style>
<class name="monospace"/>
</style>
</object>
</child>
<child>
<object class="GtkButton">
<property name="label" translatable="yes">Alphabet</property>
<signal name="clicked" handler="set_text_alphabet"/>
</object>
</child>
<child>
<object class="GtkButton">
<property name="label" translatable="yes">Paragraph</property>
<signal name="clicked" handler="set_text_paragraph"/>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox">
<property name="spacing">10</property>
<child>
<object class="GtkLabel" id="description">
<property name="wrap">1</property>
<property name="wrap-mode">char</property>
<property name="xalign">0</property>
<property name="valign">end</property>
<property name="width-chars">50</property>
<property name="max-width-chars">50</property>
<property name="hexpand">1</property>
<style>
<class name="monospace"/>
</style>
</object>
</child>
<child>
<object class="GtkBox">
<style>
<class name="linked"/>
</style>
<property name="valign">end</property>
<child>
<object class="GtkToggleButton" id="plain_toggle">
<property name="label" translatable="yes">Plain</property>
<property name="active">1</property>
<property name="valign">baseline</property>
<signal name="toggled" handler="font_features_toggle_plain"/>
</object>
</child>
<child>
<object class="GtkToggleButton" id="waterfall_toggle">
<property name="label" translatable="yes">Waterfall</property>
<property name="valign">baseline</property>
<property name="group">plain_toggle</property>
<signal name="toggled" handler="font_features_toggle_plain"/>
<signal name="notify::active" handler="font_features_notify_waterfall"/>
</object>
</child>
</object>
</child>
<child>
<object class="GtkToggleButton" id="edit_toggle">
<property name="group">waterfall_toggle</property>
<property name="icon-name">document-edit-symbolic</property>
<property name="halign">end</property>
<property name="valign">end</property>
<signal name="clicked" handler="font_features_toggle_edit"/>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</interface>
+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");
+1 -2
View File
@@ -42,8 +42,7 @@ do_listbox_controls (GtkWidget *do_widget)
GtkBuilder *builder;
scope = gtk_builder_cscope_new ();
gtk_builder_cscope_add_callback_symbol (GTK_BUILDER_CSCOPE (scope),
"row_activated", G_CALLBACK (row_activated));
gtk_builder_cscope_add_callback (scope, row_activated);
builder = gtk_builder_new ();
gtk_builder_set_scope (builder, scope);
+4 -4
View File
@@ -356,10 +356,10 @@ do_listview_settings (GtkWidget *do_widget)
g_type_ensure (SETTINGS_TYPE_KEY);
scope = gtk_builder_cscope_new ();
gtk_builder_cscope_add_callback_symbol (GTK_BUILDER_CSCOPE (scope), "search_enabled", (GCallback)search_enabled);
gtk_builder_cscope_add_callback_symbol (GTK_BUILDER_CSCOPE (scope), "search_changed", (GCallback)search_changed);
gtk_builder_cscope_add_callback_symbol (GTK_BUILDER_CSCOPE (scope), "stop_search", (GCallback)stop_search);
gtk_builder_cscope_add_callback_symbol (GTK_BUILDER_CSCOPE (scope), "item_value_changed", (GCallback)item_value_changed);
gtk_builder_cscope_add_callback (scope, search_enabled);
gtk_builder_cscope_add_callback (scope, search_changed);
gtk_builder_cscope_add_callback (scope, stop_search);
gtk_builder_cscope_add_callback (scope, item_value_changed);
builder = gtk_builder_new ();
gtk_builder_set_scope (builder, scope);
+3 -4
View File
@@ -1,5 +1,5 @@
/* Lists/Words
* #Keywords: GtkListView, GtkFilterListModel
* #Keywords: GtkListView, GtkFilterListModel, GtkInscription
*
* This demo shows filtering a long list - of words.
*
@@ -17,10 +17,9 @@ const char *factory_text =
"<interface>\n"
" <template class='GtkListItem'>\n"
" <property name='child'>\n"
" <object class='GtkLabel'>\n"
" <property name='ellipsize'>end</property>\n"
" <object class='GtkInscription'>\n"
" <property name='xalign'>0</property>\n"
" <binding name='label'>\n"
" <binding name='text'>\n"
" <lookup name='string' type='GtkStringObject'>\n"
" <lookup name='item'>GtkListItem</lookup>\n"
" </lookup>\n"
+3 -3
View File
@@ -7,9 +7,9 @@
<lookup name="item">GtkListItem</lookup>
</binding>
<property name="child">
<object class="GtkLabel">
<property name="halign">start</property>
<binding name="label">
<object class="GtkInscription">
<property name="hexpand">1</property>
<binding name="text">
<lookup name="title" type="GtkDemo">
<lookup name="item">expander</lookup>
</lookup>
+1
View File
@@ -73,6 +73,7 @@ demos = files([
'peg_solitaire.c',
'pickers.c',
'printing.c',
'read_more.c',
'revealer.c',
'rotated_text.c',
'scale.c',
+1 -1
View File
@@ -2,7 +2,7 @@
* #Keywords: GtkColorChooser, GtkFontChooser, GtkApplicationChooser
*
* These widgets are mainly intended for use in preference dialogs.
* They allow to select colors, fonts, directories and applications.
* They allow to select colors, fonts and applications.
*
* This demo shows both the default appearance for these dialogs,
* as well as some of the customizations that are possible.
+239
View File
@@ -0,0 +1,239 @@
/* Read More
* #Keywords: GtkInscription
*
* A simple implementation of a widget that can either
* display a lot of text or just the first few lines with a
* "Read More" button.
*/
#include <gtk/gtk.h>
#define READ_TYPE_MORE (read_more_get_type ())
G_DECLARE_FINAL_TYPE(ReadMore, read_more, READ, MORE, GtkWidget)
struct _ReadMore {
GtkWidget parent_instance;
GtkWidget *label;
GtkWidget *inscription;
GtkWidget *box;
gboolean show_more;
};
G_DEFINE_TYPE (ReadMore, read_more, GTK_TYPE_WIDGET)
static GtkSizeRequestMode
read_more_get_request_mode (GtkWidget *widget)
{
return GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH;
}
static void
read_more_measure (GtkWidget *widget,
GtkOrientation orientation,
int for_size,
int *minimum,
int *natural,
int *minimum_baseline,
int *natural_baseline)
{
ReadMore *self = READ_MORE (widget);
int label_min, label_nat, label_min_baseline, label_nat_baseline;
int box_min, box_nat, box_min_baseline, box_nat_baseline;
int min_check;
if (self->show_more)
min_check = G_MAXINT;
else if (for_size >= 0)
gtk_widget_measure (self->box, 1 - orientation, -1, &min_check, NULL, NULL, NULL);
else
min_check = -1;
if (min_check > for_size)
{
gtk_widget_measure (self->label,
orientation,
for_size,
minimum, natural,
minimum_baseline, natural_baseline);
return;
}
else if (for_size >= 0)
gtk_widget_measure (self->label, 1 - orientation, -1, &min_check, NULL, NULL, NULL);
else
min_check = -1;
if (min_check > for_size)
{
gtk_widget_measure (self->box,
orientation,
for_size,
minimum, natural,
minimum_baseline, natural_baseline);
return;
}
gtk_widget_measure (self->label,
orientation,
for_size,
&label_min, &label_nat,
&label_min_baseline, &label_nat_baseline);
gtk_widget_measure (self->box,
orientation,
for_size,
&box_min, &box_nat,
&box_min_baseline, &box_nat_baseline);
*minimum = MIN (label_min, box_min);
*natural = MIN (label_nat, box_nat);
/* FIXME: Figure out baselines! */
}
static void
read_more_allocate (GtkWidget *widget,
int width,
int height,
int baseline)
{
ReadMore *self = READ_MORE (widget);
gboolean show_more;
if (self->show_more)
{
show_more = TRUE;
}
else
{
int needed;
/* check to see if we have enough space to show all text */
gtk_widget_measure (self->label,
GTK_ORIENTATION_VERTICAL,
width,
&needed, NULL, NULL, NULL);
show_more = needed <= height;
}
gtk_widget_set_child_visible (self->label, show_more);
gtk_widget_set_child_visible (self->box, !show_more);
if (show_more)
gtk_widget_size_allocate (self->label, &(GtkAllocation) { 0, 0, width, height }, baseline);
else
gtk_widget_size_allocate (self->box, &(GtkAllocation) { 0, 0, width, height }, baseline);
}
static void
read_more_dispose (GObject *object)
{
ReadMore *self = READ_MORE (object);
g_clear_pointer (&self->label, gtk_widget_unparent);
g_clear_pointer (&self->box, gtk_widget_unparent);
G_OBJECT_CLASS (read_more_parent_class)->dispose (object);
}
static void
read_more_class_init (ReadMoreClass *klass)
{
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
GObjectClass *object_class = G_OBJECT_CLASS (klass);
widget_class->get_request_mode = read_more_get_request_mode;
widget_class->measure = read_more_measure;
widget_class->size_allocate = read_more_allocate;
object_class->dispose = read_more_dispose;
}
static void
read_more_clicked (GtkButton *button,
ReadMore *self)
{
self->show_more = TRUE;
gtk_widget_queue_resize (GTK_WIDGET (self));
}
static void
read_more_init (ReadMore *self)
{
GtkWidget *button;
self->label = gtk_label_new (NULL);
gtk_label_set_xalign (GTK_LABEL (self->label), 0.0);
gtk_label_set_yalign (GTK_LABEL (self->label), 0.0);
gtk_label_set_wrap (GTK_LABEL (self->label), TRUE);
gtk_label_set_width_chars (GTK_LABEL (self->label), 3);
gtk_label_set_max_width_chars (GTK_LABEL (self->label), 30);
gtk_widget_set_parent (self->label, GTK_WIDGET (self));
self->box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_widget_set_vexpand (self->box, FALSE);
gtk_widget_set_parent (self->box, GTK_WIDGET (self));
self->inscription = gtk_inscription_new (NULL);
gtk_inscription_set_xalign (GTK_INSCRIPTION (self->inscription), 0.0);
gtk_inscription_set_yalign (GTK_INSCRIPTION (self->inscription), 0.0);
gtk_inscription_set_min_lines (GTK_INSCRIPTION (self->inscription), 3);
gtk_inscription_set_nat_chars (GTK_INSCRIPTION (self->inscription), 30);
gtk_widget_set_vexpand (self->inscription, TRUE);
gtk_box_append (GTK_BOX (self->box), self->inscription);
button = gtk_button_new_with_label ("Read More");
g_signal_connect (button, "clicked", G_CALLBACK (read_more_clicked), self);
gtk_box_append (GTK_BOX (self->box), button);
}
static void
read_more_set_text (ReadMore *self,
const char *text)
{
gtk_label_set_label (GTK_LABEL (self->label), text);
gtk_inscription_set_text (GTK_INSCRIPTION (self->inscription), text);
}
static GtkWidget *
read_more_new (const char *text)
{
ReadMore *self = g_object_new (READ_TYPE_MORE, NULL);
read_more_set_text (self, text);
return GTK_WIDGET (self);
}
GtkWidget *
do_read_more (GtkWidget *do_widget)
{
static GtkWidget *window = NULL;
if (!window)
{
GtkWidget *readmore;
window = gtk_window_new ();
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));
gtk_window_set_title (GTK_WINDOW (window), "Read More");
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
readmore = read_more_new (
"I'd just like to interject for a moment. What you're referring to as Linux, is in fact, GNU/Linux, or as I've recently taken to calling it, GNU plus Linux. Linux is not an operating system unto itself, but rather another free component of a fully functioning GNU system made useful by the GNU corelibs, shell utilities and vital system components comprising a full OS as defined by POSIX.\n"
"\n"
"Many computer users run a modified version of the GNU system every day, without realizing it. Through a peculiar turn of events, the version of GNU which is widely used today is often called \"Linux\", and many of its users are not aware that it is basically the GNU system, developed by the GNU Project.\n"
"\n"
"There really is a Linux, and these people are using it, but it is just a part of the system they use. Linux is the kernel: the program in the system that allocates the machine's resources to the other programs that you run. The kernel is an essential part of an operating system, but useless by itself; it can only function in the context of a complete operating system. Linux is normally used in combination with the GNU operating system: the whole system is basically GNU with Linux added, or GNU/Linux. All the so-called \"Linux\" distributions are really distributions of GNU/Linux.");
gtk_window_set_child (GTK_WINDOW (window), readmore);
}
if (!gtk_widget_get_visible (window))
gtk_widget_show (window);
else
gtk_window_destroy (GTK_WINDOW (window));
return window;
}
+3 -4
View File
@@ -137,7 +137,7 @@ insert_text (GtkTextView *view)
icon_theme = gtk_icon_theme_get_for_display (gtk_widget_get_display (widget));
icon = gtk_icon_theme_lookup_icon (icon_theme,
"face-cool",
"drive-harddisk",
NULL,
32, 1,
gtk_widget_get_direction (widget),
@@ -239,8 +239,6 @@ insert_text (GtkTextView *view)
gtk_text_buffer_insert (buffer, &iter, "The buffer can have images in it: ", -1);
gtk_text_buffer_insert_paintable (buffer, &iter, GDK_PAINTABLE (icon));
gtk_text_buffer_insert_paintable (buffer, &iter, GDK_PAINTABLE (icon));
gtk_text_buffer_insert_paintable (buffer, &iter, nuclear);
gtk_text_buffer_insert (buffer, &iter, " for example.\n\n", -1);
@@ -441,11 +439,12 @@ attach_widgets (GtkTextView *text_view)
{
widget = gtk_scale_new (GTK_ORIENTATION_HORIZONTAL, NULL);
gtk_range_set_range (GTK_RANGE (widget), 0, 100);
gtk_widget_set_size_request (widget, 70, -1);
gtk_widget_set_size_request (widget, 100, -1);
}
else if (i == 3)
{
widget = gtk_entry_new ();
gtk_editable_set_width_chars (GTK_EDITABLE (widget), 10);
}
else
{
+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,
+18 -20
View File
@@ -2081,26 +2081,24 @@ activate (GApplication *app)
builder = gtk_builder_new ();
scope = gtk_builder_cscope_new ();
gtk_builder_cscope_add_callback_symbols (GTK_BUILDER_CSCOPE (scope),
"on_entry_icon_release", (GCallback)on_entry_icon_release,
"on_scale_button_value_changed", (GCallback)on_scale_button_value_changed,
"on_record_button_toggled", (GCallback)on_record_button_toggled,
"on_page_combo_changed", (GCallback)on_page_combo_changed,
"on_range_from_changed", (GCallback)on_range_from_changed,
"on_range_to_changed", (GCallback)on_range_to_changed,
"on_picture_drag_prepare", (GCallback)on_picture_drag_prepare,
"on_picture_drop", (GCallback)on_picture_drop,
"tab_close_cb", (GCallback)tab_close_cb,
"increase_icon_size", (GCallback)increase_icon_size,
"decrease_icon_size", (GCallback)decrease_icon_size,
"reset_icon_size", (GCallback)reset_icon_size,
"osd_frame_pressed", (GCallback)osd_frame_pressed,
"age_entry_changed", (GCallback)age_entry_changed,
"validate_more_details", (GCallback)validate_more_details,
"mode_switch_state_set", (GCallback)mode_switch_state_set,
"level_scale_value_changed", (GCallback)level_scale_value_changed,
"transition_speed_changed", (GCallback)transition_speed_changed,
NULL);
gtk_builder_cscope_add_callback (scope, on_entry_icon_release);
gtk_builder_cscope_add_callback (scope, on_scale_button_value_changed);
gtk_builder_cscope_add_callback (scope, on_record_button_toggled);
gtk_builder_cscope_add_callback (scope, on_page_combo_changed);
gtk_builder_cscope_add_callback (scope, on_range_from_changed);
gtk_builder_cscope_add_callback (scope, on_range_to_changed);
gtk_builder_cscope_add_callback (scope, on_picture_drag_prepare);
gtk_builder_cscope_add_callback (scope, on_picture_drop);
gtk_builder_cscope_add_callback (scope, tab_close_cb);
gtk_builder_cscope_add_callback (scope, increase_icon_size);
gtk_builder_cscope_add_callback (scope, decrease_icon_size);
gtk_builder_cscope_add_callback (scope, osd_frame_pressed);
gtk_builder_cscope_add_callback (scope, age_entry_changed);
gtk_builder_cscope_add_callback (scope, validate_more_details);
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))
+6 -13
View File
@@ -117,6 +117,7 @@ static const GdkDebugKey gdk_debug_keys[] = {
{ "selection", GDK_DEBUG_SELECTION, "Information about selections" },
{ "clipboard", GDK_DEBUG_CLIPBOARD, "Information about clipboards" },
{ "nograbs", GDK_DEBUG_NOGRABS, "Disable pointer and keyboard grabs (X11)" },
{ "portals", GDK_DEBUG_PORTALS, "Force the use of portals" },
{ "gl-disable", GDK_DEBUG_GL_DISABLE, "Disable OpenGL support" },
{ "gl-software", GDK_DEBUG_GL_SOFTWARE, "Force OpenGL software rendering" },
{ "gl-texture-rect", GDK_DEBUG_GL_TEXTURE_RECT, "Use OpenGL texture rectangle extension" },
@@ -360,21 +361,13 @@ gdk_running_in_sandbox (void)
gboolean
gdk_should_use_portal (void)
{
static const char *use_portal = NULL;
if (GDK_DISPLAY_DEBUG_CHECK (NULL, PORTALS))
return TRUE;
if (G_UNLIKELY (use_portal == NULL))
{
if (gdk_running_in_sandbox ())
use_portal = "1";
else
{
use_portal = g_getenv ("GTK_USE_PORTAL");
if (!use_portal)
use_portal = "";
}
}
if (gdk_running_in_sandbox ())
return TRUE;
return use_portal[0] == '1';
return FALSE;
}
PangoDirection
+14 -13
View File
@@ -38,19 +38,20 @@ typedef enum {
GDK_DEBUG_CLIPBOARD = 1 << 10,
/* flags below are influencing behavior */
GDK_DEBUG_NOGRABS = 1 << 11,
GDK_DEBUG_GL_DISABLE = 1 << 12,
GDK_DEBUG_GL_SOFTWARE = 1 << 13,
GDK_DEBUG_GL_TEXTURE_RECT = 1 << 14,
GDK_DEBUG_GL_LEGACY = 1 << 15,
GDK_DEBUG_GL_GLES = 1 << 16,
GDK_DEBUG_GL_DEBUG = 1 << 17,
GDK_DEBUG_GL_EGL = 1 << 18,
GDK_DEBUG_GL_GLX = 1 << 19,
GDK_DEBUG_GL_WGL = 1 << 20,
GDK_DEBUG_VULKAN_DISABLE = 1 << 21,
GDK_DEBUG_VULKAN_VALIDATE = 1 << 22,
GDK_DEBUG_DEFAULT_SETTINGS= 1 << 23,
GDK_DEBUG_HIGH_DEPTH = 1 << 24,
GDK_DEBUG_PORTALS = 1 << 12,
GDK_DEBUG_GL_DISABLE = 1 << 13,
GDK_DEBUG_GL_SOFTWARE = 1 << 14,
GDK_DEBUG_GL_TEXTURE_RECT = 1 << 15,
GDK_DEBUG_GL_LEGACY = 1 << 16,
GDK_DEBUG_GL_GLES = 1 << 17,
GDK_DEBUG_GL_DEBUG = 1 << 18,
GDK_DEBUG_GL_EGL = 1 << 19,
GDK_DEBUG_GL_GLX = 1 << 20,
GDK_DEBUG_GL_WGL = 1 << 21,
GDK_DEBUG_VULKAN_DISABLE = 1 << 22,
GDK_DEBUG_VULKAN_VALIDATE = 1 << 23,
GDK_DEBUG_DEFAULT_SETTINGS= 1 << 24,
GDK_DEBUG_HIGH_DEPTH = 1 << 25,
} GdkDebugFlags;
extern guint _gdk_debug_flags;
+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;
}
+2 -3
View File
@@ -623,7 +623,7 @@ _gdk_wayland_display_open (const char *display_name)
wl_registry_bind (display_wayland->wl_registry,
display_wayland->xdg_wm_base_id,
&xdg_wm_base_interface,
MIN (display_wayland->xdg_wm_base_version, 3));
MIN (display_wayland->xdg_wm_base_version, 4));
xdg_wm_base_add_listener (display_wayland->xdg_wm_base,
&xdg_wm_base_listener,
display_wayland);
@@ -2169,8 +2169,7 @@ gdk_wayland_display_get_setting (GdkDisplay *display,
{
if (strcmp (name, "gtk-decoration-layout") == 0)
set_decoration_layout_from_entry (display, entry, value);
else if (strcmp (name, "gtk-theme-name") == 0 ||
strcmp (name, "gtk-icon-theme-name") == 0)
else if (strcmp (name, "gtk-theme-name") == 0)
set_theme_from_entry (display, entry, value);
else
set_value_from_entry (display, entry, value);
+46 -7
View File
@@ -168,6 +168,10 @@ struct _GdkWaylandSurface
struct {
GdkToplevelLayout *layout;
int bounds_width;
int bounds_height;
gboolean has_bounds;
} toplevel;
struct {
@@ -182,6 +186,10 @@ struct _GdkWaylandSurface
int height;
GdkToplevelState state;
gboolean is_resizing;
int bounds_width;
int bounds_height;
gboolean has_bounds;
} toplevel;
struct {
@@ -1394,19 +1402,28 @@ configure_toplevel_geometry (GdkSurface *surface)
{
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
GdkDisplay *display = gdk_surface_get_display (surface);
GdkMonitor *monitor;
GdkRectangle monitor_geometry;
int bounds_width, bounds_height;
GdkToplevelSize size;
GdkToplevelLayout *layout;
GdkGeometry geometry;
GdkSurfaceHints mask;
monitor = g_list_model_get_item (gdk_display_get_monitors (display), 0);
gdk_monitor_get_geometry (monitor, &monitor_geometry);
g_object_unref (monitor);
bounds_width = monitor_geometry.width;
bounds_height = monitor_geometry.height;
if (impl->toplevel.has_bounds)
{
bounds_width = impl->toplevel.bounds_width;
bounds_height = impl->toplevel.bounds_height;
}
else
{
GdkMonitor *monitor;
GdkRectangle monitor_geometry;
monitor = g_list_model_get_item (gdk_display_get_monitors (display), 0);
gdk_monitor_get_geometry (monitor, &monitor_geometry);
bounds_width = monitor_geometry.width;
bounds_height = monitor_geometry.height;
g_object_unref (monitor);
}
gdk_toplevel_size_init (&size, bounds_width, bounds_height);
gdk_toplevel_notify_compute_size (GDK_TOPLEVEL (surface), &size);
@@ -1508,6 +1525,13 @@ gdk_wayland_surface_configure_toplevel (GdkSurface *surface)
is_resizing = impl->pending.toplevel.is_resizing;
impl->pending.toplevel.is_resizing = FALSE;
if (impl->pending.toplevel.has_bounds)
{
impl->toplevel.bounds_width = impl->pending.toplevel.bounds_width;
impl->toplevel.bounds_height = impl->pending.toplevel.bounds_height;
impl->toplevel.has_bounds = TRUE;
}
fixed_size =
new_state & (GDK_TOPLEVEL_STATE_MAXIMIZED |
GDK_TOPLEVEL_STATE_FULLSCREEN |
@@ -1847,9 +1871,24 @@ xdg_toplevel_close (void *data,
gdk_wayland_surface_handle_close (surface);
}
static void
xdg_toplevel_configure_bounds (void *data,
struct xdg_toplevel *xdg_toplevel,
int32_t width,
int32_t height)
{
GdkSurface *surface = GDK_SURFACE (data);
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
impl->pending.toplevel.bounds_width = width;
impl->pending.toplevel.bounds_height = height;
impl->pending.toplevel.has_bounds = TRUE;
}
static const struct xdg_toplevel_listener xdg_toplevel_listener = {
xdg_toplevel_configure,
xdg_toplevel_close,
xdg_toplevel_configure_bounds,
};
static void
+13
View File
@@ -220,6 +220,19 @@ _gdk_win32_get_setting (const char *name,
return TRUE;
}
else if (strcmp ("gtk-overlay-scrolling", name) == 0)
{
DWORD val = 0;
DWORD sz = sizeof (val);
LSTATUS ret = 0;
ret = RegGetValueW (HKEY_CURRENT_USER, L"Control Panel\\Accessibility", L"DynamicScrollbars", RRF_RT_DWORD, NULL, &val, &sz);
if (ret == ERROR_SUCCESS)
{
g_value_set_boolean (value, val != 0);
return TRUE;
}
}
return FALSE;
}
+9 -4
View File
@@ -2793,14 +2793,19 @@ gdk_x11_surface_get_frame_extents (GdkSurface *surface,
impl = GDK_X11_SURFACE (surface);
/* Refine our fallback answer a bit using local information */
rect->x = impl->abs_x * impl->surface_scale;
rect->y = impl->abs_y * impl->surface_scale;
rect->width = surface->width * impl->surface_scale;
rect->height = surface->height * impl->surface_scale;
rect->x = impl->abs_x;
rect->y = impl->abs_y;
rect->width = surface->width;
rect->height = surface->height;
if (GDK_SURFACE_DESTROYED (surface) || impl->override_redirect)
return;
rect->x *= impl->surface_scale;
rect->y *= impl->surface_scale;
rect->width *= impl->surface_scale;
rect->height *= impl->surface_scale;
nvroots = 0;
vroots = NULL;
+271
View File
@@ -32,6 +32,7 @@
#include "gtkatcontextprivate.h"
#include "gtkdebug.h"
#include "gtkeditable.h"
#include "gtkinscriptionprivate.h"
#include "gtklabelprivate.h"
#include "gtkentryprivate.h"
#include "gtksearchentryprivate.h"
@@ -406,6 +407,274 @@ static const GDBusInterfaceVTable label_vtable = {
NULL,
};
/* }}} */
/* {{{ GtkInscription */
static void
inscription_handle_method (GDBusConnection *connection,
const gchar *sender,
const gchar *object_path,
const gchar *interface_name,
const gchar *method_name,
GVariant *parameters,
GDBusMethodInvocation *invocation,
gpointer user_data)
{
GtkATContext *self = user_data;
GtkAccessible *accessible = gtk_at_context_get_accessible (self);
GtkWidget *widget = GTK_WIDGET (accessible);
if (g_strcmp0 (method_name, "GetCaretOffset") == 0)
{
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(i)", 0));
}
else if (g_strcmp0 (method_name, "SetCaretOffset") == 0)
{
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(b)", FALSE));
}
else if (g_strcmp0 (method_name, "GetText") == 0)
{
int start, end;
const char *text;
int len;
char *string;
g_variant_get (parameters, "(ii)", &start, &end);
text = gtk_inscription_get_text (GTK_INSCRIPTION (widget));
len = g_utf8_strlen (text, -1);
start = CLAMP (start, 0, len);
end = CLAMP (end, 0, len);
if (end <= start)
string = g_strdup ("");
else
{
const char *p, *q;
p = g_utf8_offset_to_pointer (text, start);
q = g_utf8_offset_to_pointer (text, end);
string = g_strndup (p, q - p);
}
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(s)", string));
g_free (string);
}
else if (g_strcmp0 (method_name, "GetTextBeforeOffset") == 0)
{
PangoLayout *layout = gtk_inscription_get_layout (GTK_INSCRIPTION (widget));;
int offset;
AtspiTextBoundaryType boundary_type;
char *string;
int start, end;
g_variant_get (parameters, "(iu)", &offset, &boundary_type);
string = gtk_pango_get_text_before (layout, offset, boundary_type, &start, &end);
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(sii)", string, start, end));
g_free (string);
}
else if (g_strcmp0 (method_name, "GetTextAtOffset") == 0)
{
PangoLayout *layout = gtk_inscription_get_layout (GTK_INSCRIPTION (widget));;
int offset;
AtspiTextBoundaryType boundary_type;
char *string;
int start, end;
g_variant_get (parameters, "(iu)", &offset, &boundary_type);
string = gtk_pango_get_text_at (layout, offset, boundary_type, &start, &end);
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(sii)", string, start, end));
g_free (string);
}
else if (g_strcmp0 (method_name, "GetTextAfterOffset") == 0)
{
PangoLayout *layout = gtk_inscription_get_layout (GTK_INSCRIPTION (widget));;
int offset;
AtspiTextBoundaryType boundary_type;
char *string;
int start, end;
g_variant_get (parameters, "(iu)", &offset, &boundary_type);
string = gtk_pango_get_text_after (layout, offset, boundary_type, &start, &end);
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(sii)", string, start, end));
g_free (string);
}
else if (g_strcmp0 (method_name, "GetCharacterAtOffset") == 0)
{
int offset;
const char *text;
gunichar ch = 0;
g_variant_get (parameters, "(i)", &offset);
text = gtk_inscription_get_text (GTK_INSCRIPTION (widget));
if (0 <= offset && offset < g_utf8_strlen (text, -1))
ch = g_utf8_get_char (g_utf8_offset_to_pointer (text, offset));
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(i)", ch));
}
else if (g_strcmp0 (method_name, "GetStringAtOffset") == 0)
{
PangoLayout *layout = gtk_inscription_get_layout (GTK_INSCRIPTION (widget));;
int offset;
AtspiTextGranularity granularity;
char *string;
int start, end;
g_variant_get (parameters, "(iu)", &offset, &granularity);
string = gtk_pango_get_string_at (layout, offset, granularity, &start, &end);
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(sii)", string, start, end));
g_free (string);
}
else if (g_strcmp0 (method_name, "GetAttributes") == 0)
{
PangoLayout *layout = gtk_inscription_get_layout (GTK_INSCRIPTION (widget));;
GVariantBuilder builder = G_VARIANT_BUILDER_INIT (G_VARIANT_TYPE ("a{ss}"));
int offset;
int start, end;
g_variant_get (parameters, "(i)", &offset);
gtk_pango_get_run_attributes (layout, &builder, offset, &start, &end);
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(a{ss}ii)", &builder, start, end));
}
else if (g_strcmp0 (method_name, "GetAttributeValue") == 0)
{
PangoLayout *layout = gtk_inscription_get_layout (GTK_INSCRIPTION (widget));;
GVariantBuilder builder = G_VARIANT_BUILDER_INIT (G_VARIANT_TYPE ("a{ss}"));
int offset;
const char *name;
int start, end;
GVariant *attrs;
const char *val;
g_variant_get (parameters, "(i&s)", &offset, &name);
gtk_pango_get_run_attributes (layout, &builder, offset, &start, &end);
attrs = g_variant_builder_end (&builder);
if (!g_variant_lookup (attrs, name, "&s", &val))
val = "";
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(s)", val));
g_variant_unref (attrs);
}
else if (g_strcmp0 (method_name, "GetAttributeRun") == 0)
{
PangoLayout *layout = gtk_inscription_get_layout (GTK_INSCRIPTION (widget));;
GVariantBuilder builder = G_VARIANT_BUILDER_INIT (G_VARIANT_TYPE ("a{ss}"));
int offset;
gboolean include_defaults;
int start, end;
g_variant_get (parameters, "(ib)", &offset, &include_defaults);
if (include_defaults)
gtk_pango_get_default_attributes (layout, &builder);
gtk_pango_get_run_attributes (layout, &builder, offset, &start, &end);
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(a{ss}ii)", &builder, start, end));
}
else if (g_strcmp0 (method_name, "GetDefaultAttributes") == 0 ||
g_strcmp0 (method_name, "GetDefaultAttributeSet") == 0)
{
PangoLayout *layout = gtk_inscription_get_layout (GTK_INSCRIPTION (widget));;
GVariantBuilder builder = G_VARIANT_BUILDER_INIT (G_VARIANT_TYPE ("a{ss}"));
gtk_pango_get_default_attributes (layout, &builder);
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(a{ss})", &builder));
}
else if (g_strcmp0 (method_name, "GetNSelections") == 0)
{
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(i)", 0));
}
else if (g_strcmp0 (method_name, "GetSelection") == 0)
{
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, "No selections available");
}
else if (g_strcmp0 (method_name, "AddSelection") == 0)
{
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(b)", FALSE));
}
else if (g_strcmp0 (method_name, "RemoveSelection") == 0)
{
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(b)", FALSE));
}
else if (g_strcmp0 (method_name, "SetSelection") == 0)
{
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(b)", FALSE));
}
else if (g_strcmp0 (method_name, "GetCharacterExtents") == 0)
{
g_dbus_method_invocation_return_error_literal (invocation, G_DBUS_ERROR, G_DBUS_ERROR_NOT_SUPPORTED, "");
}
else if (g_strcmp0 (method_name, "GetRangeExtents") == 0)
{
g_dbus_method_invocation_return_error_literal (invocation, G_DBUS_ERROR, G_DBUS_ERROR_NOT_SUPPORTED, "");
}
else if (g_strcmp0 (method_name, "GetBoundedRanges") == 0)
{
g_dbus_method_invocation_return_error_literal (invocation, G_DBUS_ERROR, G_DBUS_ERROR_NOT_SUPPORTED, "");
}
else if (g_strcmp0 (method_name, "ScrollSubstringTo") == 0)
{
g_dbus_method_invocation_return_error_literal (invocation, G_DBUS_ERROR, G_DBUS_ERROR_NOT_SUPPORTED, "");
}
else if (g_strcmp0 (method_name, "ScrollSubstringToPoint") == 0)
{
g_dbus_method_invocation_return_error_literal (invocation, G_DBUS_ERROR, G_DBUS_ERROR_NOT_SUPPORTED, "");
}
}
static GVariant *
inscription_get_property (GDBusConnection *connection,
const gchar *sender,
const gchar *object_path,
const gchar *interface_name,
const gchar *property_name,
GError **error,
gpointer user_data)
{
GtkATContext *self = user_data;
GtkAccessible *accessible = gtk_at_context_get_accessible (self);
GtkWidget *widget = GTK_WIDGET (accessible);
if (g_strcmp0 (property_name, "CharacterCount") == 0)
{
const char *text;
int len;
text = gtk_inscription_get_text (GTK_INSCRIPTION (widget));
len = g_utf8_strlen (text, -1);
return g_variant_new_int32 (len);
}
else if (g_strcmp0 (property_name, "CaretOffset") == 0)
{
return g_variant_new_int32 (0);
}
return NULL;
}
static const GDBusInterfaceVTable inscription_vtable = {
inscription_handle_method,
inscription_get_property,
NULL,
};
/* }}} */
/* {{{ GtkEditable */
@@ -1301,6 +1570,8 @@ gtk_atspi_get_text_vtable (GtkAccessible *accessible)
{
if (GTK_IS_LABEL (accessible))
return &label_vtable;
else if (GTK_IS_INSCRIPTION (accessible))
return &inscription_vtable;
else if (GTK_IS_EDITABLE (accessible) &&
GTK_IS_TEXT (gtk_editable_get_delegate (GTK_EDITABLE (accessible))))
return &editable_vtable;
+1
View File
@@ -155,6 +155,7 @@
#include <gtk/gtkimcontextsimple.h>
#include <gtk/gtkimmulticontext.h>
#include <gtk/gtkinfobar.h>
#include <gtk/gtkinscription.h>
#include <gtk/gtklabel.h>
#include <gtk/gtklayoutmanager.h>
#include <gtk/gtklayoutchild.h>
+7
View File
@@ -47,6 +47,13 @@
* the full width of the box, even if the children at either side take
* up different amounts of space.
*
* # GtkActionBar as GtkBuildable
*
* The `GtkActionBar` implementation of the `GtkBuildable` interface supports
* adding children at the start or end sides by specifying start or end as
* the type attribute of a `<child>` element, or setting the center widget
* by specifying center value.
*
* # CSS nodes
*
* ```
+78 -19
View File
@@ -158,6 +158,30 @@ struct _GtkAssistantClass
void (* cancel) (GtkAssistant *assistant);
};
#define GTK_TYPE_ASSISTANT_PAGES (gtk_assistant_pages_get_type ())
G_DECLARE_FINAL_TYPE (GtkAssistantPages, gtk_assistant_pages, GTK, ASSISTANT_PAGES, GObject)
struct _GtkAssistantPages
{
GObject parent_instance;
GtkAssistant *assistant;
};
struct _GtkAssistantPagesClass
{
GObjectClass parent_class;
};
enum {
PAGES_PROP_0,
PAGES_PROP_ITEM_TYPE,
PAGES_PROP_N_ITEMS,
PAGES_N_PROPS
};
static GParamSpec *pages_properties[PAGES_N_PROPS] = { NULL, };
static void gtk_assistant_dispose (GObject *object);
static void gtk_assistant_map (GtkWidget *widget);
static void gtk_assistant_unmap (GtkWidget *widget);
@@ -1289,8 +1313,11 @@ gtk_assistant_dispose (GObject *object)
{
GtkAssistant *assistant = GTK_ASSISTANT (object);
if (assistant->model)
g_list_model_items_changed (G_LIST_MODEL (assistant->model), 0, g_list_length (assistant->pages), 0);
if (assistant->model && g_list_length (assistant->pages))
{
g_list_model_items_changed (G_LIST_MODEL (assistant->model), 0, g_list_length (assistant->pages), 0);
g_object_notify_by_pspec (G_OBJECT (assistant->model), pages_properties[PAGES_PROP_N_ITEMS]);
}
/* We set current to NULL so that the remove code doesn't try
* to do anything funny
@@ -1733,7 +1760,10 @@ gtk_assistant_add_page (GtkAssistant *assistant,
}
if (assistant->model)
g_list_model_items_changed (assistant->model, position, 0, 1);
{
g_list_model_items_changed (assistant->model, position, 0, 1);
g_object_notify_by_pspec (G_OBJECT (assistant->model), pages_properties[PAGES_PROP_N_ITEMS]);
}
return position;
}
@@ -1759,7 +1789,10 @@ gtk_assistant_remove_page (GtkAssistant *assistant,
assistant_remove_page (assistant, page);
if (assistant->model)
g_list_model_items_changed (assistant->model, page_num, 1, 0);
{
g_list_model_items_changed (assistant->model, page_num, 1, 0);
g_object_notify_by_pspec (G_OBJECT (assistant->model), pages_properties[PAGES_PROP_N_ITEMS]);
}
}
/**
@@ -2184,20 +2217,6 @@ gtk_assistant_page_get_child (GtkAssistantPage *page)
return page->page;
}
#define GTK_TYPE_ASSISTANT_PAGES (gtk_assistant_pages_get_type ())
G_DECLARE_FINAL_TYPE (GtkAssistantPages, gtk_assistant_pages, GTK, ASSISTANT_PAGES, GObject)
struct _GtkAssistantPages
{
GObject parent_instance;
GtkAssistant *assistant;
};
struct _GtkAssistantPagesClass
{
GObjectClass parent_class;
};
static GType
gtk_assistant_pages_get_item_type (GListModel *model)
{
@@ -2231,17 +2250,57 @@ gtk_assistant_pages_list_model_init (GListModelInterface *iface)
iface->get_n_items = gtk_assistant_pages_get_n_items;
iface->get_item = gtk_assistant_pages_get_item;
}
G_DEFINE_TYPE_WITH_CODE (GtkAssistantPages, gtk_assistant_pages, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (G_TYPE_LIST_MODEL, gtk_assistant_pages_list_model_init))
static void
gtk_assistant_pages_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GtkAssistantPages *self = GTK_ASSISTANT_PAGES (object);
switch (prop_id)
{
case PAGES_PROP_ITEM_TYPE:
g_value_set_gtype (value, GTK_TYPE_ASSISTANT_PAGE);
break;
case PAGES_PROP_N_ITEMS:
g_value_set_uint (value, gtk_assistant_pages_get_n_items (G_LIST_MODEL (self)));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gtk_assistant_pages_init (GtkAssistantPages *pages)
{
}
static void
gtk_assistant_pages_class_init (GtkAssistantPagesClass *class)
gtk_assistant_pages_class_init (GtkAssistantPagesClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->get_property = gtk_assistant_pages_get_property;
pages_properties[PAGES_PROP_ITEM_TYPE] =
g_param_spec_gtype ("item-type", NULL, NULL,
GTK_TYPE_ASSISTANT_PAGE,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
pages_properties[PAGES_PROP_N_ITEMS] =
g_param_spec_uint ("n-items", NULL, NULL,
0, G_MAXUINT, 0,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (object_class, PAGES_N_PROPS, pages_properties);
}
static GtkAssistantPages *
+45 -8
View File
@@ -43,7 +43,10 @@ enum {
PROP_FILENAME,
PROP_ATTRIBUTES,
PROP_IO_PRIORITY,
PROP_ITEM_TYPE,
PROP_LOADING,
PROP_N_ITEMS,
NUM_PROPERTIES
};
@@ -149,10 +152,10 @@ gtk_bookmark_list_set_property (GObject *object,
}
static void
gtk_bookmark_list_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
gtk_bookmark_list_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GtkBookmarkList *self = GTK_BOOKMARK_LIST (object);
@@ -162,18 +165,26 @@ gtk_bookmark_list_get_property (GObject *object,
g_value_set_string (value, self->attributes);
break;
case PROP_IO_PRIORITY:
g_value_set_int (value, self->io_priority);
break;
case PROP_FILENAME:
g_value_set_string (value, self->filename);
break;
case PROP_IO_PRIORITY:
g_value_set_int (value, self->io_priority);
break;
case PROP_ITEM_TYPE:
g_value_set_gtype (value, G_TYPE_FILE_INFO);
break;
case PROP_LOADING:
g_value_set_boolean (value, gtk_bookmark_list_is_loading (self));
break;
case PROP_N_ITEMS:
g_value_set_uint (value, g_sequence_get_length (self->items));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -236,6 +247,18 @@ gtk_bookmark_list_class_init (GtkBookmarkListClass *class)
-G_MAXINT, G_MAXINT, G_PRIORITY_DEFAULT,
GTK_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
/**
* GtkBookmarkList:item-type:
*
* The type of items. See [method@Gio.ListModel.get_item_type].
*
* Since: 4.8
**/
properties[PROP_ITEM_TYPE] =
g_param_spec_gtype ("item-type", NULL, NULL,
G_TYPE_FILE_INFO,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
/**
* GtkBookmarkList:loading: (attributes org.gtk.Property.get=gtk_bookmark_list_is_loading)
*
@@ -246,6 +269,18 @@ gtk_bookmark_list_class_init (GtkBookmarkListClass *class)
FALSE,
GTK_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY);
/**
* GtkBookmarkList:n-items:
*
* The number of items. See [method@Gio.ListModel.get_n_items].
*
* Since: 4.8
**/
properties[PROP_N_ITEMS] =
g_param_spec_uint ("n-items", NULL, NULL,
0, G_MAXUINT, 0,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (gobject_class, NUM_PROPERTIES, properties);
}
@@ -306,6 +341,7 @@ got_file_info (GObject *source,
g_sequence_append (self->items, info);
g_list_model_items_changed (G_LIST_MODEL (self), g_sequence_get_length (self->items) - 1, 0, 1);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_N_ITEMS]);
g_free (uri);
}
@@ -331,6 +367,7 @@ gtk_bookmark_list_clear_items (GtkBookmarkList *self)
g_sequence_get_end_iter (self->items));
g_list_model_items_changed (G_LIST_MODEL (self), 0, n_items, 0);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_N_ITEMS]);
}
}
+7 -5
View File
@@ -85,22 +85,24 @@ static GParamSpec *properties[N_PROPS] = { NULL, };
static void
gtk_builder_list_item_factory_setup (GtkListItemFactory *factory,
GtkListItemWidget *widget,
GtkListItem *list_item)
GObject *item,
gboolean bind,
GFunc func,
gpointer data)
{
GtkBuilderListItemFactory *self = GTK_BUILDER_LIST_ITEM_FACTORY (factory);
GtkBuilder *builder;
GError *error = NULL;
GTK_LIST_ITEM_FACTORY_CLASS (gtk_builder_list_item_factory_parent_class)->setup (factory, widget, list_item);
GTK_LIST_ITEM_FACTORY_CLASS (gtk_builder_list_item_factory_parent_class)->setup (factory, item, bind, func, data);
builder = gtk_builder_new ();
gtk_builder_set_current_object (builder, G_OBJECT (list_item));
gtk_builder_set_current_object (builder, item);
if (self->scope)
gtk_builder_set_scope (builder, self->scope);
if (!gtk_builder_extend_with_template (builder, G_OBJECT (list_item), G_OBJECT_TYPE (list_item),
if (!gtk_builder_extend_with_template (builder, G_OBJECT (item), G_OBJECT_TYPE (item),
(const char *)g_bytes_get_data (self->data, NULL),
g_bytes_get_size (self->data),
&error))
+1 -1
View File
@@ -1495,7 +1495,7 @@ parse_signal (ParserData *data,
return;
}
if (!g_signal_parse_name (name, object_info->type, &id, &detail, FALSE))
if (!g_signal_parse_name (name, object_info->type, &id, &detail, TRUE))
{
g_set_error (error,
GTK_BUILDER_ERROR,
+13
View File
@@ -428,6 +428,19 @@ gtk_builder_cscope_new (void)
return g_object_new (GTK_TYPE_BUILDER_CSCOPE, NULL);
}
/**
* gtk_builder_cscope_add_callback:
* @self: a `GtkBuilderCScope`
* @callback_symbols: (scope async): The callback pointer
*
* Adds the @callback_symbol to the scope of @builder under its
* own name.
*
* This is a convenience wrapper of [method@Gtk.BuilderCScope.add_callback_symbol].
*
* Since: 4.8
*/
/**
* gtk_builder_cscope_add_callback_symbol:
* @self: a `GtkBuilderCScope`
+6 -2
View File
@@ -114,10 +114,14 @@ GDK_AVAILABLE_IN_ALL
void gtk_builder_cscope_add_callback_symbols (GtkBuilderCScope *self,
const char *first_callback_name,
GCallback first_callback_symbol,
...) G_GNUC_NULL_TERMINATED;
...) G_GNUC_NULL_TERMINATED;
#define gtk_builder_cscope_add_callback(scope, callback) \
gtk_builder_cscope_add_callback_symbol (GTK_BUILDER_CSCOPE (scope), #callback, G_CALLBACK (callback))
GDK_AVAILABLE_IN_ALL
GCallback gtk_builder_cscope_lookup_callback_symbol(GtkBuilderCScope *self,
const char *callback_name);
const char *callback_name);
G_END_DECLS
+25 -15
View File
@@ -43,10 +43,13 @@ G_DEFINE_TYPE (GtkColumnListItemFactory, gtk_column_list_item_factory, GTK_TYPE_
static void
gtk_column_list_item_factory_setup (GtkListItemFactory *factory,
GtkListItemWidget *widget,
GtkListItem *list_item)
GObject *item,
gboolean bind,
GFunc func,
gpointer data)
{
GtkColumnListItemFactory *self = GTK_COLUMN_LIST_ITEM_FACTORY (factory);
GtkListItemWidget *widget = data;
GListModel *columns;
guint i;
@@ -54,7 +57,7 @@ gtk_column_list_item_factory_setup (GtkListItemFactory *factory,
gtk_widget_set_layout_manager (GTK_WIDGET (widget),
gtk_column_view_layout_new (self->view));
GTK_LIST_ITEM_FACTORY_CLASS (gtk_column_list_item_factory_parent_class)->setup (factory, widget, list_item);
GTK_LIST_ITEM_FACTORY_CLASS (gtk_column_list_item_factory_parent_class)->setup (factory, item, bind, func, data);
columns = gtk_column_view_get_columns (self->view);
@@ -63,7 +66,7 @@ gtk_column_list_item_factory_setup (GtkListItemFactory *factory,
GtkColumnViewColumn *column = g_list_model_get_item (columns, i);
gtk_column_list_item_factory_add_column (self,
list_item->owner,
widget,
column,
FALSE);
@@ -73,12 +76,15 @@ gtk_column_list_item_factory_setup (GtkListItemFactory *factory,
static void
gtk_column_list_item_factory_teardown (GtkListItemFactory *factory,
GtkListItemWidget *widget,
GtkListItem *list_item)
GObject *item,
gboolean unbind,
GFunc func,
gpointer data)
{
GtkListItemWidget *widget = data;
GtkWidget *child;
GTK_LIST_ITEM_FACTORY_CLASS (gtk_column_list_item_factory_parent_class)->teardown (factory, widget, list_item);
GTK_LIST_ITEM_FACTORY_CLASS (gtk_column_list_item_factory_parent_class)->teardown (factory, item, unbind, func, data);
while ((child = gtk_widget_get_first_child (GTK_WIDGET (widget))))
{
@@ -88,21 +94,25 @@ gtk_column_list_item_factory_teardown (GtkListItemFactory *factory,
static void
gtk_column_list_item_factory_update (GtkListItemFactory *factory,
GtkListItemWidget *widget,
GtkListItem *list_item,
guint position,
gpointer item,
gboolean selected)
GObject *item,
gboolean unbind,
gboolean bind,
GFunc func,
gpointer data)
{
GtkListItem *list_item = GTK_LIST_ITEM (item);
GtkWidget *child;
GTK_LIST_ITEM_FACTORY_CLASS (gtk_column_list_item_factory_parent_class)->update (factory, widget, list_item, position, item, selected);
GTK_LIST_ITEM_FACTORY_CLASS (gtk_column_list_item_factory_parent_class)->update (factory, item, unbind, bind, func, data);
for (child = gtk_widget_get_first_child (GTK_WIDGET (widget));
for (child = gtk_widget_get_first_child (GTK_WIDGET (list_item->owner));
child;
child = gtk_widget_get_next_sibling (child))
{
gtk_list_item_widget_update (GTK_LIST_ITEM_WIDGET (child), position, item, selected);
gtk_list_item_widget_update (GTK_LIST_ITEM_WIDGET (child),
gtk_list_item_get_position (list_item),
gtk_list_item_get_item (list_item),
gtk_list_item_get_selected (list_item));
}
}
+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);
+42 -1
View File
@@ -60,8 +60,11 @@ enum {
PROP_ERROR,
PROP_FILE,
PROP_IO_PRIORITY,
PROP_ITEM_TYPE,
PROP_LOADING,
PROP_MONITORED,
PROP_N_ITEMS,
NUM_PROPERTIES
};
@@ -204,6 +207,10 @@ gtk_directory_list_get_property (GObject *object,
g_value_set_int (value, self->io_priority);
break;
case PROP_ITEM_TYPE:
g_value_set_gtype (value, G_TYPE_FILE_INFO);
break;
case PROP_LOADING:
g_value_set_boolean (value, gtk_directory_list_is_loading (self));
break;
@@ -212,6 +219,10 @@ gtk_directory_list_get_property (GObject *object,
g_value_set_boolean (value, gtk_directory_list_get_monitored (self));
break;
case PROP_N_ITEMS:
g_value_set_uint (value, g_sequence_get_length (self->items));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -312,6 +323,18 @@ gtk_directory_list_class_init (GtkDirectoryListClass *class)
-G_MAXINT, G_MAXINT, G_PRIORITY_DEFAULT,
GTK_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
/**
* GtkDirectoryList:item-type:
*
* The type of items. See [method@Gio.ListModel.get_item_type].
*
* Since: 4.8
**/
properties[PROP_ITEM_TYPE] =
g_param_spec_gtype ("item-type", NULL, NULL,
G_TYPE_FILE_INFO,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
/**
* GtkDirectoryList:loading: (attributes org.gtk.Property.get=gtk_directory_list_is_loading)
*
@@ -332,6 +355,18 @@ gtk_directory_list_class_init (GtkDirectoryListClass *class)
TRUE,
GTK_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
/**
* GtkDirectoryList:n-items:
*
* The number of items. See [method@Gio.ListModel.get_n_items].
*
* Since: 4.8
**/
properties[PROP_N_ITEMS] =
g_param_spec_uint ("n-items", NULL, NULL,
0, G_MAXUINT, 0,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (gobject_class, NUM_PROPERTIES, properties);
}
@@ -380,6 +415,7 @@ gtk_directory_list_clear_items (GtkDirectoryList *self)
g_sequence_get_end_iter (self->items));
g_list_model_items_changed (G_LIST_MODEL (self), 0, n_items, 0);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_N_ITEMS]);
}
if (self->error)
@@ -462,7 +498,10 @@ gtk_directory_list_got_files_cb (GObject *source,
self);
if (n > 0)
g_list_model_items_changed (G_LIST_MODEL (self), g_sequence_get_length (self->items) - n, 0, n);
{
g_list_model_items_changed (G_LIST_MODEL (self), g_sequence_get_length (self->items) - n, 0, n);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_N_ITEMS]);
}
}
static void
@@ -580,6 +619,7 @@ handle_event (QueuedEvent *event)
position = g_sequence_get_length (self->items);
g_sequence_append (self->items, g_object_ref (info));
g_list_model_items_changed (G_LIST_MODEL (self), position, 0, 1);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_N_ITEMS]);
}
break;
@@ -591,6 +631,7 @@ handle_event (QueuedEvent *event)
position = g_sequence_iter_get_position (iter);
g_sequence_remove (iter);
g_list_model_items_changed (G_LIST_MODEL (self), position, 1, 0);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_N_ITEMS]);
}
break;
+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 ();
}
+63 -6
View File
@@ -43,7 +43,9 @@ enum {
PROP_0,
PROP_FILTER,
PROP_INCREMENTAL,
PROP_ITEM_TYPE,
PROP_MODEL,
PROP_N_ITEMS,
PROP_PENDING,
NUM_PROPERTIES
};
@@ -206,14 +208,18 @@ gtk_filter_list_model_emit_items_changed_for_changes (GtkFilterListModel *self,
gtk_bitset_difference (changes, old);
if (!gtk_bitset_is_empty (changes))
{
guint min, max;
guint min, max, removed, added;
min = gtk_bitset_get_minimum (changes);
max = gtk_bitset_get_maximum (changes);
removed = gtk_bitset_get_size_in_range (old, min, max);
added = gtk_bitset_get_size_in_range (self->matches, min, max);
g_list_model_items_changed (G_LIST_MODEL (self),
min > 0 ? gtk_bitset_get_size_in_range (self->matches, 0, min - 1) : 0,
gtk_bitset_get_size_in_range (old, min, max),
gtk_bitset_get_size_in_range (self->matches, min, max));
removed,
added);
if (removed != added)
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_N_ITEMS]);
}
gtk_bitset_unref (changes);
gtk_bitset_unref (old);
@@ -286,6 +292,8 @@ gtk_filter_list_model_items_changed_cb (GListModel *model,
case GTK_FILTER_MATCH_ALL:
g_list_model_items_changed (G_LIST_MODEL (self), position, removed, added);
if (removed != added)
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_N_ITEMS]);
return;
case GTK_FILTER_MATCH_SOME:
@@ -316,6 +324,8 @@ gtk_filter_list_model_items_changed_cb (GListModel *model,
g_list_model_items_changed (G_LIST_MODEL (self),
position > 0 ? gtk_bitset_get_size_in_range (self->matches, 0, position - 1) : 0,
filter_removed, filter_added);
if (filter_removed != filter_added)
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_N_ITEMS]);
}
static void
@@ -364,10 +374,18 @@ gtk_filter_list_model_get_property (GObject *object,
g_value_set_boolean (value, self->incremental);
break;
case PROP_ITEM_TYPE:
g_value_set_gtype (value, gtk_filter_list_model_get_item_type (G_LIST_MODEL (self)));
break;
case PROP_MODEL:
g_value_set_object (value, self->model);
break;
case PROP_N_ITEMS:
g_value_set_uint (value, gtk_filter_list_model_get_n_items (G_LIST_MODEL (self)));
break;
case PROP_PENDING:
g_value_set_uint (value, gtk_filter_list_model_get_pending (self));
break;
@@ -415,7 +433,10 @@ gtk_filter_list_model_refilter (GtkFilterListModel *self,
self->strictness = new_strictness;
gtk_filter_list_model_stop_filtering (self);
if (n_before > 0)
g_list_model_items_changed (G_LIST_MODEL (self), 0, n_before, 0);
{
g_list_model_items_changed (G_LIST_MODEL (self), 0, n_before, 0);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_N_ITEMS]);
}
}
break;
@@ -423,8 +444,17 @@ gtk_filter_list_model_refilter (GtkFilterListModel *self,
switch (self->strictness)
{
case GTK_FILTER_MATCH_NONE:
self->strictness = new_strictness;
g_list_model_items_changed (G_LIST_MODEL (self), 0, 0, g_list_model_get_n_items (self->model));
{
guint n_items;
self->strictness = new_strictness;
n_items = g_list_model_get_n_items (self->model);
if (n_items > 0)
{
g_list_model_items_changed (G_LIST_MODEL (self), 0, 0, n_items);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_N_ITEMS]);
}
}
break;
case GTK_FILTER_MATCH_ALL:
self->strictness = new_strictness;
@@ -460,6 +490,7 @@ gtk_filter_list_model_refilter (GtkFilterListModel *self,
g_clear_pointer (&self->matches, gtk_bitset_unref);
g_list_model_items_changed (G_LIST_MODEL (self), start, n_before - end - start, n_after - end - start);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_N_ITEMS]);
}
}
break;
@@ -571,6 +602,18 @@ gtk_filter_list_model_class_init (GtkFilterListModelClass *class)
FALSE,
GTK_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
/**
* GtkFilterListModel:item-type:
*
* The type of items. See [method@Gio.ListModel.get_item_type].
*
* Since: 4.8
**/
properties[PROP_ITEM_TYPE] =
g_param_spec_gtype ("item-type", NULL, NULL,
G_TYPE_OBJECT,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
/**
* GtkFilterListModel:model: (attributes org.gtk.Property.get=gtk_filter_list_model_get_model org.gtk.Property.set=gtk_filter_list_model_set_model)
*
@@ -581,6 +624,18 @@ gtk_filter_list_model_class_init (GtkFilterListModelClass *class)
G_TYPE_LIST_MODEL,
GTK_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
/**
* GtkFilterListModel:n-items:
*
* The number of items. See [method@Gio.ListModel.get_n_items].
*
* Since: 4.8
**/
properties[PROP_N_ITEMS] =
g_param_spec_uint ("n-items", NULL, NULL,
0, G_MAXUINT, 0,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
/**
* GtkFilterListModel:pending: (attributes org.gtk.Property.get=gtk_filter_list_model_get_pending)
*
@@ -737,6 +792,8 @@ gtk_filter_list_model_set_model (GtkFilterListModel *self,
if (removed > 0 || added > 0)
g_list_model_items_changed (G_LIST_MODEL (self), 0, removed, added);
if (removed != added)
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_N_ITEMS]);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_MODEL]);
}
+41
View File
@@ -36,7 +36,10 @@
enum {
PROP_0,
PROP_ITEM_TYPE,
PROP_MODEL,
PROP_N_ITEMS,
NUM_PROPERTIES
};
@@ -239,6 +242,8 @@ gtk_flatten_list_model_items_changed_cb (GListModel *model,
}
g_list_model_items_changed (G_LIST_MODEL (self), real_position, removed, added);
if (removed != added)
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_N_ITEMS]);
}
static void
@@ -332,10 +337,18 @@ gtk_flatten_list_model_get_property (GObject *object,
switch (prop_id)
{
case PROP_ITEM_TYPE:
g_value_set_gtype (value, gtk_flatten_list_model_get_item_type (G_LIST_MODEL (self)));
break;
case PROP_MODEL:
g_value_set_object (value, self->model);
break;
case PROP_N_ITEMS:
g_value_set_uint (value, gtk_flatten_list_model_get_n_items (G_LIST_MODEL (self)));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -367,6 +380,8 @@ gtk_flatten_list_model_model_items_changed_cb (GListModel *model,
if (real_removed > 0 || real_added > 0)
g_list_model_items_changed (G_LIST_MODEL (self), real_position, real_removed, real_added);
if (real_removed != real_added)
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_N_ITEMS]);
}
static void
@@ -399,6 +414,18 @@ gtk_flatten_list_model_class_init (GtkFlattenListModelClass *class)
gobject_class->get_property = gtk_flatten_list_model_get_property;
gobject_class->dispose = gtk_flatten_list_model_dispose;
/**
* GtkFlattenListModel:item-type:
*
* The type of items. See [method@Gio.ListModel.get_item_type].
*
* Since: 4.8
**/
properties[PROP_ITEM_TYPE] =
g_param_spec_gtype ("item-type", NULL, NULL,
G_TYPE_OBJECT,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
/**
* GtkFlattenListModel:model: (attributes org.gtk.Property.get=gtk_flatten_list_model_get_model org.gtk.Property.set=gtk_flatten_list_model_set_model)
*
@@ -409,6 +436,18 @@ gtk_flatten_list_model_class_init (GtkFlattenListModelClass *class)
G_TYPE_LIST_MODEL,
GTK_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
/**
* GtkFlattenListModel:n-items:
*
* The number of items. See [method@Gio.ListModel.get_n_items].
*
* Since: 4.8
**/
properties[PROP_N_ITEMS] =
g_param_spec_uint ("n-items", NULL, NULL,
0, G_MAXUINT, 0,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (gobject_class, NUM_PROPERTIES, properties);
}
@@ -481,6 +520,8 @@ gtk_flatten_list_model_set_model (GtkFlattenListModel *self,
if (removed > 0 || added > 0)
g_list_model_items_changed (G_LIST_MODEL (self), 0, removed, added);
if (removed != added)
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_N_ITEMS]);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_MODEL]);
}
+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);
}
+106 -19
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);
@@ -1780,15 +1784,30 @@ typedef struct {
GtkWidget *example;
} FeatureItem;
static const char *
static char *
get_feature_display_name (hb_tag_t tag)
{
int i;
char buf[5] = { 0, };
hb_tag_to_string (tag, buf);
if (buf[0] == 's' && buf[1] == 's' && g_ascii_isdigit (buf[2]) && g_ascii_isdigit (buf[3]))
{
int num = (buf[2] - '0') * 10 + (buf[3] - '0');
return g_strdup_printf (g_dpgettext2 (NULL, "OpenType layout", "Stylistic Set %d"), num);
}
if (buf[0] == 'c' && buf[1] == 'v' && g_ascii_isdigit (buf[2]) && g_ascii_isdigit (buf[3]))
{
int num = (buf[2] - '0') * 10 + (buf[3] - '0');
return g_strdup_printf (g_dpgettext2 (NULL, "OpenType layout", "Character Variant %d"), num);
}
for (i = 0; i < G_N_ELEMENTS (open_type_layout_features); i++)
{
if (tag == open_type_layout_features[i].tag)
return g_dpgettext2 (NULL, "OpenType layout", open_type_layout_features[i].name);
return g_strdup (g_dpgettext2 (NULL, "OpenType layout", open_type_layout_features[i].name));
}
return NULL;
@@ -1854,7 +1873,12 @@ find_affected_text (GtkFontChooserWidget *fontchooser,
hb_ot_layout_script_find_language (hb_face, HB_OT_TAG_GSUB, script_index, lang_tag, &lang_index);
G_GNUC_END_IGNORE_DEPRECATIONS
if (hb_ot_layout_language_find_feature (hb_face, HB_OT_TAG_GSUB, script_index, lang_index, feature_tag, &feature_index))
if (hb_ot_layout_language_find_feature (hb_face,
HB_OT_TAG_GSUB,
script_index,
lang_index,
feature_tag,
&feature_index))
{
unsigned int lookup_indexes[32];
unsigned int lookup_count = 32;
@@ -1869,22 +1893,27 @@ find_affected_text (GtkFontChooserWidget *fontchooser,
lookup_indexes);
if (count > 0)
{
hb_set_t* glyphs_before = NULL;
hb_set_t* glyphs_input = NULL;
hb_set_t* glyphs_after = NULL;
hb_set_t* glyphs_output = NULL;
hb_set_t *glyphs_before = NULL;
hb_set_t *glyphs_after = NULL;
hb_set_t *glyphs_output = NULL;
hb_set_t *glyphs_input;
hb_codepoint_t gid;
char buf[5] = { 0, };
glyphs_input = hb_set_create ();
hb_tag_to_string (feature_tag, buf);
// XXX For now, just look at first index
hb_ot_layout_lookup_collect_glyphs (hb_face,
HB_OT_TAG_GSUB,
lookup_indexes[0],
glyphs_before,
glyphs_input,
glyphs_after,
glyphs_output);
glyphs_input = hb_set_create ();
for (int i = 0; i < count; i++)
{
hb_ot_layout_lookup_collect_glyphs (hb_face,
HB_OT_TAG_GSUB,
lookup_indexes[i],
glyphs_before,
glyphs_input,
glyphs_after,
glyphs_output);
}
if (!fontchooser->glyphmap)
{
@@ -1898,6 +1927,7 @@ find_affected_text (GtkFontChooserWidget *fontchooser,
}
}
gid = HB_SET_VALUE_INVALID;
while (hb_set_next (glyphs_input, &gid))
{
hb_codepoint_t ch;
@@ -1922,6 +1952,53 @@ find_affected_text (GtkFontChooserWidget *fontchooser,
return g_string_free (chars, FALSE);
}
static void
update_feature_label (GtkFontChooserWidget *fontchooser,
FeatureItem *item,
hb_font_t *hb_font,
hb_tag_t script_tag,
hb_tag_t lang_tag)
{
hb_face_t *hb_face;
unsigned int script_index, lang_index, feature_index;
hb_ot_name_id_t id;
unsigned int len;
char *label;
hb_face = hb_font_get_face (hb_font);
if (!(g_str_has_prefix (item->name, "ss") || g_str_has_prefix (item->name, "cv")) ||
!g_ascii_isdigit (item->name[2]) || !g_ascii_isdigit (item->name[3]))
return;
hb_ot_layout_table_find_script (hb_face, HB_OT_TAG_GSUB, script_tag, &script_index);
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
hb_ot_layout_script_find_language (hb_face, HB_OT_TAG_GSUB, script_index, lang_tag, &lang_index);
G_GNUC_END_IGNORE_DEPRECATIONS
if (hb_ot_layout_language_find_feature (hb_face, HB_OT_TAG_GSUB, script_index, lang_index, item->tag, &feature_index) &&
hb_ot_layout_feature_get_name_ids (hb_face, HB_OT_TAG_GSUB, feature_index, &id, NULL, NULL, NULL, NULL))
{
len = hb_ot_name_get_utf8 (hb_face, id, HB_LANGUAGE_INVALID, NULL, NULL);
len++;
label = g_new (char, len);
hb_ot_name_get_utf8 (hb_face, id, HB_LANGUAGE_INVALID, &len, label);
char *s = g_strdup_printf ("%s (%s)", label, item->name);
gtk_check_button_set_label (GTK_CHECK_BUTTON (item->feat), s);
g_free (s);
g_free (label);
}
else
{
label = get_feature_display_name (item->tag);
gtk_check_button_set_label (GTK_CHECK_BUTTON (item->feat), label);
g_free (label);
}
}
static void
update_feature_example (GtkFontChooserWidget *fontchooser,
FeatureItem *item,
@@ -2062,10 +2139,13 @@ add_check_group (GtkFontChooserWidget *fontchooser,
GtkGesture *gesture;
GtkWidget *box;
GtkWidget *example;
char *name;
tag = hb_tag_from_string (tags[i], -1);
feat = gtk_check_button_new_with_label (get_feature_display_name (tag));
name = get_feature_display_name (tag);
feat = gtk_check_button_new_with_label (name);
g_free (name);
set_inconsistent (GTK_CHECK_BUTTON (feat), TRUE);
g_signal_connect (feat, "toggled", G_CALLBACK (font_feature_toggled_cb), fontchooser);
g_signal_connect_swapped (feat, "notify::inconsistent", G_CALLBACK (update_font_features), fontchooser);
@@ -2127,14 +2207,14 @@ add_radio_group (GtkFontChooserWidget *fontchooser,
hb_tag_t tag;
GtkWidget *feat;
FeatureItem *item;
const char *name;
char *name;
GtkWidget *box;
GtkWidget *example;
tag = hb_tag_from_string (tags[i], -1);
name = get_feature_display_name (tag);
feat = gtk_check_button_new_with_label (name ? name : _("Default"));
g_free (name);
if (group_button == NULL)
group_button = feat;
else
@@ -2261,6 +2341,7 @@ gtk_font_chooser_widget_update_font_features (GtkFontChooserWidget *fontchooser)
gtk_widget_show (item->top);
gtk_widget_show (gtk_widget_get_parent (item->top));
update_feature_label (fontchooser, item, hb_font, script_tag, lang_tag);
update_feature_example (fontchooser, item, hb_font, script_tag, lang_tag, fontchooser->font_desc);
if (GTK_IS_CHECK_BUTTON (item->feat))
@@ -2560,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);
}
}
}
+1314
View File
File diff suppressed because it is too large Load Diff
+116
View File
@@ -0,0 +1,116 @@
/*
* Copyright © 2022 Benjamin Otte
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Authors: Benjamin Otte <otte@gnome.org>
*/
#ifndef __GTK_INSCRIPTION_H__
#define __GTK_INSCRIPTION_H__
#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
#error "Only <gtk/gtk.h> can be included directly."
#endif
#include <gtk/gtkwidget.h>
G_BEGIN_DECLS
#define GTK_TYPE_INSCRIPTION (gtk_inscription_get_type ())
/**
* GtkInscriptionOverflow:
* @GTK_INSCRIPTION_OVERFLOW_CLIP: Clip the remaining text
* @GTK_INSCRIPTION_OVERFLOW_ELLIPSIZE_START: Omit characters at the start of the text
* @GTK_INSCRIPTION_OVERFLOW_ELLIPSIZE_MIDDLE: Omit characters at the middle of the text
* @GTK_INSCRIPTION_OVERFLOW_ELLIPSIZE_END: Omit characters at the end of the text
*
* The different methods to handle text in #GtkInscription when it doesn't
* fit the available space.
*
* Since: 4.8
*/
typedef enum {
GTK_INSCRIPTION_OVERFLOW_CLIP,
GTK_INSCRIPTION_OVERFLOW_ELLIPSIZE_START,
GTK_INSCRIPTION_OVERFLOW_ELLIPSIZE_MIDDLE,
GTK_INSCRIPTION_OVERFLOW_ELLIPSIZE_END
} GtkInscriptionOverflow;
GDK_AVAILABLE_IN_4_8
G_DECLARE_FINAL_TYPE (GtkInscription, gtk_inscription, GTK, INSCRIPTION, GtkWidget)
GDK_AVAILABLE_IN_4_8
GtkWidget * gtk_inscription_new (const char *text);
GDK_AVAILABLE_IN_4_8
const char * gtk_inscription_get_text (GtkInscription *self);
GDK_AVAILABLE_IN_4_8
void gtk_inscription_set_text (GtkInscription *self,
const char *text);
GDK_AVAILABLE_IN_4_8
PangoAttrList * gtk_inscription_get_attributes (GtkInscription *self);
GDK_AVAILABLE_IN_4_8
void gtk_inscription_set_attributes (GtkInscription *self,
PangoAttrList *attrs);
GDK_AVAILABLE_IN_4_8
void gtk_inscription_set_markup (GtkInscription *self,
const char *markup);
GDK_AVAILABLE_IN_4_8
GtkInscriptionOverflow gtk_inscription_get_text_overflow (GtkInscription *self);
GDK_AVAILABLE_IN_4_8
void gtk_inscription_set_text_overflow (GtkInscription *self,
GtkInscriptionOverflow overflow);
GDK_AVAILABLE_IN_4_8
PangoWrapMode gtk_inscription_get_wrap_mode (GtkInscription *self);
GDK_AVAILABLE_IN_4_8
void gtk_inscription_set_wrap_mode (GtkInscription *self,
PangoWrapMode wrap_mode);
GDK_AVAILABLE_IN_4_8
guint gtk_inscription_get_min_chars (GtkInscription *self);
GDK_AVAILABLE_IN_4_8
void gtk_inscription_set_min_chars (GtkInscription *self,
guint min_chars);
GDK_AVAILABLE_IN_4_8
guint gtk_inscription_get_nat_chars (GtkInscription *self);
GDK_AVAILABLE_IN_4_8
void gtk_inscription_set_nat_chars (GtkInscription *self,
guint nat_chars);
GDK_AVAILABLE_IN_4_8
guint gtk_inscription_get_min_lines (GtkInscription *self);
GDK_AVAILABLE_IN_4_8
void gtk_inscription_set_min_lines (GtkInscription *self,
guint min_lines);
GDK_AVAILABLE_IN_4_8
guint gtk_inscription_get_nat_lines (GtkInscription *self);
GDK_AVAILABLE_IN_4_8
void gtk_inscription_set_nat_lines (GtkInscription *self,
guint nat_lines);
GDK_AVAILABLE_IN_4_8
float gtk_inscription_get_xalign (GtkInscription *self);
GDK_AVAILABLE_IN_4_8
void gtk_inscription_set_xalign (GtkInscription *self,
float xalign);
GDK_AVAILABLE_IN_4_8
float gtk_inscription_get_yalign (GtkInscription *self);
GDK_AVAILABLE_IN_4_8
void gtk_inscription_set_yalign (GtkInscription *self,
float yalign);
G_END_DECLS
#endif /* __GTK_INSCRIPTION_H__ */
+33
View File
@@ -0,0 +1,33 @@
/*
* Copyright © 2022 Benjamin Otte
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Authors: Benjamin Otte <otte@gnome.org>
*/
#ifndef __GTK_INSCRIPTION_PRIVATE_H__
#define __GTK_INSCRIPTION_PRIVATE_H__
#include <gtk/gtkinscription.h>
G_BEGIN_DECLS
PangoLayout * gtk_inscription_get_layout (GtkInscription *self);
G_END_DECLS
#endif /* __GTK_INSCRIPTION_PRIVATE_H__ */
+24 -20
View File
@@ -1363,34 +1363,20 @@ gtk_list_base_size_allocate_child (GtkListBase *self,
self_width = gtk_widget_get_width (GTK_WIDGET (self));
self_height = gtk_widget_get_height (GTK_WIDGET (self));
if (y + height + GTK_LIST_BASE_CHILD_MAX_OVERDRAW <= 0 ||
y - GTK_LIST_BASE_CHILD_MAX_OVERDRAW >= self_height ||
x + width + GTK_LIST_BASE_CHILD_MAX_OVERDRAW <= 0 ||
x - GTK_LIST_BASE_CHILD_MAX_OVERDRAW >= self_width)
{
/* child is fully outside the viewport, hide it and don't allocate it */
gtk_widget_set_child_visible (child, FALSE);
return;
}
gtk_widget_set_child_visible (child, TRUE);
if (gtk_list_base_get_orientation (GTK_LIST_BASE (self)) == GTK_ORIENTATION_VERTICAL)
{
if (_gtk_widget_get_direction (GTK_WIDGET (self)) == GTK_TEXT_DIR_LTR)
{
child_allocation.x = x;
child_allocation.y = y;
child_allocation.width = width;
child_allocation.height = height;
}
else
{
child_allocation.x = self_width - x - width;
child_allocation.y = y;
child_allocation.width = width;
child_allocation.height = height;
}
child_allocation.width = width;
child_allocation.height = height;
}
else
{
@@ -1398,18 +1384,32 @@ gtk_list_base_size_allocate_child (GtkListBase *self,
{
child_allocation.x = y;
child_allocation.y = x;
child_allocation.width = height;
child_allocation.height = width;
}
else
{
child_allocation.x = self_width - y - height;
child_allocation.y = x;
child_allocation.width = height;
child_allocation.height = width;
}
child_allocation.width = height;
child_allocation.height = width;
}
if (!gdk_rectangle_intersect (&child_allocation,
&(GdkRectangle) {
- GTK_LIST_BASE_CHILD_MAX_OVERDRAW,
- GTK_LIST_BASE_CHILD_MAX_OVERDRAW,
self_width + GTK_LIST_BASE_CHILD_MAX_OVERDRAW,
self_height + GTK_LIST_BASE_CHILD_MAX_OVERDRAW
},
NULL))
{
/* child is fully outside the viewport, hide it and don't allocate it */
gtk_widget_set_child_visible (child, FALSE);
return;
}
gtk_widget_set_child_visible (child, TRUE);
gtk_widget_size_allocate (child, &child_allocation, -1);
}
@@ -1740,8 +1740,12 @@ gtk_list_base_drag_end (GtkGestureDrag *gesture,
double offset_y,
GtkListBase *self)
{
GtkListBasePrivate *priv = gtk_list_base_get_instance_private (self);
gboolean modify, extend;
if (!priv->rubberband)
return;
gtk_list_base_drag_update (gesture, offset_x, offset_y, self);
get_selection_modifiers (GTK_GESTURE (gesture), &modify, &extend);
gtk_list_base_stop_rubberband (self, modify, extend);
+36 -38
View File
@@ -80,31 +80,36 @@ G_DEFINE_TYPE (GtkListItemFactory, gtk_list_item_factory, G_TYPE_OBJECT)
static void
gtk_list_item_factory_default_setup (GtkListItemFactory *self,
GtkListItemWidget *widget,
GtkListItem *list_item)
GObject *item,
gboolean bind,
GFunc func,
gpointer data)
{
gtk_list_item_widget_default_setup (widget, list_item);
if (func)
func (item, data);
}
static void
gtk_list_item_factory_default_teardown (GtkListItemFactory *self,
GtkListItemWidget *widget,
GtkListItem *list_item)
GObject *item,
gboolean unbind,
GFunc func,
gpointer data)
{
gtk_list_item_widget_default_teardown (widget, list_item);
gtk_list_item_set_child (list_item, NULL);
if (func)
func (item, data);
}
static void
gtk_list_item_factory_default_update (GtkListItemFactory *self,
GtkListItemWidget *widget,
GtkListItem *list_item,
guint position,
gpointer item,
gboolean selected)
GObject *item,
gboolean unbind,
gboolean bind,
GFunc func,
gpointer data)
{
gtk_list_item_widget_default_update (widget, list_item, position, item, selected);
if (func)
func (item, data);
}
static void
@@ -122,45 +127,38 @@ gtk_list_item_factory_init (GtkListItemFactory *self)
void
gtk_list_item_factory_setup (GtkListItemFactory *self,
GtkListItemWidget *widget)
GObject *item,
gboolean bind,
GFunc func,
gpointer data)
{
GtkListItem *list_item;
g_return_if_fail (GTK_IS_LIST_ITEM_FACTORY (self));
list_item = gtk_list_item_new ();
GTK_LIST_ITEM_FACTORY_GET_CLASS (self)->setup (self, widget, list_item);
GTK_LIST_ITEM_FACTORY_GET_CLASS (self)->setup (self, item, bind, func, data);
}
void
gtk_list_item_factory_teardown (GtkListItemFactory *self,
GtkListItemWidget *widget)
GObject *item,
gboolean unbind,
GFunc func,
gpointer data)
{
GtkListItem *list_item;
g_return_if_fail (GTK_IS_LIST_ITEM_FACTORY (self));
list_item = gtk_list_item_widget_get_list_item (widget);
GTK_LIST_ITEM_FACTORY_GET_CLASS (self)->teardown (self, widget, list_item);
g_object_unref (list_item);
GTK_LIST_ITEM_FACTORY_GET_CLASS (self)->teardown (self, item, unbind, func, data);
}
void
gtk_list_item_factory_update (GtkListItemFactory *self,
GtkListItemWidget *widget,
guint position,
gpointer item,
gboolean selected)
GObject *item,
gboolean unbind,
gboolean bind,
GFunc func,
gpointer data)
{
GtkListItem *list_item;
g_return_if_fail (GTK_IS_LIST_ITEM_FACTORY (self));
g_return_if_fail (GTK_IS_LIST_ITEM_WIDGET (widget));
g_return_if_fail (G_IS_OBJECT (item));
list_item = gtk_list_item_widget_get_list_item (widget);
GTK_LIST_ITEM_FACTORY_GET_CLASS (self)->update (self, widget, list_item, position, item, selected);
GTK_LIST_ITEM_FACTORY_GET_CLASS (self)->update (self, item, unbind, bind, func, data);
}
+26 -15
View File
@@ -37,33 +37,44 @@ struct _GtkListItemFactoryClass
/* setup @list_item so it can be bound */
void (* setup) (GtkListItemFactory *self,
GtkListItemWidget *widget,
GtkListItem *list_item);
GObject *item,
gboolean bind,
GFunc func,
gpointer data);
/* undo the effects of GtkListItemFactoryClass::setup() */
void (* teardown) (GtkListItemFactory *self,
GtkListItemWidget *widget,
GtkListItem *list_item);
GObject *item,
gboolean unbind,
GFunc func,
gpointer data);
/* Update properties on @list_item to the given @item, which is in @position and @selected state.
* One or more of those properties might be unchanged. */
void (* update) (GtkListItemFactory *self,
GtkListItemWidget *widget,
GtkListItem *list_item,
guint position,
gpointer item,
gboolean selected);
GObject *item,
gboolean unbind,
gboolean bind,
GFunc func,
gpointer data);
};
void gtk_list_item_factory_setup (GtkListItemFactory *self,
GtkListItemWidget *widget);
GObject *item,
gboolean bind,
GFunc func,
gpointer data);
void gtk_list_item_factory_teardown (GtkListItemFactory *self,
GtkListItemWidget *widget);
GObject *item,
gboolean unbind,
GFunc func,
gpointer data);
void gtk_list_item_factory_update (GtkListItemFactory *self,
GtkListItemWidget *widget,
guint position,
gpointer item,
gboolean selected);
GObject *item,
gboolean unbind,
gboolean bind,
GFunc func,
gpointer data);
G_END_DECLS
+134 -80
View File
@@ -140,6 +140,85 @@ gtk_list_item_widget_grab_focus (GtkWidget *widget)
return GTK_WIDGET_CLASS (gtk_list_item_widget_parent_class)->grab_focus (widget);
}
static void
gtk_list_item_widget_setup_func (gpointer object,
gpointer data)
{
GtkListItemWidget *self = data;
GtkListItemWidgetPrivate *priv = gtk_list_item_widget_get_instance_private (self);
GtkListItem *list_item = object;
priv->list_item = list_item;
list_item->owner = self;
if (list_item->child)
gtk_list_item_widget_add_child (self, list_item->child);
gtk_list_item_widget_set_activatable (self, list_item->activatable);
gtk_list_item_do_notify (list_item,
priv->item != NULL,
priv->position != GTK_INVALID_LIST_POSITION,
priv->selected);
}
static void
gtk_list_item_widget_setup_factory (GtkListItemWidget *self)
{
GtkListItemWidgetPrivate *priv = gtk_list_item_widget_get_instance_private (self);
GtkListItem *list_item;
list_item = gtk_list_item_new ();
gtk_list_item_factory_setup (priv->factory,
G_OBJECT (list_item),
priv->item != NULL,
gtk_list_item_widget_setup_func,
self);
g_assert (priv->list_item == list_item);
}
static void
gtk_list_item_widget_teardown_func (gpointer object,
gpointer data)
{
GtkListItemWidget *self = data;
GtkListItemWidgetPrivate *priv = gtk_list_item_widget_get_instance_private (self);
GtkListItem *list_item = object;
g_assert (priv->list_item == list_item);
priv->list_item = NULL;
list_item->owner = NULL;
if (list_item->child)
gtk_list_item_widget_remove_child (self, list_item->child);
gtk_list_item_widget_set_activatable (self, FALSE);
gtk_list_item_do_notify (list_item,
priv->item != NULL,
priv->position != GTK_INVALID_LIST_POSITION,
priv->selected);
gtk_list_item_set_child (list_item, NULL);
}
static void
gtk_list_item_widget_teardown_factory (GtkListItemWidget *self)
{
GtkListItemWidgetPrivate *priv = gtk_list_item_widget_get_instance_private (self);
gtk_list_item_factory_teardown (priv->factory,
G_OBJECT (priv->list_item),
priv->item != NULL,
gtk_list_item_widget_teardown_func,
self);
g_assert (priv->list_item == NULL);
}
static void
gtk_list_item_widget_root (GtkWidget *widget)
{
@@ -149,7 +228,7 @@ gtk_list_item_widget_root (GtkWidget *widget)
GTK_WIDGET_CLASS (gtk_list_item_widget_parent_class)->root (widget);
if (priv->factory)
gtk_list_item_factory_setup (priv->factory, self);
gtk_list_item_widget_setup_factory (self);
}
static void
@@ -161,7 +240,7 @@ gtk_list_item_widget_unroot (GtkWidget *widget)
GTK_WIDGET_CLASS (gtk_list_item_widget_parent_class)->unroot (widget);
if (priv->list_item)
gtk_list_item_factory_teardown (priv->factory, self);
gtk_list_item_widget_teardown_factory (self);
}
static void
@@ -474,6 +553,45 @@ gtk_list_item_widget_new (GtkListItemFactory *factory,
NULL);
}
typedef struct {
GtkListItemWidget *widget;
guint position;
gpointer item;
gboolean selected;
} GtkListItemWidgetUpdate;
static void
gtk_list_item_widget_update_func (gpointer object,
gpointer data)
{
GtkListItemWidgetUpdate *update = data;
GtkListItem *list_item = object;
/* Track notify manually instead of freeze/thaw_notify for performance reasons. */
gboolean notify_item = FALSE, notify_position = FALSE, notify_selected = FALSE;
GtkListItemWidget *self = update->widget;
GtkListItemWidgetPrivate *priv = gtk_list_item_widget_get_instance_private (self);
/* FIXME: It's kinda evil to notify external objects from here... */
if (g_set_object (&priv->item, update->item))
notify_item = TRUE;
if (priv->position != update->position)
{
priv->position = update->position;
notify_position = TRUE;
}
if (priv->selected != update->selected)
{
priv->selected = update->selected;
notify_selected = TRUE;
}
if (list_item)
gtk_list_item_do_notify (list_item, notify_item, notify_position, notify_selected);
}
void
gtk_list_item_widget_update (GtkListItemWidget *self,
guint position,
@@ -481,14 +599,24 @@ gtk_list_item_widget_update (GtkListItemWidget *self,
gboolean selected)
{
GtkListItemWidgetPrivate *priv = gtk_list_item_widget_get_instance_private (self);
GtkListItemWidgetUpdate update = { self, position, item, selected };
gboolean was_selected;
was_selected = priv->selected;
if (priv->list_item)
gtk_list_item_factory_update (priv->factory, self, position, item, selected);
{
gtk_list_item_factory_update (priv->factory,
G_OBJECT (priv->list_item),
priv->item != NULL,
item != NULL,
gtk_list_item_widget_update_func,
&update);
}
else
gtk_list_item_widget_default_update (self, NULL, position, item, selected);
{
gtk_list_item_widget_update_func (NULL, &update);
}
/* don't look at selected variable, it's not reentrancy safe */
if (was_selected != priv->selected)
@@ -504,80 +632,6 @@ gtk_list_item_widget_update (GtkListItemWidget *self,
}
}
void
gtk_list_item_widget_default_setup (GtkListItemWidget *self,
GtkListItem *list_item)
{
GtkListItemWidgetPrivate *priv = gtk_list_item_widget_get_instance_private (self);
priv->list_item = list_item;
list_item->owner = self;
if (list_item->child)
gtk_list_item_widget_add_child (self, list_item->child);
gtk_list_item_widget_set_activatable (self, list_item->activatable);
gtk_list_item_do_notify (list_item,
priv->item != NULL,
priv->position != GTK_INVALID_LIST_POSITION,
priv->selected);
}
void
gtk_list_item_widget_default_teardown (GtkListItemWidget *self,
GtkListItem *list_item)
{
GtkListItemWidgetPrivate *priv = gtk_list_item_widget_get_instance_private (self);
g_assert (priv->list_item == list_item);
priv->list_item = NULL;
list_item->owner = NULL;
if (list_item->child)
gtk_list_item_widget_remove_child (self, list_item->child);
gtk_list_item_widget_set_activatable (self, FALSE);
gtk_list_item_do_notify (list_item,
priv->item != NULL,
priv->position != GTK_INVALID_LIST_POSITION,
priv->selected);
}
void
gtk_list_item_widget_default_update (GtkListItemWidget *self,
GtkListItem *list_item,
guint position,
gpointer item,
gboolean selected)
{
/* Track notify manually instead of freeze/thaw_notify for performance reasons. */
gboolean notify_item = FALSE, notify_position = FALSE, notify_selected = FALSE;
GtkListItemWidgetPrivate *priv = gtk_list_item_widget_get_instance_private (self);
/* FIXME: It's kinda evil to notify external objects from here... */
if (g_set_object (&priv->item, item))
notify_item = TRUE;
if (priv->position != position)
{
priv->position = position;
notify_position = TRUE;
}
if (priv->selected != selected)
{
priv->selected = selected;
notify_selected = TRUE;
}
if (list_item)
gtk_list_item_do_notify (list_item, notify_item, notify_position, notify_selected);
}
void
gtk_list_item_widget_set_factory (GtkListItemWidget *self,
GtkListItemFactory *factory)
@@ -590,7 +644,7 @@ gtk_list_item_widget_set_factory (GtkListItemWidget *self,
if (priv->factory)
{
if (priv->list_item)
gtk_list_item_factory_teardown (factory, self);
gtk_list_item_widget_teardown_factory (self);
g_clear_object (&priv->factory);
}
@@ -599,7 +653,7 @@ gtk_list_item_widget_set_factory (GtkListItemWidget *self,
priv->factory = g_object_ref (factory);
if (gtk_widget_get_root (GTK_WIDGET (self)))
gtk_list_item_factory_setup (factory, self);
gtk_list_item_widget_setup_factory (self);
}
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_FACTORY]);
-10
View File
@@ -59,16 +59,6 @@ void gtk_list_item_widget_update (GtkListItemWidg
gboolean selected);
GtkListItem * gtk_list_item_widget_get_list_item (GtkListItemWidget *self);
void gtk_list_item_widget_default_setup (GtkListItemWidget *self,
GtkListItem *list_item);
void gtk_list_item_widget_default_teardown (GtkListItemWidget *self,
GtkListItem *list_item);
void gtk_list_item_widget_default_update (GtkListItemWidget *self,
GtkListItem *list_item,
guint position,
gpointer item,
gboolean selected);
void gtk_list_item_widget_set_factory (GtkListItemWidget *self,
GtkListItemFactory *factory);
void gtk_list_item_widget_set_single_click_activate
+53 -1
View File
@@ -48,6 +48,16 @@ struct _GtkListListModelClass
GObjectClass parent_class;
};
enum {
PROP_0,
PROP_ITEM_TYPE,
PROP_N_ITEMS,
N_PROPS
};
static GParamSpec *properties[N_PROPS] = { NULL, };
static GType
gtk_list_list_model_get_item_type (GListModel *list)
{
@@ -109,6 +119,30 @@ G_DEFINE_TYPE_WITH_CODE (GtkListListModel, gtk_list_list_model,
G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (G_TYPE_LIST_MODEL, gtk_list_list_model_list_model_init))
static void
gtk_list_list_model_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GtkListListModel *self = GTK_LIST_LIST_MODEL (object);
switch (prop_id)
{
case PROP_ITEM_TYPE:
g_value_set_gtype (value, G_TYPE_OBJECT);
break;
case PROP_N_ITEMS:
g_value_set_uint (value, self->n_items);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gtk_list_list_model_dispose (GObject *object)
{
@@ -128,7 +162,20 @@ gtk_list_list_model_class_init (GtkListListModelClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->get_property = gtk_list_list_model_get_property;
object_class->dispose = gtk_list_list_model_dispose;
properties[PROP_ITEM_TYPE] =
g_param_spec_gtype ("item-type", NULL, NULL,
G_TYPE_OBJECT,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
properties[PROP_N_ITEMS] =
g_param_spec_uint ("n-items", NULL, NULL,
0, G_MAXUINT, 0,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (object_class, N_PROPS, properties);
}
static void
@@ -231,6 +278,7 @@ gtk_list_list_model_item_added_at (GtkListListModel *self,
self->n_items += 1;
g_list_model_items_changed (G_LIST_MODEL (self), position, 0, 1);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_N_ITEMS]);
}
void
@@ -292,6 +340,7 @@ gtk_list_list_model_item_removed_at (GtkListListModel *self,
self->n_items -= 1;
g_list_model_items_changed (G_LIST_MODEL (self), position, 1, 0);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_N_ITEMS]);
}
void
@@ -310,7 +359,10 @@ gtk_list_list_model_clear (GtkListListModel *self)
self->notify = NULL;
if (n_items > 0)
g_list_model_items_changed (G_LIST_MODEL (self), 0, n_items, 0);
{
g_list_model_items_changed (G_LIST_MODEL (self), 0, n_items, 0);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_N_ITEMS]);
}
}
+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,
+41
View File
@@ -60,7 +60,10 @@
enum {
PROP_0,
PROP_HAS_MAP,
PROP_ITEM_TYPE,
PROP_MODEL,
PROP_N_ITEMS,
NUM_PROPERTIES
};
@@ -221,6 +224,8 @@ gtk_map_list_model_items_changed_cb (GListModel *model,
if (self->items == NULL)
{
g_list_model_items_changed (G_LIST_MODEL (self), position, removed, added);
if (removed != added)
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_N_ITEMS]);
return;
}
@@ -269,6 +274,8 @@ gtk_map_list_model_items_changed_cb (GListModel *model,
}
g_list_model_items_changed (G_LIST_MODEL (self), position, removed, added);
if (removed != added)
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_N_ITEMS]);
}
static void
@@ -305,10 +312,18 @@ gtk_map_list_model_get_property (GObject *object,
g_value_set_boolean (value, self->items != NULL);
break;
case PROP_ITEM_TYPE:
g_value_set_gtype (value, gtk_map_list_model_get_item_type (G_LIST_MODEL (self)));
break;
case PROP_MODEL:
g_value_set_object (value, self->model);
break;
case PROP_N_ITEMS:
g_value_set_uint (value, gtk_map_list_model_get_n_items (G_LIST_MODEL (self)));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -360,6 +375,18 @@ gtk_map_list_model_class_init (GtkMapListModelClass *class)
FALSE,
GTK_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY);
/**
* GtkMapListModel:item-type:
*
* The type of items. See [method@Gio.ListModel.get_item_type].
*
* Since: 4.8
**/
properties[PROP_ITEM_TYPE] =
g_param_spec_gtype ("item-type", NULL, NULL,
G_TYPE_OBJECT,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
/**
* GtkMapListModel:model: (attributes org.gtk.Property.get=gtk_map_list_model_get_model org.gtk.Property.set=gtk_map_list_model_set_model)
*
@@ -370,6 +397,18 @@ gtk_map_list_model_class_init (GtkMapListModelClass *class)
G_TYPE_LIST_MODEL,
GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_EXPLICIT_NOTIFY);
/**
* GtkMapListModel:n-items:
*
* The number of items. See [method@Gio.ListModel.get_n_items].
*
* Since: 4.8
**/
properties[PROP_N_ITEMS] =
g_param_spec_uint ("n-items", NULL, NULL,
0, G_MAXUINT, 0,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (gobject_class, NUM_PROPERTIES, properties);
}
@@ -578,6 +617,8 @@ gtk_map_list_model_set_model (GtkMapListModel *self,
if (removed > 0 || added > 0)
g_list_model_items_changed (G_LIST_MODEL (self), 0, removed, added);
if (removed != added)
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_N_ITEMS]);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_MODEL]);
}
+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);
}
+24 -17
View File
@@ -201,13 +201,10 @@ gtk_menu_tracker_item_finalize (GObject *object)
{
GtkMenuTrackerItem *self = GTK_MENU_TRACKER_ITEM (object);
g_free (self->action_namespace);
g_free (self->action_and_target);
if (self->observable)
g_object_unref (self->observable);
g_object_unref (self->item);
g_clear_pointer (&self->action_namespace, g_free);
g_clear_pointer (&self->action_and_target, g_free);
g_clear_object (&self->observable);
g_clear_object (&self->item);
G_OBJECT_CLASS (gtk_menu_tracker_item_parent_class)->finalize (object);
}
@@ -873,18 +870,27 @@ gtk_menu_tracker_opener_finalize (GObject *object)
{
GtkMenuTrackerOpener *opener = (GtkMenuTrackerOpener *)object;
gtk_action_observable_unregister_observer (opener->item->observable,
opener->submenu_action,
(GtkActionObserver *)opener);
if (opener->item != NULL)
{
GtkMenuTrackerItem *item = g_object_ref (opener->item);
if (GTK_IS_ACTION_MUXER (opener->item->observable))
gtk_action_muxer_change_action_state (GTK_ACTION_MUXER (opener->item->observable),
opener->submenu_action,
g_variant_new_boolean (FALSE));
g_clear_weak_pointer (&opener->item);
gtk_menu_tracker_item_set_submenu_shown (opener->item, FALSE);
gtk_action_observable_unregister_observer (item->observable,
opener->submenu_action,
(GtkActionObserver *)opener);
g_free (opener->submenu_action);
if (GTK_IS_ACTION_MUXER (item->observable))
gtk_action_muxer_change_action_state (GTK_ACTION_MUXER (item->observable),
opener->submenu_action,
g_variant_new_boolean (FALSE));
gtk_menu_tracker_item_set_submenu_shown (item, FALSE);
g_object_unref (item);
}
g_clear_pointer (&opener->submenu_action, g_free);
G_OBJECT_CLASS (gtk_menu_tracker_opener_parent_class)->finalize (object);
}
@@ -995,7 +1001,8 @@ gtk_menu_tracker_opener_new (GtkMenuTrackerItem *item,
opener = g_object_new (gtk_menu_tracker_opener_get_type (), NULL);
opener->first_time = TRUE;
opener->item = item;
g_set_weak_pointer (&opener->item, item);
if (item->action_namespace)
opener->submenu_action = g_strjoin (".", item->action_namespace, submenu_action, NULL);
+65
View File
@@ -71,6 +71,16 @@ struct _GtkMultiFilterClass
GtkFilterChange removal_change;
};
enum {
PROP_0,
PROP_ITEM_TYPE,
PROP_N_ITEMS,
N_PROPS
};
static GParamSpec *properties[N_PROPS] = { NULL, };
static GType
gtk_multi_filter_get_item_type (GListModel *list)
{
@@ -139,6 +149,30 @@ gtk_multi_filter_changed_cb (GtkFilter *filter,
gtk_filter_changed (GTK_FILTER (self), change);
}
static void
gtk_multi_filter_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GtkMultiFilter *self = GTK_MULTI_FILTER (object);
switch (prop_id)
{
case PROP_ITEM_TYPE:
g_value_set_gtype (value, GTK_TYPE_FILTER);
break;
case PROP_N_ITEMS:
g_value_set_uint (value, gtk_filters_get_size (&self->filters));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gtk_multi_filter_dispose (GObject *object)
{
@@ -161,7 +195,34 @@ gtk_multi_filter_class_init (GtkMultiFilterClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
object_class->get_property = gtk_multi_filter_get_property;
object_class->dispose = gtk_multi_filter_dispose;
/**
* GtkMultiFilter:item-type:
*
* The type of items. See [method@Gio.ListModel.get_item_type].
*
* Since: 4.8
**/
properties[PROP_ITEM_TYPE] =
g_param_spec_gtype ("item-type", NULL, NULL,
GTK_TYPE_FILTER,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
/**
* GtkMultiFilter:n-items:
*
* The number of items. See [method@Gio.ListModel.get_n_items].
*
* Since: 4.8
**/
properties[PROP_N_ITEMS] =
g_param_spec_uint ("n-items", NULL, NULL,
0, G_MAXUINT, 0,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (object_class, N_PROPS, properties);
}
static void
@@ -186,6 +247,8 @@ gtk_multi_filter_append (GtkMultiFilter *self,
g_signal_connect (filter, "changed", G_CALLBACK (gtk_multi_filter_changed_cb), self);
gtk_filters_append (&self->filters, filter);
g_list_model_items_changed (G_LIST_MODEL (self), gtk_filters_get_size (&self->filters) - 1, 0, 1);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_N_ITEMS]);
gtk_filter_changed (GTK_FILTER (self),
GTK_MULTI_FILTER_GET_CLASS (self)->addition_change);
@@ -216,6 +279,8 @@ gtk_multi_filter_remove (GtkMultiFilter *self,
filter = gtk_filters_get (&self->filters, position);
g_signal_handlers_disconnect_by_func (filter, gtk_multi_filter_changed_cb, self);
gtk_filters_splice (&self->filters, position, 1, FALSE, NULL, 0);
g_list_model_items_changed (G_LIST_MODEL (self), position, 1, 0);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_N_ITEMS]);
gtk_filter_changed (GTK_FILTER (self),
GTK_MULTI_FILTER_GET_CLASS (self)->removal_change);
+38
View File
@@ -49,7 +49,9 @@ struct _GtkMultiSelectionClass
enum {
PROP_0,
PROP_ITEM_TYPE,
PROP_MODEL,
PROP_N_ITEMS,
N_PROPS,
};
@@ -266,6 +268,8 @@ gtk_multi_selection_items_changed_cb (GListModel *model,
g_clear_pointer (&pending, g_hash_table_unref);
g_list_model_items_changed (G_LIST_MODEL (self), position, removed, added);
if (removed != added)
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_N_ITEMS]);
}
static void
@@ -311,10 +315,18 @@ gtk_multi_selection_get_property (GObject *object,
switch (prop_id)
{
case PROP_ITEM_TYPE:
g_value_set_gtype (value, gtk_multi_selection_get_item_type (G_LIST_MODEL (self)));
break;
case PROP_MODEL:
g_value_set_object (value, self->model);
break;
case PROP_N_ITEMS:
g_value_set_uint (value, gtk_multi_selection_get_n_items (G_LIST_MODEL (self)));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -343,6 +355,18 @@ gtk_multi_selection_class_init (GtkMultiSelectionClass *klass)
gobject_class->set_property = gtk_multi_selection_set_property;
gobject_class->dispose = gtk_multi_selection_dispose;
/**
* GtkMultiSelection:item-type:
*
* The type of items. See [method@Gio.ListModel.get_item_type].
*
* Since: 4.8
**/
properties[PROP_ITEM_TYPE] =
g_param_spec_gtype ("item-type", NULL, NULL,
G_TYPE_OBJECT,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
/**
* GtkMultiSelection:model: (attributes org.gtk.Property.get=gtk_multi_selection_get_model org.gtk.Property.set=gtk_multi_selection_set_model)
*
@@ -353,6 +377,18 @@ gtk_multi_selection_class_init (GtkMultiSelectionClass *klass)
G_TYPE_LIST_MODEL,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
/**
* GtkMultiSelection:n-items:
*
* The number of items. See [method@Gio.ListModel.get_n_items].
*
* Since: 4.8
**/
properties[PROP_N_ITEMS] =
g_param_spec_uint ("n-items", NULL, NULL,
0, G_MAXUINT, 0,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (gobject_class, N_PROPS, properties);
}
@@ -446,6 +482,8 @@ gtk_multi_selection_set_model (GtkMultiSelection *self,
gtk_bitset_remove_all (self->selected);
g_hash_table_remove_all (self->items);
g_list_model_items_changed (G_LIST_MODEL (self), 0, n_items_before, 0);
if (n_items_before)
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_N_ITEMS]);
}
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_MODEL]);
+65
View File
@@ -66,6 +66,16 @@ struct _GtkMultiSortKeys
GtkMultiSortKey keys[];
};
enum {
PROP_0,
PROP_ITEM_TYPE,
PROP_N_ITEMS,
N_PROPS
};
static GParamSpec *properties[N_PROPS] = { NULL, };
static void
gtk_multi_sort_keys_free (GtkSortKeys *keys)
{
@@ -327,6 +337,30 @@ gtk_multi_sorter_changed_cb (GtkSorter *sorter,
gtk_multi_sort_keys_new (self));
}
static void
gtk_multi_sorter_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GtkMultiSorter *self = GTK_MULTI_SORTER (object);
switch (prop_id)
{
case PROP_ITEM_TYPE:
g_value_set_gtype (value, GTK_TYPE_SORTER);
break;
case PROP_N_ITEMS:
g_value_set_uint (value, gtk_sorters_get_size (&self->sorters));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gtk_multi_sorter_dispose (GObject *object)
{
@@ -352,7 +386,34 @@ gtk_multi_sorter_class_init (GtkMultiSorterClass *class)
sorter_class->compare = gtk_multi_sorter_compare;
sorter_class->get_order = gtk_multi_sorter_get_order;
object_class->get_property = gtk_multi_sorter_get_property;
object_class->dispose = gtk_multi_sorter_dispose;
/**
* GtkMultiSorter:item-type:
*
* The type of items. See [method@Gio.ListModel.get_item_type].
*
* Since: 4.8
**/
properties[PROP_ITEM_TYPE] =
g_param_spec_gtype ("item-type", NULL, NULL,
GTK_TYPE_SORTER,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
/**
* GtkMultiSorter:n-items:
*
* The number of items. See [method@Gio.ListModel.get_n_items].
*
* Since: 4.8
**/
properties[PROP_N_ITEMS] =
g_param_spec_uint ("n-items", NULL, NULL,
0, G_MAXUINT, 0,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (object_class, N_PROPS, properties);
}
static void
@@ -402,6 +463,8 @@ gtk_multi_sorter_append (GtkMultiSorter *self,
g_signal_connect (sorter, "changed", G_CALLBACK (gtk_multi_sorter_changed_cb), self);
gtk_sorters_append (&self->sorters, sorter);
g_list_model_items_changed (G_LIST_MODEL (self), gtk_sorters_get_size (&self->sorters) - 1, 0, 1);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_N_ITEMS]);
gtk_sorter_changed_with_keys (GTK_SORTER (self),
GTK_SORTER_CHANGE_MORE_STRICT,
@@ -434,6 +497,8 @@ gtk_multi_sorter_remove (GtkMultiSorter *self,
sorter = gtk_sorters_get (&self->sorters, position);
g_signal_handlers_disconnect_by_func (sorter, gtk_multi_sorter_changed_cb, self);
gtk_sorters_splice (&self->sorters, position, 1, FALSE, NULL, 0);
g_list_model_items_changed (G_LIST_MODEL (self), position, 1, 0);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_N_ITEMS]);
gtk_sorter_changed_with_keys (GTK_SORTER (self),
GTK_SORTER_CHANGE_LESS_STRICT,
+57 -5
View File
@@ -48,7 +48,9 @@ struct _GtkNoSelectionClass
enum {
PROP_0,
PROP_ITEM_TYPE,
PROP_MODEL,
PROP_N_ITEMS,
N_PROPS
};
@@ -119,6 +121,18 @@ G_DEFINE_TYPE_EXTENDED (GtkNoSelection, gtk_no_selection, G_TYPE_OBJECT, 0,
G_IMPLEMENT_INTERFACE (GTK_TYPE_SELECTION_MODEL,
gtk_no_selection_selection_model_init))
static void
gtk_no_selection_items_changed_cb (GListModel *model,
guint position,
guint removed,
guint added,
GtkNoSelection *self)
{
g_list_model_items_changed (G_LIST_MODEL (self), position, removed, added);
if (removed != added)
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_N_ITEMS]);
}
static void
gtk_no_selection_clear_model (GtkNoSelection *self)
{
@@ -126,7 +140,7 @@ gtk_no_selection_clear_model (GtkNoSelection *self)
return;
g_signal_handlers_disconnect_by_func (self->model,
g_list_model_items_changed,
gtk_no_selection_items_changed_cb,
self);
g_clear_object (&self->model);
}
@@ -162,10 +176,19 @@ gtk_no_selection_get_property (GObject *object,
switch (prop_id)
{
case PROP_ITEM_TYPE:
g_value_set_gtype (value, gtk_no_selection_get_item_type (G_LIST_MODEL (self)));
break;
case PROP_MODEL:
g_value_set_object (value, self->model);
break;
case PROP_N_ITEMS:
g_value_set_uint (value, gtk_no_selection_get_n_items (G_LIST_MODEL (self)));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -191,6 +214,18 @@ gtk_no_selection_class_init (GtkNoSelectionClass *klass)
gobject_class->set_property = gtk_no_selection_set_property;
gobject_class->dispose = gtk_no_selection_dispose;
/**
* GtkNoSelection:item-type:
*
* The type of items. See [method@Gio.ListModel.get_item_type].
*
* Since: 4.8
**/
properties[PROP_ITEM_TYPE] =
g_param_spec_gtype ("item-type", NULL, NULL,
G_TYPE_OBJECT,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
/**
* GtkNoSelection:model: (attributes org.gtk.property.get=gtk_no_selection_get_model org.gtk.Property.set=gtk_no_selection_set_model)
*
@@ -201,6 +236,18 @@ gtk_no_selection_class_init (GtkNoSelectionClass *klass)
G_TYPE_LIST_MODEL,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
/**
* GtkNoSelection:n-items:
*
* The number of items. See [method@Gio.ListModel.get_n_items].
*
* Since: 4.8
**/
properties[PROP_N_ITEMS] =
g_param_spec_uint ("n-items", NULL, NULL,
0, G_MAXUINT, 0,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (gobject_class, N_PROPS, properties);
}
@@ -263,7 +310,7 @@ void
gtk_no_selection_set_model (GtkNoSelection *self,
GListModel *model)
{
guint n_items_before;
guint n_items_before, n_items_after;
g_return_if_fail (GTK_IS_NO_SELECTION (self));
g_return_if_fail (model == NULL || G_IS_LIST_MODEL (model));
@@ -277,14 +324,19 @@ gtk_no_selection_set_model (GtkNoSelection *self,
if (model)
{
self->model = g_object_ref (model);
g_signal_connect_swapped (self->model, "items-changed",
G_CALLBACK (g_list_model_items_changed), self);
g_signal_connect (self->model, "items-changed",
G_CALLBACK (gtk_no_selection_items_changed_cb), self);
n_items_after = g_list_model_get_n_items (self->model);
}
else
n_items_after = 0;
g_list_model_items_changed (G_LIST_MODEL (self),
0,
n_items_before,
model ? g_list_model_get_n_items (self->model) : 0);
n_items_after);
if (n_items_before != n_items_after)
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_N_ITEMS]);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_MODEL]);
}
+1 -1
View File
@@ -31,7 +31,7 @@
G_BEGIN_DECLS
PangoAttrList *_gtk_pango_attr_list_merge (PangoAttrList *into,
PangoAttrList *from);
PangoAttrList *from) G_GNUC_WARN_UNUSED_RESULT;
gboolean gtk_buildable_attribute_tag_start (GtkBuildable *buildable,
GtkBuilder *builder,
+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);
+39 -31
View File
@@ -295,12 +295,49 @@ gtk_picture_get_property (GObject *object,
}
}
static void
gtk_picture_paintable_invalidate_contents (GdkPaintable *paintable,
GtkPicture *self)
{
gtk_widget_queue_draw (GTK_WIDGET (self));
}
static void
gtk_picture_paintable_invalidate_size (GdkPaintable *paintable,
GtkPicture *self)
{
gtk_widget_queue_resize (GTK_WIDGET (self));
}
static void
gtk_picture_clear_paintable (GtkPicture *self)
{
guint flags;
if (self->paintable == NULL)
return;
flags = gdk_paintable_get_flags (self->paintable);
if ((flags & GDK_PAINTABLE_STATIC_CONTENTS) == 0)
g_signal_handlers_disconnect_by_func (self->paintable,
gtk_picture_paintable_invalidate_contents,
self);
if ((flags & GDK_PAINTABLE_STATIC_SIZE) == 0)
g_signal_handlers_disconnect_by_func (self->paintable,
gtk_picture_paintable_invalidate_size,
self);
g_object_unref (self->paintable);
}
static void
gtk_picture_dispose (GObject *object)
{
GtkPicture *self = GTK_PICTURE (object);
gtk_picture_set_paintable (self, NULL);
gtk_picture_clear_paintable (self);
g_clear_object (&self->file);
g_clear_pointer (&self->alternative_text, g_free);
@@ -707,20 +744,6 @@ gtk_picture_set_pixbuf (GtkPicture *self,
g_object_unref (texture);
}
static void
gtk_picture_paintable_invalidate_contents (GdkPaintable *paintable,
GtkPicture *self)
{
gtk_widget_queue_draw (GTK_WIDGET (self));
}
static void
gtk_picture_paintable_invalidate_size (GdkPaintable *paintable,
GtkPicture *self)
{
gtk_widget_queue_resize (GTK_WIDGET (self));
}
/**
* gtk_picture_set_paintable: (attributes org.gtk.Method.set_property=paintable)
* @self: a `GtkPicture`
@@ -747,22 +770,7 @@ gtk_picture_set_paintable (GtkPicture *self,
if (paintable)
g_object_ref (paintable);
if (self->paintable)
{
const guint flags = gdk_paintable_get_flags (self->paintable);
if ((flags & GDK_PAINTABLE_STATIC_CONTENTS) == 0)
g_signal_handlers_disconnect_by_func (self->paintable,
gtk_picture_paintable_invalidate_contents,
self);
if ((flags & GDK_PAINTABLE_STATIC_SIZE) == 0)
g_signal_handlers_disconnect_by_func (self->paintable,
gtk_picture_paintable_invalidate_size,
self);
g_object_unref (self->paintable);
}
gtk_picture_clear_paintable (self);
self->paintable = paintable;
+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);
+22 -1
View File
@@ -39,6 +39,7 @@
enum {
PROP_0,
PROP_ITEM_TYPE,
PROP_N_ITEMS,
PROP_OBJECT,
PROP_PROPERTY,
NUM_PROPERTIES
@@ -184,6 +185,8 @@ gtk_property_lookup_list_model_notify_cb (GObject *object,
if (removed > 0 || added > 0)
g_list_model_items_changed (G_LIST_MODEL (self), position, removed, added);
if (removed != added)
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_N_ITEMS]);
}
static guint
@@ -318,6 +321,10 @@ gtk_property_lookup_list_model_get_property (GObject *object,
g_value_set_gtype (value, self->item_type);
break;
case PROP_N_ITEMS:
g_value_set_uint (value, gtk_property_lookup_list_model_get_n_items (G_LIST_MODEL (self)));
break;
case PROP_OBJECT:
g_value_set_object (value, gtk_property_lookup_list_model_get_object (self));
break;
@@ -366,13 +373,25 @@ gtk_property_lookup_list_model_class_init (GtkPropertyLookupListModelClass *klas
/**
* GtkPropertyLookupListModel:item-type:
*
* The `GType` for elements of this object
* The `GType` for elements of this object. See [method@Gio.ListModel.get_item_type].
*/
properties[PROP_ITEM_TYPE] =
g_param_spec_gtype ("item-type", NULL, NULL,
G_TYPE_OBJECT,
GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_EXPLICIT_NOTIFY);
/**
* GtkPropertyLookupListModel:n-items:
*
* The number of items. See [method@Gio.ListModel.get_n_items].
*
* Since: 4.8
**/
properties[PROP_N_ITEMS] =
g_param_spec_uint ("n-items", NULL, NULL,
0, G_MAXUINT, 0,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
/**
* GtkPropertyLookupListModel:property:
*
@@ -456,6 +475,8 @@ gtk_property_lookup_list_model_set_object (GtkPropertyLookupListModel *self,
g_assert (removed != 0 || added != 0);
g_list_model_items_changed (G_LIST_MODEL (self), 0, removed, added);
if (removed != added)
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_N_ITEMS]);
}
gpointer
+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
+39
View File
@@ -34,7 +34,10 @@
enum {
PROP_0,
PROP_ITEM_TYPE,
PROP_MODEL,
PROP_N_ITEMS,
NUM_PROPERTIES
};
@@ -127,6 +130,8 @@ selection_filter_model_items_changed (GtkSelectionFilterModel *self,
if (sel_removed > 0 || sel_added > 0)
g_list_model_items_changed (G_LIST_MODEL (self), sel_position, sel_removed, sel_added);
if (sel_removed != sel_added)
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_N_ITEMS]);
}
static void
@@ -178,10 +183,18 @@ gtk_selection_filter_model_get_property (GObject *object,
switch (prop_id)
{
case PROP_ITEM_TYPE:
g_value_set_gtype (value, gtk_selection_filter_model_get_item_type (G_LIST_MODEL (self)));
break;
case PROP_MODEL:
g_value_set_object (value, self->model);
break;
case PROP_N_ITEMS:
g_value_set_uint (value, gtk_selection_filter_model_get_n_items (G_LIST_MODEL (self)));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -220,6 +233,18 @@ gtk_selection_filter_model_class_init (GtkSelectionFilterModelClass *class)
gobject_class->get_property = gtk_selection_filter_model_get_property;
gobject_class->dispose = gtk_selection_filter_model_dispose;
/**
* GtkSelectionFilterModel:item-type:
*
* The type of items. See [method@Gio.ListModel.get_item_type].
*
* Since: 4.8
**/
properties[PROP_ITEM_TYPE] =
g_param_spec_gtype ("item-type", NULL, NULL,
G_TYPE_OBJECT,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
/**
* GtkSelectionFilterModel:model: (attributes org.gtk.Property.get=gtk_selection_filter_model_get_model org.gtk.Property.set=gtk_selection_filter_model_set_model)
*
@@ -230,6 +255,18 @@ gtk_selection_filter_model_class_init (GtkSelectionFilterModelClass *class)
GTK_TYPE_SELECTION_MODEL,
GTK_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
/**
* GtkSelectionFilterModel:n-items:
*
* The number of items. See [method@Gio.ListModel.get_n_items].
*
* Since: 4.8
**/
properties[PROP_N_ITEMS] =
g_param_spec_uint ("n-items", NULL, NULL,
0, G_MAXUINT, 0,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (gobject_class, NUM_PROPERTIES, properties);
}
@@ -300,6 +337,8 @@ gtk_selection_filter_model_set_model (GtkSelectionFilterModel *self,
if (removed > 0 || added > 0)
g_list_model_items_changed (G_LIST_MODEL (self), 0, removed, added);
if (removed != added)
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_N_ITEMS]);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_MODEL]);
}
+50 -4
View File
@@ -103,8 +103,10 @@ struct _GtkShortcutControllerClass
enum {
PROP_0,
PROP_ITEM_TYPE,
PROP_MNEMONICS_MODIFIERS,
PROP_MODEL,
PROP_N_ITEMS,
PROP_SCOPE,
N_PROPS
@@ -186,6 +188,18 @@ gtk_shortcut_controller_is_rooted (GtkShortcutController *self)
return gtk_widget_get_root (widget) != NULL;
}
static void
gtk_shortcut_controller_items_changed_cb (GListModel *model,
guint position,
guint removed,
guint added,
GtkShortcutController *self)
{
g_list_model_items_changed (G_LIST_MODEL (self), position, removed, added);
if (removed != added)
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_N_ITEMS]);
}
static void
gtk_shortcut_controller_set_property (GObject *object,
guint prop_id,
@@ -214,10 +228,10 @@ gtk_shortcut_controller_set_property (GObject *object,
self->custom_shortcuts = FALSE;
}
self->shortcuts_changed_id = g_signal_connect_swapped (self->shortcuts,
"items-changed",
G_CALLBACK (g_list_model_items_changed),
self);
self->shortcuts_changed_id = g_signal_connect (self->shortcuts,
"items-changed",
G_CALLBACK (gtk_shortcut_controller_items_changed_cb),
self);
}
break;
@@ -240,10 +254,18 @@ gtk_shortcut_controller_get_property (GObject *object,
switch (prop_id)
{
case PROP_ITEM_TYPE:
g_value_set_gtype (value, G_TYPE_OBJECT);
break;
case PROP_MNEMONICS_MODIFIERS:
g_value_set_flags (value, self->mnemonics_modifiers);
break;
case PROP_N_ITEMS:
g_value_set_uint (value, g_list_model_get_n_items (self->shortcuts));
break;
case PROP_SCOPE:
g_value_set_enum (value, self->scope);
break;
@@ -562,6 +584,18 @@ gtk_shortcut_controller_class_init (GtkShortcutControllerClass *klass)
controller_class->set_widget = gtk_shortcut_controller_set_widget;
controller_class->unset_widget = gtk_shortcut_controller_unset_widget;
/**
* GtkShortcutController:item-type:
*
* The type of items. See [method@Gio.ListModel.get_item_type].
*
* Since: 4.8
**/
properties[PROP_ITEM_TYPE] =
g_param_spec_gtype ("item-type", NULL, NULL,
G_TYPE_OBJECT,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
/**
* GtkShortcutController:mnemonic-modifiers: (attributes org.gtk.Property.get=gtk_shortcut_controller_get_mnemonics_modifiers org.gtk.Property.set=gtk_shortcut_controller_set_mnemonics_modifiers)
*
@@ -583,6 +617,18 @@ gtk_shortcut_controller_class_init (GtkShortcutControllerClass *klass)
G_TYPE_LIST_MODEL,
G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
/**
* GtkShortcutController:n-items:
*
* The number of items. See [method@Gio.ListModel.get_n_items].
*
* Since: 4.8
**/
properties[PROP_N_ITEMS] =
g_param_spec_uint ("n-items", NULL, NULL,
0, G_MAXUINT, 0,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
/**
* GtkShortcutController:scope: (attributes org.gtk.Property.get=gtk_shortcut_controller_get_scope org.gtk.Property.set=gtk_shortcut_controller_set_scope)
*
+43 -37
View File
@@ -103,45 +103,49 @@ static guint signals[LAST_SIGNAL] = { 0 };
static void
gtk_signal_list_item_factory_setup (GtkListItemFactory *factory,
GtkListItemWidget *widget,
GtkListItem *list_item)
GObject *item,
gboolean bind,
GFunc func,
gpointer data)
{
g_signal_emit (factory, signals[SETUP], 0, list_item);
g_signal_emit (factory, signals[SETUP], 0, item);
GTK_LIST_ITEM_FACTORY_CLASS (gtk_signal_list_item_factory_parent_class)->setup (factory, widget, list_item);
GTK_LIST_ITEM_FACTORY_CLASS (gtk_signal_list_item_factory_parent_class)->setup (factory, item, bind, func, data);
if (gtk_list_item_get_item (list_item))
g_signal_emit (factory, signals[BIND], 0, list_item);
if (bind)
g_signal_emit (factory, signals[BIND], 0, item);
}
static void
gtk_signal_list_item_factory_update (GtkListItemFactory *factory,
GtkListItemWidget *widget,
GtkListItem *list_item,
guint position,
gpointer item,
gboolean selected)
GObject *item,
gboolean unbind,
gboolean bind,
GFunc func,
gpointer data)
{
if (gtk_list_item_get_item (list_item))
g_signal_emit (factory, signals[UNBIND], 0, list_item);
if (unbind)
g_signal_emit (factory, signals[UNBIND], 0, item);
GTK_LIST_ITEM_FACTORY_CLASS (gtk_signal_list_item_factory_parent_class)->update (factory, widget, list_item, position, item, selected);
GTK_LIST_ITEM_FACTORY_CLASS (gtk_signal_list_item_factory_parent_class)->update (factory, item, unbind, bind, func, data);
if (item)
g_signal_emit (factory, signals[BIND], 0, list_item);
if (bind)
g_signal_emit (factory, signals[BIND], 0, item);
}
static void
gtk_signal_list_item_factory_teardown (GtkListItemFactory *factory,
GtkListItemWidget *widget,
GtkListItem *list_item)
GObject *item,
gboolean unbind,
GFunc func,
gpointer data)
{
if (gtk_list_item_get_item (list_item))
g_signal_emit (factory, signals[UNBIND], 0, list_item);
if (unbind)
g_signal_emit (factory, signals[UNBIND], 0, item);
GTK_LIST_ITEM_FACTORY_CLASS (gtk_signal_list_item_factory_parent_class)->teardown (factory, widget, list_item);
GTK_LIST_ITEM_FACTORY_CLASS (gtk_signal_list_item_factory_parent_class)->teardown (factory, item, unbind, func, data);
g_signal_emit (factory, signals[TEARDOWN], 0, list_item);
g_signal_emit (factory, signals[TEARDOWN], 0, item);
}
static void
@@ -156,7 +160,7 @@ gtk_signal_list_item_factory_class_init (GtkSignalListItemFactoryClass *klass)
/**
* GtkSignalListItemFactory::setup:
* @self: The `GtkSignalListItemFactory`
* @listitem: The `GtkListItem` to set up
* @object: The `GObject` to set up
*
* Emitted when a new listitem has been created and needs to be setup for use.
*
@@ -173,7 +177,7 @@ gtk_signal_list_item_factory_class_init (GtkSignalListItemFactoryClass *klass)
NULL, NULL,
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE, 1,
GTK_TYPE_LIST_ITEM);
G_TYPE_OBJECT);
g_signal_set_va_marshaller (signals[SETUP],
G_TYPE_FROM_CLASS (klass),
g_cclosure_marshal_VOID__OBJECTv);
@@ -181,13 +185,14 @@ gtk_signal_list_item_factory_class_init (GtkSignalListItemFactoryClass *klass)
/**
* GtkSignalListItemFactory::bind:
* @self: The `GtkSignalListItemFactory`
* @listitem: The `GtkListItem` to bind
* @object: The `GObject` to bind
*
* Emitted when a new [property@Gtk.ListItem:item] has been set
* on the @listitem and should be bound for use.
* Emitted when an object has been bound, for example when a
* new [property@Gtk.ListItem:item] has been set on a
* `GtkListItem` and should be bound for use.
*
* After this signal was emitted, the listitem might be shown in
* a [class@Gtk.ListView] or other list widget.
* After this signal was emitted, the object might be shown in
* a [class@Gtk.ListView] or other widget.
*
* The [signal@Gtk.SignalListItemFactory::unbind] signal is the
* opposite of this signal and can be used to undo everything done
@@ -201,7 +206,7 @@ gtk_signal_list_item_factory_class_init (GtkSignalListItemFactoryClass *klass)
NULL, NULL,
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE, 1,
GTK_TYPE_LIST_ITEM);
G_TYPE_OBJECT);
g_signal_set_va_marshaller (signals[BIND],
G_TYPE_FROM_CLASS (klass),
g_cclosure_marshal_VOID__OBJECTv);
@@ -209,9 +214,10 @@ gtk_signal_list_item_factory_class_init (GtkSignalListItemFactoryClass *klass)
/**
* GtkSignalListItemFactory::unbind:
* @self: The `GtkSignalListItemFactory`
* @listitem: The `GtkListItem` to unbind
* @object: The `GObject` to unbind
*
* Emitted when a listitem has been removed from use in a list widget
* Emitted when a object has been unbound from its item, for example when
* a listitem was removed from use in a list widget
* and its new [property@Gtk.ListItem:item] is about to be unset.
*
* This signal is the opposite of the [signal@Gtk.SignalListItemFactory::bind]
@@ -225,7 +231,7 @@ gtk_signal_list_item_factory_class_init (GtkSignalListItemFactoryClass *klass)
NULL, NULL,
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE, 1,
GTK_TYPE_LIST_ITEM);
G_TYPE_OBJECT);
g_signal_set_va_marshaller (signals[UNBIND],
G_TYPE_FROM_CLASS (klass),
g_cclosure_marshal_VOID__OBJECTv);
@@ -233,11 +239,11 @@ gtk_signal_list_item_factory_class_init (GtkSignalListItemFactoryClass *klass)
/**
* GtkSignalListItemFactory::teardown:
* @self: The `GtkSignalListItemFactory`
* @listitem: The `GtkListItem` to teardown
* @object: The `GObject` to tear down
*
* Emitted when a listitem is about to be destroyed.
* Emitted when an object is about to be destroyed.
*
* It is the last signal ever emitted for this @listitem.
* It is the last signal ever emitted for this @object.
*
* This signal is the opposite of the [signal@Gtk.SignalListItemFactory::setup]
* signal and should be used to undo everything done in that signal.
@@ -250,7 +256,7 @@ gtk_signal_list_item_factory_class_init (GtkSignalListItemFactoryClass *klass)
NULL, NULL,
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE, 1,
GTK_TYPE_LIST_ITEM);
G_TYPE_OBJECT);
g_signal_set_va_marshaller (signals[TEARDOWN],
G_TYPE_FROM_CLASS (klass),
g_cclosure_marshal_VOID__OBJECTv);
+52 -13
View File
@@ -57,9 +57,11 @@ enum {
PROP_0,
PROP_AUTOSELECT,
PROP_CAN_UNSELECT,
PROP_ITEM_TYPE,
PROP_MODEL,
PROP_N_ITEMS,
PROP_SELECTED,
PROP_SELECTED_ITEM,
PROP_MODEL,
N_PROPS
};
@@ -271,6 +273,8 @@ gtk_single_selection_items_changed_cb (GListModel *model,
}
g_list_model_items_changed (G_LIST_MODEL (self), position, removed, added);
if (removed != added)
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_N_ITEMS]);
g_object_thaw_notify (G_OBJECT (self));
}
@@ -337,10 +341,19 @@ gtk_single_selection_get_property (GObject *object,
case PROP_CAN_UNSELECT:
g_value_set_boolean (value, self->can_unselect);
break;
case PROP_ITEM_TYPE:
g_value_set_gtype (value, gtk_single_selection_get_item_type (G_LIST_MODEL (self)));
break;
case PROP_MODEL:
g_value_set_object (value, self->model);
break;
case PROP_N_ITEMS:
g_value_set_uint (value, gtk_single_selection_get_n_items (G_LIST_MODEL (self)));
break;
case PROP_SELECTED:
g_value_set_uint (value, self->selected);
break;
@@ -397,6 +410,40 @@ gtk_single_selection_class_init (GtkSingleSelectionClass *klass)
FALSE,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
/**
* GtkSingleSelection:item-type:
*
* The type of items. See [method@Gio.ListModel.get_item_type].
*
* Since: 4.8
**/
properties[PROP_ITEM_TYPE] =
g_param_spec_gtype ("item-type", NULL, NULL,
G_TYPE_OBJECT,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
/**
* GtkSingleSelection:model: (attributes org.gtk.Property.get=gtk_single_selection_get_model org.gtk.Property.set=gtk_single_selection_set_model)
*
* The model being managed.
*/
properties[PROP_MODEL] =
g_param_spec_object ("model", NULL, NULL,
G_TYPE_LIST_MODEL,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
/**
* GtkSingleSelection:n-items:
*
* The number of items. See [method@Gio.ListModel.get_n_items].
*
* Since: 4.8
**/
properties[PROP_N_ITEMS] =
g_param_spec_uint ("n-items", NULL, NULL,
0, G_MAXUINT, 0,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
/**
* GtkSingleSelection:selected: (attributes org.gtk.Property.get=gtk_single_selection_get_selected org.gtk.Property.set=gtk_single_selection_set_selected)
*
@@ -414,18 +461,8 @@ gtk_single_selection_class_init (GtkSingleSelectionClass *klass)
*/
properties[PROP_SELECTED_ITEM] =
g_param_spec_object ("selected-item", NULL, NULL,
G_TYPE_OBJECT,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
/**
* GtkSingleSelection:model: (attributes org.gtk.Property.get=gtk_single_selection_get_model org.gtk.Property.set=gtk_single_selection_set_model)
*
* The model being managed.
*/
properties[PROP_MODEL] =
g_param_spec_object ("model", NULL, NULL,
G_TYPE_LIST_MODEL,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
G_TYPE_OBJECT,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (gobject_class, N_PROPS, properties);
}
@@ -528,6 +565,8 @@ gtk_single_selection_set_model (GtkSingleSelection *self,
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SELECTED_ITEM]);
}
g_list_model_items_changed (G_LIST_MODEL (self), 0, n_items_before, 0);
if (n_items_before)
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_N_ITEMS]);
}
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_MODEL]);
+48 -2
View File
@@ -38,7 +38,9 @@
enum {
PROP_0,
PROP_ITEM_TYPE,
PROP_MODEL,
PROP_N_ITEMS,
PROP_OFFSET,
PROP_SIZE,
NUM_PROPERTIES
@@ -162,6 +164,8 @@ gtk_slice_list_model_items_changed_cb (GListModel *model,
n_before = CLAMP (n_before, self->offset, self->offset + self->size) - self->offset;
g_list_model_items_changed (G_LIST_MODEL (self), skip, n_before - skip, n_after - skip);
if (n_before != n_after)
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_N_ITEMS]);
}
}
@@ -203,10 +207,18 @@ gtk_slice_list_model_get_property (GObject *object,
switch (prop_id)
{
case PROP_ITEM_TYPE:
g_value_set_gtype (value, gtk_slice_list_model_get_item_type (G_LIST_MODEL (self)));
break;
case PROP_MODEL:
g_value_set_object (value, self->model);
break;
case PROP_N_ITEMS:
g_value_set_uint (value, gtk_slice_list_model_get_n_items (G_LIST_MODEL (self)));
break;
case PROP_OFFSET:
g_value_set_uint (value, self->offset);
break;
@@ -250,6 +262,18 @@ gtk_slice_list_model_class_init (GtkSliceListModelClass *class)
gobject_class->get_property = gtk_slice_list_model_get_property;
gobject_class->dispose = gtk_slice_list_model_dispose;
/**
* GtkSliceListModel:item-type:
*
* The type of items. See [method@Gio.ListModel.get_item_type].
*
* Since: 4.8
**/
properties[PROP_ITEM_TYPE] =
g_param_spec_gtype ("item-type", NULL, NULL,
G_TYPE_OBJECT,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
/**
* GtkSliceListModel:model: (attributes org.gtk.Property.get=gtk_slice_list_model_get_model org.gtk.Property.set=gtk_slice_list_model_set_model)
*
@@ -260,6 +284,18 @@ gtk_slice_list_model_class_init (GtkSliceListModelClass *class)
G_TYPE_LIST_MODEL,
GTK_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
/**
* GtkSliceListModel:n-items:
*
* The number of items. See [method@Gio.ListModel.get_n_items].
*
* Since: 4.8
**/
properties[PROP_N_ITEMS] =
g_param_spec_uint ("n-items", NULL, NULL,
0, G_MAXUINT, 0,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
/**
* GtkSliceListModel:offset: (attributes org.gtk.Property.get=gtk_slice_list_model_get_offset org.gtk.Property.set=gtk_slice_list_model_set_offset)
*
@@ -360,6 +396,8 @@ gtk_slice_list_model_set_model (GtkSliceListModel *self,
if (removed > 0 || added > 0)
g_list_model_items_changed (G_LIST_MODEL (self), 0, removed, added);
if (removed != added)
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_N_ITEMS]);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_MODEL]);
}
@@ -409,6 +447,8 @@ gtk_slice_list_model_set_offset (GtkSliceListModel *self,
if (before > 0 || after > 0)
g_list_model_items_changed (G_LIST_MODEL (self), 0, before, after);
if (before != after)
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_N_ITEMS]);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_OFFSET]);
}
@@ -458,9 +498,15 @@ gtk_slice_list_model_set_size (GtkSliceListModel *self,
after = g_list_model_get_n_items (G_LIST_MODEL (self));
if (before > after)
g_list_model_items_changed (G_LIST_MODEL (self), after, before - after, 0);
{
g_list_model_items_changed (G_LIST_MODEL (self), after, before - after, 0);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_N_ITEMS]);
}
else if (before < after)
g_list_model_items_changed (G_LIST_MODEL (self), before, 0, after - before);
{
g_list_model_items_changed (G_LIST_MODEL (self), before, 0, after - before);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_N_ITEMS]);
}
/* else nothing */
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SIZE]);
+40
View File
@@ -79,7 +79,9 @@
enum {
PROP_0,
PROP_INCREMENTAL,
PROP_ITEM_TYPE,
PROP_MODEL,
PROP_N_ITEMS,
PROP_PENDING,
PROP_SORTER,
NUM_PROPERTIES
@@ -580,6 +582,8 @@ gtk_sort_list_model_items_changed_cb (GListModel *model,
{
self->n_items = self->n_items - removed + added;
g_list_model_items_changed (G_LIST_MODEL (self), position, removed, added);
if (removed != added)
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_N_ITEMS]);
return;
}
@@ -620,6 +624,8 @@ gtk_sort_list_model_items_changed_cb (GListModel *model,
n_items = self->n_items - start - end;
g_list_model_items_changed (G_LIST_MODEL (self), start, n_items - added + removed, n_items);
if (removed != added)
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_N_ITEMS]);
}
static void
@@ -664,10 +670,18 @@ gtk_sort_list_model_get_property (GObject *object,
g_value_set_boolean (value, self->incremental);
break;
case PROP_ITEM_TYPE:
g_value_set_gtype (value, gtk_sort_list_model_get_item_type (G_LIST_MODEL (self)));
break;
case PROP_MODEL:
g_value_set_object (value, self->model);
break;
case PROP_N_ITEMS:
g_value_set_uint (value, gtk_sort_list_model_get_n_items (G_LIST_MODEL (self)));
break;
case PROP_PENDING:
g_value_set_uint (value, gtk_sort_list_model_get_pending (self));
break;
@@ -788,6 +802,18 @@ gtk_sort_list_model_class_init (GtkSortListModelClass *class)
FALSE,
GTK_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
/**
* GtkSortListModel:item-type:
*
* The type of items. See [method@Gio.ListModel.get_item_type].
*
* Since: 4.8
**/
properties[PROP_ITEM_TYPE] =
g_param_spec_gtype ("item-type", NULL, NULL,
G_TYPE_OBJECT,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
/**
* GtkSortListModel:model: (attributes org.gtk.Property.get=gtk_sort_list_model_get_model org.gtk.Property.set=gtk_sort_list_model_set_model)
*
@@ -798,6 +824,18 @@ gtk_sort_list_model_class_init (GtkSortListModelClass *class)
G_TYPE_LIST_MODEL,
GTK_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
/**
* GtkSortListModel:n-items:
*
* The number of items. See [method@Gio.ListModel.get_n_items].
*
* Since: 4.8
**/
properties[PROP_N_ITEMS] =
g_param_spec_uint ("n-items", NULL, NULL,
0, G_MAXUINT, 0,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
/**
* GtkSortListModel:pending: (attributes org.gtk.Property.get=gtk_sort_list_model_get_pending)
*
@@ -898,6 +936,8 @@ gtk_sort_list_model_set_model (GtkSortListModel *self,
if (removed > 0 || self->n_items > 0)
g_list_model_items_changed (G_LIST_MODEL (self), 0, removed, self->n_items);
if (removed != self->n_items)
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_N_ITEMS]);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_MODEL]);
}
+63 -5
View File
@@ -498,6 +498,16 @@ struct _GtkStackPagesClass
GObjectClass parent_class;
};
enum {
PAGES_PROP_0,
PAGES_PROP_ITEM_TYPE,
PAGES_PROP_N_ITEMS,
PAGES_N_PROPS
};
static GParamSpec *pages_properties[PAGES_N_PROPS] = { NULL, };
static GType
gtk_stack_pages_get_item_type (GListModel *model)
{
@@ -582,14 +592,53 @@ G_DEFINE_TYPE_WITH_CODE (GtkStackPages, gtk_stack_pages, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (G_TYPE_LIST_MODEL, gtk_stack_pages_list_model_init)
G_IMPLEMENT_INTERFACE (GTK_TYPE_SELECTION_MODEL, gtk_stack_pages_selection_model_init))
static void
gtk_stack_pages_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GtkStackPages *self = GTK_STACK_PAGES (object);
switch (prop_id)
{
case PAGES_PROP_ITEM_TYPE:
g_value_set_gtype (value, GTK_TYPE_STACK_PAGE);
break;
case PAGES_PROP_N_ITEMS:
g_value_set_uint (value, gtk_stack_pages_get_n_items (G_LIST_MODEL (self)));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gtk_stack_pages_init (GtkStackPages *pages)
{
}
static void
gtk_stack_pages_class_init (GtkStackPagesClass *class)
gtk_stack_pages_class_init (GtkStackPagesClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->get_property = gtk_stack_pages_get_property;
pages_properties[PAGES_PROP_ITEM_TYPE] =
g_param_spec_gtype ("item-type", NULL, NULL,
GTK_TYPE_STACK_PAGE,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
pages_properties[PAGES_PROP_N_ITEMS] =
g_param_spec_uint ("n-items", NULL, NULL,
0, G_MAXUINT, 0,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (object_class, PAGES_N_PROPS, pages_properties);
}
static GtkStackPages *
@@ -680,8 +729,11 @@ gtk_stack_dispose (GObject *obj)
while ((child = gtk_widget_get_first_child (GTK_WIDGET (stack))))
stack_remove (stack, child, TRUE);
if (priv->pages)
g_list_model_items_changed (G_LIST_MODEL (priv->pages), 0, n_pages, 0);
if (priv->pages && n_pages > 0)
{
g_list_model_items_changed (G_LIST_MODEL (priv->pages), 0, n_pages, 0);
g_object_notify_by_pspec (G_OBJECT (priv->pages), pages_properties[PAGES_PROP_N_ITEMS]);
}
G_OBJECT_CLASS (gtk_stack_parent_class)->dispose (obj);
}
@@ -1535,7 +1587,10 @@ gtk_stack_add_page (GtkStack *stack,
gtk_widget_set_parent (child_info->widget, GTK_WIDGET (stack));
if (priv->pages)
g_list_model_items_changed (G_LIST_MODEL (priv->pages), g_list_length (priv->children) - 1, 0, 1);
{
g_list_model_items_changed (G_LIST_MODEL (priv->pages), g_list_length (priv->children) - 1, 0, 1);
g_object_notify_by_pspec (G_OBJECT (priv->pages), pages_properties[PAGES_PROP_N_ITEMS]);
}
g_signal_connect (child_info->widget, "notify::visible",
G_CALLBACK (stack_child_visibility_notify_cb), stack);
@@ -1616,7 +1671,10 @@ gtk_stack_remove (GtkStack *stack,
stack_remove (stack, child, FALSE);
if (priv->pages)
g_list_model_items_changed (G_LIST_MODEL (priv->pages), position, 1, 0);
{
g_list_model_items_changed (G_LIST_MODEL (priv->pages), position, 1, 0);
g_object_notify_by_pspec (G_OBJECT (priv->pages), pages_properties[PAGES_PROP_N_ITEMS]);
}
}
/**
+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);
+44 -2
View File
@@ -34,7 +34,9 @@
enum {
PROP_0,
PROP_AUTOEXPAND,
PROP_ITEM_TYPE,
PROP_MODEL,
PROP_N_ITEMS,
PROP_PASSTHROUGH,
NUM_PROPERTIES
};
@@ -432,6 +434,8 @@ gtk_tree_list_model_items_changed_cb (GListModel *model,
tree_position,
tree_removed,
tree_added);
if (tree_removed != tree_added)
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_N_ITEMS]);
}
static void gtk_tree_list_row_destroy (GtkTreeListRow *row);
@@ -645,10 +649,18 @@ gtk_tree_list_model_get_property (GObject *object,
g_value_set_boolean (value, self->autoexpand);
break;
case PROP_ITEM_TYPE:
g_value_set_gtype (value, gtk_tree_list_model_get_item_type (G_LIST_MODEL (self)));
break;
case PROP_MODEL:
g_value_set_object (value, self->root_node.model);
break;
case PROP_N_ITEMS:
g_value_set_uint (value, tree_node_get_n_children (&self->root_node));
break;
case PROP_PASSTHROUGH:
g_value_set_boolean (value, self->passthrough);
break;
@@ -690,6 +702,18 @@ gtk_tree_list_model_class_init (GtkTreeListModelClass *class)
FALSE,
GTK_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
/**
* GtkTreeListModel:item-type:
*
* The type of items. See [method@Gio.ListModel.get_item_type].
*
* Since: 4.8
**/
properties[PROP_ITEM_TYPE] =
g_param_spec_gtype ("item-type", NULL, NULL,
G_TYPE_OBJECT,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
/**
* GtkTreeListModel:model: (attributes org.gtk.Property.get=gtk_tree_list_model_get_model)
*
@@ -700,6 +724,18 @@ gtk_tree_list_model_class_init (GtkTreeListModelClass *class)
G_TYPE_LIST_MODEL,
GTK_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY);
/**
* GtkTreeListModel:n-items:
*
* The number of items. See [method@Gio.ListModel.get_n_items].
*
* Since: 4.8
**/
properties[PROP_N_ITEMS] =
g_param_spec_uint ("n-items", NULL, NULL,
0, G_MAXUINT, 0,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
/**
* GtkTreeListModel:passthrough: (attributes org.gtk.Property.get=gtk_tree_list_model_get_passthrough)
*
@@ -1192,13 +1228,19 @@ gtk_tree_list_row_set_expanded (GtkTreeListRow *self,
{
n_items = gtk_tree_list_model_expand_node (list, self->node);
if (n_items > 0)
g_list_model_items_changed (G_LIST_MODEL (list), tree_node_get_position (self->node) + 1, 0, n_items);
{
g_list_model_items_changed (G_LIST_MODEL (list), tree_node_get_position (self->node) + 1, 0, n_items);
g_object_notify_by_pspec (G_OBJECT (list), properties[PROP_N_ITEMS]);
}
}
else
{
n_items = gtk_tree_list_model_collapse_node (list, self->node);
if (n_items > 0)
g_list_model_items_changed (G_LIST_MODEL (list), tree_node_get_position (self->node) + 1, n_items, 0);
{
g_list_model_items_changed (G_LIST_MODEL (list), tree_node_get_position (self->node) + 1, n_items, 0);
g_object_notify_by_pspec (G_OBJECT (list), properties[PROP_N_ITEMS]);
}
}
g_object_notify_by_pspec (G_OBJECT (self), row_properties[ROW_PROP_EXPANDED]);
+1 -1
View File
@@ -653,7 +653,7 @@ gtk_video_set_media_stream (GtkVideo *self,
}
/**
* gtk_video_get_file: (attributes org.gtk.Method.get_propert=file)
* gtk_video_get_file: (attributes org.gtk.Method.get_property=file)
* @self: a `GtkVideo`
*
* Gets the file played by @self or %NULL if not playing back
+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);
+37
View File
@@ -94,6 +94,10 @@
#include "wayland/gdksurface-wayland.h"
#endif
#ifdef GDK_WINDOWING_MACOS
#include "macos/gdkmacos.h"
#endif
#ifdef GDK_WINDOWING_BROADWAY
#include "broadway/gdkbroadway.h"
#endif
@@ -6264,6 +6268,27 @@ gtk_window_export_handle (GtkWindow *window,
}
}
#endif
#ifdef GDK_WINDOWING_MACOS
if (GDK_IS_MACOS_DISPLAY (gtk_widget_get_display (GTK_WIDGET (window))))
{
callback (window, NULL, user_data);
return TRUE;
}
#endif
#ifdef GDK_WINDOWING_WIN32
if (GDK_IS_WIN32_DISPLAY (gtk_widget_get_display (GTK_WIDGET (window))))
{
callback (window, NULL, user_data);
return TRUE;
}
#endif
#ifdef GDK_WINDOWING_BROADWAY
if (GDK_IS_BROADWAY_DISPLAY (gtk_widget_get_display (GTK_WIDGET (window))))
{
callback (window, NULL, user_data);
return TRUE;
}
#endif
g_warning ("Couldn't export handle for %s surface, unsupported windowing system",
G_OBJECT_TYPE_NAME (priv->surface));
@@ -6287,6 +6312,18 @@ gtk_window_unexport_handle (GtkWindow *window)
if (GDK_IS_X11_DISPLAY (gtk_widget_get_display (GTK_WIDGET (window))))
return;
#endif
#ifdef GDK_WINDOWING_MACOS
if (GDK_IS_MACOS_DISPLAY (gtk_widget_get_display (GTK_WIDGET (window))))
return;
#endif
#ifdef GDK_WINDOWING_WIN32
if (GDK_IS_WIN32_DISPLAY (gtk_widget_get_display (GTK_WIDGET (window))))
return;
#endif
#ifdef GDK_WINDOWING_BROADWAY
if (GDK_IS_BROADWAY_DISPLAY (gtk_widget_get_display (GTK_WIDGET (window))))
return;
#endif
g_warning ("Couldn't unexport handle for %s surface, unsupported windowing system",
G_OBJECT_TYPE_NAME (priv->surface));
+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);
}

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