Compare commits

...

978 Commits

Author SHA1 Message Date
Matthias Clasen
303dcc667b gtk-demo: Add a few path benchmarks
The Tiger and Graph examples in the fishbowl test
path handling.
2022-04-08 16:44:29 -04:00
Matthias Clasen
a73b6b4392 Add gsk_stroke_node_get_stroke_path
We will implement stroking by filling the stroke path.
2022-04-08 16:44:29 -04:00
Matthias Clasen
a88dbb820b Add GskRoundedRectContour
The main advantage here is that we can avoid
going through the stroker for the common case
of rounded rectangles.
2022-04-08 16:44:29 -04:00
Matthias Clasen
b61058cd22 Add a demo for path ops 2022-04-08 16:44:29 -04:00
Matthias Clasen
8b1d7fd622 Add some tests for pathops 2022-04-08 16:44:29 -04:00
Matthias Clasen
4e24f88482 path: Implement path ops
Implement boolean operations on paths.
2022-04-08 16:44:29 -04:00
Matthias Clasen
98c40daa5f path: Add gsk_path_transform
This is an obvious operation to want for paths.
2022-04-08 16:44:29 -04:00
Matthias Clasen
def04f5df3 path: Add gsk_path_is_convex
Add a function to compute whether a path is convex.
2022-04-08 16:44:29 -04:00
Matthias Clasen
9709f20c53 path: Add gsk_path_get_flags
The flags contain some useful information.
2022-04-08 16:44:29 -04:00
Matthias Clasen
3661086dcc path: Add gsk_path_reverse
This is a natural operation, and useful for debugging things.
2022-04-08 16:44:29 -04:00
Matthias Clasen
d71183bbfe curve: Limit recursion depth 2022-04-08 16:44:29 -04:00
Matthias Clasen
2430c55228 gtk-demo: Use gsk_path_builder_add_layout
We have an api now to hide the cairo use.
2022-04-08 16:44:29 -04:00
Matthias Clasen
a8aa460330 pathbuilder: Add gsk_path_builder_add_layout
This api makes it easy to turn text into a path that
can be further manipulated.

The implementation currently goes via cairo.
2022-04-08 16:44:29 -04:00
Matthias Clasen
b148c792ca Add an interactive path test
This one is for interactive exploring of svg paths.

You can enter an SVG path in the entry and hit Enter
to see how GSK renders it. If you click the button
in the headerbar, you can see what GTK thinks the
closest point, tangent and distance are wrt. to the
mouse position, and the bounding box of the path.

There's also stroke parameters to play with.
2022-04-08 16:44:29 -04:00
Matthias Clasen
cc3b47cef6 pathmeasure: Add gsk_path_measure_get_curvature 2022-04-08 16:44:29 -04:00
Matthias Clasen
386a58f0f4 stroke: Make gsk_stroke_to_cairo public
It comes in handy, and does no harm.
2022-04-08 16:44:29 -04:00
Matthias Clasen
10cd4fc48c gtk-demo: Add a curve editor demo 2022-04-08 16:44:29 -04:00
Matthias Clasen
0debc3d891 path: Implement offsetting
Implement offsetting of paths by reusing the
infrastructure of the stroker.
2022-04-08 16:44:29 -04:00
Matthias Clasen
f166ec5bc9 path: Add gsk_path_offset
Add a function that takes a path, and offsets it
by some distance, applying line-join parameters
as needed.

This commit just adds the api, the implementation
will be in the following commit.
2022-04-08 16:44:29 -04:00
Matthias Clasen
95c3a34cfb stroker: Implement arcs
Implement arced joins as specified in SVG2.
2022-04-08 16:44:29 -04:00
Matthias Clasen
3720429958 Add GSK_LINE_JOIN_ARCS
Implementation will follow.
2022-04-08 16:44:29 -04:00
Matthias Clasen
57904fcd6a Add another stroker test
Check that the outlines of random paths look as
expected. We currently have to exclude paths where
points get too close to each other.
2022-04-08 16:44:29 -04:00
Matthias Clasen
9620b5eb38 Add basic tests for strokes
Add tests to check that any point on a path is
always at most half the line-width away from the
stroke path with that line-width.
2022-04-08 16:44:29 -04:00
Matthias Clasen
9bb552d23c path: Implement stroking
Implement gsk_contour_default_add_stroke, which takes a contour
and stroke parameters, and adds contours to a path builder for
the outline that would be produced by stroking the path with these
parameters.

The current implementation does not try to handle short segments
in the vicinity of sharp joins in any special way, so there can
be some artifacts in that situation.
2022-04-08 16:44:29 -04:00
Matthias Clasen
188f78478c curve: Add some curve utilities
These apis will be used in the stroker.
2022-04-08 16:44:29 -04:00
Matthias Clasen
2b8fe62b55 contour: Special-case circles for strokes
The outline of a circle is just two circles.
2022-04-08 16:44:29 -04:00
Matthias Clasen
31fe02e449 contour: Special-case rects for strokes
In many cases, the outline of a rectangle is just
two rectangles.
2022-04-08 16:44:29 -04:00
Matthias Clasen
068838eac4 path: Add gsk_path_stroke
Add the plumbing that will let us do special-case stroking
for rectangles, circles and other special contours.

There is no implementation yet.
2022-04-08 16:44:29 -04:00
Matthias Clasen
81dae3e15f curve: Add gsk_curve_print
Useful for debugging.
2022-04-08 16:44:28 -04:00
Matthias Clasen
e9a010eb67 curve: Add gsk_curve_get_curvature
This will be used in the stroker.
2022-04-08 16:44:28 -04:00
Matthias Clasen
282be569f6 curve: Add gsk_curve_get_normal
Its easy but thats no reason not to have this api.
2022-04-08 16:44:28 -04:00
Matthias Clasen
f2069508cf Add a test for gsk_curve_offset
The stroker relies on offsetting.
This only tests a few very simple cases.
2022-04-08 16:44:28 -04:00
Matthias Clasen
56f587a5a3 Add a test for gsk_curve_reverse
The stroker relies on this working.
2022-04-08 16:44:28 -04:00
Matthias Clasen
64807abc59 Add a test for tangents of degenerate curves
The stroker relies on these to work.
2022-04-08 16:44:28 -04:00
Matthias Clasen
2cace6bada curve: Handle degenerate cases
Nothing prevents control points from being identical,
and if that happens, some of our constructions involving
tangents and normals break down. Handle these cases in
get_{start,end}_tangent and offset, for the case of
cubics.
2022-04-08 16:44:28 -04:00
Matthias Clasen
b1363aadeb curve: Add gsk_curve_reverse
This will be used in stroking.
2022-04-08 16:44:28 -04:00
Matthias Clasen
e44be94835 curve: Add gsk_curve_offset
This method creates an offset curve from an existing
curve by just moving the control points laterally.

This will be used in stroking.
2022-04-08 16:44:28 -04:00
Matthias Clasen
ffc663b5c5 Add conic decomposition tests
We don't have good error bounds here, unfortunately.
2022-04-08 16:44:28 -04:00
Matthias Clasen
fcf43c4012 path: support conic->curve in foreach 2022-04-08 16:44:28 -04:00
Matthias Clasen
a9c36f8ba9 curve: Add gsk_curve_decompose_curve
This is mainly useful for decomposing a conic into
cubics. The criterion here for terminating the
subdivision is very improvised.
2022-04-08 16:44:28 -04:00
Matthias Clasen
72835f321f Add a performance test for curve eval
All curve types are equally fast here.
2022-04-08 16:44:28 -04:00
Matthias Clasen
8069495f76 Add a performance test for curve intersection
This shows how much more expensive curve
intersections are.
2022-04-08 16:44:28 -04:00
Matthias Clasen
6a51dfc929 Add curve split tests 2022-04-08 16:44:28 -04:00
Matthias Clasen
1fba399296 testsuite: Add special-case curve tests 2022-04-08 16:44:28 -04:00
Matthias Clasen
4d6c2108ac Add curve intersection tests
These tests check that gsk_curve_intersect finds
the intersections we want.
2022-04-08 16:44:28 -04:00
Matthias Clasen
ac5c742df6 curve: Add gsk_curve_intersect
Add a way to find the intersections of two curves.
This will be used in stroking.
2022-04-08 16:44:28 -04:00
Matthias Clasen
ee799830ef curve: Add gsk_curve_get_bounds
Add getters for bounding boxes of curves.
2022-04-08 16:44:28 -04:00
Matthias Clasen
7e9c94e599 Add a bounding box type
graphene_rect_t does not quite work for this purpose.
2022-04-08 16:44:28 -04:00
Matthias Clasen
9e2c689745 Only test conic weights between 1/20 and 20
The rest just give us no end of numeric trouble.
2022-04-08 16:44:28 -04:00
Benjamin Otte
94f93dbd2d path: Add gsk_path_builder_add_ellipse() 2022-04-08 16:44:28 -04:00
Benjamin Otte
846ae95818 path: Change semantics of gtk_path_builder_add_segment()
Allow start >= end to mean that the path continues at the beginning
after reaching the end until it reaches the point at @end.
2022-04-08 16:44:28 -04:00
Benjamin Otte
c28fd1dbe6 pathmeasure: Add gsk_path_measure_is_closed () 2022-04-08 16:44:28 -04:00
Benjamin Otte
6021b76a6b pathmeasure: Add gsk_path_measure_restrict_to_contour() 2022-04-08 16:44:28 -04:00
Matthias Clasen
15541842e4 pathmeasure: Add gsk_path_measure_get_{path,tolerance}
These are just nice apis to have and avoid having to carry
these around as extra arguments in many places.

This was showing up as inconvenience in writing tests
for the measure apis.
2022-04-08 16:44:28 -04:00
Benjamin Otte
1dbfff9f2b gtk-demo: Use dashes in path-fill demo 2022-04-08 16:44:28 -04:00
Matthias Clasen
2418d67e23 gsk: Use stroke bounds in the stroke node
We can use gsk_path_get_stroke_bounds to get a
better estimate for the bounds of the stroke node.
2022-04-08 16:44:28 -04:00
Matthias Clasen
91193e807f path: Add gsk_path_get_stroke_bounds
A relatively cheap way to get bounds for the area
that would be affected by stroking a path.
2022-04-08 16:44:28 -04:00
Benjamin Otte
d537df1f62 testsuite: Add tests for the dasher 2022-04-08 16:44:28 -04:00
Benjamin Otte
4a596fe5bf path: Add a foreach function that dashes a path 2022-04-08 16:44:28 -04:00
Benjamin Otte
27e7b97d28 path: Deal with non-uniformness of progress parameter
The progress is non-uniform, so simple translation of progress doesn't work.
So check if larger and smaller values inch closer towards minimal distance.
2022-04-08 16:44:28 -04:00
Benjamin Otte
95a34803cb path: Always decompose conics into at least 2 segments
Conics are evil in that their parameter skews towards the center, and if
it's a very flat conic (weight almost equal to 0), then we'd approximate
it with a single segment and not subdivide, which would cause the
parameter to be wildly off around 0.25 or 0.75.

And that would cause offset calculations to fail.
2022-04-08 16:44:28 -04:00
Matthias Clasen
c3571c104d testsuite Add curve tangent tests 2022-04-08 16:44:28 -04:00
Benjamin Otte
451a629de1 testsuite: Add a test for the conic that got us segment() 2022-04-08 16:44:28 -04:00
Benjamin Otte
c0e332f677 path: Add gsk_curve_segment()
Using split() twice with scaled t values does not work with conics.
2022-04-08 16:44:28 -04:00
Benjamin Otte
66edb0b5cd testsuite: Add a test for gsk_curve_decompose() 2022-04-08 16:44:28 -04:00
Benjamin Otte
a430099e35 testuite: Add tests for gsk_curve_get_tangent() 2022-04-08 16:44:28 -04:00
Matthias Clasen
26aef58709 testuite: Add tests for gsk_curve_get_point()
Add a few tests for gsk_curve_get_point().

Since GskCurve is not public api, we add gskcurve.c
as source to the test binary.
2022-04-08 16:44:28 -04:00
Benjamin Otte
d15f558769 curve: Split eval() into get_point() and get_tangent()
That's more in line with the get_start/end_point/tangent() functions.

Plus, those calls are independent and we usually want one or the other.
2022-04-08 16:44:28 -04:00
Matthias Clasen
0c2f43d1bd curve: Add gsk_curve_get_{start,end}_tangent
Add a way to get the tangents at the start and end of the curve.
This will be used in stroking.
2022-04-08 16:44:28 -04:00
Benjamin Otte
77d6bc9158 testsuite: Add conics to the random paths 2022-04-08 16:44:28 -04:00
Benjamin Otte
ef120ef1a0 path: Add GskCurve
GskCurve is an abstraction for path operations. It's essentially a
collection of vfuncs per GskPathOperation.

GskStandardContour has been ported to use it where appropriate.
2022-04-08 16:44:28 -04:00
Benjamin Otte
dcf0ba6920 path: Introduce gskpathop
A gskpathop is a pointer to a graphene_point_t* with the low bits used
to encode the GskPathOperation. It's an easy way to introduce API for
operations.

So far it's just used to replace GskStandardOperation.
2022-04-08 08:06:02 -04:00
Benjamin Otte
159fb16494 css: Replace border rendering code with GskPath 2022-04-08 08:06:02 -04:00
Benjamin Otte
7965c420bc pathbuilder: Add gsk_path_builder_add_rounded_rect()
It works, but does not use a custom contour yet.
2022-04-08 08:06:02 -04:00
Benjamin Otte
7b83101ed7 path: Add conic curves
So far this just adds the API, if you use it, you'll get lots of
g_warnings().

This will be fixed in future commits.
2022-04-08 08:06:02 -04:00
Benjamin Otte
dd2036ea01 path: Rename to gtk_path_builder_add_segment()
It's about bulding paths, not about measuring them.
2022-04-08 08:06:02 -04:00
Matthias Clasen
c66d61a55c path: Split contours into their own file
I'm not sure I want to keep all contours in one file,
but for now that's how it is.
2022-04-08 08:06:02 -04:00
Benjamin Otte
e2b5e83812 path: Make all private contour APIs take a GskContour
... instead of a path, index tuple.
2022-04-08 08:06:02 -04:00
Matthias Clasen
d773a36623 Add a nodeparser tests for fill and stroke nodes 2022-04-08 08:06:02 -04:00
Benjamin Otte
a4374f41db stroke: Add support for dashes
... and hook it up in the node parser and for Cairo rendering.
2022-04-08 08:06:02 -04:00
Matthias Clasen
822cfb022f gsk: Implement parsing fill and stroke nodes
Make serialization and deserialization work for stroke and
fill nodes.
2022-04-08 08:06:02 -04:00
Benjamin Otte
95c823a377 path: Add flags to gsk_path_foreach()
This way we can default to the siplest possible foreach() output - like
cairo_copy_path_flat() decomposing everything into lines - and add flags
to get more and more fancy.

This will be useful to have conics automatically decomposed for Cairo
drawing or if we want to add more line types in the future.
2022-04-08 08:06:02 -04:00
Benjamin Otte
6949cfa14b testsuite: Add tests for in_fill()
Add a test for measure_in_fill. Also test some
special cases involving horizontal edges.
2022-04-08 08:06:02 -04:00
Matthias Clasen
ccd1d6a0be pathmeasure: Implement gsk_path_measure_in_fill
Implement this in the obvious way, using the decomposed form
of standard contours. Since the decomposed form is part of the
measure object, this api moves from gsk_path_in_fill to
gsk_path_measure_in_fill.
2022-04-08 08:06:02 -04:00
Benjamin Otte
45c0851577 testsuite: Add a parsing test
This test includes an implementation of a gsk_path_equal() func with
a tolerance that is necessary because parsing does not always work
100% exactly due to floating point rounding, so we can't just
compare the to_string() output.
2022-04-08 08:06:02 -04:00
Matthias Clasen
37c1461a60 path: Special-case rects and circles
Write out the commands for rects and circles in a special
way, and add code in the parser to recognize this, so we
can successfully round-trip these through the SVG path format.

The special way - for people who want to use it for debugging -
for now is that we use uppercase "Z" to close standard paths, but
lowercase "z" to close our special paths.

A test is included, but the random path serializations should take care
of it, too.
2022-04-08 08:06:02 -04:00
Matthias Clasen
84162d8550 path: Fix serialization for circles
The svg A can not do a full circle, since it is a two point
parametrization - if the start and end point are the same,
it draws nothing. So, use two arcs.
2022-04-08 08:06:02 -04:00
Benjamin Otte
3f77813ce2 testsuite: Add librsvg path tests 2022-04-08 08:06:02 -04:00
Matthias Clasen
b539e21528 path: Implement gsk_path_parse
Implement the SVG path syntax to read back the strings
that we generate when serializing paths. The tests for
this code are taken from librsvg.

This includes an elliptical arc implementation according
to the SVG spec. The code is mostly taken from librsvg,
but pretty directly follows the SVG spec implementation
notes. We don't export this, since the parametrization
is inconvenient. We do want an arc_to API, but
these are not the arcs we are looking for.
2022-04-08 08:06:02 -04:00
Matthias Clasen
00f0225712 path: Implement SVG arcs
This is elliptical arc implementation according to the SVG spec.
The code is mostly taken from librsvg, but pretty directly
follows the SVG spec implementation notes.

We don't export this, since the parametrization is inconvenient.
We do want an arc_to API, but these are not the arcs we are
looking for.

It will be used in parsing SVG path syntax.
2022-04-08 08:06:02 -04:00
Matthias Clasen
7aad5998c6 stroke: Add miter limit
Add a miter limit to GskStroke. This will be needed to
fully implement line joins.

Also introduce the GSK_LINE_JOIN_MITER_CLIP value,
following SVG 2.0. cairo does not have it, so translate
it to plain miter when using cairo.
2022-04-08 08:06:02 -04:00
Benjamin Otte
a5fa6fded0 testsuite: Add relative path functions
They're making the paths slightly weirder, but they test public API, so
woohoo!
2022-04-08 08:06:02 -04:00
Benjamin Otte
845102fc22 pathbuilder: Add relative path commands
And gsk_path_builder_get_current_point().

They will be needed by the string parser.
2022-04-08 08:06:02 -04:00
Benjamin Otte
d570e96a15 path: Add GSK_CIRCLE_POINT_INIT() to initialize points on the circle
This is just splitting out a commonly done operation into a macro.
2022-04-08 08:06:02 -04:00
Benjamin Otte
924f036667 pathbuilder: Redo semantics for starting curves
We now always have a "current point" which is either the last point an
operation was made to, or (0, 0) if no drawing operation has
been made yet.

Adding a contour of any kind to the builder will always update the
current point to that contour's end point.
2022-04-08 08:06:02 -04:00
Benjamin Otte
e8750af295 gtk-demo: Show closest point in text-on-path demo 2022-04-08 08:06:02 -04:00
Benjamin Otte
4bcc4529da path: Split GskPathBuilder into its own file
... and add missing API docs.
2022-04-08 08:06:02 -04:00
Benjamin Otte
25582c8b32 testsuite: Add a test using get_point() and get_closest_point() 2022-04-08 08:06:02 -04:00
Benjamin Otte
8007e378c3 testsuite: Add a test for get_point() 2022-04-08 08:06:02 -04:00
Benjamin Otte
3dac5d2217 testsuite: Update create_random_path()
1. Allow specifying the max number of contours
2. Be smarter about creating the paths:
   With 10% chance, create a "weird" path like the empty one or only
   points or things like that.
   Otherwise create a bunch of contours, with 2/3 a standard contour,
   with 1/3 a predetermined one.
2022-04-08 08:06:02 -04:00
Benjamin Otte
bcd90a884c gtk-demo: Add cute maze demo 2022-04-08 08:06:02 -04:00
Benjamin Otte
d77f8c6ab9 testsuite: Add tests for gsk_path_measure_get_closest_point() 2022-04-08 08:06:02 -04:00
Benjamin Otte
3b8cbd10f8 pathmeasure: Add gsk_path_measure_get_closest_point()
... and gsk_path_measure_get_closest_point_full().

Those 2 functions allow finding the closest point
on a path to a given point.
2022-04-08 08:06:02 -04:00
Benjamin Otte
d5f378bd0a spline: Use Skia's tolerance checks
This avoids measuring being too far off (it's still off, but it's less
than a percent now.
2022-04-08 08:06:02 -04:00
Benjamin Otte
895205894e testsuite: Add tests for gsk_path_measure_add_segment() 2022-04-08 08:06:02 -04:00
Benjamin Otte
f23af85cb2 gtk-demo: Add a text-on-path demo 2022-04-08 08:06:02 -04:00
Benjamin Otte
cdb528e566 gtk-demo: Add a path-fill demo 2022-04-07 22:37:56 -04:00
Benjamin Otte
7465f57a57 pathmeasure: Add gsk_path_measure_get_point()
Allows querying the coordinates and direction
of any specific point on a path.
2022-04-07 22:37:56 -04:00
Matthias Clasen
d9b3589164 path: Add gsk_path_add_circle()
Adds a circle contour, too.
2022-04-07 22:37:56 -04:00
Benjamin Otte
f1d8b96fd3 pathmeasure: Implement support for beziers
Instead of treating bezier curves as lines, we properly decompose them
into line segments now so that we can treat those as lines.
2022-04-07 22:37:56 -04:00
Benjamin Otte
19111abcdd path: Implement gsk_path_to_cairo() using foreach() 2022-04-07 22:37:56 -04:00
Benjamin Otte
32fb2667ff path: Add gsk_path_foreach() 2022-04-07 22:37:56 -04:00
Benjamin Otte
e69a774da9 path: Collect flags
We don't need them yet, but maybe later.
2022-04-07 22:37:56 -04:00
Benjamin Otte
adb0877a6b testsuite: Add path tests 2022-04-07 22:37:56 -04:00
Benjamin Otte
ffb2744408 pathmeasure: Add gsk_path_measure_add_segment()
This allows chunking paths, weeee.
2022-04-07 22:37:56 -04:00
Benjamin Otte
8e073912e4 path: Add gsk_path_builder_add_path() 2022-04-07 22:37:56 -04:00
Benjamin Otte
be3e7bbeb0 gsk: Add GskPathMeasure
An object to do measuring operations on paths - determining their
length, cutting off subpaths, things like that.
2022-04-07 22:37:56 -04:00
Benjamin Otte
9dfac7204f path: Change data structure for standard path
Instead of the Cairo method and imitating cairo_path_data_t, use the
Skia method and keep points and operations separate.

That way we get a points array that includes the starting point -
because it's always the end point of the previous operation.
2022-04-07 22:37:56 -04:00
Benjamin Otte
93798a0877 popover: Use fill and stroke nodes instead of Cairo
... to render the arrow.

The arrow should really be turned into a real thing - maybe an icon?
2022-04-07 22:37:56 -04:00
Benjamin Otte
a0676cff0e snapshot: Add gtk_snapshot_push_stroke() 2022-04-07 22:37:56 -04:00
Benjamin Otte
e501c81621 gsk: Add GskStrokeNode 2022-04-07 22:37:56 -04:00
Benjamin Otte
b349519629 gsk: Add GskStroke
It's unused in this commit. This just prepares the new object.
2022-04-07 22:37:56 -04:00
Benjamin Otte
93d8b46a64 demos: Add a simple demo filling a path 2022-04-07 22:37:56 -04:00
Benjamin Otte
92d5dcb37e snapshot: Add gtk_snapshot_push_fill() 2022-04-07 22:37:56 -04:00
Benjamin Otte
5b16d333a6 gsk: Add GskFillNode
Take a rendernode as source and a GskPath and fill the region in the
path just like cairo_fill() would.
2022-04-07 22:37:56 -04:00
Benjamin Otte
b3424bad52 gsk: Add GskPath 2022-04-07 22:37:56 -04:00
Matthias Clasen
fb7f87618a Add a debug key for paths
Not used yet.
2022-04-07 22:37:56 -04:00
Matthias Clasen
8c548d5579 Merge branch 'nonoverlapping-containers' into 'main'
gsk/gl: Avoid offscreening in more cases

See merge request GNOME/gtk!4619
2022-04-07 14:32:53 +00:00
Matthias Clasen
09d5ec1b08 Merge branch 'n-docs-fixes' into 'main'
More doc fixes

See merge request GNOME/gtk!4618
2022-04-07 14:05:40 +00:00
Matthias Clasen
28bba484da Merge branch 'matthiasc/for-main' into 'main'
gl: Don't leak big glyphs

See merge request GNOME/gtk!4626
2022-04-07 11:46:11 +00:00
Matthias Clasen
191558cfa4 gtk-demo: Small fixup to the cursors demo 2022-04-07 07:01:29 -04:00
Matthias Clasen
af6bec7539 Merge branch 'push-history-position-fix' into 'main'
gdk: always populate GDK_AXIS_{X,Y} in merged event history

Closes #4809

See merge request GNOME/gtk!4623
2022-04-06 15:56:26 +00:00
Matthias Clasen
38362c2803 Merge branch 'wip/carlosg/osk-activation' into 'main'
imwayland: Connect OSK activating gesture to parent widget on editables

Closes #4795

See merge request GNOME/gtk!4624
2022-04-06 15:44:43 +00:00
Carlos Garnacho
eb7c78aa48 imwayland: Do not defer commit() after set_surrounding_text()
For reasons that only apply to the old serial handling, asking for
the surrounding after IM changes resulted in lazy handling of
commit() afterwards.

With the recent interpretation of serials, this problem became more
apparent, since it is in fact very likely that the last interaction
step after an IM change is notifying of the changed surrounding
text after the IM change was applied.

Make handling of surrounding text similar to caret position changes,
always commit() after the state change, but skip through non-changes.

This makes the compositor state fully up-to-date after an IM change.
2022-04-06 13:52:05 +02:00
Carlos Garnacho
7ab39b5461 imwayland: Connect OSK activating gesture to parent widget on editables
The gesture as connected currently on the child GtkText is easily overridden
by the parent editables (and gently done so in the attempt to consume all
clicks).

Connect this gesture to the parent editable widget in these cases, so the
gesture can cohabit with the click-consuming one. It's not part of the same
group, but it won't be abruptly cancelled.

Fixes: https://gitlab.gnome.org/GNOME/gtk/-/issues/4795
2022-04-06 13:52:05 +02:00
Hemidark
0c44851848 gdk: always populate GDK_AXIS_{X,Y} in merged event history
Since GdkTimeCoord stores only axis values, prior to this change,
if a device didn't report GDK_AXIS_X or GDK_AXIS_Y, the history
attached to merged motion events wouldn't contain any positional
information.

Commit 6012276093 already addressed
this issue for devices without tools by storing the event position
in GdkTimeCoord using GDK_AXIS_X and GDK_AXIS_Y and augmenting the
GdkTimeCoord's axis bitmask accordingly.

This change generalizes that workaround to all devices. Note that
if a device DOES report values for GDK_AXIS_X and GDK_AXIS_Y, those
values won't be overwritten.

Closes #4809
2022-04-05 15:35:12 -07:00
Matthias Clasen
d72ed045df gsk/gl: Use pre-collected opacity information
We now collect this information during node
construction, so use it here.

The concrete change here is that we now avoid
offscreens for container nodes with multiple children,
as long as they don't overlap. In particular, this
avoid offscreens for ellipsized dim labels.
2022-04-05 14:57:38 -04:00
Matthias Clasen
38eb182947 gsk: Collect opacity information
Collect information about whether to use offscreens
for opacity during node construction, so we don't
need to walk the tree repeatedly, later.
2022-04-05 14:57:38 -04:00
Matthias Clasen
0eba21b2b5 gsk: Track disjointness of container nodes
This can be used to optimize some things in the
GL renderer.
2022-04-05 14:57:38 -04:00
Matthias Clasen
21cba193ad Merge branch 'blurry-offscreen' into 'main'
gsk/gl: Always align offscreen rendering with the pixel grid

Closes #3833

See merge request GNOME/gtk!4621
2022-04-05 12:25:59 +00:00
Matthias Clasen
ee7c83e15a Merge branch 'matthiasc/for-main' into 'main'
gl: Don't leak big glyphs

See merge request GNOME/gtk!4622
2022-04-05 03:15:53 +00:00
Matthias Clasen
48dbbbc099 gl: Don't leak big glyphs
We were never resetting the accessed bit of
glyphs that are big enough to be stored individually,
so these would just accumulate and never be dropped.
2022-04-04 23:00:45 -04:00
Sebastian Keller
1c733857b3 testsuite: Add unaligned-offscreen test
Tests whether text rendered to an offscreen node unaligned with the
pixel grid introduces blurriness.
2022-04-04 23:48:58 +02:00
Sebastian Keller
85a6517d65 gsk/gl: Always align offscreen rendering with the pixel grid
This fixes two issues with the offscreen rendering code for nodes with
bounds not aligned with the pixel grid:

1.) When drawing to an offscreen buffer the size of the offscreen buffer
was rounded up, but then later when used as texture the vertices
correspond to the original bounds with the unrounded size. This could
then result in the offscreen texture being drawn onscreen at a slightly
smaller size, which then lead to it being visually shifted and blurry.

This is fixed by adjusting the u/v coordinates to ignore the padding
region in the offscreen texture that got added by the size increase from
rounding.

2.) The viewport used when rendering to the offscreen buffer was not
aligned with the pixel grid for nodes at coordinates not aligned with
the pixel grid. Then because the content of the offscreen buffer is not
aligned with the pixel grid and later when used as textures sampling
from it will result in interpolated values for an onscreen pixel. This
could also result in shifting and blurriness, especially for nested
offscreen rendering at different offsets.

This is fixed by adding similar padding at the beginning of the
texture and also adjusting the u/v coordinates to ignore this region.

Fixes: https://gitlab.gnome.org/GNOME/gtk/-/issues/3833
2022-04-04 21:40:01 +02:00
Christian Hergert
d75147db0a Merge branch 'sumibi-yakitori/fix-minimize-window-macos' into 'main'
macos: Fix problem that window cannot be minimized by user operation

Closes #4811

See merge request GNOME/gtk!4613
2022-04-04 18:53:19 +00:00
sumibi-yakitori
d3cf7088b3 macos: Skip running showAndMakeKey when a window is minimized by user action
When a window is minimized by user action, the `showAndMakeKey` method is not executed when idle. This prevents the window from being un-minimized immediately.
And allow programmatic minimization of a window by un-minimizing them in `_gdk_macos_toplevel_surface_present`

Closes #4811
2022-04-05 01:06:44 +09:00
Maximiliano Sandoval R
ffa7185397 application: Add link and inline code blocks 2022-04-04 14:11:16 +02:00
Maximiliano Sandoval R
d7fe62817c filter: Add link to FilterListmodel 2022-04-04 14:10:56 +02:00
Maximiliano Sandoval R
a034bdb17e texttag: Correct typo
Does not generate a gir docstring without it.
2022-04-04 14:10:18 +02:00
Matthias Clasen
af20f7e9b5 gl: Don't leak big glyphs
We were never resetting the accessed bit of
glyphs that are big enough to be stored individually,
so these would just accumulate and never be dropped.
2022-04-03 20:25:22 -04:00
Christian Hergert
15b7a4572b Merge branch 'sumibi-yakitori/fix-maximize-window-macos' into 'main'
macos: prohibit fullscreen transition if in transtion

This prevents performing additional fullscreen transitions while
a transition is already in progress.

Closes #4808

See merge request GNOME/gtk!4612
2022-04-03 22:14:52 +00:00
sumibi-yakitori
146bb70c2e macos: prohibit fullscreen transition if in transtion
This prevents performing additional fullscreen transitions while
a transition is already in progress.
2022-04-03 22:14:52 +00:00
Matthias Clasen
494de142f6 Merge branch 'matthiasc/for-main' into 'main'
inspector: Avoid a crash

See merge request GNOME/gtk!4617
2022-04-03 20:11:29 +00:00
Matthias Clasen
5d979cde82 inspector: Avoid another crash
We need to handle all event types here.
This was tripping over GDK_TOUCHPAD_HOLD events.
2022-04-03 15:55:21 -04:00
Matthias Clasen
f48b894468 inspector: Avoid a crash
Attribute lists can be NULL, it turns out.
2022-04-03 15:55:21 -04:00
Matthias Clasen
a6e47892be Merge branch 'matthiasc/for-main' into 'main'
gsk: Plug a memory leak

See merge request GNOME/gtk!4616
2022-04-03 14:21:13 +00:00
Matthias Clasen
1e0c25d96a Merge branch 'meson_fixes' into 'main'
meson: Use proper type for bools

See merge request GNOME/gtk!4615
2022-04-03 12:41:14 +00:00
Matthias Clasen
f57eec5288 css: Plug a memory leak
We were leaking the terms of calc values. Oops.
2022-04-03 08:04:35 -04:00
illiliti
e938befcbc meson: Use proper type for bools
Fix invalid usage of bools which violates official meson specification and thus
breaks muon, an implementation of meson written in C.
2022-04-03 14:55:33 +03:00
Matthias Clasen
2af8ac655b gsk: Plug a memory leak
This was introduced in 9defc7fc64.
2022-04-03 07:34:44 -04:00
Matthias Clasen
cc3c0125a8 Merge branch 'matthiasc/for-main' into 'main'
imcontextsimple: Plug a memory leak

See merge request GNOME/gtk!4614
2022-04-02 19:47:03 +00:00
Matthias Clasen
59f9be457f imcontextsimple: Plug a memory leak 2022-04-02 15:30:47 -04:00
Emmanuele Bassi
d1ce514260 Merge branch 'selection-model-docs' into 'main'
docs: Fix links in selection models

See merge request GNOME/gtk!4609
2022-04-01 11:20:11 +00:00
Maximiliano Sandoval R
ad5e72728f docs: Fix links in selection models 2022-04-01 13:04:14 +02:00
Andika Triwidada
1bf24f7b19 Update Indonesian translation 2022-04-01 03:56:36 +00:00
Matthias Clasen
a3cedb0163 Merge branch 'clipboard-seg' into 'main'
x11: Check return of gdk_x11_get_xatom_name_for_display

See merge request GNOME/gtk!4607
2022-04-01 00:56:32 +00:00
Matthias Clasen
97bab27d82 Merge branch 'fix-win32-empty-clipboard' into 'main'
gdkclipboard-win32.c: Fix call to gdk_clipboard_claim_remote() (check GdkContentFormat is not NULL

Closes #4796

See merge request GNOME/gtk!4604
2022-04-01 00:56:02 +00:00
Matthias Clasen
6030da573d Merge branch 'nls' into 'main'
Remove #ifdef ENABLE_NLS

See merge request GNOME/gtk!4606
2022-03-31 17:07:37 +00:00
Matthias Clasen
0128574ca1 Merge branch 'wip/carlosg/immulticontext-display-switch' into 'main'
gtkimmulticontext: Handle switches between displays

Closes #4805

See merge request GNOME/gtk!4605
2022-03-31 16:29:38 +00:00
Christoph Reiter
b27a169200 Merge branch 'msys2-ci-cleanup' into 'main'
CI: clean up MSYS2 build dependencies

See merge request GNOME/gtk!4600
2022-03-31 15:46:54 +00:00
Xavier Claessens
bcd0704511 Remove #ifdef ENABLE_NLS
libintl API is guaranteed to always be available, glib will fallback to
proxy-libintl in case gettext is not found.
2022-03-31 11:41:34 -04:00
Dr. David Alan Gilbert
506566b6a4 x11: Check return of gdk_x11_get_xatom_name_for_display
When given an invalid atom, gdk_x11_get_xatom_name_for_display can
return NULL and trigger a seg in gdk_x11_clipboard_formats_from_atoms.
Check for NULL.

Why I'm seeing a bad atom there is probably a separate question.
https://bugzilla.redhat.com/show_bug.cgi?id=2037786
2022-03-31 15:56:09 +01:00
Carlos Garnacho
b67da38916 gtkimmulticontext: Handle switches between displays
Currently the GtkIMMultiContext may stick to a delegate GtkIMContext
that no longer applies after the multicontext is dissociated from
any widget.

Handle set_client_widget() so that it can handle changes between
widgets from 2 different display, but also so the delegate is made
NULL whenever the context has a NULL widget.

Doing so, any new client widget results in a new delegate IM context
lookup from the right GdkDisplay and GtkSettings, which avoids any
mix up.

Fixes: https://gitlab.gnome.org/GNOME/gtk/-/issues/4805
2022-03-31 16:35:29 +02:00
Chun-wei Fan
8519ab56f5 gdkclipboard-win32.c: Fix call to gdk_clipboard_claim_remote()
The call to gdk_win32_clipboard_request_contentformats() can return NULL even
without an error condition being hit (such as when the system clipboard is
empty), so check whether the returned GdkContentFormat pointer is not NULL
before calling gdk_clipboard_claim_remote(), which expects it to be not NULL,
otherwise we face a warning from that funtion and the subsequent
g_object_unref().

This at least partially fixes issue #4796.
2022-03-31 10:55:39 +08:00
Carlos Garnacho
04c9c6b428 Merge branch 'wip/exalm/scroll-hold' into 'main'
eventcontrollerscroll: Always propagate hold events

See merge request GNOME/gtk!4599
2022-03-28 14:27:55 +00:00
Alexander Mikhaylenko
9bd8ed0d82 eventcontrollerscroll: Always propagate hold events
Otherwise a stray scroll controller may prevent others from getting hold
events, even if it always propagates scroll events and does absolutely
nothing.
2022-03-28 12:04:15 +00:00
Rūdolfs Mazurs
40386c97eb Update Latvian translation
(cherry picked from commit 3b50f2e8b9)
2022-03-27 20:19:34 +00:00
Rūdolfs Mazurs
6649cc6e5e Update Latvian translation
(cherry picked from commit d4dd7969d6)
2022-03-27 19:54:19 +00:00
Christoph Reiter
e69dc04a7f CI: clean up MSYS2 build dependencies
We only need a C compiler and not the whole toolchain,
and gst-plugins-bad was split into libraries and plugins.
pkg-config -> pkgconf.

This should speed the CI setup up a bit.
2022-03-27 20:10:58 +02:00
Emmanuele Bassi
c1361f7a5a Merge branch 'antoniof-main-patch-34986' into 'main'
overlaylayout: Set position style class on child

Closes nautilus#2099

See merge request GNOME/gtk!4597
2022-03-27 16:25:50 +00:00
António Fernandes
351ffef704 overlaylayout: Set position style class on child
As documented:
> Overlay children whose alignments cause them to be positioned
> at an edge get the style classes “.left”, “.right”, “.top”, 
> and/or “.bottom” according to their position.

Likely accidental regression in b7ee2cbc28

Fixes https://gitlab.gnome.org/GNOME/nautilus/-/issues/2099
2022-03-27 14:59:10 +00:00
Matthias Clasen
a1ddd3fead Merge branch 'inspector-attributes' into 'main'
inspector: Allow viewing PangoAttrList properties

See merge request GNOME/gtk!4596
2022-03-25 13:03:00 +00:00
Matthias Clasen
79f0f4ee8e inspector: Allow viewing PangoAttrList properties
We have pango_attr_list_to/from_string, so this is
easy. The editing UI isn't ideal, but it solves my
immediate need to see attributes.
2022-03-25 08:35:16 -04:00
Matthias Clasen
7b8bfb4c80 Merge branch 'main' into 'main'
Check for 'rst2man' misses installed 'rst2man.py' (#4728)

See merge request GNOME/gtk!4586
2022-03-25 11:48:28 +00:00
Benjamin Otte
7106cf6524 Merge branch 'wip/chergert/fix-gl-rgba' into 'main'
gdk/gl: handle GL_RGBA/GL_UNSIGNED_NORMALIZED

Closes #4783

See merge request GNOME/gtk!4594
2022-03-25 01:34:15 +00:00
Christian Hergert
e706e14fd9 gdk/gl: handle GL_RGBA/GL_UNSIGNED_NORMALIZED
WebKit's GTK 4 port can give us textures with an internal format of
GL_RGBA with GL_UNSIGNED_NORMALIZED and a bit-depth of 8. This fixes
warnings for every GdkGLTexture created/delivered to the GskGLRenderer.

The format is essentially the same as GL_RGBA8 since it is normalized
between 0.0..1.0 for 8-bit components.

Fixes #4783
2022-03-24 18:05:11 -07:00
Matthias Clasen
3f1021048f Merge branch 'want_prepare_without_play_for_size' into 'main'
GtkMediaStream with gstreamer backend isn't 'prepared' until media is played

See merge request GNOME/gtk!4560
2022-03-24 19:19:01 +00:00
Matthias Clasen
ddba7f8601 Apply 1 suggestion(s) to 1 file(s) 2022-03-24 17:16:11 +00:00
Bruce Cowan
1660a0eaf1 Update British English translation
(cherry picked from commit dd198cfc06)
2022-03-24 13:19:45 +00:00
Kukuh Syafaat
ffffb382e2 Update Indonesian translation 2022-03-23 15:39:17 +00:00
Kukuh Syafaat
09453bc60b Update Indonesian translation 2022-03-23 13:46:25 +00:00
Matthias Clasen
f76b749e43 Merge branch 'fix-popover-menu-rtl-position' into 'main'
popover-menu: Fix buttons' position in RTL

See merge request GNOME/gtk!4587
2022-03-23 02:16:41 +00:00
Cheng-Chia Tseng
0aca2a03b4 Update Chinese (Taiwan) translation 2022-03-22 14:47:50 +00:00
Matthias Clasen
fd358990a2 Merge branch 'wip/chergert/reduce-overlay-overhead' into 'main'
Default: avoid use of opacity for overlay scrollbars

See merge request GNOME/gtk!4590
2022-03-22 13:27:54 +00:00
Matthias Clasen
01b91c1ba3 Merge branch 'fix-high-depth-switch' into 'main'
surface: Use correct display when destroying a surface for depth switch

Closes #4773

See merge request GNOME/gtk!4591
2022-03-22 12:58:07 +00:00
Sebastian Keller
cc02076b75 surface: Use correct display when destroying a surface for depth switch
When surface depth switches from non-high-depth to high-depth (or vice
versa) the current surface has to be destroyed before a new one can be
created for this window. eglDestroySurface however was getting passed a
GdkDisplay, rather than the EGLDisplay it expects. As a result the old
surface did not get destroyed and the new surface could not be created
causing rendering to freeze.

Fixes: https://gitlab.gnome.org/GNOME/gtk/-/issues/4773
2022-03-22 08:18:26 +01:00
Christian Hergert
b726a2d902 Default: avoid use of opacity for overlay scrollbars
If using the opacity CSS property the renderer cannot optimize these
handles without the use of offscreens due to the use of both a border
and rgb render node.

Instead, we can apply the alpha to the color values and get the same
effect in a way that the GL renderer can optimize without the use of
offscreen textures for a sizeable reduction in runtime overhead.
2022-03-21 22:10:23 -07:00
Marek Černocký
654ae5928a Updated Czech translation 2022-03-21 14:57:35 +01:00
Marek Černocký
1c24514798 Updated Czech translation 2022-03-21 12:14:36 +01:00
Yosef Or Boczko
33f3ab9991 popover-menu: Fix buttons' position in RTL
The radio/check/previous buttons shows in
the wrong place in RTL. Fix it.

#4641

Signed-off-by: Yosef Or Boczko <yoseforb@gmail.com>
2022-03-20 00:54:26 +02:00
aneejit1
91511a80ac Check for 'rst2man' misses installed 'rst2man.py' (#4728)
By default, 'docutils' installs 'rst2man' as 'rst2man.py'. Amend the
check for 'rst2man' to look for 'rst2man.py' as well if 'rst2man' is
not found.
2022-03-19 13:58:40 +00:00
Philipp Kiemle
a585457861 Update German translation
(cherry picked from commit d9c39f6795)
2022-03-19 12:32:43 +00:00
Carlos Garnacho
4a0ddac307 Merge branch 'wip/carlosg/fix-accumulated-velocity' into 'main'
kinetic scroll fixes

See merge request GNOME/gtk!4572
2022-03-19 12:02:56 +00:00
Carlos Garnacho
f7d9ede82d gtkkineticscrolling: Do not take distance based shortcuts
The pixel distance could be small enough between tick() calls that
this kind of checks might potentially become a problem. Rely only on
the calculated velocity to trigger the STOPPED phase, and use a lower
threshold to avoid cutting the animation too early.

Related: https://gitlab.gnome.org/GNOME/gtk/-/issues/4725
2022-03-19 12:35:11 +01:00
Carlos Garnacho
65839f67f8 gtkscrolledwindow: Do not trigger kinetic helpers on 0 velocity
Doing this is pointless, so it could be skipped.
2022-03-19 12:35:11 +01:00
Carlos Garnacho
df40db137b gtkscrolledwindow: Change lifetime of kinetic scroll helpers
In order to properly accumulate scroll velocities, we need to keep
the kinetic scroll helpers after we have possibly stopped them
in the process of initiating a further scroll flick.

So, instead of stopping (and destroying) those helpers on scroll-begin,
keep them until the next scroll-end if a scroll was initiated before
kinetic scroll finished. This way we can fetch the last velocity when
calculating the extra kick.

In order to ensure the helpers don't live beyond what it is expected,
we now also remove them after a finished hold event.

Fixes the accumulation of scrolling velocity on consecutive scroll
sequences.
2022-03-19 12:35:11 +01:00
Carlos Garnacho
129bc27d53 gtkscrolledwindow: Refactor kinetic scroll animation
Do not depend on the kinetic scroll helpers existing or not before
exiting the animation, as we may want to keep those a little bit
longer after stopped.
2022-03-19 12:35:11 +01:00
Carlos Garnacho
274e2b221f gtkkineticscroll: Do not reset velocity after stop()
We may want to fetch the last velocity obtained, even though we
preemptively called stop() on a kinetic scroll helper. Keep this
velocity so it can be queried later on.
2022-03-19 12:35:11 +01:00
Emmanuele Bassi
adc4009354 Merge branch 'search-delay-versions' into 'main'
Fix GtkSearchEntry:search-delay docs

See merge request GNOME/gtk!4585
2022-03-19 10:14:04 +00:00
Sebastian Dröge
f058a42bd3 Add version marker to GtkSearchEntry:search-delay property 2022-03-19 11:56:05 +02:00
Sebastian Dröge
3a8cb276e7 Fix typo in gtk_search_entry_set_search_delay() docs causing it to not show up 2022-03-19 11:55:03 +02:00
Matthias Clasen
eeaa73c12a Merge branch 'macos-fix-scroll-unit-build' into 'main'
macos: fix scroll-unit build

See merge request GNOME/gtk!4584
2022-03-19 03:57:48 +00:00
panoplie
3873861b27 macos: fix scroll-unit build 2022-03-19 02:55:02 +01:00
Carlos Garnacho
8e455e333b Merge branch 'scroll-unit' into 'main'
GdkScrollEvent: indicate the delta unit with a new GdkScrollUnit enum

See merge request GNOME/gtk!4508
2022-03-19 00:47:08 +00:00
Matthias Clasen
3d10e6c3d1 Merge branch 'wip/carlosg/rewritten-events-from-other-toplevels' into 'main'
gtk/main: Make coords out of surface when rewriting events for grabs

Closes #4760

See merge request GNOME/gtk!4566
2022-03-19 00:34:17 +00:00
Matthias Clasen
dcc7cf7114 Merge branch 'wip/chergert/gsk-gl-texture-library' into 'main'
gsk/gl: texture libraries, shader creation

See merge request GNOME/gtk!4583
2022-03-18 23:46:17 +00:00
panoplie
f1d0886087 gtkeventcontrollerscroll: Map surface scroll unit in discrete steps 2022-03-19 00:41:26 +01:00
panoplie
951e4ee6b2 recorder: Show scroll events deltas unit 2022-03-19 00:41:26 +01:00
panoplie
f9e2c106bc gtkrange: Add scroll unit handling 2022-03-19 00:41:26 +01:00
panoplie
53956e5389 gtkscrolledwindow: Add scroll unit handling
On the "scroll" signal, the widget uses
gtk_event_controller_scroll_get_unit() to get the
scroll unit.

When the unit is GDK_SCROLL_UNIT_WHEEL, the
behavior is unchanged: the widget scrolls a
certain number of pixels at each wheel detent
click. This number of pixels is determined by the
window dimensions in get_wheel_detent_scroll_step().

When the delta unit is GDK_SCROLL_UNIT_SURFACE, the
widget directly adds the delta to the number of
scrolled pixels no matter the window dimensions.
2022-03-19 00:41:26 +01:00
panoplie
3ab63fd03b gtkeventcontrollerscroll: Add scroll unit getter
The scroll unit is accessible through
gtk_event_controller_scroll_get_unit() after the
"scroll" signal reception.
2022-03-19 00:41:26 +01:00
panoplie
fb4927827b gdk: Add enum to indicate the unit of scroll deltas
Add a new GdkScrollUnit enum that represent the
unit of scroll deltas provided by GdkScrollEvent.
The unit is accessible through
gdk_scroll_event_get_unit().
2022-03-19 00:41:26 +01:00
Christian Hergert
cbbca38d88 gsk/gl: use consistent library naming 2022-03-18 14:59:49 -07:00
Christian Hergert
c64836e1c9 gsk/gl: make texture libraries more autonomous
This moves a lot of the texture atlas control out of the driver and into
the various texture libraries through their base GskGLTextureLibrary class.

Additionally, this gives more control to libraries on allocating which can
be necessary for some tooling such as future Glyphy integration.

As part of this, the 1x1 pixel initialization is moved to the Glyph library
which is the only place where it is actually needed.

The compact vfunc now is responsible for compaction and it allows for us
to iterate the atlas hashtable a single time instead of twice as we were
doing previously.

The init_atlas vfunc is used to do per-library initialization such as
adding a 1x1 pixel in the Glyph cache used for coloring lines.

The allocate vfunc purely allocates but does no upload. This can be useful
for situations where a library wants to reuse the allocator from the
base class but does not want to actually insert a key/value entry. The
glyph library uses this for it's 1x1 pixel.

In the future, we will also likely want to decouple the rectangle packing
implementation from the atlas structure, or at least move it into a union
so that we do not allocate unused memory for alternate allocators.
2022-03-18 14:59:46 -07:00
Christian Hergert
6b23fe3aa7 gsk/gl: pin atlases to single texture library
This removes the sharing of atlases across various texture libraries. Doing
so is necessary so that atlases can have different semantics for how they
allocate within the texture as well as potentially allowing for different
formats of texture data.

For example, in the future we might store non-pixel data in the textures
such as Glyphy or even keep glyphs with color content separate from glyphs
which do not and can use alpha channel only.
2022-03-18 12:48:43 -07:00
Christian Hergert
9defc7fc64 gsk/gl: add more control over shader generation
This allows the gskglprograms.defs a bit more control over how a shader
will get generated and if it needs to combine sources. Currently, none of
the built-in shaders do that, but upcoming shaders which come from external
libraries will need the ability to inject additional sources in-between
layers.
2022-03-18 12:34:32 -07:00
Christian Hergert
9d56f44cdf gsk/gl: rename glyphs to glyphs_library
This naming style is less likely to collide with shader naming and makes
it clear where it is consumed what it is.
2022-03-18 12:34:32 -07:00
Christian Hergert
1b9da2bb17 gsk/gl: allow configuring atlas size 2022-03-18 12:34:27 -07:00
Christian Hergert
2efc1729e2 gsk/gl: check for format as well
This could potentially happen if a uniform had never been set.
2022-03-18 12:33:33 -07:00
Christian Hergert
a66a0dde81 gsk/gl: only clear glyph cache durign reclaimation
We don't need to clear the front cache on every frame as we can clear it
specifically when we do reclaimation to avoid unnecessary memset() calls.
2022-03-18 12:33:33 -07:00
Christian Hergert
7062411bad gsk/gl: ignore max_entry_size when zero
If the max_entry_size is zero, then assume we can add anything to the
atlas. This allows for situations where we might be uploading an arc list
to the atlas instead of pixel data for GPU font rendering.
2022-03-18 12:33:33 -07:00
Christian Hergert
9dbd137ec8 gsk/gl: make max-frame-age configurable
This is nice for some texture libraries that we might want to keep around
for longer than say 60 frames such as a glyph cache.
2022-03-18 12:33:33 -07:00
Matthias Clasen
79fad9f221 gtk-demo: Don't hardcode a title font
We want a large font size, but we don't have to
hardcode Sans.
2022-03-18 12:33:33 -07:00
Matthias Clasen
8f9ee48aaa Merge branch 'filefilter-suffixes' into 'main'
filefilter: Fix <suffixes> in buildable

See merge request GNOME/gtk!4581
2022-03-17 16:57:09 +00:00
James Westman
8eb9844a45 filefilter: Fix <suffixes> in buildable
A bug in GtkFileFilter's GtkBuildable implementation caused the
<suffixes> tag not to be recognized.
2022-03-17 10:52:20 -05:00
Milo Casagrande
b90132c917 Update Italian translation
(cherry picked from commit 3e4bfa2bae)
2022-03-17 08:36:13 +00:00
Milo Casagrande
23806b7788 Update Italian translation
(cherry picked from commit 9bbf09fb0a)
2022-03-17 08:34:32 +00:00
Мирослав Николић
d266c0d105 Update Serbian translation
(cherry picked from commit c874f65d95)
2022-03-17 06:04:41 +00:00
Carlos Garnacho
581461c2b5 Merge branch 'wip/carlosg/im-wayland-serials' into 'main'
gtk/imwayland: Use serial to control outbound messages

Closes #3641

See merge request GNOME/gtk!4398
2022-03-16 18:52:24 +00:00
Carlos Garnacho
f108f053d4 gtk/imwayland: Use serial to control outbound messages
Following the text-input protocol changes at
https://gitlab.freedesktop.org/wayland/wayland-protocols/-/merge_requests/115,
use the serial number to have the client push changes to the
zwp_text_input_v3 object only after compositor/client states match.

This specifically is more lenient to compositors pushing multiple
.done events ahead of the client replying to them.

Closes: https://gitlab.gnome.org/GNOME/gtk/-/issues/3641
2022-03-16 17:38:14 +01:00
Matthias Clasen
df593ee651 Merge branch 'wip/carlosg/im-text-location' into 'main'
gtkimcontextwayland: Add native surface offset to input coordinates

Closes #4668

See merge request GNOME/gtk!4573
2022-03-16 11:54:26 +00:00
Carlos Garnacho
4dcd011486 gtkimcontextwayland: Add native surface offset to input coordinates
We were missing the surface offset (e.g. shadows) at the time of expressing
the text caret location in surface coordinates. Add this offset so the
coordinates are as expected by the compositor.

Fixes: https://gitlab.gnome.org/GNOME/gtk/-/issues/4668
2022-03-16 09:57:42 +01:00
Matthias Clasen
6fe7e373e2 Merge branch 'gtk/gss-search-delay' into 'main'
searchentry: Make search delay editable

Closes #4133

See merge request GNOME/gtk!4563
2022-03-15 22:40:54 +00:00
Ondřej Míchal
0c3583b4bd searchentry: Make search delay editable
The default search delay of 150ms can be too low at times[0], leading app
developers to add additional delay while handling the search-changed
signal[1].

Based on past work from hugsie[2].

Fixes https://gitlab.gnome.org/GNOME/gtk/-/issues/4133

[0] https://github.com/getting-things-gnome/gtg/issues/281
[1] https://github.com/getting-things-gnome/gtg/pull/587
[2] https://gitlab.gnome.org/GNOME/gtk/-/issues/678
2022-03-15 23:55:10 +02:00
Kjartan Maraas
5bd0179a88 Update Norwegian Bokmål translation
(cherry picked from commit 72a557087c)
2022-03-15 15:26:58 +00:00
Matthias Clasen
f116efd48e Merge branch 'main' into 'main'
gtkplacessidebar: Prevent calling g_object_unref on null

See merge request GNOME/gtk!4569
2022-03-15 14:37:14 +00:00
Matthias Clasen
8057bee295 Apply 1 suggestion(s) to 1 file(s) 2022-03-15 14:35:09 +00:00
Matthias Clasen
ab330f1efc Merge branch 'wip/jimmac/symbolics-gnome-42-sync' into 'main'
icons: update symbolics

See merge request GNOME/gtk!4571
2022-03-15 14:29:27 +00:00
Carlos Garnacho
e5dc66b10e gtk/main: Fix handling of !owner_events grabs
These are meant to always redirect events to the grabbing surface,
even for other surfaces of the same client. We weren't doing that
(instead letting the event go through unmodified), fix this handling
so GTK sees the events consistenty.
2022-03-15 14:40:49 +01:00
Carlos Garnacho
aa43d97a80 gtk/main: Make coords out of surface when rewriting events for grabs
If a grab is held on a toplevel surface tree, and events happen on a
different surface tree from another toplevel/window group, we rewrite
these events so they look like generated on the window group that
holds the grab, but it missed that coordinates would fail to be
translated, so these would stay unchanged and "pointing" to random
parts of the toplevel that is holding the grab and handling the events.

Since off-surface coordinates are not specially meaningful, and in
fact impossible to obtain in some backends, just fake the coordinates
making it sure that all rewritten events point outside the surface.

The grabbing window will still handle the events, but the coordinates
in these will be harmlessly moot.

Fixes: https://gitlab.gnome.org/GNOME/gtk/-/issues/4760
2022-03-15 14:29:16 +01:00
Matthias Clasen
eaf4fb68f3 Merge branch 'avoid-objcopy-on-arm' into 'main'
build: Avoid objcopy on arm

Closes #4757, #4748, and #4752

See merge request GNOME/gtk!4567
2022-03-15 13:08:53 +00:00
Jakub Steiner
bfe193e6e2 icons: update symbolics
- match the metaphors/style updates of gnome 42

See https://gitlab.gnome.org/GNOME/gtk/-/issues/4764
2022-03-15 08:31:26 +01:00
Мирослав Николић
aa8dec3d27 Update Serbian translation
(cherry picked from commit b59f9b97f3)
2022-03-15 06:33:46 +00:00
Matthias Clasen
d2e7060150 Merge branch 'builder-tool-nodisplay' into 'main'
gtk-builder-tool: Operate without display

See merge request GNOME/gtk!4568
2022-03-14 22:15:11 +00:00
Fina Wilke
08f3acb534 gtkplacessidebar: Prevent calling g_object_unref on null
g_object_unref would be called on a null end_icon when provider_account_status
is CLOUD_PROVIDERS_ACCOUNT_STATUS_IDLE
2022-03-14 22:33:35 +01:00
Matthias Clasen
525f96f2f8 gtk-builder-tool: Operate without display
The simplify and validate commands can function
without a display connection, only preview absolutely
needs one. Allow this, by using gtk_init_check().
2022-03-14 15:40:12 -04:00
Matthias Clasen
b6b2682bd6 build: Avoid objcopy on arm
The trickery we do with objcopy and ld to speed up
resource inclusion does not seem to work right on
32bit Arm, so just skip it there.

Fixes: #4757, #4748, #4752
2022-03-14 08:44:09 -04:00
Christian Kirbach
1832964188 Update German translation
(cherry picked from commit a1f4735652)
2022-03-13 22:09:17 +00:00
Matthias Clasen
eb599653e6 Merge branch 'wip/lantw/build-Don't-use-ld-and-objcopy-when-cross-compiling' into 'main'
build: Don't use ld and objcopy when cross-compiling

See merge request GNOME/gtk!4565
2022-03-13 14:31:23 +00:00
Ting-Wei Lan
e1e88ce665 build: Don't use ld and objcopy when cross-compiling
These commands don't work when compiling Windows binaries on Linux.
2022-03-13 15:19:46 +08:00
Balázs Úr
66d21689bc Update Hungarian translation 2022-03-13 00:23:04 +00:00
Matthias Clasen
8186cb8bee Merge branch 'wip/chergert/for-main' into 'main'
macos: fit'n'finish fixes for main

See merge request GNOME/gtk!4564
2022-03-12 19:07:41 +00:00
Baurzhan Muftakhidinov
9b8f28903b Update Kazakh translation
(cherry picked from commit 6ac723321f)
2022-03-12 13:23:41 +00:00
Anders Jonsson
1cd42825c2 Update Swedish translation
(cherry picked from commit 343b08f3e6)
2022-03-12 11:39:33 +00:00
Christian Hergert
166444f115 macos: exclude popups from window list
This probably only matters if you do window list integration for the global
menu on macOS.
2022-03-11 22:36:26 -08:00
Christian Hergert
3cd68c5de5 macos: pass events to foreign windows 2022-03-11 18:25:47 -08:00
Christian Hergert
9e2357d5f3 macos: clear sorted surfaces when showing file chooser
When showing the native file chooser, we need to ensure we clear the
sorted surfaces in the display so that we don't risk delivering events
correctly on the next frame.
2022-03-11 18:19:44 -08:00
Christian Hergert
bd0c68f641 macos: dont steal key window from NSPanel
Or we risk making it really difficult to use native file choosers.
2022-03-11 18:07:34 -08:00
Christian Hergert
c3a7d79154 macos: fix window level for popups
This comment isn't really accurate anymore it seems, so we can start
setting the proper stacking order for popups now.
2022-03-11 18:01:05 -08:00
Christian Hergert
25624083dd macos: fix attachment of popups to parents
We had code to do it and it never actually got used correctly. This ensures
that the popup services are attached to the parents so that they get proper
stacking orders when displayed. Additionally, it fixes popups from being
shown as their own windows in Exposé.
2022-03-11 17:53:42 -08:00
Christian Hergert
407b5246a6 macos: fix window activation during shadow click-through
If we are clicking through the shadow of a window, we need to take special
care to not raise the old window on mouseUp. This is normally done by the
display server for us, so we need to use the proper API that is public to
handle this (rather than CGSSetWindowTags()). Doing so requires us to
dispatch the event to the NSView and then cancel the activcation from
the mouseDown: event there.
2022-03-11 14:44:07 -08:00
Christian Hergert
6bedcf22bc macos: select new key window after processing events
If we closed a key window in response to events, we need to denote another
window as the new key window. This is easiest to do from an idle so that
we don't clobber notification pairs of "did resign"/"did become" key
window.

We have a sorted set of surfaces by display server stacking, so we can
take the first one we come across that is already mapped and re-show it
to become key/main.
2022-03-11 14:44:06 -08:00
Christian Hergert
eeb9d6c398 macos: request layout with server-side decoration
If we have server-side decorations we might need to request a layout in
response to the resize notification. We don't need to do this in other
cases because we already handle that in the process of doing the resize
(and that code is that way because of delayed delivery of NSNotification).
2022-03-11 14:44:06 -08:00
Christian Hergert
cf8d2374c5 macos: fix resize when using server-side decorations
If we are using NSWindow titled windows, we don't end up waking up the
frame clock when the window is resized on the display server. This ensures
that we do that after getting a notification of resize.
2022-03-11 14:44:06 -08:00
Christian Hergert
9fa5378d83 macos: set main window in addition to key
If we are showing the window, we might also want to make it the main
window for the application when shown.
2022-03-11 14:44:06 -08:00
Dušan Kazik
90352d760d Update Slovak translation
(cherry picked from commit c8d1f23ff5)
2022-03-11 07:44:15 +00:00
Balázs Úr
c3c1763a9f Update Hungarian translation 2022-03-11 01:09:19 +00:00
Matthias Clasen
9f7c9ce6ad Merge branch 'better-format-conversions' into 'main'
gdk: Clean up the optimised premultiply conversion function

See merge request GNOME/gtk!4550
2022-03-10 19:26:25 +00:00
Matthias Clasen
1f155bf39a Merge branch 'wlprotocols-dependency-correctness' into 'main'
meson: use proper handling of wayland-protocols dependency

See merge request GNOME/gtk!4561
2022-03-10 19:15:39 +00:00
Christian Hergert
84014e3414 macos: make transient-for key window when hiding surface
This only handled the popover case before and not the transient-for case.
2022-03-10 08:04:14 -08:00
Christian Hergert
4ced1c90f1 macos: actually drop unnecessary momentum events
These would get passed along to the NSApplication which we don't really
need to have happen. Denote it as such.
2022-03-10 03:21:12 -08:00
Christian Hergert
54c3b947fc macos: queue all pending events
Rather than process these a single event at a time, queue all of the
outstanding events from the NSEvent queue.
2022-03-10 03:20:07 -08:00
Eli Schwartz
94007caf8d meson: use proper handling of wayland-protocols dependency
Ensure that resolution of the subproject occurs via the dependency
interface, not the "poke at subprojects manually" interface, and make
that actually work via --wrap-mode=forcefallback.

There's no need to mark it as not-required and then manually invoke
subproject(), since fallback should work correctly and it is always
needed.

However, if fallback was performed (or forced) it would error out since
get_variable() was instructed to only use pkg-config while the relevant
variable was exported by the subproject as an internal fallback
dependency.
2022-03-10 00:08:36 -05:00
Matthias Clasen
675c8b45b1 Merge branch 'wip/jimmac/legacy-icons-gtk4' into 'main'
icons: add missing legacy fullcolor

See merge request GNOME/gtk!4558
2022-03-09 23:37:26 +00:00
Christian Hergert
ea59d174a0 macos: drop enter/exit when in manual drag/resize
If we are in a manual resize/drag then we don't want to generate crossing
events as they can just confuse things.
2022-03-09 13:20:53 -08:00
Christian Hergert
32935d9fb0 macos: allow dropping NSEvent without propagation
There are cases we might want to consume a NSEvent without creating a
GdkEvent or passing it along to the NSApplication for processing. This
creates a new value we can use and check against to propagate that without
having to do out parameters at the slightly odd invalid pointer value for
a GdkEvent (similar to how MMAP_FAILED is done).
2022-03-09 13:19:22 -08:00
Christian Hergert
b390e1da4f macos: do not focus new window when resigning main
This can get in the way of how we track changes while events are actively
processing. Instead, we may want to delay this until the next main loop
idle and then check to see if we have a main window as the NSNotification
may have come in right after this.
2022-03-09 12:33:46 -08:00
Jiri Grönroos
cccd1147e7 Update Finnish translation
(cherry picked from commit d188c6dbaf)
2022-03-09 19:03:58 +00:00
Emmanuele Bassi
d8db5f3217 Merge branch 'fix_gtk_accessible_update_relation_example' into 'main'
fix docs for gtk_accessible_update_relation example

See merge request GNOME/gtk!4559
2022-03-09 18:22:54 +00:00
Marek Černocký
f5bb364bb5 Fixed Czech translation 2022-03-09 19:06:22 +01:00
Caolán McNamara
82f57c6a93 GtkMediaStream with gstreamer backend isn't 'prepared' until media is played
This seems to be a problem since:
https://gitlab.gnome.org/GNOME/gtk/-/merge_requests/3565

To demo the problem, the video demo in gtk4-demo is currently set to
autoplay, but it doesn't autoplay on load as expected because the
"prepared" notification doesn't fire until the user explicitly presses
play.

Similarly if the demo is tweaked to disable autoplay then on loading a
video (or an audio-only ogg) the duration is not known or shown until
the user presses play.

In LibreOffice we want to know what the size of the video is to position
it before the user can interact with it to set it to play. We can
workaround this to some degree by listening to "invalidate-size" on the
GtkMediaStream object which updates for videos, but that doesn't wor
for audio-only streams.

So restore listening to media-info-updated but ignore -1 (which I see
for audio-only where I get -1 and then a useful value) and 0 of the
original report.

see also:
https://gitlab.gnome.org/GNOME/gtk/-/merge_requests/3550

GNOME/gtk!4513
2022-03-09 16:29:11 +00:00
Caolán McNamara
20c41dce80 fix docs for gtk_accessible_update_relation example 2022-03-09 16:24:47 +00:00
Jakub Steiner
a9de385ac5 icons: add missing legacy fullcolor
- relied on in testsuite

See https://gitlab.gnome.org/GNOME/gtk/-/issues/4754
2022-03-09 16:19:16 +01:00
Anders Jonsson
ead210c170 Update Swedish translation
(cherry picked from commit 9053fd8335)
2022-03-09 10:50:11 +00:00
Matthias Clasen
2ad471542a Merge branch 'fix-focus-issues' into 'main'
Fix some focus issues

See merge request GNOME/gtk!4556
2022-03-08 19:37:45 +00:00
Danial Behzadi
d73cff5846 Update Persian translation
(cherry picked from commit a9720259f0)
2022-03-08 15:01:00 +00:00
Matthias Clasen
213376ee0a text: Stop blinking when we lose focus
We were looking at GtkWidget:has-focus from
event controller signal handlers here, but
the widget property is only changed after
the event controllers.
2022-03-08 06:06:47 -07:00
Matthias Clasen
1cc100415f focus controller: Update for active window
When the window gains or looses active status,
update the focus controllers status.
2022-03-08 06:06:47 -07:00
Matthias Clasen
d9ad7884e9 window: Update has-focus property
Update the :has-focus property of the focus
widget when the active status of the window
changes.

We change the property after generating the
GDK_CROSSING_ACTIVE crossing events.
2022-03-08 06:05:49 -07:00
Ask Hjorth Larsen
f545d7a910 Updated Danish translation 2022-03-08 01:28:14 +01:00
Ask Hjorth Larsen
206eb647a4 Updated Danish translation of gtk-properties 2022-03-08 01:28:11 +01:00
Aurimas Černius
00e637b480 Updated Lithuanian translation 2022-03-07 18:29:37 +02:00
Emmanuele Bassi
bfc8b7b7b6 Merge branch 'gdk-tests-naming' into 'main'
Use the correct name for installed gdk tests

See merge request GNOME/gtk!4555
2022-03-07 15:34:31 +00:00
Sebastien Bacher
c44288c739 Use the correct name for installed gdk tests 2022-03-07 16:13:38 +01:00
Luna Jernberg
2fb5104731 Update Swedish translation
(cherry picked from commit 89bba41fd7)
2022-03-07 08:09:54 +00:00
Matthias Clasen
0ae4d80766 Merge branch 'wip/chergert/for-main' into 'main'
macos: fixes for main

See merge request GNOME/gtk!4553
2022-03-06 01:36:13 +00:00
Christian Hergert
f5098e4fc5 macos: fix cursor blink time
The value from settings is for the duration of the blink period, not the
timeout. This fixes the blink lasting longer than 10 seconds.
2022-03-05 12:01:53 -08:00
Christian Hergert
28607f082c macos: require input region to become key
Some things cannot become key windows (like tooltips). We can use the
input_region existence to determine if we should allow it as a key window.
2022-03-05 11:58:43 -08:00
Matthias Clasen
f3968f2f1e Merge branch 'fix-doc-typo' into 'main'
Fix a documentation typo

Closes #4747

See merge request GNOME/gtk!4552
2022-03-05 05:50:10 +00:00
Matthias Clasen
88fa226223 Fix a documentation typo
It is XDG_DATA_HOME.

Fixes: #4747
2022-03-04 22:18:06 -07:00
Jordi Mas i Hernandez
c4c496a31c Update Catalan translation
(cherry picked from commit 2be2912e43)
2022-03-04 21:40:53 +00:00
Changwoo Ryu
c1eac4a421 Update Korean translation 2022-03-04 14:22:53 +00:00
Changwoo Ryu
b5d1323f49 Update Korean translation
(cherry picked from commit 2755ad19be)
2022-03-04 14:20:48 +00:00
Matthias Clasen
e297ac319d Merge branch 'fixup-shadernode-constructor' into 'main'
Fix up preconditions of gsk_gl_shader_node_new

Closes #4739

See merge request GNOME/gtk!4551
2022-03-04 06:06:35 +00:00
Matthias Clasen
bf852bea24 Fix up preconditions of gsk_gl_shader_node_new
These were not quite right, and implied that args
may be NULL, when it really can't.

Fixes: #4739
2022-03-03 22:40:10 -07:00
Matthias Clasen
a652507b7b Merge branch 'center-layout-setters' into 'main'
gtk: Have GtkCenterLayout hold a reference to its widgets

See merge request GNOME/gtk!4544
2022-03-03 19:38:28 +00:00
Jason Francis
4a2a76c231 gtk: Have GtkCenterLayout hold a reference to its widgets 2022-03-03 14:00:25 -05:00
Benjamin Otte
8cb7369b7a Merge branch 'wip/chergert/KHR_swap_buffers_with_damage' into 'main'
gdk: use EGL_KHR_swap_buffers_with_damage

See merge request GNOME/gtk!4548
2022-03-03 15:29:47 +00:00
Emmanuel Gil Peyrot
588076d166 gdk: Add a rgb8 → rgba8 conversion macro
This one can be used for both premultiplied and non-premultiplied alpha
formats, since alpha is always 255.  It is useful for opaque PNG upload
on both cairo and GL renderers.
2022-03-03 16:05:52 +01:00
Emmanuel Gil Peyrot
3a98b28ab7 gdk: Make the optimized premultiply function a macro
That way, all permutations are possible.  Previously it was only useful
in the cairo renderer, which required rgba8 → premultiplied bgra8, while
the GL renderer required rgba8 → premultiplied rgba8.  Now both are
available.
2022-03-03 16:04:45 +01:00
Emmanuel Gil Peyrot
cfeedcc321 gdk: Remove pixel format conversion ARM intrinsics
This was only useful when building for AArch32 without -mfpu=neon, on
AArch64 or with -mfpu=neon gcc is smart enough to do the auto-
vectorisation, leading to code almost as good as what I wrote in
1fdf5b7cf8.
2022-03-03 16:04:45 +01:00
Matthias Clasen
d0aedbc9fc Merge branch 'bilelmoussaoui/docs' into 'main'
headerbar: Fix docs

See merge request GNOME/gtk!4545
2022-03-03 14:11:25 +00:00
Changwoo Ryu
5557a528b6 Update Korean translation
(cherry picked from commit 156f99560d)
2022-03-03 12:46:55 +00:00
Christian Hergert
5316eb0c35 gdk: use EGL_KHR_swap_buffers_with_damage
It appears that NVIDIA does not implement EGL_EXT_swap_buffers_with_damage
on their EGL implementation, but does implement the KHR variant of it.
This checks for a suitable implementation and stores a pointer to the
compatible implementation within the GdkGLContextPrivate struct.
2022-03-03 01:22:01 -08:00
Bilal Elmoussaoui
e6afe28de5 headerbar: Fix docs 2022-03-03 08:36:33 +00:00
Matthias Clasen
eaf0353205 Merge branch 'wip/chergert/for-main' into 'main'
macos: various fixes

See merge request GNOME/gtk!4543
2022-03-02 13:37:06 +00:00
Carlos Garnacho
f9f9bd3f5b Merge branch 'xdg-activation-no-surface' into 'main'
wayland: xdg-activation: Don't assume there's a focus surface

See merge request GNOME/gtk!4366
2022-03-02 12:44:52 +00:00
Christian Hergert
ca79688f52 macos: clear window stack before requesting motion
We want to ensure that we recalculate the sort order of windows before
processing the motion. Generally this would be done in response from the
display server in GdkMacosWindow, but I've seen it possible to race there.
2022-03-02 01:04:53 -08:00
Christian Hergert
efa8f903c2 macos: invalidate surface contents when mapping 2022-03-02 00:48:06 -08:00
Christian Hergert
f7d0b91267 macos: move children when monitor changes
We can rely on other code to move monitors, but specifically with children
we want to try harder to move them as a group and keep positioning in tact.
2022-03-02 00:47:27 -08:00
Christian Hergert
ed4f0de2b0 macos: make move_resize possibly idempotent
We need to handle the case where we might be racing against an incoming
configure event due to how notifications are queued from the display
server. Rather than calling configure (and possibly causing other things
to move around) this just queries the display server directly for the
coordinates that we care about.

Additionally, we can display:NO as we are in control of all the display
process now using CALayer.
2022-03-02 00:45:44 -08:00
Christian Hergert
50b96dcdd5 macos: handle transient-for from configure
We failed to handle the toplevel with transient-for case here which could
cause our X/Y calculations to be off in other areas such as best monitor
detection.
2022-03-02 00:43:33 -08:00
Christian Hergert
cf25f2c04b macos: use parent frame clock again
We do actually need the parent frame clock here because it is the way we
ensure that we get layout called for our popup surfaces at the same time
as the parent surface.
2022-03-02 00:42:09 -08:00
Christian Hergert
ddf07ffe22 macos: reduce chances for layout cycles
We need to be more careful about when we request a layout because it can
cause us to get into a layout cycle at maximum frame rate.
2022-03-02 00:40:21 -08:00
Christian Hergert
82f1eaacc9 macos: improve initial placement of toplevels with parent
This doesn't appear to happen much, but if it does it is nice to setup
the window placement initially. Generally, transient-for is set after
the creation of the toplevel rather than here.
2022-03-02 00:38:39 -08:00
Christian Hergert
4cdb07fa02 macos: leave a note about monitor configuration
It can be helpful to see what the range of monitor values is when emulating
the GDK coordinate system.
2022-03-02 00:37:07 -08:00
Christian Hergert
bdd5393084 macos: use GdkMacosBuffer for storing damage region
The GdkMacosBuffer object already has storage for tracking the damage
region as it is used in GdkMacosCairoContext to manually copy regions from
the front buffer to the back buffer. This makes the GdkMacosGLContext also
use that field so that we can easily drop old damage regions when the
buffer is lost. This happens during resizes, monitor changes, etc.
2022-03-02 00:36:17 -08:00
Christian Hergert
27b87ebec5 macos: add clamp helper to keep rectangle in workarea
This helper is useful to ensure we are consistent with how we keep a
window clamped to the workarea of a monitor when placing windows on
screen. (This does not affect snap-to-edges).
2022-03-02 00:34:27 -08:00
Christian Hergert
8c0df66d5f macos: style cleanup 2022-03-02 00:33:13 -08:00
Christian Hergert
e5238bf54f macos: add re-entrancy check when monitors change 2022-03-02 00:32:50 -08:00
Christian Hergert
e9abcde031 macos: check for best_monitor before using
Make sure we have a monitor to enqueue/dequeue from before using it. That
also allows us to use this from destroy and what-not.
2022-03-02 00:32:07 -08:00
Goran Vidović
d45281e6c7 Update Croatian translation
(cherry picked from commit 4eee322654)
2022-03-01 13:05:13 +00:00
Goran Vidović
3fd5ebffcb Update Croatian translation
(cherry picked from commit 67ae05d855)
2022-03-01 12:54:18 +00:00
Carlos Garnacho
88a621fa13 Merge branch 'wip/carlosg/focus-request-over-xdg-activation' into 'main'
wayland: Use xdg-activation for non-startup initiated focus requests

See merge request GNOME/gtk!4535
2022-03-01 11:21:12 +00:00
Marek Černocký
ce4b799f1e Updated Czech translation 2022-03-01 12:08:18 +01:00
Carlos Garnacho
4dcacff312 wayland: Use xdg-activation for non-startup initiated focus requests
Currently, we have all the plumbing in place so that GTK consumes the
startup notification ID when focusing a window through the xdg-activation
protocol.

This however misses the case that a window might be requested to be
focused with no startup ID (i.e. via interaction with the application,
not through GApplication or other application launching logic).

In this case, we let the application create a token that will be
consumed by itself. The serial used is that from the last
interaction, so the compositor will still be able to do focus prevention
logic if it applies.

Since we already do have a last serial at hand, prefer xdg-activation
all the way over the now stale gtk-shell focusing support. The timestamp
argument becomes unused, but that is a weak argument to prefer the
private protocol over the standard one. The gtk-shell protocol support
is so far left for interaction with older Mutter.
2022-03-01 11:38:51 +01:00
Matthias Clasen
fd7667246d Merge branch 'wip/chergert/for-main' into 'main'
macos: various fixes and multi-monitor frame clocks

Closes #4736, #4735, #4732, #4733, and #4734

See merge request GNOME/gtk!4533
2022-02-28 22:13:03 +00:00
Matthias Clasen
b8cb15f28d Merge branch 'wip/carlosg/scrolledwindow-warning' into 'main'
gtkscrolledwindow: Do not try to doubly trigger deceleration

Closes #4730

See merge request GNOME/gtk!4536
2022-02-28 21:50:19 +00:00
Christian Hergert
51607ce93c macos: avoid size/origin changes when possible
If _gdk_macos_surface_move_resize() was called with various -1 parameters
we really want to avoid changing anything even if we think we know what
the value might be. Otherwise, we risk messing up in-flight operations that
we have not yet been notified of yet.

This improves the chances we place windows in an appropriate location as
they don't et screwed up before window-manager placement.
2022-02-28 13:09:57 -08:00
Christian Hergert
66284cd245 macos: start application in foreground
We need to bring the application to the foreground in multiple ways, and
this call to [NSApp activateIgnoringOtherApps:YES] ensures that we become
foreground before the first window is opened. Otherwise we end up starting
applications in the background.

Fixes #4736
2022-02-28 12:20:24 -08:00
Christian Hergert
f9faecd5b7 macos: add GDK_NOTE when surface changes monitor 2022-02-28 12:13:29 -08:00
Christian Hergert
92261b5022 macos: add GDK_NOTE for surface sizing and placement
This can be useful to debug sizing issues with the surface as well as the
"window manager" placement code.
2022-02-28 11:50:21 -08:00
Christian Hergert
91f5bfd211 macos: leave note about monitor discovery 2022-02-28 11:36:27 -08:00
Christian Hergert
63f20b173d macos: external access to display name helpers
These can be handy to print debug information when we don't have a
GdkMacosMonitor to work with.
2022-02-28 11:36:27 -08:00
Christian Hergert
25b3bd64af macos: fix redisplay of GdkPopup
This broke recently during the configure cleanups and also needed to have
the tail directions fixed again.
2022-02-28 11:36:27 -08:00
Christian Hergert
fc4d36e50a macos: fix cairo renderer with double buffering
If we are double buffering surfaces with IOSurface then we need to copy
the area that was damaged in the previous frame to the back buffer. This
can be done with IOSurface but we need to hold the read-only lock so that
we don't cause the underlying IOSurface contents to be invalidated.

Additionally, since this is only used in the context of rendering to a
GdkMacosSurface, we know the life-time of the cairo_surface_t and can
simply lock/unlock the IOSurface buffer from begin_frame/end_frame to have
the buffer flushing semantics we want.

To ensure that we don't over damage, we store the damage in begin_frame
(and copy it) and then subtract it from the next frames damage to determine
the smallest amount we need to copy (taking scale factor into account).

We don't care to modify the damage region to swapBuffers because they
already have the right contents and could potentially fall into another
tile anyway and we'd like to avoid damaging that.

Fixes #4735
2022-02-28 11:36:27 -08:00
Christian Hergert
dbede0b115 macos: add readonly IOSurfaceLock helper
This can be used to lock a surface for reading to avoid causing the
surface contents to be invalidated. This is needed when reading back from
a front-buffer to the back-buffer as is needed when using Cairo surfaces
to implement something similar to BufferAge.
2022-02-28 11:36:27 -08:00
Christian Hergert
1e40033852 macos: short-circuit on NSEventPhaseMayBegin
We only need to send a single event in this case, so just short-circuit
instead of trying to return an additional event.
2022-02-28 11:36:27 -08:00
Christian Hergert
478bf45320 macos: support mix-rate monitors
Previously, a single CVDisplayLink was used to drive updates for all
surfaces across all monitors. It used a 'best guess' rate which would
allow for updates across monitors of mixed rates. This is undesirable for
situations where you might have a 144hz monitor as it does not allow for
reaching up to that frame rate.

Instead, we want to use a per-monitor CVDisplayLink which will fire at the
rate of the monitor down to the level of updates we require. This commit
does just that.

When a surface crosses onto a new monitor, that monitor is used to drive
the GdkFrameClock.

Fixes #4732
2022-02-28 11:36:27 -08:00
Christian Hergert
dac0b7d609 macos: use video mode for refresh rate and interval
Using the mode allows better detection of refresh rate and refresh
interval for the CVDisplayLink bridge to GdkFrameClock. Using it can help
ensure that our 144hz displays can actually reach that rather than falling
back to just 60hz.

This will also need future commits to rework the displaylink source to be
per-monitor.
2022-02-28 11:36:27 -08:00
Christian Hergert
d14987e819 macos: send stop event when fingers touch
When the fingers are placed on the touchpad, we get a scroll event with
the phase NSEventPhaseMayBegin. We can use this to synthesize an is_stop
event. This results in the scrolledwindow stopping scroll with stop
gestures.

This can cause another warning as well, however, which should be addressed
from #4730.

Fixes #4733
2022-02-28 11:36:27 -08:00
Christian Hergert
3a0077f65f macos: remove emulated scroll events
We don't appear to actually need the emulated scroll events and they get
in the way of proper scrolling with the touchpad.

Fixes #4734
2022-02-28 11:36:27 -08:00
Christian Hergert
03882ef8e5 macos: do not inherit parents frame clock
Windows can end up on different monitors despite having a parent or
transient-for ancestor. We want them to be driven by the CVDisplayLink
for the best-monitor, and so this needs to be unshared.
2022-02-28 11:36:27 -08:00
Christian Hergert
505e10f3ea macos: calculate best monitor when changing screens
When we change screens, we can keep track of the best monitor so that we
can use it to register CVDisplayLink callbacks.
2022-02-28 11:36:27 -08:00
Christian Hergert
1e01444de8 macos: remove duplicated opaque_region field
This can be relied upon from GdkSurface and we do not need to keep a copy
of it. Just remove it and use the GdkSurface.opaque_region field.
2022-02-28 11:36:27 -08:00
Christian Hergert
4404c43cd3 macos: use display id when creating CVDisplayLink
Currently we're using a display link that is for all active displays which
is just the display server trying to find some timings that try to overlap
as many as possible.

That was fine for a prototype, but we really need to do better for
situations with mixed frame rate (such as 60hz and 120hz promotion
displays). Additionally, the 144hz external monitor I have will never
reach 144hz using the current design.

This is just the first step in changing this, but the goal is to have
one of these attached to each GdkMacosMonitor which we can then use to
thaw surfaces specific to that monitor.
2022-02-28 11:36:27 -08:00
Christian Hergert
92a7c7cdc3 macos: move feedback mechanisms into separate file
We will eventually be needing additional feedback from the display server
which would be nice to keep away from the rest of GdkMacosDisplay for
cleanliness sake. Particularly for feedback from mission control and other
environment factors that requires private API for proper integration.
2022-02-28 11:36:23 -08:00
Carlos Garnacho
33db142eab gtkscrolledwindow: Do not try to doubly trigger deceleration
This may come from different sources at around the same time, e.g.
a hold gesture while on overshoot. Avoid doing that if an
animation is already set.

Fixes: https://gitlab.gnome.org/GNOME/gtk/-/issues/4730
2022-02-28 20:27:43 +01:00
Carlos Garnacho
68319afd23 Merge branch 'startup-vs-xdg-activation' into 'main'
Startup tracking with xdg-activation

See merge request GNOME/gtk!3883
2022-02-28 17:29:09 +00:00
Guido Günther
25f4e597ee print-editor: Use gtk_window_present()
This lets xdg-activation work as otherwise gdk_wayland_surface_focus is
never invoked.
2022-02-28 16:55:54 +00:00
Guido Günther
db8339ca66 demo: Use gtk_window_present()
This lets xdg-activation work as otherwise gdk_wayland_surface_focus is
never invoked.
2022-02-28 16:55:54 +00:00
Guido Günther
5ba02e3459 widget-factory: Use gtk_window_present()
This lets xdg-activation work as otherwise gdk_wayland_surface_focus is
never invoked.
2022-02-28 16:55:54 +00:00
Guido Günther
999509be61 wayland: Keep startup_notification_id around long enough
When using xdg_activation we need to keep the id around until we send
the first activate to signal succesful startup.
2022-02-28 16:55:54 +00:00
Guido Günther
5dca6dce91 window: Make sure we call gdk_wayland_surface_focus
When using xdg_activation this is responsible for submitting
the activation token / startup id to the compositor.
2022-02-28 16:55:54 +00:00
Luca Bacci
d3acfa8c2b Merge branch 'gdk-win32-configure-as-needed-fullscreen' into 'main'
GdkWin32: Configure as needed when fullscreening toplevels

Closes #4631

See merge request GNOME/gtk!4506
2022-02-28 15:11:36 +00:00
Luca Bacci
c1cc8c979b Merge branch 'win32-fix-4724-gtk4' into 'main'
gdkkeys-win32: Only perform substitution as last-resort [GTK4]

See merge request GNOME/gtk!4531
2022-02-28 08:44:10 +00:00
Matthias Clasen
eed74f6ea0 Merge branch 'ci-disable-debug' into 'main'
CI: disable debug for MSVC

See merge request GNOME/gtk!4525
2022-02-27 15:45:16 +00:00
Philip Zander
e5a4b91997 gdkkeys-win32: Only perform substitution as last-resort
Instead of performing keyboard layout substitution whenever we find a matching
entry in the registry, first try to load the original layout and only attempt
substitution when that fails.

See #4724
2022-02-27 16:40:58 +01:00
Matthias Clasen
885b34d382 Merge branch 'wip/ricotz/annotations' into 'main'
gdk: Add missing out annotation on gdk_content_deserialize_finish

See merge request GNOME/gtk!4529
2022-02-27 00:50:07 +00:00
Rico Tzschichholz
3faf9d85bb gdk: Add missing out annotation on gdk_content_deserialize_finish 2022-02-26 22:05:20 +01:00
Benjamin Otte
4cd4c25c25 Merge branch 'wip/otte/for-main' into 'main'
glrenderer: Don't return NULL form render_texture()

See merge request GNOME/gtk!4522
2022-02-26 20:15:18 +00:00
Benjamin Otte
bffa5dfddd listview: Fix return_if_fail()s 2022-02-26 20:35:44 +01:00
Benjamin Otte
2fe20878c3 flattenlistmodel: Fix indentation 2022-02-26 20:35:44 +01:00
Benjamin Otte
b28c3ef3d9 renderers: Handle large viewports
When large viewports are passed to gsk_renderer_render_texture(), don't
fail (or even return NULL).

Instead, draw multiple tiles and assemble them into a memory texture.

Tests added to the testsuite for this.
2022-02-26 20:35:44 +01:00
Matthias Clasen
ed5fb4bbfe Merge branch 'try-to-fix-ci-build' into 'main'
Revert "Bump the wayland-protocols dep"

See merge request GNOME/gtk!4528
2022-02-26 18:08:38 +00:00
Matthias Clasen
2dd86aaa00 Revert "Bump the wayland-protocols dep"
This reverts commit 6a7da77980.

This is causing various build problems between wayland-protocols
and wayland-scanner.
2022-02-26 12:03:22 -05:00
Christoph Reiter
eaf952d902 CI: disable debug for MSVC
CI currently fails with "fatal error LNK1318: Unexpected PDB error; OK (0) ''"
Google tells me it might be related to hitting a memory limit. Let's try
disabling debug for now.
2022-02-26 16:32:15 +01:00
Piotr Drąg
88cb6a46f2 Update Polish translation 2022-02-26 13:29:33 +01:00
Matthias Clasen
c76b4bdc77 Merge branch 'wip/chergert/macos-add-window-accessor' into 'main'
macos: add getter for NSWindow with macOS windowing

See merge request GNOME/gtk!4509
2022-02-26 03:17:59 +00:00
Matej Urbančič
62fe4eae16 Update Slovenian translation 2022-02-25 21:13:32 +00:00
Christian Hergert
99a40de8ad macos: add getter for NSWindow with macOS windowing
There may be various reasons that an application could need access to the
underlying NSWindow that is being used to display the GdkMacosSurface
contents. This provides a minimal API to do that without exposing our
implementation details through public API.

As our rendering system is likely to change over time, we very much want
to keep GdkMacosView, GdkMacosLayer, GdkMacosTile, and GdkMacosWindow all
private implementation details which are subject to change.

As this is public API, we are a bit long-winded with the name so it is
clear what is being accessed without polluting symbol names with things
like "ns" as we used to.
2022-02-25 11:36:39 -08:00
Aleksandr Melman
b8376407a4 Update Russian translation 2022-02-25 18:38:49 +00:00
Luca Bacci
a5643b0c83 Merge branch 'gdk-win32-fix-issue-1402-gtk4' into 'main'
Fix last error reporting when calling GetClipboardOwner

Closes #1402

See merge request GNOME/gtk!4521
2022-02-25 16:54:15 +00:00
Luca Bacci
828688d5cd Fix last error reporting when calling GetClipboardOwner
Fixes https://gitlab.gnome.org/GNOME/gtk/-/issues/1402
2022-02-25 17:14:39 +01:00
Matthias Clasen
fc47b913b1 Merge branch 'wip/chergert/macos-fix-popover-tails' into 'main'
macos: fix positioning of popover tails

See merge request GNOME/gtk!4515
2022-02-25 15:50:15 +00:00
Matthias Clasen
7d8b3357a5 Merge branch 'wip/chergert/better-positioning' into 'main'
macos: fix positioning of popover tails

See merge request GNOME/gtk!4516
2022-02-25 15:49:50 +00:00
Matthias Clasen
e0b98bc7de Merge branch 'wip/chergert/macos-fix-titled-resize' into 'main'
macos: fix origin during live resize of titled window

See merge request GNOME/gtk!4519
2022-02-25 15:49:07 +00:00
Matthias Clasen
493b145496 Merge branch 'wip/chergert/macos-unfullscreen' into 'main'
macos: restore unfullscreen frame with style mask

See merge request GNOME/gtk!4518
2022-02-25 15:48:44 +00:00
Matthias Clasen
1b2c11d7f5 Merge branch 'wip/chergert/fix-macos-overshoot' into 'main'
macos: fix kinetic scrolling with overshoot

See merge request GNOME/gtk!4517
2022-02-25 14:37:45 +00:00
Christian Hergert
a56828237a macos: fix origin during live resize of titled window
When using server-side-decorations, we need to avoid potential cycles with
compute-size as it may not have the new sizing information yet. We can
just short circuit during "live resize" to get that effect.

Fixes poor window resizing from top-left on titled windows.
2022-02-24 23:29:18 -08:00
Christian Hergert
56e2a7e8bb macos: restore unfullscreen frame with style mask
This doesn't give us appropriate results if we use the window delegate.
Instead, we need to adjust the frame at the same time we change the
style mask so that we end up in the same location.
2022-02-24 22:32:43 -08:00
Christian Hergert
f278f3610b macos: fix kinetic scrolling with overshoot
Previously we had issues on macos where the overshoot would keep showing.
To fix this we need to actually use discrete events instead of the
generated deltas from macOS in the scroll wheel case. Additionally, we need
to drop the kinetic momentum events from macOS and rely on the gtk kinetic
events which are already happening anyway. We also need to submit the
is_stop event for the GDK_SCROLL_SMOOTH case when we detect it.

To keep the discrete scroll events correct, we need to alter the hack in
gtkscrolledwindow.c to use the same path as other platforms except for
when a smooth scroll event is in place. In the future, I would imagine that
this falls into the boundary of high-precision scrolling and would share
the same code paths as other platforms.

With all of these in place, kinetic scrolling with overshoot appears the
same on macOS as other platforms.
2022-02-24 18:58:48 -08:00
Christian Hergert
c111e633e9 macos: remove unused code 2022-02-24 18:58:07 -08:00
Christian Hergert
eea7cf30bb macos: create new windows with slight origin offset
When creating new windows, it is better if we create them with a slight
offset to where they were created before so that they are visible to the
user separately from what they might be overshadowing.
2022-02-24 18:58:07 -08:00
Christian Hergert
36bdcfaccb macos: fix positioning of popover tails
This broke with the previous fixes for initial window positioning. We need
the initial positioning so that tails will be displayed correctly when the
popover surface is displayed.
2022-02-24 16:29:53 -08:00
Luming Zh
45bb820656 Update Chinese (China) translation 2022-02-25 00:07:39 +00:00
Fran Dieguez
617deb8bb6 Update Galician translation 2022-02-24 12:53:57 +00:00
Matthias Clasen
8efcd34dbe Merge branch 'ebassi/unexport-x11' into 'main'
Remove unnecessary warning

See merge request GNOME/gtk!4512
2022-02-24 12:32:41 +00:00
Daniel Mustieles
a78b573f8b Updated Spanish translation 2022-02-24 12:54:02 +01:00
Emmanuele Bassi
226f0e0567 Remove unnecessary warning
Unexporting the window handle on X11 is a no-op, so there's no need
to emit a warning.
2022-02-24 02:04:06 +00:00
Rafael Fontenelle
4304a494ae Update Brazilian Portuguese translation 2022-02-23 23:54:08 +00:00
Matthias Clasen
b71ff21530 Merge branch 'bump-wayland-dep' into 'main'
Bump the wayland-protocols dep

See merge request GNOME/gtk!4511
2022-02-23 21:05:01 +00:00
Matthias Clasen
6a7da77980 Bump the wayland-protocols dep
Bump the dep to 1.25, so we can add support
for toplevel bounds.
2022-02-23 14:30:49 -05:00
Matthias Clasen
c5f92340ee Fix up tests for version bump 2022-02-23 14:29:48 -05:00
Hugo Carvalho
572a884e90 Update Portuguese translation 2022-02-23 11:29:15 +00:00
Emin Tufan Çetin
69bc9d0702 Update Turkish translation 2022-02-23 09:42:06 +00:00
Yuri Chornoivan
34ff9e359b Update Ukrainian translation 2022-02-23 07:10:19 +00:00
Benjamin Otte
de705c2a2b Add 4.8 version macros 2022-02-22 22:55:48 -05:00
Benjamin Otte
d1102f586c build: Set version to 4.7 2022-02-22 22:55:42 -05:00
Matthias Clasen
bcb6cf04ed Merge branch 'wip/chergert/macos-window-manager' into 'main'
macos: improve placement of windows

See merge request GNOME/gtk!4510
2022-02-23 03:53:33 +00:00
Matthias Clasen
c9dbb30aff Merge branch 'ebassi/docs-related' into 'main'
docs: Split dependencies from related libraries

See merge request GNOME/gtk!4474
2022-02-23 03:28:47 +00:00
Matthias Clasen
2c88797195 Merge branch 'wip/chergert/macos-iosurface' into 'main'
macos: modernize rendering with CALayer and IOSurface

See merge request GNOME/gtk!4477
2022-02-23 03:10:43 +00:00
Christian Hergert
89a351fd66 macos: improve placement of windows
This does some very basic window management so that we place surfaces in
locations where they can actually be interacted with correctly.
2022-02-22 18:43:46 -08:00
Christian Hergert
e1d3d01e2f macos: update CGL context when surface resizes 2022-02-22 13:15:25 -08:00
Christian Hergert
76a58c40db macos: force pixel format without depth/stencil
We don't need either depth or stencil buffers, so we want a pixel format
without them so that things like glClear() can do less work.
2022-02-22 13:09:30 -08:00
Yosef Or Boczko
3b0ceeb09a Update Hebrew translation 2022-02-22 20:22:59 +00:00
Danial Behzadi
f95e082186 Update Persian translation 2022-02-22 20:08:03 +00:00
Christian Hergert
df8e2bc0a0 macos: only invalidate tiles when size changes
If the size changes, we need to relayout the tiles. Otherwise we can keep
using what we had before. Generally, that shouldn't happen, but the
previous check was failing in a number of ways.
2022-02-22 12:01:29 -08:00
Christian Hergert
42164fa8bb macos: reload IOSurface when monitor configuration changes
We also want to reload buffer contents if the display server changes the
monitor configuration, such as after changing resolution or orientation.
2022-02-22 12:01:29 -08:00
Christian Hergert
6016e17a38 macos: double buffer IOSurface
It looks like, particularly on the M1, we might need to double buffer the
contents of the IOSurface<->OpenGL texture bindings. This doesn't appear
to show up on the Intel macbooks I've tried, but I've seen it in the wild
on an M1.
2022-02-22 12:01:29 -08:00
Christian Hergert
b2de83efcb macos: restore key window after hiding popup
This fixes the focus returning to the parent window after the popup has
been hidden in the form of being a "Key Window" in macOS.
2022-02-22 12:01:29 -08:00
Christian Hergert
493f90499b macos: fix window drag across mixed-scale monitors
If we have a 2x scale laptop with a 1x scale external display, we would
need to create a new IOSurface for the external display once it crosses
a boundary, otherwise we won't have something capable of displaying
correctly on the second monitor.
2022-02-22 12:01:29 -08:00
Christian Hergert
8b71cff71d macos: use CALayer and IOSurface for rendering
This provides a major shift in how we draw both when accelerated OpenGL
as well as software rendering with Cairo. In short, it uses tiles of Core
Animation's CALayer to display contents from an OpenGL or Cairo rendering
so that the window can provide partial damage updates. Partial damage is
not generally available when using OpenGL as the whole buffer is flipped
even if you only submitted a small change using a scissor rect.

Thankfully, this speeds up Cairo rendering a bit too by using IOSurface to
upload contents to the display server. We use the tiling system we do for
OpenGL which reduces overall complexity and differences between them.

A New Buffer
============

GdkMacosBuffer is a wrapper around an IOSurfaceRef. The term buffer was
used because 1) surface is already used and 2) it loosely maps to a
front/back buffer semantic.

However, it appears that IOSurfaceRef contents are being retained in
some fashion (likely in the compositor result) so we can update the same
IOSurfaceRef without flipping as long as we're fast. This appears to be
what Chromium does as well, but Firefox uses two IOSurfaceRef and flips
between them. We would like to avoid two surfaces because it doubles the
GPU VRAM requirements of the application.

Changes to Windows
==================

Previously, the NSWindow would dynamically change between different
types of NSView based on the renderer being used. This is no longer
necessary as we just have a single NSView type, GdkMacosView, which
inherits from GdkMacosBaseView just to keep the tedius stuff separate
from the machinery of GdkMacosView. We can merge those someday if we
are okay with that.

Changes to Views
================

GdkMacosCairoView, GdkMacosCairoSubView, GdkMacosGLView have all been
removed and replaced with GdkMacosView. This new view has a single
CALayer (GdkMacosLayer) attached to it which itself has sublayers.

The contents of the CALayer is populated with an IOSurfaceRef which
we allocated with the GdkMacosSurface. The surface is replaced when
the NSWindow resizes.

Changes to Layers
=================

We now have a dedicated GdkMacosLayer which contains sublayers of
GdkMacosTile. The tile has a maximum size of 128x128 pixels in device
units.

The GdkMacosTile is partitioned by splitting both the transparent
region (window bounds minus opaque area) and then by splitting the
opaque area.

A tile has either translucent contents (and therefore is not opaque) or
has opaque contents (and therefore is opaque). An opaque tile never
contains transparent contents. As such, the opaque tiles contain a black
background so that Core Animation will consider the tile's bounds as
opaque. This can be verified with "Quartz Debug -> Show opaque regions".

Changes to Cairo
================

GTK 4 cannot currently use cairo-quartz because of how CSS borders are
rendered. It simply causes errors in the cairo_quartz_surface_t backend.

Since we are restricted to using cairo_image_surface_t (which happens to
be faster anyway) we can use the IOSurfaceBaseAddress() to obtain a
mapping of the IOSurfaceRef in user-space. It always uses BGRA 32-bit
with alpha channel even if we will discard the alpha channel as that is
necessary to hit the fast paths in other parts of the platform. Note
that while Cairo says CAIRO_FORMAT_ARGB32, it is really 32-bit BGRA on
little-endian as we expect.

OpenGL will render flipped (Quartz Native Co-ordinates) while Cairo
renders with 0,O in the top-left. We could use cairo_translate() and
cairo_scale() to reverse this, but it looks like some cairo things may
not look quite as right if we do so. To reduce the chances of one-off
bugs this continues to draw as Cairo would normally, but instead uses
an CGAffineTransform in the tiles and some CGRect translation when
swapping buffers to get the same effect.

Changes to OpenGL
=================

To simplify things, removal of all NSOpenGL* related components have
been removed and we strictly use the Core GL (CGL*) API. This probably
should have been done long ago anyay.

Most examples found in the browsers to use IOSurfaceRef with OpenGL are
using Legacy GL and there is still work underway to make this fit in
with the rest of how the GSK GL renderer works.

Since IOSurfaceRef bound to a texture/framebuffer will not have a
default framebuffer ID of 0, we needed to add a default framebuffer id
to the GdkGLContext. GskGLRenderer can use this to setup the command
queue in such a way that our IOSurface destination has been
glBindFramebuffer() as if it were the default drawable.

This stuff is pretty slight-of-hand, so where things are and what needs
flushing when and where has been a bit of an experiment to see what
actually works to get synchronization across subsystems.

Efficient Damages
=================

After we draw with Cairo, we unlock the IOSurfaceRef and the contents
are uploaded to the GPU. To make the contents visible to the app,
we must clear the tiles contents with `layer.contents=nil;` and then
re-apply the IOSurfaceRef. Since the buffer has likely not changed, we
only do this if the tile overlaps the damage region.

This gives the effect of having more tightly controlled damage regions
even though updating the layer would damage be the whole window (as it
is with OpenGL/Metal today with the exception of scissor-rect).

This too can be verified usign "Quartz Debug -> Flash screen udpates".

Frame Synchronized Resize
=========================

In GTK 4, we have the ability to perform sizing changes from compute-size
during the layout phase. Since the macOS backend already tracks window
resizes manually, we can avoid doing the setFrame: immediately and instead
do it within the frame clock's layout phase.

Doing so gives us vastly better resize experience as we're more likely to
get the size-change and updated-contents in the same frame on screen. It
makes things feel "connected" in a way they weren't before.

Some additional effort to tweak gravity during the process is also
necessary but we were already doing that in the GTK 4 backend.

Backporting
===========

The design here has made an attempt to make it possible to backport by
keeping GdkMacosBuffer, GdkMacosLayer, and GdkMacosTile fairly
independent. There may be an opportunity to integrate this into GTK 3's
quartz backend with a fair bit of work. Doing so could improve the
situation for applications which are damage-rich such as The GIMP.
2022-02-22 12:01:29 -08:00
Christian Hergert
f9268e8137 gsk/gl: support non-standard default framebuffer
There are situations where our "default framebuffer" is not actually
zero, yet we still want to apply a scissor rect.

Generally, 0 is the default framebuffer. But on platforms where we need
to bind a platform-specific feature to a GL_FRAMEBUFFER, we might have a
default that is not 0. For example, on macOS we bind an IOSurfaceRef to
a GL_TEXTURE_RECTANGLE which then is assigned as the backing store for a
framebuffer. This is different than using gsk_gl_renderer_render_texture()
in that we don't want to incur an extra copy to the destination surface
nor do we even have a way to pass a texture_id into render_texture().
2022-02-22 12:01:24 -08:00
Christian Hergert
b4b282dc81 macos: fix allocation for filechoosernative filter
The GtkFileCHooserNativeQuartz injects a NSComboBox into the NSSavePanel
(which is displayed in a remote process since 10.15 whether or not you are
a sandboxed application). The style has changed and we need more space
here to not clip part of the combobox out of view.

I tried every size from 22 to 30 and this seemed to look the most natural
without skewing the location of the text within the combobox.
2022-02-22 11:53:33 -08:00
Matthias Clasen
d4d328f96f Merge branch 'scale-button-empty-icon-list' into 'main'
Don't crash when updating the icon on a `GtkScaleButton` with a non-`NULL` empty icon list

See merge request GNOME/gtk!4475
2022-02-22 19:39:32 +00:00
Matthias Clasen
553eb55f8a Merge branch 'wip/hadess/app-id-inspector-4' into 'main'
inspector: Show app ID and resource path in the General tab

See merge request GNOME/gtk!4493
2022-02-22 19:37:36 +00:00
Matthias Clasen
9ea43096d4 Merge branch 'wip/chergert/macos-fix-event-filter' into 'main'
macos: improve event filtering for foreign panels

See merge request GNOME/gtk!4495
2022-02-22 19:36:43 +00:00
Matthias Clasen
e9ffe8f212 Merge branch 'wip/chergert/macos-fix-fullscreen' into 'main'
macos: allow windows to enter fullscreen

See merge request GNOME/gtk!4494
2022-02-22 19:36:20 +00:00
Matthias Clasen
931be7d729 Merge branch 'optimise-png-premultiply' into 'main'
gdk: Specialise RGBA8 → premultiplied BGRA8 conversion

See merge request GNOME/gtk!4481
2022-02-22 19:25:41 +00:00
Matthias Clasen
378bb481fa Merge branch 'ebassi/graphene-build-opts' into 'main'
build: Disable graphene tests

See merge request GNOME/gtk!4500
2022-02-22 18:05:14 +00:00
Matthias Clasen
8f83c7e255 Merge branch 'emoji-40' into 'main'
emoji: Update data to CLDRv40 and add more locales

Closes #4568

See merge request GNOME/gtk!4507
2022-02-22 18:04:24 +00:00
Matthias Clasen
3c99b50d2c Merge branch 'wip/chergert/gsk-gl-less-glClear' into 'main'
gsk/gl: avoid clearing opaque regions

See merge request GNOME/gtk!4504
2022-02-22 17:56:40 +00:00
Matthias Clasen
9fccbeaa75 Merge branch 'wip/chergert/macos-fix-backdrop' into 'main'
macos: fix backdrop when displaying popover

See merge request GNOME/gtk!4505
2022-02-22 17:54:20 +00:00
Matthias Clasen
d35bac452b Merge branch 'wip/chergert/macos-fix-toplevel-resize' into 'main'
macos: fix configure, move-resize, and compute-size

See merge request GNOME/gtk!4486
2022-02-22 13:10:34 +00:00
Kévin Commaille
d8c79e91a2 emoji: Add more locales
Based on the locales that are at least 85% translated in Damned Lies:
https://l10n.gnome.org/releases/gnome-41/
Limited by the locales available in emojibase

Closes #4568
2022-02-22 11:28:15 +01:00
Kévin Commaille
7f5a249056 emoji: Update data to CLDR v40
Based on emojibase-data v7.0.1
Contains the changes in Unicode 14.0

https://unicode.org/versions/Unicode14.0.0/
https://cldr.unicode.org/index/downloads/cldr-40
https://github.com/milesj/emojibase/blob/b85382524c/packages/data/CHANGELOG.md
2022-02-22 11:28:15 +01:00
Kévin Commaille
70ce353a58 emoji: Fix the convert-emoji program
The annotation field has been renamed to label in emojibase-data

https://github.com/milesj/emojibase/blob/b85382524c/packages/data/CHANGELOG.md
2022-02-22 11:28:06 +01:00
Luca Bacci
ab65e8e178 GdkWin32: Configure as needed when going fullscreen
Apply the fixes made by Chun-Wei Fan in [1] also for fullscreening /
unfullscreen. Fixes https://gitlab.gnome.org/GNOME/gtk/-/issues/4631

Also set the SWP_FRAMECHANGED flag as written by Raymond Chen in "How
do I switch a window between normal and fullscreen?" [2]

> An important flag to pass here is SWP_FRAME­CHANGED, which tells
> the window manager to recalculate the window decorations (which we
> need it to do because we just changed them).

References:
[1] - https://gitlab.gnome.org/GNOME/gtk/-/merge_requests/3712
[2] - https://devblogs.microsoft.com/oldnewthing/20100412-00/?p=14353
2022-02-22 09:15:28 +01:00
Christian Hergert
c0ede8d46e macos: fix backdrop when displaying popover
Previously, the popover would cause the window to go into the :backdrop
state which is not what we want for consistency with other platforms. This
fixes that by walking up the surface chain when we get notified of
loosing or acquiring "key" input from the display server.
2022-02-22 00:08:37 -08:00
Luca Bacci
8f02ea39e5 Merge branch 'gdk-win32-implicit-grabs-cleanup' into 'main'
GdkWin32: Remove implicit_grab_surface

Closes #4188

See merge request GNOME/gtk!4503
2022-02-22 07:53:54 +00:00
Luca Bacci
8a8cd4e248 Merge branch 'win32-ime-fix-popup-positioning' into 'main'
Win32 IME: Fix popup positioning

Closes #374 and #2338

See merge request GNOME/gtk!4501
2022-02-22 07:52:59 +00:00
Christian Hergert
08d0575ed0 gsk/gl: avoid clearing opaque regions
If the rendering operation is over an opaque region, we can potentially
avoid clearing a large section of the framebuffer destination. Some cases
you do want to clear, such as when clearing the whole contents as some
drivers have fast paths for that to avoid bringing data back into the
framebuffer.
2022-02-21 23:43:17 -08:00
Luca Bacci
43476c09ed GdkWin32: Remove implicit_grab_surface 2022-02-21 17:38:50 +01:00
Luca Bacci
6123212a68 Win32 IME: Fix popup position 2022-02-21 16:13:06 +01:00
Luca Bacci
6106207b93 Win32 IME: Rename a variable 2022-02-21 15:53:22 +01:00
Luca Bacci
b5036faa2a Win32 IME: Keep track of the client widget 2022-02-21 15:53:13 +01:00
Luca Bacci
56fd3af4d0 Win32 IME: Remove the get_window_position util function
It always returns (0, 0)
2022-02-21 15:49:52 +01:00
Emmanuele Bassi
26beab6064 build: Disable graphene tests
When building Graphene as a subproject we don't really need
to build tests. Disabling tests also removes the dependency
on mutest.
2022-02-21 13:41:40 +00:00
Emmanuele Bassi
f41fe7b8e4 Merge branch 'msvc-cmake-dep' into 'main'
Meson: Use CMake more for finding deps on Visual Studio-like builds

See merge request GNOME/gtk!4499
2022-02-21 13:37:12 +00:00
Luca Bacci
7d6797c9ed Merge branch 'forward-port-mr-775-to-gtk4' into 'main'
gtkimcontextime.c: Fix preedit window placement on HiDPI

See merge request GNOME/gtk!4498
2022-02-21 12:01:21 +00:00
Chun-wei Fan
2e34d62111 meson.build: Use CMake to find libjpeg on MSVC-like builds
One may be using IJG libjpeg or libjpeg-turbo to build GTK, and their
build files may or may not generate pkg-config files for us.  To make
things easier, we can make use of CMake's built-in support for finding
IJG libjpeg or libjpeg-turbo.
2022-02-21 17:53:50 +08:00
Chun-wei Fan
6eda5deeff meson.build: Use CMake to find libtiff on MSVC-like
The CMake build files for libtiff may or may not generate pkg-config
files for us, so we can use Meson's CMake support to help us find
libtiff, as CMake has built-in support for finding libtiff.
2022-02-21 17:53:40 +08:00
Chun-wei Fan
83b98738b6 meson.build: Consolidate items with MSVC-like compilers
Add a variable in meson.build that covers Visual Studio-like compilers,
so that we can use it to help us find depedencies using CMake rather
than via pkg-config, where applicable.

Change the existing use case for finding libpng accordingly.
2022-02-21 17:53:31 +08:00
Emin Tufan Çetin
a07455aa0d Update Turkish translation 2022-02-20 15:04:41 +00:00
Emin Tufan Çetin
49a4d27245 Update Turkish translation 2022-02-20 14:47:56 +00:00
Danial Behzadi
ff59bf356b Update Persian translation 2022-02-20 11:14:09 +00:00
Chun-wei Fan
c6ce05b782 gtkimcontextime.c: Fix preedit window placement on HiDPI
We must also take the scaling factor into account for placing the IME
preedit window that is often used for Chinese and Japanese input on
Windows.
2022-02-19 18:31:28 +01:00
Christian Hergert
db77204a52 macos: improve event filtering for foreign panels
We might have panels with controls in them where the window is running in
another process. The control could have a wrapper window which we would
see from this process. This can happen with the GtkFileChooserNative, but
any NSSavePanel in macOS 10.15+ is out of process (not just sandboxed
applications).
2022-02-18 03:39:52 -08:00
Christian Hergert
4c08d1643f macos: fix configure, move-resize, and compute-size
This significantly cleans up how we handle various move-resize, compute-
size, and configure (notification of changes) in the macOS GDK backend.

Originally when prototyping this backend, there were some bits that came
over from the quartz backend and some bits which did not. It got confusing
and so this makes an attempt to knock down all that technical debt.

It is much simpler now in that the GdkMacosSurface makes requests of the
GdkMacosWindow, and the GdkMacosWindow notifies the GdkMacosSurface of
changes that happen.

User resizes are delayed until the next compute-size so that we are much
closer to the layout phase, reducing chances for in-between frames.

This also improves the situation of leaving maximized state so that a
grab and drag feels like you'd expect on other platforms.

I removed the opacity hack we had in before, because that is all coming
out anyway and it's a bit obnoxious to maintain through the async flows
here.
2022-02-18 02:50:46 -08:00
Christian Hergert
592436503c macos: allow windows to enter fullscreen
This fixes GTK's NSWindow for toplevels so that they are allowed to enter
fullscreen. We were already handlign the state transitions from the
setStyleMask: halper, but we didn't previously tell the window we are
allowed to transition into that.

There is a bit of a mismatch here in that GTK doesn't have any such flag
that determines if a window is "allowed" by policy to enter fullscreen
since window managers on Linux are free to do that at will.
2022-02-18 01:54:10 -08:00
Bastien Nocera
1877bb8a27 inspector: Show app ID and resource path in the General tab
This makes it easier to figure out those values (which are mentioned in
the GtkApplication documentation) rather than working that out from the
way they're generated (or documented as being generated).
2022-02-17 15:14:16 +01:00
Matthias Clasen
67a5120b5b Merge branch 'wip/chergert/macos-gst-cgl' into 'main'
media: support OpenGL-based video playback on macOS

See merge request GNOME/gtk!4491
2022-02-17 13:54:42 +00:00
Matthias Clasen
9d8f56edaa Merge branch 'wip/chergert/macos-fix-popup-input' into 'main'
macos: fix keyboard input on popovers

See merge request GNOME/gtk!4490
2022-02-17 13:53:04 +00:00
Christian Hergert
7ec9c5181d media: support OpenGL-based video playback on macOS
If we have GStreamer on macOS we likely have support for CGL to get an
OpenGL context we can use. This provides the missing pieces to get
accelerated video playback in gtk4-widget-factory working.
2022-02-16 21:31:20 -08:00
Christian Hergert
853ef43dae macos: fix keyboard input on popovers
GdkPopup can also become the "key" window (just not the "main" window).
2022-02-16 17:53:59 -08:00
Emmanuel Gil Peyrot
1fdf5b7cf8 gdk: Optimise RGBA8 → premultiplied BGRA8 for ARM
This more than halves the total runtime of this function since the
previous commit, from 8.36% to 4.02%, and is most likely memory
bandwidth limited on this specific board now.

I tried to do a SSE2 version as well, but couldn’t find any equivalent
of the LD4/ST4 ARM instruction.
2022-02-16 16:36:33 +01:00
Emmanuel Gil Peyrot
0e3ed7a738 gdk: Specialise RGBA8 → premultiplied BGRA8 conversion
On x86 on a Kaby Lake CPU, this makes it go from 6.63% of the total
execution time (loading some PNGs using the cairo backend) down to
3.20%.

On ARM on a Cortex-A7, on the same workload, this makes it go from 57%
to 8.36%.
2022-02-16 16:35:39 +01:00
Matthias Clasen
9c1a66518b Merge branch 'wip/chergert/for-macos-1' into 'main'
macos: various correctness fixes

See merge request GNOME/gtk!4485
2022-02-16 13:54:43 +00:00
Matthias Clasen
280544b874 Merge branch 'wip/baedert/for-master' into 'main'
gtkgstpaintable: Handle a NULL value

See merge request GNOME/gtk!4484
2022-02-16 13:48:51 +00:00
Christian Hergert
3c9687fcf1 macos: add helper to check if surface is opaque 2022-02-16 03:08:55 -08:00
Christian Hergert
f207402228 macos: use input_region to specify tracking areas
We want our tracking area to be limited to the input region so that we
don't pass along events outside of them for the window. This improves the
chances we click-out of a popover with a large shadow.

This still doesn't let us pass-through clicks for large shadows on top-
level windows though.
2022-02-16 03:07:51 -08:00
Christian Hergert
a080f1197a macos: ignore mouse events outside tracking area
We also need to ignore events outside the tracking areas when we are
translating them from NSevent into GdkEvent.
2022-02-16 03:06:51 -08:00
Christian Hergert
8f0b9bf5ae macos: fix incorrect signal disconnect 2022-02-16 01:46:25 -08:00
Timm Bäder
b74d3c2221 gtkgstpaintable: Handle a NULL value
gst_element_factory_make can return NULL.
2022-02-16 10:02:24 +01:00
Benjamin Otte
49b0ee21c1 Merge branch 'wip/otte/for-main' into 'main'
glcontext: Remove leftover function call

Closes #4697

See merge request GNOME/gtk!4483
2022-02-16 03:07:05 +00:00
Benjamin Otte
481634930c glcontext: Remove leftover function call
That call should have been removed way back when.

Add a testcase to make sure this keeps working.

Fixes #4697
2022-02-16 03:48:15 +01:00
Christian Hergert
d58c038fe8 macos: remove assertion from external API
We only should be asserting in static functions. Furthermore, this function
did not need to have GDK_BEGIN_MACOS_ALLOC_POOL as nothing is being
allocated there which would cause pooling to get used.
2022-02-15 12:38:07 -08:00
Christian Hergert
056e9012d2 macos: improve monitor detection at display coordinates
This needs to handle the boundary case where the value is exactly equal
to the edge of a rectangle (which gdk_rectangle_contains_point() does not
consider to be containing). However, if there is a monitor in the list
that is a better match, we still want to prefer it.
2022-02-15 12:38:07 -08:00
Benjamin Otte
82e4690564 Merge branch 'viewport-scroll-to-focus' into 'main'
scrolledwindow: Set scroll-to-focus on viewports

See merge request GNOME/gtk!4356
2022-02-15 16:05:32 +00:00
Maximiliano Sandoval R
8dc2c4b24a viewport: Set scroll-to-focus to TRUE by default
In GTK 3 this was the default.
2022-02-15 16:29:08 +01:00
Christian Hergert
3e913ff16e Merge branch 'mac-scrolling-fix' into 'main'
gdk: fix reversed and sluggish scrolling on MacOS

See merge request GNOME/gtk!4479
2022-02-14 23:00:27 +00:00
Andy Russell
37702af22b gdk: fix reversed and sluggish scrolling on MacOS
When using an external mouse on MacOS, the scrolling behavior is
reversed from the user's scrolling preference. Additionally, it is
noticeably sluggish.

This commit fixes both issues by negating the deltas and multiplying
them by 32 before constructing a new scroll event. 32 seems to be the
"traditional" scaling factor according to [Druid], but I'm not sure
where that value actually comes from. Regardless, scaling the deltas by
this amount makes scrolling feel a lot more responsive in the GTK demos.

Scrolling with a trackpad is not affected by either issue because it
triggers a different code path that uses more precise deltas, and
already negates them.

[Druid]: https://linebender.gitbook.io/linebender-graphics-wiki/mouse-wheel#external-mouse-wheel-vs-trackpad
2022-02-14 14:05:39 -05:00
Benjamin Otte
12908ab863 docs: Add Since annotations to GDK_VERSION macros 2022-02-14 00:30:50 +01:00
Matej Urbančič
4cb599f378 Update Slovenian translation 2022-02-13 18:58:22 +00:00
Matej Urbančič
fe210fb0dd Update Slovenian translation 2022-02-13 18:56:28 +00:00
Asier Sarasua Garmendia
1fee30af36 Update Basque translation 2022-02-13 09:22:58 +00:00
Sebastian Dröge
3f329b2d0f Don't crash when updating the icon on a GtkScaleButton with a non-NULL empty icon list 2022-02-13 11:16:32 +02:00
Marek Černocký
1fd03acf9d Updated Czech translation 2022-02-12 19:48:40 +01:00
Benjamin Otte
a26c1a5f0d widget-factory: Make <F11> toggle fullscreen 2022-02-12 19:05:19 +01:00
Emmanuele Bassi
7a608bda27 docs: Split dependencies from related libraries
We currently list everything as a dependencies, regardless of whether
it actually is; this is a source of confusion for users that read the
GTK documentation.

Gi-docgen has a new "related" key in the project configuration which
allows us to list libraries that are merely related to the namespace
we are documenting; the "dependencies" key is used to document the
actual namespace dependencies, now.
2022-02-12 17:28:00 +00:00
Jordi Mas i Hernandez
c400dce0b1 Update Catalan translation 2022-02-12 14:41:46 +00:00
Matthias Clasen
5912b2d64a Merge branch 'wip/chergert/fix-text-overdraw' into 'main'
css: reduce overdraws from "textview > text"

See merge request GNOME/gtk!4472
2022-02-12 08:34:18 +00:00
Christian Hergert
e38e8ed73e css: reduce overdraws from "textview > text"
This was causing us to draw the same background content twice which is a
significant amount of bits to flip in the GPU for maximized windows,
especially twice.
2022-02-11 23:06:16 -08:00
Matthias Clasen
5088103d31 4.6.1 2022-02-11 20:09:15 -05:00
Matthias Clasen
76b185e6f6 Merge branch 'wip/chergert/popover-opaque-region' into 'main'
add opaque regions to popovers

Closes #4689

See merge request GNOME/gtk!4468
2022-02-11 23:16:43 +00:00
Christian Hergert
f3999f7ebf popover: use GtkNative opaque region API
This updates GtkPopover to use the new GtkNative abstraction for
reporting opaque regions of the window, in hopes that it can speed
up compositors for things like animated lists, menu transitions,
and more.

Fixes #4689
2022-02-11 14:37:46 -08:00
Christian Hergert
f8e7ecfde1 window: use GtkNative API to update opaque region
This switches to using the new GtkNative machinery for updating the
opaque region. Some amount of local calculation is still required for
determining when we should apply shadows, and this inherits what was
done previous for that.

Related #4689
2022-02-11 14:37:46 -08:00
Christian Hergert
cc49e044a5 native: add API to update opaque region
This abstracts the machinery to update the opaque region for a GtkWindow
into GtkNative so it may be used from other native impelementations such
as GtkPopover.

Related #4689
2022-02-11 14:37:43 -08:00
Matthias Clasen
9205193147 Merge branch 'bilelmoussaoui/entry-completion' into 'main'
entry completion: add checks that entry is set already

See merge request GNOME/gtk!4450
2022-02-11 17:49:26 +00:00
Matthias Clasen
124d689f45 Merge branch 'enum-docs' into 'main'
docs: Use links in enums

See merge request GNOME/gtk!4452
2022-02-11 17:35:42 +00:00
Matthias Clasen
d2a2591d28 Merge branch 'bilelmoussaoui/g-i' into 'main'
g-i: add a couple of missing nullable annotations

See merge request GNOME/gtk!4470
2022-02-11 17:33:05 +00:00
Carlos Garnacho
64a1a1dd6b Merge branch 'primary' into 'main'
gdk: don't leak wayland primary selection offers

See merge request GNOME/gtk!4458
2022-02-11 14:29:19 +00:00
Bilal Elmoussaoui
3b383569a4 g-i: Add nullable annotations to EventControllerKey::im-context
Fixes https://github.com/gtk-rs/gtk4-rs/issues/874
2022-02-11 12:59:55 +01:00
Bilal Elmoussaoui
c2fe438676 g-i: Add nullable annotations to CellArea getters
Fixes https://github.com/gtk-rs/gtk4-rs/issues/891
2022-02-11 12:55:28 +01:00
Emmanuele Bassi
0ade146e26 Merge branch 'bilelmoussaoui/layout-manager' into 'main'
layout manager: add a check if the widget exists

See merge request GNOME/gtk!4469
2022-02-11 11:51:44 +00:00
Bilal Elmoussaoui
ba266325d0 g-i: Mark FileChooser [s|g]et_current_[folder|name] as nullable
The code seems to already check if folder/name is NULL
Fixes https://github.com/gtk-rs/gtk4-rs/issues/896
2022-02-11 12:21:58 +01:00
Bilal Elmoussaoui
e6322e177e g-i: Mark get_print_settings as nullable
Fixes https://github.com/gtk-rs/gtk4-rs/issues/880
2022-02-11 12:07:54 +01:00
Maximiliano Sandoval R
080a4cda49 docs: Use links in enums
Properties already refer to their object, so

    [property@Widget:sensitive] property on [class@Widget]

is redundant.
2022-02-11 12:07:09 +01:00
Bilal Elmoussaoui
6b63868641 g-i: mark get_selected_printer as nullable
There is no selected printer if the user closes the dialog
Fixes https://github.com/gtk-rs/gtk4-rs/issues/882
2022-02-11 12:05:42 +01:00
Bilal Elmoussaoui
cb710f1999 g-i: mark EventController::name as nullable
Fixes https://github.com/gtk-rs/gtk4-rs/issues/893
2022-02-11 12:02:07 +01:00
Bilal Elmoussaoui
85bb9aaefc g-i: add nullable annotation to gtk_single_selection_get_model 2022-02-11 11:56:40 +01:00
Bilal Elmoussaoui
6c02017212 layout manager: add a check if the widget exists
Avoid a crash when calling _gtk_widget_get_first_child
Fixes https://github.com/gtk-rs/gtk4-rs/issues/889
2022-02-11 11:44:16 +01:00
Matthias Clasen
90bccf4e82 Merge branch 'fix-wayland-subproject-build' into 'main'
NEWS: Updates

See merge request GNOME/gtk!4466
2022-02-10 21:57:27 +00:00
Matthias Clasen
18db7ad470 NEWS: Updates 2022-02-10 15:06:37 -05:00
Julian Orth
468ddd4d49 gdk: don't leak wayland primary selection offers
Signed-off-by: Julian Orth <ju.orth@gmail.com>
2022-02-10 20:44:32 +01:00
Matthias Clasen
ff4b5c8996 Merge branch 'fix-wayland-subproject-build' into 'main'
Fix build with wayland-protocols subproject

Closes #4530

See merge request GNOME/gtk!4465
2022-02-10 19:13:33 +00:00
Matthias Clasen
06aa640664 Fix build with wayland-protocols subproject
The missing files() was pointed out in #4530.

Fixes: #4530
2022-02-10 13:21:28 -05:00
Matthias Clasen
9f24229f82 Merge branch 'column-view-column-new-nullable-factory' into 'main'
Allow passing a `NULL` factory to `gtk_column_view_column_new()`

See merge request GNOME/gtk!4454
2022-02-10 11:42:38 +00:00
Matthias Clasen
214370ee23 Merge branch 'icon-view-drag-dest-item-nullable' into 'main'
Mark `path` out parameter of `gtk_icon_view_get_drag_dest_item()` as `(nullable)`

See merge request GNOME/gtk!4451
2022-02-10 11:24:04 +00:00
Matthias Clasen
217d817408 Merge branch 'gwagner/gtkbuilder-rng' into 'main'
tools: updated gtk4builder.rng to current state

See merge request GNOME/gtk!4457
2022-02-09 19:25:32 +00:00
Matthias Clasen
6dfaafc9f2 Merge branch 'update-keysyms' into 'main'
gdk: Update keyboard symbols from libxkbcommon

See merge request GNOME/gtk!4422
2022-02-09 19:23:59 +00:00
Matthias Clasen
287de3844d Merge branch 'gtk_assisten_set_current_page-no-pages-guard' into 'main'
Don't dereference a `NULL` page in `gtk_assistant_set_current_page()` if there are no pages at all

See merge request GNOME/gtk!4464
2022-02-09 19:19:24 +00:00
Sebastian Dröge
878e4a34d3 Don't dereference a NULL page in gtk_assistant_set_current_page() if there are no pages at all 2022-02-09 17:50:55 +02:00
Matthias Clasen
b893dc9552 Merge branch 'bilelmoussaoui/g-i' into 'main'
gdk: mark gdk_device_get_device_tool as nullable

See merge request GNOME/gtk!4463
2022-02-09 13:43:50 +00:00
Matthias Clasen
687b80a037 Merge branch 'revert-misdeprecation' into 'main'
Revert "Deprecate GdkDevice:source"

See merge request GNOME/gtk!4462
2022-02-09 13:13:35 +00:00
Bilal Elmoussaoui
a8a98523db gdk: mark gdk_device_get_device_tool as nullable 2022-02-09 13:09:47 +00:00
Matthias Clasen
0a224964a6 Revert "Deprecate GdkDevice:source"
This reverts commit fd9e0dd13a.
2022-02-09 07:55:28 -05:00
Luca Bacci
0457c37847 Merge branch 'win32-fix-ctrl-shift-gtk4' into 'main'
gdkkeys-win32: Also ignore Ctrl + Shift (etc.)

See merge request GNOME/gtk!4460
2022-02-09 10:08:52 +00:00
Philip Zander
037c0e4005 gdkkeys-win32: Also ignore Ctrl + Shift (etc.)
Some Windows keymaps have bogus mappings for the Ctrl modifier. !4423 attempted
to fix this by ignoring the Ctrl layer, but that was not enough. We also need to
ignore combinations of Ctrl with other modifiers, i.e. Ctrl + Shift. For example,
Ctrl + Shift + 6 is mapped to the character 0x1E on a US keyboard (but it should
be treated as Ctrl + ^). Basically, always ignore Ctrl unless it is used in
conjunction with Alt, i.e. as part of AltGr.

Related issue: #4667
2022-02-09 10:43:07 +01:00
Christian Hergert
b9389d3784 Merge branch 'bilelmoussaoui/macos-gdk-display' into 'main'
macos: Don't set NULL as a display name

See merge request GNOME/gtk!4453
2022-02-09 00:30:04 +00:00
Günther Wagner
86a3400f2e tools: updated gtk4builder.rng to current state 2022-02-08 21:42:41 +01:00
Sebastian Dröge
8245fd4beb Allow passing a NULL factory to gtk_column_view_column_new() 2022-02-08 16:25:28 +02:00
Bilal Elmoussaoui
f41cfd3caa macos: Don't set NULL as a display name
Other GDK backends ensure there is always a default name set.
Fixes https://github.com/gtk-rs/gtk4-rs/issues/868
2022-02-08 13:38:33 +01:00
Sebastian Dröge
07d6ef13c5 Mark path out parameter of gtk_icon_view_get_drag_dest_item() as (nullable)
It can be set to `NULL` and the function body handles `NULL` explictly,
so annotate it accordingly.
2022-02-08 12:50:24 +02:00
Bilal Elmoussaoui
883e8328e0 entry completion: add checks that entry is set already
If any of the APIs that assumes that the entry is set already is used
before having one already set, things break pretty badly.

Fixes a downstream issue reported at https://github.com/gtk-rs/gtk4-rs/issues/873
2022-02-08 11:22:52 +01:00
Benjamin Otte
c6d5816c95 Merge branch 'wip/otte/for-main' into 'main'
gltexture: Only use glGetFramebufferParameter() when available

Closes #4678

See merge request GNOME/gtk!4449
2022-02-08 02:08:26 +00:00
Benjamin Otte
f37c5ebd26 rgba: Fix GDK_RGBA() macro to work with alpha
Previously we dividied by an integer, so alpha was either 0.0 or 1.0.
2022-02-08 01:34:19 +01:00
Benjamin Otte
2c71825324 gltexture: Only use glGetFramebufferParameter() when available
Fixes #4678
2022-02-08 01:34:19 +01:00
Matthias Clasen
38ad56e6a1 Merge branch 'wip/jimmac/selected_text' into 'main'
style: legible text selections

Closes #4664

See merge request GNOME/gtk!4433
2022-02-08 00:15:45 +00:00
Matthias Clasen
84d698464c Merge branch 'antoniof-main-patch-89408' into 'main'
columnviewcolumn: Define autocleanup function

See merge request GNOME/gtk!4440
2022-02-07 23:57:46 +00:00
Matthias Clasen
9363269ceb Merge branch 'more-noexecstack' into 'main'
demos: Make our stack noexec

See merge request GNOME/gtk!4439
2022-02-07 23:57:26 +00:00
Matthias Clasen
59eb9aeb73 Merge branch 'wip/chergert/macos-fixes' into 'main'
various macOS fixes

See merge request GNOME/gtk!4424
2022-02-07 23:56:40 +00:00
Matthias Clasen
d9109a0e92 Merge branch 'mg/gdk-macos-gdkdisplaylinksource' into 'main'
Include `gdk-private.h` to fix error about `g_source_set_static_name`

See merge request GNOME/gtk!4443
2022-02-07 23:54:55 +00:00
Matthias Clasen
f27c0c65b1 Merge branch 'mg/implicit-declaration-free' into 'main'
gdkjpeg: include `stdlib.h` necessary for `free`

See merge request GNOME/gtk!4445
2022-02-07 23:53:36 +00:00
Matej Urbančič
212f629876 Update Slovenian translation 2022-02-07 19:39:08 +00:00
Matej Urbančič
05f2f3ba8c Update Slovenian translation 2022-02-07 19:30:34 +00:00
Emmanuele Bassi
a66072f312 Merge branch 'drop-target-get-formats-transfer-none' into 'main'
Mark `gtk_drop_target_get_formats()` return value as `transfer none`

See merge request GNOME/gtk!4446
2022-02-07 15:17:39 +00:00
Sebastian Dröge
3ba582375d Mark gtk_drop_target_get_formats() return value as transfer none
It was wrongly inferred as `transfer full` by gobject-introspection.
2022-02-07 16:23:01 +02:00
Mosè Giordano
4c211f1872 gdkjpeg: include stdlib.h necessary for free
`free` is defined in `stdlib.h`, see for example
<https://pubs.opengroup.org/onlinepubs/009604499/functions/free.html>.  Without
this include compilation can fail with the following error:

```
../gdk/loaders/gdkjpeg.c: In function ‘gdk_save_jpeg’:
../gdk/loaders/gdkjpeg.c:264:7: warning: implicit declaration of function ‘free’ [-Wimplicit-function-declaration]
       free (data);
       ^
../gdk/loaders/gdkjpeg.c:264:7: warning: incompatible implicit declaration of built-in function ‘free’
../gdk/loaders/gdkjpeg.c:264:7: note: include ‘<stdlib.h>’ or provide a declaration of ‘free’
../gdk/loaders/gdkjpeg.c:302:67: error: ‘free’ undeclared (first use in this function)
   return g_bytes_new_with_free_func (data, size, (GDestroyNotify) free, NULL);
                                                                   ^
../gdk/loaders/gdkjpeg.c:302:67: note: each undeclared identifier is reported only once for each function it appears in
../gdk/loaders/gdkjpeg.c:303:1: warning: control reaches end of non-void function [-Wreturn-type]
 }
 ^
```
2022-02-06 15:41:33 +00:00
Mosè Giordano
2ceba0d31c Include gdk-private.h to fix error about g_source_set_static_name
Without this change we get the following error:

```
[1/13] Compiling C object gdk/macos/libgdk-macos.a.p/gdkdisplaylinksource.c.o
ninja: job failed: /opt/bin/aarch64-apple-darwin20-libgfortran5-cxx11/aarch64-apple-darwin20-clang -Igdk/macos/libgdk-macos.a.p -Igdk/macos -I../gdk/macos -I. -I.. -Igdk -I../gdk -Isubprojects/pango/pango -I../subprojects/pango/pango -Isubprojects/pango -I../subprojects/pango -I/workspace/destdir/include/gdk-pixbuf-2.0 -I/workspace/destdir/include -I/workspace/destdir/include/glib-2.0 -I/workspace/destdir/lib/glib-2.0/include -I/workspace/destdir/lib/libffi-3.2.1/include -I/workspace/destdir/include/libpng16 -I/usr/include/libmount -I/usr/include/blkid -I/workspace/destdir/include/cairo -I/workspace/destdir/include/pixman-1 -I/workspace/destdir/include/freetype2 -I/workspace/destdir/include/fribidi -I/workspace/destdir/include/harfbuzz -I/workspace/destdir/include/graphene-1.0 -I/workspace/destdir/lib/graphene-1.0/include -I/workspace/destdir/include/gio-unix-2.0 -fcolor-diagnostics -Wall -Winvalid-pch -std=gnu99 -O2 -g -DG_LOG_USE_STRUCTURED=1 -DGLIB_DISABLE_DEPRECATION_WARNINGS '-DGTK_VERSION="4.6.0"' -D_GNU_SOURCE -DG_ENABLE_DEBUG -DGTK_COMPILATION '-DG_LOG_DOMAIN="Gdk"' -xobjective-c -fno-strict-aliasing -Wno-c++11-extensions -Wno-missing-include-dirs -Wno-typedef-redefinition -Wformat=2 -Wformat-nonliteral -Wformat-security -Wignored-qualifiers -Wimplicit-function-declaration -Wmisleading-indentation -Wmissing-format-attribute -Wmissing-include-dirs -Wmissing-noreturn -Wnested-externs -Wold-style-definition -Wpointer-arith -Wshadow -Wstrict-prototypes -Wswitch-default -Wswitch-enum -Wundef -Wuninitialized -Wunused -Werror=address -Werror=array-bounds -Werror=empty-body -Werror=implicit -Werror=implicit-fallthrough -Werror=init-self -Werror=int-to-pointer-cast -Werror=main -Werror=missing-braces -Werror=missing-declarations -Werror=missing-prototypes -Werror=nonnull -Werror=pointer-to-int-cast -Werror=redundant-decls -Werror=return-type -Werror=sequence-point -Werror=trigraphs -Werror=vla -Werror=write-strings -Wnull-dereference -fvisibility=hidden -MD -MQ gdk/macos/libgdk-macos.a.p/gdkdisplaylinksource.c.o -MF gdk/macos/libgdk-macos.a.p/gdkdisplaylinksource.c.o.d -o gdk/macos/libgdk-macos.a.p/gdkdisplaylinksource.c.o -c ../gdk/macos/gdkdisplaylinksource.c
../gdk/macos/gdkdisplaylinksource.c:201:3: error: implicit declaration of function 'g_source_set_static_name' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
  g_source_set_static_name (source, "[gdk] quartz frame clock");
  ^
1 error generated.
ninja: subcommand failed
```
2022-02-05 21:51:40 +00:00
Christian Hergert
95168e179c macos: fallback to conversion on WCG colorspace
We don't want to risk having something really weird come out if we have a
WCG colorspace, so instead only do the performance hack on systems where
the output is likely reasonable.

We will want to eventually just be drawing in the appropriate colorspace,
but that is not available yet.
2022-02-05 12:42:57 -08:00
Asier Sarasua Garmendia
34959b58f4 Update Basque translation 2022-02-05 11:21:02 +00:00
Christian Hergert
2be51dc3b1 macos: handle sizing changes when switching monitors
This should make sure that our scales are updated as well as
ensuring we repaint the whole surface.
2022-02-04 12:29:57 -08:00
Benjamin Otte
14bdf82e33 Merge branch 'wip/hadess/inspector-search-by-pointer-gtk4' into 'main'
inspector: Search by pointer address

See merge request GNOME/gtk!4442
2022-02-04 18:07:28 +00:00
Christian Hergert
6b85d501f0 macos: assume monitor colorspace when drawing
When using software rendering w/ cairo, assume we're drawing in
the best-monitor's colorspace rather than RGB to avoid colorspace
conversions on every frame.
2022-02-04 09:46:10 -08:00
Christian Hergert
473aceea68 macos: add API to get monitor colorspace 2022-02-04 09:45:55 -08:00
Bastien Nocera
0621dbc745 inspector: Search by pointer address
Useful to find a widget that corresponds to a pointer address in gdb.
2022-02-04 18:39:56 +01:00
Christian Hergert
8ea0a4fc50 macos: precalculate clip regions as CGRect
We can make our drawRect do less work if we precalculate the clip
and damage regions upfront by intersecting them with the bounds.
2022-02-04 09:31:37 -08:00
António Fernandes
94ef818c9a columnviewcolumn: Define autocleanup function 2022-02-04 11:13:46 +00:00
Christian Hergert
8112b49c36 macos: fix unmaximize opacity around edges of window 2022-02-03 19:26:16 -08:00
Christian Hergert
58b9c3a6d4 macos: use CGContext to draw cairo surfaces
Instead of relying on cairo_t to perform drawing from our backing
image surface to the Core Graphics context, we can convert the
cairo_image_surface_t into a CGImageRef without having to copy
data if we are certain of the alignment of the image up front.

Without this, there are many situations, based on the size of the
window that could cause cairo to take a slow path and malloc/copy
the data to ensure that alignment.

The previous commit titled "macos: align image surface rowstride to
16-bytes" ensures that this invariant is true so that our drawing
code can assume we can reference the framebuffer from the
cairo_image_surface_t using a CGDataProvider.

Since GdkMacosCairoContext and GdkMacosCairoSubview are coordinating,
we can also setup the transformation/scale early when drawing the
cairo_image_surface_t instead of when copying it to Core Graphics.

Furthermore, the CGImageRef is created with an RGB colorspace so
that we are not performing colorspace conversion to the output
device. We don't get color matching between displays, but we don't
expect that anyway, particularly with the software renderer.
2022-02-03 19:26:16 -08:00
Christian Hergert
4373743d4c macos: align image surface rowstride to 16-bytes
When creating a cairo_image_surface_t we want both the framebuffer pointer
and each row to be aligned to 16-bytes so that Core Graphics will use more
optimal paths.

However, cairo_image_surface_create() will not guarantee that the rowstride
is aligned to 16-bytes so we must do that ourselves.
2022-02-03 19:26:16 -08:00
Christian Hergert
58159552ba macos: avoid unnecessarily destroying cairo_t
This avoids destroying a cairo_t when we are within the frame as it
otherwise causes the surface to unnecessarily flush.
2022-02-03 19:26:16 -08:00
Christian Hergert
4bff24f83a macos: cleanup window surface when destroying context
Make sure we release the cairo_surface_t for the window when
disposing the GdkMacosCairoContext.
2022-02-03 19:26:16 -08:00
Christian Hergert
f644925570 macos: be more careful about freezing/thawing surfaces
We need to avoid conflating the managing of frame callbacks from
the freeze/thaw mechanics and ensure we don't perform extra thaw
requests at the wrong time.
2022-02-03 19:26:16 -08:00
Christian Hergert
8a4fd3f2af macos: check for destroyed surfaces in vfuncs 2022-02-03 19:26:16 -08:00
Christian Hergert
b7130a1ce3 macos: be more defensive about freezing updates
We only need to freeze the updates if we weren't in the queue already.
That should be the case, but just better to be defensive here.
2022-02-03 19:26:16 -08:00
Christian Hergert
519a44d224 macos: push to head of awaiting frames
Always add to the head of awaiting frames as the list is processed
in the opposite direction.
2022-02-03 19:26:16 -08:00
Christian Hergert
936034e07a macos: remove popup surface from parent 2022-02-03 19:26:16 -08:00
Christian Hergert
ea43939f52 macos: handle NULL frame-clock when thawing 2022-02-03 19:26:16 -08:00
Jan Alexander Steffens (heftig)
d8befc612f demos: Make our stack noexec
This is similar to https://gitlab.gnome.org/GNOME/gtk/-/merge_requests/4330
and https://gitlab.gnome.org/GNOME/gtk/-/merge_requests/4334, which fixed
the main library but missed the demos.
2022-02-03 19:14:36 +00:00
Emmanuele Bassi
06ec4ec148 Merge branch 'zbrown/its-a-filename' into 'main'
cssprovider: from_path takes a path

See merge request GNOME/gtk!4436
2022-02-02 23:11:44 +00:00
Zander Brown
6fbcb967a0 cssprovider: from_path takes a path
Annotate it as such so that bindings can expose that appropriately

Related: https://github.com/gtk-rs/gtk4-rs/issues/861
2022-02-02 22:47:39 +00:00
Emmanuele Bassi
82e0241c42 Merge branch 'fix-app-launch-context-docs' into 'main'
gdkapplaunchcontext: Fix docs a bit

See merge request GNOME/gtk!4434
2022-02-01 20:34:41 +00:00
Phaedrus Leeds
8e000c2dbf gdkapplaunchcontext: Fix docs a bit
The set_screen() and set_display() methods no longer exist.
2022-02-01 11:17:55 -08:00
Jakub Steiner
1f1aafd5c2 style: legible text selections
- follow adwaita styling

Fixes https://gitlab.gnome.org/GNOME/gtk/-/issues/4664
2022-02-01 17:12:52 +01:00
Luca Bacci
d314298644 Merge branch 'win32-keys-ignore-ctrl-gtk4' into 'main'
gdkkeys-win32: Ignore CTRL bit for key translation

Closes #4667

See merge request GNOME/gtk!4431
2022-02-01 15:33:01 +00:00
Emmanuele Bassi
3cbe3abf67 Merge branch '4602-fix-kerning-of-gl-rendered-glyphs' into 'main'
Fix kerning of GL rendered glyphs

Closes #4602

See merge request GNOME/gtk!4429
2022-02-01 14:31:47 +00:00
Philip Zander
90ab8b8dd3 gdkkeys-win32: Ignore CTRL bit for key translation
Some keymaps on Windows contain bogus mappings for Ctrl+key for certain
keys, e.g. Ctrl+Backspace = Delete, or Ctrl+[ = 0x1B. These are never
used on Windows, so we should ignore them.

Fixes #4667
2022-02-01 14:12:56 +01:00
Marek Kasik
cb1dd66220 Fix kerning of GL rendered glyphs
Multiple scaled shifts by 1024 too.

Fixes: #4602
2022-02-01 09:31:35 +01:00
Boyuan Yang
d033a099ae Update Chinese (China) translation 2022-01-31 03:51:23 +00:00
Boyuan Yang
78d9e5e181 Update Chinese (China) translation 2022-01-31 03:46:30 +00:00
sicklylife
41270ba8c9 Update Japanese translation 2022-01-30 15:26:50 +00:00
sicklylife
e2277438e9 Update Japanese translation 2022-01-30 15:15:27 +00:00
Piotr Drąg
b0936c913b Update Polish translation 2022-01-29 14:59:17 +01:00
Väinö Mäkelä
4b05eb62c9 gdk: Update keyboard symbols from libxkbcommon
GTK's old key symbol list is missing a few symbols like the per mille
sign that is included in some keyboard layouts. This commit updates
gdkkeyuni.c to match libxkbcommon's current key symbol list.
2022-01-29 14:31:09 +02:00
Aleksandr Melman
fbacf0cb65 Update Russian translation 2022-01-28 11:05:57 +00:00
Emmanuele Bassi
05a53a1582 Merge branch 'infobar-xml' into 'main'
Escape Builder XML in GtkInfoBar docs

See merge request GNOME/gtk!4421
2022-01-28 10:49:37 +00:00
Elliott Sales de Andrade
be5873a057 Escape Builder XML in GtkInfoBar docs 2022-01-28 05:32:16 -05:00
Daniel Mustieles
c97f46bf28 Updated Spanish translation 2022-01-28 11:01:09 +01:00
Emmanuele Bassi
1d47882eab Merge branch 'ebassi/manifest-dep-fix' into 'main'
flatpak: Add wayland-protocols to the manifests

See merge request GNOME/gtk!4420
2022-01-28 02:05:59 +00:00
Emmanuele Bassi
9dcbbb4300 flatpak: Use "main" branch for wayland
The default branch for wayland has changed, but the "master" branch
is still available with an older version.
2022-01-28 01:25:04 +00:00
Matthias Clasen
c9eda02fa1 Merge branch 'tiled-window-bracket-fix' into 'main'
theme: Drop shadow and border fixes for tiled windows

See merge request GNOME/gtk!4418
2022-01-27 17:29:13 +00:00
Matthias Clasen
a37584a404 Merge branch 'wip/baedert/for-master' into 'main'
build: Make GCC ignore fallthrough comments

Closes #4663

See merge request GNOME/gtk!4419
2022-01-27 16:27:12 +00:00
Leônidas Araújo
566f217f6f Update Brazilian Portuguese translation 2022-01-27 16:25:07 +00:00
Matheus Barbosa
ca34c79443 Update Brazilian Portuguese translation 2022-01-27 15:47:53 +00:00
Timm Bäder
4be6c5b197 gesturesingle: Get rid of a fallthrough comment
Fixes #4663
2022-01-27 16:06:56 +01:00
Timm Bäder
7194196100 build: Make GCC ignore fallthrough comments
From the GCC manpage:

> Wimplicit-fallthrough=5 doesn't recognize any comments as
> fallthrough comments, only attributes disable
> the warning.

So, check for the =5 version after checking for the simple version. This
way we get -Wfallhrough with clang and -Wfallthrough -Wfallthrough=5
with GCC, which works.
2022-01-27 16:05:33 +01:00
Yuri Chornoivan
d9d2eb978d Update Ukrainian translation 2022-01-27 14:47:37 +00:00
Carlos Garnacho
c8460c51bd Merge branch 'realize-vs-focus-in' into 'main'
gtktext: Make sure input method sees focus in

See merge request GNOME/gtk!4402
2022-01-27 14:13:55 +00:00
Joonas Henriksson
b4d0235a05 theme: Fix incorrect border color for tiled windows 2022-01-27 06:08:40 +02:00
Joonas Henriksson
a5d1f78bf2 theme: Fix drop shadow for tiled windows
Misplaced curly bracket prevented the :backdrop styling from getting
applied. Also fix the indentation while at it.
2022-01-27 05:50:06 +02:00
Carlos Garnacho
9a7750e339 Merge branch 'hold-gestures' into 'main'
Add hold gestures

See merge request GNOME/gtk!3454
2022-01-26 23:37:28 +00:00
Fran Dieguez
d7c4ac7d02 Update Galician translation 2022-01-26 23:36:27 +00:00
Hugo Carvalho
1a08be066e Update Portuguese translation 2022-01-26 22:48:02 +00:00
José Expósito
fe86aa5f6b gtkgestureswipe: Don't filter hold events
Part-of: <!3454>
2022-01-26 22:49:53 +01:00
José Expósito
34133ec1e8 gtkgesturerotate: Don't filter hold events
Part-of: <!3454>
2022-01-26 22:49:53 +01:00
José Expósito
a99a75827c gtkgesturezoom: Don't filter hold events
Part-of: <!3454>
2022-01-26 22:49:53 +01:00
José Expósito
3bfcc12ec0 gtkgesture: Handle hold gestures
Hold gestures are used to bring existing gestures on touchpad
semantically closer to touchscreen gestures.

Touchpad gestures observe hold gestures with a matching amount of
fingers and emit their begin and end signals when fingers are detected
or removed on/from the touchpad.

When a hold cancel event is detected, it is required to wait a few
milliseconds until the next event(s) are received to avoid emitting
multiple begin signals.

Part-of: <!3454>
2022-01-26 22:49:53 +01:00
José Expósito
382341e1bf gtkgesture: Add hold to EVENT_IS_TOUCHPAD_GESTURE
Part-of: <!3454>
2022-01-26 22:49:53 +01:00
José Expósito
44b0d8b330 scrolledwindow: Stop kinetic scrolling on begin
Stop kinetic scrolling when a scroll begin signal is sent during the
event capture phase.

Part-of: <!3454>
2022-01-26 22:49:53 +01:00
José Expósito
62808722d2 kineticscrolling: Add stop function
Move the logic to stop kinetic scrolling to its own function and allow
to call it from the outside.

Part-of: <!3454>
2022-01-26 22:49:53 +01:00
José Expósito
f09338c8de gtkeventcontrollerscroll: Handle hold gestures
Handle hold events:

 - GDK_TOUCHPAD_GESTURE_PHASE_BEGIN: scroll-begin is emitted.
 - GDK_TOUCHPAD_GESTURE_PHASE_END: A hold gesture ends only when all
   fingers are lifted from the touchpad without movement, so
   scroll-end is emitted right away.
 - GDK_TOUCHPAD_GESTURE_PHASE_CANCEL: A hold gesture is cancelled when
   some fingers are lifted/put down or movement is detected. In this
   case, scroll-end is emitted after a small timeout only if
   GDK_SCROLL wasn't detected.

Part-of: <!3454>
2022-01-26 22:49:53 +01:00
José Expósito
ec91b2de10 gtkeventcontrollerscroll: Refactor scroll end
Move the logic to end scrolling to its own function to be able to
reuse it.

Refactor, no functional changes.

Part-of: <!3454>
2022-01-26 22:49:53 +01:00
José Expósito
5cd289dc1d gtkeventcontrollerscroll: Refactor scroll begin
Move the logic to begin scrolling to its own function to be able to
reuse it.

Refactor, no functional changes.

Part-of: <!3454>
2022-01-26 22:49:53 +01:00
José Expósito
299caaa383 wayland/pointer-gestures: Receive hold gesture
Add the glue code to receive hold gesture events from the compositor,
transform them into GdkEvents and finally enqueue them.

Part-of: <!3454>
2022-01-26 22:49:53 +01:00
José Expósito
0aa2a4ef14 gtkmain: Handle hold events
Part-of: <!3454>
2022-01-26 22:49:53 +01:00
José Expósito
331f1ee722 gdk/events: Add hold GdkEvent
Allow to create hold events as well as the required functions to get
information about the event: gesture phase, finger count, etc

Part-of: <!3454>
2022-01-26 22:49:53 +01:00
José Expósito
0f351508bc build: Bump wayland-protocols to v1.23
Part-of: <!3454>
2022-01-26 22:47:51 +01:00
Matthias Clasen
304527ab01 Merge branch 'sri-main-patch-28302' into 'main'
Update docs/reference/gtk/migrating-3to4.md

See merge request GNOME/gtk!4404
2022-01-26 19:37:28 +00:00
Matthias Clasen
b3d778469a Merge branch 'rafaelff-hig' into 'main'
buildertool: use curly apostrophe

See merge request GNOME/gtk!4414
2022-01-26 19:35:21 +00:00
Matthias Clasen
6f5210afea Merge branch 'wip/carlosg/touchpad-gesture-fixes' into 'main'
Touchpad gesture fixes

See merge request GNOME/gtk!4417
2022-01-26 19:32:33 +00:00
Matthias Clasen
6b1de35c01 Merge branch 'antoniof-main-patch-39484' into 'main'
gtkbitset: Define autocleanup function

See merge request GNOME/gtk!4416
2022-01-26 19:29:08 +00:00
Matthias Clasen
8fccfc7a3d Merge branch 'bilelmoussaoui/g-i' into 'main'
g-i: mark GtkSnapshot to_(node|paintable) as nullable

See merge request GNOME/gtk!4413
2022-01-26 19:19:42 +00:00
Carlos Garnacho
6fd3645713 gtk/gesture: Fix point info lookup on touchpad events
Since the addition of GdkEventSequence in touchpad events, these
are now stored in the gesture using that sequence. This bit of touchpad
gesture handling was however missing to be updated, still looking up
the special NULL sequence.

Use the last sequence here, which will be the one coming from touchpad
gesture events.
2022-01-26 16:02:00 +01:00
Carlos Garnacho
8e86e6325b gtk/main: Do not use touchpad event sequence for pointer focus lookup
Despite touchpad gestures having a sequence, these must use the logical
pointer focus. Avoid using the sequence for GtkPointerFocus lookups with
those events, in order to ensure those events make it all the way to the
intended target.

This is fallout from adding GdkEventSequence information to touchpad
gestures.
2022-01-26 15:59:36 +01:00
Carlos Garnacho
2b41e72196 gdk: Always request "flush events" frame clock phase on events
This change is done for 2 reasons:

- The logic to request this phase when compressing scroll events is
  slightly broken. If there are multiple scroll events that are
  coalesced into one, the surface frame clock will not get this request.
  The worst case is having >= 2 scroll events on every frame, as the
  compressed event will be left in the queue, and be further compressed
  on future events.

- Even scroll events aside, this phase is requested in oddly specific
  places that are not enough to cover all events, others do rely on
  unrelated GdkFrameClock activity that happens to flush the events
  as well.

Unify this phase request so it explicitly happens on the arrival of any
event. This ensures that events (compressed or not) will be handled
promptly after arrival.
2022-01-26 15:49:29 +01:00
António Fernandes
1a64eeb88e gtkbitset: Define autocleanup function 2022-01-25 21:33:31 +00:00
Emmanuele Bassi
2f8eac2c0a Merge branch 'fix-popovermenu-removechild' into 'main'
popovermenu: Fix crash when removing child

See merge request GNOME/gtk!4393
2022-01-25 15:40:28 +00:00
Kévin Commaille
aaba777ad0 popovermenu: Fix crash when removing child
gtk_menu_section_box_remove_custom was looking in the wrong place for the
stack ancestor, causing an assertion error.
2022-01-25 15:31:00 +01:00
Guido Günther
a580547f47 gtktext: Make sure input method sees focus in
Currently when the widget is realized after the focus in event the input
method isn't activated as enable is never sent. The call trace is

  gtk_text_focus_changed ->
    gtk_im_context_focus_in ->
      gtk_im_context_wayland_focus_in

which returns early as self->widget is NULL since it's set up in
gtk_text_realize() via gtk_im_context_set_client_widget(). Handle that
case by invoking gtk_im_context_focus_in() from gtk_text_realize() too.

A case where the above happens is a GtkSearchEntry in a GtkSearchBar.
E.g. in gtk4-demo when starting the demo and then hitting the search
button right away.
2022-01-25 11:15:29 +01:00
Boyuan Yang
00ee7ffa6a Update Chinese (China) translation 2022-01-24 19:46:37 +00:00
Leônidas Araújo
f02b7d55b1 Update Brazilian Portuguese translation 2022-01-24 17:08:46 +00:00
Rafael Fontenelle
bed709a322 buildertool: use curly apostrophe 2022-01-24 17:04:17 +00:00
Bilal Elmoussaoui
b362eeefdf g-i: mark GtkSnapshot to_(node|paintable) as nullable
Fixes an upstream issue reported at https://github.com/gtk-rs/gtk4-rs/issues/845
2022-01-23 22:11:07 +00:00
Matthias Clasen
7b02498963 Merge branch 'matthiasc/for-main' into 'main'
Use pango api better

See merge request GNOME/gtk!4412
2022-01-23 15:19:39 +00:00
Matthias Clasen
6fd53f28f3 Use pango api better
Avoid direct access to PangoLayoutLine members,
use pango api for it where we can.#
2022-01-23 09:55:46 -05:00
Matthias Clasen
fefc8b5a82 Merge branch 'matthiasc/for-main' into 'main'
Use pango api better

See merge request GNOME/gtk!4411
2022-01-23 14:34:58 +00:00
Matthias Clasen
4fe976549e Use pango api better
Avoid direct access to PangoLayoutLine members,
use pango api for it where we can.
2022-01-23 09:09:57 -05:00
Matthias Clasen
044ff82d0b Merge branch 'matthiasc/for-main' into 'main'
Use pango api better

See merge request GNOME/gtk!4409
2022-01-23 04:29:58 +00:00
Matthias Clasen
feac1e5fba Use pango api better
Avoid direct access to PangoLayoutLine members,
use pango api for it where we can.
2022-01-22 23:10:53 -05:00
Yaron Shahrabani
dd5455fcd2 Update Hebrew translation 2022-01-21 16:04:24 +00:00
Yaron Shahrabani
315971f02d Update Hebrew translation 2022-01-21 15:53:39 +00:00
Emmanuele Bassi
a092986af3 Merge branch 'targz' into 'main'
ci: Put gtk dll into an archive

Closes #4653

See merge request GNOME/gtk!4403
2022-01-19 19:58:36 +00:00
Sri Ramkrishna
6633f4e02f Update docs/reference/gtk/migrating-3to4.md 2022-01-19 19:24:01 +00:00
Guido Günther
ee8970f23d ci: Only use letters in "expose_as" 2022-01-19 18:51:29 +01:00
Guido Günther
46f1e4c414 ci: Put gtk dll into an archive
This avoids the wild card that makes the CI fail
2022-01-19 18:51:16 +01:00
Dz Chen
a853e27765 Update Chinese (China) translation 2022-01-19 15:44:00 +00:00
Matthias Clasen
68985d42bb Merge branch 'win32-gl-improvements' into 'main'
Windows: Some fixes to GL context realization (EGL/GLES in particular)

See merge request GNOME/gtk!4386
2022-01-19 13:49:40 +00:00
Matthias Clasen
9146a21738 Merge branch 'bilelmoussaoui/g-i' into 'main'
g-i: mark gtk_text_iter_get_child_anchor as nullable

See merge request GNOME/gtk!4401
2022-01-19 13:48:57 +00:00
Luca Bacci
8c2128703b Merge branch 'provide-libgtk-dll-as-ci-artifact' into 'main'
Provide GTK DLL as GitLab CI artifact

See merge request GNOME/gtk!4395
2022-01-19 11:17:28 +00:00
Luca Bacci
b2d9cae0ec Provide GTK DLL as GitLab CI artifact 2022-01-19 11:17:28 +00:00
Carlos Garnacho
11eb66298d Merge branch 'context-early' into 'main'
gtkimcontextwayland: Remember context on focus-in so enable can happen later

See merge request GNOME/gtk!4397
2022-01-19 10:48:48 +00:00
Bilal Elmoussaoui
0f67e46549 g-i: mark gtk_text_iter_get_paintable as nullable 2022-01-19 10:22:40 +00:00
Guido Günther
45397534eb gtkimcontextwayland: Save context even when text_input isn't around yet
Remember the current context on focus-in even though the text-input
isn't set up yet. This helps in the case where the text-input is not yet
created but a widget already got focused. Without that the enable()
invocation in text_input_enter() woulnd't be invoked leaving the input
method disabled.

This fixes

    gtk4-demo --run=search_entry

which would initially not show the on-screen keyboard when e.g using
phoc/sway as compositor.
2022-01-19 10:20:46 +00:00
Bilal Elmoussaoui
ffa93b87f8 g-i: mark gtk_text_iter_get_child_anchor as nullable 2022-01-19 10:18:40 +00:00
Guido Günther
4d741bac98 wayland: xdg-activation: Don't assume there's a focus surface
Tools like gtk4-launch can't set surface on the activation token so
don't require it. If the compositor requires it we can't do anything
about it anyway. This avoids a critical:

   (gtk4-launch:23497): Gdk-CRITICAL **: 17:07:24.704: gdk_wayland_surface_get_wl_surface: assertion 'GDK_IS_WAYLAND_SURFACE (surface)' failed

Fixes: be4216e051 ("gdk/wayland: Support the xdg-activation wayland protocol")

Signed-off-by: Guido Günther <agx@sigxcpu.org>
2022-01-19 08:57:10 +01:00
Chun-wei Fan
0fe37d1828 gdkdisplay-win32.c: Clean up GL initialization further 2022-01-19 11:56:32 +08:00
Chun-wei Fan
43839898b3 GDK: Force GLES 3.0+ on libANGLE
...when libANGLE is being used on Windows, by checking for a
Windows-specific an ANGLE-specific extension.
2022-01-19 11:56:32 +08:00
Chun-wei Fan
6f2848c311 Cleanup "GDK/Win32: Try to fix initializing GLES contexts"
As per Benjamin's suggestions, cleanup the previous implementation on
initializing the GLES context on Windows, so that we use more items that are
already in GDK proper and integrate two functions into one.
2022-01-19 11:56:32 +08:00
Chun-wei Fan
38c17c1f79 gdkglcontext-win32-wgl.c: Cleanup GL context creation
Instead of first trying to explicitly ask for a WGL 4.1 context, ask for
the WGL context version that matches what is reported via
epoxy_gl_version(), so that we get the maximum WGL version that is
supported by the graphics drivers, and make sure any WGL contexts that
are shared with this (initial) WGL context are created likewise.

We can try to do a default-bog-standard 3.2 core WGL context creation
if the need arises, but let's leave that alone for now.
2022-01-19 11:56:32 +08:00
Chun-wei Fan
b85aa10700 gdkglcontext.c: Ensure EGL contexts are in-sync with shared context
The EGL context that we are actually creating must have matching OpenGL/ES
versions and allowed GL API set with the previously-created EGL context
that will be shared with it so that they can interoperate together, if
applicable.

This will fix the situation by making sure that we request for the
OpenGL/ES version and OpenGL API set that match with what we have in our shared
EGL context.  Otherwise, the newly-created EGL context assumed a OpenGL/ES 2.0
context that supported desktop OpenGL, which may not be what we wanted, such as
in the case of libANGLE.
2022-01-19 11:56:32 +08:00
Chun-wei Fan
598c7d9cf4 GDK/Win32: Try to fix initializing GLES contexts
We are now able to create EGL contexts properly on Windows, but not GLES.  This
tries to fix things by doing the following:

*  Record the GL context type in a more proper fashion, using an Enum.  This
   makes things a bit cleaner.
*  Force GLES-3.0+ contexts, since libANGLE requires this to properly work with
   the shaders-its 2.0 contexts don't work well with our shaders.
2022-01-19 11:56:32 +08:00
Chun-wei Fan
3e9d858af1 gskrenderer.c: Use GL renderer on Windows by default
Since now we have the shaders working on Windows under GLES with libANGLE using
a 3.0+ context, drop the check to fall back to the Cairo renderer when GLES is
being used.
2022-01-19 11:56:32 +08:00
Matthias Clasen
6fd29e6600 Merge branch 'wip/wayland-surface-offset' into 'main'
Fix DND hotspot position under Wayland + EGL/Vulkan

See merge request GNOME/gtk!3705
2022-01-18 23:48:26 +00:00
Matthias Clasen
b67636747b Merge branch 'gdksurface-wayland-assert' into 'main'
gdksurface-wayland: Fix contradictory assert

See merge request GNOME/gtk!4385
2022-01-18 23:46:59 +00:00
Matthias Clasen
ea464c9874 Merge branch 'gsk-transform-nullable' into 'main'
Mark various GskTransform functions as nullable in their return value

See merge request GNOME/gtk!4378
2022-01-18 23:44:23 +00:00
Matthias Clasen
0e9c4a3964 Merge branch 'document_shortcut_func_ret' into 'main'
gtk: document return value of ShortcutFunc

See merge request GNOME/gtk!4389
2022-01-18 23:41:15 +00:00
Matthias Clasen
1b15f89dfd Merge branch 'wip/dont-always-restore-saved-gtk4' into 'main'
wayland: Don't always restore the saved size when floating

Closes #4634

See merge request GNOME/gtk!4394
2022-01-18 23:40:49 +00:00
Matthias Clasen
7192ff672e Merge branch 'build-post-install-query-media-modules' into 'main'
Meson: Also query media modules in post-install

See merge request GNOME/gtk!4380
2022-01-18 23:39:26 +00:00
Matthias Clasen
7a99e03888 Merge branch 'ebassi/fix-release-test' into 'main'
reftest: Avoid assertions being compiled out

See merge request GNOME/gtk!4391
2022-01-18 15:07:37 +00:00
Jonas Ådahl
be7a391a13 wayland: Don't always restore the saved size when floating
We only save the size when we transition from floating to fixed, so that
we can restore the size to the one prior to being fixed.

However, we should not restore to this size whenever we see a 0x0 size
from xdg_toplevel, as it can do that any time it doesn't care about the
size, e.g. when the surface is floating and just changing state.

Fix this by only using the saved size when transitioning from fixed to
floating, not when staying floating while previously floating.

Closes: https://gitlab.gnome.org/GNOME/gtk/-/issues/4634
2022-01-18 15:46:10 +01:00
Emmanuele Bassi
23aec81f1a reftest: Avoid assertions being compiled out
Calling functions inside a g_assert() means those functions will be
compiled out when building with G_DISABLE_ASSERT.

This fixes the release job in the CI pipeline.
2022-01-18 14:07:37 +00:00
Alexandros Theodotou
738d962aca gtk: document return value of ShortcutFunc 2022-01-18 10:58:47 +00:00
Luca Bacci
93bc97b7ec Merge branch 'fix-keyboard-shortcuts-win32' into 'main'
Win32 key events cleanup

See merge request GNOME/gtk!4349
2022-01-17 13:34:17 +00:00
Luca Bacci
243bb57a27 GdkWin32: Add translation result w/o CAPS LOCK to key events for accelerator matching 2022-01-17 14:14:55 +01:00
Luca Bacci
4916ebd05e GdkWin32: Remove _gdk_input_codepage variable
It's unused
2022-01-17 14:14:55 +01:00
Luca Bacci
8bbf48eb64 GdkWin32: Code reorganization for gdk_event_translate 2022-01-17 14:14:47 +01:00
Matthias Clasen
56920092b9 Merge branch 'ebassi/issue-4596' into 'main'
i18n: Detect more translatable attribute values

Closes #4596

See merge request GNOME/gtk!4383
2022-01-17 12:58:01 +00:00
Luca Bacci
672ab4fc35 Merge branch 'win32-imcontextime-ignore-control-characters' into 'main'
Fix handling of control characters & remove Win32-specific hacks from gdkkeyuni.c

Closes #2865

See merge request GNOME/gtk!4387
2022-01-17 11:44:12 +00:00
Philip Zander
52616dee8e GtkIMContextIME: Ignore ASCII control characters
Make GtkIMContextIME ignore ASCII control characters just like other
IMContext implementations (e.G. GtkIMContextSimple). Fixes bogus
characters appearing in text input fields (old bug 676077).
2022-01-17 12:03:01 +01:00
Chun-wei Fan
905f021bbd Revert "Bug 676077: Fix handling of Keyboard Input on Windows"
The actual code that does the IM context code handling on Windows now uses the
native Windows APIs to handle keystrokes, so this patch is no longer needed, as
it was found that it instead caused issues.

Pointed out in issue #2865.

This reverts commit fd6ce9975e.
2022-01-17 11:38:37 +01:00
Kritphong Mongkhonvanit
55016ada92 gdksurface-wayland: Fix contradictory assert
gdk_wayland_toplevel_inhibit_idle() contained a contradictory assert
that always fail. More specifically, in the branch that is supposed to
create the idle inhibitor, there is an assertion that it must already
exist and that the refcount must be greater than zero. This causes a
crash on WMs/DEs that use the ZWP idle inhibit manager protocol such as
KDE Plasma and Sway. Fix this by just asserting that the refcount is
zero instead.
2022-01-17 15:50:08 +07:00
Aurimas Černius
3bfaaab4f7 Updated Lithuanian translation 2022-01-16 21:38:08 +02:00
Emmanuele Bassi
9e83eb6501 i18n: Detect more translatable attribute values
GtkBuilder uses GMarkup, which defines a boolean attribute value as:

- yes/no
- true/false
- 1/0

The ITS file for GtkBuilder UI definitions is only using the first pair,
likely because Glade only ever used those values. GTK's own tools, though,
will typically simplify the full yes/no and true/false strings to 1 and 0,
to minimise the parsing time.

Fixes: #4596
2022-01-16 14:03:05 +00:00
Luca Bacci
ef1905a665 post install: query media modules 2022-01-14 18:57:03 +01:00
Sebastian Dröge
c44badd26a Mark various GskTransform functions as nullable in their return value
Various transforms are normalized with their next transform, and if they
end up being the identity transform will return NULL.

For example a translation by (x,y,z) and followed by (-x,-y,-z) will
result in NULL.
2022-01-14 11:57:23 +02:00
Jonas Ådahl
66ebc660b4 wayland/surface: Use wl_surface_offset() instead of x,y of attach()
This makes the hotspot of DND surfaces work when using the Vulkan and
OpenGL renderers.

This bumps the CI image used to the newly built image. This is needed to
install a new enough libwayland-client.so needed for wl_surface.offset.

This is done by adding wayland as a meson subproject, building it
on-demand if the version in the system is not new enough. As
libwayland-client.so is pulled in implicitly when linking to gtk4, the
compile step needs LD_LIBRARY_PATH set to make ld find the right library
to link to.
2022-01-14 09:27:07 +01:00
Luca Bacci
06e5da456f Merge branch 'win32-fix-altgr-gtk4' into 'main'
IMContextSimple/IMContextIME: Fix AltGr not working on Win32 [GTK4]

See merge request GNOME/gtk!4375
2022-01-13 23:02:50 +00:00
Boyuan Yang
689486eae5 Update Chinese (China) translation 2022-01-13 20:20:45 +00:00
Emmanuele Bassi
48dc6ecfe3 Merge branch 'ebassi/docs-repo-link' into 'main'
docs: Point source links to the correct branch

See merge request GNOME/gtk!4373
2022-01-13 16:58:47 +00:00
Philip Zander
b9bc7d9166 IMContextSimple/IMContextIME: Fix AltGr not working on Win32
The old code assumed that any key press containing Ctrl or Alt cannot be
regular text input. This is not correct on Win32 as AltGr = Ctrl + Alt.
2022-01-13 17:26:59 +01:00
Emmanuele Bassi
63ee135a1e Update the link to the development branch
The default development branch for GTK is now "main".
2022-01-13 14:42:34 +00:00
Emmanuele Bassi
ca2aa52ba9 docs: Point to the correct development branch
The default development branch of GTK is now "main".
2022-01-13 14:39:39 +00:00
Emmanuele Bassi
96d28738c9 docs: Point source links to the correct branch
The default development branch for GTK is now "main".
2022-01-13 14:39:03 +00:00
Piotr Drąg
e4b05e55e1 Update POTFILES.in 2022-01-13 13:43:15 +01:00
Luca Bacci
4a4a579fd9 Merge branch 'forward-port-gdk-win32-keymap-bugfixes-to-gtk4' into 'main'
GdkWin32Keymap bugfixes

See merge request GNOME/gtk!4372
2022-01-12 21:36:19 +00:00
Fran Dieguez
df716e5c9f Update Galician translation 2022-01-12 21:35:13 +00:00
Fran Dieguez
52000177d9 Update Galician translation 2022-01-12 21:34:57 +00:00
David Hogan
7d6257cb1e gdkkeys-win32: Perform keyboard layout substitution
For some users, GetKeyboardLayoutNameA() returns an alias instead of the
fully resolved keyboard layout identifier. In that case, we have to
query the registry to resolve the alias before we can look up the DLL
path.

See comments under https://gitlab.gnome.org/GNOME/gtk/-/issues/4610
2022-01-12 21:44:28 +01:00
Philip Zander
db0234ecb4 gdkkeys-win32: Fix handling of SGCAPS
Contrary to what you can read on the internet, SGCAPS keys don't work
by having capslock toggle the KBDCTRL bit, they actually have two
consecutive table entries, the first of which is for the normal
version and the second of which is for the capslocked version.

Background: SGCAPS is short for Swiss German caps because Swiss German
was the first layout to use this feature. For keys with the SGCAPS flag,
capslock has a different effect than pressing shift. For example:
Shift + ü = è,  CapsLock + ü = Ü,  CapsLock + Shift + ü = È
2022-01-12 21:44:24 +01:00
Philip Zander
438fad803e gdkkeys-win32: Fix crash when keyboard DLL failed to load
DLL loading failures should not happen under normal circumstances, but
we should at least try not to crash and and print better diagnostic
messages if they do happen.

See https://gitlab.gnome.org/GNOME/gtk/-/issues/4610
2022-01-12 21:44:15 +01:00
Philip Zander
82f8f878bc gdkkeys-win32: Add keysym mapping for capslock key
Add missing mapping between VK_CAPITAL and GDK_KEY_Caps_Lock, so
applications get a meaningful keyval rather than ffffff.
2022-01-12 21:44:07 +01:00
Philip Zander
b0818f9535 gdkkeys-win32: Fix capslock handling
Previously, we treated CapsLock and KanaLock as part of the global
keyboard state, much like NumLock and ScrollLock, rather than using
the supplied modifier mask. This was because GDK does not have a
modifier mask for KanaLock, only for CapsLock, so it would not have been
possible to properly support it.

However, this approach ended up causing problems, with certain keyboard
shortcuts not registering when capslock was active. This was first
observed in Inkscape [0] and appears to affect shortcuts consisting of a
single key (like 'a') with no additional modifiers (wheareas shortcuts
like 'ctrl+a' work).

So now we are using the supplied GDK_LOCK_MASK instead, and dropped
support for KanaLock, which we probably don't need anyway (since regular
text input should be handled by the IME input module -- the keymap is
mainly for shortcuts and keybindings, where you don't really want
KanaLock).

[0] https://gitlab.com/inkscape/inkscape/-/issues/3082
2022-01-12 21:43:53 +01:00
Luca Bacci
c71cb35e9d Merge branch 'forward-port-rewrite-gdkwin32keymap-to-gtk4' into 'main'
Rewrite GdkWin32Keymap (V2)

Closes #1033 and #2055

See merge request GNOME/gtk!4338
2022-01-12 19:53:54 +00:00
Luca Bacci
5bf5d25bc1 Merge branch 'fix-build-no-pangoft' into 'main'
Improve and fix building font features on Windows (was: Fix builds without PangoFT2)

Closes #4605

See merge request GNOME/gtk!4339
2022-01-12 19:53:39 +00:00
Matthias Clasen
45d6b3ba51 Merge branch 'fabian.kirsch-main-patch-28134' into 'main'
corrected small typo input-handling.md

See merge request GNOME/gtk!4368
2022-01-12 19:38:10 +00:00
Matthias Clasen
e4e1b9ccbe Merge branch '4627-printing-Unref-old-spool_io-before-setting-new-one' into 'main'
printing: Unref old spool_io before setting new one

Closes #4627

See merge request GNOME/gtk!4370
2022-01-12 19:37:18 +00:00
Matthias Clasen
d50df7db37 Merge branch 'revert-texture-annotations' into 'main'
Revert "gir: Annotate `GdkTexture` constructors for reading from a...

See merge request GNOME/gtk!4371
2022-01-12 19:34:18 +00:00
Matthias Clasen
7257d1c15f Revert "gir: Annotate GdkTexture constructors for reading from a file/memory/resource to return a GdkMemoryTexture"
This reverts commit ae8e844dec.

No agreement that this will stay this way going forward.
2022-01-12 14:11:20 -05:00
Philip Zander
ea65abc7e2 Rewrite GdkWin32Keymap (load table directly from layout DLL)
The old code used repeated calls to `ToUnicodeEx` to populate
the translation table, which is slow and buggy. The new code
directly loads the layout driver DLLs from Windows.

See https://gitlab.gnome.org/GNOME/gtk/-/merge_requests/4338
2022-01-12 19:01:35 +01:00
Marek Kasik
915090f118 printing: Unref old spool_io before setting new one
Unref private spool_io of GtkPrintJob before setting it to a new one
in gtk_print_job_set_source_file() and gtk_print_job_set_source_fd()
to prevent a leak.

Fixes: #4627
2022-01-12 12:47:28 +01:00
Chun-wei Fan
629dcd3dcf meson.build: Don't apply iso-codes cflag on Windows
They are no longer applicable for Windows builds.
2022-01-12 17:29:30 +08:00
Chun-wei Fan
169172a9e0 demos: Always build font explorer demo
We are no longer using PangoFT2 APIs in this demo, so make sure that we build
it on all builds since we already depend on a HarfBuzz/Pango version that
provide everything that we need here.

Drop the unnecessary pangofc-font.h include as a result.
2022-01-12 17:29:30 +08:00
Chun-wei Fan
0a3fad4d47 gtk-demo/language-names.c: Acquire language names natively on Windows
Like what was done on gtk/language-names.c, acquire the language names via the
native Windows NLS APIs, eliminating a run-time dependency on iso-codes on
Windows.
2022-01-12 17:29:30 +08:00
Chun-wei Fan
b666a767e4 language-names: Use Windows APIs to acquire language names
Instead of relying on the iso-codes package, use the native Windows NLS APIs to
acquire the localized (translated) language names so that we do not need to
incur an extra runtime dependency on Windows.  It's not coverering 100% of the
languages that we would like to support through this, but should cover much of
the things that are required.
2022-01-12 17:29:30 +08:00
Chun-wei Fan
ee2dd1acc7 gtk/meson.build: Fix builds without PangoFT2
We aren't really using PangoFT2 for [language|script]-names.c, and are
always using items from them, so make sure they are being built.

Also always include the pangoft2 dependency in gtk_dep if it is found.
2022-01-12 17:29:28 +08:00
Fabian Kirsch
4f36583898 corrected small typo input-handling.md 2022-01-12 09:02:01 +00:00
Matthias Clasen
21d40fc038 Merge branch 'fix-directory-list' into 'main'
directorylist: Fix several issues

Closes #3784

See merge request GNOME/gtk!4367
2022-01-12 02:58:25 +00:00
Matthias Clasen
93ff65c685 Merge branch 'should_be_mapped' into 'main'
gdk/wayland/surface: Remove redundant `should_be_mapped` code

See merge request GNOME/gtk!4203
2022-01-12 02:48:10 +00:00
Matthias Clasen
7e7201745d Merge branch 'wip/keep-scale' into 'main'
wayland/surface: Only update the scale if on any outputs

See merge request GNOME/gtk!4352
2022-01-12 02:46:43 +00:00
Matthias Clasen
50a986605c Merge branch 'ebassi/for-main' into 'main'
tests: Don't drop chdir()'s return value on the floor

See merge request GNOME/gtk!4328
2022-01-12 02:45:15 +00:00
Matthias Clasen
96994568fd Merge branch 'bilelmoussaoui/build' into 'main'
meson: only update-icon-cache when the demos are built

See merge request GNOME/gtk!4358
2022-01-12 02:44:29 +00:00
Matthias Clasen
b494d94bdb Merge branch 'drop-script-names' into 'main'
Drop the script name data

See merge request GNOME/gtk!4361
2022-01-12 02:43:54 +00:00
Matthias Clasen
9d6ccc0fe0 Merge branch 'texture-new-return-types' into 'main'
gir: Annotate `GdkTexture` constructors for reading from a...

See merge request GNOME/gtk!4365
2022-01-12 02:42:17 +00:00
Matthias Clasen
a56e187352 Merge branch 'nielsdg/gsk-gl-renderer-assertion' into 'main'
gsk: Document gsk_renderer_realize()

See merge request GNOME/gtk!4363
2022-01-12 02:41:32 +00:00
Matthias Clasen
dcdcc659ef directorylist: Fix several issues
We were handling events in the wrong order,
by doing async calls for some of them, but not
for all of them.

And we were not taking into account that GFileMonitors
RENAMED events may or may not move a file on top
of an existing file.

Fixes: #3784
2022-01-11 21:35:19 -05:00
Sebastian Dröge
ae8e844dec gir: Annotate GdkTexture constructors for reading from a file/memory/resource to return a GdkMemoryTexture 2022-01-11 15:46:22 +02:00
Niels De Graef
e566ba54d9 gsk: Document gsk_renderer_realize()
Document the return value and more importantly, specify that a call to
`gsk_renderer_realize()` needs to be matched with a call
`gsk_renderer_unrealize()`.

Prevents issues like https://gitlab.gnome.org/GNOME/gtk/-/issues/4625
2022-01-11 13:09:53 +01:00
Matthias Clasen
70732afb95 Drop the script name data
It is not used in GTK itself, and gtk4-demo
has its own copy.
2022-01-10 10:43:05 -05:00
Danial Behzadi
f2aed69f87 Update Persian translation 2022-01-10 11:39:53 +00:00
Emmanuele Bassi
6bd96522e8 Merge branch 'docs-typo-list' into 'main'
Fix typo in IconView docs

See merge request GNOME/gtk!4360
2022-01-09 13:28:57 +00:00
Sebastian Dröge
1e26c352d6 Fix typo in IconView docs
g_lsit_free_full() -> g_list_free_full()
2022-01-09 13:59:59 +02:00
Timm Bäder
2de65ebd4d Merge branch 'wip/smcv/png-endian' into 'main'
png: Correct endianness for big-endian machines

Closes #4616

See merge request GNOME/gtk!4357
2022-01-09 08:21:54 +00:00
Bilal Elmoussaoui
ed3d9aaaed meson: only update-icon-cache when the demos are built
Without building the demos, nothing gets installed into $prefix/share/icons/hicolor. Which makes running 
`gtk4-update-icon-cache` on the machine causes an error. This is easily reproducible on a Windows machine with MSVC where 
there is nothing pre-installed on hicolor icon theme and that makes building gtk without the demos fails with "No such file or directory".
2022-01-09 07:27:59 +00:00
Jordi Mas
27a3998c8f Update Catalan translation 2022-01-08 22:55:05 +01:00
Simon McVittie
979c124e57 png: Correct endianness for big-endian machines
libpng wants to receive samples in either RGB or RGBA order, whether
each sample is big-endian or not. This resolves test failures in
testsuite/gdk/memorytexture.c (and a lot of reftests) on s390x, and
probably the PowerPC family too.

Modifying the test to show the color in use and write out the PNG bytes
to a file, and running the memorytexture test on s390x, produces a PNG
that loads with the correct color values in GIMP (on an x86_64 machine),
which seems like evidence that this is the correct change and not just
compensating errors.

Resolves: https://gitlab.gnome.org/GNOME/gtk/-/issues/4616
Signed-off-by: Simon McVittie <smcv@debian.org>
2022-01-08 17:09:29 +00:00
Emmanuele Bassi
20ad839075 tests: Don't drop chdir()'s return value on the floor
Avoid a compile time warning, and ensure that the test suite is actually
doing its job.
2022-01-08 15:17:25 +00:00
Emmanuele Bassi
bed67edd2e Merge branch 'ebassi/docs-for-main' into 'main'
Document side effect of GLArea:has-depth-buffer

Closes #838

See merge request GNOME/gtk!4351
2022-01-07 19:14:59 +00:00
Jonas Ådahl
6efcc02806 wayland/surface: Only update the scale if on any outputs
If we ended up on no output at all, keep the HiDPI scale as is, as it
likely means we were on a workspace that was switched away from. By
keeping the same scale, we avoid unnecessary scale changes that would
otherwise take place if the scale when on monitors would end up being
more than 1.
2022-01-07 19:32:04 +01:00
Emmanuele Bassi
8a6dd2805f Document side effect of GLArea:has-depth-buffer
We enable depth testing when creating a depth buffer.

Fixes: #838
2022-01-07 18:30:54 +00:00
Matthias Clasen
464219c0fa Merge branch 'wip/baedert/for-master' into 'main'
label: Remove a redundant assignment

See merge request GNOME/gtk!4348
2022-01-07 16:47:07 +00:00
Timm Bäder
e602768794 Merge branch 'ebassi/docs-for-main' into 'main'
docs: Clean up the ToggleButton description

See merge request GNOME/gtk!4347
2022-01-07 16:25:41 +00:00
Timm Bäder
262f2a1453 Make some code samples compile 2022-01-07 17:21:37 +01:00
Timm Bäder
b408967278 label: Remove a redundant assignment
clang-tidy says:

gtklabel.c:1188:15: warning: Although the value stored to 'mid' is used in the enclosing expression, the value is never actually read from 'mid'
        min = mid = text_width;
              ^     ~~~~~~~~~~

Which seems right since mid will be assigned to at the beginning of the
next loop iteration anyway.
2022-01-07 17:21:37 +01:00
Emmanuele Bassi
1fd97fed91 docs: Clean up the ToggleButton description
- Use different headings
- Fix the coding style of the example
2022-01-07 15:42:08 +00:00
Matthias Clasen
fef179b625 Merge branch 'matthiasc/for-main' into 'main'
docs; Update supported backends

See merge request GNOME/gtk!4344
2022-01-07 03:16:47 +00:00
Matthias Clasen
87ac411c50 Merge branch 'doc-improvs-ii' into 'main'
Doc improvements on textures

See merge request GNOME/gtk!4342
2022-01-07 03:16:19 +00:00
Matthias Clasen
46a7aaac76 Merge branch 'wip/chergert/fix-textview-dnd-move-same-view' into 'main'
textview: remove drag selection after dnd move action

See merge request GNOME/gtk!4346
2022-01-07 03:15:48 +00:00
Christian Hergert
e14d6fe9d5 textview: remove drag selection after dnd move action
If we have a GDK_ACTION_MOVE, we need to delete the selection. However,
previously this only worked when the drop target and drag source were
different applications, as the selection would get messed up along the
way.

Instead, we stash marks for the duration of the operation so that we can
delete the appropriate selection when completing the move.
2022-01-06 16:30:34 -08:00
Matthias Clasen
fb5b2d3d8e docs; Update supported backends
Some strings have changed here.
2022-01-06 14:56:16 -05:00
Matthias Clasen
9dccdd1008 Merge branch 'docs-improvs-i' into 'main'
docs: Improve docs for four classes

See merge request GNOME/gtk!4337
2022-01-06 19:19:31 +00:00
Benjamin Otte
8e8a746cce Merge branch 'wip/otte/for-main' into 'main'
testsuite: clear_current() when done

See merge request GNOME/gtk!4343
2022-01-06 19:07:58 +00:00
Maximiliano Sandoval R
ee71effe98 docs: State that Textures are thread safe gobjects 2022-01-06 19:30:54 +01:00
Maximiliano Sandoval R
ce2c4f0f08 docs: Improve docs for MemoryTexture 2022-01-06 19:30:30 +01:00
Maximiliano Sandoval R
ef9dbf73cc gir: Add type annotations for {GL,Memory}Texture 2022-01-06 19:30:29 +01:00
Maximiliano Sandoval R
3bed5334bf docs: Improve docs for gdktexture.c 2022-01-06 19:30:28 +01:00
Benjamin Otte
5dc940ead2 glcontext: Don't spew warnings on surfaceless contexts
Get the display directly instead of via the nonexisting surface.
2022-01-06 19:23:29 +01:00
Benjamin Otte
7872b41f16 testsuite: clear_current() when done
That way we ensure that the GL context(s) get disposed, which they
previously weren't due to them still being the current context.

This also implicitly adds testing of gLContext destruction, which
previously wasn't ever done by any test.
2022-01-06 19:22:47 +01:00
Jordi Mas
be81f6b4ab Update Catalan translation 2022-01-06 08:25:29 +01:00
Maximiliano Sandoval R
1229032b4e docs: Add misc links 2022-01-05 14:06:43 +01:00
Maximiliano Sandoval R
ad73e2d07b docs: Improve docs for gskrendernode.c 2022-01-05 14:06:42 +01:00
Maximiliano Sandoval R
6d80135342 docs: Improve docs for gtksnapshot.c 2022-01-05 14:06:41 +01:00
Maximiliano Sandoval R
c36a10da83 docs: Improve docs for gtkversion.h 2022-01-05 13:24:32 +01:00
Maximiliano Sandoval R
c30d09cef4 docs: Improve docs for gtkactionable.c 2022-01-05 13:24:30 +01:00
Aleksandr Melman
716e0b97bd Update Russian translation 2022-01-05 11:03:11 +00:00
Matthias Clasen
ff862dc926 Merge branch 'wip/smcv/gresource-internal' into 'main'
build: Tell glib-compile-resources to make symbols internal where possible

See merge request GNOME/gtk!4334
2022-01-04 18:58:14 +00:00
Simon McVittie
17c2a1cb4e build: Tell glib-compile-resources to make symbols internal where possible
Partial solution to https://gitlab.gnome.org/GNOME/gtk/-/issues/4598

Signed-off-by: Simon McVittie <smcv@debian.org>
2022-01-04 18:08:22 +00:00
Aleksandr Melman
895e640fd0 Update Russian translation 2022-01-04 17:00:55 +00:00
Emmanuele Bassi
e8f5f86ad5 Merge branch 'label-fix-section-link' into 'main'
docs: Fix link to section in GtkLabel

See merge request GNOME/gtk!4333
2022-01-04 15:54:05 +00:00
Marco Melorio
5055b41ee7 docs: Fix link to section in GtkLabel 2022-01-04 16:33:00 +01:00
Matthias Clasen
7efd08ca2e Merge branch 'fix-hc-warning' into 'main'
gdk/display-wayland: Don't bypass portal for theme entries

Closes #4593

See merge request GNOME/gtk!4331
2022-01-04 14:51:05 +00:00
Hugo Carvalho
76b421e064 Update Portuguese translation 2022-01-04 14:12:59 +00:00
Luca Bacci
063e6baa0a Merge branch 'gtk-grab-file-chooser-native-win32' into 'main'
GTK grab for GtkFileChooserNativeWin32

Closes #4582

See merge request GNOME/gtk!4329
2022-01-04 13:59:08 +00:00
Florian Müllner
9e5d412a8b gdk/display-wayland: Don't bypass portal for theme entries
When commit 49589e1da added support for the new high-contrast key,
it missed that the getter should only use the setting directly when
not going through the portal.

https://gitlab.gnome.org/GNOME/gtk/-/issues/4593
2022-01-04 14:58:58 +01:00
Daniel Mustieles
fa9b634d8f Updated Spanish translation 2022-01-04 14:38:09 +01:00
Matthias Clasen
d76379428d Merge branch 'noexecstack' into 'main'
Make our stack noexec

Closes #4598

See merge request GNOME/gtk!4330
2022-01-04 13:09:39 +00:00
Matthias Clasen
46509b6dd2 Make our stack noexec
The change to use ld and objcopy for resources
had some side-effects: it leaked a few symbols
and made our stack executable. We don't want that.

Use -z nonexecstack and --strip-all to avoid this.

Fixes: #4598
2022-01-04 07:51:56 -05:00
Daniel Mustieles
89dbf9cc81 Updated Spanish translation 2022-01-04 12:18:11 +01:00
Luca Bacci
c138aaabf3 Use a GTK grab when showing a modal GtkFileChooserNativeWin32 2022-01-04 10:46:20 +01:00
Yuri Chornoivan
7cef454c86 Update Ukrainian translation 2022-01-03 20:51:23 +00:00
Emmanuele Bassi
5cb8d15505 Merge branch 'fredmorcos-master-patch-48389' into 'main'
Minor doc fix

See merge request GNOME/gtk!4325
2022-01-03 13:34:00 +00:00
Luca Bacci
2aab55983d Merge branch 'wgl-legacy' into 'main'
GSK/GL: Relax check for GL 3.x+ legacy contexts

See merge request GNOME/gtk!4187
2022-01-03 13:11:04 +00:00
Fred Morcos
31714e5c1d Minor doc fix 2022-01-03 10:27:51 +00:00
Luca Bacci
96c351e792 Merge branch 'for-main' into 'main'
For main

See merge request GNOME/gtk!4322
2022-01-03 09:51:10 +00:00
Matthias Clasen
edd57004d3 Merge branch 'matthiasc/for-main' into 'main'
fontchooser: Use new hb api

See merge request GNOME/gtk!4323
2022-01-03 02:52:45 +00:00
Matthias Clasen
234d20641c fontbutton: Pass the fontmap to the dialog 2022-01-02 21:37:32 -05:00
Matthias Clasen
dd802f21e7 fontchooser: Cosmetics
Use harfbuzz api to format variations and features.
That matches what pango uses to parse them.
2022-01-02 21:37:32 -05:00
Matthias Clasen
dbbc990c72 fontchooser: Use new hb api
Use hb_font_get_var_coords_design if we have it.
This should fix our handling of fonts with AVAR.
2022-01-02 21:37:32 -05:00
Matthias Clasen
3a6e772cba Merge branch 'wip/antoniof/expression-autocleanup' into 'main'
gtk: Define the GtkExpression autocleanup func

See merge request GNOME/gtk!4319
2022-01-02 17:49:49 +00:00
António Fernandes
c9fa16fcfa gtk: Define the GtkExpression autocleanup func 2022-01-02 17:49:48 +00:00
Luca Bacci
07b04fbea9 Remove some unneeded files from gdk/win32
bdfcursor.c, cursor.bdf and libwntab32x.la
2022-01-02 18:49:44 +01:00
Luca Bacci
1c633cbea2 Add hid.lib to pkg-config file listing 2022-01-02 18:45:17 +01:00
Luca Bacci
2f685d5d2a Remove leftover code dealing with input-only windows 2022-01-02 18:42:33 +01:00
Luca Bacci
0fdf2cc195 Fix compilation with clang
From https://github.com/msys2/MINGW-packages/pull/9509
2022-01-02 18:42:33 +01:00
Luca Bacci
4f7d18a28f Do not use GetProcAddress for FlashWindowEx
It's available since Windows XP
2022-01-02 18:42:32 +01:00
Luca Bacci
c77272a7d7 Remove call to ShowOwnedPopups (FALSE) to hide owned windows
This is needed to fully support windows with the property
"destroy-with-parent" set to FALSE.
2022-01-02 18:42:31 +01:00
Luca Bacci
7a1004df73 Remove WM_SYNCPAINT message handler
It was added to work around what seemed to be an OS or graphics
driver issue on Windows XP. The issue was not reproducible on
Windows Vista anyway.

References:
* https://bugzilla.gnome.org/show_bug.cgi?id=153567
* https://gitlab.gnome.org/GNOME/gtk/-/commit/c8fef535
* https://devblogs.microsoft.com/oldnewthing/20120723-00/?p=7073
2022-01-02 18:42:31 +01:00
Matthias Clasen
0e86d2b345 Merge branch 'ebassi/issue-4576' into 'main'
Update the accessible description of MenuButton

Closes #4576

See merge request GNOME/gtk!4317
2022-01-02 01:12:53 +00:00
Matthias Clasen
2441bdb900 Merge branch 'radioactiveman-main-patch-13472' into 'main'
texture: Fix typo in error message

See merge request GNOME/gtk!4311
2022-01-02 00:51:43 +00:00
Matthias Clasen
57679b7b7f Merge branch 'wip-fontchooser-tewaks' into 'main'
Revert "fontchoserwidget: Do our own face filtering"

See merge request GNOME/gtk!4314
2022-01-02 00:50:57 +00:00
Emmanuele Bassi
37063e7a05 Update the accessible description of MenuButton
We update the labelled-by relation, but we never update the described-by
one.

Fixes: #4576
2022-01-02 00:35:53 +00:00
Matthias Clasen
791dc7b9be fontchooser: Speed up fature examples
We were doing unnecessary work here, which could
get really slow with some fonts. Just compute
the reverse charmap once and reuse it.
2022-01-01 15:38:04 -05:00
Matthias Clasen
ff24dfb2e7 Revert "fontchooserwidget: Revise handling of named instances"
This reverts commit 2dc56a6e9b.

This wasn't ready yet.
2022-01-01 15:36:29 -05:00
Matthias Clasen
4db60fa5a8 Revert "fontchoserwidget: Do our own face filtering"
This reverts commit b7b6c147f9.

This was premature.
2022-01-01 15:36:27 -05:00
Emmanuele Bassi
5301367630 Merge branch 'bilelmoussaoui/g-i' into 'main'
gdk: add missing nullable annotations

See merge request GNOME/gtk!4310
2022-01-01 20:22:18 +00:00
Bilal Elmoussaoui
9409b7ef7d gtk: mark few GtkPrinterSettings as nullable
Everything that makes use of gtk_printer_settings_get should be nullable
Because the hashtable might not contain the key and there's no default value provided
2022-01-01 19:20:29 +01:00
Bilal Elmoussaoui
afeb7f668b gtk: mark few GtkFileChooser functions as nullable
- get_file, if no file is selected returns a NULL
- get_id, if the interface doesn't implement such function returns NULL
2022-01-01 19:11:10 +01:00
Bilal Elmoussaoui
38b8da0f5f gtk: mark gtk_flatten_list_model_get_model_for_item as nullable 2022-01-01 19:07:13 +01:00
Bilal Elmoussaoui
d029b62d23 gtk: mark gtk_mount_operation_get_parent as nullable 2022-01-01 19:05:33 +01:00
Bilal Elmoussaoui
1e9bdb4647 gtk: mark gtk_list_box_get_adjustment as nullable
similar to its setter function
2022-01-01 19:05:06 +01:00
Bilal Elmoussaoui
1d72024605 gtk: mark MenuButton::get_label/get_icon_name as nullable 2022-01-01 18:38:56 +01:00
Bilal Elmoussaoui
06570443b7 gtk: mark gtk_icon_view_create_drag_icon as nullable 2022-01-01 18:33:29 +01:00
Bilal Elmoussaoui
77f7caf18d gtk: mark gtk_glarea_get_context as nullable 2022-01-01 18:26:40 +01:00
Thomas Lange
8767ffde2f texture: Fix typo in error message 2022-01-01 17:23:22 +00:00
Bilal Elmoussaoui
d58b7fa779 gtk: mark gtk_text_mark_get_buffer as nullable 2022-01-01 18:19:41 +01:00
Bilal Elmoussaoui
dcbf3f8879 gtk: mark gtk_lock_button_get_permission as nullable
like the constructor/setter
2022-01-01 18:17:31 +01:00
Bilal Elmoussaoui
30d8c8e17c gtk: mark buildable_get_id as nullable
the vfunc can return a nullable
2022-01-01 18:12:05 +01:00
Bilal Elmoussaoui
b803bb5edb gtk: mark MultiSelection::get_model as nullable
the constructor & setter takes a nullable model
2022-01-01 18:04:24 +01:00
Bilal Elmoussaoui
985a39d41f gtk: mark gtk_native_get_for_surface as nullable 2022-01-01 17:59:35 +01:00
Bilal Elmoussaoui
f846eec894 gtk: mark gtk_no_selection_get_model nullable
The constructor is nullable so should the getter be
2022-01-01 17:56:07 +01:00
Bilal Elmoussaoui
e7fc8ad1f5 gtk: fix PasswordEntry annotation 2022-01-01 17:49:11 +01:00
Bilal Elmoussaoui
95169ad54b gtk: add nullable annotations to PopoverMenuBar/PopoverMenu
The constructor/setter accepts a null as a model so should the getter
2022-01-01 17:47:21 +01:00
Bilal Elmoussaoui
ddb2e91a42 gtk: add nullable annotations for Scrollable getters
The adjustment setters takes a nullable and so should the getters be annotated
2022-01-01 17:39:45 +01:00
Bilal Elmoussaoui
90357193c9 gtk: add nullable annotation to gtk_css_section_get_file
The constructor takes a nullable file param
2022-01-01 17:31:38 +01:00
Bilal Elmoussaoui
a336fe2850 gdk: add missing nullable annotations 2022-01-01 17:03:10 +01:00
Matthias Clasen
fcb8e4cf37 Merge branch 'fontchooser-tweaks' into 'main'
fontchooserwidget: Avoid a crash

See merge request GNOME/gtk!4309
2021-12-31 18:32:49 +00:00
Matthias Clasen
b7b6c147f9 fontchoserwidget: Do our own face filtering
Pango may not do this for us, so don't rely on it.
We only show one face with a given name, and we
prefer a variable face over a non-variable one.

The check for variable faces requires new Pango
API that will be in Pango 1.52.
2021-12-31 09:58:26 -05:00
Emmanuele Bassi
35ee82ca07 Merge branch 'wip/baedert/for-master' into 'main'
baseline = -1 means no baseline

Closes #4385

See merge request GNOME/gtk!4307
2021-12-31 14:55:20 +00:00
Matthias Clasen
2dc56a6e9b fontchooserwidget: Revise handling of named instances
Allowing to tweak the axes of named instances does
not do any harm. If we don't, we have to worry that
we need at least one non-named-instance in the face
list, and make it more obvious how to pick it out.
2021-12-31 09:50:47 -05:00
Matthias Clasen
e12ef76de5 fontchooserwidget: Avoid a crash
languages may be NULL, we need to be more careful here.
2021-12-31 09:49:40 -05:00
Matthias Clasen
536b05e35b maplistmodel: Cosmetics 2021-12-31 09:48:34 -05:00
Timm Bäder
1354854d23 inspector: Fix coding style
ffs
2021-12-31 14:41:35 +01:00
Timm Bäder
2b062d60f2 baseline = -1 means no baseline
Fixes #4385
2021-12-31 13:08:01 +01:00
Matthias Clasen
c8bdb4c7fb Merge branch 'fontchooser-cleanups' into 'main'
fontchooser: Stop using pangofc api

See merge request GNOME/gtk!4306
2021-12-31 04:30:04 +00:00
Matthias Clasen
80328e8a4f fontchooser: Stop using pangofc api
Pango now has backend-independent api for all
we need, so we can drop all the ifdefs.
2021-12-30 22:52:52 -05:00
Emmanuele Bassi
1138e3770b Merge branch 'bilelmoussaoui/g-i' into 'main'
g-i: add missing nullable annotation

See merge request GNOME/gtk!4304
2021-12-30 17:12:59 +00:00
Bilal Elmoussaoui
ec58013b22 g-i: add missing nullable annotation
the constructor takes a nullable expression parameter, so should the getter be
2021-12-30 16:52:53 +00:00
Matthias Clasen
70cb61fb71 4.6.0 2021-12-30 10:31:52 -05:00
Yuri Chornoivan
8e6a0ec23d Update Ukrainian translation 2021-12-29 22:17:32 +00:00
Matthias Clasen
e2ab334636 Merge branch 'doc-window' into 'main'
Document built-in actions on GtkWindow

See merge request GNOME/gtk!4297
2021-12-29 17:23:16 +00:00
Matthias Clasen
dd0effe957 Merge branch 'wip/chergert/4575-fix-texthistory-selection' into 'main'
testsuite: ignore texthistory selection on delete/backspace

Closes #4575

See merge request GNOME/gtk!4287
2021-12-29 14:58:53 +00:00
Hofer-Julian
ac210c1765 docs: Add missing star to block comment 2021-12-29 15:46:59 +01:00
Hofer-Julian
c58e48e648 doc: Fix docs of window.minimize 2021-12-29 15:45:44 +01:00
Hofer-Julian
acdadab617 docs: Document built-in actions on GtkWindow 2021-12-29 15:45:43 +01:00
Matthias Clasen
aa19194f7b Merge branch 'wip/exalm/inspector' into 'main'
inspector: Register extension on startup

See merge request GNOME/gtk!4296
2021-12-29 14:38:28 +00:00
Matthias Clasen
9319a6e39b Merge branch 'matthiasc/for-main' into 'main'
tests: Make fontchooser test build on macOS

See merge request GNOME/gtk!4300
2021-12-29 14:34:26 +00:00
Matthias Clasen
b41206abab tests: Make fontchooser test build on macOS
Not sure what changed here, but we want to
be able to build this without fontconfig too.
2021-12-29 09:15:26 -05:00
Matthias Clasen
07c3dc6b6f Merge branch 'nullable' into 'main'
popover: Add missing nullable annotation

Closes #4556

See merge request GNOME/gtk!4295
2021-12-29 00:28:09 +00:00
Matthias Clasen
fa71a2a993 Merge branch 'wip/baedert/for-master' into 'main'
application demo: Resolve a keyboard shortcut conflict

See merge request GNOME/gtk!4290
2021-12-29 00:24:46 +00:00
Alexander Mikhaylenko
b997d1e892 inspector: Register extension on startup 2021-12-29 04:42:51 +05:00
Alexander Mikhaylenko
4b71fba540 Revert "inspector: Export gtk_inspector_init"
This reverts commit 3f5107cea5.
2021-12-29 04:12:16 +05:00
Ian Douglas Scott
48d39c0a57 popover: Add missing nullable annotation
Fixes https://gitlab.gnome.org/GNOME/gtk/-/issues/4556.

Looks like the other `Popover` methods are have correct nullable
annotations.
2021-12-28 09:43:06 -08:00
Hugo Carvalho
0aad053507 Update Portuguese translation 2021-12-27 22:53:20 +00:00
Matthias Clasen
6ed14b2a5f Merge branch 'm-shinder-master-patch-90567' into 'main'
gdk_content_provider_get_value() argument should have 'out' direction

See merge request GNOME/gtk!4283
2021-12-27 15:08:48 +00:00
Matthias Clasen
c7df5ef957 Merge branch 'get-key-capture-widget-nullable' into 'main'
GtkSearchBar - Mark get_key_capture_widget() return value as nullable

See merge request GNOME/gtk!4286
2021-12-27 15:06:56 +00:00
Yuri Chornoivan
a9013febcf Update Ukrainian translation 2021-12-27 14:08:03 +00:00
Benjamin Otte
815c430ba1 Merge branch 'wip/otte/for-main' into 'main'
inspector: Add dnd inspection support

See merge request GNOME/gtk!4289
2021-12-27 13:54:27 +00:00
Timm Bäder
e94d5bf006 applicationwindow: Don't pass for_size < -1 to measure()
If the application window is measured with for_size -1 horizontally,
this code clearly passes something lower to the parent class measure()
implementation. Only subtract the menubar_height if we're passed a
for_size > -1.
2021-12-27 12:15:02 +01:00
Timm Bäder
a00480f4a1 application demo: Resolve a keyboard shortcut conflict
There were two menu entries side-by-side with the same keyboard shortcut
2021-12-27 10:02:03 +01:00
Benjamin Otte
6da952100c inspector: Add dnd inspection support
This has lots of issues:
 * It randomly crashes when data is loading while the dnd goes away.
 * The data gets randomly reset at the wrong time
 * Can't scroll the window on Wayland
 * ...

But it's better than nothing, so better get it committed.
2021-12-27 05:59:16 +01:00
Benjamin Otte
df8588e9b7 Merge branch 'wip/otte/for-main' into 'main'
widget: Don't queue an allocate on a nonexisting parent

See merge request GNOME/gtk!4288
2021-12-26 23:20:34 +00:00
Benjamin Otte
fce9b35e4d css: Don't crash on invalid rotate3d() 2021-12-26 22:58:09 +01:00
m-shinder
6fd4421add Merge branch 'main' into 'm-shinder-master-patch-90567'
# Conflicts:
#   NEWS
2021-12-26 21:20:33 +00:00
Benjamin Otte
7149bfd100 widget: Don't queue an allocate on a nonexisting parent
No test, no idea how to trigger this reliably.
2021-12-26 22:17:54 +01:00
Christian Hergert
344ad0355e textview: scroll insert onscreen after undo/redo
After performing an action such as undo/redo, we need to actually scroll
to the position where the operation occurred.

I do note that the scroll here seems to often get invalidated if it is
pages away, and we never make the full scroll. But I've seen this all over
the place elsewhere too and that needs to be handled, most likely, as a
more comprehensive fix for scrolling during line validation.

Related #4575
2021-12-26 12:56:42 -08:00
Christian Hergert
e7871fbc43 texthistory: always track selection bounds
It's cheap to store the selection position, so always set it even if we
are in a user section. Otherwise, we risk not having the right position
when starting a delete action within a begin_user_action(),
end_user_action() pair.

Related #4575
2021-12-26 12:47:45 -08:00
Christian Hergert
99d8dd751e testsuite: add failing test for delete selection
This adds a test to expose the failure of #4575 which results in the
selection being incorrect when performing a delete as we are likely
already in a begin_user_action()/end_user_action() pair.

Related #4575
2021-12-26 12:46:16 -08:00
Christian Hergert
22b1abb36d testsuite: ignore texthistory selection on delete/backspace
We don't need to apply these here, as it will clear the selection which is
needed for the undo. Otherwise we won't be able to test that we end up at
the right selection afterwards.
2021-12-26 12:43:22 -08:00
Sebastian Dröge
aa289d1023 GtkSearchBar - Mark get_key_capture_widget() return value as nullable
The setter allows setting NULL so this can clearly also return NULL
under normal circumstances.

Same for the corresponding API in GtkSearchEntry.
2021-12-26 11:06:34 +02:00
Emmanuele Bassi
ef51e02767 Merge branch 'ebassi/build-fixes' into 'main'
build: Replace source_root()

See merge request GNOME/gtk!4281
2021-12-25 17:26:06 +00:00
Benjamin Otte
7118127139 Merge branch 'wip/otte/gles' into 'main'
Fix GLES

Closes #4571

See merge request GNOME/gtk!4285
2021-12-25 15:34:01 +00:00
Benjamin Otte
2ce2afa036 gles: Be picky abpout glGetFramebufferAttachmentParameter()
This function does not at all work like in OpenGL - if it works at all.
So make it behave accordingly.

Fixes #4571
2021-12-25 15:07:44 +01:00
Benjamin Otte
5803dd765d gles: glGetTexLevelParameter() isn't supported 2021-12-25 15:07:44 +01:00
Benjamin Otte
6a310b5069 gles: GLES 2 doesn't have glDrawBuffers()
So don't call it.
2021-12-25 15:07:44 +01:00
Benjamin Otte
2caab68be9 gl: Change gdk_gl_context_check_version()
Instead of just passing major/minor, pass them twice, once for GL and
once for GLES. This way, we don't need to check for GL and GLES
separately.

If something is supported unconditionally, passing 0/0 works fine.

That said, I'd like to group the arguments somehow, because otherwise
it's just a confusing list of numbers - but I have no idea how to do
that.
2021-12-25 15:07:44 +01:00
Benjamin Otte
4e2dbc1258 glcontext: Use different log levels for GL debug
We want critical GL debug messages to be critical, so that the testsuite
sudokus itself when they appear.

This is relevant in particular for GLES warnings in the GLES runner,
because its warnings can cause crashes on GL drivers less forgiving than
Mesa.

Related: #4571
2021-12-25 15:07:44 +01:00
Emmanuele Bassi
40eca1a68e Apply 1 suggestion(s) to 1 file(s) 2021-12-25 13:29:07 +00:00
m-shinder
98f937ba15 Fix: Set direction for value parameter 2021-12-25 10:04:43 +00:00
Emmanuele Bassi
a70988ecd5 build: Remove deprecated get_pkgconfig_variable()
Replace it with `get_variable(pkgconfig:...)`.
2021-12-24 15:55:26 +00:00
Emmanuele Bassi
6f2ff620bd build: Replace deprecated 'gui_app'
Use `win_subsystem: 'windows'` instead.
2021-12-24 15:51:11 +00:00
Emmanuele Bassi
bd772610b1 build: Replace source_root()
Use project_source_root(), which replaces the deprecated source_root().
2021-12-24 15:48:06 +00:00
Matthias Clasen
de42b5bfae sizerequest: Remove critical warning for now
At last as long as widgets like GtkFlowBox and
GtkGrid still trigger this, it is not a great
idea to have this warning in a stable release.
So remove it for 4.6
2021-12-23 16:59:26 -05:00
Benjamin Otte
fcdd5173bd Merge branch 'wip/otte/for-main' into 'main'
gl: Clear current when destroying current's surface

Closes #4554

See merge request GNOME/gtk!4279
2021-12-22 19:45:53 +00:00
Benjamin Otte
c419799313 gl: Clear current when destroying current's surface
When destroying the EGLSurface or GLXDrawable of a GdkSurface, make sure
the current context is not still bound to it.

If it is, clear the current context.

Fixes #4554
2021-12-22 20:00:52 +01:00
Matthias Clasen
c5973a630b Merge branch 'wip/baedert/for-master' into 'main'
label: Fix get_natural_wrap_mode() precondition check

See merge request GNOME/gtk!4278
2021-12-22 16:54:18 +00:00
Timm Bäder
e5a88b64b1 label: Fix get_natural_wrap_mode() precondition check 2021-12-22 17:38:33 +01:00
Hugo Carvalho
74f58a49b9 Update Portuguese translation 2021-12-22 14:05:50 +00:00
Yuri Chornoivan
cff9d9f5eb Update Ukrainian translation 2021-12-22 12:52:52 +00:00
Timm Bäder
ddd64f2918 Merge branch 'fix_typos' into 'main'
Fix minor typo

See merge request GNOME/gtk!4275
2021-12-22 08:08:38 +00:00
Yuri Chornoivan
9f06f53a59 Fix minor typo 2021-12-21 23:42:12 +02:00
Yuri Chornoivan
4c00d7a306 Update Ukrainian translation 2021-12-21 21:36:53 +00:00
Matthias Clasen
88726e12f7 Merge branch 'high-contrast-4' into 'main'
gdk/wayland: Support new `high-contrast` key

See merge request GNOME/gtk!4271
2021-12-21 19:20:34 +00:00
Matthias Clasen
248bb148af Merge branch 'discrete-scroll' into 'main'
Don't keep discrete scroll events in the queue

See merge request GNOME/gtk!4274
2021-12-21 18:22:53 +00:00
Florian Müllner
49589e1da1 gdk/wayland: Support new high-contrast key
We now have a boolean setting that determines whether the high-contrast
theme should be used. Support it by automatically setting the existing
`gtk-theme-name` and `gtk-icon-theme-name` properties when enabled.

With that, it is no longer necessary to change the regular theme settings
for high-contrast, so toggling between high-contrast and a non-default
theme finally works reliably.
2021-12-21 14:02:02 +01:00
Matthias Clasen
552267b93d Don't keep discrete scroll events in the queue
We are not going to compress those anyway.
2021-12-20 14:51:37 -05:00
Matthias Clasen
855357f871 Merge branch 'testsuite-introspection-extend-envvars' into 'main'
testsuite: introspection: Do not override environment variables.

See merge request GNOME/gtk!4268
2021-12-20 19:08:59 +00:00
Benjamin Otte
c83cba2322 Merge branch 'wip/otte/diff' into 'main'
Make render node diffing not slow

Closes #4560 and #2396

See merge request GNOME/gtk!4269
2021-12-20 19:01:52 +00:00
Benjamin Otte
20dcc31d19 rendernode: Limit diff region
Limit the diff region to 30 rectangles (randomly chosen because it
looked big enough to not trigger by accident and small enough to not
cause performance issues).

If the diff region gets more complicated, we abort to the parent node
and use its bounds as the diff region instead and then continue diffing
the rest of the node tree.

Fixes: #4560
Fixes: #2396
2021-12-20 18:40:02 +01:00
Maxim Cournoyer
29e6cc5808 testsuite: introspection: Do not override environment variables.
Functional package managers such as GNU Guix rely on environment
variables such as GI_TYPELIB_PATH to discover the system libraries and
resources; extend rather than override them.

* testsuite/introspection/meson.build (env): New variable that extends
rather than override the GI_TYPELIB_PATH and LD_PRELOAD environment
variables.
(api): Use the above as the value of the 'env' keyword argument.
2021-12-20 11:22:41 -05:00
Benjamin Otte
4e6ee28bcb gsk: Allow diffing code to abort
Now the vfuncs can decide they don't want to diff anymore, not just the
actual diff function.
2021-12-20 17:08:15 +01:00
Hugo Carvalho
4b3247576a Update Portuguese translation 2021-12-20 16:07:31 +00:00
Matthias Clasen
69edf17c2a Merge branch 'wip/otte/wrapping-is-natural' into 'main'
label: Add gtk_label_set_natural_wrap_mode()

See merge request GNOME/gtk!4267
2021-12-20 15:49:05 +00:00
Matthias Clasen
d91a4ad1dd Merge branch 'progressbar-queue-allocate' into 'main'
progressbar: Queue allocate when setting "inverted"

See merge request GNOME/gtk!4264
2021-12-20 15:45:36 +00:00
Matthias Clasen
9b750ef69f Merge branch 'ebassi/find-gi' into 'main'
build: Check for the gi python module

See merge request GNOME/gtk!4266
2021-12-20 15:41:51 +00:00
Fran Dieguez
0bf22ee3ce Update Galician translation 2021-12-20 08:50:36 +00:00
Benjamin Otte
981ed22dff label: Add gtk_label_set_natural_wrap_mode()
Allows influencing natural size requests so that labels can request more
width than necessary for a given height.

Related: !4245
Related: #4535
2021-12-20 02:28:37 +01:00
Emmanuele Bassi
d40321ef63 ci: Add pygobject to the MSYS2 job 2021-12-19 16:26:37 +00:00
Emmanuele Bassi
c94996e8e8 build: Check for the gi python module
The introspection tests depend on the pygobject module, but we currently
are not checking if it's available at configuration time, which means we
can get build failures like:

> ModuleNotFoundError: No module named 'gi'

when running the test suite.
2021-12-19 16:06:49 +00:00
Marco Melorio
4b19dd46dd progressbar: Queue allocate when setting "inverted" 2021-12-18 18:45:28 +01:00
Piotr Drąg
942e841cbc Update POTFILES.skip 2021-12-18 13:36:19 +01:00
Yuri Chornoivan
e0a595273a Update Ukrainian translation 2021-12-18 06:29:43 +00:00
Matthias Clasen
92ca52822c Merge branch 'meson-msvc-cleanup' into 'main'
Remove Visual Studio 2013 bits from Meson files

See merge request GNOME/gtk!4249
2021-12-17 12:58:01 +00:00
Hugo Carvalho
f89dbce93c Update Portuguese translation 2021-12-17 12:41:33 +00:00
Matthias Clasen
28f0e2eb2a 4.5.1 2021-12-16 21:43:20 -05:00
Matthias Clasen
47ac080565 Merge branch 'wip/otte/for-main' into 'main'
label: word-char wrapping should word-wrap for natural size

Closes #4535

See merge request GNOME/gtk!4245
2021-12-17 02:11:50 +00:00
Matthias Clasen
afdf5cfde9 NEWS: Updates 2021-12-16 21:00:47 -05:00
Matthias Clasen
a4760bcff7 Merge branch 'toolbar-combobox' into 'main'
Don't make all buttons in toolbars flat

Closes #4384

See merge request GNOME/gtk!4103
2021-12-17 00:35:18 +00:00
Matthias Clasen
72e571a3de Merge branch 'main' into 'main'
docs: Mention GtkImage and GtkPicture changes

Closes #4415

See merge request GNOME/gtk!4251
2021-12-17 00:32:08 +00:00
Jakub Kulík
484c0fdd15 docs: Mention GtkImage and GtkPicture changes 2021-12-17 00:32:08 +00:00
Matthias Clasen
2636fb7c8d Merge branch 'wip/baedert/for-master' into 'main'
settings test: Print expected and seen values

See merge request GNOME/gtk!4259
2021-12-17 00:31:20 +00:00
Benjamin Otte
99c2936e90 Merge branch 'wip/otte/inspector' into 'main'
inspector: Add measure graph

See merge request GNOME/gtk!4260
2021-12-16 21:46:52 +00:00
Benjamin Otte
66c74d6091 inspector: Add measure graph
Generates a graph visualizing calls to gtk_widget_measure().

Generation of the graph can be slow - like when it forces Pango to wrap
a huge label 1000s of times.

You can dnd the graph to look at it closer or to impress people in
gitlab issues.
2021-12-16 19:36:54 +01:00
Benjamin Otte
a43ba245e2 inspector: Remove a stray g_print() 2021-12-16 19:36:54 +01:00
Benjamin Otte
810d734eda label: Fix docs 2021-12-16 19:36:54 +01:00
Hugo Carvalho
687d6c5dc4 Update Portuguese translation 2021-12-16 15:48:11 +00:00
Luca Bacci
5e090c1fac Merge branch 'fix-3728-3799' into 'main'
GDK-Win32: Force toplevel surfaces to configure as needed (fix issues #3728 and #3799)

Closes #3728 and #3799

See merge request GNOME/gtk!3712
2021-12-16 14:58:03 +00:00
Timm Bäder
ceb61e6600 gskglcommandqueue: Mark some variables G_GNUC_UNUSED
These are unused if sysprof isn't being used.
2021-12-16 11:06:50 +01:00
Timm Bäder
ae60293c24 textlayout: Remove unused-but-set variables 2021-12-16 11:06:50 +01:00
Timm Bäder
e411081c84 settings test: Print expected and seen values
That test breaks locally (and in CI it seems?), so at least print the
values we see.
2021-12-16 11:06:50 +01:00
Matthias Clasen
0682a5e45e Merge branch 'event-recorder' into 'main'
inspector: Add axes to event details in recorder

See merge request GNOME/gtk!4258
2021-12-16 04:34:01 +00:00
Matthias Clasen
4f751aa53d inspector: Highlight event sequences
Optionally, highlight rows of events whose
event sequences match the selected event.
2021-12-15 22:07:07 -05:00
Matthias Clasen
27fa51cfa6 wayland: Add sequences for touchpad gestures
It makes sense.
2021-12-15 21:58:57 -05:00
Matthias Clasen
2772ff624f gdk: Prepare touchpad events for sequences
It makes sense to connect the begin/update/end events
for touchpad swipes and pinches in a sequence. This
commit adds the plumbing for it, but not backends
are setting sequences yet.
2021-12-15 21:58:57 -05:00
Matthias Clasen
69b160cfe8 inspector: Details about touchpad events
Useful to have for debugging these.
2021-12-15 21:58:57 -05:00
Matthias Clasen
ee7541c032 inspector: Add axes to event details in recorder
This is useful information if you have devices
producing such events.
2021-12-15 21:58:57 -05:00
Matthias Clasen
abf6068d91 docs: Add some information about event axes 2021-12-15 21:58:57 -05:00
Sveinn í Felli
9d5f3e787d Update Icelandic translation 2021-12-15 19:44:49 +00:00
Sveinn í Felli
ab2b9ba444 Update Icelandic translation 2021-12-15 18:37:57 +00:00
Matthias Clasen
6ab1aff531 Merge branch 'event-recorder' into 'main'
inspector: Tweaks to the recorder

See merge request GNOME/gtk!4256
2021-12-15 05:51:28 +00:00
Matthias Clasen
6012276093 Fix event history
Collecting of history wasn't working correctly
for either motion or scroll events.
2021-12-15 00:30:50 -05:00
Matthias Clasen
9648cf226b inspector: Show event history in recorder
This was instrumental in debugging why
scroll compression does not work.
2021-12-14 23:43:29 -05:00
Matthias Clasen
56532a505d Cosmetrics: Remove mention of a nonexisting type
No such thing as GdkScrollHistory.
2021-12-14 23:42:35 -05:00
Matthias Clasen
6bb2e5625a inspector: Remove debug spew 2021-12-14 22:03:52 -05:00
Matthias Clasen
d57a5dffa1 inspector: Add event recording
Make the recorder also keep track of events,
and show them in some detail.
2021-12-14 22:01:40 -05:00
Matthias Clasen
1028ca0841 inspector: More tweaks to the recorder
Put the two left columns in a stack, and add
an empty page there. This will let us add
other recording types in the future, with
their own pages.
2021-12-14 19:51:35 -05:00
Matthias Clasen
6dbe6b42c2 inspector: Tweaks to the recorder
Don't show the profiler data in the frame list,
instead show timestamps there.
2021-12-14 19:34:53 -05:00
Matthias Clasen
7611c3ea03 Merge branch 'matthiasc/for-main' into 'main'
inspector: Use a listview in the recorder

See merge request GNOME/gtk!4255
2021-12-15 00:06:11 +00:00
Christian Hergert
2fa9f934b6 a11y: return -1 if parent is NULL 2021-12-14 21:18:13 +01:00
Matthias Clasen
e9fd7b7ed6 inspector: Use a listview in the recorder
Its the awesome new list widget, lets use it!
2021-12-14 15:10:11 -05:00
Matthias Clasen
075e954b71 Merge branch 'ebassi/issue-4543' into 'main'
Add a boxed GType for GtkBitsetIter

Closes #4543

See merge request GNOME/gtk!4253
2021-12-14 18:09:01 +00:00
Emmanuele Bassi
3f7122b3d2 Add a boxed GType for GtkBitsetIter
This way language bindings have a chance at managing the memory of
GtkBitset iterators.

Fixes: #4543
2021-12-14 15:51:13 +00:00
Hugo Carvalho
35251c6d9c Update Portuguese translation 2021-12-14 14:20:25 +00:00
Hugo Carvalho
173594365c Update Portuguese translation 2021-12-14 14:03:49 +00:00
Yuri Chornoivan
2fc44fb27d Update Ukrainian translation 2021-12-14 13:21:33 +00:00
Aurimas Černius
0264630c90 Updated Lithuanian translation 2021-12-14 13:41:59 +02:00
Chun-wei Fan
e2b4108377 Revert "gtk/meson.build: Fix linking on Visual Studio 2013"
We now require a Pango version that requires Visual Studio 2015 or later to
build, and non-UCRT-based (VS2013) binaries may not bode well with
UCRT-based binaries (VS2015+). Drop the support for VS2013 as a result.

This reverts commit e208e0e07886248d4d86118aa5591c9882f0ed5c.
2021-12-14 10:29:28 +08:00
Benjamin Otte
02c484e844 label: Fix docs 2021-12-13 18:23:32 +01:00
Benjamin Otte
5face79cd0 label: word-char wrapping should word-wrap for natural size
Testcase added

Fixes #4535
2021-12-13 14:49:39 +01:00
Chun-wei Fan
da535164b4 gdksurface-win32.c: Rename window->surface as appropriate
Update the functions that were updated in the previous commit to have all
GdkSurface variables named as 'surface' instead of the GTK-3.x-era window, to
make things more consistent across the board.  Also fix formatting a bit.
2021-12-01 17:32:40 +08:00
Chun-wei Fan
82d9570ed4 GDK-Win32: Make surface ready for updates
Make the toplevel surface respond to size computations unless it is just being
created, or maximized, made fullscreen or underwent an AeroSnap operation.

This will ensure that the surface size is properly computed in time, so that
surfaces can be resized as needed.

This will fix issues 3728 and 3799.
2021-12-01 17:32:40 +08:00
Chun-wei Fan
a619e8af4a gskglcompiler.c: Relax check for GL 3.x+ legacy contexts
On Windows with nVidia drivers at least, when we create a legacy context
via wglCreateContext(), we may still get a (W)GL 4.x context.  Allow
such contexts to also use GLSL version 130 instead of 110, so that
things do continue to work.
2021-12-01 17:29:02 +08:00
Ian Douglas Scott
25ec20d861 gdk/wayland/surface: Remove redundant should_be_mapped code
As far as I can tell, the code here is redundant and probably ended up
this way for historical reasons. A drag surface without
`->is_drag_surface` would be created if `gdk_display_create_surface`
were called with `GDK_SURFACE_TEMP`, but drag surfaces never seem to be
created that way.

In `gtk4-demos`, drag and drop and popovers seem to be working normally
with this.
2021-11-30 10:36:46 -08:00
Matthias Clasen
0579220546 Mention 'main' branch in NEWS
The default development branch is now `main`.
This commit only exists on `master` to point people
towards that.
2021-11-29 18:13:06 -05:00
Matthias Clasen
031c37c7b0 theme: Remove GtkToolbar remnants
We don't ship a widget with css name 'toolbar'
anymore, so don't waste selectors on it.
2021-10-29 11:51:18 -04:00
Matthias Clasen
860821114a Don't make all buttons in toolbars flat
When a combobox is put in a toolbar, we don't want
its button to lose its border.

Fixes: #4384
2021-10-29 11:51:18 -04:00
Matthias Clasen
73bba62d82 widget-factory: Add a color button to the toolbar
This is to check that our 'nested' buttons come out as
expected in a toolbar context.
2021-10-29 11:51:18 -04:00
635 changed files with 126388 additions and 107055 deletions

View File

@@ -25,7 +25,7 @@ variables:
BACKEND_FLAGS: "-Dx11-backend=true -Dwayland-backend=true -Dbroadway-backend=true"
FEATURE_FLAGS: "-Dvulkan=enabled -Dcloudproviders=enabled"
MESON_TEST_TIMEOUT_MULTIPLIER: 3
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v35"
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v36"
FLATPAK_IMAGE: "registry.gitlab.gnome.org/gnome/gnome-runtime-images/gnome:master"
.only-default:
@@ -88,7 +88,7 @@ fedora-x86_64:
- meson compile -C _build
- meson install -C _build
- PKG_CONFIG_PATH=${CI_PROJECT_DIR}/_install/lib64/pkgconfig:${CI_PROJECT_DIR}/_install/share/pkgconfig meson setup _build_hello examples/hello
- meson compile -C _build_hello
- LD_LIBRARY_PATH=${CI_PROJECT_DIR}/_install/lib64 meson compile -C _build_hello
- .gitlab-ci/run-tests.sh _build x11
- .gitlab-ci/run-tests.sh _build wayland
- .gitlab-ci/run-tests.sh _build waylandgles
@@ -156,6 +156,11 @@ msys2-mingw64:
variables:
MSYSTEM: "MINGW64"
CHERE_INVOKING: "yes"
artifacts:
when: always
expose_as: 'Windows_DLL_MSYS2_64_bit_toolchain'
paths:
- "${CI_PROJECT_DIR}/_build/gtkdll.tar.gz"
macos:
extends: .only-default

View File

@@ -95,6 +95,8 @@ RUN dnf -y install \
weston-libs \
which \
xorg-x11-server-Xvfb \
&& dnf install -y 'dnf-command(builddep)' \
&& dnf builddep -y wayland \
&& dnf clean all
# Enable sudo for wheel users

View File

@@ -6,7 +6,7 @@ call "C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliar
:: FIXME: make warnings fatal
pip3 install --upgrade --user meson==0.59 || goto :error
meson -Dmedia-gstreamer=disabled _build || goto :error
meson -Ddebug=false -Dmedia-gstreamer=disabled _build || goto :error
ninja -C _build || goto :error
goto :EOF

View File

@@ -15,9 +15,9 @@ pacman --noconfirm -Suy
pacman --noconfirm -S --needed \
base-devel \
git \
mingw-w64-$MSYS2_ARCH-toolchain \
mingw-w64-$MSYS2_ARCH-cc \
mingw-w64-$MSYS2_ARCH-ccache \
mingw-w64-$MSYS2_ARCH-pkg-config \
mingw-w64-$MSYS2_ARCH-pkgconf \
mingw-w64-$MSYS2_ARCH-gobject-introspection \
mingw-w64-$MSYS2_ARCH-meson \
mingw-w64-$MSYS2_ARCH-adwaita-icon-theme \
@@ -30,8 +30,9 @@ pacman --noconfirm -S --needed \
mingw-w64-$MSYS2_ARCH-libepoxy \
mingw-w64-$MSYS2_ARCH-pango \
mingw-w64-$MSYS2_ARCH-fribidi \
mingw-w64-$MSYS2_ARCH-gst-plugins-bad \
mingw-w64-$MSYS2_ARCH-shared-mime-info
mingw-w64-$MSYS2_ARCH-gst-plugins-bad-libs \
mingw-w64-$MSYS2_ARCH-shared-mime-info \
mingw-w64-$MSYS2_ARCH-python-gobject
mkdir -p _ccache
export CCACHE_BASEDIR="$(pwd)"
@@ -72,3 +73,5 @@ unset CCACHE_DISABLE
ninja -C _build
ccache --show-stats
tar zcf _build/gtkdll.tar.gz _build/gtk/libgtk*.dll

190
NEWS
View File

@@ -1,8 +1,194 @@
Overview of Changes
===================
Overview of Changes in 4.6.1, 11-02-2022
========================================
* GtkFontChooser:
- Stop using PangoFc api
- Fix a crash
- Use new HarfBuzz api
* GtkMenuButton:
- Update accessible description
* GtkTextView:
- Fix intra-widget dnd
* Printing:
- Fix an fd leak
* Input:
- Make sure input methods get focus-in events
- Always flush events to avoid scroll event pileup
- Support hold events
- Update keysyms from libxkbcommon
* Theme:
- Improve text selection legibility
* Introspection:
- Add missing nullable annotations everywhere
* Build:
- Make stack noexec again
- Avoid symbol leaks
- Drop unneeded script data
* Windows:
- Stop using WM_SYNCPAINT
- Relax check for GL 3.x legacy contexts
- Use native apis for language names
- Rewrite the keymap code
- Use the GL renderer by default
* Wayland:
- Fix support for the new high-contrast setting
- Avoid redundant scale changes
- Fix DND hotspot handling
- Don't always restore the saved size when floating
* MacOS:
- Various performance improvements
* Translation updates:
Brazilian Portuguese
Catalan
Chinese (China)
Galician
Hebrew
Japanese
Lithuanian
Persian
Polish
Portuguese
Russian
Slovenian
Spanish
Ukrainian
Overview of Changes in 4.6.0, 30-12-2021
========================================
* GtkProgressBar:
- Fix handling of "inverted"
* GtkLabel:
- Add a "natural wrap mode" property to influence how
natural width is determined
* GtkTextView
- Scroll insertion on-screen after undo / redo
* gsk:
- Abort region diffing when changes are too complex
* gdk:
- Avoid compressing discrete scroll events
- Fix problems with hiding windows
- Improve GL and GLES version checks
* Wayland:
- Support new high-contrast setting
* Inspector:
- Add DND inspection support
* build:
- Avoid deprecated meson apis
* Translation updates
Galician
Portuguese
Ukrainian
Overview of Changes in 4.5.1, 16-12-2021
========================================
* GtkWidget sizing has been rewritten to implement
width-for-height more properly. This had some fallout,
and some widgets may still not react kindly to the
new way of doing things.
See https://blog.gtk.org/2021/12/03/sizable-news/
for details, and please file issues if you notice fallout.
* Rename git `master` branch to `main`
* Css:
- Fully support font-variant-caps
- Fix a crash with gradients
* Make various widgets activatable:
- GtkComboBox
- GtkDropDown
* GtkPopover:
- Make focus indicators not disappear
* GtkTextView:
- Don't leave embedded children stranded when scrolling
- Don't insert Emoji into non-editable textviews
- Fix Emoji chooser positioning
- Fix problems with pasting text
- Improve scroll-to-mark behavior
- Support right-aligned, centered and decimal tabs
- Make child anchor replacement character settable
- Provide more context to input methods
* GtkDragIcon:
- Provide default icons for paintables and files
* GtkBuilder:
- Speed up template precompilation
* Actions:
- Reduce allocations during signal emissions
- Avoid duplication and unnecessary recursion
* Inspector:
- Show the selected im-module in the General tab
- Add a clipboard viewer
- Make the recorder record events too
- Add a graph visualizing gtk_widget_measure()
* Gsk:
- Fix hexbox rendering
- Fix transformed linear gradient rendering
* Printing:
- Fix dialog-less printing
* Windows:
- Use the common EGL setup code
- Respect GDK_DEBUG=gl-egl
- Fix AeroSnap indicator and positioning
* X11:
- Improve behavior of windows drags on headerbar controls
- Trap errors for RANDR changes
- Fix problems with drag icons
* Wayland:
- Ensure we prefer the Wayland im-module over others
* Translation updates
Basque
Catalan
Croatian
Friulian
Galician
Hebrew
Icelandic
Italian
Latvian
Lithuanian
Occitan
Persian
Portuguese
Spanish
Swedish
Ukrainian
Overview of Changes in 4.5.0
============================

View File

@@ -43,7 +43,8 @@
"sources" : [
{
"type" : "git",
"url" : "https://gitlab.freedesktop.org/wayland/wayland.git"
"url" : "https://gitlab.freedesktop.org/wayland/wayland.git",
"branch" : "main"
}
]
},

View File

@@ -43,7 +43,8 @@
"sources" : [
{
"type" : "git",
"url" : "https://gitlab.freedesktop.org/wayland/wayland.git"
"url" : "https://gitlab.freedesktop.org/wayland/wayland.git",
"branch" : "main"
}
]
},

View File

@@ -43,7 +43,8 @@
"sources" : [
{
"type" : "git",
"url" : "https://gitlab.freedesktop.org/wayland/wayland.git"
"url" : "https://gitlab.freedesktop.org/wayland/wayland.git",
"branch" : "main"
}
]
},

View File

@@ -13,7 +13,7 @@ if 'DESTDIR' not in os.environ:
gtk_moduledir = os.path.join(gtk_libdir, 'gtk-' + gtk_api_version, gtk_abi_version)
gtk_printmodule_dir = os.path.join(gtk_moduledir, 'printbackends')
gtk_immodule_dir = os.path.join(gtk_moduledir, 'immodules')
gtk_mediamodule_dir = os.path.join(gtk_moduledir, 'media')
print('Compiling GSettings schemas...')
glib_compile_schemas = subprocess.check_output(['pkg-config',
@@ -40,6 +40,6 @@ if 'DESTDIR' not in os.environ:
gio_querymodules = 'gio-querymodules'
subprocess.call([gio_querymodules, gtk_printmodule_dir])
print('Updating module cache for input methods...')
os.makedirs(gtk_immodule_dir, exist_ok=True)
subprocess.call([gio_querymodules, gtk_immodule_dir])
print('Updating module cache for media backends...')
os.makedirs(gtk_mediamodule_dir, exist_ok=True)
subprocess.call([gio_querymodules, gtk_mediamodule_dir])

View File

@@ -17,7 +17,7 @@ executable('gtk4-constraint-editor',
c_args: common_cflags,
dependencies: libgtk_dep,
include_directories: confinc,
gui_app: true,
win_subsystem: 'windows',
link_args: extra_demo_ldflags,
install: false,
)

View File

@@ -24,6 +24,7 @@ do_cursors (GtkWidget *do_widget)
builder = gtk_builder_new_from_resource ("/cursors/cursors.ui");
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));
g_signal_connect (window, "destroy",
@@ -34,9 +35,7 @@ do_cursors (GtkWidget *do_widget)
if (!gtk_widget_get_visible (window))
gtk_widget_show (window);
else
{
gtk_window_destroy (GTK_WINDOW (window));
}
gtk_window_destroy (GTK_WINDOW (window));
return window;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,36 @@
#pragma once
#include <gtk/gtk.h>
G_BEGIN_DECLS
#define CURVE_TYPE_EDITOR (curve_editor_get_type ())
G_DECLARE_FINAL_TYPE (CurveEditor, curve_editor, CURVE, EDITOR, GtkWidget)
GtkWidget * curve_editor_new (void);
void curve_editor_set_edit (CurveEditor *self,
gboolean edit);
void curve_editor_set_path (CurveEditor *self,
GskPath *path);
GskPath * curve_editor_get_path (CurveEditor *self);
void curve_editor_set_stroke (CurveEditor *self,
GskStroke *stroke);
const GskStroke * curve_editor_get_stroke (CurveEditor *self);
void curve_editor_set_color (CurveEditor *self,
GdkRGBA *color);
const GdkRGBA * curve_editor_get_color (CurveEditor *self);
gboolean curve_editor_get_show_outline (CurveEditor *self);
void curve_editor_set_show_outline (CurveEditor *self,
gboolean show_outline);
G_END_DECLS

272
demos/gtk-demo/curve.c Normal file
View File

@@ -0,0 +1,272 @@
/* Path/Curve Editor
*
* This demo shows an elaborate curve editor that you would expect to find
* in a vector graphics editor. It is built on top of GTK's path APIs.
*/
#include <gtk/gtk.h>
#include "curve-editor.h"
static GskPath *
make_circle_path (void)
{
float w = 310;
float h = 310;
float cx = w / 2;
float cy = h / 2;
float pad = 20;
float r = (w - 2 * pad) / 2;
float k = 0.55228;
float kr = k * r;
GskPathBuilder *builder;
builder = gsk_path_builder_new ();
gsk_path_builder_move_to (builder, cx, pad);
gsk_path_builder_curve_to (builder, cx + kr, pad,
w - pad, cy - kr,
w - pad, cy);
gsk_path_builder_curve_to (builder, w - pad, cy + kr,
cx + kr, h - pad,
cx, h - pad);
gsk_path_builder_curve_to (builder, cx - kr, h - pad,
pad, cy + kr,
pad, cy);
gsk_path_builder_curve_to (builder, pad, cy - kr,
cx - kr, pad,
cx, pad);
gsk_path_builder_close (builder);
return gsk_path_builder_free_to_path (builder);
}
static void
edit_changed (GtkToggleButton *button,
GParamSpec *pspec,
CurveEditor *editor)
{
curve_editor_set_edit (editor, gtk_toggle_button_get_active (button));
}
static void
reset (GtkButton *button,
CurveEditor *editor)
{
GskPath *path;
path = make_circle_path ();
curve_editor_set_path (editor, path);
gsk_path_unref (path);
}
static void
line_width_changed (GtkSpinButton *spin,
CurveEditor *editor)
{
GskStroke *stroke;
stroke = gsk_stroke_copy (curve_editor_get_stroke (editor));
gsk_stroke_set_line_width (stroke, gtk_spin_button_get_value (spin));
curve_editor_set_stroke (editor, stroke);
gsk_stroke_free (stroke);
}
static void
cap_changed (GtkDropDown *combo,
GParamSpec *pspec,
CurveEditor *editor)
{
GskStroke *stroke;
stroke = gsk_stroke_copy (curve_editor_get_stroke (editor));
gsk_stroke_set_line_cap (stroke, (GskLineCap)gtk_drop_down_get_selected (combo));
curve_editor_set_stroke (editor, stroke);
gsk_stroke_free (stroke);
}
static void
join_changed (GtkDropDown *combo,
GParamSpec *pspec,
CurveEditor *editor)
{
GskStroke *stroke;
stroke = gsk_stroke_copy (curve_editor_get_stroke (editor));
gsk_stroke_set_line_join (stroke, (GskLineJoin)gtk_drop_down_get_selected (combo));
curve_editor_set_stroke (editor, stroke);
gsk_stroke_free (stroke);
}
static void
color_changed (GtkColorChooser *chooser,
GParamSpec *pspec,
CurveEditor *editor)
{
GdkRGBA color;
gtk_color_chooser_get_rgba (chooser, &color);
curve_editor_set_color (editor, &color);
}
static void
stroke_toggled (GtkCheckButton *button,
CurveEditor *editor)
{
curve_editor_set_show_outline (editor, gtk_check_button_get_active (button));
gtk_widget_queue_draw (GTK_WIDGET (editor));
}
static void
limit_changed (GtkSpinButton *spin,
CurveEditor *editor)
{
GskStroke *stroke;
stroke = gsk_stroke_copy (curve_editor_get_stroke (editor));
gsk_stroke_set_miter_limit (stroke, gtk_spin_button_get_value (spin));
curve_editor_set_stroke (editor, stroke);
gsk_stroke_free (stroke);
}
static void
dashes_changed (GtkEntry *entry,
GParamSpec *spec,
CurveEditor *editor)
{
const char *text;
char **split;
GArray *dash;
GskStroke *stroke;
text = gtk_editable_get_text (GTK_EDITABLE (entry));
split = g_strsplit (text, " ", 0);
dash = g_array_new (FALSE, FALSE, sizeof (float));
for (int i = 0; split[i] != NULL; i++)
{
double d;
char *endp = 0;
d = g_strtod (split[i], &endp);
if (*endp == '\0')
g_array_append_vals (dash, (float[1]) { d }, 1);
}
g_strfreev (split);
stroke = gsk_stroke_copy (curve_editor_get_stroke (editor));
gsk_stroke_set_dash (stroke, (const float *)dash->data, dash->len);
curve_editor_set_stroke (editor, stroke);
gsk_stroke_free (stroke);
g_array_free (dash, TRUE);
}
GtkWidget *
do_curve (GtkWidget *do_widget)
{
static GtkWidget *window = NULL;
GtkWidget *demo;
GtkWidget *edit_toggle;
GtkWidget *reset_button;
GtkWidget *titlebar;
GtkWidget *stroke_toggle;
GtkWidget *line_width_spin;
GtkWidget *stroke_button;
GtkWidget *popover;
GtkWidget *grid;
GtkWidget *cap_combo;
GtkWidget *join_combo;
GtkWidget *color_button;
GtkWidget *limit_spin;
GtkWidget *dash_entry;
if (!window)
{
window = gtk_window_new ();
gtk_window_set_title (GTK_WINDOW (window), "Curve Editor");
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
gtk_window_set_default_size (GTK_WINDOW (window), 315, 350);
edit_toggle = gtk_toggle_button_new ();
gtk_button_set_icon_name (GTK_BUTTON (edit_toggle), "document-edit-symbolic");
reset_button = gtk_button_new_from_icon_name ("edit-undo-symbolic");
stroke_button = gtk_menu_button_new ();
gtk_menu_button_set_icon_name (GTK_MENU_BUTTON (stroke_button), "open-menu-symbolic");
popover = gtk_popover_new ();
gtk_menu_button_set_popover (GTK_MENU_BUTTON (stroke_button), popover);
grid = gtk_grid_new ();
gtk_grid_set_row_spacing (GTK_GRID (grid), 6);
gtk_grid_set_column_spacing (GTK_GRID (grid), 6);
gtk_popover_set_child (GTK_POPOVER (popover), grid);
gtk_grid_attach (GTK_GRID (grid), gtk_label_new ("Color:"), 0, 0, 1, 1);
color_button = gtk_color_button_new_with_rgba (&(GdkRGBA){ 0., 0., 0., 1.});
gtk_grid_attach (GTK_GRID (grid), color_button, 1, 0, 1, 1);
gtk_grid_attach (GTK_GRID (grid), gtk_label_new ("Line width:"), 0, 1, 1, 1);
line_width_spin = gtk_spin_button_new_with_range (1, 20, 1);
gtk_spin_button_set_value (GTK_SPIN_BUTTON (line_width_spin), 1);
gtk_grid_attach (GTK_GRID (grid), line_width_spin, 1, 1, 1, 1);
gtk_grid_attach (GTK_GRID (grid), gtk_label_new ("Line cap:"), 0, 2, 1, 1);
cap_combo = gtk_drop_down_new_from_strings ((const char *[]){"Butt", "Round", "Square", NULL});
gtk_grid_attach (GTK_GRID (grid), cap_combo, 1, 2, 1, 1);
gtk_grid_attach (GTK_GRID (grid), gtk_label_new ("Line join:"), 0, 3, 1, 1);
join_combo = gtk_drop_down_new_from_strings ((const char *[]){"Miter", "Miter-clip", "Round", "Bevel", "Arcs", NULL});
gtk_grid_attach (GTK_GRID (grid), join_combo, 1, 3, 1, 1);
gtk_grid_attach (GTK_GRID (grid), gtk_label_new ("Miter limit:"), 0, 4, 1, 1);
limit_spin = gtk_spin_button_new_with_range (0, 10, 1);
gtk_spin_button_set_digits (GTK_SPIN_BUTTON (limit_spin), 1);
gtk_spin_button_set_value (GTK_SPIN_BUTTON (limit_spin), 4);
gtk_grid_attach (GTK_GRID (grid), limit_spin, 1, 4, 1, 1);
gtk_grid_attach (GTK_GRID (grid), gtk_label_new ("Dashes:"), 0, 5, 1, 1);
dash_entry = gtk_entry_new ();
gtk_grid_attach (GTK_GRID (grid), dash_entry, 1, 5, 1, 1);
stroke_toggle = gtk_check_button_new_with_label ("Show outline");
gtk_grid_attach (GTK_GRID (grid), stroke_toggle, 1, 6, 1, 1);
titlebar = gtk_header_bar_new ();
gtk_header_bar_pack_start (GTK_HEADER_BAR (titlebar), edit_toggle);
gtk_header_bar_pack_start (GTK_HEADER_BAR (titlebar), reset_button);
gtk_header_bar_pack_start (GTK_HEADER_BAR (titlebar), stroke_button);
gtk_window_set_titlebar (GTK_WINDOW (window), titlebar);
demo = curve_editor_new ();
g_signal_connect (stroke_toggle, "toggled", G_CALLBACK (stroke_toggled), demo);
g_signal_connect (edit_toggle, "notify::active", G_CALLBACK (edit_changed), demo);
g_signal_connect (reset_button, "clicked", G_CALLBACK (reset), demo);
g_signal_connect (cap_combo, "notify::selected", G_CALLBACK (cap_changed), demo);
g_signal_connect (join_combo, "notify::selected", G_CALLBACK (join_changed), demo);
g_signal_connect (color_button, "notify::rgba", G_CALLBACK (color_changed), demo);
g_signal_connect (line_width_spin, "value-changed", G_CALLBACK (line_width_changed), demo);
g_signal_connect (limit_spin, "value-changed", G_CALLBACK (limit_changed), demo);
g_signal_connect (dash_entry, "notify::text", G_CALLBACK (dashes_changed), demo);
reset (NULL, CURVE_EDITOR (demo));
gtk_spin_button_set_value (GTK_SPIN_BUTTON (line_width_spin), 6);
gtk_color_chooser_set_rgba (GTK_COLOR_CHOOSER (color_button), &(GdkRGBA) { 1, 0, 0, 1 });
gtk_drop_down_set_selected (GTK_DROP_DOWN (cap_combo), GSK_LINE_CAP_ROUND);
gtk_editable_set_text (GTK_EDITABLE (dash_entry), "0 8");
gtk_window_set_child (GTK_WINDOW (window), demo);
}
if (!gtk_widget_get_visible (window))
gtk_widget_show (window);
else
gtk_window_destroy (GTK_WINDOW (window));
return window;
}

View File

@@ -128,6 +128,7 @@
<file>fishbowl.ui</file>
<file>gtkfishbowl.c</file>
<file>gtkfishbowl.h</file>
<file>tiger.node</file>
</gresource>
<gresource prefix="/frames">
<file>frames.ui</file>
@@ -250,6 +251,10 @@
<gresource prefix="/video-player">
<file>bbb.png</file>
</gresource>
<gresource prefix="/curve">
<file>curve-editor.c</file>
<file>curve-editor.h</file>
</gresource>
<gresource prefix="/sources">
<file>application_demo.c</file>
<file>assistant.c</file>
@@ -267,6 +272,7 @@
<file>css_pixbufs.c</file>
<file>css_shadows.c</file>
<file>cursors.c</file>
<file>curve.c</file>
<file>dialog.c</file>
<file>drawingarea.c</file>
<file>dropdown.c</file>
@@ -287,6 +293,7 @@
<file>gears.c</file>
<file>gestures.c</file>
<file>glarea.c</file>
<file>glyphs.c</file>
<file>gltransition.c</file>
<file>headerbar.c</file>
<file>hypertext.c</file>
@@ -325,6 +332,9 @@
<file>paintable_symbolic.c</file>
<file>panes.c</file>
<file>password_entry.c</file>
<file>path_fill.c</file>
<file>path_maze.c</file>
<file>path_text.c</file>
<file>peg_solitaire.c</file>
<file>pickers.c</file>
<file>printing.c</file>
@@ -409,6 +419,9 @@
<gresource prefix="/fontrendering">
<file>fontrendering.ui</file>
</gresource>
<gresource prefix="/path_text">
<file>path_text.ui</file>
</gresource>
<gresource prefix="/org/gtk/Demo4">
<file>icons/16x16/actions/application-exit.png</file>
<file>icons/16x16/actions/document-new.png</file>

View File

@@ -11,6 +11,9 @@
#include "gtkgears.h"
#include "gskshaderpaintable.h"
#include "nodewidget.h"
#include "graphwidget.h"
const char *const css =
".blurred-button {"
" box-shadow: 0px 0px 5px 10px rgba(0, 0, 0, 0.5);"
@@ -201,6 +204,18 @@ create_menu_button (void)
return w;
}
static GtkWidget *
create_tiger (void)
{
return node_widget_new ("/fishbowl/tiger.node");
}
static GtkWidget *
create_graph (void)
{
return graph_widget_new ();
}
static const struct {
const char *name;
GtkWidget * (*create_func) (void);
@@ -218,6 +233,8 @@ static const struct {
{ "Switch", create_switch },
{ "Menubutton", create_menu_button },
{ "Shader", create_cogs },
{ "Tiger", create_tiger },
{ "Graph", create_graph },
};
static int selected_widget_type = -1;

View File

@@ -12,7 +12,6 @@
*/
#include <gtk/gtk.h>
#include <pango/pangofc-font.h>
#include <hb.h>
#include <hb-ot.h>
#include <glib/gi18n.h>

1168
demos/gtk-demo/glyphs.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,164 @@
#include "graphwidget.h"
struct _GraphWidget
{
GtkWidget parent_instance;
GskPath *path;
GskStroke *stroke;
GdkRGBA color;
GskPath *stroke_path;
guint tick_cb;
guint64 start_time;
double period;
double amplitude;
};
struct _GraphWidgetClass
{
GtkWidgetClass parent_class;
};
G_DEFINE_TYPE (GraphWidget, graph_widget, GTK_TYPE_WIDGET)
static void
update_path (GraphWidget *self,
float amplitude)
{
graphene_point_t p[20];
GskPathBuilder *builder;
g_clear_pointer (&self->path, gsk_path_unref);
g_clear_pointer (&self->stroke_path, gsk_path_unref);
for (int i = 0; i < 20; i++)
{
p[i].x = 10 * i;
p[i].y = 50;
if (i % 4 == 1 || i % 4 == 2)
{
if (i % 8 < 4)
p[i].y += amplitude;
else
p[i].y -= amplitude;
}
}
builder = gsk_path_builder_new ();
gsk_path_builder_move_to (builder, p[0].x, p[0].y);
for (int i = 0; i < 20; i += 4)
gsk_path_builder_curve_to (builder,
p[i+1].x, p[i+1].y,
p[i+2].x, p[i+2].y,
p[i+3].x, p[i+3].y);
self->path = gsk_path_builder_free_to_path (builder);
self->stroke_path = gsk_path_stroke (self->path, self->stroke);
}
static gboolean
tick_cb (GtkWidget *widget,
GdkFrameClock *frame_clock,
gpointer user_data)
{
GraphWidget *self = GRAPH_WIDGET (widget);
guint64 now;
double angle;
now = gdk_frame_clock_get_frame_time (frame_clock);
if (self->start_time == 0)
self->start_time = now;
angle = 360 * (now - self->start_time) / (double)(self->period * G_TIME_SPAN_MINUTE);
update_path (self, sin (angle) * self->amplitude);
gtk_widget_queue_draw (widget);
return G_SOURCE_CONTINUE;
}
static void
graph_widget_init (GraphWidget *self)
{
self->color.red = g_random_double_range (0, 1);
self->color.green = g_random_double_range (0, 1);
self->color.blue = g_random_double_range (0, 1);
self->color.alpha = 1;
self->period = g_random_double_range (0.5, 1);
self->amplitude = g_random_double_range (10, 25);
self->stroke = gsk_stroke_new (2);
update_path (self, 0);
self->start_time = 0;
self->tick_cb = gtk_widget_add_tick_callback (GTK_WIDGET (self), tick_cb, NULL, NULL);
}
static void
graph_widget_dispose (GObject *object)
{
GraphWidget *self = GRAPH_WIDGET (object);
gsk_path_unref (self->path);
gsk_stroke_free (self->stroke);
G_OBJECT_CLASS (graph_widget_parent_class)->dispose (object);
}
static void
graph_widget_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot)
{
GraphWidget *self = GRAPH_WIDGET (widget);
int width, height;
width = gtk_widget_get_width (widget);
height = gtk_widget_get_height (widget);
gtk_snapshot_push_fill (snapshot, self->stroke_path, GSK_FILL_RULE_WINDING);
gtk_snapshot_append_color (snapshot,
&self->color,
&GRAPHENE_RECT_INIT (0, 0, width, height));
gtk_snapshot_pop (snapshot);
}
static void
graph_widget_measure (GtkWidget *widget,
GtkOrientation orientation,
int for_size,
int *minimum,
int *natural,
int *minimum_baseline,
int *natural_baseline)
{
if (orientation == GTK_ORIENTATION_HORIZONTAL)
*minimum = *natural = 200;
else
*minimum = *natural = 100;
}
static void
graph_widget_class_init (GraphWidgetClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
object_class->dispose = graph_widget_dispose;
widget_class->snapshot = graph_widget_snapshot;
widget_class->measure = graph_widget_measure;
}
GtkWidget *
graph_widget_new (void)
{
return g_object_new (GRAPH_TYPE_WIDGET, NULL);
}

View File

@@ -0,0 +1,8 @@
#pragma once
#include <gtk/gtk.h>
#define GRAPH_TYPE_WIDGET (graph_widget_get_type ())
G_DECLARE_FINAL_TYPE (GraphWidget, graph_widget, GRAPH, WIDGET, GtkWidget)
GtkWidget * graph_widget_new (void);

View File

@@ -18,15 +18,81 @@
#include "language-names.h"
#ifdef G_OS_WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#else
#ifndef ISO_CODES_PREFIX
#define ISO_CODES_PREFIX "/usr"
#endif
#define ISO_CODES_DATADIR ISO_CODES_PREFIX "/share/xml/iso-codes"
#define ISO_CODES_LOCALESDIR ISO_CODES_PREFIX "/share/locale"
#endif
static GHashTable *language_map;
#ifdef G_OS_WIN32
/* if we are using native Windows use native Windows API for language names */
static BOOL CALLBACK
get_win32_all_locales_scripts (LPWSTR locale_w, DWORD flags, LPARAM param)
{
wchar_t *langname_w = NULL;
wchar_t locale_abbrev_w[9];
gchar *langname, *locale_abbrev, *locale, *p;
gint i;
const LCTYPE iso639_lctypes[] = { LOCALE_SISO639LANGNAME, LOCALE_SISO639LANGNAME2 };
GHashTable *ht_scripts_langs = (GHashTable *) param;
PangoLanguage *lang;
gint langname_size, locale_abbrev_size;
langname_size = GetLocaleInfoEx (locale_w, LOCALE_SLOCALIZEDDISPLAYNAME, langname_w, 0);
if (langname_size == 0)
return FALSE;
langname_w = g_new0 (wchar_t, langname_size);
if (langname_size == 0)
return FALSE;
GetLocaleInfoEx (locale_w, LOCALE_SLOCALIZEDDISPLAYNAME, langname_w, langname_size);
langname = g_utf16_to_utf8 (langname_w, -1, NULL, NULL, NULL);
locale = g_utf16_to_utf8 (locale_w, -1, NULL, NULL, NULL);
p = strchr (locale, '-');
lang = pango_language_from_string (locale);
if (g_hash_table_lookup (ht_scripts_langs, lang) == NULL)
g_hash_table_insert (ht_scripts_langs, lang, langname);
/*
* Track 3+-letter ISO639-2/3 language codes as well (these have a max length of 9 including terminating NUL)
* ISO639-2: iso639_lctypes[0] = LOCALE_SISO639LANGNAME
* ISO639-3: iso639_lctypes[1] = LOCALE_SISO639LANGNAME2
*/
for (i = 0; i < 2; i++)
{
locale_abbrev_size = GetLocaleInfoEx (locale_w, iso639_lctypes[i], locale_abbrev_w, 0);
if (locale_abbrev_size > 0)
{
GetLocaleInfoEx (locale_w, iso639_lctypes[i], locale_abbrev_w, locale_abbrev_size);
locale_abbrev = g_utf16_to_utf8 (locale_abbrev_w, -1, NULL, NULL, NULL);
lang = pango_language_from_string (locale_abbrev);
if (g_hash_table_lookup (ht_scripts_langs, lang) == NULL)
g_hash_table_insert (ht_scripts_langs, lang, langname);
g_free (locale_abbrev);
}
}
g_free (locale);
g_free (langname_w);
return TRUE;
}
#else /* non-Windows */
static char *
get_first_item_in_semicolon_list (const char *list)
{
@@ -210,6 +276,7 @@ languages_variant_init (const char *variant)
g_free (filename);
g_free (buf);
}
#endif
static void
languages_init (void)
@@ -218,8 +285,13 @@ languages_init (void)
return;
language_map = g_hash_table_new_full (NULL, NULL, NULL, g_free);
#ifdef G_OS_WIN32
g_return_if_fail (EnumSystemLocalesEx (&get_win32_all_locales_scripts, LOCALE_ALL, (LPARAM) language_map, NULL));
#else
languages_variant_init ("iso_639");
languages_variant_init ("iso_639_3");
#endif
}
const char *

View File

@@ -512,7 +512,7 @@ load_file (const char *demoname,
info_buffer = gtk_text_buffer_new (NULL);
gtk_text_buffer_create_tag (info_buffer, "title",
"font", "Sans 18",
"size", 18 * 1024,
"pixels-below-lines", 10,
NULL);
@@ -1040,7 +1040,7 @@ out:
g_signal_connect_swapped (G_OBJECT (demo), "destroy", G_CALLBACK (g_application_quit), app);
}
else
gtk_widget_show (GTK_WIDGET (window));
gtk_window_present (GTK_WINDOW (window));
if (autoquit)
g_timeout_add_seconds (1, auto_quit, app);

View File

@@ -21,7 +21,7 @@
<item>
<attribute name="label" translatable="yes">Save _As...</attribute>
<attribute name="action">app.save-as</attribute>
<attribute name="accel">&lt;Control&gt;s</attribute>
<attribute name="accel">&lt;Control&gt;&lt;Shift&gt;s</attribute>
</item>
</section>
<section>

View File

@@ -17,6 +17,7 @@ demos = files([
'css_pixbufs.c',
'css_shadows.c',
'cursors.c',
'curve.c',
'dialog.c',
'drawingarea.c',
'dnd.c',
@@ -34,6 +35,7 @@ demos = files([
'gestures.c',
'glarea.c',
'gltransition.c',
'glyphs.c',
'headerbar.c',
'hypertext.c',
'iconscroll.c',
@@ -70,6 +72,9 @@ demos = files([
'paintable_symbolic.c',
'panes.c',
'password_entry.c',
'path_fill.c',
'path_maze.c',
'path_text.c',
'peg_solitaire.c',
'pickers.c',
'printing.c',
@@ -98,6 +103,7 @@ demos = files([
'transparent.c',
'tree_store.c',
'video_player.c',
'font_features.c',
])
gtkdemo_deps = [ libgtk_dep, ]
@@ -128,14 +134,12 @@ extra_demo_sources = files([
'script-names.c',
'unicode-names.c',
'suggestionentry.c',
'language-names.c',
'curve-editor.c',
'nodewidget.c',
'graphwidget.c',
])
if harfbuzz_dep.found() and pangoft_dep.found()
demos += files(['font_features.c'])
extra_demo_sources += files(['language-names.c'])
gtkdemo_deps += [ harfbuzz_dep, epoxy_dep ]
endif
if os_unix
demos += files('pagesetup.c')
endif
@@ -164,7 +168,7 @@ endif
ld = find_program('ld', required : false)
if build_machine.system() == 'linux' and objcopy.found() and objcopy_supports_add_symbol and ld.found()
if not meson.is_cross_build() and build_machine.cpu_family() != 'arm' and build_machine.system() == 'linux' and objcopy.found() and objcopy_supports_add_symbol and ld.found()
glib_compile_resources = find_program('glib-compile-resources')
# Create the resource blob
@@ -174,6 +178,7 @@ if build_machine.system() == 'linux' and objcopy.found() and objcopy_supports_ad
depfile : 'gtkdemo.gresource.d',
command : [glib_compile_resources,
'--generate',
'--internal',
'--target=@OUTPUT@',
'--dependency-file=@DEPFILE@',
'--sourcedir=' + meson.current_source_dir(),
@@ -187,6 +192,7 @@ if build_machine.system() == 'linux' and objcopy.found() and objcopy_supports_ad
depfile : 'gtkdemo_resources.c.d',
command : [glib_compile_resources,
'--generate-source',
'--internal',
'--target=@OUTPUT@',
'--dependency-file=@DEPFILE@',
'--sourcedir=' + meson.current_source_dir(),
@@ -200,6 +206,7 @@ if build_machine.system() == 'linux' and objcopy.found() and objcopy_supports_ad
input : gtkdemo_gresource,
output : 'gtkdemo_resources.o',
command : [ld,
'-z', 'noexecstack',
'-r',
'-b','binary',
'@INPUT@',
@@ -210,6 +217,7 @@ if build_machine.system() == 'linux' and objcopy.found() and objcopy_supports_ad
input : gtkdemo_resources_binary,
output : 'gtkdemo_resources2.o',
command : [objcopy,
'--strip-all',
'--add-symbol','_g_binary_gtkdemo_resource_data=.data:0',
'@INPUT@',
'@OUTPUT@'])
@@ -242,7 +250,7 @@ executable('gtk4-demo',
c_args: gtkdemo_args + demo_cflags,
dependencies: gtkdemo_deps,
include_directories: confinc,
gui_app: true,
win_subsystem: 'windows',
link_args: extra_demo_ldflags,
install: true,
)
@@ -252,7 +260,7 @@ executable('gtk4-demo-application',
c_args: gtkdemo_args + common_cflags,
dependencies: gtkdemo_deps,
include_directories: confinc,
gui_app: true,
win_subsystem: 'windows',
link_args: extra_demo_ldflags,
install: true,
)

View File

@@ -0,0 +1,76 @@
#include "nodewidget.h"
struct _NodeWidget
{
GtkWidget parent_instance;
GskRenderNode *node;
};
struct _NodeWidgetClass
{
GtkWidgetClass parent_class;
};
G_DEFINE_TYPE (NodeWidget, node_widget, GTK_TYPE_WIDGET)
static void
node_widget_init (NodeWidget *self)
{
}
static void
node_widget_dispose (GObject *object)
{
NodeWidget *self = NODE_WIDGET (object);
gsk_render_node_unref (self->node);
G_OBJECT_CLASS (node_widget_parent_class)->dispose (object);
}
static void
node_widget_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot)
{
NodeWidget *self = NODE_WIDGET (widget);
gtk_snapshot_append_node (snapshot, self->node);
}
static void
node_widget_class_init (NodeWidgetClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
object_class->dispose = node_widget_dispose;
widget_class->snapshot = node_widget_snapshot;
}
GtkWidget *
node_widget_new (const char *resource)
{
NodeWidget *self;
GBytes *bytes;
GskRenderNode *node;
graphene_rect_t bounds;
float scale;
GskTransform *transform;
self = g_object_new (NODE_TYPE_WIDGET, NULL);
bytes = g_resources_lookup_data (resource, 0, NULL);
node = gsk_render_node_deserialize (bytes, NULL, NULL);
g_bytes_unref (bytes);
gsk_render_node_get_bounds (node, &bounds);
scale = MIN (100.0/bounds.size.width, 100.0/bounds.size.height);
transform = gsk_transform_scale (NULL, scale, scale);
self->node = gsk_transform_node_new (node, transform);
gsk_transform_unref (transform);
gsk_render_node_unref (node);
return GTK_WIDGET (self);
}

View File

@@ -0,0 +1,8 @@
#pragma once
#include <gtk/gtk.h>
#define NODE_TYPE_WIDGET (node_widget_get_type ())
G_DECLARE_FINAL_TYPE (NodeWidget, node_widget, NODE, WIDGET, GtkWidget)
GtkWidget * node_widget_new (const char *file);

348
demos/gtk-demo/path_fill.c Normal file
View File

@@ -0,0 +1,348 @@
/* Path/Text Fill
*
* This demo shows how to use PangoCairo to draw text with more than
* just a single color.
*/
#include <glib/gi18n.h>
#include <gtk/gtk.h>
#include "paintable.h"
#include "gsk/gskpathdashprivate.h"
#define GTK_TYPE_PATH_PAINTABLE (gtk_path_paintable_get_type ())
G_DECLARE_FINAL_TYPE (GtkPathPaintable, gtk_path_paintable, GTK, PATH_PAINTABLE, GObject)
struct _GtkPathPaintable
{
GObject parent_instance;
int width;
int height;
GskPath *path;
GdkPaintable *background;
};
struct _GtkPathPaintableClass
{
GObjectClass parent_class;
};
static int
gtk_path_paintable_get_intrinsic_width (GdkPaintable *paintable)
{
GtkPathPaintable *self = GTK_PATH_PAINTABLE (paintable);
if (self->background)
return MAX (gdk_paintable_get_intrinsic_width (self->background), self->width);
else
return self->width;
}
static int
gtk_path_paintable_get_intrinsic_height (GdkPaintable *paintable)
{
GtkPathPaintable *self = GTK_PATH_PAINTABLE (paintable);
if (self->background)
return MAX (gdk_paintable_get_intrinsic_height (self->background), self->height);
else
return self->height;
}
static void
gtk_path_paintable_snapshot (GdkPaintable *paintable,
GdkSnapshot *snapshot,
double width,
double height)
{
GtkPathPaintable *self = GTK_PATH_PAINTABLE (paintable);
#if 0
gtk_snapshot_push_fill (snapshot, self->path, GSK_FILL_RULE_WINDING);
#else
GskStroke *stroke = gsk_stroke_new (2.0);
gtk_snapshot_push_stroke (snapshot, self->path, stroke);
gsk_stroke_free (stroke);
#endif
if (self->background)
{
gdk_paintable_snapshot (self->background, snapshot, width, height);
}
else
{
gtk_snapshot_append_linear_gradient (snapshot,
&GRAPHENE_RECT_INIT (0, 0, width, height),
&GRAPHENE_POINT_INIT (0, 0),
&GRAPHENE_POINT_INIT (width, height),
(GskColorStop[8]) {
{ 0.0, { 1.0, 0.0, 0.0, 1.0 } },
{ 0.2, { 1.0, 0.0, 0.0, 1.0 } },
{ 0.3, { 1.0, 1.0, 0.0, 1.0 } },
{ 0.4, { 0.0, 1.0, 0.0, 1.0 } },
{ 0.6, { 0.0, 1.0, 1.0, 1.0 } },
{ 0.7, { 0.0, 0.0, 1.0, 1.0 } },
{ 0.8, { 1.0, 0.0, 1.0, 1.0 } },
{ 1.0, { 1.0, 0.0, 1.0, 1.0 } }
},
8);
}
gtk_snapshot_pop (snapshot);
}
static GdkPaintableFlags
gtk_path_paintable_get_flags (GdkPaintable *paintable)
{
GtkPathPaintable *self = GTK_PATH_PAINTABLE (paintable);
if (self->background)
return gdk_paintable_get_flags (self->background);
else
return GDK_PAINTABLE_STATIC_CONTENTS | GDK_PAINTABLE_STATIC_SIZE;
}
static void
gtk_path_paintable_paintable_init (GdkPaintableInterface *iface)
{
iface->get_intrinsic_width = gtk_path_paintable_get_intrinsic_width;
iface->get_intrinsic_height = gtk_path_paintable_get_intrinsic_height;
iface->snapshot = gtk_path_paintable_snapshot;
iface->get_flags = gtk_path_paintable_get_flags;
}
/* When defining the GType, we need to implement the GdkPaintable interface */
G_DEFINE_TYPE_WITH_CODE (GtkPathPaintable, gtk_path_paintable, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (GDK_TYPE_PAINTABLE,
gtk_path_paintable_paintable_init))
/* Here's the boilerplate for the GObject declaration.
* We don't need to do anything special here, because we keep no
* data of our own.
*/
static void
gtk_path_paintable_class_init (GtkPathPaintableClass *klass)
{
}
static void
gtk_path_paintable_init (GtkPathPaintable *self)
{
}
/* And finally, we add a simple constructor.
* It is declared in the header so that the other examples
* can use it.
*/
GdkPaintable *
gtk_path_paintable_new (GskPath *path,
GdkPaintable *background,
int width,
int height)
{
GtkPathPaintable *self;
self = g_object_new (GTK_TYPE_PATH_PAINTABLE, NULL);
self->path = path;
self->background = background;
if (self->background)
{
g_signal_connect_swapped (self->background, "invalidate-contents", G_CALLBACK (gdk_paintable_invalidate_contents), self);
g_signal_connect_swapped (self->background, "invalidate-size", G_CALLBACK (gdk_paintable_invalidate_size), self);
}
self->width = width;
self->height = height;
return GDK_PAINTABLE (self);
}
void
gtk_path_paintable_set_path (GtkPathPaintable *self,
GskPath *path)
{
g_clear_pointer (&self->path, gsk_path_unref);
self->path = gsk_path_ref (path);
gdk_paintable_invalidate_contents (GDK_PAINTABLE (self));
}
static GskPath *
create_hexagon (GtkWidget *widget)
{
GskPathBuilder *builder;
builder = gsk_path_builder_new ();
gsk_path_builder_move_to (builder, 120, 0);
gsk_path_builder_line_to (builder, 360, 0);
gsk_path_builder_line_to (builder, 480, 208);
gsk_path_builder_line_to (builder, 360, 416);
gsk_path_builder_line_to (builder, 120, 416);
gsk_path_builder_line_to (builder, 0, 208);
gsk_path_builder_close (builder);
return gsk_path_builder_free_to_path (builder);
}
static GskPath *
create_path_from_text (GtkWidget *widget)
{
PangoLayout *layout;
PangoFontDescription *desc;
GskPathBuilder *builder;
layout = gtk_widget_create_pango_layout (widget, "Pango power!\nPango power!\nPango power!");
desc = pango_font_description_from_string ("sans bold 36");
pango_layout_set_font_description (layout, desc);
pango_font_description_free (desc);
builder = gsk_path_builder_new ();
gsk_path_builder_add_layout (builder, layout);
return gsk_path_builder_free_to_path (builder);
}
static gboolean
build_path (GskPathOperation op,
const graphene_point_t *pts,
gsize n_pts,
float weight,
gpointer user_data)
{
GskPathBuilder *builder = user_data;
switch (op)
{
case GSK_PATH_MOVE:
gsk_path_builder_move_to (builder, pts[0].x, pts[0].y);
break;
case GSK_PATH_CLOSE:
gsk_path_builder_close (builder);
break;
case GSK_PATH_LINE:
gsk_path_builder_line_to (builder, pts[1].x, pts[1].y);
break;
case GSK_PATH_CURVE:
gsk_path_builder_curve_to (builder, pts[1].x, pts[1].y, pts[2].x, pts[2].y, pts[3].x, pts[3].y);
break;
case GSK_PATH_CONIC:
gsk_path_builder_conic_to (builder, pts[1].x, pts[1].y, pts[2].x, pts[2].y, weight);
break;
default:
g_assert_not_reached ();
break;
}
return TRUE;
}
static gboolean
update_path (GtkWidget *widget,
GdkFrameClock *frame_clock,
gpointer measure)
{
float progress = gdk_frame_clock_get_frame_time (frame_clock) % (60 * G_USEC_PER_SEC) / (float) (30 * G_USEC_PER_SEC);
GskPathBuilder *builder;
GskPath *path;
graphene_point_t pos;
graphene_vec2_t tangent;
GskStroke *stroke;
builder = gsk_path_builder_new ();
gsk_path_builder_add_segment (builder,
measure,
#if 1
0.0, gsk_path_measure_get_length (measure));
#else
progress > 1 ? (progress - 1) * gsk_path_measure_get_length (measure) : 0.0,
(progress < 1 ? progress : 1.0) * gsk_path_measure_get_length (measure));
#endif
path = gsk_path_builder_free_to_path (builder);
stroke = gsk_stroke_new (1);
gsk_stroke_set_dash (stroke, (float[2]) { 10, 5 }, 2);
gsk_stroke_set_dash_offset (stroke, - (gdk_frame_clock_get_frame_time (frame_clock) % G_USEC_PER_SEC) * 15. / G_USEC_PER_SEC);
builder = gsk_path_builder_new ();
gsk_path_dash (path, stroke, 0.2, build_path, builder);
gsk_path_unref (path);
gsk_path_measure_get_point (measure,
(progress > 1 ? (progress - 1) : progress) * gsk_path_measure_get_length (measure),
&pos,
&tangent);
gsk_path_builder_move_to (builder, pos.x + 5 * graphene_vec2_get_x (&tangent), pos.y + 5 * graphene_vec2_get_y (&tangent));
gsk_path_builder_line_to (builder, pos.x + 3 * graphene_vec2_get_y (&tangent), pos.y + 3 * graphene_vec2_get_x (&tangent));
gsk_path_builder_line_to (builder, pos.x - 3 * graphene_vec2_get_y (&tangent), pos.y - 3 * graphene_vec2_get_x (&tangent));
gsk_path_builder_close (builder);
path = gsk_path_builder_free_to_path (builder);
gtk_path_paintable_set_path (GTK_PATH_PAINTABLE (gtk_picture_get_paintable (GTK_PICTURE (widget))),
path);
gsk_path_unref (path);
return G_SOURCE_CONTINUE;
}
GtkWidget *
do_path_fill (GtkWidget *do_widget)
{
static GtkWidget *window = NULL;
if (!window)
{
GtkWidget *picture;
GdkPaintable *paintable;
GtkMediaStream *stream;
GskPath *path;
graphene_rect_t bounds;
GskPathMeasure *measure;
window = gtk_window_new ();
gtk_window_set_resizable (GTK_WINDOW (window), TRUE);
gtk_window_set_title (GTK_WINDOW (window), "Path Fill");
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
#if 0
stream = gtk_media_file_new_for_resource ("/images/gtk-logo.webm");
#else
stream = gtk_nuclear_media_stream_new ();
#endif
gtk_media_stream_play (stream);
gtk_media_stream_set_loop (stream, TRUE);
path = create_hexagon (window);
path = create_path_from_text (window);
gsk_path_get_bounds (path, &bounds);
paintable = gtk_path_paintable_new (path,
GDK_PAINTABLE (stream),
bounds.origin.x + bounds.size.width,
bounds.origin.y + bounds.size.height);
picture = gtk_picture_new_for_paintable (paintable);
measure = gsk_path_measure_new (path);
gtk_widget_add_tick_callback (picture, update_path, measure, (GDestroyNotify) gsk_path_measure_unref);
gtk_picture_set_keep_aspect_ratio (GTK_PICTURE (picture), FALSE);
gtk_picture_set_can_shrink (GTK_PICTURE (picture), FALSE);
g_object_unref (paintable);
gtk_window_set_child (GTK_WINDOW (window), picture);
}
if (!gtk_widget_get_visible (window))
gtk_widget_show (window);
else
gtk_window_destroy (GTK_WINDOW (window));
return window;
}

339
demos/gtk-demo/path_maze.c Normal file
View File

@@ -0,0 +1,339 @@
/* Path/Maze
* #Keywords: game, mouse
*
* This demo shows how to use a GskPath to create a maze and use
* gsk_path_measure_get_closest_point() to check the mouse stays
* on the path.
*
* It also shows off the performance of GskPath (or not) as this
* is a rather complex path.
*/
#include <glib/gi18n.h>
#include <gtk/gtk.h>
#include "paintable.h"
#define MAZE_GRID_SIZE 20
#define MAZE_STROKE_SIZE_ACTIVE (MAZE_GRID_SIZE - 4)
#define MAZE_STROKE_SIZE_INACTIVE (MAZE_GRID_SIZE - 12)
#define MAZE_WIDTH 31
#define MAZE_HEIGHT 21
#define GTK_TYPE_MAZE (gtk_maze_get_type ())
G_DECLARE_FINAL_TYPE (GtkMaze, gtk_maze, GTK, MAZE, GtkWidget)
struct _GtkMaze
{
GtkWidget parent_instance;
int width;
int height;
GskPath *path;
GskPathMeasure *measure;
GdkPaintable *background;
gboolean active;
};
struct _GtkMazeClass
{
GtkWidgetClass parent_class;
};
G_DEFINE_TYPE (GtkMaze, gtk_maze, GTK_TYPE_WIDGET)
static void
gtk_maze_measure (GtkWidget *widget,
GtkOrientation orientation,
int for_size,
int *minimum,
int *natural,
int *minimum_baseline,
int *natural_baseline)
{
GtkMaze *self = GTK_MAZE (widget);
if (orientation == GTK_ORIENTATION_HORIZONTAL)
*minimum = *natural = self->width;
else
*minimum = *natural = self->height;
}
static void
gtk_maze_snapshot (GtkWidget *widget,
GdkSnapshot *snapshot)
{
GtkMaze *self = GTK_MAZE (widget);
double width = gtk_widget_get_width (widget);
double height = gtk_widget_get_height (widget);
GskStroke *stroke;
stroke = gsk_stroke_new (MAZE_STROKE_SIZE_INACTIVE);
if (self->active)
gsk_stroke_set_line_width (stroke, MAZE_STROKE_SIZE_ACTIVE);
gsk_stroke_set_line_join (stroke, GSK_LINE_JOIN_ROUND);
gsk_stroke_set_line_cap (stroke, GSK_LINE_CAP_ROUND);
gtk_snapshot_push_stroke (snapshot, self->path, stroke);
gsk_stroke_free (stroke);
if (self->background)
{
gdk_paintable_snapshot (self->background, snapshot, width, height);
}
else
{
gtk_snapshot_append_linear_gradient (snapshot,
&GRAPHENE_RECT_INIT (0, 0, width, height),
&GRAPHENE_POINT_INIT (0, 0),
&GRAPHENE_POINT_INIT (width, height),
(GskColorStop[8]) {
{ 0.0, { 1.0, 0.0, 0.0, 1.0 } },
{ 0.2, { 1.0, 0.0, 0.0, 1.0 } },
{ 0.3, { 1.0, 1.0, 0.0, 1.0 } },
{ 0.4, { 0.0, 1.0, 0.0, 1.0 } },
{ 0.6, { 0.0, 1.0, 1.0, 1.0 } },
{ 0.7, { 0.0, 0.0, 1.0, 1.0 } },
{ 0.8, { 1.0, 0.0, 1.0, 1.0 } },
{ 1.0, { 1.0, 0.0, 1.0, 1.0 } }
},
8);
}
gtk_snapshot_pop (snapshot);
}
static void
gtk_maze_dispose (GObject *object)
{
GtkMaze *self = GTK_MAZE (object);
g_clear_pointer (&self->path, gsk_path_unref);
g_clear_pointer (&self->measure, gsk_path_measure_unref);
if (self->background)
{
g_signal_handlers_disconnect_matched (self->background, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, self);
g_clear_object (&self->background);
}
G_OBJECT_CLASS (gtk_maze_parent_class)->dispose (object);
}
static void
gtk_maze_class_init (GtkMazeClass *klass)
{
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->dispose = gtk_maze_dispose;
widget_class->measure = gtk_maze_measure;
widget_class->snapshot = gtk_maze_snapshot;
}
static void
pointer_motion (GtkEventControllerMotion *controller,
double x,
double y,
GtkMaze *self)
{
if (!self->active)
return;
if (gsk_path_measure_get_closest_point (self->measure, &GRAPHENE_POINT_INIT (x, y), NULL) <= MAZE_STROKE_SIZE_ACTIVE / 2.0f)
return;
self->active = FALSE;
gtk_widget_queue_draw (GTK_WIDGET (self));
}
static void
pointer_leave (GtkEventControllerMotion *controller,
GtkMaze *self)
{
if (!self->active)
{
self->active = TRUE;
gtk_widget_queue_draw (GTK_WIDGET (self));
}
}
static void
gtk_maze_init (GtkMaze *self)
{
GtkEventController *controller;
controller = GTK_EVENT_CONTROLLER (gtk_event_controller_motion_new ());
g_signal_connect (controller, "motion", G_CALLBACK (pointer_motion), self);
g_signal_connect (controller, "leave", G_CALLBACK (pointer_leave), self);
gtk_widget_add_controller (GTK_WIDGET (self), controller);
self->active = TRUE;
}
static void
gtk_maze_set_path (GtkMaze *self,
GskPath *path)
{
g_clear_pointer (&self->path, gsk_path_unref);
g_clear_pointer (&self->measure, gsk_path_measure_unref);
self->path = gsk_path_ref (path);
self->measure = gsk_path_measure_new (path);
gtk_widget_queue_draw (GTK_WIDGET (self));
}
GtkWidget *
gtk_maze_new (GskPath *path,
GdkPaintable *background,
int width,
int height)
{
GtkMaze *self;
self = g_object_new (GTK_TYPE_MAZE, NULL);
gtk_maze_set_path (self, path);
gsk_path_unref (path);
self->background = background;
if (self->background)
{
g_signal_connect_swapped (self->background, "invalidate-contents", G_CALLBACK (gtk_widget_queue_draw), self);
g_signal_connect_swapped (self->background, "invalidate-size", G_CALLBACK (gtk_widget_queue_resize), self);
}
self->width = width;
self->height = height;
return GTK_WIDGET (self);
}
static void
add_point_to_maze (GtkBitset *maze,
GskPathBuilder *builder,
guint x,
guint y)
{
gboolean set[4] = { };
guint dir;
gtk_bitset_add (maze, y * MAZE_WIDTH + x);
while (TRUE)
{
set[0] = set[0] || x == 0 || gtk_bitset_contains (maze, y * MAZE_WIDTH + x - 1);
set[1] = set[1] || y == 0 || gtk_bitset_contains (maze, (y - 1) * MAZE_WIDTH + x);
set[2] = set[2] || x + 1 == MAZE_WIDTH || gtk_bitset_contains (maze, y * MAZE_WIDTH + x + 1);
set[3] = set[3] || y + 1 == MAZE_HEIGHT || gtk_bitset_contains (maze, (y + 1) * MAZE_WIDTH + x);
if (set[0] && set[1] && set[2] && set[3])
return;
do
{
dir = g_random_int_range (0, 4);
}
while (set[dir]);
switch (dir)
{
case 0:
gsk_path_builder_move_to (builder, (x + 0.5) * MAZE_GRID_SIZE, (y + 0.5) * MAZE_GRID_SIZE);
gsk_path_builder_line_to (builder, (x - 0.5) * MAZE_GRID_SIZE, (y + 0.5) * MAZE_GRID_SIZE);
add_point_to_maze (maze, builder, x - 1, y);
break;
case 1:
gsk_path_builder_move_to (builder, (x + 0.5) * MAZE_GRID_SIZE, (y + 0.5) * MAZE_GRID_SIZE);
gsk_path_builder_line_to (builder, (x + 0.5) * MAZE_GRID_SIZE, (y - 0.5) * MAZE_GRID_SIZE);
add_point_to_maze (maze, builder, x, y - 1);
break;
case 2:
gsk_path_builder_move_to (builder, (x + 0.5) * MAZE_GRID_SIZE, (y + 0.5) * MAZE_GRID_SIZE);
gsk_path_builder_line_to (builder, (x + 1.5) * MAZE_GRID_SIZE, (y + 0.5) * MAZE_GRID_SIZE);
add_point_to_maze (maze, builder, x + 1, y);
break;
case 3:
gsk_path_builder_move_to (builder, (x + 0.5) * MAZE_GRID_SIZE, (y + 0.5) * MAZE_GRID_SIZE);
gsk_path_builder_line_to (builder, (x + 0.5) * MAZE_GRID_SIZE, (y + 1.5) * MAZE_GRID_SIZE);
add_point_to_maze (maze, builder, x, y + 1);
break;
default:
g_assert_not_reached ();
break;
}
}
}
static GskPath *
create_path_for_maze (GtkWidget *widget)
{
GskPathBuilder *builder;
GtkBitset *maze;
builder = gsk_path_builder_new ();
maze = gtk_bitset_new_empty ();
/* make sure the outer lines are unreachable:
* Set the full range, then remove the center again. */
gtk_bitset_add_range (maze, 0, MAZE_WIDTH * MAZE_HEIGHT);
gtk_bitset_remove_rectangle (maze, MAZE_WIDTH + 1, MAZE_WIDTH - 2, MAZE_HEIGHT - 2, MAZE_WIDTH);
/* Fill the maze */
add_point_to_maze (maze, builder, MAZE_WIDTH / 2, MAZE_HEIGHT / 2);
/* Add start and stop lines */
gsk_path_builder_move_to (builder, 1.5 * MAZE_GRID_SIZE, -0.5 * MAZE_GRID_SIZE);
gsk_path_builder_line_to (builder, 1.5 * MAZE_GRID_SIZE, 1.5 * MAZE_GRID_SIZE);
gsk_path_builder_move_to (builder, (MAZE_WIDTH - 1.5) * MAZE_GRID_SIZE, (MAZE_HEIGHT - 1.5) * MAZE_GRID_SIZE);
gsk_path_builder_line_to (builder, (MAZE_WIDTH - 1.5) * MAZE_GRID_SIZE, (MAZE_HEIGHT + 0.5) * MAZE_GRID_SIZE);
gtk_bitset_unref (maze);
return gsk_path_builder_free_to_path (builder);
}
GtkWidget *
do_path_maze (GtkWidget *do_widget)
{
static GtkWidget *window = NULL;
if (!window)
{
GtkWidget *maze;
GtkMediaStream *stream;
GskPath *path;
window = gtk_window_new ();
gtk_window_set_resizable (GTK_WINDOW (window), TRUE);
gtk_window_set_title (GTK_WINDOW (window), "Follow the maze with the mouse");
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
#if 0
stream = gtk_media_file_new_for_resource ("/images/gtk-logo.webm");
#else
stream = gtk_nuclear_media_stream_new ();
#endif
gtk_media_stream_play (stream);
gtk_media_stream_set_loop (stream, TRUE);
path = create_path_for_maze (window);
maze = gtk_maze_new (path,
GDK_PAINTABLE (stream),
MAZE_WIDTH * MAZE_GRID_SIZE,
MAZE_HEIGHT * MAZE_GRID_SIZE);
gtk_window_set_child (GTK_WINDOW (window), maze);
}
if (!gtk_widget_get_visible (window))
gtk_widget_show (window);
else
gtk_window_destroy (GTK_WINDOW (window));
return window;
}

594
demos/gtk-demo/path_text.c Normal file
View File

@@ -0,0 +1,594 @@
/* Path/Curved Text
*
* This demo shows how to use GskPath to animate a path along another path.
*/
#include <glib/gi18n.h>
#include <gtk/gtk.h>
#define GTK_TYPE_PATH_WIDGET (gtk_path_widget_get_type ())
G_DECLARE_FINAL_TYPE (GtkPathWidget, gtk_path_widget, GTK, PATH_WIDGET, GtkWidget)
#define POINT_SIZE 8
enum {
PROP_0,
PROP_TEXT,
PROP_EDITABLE,
N_PROPS
};
struct _GtkPathWidget
{
GtkWidget parent_instance;
char *text;
gboolean editable;
graphene_point_t points[4];
guint active_point;
float line_closest;
GskPath *line_path;
GskPathMeasure *line_measure;
GskPath *text_path;
GdkPaintable *background;
};
struct _GtkPathWidgetClass
{
GtkWidgetClass parent_class;
};
static GParamSpec *properties[N_PROPS] = { NULL, };
G_DEFINE_TYPE (GtkPathWidget, gtk_path_widget, GTK_TYPE_WIDGET)
static GskPath *
create_path_from_text (GtkWidget *widget,
const char *text)
{
cairo_surface_t *surface;
cairo_t *cr;
cairo_path_t *path;
PangoLayout *layout;
PangoFontDescription *desc;
GskPath *result;
surface = cairo_recording_surface_create (CAIRO_CONTENT_COLOR_ALPHA, NULL);
cr = cairo_create (surface);
layout = gtk_widget_create_pango_layout (widget, text);
desc = pango_font_description_from_string ("sans bold 36");
pango_layout_set_font_description (layout, desc);
pango_font_description_free (desc);
cairo_move_to (cr, 0, - pango_layout_get_baseline (layout) / (double) PANGO_SCALE);
pango_cairo_layout_path (cr, layout);
path = cairo_copy_path (cr);
result = gsk_path_new_from_cairo (path);
cairo_path_destroy (path);
g_object_unref (layout);
cairo_destroy (cr);
cairo_surface_destroy (surface);
return result;
}
typedef struct
{
GskPathMeasure *measure;
GskPathBuilder *builder;
double scale;
} GtkPathTransform;
static void
gtk_path_transform_point (GskPathMeasure *measure,
const graphene_point_t *pt,
float scale,
graphene_point_t *res)
{
graphene_vec2_t tangent;
gsk_path_measure_get_point (measure, pt->x * scale, res, &tangent);
res->x -= pt->y * scale * graphene_vec2_get_y (&tangent);
res->y += pt->y * scale * graphene_vec2_get_x (&tangent);
}
static gboolean
gtk_path_transform_op (GskPathOperation op,
const graphene_point_t *pts,
gsize n_pts,
float weight,
gpointer data)
{
GtkPathTransform *transform = data;
switch (op)
{
case GSK_PATH_MOVE:
{
graphene_point_t res;
gtk_path_transform_point (transform->measure, &pts[0], transform->scale, &res);
gsk_path_builder_move_to (transform->builder, res.x, res.y);
}
break;
case GSK_PATH_LINE:
{
graphene_point_t res;
gtk_path_transform_point (transform->measure, &pts[1], transform->scale, &res);
gsk_path_builder_line_to (transform->builder, res.x, res.y);
}
break;
case GSK_PATH_CURVE:
{
graphene_point_t res[3];
gtk_path_transform_point (transform->measure, &pts[1], transform->scale, &res[0]);
gtk_path_transform_point (transform->measure, &pts[2], transform->scale, &res[1]);
gtk_path_transform_point (transform->measure, &pts[3], transform->scale, &res[2]);
gsk_path_builder_curve_to (transform->builder, res[0].x, res[0].y, res[1].x, res[1].y, res[2].x, res[2].y);
}
break;
case GSK_PATH_CONIC:
{
graphene_point_t res[2];
gtk_path_transform_point (transform->measure, &pts[1], transform->scale, &res[0]);
gtk_path_transform_point (transform->measure, &pts[2], transform->scale, &res[1]);
gsk_path_builder_conic_to (transform->builder, res[0].x, res[0].y, res[1].x, res[1].y, weight);
}
break;
case GSK_PATH_CLOSE:
gsk_path_builder_close (transform->builder);
break;
default:
g_assert_not_reached();
return FALSE;
}
return TRUE;
}
static GskPath *
gtk_path_transform (GskPathMeasure *measure,
GskPath *path)
{
GtkPathTransform transform = { measure, gsk_path_builder_new () };
graphene_rect_t bounds;
gsk_path_get_bounds (path, &bounds);
if (bounds.origin.x + bounds.size.width > 0)
transform.scale = gsk_path_measure_get_length (measure) / (bounds.origin.x + bounds.size.width);
else
transform.scale = 1.0f;
gsk_path_foreach (path, GSK_PATH_FOREACH_ALLOW_CURVE, gtk_path_transform_op, &transform);
return gsk_path_builder_free_to_path (transform.builder);
}
static void
gtk_path_widget_clear_text_path (GtkPathWidget *self)
{
g_clear_pointer (&self->text_path, gsk_path_unref);
}
static void
gtk_path_widget_clear_paths (GtkPathWidget *self)
{
gtk_path_widget_clear_text_path (self);
g_clear_pointer (&self->line_path, gsk_path_unref);
g_clear_pointer (&self->line_measure, gsk_path_measure_unref);
}
static void
gtk_path_widget_create_text_path (GtkPathWidget *self)
{
GskPath *path;
gtk_path_widget_clear_text_path (self);
if (self->line_measure == NULL)
return;
path = create_path_from_text (GTK_WIDGET (self), self->text);
self->text_path = gtk_path_transform (self->line_measure, path);
gsk_path_unref (path);
}
static void
gtk_path_widget_create_paths (GtkPathWidget *self)
{
double width = gtk_widget_get_width (GTK_WIDGET (self));
double height = gtk_widget_get_height (GTK_WIDGET (self));
GskPathBuilder *builder;
gtk_path_widget_clear_paths (self);
if (width <= 0 || height <= 0)
return;
builder = gsk_path_builder_new ();
gsk_path_builder_move_to (builder,
self->points[0].x * width, self->points[0].y * height);
gsk_path_builder_curve_to (builder,
self->points[1].x * width, self->points[1].y * height,
self->points[2].x * width, self->points[2].y * height,
self->points[3].x * width, self->points[3].y * height);
self->line_path = gsk_path_builder_free_to_path (builder);
self->line_measure = gsk_path_measure_new (self->line_path);
gtk_path_widget_create_text_path (self);
}
static void
gtk_path_widget_allocate (GtkWidget *widget,
int width,
int height,
int baseline)
{
GtkPathWidget *self = GTK_PATH_WIDGET (widget);
GTK_WIDGET_CLASS (gtk_path_widget_parent_class)->size_allocate (widget, width, height, baseline);
gtk_path_widget_create_paths (self);
}
static void
gtk_path_widget_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot)
{
GtkPathWidget *self = GTK_PATH_WIDGET (widget);
double width = gtk_widget_get_width (widget);
double height = gtk_widget_get_height (widget);
GskPath *path;
GskStroke *stroke;
gsize i;
/* frosted glass the background */
gtk_snapshot_push_blur (snapshot, 100);
gdk_paintable_snapshot (self->background, snapshot, width, height);
gtk_snapshot_append_color (snapshot, &(GdkRGBA) { 1, 1, 1, 0.5 }, &GRAPHENE_RECT_INIT (0, 0, width, height));
gtk_snapshot_pop (snapshot);
/* draw the text */
if (self->text_path)
{
gtk_snapshot_push_fill (snapshot, self->text_path, GSK_FILL_RULE_WINDING);
gdk_paintable_snapshot (self->background, snapshot, width, height);
/* ... with an emboss effect */
stroke = gsk_stroke_new (2.0);
gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT(1, 1));
gtk_snapshot_push_stroke (snapshot, self->text_path, stroke);
gtk_snapshot_append_color (snapshot, &(GdkRGBA) { 0, 0, 0, 0.2 }, &GRAPHENE_RECT_INIT (0, 0, width, height));
gsk_stroke_free (stroke);
gtk_snapshot_pop (snapshot);
gtk_snapshot_pop (snapshot);
}
if (self->editable && self->line_path)
{
/* draw the control line */
stroke = gsk_stroke_new (1.0);
gtk_snapshot_push_stroke (snapshot, self->line_path, stroke);
gsk_stroke_free (stroke);
gtk_snapshot_append_color (snapshot, &(GdkRGBA) { 0, 0, 0, 1 }, &GRAPHENE_RECT_INIT (0, 0, width, height));
gtk_snapshot_pop (snapshot);
}
if (self->line_closest >= 0)
{
GskPathBuilder *builder;
graphene_point_t closest;
builder = gsk_path_builder_new ();
gsk_path_measure_get_point (self->line_measure, self->line_closest, &closest, NULL);
gsk_path_builder_add_circle (builder, &closest, POINT_SIZE);
path = gsk_path_builder_free_to_path (builder);
gtk_snapshot_push_fill (snapshot, path, GSK_FILL_RULE_WINDING);
gtk_snapshot_append_color (snapshot, &(GdkRGBA) { 0, 0, 1, 1 }, &GRAPHENE_RECT_INIT (0, 0, width, height));
gtk_snapshot_pop (snapshot);
gsk_path_unref (path);
}
if (self->editable && self->line_path)
{
GskPathBuilder *builder;
/* draw the points */
builder = gsk_path_builder_new ();
for (i = 0; i < 4; i++)
{
gsk_path_builder_add_circle (builder, &GRAPHENE_POINT_INIT (self->points[i].x * width, self->points[i].y * height), POINT_SIZE);
}
path = gsk_path_builder_free_to_path (builder);
gtk_snapshot_push_fill (snapshot, path, GSK_FILL_RULE_WINDING);
gtk_snapshot_append_color (snapshot, &(GdkRGBA) { 1, 1, 1, 1 }, &GRAPHENE_RECT_INIT (0, 0, width, height));
gtk_snapshot_pop (snapshot);
stroke = gsk_stroke_new (1.0);
gtk_snapshot_push_stroke (snapshot, path, stroke);
gsk_stroke_free (stroke);
gtk_snapshot_append_color (snapshot, &(GdkRGBA) { 0, 0, 0, 1 }, &GRAPHENE_RECT_INIT (0, 0, width, height));
gtk_snapshot_pop (snapshot);
gsk_path_unref (path);
}
}
static void
gtk_path_widget_set_text (GtkPathWidget *self,
const char *text)
{
if (g_strcmp0 (self->text, text) == 0)
return;
g_free (self->text);
self->text = g_strdup (text);
gtk_path_widget_create_paths (self);
gtk_widget_queue_draw (GTK_WIDGET (self));
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_TEXT]);
}
static void
gtk_path_widget_set_editable (GtkPathWidget *self,
gboolean editable)
{
if (self->editable == editable)
return;
self->editable = editable;
gtk_widget_queue_draw (GTK_WIDGET (self));
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_EDITABLE]);
}
static void
gtk_path_widget_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
GtkPathWidget *self = GTK_PATH_WIDGET (object);
switch (prop_id)
{
case PROP_TEXT:
gtk_path_widget_set_text (self, g_value_get_string (value));
break;
case PROP_EDITABLE:
gtk_path_widget_set_editable (self, g_value_get_boolean (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gtk_path_widget_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GtkPathWidget *self = GTK_PATH_WIDGET (object);
switch (prop_id)
{
case PROP_TEXT:
g_value_set_string (value, self->text);
break;
case PROP_EDITABLE:
g_value_set_boolean (value, self->editable);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gtk_path_widget_dispose (GObject *object)
{
GtkPathWidget *self = GTK_PATH_WIDGET (object);
gtk_path_widget_clear_paths (self);
G_OBJECT_CLASS (gtk_path_widget_parent_class)->dispose (object);
}
static void
gtk_path_widget_class_init (GtkPathWidgetClass *klass)
{
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->dispose = gtk_path_widget_dispose;
object_class->set_property = gtk_path_widget_set_property;
object_class->get_property = gtk_path_widget_get_property;
widget_class->size_allocate = gtk_path_widget_allocate;
widget_class->snapshot = gtk_path_widget_snapshot;
properties[PROP_TEXT] =
g_param_spec_string ("text",
"text",
"Text transformed along a path",
NULL,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
properties[PROP_EDITABLE] =
g_param_spec_boolean ("editable",
"editable",
"If the path can be edited by the user",
FALSE,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (object_class, N_PROPS, properties);
}
static void
drag_begin (GtkGestureDrag *gesture,
double x,
double y,
GtkPathWidget *self)
{
graphene_point_t mouse = GRAPHENE_POINT_INIT (x, y);
double width = gtk_widget_get_width (GTK_WIDGET (self));
double height = gtk_widget_get_height (GTK_WIDGET (self));
gsize i;
for (i = 0; i < 4; i++)
{
if (graphene_point_distance (&GRAPHENE_POINT_INIT (self->points[i].x * width, self->points[i].y * height), &mouse, NULL, NULL) <= POINT_SIZE)
{
self->active_point = i;
break;
}
}
if (i == 4)
{
gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_DENIED);
return;
}
gtk_widget_queue_draw (GTK_WIDGET (self));
}
static void
drag_update (GtkGestureDrag *drag,
double offset_x,
double offset_y,
GtkPathWidget *self)
{
double width = gtk_widget_get_width (GTK_WIDGET (self));
double height = gtk_widget_get_height (GTK_WIDGET (self));
double start_x, start_y;
gtk_gesture_drag_get_start_point (drag, &start_x, &start_y);
self->points[self->active_point] = GRAPHENE_POINT_INIT ((start_x + offset_x) / width,
(start_y + offset_y) / height);
self->points[self->active_point].x = CLAMP (self->points[self->active_point].x, 0, 1);
self->points[self->active_point].y = CLAMP (self->points[self->active_point].y, 0, 1);
gtk_path_widget_create_paths (self);
gtk_widget_queue_draw (GTK_WIDGET (self));
}
static void
pointer_motion (GtkEventControllerMotion *controller,
double x,
double y,
GtkPathWidget *self)
{
gsk_path_measure_get_closest_point_full (self->line_measure,
&GRAPHENE_POINT_INIT (x, y),
INFINITY,
NULL, NULL,
&self->line_closest,
NULL);
gtk_widget_queue_draw (GTK_WIDGET (self));
}
static void
pointer_leave (GtkEventControllerMotion *controller,
GtkPathWidget *self)
{
self->line_closest = -1;
gtk_widget_queue_draw (GTK_WIDGET (self));
}
static void
gtk_path_widget_init (GtkPathWidget *self)
{
GtkEventController *controller;
controller = GTK_EVENT_CONTROLLER (gtk_gesture_drag_new ());
g_signal_connect (controller, "drag-begin", G_CALLBACK (drag_begin), self);
g_signal_connect (controller, "drag-update", G_CALLBACK (drag_update), self);
g_signal_connect (controller, "drag-end", G_CALLBACK (drag_update), self);
gtk_widget_add_controller (GTK_WIDGET (self), controller);
controller = GTK_EVENT_CONTROLLER (gtk_event_controller_motion_new ());
g_signal_connect (controller, "enter", G_CALLBACK (pointer_motion), self);
g_signal_connect (controller, "motion", G_CALLBACK (pointer_motion), self);
g_signal_connect (controller, "leave", G_CALLBACK (pointer_leave), self);
gtk_widget_add_controller (GTK_WIDGET (self), controller);
self->line_closest = -1;
self->points[0] = GRAPHENE_POINT_INIT (0.1, 0.9);
self->points[1] = GRAPHENE_POINT_INIT (0.3, 0.1);
self->points[2] = GRAPHENE_POINT_INIT (0.7, 0.1);
self->points[3] = GRAPHENE_POINT_INIT (0.9, 0.9);
self->background = GDK_PAINTABLE (gdk_texture_new_from_resource ("/sliding_puzzle/portland-rose.jpg"));
gtk_path_widget_set_text (self, "It's almost working");
}
GtkWidget *
gtk_path_widget_new (void)
{
GtkPathWidget *self;
self = g_object_new (GTK_TYPE_PATH_WIDGET, NULL);
return GTK_WIDGET (self);
}
GtkWidget *
do_path_text (GtkWidget *do_widget)
{
static GtkWidget *window = NULL;
if (!window)
{
GtkBuilder *builder;
g_type_ensure (GTK_TYPE_PATH_WIDGET);
builder = gtk_builder_new_from_resource ("/path_text/path_text.ui");
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *) &window);
g_object_unref (builder);
}
if (!gtk_widget_get_visible (window))
gtk_widget_show (window);
else
gtk_window_destroy (GTK_WINDOW (window));
return window;
}

View File

@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkWindow" id="window">
<property name="title" translatable="yes">Text along a Path</property>
<child type="titlebar">
<object class="GtkHeaderBar">
<child type="end">
<object class="GtkToggleButton" id="edit-toggle">
<property name="icon-name">document-edit-symbolic</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<child>
<object class="GtkRevealer">
<property name="reveal-child" bind-source="edit-toggle" bind-property="active" bind-flags="sync-create"></property>
<child>
<object class="GtkEntry" id="text">
<property name="text">Through the looking glass</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkPathWidget" id="view">
<property name="editable" bind-source="edit-toggle" bind-property="active" bind-flags="sync-create"></property>
<property name="text" bind-source="text" bind-property="text" bind-flags="sync-create"></property>
<property name="hexpand">true</property>
<property name="vexpand">true</property>
</object>
</child>
</object>
</child>
</object>
</interface>

2218
demos/gtk-demo/tiger.node Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -16,7 +16,7 @@ executable('gtk4-icon-browser',
c_args: common_cflags,
dependencies: [ libgtk_dep, demo_conf_h ],
include_directories: confinc,
gui_app: true,
win_subsystem: 'windows',
link_args: extra_demo_ldflags,
install: true,
)

View File

@@ -3,7 +3,7 @@ demo_profile = get_option('profile')
demo_conf_h = declare_dependency(
sources: custom_target('demo-header',
command: [gen_demo_header, meson.source_root(), demo_profile],
command: [gen_demo_header, meson.project_source_root(), demo_profile],
capture: true,
output: 'demo_conf.h',
build_by_default: true,

View File

@@ -17,7 +17,7 @@ executable('gtk4-node-editor',
c_args: [
'-DNODE_EDITOR_SOURCE_DIR="@0@/../../testsuite/gsk/compare/"'.format(meson.current_source_dir())
] + common_cflags,
gui_app: true,
win_subsystem: 'windows',
link_args: extra_demo_ldflags,
install: false,
)

View File

@@ -3,7 +3,7 @@ executable('gtk4-print-editor',
c_args: common_cflags,
dependencies: [ libgtk_dep, demo_conf_h ],
include_directories: confinc,
gui_app: true,
win_subsystem: 'windows',
link_args: extra_demo_ldflags,
install: true,
)

View File

@@ -871,7 +871,7 @@ activate (GApplication *app)
update_ui ();
gtk_widget_show (main_window);
gtk_window_present (GTK_WINDOW (main_window));
}
static void

View File

@@ -8,7 +8,7 @@ endif
ld = find_program('ld', required : false)
if build_machine.system() == 'linux' and objcopy.found() and objcopy_supports_add_symbol and ld.found()
if not meson.is_cross_build() and build_machine.cpu_family() != 'arm' and build_machine.system() == 'linux' and objcopy.found() and objcopy_supports_add_symbol and ld.found()
glib_compile_resources = find_program('glib-compile-resources')
# Create the resource blob
@@ -18,6 +18,7 @@ if build_machine.system() == 'linux' and objcopy.found() and objcopy_supports_ad
depfile: 'widgetfactory.gresource.d',
command : [glib_compile_resources,
'--generate',
'--internal',
'--target=@OUTPUT@',
'--dependency-file=@DEPFILE@',
'--sourcedir=' + meson.current_source_dir(),
@@ -31,6 +32,7 @@ if build_machine.system() == 'linux' and objcopy.found() and objcopy_supports_ad
depfile: 'widgetfactory_resources.c.d',
command : [glib_compile_resources,
'--generate-source',
'--internal',
'--target=@OUTPUT@',
'--dependency-file=@DEPFILE@',
'--sourcedir=' + meson.current_source_dir(),
@@ -44,6 +46,7 @@ if build_machine.system() == 'linux' and objcopy.found() and objcopy_supports_ad
input : widgetfactory_gresource,
output : 'widgetfactory_resources.o',
command : [ld,
'-z', 'noexecstack',
'-r',
'-b','binary',
'@INPUT@',
@@ -54,6 +57,7 @@ if build_machine.system() == 'linux' and objcopy.found() and objcopy_supports_ad
input : widgetfactory_resources_binary,
output : 'widgetfactory_resources2.o',
command : [objcopy,
'--strip-all',
'--add-symbol','_g_binary_widgetfactory_resource_data=.data:0',
'@INPUT@',
'@OUTPUT@'])
@@ -74,7 +78,7 @@ executable('gtk4-widget-factory',
c_args: common_cflags,
dependencies: [ libgtk_dep, demo_conf_h ],
include_directories: confinc,
gui_app: true,
win_subsystem: 'windows',
link_args: extra_demo_ldflags,
install: true,
)

View File

@@ -2053,6 +2053,7 @@ activate (GApplication *app)
{ "win.open", { "<Control>o", NULL } },
{ "win.record", { "<Control>r", NULL } },
{ "win.lock", { "<Control>l", NULL } },
{ "win.fullscreen", { "F11", NULL } },
};
struct {
const char *action_and_target;
@@ -2359,7 +2360,7 @@ activate (GApplication *app)
model = (GMenuModel *)gtk_builder_get_object (builder, "new_style_context_menu_model");
set_up_context_popover (widget, model);
gtk_widget_show (GTK_WIDGET (window));
gtk_window_present (window);
g_object_unref (builder);
}

View File

@@ -1927,6 +1927,12 @@ microphone-sensitivity-medium-symbolic</property>
<property name="tooltip-text" translatable="1">Insert something</property>
</object>
</child>
<child>
<object class="GtkColorButton">
<property name="rgba">#9141AC</property>
<property name="tooltip-text" translatable="1">Select a color</property>
</object>
</child>
</object>
</child>
<child>

View File

@@ -7,20 +7,21 @@ authors = "GTK Development Team"
logo_url = "gtk-logo.svg"
license = "GPL-2.1-or-later"
description = "The GTK toolkit"
dependencies = [ "GObject-2.0" ]
devhelp = true
[dependencies."GObject-2.0"]
name = "GObject"
description = "The base type system library"
docs_url = "https://docs.gtk.org/gobject/"
dependencies = ["Gdk-4.0"]
[dependencies."Gdk-4.0"]
name = "GDK"
description = "The GTK drawing kit"
docs_url = "https://docs.gtk.org/gdk/"
[theme]
name = "basic"
show_index_summary = true
[source-location]
base_url = "https://gitlab.gnome.org/GNOME/gtk/-/blob/master/"
base_url = "https://gitlab.gnome.org/GNOME/gtk/-/blob/main/"
[extra]
content_images = [

View File

@@ -7,20 +7,20 @@ authors = "GTK Development Team"
logo_url = "gtk-logo.svg"
license = "GPL-2.1-or-later"
description = "The GTK toolkit"
dependencies = [ "GObject-2.0" ]
dependencies = ["Gdk-4.0"]
devhelp = true
[dependencies."GObject-2.0"]
name = "GObject"
description = "The base type system library"
docs_url = "https://docs.gtk.org/gobject/"
[dependencies."Gdk-4.0"]
name = "GDK"
description = "The GTK drawing kit"
docs_url = "https://docs.gtk.org/gdk4/"
[theme]
name = "basic"
show_index_summary = true
[source-location]
base_url = "https://gitlab.gnome.org/GNOME/gtk/-/blob/master/"
base_url = "https://gitlab.gnome.org/GNOME/gtk/-/blob/main/"
[extra]
content_images = [

View File

@@ -8,7 +8,7 @@ authors = "GTK Development Team"
logo_url = "gtk-logo.svg"
license = "LGPL-2.1-or-later"
description = "The GTK toolkit"
dependencies = [ "GObject-2.0", "cairo-1.0", "Pango-1.0", "GdkWayland-4.0", "GdkX11-4.0" ]
dependencies = ["GObject-2.0", "Gio-2.0", "cairo-1.0", "Pango-1.0", "GdkPixbuf-2.0"]
devhelp = true
search_index = true
@@ -17,6 +17,11 @@ search_index = true
description = "The base type system library"
docs_url = "https://docs.gtk.org/gobject/"
[dependencies."Gio-2.0"]
name = "GIO"
description = "GObject Interfaces and Objects, Networking, IPC, and I/O"
docs_url = "https://docs.gtk.org/gio/"
[dependencies."cairo-1.0"]
name = "Cairo"
description = "A 2D graphics library with support for multiple output devices"
@@ -27,12 +32,19 @@ search_index = true
description = "Text shaping and rendering"
docs_url = "https://docs.gtk.org/Pango/"
[dependencies."GdkWayland-4.0"]
[dependencies."GdkPixbuf-2.0"]
name = "GdkPixbuf"
description = "Image data loading"
docs_url = "https://docs.gtk.org/gdk-pixbuf/"
related = ["GdkWayland-4.0", "GdkX11-4.0"]
[related."GdkWayland-4.0"]
name = "GdkWayland"
description = "GDK Wayland Backend"
docs_url = "https://docs.gtk.org/gdk4-wayland/"
[dependencies."GdkX11-4.0"]
[related."GdkX11-4.0"]
name = "GdkX11"
description = "GDK X11 Backend"
docs_url = "https://docs.gtk.org/gdk4-x11/"
@@ -43,7 +55,7 @@ show_index_summary = true
show_class_hierarchy = true
[source-location]
base_url = "https://gitlab.gnome.org/GNOME/gtk/-/blob/master/"
base_url = "https://gitlab.gnome.org/GNOME/gtk/-/blob/main/"
[extra]
content_files = [

View File

@@ -8,25 +8,16 @@ authors = "GTK Development Team"
logo_url = "gtk-logo.svg"
license = "LGPL-2.1-or-later"
description = "The GTK toolkit"
dependencies = [ "GObject-2.0", "Graphene-1.0", "Pango-1.0", "Gdk-4.0" ]
devhelp = true
search_index = true
[dependencies."GObject-2.0"]
name = "GObject"
description = "The base type system library"
docs_url = "https://docs.gtk.org/gobject/"
dependencies = ["Graphene-1.0", "Gdk-4.0"]
[dependencies."Graphene-1.0"]
name = "Graphene"
description = "A thin layer of mathematical types for 3D libraries"
docs_url = "https://ebassi.github.io/graphene/docs/"
[dependencies."Pango-1.0"]
name = "Pango"
description = "Text shaping and rendering"
docs_url = "https://docs.gtk.org/Pango/"
[dependencies."Gdk-4.0"]
name = "GDK"
description = "The GTK windowing system abstraction"
@@ -38,7 +29,7 @@ show_index_summary = true
show_class_hierarchy = true
[source-location]
base_url = "https://gitlab.gnome.org/GNOME/gtk/-/blob/master/"
base_url = "https://gitlab.gnome.org/GNOME/gtk/-/blob/main/"
[extra]
content_images = [

View File

@@ -170,7 +170,7 @@ activate (GtkApplication *app,
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_widget_set_halign (box, GTK_ALIGN_CENTER);
gtk_widget_set_valign (box, GTK_ALIGN_CENTER);
gtk_window_set_child (GTK_WINDOW (window), box);
button = gtk_button_new_with_label ("Hello World");
@@ -752,7 +752,7 @@ templates, resources, application menus, settings, [class@Gtk.HeaderBar], [class
The full, buildable sources for these examples can be found in the
`examples` directory of the GTK source distribution, or
[online](https://gitlab.gnome.org/GNOME/gtk/blob/master/examples) in the GTK
[online](https://gitlab.gnome.org/GNOME/gtk/blob/main/examples) in the GTK
source code repository. You can build each example separately by using make
with the `Makefile.example` file. For more information, see the `README`
included in the examples directory.
@@ -972,7 +972,7 @@ example_app_window_class_init (ExampleAppWindowClass *class)
...
```
([full source](https://gitlab.gnome.org/GNOME/gtk/blob/master/examples/application2/exampleappwin.c))
([full source](https://gitlab.gnome.org/GNOME/gtk/blob/main/examples/application2/exampleappwin.c))
You may have noticed that we used the `_from_resource()` variant of the function
that sets a template. Now we need to use
@@ -1043,7 +1043,7 @@ example_app_window_class_init (ExampleAppWindowClass *class)
...
```
([full source](https://gitlab.gnome.org/GNOME/gtk/blob/master/examples/application3/exampleappwin.c))
([full source](https://gitlab.gnome.org/GNOME/gtk/blob/main/examples/application3/exampleappwin.c))
Now we revisit the `example_app_window_open()` function that is called for each
commandline argument, and construct a GtkTextView that we then add as a page
@@ -1087,7 +1087,7 @@ example_app_window_open (ExampleAppWindow *win,
...
```
([full source](https://gitlab.gnome.org/GNOME/gtk/blob/master/examples/application3/exampleappwin.c))
([full source](https://gitlab.gnome.org/GNOME/gtk/blob/main/examples/application3/exampleappwin.c))
Lastly, we add a [class@Gtk.StackSwitcher] to the titlebar area in the UI file, and we
tell it to display information about our stack.
@@ -1188,7 +1188,7 @@ example_app_class_init (ExampleAppClass *class)
...
```
([full source](https://gitlab.gnome.org/GNOME/gtk/blob/master/examples/application4/exampleapp.c))
([full source](https://gitlab.gnome.org/GNOME/gtk/blob/main/examples/application4/exampleapp.c))
Our preferences menu item does not do anything yet, but the Quit menu item
is fully functional. Note that it can also be activated by the usual Ctrl-Q
@@ -1258,7 +1258,7 @@ example_app_window_init (ExampleAppWindow *win)
...
```
([full source](https://gitlab.gnome.org/GNOME/gtk/blob/master/examples/application5/exampleappwin.c))
([full source](https://gitlab.gnome.org/GNOME/gtk/blob/main/examples/application5/exampleappwin.c))
The code to connect the font setting is a little more involved, since there
is no simple object property that it corresponds to, so we are not going to
@@ -1429,7 +1429,7 @@ preferences_activated (GSimpleAction *action,
...
```
([full source](https://gitlab.gnome.org/GNOME/gtk/blob/master/examples/application6/exampleapp.c))
([full source](https://gitlab.gnome.org/GNOME/gtk/blob/main/examples/application6/exampleapp.c))
After all this work, our application can now show a preference dialog
like this:
@@ -1549,7 +1549,7 @@ example_app_window_init (ExampleAppWindow *win)
...
```
([full source](https://gitlab.gnome.org/GNOME/gtk/blob/master/examples/application7/exampleappwin.c))
([full source](https://gitlab.gnome.org/GNOME/gtk/blob/main/examples/application7/exampleappwin.c))
With the search bar, our application now looks like this:
@@ -1682,7 +1682,7 @@ example_app_window_init (ExampleAppWindow *win)
...
```
([full source](https://gitlab.gnome.org/GNOME/gtk/blob/master/examples/application8/exampleappwin.c))
([full source](https://gitlab.gnome.org/GNOME/gtk/blob/main/examples/application8/exampleappwin.c))
What our application looks like now:
@@ -1760,10 +1760,10 @@ example_app_window_init (ExampleAppWindow *win)
...
```
([full source](https://gitlab.gnome.org/GNOME/gtk/blob/master/examples/application9/exampleappwin.c))
([full source](https://gitlab.gnome.org/GNOME/gtk/blob/main/examples/application9/exampleappwin.c))
We also need a function that counts the lines of the currently active tab,
and updates the `lines` label. See the [full source](https://gitlab.gnome.org/GNOME/gtk/blob/master/examples/application9/exampleappwin.c)
and updates the `lines` label. See the [full source](https://gitlab.gnome.org/GNOME/gtk/blob/main/examples/application9/exampleappwin.c)
if you are interested in the details.
This brings our example application to this appearance:

View File

@@ -8,24 +8,10 @@ authors = "GTK Development Team"
logo_url = "gtk-logo.svg"
license = "LGPL-2.1-or-later"
description = "The GTK toolkit"
dependencies = [ "GObject-2.0", "Graphene-1.0", "Pango-1.0", "Gdk-4.0", "Gsk-4.0" ]
devhelp = true
search_index = true
[dependencies."GObject-2.0"]
name = "GObject"
description = "The base type system library"
docs_url = "https://docs.gtk.org/gobject/"
[dependencies."Graphene-1.0"]
name = "Graphene"
description = "A thin layer of mathematical types for 3D libraries"
docs_url = "https://ebassi.github.io/graphene/docs"
[dependencies."Pango-1.0"]
name = "Pango"
description = "Text shaping and rendering"
docs_url = "https://docs.gtk.org/Pango/"
dependencies = ["Gdk-4.0", "Gsk-4.0"]
[dependencies."Gdk-4.0"]
name = "GDK"
@@ -37,13 +23,35 @@ search_index = true
description = "The GTK rendering abstraction"
docs_url = "https://docs.gtk.org/gsk4/"
related = ["Pango-1.0", "Graphene-1.0", "GObject-2.0", "Gio-2.0"]
[related."GObject-2.0"]
name = "GObject"
description = "The base type system library"
docs_url = "https://docs.gtk.org/gobject/"
[related."Gio-2.0"]
name = "GIO"
description = "GObject Interfaces and Objects, Networking, IPC, and I/O"
docs_url = "https://docs.gtk.org/gio/"
[related."Graphene-1.0"]
name = "Graphene"
description = "A thin layer of mathematical types for 3D libraries"
docs_url = "https://ebassi.github.io/graphene/docs"
[related."Pango-1.0"]
name = "Pango"
description = "Text shaping and rendering"
docs_url = "https://docs.gtk.org/Pango/"
[theme]
name = "basic"
show_index_summary = true
show_class_hierarchy = true
[source-location]
base_url = "https://gitlab.gnome.org/GNOME/gtk/-/blob/master/"
base_url = "https://gitlab.gnome.org/GNOME/gtk/-/blob/main/"
[extra]
# The same order will be used when generating the index

View File

@@ -42,7 +42,7 @@ univocally identifies events that are related to the same
interaction.
When GTK creates a `GdkSurface`, it connects to the ::event
signal on it, which receives all of these input events. Surfaces have
signal on it, which receives all of these input events. Surfaces
have signals and properties, e.g. to deal with window management
related events.

View File

@@ -57,7 +57,7 @@ if get_option('gtk_doc')
)
endif
rst2man = find_program('rst2man', required: false)
rst2man = find_program('rst2man', 'rst2man.py', required: false)
if get_option('man-pages') and not rst2man.found()
error('No rst2man found, but man pages were explicitly enabled')
endif

View File

@@ -1276,6 +1276,15 @@ is provided in the form of a `GtkIconPaintable` (this can be checked with
[method@Gtk.IconPaintable.is_symbolic]), you have to call
[method@Gtk.IconPaintable.get_icon_name] and set the icon name on a `GtkImage`.
### Adapt to GtkImage changes
`GtkPicture`'s behaviour was "split out" of `GtkImage` as the latter was covering
too many use cases; if you're loading an icon, [class@Gtk.Image] in GTK3 and GTK4 are
perfectly equivalent. If you are loading a more complex image asset, like a picture
or a thumbnail, then [class@Gtk.Picture] is the appropriate widget.
One noteworthy distinction is that while `GtkImage` has its size computed by
GTK, `GtkPicture` lets you decide about the size.
### Update to GtkFileChooser API changes
`GtkFileChooser` moved to a GFile-based API. If you need to convert a path
@@ -1373,5 +1382,5 @@ a new family of widgets for this purpose that uses list models instead
of tree models, and widgets instead of cell renderers.
To learn more about the new list widgets, you can read the [List Widget
Overview](#ListWidget).
Overview](https://docs.gtk.org/gtk4/section-list-widget.html).

View File

@@ -26,7 +26,7 @@ GTK with your code applied, and run the test suite, on multiple platforms
and architectures, and verify that nothing breaks. They also allow us to
do proper code reviews, so we can iterate over the changes.
You should follow the [contribution guide](https://gitlab.gnome.org/GNOME/gtk/blob/master/CONTRIBUTING.md)
You should follow the [contribution guide](https://gitlab.gnome.org/GNOME/gtk/blob/main/CONTRIBUTING.md)
for GTK, available on GitLab.
If you want to discuss your approach before or after working on it,

View File

@@ -286,7 +286,7 @@ requires that GTK is compiled with support for that backend.
The following backends can be selected, provided they are
included in the GDK libraries you are using:
`quartz`
`macos`
: Selects the native Quartz backend
`win32`
@@ -336,9 +336,6 @@ using and the GDK backend supports them:
`gl`
: Selects the "gl" OpenGL renderer
`ngl`
: Selects the "ngl" OpenGL renderer
`vulkan`
: Selects the Vulkan renderer
@@ -375,7 +372,7 @@ library you are using:
The `test` accessibility backend is recommended for test suites and remote
continuous integration pipelines.
### `XDG_DTA_HOME`, `XDG_DATA_DIRS`
### `XDG_DATA_HOME`, `XDG_DATA_DIRS`
GTK uses these environment variables to locate icon themes
and MIME information. For more information, see the

View File

@@ -31,8 +31,7 @@
* `GdkAppLaunchContext` handles launching an application in a graphical context.
*
* It is an implementation of `GAppLaunchContext` that provides startup
* notification and allows to launch applications on a specific screen
* or workspace.
* notification and allows to launch applications on a specific workspace.
*
* ## Launching an application
*
@@ -41,7 +40,6 @@
*
* context = gdk_display_get_app_launch_context (display);
*
* gdk_app_launch_context_set_display (display);
* gdk_app_launch_context_set_timestamp (gdk_event_get_time (event));
*
* if (!g_app_info_launch_default_for_uri ("http://www.gtk.org", context, &error))
@@ -196,6 +194,10 @@ gdk_app_launch_context_get_display (GdkAppLaunchContext *context)
* This only works when running under a window manager that
* supports multiple workspaces, as described in the
* [Extended Window Manager Hints](http://www.freedesktop.org/Standards/wm-spec).
* Specifically this sets the `_NET_WM_DESKTOP` property described
* in that spec.
*
* This only works when using the X11 backend.
*
* When the workspace is not specified or @desktop is set to -1,
* it is up to the window manager to pick one, typically it will

View File

@@ -264,7 +264,7 @@ gdk_content_deserializer_get_priority (GdkContentDeserializer *deserializer)
*
* This is the `GCancellable` that was passed to [func@Gdk.content_deserialize_async].
*
* Returns: (transfer none): the cancellable for the current operation
* Returns: (transfer none) (nullable): the cancellable for the current operation
*/
GCancellable *
gdk_content_deserializer_get_cancellable (GdkContentDeserializer *deserializer)
@@ -576,7 +576,7 @@ gdk_content_deserialize_async (GInputStream *stream,
/**
* gdk_content_deserialize_finish:
* @result: the `GAsyncResult`
* @value: return location for the result of the operation
* @value: (out): return location for the result of the operation
* @error: return location for an error
*
* Finishes a content deserialization operation.

View File

@@ -342,7 +342,7 @@ gdk_content_provider_write_mime_type_finish (GdkContentProvider *provider,
/**
* gdk_content_provider_get_value:
* @provider: a `GdkContentProvider`
* @value: the `GValue` to fill
* @value: (out caller-allocates): the `GValue` to fill
* @error: a `GError` location to store the error occurring
*
* Gets the contents of @provider stored in @value.

View File

@@ -270,7 +270,7 @@ gdk_content_serializer_get_priority (GdkContentSerializer *serializer)
*
* This is the `GCancellable` that was passed to [func@content_serialize_async].
*
* Returns: (transfer none): the cancellable for the current operation
* Returns: (transfer none) (nullable): the cancellable for the current operation
*/
GCancellable *
gdk_content_serializer_get_cancellable (GdkContentSerializer *serializer)

View File

@@ -47,8 +47,7 @@
* Cursors by themselves are not very interesting: they must be bound to a
* window for users to see them. This is done with [method@Gdk.Surface.set_cursor]
* or [method@Gdk.Surface.set_device_cursor]. Applications will typically
* use higher-level GTK functions such as [method@Gtk.Widget.set_cursor]`
* instead.
* use higher-level GTK functions such as [method@Gtk.Widget.set_cursor] instead.
*
* Cursors are not bound to a given [class@Gdk.Display], so they can be shared.
* However, the appearance of cursors may vary when used on different

View File

@@ -132,8 +132,6 @@ gdk_device_class_init (GdkDeviceClass *klass)
* GdkDevice:source: (attributes org.gtk.Property.get=gdk_device_get_source)
*
* Source type for the device.
*
* Deprecated: 4.6: Use GdkDeviceTool:tool-type instead
*/
device_props[PROP_SOURCE] =
g_param_spec_enum ("source",
@@ -598,8 +596,6 @@ gdk_device_get_has_cursor (GdkDevice *device)
* Determines the type of the device.
*
* Returns: a `GdkInputSource`
*
* Deprecated: 4.6: Use gdk_device_tool_get_tool_type() instead
*/
GdkInputSource
gdk_device_get_source (GdkDevice *device)
@@ -1242,7 +1238,7 @@ gdk_device_get_num_touches (GdkDevice *device)
*
* Retrieves the current tool for @device.
*
* Returns: (transfer none): the `GdkDeviceTool`
* Returns: (transfer none) (nullable): the `GdkDeviceTool`
*/
GdkDeviceTool *
gdk_device_get_device_tool (GdkDevice *device)

View File

@@ -92,7 +92,7 @@ GDK_AVAILABLE_IN_ALL
GdkDisplay * gdk_device_get_display (GdkDevice *device);
GDK_AVAILABLE_IN_ALL
GdkSeat * gdk_device_get_seat (GdkDevice *device);
GDK_DEPRECATED_IN_4_6_FOR(gdk_device_tool_get_tool_type)
GDK_AVAILABLE_IN_ALL
GdkDeviceTool * gdk_device_get_device_tool (GdkDevice *device);
GDK_AVAILABLE_IN_ALL

View File

@@ -1721,12 +1721,12 @@ gdk_display_init_egl (GdkDisplay *self,
self->have_egl_buffer_age =
epoxy_has_egl_extension (priv->egl_display, "EGL_EXT_buffer_age");
self->have_egl_swap_buffers_with_damage =
epoxy_has_egl_extension (priv->egl_display, "EGL_EXT_swap_buffers_with_damage");
self->have_egl_no_config_context =
epoxy_has_egl_extension (priv->egl_display, "EGL_KHR_no_config_context");
self->have_egl_pixel_format_float =
epoxy_has_egl_extension (priv->egl_display, "EGL_EXT_pixel_format_float");
self->have_egl_win32_libangle =
epoxy_has_egl_extension (priv->egl_display, "EGL_ANGLE_d3d_share_handle_client_buffer");
if (self->have_egl_no_config_context)
priv->egl_config_high_depth = gdk_display_create_egl_config (self,

View File

@@ -107,9 +107,9 @@ struct _GdkDisplay
/* egl info */
guint have_egl_buffer_age : 1;
guint have_egl_swap_buffers_with_damage : 1;
guint have_egl_no_config_context : 1;
guint have_egl_pixel_format_float : 1;
guint have_egl_win32_libangle : 1;
};
struct _GdkDisplayClass

View File

@@ -19,7 +19,7 @@
* Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog
* files for a list of changes. These files are distributed with
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
#include "config.h"
@@ -522,7 +522,9 @@ _gdk_event_queue_find_first (GdkDisplay *display)
if (pending_motion)
return pending_motion;
if (event->event_type == GDK_MOTION_NOTIFY && (event->flags & GDK_EVENT_FLUSHED) == 0)
if ((event->event_type == GDK_MOTION_NOTIFY ||
(event->event_type == GDK_SCROLL && gdk_scroll_event_get_direction (event) == GDK_SCROLL_SMOOTH)) &&
(event->flags & GDK_EVENT_FLUSHED) == 0)
pending_motion = tmp_list;
else
return tmp_list;
@@ -595,7 +597,11 @@ _gdk_event_unqueue (GdkDisplay *display)
/*
* If the last N events in the event queue are smooth scroll events
* for the same surface and device, combine them into one.
* for the same surface, the same device and the same scroll unit,
* combine them into one.
*
* We give the remaining event a history with N items, and deltas
* that are the sum over the history entries.
*/
void
gdk_event_queue_handle_scroll_compression (GdkDisplay *display)
@@ -605,8 +611,9 @@ gdk_event_queue_handle_scroll_compression (GdkDisplay *display)
GdkDevice *device = NULL;
GdkEvent *last_event = NULL;
GList *scrolls = NULL;
double delta_x, delta_y;
GArray *history = NULL;
GdkScrollUnit scroll_unit = GDK_SCROLL_UNIT_WHEEL;
gboolean scroll_unit_defined = FALSE;
GdkTimeCoord hist;
l = g_queue_peek_tail_link (&display->queued_events);
@@ -614,6 +621,7 @@ gdk_event_queue_handle_scroll_compression (GdkDisplay *display)
while (l)
{
GdkEvent *event = l->data;
GdkScrollEvent *scroll_event = (GdkScrollEvent *) event;
if (event->flags & GDK_EVENT_PENDING)
break;
@@ -630,45 +638,58 @@ gdk_event_queue_handle_scroll_compression (GdkDisplay *display)
device != event->device)
break;
if (scroll_unit_defined &&
scroll_unit != scroll_event->unit)
break;
if (!last_event)
last_event = event;
surface = event->surface;
device = event->device;
scroll_unit = scroll_event->unit;
scroll_unit_defined = TRUE;
scrolls = l;
l = l->prev;
}
delta_x = delta_y = 0;
while (scrolls && scrolls->next != NULL)
{
GdkEvent *event = scrolls->data;
GList *next = scrolls->next;
double dx, dy;
gboolean inherited = FALSE;
if (!history && ((GdkScrollEvent *)event)->history)
{
history = ((GdkScrollEvent *)event)->history;
((GdkScrollEvent *)event)->history = NULL;
inherited = TRUE;
}
if (!history)
history = g_array_new (FALSE, TRUE, sizeof (GdkTimeCoord));
gdk_scroll_event_get_deltas (event, &dx, &dy);
delta_x += dx;
delta_y += dy;
if (!inherited)
{
gdk_scroll_event_get_deltas (event, &dx, &dy);
memset (&hist, 0, sizeof (GdkTimeCoord));
hist.time = gdk_event_get_time (event);
hist.flags = GDK_AXIS_FLAG_DELTA_X | GDK_AXIS_FLAG_DELTA_Y;
hist.axes[GDK_AXIS_DELTA_X] = dx;
hist.axes[GDK_AXIS_DELTA_Y] = dy;
memset (&hist, 0, sizeof (GdkTimeCoord));
hist.time = gdk_event_get_time (event);
hist.flags = GDK_AXIS_FLAG_DELTA_X | GDK_AXIS_FLAG_DELTA_Y;
hist.axes[GDK_AXIS_DELTA_X] = dx;
hist.axes[GDK_AXIS_DELTA_Y] = dy;
g_array_append_val (history, hist);
g_array_append_val (history, hist);
}
gdk_event_unref (event);
g_queue_delete_link (&display->queued_events, scrolls);
scrolls = next;
}
if (scrolls)
if (scrolls && history)
{
GdkEvent *old_event, *event;
double dx, dy;
@@ -676,14 +697,31 @@ gdk_event_queue_handle_scroll_compression (GdkDisplay *display)
old_event = scrolls->data;
gdk_scroll_event_get_deltas (old_event, &dx, &dy);
memset (&hist, 0, sizeof (GdkTimeCoord));
hist.time = gdk_event_get_time (old_event);
hist.flags = GDK_AXIS_FLAG_DELTA_X | GDK_AXIS_FLAG_DELTA_Y;
hist.axes[GDK_AXIS_DELTA_X] = dx;
hist.axes[GDK_AXIS_DELTA_Y] = dy;
g_array_append_val (history, hist);
dx = dy = 0;
for (int i = 0; i < history->len; i++)
{
GdkTimeCoord *val = &g_array_index (history, GdkTimeCoord, i);
dx += val->axes[GDK_AXIS_DELTA_X];
dy += val->axes[GDK_AXIS_DELTA_Y];
}
event = gdk_scroll_event_new (surface,
device,
gdk_event_get_device_tool (old_event),
gdk_event_get_time (old_event),
gdk_event_get_modifier_state (old_event),
delta_x + dx,
delta_y + dy,
gdk_scroll_event_is_stop (old_event));
dx,
dy,
gdk_scroll_event_is_stop (old_event),
scroll_unit);
((GdkScrollEvent *)event)->history = history;
@@ -692,14 +730,6 @@ gdk_event_queue_handle_scroll_compression (GdkDisplay *display)
gdk_event_unref (old_event);
}
if (g_queue_get_length (&display->queued_events) == 1 &&
g_queue_peek_head_link (&display->queued_events) == scrolls)
{
GdkFrameClock *clock = gdk_surface_get_frame_clock (surface);
if (clock) /* might be NULL if surface was destroyed */
gdk_frame_clock_request_phase (clock, GDK_FRAME_CLOCK_PHASE_FLUSH_EVENTS);
}
}
static void
@@ -714,24 +744,47 @@ gdk_motion_event_push_history (GdkEvent *event,
g_assert (GDK_IS_EVENT_TYPE (event, GDK_MOTION_NOTIFY));
g_assert (GDK_IS_EVENT_TYPE (history_event, GDK_MOTION_NOTIFY));
if (!self->tool)
return;
if (G_UNLIKELY (!self->history))
self->history = g_array_new (FALSE, TRUE, sizeof (GdkTimeCoord));
if (((GdkMotionEvent *)history_event)->history)
{
GArray *history = ((GdkMotionEvent *)history_event)->history;
g_array_append_vals (self->history, history->data, history->len);
}
tool = gdk_event_get_device_tool (history_event);
memset (&hist, 0, sizeof (GdkTimeCoord));
hist.time = gdk_event_get_time (history_event);
hist.flags = gdk_device_tool_get_axes (tool);
for (i = GDK_AXIS_X; i < GDK_AXIS_LAST; i++)
gdk_event_get_axis (history_event, i, &hist.axes[i]);
if (tool)
{
hist.flags = gdk_device_tool_get_axes (tool);
for (i = GDK_AXIS_X; i < GDK_AXIS_LAST; i++)
gdk_event_get_axis (history_event, i, &hist.axes[i]);
}
if (G_UNLIKELY (!self->history))
self->history = g_array_new (FALSE, TRUE, sizeof (GdkTimeCoord));
/* GdkTimeCoord has no dedicated fields to record event position. For plain
* pointer events, and for tools which don't report GDK_AXIS_X/GDK_AXIS_Y
* on their own, we surface the position using the X and Y input axes.
*/
if (!(hist.flags & GDK_AXIS_FLAG_X) || !(hist.flags & GDK_AXIS_FLAG_Y))
{
hist.flags |= GDK_AXIS_FLAG_X | GDK_AXIS_FLAG_Y;
gdk_event_get_position (history_event, &hist.axes[GDK_AXIS_X], &hist.axes[GDK_AXIS_Y]);
}
g_array_append_val (self->history, hist);
}
/* If the last N events in the event queue are motion notify
* events for the same surface, drop all but the last.
*
* If a button is held down or the device has a tool, then
* we give the remaining events a history containing the N-1
* dropped events.
*/
void
_gdk_event_queue_handle_motion_compression (GdkDisplay *display)
{
@@ -741,9 +794,6 @@ _gdk_event_queue_handle_motion_compression (GdkDisplay *display)
GdkDevice *pending_motion_device = NULL;
GdkEvent *last_motion = NULL;
/* If the last N events in the event queue are motion notify
* events for the same surface, drop all but the last */
tmp_list = g_queue_peek_tail_link (&display->queued_events);
while (tmp_list)
@@ -780,26 +830,17 @@ _gdk_event_queue_handle_motion_compression (GdkDisplay *display)
if (last_motion != NULL)
{
GdkModifierType state = gdk_event_get_modifier_state (last_motion);
if (state &
(GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK |
GDK_BUTTON4_MASK | GDK_BUTTON5_MASK))
gdk_motion_event_push_history (last_motion, pending_motions->data);
if ((gdk_event_get_modifier_state (last_motion) &
(GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK |
GDK_BUTTON4_MASK | GDK_BUTTON5_MASK)) ||
gdk_event_get_device_tool (last_motion) != NULL)
gdk_motion_event_push_history (last_motion, pending_motions->data);
}
gdk_event_unref (pending_motions->data);
g_queue_delete_link (&display->queued_events, pending_motions);
pending_motions = next;
}
if (g_queue_get_length (&display->queued_events) == 1 &&
g_queue_peek_head_link (&display->queued_events) == pending_motions)
{
GdkFrameClock *clock = gdk_surface_get_frame_clock (pending_motion_surface);
if (clock) /* might be NULL if surface was destroyed */
gdk_frame_clock_request_phase (clock, GDK_FRAME_CLOCK_PHASE_FLUSH_EVENTS);
}
}
void
@@ -903,6 +944,9 @@ gdk_event_get_pointer_emulated (GdkEvent *event)
* Extract the axis value for a particular axis use from
* an event structure.
*
* To find out which axes are used, use [method@Gdk.DeviceTool.get_axes]
* on the device tool returned by [method@Gdk.Event.get_device_tool].
*
* Returns: %TRUE if the specified axis was found, otherwise %FALSE
*/
gboolean
@@ -1129,6 +1173,9 @@ G_DEFINE_BOXED_TYPE (GdkEventSequence, gdk_event_sequence,
*
* Extracts all axis values from an event.
*
* To find out which axes are used, use [method@Gdk.DeviceTool.get_axes]
* on the device tool returned by [method@Gdk.Event.get_device_tool].
*
* Returns: %TRUE on success, otherwise %FALSE
*/
gboolean
@@ -1179,7 +1226,7 @@ gdk_event_get_event_type (GdkEvent *event)
*
* Extracts the surface associated with an event.
*
* Returns: (transfer none): The `GdkSurface` associated with the event
* Returns: (transfer none) (nullable): The `GdkSurface` associated with the event
*/
GdkSurface *
gdk_event_get_surface (GdkEvent *event)
@@ -2304,7 +2351,8 @@ gdk_scroll_event_new (GdkSurface *surface,
GdkModifierType state,
double delta_x,
double delta_y,
gboolean is_stop)
gboolean is_stop,
GdkScrollUnit unit)
{
GdkScrollEvent *self = gdk_event_alloc (GDK_SCROLL, surface, device, time);
@@ -2314,6 +2362,7 @@ gdk_scroll_event_new (GdkSurface *surface,
self->delta_x = delta_x;
self->delta_y = delta_y;
self->is_stop = is_stop;
self->unit = unit;
return (GdkEvent *) self;
}
@@ -2333,6 +2382,7 @@ gdk_scroll_event_new_discrete (GdkSurface *surface,
self->state = state;
self->direction = direction;
self->pointer_emulated = emulated;
self->unit = GDK_SCROLL_UNIT_WHEEL;
return (GdkEvent *) self;
}
@@ -2366,6 +2416,9 @@ gdk_scroll_event_get_direction (GdkEvent *event)
*
* The deltas will be zero unless the scroll direction
* is %GDK_SCROLL_SMOOTH.
*
* For the representation unit of these deltas, see
* [method@Gdk.ScrollEvent.get_unit].
*/
void
gdk_scroll_event_get_deltas (GdkEvent *event,
@@ -2408,6 +2461,31 @@ gdk_scroll_event_is_stop (GdkEvent *event)
return self->is_stop;
}
/**
* gdk_scroll_event_get_unit:
* @event: (type GdkScrollEvent): a scroll event.
*
* Extracts the scroll delta unit of a scroll event.
*
* The unit will always be %GDK_SCROLL_UNIT_WHEEL if the scroll direction is not
* %GDK_SCROLL_SMOOTH.
*
* Returns: the scroll unit.
*
* Since: 4.8
*/
GdkScrollUnit
gdk_scroll_event_get_unit (GdkEvent *event)
{
GdkScrollEvent *self = (GdkScrollEvent *) event;
g_return_val_if_fail (GDK_IS_EVENT (event), GDK_SCROLL_UNIT_WHEEL);
g_return_val_if_fail (GDK_IS_EVENT_TYPE (event, GDK_SCROLL),
GDK_SCROLL_UNIT_WHEEL);
return self->unit;
}
/* }}} */
/* {{{ GdkTouchpadEvent */
@@ -2431,6 +2509,14 @@ gdk_touchpad_event_get_state (GdkEvent *event)
return self->state;
}
static GdkEventSequence *
gdk_touchpad_event_get_sequence (GdkEvent *event)
{
GdkTouchpadEvent *self = (GdkTouchpadEvent *) event;
return self->sequence;
}
static gboolean
gdk_touchpad_event_get_position (GdkEvent *event,
double *x,
@@ -2450,7 +2536,7 @@ static const GdkEventTypeInfo gdk_touchpad_event_info = {
NULL,
gdk_touchpad_event_get_state,
gdk_touchpad_event_get_position,
NULL,
gdk_touchpad_event_get_sequence,
NULL,
NULL,
};
@@ -2458,22 +2544,32 @@ static const GdkEventTypeInfo gdk_touchpad_event_info = {
GDK_DEFINE_EVENT_TYPE (GdkTouchpadEvent, gdk_touchpad_event,
&gdk_touchpad_event_info,
GDK_EVENT_TYPE_SLOT (GDK_TOUCHPAD_SWIPE)
GDK_EVENT_TYPE_SLOT (GDK_TOUCHPAD_PINCH))
GDK_EVENT_TYPE_SLOT (GDK_TOUCHPAD_PINCH)
GDK_EVENT_TYPE_SLOT (GDK_TOUCHPAD_HOLD))
GdkEvent *
gdk_touchpad_event_new_swipe (GdkSurface *surface,
GdkDevice *device,
guint32 time,
GdkModifierType state,
GdkTouchpadGesturePhase phase,
double x,
double y,
int n_fingers,
double dx,
double dy)
gdk_touchpad_event_new_swipe (GdkSurface *surface,
GdkEventSequence *sequence,
GdkDevice *device,
guint32 time,
GdkModifierType state,
GdkTouchpadGesturePhase phase,
double x,
double y,
int n_fingers,
double dx,
double dy)
{
GdkTouchpadEvent *self = gdk_event_alloc (GDK_TOUCHPAD_SWIPE, surface, device, time);
GdkTouchpadEvent *self;
g_return_val_if_fail (phase == GDK_TOUCHPAD_GESTURE_PHASE_BEGIN ||
phase == GDK_TOUCHPAD_GESTURE_PHASE_END ||
phase == GDK_TOUCHPAD_GESTURE_PHASE_UPDATE ||
phase == GDK_TOUCHPAD_GESTURE_PHASE_CANCEL, NULL);
self = gdk_event_alloc (GDK_TOUCHPAD_SWIPE, surface, device, time);
self->sequence = sequence;
self->state = state;
self->phase = phase;
self->x = x;
@@ -2486,21 +2582,30 @@ gdk_touchpad_event_new_swipe (GdkSurface *surface,
}
GdkEvent *
gdk_touchpad_event_new_pinch (GdkSurface *surface,
GdkDevice *device,
guint32 time,
GdkModifierType state,
GdkTouchpadGesturePhase phase,
double x,
double y,
int n_fingers,
double dx,
double dy,
double scale,
double angle_delta)
gdk_touchpad_event_new_pinch (GdkSurface *surface,
GdkEventSequence *sequence,
GdkDevice *device,
guint32 time,
GdkModifierType state,
GdkTouchpadGesturePhase phase,
double x,
double y,
int n_fingers,
double dx,
double dy,
double scale,
double angle_delta)
{
GdkTouchpadEvent *self = gdk_event_alloc (GDK_TOUCHPAD_PINCH, surface, device, time);
GdkTouchpadEvent *self;
g_return_val_if_fail (phase == GDK_TOUCHPAD_GESTURE_PHASE_BEGIN ||
phase == GDK_TOUCHPAD_GESTURE_PHASE_END ||
phase == GDK_TOUCHPAD_GESTURE_PHASE_UPDATE ||
phase == GDK_TOUCHPAD_GESTURE_PHASE_CANCEL, NULL);
self = gdk_event_alloc (GDK_TOUCHPAD_PINCH, surface, device, time);
self->sequence = sequence;
self->state = state;
self->phase = phase;
self->x = x;
@@ -2514,6 +2619,27 @@ gdk_touchpad_event_new_pinch (GdkSurface *surface,
return (GdkEvent *) self;
}
GdkEvent *
gdk_touchpad_event_new_hold (GdkSurface *surface,
GdkDevice *device,
guint32 time,
GdkModifierType state,
GdkTouchpadGesturePhase phase,
double x,
double y,
int n_fingers)
{
GdkTouchpadEvent *self = gdk_event_alloc (GDK_TOUCHPAD_HOLD, surface, device, time);
self->state = state;
self->phase = phase;
self->x = x;
self->y = y;
self->n_fingers = n_fingers;
return (GdkEvent *) self;
}
/**
* gdk_touchpad_event_get_gesture_phase:
* @event: (type GdkTouchpadEvent): a touchpad event
@@ -2529,7 +2655,8 @@ gdk_touchpad_event_get_gesture_phase (GdkEvent *event)
g_return_val_if_fail (GDK_IS_EVENT (event), 0);
g_return_val_if_fail (GDK_IS_EVENT_TYPE (event, GDK_TOUCHPAD_PINCH) ||
GDK_IS_EVENT_TYPE (event, GDK_TOUCHPAD_SWIPE), 0);
GDK_IS_EVENT_TYPE (event, GDK_TOUCHPAD_SWIPE) ||
GDK_IS_EVENT_TYPE (event, GDK_TOUCHPAD_HOLD), 0);
return self->phase;
}
@@ -2549,7 +2676,8 @@ gdk_touchpad_event_get_n_fingers (GdkEvent *event)
g_return_val_if_fail (GDK_IS_EVENT (event), 0);
g_return_val_if_fail (GDK_IS_EVENT_TYPE (event, GDK_TOUCHPAD_PINCH) ||
GDK_IS_EVENT_TYPE (event, GDK_TOUCHPAD_SWIPE), 0);
GDK_IS_EVENT_TYPE (event, GDK_TOUCHPAD_SWIPE) ||
GDK_IS_EVENT_TYPE (event, GDK_TOUCHPAD_HOLD), 0);
return self->n_fingers;
}
@@ -2907,7 +3035,8 @@ gdk_motion_event_new (GdkSurface *surface,
* to the application because they occurred in the same frame as @event.
*
* Note that only motion and scroll events record history, and motion
* events do it only if one of the mouse buttons is down.
* events do it only if one of the mouse buttons is down, or the device
* has a tool.
*
* Returns: (transfer container) (array length=out_n_coords) (nullable): an
* array of time and coordinates

View File

@@ -169,6 +169,8 @@ typedef struct _GdkTouchpadEvent GdkTouchpadEvent;
* @GDK_PAD_RING: A tablet pad axis event from a "ring".
* @GDK_PAD_STRIP: A tablet pad axis event from a "strip".
* @GDK_PAD_GROUP_MODE: A tablet pad group mode change.
* @GDK_TOUCHPAD_HOLD: A touchpad hold gesture event, the current state
* is determined by its phase field. Since: 4.6
* @GDK_EVENT_LAST: marks the end of the GdkEventType enumeration.
*
* Specifies the type of the event.
@@ -203,6 +205,7 @@ typedef enum
GDK_PAD_RING,
GDK_PAD_STRIP,
GDK_PAD_GROUP_MODE,
GDK_TOUCHPAD_HOLD,
GDK_EVENT_LAST /* helper variable for decls */
} GdkEventType;
@@ -262,6 +265,37 @@ typedef enum
GDK_SCROLL_SMOOTH
} GdkScrollDirection;
/**
* GdkScrollUnit:
* @GDK_SCROLL_UNIT_WHEEL: The delta is in number of wheel clicks.
* @GDK_SCROLL_UNIT_SURFACE: The delta is in surface pixels to scroll directly
* on screen.
*
* Specifies the unit of scroll deltas.
*
* When you get %GDK_SCROLL_UNIT_WHEEL, a delta of 1.0 means 1 wheel detent
* click in the south direction, 2.0 means 2 wheel detent clicks in the south
* direction... This is the same logic for negative values but in the north
* direction.
*
* If you get %GDK_SCROLL_UNIT_SURFACE, are managing a scrollable view and get a
* value of 123, you have to scroll 123 surface logical pixels right if it's
* @delta_x or down if it's @delta_y. This is the same logic for negative values
* but you have to scroll left instead of right if it's @delta_x and up instead
* of down if it's @delta_y.
*
* 1 surface logical pixel is equal to 1 real screen pixel multiplied by the
* final scale factor of your graphical interface (the product of the desktop
* scale factor and eventually a custom scale factor in your app).
*
* Since: 4.8
*/
typedef enum
{
GDK_SCROLL_UNIT_WHEEL,
GDK_SCROLL_UNIT_SURFACE
} GdkScrollUnit;
/**
* GdkNotifyType:
* @GDK_NOTIFY_ANCESTOR: the surface is entered from an ancestor or
@@ -392,6 +426,8 @@ GDK_AVAILABLE_IN_ALL
void gdk_scroll_event_get_deltas (GdkEvent *event,
double *delta_x,
double *delta_y);
GDK_AVAILABLE_IN_4_8
GdkScrollUnit gdk_scroll_event_get_unit (GdkEvent *event);
GDK_AVAILABLE_IN_ALL
gboolean gdk_scroll_event_is_stop (GdkEvent *event);

View File

@@ -209,9 +209,10 @@ struct _GdkTouchEvent
* @pointer_emulated: whether the scroll event was the result of
* a pointer emulation
* @tool: a `GdkDeviceTool`
* @history: (element-type GdkScrollHistory): array of times and deltas
* @history: (element-type GdkTimeCoord): array of times and deltas
* for other scroll events that were compressed before delivering the
* current event
* @unit: The scroll unit in which delta_x and delta_y are represented.
*
* Generated from button presses for the buttons 4 to 7. Wheel mice are
* usually configured to generate button press events for buttons 4 and 5
@@ -233,7 +234,8 @@ struct _GdkScrollEvent
gboolean pointer_emulated;
gboolean is_stop;
GdkDeviceTool *tool;
GArray *history; /* <GdkScrollHistory> */
GArray *history; /* <GdkTimeCoord> */
GdkScrollUnit unit;
};
/*
@@ -402,6 +404,7 @@ struct _GdkTouchpadEvent
{
GdkEvent parent_instance;
GdkEventSequence *sequence;
GdkModifierType state;
gint8 phase;
gint8 n_fingers;
@@ -485,7 +488,8 @@ GdkEvent * gdk_scroll_event_new (GdkSurface *surface,
GdkModifierType state,
double delta_x,
double delta_y,
gboolean is_stop);
gboolean is_stop,
GdkScrollUnit unit);
GdkEvent * gdk_scroll_event_new_discrete (GdkSurface *surface,
GdkDevice *device,
@@ -506,18 +510,20 @@ GdkEvent * gdk_touch_event_new (GdkEventType type,
double *axes,
gboolean emulating);
GdkEvent * gdk_touchpad_event_new_swipe (GdkSurface *surface,
GdkDevice *device,
guint32 time,
GdkModifierType state,
GdkEvent * gdk_touchpad_event_new_swipe (GdkSurface *surface,
GdkEventSequence *sequence,
GdkDevice *device,
guint32 time,
GdkModifierType state,
GdkTouchpadGesturePhase phase,
double x,
double y,
int n_fingers,
double dx,
double dy);
double x,
double y,
int n_fingers,
double dx,
double dy);
GdkEvent * gdk_touchpad_event_new_pinch (GdkSurface *surface,
GdkEventSequence *sequence,
GdkDevice *device,
guint32 time,
GdkModifierType state,
@@ -530,6 +536,15 @@ GdkEvent * gdk_touchpad_event_new_pinch (GdkSurface *surface,
double scale,
double angle_delta);
GdkEvent * gdk_touchpad_event_new_hold (GdkSurface *surface,
GdkDevice *device,
guint32 time,
GdkModifierType state,
GdkTouchpadGesturePhase phase,
double x,
double y,
int n_fingers);
GdkEvent * gdk_pad_event_new_ring (GdkSurface *surface,
GdkDevice *device,
guint32 time,

View File

@@ -117,6 +117,7 @@ typedef struct {
#ifdef HAVE_EGL
EGLContext egl_context;
EGLBoolean (*eglSwapBuffersWithDamage) (EGLDisplay, EGLSurface, const EGLint *, EGLint);
#endif
} GdkGLContextPrivate;
@@ -151,6 +152,12 @@ unmask_context (MaskedContext *mask)
return GDK_GL_CONTEXT (GSIZE_TO_POINTER (GPOINTER_TO_SIZE (mask) & ~(gsize) 1));
}
static inline gboolean
mask_is_surfaceless (MaskedContext *mask)
{
return GPOINTER_TO_SIZE (mask) & (gsize) 1;
}
static void
unref_unmasked (gpointer data)
{
@@ -179,8 +186,7 @@ gdk_gl_context_dispose (GObject *gobject)
if (priv->egl_context != NULL)
{
GdkSurface *surface = gdk_gl_context_get_surface (context);
GdkDisplay *display = gdk_surface_get_display (surface);
GdkDisplay *display = gdk_draw_context_get_display (GDK_DRAW_CONTEXT (context));
EGLDisplay *egl_display = gdk_display_get_egl_display (display);
if (eglGetCurrentContext () == priv->egl_context)
@@ -273,7 +279,11 @@ gdk_gl_context_real_realize (GdkGLContext *context,
int i = 0;
G_GNUC_UNUSED gint64 start_time = GDK_PROFILER_CURRENT_TIME;
gdk_gl_context_get_required_version (context, &major, &minor);
if (share != NULL)
gdk_gl_context_get_required_version (share, &major, &minor);
else
gdk_gl_context_get_required_version (context, &major, &minor);
debug_bit = gdk_gl_context_get_debug_enabled (context);
forward_bit = gdk_gl_context_get_forward_compatible (context);
legacy_bit = GDK_DISPLAY_DEBUG_CHECK (display, GL_LEGACY) ||
@@ -411,6 +421,11 @@ gdk_gl_context_real_realize (GdkGLContext *context,
gdk_gl_context_set_is_legacy (context, legacy_bit);
if (epoxy_has_egl_extension (egl_display, "EGL_KHR_swap_buffers_with_damage"))
priv->eglSwapBuffersWithDamage = (gpointer)epoxy_eglGetProcAddress ("eglSwapBuffersWithDamageKHR");
else if (epoxy_has_egl_extension (egl_display, "EGL_EXT_swap_buffers_with_damage"))
priv->eglSwapBuffersWithDamage = (gpointer)epoxy_eglGetProcAddress ("eglSwapBuffersWithDamageEXT");
gdk_profiler_end_mark (start_time, "realize GdkWaylandGLContext", NULL);
return api;
@@ -574,8 +589,8 @@ gdk_gl_context_real_begin_frame (GdkDrawContext *draw_context,
glViewport (0, 0, ww, wh);
#ifdef HAVE_EGL
if (priv->egl_context)
glDrawBuffers (1, (GLenum[1]) { GL_BACK_LEFT });
if (priv->egl_context && gdk_gl_context_check_version (context, 0, 0, 3, 0))
glDrawBuffers (1, (GLenum[1]) { gdk_gl_context_get_use_es (context) ? GL_BACK : GL_BACK_LEFT });
#endif
}
@@ -599,7 +614,7 @@ gdk_gl_context_real_end_frame (GdkDrawContext *draw_context,
gdk_profiler_add_mark (GDK_PROFILER_CURRENT_TIME, 0, "EGL", "swap buffers");
if (display->have_egl_swap_buffers_with_damage)
if (priv->eglSwapBuffersWithDamage)
{
EGLint stack_rects[4 * 4]; /* 4 rects */
EGLint *heap_rects = NULL;
@@ -623,7 +638,7 @@ gdk_gl_context_real_end_frame (GdkDrawContext *draw_context,
rects[j++] = rect.width * scale;
rects[j++] = rect.height * scale;
}
eglSwapBuffersWithDamageEXT (gdk_display_get_egl_display (display), egl_surface, rects, n_rects);
priv->eglSwapBuffersWithDamage (gdk_display_get_egl_display (display), egl_surface, rects, n_rects);
g_free (heap_rects);
}
else
@@ -639,6 +654,12 @@ gdk_gl_context_surface_resized (GdkDrawContext *draw_context)
gdk_gl_context_clear_old_updated_area (context);
}
static guint
gdk_gl_context_real_get_default_framebuffer (GdkGLContext *self)
{
return 0;
}
static void
gdk_gl_context_class_init (GdkGLContextClass *klass)
{
@@ -650,6 +671,7 @@ gdk_gl_context_class_init (GdkGLContextClass *klass)
klass->is_shared = gdk_gl_context_real_is_shared;
klass->make_current = gdk_gl_context_real_make_current;
klass->clear_current = gdk_gl_context_real_clear_current;
klass->get_default_framebuffer = gdk_gl_context_real_get_default_framebuffer;
draw_context_class->begin_frame = gdk_gl_context_real_begin_frame;
draw_context_class->end_frame = gdk_gl_context_real_end_frame;
@@ -997,16 +1019,33 @@ gdk_gl_context_set_required_version (GdkGLContext *context,
}
gboolean
gdk_gl_context_check_version (GdkGLContext *context,
int required_major,
int required_minor)
gdk_gl_context_check_version (GdkGLContext *self,
int required_gl_major,
int required_gl_minor,
int required_gles_major,
int required_gles_minor)
{
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (self);
g_return_val_if_fail (GDK_IS_GL_CONTEXT (context), FALSE);
g_return_val_if_fail (required_minor < 10, FALSE);
g_return_val_if_fail (GDK_IS_GL_CONTEXT (self), FALSE);
g_return_val_if_fail (required_gl_minor < 10, FALSE);
g_return_val_if_fail (required_gles_minor < 10, FALSE);
return priv->gl_version >= required_major * 10 + required_minor;
if (!gdk_gl_context_is_realized (self))
return FALSE;
switch (priv->api)
{
case GDK_GL_API_GL:
return priv->gl_version >= required_gl_major * 10 + required_gl_minor;
case GDK_GL_API_GLES:
return priv->gl_version >= required_gles_major * 10 + required_gles_minor;
default:
g_return_val_if_reached (FALSE);
}
}
/**
@@ -1026,26 +1065,29 @@ gdk_gl_context_get_required_version (GdkGLContext *context,
{
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
gboolean force_gles = FALSE;
#ifdef G_ENABLE_DEBUG
GdkDisplay *display;
#endif
int default_major, default_minor;
int maj, min;
g_return_if_fail (GDK_IS_GL_CONTEXT (context));
#ifdef G_ENABLE_DEBUG
display = gdk_draw_context_get_display (GDK_DRAW_CONTEXT (context));
#ifdef G_ENABLE_DEBUG
force_gles = GDK_DISPLAY_DEBUG_CHECK (display, GL_GLES);
#endif
/* libANGLE on Windows at least requires GLES 3.0+ */
if (display->have_egl_win32_libangle)
force_gles = TRUE;
/* Default fallback values for uninitialised contexts; we
* enforce a context version number of 3.2 for desktop GL,
* and 2.0 for GLES
*/
if (gdk_gl_context_get_use_es (context) || force_gles)
{
default_major = 2;
default_major = display->have_egl_win32_libangle ? 3 : 2;
default_minor = 0;
}
else
@@ -1323,6 +1365,7 @@ gl_debug_message_callback (GLenum source,
const char *message_source;
const char *message_type;
const char *message_severity;
GLogLevelFlags log_level;
if (severity == GL_DEBUG_SEVERITY_NOTIFICATION)
return;
@@ -1384,22 +1427,31 @@ gl_debug_message_callback (GLenum source,
{
case GL_DEBUG_SEVERITY_HIGH:
message_severity = "High";
log_level = G_LOG_LEVEL_CRITICAL;
break;
case GL_DEBUG_SEVERITY_MEDIUM:
message_severity = "Medium";
log_level = G_LOG_LEVEL_WARNING;
break;
case GL_DEBUG_SEVERITY_LOW:
message_severity = "Low";
log_level = G_LOG_LEVEL_MESSAGE;
break;
case GL_DEBUG_SEVERITY_NOTIFICATION:
message_severity = "Notification";
log_level = G_LOG_LEVEL_INFO;
break;
default:
message_severity = "Unknown";
log_level = G_LOG_LEVEL_MESSAGE;
}
g_warning ("OPENGL:\n Source: %s\n Type: %s\n Severity: %s\n Message: %s",
message_source, message_type, message_severity, message);
/* There's no higher level function taking a log level argument... */
g_log_structured_standard (G_LOG_DOMAIN, log_level,
__FILE__, G_STRINGIFY (__LINE__),
G_STRFUNC,
"OPENGL:\n Source: %s\n Type: %s\n Severity: %s\n Message: %s",
message_source, message_type, message_severity, message);
}
/**
@@ -1655,6 +1707,31 @@ gdk_gl_context_clear_current (void)
}
}
/*<private>
* gdk_gl_context_clear_current_if_surface:
* @surface: surface to clear for
*
* Does a gdk_gl_context_clear_current() if the current context is attached
* to @surface, leaves the current context alone otherwise.
**/
void
gdk_gl_context_clear_current_if_surface (GdkSurface *surface)
{
MaskedContext *current;
current = g_private_get (&thread_current_context);
if (current != NULL && !mask_is_surfaceless (current))
{
GdkGLContext *context = unmask_context (current);
if (gdk_gl_context_get_surface (context) != surface)
return;
if (GDK_GL_CONTEXT_GET_CLASS (context)->clear_current (context))
g_private_replace (&thread_current_context, NULL);
}
}
/**
* gdk_gl_context_get_current:
*

View File

@@ -71,6 +71,8 @@ struct _GdkGLContextClass
gboolean (* is_shared) (GdkGLContext *self,
GdkGLContext *other);
guint (* get_default_framebuffer) (GdkGLContext *self);
};
typedef struct {
@@ -99,6 +101,8 @@ gboolean gdk_gl_backend_can_be_used (GdkGLBackend
GError **error);
void gdk_gl_backend_use (GdkGLBackend backend_type);
void gdk_gl_context_clear_current_if_surface (GdkSurface *surface);
GdkGLContext * gdk_gl_context_new (GdkDisplay *display,
GdkSurface *surface);
@@ -109,8 +113,10 @@ void gdk_gl_context_set_is_legacy (GdkGLContext
gboolean is_legacy);
gboolean gdk_gl_context_check_version (GdkGLContext *context,
int required_major,
int required_minor);
int required_gl_major,
int required_gl_minor,
int required_gles_major,
int required_gles_minor);
gboolean gdk_gl_context_has_unpack_subimage (GdkGLContext *context);
void gdk_gl_context_push_debug_group (GdkGLContext *context,

View File

@@ -21,6 +21,7 @@
#include "gdkgltextureprivate.h"
#include "gdkdisplayprivate.h"
#include "gdkglcontextprivate.h"
#include "gdkmemoryformatprivate.h"
#include "gdkmemorytextureprivate.h"
#include "gdktextureprivate.h"
@@ -174,10 +175,19 @@ gdk_gl_texture_do_download (gpointer texture_,
glGenFramebuffers (1, &fbo);
glBindFramebuffer (GL_FRAMEBUFFER, fbo);
glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, self->id, 0);
glGetFramebufferParameteriv (GL_FRAMEBUFFER, GL_IMPLEMENTATION_COLOR_READ_FORMAT, &gl_read_format);
glGetFramebufferParameteriv (GL_FRAMEBUFFER, GL_IMPLEMENTATION_COLOR_READ_TYPE, &gl_read_type);
if (!gdk_gl_texture_find_format (gdk_gl_context_get_use_es (self->context), gl_read_format, gl_read_type, &actual_format))
actual_format = GDK_MEMORY_R8G8B8A8_PREMULTIPLIED; /* pray */
if (gdk_gl_context_check_version (self->context, 4, 3, 3, 1))
{
glGetFramebufferParameteriv (GL_FRAMEBUFFER, GL_IMPLEMENTATION_COLOR_READ_FORMAT, &gl_read_format);
glGetFramebufferParameteriv (GL_FRAMEBUFFER, GL_IMPLEMENTATION_COLOR_READ_TYPE, &gl_read_type);
if (!gdk_gl_texture_find_format (gdk_gl_context_get_use_es (self->context), gl_read_format, gl_read_type, &actual_format))
actual_format = GDK_MEMORY_R8G8B8A8_PREMULTIPLIED; /* pray */
}
else
{
gl_read_format = GL_RGBA;
gl_read_type = GL_UNSIGNED_BYTE;
actual_format = GDK_MEMORY_R8G8B8A8_PREMULTIPLIED;
}
if (download->format == actual_format &&
(download->stride == expected_stride))
@@ -305,9 +315,11 @@ gdk_gl_texture_determine_format (GdkGLTexture *self)
GLint active_texture;
GLint internal_format;
if (self->context != gdk_gl_context_get_current ())
/* Abort if somebody else is GL-ing here... */
if (self->context != gdk_gl_context_get_current () ||
/* ... or glGetTexLevelParameter() isn't supported */
!gdk_gl_context_check_version (self->context, 0, 0, 3, 1))
{
/* Somebody else is GL-ing here, abort! */
texture->format = GDK_MEMORY_DEFAULT;
return;
}
@@ -353,6 +365,42 @@ gdk_gl_texture_determine_format (GdkGLTexture *self)
texture->format = GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED;
break;
case GL_RGBA:
{
GLint red_size = 0;
GLint green_size = 0;
GLint blue_size = 0;
GLint alpha_size = 0;
GLint red_type = 0;
GLint green_type = 0;
GLint blue_type = 0;
GLint alpha_type = 0;
glGetTexLevelParameteriv (GL_TEXTURE_2D, 0, GL_TEXTURE_RED_TYPE, &red_type);
glGetTexLevelParameteriv (GL_TEXTURE_2D, 0, GL_TEXTURE_GREEN_TYPE, &green_type);
glGetTexLevelParameteriv (GL_TEXTURE_2D, 0, GL_TEXTURE_BLUE_TYPE, &blue_type);
glGetTexLevelParameteriv (GL_TEXTURE_2D, 0, GL_TEXTURE_ALPHA_TYPE, &alpha_type);
glGetTexLevelParameteriv (GL_TEXTURE_2D, 0, GL_TEXTURE_RED_SIZE, &red_size);
glGetTexLevelParameteriv (GL_TEXTURE_2D, 0, GL_TEXTURE_GREEN_SIZE, &green_size);
glGetTexLevelParameteriv (GL_TEXTURE_2D, 0, GL_TEXTURE_BLUE_SIZE, &blue_size);
glGetTexLevelParameteriv (GL_TEXTURE_2D, 0, GL_TEXTURE_ALPHA_SIZE, &alpha_size);
#define CHECK_RGBA(rt,gt,bt,at,rs,gs,bs,as) \
(red_type == rt && green_type == gt && blue_type == bt && alpha_type == at && \
red_size == rs && green_size == gs && blue_size == bs && alpha_size == as)
if (CHECK_RGBA (GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 8))
{
texture->format = GDK_MEMORY_R8G8B8A8_PREMULTIPLIED;
break;
}
#undef CHECK_RGBA
}
G_GNUC_FALLTHROUGH;
default:
g_warning ("Texture in unexpected format 0x%X (%d). File a bug about adding it to GTK", internal_format, internal_format);
/* fallback to the dumbest possible format
@@ -380,7 +428,8 @@ gdk_gl_texture_determine_format (GdkGLTexture *self)
* which will happen when the GdkTexture object is finalized, or due to
* an explicit call of [method@Gdk.GLTexture.release].
*
* Return value: (transfer full): A newly-created `GdkTexture`
* Return value: (transfer full) (type GdkGLTexture): A newly-created
* `GdkTexture`
*/
GdkTexture *
gdk_gl_texture_new (GdkGLContext *context,

View File

@@ -19,7 +19,7 @@
* Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog
* files for a list of changes. These files are distributed with
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
#ifndef __GDKINTL_H__
@@ -27,10 +27,6 @@
#include <glib/gi18n-lib.h>
#ifdef ENABLE_NLS
#define P_(String) dgettext(GETTEXT_PACKAGE "-properties",String)
#else
#define P_(String) (String)
#endif
#define P_(String) dgettext (GETTEXT_PACKAGE "-properties", String)
#endif

View File

@@ -1,16 +1,16 @@
#!/usr/bin/env perl
# Updates https://gitlab.gnome.org/GNOME/gtk/tree/master/gdk/gdkkeysyms.h from upstream (X.org 7.x),
# Updates https://gitlab.gnome.org/GNOME/gtk/tree/main/gdk/gdkkeysyms.h from upstream (X.org 7.x),
# from https://cgit.freedesktop.org/xorg/proto/x11proto/plain/keysymdef.h
#
#
# Author : Simos Xenitellis <simos at gnome dot org>.
# Author : Bastien Nocera <hadess@hadess.net>
# Version : 1.2
#
# Input : https://cgit.freedesktop.org/xorg/proto/x11proto/plain/keysymdef.h
# Input : https://cgit.freedesktop.org/xorg/proto/x11proto/plain/XF86keysym.h
# Output : https://gitlab.gnome.org/GNOME/gtk/tree/master/gdk/gdkkeysyms.h
#
# Output : https://gitlab.gnome.org/GNOME/gtk/tree/main/gdk/gdkkeysyms.h
#
# Notes : It downloads keysymdef.h from the Internet, if not found locally,
# Notes : and creates an updated gdkkeysyms.h
# Notes : This version updates the source of gdkkeysyms.h from CVS to the GIT server.
@@ -24,7 +24,7 @@ if ( ! -f "keysymdef.h" )
{
print "Trying to download keysymdef.h from\n";
print "http://cgit.freedesktop.org/xorg/proto/x11proto/plain/keysymdef.h\n";
die "Unable to download keysymdef.h from http://cgit.freedesktop.org/xorg/proto/x11proto/plain/keysymdef.h\n"
die "Unable to download keysymdef.h from http://cgit.freedesktop.org/xorg/proto/x11proto/plain/keysymdef.h\n"
unless system("wget -c -O keysymdef.h \"http://cgit.freedesktop.org/xorg/proto/x11proto/plain/keysymdef.h\"") == 0;
print " done.\n\n";
}
@@ -39,7 +39,7 @@ if ( ! -f "XF86keysym.h" )
{
print "Trying to download XF86keysym.h from\n";
print "http://cgit.freedesktop.org/xorg/proto/x11proto/plain/XF86keysym.h\n";
die "Unable to download keysymdef.h from http://cgit.freedesktop.org/xorg/proto/x11proto/plain/XF86keysym.h\n"
die "Unable to download keysymdef.h from http://cgit.freedesktop.org/xorg/proto/x11proto/plain/XF86keysym.h\n"
unless system("wget -c -O XF86keysym.h \"http://cgit.freedesktop.org/xorg/proto/x11proto/plain/XF86keysym.h\"") == 0;
print " done.\n\n";
}
@@ -82,7 +82,7 @@ print OUT_GDKKEYSYMS $LICENSE_HEADER;
print OUT_GDKKEYSYMS<<EOF;
/*
* File auto-generated from script https://gitlab.gnome.org/GNOME/gtk/tree/master/gdk/gdkkeysyms-update.pl
* File auto-generated from script https://gitlab.gnome.org/GNOME/gtk/tree/main/gdk/gdkkeysyms-update.pl
* using the input file
* http://cgit.freedesktop.org/xorg/proto/x11proto/plain/keysymdef.h
* and
@@ -111,7 +111,7 @@ while (<IN_KEYSYMDEF>)
$_ = $keysymelements[1];
die "Internal error, was expecting \"XC_*\", found: $_\n" if ( ! /^XK_/ );
$_ = $keysymelements[2];
die "Internal error, was expecting \"0x*\", found: $_\n" if ( ! /^0x/ );

View File

@@ -18,7 +18,7 @@
/*
* File auto-generated from script https://gitlab.gnome.org/GNOME/gtk/tree/master/gdk/gdkkeysyms-update.pl
* File auto-generated from script https://gitlab.gnome.org/GNOME/gtk/tree/main/gdk/gdkkeysyms-update.pl
* using the input file
* http://cgit.freedesktop.org/xorg/proto/x11proto/plain/keysymdef.h
* and

View File

@@ -369,7 +369,7 @@ static const struct {
{ 0x07a2, 0x0388 }, /* Greek_EPSILONaccent Έ GREEK CAPITAL LETTER EPSILON WITH TONOS */
{ 0x07a3, 0x0389 }, /* Greek_ETAaccent Ή GREEK CAPITAL LETTER ETA WITH TONOS */
{ 0x07a4, 0x038a }, /* Greek_IOTAaccent Ί GREEK CAPITAL LETTER IOTA WITH TONOS */
{ 0x07a5, 0x03aa }, /* Greek_IOTAdieresis Ϊ GREEK CAPITAL LETTER IOTA WITH DIALYTIKA */
{ 0x07a5, 0x03aa }, /* Greek_IOTAdiaeresis Ϊ GREEK CAPITAL LETTER IOTA WITH DIALYTIKA */
{ 0x07a7, 0x038c }, /* Greek_OMICRONaccent Ό GREEK CAPITAL LETTER OMICRON WITH TONOS */
{ 0x07a8, 0x038e }, /* Greek_UPSILONaccent Ύ GREEK CAPITAL LETTER UPSILON WITH TONOS */
{ 0x07a9, 0x03ab }, /* Greek_UPSILONdieresis Ϋ GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA */
@@ -436,22 +436,22 @@ static const struct {
{ 0x07f7, 0x03c7 }, /* Greek_chi χ GREEK SMALL LETTER CHI */
{ 0x07f8, 0x03c8 }, /* Greek_psi ψ GREEK SMALL LETTER PSI */
{ 0x07f9, 0x03c9 }, /* Greek_omega ω GREEK SMALL LETTER OMEGA */
/* 0x08a1 leftradical ? ??? */
/* 0x08a2 topleftradical ? ??? */
/* 0x08a3 horizconnector ? ??? */
{ 0x08a1, 0x23b7 }, /* leftradical ??? */
{ 0x08a2, 0x250c }, /* topleftradical ┌ BOX DRAWINGS LIGHT DOWN AND RIGHT */
{ 0x08a3, 0x2500 }, /* horizconnector ─ BOX DRAWINGS LIGHT HORIZONTAL */
{ 0x08a4, 0x2320 }, /* topintegral ⌠ TOP HALF INTEGRAL */
{ 0x08a5, 0x2321 }, /* botintegral ⌡ BOTTOM HALF INTEGRAL */
{ 0x08a6, 0x2502 }, /* vertconnector │ BOX DRAWINGS LIGHT VERTICAL */
/* 0x08a7 topleftsqbracket ? ??? */
/* 0x08a8 botleftsqbracket ? ??? */
/* 0x08a9 toprightsqbracket ? ??? */
/* 0x08aa botrightsqbracket ? ??? */
/* 0x08ab topleftparens ? ??? */
/* 0x08ac botleftparens ? ??? */
/* 0x08ad toprightparens ? ??? */
/* 0x08ae botrightparens ? ??? */
/* 0x08af leftmiddlecurlybrace ? ??? */
/* 0x08b0 rightmiddlecurlybrace ? ??? */
{ 0x08a7, 0x23a1 }, /* topleftsqbracket ??? */
{ 0x08a8, 0x23a3 }, /* botleftsqbracket ??? */
{ 0x08a9, 0x23a4 }, /* toprightsqbracket ??? */
{ 0x08aa, 0x23a6 }, /* botrightsqbracket ??? */
{ 0x08ab, 0x239b }, /* topleftparens ??? */
{ 0x08ac, 0x239d }, /* botleftparens ??? */
{ 0x08ad, 0x239e }, /* toprightparens ??? */
{ 0x08ae, 0x23a0 }, /* botrightparens ??? */
{ 0x08af, 0x23a8 }, /* leftmiddlecurlybrace ??? */
{ 0x08b0, 0x23ac }, /* rightmiddlecurlybrace ??? */
/* 0x08b1 topleftsummation ? ??? */
/* 0x08b2 botleftsummation ? ??? */
/* 0x08b3 topvertsummationconnector ? ??? */
@@ -467,8 +467,8 @@ static const struct {
{ 0x08c1, 0x221d }, /* variation ∝ PROPORTIONAL TO */
{ 0x08c2, 0x221e }, /* infinity ∞ INFINITY */
{ 0x08c5, 0x2207 }, /* nabla ∇ NABLA */
{ 0x08c8, 0x2245 }, /* approximate ≅ APPROXIMATELY EQUAL TO */
/* 0x08c9 similarequal ? ??? */
{ 0x08c8, 0x223c }, /* approximate TILDE OPERATOR */
{ 0x08c9, 0x2243 }, /* similarequal ≃ ASYMPTOTICALLY EQUAL TO */
{ 0x08cd, 0x21d4 }, /* ifonlyif ⇔ LEFT RIGHT DOUBLE ARROW */
{ 0x08ce, 0x21d2 }, /* implies ⇒ RIGHTWARDS DOUBLE ARROW */
{ 0x08cf, 0x2261 }, /* identical ≡ IDENTICAL TO */
@@ -485,7 +485,7 @@ static const struct {
{ 0x08fc, 0x2191 }, /* uparrow ↑ UPWARDS ARROW */
{ 0x08fd, 0x2192 }, /* rightarrow → RIGHTWARDS ARROW */
{ 0x08fe, 0x2193 }, /* downarrow ↓ DOWNWARDS ARROW */
{ 0x09df, 0x2422 }, /* blank ␢ BLANK SYMBOL */
/* 0x09df blank ? ??? */
{ 0x09e0, 0x25c6 }, /* soliddiamond ◆ BLACK DIAMOND */
{ 0x09e1, 0x2592 }, /* checkerboard ▒ MEDIUM SHADE */
{ 0x09e2, 0x2409 }, /* ht ␉ SYMBOL FOR HORIZONTAL TABULATION */
@@ -499,11 +499,11 @@ static const struct {
{ 0x09ec, 0x250c }, /* upleftcorner ┌ BOX DRAWINGS LIGHT DOWN AND RIGHT */
{ 0x09ed, 0x2514 }, /* lowleftcorner └ BOX DRAWINGS LIGHT UP AND RIGHT */
{ 0x09ee, 0x253c }, /* crossinglines ┼ BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL */
/* 0x09ef horizlinescan1 ? ??? */
/* 0x09f0 horizlinescan3 ? ??? */
{ 0x09ef, 0x23ba }, /* horizlinescan1 ⎺ HORIZONTAL SCAN LINE-1 (Unicode 3.2 draft) */
{ 0x09f0, 0x23bb }, /* horizlinescan3 ⎻ HORIZONTAL SCAN LINE-3 (Unicode 3.2 draft) */
{ 0x09f1, 0x2500 }, /* horizlinescan5 ─ BOX DRAWINGS LIGHT HORIZONTAL */
/* 0x09f2 horizlinescan7 ? ??? */
/* 0x09f3 horizlinescan9 ? ??? */
{ 0x09f2, 0x23bc }, /* horizlinescan7 ⎼ HORIZONTAL SCAN LINE-7 (Unicode 3.2 draft) */
{ 0x09f3, 0x23bd }, /* horizlinescan9 ⎽ HORIZONTAL SCAN LINE-9 (Unicode 3.2 draft) */
{ 0x09f4, 0x251c }, /* leftt ├ BOX DRAWINGS LIGHT VERTICAL AND RIGHT */
{ 0x09f5, 0x2524 }, /* rightt ┤ BOX DRAWINGS LIGHT VERTICAL AND LEFT */
{ 0x09f6, 0x2534 }, /* bott ┴ BOX DRAWINGS LIGHT UP AND HORIZONTAL */
@@ -519,9 +519,9 @@ static const struct {
{ 0x0aa8, 0x200a }, /* hairspace HAIR SPACE */
{ 0x0aa9, 0x2014 }, /* emdash — EM DASH */
{ 0x0aaa, 0x2013 }, /* endash EN DASH */
/* 0x0aac signifblank ? ??? */
{ 0x0aac, 0x2423 }, /* signifblank ␣ OPEN BOX */
{ 0x0aae, 0x2026 }, /* ellipsis … HORIZONTAL ELLIPSIS */
/* 0x0aaf doubbaselinedot ? ??? */
{ 0x0aaf, 0x2025 }, /* doubbaselinedot ‥ TWO DOT LEADER */
{ 0x0ab0, 0x2153 }, /* onethird ⅓ VULGAR FRACTION ONE THIRD */
{ 0x0ab1, 0x2154 }, /* twothirds ⅔ VULGAR FRACTION TWO THIRDS */
{ 0x0ab2, 0x2155 }, /* onefifth ⅕ VULGAR FRACTION ONE FIFTH */
@@ -532,9 +532,9 @@ static const struct {
{ 0x0ab7, 0x215a }, /* fivesixths ⅚ VULGAR FRACTION FIVE SIXTHS */
{ 0x0ab8, 0x2105 }, /* careof ℅ CARE OF */
{ 0x0abb, 0x2012 }, /* figdash FIGURE DASH */
{ 0x0abc, 0x2329 }, /* leftanglebracket 〈 LEFT-POINTING ANGLE BRACKET */
{ 0x0abc, 0x27e8 }, /* leftanglebracket ⟨ MATHEMATICAL LEFT ANGLE BRACKET */
{ 0x0abd, 0x002e }, /* decimalpoint . FULL STOP */
{ 0x0abe, 0x232a }, /* rightanglebracket 〉 RIGHT-POINTING ANGLE BRACKET */
{ 0x0abe, 0x27e9 }, /* rightanglebracket ⟩ MATHEMATICAL RIGHT ANGLE BRACKET */
/* 0x0abf marker ? ??? */
{ 0x0ac3, 0x215b }, /* oneeighth ⅛ VULGAR FRACTION ONE EIGHTH */
{ 0x0ac4, 0x215c }, /* threeeighths ⅜ VULGAR FRACTION THREE EIGHTHS */
@@ -546,12 +546,13 @@ static const struct {
{ 0x0acc, 0x25c1 }, /* leftopentriangle ◁ WHITE LEFT-POINTING TRIANGLE */
{ 0x0acd, 0x25b7 }, /* rightopentriangle ▷ WHITE RIGHT-POINTING TRIANGLE */
{ 0x0ace, 0x25cb }, /* emopencircle ○ WHITE CIRCLE */
{ 0x0acf, 0x25a1 }, /* emopenrectangle WHITE SQUARE */
{ 0x0acf, 0x25af }, /* emopenrectangle WHITE VERTICAL RECTANGLE */
{ 0x0ad0, 0x2018 }, /* leftsinglequotemark LEFT SINGLE QUOTATION MARK */
{ 0x0ad1, 0x2019 }, /* rightsinglequotemark RIGHT SINGLE QUOTATION MARK */
{ 0x0ad2, 0x201c }, /* leftdoublequotemark “ LEFT DOUBLE QUOTATION MARK */
{ 0x0ad3, 0x201d }, /* rightdoublequotemark ” RIGHT DOUBLE QUOTATION MARK */
{ 0x0ad4, 0x211e }, /* prescription ℞ PRESCRIPTION TAKE */
{ 0x0ad5, 0x2030 }, /* permille ‰ PER MILLE SIGN */
{ 0x0ad6, 0x2032 }, /* minutes PRIME */
{ 0x0ad7, 0x2033 }, /* seconds ″ DOUBLE PRIME */
{ 0x0ad9, 0x271d }, /* latincross ✝ LATIN CROSS */
@@ -560,7 +561,7 @@ static const struct {
{ 0x0adc, 0x25c0 }, /* filledlefttribullet ◀ BLACK LEFT-POINTING TRIANGLE */
{ 0x0add, 0x25b6 }, /* filledrighttribullet ▶ BLACK RIGHT-POINTING TRIANGLE */
{ 0x0ade, 0x25cf }, /* emfilledcircle ● BLACK CIRCLE */
{ 0x0adf, 0x25a0 }, /* emfilledrect BLACK SQUARE */
{ 0x0adf, 0x25ae }, /* emfilledrect BLACK VERTICAL RECTANGLE */
{ 0x0ae0, 0x25e6 }, /* enopencircbullet ◦ WHITE BULLET */
{ 0x0ae1, 0x25ab }, /* enopensquarebullet ▫ WHITE SMALL SQUARE */
{ 0x0ae2, 0x25ad }, /* openrectbullet ▭ WHITE RECTANGLE */
@@ -805,15 +806,16 @@ static const struct {
{ 0x0ef0, 0x3171 }, /* Hangul_SunkyeongeumMieum ㅱ HANGUL LETTER KAPYEOUNMIEUM */
{ 0x0ef1, 0x3178 }, /* Hangul_SunkyeongeumPieub ㅸ HANGUL LETTER KAPYEOUNPIEUP */
{ 0x0ef2, 0x317f }, /* Hangul_PanSios ㅿ HANGUL LETTER PANSIOS */
/* 0x0ef3 Hangul_KkogjiDalrinIeung ? ??? */
{ 0x0ef3, 0x3181 }, /* Hangul_KkogjiDalrinIeung ㆁ HANGUL LETTER YESIEUNG */
{ 0x0ef4, 0x3184 }, /* Hangul_SunkyeongeumPhieuf ㆄ HANGUL LETTER KAPYEOUNPHIEUPH */
{ 0x0ef5, 0x3186 }, /* Hangul_YeorinHieuh ㆆ HANGUL LETTER YEORINHIEUH */
{ 0x0ef6, 0x318d }, /* Hangul_AraeA ㆍ HANGUL LETTER ARAEA */
{ 0x0ef7, 0x318e }, /* Hangul_AraeAE ㆎ HANGUL LETTER ARAEAE */
{ 0x0ef8, 0x11eb }, /* Hangul_J_PanSios ᇫ HANGUL JONGSEONG PANSIOS */
/* 0x0ef9 Hangul_J_KkogjiDalrinIeung ? ??? */
{ 0x0ef9, 0x11f0 }, /* Hangul_J_KkogjiDalrinIeung ᇰ HANGUL JONGSEONG YESIEUNG */
{ 0x0efa, 0x11f9 }, /* Hangul_J_YeorinHieuh ᇹ HANGUL JONGSEONG YEORINHIEUH */
{ 0x0eff, 0x20a9 }, /* Korean_Won ₩ WON SIGN */
{ 0x13a4, 0x20ac }, /* Euro € EURO SIGN */
{ 0x13bc, 0x0152 }, /* OE Œ LATIN CAPITAL LIGATURE OE */
{ 0x13bd, 0x0153 }, /* oe œ LATIN SMALL LIGATURE OE */
{ 0x13be, 0x0178 }, /* Ydiaeresis Ÿ LATIN CAPITAL LETTER Y WITH DIAERESIS */
@@ -835,18 +837,13 @@ static const struct {
/* Following items added to GTK, not in the xterm table */
/* A few ASCII control characters */
#ifndef GDK_WINDOWING_WIN32
{ 0xFF08 /* Backspace */, '\b' },
{ 0xFF09 /* Tab */, '\t' },
#endif
{ 0xFF0A /* Linefeed */, '\n' },
{ 0xFF0B /* Vert. Tab */, '\v' },
#ifndef GDK_WINDOWING_WIN32
{ 0xFF0D /* Return */, '\r' },
{ 0xFF1B /* Escape */, '\033' },
#endif
/* Numeric keypad */
@@ -871,9 +868,7 @@ static const struct {
/* End numeric keypad */
#ifndef GDK_WINDOWING_WIN32
{ 0xFFFF /* Delete */, '\177' }
#endif
};
/**
@@ -1084,7 +1079,7 @@ static const struct {
{ 0x07d7, 0x03a7 }, /* Greek_CHI Χ GREEK CAPITAL LETTER CHI */
{ 0x07d8, 0x03a8 }, /* Greek_PSI Ψ GREEK CAPITAL LETTER PSI */
{ 0x07d9, 0x03a9 }, /* Greek_OMEGA Ω GREEK CAPITAL LETTER OMEGA */
{ 0x07a5, 0x03aa }, /* Greek_IOTAdieresis Ϊ GREEK CAPITAL LETTER IOTA WITH DIALYTIKA */
{ 0x07a5, 0x03aa }, /* Greek_IOTAdiaeresis Ϊ GREEK CAPITAL LETTER IOTA WITH DIALYTIKA */
{ 0x07a9, 0x03ab }, /* Greek_UPSILONdieresis Ϋ GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA */
{ 0x07b1, 0x03ac }, /* Greek_alphaaccent ά GREEK SMALL LETTER ALPHA WITH TONOS */
{ 0x07b2, 0x03ad }, /* Greek_epsilonaccent έ GREEK SMALL LETTER EPSILON WITH TONOS */
@@ -1399,6 +1394,7 @@ static const struct {
{ 0x0eed, 0x11c1 }, /* Hangul_J_Phieuf ᇁ HANGUL JONGSEONG PHIEUPH */
{ 0x0eee, 0x11c2 }, /* Hangul_J_Hieuh ᇂ HANGUL JONGSEONG HIEUH */
{ 0x0ef8, 0x11eb }, /* Hangul_J_PanSios ᇫ HANGUL JONGSEONG PANSIOS */
{ 0x0ef9, 0x11f0 }, /* Hangul_J_KkogjiDalrinIeung ᇰ HANGUL JONGSEONG YESIEUNG */
{ 0x0efa, 0x11f9 }, /* Hangul_J_YeorinHieuh ᇹ HANGUL JONGSEONG YEORINHIEUH */
{ 0x0aa2, 0x2002 }, /* enspace EN SPACE */
{ 0x0aa1, 0x2003 }, /* emspace EM SPACE */
@@ -1422,7 +1418,9 @@ static const struct {
{ 0x0af1, 0x2020 }, /* dagger † DAGGER */
{ 0x0af2, 0x2021 }, /* doubledagger ‡ DOUBLE DAGGER */
{ 0x0ae6, 0x2022 }, /* enfilledcircbullet • BULLET */
{ 0x0aaf, 0x2025 }, /* doubbaselinedot ‥ TWO DOT LEADER */
{ 0x0aae, 0x2026 }, /* ellipsis … HORIZONTAL ELLIPSIS */
{ 0x0ad5, 0x2030 }, /* permille ‰ PER MILLE SIGN */
{ 0x0ad6, 0x2032 }, /* minutes PRIME */
{ 0x0ad7, 0x2033 }, /* seconds ″ DOUBLE PRIME */
{ 0x0afc, 0x2038 }, /* caret ‸ CARET */
@@ -1480,7 +1478,8 @@ static const struct {
{ 0x0bd6, 0x222a }, /* downshoe UNION */
{ 0x08bf, 0x222b }, /* integral ∫ INTEGRAL */
{ 0x08c0, 0x2234 }, /* therefore ∴ THEREFORE */
{ 0x08c8, 0x2245 }, /* approximate ≅ APPROXIMATELY EQUAL TO */
{ 0x08c8, 0x223c }, /* approximate TILDE OPERATOR */
{ 0x08c9, 0x2243 }, /* similarequal ≃ ASYMPTOTICALLY EQUAL TO */
{ 0x08bd, 0x2260 }, /* notequal ≠ NOT EQUAL TO */
{ 0x08cf, 0x2261 }, /* identical ≡ IDENTICAL TO */
{ 0x08bc, 0x2264 }, /* lessthanequal ≤ LESS-THAN OR EQUAL TO */
@@ -1498,15 +1497,28 @@ static const struct {
{ 0x0afa, 0x2315 }, /* telephonerecorder ⌕ TELEPHONE RECORDER */
{ 0x08a4, 0x2320 }, /* topintegral ⌠ TOP HALF INTEGRAL */
{ 0x08a5, 0x2321 }, /* botintegral ⌡ BOTTOM HALF INTEGRAL */
{ 0x0abc, 0x2329 }, /* leftanglebracket 〈 LEFT-POINTING ANGLE BRACKET */
{ 0x0abe, 0x232a }, /* rightanglebracket 〉 RIGHT-POINTING ANGLE BRACKET */
{ 0x0bcc, 0x2395 }, /* quad ⎕ APL FUNCTIONAL SYMBOL QUAD (Unicode 3.0) */
{ 0x08a7, 0x23a1 }, /* topleftsqbracket ⎡ ??? */
{ 0x08a8, 0x23a3 }, /* botleftsqbracket ⎣ ??? */
{ 0x08a9, 0x23a4 }, /* toprightsqbracket ⎤ ??? */
{ 0x08aa, 0x23a6 }, /* botrightsqbracket ⎦ ??? */
{ 0x08ab, 0x239b }, /* topleftparens ⎛ ??? */
{ 0x08ac, 0x239d }, /* botleftparens ⎝ ??? */
{ 0x08ad, 0x239e }, /* toprightparens ⎞ ??? */
{ 0x08ae, 0x23a0 }, /* botrightparens ⎠ ??? */
{ 0x08af, 0x23a8 }, /* leftmiddlecurlybrace ⎨ ??? */
{ 0x08b0, 0x23ac }, /* rightmiddlecurlybrace ⎬ ??? */
{ 0x08a1, 0x23b7 }, /* leftradical ⎷ ??? */
{ 0x09ef, 0x23ba }, /* horizlinescan1 ⎺ HORIZONTAL SCAN LINE-1 (Unicode 3.2 draft) */
{ 0x09f0, 0x23bb }, /* horizlinescan3 ⎻ HORIZONTAL SCAN LINE-3 (Unicode 3.2 draft) */
{ 0x09f2, 0x23bc }, /* horizlinescan7 ⎼ HORIZONTAL SCAN LINE-7 (Unicode 3.2 draft) */
{ 0x09f3, 0x23bd }, /* horizlinescan9 ⎽ HORIZONTAL SCAN LINE-9 (Unicode 3.2 draft) */
{ 0x09e2, 0x2409 }, /* ht ␉ SYMBOL FOR HORIZONTAL TABULATION */
{ 0x09e5, 0x240a }, /* lf ␊ SYMBOL FOR LINE FEED */
{ 0x09e9, 0x240b }, /* vt ␋ SYMBOL FOR VERTICAL TABULATION */
{ 0x09e3, 0x240c }, /* ff ␌ SYMBOL FOR FORM FEED */
{ 0x09e4, 0x240d }, /* cr ␍ SYMBOL FOR CARRIAGE RETURN */
{ 0x09df, 0x2422 }, /* blank ␢ BLANK SYMBOL */
{ 0x0aac, 0x2423 }, /* signifblank ␣ OPEN BOX */
{ 0x09e8, 0x2424 }, /* nl ␤ SYMBOL FOR NEWLINE */
{ 0x09f1, 0x2500 }, /* horizlinescan5 ─ BOX DRAWINGS LIGHT HORIZONTAL */
{ 0x08a6, 0x2502 }, /* vertconnector │ BOX DRAWINGS LIGHT VERTICAL */
@@ -1522,11 +1534,11 @@ static const struct {
{ 0x09ee, 0x253c }, /* crossinglines ┼ BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL */
{ 0x09e1, 0x2592 }, /* checkerboard ▒ MEDIUM SHADE */
{ 0x0adf, 0x25a0 }, /* emfilledrect ■ BLACK SQUARE */
{ 0x0acf, 0x25a1 }, /* emopenrectangle □ WHITE SQUARE */
{ 0x0ae7, 0x25aa }, /* enfilledsqbullet ▪ BLACK SMALL SQUARE */
{ 0x0ae1, 0x25ab }, /* enopensquarebullet ▫ WHITE SMALL SQUARE */
{ 0x0adb, 0x25ac }, /* filledrectbullet ▬ BLACK RECTANGLE */
{ 0x0ae2, 0x25ad }, /* openrectbullet ▭ WHITE RECTANGLE */
{ 0x0acf, 0x25af }, /* emopenrectangle ▯ WHITE VERTICAL RECTANGLE */
{ 0x0ae8, 0x25b2 }, /* filledtribulletup ▲ BLACK UP-POINTING TRIANGLE */
{ 0x0ae3, 0x25b3 }, /* opentribulletup △ WHITE UP-POINTING TRIANGLE */
{ 0x0add, 0x25b6 }, /* filledrighttribullet ▶ BLACK RIGHT-POINTING TRIANGLE */
@@ -1556,6 +1568,8 @@ static const struct {
{ 0x0af4, 0x2717 }, /* ballotcross ✗ BALLOT X */
{ 0x0ad9, 0x271d }, /* latincross ✝ LATIN CROSS */
{ 0x0af0, 0x2720 }, /* maltesecross ✠ MALTESE CROSS */
{ 0x0abc, 0x27e8 }, /* leftanglebracket ⟨ MATHEMATICAL LEFT ANGLE BRACKET */
{ 0x0abe, 0x27e9 }, /* rightanglebracket ⟩ MATHEMATICAL RIGHT ANGLE BRACKET */
{ 0x04a4, 0x3001 }, /* kana_comma 、 IDEOGRAPHIC COMMA */
{ 0x04a1, 0x3002 }, /* kana_fullstop 。 IDEOGRAPHIC FULL STOP */
{ 0x04a2, 0x300c }, /* kana_openingbracket 「 LEFT CORNER BRACKET */
@@ -1674,6 +1688,7 @@ static const struct {
{ 0x0ef0, 0x3171 }, /* Hangul_SunkyeongeumMieum ㅱ HANGUL LETTER KAPYEOUNMIEUM */
{ 0x0ef1, 0x3178 }, /* Hangul_SunkyeongeumPieub ㅸ HANGUL LETTER KAPYEOUNPIEUP */
{ 0x0ef2, 0x317f }, /* Hangul_PanSios ㅿ HANGUL LETTER PANSIOS */
{ 0x0ef3, 0x3181 }, /* Hangul_KkogjiDalrinIeung ㆁ HANGUL LETTER YESIEUNG */
{ 0x0ef4, 0x3184 }, /* Hangul_SunkyeongeumPhieuf ㆄ HANGUL LETTER KAPYEOUNPHIEUPH */
{ 0x0ef5, 0x3186 }, /* Hangul_YeorinHieuh ㆆ HANGUL LETTER YEORINHIEUH */
{ 0x0ef6, 0x318d }, /* Hangul_AraeA ㆍ HANGUL LETTER ARAEA */

View File

@@ -166,6 +166,54 @@ r32g32b32a32_float_from_float (guchar *dest,
memcpy (dest, src, sizeof (float) * n * 4);
}
#define PREMULTIPLY_FUNC(name, R1, G1, B1, A1, R2, G2, B2, A2) \
static void \
name (guchar *dest, \
const guchar *src, \
gsize n) \
{ \
for (; n > 0; n--) \
{ \
guchar a = src[A1]; \
guint16 r = (guint16)src[R1] * a + 127; \
guint16 g = (guint16)src[G1] * a + 127; \
guint16 b = (guint16)src[B1] * a + 127; \
dest[R2] = (r + (r >> 8) + 1) >> 8; \
dest[G2] = (g + (g >> 8) + 1) >> 8; \
dest[B2] = (b + (b >> 8) + 1) >> 8; \
dest[A2] = a; \
dest += 4; \
src += 4; \
} \
}
PREMULTIPLY_FUNC(r8g8b8a8_to_r8g8b8a8_premultiplied, 0, 1, 2, 3, 0, 1, 2, 3)
PREMULTIPLY_FUNC(r8g8b8a8_to_b8g8r8a8_premultiplied, 0, 1, 2, 3, 2, 1, 0, 3)
PREMULTIPLY_FUNC(r8g8b8a8_to_a8r8g8b8_premultiplied, 0, 1, 2, 3, 1, 2, 3, 0)
PREMULTIPLY_FUNC(r8g8b8a8_to_a8b8g8r8_premultiplied, 0, 1, 2, 3, 3, 2, 1, 0)
#define ADD_ALPHA_FUNC(name, R1, G1, B1, R2, G2, B2, A2) \
static void \
name (guchar *dest, \
const guchar *src, \
gsize n) \
{ \
for (; n > 0; n--) \
{ \
dest[R2] = src[R1]; \
dest[G2] = src[G1]; \
dest[B2] = src[B1]; \
dest[A2] = 255; \
dest += 4; \
src += 3; \
} \
}
ADD_ALPHA_FUNC(r8g8b8_to_r8g8b8a8, 0, 1, 2, 0, 1, 2, 3)
ADD_ALPHA_FUNC(r8g8b8_to_b8g8r8a8, 0, 1, 2, 2, 1, 0, 3)
ADD_ALPHA_FUNC(r8g8b8_to_a8r8g8b8, 0, 1, 2, 1, 2, 3, 0)
ADD_ALPHA_FUNC(r8g8b8_to_a8b8g8r8, 0, 1, 2, 3, 2, 1, 0)
struct _GdkMemoryFormatDescription
{
GdkMemoryAlpha alpha;
@@ -475,10 +523,59 @@ gdk_memory_convert (guchar *dest_data,
const GdkMemoryFormatDescription *src_desc = &memory_formats[src_format];
float *tmp;
gsize y;
void (*func) (guchar *, const guchar *, gsize) = NULL;
g_assert (dest_format < GDK_MEMORY_N_FORMATS);
g_assert (src_format < GDK_MEMORY_N_FORMATS);
if (src_format == GDK_MEMORY_R8G8B8A8 && dest_format == GDK_MEMORY_R8G8B8A8_PREMULTIPLIED)
func = r8g8b8a8_to_r8g8b8a8_premultiplied;
else if (src_format == GDK_MEMORY_B8G8R8A8 && dest_format == GDK_MEMORY_R8G8B8A8_PREMULTIPLIED)
func = r8g8b8a8_to_b8g8r8a8_premultiplied;
else if (src_format == GDK_MEMORY_R8G8B8A8 && dest_format == GDK_MEMORY_B8G8R8A8_PREMULTIPLIED)
func = r8g8b8a8_to_b8g8r8a8_premultiplied;
else if (src_format == GDK_MEMORY_B8G8R8A8 && dest_format == GDK_MEMORY_B8G8R8A8_PREMULTIPLIED)
func = r8g8b8a8_to_r8g8b8a8_premultiplied;
else if (src_format == GDK_MEMORY_R8G8B8A8 && dest_format == GDK_MEMORY_A8R8G8B8_PREMULTIPLIED)
func = r8g8b8a8_to_a8r8g8b8_premultiplied;
else if (src_format == GDK_MEMORY_B8G8R8A8 && dest_format == GDK_MEMORY_A8R8G8B8_PREMULTIPLIED)
func = r8g8b8a8_to_a8b8g8r8_premultiplied;
else if (src_format == GDK_MEMORY_R8G8B8 && dest_format == GDK_MEMORY_R8G8B8A8_PREMULTIPLIED)
func = r8g8b8_to_r8g8b8a8;
else if (src_format == GDK_MEMORY_B8G8R8 && dest_format == GDK_MEMORY_R8G8B8A8_PREMULTIPLIED)
func = r8g8b8_to_b8g8r8a8;
else if (src_format == GDK_MEMORY_R8G8B8 && dest_format == GDK_MEMORY_B8G8R8A8_PREMULTIPLIED)
func = r8g8b8_to_b8g8r8a8;
else if (src_format == GDK_MEMORY_B8G8R8 && dest_format == GDK_MEMORY_B8G8R8A8_PREMULTIPLIED)
func = r8g8b8_to_r8g8b8a8;
else if (src_format == GDK_MEMORY_R8G8B8 && dest_format == GDK_MEMORY_A8R8G8B8_PREMULTIPLIED)
func = r8g8b8_to_a8r8g8b8;
else if (src_format == GDK_MEMORY_B8G8R8 && dest_format == GDK_MEMORY_A8R8G8B8_PREMULTIPLIED)
func = r8g8b8_to_a8b8g8r8;
else if (src_format == GDK_MEMORY_R8G8B8 && dest_format == GDK_MEMORY_R8G8B8A8)
func = r8g8b8_to_r8g8b8a8;
else if (src_format == GDK_MEMORY_B8G8R8 && dest_format == GDK_MEMORY_R8G8B8A8)
func = r8g8b8_to_b8g8r8a8;
else if (src_format == GDK_MEMORY_R8G8B8 && dest_format == GDK_MEMORY_B8G8R8A8)
func = r8g8b8_to_b8g8r8a8;
else if (src_format == GDK_MEMORY_B8G8R8 && dest_format == GDK_MEMORY_B8G8R8A8)
func = r8g8b8_to_r8g8b8a8;
else if (src_format == GDK_MEMORY_R8G8B8 && dest_format == GDK_MEMORY_A8R8G8B8)
func = r8g8b8_to_a8r8g8b8;
else if (src_format == GDK_MEMORY_B8G8R8 && dest_format == GDK_MEMORY_A8R8G8B8)
func = r8g8b8_to_a8b8g8r8;
if (func != NULL)
{
for (y = 0; y < height; y++)
{
func (dest_data, src_data, width);
src_data += src_stride;
dest_data += dest_stride;
}
return;
}
tmp = g_new (float, width * 4);
for (y = 0; y < height; y++)

View File

@@ -133,10 +133,10 @@ gdk_memory_sanitize (GBytes *bytes,
*
* Creates a new texture for a blob of image data.
*
* The `GBytes` must contain @stride x @height pixels
* The `GBytes` must contain @stride × @height pixels
* in the given format.
*
* Returns: A newly-created `GdkTexture`
* Returns: (type GdkMemoryTexture): A newly-created `GdkTexture`
*/
GdkTexture *
gdk_memory_texture_new (int width,

View File

@@ -1,5 +1,5 @@
/* GDK - The GIMP Drawing Kit
* Copyright (C) 2000 Red Hat, Inc.
* Copyright (C) 2000 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
@@ -52,25 +52,25 @@ layout_iter_get_line_clip_region (PangoLayoutIter *iter,
i = 0;
while (i < n_ranges)
{
{
int *pixel_ranges = NULL;
int n_pixel_ranges = 0;
int j;
/* Note that get_x_ranges returns layout coordinates
*/
if (index_ranges[i*2+1] >= line->start_index &&
index_ranges[i*2] < line->start_index + line->length)
if (index_ranges[i*2+1] >= pango_layout_line_get_start_index (line) &&
index_ranges[i*2] < pango_layout_line_get_start_index (line) + pango_layout_line_get_length (line))
pango_layout_line_get_x_ranges (line,
index_ranges[i*2],
index_ranges[i*2+1],
&pixel_ranges, &n_pixel_ranges);
for (j = 0; j < n_pixel_ranges; j++)
{
GdkRectangle rect;
int x_off, y_off;
x_off = PANGO_PIXELS (pixel_ranges[2*j] - logical_rect.x);
y_off = PANGO_PIXELS (baseline - logical_rect.y);
@@ -124,14 +124,14 @@ gdk_pango_layout_line_get_clip_region (PangoLayoutLine *line,
{
cairo_region_t *clip_region;
PangoLayoutIter *iter;
g_return_val_if_fail (line != NULL, NULL);
g_return_val_if_fail (index_ranges != NULL, NULL);
iter = pango_layout_get_iter (line->layout);
while (pango_layout_iter_get_line_readonly (iter) != line)
pango_layout_iter_next_line (iter);
clip_region = layout_iter_get_line_clip_region(iter, x_origin, y_origin, index_ranges, n_ranges);
pango_layout_iter_free (iter);
@@ -167,26 +167,26 @@ gdk_pango_layout_get_clip_region (PangoLayout *layout,
const int *index_ranges,
int n_ranges)
{
PangoLayoutIter *iter;
PangoLayoutIter *iter;
cairo_region_t *clip_region;
g_return_val_if_fail (PANGO_IS_LAYOUT (layout), NULL);
g_return_val_if_fail (index_ranges != NULL, NULL);
clip_region = cairo_region_create ();
iter = pango_layout_get_iter (layout);
do
{
PangoRectangle logical_rect;
cairo_region_t *line_region;
int baseline;
pango_layout_iter_get_line_extents (iter, NULL, &logical_rect);
baseline = pango_layout_iter_get_baseline (iter);
line_region = layout_iter_get_line_clip_region(iter,
pango_layout_iter_get_line_extents (iter, NULL, &logical_rect);
baseline = pango_layout_iter_get_baseline (iter);
line_region = layout_iter_get_line_clip_region(iter,
x_origin + PANGO_PIXELS (logical_rect.x),
y_origin + PANGO_PIXELS (baseline),
index_ranges,

View File

@@ -187,7 +187,7 @@ gdk_popup_get_rect_anchor (GdkPopup *popup)
*
* Returns the parent surface of a popup.
*
* Returns: (transfer none): the parent surface
* Returns: (transfer none) (nullable): the parent surface
*/
GdkSurface *
gdk_popup_get_parent (GdkPopup *popup)

View File

@@ -33,7 +33,7 @@
((_GDK_RGBA_SELECT_COLOR(str, 0, 0) << 4) | _GDK_RGBA_SELECT_COLOR(str, 0, 1)) / 255., \
((_GDK_RGBA_SELECT_COLOR(str, 1, 2) << 4) | _GDK_RGBA_SELECT_COLOR(str, 1, 3)) / 255., \
((_GDK_RGBA_SELECT_COLOR(str, 2, 4) << 4) | _GDK_RGBA_SELECT_COLOR(str, 2, 5)) / 255., \
((sizeof(str) % 4 == 1) ? ((_GDK_RGBA_SELECT_COLOR(str, 3, 6) << 4) | _GDK_RGBA_SELECT_COLOR(str, 3, 7)) : 0xFF) / 255 })
((sizeof(str) % 4 == 1) ? ((_GDK_RGBA_SELECT_COLOR(str, 3, 6) << 4) | _GDK_RGBA_SELECT_COLOR(str, 3, 7)) : 0xFF) / 255. })
gboolean gdk_rgba_parser_parse (GtkCssParser *parser,

View File

@@ -1095,6 +1095,7 @@ gdk_surface_set_egl_native_window (GdkSurface *self,
if (priv->egl_surface != NULL)
{
gdk_gl_context_clear_current_if_surface (self);
eglDestroySurface (gdk_surface_get_display (self), priv->egl_surface);
priv->egl_surface = NULL;
}
@@ -1123,7 +1124,8 @@ gdk_surface_ensure_egl_surface (GdkSurface *self,
priv->egl_surface != NULL &&
gdk_display_get_egl_config_high_depth (display) != gdk_display_get_egl_config (display))
{
eglDestroySurface (gdk_surface_get_display (self), priv->egl_surface);
gdk_gl_context_clear_current_if_surface (self);
eglDestroySurface (gdk_display_get_egl_display (display), priv->egl_surface);
priv->egl_surface = NULL;
}
@@ -2242,7 +2244,7 @@ _gdk_windowing_got_event (GdkDisplay *display,
GdkEvent *event,
gulong serial)
{
GdkSurface *event_surface;
GdkSurface *event_surface = NULL;
gboolean unlink_event = FALSE;
GdkDeviceGrabInfo *button_release_grab;
GdkPointerSurfaceInfo *pointer_info = NULL;
@@ -2334,6 +2336,14 @@ _gdk_windowing_got_event (GdkDisplay *display,
*/
_gdk_event_queue_handle_motion_compression (display);
gdk_event_queue_handle_scroll_compression (display);
if (event_surface)
{
GdkFrameClock *clock = gdk_surface_get_frame_clock (event_surface);
if (clock) /* might be NULL if surface was destroyed */
gdk_frame_clock_request_phase (clock, GDK_FRAME_CLOCK_PHASE_FLUSH_EVENTS);
}
}
/**

View File

@@ -25,14 +25,14 @@
* multiple frames, and will be used for a long time.
*
* There are various ways to create `GdkTexture` objects from a
* `GdkPixbuf`, or a Cairo surface, or other pixel data.
* [class@GdkPixbuf.Pixbuf], or a Cairo surface, or other pixel data.
*
* The ownership of the pixel data is transferred to the `GdkTexture`
* instance; you can only make a copy of it, via [method@Gdk.Texture.download].
*
* `GdkTexture` is an immutable object: That means you cannot change
* anything about it other than increasing the reference count via
* g_object_ref().
* [method@GObject.Object.ref], and consequently, it is a thread-safe object.
*/
#include "config.h"
@@ -346,7 +346,7 @@ gdk_texture_init (GdkTexture *self)
*
* Creates a new texture object representing the surface.
*
* @surface must be an image surface with format CAIRO_FORMAT_ARGB32.
* @surface must be an image surface with format `CAIRO_FORMAT_ARGB32`.
*
* Returns: a new `GdkTexture`
*/
@@ -384,7 +384,7 @@ gdk_texture_new_for_surface (cairo_surface_t *surface)
* Creates a new texture object representing the `GdkPixbuf`.
*
* This function is threadsafe, so that you can e.g. use GTask
* and g_task_run_in_thread() to avoid blocking the main thread
* and [method@Gio.Task.run_in_thread] to avoid blocking the main thread
* while loading a big image.
*
* Returns: a new `GdkTexture`
@@ -430,7 +430,7 @@ gdk_texture_new_for_pixbuf (GdkPixbuf *pixbuf)
* [ctor@Gdk.Texture.new_from_file] to load it.
*
* This function is threadsafe, so that you can e.g. use GTask
* and g_task_run_in_thread() to avoid blocking the main thread
* and [method@Gio.Task.run_in_thread] to avoid blocking the main thread
* while loading a big image.
*
* Return value: A newly-created `GdkTexture`
@@ -454,7 +454,7 @@ gdk_texture_new_from_resource (const char *resource_path)
texture = NULL;
if (texture == NULL)
g_error ("Resource path %s s not a valid image: %s", resource_path, error->message);
g_error ("Resource path %s is not a valid image: %s", resource_path, error->message);
return texture;
}
@@ -472,7 +472,7 @@ gdk_texture_new_from_resource (const char *resource_path)
* If %NULL is returned, then @error will be set.
*
* This function is threadsafe, so that you can e.g. use GTask
* and g_task_run_in_thread() to avoid blocking the main thread
* and [method@Gio.Task.run_in_thread] to avoid blocking the main thread
* while loading a big image.
*
* Return value: A newly-created `GdkTexture`
@@ -565,7 +565,7 @@ gdk_texture_new_from_bytes_pixbuf (GBytes *bytes,
* If %NULL is returned, then @error will be set.
*
* This function is threadsafe, so that you can e.g. use GTask
* and g_task_run_in_thread() to avoid blocking the main thread
* and [method@Gio.Task.run_in_thread] to avoid blocking the main thread
* while loading a big image.
*
* Return value: A newly-created `GdkTexture`
@@ -611,7 +611,7 @@ gdk_texture_new_from_bytes (GBytes *bytes,
* If %NULL is returned, then @error will be set.
*
* This function is threadsafe, so that you can e.g. use GTask
* and g_task_run_in_thread() to avoid blocking the main thread
* and [method@Gio.Task.run_in_thread] to avoid blocking the main thread
* while loading a big image.
*
* Return value: A newly-created `GdkTexture`
@@ -796,7 +796,7 @@ gdk_texture_get_render_data (GdkTexture *self,
*
* This is a utility function intended for debugging and testing.
* If you want more control over formats, proper error handling or
* want to store to a `GFile` or other location, you might want to
* want to store to a [iface@Gio.File] or other location, you might want to
* use [method@Gdk.Texture.save_to_png_bytes] or look into the
* gdk-pixbuf library.
*

View File

@@ -83,6 +83,8 @@
*
* A macro that evaluates to the 4.2 version of GDK, in a format
* that can be used by the C pre-processor.
*
* Since: 4.2
*/
#define GDK_VERSION_4_2 (G_ENCODE_VERSION (4, 2))
@@ -91,6 +93,8 @@
*
* A macro that evaluates to the 4.4 version of GDK, in a format
* that can be used by the C pre-processor.
*
* Since: 4.4
*/
#define GDK_VERSION_4_4 (G_ENCODE_VERSION (4, 4))
@@ -99,9 +103,21 @@
*
* A macro that evaluates to the 4.6 version of GDK, in a format
* that can be used by the C pre-processor.
*
* Since: 4.6
*/
#define GDK_VERSION_4_6 (G_ENCODE_VERSION (4, 6))
/**
* GDK_VERSION_4_8:
*
* A macro that evaluates to the 4.8 version of GDK, in a format
* that can be used by the C pre-processor.
*
* Since: 4.8
*/
#define GDK_VERSION_4_8 (G_ENCODE_VERSION (4, 8))
/* evaluates to the current stable version; for development cycles,
* this means the next stable target, with a hard backstop to the
@@ -243,4 +259,18 @@
# define GDK_DEPRECATED_IN_4_6_FOR(f) _GDK_EXTERN
#endif
#if GDK_VERSION_MAX_ALLOWED < GDK_VERSION_4_8
# define GDK_AVAILABLE_IN_4_8 GDK_UNAVAILABLE(4, 8)
#else
# define GDK_AVAILABLE_IN_4_8 _GDK_EXTERN
#endif
#if GDK_VERSION_MIN_REQUIRED >= GDK_VERSION_4_8
# define GDK_DEPRECATED_IN_4_8 GDK_DEPRECATED
# define GDK_DEPRECATED_IN_4_8_FOR(f) GDK_DEPRECATED_FOR(f)
#else
# define GDK_DEPRECATED_IN_4_8 _GDK_EXTERN
# define GDK_DEPRECATED_IN_4_8_FOR(f) _GDK_EXTERN
#endif
#endif /* __GDK_VERSION_MACROS_H__ */

View File

@@ -15,6 +15,8 @@
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include "config.h"
#include "gdkjpegprivate.h"

View File

@@ -222,11 +222,7 @@ gdk_load_png (GBytes *bytes,
case PNG_COLOR_TYPE_RGB_ALPHA:
if (depth == 8)
{
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
format = GDK_MEMORY_R8G8B8A8;
#elif G_BYTE_ORDER == G_BIG_ENDIAN
format = GDK_MEMORY_A8B8G8R8;
#endif
}
else
{
@@ -236,11 +232,7 @@ gdk_load_png (GBytes *bytes,
case PNG_COLOR_TYPE_RGB:
if (depth == 8)
{
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
format = GDK_MEMORY_R8G8B8;
#elif G_BYTE_ORDER == G_BIG_ENDIAN
format = GDK_MEMORY_B8G8R8;
#endif
}
else if (depth == 16)
{
@@ -325,22 +317,14 @@ gdk_save_png (GdkTexture *texture)
case GDK_MEMORY_A8R8G8B8:
case GDK_MEMORY_R8G8B8A8:
case GDK_MEMORY_A8B8G8R8:
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
format = GDK_MEMORY_R8G8B8A8;
#elif G_BYTE_ORDER == G_BIG_ENDIAN
format = GDK_MEMORY_A8B8G8R8;
#endif
png_format = PNG_COLOR_TYPE_RGB_ALPHA;
depth = 8;
break;
case GDK_MEMORY_R8G8B8:
case GDK_MEMORY_B8G8R8:
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
format = GDK_MEMORY_R8G8B8;
#elif G_BYTE_ORDER == G_BIG_ENDIAN
format = GDK_MEMORY_B8G8R8;
#endif
png_format = PNG_COLOR_TYPE_RGB;
depth = 8;
break;

View File

@@ -45,7 +45,6 @@
options = (NSTrackingMouseEnteredAndExited |
NSTrackingMouseMoved |
NSTrackingInVisibleRect |
NSTrackingActiveAlways);
trackingArea = [[NSTrackingArea alloc] initWithRect:rect
options:options
@@ -57,9 +56,26 @@
return self;
}
-(void)setInputArea:(const cairo_rectangle_int_t *)area
{
NSRect rect = NSMakeRect (area->x, area->y, area->width, area->height);
NSTrackingAreaOptions options;
[self removeTrackingArea:trackingArea];
options = (NSTrackingMouseEnteredAndExited |
NSTrackingMouseMoved |
NSTrackingActiveAlways);
trackingArea = [[NSTrackingArea alloc] initWithRect:rect
options:options
owner:(id)self
userInfo:nil];
[self addTrackingArea:trackingArea];
}
-(void)setOpaqueRegion:(cairo_region_t *)region
{
/* Do nothing */
/* Handled in Subclass */
}
-(BOOL)acceptsFirstMouse

View File

@@ -42,5 +42,6 @@
-(void)setNeedsInvalidateShadow: (BOOL)invalidate;
-(NSTrackingArea *)trackingArea;
-(void)setOpaqueRegion:(cairo_region_t *)region;
-(void)setInputArea:(const cairo_rectangle_int_t *)area;
@end

View File

@@ -1,201 +0,0 @@
/* GdkMacosCairoSubview.c
*
* Copyright © 2020 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/>.
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*/
#include "config.h"
#include <CoreGraphics/CoreGraphics.h>
#include <cairo-quartz.h>
#import "GdkMacosCairoSubview.h"
#import "GdkMacosCairoView.h"
#include "gdkmacossurface-private.h"
@implementation GdkMacosCairoSubview
-(void)dealloc
{
g_clear_pointer (&self->clip, cairo_region_destroy);
[super dealloc];
}
-(BOOL)isOpaque
{
return _isOpaque;
}
-(BOOL)isFlipped
{
return YES;
}
-(GdkSurface *)gdkSurface
{
return GDK_SURFACE ([(GdkMacosBaseView *)[self superview] gdkSurface]);
}
-(void)drawRect:(NSRect)rect
{
CGContextRef cgContext;
GdkSurface *gdk_surface;
cairo_surface_t *dest;
const NSRect *rects = NULL;
NSView *root_view;
NSInteger n_rects = 0;
NSRect abs_bounds;
cairo_t *cr;
CGSize scale;
int scale_factor;
if (self->cairoSurface == NULL)
return;
/* Acquire everything we need to do translations, drawing, etc */
gdk_surface = [self gdkSurface];
scale_factor = gdk_surface_get_scale_factor (gdk_surface);
root_view = [[self window] contentView];
cgContext = [[NSGraphicsContext currentContext] CGContext];
abs_bounds = [self convertRect:[self bounds] toView:root_view];
CGContextSaveGState (cgContext);
/* Translate scaling to remove HiDPI scaling from CGContext as
* cairo will be doing that for us already.
*/
scale = CGSizeMake (1.0, 1.0);
scale = CGContextConvertSizeToDeviceSpace (cgContext, scale);
CGContextScaleCTM (cgContext, 1.0 / scale.width, 1.0 / scale.height);
/* Create the cairo surface to draw to the CGContext and translate
* coordinates so we can pretend we are in the same coordinate system
* as the GDK surface.
*/
dest = cairo_quartz_surface_create_for_cg_context (cgContext,
gdk_surface->width * scale_factor,
gdk_surface->height * scale_factor);
cairo_surface_set_device_scale (dest, scale_factor, scale_factor);
/* Create cairo context and translate things into the origin of
* the topmost contentView so that we just draw at 0,0 with a
* clip region to paint the surface.
*/
cr = cairo_create (dest);
cairo_translate (cr, -abs_bounds.origin.x, -abs_bounds.origin.y);
/* Apply the clip if provided one */
if (self->clip != NULL)
{
cairo_rectangle_int_t area;
n_rects = cairo_region_num_rectangles (self->clip);
for (guint i = 0; i < n_rects; i++)
{
cairo_region_get_rectangle (self->clip, i, &area);
cairo_rectangle (cr, area.x, area.y, area.width, area.height);
}
cairo_clip (cr);
}
/* Clip the cairo context based on the rectangles to be drawn
* within the bounding box :rect.
*/
[self getRectsBeingDrawn:&rects count:&n_rects];
for (NSInteger i = 0; i < n_rects; i++)
{
NSRect area = [self convertRect:rects[i] toView:root_view];
cairo_rectangle (cr,
area.origin.x, area.origin.y,
area.size.width, area.size.height);
}
cairo_clip (cr);
/* Now paint the surface (without blending) as we do not need
* any compositing here. The transparent regions (like shadows)
* are already on non-opaque layers.
*/
cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
cairo_set_source_surface (cr, self->cairoSurface, 0, 0);
cairo_paint (cr);
/* Cleanup state, flush the surface to the backing layer, and
* restore GState for future use.
*/
cairo_destroy (cr);
cairo_surface_flush (dest);
cairo_surface_destroy (dest);
CGContextRestoreGState (cgContext);
}
-(void)setCairoSurface:(cairo_surface_t *)surface
withDamage:(cairo_region_t *)region
{
if (surface != self->cairoSurface)
{
g_clear_pointer (&self->cairoSurface, cairo_surface_destroy);
if (surface != NULL)
self->cairoSurface = cairo_surface_reference (surface);
}
if (region != NULL)
{
NSView *root_view = [[self window] contentView];
NSRect abs_bounds = [self convertRect:[self bounds] toView:root_view];
guint n_rects = cairo_region_num_rectangles (region);
for (guint i = 0; i < n_rects; i++)
{
cairo_rectangle_int_t rect;
NSRect nsrect;
cairo_region_get_rectangle (region, i, &rect);
nsrect = NSMakeRect (rect.x, rect.y, rect.width, rect.height);
if (NSIntersectsRect (abs_bounds, nsrect))
{
nsrect.origin.x -= abs_bounds.origin.x;
nsrect.origin.y -= abs_bounds.origin.y;
[self setNeedsDisplayInRect:nsrect];
}
}
}
for (id view in [self subviews])
[(GdkMacosCairoSubview *)view setCairoSurface:surface
withDamage:region];
}
-(void)setOpaque:(BOOL)opaque
{
self->_isOpaque = opaque;
}
-(void)setClip:(cairo_region_t*)region
{
if (region != self->clip)
{
g_clear_pointer (&self->clip, cairo_region_destroy);
if (region != NULL)
self->clip = cairo_region_reference (region);
}
}
@end

View File

@@ -1,187 +0,0 @@
/* GdkMacosCairoView.c
*
* Copyright © 2020 Red Hat, Inc.
* Copyright © 2005-2007 Imendio AB
*
* 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/>.
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*/
#include "config.h"
#include <CoreGraphics/CoreGraphics.h>
#include <cairo-quartz.h>
#import "GdkMacosCairoView.h"
#import "GdkMacosCairoSubview.h"
#include "gdkmacossurface-private.h"
@implementation GdkMacosCairoView
-(void)dealloc
{
g_clear_pointer (&self->opaque, g_ptr_array_unref);
self->transparent = NULL;
[super dealloc];
}
-(BOOL)isOpaque
{
if ([self window])
return [[self window] isOpaque];
return YES;
}
-(BOOL)isFlipped
{
return YES;
}
-(void)setNeedsDisplay:(BOOL)needsDisplay
{
for (id child in [self subviews])
[child setNeedsDisplay:needsDisplay];
}
-(void)setCairoSurface:(cairo_surface_t *)cairoSurface
withDamage:(cairo_region_t *)cairoRegion
{
for (id view in [self subviews])
[(GdkMacosCairoSubview *)view setCairoSurface:cairoSurface
withDamage:cairoRegion];
}
-(void)removeOpaqueChildren
{
[[self->transparent subviews]
makeObjectsPerformSelector:@selector(removeFromSuperview)];
if (self->opaque->len)
g_ptr_array_remove_range (self->opaque, 0, self->opaque->len);
}
-(void)setOpaqueRegion:(cairo_region_t *)region
{
cairo_region_t *transparent_clip;
NSRect abs_bounds;
guint n_rects;
if (region == NULL)
return;
abs_bounds = [self convertRect:[self bounds] toView:nil];
n_rects = cairo_region_num_rectangles (region);
/* First, we create a clip region for the transparent region to use so that
* we dont end up exposing too much other than the corners on CSD.
*/
transparent_clip = cairo_region_create_rectangle (&(cairo_rectangle_int_t) {
abs_bounds.origin.x, abs_bounds.origin.y,
abs_bounds.size.width, abs_bounds.size.height
});
cairo_region_subtract (transparent_clip, region);
[(GdkMacosCairoSubview *)self->transparent setClip:transparent_clip];
cairo_region_destroy (transparent_clip);
/* The common case (at least for opaque windows and CSD) is that we will
* have either one or two opaque rectangles. If we detect that the same
* number of them are available as the previous, we can just resize the
* previous ones to avoid adding/removing views at a fast rate while
* resizing.
*/
if (n_rects == self->opaque->len)
{
for (guint i = 0; i < n_rects; i++)
{
GdkMacosCairoSubview *child;
cairo_rectangle_int_t rect;
child = g_ptr_array_index (self->opaque, i);
cairo_region_get_rectangle (region, i, &rect);
[child setFrame:NSMakeRect (rect.x - abs_bounds.origin.x,
rect.y - abs_bounds.origin.y,
rect.width,
rect.height)];
}
return;
}
[self removeOpaqueChildren];
for (guint i = 0; i < n_rects; i++)
{
GdkMacosCairoSubview *child;
cairo_rectangle_int_t rect;
NSRect nsrect;
cairo_region_get_rectangle (region, i, &rect);
nsrect = NSMakeRect (rect.x - abs_bounds.origin.x,
rect.y - abs_bounds.origin.y,
rect.width,
rect.height);
child = [[GdkMacosCairoSubview alloc] initWithFrame:nsrect];
[child setOpaque:YES];
[child setWantsLayer:YES];
[self->transparent addSubview:child];
g_ptr_array_add (self->opaque, child);
}
}
-(NSView *)initWithFrame:(NSRect)frame
{
if ((self = [super initWithFrame:frame]))
{
/* An array to track all the opaque children placed into
* the child self->transparent. This allows us to reuse them
* when we receive a new opaque area instead of discarding
* them on each draw.
*/
self->opaque = g_ptr_array_new ();
/* Setup our primary subview which will render all content that is not
* within an opaque region (such as shadows for CSD windows). For opaque
* windows, this will all be obscurred by other views, so it doesn't
* matter much to have it here.
*/
self->transparent = [[GdkMacosCairoSubview alloc] initWithFrame:frame];
[self addSubview:self->transparent];
}
return self;
}
-(void)setFrame:(NSRect)rect
{
[super setFrame:rect];
[self->transparent setFrame:NSMakeRect (0, 0, rect.size.width, rect.size.height)];
}
-(BOOL)acceptsFirstMouse
{
return YES;
}
-(BOOL)mouseDownCanMoveWindow
{
return NO;
}
@end

View File

@@ -1,125 +0,0 @@
/* GdkMacosGLView.c
*
* Copyright 2020 Christian Hergert <chergert@redhat.com>
*
* 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/>.
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*/
#include "config.h"
#include <CoreGraphics/CoreGraphics.h>
#include <OpenGL/gl.h>
#include "gdkmacossurface-private.h"
#import "GdkMacosGLView.h"
@implementation GdkMacosGLView
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
-(void)lockFocus
{
NSOpenGLContext *context;
[super lockFocus];
context = [self openGLContext];
if ([context view] != self)
[context setView: self];
}
-(void)drawRect:(NSRect)rect
{
}
-(void)clearGLContext
{
if (_openGLContext != nil)
[_openGLContext clearDrawable];
_openGLContext = nil;
}
-(void)setOpenGLContext:(NSOpenGLContext*)context
{
if (_openGLContext != context)
{
if (_openGLContext != nil)
[_openGLContext clearDrawable];
_openGLContext = context;
if (_openGLContext != nil)
{
[_openGLContext setView:self];
[self setWantsLayer:YES];
[self.layer setContentsGravity:kCAGravityBottomLeft];
[_openGLContext update];
}
}
}
-(NSOpenGLContext *)openGLContext
{
return _openGLContext;
}
-(BOOL)isOpaque
{
if ([self window])
return [[self window] isOpaque];
return YES;
}
-(BOOL)isFlipped
{
return YES;
}
-(BOOL)acceptsFirstMouse
{
return YES;
}
-(BOOL)mouseDownCanMoveWindow
{
return NO;
}
-(void)invalidateRegion:(const cairo_region_t *)region
{
if (region != NULL)
{
guint n_rects = cairo_region_num_rectangles (region);
for (guint i = 0; i < n_rects; i++)
{
cairo_rectangle_int_t rect;
NSRect nsrect;
cairo_region_get_rectangle (region, i, &rect);
nsrect = NSMakeRect (rect.x, rect.y, rect.width, rect.height);
[self setNeedsDisplayInRect:nsrect];
}
}
}
G_GNUC_END_IGNORE_DEPRECATIONS
@end

386
gdk/macos/GdkMacosLayer.c Normal file
View File

@@ -0,0 +1,386 @@
/* GdkMacosLayer.c
*
* Copyright © 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/>.
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*/
#include "config.h"
#import "GdkMacosLayer.h"
#import "GdkMacosTile.h"
@protocol CanSetContentsOpaque
- (void)setContentsOpaque:(BOOL)mask;
@end
@implementation GdkMacosLayer
#define TILE_MAX_SIZE 128
#define TILE_EDGE_MAX_SIZE 512
static CGAffineTransform flipTransform;
static gboolean hasFlipTransform;
typedef struct
{
GdkMacosTile *tile;
cairo_rectangle_int_t cr_area;
CGRect area;
guint opaque : 1;
} TileInfo;
typedef struct
{
const cairo_region_t *region;
guint n_rects;
guint iter;
cairo_rectangle_int_t rect;
cairo_rectangle_int_t stash;
guint finished : 1;
} Tiler;
static void
tiler_init (Tiler *tiler,
const cairo_region_t *region)
{
memset (tiler, 0, sizeof *tiler);
if (region == NULL)
{
tiler->finished = TRUE;
return;
}
tiler->region = region;
tiler->n_rects = cairo_region_num_rectangles (region);
if (tiler->n_rects > 0)
cairo_region_get_rectangle (region, 0, &tiler->rect);
else
tiler->finished = TRUE;
}
static gboolean
tiler_next (Tiler *tiler,
cairo_rectangle_int_t *tile,
int max_size)
{
if (tiler->finished)
return FALSE;
if (tiler->rect.width == 0 || tiler->rect.height == 0)
{
tiler->iter++;
if (tiler->iter >= tiler->n_rects)
{
tiler->finished = TRUE;
return FALSE;
}
cairo_region_get_rectangle (tiler->region, tiler->iter, &tiler->rect);
}
/* If the next rectangle is too tall, slice the bottom off to
* leave just the height we want into tiler->stash.
*/
if (tiler->rect.height > max_size)
{
tiler->stash = tiler->rect;
tiler->stash.y += max_size;
tiler->stash.height -= max_size;
tiler->rect.height = max_size;
}
/* Now we can take the next horizontal slice */
tile->x = tiler->rect.x;
tile->y = tiler->rect.y;
tile->height = tiler->rect.height;
tile->width = MIN (max_size, tiler->rect.width);
tiler->rect.x += tile->width;
tiler->rect.width -= tile->width;
if (tiler->rect.width == 0)
{
tiler->rect = tiler->stash;
tiler->stash.width = tiler->stash.height = 0;
}
return TRUE;
}
static inline CGRect
toCGRect (const cairo_rectangle_int_t *rect)
{
return CGRectMake (rect->x, rect->y, rect->width, rect->height);
}
static inline cairo_rectangle_int_t
fromCGRect (const CGRect rect)
{
return (cairo_rectangle_int_t) {
rect.origin.x,
rect.origin.y,
rect.size.width,
rect.size.height
};
}
-(id)init
{
if (!hasFlipTransform)
{
hasFlipTransform = TRUE;
flipTransform = CGAffineTransformMakeScale (1, -1);
}
self = [super init];
if (self == NULL)
return NULL;
self->_layoutInvalid = TRUE;
[self setContentsGravity:kCAGravityCenter];
[self setContentsScale:1.0f];
[self setGeometryFlipped:YES];
return self;
}
-(BOOL)isOpaque
{
return NO;
}
-(void)_applyLayout:(GArray *)tiles
{
CGAffineTransform transform;
GArray *prev;
gboolean exhausted;
guint j = 0;
if (self->_isFlipped)
transform = flipTransform;
else
transform = CGAffineTransformIdentity;
prev = g_steal_pointer (&self->_tiles);
self->_tiles = tiles;
exhausted = prev == NULL;
/* Try to use existing CALayer to avoid creating new layers
* as that can be rather expensive.
*/
for (guint i = 0; i < tiles->len; i++)
{
TileInfo *info = &g_array_index (tiles, TileInfo, i);
if (!exhausted)
{
TileInfo *other = NULL;
for (; j < prev->len; j++)
{
other = &g_array_index (prev, TileInfo, j);
if (other->opaque == info->opaque)
{
j++;
break;
}
other = NULL;
}
if (other != NULL)
{
info->tile = g_steal_pointer (&other->tile);
[info->tile setFrame:info->area];
[info->tile setAffineTransform:transform];
continue;
}
}
info->tile = [GdkMacosTile layer];
[info->tile setAffineTransform:transform];
[info->tile setContentsScale:1.0f];
[info->tile setOpaque:info->opaque];
[(id<CanSetContentsOpaque>)info->tile setContentsOpaque:info->opaque];
[info->tile setFrame:info->area];
[self addSublayer:info->tile];
}
/* Release all of our old layers */
if (prev != NULL)
{
for (guint i = 0; i < prev->len; i++)
{
TileInfo *info = &g_array_index (prev, TileInfo, i);
if (info->tile != NULL)
[info->tile removeFromSuperlayer];
}
g_array_unref (prev);
}
}
-(void)layoutSublayers
{
Tiler tiler;
GArray *ar;
cairo_region_t *transparent;
cairo_rectangle_int_t rect;
int max_size;
if (!self->_inSwapBuffer)
return;
self->_layoutInvalid = FALSE;
ar = g_array_sized_new (FALSE, FALSE, sizeof (TileInfo), 32);
rect = fromCGRect ([self bounds]);
rect.x = rect.y = 0;
/* Calculate the transparent region (edges usually) */
transparent = cairo_region_create_rectangle (&rect);
if (self->_opaqueRegion)
cairo_region_subtract (transparent, self->_opaqueRegion);
self->_opaque = cairo_region_is_empty (transparent);
/* If we have transparent borders around the opaque region, then
* we are okay with a bit larger tiles since they don't change
* all that much and are generally small in width.
*/
if (!self->_opaque &&
self->_opaqueRegion &&
!cairo_region_is_empty (self->_opaqueRegion))
max_size = TILE_EDGE_MAX_SIZE;
else
max_size = TILE_MAX_SIZE;
/* Track transparent children */
tiler_init (&tiler, transparent);
while (tiler_next (&tiler, &rect, max_size))
{
TileInfo *info;
g_array_set_size (ar, ar->len+1);
info = &g_array_index (ar, TileInfo, ar->len-1);
info->tile = NULL;
info->opaque = FALSE;
info->cr_area = rect;
info->area = toCGRect (&info->cr_area);
}
/* Track opaque children */
tiler_init (&tiler, self->_opaqueRegion);
while (tiler_next (&tiler, &rect, TILE_MAX_SIZE))
{
TileInfo *info;
g_array_set_size (ar, ar->len+1);
info = &g_array_index (ar, TileInfo, ar->len-1);
info->tile = NULL;
info->opaque = TRUE;
info->cr_area = rect;
info->area = toCGRect (&info->cr_area);
}
cairo_region_destroy (transparent);
[self _applyLayout:g_steal_pointer (&ar)];
[super layoutSublayers];
}
-(void)setFrame:(NSRect)frame
{
if (frame.size.width != self.bounds.size.width ||
frame.size.height != self.bounds.size.height)
{
self->_layoutInvalid = TRUE;
[self setNeedsLayout];
}
[super setFrame:frame];
}
-(void)setOpaqueRegion:(const cairo_region_t *)opaqueRegion
{
g_clear_pointer (&self->_opaqueRegion, cairo_region_destroy);
self->_opaqueRegion = cairo_region_copy (opaqueRegion);
self->_layoutInvalid = TRUE;
[self setNeedsLayout];
}
-(void)swapBuffer:(GdkMacosBuffer *)buffer withDamage:(const cairo_region_t *)damage
{
IOSurfaceRef ioSurface = _gdk_macos_buffer_get_native (buffer);
gboolean flipped = _gdk_macos_buffer_get_flipped (buffer);
double scale = _gdk_macos_buffer_get_device_scale (buffer);
double width = _gdk_macos_buffer_get_width (buffer) / scale;
double height = _gdk_macos_buffer_get_height (buffer) / scale;
if (flipped != self->_isFlipped)
{
self->_isFlipped = flipped;
self->_layoutInvalid = TRUE;
}
if (self->_layoutInvalid)
{
self->_inSwapBuffer = TRUE;
[self layoutSublayers];
self->_inSwapBuffer = FALSE;
}
if (self->_tiles == NULL)
return;
for (guint i = 0; i < self->_tiles->len; i++)
{
const TileInfo *info = &g_array_index (self->_tiles, TileInfo, i);
cairo_region_overlap_t overlap;
CGRect area;
overlap = cairo_region_contains_rectangle (damage, &info->cr_area);
if (overlap == CAIRO_REGION_OVERLAP_OUT)
continue;
area.origin.x = info->area.origin.x / width;
area.size.width = info->area.size.width / width;
area.size.height = info->area.size.height / height;
if (flipped)
area.origin.y = (height - info->area.origin.y - info->area.size.height) / height;
else
area.origin.y = info->area.origin.y / height;
[info->tile swapBuffer:ioSurface withRect:area];
}
}
@end

44
gdk/macos/GdkMacosLayer.h Normal file
View File

@@ -0,0 +1,44 @@
/* GdkMacosLayer.h
*
* Copyright © 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/>.
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*/
#include <QuartzCore/QuartzCore.h>
#include <IOSurface/IOSurface.h>
#include <cairo.h>
#include <glib.h>
#include "gdkmacosbuffer-private.h"
#define GDK_IS_MACOS_LAYER(obj) ((obj) && [obj isKindOfClass:[GdkMacosLayer class]])
@interface GdkMacosLayer : CALayer
{
cairo_region_t *_opaqueRegion;
GArray *_tiles;
guint _opaque : 1;
guint _layoutInvalid : 1;
guint _inSwapBuffer : 1;
guint _isFlipped : 1;
};
-(void)setOpaqueRegion:(const cairo_region_t *)opaqueRegion;
-(void)swapBuffer:(GdkMacosBuffer *)buffer withDamage:(const cairo_region_t *)damage;
@end

View File

@@ -1,7 +1,6 @@
/* GdkMacosGLView.h
/* GdkMacosTile.c
*
* Copyright © 2020 Red Hat, Inc.
* Copyright © 2005-2007 Imendio AB
* Copyright © 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
@@ -19,23 +18,34 @@
* SPDX-License-Identifier: LGPL-2.1-or-later
*/
#include <cairo.h>
#include "config.h"
#import "GdkMacosBaseView.h"
#include <AppKit/AppKit.h>
#define GDK_IS_MACOS_GL_VIEW(obj) ((obj) && [obj isKindOfClass:[GdkMacosGLView class]])
#import "GdkMacosTile.h"
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
@implementation GdkMacosTile
@interface GdkMacosGLView : GdkMacosBaseView
-(id)init
{
NSOpenGLContext *_openGLContext;
self = [super init];
[self setContentsScale:1.0];
[self setEdgeAntialiasingMask:0];
[self setDrawsAsynchronously:YES];
return self;
}
-(void)setOpenGLContext:(NSOpenGLContext*)context;
-(NSOpenGLContext *)openGLContext;
-(void)invalidateRegion:(const cairo_region_t *)region;
-(void)swapBuffer:(IOSurfaceRef)buffer withRect:(CGRect)rect
{
if G_LIKELY ([self contents] == (id)buffer)
[(id<CanSetContentsChanged>)self setContentsChanged];
else
[self setContents:(id)buffer];
G_GNUC_END_IGNORE_DEPRECATIONS
if G_UNLIKELY (!CGRectEqualToRect ([self contentsRect], rect))
self.contentsRect = rect;
}
@end

View File

@@ -1,6 +1,6 @@
/* GdkMacosCairoSubview.h
/* GdkMacosTile.h
*
* Copyright © 2020 Red Hat, Inc.
* Copyright © 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
@@ -18,20 +18,20 @@
* SPDX-License-Identifier: LGPL-2.1-or-later
*/
#include <AppKit/AppKit.h>
#include <QuartzCore/QuartzCore.h>
#define GDK_IS_MACOS_CAIRO_SUBVIEW(obj) ((obj) && [obj isKindOfClass:[GdkMacosCairoSubview class]])
#include "gdkmacosbuffer-private.h"
@interface GdkMacosCairoSubview : NSView
#define GDK_IS_MACOS_TILE(obj) ((obj) && [obj isKindOfClass:[GdkMacosTile class]])
@protocol CanSetContentsChanged
-(void)setContentsChanged;
@end
@interface GdkMacosTile : CALayer
{
BOOL _isOpaque;
cairo_surface_t *cairoSurface;
cairo_region_t *clip;
}
};
-(void)setOpaque:(BOOL)opaque;
-(void)setCairoSurface:(cairo_surface_t *)cairoSurface
withDamage:(cairo_region_t *)region;
-(void)setClip:(cairo_region_t*)region;
-(void)swapBuffer:(IOSurfaceRef)buffer withRect:(CGRect)rect;
@end

100
gdk/macos/GdkMacosView.c Normal file
View File

@@ -0,0 +1,100 @@
/* GdkMacosView.c
*
* Copyright 2022 Christian Hergert <chergert@redhat.com>
*
* 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/>.
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*/
#include "config.h"
#include <CoreGraphics/CoreGraphics.h>
#import "GdkMacosLayer.h"
#import "GdkMacosView.h"
#import "GdkMacosWindow.h"
@implementation GdkMacosView
-(id)initWithFrame:(NSRect)frame
{
if ((self = [super initWithFrame:frame]))
{
GdkMacosLayer *layer = [GdkMacosLayer layer];
[self setLayerContentsRedrawPolicy:NSViewLayerContentsRedrawNever];
[self setLayer:layer];
[self setWantsLayer:YES];
}
return self;
}
-(BOOL)isFlipped
{
return YES;
}
-(BOOL)acceptsFirstMouse
{
return YES;
}
-(BOOL)mouseDownCanMoveWindow
{
return NO;
}
-(void)mouseDown:(NSEvent *)nsevent
{
if ([(GdkMacosWindow *)[self window] needsMouseDownQuirk])
/* We should only hit this when we are trying to click through
* the shadow of a window into another window. Just request
* that the application not activate this window on mouseUp.
* See gdkmacosdisplay-translate.c for the other half of this.
*/
[NSApp preventWindowOrdering];
else
[super mouseDown:nsevent];
}
-(void)setFrame:(NSRect)rect
{
[super setFrame:rect];
self->_nextFrameDirty = TRUE;
}
-(void)setOpaqueRegion:(const cairo_region_t *)opaqueRegion
{
[(GdkMacosLayer *)[self layer] setOpaqueRegion:opaqueRegion];
}
-(BOOL)wantsUpdateLayer
{
return YES;
}
-(void)swapBuffer:(GdkMacosBuffer *)buffer withDamage:(const cairo_region_t *)damage
{
if (self->_nextFrameDirty)
{
self->_nextFrameDirty = FALSE;
[[self layer] setFrame:[self frame]];
}
[(GdkMacosLayer *)[self layer] swapBuffer:buffer withDamage:damage];
}
@end

View File

@@ -1,7 +1,6 @@
/* GdkMacosCairoView.h
/* GdkMacosView.h
*
* Copyright © 2020 Red Hat, Inc.
* Copyright © 2005-2007 Imendio AB
* Copyright 2022 Christian Hergert <chergert@redhat.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -23,15 +22,17 @@
#import "GdkMacosBaseView.h"
#define GDK_IS_MACOS_CAIRO_VIEW(obj) ((obj) && [obj isKindOfClass:[GdkMacosCairoView class]])
#include "gdkmacosbuffer-private.h"
@interface GdkMacosCairoView : GdkMacosBaseView
#define GDK_IS_MACOS_VIEW(obj) ((obj) && [obj isKindOfClass:[GdkMacosView class]])
@interface GdkMacosView : GdkMacosBaseView
{
NSView *transparent;
GPtrArray *opaque;
NSRect _nextFrame;
guint _nextFrameDirty : 1;
}
-(void)setCairoSurface:(cairo_surface_t *)cairoSurface
withDamage:(cairo_region_t *)region;
-(void)setOpaqueRegion:(const cairo_region_t *)opaqueRegion;
-(void)swapBuffer:(GdkMacosBuffer *)buffer withDamage:(const cairo_region_t *)damage;
@end

View File

@@ -24,8 +24,7 @@
#include <gdk/gdk.h>
#import "GdkMacosBaseView.h"
#import "GdkMacosCairoView.h"
#import "GdkMacosGLView.h"
#import "GdkMacosView.h"
#import "GdkMacosWindow.h"
#include "gdkmacosclipboard-private.h"
@@ -150,8 +149,7 @@ typedef NSString *CALayerContentsGravity;
_gdk_macos_display_break_all_grabs (GDK_MACOS_DISPLAY (display), time);
/* Reset gravity */
if (GDK_IS_MACOS_GL_VIEW ([self contentView]))
[[[self contentView] layer] setContentsGravity:kCAGravityBottomLeft];
[[[self contentView] layer] setContentsGravity:kCAGravityBottomLeft];
break;
}
@@ -173,6 +171,11 @@ typedef NSString *CALayerContentsGravity;
return inMove;
}
- (BOOL)inFullscreenTransition;
{
return inFullscreenTransition;
}
-(void)checkSendEnterNotify
{
/* When a new window has been created, and the mouse is in the window
@@ -203,69 +206,20 @@ typedef NSString *CALayerContentsGravity;
}
}
-(void)windowDidUnmaximize
{
NSWindowStyleMask style_mask = [self styleMask];
gdk_synthesize_surface_state (GDK_SURFACE (gdk_surface), GDK_TOPLEVEL_STATE_MAXIMIZED, 0);
/* If we are using CSD, then we transitioned to an opaque
* window while we were maximized. Now we need to drop that
* as we are leaving maximized state.
*/
if ((style_mask & NSWindowStyleMaskTitled) == 0 && [self isOpaque])
[self setOpaque:NO];
}
-(void)windowDidMove:(NSNotification *)aNotification
-(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;
/* In case the window is changed when maximized remove the maximized state */
if (maximized && !inMaximizeTransition && !NSEqualRects (lastMaximizedFrame, [self frame]))
[self windowDidUnmaximize];
if (maximized && !inMaximizeTransition && !NSEqualRects (lastMaximizedFrame, frame))
{
gdk_synthesize_surface_state (surface, GDK_TOPLEVEL_STATE_MAXIMIZED, 0);
_gdk_surface_update_size (surface);
}
_gdk_macos_surface_update_position (gdk_surface);
_gdk_macos_surface_reposition_children (gdk_surface);
[self checkSendEnterNotify];
}
-(void)windowDidResize:(NSNotification *)aNotification
{
NSRect content_rect;
GdkSurface *surface;
GdkDisplay *display;
gboolean maximized;
surface = GDK_SURFACE (gdk_surface);
display = gdk_surface_get_display (surface);
content_rect = [self contentRectForFrameRect:[self frame]];
maximized = (surface->state & GDK_TOPLEVEL_STATE_MAXIMIZED) != 0;
/* see same in windowDidMove */
if (maximized && !inMaximizeTransition && !NSEqualRects (lastMaximizedFrame, [self frame]))
[self windowDidUnmaximize];
surface->width = content_rect.size.width;
surface->height = content_rect.size.height;
/* Certain resize operations (e.g. going fullscreen), also move the
* origin of the window.
*/
_gdk_macos_surface_update_position (GDK_MACOS_SURFACE (surface));
[[self contentView] setFrame:NSMakeRect (0, 0, surface->width, surface->height)];
_gdk_surface_update_size (surface);
gdk_surface_request_layout (surface);
_gdk_macos_surface_reposition_children (gdk_surface);
[self checkSendEnterNotify];
[super setFrame:frame display:display];
[[self contentView] setFrame:NSMakeRect (0, 0, contentRect.size.width, contentRect.size.height)];
}
-(id)initWithContentRect:(NSRect)contentRect
@@ -274,7 +228,7 @@ typedef NSString *CALayerContentsGravity;
defer:(BOOL)flag
screen:(NSScreen *)screen
{
GdkMacosCairoView *view;
GdkMacosView *view;
self = [super initWithContentRect:contentRect
styleMask:styleMask
@@ -285,8 +239,9 @@ typedef NSString *CALayerContentsGravity;
[self setAcceptsMouseMovedEvents:YES];
[self setDelegate:(id<NSWindowDelegate>)self];
[self setReleasedWhenClosed:YES];
[self setPreservesContentDuringLiveResize:NO];
view = [[GdkMacosCairoView alloc] initWithFrame:contentRect];
view = [[GdkMacosView alloc] initWithFrame:contentRect];
[self setContentView:view];
[view release];
@@ -303,7 +258,8 @@ typedef NSString *CALayerContentsGravity;
-(BOOL)canBecomeKeyWindow
{
return GDK_IS_TOPLEVEL (gdk_surface);
return GDK_IS_TOPLEVEL (gdk_surface) ||
(GDK_IS_POPUP (gdk_surface) && GDK_SURFACE (gdk_surface)->input_region != NULL);
}
-(void)showAndMakeKey:(BOOL)makeKey
@@ -311,9 +267,12 @@ typedef NSString *CALayerContentsGravity;
inShowOrHide = YES;
if (makeKey && [self canBecomeKeyWindow])
[self makeKeyAndOrderFront:nil];
[self makeKeyAndOrderFront:self];
else
[self orderFront:nil];
[self orderFront:self];
if (makeKey && [self canBecomeMainWindow])
[self makeMainWindow];
inShowOrHide = NO;
@@ -411,12 +370,31 @@ typedef NSString *CALayerContentsGravity;
windowFrame.origin.x = new_origin.x;
windowFrame.origin.y = new_origin.y;
/* And now apply the frame to the window */
[self setFrameOrigin:NSMakePoint(new_origin.x, new_origin.y)];
[self setFrame:NSMakeRect (new_origin.x, new_origin.y,
window_gdk.width, window_gdk.height)
display:YES];
return YES;
}
-(void)windowDidMove:(NSNotification *)notification
{
_gdk_macos_surface_configure ([self gdkSurface]);
}
-(void)windowDidResize:(NSNotification *)notification
{
_gdk_macos_surface_configure (gdk_surface);
/* If we're using server-side decorations, this notification is coming
* in from a display-side change. We need to request a layout in
* addition to the configure event.
*/
if (GDK_IS_MACOS_TOPLEVEL_SURFACE (gdk_surface) &&
GDK_MACOS_TOPLEVEL_SURFACE (gdk_surface)->decorated)
gdk_surface_request_layout (GDK_SURFACE (gdk_surface));
}
/* Used by gdkmacosdisplay-translate.c to decide if our sendEvent() handler
* above will see the event or if it will be subjected to standard processing
* by GDK.
@@ -428,6 +406,7 @@ typedef NSString *CALayerContentsGravity;
-(void)beginManualMove
{
gboolean maximized = GDK_SURFACE (gdk_surface)->state & GDK_TOPLEVEL_STATE_MAXIMIZED;
NSPoint initialMoveLocation;
GdkPoint point;
GdkMonitor *monitor;
@@ -446,6 +425,13 @@ 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,
@@ -537,15 +523,7 @@ typedef NSString *CALayerContentsGravity;
new_frame.size.height = min_size.height;
}
/* We could also apply aspect ratio:
new_frame.size.height = new_frame.size.width / [self aspectRatio].width * [self aspectRatio].height;
*/
[self setFrame:new_frame display:YES];
/* Let the resizing be handled by GTK. */
if (g_main_context_pending (NULL))
g_main_context_iteration (NULL, FALSE);
_gdk_macos_surface_user_resize ([self gdkSurface], new_frame);
inTrackManualResize = NO;
@@ -554,49 +532,46 @@ typedef NSString *CALayerContentsGravity;
-(void)beginManualResize:(GdkSurfaceEdge)edge
{
CALayerContentsGravity gravity = kCAGravityBottomLeft;
if (inMove || inManualMove || inManualResize)
return;
inManualResize = YES;
resizeEdge = edge;
if (GDK_IS_MACOS_GL_VIEW ([self contentView]))
switch (edge)
{
CALayerContentsGravity gravity = kCAGravityBottomLeft;
default:
case GDK_SURFACE_EDGE_NORTH:
gravity = kCAGravityTopLeft;
break;
switch (edge)
{
default:
case GDK_SURFACE_EDGE_NORTH:
gravity = kCAGravityTopLeft;
break;
case GDK_SURFACE_EDGE_NORTH_WEST:
gravity = kCAGravityTopRight;
break;
case GDK_SURFACE_EDGE_NORTH_WEST:
gravity = kCAGravityTopRight;
break;
case GDK_SURFACE_EDGE_SOUTH_WEST:
case GDK_SURFACE_EDGE_WEST:
gravity = kCAGravityBottomRight;
break;
case GDK_SURFACE_EDGE_SOUTH_WEST:
case GDK_SURFACE_EDGE_WEST:
gravity = kCAGravityBottomRight;
break;
case GDK_SURFACE_EDGE_SOUTH:
case GDK_SURFACE_EDGE_SOUTH_EAST:
gravity = kCAGravityBottomLeft;
break;
case GDK_SURFACE_EDGE_SOUTH:
case GDK_SURFACE_EDGE_SOUTH_EAST:
gravity = kCAGravityBottomLeft;
break;
case GDK_SURFACE_EDGE_EAST:
gravity = kCAGravityBottomLeft;
break;
case GDK_SURFACE_EDGE_EAST:
gravity = kCAGravityBottomLeft;
break;
case GDK_SURFACE_EDGE_NORTH_EAST:
gravity = kCAGravityTopLeft;
break;
}
[[[self contentView] layer] setContentsGravity:gravity];
case GDK_SURFACE_EDGE_NORTH_EAST:
gravity = kCAGravityTopLeft;
break;
}
[[[self contentView] layer] setContentsGravity:gravity];
initialResizeFrame = [self frame];
initialResizeLocation = convert_nspoint_to_screen (self, [self mouseLocationOutsideOfEventStream]);
}
@@ -710,7 +685,12 @@ typedef NSString *CALayerContentsGravity;
is_opaque = (([self styleMask] & NSWindowStyleMaskTitled) != 0);
if (was_fullscreen != is_fullscreen)
_gdk_macos_surface_update_fullscreen_state (gdk_surface);
{
if (was_fullscreen)
[self setFrame:lastUnfullscreenFrame display:NO];
_gdk_macos_surface_update_fullscreen_state (gdk_surface);
}
if (was_opaque != is_opaque)
{
@@ -760,7 +740,6 @@ typedef NSString *CALayerContentsGravity;
if (state & GDK_TOPLEVEL_STATE_MAXIMIZED)
{
lastMaximizedFrame = newFrame;
[self windowDidUnmaximize];
}
else
{
@@ -775,16 +754,7 @@ typedef NSString *CALayerContentsGravity;
-(void)windowDidEndLiveResize:(NSNotification *)aNotification
{
gboolean maximized = GDK_SURFACE (gdk_surface)->state & GDK_TOPLEVEL_STATE_MAXIMIZED;
inMaximizeTransition = NO;
/* Even if this is CSD, we want to be opaque while maximized
* to speed up compositing by allowing the display server to
* avoid costly blends.
*/
if (maximized)
[self setOpaque:YES];
}
-(NSSize)window:(NSWindow *)window willUseFullScreenContentSize:(NSSize)proposedSize
@@ -794,16 +764,37 @@ typedef NSString *CALayerContentsGravity;
-(void)windowWillEnterFullScreen:(NSNotification *)aNotification
{
inFullscreenTransition = YES;
lastUnfullscreenFrame = [self frame];
}
-(void)windowDidEnterFullScreen:(NSNotification *)aNotification
{
inFullscreenTransition = NO;
initialPositionKnown = NO;
[self checkSendEnterNotify];
}
-(void)windowWillExitFullScreen:(NSNotification *)aNotification
{
[self setFrame:lastUnfullscreenFrame display:YES];
inFullscreenTransition = YES;
}
-(void)windowDidExitFullScreen:(NSNotification *)aNotification
{
inFullscreenTransition = NO;
initialPositionKnown = NO;
[self checkSendEnterNotify];
}
-(void)windowDidFailToEnterFullScreen:(NSNotification *)aNotification
{
inFullscreenTransition = NO;
}
-(void)windowDidFailToExitFullScreen:(NSNotification *)aNotification
{
inFullscreenTransition = NO;
}
-(void)windowDidChangeScreen:(NSNotification *)aNotification
@@ -845,4 +836,15 @@ typedef NSString *CALayerContentsGravity;
return NO;
}
-(void)swapBuffer:(GdkMacosBuffer *)buffer withDamage:(const cairo_region_t *)damage
{
[(GdkMacosView *)[self contentView] swapBuffer:buffer withDamage:damage];
}
-(BOOL)needsMouseDownQuirk
{
return GDK_IS_MACOS_TOPLEVEL_SURFACE (gdk_surface) &&
!GDK_MACOS_TOPLEVEL_SURFACE (gdk_surface)->decorated;
}
@end

View File

@@ -21,9 +21,11 @@
#import <AppKit/AppKit.h>
#import <Foundation/Foundation.h>
#import <IOSurface/IOSurface.h>
#include <gdk/gdk.h>
#include "gdkmacosbuffer-private.h"
#include "gdkmacosdisplay.h"
#include "gdkmacossurface.h"
#include "edgesnapping.h"
@@ -51,6 +53,7 @@
NSRect lastMaximizedFrame;
NSRect lastUnfullscreenFrame;
BOOL inMaximizeTransition;
BOOL inFullscreenTransition;
}
-(void)beginManualMove;
@@ -66,5 +69,8 @@
-(BOOL)trackManualMove;
-(BOOL)trackManualResize;
-(void)setDecorated:(BOOL)decorated;
-(void)swapBuffer:(GdkMacosBuffer *)buffer withDamage:(const cairo_region_t *)damage;
-(BOOL)needsMouseDownQuirk;
-(BOOL)inFullscreenTransition;
@end

View File

@@ -26,7 +26,10 @@
#include "gdkdisplaylinksource.h"
#include "gdkdebug.h"
#include "gdkmacoseventsource-private.h"
#include "gdkmacosmonitor-private.h"
#include "gdk-private.h"
static gint64 host_to_frame_clock_time (gint64 val);
@@ -64,7 +67,7 @@ gdk_display_link_source_dispatch (GSource *source,
impl->needs_dispatch = FALSE;
if (callback != NULL)
if (!impl->paused && callback != NULL)
ret = callback (user_data);
return ret;
@@ -75,7 +78,9 @@ gdk_display_link_source_finalize (GSource *source)
{
GdkDisplayLinkSource *impl = (GdkDisplayLinkSource *)source;
CVDisplayLinkStop (impl->display_link);
if (!impl->paused)
CVDisplayLinkStop (impl->display_link);
CVDisplayLinkRelease (impl->display_link);
}
@@ -89,12 +94,18 @@ static GSourceFuncs gdk_display_link_source_funcs = {
void
gdk_display_link_source_pause (GdkDisplayLinkSource *source)
{
g_return_if_fail (source->paused == FALSE);
source->paused = TRUE;
CVDisplayLinkStop (source->display_link);
}
void
gdk_display_link_source_unpause (GdkDisplayLinkSource *source)
{
g_return_if_fail (source->paused == TRUE);
source->paused = FALSE;
CVDisplayLinkStart (source->display_link);
}
@@ -146,6 +157,7 @@ gdk_display_link_source_frame_cb (CVDisplayLinkRef display_link,
/**
* gdk_display_link_source_new:
* @display_id: the identifier of the monitor
*
* Creates a new `GSource` that will activate the dispatch function upon
* notification from a CVDisplayLink that a new frame should be drawn.
@@ -158,41 +170,61 @@ gdk_display_link_source_frame_cb (CVDisplayLinkRef display_link,
* Returns: (transfer full): A newly created `GSource`
*/
GSource *
gdk_display_link_source_new (void)
gdk_display_link_source_new (CGDirectDisplayID display_id,
CGDisplayModeRef mode)
{
GdkDisplayLinkSource *impl;
GSource *source;
CVReturn ret;
double period;
char *name;
source = g_source_new (&gdk_display_link_source_funcs, sizeof *impl);
impl = (GdkDisplayLinkSource *)source;
impl->display_id = display_id;
impl->paused = TRUE;
/*
* Create our link based on currently connected displays.
* If there are multiple displays, this will be something that tries
* to work for all of them. In the future, we may want to explore multiple
* links based on the connected displays.
/* Create DisplayLink for timing information for the display in
* question so that we can produce graphics for that display at whatever
* rate it can provide.
*/
ret = CVDisplayLinkCreateWithActiveCGDisplays (&impl->display_link);
if (ret != kCVReturnSuccess)
if (CVDisplayLinkCreateWithCGDisplay (display_id, &impl->display_link) != kCVReturnSuccess)
{
g_warning ("Failed to initialize CVDisplayLink!");
return source;
goto failure;
}
/*
* Determine our nominal period between frames.
*/
period = CVDisplayLinkGetActualOutputVideoRefreshPeriod (impl->display_link);
if (period == 0.0)
period = 1.0 / 60.0;
impl->refresh_interval = period * 1000000L;
impl->refresh_rate = 1.0 / period * 1000L;
impl->refresh_rate = CGDisplayModeGetRefreshRate (mode) * 1000.0;
/*
* Wire up our callback to be executed within the high-priority thread.
*/
if (impl->refresh_rate == 0)
{
const CVTime time = CVDisplayLinkGetNominalOutputVideoRefreshPeriod (impl->display_link);
if (!(time.flags & kCVTimeIsIndefinite))
impl->refresh_rate = (double)time.timeScale / (double)time.timeValue * 1000.0;
}
if (impl->refresh_rate != 0)
{
impl->refresh_interval = 1000000.0 / (double)impl->refresh_rate * 1000.0;
}
else
{
double period = CVDisplayLinkGetActualOutputVideoRefreshPeriod (impl->display_link);
if (period == 0.0)
period = 1.0 / 60.0;
impl->refresh_rate = 1.0 / period * 1000L;
impl->refresh_interval = period * 1000000L;
}
name = _gdk_macos_monitor_get_connector_name (display_id);
GDK_NOTE (MISC,
g_message ("Monitor \"%s\" discovered with Refresh Rate %d and Interval %"G_GINT64_FORMAT,
name ? name : "unknown",
impl->refresh_rate,
impl->refresh_interval));
g_free (name);
/* Wire up our callback to be executed within the high-priority thread. */
CVDisplayLinkSetOutputCallback (impl->display_link,
gdk_display_link_source_frame_cb,
source);
@@ -200,6 +232,10 @@ gdk_display_link_source_new (void)
g_source_set_static_name (source, "[gdk] quartz frame clock");
return source;
failure:
g_source_unref (source);
return NULL;
}
static gint64

View File

@@ -30,17 +30,20 @@ G_BEGIN_DECLS
typedef struct
{
GSource source;
GSource source;
CVDisplayLinkRef display_link;
gint64 refresh_interval;
guint refresh_rate;
CGDirectDisplayID display_id;
CVDisplayLinkRef display_link;
gint64 refresh_interval;
guint refresh_rate;
guint paused : 1;
volatile gint64 presentation_time;
volatile guint needs_dispatch;
volatile gint64 presentation_time;
volatile guint needs_dispatch;
} GdkDisplayLinkSource;
GSource *gdk_display_link_source_new (void);
GSource *gdk_display_link_source_new (CGDirectDisplayID display_id,
CGDisplayModeRef mode);
void gdk_display_link_source_pause (GdkDisplayLinkSource *source);
void gdk_display_link_source_unpause (GdkDisplayLinkSource *source);

View File

@@ -0,0 +1,60 @@
/*
* Copyright © 2021 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.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*/
#ifndef __GDK_MACOS_BUFFER_PRIVATE_H__
#define __GDK_MACOS_BUFFER_PRIVATE_H__
#include <CoreGraphics/CoreGraphics.h>
#include <Foundation/Foundation.h>
#include <IOSurface/IOSurface.h>
#include <cairo.h>
#include <glib-object.h>
G_BEGIN_DECLS
#define GDK_TYPE_MACOS_BUFFER (gdk_macos_buffer_get_type())
G_DECLARE_FINAL_TYPE (GdkMacosBuffer, gdk_macos_buffer, GDK, MACOS_BUFFER, GObject)
GdkMacosBuffer *_gdk_macos_buffer_new (int width,
int height,
double device_scale,
int bytes_per_element,
int bits_per_pixel);
IOSurfaceRef _gdk_macos_buffer_get_native (GdkMacosBuffer *self);
void _gdk_macos_buffer_lock (GdkMacosBuffer *self);
void _gdk_macos_buffer_unlock (GdkMacosBuffer *self);
void _gdk_macos_buffer_read_lock (GdkMacosBuffer *self);
void _gdk_macos_buffer_read_unlock (GdkMacosBuffer *self);
guint _gdk_macos_buffer_get_width (GdkMacosBuffer *self);
guint _gdk_macos_buffer_get_height (GdkMacosBuffer *self);
guint _gdk_macos_buffer_get_stride (GdkMacosBuffer *self);
double _gdk_macos_buffer_get_device_scale (GdkMacosBuffer *self);
const cairo_region_t *_gdk_macos_buffer_get_damage (GdkMacosBuffer *self);
void _gdk_macos_buffer_set_damage (GdkMacosBuffer *self,
cairo_region_t *damage);
gpointer _gdk_macos_buffer_get_data (GdkMacosBuffer *self);
gboolean _gdk_macos_buffer_get_flipped (GdkMacosBuffer *self);
void _gdk_macos_buffer_set_flipped (GdkMacosBuffer *self,
gboolean flipped);
G_END_DECLS
#endif /* __GDK_MACOS_BUFFER_PRIVATE_H__ */

310
gdk/macos/gdkmacosbuffer.c Normal file
View File

@@ -0,0 +1,310 @@
/*
* Copyright © 2021 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.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*/
#include "config.h"
#include <IOSurface/IOSurface.h>
#include <Foundation/Foundation.h>
#include <OpenGL/CGLIOSurface.h>
#include <QuartzCore/QuartzCore.h>
#include "gdkmacosbuffer-private.h"
struct _GdkMacosBuffer
{
GObject parent_instance;
cairo_region_t *damage;
IOSurfaceRef surface;
int lock_count;
guint bytes_per_element;
guint bits_per_pixel;
guint width;
guint height;
guint stride;
double device_scale;
guint flipped : 1;
};
G_DEFINE_TYPE (GdkMacosBuffer, gdk_macos_buffer, G_TYPE_OBJECT)
static void
gdk_macos_buffer_dispose (GObject *object)
{
GdkMacosBuffer *self = (GdkMacosBuffer *)object;
if (self->lock_count != 0)
g_critical ("Attempt to dispose %s while lock is held",
G_OBJECT_TYPE_NAME (self));
/* We could potentially force the unload of our surface here with
* IOSurfaceSetPurgeable (self->surface, kIOSurfacePurgeableEmpty, NULL)
* but that would cause it to empty when the layers may still be attached
* to it. Better to just let it get GC'd by the system after they have
* moved on to a new buffer.
*/
g_clear_pointer (&self->surface, CFRelease);
g_clear_pointer (&self->damage, cairo_region_destroy);
G_OBJECT_CLASS (gdk_macos_buffer_parent_class)->dispose (object);
}
static void
gdk_macos_buffer_class_init (GdkMacosBufferClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->dispose = gdk_macos_buffer_dispose;
}
static void
gdk_macos_buffer_init (GdkMacosBuffer *self)
{
}
static void
add_int (CFMutableDictionaryRef dict,
const CFStringRef key,
int value)
{
CFNumberRef number = CFNumberCreate (NULL, kCFNumberIntType, &value);
CFDictionaryAddValue (dict, key, number);
CFRelease (number);
}
static IOSurfaceRef
create_surface (int width,
int height,
int bytes_per_element,
guint *stride)
{
CFMutableDictionaryRef props;
IOSurfaceRef ret;
size_t bytes_per_row;
size_t total_bytes;
props = CFDictionaryCreateMutable (kCFAllocatorDefault,
16,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
if (props == NULL)
return NULL;
bytes_per_row = IOSurfaceAlignProperty (kIOSurfaceBytesPerRow, width * bytes_per_element);
total_bytes = IOSurfaceAlignProperty (kIOSurfaceAllocSize, height * bytes_per_row);
add_int (props, kIOSurfaceAllocSize, total_bytes);
add_int (props, kIOSurfaceBytesPerElement, bytes_per_element);
add_int (props, kIOSurfaceBytesPerRow, bytes_per_row);
add_int (props, kIOSurfaceHeight, height);
add_int (props, kIOSurfacePixelFormat, (int)'BGRA');
add_int (props, kIOSurfaceWidth, width);
ret = IOSurfaceCreate (props);
CFRelease (props);
*stride = bytes_per_row;
return ret;
}
GdkMacosBuffer *
_gdk_macos_buffer_new (int width,
int height,
double device_scale,
int bytes_per_element,
int bits_per_pixel)
{
GdkMacosBuffer *self;
g_return_val_if_fail (width > 0, NULL);
g_return_val_if_fail (height > 0, NULL);
self = g_object_new (GDK_TYPE_MACOS_BUFFER, NULL);
self->bytes_per_element = bytes_per_element;
self->bits_per_pixel = bits_per_pixel;
self->surface = create_surface (width, height, bytes_per_element, &self->stride);
self->width = width;
self->height = height;
self->device_scale = device_scale;
self->lock_count = 0;
if (self->surface == NULL)
g_clear_object (&self);
return self;
}
IOSurfaceRef
_gdk_macos_buffer_get_native (GdkMacosBuffer *self)
{
g_return_val_if_fail (GDK_IS_MACOS_BUFFER (self), NULL);
return self->surface;
}
/**
* _gdk_macos_buffer_lock:
*
* This function matches the IOSurfaceLock() name but what it really
* does is page the buffer back for the CPU to access from VRAM.
*
* Generally we don't want to do that, but we do need to in some
* cases such as when we are rendering with Cairo. There might
* be an opportunity later to avoid that, but since we are using
* GL pretty much everywhere already, we don't try.
*/
void
_gdk_macos_buffer_lock (GdkMacosBuffer *self)
{
g_return_if_fail (GDK_IS_MACOS_BUFFER (self));
g_return_if_fail (self->lock_count == 0);
self->lock_count++;
IOSurfaceLock (self->surface, 0, NULL);
}
void
_gdk_macos_buffer_unlock (GdkMacosBuffer *self)
{
g_return_if_fail (GDK_IS_MACOS_BUFFER (self));
g_return_if_fail (self->lock_count == 1);
self->lock_count--;
IOSurfaceUnlock (self->surface, 0, NULL);
}
/**
* _gdk_macos_buffer_lock_readonly:
*
* Like _gdk_macos_buffer_lock() but uses the read-only flag to
* indicate we are not interested in retrieving the updates from
* the GPU before modifying the CPU-side cache.
*
* Must be used with _gdk_macos_buffer_unlock_readonly().
*/
void
_gdk_macos_buffer_read_lock (GdkMacosBuffer *self)
{
kern_return_t ret;
g_return_if_fail (GDK_IS_MACOS_BUFFER (self));
g_return_if_fail (self->lock_count == 0);
self->lock_count++;
ret = IOSurfaceLock (self->surface, kIOSurfaceLockReadOnly, NULL);
g_return_if_fail (ret == KERN_SUCCESS);
}
void
_gdk_macos_buffer_read_unlock (GdkMacosBuffer *self)
{
kern_return_t ret;
g_return_if_fail (GDK_IS_MACOS_BUFFER (self));
g_return_if_fail (self->lock_count == 1);
self->lock_count--;
ret = IOSurfaceUnlock (self->surface, kIOSurfaceLockReadOnly, NULL);
g_return_if_fail (ret == KERN_SUCCESS);
}
guint
_gdk_macos_buffer_get_width (GdkMacosBuffer *self)
{
g_return_val_if_fail (GDK_IS_MACOS_BUFFER (self), 0);
return self->width;
}
guint
_gdk_macos_buffer_get_height (GdkMacosBuffer *self)
{
g_return_val_if_fail (GDK_IS_MACOS_BUFFER (self), 0);
return self->height;
}
guint
_gdk_macos_buffer_get_stride (GdkMacosBuffer *self)
{
g_return_val_if_fail (GDK_IS_MACOS_BUFFER (self), 0);
return self->stride;
}
double
_gdk_macos_buffer_get_device_scale (GdkMacosBuffer *self)
{
g_return_val_if_fail (GDK_IS_MACOS_BUFFER (self), 1.0);
return self->device_scale;
}
const cairo_region_t *
_gdk_macos_buffer_get_damage (GdkMacosBuffer *self)
{
g_return_val_if_fail (GDK_IS_MACOS_BUFFER (self), NULL);
return self->damage;
}
void
_gdk_macos_buffer_set_damage (GdkMacosBuffer *self,
cairo_region_t *damage)
{
g_return_if_fail (GDK_IS_MACOS_BUFFER (self));
if (damage == self->damage)
return;
g_clear_pointer (&self->damage, cairo_region_destroy);
self->damage = cairo_region_copy (damage);
}
gpointer
_gdk_macos_buffer_get_data (GdkMacosBuffer *self)
{
g_return_val_if_fail (GDK_IS_MACOS_BUFFER (self), NULL);
return IOSurfaceGetBaseAddress (self->surface);
}
gboolean
_gdk_macos_buffer_get_flipped (GdkMacosBuffer *self)
{
g_return_val_if_fail (GDK_IS_MACOS_BUFFER (self), FALSE);
return self->flipped;
}
void
_gdk_macos_buffer_set_flipped (GdkMacosBuffer *self,
gboolean flipped)
{
g_return_if_fail (GDK_IS_MACOS_BUFFER (self));
self->flipped = !!flipped;
}

View File

@@ -22,18 +22,17 @@
#include "gdkconfig.h"
#include <cairo.h>
#include <QuartzCore/QuartzCore.h>
#include <CoreGraphics/CoreGraphics.h>
#import "GdkMacosCairoView.h"
#include "gdkmacosbuffer-private.h"
#include "gdkmacoscairocontext-private.h"
#include "gdkmacossurface-private.h"
struct _GdkMacosCairoContext
{
GdkCairoContext parent_instance;
cairo_surface_t *window_surface;
GdkCairoContext parent_instance;
};
struct _GdkMacosCairoContextClass
@@ -43,41 +42,150 @@ struct _GdkMacosCairoContextClass
G_DEFINE_TYPE (GdkMacosCairoContext, _gdk_macos_cairo_context, GDK_TYPE_CAIRO_CONTEXT)
static cairo_surface_t *
create_cairo_surface_for_surface (GdkSurface *surface)
{
cairo_surface_t *cairo_surface;
int scale;
int width;
int height;
g_assert (GDK_IS_MACOS_SURFACE (surface));
scale = gdk_surface_get_scale_factor (surface);
width = scale * gdk_surface_get_width (surface);
height = scale * gdk_surface_get_height (surface);
/* We use a cairo image surface here instead of a quartz surface because we
* get strange artifacts with the quartz surface such as empty cross-fades
* when hovering buttons. For performance, we want to be using GL rendering
* so there isn't much point here as correctness is better.
*/
cairo_surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
if (cairo_surface != NULL)
cairo_surface_set_device_scale (cairo_surface, scale, scale);
return cairo_surface;
}
static cairo_t *
_gdk_macos_cairo_context_cairo_create (GdkCairoContext *cairo_context)
{
GdkMacosCairoContext *self = (GdkMacosCairoContext *)cairo_context;
const cairo_region_t *damage;
cairo_surface_t *image_surface;
GdkMacosBuffer *buffer;
GdkSurface *surface;
NSWindow *nswindow;
cairo_t *cr;
gpointer data;
double scale;
guint width;
guint height;
guint stride;
gboolean opaque;
g_assert (GDK_IS_MACOS_CAIRO_CONTEXT (self));
return cairo_create (self->window_surface);
surface = gdk_draw_context_get_surface (GDK_DRAW_CONTEXT (self));
nswindow = _gdk_macos_surface_get_native (GDK_MACOS_SURFACE (surface));
opaque = [nswindow isOpaque];
buffer = _gdk_macos_surface_get_buffer (GDK_MACOS_SURFACE (surface));
damage = _gdk_macos_buffer_get_damage (buffer);
width = _gdk_macos_buffer_get_width (buffer);
height = _gdk_macos_buffer_get_height (buffer);
scale = _gdk_macos_buffer_get_device_scale (buffer);
stride = _gdk_macos_buffer_get_stride (buffer);
data = _gdk_macos_buffer_get_data (buffer);
/* Instead of forcing cairo to do everything through a CGContext,
* we just use an image surface backed by an IOSurfaceRef mapped
* into user-space. We can then use pixman which is quite fast as
* far as software rendering goes.
*
* Additionally, cairo_quartz_surface_t can't handle a number of
* tricks that the GSK cairo renderer does with border nodes and
* shadows, so an image surface is necessary for that.
*
* Since our IOSurfaceRef is width*scale-by-height*scale, we undo
* the scaling using cairo_surface_set_device_scale() so the renderer
* just thinks it's on a 2x scale surface for HiDPI.
*/
image_surface = cairo_image_surface_create_for_data (data,
CAIRO_FORMAT_ARGB32,
width,
height,
stride);
cairo_surface_set_device_scale (image_surface, scale, scale);
/* The buffer should already be locked at this point, and will
* be unlocked as part of end_frame.
*/
if (!(cr = cairo_create (image_surface)))
goto failure;
/* Clip to the current damage region */
if (damage != NULL)
{
gdk_cairo_region (cr, damage);
cairo_clip (cr);
}
/* If we have some exposed transparent area in the damage region,
* we need to clear the existing content first to leave an transparent
* area for cairo. We use (surface_bounds or damage)-(opaque) to get
* the smallest set of rectangles we need to clear as it's expensive.
*/
if (!opaque)
{
cairo_region_t *transparent;
cairo_rectangle_int_t r = { 0, 0, width/scale, height/scale };
cairo_save (cr);
if (damage != NULL)
cairo_region_get_extents (damage, &r);
transparent = cairo_region_create_rectangle (&r);
if (surface->opaque_region)
cairo_region_subtract (transparent, surface->opaque_region);
if (!cairo_region_is_empty (transparent))
{
gdk_cairo_region (cr, transparent);
cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
cairo_fill (cr);
}
cairo_region_destroy (transparent);
cairo_restore (cr);
}
failure:
cairo_surface_destroy (image_surface);
return cr;
}
static void
copy_surface_data (GdkMacosBuffer *from,
GdkMacosBuffer *to,
const cairo_region_t *region,
int scale)
{
const guint8 *from_base;
guint8 *to_base;
guint from_stride;
guint to_stride;
guint n_rects;
g_assert (GDK_IS_MACOS_BUFFER (from));
g_assert (GDK_IS_MACOS_BUFFER (to));
g_assert (region != NULL);
g_assert (!cairo_region_is_empty (region));
from_base = _gdk_macos_buffer_get_data (from);
from_stride = _gdk_macos_buffer_get_stride (from);
to_base = _gdk_macos_buffer_get_data (to);
to_stride = _gdk_macos_buffer_get_stride (to);
n_rects = cairo_region_num_rectangles (region);
for (guint i = 0; i < n_rects; i++)
{
cairo_rectangle_int_t rect;
int y2;
cairo_region_get_rectangle (region, i, &rect);
rect.y *= scale;
rect.height *= scale;
rect.x *= scale;
rect.width *= scale;
y2 = rect.y + rect.height;
for (int y = rect.y; y < y2; y++)
memcpy (&to_base[y * to_stride + rect.x * 4],
&from_base[y * from_stride + rect.x * 4],
rect.width * 4);
}
}
static void
@@ -86,28 +194,49 @@ _gdk_macos_cairo_context_begin_frame (GdkDrawContext *draw_context,
cairo_region_t *region)
{
GdkMacosCairoContext *self = (GdkMacosCairoContext *)draw_context;
GdkSurface *surface;
NSWindow *nswindow;
GdkMacosBuffer *buffer;
GdkMacosSurface *surface;
g_assert (GDK_IS_MACOS_CAIRO_CONTEXT (self));
surface = gdk_draw_context_get_surface (draw_context);
nswindow = _gdk_macos_surface_get_native (GDK_MACOS_SURFACE (surface));
[CATransaction begin];
[CATransaction setDisableActions:YES];
if (self->window_surface == NULL)
surface = GDK_MACOS_SURFACE (gdk_draw_context_get_surface (draw_context));
buffer = _gdk_macos_surface_get_buffer (surface);
_gdk_macos_buffer_set_damage (buffer, region);
_gdk_macos_buffer_set_flipped (buffer, FALSE);
_gdk_macos_buffer_lock (buffer);
/* If there is damage that was on the previous frame that is not on
* this frame, we need to copy that rendered region over to the back
* buffer so that when swapping buffers, we still have that content.
* This is done with a read-only lock on the IOSurface to avoid
* invalidating the buffer contents.
*/
if (surface->front != NULL)
{
self->window_surface = create_cairo_surface_for_surface (surface);
}
else
{
if (![nswindow isOpaque])
const cairo_region_t *previous = _gdk_macos_buffer_get_damage (surface->front);
if (previous != NULL)
{
cairo_t *cr = cairo_create (self->window_surface);
gdk_cairo_region (cr, region);
cairo_set_source_rgba (cr, 0, 0, 0, 0);
cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
cairo_fill (cr);
cairo_destroy (cr);
cairo_region_t *copy;
copy = cairo_region_copy (previous);
cairo_region_subtract (copy, region);
if (!cairo_region_is_empty (copy))
{
int scale = gdk_surface_get_scale_factor (GDK_SURFACE (surface));
_gdk_macos_buffer_read_lock (surface->front);
copy_surface_data (surface->front, buffer, copy, scale);
_gdk_macos_buffer_read_unlock (surface->front);
}
cairo_region_destroy (copy);
}
}
}
@@ -117,28 +246,27 @@ _gdk_macos_cairo_context_end_frame (GdkDrawContext *draw_context,
cairo_region_t *painted)
{
GdkMacosCairoContext *self = (GdkMacosCairoContext *)draw_context;
GdkSurface *surface;
NSView *nsview;
GdkMacosSurface *surface;
GdkMacosBuffer *buffer;
g_assert (GDK_IS_MACOS_CAIRO_CONTEXT (self));
g_assert (self->window_surface != NULL);
surface = gdk_draw_context_get_surface (draw_context);
nsview = _gdk_macos_surface_get_view (GDK_MACOS_SURFACE (surface));
surface = GDK_MACOS_SURFACE (gdk_draw_context_get_surface (draw_context));
buffer = _gdk_macos_surface_get_buffer (surface);
if (GDK_IS_MACOS_CAIRO_VIEW (nsview))
[(GdkMacosCairoView *)nsview setCairoSurface:self->window_surface
withDamage:painted];
_gdk_macos_buffer_unlock (buffer);
_gdk_macos_surface_swap_buffers (surface, painted);
[CATransaction commit];
}
static void
_gdk_macos_cairo_context_surface_resized (GdkDrawContext *draw_context)
{
GdkMacosCairoContext *self = (GdkMacosCairoContext *)draw_context;
g_assert (GDK_IS_MACOS_CAIRO_CONTEXT (draw_context));
g_assert (GDK_IS_MACOS_CAIRO_CONTEXT (self));
g_clear_pointer (&self->window_surface, cairo_surface_destroy);
/* Do nothing, next begin_frame will get new buffer */
}
static void

View File

@@ -0,0 +1,105 @@
/*
* Copyright © 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.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*/
#include "config.h"
#include <AppKit/AppKit.h>
#include "gdkmacosdisplay-private.h"
#include "gdkmacossurface-private.h"
static void
gdk_macos_display_user_defaults_changed_cb (CFNotificationCenterRef center,
void *observer,
CFStringRef name,
const void *object,
CFDictionaryRef userInfo)
{
GdkMacosDisplay *self = observer;
g_assert (GDK_IS_MACOS_DISPLAY (self));
_gdk_macos_display_reload_settings (self);
}
static void
gdk_macos_display_monitors_changed_cb (CFNotificationCenterRef center,
void *observer,
CFStringRef name,
const void *object,
CFDictionaryRef userInfo)
{
GdkMacosDisplay *self = observer;
g_assert (GDK_IS_MACOS_DISPLAY (self));
_gdk_macos_display_reload_monitors (self);
/* Now we need to update all our surface positions since they
* probably just changed origins.
*/
for (const GList *iter = _gdk_macos_display_get_surfaces (self);
iter != NULL;
iter = iter->next)
{
GdkMacosSurface *surface = iter->data;
g_assert (GDK_IS_MACOS_SURFACE (surface));
_gdk_macos_surface_monitor_changed (surface);
}
}
void
_gdk_macos_display_feedback_init (GdkMacosDisplay *self)
{
g_return_if_fail (GDK_IS_MACOS_DISPLAY (self));
CFNotificationCenterAddObserver (CFNotificationCenterGetLocalCenter (),
self,
gdk_macos_display_monitors_changed_cb,
CFSTR ("NSApplicationDidChangeScreenParametersNotification"),
NULL,
CFNotificationSuspensionBehaviorDeliverImmediately);
CFNotificationCenterAddObserver (CFNotificationCenterGetDistributedCenter (),
self,
gdk_macos_display_user_defaults_changed_cb,
CFSTR ("NSUserDefaultsDidChangeNotification"),
NULL,
CFNotificationSuspensionBehaviorDeliverImmediately);
}
void
_gdk_macos_display_feedback_destroy (GdkMacosDisplay *self)
{
g_return_if_fail (GDK_IS_MACOS_DISPLAY (self));
CFNotificationCenterRemoveObserver (CFNotificationCenterGetDistributedCenter (),
self,
CFSTR ("NSApplicationDidChangeScreenParametersNotification"),
NULL);
CFNotificationCenterRemoveObserver (CFNotificationCenterGetDistributedCenter (),
self,
CFSTR ("NSUserDefaultsDidChangeNotification"),
NULL);
}

View File

@@ -43,6 +43,8 @@ G_BEGIN_DECLS
#define GIC_FILTER_PASSTHRU 0
#define GIC_FILTER_FILTERED 1
#define GDK_MACOS_EVENT_DROP (GdkEvent *)GSIZE_TO_POINTER(1)
struct _GdkMacosDisplay
{
GdkDisplay parent_instance;
@@ -68,16 +70,6 @@ struct _GdkMacosDisplay
*/
GQueue sorted_surfaces;
/* Our CVDisplayLink based GSource which we use to freeze/thaw the
* GdkFrameClock for the surface.
*/
GSource *frame_source;
/* A queue of surfaces which we know are awaiting frames to be drawn. This
* uses the GdkMacosSurface.frame link.
*/
GQueue awaiting_frames;
/* The surface that is receiving keyboard events */
GdkMacosSurface *keyboard_surface;
@@ -92,6 +84,14 @@ struct _GdkMacosDisplay
int min_y;
int max_x;
int max_y;
/* A GSource to select a new main/key window */
guint select_key_in_idle;
/* Note if we have a key window that is not a GdkMacosWindow
* such as a NSPanel used for native dialogs.
*/
guint key_window_is_foregin : 1;
};
struct _GdkMacosDisplayClass
@@ -124,6 +124,8 @@ GdkMonitor *_gdk_macos_display_get_monitor_at_display_coords (GdkMacosDisp
int y);
GdkEvent *_gdk_macos_display_translate (GdkMacosDisplay *self,
NSEvent *event);
void _gdk_macos_display_feedback_init (GdkMacosDisplay *self);
void _gdk_macos_display_feedback_destroy (GdkMacosDisplay *self);
void _gdk_macos_display_break_all_grabs (GdkMacosDisplay *self,
guint32 time);
GdkModifierType _gdk_macos_display_get_current_keyboard_modifiers (GdkMacosDisplay *self);
@@ -136,10 +138,6 @@ GdkMacosSurface *_gdk_macos_display_get_surface_at_display_coords (GdkMacosDisp
void _gdk_macos_display_reload_monitors (GdkMacosDisplay *self);
void _gdk_macos_display_surface_removed (GdkMacosDisplay *self,
GdkMacosSurface *surface);
void _gdk_macos_display_add_frame_callback (GdkMacosDisplay *self,
GdkMacosSurface *surface);
void _gdk_macos_display_remove_frame_callback (GdkMacosDisplay *self,
GdkMacosSurface *surface);
NSWindow *_gdk_macos_display_find_native_under_pointer (GdkMacosDisplay *self,
int *x,
int *y);
@@ -155,7 +153,6 @@ void _gdk_macos_display_surface_resigned_key (GdkMacosDisp
GdkMacosSurface *surface);
void _gdk_macos_display_surface_became_key (GdkMacosDisplay *self,
GdkMacosSurface *surface);
int _gdk_macos_display_get_nominal_refresh_rate (GdkMacosDisplay *self);
void _gdk_macos_display_clear_sorting (GdkMacosDisplay *self);
const GList *_gdk_macos_display_get_surfaces (GdkMacosDisplay *self);
void _gdk_macos_display_send_button_event (GdkMacosDisplay *self,
@@ -174,6 +171,10 @@ void _gdk_macos_display_set_drag (GdkMacosDisp
void _gdk_macos_display_set_drop (GdkMacosDisplay *self,
NSInteger sequence_number,
GdkDrop *drop);
void _gdk_macos_display_position_surface (GdkMacosDisplay *self,
GdkMacosSurface *surface,
int *x,
int *y);
G_END_DECLS

View File

@@ -34,7 +34,7 @@ typedef struct
const char *font_name;
int xft_dpi;
int double_click_time;
int cursor_blink_timeout;
int cursor_blink_time;
guint enable_animations : 1;
guint shell_shows_desktop : 1;
guint shell_shows_menubar : 1;
@@ -65,9 +65,9 @@ _gdk_macos_settings_load (GdkMacosSettings *settings)
ival = [defaults integerForKey:@"NSTextInsertionPointBlinkPeriod"];
if (ival > 0)
settings->cursor_blink_timeout = ival;
settings->cursor_blink_time = ival;
else
settings->cursor_blink_timeout = 1000;
settings->cursor_blink_time = 1000;
settings->primary_button_warps_slider =
[[NSUserDefaults standardUserDefaults] boolForKey:@"AppleScrollerPagingBehavior"] == YES;
@@ -124,9 +124,9 @@ _gdk_macos_display_get_setting (GdkMacosDisplay *self,
g_value_set_int (value, current_settings.xft_dpi);
ret = TRUE;
}
else if (strcmp (setting, "gtk-cursor-blink-timeout") == 0)
else if (strcmp (setting, "gtk-cursor-blink-time") == 0)
{
g_value_set_int (value, current_settings.cursor_blink_timeout);
g_value_set_int (value, current_settings.cursor_blink_time);
ret = TRUE;
}
else if (strcmp (setting, "gtk-double-click-time") == 0)

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