Compare commits

...

282 Commits

Author SHA1 Message Date
Matthias Clasen dd06452b0f gsk: Add some inline vec2 apis
The gpu renderers are using a vec2 for their scale, and frequently
need to access the components. Avoid PLT overhead for this.
2024-03-12 22:08:28 -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
Matthias Clasen ee5afdf919 Merge branch 'fix-inhibit-idle-warning' into 'main'
application: Prevent a warning

Closes #6470

See merge request GNOME/gtk!6942
2024-02-25 14:05:11 +00:00
Rūdolfs Mazurs 49a6b5d50a Update Latvian translation 2024-02-25 13:36:27 +00:00
Matthias Clasen dd7a0cbeb7 application: Prevent a warning
When we've handled a inhibit idle request via Wayland, there is
no need to call into the D-Bus inhibit api unless there's other
inhibit flags to handle.

Fixes: #6470
2024-02-25 08:21:05 -05:00
Sabri Ünal 38d808f3e2 Update Turkish translation 2024-02-25 13:08:46 +00:00
Andika Triwidada 16a608b9e5 Update Indonesian translation 2024-02-25 09:18:45 +00:00
Asier Sarasua Garmendia f1ff37e970 Update Basque translation 2024-02-25 06:41:43 +00:00
Baurzhan Muftakhidinov 71c68f5f36 Update Kazakh translation 2024-02-25 04:41:15 +00:00
Matthias Clasen 0d3265edc7 Merge branch 'more-monitor-madness' into 'main'
wayland: Fix handling of output scales more

Closes #6472

See merge request GNOME/gtk!6941
2024-02-25 02:19:08 +00:00
Matthias Clasen 854e40c60c wayland: Fix handling of output scales more
It turns out that the workaround in 7b380b2ffc was insufficient.
During initialization, we end up calling apply_monitor_changes()
while xdg_output is set, but xdg_output_geometry isn't. Be more
careful and prevent that from wreaking havoc with negative scales.

Fixes: #6472
2024-02-24 20:56:19 -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
Yaron Shahrabani 06f3b5dfd4 Update Hebrew translation 2024-02-24 16:37:47 +00:00
Matthias Clasen 05acb70d1c Merge branch 'matthiasc/for-main' into 'main'
wayland: Fix handling of output scales

See merge request GNOME/gtk!6940
2024-02-24 12:00:16 +00:00
Matthias Clasen 7b380b2ffc wayland: Fix handling of output scales
Wayland protocols, in their wisdom, replaced xdg_output_done
with wl_output_done, just to make it more fun to handle multiple
protocol versions.
2024-02-23 22:50:58 -05:00
Matthias Clasen f6e4b964b7 Merge branch 'gdkenums-formats' into 'main'
gdk: Improve docs for GdkMemoryFormat

See merge request GNOME/gtk!6939
2024-02-24 01:18:11 +00:00
Matthias Clasen 0b2d08f076 Merge branch 'fix-since-flag' into 'main'
gtkenums: Set since tag on POPOVER_MENU_SLIDING

See merge request GNOME/gtk!6938
2024-02-24 01:10:15 +00:00
Maximiliano Sandoval 1ad1a9fe4a gdkenums: Backtick the formats in docs 2024-02-24 01:12:59 +01:00
Maximiliano Sandoval fe15db92bd gdkenums: Add docs for missing formats 2024-02-24 01:12:57 +01:00
Maximiliano Sandoval 682b7773fc gdkenums: Document Since tags for memory formats 2024-02-24 00:43:21 +01:00
Maximiliano Sandoval 9055b6c6e5 gtkenums: Set since tag on POPOVER_MENU_SLIDING
See https://gitlab.gnome.org/GNOME/gtk/-/commit/d05f47a695f450ee81e4daae40de8a953283a273#note_2024930.
2024-02-24 00:19:18 +01:00
Danial Behzadi 9fd56dc5ad Update Persian translation 2024-02-23 20:50:54 +00:00
Matthias Clasen 1ec7f2bbcd Merge branch 'bilelmoussaoui/icons' into 'main'
icons: Set is_symbolic in IconPaintable.new_for_file

See merge request GNOME/gtk!6937
2024-02-23 20:42:45 +00:00
Bilal Elmoussaoui 4eb7208e35 icons: Set is_symbolic in IconPaintable.new_for_file
Otherwise symbolic icons won't be recognized as such.
Currently, in apps like Icon Library / App Icon Preview. Trying to
render the generated on-fly symbolic icons, require caching them in a
directory that mimics an icon theme and updating the search path of the
default gtk::IconTheme. That is mostly because
Gtk.IconPaintable.new_for_file wouldn't set is-symbolic even if the
passed file is a symbolic icon.
This would allow us to remove all the hacks in our apps
2024-02-23 18:43:06 +01:00
Andi Chandler 1ad88f7662 Update British English translation 2024-02-23 17:09:53 +00:00
Yuri Chornoivan 96b30073cf Update Ukrainian translation 2024-02-23 07:48:03 +00:00
Matthias Clasen 456956a2bd Merge branch 'matthiasc/for-main' into 'main'
entrybuffer: Fix some ubsan warnings

See merge request GNOME/gtk!6934
2024-02-23 01:47:25 +00:00
Matthias Clasen 4c794505da Merge branch 'michaelweghorn/a11y_report_empty_string' into 'main'
a11y: Report empty string as such

See merge request GNOME/gtk!6933
2024-02-23 01:06:10 +00:00
Matthias Clasen f627c9443e wayland: Quiet an ubsan complaint
unsigned char is promoted to int, which lacks the 32nd bit to
make 0xff << 24 work. Explicitly cast to unsigned int to make
it clear what we want to happen.
2024-02-22 19:57:02 -05:00
Matthias Clasen 06fa9befe0 tree model: Fix some ubsan warnings
memcpy() does not accept NULL as arguments.
2024-02-22 19:27:33 -05:00
Matthias Clasen a95dc5d609 entrybuffer: Fix some ubsan warnings
memcpy() does not accept NULL as argument.
2024-02-22 19:27:07 -05:00
Ekaterine Papava 2abe588e91 Update Georgian translation 2024-02-22 18:50:15 +00:00
Fran Dieguez ecdee288a7 Update Galician translation 2024-02-22 18:20:06 +00:00
Michael Weghorn e363fcca3c a11y: Report empty string as such
While the text data returned by the `get_contents`
function from the `GtkAccessibleTextInterface` does not
have to be NUL-terminated,
`gtk_accessible_text_get_contents` returns the
text contents as NUL-terminated UTF-8 data.

An empty string (returned as empty, i.e. size = 0,
but not NULL GBytes* data by `get_contents`) is valid, and
therefore also needs to be NUL-terminated, so do this.

Without this, e.g. querying the text of an empty paragraph
in the Gtk 4 variant of LibreOffice with the newly added
GtkAccessibleInterface implementation [1] gives an incorrect
result.

Previous sample use in Accerciser's IPython console:

    In [24]: acc.queryText().getText(0, -1)
    Out[24]: '[Invalid UTF-8]'

With this change in place, it now returns an empty
string as expected:

    In [25]: acc.queryText().getText(0, -1)
    Out[25]: ''

[1] https://git.libreoffice.org/core/commit/e268efd612d12ae9a459d6b9d0cb23220f025163
2024-02-22 18:16:37 +01:00
Matthias Clasen f46fb7c6fc Merge branch 'multilanguage-searching' into 'main'
Multilanguage searching for GtkEmojiChooser

This makes the Emoji chooser search look for strings in both
the current locale (if available), and in English. Each resource
file now contains the locale+English data. To accommodate the
changed dataset and schema, the recent-emoji settings key has
been renamed to recently-used-emoji.

See merge request GNOME/gtk!6804
2024-02-22 17:09:23 +00:00
Sudip Shil 985d964a34 Multilanguage searching for GtkEmojiChooser 2024-02-22 17:09:23 +00:00
Matthias Clasen 2a0286c19c Merge branch 'ebassi/issue-6462' into 'main'
a11y: Add "terminal" role

Closes #6462

See merge request GNOME/gtk!6932
2024-02-22 15:33:33 +00:00
Emmanuele Bassi 9a05af61e8 a11y: Map GTK terminal role to AT-SPI
AT-SPI has a terminal role for virtual terminals.

Fixes: #6462
2024-02-22 14:46:11 +00:00
Emmanuele Bassi 68d2e9c068 a11y: Add "terminal" role
Not in the WAI-ARIA spec, but UI toolkits have terminal widgets.
2024-02-22 14:46:11 +00:00
Ekaterine Papava 89ba937fd3 Update Georgian translation 2024-02-22 13:57:24 +00:00
Emmanuele Bassi 840cd6f10f Merge branch 'michaelweghorn/a11y_fix_atspi_getcharacteratoffset' into 'main'
a11y: Fix offset handling for AT-SPI GetCharacterAtOffset

See merge request GNOME/gtk!6931
2024-02-22 13:16:42 +00:00
Yuri Chornoivan cccfc1a38d Update Ukrainian translation 2024-02-22 12:53:09 +00:00
Michael Weghorn ff26aa2fa7 a11y: Fix offset handling for AT-SPI GetCharacterAtOffset
The text retrieved using `gtk_accessible_text_get_contents`
already contains only the character at the given offset,
and so the character is at index 0 in `str`, rather than at
the same offset again, so adjust this accordingly.

With this in place, querying the character in a
LibreOffice paragraph consisting of the text
"Hello world." now gives the expected results
with a pending LibreOffice change [1] to support
the new GtkAccessibleText interface:

    In [1]: text  = acc.queryText()
    In [2]: text.getCharacterAtOffset(0)
    Out[2]: 72
    In [3]: text.getCharacterAtOffset(1)
    Out[3]: 101
    In [4]: text.getCharacterAtOffset(2)
    Out[4]: 108
    In [5]: text.getCharacterAtOffset(3)
    Out[5]: 108
    In [6]: text.getCharacterAtOffset(4)
    Out[6]: 111

Previously, this would only work correctly
for an index of 0:

    In [1]: text = acc.queryText()
    In [2]: text.getCharacterAtOffset(0)
    Out[2]: 72
    In [3]: text.getCharacterAtOffset(1)
    Out[3]: 0
    In [4]: text.getCharacterAtOffset(2)
    Out[4]: 0
    In [5]: text.getCharacterAtOffset(3)
    Out[5]: 0
    In [6]: text.getCharacterAtOffset(4)
    Out[6]: 0

[1] https://gerrit.libreoffice.org/c/core/+/163733
2024-02-22 13:11:01 +01:00
Danial Behzadi 7192e67a6f Update Persian translation 2024-02-22 11:49:08 +00:00
Matthias Clasen 5354b91e64 Merge branch 'rendernode-tool-compare' into 'main'
rendernode tool: Add a compare command

See merge request GNOME/gtk!6930
2024-02-22 11:34:51 +00:00
Matthias Clasen c9c6b7bb2a rendernode tool: Add a compare command
This command can be used to compare the rendering of a node
to a reference image. It can also be used to compare the
renderings of two nodes, or to compare two images.
2024-02-21 22:27:32 -05:00
Matthias Clasen c93fa922dc Merge branch 'x11-shadow-fix' into 'main'
x11: Shadows require compositing

Closes #6464

See merge request GNOME/gtk!6928
2024-02-21 22:58:41 +00:00
Jordi Mas 8d7bfa2628 Update Catalan translation 2024-02-21 21:16:32 +01:00
Matthias Clasen e6a4cc8ba2 x11: Shadows require compositing
We can only do client-side shadows if we have an rgba visual
and a compositing wm.

Fallout from 6e7893d5.

Fixes: #6464
2024-02-21 12:35:02 -05:00
Matthias Clasen 7926ee68b8 Merge branch 'matthiasc/for-main' into 'main'
editable: Less draconian preconditions

Closes #6463

See merge request GNOME/gtk!6927
2024-02-21 12:37:04 +00:00
Matthias Clasen 239d47791d editable: Less draconian preconditions
Getting or deleting an empty string should be ok, and we do it
ourselves, e.g. in the file chooser.

Fixes: #6463
2024-02-21 07:14:44 -05:00
Daniel Mustieles 33f210bc85 Update Spanish translation 2024-02-21 11:38:09 +00:00
Matthias Clasen 021aae84dd Post-release version bump 2024-02-20 15:02:39 -05:00
Matthias Clasen e8508762f5 4.13.8 2024-02-20 15:02:39 -05:00
Matej Urbančič a0bbdfbeee Update Slovenian translation 2024-02-20 19:42:53 +00: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
215 changed files with 23441 additions and 11808 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.
+110 -2
View File
@@ -1,11 +1,119 @@
Overview of Changes in 4.13.8, 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
=========================================
* Accessibility:
- Add a GtkAccessibleText interface for allowing 3rd party
+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:
@@ -13,6 +13,7 @@ SYNOPSIS
| **gtk4-rendernode-tool** <COMMAND> [OPTIONS...] <FILE>
|
| **gtk4-rendernode-tool** benchmark [OPTIONS...] <FILE>
| **gtk4-rendernode-tool** compare [OPTIONS...] <FILE1> <FILE2>
| **gtk4-rendernode-tool** info [OPTIONS...] <FILE>
| **gtk4-rendernode-tool** render [OPTIONS...] <FILE> [<FILE>]
| **gtk4-rendernode-tool** show [OPTIONS...] <FILE>
@@ -75,7 +76,21 @@ and prints the runtimes.
the execution of the commands on the GPU. It can be useful to use this flag to test
command submission performance.
Compare
^^^^^^^
The ``compare`` command compares the rendering of a node with a reference image,
or the renderings of two nodes, or two images. If any differences are found, the
exit code is 1. If the images are identical, it is 0.
``--renderer=RENDERER``
Use the given renderer.
``--output=FILE``
Save the differences as a png image in ``FILE``.
``--quiet``
Don't write results to stdout.`
+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
+177 -42
View File
@@ -309,67 +309,202 @@ typedef enum
* The color values are premultiplied with the alpha value.
* @GDK_MEMORY_R8G8B8A8_PREMULTIPLIED: 4 bytes; for red, green, blue, alpha
* The color values are premultiplied with the alpha value.
* @GDK_MEMORY_A8B8G8R8_PREMULTIPLIED: 4 bytes; for alpha, blue, green, red,
* The color values are premultiplied with the alpha value. Since 4.14
* @GDK_MEMORY_B8G8R8A8: 4 bytes; for blue, green, red, alpha.
* @GDK_MEMORY_A8R8G8B8: 4 bytes; for alpha, red, green, blue.
* @GDK_MEMORY_R8G8B8A8: 4 bytes; for red, green, blue, alpha.
* @GDK_MEMORY_A8B8G8R8: 4 bytes; for alpha, blue, green, red.
* @GDK_MEMORY_B8G8R8X8: 4 bytes; for blue, green, red, unused. Since 4.14
* @GDK_MEMORY_X8R8G8B8: 4 bytes; for unused, red, green, blue. Since 4.14
* @GDK_MEMORY_R8G8B8X8: 4 bytes; for red, green, blue, unused. Since 4.14
* @GDK_MEMORY_X8B8G8R8: 4 bytes; for unused, blue, green, red. Since 4.14
* @GDK_MEMORY_R8G8B8: 3 bytes; for red, green, blue. The data is opaque.
* @GDK_MEMORY_B8G8R8: 3 bytes; for blue, green, red. The data is opaque.
* @GDK_MEMORY_R16G16B16: 3 guint16 values; for red, green, blue. Since: 4.6
* @GDK_MEMORY_R16G16B16A16_PREMULTIPLIED: 4 guint16 values; for red, green,
* blue, alpha. The color values are premultiplied with the alpha value.
* Since: 4.6
* @GDK_MEMORY_R16G16B16A16: 4 guint16 values; for red, green, blue, alpha.
* Since: 4.6
* @GDK_MEMORY_R16G16B16_FLOAT: 3 half-float values; for red, green, blue.
* The data is opaque. Since: 4.6
* @GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED: 4 half-float values; for
* red, green, blue and alpha. The color values are premultiplied with
* the alpha value. Since: 4.6
* @GDK_MEMORY_R16G16B16A16_FLOAT: 4 half-float values; for red, green,
* blue and alpha. Since: 4.6
* @GDK_MEMORY_B32G32R32_FLOAT: 3 float values; for blue, green, red.
* The data is opaque. Since: 4.6
* @GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED: 4 float values; for
* red, green, blue and alpha. The color values are premultiplied with
* the alpha value. Since: 4.6
* @GDK_MEMORY_R32G32B32A32_FLOAT: 4 float values; for red, green, blue and
* alpha. Since: 4.6
* @GDK_MEMORY_G8A8_PREMULTIPLIED: 2 bytes; for grayscale, alpha. The color
* values are premultiplied with the alpha value. Since: 4.12
* @GDK_MEMORY_G8A8: 2 bytes; for grayscale, alpha. Since: 4.12
* @GDK_MEMORY_G8: One byte; for grayscale. The data is opaque.
* Since: 4.12
* @GDK_MEMORY_G16A16_PREMULTIPLIED: 2 guint16 values; for grayscale, alpha.
* The color values are premultiplied with the alpha value. Since: 4.12
* @GDK_MEMORY_G16A16: 2 guint16 values; for grayscale, alpha. Since: 4.12
* @GDK_MEMORY_G16: One guint16 value; for grayscale. The data is opaque.
* Since: 4.12
* @GDK_MEMORY_A8: One byte; for alpha.
* Since: 4.12
* @GDK_MEMORY_A16: One guint16 value; for alpha.
* Since: 4.12
* @GDK_MEMORY_N_FORMATS: The number of formats. This value will change as
* more formats get added, so do not rely on its concrete integer.
* @GDK_MEMORY_R32G32B32_FLOAT: 3 float values; for red, green, blue.
*
* `GdkMemoryFormat` describes formats that image data can have in memory.
*
* It describes formats by listing the contents of the memory passed to it.
* So GDK_MEMORY_A8R8G8B8 will be 1 byte (8 bits) of alpha, followed by a
* So `GDK_MEMORY_A8R8G8B8` will be 1 byte (8 bits) of alpha, followed by a
* byte each of red, green and blue. It is not endian-dependent, so
* CAIRO_FORMAT_ARGB32 is represented by different `GdkMemoryFormats`
* `CAIRO_FORMAT_ARGB32` is represented by different `GdkMemoryFormats`
* on architectures with different endiannesses.
*
* Its naming is modelled after
* [VkFormat](https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#VkFormat)
* for details).
*/
/**
* GDK_MEMORY_A8B8G8R8_PREMULTIPLIED:
*
* 4 bytes; for alpha, blue, green, red, The color values are premultiplied with
* the alpha value.
*
* Since: 4.14
*/
/**
* GDK_MEMORY_B8G8R8X8:
*
* 4 bytes; for blue, green, red, unused.
*
* Since: 4.14
*/
/**
* GDK_MEMORY_X8R8G8B8:
*
* 4 bytes; for unused, red, green, blue.
*
* Since: 4.14
*/
/**
* GDK_MEMORY_R8G8B8X8:
*
* 4 bytes; for red, green, blue, unused.
*
* Since: 4.14
*/
/**
* GDK_MEMORY_X8B8G8R8:
*
* 4 bytes; for unused, blue, green, red.
*
* Since: 4.14
*/
/**
* GDK_MEMORY_R16G16B16:
*
* 3 guint16 values; for red, green, blue.
*
* Since: 4.6
*/
/**
* GDK_MEMORY_R16G16B16A16_PREMULTIPLIED:
*
* 4 guint16 values; for red, green, blue, alpha. The color values are
* premultiplied with the alpha value.
*
* Since: 4.6
*/
/**
* GDK_MEMORY_R16G16B16A16:
*
* 4 guint16 values; for red, green, blue, alpha.
*
* Since: 4.6
*/
/**
* GDK_MEMORY_R16G16B16_FLOAT:
*
* 3 half-float values; for red, green, blue. The data is opaque.
*
* Since: 4.6
*/
/**
* GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED:
*
* 4 half-float values; for red, green, blue and alpha. The color values are
* premultiplied with the alpha value.
*
* Since: 4.6
*/
/**
* GDK_MEMORY_R16G16B16A16_FLOAT:
*
* 4 half-float values; for red, green, blue and alpha.
*
* Since: 4.6
*/
/**
* GDK_MEMORY_B32G32R32_FLOAT:
*
* 3 float values; for blue, green, red. The data is opaque.
*
* Since: 4.6
*/
/**
* GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED:
*
* 4 float values; for red, green, blue and alpha. The color values are
* premultiplied with the alpha value.
*
* Since: 4.6
*/
/**
* GDK_MEMORY_R32G32B32A32_FLOAT:
*
* 4 float values; for red, green, blue and alpha.
*
* Since: 4.6
*/
/**
* GDK_MEMORY_G8A8_PREMULTIPLIED:
*
* 2 bytes; for grayscale, alpha. The color values are premultiplied with the
* alpha value.
*
* Since: 4.12
*/
/**
* GDK_MEMORY_G8A8:
*
* 2 bytes; for grayscale, alpha.
*
* Since: 4.12
*/
/**
* GDK_MEMORY_G8:
*
* One byte; for grayscale. The data is opaque.
*
* Since: 4.12
*/
/**
* GDK_MEMORY_G16A16_PREMULTIPLIED:
*
* 2 guint16 values; for grayscale, alpha. The color values are premultiplied
* with the alpha value.
*
* Since: 4.12
*/
/**
* GDK_MEMORY_G16A16:
*
* 2 guint16 values; for grayscale, alpha.
*
* Since: 4.12
*/
/**
* GDK_MEMORY_G16:
*
* One guint16 value; for grayscale. The data is opaque.
*
* Since: 4.12
*/
/**
* GDK_MEMORY_A8:
*
* One byte; for alpha.
*
* Since: 4.12
*/
/**
* GDK_MEMORY_A16:
*
* One guint16 value; for alpha.
*
* Since: 4.12
*/
/**
* GDK_MEMORY_A16_FLOAT:
*
* One half-float value; for alpha.
*
* Since: 4.12
*/
/**
* GDK_MEMORY_A32_FLOAT:
*
* One float value; for alpha.
*
* Since: 4.12
*/
typedef enum {
GDK_MEMORY_B8G8R8A8_PREMULTIPLIED,
GDK_MEMORY_A8R8G8B8_PREMULTIPLIED,
+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)
{
+4 -4
View File
@@ -266,10 +266,10 @@ _XcursorReadUInt (XcursorFile *file, XcursorUInt *u)
if ((*file->read) (file, bytes, 4) != 4)
return XcursorFalse;
*u = ((bytes[0] << 0) |
(bytes[1] << 8) |
(bytes[2] << 16) |
(bytes[3] << 24));
*u = ((((unsigned int)(bytes[0])) << 0) |
(((unsigned int)(bytes[1])) << 8) |
(((unsigned int)(bytes[2])) << 16) |
(((unsigned int)(bytes[3])) << 24));
return XcursorTrue;
}
+6 -4
View File
@@ -2437,12 +2437,13 @@ apply_monitor_change (GdkWaylandMonitor *monitor)
gboolean needs_scaling = FALSE;
double scale;
if (monitor->xdg_output_done)
if (monitor_has_xdg_output (monitor) &&
monitor->xdg_output_geometry.width != 0 &&
monitor->xdg_output_geometry.height != 0)
{
logical_geometry = monitor->xdg_output_geometry;
needs_scaling =
logical_geometry.width == monitor->output_geometry.width ||
logical_geometry.height == monitor->output_geometry.height;
needs_scaling = logical_geometry.width == monitor->output_geometry.width &&
logical_geometry.height == monitor->output_geometry.height;
}
else
{
@@ -2453,6 +2454,7 @@ apply_monitor_change (GdkWaylandMonitor *monitor)
if (needs_scaling)
{
int scale_factor = gdk_monitor_get_scale_factor (GDK_MONITOR (monitor));
logical_geometry.y /= scale_factor;
logical_geometry.x /= scale_factor;
logical_geometry.width /= scale_factor;
+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;
+8 -1
View File
@@ -1430,6 +1430,8 @@ gdk_x11_display_open (const char *display_name)
int maj, min;
char *cm_name;
gboolean frame_extents;
gboolean rgba;
gboolean composited;
XInitThreads ();
@@ -1646,7 +1648,10 @@ gdk_x11_display_open (const char *display_name)
frame_extents = gdk_x11_screen_supports_net_wm_hint (gdk_x11_display_get_screen (display),
g_intern_static_string ("_GTK_FRAME_EXTENTS"));
gdk_display_set_shadow_width (display, frame_extents);
rgba = gdk_display_is_rgba (display);
composited = gdk_display_is_composited (display);
gdk_display_set_shadow_width (display, frame_extents && rgba && composited);
gdk_display_emit_opened (display);
@@ -3010,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
+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
+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;
}
+118 -54
View File
@@ -36,10 +36,12 @@
#include "gskdebugprivate.h"
#include "gskpath.h"
#include "gskrectprivate.h"
#include "gskvec2private.h"
#include "gskrendernodeprivate.h"
#include "gskroundedrectprivate.h"
#include "gskstrokeprivate.h"
#include "gsktransformprivate.h"
#include "gskprivate.h"
#include "gdk/gdkrgbaprivate.h"
#include "gdk/gdksubsurfaceprivate.h"
@@ -183,20 +185,20 @@ 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;
gsk_gpu_image_get_projection_matrix (target, &self->projection);
graphene_vec2_init (&self->scale,
width / viewport->size.width,
height / viewport->size.height);
gsk_vec2_init (&self->scale,
width / viewport->size.width,
height / viewport->size.height);
self->offset = GRAPHENE_POINT_INIT (-viewport->origin.x,
-viewport->origin.y);
self->opacity = 1.0;
@@ -318,8 +320,8 @@ rect_round_to_pixels (const graphene_rect_t *src,
{
float x, y, xscale, yscale, inv_xscale, inv_yscale;
xscale = graphene_vec2_get_x (pixel_scale);
yscale = graphene_vec2_get_y (pixel_scale);
xscale = gsk_vec2_get_x (pixel_scale);
yscale = gsk_vec2_get_y (pixel_scale);
inv_xscale = 1.0f / xscale;
inv_yscale = 1.0f / yscale;
@@ -344,8 +346,8 @@ gsk_gpu_node_processor_init_draw (GskGpuNodeProcessor *self,
area.x = 0;
area.y = 0;
area.width = ceilf (graphene_vec2_get_x (scale) * viewport->size.width - EPSILON);
area.height = ceilf (graphene_vec2_get_y (scale) * viewport->size.height - EPSILON);
area.width = ceilf (gsk_vec2_get_x (scale) * viewport->size.width - EPSILON);
area.height = ceilf (gsk_vec2_get_y (scale) * viewport->size.height - EPSILON);
image = gsk_gpu_device_create_offscreen_image (gsk_gpu_frame_get_device (frame),
FALSE,
@@ -628,8 +630,8 @@ gsk_gpu_node_processor_rect_is_integer (GskGpuNodeProcessor *self,
cairo_rectangle_int_t *int_rect)
{
graphene_rect_t transformed_rect;
float scale_x = graphene_vec2_get_x (&self->scale);
float scale_y = graphene_vec2_get_y (&self->scale);
float scale_x = gsk_vec2_get_x (&self->scale);
float scale_y = gsk_vec2_get_y (&self->scale);
switch (gsk_transform_get_category (self->modelview))
{
@@ -1029,7 +1031,7 @@ gsk_gpu_node_processor_blur_op (GskGpuNodeProcessor *self,
gsk_gpu_node_processor_sync_globals (&other, 0);
graphene_vec2_init (&direction, blur_radius, 0.0f);
gsk_vec2_init (&direction, blur_radius, 0.0f);
gsk_gpu_blur_op (other.frame,
gsk_gpu_clip_get_shader_clip (&other.clip, &other.offset, &intermediate_rect),
source_desc,
@@ -1043,7 +1045,7 @@ gsk_gpu_node_processor_blur_op (GskGpuNodeProcessor *self,
real_offset = GRAPHENE_POINT_INIT (self->offset.x + shadow_offset->x,
self->offset.y + shadow_offset->y);
graphene_vec2_init (&direction, 0.0f, blur_radius);
gsk_vec2_init (&direction, 0.0f, blur_radius);
intermediate_descriptor = gsk_gpu_node_processor_add_image (self, intermediate, GSK_GPU_SAMPLER_TRANSPARENT);
if (shadow_color)
{
@@ -1327,7 +1329,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;
@@ -1580,8 +1582,8 @@ gsk_gpu_node_processor_add_transform_node (GskGpuNodeProcessor *self,
gsk_gpu_clip_scale (&self->clip, &old_clip, scale_x, scale_y);
self->offset.x = (self->offset.x + dx) / scale_x;
self->offset.y = (self->offset.y + dy) / scale_y;
graphene_vec2_init (&self->scale, fabs (scale_x), fabs (scale_y));
graphene_vec2_multiply (&self->scale, &old_scale, &self->scale);
gsk_vec2_init (&self->scale, fabs (scale_x), fabs (scale_y));
gsk_vec2_multiply (&self->scale, &old_scale, &self->scale);
self->modelview = gsk_transform_scale (self->modelview,
scale_x / fabs (scale_x),
scale_y / fabs (scale_y));
@@ -1610,7 +1612,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))
{
@@ -1641,17 +1643,20 @@ gsk_gpu_node_processor_add_transform_node (GskGpuNodeProcessor *self,
old_modelview = gsk_transform_ref (self->modelview);
self->modelview = gsk_transform_scale (self->modelview,
graphene_vec2_get_x (&self->scale),
graphene_vec2_get_y (&self->scale));
gsk_vec2_get_x (&self->scale),
gsk_vec2_get_y (&self->scale));
self->modelview = gsk_transform_transform (self->modelview, clip_transform);
gsk_transform_unref (clip_transform);
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 (gsk_vec2_get_x (&old_scale) * old_clip.rect.bounds.size.width,
gsk_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;
@@ -1659,7 +1664,7 @@ gsk_gpu_node_processor_add_transform_node (GskGpuNodeProcessor *self,
}
self->modelview = gsk_transform_scale (self->modelview, 1 / scale_x, 1 / scale_y);
graphene_vec2_init (&self->scale, scale_x, scale_y);
gsk_vec2_init (&self->scale, scale_x, scale_y);
self->offset = *graphene_point_zero ();
}
break;
@@ -1731,8 +1736,8 @@ gsk_gpu_node_processor_create_transform_pattern (GskGpuPatternWriter *self,
self->bounds.size.width *= inv_sx;
self->bounds.size.height *= inv_sy;
self->offset = GRAPHENE_POINT_INIT (0, 0);
graphene_vec2_init (&self->scale, fabs (sx), fabs (sy));
graphene_vec2_multiply (&self->scale, &old_scale, &self->scale);
gsk_vec2_init (&self->scale, fabs (sx), fabs (sy));
gsk_vec2_multiply (&self->scale, &old_scale, &self->scale);
}
break;
@@ -1816,8 +1821,8 @@ gsk_gpu_node_processor_add_color_node (GskGpuNodeProcessor *self,
return;
}
scale_x = graphene_vec2_get_x (&self->scale);
scale_y = graphene_vec2_get_y (&self->scale);
scale_x = gsk_vec2_get_x (&self->scale);
scale_y = gsk_vec2_get_y (&self->scale);
clipped = GRAPHENE_RECT_INIT (int_clipped.x / scale_x, int_clipped.y / scale_y,
int_clipped.width / scale_x, int_clipped.height / scale_y);
shader_clip = gsk_gpu_clip_get_shader_clip (&self->clip, graphene_point_zero(), &clipped);
@@ -1944,8 +1949,8 @@ gsk_gpu_node_processor_add_texture_node (GskGpuNodeProcessor *self,
}
if (gsk_gpu_frame_should_optimize (self->frame, GSK_GPU_OPTIMIZE_MIPMAP) &&
(gdk_texture_get_width (texture) > 2 * node->bounds.size.width * graphene_vec2_get_x (&self->scale) ||
gdk_texture_get_height (texture) > 2 * node->bounds.size.height * graphene_vec2_get_y (&self->scale)))
(gdk_texture_get_width (texture) > 2 * node->bounds.size.width * gsk_vec2_get_x (&self->scale) ||
gdk_texture_get_height (texture) > 2 * node->bounds.size.height * gsk_vec2_get_y (&self->scale)))
{
guint32 descriptor;
@@ -2011,8 +2016,8 @@ gsk_gpu_node_processor_create_texture_pattern (GskGpuPatternWriter *self,
}
if (gsk_gpu_frame_should_optimize (self->frame, GSK_GPU_OPTIMIZE_MIPMAP) &&
(gdk_texture_get_width (texture) > 2 * node->bounds.size.width * graphene_vec2_get_x (&self->scale) ||
gdk_texture_get_height (texture) > 2 * node->bounds.size.height * graphene_vec2_get_y (&self->scale)))
(gdk_texture_get_width (texture) > 2 * node->bounds.size.width * gsk_vec2_get_x (&self->scale) ||
gdk_texture_get_height (texture) > 2 * node->bounds.size.height * gsk_vec2_get_y (&self->scale)))
{
image = gsk_gpu_node_processor_ensure_image (self->frame,
image,
@@ -2055,8 +2060,8 @@ gsk_gpu_node_processor_add_texture_scale_node (GskGpuNodeProcessor *self,
guint32 descriptor;
gboolean need_mipmap, need_offscreen;
need_offscreen = self->modelview != NULL ||
!graphene_vec2_equal (&self->scale, graphene_vec2_one ());
need_offscreen = self->modelview != NULL ||
gsk_vec2_equal (&self->scale, graphene_vec2_one ());
if (need_offscreen)
{
GskGpuImage *offscreen;
@@ -2997,6 +3002,7 @@ gsk_gpu_node_processor_add_glyph_node (GskGpuNodeProcessor *self,
float scale, inv_scale;
GdkRGBA color;
gboolean glyph_align;
gboolean hinting;
if (self->opacity < 1.0 &&
gsk_text_node_has_color_glyphs (node))
@@ -3005,9 +3011,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);
@@ -3017,9 +3022,12 @@ gsk_gpu_node_processor_add_glyph_node (GskGpuNodeProcessor *self,
offset.x += self->offset.x;
offset.y += self->offset.y;
scale = MAX (graphene_vec2_get_x (&self->scale), graphene_vec2_get_y (&self->scale));
scale = MAX (gsk_vec2_get_x (&self->scale), gsk_vec2_get_y (&self->scale));
inv_scale = 1.f / scale;
glyph_align = gsk_gpu_frame_should_optimize (self->frame, GSK_GPU_OPTIMIZE_GLYPH_ALIGN);
hinting = gsk_font_get_hint_style (font) != CAIRO_HINT_STYLE_NONE;
for (i = 0; i < num_glyphs; i++)
{
GskGpuImage *image;
@@ -3030,10 +3038,21 @@ gsk_gpu_node_processor_add_glyph_node (GskGpuNodeProcessor *self,
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)
if (hinting && glyph_align)
{
glyph_origin.x = roundf (glyph_origin.x * scale * 4);
glyph_origin.y = roundf (glyph_origin.y * scale * 4);
/* Force glyph_origin.y to be device pixel aligned.
* The hinter expects that.
*/
glyph_origin.x = floor (glyph_origin.x * scale * 4 + .5);
flags = ((int) glyph_origin.x & 3);
glyph_origin.x = 0.25 * inv_scale * glyph_origin.x;
glyph_origin.y = floor (glyph_origin.y * scale + .5) * inv_scale;
}
else if (glyph_align)
{
glyph_origin.x = floor (glyph_origin.x * scale * 4 + .5);
glyph_origin.y = floor (glyph_origin.y * scale * 4 + .5);
flags = ((int) glyph_origin.x & 3) |
(((int) glyph_origin.y & 3) << 2);
glyph_origin.x = 0.25 * inv_scale * glyph_origin.x;
@@ -3041,6 +3060,8 @@ gsk_gpu_node_processor_add_glyph_node (GskGpuNodeProcessor *self,
}
else
{
glyph_origin.x = floor (glyph_origin.x * scale + .5) * inv_scale;
glyph_origin.y = floor (glyph_origin.y * scale + .5) * inv_scale;
flags = 0;
}
@@ -3053,11 +3074,19 @@ 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 (glyphs[i].attr.is_color)
gsk_gpu_texture_op (self->frame,
gsk_gpu_clip_get_shader_clip (&self->clip, &glyph_offset, &glyph_bounds),
@@ -3093,6 +3122,8 @@ gsk_gpu_node_processor_create_glyph_pattern (GskGpuPatternWriter *self,
guint32 tex_id;
GskGpuImage *last_image;
graphene_point_t offset;
gboolean glyph_align;
gboolean hinting;
if (gsk_text_node_has_color_glyphs (node))
return FALSE;
@@ -3105,25 +3136,58 @@ gsk_gpu_node_processor_create_glyph_pattern (GskGpuPatternWriter *self,
offset.x += self->offset.x;
offset.y += self->offset.y;
scale = MAX (graphene_vec2_get_x (&self->scale), graphene_vec2_get_y (&self->scale));
scale = MAX (gsk_vec2_get_x (&self->scale), gsk_vec2_get_y (&self->scale));
inv_scale = 1.f / scale;
gsk_gpu_pattern_writer_append_uint (self, GSK_GPU_PATTERN_GLYPHS);
gsk_gpu_pattern_writer_append_rgba (self, gsk_text_node_get_color (node));
gsk_gpu_pattern_writer_append_uint (self, num_glyphs);
glyph_align = gsk_gpu_frame_should_optimize (self->frame, GSK_GPU_OPTIMIZE_GLYPH_ALIGN);
hinting = gsk_font_get_hint_style (font) != CAIRO_HINT_STYLE_NONE;
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 + (float) glyphs[i].geometry.x_offset / PANGO_SCALE,
offset.y + (float) glyphs[i].geometry.y_offset / PANGO_SCALE);
if (hinting && glyph_align)
{
/* Force glyph_origin.y to be device pixel aligned.
* The hinter expects that.
*/
glyph_origin.x = roundf (glyph_origin.x * scale * 4);
flags = ((int) glyph_origin.x & 3);
glyph_origin.x = 0.25 * inv_scale * glyph_origin.x;
glyph_origin.y = roundf (glyph_origin.y * scale) * inv_scale;
}
else 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
{
glyph_origin.x = roundf (glyph_origin.x * scale) * inv_scale;
glyph_origin.y = roundf (glyph_origin.y * scale) * inv_scale;
flags = 0;
}
image = gsk_gpu_device_lookup_glyph_image (device,
self->frame,
font,
glyphs[i].glyph,
0,
flags,
scale,
&glyph_bounds,
&glyph_offset);
@@ -3136,8 +3200,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 +3211,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,7 +3219,7 @@ 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;
}
+23 -10
View File
@@ -14,6 +14,7 @@
#include "gdk/gdkglcontextprivate.h"
#include "gsk/gskdebugprivate.h"
#include "gskvec2private.h"
static GskGpuOp *
gsk_gpu_upload_op_gl_command_with_area (GskGpuOp *op,
@@ -110,8 +111,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,
@@ -465,8 +466,8 @@ gsk_gpu_upload_cairo_op (GskGpuFrame *frame,
self->image = gsk_gpu_device_create_upload_image (gsk_gpu_frame_get_device (frame),
FALSE,
GDK_MEMORY_DEFAULT,
ceil (graphene_vec2_get_x (scale) * viewport->size.width),
ceil (graphene_vec2_get_y (scale) * viewport->size.height));
ceil (gsk_vec2_get_x (scale) * viewport->size.width),
ceil (gsk_vec2_get_y (scale) * viewport->size.height));
self->viewport = *viewport;
self->func = func;
self->user_data = user_data;
@@ -485,7 +486,6 @@ struct _GskGpuUploadGlyphOp
cairo_rectangle_int_t area;
PangoFont *font;
PangoGlyph glyph;
float scale;
graphene_point_t origin;
GskGpuBuffer *buffer;
@@ -509,11 +509,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 +532,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 +540,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 +554,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 +625,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 +635,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)
{
}
+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;
+43
View File
@@ -0,0 +1,43 @@
#pragma once
#include <graphene.h>
#include <math.h>
static inline float
gsk_vec2_get_x (const graphene_vec2_t *v)
{
return graphene_simd4f_get_x (v->__graphene_private_value);
}
static inline float
gsk_vec2_get_y (const graphene_vec2_t *v)
{
return graphene_simd4f_get_y (v->__graphene_private_value);
}
static inline graphene_vec2_t *
gsk_vec2_init (graphene_vec2_t *v,
float x,
float y)
{
v->__graphene_private_value = graphene_simd4f_init (x, y, 0.f, 0.f);
return v;
}
static inline void
gsk_vec2_multiply (const graphene_vec2_t *a,
const graphene_vec2_t *b,
graphene_vec2_t *res)
{
res->__graphene_private_value = graphene_simd4f_mul (a->__graphene_private_value,
b->__graphene_private_value);
}
static inline bool
gsk_vec2_equal (const graphene_vec2_t *v1,
const graphene_vec2_t *v2)
{
return graphene_simd4f_cmp_eq (v1->__graphene_private_value, v2->__graphene_private_value);
}
+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
+104 -30
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>
@@ -130,9 +130,8 @@ accessible_text_handle_method (GDBusConnection *connection,
if (text != NULL)
{
const char *str = g_bytes_get_data (text, NULL);
if (0 <= offset && offset < g_utf8_strlen (str, -1))
ch = g_utf8_get_char (g_utf8_offset_to_pointer (str, offset));
if (g_utf8_strlen (str, -1) > 0)
ch = g_utf8_get_char (str);
}
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(i)", ch));
@@ -223,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));
@@ -249,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);
@@ -1057,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;
@@ -1610,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,
+3
View File
@@ -291,6 +291,9 @@ gtk_accessible_role_to_atspi_role (GtkAccessibleRole role)
case GTK_ACCESSIBLE_ROLE_TOGGLE_BUTTON:
return ATSPI_ROLE_TOGGLE_BUTTON;
case GTK_ACCESSIBLE_ROLE_TERMINAL:
return ATSPI_ROLE_TERMINAL;
default:
break;
}
+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);
+4 -2
View File
@@ -852,7 +852,8 @@ gtk_tree_path_prepend_index (GtkTreePath *path,
int *indices;
path->alloc = MAX (path->alloc * 2, 1);
indices = g_new (int, path->alloc);
memcpy (indices + 1, path->indices, path->depth * sizeof (int));
if (path->depth > 0)
memcpy (indices + 1, path->indices, path->depth * sizeof (int));
g_free (path->indices);
path->indices = indices;
}
@@ -972,7 +973,8 @@ gtk_tree_path_copy (const GtkTreePath *path)
retval->depth = path->depth;
retval->alloc = retval->depth;
retval->indices = g_new (int, path->alloc);
memcpy (retval->indices, path->indices, path->depth * sizeof (int));
if (path->depth > 0)
memcpy (retval->indices, path->indices, path->depth * sizeof (int));
return retval;
}
BIN
View File
Binary file not shown.
+115 -54
View File
@@ -22,13 +22,20 @@
* language-specific data.raw.json as input
*/
/* The format of the generated data is: a(ausasu).
/* 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
* s - name, e.g. "man worker"
* as - keywords, e.g. "man", "worker"
* 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"
* as - keywords in locale
* u - the group that this item belongs to:
* 0: smileys-emotion
* 1: people-body
@@ -46,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;
@@ -64,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;
}
@@ -77,90 +105,123 @@ main (int argc, char *argv[])
{
JsonParser *parser;
JsonNode *root;
JsonParser *parser_en;
JsonNode *root_en;
JsonObject *ro;
JsonArray *array;
JsonArray *array_en;
JsonNode *node;
const char *unicode;
JsonObjectIter iter;
GError *error = NULL;
guint length, i;
guint length, length_en, i;
GVariantBuilder builder;
GVariant *v;
GString *s;
GHashTable *names;
GString *name_key;
if (argc != 3)
if (argc != 4) //0 -> compiled file, 1 -> en/data.raw.json, 2 -> de/data.raw.json, 3 -> de.data
{
g_print ("Usage: emoji-convert INPUT OUTPUT\n");
g_print ("Usage: emoji-convert INPUT1 INPUT2 OUTPUT\nINPUT1 should be raw json data for English\nINPUT2 should be raw json data for the locale\n");
return 1;
}
parser = json_parser_new ();
parser_en = json_parser_new ();
if (!json_parser_load_from_file (parser, argv[1], &error))
if (!json_parser_load_from_file (parser_en, argv[1], &error))
{
g_error ("%s", error->message);
return 1;
}
if (!json_parser_load_from_file (parser, argv[2], &error))
{
g_error ("%s", error->message);
return 1;
}
root = json_parser_get_root (parser);
array = json_node_get_array (root);
length = json_array_get_length (array);
root_en = json_parser_get_root (parser_en);
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(ausasu)"));
g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(aussasasu)"));
for (i = 0; i < length; i++)
{
JsonObject *obj = json_array_get_object_element (array, i);
GVariantBuilder b1;
GVariantBuilder b2;
guint group;
const char *name;
char *code;
{
JsonObject *obj = json_array_get_object_element (array, i);
JsonObject *obj_en = json_array_get_object_element (array_en, i);
GVariantBuilder b1;
GVariantBuilder b2;
GVariantBuilder b3;
guint group;
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, "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");
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 (json_object_has_member (obj, "skins"))
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");
JsonNode *n2 = json_array_get_element (a2, 0);
JsonObject *o2 = json_node_get_object (n2);
code = g_strdup (json_object_get_string_member (o2, "hexcode"));
}
else
{
code = g_strdup (json_object_get_string_member (obj, "hexcode"));
}
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"));
if (json_object_has_member (obj_en, "tags"))
{
JsonArray *tags_en = json_object_get_array_member (obj_en, "tags");
for (int j = 0; j < json_array_get_length (tags_en); j++)
{
JsonArray *a2 = json_object_get_array_member (obj, "skins");
JsonNode *n2 = json_array_get_element (a2, 0);
JsonObject *o2 = json_node_get_object (n2);
code = g_strdup (json_object_get_string_member (o2, "hexcode"));
g_variant_builder_add (&b2, "s", json_array_get_string_element (tags_en, j));
}
else
}
g_variant_builder_init (&b3, G_VARIANT_TYPE ("as"));
if (json_object_has_member (obj, "tags"))
{
JsonArray *tags = json_object_get_array_member (obj, "tags");
for (int j = 0; j < json_array_get_length (tags); j++)
{
code = g_strdup (json_object_get_string_member (obj, "hexcode"));
g_variant_builder_add (&b3, "s", json_array_get_string_element (tags, j));
}
g_variant_builder_init (&b1, G_VARIANT_TYPE ("au"));
if (!parse_code (&b1, code))
return 1;
g_variant_builder_init (&b2, G_VARIANT_TYPE ("as"));
if (json_object_has_member (obj, "tags"))
{
JsonArray *tags = json_object_get_array_member (obj, "tags");
for (int j = 0; j < json_array_get_length (tags); j++)
g_variant_builder_add (&b2, "s", json_array_get_string_element (tags, j));
}
g_variant_builder_add (&builder, "(ausasu)", &b1, name, &b2, group);
}
}
g_variant_builder_add (&builder, "(aussasasu)", &b1, name_en, name, &b2, &b3, group);
}
v = g_variant_builder_end (&builder);
if (g_str_has_suffix (argv[2], ".json"))
if (g_str_has_suffix (argv[3], ".json"))
{
JsonNode *node;
char *out;
node = json_gvariant_serialize (v);
out = json_to_string (node, TRUE);
if (!g_file_set_contents (argv[2], out, -1, &error))
if (!g_file_set_contents (argv[3], out, -1, &error))
{
g_error ("%s", error->message);
return 1;
@@ -171,7 +232,7 @@ main (int argc, char *argv[])
GBytes *bytes;
bytes = g_variant_get_data_as_bytes (v);
if (!g_file_set_contents (argv[2], g_bytes_get_data (bytes, NULL), g_bytes_get_size (bytes), &error))
if (!g_file_set_contents (argv[3], g_bytes_get_data (bytes, NULL), g_bytes_get_size (bytes), &error))
{
g_error ("%s", error->message);
return 1;
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.
+2
View File
@@ -871,6 +871,7 @@ static const char *role_names[] = {
[GTK_ACCESSIBLE_ROLE_BLOCK_QUOTE] = NC_("accessibility", "block quote"),
[GTK_ACCESSIBLE_ROLE_ARTICLE] = NC_("accessibility", "article"),
[GTK_ACCESSIBLE_ROLE_COMMENT] = NC_("accessibility", "comment"),
[GTK_ACCESSIBLE_ROLE_TERMINAL] = NC_("accessibility", "terminal"),
};
/*< private >
@@ -989,6 +990,7 @@ static struct {
{ GTK_ACCESSIBLE_ROLE_DIALOG, GTK_ACCESSIBLE_ROLE_ALERT_DIALOG },
{ GTK_ACCESSIBLE_ROLE_DOCUMENT, GTK_ACCESSIBLE_ROLE_ARTICLE },
{ GTK_ACCESSIBLE_ROLE_ARTICLE, GTK_ACCESSIBLE_ROLE_COMMENT },
{ GTK_ACCESSIBLE_ROLE_TERMINAL, GTK_ACCESSIBLE_ROLE_WIDGET },
};
gboolean
+170 -3
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 *
@@ -80,12 +90,13 @@ nul_terminate_contents (GBytes *bytes)
gsize size;
data = g_bytes_get_data (bytes, &size);
if (size > 0 && data[size - 1] != '\0')
if (size == 0 || (size > 0 && data[size - 1] != '\0'))
{
guchar *copy;
copy = g_new (guchar, size + 1);
memcpy (copy, data, size);
if (size > 0)
memcpy (copy, data, size);
copy[size] = '\0';
g_bytes_unref (bytes);
@@ -154,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);
}
@@ -259,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
+2 -1
View File
@@ -146,7 +146,8 @@ gtk_application_impl_wayland_inhibit (GtkApplicationImpl *impl,
}
}
inhibitor->dbus_cookie = ((GtkApplicationImplWaylandClass *) G_OBJECT_GET_CLASS (wayland))->dbus_inhibit (impl, window, flags, reason);
if (flags)
inhibitor->dbus_cookie = ((GtkApplicationImplWaylandClass *) G_OBJECT_GET_CLASS (wayland))->dbus_inhibit (impl, window, flags, reason);
return inhibitor->cookie;
}
+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
+2 -2
View File
@@ -517,7 +517,7 @@ gtk_editable_delete_text (GtkEditable *editable,
{
g_return_if_fail (GTK_IS_EDITABLE (editable));
g_return_if_fail (start_pos >= 0);
g_return_if_fail (end_pos == -1 || end_pos > start_pos);
g_return_if_fail (end_pos == -1 || end_pos >= start_pos);
GTK_EDITABLE_GET_IFACE (editable)->do_delete_text (editable, start_pos, end_pos);
}
@@ -552,7 +552,7 @@ gtk_editable_get_chars (GtkEditable *editable,
g_return_val_if_fail (GTK_IS_EDITABLE (editable), NULL);
g_return_val_if_fail (start_pos >= 0, NULL);
g_return_val_if_fail (end_pos == -1 || end_pos > start_pos, NULL);
g_return_val_if_fail (end_pos == -1 || end_pos >= start_pos, NULL);
text = GTK_EDITABLE_GET_IFACE (editable)->get_text (editable);
length = g_utf8_strlen (text, -1);
+26 -18
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);
@@ -321,7 +322,7 @@ populate_recent_section (GtkEmojiChooser *chooser)
GVariantIter iter;
gboolean empty = TRUE;
variant = g_settings_get_value (chooser->settings, "recent-emoji");
variant = g_settings_get_value (chooser->settings, "recently-used-emoji");
g_variant_iter_init (&iter, variant);
while ((item = g_variant_iter_next_value (&iter)))
{
@@ -354,8 +355,8 @@ add_recent_item (GtkEmojiChooser *chooser,
g_variant_ref (item);
g_variant_builder_init (&builder, G_VARIANT_TYPE ("a((ausasu)u)"));
g_variant_builder_add (&builder, "(@(ausasu)u)", item, modifier);
g_variant_builder_init (&builder, G_VARIANT_TYPE ("a((aussasasu)u)"));
g_variant_builder_add (&builder, "(@(aussasasu)u)", item, modifier);
children = NULL;
for (child = gtk_widget_get_last_child (chooser->recent.box);
@@ -380,7 +381,7 @@ add_recent_item (GtkEmojiChooser *chooser,
continue;
}
g_variant_builder_add (&builder, "(@(ausasu)u)", item2, modifier2);
g_variant_builder_add (&builder, "(@(aussasasu)u)", item2, modifier2);
}
g_list_free (children);
@@ -390,7 +391,7 @@ add_recent_item (GtkEmojiChooser *chooser,
gtk_widget_set_visible (chooser->recent.box, TRUE);
gtk_widget_set_sensitive (chooser->recent.button, TRUE);
g_settings_set_value (chooser->settings, "recent-emoji", g_variant_builder_end (&builder));
g_settings_set_value (chooser->settings, "recently-used-emoji", g_variant_builder_end (&builder));
g_variant_unref (item);
}
@@ -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);
@@ -720,7 +720,7 @@ populate_emoji_chooser (gpointer data)
bytes = get_emoji_data ();
chooser->data = g_variant_ref_sink (g_variant_new_from_bytes (G_VARIANT_TYPE ("a(ausasu)"), bytes, TRUE));
chooser->data = g_variant_ref_sink (g_variant_new_from_bytes (G_VARIANT_TYPE ("a(aussasasu)"), bytes, TRUE));
g_bytes_unref (bytes);
}
@@ -734,7 +734,7 @@ populate_emoji_chooser (gpointer data)
{
guint group;
g_variant_get_child (item, 3, "u", &group);
g_variant_get_child (item, 5, "u", &group);
if (group == chooser->people.group)
chooser->box = chooser->people.box;
@@ -866,9 +866,12 @@ filter_func (GtkFlowBoxChild *child,
GtkEmojiChooser *chooser;
GVariant *emoji_data;
const char *text;
const char *name_en;
const char *name;
const char **keywords_en;
const char **keywords;
char **term_tokens;
char **name_tokens_en;
char **name_tokens;
gboolean res;
@@ -885,16 +888,21 @@ filter_func (GtkFlowBoxChild *child,
goto out;
term_tokens = g_str_tokenize_and_fold (text, "en", NULL);
g_variant_get_child (emoji_data, 1, "&s", &name);
name_tokens = g_str_tokenize_and_fold (name, "en", NULL);
g_variant_get_child (emoji_data, 2, "^a&s", &keywords);
g_variant_get_child (emoji_data, 1, "&s", &name_en);
name_tokens = g_str_tokenize_and_fold (name_en, "en", NULL);
g_variant_get_child (emoji_data, 2, "&s", &name);
name_tokens_en = g_str_tokenize_and_fold (name, "en", NULL);
g_variant_get_child (emoji_data, 3, "^a&s", &keywords_en);
g_variant_get_child (emoji_data, 4, "^a&s", &keywords);
res = match_tokens ((const char **)term_tokens, (const char **)name_tokens) ||
match_tokens ((const char **)term_tokens, keywords);
match_tokens ((const char **)term_tokens, (const char **)name_tokens_en) ||
match_tokens ((const char **)term_tokens, keywords) ||
match_tokens ((const char **)term_tokens, keywords_en);
g_strfreev (term_tokens);
g_strfreev (name_tokens);
g_strfreev (name_tokens_en);
out:
if (res)
@@ -978,7 +986,7 @@ setup_section (GtkEmojiChooser *chooser,
section->group = group;
gtk_button_set_icon_name (GTK_BUTTON (section->button), icon);
gtk_flow_box_disable_move_cursor (GTK_FLOW_BOX (section->box));
gtk_flow_box_set_filter_func (GTK_FLOW_BOX (section->box), filter_func, section, NULL);
g_signal_connect_swapped (section->button, "clicked", G_CALLBACK (scroll_to_section), section);
+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;
}
+6 -3
View File
@@ -162,9 +162,12 @@ gtk_entry_buffer_normal_insert_text (GtkEntryBuffer *buffer,
/* Could be a password, so can't leave stuff in memory. */
et_new = g_malloc (pv->normal_text_size);
memcpy (et_new, pv->normal_text, MIN (prev_size, pv->normal_text_size));
trash_area (pv->normal_text, prev_size);
g_free (pv->normal_text);
if (pv->normal_text)
{
memcpy (et_new, pv->normal_text, MIN (prev_size, pv->normal_text_size));
trash_area (pv->normal_text, prev_size);
g_free (pv->normal_text);
}
pv->normal_text = et_new;
}
+14 -3
View File
@@ -1432,6 +1432,13 @@ typedef enum {
* Since: 4.14
*/
/**
* GTK_ACCESSIBLE_ROLE_TERMINAL:
*
* A virtual terminal.
*
* Since: 4.14
*/
typedef enum {
GTK_ACCESSIBLE_ROLE_ALERT,
GTK_ACCESSIBLE_ROLE_ALERT_DIALOG,
@@ -1516,7 +1523,8 @@ typedef enum {
GTK_ACCESSIBLE_ROLE_PARAGRAPH GDK_AVAILABLE_ENUMERATOR_IN_4_14,
GTK_ACCESSIBLE_ROLE_BLOCK_QUOTE GDK_AVAILABLE_ENUMERATOR_IN_4_14,
GTK_ACCESSIBLE_ROLE_ARTICLE GDK_AVAILABLE_ENUMERATOR_IN_4_14,
GTK_ACCESSIBLE_ROLE_COMMENT GDK_AVAILABLE_ENUMERATOR_IN_4_14
GTK_ACCESSIBLE_ROLE_COMMENT GDK_AVAILABLE_ENUMERATOR_IN_4_14,
GTK_ACCESSIBLE_ROLE_TERMINAL GDK_AVAILABLE_ENUMERATOR_IN_4_14
} GtkAccessibleRole;
/**
@@ -1826,13 +1834,16 @@ typedef enum {
/**
* GtkPopoverMenuFlags:
* @GTK_POPOVER_MENU_SLIDING: Submenus are presented as sliding submenus that
* replace the main menu.
* @GTK_POPOVER_MENU_NESTED: Submenus are presented as traditional, nested
* popovers.
*
* Flags that affect how [class@Gtk.PopoverMenu] widgets built from
* a [class@Gio.MenuModel] are created and displayed.
*/
/**
* GTK_POPOVER_MENU_SLIDING:
*
* Submenus are presented as sliding submenus that replace the main menu.
*
* Since: 4.14
*/
+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);
+1
View File
@@ -4013,6 +4013,7 @@ gtk_icon_paintable_new_for_file (GFile *file,
}
icon->is_svg = suffix_from_name (icon->filename) == ICON_CACHE_FLAG_SVG_SUFFIX;
icon->is_symbolic = icon_uri_is_symbolic (icon->filename, -1);
return icon;
}
+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;
}
/* }}} */
+26 -11
View File
@@ -26,37 +26,36 @@
#include "gtklabelprivate.h"
#include "gtkaccessibletextprivate.h"
#include "gtkbuildable.h"
#include "gtkcsscolorvalueprivate.h"
#include "gtkdragsourceprivate.h"
#include "gtkdragicon.h"
#include "gtkeventcontrollermotion.h"
#include "gtkeventcontrollerfocus.h"
#include "gtkfilelauncher.h"
#include "gtkgesturedrag.h"
#include "gtkgestureclick.h"
#include "gtkgesturesingle.h"
#include "gtkjoinedmenuprivate.h"
#include "gtkmarshalers.h"
#include "gtknative.h"
#include "gtknotebook.h"
#include "gtkpangoprivate.h"
#include "gtkpopovermenu.h"
#include "gtkprivate.h"
#include "gtkrenderbackgroundprivate.h"
#include "gtkrenderborderprivate.h"
#include "gtkrenderlayoutprivate.h"
#include "gtkshortcut.h"
#include "gtkshortcutcontroller.h"
#include "gtkshortcuttrigger.h"
#include "gtksnapshot.h"
#include "gtkrenderbackgroundprivate.h"
#include "gtkrenderborderprivate.h"
#include "gtkrenderlayoutprivate.h"
#include "gtktextutilprivate.h"
#include "gtktooltip.h"
#include "gtktypebuiltins.h"
#include "gtkurilauncher.h"
#include "gtkwidgetprivate.h"
#include "gtkpopovermenu.h"
#include "gtknative.h"
#include "gtkdragsourceprivate.h"
#include "gtkdragicon.h"
#include "gtkcsscolorvalueprivate.h"
#include "gtkjoinedmenuprivate.h"
#include "gtkaccessibletext-private.h"
#include "gtkpangoprivate.h"
#include <math.h>
#include <stdlib.h>
@@ -1524,6 +1523,7 @@ gtk_label_dispose (GObject *object)
GtkLabel *self = GTK_LABEL (object);
gtk_label_set_mnemonic_widget (self, NULL);
gtk_label_clear_select_info (self);
G_OBJECT_CLASS (gtk_label_parent_class)->dispose (object);
}
@@ -6134,6 +6134,20 @@ gtk_label_accessible_text_get_selection (GtkAccessibleText *self,
return TRUE;
}
static void
gtk_label_accessible_text_get_default_attributes (GtkAccessibleText *self,
char ***attribute_names,
char ***attribute_values)
{
PangoLayout *layout = gtk_label_get_layout (GTK_LABEL (self));
char **names, **values;
gtk_pango_get_default_attributes (layout, &names, &values);
*attribute_names = names;
*attribute_values = values;
}
static gboolean
gtk_label_accessible_text_get_attributes (GtkAccessibleText *self,
unsigned int offset,
@@ -6173,6 +6187,7 @@ gtk_label_accessible_text_init (GtkAccessibleTextInterface *iface)
iface->get_caret_position = gtk_label_accessible_text_get_caret_position;
iface->get_selection = gtk_label_accessible_text_get_selection;
iface->get_attributes = gtk_label_accessible_text_get_attributes;
iface->get_default_attributes = gtk_label_accessible_text_get_default_attributes;
}
/* }}} */
+8
View File
@@ -886,6 +886,14 @@ gesture_drag_begin_cb (GtkGestureDrag *gesture,
GdkDevice *device;
gboolean is_touch;
/* Only drag the handle when it's visible */
if (!gtk_widget_get_child_visible (paned->handle_widget))
{
gtk_gesture_set_state (GTK_GESTURE (gesture),
GTK_EVENT_SEQUENCE_DENIED);
return;
}
sequence = gtk_gesture_single_get_current_sequence (GTK_GESTURE_SINGLE (gesture));
event = gtk_gesture_get_last_event (GTK_GESTURE (gesture), sequence);
device = gdk_event_get_device (event);

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