Compare commits
479 Commits
foreach-ap
...
subsurface
Author | SHA1 | Date | |
---|---|---|---|
|
a77fde155d | ||
|
004c2b8cc2 | ||
|
0605888ac6 | ||
|
ef5b1ba044 | ||
|
5fa7457171 | ||
|
f50edb6910 | ||
|
2d874e601c | ||
|
c9b83dfa1d | ||
|
dd7a38069f | ||
|
51a181af7a | ||
|
8fcd9bc0c4 | ||
|
e2edf693f5 | ||
|
323300e92a | ||
|
e688be1cff | ||
|
611d5cf844 | ||
|
51cb1aeb4e | ||
|
625eb508e8 | ||
|
2718e1715d | ||
|
6ddcad6b33 | ||
|
0c23997f70 | ||
|
4d1ef63009 | ||
|
30e14f73fa | ||
|
39e205aa78 | ||
|
f0ec1660c1 | ||
|
79f98f3a13 | ||
|
5f0557027d | ||
|
a579e3bc6d | ||
|
8f70f4b85e | ||
|
911198cddd | ||
|
ca5247a995 | ||
|
004a881521 | ||
|
65993ed0e0 | ||
|
a4d0a5bda5 | ||
|
33bc276639 | ||
|
06822581f7 | ||
|
976143fbe9 | ||
|
9fd4feef0c | ||
|
5eed13bd07 | ||
|
d02d45dd8d | ||
|
13d0e311b7 | ||
|
52254f755f | ||
|
494154beb6 | ||
|
adde188eca | ||
|
8fb0ab2b43 | ||
|
b8b5835fc6 | ||
|
463307655c | ||
|
d17d8e04a6 | ||
|
d8d1dfd8f3 | ||
|
f581280811 | ||
|
3a9aea44df | ||
|
e05764806a | ||
|
5ca65f04fe | ||
|
32ba1e389c | ||
|
beb9e0c906 | ||
|
98f02f6221 | ||
|
13848969f4 | ||
|
0817dfe67f | ||
|
9e3f537a15 | ||
|
612e0e29f9 | ||
|
e1cbc96b8c | ||
|
410240fe7b | ||
|
73cf3a92f9 | ||
|
dd15122ccb | ||
|
5299f1384f | ||
|
58a0e4ffaa | ||
|
7ab9056c11 | ||
|
2d9fbb16bc | ||
|
cbfd8542c6 | ||
|
7679504134 | ||
|
446d461ad2 | ||
|
5b6fcfe8c9 | ||
|
59ce7ab222 | ||
|
0992837b08 | ||
|
aca02916ad | ||
|
98e883f9b4 | ||
|
2c66aa0c15 | ||
|
8843c0d504 | ||
|
8858f1c9ec | ||
|
a1c5c20e2c | ||
|
1da674423d | ||
|
10250a0a6a | ||
|
c0a2f9fbc3 | ||
|
bd974b08b3 | ||
|
d289c0d4f1 | ||
|
f4722289f7 | ||
|
389af3591c | ||
|
008d9e5327 | ||
|
09723d79c6 | ||
|
4586af5876 | ||
|
193d9cd31a | ||
|
f29303dea7 | ||
|
4e47d0d71e | ||
|
dd8c6e9f51 | ||
|
65676150c4 | ||
|
b0e26873f6 | ||
|
f4a67ebcbb | ||
|
000c876953 | ||
|
b8ffceaebb | ||
|
148b8e5cd8 | ||
|
583ad47b03 | ||
|
b95d8ebdd3 | ||
|
677a601d11 | ||
|
194db51fba | ||
|
d55fa0dfef | ||
|
612b5416af | ||
|
54637ae3b3 | ||
|
014adb841e | ||
|
a5c6a40b3c | ||
|
402a51b876 | ||
|
d1e091279c | ||
|
7325121c63 | ||
|
31abe56b7a | ||
|
ca3fd16039 | ||
|
4417509515 | ||
|
9dc2e554e5 | ||
|
bfb01f5a4b | ||
|
570e80a9ff | ||
|
6d90d25a74 | ||
|
a7f6e65291 | ||
|
59641b3c7b | ||
|
2f842b087c | ||
|
699f6a7993 | ||
|
f04ba3bc60 | ||
|
09aac114d4 | ||
|
9132600e1f | ||
|
5dcd6c7e12 | ||
|
9f8d34ab01 | ||
|
7a4580fa89 | ||
|
45a7617cc8 | ||
|
57d8cc08a3 | ||
|
1ca067a478 | ||
|
7a13e4f9b9 | ||
|
d101e17608 | ||
|
203a4fc45e | ||
|
a9823e05bb | ||
|
6f5833df28 | ||
|
5631ab6711 | ||
|
62fedf4eed | ||
|
c274d073e0 | ||
|
8dda753505 | ||
|
4e66df79c4 | ||
|
71c7e61162 | ||
|
e39ecbf16d | ||
|
0dbd2bd09e | ||
|
1297cc188d | ||
|
e584d17aad | ||
|
4936965fb6 | ||
|
e9cc53796e | ||
|
c93efe85dd | ||
|
44daa847ff | ||
|
d23e13aced | ||
|
40102a2b61 | ||
|
49fbbfb6cc | ||
|
fefd856d67 | ||
|
39dab6d7bd | ||
|
7b5b78b065 | ||
|
005b5042f6 | ||
|
b5149a483f | ||
|
15c43e5284 | ||
|
fc4c0f769c | ||
|
e8ecbb2009 | ||
|
964affb1cc | ||
|
05b51af2d5 | ||
|
28e51c763b | ||
|
ebf8e18319 | ||
|
d8bbe1c296 | ||
|
c1417d3d4a | ||
|
3b4359d76d | ||
|
16806294e3 | ||
|
822425072b | ||
|
7cc1283a26 | ||
|
f4198706d1 | ||
|
8478ba66fe | ||
|
1d58de6ffb | ||
|
f5cec5c0f2 | ||
|
368f2af634 | ||
|
66a9fee071 | ||
|
6e0ac83d99 | ||
|
12ad6b3157 | ||
|
fda9fd5ced | ||
|
029ce83a69 | ||
|
5ced6be416 | ||
|
bbda833b01 | ||
|
c86bc00330 | ||
|
68755c0fd2 | ||
|
9090c28125 | ||
|
3a3244891e | ||
|
b55117334c | ||
|
02e5c7b9ad | ||
|
7268167f4c | ||
|
93c7502cf7 | ||
|
789705cfe4 | ||
|
741471a1f8 | ||
|
f8da751cc2 | ||
|
8174842d9f | ||
|
e872952f36 | ||
|
b010e46d13 | ||
|
eb646a8e8b | ||
|
1e2975147d | ||
|
653c10e8b6 | ||
|
dfbafdf047 | ||
|
d8c821a851 | ||
|
83376648d7 | ||
|
089c34fa03 | ||
|
c846f8d745 | ||
|
79ebd76ac8 | ||
|
6eb9836eb0 | ||
|
4a8f8a6eea | ||
|
3ea723730b | ||
|
90be2baf8b | ||
|
0b64fa88a1 | ||
|
c6cc446e63 | ||
|
0cad37760e | ||
|
e720008dca | ||
|
9c636a6136 | ||
|
1e24aa425e | ||
|
a8c597005a | ||
|
97a781b380 | ||
|
313cadefe6 | ||
|
9f078bd5c9 | ||
|
8ff4e27103 | ||
|
8389ca633d | ||
|
18fbec0fe1 | ||
|
eb0a00067d | ||
|
91216408e5 | ||
|
6da5b8cb25 | ||
|
7bee7bf5fc | ||
|
fac66ade01 | ||
|
96eae5f62e | ||
|
1cc99847f4 | ||
|
d8b14cd3e3 | ||
|
0c80eb5afb | ||
|
fdcb1d92c5 | ||
|
d65dc6c730 | ||
|
c721c4d6ef | ||
|
1a7ba3c512 | ||
|
25ee1a7784 | ||
|
0b2cebe3d8 | ||
|
5dd0d39a6b | ||
|
9f3ff427c1 | ||
|
14e60d21ac | ||
|
65c3796135 | ||
|
25acc26531 | ||
|
859bf8b15d | ||
|
e0bf96f329 | ||
|
11c5ea1fec | ||
|
bc063350ef | ||
|
347b0317e5 | ||
|
72d832a4f3 | ||
|
76df3ade18 | ||
|
d849a53b98 | ||
|
ef6d3af6b9 | ||
|
f513914306 | ||
|
7135f80094 | ||
|
ef82e0ce4e | ||
|
1910834f8f | ||
|
f94a0624fa | ||
|
4c46f5a8f7 | ||
|
17c59d6da6 | ||
|
56c0aa596e | ||
|
a1c73a9b2e | ||
|
cac0cb7f02 | ||
|
7eb999720a | ||
|
05e15241b4 | ||
|
a730867778 | ||
|
8513621709 | ||
|
14d99bacbc | ||
|
cbbd3e8fc3 | ||
|
8fa45d5fef | ||
|
3e1706679c | ||
|
7f359e31c6 | ||
|
e4af2c4d80 | ||
|
2d121c07c9 | ||
|
cc904698a6 | ||
|
a5fdd1228f | ||
|
271d7632cb | ||
|
a8613377a5 | ||
|
d7cf5c2b1b | ||
|
95865cb1bf | ||
|
0b813de72a | ||
|
9c159cf129 | ||
|
957d494090 | ||
|
968b4237a9 | ||
|
f67c57b1f8 | ||
|
84f8c2d91d | ||
|
8f1d8d7cb5 | ||
|
e98d9d62eb | ||
|
5a0b65c611 | ||
|
5777587e7a | ||
|
ecfc661054 | ||
|
e00722dee6 | ||
|
5af21e70ec | ||
|
7e13cfea91 | ||
|
68b4d9c35e | ||
|
1f3b69e7db | ||
|
ca63552cf8 | ||
|
a6d2d983b8 | ||
|
7cd97192e5 | ||
|
8ac8bca52a | ||
|
cf8f6d254e | ||
|
a267dfac5d | ||
|
745b28ef38 | ||
|
5c27899efa | ||
|
fd006592b5 | ||
|
201f27fe19 | ||
|
36c4dc8aea | ||
|
f0bd0c3e50 | ||
|
4d71ff6da1 | ||
|
6d16776e27 | ||
|
7cdff6bbb3 | ||
|
bf43859bdc | ||
|
4b45f8415f | ||
|
86e0d5c13e | ||
|
d21ee115d0 | ||
|
2dd8e3b0eb | ||
|
6d001f79f9 | ||
|
eb6ca8f39a | ||
|
abebd92b19 | ||
|
014ca76334 | ||
|
a520f9fcf7 | ||
|
de724b2a57 | ||
|
061637f4eb | ||
|
dab1897d4e | ||
|
9ebb030c78 | ||
|
93477ec019 | ||
|
f2a71898b1 | ||
|
24048dce43 | ||
|
41af8ee2e2 | ||
|
60c20fa6ed | ||
|
5152c13081 | ||
|
e9089f65e3 | ||
|
9aaec91f95 | ||
|
1c971c595f | ||
|
f8627755b5 | ||
|
55ae8dc39e | ||
|
dd7d145249 | ||
|
0b2c249de3 | ||
|
ea6b95f60d | ||
|
ed44f37de4 | ||
|
3780a5ed6a | ||
|
fec3f0191a | ||
|
359fa99945 | ||
|
5441ed2227 | ||
|
ec1a1d0e34 | ||
|
8f4fb45715 | ||
|
9db2288064 | ||
|
1502c21e97 | ||
|
408dd4b34d | ||
|
609e1f54ef | ||
|
f49d0fbbf6 | ||
|
dde47b7966 | ||
|
f84da62740 | ||
|
cbfbe6dc23 | ||
|
2c63a34791 | ||
|
9ab07553a3 | ||
|
c29fb838e9 | ||
|
aecc76d916 | ||
|
713a5188cf | ||
|
911f3bf555 | ||
|
c752598a3d | ||
|
9dfdb1b65b | ||
|
a05a021fd1 | ||
|
9ffd7840ba | ||
|
dd64084b44 | ||
|
21277a37d6 | ||
|
ddc7e36543 | ||
|
f429dff03e | ||
|
6f07c6a3f1 | ||
|
4cb4aa1029 | ||
|
cecab7801e | ||
|
ea7fd1ff5a | ||
|
ad474a60c0 | ||
|
1e8e7e0c00 | ||
|
1e9e8d24c3 | ||
|
9bd9b6f2ca | ||
|
913a6ddcc9 | ||
|
31da6f60d0 | ||
|
c4c118e425 | ||
|
02599acf4d | ||
|
6a653e4675 | ||
|
29e92d6a0e | ||
|
b4fcc8b5f0 | ||
|
b00333c603 | ||
|
63614727a3 | ||
|
061a56d213 | ||
|
3f63ba36ce | ||
|
d9b96c34be | ||
|
39a8c64624 | ||
|
360b77cc50 | ||
|
1186eff1b7 | ||
|
0b8582ccba | ||
|
dc2914e1f9 | ||
|
a0d8678a9c | ||
|
c8a43da526 | ||
|
90ee05ae64 | ||
|
67a7602080 | ||
|
37db270d19 | ||
|
f3312f677b | ||
|
05547d98d6 | ||
|
11b219bc61 | ||
|
5721c3cb8f | ||
|
f90ca697af | ||
|
7a0e27b6e8 | ||
|
e81aa18c82 | ||
|
827bbc0cc1 | ||
|
7095a67910 | ||
|
dcbca3f0d7 | ||
|
702d7c238a | ||
|
5a3ed65ad8 | ||
|
2e24a9ece4 | ||
|
2a17320314 | ||
|
0dbff14555 | ||
|
c5d89d00f1 | ||
|
6f3be310f4 | ||
|
0ea6b70d55 | ||
|
2ca9982b91 | ||
|
a40282b2fb | ||
|
ad9fb1e101 | ||
|
02a9652af4 | ||
|
6f823d2d0d | ||
|
a5c9cd5657 | ||
|
21ab5b6fa3 | ||
|
2582fd45e4 | ||
|
0a28a5d53a | ||
|
ddd4855bbc | ||
|
204216e3d5 | ||
|
1e6a124665 | ||
|
78c5aff956 | ||
|
8d1844135b | ||
|
b5dd9dae0d | ||
|
ebcb518e4f | ||
|
b7ea22f168 | ||
|
f0b3381660 | ||
|
0796c72049 | ||
|
822e988efe | ||
|
cee043f977 | ||
|
b420540b15 | ||
|
031c0ec3e5 | ||
|
43b6822eb0 | ||
|
ba3a657c48 | ||
|
5f2f116c28 | ||
|
1db75e521d | ||
|
2297a353b8 | ||
|
80903e5f44 | ||
|
7342ce5bca | ||
|
167b38dfa1 | ||
|
ead88c36ec | ||
|
b8a3d7fa00 | ||
|
0fce24674a | ||
|
739084e9bc | ||
|
99ad585252 | ||
|
949b6692ac | ||
|
eb0479d8ed | ||
|
6defdb4e8a | ||
|
9fdad6d4ee | ||
|
b6e285844f | ||
|
c989a06718 | ||
|
1c8bd8658d | ||
|
ab50cba4e9 | ||
|
57918813e2 | ||
|
a4df8d8818 | ||
|
4b00cfc1ce | ||
|
889688c978 | ||
|
0bf1ae033d | ||
|
994afcaeed | ||
|
b69cc832ef | ||
|
ca188b41ae | ||
|
81c8d1dd28 | ||
|
32d00ca9ed | ||
|
01b9997590 | ||
|
677e19042d | ||
|
bd79f61cc5 | ||
|
361cdecfe4 | ||
|
2782daadb4 | ||
|
81821978ae | ||
|
ae7ec40cf2 | ||
|
8aaecc3416 | ||
|
afbcbb8404 | ||
|
5c00dc7ef4 |
@@ -207,9 +207,7 @@ msys2-mingw64:
|
|||||||
|
|
||||||
macos-x86_64:
|
macos-x86_64:
|
||||||
rules:
|
rules:
|
||||||
# run merge request pipelines
|
# Do not run in forks as the runner is not available there.
|
||||||
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
|
|
||||||
# do not run in forks
|
|
||||||
- if: $CI_PROJECT_NAMESPACE == "GNOME"
|
- if: $CI_PROJECT_NAMESPACE == "GNOME"
|
||||||
stage: build
|
stage: build
|
||||||
tags:
|
tags:
|
||||||
@@ -219,25 +217,32 @@ macos-x86_64:
|
|||||||
MESON_FORCE_BACKTRACKE: 1
|
MESON_FORCE_BACKTRACKE: 1
|
||||||
TMPDIR: /Users/Shared/work/tmp
|
TMPDIR: /Users/Shared/work/tmp
|
||||||
SDKROOT: /opt/sdks/MacOSX10.13.4.sdk
|
SDKROOT: /opt/sdks/MacOSX10.13.4.sdk
|
||||||
CCACHE_DIR: /Users/Shared/work/ccache
|
|
||||||
PIP_CACHE_DIR: /Users/Shared/build/cache
|
PIP_CACHE_DIR: /Users/Shared/build/cache
|
||||||
PIPENV_CACHE_DIR: $PIP_CACHE_DIR
|
PIPENV_CACHE_DIR: $PIP_CACHE_DIR
|
||||||
PYTHONPYCACHEPREFIX: $PIP_CACHE_DIR
|
PYTHONPYCACHEPREFIX: $PIP_CACHE_DIR
|
||||||
|
EXTRA_MESON_FLAGS: "-Dgobject-introspection:werror=false"
|
||||||
before_script:
|
before_script:
|
||||||
|
# Not using ccache on purpose as it accelerates the build so much that it
|
||||||
|
# can trigger race conditions in the gobject-introspection subproject.
|
||||||
- bash .gitlab-ci/show-info-osx.sh
|
- bash .gitlab-ci/show-info-osx.sh
|
||||||
- python3 -m venv .venv
|
- /opt/macports/bin/python3.10 -m venv .venv
|
||||||
- ln -s /opt/cmake/CMake.app/Contents/bin/cmake .venv/bin
|
- ln -s /opt/cmake/CMake.app/Contents/bin/cmake .venv/bin
|
||||||
- ln -s /opt/ccache/ccache .venv/bin
|
- ln -s /opt/pkg-config/bin/pkg-config .venv/bin
|
||||||
|
- ln -s /opt/bison/bin/bison .venv/bin
|
||||||
- source .venv/bin/activate
|
- source .venv/bin/activate
|
||||||
- pip3 install meson==1.2.0
|
- pip3 install meson==1.2.0
|
||||||
- pip3 install ninja==1.11.1
|
- pip3 install ninja==1.11.1
|
||||||
|
- pip3 install /Users/Shared/build/pkgs/PyGObject-3.44.0-cp310-cp310-macosx_10_13_x86_64.whl
|
||||||
|
/Users/Shared/build/pkgs/pycairo-1.23.0-cp310-cp310-macosx_10_13_x86_64.whl
|
||||||
script:
|
script:
|
||||||
- meson setup ${COMMON_MESON_FLAGS}
|
- meson setup
|
||||||
|
${COMMON_MESON_FLAGS}
|
||||||
|
${EXTRA_MESON_FLAGS}
|
||||||
-Dx11-backend=false
|
-Dx11-backend=false
|
||||||
-Dbroadway-backend=true
|
-Dbroadway-backend=true
|
||||||
-Dmacos-backend=true
|
-Dmacos-backend=true
|
||||||
-Dmedia-gstreamer=disabled
|
-Dmedia-gstreamer=disabled
|
||||||
-Dintrospection=disabled
|
-Dintrospection=enabled
|
||||||
-Dcpp_std=c++11
|
-Dcpp_std=c++11
|
||||||
-Dpixman:tests=disabled
|
-Dpixman:tests=disabled
|
||||||
-Dlibjpeg-turbo:simd=disabled
|
-Dlibjpeg-turbo:simd=disabled
|
||||||
|
@@ -23,6 +23,7 @@ case "${backend}" in
|
|||||||
--suite=gtk \
|
--suite=gtk \
|
||||||
--no-suite=failing \
|
--no-suite=failing \
|
||||||
--no-suite=flaky \
|
--no-suite=flaky \
|
||||||
|
--no-suite=headless \
|
||||||
--no-suite=gsk-compare-broadway
|
--no-suite=gsk-compare-broadway
|
||||||
|
|
||||||
# Store the exit code for the CI run, but always
|
# Store the exit code for the CI run, but always
|
||||||
@@ -45,6 +46,7 @@ case "${backend}" in
|
|||||||
--suite=gtk \
|
--suite=gtk \
|
||||||
--no-suite=failing \
|
--no-suite=failing \
|
||||||
--no-suite=flaky \
|
--no-suite=flaky \
|
||||||
|
--no-suite=headless \
|
||||||
--no-suite=${backend}_failing \
|
--no-suite=${backend}_failing \
|
||||||
--no-suite=gsk-compare-broadway
|
--no-suite=gsk-compare-broadway
|
||||||
exit_code=$?
|
exit_code=$?
|
||||||
@@ -67,6 +69,7 @@ case "${backend}" in
|
|||||||
--suite=gtk \
|
--suite=gtk \
|
||||||
--no-suite=failing \
|
--no-suite=failing \
|
||||||
--no-suite=flaky \
|
--no-suite=flaky \
|
||||||
|
--no-suite=headless \
|
||||||
--no-suite=gsk-compare-opengl
|
--no-suite=gsk-compare-opengl
|
||||||
|
|
||||||
kill ${server}
|
kill ${server}
|
||||||
|
@@ -35,8 +35,7 @@ The issue tracker is meant to be used for actionable issues only.
|
|||||||
|
|
||||||
You should not open a new issue for security related questions.
|
You should not open a new issue for security related questions.
|
||||||
|
|
||||||
When in doubt, send an email to the [security](mailto:security@gnome.org)
|
When in doubt, follow [security](https://security.gnome.org/).
|
||||||
mailing list.
|
|
||||||
|
|
||||||
### Bug reports
|
### Bug reports
|
||||||
|
|
||||||
@@ -244,13 +243,11 @@ people committing to GTK to follow a few rules:
|
|||||||
code, you should always ask. If your change is minor and you've been
|
code, you should always ask. If your change is minor and you've been
|
||||||
working on GTK for a while it probably isn't necessary to ask. But when
|
working on GTK for a while it probably isn't necessary to ask. But when
|
||||||
in doubt, ask. Even if your change is correct, somebody may know a
|
in doubt, ask. Even if your change is correct, somebody may know a
|
||||||
better way to do things. If you are making changes to GTK, you should
|
better way to do things.
|
||||||
be subscribed to the [gtk-devel](https://mail.gnome.org/mailman/listinfo/gtk-devel-list)
|
The `gtk` [room on matrix](https://matrix.to/#/#gtk:gnome.org) is also a
|
||||||
mailing list; this is a good place to ask about intended changes.
|
good place to find GTK developers to discuss changes, but if you live
|
||||||
The `#gtk` IRC channel on irc.gnome.org is also a good place to find GTK
|
outside of the EU/US time zones, the [gtk tag on the GNOME Discourse instance](https://discourse.gnome.org/tag/gtk)
|
||||||
developers to discuss changes, but if you live outside of the EU/US time
|
is the most certain and preferred method.
|
||||||
zones, an email to the gtk-devel mailing list is the most certain and
|
|
||||||
preferred method.
|
|
||||||
|
|
||||||
0. Ask _first_.
|
0. Ask _first_.
|
||||||
|
|
||||||
|
194
NEWS
@@ -1,6 +1,198 @@
|
|||||||
Overview of Changes in 4.13.0, xx-xx-xxxx
|
Overview of Changes in 4.13.3, xx-xx-xxxx
|
||||||
=========================================
|
=========================================
|
||||||
|
|
||||||
|
Overview of Changes in 4.13.2, 22-10-2023
|
||||||
|
=========================================
|
||||||
|
|
||||||
|
* GtkPrintdialog:
|
||||||
|
- New async-style api to replace GtkPrintOperation
|
||||||
|
|
||||||
|
* GtkEmojiChooser:
|
||||||
|
- Add more languages: Bengali, Hindi, Japanese, Finnish,
|
||||||
|
Thai and Norwegian bokmål
|
||||||
|
|
||||||
|
* Accessibility:
|
||||||
|
- Fix some utf8 handling issues
|
||||||
|
|
||||||
|
* GDK:
|
||||||
|
- Add support for dmabuf textures, with GdkDmabufTextureBuilder
|
||||||
|
- Add a few more supported memory formats for textures
|
||||||
|
|
||||||
|
* GSK:
|
||||||
|
- Add a fast-path for masking color
|
||||||
|
- Add support for importing dmabuf textures
|
||||||
|
- Handle GLES better by using some extensions
|
||||||
|
|
||||||
|
* Translation updates:
|
||||||
|
Catalan
|
||||||
|
Russian
|
||||||
|
Turkish
|
||||||
|
|
||||||
|
|
||||||
|
Overview of Changes in 4.13.1, 28-09-2023
|
||||||
|
=========================================
|
||||||
|
|
||||||
|
* GtkTooltip:
|
||||||
|
- Don't cross native boundaries when looking for tooltips
|
||||||
|
|
||||||
|
* GtkCenterLayout, GtkEntry, GtkSearchEntry:
|
||||||
|
- Fix some issues with baseline handling
|
||||||
|
|
||||||
|
* GtkColorButton, GtkFontButton:
|
||||||
|
- Propagate focus-on-click
|
||||||
|
|
||||||
|
* GtkFileChooser:
|
||||||
|
- Make "Visit file" scroll to the file
|
||||||
|
|
||||||
|
* GtkSwitch:
|
||||||
|
- Respect text direction
|
||||||
|
|
||||||
|
* GtkWindow:
|
||||||
|
- Don't assume titlebars are GtkHeaderBars
|
||||||
|
|
||||||
|
* Printing:
|
||||||
|
- Fix some problems with the portal implementation
|
||||||
|
- Add a new simple print API: GtkPrintDialog
|
||||||
|
|
||||||
|
* Paths:
|
||||||
|
- GskPathMeasure performance has been improved
|
||||||
|
- Add custom contours for circles, rounded rectangles and rectangles
|
||||||
|
- Simplify GskPathPoint handling
|
||||||
|
- gsk_path_point_get_closest_point now returns the distance as well
|
||||||
|
- Make GskPathBuilder simplify curves
|
||||||
|
|
||||||
|
* Input:
|
||||||
|
- Handle (some) single-key compose sequences
|
||||||
|
- Fix active state tracking with sensitivity changes and grabs
|
||||||
|
|
||||||
|
* GSK:
|
||||||
|
- Make the repeated gradients match between GL and cairo
|
||||||
|
- Make rounded rect shrinking match between Vulkan, GL and cairo
|
||||||
|
- Fix parsing of text nodes with color glyphs
|
||||||
|
- Restrict an optimization to the cases where it is crrect
|
||||||
|
- Fix rendering of shadows with opacity
|
||||||
|
- The Vulkan renderer now requires Vulkan 1.2
|
||||||
|
- GL: Transition gradients unpremultiplied
|
||||||
|
- GL: Fix clipping of shadows
|
||||||
|
- GL: Some optimizations
|
||||||
|
- Broadway: Fix memory leaks in the renderer
|
||||||
|
|
||||||
|
* Wayland:
|
||||||
|
- Make activation more reliable
|
||||||
|
|
||||||
|
* macOS:
|
||||||
|
- Clamp damage regions to the surface size
|
||||||
|
|
||||||
|
* Tools:
|
||||||
|
- gtk4-path-tool gained restrict and reverse commands
|
||||||
|
- gtk4-path-tool show and render can show control points
|
||||||
|
|
||||||
|
* Demos:
|
||||||
|
- Add a demo for hit testing with paths
|
||||||
|
|
||||||
|
* Build:
|
||||||
|
- Fix build problems with C++ compilers
|
||||||
|
|
||||||
|
* Deprecations:
|
||||||
|
- gtk_window_present_with_time
|
||||||
|
|
||||||
|
* Translation updates
|
||||||
|
Brazilian Portuguese
|
||||||
|
British English
|
||||||
|
Catalan
|
||||||
|
Chinese (China)
|
||||||
|
Czech
|
||||||
|
Danish
|
||||||
|
Dutch
|
||||||
|
Esperanto
|
||||||
|
Galician
|
||||||
|
Georgian
|
||||||
|
Italian
|
||||||
|
Korean
|
||||||
|
Latvian
|
||||||
|
Lithuanian
|
||||||
|
Persian
|
||||||
|
Polish
|
||||||
|
Punjabi
|
||||||
|
Slovenian
|
||||||
|
Turkish
|
||||||
|
|
||||||
|
|
||||||
|
Overview of Changes in 4.13.0, 25-08-2023
|
||||||
|
=========================================
|
||||||
|
|
||||||
|
* GskPath, GskPathBuilder, GskPathMeasure:
|
||||||
|
Data types and APIs for path rendering. These APIs are still
|
||||||
|
considered experimental, and may change until 4.14. Please try
|
||||||
|
them out and give us feedback. Documentation can be found
|
||||||
|
here: https://docs.gtk.org/gsk4/paths.html
|
||||||
|
|
||||||
|
* GtkGridView:
|
||||||
|
- Fix a crash when scrolling
|
||||||
|
|
||||||
|
* GtkColumnView:
|
||||||
|
- Fix a refcounting issue in the new scroll_to api
|
||||||
|
|
||||||
|
* GtkTreeView
|
||||||
|
- Fix style classes for sort arrows
|
||||||
|
|
||||||
|
* GtkEntry:
|
||||||
|
- Improve tracking of user changes (for undo)
|
||||||
|
|
||||||
|
* GtkNotebook:
|
||||||
|
- Fix a critical when switching pages
|
||||||
|
|
||||||
|
* GtkColor/FontDialogButton:
|
||||||
|
- Make these widgets activatable
|
||||||
|
|
||||||
|
* GtkMenuButton:
|
||||||
|
- Fix problems with focus handling
|
||||||
|
- Fix problems with DND
|
||||||
|
- Make flags a settable property
|
||||||
|
|
||||||
|
* GtkShortcutsWindow:
|
||||||
|
- Add API to build shortcuts windows programmatically
|
||||||
|
|
||||||
|
* Printing
|
||||||
|
- Fix the cpdb backend build
|
||||||
|
|
||||||
|
* MacOS:
|
||||||
|
- Make file filters work again
|
||||||
|
|
||||||
|
* GSK:
|
||||||
|
- Fix issues with color matrix nodes
|
||||||
|
|
||||||
|
* Wayland:
|
||||||
|
- Fix a crash with compositors other than gnome-shell
|
||||||
|
|
||||||
|
* Deprecations:
|
||||||
|
- Remaining GtkTreeModel-related types
|
||||||
|
|
||||||
|
* Demos:
|
||||||
|
- Add a few path demos to gtk4-demo
|
||||||
|
|
||||||
|
* Tools:
|
||||||
|
- gtk4-path-tool provides a commandline interface for paths
|
||||||
|
|
||||||
|
* Translation updates:
|
||||||
|
Basque
|
||||||
|
Catalan
|
||||||
|
Finnish
|
||||||
|
Galician
|
||||||
|
Georgian
|
||||||
|
German
|
||||||
|
Greek
|
||||||
|
Indonesian
|
||||||
|
Kazakh
|
||||||
|
Persian
|
||||||
|
Polish
|
||||||
|
Romanian
|
||||||
|
Spanish
|
||||||
|
Swedish
|
||||||
|
Turkish
|
||||||
|
Ukrainian
|
||||||
|
|
||||||
|
|
||||||
Overview of Changes in 4.12.0, 05-08-2023
|
Overview of Changes in 4.12.0, 05-08-2023
|
||||||
=========================================
|
=========================================
|
||||||
|
|
||||||
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.8 KiB |
@@ -223,7 +223,7 @@ delete_messages (gpointer data)
|
|||||||
static void
|
static void
|
||||||
pop_message (GtkWidget *status)
|
pop_message (GtkWidget *status)
|
||||||
{
|
{
|
||||||
GList *messages = (GList *) g_object_get_data (G_OBJECT (status), "messages");
|
GList *messages = (GList *) g_object_steal_data (G_OBJECT (status), "messages");
|
||||||
|
|
||||||
if (messages)
|
if (messages)
|
||||||
{
|
{
|
||||||
@@ -241,7 +241,7 @@ static void
|
|||||||
push_message (GtkWidget *status,
|
push_message (GtkWidget *status,
|
||||||
const char *message)
|
const char *message)
|
||||||
{
|
{
|
||||||
GList *messages = (GList *) g_object_get_data (G_OBJECT (status), "messages");
|
GList *messages = (GList *) g_object_steal_data (G_OBJECT (status), "messages");
|
||||||
|
|
||||||
gtk_label_set_label (GTK_LABEL (status), message);
|
gtk_label_set_label (GTK_LABEL (status), message);
|
||||||
messages = g_list_prepend (messages, g_strdup (message));
|
messages = g_list_prepend (messages, g_strdup (message));
|
||||||
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 985 B After Width: | Height: | Size: 1019 B |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
@@ -127,6 +127,7 @@
|
|||||||
<file>fishbowl.ui</file>
|
<file>fishbowl.ui</file>
|
||||||
<file>gtkfishbowl.c</file>
|
<file>gtkfishbowl.c</file>
|
||||||
<file>gtkfishbowl.h</file>
|
<file>gtkfishbowl.h</file>
|
||||||
|
<file>tiger.node</file>
|
||||||
</gresource>
|
</gresource>
|
||||||
<gresource prefix="/frames">
|
<gresource prefix="/frames">
|
||||||
<file>frames.ui</file>
|
<file>frames.ui</file>
|
||||||
@@ -336,6 +337,7 @@
|
|||||||
<file>panes.c</file>
|
<file>panes.c</file>
|
||||||
<file>password_entry.c</file>
|
<file>password_entry.c</file>
|
||||||
<file>path_fill.c</file>
|
<file>path_fill.c</file>
|
||||||
|
<file>path_maze.c</file>
|
||||||
<file>path_spinner.c</file>
|
<file>path_spinner.c</file>
|
||||||
<file>path_walk.c</file>
|
<file>path_walk.c</file>
|
||||||
<file>path_text.c</file>
|
<file>path_text.c</file>
|
||||||
|
@@ -34,7 +34,7 @@ transition (GtkWidget *widget,
|
|||||||
{
|
{
|
||||||
DemoWidget *self = DEMO_WIDGET (widget);
|
DemoWidget *self = DEMO_WIDGET (widget);
|
||||||
DemoLayout *demo_layout = DEMO_LAYOUT (gtk_widget_get_layout_manager (widget));
|
DemoLayout *demo_layout = DEMO_LAYOUT (gtk_widget_get_layout_manager (widget));
|
||||||
gint64 now = g_get_monotonic_time ();
|
gint64 now = gdk_frame_clock_get_frame_time (frame_clock);
|
||||||
|
|
||||||
gtk_widget_queue_allocate (widget);
|
gtk_widget_queue_allocate (widget);
|
||||||
|
|
||||||
@@ -66,11 +66,13 @@ clicked (GtkGestureClick *gesture,
|
|||||||
gpointer data)
|
gpointer data)
|
||||||
{
|
{
|
||||||
DemoWidget *self = data;
|
DemoWidget *self = data;
|
||||||
|
GdkFrameClock *frame_clock;
|
||||||
|
|
||||||
if (self->tick_id != 0)
|
if (self->tick_id != 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
self->start_time = g_get_monotonic_time ();
|
frame_clock = gtk_widget_get_frame_clock (GTK_WIDGET (self));
|
||||||
|
self->start_time = gdk_frame_clock_get_frame_time (frame_clock);
|
||||||
self->tick_id = gtk_widget_add_tick_callback (GTK_WIDGET (self), transition, NULL, NULL);
|
self->tick_id = gtk_widget_add_tick_callback (GTK_WIDGET (self), transition, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.5 KiB |
@@ -11,6 +11,9 @@
|
|||||||
#include "gtkgears.h"
|
#include "gtkgears.h"
|
||||||
#include "gskshaderpaintable.h"
|
#include "gskshaderpaintable.h"
|
||||||
|
|
||||||
|
#include "nodewidget.h"
|
||||||
|
#include "graphwidget.h"
|
||||||
|
|
||||||
const char *const css =
|
const char *const css =
|
||||||
".blurred-button {"
|
".blurred-button {"
|
||||||
" box-shadow: 0px 0px 5px 10px rgba(0, 0, 0, 0.5);"
|
" box-shadow: 0px 0px 5px 10px rgba(0, 0, 0, 0.5);"
|
||||||
@@ -71,14 +74,7 @@ create_blurred_button (void)
|
|||||||
static GtkWidget *
|
static GtkWidget *
|
||||||
create_font_button (void)
|
create_font_button (void)
|
||||||
{
|
{
|
||||||
GtkFontDialog *dialog;
|
return gtk_font_dialog_button_new (gtk_font_dialog_new ());
|
||||||
GtkWidget *button;
|
|
||||||
|
|
||||||
dialog = gtk_font_dialog_new ();
|
|
||||||
button = gtk_font_dialog_button_new (dialog);
|
|
||||||
g_object_unref (dialog);
|
|
||||||
|
|
||||||
return button;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static GtkWidget *
|
static GtkWidget *
|
||||||
@@ -208,6 +204,18 @@ create_menu_button (void)
|
|||||||
return w;
|
return w;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GtkWidget *
|
||||||
|
create_tiger (void)
|
||||||
|
{
|
||||||
|
return node_widget_new ("/fishbowl/tiger.node");
|
||||||
|
}
|
||||||
|
|
||||||
|
static GtkWidget *
|
||||||
|
create_graph (void)
|
||||||
|
{
|
||||||
|
return graph_widget_new ();
|
||||||
|
}
|
||||||
|
|
||||||
static const struct {
|
static const struct {
|
||||||
const char *name;
|
const char *name;
|
||||||
GtkWidget * (*create_func) (void);
|
GtkWidget * (*create_func) (void);
|
||||||
@@ -225,6 +233,8 @@ static const struct {
|
|||||||
{ "Switch", create_switch },
|
{ "Switch", create_switch },
|
||||||
{ "Menubutton", create_menu_button },
|
{ "Menubutton", create_menu_button },
|
||||||
{ "Shader", create_cogs },
|
{ "Shader", create_cogs },
|
||||||
|
{ "Tiger", create_tiger },
|
||||||
|
{ "Graph", create_graph },
|
||||||
};
|
};
|
||||||
|
|
||||||
static int selected_widget_type = -1;
|
static int selected_widget_type = -1;
|
||||||
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
153
demos/gtk-demo/graphwidget.c
Normal file
@@ -0,0 +1,153 @@
|
|||||||
|
#include "graphwidget.h"
|
||||||
|
|
||||||
|
struct _GraphWidget
|
||||||
|
{
|
||||||
|
GtkWidget parent_instance;
|
||||||
|
|
||||||
|
GskPath *path;
|
||||||
|
GskStroke *stroke;
|
||||||
|
GdkRGBA color;
|
||||||
|
|
||||||
|
guint tick_cb;
|
||||||
|
guint64 start_time;
|
||||||
|
|
||||||
|
double period;
|
||||||
|
double amplitude;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _GraphWidgetClass
|
||||||
|
{
|
||||||
|
GtkWidgetClass parent_class;
|
||||||
|
};
|
||||||
|
|
||||||
|
G_DEFINE_TYPE (GraphWidget, graph_widget, GTK_TYPE_WIDGET)
|
||||||
|
|
||||||
|
static void
|
||||||
|
update_path (GraphWidget *self,
|
||||||
|
float amplitude)
|
||||||
|
{
|
||||||
|
graphene_point_t p[20];
|
||||||
|
GskPathBuilder *builder;
|
||||||
|
|
||||||
|
g_clear_pointer (&self->path, gsk_path_unref);
|
||||||
|
|
||||||
|
for (int i = 0; i < 20; i++)
|
||||||
|
{
|
||||||
|
p[i].x = 10 * i;
|
||||||
|
p[i].y = 50;
|
||||||
|
|
||||||
|
if (i % 4 == 1 || i % 4 == 2)
|
||||||
|
{
|
||||||
|
if (i % 8 < 4)
|
||||||
|
p[i].y += amplitude;
|
||||||
|
else
|
||||||
|
p[i].y -= amplitude;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
builder = gsk_path_builder_new ();
|
||||||
|
gsk_path_builder_move_to (builder, p[0].x, p[0].y);
|
||||||
|
|
||||||
|
for (int i = 0; i < 20; i += 4)
|
||||||
|
gsk_path_builder_cubic_to (builder,
|
||||||
|
p[i+1].x, p[i+1].y,
|
||||||
|
p[i+2].x, p[i+2].y,
|
||||||
|
p[i+3].x, p[i+3].y);
|
||||||
|
|
||||||
|
self->path = gsk_path_builder_free_to_path (builder);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
tick_cb (GtkWidget *widget,
|
||||||
|
GdkFrameClock *frame_clock,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
GraphWidget *self = GRAPH_WIDGET (widget);
|
||||||
|
guint64 now;
|
||||||
|
double angle;
|
||||||
|
|
||||||
|
now = gdk_frame_clock_get_frame_time (frame_clock);
|
||||||
|
|
||||||
|
if (self->start_time == 0)
|
||||||
|
self->start_time = now;
|
||||||
|
|
||||||
|
angle = 360 * (now - self->start_time) / (double)(self->period * G_TIME_SPAN_MINUTE);
|
||||||
|
update_path (self, sin (angle) * self->amplitude);
|
||||||
|
|
||||||
|
gtk_widget_queue_draw (widget);
|
||||||
|
|
||||||
|
return G_SOURCE_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
graph_widget_init (GraphWidget *self)
|
||||||
|
{
|
||||||
|
self->color.red = g_random_double_range (0, 1);
|
||||||
|
self->color.green = g_random_double_range (0, 1);
|
||||||
|
self->color.blue = g_random_double_range (0, 1);
|
||||||
|
self->color.alpha = 1;
|
||||||
|
|
||||||
|
self->period = g_random_double_range (0.5, 1);
|
||||||
|
self->amplitude = g_random_double_range (10, 25);
|
||||||
|
|
||||||
|
self->stroke = gsk_stroke_new (2);
|
||||||
|
|
||||||
|
update_path (self, 0);
|
||||||
|
|
||||||
|
self->start_time = 0;
|
||||||
|
self->tick_cb = gtk_widget_add_tick_callback (GTK_WIDGET (self), tick_cb, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
graph_widget_dispose (GObject *object)
|
||||||
|
{
|
||||||
|
GraphWidget *self = GRAPH_WIDGET (object);
|
||||||
|
|
||||||
|
g_clear_pointer (&self->path, gsk_path_unref);
|
||||||
|
gsk_stroke_free (self->stroke);
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (graph_widget_parent_class)->dispose (object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
graph_widget_snapshot (GtkWidget *widget,
|
||||||
|
GtkSnapshot *snapshot)
|
||||||
|
{
|
||||||
|
GraphWidget *self = GRAPH_WIDGET (widget);
|
||||||
|
|
||||||
|
gtk_snapshot_append_stroke (snapshot, self->path, self->stroke, &self->color);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
graph_widget_measure (GtkWidget *widget,
|
||||||
|
GtkOrientation orientation,
|
||||||
|
int for_size,
|
||||||
|
int *minimum,
|
||||||
|
int *natural,
|
||||||
|
int *minimum_baseline,
|
||||||
|
int *natural_baseline)
|
||||||
|
{
|
||||||
|
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||||
|
*minimum = *natural = 200;
|
||||||
|
else
|
||||||
|
*minimum = *natural = 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
graph_widget_class_init (GraphWidgetClass *class)
|
||||||
|
{
|
||||||
|
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||||
|
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
|
||||||
|
|
||||||
|
object_class->dispose = graph_widget_dispose;
|
||||||
|
|
||||||
|
widget_class->snapshot = graph_widget_snapshot;
|
||||||
|
widget_class->measure = graph_widget_measure;
|
||||||
|
}
|
||||||
|
|
||||||
|
GtkWidget *
|
||||||
|
graph_widget_new (void)
|
||||||
|
{
|
||||||
|
return g_object_new (GRAPH_TYPE_WIDGET, NULL);
|
||||||
|
}
|
8
demos/gtk-demo/graphwidget.h
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
|
#define GRAPH_TYPE_WIDGET (graph_widget_get_type ())
|
||||||
|
G_DECLARE_FINAL_TYPE (GraphWidget, graph_widget, GRAPH, WIDGET, GtkWidget)
|
||||||
|
|
||||||
|
GtkWidget * graph_widget_new (void);
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.8 KiB |
@@ -73,6 +73,7 @@ demos = files([
|
|||||||
'panes.c',
|
'panes.c',
|
||||||
'password_entry.c',
|
'password_entry.c',
|
||||||
'path_fill.c',
|
'path_fill.c',
|
||||||
|
'path_maze.c',
|
||||||
'path_spinner.c',
|
'path_spinner.c',
|
||||||
'path_walk.c',
|
'path_walk.c',
|
||||||
'path_text.c',
|
'path_text.c',
|
||||||
@@ -140,6 +141,8 @@ extra_demo_sources = files([
|
|||||||
'unicode-names.c',
|
'unicode-names.c',
|
||||||
'suggestionentry.c',
|
'suggestionentry.c',
|
||||||
'language-names.c',
|
'language-names.c',
|
||||||
|
'nodewidget.c',
|
||||||
|
'graphwidget.c',
|
||||||
])
|
])
|
||||||
|
|
||||||
if os_unix
|
if os_unix
|
||||||
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.7 KiB |
76
demos/gtk-demo/nodewidget.c
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
#include "nodewidget.h"
|
||||||
|
|
||||||
|
struct _NodeWidget
|
||||||
|
{
|
||||||
|
GtkWidget parent_instance;
|
||||||
|
|
||||||
|
GskRenderNode *node;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _NodeWidgetClass
|
||||||
|
{
|
||||||
|
GtkWidgetClass parent_class;
|
||||||
|
};
|
||||||
|
|
||||||
|
G_DEFINE_TYPE (NodeWidget, node_widget, GTK_TYPE_WIDGET)
|
||||||
|
|
||||||
|
static void
|
||||||
|
node_widget_init (NodeWidget *self)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
node_widget_dispose (GObject *object)
|
||||||
|
{
|
||||||
|
NodeWidget *self = NODE_WIDGET (object);
|
||||||
|
|
||||||
|
gsk_render_node_unref (self->node);
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (node_widget_parent_class)->dispose (object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
node_widget_snapshot (GtkWidget *widget,
|
||||||
|
GtkSnapshot *snapshot)
|
||||||
|
{
|
||||||
|
NodeWidget *self = NODE_WIDGET (widget);
|
||||||
|
|
||||||
|
gtk_snapshot_append_node (snapshot, self->node);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
node_widget_class_init (NodeWidgetClass *class)
|
||||||
|
{
|
||||||
|
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||||
|
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
|
||||||
|
|
||||||
|
object_class->dispose = node_widget_dispose;
|
||||||
|
|
||||||
|
widget_class->snapshot = node_widget_snapshot;
|
||||||
|
}
|
||||||
|
|
||||||
|
GtkWidget *
|
||||||
|
node_widget_new (const char *resource)
|
||||||
|
{
|
||||||
|
NodeWidget *self;
|
||||||
|
GBytes *bytes;
|
||||||
|
GskRenderNode *node;
|
||||||
|
graphene_rect_t bounds;
|
||||||
|
float scale;
|
||||||
|
GskTransform *transform;
|
||||||
|
|
||||||
|
self = g_object_new (NODE_TYPE_WIDGET, NULL);
|
||||||
|
|
||||||
|
bytes = g_resources_lookup_data (resource, 0, NULL);
|
||||||
|
node = gsk_render_node_deserialize (bytes, NULL, NULL);
|
||||||
|
g_bytes_unref (bytes);
|
||||||
|
|
||||||
|
gsk_render_node_get_bounds (node, &bounds);
|
||||||
|
scale = MIN (100.0/bounds.size.width, 100.0/bounds.size.height);
|
||||||
|
transform = gsk_transform_scale (NULL, scale, scale);
|
||||||
|
self->node = gsk_transform_node_new (node, transform);
|
||||||
|
gsk_transform_unref (transform);
|
||||||
|
gsk_render_node_unref (node);
|
||||||
|
|
||||||
|
return GTK_WIDGET (self);
|
||||||
|
}
|
8
demos/gtk-demo/nodewidget.h
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
|
#define NODE_TYPE_WIDGET (node_widget_get_type ())
|
||||||
|
G_DECLARE_FINAL_TYPE (NodeWidget, node_widget, NODE, WIDGET, GtkWidget)
|
||||||
|
|
||||||
|
GtkWidget * node_widget_new (const char *file);
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.3 KiB |
@@ -2,10 +2,13 @@
|
|||||||
*
|
*
|
||||||
* This demo shows how to use GskPath to draw shapes that are (a bit)
|
* This demo shows how to use GskPath to draw shapes that are (a bit)
|
||||||
* more complex than a rounded rectangle.
|
* more complex than a rounded rectangle.
|
||||||
|
*
|
||||||
|
* It also demonstrates printing to a stream with GtkPrintDialog.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <glib/gi18n.h>
|
#include <glib/gi18n.h>
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
|
#include <cairo-pdf.h>
|
||||||
|
|
||||||
#include "paintable.h"
|
#include "paintable.h"
|
||||||
|
|
||||||
@@ -165,6 +168,89 @@ gtk_logo_paintable_new (void)
|
|||||||
return GDK_PAINTABLE (self);
|
return GDK_PAINTABLE (self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static cairo_status_t
|
||||||
|
write_cairo (void *closure,
|
||||||
|
const unsigned char *data,
|
||||||
|
unsigned int length)
|
||||||
|
{
|
||||||
|
GOutputStream *stream = closure;
|
||||||
|
gsize written;
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
if (!g_output_stream_write_all (stream, data, length, &written, NULL, &error))
|
||||||
|
{
|
||||||
|
g_print ("Error writing pdf stream: %s\n", error->message);
|
||||||
|
g_error_free (error);
|
||||||
|
return CAIRO_STATUS_WRITE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return CAIRO_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
print_ready (GObject *source,
|
||||||
|
GAsyncResult *result,
|
||||||
|
gpointer data)
|
||||||
|
{
|
||||||
|
GtkPrintDialog *dialog = GTK_PRINT_DIALOG (source);
|
||||||
|
GError *error = NULL;
|
||||||
|
GOutputStream *stream;
|
||||||
|
GtkSnapshot *snapshot;
|
||||||
|
GdkPaintable *paintable;
|
||||||
|
GskRenderNode *node;
|
||||||
|
cairo_surface_t *surface;
|
||||||
|
cairo_t *cr;
|
||||||
|
|
||||||
|
stream = gtk_print_dialog_print_finish (dialog, result, &error);
|
||||||
|
if (stream == NULL)
|
||||||
|
{
|
||||||
|
g_print ("Failed to get output stream: %s\n", error->message);
|
||||||
|
g_error_free (error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
snapshot = gtk_snapshot_new ();
|
||||||
|
paintable = gtk_picture_get_paintable (GTK_PICTURE (data));
|
||||||
|
gdk_paintable_snapshot (paintable, snapshot, 100, 100);
|
||||||
|
node = gtk_snapshot_free_to_node (snapshot);
|
||||||
|
|
||||||
|
surface = cairo_pdf_surface_create_for_stream (write_cairo, stream, 100, 100);
|
||||||
|
cr = cairo_create (surface);
|
||||||
|
|
||||||
|
gsk_render_node_draw (node, cr);
|
||||||
|
|
||||||
|
cairo_destroy (cr);
|
||||||
|
cairo_surface_destroy (surface);
|
||||||
|
gsk_render_node_unref (node);
|
||||||
|
|
||||||
|
if (!g_output_stream_close (stream, NULL, &error))
|
||||||
|
{
|
||||||
|
g_print ("Error from close: %s\n", error->message);
|
||||||
|
g_error_free (error);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_object_unref (stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
print (GtkButton *button,
|
||||||
|
gpointer data)
|
||||||
|
{
|
||||||
|
GtkWidget *picture = data;
|
||||||
|
GtkPrintDialog *dialog;
|
||||||
|
|
||||||
|
dialog = gtk_print_dialog_new ();
|
||||||
|
|
||||||
|
gtk_print_dialog_print (dialog,
|
||||||
|
GTK_WINDOW (gtk_widget_get_root (picture)),
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
print_ready,
|
||||||
|
picture);
|
||||||
|
|
||||||
|
g_object_unref (dialog);
|
||||||
|
}
|
||||||
|
|
||||||
GtkWidget *
|
GtkWidget *
|
||||||
do_path_fill (GtkWidget *do_widget)
|
do_path_fill (GtkWidget *do_widget)
|
||||||
{
|
{
|
||||||
@@ -172,12 +258,21 @@ do_path_fill (GtkWidget *do_widget)
|
|||||||
|
|
||||||
if (!window)
|
if (!window)
|
||||||
{
|
{
|
||||||
|
GtkWidget *header, *button, *label;
|
||||||
GtkWidget *picture;
|
GtkWidget *picture;
|
||||||
GdkPaintable *paintable;
|
GdkPaintable *paintable;
|
||||||
|
|
||||||
window = gtk_window_new ();
|
window = gtk_window_new ();
|
||||||
gtk_window_set_resizable (GTK_WINDOW (window), TRUE);
|
gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
|
||||||
|
gtk_window_set_default_size (GTK_WINDOW (window), 100, 100);
|
||||||
gtk_window_set_title (GTK_WINDOW (window), "Fill and Stroke");
|
gtk_window_set_title (GTK_WINDOW (window), "Fill and Stroke");
|
||||||
|
header = gtk_header_bar_new ();
|
||||||
|
button = gtk_button_new_from_icon_name ("printer-symbolic");
|
||||||
|
gtk_header_bar_pack_start (GTK_HEADER_BAR (header), button);
|
||||||
|
label = gtk_label_new ("Fill and Stroke");
|
||||||
|
gtk_widget_add_css_class (label, "title");
|
||||||
|
gtk_header_bar_set_title_widget (GTK_HEADER_BAR (header), label);
|
||||||
|
gtk_window_set_titlebar (GTK_WINDOW (window), header);
|
||||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
||||||
|
|
||||||
paintable = gtk_logo_paintable_new ();
|
paintable = gtk_logo_paintable_new ();
|
||||||
@@ -186,6 +281,8 @@ do_path_fill (GtkWidget *do_widget)
|
|||||||
gtk_picture_set_can_shrink (GTK_PICTURE (picture), FALSE);
|
gtk_picture_set_can_shrink (GTK_PICTURE (picture), FALSE);
|
||||||
g_object_unref (paintable);
|
g_object_unref (paintable);
|
||||||
|
|
||||||
|
g_signal_connect (button, "clicked", G_CALLBACK (print), picture);
|
||||||
|
|
||||||
gtk_window_set_child (GTK_WINDOW (window), picture);
|
gtk_window_set_child (GTK_WINDOW (window), picture);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
369
demos/gtk-demo/path_maze.c
Normal file
@@ -0,0 +1,369 @@
|
|||||||
|
/* Path/Maze
|
||||||
|
*
|
||||||
|
* This demo shows how to use a GskPath to create a maze and use
|
||||||
|
* gsk_path_get_closest_point() to check the mouse stays
|
||||||
|
* on the path.
|
||||||
|
*
|
||||||
|
* It also shows off the performance of GskPath (or not) as this
|
||||||
|
* is a rather complex path.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
#include <glib/gi18n.h>
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
|
#include "paintable.h"
|
||||||
|
|
||||||
|
#define MAZE_GRID_SIZE 20
|
||||||
|
#define MAZE_STROKE_SIZE_ACTIVE (MAZE_GRID_SIZE - 4)
|
||||||
|
#define MAZE_STROKE_SIZE_INACTIVE (MAZE_GRID_SIZE - 12)
|
||||||
|
#define MAZE_WIDTH 31
|
||||||
|
#define MAZE_HEIGHT 21
|
||||||
|
|
||||||
|
#define GTK_TYPE_MAZE (gtk_maze_get_type ())
|
||||||
|
G_DECLARE_FINAL_TYPE (GtkMaze, gtk_maze, GTK, MAZE, GtkWidget)
|
||||||
|
|
||||||
|
struct _GtkMaze
|
||||||
|
{
|
||||||
|
GtkWidget parent_instance;
|
||||||
|
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
GskPath *path;
|
||||||
|
GskPathMeasure *measure;
|
||||||
|
GdkPaintable *background;
|
||||||
|
|
||||||
|
gboolean active;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _GtkMazeClass
|
||||||
|
{
|
||||||
|
GtkWidgetClass parent_class;
|
||||||
|
};
|
||||||
|
|
||||||
|
G_DEFINE_TYPE (GtkMaze, gtk_maze, GTK_TYPE_WIDGET)
|
||||||
|
|
||||||
|
static void
|
||||||
|
gtk_maze_measure (GtkWidget *widget,
|
||||||
|
GtkOrientation orientation,
|
||||||
|
int for_size,
|
||||||
|
int *minimum,
|
||||||
|
int *natural,
|
||||||
|
int *minimum_baseline,
|
||||||
|
int *natural_baseline)
|
||||||
|
{
|
||||||
|
GtkMaze *self = GTK_MAZE (widget);
|
||||||
|
|
||||||
|
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||||
|
*minimum = *natural = self->width;
|
||||||
|
else
|
||||||
|
*minimum = *natural = self->height;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gtk_maze_snapshot (GtkWidget *widget,
|
||||||
|
GdkSnapshot *snapshot)
|
||||||
|
{
|
||||||
|
GtkMaze *self = GTK_MAZE (widget);
|
||||||
|
double width = gtk_widget_get_width (widget);
|
||||||
|
double height = gtk_widget_get_height (widget);
|
||||||
|
GskStroke *stroke;
|
||||||
|
|
||||||
|
stroke = gsk_stroke_new (MAZE_STROKE_SIZE_INACTIVE);
|
||||||
|
if (self->active)
|
||||||
|
gsk_stroke_set_line_width (stroke, MAZE_STROKE_SIZE_ACTIVE);
|
||||||
|
gsk_stroke_set_line_join (stroke, GSK_LINE_JOIN_ROUND);
|
||||||
|
gsk_stroke_set_line_cap (stroke, GSK_LINE_CAP_ROUND);
|
||||||
|
gtk_snapshot_push_stroke (snapshot, self->path, stroke);
|
||||||
|
gsk_stroke_free (stroke);
|
||||||
|
|
||||||
|
if (self->background)
|
||||||
|
{
|
||||||
|
gdk_paintable_snapshot (self->background, snapshot, width, height);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gtk_snapshot_append_linear_gradient (snapshot,
|
||||||
|
&GRAPHENE_RECT_INIT (0, 0, width, height),
|
||||||
|
&GRAPHENE_POINT_INIT (0, 0),
|
||||||
|
&GRAPHENE_POINT_INIT (width, height),
|
||||||
|
(GskColorStop[8]) {
|
||||||
|
{ 0.0, { 1.0, 0.0, 0.0, 1.0 } },
|
||||||
|
{ 0.2, { 1.0, 0.0, 0.0, 1.0 } },
|
||||||
|
{ 0.3, { 1.0, 1.0, 0.0, 1.0 } },
|
||||||
|
{ 0.4, { 0.0, 1.0, 0.0, 1.0 } },
|
||||||
|
{ 0.6, { 0.0, 1.0, 1.0, 1.0 } },
|
||||||
|
{ 0.7, { 0.0, 0.0, 1.0, 1.0 } },
|
||||||
|
{ 0.8, { 1.0, 0.0, 1.0, 1.0 } },
|
||||||
|
{ 1.0, { 1.0, 0.0, 1.0, 1.0 } }
|
||||||
|
},
|
||||||
|
8);
|
||||||
|
}
|
||||||
|
|
||||||
|
gtk_snapshot_pop (snapshot);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gtk_maze_dispose (GObject *object)
|
||||||
|
{
|
||||||
|
GtkMaze *self = GTK_MAZE (object);
|
||||||
|
|
||||||
|
g_clear_pointer (&self->path, gsk_path_unref);
|
||||||
|
g_clear_pointer (&self->measure, gsk_path_measure_unref);
|
||||||
|
if (self->background)
|
||||||
|
{
|
||||||
|
g_signal_handlers_disconnect_matched (self->background, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, self);
|
||||||
|
g_clear_object (&self->background);
|
||||||
|
}
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (gtk_maze_parent_class)->dispose (object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gtk_maze_class_init (GtkMazeClass *klass)
|
||||||
|
{
|
||||||
|
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||||
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
|
|
||||||
|
object_class->dispose = gtk_maze_dispose;
|
||||||
|
|
||||||
|
widget_class->measure = gtk_maze_measure;
|
||||||
|
widget_class->snapshot = gtk_maze_snapshot;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
celebrate (gboolean win)
|
||||||
|
{
|
||||||
|
char *path;
|
||||||
|
GtkMediaStream *stream;
|
||||||
|
|
||||||
|
if (win)
|
||||||
|
path = g_build_filename (GTK_DATADIR, "sounds", "freedesktop", "stereo", "complete.oga", NULL);
|
||||||
|
else
|
||||||
|
path = g_build_filename (GTK_DATADIR, "sounds", "freedesktop", "stereo", "suspend-error.oga", NULL);
|
||||||
|
stream = gtk_media_file_new_for_filename (path);
|
||||||
|
gtk_media_stream_set_volume (stream, 1.0);
|
||||||
|
gtk_media_stream_play (stream);
|
||||||
|
|
||||||
|
g_signal_connect (stream, "notify::ended", G_CALLBACK (g_object_unref), NULL);
|
||||||
|
g_free (path);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
pointer_motion (GtkEventControllerMotion *controller,
|
||||||
|
double x,
|
||||||
|
double y,
|
||||||
|
GtkMaze *self)
|
||||||
|
{
|
||||||
|
GskPathPoint point;
|
||||||
|
float distance;
|
||||||
|
|
||||||
|
if (!self->active)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (gsk_path_get_closest_point (self->path,
|
||||||
|
&GRAPHENE_POINT_INIT (x, y),
|
||||||
|
INFINITY,
|
||||||
|
&point,
|
||||||
|
&distance))
|
||||||
|
{
|
||||||
|
if (distance < MAZE_STROKE_SIZE_ACTIVE / 2.f)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
celebrate (FALSE);
|
||||||
|
|
||||||
|
self->active = FALSE;
|
||||||
|
gtk_widget_queue_draw (GTK_WIDGET (self));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
pointer_leave (GtkEventControllerMotion *controller,
|
||||||
|
GtkMaze *self)
|
||||||
|
{
|
||||||
|
if (!self->active)
|
||||||
|
{
|
||||||
|
self->active = TRUE;
|
||||||
|
gtk_widget_queue_draw (GTK_WIDGET (self));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gtk_maze_init (GtkMaze *self)
|
||||||
|
{
|
||||||
|
GtkEventController *controller;
|
||||||
|
|
||||||
|
controller = GTK_EVENT_CONTROLLER (gtk_event_controller_motion_new ());
|
||||||
|
g_signal_connect (controller, "motion", G_CALLBACK (pointer_motion), self);
|
||||||
|
g_signal_connect (controller, "leave", G_CALLBACK (pointer_leave), self);
|
||||||
|
gtk_widget_add_controller (GTK_WIDGET (self), controller);
|
||||||
|
|
||||||
|
self->active = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gtk_maze_set_path (GtkMaze *self,
|
||||||
|
GskPath *path)
|
||||||
|
{
|
||||||
|
g_clear_pointer (&self->path, gsk_path_unref);
|
||||||
|
g_clear_pointer (&self->measure, gsk_path_measure_unref);
|
||||||
|
self->path = gsk_path_ref (path);
|
||||||
|
self->measure = gsk_path_measure_new (path);
|
||||||
|
|
||||||
|
gtk_widget_queue_draw (GTK_WIDGET (self));
|
||||||
|
}
|
||||||
|
|
||||||
|
GtkWidget *
|
||||||
|
gtk_maze_new (GskPath *path,
|
||||||
|
GdkPaintable *background,
|
||||||
|
int width,
|
||||||
|
int height)
|
||||||
|
{
|
||||||
|
GtkMaze *self;
|
||||||
|
|
||||||
|
self = g_object_new (GTK_TYPE_MAZE, NULL);
|
||||||
|
|
||||||
|
gtk_maze_set_path (self, path);
|
||||||
|
gsk_path_unref (path);
|
||||||
|
self->background = background;
|
||||||
|
if (self->background)
|
||||||
|
{
|
||||||
|
g_signal_connect_swapped (self->background, "invalidate-contents", G_CALLBACK (gtk_widget_queue_draw), self);
|
||||||
|
g_signal_connect_swapped (self->background, "invalidate-size", G_CALLBACK (gtk_widget_queue_resize), self);
|
||||||
|
}
|
||||||
|
self->width = width;
|
||||||
|
self->height = height;
|
||||||
|
|
||||||
|
return GTK_WIDGET (self);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
add_point_to_maze (GtkBitset *maze,
|
||||||
|
GskPathBuilder *builder,
|
||||||
|
guint x,
|
||||||
|
guint y)
|
||||||
|
{
|
||||||
|
gboolean set[4] = { FALSE, FALSE, FALSE, FALSE };
|
||||||
|
guint dir;
|
||||||
|
|
||||||
|
gtk_bitset_add (maze, y * MAZE_WIDTH + x);
|
||||||
|
|
||||||
|
while (TRUE)
|
||||||
|
{
|
||||||
|
set[0] = set[0] || x == 0 || gtk_bitset_contains (maze, y * MAZE_WIDTH + x - 1);
|
||||||
|
set[1] = set[1] || y == 0 || gtk_bitset_contains (maze, (y - 1) * MAZE_WIDTH + x);
|
||||||
|
set[2] = set[2] || x + 1 == MAZE_WIDTH || gtk_bitset_contains (maze, y * MAZE_WIDTH + x + 1);
|
||||||
|
set[3] = set[3] || y + 1 == MAZE_HEIGHT || gtk_bitset_contains (maze, (y + 1) * MAZE_WIDTH + x);
|
||||||
|
|
||||||
|
if (set[0] && set[1] && set[2] && set[3])
|
||||||
|
return;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
dir = g_random_int_range (0, 4);
|
||||||
|
}
|
||||||
|
while (set[dir]);
|
||||||
|
|
||||||
|
switch (dir)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
gsk_path_builder_move_to (builder, (x + 0.5) * MAZE_GRID_SIZE, (y + 0.5) * MAZE_GRID_SIZE);
|
||||||
|
gsk_path_builder_line_to (builder, (x - 0.5) * MAZE_GRID_SIZE, (y + 0.5) * MAZE_GRID_SIZE);
|
||||||
|
add_point_to_maze (maze, builder, x - 1, y);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
gsk_path_builder_move_to (builder, (x + 0.5) * MAZE_GRID_SIZE, (y + 0.5) * MAZE_GRID_SIZE);
|
||||||
|
gsk_path_builder_line_to (builder, (x + 0.5) * MAZE_GRID_SIZE, (y - 0.5) * MAZE_GRID_SIZE);
|
||||||
|
add_point_to_maze (maze, builder, x, y - 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
gsk_path_builder_move_to (builder, (x + 0.5) * MAZE_GRID_SIZE, (y + 0.5) * MAZE_GRID_SIZE);
|
||||||
|
gsk_path_builder_line_to (builder, (x + 1.5) * MAZE_GRID_SIZE, (y + 0.5) * MAZE_GRID_SIZE);
|
||||||
|
add_point_to_maze (maze, builder, x + 1, y);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
gsk_path_builder_move_to (builder, (x + 0.5) * MAZE_GRID_SIZE, (y + 0.5) * MAZE_GRID_SIZE);
|
||||||
|
gsk_path_builder_line_to (builder, (x + 0.5) * MAZE_GRID_SIZE, (y + 1.5) * MAZE_GRID_SIZE);
|
||||||
|
add_point_to_maze (maze, builder, x, y + 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
g_assert_not_reached ();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static GskPath *
|
||||||
|
create_path_for_maze (GtkWidget *widget)
|
||||||
|
{
|
||||||
|
GskPathBuilder *builder;
|
||||||
|
GtkBitset *maze;
|
||||||
|
|
||||||
|
builder = gsk_path_builder_new ();
|
||||||
|
maze = gtk_bitset_new_empty ();
|
||||||
|
/* make sure the outer lines are unreachable:
|
||||||
|
* Set the full range, then remove the center again. */
|
||||||
|
gtk_bitset_add_range (maze, 0, MAZE_WIDTH * MAZE_HEIGHT);
|
||||||
|
gtk_bitset_remove_rectangle (maze, MAZE_WIDTH + 1, MAZE_WIDTH - 2, MAZE_HEIGHT - 2, MAZE_WIDTH);
|
||||||
|
|
||||||
|
/* Fill the maze */
|
||||||
|
add_point_to_maze (maze, builder, MAZE_WIDTH / 2, MAZE_HEIGHT / 2);
|
||||||
|
|
||||||
|
/* Add start and stop lines */
|
||||||
|
gsk_path_builder_move_to (builder, 1.5 * MAZE_GRID_SIZE, -0.5 * MAZE_GRID_SIZE);
|
||||||
|
gsk_path_builder_line_to (builder, 1.5 * MAZE_GRID_SIZE, 1.5 * MAZE_GRID_SIZE);
|
||||||
|
gsk_path_builder_move_to (builder, (MAZE_WIDTH - 1.5) * MAZE_GRID_SIZE, (MAZE_HEIGHT - 1.5) * MAZE_GRID_SIZE);
|
||||||
|
gsk_path_builder_line_to (builder, (MAZE_WIDTH - 1.5) * MAZE_GRID_SIZE, (MAZE_HEIGHT + 0.5) * MAZE_GRID_SIZE);
|
||||||
|
|
||||||
|
|
||||||
|
gtk_bitset_unref (maze);
|
||||||
|
|
||||||
|
return gsk_path_builder_free_to_path (builder);
|
||||||
|
}
|
||||||
|
|
||||||
|
GtkWidget *
|
||||||
|
do_path_maze (GtkWidget *do_widget)
|
||||||
|
{
|
||||||
|
static GtkWidget *window = NULL;
|
||||||
|
|
||||||
|
if (!window)
|
||||||
|
{
|
||||||
|
GtkWidget *maze;
|
||||||
|
GtkMediaStream *stream;
|
||||||
|
GskPath *path;
|
||||||
|
|
||||||
|
window = gtk_window_new ();
|
||||||
|
gtk_window_set_resizable (GTK_WINDOW (window), TRUE);
|
||||||
|
gtk_window_set_title (GTK_WINDOW (window), "Follow the maze with the mouse");
|
||||||
|
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
stream = gtk_media_file_new_for_resource ("/images/gtk-logo.webm");
|
||||||
|
#else
|
||||||
|
stream = gtk_nuclear_media_stream_new ();
|
||||||
|
#endif
|
||||||
|
gtk_media_stream_play (stream);
|
||||||
|
gtk_media_stream_set_loop (stream, TRUE);
|
||||||
|
|
||||||
|
path = create_path_for_maze (window);
|
||||||
|
|
||||||
|
maze = gtk_maze_new (path,
|
||||||
|
GDK_PAINTABLE (stream),
|
||||||
|
MAZE_WIDTH * MAZE_GRID_SIZE,
|
||||||
|
MAZE_HEIGHT * MAZE_GRID_SIZE);
|
||||||
|
|
||||||
|
gtk_window_set_child (GTK_WINDOW (window), maze);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!gtk_widget_get_visible (window))
|
||||||
|
gtk_window_present (GTK_WINDOW (window));
|
||||||
|
else
|
||||||
|
gtk_window_destroy (GTK_WINDOW (window));
|
||||||
|
|
||||||
|
return window;
|
||||||
|
}
|
@@ -9,6 +9,8 @@
|
|||||||
|
|
||||||
#include "paintable.h"
|
#include "paintable.h"
|
||||||
|
|
||||||
|
#undef SHOW_CONTROLS
|
||||||
|
|
||||||
#define GTK_TYPE_SPINNER_PAINTABLE (gtk_spinner_paintable_get_type ())
|
#define GTK_TYPE_SPINNER_PAINTABLE (gtk_spinner_paintable_get_type ())
|
||||||
G_DECLARE_FINAL_TYPE (GtkSpinnerPaintable, gtk_spinner_paintable, GTK, SPINNER_PAINTABLE, GObject)
|
G_DECLARE_FINAL_TYPE (GtkSpinnerPaintable, gtk_spinner_paintable, GTK, SPINNER_PAINTABLE, GObject)
|
||||||
|
|
||||||
@@ -56,9 +58,9 @@ gtk_spinner_paintable_get_intrinsic_height (GdkPaintable *paintable)
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
gtk_spinner_paintable_snapshot (GdkPaintable *paintable,
|
gtk_spinner_paintable_snapshot (GdkPaintable *paintable,
|
||||||
GdkSnapshot *snapshot,
|
GdkSnapshot *snapshot,
|
||||||
double width,
|
double width,
|
||||||
double height)
|
double height)
|
||||||
{
|
{
|
||||||
GtkSpinnerPaintable *self = GTK_SPINNER_PAINTABLE (paintable);
|
GtkSpinnerPaintable *self = GTK_SPINNER_PAINTABLE (paintable);
|
||||||
|
|
||||||
@@ -150,6 +152,7 @@ static gboolean
|
|||||||
add_controls (GskPathOperation op,
|
add_controls (GskPathOperation op,
|
||||||
const graphene_point_t *pts,
|
const graphene_point_t *pts,
|
||||||
gsize n_pts,
|
gsize n_pts,
|
||||||
|
float weight,
|
||||||
gpointer data)
|
gpointer data)
|
||||||
{
|
{
|
||||||
GskPathBuilder *builder = data;
|
GskPathBuilder *builder = data;
|
||||||
@@ -166,7 +169,7 @@ add_controls (GskPathOperation op,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case GSK_PATH_QUAD:
|
case GSK_PATH_QUAD:
|
||||||
case GSK_PATH_ARC:
|
case GSK_PATH_CONIC:
|
||||||
gsk_path_builder_line_to (builder, pts[1].x, pts[1].y);
|
gsk_path_builder_line_to (builder, pts[1].x, pts[1].y);
|
||||||
gsk_path_builder_line_to (builder, pts[2].x, pts[2].y);
|
gsk_path_builder_line_to (builder, pts[2].x, pts[2].y);
|
||||||
break;
|
break;
|
||||||
@@ -190,32 +193,21 @@ update_path (GtkSpinnerPaintable *self)
|
|||||||
{
|
{
|
||||||
GskPathBuilder *builder;
|
GskPathBuilder *builder;
|
||||||
GskPathPoint start, end;
|
GskPathPoint start, end;
|
||||||
GskTransform *t;
|
graphene_point_t p0, p1;
|
||||||
graphene_point_t p, p0, p1;
|
|
||||||
float start_angle, end_angle;
|
float start_angle, end_angle;
|
||||||
|
|
||||||
p = GRAPHENE_POINT_INIT (40, 0);
|
|
||||||
start_angle = self->angle;
|
start_angle = self->angle;
|
||||||
end_angle = fmod (self->angle + 360 * self->completion / 100, 360);
|
end_angle = fmod (self->angle + 360 * self->completion / 100, 360);
|
||||||
|
|
||||||
t = gsk_transform_translate (
|
p0 = GRAPHENE_POINT_INIT (50 + 40 * cos (M_PI * start_angle / 180),
|
||||||
gsk_transform_rotate (
|
50 + 40 * sin (M_PI * start_angle / 180));
|
||||||
gsk_transform_translate (NULL, &GRAPHENE_POINT_INIT (50, 50)),
|
p1 = GRAPHENE_POINT_INIT (50 + 40 * cos (M_PI * end_angle / 180),
|
||||||
start_angle),
|
50 + 40 * sin (M_PI * end_angle / 180));
|
||||||
&GRAPHENE_POINT_INIT (-50, -50));
|
|
||||||
gsk_transform_transform_point (t, &p, &p0);
|
|
||||||
|
|
||||||
t = gsk_transform_translate (
|
|
||||||
gsk_transform_rotate (
|
|
||||||
gsk_transform_translate (NULL, &GRAPHENE_POINT_INIT (50, 50)),
|
|
||||||
end_angle),
|
|
||||||
&GRAPHENE_POINT_INIT (-50, -50));
|
|
||||||
gsk_transform_transform_point (t, &p, &p1);
|
|
||||||
|
|
||||||
g_clear_pointer (&self->path, gsk_path_unref);
|
g_clear_pointer (&self->path, gsk_path_unref);
|
||||||
|
|
||||||
gsk_path_get_closest_point (self->circle, &p0, INFINITY, &start);
|
gsk_path_get_closest_point (self->circle, &p0, INFINITY, &start, NULL);
|
||||||
gsk_path_get_closest_point (self->circle, &p1, INFINITY, &end);
|
gsk_path_get_closest_point (self->circle, &p1, INFINITY, &end, NULL);
|
||||||
|
|
||||||
builder = gsk_path_builder_new ();
|
builder = gsk_path_builder_new ();
|
||||||
gsk_path_builder_add_segment (builder, self->circle, &start, &end);
|
gsk_path_builder_add_segment (builder, self->circle, &start, &end);
|
||||||
|
@@ -104,19 +104,20 @@ gtk_path_transform_point (GskPathMeasure *measure,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gtk_path_transform_op (const graphene_point_t *start,
|
gtk_path_transform_op (GskPathOperation op,
|
||||||
const graphene_point_t *end,
|
const graphene_point_t *pts,
|
||||||
const GskPathControl *control,
|
gsize n_pts,
|
||||||
|
float weight,
|
||||||
gpointer data)
|
gpointer data)
|
||||||
{
|
{
|
||||||
GtkPathTransform *transform = data;
|
GtkPathTransform *transform = data;
|
||||||
|
|
||||||
switch (control->op)
|
switch (op)
|
||||||
{
|
{
|
||||||
case GSK_PATH_MOVE:
|
case GSK_PATH_MOVE:
|
||||||
{
|
{
|
||||||
graphene_point_t res;
|
graphene_point_t res;
|
||||||
gtk_path_transform_point (transform->measure, end, &transform->offset, transform->scale, &res);
|
gtk_path_transform_point (transform->measure, &pts[0], &transform->offset, transform->scale, &res);
|
||||||
gsk_path_builder_move_to (transform->builder, res.x, res.y);
|
gsk_path_builder_move_to (transform->builder, res.x, res.y);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -124,7 +125,7 @@ gtk_path_transform_op (const graphene_point_t *start,
|
|||||||
case GSK_PATH_LINE:
|
case GSK_PATH_LINE:
|
||||||
{
|
{
|
||||||
graphene_point_t res;
|
graphene_point_t res;
|
||||||
gtk_path_transform_point (transform->measure, end, &transform->offset, transform->scale, &res);
|
gtk_path_transform_point (transform->measure, &pts[1], &transform->offset, transform->scale, &res);
|
||||||
gsk_path_builder_line_to (transform->builder, res.x, res.y);
|
gsk_path_builder_line_to (transform->builder, res.x, res.y);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -132,8 +133,8 @@ gtk_path_transform_op (const graphene_point_t *start,
|
|||||||
case GSK_PATH_QUAD:
|
case GSK_PATH_QUAD:
|
||||||
{
|
{
|
||||||
graphene_point_t res[2];
|
graphene_point_t res[2];
|
||||||
gtk_path_transform_point (transform->measure, &control->quad.control, &transform->offset, transform->scale, &res[0]);
|
gtk_path_transform_point (transform->measure, &pts[1], &transform->offset, transform->scale, &res[0]);
|
||||||
gtk_path_transform_point (transform->measure, end, &transform->offset, transform->scale, &res[1]);
|
gtk_path_transform_point (transform->measure, &pts[2], &transform->offset, transform->scale, &res[1]);
|
||||||
gsk_path_builder_quad_to (transform->builder, res[0].x, res[0].y, res[1].x, res[1].y);
|
gsk_path_builder_quad_to (transform->builder, res[0].x, res[0].y, res[1].x, res[1].y);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -141,9 +142,9 @@ gtk_path_transform_op (const graphene_point_t *start,
|
|||||||
case GSK_PATH_CUBIC:
|
case GSK_PATH_CUBIC:
|
||||||
{
|
{
|
||||||
graphene_point_t res[3];
|
graphene_point_t res[3];
|
||||||
gtk_path_transform_point (transform->measure, &control->cubic.control1, &transform->offset, transform->scale, &res[0]);
|
gtk_path_transform_point (transform->measure, &pts[1], &transform->offset, transform->scale, &res[0]);
|
||||||
gtk_path_transform_point (transform->measure, &control->cubic.control2, &transform->offset, transform->scale, &res[1]);
|
gtk_path_transform_point (transform->measure, &pts[2], &transform->offset, transform->scale, &res[1]);
|
||||||
gtk_path_transform_point (transform->measure, end, &transform->offset, transform->scale, &res[2]);
|
gtk_path_transform_point (transform->measure, &pts[3], &transform->offset, transform->scale, &res[2]);
|
||||||
gsk_path_builder_cubic_to (transform->builder, res[0].x, res[0].y, res[1].x, res[1].y, res[2].x, res[2].y);
|
gsk_path_builder_cubic_to (transform->builder, res[0].x, res[0].y, res[1].x, res[1].y, res[2].x, res[2].y);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -151,9 +152,9 @@ gtk_path_transform_op (const graphene_point_t *start,
|
|||||||
case GSK_PATH_CONIC:
|
case GSK_PATH_CONIC:
|
||||||
{
|
{
|
||||||
graphene_point_t res[2];
|
graphene_point_t res[2];
|
||||||
gtk_path_transform_point (transform->measure, &control->conic.control, &transform->offset, transform->scale, &res[0]);
|
gtk_path_transform_point (transform->measure, &pts[1], &transform->offset, transform->scale, &res[0]);
|
||||||
gtk_path_transform_point (transform->measure, end, &transform->offset, transform->scale, &res[1]);
|
gtk_path_transform_point (transform->measure, &pts[3], &transform->offset, transform->scale, &res[1]);
|
||||||
gsk_path_builder_conic_to (transform->builder, res[0].x, res[0].y, res[1].x, res[1].y, control->conic.weight);
|
gsk_path_builder_conic_to (transform->builder, res[0].x, res[0].y, res[1].x, res[1].y, weight);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -500,15 +501,13 @@ pointer_motion (GtkEventControllerMotion *controller,
|
|||||||
GtkPathWidget *self)
|
GtkPathWidget *self)
|
||||||
{
|
{
|
||||||
GskPathPoint point;
|
GskPathPoint point;
|
||||||
graphene_point_t pos;
|
|
||||||
|
|
||||||
if (gsk_path_get_closest_point (self->line_path,
|
if (gsk_path_get_closest_point (self->line_path,
|
||||||
&GRAPHENE_POINT_INIT (x, y),
|
&GRAPHENE_POINT_INIT (x, y),
|
||||||
INFINITY,
|
INFINITY,
|
||||||
&point))
|
&point,
|
||||||
|
NULL))
|
||||||
{
|
{
|
||||||
gsk_path_point_get_position (&point, self->line_path, &pos);
|
|
||||||
|
|
||||||
gtk_widget_queue_draw (GTK_WIDGET (self));
|
gtk_widget_queue_draw (GTK_WIDGET (self));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -11,6 +11,8 @@
|
|||||||
<property name="lower">0</property>
|
<property name="lower">0</property>
|
||||||
<property name="upper">5000</property>
|
<property name="upper">5000</property>
|
||||||
<property name="value">500</property>
|
<property name="value">500</property>
|
||||||
|
<property name="step-increment">1</property>
|
||||||
|
<property name="page-increment">10</property>
|
||||||
</object>
|
</object>
|
||||||
</property>
|
</property>
|
||||||
</object>
|
</object>
|
||||||
|
@@ -1,8 +1,9 @@
|
|||||||
/* Pickers and Launchers
|
/* Pickers and Launchers
|
||||||
* #Keywords: GtkColorDialog, GtkFontDialog, GtkFileDialog, GtkFileLauncher, GtkUriLauncher
|
* #Keywords: GtkColorDialog, GtkFontDialog, GtkFileDialog, GtkPrintDialog, GtkFileLauncher, GtkUriLauncher
|
||||||
*
|
*
|
||||||
* The dialogs are mainly intended for use in preference dialogs.
|
* The dialogs are mainly intended for use in preference dialogs.
|
||||||
* They allow to select colors, fonts and applications.
|
* They allow to select colors, fonts and files. There is also a
|
||||||
|
* print dialog.
|
||||||
*
|
*
|
||||||
* The launchers let you open files or URIs in applications that
|
* The launchers let you open files or URIs in applications that
|
||||||
* can handle them.
|
* can handle them.
|
||||||
@@ -11,11 +12,13 @@
|
|||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
static GtkWidget *app_picker;
|
static GtkWidget *app_picker;
|
||||||
|
static GtkWidget *print_button;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
set_file (GFile *file,
|
set_file (GFile *file,
|
||||||
gpointer data)
|
gpointer data)
|
||||||
{
|
{
|
||||||
|
GFileInfo *info;
|
||||||
char *name;
|
char *name;
|
||||||
|
|
||||||
if (!file)
|
if (!file)
|
||||||
@@ -31,6 +34,13 @@ set_file (GFile *file,
|
|||||||
|
|
||||||
gtk_widget_set_sensitive (app_picker, TRUE);
|
gtk_widget_set_sensitive (app_picker, TRUE);
|
||||||
g_object_set_data_full (G_OBJECT (app_picker), "file", g_object_ref (file), g_object_unref);
|
g_object_set_data_full (G_OBJECT (app_picker), "file", g_object_ref (file), g_object_unref);
|
||||||
|
|
||||||
|
info = g_file_query_info (file, "standard::content-type", 0, NULL, NULL);
|
||||||
|
if (strcmp (g_file_info_get_content_type (info), "application/pdf") == 0)
|
||||||
|
{
|
||||||
|
gtk_widget_set_sensitive (print_button, TRUE);
|
||||||
|
g_object_set_data_full (G_OBJECT (print_button), "file", g_object_ref (file), g_object_unref);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -47,6 +57,10 @@ file_opened (GObject *source,
|
|||||||
{
|
{
|
||||||
g_print ("%s\n", error->message);
|
g_print ("%s\n", error->message);
|
||||||
g_error_free (error);
|
g_error_free (error);
|
||||||
|
gtk_widget_set_sensitive (app_picker, FALSE);
|
||||||
|
g_object_set_data (G_OBJECT (app_picker), "file", NULL);
|
||||||
|
gtk_widget_set_sensitive (print_button, FALSE);
|
||||||
|
g_object_set_data (G_OBJECT (print_button), "file", NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
set_file (file, data);
|
set_file (file, data);
|
||||||
@@ -114,6 +128,53 @@ open_app (GtkButton *picker)
|
|||||||
g_object_unref (launcher);
|
g_object_unref (launcher);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
print_file_done (GObject *source,
|
||||||
|
GAsyncResult *result,
|
||||||
|
gpointer data)
|
||||||
|
{
|
||||||
|
GtkPrintDialog *dialog = GTK_PRINT_DIALOG (source);
|
||||||
|
GError *error = NULL;
|
||||||
|
GCancellable *cancellable;
|
||||||
|
unsigned int id;
|
||||||
|
|
||||||
|
cancellable = g_task_get_cancellable (G_TASK (result));
|
||||||
|
id = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (cancellable), "timeout"));
|
||||||
|
if (id)
|
||||||
|
g_source_remove (id);
|
||||||
|
|
||||||
|
if (!gtk_print_dialog_print_file_finish (dialog, result, &error))
|
||||||
|
{
|
||||||
|
g_print ("%s\n", error->message);
|
||||||
|
g_error_free (error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
print_file (GtkButton *picker)
|
||||||
|
{
|
||||||
|
GtkWindow *parent = GTK_WINDOW (gtk_widget_get_root (GTK_WIDGET (picker)));
|
||||||
|
GtkPrintDialog *dialog;
|
||||||
|
GCancellable *cancellable;
|
||||||
|
GFile *file;
|
||||||
|
unsigned int id;
|
||||||
|
|
||||||
|
file = G_FILE (g_object_get_data (G_OBJECT (picker), "file"));
|
||||||
|
dialog = gtk_print_dialog_new ();
|
||||||
|
|
||||||
|
cancellable = g_cancellable_new ();
|
||||||
|
|
||||||
|
id = g_timeout_add_seconds_full (G_PRIORITY_DEFAULT,
|
||||||
|
20,
|
||||||
|
abort_mission, g_object_ref (cancellable), g_object_unref);
|
||||||
|
g_object_set_data (G_OBJECT (cancellable), "timeout", GUINT_TO_POINTER (id));
|
||||||
|
|
||||||
|
gtk_print_dialog_print_file (dialog, parent, NULL, file, cancellable, print_file_done, NULL);
|
||||||
|
|
||||||
|
g_object_unref (cancellable);
|
||||||
|
g_object_unref (dialog);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
open_uri_done (GObject *source,
|
open_uri_done (GObject *source,
|
||||||
GAsyncResult *result,
|
GAsyncResult *result,
|
||||||
@@ -234,8 +295,14 @@ do_pickers (GtkWidget *do_widget)
|
|||||||
gtk_widget_set_sensitive (app_picker, FALSE);
|
gtk_widget_set_sensitive (app_picker, FALSE);
|
||||||
g_signal_connect (app_picker, "clicked", G_CALLBACK (open_app), NULL);
|
g_signal_connect (app_picker, "clicked", G_CALLBACK (open_app), NULL);
|
||||||
gtk_box_append (GTK_BOX (picker), app_picker);
|
gtk_box_append (GTK_BOX (picker), app_picker);
|
||||||
gtk_grid_attach (GTK_GRID (table), picker, 1, 2, 1, 1);
|
|
||||||
|
|
||||||
|
print_button = gtk_button_new_from_icon_name ("printer-symbolic");
|
||||||
|
gtk_widget_set_tooltip_text (print_button, "Print file");
|
||||||
|
gtk_widget_set_sensitive (print_button, FALSE);
|
||||||
|
g_signal_connect (print_button, "clicked", G_CALLBACK (print_file), NULL);
|
||||||
|
gtk_box_append (GTK_BOX (picker), print_button);
|
||||||
|
|
||||||
|
gtk_grid_attach (GTK_GRID (table), picker, 1, 2, 1, 1);
|
||||||
|
|
||||||
label = gtk_label_new ("URI:");
|
label = gtk_label_new ("URI:");
|
||||||
gtk_widget_set_halign (label, GTK_ALIGN_START);
|
gtk_widget_set_halign (label, GTK_ALIGN_START);
|
||||||
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 844 B After Width: | Height: | Size: 1.1 KiB |
2218
demos/gtk-demo/tiger.node
Normal file
Before Width: | Height: | Size: 823 B After Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
@@ -147,6 +147,19 @@ Creates a node like `gsk_cross_fade_node_new()` with the given properties.
|
|||||||
|
|
||||||
Creates a node like `gsk_debug_node_new()` with the given properties.
|
Creates a node like `gsk_debug_node_new()` with the given properties.
|
||||||
|
|
||||||
|
### fill
|
||||||
|
|
||||||
|
| property | syntax | default | printed |
|
||||||
|
| --------- | --------------- | ---------------------- | ----------- |
|
||||||
|
| child | `<node>` | *see below* | always |
|
||||||
|
| path | `<string>` | "" | always |
|
||||||
|
| fill-rule | `<fill-rule>` | winding | always |
|
||||||
|
|
||||||
|
Creates a node like `gsk_fill_node_new()` with the given properties.
|
||||||
|
|
||||||
|
The default child node is the default color node, but created with the
|
||||||
|
bounds of the path.
|
||||||
|
|
||||||
### glshader
|
### glshader
|
||||||
|
|
||||||
| property | syntax | default | printed |
|
| property | syntax | default | printed |
|
||||||
@@ -289,6 +302,24 @@ Creates a node like `gsk_rounded_clip_node_new()` with the given properties.
|
|||||||
|
|
||||||
Creates a node like `gsk_shadow_node_new()` with the given properties.
|
Creates a node like `gsk_shadow_node_new()` with the given properties.
|
||||||
|
|
||||||
|
### stroke
|
||||||
|
|
||||||
|
| property | syntax | default | printed |
|
||||||
|
| ----------- | ------------------ | ----------------- | ----------- |
|
||||||
|
| child | `<node>` | *see below* | always |
|
||||||
|
| path | `<string>` | "" | always |
|
||||||
|
| line-width | `<number>` | 0 | non-default |
|
||||||
|
| line-cap | `<line-cap>` | butt | always |
|
||||||
|
| line-join | `<line-join>` | miter | always |
|
||||||
|
| miter-limit | `<number>` | 4 | non-default |
|
||||||
|
| dash | `<number>{+}|none` | none | non-default |
|
||||||
|
| dash-offset | `<number>` | 0 | non-default |
|
||||||
|
|
||||||
|
Creates a node like `gsk_stroke_node_new()` with the given properties.
|
||||||
|
|
||||||
|
The default child node is the default color node, but created with the
|
||||||
|
stroke bounds of the path.
|
||||||
|
|
||||||
### text
|
### text
|
||||||
|
|
||||||
| property | syntax | default | printed |
|
| property | syntax | default | printed |
|
||||||
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 985 B After Width: | Height: | Size: 1019 B |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 844 B After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 823 B After Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
@@ -15,6 +15,7 @@ SYNOPSIS
|
|||||||
| **gtk4-path-tool** decompose [OPTIONS...] <PATH>
|
| **gtk4-path-tool** decompose [OPTIONS...] <PATH>
|
||||||
| **gtk4-path-tool** show [OPTIONS...] <PATH>
|
| **gtk4-path-tool** show [OPTIONS...] <PATH>
|
||||||
| **gtk4-path-tool** render [OPTIONS...] <PATH>
|
| **gtk4-path-tool** render [OPTIONS...] <PATH>
|
||||||
|
| **gtk4-path-tool** reverse [OPTIONS...] <PATH>
|
||||||
| **gtk4-path-tool** info [OPTIONS...] <PATH>
|
| **gtk4-path-tool** info [OPTIONS...] <PATH>
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
@@ -54,6 +55,22 @@ Showing
|
|||||||
The ``show`` command displays the given path in a window. The interior
|
The ``show`` command displays the given path in a window. The interior
|
||||||
of the path is filled.
|
of the path is filled.
|
||||||
|
|
||||||
|
``--fill``
|
||||||
|
|
||||||
|
Fill the path (this is the default).
|
||||||
|
|
||||||
|
``--stroke``
|
||||||
|
|
||||||
|
Stroke the path instead of filling it.
|
||||||
|
|
||||||
|
``--points``
|
||||||
|
|
||||||
|
Show points on the path.
|
||||||
|
|
||||||
|
``--controls``
|
||||||
|
|
||||||
|
Show control points.
|
||||||
|
|
||||||
``--fill-rule=VALUE``
|
``--fill-rule=VALUE``
|
||||||
|
|
||||||
The fill rule that is used to determine what areas are inside the path.
|
The fill rule that is used to determine what areas are inside the path.
|
||||||
@@ -69,13 +86,10 @@ of the path is filled.
|
|||||||
The color that is used to render the background behind the path.
|
The color that is used to render the background behind the path.
|
||||||
If not specified, white is used.
|
If not specified, white is used.
|
||||||
|
|
||||||
``--fill``
|
``--point-color=COLOR``
|
||||||
|
|
||||||
Fill the path (this is the default).
|
The color that is used to render the points.
|
||||||
|
If not specified, red is used.
|
||||||
``--stroke``
|
|
||||||
|
|
||||||
Stroke the path instead of filling it.
|
|
||||||
|
|
||||||
``--line-width=VALUE``
|
``--line-width=VALUE``
|
||||||
|
|
||||||
@@ -118,6 +132,22 @@ Rendering
|
|||||||
The ``render`` command renders the given path as a PNG image.
|
The ``render`` command renders the given path as a PNG image.
|
||||||
The interior of the path is filled.
|
The interior of the path is filled.
|
||||||
|
|
||||||
|
``--fill``
|
||||||
|
|
||||||
|
Fill the path (this is the default).
|
||||||
|
|
||||||
|
``--stroke``
|
||||||
|
|
||||||
|
Stroke the path instead of filling it.
|
||||||
|
|
||||||
|
``--points``
|
||||||
|
|
||||||
|
Show points on the path.
|
||||||
|
|
||||||
|
``--controls``
|
||||||
|
|
||||||
|
Show control points.
|
||||||
|
|
||||||
``--fill-rule=VALUE``
|
``--fill-rule=VALUE``
|
||||||
|
|
||||||
The fill rule that is used to determine what areas are inside the path.
|
The fill rule that is used to determine what areas are inside the path.
|
||||||
@@ -133,19 +163,16 @@ The interior of the path is filled.
|
|||||||
The color that is used to render the background behind the path.
|
The color that is used to render the background behind the path.
|
||||||
If not specified, white is used.
|
If not specified, white is used.
|
||||||
|
|
||||||
|
``--point-color=COLOR``
|
||||||
|
|
||||||
|
The color that is used to render the points.
|
||||||
|
If not specified, red is used.
|
||||||
|
|
||||||
``--output-file=FILE``
|
``--output-file=FILE``
|
||||||
|
|
||||||
The file to save the PNG image to.
|
The file to save the PNG image to.
|
||||||
If not specified, "path.png" is used.
|
If not specified, "path.png" is used.
|
||||||
|
|
||||||
``--fill``
|
|
||||||
|
|
||||||
Fill the path (this is the default).
|
|
||||||
|
|
||||||
``--stroke``
|
|
||||||
|
|
||||||
Stroke the path instead of filling it.
|
|
||||||
|
|
||||||
``--line-width=VALUE``
|
``--line-width=VALUE``
|
||||||
|
|
||||||
The line width to use for the stroke. ``VALUE`` must be a positive number.
|
The line width to use for the stroke. ``VALUE`` must be a positive number.
|
||||||
@@ -181,6 +208,12 @@ The interior of the path is filled.
|
|||||||
The offset into the dash pattern where dashing should begin.
|
The offset into the dash pattern where dashing should begin.
|
||||||
The default value is 0.
|
The default value is 0.
|
||||||
|
|
||||||
|
Reversing
|
||||||
|
^^^^^^^^^
|
||||||
|
|
||||||
|
The ``reverse`` command changes the direction of the path. The resulting
|
||||||
|
paths starts where the original path ends.
|
||||||
|
|
||||||
Info
|
Info
|
||||||
^^^^
|
^^^^
|
||||||
|
|
||||||
|
@@ -170,35 +170,41 @@ This variable can be set to a list of debug options, which cause GDK to
|
|||||||
print out different types of debugging information. Some of these options
|
print out different types of debugging information. Some of these options
|
||||||
are only available when GTK has been configured with `-Ddebug=true`.
|
are only available when GTK has been configured with `-Ddebug=true`.
|
||||||
|
|
||||||
`cursor`
|
`misc`
|
||||||
: Information about cursor objects (only win32)
|
: Miscellaneous information
|
||||||
|
|
||||||
|
`events`
|
||||||
|
: Information about events
|
||||||
|
|
||||||
|
`dnd`
|
||||||
|
: Information about drag-and-drop
|
||||||
|
|
||||||
|
`input`
|
||||||
|
: Information about input (mostly Windows)
|
||||||
|
|
||||||
`eventloop`
|
`eventloop`
|
||||||
: Information about event loop operation (mostly macOS)
|
: Information about event loop operation (mostly macOS)
|
||||||
|
|
||||||
`misc`
|
|
||||||
: Miscellaneous information
|
|
||||||
|
|
||||||
`frames`
|
`frames`
|
||||||
: Information about the frame clock
|
: Information about the frame clock
|
||||||
|
|
||||||
`settings`
|
`settings`
|
||||||
: Information about xsettings
|
: Information about xsettings
|
||||||
|
|
||||||
|
`opengl`
|
||||||
|
: Information about OpenGL
|
||||||
|
|
||||||
|
`vulkan`
|
||||||
|
: Information about Vulkan
|
||||||
|
|
||||||
`selection`
|
`selection`
|
||||||
: Information about selections
|
: Information about selections
|
||||||
|
|
||||||
`clipboard`
|
`clipboard`
|
||||||
: Information about clipboards
|
: Information about clipboards
|
||||||
|
|
||||||
`dnd`
|
`dmabuf`
|
||||||
: Information about drag-and-drop
|
: Information about dmabuf handling (Linux-only)
|
||||||
|
|
||||||
`opengl`
|
|
||||||
: Information about OpenGL
|
|
||||||
|
|
||||||
`vulkan`
|
|
||||||
: Information about Vulkan
|
|
||||||
|
|
||||||
A number of options affect behavior instead of logging:
|
A number of options affect behavior instead of logging:
|
||||||
|
|
||||||
@@ -217,6 +223,9 @@ A number of options affect behavior instead of logging:
|
|||||||
`gl-fractional`
|
`gl-fractional`
|
||||||
: Enable fractional scaling for OpenGL. This is experimental
|
: Enable fractional scaling for OpenGL. This is experimental
|
||||||
|
|
||||||
|
`gl-debug`
|
||||||
|
: Insert debugging information in OpenGL
|
||||||
|
|
||||||
`gl-legacy`
|
`gl-legacy`
|
||||||
: Use a legacy OpenGL context
|
: Use a legacy OpenGL context
|
||||||
|
|
||||||
@@ -244,6 +253,12 @@ A number of options affect behavior instead of logging:
|
|||||||
`high-depth`
|
`high-depth`
|
||||||
: Use high bit depth rendering if possible
|
: Use high bit depth rendering if possible
|
||||||
|
|
||||||
|
`no-vsync`
|
||||||
|
: Repaint instantly (uses 100% CPU with animations)
|
||||||
|
|
||||||
|
`dmabuf-disable`
|
||||||
|
: Disable dmabuf support
|
||||||
|
|
||||||
The special value `all` can be used to turn on all debug options. The special
|
The special value `all` can be used to turn on all debug options. The special
|
||||||
value `help` can be used to obtain a list of all supported debug options.
|
value `help` can be used to obtain a list of all supported debug options.
|
||||||
|
|
||||||
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
@@ -117,6 +117,8 @@ static const GdkDebugKey gdk_debug_keys[] = {
|
|||||||
{ "vulkan", GDK_DEBUG_VULKAN, "Information about Vulkan" },
|
{ "vulkan", GDK_DEBUG_VULKAN, "Information about Vulkan" },
|
||||||
{ "selection", GDK_DEBUG_SELECTION, "Information about selections" },
|
{ "selection", GDK_DEBUG_SELECTION, "Information about selections" },
|
||||||
{ "clipboard", GDK_DEBUG_CLIPBOARD, "Information about clipboards" },
|
{ "clipboard", GDK_DEBUG_CLIPBOARD, "Information about clipboards" },
|
||||||
|
{ "dmabuf", GDK_DEBUG_DMABUF, "Information about dmabuf buffers" },
|
||||||
|
|
||||||
{ "nograbs", GDK_DEBUG_NOGRABS, "Disable pointer and keyboard grabs (X11)", TRUE },
|
{ "nograbs", GDK_DEBUG_NOGRABS, "Disable pointer and keyboard grabs (X11)", TRUE },
|
||||||
{ "portals", GDK_DEBUG_PORTALS, "Force use of portals", TRUE },
|
{ "portals", GDK_DEBUG_PORTALS, "Force use of portals", TRUE },
|
||||||
{ "no-portals", GDK_DEBUG_NO_PORTALS, "Disable use of portals", TRUE },
|
{ "no-portals", GDK_DEBUG_NO_PORTALS, "Disable use of portals", TRUE },
|
||||||
@@ -133,6 +135,7 @@ static const GdkDebugKey gdk_debug_keys[] = {
|
|||||||
{ "default-settings",GDK_DEBUG_DEFAULT_SETTINGS, "Force default values for xsettings", TRUE },
|
{ "default-settings",GDK_DEBUG_DEFAULT_SETTINGS, "Force default values for xsettings", TRUE },
|
||||||
{ "high-depth", GDK_DEBUG_HIGH_DEPTH, "Use high bit depth rendering if possible", TRUE },
|
{ "high-depth", GDK_DEBUG_HIGH_DEPTH, "Use high bit depth rendering if possible", TRUE },
|
||||||
{ "no-vsync", GDK_DEBUG_NO_VSYNC, "Repaint instantly (uses 100% CPU with animations)", TRUE },
|
{ "no-vsync", GDK_DEBUG_NO_VSYNC, "Repaint instantly (uses 100% CPU with animations)", TRUE },
|
||||||
|
{ "dmabuf-disable", GDK_DEBUG_DMABUF_DISABLE, "Disable dmabuf support", TRUE },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -263,7 +266,7 @@ gdk_parse_debug_var (const char *variable,
|
|||||||
if (debug_enabled || keys[i].always_enabled)
|
if (debug_enabled || keys[i].always_enabled)
|
||||||
fprintf (stderr, " %s%*s%s\n", keys[i].key, (int)(max_width - strlen (keys[i].key)), " ", keys[i].help);
|
fprintf (stderr, " %s%*s%s\n", keys[i].key, (int)(max_width - strlen (keys[i].key)), " ", keys[i].help);
|
||||||
}
|
}
|
||||||
fprintf (stderr, " %s%*s%s\n", "all", max_width - 3, " ", "Enable all values");
|
fprintf (stderr, " %s%*s%s\n", "all", max_width - 3, " ", "Enable all values. Other given values are subtracted");
|
||||||
fprintf (stderr, " %s%*s%s\n", "help", max_width - 4, " ", "Print this help");
|
fprintf (stderr, " %s%*s%s\n", "help", max_width - 4, " ", "Print this help");
|
||||||
fprintf (stderr, "\nMultiple values can be given, separated by : or space.\n");
|
fprintf (stderr, "\nMultiple values can be given, separated by : or space.\n");
|
||||||
}
|
}
|
||||||
|
@@ -42,6 +42,9 @@
|
|||||||
#include <gdk/gdkdevicetool.h>
|
#include <gdk/gdkdevicetool.h>
|
||||||
#include <gdk/gdkdisplay.h>
|
#include <gdk/gdkdisplay.h>
|
||||||
#include <gdk/gdkdisplaymanager.h>
|
#include <gdk/gdkdisplaymanager.h>
|
||||||
|
#include <gdk/gdkdmabufformats.h>
|
||||||
|
#include <gdk/gdkdmabuftexture.h>
|
||||||
|
#include <gdk/gdkdmabuftexturebuilder.h>
|
||||||
#include <gdk/gdkdrag.h>
|
#include <gdk/gdkdrag.h>
|
||||||
#include <gdk/gdkdragsurface.h>
|
#include <gdk/gdkdragsurface.h>
|
||||||
#include <gdk/gdkdragsurfacesize.h>
|
#include <gdk/gdkdragsurfacesize.h>
|
||||||
|
@@ -82,6 +82,18 @@ gdk_array(init) (GdkArray *self)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
G_GNUC_UNUSED static inline gsize
|
||||||
|
gdk_array(get_capacity) (const GdkArray *self)
|
||||||
|
{
|
||||||
|
return self->end_allocation - self->start;
|
||||||
|
}
|
||||||
|
|
||||||
|
G_GNUC_UNUSED static inline gsize
|
||||||
|
gdk_array(get_size) (const GdkArray *self)
|
||||||
|
{
|
||||||
|
return self->end - self->start;
|
||||||
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
gdk_array(free_elements) (_T_ *start,
|
gdk_array(free_elements) (_T_ *start,
|
||||||
_T_ *end)
|
_T_ *end)
|
||||||
@@ -110,6 +122,38 @@ gdk_array(clear) (GdkArray *self)
|
|||||||
gdk_array(init) (self);
|
gdk_array(init) (self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* gdk_array_steal:
|
||||||
|
* @self: the array
|
||||||
|
*
|
||||||
|
* Steals all data in the array and clears the array.
|
||||||
|
*
|
||||||
|
* If you need to know the size of the data, you should query it
|
||||||
|
* beforehand.
|
||||||
|
*
|
||||||
|
* Returns: The array's data
|
||||||
|
**/
|
||||||
|
G_GNUC_UNUSED static inline _T_ *
|
||||||
|
gdk_array(steal) (GdkArray *self)
|
||||||
|
{
|
||||||
|
_T_ *result;
|
||||||
|
|
||||||
|
#ifdef GDK_ARRAY_PREALLOC
|
||||||
|
if (self->start == self->preallocated)
|
||||||
|
{
|
||||||
|
gsize size = GDK_ARRAY_REAL_SIZE (gdk_array(get_size) (self));
|
||||||
|
result = g_new (_T_, size);
|
||||||
|
memcpy (result, self->preallocated, sizeof (_T_) * size);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
result = self->start;
|
||||||
|
|
||||||
|
gdk_array(init) (self);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
G_GNUC_UNUSED static inline _T_ *
|
G_GNUC_UNUSED static inline _T_ *
|
||||||
gdk_array(get_data) (const GdkArray *self)
|
gdk_array(get_data) (const GdkArray *self)
|
||||||
{
|
{
|
||||||
@@ -123,18 +167,6 @@ gdk_array(index) (const GdkArray *self,
|
|||||||
return self->start + pos;
|
return self->start + pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
G_GNUC_UNUSED static inline gsize
|
|
||||||
gdk_array(get_capacity) (const GdkArray *self)
|
|
||||||
{
|
|
||||||
return self->end_allocation - self->start;
|
|
||||||
}
|
|
||||||
|
|
||||||
G_GNUC_UNUSED static inline gsize
|
|
||||||
gdk_array(get_size) (const GdkArray *self)
|
|
||||||
{
|
|
||||||
return self->end - self->start;
|
|
||||||
}
|
|
||||||
|
|
||||||
G_GNUC_UNUSED static inline gboolean
|
G_GNUC_UNUSED static inline gboolean
|
||||||
gdk_array(is_empty) (const GdkArray *self)
|
gdk_array(is_empty) (const GdkArray *self)
|
||||||
{
|
{
|
||||||
@@ -151,7 +183,7 @@ gdk_array(reserve) (GdkArray *self,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
size = gdk_array(get_size) (self);
|
size = gdk_array(get_size) (self);
|
||||||
new_size = 1 << g_bit_storage (MAX (GDK_ARRAY_REAL_SIZE (n), 16) - 1);
|
new_size = ((gsize) 1) << g_bit_storage (MAX (GDK_ARRAY_REAL_SIZE (n), 16) - 1);
|
||||||
|
|
||||||
#ifdef GDK_ARRAY_PREALLOC
|
#ifdef GDK_ARRAY_PREALLOC
|
||||||
if (self->start == self->preallocated)
|
if (self->start == self->preallocated)
|
||||||
@@ -183,7 +215,11 @@ gdk_array(splice) (GdkArray *self,
|
|||||||
gsize pos,
|
gsize pos,
|
||||||
gsize removed,
|
gsize removed,
|
||||||
gboolean stolen,
|
gboolean stolen,
|
||||||
|
#ifdef GDK_ARRAY_BY_VALUE
|
||||||
|
const _T_ *additions,
|
||||||
|
#else
|
||||||
_T_ *additions,
|
_T_ *additions,
|
||||||
|
#endif
|
||||||
gsize added)
|
gsize added)
|
||||||
{
|
{
|
||||||
gsize size;
|
gsize size;
|
||||||
@@ -286,3 +322,5 @@ gdk_array(get) (const GdkArray *self,
|
|||||||
#undef GDK_ARRAY_TYPE_NAME
|
#undef GDK_ARRAY_TYPE_NAME
|
||||||
#undef GDK_ARRAY_NO_MEMSET
|
#undef GDK_ARRAY_NO_MEMSET
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
@@ -36,23 +36,26 @@ typedef enum {
|
|||||||
GDK_DEBUG_VULKAN = 1 << 8,
|
GDK_DEBUG_VULKAN = 1 << 8,
|
||||||
GDK_DEBUG_SELECTION = 1 << 9,
|
GDK_DEBUG_SELECTION = 1 << 9,
|
||||||
GDK_DEBUG_CLIPBOARD = 1 << 10,
|
GDK_DEBUG_CLIPBOARD = 1 << 10,
|
||||||
|
GDK_DEBUG_DMABUF = 1 << 11,
|
||||||
|
|
||||||
/* flags below are influencing behavior */
|
/* flags below are influencing behavior */
|
||||||
GDK_DEBUG_NOGRABS = 1 << 11,
|
GDK_DEBUG_NOGRABS = 1 << 12,
|
||||||
GDK_DEBUG_PORTALS = 1 << 12,
|
GDK_DEBUG_PORTALS = 1 << 13,
|
||||||
GDK_DEBUG_NO_PORTALS = 1 << 13,
|
GDK_DEBUG_NO_PORTALS = 1 << 14,
|
||||||
GDK_DEBUG_GL_DISABLE = 1 << 14,
|
GDK_DEBUG_GL_DISABLE = 1 << 15,
|
||||||
GDK_DEBUG_GL_FRACTIONAL = 1 << 15,
|
GDK_DEBUG_GL_FRACTIONAL = 1 << 16,
|
||||||
GDK_DEBUG_GL_LEGACY = 1 << 16,
|
GDK_DEBUG_GL_LEGACY = 1 << 17,
|
||||||
GDK_DEBUG_GL_GLES = 1 << 17,
|
GDK_DEBUG_GL_GLES = 1 << 18,
|
||||||
GDK_DEBUG_GL_DEBUG = 1 << 18,
|
GDK_DEBUG_GL_DEBUG = 1 << 19,
|
||||||
GDK_DEBUG_GL_EGL = 1 << 19,
|
GDK_DEBUG_GL_EGL = 1 << 20,
|
||||||
GDK_DEBUG_GL_GLX = 1 << 20,
|
GDK_DEBUG_GL_GLX = 1 << 21,
|
||||||
GDK_DEBUG_GL_WGL = 1 << 21,
|
GDK_DEBUG_GL_WGL = 1 << 22,
|
||||||
GDK_DEBUG_VULKAN_DISABLE = 1 << 22,
|
GDK_DEBUG_VULKAN_DISABLE = 1 << 23,
|
||||||
GDK_DEBUG_VULKAN_VALIDATE = 1 << 23,
|
GDK_DEBUG_VULKAN_VALIDATE = 1 << 24,
|
||||||
GDK_DEBUG_DEFAULT_SETTINGS= 1 << 24,
|
GDK_DEBUG_DEFAULT_SETTINGS= 1 << 25,
|
||||||
GDK_DEBUG_HIGH_DEPTH = 1 << 25,
|
GDK_DEBUG_HIGH_DEPTH = 1 << 26,
|
||||||
GDK_DEBUG_NO_VSYNC = 1 << 26,
|
GDK_DEBUG_NO_VSYNC = 1 << 27,
|
||||||
|
GDK_DEBUG_DMABUF_DISABLE = 1 << 28,
|
||||||
} GdkDebugFlags;
|
} GdkDebugFlags;
|
||||||
|
|
||||||
extern guint _gdk_debug_flags;
|
extern guint _gdk_debug_flags;
|
||||||
|
111
gdk/gdkdisplay.c
@@ -31,6 +31,9 @@
|
|||||||
#include "gdkclipboardprivate.h"
|
#include "gdkclipboardprivate.h"
|
||||||
#include "gdkdeviceprivate.h"
|
#include "gdkdeviceprivate.h"
|
||||||
#include "gdkdisplaymanagerprivate.h"
|
#include "gdkdisplaymanagerprivate.h"
|
||||||
|
#include "gdkdmabufformatsbuilderprivate.h"
|
||||||
|
#include "gdkdmabufformatsprivate.h"
|
||||||
|
#include "gdkdmabuftextureprivate.h"
|
||||||
#include "gdkeventsprivate.h"
|
#include "gdkeventsprivate.h"
|
||||||
#include "gdkframeclockidleprivate.h"
|
#include "gdkframeclockidleprivate.h"
|
||||||
#include "gdkglcontextprivate.h"
|
#include "gdkglcontextprivate.h"
|
||||||
@@ -69,6 +72,7 @@ enum
|
|||||||
PROP_COMPOSITED,
|
PROP_COMPOSITED,
|
||||||
PROP_RGBA,
|
PROP_RGBA,
|
||||||
PROP_INPUT_SHAPES,
|
PROP_INPUT_SHAPES,
|
||||||
|
PROP_DMABUF_FORMATS,
|
||||||
LAST_PROP
|
LAST_PROP
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -138,6 +142,10 @@ gdk_display_get_property (GObject *object,
|
|||||||
g_value_set_boolean (value, gdk_display_supports_input_shapes (display));
|
g_value_set_boolean (value, gdk_display_supports_input_shapes (display));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PROP_DMABUF_FORMATS:
|
||||||
|
g_value_set_boxed (value, gdk_display_get_dmabuf_formats (display));
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
}
|
}
|
||||||
@@ -239,6 +247,11 @@ gdk_display_class_init (GdkDisplayClass *class)
|
|||||||
TRUE,
|
TRUE,
|
||||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
||||||
|
|
||||||
|
props[PROP_DMABUF_FORMATS] =
|
||||||
|
g_param_spec_boxed ("dmabuf-formats", NULL, NULL,
|
||||||
|
GDK_TYPE_DMABUF_FORMATS,
|
||||||
|
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
||||||
|
|
||||||
g_object_class_install_properties (object_class, LAST_PROP, props);
|
g_object_class_install_properties (object_class, LAST_PROP, props);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -378,6 +391,9 @@ gdk_display_dispose (GObject *object)
|
|||||||
|
|
||||||
g_queue_clear (&display->queued_events);
|
g_queue_clear (&display->queued_events);
|
||||||
|
|
||||||
|
g_clear_object (&display->egl_gsk_renderer);
|
||||||
|
g_clear_pointer (&display->egl_external_formats, gdk_dmabuf_formats_unref);
|
||||||
|
|
||||||
g_clear_object (&priv->gl_context);
|
g_clear_object (&priv->gl_context);
|
||||||
#ifdef HAVE_EGL
|
#ifdef HAVE_EGL
|
||||||
g_clear_pointer (&priv->egl_display, eglTerminate);
|
g_clear_pointer (&priv->egl_display, eglTerminate);
|
||||||
@@ -404,6 +420,8 @@ gdk_display_finalize (GObject *object)
|
|||||||
|
|
||||||
g_list_free_full (display->seats, g_object_unref);
|
g_list_free_full (display->seats, g_object_unref);
|
||||||
|
|
||||||
|
g_clear_pointer (&display->dmabuf_formats, gdk_dmabuf_formats_unref);
|
||||||
|
|
||||||
G_OBJECT_CLASS (gdk_display_parent_class)->finalize (object);
|
G_OBJECT_CLASS (gdk_display_parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -473,8 +491,7 @@ gdk_display_get_event (GdkDisplay *display)
|
|||||||
* @display: a `GdkDisplay`
|
* @display: a `GdkDisplay`
|
||||||
* @event: (transfer none): a `GdkEvent`
|
* @event: (transfer none): a `GdkEvent`
|
||||||
*
|
*
|
||||||
* Appends the given event onto the front of the event
|
* Adds the given event to the event queue for @display.
|
||||||
* queue for @display.
|
|
||||||
*
|
*
|
||||||
* Deprecated: 4.10: This function is only useful in very
|
* Deprecated: 4.10: This function is only useful in very
|
||||||
* special situations and should not be used by applications.
|
* special situations and should not be used by applications.
|
||||||
@@ -1756,6 +1773,10 @@ gdk_display_init_egl (GdkDisplay *self,
|
|||||||
epoxy_has_egl_extension (priv->egl_display, "EGL_KHR_no_config_context");
|
epoxy_has_egl_extension (priv->egl_display, "EGL_KHR_no_config_context");
|
||||||
self->have_egl_pixel_format_float =
|
self->have_egl_pixel_format_float =
|
||||||
epoxy_has_egl_extension (priv->egl_display, "EGL_EXT_pixel_format_float");
|
epoxy_has_egl_extension (priv->egl_display, "EGL_EXT_pixel_format_float");
|
||||||
|
self->have_egl_dma_buf_import =
|
||||||
|
epoxy_has_egl_extension (priv->egl_display, "EGL_EXT_image_dma_buf_import_modifiers");
|
||||||
|
self->have_egl_dma_buf_export =
|
||||||
|
epoxy_has_egl_extension (priv->egl_display, "EGL_MESA_image_dma_buf_export");
|
||||||
|
|
||||||
if (self->have_egl_no_config_context)
|
if (self->have_egl_no_config_context)
|
||||||
priv->egl_config_high_depth = gdk_display_create_egl_config (self,
|
priv->egl_config_high_depth = gdk_display_create_egl_config (self,
|
||||||
@@ -1825,6 +1846,92 @@ gdk_display_get_egl_display (GdkDisplay *self)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_DMABUF
|
||||||
|
static void
|
||||||
|
gdk_display_add_dmabuf_downloader (GdkDisplay *display,
|
||||||
|
const GdkDmabufDownloader *downloader,
|
||||||
|
GdkDmabufFormatsBuilder *builder)
|
||||||
|
{
|
||||||
|
gsize i;
|
||||||
|
|
||||||
|
if (!downloader->add_formats (downloader, display, builder))
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* dmabuf_downloaders is NULL-terminated */
|
||||||
|
for (i = 0; i < G_N_ELEMENTS (display->dmabuf_downloaders) - 1; i++)
|
||||||
|
{
|
||||||
|
if (display->dmabuf_downloaders[i] == NULL)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_assert (i < G_N_ELEMENTS (display->dmabuf_downloaders));
|
||||||
|
|
||||||
|
display->dmabuf_downloaders[i] = downloader;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* To support a drm format, we must be able to import it into GL
|
||||||
|
* using the relevant EGL extensions, and download it into a memory
|
||||||
|
* texture, possibly doing format conversion with shaders (in GSK).
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
gdk_display_init_dmabuf (GdkDisplay *self)
|
||||||
|
{
|
||||||
|
GdkDmabufFormatsBuilder *builder;
|
||||||
|
|
||||||
|
if (self->dmabuf_formats != NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
GDK_DISPLAY_DEBUG (self, DMABUF,
|
||||||
|
"Beginning initialization of dmabuf support");
|
||||||
|
|
||||||
|
builder = gdk_dmabuf_formats_builder_new ();
|
||||||
|
|
||||||
|
#ifdef HAVE_DMABUF
|
||||||
|
if (!GDK_DEBUG_CHECK (DMABUF_DISABLE))
|
||||||
|
{
|
||||||
|
gdk_display_prepare_gl (self, NULL);
|
||||||
|
|
||||||
|
gdk_display_add_dmabuf_downloader (self, gdk_dmabuf_get_direct_downloader (), builder);
|
||||||
|
|
||||||
|
#ifdef HAVE_EGL
|
||||||
|
if (gdk_display_prepare_gl (self, NULL))
|
||||||
|
gdk_display_add_dmabuf_downloader (self, gdk_dmabuf_get_egl_downloader (), builder);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
self->dmabuf_formats = gdk_dmabuf_formats_builder_free_to_formats (builder);
|
||||||
|
|
||||||
|
GDK_DISPLAY_DEBUG (self, DMABUF,
|
||||||
|
"Initialized support for %zu dmabuf formats",
|
||||||
|
gdk_dmabuf_formats_get_n_formats (self->dmabuf_formats));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gdk_display_get_dmabuf_formats:
|
||||||
|
* @display: a `GdkDisplay`
|
||||||
|
*
|
||||||
|
* Returns the dma-buf formats that are supported on this display.
|
||||||
|
*
|
||||||
|
* GTK may use OpenGL or Vulkan to support some formats.
|
||||||
|
* Calling this function will then initialize them if they aren't yet.
|
||||||
|
*
|
||||||
|
* The formats returned by this function can be used for negotiating
|
||||||
|
* buffer formats with producers such as v4l, pipewire or GStreamer.
|
||||||
|
*
|
||||||
|
* Returns: (transfer none): a `GdkDmabufFormats` object
|
||||||
|
*
|
||||||
|
* Since: 4.14
|
||||||
|
*/
|
||||||
|
GdkDmabufFormats *
|
||||||
|
gdk_display_get_dmabuf_formats (GdkDisplay *display)
|
||||||
|
{
|
||||||
|
gdk_display_init_dmabuf (display);
|
||||||
|
|
||||||
|
return display->dmabuf_formats;
|
||||||
|
}
|
||||||
|
|
||||||
GdkDebugFlags
|
GdkDebugFlags
|
||||||
gdk_display_get_debug_flags (GdkDisplay *display)
|
gdk_display_get_debug_flags (GdkDisplay *display)
|
||||||
{
|
{
|
||||||
|
@@ -134,6 +134,10 @@ gboolean gdk_display_get_setting (GdkDisplay *display,
|
|||||||
const char *name,
|
const char *name,
|
||||||
GValue *value);
|
GValue *value);
|
||||||
|
|
||||||
|
GDK_AVAILABLE_IN_4_14
|
||||||
|
GdkDmabufFormats *
|
||||||
|
gdk_display_get_dmabuf_formats (GdkDisplay *display);
|
||||||
|
|
||||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkDisplay, g_object_unref)
|
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkDisplay, g_object_unref)
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
@@ -25,6 +25,7 @@
|
|||||||
#include "gdksurfaceprivate.h"
|
#include "gdksurfaceprivate.h"
|
||||||
#include "gdkkeysprivate.h"
|
#include "gdkkeysprivate.h"
|
||||||
#include "gdkdeviceprivate.h"
|
#include "gdkdeviceprivate.h"
|
||||||
|
#include "gdkdmabufprivate.h"
|
||||||
|
|
||||||
#ifdef GDK_RENDERING_VULKAN
|
#ifdef GDK_RENDERING_VULKAN
|
||||||
#include <vulkan/vulkan.h>
|
#include <vulkan/vulkan.h>
|
||||||
@@ -113,6 +114,15 @@ struct _GdkDisplay
|
|||||||
guint have_egl_buffer_age : 1;
|
guint have_egl_buffer_age : 1;
|
||||||
guint have_egl_no_config_context : 1;
|
guint have_egl_no_config_context : 1;
|
||||||
guint have_egl_pixel_format_float : 1;
|
guint have_egl_pixel_format_float : 1;
|
||||||
|
guint have_egl_dma_buf_import : 1;
|
||||||
|
guint have_egl_dma_buf_export : 1;
|
||||||
|
|
||||||
|
GdkDmabufFormats *dmabuf_formats;
|
||||||
|
const GdkDmabufDownloader *dmabuf_downloaders[4];
|
||||||
|
|
||||||
|
/* Cached data the EGL dmabuf downloader */
|
||||||
|
gpointer egl_gsk_renderer;
|
||||||
|
GdkDmabufFormats *egl_external_formats;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GdkDisplayClass
|
struct _GdkDisplayClass
|
||||||
@@ -207,6 +217,8 @@ gulong _gdk_display_get_next_serial (GdkDisplay *display
|
|||||||
void _gdk_display_pause_events (GdkDisplay *display);
|
void _gdk_display_pause_events (GdkDisplay *display);
|
||||||
void _gdk_display_unpause_events (GdkDisplay *display);
|
void _gdk_display_unpause_events (GdkDisplay *display);
|
||||||
|
|
||||||
|
void gdk_display_init_dmabuf (GdkDisplay *self);
|
||||||
|
|
||||||
GdkVulkanContext * gdk_display_create_vulkan_context (GdkDisplay *self,
|
GdkVulkanContext * gdk_display_create_vulkan_context (GdkDisplay *self,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
|