Compare commits

..

420 Commits

Author SHA1 Message Date
Matthias Clasen 16c3d4b236 Add gsk vulkan tests
Add a testsuite called gsk-compare-vulkan to run
the gsk renderer tests with the Vulkan renderer.

The current stats:

Ok:                 184
Expected Fail:      0
Fail:               204
Unexpected Pass:    0
Skipped:            2
Timeout:            0

For now, we mark all the tests as failing to
avoid ci breakage. To run the tests locally,
you can do:

meson test -C_build --suite gsk-compare-vulkan
2023-05-07 07:42:20 -04:00
Matthias Clasen df93875c0c Merge branch 'matthiasc/for-main' into 'main'
rendernodeparser: Handle shader nodes better

See merge request GNOME/gtk!5930
2023-05-07 00:58:05 +00:00
Matthias Clasen 5a156e6b5f rendernodeparser: Handle shader nodes better
Avoid criticals when editing shader nodes in
the node editor.
2023-05-06 14:33:45 -04:00
Matthias Clasen 0e488b3dfe Merge branch 'headless-test-logging' into 'main'
ci: Improve headless test logging

See merge request GNOME/gtk!5929
2023-05-06 13:28:06 +00:00
Matthias Clasen 8495e0e412 Add a test for quick key events 2023-05-06 09:09:13 -04:00
Matthias Clasen c9b0ca0de7 ci: Improve headless test logging 2023-05-06 09:02:25 -04:00
Benjamin Otte 2a950dec71 Merge branch 'wip/otte/update-texture' into 'main'
Add texture update regions

See merge request GNOME/gtk!5880
2023-05-06 00:59:25 +00:00
Matthias Clasen d6c80d4f35 Merge branch 'tiled-states' into 'main'
Fix a corner-case in window states

Closes #5809

See merge request GNOME/gtk!5926
2023-05-05 23:58:08 +00:00
Matthias Clasen e41cc99474 Merge branch 'wip/kabus/column-id-leak' into 'main'
gtk/columnviewcolumn: Fix id leak

See merge request GNOME/gtk!5927
2023-05-05 23:55:34 +00:00
Matthias Clasen 61fe5ac684 Handle the opposite case too
Just in case.
2023-05-05 19:40:42 -04:00
Khalid Abu Shawarib 1cf3f492b8 gtk/columnviewcolumn: Fix id leak
Add a free that was missing in commit 3e2b962a
2023-05-05 22:18:16 +00:00
Matthias Clasen 54fed96f8c Fix a corner-case in window states
Remove detailed tiled states when not tiled.

Fixes: #5809
2023-05-05 16:47:43 -04:00
Matthias Clasen e2d659d5c2 Merge branch 'matthiasc/for-main' into 'main'
ci: Bump timeouts for headless tests

See merge request GNOME/gtk!5925
2023-05-05 20:34:39 +00:00
Matthias Clasen 8ad1189b0b ci: Bump timeouts for headless tests 2023-05-05 16:21:54 -04:00
Matthias Clasen b5b7e1f2b4 Merge branch 'matthiasc/for-main' into 'main'
Add a masked variation to gsk tests

See merge request GNOME/gtk!5924
2023-05-05 20:12:12 +00:00
Matthias Clasen e56a539363 Add a masked variation to gsk tests
This improves test coverage for mask nodes.
2023-05-05 15:05:08 -04:00
Matthias Clasen 5f91bb81ed Merge branch 'matthiasc/for-main' into 'main'
node-editor: Be a bit better about saving

See merge request GNOME/gtk!5923
2023-05-05 18:50:16 +00:00
Matthias Clasen 1fba59f1d1 node-editor: Be a bit better about saving
When we have a file, suggest it for saving.
This has the side benefit of giving us a test case
for gtk_file_dialog_set_initial_file.
2023-05-05 14:18:40 -04:00
Matthias Clasen 68a2ca7e85 Merge branch 'matthiasc/for-main' into 'main'
gsk: Add a few assertions

See merge request GNOME/gtk!5922
2023-05-05 17:48:14 +00:00
Matthias Clasen 93ccf08c81 ci: Bump timeouts of headless tests 2023-05-05 12:05:10 -04:00
Matthias Clasen e9f5a3e9e2 gsk: Introduce a constant
We need this number in a couple of places,
so pull it out as a constant.
2023-05-05 12:05:10 -04:00
Matthias Clasen 2b85c49fb1 gsk: Add a few assertions
Make sure we don't overflow our fixed-size arrays.
2023-05-05 12:05:10 -04:00
Matthias Clasen d7c3235cd0 gsk: Add some debug helpers 2023-05-05 12:05:09 -04:00
Matthias Clasen ea94bac79e Merge branch 'better-masks' into 'main'
gsk: Avoid some offscreens

See merge request GNOME/gtk!5921
2023-05-05 15:56:16 +00:00
Matthias Clasen 63713c3b68 Merge branch 'fix-typo' into 'main'
gtkapplication-quartz: fix typo

Closes #5807

See merge request GNOME/gtk!5920
2023-05-05 15:39:46 +00:00
Matthias Clasen 81fd9741ff gsk: Better handling of offscreens
Take the scale into account for sizing the
offscreens for masks, blends and cross-fades.
2023-05-05 11:37:23 -04:00
Luca Bacci c7523cecf1 gtkapplication-quartz: fix typo
Fixes #5807
2023-05-05 16:26:26 +02:00
Matthias Clasen ce6569d1a6 gsk: Avoid some offscreens
We don't have to be too conservative when checking
if a rect is contained in a rounded rect, we have
a precise api for this.
2023-05-04 22:30:12 -04:00
Matthias Clasen 852f46df19 Remove a no longer building test 2023-05-04 20:53:15 -04:00
Matthias Clasen d82f603fcb Merge branch 'smalltexture-plus-gles' into 'main'
Merge wayland_smalltexture and wayland_gles

See merge request GNOME/gtk!5917
2023-05-04 21:12:40 +00:00
Matthias Clasen 5e8e4130a5 Skip another failing gsk test with small textures 2023-05-04 15:36:57 -04:00
Matthias Clasen f81aa14d93 Merge wayland_smalltexture and wayland_gles
We don't really need to have two full separate
test runs for these conditions, so combine them
into one test setup.
2023-05-04 15:13:09 -04:00
Matthias Clasen 81db6e9e61 Merge branch 'headless-tests' into 'main'
Get the headless monitor test to work in ci

See merge request GNOME/gtk!5915
2023-05-04 15:51:21 +00:00
Matthias Clasen ac0311b621 ci: Mark headless monitor test as working 2023-05-04 11:39:35 -04:00
Matthias Clasen f41e58d179 ci: Make run-docker run work
We want to have a writable volume and the same user
inside the container.
2023-05-04 11:38:55 -04:00
Matthias Clasen d288931b45 More debug spew
Lets see what MUTTER_DEBUG=screen-cast says.
2023-05-04 11:38:55 -04:00
Matthias Clasen 03adeecfa3 Add generous waits
These tests work in the smae container locally.
Perhaps this is down to timing?
2023-05-04 11:38:55 -04:00
Matthias Clasen 5439f4596c Merge branch 'headless-tests' into 'main'
Add headless tests using mutter

See merge request GNOME/gtk!5908
2023-05-04 04:20:11 +00:00
Matthias Clasen f98d1a6474 Mark the headless monitor test as failing
This is failing because I can't figure out
how to make wireplumber and pipewire work
in ci enough to let me add a new monitor :(

As usual, the test works fine locally.
2023-05-03 23:53:14 -04:00
Matthias Clasen 57e6aae80a Try to fix dnd tests 2023-05-03 23:27:09 -04:00
Matthias Clasen f23eaafc85 Typo fix 2023-05-03 23:27:09 -04:00
Matthias Clasen 926b26e9fc headless tests: Add debug spew
Trying to track down what is going on with our
missing monitors.
2023-05-03 23:27:09 -04:00
Matthias Clasen 88f27c423c ci: Launch pipewire and wireplumber
The headless tests require pipewire and wireplumber
for screencast sessions to work. So launch them.
2023-05-03 23:27:09 -04:00
Matthias Clasen 30342896d0 Use python3
No /usr/bin/python in our CI image :(
2023-05-03 23:27:09 -04:00
Matthias Clasen be8e203edc Make the headless input tests work
These needed some updates and workarounds.

They are now part of the testsuite and can
be run like this:

    meson test -Cbuild --suite headless
2023-05-03 23:27:09 -04:00
Matthias Clasen 623c93ccc8 Disable a11y for the headless tests
Otherwise, we go off activating things and end up
failing to launch systemd.
2023-05-03 23:27:09 -04:00
Matthias Clasen 34d8beaf4f Add a dnd test to the headless tests 2023-05-03 23:27:09 -04:00
Matthias Clasen 983b6ce341 Use headless mutter for input tests
Add some input tests that are using headless
mutter, and python with our in-tree gir files.

So far, test that we can roundtrip key events,
and move the pointer around.
2023-05-03 23:27:09 -04:00
Matthias Clasen 771df47820 Use headless mutter for monitor tests
Add some monitor tests that are using headless
mutter, and python with our in-tree gir files.

So far, we test that we get expected signals
when monitors are added and removed.
2023-05-03 23:27:09 -04:00
Matthias Clasen 3c218687e3 Merge branch 'ci-update-meson' into 'main'
ci: Use newer meson

See merge request GNOME/gtk!5914
2023-05-04 02:57:23 +00:00
Matthias Clasen 37fb370a5d ci: Remove the hack 2023-05-03 22:32:00 -04:00
Matthias Clasen 1cc9413383 ci: Use newer meson 2023-05-03 20:18:58 -04:00
Matthias Clasen bfea39ab2f ci: Add meson back to the fedora image 2023-05-03 20:18:58 -04:00
Matthias Clasen 84d6f023b5 ci: Add pipewire-gstreamer too 2023-05-03 20:18:58 -04:00
Matthias Clasen 7fe04a7122 ci: Add pipewire to the image
And its buddy, wireplumber.

But we don't need gnome-desktop-testing
anymore, now that installed tests are gone.
2023-05-03 20:18:58 -04:00
Matthias Clasen 19cea99007 Merge branch 'matthiasc/for-main' into 'main'
ci: Stop running failing tests

See merge request GNOME/gtk!5913
2023-05-03 19:54:24 +00:00
Matthias Clasen 1c4ad78d52 Merge branch 'stop-running-failing-tests' into 'main'
ci: Stop running failing tests

See merge request GNOME/gtk!5912
2023-05-03 19:33:35 +00:00
Matthias Clasen 955a7e643e ci: Produce less terminal output
Pass --quiet to meson test.
Less is more, in this case.
2023-05-03 15:32:50 -04:00
Matthias Clasen b85a137a68 Fix scan-build warning 2023-05-03 15:32:19 -04:00
Matthias Clasen d17ca6b451 ci: Stop running the unstable test setups
This is just duplicating all our test runs,
for no discernible gain.
2023-05-03 15:11:53 -04:00
Matthias Clasen da7040874e ci: Stop running failing tests
This makes the test output much harder to read,
and is just a waste of time.
2023-05-03 14:42:10 -04:00
Danial Behzadi 6f9c4c894d Update Persian translation
(cherry picked from commit 954011ef80)
2023-05-03 09:01:04 +00:00
Benjamin Otte cc7a35cd30 Merge branch 'wip/otte/for-main' into 'main'
build: Use generated SPIR-V files

Closes #5798

See merge request GNOME/gtk!5910
2023-05-02 18:09:13 +00:00
Benjamin Otte f841621348 css: Don't transition to currentColor
Transition to the color that is in use instead.

Fixes crashes because currentColor is not an RGBA color and
therefor could not be queried later.

Fixes #5798
2023-05-02 19:50:31 +02:00
Benjamin Otte f99ecd3739 vulkan: Compute offscreen texture coords properly
Most of the time we want to compute them based on the child node we
render to the offscreen, but not always.
For blend and cross-fade nodes, they need to be computed based on the
node's bounds.

Fixes widget-factory page fade animation weirdly resizing the fading
pages.
2023-05-02 19:44:06 +02:00
Matthias Clasen 5eb7e550d1 Merge branch 'matthiasc/for-main' into 'main'
Expand gtk_init docs

Closes #5781

See merge request GNOME/gtk!5909
2023-05-02 17:42:29 +00:00
Matthias Clasen 8d33f2a511 Add a comment to pango.wrap
So we remember the next time we try to
switch to stable dependencies.
2023-05-02 13:18:49 -04:00
Matthias Clasen 27b0321dec Expand gtk_init docs
Make it clear that some aspects of GApplication
functionality happen before startup.

Fixes: #5781
2023-05-02 13:18:49 -04:00
Matthias Clasen 538605eccb Merge branch 'matthiasc/for-main' into 'main'
Don't build fribidi docs

See merge request GNOME/gtk!5906
2023-05-02 13:29:20 +00:00
Matthias Clasen 81f5967587 Make run-test.sh easier to use locally
Set a default timeout multiplier so we don't
have to rememver obscure environment variables.
2023-05-02 06:38:30 -04:00
Matthias Clasen 771437acf9 Go back to fribidi master
Fribidi 1.0.12 does not work as a subproject :(
2023-05-02 06:22:44 -04:00
Matthias Clasen a3da58133e Don't build fribidi docs
There's no need for that. This matches what pango does.
2023-05-02 06:22:24 -04:00
Benjamin Otte 9b558b50b8 vulkan: Rebuild SPIR-V files
It's been a while since somebody last compiled them, glslc should be
somewhat newer by now.
2023-05-02 08:47:10 +02:00
Benjamin Otte 7ce2eeac47 build: Use generated SPIR-V files
We weren't looking in the build dir for generated files.

Actually make sure that we look in the build dir *first*, otherwise
glib-compile-resources will still use the wrong files.
2023-05-02 08:41:43 +02:00
Matthias Clasen 182dccb8f0 Use pango main as subproject
This is necessary to get the latest pango docs
built in ci.
2023-05-01 23:55:21 -04:00
Matthias Clasen 17d2ba94d6 stop using deprecated pango api 2023-05-01 23:49:42 -04:00
Matthias Clasen 5bac4f13a0 ci: Add mutter to the fedora image
This is in preparation for trying to use mutter --headless
in ci.
2023-05-01 21:11:01 -04:00
Benjamin Otte 97aff588d5 TEST TEST TEST
Add some random updates to the GL Area, so that funky testing can be
done with the GLArea and Gears gtk-demo.
2023-05-02 00:30:58 +02:00
Benjamin Otte e4040adbe7 rendernode: Implement texture diffing for scale nodes 2023-05-02 00:30:58 +02:00
Benjamin Otte 6506a3bc9c texturebuilder: Add ::udpate-region and ::update-texture 2023-05-02 00:30:58 +02:00
Matthias Clasen 64f9d82506 Merge branch 'gsk-flip-tests' into 'main'
more gsk tests

See merge request GNOME/gtk!5811
2023-05-01 21:06:32 +00:00
Matthias Clasen b83f3d871f Merge branch 'matthiasc/for-main' into 'main'
Cosmetics: Unset baseline too

See merge request GNOME/gtk!5904
2023-05-01 20:41:13 +00:00
Matthias Clasen a235b59089 Skip some tests with small textures
When textures are too large, we will scale them down
to fit the max texture size, which will cause comparisons
to fail.
2023-05-01 16:29:45 -04:00
Benjamin Otte 1883035d34 texture: Add gdk_texture_diff()
... and use it in rendernodes.

Setting up textures for diffing is done via gdk_texture_set_diff() which
should only be used during texture construction.

Note that the pointers to next/previous are allowed to dangle if one of
the textures is finalized, but that's fine because we always check both
textures' links to each other before we consider the pointer valid.
2023-05-01 22:24:14 +02:00
Matthias Clasen 0ca6471df4 Cosmetics: Unset baseline too
We set width and height to 0 when unrealizing
a widget. No reason to let the baseline value
linger.
2023-05-01 16:15:11 -04:00
Matthias Clasen 98dde97f20 Merge branch 'better-switch-docs' into 'main'
switch: Expand the docs

See merge request GNOME/gtk!5903
2023-05-01 20:03:44 +00:00
Matthias Clasen 9bd9847b3f switch: Expand the docs
Add more text and explanation around active vs state,
since people seem easily confused by it.
2023-05-01 15:15:53 -04:00
Matthias Clasen b79d4a3a22 gsk: Fix rendering big textures with offsets
When slicing the texture, the GL renderer was
forgetting to apply the viewport origin. This
shows up when rendering things with negative
scales, leading to negative origins.
2023-05-01 14:46:30 -04:00
Matthias Clasen 33ab588d4e Improve test coverage
Check that our two rounded rect intersection functions agree.
2023-05-01 13:58:42 -04:00
Matthias Clasen 7200a93a88 gsk: Give up on one test
The rounded-clip-in-clip-3d test fails in GL when
flipped. Given that it was already excluded from cairo,
and also fails cairo when flipped, give up on it for now.
2023-05-01 13:45:20 -04:00
Matthias Clasen 319762b908 gsk: Extract scales properly from 2D transforms
We have the code to do it properly.
2023-05-01 13:45:20 -04:00
Matthias Clasen e453a989df Improve rounded rect intersection
Move the rounded rect/rect intersection code to
gskroundedrect.c, make it more precise, and add
tests for it.

Update the callers in the GL renderer.
2023-05-01 13:45:20 -04:00
Matthias Clasen f56328a6cc gsk: Fix mask transform handling
We must reset the modelview transform when
offscreen, or else we end up applying
it twice.
2023-05-01 13:45:20 -04:00
Matthias Clasen f29b24517e Add a test for rotated blend nodes 2023-05-01 13:45:20 -04:00
Matthias Clasen 552df197c4 gsk: Fix blend transform handling
We must reset the modelview transform when
rendering offscreen, or else we end up applying
it twice.
2023-05-01 13:45:20 -04:00
Matthias Clasen f6e47b7eb0 Add a test for rotated cross-fade nodes
This one checks that we don't apply the modelview
transform twice with cross-fades.
2023-05-01 13:45:13 -04:00
Matthias Clasen 4214067d52 gsk: Fix cross-fade transform handling
We must reset the modelview transform when
rendering offscreen, or else we end up applying
it twice.
2023-05-01 13:44:55 -04:00
Matthias Clasen d9a2b74b4a gsk: More fixes
Work towards handling negative scales and
denormalized rects everywhere.
2023-05-01 13:43:33 -04:00
Matthias Clasen 21df62f428 Add another test 2023-05-01 13:43:33 -04:00
Matthias Clasen 4e501d2d44 gsk: Transform rounded rects better 2023-05-01 13:43:33 -04:00
Matthias Clasen 5afd5cfec7 Add another gsk test 2023-05-01 13:43:33 -04:00
Matthias Clasen ad65db901a gsk: Normalize rects in GLSL
Our coverage computation only works for well-behaved
rects and rounded rects. But our modelview transform
might flip x or y around, causing things to fail.

Add functions to normalize rects and rounded rects,
and use it whenever we transform a rounded rect in GLSL.
2023-05-01 13:43:33 -04:00
Matthias Clasen 406b1e2e03 testsuite: Fix gsk test
The repeated tests were not careful enough to produce
the correct reference image to match what the repeat
node does.

With these changes, all cairo tests pass.
2023-05-01 13:43:33 -04:00
Matthias Clasen f1729affa8 testsuite: Add more gsk tests
Add separate suites for running the gsk compare-render
tests with the --flip, --rotate or --repeat options.
A bunch of these fail currently, and need diagnosis.
2023-05-01 13:35:35 -04:00
Matthias Clasen 3b2ba8ed99 Add more gsk tests
Add options to the gsk compare-render test for
modifying the node (and do a matching change to
the reference image).

flip: negative scale flipping things horizontally
rotate: 90 degree rotation
repeat: 2x2 grid
2023-05-01 13:35:35 -04:00
Matthias Clasen 386c3ac34f Add another transform test
Test that transforming bounds with negative scales
works as expected.
2023-05-01 13:35:22 -04:00
Matthias Clasen d92c6406d1 Merge branch 'displaymanager-warning-fix' into 'main'
Avoid a bad warning

See merge request GNOME/gtk!5901
2023-05-01 16:56:40 +00:00
Matthias Clasen d666f4ab7f Avoid a bad warning
This isn't what we intended, and it breaks CI for
various projects.
2023-05-01 10:40:26 -04:00
Georges Basile Stavracas Neto 5df360f436 Merge branch 'alatiera/vulkan-headers-fix' into 'main'
vulkan: Correct error enum version guards

See merge request GNOME/gtk!5900
2023-05-01 14:00:43 +00:00
Jordan Petridis 0197149ba3 vulkan: Correct error enum version guards
Vulkan 218 introduced these errors by they were marked as
the beta till version 238.

https://github.com/KhronosGroup/Vulkan-Headers/commit/00671c64ba5c488ade22ad572a0ef81d5e64c803#diff-e222ae95c2b0d5082b94d6086fb1c24da18ee31384c1a39840df3b9152023ee6

Followup to f9b2d3104a
2023-05-01 09:41:35 +03:00
Matthias Clasen b310ab7304 Merge branch 'matthiasc/for-main' into 'main'
docs: Migration guide updates

See merge request GNOME/gtk!5899
2023-04-30 22:39:57 +00:00
Matthias Clasen 062e3da57d Merge branch 'emojichooser-variation-fix' into 'main'
emojichooser: Avoid extraneous variation selectors

See merge request GNOME/gtk!5898
2023-04-30 22:29:11 +00:00
Matthias Clasen cdbd931dba docs: Migration guide updates
Mention various widget size apis going away.
2023-04-30 18:21:46 -04:00
Matthias Clasen 2f96a08b3f gsk: Plug a few memory leaks 2023-04-30 18:21:23 -04:00
Matthias Clasen c1fc6c35cf emojichooser: Avoid extraneous variation selectors
Only add a variation selector if there isn't one already.
2023-04-30 11:56:43 -04:00
Daniel Boles 060992aeba migrating-3to4: Fix unescaped ptr * used as italic 2023-04-30 16:55:31 +01:00
Daniel Boles 2c15d563e2 gtk-demo/listbox: Fix 0 space between nick & date,
by restoring the right-alignment that gtk-3-24 has here, but we had lost
– I guess because we dropped the default child expand and pack-end props
2023-04-30 16:39:16 +01:00
Daniel Boles 2dd7ab2a50 Inscription|InfoBar: Fix small cosmetic issue@docs 2023-04-30 16:05:11 +01:00
Daniel Boles 0736fef585 Merge branch 'dboles/expander-css-nodes-doc' into 'main'
Expander: Clarify/format “CSS nodes” documentation

See merge request GNOME/gtk!5896
2023-04-30 11:37:55 +00:00
Daniel Boles 0442fc2b55 Expander: Clarify/format CSS nodes documentation
Use backticks to highlight the node names, mention the box, and clarify
that the arrow referred to in the last sentence is the `expander` node.
2023-04-30 11:56:07 +01:00
Matthias Clasen 27c621695e Merge branch 'deprecated-get-allocated-width' into 'main'
Deprecated get allocated width

See merge request GNOME/gtk!5894
2023-04-29 18:55:45 +00:00
Matthias Clasen 1a237ef6a8 Merge branch 'box-baseline-child' into 'main'
boxlayout: Add a baseline child property

See merge request GNOME/gtk!5891
2023-04-29 18:30:59 +00:00
Matthias Clasen e7ba8e7e9a Deprecate gtk_widget_get_allocated_width 2023-04-29 14:30:21 -04:00
Matthias Clasen 14279785e6 tests: Stop using gtk_widget_get_allocated_width 2023-04-29 14:30:21 -04:00
Matthias Clasen 5b6f8d7002 gtk4-demo: Stop using gtk_widget_get_allocated_size 2023-04-29 14:30:21 -04:00
Matthias Clasen 71a752490a popover: Stop using gtk_widget_get_allocated_width 2023-04-29 14:30:21 -04:00
Matthias Clasen 3f4f37661c placesview: Stop using gtk_widget_get_allocated_width 2023-04-29 14:30:21 -04:00
Matthias Clasen 5bc5a6f2cd placessidebar: Stop using gtk_widget_get_allocated_width 2023-04-29 14:30:21 -04:00
Matthias Clasen 1a90724de9 columnview: Stop using gtk_widget_get_allocated_width 2023-04-29 14:30:21 -04:00
Matthias Clasen f8f91095a3 Merge branch 'matthiasc/for-main' into 'main'
widget: Cosmetics

See merge request GNOME/gtk!5892
2023-04-29 18:29:14 +00:00
Benjamin Otte 6cc1548c5f Merge branch 'wip/carlosg/x11-artifacts' into 'main'
gdk/x11: Invalidate whole surface after size change

See merge request GNOME/gtk!5857
2023-04-29 18:11:21 +00:00
Matthias Clasen 30b12ff890 docs: Mention baselines
Add a paragraph about baselines to the coordinates overview.
2023-04-29 13:48:03 -04:00
Matthias Clasen b9931e9573 widget: Cosmetics
Rename allocated_size_baseline to allocated_baseline,
to match better with the other allocated_ fields.
2023-04-29 13:47:51 -04:00
Matthias Clasen cab8981c57 spinbutton: Use GtkBoxLayout:baseline-child
This makes it so that vertical spin buttons are
properly aligned to the baseline.
2023-04-29 13:28:55 -04:00
Matthias Clasen b6786b8a49 Revert "spinbutton: Use a grid layout"
This reverts commit d648a7721e.
2023-04-29 13:28:55 -04:00
Matthias Clasen 2d9ae241d5 boxlayout: Add a baseline child property
In horizontal layout, we line up the baselines of all children to find
how much space we need above and below the box baseline.

In vertical layout, we need to pick one child to inherit the baseline
from, which is what the new GtkBoxLayout:baseline-child property is
about. It is the equivalent of GtkGridLayout:baseline-row.
2023-04-29 13:28:55 -04:00
Daniel Boles a24a924a6b EventController: Fix type "even propagation"→event 2023-04-29 18:12:30 +01:00
Matthias Clasen 825eb93509 Remove more debug spew 2023-04-29 11:46:16 -04:00
Matthias Clasen a8a0850b64 Merge branch 'matthiasc/for-main' into 'main'
entry: Ignore the baseline when centering

See merge request GNOME/gtk!5889
2023-04-29 14:16:42 +00:00
Matthias Clasen 03f388d099 widget: Don't set baselines when unused
When we are not doing baseline alignment, don't pass
a baseline to the allocated widget. This helps because
a number of widgets (GtkLabel, GtkEntry, etc) always
position their text on the given baseline.
2023-04-29 09:52:34 -04:00
Matthias Clasen 92205744d2 entry: Ignore the baseline when centering
GtkEntry was always placing its text on the baseline,
even when the valign said something else.
2023-04-29 09:52:34 -04:00
Matthias Clasen f6f3a78dd9 Merge branch 'matthiasc/for-main' into 'main'
theme: Reinstate switch labels in hc

See merge request GNOME/gtk!5888
2023-04-29 12:27:23 +00:00
Matthias Clasen 76698e5de8 testbaseline2: Don't set height-requests
Widget with height requests have their baselines
ignored. Oops.
2023-04-29 08:01:11 -04:00
Matthias Clasen 21260e8ed4 theme: Reinstate switch labels in hc
Since we show them in GNOME shell, show them here too.

The comment that says "only show these in the a11y
theme" was still there, but we were always hiding them.
2023-04-29 08:01:03 -04:00
Carlos Garnacho 24302315fb gdk/x11: Invalidate whole surface after size change
The Expose events following a ConfigureNotify may arrive at
a time that we did not resize the surface yet, making these
expose events a no-op. Even though gsk/gtk take care of the
window content itself, this might lead to unrendered portions
of the window shadow.

This may be seen with GSK_RENDERER=cairo and GDK_BACKEND=x11,
attempting to tile a window (e.g. gtk4-demo) left or right.
The window will show black rectangles or other artifacts in
the window shadow areas that correspond to the newly painted
portions (as the window needs to expand vertically).

In order to fix this with a similar behavior to Wayland,
consider ourselves the whole surface invalidated after resize,
in order to ensure everything is painted from scratch.
2023-04-29 11:51:32 +02:00
Fabio Tomat fc9642ce2a Update Friulian translation 2023-04-29 08:57:53 +00:00
Benjamin Otte c542351a73 Merge branch 'wip/otte/for-main' into 'main'
wayland: Use wl_surface_damage_buffer() in Cairo

See merge request GNOME/gtk!5886
2023-04-29 03:43:45 +00:00
Benjamin Otte 3198330188 rendernode: Add diffing for affine transforms
This will be needed most importantly for inverted textures,
like in GLArea.
2023-04-29 05:10:51 +02:00
Benjamin Otte 11aaa29a69 wayland: Use wl_surface_damage_buffer() in Cairo
... when it is available.

Also introduce the new function gdk_rectangle_transform_affine(), which
looks like overkill for this purpose, but I'm about to use it elsewhere.
2023-04-29 05:07:03 +02:00
Matthias Clasen d1a25178fd Merge branch 'matthiasc/for-main' into 'main'
shortcutswindow: Avoid criticals

See merge request GNOME/gtk!5885
2023-04-29 01:15:58 +00:00
Matthias Clasen 092745161c shortcutswindow: Avoid criticals
No point in resetting accessible relations
when we are in finalize.
2023-04-28 20:44:18 -04:00
Matthias Clasen 0da4a92298 Merge branch 'clarify-swapped-default-object-signal' into 'main'
builder: Clarify default "swapped" value when "object" is set for signals

See merge request GNOME/gtk!4514
2023-04-28 23:00:31 +00:00
Matthias Clasen 8b816d3b03 Merge branch 'gtkshortcutswindow_a11y' into 'main'
GtkShortcutsWindow: Allow a screen reader user to browse the available shortcuts

See merge request GNOME/gtk!5042
2023-04-28 22:57:10 +00:00
Matthias Clasen 63b50f48a9 Merge branch 'harmonize-would_drop' into 'main'
Harmonize would_drop() replacement for g_log_writer_default_would_drop()

See merge request GNOME/gtk!4935
2023-04-28 22:55:42 +00:00
Matthias Clasen 8b91762c42 Merge branch 'deprecate-get-allocation' into 'main'
Deprecate get allocation

See merge request GNOME/gtk!5882
2023-04-28 22:49:42 +00:00
Matthias Clasen 01f39d8522 README: Updates
Drop the section that talked about main and how to update
local checkouts - its been 2 years, people should have gotten
around to it by now. Add some general git hints instead.
2023-04-28 17:31:12 -04:00
Benjamin Otte e94416054c Merge branch 'wip/otte/for-main' into 'main'
Fix hangs on Wayland

Closes #5761

See merge request GNOME/gtk!5884
2023-04-28 21:22:12 +00:00
Benjamin Otte b4c859c011 wayland: Set EGL swap interval to 0.
There's no need for EGL to do any timing, we do it in GTK already.

This fixes hangs in Mesa when we hide a surface after a SwapBuffers()
but before the frame callback arrives.
If we then reshow the surface and immediately render to it, Mesa would
still have a frame callback from before the hiding and forever poll()
waiting for the compositor to send the callback.

Fixes #5761
2023-04-28 22:40:39 +02:00
Benjamin Otte 45216e1c88 wayland: Disconnect the frame callback when hiding
Do not leave spurious frame callbacks around wen hiding surfaces.
Instead, store the callback and remove it.
2023-04-28 22:21:42 +02:00
Daniel Boles 7bea2685e1 migrating-3to4: Don't mention removed Box method &
donʼt mention its renamed successor either, as that has its own section
later. We could have another sentence paragraph like ‘In the case of
GtkBox, the pack methods have been renamed to X and lost the trailing
arguments Y’, but that wonʼt help people prepare still on GTK3, which is
the point in the affected section… so just remove the misleading relic.
2023-04-28 21:14:37 +01:00
Matthias Clasen b7d1774c56 Merge branch 'matthiasc/for-main' into 'main'
Cosmetics

See merge request GNOME/gtk!5883
2023-04-28 20:09:17 +00:00
Matthias Clasen 3afd91ea06 Updates 2023-04-28 16:02:18 -04:00
Matthias Clasen d7dd6ca552 Cosmetics 2023-04-28 15:36:37 -04:00
Matthias Clasen 9c40e8b873 Deprecate gtk_widget_get_allocated_baseline 2023-04-28 15:26:16 -04:00
Matthias Clasen b201d66981 Stop using gtk_widget_get_allocated_baseline
Use gtk_widget_get_baseline instead.
2023-04-28 15:25:58 -04:00
Matthias Clasen 3ea289751d Add gtk_widget_get_baseline
This is just a renaming of gtk_widget_get_allocated_baseline
that fits better with gtk_widget_get_width/height.
2023-04-28 15:18:13 -04:00
Matthias Clasen 8205c7032a Deprecate gtk_widget_get_allocation 2023-04-28 15:05:39 -04:00
Matthias Clasen ba379c928b flowbox: Use deprecation guards around get_allocation 2023-04-28 15:05:39 -04:00
Matthias Clasen 5306ef12f4 inspector: Show bounds instead of allocation 2023-04-28 15:05:39 -04:00
Matthias Clasen be62147dee scrolledwindow: Stop using gtk_widget_get_allocation 2023-04-28 15:05:39 -04:00
Matthias Clasen 627ce3d447 textutil: Stop using gtk_widget_get_allocation 2023-04-28 15:05:39 -04:00
Matthias Clasen 79119e64f9 tetview: Stop using gtk_widget_get_allocation 2023-04-28 15:05:39 -04:00
Matthias Clasen 37b2b3cb83 text: Stop using gtk_widget_get_allocation 2023-04-28 15:05:39 -04:00
Boyuan Yang 731c1be9e0 Update Chinese (China) translation 2023-04-28 18:51:56 +00:00
Benjamin Otte 76777cdd18 Merge branch 'wip/otte/texturebuilder' into 'main'
Add GdkGLTextureBuilder

See merge request GNOME/gtk!5862
2023-04-28 15:58:10 +00:00
Matthias Clasen bdec7782b4 Merge branch 'baseline-fixes' into 'main'
boxlayout: Fix baselines a bit

See merge request GNOME/gtk!5879
2023-04-28 14:40:57 +00:00
Matthias Clasen 55f5edffd1 More docs for BASELINE
Add some more details to the docs for GTK_ALIGN_BASELINE.
2023-04-28 09:21:15 -04:00
Matthias Clasen bb961d062a widget: Handle baseline better
When adjusting allocations, treat BASELINE more like CENTER
than like FILL. The results are better, in particular for
controls like entries or switches, which we never want to
scale up vertically, but still want to align to the baseline.
2023-04-28 09:13:49 -04:00
Matthias Clasen 38ffd099eb image: Simplify baseline handling
We guarantee that the out arguments of the measure
vfunc are non-NULL, no need to check.
2023-04-28 09:12:22 -04:00
Matthias Clasen 12af75df9b switch: Fix up baseline handling
We need to report a baseline for baseline alignment
to work...
2023-04-28 08:52:05 -04:00
Matthias Clasen d648a7721e spinbutton: Use a grid layout
A grid layout lets us get the baseline right in
vertical orientation, by setting a baseline row.

It would be nice if the box layout supported this
as well, but currently it doesn't, and adding that
feature isn't trivial.
2023-04-28 08:50:12 -04:00
Matthias Clasen e187587643 boxlayout: Fix baselines a bit
When we are not doing height-for-width, we still
need to line up baselines.
2023-04-28 08:50:12 -04:00
Matthias Clasen 3766f1da8b Add another baseline test client 2023-04-28 08:50:12 -04:00
Matthias Clasen 92a9f8cd7e gldriver: Add a sync when creating textures 2023-04-28 06:23:45 +02:00
Matthias Clasen b9a7e5fa85 gstreamer: Defer the sync
Don't sync right when we receive the buffer,
pass it along with the texture to be executed
later in the renderer.
2023-04-28 06:23:45 +02:00
Matthias Clasen bec0afa61b glarea: Synchronize
Create a fence object and pass it along when
creating the GL texture, so that the GL renderer
can wait for the texture to be ready.
2023-04-28 06:23:40 +02:00
Matthias Clasen bedc3dba7e filechooser: Plug a memory leak 2023-04-27 13:42:03 +02:00
Matthias Clasen 7c4acac135 Add some more valgrind suppressions 2023-04-27 13:42:03 +02:00
Matthias Clasen 0bb6988c0e columnview: Plug a memory leak
g_list_model_get_item strikes again.
2023-04-27 13:42:03 +02:00
Matthias Clasen df3622b295 filechooser: Plug a memory leak
We own references to the columns. Drop them.
2023-04-27 13:42:03 +02:00
Matthias Clasen df9f3fc694 filechoosernative: Plug a memory leak
Unref all the GVariants.
2023-04-27 13:42:03 +02:00
Matthias Clasen 39b3b2444b filedialog: Plug a memory leak
We own a reference to the native dialog,
and we need to drop it when we're done.
2023-04-27 13:42:03 +02:00
Matthias Clasen c237643b24 node-editor: Plug a memory leak 2023-04-27 13:42:03 +02:00
Matthias Clasen cc682a96d9 notebook: Drop an unused variable 2023-04-27 13:42:03 +02:00
Matthias Clasen 051b463c9a Fix various bitfield warnings
clang rightly complains about using gboolean
as type for bitfields, since it is signed.
Avoid that.
2023-04-27 13:42:03 +02:00
Matthias Clasen 8292b846d5 gsk: Synchronize when using textures
Pass the GLsync object from texture into our
command queue, and when executing the queue,
wait on the sync object the first time we
use its associated texture.
2023-04-27 06:57:02 +02:00
Matthias Clasen 6efaa79e3c gltexture: Synchronize when downloading
If the GL texture has a sync object, wait
on it before downloading the data.
2023-04-27 06:57:02 +02:00
Matthias Clasen 92eb845482 gltexture: Optionally take a sync object
Add a new function to TextureBuilder that takes a GLsync that
requires internal code to wait on before using the texture.

Somewhat sneakily, we don't take the sync if syncs are not supported by
the current GL context.
As public API has no code to query the sync for the destroy notify, this
is fine and it means we don't have to do the check every time we want to
call gdk_texture_get_sync() internally.
2023-04-27 06:55:37 +02:00
Matthias Clasen 5071e6154c glcontext: Add a way to check for GLsync 2023-04-27 06:54:49 +02:00
Benjamin Otte 18a4b2475e gltexture: Deprecate gdk_gl_texture_new()
Use GdkGLTextureBuilder instead.
2023-04-27 06:40:47 +02:00
Benjamin Otte 76e5fd0ece glrenderer: Port to GdkGLTextureBuilder 2023-04-27 06:40:47 +02:00
Benjamin Otte fa44d258d0 media-gstreamer: Port to GdkGLTextureBuilder
This is a rudimentary port that does not take advantage of all the cool
new formats that we could support now.
2023-04-27 06:40:47 +02:00
Benjamin Otte 778979cf0e testsuite: Use GLTextureBuilder 2023-04-27 06:40:47 +02:00
Benjamin Otte 053a4d2e9d glarea: Port to GdkGLTextureBuilder 2023-04-27 06:40:47 +02:00
Benjamin Otte aae7b2c8a8 texturebuilder: Pass the destroy notify to the build() function
This is more compatible with bindings that want to create per-object
callbacks and not have their callbacks reused over different build()
calls.
2023-04-27 06:40:47 +02:00
Benjamin Otte e37fbaf13a texturebuilder: Add ::format and ::has-mipmap
We were trying to deduce that previously. Now we have explicit API
2023-04-27 06:40:47 +02:00
Benjamin Otte e4f4cfaf14 gdk: Add GdkGLTextureBuilder
Building GL textures is complicated, so create an object to make them.

So far, this object just contains the functionality of
gdk_gl_texture_new(), but that will change in the future.
2023-04-27 06:40:47 +02:00
Matthias Clasen 9ae0a3865c Merge branch 'matthiasc/for-main' into 'main'
Fix the build with clang

See merge request GNOME/gtk!5876
2023-04-27 04:37:12 +00:00
Benjamin Otte 3b5a2d60c7 Merge branch 'wip/otte/gl-version' into 'main'
Make sure highest possible version GLContext is created

See merge request GNOME/gtk!5870
2023-04-27 00:39:19 +00:00
Benjamin Otte 9254ab8503 wgl: Improve error messages when GL init fails
In particular, we want to get the GL version, when the Windows box/VM
has an unsuitable GL implementation.

This is somewhat helpful in analyzing failures to bring up GL on
machines where users claim GL does work.
2023-04-27 02:19:25 +02:00
Benjamin Otte d6afcee1e4 wgl: Create context during WGL initialization
This way, we can realize it and either print success information about
it or return NULL if that fails.

This makes it more likely that we fail early, which means we can then
initialize EGL.
2023-04-27 02:16:46 +02:00
Benjamin Otte c71ca481c1 win32: Get rid of display->gl_version
We can just query the display's GL context.

And it's not used otherwise anymore.
2023-04-27 02:13:33 +02:00
Benjamin Otte 8ef38c46b5 win32: Refactor context creation
This refactor achieves the following:

 * check GL version against proper matching context version
   In particular, for legacy contexts, we now actually check
 * make sure the actual version is set, even for legacy contexts
 * make sure set_is_legacy() is set properly
2023-04-27 02:13:33 +02:00
Benjamin Otte 4333d754b8 gdk: Add workaround for Visual Studio
apparently casting something to itself makes it not constant.
2023-04-27 02:13:33 +02:00
Benjamin Otte 9f82d537b0 mac: Properly set GLContext.is_legacy() 2023-04-27 02:13:32 +02:00
Benjamin Otte 7c7a3d67ca glcontext: assert all contexts set the version on realize()
Now that all contexts do that, insist that they keep doing it.

And because they keep doing it, we can support querying the GL version
from gdk_gl_context_get_version() without requiring the context to be
made current.
2023-04-27 02:13:32 +02:00
Benjamin Otte d33b82249b mac: Try all different OpenGL profiles
.. and pick the best one that is supported.

Also make sure that the resulting context has at least the desired
version, otherwise bail.
2023-04-27 02:13:32 +02:00
Benjamin Otte 5f833f1d31 glcontext: Compute matching version the simple way
Do it all in one function instead of requiring two different ones.
2023-04-27 02:13:32 +02:00
Benjamin Otte b8958419e6 win32: Make sure highest possible GL version is created
Mirror EGL here.
2023-04-27 02:13:32 +02:00
Benjamin Otte 919c90182f win32: Pass the version properly through the creation stack
We were using major/minor instead of GdkGLVersion.

And we were resetting back to 0 and ignoring the required min version
which we should not do.
2023-04-27 02:13:32 +02:00
Benjamin Otte ab2a548479 glx: Make sure highest possible GL version is created
Mirror EGL here.
2023-04-27 02:13:32 +02:00
Benjamin Otte 34662fc4b0 egl: Make sure highest possible GL version is created
The EGL spec states:

    The context returned must be the specified version, or a later
    version which is backwards compatible with that version.
    Even if a later version is returned, the specified version
    must correspond to a defined version of the client API.

GTK has so far been relying on EGL implementations returning a
later version, because that is what Mesa does.
But ANGLE does not do that and only provides the minimum version, which
means Windows EGL has been forced to use a lower EGL version for no
reason.

So fix this and try versions in order from highest to lowest.
2023-04-27 02:13:32 +02:00
Benjamin Otte 5b376cedcf gdk: Move GdkGLAPI enum into gdkenums.h 2023-04-27 02:13:32 +02:00
Benjamin Otte 3aefed39b1 glcontext: Use GdkGLVersion elsewhere
... and add a convenience API to generate GL versions from strings to
make the gdk_gl_context_check() API nicer.
2023-04-27 02:13:32 +02:00
Benjamin Otte f86429177a gdk: Introduce GdkGLVersion
... and use it.

Makes the code simpler.
2023-04-27 02:13:32 +02:00
Benjamin Otte dacfed3e11 win32: Remove an outdated check
We require GL 3.0, so checking for less than 2.0 makes no sense anymore.
2023-04-27 02:13:32 +02:00
Matthias Clasen 8fb2ee7d67 Fix a crash
Fix an oversight from c87b193d2a.
2023-04-27 00:09:18 +02:00
Benjamin Otte 29e7186829 Merge branch 'wip/otte/treelistmodel-madness' into 'main'
treelistmodel: Be safer during collapsing

See merge request GNOME/gtk!5875
2023-04-26 22:06:40 +00:00
Matthias Clasen 951e3b3d6b Fix the build with clang
This broke our macos ci.
2023-04-26 23:54:43 +02:00
Benjamin Otte 3c76f3fb58 treelistmodel: Delay notifies from TreeListRow
Don't notify during destruction, notify afterwards.
This way we don't call into user code from a half-destructed node.

Note that this changes the order in which those notifies happen when
collapsing a large tree: From parent node before child nodes to child
nodes before parent node.

No actual use case for this, just thought it would be safer.
2023-04-26 23:40:56 +02:00
Benjamin Otte 8766a6fab2 treelistmodel: Be safer during collapsing
While we are collapsing a subtree, some signal handlers may not be
disconnected while we are doing this. By adding this check and not
giving those nodes no longer access to the model, we can stop it from
modifying it while we are trying to collapse stuff.

Fixes some crashes in gnome-builder.
2023-04-26 23:30:37 +02:00
Benjamin Otte f52975c220 Merge branch 'wip/otte/surface-surgery' into 'main'
refactor internal surface API

See merge request GNOME/gtk!5846
2023-04-26 21:03:24 +00:00
Daniel Boles abd4a57031 3to4: Fix we said we replace doubles with doubles,
when what we are replacing are ints!
2023-04-26 21:30:10 +01:00
Benjamin Otte 9d0448756f display: Remove ::create_surface() vfunc
Instead, have a toplevel_type and popup_type in GdkDisplay and
call g_object_new() with those types.
2023-04-26 21:03:34 +02:00
Benjamin Otte 03d7ce3287 wayland: Set default title in toplevel_init() 2023-04-26 21:03:34 +02:00
Benjamin Otte f2083d36a1 macos: Add surface from ::constructed() 2023-04-26 21:03:34 +02:00
Benjamin Otte cb642bec25 gdk: Remove GDK_SURFACE_DRAG enum member
I want to remove the whole enum, but this value was used all over the
place. So removing it first ensures I didn't forget anything.
2023-04-26 21:03:34 +02:00
Benjamin Otte 8c530264f7 wayland: Create drag surface directly
... instead of going through create_surface().
2023-04-26 21:03:34 +02:00
Benjamin Otte d99042dd91 wayland: Remove struct member
It's unused.
2023-04-26 21:03:34 +02:00
Benjamin Otte 486196c979 x11: Add private gdk_x11_drag_surface_new()
... and use it.
2023-04-26 21:03:34 +02:00
Benjamin Otte 83faacabe3 x11: Set frame clock in ::constructed 2023-04-26 21:03:34 +02:00
Benjamin Otte 31aae62f9a x11: Move window construction to ::constructed() 2023-04-26 21:03:34 +02:00
Benjamin Otte 726be8e2b2 broadway: Create gdk_broadway_drag_surface_new()
... and use it.
2023-04-26 21:03:34 +02:00
Benjamin Otte ab0fa08d8e win32: Create gdk_win32_draw_surface_new()
... and use it.
2023-04-26 21:03:34 +02:00
Benjamin Otte 42cea18f3e macos: Set frame clock in ::constructed 2023-04-26 21:03:34 +02:00
Benjamin Otte 44e54e1b4c broadway: Set frame clock in ::constructed
... instead of passing it to g_object_new().
2023-04-26 21:03:34 +02:00
Benjamin Otte a79ae95e7e broadway: Move surface init code into ::constructed() 2023-04-26 21:03:34 +02:00
Benjamin Otte 77fe9116af win32: Set frame clock in constructed()
... instead of passing it as construct argument.
2023-04-26 21:03:34 +02:00
Benjamin Otte 808cde74be wayland: Construct the frame clock in the surface
... instead of passing it to g_object_new().
2023-04-26 21:03:34 +02:00
Benjamin Otte 13120ccf9d surface: Make gdk_surface_set_frame_clock() available
... to backends.

That way, frame clocks can be constructed by the backends' surface
implementations and dont need to be passed in as construct arguments.

Also add an assertion that they are indeed constructed.
2023-04-26 21:03:34 +02:00
Benjamin Otte a306401023 macos: Move native window creation to ::constructed()
That way, it doesn't need a specific init function.

Also chain up last, so that the generic initialization code in
GdkSurface::constructed can access a fully initialized macos surface.
2023-04-26 21:03:34 +02:00
Benjamin Otte 7e18a1cea7 macos: Don't pass sizes to macos_surface_new()
They're 0, 0, 100, 100 always, so just use those values everywhere.
2023-04-26 21:03:34 +02:00
Benjamin Otte 9a6e6be785 macos: Create drag surface directly
Do not go via macos_surface_new().
2023-04-26 21:03:34 +02:00
Benjamin Otte 093a4e83d5 macos: Move construction stuff into ::constructed 2023-04-26 21:03:34 +02:00
Benjamin Otte 428798b53f macos: toplevels have no parent 2023-04-26 21:03:34 +02:00
Benjamin Otte 4fa81cf70f win32: Move surface init code into ::constructed() 2023-04-26 21:03:34 +02:00
Benjamin Otte 9ac31fe0a0 win32: Abort on error
Returning NULL from a function that must not return NULL is not a good
idea.
2023-04-26 21:03:34 +02:00
Benjamin Otte 69fabb3ce9 win32: Remove outdated debug messages
They are not needed anymore as they print stuff that's no decided in
that function anymore.
2023-04-26 21:03:34 +02:00
Benjamin Otte f59c230a96 win32: Move toplevel signal into the toplevel class 2023-04-26 21:03:34 +02:00
Benjamin Otte 80d99b893e broadway: Pass parent as a construct argument 2023-04-26 21:03:34 +02:00
Benjamin Otte cbe89b955a x11: Get rid of sizes when constructing surfaces
Just call XCreateWindow with 0, 0, 1, 1 size.
2023-04-26 21:03:34 +02:00
Benjamin Otte 2d827978a6 x11: Remove unused variable 2023-04-26 21:03:34 +02:00
Benjamin Otte b2e304189e wayland: Move surface initialization into constructed()
That way, it doesn't ned a specific init function.

Also chain up last, so that the generic initialization code can access a
fully initialized wayland surface.
2023-04-26 21:03:34 +02:00
Benjamin Otte 35c2d85468 wayland: Move toplevel-specific code into the toplevel
The display->toplevels tracking belongs to GdkWAylandToplevel.
2023-04-26 21:03:34 +02:00
Benjamin Otte 7ef5f6ef1a display: Remove x/y/w/h from create_surface() 2023-04-26 21:03:34 +02:00
Matthias Clasen 9364da673f Merge branch 'application-signal-cleanup' into 'main'
application: Clean up signal handlers

See merge request GNOME/gtk!5872
2023-04-26 13:11:43 +00:00
Matthias Clasen c87b193d2a application: Clean up signal handlers
This is the right thing to do and might help for #5775.
2023-04-26 14:15:31 +02:00
Matthias Clasen 045ab0f107 Merge branch 'win32-warnings' into 'main'
Fix some win32 warnings

See merge request GNOME/gtk!5868
2023-04-26 06:58:09 +00:00
Matthias Clasen 27d9023ac8 Merge branch 'pathbar-webdav-root' into 'main'
pathbar: Handle webdav where is the root is a path

Closes #2866

See merge request GNOME/gtk!5830
2023-04-26 06:50:10 +00:00
Matthias Clasen 8a82e1b8b4 Merge branch 'matthiasc/for-main' into 'main'
gsk: Don't misuse bitwise operators

See merge request GNOME/gtk!5869
2023-04-26 06:49:32 +00:00
Matthias Clasen 8e695f7c56 Merge branch 'modelbutton-no-click-outside' into 'main'
gtkmodelbutton: Ignore releases outside of the button

Closes #5760

See merge request GNOME/gtk!5852
2023-04-26 05:56:31 +00:00
Fran Dieguez 1f886668ce Update Galician translation
(cherry picked from commit 7470bc01f2)
2023-04-25 23:22:28 +00:00
Sebastian Keller a678e9fdd9 gtkmodelbutton: Ignore releases outside of the button
This is also how regular buttons behave. Otherwise releasing on a
different menu item would register a click on the item that was
originally pressed. In these cases it is better to not register a click
at all.

Closes: https://gitlab.gnome.org/GNOME/gtk/-/issues/5760
2023-04-25 19:28:42 +02:00
Matthias Clasen 74c0171edf gsk: Don't misuse bitwise operators
We should use && for booleans, not &=.
2023-04-25 16:43:02 +02:00
Matthias Clasen 248d13d8dc Merge branch 'matthiasc/for-main' into 'main'
gsk: Don't misuse bitwise operators

See merge request GNOME/gtk!5867
2023-04-25 12:48:13 +00:00
Marc-André Lureau 2d11d3f8d3 gtk/win32: fix usage of deprecated function
[106/939] Compiling C object gtk/libgtk.a.p/gtkimcontextime.c.obj
../gtk/gtkimcontextime.c: In function 'gtk_im_context_ime_set_preedit_font':
../gtk/gtkimcontextime.c:780:3: warning: 'gtk_widget_get_style_context' is deprecated [-Wdeprecated-declarations]
  780 |   font_desc = gtk_css_style_get_pango_font (gtk_style_context_lookup_style (gtk_widget_get_style_context (context_ime->client_widget)));

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
2023-04-25 16:37:58 +04:00
Marc-André Lureau ff9cd989c6 gdk/win32: fix defined but not used warnings
[30/1038] Compiling C object gdk/win32/libgdk-win32.a.p/gdkmain-win32.c.obj
../gdk/win32/gdkmain-win32.c:146:1: warning: 'gdk_win32_finalize_ole' defined but not used [-Wunused-function]
  146 | gdk_win32_finalize_ole (void)
      | ^~~~~~~~~~~~~~~~~~~~~~
../gdk/win32/gdkmain-win32.c:113:1: warning: 'gdk_win32_finalize_com' defined but not used [-Wunused-function]
  113 | gdk_win32_finalize_com (void)

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
2023-04-25 16:37:58 +04:00
Marc-André Lureau 5b69df96fe gdk/win32: fix hr set but not used
A number of warnings are produced:

[23/1038] Compiling C object gdk/win32/libgdk-win32.a.p/gdkinput-dmanipulation.c.obj
../gdk/win32/gdkinput-dmanipulation.c: In function 'reset_viewport':
../gdk/win32/gdkinput-dmanipulation.c:354:11: warning: variable 'hr' set but not used [-Wunused-but-set-variable]
  354 |   HRESULT hr;
      |           ^~

Try to do something sensible instead.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
2023-04-25 16:37:58 +04:00
Marc-André Lureau d8ead56b9c gdk/win32: fix g_string_free warning
../gdk/win32/gdkclipdrop-win32.c: In function 'transmute_cf_shell_id_list_to_text_uri_list':
C:/msys64/ucrt64/include/glib-2.0/glib/gstring.h:72:5: warning: ignoring return value of 'g_string_free_and_steal' declared with attribute 'warn_unused_result' [-Wunused-result]

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
2023-04-25 16:14:57 +04:00
Marc-André Lureau 0e2d7111eb gdk/win32: fix GDK_NOTE redefined warning
In file included from ../gdk/win32/gdkdrag-win32.c:201:
../gdk/win32/gdkprivate-win32.h:45: warning: "GDK_NOTE" redefined
   45 | #define GDK_NOTE(type,action)                             \
      |
../gdk/win32/gdkdrag-win32.c:40: note: this is the location of the previous definition
   40 | #define GDK_NOTE(a,b)

Fixes: bc159207bd ("gdk: Drop old debug macros")

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
2023-04-25 16:11:11 +04:00
Matthias Clasen 2263db6259 gsk: Don't misuse bitwise operators
We should use || for booleans, not |=.
2023-04-25 13:45:37 +02:00
Matthias Clasen ec318e911c Merge branch 'label_get_active_uri' into 'main'
Fix hovered link URI not returned by gtk_label_get_current_uri

See merge request GNOME/gtk!5864
2023-04-25 11:22:34 +00:00
Matthias Clasen ed69435a1b Merge branch 'icontheme-has-icon-consistency' into 'main'
icontheme: make has_(g)icon consistent with lookup

Closes #5709

See merge request GNOME/gtk!5865
2023-04-25 07:49:12 +00:00
Matthias Clasen e111f688c2 Merge branch 'null-display' into 'main'
gdkdisplaymanager: Add missing nullable to display name

See merge request GNOME/gtk!5866
2023-04-25 07:46:21 +00:00
Takao Fujiwara 26e3824d1d gdkdisplaymanager: Add missing nullable to display name 2023-04-25 12:08:08 +09:00
velsinki e20a5e1bc1 icontheme: make has_(g)icon consistent with lookup
Make `gtk_icon_theme_has_icon` and `gtk_icon_theme_has_gicon` also
consider unthemed icons. This makes their behavior consistent with the
actual (documented) lookup behavior.

Fixes: #5709 and makes the workaround in nautilus@b643a00b obsolete
2023-04-24 23:38:20 +02:00
Chris Mayo 66cfeb3ad1 Fix hovered link URI not returned by gtk_label_get_current_uri
This is needed for a query-tooltip handler, as mentioned in the
documentation, when there has been a hover timeout.

Maintain the previous behaviour when the link is clicked and follow the
existing documentation regarding selectable labels.

A notify::cursor handler can now also be used to retrieve the URI of the
link under the cursor.
2023-04-24 19:35:47 +01:00
Matthias Clasen 63d7756658 Merge branch 'ebassi/button-can-shrink' into 'main'
Add GtkButton:can-shrink

See merge request GNOME/gtk!5552
2023-04-24 12:28:12 +00:00
Emmanuele Bassi e28676869e Add GtkMenuButton:can-shrink
Map the GtkMenuButton property to the underlying GtkButton widget.
2023-04-24 11:09:01 +01:00
Sabri Ünal fabfc1eefa Update Turkish translation 2023-04-23 21:12:44 +00:00
Benjamin Otte 72016341c6 Merge branch 'wip/otte/for-main' into 'main'
surface: Clean up drawing code

See merge request GNOME/gtk!5861
2023-04-22 15:10:02 +00:00
Benjamin Otte 104b5ef157 surface: reformat function
Make the function follow usual coding conventions.

And while doing that, remove duplicate functionality.
2023-04-22 16:35:16 +02:00
Benjamin Otte 893862a51a surface: Refactor code
Move the early exit conditions to the top and turn them into early exits
instead of nesting if statements.
2023-04-22 16:33:35 +02:00
Benjamin Otte 823eb4c6d9 surface: Fold function into its only caller
No other changes
2023-04-22 16:29:58 +02:00
Benjamin Otte be0ed15b40 surface: Stop maintaining an unused linked list
wat?
2023-04-22 16:27:27 +02:00
Benjamin Otte 040af44b00 surface: Remove in_update tracking
It's 2023, we use frame clocks now and don't have nested surface drawing
anymore.
2023-04-22 16:24:16 +02:00
Benjamin Otte 4154f87418 surface: Stop tracking the active update area
It's unused.
2023-04-22 16:10:24 +02:00
Aleksandr Melman 27e3ac5fc5 Update Russian translation 2023-04-22 12:03:07 +00:00
Piotr Drąg eaaddd2647 Update Polish translation 2023-04-22 11:16:24 +02:00
Matthias Clasen 6d0659a83a Merge branch 'gtkfilesystemmodel-emit-items-changed-on-modifying-attributes' into 'main'
filesystemmodel: Emit items-changed when modifying attributes

Closes #5758

See merge request GNOME/gtk!5853
2023-04-22 05:54:58 +00:00
Olivier Crête 0ce6bc677e filesystemmodel: Emit items-changed when modifying attributes 2023-04-22 05:54:57 +00:00
Matthias Clasen b579a39a47 Merge branch 'wip/corey/file-chooser-signal' into 'main'
Port filechooserwidget to GtkSignalListItemFactory

See merge request GNOME/gtk!5858
2023-04-22 05:26:43 +00:00
Corey Berla aeaaead2bd filechoosercell: Drop show-time property
Now that we are using GtkSignalListItemFactory, the convoluted show-time
property is no longer necessary.
2023-04-21 08:14:32 -07:00
Corey Berla 056237fc04 filechooserwidget: Port to GtkSignalListItemFactory
BuilderListItemFactory isn't quite suited for our purposes, primarily
because you can't pass user data to BuilderListItemFactory.  Because
we can't get the data we are using a workaround to get the
GtkFileChooserWidget ancestory, which used to work, but with the
recent list view changes no longer doesn't.  Use GtkSignalListItemFactory
with the GtkFileChooserWidget as the user data.
2023-04-21 08:14:32 -07:00
Corey Berla 1a7e808c27 Revert "filechooser: Set date and time after cell is a child of filechooserwidget"
This reverts commit 2a70093a30.

This fix was incomplete, the actual fix	is to use signal factory.
2023-04-21 08:14:24 -07:00
Corey Berla 3de47fa5c6 Revert "filechoosercell: Store type_format in filechoosercell"
This reverts commit dd407dab00.

This fix was incomplete, the actual fix is to use signal factory.
2023-04-21 08:14:14 -07:00
Hugo Carvalho 9f7c8f7d42 Update Portuguese translation
(cherry picked from commit 5bc3284dd8)
2023-04-21 14:30:55 +00:00
Yosef Or Boczko feb3254a6a Update Hebrew translation 2023-04-21 09:10:12 +00:00
Benjamin Otte 03b71a9759 Merge branch 'wip/otte/for-main' into 'main'
testsuite: Be less verbose in accessor-apis test

Closes #5763

See merge request GNOME/gtk!5851
2023-04-20 21:50:44 +00:00
Benjamin Otte f393f70ee2 listbase: Don't warn on scroll in empty list
Empty lists can still be scrolled if the scroll happens in the same
frame as the emptying of the list.

Related: #5763
2023-04-20 23:33:28 +02:00
Benjamin Otte 75c47755e3 adjustment: sanity-check values when setting them
It's not enough to sanitize values when starting an animation, as the
adjustment can reconfigure itself while the animation runs.
So as a simple way to handle this, we sanitize every value right before
setting it, too.

In the future we might also want to look at sanitizing start/end values
of the animation.

Fixes #5763
2023-04-20 23:33:28 +02:00
Benjamin Otte e47c076048 adjustment: Split out a function 2023-04-20 23:33:28 +02:00
Matthias Clasen 6ecd57eba8 Merge branch 'dark_theme_fix_hover_toolbar_buttons' into 'main'
theme: fix 'hover' and 'check' colors for buttons under .toolbar

See merge request GNOME/gtk!5844
2023-04-20 20:08:31 +00:00
Matthias Clasen 8b3831d43a Merge branch 'dark_theme_increase_selection_color' into 'main'
Increase contrast for text entry selection color on dark theme

See merge request GNOME/gtk!5843
2023-04-20 20:08:01 +00:00
Benjamin Otte 39583e40ef testsuite: Allow accessors in interfaces
There are a lot of cases where properties are implemented in classes but
the getters for these exist in an interface that class implements.

A common Example is g_list_model_get_n_items() being the getter for
GtkWhateverListModel::n-items.
But also property implementations that don't use override_property()
(usually because they have a different default) are handled by this.
2023-04-20 17:47:54 +02:00
Benjamin Otte be5f225022 testsuite: Be less verbose in accessor-apis test
Only print the tried names when --verbose is passed to the test.
2023-04-20 17:47:54 +02:00
Emin Tufan Çetin 427ed50759 Update Turkish translation 2023-04-19 13:22:31 +00:00
Matthias Clasen 9892243df6 Merge branch 'mask-node-transforms' into 'main'
Fix a comment

See merge request GNOME/gtk!5848
2023-04-19 07:44:45 +00:00
Matthias Clasen 83091c4f15 gsk: Use explicit switches
This makes it harder to forget to add new
node types here.
2023-04-19 09:19:12 +02:00
Matthias Clasen 503a5de7d1 gsk: Mask nodes support 2d transforms
When adding mask nodes, I overlooked that
we have two separate functions for determining
what transforms a node supports without offlines.

Since we claim that mask nodes support general
transform, they must certainly support 2d transforms
as well.
2023-04-19 08:13:55 +02:00
Matthias Clasen d7d75f0b26 Fix a comment
I tried to improve things in d67101d46e,
but I made it worse. The original note was meant
to be removed. Pointed out be Sebastian Bacher.
2023-04-19 07:49:36 +02:00
Benjamin Otte 40ac37245d Merge branch 'angle-gles' into 'main'
gdk: prefer GLES when on win32/ANGLE

See merge request GNOME/gtk!5829
2023-04-17 11:56:03 +00:00
Marc-André Lureau 250414d6b3 gdk/win32: drop some unused variables
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
2023-04-17 04:50:17 +00:00
Marc-André Lureau d69cdf6c05 gdk: drop libangle GLES minimum version
GLES 2.0 version is fine now with current gtk according to B. Otte.
Let's use the same minimum requirement for all implementations.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
2023-04-17 04:50:17 +00:00
Marc-André Lureau 9532657fa2 gdk: use GLES when on win32/ANGLE
When using GDK_DEBUG=gl-egl, we end up using GL, but that is not well supported:

Creating EGL context version 3.0 (debug:no, forward:no, legacy:yes, es:no)
Created EGL context[0000000000000004]
OpenGL version: 0.0 (legacy)
* GLSL version: (NULL)
* Max texture size: -1059701680
* Extensions checked:
 - GL_KHR_debug: no
 - GL_EXT_unpack_subimage: yes
 - OES_vertex_half_float: no

** (gtk4-demo.exe:14324): WARNING **: 19:16:41.468: Compile failure in
vertex shader:
ERROR: 0:7: 'gl_Position' : undeclared identifier
---8<---

Use GLES when EGL implementation is ANGLE.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
2023-04-17 04:50:17 +00:00
Marc-André Lureau 3cb2115212 gdk: drop unused vertex_array_object
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
2023-04-17 04:50:17 +00:00
Benjamin Otte dd7c85adc3 Merge branch 'wip/otte/for-main' into 'main'
glrenderer: Don't try to use float framebuffers on GLES2

See merge request GNOME/gtk!5845
2023-04-17 04:49:59 +00:00
Benjamin Otte 8965d6c7f8 gl: Only allow RGB(A)8 on GLES2
GLES2 has no idea what 16bit textures even are, let alone floating point.
2023-04-17 05:57:44 +02:00
Benjamin Otte d7309a009c glrenderer: Don't try to use float framebuffers on GLES2
GLES doesn't know what that is.
2023-04-17 05:57:44 +02:00
Nelson Benítez León bd9b117517 theme: more contrast for text entry selection color on dark theme
Part of #5725
2023-04-16 16:33:54 -04:00
Nelson Benítez León a309a56acf theme: fix 'hover' and 'check' colors for buttons under .toolbar
Buttons under .toolbar were using for their 'hover', 'active'
and 'check' colors the default ones from %button_basic_flat
which are very dimmed, so we explicitly darken them.

Part of #5725
2023-04-16 16:16:10 -04:00
Matthias Clasen b6fac448d7 Merge branch 'matthiasc/for-main' into 'main'
Try harder to fix focus tests

See merge request GNOME/gtk!5842
2023-04-16 20:00:46 +00:00
Matthias Clasen 765f55dfbe testsuite: Skip focus tests when necessary
If our window does not get focus, we can't reliably
test things that depend on widgets being focused.
2023-04-16 20:58:26 +02:00
Matthias Clasen bebaad3e1f Merge branch 'ccook/doc-changes' into 'main'
Two corrections that show up in docs

See merge request GNOME/gtk!5838
2023-04-16 18:16:36 +00:00
Matthias Clasen db6a116d49 Try harder to fix focus tests
The focus test now asserts that its window is active.
So we should not run them in parallel with other tests,
since those might steal the focus.
2023-04-16 20:08:03 +02:00
Benjamin Otte a299656c60 Merge branch 'wip/otte/alt.wl_surface.die.die.die' into 'main'
wayland: Don't leak all surfaces

See merge request GNOME/gtk!5840
2023-04-16 18:02:33 +00:00
Benjamin Otte 27fd0b907d testsuite: Fix broken test to not unref surfaces twice
The test doesn't hold 2 references, it holds only one.

The reason one unref can cause a leak is that some backends - like X11 -
only destroy the surface once the DestroyNotify event from the X server
has come in.
2023-04-16 19:28:21 +02:00
Benjamin Otte 62951c7277 wayland: Don't leak all surfaces
X11 does add an extra reference to surfaces that gets released when the
DestroyNotify event arrives.
Wayland doesn't ave such an event, so that reference never gets
released.

This fixes a copy/paste error introduced in commit 590f3dfa1f.
2023-04-16 19:28:21 +02:00
Benjamin Otte 8e00f6e5e5 wayland: Don't insta-crash when a surface gets disposed
We want to remove the event queue from the list of event queues, not the
surface.
Otherwise the freed queue stays in the list and the next time an event
comes in, we access invalid memory.

Fixes thinko introduced in commit 7fafa5133b.

Luckily, we leak all surfaces, so this problem never occured.
2023-04-16 19:28:21 +02:00
Matthias Clasen ff141a1ed4 Merge branch 'ccook/gtklabel-doc-changes' into 'main'
GtkLabel doc corrections

See merge request GNOME/gtk!5839
2023-04-16 17:07:49 +00:00
Matthias Clasen 25a10f502e Merge branch 'focus-testsuite-fixes' into 'main'
text: Fix fallout from focus changes

See merge request GNOME/gtk!5841
2023-04-16 07:36:11 +00:00
Matthias Clasen 585fb497c1 testsuite: Actually wait for focus
We were failing to properly iterate the main
context here. Oops.
2023-04-16 09:11:24 +02:00
Matthias Clasen c57e5811f1 tests: Check is-focus instead of has-focus
We are not presenting windows here.
2023-04-16 08:50:35 +02:00
Matthias Clasen 940a2b6923 text: Fix fallout from focus changes
We don't get proper notification for when the toplevel
is-active property changes, so monitor has-focus, and
update cursor blinking.
2023-04-16 08:49:20 +02:00
Cam Cook 3277e2ee3e | method | current | suggestion |
|---------------------------------------------------------------------------------------|-----------------------------------------------------------------|----------------------------------------------------------------------|
| [get_attributes](https://gitlab.gnome.org/GNOME/gtk/-/blob/main/gtk/gtklabel.c#L3242) | "use`pango_layout_get_attribute (gtk_label_get_layout (self))`" | "use`pango_layout_get_attributes (gtk_label_get_layout (self))`" [1] |
| [set_yalign](https://gitlab.gnome.org/GNOME/gtk/-/blob/main/gtk/gtklabel.c#L5897)     | "(attributes org.gtk.Method.get_property=yalign)"               | "(attributes org.gtk.Method.set_property=yalign)"                    |
| [get_yalign](https://gitlab.gnome.org/GNOME/gtk/-/blob/main/gtk/gtklabel.c#L5923)     | "(attributes org.gtk.Method.set_property=yalign)"               | "(attributes org.gtk.Method.get_property=yalign)"                    |
| [set_ellipsize](https://gitlab.gnome.org/GNOME/gtk/-/blob/main/gtk/gtklabel.c#L3892)  | "to ellipsizei"                                                 | "to ellipsize"                                                       |
| [get_attributes](https://gitlab.gnome.org/GNOME/gtk/-/blob/main/gtk/gtklabel.c#L3239) | "from the labels markup"                                        | "from the label's markup"                                            |

[1] https://docs.gtk.org/Pango/method.Layout.get_attributes.html
2023-04-15 21:48:27 -04:00
Cam Cook 3e8489fea5 | method | current | suggestion |
|-------------------------------------------------------------------------------------------------|------------------------------------------------------------|-----------------------------------------------------------|
| [Entry/set_invisible_char](https://gitlab.gnome.org/GNOME/gtk/-/blob/main/gtk/gtkentry.c#L2101) | "(attributes org.gtk.Method.sets_property=invisible-char)" | "(attributes org.gtk.Method.set_property=invisible-char)" |
| [FlowBox::activate](https://gitlab.gnome.org/GNOME/gtk/-/blob/main/gtk/gtkflowbox.c#L541)       | "This can be happen either by"                             | "This can happen either by"                               |
2023-04-15 12:41:13 -04:00
Cam Cook 1035640020 Revert "Two corrections and added method linking that show up in docs"
This reverts commit c7f30ecdfd.
2023-04-15 12:40:22 -04:00
Matthias Clasen 6cee73d100 Merge branch 'wip/otte/gles-fixes' into 'main'
GLES 2 fixes

See merge request GNOME/gtk!5837
2023-04-15 16:27:16 +00:00
Matthias Clasen e4c43901c1 Merge branch 'matthiasc/for-main' into 'main'
window: Don't mark widget prematurely as has-focus

See merge request GNOME/gtk!5836
2023-04-15 16:09:32 +00:00
Cam Cook c7f30ecdfd Two corrections and added method linking that show up in docs
| method                                                                                          | current                                                    | suggestion                                                |
|-------------------------------------------------------------------------------------------------|------------------------------------------------------------|-----------------------------------------------------------|
| [Entry/set_invisible_char](https://gitlab.gnome.org/GNOME/gtk/-/blob/main/gtk/gtkentry.c#L2101) | "(attributes org.gtk.Method.sets_property=invisible-char)" | "(attributes org.gtk.Method.set_property=invisible-char)" |
| [FlowBox::activate](https://gitlab.gnome.org/GNOME/gtk/-/blob/main/gtk/gtkflowbox.c#L541)       | "This can be happen either by"                             | "This can happen either by"                               |

| method                                                                                                    | current                                                | suggestion                                                   |
|-----------------------------------------------------------------------------------------------------------|--------------------------------------------------------|--------------------------------------------------------------|
| [Box/get_baseline_position](https://gitlab.gnome.org/GNOME/gtk/-/blob/main/gtk/gtkbox.c#L461)             | "value set by gtk_box_set_baseline_position()."        | "value set by [method@Gtk.Box.set_baseline_position]."       |
| [Box/get_spacing](https://gitlab.gnome.org/GNOME/gtk/-/blob/main/gtk/gtkbox.c#L412)                       | "value set by gtk_box_set_spacing()."                  | "value set by [method@Gtk.Box.set_spacing]."                 |
| [CenterBox/get_baseline_position](https://gitlab.gnome.org/GNOME/gtk/-/blob/main/gtk/gtkcenterbox.c#L528) | "value set by gtk_center_box_set_baseline_position()." | "value set by [method@Gtk.CenterBox.set_baseline_position]." |
| [Entry/get_activates_default](https://gitlab.gnome.org/GNOME/gtk/-/blob/main/gtk/gtkentry.c#L2296)        | "value set by gtk_entry_set_activates_default()."      | "value set by [method@Gtk.Entry.set_activates_default]."     |
| [Entry/get_alignment](https://gitlab.gnome.org/GNOME/gtk/-/blob/main/gtk/gtkentry.c#L2380)                | "value set by gtk_entry_set_alignment()."              | "value set by [method@Gtk.Entry.set_alignment]."             |
| [Entry/get_extra_menu](https://gitlab.gnome.org/GNOME/gtk/-/blob/main/gtk/gtkentry.c#L3727)               | "set with gtk_entry_set_extra_menu()."                 | "set with [method@Gtk.Entry.set_extra_menu]."                |
| [Entry/get_has_frame](https://gitlab.gnome.org/GNOME/gtk/-/blob/main/gtk/gtkentry.c#L2340)                | "value set by gtk_entry_set_has_frame()."              | "value set by [method@Gtk.Entry.set_has_frame]."             |
| [Entry/get_progress_pulse_step](https://gitlab.gnome.org/GNOME/gtk/-/blob/main/gtk/gtkentry.c#L3372)      | "set with gtk_entry_set_progress_pulse_step()."        | "set with [method@Gtk.Entry.set_progress_pulse_step]."       |
| [Fixed/get_child_transform](https://gitlab.gnome.org/GNOME/gtk/-/blob/main/gtk/gtkfixed.c#L314)           | "set using gtk_fixed_set_child_transform()."           | "set using [method@Gtk.Fixed.set_child_transform]."          |
2023-04-15 12:08:46 -04:00
Benjamin Otte b64f7050ba testsuite: Make GLES testsuite run use GLES 2
We want to support GLES 2, so make sure we test that support.

Also force-disable common extensions we don't explicitly check for and
don't want to accidentally use.
2023-04-15 17:55:20 +02:00
Benjamin Otte d37b9619e2 gles: Don't use vertex array objects
They're not needed and GLES doesn't technically support them, even
though GTK had been using them via epoxy sneakily using the
GL_OES_vertex_array_object extension behind our back.
2023-04-15 17:55:20 +02:00
Matthias Clasen 4a22e681b3 text: Only claim primary when focused
It does not make sense otherwise, and has unfortunate
side-effects on Wayland.
2023-04-15 15:02:52 +02:00
Matthias Clasen 189aced844 wayland: Improve logging for primary selection 2023-04-15 15:02:52 +02:00
Matthias Clasen d90cb02570 window: Don't mark widget prematurely as has-focus
has-focus is defined is-focus && toplevel::is-active.
We were forgetting to look at is_active when handling
focus widget changes.
2023-04-15 14:58:57 +02:00
Matthias Clasen 4246c7bafd Merge branch 'better-snapshot-nodes-docs' into 'main'
gtk: Improve documentation on returned nodes for snapshot

Closes #5747

See merge request GNOME/gtk!5831
2023-04-15 10:51:39 +00:00
Matthias Clasen d67101d46e Tweak the wording 2023-04-15 10:35:12 +00:00
Benjamin Otte 60f3cc398a Merge branch 'wip/otte/for-main' into 'main'
inspector: Don't randomly emit application signals

See merge request GNOME/gtk!5834
2023-04-15 03:40:00 +00:00
Benjamin Otte e010cd242c listlistmodel: Add a cache
Cache the last looked up item and use it for looking up the next item if
it's closest. This massively speeds up iteration over the model, because
each call to get_item() will be adjacent to the previous one.

Improves performance of the inspector quite a bit.
2023-04-15 05:27:47 +02:00
Benjamin Otte 41454b63b4 testsuite: Add some more exhaustive testing to listlistmodel 2023-04-15 05:27:47 +02:00
Benjamin Otte f458951745 inspector: Don't randomly emit application signals
When the variant-editor emits a callback, it might not actually have
edited the value in question. Try to detect that by only emitting
signals if the value changed.
2023-04-15 05:27:47 +02:00
Benjamin Otte ef3793ec37 Merge branch 'gbsneto/vulkan-buffer-release' into 'main'
gsk/vulkan/render: Download image before reset

See merge request GNOME/gtk!5832
2023-04-14 23:28:55 +00:00
Georges Basile Stavracas Neto 94b1a78378 gsk/vulkan/render: Download image before reset
gsk_vulkan_render_download_target() currently resets the uploader
objects before downloading the image that it produces. This is
problematic because there might be unreleased buffers and images
in the command queue.

In particular, this can make validation layers complain about the
glyph atlas - of all things! - upload buffer being released while
still being used by the command queue.

Fix that by resetting the uploader after downloading the image.
2023-04-14 16:43:04 -03:00
Marco Trevisan (Treviño) 584fd36a5f gtk: Improve documentation on returned nodes for snapshot
Closes: #5747
2023-04-14 18:05:21 +02:00
Emmanuele Bassi 4ea818fee6 Add GtkButton:can-shrink
For certain kinds of layouts, especially ones where one or both sizes of
a top level is constrained by physical limits, it's acceptable to have
buttons that rely on the minimum size of their contents, rather than the
natural size. It is left to the application authors, or the localization
teams, to ensure that things like translations and font sizes do not
result in a broken UI.
2023-04-14 15:00:07 +01:00
Olivier Crête c271cd1a3f pathbar: Handle webdav where is the root is a path
Our webdav server has a root which is davs://mynextcloud/remote.php/webdav
When once creates a GFile out of or out of a subdirectory, and one call
g_file_get_parent(), it recurses too far up and try to query
davs://mynextcloud/remote.php which fails, resulting in a broken pathbar.

To fix that, before querying the metadata of each element of the path,
I query the "enclosing mount", then use it's root to compare the GFile
against.

With the right GMount, we can also fix the icon drawing code in the
pathbar for network drives.
2023-04-13 17:54:57 -06:00
Matthias Clasen 64a1969293 Merge branch 'fix_scalebutton_orientation' into 'main'
ScaleButton: fix CSS name in documentation, fix orientation doing nothing

See merge request GNOME/gtk!5819
2023-04-13 20:44:23 +00:00
Matthias Clasen 2baab9732c Merge branch 'check-openuri-portal-version' into 'main'
openuriportal: Detect if the interface isn't there

Closes #5733

See merge request GNOME/gtk!5826
2023-04-13 20:44:03 +00:00
Georges Basile Stavracas Neto 8134daf843 Merge branch 'gbsneto/vulkan-mailbox' into 'main'
gdk/vulkancontext: Use more appropriate present mode

See merge request GNOME/gtk!5828
2023-04-13 17:07:59 +00:00
Georges Basile Stavracas Neto 9c013d40c1 gdk/vulkancontext: Use more appropriate present mode
Check if the driver supports MAILBOX and prefer using it; in its
absense, checkif the driver supports IMMEDIATE and prefer using
it; finally, if neither of them are supported, use the guaranteed
to be supported FIFO mode.
2023-04-13 13:54:45 -03:00
Benjamin Otte d798372a53 Merge branch 'wip/otte/for-main' into 'main'
x11: Remove commented outdated code

See merge request GNOME/gtk!5827
2023-04-13 15:34:48 +00:00
Benjamin Otte cfaf1b3e71 x11: Remove commented outdated code
... and it's copy/paste into the win32 backend
2023-04-13 17:15:35 +02:00
Benjamin Otte 9763d83a9d gdk: Remove unused vfunc 2023-04-13 17:15:35 +02:00
Benjamin Otte 5f82a496cb Merge branch 'wip/otte/wl-gloria-gaynor' into 'main'
wayland: Make wl_surface survive until surface is desstroyed

See merge request GNOME/gtk!5825
2023-04-13 15:12:07 +00:00
Matthias Clasen 0c35015c44 Merge branch 'wip/exalm/print-dialog' into 'main'
printunixdialog: Remove a redundant style class

See merge request GNOME/gtk!5823
2023-04-13 05:39:08 +00:00
Matthias Clasen 3da0572078 openuriportal: Detect if the interface isn't there
Check the portal version number before trying to use
it. Most importantly, this will detect the case where
the interface isn't supported at all, since the proxy
will report a version of 0 in that case.

Fixes: #5733
2023-04-13 07:24:38 +02:00
Matthias Clasen c649d8a4ec Merge branch 'bilelmoussaoui/g-i' into 'main'
g-i: Fix GtkGLArea type name

See merge request GNOME/gtk!5824
2023-04-13 04:37:45 +00:00
Benjamin Otte 75bea01a86 wayland: Keep EGL window around when hidden
See previous commit:

We want to keep resources around as long as the surface exists.
2023-04-13 05:19:18 +02:00
Benjamin Otte 5d3cec5441 wayland: Don't destroy the wl_surface on hide()
We want to keep the wl_surface around, because surfaces create their
resources on construct and keep them until destroyed. See the HWND ond
Windows and the XWindow on X11.

This is relevant for graphics resources, where we want to have access
to the VkSurface and eglSurface while the GdkSurface is hidden.
We also want these surfaces to be permanent and not change during the
lifetime of the GdkSurface.

What we can - and must - destroy however are the xdg surfaces, because
those handle visibility on screen.
And we also need to ensure no buffer is attached, so that during the
next creation of the xdg surface we don't get a protocol error.
2023-04-13 04:23:35 +02:00
Benjamin Otte 891242920e wayland: Split out a function
We have a create_wl_surface(), create a matching destroy_wl_surface().
2023-04-13 02:56:12 +02:00
Benjamin Otte b375f17f09 wayland: Remove useless function
gdk_wayland_surface_maybe_resize() just calls
gdk_wayland_surface_update_size(), so make all callers call that one
instead.

The check that it does is done by the other function again.
2023-04-13 02:48:47 +02:00
Benjamin Otte ec69990126 wayland: Remove an old workaround
This workaround - were it ever to trigger - is broken today. It destroys
the wl_surface and all associated structs but does not recreate the
xdg_popup or xdg_toplevel struct, so it would cause a hidden window.

The workaround looked a lot different when it was introduced in commit
83b54bab57, too - both in what it did and
in what the vfuncs did that it called.
2023-04-13 02:44:05 +02:00
Bilal Elmoussaoui aec5a5739e g-i: Fix GtkGLArea type name 2023-04-12 18:12:40 +00:00
Alexander Mikhaylenko ac9e0039b8 printunixdialog: Remove a redundant style class
.view does absolutely nothing in Default style since the whole box is
covered with a GtkNotebook which has its own background, and adds an
unwanted background onto the tab strip in Adwaita.
2023-04-12 21:09:25 +04:00
Matthias Clasen 4574b21fd6 Merge branch 'dialogs-force-window-destruction' into 'main'
gtk/dialogs: Destroy the window promptly on finish async function

Closes #5741

See merge request GNOME/gtk!5820
2023-04-12 13:54:13 +00:00
Marco Trevisan (Treviño) 31c5961c4f gtk/dialogs: Destroy the window promptly on finish async function
Some bindings (GJS!) could add temporary references to the GAsyncResult
argument that we return, and thus to the GTask, which may cause the
dialog not to close when the finish function is called (but at garbage
collection instead!).

To prevent this, just manually destroy the window (by removing the task
data), so that we are not bound to the GTask lifetime anymore.

Closes: https://gitlab.gnome.org/GNOME/gtk/-/issues/5741
2023-04-12 15:39:39 +02:00
Matthias Clasen 8fc3f06155 Merge branch 'filechooserentry-fixes' into 'main'
filechooserentry: Make filtering work again

Closes #5743

See merge request GNOME/gtk!5822
2023-04-12 10:38:04 +00:00
Matthias Clasen 5327203201 Merge branch 'wip/carlosg/multi-click-text-view' into 'main'
textview: Reset press counter if double/triple clicking on a different line

See merge request GNOME/gtk!5821
2023-04-12 10:11:16 +00:00
Matthias Clasen 8442fce962 Merge branch 'touch-no-double-click-threshold' into 'main'
gestureclick: Don't use threshold for touch

Closes #5580

See merge request GNOME/gtk!5798
2023-04-12 10:10:31 +00:00
Matthias Clasen d8b46c16cc Merge branch 'stylus-fixes' into 'main'
gtk-demo: Test stylus-only mode

See merge request GNOME/gtk!5804
2023-04-12 10:10:11 +00:00
Matthias Clasen 4df7273266 filechooserentry: Plug a memory leak 2023-04-12 12:09:02 +02:00
Matthias Clasen 2b8fd89fd5 filechooserentry: Make filtering work again
We need to look at the filchooser::filtered-out
attribute to know which files the filesystem model
has filtered away.

Fixes: #5743
2023-04-12 12:08:43 +02:00
Carlos Garnacho 5b9a7863cf textview: Reset press counter if double/triple clicking on a different line
If we click close enough between lines, and with the maximum distances applied
by GtkGestureClick we could jump between lines when handling double/triple
click for word/line selection.

Ensure that the whole operation stays in the same line and reset the
gesture/counter if we do move between lines, so we start from scratch in the
new line.
2023-04-12 11:27:41 +02:00
G.Willems d625ff8106 scalebutton: fix orientation not applied to scale 2023-04-11 23:54:06 +02:00
G.Willems 5ecd8a1c10 scalebutton: fix CSS name in documentation 2023-04-11 22:06:54 +02:00
Matthias Clasen e9f7a9b8e6 Merge branch 'matthiasc/for-main' into 'main'
filechooser: Fix the gridview

See merge request GNOME/gtk!5817
2023-04-11 06:10:56 +00:00
Matthias Clasen 93b1130c07 filechooser: Fix the gridview
2a70093a30 was a bit overeager in its porting
to GtkColumnViewCell. The gridview needs to keep its
list items.
2023-04-11 07:41:09 +02:00
Matthias Clasen db48cd6467 Merge branch 'wip/corey/file-chooser-widget' into 'main'
More fixes to filechooserwidget

See merge request GNOME/gtk!5815
2023-04-11 05:32:38 +00:00
Matthias Clasen ba43a126b9 Merge branch 'wip/corey/filesystemmodel' into 'main'
filesystemmodel: Notify correct position removed in remove_file()

See merge request GNOME/gtk!5814
2023-04-11 05:27:24 +00:00
Corey Berla 2a70093a30 filechooser: Set date and time after cell is a child of filechooserwidget
The date/time column relies on the filechooserwidget to format the date
properly.  During bind, the filechoosercell, get the filechooserwidget
ancestor, but now due to changes in the listview, the cell isn't a
child of the filechooserwidget at that point.  Since this is deeply
ingrained into the filechooserwidget, let's keep the same behavior,
but move it to filechoosercell in realize.  Alternatively, we could have
used a signal factory (with the file chooser widget as the user data),
but that would have been a major overhaul.
2023-04-10 18:02:35 -07:00
Corey Berla dd407dab00 filechoosercell: Store type_format in filechoosercell
The format of the type column depends on the the type_format, which
is stored in the filechooserwidget.  We get that setting by looking
for the filechooserwidget ancestor, which no longer works after recent
changes to the list views (it was fragile to begin with).  At one point,
the setting appears to have been dynamic, but now it is only loading
from GSettings, so let's simply do the same within FileChooserCell.
2023-04-10 18:02:35 -07:00
Corey Berla ccae75022b filechooserwidget: Finish port to GtkColumnViewCell
Some missing updates from f5dea9a3c2
2023-04-10 18:02:24 -07:00
Corey Berla faac2f7894 filesystemmodel: Notify correct position removed in remove_file()
32247bc50e made several changes to account for the
fact that we no longer have a NULL editable at the beginning of the list
model.  The commit mistakenly left out one change in remove_file(),
which causes the wrong file to be removed.
2023-04-10 12:56:08 -07:00
Matthias Clasen d00b78d283 Merge branch 'matthiasc/for-main' into 'main'
node-editor: Typo fixes

See merge request GNOME/gtk!5812
2023-04-10 14:28:38 +00:00
Matthias Clasen 3eee1c0724 node-editor: Typo fixes
Fix some typos in the node format documentation.
2023-04-10 16:04:17 +02:00
Matthias Clasen 5e6bc681a3 Merge branch 'scrolled-window-critical' into 'main'
scrolledwindow: Avoid a critical

See merge request GNOME/gtk!5809
2023-04-10 05:50:20 +00:00
Matthias Clasen 87e16f3ad9 testsuite: Check widget properties better
Check that setting a property after resetting
it works. An instance of this was fixed in the
previous commit.
2023-04-10 00:24:57 -04:00
Matthias Clasen aa9e83876d scrolledwindow: Avoid a critical
When setting the child property to NULL, we also need
to unset auto_added_viewport, to avoid triggering a
critical when setting it again.
2023-04-10 00:22:20 -04:00
Matthias Clasen d8796b3075 Merge branch 'warn-show-destoyed-window' into 'main'
Show a warning when a destroyed window is shown

See merge request GNOME/gtk!5122
2023-04-09 20:16:52 +00:00
Matthias Clasen cefd720789 Merge branch 'matthiasc/for-main' into 'main'
gtk-demo: Add a keyword

See merge request GNOME/gtk!5805
2023-04-09 13:02:55 +00:00
Matthias Clasen e12669e230 gesture stylus: Fix condition
Now that the paint demo lets us test this, it has
become apparent that this condition is wrong, and
we don't get the expected events if stylus-only is
FALSE.
2023-04-09 08:35:03 -04:00
Matthias Clasen 7f906bef06 gtk-demo: Work without stylus
In the paint demo, don't assume that the event
backlog contains pressure. It won't, if we are
working with a plain old mouse.
2023-04-09 08:35:03 -04:00
Matthias Clasen 5970a14217 gtk-demo: Test stylus-only mode
Add a checkbutton to toggle the stylus-only
mode of GtkGestureStylus, so we can test this.
2023-04-09 08:35:03 -04:00
Matthias Clasen 2c3f82fd01 Tweak the wording of the message. 2023-04-08 16:14:52 +00:00
Matthias Clasen 5f4a6210c2 gestureclick: Use drag threshold for updates 2023-04-07 17:57:14 -04:00
Matthias Clasen c0fa9e80aa gestureclick: Don't use threshold for touch
When determining double-clicks, don't use the distance
threshold for touch events. It is very hard to double
touch reliably within a few pixels of the same position.

Fixes: #5580
2023-04-07 17:57:14 -04:00
Aaron Erhardt 2fde4c9a5f Show a warning when a destroyed window is shown
Showing a destroyed window might cause an application to
behave in an unexpected manner. For example, showing a
dialog after it has been closed by the user might cause the
application to freeze. The warning will help developers to
track down the issue.

Signed-off-by: Aaron Erhardt <aaron.erhardt@t-online.de>
2022-10-16 14:24:27 +02:00
Lukáš Tyrychtr 33e5d2c307 GtkShortcutsWindow: Allow a screen reader user to browse the available shortcuts
That required making the shortcuts focusable and with a meaningful
accessibility labels.
2022-09-21 15:34:17 +02:00
Hannes Müller f23c124af2 Harmonize would_drop() replacement for g_log_writer_default_would_drop()
Reuse a better to read would_drop() from ./testsuite/reftests/gtk-reftest.c
in ./tools/gtk-builder-tool.c

Fixed wrong indentation in ./testsuite/reftests/gtk-reftest.c
2022-08-08 20:12:50 +02:00
vanadiae b4b185d53d builder: Clarify default "swapped" value when "object" is set for signals
I encountered this issue where I casted user_data to my self type, but it
showed me they were actually swapped when I set the "object" signal attribute.
After checking the source code which confirms this, it is a good idea to
properly document that convenient behaviour.
2022-02-24 23:04:20 +01:00
303 changed files with 11326 additions and 8216 deletions
+6 -29
View File
@@ -26,7 +26,7 @@ variables:
BACKEND_FLAGS: "-Dx11-backend=true -Dwayland-backend=true -Dbroadway-backend=true"
FEATURE_FLAGS: "-Dvulkan=enabled -Dcloudproviders=enabled -Ddemos=false -Dbuild-examples=false -Dbuild-tests=false -Dbuild-testsuite=true"
MESON_TEST_TIMEOUT_MULTIPLIER: 3
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v42"
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v46"
workflow:
rules:
@@ -57,15 +57,9 @@ style-check-diff:
reports:
junit:
- "${CI_PROJECT_DIR}/_build/report-x11.xml"
- "${CI_PROJECT_DIR}/_build/report-x11_unstable.xml"
- "${CI_PROJECT_DIR}/_build/report-wayland.xml"
- "${CI_PROJECT_DIR}/_build/report-wayland_unstable.xml"
- "${CI_PROJECT_DIR}/_build/report-wayland_gles.xml"
- "${CI_PROJECT_DIR}/_build/report-wayland_gles_unstable.xml"
- "${CI_PROJECT_DIR}/_build/report-wayland_smalltexture.xml"
- "${CI_PROJECT_DIR}/_build/report-wayland_smalltexture_unstable.xml"
- "${CI_PROJECT_DIR}/_build/report-broadway.xml"
- "${CI_PROJECT_DIR}/_build/report-broadway_unstable.xml"
name: "gtk-${CI_COMMIT_REF_NAME}"
paths:
- "${CI_PROJECT_DIR}/_build/meson-logs"
@@ -76,6 +70,7 @@ style-check-diff:
- "${CI_PROJECT_DIR}/_build/testsuite/tools/output/*/*"
- "${CI_PROJECT_DIR}/_build/testsuite/gsk/compare/*/*/*.png"
- "${CI_PROJECT_DIR}/_build/testsuite/css/output/*/*.syscap"
- "${CI_PROJECT_DIR}/_build/testsuite/headless/*/*.log"
- "${CI_PROJECT_DIR}/_build_hello/meson-logs"
cache:
key: "$CI_JOB_NAME"
@@ -91,7 +86,6 @@ fedora-x86_64:
script:
- .gitlab-ci/show-info-linux.sh
- export PATH="$HOME/.local/bin:$PATH"
- pip3 install --user meson~=0.64
- meson subprojects download
- meson subprojects update --reset
- mkdir _install
@@ -109,7 +103,6 @@ fedora-x86_64:
- .gitlab-ci/run-tests.sh _build x11
- .gitlab-ci/run-tests.sh _build wayland
- .gitlab-ci/run-tests.sh _build wayland_gles
- .gitlab-ci/run-tests.sh _build wayland_smalltexture
- .gitlab-ci/run-tests.sh _build broadway
release-build:
@@ -121,7 +114,6 @@ release-build:
script:
- .gitlab-ci/show-info-linux.sh
- export PATH="$HOME/.local/bin:$PATH"
- pip3 install --user meson~=0.64
- meson subprojects download
- meson subprojects update --reset
- meson setup
@@ -152,23 +144,11 @@ fedora-mingw64:
script:
- .gitlab-ci/show-info-linux.sh
- export PATH="$HOME/.local/bin:$PATH"
- pip3 install --user meson~=0.64
- pip3 install --user meson~=1.0
- meson subprojects download
- meson subprojects update --reset
# Test that mingw64-meson still fails. If it has stopped failing, the CI
# will fail and now you should remove the hack that follows this.
- FAILED=false
- mingw64-meson --version || FAILED=true
- test $FAILED = false && echo "mingw64-meson works now, remove the hack" && exit 1
# HACK: Running mingw64-meson directly fails on the CI with:
# /usr/bin/mingw64-meson: line 92: fg: no job control
# Because rpm is not evaluating %__meson and it gets interpreted as a job
# specifier. So we fix that and run it ourselves.
- rpm --eval "%{mingw64_meson}" > mingw64-meson.sh
- sed -i -e 's/%__meson/meson/' mingw64-meson.sh
- chmod +x mingw64-meson.sh
- ./mingw64-meson.sh -Dintrospection=disabled -Dgraphene:introspection=disabled _build
- ninja -C _build
- meson -Dintrospection=disabled -Dgraphene:introspection=disabled _build
- meson compile -C _build
.mingw-defaults:
stage: build
@@ -210,7 +190,7 @@ macos:
needs: []
before_script:
- bash .gitlab-ci/show-info-osx.sh
- pip3 install --user meson~=0.64
- pip3 install --user meson~=1.0
- pip3 install --user ninja
- export PATH=/Users/gitlabrunner/Library/Python/3.7/bin:$PATH
- export MESON_FORCE_BACKTRACE=1
@@ -368,7 +348,6 @@ static-scan:
EXTRA_MESON_FLAGS: "--buildtype=debug"
script:
- export PATH="$HOME/.local/bin:$PATH"
- pip3 install --user meson~=0.64
- meson setup
${COMMON_MESON_FLAGS}
${EXTRA_MESON_FLAGS}
@@ -390,7 +369,6 @@ asan-build:
variables:
script:
- export PATH="$HOME/.local/bin:$PATH"
- pip3 install --user meson~=0.64
- CC=clang meson setup --buildtype=debugoptimized -Db_sanitize=address -Db_lundef=false -Dintrospection=disabled -Df16c=disabled _build
- ninja -C _build
- .gitlab-ci/run-tests.sh _build wayland
@@ -405,7 +383,6 @@ reference:
needs: []
script:
- export PATH="$HOME/.local/bin:$PATH"
- pip3 install --user meson~=0.64
- meson setup
${COMMON_MESON_FLAGS}
--buildtype=release
+6 -1
View File
@@ -32,7 +32,6 @@ RUN dnf -y install \
glib2-static \
glibc-devel \
glibc-headers \
gnome-desktop-testing \
gnupg2 \
gobject-introspection-devel \
graphene-devel \
@@ -73,10 +72,14 @@ RUN dnf -y install \
mesa-dri-drivers \
mesa-libEGL-devel \
mesa-libGLES-devel \
meson \
mutter \
ninja-build \
pango-devel \
pcre-devel \
pcre-static \
pipewire \
pipewire-gstreamer \
python3 \
python3-docutils \
python3-gobject \
@@ -84,6 +87,7 @@ RUN dnf -y install \
python3-markdown \
python3-packaging \
python3-pip \
python3-pydbus \
python3-pygments \
python3-typogrify \
python3-wheel \
@@ -95,6 +99,7 @@ RUN dnf -y install \
weston \
weston-libs \
which \
wireplumber \
xorg-x11-server-Xvfb \
&& dnf clean all
+2 -1
View File
@@ -138,7 +138,8 @@ if [ $run == 1 ]; then
echo -e "\e[1;32mRUNNING\e[0m: ${base} as ${TAG}"
${CMD} run \
--rm \
--volume "$(pwd)/..:/home/user/app" \
--userns=keep-id \
--volume "$(pwd)/..:/home/user/app:rw,z" \
--workdir "/home/user/app" \
--tty \
--interactive "${TAG}" \
+18 -36
View File
@@ -6,6 +6,7 @@ set +e
srcdir=$( pwd )
builddir=$1
backend=$2
multiplier=${MESON_TEST_TIMEOUT_MULTIPLIER:-1}
# Ignore memory leaks lower in dependencies
export LSAN_OPTIONS=suppressions=$srcdir/lsan.supp:print_suppressions=0:verbosity=1:log_threads=1
@@ -15,7 +16,8 @@ case "${backend}" in
x11)
xvfb-run -a -s "-screen 0 1024x768x24 -noreset" \
meson test -C ${builddir} \
--timeout-multiplier "${MESON_TEST_TIMEOUT_MULTIPLIER}" \
--quiet \
--timeout-multiplier "${multiplier}" \
--print-errorlogs \
--setup=${backend} \
--suite=gtk \
@@ -26,14 +28,6 @@ case "${backend}" in
# Store the exit code for the CI run, but always
# generate the reports
exit_code=$?
xvfb-run -a -s "-screen 0 1024x768x24 -noreset" \
meson test -C ${builddir} \
--timeout-multiplier "${MESON_TEST_TIMEOUT_MULTIPLIER}" \
--print-errorlogs \
--setup=${backend}_unstable \
--suite=flaky \
--suite=failing || true
;;
wayland*)
@@ -44,22 +38,17 @@ case "${backend}" in
export WAYLAND_DISPLAY=wayland-5
meson test -C ${builddir} \
--timeout-multiplier "${MESON_TEST_TIMEOUT_MULTIPLIER}" \
--quiet \
--timeout-multiplier "${multiplier}" \
--print-errorlogs \
--setup=${backend} \
--suite=gtk \
--no-suite=failing \
--no-suite=flaky \
--no-suite=${backend}_failing \
--no-suite=gsk-compare-broadway
exit_code=$?
meson test -C ${builddir} \
--timeout-multiplier "${MESON_TEST_TIMEOUT_MULTIPLIER}" \
--print-errorlogs \
--setup=${backend}_unstable \
--suite=flaky \
--suite=failing || true
kill ${compositor}
;;
@@ -71,7 +60,8 @@ case "${backend}" in
export BROADWAY_DISPLAY=:5
meson test -C ${builddir} \
--timeout-multiplier "${MESON_TEST_TIMEOUT_MULTIPLIER}" \
--quiet \
--timeout-multiplier "${multiplier}" \
--print-errorlogs \
--setup=${backend} \
--suite=gtk \
@@ -82,13 +72,6 @@ case "${backend}" in
# don't let Broadway failures fail the run, for now
exit_code=0
meson test -C ${builddir} \
--timeout-multiplier "${MESON_TEST_TIMEOUT_MULTIPLIER}" \
--print-errorlogs \
--setup=${backend}_unstable \
--suite=flaky \
--suite=failing || true
kill ${server}
;;
@@ -101,20 +84,19 @@ esac
cd ${builddir}
for suffix in "" "_unstable"; do
$srcdir/.gitlab-ci/meson-junit-report.py \
$srcdir/.gitlab-ci/meson-junit-report.py \
--project-name=gtk \
--backend="${backend}${suffix}" \
--backend="${backend}" \
--job-id="${CI_JOB_NAME}" \
--output="report-${backend}${suffix}.xml" \
"meson-logs/testlog-${backend}${suffix}.json"
$srcdir/.gitlab-ci/meson-html-report.py \
--output="report-${backend}.xml" \
"meson-logs/testlog-${backend}.json"
$srcdir/.gitlab-ci/meson-html-report.py \
--project-name=gtk \
--backend="${backend}${suffix}" \
--backend="${backend}" \
--job-id="${CI_JOB_NAME}" \
--reftest-output-dir="testsuite/reftests/output/${backend}${suffix}" \
--output="report-${backend}${suffix}.html" \
"meson-logs/testlog-${backend}${suffix}.json"
done
--reftest-output-dir="testsuite/reftests/output/${backend}" \
--output="report-${backend}.html" \
"meson-logs/testlog-${backend}.json"
exit $exit_code
+68
View File
@@ -1,6 +1,74 @@
Overview of Changes in 4.11.2, xx-xx-xxxx
=========================================
* GtkGLArea:
- Add an allowed-apis property
* GtkListBox:
- Fix a problem with gtk_list_box_remove_all
* GtkCenterBox:
- Add a shrink-center-last property
* GtkButton, GtkMenuButton:
- Add a can-shrink property
* GtkPopover:
- Fix problems with grabs
* GtkFileChooser:
- Fix a problem with removing files
- Make the date, time and location columns work
- Fix filtering in the save entry popup
- A few memory leak fixes
- Handle webdav in the pathbar
* Dialogs:
- Destroy windows promptly when the async callback finishes
- Detect absence of the OpenURI portal and fall back
* Theme:
- Add explicit style classes to a number of widgets
- Fix some contrast issues in the dark theme
* Accessibility:
- Fix alert dialogs in the a11y tree
* Layout:
- Some fixes to baseline alignment
* GL:
- Add GdkGLTextureBuilder, a more flexible api for creating textures
- Ensure that we work with GLES 2
* Vulkan:
- More fixes to the experimental Vulkan renderer
- Rework glyph caching
* Wayland:
- Don't destroy wl_surfaces on hide
- Plug leaks of compositor-side resources
* Inspector:
- Improve the action list
- Fix a crash
* Tools:
- gtk4-node-editor: Improve scaling
- gtk4-node-editor: Preserve aspect ratio of textures
- gtk4-demo: Make the stylus demo work with mice
* Translation updates
Bulgarian
Chinese (China)
Galician
Hebrew
Polish
Portuguese
Russian
Turkish
Overview of Changes in 4.11.1, 03-04-2023
=========================================
+5 -12
View File
@@ -116,19 +116,12 @@ docs/reference/gtk/html/gtk-building.html
Or [online](https://docs.gtk.org/gtk4/building.html)
Default branch renamed to `main`
--------------------------------
Building from git
-----------------
The default development branch of GTK has been renamed to `main`.
To update your local checkout, use:
```sh
git checkout master
git branch -m master main
git fetch
git branch --unset-upstream
git branch -u origin/main
git symbolic-ref refs/remotes/origin/HEAD refs/remotes/origin/main
```
The GTK sources are hosted on [gitlab.gnome.org](http://gitlab.gnome.org). The main
development branch is called `main`, and stable branches are named after their minor
version, for example `gtk-4-10`.
How to report bugs
------------------
+10 -4
View File
@@ -109,15 +109,21 @@ static void
apply_transform (CanvasItem *item)
{
GskTransform *transform;
graphene_rect_t bounds;
double x, y;
x = gtk_widget_get_allocated_width (item->label) / 2.0;
y = gtk_widget_get_allocated_height (item->label) / 2.0;
item->r = sqrt (x*x + y*y);
/* Add css padding and margin */
if (!gtk_widget_compute_bounds (item->label, item->label, &bounds))
return;
x = bounds.size.width / 2.;
y = bounds.size.height / 2.;
item->r = sqrt (x * x + y * y);
transform = gsk_transform_translate (NULL, &(graphene_point_t) { item->r, item->r });
transform = gsk_transform_rotate (transform, item->angle + item->delta);
transform = gsk_transform_translate (transform, &(graphene_point_t) { -x, -y });
transform = gsk_transform_translate (transform, &GRAPHENE_POINT_INIT (-x, -y));
gtk_fixed_set_child_transform (GTK_FIXED (item->fixed), item->label, transform);
gsk_transform_unref (transform);
+6 -6
View File
@@ -42,8 +42,8 @@ val_to_xy (GtkFontPlane *plane,
double u, v;
int width, height;
width = gtk_widget_get_allocated_width (GTK_WIDGET (plane));
height = gtk_widget_get_allocated_height (GTK_WIDGET (plane));
width = gtk_widget_get_width (GTK_WIDGET (plane));
height = gtk_widget_get_height (GTK_WIDGET (plane));
u = adjustment_get_normalized_value (plane->width_adj);
v = adjustment_get_normalized_value (plane->weight_adj);
@@ -62,8 +62,8 @@ plane_snapshot (GtkWidget *widget,
cairo_t *cr;
val_to_xy (plane, &x, &y);
width = gtk_widget_get_allocated_width (widget);
height = gtk_widget_get_allocated_height (widget);
width = gtk_widget_get_width (widget);
height = gtk_widget_get_height (widget);
cr = gtk_snapshot_append_cairo (snapshot,
&GRAPHENE_RECT_INIT (0, 0, width, height));
@@ -131,8 +131,8 @@ update_value (GtkFontPlane *plane,
GtkWidget *widget = GTK_WIDGET (plane);
double u, v;
u = CLAMP (x * (1.0 / gtk_widget_get_allocated_width (widget)), 0, 1);
v = CLAMP (1 - y * (1.0 / gtk_widget_get_allocated_height (widget)), 0, 1);
u = CLAMP (x * (1.0 / gtk_widget_get_width (widget)), 0, 1);
v = CLAMP (1 - y * (1.0 / gtk_widget_get_height (widget)), 0, 1);
adjustment_set_normalized_value (plane->width_adj, u);
adjustment_set_normalized_value (plane->weight_adj, v);
+2
View File
@@ -64,6 +64,8 @@
</child>
<child>
<object class="GtkLabel" id="short_time_label">
<property name="hexpand">1</property>
<property name="xalign">1</property>
<property name="valign">baseline</property>
<property name="label" translatable="yes">38m</property>
<style>
+26 -8
View File
@@ -24,6 +24,7 @@ typedef struct
GdkRGBA draw_color;
GtkPadController *pad_controller;
double brush_size;
GtkGesture *gesture;
} DrawingArea;
typedef struct
@@ -260,7 +261,7 @@ drawing_area_apply_stroke (DrawingArea *area,
double y,
double pressure)
{
if (gdk_device_tool_get_tool_type (tool) == GDK_DEVICE_TOOL_TYPE_ERASER)
if (tool && gdk_device_tool_get_tool_type (tool) == GDK_DEVICE_TOOL_TYPE_ERASER)
{
cairo_set_line_width (area->cr, 10 * pressure * area->brush_size);
cairo_set_operator (area->cr, CAIRO_OPERATOR_DEST_OUT);
@@ -311,7 +312,9 @@ stylus_gesture_motion (GtkGestureStylus *gesture,
drawing_area_apply_stroke (area, tool,
backlog[i].axes[GDK_AXIS_X],
backlog[i].axes[GDK_AXIS_Y],
backlog[i].axes[GDK_AXIS_PRESSURE]);
backlog[i].flags & GDK_AXIS_FLAG_PRESSURE
? backlog[i].axes[GDK_AXIS_PRESSURE]
: 1);
}
g_free (backlog);
@@ -341,6 +344,8 @@ drawing_area_init (DrawingArea *area)
area->draw_color = (GdkRGBA) { 0, 0, 0, 1 };
area->brush_size = 1;
area->gesture = gesture;
}
static GtkWidget *
@@ -379,6 +384,12 @@ drawing_area_color_set (DrawingArea *area,
gtk_color_dialog_button_set_rgba (button, color);
}
static GtkGesture *
drawing_area_get_gesture (DrawingArea *area)
{
return area->gesture;
}
GtkWidget *
do_paint (GtkWidget *toplevel)
{
@@ -386,7 +397,7 @@ do_paint (GtkWidget *toplevel)
if (!window)
{
GtkWidget *draw_area, *headerbar, *colorbutton;
GtkWidget *draw_area, *headerbar, *button;
window = gtk_window_new ();
@@ -395,15 +406,22 @@ do_paint (GtkWidget *toplevel)
headerbar = gtk_header_bar_new ();
colorbutton = gtk_color_dialog_button_new (gtk_color_dialog_new ());
g_signal_connect (colorbutton, "notify::rgba",
button = gtk_color_dialog_button_new (gtk_color_dialog_new ());
g_signal_connect (button, "notify::rgba",
G_CALLBACK (color_button_color_set), draw_area);
g_signal_connect (draw_area, "color-set",
G_CALLBACK (drawing_area_color_set), colorbutton);
gtk_color_dialog_button_set_rgba (GTK_COLOR_DIALOG_BUTTON (colorbutton),
G_CALLBACK (drawing_area_color_set), button);
gtk_color_dialog_button_set_rgba (GTK_COLOR_DIALOG_BUTTON (button),
&(GdkRGBA) { 0, 0, 0, 1 });
gtk_header_bar_pack_end (GTK_HEADER_BAR (headerbar), colorbutton);
gtk_header_bar_pack_end (GTK_HEADER_BAR (headerbar), button);
button = gtk_check_button_new_with_label ("Stylus only");
g_object_bind_property (button, "active",
drawing_area_get_gesture ((DrawingArea *)draw_area), "stylus-only",
G_BINDING_SYNC_CREATE);
gtk_header_bar_pack_start (GTK_HEADER_BAR (headerbar), button);
gtk_window_set_titlebar (GTK_WINDOW (window), headerbar);
gtk_window_set_title (GTK_WINDOW (window), "Paint");
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
+1 -1
View File
@@ -471,7 +471,7 @@ suggestion_entry_size_allocate (GtkWidget *widget,
&(GtkAllocation) { width - arrow_nat, 0, arrow_nat, height },
baseline);
gtk_widget_set_size_request (self->popup, gtk_widget_get_allocated_width (GTK_WIDGET (self)), -1);
gtk_widget_set_size_request (self->popup, gtk_widget_get_width (GTK_WIDGET (self)), -1);
gtk_widget_queue_resize (self->popup);
gtk_popover_present (GTK_POPOVER (self->popup));
+2
View File
@@ -78,6 +78,8 @@ gtk_renderer_paintable_paintable_snapshot (GdkPaintable *paintable,
gdk_paintable_snapshot (GDK_PAINTABLE (texture), snapshot, width, height);
g_object_unref (texture);
gsk_render_node_unref (node);
}
static int
+30 -10
View File
@@ -64,6 +64,7 @@ struct _NodeEditorWindow
GListStore *renderers;
GskRenderNode *node;
GFile *file;
GFileMonitor *file_monitor;
GArray *errors;
@@ -544,12 +545,14 @@ node_editor_window_load (NodeEditorWindow *self,
{
GError *error = NULL;
g_clear_object (&self->file);
g_clear_object (&self->file_monitor);
if (!load_file_contents (self, file))
return FALSE;
self->file_monitor = g_file_monitor_file (file, G_FILE_MONITOR_NONE, NULL, &error);
self->file = g_object_ref (file);
self->file_monitor = g_file_monitor_file (self->file, G_FILE_MONITOR_NONE, NULL, &error);
if (error)
{
@@ -586,13 +589,21 @@ static void
show_open_filechooser (NodeEditorWindow *self)
{
GtkFileDialog *dialog;
GFile *cwd;
dialog = gtk_file_dialog_new ();
gtk_file_dialog_set_title (dialog, "Open node file");
cwd = g_file_new_for_path (".");
gtk_file_dialog_set_initial_folder (dialog, cwd);
g_object_unref (cwd);
if (self->file)
{
gtk_file_dialog_set_initial_file (dialog, self->file);
}
else
{
GFile *cwd;
cwd = g_file_new_for_path (".");
gtk_file_dialog_set_initial_folder (dialog, cwd);
g_object_unref (cwd);
}
gtk_file_dialog_open (dialog, GTK_WINDOW (self),
NULL, open_response_cb, self);
g_object_unref (dialog);
@@ -650,14 +661,21 @@ save_cb (GtkWidget *button,
NodeEditorWindow *self)
{
GtkFileDialog *dialog;
GFile *cwd;
dialog = gtk_file_dialog_new ();
gtk_file_dialog_set_title (dialog, "Save node");
cwd = g_file_new_for_path (".");
gtk_file_dialog_set_initial_folder (dialog, cwd);
gtk_file_dialog_set_initial_name (dialog, "demo.node");
g_object_unref (cwd);
if (self->file)
{
gtk_file_dialog_set_initial_file (dialog, self->file);
}
else
{
GFile *cwd = g_file_new_for_path (".");
gtk_file_dialog_set_initial_folder (dialog, cwd);
gtk_file_dialog_set_initial_name (dialog, "demo.node");
g_object_unref (cwd);
}
gtk_file_dialog_save (dialog,
GTK_WINDOW (gtk_widget_get_root (GTK_WIDGET (button))),
NULL,
@@ -1091,6 +1109,8 @@ node_editor_window_finalize (GObject *object)
g_clear_pointer (&self->node, gsk_render_node_unref);
g_clear_object (&self->renderers);
g_clear_object (&self->file_monitor);
g_clear_object (&self->file);
G_OBJECT_CLASS (node_editor_window_parent_class)->finalize (object);
}
+2 -2
View File
@@ -2,7 +2,7 @@
GSK render nodes can be serialized and deserialized using APIs such as `gsk_render_node_serialize()` and `gsk_render_node_deserialize()`. The intended use for this is development - primarily the development of GTK - by allowing things such as creating testsuites and benchmarks, exchanging nodes in bug reports. GTK includes the `gtk4-node-editor` application for creating such test files.
The format is a text format that follows the [CSS syntax rules](https://drafts.csswg.org/css-syntax-3/). In particular, this means that every array of bytes will produce a render node when parsed, as there is a defined error recovery method. For more details on error handling, please refer to the documentation of the aprsing APIs.
The format is a text format that follows the [CSS syntax rules](https://drafts.csswg.org/css-syntax-3/). In particular, this means that every array of bytes will produce a render node when parsed, as there is a defined error recovery method. For more details on error handling, please refer to the documentation of the parsing APIs.
The grammar of a node text representation using [the CSS value definition syntax](https://drafts.csswg.org/css-values-3/#value-defs) looks like this:
**document**: `<node>\*`
@@ -23,7 +23,7 @@ Nodes can be given a name by adding a string after the `<node-type>` in their de
### Textures
Just like nodes, textures can be referenced by name. When definining the named texture, the name has to be placed in front of the URL.
Just like nodes, textures can be referenced by name. When defining a named texture, the name has to be placed in front of the URL.
# Nodes
+4
View File
@@ -44,6 +44,10 @@ widgets (although most of the time, the transformation will be a simple 2D trans
The transform to go from one widgets coordinate system to another one can be obtained
with [method@Gtk.Widget.compute_transform].
In addition to a size, widgets can optionally have a **_baseline_** to position text on.
Containers such as [class@Gtk.Box] may position their children to match up their baselines.
[method@Gtk.Widget.get_baseline] returns the y position of the baseline in widget coordinates.
When widget APIs expect positions or areas, they need to be expressed in this coordinate
system, typically called **_widget coordinates_**. GTK provides a number of APIs to translate
between different widgets' coordinate systems, such as [method@Gtk.Widget.compute_point]
+1
View File
@@ -68,6 +68,7 @@ ui_files = [
'stackswitcher.ui',
'statusbar.ui',
'switch.ui',
'switch-state.ui',
'toggle-button.ui',
'video.ui',
'volumebutton.ui',
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

+43
View File
@@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkWindow">
<property name="decorated">0</property>
<property name="resizable">0</property>
<property name="default-width">280</property>
<property name="default-height">120</property>
<style>
<class name="nobackground"/>
</style>
<child>
<object class="GtkBox">
<style>
<class name="shadow"/>
<class name="background"/>
<class name="frame"/>
</style>
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<property name="spacing">3</property>
<property name="hexpand">1</property>
<property name="vexpand">1</property>
<property name="halign">center</property>
<property name="valign">center</property>
<child>
<object class="GtkSwitch">
<property name="active">1</property>
<property name="state">0</property>
</object>
</child>
<child>
<object class="GtkSwitch">
<property name="active">0</property>
<property name="state">1</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</interface>
+5 -5
View File
@@ -258,7 +258,7 @@ Instead of implementing GtkWidget.destroy, you can implement GObject.dispose.
GTK 4 removes `gtk_container_add()` and `gtk_container_remove()`. While there
is not always a replacement for `gtk_container_remove()` in GTK 3, you can
replace many uses of `gtk_container_add()` with equivalent container-specific
APIs such as `gtk_box_pack_start()` or `gtk_grid_attach()`, and thereby reduce
APIs such as `gtk_grid_attach()`, and thereby reduce
the amount of work you have to do at the time of the switch.
### Review your use of icon resources
@@ -402,9 +402,9 @@ is open, use the [property@Gtk.Window:modal] property of the dialog.
### Adapt to coordinate API changes
A number of coordinate APIs in GTK 3 had `double` variants:
A number of coordinate APIs in GTK 3 had variants taking `int` arguments:
`gdk_device_get_surface_at_position()`, `gdk_surface_get_device_position()`.
These have been changed to use doubles, and the `double` variants
These have been changed to use `double` arguments, and the `int` variants
have been removed. Update your code accordingly.
Any APIs that deal with global (or root) coordinates have been
@@ -875,10 +875,10 @@ reference.
### Adapt to coordinate API changes
A number of APIs that are accepting or returning coordinates have
been changed from ints to doubles: `gtk_widget_translate_coordinates()`,
been changed from `int`s to `double`s: `gtk_widget_translate_coordinates()`,
`gtk_fixed_put()`, `gtk_fixed_move()`. This change is mostly transparent,
except for cases where out parameters are involved: you need to
pass double* now, instead of int*.
pass `double*` now, instead of `int*`.
### Adapt to GtkStyleContext API changes
+14
View File
@@ -119,3 +119,17 @@ it no longer has a resize handle for the window.
These are very specialized widgets that should better live with the application
where they are used.
## Widget size api changes
The functions gtk_widget_get_allocated_width() and gtk_widget_get_allocated_height()
are going away. In most cases, [method@Gtk.Widget.get_width] and [method@Gtk.Widget.get_height]
are suitable replacements. Note that the semantics are slightly different though:
the old functions return the size of the CSS border area, while the new functions return
the size of the widgets content area. In places where this difference matters, you can
use `gtk_widget_compute_bounds (widget, widget, &bounds)` instead.
The function gtk_widget_get_allocation() is also going away. It does not have a direct
replacement, but the previously mentioned alternatives can be used for it too.
The function gtk_widget_get_allocated_baseline() has been renamed to [method@Gtk.Widget.get_baseline].
+2 -1
View File
@@ -477,6 +477,8 @@ gdk_broadway_display_class_init (GdkBroadwayDisplayClass * class)
object_class->dispose = gdk_broadway_display_dispose;
object_class->finalize = gdk_broadway_display_finalize;
display_class->toplevel_type = GDK_TYPE_BROADWAY_TOPLEVEL;
display_class->popup_type = GDK_TYPE_BROADWAY_POPUP;
display_class->cairo_context_type = GDK_TYPE_BROADWAY_CAIRO_CONTEXT;
display_class->get_name = gdk_broadway_display_get_name;
@@ -488,7 +490,6 @@ gdk_broadway_display_class_init (GdkBroadwayDisplayClass * class)
display_class->get_next_serial = gdk_broadway_display_get_next_serial;
display_class->notify_startup_complete = gdk_broadway_display_notify_startup_complete;
display_class->create_surface = _gdk_broadway_display_create_surface;
display_class->get_keymap = _gdk_broadway_display_get_keymap;
display_class->get_monitors = gdk_broadway_display_get_monitors;
-7
View File
@@ -103,13 +103,6 @@ void _gdk_broadway_display_get_default_cursor_size (GdkDisplay *display,
void _gdk_broadway_display_get_maximal_cursor_size (GdkDisplay *display,
guint *width,
guint *height);
GdkSurface * _gdk_broadway_display_create_surface (GdkDisplay *display,
GdkSurfaceType surface_type,
GdkSurface *parent,
int x,
int y,
int width,
int height);
GdkKeymap* _gdk_broadway_display_get_keymap (GdkDisplay *display);
void _gdk_broadway_display_consume_all_input (GdkDisplay *display);
BroadwayInputMsg * _gdk_broadway_display_block_for_input (GdkDisplay *display,
+148 -174
View File
@@ -47,19 +47,8 @@
#include <stdio.h>
#include <string.h>
/* Forward declarations */
static void gdk_broadway_surface_finalize (GObject *object);
G_DEFINE_TYPE (GdkBroadwaySurface, gdk_broadway_surface, GDK_TYPE_SURFACE)
GType gdk_broadway_toplevel_get_type (void) G_GNUC_CONST;
GType gdk_broadway_popup_get_type (void) G_GNUC_CONST;
GType gdk_broadway_drag_surface_get_type (void) G_GNUC_CONST;
#define GDK_TYPE_BROADWAY_TOPLEVEL (gdk_broadway_toplevel_get_type ())
#define GDK_TYPE_BROADWAY_POPUP (gdk_broadway_popup_get_type ())
#define GDK_TYPE_BROADWAY_DRAG_SURFACE (gdk_broadway_drag_surface_get_type ())
/* We need to flush in an idle rather than AFTER_PAINT, as the clock
is frozen during e.g. surface resizes so the paint will not happen
and the surface resize request is never flushed. */
@@ -74,6 +63,93 @@ gdk_broadway_surface_init (GdkBroadwaySurface *impl)
{
}
static void
on_frame_clock_after_paint (GdkFrameClock *clock,
GdkSurface *surface)
{
GdkDisplay *display = gdk_surface_get_display (surface);
GdkBroadwaySurface *impl = GDK_BROADWAY_SURFACE (surface);
GdkBroadwayDisplay *broadway_display;
impl->pending_frame_counter = gdk_frame_clock_get_frame_counter (clock);
gdk_surface_freeze_updates (surface);
broadway_display = GDK_BROADWAY_DISPLAY (display);
_gdk_broadway_server_roundtrip (broadway_display->server, impl->id, _gdk_display_get_next_serial (display));
gdk_display_flush (display);
}
static void
on_frame_clock_before_paint (GdkFrameClock *clock,
GdkSurface *surface)
{
GdkFrameTimings *timings = gdk_frame_clock_get_current_timings (clock);
gint64 presentation_time;
gint64 refresh_interval;
if (surface->update_freeze_count > 0)
return;
gdk_frame_clock_get_refresh_info (clock,
timings->frame_time,
&refresh_interval, &presentation_time);
if (presentation_time != 0)
{
timings->predicted_presentation_time = presentation_time + refresh_interval;
}
else
{
timings->predicted_presentation_time = timings->frame_time + refresh_interval / 2 + refresh_interval;
}
}
static void
connect_frame_clock (GdkSurface *surface)
{
GdkFrameClock *frame_clock = gdk_surface_get_frame_clock (surface);
g_signal_connect (frame_clock, "before-paint",
G_CALLBACK (on_frame_clock_before_paint), surface);
g_signal_connect (frame_clock, "after-paint",
G_CALLBACK (on_frame_clock_after_paint), surface);
}
static void
disconnect_frame_clock (GdkSurface *surface)
{
GdkFrameClock *frame_clock = gdk_surface_get_frame_clock (surface);
g_signal_handlers_disconnect_by_func (frame_clock,
on_frame_clock_before_paint, surface);
g_signal_handlers_disconnect_by_func (frame_clock,
on_frame_clock_after_paint, surface);
}
static void
gdk_broadway_surface_constructed (GObject *object)
{
GdkBroadwaySurface *self = GDK_BROADWAY_SURFACE (object);
GdkSurface *surface = GDK_SURFACE (object);
GdkBroadwayDisplay *broadway_display = GDK_BROADWAY_DISPLAY (gdk_surface_get_display (surface));
if (!surface->parent)
broadway_display->toplevels = g_list_prepend (broadway_display->toplevels, self);
self->id = _gdk_broadway_server_new_surface (broadway_display->server,
self->root_x,
self->root_y,
1, 1);
g_hash_table_insert (broadway_display->id_ht, GINT_TO_POINTER (self->id), surface);
g_object_ref (self);
G_OBJECT_CLASS (gdk_broadway_surface_parent_class)->constructed (object);
connect_frame_clock (surface);
}
static void
gdk_broadway_surface_finalize (GObject *object)
{
@@ -143,164 +219,6 @@ _gdk_broadway_roundtrip_notify (GdkSurface *surface,
}
}
static void
on_frame_clock_after_paint (GdkFrameClock *clock,
GdkSurface *surface)
{
GdkDisplay *display = gdk_surface_get_display (surface);
GdkBroadwaySurface *impl = GDK_BROADWAY_SURFACE (surface);
GdkBroadwayDisplay *broadway_display;
impl->pending_frame_counter = gdk_frame_clock_get_frame_counter (clock);
gdk_surface_freeze_updates (surface);
broadway_display = GDK_BROADWAY_DISPLAY (display);
_gdk_broadway_server_roundtrip (broadway_display->server, impl->id, _gdk_display_get_next_serial (display));
gdk_display_flush (display);
}
static void
on_frame_clock_before_paint (GdkFrameClock *clock,
GdkSurface *surface)
{
GdkFrameTimings *timings = gdk_frame_clock_get_current_timings (clock);
gint64 presentation_time;
gint64 refresh_interval;
if (surface->update_freeze_count > 0)
return;
gdk_frame_clock_get_refresh_info (clock,
timings->frame_time,
&refresh_interval, &presentation_time);
if (presentation_time != 0)
{
timings->predicted_presentation_time = presentation_time + refresh_interval;
}
else
{
timings->predicted_presentation_time = timings->frame_time + refresh_interval / 2 + refresh_interval;
}
}
static void
connect_frame_clock (GdkSurface *surface)
{
GdkFrameClock *frame_clock = gdk_surface_get_frame_clock (surface);
g_signal_connect (frame_clock, "before-paint",
G_CALLBACK (on_frame_clock_before_paint), surface);
g_signal_connect (frame_clock, "after-paint",
G_CALLBACK (on_frame_clock_after_paint), surface);
}
static void
disconnect_frame_clock (GdkSurface *surface)
{
GdkFrameClock *frame_clock = gdk_surface_get_frame_clock (surface);
g_signal_handlers_disconnect_by_func (frame_clock,
on_frame_clock_before_paint, surface);
g_signal_handlers_disconnect_by_func (frame_clock,
on_frame_clock_after_paint, surface);
}
GdkSurface *
_gdk_broadway_display_create_surface (GdkDisplay *display,
GdkSurfaceType surface_type,
GdkSurface *parent,
int x,
int y,
int width,
int height)
{
GdkBroadwayDisplay *broadway_display;
GdkFrameClock *frame_clock;
GdkSurface *surface;
GdkBroadwaySurface *impl;
GType type;
if (parent)
frame_clock = g_object_ref (gdk_surface_get_frame_clock (parent));
else
frame_clock = _gdk_frame_clock_idle_new ();
switch (surface_type)
{
case GDK_SURFACE_TOPLEVEL:
type = GDK_TYPE_BROADWAY_TOPLEVEL;
break;
case GDK_SURFACE_POPUP:
type = GDK_TYPE_BROADWAY_POPUP;
break;
case GDK_SURFACE_DRAG:
type = GDK_TYPE_BROADWAY_DRAG_SURFACE;
break;
default:
g_assert_not_reached ();
break;
}
surface = g_object_new (type,
"display", display,
"frame-clock", frame_clock,
NULL);
g_object_unref (frame_clock);
surface->parent = parent;
surface->x = x;
surface->y = y;
surface->width = width;
surface->height = height;
broadway_display = GDK_BROADWAY_DISPLAY (display);
impl = GDK_BROADWAY_SURFACE (surface);
impl->root_x = x;
impl->root_y = y;
if (parent)
{
impl->root_x += GDK_BROADWAY_SURFACE (parent)->root_x;
impl->root_y += GDK_BROADWAY_SURFACE (parent)->root_y;
}
impl->id = _gdk_broadway_server_new_surface (broadway_display->server,
impl->root_x,
impl->root_y,
surface->width,
surface->height);
g_hash_table_insert (broadway_display->id_ht, GINT_TO_POINTER(impl->id), surface);
g_object_ref (surface);
if (!surface->parent)
broadway_display->toplevels = g_list_prepend (broadway_display->toplevels, impl);
connect_frame_clock (surface);
/* We treat the real parent as a default transient for to get stacking right */
if (parent)
{
impl->transient_for = GDK_BROADWAY_SURFACE (parent)->id;
_gdk_broadway_server_surface_set_transient_for (broadway_display->server, impl->id, impl->transient_for);
}
return surface;
}
static cairo_surface_t *
gdk_broadway_surface_ref_cairo_surface (GdkSurface *surface)
{
if (GDK_IS_BROADWAY_SURFACE (surface) &&
GDK_SURFACE_DESTROYED (surface))
return NULL;
return cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 1, 1);
}
static void
_gdk_broadway_surface_destroy (GdkSurface *surface,
gboolean foreign_destroy)
@@ -1107,6 +1025,14 @@ _gdk_broadway_moveresize_configure_done (GdkDisplay *display,
return TRUE;
}
static GdkSurface *
gdk_broadway_drag_surface_new (GdkDisplay *display)
{
return g_object_new (GDK_TYPE_BROADWAY_DRAG_SURFACE,
"display", display,
NULL);
}
static void
create_moveresize_surface (MoveResizeData *mv_resize,
guint32 timestamp)
@@ -1118,11 +1044,9 @@ create_moveresize_surface (MoveResizeData *mv_resize,
g_assert (mv_resize->moveresize_emulation_surface == NULL);
mv_resize->moveresize_emulation_surface =
_gdk_broadway_display_create_surface (mv_resize->display,
GDK_SURFACE_DRAG,
NULL,
-100, -100, 1, 1);
gdk_broadway_drag_surface_new (mv_resize->display);
gdk_broadway_surface_move_resize_internal (mv_resize->moveresize_emulation_surface, TRUE, -100, -100, 1, 1);
gdk_broadway_surface_show (mv_resize->moveresize_emulation_surface, FALSE);
seat = gdk_display_get_default_seat (mv_resize->display);
@@ -1252,9 +1176,9 @@ gdk_broadway_surface_class_init (GdkBroadwaySurfaceClass *klass)
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GdkSurfaceClass *impl_class = GDK_SURFACE_CLASS (klass);
object_class->constructed = gdk_broadway_surface_constructed;
object_class->finalize = gdk_broadway_surface_finalize;
impl_class->ref_cairo_surface = gdk_broadway_surface_ref_cairo_surface;
impl_class->hide = gdk_broadway_surface_hide;
impl_class->get_geometry = gdk_broadway_surface_get_geometry;
impl_class->get_root_coords = gdk_broadway_surface_get_root_coords;
@@ -1290,6 +1214,25 @@ gdk_broadway_popup_init (GdkBroadwayPopup *popup)
{
}
static void
gdk_broadway_popup_constructed (GObject *object)
{
GdkBroadwaySurface *self = GDK_BROADWAY_SURFACE (object);
GdkSurface *surface = GDK_SURFACE (self);
GdkBroadwayDisplay *broadway_display = GDK_BROADWAY_DISPLAY (gdk_surface_get_display (surface));
self->root_x = GDK_BROADWAY_SURFACE (surface->parent)->root_x;
self->root_y = GDK_BROADWAY_SURFACE (surface->parent)->root_y;
gdk_surface_set_frame_clock (surface, gdk_surface_get_frame_clock (surface->parent));
G_OBJECT_CLASS (gdk_broadway_popup_parent_class)->constructed (object);
/* We treat the real parent as a default transient for to get stacking right */
self->transient_for = GDK_BROADWAY_SURFACE (surface->parent)->id;
_gdk_broadway_server_surface_set_transient_for (broadway_display->server, self->id, self->transient_for);
}
static void
gdk_broadway_popup_get_property (GObject *object,
guint prop_id,
@@ -1345,6 +1288,7 @@ gdk_broadway_popup_class_init (GdkBroadwayPopupClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
object_class->constructed = gdk_broadway_popup_constructed;
object_class->get_property = gdk_broadway_popup_get_property;
object_class->set_property = gdk_broadway_popup_set_property;
@@ -1415,6 +1359,19 @@ gdk_broadway_toplevel_init (GdkBroadwayToplevel *toplevel)
{
}
static void
gdk_broadway_toplevel_constructed (GObject *object)
{
GdkSurface *surface = GDK_SURFACE (object);
GdkFrameClock *frame_clock;
frame_clock = _gdk_frame_clock_idle_new ();
gdk_surface_set_frame_clock (surface, frame_clock);
g_object_unref (frame_clock);
G_OBJECT_CLASS (gdk_broadway_toplevel_parent_class)->constructed (object);
}
static void
gdk_broadway_toplevel_set_property (GObject *object,
guint prop_id,
@@ -1518,6 +1475,7 @@ gdk_broadway_toplevel_class_init (GdkBroadwayToplevelClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
object_class->constructed = gdk_broadway_toplevel_constructed;
object_class->get_property = gdk_broadway_toplevel_get_property;
object_class->set_property = gdk_broadway_toplevel_set_property;
@@ -1678,9 +1636,25 @@ gdk_broadway_drag_surface_init (GdkBroadwayDragSurface *surface)
{
}
static void
gdk_broadway_drag_surface_constructed (GObject *object)
{
GdkSurface *surface = GDK_SURFACE (object);
GdkFrameClock *frame_clock;
frame_clock = _gdk_frame_clock_idle_new ();
gdk_surface_set_frame_clock (surface, frame_clock);
g_object_unref (frame_clock);
G_OBJECT_CLASS (gdk_broadway_drag_surface_parent_class)->constructed (object);
}
static void
gdk_broadway_drag_surface_class_init (GdkBroadwayDragSurfaceClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
object_class->constructed = gdk_broadway_drag_surface_constructed;
}
static gboolean
+8
View File
@@ -32,6 +32,14 @@ G_BEGIN_DECLS
/* Surface implementation for Broadway
*/
GType gdk_broadway_toplevel_get_type (void) G_GNUC_CONST;
GType gdk_broadway_popup_get_type (void) G_GNUC_CONST;
GType gdk_broadway_drag_surface_get_type (void) G_GNUC_CONST;
#define GDK_TYPE_BROADWAY_TOPLEVEL (gdk_broadway_toplevel_get_type ())
#define GDK_TYPE_BROADWAY_POPUP (gdk_broadway_popup_get_type ())
#define GDK_TYPE_BROADWAY_DRAG_SURFACE (gdk_broadway_drag_surface_get_type ())
struct _GdkBroadwaySurface
{
GdkSurface parent_instance;
+1
View File
@@ -54,6 +54,7 @@
#include <gdk/gdkframetimings.h>
#include <gdk/gdkglcontext.h>
#include <gdk/gdkgltexture.h>
#include <gdk/gdkgltexturebuilder.h>
#include <gdk/gdkkeys.h>
#include <gdk/gdkkeysyms.h>
#include <gdk/gdkmemorytexture.h>
-17
View File
@@ -1196,21 +1196,6 @@ _gdk_display_unpause_events (GdkDisplay *display)
display->event_pause_count--;
}
GdkSurface *
gdk_display_create_surface (GdkDisplay *display,
GdkSurfaceType surface_type,
GdkSurface *parent,
int x,
int y,
int width,
int height)
{
return GDK_DISPLAY_GET_CLASS (display)->create_surface (display,
surface_type,
parent,
x, y, width, height);
}
/*< private >
* gdk_display_get_keymap:
* @display: the `GdkDisplay`
@@ -1723,8 +1708,6 @@ gdk_display_init_egl (GdkDisplay *self,
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,
+2 -2
View File
@@ -369,7 +369,7 @@ gdk_display_manager_list_displays (GdkDisplayManager *manager)
/**
* gdk_display_manager_open_display:
* @manager: a `GdkDisplayManager`
* @name: the name of the display to open
* @name: (nullable): the name of the display to open
*
* Opens a display.
*
@@ -437,7 +437,7 @@ gdk_display_manager_open_display (GdkDisplayManager *manager,
}
}
if (!found && !display)
if (!found && !any && !display)
g_warning ("No such backend: %s", backend);
}
+3 -17
View File
@@ -108,13 +108,14 @@ struct _GdkDisplay
guint have_egl_buffer_age : 1;
guint have_egl_no_config_context : 1;
guint have_egl_pixel_format_float : 1;
guint have_egl_win32_libangle : 1;
};
struct _GdkDisplayClass
{
GObjectClass parent_class;
GType toplevel_type; /* Type for GdkToplevel, must be set */
GType popup_type; /* Type for GdkPopup, must be set */
GType cairo_context_type; /* type for GdkCairoContext, must be set */
GType vk_context_type; /* type for GdkVulkanContext, must be set if vk_extension_name != NULL */
const char *vk_extension_name; /* Name of required windowing vulkan extension or %NULL (default) if Vulkan isn't supported */
@@ -135,15 +136,7 @@ struct _GdkDisplayClass
const char *startup_id);
const char * (*get_startup_notification_id) (GdkDisplay *display);
GdkSurface * (*create_surface) (GdkDisplay *display,
GdkSurfaceType surface_type,
GdkSurface *parent,
int x,
int y,
int width,
int height);
GdkKeymap * (*get_keymap) (GdkDisplay *display);
GdkKeymap * (*get_keymap) (GdkDisplay *display);
GdkGLContext * (* init_gl) (GdkDisplay *display,
GError **error);
@@ -208,13 +201,6 @@ void _gdk_display_pointer_info_foreach (GdkDisplay *display
gulong _gdk_display_get_next_serial (GdkDisplay *display);
void _gdk_display_pause_events (GdkDisplay *display);
void _gdk_display_unpause_events (GdkDisplay *display);
GdkSurface * gdk_display_create_surface (GdkDisplay *display,
GdkSurfaceType surface_type,
GdkSurface *parent,
int x,
int y,
int width,
int height);
GdkGLContext * gdk_display_get_gl_context (GdkDisplay *display);
+14
View File
@@ -32,6 +32,20 @@
G_BEGIN_DECLS
/**
* GdkGLAPI:
* @GDK_GL_API_GL: The OpenGL API
* @GDK_GL_API_GLES: The OpenGL ES API
*
* The list of the different APIs that GdkGLContext can potentially support.
*
* Since: 4.6
*/
typedef enum { /*< underscore_name=GDK_GL_API >*/
GDK_GL_API_GL = 1 << 0,
GDK_GL_API_GLES = 1 << 1
} GdkGLAPI;
/* Currently, these are the same values numerically as in the
* X protocol. If you change that, gdksurface-x11.c/gdk_surface_set_geometry_hints()
* will need fixing.
+95 -98
View File
@@ -82,6 +82,7 @@
#include "gdkmemoryformatprivate.h"
#include "gdkmemorytextureprivate.h"
#include "gdkprofilerprivate.h"
#include "gdkglversionprivate.h"
#include "gdkprivate.h"
@@ -99,13 +100,13 @@
#define DEFAULT_ALLOWED_APIS GDK_GL_API_GL | GDK_GL_API_GLES
typedef struct {
int major;
int minor;
int gl_version;
GdkGLVersion required;
GdkGLVersion gl_version;
guint has_khr_debug : 1;
guint use_khr_debug : 1;
guint has_half_float : 1;
guint has_sync : 1;
guint has_unpack_subimage : 1;
guint has_debug_output : 1;
guint extensions_checked : 1;
@@ -287,8 +288,11 @@ gdk_gl_context_create_egl_context (GdkGLContext *context,
EGLConfig egl_config;
EGLContext ctx;
EGLint context_attribs[N_EGL_ATTRS], i = 0, flags = 0;
gsize major_idx, minor_idx;
gboolean debug_bit, forward_bit;
int min_major, min_minor, major = 0, minor = 0;
GdkGLVersion version;
const GdkGLVersion* supported_versions;
gsize j;
G_GNUC_UNUSED gint64 start_time = GDK_PROFILER_CURRENT_TIME;
if (!gdk_gl_context_is_api_allowed (context, api, NULL))
@@ -296,12 +300,7 @@ gdk_gl_context_create_egl_context (GdkGLContext *context,
/* We will use the default version matching the context status
* unless the user requested a version which makes sense */
gdk_gl_context_get_matching_version (api, legacy,
display->have_egl_win32_libangle,
&min_major, &min_minor);
gdk_gl_context_get_clipped_version (context,
min_major, min_minor,
&major, &minor);
gdk_gl_context_get_matching_version (context, api, legacy, &version);
if (!eglBindAPI (gdk_api_to_egl_api (api)))
return 0;
@@ -332,9 +331,9 @@ gdk_gl_context_create_egl_context (GdkGLContext *context,
flags &= ~EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR;
context_attribs[i++] = EGL_CONTEXT_MAJOR_VERSION;
context_attribs[i++] = major;
major_idx = i++;
context_attribs[i++] = EGL_CONTEXT_MINOR_VERSION;
context_attribs[i++] = minor;
minor_idx = i++;
context_attribs[i++] = EGL_CONTEXT_FLAGS_KHR;
context_attribs[i++] = flags;
@@ -343,23 +342,33 @@ gdk_gl_context_create_egl_context (GdkGLContext *context,
GDK_DISPLAY_DEBUG (display, OPENGL,
"Creating EGL context version %d.%d (debug:%s, forward:%s, legacy:%s, es:%s)",
major, minor,
gdk_gl_version_get_major (&version), gdk_gl_version_get_minor (&version),
debug_bit ? "yes" : "no",
forward_bit ? "yes" : "no",
legacy ? "yes" : "no",
api == GDK_GL_API_GLES ? "yes" : "no");
ctx = eglCreateContext (egl_display,
egl_config,
share ? share_priv->egl_context : EGL_NO_CONTEXT,
context_attribs);
supported_versions = gdk_gl_versions_get_for_api (api);
for (j = 0; gdk_gl_version_greater_equal (&supported_versions[j], &version); j++)
{
context_attribs [major_idx] = gdk_gl_version_get_major (&supported_versions[j]);
context_attribs [minor_idx] = gdk_gl_version_get_minor (&supported_versions[j]);
ctx = eglCreateContext (egl_display,
egl_config,
share ? share_priv->egl_context : EGL_NO_CONTEXT,
context_attribs);
if (ctx != NULL)
break;
}
if (ctx == NULL)
return 0;
return 0;
GDK_DISPLAY_DEBUG (display, OPENGL, "Created EGL context[%p]", ctx);
priv->egl_context = ctx;
gdk_gl_context_set_version (context, &supported_versions[j]);
gdk_gl_context_set_is_legacy (context, legacy);
if (epoxy_has_egl_extension (egl_display, "EGL_KHR_swap_buffers_with_damage"))
@@ -621,7 +630,7 @@ gdk_gl_context_real_begin_frame (GdkDrawContext *draw_context,
glViewport (0, 0, ww, wh);
#ifdef HAVE_EGL
if (priv->egl_context && gdk_gl_context_check_version (context, 0, 0, 3, 0))
if (priv->egl_context && gdk_gl_context_check_version (context, NULL, "3.0"))
glDrawBuffers (1, (GLenum[1]) { gdk_gl_context_get_use_es (context) ? GL_BACK : GL_BACK_LEFT });
#endif
}
@@ -987,45 +996,33 @@ gdk_gl_context_get_forward_compatible (GdkGLContext *context)
}
void
gdk_gl_context_get_matching_version (GdkGLAPI api,
gboolean legacy,
gboolean win32_libangle,
int *major,
int *minor)
gdk_gl_context_get_matching_version (GdkGLContext *context,
GdkGLAPI api,
gboolean legacy,
GdkGLVersion *out_version)
{
int maj, min;
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
GdkGLVersion min_version;
g_return_if_fail (GDK_IS_GL_CONTEXT (context));
if (api == GDK_GL_API_GL)
{
if (legacy)
{
maj = GDK_GL_MIN_GL_LEGACY_VERSION_MAJOR;
min = GDK_GL_MIN_GL_LEGACY_VERSION_MINOR;
}
min_version = GDK_GL_MIN_GL_LEGACY_VERSION;
else
{
maj = GDK_GL_MIN_GL_VERSION_MAJOR;
min = GDK_GL_MIN_GL_VERSION_MINOR;
}
min_version = GDK_GL_MIN_GL_VERSION;
}
else
{
if (win32_libangle)
{
maj = GDK_GL_MIN_GLES_WIN32_ANGLE_VERSION_MAJOR;
min = GDK_GL_MIN_GLES_WIN32_ANGLE_VERSION_MINOR;
}
else
{
maj = GDK_GL_MIN_GLES_VERSION_MAJOR;
min = GDK_GL_MIN_GLES_VERSION_MINOR;
}
min_version = GDK_GL_MIN_GLES_VERSION;
}
if (major != NULL)
*major = maj;
if (minor != NULL)
*minor = min;
if (gdk_gl_version_greater_equal (&priv->required, &min_version))
*out_version = priv->required;
else
*out_version = min_version;
}
/**
@@ -1054,22 +1051,17 @@ gdk_gl_context_set_required_version (GdkGLContext *context,
g_return_if_fail (GDK_IS_GL_CONTEXT (context));
g_return_if_fail (!gdk_gl_context_is_realized (context));
priv->major = major;
priv->minor = minor;
priv->required = GDK_GL_VERSION_INIT (major, minor);
}
gboolean
gdk_gl_context_check_version (GdkGLContext *self,
int required_gl_major,
int required_gl_minor,
int required_gles_major,
int required_gles_minor)
gdk_gl_context_check_gl_version (GdkGLContext *self,
const GdkGLVersion *required_gl,
const GdkGLVersion *required_gles)
{
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (self);
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);
if (!gdk_gl_context_is_realized (self))
return FALSE;
@@ -1077,10 +1069,10 @@ gdk_gl_context_check_version (GdkGLContext *self,
switch (priv->api)
{
case GDK_GL_API_GL:
return priv->gl_version >= required_gl_major * 10 + required_gl_minor;
return required_gl == NULL || gdk_gl_version_greater_equal (&priv->gl_version, required_gl);
case GDK_GL_API_GLES:
return priv->gl_version >= required_gles_major * 10 + required_gles_minor;
return required_gles == NULL || gdk_gl_version_greater_equal (&priv->gl_version, required_gles);
default:
g_return_val_if_reached (FALSE);
@@ -1111,33 +1103,9 @@ gdk_gl_context_get_required_version (GdkGLContext *context,
g_return_if_fail (GDK_IS_GL_CONTEXT (context));
if (major != NULL)
*major = priv->major;
*major = gdk_gl_version_get_major (&priv->required);
if (minor != NULL)
*minor = priv->minor;
}
void
gdk_gl_context_get_clipped_version (GdkGLContext *context,
int min_major,
int min_minor,
int *major,
int *minor)
{
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
int maj = min_major, min = min_minor;
g_return_if_fail (GDK_IS_GL_CONTEXT (context));
if (priv->major > maj || (priv->major == maj && priv->minor > min))
{
maj = priv->major;
min = priv->minor;
}
if (major != NULL)
*major = maj;
if (minor != NULL)
*minor = min;
*minor = gdk_gl_version_get_minor (&priv->required);
}
/**
@@ -1174,6 +1142,15 @@ gdk_gl_context_is_legacy (GdkGLContext *context)
return priv->is_legacy;
}
void
gdk_gl_context_set_version (GdkGLContext *context,
const GdkGLVersion *version)
{
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
priv->gl_version = *version;
}
void
gdk_gl_context_set_is_legacy (GdkGLContext *context,
gboolean is_legacy)
@@ -1509,11 +1486,23 @@ gdk_gl_context_realize (GdkGLContext *context,
priv->api = GDK_GL_CONTEXT_GET_CLASS (context)->realize (context, error);
if (priv->api)
g_object_notify_by_pspec (G_OBJECT (context), properties[PROP_API]);
{
g_assert (gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (0, 0)));
g_object_notify_by_pspec (G_OBJECT (context), properties[PROP_API]);
}
return priv->api;
}
void
gdk_gl_version_init_epoxy (GdkGLVersion *version)
{
int epoxy_version = epoxy_gl_version ();
*version = GDK_GL_VERSION_INIT (epoxy_version / 10, epoxy_version % 10);
}
static void
gdk_gl_context_check_extensions (GdkGLContext *context)
{
@@ -1527,8 +1516,6 @@ gdk_gl_context_check_extensions (GdkGLContext *context)
if (priv->extensions_checked)
return;
priv->gl_version = epoxy_gl_version ();
priv->has_debug_output = epoxy_has_gl_extension ("GL_ARB_debug_output") ||
epoxy_has_gl_extension ("GL_KHR_debug");
@@ -1554,7 +1541,7 @@ gdk_gl_context_check_extensions (GdkGLContext *context)
priv->has_khr_debug = epoxy_has_gl_extension ("GL_KHR_debug");
/* We asked for a core profile, but we didn't get one, so we're in legacy mode */
if (priv->gl_version < 32)
if (!gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (3, 2)))
priv->is_legacy = TRUE;
}
@@ -1564,9 +1551,13 @@ gdk_gl_context_check_extensions (GdkGLContext *context)
glGetIntegerv (GL_MAX_LABEL_LENGTH, &priv->max_debug_label_length);
}
priv->has_half_float = gdk_gl_context_check_version (context, 3, 0, 3, 0) ||
priv->has_half_float = gdk_gl_context_check_version (context, "3.0", "3.0") ||
epoxy_has_gl_extension ("OES_vertex_half_float");
priv->has_sync = gdk_gl_context_check_version (context, "3.2", "3.0") ||
epoxy_has_gl_extension ("GL_ARB_sync") ||
epoxy_has_gl_extension ("GK_APPLE_sync");
#ifdef G_ENABLE_DEBUG
{
int max_texture_size;
@@ -1578,15 +1569,17 @@ gdk_gl_context_check_extensions (GdkGLContext *context)
"* Extensions checked:\n"
" - GL_KHR_debug: %s\n"
" - GL_EXT_unpack_subimage: %s\n"
" - OES_vertex_half_float: %s",
" - half float: %s\n"
" - sync: %s",
gdk_gl_context_get_use_es (context) ? "OpenGL ES" : "OpenGL",
priv->gl_version / 10, priv->gl_version % 10,
gdk_gl_version_get_major (&priv->gl_version), gdk_gl_version_get_minor (&priv->gl_version),
priv->is_legacy ? "legacy" : "core",
glGetString (GL_SHADING_LANGUAGE_VERSION),
max_texture_size,
priv->has_khr_debug ? "yes" : "no",
priv->has_unpack_subimage ? "yes" : "no",
priv->has_half_float ? "yes" : "no");
priv->has_half_float ? "yes" : "no",
priv->has_sync ? "yes" : "no");
}
#endif
@@ -1708,10 +1701,6 @@ gdk_gl_context_get_shared_context (GdkGLContext *context)
* Retrieves the OpenGL version of the @context.
*
* The @context must be realized prior to calling this function.
*
* If the @context has never been made current, the version cannot
* be known and it will return 0 for both @major and @minor.
*
*/
void
gdk_gl_context_get_version (GdkGLContext *context,
@@ -1724,9 +1713,9 @@ gdk_gl_context_get_version (GdkGLContext *context,
g_return_if_fail (gdk_gl_context_is_realized (context));
if (major != NULL)
*major = priv->gl_version / 10;
*major = gdk_gl_version_get_major (&priv->gl_version);
if (minor != NULL)
*minor = priv->gl_version % 10;
*minor = gdk_gl_version_get_minor (&priv->gl_version);
}
/**
@@ -1818,6 +1807,14 @@ gdk_gl_context_has_vertex_half_float (GdkGLContext *self)
return priv->has_half_float;
}
gboolean
gdk_gl_context_has_sync (GdkGLContext *self)
{
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (self);
return priv->has_sync;
}
/* This is currently private! */
/* When using GL/ES, don't flip the 'R' and 'B' bits on Windows/ANGLE for glReadPixels() */
gboolean
+2 -15
View File
@@ -24,25 +24,12 @@
#error "Only <gdk/gdk.h> can be included directly."
#endif
#include <gdk/gdkversionmacros.h>
#include <gdk/gdkenums.h>
#include <gdk/gdktypes.h>
#include <gdk/gdkversionmacros.h>
G_BEGIN_DECLS
/**
* GdkGLAPI:
* @GDK_GL_API_GL: The OpenGL API
* @GDK_GL_API_GLES: The OpenGL ES API
*
* The list of the different APIs that GdkGLContext can potentially support.
*
* Since: 4.6
*/
typedef enum { /*< underscore_name=GDK_GL_API >*/
GDK_GL_API_GL = 1 << 0,
GDK_GL_API_GLES = 1 << 1
} GdkGLAPI;
#define GDK_TYPE_GL_CONTEXT (gdk_gl_context_get_type ())
#define GDK_GL_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDK_TYPE_GL_CONTEXT, GdkGLContext))
#define GDK_IS_GL_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDK_TYPE_GL_CONTEXT))
+27 -44
View File
@@ -22,32 +22,10 @@
#include "gdkglcontext.h"
#include "gdkdrawcontextprivate.h"
#include "gdkglversionprivate.h"
G_BEGIN_DECLS
/* Version requirements for EGL contexts.
*
* If you add support for EGL to your backend, please require this.
*/
#define GDK_EGL_MIN_VERSION_MAJOR (1)
#define GDK_EGL_MIN_VERSION_MINOR (4)
/* Minimum OpenGL versions supported by GTK.
* Backends should make sure to never create a context of a previous version.
*
* The macros refer to OpenGL; OpenGL with OPENGL_COMPATIBILITY_PROFILE_BIT as
* OPENGL_PROFILE_MASK; OpenGL ES; and OpenGL ES win32 Angle implementation,
* respectively
*/
#define GDK_GL_MIN_GL_VERSION_MAJOR (3)
#define GDK_GL_MIN_GL_VERSION_MINOR (2)
#define GDK_GL_MIN_GL_LEGACY_VERSION_MAJOR (3)
#define GDK_GL_MIN_GL_LEGACY_VERSION_MINOR (0)
#define GDK_GL_MIN_GLES_VERSION_MAJOR (2)
#define GDK_GL_MIN_GLES_VERSION_MINOR (0)
#define GDK_GL_MIN_GLES_WIN32_ANGLE_VERSION_MAJOR (3)
#define GDK_GL_MIN_GLES_WIN32_ANGLE_VERSION_MINOR (0)
typedef enum {
GDK_GL_NONE = 0,
GDK_GL_EGL,
@@ -100,7 +78,6 @@ typedef struct {
} GdkGLContextProgram;
typedef struct {
guint vertex_array_object;
guint tmp_framebuffer;
guint tmp_vertex_buffer;
@@ -122,27 +99,31 @@ void gdk_gl_context_clear_current_if_surface (GdkSurface
GdkGLContext * gdk_gl_context_new (GdkDisplay *display,
GdkSurface *surface);
gboolean gdk_gl_context_is_api_allowed (GdkGLContext *self,
GdkGLAPI api,
GError **error);
void gdk_gl_context_set_is_legacy (GdkGLContext *context,
gboolean is_legacy);
gboolean gdk_gl_context_is_api_allowed (GdkGLContext *self,
GdkGLAPI api,
GError **error);
void gdk_gl_context_set_version (GdkGLContext *context,
const GdkGLVersion *version);
void gdk_gl_context_set_is_legacy (GdkGLContext *context,
gboolean is_legacy);
gboolean gdk_gl_context_check_gl_version (GdkGLContext *context,
const GdkGLVersion *gl_version,
const GdkGLVersion *gles_version);
gboolean gdk_gl_context_check_version (GdkGLContext *context,
int required_gl_major,
int required_gl_minor,
int required_gles_major,
int required_gles_minor);
void gdk_gl_context_get_clipped_version (GdkGLContext *context,
int min_major,
int min_minor,
int *major,
int *minor);
void gdk_gl_context_get_matching_version (GdkGLAPI api,
gboolean legacy,
gboolean win32_libangle,
int *major,
int *minor);
static inline gboolean
gdk_gl_context_check_version (GdkGLContext *context,
const char *gl_version,
const char *gles_version)
{
return gdk_gl_context_check_gl_version (context,
gl_version ? &GDK_GL_VERSION_STRING (gl_version) : NULL,
gles_version ? &GDK_GL_VERSION_STRING (gles_version) : NULL);
}
void gdk_gl_context_get_matching_version (GdkGLContext *context,
GdkGLAPI api,
gboolean legacy,
GdkGLVersion *out_version);
gboolean gdk_gl_context_has_unpack_subimage (GdkGLContext *context);
void gdk_gl_context_push_debug_group (GdkGLContext *context,
@@ -167,6 +148,8 @@ gboolean gdk_gl_context_use_es_bgra (GdkGLContext
gboolean gdk_gl_context_has_vertex_half_float (GdkGLContext *self) G_GNUC_PURE;
gboolean gdk_gl_context_has_sync (GdkGLContext *self) G_GNUC_PURE;
double gdk_gl_context_get_scale (GdkGLContext *self);
G_END_DECLS
+65 -5
View File
@@ -39,6 +39,7 @@ struct _GdkGLTexture {
GdkGLContext *context;
guint id;
gboolean has_mipmap;
gpointer sync;
GdkTexture *saved;
@@ -99,6 +100,10 @@ gdk_gl_texture_invoke_callback (gpointer data)
context = gdk_display_get_gl_context (gdk_gl_context_get_display (invoke->self->context));
gdk_gl_context_make_current (context);
if (invoke->self->sync && context != invoke->self->context)
glWaitSync (invoke->self->sync, 0, GL_TIMEOUT_IGNORED);
glBindTexture (GL_TEXTURE_2D, invoke->self->id);
invoke->func (invoke->self, context, invoke->data);
@@ -131,6 +136,8 @@ struct _Download
static gboolean
gdk_gl_texture_find_format (gboolean use_es,
guint gl_major,
guint gl_minor,
GLint gl_format,
GLint gl_type,
GdkMemoryFormat *out_format)
@@ -141,7 +148,7 @@ gdk_gl_texture_find_format (gboolean use_es,
{
GLenum q_internal_format, q_format, q_type;
if (!gdk_memory_format_gl_format (format, use_es, &q_internal_format, &q_format, &q_type))
if (!gdk_memory_format_gl_format (format, use_es, gl_major, gl_minor, &q_internal_format, &q_format, &q_type))
continue;
if (q_format != gl_format || q_type != gl_type)
@@ -163,12 +170,14 @@ gdk_gl_texture_do_download (GdkGLTexture *self,
gsize expected_stride;
Download *download = download_;
GLenum gl_internal_format, gl_format, gl_type;
int major, minor;
expected_stride = texture->width * gdk_memory_format_bytes_per_pixel (download->format);
gdk_gl_context_get_version (context, &major, &minor);
if (download->stride == expected_stride &&
!gdk_gl_context_get_use_es (context) &&
gdk_memory_format_gl_format (download->format, TRUE, &gl_internal_format, &gl_format, &gl_type))
gdk_memory_format_gl_format (download->format, TRUE, major, minor, &gl_internal_format, &gl_format, &gl_type))
{
glGetTexImage (GL_TEXTURE_2D,
0,
@@ -185,11 +194,12 @@ gdk_gl_texture_do_download (GdkGLTexture *self,
glGenFramebuffers (1, &fbo);
glBindFramebuffer (GL_FRAMEBUFFER, fbo);
glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, self->id, 0);
if (gdk_gl_context_check_version (context, 4, 3, 3, 1))
if (gdk_gl_context_check_version (context, "4.3", "3.1"))
{
gdk_gl_context_get_version (context, &major, &minor);
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 (context), gl_read_format, gl_read_type, &actual_format))
if (!gdk_gl_texture_find_format (gdk_gl_context_get_use_es (context), major, minor, gl_read_format, gl_read_type, &actual_format))
actual_format = GDK_MEMORY_R8G8B8A8_PREMULTIPLIED; /* pray */
}
else
@@ -291,6 +301,12 @@ gdk_gl_texture_has_mipmap (GdkGLTexture *self)
return self->has_mipmap;
}
gpointer
gdk_gl_texture_get_sync (GdkGLTexture *self)
{
return self->sync;
}
/**
* gdk_gl_texture_release:
* @self: a `GdkTexture` wrapping a GL texture
@@ -316,6 +332,47 @@ gdk_gl_texture_release (GdkGLTexture *self)
drop_gl_resources (self);
}
GdkTexture *
gdk_gl_texture_new_from_builder (GdkGLTextureBuilder *builder,
GDestroyNotify destroy,
gpointer data)
{
GdkGLTexture *self;
GdkTexture *update_texture;
self = g_object_new (GDK_TYPE_GL_TEXTURE,
"width", gdk_gl_texture_builder_get_width (builder),
"height", gdk_gl_texture_builder_get_height (builder),
NULL);
self->context = g_object_ref (gdk_gl_texture_builder_get_context (builder));
self->id = gdk_gl_texture_builder_get_id (builder);
GDK_TEXTURE (self)->format = gdk_gl_texture_builder_get_format (builder);
self->has_mipmap = gdk_gl_texture_builder_get_has_mipmap (builder);
if (gdk_gl_context_has_sync (self->context))
self->sync = gdk_gl_texture_builder_get_sync (builder);
self->destroy = destroy;
self->data = data;
update_texture = gdk_gl_texture_builder_get_update_texture (builder);
if (update_texture)
{
cairo_region_t *update_region = gdk_gl_texture_builder_get_update_region (builder);
if (update_region)
{
update_region = cairo_region_copy (update_region);
cairo_region_intersect_rectangle (update_region,
&(cairo_rectangle_int_t) {
0, 0,
update_texture->width, update_texture->height
});
gdk_texture_set_diff (GDK_TEXTURE (self), update_texture, update_region);
}
}
return GDK_TEXTURE (self);
}
static void
gdk_gl_texture_determine_format (GdkGLTexture *self)
{
@@ -330,7 +387,7 @@ gdk_gl_texture_determine_format (GdkGLTexture *self)
if (context == NULL ||
!gdk_gl_context_is_shared (self->context, context) ||
/* ... or glGetTexLevelParameter() isn't supported */
!gdk_gl_context_check_version (context, 0, 0, 3, 1))
!gdk_gl_context_check_version (context, NULL, "3.1"))
{
texture->format = GDK_MEMORY_DEFAULT;
self->has_mipmap = FALSE;
@@ -458,6 +515,9 @@ gdk_gl_texture_determine_format (GdkGLTexture *self)
*
* Return value: (transfer full) (type GdkGLTexture): A newly-created
* `GdkTexture`
*
* Deprecated: 4.12: [class@Gdk.GLTextureBuilder] supercedes this function
* and provides extended functionality for creating GL textures.
*/
GdkTexture *
gdk_gl_texture_new (GdkGLContext *context,
+1 -1
View File
@@ -38,7 +38,7 @@ typedef struct _GdkGLTextureClass GdkGLTextureClass;
GDK_AVAILABLE_IN_ALL
GType gdk_gl_texture_get_type (void) G_GNUC_CONST;
GDK_AVAILABLE_IN_ALL
GDK_DEPRECATED_IN_4_12_FOR(GdkGLTextureBuilder)
GdkTexture * gdk_gl_texture_new (GdkGLContext *context,
guint id,
int width,
+802
View File
@@ -0,0 +1,802 @@
/*
* Copyright © 2023 Benjamin Otte
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Authors: Benjamin Otte <otte@gnome.org>
*/
#include "config.h"
#include "gdkgltexturebuilder.h"
#include "gdkenumtypes.h"
#include "gdkglcontext.h"
#include "gdkgltextureprivate.h"
#include <cairo-gobject.h>
struct _GdkGLTextureBuilder
{
GObject parent_instance;
GdkGLContext *context;
guint id;
int width;
int height;
GdkMemoryFormat format;
gboolean has_mipmap;
gpointer sync;
GdkTexture *update_texture;
cairo_region_t *update_region;
};
struct _GdkGLTextureBuilderClass
{
GObjectClass parent_class;
};
/**
* GdkGLTextureBuilder:
*
* `GdkGLTextureBuilder` is a buider used to construct [class@Gdk.Texture] objects from
* GL textures.
*
* The operation is quite simple: Create a texture builder, set all the necessary
* properties - keep in mind that the properties [property@Gdk.GLTextureBuilder:context],
* [property@Gdk.GLTextureBuilder:id], [property@Gdk.GLTextureBuilder:width], and
* [property@Gdk.GLTextureBuilder:height] are mandatory - and then call
* [method@Gdk.GLTextureBuilder.build] to create the new texture.
*
* `GdkGLTextureBuilder` can be used for quick one-shot construction of
* textures as well as kept around and reused to construct multiple textures.
*
* Since: 4.12
*/
enum
{
PROP_0,
PROP_CONTEXT,
PROP_FORMAT,
PROP_HAS_MIPMAP,
PROP_HEIGHT,
PROP_ID,
PROP_SYNC,
PROP_UPDATE_REGION,
PROP_UPDATE_TEXTURE,
PROP_WIDTH,
N_PROPS
};
G_DEFINE_TYPE (GdkGLTextureBuilder, gdk_gl_texture_builder, G_TYPE_OBJECT)
static GParamSpec *properties[N_PROPS] = { NULL, };
static void
gdk_gl_texture_builder_dispose (GObject *object)
{
GdkGLTextureBuilder *self = GDK_GL_TEXTURE_BUILDER (object);
g_clear_object (&self->context);
g_clear_object (&self->update_texture);
g_clear_pointer (&self->update_region, cairo_region_destroy);
G_OBJECT_CLASS (gdk_gl_texture_builder_parent_class)->dispose (object);
}
static void
gdk_gl_texture_builder_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
GdkGLTextureBuilder *self = GDK_GL_TEXTURE_BUILDER (object);
switch (property_id)
{
case PROP_CONTEXT:
g_value_set_object (value, self->context);
break;
case PROP_FORMAT:
g_value_set_enum (value, self->format);
break;
case PROP_HAS_MIPMAP:
g_value_set_boolean (value, self->has_mipmap);
break;
case PROP_HEIGHT:
g_value_set_int (value, self->height);
break;
case PROP_ID:
g_value_set_uint (value, self->id);
break;
case PROP_SYNC:
g_value_set_pointer (value, self->sync);
break;
case PROP_UPDATE_REGION:
g_value_set_boxed (value, self->update_region);
break;
case PROP_UPDATE_TEXTURE:
g_value_set_object (value, self->update_texture);
break;
case PROP_WIDTH:
g_value_set_int (value, self->width);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gdk_gl_texture_builder_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
GdkGLTextureBuilder *self = GDK_GL_TEXTURE_BUILDER (object);
switch (property_id)
{
case PROP_CONTEXT:
gdk_gl_texture_builder_set_context (self, g_value_get_object (value));
break;
case PROP_FORMAT:
gdk_gl_texture_builder_set_format (self, g_value_get_enum (value));
break;
case PROP_HAS_MIPMAP:
gdk_gl_texture_builder_set_has_mipmap (self, g_value_get_boolean (value));
break;
case PROP_HEIGHT:
gdk_gl_texture_builder_set_height (self, g_value_get_int (value));
break;
case PROP_ID:
gdk_gl_texture_builder_set_id (self, g_value_get_uint (value));
break;
case PROP_SYNC:
gdk_gl_texture_builder_set_sync (self, g_value_get_pointer (value));
break;
case PROP_UPDATE_REGION:
gdk_gl_texture_builder_set_update_region (self, g_value_get_boxed (value));
break;
case PROP_UPDATE_TEXTURE:
gdk_gl_texture_builder_set_update_texture (self, g_value_get_object (value));
break;
case PROP_WIDTH:
gdk_gl_texture_builder_set_width (self, g_value_get_int (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gdk_gl_texture_builder_class_init (GdkGLTextureBuilderClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
gobject_class->dispose = gdk_gl_texture_builder_dispose;
gobject_class->get_property = gdk_gl_texture_builder_get_property;
gobject_class->set_property = gdk_gl_texture_builder_set_property;
/**
* GdkGLTextureBuilder:context: (attributes org.gdk.Property.get=gdk_gl_texture_builder_get_context org.gdk.Property.set=gdk_gl_texture_builder_set_context)
*
* The context owning the texture.
*
* Since: 4.12
*/
properties[PROP_CONTEXT] =
g_param_spec_object ("context", NULL, NULL,
GDK_TYPE_GL_CONTEXT,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
/**
* GdkGLTextureBuilder:format: (attributes org.gdk.Property.get=gdk_gl_texture_builder_get_format org.gdk.Property.set=gdk_gl_texture_builder_set_format)
*
* The format when downloading the texture.
*
* Since: 4.12
*/
properties[PROP_FORMAT] =
g_param_spec_enum ("format", NULL, NULL,
GDK_TYPE_MEMORY_FORMAT,
GDK_MEMORY_R8G8B8A8_PREMULTIPLIED,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
/**
* GdkGLTextureBuilder:has-mipmap: (attributes org.gdk.Property.get=gdk_gl_texture_builder_get_has_mipmap org.gdk.Property.set=gdk_gl_texture_builder_set_has_mipmap)
*
* If the texture has a mipmap.
*
* Since: 4.12
*/
properties[PROP_HAS_MIPMAP] =
g_param_spec_boolean ("has-mipmap", NULL, NULL,
FALSE,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
/**
* GdkGLTextureBuilder:height: (attributes org.gdk.Property.get=gdk_gl_texture_builder_get_height org.gdk.Property.set=gdk_gl_texture_builder_set_height)
*
* The height of the texture.
*
* Since: 4.12
*/
properties[PROP_HEIGHT] =
g_param_spec_int ("height", NULL, NULL,
G_MININT, G_MAXINT, 0,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
/**
* GdkGLTextureBuilder:id: (attributes org.gdk.Property.get=gdk_gl_texture_builder_get_id org.gdk.Property.set=gdk_gl_texture_builder_set_id)
*
* The texture ID to use.
*
* Since: 4.12
*/
properties[PROP_ID] =
g_param_spec_uint ("id", NULL, NULL,
0, G_MAXUINT, 0,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
/**
* GdkGLTextureBuilder:sync: (attributes org.gdk.Property.get=gdk_gl_texture_builder_get_sync org.gdk.Property.set=gdk_gl_texture_builder_set_sync)
*
* An optional `GLSync` object.
*
* If this is set, GTK will wait on it before using the texture.
*
* Since: 4.12
*/
properties[PROP_SYNC] =
g_param_spec_pointer ("sync", NULL, NULL,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
/**
* GdkGLTextureBuilder:update-region: (attributes org.gdk.Property.get=gdk_gl_texture_builder_get_update_region org.gdk.Property.set=gdk_gl_texture_builder_set_update_region)
*
* The update region for [property@Gdk.GLTextureBuilder:update-texture].
*
* Since: 4.12
*/
properties[PROP_UPDATE_REGION] =
g_param_spec_boxed ("update-region", NULL, NULL,
CAIRO_GOBJECT_TYPE_REGION,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
/**
* GdkGLTextureBuilder:update-texture: (attributes org.gdk.Property.get=gdk_gl_texture_builder_get_update_texture org.gdk.Property.set=gdk_gl_texture_builder_set_update_texture)
*
* The texture [property@Gdk.GLTextureBuilder:update-region] is an update for.
*
* Since: 4.12
*/
properties[PROP_UPDATE_TEXTURE] =
g_param_spec_object ("update-texture", NULL, NULL,
GDK_TYPE_TEXTURE,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
/**
* GdkGLTextureBuilder:width: (attributes org.gdk.Property.get=gdk_gl_texture_builder_get_width org.gdk.Property.set=gdk_gl_texture_builder_set_width)
*
* The width of the texture.
*
* Since: 4.12
*/
properties[PROP_WIDTH] =
g_param_spec_int ("width", NULL, NULL,
G_MININT, G_MAXINT, 0,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (gobject_class, N_PROPS, properties);
}
static void
gdk_gl_texture_builder_init (GdkGLTextureBuilder *self)
{
self->format = GDK_MEMORY_R8G8B8A8_PREMULTIPLIED;
}
/**
* gdk_gl_texture_builder_new: (constructor):
*
* Creates a new texture builder.
*
* Returns: the new `GdkTextureBuilder`
*
* Since: 4.12
**/
GdkGLTextureBuilder *
gdk_gl_texture_builder_new (void)
{
return g_object_new (GDK_TYPE_GL_TEXTURE_BUILDER, NULL);
}
/**
* gdk_gl_texture_builder_get_context: (attributes org.gdk.Method.get_property=context)
* @self: a `GdkGLTextureBuilder`
*
* Gets the context previously set via gdk_gl_texture_builder_set_context() or
* %NULL if none was set.
*
* Returns: (transfer none) (nullable): The context
*
* Since: 4.12
*/
GdkGLContext *
gdk_gl_texture_builder_get_context (GdkGLTextureBuilder *self)
{
g_return_val_if_fail (GDK_IS_GL_TEXTURE_BUILDER (self), NULL);
return self->context;
}
/**
* gdk_gl_texture_builder_set_context: (attributes org.gdk.Method.set_property=context)
* @self: a `GdkGLTextureBuilder`
* @context: (nullable): The context the texture beongs to or %NULL to unset
*
* Sets the context to be used for the texture. This is the context that owns
* the texture.
*
* The context must be set before calling [method@Gdk.GLTextureBuilder.build].
*
* Since: 4.12
*/
void
gdk_gl_texture_builder_set_context (GdkGLTextureBuilder *self,
GdkGLContext *context)
{
g_return_if_fail (GDK_IS_GL_TEXTURE_BUILDER (self));
g_return_if_fail (context == NULL || GDK_IS_GL_CONTEXT (context));
if (!g_set_object (&self->context, context))
return;
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_CONTEXT]);
}
/**
* gdk_gl_texture_builder_get_height: (attributes org.gdk.Method.get_property=height)
* @self: a `GdkGLTextureBuilder`
*
* Gets the height previously set via gdk_gl_texture_builder_set_height() or
* 0 if the height wasn't set.
*
* Returns: The height
*
* Since: 4.12
*/
int
gdk_gl_texture_builder_get_height (GdkGLTextureBuilder *self)
{
g_return_val_if_fail (GDK_IS_GL_TEXTURE_BUILDER (self), 0);
return self->height;
}
/**
* gdk_gl_texture_builder_set_height: (attributes org.gdk.Method.set_property=height)
* @self: a `GdkGLTextureBuilder`
* @height: The texture's height or 0 to unset
*
* Sets the height of the texture.
*
* The height must be set before calling [method@Gdk.GLTextureBuilder.build].
*
* Since: 4.12
*/
void
gdk_gl_texture_builder_set_height (GdkGLTextureBuilder *self,
int height)
{
g_return_if_fail (GDK_IS_GL_TEXTURE_BUILDER (self));
if (self->height == height)
return;
self->height = height;
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_HEIGHT]);
}
/**
* gdk_gl_texture_builder_get_id: (attributes org.gdk.Method.get_property=id)
* @self: a `GdkGLTextureBuilder`
*
* Gets the texture id previously set via gdk_gl_texture_builder_set_id() or
* 0 if the id wasn't set.
*
* Returns: The id
*
* Since: 4.12
*/
guint
gdk_gl_texture_builder_get_id (GdkGLTextureBuilder *self)
{
g_return_val_if_fail (GDK_IS_GL_TEXTURE_BUILDER (self), 0);
return self->id;
}
/**
* gdk_gl_texture_builder_set_id: (attributes org.gdk.Method.set_property=id)
* @self: a `GdkGLTextureBuilder`
* @id: The texture id to be used for creating the texture
*
* Sets the texture id of the texture. The texture id must remain unmodified
* until the texture was finalized. See [method@Gdk.GLTextureBuilder.build]
* for a longer discussion.
*
* The id must be set before calling [method@Gdk.GLTextureBuilder.build].
*
* Since: 4.12
*/
void
gdk_gl_texture_builder_set_id (GdkGLTextureBuilder *self,
guint id)
{
g_return_if_fail (GDK_IS_GL_TEXTURE_BUILDER (self));
if (self->id == id)
return;
self->id = id;
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_ID]);
}
/**
* gdk_gl_texture_builder_get_width: (attributes org.gdk.Method.get_property=width)
* @self: a `GdkGLTextureBuilder`
*
* Gets the width previously set via gdk_gl_texture_builder_set_width() or
* 0 if the width wasn't set.
*
* Returns: The width
*
* Since: 4.12
*/
int
gdk_gl_texture_builder_get_width (GdkGLTextureBuilder *self)
{
g_return_val_if_fail (GDK_IS_GL_TEXTURE_BUILDER (self), 0);
return self->width;
}
/**
* gdk_gl_texture_builder_set_width: (attributes org.gdk.Method.set_property=width)
* @self: a `GdkGLTextureBuilder`
* @width: The texture's width or 0 to unset
*
* Sets the width of the texture.
*
* The width must be set before calling [method@Gdk.GLTextureBuilder.build].
*
* Since: 4.12
*/
void
gdk_gl_texture_builder_set_width (GdkGLTextureBuilder *self,
int width)
{
g_return_if_fail (GDK_IS_GL_TEXTURE_BUILDER (self));
if (self->width == width)
return;
self->width = width;
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_WIDTH]);
}
/**
* gdk_gl_texture_builder_get_has_mipmap: (attributes org.gdk.Method.get_property=has-mipmap)
* @self: a `GdkGLTextureBuilder`
*
* Gets whether the texture has a mipmap.
*
* Returns: Whether the texture has a mipmap
*
* Since: 4.12
*/
gboolean
gdk_gl_texture_builder_get_has_mipmap (GdkGLTextureBuilder *self)
{
g_return_val_if_fail (GDK_IS_GL_TEXTURE_BUILDER (self), FALSE);
return self->has_mipmap;
}
/**
* gdk_gl_texture_builder_set_has_mipmap: (attributes org.gdk.Method.set_property=has-mipmap)
* @self: a `GdkGLTextureBuilder`
* @has_mipmap: Whether the texture has a mipmap
*
* Sets whether the texture has a mipmap. This allows the renderer and other users of the
* generated texture to use a higher quality downscaling.
*
* Typically, the `glGenerateMipmap` function is used to generate a mimap.
*
* Since: 4.12
*/
void
gdk_gl_texture_builder_set_has_mipmap (GdkGLTextureBuilder *self,
gboolean has_mipmap)
{
g_return_if_fail (GDK_IS_GL_TEXTURE_BUILDER (self));
if (self->has_mipmap == has_mipmap)
return;
self->has_mipmap = has_mipmap;
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_HAS_MIPMAP]);
}
/**
* gdk_gl_texture_builder_get_sync: (attributes org.gdk.Method.get_property=sync)
* @self: a `GdkGLTextureBuilder`
*
* Gets the `GLsync` previously set via gdk_gl_texture_builder_set_sync().
*
* Returns: (nullable): the `GLSync`
*
* Since: 4.12
*/
gpointer
gdk_gl_texture_builder_get_sync (GdkGLTextureBuilder *self)
{
g_return_val_if_fail (GDK_IS_GL_TEXTURE_BUILDER (self), NULL);
return self->sync;
}
/**
* gdk_gl_texture_builder_set_sync: (attributes org.gdk.Method.set_property=sync)
* @self: a `GdkGLTextureBuilder`
* @sync: (nullable): the GLSync object
*
* Sets the GLSync object to use for the texture.
*
* GTK will wait on this object before using the created `GdkTexture`.
*
* The `destroy` function that is passed to [method@Gdk.GLTextureBuilder.build]
* is responsible for freeing the sync object when it is no longer needed.
* The texture builder does not destroy it and it is the callers
* responsibility to make sure it doesn't leak.
*
* Since: 4.12
*/
void
gdk_gl_texture_builder_set_sync (GdkGLTextureBuilder *self,
gpointer sync)
{
g_return_if_fail (GDK_IS_GL_TEXTURE_BUILDER (self));
if (self->sync == sync)
return;
self->sync = sync;
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SYNC]);
}
/**
* gdk_gl_texture_builder_get_format: (attributes org.gdk.Method.get_property=format)
* @self: a `GdkGLTextureBuilder`
*
* Gets the format previously set via gdk_gl_texture_builder_set_format().
*
* Returns: The format
*
* Since: 4.12
*/
GdkMemoryFormat
gdk_gl_texture_builder_get_format (GdkGLTextureBuilder *self)
{
g_return_val_if_fail (GDK_IS_GL_TEXTURE_BUILDER (self), GDK_MEMORY_R8G8B8A8_PREMULTIPLIED);
return self->format;
}
/**
* gdk_gl_texture_builder_set_format: (attributes org.gdk.Method.set_property=format)
* @self: a `GdkGLTextureBuilder`
* @format: The texture's format
*
* Sets the format of the texture. The default is `GDK_MEMORY_R8G8B8A8_PREMULTIPLIED`.
*
* The format is the preferred format the texture data should be downloaded to. The
* format must be supported by the GL version of [property@Gdk.GLTextureBuilder:context].
*
* Setting the right format is particularly useful when using high bit depth textures
* to preserve the bit depth, to set the correct value for unpremultiplied textures
* and to make sure opaque textures are treated as such.
*
* Since: 4.12
*/
void
gdk_gl_texture_builder_set_format (GdkGLTextureBuilder *self,
GdkMemoryFormat format)
{
g_return_if_fail (GDK_IS_GL_TEXTURE_BUILDER (self));
if (self->format == format)
return;
self->format = format;
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_FORMAT]);
}
/**
* gdk_gl_texture_builder_get_update_texture: (attributes org.gdk.Method.get_property=update_texture)
* @self: a `GdkGLTextureBuilder`
*
* Gets the texture previously set via gdk_gl_texture_builder_set_update_texture() or
* %NULL if none was set.
*
* Returns: (transfer none) (nullable): The texture
*
* Since: 4.12
*/
GdkTexture *
gdk_gl_texture_builder_get_update_texture (GdkGLTextureBuilder *self)
{
g_return_val_if_fail (GDK_IS_GL_TEXTURE_BUILDER (self), NULL);
return self->update_texture;
}
/**
* gdk_gl_texture_builder_set_update_texture: (attributes org.gdk.Method.set_property=update_texture)
* @self: a `GdkGLTextureBuilder`
* @texture: (nullable): the texture to update
*
* Sets the texture to be updated by this texture. See
* [method@Gdk.GLTextureBuilder.set_update_region] for an explanation.
*
* Since: 4.12
*/
void
gdk_gl_texture_builder_set_update_texture (GdkGLTextureBuilder *self,
GdkTexture *texture)
{
g_return_if_fail (GDK_IS_GL_TEXTURE_BUILDER (self));
g_return_if_fail (texture == NULL || GDK_IS_TEXTURE (texture));
if (!g_set_object (&self->update_texture, texture))
return;
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_UPDATE_TEXTURE]);
}
/**
* gdk_gl_texture_builder_get_update_region: (attributes org.gdk.Method.get_property=update_region)
* @self: a `GdkGLTextureBuilder`
*
* Gets the region previously set via gdk_gl_texture_builder_set_update_region() or
* %NULL if none was set.
*
* Returns: (transfer none) (nullable): The region
*
* Since: 4.12
*/
cairo_region_t *
gdk_gl_texture_builder_get_update_region (GdkGLTextureBuilder *self)
{
g_return_val_if_fail (GDK_IS_GL_TEXTURE_BUILDER (self), NULL);
return self->update_region;
}
/**
* gdk_gl_texture_builder_set_update_region: (attributes org.gdk.Method.set_property=update_region)
* @self: a `GdkGLTextureBuilder`
* @region: (nullable): the region to update
*
* Sets the region to be updated by this texture. Together with
* [property@Gdk.GLTextureBuilder:update-texture] this describes an
* update of a previous texture.
*
* When rendering animations of large textures, it is possible that
* consecutive textures are only updating contents in parts of the texture.
* It is then possible to describe this update via these two properties,
* so that GTK can avoid rerendering parts that did not change.
*
* An example would be a screen recording where only the mouse pointer moves.
*
* Since: 4.12
*/
void
gdk_gl_texture_builder_set_update_region (GdkGLTextureBuilder *self,
cairo_region_t *region)
{
g_return_if_fail (GDK_IS_GL_TEXTURE_BUILDER (self));
if (self->update_region == region)
return;
g_clear_pointer (&self->update_region, cairo_region_destroy);
if (region)
self->update_region = cairo_region_reference (region);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_UPDATE_REGION]);
}
/**
* gdk_gl_texture_builder_build:
* @self: a `GdkGLTextureBuilder`
* @destroy: (nullable): destroy function to be called when the texture is
* released
* @data: user data to pass to the destroy function
*
* Builds a new `GdkTexture` with the values set up in the builder.
*
* The `destroy` function gets called when the returned texture gets released;
* either when the texture is finalized or by an explicit call to
* [method@Gdk.GLTexture.release]. It should release all GL resources associated
* with the texture, such as the [property@Gdk.GLTextureBuilder:id] and the
* [property@Gdk.GLTextureBuilder:sync].
*
* Note that it is a programming error to call this function if any mandatory
* property has not been set.
*
* It is possible to call this function multiple times to create multiple textures,
* possibly with changing properties in between.
*
* Returns: (transfer full): a newly built `GdkTexture`
*
* Since: 4.12
*/
GdkTexture *
gdk_gl_texture_builder_build (GdkGLTextureBuilder *self,
GDestroyNotify destroy,
gpointer data)
{
g_return_val_if_fail (GDK_IS_GL_TEXTURE_BUILDER (self), NULL);
g_return_val_if_fail (destroy == NULL || data != NULL, NULL);
g_return_val_if_fail (self->context != NULL, NULL);
g_return_val_if_fail (self->id != 0, NULL);
g_return_val_if_fail (self->width > 0, NULL);
g_return_val_if_fail (self->height > 0, NULL);
return gdk_gl_texture_new_from_builder (self, destroy, data);
}
+99
View File
@@ -0,0 +1,99 @@
/*
* Copyright © 2023 Benjamin Otte
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Authors: Benjamin Otte <otte@gnome.org>
*/
#pragma once
#if !defined (__GDK_H_INSIDE__) && !defined (GTK_COMPILATION)
#error "Only <gdk/gdk.h> can be included directly."
#endif
#include <gdk/gdkenums.h>
#include <gdk/gdktypes.h>
#include <gdk/gdkversionmacros.h>
G_BEGIN_DECLS
#define GDK_TYPE_GL_TEXTURE_BUILDER (gdk_gl_texture_builder_get_type ())
GDK_AVAILABLE_IN_4_12
GDK_DECLARE_INTERNAL_TYPE (GdkGLTextureBuilder, gdk_gl_texture_builder, GDK, GL_TEXTURE_BUILDER, GObject)
GDK_AVAILABLE_IN_4_12
GdkGLTextureBuilder * gdk_gl_texture_builder_new (void);
GDK_AVAILABLE_IN_4_12
GdkGLContext * gdk_gl_texture_builder_get_context (GdkGLTextureBuilder *self) G_GNUC_PURE;
GDK_AVAILABLE_IN_4_12
void gdk_gl_texture_builder_set_context (GdkGLTextureBuilder *self,
GdkGLContext *context);
GDK_AVAILABLE_IN_4_12
guint gdk_gl_texture_builder_get_id (GdkGLTextureBuilder *self) G_GNUC_PURE;
GDK_AVAILABLE_IN_4_12
void gdk_gl_texture_builder_set_id (GdkGLTextureBuilder *self,
guint id);
GDK_AVAILABLE_IN_4_12
int gdk_gl_texture_builder_get_width (GdkGLTextureBuilder *self) G_GNUC_PURE;
GDK_AVAILABLE_IN_4_12
void gdk_gl_texture_builder_set_width (GdkGLTextureBuilder *self,
int width);
GDK_AVAILABLE_IN_4_12
int gdk_gl_texture_builder_get_height (GdkGLTextureBuilder *self) G_GNUC_PURE;
GDK_AVAILABLE_IN_4_12
void gdk_gl_texture_builder_set_height (GdkGLTextureBuilder *self,
int height);
GDK_AVAILABLE_IN_4_12
GdkMemoryFormat gdk_gl_texture_builder_get_format (GdkGLTextureBuilder *self) G_GNUC_PURE;
GDK_AVAILABLE_IN_4_12
void gdk_gl_texture_builder_set_format (GdkGLTextureBuilder *self,
GdkMemoryFormat format);
GDK_AVAILABLE_IN_4_12
gboolean gdk_gl_texture_builder_get_has_mipmap (GdkGLTextureBuilder *self) G_GNUC_PURE;
GDK_AVAILABLE_IN_4_12
void gdk_gl_texture_builder_set_has_mipmap (GdkGLTextureBuilder *self,
gboolean has_mipmap);
GDK_AVAILABLE_IN_4_12
gpointer gdk_gl_texture_builder_get_sync (GdkGLTextureBuilder *self) G_GNUC_PURE;
GDK_AVAILABLE_IN_4_12
void gdk_gl_texture_builder_set_sync (GdkGLTextureBuilder *self,
gpointer sync);
GDK_AVAILABLE_IN_4_12
GdkTexture * gdk_gl_texture_builder_get_update_texture (GdkGLTextureBuilder *self) G_GNUC_PURE;
GDK_AVAILABLE_IN_4_12
void gdk_gl_texture_builder_set_update_texture (GdkGLTextureBuilder *self,
GdkTexture *texture);
GDK_AVAILABLE_IN_4_12
cairo_region_t * gdk_gl_texture_builder_get_update_region (GdkGLTextureBuilder *self) G_GNUC_PURE;
GDK_AVAILABLE_IN_4_12
void gdk_gl_texture_builder_set_update_region (GdkGLTextureBuilder *self,
cairo_region_t *region);
GDK_AVAILABLE_IN_4_12
GdkTexture * gdk_gl_texture_builder_build (GdkGLTextureBuilder *self,
GDestroyNotify destroy,
gpointer data);
G_END_DECLS
+7
View File
@@ -2,13 +2,20 @@
#include "gdkgltexture.h"
#include "gdkgltexturebuilder.h"
#include "gdktextureprivate.h"
G_BEGIN_DECLS
GdkTexture * gdk_gl_texture_new_from_builder (GdkGLTextureBuilder *builder,
GDestroyNotify destroy,
gpointer data);
GdkGLContext * gdk_gl_texture_get_context (GdkGLTexture *self);
guint gdk_gl_texture_get_id (GdkGLTexture *self);
gboolean gdk_gl_texture_has_mipmap (GdkGLTexture *self);
gpointer gdk_gl_texture_get_sync (GdkGLTexture *self);
G_END_DECLS
+138
View File
@@ -0,0 +1,138 @@
/* GDK - The GIMP Drawing Kit
*
* gdkglcontextprivate.h: GL context abstraction
*
* Copyright © 2014 Emmanuele Bassi
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <gdkenums.h>
G_BEGIN_DECLS
/* Version requirements for EGL contexts.
*
* If you add support for EGL to your backend, please require this.
*/
#define GDK_EGL_MIN_VERSION_MAJOR (1)
#define GDK_EGL_MIN_VERSION_MINOR (4)
/* Minimum OpenGL versions supported by GTK.
* Backends should make sure to never create a context of a previous version.
*
* The macros refer to OpenGL; OpenGL with OPENGL_COMPATIBILITY_PROFILE_BIT as
* OPENGL_PROFILE_MASK; and OpenGL ES respectively
*/
#define GDK_GL_MIN_GL_VERSION GDK_GL_VERSION_INIT (3, 2)
#define GDK_GL_MIN_GL_LEGACY_VERSION GDK_GL_VERSION_INIT (3, 0)
#define GDK_GL_MIN_GLES_VERSION GDK_GL_VERSION_INIT (2, 0)
typedef struct _GdkGLVersion GdkGLVersion;
struct _GdkGLVersion
{
int major;
int minor;
};
#define GDK_GL_VERSION_INIT(maj,min) { maj, min }
static const GdkGLVersion supported_gl_versions[] = {
GDK_GL_VERSION_INIT (4, 6),
GDK_GL_VERSION_INIT (4, 5),
GDK_GL_VERSION_INIT (4, 4),
GDK_GL_VERSION_INIT (4, 3),
GDK_GL_VERSION_INIT (4, 2),
GDK_GL_VERSION_INIT (4, 1),
GDK_GL_VERSION_INIT (4, 0),
GDK_GL_VERSION_INIT (3, 3),
GDK_GL_VERSION_INIT (3, 2),
GDK_GL_VERSION_INIT (3, 1),
GDK_GL_VERSION_INIT (3, 0),
GDK_GL_VERSION_INIT (0, 0)
};
static const GdkGLVersion supported_gles_versions[] = {
GDK_GL_VERSION_INIT (3, 2),
GDK_GL_VERSION_INIT (3, 1),
GDK_GL_VERSION_INIT (3, 0),
GDK_GL_VERSION_INIT (2, 0),
GDK_GL_VERSION_INIT (0, 0)
};
#undef GDK_GL_VERSION_INIT
#define GDK_GL_VERSION_INIT(maj,min) (GdkGLVersion) { maj, min }
#define GDK_GL_VERSION_STRING(str) GDK_GL_VERSION_INIT(str[0] - '0', str[2] - '0')
static inline const GdkGLVersion *
gdk_gl_versions_get_for_api (GdkGLAPI api)
{
switch (api)
{
case GDK_GL_API_GL:
return supported_gl_versions;
case GDK_GL_API_GLES:
return supported_gles_versions;
default:
g_assert_not_reached ();
return NULL;
}
}
static inline int
gdk_gl_version_get_major (const GdkGLVersion *self)
{
return self->major;
}
static inline int
gdk_gl_version_get_minor (const GdkGLVersion *self)
{
return self->minor;
}
static inline int
gdk_gl_version_compare (const GdkGLVersion *a,
const GdkGLVersion *b)
{
if (a->major > b->major)
return 1;
if (a->major < b->major)
return -1;
if (a->minor > b->minor)
return 1;
if (a->minor < b->minor)
return -1;
return 0;
}
static inline gboolean
gdk_gl_version_greater_equal (const GdkGLVersion *a,
const GdkGLVersion *b)
{
return gdk_gl_version_compare (a, b) >= 0;
}
/* in gdkglcontext.c */
void gdk_gl_version_init_epoxy (GdkGLVersion *version);
G_END_DECLS
+40 -21
View File
@@ -220,7 +220,12 @@ struct _GdkMemoryFormatDescription
gsize bytes_per_pixel;
gsize alignment;
gboolean prefers_high_depth;
gboolean supports_gles;
struct {
guint gl_major;
guint gl_minor;
guint gles_major;
guint gles_minor;
} min_gl_version;
struct {
guint internal_format;
guint format;
@@ -245,7 +250,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
4,
G_ALIGNOF (guchar),
FALSE,
FALSE,
{ 0, 0, G_MAXUINT, G_MAXUINT },
{ GL_RGBA8, GL_BGRA, GL_UNSIGNED_BYTE },
b8g8r8a8_premultiplied_to_float,
b8g8r8a8_premultiplied_from_float,
@@ -255,7 +260,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
4,
G_ALIGNOF (guchar),
FALSE,
FALSE,
{ 0, 0, G_MAXUINT, G_MAXUINT },
{ GL_RGBA8, GL_BGRA, GDK_GL_UNSIGNED_BYTE_FLIPPED },
a8r8g8b8_premultiplied_to_float,
a8r8g8b8_premultiplied_from_float,
@@ -265,7 +270,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
4,
G_ALIGNOF (guchar),
FALSE,
TRUE,
{ 0, 0, 0, 0 },
{ GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE },
r8g8b8a8_premultiplied_to_float,
r8g8b8a8_premultiplied_from_float,
@@ -275,7 +280,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
4,
G_ALIGNOF (guchar),
FALSE,
FALSE,
{ 0, 0, G_MAXUINT, G_MAXUINT },
{ GL_RGBA8, GL_BGRA, GL_UNSIGNED_BYTE },
b8g8r8a8_to_float,
b8g8r8a8_from_float,
@@ -285,7 +290,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
4,
G_ALIGNOF (guchar),
FALSE,
FALSE,
{ 0, 0, G_MAXUINT, G_MAXUINT },
{ GL_RGBA8, GL_RGBA, GDK_GL_UNSIGNED_BYTE_FLIPPED },
a8r8g8b8_to_float,
a8r8g8b8_from_float,
@@ -295,7 +300,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
4,
G_ALIGNOF (guchar),
FALSE,
TRUE,
{ 0, 0, 0, 0 },
{ GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE },
r8g8b8a8_to_float,
r8g8b8a8_from_float,
@@ -305,7 +310,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
4,
G_ALIGNOF (guchar),
FALSE,
FALSE,
{ 0, 0, G_MAXUINT, G_MAXUINT },
{ GL_RGBA8, GL_BGRA, GDK_GL_UNSIGNED_BYTE_FLIPPED },
a8b8g8r8_to_float,
a8b8g8r8_from_float,
@@ -315,7 +320,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
3,
G_ALIGNOF (guchar),
FALSE,
TRUE,
{ 0, 0, 0, 0 },
{ GL_RGB8, GL_RGB, GL_UNSIGNED_BYTE },
r8g8b8_to_float,
r8g8b8_from_float,
@@ -325,7 +330,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
3,
G_ALIGNOF (guchar),
FALSE,
FALSE,
{ 0, 0, G_MAXUINT, G_MAXUINT },
{ GL_RGB8, GL_BGR, GL_UNSIGNED_BYTE },
b8g8r8_to_float,
b8g8r8_from_float,
@@ -335,7 +340,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
6,
G_ALIGNOF (guint16),
TRUE,
TRUE,
{ 0, 0, 3, 0 },
{ GL_RGB16, GL_RGB, GL_UNSIGNED_SHORT },
r16g16b16_to_float,
r16g16b16_from_float,
@@ -345,7 +350,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
8,
G_ALIGNOF (guint16),
TRUE,
TRUE,
{ 0, 0, 3, 0 },
{ GL_RGBA16, GL_RGBA, GL_UNSIGNED_SHORT },
r16g16b16a16_to_float,
r16g16b16a16_from_float,
@@ -355,7 +360,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
8,
G_ALIGNOF (guint16),
TRUE,
TRUE,
{ 0, 0, 3, 0 },
{ GL_RGBA16, GL_RGBA, GL_UNSIGNED_SHORT },
r16g16b16a16_to_float,
r16g16b16a16_from_float,
@@ -365,7 +370,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
6,
G_ALIGNOF (guint16),
TRUE,
TRUE,
{ 0, 0, 3, 0 },
{ GL_RGB16F, GL_RGB, GL_HALF_FLOAT },
r16g16b16_float_to_float,
r16g16b16_float_from_float,
@@ -375,7 +380,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
8,
G_ALIGNOF (guint16),
TRUE,
TRUE,
{ 0, 0, 3, 0 },
{ GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT },
r16g16b16a16_float_to_float,
r16g16b16a16_float_from_float,
@@ -385,7 +390,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
8,
G_ALIGNOF (guint16),
TRUE,
TRUE,
{ 0, 0, 3, 0 },
{ GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT },
r16g16b16a16_float_to_float,
r16g16b16a16_float_from_float,
@@ -395,7 +400,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
12,
G_ALIGNOF (float),
TRUE,
TRUE,
{ 0, 0, 3, 0 },
{ GL_RGB32F, GL_RGB, GL_FLOAT },
r32g32b32_float_to_float,
r32g32b32_float_from_float,
@@ -405,7 +410,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
16,
G_ALIGNOF (float),
TRUE,
TRUE,
{ 0, 0, 3, 0 },
{ GL_RGBA32F, GL_RGBA, GL_FLOAT },
r32g32b32a32_float_to_float,
r32g32b32a32_float_from_float,
@@ -415,7 +420,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
16,
G_ALIGNOF (float),
TRUE,
TRUE,
{ 0, 0, 3, 0 },
{ GL_RGBA32F, GL_RGBA, GL_FLOAT },
r32g32b32a32_float_to_float,
r32g32b32a32_float_from_float,
@@ -463,6 +468,8 @@ gdk_memory_format_prefers_high_depth (GdkMemoryFormat format)
gboolean
gdk_memory_format_gl_format (GdkMemoryFormat format,
gboolean gles,
guint gl_major,
guint gl_minor,
guint *out_internal_format,
guint *out_format,
guint *out_type)
@@ -474,8 +481,20 @@ gdk_memory_format_gl_format (GdkMemoryFormat format,
if (memory_formats[format].alpha == GDK_MEMORY_ALPHA_STRAIGHT)
return FALSE;
if (gles && !memory_formats[format].supports_gles)
return FALSE;
if (gles)
{
if (memory_formats[format].min_gl_version.gles_major > gl_major ||
(memory_formats[format].min_gl_version.gles_major == gl_major &&
memory_formats[format].min_gl_version.gles_minor > gl_minor))
return FALSE;
}
else
{
if (memory_formats[format].min_gl_version.gl_major > gl_major ||
(memory_formats[format].min_gl_version.gl_major == gl_major &&
memory_formats[format].min_gl_version.gl_minor > gl_minor))
return FALSE;
}
return TRUE;
}
+2
View File
@@ -35,6 +35,8 @@ gsize gdk_memory_format_bytes_per_pixel (GdkMemoryFormat
gboolean gdk_memory_format_prefers_high_depth(GdkMemoryFormat format) G_GNUC_CONST;
gboolean gdk_memory_format_gl_format (GdkMemoryFormat format,
gboolean gles,
guint gl_major,
guint gl_minor,
guint *out_internal_format,
guint *out_format,
guint *out_type);
+57
View File
@@ -0,0 +1,57 @@
#pragma once
#include "gdkrectangle.h"
#include <math.h>
G_BEGIN_DECLS
/*
* gdk_rectangle_transform_affine:
* @src: the rectangle to transform
* @scale_x: scale factor in the X direction. The scale factor
* may be negative or 0.
* @scale_y: scale factor in the Y direction. The scale factor
* may be negative or 0.
* @offset_x: offset of result in X direction.
* @offset_y: offset of result in Y direction.
* @dest: (out caller-allocates): destination rectangle, may be
* identical to @src
*
* Does an affine transform of the source rectangle and stores the
* result in the dest rectangle. If the destination rectangle does
* not fit on integer bounds, the result will be enlarged to make it
* fit.
* (Fun fact: This means with a scale of 0 and an offset of 0.5,
* the resulting rect will have a width of 1.)
*
* The width and height of the result will be positive, even if the
* src rectangle or the scale were negative.
*
* This function can be used with the output of
* gsk_transform_to_affine().
**/
static inline void
gdk_rectangle_transform_affine (const GdkRectangle *src,
float scale_x,
float scale_y,
float offset_x,
float offset_y,
GdkRectangle *dest)
{
float x1, x2, y1, y2;
x1 = offset_x + src->x * scale_x;
x2 = offset_x + (src->x + src->width) * scale_x;
y1 = offset_y + src->y * scale_y;
y2 = offset_y + (src->y + src->height) * scale_y;
dest->x = floorf (MIN (x1, x2));
dest->y = floorf (MIN (y1, y2));
dest->width = ceilf (MAX (x1, x2)) - dest->x;
dest->height = ceilf (MAX (y1, y2)) - dest->y;
}
G_END_DECLS
+39 -113
View File
@@ -115,9 +115,6 @@ static void gdk_surface_get_property (GObject *object,
static void update_cursor (GdkDisplay *display,
GdkDevice *device);
static void gdk_surface_set_frame_clock (GdkSurface *surface,
GdkFrameClock *clock);
static void gdk_surface_queue_set_is_mapped (GdkSurface *surface,
gboolean is_mapped);
@@ -496,11 +493,22 @@ gdk_surface_real_get_scale (GdkSurface *surface)
return 1.0;
}
static void
gdk_surface_constructed (GObject *object)
{
G_GNUC_UNUSED GdkSurface *surface = GDK_SURFACE (object);
g_assert (surface->frame_clock != NULL);
G_OBJECT_CLASS (gdk_surface_parent_class)->constructed (object);
}
static void
gdk_surface_class_init (GdkSurfaceClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->constructed = gdk_surface_constructed;
object_class->finalize = gdk_surface_finalize;
object_class->set_property = gdk_surface_set_property;
object_class->get_property = gdk_surface_get_property;
@@ -845,21 +853,6 @@ _gdk_surface_update_size (GdkSurface *surface)
g_object_notify (G_OBJECT (surface), "height");
}
static GdkSurface *
gdk_surface_new (GdkDisplay *display,
GdkSurfaceType surface_type,
GdkSurface *parent,
int x,
int y,
int width,
int height)
{
return gdk_display_create_surface (display,
surface_type,
parent,
x, y, width, height);
}
/**
* gdk_surface_new_toplevel: (constructor)
* @display: the display to create the surface on
@@ -873,8 +866,9 @@ gdk_surface_new_toplevel (GdkDisplay *display)
{
g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
return gdk_surface_new (display, GDK_SURFACE_TOPLEVEL,
NULL, 0, 0, 1, 1);
return g_object_new (GDK_DISPLAY_GET_CLASS (display)->toplevel_type,
"display", display,
NULL);
}
/**
@@ -894,11 +888,16 @@ gdk_surface_new_popup (GdkSurface *parent,
gboolean autohide)
{
GdkSurface *surface;
GdkDisplay *display;
g_return_val_if_fail (GDK_IS_SURFACE (parent), NULL);
surface = gdk_surface_new (parent->display, GDK_SURFACE_POPUP,
parent, 0, 0, 100, 100);
display = gdk_surface_get_display (parent);
surface = g_object_new (GDK_DISPLAY_GET_CLASS (display)->popup_type,
"display", display,
"parent", parent,
NULL);
surface->autohide = autohide;
@@ -1270,40 +1269,6 @@ gdk_surface_create_vulkan_context (GdkSurface *surface,
NULL);
}
/* Code for dirty-region queueing
*/
static GSList *update_surfaces = NULL;
static void
gdk_surface_add_update_surface (GdkSurface *surface)
{
GSList *tmp;
/* Check whether "surface" is already in "update_surfaces" list.
* It could be added during execution of gtk_widget_destroy() when
* setting focus widget to NULL and redrawing old focus widget.
* See bug 711552.
*/
tmp = g_slist_find (update_surfaces, surface);
if (tmp != NULL)
return;
update_surfaces = g_slist_prepend (update_surfaces, g_object_ref (surface));
}
static void
gdk_surface_remove_update_surface (GdkSurface *surface)
{
GSList *link;
link = g_slist_find (update_surfaces, surface);
if (link != NULL)
{
update_surfaces = g_slist_delete_link (update_surfaces, link);
g_object_unref (surface);
}
}
static gboolean
gdk_surface_is_toplevel_frozen (GdkSurface *surface)
{
@@ -1332,46 +1297,6 @@ gdk_surface_schedule_update (GdkSurface *surface)
GDK_FRAME_CLOCK_PHASE_PAINT);
}
static void
gdk_surface_process_updates_internal (GdkSurface *surface)
{
/* Ensure the surface lives while updating it */
g_object_ref (surface);
surface->in_update = TRUE;
/* If an update got queued during update processing, we can get a
* surface in the update queue that has an empty update_area.
* just ignore it.
*/
if (surface->update_area)
{
g_assert (surface->active_update_area == NULL); /* No reentrancy */
surface->active_update_area = surface->update_area;
surface->update_area = NULL;
if (GDK_SURFACE_IS_MAPPED (surface))
{
cairo_region_t *expose_region;
gboolean handled;
expose_region = cairo_region_copy (surface->active_update_area);
g_signal_emit (surface, signals[RENDER], 0, expose_region, &handled);
cairo_region_destroy (expose_region);
}
cairo_region_destroy (surface->active_update_area);
surface->active_update_area = NULL;
}
surface->in_update = FALSE;
g_object_unref (surface);
}
static void
gdk_surface_layout_on_clock (GdkFrameClock *clock,
void *data)
@@ -1429,28 +1354,32 @@ gdk_surface_paint_on_clock (GdkFrameClock *clock,
void *data)
{
GdkSurface *surface = GDK_SURFACE (data);
cairo_region_t *expose_region;
g_return_if_fail (GDK_IS_SURFACE (surface));
if (GDK_SURFACE_DESTROYED (surface))
if (GDK_SURFACE_DESTROYED (surface) ||
!surface->update_area ||
surface->update_freeze_count ||
gdk_surface_is_toplevel_frozen (surface))
return;
g_object_ref (surface);
surface->pending_phases &= ~GDK_FRAME_CLOCK_PHASE_PAINT;
expose_region = surface->update_area;
surface->update_area = NULL;
if (surface->update_area &&
!surface->update_freeze_count &&
!gdk_surface_is_toplevel_frozen (surface) &&
/* Don't recurse into process_updates_internal, we'll
* do the update later when idle instead. */
!surface->in_update)
if (GDK_SURFACE_IS_MAPPED (surface))
{
surface->pending_phases &= ~GDK_FRAME_CLOCK_PHASE_PAINT;
gdk_surface_process_updates_internal (surface);
gdk_surface_remove_update_surface (surface);
gboolean handled;
g_object_ref (surface);
g_signal_emit (surface, signals[RENDER], 0, expose_region, &handled);
g_object_unref (surface);
}
g_object_unref (surface);
cairo_region_destroy (expose_region);
}
/*
@@ -1498,7 +1427,6 @@ impl_surface_add_update_area (GdkSurface *impl_surface,
cairo_region_union (impl_surface->update_area, region);
else
{
gdk_surface_add_update_surface (impl_surface);
impl_surface->update_area = cairo_region_copy (region);
gdk_surface_schedule_update (impl_surface);
}
@@ -1582,8 +1510,6 @@ _gdk_surface_clear_update_area (GdkSurface *surface)
if (surface->update_area)
{
gdk_surface_remove_update_surface (surface);
cairo_region_destroy (surface->update_area);
surface->update_area = NULL;
}
@@ -2530,7 +2456,7 @@ gdk_surface_resume_events (GdkFrameClock *clock,
}
}
static void
void
gdk_surface_set_frame_clock (GdkSurface *surface,
GdkFrameClock *clock)
{
+2 -14
View File
@@ -26,13 +26,6 @@
G_BEGIN_DECLS
typedef enum
{
GDK_SURFACE_TOPLEVEL,
GDK_SURFACE_POPUP,
GDK_SURFACE_DRAG
} GdkSurfaceType;
struct _GdkSurface
{
GObject parent_instance;
@@ -55,10 +48,6 @@ struct _GdkSurface
cairo_region_t *update_area;
guint update_freeze_count;
GdkFrameClockPhase pending_phases;
/* This is the update_area that was in effect when the current expose
started. It may be smaller than the expose area if we'e painting
more than we have to, but it represents the "true" damage. */
cairo_region_t *active_update_area;
GdkToplevelState pending_set_flags;
GdkToplevelState pending_unset_flags;
@@ -71,7 +60,6 @@ struct _GdkSurface
guint modal_hint : 1;
guint destroyed : 2;
guint in_update : 1;
guint frame_clock_events_paused : 1;
guint autohide : 1;
guint shortcuts_inhibited : 1;
@@ -110,8 +98,6 @@ struct _GdkSurfaceClass
{
GObjectClass parent_class;
cairo_surface_t *
(* ref_cairo_surface) (GdkSurface *surface);
void (* hide) (GdkSurface *surface);
void (* get_geometry) (GdkSurface *surface,
int *x,
@@ -292,6 +278,8 @@ void gdk_surface_get_geometry (GdkSurface *surface,
int *width,
int *height);
void gdk_surface_set_frame_clock (GdkSurface *surface,
GdkFrameClock *clock);
void gdk_surface_set_egl_native_window (GdkSurface *self,
gpointer native_window);
void gdk_surface_ensure_egl_surface (GdkSurface *self,
+43 -1
View File
@@ -282,6 +282,8 @@ gdk_texture_dispose (GObject *object)
{
GdkTexture *self = GDK_TEXTURE (object);
g_clear_pointer (&self->diff_to_previous, cairo_region_destroy);
gdk_texture_clear_render_data (self);
G_OBJECT_CLASS (gdk_texture_parent_class)->dispose (object);
@@ -671,7 +673,47 @@ gdk_texture_do_download (GdkTexture *texture,
guchar *data,
gsize stride)
{
GDK_TEXTURE_GET_CLASS (texture)->download (texture, format, data,stride);
GDK_TEXTURE_GET_CLASS (texture)->download (texture, format, data, stride);
}
void
gdk_texture_diff (GdkTexture *self,
GdkTexture *other,
cairo_region_t *region)
{
if (self == other)
return;
if (self->previous_texture == other &&
g_atomic_pointer_get (&other->next_texture) == self)
{
cairo_region_union (region, self->diff_to_previous);
}
else if (other->previous_texture == self &&
g_atomic_pointer_get (&self->next_texture) == other)
{
cairo_region_union (region, other->diff_to_previous);
}
else
{
cairo_region_union_rectangle (region,
&(cairo_rectangle_int_t) {
0,
0,
MAX (self->width, other->width),
MAX (self->height, other->height)
});
}
}
void
gdk_texture_set_diff (GdkTexture *self,
GdkTexture *previous,
cairo_region_t *diff)
{
self->previous_texture = previous;
self->diff_to_previous = diff;
g_atomic_pointer_set (&previous->next_texture, self);
}
cairo_surface_t *
+14
View File
@@ -21,6 +21,12 @@ struct _GdkTexture
gpointer render_key;
gpointer render_data;
GDestroyNotify render_notify;
/* for diffing swapchain-like textures.
* Links are only valid if both textures agree on them */
gpointer next_texture; /* atomic, no reference, may be invalid pointer */
gpointer previous_texture; /* no reference, may be invalid pointer */
cairo_region_t *diff_to_previous;
};
struct _GdkTextureClass {
@@ -42,6 +48,14 @@ void gdk_texture_do_download (GdkTexture
GdkMemoryFormat format,
guchar *data,
gsize stride);
void gdk_texture_diff (GdkTexture *self,
GdkTexture *other,
cairo_region_t *region);
void gdk_texture_set_diff (GdkTexture *self,
GdkTexture *previous,
cairo_region_t *diff);
gboolean gdk_texture_set_render_data (GdkTexture *self,
gpointer key,
gpointer data,
+76 -2
View File
@@ -223,7 +223,7 @@ gdk_vulkan_strerror (VkResult result)
#if VK_HEADER_VERSION < 140
case VK_RESULT_RANGE_SIZE:
#endif
#if VK_HEADER_VERSION >= 218
#if VK_HEADER_VERSION >= 238
case VK_ERROR_IMAGE_USAGE_NOT_SUPPORTED_KHR:
return "The requested VkImageUsageFlags are not supported. (VK_ERROR_IMAGE_USAGE_NOT_SUPPORTED_KHR)";
case VK_ERROR_VIDEO_PICTURE_LAYOUT_NOT_SUPPORTED_KHR:
@@ -243,6 +243,74 @@ gdk_vulkan_strerror (VkResult result)
}
}
#ifdef G_ENABLE_DEBUG
static const char *
surface_present_mode_to_string (VkPresentModeKHR present_mode)
{
switch (present_mode)
{
case VK_PRESENT_MODE_MAILBOX_KHR:
return "VK_PRESENT_MODE_MAILBOX_KHR";
case VK_PRESENT_MODE_IMMEDIATE_KHR:
return "VK_PRESENT_MODE_IMMEDIATE_KHR";
case VK_PRESENT_MODE_FIFO_KHR:
return "VK_PRESENT_MODE_FIFO_KHR";
case VK_PRESENT_MODE_FIFO_RELAXED_KHR:
return "VK_PRESENT_MODE_FIFO_RELAXED_KHR";
case VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR:
case VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR:
case VK_PRESENT_MODE_MAX_ENUM_KHR:
default:
return "(invalid)";
}
return "(unknown)";
}
#endif
static const VkPresentModeKHR preferred_present_modes[] = {
VK_PRESENT_MODE_MAILBOX_KHR,
VK_PRESENT_MODE_IMMEDIATE_KHR,
};
static VkPresentModeKHR
find_best_surface_present_mode (GdkVulkanContext *context)
{
GdkVulkanContextPrivate *priv = gdk_vulkan_context_get_instance_private (context);
VkPresentModeKHR *available_present_modes;
uint32_t n_present_modes;
VkResult res;
res = GDK_VK_CHECK (vkGetPhysicalDeviceSurfacePresentModesKHR, gdk_vulkan_context_get_physical_device (context),
priv->surface,
&n_present_modes,
NULL);
if (res != VK_SUCCESS)
goto fallback_present_mode;
available_present_modes = g_alloca (sizeof (VkPresentModeKHR) * n_present_modes);
res = GDK_VK_CHECK (vkGetPhysicalDeviceSurfacePresentModesKHR, gdk_vulkan_context_get_physical_device (context),
priv->surface,
&n_present_modes,
available_present_modes);
if (res != VK_SUCCESS)
goto fallback_present_mode;
for (uint32_t i = 0; i < G_N_ELEMENTS (preferred_present_modes); i++)
{
for (uint32_t j = 0; j < n_present_modes; j++)
{
if (preferred_present_modes[i] == available_present_modes[j])
return available_present_modes[j];
}
}
fallback_present_mode:
return VK_PRESENT_MODE_FIFO_KHR;
}
static void
gdk_vulkan_context_dispose (GObject *gobject)
{
@@ -302,6 +370,7 @@ gdk_vulkan_context_check_swapchain (GdkVulkanContext *context,
GdkSurface *surface = gdk_draw_context_get_surface (GDK_DRAW_CONTEXT (context));
VkSurfaceCapabilitiesKHR capabilities;
VkCompositeAlphaFlagBitsKHR composite_alpha;
VkPresentModeKHR present_mode;
VkSwapchainKHR new_swapchain;
VkResult res;
VkDevice device;
@@ -333,6 +402,11 @@ gdk_vulkan_context_check_swapchain (GdkVulkanContext *context,
composite_alpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
}
present_mode = find_best_surface_present_mode (context);
GDK_DEBUG (VULKAN, "Using surface present mode %s",
surface_present_mode_to_string (present_mode));
/*
* Per https://www.khronos.org/registry/vulkan/specs/1.0-wsi_extensions/xhtml/vkspec.html#VkSurfaceCapabilitiesKHR
* the current extent may assume a special value, meaning that the extent should assume whatever
@@ -367,7 +441,7 @@ gdk_vulkan_context_check_swapchain (GdkVulkanContext *context,
},
.preTransform = capabilities.currentTransform,
.compositeAlpha = composite_alpha,
.presentMode = VK_PRESENT_MODE_FIFO_KHR,
.presentMode = present_mode,
.clipped = VK_FALSE,
.oldSwapchain = priv->swapchain
},
+2
View File
@@ -121,6 +121,8 @@ GdkMonitor *_gdk_macos_display_get_monitor_at_coords (GdkMacosDisp
GdkMonitor *_gdk_macos_display_get_monitor_at_display_coords (GdkMacosDisplay *self,
int x,
int y);
void _gdk_macos_display_surface_added (GdkMacosDisplay *self,
GdkMacosSurface *surface);
GdkEvent *_gdk_macos_display_translate (GdkMacosDisplay *self,
NSEvent *event);
void _gdk_macos_display_feedback_init (GdkMacosDisplay *self);
+5 -25
View File
@@ -36,8 +36,10 @@
#include "gdkmacosglcontext-private.h"
#include "gdkmacoskeymap-private.h"
#include "gdkmacosmonitor-private.h"
#include "gdkmacospopupsurface-private.h"
#include "gdkmacosseat-private.h"
#include "gdkmacossurface-private.h"
#include "gdkmacostoplevelsurface-private.h"
#include "gdkmacosutils-private.h"
G_DEFINE_TYPE (GdkMacosDisplay, gdk_macos_display, GDK_TYPE_DISPLAY)
@@ -333,7 +335,7 @@ gdk_macos_display_queue_events (GdkDisplay *display)
}
}
static void
void
_gdk_macos_display_surface_added (GdkMacosDisplay *self,
GdkMacosSurface *surface)
{
@@ -539,29 +541,6 @@ _gdk_macos_display_surface_resigned_main (GdkMacosDisplay *self,
_gdk_macos_display_clear_sorting (self);
}
static GdkSurface *
gdk_macos_display_create_surface (GdkDisplay *display,
GdkSurfaceType surface_type,
GdkSurface *parent,
int x,
int y,
int width,
int height)
{
GdkMacosDisplay *self = (GdkMacosDisplay *)display;
GdkMacosSurface *surface;
g_assert (GDK_IS_MACOS_DISPLAY (self));
g_assert (!parent || GDK_IS_MACOS_SURFACE (parent));
surface = _gdk_macos_surface_new (self, surface_type, parent, x, y, width, height);
if (surface != NULL)
_gdk_macos_display_surface_added (self, surface);
return GDK_SURFACE (surface);
}
static GdkKeymap *
gdk_macos_display_get_keymap (GdkDisplay *display)
{
@@ -617,10 +596,11 @@ gdk_macos_display_class_init (GdkMacosDisplayClass *klass)
object_class->finalize = gdk_macos_display_finalize;
display_class->toplevel_type = GDK_TYPE_MACOS_TOPLEVEL_SURFACE;
display_class->popup_type = GDK_TYPE_MACOS_POPUP_SURFACE;
display_class->cairo_context_type = GDK_TYPE_MACOS_CAIRO_CONTEXT;
display_class->beep = gdk_macos_display_beep;
display_class->create_surface = gdk_macos_display_create_surface;
display_class->flush = gdk_macos_display_flush;
display_class->get_keymap = gdk_macos_display_get_keymap;
display_class->get_monitors = gdk_macos_display_get_monitors;
+1 -6
View File
@@ -31,12 +31,7 @@ typedef struct _GdkMacosDragSurfaceClass GdkMacosDragSurfaceClass;
#define GDK_IS_MACOS_DRAG_SURFACE(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_MACOS_DRAG_SURFACE))
GType _gdk_macos_drag_surface_get_type (void);
GdkMacosSurface *_gdk_macos_drag_surface_new (GdkMacosDisplay *display,
GdkFrameClock *frame_clock,
int x,
int y,
int width,
int height);
GdkMacosSurface *_gdk_macos_drag_surface_new (GdkMacosDisplay *display);
G_END_DECLS
+38 -28
View File
@@ -25,6 +25,8 @@
#include "gdkmacosdisplay-private.h"
#include "gdkmacosutils-private.h"
#include "gdk/gdkframeclockidleprivate.h"
struct _GdkMacosDragSurface
{
GdkMacosSurface parent_instance;
@@ -62,27 +64,15 @@ G_DEFINE_TYPE_WITH_CODE (GdkMacosDragSurface, _gdk_macos_drag_surface, GDK_TYPE_
G_IMPLEMENT_INTERFACE (GDK_TYPE_DRAG_SURFACE, drag_surface_iface_init))
static void
_gdk_macos_drag_surface_class_init (GdkMacosDragSurfaceClass *klass)
{
}
static void
_gdk_macos_drag_surface_init (GdkMacosDragSurface *self)
{
}
GdkMacosSurface *
_gdk_macos_drag_surface_new (GdkMacosDisplay *display,
GdkFrameClock *frame_clock,
int x,
int y,
int width,
int height)
_gdk_macos_drag_surface_constructed (GObject *object)
{
GDK_BEGIN_MACOS_ALLOC_POOL;
GdkMacosWindow *window;
GdkMacosSurface *self;
GdkMacosSurface *self = GDK_MACOS_SURFACE (object);
GdkSurface *surface = GDK_SURFACE (self);
GdkMacosDisplay *display = GDK_MACOS_DISPLAY (gdk_surface_get_display (GDK_SURFACE (self)));
GdkFrameClock *frame_clock;
NSScreen *screen;
NSUInteger style_mask;
NSRect content_rect;
@@ -90,18 +80,15 @@ _gdk_macos_drag_surface_new (GdkMacosDisplay *display,
int nx;
int ny;
g_return_val_if_fail (GDK_IS_MACOS_DISPLAY (display), NULL);
g_return_val_if_fail (!frame_clock || GDK_IS_FRAME_CLOCK (frame_clock), NULL);
style_mask = NSWindowStyleMaskBorderless;
_gdk_macos_display_to_display_coords (display, x, y, &nx, &ny);
_gdk_macos_display_to_display_coords (display, 0, 0, &nx, &ny);
screen = _gdk_macos_display_get_screen_at_display_coords (display, nx, ny);
screen_rect = [screen frame];
nx -= screen_rect.origin.x;
ny -= screen_rect.origin.y;
content_rect = NSMakeRect (nx, ny - height, width, height);
content_rect = NSMakeRect (nx, ny - 1, 1, 1);
window = [[GdkMacosWindow alloc] initWithContentRect:content_rect
styleMask:style_mask
@@ -113,13 +100,36 @@ _gdk_macos_drag_surface_new (GdkMacosDisplay *display,
[window setBackgroundColor:[NSColor clearColor]];
[window setDecorated:NO];
self = g_object_new (GDK_TYPE_MACOS_DRAG_SURFACE,
"display", display,
"frame-clock", frame_clock,
"native", window,
NULL);
_gdk_macos_surface_set_native (self, window);
frame_clock = _gdk_frame_clock_idle_new ();
gdk_surface_set_frame_clock (surface, frame_clock);
g_object_unref (frame_clock);
GDK_END_MACOS_ALLOC_POOL;
return g_steal_pointer (&self);
G_OBJECT_CLASS (_gdk_macos_drag_surface_parent_class)->constructed (object);
}
static void
_gdk_macos_drag_surface_class_init (GdkMacosDragSurfaceClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->constructed = _gdk_macos_drag_surface_constructed;
}
static void
_gdk_macos_drag_surface_init (GdkMacosDragSurface *self)
{
}
GdkMacosSurface *
_gdk_macos_drag_surface_new (GdkMacosDisplay *display)
{
g_return_val_if_fail (GDK_IS_MACOS_DISPLAY (display), NULL);
return g_object_new (GDK_TYPE_MACOS_DRAG_SURFACE,
"display", display,
NULL);
}
+40 -15
View File
@@ -323,12 +323,12 @@ gdk_macos_gl_context_release (GdkMacosGLContext *self)
}
static CGLPixelFormatObj
create_pixel_format (int major,
int minor,
GError **error)
create_pixel_format (GdkGLVersion *version,
gboolean *out_legacy,
GError **error)
{
CGLPixelFormatAttribute attrs[] = {
kCGLPFAOpenGLProfile, (CGLPixelFormatAttribute)kCGLOGLPVersion_Legacy,
kCGLPFAOpenGLProfile, 0,
kCGLPFAAllowOfflineRenderers, /* allow sharing across GPUs */
kCGLPFADepthSize, 0,
kCGLPFAStencilSize, 0,
@@ -339,14 +339,28 @@ create_pixel_format (int major,
CGLPixelFormatObj format = NULL;
GLint n_format = 1;
if (major == 3 && minor == 2)
attrs[1] = (CGLPixelFormatAttribute)kCGLOGLPVersion_GL3_Core;
else if (major == 4 && minor == 1)
attrs[1] = (CGLPixelFormatAttribute)kCGLOGLPVersion_GL4_Core;
*out_legacy = FALSE;
if (gdk_gl_version_get_major (version) >= 4)
{
attrs[1] = (CGLPixelFormatAttribute)kCGLOGLPVersion_GL4_Core;
if (CGLChoosePixelFormat (attrs, &format, &n_format))
return g_steal_pointer (&format);
}
if (gdk_gl_version_greater_equal (version, &GDK_GL_MIN_GL_VERSION))
{
attrs[1] = (CGLPixelFormatAttribute)kCGLOGLPVersion_GL3_Core;
if (CGLChoosePixelFormat (attrs, &format, &n_format))
return g_steal_pointer (&format);
}
attrs[1] = (CGLPixelFormatAttribute) kCGLOGLPVersion_Legacy;
if (!CHECK (error, CGLChoosePixelFormat (attrs, &format, &n_format)))
return NULL;
*out_legacy = TRUE;
return g_steal_pointer (&format);
}
@@ -366,7 +380,8 @@ gdk_macos_gl_context_real_realize (GdkGLContext *context,
GLint validate = 0;
GLint renderer_id = 0;
GLint swapRect[4];
int major, minor;
GdkGLVersion min_version, version;
gboolean legacy;
g_assert (GDK_IS_MACOS_GL_CONTEXT (self));
@@ -378,10 +393,10 @@ gdk_macos_gl_context_real_realize (GdkGLContext *context,
existing = CGLGetCurrentContext ();
gdk_gl_context_get_clipped_version (context,
GDK_GL_MIN_GL_VERSION_MAJOR,
GDK_GL_MIN_GL_VERSION_MINOR,
&major, &minor);
gdk_gl_context_get_matching_version (context,
GDK_GL_API_GL,
FALSE,
&version);
display = gdk_gl_context_get_display (context);
shared = gdk_display_get_gl_context (display);
@@ -400,9 +415,9 @@ gdk_macos_gl_context_real_realize (GdkGLContext *context,
GDK_DISPLAY_DEBUG (display, OPENGL,
"Creating CGLContextObj (version %d.%d)",
major, minor);
gdk_gl_version_get_major (&min_version), gdk_gl_version_get_minor (&min_version));
if (!(pixelFormat = create_pixel_format (major, minor, error)))
if (!(pixelFormat = create_pixel_format (&min_version, &legacy, error)))
return 0;
if (!CHECK (error, CGLCreateContext (pixelFormat, shared_gl_context, &cgl_context)))
@@ -414,6 +429,13 @@ gdk_macos_gl_context_real_realize (GdkGLContext *context,
CGLSetCurrentContext (cgl_context);
CGLReleasePixelFormat (pixelFormat);
gdk_gl_version_init_epoxy (&version);
if (!gdk_gl_version_greater_equal (&version, &min_version))
{
CGLReleaseContext (cgl_context);
return 0;
}
if (validate)
CHECK (NULL, CGLEnable (cgl_context, kCGLCEStateValidation));
@@ -445,6 +467,9 @@ gdk_macos_gl_context_real_realize (GdkGLContext *context,
cgl_context,
get_renderer_name (renderer_id));
gdk_gl_context_set_version (context, &version);
gdk_gl_context_set_is_legacy (context, legacy);
self->cgl_context = g_steal_pointer (&cgl_context);
if (existing != NULL)
+1 -5
View File
@@ -33,11 +33,7 @@ typedef struct _GdkMacosPopupSurfaceClass GdkMacosPopupSurfaceClass;
GType _gdk_macos_popup_surface_get_type (void);
GdkMacosSurface *_gdk_macos_popup_surface_new (GdkMacosDisplay *display,
GdkSurface *parent,
GdkFrameClock *frame_clock,
int x,
int y,
int width,
int height);
GdkFrameClock *frame_clock);
void _gdk_macos_popup_surface_attach_to_parent (GdkMacosPopupSurface *self);
void _gdk_macos_popup_surface_detach_from_parent (GdkMacosPopupSurface *self);
void _gdk_macos_popup_surface_reposition (GdkMacosPopupSurface *self);
+31 -41
View File
@@ -284,38 +284,14 @@ _gdk_macos_popup_surface_set_property (GObject *object,
}
static void
_gdk_macos_popup_surface_class_init (GdkMacosPopupSurfaceClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GdkSurfaceClass *surface_class = GDK_SURFACE_CLASS (klass);
object_class->finalize = _gdk_macos_popup_surface_finalize;
object_class->get_property = _gdk_macos_popup_surface_get_property;
object_class->set_property = _gdk_macos_popup_surface_set_property;
surface_class->hide = _gdk_macos_popup_surface_hide;
gdk_popup_install_properties (object_class, LAST_PROP);
}
static void
_gdk_macos_popup_surface_init (GdkMacosPopupSurface *self)
{
}
GdkMacosSurface *
_gdk_macos_popup_surface_new (GdkMacosDisplay *display,
GdkSurface *parent,
GdkFrameClock *frame_clock,
int x,
int y,
int width,
int height)
_gdk_macos_popup_surface_constructed (GObject *object)
{
GDK_BEGIN_MACOS_ALLOC_POOL;
GdkMacosWindow *window;
GdkMacosSurface *self;
GdkMacosPopupSurface *self = GDK_MACOS_POPUP_SURFACE (object);
GdkSurface *surface = GDK_SURFACE (self);
GdkMacosDisplay *display = GDK_MACOS_DISPLAY (gdk_surface_get_display (GDK_SURFACE (self)));
NSScreen *screen;
NSUInteger style_mask;
NSRect content_rect;
@@ -323,19 +299,15 @@ _gdk_macos_popup_surface_new (GdkMacosDisplay *display,
int nx;
int ny;
g_return_val_if_fail (GDK_IS_MACOS_DISPLAY (display), NULL);
g_return_val_if_fail (!frame_clock || GDK_IS_FRAME_CLOCK (frame_clock), NULL);
g_return_val_if_fail (!parent || GDK_IS_MACOS_SURFACE (parent), NULL);
style_mask = NSWindowStyleMaskBorderless;
_gdk_macos_display_to_display_coords (display, x, y, &nx, &ny);
_gdk_macos_display_to_display_coords (display, 0, 0, &nx, &ny);
screen = _gdk_macos_display_get_screen_at_display_coords (display, nx, ny);
screen_rect = [screen frame];
nx -= screen_rect.origin.x;
ny -= screen_rect.origin.y;
content_rect = NSMakeRect (nx, ny - height, width, height);
content_rect = NSMakeRect (nx, ny - 100, 100, 100);
window = [[GdkMacosWindow alloc] initWithContentRect:content_rect
styleMask:style_mask
@@ -349,16 +321,34 @@ _gdk_macos_popup_surface_new (GdkMacosDisplay *display,
[window setExcludedFromWindowsMenu:YES];
[window setLevel:NSPopUpMenuWindowLevel];
self = g_object_new (GDK_TYPE_MACOS_POPUP_SURFACE,
"display", display,
"frame-clock", frame_clock,
"native", window,
"parent", parent,
NULL);
_gdk_macos_surface_set_native (GDK_MACOS_SURFACE (self), window);
gdk_surface_set_frame_clock (surface, gdk_surface_get_frame_clock (surface->parent));
GDK_END_MACOS_ALLOC_POOL;
return g_steal_pointer (&self);
G_OBJECT_CLASS (_gdk_macos_popup_surface_parent_class)->constructed (object);
}
static void
_gdk_macos_popup_surface_class_init (GdkMacosPopupSurfaceClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GdkSurfaceClass *surface_class = GDK_SURFACE_CLASS (klass);
object_class->constructed = _gdk_macos_popup_surface_constructed;
object_class->finalize = _gdk_macos_popup_surface_finalize;
object_class->get_property = _gdk_macos_popup_surface_get_property;
object_class->set_property = _gdk_macos_popup_surface_set_property;
surface_class->hide = _gdk_macos_popup_surface_hide;
gdk_popup_install_properties (object_class, LAST_PROP);
}
static void
_gdk_macos_popup_surface_init (GdkMacosPopupSurface *self)
{
}
void
+2 -7
View File
@@ -84,14 +84,9 @@ struct _GdkMacosSurfaceClass
GdkSurfaceClass parent_class;
};
GdkMacosSurface *_gdk_macos_surface_new (GdkMacosDisplay *display,
GdkSurfaceType surface_type,
GdkSurface *parent,
int x,
int y,
int width,
int height);
NSWindow *_gdk_macos_surface_get_native (GdkMacosSurface *self);
void _gdk_macos_surface_set_native (GdkMacosSurface *self,
GdkMacosWindow *window);
CGDirectDisplayID _gdk_macos_surface_get_screen_id (GdkMacosSurface *self);
const char *_gdk_macos_surface_get_title (GdkMacosSurface *self);
void _gdk_macos_surface_set_title (GdkMacosSurface *self,
+20 -83
View File
@@ -31,7 +31,7 @@
#include "gdkdeviceprivate.h"
#include "gdkdisplay.h"
#include "gdkeventsprivate.h"
#include "gdkframeclockidleprivate.h"
#include "gdkframeclockprivate.h"
#include "gdkseatprivate.h"
#include "gdksurfaceprivate.h"
@@ -43,8 +43,8 @@
#include "gdkmacosglcontext-private.h"
#include "gdkmacosmonitor-private.h"
#include "gdkmacospopupsurface-private.h"
#include "gdkmacostoplevelsurface-private.h"
#include "gdkmacosutils-private.h"
#include "gdkmacostoplevelsurface-private.h"
G_DEFINE_ABSTRACT_TYPE (GdkMacosSurface, gdk_macos_surface, GDK_TYPE_SURFACE)
@@ -416,10 +416,6 @@ gdk_macos_surface_drag_begin (GdkSurface *surface,
GdkMacosSurface *drag_surface;
GdkMacosDrag *drag;
GdkCursor *cursor;
double px;
double py;
int sx;
int sy;
g_assert (GDK_IS_MACOS_SURFACE (self));
g_assert (GDK_IS_MACOS_TOPLEVEL_SURFACE (self) ||
@@ -427,12 +423,7 @@ gdk_macos_surface_drag_begin (GdkSurface *surface,
g_assert (GDK_IS_MACOS_DEVICE (device));
g_assert (GDK_IS_CONTENT_PROVIDER (content));
gdk_macos_device_query_state (device, surface, NULL, &px, &py, NULL);
_gdk_macos_surface_get_root_coords (GDK_MACOS_SURFACE (surface), &sx, &sy);
drag_surface = _gdk_macos_surface_new (GDK_MACOS_DISPLAY (surface->display),
GDK_SURFACE_DRAG,
NULL,
sx, sy, 1, 1);
drag_surface = _gdk_macos_drag_surface_new (GDK_MACOS_DISPLAY (surface->display));
drag = g_object_new (GDK_TYPE_MACOS_DRAG,
"drag-surface", drag_surface,
"surface", surface,
@@ -527,8 +518,14 @@ gdk_macos_surface_constructed (GObject *object)
G_CONNECT_SWAPPED);
}
gdk_surface_freeze_updates (GDK_SURFACE (self));
_gdk_macos_surface_monitor_changed (self);
if (self->window != NULL)
_gdk_macos_surface_configure (self);
_gdk_macos_display_surface_added (GDK_MACOS_DISPLAY (gdk_surface_get_display (GDK_SURFACE (self))),
self);
}
static void
@@ -550,26 +547,6 @@ gdk_macos_surface_get_property (GObject *object,
}
}
static void
gdk_macos_surface_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
GdkMacosSurface *self = GDK_MACOS_SURFACE (object);
switch (prop_id)
{
case PROP_NATIVE:
self->window = g_value_get_pointer (value);
[self->window setGdkSurface:self];
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
gdk_macos_surface_class_init (GdkMacosSurfaceClass *klass)
{
@@ -578,7 +555,6 @@ gdk_macos_surface_class_init (GdkMacosSurfaceClass *klass)
object_class->constructed = gdk_macos_surface_constructed;
object_class->get_property = gdk_macos_surface_get_property;
object_class->set_property = gdk_macos_surface_set_property;
surface_class->destroy = gdk_macos_surface_destroy;
surface_class->drag_begin = gdk_macos_surface_drag_begin;
@@ -597,7 +573,7 @@ gdk_macos_surface_class_init (GdkMacosSurfaceClass *klass)
*/
properties [PROP_NATIVE] =
g_param_spec_pointer ("native", NULL, NULL,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (object_class, LAST_PROP, properties);
}
@@ -611,55 +587,6 @@ gdk_macos_surface_init (GdkMacosSurface *self)
self->monitors = g_ptr_array_new_with_free_func (g_object_unref);
}
GdkMacosSurface *
_gdk_macos_surface_new (GdkMacosDisplay *display,
GdkSurfaceType surface_type,
GdkSurface *parent,
int x,
int y,
int width,
int height)
{
GdkFrameClock *frame_clock;
GdkMacosSurface *ret;
g_return_val_if_fail (GDK_IS_MACOS_DISPLAY (display), NULL);
if (parent != NULL)
frame_clock = g_object_ref (parent->frame_clock);
else
frame_clock = _gdk_frame_clock_idle_new ();
switch (surface_type)
{
case GDK_SURFACE_TOPLEVEL:
ret = _gdk_macos_toplevel_surface_new (display, parent, frame_clock, x, y, width, height);
break;
case GDK_SURFACE_POPUP:
ret = _gdk_macos_popup_surface_new (display, parent, frame_clock, x, y, width, height);
break;
case GDK_SURFACE_DRAG:
ret = _gdk_macos_drag_surface_new (display, frame_clock, x, y, width, height);
break;
default:
g_warn_if_reached ();
ret = NULL;
}
if (ret != NULL)
{
gdk_surface_freeze_updates (GDK_SURFACE (ret));
_gdk_macos_surface_monitor_changed (ret);
}
g_object_unref (frame_clock);
return g_steal_pointer (&ret);
}
void
_gdk_macos_surface_get_shadow (GdkMacosSurface *self,
int *top,
@@ -755,6 +682,16 @@ _gdk_macos_surface_get_native (GdkMacosSurface *self)
return (NSWindow *)self->window;
}
void
_gdk_macos_surface_set_native (GdkMacosSurface *self,
GdkMacosWindow *window)
{
g_assert (self->window == NULL);
self->window = window;
[self->window setGdkSurface:self];
}
/**
* gdk_macos_surface_get_native_window: (attributes org.gtk.Method.get_property=native)
* @self: a #GdkMacosSurface
@@ -45,13 +45,6 @@ struct _GdkMacosToplevelSurfaceClass
};
GType _gdk_macos_toplevel_surface_get_type (void);
GdkMacosSurface *_gdk_macos_toplevel_surface_new (GdkMacosDisplay *display,
GdkSurface *parent,
GdkFrameClock *frame_clock,
int x,
int y,
int width,
int height);
void _gdk_macos_toplevel_surface_attach_to_parent (GdkMacosToplevelSurface *self);
void _gdk_macos_toplevel_surface_detach_from_parent (GdkMacosToplevelSurface *self);
+49 -60
View File
@@ -23,6 +23,7 @@
#include "gdkmacostoplevelsurface-private.h"
#include "gdkframeclockidleprivate.h"
#include "gdkseatprivate.h"
#include "gdktoplevelprivate.h"
@@ -625,12 +626,60 @@ _gdk_macos_toplevel_surface_set_property (GObject *object,
}
}
static void
_gdk_macos_toplevel_surface_constructed (GObject *object)
{
GDK_BEGIN_MACOS_ALLOC_POOL;
GdkMacosWindow *window;
GdkMacosToplevelSurface *self = GDK_MACOS_TOPLEVEL_SURFACE (object);
GdkSurface *surface = GDK_SURFACE (self);
GdkMacosDisplay *display = GDK_MACOS_DISPLAY (gdk_surface_get_display (surface));
GdkFrameClock *frame_clock;
NSUInteger style_mask;
NSRect content_rect;
NSRect visible_frame;
NSScreen *screen;
int nx;
int ny;
style_mask = (NSWindowStyleMaskTitled |
NSWindowStyleMaskClosable |
NSWindowStyleMaskMiniaturizable |
NSWindowStyleMaskResizable);
_gdk_macos_display_to_display_coords (display, 0, 100, &nx, &ny);
screen = _gdk_macos_display_get_screen_at_display_coords (display, nx, ny);
visible_frame = [screen visibleFrame];
content_rect = NSMakeRect (nx - visible_frame.origin.x, ny - visible_frame.origin.y, 100, 100);
window = [[GdkMacosWindow alloc] initWithContentRect:content_rect
styleMask:style_mask
backing:NSBackingStoreBuffered
defer:NO
screen:screen];
/* Allow NSWindow to go fullscreen */
[window setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary];
_gdk_macos_surface_set_native (GDK_MACOS_SURFACE (self), window);
frame_clock = _gdk_frame_clock_idle_new ();
gdk_surface_set_frame_clock (surface, frame_clock);
g_object_unref (frame_clock);
GDK_END_MACOS_ALLOC_POOL;
G_OBJECT_CLASS (_gdk_macos_toplevel_surface_parent_class)->constructed (object);
}
static void
_gdk_macos_toplevel_surface_class_init (GdkMacosToplevelSurfaceClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GdkSurfaceClass *surface_class = GDK_SURFACE_CLASS (klass);
object_class->constructed = _gdk_macos_toplevel_surface_constructed;
object_class->get_property = _gdk_macos_toplevel_surface_get_property;
object_class->set_property = _gdk_macos_toplevel_surface_set_property;
@@ -648,66 +697,6 @@ _gdk_macos_toplevel_surface_init (GdkMacosToplevelSurface *self)
self->decorated = TRUE;
}
GdkMacosSurface *
_gdk_macos_toplevel_surface_new (GdkMacosDisplay *display,
GdkSurface *parent,
GdkFrameClock *frame_clock,
int x,
int y,
int width,
int height)
{
GDK_BEGIN_MACOS_ALLOC_POOL;
GdkMacosWindow *window;
GdkMacosSurface *self;
NSUInteger style_mask;
NSRect content_rect;
NSRect visible_frame;
NSScreen *screen;
int nx;
int ny;
g_return_val_if_fail (GDK_IS_MACOS_DISPLAY (display), NULL);
g_return_val_if_fail (!frame_clock || GDK_IS_FRAME_CLOCK (frame_clock), NULL);
g_return_val_if_fail (!parent || GDK_IS_MACOS_SURFACE (parent), NULL);
style_mask = (NSWindowStyleMaskTitled |
NSWindowStyleMaskClosable |
NSWindowStyleMaskMiniaturizable |
NSWindowStyleMaskResizable);
if (parent != NULL)
{
x += GDK_MACOS_SURFACE (parent)->root_x;
y += GDK_MACOS_SURFACE (parent)->root_y;
}
_gdk_macos_display_to_display_coords (display, x, y + height, &nx, &ny);
screen = _gdk_macos_display_get_screen_at_display_coords (display, nx, ny);
visible_frame = [screen visibleFrame];
content_rect = NSMakeRect (nx - visible_frame.origin.x, ny - visible_frame.origin.y, width, height);
window = [[GdkMacosWindow alloc] initWithContentRect:content_rect
styleMask:style_mask
backing:NSBackingStoreBuffered
defer:NO
screen:screen];
/* Allow NSWindow to go fullscreen */
[window setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary];
self = g_object_new (GDK_TYPE_MACOS_TOPLEVEL_SURFACE,
"display", display,
"frame-clock", frame_clock,
"native", window,
NULL);
GDK_END_MACOS_ALLOC_POOL;
return g_steal_pointer (&self);
}
void
_gdk_macos_toplevel_surface_attach_to_parent (GdkMacosToplevelSurface *self)
{
+2
View File
@@ -29,6 +29,7 @@ gdk_public_sources = files([
'gdkglcontext.c',
'gdkglobals.c',
'gdkgltexture.c',
'gdkgltexturebuilder.c',
'gdkhsla.c',
'gdkkeys.c',
'gdkkeyuni.c',
@@ -86,6 +87,7 @@ gdk_public_headers = files([
'gdkframetimings.h',
'gdkglcontext.h',
'gdkgltexture.h',
'gdkgltexturebuilder.h',
'gdkkeys.h',
'gdkkeysyms.h',
'gdkmemorytexture.h',
+2 -1
View File
@@ -967,6 +967,8 @@ gdk_wayland_display_class_init (GdkWaylandDisplayClass *class)
object_class->dispose = gdk_wayland_display_dispose;
object_class->finalize = gdk_wayland_display_finalize;
display_class->toplevel_type = GDK_TYPE_WAYLAND_TOPLEVEL;
display_class->popup_type = GDK_TYPE_WAYLAND_POPUP;
display_class->cairo_context_type = GDK_TYPE_WAYLAND_CAIRO_CONTEXT;
#ifdef GDK_RENDERING_VULKAN
@@ -987,7 +989,6 @@ G_GNUC_BEGIN_IGNORE_DEPRECATIONS
display_class->get_startup_notification_id = gdk_wayland_display_get_startup_notification_id;
G_GNUC_END_IGNORE_DEPRECATIONS
display_class->notify_startup_complete = gdk_wayland_display_notify_startup_complete;
display_class->create_surface = _gdk_wayland_display_create_surface;
display_class->get_keymap = _gdk_wayland_display_get_keymap;
display_class->init_gl = gdk_wayland_display_init_gl;
+5 -4
View File
@@ -24,6 +24,7 @@
#include "gdkdisplay-wayland.h"
#include <glib/gi18n-lib.h>
#include "gdkseat-wayland.h"
#include "gdksurface-wayland-private.h"
#include "gdkdeviceprivate.h"
@@ -46,7 +47,6 @@ struct _GdkWaylandDrag
{
GdkDrag drag;
GdkSurface *dnd_surface;
struct wl_surface *dnd_wl_surface;
struct wl_data_source *data_source;
struct wl_data_offer *offer;
uint32_t serial;
@@ -382,8 +382,9 @@ _gdk_wayland_surface_drag_begin (GdkSurface *surface,
drag = GDK_DRAG (drag_wayland);
drag_wayland->dnd_surface = _gdk_wayland_display_create_surface (display, GDK_SURFACE_DRAG, NULL, 0, 0, 100, 100);
drag_wayland->dnd_wl_surface = gdk_wayland_surface_get_wl_surface (drag_wayland->dnd_surface);
drag_wayland->dnd_surface = g_object_new (GDK_TYPE_WAYLAND_DRAG_SURFACE,
"display", display,
NULL);
gdk_wayland_drag_create_data_source (drag);
@@ -395,7 +396,7 @@ _gdk_wayland_surface_drag_begin (GdkSurface *surface,
wl_data_device_start_drag (gdk_wayland_device_get_data_device (device),
drag_wayland->data_source,
gdk_wayland_surface_get_wl_surface (surface),
drag_wayland->dnd_wl_surface,
gdk_wayland_surface_get_wl_surface (drag_wayland->dnd_surface),
_gdk_wayland_seat_get_implicit_grab_serial (seat, NULL));
cursor = gdk_drag_get_cursor (drag, gdk_drag_get_selected_action (drag));
+16 -3
View File
@@ -101,11 +101,27 @@ gdk_wayland_drag_surface_compute_size (GdkSurface *surface)
return FALSE;
}
static void
gdk_wayland_drag_surface_constructed (GObject *object)
{
GdkSurface *surface = GDK_SURFACE (object);
GdkFrameClock *frame_clock;
frame_clock = _gdk_frame_clock_idle_new ();
gdk_surface_set_frame_clock (surface, frame_clock);
g_object_unref (frame_clock);
G_OBJECT_CLASS (gdk_wayland_drag_surface_parent_class)->constructed (object);
}
static void
gdk_wayland_drag_surface_class_init (GdkWaylandDragSurfaceClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
GdkSurfaceClass *surface_class = GDK_SURFACE_CLASS (class);
object_class->constructed = gdk_wayland_drag_surface_constructed;
surface_class->compute_size = gdk_wayland_drag_surface_compute_size;
}
@@ -127,9 +143,6 @@ gdk_wayland_drag_surface_present (GdkDragSurface *drag_surface,
GdkSurface *surface = GDK_SURFACE (drag_surface);
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
if (!impl->display_server.wl_surface)
gdk_wayland_surface_create_wl_surface (surface);
impl->next_layout.configured_width = width;
impl->next_layout.configured_height = height;
impl->next_layout.surface_geometry_dirty = TRUE;
+3
View File
@@ -75,6 +75,9 @@ gdk_wayland_gl_context_end_frame (GdkDrawContext *draw_context,
WL_SURFACE_OFFSET_SINCE_VERSION)
wl_surface_offset (impl->display_server.wl_surface, dx, dy);
/* We should do ths when setting up the EGLSurface, but we don't make_current then */
eglSwapInterval (gdk_display_get_egl_display (gdk_draw_context_get_display (draw_context)), 0);
GDK_DRAW_CONTEXT_CLASS (gdk_wayland_gl_context_parent_class)->end_frame (draw_context, painted);
gdk_wayland_surface_notify_committed (surface);
+12 -5
View File
@@ -1040,6 +1040,17 @@ gdk_wayland_popup_init (GdkWaylandPopup *popup)
{
}
static void
gdk_wayland_popup_constructed (GObject *object)
{
GdkWaylandPopup *self = GDK_WAYLAND_POPUP (object);
GdkSurface *surface = GDK_SURFACE (self);
gdk_surface_set_frame_clock (surface, gdk_surface_get_frame_clock (gdk_popup_get_parent (GDK_POPUP (self))));
G_OBJECT_CLASS (gdk_wayland_popup_parent_class)->constructed (object);
}
static void
gdk_wayland_popup_get_property (GObject *object,
guint prop_id,
@@ -1097,6 +1108,7 @@ gdk_wayland_popup_class_init (GdkWaylandPopupClass *class)
GdkSurfaceClass *surface_class = GDK_SURFACE_CLASS (class);
GdkWaylandSurfaceClass *wayland_surface_class = GDK_WAYLAND_SURFACE_CLASS (class);
object_class->constructed = gdk_wayland_popup_constructed;
object_class->get_property = gdk_wayland_popup_get_property;
object_class->set_property = gdk_wayland_popup_set_property;
@@ -1289,11 +1301,6 @@ show_popup (GdkWaylandPopup *wayland_popup,
int height,
GdkPopupLayout *layout)
{
GdkWaylandSurface *wayland_surface = GDK_WAYLAND_SURFACE (wayland_popup);
if (!wayland_surface->display_server.wl_surface)
gdk_wayland_surface_create_wl_surface (GDK_SURFACE (wayland_popup));
if (wayland_popup->thaw_upon_show)
{
wayland_popup->thaw_upon_show = FALSE;
+11 -4
View File
@@ -99,7 +99,7 @@ gdk_wayland_primary_claim_remote (GdkWaylandPrimary *cb,
if (cb->source)
{
GDK_DISPLAY_DEBUG (gdk_clipboard_get_display (GDK_CLIPBOARD (cb)), CLIPBOARD, "%p: Ignoring clipboard offer for self", cb);
GDK_DISPLAY_DEBUG (gdk_clipboard_get_display (GDK_CLIPBOARD (cb)), CLIPBOARD, "%p: Ignoring primary offer for self", cb);
gdk_content_formats_unref (formats);
g_clear_pointer (&offer, zwp_primary_selection_offer_v1_destroy);
return;
@@ -111,7 +111,7 @@ gdk_wayland_primary_claim_remote (GdkWaylandPrimary *cb,
if (GDK_DISPLAY_DEBUG_CHECK (gdk_clipboard_get_display (GDK_CLIPBOARD (cb)), CLIPBOARD))
{
char *s = gdk_content_formats_to_string (formats);
gdk_debug_message ("%p: remote clipboard claim for %s", cb, s);
gdk_debug_message ("%p: remote primary claim for %s", cb, s);
g_free (s);
}
#endif
@@ -119,8 +119,7 @@ gdk_wayland_primary_claim_remote (GdkWaylandPrimary *cb,
cb->offer_formats = formats;
cb->offer = offer;
gdk_clipboard_claim_remote (GDK_CLIPBOARD (cb),
cb->offer_formats);
gdk_clipboard_claim_remote (GDK_CLIPBOARD (cb), cb->offer_formats);
}
static void
@@ -271,6 +270,14 @@ gdk_wayland_primary_claim (GdkClipboard *clipboard,
{
GdkWaylandPrimary *cb = GDK_WAYLAND_PRIMARY (clipboard);
#ifdef G_ENABLE_DEBUG
if (GDK_DISPLAY_DEBUG_CHECK (gdk_clipboard_get_display (clipboard), CLIPBOARD))
{
char *s = gdk_content_formats_to_string (formats);
gdk_debug_message ("%p: claim primary (%s) for %s", cb, local ? "local" : "remote", s);
g_free (s);
}
#endif
if (local)
{
GdkWaylandDisplay *wdisplay = GDK_WAYLAND_DISPLAY (gdk_clipboard_get_display (clipboard));
-8
View File
@@ -157,14 +157,6 @@ void gdk_wayland_drop_set_source_actions (GdkDrop
void gdk_wayland_drop_set_action (GdkDrop *drop,
uint32_t action);
GdkSurface * _gdk_wayland_display_create_surface (GdkDisplay *display,
GdkSurfaceType surface_type,
GdkSurface *parent,
int x,
int y,
int width,
int height);
void _gdk_wayland_display_create_seat (GdkWaylandDisplay *display,
guint32 id,
struct wl_seat *seat);
+1 -2
View File
@@ -42,11 +42,11 @@ struct _GdkWaylandSurface
} display_server;
struct wl_event_queue *event_queue;
struct wl_callback *frame_callback;
unsigned int initial_configure_received : 1;
unsigned int has_uncommitted_ack_configure : 1;
unsigned int mapped : 1;
unsigned int awaiting_frame : 1;
unsigned int awaiting_frame_frozen : 1;
int pending_buffer_offset_x;
@@ -104,7 +104,6 @@ struct _GdkWaylandSurfaceClass
#define GDK_WAYLAND_SURFACE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_WAYLAND_SURFACE, GdkWaylandSurfaceClass))
void gdk_wayland_surface_create_wl_surface (GdkSurface *surface);
void gdk_wayland_surface_update_size (GdkSurface *surface,
int32_t width,
int32_t height,
+123 -239
View File
@@ -28,6 +28,7 @@
#include "gdkmonitor-wayland.h"
#include "gdkpopupprivate.h"
#include "gdkprivate-wayland.h"
#include "gdkrectangleprivate.h"
#include "gdkseat-wayland.h"
#include "gdksurfaceprivate.h"
#include "gdktoplevelprivate.h"
@@ -107,20 +108,6 @@ fill_presentation_time_from_frame_time (GdkFrameTimings *timings,
}
}
static const char *
get_default_title (void)
{
const char *title;
title = g_get_application_name ();
if (!title)
title = g_get_prgname ();
if (!title)
title = "";
return title;
}
static gboolean
is_realized_shell_surface (GdkWaylandSurface *impl)
{
@@ -198,38 +185,6 @@ gdk_wayland_surface_thaw_state (GdkSurface *surface)
gdk_wayland_surface_configure (surface);
}
static void
gdk_wayland_surface_maybe_resize (GdkSurface *surface,
int width,
int height,
const GdkFractionalScale *scale)
{
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
gboolean hide_temporarily;
if (surface->width == width &&
surface->height == height &&
gdk_fractional_scale_equal (&impl->scale, scale))
return;
/* For xdg_popup using an xdg_positioner, there is a race condition if
* the application tries to change the size after it's mapped, but before
* the initial configure is received, so hide and show the surface again
* force the new size onto the compositor. See bug #772505.
*/
hide_temporarily = GDK_IS_WAYLAND_POPUP (surface) &&
gdk_surface_get_mapped (surface) &&
!impl->initial_configure_received;
if (hide_temporarily)
gdk_surface_hide (surface);
gdk_wayland_surface_update_size (surface, width, height, scale);
if (hide_temporarily)
gdk_wayland_surface_create_wl_surface (surface);
}
static inline void
get_egl_window_size (GdkSurface *surface,
int *width,
@@ -318,17 +273,13 @@ frame_callback (void *data,
gdk_profiler_add_mark (GDK_PROFILER_CURRENT_TIME, 0, "wayland", "frame event");
GDK_DISPLAY_DEBUG (GDK_DISPLAY (display_wayland), EVENTS, "frame %p", surface);
wl_callback_destroy (callback);
g_assert (impl->frame_callback == callback);
g_assert (!GDK_SURFACE_DESTROYED (surface));
if (GDK_SURFACE_DESTROYED (surface))
return;
if (!impl->awaiting_frame)
return;
g_clear_pointer (&impl->frame_callback, wl_callback_destroy);
GDK_WAYLAND_SURFACE_GET_CLASS (impl)->handle_frame (impl);
impl->awaiting_frame = FALSE;
if (impl->awaiting_frame_frozen)
{
impl->awaiting_frame_frozen = FALSE;
@@ -416,20 +367,17 @@ gdk_wayland_surface_request_layout (GdkSurface *surface)
void
gdk_wayland_surface_request_frame (GdkSurface *surface)
{
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
struct wl_callback *callback;
GdkWaylandSurface *self = GDK_WAYLAND_SURFACE (surface);
GdkFrameClock *clock;
if (impl->awaiting_frame)
return;
g_assert (self->frame_callback == NULL);
clock = gdk_surface_get_frame_clock (surface);
callback = wl_surface_frame (impl->display_server.wl_surface);
wl_proxy_set_queue ((struct wl_proxy *) callback, NULL);
wl_callback_add_listener (callback, &frame_listener, surface);
impl->pending_frame_counter = gdk_frame_clock_get_frame_counter (clock);
impl->awaiting_frame = TRUE;
self->frame_callback = wl_surface_frame (self->display_server.wl_surface);
wl_proxy_set_queue ((struct wl_proxy *) self->frame_callback, NULL);
wl_callback_add_listener (self->frame_callback, &frame_listener, surface);
self->pending_frame_counter = gdk_frame_clock_get_frame_counter (clock);
}
gboolean
@@ -468,9 +416,10 @@ on_frame_clock_after_paint (GdkFrameClock *clock,
gdk_wayland_surface_notify_committed (surface);
}
if (impl->awaiting_frame &&
if (impl->frame_callback &&
impl->pending_frame_counter == gdk_frame_clock_get_frame_counter (clock))
{
g_assert (!impl->awaiting_frame_frozen);
impl->awaiting_frame_frozen = TRUE;
gdk_surface_freeze_updates (surface);
}
@@ -508,105 +457,9 @@ gdk_wayland_surface_update_scale (GdkSurface *surface)
}
/* Notify app that scale changed */
gdk_wayland_surface_maybe_resize (surface,
surface->width, surface->height,
&GDK_FRACTIONAL_SCALE_INIT_INT (scale));
}
GdkSurface *
_gdk_wayland_display_create_surface (GdkDisplay *display,
GdkSurfaceType surface_type,
GdkSurface *parent,
int x,
int y,
int width,
int height)
{
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
GdkSurface *surface;
GdkFrameClock *frame_clock;
if (parent)
frame_clock = g_object_ref (gdk_surface_get_frame_clock (parent));
else
frame_clock = _gdk_frame_clock_idle_new ();
switch (surface_type)
{
case GDK_SURFACE_TOPLEVEL:
g_warn_if_fail (parent == NULL);
surface = g_object_new (GDK_TYPE_WAYLAND_TOPLEVEL,
"display", display,
"frame-clock", frame_clock,
"title", get_default_title (),
NULL);
display_wayland->toplevels = g_list_prepend (display_wayland->toplevels, surface);
break;
case GDK_SURFACE_POPUP:
g_warn_if_fail (parent != NULL);
surface = g_object_new (GDK_TYPE_WAYLAND_POPUP,
"parent", parent,
"display", display,
"frame-clock", frame_clock,
NULL);
break;
case GDK_SURFACE_DRAG:
g_warn_if_fail (parent == NULL);
surface = g_object_new (GDK_TYPE_WAYLAND_DRAG_SURFACE,
"display", display,
"frame-clock", frame_clock,
NULL);
break;
default:
g_assert_not_reached ();
break;
}
if (width > 65535)
{
g_warning ("Native Surfaces wider than 65535 pixels are not supported");
width = 65535;
}
if (height > 65535)
{
g_warning ("Native Surfaces taller than 65535 pixels are not supported");
height = 65535;
}
surface->x = x;
surface->y = y;
surface->width = width;
surface->height = height;
g_object_ref (surface);
/* More likely to be right than just assuming 1 */
if (wl_compositor_get_version (display_wayland->compositor) >= WL_SURFACE_SET_BUFFER_SCALE_SINCE_VERSION)
{
GdkMonitor *monitor = g_list_model_get_item (gdk_display_get_monitors (display), 0);
if (monitor)
{
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
guint32 monitor_scale = gdk_monitor_get_scale_factor (monitor);
if (monitor_scale != 1)
{
impl->scale = GDK_FRACTIONAL_SCALE_INIT_INT (monitor_scale);
impl->buffer_scale_dirty = TRUE;
}
g_object_unref (monitor);
}
}
gdk_wayland_surface_create_wl_surface (surface);
g_signal_connect (frame_clock, "before-paint", G_CALLBACK (on_frame_clock_before_paint), surface);
g_signal_connect (frame_clock, "after-paint", G_CALLBACK (on_frame_clock_after_paint), surface);
g_object_unref (frame_clock);
return surface;
gdk_wayland_surface_update_size (surface,
surface->width, surface->height,
&GDK_FRACTIONAL_SCALE_INIT_INT (scale));
}
void
@@ -616,6 +469,7 @@ gdk_wayland_surface_attach_image (GdkSurface *surface,
{
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
cairo_rectangle_int_t rect;
uint32_t wl_surface_version;
int i, n;
if (GDK_SURFACE_DESTROYED (surface))
@@ -623,14 +477,15 @@ gdk_wayland_surface_attach_image (GdkSurface *surface,
g_assert (_gdk_wayland_is_shm_surface (cairo_surface));
wl_surface_version = wl_surface_get_version (impl->display_server.wl_surface);
/* Attach this new buffer to the surface */
wl_surface_attach (impl->display_server.wl_surface,
_gdk_wayland_shm_surface_get_wl_buffer (cairo_surface),
0, 0);
if ((impl->pending_buffer_offset_x || impl->pending_buffer_offset_y) &&
wl_surface_get_version (impl->display_server.wl_surface) >=
WL_SURFACE_OFFSET_SINCE_VERSION)
wl_surface_version >= WL_SURFACE_OFFSET_SINCE_VERSION)
wl_surface_offset (impl->display_server.wl_surface,
impl->pending_buffer_offset_x,
impl->pending_buffer_offset_y);
@@ -641,7 +496,16 @@ gdk_wayland_surface_attach_image (GdkSurface *surface,
for (i = 0; i < n; i++)
{
cairo_region_get_rectangle (damage, i, &rect);
wl_surface_damage (impl->display_server.wl_surface, rect.x, rect.y, rect.width, rect.height);
if (wl_surface_version >= WL_SURFACE_DAMAGE_BUFFER_SINCE_VERSION)
{
float scale = gdk_surface_get_scale (surface);
gdk_rectangle_transform_affine (&rect, scale, scale, 0, 0, &rect);
wl_surface_damage_buffer (impl->display_server.wl_surface, rect.x, rect.y, rect.width, rect.height);
}
else
{
wl_surface_damage (impl->display_server.wl_surface, rect.x, rect.y, rect.width, rect.height);
}
}
}
@@ -653,21 +517,6 @@ gdk_wayland_surface_beep (GdkSurface *surface)
return TRUE;
}
static void
gdk_wayland_surface_constructed (GObject *object)
{
GdkSurface *surface = GDK_SURFACE (object);
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
GdkWaylandDisplay *display_wayland =
GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface));
G_OBJECT_CLASS (gdk_wayland_surface_parent_class)->constructed (object);
impl->event_queue = wl_display_create_queue (display_wayland->wl_display);
display_wayland->event_queues = g_list_prepend (display_wayland->event_queues,
impl->event_queue);
}
static void
gdk_wayland_surface_dispose (GObject *object)
{
@@ -684,7 +533,7 @@ gdk_wayland_surface_dispose (GObject *object)
GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface));
display_wayland->event_queues =
g_list_remove (display_wayland->event_queues, surface);
g_list_remove (display_wayland->event_queues, impl->event_queue);
g_clear_pointer (&impl->event_queue, wl_event_queue_destroy);
}
@@ -858,9 +707,9 @@ gdk_wayland_surface_fractional_scale_preferred_scale_cb (void *data,
GdkSurface *surface = GDK_SURFACE (self);
/* Notify app that scale changed */
gdk_wayland_surface_maybe_resize (surface,
surface->width, surface->height,
&GDK_FRACTIONAL_SCALE_INIT (scale));
gdk_wayland_surface_update_size (surface,
surface->width, surface->height,
&GDK_FRACTIONAL_SCALE_INIT (scale));
}
static const struct wp_fractional_scale_v1_listener fractional_scale_listener = {
@@ -915,7 +764,7 @@ static const struct wl_surface_listener surface_listener = {
surface_leave
};
void
static void
gdk_wayland_surface_create_wl_surface (GdkSurface *surface)
{
GdkWaylandSurface *self = GDK_WAYLAND_SURFACE (surface);
@@ -942,6 +791,62 @@ gdk_wayland_surface_create_wl_surface (GdkSurface *surface)
self->display_server.wl_surface = wl_surface;
}
static void
gdk_wayland_surface_constructed (GObject *object)
{
GdkSurface *surface = GDK_SURFACE (object);
GdkWaylandSurface *self = GDK_WAYLAND_SURFACE (surface);
GdkDisplay *display = gdk_surface_get_display (surface);
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
GdkFrameClock *frame_clock = gdk_surface_get_frame_clock (surface);
self->event_queue = wl_display_create_queue (display_wayland->wl_display);
display_wayland->event_queues = g_list_prepend (display_wayland->event_queues,
self->event_queue);
/* More likely to be right than just assuming 1 */
if (wl_compositor_get_version (display_wayland->compositor) >= WL_SURFACE_SET_BUFFER_SCALE_SINCE_VERSION)
{
GdkMonitor *monitor = g_list_model_get_item (gdk_display_get_monitors (display), 0);
if (monitor)
{
guint32 monitor_scale = gdk_monitor_get_scale_factor (monitor);
if (monitor_scale != 1)
{
self->scale = GDK_FRACTIONAL_SCALE_INIT_INT (monitor_scale);
self->buffer_scale_dirty = TRUE;
}
g_object_unref (monitor);
}
}
gdk_wayland_surface_create_wl_surface (surface);
g_signal_connect (frame_clock, "before-paint", G_CALLBACK (on_frame_clock_before_paint), surface);
g_signal_connect (frame_clock, "after-paint", G_CALLBACK (on_frame_clock_after_paint), surface);
G_OBJECT_CLASS (gdk_wayland_surface_parent_class)->constructed (object);
}
static void
gdk_wayland_surface_destroy_wl_surface (GdkWaylandSurface *self)
{
if (self->display_server.egl_window)
{
gdk_surface_set_egl_native_window (GDK_SURFACE (self), NULL);
g_clear_pointer (&self->display_server.egl_window, wl_egl_window_destroy);
}
g_clear_pointer (&self->display_server.viewport, wp_viewport_destroy);
g_clear_pointer (&self->display_server.fractional_scale, wp_fractional_scale_v1_destroy);
g_clear_pointer (&self->display_server.wl_surface, wl_surface_destroy);
g_clear_pointer (&self->display_server.outputs, g_slist_free);
}
static void
maybe_notify_mapped (GdkSurface *surface)
{
@@ -1069,59 +974,42 @@ gdk_wayland_surface_hide_surface (GdkSurface *surface)
{
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
if (!impl->mapped)
return;
unmap_popups_for_surface (surface);
if (impl->display_server.wl_surface)
g_clear_pointer (&impl->frame_callback, wl_callback_destroy);
if (impl->awaiting_frame_frozen)
{
if (impl->display_server.egl_window)
{
gdk_surface_set_egl_native_window (surface, NULL);
wl_egl_window_destroy (impl->display_server.egl_window);
impl->display_server.egl_window = NULL;
}
impl->awaiting_frame = FALSE;
if (impl->awaiting_frame_frozen)
{
impl->awaiting_frame_frozen = FALSE;
gdk_surface_thaw_updates (surface);
}
GDK_WAYLAND_SURFACE_GET_CLASS (impl)->hide_surface (impl);
if (impl->display_server.xdg_surface)
{
xdg_surface_destroy (impl->display_server.xdg_surface);
impl->display_server.xdg_surface = NULL;
if (!impl->initial_configure_received)
gdk_surface_thaw_updates (surface);
else
impl->initial_configure_received = FALSE;
}
if (impl->display_server.zxdg_surface_v6)
{
g_clear_pointer (&impl->display_server.zxdg_surface_v6, zxdg_surface_v6_destroy);
if (!impl->initial_configure_received)
gdk_surface_thaw_updates (surface);
else
impl->initial_configure_received = FALSE;
}
g_clear_pointer (&impl->display_server.fractional_scale, wp_fractional_scale_v1_destroy);
g_clear_pointer (&impl->display_server.viewport, wp_viewport_destroy);
g_clear_pointer (&impl->display_server.wl_surface, wl_surface_destroy);
g_slist_free (impl->display_server.outputs);
impl->display_server.outputs = NULL;
impl->awaiting_frame_frozen = FALSE;
gdk_surface_thaw_updates (surface);
}
GDK_WAYLAND_SURFACE_GET_CLASS (impl)->hide_surface (impl);
if (impl->display_server.xdg_surface)
{
xdg_surface_destroy (impl->display_server.xdg_surface);
impl->display_server.xdg_surface = NULL;
if (!impl->initial_configure_received)
gdk_surface_thaw_updates (surface);
else
impl->initial_configure_received = FALSE;
}
if (impl->display_server.zxdg_surface_v6)
{
g_clear_pointer (&impl->display_server.zxdg_surface_v6, zxdg_surface_v6_destroy);
if (!impl->initial_configure_received)
gdk_surface_thaw_updates (surface);
else
impl->initial_configure_received = FALSE;
}
wl_surface_attach (impl->display_server.wl_surface, NULL, 0, 0);
wl_surface_commit (impl->display_server.wl_surface);
impl->has_uncommitted_ack_configure = FALSE;
impl->input_region_dirty = TRUE;
impl->opaque_region_dirty = TRUE;
impl->viewport_dirty = TRUE;
if (!gdk_fractional_scale_equal (&impl->scale, &GDK_FRACTIONAL_SCALE_INIT_INT (1)))
impl->buffer_scale_dirty = TRUE;
impl->last_sent_window_geometry = (GdkRectangle) { 0 };
impl->mapped = FALSE;
@@ -1155,7 +1043,7 @@ gdk_wayland_surface_move_resize (GdkSurface *surface,
surface->x = x;
surface->y = y;
gdk_wayland_surface_maybe_resize (surface, width, height, &impl->scale);
gdk_wayland_surface_update_size (surface, width, height, &impl->scale);
}
static void
@@ -1250,11 +1138,8 @@ static void
gdk_wayland_surface_destroy (GdkSurface *surface,
gboolean foreign_destroy)
{
GdkWaylandDisplay *display;
GdkFrameClock *frame_clock;
g_return_if_fail (GDK_IS_SURFACE (surface));
/* Wayland surfaces can't be externally destroyed; we may possibly
* eventually want to use this path at display close-down
*/
@@ -1262,12 +1147,11 @@ gdk_wayland_surface_destroy (GdkSurface *surface,
gdk_wayland_surface_hide_surface (surface);
gdk_wayland_surface_destroy_wl_surface (GDK_WAYLAND_SURFACE(surface));
frame_clock = gdk_surface_get_frame_clock (surface);
g_signal_handlers_disconnect_by_func (frame_clock, on_frame_clock_before_paint, surface);
g_signal_handlers_disconnect_by_func (frame_clock, on_frame_clock_after_paint, surface);
display = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface));
display->toplevels = g_list_remove (display->toplevels, surface);
}
static void
+46 -17
View File
@@ -823,6 +823,20 @@ gdk_wayland_surface_create_xdg_toplevel (GdkWaylandToplevel *wayland_toplevel)
wl_surface_commit (wayland_surface->display_server.wl_surface);
}
static const char *
get_default_title (void)
{
const char *title;
title = g_get_application_name ();
if (!title)
title = g_get_prgname ();
if (!title)
title = "";
return title;
}
static void
gdk_wayland_toplevel_init (GdkWaylandToplevel *toplevel)
{
@@ -830,6 +844,8 @@ gdk_wayland_toplevel_init (GdkWaylandToplevel *toplevel)
toplevel->shortcuts_inhibitors = g_hash_table_new (NULL, NULL);
toplevel->saved_width = -1;
toplevel->saved_height = -1;
toplevel->title = g_strdup (get_default_title ());
}
static void
@@ -1259,28 +1275,43 @@ gdk_wayland_toplevel_get_property (GObject *object,
static void
gdk_wayland_toplevel_finalize (GObject *object)
{
GdkWaylandToplevel *wayland_toplevel;
GdkWaylandToplevel *self = GDK_WAYLAND_TOPLEVEL (object);
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (GDK_SURFACE (object)));
g_return_if_fail (GDK_IS_WAYLAND_TOPLEVEL (object));
display_wayland->toplevels = g_list_remove (display_wayland->toplevels, self);
wayland_toplevel = GDK_WAYLAND_TOPLEVEL (object);
if (gdk_wayland_toplevel_is_exported (self))
gdk_wayland_toplevel_unexport_handle (GDK_TOPLEVEL (self));
if (gdk_wayland_toplevel_is_exported (wayland_toplevel))
gdk_wayland_toplevel_unexport_handle (GDK_TOPLEVEL (wayland_toplevel));
g_free (self->application.application_id);
g_free (self->application.app_menu_path);
g_free (self->application.menubar_path);
g_free (self->application.window_object_path);
g_free (self->application.application_object_path);
g_free (self->application.unique_bus_name);
g_free (wayland_toplevel->application.application_id);
g_free (wayland_toplevel->application.app_menu_path);
g_free (wayland_toplevel->application.menubar_path);
g_free (wayland_toplevel->application.window_object_path);
g_free (wayland_toplevel->application.application_object_path);
g_free (wayland_toplevel->application.unique_bus_name);
g_free (wayland_toplevel->title);
g_clear_pointer (&wayland_toplevel->shortcuts_inhibitors, g_hash_table_unref);
g_free (self->title);
g_clear_pointer (&self->shortcuts_inhibitors, g_hash_table_unref);
G_OBJECT_CLASS (gdk_wayland_toplevel_parent_class)->finalize (object);
}
static void
gdk_wayland_toplevel_constructed (GObject *object)
{
GdkSurface *surface = GDK_SURFACE (object);
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface));
GdkFrameClock *frame_clock;
frame_clock = _gdk_frame_clock_idle_new ();
gdk_surface_set_frame_clock (surface, frame_clock);
g_object_unref (frame_clock);
display_wayland->toplevels = g_list_prepend (display_wayland->toplevels, object);
G_OBJECT_CLASS (gdk_wayland_toplevel_parent_class)->constructed (object);
}
static void
gdk_wayland_toplevel_class_init (GdkWaylandToplevelClass *class)
{
@@ -1291,6 +1322,7 @@ gdk_wayland_toplevel_class_init (GdkWaylandToplevelClass *class)
object_class->get_property = gdk_wayland_toplevel_get_property;
object_class->set_property = gdk_wayland_toplevel_set_property;
object_class->finalize = gdk_wayland_toplevel_finalize;
object_class->constructed = gdk_wayland_toplevel_constructed;
surface_class->compute_size = gdk_wayland_toplevel_compute_size;
@@ -1526,9 +1558,6 @@ gdk_wayland_toplevel_show (GdkWaylandToplevel *toplevel)
{
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (toplevel);
if (!impl->display_server.wl_surface)
gdk_wayland_surface_create_wl_surface (GDK_SURFACE (impl));
if (impl->mapped)
return;
+1 -3
View File
@@ -2546,13 +2546,11 @@ transmute_cf_shell_id_list_to_text_uri_list (const guchar *data,
ILFree (file_id_full);
}
*set_data = (guchar *) result->str;
if (set_data_length)
*set_data_length = result->len;
*set_data = (guchar *) g_string_free (result, FALSE);
if (set_data_destroy)
*set_data_destroy = g_free;
g_string_free (result, FALSE);
}
void
+1 -5
View File
@@ -427,11 +427,7 @@ wintab_init_check (GdkDeviceManagerWin32 *device_manager)
ndevices, ncursors));
#endif
/* Create a dummy window to receive wintab events */
wintab_window =
_gdk_win32_display_create_surface (display,
GDK_SURFACE_DRAG,
NULL,
-100, -100, 2, 2);
wintab_window = gdk_win32_drag_surface_new (display);
g_object_ref (wintab_window);
+8 -7
View File
@@ -28,6 +28,7 @@
#include "gdkdisplay-win32.h"
#include "gdkdevicemanager-win32.h"
#include "gdkglcontext-win32.h"
#include "gdksurface-win32.h"
#include "gdkwin32display.h"
#include "gdkwin32screen.h"
#include "gdkwin32surface.h"
@@ -1181,6 +1182,7 @@ gdk_win32_display_init_gl (GdkDisplay *display,
{
GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (display);
HDC init_gl_hdc = NULL;
GdkGLContext *context;
if (display_win32->dummy_context_wgl.hdc == NULL)
display_win32->dummy_context_wgl.hdc = GetDC (display_win32->hwnd);
@@ -1207,6 +1209,7 @@ gdk_win32_display_init_gl (GdkDisplay *display,
{
return g_object_new (GDK_TYPE_WIN32_GL_CONTEXT_EGL,
"display", display,
"allowed-apis", GDK_GL_API_GLES,
NULL);
}
else
@@ -1214,12 +1217,9 @@ gdk_win32_display_init_gl (GdkDisplay *display,
}
#endif
if (gdk_win32_display_init_wgl (display, error))
{
return g_object_new (GDK_TYPE_WIN32_GL_CONTEXT_WGL,
"display", display,
NULL);
}
context = gdk_win32_display_init_wgl (display, error);
if (context)
return context;
#ifdef HAVE_EGL
g_clear_error (error);
@@ -1267,6 +1267,8 @@ gdk_win32_display_class_init (GdkWin32DisplayClass *klass)
object_class->dispose = gdk_win32_display_dispose;
object_class->finalize = gdk_win32_display_finalize;
display_class->toplevel_type = GDK_TYPE_WIN32_TOPLEVEL;
display_class->popup_type = GDK_TYPE_WIN32_POPUP;
display_class->cairo_context_type = GDK_TYPE_WIN32_CAIRO_CONTEXT;
display_class->get_name = gdk_win32_display_get_name;
@@ -1280,7 +1282,6 @@ gdk_win32_display_class_init (GdkWin32DisplayClass *klass)
display_class->get_next_serial = gdk_win32_display_get_next_serial;
display_class->notify_startup_complete = gdk_win32_display_notify_startup_complete;
display_class->create_surface = _gdk_win32_display_create_surface;
display_class->get_keymap = _gdk_win32_display_get_keymap;
+2 -1
View File
@@ -24,6 +24,8 @@
#include "gdkwin32screen.h"
#include "gdkwin32cursor.h"
#include "gdkglversionprivate.h"
#ifdef HAVE_EGL
# include <epoxy/egl.h>
#endif
@@ -124,7 +126,6 @@ struct _GdkWin32Display
/* WGL/OpenGL Items */
GdkWin32GLDummyContextWGL dummy_context_wgl;
guint gl_version;
GListModel *monitors;
+1 -41
View File
@@ -37,8 +37,6 @@
#include <math.h>
#include <string.h>
#define GDK_NOTE(a,b)
/*
* Support for OLE-2 drag and drop added at Archaeopteryx Software, 2001
* For more information, do not contact Stephan R.A. Deibel (sdeibel@archaeopteryx.com),
@@ -1646,19 +1644,6 @@ _gdk_win32_dnd_exit (void)
CoUninitialize ();
}
static GdkSurface *
create_drag_surface (GdkDisplay *display)
{
GdkSurface *surface;
surface = _gdk_win32_display_create_surface (display,
GDK_SURFACE_DRAG,
NULL,
0, 0, 100, 100);
return surface;
}
GdkDrag *
_gdk_win32_surface_drag_begin (GdkSurface *surface,
GdkDevice *device,
@@ -1698,7 +1683,7 @@ _gdk_win32_surface_drag_begin (GdkSurface *surface,
g_set_object (&drag_win32->grab_surface, surface);
drag_win32->drag_surface = create_drag_surface (gdk_surface_get_display (surface));
drag_win32->drag_surface = gdk_win32_drag_surface_new (gdk_surface_get_display (surface));
if (!drag_context_grab (drag))
{
@@ -1882,11 +1867,6 @@ gdk_win32_drag_drop_done (GdkDrag *drag,
GdkDragAnim *anim;
GdkWin32Clipdrop *clipdrop;
gpointer ddd;
/*
cairo_surface_t *win_surface;
cairo_surface_t *surface;
cairo_t *cr;
*/
guint id;
GDK_NOTE (DND, g_print ("gdk_win32_drag_drop_done: 0x%p %s\n",
@@ -1916,26 +1896,6 @@ gdk_win32_drag_drop_done (GdkDrag *drag,
return;
}
/*
win_surface = _gdk_surface_ref_cairo_surface (drag_win32->drag_surface);
surface = gdk_surface_create_similar_surface (drag_win32->drag_surface,
cairo_surface_get_content (win_surface),
gdk_surface_get_width (drag_win32->drag_surface),
gdk_surface_get_height (drag_win32->drag_surface));
cr = cairo_create (surface);
cairo_set_source_surface (cr, win_surface, 0, 0);
cairo_paint (cr);
cairo_destroy (cr);
cairo_surface_destroy (win_surface);
pattern = cairo_pattern_create_for_surface (surface);
gdk_surface_set_background_pattern (drag_win32->drag_surface, pattern);
cairo_pattern_destroy (pattern);
cairo_surface_destroy (surface);
*/
anim = g_new0 (GdkDragAnim, 1);
g_set_object (&anim->drag, drag_win32);
anim->frame_clock = gdk_surface_get_frame_clock (drag_win32->drag_surface);
-7
View File
@@ -83,20 +83,13 @@ gdk_win32_gl_context_egl_end_frame (GdkDrawContext *draw_context,
cairo_region_t *painted)
{
GdkGLContext *context = GDK_GL_CONTEXT (draw_context);
GdkWin32GLContextEGL *context_egl = GDK_WIN32_GL_CONTEXT_EGL (context);
GdkSurface *surface = gdk_gl_context_get_surface (context);
GdkDisplay *display = gdk_gl_context_get_display (context);
cairo_rectangle_int_t whole_window;
EGLSurface egl_surface;
GDK_DRAW_CONTEXT_CLASS (gdk_win32_gl_context_egl_parent_class)->end_frame (draw_context, painted);
gdk_gl_context_make_current (context);
whole_window =
(GdkRectangle) { 0, 0,
gdk_surface_get_width (surface),
gdk_surface_get_height (surface)
};
egl_surface = gdk_surface_get_egl_surface (surface);
+195 -190
View File
@@ -247,16 +247,17 @@ gdk_init_dummy_wgl_context (GdkWin32Display *display_win32)
return best_idx;
}
gboolean
GdkGLContext *
gdk_win32_display_init_wgl (GdkDisplay *display,
GError **error)
{
int best_idx = 0;
GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (display);
GdkGLContext *context;
HDC hdc;
if (!gdk_gl_backend_can_be_used (GDK_GL_WGL, error))
return FALSE;
return NULL;
/* acquire and cache dummy Window (HWND & HDC) and
* dummy GL Context, it is used to query functions
@@ -275,25 +276,7 @@ gdk_win32_display_init_wgl (GdkDisplay *display,
GDK_GL_ERROR_NOT_AVAILABLE,
_("No GL implementation is available"));
return FALSE;
}
display_win32->gl_version = epoxy_gl_version ();
/* We must have OpenGL/WGL 2.0 or later, or have the GL_ARB_shader_objects extension */
if (display_win32->gl_version < 20)
{
if (!epoxy_has_gl_extension ("GL_ARB_shader_objects"))
{
wglMakeCurrent (NULL, NULL);
wglDeleteContext (display_win32->dummy_context_wgl.hglrc);
g_set_error_literal (error, GDK_GL_ERROR,
GDK_GL_ERROR_NOT_AVAILABLE,
_("No GL implementation is available"));
return FALSE;
}
return NULL;
}
display_win32->hasWglARBCreateContext =
@@ -307,45 +290,92 @@ gdk_win32_display_init_wgl (GdkDisplay *display,
display_win32->hasWglARBmultisample =
epoxy_has_wgl_extension (hdc, "WGL_ARB_multisample");
GDK_NOTE (OPENGL,
g_print ("WGL API version %d.%d found\n"
" - Vendor: %s\n"
" - Checked extensions:\n"
"\t* WGL_ARB_pixel_format: %s\n"
"\t* WGL_ARB_create_context: %s\n"
"\t* WGL_EXT_swap_control: %s\n"
"\t* WGL_OML_sync_control: %s\n"
"\t* WGL_ARB_multisample: %s\n",
display_win32->gl_version / 10,
display_win32->gl_version % 10,
glGetString (GL_VENDOR),
display_win32->hasWglARBPixelFormat ? "yes" : "no",
display_win32->hasWglARBCreateContext ? "yes" : "no",
display_win32->hasWglEXTSwapControl ? "yes" : "no",
display_win32->hasWglOMLSyncControl ? "yes" : "no",
display_win32->hasWglARBmultisample ? "yes" : "no"));
context = g_object_new (GDK_TYPE_WIN32_GL_CONTEXT_WGL,
"display", display,
NULL);
if (!gdk_gl_context_realize (context, error))
{
g_object_unref (context);
return NULL;
}
#if G_ENABLE_DEBUG
{
int major, minor;
gdk_gl_context_get_version (context, &major, &minor);
GDK_NOTE (OPENGL, g_print ("WGL API version %d.%d found\n"
" - Vendor: %s\n"
" - Checked extensions:\n"
"\t* WGL_ARB_pixel_format: %s\n"
"\t* WGL_ARB_create_context: %s\n"
"\t* WGL_EXT_swap_control: %s\n"
"\t* WGL_OML_sync_control: %s\n"
"\t* WGL_ARB_multisample: %s\n",
major, minor,
glGetString (GL_VENDOR),
display_win32->hasWglARBPixelFormat ? "yes" : "no",
display_win32->hasWglARBCreateContext ? "yes" : "no",
display_win32->hasWglEXTSwapControl ? "yes" : "no",
display_win32->hasWglOMLSyncControl ? "yes" : "no",
display_win32->hasWglARBmultisample ? "yes" : "no"));
}
#endif
wglMakeCurrent (NULL, NULL);
return TRUE;
return context;
}
/* Setup the legacy context after creating it */
static gboolean
ensure_legacy_wgl_context (HDC hdc,
HGLRC hglrc_legacy,
GdkGLContext *share)
ensure_legacy_wgl_context (HDC hdc,
HGLRC hglrc_legacy,
GdkGLContext *share,
GdkGLVersion *version,
GError **error)
{
GdkWin32GLContextWGL *context_wgl;
GdkGLVersion legacy_version;
GDK_NOTE (OPENGL,
g_print ("Creating legacy WGL context (version:%d.%d)\n",
gdk_gl_version_get_major (version),
gdk_gl_version_get_minor (version)));
if (!wglMakeCurrent (hdc, hglrc_legacy))
return FALSE;
{
g_set_error_literal (error, GDK_GL_ERROR,
GDK_GL_ERROR_NOT_AVAILABLE,
_("Unable to create a GL context"));
return FALSE;
}
gdk_gl_version_init_epoxy (&legacy_version);
if (!gdk_gl_version_greater_equal (&legacy_version, version))
{
g_set_error (error, GDK_GL_ERROR,
GDK_GL_ERROR_NOT_AVAILABLE,
_("WGL version %d.%d is too low, need at least %d.%d"),
gdk_gl_version_get_major (&legacy_version),
gdk_gl_version_get_minor (&legacy_version),
gdk_gl_version_get_major (version),
gdk_gl_version_get_minor (version));
return FALSE;
}
*version = legacy_version;
if (share != NULL)
{
context_wgl = GDK_WIN32_GL_CONTEXT_WGL (share);
return wglShareLists (hglrc_legacy, context_wgl->wgl_context);
if (!wglShareLists (hglrc_legacy, context_wgl->wgl_context))
{
g_set_error (error, GDK_GL_ERROR,
GDK_GL_ERROR_UNSUPPORTED_PROFILE,
_("GL implementation cannot share GL contexts"));
return FALSE;
}
}
return TRUE;
@@ -356,130 +386,138 @@ create_wgl_context_with_attribs (HDC hdc,
HGLRC hglrc_base,
GdkGLContext *share,
int flags,
int major,
int minor,
gboolean *is_legacy)
gboolean is_legacy,
GdkGLVersion *version)
{
HGLRC hglrc;
GdkWin32GLContextWGL *context_wgl;
const GdkGLVersion *supported_versions = gdk_gl_versions_get_for_api (GDK_GL_API_GL);
guint i;
/* if we have wglCreateContextAttribsARB(), create a
* context with the compatibility profile if a legacy
* context is requested, or when we go into fallback mode
*/
int profile = *is_legacy ? WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB :
WGL_CONTEXT_CORE_PROFILE_BIT_ARB;
GDK_NOTE (OPENGL,
g_print ("Creating %s WGL context (version:%d.%d, debug:%s, forward:%s)\n",
is_legacy ? "core" : "compat",
gdk_gl_version_get_major (version),
gdk_gl_version_get_minor (version),
(flags & WGL_CONTEXT_DEBUG_BIT_ARB) ? "yes" : "no",
(flags & WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB) ? "yes" : "no"));
int attribs[] = {
WGL_CONTEXT_PROFILE_MASK_ARB, profile,
WGL_CONTEXT_MAJOR_VERSION_ARB, *is_legacy ? 3 : major,
WGL_CONTEXT_MINOR_VERSION_ARB, *is_legacy ? 0 : minor,
WGL_CONTEXT_FLAGS_ARB, flags,
0
};
for (i = 0; gdk_gl_version_greater_equal (&supported_versions[i], version); i++)
{
/* if we have wglCreateContextAttribsARB(), create a
* context with the compatibility profile if a legacy
* context is requested, or when we go into fallback mode
*/
int profile = is_legacy ? WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB :
WGL_CONTEXT_CORE_PROFILE_BIT_ARB;
if (share != NULL)
context_wgl = GDK_WIN32_GL_CONTEXT_WGL (share);
int attribs[] = {
WGL_CONTEXT_PROFILE_MASK_ARB, profile,
WGL_CONTEXT_MAJOR_VERSION_ARB, gdk_gl_version_get_major (&supported_versions[i]),
WGL_CONTEXT_MINOR_VERSION_ARB, gdk_gl_version_get_minor (&supported_versions[i]),
WGL_CONTEXT_FLAGS_ARB, flags,
0
};
hglrc = wglCreateContextAttribsARB (hdc,
share != NULL ? context_wgl->wgl_context : NULL,
attribs);
if (share != NULL)
context_wgl = GDK_WIN32_GL_CONTEXT_WGL (share);
return hglrc;
hglrc = wglCreateContextAttribsARB (hdc,
share != NULL ? context_wgl->wgl_context : NULL,
attribs);
if (hglrc)
{
*version = supported_versions[i];
return hglrc;
}
}
return NULL;
}
static HGLRC
create_wgl_context (HDC hdc,
GdkGLContext *share,
int flags,
int major,
int minor,
gboolean *is_legacy,
gboolean hasWglARBCreateContext)
create_wgl_context (GdkGLContext *context,
HDC hdc,
gboolean hasWglARBCreateContext,
GdkGLContext *share,
int flags,
gboolean legacy,
GError **error)
{
/* We need a legacy context for *all* cases */
HGLRC hglrc_base = wglCreateContext (hdc);
gboolean success = TRUE;
HGLRC hglrc_base, hglrc;
GdkGLVersion version;
/* Save up the HDC and HGLRC that we are currently using, to restore back to it when we are done here */
HDC hdc_current = wglGetCurrentDC ();
HGLRC hglrc_current = wglGetCurrentContext ();
/* if we have no wglCreateContextAttribsARB(), return the legacy context when all is set */
if (*is_legacy && !hasWglARBCreateContext)
hglrc_base = wglCreateContext (hdc);
if (hglrc_base == NULL ||
!wglMakeCurrent (hdc, hglrc_base))
{
if (ensure_legacy_wgl_context (hdc, hglrc_base, share))
{
wglMakeCurrent (hdc_current, hglrc_current);
return hglrc_base;
}
success = FALSE;
goto gl_fail;
g_clear_pointer (&hglrc_base, wglDeleteContext);
g_set_error_literal (error, GDK_GL_ERROR,
GDK_GL_ERROR_NOT_AVAILABLE,
_("Unable to create a GL context"));
return 0;
}
else
hglrc = NULL;
if (hasWglARBCreateContext)
{
HGLRC hglrc = NULL;
if (!wglMakeCurrent (hdc, hglrc_base))
if (!legacy)
{
success = FALSE;
goto gl_fail;
gdk_gl_context_get_matching_version (context,
GDK_GL_API_GL,
FALSE,
&version);
hglrc = create_wgl_context_with_attribs (hdc,
hglrc_base,
share,
flags,
FALSE,
&version);
}
hglrc = create_wgl_context_with_attribs (hdc,
hglrc_base,
share,
flags,
major,
minor,
is_legacy);
/* return the legacy context we have if it could be setup properly, in case the 3.0+ context creation failed */
if (hglrc == NULL)
{
if (!(*is_legacy))
{
/* If we aren't using a legacy context in the beginning, try again with a compatibility profile 3.0 context */
hglrc = create_wgl_context_with_attribs (hdc,
hglrc_base,
share,
flags,
0, 0,
is_legacy);
*is_legacy = TRUE;
}
if (hglrc == NULL)
{
if (!ensure_legacy_wgl_context (hdc, hglrc_base, share))
success = FALSE;
}
if (success)
GDK_NOTE (OPENGL, g_print ("Using legacy context as fallback\n"));
legacy = TRUE;
gdk_gl_context_get_matching_version (context,
GDK_GL_API_GL,
TRUE,
&version);
hglrc = create_wgl_context_with_attribs (hdc,
hglrc_base,
share,
flags,
TRUE,
&version);
}
}
gl_fail:
if (hglrc == NULL)
{
legacy = TRUE;
gdk_gl_context_get_matching_version (context,
GDK_GL_API_GL,
TRUE,
&version);
if (ensure_legacy_wgl_context (hdc, hglrc_base, share, &version, error))
hglrc = g_steal_pointer (&hglrc_base);
}
if (!success)
{
wglMakeCurrent (NULL, NULL);
wglDeleteContext (hglrc_base);
return NULL;
}
if (hglrc)
{
gdk_gl_context_set_version (context, &version);
gdk_gl_context_set_is_legacy (context, legacy);
}
wglMakeCurrent (hdc_current, hglrc_current);
g_clear_pointer (&hglrc_base, wglDeleteContext);
if (hglrc != NULL)
{
wglDeleteContext (hglrc_base);
return hglrc;
}
wglMakeCurrent (hdc_current, hglrc_current);
return hglrc_base;
}
return hglrc;
}
static gboolean
@@ -525,8 +563,6 @@ gdk_win32_gl_context_wgl_realize (GdkGLContext *context,
/* request flags and specific versions for core (3.2+) WGL context */
int flags = 0;
int major = 0;
int minor = 0;
HGLRC hglrc;
int pixel_format;
HDC hdc;
@@ -542,24 +578,6 @@ gdk_win32_gl_context_wgl_realize (GdkGLContext *context,
debug_bit = gdk_gl_context_get_debug_enabled (context);
compat_bit = gdk_gl_context_get_forward_compatible (context);
/*
* We may need a Core GL 4.1+ context in order to use the GL support in
* the GStreamer media widget backend (such as on Intel drivers), but
* wglCreateContextAttribsARB() may only give us the GL context version
* that we ask for here, and nothing more. So, improve things here by
* asking for the GL version that is reported to us via epoxy_gl_version(),
* rather than the default GL core 3.2 context.
*/
gdk_gl_context_get_clipped_version (context,
display_win32->gl_version / 10,
display_win32->gl_version % 10,
&major, &minor);
if (surface != NULL)
hdc = GDK_WIN32_SURFACE (surface)->hdc;
else
hdc = display_win32->dummy_context_wgl.hdc;
/*
* A legacy context cannot be shared with core profile ones, so this means we
* must stick to a legacy context if the shared context is a legacy context
@@ -568,6 +586,11 @@ gdk_win32_gl_context_wgl_realize (GdkGLContext *context,
? TRUE
: share != NULL && gdk_gl_context_is_legacy (share);
if (surface != NULL)
hdc = GDK_WIN32_SURFACE (surface)->hdc;
else
hdc = display_win32->dummy_context_wgl.hdc;
if (!set_wgl_pixformat_for_hdc (hdc,
&pixel_format,
display_win32))
@@ -587,30 +610,15 @@ gdk_win32_gl_context_wgl_realize (GdkGLContext *context,
if (compat_bit)
flags |= WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;
GDK_NOTE (OPENGL,
g_print ("Creating %s WGL context (version:%d.%d, debug:%s, forward:%s, legacy: %s)\n",
compat_bit ? "core" : "compat",
major,
minor,
debug_bit ? "yes" : "no",
compat_bit ? "yes" : "no",
legacy_bit ? "yes" : "no"));
hglrc = create_wgl_context (hdc,
hglrc = create_wgl_context (context,
hdc,
display_win32->hasWglARBCreateContext,
share,
flags,
major,
minor,
&legacy_bit,
display_win32->hasWglARBCreateContext);
legacy_bit,
error);
if (hglrc == NULL)
{
g_set_error_literal (error, GDK_GL_ERROR,
GDK_GL_ERROR_NOT_AVAILABLE,
_("Unable to create a GL context"));
return 0;
}
return 0;
GDK_NOTE (OPENGL,
g_print ("Created WGL context[%p], pixel_format=%d\n",
@@ -619,9 +627,6 @@ gdk_win32_gl_context_wgl_realize (GdkGLContext *context,
context_wgl->wgl_context = hglrc;
/* Ensure that any other context is created with a legacy bit set */
gdk_gl_context_set_is_legacy (context, legacy_bit);
return GDK_GL_API_GL;
}
@@ -715,10 +720,11 @@ gdk_win32_gl_context_wgl_init (GdkWin32GLContextWGL *wgl_context)
*/
gboolean
gdk_win32_display_get_wgl_version (GdkDisplay *display,
int *major,
int *minor)
int *major,
int *minor)
{
GdkWin32Display *display_win32;
GdkGLContext *context;
g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
if (!GDK_IS_WIN32_DISPLAY (display))
@@ -727,12 +733,11 @@ gdk_win32_display_get_wgl_version (GdkDisplay *display,
if (!gdk_gl_backend_can_be_used (GDK_GL_WGL, NULL))
return FALSE;
display_win32 = GDK_WIN32_DISPLAY (display);
context = gdk_display_get_gl_context (display);
if (context == NULL)
return FALSE;
if (major != NULL)
*major = display_win32->gl_version / 10;
if (minor != NULL)
*minor = display_win32->gl_version % 10;
gdk_gl_context_get_version (context, major, minor);
return TRUE;
}
+4 -4
View File
@@ -64,10 +64,10 @@ struct _GdkWin32GLContextClass
typedef struct _GdkWin32GLContextWGL GdkWin32GLContextWGL;
gboolean gdk_win32_display_init_wgl (GdkDisplay *display,
GError **error);
void gdk_win32_gl_context_wgl_bind_surface (GdkWin32GLContextWGL *ctx,
GdkWin32Surface *win32_surface);
GdkGLContext * gdk_win32_display_init_wgl (GdkDisplay *display,
GError **error);
void gdk_win32_gl_context_wgl_bind_surface (GdkWin32GLContextWGL *ctx,
GdkWin32Surface *win32_surface);
GType gdk_win32_gl_context_wgl_get_type (void) G_GNUC_CONST;
+7 -6
View File
@@ -354,12 +354,13 @@ reset_viewport (IDirectManipulationViewport *viewport)
HRESULT hr;
hr = IDirectManipulationViewport_GetPrimaryContent (viewport, iid, (void**)&content);
HR_CHECK (hr);
HR_CHECK_GOTO (hr, failed);
hr = IDirectManipulationContent_SyncContentTransform (content, identity,
G_N_ELEMENTS (identity));
HR_CHECK (hr);
HR_CHECK_GOTO (hr, failed);
failed:
IUnknown_Release (content);
}
@@ -384,7 +385,7 @@ create_viewport (GdkSurface *surface,
{
DIRECTMANIPULATION_CONFIGURATION configuration = 0;
HWND hwnd = GDK_SURFACE_HWND (surface);
IDirectManipulationViewportEventHandler *handler;
IDirectManipulationViewportEventHandler *handler = NULL;
DWORD cookie = 0;
HRESULT hr;
@@ -500,7 +501,7 @@ void gdk_dmanipulation_initialize_surface (GdkSurface *surface)
hr = IDirectManipulationManager_Activate (dmanipulation_manager,
GDK_SURFACE_HWND (surface));
HR_CHECK (hr);
HR_CHECK_RETURN (hr);
}
void gdk_dmanipulation_finalize_surface (GdkSurface *surface)
@@ -536,11 +537,11 @@ void gdk_dmanipulation_maybe_add_contact (GdkSurface *surface,
hr = IDirectManipulationViewport_SetContact (surface_win32->dmanipulation_viewport_pan,
pointer_id);
HR_CHECK (hr);
HR_CHECK_RETURN (hr);
hr = IDirectManipulationViewport_SetContact (surface_win32->dmanipulation_viewport_zoom,
pointer_id);
HR_CHECK (hr);
HR_CHECK_RETURN (hr);
}
}
-20
View File
@@ -109,16 +109,6 @@ gdk_win32_ensure_com (void)
return co_initialized;
}
static void
gdk_win32_finalize_com (void)
{
if (co_initialized)
{
CoUninitialize ();
co_initialized = FALSE;
}
}
gboolean
gdk_win32_ensure_ole (void)
{
@@ -142,16 +132,6 @@ gdk_win32_ensure_ole (void)
return ole_initialized;
}
static void
gdk_win32_finalize_ole (void)
{
if (ole_initialized)
{
OleUninitialize ();
ole_initialized = FALSE;
}
}
void
_gdk_win32_api_failed (const char *where,
const char *api)
-9
View File
@@ -276,7 +276,6 @@ void _gdk_other_api_failed (const char *where,
#define HR_CHECK_RETURN(hr) { if G_UNLIKELY (FAILED (hr)) return; }
#define HR_CHECK_RETURN_VAL(hr, val) { if G_UNLIKELY (FAILED (hr)) return val; }
#define HR_CHECK(hr)
#define HR_CHECK_GOTO(hr, label) { if G_UNLIKELY (FAILED (hr)) goto label; }
extern LRESULT CALLBACK _gdk_win32_surface_procedure (HWND, UINT, WPARAM, LPARAM);
@@ -382,14 +381,6 @@ GdkModifierType _gdk_win32_keymap_get_mod_mask (GdkWin32Keymap *keymap);
GdkKeymap *_gdk_win32_display_get_keymap (GdkDisplay *display);
GdkSurface *_gdk_win32_display_create_surface (GdkDisplay *display,
GdkSurfaceType surface_type,
GdkSurface *parent,
int x,
int y,
int width,
int height);
/* stray GdkSurfaceImplWin32 members */
void _gdk_win32_surface_register_dnd (GdkSurface *window);
void _gdk_win32_surface_unregister_dnd (GdkSurface *window);
+87 -189
View File
@@ -135,14 +135,6 @@ static void gdk_win32_impl_frame_clock_after_paint (GdkFrameClock *clock,
G_DEFINE_TYPE (GdkWin32Surface, gdk_win32_surface, GDK_TYPE_SURFACE)
GType gdk_win32_toplevel_get_type (void) G_GNUC_CONST;
GType gdk_win32_popup_get_type (void) G_GNUC_CONST;
GType gdk_win32_drag_surface_get_type (void) G_GNUC_CONST;
#define GDK_TYPE_WIN32_TOPLEVEL (gdk_win32_toplevel_get_type ())
#define GDK_TYPE_WIN32_POPUP (gdk_win32_popup_get_type ())
#define GDK_TYPE_WIN32_DRAG_SURFACE (gdk_win32_drag_surface_get_type ())
static void
gdk_win32_surface_init (GdkWin32Surface *impl)
{
@@ -212,10 +204,6 @@ gdk_surface_win32_finalize (GObject *object)
g_assert (surface->transient_owner == NULL);
g_assert (surface->transient_children == NULL);
g_signal_handlers_disconnect_by_func (GDK_SURFACE (object),
gdk_win32_toplevel_state_callback,
NULL);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
@@ -334,7 +322,7 @@ get_default_title (void)
* get its own class
*/
static ATOM
RegisterGdkClass (GdkSurfaceType wtype)
RegisterGdkClass (GType wtype)
{
static ATOM klassTOPLEVEL = 0;
static ATOM klassTEMP = 0;
@@ -407,10 +395,8 @@ RegisterGdkClass (GdkSurfaceType wtype)
/* MSDN: CS_OWNDC is needed for OpenGL contexts */
wcl.style |= CS_OWNDC;
switch (wtype)
if (wtype != GDK_TYPE_WIN32_DRAG_SURFACE)
{
case GDK_SURFACE_TOPLEVEL:
case GDK_SURFACE_POPUP:
if (0 == klassTOPLEVEL)
{
wcl.lpszClassName = L"gdkSurfaceToplevel";
@@ -419,9 +405,9 @@ RegisterGdkClass (GdkSurfaceType wtype)
klassTOPLEVEL = RegisterClassExW (&wcl);
}
klass = klassTOPLEVEL;
break;
case GDK_SURFACE_DRAG:
}
else
{
if (klassTEMP == 0)
{
wcl.lpszClassName = L"gdkSurfaceTemp";
@@ -431,12 +417,6 @@ RegisterGdkClass (GdkSurfaceType wtype)
}
klass = klassTEMP;
break;
default:
g_assert_not_reached ();
break;
}
if (klass == 0)
@@ -447,86 +427,20 @@ RegisterGdkClass (GdkSurfaceType wtype)
return klass;
}
/*
* Create native windows.
*
* With the default Gdk the created windows are mostly toplevel windows.
*
* Placement of the window is derived from the passed in window,
* except for toplevel window where OS/Window Manager placement
* is used.
*
* [1] http://mail.gnome.org/archives/gtk-devel-list/2010-August/msg00214.html
*/
GdkSurface *
_gdk_win32_display_create_surface (GdkDisplay *display,
GdkSurfaceType surface_type,
GdkSurface *parent,
int x,
int y,
int width,
int height)
static void
gdk_win32_surface_constructed (GObject *object)
{
HWND hwndNew;
GdkWin32Surface *impl = GDK_WIN32_SURFACE (object);
GdkSurface *surface = GDK_SURFACE (impl);
GdkDisplay *display = gdk_surface_get_display (surface);
GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (display);
GdkFrameClock *frame_clock;
HANDLE owner;
ATOM klass = 0;
DWORD dwStyle = 0, dwExStyle;
RECT rect;
GdkWin32Surface *impl;
GdkWin32Display *display_win32;
GdkSurface *surface;
const char *title;
wchar_t *wtitle;
int window_width, window_height;
int window_x, window_y;
int real_x = 0, real_y = 0;
GdkFrameClock *frame_clock;
g_return_val_if_fail (display == _gdk_display, NULL);
GDK_NOTE (MISC,
g_print ("_gdk_surface_new: %s\n", (surface_type == GDK_SURFACE_TOPLEVEL ? "TOPLEVEL" :
(surface_type == GDK_SURFACE_DRAG? "TEMP" :
(surface_type == GDK_SURFACE_DRAG ? "POPUP" : "???")))));
display_win32 = GDK_WIN32_DISPLAY (display);
if (parent)
frame_clock = g_object_ref (gdk_surface_get_frame_clock (parent));
else
frame_clock = _gdk_frame_clock_idle_new ();
switch (surface_type)
{
case GDK_SURFACE_TOPLEVEL:
impl = g_object_new (GDK_TYPE_WIN32_TOPLEVEL,
"display", display,
"frame-clock", frame_clock,
NULL);
break;
case GDK_SURFACE_POPUP:
impl = g_object_new (GDK_TYPE_WIN32_POPUP,
"parent", parent,
"display", display,
"frame-clock", frame_clock,
NULL);
break;
case GDK_SURFACE_DRAG:
impl = g_object_new (GDK_TYPE_WIN32_DRAG_SURFACE,
"display", display,
"frame-clock", frame_clock,
NULL);
break;
default:
g_assert_not_reached ();
break;
}
surface = GDK_SURFACE (impl);
surface->x = x;
surface->y = y;
surface->width = width;
surface->height = height;
impl->surface_scale = gdk_win32_display_get_monitor_scale_factor (display_win32, NULL, NULL);
@@ -536,86 +450,60 @@ _gdk_win32_display_create_surface (GdkDisplay *display,
/* MSDN: We need WS_CLIPCHILDREN and WS_CLIPSIBLINGS for GL Context Creation */
dwStyle = WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
switch (surface_type)
if (G_OBJECT_TYPE (impl) == GDK_TYPE_WIN32_TOPLEVEL)
{
case GDK_SURFACE_TOPLEVEL:
dwStyle |= WS_OVERLAPPEDWINDOW;
break;
case GDK_SURFACE_DRAG:
dwExStyle |= WS_EX_TOOLWINDOW | WS_EX_TOPMOST;
/* fall through */
case GDK_SURFACE_POPUP:
dwStyle |= WS_POPUP;
/* Only popup and temp windows are fit to use the Owner Window mechanism */
if (parent != NULL)
owner = GDK_SURFACE_HWND (parent);
break;
default:
g_assert_not_reached ();
frame_clock = _gdk_frame_clock_idle_new ();
}
rect.left = x * impl->surface_scale;
rect.top = y * impl->surface_scale;
rect.right = rect.left + width * impl->surface_scale;
rect.bottom = rect.top + height * impl->surface_scale;
AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
real_x = x * impl->surface_scale;
real_y = y * impl->surface_scale;
if (surface_type == GDK_SURFACE_TOPLEVEL)
else if (G_OBJECT_TYPE (impl) == GDK_TYPE_WIN32_DRAG_SURFACE)
{
/* We initially place it at default so that we can get the
default window positioning if we want */
window_x = window_y = CW_USEDEFAULT;
dwExStyle |= WS_EX_TOOLWINDOW | WS_EX_TOPMOST;
dwStyle |= WS_POPUP;
frame_clock = _gdk_frame_clock_idle_new ();
}
else if (G_OBJECT_TYPE (impl) == GDK_TYPE_WIN32_POPUP)
{
GdkSurface *parent = gdk_popup_get_parent (GDK_POPUP (impl));
dwStyle |= WS_POPUP;
owner = GDK_SURFACE_HWND (parent);
frame_clock = g_object_ref (gdk_surface_get_frame_clock (parent));
}
else
{
/* TEMP: Put these where requested */
window_x = real_x;
window_y = real_y;
g_assert_not_reached ();
}
window_width = rect.right - rect.left;
window_height = rect.bottom - rect.top;
gdk_surface_set_frame_clock (surface, frame_clock);
g_object_unref (frame_clock);
title = get_default_title ();
if (!title || !*title)
title = "";
klass = RegisterGdkClass (surface_type);
klass = RegisterGdkClass (G_OBJECT_TYPE (impl));
wtitle = g_utf8_to_utf16 (title, -1, NULL, NULL, NULL);
hwndNew = CreateWindowExW (dwExStyle,
MAKEINTRESOURCEW (klass),
wtitle,
dwStyle,
window_x, window_y,
window_width, window_height,
owner,
NULL,
_gdk_dll_hinstance,
surface);
impl->handle = hwndNew;
impl->handle = CreateWindowExW (dwExStyle,
MAKEINTRESOURCEW (klass),
wtitle,
dwStyle,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
owner,
NULL,
_gdk_dll_hinstance,
surface);
if (impl->handle == NULL)
{
WIN32_API_FAILED ("CreateWindowExW");
g_error ("Fatal error: CreateWindowExW failed.");
}
GetWindowRect (hwndNew, &rect);
GetWindowRect (impl->handle, &rect);
impl->initial_x = rect.left;
impl->initial_y = rect.top;
/* Now we know the initial position, move to actually specified position */
if (real_x != window_x || real_y != window_y)
{
API_CALL (SetWindowPos, (hwndNew,
SWP_NOZORDER_SPECIFIED,
real_x, real_y, 0, 0,
SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER));
}
g_object_ref (impl);
/* Take note: we're inserting a pointer into a heap-allocated
* object (impl). Inserting a pointer to a stack variable
@@ -627,26 +515,11 @@ _gdk_win32_display_create_surface (GdkDisplay *display,
*/
gdk_win32_handle_table_insert (&GDK_SURFACE_HWND (impl), impl);
GDK_NOTE (MISC, g_print ("... \"%s\" %dx%d@%+d%+d %p = %p\n",
title,
window_width, window_height,
surface->x,
surface->y,
owner,
hwndNew));
g_free (wtitle);
if (impl->handle == NULL)
{
WIN32_API_FAILED ("CreateWindowExW");
g_object_unref (impl);
return NULL;
}
gdk_surface_set_egl_native_window (surface, (void *) impl->handle);
if (surface_type != GDK_SURFACE_DRAG)
if (G_OBJECT_TYPE (impl) != GDK_TYPE_WIN32_DRAG_SURFACE)
{
if (display_win32->tablet_input_api == GDK_WIN32_TABLET_INPUT_API_WINPOINTER)
gdk_winpointer_initialize_surface (surface);
@@ -663,18 +536,10 @@ _gdk_win32_display_create_surface (GdkDisplay *display,
G_CALLBACK (gdk_win32_impl_frame_clock_after_paint),
impl);
g_object_unref (frame_clock);
impl->hdc = GetDC (impl->handle);
impl->inhibit_configure = TRUE;
if (surface_type == GDK_SURFACE_TOPLEVEL)
{
g_signal_connect (surface, "notify::state",
G_CALLBACK (gdk_win32_toplevel_state_callback),
NULL);
}
return surface;
G_OBJECT_CLASS (parent_class)->constructed (object);
}
static void
@@ -4636,6 +4501,7 @@ gdk_win32_surface_class_init (GdkWin32SurfaceClass *klass)
parent_class = g_type_class_peek_parent (klass);
object_class->constructed = gdk_win32_surface_constructed;
object_class->dispose = gdk_surface_win32_dispose;
object_class->finalize = gdk_surface_win32_finalize;
@@ -4824,15 +4690,20 @@ G_DEFINE_TYPE_WITH_CODE (GdkWin32Toplevel, gdk_win32_toplevel, GDK_TYPE_WIN32_SU
gdk_win32_toplevel_iface_init))
static void
gdk_win32_toplevel_init (GdkWin32Toplevel *toplevel)
gdk_win32_toplevel_constructed (GObject *object)
{
g_signal_connect (object, "notify::state",
G_CALLBACK (gdk_win32_toplevel_state_callback),
NULL);
G_OBJECT_CLASS (gdk_win32_toplevel_parent_class)->constructed (object);
}
static void
gdk_win32_toplevel_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
GdkSurface *surface = GDK_SURFACE (object);
@@ -4891,9 +4762,9 @@ gdk_win32_toplevel_set_property (GObject *object,
static void
gdk_win32_toplevel_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GdkSurface *surface = GDK_SURFACE (object);
@@ -4942,17 +4813,36 @@ gdk_win32_toplevel_get_property (GObject *object,
}
}
static void
gdk_win32_toplevel_finalize (GObject *object)
{
GdkWin32Surface *self = GDK_WIN32_SURFACE (object);
g_signal_handlers_disconnect_by_func (self,
gdk_win32_toplevel_state_callback,
NULL);
G_OBJECT_CLASS (gdk_win32_toplevel_parent_class)->finalize (object);
}
static void
gdk_win32_toplevel_class_init (GdkWin32ToplevelClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
object_class->constructed = gdk_win32_toplevel_constructed;
object_class->finalize = gdk_win32_toplevel_finalize;
object_class->get_property = gdk_win32_toplevel_get_property;
object_class->set_property = gdk_win32_toplevel_set_property;
gdk_toplevel_install_properties (object_class, 1);
}
static void
gdk_win32_toplevel_init (GdkWin32Toplevel *toplevel)
{
}
static void
gdk_win32_toplevel_present (GdkToplevel *toplevel,
GdkToplevelLayout *layout)
@@ -5228,3 +5118,11 @@ _gdk_win32_surface_invalidate_egl_framebuffer (GdkSurface *surface)
}
#endif
}
GdkSurface *
gdk_win32_drag_surface_new (GdkDisplay *display)
{
return g_object_new (GDK_TYPE_WIN32_DRAG_SURFACE,
"display", display,
NULL);
}
+10
View File
@@ -39,6 +39,14 @@
G_BEGIN_DECLS
GType gdk_win32_toplevel_get_type (void) G_GNUC_CONST;
GType gdk_win32_popup_get_type (void) G_GNUC_CONST;
GType gdk_win32_drag_surface_get_type (void) G_GNUC_CONST;
#define GDK_TYPE_WIN32_TOPLEVEL (gdk_win32_toplevel_get_type ())
#define GDK_TYPE_WIN32_POPUP (gdk_win32_popup_get_type ())
#define GDK_TYPE_WIN32_DRAG_SURFACE (gdk_win32_drag_surface_get_type ())
typedef enum
{
GDK_DECOR_ALL = 1 << 0,
@@ -364,6 +372,8 @@ void gdk_win32_surface_move_resize (GdkSurface *window,
int width,
int height);
GdkSurface *gdk_win32_drag_surface_new (GdkDisplay *display);
RECT
gdk_win32_surface_handle_queued_move_resize (GdkDrawContext *draw_context);
+3 -6
View File
@@ -1391,11 +1391,7 @@ gdk_x11_display_init_leader_surface (GdkX11Display *self)
gdk_event_init (display);
self->leader_gdk_surface =
_gdk_x11_display_create_surface (display,
GDK_SURFACE_DRAG,
NULL,
-100, -100, 1, 1);
self->leader_gdk_surface = gdk_x11_drag_surface_new (display);
(_gdk_x11_surface_get_toplevel (self->leader_gdk_surface))->is_leader = TRUE;
self->leader_window = GDK_SURFACE_XID (self->leader_gdk_surface);
@@ -3032,6 +3028,8 @@ gdk_x11_display_class_init (GdkX11DisplayClass * class)
object_class->dispose = gdk_x11_display_dispose;
object_class->finalize = gdk_x11_display_finalize;
display_class->toplevel_type = GDK_TYPE_X11_TOPLEVEL;
display_class->popup_type = GDK_TYPE_X11_POPUP;
display_class->cairo_context_type = GDK_TYPE_X11_CAIRO_CONTEXT;
#ifdef GDK_RENDERING_VULKAN
display_class->vk_context_type = GDK_TYPE_X11_VULKAN_CONTEXT;
@@ -3052,7 +3050,6 @@ G_GNUC_BEGIN_IGNORE_DEPRECATIONS
display_class->get_startup_notification_id = gdk_x11_display_get_startup_notification_id;
G_GNUC_END_IGNORE_DEPRECATIONS
display_class->notify_startup_complete = gdk_x11_display_notify_startup_complete;
display_class->create_surface = _gdk_x11_display_create_surface;
display_class->get_keymap = gdk_x11_display_get_keymap;
display_class->init_gl = gdk_x11_display_init_gl;
+2 -43
View File
@@ -1255,19 +1255,6 @@ gdk_drag_do_leave (GdkX11Drag *drag_x11)
}
}
static GdkSurface *
create_drag_surface (GdkDisplay *display)
{
GdkSurface *surface;
surface = _gdk_x11_display_create_surface (display,
GDK_SURFACE_DRAG,
NULL,
0, 0, 100, 100);
return surface;
}
static Window
_gdk_x11_display_get_drag_protocol (GdkDisplay *display,
Window xid,
@@ -1843,11 +1830,6 @@ gdk_x11_drag_drop_done (GdkDrag *drag,
{
GdkX11Drag *x11_drag = GDK_X11_DRAG (drag);
GdkDragAnim *anim;
/*
cairo_surface_t *win_surface;
cairo_surface_t *surface;
cairo_t *cr;
*/
guint id;
gdk_x11_drag_release_selection (drag);
@@ -1862,26 +1844,6 @@ gdk_x11_drag_drop_done (GdkDrag *drag,
return;
}
/*
win_surface = _gdk_surface_ref_cairo_surface (x11_drag->drag_surface);
surface = gdk_surface_create_similar_surface (x11_drag->drag_surface,
cairo_surface_get_content (win_surface),
gdk_surface_get_width (x11_drag->drag_surface),
gdk_surface_get_height (x11_drag->drag_surface));
cr = cairo_create (surface);
cairo_set_source_surface (cr, win_surface, 0, 0);
cairo_paint (cr);
cairo_destroy (cr);
cairo_surface_destroy (win_surface);
pattern = cairo_pattern_create_for_surface (surface);
gdk_surface_set_background_pattern (x11_drag->drag_surface, pattern);
cairo_pattern_destroy (pattern);
cairo_surface_destroy (surface);
*/
anim = g_new0 (GdkDragAnim, 1);
anim->drag = g_object_ref (x11_drag);
anim->frame_clock = gdk_surface_get_frame_clock (x11_drag->drag_surface);
@@ -2026,10 +1988,7 @@ _gdk_x11_surface_drag_begin (GdkSurface *surface,
display = gdk_surface_get_display (surface);
ipc_surface = _gdk_x11_display_create_surface (display,
GDK_SURFACE_DRAG,
NULL,
-99, -99, 1, 1);
ipc_surface = gdk_x11_drag_surface_new (display);
drag = (GdkDrag *) g_object_new (GDK_TYPE_X11_DRAG,
"surface", ipc_surface,
@@ -2063,7 +2022,7 @@ _gdk_x11_surface_drag_begin (GdkSurface *surface,
gdk_surface_set_is_mapped (x11_drag->ipc_surface, TRUE);
gdk_x11_surface_show (x11_drag->ipc_surface, FALSE);
x11_drag->drag_surface = create_drag_surface (display);
x11_drag->drag_surface = gdk_x11_drag_surface_new (display);
if (!drag_grab (drag))
{
+45 -25
View File
@@ -477,8 +477,11 @@ gdk_x11_context_create_glx_context (GdkGLContext *context,
GdkSurface *surface = gdk_gl_context_get_surface (context);
GLXContext ctx;
int context_attribs[N_GLX_ATTRS], i = 0, flags = 0;
int min_major, min_minor, major, minor;
gsize major_idx, minor_idx;
GdkGLVersion version;
const GdkGLVersion* supported_versions;
gboolean debug_bit, compat_bit;
gsize j;
if (!gdk_gl_context_is_api_allowed (context, api, NULL))
return 0;
@@ -488,10 +491,7 @@ gdk_x11_context_create_glx_context (GdkGLContext *context,
/* We will use the default version matching the context status
* unless the user requested a version which makes sense */
gdk_gl_context_get_matching_version (api, legacy, 0,
&min_major, &min_minor);
gdk_gl_context_get_clipped_version (context, min_major, min_minor,
&major, &minor);
gdk_gl_context_get_matching_version (context, api, legacy, &version);
debug_bit = gdk_gl_context_get_debug_enabled (context);
compat_bit = gdk_gl_context_get_forward_compatible (context);
@@ -511,9 +511,9 @@ gdk_x11_context_create_glx_context (GdkGLContext *context,
context_attribs[i++] = GLX_CONTEXT_ES2_PROFILE_BIT_EXT;
context_attribs[i++] = GLX_CONTEXT_MAJOR_VERSION_ARB;
context_attribs[i++] = major;
major_idx = i++;
context_attribs[i++] = GLX_CONTEXT_MINOR_VERSION_ARB;
context_attribs[i++] = minor;
minor_idx = i++;
context_attribs[i++] = GLX_CONTEXT_FLAGS_ARB;
context_attribs[i++] = flags;
@@ -522,7 +522,7 @@ gdk_x11_context_create_glx_context (GdkGLContext *context,
GDK_DISPLAY_DEBUG (display, OPENGL,
"Creating GLX context version %d.%d (debug:%s, forward:%s, legacy:%s, es:%s)",
major, minor,
gdk_gl_version_get_major (&version), gdk_gl_version_get_minor (&version),
debug_bit ? "yes" : "no",
compat_bit ? "yes" : "no",
legacy ? "yes" : "no",
@@ -533,25 +533,44 @@ gdk_x11_context_create_glx_context (GdkGLContext *context,
gdk_x11_display_error_trap_push (display);
/* If we don't have access to GLX_ARB_create_context_profile, then
* we have to fall back to the old GLX 1.3 API.
*/
if (legacy && !display_x11->has_glx_create_context)
ctx = glXCreateNewContext (gdk_x11_display_get_xdisplay (display),
display_x11->glx_config,
GLX_RGBA_TYPE,
share_glx != NULL ? share_glx->glx_context : NULL,
TRUE);
supported_versions = gdk_gl_versions_get_for_api (api);
for (j = 0; gdk_gl_version_greater_equal (&supported_versions[j], &version); j++)
{
context_attribs [major_idx] = gdk_gl_version_get_major (&supported_versions[j]);
context_attribs [minor_idx] = gdk_gl_version_get_minor (&supported_versions[j]);
else
ctx = glXCreateContextAttribsARB (gdk_x11_display_get_xdisplay (display),
display_x11->glx_config,
share_glx != NULL ? share_glx->glx_context : NULL,
True,
context_attribs);
/* If we don't have access to GLX_ARB_create_context_profile, then
* we have to fall back to the old GLX 1.3 API.
*/
if (legacy && !display_x11->has_glx_create_context)
ctx = glXCreateNewContext (gdk_x11_display_get_xdisplay (display),
display_x11->glx_config,
GLX_RGBA_TYPE,
share_glx != NULL ? share_glx->glx_context : NULL,
TRUE);
if (gdk_x11_display_error_trap_pop (display) || ctx == NULL)
return 0;
else
ctx = glXCreateContextAttribsARB (gdk_x11_display_get_xdisplay (display),
display_x11->glx_config,
share_glx != NULL ? share_glx->glx_context : NULL,
True,
context_attribs);
if (ctx)
break;
}
if (ctx == NULL)
{
gdk_x11_display_error_trap_pop_ignored (display);
return 0;
}
if (gdk_x11_display_error_trap_pop (display))
{
glXDestroyContext (dpy, ctx);
return 0;
}
GDK_DISPLAY_DEBUG (display, OPENGL,
"Realized GLX context[%p], %s, version: %d.%d",
@@ -561,6 +580,7 @@ gdk_x11_context_create_glx_context (GdkGLContext *context,
display_x11->glx_version % 10);
context_glx->glx_context = ctx;
gdk_gl_context_set_version (context, &supported_versions[j]);
gdk_gl_context_set_is_legacy (context, legacy);
#ifdef HAVE_XDAMAGE
-7
View File
@@ -173,13 +173,6 @@ void _gdk_x11_display_get_maximal_cursor_size (GdkDisplay *display,
guint *width,
guint *height);
GdkSurface * _gdk_x11_display_create_surface (GdkDisplay *display,
GdkSurfaceType surface_type,
GdkSurface *parent,
int x,
int y,
int width,
int height);
GList * gdk_x11_display_get_toplevel_windows (GdkDisplay *display);
void _gdk_x11_precache_atoms (GdkDisplay *display,
+452 -464
View File
File diff suppressed because it is too large Load Diff
+10
View File
@@ -36,6 +36,14 @@
G_BEGIN_DECLS
GType gdk_x11_toplevel_get_type (void) G_GNUC_CONST;
GType gdk_x11_popup_get_type (void) G_GNUC_CONST;
GType gdk_x11_drag_surface_get_type (void) G_GNUC_CONST;
#define GDK_TYPE_X11_TOPLEVEL (gdk_x11_toplevel_get_type ())
#define GDK_TYPE_X11_POPUP (gdk_x11_popup_get_type ())
#define GDK_TYPE_X11_DRAG_SURFACE (gdk_x11_drag_surface_get_type ())
typedef struct _GdkToplevelX11 GdkToplevelX11;
typedef struct _GdkXPositionInfo GdkXPositionInfo;
@@ -191,6 +199,8 @@ struct _GdkToplevelX11
#endif
};
GdkSurface *gdk_x11_drag_surface_new (GdkDisplay *display);
GdkToplevelX11 *_gdk_x11_surface_get_toplevel (GdkSurface *window);
GdkCursor *_gdk_x11_surface_get_cursor (GdkSurface *window);
+1
View File
@@ -78,6 +78,7 @@ gsk_gl_attachment_state_bind_texture (GskGLAttachmentState *self,
target == GL_TEXTURE_2D ||
target == GL_TEXTURE_3D);
g_assert (texture >= GL_TEXTURE0 && texture <= GL_TEXTURE16);
g_assert (texture - GL_TEXTURE0 < G_N_ELEMENTS (self->textures));
attach = &self->textures[texture - GL_TEXTURE0];
+4 -2
View File
@@ -73,11 +73,13 @@ struct _GskGLBindFramebuffer
G_STATIC_ASSERT (sizeof (GskGLBindFramebuffer) == 4);
/* Increase if shaders add more textures */
#define GSK_GL_MAX_TEXTURES_PER_PROGRAM 4
struct _GskGLAttachmentState
{
GskGLBindFramebuffer fbo;
/* Increase if shaders add more textures */
GskGLBindTexture textures[4];
GskGLBindTexture textures[GSK_GL_MAX_TEXTURES_PER_PROGRAM];
guint n_changed;
};
+66 -27
View File
@@ -427,6 +427,7 @@ gsk_gl_command_queue_dispose (GObject *object)
gsk_gl_command_batches_clear (&self->batches);
gsk_gl_command_binds_clear (&self->batch_binds);
gsk_gl_command_uniforms_clear (&self->batch_uniforms);
gsk_gl_syncs_clear (&self->syncs);
gsk_gl_buffer_destroy (&self->vertices);
@@ -449,6 +450,7 @@ gsk_gl_command_queue_init (GskGLCommandQueue *self)
gsk_gl_command_batches_init (&self->batches, 128);
gsk_gl_command_binds_init (&self->batch_binds, 1024);
gsk_gl_command_uniforms_init (&self->batch_uniforms, 2048);
gsk_gl_syncs_init (&self->syncs, 10);
gsk_gl_buffer_init (&self->vertices, GL_ARRAY_BUFFER, sizeof (GskGLDrawVertex));
}
@@ -491,7 +493,7 @@ gsk_gl_command_queue_new (GdkGLContext *context,
}
}
self->has_samplers = gdk_gl_context_check_version (context, 3, 3, 3, 0);
self->has_samplers = gdk_gl_context_check_version (context, "3.3", "3.0");
/* create the samplers */
if (self->has_samplers)
@@ -1020,14 +1022,14 @@ gsk_gl_command_queue_execute (GskGLCommandQueue *self,
guint program = 0;
guint width = 0;
guint height = 0;
G_GNUC_UNUSED guint n_binds = 0;
guint n_fbos = 0;
G_GNUC_UNUSED guint n_uniforms = 0;
guint n_programs = 0;
G_GNUC_UNUSED unsigned int n_binds = 0;
G_GNUC_UNUSED unsigned int n_fbos = 0;
G_GNUC_UNUSED unsigned int n_uniforms = 0;
G_GNUC_UNUSED unsigned int n_programs = 0;
guint vao_id;
guint vbo_id;
int textures[4];
int samplers[4];
int textures[GSK_GL_MAX_TEXTURES_PER_PROGRAM];
int samplers[GSK_GL_MAX_TEXTURES_PER_PROGRAM];
int framebuffer = -1;
int next_batch_index;
int active = -1;
@@ -1060,8 +1062,11 @@ gsk_gl_command_queue_execute (GskGLCommandQueue *self,
glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glBlendEquation (GL_FUNC_ADD);
glGenVertexArrays (1, &vao_id);
glBindVertexArray (vao_id);
if (!gdk_gl_context_get_use_es (self->context))
{
glGenVertexArrays (1, &vao_id);
glBindVertexArray (vao_id);
}
vbo_id = gsk_gl_buffer_submit (&self->vertices);
@@ -1157,16 +1162,26 @@ gsk_gl_command_queue_execute (GskGLCommandQueue *self,
{
const GskGLCommandBind *bind = &self->batch_binds.items[batch->draw.bind_offset];
g_assert (bind->texture < G_N_ELEMENTS (textures));
for (guint i = 0; i < batch->draw.bind_count; i++)
{
if (textures[bind->texture] != bind->id)
{
GskGLSync *s;
if (active != bind->texture)
{
active = bind->texture;
glActiveTexture (GL_TEXTURE0 + bind->texture);
}
s = gsk_gl_syncs_get_sync (&self->syncs, bind->id);
if (s && s->sync)
{
glWaitSync ((GLsync) s->sync, 0, GL_TIMEOUT_IGNORED);
s->sync = NULL;
}
glBindTexture (GL_TEXTURE_2D, bind->id);
textures[bind->texture] = bind->id;
if (!self->has_samplers)
@@ -1234,7 +1249,8 @@ gsk_gl_command_queue_execute (GskGLCommandQueue *self,
}
glDeleteBuffers (1, &vbo_id);
glDeleteVertexArrays (1, &vao_id);
if (!gdk_gl_context_get_use_es (self->context))
glDeleteVertexArrays (1, &vao_id);
gdk_profiler_set_int_counter (self->metrics.n_binds, n_binds);
gdk_profiler_set_int_counter (self->metrics.n_uniforms, n_uniforms);
@@ -1311,6 +1327,7 @@ gsk_gl_command_queue_end_frame (GskGLCommandQueue *self)
self->batches.len = 0;
self->batch_binds.len = 0;
self->batch_uniforms.len = 0;
self->syncs.len = 0;
self->n_uploads = 0;
self->tail_batch_index = -1;
self->in_frame = FALSE;
@@ -1425,28 +1442,44 @@ gsk_gl_command_queue_create_framebuffer (GskGLCommandQueue *self)
static GdkMemoryFormat
memory_format_gl_format (GdkMemoryFormat data_format,
gboolean use_es,
guint major,
guint minor,
guint *gl_internalformat,
guint *gl_format,
guint *gl_type)
{
if (gdk_memory_format_gl_format (data_format,
use_es,
major,
minor,
gl_internalformat,
gl_format,
gl_type))
return data_format;
if (gdk_memory_format_prefers_high_depth (data_format))
{
data_format = GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED;
if (gdk_memory_format_gl_format (data_format,
use_es,
major,
minor,
gl_internalformat,
gl_format,
gl_type))
return data_format;
}
data_format = GDK_MEMORY_R8G8B8A8_PREMULTIPLIED;
if (!gdk_memory_format_gl_format (data_format,
use_es,
major,
minor,
gl_internalformat,
gl_format,
gl_type))
{
if (gdk_memory_format_prefers_high_depth (data_format))
data_format = GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED;
else
data_format = GDK_MEMORY_R8G8B8A8_PREMULTIPLIED;
if (!gdk_memory_format_gl_format (data_format,
use_es,
gl_internalformat,
gl_format,
gl_type))
{
g_assert_not_reached ();
}
g_assert_not_reached ();
}
return data_format;
@@ -1458,7 +1491,6 @@ gsk_gl_command_queue_do_upload_texture_chunk (GskGLCommandQueue *self,
int x,
int y)
{
GdkGLContext *context;
const guchar *data;
gsize stride;
GBytes *bytes;
@@ -1470,15 +1502,18 @@ gsk_gl_command_queue_do_upload_texture_chunk (GskGLCommandQueue *self,
GLenum gl_type;
gsize bpp;
gboolean use_es;
int major, minor;
context = gdk_gl_context_get_current ();
use_es = gdk_gl_context_get_use_es (context);
use_es = gdk_gl_context_get_use_es (self->context);
gdk_gl_context_get_version (self->context, &major, &minor);
data_format = gdk_texture_get_format (texture);
width = gdk_texture_get_width (texture);
height = gdk_texture_get_height (texture);
data_format = memory_format_gl_format (data_format,
use_es,
major,
minor,
&gl_internalformat,
&gl_format,
&gl_type);
@@ -1500,7 +1535,7 @@ gsk_gl_command_queue_do_upload_texture_chunk (GskGLCommandQueue *self,
glTexSubImage2D (GL_TEXTURE_2D, 0, x, y, width, height, gl_format, gl_type, data);
}
else if (stride % bpp == 0 &&
(gdk_gl_context_check_version (context, 0, 0, 3, 0) || gdk_gl_context_has_unpack_subimage (context)))
(gdk_gl_context_check_version (self->context, NULL, "3.0") || gdk_gl_context_has_unpack_subimage (self->context)))
{
glPixelStorei (GL_UNPACK_ROW_LENGTH, stride / bpp);
@@ -1532,6 +1567,7 @@ gsk_gl_command_queue_upload_texture_chunks (GskGLCommandQueue *self,
GLenum gl_type;
gboolean use_es;
int texture_id;
int major, minor;
g_assert (GSK_IS_GL_COMMAND_QUEUE (self));
@@ -1564,10 +1600,13 @@ gsk_gl_command_queue_upload_texture_chunks (GskGLCommandQueue *self,
glBindTexture (GL_TEXTURE_2D, texture_id);
/* Initialize the texture */
use_es = gdk_gl_context_get_use_es (gdk_gl_context_get_current ());
use_es = gdk_gl_context_get_use_es (self->context);
gdk_gl_context_get_version (self->context, &major, &minor);
data_format = gdk_texture_get_format (chunks[0].texture);
memory_format_gl_format (data_format,
use_es,
major,
minor,
&gl_internalformat,
&gl_format,
&gl_type);
+41
View File
@@ -168,9 +168,15 @@ typedef union _GskGLCommandBatch
G_STATIC_ASSERT (sizeof (GskGLCommandBatch) == 32);
typedef struct _GskGLSync {
guint id;
gpointer sync;
} GskGLSync;
DEFINE_INLINE_ARRAY (GskGLCommandBatches, gsk_gl_command_batches, GskGLCommandBatch)
DEFINE_INLINE_ARRAY (GskGLCommandBinds, gsk_gl_command_binds, GskGLCommandBind)
DEFINE_INLINE_ARRAY (GskGLCommandUniforms, gsk_gl_command_uniforms, GskGLCommandUniform)
DEFINE_INLINE_ARRAY (GskGLSyncs, gsk_gl_syncs, GskGLSync)
struct _GskGLCommandQueue
{
@@ -233,6 +239,10 @@ struct _GskGLCommandQueue
*/
GLuint samplers[GSK_GL_N_FILTERS * GSK_GL_N_FILTERS];
/* Array of sync objects to wait on.
*/
GskGLSyncs syncs;
/* Discovered max texture size when loading the command queue so that we
* can either scale down or slice textures to fit within this size. Assumed
* to be both height and width.
@@ -371,5 +381,36 @@ gsk_gl_command_queue_bind_framebuffer (GskGLCommandQueue *self,
return ret;
}
static inline GskGLSync *
gsk_gl_syncs_get_sync (GskGLSyncs *syncs,
guint id)
{
for (unsigned int i = 0; i < syncs->len; i++)
{
GskGLSync *sync = &syncs->items[i];
if (sync->id == id)
return sync;
}
return NULL;
}
static inline void
gsk_gl_syncs_add_sync (GskGLSyncs *syncs,
guint id,
gpointer sync)
{
GskGLSync *s;
s = gsk_gl_syncs_get_sync (syncs, id);
if (s)
g_assert (s->sync == sync);
else
{
s = gsk_gl_syncs_append (syncs);
s->id = id;
s->sync = sync;
}
}
G_END_DECLS
+36 -18
View File
@@ -1121,19 +1121,27 @@ gsk_gl_driver_lookup_shader (GskGLDriver *self,
}
#ifdef G_ENABLE_DEBUG
static void
write_atlas_to_png (GskGLDriver *driver,
GskGLTextureAtlas *atlas,
const char *filename)
void
gsk_gl_driver_save_texture_to_png (GskGLDriver *driver,
int texture_id,
int width,
int height,
const char *filename)
{
GdkGLTextureBuilder *builder;
GdkTexture *texture;
texture = gdk_gl_texture_new (gsk_gl_driver_get_context (driver),
atlas->texture_id,
atlas->width, atlas->height,
NULL, NULL);
builder = gdk_gl_texture_builder_new ();
gdk_gl_texture_builder_set_context (builder, gsk_gl_driver_get_context (driver));
gdk_gl_texture_builder_set_id (builder, texture_id);
gdk_gl_texture_builder_set_width (builder, width);
gdk_gl_texture_builder_set_height (builder, height);
texture = gdk_gl_texture_builder_build (builder, NULL, NULL);
gdk_texture_save_to_png (texture, filename);
g_object_unref (texture);
g_object_unref (builder);
}
void
@@ -1162,7 +1170,7 @@ gsk_gl_driver_save_atlases_to_png (GskGLDriver *self,
G_DIR_SEPARATOR_S,
(int)self->current_frame_id,
atlas->texture_id);
write_atlas_to_png (self, atlas, filename);
gsk_gl_driver_save_texture_to_png (self, atlas->texture_id, atlas->width, atlas->height, filename);
g_free (filename);
}
@@ -1557,6 +1565,7 @@ typedef struct _GskGLTextureState
{
GdkGLContext *context;
GLuint texture_id;
GLsync sync;
} GskGLTextureState;
static void
@@ -1569,6 +1578,8 @@ create_texture_from_texture_destroy (gpointer data)
gdk_gl_context_make_current (state->context);
glDeleteTextures (1, &state->texture_id);
if (state->sync)
glDeleteSync (state->sync);
g_clear_object (&state->context);
g_free (state);
}
@@ -1578,8 +1589,9 @@ gsk_gl_driver_create_gdk_texture (GskGLDriver *self,
guint texture_id)
{
GskGLTextureState *state;
GdkGLTextureBuilder *builder;
GskGLTexture *texture;
int width, height;
GdkTexture *result;
g_return_val_if_fail (GSK_IS_GL_DRIVER (self), NULL);
g_return_val_if_fail (self->command_queue != NULL, NULL);
@@ -1594,19 +1606,25 @@ gsk_gl_driver_create_gdk_texture (GskGLDriver *self,
state = g_new0 (GskGLTextureState, 1);
state->texture_id = texture_id;
state->context = g_object_ref (self->command_queue->context);
if (gdk_gl_context_has_sync (self->command_queue->context))
state->sync = glFenceSync (GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
g_hash_table_steal (self->textures, GUINT_TO_POINTER (texture_id));
width = texture->width;
height = texture->height;
builder = gdk_gl_texture_builder_new ();
gdk_gl_texture_builder_set_context (builder, self->command_queue->context);
gdk_gl_texture_builder_set_id (builder, texture_id);
gdk_gl_texture_builder_set_width (builder, texture->width);
gdk_gl_texture_builder_set_height (builder, texture->height);
gdk_gl_texture_builder_set_sync (builder, state->sync);
result = gdk_gl_texture_builder_build (builder,
create_texture_from_texture_destroy,
state);
texture->texture_id = 0;
gsk_gl_texture_free (texture);
g_object_unref (builder);
return gdk_gl_texture_new (self->command_queue->context,
texture_id,
width,
height,
create_texture_from_texture_destroy,
state);
return result;
}
+6 -1
View File
@@ -176,8 +176,13 @@ GskGLProgram * gsk_gl_driver_lookup_shader (GskGLDriver *s
GError **error);
#ifdef G_ENABLE_DEBUG
void gsk_gl_driver_save_texture_to_png (GskGLDriver *self,
int texture_id,
int width,
int height,
const char *filename);
void gsk_gl_driver_save_atlases_to_png (GskGLDriver *self,
const char *directory);
const char *filename);
#endif
static inline GskGLTexture *
+3 -3
View File
@@ -18,9 +18,9 @@ struct _GskGLProfiler
GLuint gl_queries[N_QUERIES];
GLuint active_query;
gboolean has_queries : 1;
gboolean has_timer : 1;
gboolean first_frame : 1;
unsigned int has_queries : 1;
unsigned int has_timer : 1;
unsigned int first_frame : 1;
};
enum {
+16
View File
@@ -285,6 +285,22 @@ gsk_gl_program_set_uniform_texture (GskGLProgram *self,
GL_LINEAR);
}
static inline void
gsk_gl_program_set_uniform_texture_with_sync (GskGLProgram *self,
guint key,
guint stamp,
GLenum texture_target,
GLenum texture_slot,
guint texture_id,
GLint min_filter,
GLint max_filter,
gpointer sync)
{
gsk_gl_program_set_uniform_texture_with_filter (self, key, stamp, texture_target, texture_slot, texture_id,
min_filter, max_filter);
gsk_gl_syncs_add_sync (&self->driver->command_queue->syncs, texture_id, sync);
}
static inline void
gsk_gl_program_set_uniform_matrix (GskGLProgram *self,
guint key,
+7 -2
View File
@@ -356,7 +356,8 @@ gsk_gl_renderer_render_texture (GskRenderer *renderer,
for (x = 0; x < width; x += max_size)
{
texture = gsk_gl_renderer_render_texture (renderer, root,
&GRAPHENE_RECT_INIT (x, y,
&GRAPHENE_RECT_INIT (viewport->origin.x + x,
viewport->origin.y + y,
MIN (max_size, viewport->size.width - x),
MIN (max_size, viewport->size.height - y)));
gdk_texture_download (texture,
@@ -372,7 +373,11 @@ gsk_gl_renderer_render_texture (GskRenderer *renderer,
return texture;
}
format = gsk_render_node_prefers_high_depth (root) ? GL_RGBA32F : GL_RGBA8;
if (gsk_render_node_prefers_high_depth (root) &&
gdk_gl_context_check_version (self->context, "3.0", "3.0"))
format = GL_RGBA32F;
else
format = GL_RGBA8;
gdk_gl_context_make_current (self->context);
+226 -184
View File
@@ -54,27 +54,6 @@
/* Make sure gradient stops fits in packed array_count */
G_STATIC_ASSERT ((MAX_GRADIENT_STOPS * 5) < (1 << GSK_GL_UNIFORM_ARRAY_BITS));
#define rounded_rect_top_left(r) \
(GRAPHENE_RECT_INIT(r->bounds.origin.x, \
r->bounds.origin.y, \
r->corner[0].width, r->corner[0].height))
#define rounded_rect_top_right(r) \
(GRAPHENE_RECT_INIT(r->bounds.origin.x + r->bounds.size.width - r->corner[1].width, \
r->bounds.origin.y, \
r->corner[1].width, r->corner[1].height))
#define rounded_rect_bottom_right(r) \
(GRAPHENE_RECT_INIT(r->bounds.origin.x + r->bounds.size.width - r->corner[2].width, \
r->bounds.origin.y + r->bounds.size.height - r->corner[2].height, \
r->corner[2].width, r->corner[2].height))
#define rounded_rect_bottom_left(r) \
(GRAPHENE_RECT_INIT(r->bounds.origin.x, \
r->bounds.origin.y + r->bounds.size.height - r->corner[2].height, \
r->corner[3].width, r->corner[3].height))
#define rounded_rect_corner0(r) rounded_rect_top_left(r)
#define rounded_rect_corner1(r) rounded_rect_top_right(r)
#define rounded_rect_corner2(r) rounded_rect_bottom_right(r)
#define rounded_rect_corner3(r) rounded_rect_bottom_left(r)
#define rounded_rect_corner(r, i) (rounded_rect_corner##i(r))
#define ALPHA_IS_CLEAR(alpha) ((alpha) < ((float) 0x00ff / (float) 0xffff))
#define RGBA_IS_CLEAR(rgba) ALPHA_IS_CLEAR((rgba)->alpha)
@@ -191,6 +170,7 @@ typedef struct _GskGLRenderOffscreen
/* Return location for texture ID */
guint texture_id;
gpointer sync;
/* Whether to force creating a new texture, even if the
* input already is a texture
@@ -255,7 +235,7 @@ gsk_rounded_rect_shrink_to_minimum (GskRoundedRect *self)
static inline gboolean G_GNUC_PURE
node_supports_2d_transform (const GskRenderNode *node)
{
switch ((int)gsk_render_node_get_node_type (node))
switch (gsk_render_node_get_node_type (node))
{
case GSK_COLOR_NODE:
case GSK_OPACITY_NODE:
@@ -273,6 +253,7 @@ node_supports_2d_transform (const GskRenderNode *node)
case GSK_CAIRO_NODE:
case GSK_BLEND_NODE:
case GSK_BLUR_NODE:
case GSK_MASK_NODE:
return TRUE;
case GSK_SHADOW_NODE:
@@ -289,8 +270,18 @@ node_supports_2d_transform (const GskRenderNode *node)
}
return TRUE;
default:
case GSK_BORDER_NODE:
case GSK_INSET_SHADOW_NODE:
case GSK_OUTSET_SHADOW_NODE:
case GSK_REPEAT_NODE:
case GSK_CLIP_NODE:
case GSK_ROUNDED_CLIP_NODE:
case GSK_GL_SHADER_NODE:
return FALSE;
case GSK_NOT_A_RENDER_NODE:
default:
g_assert_not_reached ();
}
}
@@ -304,7 +295,7 @@ node_supports_transform (const GskRenderNode *node)
* opacity or color matrix.
*/
switch ((int)gsk_render_node_get_node_type (node))
switch (gsk_render_node_get_node_type (node))
{
case GSK_COLOR_NODE:
case GSK_OPACITY_NODE:
@@ -325,8 +316,25 @@ node_supports_transform (const GskRenderNode *node)
case GSK_TRANSFORM_NODE:
return node_supports_transform (gsk_transform_node_get_child (node));
default:
case GSK_CONTAINER_NODE:
case GSK_LINEAR_GRADIENT_NODE:
case GSK_REPEATING_LINEAR_GRADIENT_NODE:
case GSK_RADIAL_GRADIENT_NODE:
case GSK_REPEATING_RADIAL_GRADIENT_NODE:
case GSK_CONIC_GRADIENT_NODE:
case GSK_BORDER_NODE:
case GSK_INSET_SHADOW_NODE:
case GSK_OUTSET_SHADOW_NODE:
case GSK_REPEAT_NODE:
case GSK_CLIP_NODE:
case GSK_ROUNDED_CLIP_NODE:
case GSK_GL_SHADER_NODE:
case GSK_TEXTURE_SCALE_NODE:
return FALSE;
case GSK_NOT_A_RENDER_NODE:
default:
g_assert_not_reached ();
}
}
@@ -400,70 +408,6 @@ rect_intersects (const graphene_rect_t *r1,
return TRUE;
}
static inline gboolean
rounded_rect_has_corner (const GskRoundedRect *r,
guint i)
{
return r->corner[i].width > 0 && r->corner[i].height > 0;
}
/* Current clip is NOT rounded but new one is definitely! */
static inline gboolean
intersect_rounded_rectilinear (const graphene_rect_t *non_rounded,
const GskRoundedRect *rounded,
GskRoundedRect *result)
{
gboolean corners[4];
/* Intersects with top left corner? */
corners[0] = rounded_rect_has_corner (rounded, 0) &&
rect_intersects (non_rounded,
&rounded_rect_corner (rounded, 0));
if (corners[0] && !rect_contains_rect (non_rounded,
&rounded_rect_corner (rounded, 0)))
return FALSE;
/* top right ? */
corners[1] = rounded_rect_has_corner (rounded, 1) &&
rect_intersects (non_rounded,
&rounded_rect_corner (rounded, 1));
if (corners[1] && !rect_contains_rect (non_rounded,
&rounded_rect_corner (rounded, 1)))
return FALSE;
/* bottom right ? */
corners[2] = rounded_rect_has_corner (rounded, 2) &&
rect_intersects (non_rounded,
&rounded_rect_corner (rounded, 2));
if (corners[2] && !rect_contains_rect (non_rounded,
&rounded_rect_corner (rounded, 2)))
return FALSE;
/* bottom left ? */
corners[3] = rounded_rect_has_corner (rounded, 3) &&
rect_intersects (non_rounded,
&rounded_rect_corner (rounded, 3));
if (corners[3] && !rect_contains_rect (non_rounded,
&rounded_rect_corner (rounded, 3)))
return FALSE;
/* We do intersect with at least one of the corners, but in such a way that the
* intersection between the two clips can still be represented by a single rounded
* rect in a trivial way. do that.
*/
graphene_rect_intersection (non_rounded, &rounded->bounds, &result->bounds);
for (guint i = 0; i < 4; i++)
{
if (corners[i])
result->corner[i] = rounded->corner[i];
else
result->corner[i].width = result->corner[i].height = 0;
}
return TRUE;
}
static inline void
init_projection_matrix (graphene_matrix_t *projection,
const graphene_rect_t *viewport)
@@ -522,13 +466,14 @@ extract_matrix_metadata (GskGLRenderModelview *modelview)
case GSK_TRANSFORM_CATEGORY_2D:
{
float xx, xy, yx, yy, dx, dy;
float skew_x, skew_y, angle, dx, dy;
gsk_transform_to_2d (modelview->transform,
&xx, &xy, &yx, &yy, &dx, &dy);
modelview->scale_x = sqrtf (xx * xx + xy * xy);
modelview->scale_y = sqrtf (yx * yx + yy * yy);
gsk_transform_to_2d_components (modelview->transform,
&skew_x, &skew_y,
&modelview->scale_x, &modelview->scale_y,
&angle, &dx, &dy);
modelview->dx = 0;
modelview->dy = 0;
}
break;
@@ -889,10 +834,10 @@ gsk_gl_render_job_untransform_bounds (GskGLRenderJob *job,
}
static inline void
gsk_gl_render_job_transform_rounded_rect (GskGLRenderJob *job,
gsk_gl_render_job_translate_rounded_rect (GskGLRenderJob *job,
const GskRoundedRect *rect,
GskRoundedRect *out_rect)
{
{
out_rect->bounds.origin.x = job->offset_x + rect->bounds.origin.x;
out_rect->bounds.origin.y = job->offset_y + rect->bounds.origin.y;
out_rect->bounds.size.width = rect->bounds.size.width;
@@ -900,6 +845,52 @@ gsk_gl_render_job_transform_rounded_rect (GskGLRenderJob *job,
memcpy (out_rect->corner, rect->corner, sizeof rect->corner);
}
static inline void
rounded_rect_scale_corners (const GskRoundedRect *rect,
GskRoundedRect *out_rect,
float scale_x,
float scale_y)
{
for (guint i = 0; i < G_N_ELEMENTS (out_rect->corner); i++)
{
out_rect->corner[i].width = rect->corner[i].width * fabs (scale_x);
out_rect->corner[i].height = rect->corner[i].height * fabs (scale_y);
}
if (scale_x < 0)
{
graphene_size_t p;
p = out_rect->corner[GSK_CORNER_TOP_LEFT];
out_rect->corner[GSK_CORNER_TOP_LEFT] = out_rect->corner[GSK_CORNER_TOP_RIGHT];
out_rect->corner[GSK_CORNER_TOP_RIGHT] = p;
p = out_rect->corner[GSK_CORNER_BOTTOM_LEFT];
out_rect->corner[GSK_CORNER_BOTTOM_LEFT] = out_rect->corner[GSK_CORNER_BOTTOM_RIGHT];
out_rect->corner[GSK_CORNER_BOTTOM_RIGHT] = p;
}
if (scale_y < 0)
{
graphene_size_t p;
p = out_rect->corner[GSK_CORNER_TOP_LEFT];
out_rect->corner[GSK_CORNER_TOP_LEFT] = out_rect->corner[GSK_CORNER_BOTTOM_LEFT];
out_rect->corner[GSK_CORNER_BOTTOM_LEFT] = p;
p = out_rect->corner[GSK_CORNER_TOP_RIGHT];
out_rect->corner[GSK_CORNER_TOP_RIGHT] = out_rect->corner[GSK_CORNER_BOTTOM_RIGHT];
out_rect->corner[GSK_CORNER_BOTTOM_RIGHT] = p;
}
}
static inline void
gsk_gl_render_job_transform_rounded_rect (GskGLRenderJob *job,
const GskRoundedRect *rect,
GskRoundedRect *out_rect)
{
gsk_gl_render_job_transform_bounds (job, &rect->bounds, &out_rect->bounds);
rounded_rect_scale_corners (rect, out_rect, job->scale_x, job->scale_y);
}
static inline void
rounded_rect_get_inner (const GskRoundedRect *rect,
graphene_rect_t *inner)
@@ -1202,13 +1193,12 @@ gsk_gl_render_job_visit_as_fallback (GskGLRenderJob *job,
{
float scale_x = job->scale_x;
float scale_y = job->scale_y;
int surface_width = ceilf (node->bounds.size.width * scale_x);
int surface_height = ceilf (node->bounds.size.height * scale_y);
int surface_width = ceilf (node->bounds.size.width * fabs (scale_x));
int surface_height = ceilf (node->bounds.size.height * fabs (scale_y));
GdkTexture *texture;
cairo_surface_t *surface;
cairo_surface_t *rendered_surface;
cairo_t *cr;
int cached_id;
int texture_id;
GskTextureKey key;
@@ -1220,18 +1210,10 @@ gsk_gl_render_job_visit_as_fallback (GskGLRenderJob *job,
key.scale_x = scale_x;
key.scale_y = scale_y;
cached_id = gsk_gl_driver_lookup_texture (job->driver, &key);
texture_id = gsk_gl_driver_lookup_texture (job->driver, &key);
if (cached_id != 0)
{
gsk_gl_render_job_begin_draw (job, CHOOSE_PROGRAM (job, blit));
gsk_gl_program_set_uniform_texture (job->current_program,
UNIFORM_SHARED_SOURCE, 0,
GL_TEXTURE_2D, GL_TEXTURE0, cached_id);
gsk_gl_render_job_draw_offscreen_rect (job, &node->bounds);
gsk_gl_render_job_end_draw (job);
return;
}
if (texture_id != 0)
goto done;
/* We first draw the recording surface on an image surface,
* just because the scaleY(-1) later otherwise screws up the
@@ -1241,7 +1223,7 @@ gsk_gl_render_job_visit_as_fallback (GskGLRenderJob *job,
surface_width,
surface_height);
cairo_surface_set_device_scale (rendered_surface, scale_x, scale_y);
cairo_surface_set_device_scale (rendered_surface, fabs (scale_x), fabs (scale_y));
cr = cairo_create (rendered_surface);
cairo_save (cr);
@@ -1255,15 +1237,16 @@ gsk_gl_render_job_visit_as_fallback (GskGLRenderJob *job,
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
surface_width,
surface_height);
cairo_surface_set_device_scale (surface, scale_x, scale_y);
cairo_surface_set_device_scale (surface, fabs (scale_x), fabs (scale_y));
cr = cairo_create (surface);
/* We draw upside down here, so it matches what GL does. */
cairo_save (cr);
cairo_scale (cr, 1, -1);
cairo_translate (cr, 0, - surface_height / scale_y);
cairo_scale (cr, scale_x < 0 ? -1 : 1, scale_y < 0 ? 1 : -1);
cairo_translate (cr, scale_x < 0 ? - surface_width / fabs (scale_x) : 0,
scale_y < 0 ? 0 : - surface_height / fabs (scale_y));
cairo_set_source_surface (cr, rendered_surface, 0, 0);
cairo_rectangle (cr, 0, 0, surface_width / scale_x, surface_height / scale_y);
cairo_rectangle (cr, 0, 0, surface_width / fabs (scale_x), surface_height / fabs (scale_y));
cairo_fill (cr);
cairo_restore (cr);
@@ -1302,6 +1285,16 @@ gsk_gl_render_job_visit_as_fallback (GskGLRenderJob *job,
gsk_gl_driver_cache_texture (job->driver, &key, texture_id);
done:
if (scale_x < 0 || scale_y < 0)
{
GskTransform *transform = gsk_transform_translate (NULL,
&GRAPHENE_POINT_INIT (scale_x < 0 ? - surface_width : 0,
scale_y < 0 ? - surface_height : 0));
gsk_gl_render_job_push_modelview (job, transform);
gsk_transform_unref (transform);
}
gsk_gl_render_job_begin_draw (job, CHOOSE_PROGRAM (job, blit));
gsk_gl_program_set_uniform_texture (job->current_program,
UNIFORM_SHARED_SOURCE, 0,
@@ -1310,6 +1303,9 @@ gsk_gl_render_job_visit_as_fallback (GskGLRenderJob *job,
texture_id);
gsk_gl_render_job_draw_offscreen_rect (job, &node->bounds);
gsk_gl_render_job_end_draw (job);
if (scale_x < 0 || scale_y < 0)
gsk_gl_render_job_pop_modelview (job);
}
static guint
@@ -1464,10 +1460,10 @@ blur_node (GskGLRenderJob *job,
offscreen->texture_id = blur_offscreen (job,
offscreen,
texture_width * scale_x,
texture_height * scale_y,
blur_radius * scale_x,
blur_radius * scale_y);
texture_width * fabs (scale_x),
texture_height * fabs (scale_y),
blur_radius * fabs (scale_x),
blur_radius * fabs (scale_y));
init_full_texture_region (offscreen);
}
@@ -1649,6 +1645,7 @@ gsk_gl_render_job_visit_clipped_child (GskGLRenderJob *job,
{
graphene_rect_t transformed_clip;
GskRoundedRect intersection;
GskRoundedRectIntersection result;
gsk_gl_render_job_transform_bounds (job, clip, &transformed_clip);
@@ -1662,10 +1659,17 @@ gsk_gl_render_job_visit_clipped_child (GskGLRenderJob *job,
gsk_gl_render_job_push_clip (job, &intersection);
gsk_gl_render_job_visit_node (job, child);
gsk_gl_render_job_pop_clip (job);
return;
}
else if (intersect_rounded_rectilinear (&transformed_clip,
&job->current_clip->rect,
&intersection))
result = gsk_rounded_rect_intersect_with_rect (&job->current_clip->rect,
&transformed_clip,
&intersection);
if (result == GSK_INTERSECTION_EMPTY)
return;
if (result == GSK_INTERSECTION_NONEMPTY)
{
gsk_gl_render_job_push_clip (job, &intersection);
gsk_gl_render_job_visit_node (job, child);
@@ -1712,28 +1716,26 @@ gsk_gl_render_job_visit_rounded_clip_node (GskGLRenderJob *job,
const GskRenderNode *child = gsk_rounded_clip_node_get_child (node);
const GskRoundedRect *clip = gsk_rounded_clip_node_get_clip (node);
GskRoundedRect transformed_clip;
float scale_x = job->scale_x;
float scale_y = job->scale_y;
gboolean need_offscreen;
if (node_is_invisible (child))
return;
gsk_gl_render_job_transform_bounds (job, &clip->bounds, &transformed_clip.bounds);
for (guint i = 0; i < G_N_ELEMENTS (transformed_clip.corner); i++)
{
transformed_clip.corner[i].width = clip->corner[i].width * scale_x;
transformed_clip.corner[i].height = clip->corner[i].height * scale_y;
}
gsk_gl_render_job_transform_rounded_rect (job, clip, &transformed_clip);
if (job->current_clip->is_rectilinear)
{
GskRoundedRect intersected_clip;
GskRoundedRectIntersection result;
if (intersect_rounded_rectilinear (&job->current_clip->rect.bounds,
&transformed_clip,
&intersected_clip))
result = gsk_rounded_rect_intersect_with_rect (&transformed_clip,
&job->current_clip->rect.bounds,
&intersected_clip);
if (result == GSK_INTERSECTION_EMPTY)
return;
if (result == GSK_INTERSECTION_NONEMPTY)
{
gsk_gl_render_job_push_clip (job, &intersected_clip);
gsk_gl_render_job_visit_node (job, child);
@@ -1748,22 +1750,13 @@ gsk_gl_render_job_visit_rounded_clip_node (GskGLRenderJob *job,
if (job->clip->len <= 1)
need_offscreen = FALSE;
else if (rounded_inner_rect_contains_rect (&job->current_clip->rect, &transformed_clip.bounds))
else if (gsk_rounded_rect_contains_rect (&job->current_clip->rect, &transformed_clip.bounds))
need_offscreen = FALSE;
else
need_offscreen = TRUE;
if (!need_offscreen)
{
/* If the new clip entirely contains the current clip, the intersection is simply
* the current clip, so we can ignore the new one.
*/
if (rounded_inner_rect_contains_rect (&transformed_clip, &job->current_clip->rect.bounds))
{
gsk_gl_render_job_visit_node (job, child);
return;
}
gsk_gl_render_job_push_clip (job, &transformed_clip);
gsk_gl_render_job_visit_node (job, child);
gsk_gl_render_job_pop_clip (job);
@@ -1885,7 +1878,7 @@ gsk_gl_render_job_visit_border_node (GskGLRenderJob *job,
sizes[3].w = MAX (widths[3], rounded_outline->corner[3].width);
}
gsk_gl_render_job_transform_rounded_rect (job, rounded_outline, &outline);
gsk_gl_render_job_translate_rounded_rect (job, rounded_outline, &outline);
gsk_gl_render_job_begin_draw (job, CHOOSE_PROGRAM (job, border));
@@ -1989,7 +1982,7 @@ gsk_gl_render_job_visit_css_background (GskGLRenderJob *job,
rgba_to_half (&gsk_border_node_get_colors (node2)[0], color);
rgba_to_half (gsk_color_node_get_color (child), color2);
gsk_gl_render_job_transform_rounded_rect (job, rounded_outline, &outline);
gsk_gl_render_job_translate_rounded_rect (job, rounded_outline, &outline);
gsk_gl_render_job_begin_draw (job, CHOOSE_PROGRAM (job, filled_border));
@@ -2130,6 +2123,7 @@ gsk_gl_render_job_visit_transform_node (GskGLRenderJob *job,
scale = gsk_transform_translate (gsk_transform_scale (NULL, sx, sy), &GRAPHENE_POINT_INIT (tx, ty));
gsk_gl_render_job_push_modelview (job, scale);
transform = gsk_transform_transform (gsk_transform_invert (scale), transform);
gsk_transform_unref (scale);
}
}
@@ -2180,7 +2174,7 @@ gsk_gl_render_job_visit_unblurred_inset_shadow_node (GskGLRenderJob *job,
GskRoundedRect transformed_outline;
guint16 color[4];
gsk_gl_render_job_transform_rounded_rect (job, outline, &transformed_outline);
gsk_gl_render_job_translate_rounded_rect (job, outline, &transformed_outline);
gsk_gl_render_job_begin_draw (job, CHOOSE_PROGRAM (job, inset_shadow));
gsk_gl_program_set_uniform_rounded_rect (job->current_program,
@@ -2280,7 +2274,7 @@ gsk_gl_render_job_visit_blurred_inset_shadow_node (GskGLRenderJob *job,
prev_fbo = gsk_gl_command_queue_bind_framebuffer (job->command_queue, render_target->framebuffer_id);
gsk_gl_command_queue_clear (job->command_queue, 0, &job->viewport);
gsk_gl_render_job_transform_rounded_rect (job, &outline_to_blur, &transformed_outline);
gsk_gl_render_job_translate_rounded_rect (job, &outline_to_blur, &transformed_outline);
/* Actual inset shadow outline drawing */
gsk_gl_render_job_begin_draw (job, CHOOSE_PROGRAM (job, inset_shadow));
@@ -2313,8 +2307,8 @@ gsk_gl_render_job_visit_blurred_inset_shadow_node (GskGLRenderJob *job,
&offscreen,
texture_width,
texture_height,
blur_radius * scale_x,
blur_radius * scale_y);
blur_radius * fabs (scale_x),
blur_radius * fabs (scale_y));
gsk_gl_driver_release_render_target (job->driver, render_target, TRUE);
@@ -2336,14 +2330,7 @@ gsk_gl_render_job_visit_blurred_inset_shadow_node (GskGLRenderJob *job,
{
GskRoundedRect node_clip;
gsk_gl_render_job_transform_bounds (job, &node_outline->bounds, &node_clip.bounds);
for (guint i = 0; i < 4; i ++)
{
node_clip.corner[i].width = node_outline->corner[i].width * scale_x;
node_clip.corner[i].height = node_outline->corner[i].height * scale_y;
}
gsk_gl_render_job_translate_rounded_rect (job, node_outline, &node_clip);
gsk_gl_render_job_push_clip (job, &node_clip);
}
@@ -2393,7 +2380,7 @@ gsk_gl_render_job_visit_unblurred_outset_shadow_node (GskGLRenderJob *job,
rgba_to_half (gsk_outset_shadow_node_get_color (node), color);
gsk_gl_render_job_transform_rounded_rect (job, outline, &transformed_outline);
gsk_gl_render_job_translate_rounded_rect (job, outline, &transformed_outline);
gsk_gl_render_job_begin_draw (job, CHOOSE_PROGRAM (job, unblurred_outset_shadow));
gsk_gl_program_set_uniform_rounded_rect (job->current_program,
@@ -2586,8 +2573,8 @@ gsk_gl_render_job_visit_blurred_outset_shadow_node (GskGLRenderJob *job,
&offscreen,
texture_width,
texture_height,
blur_radius * scale_x,
blur_radius * scale_y);
blur_radius * fabs (scale_x),
blur_radius * fabs (scale_y));
gsk_gl_shadow_library_insert (job->driver->shadows_library,
&scaled_outline,
@@ -2601,7 +2588,7 @@ gsk_gl_render_job_visit_blurred_outset_shadow_node (GskGLRenderJob *job,
blurred_texture_id = cached_tid;
}
gsk_gl_render_job_transform_rounded_rect (job, outline, &transformed_outline);
gsk_gl_render_job_translate_rounded_rect (job, outline, &transformed_outline);
if (!do_slicing)
{
@@ -2837,8 +2824,12 @@ gsk_gl_render_job_visit_cross_fade_node (GskGLRenderJob *job,
offscreen_end.reset_clip = TRUE;
offscreen_end.bounds = &node->bounds;
gsk_gl_render_job_set_modelview (job, gsk_transform_scale (NULL, fabs (job->scale_x), fabs (job->scale_y)));
if (!gsk_gl_render_job_visit_node_with_offscreen (job, start_node, &offscreen_start))
{
gsk_gl_render_job_pop_modelview (job);
gsk_gl_render_job_visit_node (job, end_node);
return;
}
@@ -2847,12 +2838,18 @@ gsk_gl_render_job_visit_cross_fade_node (GskGLRenderJob *job,
if (!gsk_gl_render_job_visit_node_with_offscreen (job, end_node, &offscreen_end))
{
float prev_alpha = gsk_gl_render_job_set_alpha (job, job->alpha * progress);
float prev_alpha;
gsk_gl_render_job_pop_modelview (job);
prev_alpha = gsk_gl_render_job_set_alpha (job, job->alpha * progress);
gsk_gl_render_job_visit_node (job, start_node);
gsk_gl_render_job_set_alpha (job, prev_alpha);
return;
}
gsk_gl_render_job_pop_modelview (job);
g_assert (offscreen_end.texture_id);
gsk_gl_render_job_begin_draw (job, CHOOSE_PROGRAM (job, cross_fade));
@@ -3246,10 +3243,14 @@ gsk_gl_render_job_visit_blend_node (GskGLRenderJob *job,
bottom_offscreen.force_offscreen = TRUE;
bottom_offscreen.reset_clip = TRUE;
gsk_gl_render_job_set_modelview (job, gsk_transform_scale (NULL, fabs (job->scale_x), fabs (job->scale_y)));
/* TODO: We create 2 textures here as big as the blend node, but both the
* start and the end node might be a lot smaller than that. */
if (!gsk_gl_render_job_visit_node_with_offscreen (job, bottom_child, &bottom_offscreen))
{
gsk_gl_render_job_pop_modelview (job);
gsk_gl_render_job_visit_node (job, top_child);
return;
}
@@ -3258,6 +3259,8 @@ gsk_gl_render_job_visit_blend_node (GskGLRenderJob *job,
if (!gsk_gl_render_job_visit_node_with_offscreen (job, top_child, &top_offscreen))
{
gsk_gl_render_job_pop_modelview (job);
gsk_gl_render_job_begin_draw (job, CHOOSE_PROGRAM (job, blit));
gsk_gl_program_set_uniform_texture (job->current_program,
UNIFORM_SHARED_SOURCE, 0,
@@ -3271,6 +3274,8 @@ gsk_gl_render_job_visit_blend_node (GskGLRenderJob *job,
g_assert (top_offscreen.was_offscreen);
gsk_gl_render_job_pop_modelview (job);
gsk_gl_render_job_begin_draw (job, CHOOSE_PROGRAM (job, blend));
gsk_gl_program_set_uniform_texture (job->current_program,
UNIFORM_SHARED_SOURCE, 0,
@@ -3307,11 +3312,14 @@ gsk_gl_render_job_visit_mask_node (GskGLRenderJob *job,
mask_offscreen.reset_clip = TRUE;
mask_offscreen.do_not_cache = TRUE;
gsk_gl_render_job_set_modelview (job, gsk_transform_scale (NULL, fabs (job->scale_x), fabs (job->scale_y)));
/* TODO: We create 2 textures here as big as the mask node, but both
* nodes might be a lot smaller than that.
*/
if (!gsk_gl_render_job_visit_node_with_offscreen (job, source, &source_offscreen))
{
gsk_gl_render_job_pop_modelview (job);
gsk_gl_render_job_visit_node (job, source);
return;
}
@@ -3320,11 +3328,14 @@ gsk_gl_render_job_visit_mask_node (GskGLRenderJob *job,
if (!gsk_gl_render_job_visit_node_with_offscreen (job, mask, &mask_offscreen))
{
gsk_gl_render_job_pop_modelview (job);
return;
}
g_assert (mask_offscreen.was_offscreen);
gsk_gl_render_job_pop_modelview (job);
gsk_gl_render_job_begin_draw (job, CHOOSE_PROGRAM (job, mask));
gsk_gl_program_set_uniform_texture (job->current_program,
UNIFORM_SHARED_SOURCE, 0,
@@ -3542,6 +3553,9 @@ gsk_gl_render_job_upload_texture (GskGLRenderJob *job,
offscreen->texture_id = gsk_gl_driver_load_texture (job->driver, texture, ensure_mipmap);
init_full_texture_region (offscreen);
offscreen->has_mipmap = ensure_mipmap;
if (gl_texture && offscreen->texture_id == gdk_gl_texture_get_id (gl_texture))
offscreen->sync = gdk_gl_texture_get_sync (gl_texture);
}
}
@@ -3555,8 +3569,8 @@ gsk_gl_render_job_visit_texture (GskGLRenderJob *job,
float scale_y = bounds->size.height / texture->height;
gboolean use_mipmap;
use_mipmap = (scale_x * job->scale_x) < 0.5 ||
(scale_y * job->scale_y) < 0.5;
use_mipmap = (scale_x * fabs (job->scale_x)) < 0.5 ||
(scale_y * fabs (job->scale_y)) < 0.5;
if G_LIKELY (texture->width <= max_texture_size &&
texture->height <= max_texture_size)
@@ -3569,13 +3583,15 @@ gsk_gl_render_job_visit_texture (GskGLRenderJob *job,
g_assert (offscreen.was_offscreen == FALSE);
gsk_gl_render_job_begin_draw (job, CHOOSE_PROGRAM (job, blit));
gsk_gl_program_set_uniform_texture_with_filter (job->current_program,
UNIFORM_SHARED_SOURCE, 0,
GL_TEXTURE_2D,
GL_TEXTURE0,
offscreen.texture_id,
offscreen.has_mipmap ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR,
GL_LINEAR);
gsk_gl_program_set_uniform_texture_with_sync (job->current_program,
UNIFORM_SHARED_SOURCE, 0,
GL_TEXTURE_2D,
GL_TEXTURE0,
offscreen.texture_id,
offscreen.has_mipmap ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR,
GL_LINEAR,
offscreen.sync);
gsk_gl_render_job_draw_offscreen (job, bounds, &offscreen);
gsk_gl_render_job_end_draw (job);
}
@@ -3705,21 +3721,29 @@ gsk_gl_render_job_visit_texture_scale_node (GskGLRenderJob *job,
if G_LIKELY (texture->width <= max_texture_size &&
texture->height <= max_texture_size)
{
gpointer sync;
texture_id = gsk_gl_driver_load_texture (job->driver, texture, filter == GSK_SCALING_FILTER_TRILINEAR);
if (GDK_IS_GL_TEXTURE (texture) && texture_id == gdk_gl_texture_get_id (GDK_GL_TEXTURE (texture)))
sync = gdk_gl_texture_get_sync (GDK_GL_TEXTURE (texture));
else
sync = NULL;
u0 = (clip_rect.origin.x - bounds->origin.x) / bounds->size.width;
v0 = (clip_rect.origin.y - bounds->origin.y) / bounds->size.height;
u1 = (clip_rect.origin.x + clip_rect.size.width - bounds->origin.x) / bounds->size.width;
v1 = (clip_rect.origin.y + clip_rect.size.height - bounds->origin.y) / bounds->size.height;
gsk_gl_render_job_begin_draw (job, CHOOSE_PROGRAM (job, blit));
gsk_gl_program_set_uniform_texture_with_filter (job->current_program,
UNIFORM_SHARED_SOURCE, 0,
GL_TEXTURE_2D,
GL_TEXTURE0,
texture_id,
min_filter,
mag_filter);
gsk_gl_program_set_uniform_texture_with_sync (job->current_program,
UNIFORM_SHARED_SOURCE, 0,
GL_TEXTURE_2D,
GL_TEXTURE0,
texture_id,
min_filter,
mag_filter,
sync);
gsk_gl_render_job_draw_coords (job,
0, 0, clip_rect.size.width, clip_rect.size.height,
u0, v0, u1, v1,
@@ -4078,7 +4102,7 @@ gsk_gl_render_job_visit_node_with_offscreen (GskGLRenderJob *job,
}
if (gsk_render_node_get_node_type (node) == GSK_TEXTURE_NODE &&
offscreen->force_offscreen == FALSE)
!offscreen->force_offscreen)
{
GdkTexture *texture = gsk_texture_node_get_texture (node);
gsk_gl_render_job_upload_texture (job, texture, FALSE, offscreen);
@@ -4096,6 +4120,7 @@ gsk_gl_render_job_visit_node_with_offscreen (GskGLRenderJob *job,
gboolean flipped_x = job->scale_x < 0;
gboolean flipped_y = job->scale_y < 0;
graphene_rect_t viewport;
gboolean reset_clip = FALSE;
if (flipped_x || flipped_y)
{
@@ -4103,6 +4128,7 @@ gsk_gl_render_job_visit_node_with_offscreen (GskGLRenderJob *job,
flipped_x ? -1 : 1,
flipped_y ? -1 : 1);
gsk_gl_render_job_push_modelview (job, transform);
gsk_transform_unref (transform);
}
gsk_gl_render_job_transform_bounds (job, offscreen->bounds, &viewport);
@@ -4140,7 +4166,9 @@ gsk_gl_render_job_visit_node_with_offscreen (GskGLRenderJob *job,
{
GskTransform *transform = gsk_transform_scale (NULL, downscale_x, downscale_y);
gsk_gl_render_job_push_modelview (job, transform);
gsk_transform_unref (transform);
gsk_gl_render_job_transform_bounds (job, offscreen->bounds, &viewport);
graphene_rect_scale (&viewport, downscale_x, downscale_y, &viewport);
}
if (downscale_x == 1)
@@ -4224,11 +4252,25 @@ gsk_gl_render_job_visit_node_with_offscreen (GskGLRenderJob *job,
gsk_gl_command_queue_clear (job->command_queue, 0, &job->viewport);
if (offscreen->reset_clip)
gsk_gl_render_job_push_clip (job, &GSK_ROUNDED_RECT_INIT_FROM_RECT (job->viewport));
{
gsk_gl_render_job_push_clip (job, &GSK_ROUNDED_RECT_INIT_FROM_RECT (job->viewport));
reset_clip = TRUE;
}
else if (flipped_x || flipped_y || downscale_x != 1 || downscale_y != 1)
{
GskRoundedRect new_clip;
float scale_x = flipped_x ? - downscale_x : downscale_x;
float scale_y = flipped_y ? - downscale_y : downscale_y;
graphene_rect_scale (&job->current_clip->rect.bounds, scale_x, scale_y, &new_clip.bounds);
rounded_rect_scale_corners (&job->current_clip->rect, &new_clip, scale_x, scale_y);
gsk_gl_render_job_push_clip (job, &new_clip);
reset_clip = TRUE;
}
gsk_gl_render_job_visit_node (job, node);
if (offscreen->reset_clip)
if (reset_clip)
gsk_gl_render_job_pop_clip (job);
if (downscale_x != 1 || downscale_y != 1)
@@ -4380,7 +4422,7 @@ get_framebuffer_format (GdkGLContext *context,
{
int size;
if (!gdk_gl_context_check_version (context, 0, 0, 3, 0))
if (!gdk_gl_context_check_version (context, NULL, "3.0"))
return GL_RGBA8;
glBindFramebuffer (GL_FRAMEBUFFER, framebuffer);
+6 -4
View File
@@ -19,6 +19,9 @@ void main() {
gsk_rounded_rect_transform(outside, u_modelview);
gsk_rounded_rect_transform(inside, u_modelview);
gsk_rounded_rect_normalize(outside);
gsk_rounded_rect_normalize(inside);
gsk_rounded_rect_encode(outside, transformed_outside_outline);
gsk_rounded_rect_encode(inside, transformed_inside_outline);
}
@@ -34,10 +37,9 @@ _IN_ _GSK_ROUNDED_RECT_UNIFORM_ transformed_inside_outline;
void main() {
vec2 frag = gsk_get_frag_coord();
float alpha = clamp(gsk_rounded_rect_coverage(gsk_decode_rect(transformed_outside_outline), frag) -
gsk_rounded_rect_coverage(gsk_decode_rect(transformed_inside_outline), frag),
0.0, 1.0);
float outer_coverage = gsk_rounded_rect_coverage(gsk_decode_rect(transformed_outside_outline), frag);
float inner_coverage = gsk_rounded_rect_coverage(gsk_decode_rect(transformed_inside_outline), frag);
float alpha = clamp(outer_coverage - inner_coverage, 0.0, 1.0);
gskSetScaledOutputColor(final_color, alpha);
}
+3
View File
@@ -21,6 +21,9 @@ void main() {
gsk_rounded_rect_transform(outside, u_modelview);
gsk_rounded_rect_transform(inside, u_modelview);
gsk_rounded_rect_normalize(outside);
gsk_rounded_rect_normalize(inside);
gsk_rounded_rect_encode(outside, transformed_outside_outline);
gsk_rounded_rect_encode(inside, transformed_inside_outline);
}
+3
View File
@@ -22,6 +22,9 @@ void main() {
gsk_rounded_rect_transform(outside, u_modelview);
gsk_rounded_rect_transform(inside, u_modelview);
gsk_rounded_rect_normalize(outside);
gsk_rounded_rect_normalize(inside);
gsk_rounded_rect_encode(outside, transformed_outside_outline);
gsk_rounded_rect_encode(inside, transformed_inside_outline);
}

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