Compare commits
562 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d4dfbc1def | |||
| fb73acc885 | |||
| acad0e8893 | |||
| d869aec29f | |||
| aae99a8704 | |||
| 19ba03d0a6 | |||
| ac59d553ce | |||
| 9991d6834d | |||
| ddf8c4dd1a | |||
| 970072ef65 | |||
| f8321029fc | |||
| f83cab01ec | |||
| 8a74770ec1 | |||
| 39c503c108 | |||
| fc32b8242b | |||
| 7c2b4eb0e7 | |||
| d8b0aea6b7 | |||
| 190d8ef8ff | |||
| 15e9194b59 | |||
| 0257da6cc0 | |||
| 907f878c9f | |||
| b2071cdeb5 | |||
| 1a292bf8ab | |||
| 7e07d63a6c | |||
| 824e983372 | |||
| 9e5417c6c7 | |||
| e94dae8536 | |||
| 0dd163254d | |||
| 341ecab41a | |||
| 9eac7ed8b9 | |||
| 4005eb8fe8 | |||
| 1d4ceac2c5 | |||
| a5246a6856 | |||
| 11d235d165 | |||
| af00beb772 | |||
| e5cd9354d5 | |||
| 6426ab7466 | |||
| b710df6f45 | |||
| 50998b0ee9 | |||
| 92c2c68c7b | |||
| c2f5b64b5d | |||
| 460bf6d8b9 | |||
| a0dff87c86 | |||
| 3015b9f120 | |||
| 01549e3c91 | |||
| bc48bfc2b6 | |||
| 6100258ba2 | |||
| e083bd7920 | |||
| e915546b44 | |||
| b6cfe35940 | |||
| 4cd9fd9b15 | |||
| 6f8cab0e9d | |||
| 6eb9161906 | |||
| d13695f586 | |||
| 749919c551 | |||
| 58980e0b4a | |||
| 5813a5cace | |||
| f88b777fe5 | |||
| a80af681b8 | |||
| 94695bb276 | |||
| be36113826 | |||
| 5dfbaa53fc | |||
| a13ddcb67b | |||
| d228bae365 | |||
| 463f12a3bb | |||
| 3f87b130ba | |||
| c17049c6d1 | |||
| f000baf0d6 | |||
| aef4c50155 | |||
| 2a1e4b8621 | |||
| cabd18fba0 | |||
| 1da4782262 | |||
| 8911ed5d9b | |||
| 294b659dc1 | |||
| 7ad74ad6c3 | |||
| bb777507ce | |||
| 1e1d79d4f7 | |||
| a254a4529f | |||
| e7bd691532 | |||
| 4e62350232 | |||
| 2c883a70e2 | |||
| 3dfeb2fd37 | |||
| 3ba3e8286f | |||
| fbf4817ef5 | |||
| db43e0669f | |||
| 386c77b13d | |||
| e6998dffe8 | |||
| 12057c8a30 | |||
| b7c422cb98 | |||
| 1c76f6586b | |||
| d43968f7b6 | |||
| 26650787e1 | |||
| b4ef072188 | |||
| 3858c5282c | |||
| 1ff8dad8ec | |||
| d8cb11ec4a | |||
| 8796950651 | |||
| c6cef6db52 | |||
| fdea27c04d | |||
| a52f9d6def | |||
| ee272646c9 | |||
| 6655177a0b | |||
| cb78f0d10a | |||
| 1cb621633c | |||
| ce25efeee7 | |||
| 375b554924 | |||
| 69eed999bb | |||
| cab5f2bd8d | |||
| 35e3c22832 | |||
| 92612c2265 | |||
| 4e1b46a7ec | |||
| 55f7f7d0ee | |||
| 442cd4a369 | |||
| 53af41e2fa | |||
| c43e1f3d0a | |||
| 32e855ad61 | |||
| 034a8a5501 | |||
| 1e9dbf2df0 | |||
| dce21f06dd | |||
| 56c1c4152f | |||
| a9d2fa296e | |||
| 5bccb106c2 | |||
| 45086487f1 | |||
| 65f03121a4 | |||
| 09769193d7 | |||
| 7f8acf960b | |||
| ee0e026237 | |||
| 6bfd581a72 | |||
| 7b6f254e64 | |||
| 47955cfe62 | |||
| e62ca17f88 | |||
| c24ba58acb | |||
| 30987168fb | |||
| 93a875bf20 | |||
| aac3bf581a | |||
| 869f07521c | |||
| 7e392a1186 | |||
| 53d87e42a5 | |||
| 6757a1b409 | |||
| 115738dd2f | |||
| 5caa66ffb7 | |||
| 7df73c4fd2 | |||
| 1ea5a08c8f | |||
| 9c669cbe90 | |||
| 1a5184bc85 | |||
| 8f2ad8f154 | |||
| d6ef39b9a2 | |||
| 52f6acd398 | |||
| 2f894bb4ef | |||
| 2509fe0d17 | |||
| 83a5611ce8 | |||
| 136c1ccd2c | |||
| 16e23b3f9e | |||
| af088d5e11 | |||
| a6e1c5c96a | |||
| 3c8c54ed15 | |||
| 628aeda7ee | |||
| 2669dc269b | |||
| c4d3d72c57 | |||
| cd79159420 | |||
| 1bc63eeadb | |||
| 071c6c60c0 | |||
| fc24f401b7 | |||
| 6c96e51b07 | |||
| e703163bc4 | |||
| ad549cbded | |||
| 673beef210 | |||
| 55baa1f2e1 | |||
| 1d8a23e97b | |||
| 422b4b6561 | |||
| 27ee8b23fd | |||
| b9847795a7 | |||
| b13f05537b | |||
| 757d1916ae | |||
| 0834dac6ee | |||
| 3c31f72219 | |||
| a0f63160d6 | |||
| c99d85954a | |||
| 33f31d06f9 | |||
| bf4b40f17e | |||
| 7aba9e3295 | |||
| 3080cb7acd | |||
| 4b404f0dea | |||
| 0c1c0524c7 | |||
| b58ef290dc | |||
| 1387fba7f8 | |||
| 34b9ec5be2 | |||
| cefdfbd894 | |||
| 3676ddbdff | |||
| 7c1a0e0c15 | |||
| 19bb043a85 | |||
| fecc80b59c | |||
| 1648dc36f8 | |||
| a27a2cbf40 | |||
| e418656a04 | |||
| d4ec1afe44 | |||
| 420be8fb0f | |||
| 9c3629653f | |||
| eb5cf831b1 | |||
| 374d97008b | |||
| fecc923c2c | |||
| 703ed608c0 | |||
| 99f07c7c0a | |||
| 51b4d70b8f | |||
| 746d12fc43 | |||
| 96ce9e10b8 | |||
| 3090795351 | |||
| 815b54f3df | |||
| 9ad27e4371 | |||
| a6e1804474 | |||
| 7ae549e253 | |||
| 434d8ef0ea | |||
| 31a6d73635 | |||
| 958ecf2855 | |||
| fb12ad807a | |||
| 965c52d369 | |||
| 474872563f | |||
| b92e52bf0e | |||
| d226dc3812 | |||
| 46e0fde606 | |||
| 1e7f525e0e | |||
| d43e0fb9a7 | |||
| 6fb6f47fc8 | |||
| 0f7d8e04d8 | |||
| c9fca559dc | |||
| b9d1b5d6a3 | |||
| 5f75ba46a5 | |||
| 2507301983 | |||
| 41aeff331d | |||
| 3aab48ec16 | |||
| ad0348b85e | |||
| 6a134551b9 | |||
| 0e1ae6ad11 | |||
| 5baf4b4b2e | |||
| 63560061e8 | |||
| be721f5797 | |||
| 0073bb79a7 | |||
| f59b506674 | |||
| 88b4404296 | |||
| e20bc7723a | |||
| 7edf8841fb | |||
| 6b5b7eab04 | |||
| c775262e9d | |||
| 553fde9761 | |||
| f2593dec4b | |||
| ab5a6ed0f1 | |||
| dd3cdc52f5 | |||
| 5a3156a8b7 | |||
| a4c2f19155 | |||
| be8fb1e9b8 | |||
| 52c97dbf67 | |||
| 57ebf26f15 | |||
| 32247bc50e | |||
| ad940bc892 | |||
| 7d34e7e0f7 | |||
| b2f43076bd | |||
| 202e889577 | |||
| a8690c84ab | |||
| 35244f4b59 | |||
| 503c3ec04d | |||
| 4a5a466975 | |||
| e694511da3 | |||
| 0a94827b9c | |||
| 735cf301a4 | |||
| e8a29f90d1 | |||
| 182cc74834 | |||
| 7801dd8944 | |||
| 38e090f5c1 | |||
| 998c382037 | |||
| ac81e71f78 | |||
| de271c9a30 | |||
| bf3cf8bb29 | |||
| 63fa5b7f52 | |||
| 96add330f5 | |||
| 44aa6a891a | |||
| 7a30a21405 | |||
| 2b3eadcfa4 | |||
| 352443d5a5 | |||
| 3574fde770 | |||
| 793689789c | |||
| 120396fa40 | |||
| d61ec38974 | |||
| 2a463baed0 | |||
| 348acde6bd | |||
| 5ba793842b | |||
| 149b608bfc | |||
| 3348ea81f2 | |||
| 63e69131bd | |||
| d42a34b0b3 | |||
| 5ee10fc669 | |||
| b0a4917ce4 | |||
| 47e22d6301 | |||
| b970b60503 | |||
| 7406f8165d | |||
| 9435e689c3 | |||
| 66c947b86b | |||
| ad1af87834 | |||
| 68700f8722 | |||
| f76270167c | |||
| 2a442c4fbb | |||
| 9356dfc404 | |||
| 7eb8439047 | |||
| 0ccf9ad8fc | |||
| c52978dfa4 | |||
| 52dfa54301 | |||
| b6f9e00a9e | |||
| 8780aa02d7 | |||
| 8d5a39d765 | |||
| 446e6a8d62 | |||
| 9b1bee99b8 | |||
| 77cf0f1719 | |||
| fc1f1366b4 | |||
| 6efd1a9dad | |||
| 8349ae2bc4 | |||
| 7c5c843b5b | |||
| bc11bc4f8d | |||
| be24e4a1f7 | |||
| 918ff1d0f4 | |||
| 20723613bc | |||
| 604aafe15d | |||
| 4041ca0f69 | |||
| 3526d8b299 | |||
| e8adfa2a88 | |||
| 7fab1b85ad | |||
| 5aeabdb3d4 | |||
| 6f01f846dc | |||
| 3c4f6144a0 | |||
| ae71d338d7 | |||
| 8b469a2727 | |||
| 53813f24f0 | |||
| 1fde83f12b | |||
| 1f7783224b | |||
| 0d04ceda76 | |||
| 9396ccf9ff | |||
| 5a68639788 | |||
| 85df554ec1 | |||
| 8776ebfe90 | |||
| 83eee03b0f | |||
| d7bba4ebac | |||
| 40e2b5b153 | |||
| f7a7313758 | |||
| 2d9ce0357f | |||
| 0ea05896df | |||
| 8c638df147 | |||
| 6605ded4c9 | |||
| ba1a9530c8 | |||
| a9fcea369e | |||
| ca2787fbba | |||
| 6d2c897dfc | |||
| 01f81b2d77 | |||
| 8a3c5c63e8 | |||
| b688f47776 | |||
| e126110ae0 | |||
| f98406b080 | |||
| 40a2910262 | |||
| ec84077486 | |||
| 188f9269b7 | |||
| 7ad693f865 | |||
| 913e3680f3 | |||
| f3ad6015c6 | |||
| 4e694c1824 | |||
| 0214cb5b1b | |||
| 12bd668f4d | |||
| f7fb069e2f | |||
| 7213bf5b09 | |||
| 5eb4a3af0d | |||
| c4c747d2ad | |||
| 671fad5f34 | |||
| 1b9c45b660 | |||
| e2f730c0bf | |||
| 8a2d35b9fb | |||
| 26cec4a021 | |||
| 8d8e83afa2 | |||
| 381bb84f3d | |||
| 977fedfdf1 | |||
| 8957302bd4 | |||
| 8a7f739f9f | |||
| fce4810fb4 | |||
| d5ba76a82c | |||
| 1cd44ec7b7 | |||
| 424d56830a | |||
| 7fc4d02851 | |||
| e7f798dcf5 | |||
| f6bd63c9ad | |||
| 99320f99c3 | |||
| 8ecb624934 | |||
| 123eebb93d | |||
| b6596d5313 | |||
| ffe333a21f | |||
| 257ca10eb1 | |||
| ae097d9674 | |||
| 1659c59410 | |||
| cf91e09d75 | |||
| 020636c49f | |||
| 59df956f4f | |||
| 09691ead4c | |||
| 18a7f715c4 | |||
| d1347bbf33 | |||
| 1b816c91d0 | |||
| 5df0cbfa69 | |||
| 47b5d0d546 | |||
| 4f65c121b7 | |||
| a0de7884cd | |||
| b5b9cb189f | |||
| ee2152ff5c | |||
| d8d5cace2a | |||
| 21e9a508bd | |||
| 3121f88265 | |||
| b56224fc16 | |||
| 4346a33a63 | |||
| 596f59f471 | |||
| d758754f20 | |||
| e049b6992d | |||
| ca0bae2196 | |||
| a920c0d2de | |||
| 0db3666d3c | |||
| 2b808bf849 | |||
| 737342ef23 | |||
| cf709473f7 | |||
| ad83d616c4 | |||
| 98bb14a849 | |||
| efbd228940 | |||
| 64c8da1bdd | |||
| 7242408d60 | |||
| 9c6dd9b3b5 | |||
| cd77936265 | |||
| 53c37cfc17 | |||
| 1a1f92178e | |||
| 6b111a9fda | |||
| cc6b0c5750 | |||
| 235f01952c | |||
| e2291259bb | |||
| 6b71ccdb43 | |||
| c81a793f63 | |||
| 143229f829 | |||
| 3e86bc65f5 | |||
| b563736b66 | |||
| 2442ed87fe | |||
| 6cb5f20942 | |||
| aafc6279a3 | |||
| 2154460139 | |||
| ef17a44876 | |||
| 8eace1c385 | |||
| 1f001a8f6a | |||
| a2b00f7ea7 | |||
| 42ba97eb5c | |||
| e5560c1535 | |||
| 7fca091371 | |||
| 93e591fdf1 | |||
| 7081bfc614 | |||
| cd7627ed02 | |||
| ce9069c85f | |||
| 6e0def6474 | |||
| a471a8b57c | |||
| b0f65ead84 | |||
| e3f805f169 | |||
| 48bcae99af | |||
| 355b42b373 | |||
| 0bdf30dfbf | |||
| e8f70be2c1 | |||
| ea056d261f | |||
| c2c99a163a | |||
| eec8cf1309 | |||
| 18e0eaa9d6 | |||
| b8962fcba7 | |||
| fba4cea2e8 | |||
| 8cf9810240 | |||
| f0a76f2ca8 | |||
| 358d9d72d1 | |||
| aabb8dce91 | |||
| 80736d782b | |||
| 1464289710 | |||
| 72c676aecb | |||
| c717d10dda | |||
| ee5324359d | |||
| 10338a5237 | |||
| 1c5caf53b6 | |||
| 0bb6377a3a | |||
| ce12ab8307 | |||
| 27613e3bc5 | |||
| a9be0be32b | |||
| 6b83ded8f0 | |||
| cc23ef6eae | |||
| 089d0caa5e | |||
| d0c4413033 | |||
| 410fa9871f | |||
| eba9c4e4c3 | |||
| f94e9d26b5 | |||
| 69cc4b42cf | |||
| 66b4f2a9dd | |||
| 99d6eb9cb4 | |||
| 631b0fa9fd | |||
| e319b14dc2 | |||
| c96fefd7f5 | |||
| b1a9afbdba | |||
| 6bed0cfb5a | |||
| 973a8752ab | |||
| db3b216ad1 | |||
| b3b5a5064e | |||
| 9fd4b215ee | |||
| 5c70f2ae9b | |||
| 5df9f4016e | |||
| 6f7a4b67c2 | |||
| 6e7ecb02f1 | |||
| 146cf0bdd4 | |||
| 00bdad23b0 | |||
| 8ff3217712 | |||
| 7a50e31b8d | |||
| 1d9ee050f4 | |||
| 40d54ad3eb | |||
| a9b387b37b | |||
| 12f9883599 | |||
| 4e23fe896e | |||
| 0effe1fd07 | |||
| a07bf1a047 | |||
| 42cd230d44 | |||
| bc8e19fcd0 | |||
| ae29fee903 | |||
| 7ad0bae12f | |||
| 3e11ea9ddf | |||
| 5b6c98d589 | |||
| 57082e2e40 | |||
| 45e3e1594f | |||
| 637ef84d04 | |||
| b297baed32 | |||
| c45f172e79 | |||
| 417382375b | |||
| 2e90a752eb | |||
| abe5181b10 | |||
| 585b6a3637 | |||
| 3007b0fd7f | |||
| 96b9ac84f8 | |||
| 860c2f8ddd | |||
| de83d57e14 | |||
| 9de963e8b4 | |||
| 5e92c26b9a | |||
| 8c7b9c30de | |||
| 6bfb35f047 | |||
| 53c3cce5e4 | |||
| acd7d739f5 | |||
| 33e7774743 | |||
| 89c816a614 | |||
| c24358cfbc | |||
| 19aaa8fee5 | |||
| 43c1a433aa | |||
| 097d87e502 | |||
| ff8d88b097 | |||
| cc546d7af1 | |||
| 03db707f3c | |||
| a8cd2750f7 | |||
| ffad21a9d6 | |||
| 5419f1f2f0 | |||
| 6dd939f13e | |||
| c85fbcea55 | |||
| 789778105d | |||
| c36685bf60 | |||
| 26c524a578 | |||
| 30525835f3 | |||
| 818ca63d35 | |||
| 2290c2bb23 | |||
| b9551a8952 | |||
| e600fcbcc5 |
+77
-51
@@ -22,11 +22,11 @@ stages:
|
||||
|
||||
# Common variables
|
||||
variables:
|
||||
COMMON_MESON_FLAGS: "-Dwerror=true -Dglib:werror=false -Dpango:werror=false -Dgtk-doc:werror=false -Dwayland-protocols:werror=false -Dsysprof:werror=false -Dwayland:werror=false"
|
||||
COMMON_MESON_FLAGS: "-Dwerror=true -Dcairo:werror=false -Dgi-docgen:werror=false -Dgraphene:werror=false -Dlibepoxy:werror=false -Dlibsass:werror=false -Dpango:werror=false -Dsassc:werror=false -Dgdk-pixbuf:werror=false -Dglib:werror=false -Dlibcloudproviders:werror=false -Dlibpng:werror=false -Dlibtiff:werror=false -Dsysprof:werror=false -Dwayland-protocols:werror=false -Dharfbuzz:werror=false -Dfreetype2:werror=false -Dfontconfig:werror=false -Dfribidi:werror=false -Dlibffi:werror=false -Dlibjpeg-turbo:werror=false -Dmutest:werror=false -Dpixman:werror=false -Dproxy-libintl:werror=false"
|
||||
BACKEND_FLAGS: "-Dx11-backend=true -Dwayland-backend=true -Dbroadway-backend=true"
|
||||
FEATURE_FLAGS: "-Dvulkan=enabled -Dcloudproviders=enabled"
|
||||
FEATURE_FLAGS: "-Dvulkan=enabled -Dcloudproviders=enabled -Ddemos=false -Dbuild-examples=false -Dbuild-tests=false -Dbuild-testsuite=true"
|
||||
MESON_TEST_TIMEOUT_MULTIPLIER: 3
|
||||
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v38"
|
||||
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v40"
|
||||
FLATPAK_IMAGE: "quay.io/gnome_infrastructure/gnome-runtime-images:gnome-master"
|
||||
|
||||
.only-default:
|
||||
@@ -71,11 +71,6 @@ style-check-diff:
|
||||
key: "$CI_JOB_NAME"
|
||||
paths:
|
||||
- _ccache/
|
||||
- subprojects/gdk-pixbuf/
|
||||
- subprojects/glib/
|
||||
- subprojects/graphene/
|
||||
- subprojects/libepoxy/
|
||||
- subprojects/pango/
|
||||
|
||||
fedora-x86_64:
|
||||
extends: .build-fedora-default
|
||||
@@ -85,10 +80,17 @@ fedora-x86_64:
|
||||
EXTRA_MESON_FLAGS: "--buildtype=debug --default-library=both"
|
||||
script:
|
||||
- .gitlab-ci/show-info-linux.sh
|
||||
- meson subprojects update
|
||||
- export PATH="$HOME/.local/bin:$PATH"
|
||||
- pip3 install --user meson~=0.64
|
||||
- meson subprojects download
|
||||
- meson subprojects update --reset
|
||||
- mkdir _install
|
||||
- meson --prefix=${CI_PROJECT_DIR}/_install
|
||||
${COMMON_MESON_FLAGS} ${EXTRA_MESON_FLAGS} ${BACKEND_FLAGS} ${FEATURE_FLAGS}
|
||||
- meson setup
|
||||
--prefix=${CI_PROJECT_DIR}/_install
|
||||
${COMMON_MESON_FLAGS}
|
||||
${EXTRA_MESON_FLAGS}
|
||||
${BACKEND_FLAGS}
|
||||
${FEATURE_FLAGS}
|
||||
_build
|
||||
- meson compile -C _build
|
||||
- meson install -C _build
|
||||
@@ -107,10 +109,17 @@ release-build:
|
||||
EXTRA_MESON_FLAGS: "--buildtype=release"
|
||||
script:
|
||||
- .gitlab-ci/show-info-linux.sh
|
||||
- meson subprojects update
|
||||
- meson ${COMMON_MESON_FLAGS} ${EXTRA_MESON_FLAGS} ${BACKEND_FLAGS} ${FEATURE_FLAGS}
|
||||
- export PATH="$HOME/.local/bin:$PATH"
|
||||
- pip3 install --user meson~=0.64
|
||||
- meson subprojects download
|
||||
- meson subprojects update --reset
|
||||
- meson setup
|
||||
${COMMON_MESON_FLAGS}
|
||||
${EXTRA_MESON_FLAGS}
|
||||
${BACKEND_FLAGS}
|
||||
${FEATURE_FLAGS}
|
||||
_build
|
||||
- ninja -C _build
|
||||
- meson compile -C _build
|
||||
- .gitlab-ci/run-tests.sh _build x11
|
||||
|
||||
fedora-mingw64:
|
||||
@@ -131,34 +140,24 @@ fedora-mingw64:
|
||||
# mingw64-graphene (rawhide)
|
||||
script:
|
||||
- .gitlab-ci/show-info-linux.sh
|
||||
- meson subprojects update
|
||||
- mkdir _build && cd _build
|
||||
- mingw64-meson -Dintrospection=disabled -Dgraphene:introspection=disabled
|
||||
- ninja
|
||||
|
||||
installed-tests:
|
||||
extends: .build-fedora-default
|
||||
stage: build
|
||||
needs: []
|
||||
variables:
|
||||
EXTRA_MESON_FLAGS: "--prefix=/usr --libdir=/usr/lib64 -Dinstall-tests=true"
|
||||
G_TEST_ACCESSIBLE: 1
|
||||
script:
|
||||
- .gitlab-ci/show-info-linux.sh
|
||||
- meson subprojects update
|
||||
- meson ${COMMON_MESON_FLAGS} ${EXTRA_MESON_FLAGS} ${BACKEND_FLAGS} ${FEATURE_FLAGS}
|
||||
_build
|
||||
- export PATH="$HOME/.local/bin:$PATH"
|
||||
- pip3 install --user meson~=0.64
|
||||
- meson subprojects download
|
||||
- meson subprojects update --reset
|
||||
# Test that mingw64-meson still fails. If it has stopped failing, the CI
|
||||
# will fail and now you should remove the hack that follows this.
|
||||
- FAILED=false
|
||||
- mingw64-meson --version || FAILED=true
|
||||
- test $FAILED = false && echo "mingw64-meson works now, remove the hack" && exit 1
|
||||
# HACK: Running mingw64-meson directly fails on the CI with:
|
||||
# /usr/bin/mingw64-meson: line 92: fg: no job control
|
||||
# Because rpm is not evaluating %__meson and it gets interpreted as a job
|
||||
# specifier. So we fix that and run it ourselves.
|
||||
- rpm --eval "%{mingw64_meson}" > mingw64-meson.sh
|
||||
- sed -i -e 's/%__meson/meson/' mingw64-meson.sh
|
||||
- chmod +x mingw64-meson.sh
|
||||
- ./mingw64-meson.sh -Dintrospection=disabled -Dgraphene:introspection=disabled _build
|
||||
- ninja -C _build
|
||||
- sudo ninja -C _build install
|
||||
- dbus-run-session xvfb-run -a -s "-screen 0 1024x768x24"
|
||||
gnome-desktop-testing-runner
|
||||
--report-directory=_build/installed-tests-report/failed/
|
||||
--parallel=0
|
||||
gtk-4.0
|
||||
artifacts:
|
||||
paths:
|
||||
- "_build/installed-tests-report/"
|
||||
|
||||
|
||||
.mingw-defaults:
|
||||
extends: .only-default
|
||||
@@ -191,6 +190,8 @@ msys2-mingw64:
|
||||
- "${CI_PROJECT_DIR}/_build/gtkdll.tar.gz"
|
||||
|
||||
macos:
|
||||
# Sadly, this fails regularly, and its failure is never enlightening
|
||||
allow_failure: true
|
||||
extends: .only-default
|
||||
only:
|
||||
- branches@GNOME/gtk
|
||||
@@ -200,12 +201,13 @@ macos:
|
||||
needs: []
|
||||
before_script:
|
||||
- bash .gitlab-ci/show-info-osx.sh
|
||||
- pip3 install --user meson==0.60.3
|
||||
- pip3 install --user meson~=0.64
|
||||
- pip3 install --user ninja
|
||||
- export PATH=/Users/gitlabrunner/Library/Python/3.7/bin:$PATH
|
||||
- export MESON_FORCE_BACKTRACE=1
|
||||
script:
|
||||
- meson -Dx11-backend=false
|
||||
- meson setup ${COMMON_MESON_FLAGS}
|
||||
-Dx11-backend=false
|
||||
-Dbroadway-backend=true
|
||||
-Dmacos-backend=true
|
||||
-Dmedia-gstreamer=disabled
|
||||
@@ -213,8 +215,12 @@ macos:
|
||||
-Dcpp_std=c++11
|
||||
-Dpixman:tests=disabled
|
||||
-Dlibjpeg-turbo:simd=disabled
|
||||
-Ddemos=false
|
||||
-Dbuild-tests=false
|
||||
-Dbuild-examples=false
|
||||
-Dbuild-testsuite=false
|
||||
_build
|
||||
- ninja -C _build
|
||||
- meson compile -C _build
|
||||
artifacts:
|
||||
when: always
|
||||
paths:
|
||||
@@ -339,23 +345,31 @@ static-scan:
|
||||
variables:
|
||||
EXTRA_MESON_FLAGS: "--buildtype=debug"
|
||||
script:
|
||||
- meson ${COMMON_MESON_FLAGS} ${EXTRA_MESON_FLAGS} _scan_build
|
||||
- export PATH="$HOME/.local/bin:$PATH"
|
||||
- pip3 install --user meson~=0.64
|
||||
- meson setup
|
||||
${COMMON_MESON_FLAGS}
|
||||
${EXTRA_MESON_FLAGS}
|
||||
_scan_build
|
||||
- ninja -C _scan_build scan-build
|
||||
artifacts:
|
||||
paths:
|
||||
- _scan_build/meson-logs
|
||||
allow_failure: true
|
||||
|
||||
# Run tests with the address sanitizer. We need to turn off introspection,
|
||||
# since it is incompatible with asan
|
||||
# Run tests with the address sanitizer. We need to turn off introspection
|
||||
# and f16c, since they are incompatible with asan
|
||||
asan-build:
|
||||
image: $FEDORA_IMAGE
|
||||
tags: [ asan ]
|
||||
stage: analysis
|
||||
needs: []
|
||||
when: manual
|
||||
variables:
|
||||
script:
|
||||
- CC=clang meson --buildtype=debugoptimized -Db_sanitize=address -Db_lundef=false -Dintrospection=disabled _build
|
||||
- export PATH="$HOME/.local/bin:$PATH"
|
||||
- pip3 install --user meson~=0.64
|
||||
- CC=clang meson setup --buildtype=debugoptimized -Db_sanitize=address -Db_lundef=false -Dintrospection=disabled -Df16c=disabled _build
|
||||
- ninja -C _build
|
||||
- .gitlab-ci/run-tests.sh _build wayland
|
||||
artifacts:
|
||||
@@ -367,10 +381,22 @@ reference:
|
||||
image: $FEDORA_IMAGE
|
||||
stage: docs
|
||||
needs: []
|
||||
variables:
|
||||
EXTRA_MESON_FLAGS: "--buildtype=release --force-fallback-for=gdk-pixbuf,pango"
|
||||
script:
|
||||
- meson ${COMMON_MESON_FLAGS} ${EXTRA_MESON_FLAGS} -Dgtk_doc=true -Dgdk-pixbuf:gtk_doc=true -Dpango:gtk_doc=true _build
|
||||
- export PATH="$HOME/.local/bin:$PATH"
|
||||
- pip3 install --user meson~=0.64
|
||||
- meson setup
|
||||
${COMMON_MESON_FLAGS}
|
||||
--buildtype=release
|
||||
--force-fallback-for=gdk-pixbuf,pango
|
||||
-Dintrospection=enabled
|
||||
-Dgtk_doc=true
|
||||
-Dgdk-pixbuf:gtk_doc=true
|
||||
-Dpango:gtk_doc=true
|
||||
-Ddemos=false
|
||||
-Dbuild-examples=false
|
||||
-Dbuild-tests=false
|
||||
-Dbuild-testsuite=false
|
||||
_build
|
||||
- meson compile -C _build
|
||||
- mkdir -p _reference/
|
||||
- mv _build/docs/reference/gdk/gdk4/ _reference/gdk4/
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM fedora:36
|
||||
FROM fedora:37
|
||||
|
||||
RUN dnf -y install \
|
||||
adwaita-icon-theme \
|
||||
@@ -18,7 +18,9 @@ RUN dnf -y install \
|
||||
dejavu-sans-mono-fonts \
|
||||
desktop-file-utils \
|
||||
diffutils \
|
||||
docbook-style-xsl \
|
||||
elfutils-libelf-devel \
|
||||
expat-devel \
|
||||
fribidi-devel \
|
||||
gcc \
|
||||
gcc-c++ \
|
||||
@@ -31,6 +33,7 @@ RUN dnf -y install \
|
||||
glibc-devel \
|
||||
glibc-headers \
|
||||
gnome-desktop-testing \
|
||||
gnupg2 \
|
||||
gobject-introspection-devel \
|
||||
graphene-devel \
|
||||
graphviz \
|
||||
@@ -70,7 +73,6 @@ RUN dnf -y install \
|
||||
mesa-dri-drivers \
|
||||
mesa-libEGL-devel \
|
||||
mesa-libGLES-devel \
|
||||
meson \
|
||||
ninja-build \
|
||||
pango-devel \
|
||||
pcre-devel \
|
||||
@@ -82,7 +84,6 @@ RUN dnf -y install \
|
||||
python3-markdown \
|
||||
python3-pip \
|
||||
python3-pygments \
|
||||
python3-toml \
|
||||
python3-typogrify \
|
||||
python3-wheel \
|
||||
redhat-rpm-config \
|
||||
@@ -94,8 +95,6 @@ RUN dnf -y install \
|
||||
weston-libs \
|
||||
which \
|
||||
xorg-x11-server-Xvfb \
|
||||
&& dnf install -y 'dnf-command(builddep)' \
|
||||
&& dnf builddep -y wayland \
|
||||
&& dnf clean all
|
||||
|
||||
# Enable sudo for wheel users
|
||||
|
||||
@@ -8,7 +8,7 @@ builddir=$1
|
||||
backend=$2
|
||||
|
||||
# Ignore memory leaks lower in dependencies
|
||||
export LSAN_OPTIONS=suppressions=$srcdir/lsan.supp:print_suppressions=0
|
||||
export LSAN_OPTIONS=suppressions=$srcdir/lsan.supp:print_suppressions=0:verbosity=1:log_threads=1
|
||||
export G_SLICE=always-malloc
|
||||
|
||||
case "${backend}" in
|
||||
|
||||
@@ -5,7 +5,7 @@ call "C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliar
|
||||
@echo on
|
||||
|
||||
:: FIXME: make warnings fatal
|
||||
pip3 install --upgrade --user meson==0.60.3 || goto :error
|
||||
pip3 install --upgrade --user meson~=0.64 || goto :error
|
||||
meson -Ddebug=false -Dmedia-gstreamer=disabled _build || goto :error
|
||||
ninja -C _build || goto :error
|
||||
|
||||
|
||||
+2
-1
@@ -21,7 +21,7 @@ many things that we value:
|
||||
Please, do not use the issue tracker for support questions. If you have
|
||||
questions on how to use GTK effectively, you can use:
|
||||
|
||||
- the `#gtk` IRC channel on irc.gnome.org
|
||||
- the `gtk` [room on matrix](https://matrix.to/#/#gtk:gnome.org)
|
||||
- the [gtk tag on the GNOME Discourse instance](https://discourse.gnome.org/tag/gtk)
|
||||
|
||||
You can also look at the GTK tag on [Stack
|
||||
@@ -44,6 +44,7 @@ If you're reporting a bug make sure to list:
|
||||
|
||||
0. which version of GTK are you using?
|
||||
0. which operating system are you using?
|
||||
0. what display and graphics driver are you using?
|
||||
0. the necessary steps to reproduce the issue
|
||||
0. the expected outcome
|
||||
0. a description of the behavior; screenshots are also welcome
|
||||
|
||||
@@ -1,6 +1,144 @@
|
||||
Overview of Changes in 4.9.2, xx-xx-xxxx
|
||||
Overview of Changes in 4.9.4, xx-xx-xxxx
|
||||
========================================
|
||||
|
||||
Overview of Changes in 4.9.3, 04-02-2023
|
||||
========================================
|
||||
|
||||
* Add GtkUriLauncher, as replacement for gtk_show_uri
|
||||
|
||||
* Add GdkMonitor::description
|
||||
|
||||
* Fix problems with tooltip sizing
|
||||
|
||||
* Deprecations:
|
||||
- GtkStatusbar
|
||||
- GtkAssistant
|
||||
- GtkLockButton
|
||||
- gtk_gesture_set_sequence_state
|
||||
|
||||
* GtkColumnView:
|
||||
- Only create widgets for visible columns
|
||||
|
||||
* GtkFileDialog:
|
||||
- Drop shortcut folders API
|
||||
|
||||
* GtkCalendar:
|
||||
- Make marked days work again
|
||||
|
||||
* GtkSwitch:
|
||||
- Make state and active independently settable
|
||||
|
||||
* GtkFileChooser:
|
||||
- Fix a crash with DND
|
||||
- Fix excessively wide sidebar
|
||||
- Make context menus work again
|
||||
|
||||
* Accessibility:
|
||||
- Make GtkAccessible public, so it can be implemented outside GTK
|
||||
- Support accessible implementation for editables
|
||||
|
||||
* CSS:
|
||||
- Fix randomly stopping CSS animations
|
||||
|
||||
* GL:
|
||||
- Fix synchronization with GStreamer
|
||||
- Fix problems with 3rd party GL in the same thread
|
||||
|
||||
* Wayland:
|
||||
- Fix startup notification with xdg_activation
|
||||
|
||||
* Broadway:
|
||||
- Implement modal windows
|
||||
|
||||
* macOS:
|
||||
- Make DND work
|
||||
|
||||
* Build:
|
||||
- Require graphene 1.10
|
||||
- Require gobject-introspection 1.72
|
||||
|
||||
* Translation updates
|
||||
Catalan
|
||||
Galician
|
||||
German
|
||||
Hebrew
|
||||
Indonesian
|
||||
Portuguese
|
||||
Russian
|
||||
Spanish
|
||||
Swedish
|
||||
Turkish
|
||||
Ukrainian
|
||||
|
||||
|
||||
Overview of Changes in 4.9.2, 26-12-2022
|
||||
========================================
|
||||
|
||||
* GtkFileChooserWidget:
|
||||
- Add a grid view
|
||||
|
||||
* GtkText, GtkTextView:
|
||||
- Fix activation of the on-screen keyboard
|
||||
- Prevent unexpected text direction changes
|
||||
|
||||
* GtkCenterBox:
|
||||
- Add properties for children
|
||||
|
||||
* GtkTreeExpander:
|
||||
- Add a hide-expander property
|
||||
|
||||
* GtkStringList:
|
||||
- Add a construct-only strings property
|
||||
|
||||
* GtkBuilder:
|
||||
- Support parsing Pango attributes in string form
|
||||
|
||||
* GtkGestureStylus:
|
||||
- Add a stylus-only property
|
||||
|
||||
* GtkFileLauncher:
|
||||
- New async-style api to replace gtk_show_uri
|
||||
|
||||
* GtkColorDialog, GtkFontDialog, GtkFileDialog,
|
||||
GtkAlertDialog:
|
||||
- APIs have seen some tweaks
|
||||
- Prefer portals when available
|
||||
- Fixes for cancellation
|
||||
|
||||
* Add GDK_DEBUG=no-portals
|
||||
|
||||
* Improve file DND with remote files
|
||||
|
||||
* GtkInfoBar has been deprecated
|
||||
|
||||
* gtk_widget_show/hide have been deprecated
|
||||
|
||||
* gtk_show_uri has been deprecated
|
||||
|
||||
* Wayland:
|
||||
- Fix button mask handling
|
||||
- Fix problems with cursor size on hi-dpi screens
|
||||
- Support newer versions of some protocols
|
||||
- Fix handling of surrounding text in input methods
|
||||
|
||||
* X11:
|
||||
- Fix some ordering problems with surface destruction
|
||||
|
||||
* Windows:
|
||||
- Improved system settings integration
|
||||
- Fix window resizing work with native decorations
|
||||
- Include a full hicolor index.theme file as a resource
|
||||
|
||||
* Translation updates
|
||||
Croatian
|
||||
Dutch
|
||||
Hungarian
|
||||
Interlingua
|
||||
Persian
|
||||
Turkish
|
||||
Ukrainian
|
||||
|
||||
|
||||
Overview of Changes in 4.9.1, 31-10-2022
|
||||
========================================
|
||||
|
||||
|
||||
@@ -228,9 +228,9 @@ open_cb (GtkWidget *button,
|
||||
dialog = gtk_file_dialog_new ();
|
||||
gtk_file_dialog_set_title (dialog, "Open file");
|
||||
cwd = g_file_new_for_path (".");
|
||||
gtk_file_dialog_set_current_folder (dialog, cwd);
|
||||
gtk_file_dialog_set_initial_folder (dialog, cwd);
|
||||
g_object_unref (cwd);
|
||||
gtk_file_dialog_open (dialog, GTK_WINDOW (self), NULL, NULL, open_response_cb, self);
|
||||
gtk_file_dialog_open (dialog, GTK_WINDOW (self), NULL, open_response_cb, self);
|
||||
g_object_unref (dialog);
|
||||
}
|
||||
|
||||
@@ -337,11 +337,10 @@ save_cb (GtkWidget *button,
|
||||
dialog = gtk_file_dialog_new ();
|
||||
gtk_file_dialog_set_title (dialog, "Save constraints");
|
||||
cwd = g_file_new_for_path (".");
|
||||
gtk_file_dialog_set_current_folder (dialog, cwd);
|
||||
gtk_file_dialog_set_initial_folder (dialog, cwd);
|
||||
g_object_unref (cwd);
|
||||
gtk_file_dialog_save (dialog,
|
||||
GTK_WINDOW (gtk_widget_get_root (GTK_WIDGET (button))),
|
||||
NULL, NULL,
|
||||
NULL,
|
||||
save_response_cb, self);
|
||||
g_object_unref (dialog);
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
|
||||
typedef GtkApplication DemoApplication;
|
||||
typedef GtkApplicationClass DemoApplicationClass;
|
||||
|
||||
@@ -124,7 +126,7 @@ activate_open (GSimpleAction *action,
|
||||
GtkFileDialog *dialog;
|
||||
|
||||
dialog = gtk_file_dialog_new ();
|
||||
gtk_file_dialog_open (dialog, NULL, NULL, NULL, open_response_cb, g_object_ref (app));
|
||||
gtk_file_dialog_open (dialog, NULL, NULL, open_response_cb, g_object_ref (app));
|
||||
g_object_unref (dialog);
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
|
||||
static GtkWidget *progress_bar = NULL;
|
||||
|
||||
static gboolean
|
||||
|
||||
@@ -37,6 +37,8 @@ remove_timeout (gpointer data)
|
||||
g_source_remove (id);
|
||||
}
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
|
||||
static gboolean
|
||||
pop_status (gpointer data)
|
||||
{
|
||||
@@ -57,6 +59,8 @@ status_message (GtkStatusbar *status,
|
||||
g_object_set_data_full (G_OBJECT (status), "timeout", GUINT_TO_POINTER (id), remove_timeout);
|
||||
}
|
||||
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
|
||||
static void
|
||||
help_activate (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
|
||||
@@ -244,8 +244,9 @@ open_file_cb (GtkWidget *button)
|
||||
gtk_file_dialog_open (dialog,
|
||||
GTK_WINDOW (gtk_widget_get_ancestor (button, GTK_TYPE_WINDOW)),
|
||||
NULL,
|
||||
NULL,
|
||||
file_chooser_response, button);
|
||||
|
||||
g_object_unref (dialog);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -277,9 +278,11 @@ open_folder_cb (GtkWidget *button)
|
||||
gtk_file_dialog_select_folder (dialog,
|
||||
GTK_WINDOW (gtk_widget_get_ancestor (button, GTK_TYPE_WINDOW)),
|
||||
NULL,
|
||||
NULL,
|
||||
folder_chooser_response, button);
|
||||
|
||||
g_object_unref (dialog);
|
||||
}
|
||||
|
||||
static void
|
||||
update_paste_button_sensitivity (GdkClipboard *clipboard,
|
||||
GtkWidget *paste_button)
|
||||
|
||||
@@ -3,7 +3,9 @@
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_PAINTABLE = 1,
|
||||
PROP_TEXTURE = 1,
|
||||
PROP_MIN_FILTER,
|
||||
PROP_MAG_FILTER,
|
||||
PROP_SCALE
|
||||
};
|
||||
|
||||
@@ -11,8 +13,10 @@ struct _Demo3Widget
|
||||
{
|
||||
GtkWidget parent_instance;
|
||||
|
||||
GdkPaintable *paintable;
|
||||
GdkTexture *texture;
|
||||
float scale;
|
||||
GskScalingFilter min_filter;
|
||||
GskScalingFilter mag_filter;
|
||||
|
||||
GtkWidget *menu;
|
||||
};
|
||||
@@ -28,6 +32,8 @@ static void
|
||||
demo3_widget_init (Demo3Widget *self)
|
||||
{
|
||||
self->scale = 1.f;
|
||||
self->min_filter = GSK_SCALING_FILTER_NEAREST;
|
||||
self->mag_filter = GSK_SCALING_FILTER_NEAREST;
|
||||
gtk_widget_init_template (GTK_WIDGET (self));
|
||||
}
|
||||
|
||||
@@ -36,7 +42,7 @@ demo3_widget_dispose (GObject *object)
|
||||
{
|
||||
Demo3Widget *self = DEMO3_WIDGET (object);
|
||||
|
||||
g_clear_object (&self->paintable);
|
||||
g_clear_object (&self->texture);
|
||||
|
||||
gtk_widget_dispose_template (GTK_WIDGET (self), DEMO3_TYPE_WIDGET);
|
||||
|
||||
@@ -50,12 +56,13 @@ demo3_widget_snapshot (GtkWidget *widget,
|
||||
Demo3Widget *self = DEMO3_WIDGET (widget);
|
||||
int x, y, width, height;
|
||||
double w, h;
|
||||
GskRenderNode *node;
|
||||
|
||||
width = gtk_widget_get_width (widget);
|
||||
height = gtk_widget_get_height (widget);
|
||||
|
||||
w = self->scale * gdk_paintable_get_intrinsic_width (self->paintable);
|
||||
h = self->scale * gdk_paintable_get_intrinsic_height (self->paintable);
|
||||
w = self->scale * gdk_texture_get_width (self->texture);
|
||||
h = self->scale * gdk_texture_get_height (self->texture);
|
||||
|
||||
x = MAX (0, (width - ceil (w)) / 2);
|
||||
y = MAX (0, (height - ceil (h)) / 2);
|
||||
@@ -63,7 +70,12 @@ demo3_widget_snapshot (GtkWidget *widget,
|
||||
gtk_snapshot_push_clip (snapshot, &GRAPHENE_RECT_INIT (0, 0, width, height));
|
||||
gtk_snapshot_save (snapshot);
|
||||
gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT (x, y));
|
||||
gdk_paintable_snapshot (self->paintable, snapshot, w, h);
|
||||
node = gsk_texture_node_new_with_filters (self->texture,
|
||||
&GRAPHENE_RECT_INIT (0, 0, w, h),
|
||||
self->min_filter,
|
||||
self->mag_filter);
|
||||
gtk_snapshot_append_node (snapshot, node);
|
||||
gsk_render_node_unref (node);
|
||||
gtk_snapshot_restore (snapshot);
|
||||
gtk_snapshot_pop (snapshot);
|
||||
}
|
||||
@@ -81,9 +93,9 @@ demo3_widget_measure (GtkWidget *widget,
|
||||
int size;
|
||||
|
||||
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
size = gdk_paintable_get_intrinsic_width (self->paintable);
|
||||
size = gdk_texture_get_width (self->texture);
|
||||
else
|
||||
size = gdk_paintable_get_intrinsic_height (self->paintable);
|
||||
size = gdk_texture_get_height (self->texture);
|
||||
|
||||
*minimum = *natural = self->scale * size;
|
||||
}
|
||||
@@ -113,9 +125,9 @@ demo3_widget_set_property (GObject *object,
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_PAINTABLE:
|
||||
g_clear_object (&self->paintable);
|
||||
self->paintable = g_value_dup_object (value);
|
||||
case PROP_TEXTURE:
|
||||
g_clear_object (&self->texture);
|
||||
self->texture = g_value_dup_object (value);
|
||||
gtk_widget_queue_resize (GTK_WIDGET (object));
|
||||
break;
|
||||
|
||||
@@ -124,6 +136,16 @@ demo3_widget_set_property (GObject *object,
|
||||
gtk_widget_queue_resize (GTK_WIDGET (object));
|
||||
break;
|
||||
|
||||
case PROP_MIN_FILTER:
|
||||
self->min_filter = g_value_get_enum (value);
|
||||
gtk_widget_queue_resize (GTK_WIDGET (object));
|
||||
break;
|
||||
|
||||
case PROP_MAG_FILTER:
|
||||
self->mag_filter = g_value_get_enum (value);
|
||||
gtk_widget_queue_resize (GTK_WIDGET (object));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
@@ -140,14 +162,22 @@ demo3_widget_get_property (GObject *object,
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_PAINTABLE:
|
||||
g_value_set_object (value, self->paintable);
|
||||
case PROP_TEXTURE:
|
||||
g_value_set_object (value, self->texture);
|
||||
break;
|
||||
|
||||
case PROP_SCALE:
|
||||
g_value_set_float (value, self->scale);
|
||||
break;
|
||||
|
||||
case PROP_MIN_FILTER:
|
||||
g_value_set_enum (value, self->min_filter);
|
||||
break;
|
||||
|
||||
case PROP_MAG_FILTER:
|
||||
g_value_set_enum (value, self->mag_filter);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
@@ -205,16 +235,26 @@ demo3_widget_class_init (Demo3WidgetClass *class)
|
||||
widget_class->measure = demo3_widget_measure;
|
||||
widget_class->size_allocate = demo3_widget_size_allocate;
|
||||
|
||||
g_object_class_install_property (object_class, PROP_PAINTABLE,
|
||||
g_param_spec_object ("paintable", "Paintable", "Paintable",
|
||||
GDK_TYPE_PAINTABLE,
|
||||
g_object_class_install_property (object_class, PROP_TEXTURE,
|
||||
g_param_spec_object ("texture", NULL, NULL,
|
||||
GDK_TYPE_TEXTURE,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property (object_class, PROP_SCALE,
|
||||
g_param_spec_float ("scale", "Scale", "Scale",
|
||||
g_param_spec_float ("scale", NULL, NULL,
|
||||
0.0, 10.0, 1.0,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property (object_class, PROP_MIN_FILTER,
|
||||
g_param_spec_enum ("min-filter", NULL, NULL,
|
||||
GSK_TYPE_SCALING_FILTER, GSK_SCALING_FILTER_LINEAR,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property (object_class, PROP_MAG_FILTER,
|
||||
g_param_spec_enum ("mag-filter", NULL, NULL,
|
||||
GSK_TYPE_SCALING_FILTER, GSK_SCALING_FILTER_LINEAR,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
/* These are the actions that we are using in the menu */
|
||||
gtk_widget_class_install_action (widget_class, "zoom.in", NULL, zoom_cb);
|
||||
gtk_widget_class_install_action (widget_class, "zoom.out", NULL, zoom_cb);
|
||||
@@ -229,16 +269,13 @@ GtkWidget *
|
||||
demo3_widget_new (const char *resource)
|
||||
{
|
||||
Demo3Widget *self;
|
||||
GdkPixbuf *pixbuf;
|
||||
GdkPaintable *paintable;
|
||||
GdkTexture *texture;
|
||||
|
||||
pixbuf = gdk_pixbuf_new_from_resource (resource, NULL);
|
||||
paintable = GDK_PAINTABLE (gdk_texture_new_for_pixbuf (pixbuf));
|
||||
texture = gdk_texture_new_from_resource (resource);
|
||||
|
||||
self = g_object_new (DEMO3_TYPE_WIDGET, "paintable", paintable, NULL);
|
||||
self = g_object_new (DEMO3_TYPE_WIDGET, "texture", texture, NULL);
|
||||
|
||||
g_object_unref (pixbuf);
|
||||
g_object_unref (paintable);
|
||||
g_object_unref (texture);
|
||||
|
||||
return GTK_WIDGET (self);
|
||||
}
|
||||
|
||||
@@ -362,7 +362,7 @@ do_drawingarea (GtkWidget *do_widget)
|
||||
G_CALLBACK (scribble_resize), NULL);
|
||||
|
||||
drag = gtk_gesture_drag_new ();
|
||||
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (drag), GDK_BUTTON_PRIMARY);
|
||||
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (drag), 0);
|
||||
gtk_widget_add_controller (da, GTK_EVENT_CONTROLLER (drag));
|
||||
|
||||
g_signal_connect (drag, "drag-begin", G_CALLBACK (drag_begin), da);
|
||||
|
||||
@@ -167,7 +167,6 @@ file_open_cb (GtkWidget *button,
|
||||
gtk_file_dialog_open (dialog,
|
||||
GTK_WINDOW (gtk_widget_get_root (button)),
|
||||
NULL,
|
||||
NULL,
|
||||
open_response_cb, stringlist);
|
||||
g_object_unref (dialog);
|
||||
}
|
||||
|
||||
+13
-1
@@ -22,9 +22,11 @@ do_menu (GtkWidget *do_widget)
|
||||
if (!window)
|
||||
{
|
||||
GtkWidget *box;
|
||||
GtkWidget *box2;
|
||||
GtkWidget *sw;
|
||||
GtkWidget *widget;
|
||||
GtkWidget *scale;
|
||||
GtkWidget *dropdown;
|
||||
|
||||
window = gtk_window_new ();
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Menu");
|
||||
@@ -43,10 +45,20 @@ do_menu (GtkWidget *do_widget)
|
||||
widget = demo3_widget_new ("/transparent/portland-rose.jpg");
|
||||
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), widget);
|
||||
|
||||
box2 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
||||
gtk_box_append (GTK_BOX (box), box2);
|
||||
|
||||
scale = gtk_scale_new_with_range (GTK_ORIENTATION_HORIZONTAL, 0.01, 10.0, 0.1);
|
||||
gtk_range_set_value (GTK_RANGE (scale), 1.0);
|
||||
gtk_box_append (GTK_BOX (box), scale);
|
||||
gtk_widget_set_hexpand (scale, TRUE);
|
||||
gtk_box_append (GTK_BOX (box2), scale);
|
||||
|
||||
dropdown = gtk_drop_down_new (G_LIST_MODEL (gtk_string_list_new ((const char *[]){ "Linear", "Nearest", "Trilinear", NULL })), NULL);
|
||||
gtk_box_append (GTK_BOX (box2), dropdown);
|
||||
|
||||
g_object_bind_property (dropdown, "selected", widget, "min-filter", G_BINDING_DEFAULT);
|
||||
g_object_bind_property (dropdown, "selected", widget, "mag-filter", G_BINDING_DEFAULT);
|
||||
|
||||
g_object_bind_property (gtk_range_get_adjustment (GTK_RANGE (scale)), "value",
|
||||
widget, "scale",
|
||||
G_BINDING_BIDIRECTIONAL);
|
||||
|
||||
@@ -156,7 +156,7 @@ demos_h = custom_target('gtk4 demo header',
|
||||
objcopy_supports_add_symbol = false
|
||||
objcopy = find_program('objcopy', required : false)
|
||||
if objcopy.found()
|
||||
objcopy_supports_add_symbol = run_command(objcopy, '--help').stdout().contains('--add-symbol')
|
||||
objcopy_supports_add_symbol = run_command(objcopy, '--help', check: false).stdout().contains('--add-symbol')
|
||||
endif
|
||||
|
||||
ld = find_program('ld', required : false)
|
||||
|
||||
@@ -55,7 +55,6 @@ show_file_open (GtkWidget *button,
|
||||
gtk_file_dialog_open (dialog,
|
||||
GTK_WINDOW (gtk_widget_get_root (button)),
|
||||
NULL,
|
||||
NULL,
|
||||
open_response_cb, picture);
|
||||
}
|
||||
|
||||
|
||||
+84
-18
@@ -1,15 +1,17 @@
|
||||
/* Pickers
|
||||
* #Keywords: GtkColorDialog, GtkFontDialog, GtkFileDialog
|
||||
/* Pickers and Launchers
|
||||
* #Keywords: GtkColorDialog, GtkFontDialog, GtkFileDialog, GtkFileLauncher, GtkUriLauncher
|
||||
*
|
||||
* These widgets 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.
|
||||
*
|
||||
* This demo shows both the default appearance for these dialogs,
|
||||
* as well as some of the customizations that are possible.
|
||||
* The launchers let you open files or URIs in applications that
|
||||
* can handle them.
|
||||
*/
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
static GtkWidget *app_picker;
|
||||
|
||||
static void
|
||||
file_opened (GObject *source,
|
||||
GAsyncResult *result,
|
||||
@@ -25,12 +27,17 @@ file_opened (GObject *source,
|
||||
{
|
||||
g_print ("%s\n", error->message);
|
||||
g_error_free (error);
|
||||
gtk_widget_set_sensitive (app_picker, FALSE);
|
||||
g_object_set_data (G_OBJECT (app_picker), "file", NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
name = g_file_get_basename (file);
|
||||
gtk_label_set_label (GTK_LABEL (data), name);
|
||||
g_free (name);
|
||||
|
||||
gtk_widget_set_sensitive (app_picker, TRUE);
|
||||
g_object_set_data_full (G_OBJECT (app_picker), "file", g_object_ref (file), g_object_unref);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -59,12 +66,70 @@ open_file (GtkButton *picker,
|
||||
20,
|
||||
abort_mission, g_object_ref (cancellable), g_object_unref);
|
||||
|
||||
gtk_file_dialog_open (dialog, parent, NULL, cancellable, file_opened, label);
|
||||
gtk_file_dialog_open (dialog, parent, cancellable, file_opened, label);
|
||||
|
||||
g_object_unref (cancellable);
|
||||
g_object_unref (dialog);
|
||||
}
|
||||
|
||||
static void
|
||||
open_app_done (GObject *source,
|
||||
GAsyncResult *result,
|
||||
gpointer data)
|
||||
{
|
||||
GtkFileLauncher *launcher = GTK_FILE_LAUNCHER (source);
|
||||
GError *error = NULL;
|
||||
|
||||
if (!gtk_file_launcher_launch_finish (launcher, result, &error))
|
||||
{
|
||||
g_print ("%s\n", error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
open_app (GtkButton *picker)
|
||||
{
|
||||
GtkWindow *parent = GTK_WINDOW (gtk_widget_get_root (GTK_WIDGET (picker)));
|
||||
GtkFileLauncher *launcher;
|
||||
GFile *file;
|
||||
|
||||
file = G_FILE (g_object_get_data (G_OBJECT (picker), "file"));
|
||||
launcher = gtk_file_launcher_new (file);
|
||||
|
||||
gtk_file_launcher_launch (launcher, parent, NULL, open_app_done, NULL);
|
||||
|
||||
g_object_unref (launcher);
|
||||
}
|
||||
|
||||
static void
|
||||
open_uri_done (GObject *source,
|
||||
GAsyncResult *result,
|
||||
gpointer data)
|
||||
{
|
||||
GtkUriLauncher *launcher = GTK_URI_LAUNCHER (source);
|
||||
GError *error = NULL;
|
||||
|
||||
if (!gtk_uri_launcher_launch_finish (launcher, result, &error))
|
||||
{
|
||||
g_print ("%s\n", error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
launch_uri (GtkButton *picker)
|
||||
{
|
||||
GtkWindow *parent = GTK_WINDOW (gtk_widget_get_root (GTK_WIDGET (picker)));
|
||||
GtkUriLauncher *launcher;
|
||||
|
||||
launcher = gtk_uri_launcher_new ("http://www.gtk.org");
|
||||
|
||||
gtk_uri_launcher_launch (launcher, parent, NULL, open_uri_done, NULL);
|
||||
|
||||
g_object_unref (launcher);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
do_pickers (GtkWidget *do_widget)
|
||||
{
|
||||
@@ -76,7 +141,7 @@ do_pickers (GtkWidget *do_widget)
|
||||
window = gtk_window_new ();
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Pickers");
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Pickers and Launchers");
|
||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
||||
|
||||
table = gtk_grid_new ();
|
||||
@@ -84,8 +149,8 @@ do_pickers (GtkWidget *do_widget)
|
||||
gtk_widget_set_margin_end (table, 20);
|
||||
gtk_widget_set_margin_top (table, 20);
|
||||
gtk_widget_set_margin_bottom (table, 20);
|
||||
gtk_grid_set_row_spacing (GTK_GRID (table), 3);
|
||||
gtk_grid_set_column_spacing (GTK_GRID (table), 10);
|
||||
gtk_grid_set_row_spacing (GTK_GRID (table), 6);
|
||||
gtk_grid_set_column_spacing (GTK_GRID (table), 6);
|
||||
gtk_window_set_child (GTK_WINDOW (window), table);
|
||||
|
||||
label = gtk_label_new ("Color:");
|
||||
@@ -112,7 +177,7 @@ do_pickers (GtkWidget *do_widget)
|
||||
gtk_widget_set_hexpand (label, TRUE);
|
||||
gtk_grid_attach (GTK_GRID (table), label, 0, 2, 1, 1);
|
||||
|
||||
picker = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 10);
|
||||
picker = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
|
||||
button = gtk_button_new_from_icon_name ("document-open-symbolic");
|
||||
label = gtk_label_new ("None");
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0.);
|
||||
@@ -121,21 +186,22 @@ do_pickers (GtkWidget *do_widget)
|
||||
g_signal_connect (button, "clicked", G_CALLBACK (open_file), label);
|
||||
gtk_box_append (GTK_BOX (picker), label);
|
||||
gtk_box_append (GTK_BOX (picker), button);
|
||||
app_picker = gtk_button_new_from_icon_name ("emblem-system-symbolic");
|
||||
gtk_widget_set_halign (app_picker, GTK_ALIGN_END);
|
||||
gtk_widget_set_sensitive (app_picker, FALSE);
|
||||
g_signal_connect (app_picker, "clicked", G_CALLBACK (open_app), NULL);
|
||||
gtk_box_append (GTK_BOX (picker), app_picker);
|
||||
gtk_grid_attach (GTK_GRID (table), picker, 1, 2, 1, 1);
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
|
||||
label = gtk_label_new ("Mail:");
|
||||
label = gtk_label_new ("URI:");
|
||||
gtk_widget_set_halign (label, GTK_ALIGN_START);
|
||||
gtk_widget_set_valign (label, GTK_ALIGN_CENTER);
|
||||
gtk_widget_set_hexpand (label, TRUE);
|
||||
|
||||
picker = gtk_app_chooser_button_new ("x-scheme-handler/mailto");
|
||||
gtk_app_chooser_button_set_show_dialog_item (GTK_APP_CHOOSER_BUTTON (picker), TRUE);
|
||||
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
|
||||
gtk_grid_attach (GTK_GRID (table), label, 0, 3, 1, 1);
|
||||
|
||||
picker = gtk_button_new_with_label ("www.gtk.org");
|
||||
g_signal_connect (picker, "clicked", G_CALLBACK (launch_uri), NULL);
|
||||
gtk_grid_attach (GTK_GRID (table), picker, 1, 3, 1, 1);
|
||||
}
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ open_clicked_cb (GtkWidget *button,
|
||||
gtk_file_filter_set_name (filter, "Video");
|
||||
g_list_store_append (filters, filter);
|
||||
|
||||
gtk_file_dialog_set_current_filter (dialog, filter);
|
||||
gtk_file_dialog_set_default_filter (dialog, filter);
|
||||
g_object_unref (filter);
|
||||
|
||||
gtk_file_dialog_set_filters (dialog, G_LIST_MODEL (filters));
|
||||
@@ -65,7 +65,6 @@ open_clicked_cb (GtkWidget *button,
|
||||
gtk_file_dialog_open (dialog,
|
||||
GTK_WINDOW (gtk_widget_get_root (button)),
|
||||
NULL,
|
||||
NULL,
|
||||
open_dialog_response_cb, video);
|
||||
}
|
||||
|
||||
|
||||
@@ -14,9 +14,7 @@ executable('gtk4-node-editor',
|
||||
sources: [node_editor_sources, node_editor_resources],
|
||||
dependencies: [ libgtk_dep, demo_conf_h ],
|
||||
include_directories: confinc,
|
||||
c_args: [
|
||||
'-DNODE_EDITOR_SOURCE_DIR="@0@/../../testsuite/gsk/compare/"'.format(meson.current_source_dir())
|
||||
] + common_cflags,
|
||||
c_args: common_cflags,
|
||||
win_subsystem: 'windows',
|
||||
link_args: extra_demo_ldflags,
|
||||
install: true,
|
||||
|
||||
@@ -32,10 +32,6 @@
|
||||
#include "gsk/vulkan/gskvulkanrenderer.h"
|
||||
#endif
|
||||
|
||||
#ifndef NODE_EDITOR_SOURCE_DIR
|
||||
#define NODE_EDITOR_SOURCE_DIR "." /* Fallback */
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
gsize start_chars;
|
||||
@@ -573,10 +569,10 @@ show_open_filechooser (NodeEditorWindow *self)
|
||||
dialog = gtk_file_dialog_new ();
|
||||
gtk_file_dialog_set_title (dialog, "Open node file");
|
||||
cwd = g_file_new_for_path (".");
|
||||
gtk_file_dialog_set_current_folder (dialog, cwd);
|
||||
gtk_file_dialog_set_initial_folder (dialog, cwd);
|
||||
g_object_unref (cwd);
|
||||
gtk_file_dialog_open (dialog, GTK_WINDOW (self),
|
||||
NULL, NULL, open_response_cb, self);
|
||||
NULL, open_response_cb, self);
|
||||
g_object_unref (dialog);
|
||||
}
|
||||
|
||||
@@ -637,13 +633,12 @@ save_cb (GtkWidget *button,
|
||||
dialog = gtk_file_dialog_new ();
|
||||
gtk_file_dialog_set_title (dialog, "Save node");
|
||||
cwd = g_file_new_for_path (".");
|
||||
gtk_file_dialog_set_current_folder (dialog, cwd);
|
||||
gtk_file_dialog_set_initial_folder (dialog, cwd);
|
||||
gtk_file_dialog_set_initial_name (dialog, "demo.node");
|
||||
g_object_unref (cwd);
|
||||
gtk_file_dialog_save (dialog,
|
||||
GTK_WINDOW (gtk_widget_get_root (GTK_WIDGET (button))),
|
||||
NULL,
|
||||
"demo.node",
|
||||
NULL,
|
||||
save_response_cb, self);
|
||||
g_object_unref (dialog);
|
||||
}
|
||||
@@ -746,11 +741,10 @@ export_image_cb (GtkWidget *button,
|
||||
|
||||
dialog = gtk_file_dialog_new ();
|
||||
gtk_file_dialog_set_title (dialog, "");
|
||||
gtk_file_dialog_set_initial_name (dialog, "example.png");
|
||||
gtk_file_dialog_save (dialog,
|
||||
GTK_WINDOW (gtk_widget_get_root (GTK_WIDGET (button))),
|
||||
NULL,
|
||||
"example.png",
|
||||
NULL,
|
||||
export_image_response_cb, texture);
|
||||
g_object_unref (dialog);
|
||||
}
|
||||
@@ -788,12 +782,52 @@ testcase_name_entry_changed_cb (GtkWidget *button,
|
||||
gtk_widget_set_sensitive (self->testcase_save_button, FALSE);
|
||||
}
|
||||
|
||||
/* Returns the location where gsk test cases are stored in
|
||||
* the GTK testsuite, if we can determine it.
|
||||
*
|
||||
* When running node editor outside of a GTK build, you can
|
||||
* set GTK_SOURCE_DIR to point it at the checkout.
|
||||
*/
|
||||
static char *
|
||||
get_source_dir (void)
|
||||
{
|
||||
const char *subdir = "testsuite/gsk/compare";
|
||||
const char *source_dir;
|
||||
char *current_dir;
|
||||
char *dir;
|
||||
|
||||
source_dir = g_getenv ("GTK_SOURCE_DIR");
|
||||
current_dir = g_get_current_dir ();
|
||||
|
||||
if (source_dir)
|
||||
{
|
||||
char *abs_source_dir = g_canonicalize_filename (source_dir, NULL);
|
||||
dir = g_canonicalize_filename (subdir, abs_source_dir);
|
||||
g_free (abs_source_dir);
|
||||
}
|
||||
else
|
||||
{
|
||||
dir = g_canonicalize_filename (subdir, current_dir);
|
||||
}
|
||||
|
||||
if (g_file_test (dir, G_FILE_TEST_EXISTS))
|
||||
{
|
||||
g_free (current_dir);
|
||||
|
||||
return dir;
|
||||
}
|
||||
|
||||
g_free (dir);
|
||||
|
||||
return current_dir;
|
||||
}
|
||||
|
||||
static void
|
||||
testcase_save_clicked_cb (GtkWidget *button,
|
||||
NodeEditorWindow *self)
|
||||
{
|
||||
const char *testcase_name = gtk_editable_get_text (GTK_EDITABLE (self->testcase_name_entry));
|
||||
char *source_dir = g_canonicalize_filename (NODE_EDITOR_SOURCE_DIR, NULL);
|
||||
char *source_dir = get_source_dir ();
|
||||
char *node_file_name;
|
||||
char *node_file;
|
||||
char *png_file_name;
|
||||
@@ -806,6 +840,8 @@ testcase_save_clicked_cb (GtkWidget *button,
|
||||
node_file = g_build_filename (source_dir, node_file_name, NULL);
|
||||
g_free (node_file_name);
|
||||
|
||||
g_debug ("Saving testcase in %s", node_file);
|
||||
|
||||
png_file_name = g_strconcat (testcase_name, ".png", NULL);
|
||||
png_file = g_build_filename (source_dir, png_file_name, NULL);
|
||||
g_free (png_file_name);
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
|
||||
#include "demo_conf.h"
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
|
||||
static GtkWidget *main_window;
|
||||
static GFile *filename = NULL;
|
||||
static GtkPageSetup *page_setup = NULL;
|
||||
@@ -508,8 +510,6 @@ activate_save_as (GSimpleAction *action,
|
||||
gtk_file_dialog_save (dialog,
|
||||
GTK_WINDOW (main_window),
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
on_save_response, NULL);
|
||||
g_object_unref (dialog);
|
||||
}
|
||||
@@ -553,7 +553,6 @@ activate_open (GSimpleAction *action,
|
||||
gtk_file_dialog_open (dialog,
|
||||
GTK_WINDOW (main_window),
|
||||
NULL,
|
||||
NULL,
|
||||
on_open_response, NULL);
|
||||
g_object_unref (dialog);
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
objcopy_supports_add_symbol = false
|
||||
objcopy = find_program('objcopy', required : false)
|
||||
if objcopy.found()
|
||||
objcopy_supports_add_symbol = run_command(objcopy, '--help').stdout().contains('--add-symbol')
|
||||
objcopy_supports_add_symbol = run_command(objcopy, '--help', check: false).stdout().contains('--add-symbol')
|
||||
endif
|
||||
|
||||
ld = find_program('ld', required : false)
|
||||
|
||||
@@ -237,7 +237,7 @@ activate_open_file (GSimpleAction *action,
|
||||
GtkFileDialog *dialog;
|
||||
|
||||
dialog = gtk_file_dialog_new ();
|
||||
gtk_file_dialog_open (dialog, NULL, NULL, NULL, file_chooser_response, NULL);
|
||||
gtk_file_dialog_open (dialog, NULL, NULL, file_chooser_response, NULL);
|
||||
g_object_unref (dialog);
|
||||
}
|
||||
|
||||
@@ -2056,6 +2056,67 @@ hide_widget (GtkWidget *widget)
|
||||
gtk_widget_set_visible (widget, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
load_texture_thread (GTask *task,
|
||||
gpointer source_object,
|
||||
gpointer task_data,
|
||||
GCancellable *cancellable)
|
||||
{
|
||||
const char *resource_path = (const char *) task_data;
|
||||
GBytes *bytes;
|
||||
GdkTexture *texture;
|
||||
GError *error = NULL;
|
||||
|
||||
bytes = g_resources_lookup_data (resource_path, 0, &error);
|
||||
if (!bytes)
|
||||
{
|
||||
g_task_return_error (task, error);
|
||||
return;
|
||||
}
|
||||
|
||||
texture = gdk_texture_new_from_bytes (bytes, &error);
|
||||
g_bytes_unref (bytes);
|
||||
|
||||
if (!texture)
|
||||
{
|
||||
g_task_return_error (task, error);
|
||||
return;
|
||||
}
|
||||
|
||||
g_task_return_pointer (task, texture, g_object_unref);
|
||||
}
|
||||
|
||||
static void
|
||||
load_texture_done (GObject *source,
|
||||
GAsyncResult *result,
|
||||
gpointer data)
|
||||
{
|
||||
GtkWidget *picture = GTK_WIDGET (source);
|
||||
GdkTexture *texture;
|
||||
GError *error = NULL;
|
||||
|
||||
texture = g_task_propagate_pointer (G_TASK (result), &error);
|
||||
if (!texture)
|
||||
{
|
||||
g_warning ("%s", error->message);
|
||||
g_error_free (error);
|
||||
return;
|
||||
}
|
||||
|
||||
gtk_picture_set_paintable (GTK_PICTURE (picture), GDK_PAINTABLE (texture));
|
||||
g_object_unref (texture);
|
||||
}
|
||||
|
||||
static void
|
||||
load_texture_in_thread (GtkWidget *picture,
|
||||
const char *resource_path)
|
||||
{
|
||||
GTask *task = g_task_new (picture, NULL, load_texture_done, NULL);
|
||||
g_task_set_task_data (task, (gpointer)resource_path, NULL);
|
||||
g_task_run_in_thread (task, load_texture_thread);
|
||||
g_object_unref (task);
|
||||
}
|
||||
|
||||
static void
|
||||
activate (GApplication *app)
|
||||
{
|
||||
@@ -2155,6 +2216,13 @@ activate (GApplication *app)
|
||||
|
||||
window = (GtkWindow *)gtk_builder_get_object (builder, "window");
|
||||
|
||||
load_texture_in_thread ((GtkWidget *)gtk_builder_get_object (builder, "notebook_sunset"),
|
||||
"/org/gtk/WidgetFactory4/sunset.jpg");
|
||||
load_texture_in_thread ((GtkWidget *)gtk_builder_get_object (builder, "notebook_nyc"),
|
||||
"/org/gtk/WidgetFactory4/nyc.jpg");
|
||||
load_texture_in_thread ((GtkWidget *)gtk_builder_get_object (builder, "notebook_beach"),
|
||||
"/org/gtk/WidgetFactory4/beach.jpg");
|
||||
|
||||
if (g_strcmp0 (PROFILE, "devel") == 0)
|
||||
gtk_widget_add_css_class (GTK_WIDGET (window), "devel");
|
||||
|
||||
@@ -2184,11 +2252,13 @@ activate (GApplication *app)
|
||||
for (i = 0; i < G_N_ELEMENTS (accels); i++)
|
||||
gtk_application_set_accels_for_action (GTK_APPLICATION (app), accels[i].action_and_target, accels[i].accelerators);
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
widget = (GtkWidget *)gtk_builder_get_object (builder, "statusbar");
|
||||
gtk_statusbar_push (GTK_STATUSBAR (widget), 0, "All systems are operating normally.");
|
||||
action = G_ACTION (g_property_action_new ("statusbar", widget, "visible"));
|
||||
g_action_map_add_action (G_ACTION_MAP (window), action);
|
||||
g_object_unref (G_OBJECT (action));
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
|
||||
widget = (GtkWidget *)gtk_builder_get_object (builder, "toolbar");
|
||||
action = G_ACTION (g_property_action_new ("toolbar", widget, "visible"));
|
||||
@@ -2362,6 +2432,7 @@ G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
widget = (GtkWidget *)gtk_builder_get_object (builder, "record_button");
|
||||
g_object_set_data (G_OBJECT (window), "record_button", widget);
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
widget = (GtkWidget *)gtk_builder_get_object (builder, "lockbox");
|
||||
widget2 = (GtkWidget *)gtk_builder_get_object (builder, "lockbutton");
|
||||
g_object_set_data (G_OBJECT (window), "lockbutton", widget2);
|
||||
@@ -2379,6 +2450,7 @@ G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
G_BINDING_SYNC_CREATE);
|
||||
gtk_lock_button_set_permission (GTK_LOCK_BUTTON (widget2), permission);
|
||||
g_object_unref (permission);
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
|
||||
widget = (GtkWidget *)gtk_builder_get_object (builder, "iconview1");
|
||||
widget2 = (GtkWidget *)gtk_builder_get_object (builder, "increase_button");
|
||||
|
||||
@@ -1263,8 +1263,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
<child>
|
||||
<object class="GtkNotebookPage">
|
||||
<property name="child">
|
||||
<object class="GtkPicture">
|
||||
<property name="file">resource:///org/gtk/WidgetFactory4/sunset.jpg</property>
|
||||
<object class="GtkPicture" id="notebook_sunset">
|
||||
<property name="content-fit">cover</property>
|
||||
<child>
|
||||
<object class="GtkDragSource">
|
||||
@@ -1290,8 +1289,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
<child>
|
||||
<object class="GtkNotebookPage">
|
||||
<property name="child">
|
||||
<object class="GtkPicture">
|
||||
<property name="file">resource:///org/gtk/WidgetFactory4/nyc.jpg</property>
|
||||
<object class="GtkPicture" id="notebook_nyc">
|
||||
<child>
|
||||
<object class="GtkDragSource">
|
||||
<signal name="prepare" handler="on_picture_drag_prepare" swapped="no"/>
|
||||
@@ -1316,8 +1314,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
<child>
|
||||
<object class="GtkNotebookPage">
|
||||
<property name="child">
|
||||
<object class="GtkPicture">
|
||||
<property name="file">resource:///org/gtk/WidgetFactory4/beach.jpg</property>
|
||||
<object class="GtkPicture" id="notebook_beach">
|
||||
<child>
|
||||
<object class="GtkDragSource">
|
||||
<signal name="prepare" handler="on_picture_drag_prepare" swapped="no"/>
|
||||
|
||||
@@ -18,12 +18,12 @@ search_index = true
|
||||
docs_url = "https://docs.gtk.org/gobject/"
|
||||
|
||||
[dependencies."Gio-2.0"]
|
||||
name = "GIO"
|
||||
name = "Gio"
|
||||
description = "GObject Interfaces and Objects, Networking, IPC, and I/O"
|
||||
docs_url = "https://docs.gtk.org/gio/"
|
||||
|
||||
[dependencies."cairo-1.0"]
|
||||
name = "Cairo"
|
||||
name = "cairo"
|
||||
description = "A 2D graphics library with support for multiple output devices"
|
||||
docs_url = "https://www.cairographics.org/manual/"
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ dependencies = ["Graphene-1.0", "Gdk-4.0"]
|
||||
docs_url = "https://ebassi.github.io/graphene/docs/"
|
||||
|
||||
[dependencies."Gdk-4.0"]
|
||||
name = "GDK"
|
||||
name = "Gdk"
|
||||
description = "The GTK windowing system abstraction"
|
||||
docs_url = "https://docs.gtk.org/gdk4/"
|
||||
|
||||
|
||||
@@ -236,23 +236,17 @@ By default, GTK will try to build with support for the Vulkan graphics
|
||||
API in addition to cairo and OpenGL. This option can be used to explicitly
|
||||
control whether Vulkan should be used.
|
||||
|
||||
### `xinerama`
|
||||
|
||||
By default, GTK will try to link against the Xinerama libraries
|
||||
if they are found. This option can be used to explicitly control
|
||||
whether Xinerama should be used.
|
||||
|
||||
### `media`
|
||||
### `media-gstreamer` and `media-ffmpeg`
|
||||
|
||||
By default, GTK will try to build the gstreamer backend for
|
||||
media playback support. This option can be used to explicitly
|
||||
media playback support. These option can be used to explicitly
|
||||
control which media backends should be built.
|
||||
|
||||
### `print`
|
||||
### `print-cups`
|
||||
|
||||
By default, GTK will try to build various print backends
|
||||
if their dependencies are found. This option can be used
|
||||
to explicitly control which print backends should be built.
|
||||
to explicitly control whether the cups print backend should be built.
|
||||
|
||||
### `cloudproviders`
|
||||
|
||||
@@ -274,18 +268,13 @@ support in the file chooser.
|
||||
This option controls whether GTK should use colord for color
|
||||
calibration support in the cups print backend.
|
||||
|
||||
### `gtk_doc` and `man-pages`
|
||||
### `gtk_doc`, `man-pages` and `update_screenshots`
|
||||
|
||||
The *gtk-doc* package is used to generate the reference documentation
|
||||
included with GTK. By default support for *gtk-doc* is disabled
|
||||
The *gi-docgen* package is used to generate the reference documentation
|
||||
included with GTK. By default support for *gi-docgen* is disabled
|
||||
because it requires various extra dependencies to be installed.
|
||||
If you have *gtk-doc* and *pandoc* installed and are modifying GTK,
|
||||
you may want to enable *gtk-doc* support by passing in `-Dgtk_doc=true`.
|
||||
|
||||
Additionally, some tools provided by GTK have their own
|
||||
manual pages generated using a similar set of dependencies;
|
||||
if you have *xsltproc* then you can generate manual pages by
|
||||
passing `-Dman-pages=true` when configuring the build.
|
||||
Introspection needs to be enabled, since the documentation is generated
|
||||
from introspection data.
|
||||
|
||||
### `introspection`
|
||||
|
||||
@@ -294,9 +283,14 @@ is mainly useful for shortening turnaround times on developer
|
||||
systems. Installed builds of GTK should always have introspection
|
||||
support.
|
||||
|
||||
### `build-tests`, `install-tests`, `demos`
|
||||
### `build-testsuite`
|
||||
|
||||
By default, GTK will build quite a few tests and demos.
|
||||
If you want to run the testsuite to ensure that your GTK build
|
||||
works, you should enable it with this option.
|
||||
|
||||
### `build-tests`, `build-examples`, `demos`
|
||||
|
||||
By default, GTK will build quite a few tests, examples and demos.
|
||||
While these are useful on a developer system, they are not
|
||||
needed when GTK is built e.g. for a flatpak runtime. These
|
||||
options allow to disable building tests and demos.
|
||||
|
||||
@@ -51,7 +51,7 @@ main (int argc,
|
||||
GtkApplication *app;
|
||||
int status;
|
||||
|
||||
app = gtk_application_new ("org.gtk.example", G_APPLICATION_FLAGS_NONE);
|
||||
app = gtk_application_new ("org.gtk.example", G_APPLICATION_DEFAULT_FLAGS);
|
||||
g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
|
||||
status = g_application_run (G_APPLICATION (app), argc, argv);
|
||||
g_object_unref (app);
|
||||
@@ -189,7 +189,7 @@ main (int argc,
|
||||
GtkApplication *app;
|
||||
int status;
|
||||
|
||||
app = gtk_application_new ("org.gtk.example", G_APPLICATION_FLAGS_NONE);
|
||||
app = gtk_application_new ("org.gtk.example", G_APPLICATION_DEFAULT_FLAGS);
|
||||
g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
|
||||
status = g_application_run (G_APPLICATION (app), argc, argv);
|
||||
g_object_unref (app);
|
||||
@@ -338,7 +338,7 @@ main (int argc,
|
||||
GtkApplication *app;
|
||||
int status;
|
||||
|
||||
app = gtk_application_new ("org.gtk.example", G_APPLICATION_FLAGS_NONE);
|
||||
app = gtk_application_new ("org.gtk.example", G_APPLICATION_DEFAULT_FLAGS);
|
||||
g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
|
||||
status = g_application_run (G_APPLICATION (app), argc, argv);
|
||||
g_object_unref (app);
|
||||
@@ -377,7 +377,7 @@ demonstrates input event handling with event controllers.
|
||||
|
||||
### Drawing in response to input
|
||||
|
||||
Create a new file with the following content named `example-4.c`.
|
||||
Create a new file with the following content named `example-3.c`.
|
||||
|
||||
```c
|
||||
#include <gtk/gtk.h>
|
||||
@@ -560,7 +560,7 @@ main (int argc,
|
||||
GtkApplication *app;
|
||||
int status;
|
||||
|
||||
app = gtk_application_new ("org.gtk.example", G_APPLICATION_FLAGS_NONE);
|
||||
app = gtk_application_new ("org.gtk.example", G_APPLICATION_DEFAULT_FLAGS);
|
||||
g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
|
||||
status = g_application_run (G_APPLICATION (app), argc, argv);
|
||||
g_object_unref (app);
|
||||
@@ -572,7 +572,7 @@ main (int argc,
|
||||
You can compile the program above with GCC using:
|
||||
|
||||
```
|
||||
gcc $( pkg-config --cflags gtk4 ) -o example-4 example-4.c $( pkg-config --libs gtk4 )
|
||||
gcc $( pkg-config --cflags gtk4 ) -o example-3 example-3.c $( pkg-config --libs gtk4 )
|
||||
```
|
||||
|
||||
## Building user interfaces
|
||||
@@ -587,7 +587,7 @@ XML format that can be parsed by the [class@Gtk.Builder] class.
|
||||
|
||||
### Packing buttons with GtkBuilder
|
||||
|
||||
Create a new file with the following content named `example-3.c`.
|
||||
Create a new file with the following content named `example-4.c`.
|
||||
|
||||
```c
|
||||
#include <gtk/gtk.h>
|
||||
@@ -641,7 +641,7 @@ main (int argc,
|
||||
g_chdir (GTK_SRCDIR);
|
||||
#endif
|
||||
|
||||
GtkApplication *app = gtk_application_new ("org.gtk.example", G_APPLICATION_FLAGS_NONE);
|
||||
GtkApplication *app = gtk_application_new ("org.gtk.example", G_APPLICATION_DEFAULT_FLAGS);
|
||||
g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
|
||||
|
||||
int status = g_application_run (G_APPLICATION (app), argc, argv);
|
||||
@@ -697,7 +697,7 @@ Create a new file with the following content named `builder.ui`.
|
||||
You can compile the program above with GCC using:
|
||||
|
||||
```
|
||||
gcc $( pkg-config --cflags gtk4 ) -o example-3 example-3.c $( pkg-config --libs gtk4 )
|
||||
gcc $( pkg-config --cflags gtk4 ) -o example-4 example-4.c $( pkg-config --libs gtk4 )
|
||||
```
|
||||
|
||||
Note that `GtkBuilder` can also be used to construct objects that are
|
||||
@@ -1018,6 +1018,10 @@ Our application now looks like this:
|
||||
In this step, we make our application show the content of all the files
|
||||
that it is given on the commandline.
|
||||
|
||||
**Note: Providing filenames (e.g. `./exampleapp examplewin.c examplewin.h`) at
|
||||
the command line is a requirement for example apps 3-9 to display as shown in
|
||||
the screenshots below.**
|
||||
|
||||
To this end, we add a member to the struct of our application window subclass
|
||||
and keep a reference to the `GtkStack` there. The first member of the struct
|
||||
should be the parent type from which the class is derived. Here,
|
||||
|
||||
@@ -14,12 +14,12 @@ search_index = true
|
||||
dependencies = ["Gdk-4.0", "Gsk-4.0"]
|
||||
|
||||
[dependencies."Gdk-4.0"]
|
||||
name = "GDK"
|
||||
name = "Gdk"
|
||||
description = "The GTK windowing system abstraction"
|
||||
docs_url = "https://docs.gtk.org/gdk4/"
|
||||
|
||||
[dependencies."Gsk-4.0"]
|
||||
name = "GSK"
|
||||
name = "Gsk"
|
||||
description = "The GTK rendering abstraction"
|
||||
docs_url = "https://docs.gtk.org/gsk4/"
|
||||
|
||||
|
||||
@@ -105,3 +105,17 @@ retire it. If you need such a widget, it is relatively trivial to create one
|
||||
using a [class@Gtk.Revealer] with labels and buttons.
|
||||
|
||||
Other libraries, such as libadwaita, may provide replacements as well.
|
||||
|
||||
## gtk_show_uri is being replaced
|
||||
|
||||
Instead of gtk_show_uri(), you should use GtkUriLauncher or GtkFileLauncher.
|
||||
|
||||
## GtkStatusbar is going away
|
||||
|
||||
This is an oldfashioned widget that does not do all that much anymore, since
|
||||
it no longer has a resize handle for the window.
|
||||
|
||||
## GtkLockButton is going away
|
||||
|
||||
This is an very specialized widget that should better live with the application
|
||||
where it is used.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
toml_conf = configuration_data()
|
||||
toml_conf.set('version', meson.project_version())
|
||||
|
||||
gidocgen = find_program('gi-docgen', required: get_option('gtk_doc'))
|
||||
gidocgen = find_program('gi-docgen', required: get_option('gtk_doc'), native: true)
|
||||
|
||||
gidocgen_common_args = [
|
||||
'--quiet',
|
||||
|
||||
@@ -106,7 +106,7 @@ activate (GApplication *app,
|
||||
gtk_widget_set_halign (GTK_WIDGET (button), GTK_ALIGN_CENTER);
|
||||
gtk_widget_set_valign (GTK_WIDGET (button), GTK_ALIGN_START);
|
||||
gtk_window_set_child (GTK_WINDOW (window), button);
|
||||
gtk_widget_show (win);
|
||||
gtk_window_present (GTK_WINDOW (win));
|
||||
|
||||
g_object_unref (button_menu);
|
||||
g_object_unref (doc_actions);
|
||||
|
||||
@@ -292,7 +292,7 @@ new_window (GApplication *app,
|
||||
G_CALLBACK (text_buffer_changed_cb), window);
|
||||
text_buffer_changed_cb (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)), window);
|
||||
|
||||
gtk_widget_show (GTK_WIDGET (window));
|
||||
gtk_window_present (GTK_WINDOW (window));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -465,7 +465,7 @@ edit_accels (GSimpleAction *action,
|
||||
|
||||
gtk_drop_down_set_selected (GTK_DROP_DOWN (combo), 0);
|
||||
|
||||
gtk_widget_show (dialog);
|
||||
gtk_window_present (GTK_WINDOW (dialog));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
||||
+1
-1
@@ -37,7 +37,7 @@ activate (GtkApplication *app,
|
||||
button = gtk_builder_get_object (builder, "quit");
|
||||
g_signal_connect_swapped (button, "clicked", G_CALLBACK (quit_cb), window);
|
||||
|
||||
gtk_widget_show (GTK_WIDGET (window));
|
||||
gtk_window_present (GTK_WINDOW (window));
|
||||
g_object_unref (builder);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -164,7 +164,7 @@ activate (GtkApplication *app,
|
||||
|
||||
g_signal_connect (press, "pressed", G_CALLBACK (pressed), drawing_area);
|
||||
|
||||
gtk_widget_show (window);
|
||||
gtk_window_present (GTK_WINDOW (window));
|
||||
}
|
||||
|
||||
int
|
||||
|
||||
@@ -49,7 +49,7 @@ activate (GtkApplication *app,
|
||||
*/
|
||||
gtk_grid_attach (GTK_GRID (grid), button, 0, 1, 2, 1);
|
||||
|
||||
gtk_widget_show (window);
|
||||
gtk_window_present (GTK_WINDOW (window));
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ activate (GtkApplication *app,
|
||||
|
||||
gtk_window_set_child (GTK_WINDOW (window), button);
|
||||
|
||||
gtk_widget_show (window);
|
||||
gtk_window_present (GTK_WINDOW (window));
|
||||
}
|
||||
|
||||
int
|
||||
@@ -37,7 +37,7 @@ main (int argc,
|
||||
GtkApplication *app;
|
||||
int status;
|
||||
|
||||
app = gtk_application_new ("org.gtk.example", G_APPLICATION_FLAGS_NONE);
|
||||
app = gtk_application_new ("org.gtk.example", G_APPLICATION_DEFAULT_FLAGS);
|
||||
g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
|
||||
status = g_application_run (G_APPLICATION (app), argc, argv);
|
||||
g_object_unref (app);
|
||||
|
||||
+1
-1
@@ -112,7 +112,7 @@ new_window (GApplication *app,
|
||||
}
|
||||
}
|
||||
|
||||
gtk_widget_show (GTK_WIDGET (window));
|
||||
gtk_window_present (GTK_WINDOW (window));
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
static void
|
||||
activate_cb (GtkApplication *app,
|
||||
gpointer user_data)
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkWidget *window;
|
||||
GtkWidget *search_bar;
|
||||
@@ -11,12 +11,11 @@ activate_cb (GtkApplication *app,
|
||||
GtkWidget *menu_button;
|
||||
|
||||
window = gtk_application_window_new (app);
|
||||
gtk_widget_show (window);
|
||||
gtk_window_present (GTK_WINDOW (window));
|
||||
|
||||
search_bar = gtk_search_bar_new ();
|
||||
gtk_widget_set_valign (search_bar, GTK_ALIGN_START);
|
||||
gtk_window_set_child (GTK_WINDOW (window), search_bar);
|
||||
gtk_widget_show (search_bar);
|
||||
|
||||
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
|
||||
gtk_search_bar_set_child (GTK_SEARCH_BAR (search_bar), box);
|
||||
|
||||
+1
-1
@@ -43,7 +43,7 @@ new_window (GApplication *app,
|
||||
}
|
||||
}
|
||||
|
||||
gtk_widget_show (GTK_WIDGET (window));
|
||||
gtk_window_present (GTK_WINDOW (window));
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -9,7 +9,7 @@ activate (GtkApplication* app,
|
||||
window = gtk_application_window_new (app);
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Window");
|
||||
gtk_window_set_default_size (GTK_WINDOW (window), 200, 200);
|
||||
gtk_widget_show (window);
|
||||
gtk_window_present (GTK_WINDOW (window));
|
||||
}
|
||||
|
||||
int
|
||||
|
||||
@@ -213,6 +213,7 @@ typedef enum {
|
||||
BROADWAY_REQUEST_RELEASE_TEXTURE,
|
||||
BROADWAY_REQUEST_SET_NODES,
|
||||
BROADWAY_REQUEST_ROUNDTRIP,
|
||||
BROADWAY_REQUEST_SET_MODAL_HINT,
|
||||
} BroadwayRequestType;
|
||||
|
||||
typedef struct {
|
||||
@@ -293,6 +294,12 @@ typedef struct {
|
||||
guint32 show_keyboard;
|
||||
} BroadwayRequestSetShowKeyboard;
|
||||
|
||||
typedef struct {
|
||||
BroadwayRequestBase base;
|
||||
guint32 id;
|
||||
gboolean modal_hint;
|
||||
} BroadwayRequestSetModalHint;
|
||||
|
||||
typedef union {
|
||||
BroadwayRequestBase base;
|
||||
BroadwayRequestNewSurface new_surface;
|
||||
@@ -312,6 +319,7 @@ typedef union {
|
||||
BroadwayRequestUploadTexture upload_texture;
|
||||
BroadwayRequestReleaseTexture release_texture;
|
||||
BroadwayRequestSetNodes set_nodes;
|
||||
BroadwayRequestSetModalHint set_modal_hint;
|
||||
} BroadwayRequest;
|
||||
|
||||
typedef enum {
|
||||
|
||||
@@ -124,6 +124,7 @@ struct BroadwaySurface {
|
||||
gboolean visible;
|
||||
gint32 transient_for;
|
||||
guint32 texture;
|
||||
gboolean modal_hint;
|
||||
BroadwayNode *nodes;
|
||||
GHashTable *node_lookup;
|
||||
};
|
||||
@@ -421,6 +422,14 @@ update_event_state (BroadwayServer *server,
|
||||
{
|
||||
surface->x = message->configure_notify.x;
|
||||
surface->y = message->configure_notify.y;
|
||||
|
||||
if (server->focused_surface_id != message->configure_notify.id &&
|
||||
server->pointer_grab_surface_id == -1 && surface->modal_hint)
|
||||
{
|
||||
broadway_server_surface_raise (server, message->configure_notify.id);
|
||||
broadway_server_focus_surface (server, message->configure_notify.id);
|
||||
broadway_server_flush (server);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case BROADWAY_EVENT_ROUNDTRIP_NOTIFY:
|
||||
@@ -1568,6 +1577,7 @@ broadway_server_destroy_surface (BroadwayServer *server,
|
||||
int id)
|
||||
{
|
||||
BroadwaySurface *surface;
|
||||
gint32 transient_for = -1;
|
||||
|
||||
if (server->mouse_in_surface_id == id)
|
||||
{
|
||||
@@ -1585,11 +1595,24 @@ broadway_server_destroy_surface (BroadwayServer *server,
|
||||
surface = broadway_server_lookup_surface (server, id);
|
||||
if (surface != NULL)
|
||||
{
|
||||
if (server->focused_surface_id == id)
|
||||
transient_for = surface->transient_for;
|
||||
|
||||
server->surfaces = g_list_remove (server->surfaces, surface);
|
||||
g_hash_table_remove (server->surface_id_hash,
|
||||
GINT_TO_POINTER (id));
|
||||
broadway_surface_free (server, surface);
|
||||
}
|
||||
|
||||
if (transient_for != -1)
|
||||
{
|
||||
surface = broadway_server_lookup_surface (server, transient_for);
|
||||
if (surface != NULL)
|
||||
{
|
||||
broadway_server_focus_surface (server, transient_for);
|
||||
broadway_server_flush (server);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
@@ -1710,6 +1733,19 @@ broadway_server_surface_set_transient_for (BroadwayServer *server,
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
broadway_server_surface_set_modal_hint (BroadwayServer *server,
|
||||
int id, gboolean modal_hint)
|
||||
{
|
||||
BroadwaySurface *surface;
|
||||
|
||||
surface = broadway_server_lookup_surface (server, id);
|
||||
if (surface == NULL)
|
||||
return;
|
||||
|
||||
surface->modal_hint = modal_hint;
|
||||
}
|
||||
|
||||
gboolean
|
||||
broadway_server_has_client (BroadwayServer *server)
|
||||
{
|
||||
|
||||
@@ -130,6 +130,9 @@ gboolean broadway_server_surface_move_resize (BroadwayServer *
|
||||
int height);
|
||||
void broadway_server_focus_surface (BroadwayServer *server,
|
||||
int new_focused_surface);
|
||||
void broadway_server_surface_set_modal_hint (BroadwayServer *server,
|
||||
int id,
|
||||
gboolean modal_hint);
|
||||
|
||||
|
||||
#endif /* __BROADWAY_SERVER__ */
|
||||
|
||||
@@ -380,6 +380,11 @@ client_handle_request (BroadwayClient *client,
|
||||
case BROADWAY_REQUEST_SET_SHOW_KEYBOARD:
|
||||
broadway_server_set_show_keyboard (server, request->set_show_keyboard.show_keyboard);
|
||||
break;
|
||||
case BROADWAY_REQUEST_SET_MODAL_HINT:
|
||||
broadway_server_surface_set_modal_hint (server,
|
||||
request->set_modal_hint.id,
|
||||
request->set_modal_hint.modal_hint);
|
||||
break;
|
||||
default:
|
||||
g_warning ("Unknown request of type %d", request->base.type);
|
||||
}
|
||||
|
||||
@@ -561,6 +561,18 @@ _gdk_broadway_server_surface_set_transient_for (GdkBroadwayServer *server,
|
||||
BROADWAY_REQUEST_SET_TRANSIENT_FOR);
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_broadway_server_surface_set_modal_hint (GdkBroadwayServer *server,
|
||||
int id, gboolean modal_hint)
|
||||
{
|
||||
BroadwayRequestSetModalHint msg;
|
||||
|
||||
msg.id = id;
|
||||
msg.modal_hint = modal_hint;
|
||||
gdk_broadway_server_send_message (server, msg,
|
||||
BROADWAY_REQUEST_SET_MODAL_HINT);
|
||||
}
|
||||
|
||||
static int
|
||||
open_shared_memory (void)
|
||||
{
|
||||
|
||||
@@ -78,5 +78,8 @@ gboolean _gdk_broadway_server_surface_move_resize (GdkBroadwaySe
|
||||
int y,
|
||||
int width,
|
||||
int height);
|
||||
void _gdk_broadway_server_surface_set_modal_hint (GdkBroadwayServer *server,
|
||||
int id,
|
||||
gboolean modal_hint);
|
||||
|
||||
#endif /* __GDK_BROADWAY_SERVER__ */
|
||||
|
||||
@@ -82,6 +82,27 @@ gdk_event_source_check (GSource *source)
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void
|
||||
handle_focus_change (GdkEvent *event)
|
||||
{
|
||||
GdkEvent *focus_event;
|
||||
gboolean focus_in = (gdk_event_get_event_type (event) == GDK_ENTER_NOTIFY);
|
||||
|
||||
if (gdk_crossing_event_get_detail (event) == GDK_NOTIFY_INFERIOR)
|
||||
return;
|
||||
|
||||
if (!gdk_crossing_event_get_focus (event) )
|
||||
return;
|
||||
|
||||
focus_event = gdk_focus_event_new (gdk_event_get_surface (event),
|
||||
gdk_event_get_device (event),
|
||||
focus_in);
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
gdk_display_put_event (gdk_event_get_display (event), focus_event);
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
gdk_event_unref (focus_event);
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_broadway_events_got_input (GdkDisplay *display,
|
||||
BroadwayInputMsg *message)
|
||||
@@ -110,6 +131,8 @@ _gdk_broadway_events_got_input (GdkDisplay *display,
|
||||
|
||||
node = _gdk_event_queue_append (display, event);
|
||||
_gdk_windowing_got_event (display, node, event, message->base.serial);
|
||||
|
||||
handle_focus_change (event);
|
||||
}
|
||||
break;
|
||||
case BROADWAY_EVENT_LEAVE:
|
||||
@@ -126,6 +149,8 @@ _gdk_broadway_events_got_input (GdkDisplay *display,
|
||||
message->crossing.mode,
|
||||
GDK_NOTIFY_ANCESTOR);
|
||||
|
||||
handle_focus_change (event);
|
||||
|
||||
node = _gdk_event_queue_append (display, event);
|
||||
_gdk_windowing_got_event (display, node, event, message->base.serial);
|
||||
}
|
||||
|
||||
@@ -709,6 +709,21 @@ gdk_broadway_surface_set_transient_for (GdkSurface *surface,
|
||||
_gdk_broadway_server_surface_set_transient_for (display->server, impl->id, impl->transient_for);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_broadway_surface_set_modal_hint (GdkSurface *surface,
|
||||
gboolean modal)
|
||||
{
|
||||
GdkBroadwayDisplay *display;
|
||||
GdkBroadwaySurface *impl;
|
||||
|
||||
impl = GDK_BROADWAY_SURFACE (surface);
|
||||
|
||||
impl->modal_hint = modal;
|
||||
|
||||
display = GDK_BROADWAY_DISPLAY (gdk_surface_get_display (surface));
|
||||
_gdk_broadway_server_surface_set_modal_hint (display->server, impl->id, impl->modal_hint);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_broadway_surface_get_geometry (GdkSurface *surface,
|
||||
int *x,
|
||||
@@ -1433,6 +1448,8 @@ gdk_broadway_toplevel_set_property (GObject *object,
|
||||
break;
|
||||
|
||||
case LAST_PROP + GDK_TOPLEVEL_PROP_MODAL:
|
||||
gdk_broadway_surface_set_modal_hint (surface, g_value_get_boolean (value));
|
||||
g_object_notify_by_pspec (G_OBJECT (surface), pspec);
|
||||
break;
|
||||
|
||||
case LAST_PROP + GDK_TOPLEVEL_PROP_ICON_LIST:
|
||||
@@ -1479,6 +1496,10 @@ gdk_broadway_toplevel_get_property (GObject *object,
|
||||
g_value_set_object (value, surface->transient_for);
|
||||
break;
|
||||
|
||||
case LAST_PROP + GDK_TOPLEVEL_PROP_MODAL:
|
||||
g_value_set_boolean (value, surface->modal_hint);
|
||||
break;
|
||||
|
||||
case LAST_PROP + GDK_TOPLEVEL_PROP_ICON_LIST:
|
||||
g_value_set_pointer (value, NULL);
|
||||
break;
|
||||
|
||||
@@ -54,6 +54,7 @@ struct _GdkBroadwaySurface
|
||||
|
||||
gboolean dirty;
|
||||
gboolean last_synced;
|
||||
gboolean modal_hint;
|
||||
|
||||
GdkGeometry geometry_hints;
|
||||
GdkSurfaceHints geometry_hints_mask;
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "gdkcontentformats.h"
|
||||
#include "gdkcontentserializer.h"
|
||||
#include "gdkcontentdeserializer.h"
|
||||
#include "gdkdebugprivate.h"
|
||||
|
||||
#include <gio/gio.h>
|
||||
|
||||
@@ -213,6 +214,8 @@ file_transfer_portal_register_files (const char **files,
|
||||
afd->len = g_strv_length ((char **)files);
|
||||
afd->start = 0;
|
||||
|
||||
GDK_DEBUG (DND, "file transfer portal: registering %d files", afd->len);
|
||||
|
||||
g_variant_builder_init (&options, G_VARIANT_TYPE_VARDICT);
|
||||
g_variant_builder_add (&options, "{sv}", "writable", g_variant_new_boolean (writable));
|
||||
g_variant_builder_add (&options, "{sv}", "autostop", g_variant_new_boolean (TRUE));
|
||||
@@ -348,9 +351,8 @@ portal_ready (GObject *object,
|
||||
static void
|
||||
portal_file_serializer (GdkContentSerializer *serializer)
|
||||
{
|
||||
GFile *file;
|
||||
const GValue *value;
|
||||
GPtrArray *files;
|
||||
const GValue *value;
|
||||
|
||||
files = g_ptr_array_new_with_free_func (g_free);
|
||||
|
||||
@@ -358,9 +360,24 @@ portal_file_serializer (GdkContentSerializer *serializer)
|
||||
|
||||
if (G_VALUE_HOLDS (value, G_TYPE_FILE))
|
||||
{
|
||||
GFile *file;
|
||||
|
||||
file = g_value_get_object (gdk_content_serializer_get_value (serializer));
|
||||
if (file)
|
||||
g_ptr_array_add (files, g_file_get_path (file));
|
||||
|
||||
if (file && g_file_peek_path (file))
|
||||
{
|
||||
GDK_DEBUG (DND, "file transfer portal: Adding %s", g_file_peek_path (file));
|
||||
g_ptr_array_add (files, g_file_get_path (file));
|
||||
}
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
else if (GDK_DEBUG_CHECK (DND))
|
||||
{
|
||||
char *uri = g_file_get_uri (file);
|
||||
gdk_debug_message ("file transfer portal: %s has no path, dropping\n", uri);
|
||||
g_free (uri);
|
||||
}
|
||||
#endif
|
||||
|
||||
g_ptr_array_add (files, NULL);
|
||||
}
|
||||
else if (G_VALUE_HOLDS (value, GDK_TYPE_FILE_LIST))
|
||||
@@ -368,7 +385,21 @@ portal_file_serializer (GdkContentSerializer *serializer)
|
||||
GSList *l;
|
||||
|
||||
for (l = g_value_get_boxed (value); l; l = l->next)
|
||||
g_ptr_array_add (files, g_file_get_path (l->data));
|
||||
{
|
||||
GFile *file = l->data;
|
||||
|
||||
if (file && g_file_peek_path (file))
|
||||
{
|
||||
GDK_DEBUG (DND, "file transfer portal: Adding %s", g_file_peek_path (file));
|
||||
g_ptr_array_add (files, g_file_get_path (file));
|
||||
}
|
||||
else
|
||||
{
|
||||
char *uri = g_file_get_uri (file);
|
||||
gdk_debug_message ("file transfer portal: %s has no path, dropping", uri);
|
||||
g_free (uri);
|
||||
}
|
||||
}
|
||||
|
||||
g_ptr_array_add (files, NULL);
|
||||
}
|
||||
@@ -395,6 +426,15 @@ portal_finish (GObject *object,
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (GDK_DEBUG_CHECK (DND))
|
||||
{
|
||||
char *s = g_strjoinv (", ", files);
|
||||
gdk_debug_message ("file transfer portal: Receiving files: %s", s);
|
||||
g_free (s);
|
||||
}
|
||||
#endif
|
||||
|
||||
value = gdk_content_deserializer_get_value (deserializer);
|
||||
if (G_VALUE_HOLDS (value, G_TYPE_FILE))
|
||||
{
|
||||
|
||||
@@ -118,7 +118,8 @@ static const GdkDebugKey gdk_debug_keys[] = {
|
||||
{ "selection", GDK_DEBUG_SELECTION, "Information about selections" },
|
||||
{ "clipboard", GDK_DEBUG_CLIPBOARD, "Information about clipboards" },
|
||||
{ "nograbs", GDK_DEBUG_NOGRABS, "Disable pointer and keyboard grabs (X11)", TRUE },
|
||||
{ "portals", GDK_DEBUG_PORTALS, "Force the use of portals", TRUE },
|
||||
{ "portals", GDK_DEBUG_PORTALS, "Force use of portals", TRUE },
|
||||
{ "no-portals", GDK_DEBUG_NO_PORTALS, "Disable use of portals", TRUE },
|
||||
{ "gl-disable", GDK_DEBUG_GL_DISABLE, "Disable OpenGL support", TRUE },
|
||||
{ "gl-debug", GDK_DEBUG_GL_DEBUG, "Insert debugging information in OpenGL", TRUE },
|
||||
{ "gl-legacy", GDK_DEBUG_GL_LEGACY, "Use a legacy OpenGL context", TRUE },
|
||||
@@ -359,6 +360,9 @@ gdk_should_use_portal (void)
|
||||
if (gdk_display_get_debug_flags (NULL) & GDK_DEBUG_PORTALS)
|
||||
return TRUE;
|
||||
|
||||
if (gdk_display_get_debug_flags (NULL) & GDK_DEBUG_NO_PORTALS)
|
||||
return FALSE;
|
||||
|
||||
if (gdk_running_in_sandbox ())
|
||||
return TRUE;
|
||||
|
||||
|
||||
@@ -795,6 +795,22 @@ file_serializer_finish (GObject *source,
|
||||
gdk_content_serializer_return_success (serializer);
|
||||
}
|
||||
|
||||
static char *
|
||||
file_get_native_uri (GFile *file)
|
||||
{
|
||||
char *path;
|
||||
|
||||
path = g_file_get_path (file);
|
||||
if (path != NULL)
|
||||
{
|
||||
char *uri = g_filename_to_uri (path, NULL, NULL);
|
||||
g_free (path);
|
||||
return uri;
|
||||
}
|
||||
|
||||
return g_file_get_uri (file);
|
||||
}
|
||||
|
||||
static void
|
||||
file_uri_serializer (GdkContentSerializer *serializer)
|
||||
{
|
||||
@@ -811,7 +827,7 @@ file_uri_serializer (GdkContentSerializer *serializer)
|
||||
file = g_value_get_object (gdk_content_serializer_get_value (serializer));
|
||||
if (file)
|
||||
{
|
||||
uri = g_file_get_uri (file);
|
||||
uri = file_get_native_uri (file);
|
||||
g_string_append (str, uri);
|
||||
g_free (uri);
|
||||
}
|
||||
@@ -827,7 +843,7 @@ file_uri_serializer (GdkContentSerializer *serializer)
|
||||
|
||||
for (l = g_value_get_boxed (value); l; l = l->next)
|
||||
{
|
||||
uri = g_file_get_uri (l->data);
|
||||
uri = file_get_native_uri (l->data);
|
||||
g_string_append (str, uri);
|
||||
g_free (uri);
|
||||
g_string_append (str, "\r\n");
|
||||
|
||||
@@ -40,7 +40,8 @@ typedef enum {
|
||||
/* flags below are influencing behavior */
|
||||
GDK_DEBUG_NOGRABS = 1 << 11,
|
||||
GDK_DEBUG_PORTALS = 1 << 12,
|
||||
GDK_DEBUG_GL_DISABLE = 1 << 13,
|
||||
GDK_DEBUG_NO_PORTALS = 1 << 13,
|
||||
GDK_DEBUG_GL_DISABLE = 1 << 14,
|
||||
GDK_DEBUG_GL_LEGACY = 1 << 16,
|
||||
GDK_DEBUG_GL_GLES = 1 << 17,
|
||||
GDK_DEBUG_GL_DEBUG = 1 << 18,
|
||||
|
||||
+3
-3
@@ -197,7 +197,7 @@ gdk_device_tool_get_serial (GdkDeviceTool *tool)
|
||||
*
|
||||
* Gets the hardware ID of this tool, or 0 if it's not known.
|
||||
*
|
||||
* When non-zero, the identificator is unique for the given tool model,
|
||||
* When non-zero, the identifier is unique for the given tool model,
|
||||
* meaning that two identical tools will share the same @hardware_id,
|
||||
* but will have different serial numbers (see
|
||||
* [method@Gdk.DeviceTool.get_serial]).
|
||||
@@ -205,9 +205,9 @@ gdk_device_tool_get_serial (GdkDeviceTool *tool)
|
||||
* This is a more concrete (and device specific) method to identify
|
||||
* a `GdkDeviceTool` than [method@Gdk.DeviceTool.get_tool_type],
|
||||
* as a tablet may support multiple devices with the same
|
||||
* `GdkDeviceToolType`, but different hardware identificators.
|
||||
* `GdkDeviceToolType`, but different hardware identifiers.
|
||||
*
|
||||
* Returns: The hardware identificator of this tool.
|
||||
* Returns: The hardware identifier of this tool.
|
||||
*/
|
||||
guint64
|
||||
gdk_device_tool_get_hardware_id (GdkDeviceTool *tool)
|
||||
|
||||
+9
-8
@@ -471,8 +471,8 @@ gdk_display_get_event (GdkDisplay *display)
|
||||
* Appends the given event onto the front of the event
|
||||
* queue for @display.
|
||||
*
|
||||
* This function is only useful in very special situations
|
||||
* and should not be used by applications.
|
||||
* Deprecated: 4.10: This function is only useful in very
|
||||
* special situations and should not be used by applications.
|
||||
**/
|
||||
void
|
||||
gdk_display_put_event (GdkDisplay *display,
|
||||
@@ -1114,7 +1114,7 @@ gdk_display_get_app_launch_context (GdkDisplay *display)
|
||||
|
||||
/**
|
||||
* gdk_display_open:
|
||||
* @display_name: the name of the display to open
|
||||
* @display_name: (nullable): the name of the display to open
|
||||
*
|
||||
* Opens a display.
|
||||
*
|
||||
@@ -1148,6 +1148,8 @@ _gdk_display_get_next_serial (GdkDisplay *display)
|
||||
* with custom startup-notification identifier unless
|
||||
* [method@Gtk.Window.set_auto_startup_notification]
|
||||
* is called to disable that feature.
|
||||
*
|
||||
* Deprecated: 4.10: Using [method@Gdk.Toplevel.set_startup_id] is sufficient
|
||||
*/
|
||||
void
|
||||
gdk_display_notify_startup_complete (GdkDisplay *display,
|
||||
@@ -1166,6 +1168,8 @@ gdk_display_notify_startup_complete (GdkDisplay *display,
|
||||
* if no ID has been defined.
|
||||
*
|
||||
* Returns: (nullable): the startup notification ID for @display
|
||||
*
|
||||
* Deprecated: 4.10
|
||||
*/
|
||||
const char *
|
||||
gdk_display_get_startup_notification_id (GdkDisplay *display)
|
||||
@@ -1775,11 +1779,11 @@ gdk_display_init_egl (GdkDisplay *self,
|
||||
gpointer
|
||||
gdk_display_get_egl_display (GdkDisplay *self)
|
||||
{
|
||||
#ifdef HAVE_EGL
|
||||
GdkDisplayPrivate *priv = gdk_display_get_instance_private (self);
|
||||
|
||||
g_return_val_if_fail (GDK_IS_DISPLAY (self), NULL);
|
||||
|
||||
#ifdef HAVE_EGL
|
||||
if (!priv->egl_display &&
|
||||
!gdk_display_prepare_gl (self, NULL))
|
||||
return NULL;
|
||||
@@ -2013,10 +2017,7 @@ gdk_display_get_monitors (GdkDisplay *self)
|
||||
* Gets the monitor in which the largest area of @surface
|
||||
* resides.
|
||||
*
|
||||
* Returns a monitor close to @surface if it is outside
|
||||
* of all monitors.
|
||||
*
|
||||
* Returns: (transfer none): the monitor with the largest
|
||||
* Returns: (transfer none) (nullable): the monitor with the largest
|
||||
* overlap with @surface
|
||||
*/
|
||||
GdkMonitor *
|
||||
|
||||
+3
-3
@@ -83,10 +83,10 @@ GdkClipboard * gdk_display_get_clipboard (GdkDisplay
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkClipboard * gdk_display_get_primary_clipboard (GdkDisplay *display);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GDK_DEPRECATED_IN_4_10_FOR(gdk_toplevel_set_startup_id)
|
||||
void gdk_display_notify_startup_complete (GdkDisplay *display,
|
||||
const char *startup_id);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GDK_DEPRECATED_IN_4_10
|
||||
const char * gdk_display_get_startup_notification_id (GdkDisplay *display);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
@@ -104,7 +104,7 @@ GDK_AVAILABLE_IN_ALL
|
||||
GdkMonitor * gdk_display_get_monitor_at_surface (GdkDisplay *display,
|
||||
GdkSurface *surface);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GDK_DEPRECATED_IN_4_10
|
||||
void gdk_display_put_event (GdkDisplay *display,
|
||||
GdkEvent *event);
|
||||
|
||||
|
||||
+8
-1
@@ -1174,9 +1174,16 @@ gdk_event_get_axes (GdkEvent *event,
|
||||
double **axes,
|
||||
guint *n_axes)
|
||||
{
|
||||
gboolean ret;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_EVENT (event), FALSE);
|
||||
|
||||
return GDK_EVENT_GET_CLASS (event)->get_axes (event, axes, n_axes);
|
||||
ret = GDK_EVENT_GET_CLASS (event)->get_axes (event, axes, n_axes);
|
||||
|
||||
if (*axes == NULL)
|
||||
return FALSE;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
double *
|
||||
|
||||
@@ -621,8 +621,11 @@ gdk_frame_clock_paint_idle (void *data)
|
||||
priv->phase = GDK_FRAME_CLOCK_PHASE_NONE;
|
||||
}
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (GDK_DEBUG_CHECK (FRAMES))
|
||||
timings->frame_end_time = g_get_monotonic_time ();
|
||||
if (GDK_DEBUG_CHECK (FRAMES))
|
||||
{
|
||||
if (timings)
|
||||
timings->frame_end_time = g_get_monotonic_time ();
|
||||
}
|
||||
#endif /* G_ENABLE_DEBUG */
|
||||
G_GNUC_FALLTHROUGH;
|
||||
|
||||
|
||||
+30
-3
@@ -501,11 +501,23 @@ gdk_gl_context_real_is_shared (GdkGLContext *self,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_gl_context_real_is_current (GdkGLContext *self)
|
||||
{
|
||||
#ifdef HAVE_EGL
|
||||
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (self);
|
||||
|
||||
return priv->egl_context == eglGetCurrentContext ();
|
||||
#else
|
||||
return TRUE;
|
||||
#endif
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_gl_context_real_clear_current (GdkGLContext *context)
|
||||
{
|
||||
GdkDisplay *display = gdk_gl_context_get_display (context);
|
||||
#ifdef HAVE_EGL
|
||||
GdkDisplay *display = gdk_gl_context_get_display (context);
|
||||
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
|
||||
|
||||
if (priv->egl_context == NULL)
|
||||
@@ -670,6 +682,7 @@ gdk_gl_context_class_init (GdkGLContextClass *klass)
|
||||
klass->is_shared = gdk_gl_context_real_is_shared;
|
||||
klass->make_current = gdk_gl_context_real_make_current;
|
||||
klass->clear_current = gdk_gl_context_real_clear_current;
|
||||
klass->is_current = gdk_gl_context_real_is_current;
|
||||
klass->get_default_framebuffer = gdk_gl_context_real_get_default_framebuffer;
|
||||
|
||||
draw_context_class->begin_frame = gdk_gl_context_real_begin_frame;
|
||||
@@ -1551,6 +1564,12 @@ gdk_gl_context_check_extensions (GdkGLContext *context)
|
||||
priv->extensions_checked = TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_gl_context_check_is_current (GdkGLContext *context)
|
||||
{
|
||||
return GDK_GL_CONTEXT_GET_CLASS (context)->is_current (context);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_gl_context_make_current:
|
||||
* @context: a `GdkGLContext`
|
||||
@@ -1569,7 +1588,7 @@ gdk_gl_context_make_current (GdkGLContext *context)
|
||||
masked_context = mask_context (context, surfaceless);
|
||||
|
||||
current = g_private_get (&thread_current_context);
|
||||
if (current == masked_context)
|
||||
if (current == masked_context && gdk_gl_context_check_is_current (context))
|
||||
return;
|
||||
|
||||
/* we need to realize the GdkGLContext if it wasn't explicitly realized */
|
||||
@@ -1740,10 +1759,18 @@ GdkGLContext *
|
||||
gdk_gl_context_get_current (void)
|
||||
{
|
||||
MaskedContext *current;
|
||||
GdkGLContext *context;
|
||||
|
||||
current = g_private_get (&thread_current_context);
|
||||
context = unmask_context (current);
|
||||
|
||||
return unmask_context (current);
|
||||
if (context && !gdk_gl_context_check_is_current (context))
|
||||
{
|
||||
g_private_replace (&thread_current_context, NULL);
|
||||
context = NULL;
|
||||
}
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
gboolean
|
||||
|
||||
@@ -83,6 +83,7 @@ struct _GdkGLContextClass
|
||||
gboolean (* make_current) (GdkGLContext *context,
|
||||
gboolean surfaceless);
|
||||
gboolean (* clear_current) (GdkGLContext *context);
|
||||
gboolean (* is_current) (GdkGLContext *context);
|
||||
cairo_region_t * (* get_damage) (GdkGLContext *context);
|
||||
|
||||
gboolean (* is_shared) (GdkGLContext *self,
|
||||
|
||||
+26
-24
@@ -53,10 +53,8 @@ struct _GdkGLTextureClass {
|
||||
G_DEFINE_TYPE (GdkGLTexture, gdk_gl_texture, GDK_TYPE_TEXTURE)
|
||||
|
||||
static void
|
||||
gdk_gl_texture_dispose (GObject *object)
|
||||
drop_gl_resources (GdkGLTexture *self)
|
||||
{
|
||||
GdkGLTexture *self = GDK_GL_TEXTURE (object);
|
||||
|
||||
if (self->destroy)
|
||||
{
|
||||
self->destroy (self->data);
|
||||
@@ -66,17 +64,29 @@ gdk_gl_texture_dispose (GObject *object)
|
||||
|
||||
g_clear_object (&self->context);
|
||||
self->id = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_gl_texture_dispose (GObject *object)
|
||||
{
|
||||
GdkGLTexture *self = GDK_GL_TEXTURE (object);
|
||||
|
||||
drop_gl_resources (self);
|
||||
|
||||
g_clear_object (&self->saved);
|
||||
|
||||
G_OBJECT_CLASS (gdk_gl_texture_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
typedef void (* GLFunc) (GdkGLTexture *self,
|
||||
GdkGLContext *context,
|
||||
gpointer data);
|
||||
|
||||
typedef struct _InvokeData
|
||||
{
|
||||
GdkGLTexture *self;
|
||||
volatile int spinlock;
|
||||
GFunc func;
|
||||
GLFunc func;
|
||||
gpointer data;
|
||||
} InvokeData;
|
||||
|
||||
@@ -91,7 +101,7 @@ gdk_gl_texture_invoke_callback (gpointer data)
|
||||
gdk_gl_context_make_current (context);
|
||||
glBindTexture (GL_TEXTURE_2D, invoke->self->id);
|
||||
|
||||
invoke->func (invoke->self, invoke->data);
|
||||
invoke->func (invoke->self, context, invoke->data);
|
||||
|
||||
g_atomic_int_set (&invoke->spinlock, 1);
|
||||
|
||||
@@ -100,7 +110,7 @@ gdk_gl_texture_invoke_callback (gpointer data)
|
||||
|
||||
static void
|
||||
gdk_gl_texture_run (GdkGLTexture *self,
|
||||
GFunc func,
|
||||
GLFunc func,
|
||||
gpointer data)
|
||||
{
|
||||
InvokeData invoke = { self, 0, func, data };
|
||||
@@ -145,19 +155,19 @@ gdk_gl_texture_find_format (gboolean use_es,
|
||||
}
|
||||
|
||||
static inline void
|
||||
gdk_gl_texture_do_download (gpointer texture_,
|
||||
gpointer download_)
|
||||
gdk_gl_texture_do_download (GdkGLTexture *self,
|
||||
GdkGLContext *context,
|
||||
gpointer download_)
|
||||
{
|
||||
GdkTexture *texture = GDK_TEXTURE (self);
|
||||
gsize expected_stride;
|
||||
GdkGLTexture *self = texture_;
|
||||
GdkTexture *texture = texture_;
|
||||
Download *download = download_;
|
||||
GLenum gl_internal_format, gl_format, gl_type;
|
||||
|
||||
expected_stride = texture->width * gdk_memory_format_bytes_per_pixel (download->format);
|
||||
|
||||
if (download->stride == expected_stride &&
|
||||
!gdk_gl_context_get_use_es (self->context) &&
|
||||
!gdk_gl_context_get_use_es (context) &&
|
||||
gdk_memory_format_gl_format (download->format, TRUE, &gl_internal_format, &gl_format, &gl_type))
|
||||
{
|
||||
glGetTexImage (GL_TEXTURE_2D,
|
||||
@@ -175,11 +185,11 @@ gdk_gl_texture_do_download (gpointer texture_,
|
||||
glGenFramebuffers (1, &fbo);
|
||||
glBindFramebuffer (GL_FRAMEBUFFER, fbo);
|
||||
glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, self->id, 0);
|
||||
if (gdk_gl_context_check_version (self->context, 4, 3, 3, 1))
|
||||
if (gdk_gl_context_check_version (context, 4, 3, 3, 1))
|
||||
{
|
||||
glGetFramebufferParameteriv (GL_FRAMEBUFFER, GL_IMPLEMENTATION_COLOR_READ_FORMAT, &gl_read_format);
|
||||
glGetFramebufferParameteriv (GL_FRAMEBUFFER, GL_IMPLEMENTATION_COLOR_READ_TYPE, &gl_read_type);
|
||||
if (!gdk_gl_texture_find_format (gdk_gl_context_get_use_es (self->context), gl_read_format, gl_read_type, &actual_format))
|
||||
if (!gdk_gl_texture_find_format (gdk_gl_context_get_use_es (context), gl_read_format, gl_read_type, &actual_format))
|
||||
actual_format = GDK_MEMORY_R8G8B8A8_PREMULTIPLIED; /* pray */
|
||||
}
|
||||
else
|
||||
@@ -193,7 +203,7 @@ gdk_gl_texture_do_download (gpointer texture_,
|
||||
(download->stride == expected_stride))
|
||||
{
|
||||
glReadPixels (0, 0,
|
||||
texture->width, texture->height,
|
||||
texture->width, texture->height,
|
||||
gl_read_format,
|
||||
gl_read_type,
|
||||
download->data);
|
||||
@@ -204,7 +214,7 @@ gdk_gl_texture_do_download (gpointer texture_,
|
||||
guchar *pixels = g_malloc_n (texture->width * actual_bpp, texture->height);
|
||||
|
||||
glReadPixels (0, 0,
|
||||
texture->width, texture->height,
|
||||
texture->width, texture->height,
|
||||
gl_read_format,
|
||||
gl_read_type,
|
||||
pixels);
|
||||
@@ -297,15 +307,7 @@ gdk_gl_texture_release (GdkGLTexture *self)
|
||||
self->saved = GDK_TEXTURE (gdk_memory_texture_from_texture (texture,
|
||||
gdk_texture_get_format (texture)));
|
||||
|
||||
if (self->destroy)
|
||||
{
|
||||
self->destroy (self->data);
|
||||
self->destroy = NULL;
|
||||
self->data = NULL;
|
||||
}
|
||||
|
||||
g_clear_object (&self->context);
|
||||
self->id = 0;
|
||||
drop_gl_resources (self);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_DESCRIPTION,
|
||||
PROP_DISPLAY,
|
||||
PROP_MANUFACTURER,
|
||||
PROP_MODEL,
|
||||
@@ -81,6 +82,10 @@ gdk_monitor_get_property (GObject *object,
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_DESCRIPTION:
|
||||
g_value_set_string (value, monitor->description);
|
||||
break;
|
||||
|
||||
case PROP_DISPLAY:
|
||||
g_value_set_object (value, monitor->display);
|
||||
break;
|
||||
@@ -154,6 +159,7 @@ gdk_monitor_finalize (GObject *object)
|
||||
{
|
||||
GdkMonitor *monitor = GDK_MONITOR (object);
|
||||
|
||||
g_free (monitor->description);
|
||||
g_free (monitor->connector);
|
||||
g_free (monitor->manufacturer);
|
||||
g_free (monitor->model);
|
||||
@@ -170,6 +176,18 @@ gdk_monitor_class_init (GdkMonitorClass *class)
|
||||
object_class->get_property = gdk_monitor_get_property;
|
||||
object_class->set_property = gdk_monitor_set_property;
|
||||
|
||||
/**
|
||||
* GdkMonitor:description: (attributes org.gtk.Property.get=gdk_monitor_get_description)
|
||||
*
|
||||
* A short description of the monitor, meant for display to the user.
|
||||
*
|
||||
* Since: 4.10
|
||||
*/
|
||||
props[PROP_DESCRIPTION] =
|
||||
g_param_spec_string ("description", NULL, NULL,
|
||||
NULL,
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* GdkMonitor:display: (attributes org.gtk.Property.get=gdk_monitor_get_display)
|
||||
*
|
||||
@@ -377,6 +395,10 @@ gdk_monitor_get_height_mm (GdkMonitor *monitor)
|
||||
*
|
||||
* Gets the name of the monitor's connector, if available.
|
||||
*
|
||||
* These are strings such as "eDP-1", or "HDMI-2". They depend
|
||||
* on software and hardware configuration, and should not be
|
||||
* relied on as stable identifiers of a specific monitor.
|
||||
*
|
||||
* Returns: (transfer none) (nullable): the name of the connector
|
||||
*/
|
||||
const char *
|
||||
@@ -619,3 +641,33 @@ gdk_monitor_is_valid (GdkMonitor *monitor)
|
||||
|
||||
return monitor->valid;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_monitor_get_description: (attributes org.gtk.Method.get_property=description)
|
||||
* @monitor: a `GdkMonitor`
|
||||
*
|
||||
* Gets a string describing the monitor, if available.
|
||||
*
|
||||
* This can be used to identify a monitor in the UI.
|
||||
*
|
||||
* Returns: (transfer none) (nullable): the monitor description
|
||||
*
|
||||
* Since: 4.10
|
||||
*/
|
||||
const char *
|
||||
gdk_monitor_get_description (GdkMonitor *monitor)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_MONITOR (monitor), NULL);
|
||||
|
||||
return monitor->description;
|
||||
}
|
||||
|
||||
void
|
||||
gdk_monitor_set_description (GdkMonitor *monitor,
|
||||
const char *description)
|
||||
{
|
||||
g_free (monitor->description);
|
||||
monitor->description = g_strdup (description);
|
||||
g_object_notify_by_pspec (G_OBJECT (monitor), props[PROP_DESCRIPTION]);
|
||||
}
|
||||
|
||||
|
||||
@@ -86,6 +86,8 @@ GDK_AVAILABLE_IN_ALL
|
||||
GdkSubpixelLayout gdk_monitor_get_subpixel_layout (GdkMonitor *monitor);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gdk_monitor_is_valid (GdkMonitor *monitor);
|
||||
GDK_AVAILABLE_IN_4_10
|
||||
const char * gdk_monitor_get_description (GdkMonitor *monitor);
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkMonitor, g_object_unref)
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@ struct _GdkMonitor {
|
||||
char *manufacturer;
|
||||
char *model;
|
||||
char *connector;
|
||||
char *description;
|
||||
GdkRectangle geometry;
|
||||
int width_mm;
|
||||
int height_mm;
|
||||
@@ -70,6 +71,8 @@ void gdk_monitor_set_refresh_rate (GdkMonitor *monitor,
|
||||
void gdk_monitor_set_subpixel_layout (GdkMonitor *monitor,
|
||||
GdkSubpixelLayout subpixel);
|
||||
void gdk_monitor_invalidate (GdkMonitor *monitor);
|
||||
void gdk_monitor_set_description (GdkMonitor *monitor,
|
||||
const char *description);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
@@ -23,4 +23,23 @@ void gdk_source_set_static_name_by_id (guint tag,
|
||||
#define I_(string) g_intern_static_string (string)
|
||||
#endif
|
||||
|
||||
#if !GLIB_CHECK_VERSION (2, 75, 1)
|
||||
static inline gboolean
|
||||
g_set_str (char **str_pointer,
|
||||
const char *new_str)
|
||||
{
|
||||
char *copy;
|
||||
|
||||
if (*str_pointer == new_str ||
|
||||
(*str_pointer && new_str && strcmp (*str_pointer, new_str) == 0))
|
||||
return FALSE;
|
||||
|
||||
copy = g_strdup (new_str);
|
||||
g_free (*str_pointer);
|
||||
*str_pointer = copy;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __GDK__PRIVATE_H__ */
|
||||
|
||||
+3
-3
@@ -586,7 +586,7 @@ gdk_rgba_parser_parse (GtkCssParser *parser,
|
||||
else if (gtk_css_token_is (token, GTK_CSS_TOKEN_HASH_ID) ||
|
||||
gtk_css_token_is (token, GTK_CSS_TOKEN_HASH_UNRESTRICTED))
|
||||
{
|
||||
const char *s = token->string.string;
|
||||
const char *s = gtk_css_token_get_string (token);
|
||||
|
||||
switch (strlen (s))
|
||||
{
|
||||
@@ -637,13 +637,13 @@ gdk_rgba_parser_parse (GtkCssParser *parser,
|
||||
{
|
||||
*rgba = (GdkRGBA) { 0, 0, 0, 0 };
|
||||
}
|
||||
else if (gdk_rgba_parse (rgba, token->string.string))
|
||||
else if (gdk_rgba_parse (rgba, gtk_css_token_get_string (token)))
|
||||
{
|
||||
/* everything's fine */
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_css_parser_error_syntax (parser, "\"%s\" is not a valid color name.", token->string.string);
|
||||
gtk_css_parser_error_syntax (parser, "\"%s\" is not a valid color name.", gtk_css_token_get_string (token));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
+17
-7
@@ -2789,9 +2789,10 @@ check_autohide (GdkEvent *event)
|
||||
{
|
||||
GdkDisplay *display;
|
||||
GdkDevice *device;
|
||||
GdkSurface *grab_surface;
|
||||
GdkSurface *grab_surface, *event_surface;
|
||||
GdkEventType evtype = gdk_event_get_event_type (event);
|
||||
|
||||
switch ((guint) gdk_event_get_event_type (event))
|
||||
switch ((guint) evtype)
|
||||
{
|
||||
case GDK_BUTTON_PRESS:
|
||||
#if 0
|
||||
@@ -2810,13 +2811,15 @@ check_autohide (GdkEvent *event)
|
||||
device = gdk_event_get_device (event);
|
||||
if (gdk_device_grab_info (display, device, &grab_surface, NULL))
|
||||
{
|
||||
GdkSurface *event_surface;
|
||||
|
||||
event_surface = gdk_event_get_surface (event);
|
||||
if (event_surface->autohide &&
|
||||
!event_surface->has_pointer)
|
||||
event_surface = NULL;
|
||||
|
||||
if (grab_surface != event_surface &&
|
||||
grab_surface != event_surface->parent &&
|
||||
grab_surface->autohide)
|
||||
if (grab_surface->autohide &&
|
||||
(!event_surface ||
|
||||
(grab_surface != event_surface &&
|
||||
grab_surface != event_surface->parent)))
|
||||
{
|
||||
GdkSurface *surface = grab_surface;
|
||||
|
||||
@@ -2831,6 +2834,13 @@ check_autohide (GdkEvent *event)
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GDK_ENTER_NOTIFY:
|
||||
case GDK_LEAVE_NOTIFY:
|
||||
event_surface = gdk_event_get_surface (event);
|
||||
if (event_surface->autohide &&
|
||||
gdk_crossing_event_get_mode (event) == GDK_CROSSING_NORMAL)
|
||||
event_surface->has_pointer = evtype == GDK_ENTER_NOTIFY;
|
||||
break;
|
||||
default:;
|
||||
}
|
||||
|
||||
|
||||
@@ -77,6 +77,7 @@ struct _GdkSurface
|
||||
guint autohide : 1;
|
||||
guint shortcuts_inhibited : 1;
|
||||
guint request_motion : 1;
|
||||
guint has_pointer : 1;
|
||||
|
||||
guint request_motion_id;
|
||||
|
||||
|
||||
+3
-3
@@ -463,7 +463,7 @@ gdk_texture_new_from_resource (const char *resource_path)
|
||||
* Creates a new texture by loading an image from a file.
|
||||
*
|
||||
* The file format is detected automatically. The supported formats
|
||||
* are PNG and JPEG, though more formats might be available.
|
||||
* are PNG, JPEG and TIFF, though more formats might be available.
|
||||
*
|
||||
* If %NULL is returned, then @error will be set.
|
||||
*
|
||||
@@ -556,7 +556,7 @@ gdk_texture_new_from_bytes_pixbuf (GBytes *bytes,
|
||||
* Creates a new texture by loading an image from memory,
|
||||
*
|
||||
* The file format is detected automatically. The supported formats
|
||||
* are PNG and JPEG, though more formats might be available.
|
||||
* are PNG, JPEG and TIFF, though more formats might be available.
|
||||
*
|
||||
* If %NULL is returned, then @error will be set.
|
||||
*
|
||||
@@ -602,7 +602,7 @@ gdk_texture_new_from_bytes (GBytes *bytes,
|
||||
* Creates a new texture by loading an image from a file.
|
||||
*
|
||||
* The file format is detected automatically. The supported formats
|
||||
* are PNG and JPEG, though more formats might be available.
|
||||
* are PNG, JPEG and TIFF, though more formats might be available.
|
||||
*
|
||||
* If %NULL is returned, then @error will be set.
|
||||
*
|
||||
|
||||
+12
-8
@@ -94,7 +94,7 @@ gdk_vulkan_strerror (VkResult result)
|
||||
* Because the Vulkan people don't make adding this too easy, here's
|
||||
* the process to manage it:
|
||||
* 1. go to
|
||||
* https://github.com/KhronosGroup/Vulkan-Headers/blob/master/include/vulkan/vulkan_core.h
|
||||
* https://github.com/KhronosGroup/Vulkan-Headers/blob/main/include/vulkan/vulkan_core.h
|
||||
* 2. Find the line where this enum value was added.
|
||||
* 3. Click the commit that added this line.
|
||||
* 4. The commit you're looking at now should also change
|
||||
@@ -215,6 +215,10 @@ gdk_vulkan_strerror (VkResult result)
|
||||
case VK_ERROR_PIPELINE_COMPILE_REQUIRED_EXT:
|
||||
return "A requested pipeline creation would have required compilation, but the application requested compilation to not be performed. (VK_ERROR_PIPELINE_COMPILE_REQUIRED_EXT)";
|
||||
#endif
|
||||
#if VK_HEADER_VERSION >= 213
|
||||
case VK_ERROR_COMPRESSION_EXHAUSTED_EXT:
|
||||
return "An image creation failed because internal resources required for compression are exhausted. (VK_ERROR_COMPRESSION_EXHAUSTED_EXT)";
|
||||
#endif
|
||||
#if VK_HEADER_VERSION < 140
|
||||
case VK_RESULT_RANGE_SIZE:
|
||||
#endif
|
||||
@@ -488,7 +492,7 @@ gdk_vulkan_context_end_frame (GdkDrawContext *draw_context,
|
||||
priv->draw_semaphore
|
||||
},
|
||||
.swapchainCount = 1,
|
||||
.pSwapchains = (VkSwapchainKHR[]) {
|
||||
.pSwapchains = (VkSwapchainKHR[]) {
|
||||
priv->swapchain
|
||||
},
|
||||
.pImageIndices = (uint32_t[]) {
|
||||
@@ -608,7 +612,7 @@ gdk_vulkan_context_real_init (GInitable *initable,
|
||||
{
|
||||
g_set_error_literal (error, GDK_VULKAN_ERROR, GDK_VULKAN_ERROR_NOT_AVAILABLE,
|
||||
"No supported image format found.");
|
||||
goto out_surface;
|
||||
goto out_surface;
|
||||
}
|
||||
priv->image_format = formats[i];
|
||||
priv->has_present_region = device_supports_incremental_present (display->vk_physical_device);
|
||||
@@ -1037,8 +1041,8 @@ gdk_display_create_vulkan_instance (GdkDisplay *display,
|
||||
GDK_VK_CHECK (vkEnumerateInstanceExtensionProperties, NULL, &n_extensions, extensions);
|
||||
|
||||
used_extensions = g_ptr_array_new ();
|
||||
g_ptr_array_add (used_extensions, (gpointer) VK_KHR_SURFACE_EXTENSION_NAME);
|
||||
g_ptr_array_add (used_extensions, (gpointer) GDK_DISPLAY_GET_CLASS (display)->vk_extension_name);
|
||||
g_ptr_array_add (used_extensions, (gpointer) VK_KHR_SURFACE_EXTENSION_NAME);
|
||||
g_ptr_array_add (used_extensions, (gpointer) GDK_DISPLAY_GET_CLASS (display)->vk_extension_name);
|
||||
|
||||
for (i = 0; i < n_extensions; i++)
|
||||
{
|
||||
@@ -1118,7 +1122,7 @@ gdk_display_create_vulkan_instance (GdkDisplay *display,
|
||||
if (have_debug_report)
|
||||
{
|
||||
PFN_vkCreateDebugReportCallbackEXT vkCreateDebugReportCallbackEXT;
|
||||
|
||||
|
||||
vkCreateDebugReportCallbackEXT = (PFN_vkCreateDebugReportCallbackEXT) vkGetInstanceProcAddr (display->vk_instance, "vkCreateDebugReportCallbackEXT" );
|
||||
GDK_VK_CHECK (vkCreateDebugReportCallbackEXT, display->vk_instance,
|
||||
&(VkDebugReportCallbackCreateInfoEXT) {
|
||||
@@ -1167,7 +1171,7 @@ gdk_display_ref_vulkan (GdkDisplay *display,
|
||||
}
|
||||
|
||||
display->vulkan_refcount++;
|
||||
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -1180,7 +1184,7 @@ gdk_display_unref_vulkan (GdkDisplay *display)
|
||||
display->vulkan_refcount--;
|
||||
if (display->vulkan_refcount > 0)
|
||||
return;
|
||||
|
||||
|
||||
vkDestroyDevice (display->vk_device, NULL);
|
||||
display->vk_device = VK_NULL_HANDLE;
|
||||
if (display->vk_debug_callback != VK_NULL_HANDLE)
|
||||
|
||||
@@ -27,10 +27,12 @@
|
||||
#import "GdkMacosView.h"
|
||||
#import "GdkMacosWindow.h"
|
||||
|
||||
#include "gdkmacosclipboard-private.h"
|
||||
#include "gdkmacosdisplay-private.h"
|
||||
#include "gdkmacosdrag-private.h"
|
||||
#include "gdkmacosdrop-private.h"
|
||||
#include "gdkmacoseventsource-private.h"
|
||||
#include "gdkmacosmonitor-private.h"
|
||||
#include "gdkmacospasteboard-private.h"
|
||||
#include "gdkmacossurface-private.h"
|
||||
#include "gdkmacospopupsurface-private.h"
|
||||
#include "gdkmacostoplevelsurface-private.h"
|
||||
@@ -144,7 +146,7 @@ typedef NSString *CALayerContentsGravity;
|
||||
*
|
||||
* TODO: Can we improve grab breaking to fix this?
|
||||
*/
|
||||
_gdk_macos_display_send_button_event ([self gdkDisplay], event);
|
||||
_gdk_macos_display_send_event ([self gdkDisplay], event);
|
||||
|
||||
_gdk_macos_display_break_all_grabs (GDK_MACOS_DISPLAY (display), time);
|
||||
|
||||
@@ -246,7 +248,7 @@ typedef NSString *CALayerContentsGravity;
|
||||
[view release];
|
||||
|
||||
/* TODO: We might want to make this more extensible at some point */
|
||||
_gdk_macos_clipboard_register_drag_types (self);
|
||||
_gdk_macos_pasteboard_register_drag_types (self);
|
||||
|
||||
return self;
|
||||
}
|
||||
@@ -576,6 +578,8 @@ typedef NSString *CALayerContentsGravity;
|
||||
initialResizeLocation = convert_nspoint_to_screen (self, [self mouseLocationOutsideOfEventStream]);
|
||||
}
|
||||
|
||||
// NSDraggingDestination protocol
|
||||
|
||||
-(NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
|
||||
{
|
||||
NSPoint location = [sender draggingLocation];
|
||||
@@ -665,10 +669,64 @@ typedef NSString *CALayerContentsGravity;
|
||||
return NO;
|
||||
}
|
||||
|
||||
-(void)draggedImage:(NSImage *)anImage endedAt:(NSPoint)aPoint operation:(NSDragOperation)operation
|
||||
// NSDraggingSource protocol
|
||||
|
||||
- (NSDragOperation)draggingSession:(NSDraggingSession *)session sourceOperationMaskForDraggingContext:(NSDraggingContext)context
|
||||
{
|
||||
NSInteger sequence_number = [session draggingSequenceNumber];
|
||||
GdkDisplay *display = gdk_surface_get_display (GDK_SURFACE (gdk_surface));
|
||||
GdkDrag *drag = _gdk_macos_display_find_drag (GDK_MACOS_DISPLAY (display), sequence_number);
|
||||
GdkModifierType state = _gdk_macos_display_get_current_keyboard_modifiers (GDK_MACOS_DISPLAY (display));
|
||||
|
||||
_gdk_macos_drag_set_actions (GDK_MACOS_DRAG (drag), state);
|
||||
|
||||
return _gdk_macos_drag_operation (GDK_MACOS_DRAG (drag));
|
||||
}
|
||||
|
||||
- (void)draggingSession:(NSDraggingSession *)session willBeginAtPoint:(NSPoint)screenPoint
|
||||
{
|
||||
NSInteger sequence_number = [session draggingSequenceNumber];
|
||||
GdkDisplay *display = gdk_surface_get_display (GDK_SURFACE (gdk_surface));
|
||||
GdkDrag *drag = _gdk_macos_display_find_drag (GDK_MACOS_DISPLAY (display), sequence_number);
|
||||
int x, y;
|
||||
|
||||
_gdk_macos_display_from_display_coords (GDK_MACOS_DISPLAY (display), screenPoint.x, screenPoint.y, &x, &y);
|
||||
_gdk_macos_drag_set_start_position (GDK_MACOS_DRAG (drag), x, y);
|
||||
_gdk_macos_drag_surface_move (GDK_MACOS_DRAG (drag), x, y);
|
||||
}
|
||||
|
||||
- (void)draggingSession:(NSDraggingSession *)session movedToPoint:(NSPoint)screenPoint
|
||||
{
|
||||
NSInteger sequence_number = [session draggingSequenceNumber];
|
||||
GdkMacosDisplay *display = GDK_MACOS_DISPLAY (gdk_surface_get_display (GDK_SURFACE (gdk_surface)));
|
||||
GdkDrag *drag = _gdk_macos_display_find_drag (GDK_MACOS_DISPLAY (display), sequence_number);
|
||||
int x, y;
|
||||
|
||||
_gdk_macos_display_send_event (display, [NSApp currentEvent]);
|
||||
|
||||
_gdk_macos_display_from_display_coords (display, screenPoint.x, screenPoint.y, &x, &y);
|
||||
_gdk_macos_drag_surface_move (GDK_MACOS_DRAG (drag), x, y);
|
||||
}
|
||||
|
||||
- (void)draggingSession:(NSDraggingSession *)session endedAtPoint:(NSPoint)screenPoint operation:(NSDragOperation)operation
|
||||
{
|
||||
NSInteger sequence_number = [session draggingSequenceNumber];
|
||||
GdkMacosDisplay *display = GDK_MACOS_DISPLAY (gdk_surface_get_display (GDK_SURFACE (gdk_surface)));
|
||||
GdkDrag *drag = _gdk_macos_display_find_drag (display, sequence_number);
|
||||
|
||||
_gdk_macos_display_send_event (display, [NSApp currentEvent]);
|
||||
gdk_drag_set_selected_action (drag, _gdk_macos_drag_ns_operation_to_action (operation));
|
||||
|
||||
if (gdk_drag_get_selected_action (drag) != 0)
|
||||
g_signal_emit_by_name (drag, "drop-performed");
|
||||
else
|
||||
gdk_drag_cancel (drag, GDK_DRAG_CANCEL_NO_TARGET);
|
||||
|
||||
_gdk_macos_display_set_drag (display, [session draggingSequenceNumber], NULL);
|
||||
}
|
||||
|
||||
// end
|
||||
|
||||
-(void)setStyleMask:(NSWindowStyleMask)styleMask
|
||||
{
|
||||
gboolean was_fullscreen;
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
|
||||
#define GDK_IS_MACOS_WINDOW(obj) ([obj isKindOfClass:[GdkMacosWindow class]])
|
||||
|
||||
@interface GdkMacosWindow : NSWindow {
|
||||
@interface GdkMacosWindow : NSWindow <NSDraggingSource, NSDraggingDestination> {
|
||||
GdkMacosSurface *gdk_surface;
|
||||
|
||||
BOOL inMove;
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
#include "gdkclipboardprivate.h"
|
||||
#include "gdkmacosdisplay-private.h"
|
||||
#include "gdkmacospasteboard-private.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@@ -41,30 +42,6 @@ NSPasteboardType _gdk_macos_clipboard_to_ns_type (const char
|
||||
NSPasteboardType *alternate);
|
||||
const char *_gdk_macos_clipboard_from_ns_type (NSPasteboardType ns_type);
|
||||
void _gdk_macos_clipboard_register_drag_types (NSWindow *window);
|
||||
GdkContentFormats *_gdk_macos_pasteboard_load_formats (NSPasteboard *pasteboard);
|
||||
void _gdk_macos_pasteboard_read_async (GObject *object,
|
||||
NSPasteboard *pasteboard,
|
||||
GdkContentFormats *formats,
|
||||
int io_priority,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
GInputStream *_gdk_macos_pasteboard_read_finish (GObject *object,
|
||||
GAsyncResult *result,
|
||||
const char **out_mime_type,
|
||||
GError **error);
|
||||
|
||||
@interface GdkMacosClipboardDataProvider : NSObject <NSPasteboardItemDataProvider>
|
||||
{
|
||||
GCancellable *cancellable;
|
||||
GdkClipboard *clipboard;
|
||||
char **mimeTypes;
|
||||
}
|
||||
|
||||
-(id)initClipboard:(GdkClipboard *)gdkClipboard mimetypes:(const char * const *)mime_types;
|
||||
-(NSArray<NSPasteboardType> *)types;
|
||||
|
||||
@end
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
+15
-488
@@ -22,6 +22,7 @@
|
||||
#include <glib/gi18n.h>
|
||||
|
||||
#include "gdkmacosclipboard-private.h"
|
||||
#include "gdkmacospasteboard-private.h"
|
||||
#include "gdkmacosutils-private.h"
|
||||
#include "gdkprivate.h"
|
||||
|
||||
@@ -32,163 +33,8 @@ struct _GdkMacosClipboard
|
||||
NSInteger last_change_count;
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GMemoryOutputStream *stream;
|
||||
NSPasteboardItem *item;
|
||||
NSPasteboardType type;
|
||||
GMainContext *main_context;
|
||||
guint done : 1;
|
||||
} WriteRequest;
|
||||
|
||||
enum {
|
||||
TYPE_STRING,
|
||||
TYPE_PBOARD,
|
||||
TYPE_URL,
|
||||
TYPE_FILE_URL,
|
||||
TYPE_COLOR,
|
||||
TYPE_TIFF,
|
||||
TYPE_PNG,
|
||||
TYPE_LAST
|
||||
};
|
||||
|
||||
#define PTYPE(k) (get_pasteboard_type(TYPE_##k))
|
||||
|
||||
static NSPasteboardType pasteboard_types[TYPE_LAST];
|
||||
|
||||
G_DEFINE_TYPE (GdkMacosClipboard, _gdk_macos_clipboard, GDK_TYPE_CLIPBOARD)
|
||||
|
||||
static NSPasteboardType
|
||||
get_pasteboard_type (int type)
|
||||
{
|
||||
static gsize initialized = FALSE;
|
||||
|
||||
g_assert (type >= 0);
|
||||
g_assert (type < TYPE_LAST);
|
||||
|
||||
if (g_once_init_enter (&initialized))
|
||||
{
|
||||
pasteboard_types[TYPE_PNG] = NSPasteboardTypePNG;
|
||||
pasteboard_types[TYPE_STRING] = NSPasteboardTypeString;
|
||||
pasteboard_types[TYPE_TIFF] = NSPasteboardTypeTIFF;
|
||||
pasteboard_types[TYPE_COLOR] = NSPasteboardTypeColor;
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
pasteboard_types[TYPE_PBOARD] = NSStringPboardType;
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
|
||||
#ifdef AVAILABLE_MAC_OS_X_VERSION_10_13_AND_LATER
|
||||
pasteboard_types[TYPE_URL] = NSPasteboardTypeURL;
|
||||
pasteboard_types[TYPE_FILE_URL] = NSPasteboardTypeFileURL;
|
||||
#else
|
||||
pasteboard_types[TYPE_URL] = [[NSString alloc] initWithUTF8String:"public.url"];
|
||||
pasteboard_types[TYPE_FILE_URL] = [[NSString alloc] initWithUTF8String:"public.file-url"];
|
||||
#endif
|
||||
|
||||
g_once_init_leave (&initialized, TRUE);
|
||||
}
|
||||
|
||||
return pasteboard_types[type];
|
||||
}
|
||||
|
||||
static void
|
||||
write_request_free (WriteRequest *wr)
|
||||
{
|
||||
g_clear_pointer (&wr->main_context, g_main_context_unref);
|
||||
g_clear_object (&wr->stream);
|
||||
[wr->item release];
|
||||
g_slice_free (WriteRequest, wr);
|
||||
}
|
||||
|
||||
const char *
|
||||
_gdk_macos_clipboard_from_ns_type (NSPasteboardType type)
|
||||
{
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
|
||||
|
||||
if ([type isEqualToString:PTYPE(STRING)] ||
|
||||
[type isEqualToString:PTYPE(PBOARD)])
|
||||
return g_intern_string ("text/plain;charset=utf-8");
|
||||
else if ([type isEqualToString:PTYPE(URL)] ||
|
||||
[type isEqualToString:PTYPE(FILE_URL)])
|
||||
return g_intern_string ("text/uri-list");
|
||||
else if ([type isEqualToString:PTYPE(COLOR)])
|
||||
return g_intern_string ("application/x-color");
|
||||
else if ([type isEqualToString:PTYPE(TIFF)])
|
||||
return g_intern_string ("image/tiff");
|
||||
else if ([type isEqualToString:PTYPE(PNG)])
|
||||
return g_intern_string ("image/png");
|
||||
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
NSPasteboardType
|
||||
_gdk_macos_clipboard_to_ns_type (const char *mime_type,
|
||||
NSPasteboardType *alternate)
|
||||
{
|
||||
if (alternate)
|
||||
*alternate = NULL;
|
||||
|
||||
if (g_strcmp0 (mime_type, "text/plain;charset=utf-8") == 0)
|
||||
{
|
||||
return PTYPE(STRING);
|
||||
}
|
||||
else if (g_strcmp0 (mime_type, "text/uri-list") == 0)
|
||||
{
|
||||
if (alternate)
|
||||
*alternate = PTYPE(URL);
|
||||
return PTYPE(FILE_URL);
|
||||
}
|
||||
else if (g_strcmp0 (mime_type, "application/x-color") == 0)
|
||||
{
|
||||
return PTYPE(COLOR);
|
||||
}
|
||||
else if (g_strcmp0 (mime_type, "image/tiff") == 0)
|
||||
{
|
||||
return PTYPE(TIFF);
|
||||
}
|
||||
else if (g_strcmp0 (mime_type, "image/png") == 0)
|
||||
{
|
||||
return PTYPE(PNG);
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
static void
|
||||
populate_content_formats (GdkContentFormatsBuilder *builder,
|
||||
NSPasteboardType type)
|
||||
{
|
||||
const char *mime_type;
|
||||
|
||||
g_return_if_fail (builder != NULL);
|
||||
g_return_if_fail (type != NULL);
|
||||
|
||||
mime_type = _gdk_macos_clipboard_from_ns_type (type);
|
||||
|
||||
if (mime_type != NULL)
|
||||
gdk_content_formats_builder_add_mime_type (builder, mime_type);
|
||||
}
|
||||
|
||||
static GdkContentFormats *
|
||||
load_offer_formats (NSPasteboard *pasteboard)
|
||||
{
|
||||
GDK_BEGIN_MACOS_ALLOC_POOL;
|
||||
|
||||
GdkContentFormatsBuilder *builder;
|
||||
GdkContentFormats *formats;
|
||||
|
||||
builder = gdk_content_formats_builder_new ();
|
||||
for (NSPasteboardType type in [pasteboard types])
|
||||
populate_content_formats (builder, type);
|
||||
formats = gdk_content_formats_builder_free_to_formats (builder);
|
||||
|
||||
GDK_END_MACOS_ALLOC_POOL;
|
||||
|
||||
return g_steal_pointer (&formats);
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_macos_clipboard_load_contents (GdkMacosClipboard *self)
|
||||
{
|
||||
@@ -199,22 +45,13 @@ _gdk_macos_clipboard_load_contents (GdkMacosClipboard *self)
|
||||
|
||||
change_count = [self->pasteboard changeCount];
|
||||
|
||||
formats = load_offer_formats (self->pasteboard);
|
||||
formats = _gdk_macos_pasteboard_load_formats (self->pasteboard);
|
||||
gdk_clipboard_claim_remote (GDK_CLIPBOARD (self), formats);
|
||||
gdk_content_formats_unref (formats);
|
||||
|
||||
self->last_change_count = change_count;
|
||||
}
|
||||
|
||||
static GInputStream *
|
||||
create_stream_from_nsdata (NSData *data)
|
||||
{
|
||||
const guint8 *bytes = [data bytes];
|
||||
gsize len = [data length];
|
||||
|
||||
return g_memory_input_stream_new_from_data (g_memdup2 (bytes, len), len, g_free);
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_macos_clipboard_read_async (GdkClipboard *clipboard,
|
||||
GdkContentFormats *formats,
|
||||
@@ -245,34 +82,26 @@ static void
|
||||
_gdk_macos_clipboard_send_to_pasteboard (GdkMacosClipboard *self,
|
||||
GdkContentProvider *content)
|
||||
{
|
||||
GdkMacosPasteboardItem *item;
|
||||
NSArray<NSPasteboardItem *> *items;
|
||||
|
||||
g_assert (GDK_IS_MACOS_CLIPBOARD (self));
|
||||
g_assert (GDK_IS_CONTENT_PROVIDER (content));
|
||||
|
||||
if (self->pasteboard == NULL)
|
||||
return;
|
||||
|
||||
GDK_BEGIN_MACOS_ALLOC_POOL;
|
||||
|
||||
GdkMacosClipboardDataProvider *dataProvider;
|
||||
GdkContentFormats *serializable;
|
||||
NSPasteboardItem *item;
|
||||
const char * const *mime_types;
|
||||
gsize n_mime_types;
|
||||
|
||||
g_return_if_fail (GDK_IS_MACOS_CLIPBOARD (self));
|
||||
g_return_if_fail (GDK_IS_CONTENT_PROVIDER (content));
|
||||
|
||||
serializable = gdk_content_provider_ref_storable_formats (content);
|
||||
serializable = gdk_content_formats_union_serialize_mime_types (serializable);
|
||||
mime_types = gdk_content_formats_get_mime_types (serializable, &n_mime_types);
|
||||
|
||||
dataProvider = [[GdkMacosClipboardDataProvider alloc] initClipboard:GDK_CLIPBOARD (self)
|
||||
mimetypes:mime_types];
|
||||
item = [[NSPasteboardItem alloc] init];
|
||||
[item setDataProvider:dataProvider forTypes:[dataProvider types]];
|
||||
item = [[GdkMacosPasteboardItem alloc] initForClipboard:GDK_CLIPBOARD (self) withContentProvider:content];
|
||||
items = [NSArray arrayWithObject:item];
|
||||
|
||||
[self->pasteboard clearContents];
|
||||
if ([self->pasteboard writeObjects:[NSArray arrayWithObject:item]] == NO)
|
||||
g_warning ("Failed to write object to pasteboard");
|
||||
if ([self->pasteboard writeObjects:items] == NO)
|
||||
g_warning ("Failed to send clipboard to pasteboard");
|
||||
|
||||
self->last_change_count = [self->pasteboard changeCount];
|
||||
|
||||
g_clear_pointer (&serializable, gdk_content_formats_unref);
|
||||
|
||||
GDK_END_MACOS_ALLOC_POOL;
|
||||
}
|
||||
|
||||
@@ -365,305 +194,3 @@ _gdk_macos_clipboard_check_externally_modified (GdkMacosClipboard *self)
|
||||
if ([self->pasteboard changeCount] != self->last_change_count)
|
||||
_gdk_macos_clipboard_load_contents (self);
|
||||
}
|
||||
|
||||
@implementation GdkMacosClipboardDataProvider
|
||||
|
||||
-(id)initClipboard:(GdkClipboard *)gdkClipboard mimetypes:(const char * const *)mime_types;
|
||||
{
|
||||
[super init];
|
||||
|
||||
self->mimeTypes = g_strdupv ((char **)mime_types);
|
||||
self->clipboard = g_object_ref (gdkClipboard);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
-(void)dealloc
|
||||
{
|
||||
g_cancellable_cancel (self->cancellable);
|
||||
|
||||
g_clear_pointer (&self->mimeTypes, g_strfreev);
|
||||
g_clear_object (&self->clipboard);
|
||||
g_clear_object (&self->cancellable);
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
-(void)pasteboardFinishedWithDataProvider:(NSPasteboard *)pasteboard
|
||||
{
|
||||
g_clear_object (&self->clipboard);
|
||||
}
|
||||
|
||||
-(NSArray<NSPasteboardType> *)types
|
||||
{
|
||||
NSMutableArray *ret = [[NSMutableArray alloc] init];
|
||||
|
||||
for (guint i = 0; self->mimeTypes[i]; i++)
|
||||
{
|
||||
const char *mime_type = self->mimeTypes[i];
|
||||
NSPasteboardType type;
|
||||
NSPasteboardType alternate = nil;
|
||||
|
||||
if ((type = _gdk_macos_clipboard_to_ns_type (mime_type, &alternate)))
|
||||
{
|
||||
[ret addObject:type];
|
||||
if (alternate)
|
||||
[ret addObject:alternate];
|
||||
}
|
||||
}
|
||||
|
||||
return g_steal_pointer (&ret);
|
||||
}
|
||||
|
||||
static void
|
||||
on_data_ready_cb (GObject *object,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
GDK_BEGIN_MACOS_ALLOC_POOL;
|
||||
|
||||
GdkClipboard *clipboard = (GdkClipboard *)object;
|
||||
WriteRequest *wr = user_data;
|
||||
GError *error = NULL;
|
||||
NSData *data = nil;
|
||||
|
||||
g_assert (GDK_IS_CLIPBOARD (clipboard));
|
||||
g_assert (G_IS_ASYNC_RESULT (result));
|
||||
g_assert (wr != NULL);
|
||||
g_assert (G_IS_MEMORY_OUTPUT_STREAM (wr->stream));
|
||||
g_assert ([wr->item isKindOfClass:[NSPasteboardItem class]]);
|
||||
|
||||
if (gdk_clipboard_write_finish (clipboard, result, &error))
|
||||
{
|
||||
gsize size;
|
||||
gpointer bytes;
|
||||
|
||||
g_output_stream_close (G_OUTPUT_STREAM (wr->stream), NULL, NULL);
|
||||
|
||||
size = g_memory_output_stream_get_data_size (wr->stream);
|
||||
bytes = g_memory_output_stream_steal_data (wr->stream);
|
||||
data = [[NSData alloc] initWithBytesNoCopy:bytes
|
||||
length:size
|
||||
deallocator:^(void *alloc, NSUInteger length) { g_free (alloc); }];
|
||||
}
|
||||
else
|
||||
{
|
||||
g_warning ("Failed to serialize clipboard contents: %s",
|
||||
error->message);
|
||||
g_clear_error (&error);
|
||||
}
|
||||
|
||||
[wr->item setData:data forType:wr->type];
|
||||
|
||||
wr->done = TRUE;
|
||||
|
||||
GDK_END_MACOS_ALLOC_POOL;
|
||||
}
|
||||
|
||||
-(void) pasteboard:(NSPasteboard *)pasteboard
|
||||
item:(NSPasteboardItem *)item
|
||||
provideDataForType:(NSPasteboardType)type
|
||||
{
|
||||
const char *mime_type = _gdk_macos_clipboard_from_ns_type (type);
|
||||
GMainContext *main_context = g_main_context_default ();
|
||||
WriteRequest *wr;
|
||||
|
||||
if (self->clipboard == NULL || mime_type == NULL)
|
||||
{
|
||||
[item setData:[NSData data] forType:type];
|
||||
return;
|
||||
}
|
||||
|
||||
wr = g_slice_new0 (WriteRequest);
|
||||
wr->item = [item retain];
|
||||
wr->stream = G_MEMORY_OUTPUT_STREAM (g_memory_output_stream_new_resizable ());
|
||||
wr->type = type;
|
||||
wr->main_context = g_main_context_ref (main_context);
|
||||
wr->done = FALSE;
|
||||
|
||||
gdk_clipboard_write_async (self->clipboard,
|
||||
mime_type,
|
||||
G_OUTPUT_STREAM (wr->stream),
|
||||
G_PRIORITY_DEFAULT,
|
||||
self->cancellable,
|
||||
on_data_ready_cb,
|
||||
wr);
|
||||
|
||||
/* We're forced to provide data synchronously via this API
|
||||
* so we must block on the main loop. Using another main loop
|
||||
* than the default tends to get us locked up here, so that is
|
||||
* what we'll do for now.
|
||||
*/
|
||||
while (!wr->done)
|
||||
g_main_context_iteration (wr->main_context, TRUE);
|
||||
|
||||
write_request_free (wr);
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_macos_clipboard_register_drag_types (NSWindow *window)
|
||||
{
|
||||
[window registerForDraggedTypes:[NSArray arrayWithObjects:PTYPE(STRING),
|
||||
PTYPE(PBOARD),
|
||||
PTYPE(URL),
|
||||
PTYPE(FILE_URL),
|
||||
PTYPE(COLOR),
|
||||
PTYPE(TIFF),
|
||||
PTYPE(PNG),
|
||||
nil]];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
GdkContentFormats *
|
||||
_gdk_macos_pasteboard_load_formats (NSPasteboard *pasteboard)
|
||||
{
|
||||
return load_offer_formats (pasteboard);
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_macos_pasteboard_read_async (GObject *object,
|
||||
NSPasteboard *pasteboard,
|
||||
GdkContentFormats *formats,
|
||||
int io_priority,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
GDK_BEGIN_MACOS_ALLOC_POOL;
|
||||
|
||||
GdkContentFormats *offer_formats = NULL;
|
||||
const char *mime_type;
|
||||
GInputStream *stream = NULL;
|
||||
GTask *task = NULL;
|
||||
|
||||
g_assert (G_IS_OBJECT (object));
|
||||
g_assert (pasteboard != NULL);
|
||||
g_assert (formats != NULL);
|
||||
|
||||
task = g_task_new (object, cancellable, callback, user_data);
|
||||
g_task_set_source_tag (task, _gdk_macos_pasteboard_read_async);
|
||||
g_task_set_priority (task, io_priority);
|
||||
|
||||
offer_formats = load_offer_formats (pasteboard);
|
||||
mime_type = gdk_content_formats_match_mime_type (formats, offer_formats);
|
||||
|
||||
if (mime_type == NULL)
|
||||
{
|
||||
g_task_return_new_error (task,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_NOT_SUPPORTED,
|
||||
"%s",
|
||||
_("No compatible transfer format found"));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (strcmp (mime_type, "text/plain;charset=utf-8") == 0)
|
||||
{
|
||||
NSString *nsstr = [pasteboard stringForType:NSPasteboardTypeString];
|
||||
|
||||
if (nsstr != NULL)
|
||||
{
|
||||
const char *str = [nsstr UTF8String];
|
||||
stream = g_memory_input_stream_new_from_data (g_strdup (str),
|
||||
strlen (str) + 1,
|
||||
g_free);
|
||||
}
|
||||
}
|
||||
else if (strcmp (mime_type, "text/uri-list") == 0)
|
||||
{
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
|
||||
|
||||
if ([[pasteboard types] containsObject:PTYPE(FILE_URL)])
|
||||
{
|
||||
GString *str = g_string_new (NULL);
|
||||
NSArray *files = [pasteboard propertyListForType:NSFilenamesPboardType];
|
||||
gsize n_files = [files count];
|
||||
char *data;
|
||||
guint len;
|
||||
|
||||
for (gsize i = 0; i < n_files; ++i)
|
||||
{
|
||||
NSString* uriString = [files objectAtIndex:i];
|
||||
uriString = [@"file://" stringByAppendingString:uriString];
|
||||
uriString = [uriString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
|
||||
|
||||
g_string_append_printf (str,
|
||||
"%s\r\n",
|
||||
[uriString cStringUsingEncoding:NSUTF8StringEncoding]);
|
||||
}
|
||||
|
||||
len = str->len;
|
||||
data = g_string_free (str, FALSE);
|
||||
stream = g_memory_input_stream_new_from_data (data, len, g_free);
|
||||
}
|
||||
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS;
|
||||
}
|
||||
else if (strcmp (mime_type, "application/x-color") == 0)
|
||||
{
|
||||
NSColorSpace *colorspace;
|
||||
NSColor *nscolor;
|
||||
guint16 color[4];
|
||||
|
||||
colorspace = [NSColorSpace genericRGBColorSpace];
|
||||
nscolor = [[NSColor colorFromPasteboard:pasteboard]
|
||||
colorUsingColorSpace:colorspace];
|
||||
|
||||
color[0] = 0xffff * [nscolor redComponent];
|
||||
color[1] = 0xffff * [nscolor greenComponent];
|
||||
color[2] = 0xffff * [nscolor blueComponent];
|
||||
color[3] = 0xffff * [nscolor alphaComponent];
|
||||
|
||||
stream = g_memory_input_stream_new_from_data (g_memdup2 (&color, sizeof color),
|
||||
sizeof color,
|
||||
g_free);
|
||||
}
|
||||
else if (strcmp (mime_type, "image/tiff") == 0)
|
||||
{
|
||||
NSData *data = [pasteboard dataForType:PTYPE(TIFF)];
|
||||
stream = create_stream_from_nsdata (data);
|
||||
}
|
||||
else if (strcmp (mime_type, "image/png") == 0)
|
||||
{
|
||||
NSData *data = [pasteboard dataForType:PTYPE(PNG)];
|
||||
stream = create_stream_from_nsdata (data);
|
||||
}
|
||||
|
||||
if (stream != NULL)
|
||||
{
|
||||
g_task_set_task_data (task, g_strdup (mime_type), g_free);
|
||||
g_task_return_pointer (task, g_steal_pointer (&stream), g_object_unref);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_task_return_new_error (task,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_FAILED,
|
||||
_("Failed to decode contents with mime-type of '%s'"),
|
||||
mime_type);
|
||||
}
|
||||
|
||||
cleanup:
|
||||
g_clear_object (&task);
|
||||
g_clear_pointer (&offer_formats, gdk_content_formats_unref);
|
||||
|
||||
GDK_END_MACOS_ALLOC_POOL;
|
||||
}
|
||||
|
||||
GInputStream *
|
||||
_gdk_macos_pasteboard_read_finish (GObject *object,
|
||||
GAsyncResult *result,
|
||||
const char **out_mime_type,
|
||||
GError **error)
|
||||
{
|
||||
GTask *task = (GTask *)result;
|
||||
|
||||
g_assert (G_IS_OBJECT (object));
|
||||
g_assert (G_IS_TASK (task));
|
||||
|
||||
if (out_mime_type != NULL)
|
||||
*out_mime_type = g_strdup (g_task_get_task_data (task));
|
||||
|
||||
return g_task_propagate_pointer (task, error);
|
||||
}
|
||||
|
||||
@@ -23,6 +23,10 @@
|
||||
|
||||
#include "gdkmacoscursor-private.h"
|
||||
|
||||
@interface NSCursor()
|
||||
-(long long)_coreCursorType;
|
||||
@end
|
||||
|
||||
/* OS X only exports a number of cursor types in its public NSCursor interface.
|
||||
* By overriding the private _coreCursorType method, we can tell OS X to load
|
||||
* one of its internal cursors instead (since cursor images are loaded on demand
|
||||
|
||||
@@ -155,12 +155,13 @@ void _gdk_macos_display_surface_became_key (GdkMacosDisp
|
||||
GdkMacosSurface *surface);
|
||||
void _gdk_macos_display_clear_sorting (GdkMacosDisplay *self);
|
||||
const GList *_gdk_macos_display_get_surfaces (GdkMacosDisplay *self);
|
||||
void _gdk_macos_display_send_button_event (GdkMacosDisplay *self,
|
||||
void _gdk_macos_display_send_event (GdkMacosDisplay *self,
|
||||
NSEvent *nsevent);
|
||||
void _gdk_macos_display_warp_pointer (GdkMacosDisplay *self,
|
||||
int x,
|
||||
int y);
|
||||
NSEvent *_gdk_macos_display_get_nsevent (GdkEvent *event);
|
||||
NSEvent *_gdk_macos_display_get_last_nsevent (void);
|
||||
GdkDrag *_gdk_macos_display_find_drag (GdkMacosDisplay *self,
|
||||
NSInteger sequence_number);
|
||||
GdkDrop *_gdk_macos_display_find_drop (GdkMacosDisplay *self,
|
||||
|
||||
@@ -723,6 +723,85 @@ fill_scroll_event (GdkMacosDisplay *self,
|
||||
return g_steal_pointer (&ret);
|
||||
}
|
||||
|
||||
|
||||
static GdkEvent *
|
||||
fill_event (GdkMacosDisplay *self,
|
||||
GdkMacosWindow *window,
|
||||
NSEvent *nsevent,
|
||||
int x,
|
||||
int y)
|
||||
{
|
||||
GdkMacosSurface *surface = [window gdkSurface];
|
||||
NSEventType event_type = [nsevent type];
|
||||
GdkEvent *ret = NULL;
|
||||
|
||||
switch ((int)event_type)
|
||||
{
|
||||
case NSEventTypeLeftMouseDown:
|
||||
case NSEventTypeRightMouseDown:
|
||||
case NSEventTypeOtherMouseDown:
|
||||
case NSEventTypeLeftMouseUp:
|
||||
case NSEventTypeRightMouseUp:
|
||||
case NSEventTypeOtherMouseUp:
|
||||
ret = fill_button_event (self, surface, nsevent, x, y);
|
||||
break;
|
||||
|
||||
case NSEventTypeLeftMouseDragged:
|
||||
case NSEventTypeRightMouseDragged:
|
||||
case NSEventTypeOtherMouseDragged:
|
||||
case NSEventTypeMouseMoved:
|
||||
ret = fill_motion_event (self, surface, nsevent, x, y);
|
||||
break;
|
||||
|
||||
case NSEventTypeMagnify:
|
||||
case NSEventTypeRotate:
|
||||
ret = fill_pinch_event (self, surface, nsevent, x, y);
|
||||
break;
|
||||
|
||||
case NSEventTypeMouseExited:
|
||||
case NSEventTypeMouseEntered:
|
||||
{
|
||||
GdkSeat *seat = gdk_display_get_default_seat (GDK_DISPLAY (self));
|
||||
GdkDevice *pointer = gdk_seat_get_pointer (seat);
|
||||
GdkDeviceGrabInfo *grab = _gdk_display_get_last_device_grab (GDK_DISPLAY (self), pointer);
|
||||
|
||||
if ([(GdkMacosWindow *)window isInManualResizeOrMove])
|
||||
{
|
||||
ret = GDK_MACOS_EVENT_DROP;
|
||||
}
|
||||
else if (grab == NULL || grab->owner_events)
|
||||
{
|
||||
if (event_type == NSEventTypeMouseExited)
|
||||
[[NSCursor arrowCursor] set];
|
||||
|
||||
ret = synthesize_crossing_event (self, surface, nsevent, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case NSEventTypeKeyDown:
|
||||
case NSEventTypeKeyUp:
|
||||
case NSEventTypeFlagsChanged: {
|
||||
GdkEventType type = _gdk_macos_keymap_get_event_type (nsevent);
|
||||
|
||||
if (type)
|
||||
ret = fill_key_event (self, surface, nsevent, type);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case NSEventTypeScrollWheel:
|
||||
ret = fill_scroll_event (self, surface, nsevent, x, y);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_mouse_button_press_event (NSEventType type)
|
||||
{
|
||||
@@ -760,16 +839,9 @@ find_surface_under_pointer (GdkMacosDisplay *self,
|
||||
int *x,
|
||||
int *y)
|
||||
{
|
||||
GdkPointerSurfaceInfo *info;
|
||||
GdkMacosSurface *surface;
|
||||
GdkDevice *pointer;
|
||||
GdkSeat *seat;
|
||||
int x_tmp, y_tmp;
|
||||
|
||||
seat = gdk_display_get_default_seat (GDK_DISPLAY (self));
|
||||
pointer = gdk_seat_get_pointer (seat);
|
||||
info = _gdk_display_get_pointer_info (GDK_DISPLAY (self), pointer);
|
||||
|
||||
surface = _gdk_macos_display_get_surface_at_display_coords (self,
|
||||
screen_point.x,
|
||||
screen_point.y,
|
||||
@@ -1032,16 +1104,12 @@ find_surface_for_ns_event (GdkMacosDisplay *self,
|
||||
GdkMacosBaseView *view;
|
||||
GdkSurface *surface;
|
||||
NSPoint point;
|
||||
int x_tmp;
|
||||
int y_tmp;
|
||||
|
||||
g_assert (GDK_IS_MACOS_DISPLAY (self));
|
||||
g_assert (nsevent != NULL);
|
||||
g_assert (x != NULL);
|
||||
g_assert (y != NULL);
|
||||
|
||||
_gdk_macos_display_from_display_coords (self, point.x, point.y, &x_tmp, &y_tmp);
|
||||
|
||||
switch ((int)[nsevent type])
|
||||
{
|
||||
case NSEventTypeLeftMouseDown:
|
||||
@@ -1090,7 +1158,6 @@ _gdk_macos_display_translate (GdkMacosDisplay *self,
|
||||
GdkMacosWindow *window;
|
||||
NSEventType event_type;
|
||||
NSWindow *event_window;
|
||||
GdkEvent *ret = NULL;
|
||||
int x;
|
||||
int y;
|
||||
|
||||
@@ -1198,79 +1265,15 @@ _gdk_macos_display_translate (GdkMacosDisplay *self,
|
||||
_gdk_macos_display_clear_sorting (self);
|
||||
}
|
||||
}
|
||||
|
||||
switch ((int)event_type)
|
||||
{
|
||||
case NSEventTypeLeftMouseDown:
|
||||
case NSEventTypeRightMouseDown:
|
||||
case NSEventTypeOtherMouseDown:
|
||||
case NSEventTypeLeftMouseUp:
|
||||
case NSEventTypeRightMouseUp:
|
||||
case NSEventTypeOtherMouseUp:
|
||||
ret = fill_button_event (self, surface, nsevent, x, y);
|
||||
break;
|
||||
|
||||
case NSEventTypeLeftMouseDragged:
|
||||
case NSEventTypeRightMouseDragged:
|
||||
case NSEventTypeOtherMouseDragged:
|
||||
case NSEventTypeMouseMoved:
|
||||
ret = fill_motion_event (self, surface, nsevent, x, y);
|
||||
break;
|
||||
|
||||
case NSEventTypeMagnify:
|
||||
case NSEventTypeRotate:
|
||||
ret = fill_pinch_event (self, surface, nsevent, x, y);
|
||||
break;
|
||||
|
||||
case NSEventTypeMouseExited:
|
||||
case NSEventTypeMouseEntered:
|
||||
{
|
||||
GdkSeat *seat = gdk_display_get_default_seat (GDK_DISPLAY (self));
|
||||
GdkDevice *pointer = gdk_seat_get_pointer (seat);
|
||||
GdkDeviceGrabInfo *grab = _gdk_display_get_last_device_grab (GDK_DISPLAY (self), pointer);
|
||||
|
||||
if ([(GdkMacosWindow *)window isInManualResizeOrMove])
|
||||
{
|
||||
ret = GDK_MACOS_EVENT_DROP;
|
||||
}
|
||||
else if (grab == NULL)
|
||||
{
|
||||
if (event_type == NSEventTypeMouseExited)
|
||||
[[NSCursor arrowCursor] set];
|
||||
|
||||
ret = synthesize_crossing_event (self, surface, nsevent, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case NSEventTypeKeyDown:
|
||||
case NSEventTypeKeyUp:
|
||||
case NSEventTypeFlagsChanged: {
|
||||
GdkEventType type = _gdk_macos_keymap_get_event_type (nsevent);
|
||||
|
||||
if (type)
|
||||
ret = fill_key_event (self, surface, nsevent, type);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case NSEventTypeScrollWheel:
|
||||
ret = fill_scroll_event (self, surface, nsevent, x, y);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
return fill_event (self, window, nsevent, x, y);
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_macos_display_send_button_event (GdkMacosDisplay *self,
|
||||
NSEvent *nsevent)
|
||||
_gdk_macos_display_send_event (GdkMacosDisplay *self,
|
||||
NSEvent *nsevent)
|
||||
{
|
||||
GdkMacosSurface *surface;
|
||||
GdkMacosWindow *window;
|
||||
GdkEvent *event;
|
||||
int x;
|
||||
int y;
|
||||
@@ -1279,7 +1282,8 @@ _gdk_macos_display_send_button_event (GdkMacosDisplay *self,
|
||||
g_return_if_fail (nsevent != NULL);
|
||||
|
||||
if ((surface = find_surface_for_ns_event (self, nsevent, &x, &y)) &&
|
||||
(event = fill_button_event (self, surface, nsevent, x, y)))
|
||||
(window = (GdkMacosWindow *)_gdk_macos_surface_get_native (surface)) &&
|
||||
(event = fill_event (self, window, nsevent, x, y)))
|
||||
_gdk_windowing_got_event (GDK_DISPLAY (self),
|
||||
_gdk_event_queue_append (GDK_DISPLAY (self), event),
|
||||
event,
|
||||
|
||||
@@ -870,15 +870,12 @@ _gdk_macos_display_get_surface_at_coords (GdkMacosDisplay *self,
|
||||
for (const GList *iter = surfaces; iter; iter = iter->next)
|
||||
{
|
||||
GdkSurface *surface = iter->data;
|
||||
NSWindow *nswindow;
|
||||
|
||||
g_assert (GDK_IS_MACOS_SURFACE (surface));
|
||||
|
||||
if (!gdk_surface_get_mapped (surface))
|
||||
continue;
|
||||
|
||||
nswindow = _gdk_macos_surface_get_native (GDK_MACOS_SURFACE (surface));
|
||||
|
||||
if (x >= GDK_MACOS_SURFACE (surface)->root_x &&
|
||||
y >= GDK_MACOS_SURFACE (surface)->root_y &&
|
||||
x <= (GDK_MACOS_SURFACE (surface)->root_x + surface->width) &&
|
||||
@@ -1027,6 +1024,16 @@ _gdk_macos_display_get_nsevent (GdkEvent *event)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
NSEvent *
|
||||
_gdk_macos_display_get_last_nsevent ()
|
||||
{
|
||||
const GdkToNSEventMap *map = g_queue_peek_tail (&event_map);
|
||||
if (map)
|
||||
return map->nsevent;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GdkDrag *
|
||||
_gdk_macos_display_find_drag (GdkMacosDisplay *self,
|
||||
NSInteger sequence_number)
|
||||
|
||||
@@ -41,7 +41,6 @@ struct _GdkMacosDrag
|
||||
GdkDrag parent_instance;
|
||||
|
||||
GdkMacosDragSurface *drag_surface;
|
||||
GdkSeat *drag_seat;
|
||||
GdkCursor *cursor;
|
||||
|
||||
int hot_x;
|
||||
@@ -62,8 +61,22 @@ struct _GdkMacosDragClass
|
||||
GdkDragClass parent_class;
|
||||
};
|
||||
|
||||
GType gdk_macos_drag_get_type (void) G_GNUC_CONST;
|
||||
gboolean _gdk_macos_drag_begin (GdkMacosDrag *self);
|
||||
GType gdk_macos_drag_get_type (void) G_GNUC_CONST;
|
||||
gboolean _gdk_macos_drag_begin (GdkMacosDrag *self,
|
||||
GdkContentProvider *content,
|
||||
GdkMacosWindow *window);
|
||||
NSDragOperation _gdk_macos_drag_operation (GdkMacosDrag *self);
|
||||
GdkDragAction _gdk_macos_drag_ns_operation_to_action
|
||||
(NSDragOperation operation);
|
||||
void _gdk_macos_drag_surface_move (GdkMacosDrag *self,
|
||||
int x_root,
|
||||
int y_root);
|
||||
void _gdk_macos_drag_set_start_position (GdkMacosDrag *self,
|
||||
int start_x,
|
||||
int start_y);
|
||||
void _gdk_macos_drag_set_actions (GdkMacosDrag *self,
|
||||
GdkModifierType mods);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
+106
-261
@@ -25,6 +25,7 @@
|
||||
#include "gdkmacoscursor-private.h"
|
||||
#include "gdkmacosdisplay-private.h"
|
||||
#include "gdkmacosdragsurface-private.h"
|
||||
#include "gdkmacospasteboard-private.h"
|
||||
|
||||
#include "gdk/gdkdeviceprivate.h"
|
||||
#include "gdk/gdkeventsprivate.h"
|
||||
@@ -187,41 +188,6 @@ gdk_macos_drag_set_cursor (GdkDrag *drag,
|
||||
[nscursor set];
|
||||
}
|
||||
|
||||
static gboolean
|
||||
drag_grab (GdkMacosDrag *self)
|
||||
{
|
||||
GdkSeat *seat;
|
||||
|
||||
g_assert (GDK_IS_MACOS_DRAG (self));
|
||||
|
||||
seat = gdk_device_get_seat (gdk_drag_get_device (GDK_DRAG (self)));
|
||||
|
||||
if (gdk_seat_grab (seat,
|
||||
GDK_SURFACE (self->drag_surface),
|
||||
GDK_SEAT_CAPABILITY_ALL_POINTING,
|
||||
FALSE,
|
||||
self->cursor,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL) != GDK_GRAB_SUCCESS)
|
||||
return FALSE;
|
||||
|
||||
g_set_object (&self->drag_seat, seat);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
drag_ungrab (GdkMacosDrag *self)
|
||||
{
|
||||
GdkDisplay *display;
|
||||
|
||||
g_assert (GDK_IS_MACOS_DRAG (self));
|
||||
|
||||
display = gdk_drag_get_display (GDK_DRAG (self));
|
||||
_gdk_macos_display_break_all_grabs (GDK_MACOS_DISPLAY (display), GDK_CURRENT_TIME);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_drag_cancel (GdkDrag *drag,
|
||||
GdkDragCancelReason reason)
|
||||
@@ -234,7 +200,6 @@ gdk_macos_drag_cancel (GdkDrag *drag,
|
||||
return;
|
||||
|
||||
self->cancelled = TRUE;
|
||||
drag_ungrab (self);
|
||||
gdk_drag_drop_done (drag, FALSE);
|
||||
}
|
||||
|
||||
@@ -247,7 +212,6 @@ gdk_macos_drag_drop_performed (GdkDrag *drag,
|
||||
g_assert (GDK_IS_MACOS_DRAG (self));
|
||||
|
||||
g_object_ref (self);
|
||||
drag_ungrab (self);
|
||||
g_signal_emit_by_name (drag, "dnd-finished");
|
||||
gdk_drag_drop_done (drag, TRUE);
|
||||
g_object_unref (self);
|
||||
@@ -310,225 +274,6 @@ gdk_drag_get_current_actions (GdkModifierType state,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_drag_update (GdkDrag *drag,
|
||||
double x_root,
|
||||
double y_root,
|
||||
GdkModifierType mods,
|
||||
guint32 evtime)
|
||||
{
|
||||
GdkMacosDrag *self = (GdkMacosDrag *)drag;
|
||||
GdkDragAction suggested_action;
|
||||
GdkDragAction possible_actions;
|
||||
|
||||
g_assert (GDK_IS_MACOS_DRAG (self));
|
||||
|
||||
self->last_x = x_root;
|
||||
self->last_y = y_root;
|
||||
|
||||
gdk_drag_get_current_actions (mods,
|
||||
GDK_BUTTON_PRIMARY,
|
||||
gdk_drag_get_actions (drag),
|
||||
&suggested_action,
|
||||
&possible_actions);
|
||||
|
||||
if (GDK_IS_MACOS_SURFACE (self->drag_surface))
|
||||
_gdk_macos_surface_move (GDK_MACOS_SURFACE (self->drag_surface),
|
||||
x_root - self->hot_x,
|
||||
y_root - self->hot_y);
|
||||
|
||||
if (!self->did_update)
|
||||
{
|
||||
self->start_x = self->last_x;
|
||||
self->start_y = self->last_y;
|
||||
self->did_update = TRUE;
|
||||
}
|
||||
|
||||
gdk_drag_set_actions (drag, possible_actions);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_dnd_handle_motion_event (GdkDrag *drag,
|
||||
GdkEvent *event)
|
||||
{
|
||||
double x, y;
|
||||
int x_root, y_root;
|
||||
|
||||
g_assert (GDK_IS_MACOS_DRAG (drag));
|
||||
g_assert (event != NULL);
|
||||
|
||||
/* Ignore motion while doing zoomback */
|
||||
if (GDK_MACOS_DRAG (drag)->cancelled)
|
||||
return FALSE;
|
||||
|
||||
gdk_event_get_position (event, &x, &y);
|
||||
x_root = event->surface->x + x;
|
||||
y_root = event->surface->y + y;
|
||||
gdk_drag_update (drag, x_root, y_root,
|
||||
gdk_event_get_modifier_state (event),
|
||||
gdk_event_get_time (event));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_dnd_handle_grab_broken_event (GdkDrag *drag,
|
||||
GdkEvent *event)
|
||||
{
|
||||
GdkMacosDrag *self = GDK_MACOS_DRAG (drag);
|
||||
gboolean is_implicit = gdk_grab_broken_event_get_implicit (event);
|
||||
GdkSurface *grab_surface = gdk_grab_broken_event_get_grab_surface (event);
|
||||
|
||||
/* Don't cancel if we break the implicit grab from the initial button_press. */
|
||||
if (is_implicit || grab_surface == (GdkSurface *)self->drag_surface)
|
||||
return FALSE;
|
||||
|
||||
if (gdk_event_get_device (event) != gdk_drag_get_device (drag))
|
||||
return FALSE;
|
||||
|
||||
gdk_drag_cancel (drag, GDK_DRAG_CANCEL_ERROR);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_dnd_handle_button_event (GdkDrag *drag,
|
||||
GdkEvent *event)
|
||||
{
|
||||
GdkMacosDrag *self = GDK_MACOS_DRAG (drag);
|
||||
|
||||
g_assert (GDK_IS_MACOS_DRAG (self));
|
||||
g_assert (event != NULL);
|
||||
|
||||
#if 0
|
||||
/* FIXME: Check the button matches */
|
||||
if (event->button != self->button)
|
||||
return FALSE;
|
||||
#endif
|
||||
|
||||
if (gdk_drag_get_selected_action (drag) != 0)
|
||||
g_signal_emit_by_name (drag, "drop-performed");
|
||||
else
|
||||
gdk_drag_cancel (drag, GDK_DRAG_CANCEL_NO_TARGET);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_dnd_handle_key_event (GdkDrag *drag,
|
||||
GdkEvent *event)
|
||||
{
|
||||
GdkMacosDrag *self = GDK_MACOS_DRAG (drag);
|
||||
GdkModifierType state;
|
||||
GdkDevice *pointer;
|
||||
GdkSeat *seat;
|
||||
int dx, dy;
|
||||
|
||||
dx = dy = 0;
|
||||
state = gdk_event_get_modifier_state (event);
|
||||
seat = gdk_event_get_seat (event);
|
||||
pointer = gdk_seat_get_pointer (seat);
|
||||
|
||||
if (event->event_type == GDK_KEY_PRESS)
|
||||
{
|
||||
guint keyval = gdk_key_event_get_keyval (event);
|
||||
|
||||
switch (keyval)
|
||||
{
|
||||
case GDK_KEY_Escape:
|
||||
gdk_drag_cancel (drag, GDK_DRAG_CANCEL_USER_CANCELLED);
|
||||
return TRUE;
|
||||
|
||||
case GDK_KEY_space:
|
||||
case GDK_KEY_Return:
|
||||
case GDK_KEY_ISO_Enter:
|
||||
case GDK_KEY_KP_Enter:
|
||||
case GDK_KEY_KP_Space:
|
||||
if (gdk_drag_get_selected_action (drag) != 0)
|
||||
g_signal_emit_by_name (drag, "drop-performed");
|
||||
else
|
||||
gdk_drag_cancel (drag, GDK_DRAG_CANCEL_NO_TARGET);
|
||||
|
||||
return TRUE;
|
||||
|
||||
case GDK_KEY_Up:
|
||||
case GDK_KEY_KP_Up:
|
||||
dy = (state & GDK_ALT_MASK) ? -BIG_STEP : -SMALL_STEP;
|
||||
break;
|
||||
|
||||
case GDK_KEY_Down:
|
||||
case GDK_KEY_KP_Down:
|
||||
dy = (state & GDK_ALT_MASK) ? BIG_STEP : SMALL_STEP;
|
||||
break;
|
||||
|
||||
case GDK_KEY_Left:
|
||||
case GDK_KEY_KP_Left:
|
||||
dx = (state & GDK_ALT_MASK) ? -BIG_STEP : -SMALL_STEP;
|
||||
break;
|
||||
|
||||
case GDK_KEY_Right:
|
||||
case GDK_KEY_KP_Right:
|
||||
dx = (state & GDK_ALT_MASK) ? BIG_STEP : SMALL_STEP;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* The state is not yet updated in the event, so we need
|
||||
* to query it here. We could use XGetModifierMapping, but
|
||||
* that would be overkill.
|
||||
*/
|
||||
gdk_macos_device_query_state (pointer, NULL, NULL, NULL, NULL, &state);
|
||||
|
||||
if (dx != 0 || dy != 0)
|
||||
{
|
||||
GdkDisplay *display = gdk_event_get_display ((GdkEvent *)event);
|
||||
|
||||
self->last_x += dx;
|
||||
self->last_y += dy;
|
||||
|
||||
_gdk_macos_display_warp_pointer (GDK_MACOS_DISPLAY (display),
|
||||
self->last_x,
|
||||
self->last_y);
|
||||
}
|
||||
|
||||
gdk_drag_update (drag,
|
||||
self->last_x, self->last_y,
|
||||
state,
|
||||
gdk_event_get_time (event));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_macos_drag_handle_event (GdkDrag *drag,
|
||||
GdkEvent *event)
|
||||
{
|
||||
g_assert (GDK_IS_MACOS_DRAG (drag));
|
||||
g_assert (event != NULL);
|
||||
|
||||
switch ((guint) event->event_type)
|
||||
{
|
||||
case GDK_MOTION_NOTIFY:
|
||||
return gdk_dnd_handle_motion_event (drag, event);
|
||||
|
||||
case GDK_BUTTON_RELEASE:
|
||||
return gdk_dnd_handle_button_event (drag, event);
|
||||
|
||||
case GDK_KEY_PRESS:
|
||||
case GDK_KEY_RELEASE:
|
||||
return gdk_dnd_handle_key_event (drag, event);
|
||||
|
||||
case GDK_GRAB_BROKEN:
|
||||
return gdk_dnd_handle_grab_broken_event (drag, event);
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_drag_finalize (GObject *object)
|
||||
{
|
||||
@@ -536,7 +281,6 @@ gdk_macos_drag_finalize (GObject *object)
|
||||
GdkMacosDragSurface *drag_surface = g_steal_pointer (&self->drag_surface);
|
||||
|
||||
g_clear_object (&self->cursor);
|
||||
g_clear_object (&self->drag_seat);
|
||||
|
||||
G_OBJECT_CLASS (gdk_macos_drag_parent_class)->finalize (object);
|
||||
|
||||
@@ -598,7 +342,6 @@ gdk_macos_drag_class_init (GdkMacosDragClass *klass)
|
||||
drag_class->set_cursor = gdk_macos_drag_set_cursor;
|
||||
drag_class->cancel = gdk_macos_drag_cancel;
|
||||
drag_class->drop_performed = gdk_macos_drag_drop_performed;
|
||||
drag_class->handle_event = gdk_macos_drag_handle_event;
|
||||
|
||||
properties [PROP_DRAG_SURFACE] =
|
||||
g_param_spec_object ("drag-surface", NULL, NULL,
|
||||
@@ -614,11 +357,113 @@ gdk_macos_drag_init (GdkMacosDrag *self)
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gdk_macos_drag_begin (GdkMacosDrag *self)
|
||||
_gdk_macos_drag_begin (GdkMacosDrag *self,
|
||||
GdkContentProvider *content,
|
||||
GdkMacosWindow *window)
|
||||
{
|
||||
NSArray<NSDraggingItem *> *items;
|
||||
NSDraggingSession *session;
|
||||
NSPasteboardItem *item;
|
||||
NSEvent *nsevent;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_MACOS_DRAG (self), FALSE);
|
||||
g_return_val_if_fail (GDK_IS_MACOS_WINDOW (window), FALSE);
|
||||
|
||||
_gdk_macos_surface_show (GDK_MACOS_SURFACE (self->drag_surface));
|
||||
GDK_BEGIN_MACOS_ALLOC_POOL;
|
||||
|
||||
return drag_grab (self);
|
||||
item = [[GdkMacosPasteboardItem alloc] initForDrag:GDK_DRAG (self) withContentProvider:content];
|
||||
items = [NSArray arrayWithObject:item];
|
||||
nsevent = _gdk_macos_display_get_last_nsevent ();
|
||||
|
||||
session = [[window contentView] beginDraggingSessionWithItems:items
|
||||
event:nsevent
|
||||
source:window];
|
||||
|
||||
GDK_END_MACOS_ALLOC_POOL;
|
||||
|
||||
_gdk_macos_display_set_drag (GDK_MACOS_DISPLAY (gdk_drag_get_display (GDK_DRAG (self))),
|
||||
[session draggingSequenceNumber],
|
||||
GDK_DRAG (self));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
NSDragOperation
|
||||
_gdk_macos_drag_operation (GdkMacosDrag *self)
|
||||
{
|
||||
NSDragOperation operation = NSDragOperationNone;
|
||||
GdkDragAction actions;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_MACOS_DRAG (self), NSDragOperationNone);
|
||||
|
||||
actions = gdk_drag_get_actions (GDK_DRAG (self));
|
||||
|
||||
if (actions & GDK_ACTION_LINK)
|
||||
operation |= NSDragOperationLink;
|
||||
|
||||
if (actions & GDK_ACTION_MOVE)
|
||||
operation |= NSDragOperationMove;
|
||||
|
||||
if (actions & GDK_ACTION_COPY)
|
||||
operation |= NSDragOperationCopy;
|
||||
|
||||
return operation;
|
||||
}
|
||||
|
||||
GdkDragAction
|
||||
_gdk_macos_drag_ns_operation_to_action (NSDragOperation operation)
|
||||
{
|
||||
if (operation & NSDragOperationCopy)
|
||||
return GDK_ACTION_COPY;
|
||||
if (operation & NSDragOperationMove)
|
||||
return GDK_ACTION_MOVE;
|
||||
if (operation & NSDragOperationLink)
|
||||
return GDK_ACTION_LINK;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_macos_drag_surface_move (GdkMacosDrag *self,
|
||||
int x_root,
|
||||
int y_root)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_MACOS_DRAG (self));
|
||||
|
||||
self->last_x = x_root;
|
||||
self->last_y = y_root;
|
||||
|
||||
if (GDK_IS_MACOS_SURFACE (self->drag_surface))
|
||||
_gdk_macos_surface_move (GDK_MACOS_SURFACE (self->drag_surface),
|
||||
x_root - self->hot_x,
|
||||
y_root - self->hot_y);
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_macos_drag_set_start_position (GdkMacosDrag *self,
|
||||
int start_x,
|
||||
int start_y)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_MACOS_DRAG (self));
|
||||
|
||||
self->start_x = start_x;
|
||||
self->start_y = start_y;
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_macos_drag_set_actions (GdkMacosDrag *self,
|
||||
GdkModifierType mods)
|
||||
{
|
||||
GdkDragAction suggested_action;
|
||||
GdkDragAction possible_actions;
|
||||
|
||||
g_assert (GDK_IS_MACOS_DRAG (self));
|
||||
|
||||
gdk_drag_get_current_actions (mods,
|
||||
GDK_BUTTON_PRIMARY,
|
||||
gdk_drag_get_actions (GDK_DRAG (self)),
|
||||
&suggested_action,
|
||||
&possible_actions);
|
||||
|
||||
gdk_drag_set_selected_action (GDK_DRAG (self), suggested_action);
|
||||
gdk_drag_set_actions (GDK_DRAG (self), possible_actions);
|
||||
}
|
||||
|
||||
@@ -37,11 +37,15 @@
|
||||
/*
|
||||
* This file implementations integration between the GLib main loop and
|
||||
* the native system of the Core Foundation run loop and Cocoa event
|
||||
* handling. There are basically two different cases that we need to
|
||||
* handle: either the GLib main loop is in control (the application
|
||||
* has called gtk_main(), or is otherwise iterating the main loop), or
|
||||
* CFRunLoop is in control (we are in a modal operation such as window
|
||||
* resizing or drag-and-drop.)
|
||||
* handling. There are basically three different cases that we need to
|
||||
* handle:
|
||||
*
|
||||
* - the GLib main loop is in control. The application has called
|
||||
* gtk_main(), or is otherwise iterating the main loop.
|
||||
* - CFRunLoop is in control. We are in a modal operation such as window
|
||||
* resizing.
|
||||
* - CFRunLoop is running a nested loop. This happens when a drag-and-drop
|
||||
* operation has been initiated.
|
||||
*
|
||||
* When the GLib main loop is in control we integrate in native event
|
||||
* handling in two ways: first we add a GSource that handles checking
|
||||
@@ -57,14 +61,23 @@
|
||||
* stages of the GLib main loop (prepare, check, dispatch), and make the
|
||||
* appropriate calls into GLib.
|
||||
*
|
||||
* Both cases share a single problem: the OS X API’s don’t allow us to
|
||||
* When initiating a drag operation, a nested CFRunLoop is executed.
|
||||
* The nested run loop is started when fetching a native event in our GLib
|
||||
* main loop. The application does not receive any events until the nested loop
|
||||
* is finished. We work around this by forwarding the
|
||||
* events that trigger the callbacks of the NSDraggingSource protocol.
|
||||
* The "run loop observer" is executing the GLib main loop stages as long as we're
|
||||
* in the nested run loop, as if CFRunLoop were in control.
|
||||
* See also GdkMacosWindow.
|
||||
*
|
||||
* All cases share a single problem: the macOS API’s don’t allow us to
|
||||
* wait simultaneously for file descriptors and for events. So when we
|
||||
* need to do a blocking wait that includes file descriptor activity, we
|
||||
* push the actual work of calling select() to a helper thread (the
|
||||
* "select thread") and wait for native events in the main thread.
|
||||
*
|
||||
* The main known limitation of this code is that if a callback is triggered
|
||||
* via the OS X run loop while we are "polling" (in either case described
|
||||
* via the macOS run loop while we are "polling" (in either case described
|
||||
* above), iteration of the GLib main loop is not possible from within
|
||||
* that callback. If the programmer tries to do so explicitly, then they
|
||||
* will get a warning from GLib "main loop already active in another thread".
|
||||
@@ -640,6 +653,23 @@ _gdk_macos_event_source_get_pending (void)
|
||||
return event;
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_macos_event_source_queue_event (NSEvent *event)
|
||||
{
|
||||
/* Just used to wake us up; if an event and a FD arrived at the same
|
||||
* time; could have come from a previous iteration in some cases,
|
||||
* but the spurious wake up is harmless if a little inefficient.
|
||||
*/
|
||||
if (!event ||
|
||||
([event type] == NSEventTypeApplicationDefined &&
|
||||
[event subtype] == GDK_MACOS_EVENT_SUBTYPE_EVENTLOOP))
|
||||
return;
|
||||
|
||||
if (!current_events)
|
||||
current_events = g_queue_new ();
|
||||
g_queue_push_head (current_events, [event retain]);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_macos_event_source_prepare (GSource *source,
|
||||
int *timeout)
|
||||
@@ -782,23 +812,7 @@ poll_func (GPollFD *ufds,
|
||||
if (last_ufds == ufds && n_ready < 0)
|
||||
n_ready = select_thread_collect_poll (ufds, nfds);
|
||||
|
||||
if (event &&
|
||||
[event type] == NSEventTypeApplicationDefined &&
|
||||
[event subtype] == GDK_MACOS_EVENT_SUBTYPE_EVENTLOOP)
|
||||
{
|
||||
/* Just used to wake us up; if an event and a FD arrived at the same
|
||||
* time; could have come from a previous iteration in some cases,
|
||||
* but the spurious wake up is harmless if a little inefficient.
|
||||
*/
|
||||
event = NULL;
|
||||
}
|
||||
|
||||
if (event)
|
||||
{
|
||||
if (!current_events)
|
||||
current_events = g_queue_new ();
|
||||
g_queue_push_head (current_events, [event retain]);
|
||||
}
|
||||
_gdk_macos_event_source_queue_event (event);
|
||||
|
||||
return n_ready;
|
||||
}
|
||||
@@ -1018,7 +1032,10 @@ run_loop_observer_callback (CFRunLoopObserverRef observer,
|
||||
break;
|
||||
}
|
||||
|
||||
if (getting_events > 0) /* Activity we triggered */
|
||||
/* DnD starts a nested runloop, or so it seems.
|
||||
If we have such a loop, we still want to run
|
||||
our idle handlers. */
|
||||
if (getting_events > 0 && current_loop_level < 2)
|
||||
return;
|
||||
|
||||
switch (activity)
|
||||
@@ -1042,7 +1059,6 @@ run_loop_observer_callback (CFRunLoopObserverRef observer,
|
||||
run_loop_exit ();
|
||||
break;
|
||||
case kCFRunLoopAllActivities:
|
||||
/* TODO: Do most of the above? */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -460,12 +460,10 @@ gdk_macos_gl_context_begin_frame (GdkDrawContext *context,
|
||||
{
|
||||
GdkMacosGLContext *self = (GdkMacosGLContext *)context;
|
||||
GdkMacosBuffer *buffer;
|
||||
cairo_region_t *copy;
|
||||
GdkSurface *surface;
|
||||
|
||||
g_assert (GDK_IS_MACOS_GL_CONTEXT (self));
|
||||
|
||||
copy = cairo_region_copy (region);
|
||||
surface = gdk_draw_context_get_surface (context);
|
||||
buffer = _gdk_macos_surface_get_buffer (GDK_MACOS_SURFACE (surface));
|
||||
|
||||
@@ -550,6 +548,14 @@ gdk_macos_gl_context_clear_current (GdkGLContext *context)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_macos_gl_context_is_current (GdkGLContext *context)
|
||||
{
|
||||
GdkMacosGLContext *self = GDK_MACOS_GL_CONTEXT (context);
|
||||
|
||||
return self->cgl_context == CGLGetCurrentContext ();
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_macos_gl_context_make_current (GdkGLContext *context,
|
||||
gboolean surfaceless)
|
||||
@@ -641,6 +647,7 @@ gdk_macos_gl_context_class_init (GdkMacosGLContextClass *klass)
|
||||
|
||||
gl_class->get_damage = gdk_macos_gl_context_get_damage;
|
||||
gl_class->clear_current = gdk_macos_gl_context_clear_current;
|
||||
gl_class->is_current = gdk_macos_gl_context_is_current;
|
||||
gl_class->make_current = gdk_macos_gl_context_make_current;
|
||||
gl_class->realize = gdk_macos_gl_context_real_realize;
|
||||
gl_class->get_default_framebuffer = gdk_macos_gl_context_get_default_framebuffer;
|
||||
|
||||
@@ -276,10 +276,8 @@ gdk_macos_keymap_update (GdkMacosKeymap *self)
|
||||
{
|
||||
UInt32 state = 0;
|
||||
OSStatus err;
|
||||
UInt16 key_code;
|
||||
UniChar uc;
|
||||
|
||||
key_code = modifiers[j] | i;
|
||||
err = UCKeyTranslate (chr_data, i, kUCKeyActionDisplay,
|
||||
(modifiers[j] >> 8) & 0xFF,
|
||||
LMGetKbdType(),
|
||||
@@ -369,7 +367,7 @@ gdk_macos_keymap_update (GdkMacosKeymap *self)
|
||||
if (p[0] == known_numeric_keys[i].normal_keyval)
|
||||
p[0] = known_numeric_keys[i].keypad_keyval;
|
||||
}
|
||||
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (jis_keys); i++)
|
||||
{
|
||||
p = keyval_array + jis_keys[i].keycode * KEYVALS_PER_KEYCODE;
|
||||
|
||||
@@ -215,7 +215,6 @@ gdk_macos_monitor_display_link_cb (GdkMacosMonitor *self)
|
||||
{
|
||||
gint64 presentation_time;
|
||||
gint64 refresh_interval;
|
||||
gint64 now;
|
||||
GList *iter;
|
||||
|
||||
g_assert (GDK_IS_MACOS_MONITOR (self));
|
||||
@@ -225,7 +224,6 @@ gdk_macos_monitor_display_link_cb (GdkMacosMonitor *self)
|
||||
|
||||
presentation_time = self->display_link->presentation_time;
|
||||
refresh_interval = self->display_link->refresh_interval;
|
||||
now = g_source_get_time ((GSource *)self->display_link);
|
||||
|
||||
iter = self->awaiting_frames.head;
|
||||
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright © 2021 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#ifndef __GDK_MACOS_PASTEBOARD_PRIVATE_H__
|
||||
#define __GDK_MACOS_PASTEBOARD_PRIVATE_H__
|
||||
|
||||
#include <AppKit/AppKit.h>
|
||||
#include <gio/gio.h>
|
||||
|
||||
#include "gdkclipboardprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@interface GdkMacosPasteboardItemDataProvider : NSObject <NSPasteboardItemDataProvider>
|
||||
{
|
||||
GdkContentProvider *_contentProvider;
|
||||
GdkClipboard *_clipboard;
|
||||
GdkDrag *_drag;
|
||||
}
|
||||
|
||||
-(id)initForClipboard:(GdkClipboard *)clipboard withContentProvider:(GdkContentProvider *)contentProvider;
|
||||
-(id)initForDrag:(GdkDrag *)drag withContentProvider:(GdkContentProvider *)contentProvider;
|
||||
|
||||
@end
|
||||
|
||||
@interface GdkMacosPasteboardItem : NSPasteboardItem
|
||||
{
|
||||
GdkContentProvider *_contentProvider;
|
||||
GdkClipboard *_clipboard;
|
||||
GdkDrag *_drag;
|
||||
NSRect _draggingFrame;
|
||||
}
|
||||
|
||||
-(id)initForClipboard:(GdkClipboard *)clipboard withContentProvider:(GdkContentProvider *)contentProvider;
|
||||
-(id)initForDrag:(GdkDrag *)drag withContentProvider:(GdkContentProvider *)contentProvider;
|
||||
|
||||
@end
|
||||
|
||||
NSPasteboardType _gdk_macos_pasteboard_to_ns_type (const char *mime_type,
|
||||
NSPasteboardType *alternate);
|
||||
const char *_gdk_macos_pasteboard_from_ns_type (NSPasteboardType type);
|
||||
GdkContentFormats *_gdk_macos_pasteboard_load_formats (NSPasteboard *pasteboard);
|
||||
void _gdk_macos_pasteboard_register_drag_types (NSWindow *window);
|
||||
void _gdk_macos_pasteboard_read_async (GObject *object,
|
||||
NSPasteboard *pasteboard,
|
||||
GdkContentFormats *formats,
|
||||
int io_priority,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
GInputStream *_gdk_macos_pasteboard_read_finish (GObject *object,
|
||||
GAsyncResult *result,
|
||||
const char **out_mime_type,
|
||||
GError **error);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_MACOS_PASTEBOARD_PRIVATE_H__ */
|
||||
@@ -0,0 +1,602 @@
|
||||
/*
|
||||
* Copyright © 2021 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
|
||||
#include "gdkdragprivate.h"
|
||||
#include "gdkmacospasteboard-private.h"
|
||||
#include "gdkmacosutils-private.h"
|
||||
|
||||
enum {
|
||||
TYPE_STRING,
|
||||
TYPE_PBOARD,
|
||||
TYPE_URL,
|
||||
TYPE_FILE_URL,
|
||||
TYPE_COLOR,
|
||||
TYPE_TIFF,
|
||||
TYPE_PNG,
|
||||
TYPE_LAST
|
||||
};
|
||||
|
||||
#define PTYPE(k) (get_pasteboard_type(TYPE_##k))
|
||||
|
||||
static NSPasteboardType pasteboard_types[TYPE_LAST];
|
||||
|
||||
static NSPasteboardType
|
||||
get_pasteboard_type (int type)
|
||||
{
|
||||
static gsize initialized = FALSE;
|
||||
|
||||
g_assert (type >= 0);
|
||||
g_assert (type < TYPE_LAST);
|
||||
|
||||
if (g_once_init_enter (&initialized))
|
||||
{
|
||||
pasteboard_types[TYPE_PNG] = NSPasteboardTypePNG;
|
||||
pasteboard_types[TYPE_STRING] = NSPasteboardTypeString;
|
||||
pasteboard_types[TYPE_TIFF] = NSPasteboardTypeTIFF;
|
||||
pasteboard_types[TYPE_COLOR] = NSPasteboardTypeColor;
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
pasteboard_types[TYPE_PBOARD] = NSStringPboardType;
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
|
||||
#ifdef AVAILABLE_MAC_OS_X_VERSION_10_13_AND_LATER
|
||||
pasteboard_types[TYPE_URL] = NSPasteboardTypeURL;
|
||||
pasteboard_types[TYPE_FILE_URL] = NSPasteboardTypeFileURL;
|
||||
#else
|
||||
pasteboard_types[TYPE_URL] = [[NSString alloc] initWithUTF8String:"public.url"];
|
||||
pasteboard_types[TYPE_FILE_URL] = [[NSString alloc] initWithUTF8String:"public.file-url"];
|
||||
#endif
|
||||
|
||||
g_once_init_leave (&initialized, TRUE);
|
||||
}
|
||||
|
||||
return pasteboard_types[type];
|
||||
}
|
||||
|
||||
const char *
|
||||
_gdk_macos_pasteboard_from_ns_type (NSPasteboardType type)
|
||||
{
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
|
||||
|
||||
if ([type isEqualToString:PTYPE(STRING)] ||
|
||||
[type isEqualToString:PTYPE(PBOARD)])
|
||||
return g_intern_string ("text/plain;charset=utf-8");
|
||||
else if ([type isEqualToString:PTYPE(URL)] ||
|
||||
[type isEqualToString:PTYPE(FILE_URL)])
|
||||
return g_intern_string ("text/uri-list");
|
||||
else if ([type isEqualToString:PTYPE(COLOR)])
|
||||
return g_intern_string ("application/x-color");
|
||||
else if ([type isEqualToString:PTYPE(TIFF)])
|
||||
return g_intern_string ("image/tiff");
|
||||
else if ([type isEqualToString:PTYPE(PNG)])
|
||||
return g_intern_string ("image/png");
|
||||
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
NSPasteboardType
|
||||
_gdk_macos_pasteboard_to_ns_type (const char *mime_type,
|
||||
NSPasteboardType *alternate)
|
||||
{
|
||||
if (alternate)
|
||||
*alternate = NULL;
|
||||
|
||||
if (g_strcmp0 (mime_type, "text/plain;charset=utf-8") == 0)
|
||||
{
|
||||
return PTYPE(STRING);
|
||||
}
|
||||
else if (g_strcmp0 (mime_type, "text/uri-list") == 0)
|
||||
{
|
||||
if (alternate)
|
||||
*alternate = PTYPE(URL);
|
||||
return PTYPE(FILE_URL);
|
||||
}
|
||||
else if (g_strcmp0 (mime_type, "application/x-color") == 0)
|
||||
{
|
||||
return PTYPE(COLOR);
|
||||
}
|
||||
else if (g_strcmp0 (mime_type, "image/tiff") == 0)
|
||||
{
|
||||
return PTYPE(TIFF);
|
||||
}
|
||||
else if (g_strcmp0 (mime_type, "image/png") == 0)
|
||||
{
|
||||
return PTYPE(PNG);
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
static void
|
||||
populate_content_formats (GdkContentFormatsBuilder *builder,
|
||||
NSPasteboardType type)
|
||||
{
|
||||
const char *mime_type;
|
||||
|
||||
g_assert (builder != NULL);
|
||||
g_assert (type != NULL);
|
||||
|
||||
if ((mime_type = _gdk_macos_pasteboard_from_ns_type (type)))
|
||||
gdk_content_formats_builder_add_mime_type (builder, mime_type);
|
||||
}
|
||||
|
||||
static GdkContentFormats *
|
||||
load_offer_formats (NSPasteboard *pasteboard)
|
||||
{
|
||||
GDK_BEGIN_MACOS_ALLOC_POOL;
|
||||
|
||||
GdkContentFormatsBuilder *builder;
|
||||
GdkContentFormats *formats;
|
||||
|
||||
builder = gdk_content_formats_builder_new ();
|
||||
for (NSPasteboardType type in [pasteboard types])
|
||||
populate_content_formats (builder, type);
|
||||
formats = gdk_content_formats_builder_free_to_formats (builder);
|
||||
|
||||
GDK_END_MACOS_ALLOC_POOL;
|
||||
|
||||
return g_steal_pointer (&formats);
|
||||
}
|
||||
|
||||
GdkContentFormats *
|
||||
_gdk_macos_pasteboard_load_formats (NSPasteboard *pasteboard)
|
||||
{
|
||||
return load_offer_formats (pasteboard);
|
||||
}
|
||||
|
||||
static GInputStream *
|
||||
create_stream_from_nsdata (NSData *data)
|
||||
{
|
||||
const guint8 *bytes = [data bytes];
|
||||
gsize len = [data length];
|
||||
|
||||
return g_memory_input_stream_new_from_data (g_memdup2 (bytes, len), len, g_free);
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_macos_pasteboard_read_async (GObject *object,
|
||||
NSPasteboard *pasteboard,
|
||||
GdkContentFormats *formats,
|
||||
int io_priority,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
GDK_BEGIN_MACOS_ALLOC_POOL;
|
||||
|
||||
GdkContentFormats *offer_formats = NULL;
|
||||
const char *mime_type;
|
||||
GInputStream *stream = NULL;
|
||||
GTask *task = NULL;
|
||||
|
||||
g_assert (G_IS_OBJECT (object));
|
||||
g_assert (pasteboard != NULL);
|
||||
g_assert (formats != NULL);
|
||||
|
||||
task = g_task_new (object, cancellable, callback, user_data);
|
||||
g_task_set_source_tag (task, _gdk_macos_pasteboard_read_async);
|
||||
g_task_set_priority (task, io_priority);
|
||||
|
||||
offer_formats = load_offer_formats (pasteboard);
|
||||
mime_type = gdk_content_formats_match_mime_type (formats, offer_formats);
|
||||
|
||||
if (mime_type == NULL)
|
||||
{
|
||||
g_task_return_new_error (task,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_NOT_SUPPORTED,
|
||||
"%s",
|
||||
_("No compatible transfer format found"));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (strcmp (mime_type, "text/plain;charset=utf-8") == 0)
|
||||
{
|
||||
NSString *nsstr = [pasteboard stringForType:NSPasteboardTypeString];
|
||||
|
||||
if (nsstr != NULL)
|
||||
{
|
||||
const char *str = [nsstr UTF8String];
|
||||
stream = g_memory_input_stream_new_from_data (g_strdup (str),
|
||||
strlen (str) + 1,
|
||||
g_free);
|
||||
}
|
||||
}
|
||||
else if (strcmp (mime_type, "text/uri-list") == 0)
|
||||
{
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
|
||||
|
||||
if ([[pasteboard types] containsObject:PTYPE(FILE_URL)])
|
||||
{
|
||||
GString *str = g_string_new (NULL);
|
||||
NSArray *files = [pasteboard propertyListForType:NSFilenamesPboardType];
|
||||
gsize n_files = [files count];
|
||||
char *data;
|
||||
guint len;
|
||||
|
||||
for (gsize i = 0; i < n_files; ++i)
|
||||
{
|
||||
NSString* uriString = [files objectAtIndex:i];
|
||||
uriString = [@"file://" stringByAppendingString:uriString];
|
||||
uriString = [uriString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
|
||||
|
||||
g_string_append_printf (str,
|
||||
"%s\r\n",
|
||||
[uriString cStringUsingEncoding:NSUTF8StringEncoding]);
|
||||
}
|
||||
|
||||
len = str->len;
|
||||
data = g_string_free (str, FALSE);
|
||||
stream = g_memory_input_stream_new_from_data (data, len, g_free);
|
||||
}
|
||||
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS;
|
||||
}
|
||||
else if (strcmp (mime_type, "application/x-color") == 0)
|
||||
{
|
||||
NSColorSpace *colorspace;
|
||||
NSColor *nscolor;
|
||||
guint16 color[4];
|
||||
|
||||
colorspace = [NSColorSpace genericRGBColorSpace];
|
||||
nscolor = [[NSColor colorFromPasteboard:pasteboard]
|
||||
colorUsingColorSpace:colorspace];
|
||||
|
||||
color[0] = 0xffff * [nscolor redComponent];
|
||||
color[1] = 0xffff * [nscolor greenComponent];
|
||||
color[2] = 0xffff * [nscolor blueComponent];
|
||||
color[3] = 0xffff * [nscolor alphaComponent];
|
||||
|
||||
stream = g_memory_input_stream_new_from_data (g_memdup2 (&color, sizeof color),
|
||||
sizeof color,
|
||||
g_free);
|
||||
}
|
||||
else if (strcmp (mime_type, "image/tiff") == 0)
|
||||
{
|
||||
NSData *data = [pasteboard dataForType:PTYPE(TIFF)];
|
||||
stream = create_stream_from_nsdata (data);
|
||||
}
|
||||
else if (strcmp (mime_type, "image/png") == 0)
|
||||
{
|
||||
NSData *data = [pasteboard dataForType:PTYPE(PNG)];
|
||||
stream = create_stream_from_nsdata (data);
|
||||
}
|
||||
|
||||
if (stream != NULL)
|
||||
{
|
||||
g_task_set_task_data (task, g_strdup (mime_type), g_free);
|
||||
g_task_return_pointer (task, g_steal_pointer (&stream), g_object_unref);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_task_return_new_error (task,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_FAILED,
|
||||
_("Failed to decode contents with mime-type of '%s'"),
|
||||
mime_type);
|
||||
}
|
||||
|
||||
cleanup:
|
||||
g_clear_object (&task);
|
||||
g_clear_pointer (&offer_formats, gdk_content_formats_unref);
|
||||
|
||||
GDK_END_MACOS_ALLOC_POOL;
|
||||
}
|
||||
|
||||
GInputStream *
|
||||
_gdk_macos_pasteboard_read_finish (GObject *object,
|
||||
GAsyncResult *result,
|
||||
const char **out_mime_type,
|
||||
GError **error)
|
||||
{
|
||||
GTask *task = (GTask *)result;
|
||||
|
||||
g_assert (G_IS_OBJECT (object));
|
||||
g_assert (G_IS_TASK (task));
|
||||
|
||||
if (out_mime_type != NULL)
|
||||
*out_mime_type = g_strdup (g_task_get_task_data (task));
|
||||
|
||||
return g_task_propagate_pointer (task, error);
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_macos_pasteboard_register_drag_types (NSWindow *window)
|
||||
{
|
||||
[window registerForDraggedTypes:[NSArray arrayWithObjects:PTYPE(STRING),
|
||||
PTYPE(PBOARD),
|
||||
PTYPE(URL),
|
||||
PTYPE(FILE_URL),
|
||||
PTYPE(COLOR),
|
||||
PTYPE(TIFF),
|
||||
PTYPE(PNG),
|
||||
nil]];
|
||||
}
|
||||
|
||||
@implementation GdkMacosPasteboardItemDataProvider
|
||||
|
||||
-(id)initForClipboard:(GdkClipboard*)clipboard withContentProvider:(GdkContentProvider*)contentProvider
|
||||
{
|
||||
[super init];
|
||||
g_set_object (&self->_clipboard, clipboard);
|
||||
g_set_object (&self->_contentProvider, contentProvider);
|
||||
return self;
|
||||
}
|
||||
|
||||
-(id)initForDrag:(GdkDrag*)drag withContentProvider:(GdkContentProvider*)contentProvider
|
||||
{
|
||||
[super init];
|
||||
g_set_object (&self->_drag, drag);
|
||||
g_set_object (&self->_contentProvider, contentProvider);
|
||||
return self;
|
||||
}
|
||||
|
||||
-(void)dealloc
|
||||
{
|
||||
g_clear_object (&self->_contentProvider);
|
||||
g_clear_object (&self->_clipboard);
|
||||
g_clear_object (&self->_drag);
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
-(NSArray<NSPasteboardType> *)types
|
||||
{
|
||||
NSMutableArray *ret = [[NSMutableArray alloc] init];
|
||||
GdkContentFormats *serializable;
|
||||
const char * const *mime_types;
|
||||
gsize n_mime_types;
|
||||
|
||||
serializable = gdk_content_provider_ref_storable_formats (self->_contentProvider);
|
||||
serializable = gdk_content_formats_union_serialize_mime_types (serializable);
|
||||
mime_types = gdk_content_formats_get_mime_types (serializable, &n_mime_types);
|
||||
|
||||
for (gsize i = 0; i < n_mime_types; i++)
|
||||
{
|
||||
const char *mime_type = mime_types[i];
|
||||
NSPasteboardType type;
|
||||
NSPasteboardType alternate = nil;
|
||||
|
||||
if ((type = _gdk_macos_pasteboard_to_ns_type (mime_type, &alternate)))
|
||||
{
|
||||
[ret addObject:type];
|
||||
if (alternate)
|
||||
[ret addObject:alternate];
|
||||
}
|
||||
}
|
||||
|
||||
gdk_content_formats_unref (serializable);
|
||||
|
||||
/* Default to an url type (think gobject://internal)
|
||||
* to support internal, GType-based DnD.
|
||||
*/
|
||||
if (n_mime_types == 0)
|
||||
{
|
||||
GdkContentFormats *formats;
|
||||
gsize n_gtypes;
|
||||
|
||||
formats = gdk_content_provider_ref_formats (self->_contentProvider);
|
||||
gdk_content_formats_get_gtypes (formats, &n_gtypes);
|
||||
|
||||
if (n_gtypes)
|
||||
[ret addObject:NSPasteboardTypeURL];
|
||||
|
||||
gdk_content_formats_unref (formats);
|
||||
}
|
||||
|
||||
return g_steal_pointer (&ret);
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GMemoryOutputStream *stream;
|
||||
NSPasteboardItem *item;
|
||||
NSPasteboardType type;
|
||||
GMainContext *main_context;
|
||||
guint done : 1;
|
||||
} WriteRequest;
|
||||
|
||||
static void
|
||||
write_request_free (WriteRequest *wr)
|
||||
{
|
||||
g_clear_pointer (&wr->main_context, g_main_context_unref);
|
||||
g_clear_object (&wr->stream);
|
||||
[wr->item release];
|
||||
g_slice_free (WriteRequest, wr);
|
||||
}
|
||||
|
||||
static void
|
||||
on_data_ready_cb (GObject *object,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
GDK_BEGIN_MACOS_ALLOC_POOL;
|
||||
|
||||
WriteRequest *wr = user_data;
|
||||
GError *error = NULL;
|
||||
NSData *data = nil;
|
||||
gboolean ret;
|
||||
|
||||
g_assert (G_IS_OBJECT (object));
|
||||
g_assert (GDK_IS_CLIPBOARD (object) || GDK_IS_DRAG (object));
|
||||
g_assert (G_IS_ASYNC_RESULT (result));
|
||||
g_assert (wr != NULL);
|
||||
g_assert (G_IS_MEMORY_OUTPUT_STREAM (wr->stream));
|
||||
g_assert ([wr->item isKindOfClass:[NSPasteboardItem class]]);
|
||||
|
||||
if (GDK_IS_CLIPBOARD (object))
|
||||
ret = gdk_clipboard_write_finish (GDK_CLIPBOARD (object), result, &error);
|
||||
else if (GDK_IS_DRAG (object))
|
||||
ret = gdk_drag_write_finish (GDK_DRAG (object), result, &error);
|
||||
else
|
||||
g_return_if_reached ();
|
||||
|
||||
if (ret)
|
||||
{
|
||||
gsize size;
|
||||
gpointer bytes;
|
||||
|
||||
g_output_stream_close (G_OUTPUT_STREAM (wr->stream), NULL, NULL);
|
||||
|
||||
size = g_memory_output_stream_get_data_size (wr->stream);
|
||||
bytes = g_memory_output_stream_steal_data (wr->stream);
|
||||
data = [[NSData alloc] initWithBytesNoCopy:bytes
|
||||
length:size
|
||||
deallocator:^(void *alloc, NSUInteger length) { g_free (alloc); }];
|
||||
}
|
||||
else
|
||||
{
|
||||
g_warning ("Failed to serialize pasteboard contents: %s",
|
||||
error->message);
|
||||
g_clear_error (&error);
|
||||
}
|
||||
|
||||
[wr->item setData:data forType:wr->type];
|
||||
|
||||
wr->done = TRUE;
|
||||
|
||||
GDK_END_MACOS_ALLOC_POOL;
|
||||
}
|
||||
|
||||
-(void)pasteboard:(NSPasteboard *)pasteboard item:(NSPasteboardItem *)item provideDataForType:(NSPasteboardType)type
|
||||
{
|
||||
const char *mime_type = _gdk_macos_pasteboard_from_ns_type (type);
|
||||
GMainContext *main_context = g_main_context_default ();
|
||||
WriteRequest *wr;
|
||||
|
||||
if (self->_contentProvider == NULL || mime_type == NULL)
|
||||
{
|
||||
[item setData:[NSData data] forType:type];
|
||||
return;
|
||||
}
|
||||
|
||||
wr = g_slice_new0 (WriteRequest);
|
||||
wr->item = [item retain];
|
||||
wr->stream = G_MEMORY_OUTPUT_STREAM (g_memory_output_stream_new_resizable ());
|
||||
wr->type = type;
|
||||
wr->main_context = g_main_context_ref (main_context);
|
||||
wr->done = FALSE;
|
||||
|
||||
if (GDK_IS_CLIPBOARD (self->_clipboard))
|
||||
gdk_clipboard_write_async (self->_clipboard,
|
||||
mime_type,
|
||||
G_OUTPUT_STREAM (wr->stream),
|
||||
G_PRIORITY_DEFAULT,
|
||||
NULL,
|
||||
on_data_ready_cb,
|
||||
wr);
|
||||
else if (GDK_IS_DRAG (self->_drag))
|
||||
gdk_drag_write_async (self->_drag,
|
||||
mime_type,
|
||||
G_OUTPUT_STREAM (wr->stream),
|
||||
G_PRIORITY_DEFAULT,
|
||||
NULL,
|
||||
on_data_ready_cb,
|
||||
wr);
|
||||
else
|
||||
g_return_if_reached ();
|
||||
|
||||
/* We're forced to provide data synchronously via this API
|
||||
* so we must block on the main loop. Using another main loop
|
||||
* than the default tends to get us locked up here, so that is
|
||||
* what we'll do for now.
|
||||
*/
|
||||
while (!wr->done)
|
||||
g_main_context_iteration (wr->main_context, TRUE);
|
||||
|
||||
write_request_free (wr);
|
||||
}
|
||||
|
||||
-(void)pasteboardFinishedWithDataProvider:(NSPasteboard *)pasteboard
|
||||
{
|
||||
g_clear_object (&self->_clipboard);
|
||||
g_clear_object (&self->_drag);
|
||||
g_clear_object (&self->_contentProvider);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation GdkMacosPasteboardItem
|
||||
|
||||
-(id)initForClipboard:(GdkClipboard*)clipboard withContentProvider:(GdkContentProvider*)contentProvider
|
||||
{
|
||||
GdkMacosPasteboardItemDataProvider *dataProvider;
|
||||
|
||||
dataProvider = [[GdkMacosPasteboardItemDataProvider alloc] initForClipboard:clipboard withContentProvider:contentProvider];
|
||||
|
||||
[super init];
|
||||
g_set_object (&self->_clipboard, clipboard);
|
||||
g_set_object (&self->_contentProvider, contentProvider);
|
||||
[self setDataProvider:dataProvider forTypes:[dataProvider types]];
|
||||
|
||||
[dataProvider release];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
-(id)initForDrag:(GdkDrag*)drag withContentProvider:(GdkContentProvider*)contentProvider
|
||||
{
|
||||
GdkMacosPasteboardItemDataProvider *dataProvider;
|
||||
|
||||
dataProvider = [[GdkMacosPasteboardItemDataProvider alloc] initForDrag:drag withContentProvider:contentProvider];
|
||||
|
||||
[super init];
|
||||
g_set_object (&self->_drag, drag);
|
||||
g_set_object (&self->_contentProvider, contentProvider);
|
||||
[self setDataProvider:dataProvider forTypes:[dataProvider types]];
|
||||
|
||||
[dataProvider release];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
-(void)dealloc
|
||||
{
|
||||
g_clear_object (&self->_contentProvider);
|
||||
g_clear_object (&self->_clipboard);
|
||||
g_clear_object (&self->_drag);
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
-(NSRect)draggingFrame
|
||||
{
|
||||
return self->_draggingFrame;
|
||||
}
|
||||
|
||||
-(void)setDraggingFrame:(NSRect)draggingFrame;
|
||||
{
|
||||
self->_draggingFrame = draggingFrame;
|
||||
}
|
||||
|
||||
-(id)item
|
||||
{
|
||||
return self;
|
||||
}
|
||||
|
||||
-(NSArray* (^) (void))imageComponentsProvider
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -195,7 +195,6 @@ gdk_macos_surface_hide (GdkSurface *surface)
|
||||
{
|
||||
GdkMacosSurface *self = (GdkMacosSurface *)surface;
|
||||
GdkSeat *seat;
|
||||
gboolean was_mapped;
|
||||
gboolean was_key;
|
||||
|
||||
g_assert (GDK_IS_MACOS_SURFACE (self));
|
||||
@@ -204,7 +203,6 @@ gdk_macos_surface_hide (GdkSurface *surface)
|
||||
|
||||
_gdk_macos_surface_cancel_frame (self);
|
||||
|
||||
was_mapped = GDK_SURFACE_IS_MAPPED (surface);
|
||||
was_key = [self->window isKeyWindow];
|
||||
|
||||
seat = gdk_display_get_default_seat (surface->display);
|
||||
@@ -285,14 +283,12 @@ gdk_macos_surface_end_frame (GdkMacosSurface *self)
|
||||
{
|
||||
GdkFrameTimings *timings;
|
||||
GdkFrameClock *frame_clock;
|
||||
GdkDisplay *display;
|
||||
|
||||
g_assert (GDK_IS_MACOS_SURFACE (self));
|
||||
|
||||
if (GDK_SURFACE_DESTROYED (self))
|
||||
return;
|
||||
|
||||
display = gdk_surface_get_display (GDK_SURFACE (self));
|
||||
frame_clock = gdk_surface_get_frame_clock (GDK_SURFACE (self));
|
||||
|
||||
if ((timings = gdk_frame_clock_get_current_timings (frame_clock)))
|
||||
@@ -420,7 +416,6 @@ gdk_macos_surface_drag_begin (GdkSurface *surface,
|
||||
GdkMacosSurface *drag_surface;
|
||||
GdkMacosDrag *drag;
|
||||
GdkCursor *cursor;
|
||||
GdkSeat *seat;
|
||||
double px;
|
||||
double py;
|
||||
int sx;
|
||||
@@ -432,12 +427,11 @@ gdk_macos_surface_drag_begin (GdkSurface *surface,
|
||||
g_assert (GDK_IS_MACOS_DEVICE (device));
|
||||
g_assert (GDK_IS_CONTENT_PROVIDER (content));
|
||||
|
||||
seat = gdk_device_get_seat (device);
|
||||
gdk_macos_device_query_state (device, surface, NULL, &px, &py, NULL);
|
||||
_gdk_macos_surface_get_root_coords (GDK_MACOS_SURFACE (surface), &sx, &sy);
|
||||
drag_surface = _gdk_macos_surface_new (GDK_MACOS_DISPLAY (surface->display),
|
||||
GDK_SURFACE_DRAG,
|
||||
surface,
|
||||
NULL,
|
||||
sx, sy, 1, 1);
|
||||
drag = g_object_new (GDK_TYPE_MACOS_DRAG,
|
||||
"drag-surface", drag_surface,
|
||||
@@ -452,7 +446,7 @@ gdk_macos_surface_drag_begin (GdkSurface *surface,
|
||||
gdk_drag_get_selected_action (GDK_DRAG (drag)));
|
||||
gdk_drag_set_cursor (GDK_DRAG (drag), cursor);
|
||||
|
||||
if (!_gdk_macos_drag_begin (drag))
|
||||
if (!_gdk_macos_drag_begin (drag, content, self->window))
|
||||
{
|
||||
g_object_unref (drag);
|
||||
return NULL;
|
||||
|
||||
@@ -19,6 +19,7 @@ gdk_macos_sources = files([
|
||||
'gdkmacoseventsource.c',
|
||||
'gdkmacoskeymap.c',
|
||||
'gdkmacosmonitor.c',
|
||||
'gdkmacospasteboard.c',
|
||||
'gdkmacospopupsurface.c',
|
||||
'gdkmacosseat.c',
|
||||
'gdkmacossurface.c',
|
||||
|
||||
@@ -2,6 +2,236 @@
|
||||
#define __GDK_DEVICE_WAYLAND_PRIVATE_H__
|
||||
|
||||
#include "gdkwaylanddevice.h"
|
||||
#include "gdkwaylandseat.h"
|
||||
|
||||
#include <gdk/gdkdeviceprivate.h>
|
||||
#include <gdk/gdkkeysprivate.h>
|
||||
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
|
||||
struct _GdkWaylandDevice
|
||||
{
|
||||
GdkDevice parent_instance;
|
||||
};
|
||||
|
||||
struct _GdkWaylandDeviceClass
|
||||
{
|
||||
GdkDeviceClass parent_class;
|
||||
};
|
||||
|
||||
typedef struct _GdkWaylandTouchData GdkWaylandTouchData;
|
||||
typedef struct _GdkWaylandPointerFrameData GdkWaylandPointerFrameData;
|
||||
typedef struct _GdkWaylandPointerData GdkWaylandPointerData;
|
||||
typedef struct _GdkWaylandTabletPadGroupData GdkWaylandTabletPadGroupData;
|
||||
typedef struct _GdkWaylandTabletPadData GdkWaylandTabletPadData;
|
||||
typedef struct _GdkWaylandTabletData GdkWaylandTabletData;
|
||||
typedef struct _GdkWaylandTabletToolData GdkWaylandTabletToolData;
|
||||
|
||||
struct _GdkWaylandTouchData
|
||||
{
|
||||
uint32_t id;
|
||||
double x;
|
||||
double y;
|
||||
GdkSurface *surface;
|
||||
uint32_t touch_down_serial;
|
||||
guint initial_touch : 1;
|
||||
};
|
||||
|
||||
struct _GdkWaylandPointerFrameData
|
||||
{
|
||||
GdkEvent *event;
|
||||
|
||||
/* Specific to the scroll event */
|
||||
double delta_x, delta_y;
|
||||
int32_t value120_x, value120_y;
|
||||
gint8 is_scroll_stop;
|
||||
enum wl_pointer_axis_source source;
|
||||
};
|
||||
|
||||
struct _GdkWaylandPointerData {
|
||||
GdkSurface *focus;
|
||||
|
||||
double surface_x, surface_y;
|
||||
|
||||
GdkModifierType button_modifiers;
|
||||
|
||||
uint32_t time;
|
||||
uint32_t enter_serial;
|
||||
uint32_t press_serial;
|
||||
|
||||
GdkSurface *grab_surface;
|
||||
uint32_t grab_time;
|
||||
|
||||
struct wl_surface *pointer_surface;
|
||||
guint cursor_is_default: 1;
|
||||
GdkCursor *cursor;
|
||||
guint cursor_timeout_id;
|
||||
guint cursor_image_index;
|
||||
guint cursor_image_delay;
|
||||
guint touchpad_event_sequence;
|
||||
|
||||
guint current_output_scale;
|
||||
GSList *pointer_surface_outputs;
|
||||
|
||||
/* Accumulated event data for a pointer frame */
|
||||
GdkWaylandPointerFrameData frame;
|
||||
};
|
||||
|
||||
struct _GdkWaylandTabletPadGroupData
|
||||
{
|
||||
GdkWaylandTabletPadData *pad;
|
||||
struct zwp_tablet_pad_group_v2 *wp_tablet_pad_group;
|
||||
GList *rings;
|
||||
GList *strips;
|
||||
GList *buttons;
|
||||
|
||||
guint mode_switch_serial;
|
||||
guint n_modes;
|
||||
guint current_mode;
|
||||
|
||||
struct {
|
||||
guint source;
|
||||
gboolean is_stop;
|
||||
double value;
|
||||
} axis_tmp_info;
|
||||
};
|
||||
|
||||
struct _GdkWaylandTabletPadData
|
||||
{
|
||||
GdkSeat *seat;
|
||||
struct zwp_tablet_pad_v2 *wp_tablet_pad;
|
||||
GdkDevice *device;
|
||||
|
||||
GdkWaylandTabletData *current_tablet;
|
||||
|
||||
guint enter_serial;
|
||||
uint32_t n_buttons;
|
||||
char *path;
|
||||
|
||||
GList *rings;
|
||||
GList *strips;
|
||||
GList *mode_groups;
|
||||
};
|
||||
|
||||
struct _GdkWaylandTabletToolData
|
||||
{
|
||||
GdkSeat *seat;
|
||||
struct zwp_tablet_tool_v2 *wp_tablet_tool;
|
||||
GdkAxisFlags axes;
|
||||
GdkDeviceToolType type;
|
||||
guint64 hardware_serial;
|
||||
guint64 hardware_id_wacom;
|
||||
|
||||
GdkDeviceTool *tool;
|
||||
GdkWaylandTabletData *current_tablet;
|
||||
};
|
||||
|
||||
struct _GdkWaylandTabletData
|
||||
{
|
||||
struct zwp_tablet_v2 *wp_tablet;
|
||||
char *name;
|
||||
char *path;
|
||||
uint32_t vid;
|
||||
uint32_t pid;
|
||||
|
||||
GdkDevice *logical_device;
|
||||
GdkDevice *stylus_device;
|
||||
GdkSeat *seat;
|
||||
GdkWaylandPointerData pointer_info;
|
||||
|
||||
GList *pads;
|
||||
|
||||
GdkWaylandTabletToolData *current_tool;
|
||||
|
||||
int axis_indices[GDK_AXIS_LAST];
|
||||
double axes[GDK_AXIS_LAST];
|
||||
};
|
||||
|
||||
struct _GdkWaylandSeat
|
||||
{
|
||||
GdkSeat parent_instance;
|
||||
|
||||
guint32 id;
|
||||
struct wl_seat *wl_seat;
|
||||
struct wl_pointer *wl_pointer;
|
||||
struct wl_keyboard *wl_keyboard;
|
||||
struct wl_touch *wl_touch;
|
||||
struct zwp_pointer_gesture_swipe_v1 *wp_pointer_gesture_swipe;
|
||||
struct zwp_pointer_gesture_pinch_v1 *wp_pointer_gesture_pinch;
|
||||
struct zwp_pointer_gesture_hold_v1 *wp_pointer_gesture_hold;
|
||||
struct zwp_tablet_seat_v2 *wp_tablet_seat;
|
||||
|
||||
GdkDisplay *display;
|
||||
|
||||
GdkDevice *logical_pointer;
|
||||
GdkDevice *logical_keyboard;
|
||||
GdkDevice *pointer;
|
||||
GdkDevice *wheel_scrolling;
|
||||
GdkDevice *finger_scrolling;
|
||||
GdkDevice *continuous_scrolling;
|
||||
GdkDevice *keyboard;
|
||||
GdkDevice *logical_touch;
|
||||
GdkDevice *touch;
|
||||
GdkCursor *cursor;
|
||||
GdkKeymap *keymap;
|
||||
|
||||
GHashTable *touches;
|
||||
GList *tablets;
|
||||
GList *tablet_tools;
|
||||
GList *tablet_pads;
|
||||
|
||||
GdkWaylandPointerData pointer_info;
|
||||
GdkWaylandPointerData touch_info;
|
||||
|
||||
GdkModifierType key_modifiers;
|
||||
GdkSurface *keyboard_focus;
|
||||
GdkSurface *grab_surface;
|
||||
uint32_t grab_time;
|
||||
gboolean have_server_repeat;
|
||||
uint32_t server_repeat_rate;
|
||||
uint32_t server_repeat_delay;
|
||||
|
||||
struct wl_data_offer *pending_offer;
|
||||
GdkContentFormatsBuilder *pending_builder;
|
||||
GdkDragAction pending_source_actions;
|
||||
GdkDragAction pending_action;
|
||||
|
||||
struct wl_callback *repeat_callback;
|
||||
guint32 repeat_timer;
|
||||
guint32 repeat_key;
|
||||
guint32 repeat_count;
|
||||
gint64 repeat_deadline;
|
||||
uint32_t keyboard_time;
|
||||
uint32_t keyboard_key_serial;
|
||||
|
||||
GdkClipboard *clipboard;
|
||||
GdkClipboard *primary_clipboard;
|
||||
struct wl_data_device *data_device;
|
||||
GdkDrag *drag;
|
||||
GdkDrop *drop;
|
||||
|
||||
/* Some tracking on gesture events */
|
||||
guint gesture_n_fingers;
|
||||
double gesture_scale;
|
||||
|
||||
GdkCursor *grab_cursor;
|
||||
};
|
||||
|
||||
#define GDK_TYPE_WAYLAND_DEVICE_PAD (gdk_wayland_device_pad_get_type ())
|
||||
GType gdk_wayland_device_pad_get_type (void);
|
||||
|
||||
void gdk_wayland_seat_stop_cursor_animation (GdkWaylandSeat *seat,
|
||||
GdkWaylandPointerData *pointer);
|
||||
|
||||
GdkWaylandPointerData * gdk_wayland_device_get_pointer (GdkWaylandDevice *wayland_device);
|
||||
|
||||
void gdk_wayland_device_set_pointer (GdkWaylandDevice *wayland_device,
|
||||
GdkWaylandPointerData *pointer);
|
||||
|
||||
GdkWaylandTouchData * gdk_wayland_device_get_emulating_touch (GdkWaylandDevice *wayland_device);
|
||||
|
||||
void gdk_wayland_device_set_emulating_touch (GdkWaylandDevice *wayland_device,
|
||||
GdkWaylandTouchData *touch);
|
||||
|
||||
void gdk_wayland_device_query_state (GdkDevice *device,
|
||||
GdkSurface *surface,
|
||||
@@ -14,4 +244,24 @@ void gdk_wayland_device_pad_set_feedback (GdkDevice *device,
|
||||
guint feature_idx,
|
||||
const char *label);
|
||||
|
||||
GdkWaylandTabletPadData * gdk_wayland_seat_find_pad (GdkWaylandSeat *seat,
|
||||
GdkDevice *device);
|
||||
|
||||
GdkWaylandTabletData * gdk_wayland_seat_find_tablet (GdkWaylandSeat *seat,
|
||||
GdkDevice *device);
|
||||
|
||||
GdkWaylandTouchData * gdk_wayland_seat_get_touch (GdkWaylandSeat *seat,
|
||||
uint32_t id);
|
||||
|
||||
void gdk_wayland_device_maybe_emit_grab_crossing (GdkDevice *device,
|
||||
GdkSurface *window,
|
||||
guint32 time);
|
||||
|
||||
GdkSurface * gdk_wayland_device_maybe_emit_ungrab_crossing (GdkDevice *device,
|
||||
guint32 time_);
|
||||
|
||||
gboolean gdk_wayland_device_update_surface_cursor (GdkDevice *device);
|
||||
|
||||
GdkModifierType gdk_wayland_device_get_modifiers (GdkDevice *device);
|
||||
|
||||
#endif
|
||||
|
||||
+354
-5059
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,266 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2009 Carlos Garnacho <carlosg@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gdkwaylanddevice.h"
|
||||
#include "gdkdevice-wayland-private.h"
|
||||
|
||||
#include "tablet-unstable-v2-client-protocol.h"
|
||||
|
||||
#include <gdk/gdkdevicepadprivate.h>
|
||||
|
||||
typedef struct _GdkWaylandDevicePad GdkWaylandDevicePad;
|
||||
typedef struct _GdkWaylandDevicePadClass GdkWaylandDevicePadClass;
|
||||
|
||||
struct _GdkWaylandDevicePad
|
||||
{
|
||||
GdkWaylandDevice parent_instance;
|
||||
};
|
||||
|
||||
struct _GdkWaylandDevicePadClass
|
||||
{
|
||||
GdkWaylandDeviceClass parent_class;
|
||||
};
|
||||
|
||||
static void gdk_wayland_device_pad_iface_init (GdkDevicePadInterface *iface);
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (GdkWaylandDevicePad, gdk_wayland_device_pad,
|
||||
GDK_TYPE_WAYLAND_DEVICE,
|
||||
G_IMPLEMENT_INTERFACE (GDK_TYPE_DEVICE_PAD,
|
||||
gdk_wayland_device_pad_iface_init))
|
||||
|
||||
static int
|
||||
gdk_wayland_device_pad_get_n_groups (GdkDevicePad *pad)
|
||||
{
|
||||
GdkSeat *seat = gdk_device_get_seat (GDK_DEVICE (pad));
|
||||
GdkWaylandTabletPadData *data;
|
||||
|
||||
data = gdk_wayland_seat_find_pad (GDK_WAYLAND_SEAT (seat),
|
||||
GDK_DEVICE (pad));
|
||||
#ifdef G_DISABLE_ASSERT
|
||||
if (data == NULL)
|
||||
return 0;
|
||||
#else
|
||||
g_assert (data != NULL);
|
||||
#endif
|
||||
|
||||
return g_list_length (data->mode_groups);
|
||||
}
|
||||
|
||||
static int
|
||||
gdk_wayland_device_pad_get_group_n_modes (GdkDevicePad *pad,
|
||||
int n_group)
|
||||
{
|
||||
GdkSeat *seat = gdk_device_get_seat (GDK_DEVICE (pad));
|
||||
GdkWaylandTabletPadGroupData *group;
|
||||
GdkWaylandTabletPadData *data;
|
||||
|
||||
data = gdk_wayland_seat_find_pad (GDK_WAYLAND_SEAT (seat),
|
||||
GDK_DEVICE (pad));
|
||||
#ifdef G_DISABLE_ASSERT
|
||||
if (data == NULL)
|
||||
return 0;
|
||||
#else
|
||||
g_assert (data != NULL);
|
||||
#endif
|
||||
|
||||
group = g_list_nth_data (data->mode_groups, n_group);
|
||||
if (!group)
|
||||
return -1;
|
||||
|
||||
return group->n_modes;
|
||||
}
|
||||
|
||||
static int
|
||||
gdk_wayland_device_pad_get_n_features (GdkDevicePad *pad,
|
||||
GdkDevicePadFeature feature)
|
||||
{
|
||||
GdkSeat *seat = gdk_device_get_seat (GDK_DEVICE (pad));
|
||||
GdkWaylandTabletPadData *data;
|
||||
|
||||
data = gdk_wayland_seat_find_pad (GDK_WAYLAND_SEAT (seat),
|
||||
GDK_DEVICE (pad));
|
||||
g_assert (data != NULL);
|
||||
|
||||
switch (feature)
|
||||
{
|
||||
case GDK_DEVICE_PAD_FEATURE_BUTTON:
|
||||
return data->n_buttons;
|
||||
case GDK_DEVICE_PAD_FEATURE_RING:
|
||||
return g_list_length (data->rings);
|
||||
case GDK_DEVICE_PAD_FEATURE_STRIP:
|
||||
return g_list_length (data->strips);
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
gdk_wayland_device_pad_get_feature_group (GdkDevicePad *pad,
|
||||
GdkDevicePadFeature feature,
|
||||
int idx)
|
||||
{
|
||||
GdkSeat *seat = gdk_device_get_seat (GDK_DEVICE (pad));
|
||||
GdkWaylandTabletPadGroupData *group;
|
||||
GdkWaylandTabletPadData *data;
|
||||
GList *l;
|
||||
int i;
|
||||
|
||||
data = gdk_wayland_seat_find_pad (GDK_WAYLAND_SEAT (seat),
|
||||
GDK_DEVICE (pad));
|
||||
#ifdef G_DISABLE_ASSERT
|
||||
if (data == NULL)
|
||||
return -1;
|
||||
#else
|
||||
g_assert (data != NULL);
|
||||
#endif
|
||||
|
||||
for (l = data->mode_groups, i = 0; l; l = l->next, i++)
|
||||
{
|
||||
group = l->data;
|
||||
|
||||
switch (feature)
|
||||
{
|
||||
case GDK_DEVICE_PAD_FEATURE_BUTTON:
|
||||
if (g_list_find (group->buttons, GINT_TO_POINTER (idx)))
|
||||
return i;
|
||||
break;
|
||||
case GDK_DEVICE_PAD_FEATURE_RING:
|
||||
{
|
||||
gpointer ring;
|
||||
|
||||
ring = g_list_nth_data (data->rings, idx);
|
||||
if (ring && g_list_find (group->rings, ring))
|
||||
return i;
|
||||
break;
|
||||
}
|
||||
case GDK_DEVICE_PAD_FEATURE_STRIP:
|
||||
{
|
||||
gpointer strip;
|
||||
strip = g_list_nth_data (data->strips, idx);
|
||||
if (strip && g_list_find (group->strips, strip))
|
||||
return i;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_device_pad_iface_init (GdkDevicePadInterface *iface)
|
||||
{
|
||||
iface->get_n_groups = gdk_wayland_device_pad_get_n_groups;
|
||||
iface->get_group_n_modes = gdk_wayland_device_pad_get_group_n_modes;
|
||||
iface->get_n_features = gdk_wayland_device_pad_get_n_features;
|
||||
iface->get_feature_group = gdk_wayland_device_pad_get_feature_group;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_device_pad_class_init (GdkWaylandDevicePadClass *klass)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_device_pad_init (GdkWaylandDevicePad *pad)
|
||||
{
|
||||
}
|
||||
|
||||
static GdkWaylandTabletPadGroupData *
|
||||
tablet_pad_lookup_button_group (GdkWaylandTabletPadData *pad,
|
||||
uint32_t button)
|
||||
{
|
||||
GdkWaylandTabletPadGroupData *group;
|
||||
GList *l;
|
||||
|
||||
for (l = pad->mode_groups; l; l = l->next)
|
||||
{
|
||||
group = l->data;
|
||||
|
||||
if (g_list_find (group->buttons, GUINT_TO_POINTER (button)))
|
||||
return group;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*<private>
|
||||
* gdk_wayland_device_pad_set_feedback:
|
||||
* @device: (type GdkWaylandDevice): a %GDK_SOURCE_TABLET_PAD device
|
||||
* @feature: Feature to set the feedback label for
|
||||
* @feature_idx: 0-indexed index of the feature to set the feedback label for
|
||||
* @label: Feedback label
|
||||
*
|
||||
* Sets the feedback label for the given feature/index.
|
||||
*
|
||||
* This may be used by the compositor to provide user feedback
|
||||
* of the actions available/performed.
|
||||
*/
|
||||
void
|
||||
gdk_wayland_device_pad_set_feedback (GdkDevice *device,
|
||||
GdkDevicePadFeature feature,
|
||||
guint feature_idx,
|
||||
const char *label)
|
||||
{
|
||||
GdkWaylandTabletPadData *pad;
|
||||
GdkWaylandTabletPadGroupData *group;
|
||||
GdkSeat *seat;
|
||||
|
||||
seat = gdk_device_get_seat (device);
|
||||
pad = gdk_wayland_seat_find_pad (GDK_WAYLAND_SEAT (seat), device);
|
||||
if (!pad)
|
||||
return;
|
||||
|
||||
if (feature == GDK_DEVICE_PAD_FEATURE_BUTTON)
|
||||
{
|
||||
group = tablet_pad_lookup_button_group (pad, feature_idx);
|
||||
if (!group)
|
||||
return;
|
||||
|
||||
zwp_tablet_pad_v2_set_feedback (pad->wp_tablet_pad, feature_idx, label,
|
||||
group->mode_switch_serial);
|
||||
}
|
||||
else if (feature == GDK_DEVICE_PAD_FEATURE_RING)
|
||||
{
|
||||
struct zwp_tablet_pad_ring_v2 *wp_pad_ring;
|
||||
|
||||
wp_pad_ring = g_list_nth_data (pad->rings, feature_idx);
|
||||
if (!wp_pad_ring)
|
||||
return;
|
||||
|
||||
group = zwp_tablet_pad_ring_v2_get_user_data (wp_pad_ring);
|
||||
zwp_tablet_pad_ring_v2_set_feedback (wp_pad_ring, label,
|
||||
group->mode_switch_serial);
|
||||
|
||||
}
|
||||
else if (feature == GDK_DEVICE_PAD_FEATURE_STRIP)
|
||||
{
|
||||
struct zwp_tablet_pad_strip_v2 *wp_pad_strip;
|
||||
|
||||
wp_pad_strip = g_list_nth_data (pad->strips, feature_idx);
|
||||
if (!wp_pad_strip)
|
||||
return;
|
||||
|
||||
group = zwp_tablet_pad_strip_v2_get_user_data (wp_pad_strip);
|
||||
zwp_tablet_pad_strip_v2_set_feedback (wp_pad_strip, label,
|
||||
group->mode_switch_serial);
|
||||
}
|
||||
}
|
||||
@@ -49,6 +49,7 @@
|
||||
#include "gdkvulkancontext-wayland.h"
|
||||
#include "gdkwaylandmonitor.h"
|
||||
#include "gdkprofilerprivate.h"
|
||||
#include "gdktoplevel-wayland-private.h"
|
||||
#include <wayland/pointer-gestures-unstable-v1-client-protocol.h>
|
||||
#include "tablet-unstable-v2-client-protocol.h"
|
||||
#include <wayland/xdg-shell-unstable-v6-client-protocol.h>
|
||||
@@ -831,6 +832,8 @@ gdk_wayland_display_get_next_serial (GdkDisplay *display)
|
||||
* if no ID has been defined.
|
||||
*
|
||||
* Returns: (nullable): the startup notification ID for @display
|
||||
*
|
||||
* Deprecated: 4.10.
|
||||
*/
|
||||
const char *
|
||||
gdk_wayland_display_get_startup_notification_id (GdkDisplay *display)
|
||||
@@ -852,6 +855,8 @@ gdk_wayland_display_get_startup_notification_id (GdkDisplay *display)
|
||||
* The startup ID is also what is used to signal that the startup is
|
||||
* complete (for example, when opening a window or when calling
|
||||
* [method@Gdk.Display.notify_startup_complete]).
|
||||
*
|
||||
* Deprecated: 4.10. Use [method@Gdk.Toplevel.set_startup_id]
|
||||
*/
|
||||
void
|
||||
gdk_wayland_display_set_startup_notification_id (GdkDisplay *display,
|
||||
@@ -980,7 +985,9 @@ gdk_wayland_display_class_init (GdkWaylandDisplayClass *class)
|
||||
display_class->queue_events = _gdk_wayland_display_queue_events;
|
||||
display_class->get_app_launch_context = _gdk_wayland_display_get_app_launch_context;
|
||||
display_class->get_next_serial = gdk_wayland_display_get_next_serial;
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
display_class->get_startup_notification_id = gdk_wayland_display_get_startup_notification_id;
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
display_class->notify_startup_complete = gdk_wayland_display_notify_startup_complete;
|
||||
display_class->create_surface = _gdk_wayland_display_create_surface;
|
||||
display_class->get_keymap = _gdk_wayland_display_get_keymap;
|
||||
@@ -2325,6 +2332,7 @@ apply_monitor_change (GdkWaylandMonitor *monitor)
|
||||
monitor->x, monitor->y,
|
||||
monitor->width, monitor->height });
|
||||
gdk_monitor_set_connector (GDK_MONITOR (monitor), monitor->name);
|
||||
gdk_monitor_set_description (GDK_MONITOR (monitor), monitor->description);
|
||||
monitor->wl_output_done = FALSE;
|
||||
monitor->xdg_output_done = FALSE;
|
||||
|
||||
@@ -2381,7 +2389,7 @@ xdg_output_handle_name (void *data,
|
||||
{
|
||||
GdkWaylandMonitor *monitor = (GdkWaylandMonitor *) data;
|
||||
|
||||
GDK_DEBUG (MISC, "handle name xdg-output %d", monitor->id);
|
||||
GDK_DEBUG (MISC, "handle name xdg-output %d: %s", monitor->id, name);
|
||||
|
||||
monitor->name = g_strdup (name);
|
||||
}
|
||||
@@ -2391,8 +2399,11 @@ xdg_output_handle_description (void *data,
|
||||
struct zxdg_output_v1 *xdg_output,
|
||||
const char *description)
|
||||
{
|
||||
GDK_DEBUG (MISC, "handle description xdg-output %d",
|
||||
((GdkWaylandMonitor *)data)->id);
|
||||
GdkWaylandMonitor *monitor = (GdkWaylandMonitor *) data;
|
||||
|
||||
GDK_DEBUG (MISC, "handle description xdg-output %d: %s", monitor->id, description);
|
||||
|
||||
monitor->description = g_strdup (description);
|
||||
}
|
||||
|
||||
static const struct zxdg_output_v1_listener xdg_output_listener = {
|
||||
|
||||
@@ -367,10 +367,10 @@ _gdk_wayland_surface_drag_begin (GdkSurface *surface,
|
||||
GdkWaylandDrag *drag_wayland;
|
||||
GdkDrag *drag;
|
||||
GdkSeat *seat;
|
||||
GdkWaylandDisplay *display_wayland;
|
||||
GdkDisplay *display;
|
||||
GdkCursor *cursor;
|
||||
|
||||
display_wayland = GDK_WAYLAND_DISPLAY (gdk_device_get_display (device));
|
||||
display = gdk_device_get_display (device);
|
||||
seat = gdk_device_get_seat (device);
|
||||
|
||||
drag_wayland = g_object_new (GDK_TYPE_WAYLAND_DRAG,
|
||||
@@ -382,17 +382,13 @@ _gdk_wayland_surface_drag_begin (GdkSurface *surface,
|
||||
|
||||
drag = GDK_DRAG (drag_wayland);
|
||||
|
||||
drag_wayland->dnd_surface = create_dnd_surface (gdk_surface_get_display (surface));
|
||||
drag_wayland->dnd_surface = _gdk_wayland_display_create_surface (display, GDK_SURFACE_DRAG, NULL, 0, 0, 100, 100);
|
||||
drag_wayland->dnd_wl_surface = gdk_wayland_surface_get_wl_surface (drag_wayland->dnd_surface);
|
||||
|
||||
|
||||
gdk_wayland_drag_create_data_source (drag);
|
||||
|
||||
if (display_wayland->data_device_manager_version >=
|
||||
WL_DATA_SOURCE_SET_ACTIONS_SINCE_VERSION)
|
||||
{
|
||||
wl_data_source_set_actions (drag_wayland->data_source,
|
||||
gdk_to_wl_actions (actions));
|
||||
}
|
||||
if (GDK_WAYLAND_DISPLAY (display)->data_device_manager_version >= WL_DATA_SOURCE_SET_ACTIONS_SINCE_VERSION)
|
||||
wl_data_source_set_actions (drag_wayland->data_source, gdk_to_wl_actions (actions));
|
||||
|
||||
gdk_wayland_seat_set_drag (seat, drag);
|
||||
|
||||
|
||||
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Copyright © 2022 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License
|
||||
* as published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gdksurface-wayland.h"
|
||||
|
||||
#include "gdkdeviceprivate.h"
|
||||
#include "gdkdisplay-wayland.h"
|
||||
#include "gdkdragsurfaceprivate.h"
|
||||
#include "gdkeventsprivate.h"
|
||||
#include "gdkframeclockidleprivate.h"
|
||||
#include "gdkglcontext-wayland.h"
|
||||
#include "gdkmonitor-wayland.h"
|
||||
#include "gdkpopupprivate.h"
|
||||
#include "gdkprivate-wayland.h"
|
||||
#include "gdkprivate-wayland.h"
|
||||
#include "gdkseat-wayland.h"
|
||||
#include "gdksurfaceprivate.h"
|
||||
#include "gdktoplevelprivate.h"
|
||||
#include "gdkdevice-wayland-private.h"
|
||||
|
||||
#include <wayland/xdg-shell-unstable-v6-client-protocol.h>
|
||||
#include <wayland/xdg-foreign-unstable-v2-client-protocol.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "gdksurface-wayland-private.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GdkWaylandSurface parent_instance;
|
||||
} GdkWaylandDragSurface;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GdkWaylandSurfaceClass parent_class;
|
||||
} GdkWaylandDragSurfaceClass;
|
||||
|
||||
static void gdk_wayland_drag_surface_iface_init (GdkDragSurfaceInterface *iface);
|
||||
|
||||
#define GDK_IS_WAYLAND_DRAG_SURFACE(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_WAYLAND_DRAG_SURFACE))
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (GdkWaylandDragSurface, gdk_wayland_drag_surface, GDK_TYPE_WAYLAND_SURFACE,
|
||||
G_IMPLEMENT_INTERFACE (GDK_TYPE_DRAG_SURFACE,
|
||||
gdk_wayland_drag_surface_iface_init))
|
||||
|
||||
|
||||
static void
|
||||
gdk_wayland_drag_surface_init (GdkWaylandDragSurface *surface)
|
||||
{
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_wayland_drag_surface_compute_size (GdkSurface *surface)
|
||||
{
|
||||
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
|
||||
|
||||
if (impl->next_layout.surface_geometry_dirty)
|
||||
{
|
||||
gdk_wayland_surface_update_size (surface,
|
||||
impl->next_layout.configured_width,
|
||||
impl->next_layout.configured_height,
|
||||
impl->scale);
|
||||
|
||||
impl->next_layout.surface_geometry_dirty = FALSE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_drag_surface_class_init (GdkWaylandDragSurfaceClass *class)
|
||||
{
|
||||
GdkSurfaceClass *surface_class = GDK_SURFACE_CLASS (class);
|
||||
|
||||
surface_class->compute_size = gdk_wayland_drag_surface_compute_size;
|
||||
}
|
||||
|
||||
static void
|
||||
maybe_notify_mapped (GdkSurface *surface)
|
||||
{
|
||||
if (surface->destroyed)
|
||||
return;
|
||||
|
||||
if (!GDK_SURFACE_IS_MAPPED (surface))
|
||||
gdk_surface_set_is_mapped (surface, TRUE);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_wayland_drag_surface_present (GdkDragSurface *drag_surface,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
GdkSurface *surface = GDK_SURFACE (drag_surface);
|
||||
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
|
||||
|
||||
if (!impl->display_server.wl_surface)
|
||||
gdk_wayland_surface_create_wl_surface (surface);
|
||||
|
||||
impl->next_layout.configured_width = width;
|
||||
impl->next_layout.configured_height = height;
|
||||
impl->next_layout.surface_geometry_dirty = TRUE;
|
||||
gdk_surface_request_layout (surface);
|
||||
|
||||
maybe_notify_mapped (surface);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_drag_surface_iface_init (GdkDragSurfaceInterface *iface)
|
||||
{
|
||||
iface->present = gdk_wayland_drag_surface_present;
|
||||
}
|
||||
|
||||
@@ -46,6 +46,7 @@ gdk_wayland_monitor_finalize (GObject *object)
|
||||
GdkWaylandMonitor *monitor = (GdkWaylandMonitor *)object;
|
||||
|
||||
g_free (monitor->name);
|
||||
g_free (monitor->description);
|
||||
|
||||
g_clear_pointer (&monitor->xdg_output, zxdg_output_v1_destroy);
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ struct _GdkWaylandMonitor {
|
||||
int32_t width;
|
||||
int32_t height;
|
||||
char *name;
|
||||
char *description;
|
||||
gboolean wl_output_done;
|
||||
gboolean xdg_output_done;
|
||||
};
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user