Compare commits

...

238 Commits

Author SHA1 Message Date
Matthias Clasen 0eff31d7d5 gpu: Make GskGpuDescriptors non-objects
This is a bit involved, since we have to deal with subclassing
here, but in the end it works out ok. And it make g_object_ref
and g_object_unref disappear from the profiles.
2024-03-13 21:10:16 -04:00
Matthias Clasen 32e21d5402 Merge branch 'speedup-inner-loop' into 'main'
Simplify our inner loop

See merge request GNOME/gtk!7026
2024-03-13 12:41:43 +00:00
Marek Kasik fb3d8b8523 printing: Avoid accessing freed printers
Print backend can be disposed together with all its printers
as a reaction to user stopping enumeration of printers.
Adding a weak pointer help us to detect that the backend
was disposed and hence the backend and its printers should not
be used anymore.

Fixes #6265
2024-03-13 11:17:42 +01:00
Matthias Clasen 380523b41b gsk: Eschew more divisions
Pull out a pango_scale_inv constant, and use it.
2024-03-13 01:26:14 -04:00
Matthias Clasen 2fda256bb0 gsk: Avoid some unnecessary calls
Most of the time, the image we get for the glyphs will be the
same (the atlas), so avoid adding it to the descriptor set over
and over, and check first if have to. This matches what the
pattern variant of this function already does.
2024-03-13 01:03:32 -04:00
Matthias Clasen c71a66b6f6 gsk: Simplify our inner loop
Pull out the if-else and precompute things before the loop.
2024-03-13 01:03:31 -04:00
Matthias Clasen cb92778478 gsk: Drop the glyph-align flag
It wasn't doing anymore what it was designed for, and we are not
sure that we need it.
2024-03-13 01:00:49 -04:00
Matthias Clasen ab67936a64 Merge branch 'matthiasc/for-main' into 'main'
Drop an unused header

See merge request GNOME/gtk!7025
2024-03-13 04:44:07 +00:00
Matthias Clasen 0ae2c1a8a7 Drop an unused header
This came in with a GskPath-related merge, but it isn't used
anywhere. So drop it for now.
2024-03-12 22:14:31 -04:00
Matthias Clasen 4e166f39fe Merge branch 'matthiasc/for-main' into 'main'
Some small fixes and improvements

See merge request GNOME/gtk!7022
2024-03-12 20:52:48 +00:00
Matthias Clasen 5f79958716 gsk: Simplify some code
Just initialize the rect directly. This matches better what the
pattern variant of this method does, and it also has the nice
side-effect of eliminating the handling of negative scales in
gsk_rect_scale, which we don't need here, since our scales are

always positive.
2024-03-12 16:13:42 -04:00
Matthias Clasen aee0af34af filechooser: Assert that a string isn't NULL
It shouldn't ever be NULL, but lets make that explicit. since I've
been seeing crash reports that look like people are getting NULL
here.
2024-03-12 14:58:13 -04:00
Matthias Clasen 7e32eb2e98 entry: Add some tests for editable implementation
Test some of the editable api that is used in the filechooser
entry, since people are seeing crashes there.
2024-03-12 14:58:13 -04:00
Matthias Clasen 7ea7d5c390 Merge branch '6520_dont_drag_hidden_paned_handle' into 'main'
paned: don't claim drag-begin on invisible handle

Closes #6520

See merge request GNOME/gtk!7016
2024-03-12 15:46:53 +00:00
Matthias Clasen e3e9dda429 Merge branch 'macos_ci' into 'main'
Maintenance update for macOS Intel CI

See merge request GNOME/gtk!7005
2024-03-12 15:45:59 +00:00
Matthias Clasen a3ab25bf1d Merge branch 'wip/chergert/defer-cache-cleanup' into 'main'
gtk/textview: defer GtkTextLineDisplay finalization

See merge request GNOME/gtk!7019
2024-03-12 15:42:30 +00:00
Artur S0 095dec9238 Update Russian translation 2024-03-12 13:25:35 +00:00
Daniel Rusek 0e34365139 Update Czech translation 2024-03-12 12:40:43 +00:00
Matthias Clasen 88a62564f1 Merge branch 'matthiasc/for-main' into 'main'
Matthiasc/for main

See merge request GNOME/gtk!7020
2024-03-12 12:14:27 +00:00
Matthias Clasen 6ac94dc5c3 Post-release version bump 2024-03-12 08:12:52 -04:00
Matthias Clasen 5a9a0874bd 4.14.0 2024-03-12 07:52:13 -04:00
Matthias Clasen 91992111c3 Merge branch 'matthiasc/for-main' into 'main'
gsk: Rework font reloading again

See merge request GNOME/gtk!7018
2024-03-12 11:47:20 +00:00
Daniel Mustieles 120d874805 Update Spanish translation 2024-03-12 08:35:58 +00:00
Matthias Clasen 9454bad891 gsk: Rework font reloading again
Make a single gsk_reload_font helper that can tweak both
scale and font options, so we can ensure that our scaled
font has hint-metrics turned off (pango pays attention to
hint metrics when sizing and rendering hex boxes, and that
hurts us.
2024-03-12 00:45:14 -04:00
Christian Hergert 9cb410fd9b gtk/textview: defer GtkTextLineDisplay finalization
Defer the finalization of our GtkTextLineDisplay until we've completed
processing the current frame. Otherwise we risk doing additional work that
could cause us to miss our frame deadline.
2024-03-11 21:05:35 -07:00
Matthias Clasen 0f3fbed13c Merge branch 'wip/otte/for-main' into 'main'
Don't offscreen subsurface nodes

Closes #6499

See merge request GNOME/gtk!7009
2024-03-11 23:33:24 +00:00
Matthias Clasen 43ee9746bd Merge branch 'matthiasc/for-main' into 'main'
gsk: Avoid some roundf calls

See merge request GNOME/gtk!7017
2024-03-11 23:21:27 +00:00
Matthias Clasen 7283c5c22f gsk: Avoid some roundf calls
It seems that gcc has a hard time using intrinsics for round,
so help it out by using floor (x + .5).
2024-03-11 17:41:39 -04:00
Matthias Clasen 8b71fe4af6 Add an xfail for a rounded-clip test
This needs some changes in how we prevent offscreens from getting
too big. Filed as #6532.
2024-03-11 17:08:33 -04:00
René de Hesselle b627fb5970 ci: Install ninja from wheel for Big Sur runner
This avoids building it on the Big Sur Intel runner (because of
Python 3.8) which would require us to provide cmake.
2024-03-11 21:30:37 +01:00
Matthias Clasen be3ad1ef99 Merge branch 'wip/chergert/fix-6529' into 'main'
gtk/imcontext: fix ABI break via activate_osk_with_event

Closes #6529

See merge request GNOME/gtk!7015
2024-03-11 20:15:35 +00:00
g.willems 54264a9f78 paned: don't claim drag-begin on invisible handle
Paned handles are hidden when any of its children are hidden too,
but drag events were still accepted around the (virtual) handle position.

Instead, deny drag-begin when handle is hidden.

Fixes #6520
Closes #6520
2024-03-11 20:39:47 +01:00
Matthias Clasen 65380c66bd Merge branch 'matthiasc/for-main' into 'main'
label: Don't forget to clear select info

See merge request GNOME/gtk!7012
2024-03-11 19:35:51 +00:00
Matthias Clasen 8c96991ce0 Merge branch 'text-view-cursor-blink' into 'main'
textview: Match cursor blink behavior of GtkText

Closes #6515

See merge request GNOME/gtk!7014
2024-03-11 19:13:09 +00:00
Christian Hergert 07a44993ac gtk/imcontext: fix ABI break via activate_osk_with_event
Fixes #6529
2024-03-11 12:06:22 -07:00
Matthias Clasen 60d2d25463 Merge branch 'wip/public-activate-osk' into 'main'
gtkimcontext: Make gtk_im_context_activate_osk() public

See merge request GNOME/gtk!7013
2024-03-11 17:59:42 +00:00
Carlos Garnacho 907f99b176 gtkimcontextwayland: Drop the implicit gesture
Expect all users to call gtk_im_context_activate_osk() to get
on-screen keyboard features.
2024-03-11 18:04:16 +01:00
Carlos Garnacho ce6aa73c64 gtkimcontext: Make gtk_im_context_activate_osk() public
Make this API public so that foreign "text" widgets (e.g. VteTerminal)
have a chance to integrate this logic into their own event controllers,
without having to craft the behavior of their own gestures around the
built-in IM gesture.

In order to make it most useful for other backends, a GdkEvent argument
and a boolean return value were added. This might be useful information
for other platforms than Wayland, e.g. all investigation seems to hint
that on Windows only the a11y keyboard is available programmatically
via app launching, so the IM method implementation would need to set
up its own policies for showing up the OSK (e.g. on touch events).
2024-03-11 18:04:14 +01:00
Matthias Clasen 257bef85d0 textview: Match cursor blink behavior of GtkText
This makes the conditions in cursor_blinks() more similar to
what GtkText does, and fixes adds the same notify handler for
has-focus, so we start blinking when requires. Crucially, we
also no longer try to blink when unmapped, which should fix
a epiphany crash.

Fixes: #6515
2024-03-11 11:34:40 -04:00
Matthias Clasen a48df87a85 label: Don't forget to clear select info
This was showing up as crashes in the testsuite, where a later
test runs the mainloop, and that causes Wayland to claim the
primary selection on a widget that is already disposed.
2024-03-11 08:31:41 -04:00
Matthias Clasen fe4cd7cf0f Merge branch 'matthiasc/for-main' into 'main'
Add more offload tests

See merge request GNOME/gtk!7010
2024-03-11 02:31:13 +00:00
Matthias Clasen 229b34d478 Add more offload tests
These test various clip scenarios.
2024-03-10 22:08:44 -04:00
Benjamin Otte 1985f2c9ad gpu: Make intersecting rounded rect with NONE clip always succeed
This is a tricky topic, because it can make the clip bounds grow, so
previously we were trying to be careful.

However, this can cause perfectly trivial intersections to fail that are
caused by redraw diff regions.
And in the worst case, that means we offscreen in places where we
absolutely do not want to offscreen - in subtrees with subsurface nodes.

Fixes #6499
2024-03-11 01:39:40 +01:00
Benjamin Otte 01d57a7566 gpu: Initial clip is always NONE
We scissor the initial clip (which is why it's an integer rect that is
assigned to the scissor). And if we scissor, the result is a NONE clip.
2024-03-11 01:39:40 +01:00
Benjamin Otte 7a4b2c10c7 gpu: contained clip is a rectangular clip, too
So we can treat it like rect clip and promote it to NONE after a
successful scissor.
2024-03-11 01:39:40 +01:00
Benjamin Otte 208b2d37b6 gpu: Clarify clip types
CLIP_TYPE_NONE is valid if the clip is implemented by the scissor rect.

We always have a scissor rect and there's no way to draw outside of it.

In theory that means we can reset the clip to NONE at any point we
wish if we know nodes are contained inside a certain pixel-aligned
rectangle we can clip.
In practice that's probably quite hard...
2024-03-11 01:39:40 +01:00
Benjamin Otte ef98912779 nodeparser: Print subsurface nodes properly
The nodes actually end.

Tests included.
2024-03-11 01:39:40 +01:00
Matthias Clasen b1e3b18ede Merge branch 'matthiasc/for-main' into 'main'
ci: Add more xfails

See merge request GNOME/gtk!7007
2024-03-10 23:57:42 +00:00
Matthias Clasen 0194cadbc0 ci: Add more xfails
The gradient tests are prone to rounding errors when clipped,
so fail them.
2024-03-10 16:53:12 -04:00
Matthias Clasen b4dfc4adfc NEWS: Updates 2024-03-10 13:45:57 -04:00
Ask Hjorth Larsen fd556ec377 Update Danish translation 2024-03-10 17:33:33 +00:00
Matthias Clasen 1dbc1d67f5 Merge branch 'wip/otte/correct-fps' into 'main'
Fix fps display

See merge request GNOME/gtk!7003
2024-03-10 17:31:46 +00:00
Balázs Úr 8790c83a76 Update Hungarian translation 2024-03-10 15:56:09 +00:00
Brage Fuglseth 6b202fb838 Update Norwegian Bokmål translation 2024-03-10 13:15:47 +00:00
Fran Dieguez f69476435f Update Galician translation 2024-03-10 10:34:28 +00:00
Benjamin Otte 8df6e2cdaf frameclock: Make timings history dynamic
Keep at least 1 second of frame timings.

This is necessary for 2 reasons - a real one and a fun one.

First, with the difference in monitor refresh rates, we can have 48Hz
latops as well as 240Hz high refresh rate monitors. That's a factor of
4, and tracking frame rates in both situations reliably is kind of hard
- either we track over too many frames and the fps take a lot of time to
adjust, or we track too little time and the fps fluctuate wildly.

Second, when benchmarking with GDK_DEBUG=no-vsync with a somewhat fast
renderer (*cough*Vulkan*cough*) frame rates can go into insane dimensions
and only very few frames are actually getting presentation times
reported. So to report accurate frame rates in those cases, we need a
*very* large history that can be 1000s of times larger than the usual
history. And that's just a waste for normal usage.
2024-03-10 10:27:36 +01:00
Benjamin Otte 2861ab38ac frameclock: Report accurate fps instead of too low
Previously, our reported fps numbers could be too low when the start
timings weren't complete. In that case we would use the frame time, but
the frame time is the time when the frame was rendered, which is quite a
few milliseconds before it is presented.

So in that case we would not report the difference in presentation
times, but the difference from start of rendering. However, those times
are way more variable and can smear over the whole frame because they
depend on when we received the frame callbacks to high priority GSources
as well as our own render time predictions.

This happened in particular with GDK_DEBUG=no-vsync and could report
number that are off by a factor of 2.

Now we skip any incomplete frames, because those frames never have
presentation times reported. This makes it theoretically more likely to
not being able to report fps at all, but I'd rather have no fps than fps
off by a factor of 2.
2024-03-10 10:27:36 +01:00
Benjamin Otte 23c2122c13 inspector: Handle more digits in fps overlay
The fps used to get garbled when hitting >=10,000fps. That's quite
unlikely to happen for long periods, but it can happen for short bursts
(like after alt-tabbing).

So just handle more digits to make the display survive those corner cases.
2024-03-10 10:27:36 +01:00
Benjamin Otte 5b83ffa4a0 inspector: Make background width match fps number
Previously, we drew the same width no matter how many digits the fps
number had, which left a lot of empty space.

But we can use some quite simple math to avoid that by just shrinking
the background by the width of the non-rendered glyphs.
2024-03-10 10:27:35 +01:00
Matthias Clasen cf8e3157a7 Merge branch 'matthiasc/for-main' into 'main'
Add another path fill test

Closes #4553 and #5423

See merge request GNOME/gtk!7001
2024-03-09 18:21:19 +00:00
Matthias Clasen 7323172755 ci: Add xfails for gl rotation+opacity problems
These are the topic of #6525. Lets xfail them for now.
2024-03-09 13:02:56 -05:00
Matthias Clasen cfee8f4b11 tests: Cosmetics 2024-03-09 12:43:33 -05:00
Matthias Clasen 7ae099c94c inspector: Tweak the size groups page
Make the page scroll, and modernize it slightly. Also, fix a
case of missing top margin.

Fixes: #4553
2024-03-09 12:43:33 -05:00
Matthias Clasen 42298d8ab1 inspector: Deal with long action names
Make the action list scroll horizontally, and make the name
column resizable.

Fixes: #5423
2024-03-09 12:43:33 -05:00
Matthias Clasen 68912698f1 inspector: Drop the Window Scale spin
We don't really expect backends to make this settable, and
fractional scaling makes this more complicated anyway. The
scale values can be seen on the General tab, for the monitor,
and on the surface for each toplevel.
2024-03-09 12:43:33 -05:00
Matthias Clasen c8c56f8d42 inspector: Use GtkFontDialogButton
A small step towards respecting our own deprecations. While we
are at it, make the control only select the font family, since
that is the intention of the font setting. Font style and size
are under the control of the css, and we have a font scale slider
right below to influence font size globally.
2024-03-09 12:43:33 -05:00
Matthias Clasen 7f48b5a05c inspector: Show the linux dmabuf Wayland protocol
This was overlooked when dmabuf support was added.
2024-03-09 12:43:33 -05:00
Matthias Clasen 1e5e977b37 gsk: Minor reshuffling
Hide the temporary unhinted font object behind the private API.
There might be a way to implement this without instantiating a
font, at some point.
2024-03-09 12:43:33 -05:00
Matthias Clasen 62d44b6bc7 wayland: Add window sizes to debug spew
This may help for tracking down issues.
2024-03-09 12:43:33 -05:00
Matthias Clasen 862afeffe0 Add another path fill test
This uses the other fill rule.
2024-03-09 07:03:55 -05:00
Matthias Clasen 92f9195015 Merge branch 'matthiasc/for-main' into 'main'
Update the docs for gtk-xft-rgba

See merge request GNOME/gtk!7000
2024-03-09 04:50:09 +00:00
Matthias Clasen fc6e08082b tests: Make compare-render less repetitive
Only run the unmodified comparison if --plain is passed
on the commandline.
2024-03-08 22:27:14 -05:00
Matthias Clasen af7516b797 Update the docs for gtk-xft-rgba
Clarify that this setting has no effect.
2024-03-08 21:37:10 -05:00
Matthias Clasen 3f1821e372 Merge branch 'matthiasc/for-main' into 'main'
gsk: Make uber shader handle fonts the same

See merge request GNOME/gtk!6995
2024-03-09 02:19:25 +00:00
Matthias Clasen b569470b87 Stop setting rgb antialiasing in font options
We don't support subpixel antialiasing, so setting font options
to that effect won't do any good.
2024-03-08 20:44:42 -05:00
Matthias Clasen f1a3235039 Add tests for uber rendering
Add a --colorflip option to the compare-render test. This applies
a color matrix to the node, which has the intended side-effect of
convincing the Vulkan renderer to use its uber shader, so we get
test results comparing the uber output to its non-uber siblings.
2024-03-08 20:44:42 -05:00
Matthias Clasen 34e90005af Don't forget to unrealize the renderer
This causes a critical warning.
2024-03-08 20:44:42 -05:00
Matthias Clasen 4f1cc8ec6d gsk: Make uber shader handle fonts the same
The code converting text nodes for the uber shader was missing
some of the recent font handling improvements. Make things match.

Related: #6514
2024-03-08 20:44:42 -05:00
Matthias Clasen 5242205a65 gsk: Ignore transforms for font handling
We were turning off hinting and subpixel positioning if the
transform isn't 2D affine. The idea behind this was that transforms
likely indicate animations, and for animations, this may reduce
jitter. But the heuristic of transform==animation is not very
reliable, and we pay for this with a jump from hinted to unhinted
at the beginning and end of it. Also, the heuristic does not even
work for the most relevant 'animation' we have today: scrolling.

So, lets drop this for now. We can revisit it later.
2024-03-08 20:44:42 -05:00
Matthias Clasen 59633a6781 Add an xfail
This is causing sporadic ci failures, so file an issue and xfail it.
2024-03-08 20:44:42 -05:00
Matthias Clasen d82316edda Merge branch 'cache-get-hinted-font' into 'main'
gsk: cache sequentially requested hinted fonts

See merge request GNOME/gtk!6999
2024-03-09 01:10:18 +00:00
Matthias Clasen 0815640b22 Merge branch 'mark-for-dropped-frames' into 'main'
gdk/frameclock: add mark when we discover frames may drop

See merge request GNOME/gtk!6998
2024-03-09 01:03:13 +00:00
Matthias Clasen 26de2eae20 Merge branch 'ngl-buffer-upload-counter' into 'main'
add counter for ngl buffer uploads

See merge request GNOME/gtk!6997
2024-03-08 23:50:03 +00:00
Matthias Clasen 8fa358c4d4 Merge branch 'avoid-extraneous-uploads' into 'main'
gsk/gpu: avoid unnecessary buffer uploads

See merge request GNOME/gtk!6996
2024-03-08 23:48:52 +00:00
Christian Hergert fc72449228 gsk: cache sequentially requested hinted fonts
When getting the hinted version of fonts, they often come in sequentially.
This helps reduce overhead in many sequential gtk_text_node_new() on with
fractional scaling as you see from GtkSourceView.
2024-03-08 15:40:26 -08:00
Christian Hergert 84a304e66e gdk/frameclock: add mark when we discover frames may drop
If we discover that some number of frames have passed that perhaps should
not have, leave a mark for the profiler.
2024-03-08 14:41:59 -08:00
Christian Hergert ecf1b7c18a gsk/gpu: add counter for ngl buffer uploads
It's helpful to know how much we're uploading from Sysprof captures.
2024-03-08 14:17:31 -08:00
Christian Hergert a7c5b53f46 gsk/gpu: avoid unnecessary buffer uploads
Some maps are used for read only and do not require uploading contents
back to the GPU afterwards. In other cases, we can often upload less than
the fully allocated buffer size.
2024-03-08 13:55:57 -08:00
Rūdolfs Mazurs 09736dde93 Update Latvian translation 2024-03-08 21:02:45 +00:00
Matthias Clasen 66c00dc9f3 Merge branch 'docs-iconcache' into 'main'
docs/iconcache.txt: fix ICON_FLAGS

Closes #6489

See merge request GNOME/gtk!6993
2024-03-08 16:20:55 +00:00
Kirill Primak 3eacf8bd39 docs/iconcache.txt: fix ICON_FLAGS
The documented icon flags didn't match the actual constants used by GTK when
reading and updating icon theme cache files. Fix the values of flags in the
documentation.

Closes: https://gitlab.gnome.org/GNOME/gtk/-/issues/6489
2024-03-08 18:42:11 +03:00
Matthias Clasen 34e9ef9e78 Merge branch 'fix-foreign-check' into 'main'
Fix xdg-foreign check

See merge request GNOME/gtk!6994
2024-03-08 14:20:50 +00:00
Ivan Molodetskikh a5955106ea Fix xdg-foreign check
It was checking for xdg-foreign v1 instead of "v1 or v2".
2024-03-08 17:28:35 +04:00
Andika Triwidada ea0cfed735 Update Indonesian translation 2024-03-07 08:44:46 +00:00
Matthias Clasen f312d1ee6a Merge branch 'gtk-at-spi-context-typo' into 'main'
Fix documentation typo

See merge request GNOME/gtk!6991
2024-03-07 04:30:53 +00:00
Robert Ancell 69b6f4cf4f Fix documentation typo 2024-03-07 15:17:33 +13:00
Matthias Clasen d7e1c377fe Merge branch 'matthiasc/for-main' into 'main'
ci: Update xfails

See merge request GNOME/gtk!6990
2024-03-07 01:56:05 +00:00
Matthias Clasen cc17577763 Merge branch 'fix-emoji-pres' into 'main'
emoji: Fix presentation selector handling

See merge request GNOME/gtk!6986
2024-03-07 00:23:41 +00:00
Matthias Clasen ef4ae61c66 ci: Update xfails
A number of the xfails that were added for the new renderers have
been fixed.
2024-03-06 19:03:43 -05:00
Matthias Clasen e04ea3f311 Merge branch 'fix-mis-scaled-text' into 'main'
gsk: Fix mis-scaled text rendering

Closes #6504

See merge request GNOME/gtk!6977
2024-03-06 23:22:42 +00:00
Matthias Clasen 77a2cd4d8d gsk: Fix mis-scaled text rendering
This was happening when rotated text was partially redrawn.

A test that failed before this change is included.

Fixes: #6504
2024-03-06 17:52:35 -05:00
Matthias Clasen 0986981d1a gpu: Empty clip is still empty after transform
When transforming an empty clip, it stays empty.

Previously, we were setting it to CONTAINED, but that's wrong, because
the bounds are not contained in the clip, the clip is contained in the bounds.

This reverts part of commit a51c6aed47.

Related: !6692
2024-03-06 17:52:22 -05:00
Benjamin Otte 913f850f83 Merge branch 'wip/otte/for-main' into 'main'
Update "snapshot: linear-gradients cannot be affine-transformed"

See merge request GNOME/gtk!6989
2024-03-06 22:44:48 +00:00
Benjamin Otte ed31da3730 Update "snapshot: linear-gradients cannot be affine-transformed"
This is a better fix for commit 7ed6c39862.

The linear-gradient-nonorthogonal-linear-gradient test tests this.

Related: !6692
2024-03-06 22:35:30 +01:00
Benjamin Otte 428ff6c4ab Merge branch 'wip/otte/for-main' into 'main'
snapshot: Fix wrong nodes with transformed shadows

See merge request GNOME/gtk!6988
2024-03-06 21:06:49 +00:00
Benjamin Otte 53786841cc snapshot: Fix wrong nodes with transformed shadows
Test included.

The test is disabled for Cairo because the Cairo blurring code can't
deal with scaling, which makes things come out wrong for the test that
checks that we do the right thing with the blur radius when scaling.

Related: !6977
2024-03-06 21:52:16 +01:00
Vincent Chatelain 8f8ece44a8 Update French translation 2024-03-06 19:00:59 +00:00
Anders Jonsson 41a892b958 Update Swedish translation 2024-03-06 17:50:54 +00:00
Baurzhan Muftakhidinov b494ed5876 Update Kazakh translation 2024-03-06 03:10:20 +00:00
Josh Brobst 7b589f991d emoji: Fix presentation selector handling
The emoji presentation selector (FE0F) was being appended to every emoji
sequence inserted by GtkEmojiChooser and GtkEmojiCompletion, often
leading to invalid sequences. Modify the emoji data to include FE0F
only when necessary, and change skin tone handling to account for cases
where the generic (no tone) variation needs a presentation selector.
2024-03-05 18:44:55 -05:00
Christian Hergert d83faf82d7 Merge branch 'macos-move-maximized' into 'main'
macos: Fix moving maximized windows

Closes #6436

See merge request GNOME/gtk!6914
2024-03-05 21:53:26 +00:00
Matthias Clasen cd46016238 Merge branch 'preserve-font-dpi' into 'main'
gsk: Preserve dpi when modifying fonts

Closes #6508

See merge request GNOME/gtk!6985
2024-03-05 21:43:00 +00:00
Matthias Clasen f2a3218455 Merge branch 'wip/chergert/fix-textviewchild-double-draw' into 'main'
textview: only snapshot GtkTextViewChild once

See merge request GNOME/gtk!6984
2024-03-05 21:37:37 +00:00
Matthias Clasen 85b1959714 Merge branch 'wip/fl/macos-cursor-from-texture' into 'main'
gdk: Implement cursor from texture on MacOS

See merge request GNOME/gtk!6981
2024-03-05 21:34:30 +00:00
Matthias Clasen b23600ae4b gsk: Preserve dpi when modifying fonts
When scaling a font or changing font options, we need to be
careful to preserve the dpi as well, otherwise the rendering
might leak out of the node bounds, leading to spectacular
glitches.

Fixes: #6508
2024-03-05 16:22:26 -05:00
Christian Hergert bdc43b8fca textview: only snapshot GtkTextViewChild once
This was causing double snapshotting of textview children because the
parent snapshot will also iterate and snapshot children.
2024-03-05 11:41:11 -08:00
Matthias Clasen da2ef6911f Merge branch 'ebassi/accessible-text-util' into 'main'
Rename GtkAccessibleText private header

See merge request GNOME/gtk!6982
2024-03-05 13:23:11 +00:00
Emmanuele Bassi 0626246367 a11y: Add utilify method for text attributes
Simplify the AT-SPI implementation by having a convenience function to
extract the text attributes of a GtkAccessibleText, with or without the
default attributes.
2024-03-05 12:23:17 +00:00
Matthias Clasen 0edfafdfdf Merge branch 'macos-maximized-window' into 'main'
macos: Fix window state of initially maximized windows

Closes #5898

See merge request GNOME/gtk!6882
2024-03-05 11:35:49 +00:00
Bruce Cowan 1863b79fb3 Update British English translation 2024-03-05 11:35:24 +00:00
Emmanuele Bassi 9aa90f8df0 Rename GtkAccessibleText private header
Follow the existing naming convention, and drop the hyphen.
2024-03-05 11:00:20 +00:00
Fabio Lagalla 8080d9e7c1 gdk: Implement cursor from texture on MacOS
This is done with a NSCursor whose content is an NSImage. Image pixels are filled by a NSBitmap, and the format is premultiplied RGBA. So we can just use the texture downloader with GDK_MEMORY_R8G8B8A8_PREMULTIPLIED format.
2024-03-05 10:26:27 +01:00
Matej Urbančič f432ee775f Update Slovenian translation 2024-03-04 21:51:10 +00:00
Matthias Clasen 77f9cb11a9 Merge branch 'wip/chergert/for-main' into 'main'
gsk/gpu: add profiler node for shader loading

See merge request GNOME/gtk!6978
2024-03-04 21:36:37 +00:00
Asier Sarasua Garmendia d92e3cb864 Update Basque translation 2024-03-04 19:58:53 +00:00
Matthias Clasen 733fa156b9 Merge branch 'ebassi/accessible-text-default-attrs' into 'main'
a11y: Add GtkAccessibleText.get_default_attributes

See merge request GNOME/gtk!6973
2024-03-04 19:54:33 +00:00
Christian Hergert d181d53762 gsk/gpu: add profiler node for shader loading
This is helpful when tracking down why a frameclock cycle took so long. In
quick recordings it seems to often correlate with a shader compile.
2024-03-04 11:54:13 -08:00
Emmanuele Bassi 644e6f8ebe Consolidate TextView/TextBuffer attribute serialization
Use dictionaries of string pairs instead of abusing GVariant; we can
convert the dictionary into a GVariant when we send the data over the
wire.
2024-03-04 19:13:29 +00:00
Matthias Clasen 0b4c695d65 Merge branch 'hinting-proper-positioning' into 'main'
gsk: Handle hinted fonts better

Closes #6502

See merge request GNOME/gtk!6966
2024-03-03 23:27:00 +00:00
Matthias Clasen 448287bd58 Merge branch 'camelCaseNick/a11y-text-contents-at' into 'main'
a11y: implement get_contents_at for Gtk.Text, Gtk.TextView, Gtk.Inscription

See merge request GNOME/gtk!6971
2024-03-03 23:03:13 +00:00
Benjamin Otte 5e6aff69c6 Merge branch 'wip/otte/for-main' into 'main'
demos: shadertoy only handles GL

See merge request GNOME/gtk!6976
2024-03-03 22:38:22 +00:00
Benjamin Otte d88e616711 demos: shadertoy only handles GL
If somebody wants to add GLES support, go for it.

For now we enforce GL.
2024-03-03 22:20:44 +00:00
Aurimas Černius 0e5c94a094 Update Lithuanian translation 2024-03-03 20:47:02 +00:00
Brage Fuglseth bb0aeec99c Update Norwegian Bokmål translation 2024-03-03 20:08:02 +00:00
Matthias Clasen 880e3ef289 Add tests for glyph positioning
These tests check that we round glyph positions to integral device
pixel coordinates when hinting is enabled, and to device subpixel
positions if it isn't.
2024-03-03 14:28:19 -05:00
Sabri Ünal 94a09263d7 Update Turkish translation 2024-03-03 18:22:30 +00:00
Markus Göllnitz ab9106ac89 testsuite: test for implementation of accessible_text_get_contents_at
Signed-off-by: Markus Göllnitz <camelcasenick@bewares.it>
2024-03-03 19:13:40 +01:00
Markus Göllnitz ff6451a77e a11y: implement get_contents_at for Gtk.TextView
Signed-off-by: Markus Göllnitz <camelcasenick@bewares.it>
2024-03-03 19:13:40 +01:00
Matthias Clasen 4f2d63b8ac gsk: Handle hinted fonts better
Enforce the following rules:
- No hinting or subpixel positioning in transformed context
- glyph-align determines if we use integral or fractional
  device pixel positions
- For hinting, always use an integral y position (the hinter
  assumes integral positions, and only operates vertically).
2024-03-03 13:08:29 -05:00
Matthias Clasen 81c97f0910 gsk: Add a private helper
Add a function to get the hint style of a font.
2024-03-03 13:08:29 -05:00
Matthias Clasen d1b52cc292 gsk: Preserve the antialiasing setting of the font
When we get an unhinted font for text node extents, don't change
the antialiasing setting. It doesn't affect the extents we get
here, but if we later need an unhinted font for rendering, the
one we create this way will be the right one, so it will already
exist.
2024-03-03 13:08:29 -05:00
Matthias Clasen ddedb39329 gsk: Tweak gsk_get_hinted_font slightly
Make it possible to preserve some of the fonts original options.
2024-03-03 13:08:29 -05:00
Matthias Clasen d45987e637 Merge branch 'fallback-to-gl+llvmpipe' into 'main'
Don't fall back to cairo for software rendering

See merge request GNOME/gtk!6975
2024-03-03 17:54:07 +00:00
Matthias Clasen b95eceea60 Don't fall back to cairo for software rendering
The experience with gl+llvmpipe is not great, in particular on
fractional scales. But it is less broken than cairo in that
situation.
2024-03-03 12:28:20 -05:00
Emmanuele Bassi 2774e80fc4 a11y: Ensure that attributes are unique before sending them
The default attributes are overridden by the run attributes.
2024-03-03 17:08:39 +00:00
Matthias Clasen 7c207c4868 Merge branch 'matthiasc/for-main' into 'main'
Improve subpixel positioning tests

See merge request GNOME/gtk!6974
2024-03-03 16:33:46 +00:00
Matthias Clasen c6c8abcf21 Improve subpixel positioning tests
We want to test subpixel positioning, so turn off hinting, since
hinting and subpixel positioning are opposing forces.

This does not currently change test outcomes, but it will prevent
the tests from breaking in the future when we make changes to
improve hinting.
2024-03-03 11:19:04 -05:00
Emmanuele Bassi a59c967675 a11y: Implement AtspiText.GetDefaultAttributes
The new GtkAccessibleText.get_default_attributes() vfunc gives us the
ability to implement this AT-SPI method.
2024-03-03 15:17:53 +00:00
Emmanuele Bassi c3329f5fcc a11y: Implement AtspiText.GetAttributeRun for AccessibleText
GetAttributeRun works like GetAttributes, but it allows including the
default text attributes.

See: !6971, GNOME/orca#477
2024-03-03 15:17:53 +00:00
Emmanuele Bassi 4f06e46759 a11y: Implement get_default_attributes for TextView 2024-03-03 15:17:53 +00:00
Emmanuele Bassi 7e522a8c55 a11y: Implement get_default_attributes for Text 2024-03-03 15:17:52 +00:00
Emmanuele Bassi d9447fd2e7 a11y: Implement get_default_attributes for Label 2024-03-03 15:17:52 +00:00
Emmanuele Bassi 95214f3697 a11y: Implement get_default_attributes for Inscription 2024-03-03 15:17:52 +00:00
Emmanuele Bassi fe64c998f8 a11y: Add GtkAccessibleText.get_default_attributes
Accessible text attributes come in two flavours:

- the run attributes, which apply to a text from a given offset
- the default attributes, which apply to the whole text

The default attributes are used to gather the initial values for every
text attribute, while the run attributes operate additively.

We currently have a getter for the former, but we lack one for the
latter.
2024-03-03 15:17:52 +00:00
Markus Göllnitz 84582ad762 a11y: implement get_contents_at for Gtk.Inscription
Signed-off-by: Markus Göllnitz <camelcasenick@bewares.it>
2024-03-03 15:52:26 +01:00
Matthias Clasen fcc7a58058 Merge branch 'gst-cmp-float' into 'main'
gstreamer: Use G_APPROX_VALUE to compare floats

See merge request GNOME/gtk!6972
2024-03-03 14:16:47 +00:00
Matthias Clasen 8a48becb7e Cosmetics 2024-03-03 08:56:32 -05:00
Robert Mader 465446430e gstreamer: Use G_APPROX_VALUE to compare floats
Mainly to silence compiler warnings.
2024-03-03 14:35:27 +01:00
Luming Zh 4060c43ae7 Update Chinese (China) translation 2024-03-03 11:17:20 +00:00
Markus Göllnitz 4ec9a2a330 a11y: implement get_contents_at for Gtk.Text
There are users of GetStringAtOffset, such as Orca.

Signed-off-by: Markus Göllnitz <camelcasenick@bewares.it>
2024-03-03 04:37:01 +01:00
Matthias Clasen 90c017a762 Merge branch 'matthiasc/for-main' into 'main'
Grr, vulkan

See merge request GNOME/gtk!6970
2024-03-03 03:03:19 +00:00
Matthias Clasen e011434223 Update tests for version number bump 2024-03-02 22:02:36 -05:00
Matthias Clasen b1ccb4103d Grr, vulkan
The can always make it worse with another define.
2024-03-02 21:47:49 -05:00
Matthias Clasen 8033809f8b Merge branch 'matthiasc/for-main' into 'main'
vulkan: Add another error code

See merge request GNOME/gtk!6969
2024-03-03 01:26:44 +00:00
Matthias Clasen 66ba1f76ba vulkan: Add another error code
Handle VK_ERROR_INVALID_VIDEO_STD_PARAMETERS_KHR.
2024-03-02 20:20:16 -05:00
Matthias Clasen 0ca822c716 Merge branch 'matthiasc/for-main' into 'main'
4.13.9

See merge request GNOME/gtk!6968
2024-03-03 00:57:14 +00:00
Matthias Clasen 4ac288c1b4 Post-release version build 2024-03-02 19:56:09 -05:00
Matthias Clasen 64316ab185 4.13.9 2024-03-02 19:30:26 -05:00
Matthias Clasen 4d90a693ae Merge branch 'scaled-font' into 'main'
gsk: Use a scaled font for glyph rendering

See merge request GNOME/gtk!6936
2024-03-03 00:23:43 +00:00
Matthias Clasen 0c5f943783 Merge branch 'matthiasc/for-main' into 'main'
NEWS: Updates

See merge request GNOME/gtk!6967
2024-03-02 23:54:29 +00:00
Matthias Clasen 42fc165b94 Add glyph hinting tests
Add tests that demonstrate different rendering with and without
hinting, to prove that hinting has an effect.
2024-03-02 18:41:06 -05:00
Matthias Clasen 20a4e3f351 Add glyph antialiasing test
This test checks that the antialias font option has the indended
effect.
2024-03-02 18:41:02 -05:00
Matthias Clasen f3f90e1d71 Add a glyph scaling test
The glyph in this test has extents that will be made smaller
by hinting, which poses some challenge for our renderers.

The scaled glyph rendering is too big for the 'small texture'
text setup, so we allow the test to fail there.
2024-03-02 18:39:14 -05:00
Matthias Clasen b018da2acd gsk: Accept font options in node files
The goal is to fix all the context that influences the rendering
of text nodes in the node file. This will help with better font
testing.

The newly accepted properties are

hint-style: none/slight/full
antialias: none/gray

We are omitting font options and values that aren't supported
in GSK or have no influence on the rendering.

Note that these settings will get incorporated in the PangoFont
that gets set on the resulting text node.

Parser tests included.
2024-03-02 18:39:14 -05:00
Matthias Clasen ab5f3f59ce gsk: Use unhinted extents for text nodes
We need precise bounds. And while hinting might shift the rendering
around from these bounds by a fraction of a pixel, we account for
this in the places where it matters: when determining diff regions,
when sizing offscreens, and when determining the size of atlas
regions for glyphs.
2024-03-02 18:39:14 -05:00
Matthias Clasen 0127217e10 gsk: Add a way to get a (un)hinted font
Add a function to change the cairo font options of a font to
to the given values while keeping everything else the same.

We use pango api for this if available.

Note that this is not a fully general api, but tailored to the
needs of GSK. We don't allow setting hint-metrics (because it
only influences layout, not rendering) or subpixel-mode (since
we don't have component alpha available).
2024-03-02 18:39:14 -05:00
Matthias Clasen 16a476fe22 gsk: Stop passing scale to glyph upload op
It is always 1.0 now, so there is no point. Instead of the scale,
print the font when doing verbose logging.
2024-03-02 18:39:14 -05:00
Matthias Clasen c8ca6930c5 gsk: Use a scaled font for glyph rendering
This changes the approach we take to rendering glyphs in the
presence of a scale transform: Instead of scaling the extents
and rendering to an image surface with device scale, simply
create a scaled font and use it for extents and rendering.

This avoids clipping problems with scaling of extents in
the presence of hinting.
2024-03-02 18:39:14 -05:00
Matthias Clasen c4f33f36de gsk: Add a way to get a scaled font
Add a function to change the size of a font while keeping everything
else the same. We use pango api for this if available.
2024-03-02 18:39:14 -05:00
Matthias Clasen 0543c48862 NEWS: Updates 2024-03-02 18:27:33 -05:00
Yaron Shahrabani fcb17a86e6 Update Hebrew translation 2024-03-02 22:15:37 +00:00
Yuri Chornoivan 5633b5b637 Update Ukrainian translation 2024-03-02 20:40:15 +00:00
Artur S0 f7eaf69d67 Update Russian translation 2024-03-02 19:55:29 +00:00
Piotr Drąg 32411943ea Update Polish translation 2024-03-02 17:08:11 +01:00
Jiri Grönroos 58fa5d7617 Update Finnish translation 2024-03-02 16:03:12 +00:00
Ekaterine Papava f9ee1967f4 Update Georgian translation 2024-03-02 15:53:04 +00:00
Danial Behzadi 6a376f0a30 Update Persian translation 2024-03-02 15:32:03 +00:00
Piotr Drąg 66826c26db Update POTFILES.in 2024-03-02 16:19:28 +01:00
Matthias Clasen 8d1e37789e Merge branch 'broken-hexboxes' into 'main'
gsk: problems with hex boxes

See merge request GNOME/gtk!6963
2024-03-02 00:04:29 +00:00
Matthias Clasen 6c39a5946e Merge branch 'wip/chergert/for-main' into 'main'
gdk/gdkglcontext: include duration of eglSwapBuffers

See merge request GNOME/gtk!6964
2024-03-02 00:03:58 +00:00
Christian Hergert 2a98928286 gdk/gdkglcontext: include duration of eglSwapBuffers 2024-03-02 00:03:57 +00:00
Matthias Clasen c7806eb908 gsk: Fix handling of hex boxes
The pango code that is drawing hex boxes, invisible glyphs, etc,
is depending on the width being set in the PangoGlyphInfo. Once
we set that, everything falls into place.

Testcase included.
2024-03-01 16:51:58 -05:00
Matthias Clasen 9015734e65 Merge branch 'matthiasc/for-main' into 'main'
gsk: Make glyph parsing more flexible

See merge request GNOME/gtk!6962
2024-03-01 17:49:46 +00:00
Matthias Clasen f5159e1ecb gsk: Make glyph parsing more flexible
It is a bit annoying that one has to specify the glyph width
when specifying glyphs numerically for a text node, since this
information really is part of the font.

Make the parser more flexible, and allow to specify just the glyph
ids, without an explicit width. In this case, the width will be
determined from the font.

With this, glyphs can now be specified in any of the follwing
ways:

glyphs: "ABC";              (ASCII)
glyphs: 23, 45, 1001;       (Glyph IDs)
glyphs: 23 10, 100 11.1;    (Glyph IDs and advance widths)
glyphs: 23 10 1 2 color;    (with offsets and flags)

Tests have been updated to cover these variants.
2024-03-01 11:22:28 -05:00
Matthias Clasen aec2f50d82 testsuite: Add a forgotten test 2024-03-01 09:23:41 -05:00
Matthias Clasen 74860f7602 Merge branch 'debug-flags-ubsan' into 'main'
gdkdisplay: Don’t call _get_instance_private(NULL)

See merge request GNOME/gtk!6961
2024-03-01 13:10:30 +00:00
Philip Withnall a9175e0c03 gdkdisplay: Don’t call _get_instance_private(NULL)
While it’s documented as being safe, it triggers warnings from ubsan.
While we work out the best way to deal with that inside the
implementation of `G_ADD_PRIVATE` in GLib, let’s pragmatically just
short-circuit the code which triggers the warning here. This is helpful
because `gdk_display_get_debug_flags()` is called from a number of
locations within GTK, so is likely to be hit if anyone is running a UI
app under ubsan.

See https://gitlab.gnome.org/GNOME/glib/-/issues/3267#note_2033550

Signed-off-by: Philip Withnall <pwithnall@gnome.org>

Helps: https://gitlab.gnome.org/GNOME/glib/-/issues/3267
2024-03-01 12:16:31 +00:00
Matthias Clasen e1c56555af Merge branch 'camelCaseNick/editable-accessible-crash' into 'main'
a11y: support multiple levels of editable delegations in AT-SPI text

See merge request GNOME/gtk!6960
2024-03-01 04:12:23 +00:00
Matthias Clasen 24120c8fd0 Merge branch 'matthiasc/for-main' into 'main'
testsuite: Plug some leaks

See merge request GNOME/gtk!6959
2024-03-01 03:56:06 +00:00
Markus Göllnitz f284331f79 a11y: support multiple levels of editable delegations in AT-SPI text
Gtk.Editable.get_delegate is allowed to return another
delegating Gtk.Editable. However, the AT-SPI text
implementationn for Gtk.Editables does not handle
delegate chaining.

In the wild, you will find a Gtk.Text as the delegate of
a Gtk.SpinButton, that is in turn the delegate of an
Adw.SpinRow in libadwaita.

Note: This does not handle the more dangerous possibility
of a delegate loop when built with G_DISABLE_ASSERT,
otherwise stops after the arbitrarily chosen number of
six steps of delegation.

Signed-off-by: Markus Göllnitz <camelcasenick@bewares.it>
2024-03-01 04:14:58 +01:00
Matthias Clasen a82de96e1a Add a testsuite for nodeparser tests
This helps when changing the node parser.
2024-02-29 21:59:04 -05:00
Matthias Clasen eba9b116ed Merge branch 'camelCaseNick/text-accessible-segv' into 'main'
a11y: handle no selection ranges for AT-SPI text

Closes #6488

See merge request GNOME/gtk!6958
2024-02-29 03:52:10 +00:00
Markus Göllnitz 1f89b3c7df a11y: handle no selection ranges for AT-SPI text 2024-02-29 03:52:10 +00:00
Matthias Clasen c739b9fe7f Merge branch 'wip/kabus/misc-leaks2' into 'main'
general: Fix leaks

See merge request GNOME/gtk!6951
2024-02-28 12:35:02 +00:00
Matthias Clasen 556b729b97 Merge branch 'matthiasc/for-main' into 'main'
gsk: Serialize fonts with absolute size

See merge request GNOME/gtk!6953
2024-02-28 12:08:59 +00:00
Matthias Clasen 9fd5558acd Update nodeparser tests
The node serialization code now prints fonts with pixel sizes.
Update affected tests.
2024-02-27 23:46:33 -05:00
Matthias Clasen b7422c0f62 nodeparser: Change default font
Use Cantarell 15px instead of Cantarell 11, ot make roundtrip
tests easier to read.
2024-02-27 23:45:46 -05:00
Emmanuele Bassi ace684c7ab Merge branch 'wip/chergert/for-main' into 'main'
a11y/atspi: make TextCaretMoved match GTK 3 / ATK

See merge request GNOME/gtk!6956
2024-02-28 01:15:53 +00:00
Christian Hergert 752e704e99 accessibletext: handle NULL gracefully from get_contents_at()
This fixes a g_critical() internally with GtkTextView when running orca.
2024-02-27 16:40:48 -08:00
Christian Hergert 8c7e13746b a11y/atspi: make TextCaretMoved match GTK 3 / ATK
When testing VTE on GTK 3 using ATK, the variant parameter is <0> instead
of <''> on the wire. Make that match to increase the chances that tooling
will hit the same expectations.
2024-02-27 16:35:29 -08:00
Matthias Clasen c2311c7154 gsk: Serialize fonts with absolute size
This is more often what we want. Our testcases tend to have
pixel sizes, and we want to preserve then when resaving the
test files.
2024-02-27 14:10:10 -05:00
Khalid Abu Shawarib 44fa748826 general: Fix leaks 2024-02-27 22:01:41 +03:00
Matthias Clasen dfed398371 Merge branch 'gtk4-edge-tiling-resize-fix' into 'main'
[gtk4/wayland] Infer edge constraints from tiled edges.

See merge request GNOME/gtk!6745
2024-02-27 17:39:04 +00:00
Matthias Clasen 962ba49a8e Merge branch 'wip/chergert/for-main' into 'main'
textview: always set n_ranges out parameter

See merge request GNOME/gtk!6950
2024-02-27 02:19:40 +00:00
Christian Hergert 5811e443f8 textview: always set n_ranges out parameter 2024-02-26 17:49:03 -08:00
Aurimas Černius f55e1392d4 Update Lithuanian translation 2024-02-26 20:56:00 +00:00
Daniel Mustieles 0fbe5ba40c Update Spanish translation 2024-02-26 15:25:40 +00:00
Matthias Clasen 980ea63d78 Merge branch 'video-cursor-timeout' into 'main'
video: Install the hide cursor timeout later

Closes #6264

See merge request GNOME/gtk!6948
2024-02-26 14:45:02 +00:00
Matthias Clasen dcc3533363 video: Install the hide cursor timeout later
We were installing the timeout in root, but removing it in unmap,
which could lead to trouble if we ever dispose a GtkVideo widget
without mapping it.

Fixes: #6264
2024-02-26 08:17:27 -05:00
Matthias Clasen 28964aa0a4 Merge branch 'search-entry-input-hints-property-since-marker' into 'main'
Add missing `Since` marker to `GtkSearchEntry:input-hints`

See merge request GNOME/gtk!6947
2024-02-26 12:26:33 +00:00
Matthias Clasen 7fd8a0ac99 Merge branch 'michaelweghorn/fix_at_spi_socket_doc' into 'main'
a11y: Fix gtk_at_spi_socket_new doc

See merge request GNOME/gtk!6946
2024-02-26 12:21:34 +00:00
Sebastian Dröge d919ed4e4b Add missing Since marker to GtkSearchEntry:input-hints 2024-02-26 11:09:50 +02:00
Matej Urbančič 61ec6fb5eb Update Slovenian translation 2024-02-26 09:00:38 +00:00
Michael Weghorn 237eb8bb90 a11y: Fix gtk_at_spi_socket_new doc 2024-02-26 07:52:19 +01:00
Matthias Clasen ff57cd9331 Merge branch 'gtk-jan2024_docs_tweaks' into 'main'
docs: Clarify child objects in GtkBuilder

See merge request GNOME/gtk!6945
2024-02-26 03:05:22 +00:00
Matthias Clasen c97d02f487 docs: Mention child properties in builder docs
Clarify that there is no need for <child> if we have a property.
2024-02-25 21:46:11 -05:00
Matthias Clasen 36ced69ebf Merge branch 'matthiasc/for-main' into 'main'
Make one of the tests more robust

See merge request GNOME/gtk!6944
2024-02-26 01:36:15 +00:00
Matthias Clasen 427a52a9ad Make one of the tests more robust
The text-mixed-color-nocairo test was using a 20pt font, which
results in 16.6 pixels, which is prone to triggering rounding
errors and problems with fractional node bounds. Make it use
20px instead.
2024-02-25 20:03:35 -05:00
Matthias Clasen 9b5aee0d1b Cosmetics 2024-02-25 18:20:22 -05:00
Logan Rathbone 882387a62a docs: Cross-reference GtkExpression binding method in GtkBuilder docs
The GtkBuilder docs previously only explained the GBinding methodology.
2024-02-24 13:54:35 -05:00
Logan Rathbone 73f7370ead docs: Clarify GtkExpression usage in .ui files 2024-02-24 13:54:35 -05:00
Logan Rathbone 8e9241f3ba docs: Remove unnecessary fetching of adjustment in :output code example 2024-02-24 13:54:35 -05:00
Logan Rathbone 3c67931f5f docs: Clarify child objects in GtkBuilder
Also, document the GListStore special case.
2024-02-24 13:54:34 -05:00
Arjan Molenaar ee06ac3ad2 macos: determine zoomed state via NSWindow isZoomed
With our custom logic out of the way, this just works.
Maximized state is also update on move, since a moved maximized
window is no longer considered maximized in macOS land.
2024-02-18 14:33:26 +01:00
Arjan Molenaar 19a8870f76 macos: use native zoom/unzoom logic
In macOS, when moving a maximized window, it's not automatically
restored to its default size.

In addition, GdkMacosWindow should not check surface layout properties,
since those properties are lagging, e.i. are set after the (native)
window state has been updated.
2024-02-18 14:33:26 +01:00
Arjan Molenaar 99a3a7e94e macos: deduplicate compute_size logic
It's used in `present` currently. Need to figure out if it really
belongs there: in Wayland no size computation is done in the
`present` handler.
2024-02-17 22:47:47 +01:00
Arjan Molenaar a516441513 macos: Fix window state of initially maximized windows
GdkSurface maintains state that shadows the actual window state.
This state is not always updated in the macos backend.

In our case, when a window is initially maximized, `setFrame:display:`
was called and `inMaximizeTransition` was set.  However,
`windowDidEndLiveResize:` was never called and `inMaximizeTransition`
was never unset, making the application think the window is still
maximized.

Additionally, `windowShouldZoom:toFrame:` is only called when the window
is maximized, not when it's unmaximized.

By checking and setting the state in `windowDidResize:` we can at least
be sure that the internal maximized state is only set if the window
takes up all desktop space: the screen's visible frame.
2024-02-17 21:04:50 +01:00
Emilio Cobos Álvarez 2f5278a139 [gtk4/wayland] Infer edge constraints from tiled edges.
This is the Gtk4 version of !6742, which fixes the same bug as described
there.
2024-01-12 22:40:22 +01:00
214 changed files with 14990 additions and 8131 deletions
+3 -1
View File
@@ -219,11 +219,13 @@ macos:
- if: $RUNNER == "macosintel"
variables:
SDKROOT: /opt/sdks/MacOSX10.13.4.sdk
NINJA_PKG: $CI_API_V4_URL/projects/30745/packages/generic/ninja_macos/v1.11.1.1+9/ninja-1.11.1.1-cp38-cp38-macosx_11_0_x86_64.whl
when: manual
allow_failure: true
- if: $RUNNER == "macosarm"
variables:
SDKROOT: /opt/sdks/MacOSX11.3.sdk
NINJA_PKG: ninja==1.11.1.1
stage: build
parallel:
matrix:
@@ -246,7 +248,7 @@ macos:
- curl -L $CI_API_V4_URL/projects/30437/packages/generic/pkgconfig/v0.29.2+10/pkg-config-0.29.2+10_$(uname -m).tar.xz | tar -C .venv -xJ
- curl -L $CI_API_V4_URL/projects/30438/packages/generic/bison/v3.8.2+3/bison-3.8.2+3_$(uname -m).tar.xz | tar -C .venv -xJ
- source .venv/bin/activate
- pip3 install meson==1.3.2 ninja==1.11.1.1
- pip3 install meson==1.3.2 $NINJA_PKG
# We're not setting up ccache here on purpose as it accelerates the build
# so much that it triggers race conditions in the gobject-introspection
# subproject.
+106 -2
View File
@@ -1,11 +1,115 @@
Overview of Changes in 4.13.9, xx-xx-xxxx
Overview of Changes in 4.14.1, xx-xx-xxxx
=========================================
Overview of Changes in 4.14.0, 12-03-2024
=========================================
Note: The new renderers and dmabuf support are using graphics drivers
in different ways than the old gl renderer, and trigger new driver bugs,
(see for example https://gitlab.gnome.org/GNOME/gtk/-/issues/6418 and
https://gitlab.gnome.org/GNOME/gtk/-/issues/6388). Therefore, it is
recommended to use the latest mesa release (24.0) with the new renderers.
recommended to use the latest mesa release (24.x) with the new renderers.
* GtkTextView:
- Don't snapshot children twice
- Don't blink the cursor when hidden
* GtkEmojiChooser:
- Fix presentation selector handling
* GtkSnapshot:
- Fix wrong nodes with transformed shadows
* GtkIMContext:
- Make gtk_im_context_activate_osk public
* Accessibility:
- Implement get_contents_at for all our text widgets
- Add GtkAccessibleText.get_default_attributes
* GSK:
- Don't fall back to cairo for software rendering. gl+llvmpipe is better
- Round vertical glyph position to a device pixel position if the font is hinted
- Fix problems with clip handling
- Make vulkan and ngl match their font handling
- Fix some corner-cases with offloading and clips
- Fix problem with rendering of missing glyphs in hinted fonts
* MacOs:
- Implement cursor-from-texture
* Translation updates:
Basque
British English
French
Indonesian
Kazakh
Latvian
Lithuanian
Norwegian Bokmål
Slovenian
Spanish
Turkish
Overview of Changes in 4.13.9, 02-03-2024
=========================================
* GtkEditable:
- Fix preconditions to be not too strict
* GtkEmojiChooser:
- Support search in the locale as well as in English
* GtkIconTheme:
- Make gtk_icon_paintable_new_for_file support symbolics
* GtkVideo:
- Fix a problem with cursor handling that could lead to crashes
* Accessibility:
- Fix GetCharacterAtOffset implementation
- Add a Terminal role
- Make TextCaretMoved match gtk3
- Support multiple levels of GtkEditable delegates
* GSK:
- Make the node parser more flexible for text nodes
- Change the way font scaling is handled to avoid clipping
- Fix handling of missing glyphs in the new renderers
* X11:
- Don't claim to support shadows without a compositor
* Wayland:
- Fix handling of output scales
* Tools:
- Add a compare command to gtk4-rendernode-tool
* Build:
- Fix some ubsan complaints
* Translation updates:
Basque
British English
Catalan
Finnish
Galician
Georgian
Hebrew
Indonesian
Kazakh
Latvian
Lithuanian
Persian
Polish
Russian
Slovenian
Spanish
Turkish
Ukrainian
Overview of Changes in 4.13.8, 20-02-2024
+1 -1
View File
@@ -600,8 +600,8 @@ update_display (void)
if (s->len > 0)
{
pango_font_description_set_variations (desc, s->str);
g_string_free (s, TRUE);
}
g_string_free (s, TRUE);
font_desc = pango_font_description_to_string (desc);
+3 -1
View File
@@ -116,7 +116,9 @@ static gboolean gtk_shadertoy_tick (GtkWidget *widget,
GtkWidget *
gtk_shadertoy_new (void)
{
return g_object_new (gtk_shadertoy_get_type (), NULL);
return g_object_new (gtk_shadertoy_get_type (),
"allowed-apis", GDK_GL_API_GL,
NULL);
}
static void
+1
View File
@@ -354,6 +354,7 @@ do_images (GtkWidget *do_widget)
gicon = g_themed_icon_new_with_default_fallbacks ("battery-caution-charging-symbolic");
image = gtk_image_new_from_gicon (gicon);
gtk_image_set_icon_size (GTK_IMAGE (image), GTK_ICON_SIZE_LARGE);
g_object_unref (gicon);
gtk_frame_set_child (GTK_FRAME (frame), image);
+12 -7
View File
@@ -322,12 +322,14 @@ stroke bounds of the path.
### text
| property | syntax | default | printed |
| -------- | ------------------- | ------------------- | ----------- |
| color | `<color>` | black | non-default |
| font | `<string>` `<url>`? | "Cantarell 11" | always |
| glyphs | `<glyphs>` | "Hello" | always |
| offset | `<point>` | 0 0 | non-default |
| property | syntax | default | printed |
| ------------ | ------------------- | ------------------- | ----------- |
| color | `<color>` | black | non-default |
| font | `<string>` `<url>`? | "Cantarell 15px" | always |
| glyphs | `<glyphs>` | "Hello" | always |
| offset | `<point>` | 0 0 | non-default |
| hint-style | `<hint style>` | slight | non-default |
| antialias | `<antialias>` | gray | non-default |
Creates a node like `gsk_text_node_new()` with the given properties.
@@ -336,12 +338,15 @@ font that is specified in the string. It can be either a data url containing
a base64-encoded font file, or a regular url that points to a font file.
Glyphs can be specified as an ASCII string, or as a comma-separated list of
their glyph ID and advance width. Optionally, x and y offsets and flags can
their glyph IDs. Optionally, the advance width, x and y offsets and flags can
be specified as well, like this: 40 10 0 0 color.
If the given font does not exist or the given glyphs are invalid for the given
font, an error node will be returned.
Possible values for hint-style are none, slight or full.
Possible value for antialias are none or gray.
### texture
| property | syntax | default | printed |
+3 -3
View File
@@ -69,9 +69,9 @@ Image:
4 CARD32 IMAGE_DATA_OFFSET
ICON_FLAGS
HAS_SUFFIX_PNG 1
HAS_SUFFIX_XPM 2
HAS_SUFFIX_SVG 4
HAS_SUFFIX_XPM 1
HAS_SUFFIX_SVG 2
HAS_SUFFIX_PNG 4
HAS_ICON_FILE 8
ImageData:
+4 -1
View File
@@ -2037,9 +2037,12 @@ gdk_display_get_dmabuf_formats (GdkDisplay *display)
GdkDebugFlags
gdk_display_get_debug_flags (GdkDisplay *display)
{
if (display == NULL)
return _gdk_debug_flags;
GdkDisplayPrivate *priv = gdk_display_get_instance_private (display);
return display ? priv->debug_flags : _gdk_debug_flags;
return priv->debug_flags;
}
void
+56 -29
View File
@@ -79,14 +79,23 @@ static guint signals[LAST_SIGNAL];
static guint fps_counter;
#define FRAME_HISTORY_MAX_LENGTH 128
/* 60Hz plus some extra for monotonic time inaccuracy */
#define FRAME_HISTORY_DEFAULT_LENGTH 64
#define frame_timings_unref(x) gdk_frame_timings_unref((GdkFrameTimings *) (x))
#define GDK_ARRAY_NAME timings
#define GDK_ARRAY_TYPE_NAME Timings
#define GDK_ARRAY_ELEMENT_TYPE GdkFrameTimings *
#define GDK_ARRAY_PREALLOC FRAME_HISTORY_DEFAULT_LENGTH
#define GDK_ARRAY_FREE_FUNC frame_timings_unref
#include "gdk/gdkarrayimpl.c"
struct _GdkFrameClockPrivate
{
gint64 frame_counter;
int n_timings;
int current;
GdkFrameTimings *timings[FRAME_HISTORY_MAX_LENGTH];
Timings timings;
int n_freeze_inhibitors;
};
@@ -99,11 +108,8 @@ static void
gdk_frame_clock_finalize (GObject *object)
{
GdkFrameClockPrivate *priv = GDK_FRAME_CLOCK (object)->priv;
int i;
for (i = 0; i < FRAME_HISTORY_MAX_LENGTH; i++)
if (priv->timings[i] != 0)
gdk_frame_timings_unref (priv->timings[i]);
timings_clear (&priv->timings);
G_OBJECT_CLASS (gdk_frame_clock_parent_class)->finalize (object);
}
@@ -257,7 +263,8 @@ gdk_frame_clock_init (GdkFrameClock *clock)
clock->priv = priv = gdk_frame_clock_get_instance_private (clock);
priv->frame_counter = -1;
priv->current = FRAME_HISTORY_MAX_LENGTH - 1;
priv->current = 0;
timings_init (&priv->timings);
if (fps_counter == 0)
fps_counter = gdk_profiler_define_counter ("fps", "Frames per Second");
@@ -416,7 +423,7 @@ gdk_frame_clock_get_frame_counter (GdkFrameClock *frame_clock)
static inline gint64
_gdk_frame_clock_get_history_start (GdkFrameClock *frame_clock)
{
return frame_clock->priv->frame_counter + 1 - frame_clock->priv->n_timings;
return frame_clock->priv->frame_counter + 1 - timings_get_size (&frame_clock->priv->timings);
}
/**
@@ -445,31 +452,44 @@ gdk_frame_clock_get_history_start (GdkFrameClock *frame_clock)
}
void
_gdk_frame_clock_begin_frame (GdkFrameClock *frame_clock)
_gdk_frame_clock_begin_frame (GdkFrameClock *frame_clock,
gint64 monotonic_time)
{
GdkFrameClockPrivate *priv;
g_return_if_fail (GDK_IS_FRAME_CLOCK (frame_clock));
priv = frame_clock->priv;
priv->frame_counter++;
priv->current = (priv->current + 1) % FRAME_HISTORY_MAX_LENGTH;
/* Try to steal the previous frame timing instead of discarding
* and allocating a new one.
*/
if G_LIKELY (priv->n_timings == FRAME_HISTORY_MAX_LENGTH &&
_gdk_frame_timings_steal (priv->timings[priv->current],
priv->frame_counter))
return;
if (priv->n_timings < FRAME_HISTORY_MAX_LENGTH)
priv->n_timings++;
if (G_UNLIKELY (timings_get_size (&priv->timings) == 0))
timings_append (&priv->timings, _gdk_frame_timings_new (priv->frame_counter));
else
gdk_frame_timings_unref (priv->timings[priv->current]);
{
GdkFrameTimings *timings;
priv->timings[priv->current] = _gdk_frame_timings_new (priv->frame_counter);
priv->current = (priv->current + 1) % timings_get_size (&priv->timings);
timings = timings_get (&priv->timings, priv->current);
if (timings->frame_time + G_USEC_PER_SEC > monotonic_time)
{
/* Keep the timings, not a second old yet */
timings = _gdk_frame_timings_new (priv->frame_counter);
timings_splice (&priv->timings, priv->current, 0, FALSE, &timings, 1);
}
else if (_gdk_frame_timings_steal (timings, priv->frame_counter))
{
/* Stole the previous frame timing instead of discarding
* and allocating a new one, so nothing to do
*/
}
else
{
timings = _gdk_frame_timings_new (priv->frame_counter);
timings_splice (&priv->timings, priv->current, 1, FALSE, &timings, 1);
}
}
}
static inline GdkFrameTimings *
@@ -477,17 +497,21 @@ _gdk_frame_clock_get_timings (GdkFrameClock *frame_clock,
gint64 frame_counter)
{
GdkFrameClockPrivate *priv = frame_clock->priv;
int pos;
gsize size, pos;
if (frame_counter > priv->frame_counter)
return NULL;
if (frame_counter <= priv->frame_counter - priv->n_timings)
size = timings_get_size (&priv->timings);
if (G_UNLIKELY (size == 0))
return NULL;
pos = (priv->current - (priv->frame_counter - frame_counter) + FRAME_HISTORY_MAX_LENGTH) % FRAME_HISTORY_MAX_LENGTH;
if (priv->frame_counter - frame_counter >= size)
return NULL;
return priv->timings[pos];
pos = (priv->current - (priv->frame_counter - frame_counter) + size) % size;
return timings_get (&priv->timings, pos);
}
/**
@@ -779,7 +803,10 @@ gdk_frame_clock_get_fps (GdkFrameClock *frame_clock)
start_counter = _gdk_frame_clock_get_history_start (frame_clock);
end_counter = _gdk_frame_clock_get_frame_counter (frame_clock);
start = _gdk_frame_clock_get_timings (frame_clock, start_counter);
for (start = _gdk_frame_clock_get_timings (frame_clock, start_counter);
end_counter > start_counter && start != NULL && !gdk_frame_timings_get_complete (start);
start = _gdk_frame_clock_get_timings (frame_clock, start_counter))
start_counter++;
for (end = _gdk_frame_clock_get_timings (frame_clock, end_counter);
end_counter > start_counter && end != NULL && !gdk_frame_timings_get_complete (end);
end = _gdk_frame_clock_get_timings (frame_clock, end_counter))
+8 -1
View File
@@ -192,6 +192,13 @@ compute_smooth_frame_time (GdkFrameClock *clock,
* and new_frame_time >= old_frame_time. */
frames_passed = (new_frame_time - smoothed_frame_time_base + frame_interval / 2) / frame_interval;
if (frames_passed > 1)
gdk_profiler_add_markf ((smoothed_frame_time_base - (frame_interval * (frames_passed-1))) * 1000L,
frame_interval * (frames_passed-1) * 1000L,
"Dropped Frames",
"%u frames may have been dropped",
frames_passed-1);
/* We use an approximately whole number of frames in the future from
* last smoothed frame time. This way we avoid minor jitter in the
* frame times making the animation speed uneven, but still animate
@@ -548,7 +555,7 @@ gdk_frame_clock_paint_idle (void *data)
priv->smoothed_frame_time_period = frame_interval;
priv->smoothed_frame_time_reported = priv->smoothed_frame_time_base;
_gdk_frame_clock_begin_frame (clock);
_gdk_frame_clock_begin_frame (clock, priv->frame_time);
/* Note "current" is different now so timings != prev_timings */
timings = gdk_frame_clock_get_current_timings (clock);
+2 -1
View File
@@ -106,7 +106,8 @@ struct _GdkFrameTimings
void _gdk_frame_clock_inhibit_freeze (GdkFrameClock *clock);
void _gdk_frame_clock_uninhibit_freeze (GdkFrameClock *clock);
void _gdk_frame_clock_begin_frame (GdkFrameClock *clock);
void _gdk_frame_clock_begin_frame (GdkFrameClock *clock,
gint64 monotonic_time);
void _gdk_frame_clock_debug_print_timings (GdkFrameClock *clock,
GdkFrameTimings *timings);
void _gdk_frame_clock_add_timings_to_profiler (GdkFrameClock *frame_clock,
+3 -2
View File
@@ -658,6 +658,7 @@ gdk_gl_context_real_end_frame (GdkDrawContext *draw_context,
GdkSurface *surface = gdk_gl_context_get_surface (context);
GdkDisplay *display = gdk_surface_get_display (surface);
EGLSurface egl_surface;
G_GNUC_UNUSED gint64 begin_time = GDK_PROFILER_CURRENT_TIME;
if (priv->egl_context == NULL)
return;
@@ -666,8 +667,6 @@ gdk_gl_context_real_end_frame (GdkDrawContext *draw_context,
egl_surface = gdk_surface_get_egl_surface (surface);
gdk_profiler_add_mark (GDK_PROFILER_CURRENT_TIME, 0, "EGL swap buffers", NULL);
if (priv->eglSwapBuffersWithDamage)
{
EGLint stack_rects[4 * 4]; /* 4 rects */
@@ -698,6 +697,8 @@ gdk_gl_context_real_end_frame (GdkDrawContext *draw_context,
else
eglSwapBuffers (gdk_display_get_egl_display (display), egl_surface);
#endif
gdk_profiler_add_mark (begin_time, GDK_PROFILER_CURRENT_TIME - begin_time, "EGL swap buffers", NULL);
}
static void
+5
View File
@@ -260,6 +260,11 @@ gdk_vulkan_strerror (VkResult result)
case VK_ERROR_INCOMPATIBLE_SHADER_BINARY_EXT:
return "The provided binary shader code is not compatible with this device. (VK_ERROR_INCOMPATIBLE_SHADER_BINARY_EXT)";
#endif
#if VK_HEADER_VERSION >= 274
case VK_ERROR_INVALID_VIDEO_STD_PARAMETERS_KHR:
return "The specified Video Std parameters do not adhere to the syntactic or semantic requirements of the used video compression standard or implementation";
#endif
case VK_RESULT_MAX_ENUM:
default:
return "Unknown Vulkan error.";
+8 -59
View File
@@ -214,22 +214,6 @@ typedef NSString *CALayerContentsGravity;
}
}
-(void)setFrame:(NSRect)frame display:(BOOL)display
{
NSRect contentRect = [self contentRectForFrameRect:frame];
GdkSurface *surface = GDK_SURFACE (gdk_surface);
gboolean maximized = (surface->state & GDK_TOPLEVEL_STATE_MAXIMIZED) != 0;
if (maximized && !inMaximizeTransition && !NSEqualRects (lastMaximizedFrame, frame))
{
gdk_synthesize_surface_state (surface, GDK_TOPLEVEL_STATE_MAXIMIZED, 0);
_gdk_surface_update_size (surface);
}
[super setFrame:frame display:display];
[[self contentView] setFrame:NSMakeRect (0, 0, contentRect.size.width, contentRect.size.height)];
}
-(id)initWithContentRect:(NSRect)contentRect
styleMask:(NSWindowStyleMask)styleMask
backing:(NSBackingStoreType)backingType
@@ -387,12 +371,17 @@ typedef NSString *CALayerContentsGravity;
-(void)windowDidMove:(NSNotification *)notification
{
if ([self isZoomed])
gdk_synthesize_surface_state (GDK_SURFACE (gdk_surface), 0, GDK_TOPLEVEL_STATE_MAXIMIZED);
else
gdk_synthesize_surface_state (GDK_SURFACE (gdk_surface), GDK_TOPLEVEL_STATE_MAXIMIZED, 0);
_gdk_macos_surface_configure ([self gdkSurface]);
}
-(void)windowDidResize:(NSNotification *)notification
{
_gdk_macos_surface_configure (gdk_surface);
[self windowDidMove: notification];
/* If we're using server-side decorations, this notification is coming
* in from a display-side change. We need to request a layout in
@@ -413,7 +402,6 @@ typedef NSString *CALayerContentsGravity;
-(void)beginManualMove
{
gboolean maximized = GDK_SURFACE (gdk_surface)->state & GDK_TOPLEVEL_STATE_MAXIMIZED;
NSPoint initialMoveLocation;
GdkPoint point;
GdkMonitor *monitor;
@@ -432,13 +420,6 @@ typedef NSString *CALayerContentsGravity;
initialMoveLocation = [NSEvent mouseLocation];
if (maximized)
[self setFrame:NSMakeRect (initialMoveLocation.x - (int)lastUnmaximizedFrame.size.width/2,
initialMoveLocation.y,
lastUnmaximizedFrame.size.width,
lastUnmaximizedFrame.size.height)
display:YES];
_gdk_macos_display_from_display_coords ([self gdkDisplay],
initialMoveLocation.x,
initialMoveLocation.y,
@@ -781,43 +762,11 @@ typedef NSString *CALayerContentsGravity;
return rect;
}
/* Implementing this method avoids new windows move around the screen. */
-(NSRect)windowWillUseStandardFrame:(NSWindow *)nsWindow
defaultFrame:(NSRect)newFrame
{
NSRect screenFrame = [[self screen] visibleFrame];
GdkMacosSurface *surface = gdk_surface;
gboolean maximized = GDK_SURFACE (surface)->state & GDK_TOPLEVEL_STATE_MAXIMIZED;
if (!maximized)
return screenFrame;
else
return lastUnmaximizedFrame;
}
-(BOOL)windowShouldZoom:(NSWindow *)nsWindow
toFrame:(NSRect)newFrame
{
GdkMacosSurface *surface = gdk_surface;
GdkToplevelState state = GDK_SURFACE (surface)->state;
if (state & GDK_TOPLEVEL_STATE_MAXIMIZED)
{
lastMaximizedFrame = newFrame;
}
else
{
lastUnmaximizedFrame = [nsWindow frame];
gdk_synthesize_surface_state (GDK_SURFACE (gdk_surface), 0, GDK_TOPLEVEL_STATE_MAXIMIZED);
}
inMaximizeTransition = YES;
return YES;
}
-(void)windowDidEndLiveResize:(NSNotification *)aNotification
{
inMaximizeTransition = NO;
return newFrame;
}
-(NSSize)window:(NSWindow *)window willUseFullScreenContentSize:(NSSize)proposedSize
-3
View File
@@ -49,10 +49,7 @@
EdgeSnapping snapping;
NSRect lastUnmaximizedFrame;
NSRect lastMaximizedFrame;
NSRect lastUnfullscreenFrame;
BOOL inMaximizeTransition;
BOOL inFullscreenTransition;
}
+62 -1
View File
@@ -151,6 +151,57 @@ create_blank_cursor (void)
return nscursor;
}
static NSCursor *
create_cursor_from_texture (GdkTexture *texture,
int x,
int y)
{
guint32 width;
guint32 height;
guchar *pixels;
gsize stride;
GdkTextureDownloader *downloader;
NSCursor *nscursor;
NSBitmapImageRep *nsbitmap;
NSImage *nsimage;
if (texture == NULL)
return create_blank_cursor ();
width = gdk_texture_get_width (texture);
height = gdk_texture_get_height (texture);
nsbitmap = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL
pixelsWide:width
pixelsHigh:height
bitsPerSample:8
samplesPerPixel:4
hasAlpha:YES
isPlanar:NO
colorSpaceName:NSDeviceRGBColorSpace
bytesPerRow:0
bitsPerPixel:0];
pixels = [nsbitmap bitmapData];
stride = [nsbitmap bytesPerRow];
downloader = gdk_texture_downloader_new (texture);
gdk_texture_downloader_set_format (downloader, GDK_MEMORY_R8G8B8A8_PREMULTIPLIED);
gdk_texture_downloader_download_into (downloader,
pixels,
stride);
gdk_texture_downloader_free (downloader);
nsimage = [[NSImage alloc] init];
[nsimage addRepresentation:nsbitmap];
[nsimage setSize:NSMakeSize(width, height)];
[nsbitmap release];
nscursor = [[NSCursor alloc] initWithImage:nsimage
hotSpot:NSMakePoint(x, y)];
[nsimage release];
return nscursor;
}
NSCursor *
_gdk_macos_cursor_get_ns_cursor (GdkCursor *cursor)
{
@@ -161,7 +212,17 @@ _gdk_macos_cursor_get_ns_cursor (GdkCursor *cursor)
g_return_val_if_fail (!cursor || GDK_IS_CURSOR (cursor), NULL);
if (cursor != NULL)
name = gdk_cursor_get_name (cursor);
{
name = gdk_cursor_get_name (cursor);
if (name == NULL)
{
nscursor = create_cursor_from_texture (gdk_cursor_get_texture (cursor),
gdk_cursor_get_hotspot_x (cursor),
gdk_cursor_get_hotspot_y (cursor));
return nscursor;
}
}
if (name == NULL)
goto load_cursor;
+110 -171
View File
@@ -96,37 +96,26 @@ _gdk_macos_toplevel_surface_unminimize (GdkMacosToplevelSurface *self)
[window deminiaturize:window];
}
static void
_gdk_macos_toplevel_surface_present (GdkToplevel *toplevel,
GdkToplevelLayout *layout)
static gboolean
_gdk_macos_toplevel_surface_compute_size (GdkSurface *surface)
{
GdkSurface *surface = GDK_SURFACE (toplevel);
GdkMacosToplevelSurface *self = (GdkMacosToplevelSurface *)toplevel;
NSWindow *nswindow = _gdk_macos_surface_get_native (GDK_MACOS_SURFACE (self));
GdkDisplay *display = gdk_surface_get_display (surface);
GdkMonitor *monitor;
GdkMacosToplevelSurface *self = (GdkMacosToplevelSurface *)surface;
GdkMacosSurface *macos_surface = (GdkMacosSurface *)surface;
GdkToplevelSize size;
GdkDisplay *display;
GdkMonitor *monitor;
int bounds_width, bounds_height;
int width, height;
GdkGeometry geometry;
GdkSurfaceHints mask;
NSWindowStyleMask style_mask;
gboolean maximize;
gboolean fullscreen;
g_assert (GDK_IS_MACOS_TOPLEVEL_SURFACE (self));
g_assert (GDK_IS_MACOS_WINDOW (nswindow));
if (layout != self->layout)
{
g_clear_pointer (&self->layout, gdk_toplevel_layout_unref);
self->layout = gdk_toplevel_layout_copy (layout);
}
if (!GDK_MACOS_SURFACE (surface)->geometry_dirty)
return FALSE;
_gdk_macos_toplevel_surface_attach_to_parent (self);
style_mask = [nswindow styleMask];
GDK_MACOS_SURFACE (surface)->geometry_dirty = FALSE;
display = gdk_surface_get_display (surface);
monitor = gdk_display_get_monitor_at_surface (display, surface);
if (monitor)
@@ -144,58 +133,127 @@ _gdk_macos_toplevel_surface_present (GdkToplevel *toplevel,
}
gdk_toplevel_size_init (&size, bounds_width, bounds_height);
gdk_toplevel_notify_compute_size (toplevel, &size);
gdk_toplevel_notify_compute_size (GDK_TOPLEVEL (surface), &size);
g_warn_if_fail (size.width > 0);
g_warn_if_fail (size.height > 0);
width = size.width;
height = size.height;
if (gdk_toplevel_layout_get_resizable (layout))
if (self->layout != NULL &&
gdk_toplevel_layout_get_resizable (self->layout))
{
geometry.min_width = size.min_width;
geometry.min_height = size.min_height;
mask = GDK_HINT_MIN_SIZE;
/* Only set 'Resizable' mask to get native resize zones if the window is
* titled, otherwise we do this internally for CSD and do not need
* NSWindow to do it for us. Additionally, it can mess things up when
* doing a window resize since it can cause mouseDown to get passed
* through to the next window.
*/
if ((style_mask & NSWindowStyleMaskTitled) != 0)
style_mask |= NSWindowStyleMaskResizable;
else
style_mask &= ~NSWindowStyleMaskResizable;
}
else
{
geometry.max_width = geometry.min_width = width;
geometry.max_height = geometry.min_height = height;
geometry.max_width = geometry.min_width = size.width;
geometry.max_height = geometry.min_height = size.height;
mask = GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE;
style_mask &= ~NSWindowStyleMaskResizable;
}
if (style_mask != [nswindow styleMask])
[nswindow setStyleMask:style_mask];
if (size.shadow.is_valid)
_gdk_macos_surface_set_shadow (GDK_MACOS_SURFACE (surface),
_gdk_macos_surface_set_shadow (macos_surface,
size.shadow.top,
size.shadow.right,
size.shadow.bottom,
size.shadow.left);
_gdk_macos_surface_set_geometry_hints (GDK_MACOS_SURFACE (self), &geometry, mask);
gdk_surface_constrain_size (&geometry, mask, width, height, &width, &height);
_gdk_macos_surface_set_geometry_hints (macos_surface, &geometry, mask);
GDK_DEBUG (MISC, "Resizing \"%s\" to %dx%d",
GDK_MACOS_SURFACE (self)->title ?
GDK_MACOS_SURFACE (self)->title :
"untitled",
width, height);
if (surface->state & (GDK_TOPLEVEL_STATE_FULLSCREEN |
GDK_TOPLEVEL_STATE_MAXIMIZED |
GDK_TOPLEVEL_STATE_TILED |
GDK_TOPLEVEL_STATE_TOP_TILED |
GDK_TOPLEVEL_STATE_RIGHT_TILED |
GDK_TOPLEVEL_STATE_BOTTOM_TILED |
GDK_TOPLEVEL_STATE_LEFT_TILED |
GDK_TOPLEVEL_STATE_MINIMIZED) ||
[macos_surface->window inLiveResize])
return FALSE;
_gdk_macos_surface_resize (GDK_MACOS_SURFACE (self), width, height);
/* If we delayed a user resize until the beginning of the frame,
* apply it now so we can start processing updates for it.
*/
if (macos_surface->next_layout.width > 0 &&
macos_surface->next_layout.height > 0)
{
int root_x = macos_surface->next_layout.root_x;
int root_y = macos_surface->next_layout.root_y;
int width = macos_surface->next_layout.width;
int height = macos_surface->next_layout.height;
gdk_surface_constrain_size (&geometry, mask,
width, height,
&width, &height);
macos_surface->next_layout.width = 0;
macos_surface->next_layout.height = 0;
_gdk_macos_surface_move_resize (macos_surface,
root_x, root_y,
width, height);
return FALSE;
}
gdk_surface_constrain_size (&geometry, mask,
size.width, size.height,
&size.width, &size.height);
if ((size.width != self->last_computed_width ||
size.height != self->last_computed_height) &&
(size.width != surface->width ||
size.height != surface->height))
{
self->last_computed_width = size.width;
self->last_computed_height = size.height;
_gdk_macos_surface_resize (macos_surface, size.width, size.height);
}
return FALSE;
}
static void
_gdk_macos_toplevel_surface_present (GdkToplevel *toplevel,
GdkToplevelLayout *layout)
{
GdkSurface *surface = GDK_SURFACE (toplevel);
GdkMacosToplevelSurface *self = (GdkMacosToplevelSurface *)toplevel;
NSWindow *nswindow = _gdk_macos_surface_get_native (GDK_MACOS_SURFACE (self));
GdkDisplay *display = gdk_surface_get_display (surface);
NSWindowStyleMask style_mask;
gboolean maximize;
gboolean fullscreen;
g_assert (GDK_IS_MACOS_TOPLEVEL_SURFACE (self));
g_assert (GDK_IS_MACOS_WINDOW (nswindow));
if (layout != self->layout)
{
g_clear_pointer (&self->layout, gdk_toplevel_layout_unref);
self->layout = gdk_toplevel_layout_copy (layout);
}
_gdk_macos_toplevel_surface_attach_to_parent (self);
_gdk_macos_toplevel_surface_compute_size (surface);
/* Only set 'Resizable' mask to get native resize zones if the window is
* titled, otherwise we do this internally for CSD and do not need
* NSWindow to do it for us. Additionally, it can mess things up when
* doing a window resize since it can cause mouseDown to get passed
* through to the next window.
*/
style_mask = [nswindow styleMask];
if (gdk_toplevel_layout_get_resizable (layout) &&
(style_mask & NSWindowStyleMaskTitled) != 0)
style_mask |= NSWindowStyleMaskResizable;
else
style_mask &= ~NSWindowStyleMaskResizable;
if (style_mask != [nswindow styleMask])
[nswindow setStyleMask:style_mask];
/* Maximized state */
if (gdk_toplevel_layout_get_maximized (layout, &maximize))
@@ -378,125 +436,6 @@ _gdk_macos_toplevel_surface_hide (GdkSurface *surface)
GDK_SURFACE_CLASS (_gdk_macos_toplevel_surface_parent_class)->hide (surface);
}
static gboolean
_gdk_macos_toplevel_surface_compute_size (GdkSurface *surface)
{
GdkMacosToplevelSurface *self = (GdkMacosToplevelSurface *)surface;
GdkMacosSurface *macos_surface = (GdkMacosSurface *)surface;
GdkToplevelSize size;
GdkDisplay *display;
GdkMonitor *monitor;
int bounds_width, bounds_height;
GdkGeometry geometry;
GdkSurfaceHints mask;
g_assert (GDK_IS_MACOS_TOPLEVEL_SURFACE (self));
if (!GDK_MACOS_SURFACE (surface)->geometry_dirty)
return FALSE;
GDK_MACOS_SURFACE (surface)->geometry_dirty = FALSE;
display = gdk_surface_get_display (surface);
monitor = gdk_display_get_monitor_at_surface (display, surface);
if (monitor)
{
GdkRectangle workarea;
gdk_macos_monitor_get_workarea (monitor, &workarea);
bounds_width = workarea.width;
bounds_height = workarea.height;
}
else
{
bounds_width = G_MAXINT;
bounds_height = G_MAXINT;
}
gdk_toplevel_size_init (&size, bounds_width, bounds_height);
gdk_toplevel_notify_compute_size (GDK_TOPLEVEL (surface), &size);
g_warn_if_fail (size.width > 0);
g_warn_if_fail (size.height > 0);
if (self->layout != NULL &&
gdk_toplevel_layout_get_resizable (self->layout))
{
geometry.min_width = size.min_width;
geometry.min_height = size.min_height;
mask = GDK_HINT_MIN_SIZE;
}
else
{
geometry.max_width = geometry.min_width = size.width;
geometry.max_height = geometry.min_height = size.height;
mask = GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE;
}
if (size.shadow.is_valid)
_gdk_macos_surface_set_shadow (macos_surface,
size.shadow.top,
size.shadow.right,
size.shadow.bottom,
size.shadow.left);
_gdk_macos_surface_set_geometry_hints (macos_surface, &geometry, mask);
if (surface->state & (GDK_TOPLEVEL_STATE_FULLSCREEN |
GDK_TOPLEVEL_STATE_MAXIMIZED |
GDK_TOPLEVEL_STATE_TILED |
GDK_TOPLEVEL_STATE_TOP_TILED |
GDK_TOPLEVEL_STATE_RIGHT_TILED |
GDK_TOPLEVEL_STATE_BOTTOM_TILED |
GDK_TOPLEVEL_STATE_LEFT_TILED |
GDK_TOPLEVEL_STATE_MINIMIZED) ||
[macos_surface->window inLiveResize])
return FALSE;
/* If we delayed a user resize until the beginning of the frame,
* apply it now so we can start processing updates for it.
*/
if (macos_surface->next_layout.width > 0 &&
macos_surface->next_layout.height > 0)
{
int root_x = macos_surface->next_layout.root_x;
int root_y = macos_surface->next_layout.root_y;
int width = macos_surface->next_layout.width;
int height = macos_surface->next_layout.height;
gdk_surface_constrain_size (&geometry, mask,
width, height,
&width, &height);
macos_surface->next_layout.width = 0;
macos_surface->next_layout.height = 0;
_gdk_macos_surface_move_resize (macos_surface,
root_x, root_y,
width, height);
return FALSE;
}
gdk_surface_constrain_size (&geometry, mask,
size.width, size.height,
&size.width, &size.height);
if ((size.width != self->last_computed_width ||
size.height != self->last_computed_height) &&
(size.width != surface->width ||
size.height != surface->height))
{
self->last_computed_width = size.width;
self->last_computed_height = size.height;
_gdk_macos_surface_resize (macos_surface, size.width, size.height);
}
return FALSE;
}
static void
_gdk_macos_toplevel_surface_request_layout (GdkSurface *surface)
{
+10 -4
View File
@@ -201,17 +201,23 @@ get_egl_window_size (GdkSurface *surface,
if (GDK_DISPLAY_DEBUG_CHECK (display, GL_NO_FRACTIONAL))
{
GDK_DISPLAY_DEBUG (display, OPENGL, "Using integer scale %d for EGL window", gdk_fractional_scale_to_int (&impl->scale));
*width = surface->width * gdk_fractional_scale_to_int (&impl->scale);
*height = surface->height * gdk_fractional_scale_to_int (&impl->scale);
GDK_DISPLAY_DEBUG (display, OPENGL, "Using integer scale %d for EGL window (%d %d => %d %d)",
gdk_fractional_scale_to_int (&impl->scale),
surface->width, surface->height,
*width, *height);
}
else
{
GDK_DISPLAY_DEBUG (display, OPENGL, "Using fractional scale %g for EGL window", gdk_fractional_scale_to_double (&impl->scale));
*width = gdk_fractional_scale_scale (&impl->scale, surface->width),
*height = gdk_fractional_scale_scale (&impl->scale, surface->height);
GDK_DISPLAY_DEBUG (display, OPENGL, "Using fractional scale %g for EGL window (%d %d => %d %d)",
gdk_fractional_scale_to_double (&impl->scale),
surface->width, surface->height,
*width, *height);
}
}
+48 -8
View File
@@ -458,6 +458,49 @@ gdk_wayland_toplevel_compute_size (GdkSurface *surface)
return FALSE;
}
static gboolean
has_per_edge_tiling_info (GdkToplevelState state)
{
return state & (GDK_TOPLEVEL_STATE_TOP_TILED |
GDK_TOPLEVEL_STATE_RIGHT_TILED |
GDK_TOPLEVEL_STATE_BOTTOM_TILED |
GDK_TOPLEVEL_STATE_LEFT_TILED);
}
static GdkToplevelState
infer_edge_constraints (GdkToplevelState state)
{
if (state & (GDK_TOPLEVEL_STATE_MAXIMIZED | GDK_TOPLEVEL_STATE_FULLSCREEN))
return state;
if (!(state & GDK_TOPLEVEL_STATE_TILED) || !has_per_edge_tiling_info (state))
return state |
GDK_TOPLEVEL_STATE_TOP_RESIZABLE |
GDK_TOPLEVEL_STATE_RIGHT_RESIZABLE |
GDK_TOPLEVEL_STATE_BOTTOM_RESIZABLE |
GDK_TOPLEVEL_STATE_LEFT_RESIZABLE;
if (!(state & GDK_TOPLEVEL_STATE_TOP_TILED))
state |= GDK_TOPLEVEL_STATE_TOP_RESIZABLE;
if (!(state & GDK_TOPLEVEL_STATE_RIGHT_TILED))
state |= GDK_TOPLEVEL_STATE_RIGHT_RESIZABLE;
if (!(state & GDK_TOPLEVEL_STATE_BOTTOM_TILED))
state |= GDK_TOPLEVEL_STATE_BOTTOM_RESIZABLE;
if (!(state & GDK_TOPLEVEL_STATE_LEFT_TILED))
state |= GDK_TOPLEVEL_STATE_LEFT_RESIZABLE;
return state;
}
static gboolean
supports_native_edge_constraints (GdkWaylandToplevel*toplevel)
{
struct gtk_surface1 *gtk_surface = toplevel->display_server.gtk_surface;
if (!gtk_surface)
return FALSE;
return gtk_surface1_get_version (gtk_surface) >= GTK_SURFACE1_CONFIGURE_EDGES_SINCE_VERSION;
}
static void
gdk_wayland_toplevel_handle_configure (GdkWaylandSurface *wayland_surface)
{
@@ -475,6 +518,9 @@ gdk_wayland_toplevel_handle_configure (GdkWaylandSurface *wayland_surface)
new_state = wayland_toplevel->pending.state;
wayland_toplevel->pending.state = 0;
if (!supports_native_edge_constraints (wayland_toplevel))
new_state = infer_edge_constraints (new_state);
is_resizing = wayland_toplevel->pending.is_resizing;
wayland_toplevel->pending.is_resizing = FALSE;
@@ -1990,13 +2036,7 @@ gdk_wayland_toplevel_titlebar_gesture (GdkToplevel *toplevel,
static gboolean
gdk_wayland_toplevel_supports_edge_constraints (GdkToplevel *toplevel)
{
GdkWaylandToplevel *wayland_toplevel = GDK_WAYLAND_TOPLEVEL (toplevel);
struct gtk_surface1 *gtk_surface = wayland_toplevel->display_server.gtk_surface;
if (!gtk_surface)
return FALSE;
return gtk_surface1_get_version (gtk_surface) >= GTK_SURFACE1_CONFIGURE_EDGES_SINCE_VERSION;
return TRUE;
}
static void
@@ -2667,7 +2707,7 @@ gdk_wayland_toplevel_set_transient_for_exported (GdkToplevel *toplevel,
g_return_val_if_fail (GDK_IS_WAYLAND_TOPLEVEL (toplevel), FALSE);
g_return_val_if_fail (GDK_IS_WAYLAND_DISPLAY (display), FALSE);
if (!display_wayland->xdg_importer)
if (!display_wayland->xdg_importer && !display_wayland->xdg_importer_v2)
{
g_warning ("Server is missing xdg_foreign support");
return FALSE;
+2
View File
@@ -3015,6 +3015,8 @@ gdk_x11_display_init_gl_backend (GdkX11Display *self,
self->egl_version = epoxy_egl_version (egl_display);
XFree (visinfo);
return TRUE;
}
+15 -2
View File
@@ -1,5 +1,7 @@
#include "config.h"
#include <gdk/gdkprofilerprivate.h>
#include "gskglbufferprivate.h"
struct _GskGLBuffer
@@ -14,6 +16,9 @@ struct _GskGLBuffer
G_DEFINE_TYPE (GskGLBuffer, gsk_gl_buffer, GSK_TYPE_GPU_BUFFER)
static guint profiler_buffer_uploads_id;
static gint64 profiler_buffer_uploads;
static void
gsk_gl_buffer_finalize (GObject *object)
{
@@ -34,13 +39,19 @@ gsk_gl_buffer_map (GskGpuBuffer *buffer)
}
static void
gsk_gl_buffer_unmap (GskGpuBuffer *buffer)
gsk_gl_buffer_unmap (GskGpuBuffer *buffer,
gsize used)
{
GskGLBuffer *self = GSK_GL_BUFFER (buffer);
if (used == 0)
return;
gsk_gl_buffer_bind (self);
glBufferSubData (self->target, 0, gsk_gpu_buffer_get_size (buffer), self->data);
profiler_buffer_uploads += used;
glBufferSubData (self->target, 0, used, self->data);
gdk_profiler_set_int_counter (profiler_buffer_uploads_id, profiler_buffer_uploads);
}
static void
@@ -53,6 +64,8 @@ gsk_gl_buffer_class_init (GskGLBufferClass *klass)
buffer_class->unmap = gsk_gl_buffer_unmap;
gobject_class->finalize = gsk_gl_buffer_finalize;
profiler_buffer_uploads_id = gdk_profiler_define_int_counter ("ngl-buffer-uploads", "Number of bytes uploaded to GPU");
}
static void
+14 -26
View File
@@ -5,6 +5,7 @@
#include "gskglbufferprivate.h"
#include "gskglimageprivate.h"
struct _GskGLDescriptors
{
GskGpuDescriptors parent_instance;
@@ -13,16 +14,12 @@ struct _GskGLDescriptors
guint n_external;
};
G_DEFINE_TYPE (GskGLDescriptors, gsk_gl_descriptors, GSK_TYPE_GPU_DESCRIPTORS)
static void
gsk_gl_descriptors_finalize (GObject *object)
gsk_gl_descriptors_finalize (GskGpuDescriptors *desc)
{
GskGLDescriptors *self = GSK_GL_DESCRIPTORS (object);
GskGLDescriptors *self = GSK_GL_DESCRIPTORS (desc);
g_object_unref (self->device);
G_OBJECT_CLASS (gsk_gl_descriptors_parent_class)->finalize (object);
}
static gboolean
@@ -72,33 +69,24 @@ gsk_gl_descriptors_add_buffer (GskGpuDescriptors *desc,
return TRUE;
}
static void
gsk_gl_descriptors_class_init (GskGLDescriptorsClass *klass)
static GskGpuDescriptorsClass GSK_GL_DESCRIPTORS_CLASS =
{
GskGpuDescriptorsClass *descriptors_class = GSK_GPU_DESCRIPTORS_CLASS (klass);
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->finalize = gsk_gl_descriptors_finalize;
descriptors_class->add_image = gsk_gl_descriptors_add_image;
descriptors_class->add_buffer = gsk_gl_descriptors_add_buffer;
}
static void
gsk_gl_descriptors_init (GskGLDescriptors *self)
{
}
.finalize = gsk_gl_descriptors_finalize,
.add_image = gsk_gl_descriptors_add_image,
.add_buffer = gsk_gl_descriptors_add_buffer,
};
GskGpuDescriptors *
gsk_gl_descriptors_new (GskGLDevice *device)
{
GskGLDescriptors *self;
GskGpuDescriptors *desc;
self = g_object_new (GSK_TYPE_GL_DESCRIPTORS, NULL);
desc = gsk_gpu_descriptors_new ((GskGpuDescriptorsClass *) &GSK_GL_DESCRIPTORS_CLASS,
sizeof (GskGLDescriptors));
self->device = g_object_ref (device);
GSK_GL_DESCRIPTORS (desc)->device = g_object_ref (device);
return GSK_GPU_DESCRIPTORS (self);
return desc;
}
guint
@@ -110,7 +98,7 @@ gsk_gl_descriptors_get_n_external (GskGLDescriptors *self)
void
gsk_gl_descriptors_use (GskGLDescriptors *self)
{
GskGpuDescriptors *desc = GSK_GPU_DESCRIPTORS (self);
GskGpuDescriptors *desc = &self->parent_instance;
gsize i, ext, n_textures;
n_textures = 16 - 3 * self->n_external;
+3 -2
View File
@@ -6,9 +6,10 @@
G_BEGIN_DECLS
#define GSK_TYPE_GL_DESCRIPTORS (gsk_gl_descriptors_get_type ())
typedef struct _GskGLDescriptors GskGLDescriptors;
#define GSK_GL_DESCRIPTORS(d) ((GskGLDescriptors *) (d))
G_DECLARE_FINAL_TYPE (GskGLDescriptors, gsk_gl_descriptors, GSK, GL_DESCRIPTORS, GskGpuDescriptors)
GskGpuDescriptors * gsk_gl_descriptors_new (GskGLDevice *device);
+7
View File
@@ -9,6 +9,7 @@
#include "gdk/gdkdisplayprivate.h"
#include "gdk/gdkglcontextprivate.h"
#include "gdk/gdkprofilerprivate.h"
#include <glib/gi18n-lib.h>
@@ -473,6 +474,7 @@ gsk_gl_device_load_program (GskGLDevice *self,
guint n_external_textures,
GError **error)
{
G_GNUC_UNUSED gint64 begin_time = GDK_PROFILER_CURRENT_TIME;
GLuint vertex_shader_id, fragment_shader_id, program_id;
GLint link_status;
@@ -527,6 +529,11 @@ gsk_gl_device_load_program (GskGLDevice *self,
return 0;
}
gdk_profiler_end_markf (begin_time,
"Compile Program",
"name=%s id=%u frag=%u vert=%u",
op_class->shader_name, program_id, fragment_shader_id, vertex_shader_id);
return program_id;
}
+3 -2
View File
@@ -45,8 +45,9 @@ gsk_gpu_buffer_map (GskGpuBuffer *self)
}
void
gsk_gpu_buffer_unmap (GskGpuBuffer *self)
gsk_gpu_buffer_unmap (GskGpuBuffer *self,
gsize size)
{
GSK_GPU_BUFFER_GET_CLASS (self)->unmap (self);
GSK_GPU_BUFFER_GET_CLASS (self)->unmap (self, size);
}
+4 -2
View File
@@ -23,7 +23,8 @@ struct _GskGpuBufferClass
GObjectClass parent_class;
guchar * (* map) (GskGpuBuffer *self);
void (* unmap) (GskGpuBuffer *self);
void (* unmap) (GskGpuBuffer *self,
gsize used);
};
GType gsk_gpu_buffer_get_type (void) G_GNUC_CONST;
@@ -34,7 +35,8 @@ void gsk_gpu_buffer_setup (GskGpuB
gsize gsk_gpu_buffer_get_size (GskGpuBuffer *self);
guchar * gsk_gpu_buffer_map (GskGpuBuffer *self);
void gsk_gpu_buffer_unmap (GskGpuBuffer *self);
void gsk_gpu_buffer_unmap (GskGpuBuffer *self,
gsize used);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GskGpuBuffer, g_object_unref)
+15
View File
@@ -30,6 +30,14 @@ gsk_gpu_clip_init_rect (GskGpuClip *clip,
gsk_rounded_rect_init_from_rect (&clip->rect, rect, 0);
}
static void
gsk_gpu_clip_init_rounded_rect (GskGpuClip *self,
const GskRoundedRect *rect)
{
self->type = GSK_GPU_CLIP_ROUNDED;
gsk_rounded_rect_init_copy (&self->rect, rect);
}
void
gsk_gpu_clip_init_copy (GskGpuClip *self,
const GskGpuClip *src)
@@ -129,6 +137,13 @@ gsk_gpu_clip_intersect_rounded_rect (GskGpuClip *dest,
break;
case GSK_GPU_CLIP_NONE:
res = gsk_rounded_rect_intersect_with_rect (rounded, &src->rect.bounds, &dest->rect);
if (gsk_gpu_clip_init_after_intersection (dest, res))
break;
/* XXX: This may grow the bounds quite substantially */
gsk_gpu_clip_init_rounded_rect (dest, rounded);
break;
case GSK_GPU_CLIP_CONTAINED:
case GSK_GPU_CLIP_RECT:
res = gsk_rounded_rect_intersect_with_rect (rounded, &src->rect.bounds, &dest->rect);
+1
View File
@@ -16,6 +16,7 @@ typedef enum {
GSK_GPU_CLIP_ALL_CLIPPED,
/* No clipping is necessary, but the clip rect is set
* to the actual bounds of the underlying framebuffer
* or handled via the scissor.
*/
GSK_GPU_CLIP_NONE,
/* The clip exists outside the rect, so clipping must
+45 -24
View File
@@ -52,43 +52,39 @@ gsk_gpu_buffer_entry_clear (gpointer data)
#define GDK_ARRAY_NO_MEMSET 1
#include "gdk/gdkarrayimpl.c"
typedef struct _GskGpuDescriptorsPrivate GskGpuDescriptorsPrivate;
struct _GskGpuDescriptorsPrivate
{
GskGpuImageEntries images;
GskGpuBufferEntries buffers;
};
G_DEFINE_TYPE_WITH_PRIVATE (GskGpuDescriptors, gsk_gpu_descriptors, G_TYPE_OBJECT)
static void
gsk_gpu_descriptors_finalize (GObject *object)
static inline GskGpuDescriptorsPrivate *
gsk_gpu_descriptors_get_instance_private (GskGpuDescriptors *self)
{
GskGpuDescriptors *self = GSK_GPU_DESCRIPTORS (object);
GskGpuDescriptorsPrivate *priv = gsk_gpu_descriptors_get_instance_private (self);
gsk_gpu_image_entries_clear (&priv->images);
gsk_gpu_buffer_entries_clear (&priv->buffers);
G_OBJECT_CLASS (gsk_gpu_descriptors_parent_class)->finalize (object);
return (GskGpuDescriptorsPrivate *) (((guchar *)self) - sizeof (GskGpuDescriptorsPrivate));
}
static void
gsk_gpu_descriptors_class_init (GskGpuDescriptorsClass *klass)
/* Just for subclasses */
GskGpuDescriptors *
gsk_gpu_descriptors_new (GskGpuDescriptorsClass *desc_class,
gsize child_size)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GskGpuDescriptors *self;
GskGpuDescriptorsPrivate *priv;
guchar *data;
object_class->finalize = gsk_gpu_descriptors_finalize;
}
data = g_new0 (guchar, child_size + sizeof (GskGpuDescriptorsPrivate));
static void
gsk_gpu_descriptors_init (GskGpuDescriptors *self)
{
GskGpuDescriptorsPrivate *priv = gsk_gpu_descriptors_get_instance_private (self);
priv = (GskGpuDescriptorsPrivate *) data;
self = (GskGpuDescriptors *) (data + sizeof (GskGpuDescriptorsPrivate));
self->ref_count = 1;
self->desc_class = desc_class;
gsk_gpu_image_entries_init (&priv->images);
gsk_gpu_buffer_entries_init (&priv->buffers);
return self;
}
gsize
@@ -189,7 +185,7 @@ gsk_gpu_descriptors_add_image (GskGpuDescriptors *self,
}
}
if (!GSK_GPU_DESCRIPTORS_GET_CLASS (self)->add_image (self, image, sampler, &descriptor))
if (!self->desc_class->add_image (self, image, sampler, &descriptor))
return FALSE;
gsk_gpu_image_entries_append (&priv->images,
@@ -224,7 +220,7 @@ gsk_gpu_descriptors_add_buffer (GskGpuDescriptors *self,
}
}
if (!GSK_GPU_DESCRIPTORS_GET_CLASS (self)->add_buffer (self, buffer, &descriptor))
if (!self->desc_class->add_buffer (self, buffer, &descriptor))
return FALSE;
gsk_gpu_buffer_entries_append (&priv->buffers,
@@ -238,3 +234,28 @@ gsk_gpu_descriptors_add_buffer (GskGpuDescriptors *self,
return TRUE;
}
GskGpuDescriptors *
gsk_gpu_descriptors_ref (GskGpuDescriptors *self)
{
self->ref_count++;
return self;
}
void
gsk_gpu_descriptors_unref (GskGpuDescriptors *self)
{
self->ref_count--;
if (self->ref_count == 0)
{
GskGpuDescriptorsPrivate *priv = gsk_gpu_descriptors_get_instance_private (self);
self->desc_class->finalize (self);
gsk_gpu_image_entries_clear (&priv->images);
gsk_gpu_buffer_entries_clear (&priv->buffers);
g_free (priv);
}
}
+13 -12
View File
@@ -4,24 +4,23 @@
G_BEGIN_DECLS
#define GSK_TYPE_GPU_DESCRIPTORS (gsk_gpu_descriptors_get_type ())
#define GSK_GPU_DESCRIPTORS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GSK_TYPE_GPU_DESCRIPTORS, GskGpuDescriptors))
#define GSK_GPU_DESCRIPTORS_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), GSK_TYPE_GPU_DESCRIPTORS, GskGpuDescriptorsClass))
#define GSK_IS_GPU_DESCRIPTORS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GSK_TYPE_GPU_DESCRIPTORS))
#define GSK_IS_GPU_DESCRIPTORS_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GSK_TYPE_GPU_DESCRIPTORS))
#define GSK_GPU_DESCRIPTORS_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GSK_TYPE_GPU_DESCRIPTORS, GskGpuDescriptorsClass))
typedef struct _GskGpuDescriptors GskGpuDescriptors;
typedef struct _GskGpuDescriptorsClass GskGpuDescriptorsClass;
typedef struct _GskGpuDescriptorsPrivate GskGpuDescriptorsPrivate;
#define GSK_GPU_DESCRIPTORS(d) ((GskGpuDescriptors *) (d))
struct _GskGpuDescriptors
{
GObject parent_instance;
GskGpuDescriptorsClass *desc_class;
int ref_count;
GskGpuDescriptorsPrivate *priv;
};
struct _GskGpuDescriptorsClass
{
GObjectClass parent_class;
void (* finalize) (GskGpuDescriptors *self);
gboolean (* add_image) (GskGpuDescriptors *self,
GskGpuImage *image,
GskGpuSampler sampler,
@@ -31,7 +30,8 @@ struct _GskGpuDescriptorsClass
guint32 *out_id);
};
GType gsk_gpu_descriptors_get_type (void) G_GNUC_CONST;
GskGpuDescriptors * gsk_gpu_descriptors_ref (GskGpuDescriptors *self);
void gsk_gpu_descriptors_unref (GskGpuDescriptors *self);
gsize gsk_gpu_descriptors_get_n_images (GskGpuDescriptors *self);
gsize gsk_gpu_descriptors_get_n_buffers (GskGpuDescriptors *self);
@@ -55,7 +55,8 @@ gboolean gsk_gpu_descriptors_add_buffer (GskGpuD
GskGpuBuffer *buffer,
guint32 *out_descriptor);
GskGpuDescriptors *gsk_gpu_descriptors_new (GskGpuDescriptorsClass *desc_class,
gsize child_size);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GskGpuDescriptors, g_object_unref)
G_END_DECLS
+18 -7
View File
@@ -11,6 +11,7 @@
#include "gdk/gdkprofilerprivate.h"
#include "gsk/gskdebugprivate.h"
#include "gsk/gskprivate.h"
#define MAX_SLICES_PER_ATLAS 64
@@ -905,6 +906,7 @@ gsk_gpu_device_lookup_glyph_image (GskGpuDevice *self,
GskGpuImage *image;
gsize atlas_x, atlas_y, padding;
float subpixel_x, subpixel_y;
PangoFont *scaled_font;
cache = g_hash_table_lookup (priv->glyph_cache, &lookup);
if (cache)
@@ -916,13 +918,20 @@ gsk_gpu_device_lookup_glyph_image (GskGpuDevice *self,
return cache->image;
}
/* Note: we want to scale the font to the required size *and* ensure that
* metrics hinting is off. The latter is necessary since pango lets metrics
* hinting influence the rendering of hexboxes, and we get bad outcomes if
* that happens.
*/
scaled_font = gsk_reload_font (font, scale, CAIRO_HINT_METRICS_OFF, CAIRO_HINT_STYLE_DEFAULT, CAIRO_ANTIALIAS_DEFAULT);
subpixel_x = (flags & 3) / 4.f;
subpixel_y = ((flags >> 2) & 3) / 4.f;
pango_font_get_glyph_extents (font, glyph, &ink_rect, NULL);
origin.x = floor (ink_rect.x * scale / PANGO_SCALE + subpixel_x);
origin.y = floor (ink_rect.y * scale / PANGO_SCALE + subpixel_y);
rect.size.width = ceil ((ink_rect.x + ink_rect.width) * scale / PANGO_SCALE + subpixel_x) - origin.x;
rect.size.height = ceil ((ink_rect.y + ink_rect.height) * scale / PANGO_SCALE + subpixel_y) - origin.y;
pango_font_get_glyph_extents (scaled_font, glyph, &ink_rect, NULL);
origin.x = floor (ink_rect.x * 1.0 / PANGO_SCALE + subpixel_x);
origin.y = floor (ink_rect.y * 1.0 / PANGO_SCALE + subpixel_y);
rect.size.width = ceil ((ink_rect.x + ink_rect.width) * 1.0 / PANGO_SCALE + subpixel_x) - origin.x;
rect.size.height = ceil ((ink_rect.y + ink_rect.height) * 1.0 / PANGO_SCALE + subpixel_y) - origin.y;
padding = 1;
image = gsk_gpu_device_add_atlas_image (self,
@@ -956,7 +965,7 @@ gsk_gpu_device_lookup_glyph_image (GskGpuDevice *self,
gsk_gpu_upload_glyph_op (frame,
cache->image,
font,
scaled_font,
glyph,
&(cairo_rectangle_int_t) {
.x = rect.origin.x - padding,
@@ -964,7 +973,6 @@ gsk_gpu_device_lookup_glyph_image (GskGpuDevice *self,
.width = rect.size.width + 2 * padding,
.height = rect.size.height + 2 * padding,
},
scale,
&GRAPHENE_POINT_INIT (cache->origin.x + padding,
cache->origin.y + padding));
@@ -973,6 +981,9 @@ gsk_gpu_device_lookup_glyph_image (GskGpuDevice *self,
*out_bounds = cache->bounds;
*out_origin = cache->origin;
g_object_unref (scaled_font);
return cache->image;
}
+1 -1
View File
@@ -126,7 +126,7 @@ gsk_gpu_download_op_vk_create (GskGpuDownloadOp *self)
bytes,
stride);
g_bytes_unref (bytes);
gsk_gpu_buffer_unmap (self->buffer);
gsk_gpu_buffer_unmap (self->buffer, 0);
}
static GskGpuOp *
+5 -5
View File
@@ -426,7 +426,7 @@ gsk_gpu_frame_reserve_vertex_data (GskGpuFrame *self,
if (priv->vertex_buffer_data)
{
memcpy (new_data, priv->vertex_buffer_data, old_size);
gsk_gpu_buffer_unmap (priv->vertex_buffer);
gsk_gpu_buffer_unmap (priv->vertex_buffer, old_size);
}
g_object_unref (priv->vertex_buffer);
priv->vertex_buffer = new_buffer;
@@ -434,7 +434,7 @@ gsk_gpu_frame_reserve_vertex_data (GskGpuFrame *self,
}
priv->vertex_buffer_used = size_needed;
return size_needed - size;
}
@@ -480,7 +480,7 @@ gsk_gpu_frame_write_storage_buffer (GskGpuFrame *self,
{
g_assert (offset > 0);
gsk_gpu_buffer_unmap (priv->storage_buffer);
gsk_gpu_buffer_unmap (priv->storage_buffer, 0);
g_clear_object (&priv->storage_buffer);
priv->storage_buffer_data = 0;
priv->storage_buffer_used = 0;
@@ -591,14 +591,14 @@ gsk_gpu_frame_submit (GskGpuFrame *self)
if (priv->vertex_buffer)
{
gsk_gpu_buffer_unmap (priv->vertex_buffer);
gsk_gpu_buffer_unmap (priv->vertex_buffer, priv->vertex_buffer_used);
priv->vertex_buffer_data = NULL;
priv->vertex_buffer_used = 0;
}
if (priv->storage_buffer_data)
{
gsk_gpu_buffer_unmap (priv->storage_buffer);
gsk_gpu_buffer_unmap (priv->storage_buffer, priv->storage_buffer_used);
priv->storage_buffer_data = NULL;
priv->storage_buffer_used = 0;
}
+106 -48
View File
@@ -40,6 +40,7 @@
#include "gskroundedrectprivate.h"
#include "gskstrokeprivate.h"
#include "gsktransformprivate.h"
#include "gskprivate.h"
#include "gdk/gdkrgbaprivate.h"
#include "gdk/gdksubsurfaceprivate.h"
@@ -151,7 +152,7 @@ static void
gsk_gpu_node_processor_finish (GskGpuNodeProcessor *self)
{
g_clear_pointer (&self->modelview, gsk_transform_unref);
g_clear_object (&self->desc);
g_clear_pointer (&self->desc, gsk_gpu_descriptors_unref);
}
static void
@@ -169,7 +170,7 @@ gsk_gpu_node_processor_init (GskGpuNodeProcessor *self,
self->frame = frame;
if (desc)
self->desc = g_object_ref (desc);
self->desc = gsk_gpu_descriptors_ref (desc);
else
self->desc = NULL;
@@ -183,13 +184,13 @@ gsk_gpu_node_processor_init (GskGpuNodeProcessor *self,
{
float scale_x = viewport->size.width / width;
float scale_y = viewport->size.height / height;
gsk_gpu_clip_init_rect (&self->clip,
&GRAPHENE_RECT_INIT (
scale_x * clip->x,
scale_y * clip->y,
scale_x * clip->width,
scale_y * clip->height
));
gsk_gpu_clip_init_empty (&self->clip,
&GRAPHENE_RECT_INIT (
scale_x * clip->x,
scale_y * clip->y,
scale_x * clip->width,
scale_y * clip->height
));
}
self->modelview = NULL;
@@ -267,7 +268,7 @@ gsk_gpu_node_processor_add_image (GskGpuNodeProcessor *self,
if (gsk_gpu_descriptors_add_image (self->desc, image, sampler, &descriptor))
return descriptor;
g_object_unref (self->desc);
gsk_gpu_descriptors_unref (self->desc);
}
self->desc = gsk_gpu_frame_create_descriptors (self->frame);
@@ -544,7 +545,7 @@ gsk_gpu_pattern_writer_finish (GskGpuPatternWriter *self)
{
pattern_buffer_clear (&self->buffer);
g_assert (self->stack == 0);
g_clear_object (&self->desc);
g_clear_pointer (&self->desc, gsk_gpu_descriptors_unref);
}
static gboolean
@@ -1327,7 +1328,7 @@ gsk_gpu_node_processor_add_node_clipped (GskGpuNodeProcessor *self,
gsk_gpu_clip_init_copy (&self->clip, &old_clip);
return;
}
else if (self->clip.type == GSK_GPU_CLIP_RECT &&
else if ((self->clip.type == GSK_GPU_CLIP_RECT || self->clip.type == GSK_GPU_CLIP_CONTAINED) &&
gsk_rect_contains_rect (&self->clip.rect.bounds, &clip))
{
self->clip.type = GSK_GPU_CLIP_NONE;
@@ -1610,7 +1611,7 @@ gsk_gpu_node_processor_add_transform_node (GskGpuNodeProcessor *self,
inverse = gsk_transform_invert (gsk_transform_ref (clip_transform));
gsk_transform_transform_bounds (inverse, &old_clip.rect.bounds, &new_bounds);
gsk_transform_unref (inverse);
gsk_gpu_clip_init_contained (&self->clip, &new_bounds);
gsk_gpu_clip_init_empty (&self->clip, &new_bounds);
}
else if (!gsk_gpu_clip_transform (&self->clip, &old_clip, clip_transform, &child->bounds))
{
@@ -1648,10 +1649,13 @@ gsk_gpu_node_processor_add_transform_node (GskGpuNodeProcessor *self,
extract_scale_from_transform (self->modelview, &scale_x, &scale_y);
old_pixels = graphene_vec2_get_x (&old_scale) * graphene_vec2_get_y (&old_scale) *
old_clip.rect.bounds.size.width * old_clip.rect.bounds.size.height;
new_pixels = scale_x * scale_y * self->clip.rect.bounds.size.width * self->clip.rect.bounds.size.height;
if (new_pixels > 2 * old_pixels)
old_pixels = MAX (graphene_vec2_get_x (&old_scale) * old_clip.rect.bounds.size.width,
graphene_vec2_get_y (&old_scale) * old_clip.rect.bounds.size.height);
new_pixels = MAX (scale_x * self->clip.rect.bounds.size.width,
scale_y * self->clip.rect.bounds.size.height);
/* Check that our offscreen doesn't get too big. 1.5 ~ sqrt(2) */
if (new_pixels > 1.5 * old_pixels)
{
float forced_downscale = 2 * old_pixels / new_pixels;
scale_x *= forced_downscale;
@@ -2055,7 +2059,7 @@ gsk_gpu_node_processor_add_texture_scale_node (GskGpuNodeProcessor *self,
guint32 descriptor;
gboolean need_mipmap, need_offscreen;
need_offscreen = self->modelview != NULL ||
need_offscreen = self->modelview != NULL ||
!graphene_vec2_equal (&self->scale, graphene_vec2_one ());
if (need_offscreen)
{
@@ -2996,7 +3000,12 @@ gsk_gpu_node_processor_add_glyph_node (GskGpuNodeProcessor *self,
guint i, num_glyphs;
float scale, inv_scale;
GdkRGBA color;
gboolean glyph_align;
float align_scale_x, align_scale_y;
float inv_align_scale_x, inv_align_scale_y;
unsigned int flags_mask;
GskGpuImage *last_image;
guint32 descriptor;
const float inv_pango_scale = 1.f / PANGO_SCALE;
if (self->opacity < 1.0 &&
gsk_text_node_has_color_glyphs (node))
@@ -3005,9 +3014,8 @@ gsk_gpu_node_processor_add_glyph_node (GskGpuNodeProcessor *self,
return;
}
glyph_align = gsk_gpu_frame_should_optimize (self->frame, GSK_GPU_OPTIMIZE_GLYPH_ALIGN) &&
gsk_transform_get_category (self->modelview) >= GSK_TRANSFORM_CATEGORY_2D;
device = gsk_gpu_frame_get_device (self->frame);
color = *gsk_text_node_get_color (node);
color.alpha *= self->opacity;
num_glyphs = gsk_text_node_get_num_glyphs (node);
@@ -3020,29 +3028,38 @@ gsk_gpu_node_processor_add_glyph_node (GskGpuNodeProcessor *self,
scale = MAX (graphene_vec2_get_x (&self->scale), graphene_vec2_get_y (&self->scale));
inv_scale = 1.f / scale;
if (gsk_font_get_hint_style (font) != CAIRO_HINT_STYLE_NONE)
{
align_scale_x = scale * 4;
align_scale_y = scale;
flags_mask = 3;
}
else
{
align_scale_x = align_scale_y = scale * 4;
flags_mask = 15;
}
inv_align_scale_x = 1 / align_scale_x;
inv_align_scale_y = 1 / align_scale_y;
last_image = NULL;
descriptor = 0;
for (i = 0; i < num_glyphs; i++)
{
GskGpuImage *image;
graphene_rect_t glyph_bounds, glyph_tex_rect;
graphene_point_t glyph_offset, glyph_origin;
guint32 descriptor;
GskGpuGlyphLookupFlags flags;
glyph_origin = GRAPHENE_POINT_INIT (offset.x + (float) glyphs[i].geometry.x_offset / PANGO_SCALE,
offset.y + (float) glyphs[i].geometry.y_offset / PANGO_SCALE);
if (glyph_align)
{
glyph_origin.x = roundf (glyph_origin.x * scale * 4);
glyph_origin.y = roundf (glyph_origin.y * scale * 4);
flags = ((int) glyph_origin.x & 3) |
(((int) glyph_origin.y & 3) << 2);
glyph_origin.x = 0.25 * inv_scale * glyph_origin.x;
glyph_origin.y = 0.25 * inv_scale * glyph_origin.y;
}
else
{
flags = 0;
}
glyph_origin = GRAPHENE_POINT_INIT (offset.x + glyphs[i].geometry.x_offset * inv_pango_scale,
offset.y + glyphs[i].geometry.y_offset * inv_pango_scale);
glyph_origin.x = floorf (glyph_origin.x * align_scale_x + 0.5f);
glyph_origin.y = floorf (glyph_origin.y * align_scale_y + 0.5f);
flags = (((int) glyph_origin.x & 3) | (((int) glyph_origin.y & 3) << 2)) & flags_mask;
glyph_origin.x *= inv_align_scale_x;
glyph_origin.y *= inv_align_scale_y;
image = gsk_gpu_device_lookup_glyph_image (device,
self->frame,
@@ -3053,11 +3070,23 @@ gsk_gpu_node_processor_add_glyph_node (GskGpuNodeProcessor *self,
&glyph_bounds,
&glyph_offset);
gsk_rect_scale (&GRAPHENE_RECT_INIT (-glyph_bounds.origin.x, -glyph_bounds.origin.y, gsk_gpu_image_get_width (image), gsk_gpu_image_get_height (image)), inv_scale, inv_scale, &glyph_tex_rect);
gsk_rect_scale (&GRAPHENE_RECT_INIT(0, 0, glyph_bounds.size.width, glyph_bounds.size.height), inv_scale, inv_scale, &glyph_bounds);
glyph_tex_rect = GRAPHENE_RECT_INIT (-glyph_bounds.origin.x * inv_scale,
-glyph_bounds.origin.y * inv_scale,
gsk_gpu_image_get_width (image) * inv_scale,
gsk_gpu_image_get_height (image) * inv_scale);
glyph_bounds = GRAPHENE_RECT_INIT (0,
0,
glyph_bounds.size.width * inv_scale,
glyph_bounds.size.height * inv_scale);
glyph_origin = GRAPHENE_POINT_INIT (glyph_origin.x - glyph_offset.x * inv_scale,
glyph_origin.y - glyph_offset.y * inv_scale);
descriptor = gsk_gpu_node_processor_add_image (self, image, GSK_GPU_SAMPLER_DEFAULT);
if (image != last_image)
{
descriptor = gsk_gpu_node_processor_add_image (self, image, GSK_GPU_SAMPLER_DEFAULT);
last_image = image;
}
if (glyphs[i].attr.is_color)
gsk_gpu_texture_op (self->frame,
gsk_gpu_clip_get_shader_clip (&self->clip, &glyph_offset, &glyph_bounds),
@@ -3076,7 +3105,7 @@ gsk_gpu_node_processor_add_glyph_node (GskGpuNodeProcessor *self,
&glyph_tex_rect,
&color);
offset.x += (float) glyphs[i].geometry.width / PANGO_SCALE;
offset.x += glyphs[i].geometry.width * inv_pango_scale;
}
}
@@ -3093,6 +3122,10 @@ gsk_gpu_node_processor_create_glyph_pattern (GskGpuPatternWriter *self,
guint32 tex_id;
GskGpuImage *last_image;
graphene_point_t offset;
float align_scale_x, align_scale_y;
float inv_align_scale_x, inv_align_scale_y;
unsigned int flags_mask;
const float inv_pango_scale = 1.f / PANGO_SCALE;
if (gsk_text_node_has_color_glyphs (node))
return FALSE;
@@ -3112,18 +3145,43 @@ gsk_gpu_node_processor_create_glyph_pattern (GskGpuPatternWriter *self,
gsk_gpu_pattern_writer_append_rgba (self, gsk_text_node_get_color (node));
gsk_gpu_pattern_writer_append_uint (self, num_glyphs);
if (gsk_font_get_hint_style (font) != CAIRO_HINT_STYLE_NONE)
{
align_scale_x = scale * 4;
align_scale_y = scale;
flags_mask = 3;
}
else
{
align_scale_x = align_scale_y = scale * 4;
flags_mask = 15;
}
inv_align_scale_x = 1 / align_scale_x;
inv_align_scale_y = 1 / align_scale_y;
last_image = NULL;
for (i = 0; i < num_glyphs; i++)
{
GskGpuImage *image;
graphene_rect_t glyph_bounds;
graphene_point_t glyph_offset;
graphene_point_t glyph_offset, glyph_origin;
GskGpuGlyphLookupFlags flags;
glyph_origin = GRAPHENE_POINT_INIT (offset.x + glyphs[i].geometry.x_offset * inv_pango_scale,
offset.y + glyphs[i].geometry.y_offset * inv_pango_scale);
glyph_origin.x = floorf (glyph_origin.x * align_scale_x + 0.5f);
glyph_origin.y = floorf (glyph_origin.y * align_scale_y + 0.5f);
flags = (((int) glyph_origin.x & 3) | (((int) glyph_origin.y & 3) << 2)) & flags_mask;
glyph_origin.x *= inv_align_scale_x;
glyph_origin.y *= inv_align_scale_y;
image = gsk_gpu_device_lookup_glyph_image (device,
self->frame,
font,
glyphs[i].glyph,
0,
flags,
scale,
&glyph_bounds,
&glyph_offset);
@@ -3136,8 +3194,8 @@ gsk_gpu_node_processor_create_glyph_pattern (GskGpuPatternWriter *self,
last_image = image;
}
glyph_offset = GRAPHENE_POINT_INIT (offset.x - glyph_offset.x * inv_scale + (float) glyphs[i].geometry.x_offset / PANGO_SCALE,
offset.y - glyph_offset.y * inv_scale + (float) glyphs[i].geometry.y_offset / PANGO_SCALE);
glyph_origin = GRAPHENE_POINT_INIT (glyph_origin.x - glyph_offset.x * inv_scale,
glyph_origin.y - glyph_offset.y * inv_scale);
gsk_gpu_pattern_writer_append_uint (self, tex_id);
gsk_gpu_pattern_writer_append_rect (self,
@@ -3147,7 +3205,7 @@ gsk_gpu_node_processor_create_glyph_pattern (GskGpuPatternWriter *self,
glyph_bounds.size.width * inv_scale,
glyph_bounds.size.height * inv_scale
),
&glyph_offset);
&glyph_origin);
gsk_gpu_pattern_writer_append_rect (self,
&GRAPHENE_RECT_INIT (
- glyph_bounds.origin.x * inv_scale,
@@ -3155,9 +3213,9 @@ gsk_gpu_node_processor_create_glyph_pattern (GskGpuPatternWriter *self,
gsk_gpu_image_get_width (image) * inv_scale,
gsk_gpu_image_get_height (image) * inv_scale
),
&glyph_offset);
&glyph_origin);
offset.x += (float) glyphs[i].geometry.width / PANGO_SCALE;
offset.x += glyphs[i].geometry.width * inv_pango_scale;
}
return TRUE;
-1
View File
@@ -30,7 +30,6 @@ static const GdkDebugKey gsk_gpu_optimization_keys[] = {
{ "blit", GSK_GPU_OPTIMIZE_BLIT, "Use shaders instead of vkCmdBlit()/glBlitFramebuffer()" },
{ "gradients", GSK_GPU_OPTIMIZE_GRADIENTS, "Don't supersample gradients" },
{ "mipmap", GSK_GPU_OPTIMIZE_MIPMAP, "Avoid creating mipmaps" },
{ "glyph-align", GSK_GPU_OPTIMIZE_GLYPH_ALIGN, "Never align glyphs to the subpixel grid" },
{ "gl-baseinstance", GSK_GPU_OPTIMIZE_GL_BASE_INSTANCE, "Assume no ARB/EXT_base_instance support" },
};
+2 -2
View File
@@ -23,7 +23,7 @@ gsk_gpu_shader_op_finish (GskGpuOp *op)
{
GskGpuShaderOp *self = (GskGpuShaderOp *) op;
g_clear_object (&self->desc);
g_clear_pointer (&self->desc, gsk_gpu_descriptors_unref);
}
#ifdef GDK_RENDERING_VULKAN
@@ -197,7 +197,7 @@ gsk_gpu_shader_op_alloc (GskGpuFrame *frame,
self->variation = variation;
self->clip = clip;
if (desc)
self->desc = g_object_ref (desc);
self->desc = gsk_gpu_descriptors_ref (desc);
else
self->desc = NULL;
self->vertex_offset = gsk_gpu_frame_reserve_vertex_data (frame, op_class->vertex_size);
+1 -2
View File
@@ -118,8 +118,7 @@ typedef enum {
GSK_GPU_OPTIMIZE_BLIT = 1 << 3,
GSK_GPU_OPTIMIZE_GRADIENTS = 1 << 4,
GSK_GPU_OPTIMIZE_MIPMAP = 1 << 5,
GSK_GPU_OPTIMIZE_GLYPH_ALIGN = 1 << 6,
/* These require hardware support */
GSK_GPU_OPTIMIZE_GL_BASE_INSTANCE = 1 << 7,
GSK_GPU_OPTIMIZE_GL_BASE_INSTANCE = 1 << 6,
} GskGpuOptimizations;
+20 -8
View File
@@ -110,8 +110,8 @@ gsk_gpu_upload_op_vk_command_with_area (GskGpuOp *op,
data = gsk_gpu_buffer_map (*buffer);
draw_func (op, data, stride);
gsk_gpu_buffer_unmap (*buffer);
gsk_gpu_buffer_unmap (*buffer, area->height * stride);
vkCmdPipelineBarrier (state->vk_command_buffer,
VK_PIPELINE_STAGE_HOST_BIT,
@@ -485,7 +485,6 @@ struct _GskGpuUploadGlyphOp
cairo_rectangle_int_t area;
PangoFont *font;
PangoGlyph glyph;
float scale;
graphene_point_t origin;
GskGpuBuffer *buffer;
@@ -509,11 +508,19 @@ gsk_gpu_upload_glyph_op_print (GskGpuOp *op,
guint indent)
{
GskGpuUploadGlyphOp *self = (GskGpuUploadGlyphOp *) op;
PangoFontDescription *desc;
char *str;
desc = pango_font_describe_with_absolute_size (self->font);
str = pango_font_description_to_string (desc);
gsk_gpu_print_op (string, indent, "upload-glyph");
gsk_gpu_print_int_rect (string, &self->area);
g_string_append_printf (string, "glyph %u @ %g ", self->glyph, self->scale);
g_string_append_printf (string, "glyph %u font %s ", self->glyph, str);
gsk_gpu_print_newline (string);
g_free (str);
pango_font_description_free (desc);
}
static void
@@ -524,6 +531,7 @@ gsk_gpu_upload_glyph_op_draw (GskGpuOp *op,
GskGpuUploadGlyphOp *self = (GskGpuUploadGlyphOp *) op;
cairo_surface_t *surface;
cairo_t *cr;
PangoRectangle ink_rect = { 0, };
surface = cairo_image_surface_create_for_data (data,
CAIRO_FORMAT_ARGB32,
@@ -531,7 +539,6 @@ gsk_gpu_upload_glyph_op_draw (GskGpuOp *op,
self->area.height,
stride);
cairo_surface_set_device_offset (surface, self->origin.x, self->origin.y);
cairo_surface_set_device_scale (surface, self->scale, self->scale);
cr = cairo_create (surface);
cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
@@ -546,12 +553,19 @@ gsk_gpu_upload_glyph_op_draw (GskGpuOp *op,
/* Draw glyph */
cairo_set_source_rgba (cr, 1, 1, 1, 1);
/* The pango code for drawing hex boxes uses the glyph width */
if (self->glyph & PANGO_GLYPH_UNKNOWN_FLAG)
pango_font_get_glyph_extents (self->font, self->glyph, &ink_rect, NULL);
pango_cairo_show_glyph_string (cr,
self->font,
&(PangoGlyphString) {
.num_glyphs = 1,
.glyphs = (PangoGlyphInfo[1]) { {
.glyph = self->glyph
.glyph = self->glyph,
.geometry = {
.width = ink_rect.width,
}
} }
});
@@ -610,7 +624,6 @@ gsk_gpu_upload_glyph_op (GskGpuFrame *frame,
PangoFont *font,
const PangoGlyph glyph,
const cairo_rectangle_int_t *area,
float scale,
const graphene_point_t *origin)
{
GskGpuUploadGlyphOp *self;
@@ -621,6 +634,5 @@ gsk_gpu_upload_glyph_op (GskGpuFrame *frame,
self->area = *area;
self->font = g_object_ref (font);
self->glyph = glyph;
self->scale = scale;
self->origin = *origin;
}
-1
View File
@@ -25,7 +25,6 @@ void gsk_gpu_upload_glyph_op (GskGpuF
PangoFont *font,
PangoGlyph glyph,
const cairo_rectangle_int_t *area,
float scale,
const graphene_point_t *origin);
G_END_DECLS
+2 -1
View File
@@ -45,7 +45,8 @@ gsk_vulkan_buffer_map (GskGpuBuffer *buffer)
}
static void
gsk_vulkan_buffer_unmap (GskGpuBuffer *buffer)
gsk_vulkan_buffer_unmap (GskGpuBuffer *buffer,
gsize size)
{
}
+19 -14
View File
@@ -6,22 +6,13 @@
#include "gskvulkanframeprivate.h"
#include "gskvulkanimageprivate.h"
G_DEFINE_TYPE (GskVulkanDescriptors, gsk_vulkan_descriptors, GSK_TYPE_GPU_DESCRIPTORS)
static void
gsk_vulkan_descriptors_class_init (GskVulkanDescriptorsClass *klass)
{
}
static void
gsk_vulkan_descriptors_init (GskVulkanDescriptors *self)
{
}
GskVulkanPipelineLayout *
gsk_vulkan_descriptors_get_pipeline_layout (GskVulkanDescriptors *self)
{
return GSK_VULKAN_DESCRIPTORS_GET_CLASS (self)->get_pipeline_layout (self);
GskGpuDescriptors *desc = GSK_GPU_DESCRIPTORS (self);
GskVulkanDescriptorsClass *class = GSK_VULKAN_DESCRIPTORS_CLASS (desc->desc_class);
return class->get_pipeline_layout (self);
}
void
@@ -48,5 +39,19 @@ gsk_vulkan_descriptors_bind (GskVulkanDescriptors *self,
GskVulkanDescriptors *previous,
VkCommandBuffer vk_command_buffer)
{
return GSK_VULKAN_DESCRIPTORS_GET_CLASS (self)->bind (self, previous, vk_command_buffer);
GskGpuDescriptors *desc = GSK_GPU_DESCRIPTORS (self);
GskVulkanDescriptorsClass *class = GSK_VULKAN_DESCRIPTORS_CLASS (desc->desc_class);
return class->bind (self, previous, vk_command_buffer);
}
GskVulkanDescriptors *
gsk_vulkan_descriptors_new (GskVulkanDescriptorsClass *desc_class,
gsize child_size)
{
GskGpuDescriptors *desc;
desc = gsk_gpu_descriptors_new ((GskGpuDescriptorsClass *)desc_class, child_size);
return GSK_VULKAN_DESCRIPTORS (desc);
}
+7 -10
View File
@@ -6,15 +6,12 @@
G_BEGIN_DECLS
#define GSK_TYPE_VULKAN_DESCRIPTORS (gsk_vulkan_descriptors_get_type ())
#define GSK_VULKAN_DESCRIPTORS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GSK_TYPE_VULKAN_DESCRIPTORS, GskVulkanDescriptors))
#define GSK_VULKAN_DESCRIPTORS_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), GSK_TYPE_VULKAN_DESCRIPTORS, GskVulkanDescriptorsClass))
#define GSK_IS_VULKAN_DESCRIPTORS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GSK_TYPE_VULKAN_DESCRIPTORS))
#define GSK_IS_VULKAN_DESCRIPTORS_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GSK_TYPE_VULKAN_DESCRIPTORS))
#define GSK_VULKAN_DESCRIPTORS_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GSK_TYPE_VULKAN_DESCRIPTORS, GskVulkanDescriptorsClass))
typedef struct _GskVulkanDescriptors GskVulkanDescriptors;
typedef struct _GskVulkanDescriptorsClass GskVulkanDescriptorsClass;
#define GSK_VULKAN_DESCRIPTORS(d) ((GskVulkanDescriptors *) (d))
#define GSK_VULKAN_DESCRIPTORS_CLASS(d) ((GskVulkanDescriptorsClass *) (d))
struct _GskVulkanDescriptors
{
GskGpuDescriptors parent_instance;
@@ -30,8 +27,6 @@ struct _GskVulkanDescriptorsClass
VkCommandBuffer vk_command_buffer);
};
GType gsk_vulkan_descriptors_get_type (void) G_GNUC_CONST;
GskVulkanPipelineLayout * gsk_vulkan_descriptors_get_pipeline_layout (GskVulkanDescriptors *self);
void gsk_vulkan_descriptors_transition (GskVulkanDescriptors *self,
@@ -41,7 +36,9 @@ void gsk_vulkan_descriptors_bind
GskVulkanDescriptors *previous,
VkCommandBuffer vk_command_buffer);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GskVulkanDescriptors, g_object_unref)
GskVulkanDescriptors * gsk_vulkan_descriptors_new (GskVulkanDescriptorsClass *desc_class,
gsize child_size);
G_END_DECLS
+8 -2
View File
@@ -13,10 +13,16 @@
#include "gdk/gdkdisplayprivate.h"
#include "gdk/gdkdmabuftextureprivate.h"
static inline void
gsk_vulkan_real_descriptors_unref (GskVulkanRealDescriptors *desc)
{
gsk_gpu_descriptors_unref (GSK_GPU_DESCRIPTORS (desc));
}
#define GDK_ARRAY_NAME gsk_descriptors
#define GDK_ARRAY_TYPE_NAME GskDescriptors
#define GDK_ARRAY_ELEMENT_TYPE GskVulkanRealDescriptors *
#define GDK_ARRAY_FREE_FUNC g_object_unref
#define GDK_ARRAY_FREE_FUNC gsk_vulkan_real_descriptors_unref
#define GDK_ARRAY_NO_MEMSET 1
#include "gdk/gdkarrayimpl.c"
@@ -262,7 +268,7 @@ gsk_vulkan_frame_create_descriptors (GskGpuFrame *frame)
desc = gsk_vulkan_real_descriptors_new (self);
gsk_descriptors_append (&self->descriptors, desc);
return GSK_GPU_DESCRIPTORS (g_object_ref (desc));
return gsk_gpu_descriptors_ref (GSK_GPU_DESCRIPTORS (desc));
}
}
+17 -25
View File
@@ -2,10 +2,6 @@
#include "gskvulkanrealdescriptorsprivate.h"
#include "gskvulkanbufferprivate.h"
#include "gskvulkanframeprivate.h"
#include "gskvulkanimageprivate.h"
#define GDK_ARRAY_NAME gsk_descriptor_image_infos
#define GDK_ARRAY_TYPE_NAME GskDescriptorImageInfos
#define GDK_ARRAY_ELEMENT_TYPE VkDescriptorImageInfo
@@ -45,8 +41,6 @@ struct _GskVulkanRealDescriptors
VkDescriptorSet descriptor_sets[GSK_VULKAN_N_DESCRIPTOR_SETS];
};
G_DEFINE_TYPE (GskVulkanRealDescriptors, gsk_vulkan_real_descriptors, GSK_TYPE_VULKAN_DESCRIPTORS)
static GskVulkanPipelineLayout *
gsk_vulkan_real_descriptors_get_pipeline_layout (GskVulkanDescriptors *desc)
{
@@ -154,9 +148,9 @@ gsk_vulkan_real_descriptors_add_buffer (GskGpuDescriptors *desc,
}
static void
gsk_vulkan_real_descriptors_finalize (GObject *object)
gsk_vulkan_real_descriptors_finalize (GskGpuDescriptors *desc)
{
GskVulkanRealDescriptors *self = GSK_VULKAN_REAL_DESCRIPTORS (object);
GskVulkanRealDescriptors *self = GSK_VULKAN_REAL_DESCRIPTORS (desc);
gsk_samplers_clear (&self->immutable_samplers);
gsk_descriptor_image_infos_clear (&self->descriptor_immutable_images);
@@ -165,25 +159,18 @@ gsk_vulkan_real_descriptors_finalize (GObject *object)
gsk_vulkan_device_release_pipeline_layout (GSK_VULKAN_DEVICE (gsk_gpu_frame_get_device (GSK_GPU_FRAME (self->frame))),
self->pipeline_layout);
G_OBJECT_CLASS (gsk_vulkan_real_descriptors_parent_class)->finalize (object);
}
static void
gsk_vulkan_real_descriptors_class_init (GskVulkanRealDescriptorsClass *klass)
static GskVulkanDescriptorsClass GSK_VULKAN_REAL_DESCRIPTORS_CLASS =
{
GskVulkanDescriptorsClass *vulkan_descriptors_class = GSK_VULKAN_DESCRIPTORS_CLASS (klass);
GskGpuDescriptorsClass *descriptors_class = GSK_GPU_DESCRIPTORS_CLASS (klass);
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->finalize = gsk_vulkan_real_descriptors_finalize;
descriptors_class->add_image = gsk_vulkan_real_descriptors_add_image;
descriptors_class->add_buffer = gsk_vulkan_real_descriptors_add_buffer;
vulkan_descriptors_class->get_pipeline_layout = gsk_vulkan_real_descriptors_get_pipeline_layout;
vulkan_descriptors_class->bind = gsk_vulkan_real_descriptors_bind;
}
.parent_class = (GskGpuDescriptorsClass) {
.finalize = gsk_vulkan_real_descriptors_finalize,
.add_image = gsk_vulkan_real_descriptors_add_image,
.add_buffer = gsk_vulkan_real_descriptors_add_buffer,
},
.get_pipeline_layout = gsk_vulkan_real_descriptors_get_pipeline_layout,
.bind = gsk_vulkan_real_descriptors_bind
};
static void
gsk_vulkan_real_descriptors_init (GskVulkanRealDescriptors *self)
@@ -198,9 +185,14 @@ GskVulkanRealDescriptors *
gsk_vulkan_real_descriptors_new (GskVulkanFrame *frame)
{
GskVulkanRealDescriptors *self;
GskVulkanDescriptors *desc;
self = g_object_new (GSK_TYPE_VULKAN_REAL_DESCRIPTORS, NULL);
desc = gsk_vulkan_descriptors_new (&GSK_VULKAN_REAL_DESCRIPTORS_CLASS,
sizeof (GskVulkanRealDescriptors));
self = GSK_VULKAN_REAL_DESCRIPTORS (desc);
gsk_vulkan_real_descriptors_init (self);
self->frame = frame;
return self;
+8 -2
View File
@@ -3,11 +3,17 @@
#include "gskvulkandescriptorsprivate.h"
#include "gskvulkanframeprivate.h"
#include "gskvulkanbufferprivate.h"
#include "gskvulkanframeprivate.h"
#include "gskvulkanimageprivate.h"
G_BEGIN_DECLS
#define GSK_TYPE_VULKAN_REAL_DESCRIPTORS (gsk_vulkan_real_descriptors_get_type ())
typedef struct _GskVulkanRealDescriptors GskVulkanRealDescriptors;
#define GSK_VULKAN_REAL_DESCRIPTORS(d) ((GskVulkanRealDescriptors *) (d))
G_DECLARE_FINAL_TYPE (GskVulkanRealDescriptors, gsk_vulkan_real_descriptors, GSK, VULKAN_REAL_DESCRIPTORS, GskVulkanDescriptors)
GskVulkanRealDescriptors * gsk_vulkan_real_descriptors_new (GskVulkanFrame *frame);
+35 -31
View File
@@ -2,6 +2,7 @@
#include "gskvulkansubdescriptorsprivate.h"
struct _GskVulkanSubDescriptors
{
GskVulkanDescriptors parent_instance;
@@ -9,7 +10,31 @@ struct _GskVulkanSubDescriptors
GskVulkanDescriptors *parent;
};
G_DEFINE_TYPE (GskVulkanSubDescriptors, gsk_vulkan_sub_descriptors, GSK_TYPE_VULKAN_DESCRIPTORS)
static void gsk_vulkan_sub_descriptors_finalize (GskGpuDescriptors *desc);
static gboolean gsk_vulkan_sub_descriptors_add_buffer (GskGpuDescriptors *desc,
GskGpuBuffer *buffer,
guint32 *out_descriptor);
static gboolean gsk_vulkan_sub_descriptors_add_image (GskGpuDescriptors *desc,
GskGpuImage *image,
GskGpuSampler sampler,
guint32 *out_descriptor);
static GskVulkanPipelineLayout *
gsk_vulkan_sub_descriptors_get_pipeline_layout (GskVulkanDescriptors *desc);
static void gsk_vulkan_sub_descriptors_bind (GskVulkanDescriptors *desc,
GskVulkanDescriptors *previous,
VkCommandBuffer vk_command_buffer);
static GskVulkanDescriptorsClass GSK_VULKAN_SUB_DESCRIPTORS_CLASS =
{
.parent_class = (GskGpuDescriptorsClass) {
.finalize = gsk_vulkan_sub_descriptors_finalize,
.add_image = gsk_vulkan_sub_descriptors_add_image,
.add_buffer = gsk_vulkan_sub_descriptors_add_buffer,
},
.get_pipeline_layout = gsk_vulkan_sub_descriptors_get_pipeline_layout,
.bind = gsk_vulkan_sub_descriptors_bind,
};
static GskVulkanPipelineLayout *
gsk_vulkan_sub_descriptors_get_pipeline_layout (GskVulkanDescriptors *desc)
@@ -26,7 +51,7 @@ gsk_vulkan_sub_descriptors_bind (GskVulkanDescriptors *desc,
{
GskVulkanSubDescriptors *self = GSK_VULKAN_SUB_DESCRIPTORS (desc);
if (GSK_IS_VULKAN_SUB_DESCRIPTORS (previous))
if (GSK_GPU_DESCRIPTORS (previous)->desc_class == (GskGpuDescriptorsClass *) &GSK_VULKAN_SUB_DESCRIPTORS_CLASS)
previous = GSK_VULKAN_SUB_DESCRIPTORS (previous)->parent;
if (self->parent == previous)
@@ -62,45 +87,24 @@ gsk_vulkan_sub_descriptors_add_buffer (GskGpuDescriptors *desc,
}
static void
gsk_vulkan_sub_descriptors_finalize (GObject *object)
gsk_vulkan_sub_descriptors_finalize (GskGpuDescriptors *desc)
{
GskVulkanSubDescriptors *self = GSK_VULKAN_SUB_DESCRIPTORS (object);
GskVulkanSubDescriptors *self = GSK_VULKAN_SUB_DESCRIPTORS (desc);
g_object_unref (self->parent);
G_OBJECT_CLASS (gsk_vulkan_sub_descriptors_parent_class)->finalize (object);
}
static void
gsk_vulkan_sub_descriptors_class_init (GskVulkanSubDescriptorsClass *klass)
{
GskVulkanDescriptorsClass *vulkan_descriptors_class = GSK_VULKAN_DESCRIPTORS_CLASS (klass);
GskGpuDescriptorsClass *descriptors_class = GSK_GPU_DESCRIPTORS_CLASS (klass);
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->finalize = gsk_vulkan_sub_descriptors_finalize;
descriptors_class->add_image = gsk_vulkan_sub_descriptors_add_image;
descriptors_class->add_buffer = gsk_vulkan_sub_descriptors_add_buffer;
vulkan_descriptors_class->get_pipeline_layout = gsk_vulkan_sub_descriptors_get_pipeline_layout;
vulkan_descriptors_class->bind = gsk_vulkan_sub_descriptors_bind;
}
static void
gsk_vulkan_sub_descriptors_init (GskVulkanSubDescriptors *self)
{
gsk_gpu_descriptors_unref (GSK_GPU_DESCRIPTORS (self->parent));
}
GskVulkanSubDescriptors *
gsk_vulkan_sub_descriptors_new (GskVulkanDescriptors *parent)
{
GskVulkanSubDescriptors *self;
GskVulkanDescriptors *desc;
self = g_object_new (GSK_TYPE_VULKAN_SUB_DESCRIPTORS, NULL);
desc = gsk_vulkan_descriptors_new (&GSK_VULKAN_SUB_DESCRIPTORS_CLASS,
sizeof (GskVulkanSubDescriptors));
self->parent = g_object_ref (parent);
self = GSK_VULKAN_SUB_DESCRIPTORS (desc);
self->parent = GSK_VULKAN_DESCRIPTORS (gsk_gpu_descriptors_ref (GSK_GPU_DESCRIPTORS (parent)));
return self;
}
+3 -2
View File
@@ -4,9 +4,10 @@
G_BEGIN_DECLS
#define GSK_TYPE_VULKAN_SUB_DESCRIPTORS (gsk_vulkan_sub_descriptors_get_type ())
typedef struct _GskVulkanSubDescriptors GskVulkanSubDescriptors;
#define GSK_VULKAN_SUB_DESCRIPTORS(d) ((GskVulkanSubDescriptors *) (d))
G_DECLARE_FINAL_TYPE (GskVulkanSubDescriptors, gsk_vulkan_sub_descriptors, GSK, VULKAN_SUB_DESCRIPTORS, GskVulkanDescriptors)
GskVulkanSubDescriptors * gsk_vulkan_sub_descriptors_new (GskVulkanDescriptors *parent);
-20
View File
@@ -1,20 +0,0 @@
#pragma once
#include <graphene.h>
static inline void G_GNUC_PURE
gsk_point_interpolate (const graphene_point_t *p1,
const graphene_point_t *p2,
float t,
graphene_point_t *p)
{
p->x = p1->x * (1 - t) + p2->x * t;
p->Y = p1->y * (1 - t) + p2->y * t;
}
static inline float G_GNUC_PURE
gsk_point_distance (const graphene_point_t *p1,
const graphene_point_t *p2)
{
return sqrtf ((p1->x - p2->x)*(p1->x - p2->x) + (p1->y - p2->y)*(p1->y - p2->y));
}
+175
View File
@@ -1,6 +1,11 @@
#include "gskresources.h"
#include "gskprivate.h"
#include <cairo.h>
#include <pango/pangocairo.h>
#include <pango/pangoft2.h>
#include <math.h>
static gpointer
register_resources (gpointer data)
{
@@ -15,3 +20,173 @@ gsk_ensure_resources (void)
g_once (&register_resources_once, register_resources, NULL);
}
/*< private >
* gsk_reload_font:
* @font: a `PangoFont`
* @scale: the scale to apply
* @hint_metris: hint metrics to use or `CAIRO_HINT_METRICS_DEFAILT` to keep the
* hint metrics of the font unchanged
* @hint_style: hint style to use or `CAIRO_HINT_STYLE_DEFAULT` to keep the
* hint style of @font unchanged
* @antialias: antialiasing to use, or `CAIRO_ANTIALIAS_DEFAULT` to keep the
* antialias option of @font unchanged
*
* Returns a font that is just like @font, but uses the
* given scale and hinting options for its glyphs and metrics.
*
* Returns: (transfer full): the modified `PangoFont`
*/
PangoFont *
gsk_reload_font (PangoFont *font,
float scale,
cairo_hint_metrics_t hint_metrics,
cairo_hint_style_t hint_style,
cairo_antialias_t antialias)
{
cairo_font_options_t *options;
cairo_scaled_font_t *sf;
static PangoContext *context = NULL;
#if !PANGO_VERSION_CHECK (1, 52, 0)
PangoFontDescription *desc;
FcPattern *pattern;
double dpi;
int size;
#endif
/* These requests often come in sequentially so keep the result
* around and re-use it if everything matches.
*/
static PangoFont *last_font;
static float last_scale;
static cairo_hint_metrics_t last_hint_metrics;
static cairo_hint_style_t last_hint_style;
static cairo_antialias_t last_antialias;
static PangoFont *last_result;
if (last_result != NULL &&
last_font == font &&
last_scale == scale &&
last_hint_metrics == hint_metrics &&
last_hint_style == hint_style &&
last_antialias == antialias)
return g_object_ref (last_result);
last_scale = scale;
last_hint_metrics = hint_metrics;
last_hint_style = hint_style;
last_antialias = antialias;
g_set_object (&last_font, font);
g_clear_object (&last_result);
options = cairo_font_options_create ();
sf = pango_cairo_font_get_scaled_font (PANGO_CAIRO_FONT (font));
cairo_scaled_font_get_font_options (sf, options);
if (hint_metrics == CAIRO_HINT_METRICS_DEFAULT)
hint_metrics = cairo_font_options_get_hint_metrics (options);
if (hint_style == CAIRO_HINT_STYLE_DEFAULT)
hint_style = cairo_font_options_get_hint_style (options);
if (antialias == CAIRO_ANTIALIAS_DEFAULT)
antialias = cairo_font_options_get_antialias (options);
if (1.0 == scale &&
cairo_font_options_get_hint_metrics (options) == hint_metrics &&
cairo_font_options_get_hint_style (options) == hint_style &&
cairo_font_options_get_antialias (options) == antialias &&
cairo_font_options_get_subpixel_order (options) == CAIRO_SUBPIXEL_ORDER_DEFAULT)
{
last_result = g_object_ref (font);
cairo_font_options_destroy (options);
return g_object_ref (font);
}
cairo_font_options_set_hint_metrics (options, hint_metrics);
cairo_font_options_set_hint_style (options, hint_style);
cairo_font_options_set_antialias (options, antialias);
cairo_font_options_set_subpixel_order (options, CAIRO_SUBPIXEL_ORDER_DEFAULT);
if (!context)
context = pango_context_new ();
pango_cairo_context_set_font_options (context, options);
cairo_font_options_destroy (options);
#if PANGO_VERSION_CHECK (1, 52, 0)
last_result = pango_font_map_reload_font (pango_font_get_font_map (font), font, scale, context, NULL);
#else
pattern = pango_fc_font_get_pattern (PANGO_FC_FONT (font));
if (FcPatternGetDouble (pattern, FC_DPI, 0, &dpi) == FcResultMatch)
pango_cairo_context_set_resolution (context, dpi);
desc = pango_font_describe (font);
size = pango_font_description_get_size (desc);
if (pango_font_description_get_size_is_absolute (desc))
pango_font_description_set_absolute_size (desc, size * scale);
else
pango_font_description_set_size (desc, (int) floor (size * scale + .5));
last_result = pango_font_map_load_font (pango_font_get_font_map (font), context, desc);
pango_font_description_free (desc);
#endif
return g_object_ref (last_result);
}
/*< private >
* gsk_get_unhinted_glyph_string_extents:
* @glyphs: a `PangoGlyphString`
* @font: a `PangoFont`
* @ink_rect: (out): rectangle used to store the extents of the glyph string as drawn
*
* Compute the ink extents of a glyph string.
*
* This is like [method@Pango.GlyphString.extents], but it
* ignores hinting of the font.
*/
void
gsk_get_unhinted_glyph_string_extents (PangoGlyphString *glyphs,
PangoFont *font,
PangoRectangle *ink_rect)
{
PangoFont *unhinted;
unhinted = gsk_reload_font (font,
1.0,
CAIRO_HINT_METRICS_OFF,
CAIRO_HINT_STYLE_NONE,
CAIRO_ANTIALIAS_DEFAULT);
pango_glyph_string_extents (glyphs, unhinted, ink_rect, NULL);
g_object_unref (unhinted);
}
/*< private >
* gsk_font_get_hint_style:
* @font: a `PangoFont`
*
* Get the hint style from the cairo font options.
*
* Returns: the hint style
*/
cairo_hint_style_t
gsk_font_get_hint_style (PangoFont *font)
{
cairo_scaled_font_t *sf;
cairo_font_options_t *options;
cairo_hint_style_t style;
sf = pango_cairo_font_get_scaled_font (PANGO_CAIRO_FONT (font));
options = cairo_font_options_create ();
cairo_scaled_font_get_font_options (sf, options);
style = cairo_font_options_get_hint_style (options);
cairo_font_options_destroy (options);
return style;
}
+14 -1
View File
@@ -2,10 +2,23 @@
#include <glib.h>
#include <pango/pango.h>
#include <cairo.h>
G_BEGIN_DECLS
void gsk_ensure_resources (void);
void gsk_ensure_resources (void);
PangoFont *gsk_reload_font (PangoFont *font,
float scale,
cairo_hint_metrics_t hint_metrics,
cairo_hint_style_t hint_style,
cairo_antialias_t antialias);
void gsk_get_unhinted_glyph_string_extents (PangoGlyphString *glyphs,
PangoFont *font,
PangoRectangle *ink_rect);
cairo_hint_style_t gsk_font_get_hint_style (PangoFont *font);
G_END_DECLS
-3
View File
@@ -688,9 +688,6 @@ get_renderer_for_vulkan (GdkSurface *surface)
static GType
get_renderer_for_gles2 (GdkSurface *surface)
{
if (gl_software_rendering (surface))
return G_TYPE_INVALID;
return GSK_TYPE_GL_RENDERER;
}
+13 -7
View File
@@ -31,6 +31,7 @@
#include "gskroundedrectprivate.h"
#include "gskstrokeprivate.h"
#include "gsktransformprivate.h"
#include "gskprivate.h"
#include "gdk/gdkmemoryformatprivate.h"
#include "gdk/gdkprivate.h"
@@ -3473,7 +3474,7 @@ gsk_transform_node_draw (GskRenderNode *node,
* (like when flipping an axis at the point where scale == 0)
* and just means that nothing should be drawn.
* But Cairo throws lots of ugly errors instead of silently
* going on. So We silently go on.
* going on. So we silently go on.
*/
return;
}
@@ -5791,6 +5792,12 @@ gsk_text_node_class_init (gpointer g_class,
node_class->diff = gsk_text_node_diff;
}
static inline float
pango_units_to_float (int i)
{
return (float) i / PANGO_SCALE;
}
/**
* gsk_text_node_new:
* @font: the `PangoFont` containing the glyphs
@@ -5817,8 +5824,7 @@ gsk_text_node_new (PangoFont *font,
PangoGlyphInfo *glyph_infos;
int n;
pango_glyph_string_extents (glyphs, font, &ink_rect, NULL);
pango_extents_to_pixels (&ink_rect, NULL);
gsk_get_unhinted_glyph_string_extents (glyphs, font, &ink_rect);
/* Don't create nodes with empty bounds */
if (ink_rect.width == 0 || ink_rect.height == 0)
@@ -5855,10 +5861,10 @@ gsk_text_node_new (PangoFont *font,
self->num_glyphs = n;
gsk_rect_init (&node->bounds,
offset->x + ink_rect.x,
offset->y + ink_rect.y,
ink_rect.width,
ink_rect.height);
offset->x + pango_units_to_float (ink_rect.x),
offset->y + pango_units_to_float (ink_rect.y),
pango_units_to_float (ink_rect.width),
pango_units_to_float (ink_rect.height));
return node;
}
+188 -77
View File
@@ -30,6 +30,7 @@
#include "gskstroke.h"
#include "gsktransformprivate.h"
#include "gskenumtypes.h"
#include "gskprivate.h"
#include "gdk/gdkrgbaprivate.h"
#include "gdk/gdktextureprivate.h"
@@ -46,7 +47,9 @@
#include <cairo-script-interpreter.h>
#endif
#include <cairo-gobject.h>
#include <pango/pangocairo.h>
#ifdef HAVE_PANGOFT
#include <pango/pangofc-fontmap.h>
#endif
@@ -86,6 +89,39 @@ context_finish (Context *context)
g_clear_object (&context->fontmap);
}
static gboolean
parse_enum (GtkCssParser *parser,
GType type,
gpointer out_value)
{
GEnumClass *class;
GEnumValue *v;
char *enum_name;
enum_name = gtk_css_parser_consume_ident (parser);
if (enum_name == NULL)
return FALSE;
class = g_type_class_ref (type);
v = g_enum_get_value_by_nick (class, enum_name);
if (v == NULL)
{
gtk_css_parser_error_value (parser, "Unknown value \"%s\" for enum \"%s\"",
enum_name, g_type_name (type));
g_free (enum_name);
g_type_class_unref (class);
return FALSE;
}
*(int*)out_value = v->value;
g_free (enum_name);
g_type_class_unref (class);
return TRUE;
}
static gboolean
parse_rect (GtkCssParser *parser,
Context *context,
@@ -1182,6 +1218,8 @@ clear_font (gpointer inout_font)
g_clear_object ((PangoFont **) inout_font);
}
#define GLYPH_NEEDS_WIDTH (1 << 15)
static gboolean
parse_glyphs (GtkCssParser *parser,
Context *context,
@@ -1208,6 +1246,7 @@ parse_glyphs (GtkCssParser *parser,
gtk_css_parser_error_value (parser, "Unsupported character %d in string", i);
}
gi.glyph = PANGO_GLYPH_INVALID_INPUT - MAX_ASCII_GLYPH + s[i];
*(unsigned int *) &gi.attr |= GLYPH_NEEDS_WIDTH;
pango_glyph_string_set_size (glyph_string, glyph_string->num_glyphs + 1);
glyph_string->glyphs[glyph_string->num_glyphs - 1] = gi;
}
@@ -1216,14 +1255,22 @@ parse_glyphs (GtkCssParser *parser,
}
else
{
if (!gtk_css_parser_consume_integer (parser, &i) ||
!gtk_css_parser_consume_number (parser, &d))
if (!gtk_css_parser_consume_integer (parser, &i))
{
pango_glyph_string_free (glyph_string);
return FALSE;
}
gi.glyph = i;
gi.geometry.width = (int) (d * PANGO_SCALE);
if (gtk_css_parser_has_number (parser))
{
gtk_css_parser_consume_number (parser, &d);
gi.geometry.width = (int) (d * PANGO_SCALE);
}
else
{
*(unsigned int *) &gi.attr |= GLYPH_NEEDS_WIDTH;
}
if (gtk_css_parser_has_number (parser))
{
@@ -2193,23 +2240,36 @@ unpack_glyphs (PangoFont *font,
for (i = 0; i < glyphs->num_glyphs; i++)
{
PangoGlyph glyph = glyphs->glyphs[i].glyph;
PangoGlyphInfo *gi = &glyphs->glyphs[i];
if (glyph < PANGO_GLYPH_INVALID_INPUT - MAX_ASCII_GLYPH ||
glyph >= PANGO_GLYPH_INVALID_INPUT)
if (((*(unsigned int *) &gi->attr) & GLYPH_NEEDS_WIDTH) == 0)
continue;
glyph = glyph - (PANGO_GLYPH_INVALID_INPUT - MAX_ASCII_GLYPH) - MIN_ASCII_GLYPH;
*(unsigned int *) &gi->attr &= ~GLYPH_NEEDS_WIDTH;
if (ascii == NULL)
if (gi->glyph >= PANGO_GLYPH_INVALID_INPUT - MAX_ASCII_GLYPH &&
gi->glyph < PANGO_GLYPH_INVALID_INPUT)
{
ascii = create_ascii_glyphs (font);
if (ascii == NULL)
return FALSE;
}
PangoGlyph idx = gi->glyph - (PANGO_GLYPH_INVALID_INPUT - MAX_ASCII_GLYPH) - MIN_ASCII_GLYPH;
glyphs->glyphs[i].glyph = ascii->glyphs[glyph].glyph;
glyphs->glyphs[i].geometry.width = ascii->glyphs[glyph].geometry.width;
if (ascii == NULL)
{
ascii = create_ascii_glyphs (font);
if (ascii == NULL)
return FALSE;
}
gi->glyph = ascii->glyphs[idx].glyph;
gi->geometry.width = ascii->glyphs[idx].geometry.width;
}
else
{
PangoRectangle ink_rect;
pango_font_get_glyph_extents (font, gi->glyph, &ink_rect, NULL);
gi->geometry.width = ink_rect.width;
}
}
g_clear_pointer (&ascii, pango_glyph_string_free);
@@ -2217,6 +2277,45 @@ unpack_glyphs (PangoFont *font,
return TRUE;
}
static gboolean
parse_hint_style (GtkCssParser *parser,
Context *context,
gpointer out)
{
if (!parse_enum (parser, CAIRO_GOBJECT_TYPE_HINT_STYLE, out))
return FALSE;
if (*(cairo_hint_style_t *) out != CAIRO_HINT_STYLE_NONE &&
*(cairo_hint_style_t *) out != CAIRO_HINT_STYLE_SLIGHT &&
*(cairo_hint_style_t *) out != CAIRO_HINT_STYLE_FULL)
{
gtk_css_parser_error_value (parser, "Unsupported value for enum \"%s\"",
g_type_name (CAIRO_GOBJECT_TYPE_HINT_STYLE));
return FALSE;
}
return TRUE;
}
static gboolean
parse_antialias (GtkCssParser *parser,
Context *context,
gpointer out)
{
if (!parse_enum (parser, CAIRO_GOBJECT_TYPE_ANTIALIAS, out))
return FALSE;
if (*(cairo_antialias_t *) out != CAIRO_ANTIALIAS_NONE &&
*(cairo_antialias_t *) out != CAIRO_ANTIALIAS_GRAY)
{
gtk_css_parser_error_value (parser, "Unsupported value for enum \"%s\"",
g_type_name (CAIRO_GOBJECT_TYPE_ANTIALIAS));
return FALSE;
}
return TRUE;
}
static GskRenderNode *
parse_text_node (GtkCssParser *parser,
Context *context)
@@ -2225,11 +2324,16 @@ parse_text_node (GtkCssParser *parser,
graphene_point_t offset = GRAPHENE_POINT_INIT (0, 0);
GdkRGBA color = GDK_RGBA("000000");
PangoGlyphString *glyphs = NULL;
cairo_hint_style_t hint_style = CAIRO_HINT_STYLE_SLIGHT;
cairo_antialias_t antialias = CAIRO_ANTIALIAS_GRAY;
PangoFont *hinted;
const Declaration declarations[] = {
{ "font", parse_font, clear_font, &font },
{ "offset", parse_point, NULL, &offset },
{ "color", parse_color, NULL, &color },
{ "glyphs", parse_glyphs, clear_glyphs, &glyphs }
{ "glyphs", parse_glyphs, clear_glyphs, &glyphs },
{ "hint-style", parse_hint_style, NULL, &hint_style },
{ "antialias", parse_antialias, NULL, &antialias },
};
GskRenderNode *result;
@@ -2237,10 +2341,14 @@ parse_text_node (GtkCssParser *parser,
if (font == NULL)
{
font = font_from_string (pango_cairo_font_map_get_default (), "Cantarell 11", TRUE);
font = font_from_string (pango_cairo_font_map_get_default (), "Cantarell 15px", TRUE);
g_assert (font);
}
hinted = gsk_reload_font (font, 1.0, CAIRO_HINT_METRICS_OFF, hint_style, antialias);
g_object_unref (font);
font = hinted;
if (!glyphs)
{
const char *text = "Hello";
@@ -2252,6 +2360,7 @@ parse_text_node (GtkCssParser *parser,
for (i = 0; i < strlen (text); i++)
{
gi.glyph = PANGO_GLYPH_INVALID_INPUT - MAX_ASCII_GLYPH + text[i];
*(unsigned int *) &gi.attr |= GLYPH_NEEDS_WIDTH;
glyphs->glyphs[i] = gi;
}
}
@@ -2429,39 +2538,6 @@ clear_dash (gpointer inout_array)
g_clear_pointer ((GArray **) inout_array, g_array_unref);
}
static gboolean
parse_enum (GtkCssParser *parser,
GType type,
gpointer out_value)
{
GEnumClass *class;
GEnumValue *v;
char *enum_name;
enum_name = gtk_css_parser_consume_ident (parser);
if (enum_name == NULL)
return FALSE;
class = g_type_class_ref (type);
v = g_enum_get_value_by_nick (class, enum_name);
if (v == NULL)
{
gtk_css_parser_error_value (parser, "Unknown value \"%s\" for enum \"%s\"",
enum_name, g_type_name (type));
g_free (enum_name);
g_type_class_unref (class);
return FALSE;
}
*(int*)out_value = v->value;
g_free (enum_name);
g_type_class_unref (class);
return TRUE;
}
static gboolean
parse_fill_rule (GtkCssParser *parser,
Context *context,
@@ -3248,6 +3324,33 @@ append_string_param (Printer *p,
g_string_append_c (p->str, '\n');
}
static const char *
enum_to_nick (GType type,
int value)
{
GEnumClass *class;
GEnumValue *v;
class = g_type_class_ref (type);
v = g_enum_get_value (class, value);
g_type_class_unref (class);
return v->value_nick;
}
static void
append_enum_param (Printer *p,
const char *param_name,
GType type,
int value)
{
_indent (p);
g_string_append_printf (p->str, "%s: ", param_name);
g_string_append (p->str, enum_to_nick (type, value));
g_string_append_c (p->str, ';');
g_string_append_c (p->str, '\n');
}
static void
append_vec4_param (Printer *p,
const char *param_name,
@@ -3471,7 +3574,7 @@ gsk_text_node_serialize_font (GskRenderNode *node,
PangoFontDescription *desc;
char *s;
desc = pango_font_describe (font);
desc = pango_font_describe_with_absolute_size (font);
s = pango_font_description_to_string (desc);
g_string_append_printf (p->str, "\"%s\"", s);
g_free (s);
@@ -3515,6 +3618,37 @@ gsk_text_node_serialize_font (GskRenderNode *node,
#endif
}
static void
gsk_text_node_serialize_font_options (GskRenderNode *node,
Printer *p)
{
PangoFont *font = gsk_text_node_get_font (node);
cairo_scaled_font_t *sf = pango_cairo_font_get_scaled_font (PANGO_CAIRO_FONT (font));
cairo_font_options_t *options;
cairo_hint_style_t hint_style;
cairo_antialias_t antialias;
options = cairo_font_options_create ();
cairo_scaled_font_get_font_options (sf, options);
hint_style = cairo_font_options_get_hint_style (options);
antialias = cairo_font_options_get_antialias (options);
cairo_font_options_destroy (options);
/* medium and full are identical in the absence of subpixel modes */
if (hint_style == CAIRO_HINT_STYLE_MEDIUM)
hint_style = CAIRO_HINT_STYLE_FULL;
if (hint_style == CAIRO_HINT_STYLE_NONE ||
hint_style == CAIRO_HINT_STYLE_FULL)
append_enum_param (p, "hint-style", CAIRO_GOBJECT_TYPE_HINT_STYLE, hint_style);
/* CAIRO_ANTIALIAS_NONE is the only value we ever emit here, since gray is the default,
* and we don't accept any other values.
*/
if (antialias == CAIRO_ANTIALIAS_NONE)
append_enum_param (p, "antialias", CAIRO_GOBJECT_TYPE_ANTIALIAS, antialias);
}
void
gsk_text_node_serialize_glyphs (GskRenderNode *node,
GString *p)
@@ -3596,33 +3730,6 @@ gsk_text_node_serialize_glyphs (GskRenderNode *node,
pango_glyph_string_free (ascii);
}
static const char *
enum_to_nick (GType type,
int value)
{
GEnumClass *class;
GEnumValue *v;
class = g_type_class_ref (type);
v = g_enum_get_value (class, value);
g_type_class_unref (class);
return v->value_nick;
}
static void
append_enum_param (Printer *p,
const char *param_name,
GType type,
int value)
{
_indent (p);
g_string_append_printf (p->str, "%s: ", param_name);
g_string_append (p->str, enum_to_nick (type, value));
g_string_append_c (p->str, ';');
g_string_append_c (p->str, '\n');
}
static void
append_path_param (Printer *p,
const char *param_name,
@@ -4087,6 +4194,8 @@ render_node_print (Printer *p,
if (!graphene_point_equal (offset, graphene_point_zero ()))
append_point_param (p, "offset", offset);
gsk_text_node_serialize_font_options (node, p);
end_node (p);
}
break;
@@ -4357,6 +4466,8 @@ render_node_print (Printer *p,
start_node (p, "subsurface", node_name);
append_node_param (p, "child", gsk_subsurface_node_get_child (node));
end_node (p);
}
break;
+3 -3
View File
@@ -23,7 +23,7 @@
#include "gtkatspicontextprivate.h"
#include "gtkaccessibleprivate.h"
#include "gtkaccessibletext-private.h"
#include "gtkaccessibletextprivate.h"
#include "gtkatspiactionprivate.h"
#include "gtkatspieditabletextprivate.h"
@@ -771,7 +771,7 @@ emit_text_selection_changed (GtkAtSpiContext *self,
"org.a11y.atspi.Event.Object",
"TextCaretMoved",
g_variant_new ("(siiva{sv})",
"", cursor_position, 0, g_variant_new_string (""), NULL),
"", cursor_position, 0, g_variant_new_int32 (0), NULL),
NULL);
else
g_dbus_connection_emit_signal (self->connection,
@@ -1590,7 +1590,7 @@ gtk_at_spi_context_update_caret_position (GtkATContext *context)
"",
(int) offset,
0,
g_variant_new_string (""),
g_variant_new_int32 (0),
NULL),
NULL);
}
+3 -3
View File
@@ -418,8 +418,8 @@ gtk_at_spi_socket_embed (GtkAtSpiSocket *self,
* usually done through a side channel with the remote side, for
* example using sockets, or reading the output of a subprocess.
*
* The remote accessible object at @object_path must be a must
* have an `org.a11y.atspi.Socket` interface with the `Embedded()`
* The remote accessible object at @object_path must support
* the `org.a11y.atspi.Socket` interface with the `Embedded()`
* method.
*
* This constructor can fail, most notably if the accessibility
@@ -463,7 +463,7 @@ gtk_at_spi_socket_get_bus_name (GtkAtSpiSocket *self)
* gtk_at_spi_socket_get_object_path:
* @self: a #GtkAtSpiSocket
*
* Retrieves the object path of the remove accessible object that
* Retrieves the object path of the remote accessible object that
* the socket is connected to.
*
* Returns: (transfer none): the object path of the socket remote
+102 -27
View File
@@ -29,6 +29,7 @@
#include "a11y/atspi/atspi-text.h"
#include "gtkaccessibletextprivate.h"
#include "gtkatcontextprivate.h"
#include "gtkdebug.h"
#include "gtkeditable.h"
@@ -41,7 +42,6 @@
#include "gtkspinbuttonprivate.h"
#include "gtktextbufferprivate.h"
#include "gtktextviewprivate.h"
#include "gtkaccessibletext-private.h"
#include <gio/gio.h>
@@ -222,19 +222,72 @@ accessible_text_handle_method (GDBusConnection *connection,
}
else if (g_strcmp0 (method_name, "GetAttributeRun") == 0)
{
g_dbus_method_invocation_return_error_literal (invocation, G_DBUS_ERROR, G_DBUS_ERROR_NOT_SUPPORTED, "");
GVariantBuilder builder = G_VARIANT_BUILDER_INIT (G_VARIANT_TYPE ("a{ss}"));
gboolean include_defaults = FALSE;
int offset;
gsize n_ranges = 0;
GtkAccessibleTextRange *ranges = NULL;
int start, end;
char **attr_names = NULL;
char **attr_values = NULL;
gboolean res;
g_variant_get (parameters, "(ib)", &offset, &include_defaults);
res = gtk_accessible_text_get_attributes_run (accessible_text,
offset,
include_defaults,
&n_ranges,
&ranges,
&attr_names,
&attr_values);
if (!res)
{
/* No attributes */
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(a{ss}ii)", &builder, 0, 0));
return;
}
for (unsigned i = 0; attr_names[i] != NULL; i++)
g_variant_builder_add (&builder, "{ss}", attr_names[i], attr_values[i]);
start = 0;
end = G_MAXINT;
for (unsigned i = 0; i < n_ranges; i++)
{
start = MAX (start, ranges[i].start);
end = MIN (end, start + ranges[i].length);
}
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(a{ss}ii)", &builder, start, end));
g_clear_pointer (&ranges, g_free);
g_strfreev (attr_names);
g_strfreev (attr_values);
}
else if (g_strcmp0 (method_name, "GetDefaultAttributes") == 0 ||
g_strcmp0 (method_name, "GetDefaultAttributeSet") == 0)
{
g_dbus_method_invocation_return_error_literal (invocation, G_DBUS_ERROR, G_DBUS_ERROR_NOT_SUPPORTED, "");
GVariantBuilder builder = G_VARIANT_BUILDER_INIT (G_VARIANT_TYPE ("a{ss}"));
char **names, **values;
gtk_accessible_text_get_default_attributes (accessible_text, &names, &values);
for (unsigned i = 0; names[i] != NULL; i++)
g_variant_builder_add (&builder, "{ss}", names[i], values[i]);
g_strfreev (names);
g_strfreev (values);
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(a{ss})", &builder));
}
else if (g_strcmp0 (method_name, "GetNSelections") == 0)
{
gsize n_ranges;
GtkAccessibleTextRange *ranges = NULL;
gtk_accessible_text_get_selection (accessible_text, &n_ranges, &ranges);
if (!gtk_accessible_text_get_selection (accessible_text, &n_ranges, &ranges))
n_ranges = 0;
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(i)", (int)n_ranges));
@@ -248,7 +301,8 @@ accessible_text_handle_method (GDBusConnection *connection,
g_variant_get (parameters, "(i)", &num);
gtk_accessible_text_get_selection (accessible_text, &n_ranges, &ranges);
if (!gtk_accessible_text_get_selection (accessible_text, &n_ranges, &ranges))
n_ranges = 0;
if (num < 0 || num >= n_ranges)
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, "Not a valid selection: %d", num);
@@ -1056,15 +1110,20 @@ gtk_editable_get_text_widget (GtkWidget *widget)
{
if (GTK_IS_EDITABLE (widget))
{
GtkEditable *delegate;
GtkEditable *editable;
guint redirects = 0;
delegate = gtk_editable_get_delegate (GTK_EDITABLE (widget));
editable = GTK_EDITABLE (widget);
if (GTK_IS_TEXT (delegate))
return GTK_TEXT (delegate);
do {
if (GTK_IS_TEXT (editable))
return GTK_TEXT (editable);
if (GTK_IS_TEXT (widget))
return GTK_TEXT (widget);
if (++redirects >= 6)
g_assert_not_reached ();
editable = gtk_editable_get_delegate (editable);
} while (editable != NULL);
}
return NULL;
@@ -1609,63 +1668,79 @@ text_view_handle_method (GDBusConnection *connection,
}
else if (g_strcmp0 (method_name, "GetAttributes") == 0)
{
GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
GVariantBuilder builder = G_VARIANT_BUILDER_INIT (G_VARIANT_TYPE ("a{ss}"));
GHashTable *attrs;
GHashTableIter iter;
int offset;
int start, end;
gpointer key, value;
g_variant_get (parameters, "(i)", &offset);
gtk_text_buffer_get_run_attributes (buffer, &builder, offset, &start, &end);
attrs = gtk_text_view_get_attributes_run (GTK_TEXT_VIEW (widget), offset, FALSE, &start, &end);
g_hash_table_iter_init (&iter, attrs);
while (g_hash_table_iter_next (&iter, &key, &value))
g_variant_builder_add (&builder, "{ss}", key, value != NULL ? value : "");
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(a{ss}ii)", &builder, start, end));
g_hash_table_unref (attrs);
}
else if (g_strcmp0 (method_name, "GetAttributeValue") == 0)
{
GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (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;
GHashTable *attrs;
g_variant_get (parameters, "(i&s)", &offset, &name);
gtk_text_buffer_get_run_attributes (buffer, &builder, offset, &start, &end);
attrs = g_variant_builder_end (&builder);
if (!g_variant_lookup (attrs, name, "&s", &val))
attrs = gtk_text_view_get_attributes_run (GTK_TEXT_VIEW (widget), offset, FALSE, &start, &end);
val = g_hash_table_lookup (attrs, name);
if (val == NULL)
val = "";
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(s)", val));
g_variant_unref (attrs);
g_hash_table_unref (attrs);
}
else if (g_strcmp0 (method_name, "GetAttributeRun") == 0)
{
GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
GVariantBuilder builder = G_VARIANT_BUILDER_INIT (G_VARIANT_TYPE ("a{ss}"));
int offset;
gboolean include_defaults;
int start, end;
GHashTable *attrs;
GHashTableIter iter;
gpointer key, value;
g_variant_get (parameters, "(ib)", &offset, &include_defaults);
if (include_defaults)
gtk_text_view_add_default_attributes (GTK_TEXT_VIEW (widget), &builder);
gtk_text_buffer_get_run_attributes (buffer, &builder, offset, &start, &end);
attrs = gtk_text_view_get_attributes_run (GTK_TEXT_VIEW (widget), offset, include_defaults, &start, &end);
g_hash_table_iter_init (&iter, attrs);
while (g_hash_table_iter_next (&iter, &key, &value))
g_variant_builder_add (&builder, "{ss}", key, value != NULL ? value : "");
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(a{ss}ii)", &builder, start, end));
g_hash_table_unref (attrs);
}
else if (g_strcmp0 (method_name, "GetDefaultAttributes") == 0 ||
g_strcmp0 (method_name, "GetDefaultAttributeSet") == 0)
{
GVariantBuilder builder = G_VARIANT_BUILDER_INIT (G_VARIANT_TYPE ("a{ss}"));
GHashTable *attrs = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
GHashTableIter iter;
gpointer key, value;
gtk_text_view_add_default_attributes (GTK_TEXT_VIEW (widget), &builder);
gtk_text_view_add_default_attributes (GTK_TEXT_VIEW (widget), attrs);
g_hash_table_iter_init (&iter, attrs);
while (g_hash_table_iter_next (&iter, &key, &value))
g_variant_builder_add (&builder, "{ss}", key, value != NULL ? value : "");
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(a{ss})", &builder));
g_hash_table_unref (attrs);
}
else if (g_strcmp0 (method_name, "GetNSelections") == 0)
{
-95
View File
@@ -23,101 +23,6 @@
#include "gtktextviewprivate.h"
#include "gtkpangoprivate.h"
void
gtk_text_view_add_default_attributes (GtkTextView *view,
GVariantBuilder *builder)
{
GtkTextAttributes *text_attrs;
PangoFontDescription *font;
char *value;
text_attrs = gtk_text_view_get_default_attributes (view);
font = text_attrs->font;
if (font)
{
char **names, **values;
gtk_pango_get_font_attributes (font, &names, &values);
for (unsigned i = 0; names[i] != NULL; i++)
g_variant_builder_add (builder, "{ss}", names[i], values[i]);
g_strfreev (names);
g_strfreev (values);
}
g_variant_builder_add (builder, "{ss}", "justification",
gtk_justification_to_string (text_attrs->justification));
g_variant_builder_add (builder, "{ss}", "direction",
gtk_text_direction_to_string (text_attrs->direction));
g_variant_builder_add (builder, "{ss}", "wrap-mode",
gtk_wrap_mode_to_string (text_attrs->wrap_mode));
g_variant_builder_add (builder, "{ss}", "editable",
text_attrs->editable ? "true" : "false");
g_variant_builder_add (builder, "{ss}", "invisible",
text_attrs->invisible ? "true" : "false");
g_variant_builder_add (builder, "{ss}", "bg-full-height",
text_attrs->bg_full_height ? "true" : "false");
g_variant_builder_add (builder, "{ss}", "strikethrough",
text_attrs->appearance.strikethrough ? "true" : "false");
g_variant_builder_add (builder, "{ss}", "underline",
pango_underline_to_string (text_attrs->appearance.underline));
value = g_strdup_printf ("%u,%u,%u",
(guint)(text_attrs->appearance.bg_rgba->red * 65535),
(guint)(text_attrs->appearance.bg_rgba->green * 65535),
(guint)(text_attrs->appearance.bg_rgba->blue * 65535));
g_variant_builder_add (builder, "{ss}", "bg-color", value);
g_free (value);
value = g_strdup_printf ("%u,%u,%u",
(guint)(text_attrs->appearance.fg_rgba->red * 65535),
(guint)(text_attrs->appearance.fg_rgba->green * 65535),
(guint)(text_attrs->appearance.fg_rgba->blue * 65535));
g_variant_builder_add (builder, "{ss}", "bg-color", value);
g_free (value);
value = g_strdup_printf ("%g", text_attrs->font_scale);
g_variant_builder_add (builder, "{ss}", "scale", value);
g_free (value);
value = g_strdup ((gchar *)(text_attrs->language));
g_variant_builder_add (builder, "{ss}", "language", value);
g_free (value);
value = g_strdup_printf ("%i", text_attrs->appearance.rise);
g_variant_builder_add (builder, "{ss}", "rise", value);
g_free (value);
value = g_strdup_printf ("%i", text_attrs->pixels_inside_wrap);
g_variant_builder_add (builder, "{ss}", "pixels-inside-wrap", value);
g_free (value);
value = g_strdup_printf ("%i", text_attrs->pixels_below_lines);
g_variant_builder_add (builder, "{ss}", "pixels-below-lines", value);
g_free (value);
value = g_strdup_printf ("%i", text_attrs->pixels_above_lines);
g_variant_builder_add (builder, "{ss}", "pixels-above-lines", value);
g_free (value);
value = g_strdup_printf ("%i", text_attrs->indent);
g_variant_builder_add (builder, "{ss}", "indent", value);
g_free (value);
value = g_strdup_printf ("%i", text_attrs->left_margin);
g_variant_builder_add (builder, "{ss}", "left-margin", value);
g_free (value);
value = g_strdup_printf ("%i", text_attrs->right_margin);
g_variant_builder_add (builder, "{ss}", "right-margin", value);
g_free (value);
gtk_text_attributes_unref (text_attrs);
}
char *
gtk_text_view_get_text_before (GtkTextView *view,
int offset,
-3
View File
@@ -23,9 +23,6 @@
G_BEGIN_DECLS
void gtk_text_view_add_default_attributes (GtkTextView *view,
GVariantBuilder *builder);
char *gtk_text_view_get_text_before (GtkTextView *view,
int offset,
AtspiTextBoundaryType boundary_type,
+1
View File
@@ -370,6 +370,7 @@ gtk_cell_renderer_pixbuf_set_property (GObject *object,
else
texture = NULL;
take_image_definition (cellpixbuf, gtk_image_definition_new_paintable (GDK_PAINTABLE (texture)));
g_clear_object (&texture);
break;
case PROP_PIXBUF_EXPANDER_OPEN:
g_clear_object (&priv->pixbuf_expander_open);
BIN
View File
Binary file not shown.
+45 -9
View File
@@ -24,9 +24,14 @@
/* The format of the generated data is: a(aussasasu).
* Each member of the array has the following fields:
* au - sequence of unicode codepoints. If the
* sequence contains a 0, it marks the point
* where skin tone modifiers should be inserted
* au - sequence of unicode codepoints, including the emoji presentation
* selector (FE0F) where necessary. skin tone variations are represented
* with either the first tone code point (1F3FB) or 0. the choice indicates
* the handling of the generic sequence (i.e., no tone), which may have a
* default text presentation and thus require the emoji presentation
* selector (unlike sequences with a tone, which are always presented as
* emojis). 0 indicates the text case, that is, replace this code point
* with FE0F, while 1F3FB indicates this code point should be omitted.
* s - name in english, e.g. "man worker"
* s - name in locale
* as - keywords in english, e.g. "man", "worker"
@@ -48,7 +53,8 @@
gboolean
parse_code (GVariantBuilder *b,
const char *code)
const char *code,
gboolean needs_presentation_selector)
{
g_auto(GStrv) strv = NULL;
int j;
@@ -66,11 +72,31 @@ parse_code (GVariantBuilder *b,
return FALSE;
}
if (0x1f3fb <= u && u <= 0x1f3ff)
g_variant_builder_add (b, "u", 0);
{
if (needs_presentation_selector)
{
if (strv[j+1])
{
g_error ("unexpected inner skin tone in default-text generic sequence: %s\n", code);
return FALSE;
}
g_variant_builder_add (b, "u", 0);
needs_presentation_selector = FALSE;
}
else
{
g_variant_builder_add (b, "u", 0x1f3fb);
}
}
else
g_variant_builder_add (b, "u", u);
{
g_variant_builder_add (b, "u", u);
}
}
if (needs_presentation_selector)
g_variant_builder_add (b, "u", 0xfe0f);
return TRUE;
}
@@ -120,7 +146,6 @@ main (int argc, char *argv[])
array_en = json_node_get_array (root_en);
length_en = json_array_get_length (array_en);
g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(aussasasu)"));
for (i = 0; i < length; i++)
{
@@ -133,13 +158,21 @@ main (int argc, char *argv[])
const char *name;
const char *name_en;
char *code;
const char *text;
gboolean needs_presentation_selector;
if (!json_object_has_member (obj, "group"))
continue;
if (!json_object_has_member (obj_en, "group"))
continue;
group = json_object_get_int_member (obj, "group");
name = json_object_get_string_member (obj, "label");
name_en = json_object_get_string_member (obj_en, "label");
if (g_str_has_suffix (name_en, "skin tone"))
continue;
if (json_object_has_member (obj, "skins") && json_object_has_member (obj_en, "skins"))
{
JsonArray *a2 = json_object_get_array_member (obj, "skins");
@@ -151,9 +184,12 @@ main (int argc, char *argv[])
{
code = g_strdup (json_object_get_string_member (obj, "hexcode"));
}
g_variant_builder_init (&b1, G_VARIANT_TYPE ("au"));
if (!parse_code (&b1, code))
text = json_object_get_string_member (obj, "text");
needs_presentation_selector = *text != '\0' && json_object_get_int_member (obj, "type") == 0;
g_variant_builder_init (&b1, G_VARIANT_TYPE ("au"));
if (!parse_code (&b1, code, needs_presentation_selector))
return 1;
g_variant_builder_init (&b2, G_VARIANT_TYPE ("as"));
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+167 -1
View File
@@ -6,7 +6,7 @@
#include "config.h"
#include "gtkaccessibletext-private.h"
#include "gtkaccessibletextprivate.h"
#include "gtkatcontextprivate.h"
@@ -63,6 +63,15 @@ gtk_accessible_text_default_get_attributes (GtkAccessibleText *self,
return FALSE;
}
static void
gtk_accessible_text_default_get_default_attributes (GtkAccessibleText *self,
char ***attribute_names,
char ***attribute_values)
{
*attribute_names = NULL;
*attribute_values = NULL;
}
static void
gtk_accessible_text_default_init (GtkAccessibleTextInterface *iface)
{
@@ -71,6 +80,7 @@ gtk_accessible_text_default_init (GtkAccessibleTextInterface *iface)
iface->get_caret_position = gtk_accessible_text_default_get_caret_position;
iface->get_selection = gtk_accessible_text_default_get_selection;
iface->get_attributes = gtk_accessible_text_default_get_attributes;
iface->get_default_attributes = gtk_accessible_text_default_get_default_attributes;
}
static GBytes *
@@ -155,12 +165,16 @@ gtk_accessible_text_get_contents_at (GtkAccessibleText *self,
unsigned int *start,
unsigned int *end)
{
static const char empty[] = {0};
GBytes *bytes;
g_return_val_if_fail (GTK_IS_ACCESSIBLE_TEXT (self), NULL);
bytes = GTK_ACCESSIBLE_TEXT_GET_IFACE (self)->get_contents_at (self, offset, granularity, start, end);
if (bytes == NULL)
return g_bytes_new_static (empty, sizeof empty);
return nul_terminate_contents (bytes);
}
@@ -260,6 +274,158 @@ gtk_accessible_text_get_attributes (GtkAccessibleText *self,
attribute_values);
}
/*< private >
* gtk_accessible_text_get_default_attributes:
* @self: the accessible object
* @attribute_names: (out) (array zero-terminated=1) (element-type utf8) (optional) (transfer full):
* the names of the attributes inside the accessible object
* @attribute_values: (out) (array zero-terminated=1) (element-type utf8) (optional) (transfer full):
* the values of the attributes inside the accessible object
*
* Retrieves the default text attributes inside the accessible object.
*
* Each attribute is composed by:
*
* - a name, typically in the form of a reverse DNS identifier
* - a value
*
* If this function returns true, `n_attributes` will be set to a value
* greater than or equal to one, @ranges will be set to a newly
* allocated array of [struct#Gtk.AccessibleTextRange] which should
* be freed with g_free(), @attribute_names and @attribute_values
* will be set to string arrays that should be freed with g_strfreev().
*
* Since: 4.14
*/
void
gtk_accessible_text_get_default_attributes (GtkAccessibleText *self,
char ***attribute_names,
char ***attribute_values)
{
g_return_if_fail (GTK_IS_ACCESSIBLE_TEXT (self));
GTK_ACCESSIBLE_TEXT_GET_IFACE (self)->get_default_attributes (self,
attribute_names,
attribute_values);
}
/*< private >
* gtk_accessible_text_get_attributes_run:
* @self: the accessible object
* @offset: the offset, in characters
* @include_defaults: whether to include the default attributes in the
* returned array
* @n_ranges: (out): the number of attributes
* @ranges: (out) (array length=n_attributes) (optional): the ranges of the attributes
* inside the accessible object
* @attribute_names: (out) (array zero-terminated=1) (element-type utf8) (optional) (transfer full):
* the names of the attributes inside the accessible object
* @attribute_values: (out) (array zero-terminated=1) (element-type utf8) (optional) (transfer full):
* the values of the attributes inside the accessible object
*
* Retrieves the text attributes inside the accessible object.
*
* Each attribute is composed by:
*
* - a range
* - a name, typically in the form of a reverse DNS identifier
* - a value
*
* If this function returns true, `n_ranges` will be set to a value
* greater than or equal to one, @ranges will be set to a newly
* allocated array of [struct#Gtk.AccessibleTextRange] which should
* be freed with g_free(), @attribute_names and @attribute_values
* will be set to string arrays that should be freed with g_strfreev().
*
* Returns: true if the accessible object has at least an attribute,
* and false otherwise
*
* Since: 4.14
*/
gboolean
gtk_accessible_text_get_attributes_run (GtkAccessibleText *self,
unsigned int offset,
gboolean include_defaults,
gsize *n_ranges,
GtkAccessibleTextRange **ranges,
char ***attribute_names,
char ***attribute_values)
{
GHashTable *attrs;
GHashTableIter attr_iter;
gpointer key, value;
char **attr_names, **attr_values;
gboolean res;
GStrvBuilder *names_builder;
GStrvBuilder *values_builder;
g_return_val_if_fail (GTK_IS_ACCESSIBLE_TEXT (self), FALSE);
attrs = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
if (include_defaults)
{
gtk_accessible_text_get_default_attributes (self,
&attr_names,
&attr_values);
for (unsigned i = 0; attr_names[i] != NULL; i++)
{
g_hash_table_insert (attrs,
g_steal_pointer (&attr_names[i]),
g_steal_pointer (&attr_values[i]));
}
g_free (attr_names);
g_free (attr_values);
}
res = gtk_accessible_text_get_attributes (self,
offset,
n_ranges,
ranges,
&attr_names,
&attr_values);
/* If there are no attributes, we can bail out early */
if (!res && !include_defaults)
{
g_hash_table_unref (attrs);
*attribute_names = NULL;
*attribute_values = NULL;
return FALSE;
}
/* The text attributes override the default ones */
for (unsigned i = 0; i < *n_ranges; i++)
{
g_hash_table_insert (attrs,
g_steal_pointer (&attr_names[i]),
g_steal_pointer (&attr_values[i]));
}
g_free (attr_names);
g_free (attr_values);
names_builder = g_strv_builder_new ();
values_builder = g_strv_builder_new ();
g_hash_table_iter_init (&attr_iter, attrs);
while (g_hash_table_iter_next (&attr_iter, &key, &value))
{
g_strv_builder_add (names_builder, key);
g_strv_builder_add (values_builder, value);
}
*attribute_names = g_strv_builder_end (names_builder);
*attribute_values = g_strv_builder_end (values_builder);
g_strv_builder_unref (names_builder);
g_strv_builder_unref (values_builder);
g_hash_table_unref (attrs);
return TRUE;
}
/**
* gtk_accessible_text_update_caret_position:
* @self: the accessible object
+27
View File
@@ -228,6 +228,33 @@ struct _GtkAccessibleTextInterface
GtkAccessibleTextRange **ranges,
char ***attribute_names,
char ***attribute_values);
/**
* GtkAccessibleTextInterface::get_default_attributes:
* @self: the accessible object
* @attribute_names: (out) (array zero-terminated=1) (optional) (transfer full): the
* names of the default attributes inside the accessible object
* @attribute_values: (out) (array zero-terminated=1) (optional) (transfer full): the
* values of the default attributes inside the accessible object
*
* Retrieves the default text attributes inside the accessible object.
*
* Each attribute is composed by:
*
* - a name
* - a value
*
* It is left to the implementation to determine the serialization format
* of the value to a string.
*
* GTK provides support for various text attribute names and values, but
* implementations of this interface are free to add their own attributes.
*
* Since: 4.14
*/
void (* get_default_attributes) (GtkAccessibleText *self,
char ***attribute_names,
char ***attribute_values);
};
GDK_AVAILABLE_IN_4_14
@@ -1,4 +1,4 @@
/* gtkaccessibletext-private.h: Private definitions for GtkAccessibleText
/* gtkaccessibletextprivate.h: Private definitions for GtkAccessibleText
*
* SPDX-FileCopyrightText: 2023 Emmanuele Bassi
* SPDX-License-Identifier: LGPL-2.1-or-later
@@ -37,4 +37,19 @@ gtk_accessible_text_get_attributes (GtkAccessibleText *self,
GtkAccessibleTextRange **ranges,
char ***attribute_names,
char ***attribute_values);
void
gtk_accessible_text_get_default_attributes (GtkAccessibleText *self,
char ***attribute_names,
char ***attribute_values);
gboolean
gtk_accessible_text_get_attributes_run (GtkAccessibleText *self,
unsigned int offset,
gboolean include_defaults,
gsize *n_ranges,
GtkAccessibleTextRange **ranges,
char ***attribute_names,
char ***attribute_values);
G_END_DECLS
+19 -3
View File
@@ -1390,9 +1390,25 @@ gtk_at_context_get_text_accumulate (GtkATContext *self,
{
const char *text = gtk_widget_get_tooltip_text (GTK_WIDGET (self->accessible));
if (text && not_just_space (text))
if (!check_duplicates || ((property == GTK_ACCESSIBLE_PROPERTY_LABEL && strcmp(text, gtk_at_context_get_description_internal (self, FALSE)) != 0)
|| (property == GTK_ACCESSIBLE_PROPERTY_DESCRIPTION && strcmp(text, gtk_at_context_get_name_internal (self, FALSE)) != 0)))
append_with_space (res, text);
{
gboolean append = !check_duplicates;
if (!append)
{
char *description = gtk_at_context_get_description_internal (self, FALSE);
char *name = gtk_at_context_get_name_internal (self, FALSE);
append =
(property == GTK_ACCESSIBLE_PROPERTY_LABEL && strcmp (text, description) != 0) ||
(property == GTK_ACCESSIBLE_PROPERTY_DESCRIPTION && strcmp (text, name) != 0);
g_free (description);
g_free (name);
}
if (append)
append_with_space (res, text);
}
}
}
+53 -3
View File
@@ -99,9 +99,7 @@
* Objects are described by `<object>` elements, which can contain
* `<property>` elements to set properties, `<signal>` elements which
* connect signals to handlers, and `<child>` elements, which describe
* child objects (most often widgets inside a container, but also e.g.
* actions in an action group, or columns in a tree model). A `<child>`
* element contains an `<object>` element which describes the child object.
* child objects.
*
* Typically, the specific kind of object represented by an `<object>`
* element is specified by the class attribute. If the type has not
@@ -173,6 +171,53 @@
* exception to this rule is that an object has to be constructed before
* it can be used as the value of a construct-only property.
*
* ### Child objects
*
* Many widgets have properties for child widgets, such as
* [property@Gtk.Expander:child]. In this case, the preferred way to
* specify the child widget in a ui file is to simply set the property:
*
* ```xml
* <object class="GtkExpander">
* <property name="child">
* <object class="GtkLabel">
* ...
* </object>
* </property>
* </object>
* ```
*
* Generic containers that can contain an arbitrary number of children,
* such as [class@Gtk.Box] instead use the `<child>` element. A `<child>`
* element contains an `<object>` element which describes the child object.
* Most often, child objects are widgets inside a container, but they can
* also be, e.g., actions in an action group, or columns in a tree model.
*
* Any object type that implements the [iface@Gtk.Buildable] interface can
* specify how children may be added to it. Since many objects and widgets that
* are included with GTK already implement the `GtkBuildable` interface,
* typically child objects can be added using the `<child>` element without
* having to be concerned about the underlying implementation.
*
* See the [`GtkWidget` documentation](class.Widget.html#gtkwidget-as-gtkbuildable)
* for many examples of using `GtkBuilder` with widgets, including setting
* child objects using the `<child>` element.
*
* A noteworthy special case to the general rule that only objects implementing
* `GtkBuildable` may specify how to handle the `<child>` element is that
* `GtkBuilder` provides special support for adding objects to a
* [class@Gio.ListStore] by using the `<child>` element. For instance:
*
* ```xml
* <object class="GListStore">
* <property name="item-type">MyObject</property>
* <child>
* <object class="MyObject" />
* </child>
* ...
* </object>
* ```
*
* ### Property bindings
*
* It is also possible to bind a property value to another object's
@@ -208,6 +253,11 @@
* For more information, see the documentation of the
* [method@GObject.Object.bind_property] method.
*
* Please note that another way to set up bindings between objects in .ui files
* is to use the `GtkExpression` methodology. See the
* [`GtkExpression` documentation](class.Expression.html#gtkexpression-in-ui-files)
* for more information.
*
* ### Internal children
*
* Sometimes it is necessary to refer to widgets which have implicitly
+5 -5
View File
@@ -242,6 +242,7 @@ gtk_emoji_chooser_finalize (GObject *object)
g_source_remove (chooser->populate_idle);
g_clear_pointer (&chooser->data, g_variant_unref);
g_clear_pointer (&chooser->iter, g_variant_iter_free);
g_clear_object (&chooser->settings);
G_OBJECT_CLASS (gtk_emoji_chooser_parent_class)->finalize (object);
@@ -448,7 +449,7 @@ static gboolean
has_variations (GVariant *emoji_data)
{
GVariant *codes;
int i;
gsize i;
gboolean has_variations;
has_variations = FALSE;
@@ -457,7 +458,7 @@ has_variations (GVariant *emoji_data)
{
gunichar code;
g_variant_get_child (codes, i, "u", &code);
if (code == 0)
if (code == 0 || code == 0x1f3fb)
{
has_variations = TRUE;
break;
@@ -570,15 +571,14 @@ add_emoji (GtkWidget *box,
{
g_variant_get_child (codes, i, "u", &code);
if (code == 0)
code = modifier != 0 ? modifier : 0xfe0f;
if (code == 0x1f3fb)
code = modifier;
if (code != 0)
p += g_unichar_to_utf8 (code, p);
}
g_variant_unref (codes);
if (code != 0xFE0F && code != 0xFE0E)
p += g_unichar_to_utf8 (0xFE0F, p); /* Append a variation selector, if there isn't one already */
p[0] = 0;
label = gtk_label_new (text);
+3 -2
View File
@@ -409,7 +409,7 @@ has_variations (GVariant *emoji_data)
{
gunichar code;
g_variant_get_child (codes, i, "u", &code);
if (code == 0)
if (code == 0 || code == 0x1f3fb)
{
has_variations = TRUE;
break;
@@ -438,12 +438,13 @@ get_text (GVariant *emoji_data,
g_variant_get_child (codes, i, "u", &code);
if (code == 0)
code = modifier != 0 ? modifier : 0xfe0f;
if (code == 0x1f3fb)
code = modifier;
if (code != 0)
p += g_unichar_to_utf8 (code, p);
}
g_variant_unref (codes);
p += g_unichar_to_utf8 (0xFE0F, p); /* U+FE0F is the Emoji variation selector */
p[0] = 0;
}
+20 -3
View File
@@ -150,9 +150,10 @@
* <constant type='gchararray'>Hello, world</constant>
* ```
*
* To create a closure expression, use the `<closure>` element. The `type` and `function`
* attributes specify what function to use for the closure, the content of the element
* contains the expressions for the parameters. For instance:
* To create a closure expression, use the `<closure>` element. The `function`
* attribute specifies what function to use for the closure, and the `type`
* attribute specifies its return type. The content of the element contains the
* expressions for the parameters. For instance:
*
* ```xml
* <closure type='gchararray' function='combine_args_somehow'>
@@ -160,6 +161,22 @@
* <lookup type='GFile' name='size'>myfile</lookup>
* </closure>
* ```
*
* To create a property binding, use the `<binding>` element in place of where a
* `<property>` tag would ordinarily be used. The `name` and `object` attributes are
* supported. The `name` attribute is required, and pertains to the applicable property
* name. The `object` attribute is optional. If provided, it will use the specified object
* as the `this` object when the expression is evaluated. Here is an example in which the
* `label` property of a `GtkLabel` is bound to the `string` property of another arbitrary
* object:
*
* ```xml
* <object class='GtkLabel'>
* <binding name='label'>
* <lookup name='string'>some_other_object</lookup>
* </binding>
* </object>
* ```
*/
typedef struct _WeakRefGuard WeakRefGuard;
+1
View File
@@ -708,6 +708,7 @@ refresh_current_folder_and_file_part (GtkFileChooserEntry *chooser_entry)
old_file_part = chooser_entry->file_part;
text = gtk_file_chooser_entry_get_completion_text (chooser_entry);
g_return_if_fail (text != NULL);
last_slash = strrchr (text, G_DIR_SEPARATOR);
if (last_slash)
+2
View File
@@ -2232,6 +2232,7 @@ update_feature_example (GtkFontChooserWidget *fontchooser,
attr->start_index = 0;
attr->end_index = strlen (input);
pango_attr_list_insert (attrs, attr);
g_free (str);
str = g_strconcat (item->name, " 1", NULL);
attr = pango_attr_font_features_new (str);
attr->start_index = strlen (input) + strlen ("");
@@ -2241,6 +2242,7 @@ update_feature_example (GtkFontChooserWidget *fontchooser,
attr->start_index = strlen (input) + strlen ("");
attr->end_index = attr->start_index + strlen (input);
pango_attr_list_insert (attrs, attr);
g_free (str);
gtk_label_set_text (GTK_LABEL (item->example), text);
gtk_label_set_attributes (GTK_LABEL (item->example), attrs);
+24 -6
View File
@@ -18,7 +18,6 @@
#include "config.h"
#include <string.h>
#include "gtkimcontext.h"
#include "gtkimcontextprivate.h"
#include "gtkprivate.h"
#include "gtktypebuiltins.h"
#include "gtkmarshalers.h"
@@ -1007,11 +1006,30 @@ gtk_im_context_set_property (GObject *obj,
}
}
void
gtk_im_context_activate_osk (GtkIMContext *context)
/**
* gtk_im_context_activate_osk:
* @context: a `GtkIMContext`
* @event: (nullable): a [class@Gdk.Event]
*
* Requests the platform to show an on-screen keyboard for user input.
*
* This method will return %TRUE if this request was actually performed
* to the platform, other environmental factors may result in an on-screen
* keyboard effectively not showing up.
*
* Returns: %TRUE if an on-screen keyboard could be requested to the platform.
*
* Since: 4.14
**/
gboolean
gtk_im_context_activate_osk (GtkIMContext *context,
GdkEvent *event)
{
g_return_if_fail (GTK_IS_IM_CONTEXT (context));
g_return_val_if_fail (GTK_IS_IM_CONTEXT (context), FALSE);
g_return_val_if_fail (!event || GDK_IS_EVENT (event), FALSE);
if (GTK_IM_CONTEXT_GET_CLASS (context)->activate_osk)
GTK_IM_CONTEXT_GET_CLASS (context)->activate_osk (context);
if (!GTK_IM_CONTEXT_GET_CLASS (context)->activate_osk_with_event)
return FALSE;
return GTK_IM_CONTEXT_GET_CLASS (context)->activate_osk_with_event (context, event);
}
+6 -1
View File
@@ -96,9 +96,10 @@ struct _GtkIMContextClass
/*< private >*/
void (* activate_osk) (GtkIMContext *context);
gboolean (* activate_osk_with_event) (GtkIMContext *context,
GdkEvent *event);
/* Padding for future expansion */
void (*_gtk_reserved1) (void);
void (*_gtk_reserved2) (void);
void (*_gtk_reserved3) (void);
void (*_gtk_reserved4) (void);
@@ -168,6 +169,10 @@ gboolean gtk_im_context_delete_surrounding (GtkIMContext *context,
int offset,
int n_chars);
GDK_AVAILABLE_IN_4_14
gboolean gtk_im_context_activate_osk (GtkIMContext *context,
GdkEvent *event);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkIMContext, g_object_unref)
G_END_DECLS
-23
View File
@@ -1,23 +0,0 @@
/* GTK - The GIMP Toolkit
* Copyright (C) 2022 Red Hat Inc.
*
* 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 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/>.
*/
#pragma once
#include "gtkimcontext.h"
void gtk_im_context_activate_osk (GtkIMContext *context);
+6 -98
View File
@@ -71,10 +71,6 @@ struct _GtkIMContextWayland
GtkIMContextSimple parent_instance;
GtkWidget *widget;
GtkGesture *gesture;
double press_x;
double press_y;
struct {
char *text;
int cursor_idx;
@@ -521,7 +517,6 @@ gtk_im_context_wayland_finalize (GObject *object)
gtk_im_context_wayland_focus_out (GTK_IM_CONTEXT (context));
g_clear_object (&context->widget);
g_clear_object (&context->gesture);
g_free (context->surrounding.text);
g_free (context->current_preedit.text);
g_free (context->pending_preedit.text);
@@ -530,50 +525,6 @@ gtk_im_context_wayland_finalize (GObject *object)
G_OBJECT_CLASS (gtk_im_context_wayland_parent_class)->finalize (object);
}
static void
pressed_cb (GtkGestureClick *gesture,
int n_press,
double x,
double y,
GtkIMContextWayland *context)
{
if (n_press == 1)
{
context->press_x = x;
context->press_y = y;
}
}
static void
released_cb (GtkGestureClick *gesture,
int n_press,
double x,
double y,
GtkIMContextWayland *context)
{
GtkIMContextWaylandGlobal *global;
GtkInputHints hints;
global = gtk_im_context_wayland_get_global (context);
if (global == NULL)
return;
g_object_get (context, "input-hints", &hints, NULL);
if (global->focused &&
n_press == 1 &&
(hints & GTK_INPUT_HINT_INHIBIT_OSK) == 0 &&
!gtk_drag_check_threshold_double (context->widget,
context->press_x,
context->press_y,
x, y))
{
zwp_text_input_v3_enable (global->text_input);
notify_im_change (GTK_IM_CONTEXT_WAYLAND (context),
ZWP_TEXT_INPUT_V3_CHANGE_CAUSE_OTHER);
}
}
static void
gtk_im_context_wayland_set_client_widget (GtkIMContext *context,
GtkWidget *widget)
@@ -586,34 +537,7 @@ gtk_im_context_wayland_set_client_widget (GtkIMContext *context,
if (context_wayland->widget)
gtk_im_context_wayland_focus_out (context);
if (context_wayland->widget && context_wayland->gesture)
{
gtk_widget_remove_controller (context_wayland->widget,
GTK_EVENT_CONTROLLER (context_wayland->gesture));
context_wayland->gesture = NULL;
}
g_set_object (&context_wayland->widget, widget);
if (widget &&
!GTK_IS_TEXT (widget) &&
!GTK_IS_TEXT_VIEW (widget))
{
GtkGesture *gesture;
gesture = gtk_gesture_click_new ();
gtk_event_controller_set_static_name (GTK_EVENT_CONTROLLER (gesture), "wayland-im-context-click");
gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (gesture),
GTK_PHASE_CAPTURE);
g_signal_connect (gesture, "pressed",
G_CALLBACK (pressed_cb), context);
g_signal_connect (gesture, "released",
G_CALLBACK (released_cb), context);
gtk_widget_add_controller (context_wayland->widget,
GTK_EVENT_CONTROLLER (gesture));
context_wayland->gesture = gesture;
}
}
static void
@@ -847,9 +771,6 @@ gtk_im_context_wayland_focus_in (GtkIMContext *context)
if (!global->text_input)
return;
if (self->gesture)
gtk_event_controller_reset (GTK_EVENT_CONTROLLER (self->gesture));
if (global->focused)
enable (self, global);
}
@@ -884,7 +805,6 @@ gtk_im_context_wayland_set_cursor_location (GtkIMContext *context,
GdkRectangle *rect)
{
GtkIMContextWayland *context_wayland;
int side;
context_wayland = GTK_IM_CONTEXT_WAYLAND (context);
@@ -894,20 +814,6 @@ gtk_im_context_wayland_set_cursor_location (GtkIMContext *context,
context_wayland->cursor_rect.height == rect->height)
return;
/* Reset the gesture if the cursor changes too far (eg. clicking
* between disjoint positions in the text).
*
* Still Allow some jittering (a square almost double the cursor rect height
* on either side) as clicking on the exact same position between characters
* is hard.
*/
side = context_wayland->cursor_rect.height;
if (context_wayland->gesture &&
(ABS (rect->x - context_wayland->cursor_rect.x) >= side ||
ABS (rect->y - context_wayland->cursor_rect.y) >= side))
gtk_event_controller_reset (GTK_EVENT_CONTROLLER (context_wayland->gesture));
context_wayland->cursor_rect = *rect;
}
@@ -974,18 +880,20 @@ gtk_im_context_wayland_commit (GtkIMContext *context,
ZWP_TEXT_INPUT_V3_CHANGE_CAUSE_INPUT_METHOD);
}
static void
gtk_im_context_wayland_activate_osk (GtkIMContext *context)
static gboolean
gtk_im_context_wayland_activate_osk_with_event (GtkIMContext *context,
GdkEvent *event)
{
GtkIMContextWaylandGlobal *global;
global = gtk_im_context_wayland_get_global (GTK_IM_CONTEXT_WAYLAND (context));
if (global == NULL)
return;
return FALSE;
zwp_text_input_v3_enable (global->text_input);
notify_im_change (GTK_IM_CONTEXT_WAYLAND (context),
ZWP_TEXT_INPUT_V3_CHANGE_CAUSE_OTHER);
return TRUE;
}
static void
@@ -1007,7 +915,7 @@ gtk_im_context_wayland_class_init (GtkIMContextWaylandClass *klass)
im_context_class->set_surrounding_with_selection = gtk_im_context_wayland_set_surrounding;
im_context_class->get_surrounding_with_selection = gtk_im_context_wayland_get_surrounding;
im_context_class->commit = gtk_im_context_wayland_commit;
im_context_class->activate_osk = gtk_im_context_wayland_activate_osk;
im_context_class->activate_osk_with_event = gtk_im_context_wayland_activate_osk_with_event;
}
static void
+9 -6
View File
@@ -20,7 +20,6 @@
#include <string.h>
#include <locale.h>
#include "gtkimcontextprivate.h"
#include "gtkimmulticontext.h"
#include "gtkimmoduleprivate.h"
#include "gtklabel.h"
@@ -106,7 +105,8 @@ static gboolean gtk_im_multicontext_delete_surrounding_cb (GtkIMContext *
int offset,
int n_chars,
GtkIMMulticontext *multicontext);
static void gtk_im_multicontext_activate_osk (GtkIMContext *context);
static gboolean gtk_im_multicontext_activate_osk_with_event (GtkIMContext *context,
GdkEvent *event);
static void propagate_purpose (GtkIMMulticontext *context);
@@ -130,7 +130,7 @@ gtk_im_multicontext_class_init (GtkIMMulticontextClass *class)
im_context_class->set_use_preedit = gtk_im_multicontext_set_use_preedit;
im_context_class->set_surrounding_with_selection = gtk_im_multicontext_set_surrounding_with_selection;
im_context_class->get_surrounding_with_selection = gtk_im_multicontext_get_surrounding_with_selection;
im_context_class->activate_osk = gtk_im_multicontext_activate_osk;
im_context_class->activate_osk_with_event = gtk_im_multicontext_activate_osk_with_event;
gobject_class->finalize = gtk_im_multicontext_finalize;
}
@@ -516,14 +516,17 @@ gtk_im_multicontext_set_surrounding_with_selection (GtkIMContext *context,
gtk_im_context_set_surrounding_with_selection (delegate, text, len, cursor_index, anchor_index);
}
static void
gtk_im_multicontext_activate_osk (GtkIMContext *context)
static gboolean
gtk_im_multicontext_activate_osk_with_event (GtkIMContext *context,
GdkEvent *event)
{
GtkIMMulticontext *multicontext = GTK_IM_MULTICONTEXT (context);
GtkIMContext *delegate = gtk_im_multicontext_get_delegate (multicontext);
if (delegate)
gtk_im_context_activate_osk (delegate);
return gtk_im_context_activate_osk (delegate, event);
else
return FALSE;
}
static void
+30 -1
View File
@@ -21,7 +21,7 @@
#include "gtkinscriptionprivate.h"
#include "gtkaccessibletext-private.h"
#include "gtkaccessibletextprivate.h"
#include "gtkcssnodeprivate.h"
#include "gtkcssstylechangeprivate.h"
#include "gtkpangoprivate.h"
@@ -1363,6 +1363,19 @@ gtk_inscription_accessible_text_get_contents (GtkAccessibleText *self,
return g_bytes_new_take (string, size);
}
static GBytes *
gtk_inscription_accessible_text_get_contents_at (GtkAccessibleText *self,
unsigned int offset,
GtkAccessibleTextGranularity granularity,
unsigned int *start,
unsigned int *end)
{
PangoLayout *layout = gtk_inscription_get_layout (GTK_INSCRIPTION (self));
char *string = gtk_pango_get_string_at (layout, offset, granularity, start, end);
return g_bytes_new_take (string, strlen (string));
}
static unsigned int
gtk_inscription_accessible_text_get_caret_position (GtkAccessibleText *self)
{
@@ -1408,13 +1421,29 @@ gtk_inscription_accessible_text_get_attributes (GtkAccessibleText *self,
return TRUE;
}
static void
gtk_inscription_accessible_text_get_default_attributes (GtkAccessibleText *self,
char ***attribute_names,
char ***attribute_values)
{
PangoLayout *layout = gtk_inscription_get_layout (GTK_INSCRIPTION (self));
char **names, **values;
gtk_pango_get_default_attributes (layout, &names, &values);
*attribute_names = names;
*attribute_values = values;
}
static void
gtk_inscription_accessible_text_init (GtkAccessibleTextInterface *iface)
{
iface->get_contents = gtk_inscription_accessible_text_get_contents;
iface->get_contents_at = gtk_inscription_accessible_text_get_contents_at;
iface->get_caret_position = gtk_inscription_accessible_text_get_caret_position;
iface->get_selection = gtk_inscription_accessible_text_get_selection;
iface->get_attributes = gtk_inscription_accessible_text_get_attributes;
iface->get_default_attributes = gtk_inscription_accessible_text_get_default_attributes;
}
/* }}} */

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