Compare commits
552 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8609cd5686 | |||
| cc5edbbbb2 | |||
| 94d9e34dd3 | |||
| 3dbf5038fa | |||
| 456a2f3bcf | |||
| 8e1fa52d14 | |||
| cbf2feb633 | |||
| afe8ee501c | |||
| 4644dab081 | |||
| b37a69d76c | |||
| 51bc6ce2e4 | |||
| 988ebc2248 | |||
| 9f31e95420 | |||
| 3a076e26f7 | |||
| e3e85fc6f3 | |||
| ad3a35b4c5 | |||
| 454caa3eec | |||
| 0ffe67ffed | |||
| 8eb46bbfb2 | |||
| d8e8b3c235 | |||
| 79f273348d | |||
| fc99081658 | |||
| aba14e6a43 | |||
| 8ebcef97ff | |||
| 00956a3770 | |||
| 1635d9fb78 | |||
| 20fb155e8c | |||
| da59c77ae2 | |||
| 0d0bdaa02e | |||
| 04cf5044da | |||
| b005cd0bbd | |||
| f5379d2047 | |||
| 98c247ec29 | |||
| 38e2f9138d | |||
| 3cc7d9b8c0 | |||
| 1ac9400712 | |||
| 10d5705b70 | |||
| 2d0d579735 | |||
| ac0f524722 | |||
| 2cd0e5f60b | |||
| d83502d054 | |||
| 9e539a7f59 | |||
| c60247f51f | |||
| 06321511ad | |||
| 2e7923cad0 | |||
| 3c66c27caa | |||
| 7f4bd6917e | |||
| b89376da55 | |||
| a1dd6521e8 | |||
| 0088f840fe | |||
| 1b698c896e | |||
| 04000f28e7 | |||
| 976a05f6eb | |||
| b15902bf44 | |||
| 5ac7529771 | |||
| bbf68c0d9d | |||
| eeb3dd3511 | |||
| 7b0ce11e46 | |||
| 8ef1d6a49c | |||
| 7db60f958d | |||
| 30043e072e | |||
| 5ee7606779 | |||
| 25409c5a5a | |||
| 51122dd287 | |||
| ec9159f983 | |||
| f3d77d1c21 | |||
| 1258fcaaf4 | |||
| 00fd60aaa8 | |||
| c7a7d0582a | |||
| b6e7acfb90 | |||
| 40eae298d5 | |||
| 09a9131a10 | |||
| c93c9f5c2a | |||
| 7f08adc23e | |||
| f41012080f | |||
| 786e9d351c | |||
| 3d2cf97fbf | |||
| 1fe6fb6739 | |||
| 6710eb5eb3 | |||
| 80b1d55683 | |||
| 1cebc4316b | |||
| 20895d6f3f | |||
| 65a4118d50 | |||
| 4857829aaa | |||
| 2ea4574caf | |||
| 102b74f9eb | |||
| 8a0d4dfa94 | |||
| b4e645862a | |||
| ea48506a32 | |||
| 23f0a29260 | |||
| 9249717cf4 | |||
| 4196dfc374 | |||
| 23af707b41 | |||
| 421088c3a0 | |||
| 749f1a7c00 | |||
| 344f9fcf05 | |||
| 4c971cd4da | |||
| 43d553dcfb | |||
| 66264f9a3d | |||
| 269f369541 | |||
| 1973019962 | |||
| fe515c4c1c | |||
| 14f0a0addb | |||
| 64a2d0221c | |||
| 0ef91c3ba8 | |||
| 2adcb7be71 | |||
| a332f2402a | |||
| 131a61c51b | |||
| 39d5dd89c5 | |||
| 341efe9a40 | |||
| 5ed6f89b4a | |||
| 4d609149d2 | |||
| 0d790505aa | |||
| a486536925 | |||
| e808fb424a | |||
| 6c54abeca7 | |||
| d24b8a094c | |||
| c46391420f | |||
| 68df7527f7 | |||
| 5a3c3d8210 | |||
| 95ceb49770 | |||
| 0bde58ffd7 | |||
| ccd9827b63 | |||
| db189cfb9f | |||
| 7527f181d5 | |||
| c05b418512 | |||
| e97d996fe4 | |||
| 0537b167ca | |||
| 40446201ff | |||
| fff6b35821 | |||
| 75f2d7583f | |||
| 1fd8d3b487 | |||
| a1216599ff | |||
| 8fff0e0fdf | |||
| 439727a84a | |||
| 3a18a6dddf | |||
| d7050c63ae | |||
| b7c88ec87d | |||
| 5985b62f60 | |||
| e7c29b989c | |||
| 2100e427d9 | |||
| 2550d6dc63 | |||
| ca72fae884 | |||
| 4fc1af14a7 | |||
| 1a30ec6da6 | |||
| e77d519482 | |||
| 59806eee38 | |||
| e6f0103940 | |||
| cbaad3dbd9 | |||
| ee43a6a603 | |||
| 1ac1147ecb | |||
| 1edbc1f1f9 | |||
| 146b4c93ba | |||
| 94f90f457a | |||
| 6b7d56ac49 | |||
| 1635d7be8c | |||
| 992cd088cf | |||
| f6010b2a59 | |||
| 9222a5fd6d | |||
| 6f7fb6ba5a | |||
| a57a144f8e | |||
| 7b47e3225b | |||
| 6aa893e091 | |||
| 5aa03bcb0d | |||
| d7060025e0 | |||
| 00883016af | |||
| f0d8b614d0 | |||
| ddbd574643 | |||
| 5ea3777599 | |||
| a3949763f2 | |||
| 1b961a9ae2 | |||
| d9f6b268d3 | |||
| 934b91f65f | |||
| c3050231d1 | |||
| 4d7a01562e | |||
| 650eed7f72 | |||
| ec8614e8e4 | |||
| cb41b96a9e | |||
| 872b46a527 | |||
| b1c8613dbe | |||
| de6cd4f0d2 | |||
| aec2fb939f | |||
| 69293db804 | |||
| 61a7ebf980 | |||
| f14762b026 | |||
| 187d261400 | |||
| e905f7ff7c | |||
| aefc630d29 | |||
| a5e929ce36 | |||
| 1641d365f5 | |||
| 07d9cd8efe | |||
| 29868b2a05 | |||
| 691b6b88ea | |||
| 2ee1a00177 | |||
| 144cf2d040 | |||
| e1a308d151 | |||
| bbfaacb598 | |||
| d89ff71819 | |||
| 141c725489 | |||
| bbc3aa4ff9 | |||
| f7856f29fd | |||
| 7b69c58deb | |||
| f60d245e32 | |||
| f04e5bd590 | |||
| 90c428b4a7 | |||
| 97b5fad131 | |||
| 285a91715d | |||
| 880468f5a3 | |||
| 6ddbb2a402 | |||
| 7eab565225 | |||
| b34101d45d | |||
| 6c21a7be0b | |||
| a6f2bcb220 | |||
| ef0db01d5c | |||
| ef33ec639c | |||
| 27ca4434e2 | |||
| 9861c7d25c | |||
| 13ef82fc4d | |||
| b33ca43e14 | |||
| 39e07a8d56 | |||
| 5286743cbe | |||
| 58bb998ef0 | |||
| a56b2900dd | |||
| ff34124394 | |||
| 03b60a2d5e | |||
| d939d04885 | |||
| 73fb28a058 | |||
| 65eaf8e8c4 | |||
| beeedb5141 | |||
| 1d40750a60 | |||
| 96baf9769a | |||
| 5044031b53 | |||
| 9f7119ee58 | |||
| c514c41d0e | |||
| 45848c5298 | |||
| 8c61038b9f | |||
| b5cb2f7e41 | |||
| 8af0d4b51f | |||
| 378ad75d48 | |||
| 01d19e2aa4 | |||
| 64e16ecaf1 | |||
| 6a047e53a8 | |||
| 31a7bc70c9 | |||
| 874cae1dab | |||
| 7a3dd41dba | |||
| 149962670a | |||
| 849e3c8b4b | |||
| c9807f5afe | |||
| 9a9899597c | |||
| fecb7af66e | |||
| f5efb15cba | |||
| d7d4fed0f3 | |||
| c2c2635763 | |||
| fb33e83c96 | |||
| 291ad17a22 | |||
| 0f052d46b2 | |||
| 506423cf23 | |||
| 946a496a2e | |||
| d20526570b | |||
| 8312b9d9ca | |||
| 992f092968 | |||
| 60835227a1 | |||
| 2b6b35d91f | |||
| 897164c66c | |||
| 441d944c08 | |||
| 2b8ad6c4b5 | |||
| 99b2da4c47 | |||
| 8243b5493b | |||
| d5ef906cff | |||
| a720d8bc79 | |||
| 57691eacc5 | |||
| 526e24f5b1 | |||
| 2a79152762 | |||
| f03acaf7ab | |||
| 4e7ce9edcf | |||
| ff72619333 | |||
| 59692599ea | |||
| 4761641098 | |||
| afaa275dc8 | |||
| c736deb83b | |||
| e930a20522 | |||
| 137f32f9ef | |||
| 195b98f19a | |||
| 87e0a28482 | |||
| 3ca3d7efef | |||
| d8d8322912 | |||
| 1ea1a70fd2 | |||
| 1d5bc2838b | |||
| 45ec3fc389 | |||
| 3a5eee7dbe | |||
| 0cda6f42b8 | |||
| 0d99ef7cee | |||
| 7583810c90 | |||
| 1341bc0b19 | |||
| fd073deea9 | |||
| 5652ab0a61 | |||
| 2ff23b08be | |||
| 0336af06f1 | |||
| 2af9f1ad62 | |||
| e657da6658 | |||
| fd00aa98ea | |||
| de8a8d7bde | |||
| eb6fbf907f | |||
| 4035f86b6d | |||
| 855b44f2ed | |||
| f2e0097cac | |||
| 7c9bc7a204 | |||
| f4f104c9f9 | |||
| 28a6f0df05 | |||
| 0eab4deab0 | |||
| 6e8e467cc9 | |||
| ca9801f5fb | |||
| 6b6fc1e5d8 | |||
| e3641d0568 | |||
| a5b88a53c2 | |||
| e4d0114e0d | |||
| f974c5343e | |||
| bc39da0619 | |||
| 1995b7f34b | |||
| 36eb7c40d0 | |||
| 56af472cfc | |||
| d1fcfa58b9 | |||
| cf23324749 | |||
| b79c26b39e | |||
| 532b8c71a8 | |||
| 7c5b8911d8 | |||
| e141d61593 | |||
| 9595d440cf | |||
| 1063924bd0 | |||
| 42fedfc870 | |||
| 24836c0351 | |||
| 21b6c8b5d8 | |||
| 41fb6f6a8e | |||
| 071ea6b559 | |||
| 397a71ca8b | |||
| 40c10f83e2 | |||
| fb31581bb4 | |||
| 536a67ec96 | |||
| 53fe751371 | |||
| 7901ab857b | |||
| 8f585f7a53 | |||
| 874b19b27e | |||
| fe7b11b4e9 | |||
| 601dfeeff9 | |||
| cf623ce774 | |||
| 36b49950e8 | |||
| 77feb51b9c | |||
| 710ef00dfe | |||
| 0c8124828f | |||
| 0605c3c167 | |||
| 93d795e7c0 | |||
| d55f938f7c | |||
| 45bb4dc80c | |||
| 53af35d256 | |||
| 51a6b29e01 | |||
| e3835476ba | |||
| 256b094b13 | |||
| 699adb0b10 | |||
| c91b5eaa41 | |||
| 7e1f20bf4c | |||
| f9fe640905 | |||
| 34ea99006f | |||
| 06cce81a97 | |||
| 4a1a7940d5 | |||
| 1108d00014 | |||
| 034672e84e | |||
| 00c885c93c | |||
| 114f0bd8d6 | |||
| 24c67efdfd | |||
| 6a3748146d | |||
| 92ec754737 | |||
| d11fbbc478 | |||
| f11f0da11c | |||
| ebdf2989f8 | |||
| bc35c5d494 | |||
| 70a3e5e8ce | |||
| 74ff61a937 | |||
| 280d7e57bd | |||
| 03f5a368ec | |||
| 0b15aba82a | |||
| d8fa9de93a | |||
| afabbc4957 | |||
| d978ba31d6 | |||
| 71efa96ef2 | |||
| e336fe2bf8 | |||
| d7f15c15e9 | |||
| fff570538c | |||
| 38166a67c7 | |||
| 01b94db73d | |||
| c804645382 | |||
| 384081ce0a | |||
| afccb86f7e | |||
| 0ba5631100 | |||
| c72589f0ee | |||
| f2e5775380 | |||
| a7164208d3 | |||
| 20f3d1608d | |||
| 9320148d71 | |||
| ad617a0e06 | |||
| 62af8365f6 | |||
| 29afe5a688 | |||
| 2d3885a44a | |||
| 75a297632e | |||
| 572649740e | |||
| b5938faa06 | |||
| a4baac7193 | |||
| bdde41e290 | |||
| d888402bf9 | |||
| 378bd9fab2 | |||
| 4ad5e77907 | |||
| 4fb70c5e4d | |||
| d5963ad109 | |||
| b5fe434fea | |||
| 224c2674ab | |||
| 878b34fae3 | |||
| 5fe433418d | |||
| 02ba9bc1da | |||
| 2336120010 | |||
| 0d54d73a51 | |||
| 6c09832b9b | |||
| 1758f88492 | |||
| 34ffdc6e3f | |||
| 108933b655 | |||
| 3344bcaf92 | |||
| f22ec063a1 | |||
| 0fcf01ddd5 | |||
| 1119a74ff0 | |||
| 18ea60e235 | |||
| d752828977 | |||
| 1034271d9a | |||
| f013d3b5d6 | |||
| 5f41d26abc | |||
| 7d5826ccf7 | |||
| 2c9f2325e2 | |||
| daded2bc86 | |||
| bc7619abaf | |||
| 459d6e1349 | |||
| 6e108d310a | |||
| 9c84fa127a | |||
| 84c6708366 | |||
| f7e3016949 | |||
| dd1110ca5c | |||
| 28c4adac24 | |||
| cf20cfd31e | |||
| 7e579bb59a | |||
| 96e1b85c2c | |||
| 71e616d17e | |||
| f85d939e5e | |||
| 8d014d6cb0 | |||
| f7f8990f7a | |||
| d6f288427a | |||
| 2a8f371643 | |||
| dee863dbb2 | |||
| 7d6877ec80 | |||
| f426d23690 | |||
| 6bd0dc3e78 | |||
| 4f0c920a8e | |||
| b0b793dd94 | |||
| efbb649eee | |||
| e128a77eed | |||
| 5cd2ee927a | |||
| 90dfb5e138 | |||
| e854b90293 | |||
| 6d042d9e61 | |||
| 4310f24a4e | |||
| aebf8e3c29 | |||
| fcd449f0d4 | |||
| ab1b117d91 | |||
| 1253296387 | |||
| 466484176f | |||
| 20289ad8e1 | |||
| 0abb8c6862 | |||
| 147386189f | |||
| 9cec9e4ce2 | |||
| 26119af7a6 | |||
| 478d1f71e3 | |||
| b1d952b8a2 | |||
| b9bcdbbfdc | |||
| 6c31ed53f4 | |||
| aa95ae774f | |||
| 65adfd9243 | |||
| c4a8c0893b | |||
| e90f5e8a20 | |||
| 526c76181e | |||
| cf352374ae | |||
| 98b99201b0 | |||
| bce4d669ee | |||
| e7a326e230 | |||
| 9eaeaa8452 | |||
| 2031c5bf90 | |||
| 9fefa7b44c | |||
| a2a70c3b65 | |||
| 0b4ed8d791 | |||
| c34f98931e | |||
| 2feac2772f | |||
| fdda4e4e99 | |||
| e1cf0cff26 | |||
| 634fa772c9 | |||
| 4b3bbe0ecd | |||
| cde43541d0 | |||
| 186287ecfb | |||
| bd5d1615ac | |||
| 21299cc7e4 | |||
| e747ea7dfd | |||
| 810cd7881e | |||
| a8213d7f45 | |||
| e6f6d1e478 | |||
| 933d241bba | |||
| 7249c3a09b | |||
| d13f8ac3a9 | |||
| fa35e3b874 | |||
| 853883c6e5 | |||
| b467279c7d | |||
| c6a5ac1d16 | |||
| e41288de4f | |||
| b886988a54 | |||
| bb8a459fe2 | |||
| d5143a1bf0 | |||
| 12611fa142 | |||
| 3e319b409b | |||
| f2b16836c2 | |||
| 14bf45a0d5 | |||
| 0c6a6b3370 | |||
| 9521f609d8 | |||
| 7533369695 | |||
| f31765d5dd | |||
| d33062795c | |||
| 2da8d9b0ac | |||
| 3f56e8191f | |||
| bf4c3dc2c5 | |||
| a5365ec8cb | |||
| ec94ec0286 | |||
| af0973c847 | |||
| e71f6b0bc0 | |||
| 1738724e4a | |||
| e9e09be37e | |||
| 8a923e02a1 | |||
| 4f12e2f711 | |||
| addcf57b4d | |||
| db08bccb11 | |||
| 02f0681344 | |||
| 62dbadd536 | |||
| 0588db8a69 | |||
| 58b1a13453 | |||
| df70dbbae4 | |||
| 81c55b06d2 | |||
| c95a32def8 | |||
| 7eece7e769 | |||
| 7f6608cbed | |||
| f816a8fb82 | |||
| 3c2484142d | |||
| 0d2ea14ac1 |
@@ -24,7 +24,7 @@ variables:
|
||||
BACKEND_FLAGS: "-Dx11-backend=true -Dwayland-backend=true -Dbroadway-backend=true"
|
||||
FEATURE_FLAGS: "-Dvulkan=enabled -Dcloudproviders=enabled"
|
||||
MESON_TEST_TIMEOUT_MULTIPLIER: 3
|
||||
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v25"
|
||||
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v27"
|
||||
FLATPAK_IMAGE: "registry.gitlab.gnome.org/gnome/gnome-runtime-images/gnome:master"
|
||||
DOCS_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora-docs:v25"
|
||||
|
||||
@@ -43,6 +43,7 @@ style-check-diff:
|
||||
- .gitlab-ci/run-style-check-diff.sh
|
||||
|
||||
.build-fedora-default:
|
||||
extends: .only-default
|
||||
image: $FEDORA_IMAGE
|
||||
artifacts:
|
||||
when: always
|
||||
@@ -121,6 +122,7 @@ installed-tests:
|
||||
|
||||
|
||||
.mingw-defaults:
|
||||
extends: .only-default
|
||||
stage: build
|
||||
tags:
|
||||
- win32-ps
|
||||
@@ -144,6 +146,31 @@ msys2-mingw64:
|
||||
MSYSTEM: "MINGW64"
|
||||
CHERE_INVOKING: "yes"
|
||||
|
||||
macos:
|
||||
extends: .only-default
|
||||
only:
|
||||
- branches@GNOME/gtk
|
||||
stage: build
|
||||
tags:
|
||||
- macos
|
||||
needs: []
|
||||
before_script:
|
||||
- bash .gitlab-ci/show-execution-environment.sh
|
||||
- pip3 install --user meson==0.56
|
||||
- pip3 install --user ninja
|
||||
- export PATH=/Users/gitlabrunner/Library/Python/3.7/bin:$PATH
|
||||
script:
|
||||
- meson -Dx11-backend=false
|
||||
-Dintrospection=disabled
|
||||
-Dcpp_std=c++11
|
||||
-Dpixman:tests=disabled
|
||||
_build
|
||||
- ninja -C _build
|
||||
artifacts:
|
||||
when: always
|
||||
paths:
|
||||
- "${CI_PROJECT_DIR}/_build/meson-logs"
|
||||
|
||||
.flatpak-defaults:
|
||||
image: $FLATPAK_IMAGE
|
||||
stage: flatpak
|
||||
|
||||
@@ -65,6 +65,7 @@ RUN dnf -y install \
|
||||
libxslt \
|
||||
mesa-dri-drivers \
|
||||
mesa-libEGL-devel \
|
||||
mesa-libGLES-devel \
|
||||
mesa-libwayland-egl-devel \
|
||||
ninja-build \
|
||||
pango-devel \
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM registry.gitlab.gnome.org/gnome/gtk/fedora-base:v25
|
||||
FROM registry.gitlab.gnome.org/gnome/gtk/fedora-base:v27
|
||||
|
||||
# Enable sudo for wheel users
|
||||
RUN sed -i -e 's/# %wheel/%wheel/' -e '0,/%wheel/{s/%wheel/# %wheel/}' /etc/sudoers
|
||||
|
||||
@@ -8,7 +8,8 @@ builddir=$1
|
||||
backend=$2
|
||||
|
||||
# Ignore memory leaks lower in dependencies
|
||||
export LSAN_OPTIONS=suppressions=$srcdir/lsan.supp
|
||||
export LSAN_OPTIONS=suppressions=$srcdir/lsan.supp:print_suppressions=0
|
||||
export G_SLICE=always-malloc
|
||||
|
||||
case "${backend}" in
|
||||
x11)
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -eux -o pipefail
|
||||
|
||||
xcodebuild -version || :
|
||||
xcodebuild -showsdks || :
|
||||
|
||||
system_profiler SPSoftwareDataType || :
|
||||
@@ -1,4 +1,13 @@
|
||||
<!--
|
||||
Please, read the CONTRIBUTING.md guide on how to file a new issue.
|
||||
|
||||
https://gitlab.gnome.org/GNOME/gtk/-/blob/master/CONTRIBUTING.md
|
||||
-->
|
||||
## Steps to reproduce
|
||||
<!--
|
||||
Please, explain the sequence of actions necessary to reproduce the
|
||||
bug
|
||||
-->
|
||||
|
||||
1. ...
|
||||
2. ...
|
||||
@@ -32,5 +41,8 @@
|
||||
## Additional information
|
||||
<!--
|
||||
- Screenshots or screen recordings are useful for visual errors
|
||||
- Attaching a screenshot or a video without explaining the current
|
||||
behavior and the actions necessary to reproduce the bug will lead
|
||||
to the bug being closed
|
||||
- Please report any warning or message printed on the terminal
|
||||
-->
|
||||
|
||||
@@ -1,4 +1,14 @@
|
||||
<!--
|
||||
Please, read the CONTRIBUTING.md guide on how to file a new issue.
|
||||
|
||||
https://gitlab.gnome.org/GNOME/gtk/-/blob/master/CONTRIBUTING.md
|
||||
-->
|
||||
|
||||
## Steps to reproduce
|
||||
<!--
|
||||
Please, explain the sequence of actions necessary to reproduce the
|
||||
crash
|
||||
-->
|
||||
|
||||
1. ...
|
||||
2. ...
|
||||
|
||||
@@ -17,7 +17,7 @@ license fees or royalties.
|
||||
|
||||
The official download location
|
||||
|
||||
- https://download.gnome.org/sources/gtk+
|
||||
- https://download.gnome.org/sources/gtk/
|
||||
|
||||
The official web site
|
||||
|
||||
@@ -49,11 +49,11 @@ In order to build GTK you will need:
|
||||
You will also need various dependencies, based on the platform you are
|
||||
building for:
|
||||
|
||||
- [GLib](https://download.gnome.org/sources/glib)
|
||||
- [GdkPixbuf](https://download.gnome.org/sources/gdk-pixbuf)
|
||||
- [GObject-Introspection](https://download.gnome.org/sources/gobject-introspection)
|
||||
- [Cairo](https://www.cairographics.org)
|
||||
- [Pango](https://download.gnome.org/sources/pango)
|
||||
- [GLib](https://download.gnome.org/sources/glib/)
|
||||
- [GdkPixbuf](https://download.gnome.org/sources/gdk-pixbuf/)
|
||||
- [GObject-Introspection](https://download.gnome.org/sources/gobject-introspection/)
|
||||
- [Cairo](https://www.cairographics.org/)
|
||||
- [Pango](https://download.gnome.org/sources/pango/)
|
||||
- [Epoxy](https://github.com/anholt/libepoxy)
|
||||
- [Graphene](https://github.com/ebassi/graphene)
|
||||
- [Xkb-common](https://github.com/xkbcommon/libxkbcommon)
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import os
|
||||
from pathlib import PurePath
|
||||
import subprocess
|
||||
|
||||
stylesheets = [ 'gtk/theme/Adwaita/Adwaita.css',
|
||||
'gtk/theme/Adwaita/Adwaita-dark.css',
|
||||
'gtk/theme/HighContrast/HighContrast.css',
|
||||
'gtk/theme/HighContrast/HighContrast-dark.css' ]
|
||||
|
||||
sourceroot = os.environ.get('MESON_SOURCE_ROOT')
|
||||
distroot = os.environ.get('MESON_DIST_ROOT')
|
||||
|
||||
for stylesheet in stylesheets:
|
||||
stylesheet_path = PurePath(stylesheet)
|
||||
src = PurePath(sourceroot, stylesheet_path.with_suffix('.scss'))
|
||||
dst = PurePath(distroot, stylesheet_path)
|
||||
subprocess.call(['sassc', '-a', '-M', '-t', 'compact', src, dst])
|
||||
@@ -1,20 +1,21 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
|
||||
if 'DESTDIR' not in os.environ:
|
||||
gtk_api_version = sys.argv[1]
|
||||
gtk_abi_version = sys.argv[2]
|
||||
|
||||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
|
||||
if 'DESTDIR' not in os.environ:
|
||||
gtk_api_version = sys.argv[1]
|
||||
gtk_abi_version = sys.argv[2]
|
||||
gtk_libdir = sys.argv[3]
|
||||
gtk_datadir = sys.argv[4]
|
||||
|
||||
gtk_moduledir = os.path.join(gtk_libdir, 'gtk-' + gtk_api_version, gtk_abi_version)
|
||||
gtk_printmodule_dir = os.path.join(gtk_moduledir, 'printbackends')
|
||||
gtk_immodule_dir = os.path.join(gtk_moduledir, 'immodules')
|
||||
|
||||
print('Compiling GSettings schemas...')
|
||||
gtk_bindir = sys.argv[5]
|
||||
|
||||
gtk_moduledir = os.path.join(gtk_libdir, 'gtk-' + gtk_api_version, gtk_abi_version)
|
||||
gtk_printmodule_dir = os.path.join(gtk_moduledir, 'printbackends')
|
||||
gtk_immodule_dir = os.path.join(gtk_moduledir, 'immodules')
|
||||
|
||||
print('Compiling GSettings schemas...')
|
||||
glib_compile_schemas = subprocess.check_output(['pkg-config',
|
||||
'--variable=glib_compile_schemas',
|
||||
'gio-2.0']).strip()
|
||||
@@ -22,13 +23,14 @@ if 'DESTDIR' not in os.environ:
|
||||
# pkg-config variables only available since GLib 2.62.0.
|
||||
glib_compile_schemas = 'glib-compile-schemas'
|
||||
subprocess.call([glib_compile_schemas,
|
||||
os.path.join(gtk_datadir, 'glib-2.0', 'schemas')])
|
||||
|
||||
print('Updating icon cache...')
|
||||
subprocess.call(['gtk4-update-icon-cache', '-q', '-t' ,'-f',
|
||||
os.path.join(gtk_datadir, 'icons', 'hicolor')])
|
||||
|
||||
print('Updating module cache for print backends...')
|
||||
os.path.join(gtk_datadir, 'glib-2.0', 'schemas')])
|
||||
|
||||
print('Updating icon cache...')
|
||||
update_icon_cache = os.path.join(gtk_bindir, 'gtk4-update-icon-cache')
|
||||
subprocess.call([update_icon_cache, '-q', '-t' ,'-f',
|
||||
os.path.join(gtk_datadir, 'icons', 'hicolor')])
|
||||
|
||||
print('Updating module cache for print backends...')
|
||||
os.makedirs(gtk_printmodule_dir, exist_ok=True)
|
||||
gio_querymodules = subprocess.check_output(['pkg-config',
|
||||
'--variable=gio_querymodules',
|
||||
@@ -37,7 +39,7 @@ if 'DESTDIR' not in os.environ:
|
||||
# pkg-config variables only available since GLib 2.62.0.
|
||||
gio_querymodules = 'gio-querymodules'
|
||||
subprocess.call([gio_querymodules, gtk_printmodule_dir])
|
||||
|
||||
print('Updating module cache for input methods...')
|
||||
|
||||
print('Updating module cache for input methods...')
|
||||
os.makedirs(gtk_immodule_dir, exist_ok=True)
|
||||
subprocess.call([gio_querymodules, gtk_immodule_dir])
|
||||
|
||||
@@ -98,6 +98,9 @@ create_page1 (GtkWidget *assistant)
|
||||
gtk_box_append (GTK_BOX (box), label);
|
||||
|
||||
entry = gtk_entry_new ();
|
||||
gtk_accessible_update_relation (GTK_ACCESSIBLE (entry),
|
||||
GTK_ACCESSIBLE_RELATION_LABELLED_BY, label, NULL,
|
||||
-1);
|
||||
gtk_entry_set_activates_default (GTK_ENTRY (entry), TRUE);
|
||||
gtk_widget_set_valign (entry, GTK_ALIGN_CENTER);
|
||||
gtk_box_append (GTK_BOX (box), entry);
|
||||
|
||||
@@ -20,7 +20,7 @@ mainImage(out vec4 fragColor, in vec2 fragCoord, in vec2 resolution, in vec2 uv)
|
||||
float b = 1.0/distance (pos, p2);
|
||||
float sum = r + g + b;
|
||||
|
||||
float alpha = 1.0 - pow (1.0/(sum), 40)*pow (10.0, 40*0.7);
|
||||
float alpha = 1.0 - pow (1.0/(sum), 40.0)*pow (10.0, 40.0*0.7);
|
||||
|
||||
fragColor = vec4 (r*0.5, g*0.5, b*0.5, 1.0) * alpha;
|
||||
}
|
||||
|
||||
@@ -177,7 +177,7 @@ float ccell2(vec2 p, float r) {
|
||||
float df(vec2 p, float scale, inout vec2 nn) {
|
||||
p /= scale;
|
||||
nn = hextile(p);
|
||||
nn = round(nn);
|
||||
nn = floor(nn + 0.5);
|
||||
float r = hash(nn);
|
||||
|
||||
float d;;
|
||||
|
||||
@@ -179,7 +179,7 @@ float ccell2(vec2 p, float r) {
|
||||
float df(vec2 p, float scale, inout vec2 nn) {
|
||||
p /= scale;
|
||||
nn = hextile(p);
|
||||
nn = round(nn);
|
||||
nn = floor(nn + 0.5);
|
||||
float r = hash(nn);
|
||||
|
||||
float d;;
|
||||
|
||||
@@ -119,13 +119,12 @@ create_label (void)
|
||||
static GtkWidget *
|
||||
create_video (void)
|
||||
{
|
||||
GtkMediaStream *stream = gtk_media_file_new_for_resource ("/images/gtk-logo.webm");
|
||||
GtkWidget *w = gtk_picture_new_for_paintable (GDK_PAINTABLE (stream));
|
||||
GtkWidget *w = gtk_video_new ();
|
||||
|
||||
gtk_widget_set_size_request (w, 64, 64);
|
||||
gtk_media_stream_set_loop (stream, TRUE);
|
||||
gtk_media_stream_play (stream);
|
||||
g_object_unref (stream);
|
||||
gtk_video_set_loop (GTK_VIDEO (w), TRUE);
|
||||
gtk_video_set_autoplay (GTK_VIDEO (w), TRUE);
|
||||
gtk_video_set_resource (GTK_VIDEO (w), "/images/gtk-logo.webm");
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
@@ -787,6 +787,8 @@ gtk_gears_realize (GtkWidget *widget)
|
||||
glLinkProgram(program);
|
||||
glGetProgramInfoLog(program, sizeof msg, NULL, msg);
|
||||
g_debug ("program info: %s\n", msg);
|
||||
glDetachShader (program, v);
|
||||
glDetachShader (program, f);
|
||||
glDeleteShader (v);
|
||||
glDeleteShader (f);
|
||||
|
||||
|
||||
@@ -53,31 +53,30 @@
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
<style>
|
||||
<class name="sidebar"/>
|
||||
</style>
|
||||
<property name="width-request">120</property>
|
||||
<property name="hscrollbar-policy">never</property>
|
||||
<property name="min-content-width">150</property>
|
||||
<object class="GtkBox">
|
||||
<property name="width-request">220</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="width-request">220</property>
|
||||
<property name="orientation">vertical</property>
|
||||
|
||||
<object class="GtkSearchBar" id="searchbar">
|
||||
<property name="key-capture-widget">window</property>
|
||||
<child>
|
||||
<object class="GtkSearchBar" id="searchbar">
|
||||
<property name="key-capture-widget">window</property>
|
||||
<child>
|
||||
<object class="GtkSearchEntry" id="search-entry">
|
||||
<accessibility>
|
||||
<relation name="controls">listview</relation>
|
||||
</accessibility>
|
||||
</object>
|
||||
</child>
|
||||
<object class="GtkSearchEntry" id="search-entry">
|
||||
<accessibility>
|
||||
<relation name="controls">listview</relation>
|
||||
</accessibility>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
<style>
|
||||
<class name="sidebar"/>
|
||||
</style>
|
||||
<property name="width-request">120</property>
|
||||
<property name="hscrollbar-policy">never</property>
|
||||
<property name="min-content-width">150</property>
|
||||
<property name="vexpand">1</property>
|
||||
<child>
|
||||
<object class="GtkListView" id="listview">
|
||||
<style>
|
||||
@@ -94,7 +93,6 @@
|
||||
</accessibility>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
|
||||
@@ -31,7 +31,7 @@ void mainImage(out vec4 fragColor, in vec2 fragCoord, in vec2 resolution, in vec
|
||||
float propagation_length = time * wave_speed;
|
||||
|
||||
float t = (propagation_length - distance_from_center) / wave_length;
|
||||
float offset_magnitude = 0;
|
||||
float offset_magnitude = 0.0;
|
||||
if (t > 0.0)
|
||||
offset_magnitude = decay(wave_height * sin(t * 2.0 * PI), t);
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
<property name="right-margin">20</property>
|
||||
<property name="top-margin">20</property>
|
||||
<property name="bottom-margin">20</property>
|
||||
<property name="monospace">1</property>
|
||||
<property name="buffer">
|
||||
<object class="GtkTextBuffer" id="buffer"/>
|
||||
</property>
|
||||
|
||||
@@ -910,6 +910,26 @@ node_editor_window_init (NodeEditorWindow *self)
|
||||
self->text_buffer = gtk_text_buffer_new (self->tag_table);
|
||||
g_signal_connect (self->text_buffer, "changed", G_CALLBACK (text_changed), self);
|
||||
gtk_text_view_set_buffer (GTK_TEXT_VIEW (self->text_view), self->text_buffer);
|
||||
|
||||
/* Default */
|
||||
gtk_text_buffer_set_text (self->text_buffer,
|
||||
"shadow {\n"
|
||||
" child: texture {\n"
|
||||
" bounds: 0 0 128 128;\n"
|
||||
" texture: url(\"resource:///org/gtk/gtk4/node-editor/icons/apps/org.gtk.gtk4.NodeEditor.Devel.svg\");\n"
|
||||
" }\n"
|
||||
" shadows: rgba(0,0,0,0.5) 0 1 12;\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"transform {\n"
|
||||
" child: text {\n"
|
||||
" color: rgb(46,52,54);\n"
|
||||
" font: \"Cantarell Bold 11\";\n"
|
||||
" glyphs: \"GTK Node Editor\";\n"
|
||||
" offset: 8 14.418;\n"
|
||||
" }\n"
|
||||
" transform: translate(0, 140);\n"
|
||||
"}", -1);
|
||||
}
|
||||
|
||||
NodeEditorWindow *
|
||||
|
||||
@@ -3298,7 +3298,6 @@ bad things might happen.</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<object class="GtkSizeGroup" id="basement-indicators"/>
|
||||
<menu id="new_style_menu_model">
|
||||
<section>
|
||||
<attribute name="display-hint">circular-buttons</attribute>
|
||||
|
||||
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 45 KiB |
@@ -146,6 +146,9 @@ images = [
|
||||
'images/nwse_resize_cursor.png',
|
||||
'images/zoom_in_cursor.png',
|
||||
'images/zoom_out_cursor.png',
|
||||
'images/popup-anchors.png',
|
||||
'images/popup-flip.png',
|
||||
'images/popup-slide.png',
|
||||
]
|
||||
|
||||
src_dir = [ gdkinc ]
|
||||
|
||||
|
Before Width: | Height: | Size: 126 KiB After Width: | Height: | Size: 126 KiB |
@@ -98,19 +98,22 @@ gsk_render_node_write_to_file
|
||||
GskScalingFilter
|
||||
gsk_render_node_get_bounds
|
||||
|
||||
<SUBSECTION Nodes>
|
||||
<SUBSECTION>
|
||||
gsk_color_node_new
|
||||
gsk_color_node_get_color
|
||||
gsk_texture_node_new
|
||||
gsk_texture_node_get_texture
|
||||
<SUBSECTION>
|
||||
GskColorStop
|
||||
gsk_linear_gradient_node_new
|
||||
gsk_repeating_linear_gradient_node_new
|
||||
gsk_linear_gradient_node_get_start
|
||||
gsk_linear_gradient_node_get_end
|
||||
gsk_linear_gradient_node_get_n_color_stops
|
||||
gsk_linear_gradient_node_get_color_stops
|
||||
gsk_repeating_linear_gradient_node_new
|
||||
<SUBSECTION>
|
||||
gsk_radial_gradient_node_new
|
||||
gsk_repeating_radial_gradient_node_new
|
||||
gsk_radial_gradient_node_get_n_color_stops
|
||||
gsk_radial_gradient_node_get_color_stops
|
||||
gsk_radial_gradient_node_get_start
|
||||
@@ -118,16 +121,18 @@ gsk_radial_gradient_node_get_end
|
||||
gsk_radial_gradient_node_get_hradius
|
||||
gsk_radial_gradient_node_get_vradius
|
||||
gsk_radial_gradient_node_get_center
|
||||
gsk_repeating_radial_gradient_node_new
|
||||
<SUBSECTION>
|
||||
gsk_conic_gradient_node_new
|
||||
gsk_conic_gradient_node_get_n_color_stops
|
||||
gsk_conic_gradient_node_get_color_stops
|
||||
gsk_conic_gradient_node_get_center
|
||||
gsk_conic_gradient_node_get_rotation
|
||||
<SUBSECTION>
|
||||
gsk_border_node_new
|
||||
gsk_border_node_get_outline
|
||||
gsk_border_node_get_widths
|
||||
gsk_border_node_get_colors
|
||||
<SUBSECTION>
|
||||
gsk_inset_shadow_node_new
|
||||
gsk_inset_shadow_node_get_outline
|
||||
gsk_inset_shadow_node_get_color
|
||||
@@ -135,6 +140,7 @@ gsk_inset_shadow_node_get_dx
|
||||
gsk_inset_shadow_node_get_dy
|
||||
gsk_inset_shadow_node_get_spread
|
||||
gsk_inset_shadow_node_get_blur_radius
|
||||
<SUBSECTION>
|
||||
gsk_outset_shadow_node_new
|
||||
gsk_outset_shadow_node_get_outline
|
||||
gsk_outset_shadow_node_get_color
|
||||
@@ -142,45 +148,57 @@ gsk_outset_shadow_node_get_dx
|
||||
gsk_outset_shadow_node_get_dy
|
||||
gsk_outset_shadow_node_get_spread
|
||||
gsk_outset_shadow_node_get_blur_radius
|
||||
<SUBSECTION>
|
||||
gsk_cairo_node_new
|
||||
gsk_cairo_node_get_draw_context
|
||||
gsk_cairo_node_get_surface
|
||||
<SUBSECTION>
|
||||
gsk_container_node_new
|
||||
gsk_container_node_get_n_children
|
||||
gsk_container_node_get_child
|
||||
<SUBSECTION>
|
||||
gsk_transform_node_new
|
||||
gsk_transform_node_get_child
|
||||
gsk_transform_node_get_transform
|
||||
<SUBSECTION>
|
||||
gsk_opacity_node_new
|
||||
gsk_opacity_node_get_child
|
||||
gsk_opacity_node_get_opacity
|
||||
<SUBSECTION>
|
||||
gsk_color_matrix_node_new
|
||||
gsk_color_matrix_node_get_child
|
||||
gsk_color_matrix_node_get_color_matrix
|
||||
gsk_color_matrix_node_get_color_offset
|
||||
<SUBSECTION>
|
||||
gsk_repeat_node_new
|
||||
gsk_repeat_node_get_child
|
||||
gsk_repeat_node_get_child_bounds
|
||||
<SUBSECTION>
|
||||
gsk_clip_node_new
|
||||
gsk_clip_node_get_child
|
||||
gsk_clip_node_get_clip
|
||||
<SUBSECTION>
|
||||
gsk_rounded_clip_node_new
|
||||
gsk_rounded_clip_node_get_child
|
||||
gsk_rounded_clip_node_get_clip
|
||||
<SUBSECTION>
|
||||
GskShadow
|
||||
gsk_shadow_node_new
|
||||
gsk_shadow_node_get_shadow
|
||||
gsk_shadow_node_get_n_shadows
|
||||
gsk_shadow_node_get_child
|
||||
<SUBSECTION>
|
||||
GskBlendMode
|
||||
gsk_blend_node_new
|
||||
gsk_blend_node_get_bottom_child
|
||||
gsk_blend_node_get_top_child
|
||||
gsk_blend_node_get_blend_mode
|
||||
<SUBSECTION>
|
||||
gsk_cross_fade_node_new
|
||||
gsk_cross_fade_node_get_start_child
|
||||
gsk_cross_fade_node_get_end_child
|
||||
gsk_cross_fade_node_get_progress
|
||||
<SUBSECTION>
|
||||
gsk_text_node_new
|
||||
gsk_text_node_get_font
|
||||
gsk_text_node_get_glyphs
|
||||
@@ -188,12 +206,15 @@ gsk_text_node_get_color
|
||||
gsk_text_node_has_color_glyphs
|
||||
gsk_text_node_get_num_glyphs
|
||||
gsk_text_node_get_offset
|
||||
<SUBSECTION>
|
||||
gsk_blur_node_new
|
||||
gsk_blur_node_get_child
|
||||
gsk_blur_node_get_radius
|
||||
<SUBSECTION>
|
||||
gsk_debug_node_new
|
||||
gsk_debug_node_get_child
|
||||
gsk_debug_node_get_message
|
||||
<SUBSECTION>
|
||||
gsk_gl_shader_node_new
|
||||
gsk_gl_shader_node_get_n_children
|
||||
gsk_gl_shader_node_get_child
|
||||
|
||||
@@ -18,9 +18,9 @@ Length
|
||||
Percentage
|
||||
: %, calc()
|
||||
Angle
|
||||
: deg | grad | turn, calc()
|
||||
: deg, grad, turn, calc()
|
||||
Time
|
||||
: s | ms, calc()
|
||||
: s, ms, calc()
|
||||
|
||||
Length values with the em or ex units are resolved using the font
|
||||
size value, unless they occur in setting the font-size itself, in
|
||||
@@ -32,7 +32,7 @@ not quite the same as the CSS definition of rem.
|
||||
The calc() notation adds considerable expressive power. There are limits
|
||||
on what types can be combined in such an expression (e.g. it does not make
|
||||
sense to add a number and a time). For the full details, see the
|
||||
[CSS3 VAlues and Units](https://www.w3.org/TR/css3-values/#calc-notation)
|
||||
[CSS3 Values and Units](https://www.w3.org/TR/css3-values/#calc-notation)
|
||||
spec.
|
||||
|
||||
A common pattern among shorthand properties (called 'four sides') is one
|
||||
@@ -151,7 +151,7 @@ done with
|
||||
|caret-color|[CSS Basic User Interface Level 3](https://www.w3.org/TR/css3-ui/#caret-color) | CSS allows an auto value |
|
||||
|-gtk-secondary-caret-color|[Color](https://www.w3.org/TR/css-color-3/#valuea-def-color) | used for the secondary caret in bidirectional text |
|
||||
|letter-spacing| [CSS Text Level 3](https://www.w3.org/TR/css3-text/#letter-spacing) | |
|
||||
|text-decoration-line| [CSS Text Decoration Level 3](https://www.w3.org/TR/css-text-decor-3/#text-decoration-line-property) | CSS allows overline |
|
||||
|text-decoration-line| [CSS Text Decoration Level 3](https://www.w3.org/TR/css-text-decor-3/#text-decoration-line-property) | |
|
||||
|text-decoration-color| [CSS Text Decoration Level 3](https://www.w3.org/TR/css-text-decor-3/#text-decoration-color-property) | |
|
||||
|text-decoration-style| [CSS Text Decoration Level 3](https://www.w3.org/TR/css-text-decor-3/#text-decoration-style-property) | CSS allows dashed and dotted |
|
||||
|text-shadow| [CSS Text Decoration Level 3](https://www.w3.org/TR/css-text-decor-3/#text-shadow-property) | |
|
||||
@@ -159,11 +159,12 @@ done with
|
||||
|-gtk-icon-source| [Image](https://www.w3.org/TR/css-backgrounds-3/#typedef-image), `builtin` or `none` | used for builtin icons in buttons and expanders |
|
||||
|-gtk-icon-size| [Length](https://www.w3.org/TR/css3-values/#length-value) | size used for builtin icons in buttons and expanders |
|
||||
|-gtk-icon-style| `requested`, `regular` or `symbolic` | preferred style for application-loaded icons |
|
||||
|-gtk-icon-transform| [Transform list](https://drafts.csswg.org/css-transforms-1/#typedef-transform-list) or `none` | applied to builtin and application-loaded icons |
|
||||
|-gtk-icon-transform| [Transform list](https://www.w3.org/TR/css-transforms-1/#typedef-transform-list) or `none` | applied to builtin and application-loaded icons |
|
||||
|-gtk-icon-palette| Color palette, as explained above | used to recolor symbolic icons |
|
||||
|-gtk-icon-shadow| [Shadow](https://www.w3.org/TR/css-backgrounds-3/#typedef-shadow) or `none` | applied to builtin and application-loaded icons |
|
||||
|-gtk-icon-filter| [Filter value list](https://www.w3.org/TR/filter-effects-1/#typedef-filter-value-list) or `none` | applied to builtin and application-loaded icons |
|
||||
|transform| [CSS Transforms Level 2](https://drafts.csswg.org/css-transforms-2/) | |
|
||||
|transform| [CSS Transforms Level 1](https://www.w3.org/TR/css-transforms-1/#transform-property) | |
|
||||
|transform-origin| [CSS Transforms Level 1](https://www.w3.org/TR/css-transforms-1/#transform-origin-property) | CSS allows specifying a z component|
|
||||
|min-width| [CSS Box Model Level 3](https://www.w3.org/TR/css3-box/#min-width) | CSS allows percentages |
|
||||
|min-height| [CSS Box Model Level 3](https://www.w3.org/TR/css3-box/#min-height) | CSS allows percentages |
|
||||
|margin-top| [CSS Box Model Level 3](https://www.w3.org/TR/css3-box/#margin-top) | CSS allows percentages or auto |
|
||||
@@ -217,7 +218,7 @@ done with
|
||||
|background-size| [CSS Backgrounds and Borders Level 3](https://www.w3.org/TR/css3-background/#background-size) | |
|
||||
|background-position| [CSS Backgrounds and Borders Level 3](https://www.w3.org/TR/css3-background/#background-position) | |
|
||||
|background-repeat| [CSS Backgrounds and Borders Level 3](https://www.w3.org/TR/css3-background/#background-repeat) | |
|
||||
|background-image| [CSS Backgrounds and Borders Level 3](https://www.w3.org/TR/css3-background/#background-image) | not supported: urls without quotes, colors in crossfades |
|
||||
|background-image| [CSS Backgrounds and Borders Level 3](https://www.w3.org/TR/css3-background/#background-image) | not supported: urls without quotes |
|
||||
|box-shadow| [CSS Backgrounds and Borders Level 3](https://www.w3.org/TR/css3-background/#box-shadow) | |
|
||||
|background-blend-mode| [CSS Compositing and Blending Level 1](https://www.w3.org/TR/compositing-1/#propdef-background-blend-mode) | only affects multiple backgrounds |
|
||||
|background| [CSS Backgrounds and Borders Level 3](https://www.w3.org/TR/css3-background/#background) | |
|
||||
@@ -235,4 +236,4 @@ done with
|
||||
|animation-delay| [CSS Animations Level 1](https://www.w3.org/TR/css3-animations/#animation-delay) | |
|
||||
|animation-fill-mode| [CSS Animations Level 1](https://www.w3.org/TR/css3-animations/#animation-fill-mode) | |
|
||||
|animation| [CSS Animations Level 1](https://www.w3.org/TR/css3-animations/#animation) | |
|
||||
|border-spacing| [CSS Table Level 3](https://www.w3.org/TR/css-tables-3/#border-spacing-property) | respected by GtkBox and GtkGrid |
|
||||
|border-spacing| [CSS Table Level 3](https://www.w3.org/TR/css-tables-3/#border-spacing-property) | respected by GtkBoxLayout, GtkGridLayout, GtkCenterLayout |
|
||||
|
||||
@@ -343,20 +343,19 @@ Many widgets, like buttons, do all their drawing themselves. You just tell
|
||||
them the label you want to see, and they figure out what font to use, draw
|
||||
the button outline and focus rectangle, etc. Sometimes, it is necessary to
|
||||
do some custom drawing. In that case, a GtkDrawingArea might be the right
|
||||
widget to use. It offers a canvas on which you can draw by connecting to
|
||||
the ::draw signal.
|
||||
widget to use. It offers a canvas on which you can draw by setting its
|
||||
draw function.
|
||||
|
||||
The contents of a widget often need to be partially or fully redrawn,
|
||||
e.g. when another window is moved and uncovers part of the widget, or
|
||||
when the window containing it is resized. It is also possible to explicitly
|
||||
cause part or all of the widget to be redrawn, by calling
|
||||
gtk_widget_queue_draw() or its variants. GTK takes care of most of the
|
||||
details by providing a ready-to-use cairo context to the ::draw signal
|
||||
handler.
|
||||
cause a widget to be redrawn, by calling gtk_widget_queue_draw(). GTK takes
|
||||
care of most of the details by providing a ready-to-use cairo context to the
|
||||
draw function.
|
||||
|
||||
The following example shows a ::draw signal handler. It is a bit more
|
||||
complicated than the previous examples, since it also demonstrates
|
||||
input event handling by means of event controllers.
|
||||
The following example shows how to use a draw function with GtkDrawingArea.
|
||||
It is a bit more complicated than the previous examples, since it also
|
||||
demonstrates input event handling with event controllers.
|
||||
|
||||

|
||||
|
||||
|
||||
@@ -41,35 +41,41 @@
|
||||
<command>gtk4-builder-tool</command> can perform various operations
|
||||
on GtkBuilder .ui files.
|
||||
</para>
|
||||
<para>
|
||||
The <option>validate</option> command validates the .ui file and reports
|
||||
errors to stderr.
|
||||
</para>
|
||||
<para>
|
||||
The <option>enumerate</option> command lists all the named objects that
|
||||
are created in the .ui file.
|
||||
</para>
|
||||
<para>
|
||||
The <option>preview</option> command displays the .ui file. This command
|
||||
accepts options to specify the ID of the toplevel object and a .css file
|
||||
to use.
|
||||
</para>
|
||||
<para>
|
||||
The <option>simplify</option> command simplifies the .ui file by removing
|
||||
properties that are set to their default values and writes the resulting XML
|
||||
to stdout, or back to the input file.
|
||||
</para>
|
||||
<para>
|
||||
When the <option>--3to4</option> is specified, <option>simplify</option>
|
||||
interprets the input as a GTK 3 ui file and attempts to convert it to GTK 4
|
||||
equivalents. It performs various conversions, such as renaming properties,
|
||||
translating child properties to layout properties, rewriting the setup for
|
||||
GtkNotebook, GtkStack, GtkAssistant or changing toolbars into boxes.
|
||||
</para>
|
||||
<para>
|
||||
You should always test the modified .ui files produced by gtk4-builder-tool
|
||||
before using them in production.
|
||||
</para>
|
||||
</refsect1>
|
||||
|
||||
<refsect1><title>Commands</title>
|
||||
<para>The following commands are understood:</para>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><option>validate</option></term>
|
||||
<listitem><para>Validates the .ui file and report errors to stderr.</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><option>simplify</option></term>
|
||||
<listitem><para>Simplifies the .ui file by removing properties that
|
||||
are set to their default values and write the resulting XML to stdout,
|
||||
or back to the input file.</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><option>enumerate</option></term>
|
||||
<listitem><para>Lists all the named objects that are created in the .ui file.</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><option>preview</option></term>
|
||||
<listitem><para>Preview the .ui file. This command accepts options
|
||||
to specify the ID of an object and a .css file to use.</para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
<para>
|
||||
Note in particular that the conversion
|
||||
done with <option>--3to4</option> is meant as a starting point for a port
|
||||
from GTK 3 to GTK 4. It is expected that you will have to do manual fixups
|
||||
after the initial conversion.
|
||||
</para>
|
||||
</refsect1>
|
||||
|
||||
<refsect1><title>Simplify Options</title>
|
||||
|
||||
@@ -61,6 +61,13 @@
|
||||
<listitem><para>Write png files to <replaceable>DIRECTORY</replaceable>
|
||||
instead of the current working directory.</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--debug</term>
|
||||
<listitem><para>Generate png files of the various channels during
|
||||
the conversion. If these files are not monochrome green, they
|
||||
are often helpful in pinpointing the problematic parts of
|
||||
the source svg.</para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
|
||||
@@ -4668,7 +4668,6 @@ GTK_WINDOW_GET_CLASS
|
||||
<SUBSECTION Private>
|
||||
GtkWindowPrivate
|
||||
gtk_window_get_type
|
||||
GtkWindowGeometryInfo
|
||||
gtk_window_remove_embedded_xid
|
||||
gtk_window_add_embedded_xid
|
||||
GtkWindowKeysForeachFunc
|
||||
|
||||
@@ -19,8 +19,8 @@ gtk_assistant_page_get_type
|
||||
gtk_at_context_get_type
|
||||
gtk_bin_layout_get_type
|
||||
gtk_bitset_get_type
|
||||
gtk_expression_get_type
|
||||
gtk_bookmark_list_get_type
|
||||
gtk_bool_filter_get_type
|
||||
gtk_box_get_type
|
||||
gtk_box_layout_get_type
|
||||
gtk_buildable_get_type
|
||||
@@ -46,6 +46,7 @@ gtk_cell_renderer_spinner_get_type
|
||||
gtk_cell_renderer_text_get_type
|
||||
gtk_cell_renderer_toggle_get_type
|
||||
gtk_cell_view_get_type
|
||||
gtk_center_box_get_type
|
||||
gtk_center_layout_get_type
|
||||
gtk_check_button_get_type
|
||||
gtk_closure_expression_get_type
|
||||
@@ -65,14 +66,16 @@ gtk_constraint_target_get_type
|
||||
gtk_css_provider_get_type
|
||||
gtk_custom_filter_get_type
|
||||
gtk_custom_sorter_get_type
|
||||
gtk_custom_layout_get_type
|
||||
gtk_dialog_get_type
|
||||
gtk_directory_list_get_type
|
||||
gtk_drag_icon_get_type
|
||||
gtk_drag_source_get_type
|
||||
gtk_drawing_area_get_type
|
||||
gtk_drop_target_get_type
|
||||
gtk_drop_target_async_get_type
|
||||
gtk_drop_controller_motion_get_type
|
||||
gtk_drop_down_get_type
|
||||
gtk_drop_target_async_get_type
|
||||
gtk_drop_target_get_type
|
||||
gtk_editable_get_type
|
||||
gtk_editable_label_get_type
|
||||
gtk_emoji_chooser_get_type
|
||||
@@ -87,6 +90,7 @@ gtk_event_controller_motion_get_type
|
||||
gtk_event_controller_scroll_get_type
|
||||
gtk_every_filter_get_type
|
||||
gtk_expander_get_type
|
||||
gtk_expression_get_type
|
||||
gtk_file_chooser_dialog_get_type
|
||||
gtk_file_chooser_get_type
|
||||
gtk_file_chooser_native_get_type
|
||||
@@ -250,6 +254,7 @@ gtk_video_get_type
|
||||
gtk_viewport_get_type
|
||||
gtk_volume_button_get_type
|
||||
gtk_widget_get_type
|
||||
gtk_widget_paintable_get_type
|
||||
gtk_window_get_type
|
||||
gtk_window_controls_get_type
|
||||
gtk_window_group_get_type
|
||||
|
||||
@@ -119,21 +119,18 @@ around or to activate a widget that does not currently have the focus.
|
||||
|
||||
GTK has traditionally supported different kinds of shortcuts:
|
||||
|
||||
Accelerators
|
||||
: Accelerators are any other shortcuts that can be activated regardless
|
||||
of where the focus is, and typically trigger global actions, such as
|
||||
Ctrl-Q to quit an application.
|
||||
Mnmemonics
|
||||
: Mnemonics are usually triggered using Alt as a modifier for a letter.
|
||||
They are used in places where a label is associated with a control,
|
||||
and are indicated by underlining the letter in the label. As a special
|
||||
case, inside menus (i.e. inside #GtkPopoverMenu), mnemonics can be
|
||||
triggered without the modifier.
|
||||
Key bindings
|
||||
: Key bindings are specific to individual widgets, such as Ctrl-C or
|
||||
Ctrl-V in an entry copy to or paste from the clipboard. They are only
|
||||
triggered when the widget has focus.
|
||||
|
||||
- Accelerators are any other shortcuts that can be activated regardless
|
||||
of where the focus is, and typically trigger global actions, such as
|
||||
Ctrl-Q to quit an application.
|
||||
- Mnemonics are usually triggered using Alt as a modifier for a letter.
|
||||
They are used in places where a label is associated with a control,
|
||||
and are indicated by underlining the letter in the label. As a special
|
||||
case, inside menus (i.e. inside #GtkPopoverMenu), mnemonics can be
|
||||
triggered without the modifier.
|
||||
- Key bindings are specific to individual widgets, such as Ctrl-C or
|
||||
Ctrl-V in an entry copy to or paste from the clipboard. They are only
|
||||
triggered when the widget has focus.
|
||||
|
||||
GTK handles accelerators and mnemonics in a global scope, during the
|
||||
capture phase, and key bindings locally, during the target phase.
|
||||
|
||||
|
||||
@@ -413,10 +413,6 @@ images = [
|
||||
'images/password-entry.png',
|
||||
'images/picture.png',
|
||||
'images/popover.png',
|
||||
'images/popup-anchors.png',
|
||||
'images/popup-at.svg',
|
||||
'images/popup-flip.png',
|
||||
'images/popup-slide.png',
|
||||
'images/printdialog.png',
|
||||
'images/progressbar.png',
|
||||
'images/right-center.png',
|
||||
|
||||
@@ -165,11 +165,11 @@ for this change.
|
||||
| ::key-release-event | #GtkEventControllerKey |
|
||||
| ::enter-notify-event | #GtkEventControllerMotion |
|
||||
| ::leave-notify-event | #GtkEventControllerMotion |
|
||||
| ::configure-event | replaced by #GdkSurface::layout |
|
||||
| ::configure-event | - |
|
||||
| ::focus-in-event | #GtkEventControllerFocus |
|
||||
| ::focus-out-event | #GtkEventControllerFocus |
|
||||
| ::map-event | replaced by #GdkSurface:mapped |
|
||||
| ::unmap-event | replaced by #GdkSurface:mapped |
|
||||
| ::map-event | - |
|
||||
| ::unmap-event | - |
|
||||
| ::property-notify-event | replaced by #GdkClipboard |
|
||||
| ::selection-clear-event | replaced by #GdkClipboard |
|
||||
| ::selection-request-event | replaced by #GdkClipboard |
|
||||
@@ -178,10 +178,17 @@ for this change.
|
||||
| ::proximity-in-event | #GtkGestureStylus |
|
||||
| ::proximity-out-event | #GtkGestureStylus |
|
||||
| ::visibility-notify-event | - |
|
||||
| ::window-state-event | replaced by #GdkToplevel:state |
|
||||
| ::window-state-event | - |
|
||||
| ::damage-event | - |
|
||||
| ::grab-broken-event | - |
|
||||
|
||||
Event signals which are not directly related to input have to be dealt
|
||||
with on a one-by-one basis. If you were using ::configure-event and
|
||||
::window-state-event to save window state, you should use property
|
||||
notification for corresponding GtkWindow properties, such as
|
||||
#GtkWindow:default-width, #GtkWindow:default-height, #GtkWindow:maximized
|
||||
or #GtkWindow:fullscreened.
|
||||
|
||||
### Set a proper application ID
|
||||
|
||||
In GTK 4 we want the application's #GApplication 'application-id'
|
||||
@@ -264,14 +271,6 @@ therefore can no longer be used to break reference cycles. A typical sign
|
||||
of a reference cycle involving a toplevel window is when closing the window
|
||||
does not make the application quit.
|
||||
|
||||
A good rule to follow is: If you set a widget pointer with
|
||||
gtk_widget_class_bind_template_child() in class_init(), you need to
|
||||
unparent it in dispose(). The slight complication here is that you need
|
||||
to respect the widget hierarchy while doing so. Ie if you set both `field1`
|
||||
and `field2`, but `field1` is an ancestor of `field2`, then you only need
|
||||
to unparent `field1` — doing so will remove the the entire subtree below
|
||||
`field1`, including `field2`.
|
||||
|
||||
### Stop using GdkScreen
|
||||
|
||||
The GdkScreen object has been removed in GTK 4. Most of its APIs already
|
||||
@@ -407,7 +406,7 @@ and gdk_keymap_get_entries_for_keyval().
|
||||
GTK 3 has the idea that use of modifiers may differ between different
|
||||
platforms, and has a #GdkModifierIntent api to let platforms provide
|
||||
hint about how modifiers are expected to be used. It also promoted
|
||||
the use of <Primary> instead of <Control> to specify accelerators that
|
||||
the use of `<Primary>` instead of `<Control>` to specify accelerators that
|
||||
adapt to platform conventions.
|
||||
|
||||
In GTK 4, the meaning of modifiers has been fixed, and backends are
|
||||
@@ -426,13 +425,88 @@ GDK_CONTROL_MASK|GDK_ALT_MASK
|
||||
: Prevent text input
|
||||
|
||||
Consequently, #GdkModifierIntent and related APIs have been removed,
|
||||
and <Control> is preferred over <Primary> in accelerators.
|
||||
and `<Control>` is preferred over `<Primary>` in accelerators.
|
||||
|
||||
A related change is that GTK 4 no longer supports the use of archaic
|
||||
X11 'real' modifiers with the names Mod1,..., Mod5, and %GDK_MOD1_MASK
|
||||
has been renamed to %GDK_ALT_MASK.
|
||||
|
||||
### Stop using gtk_get_current_... APIs
|
||||
### Replace GtkClipboard with GdkClipboard
|
||||
|
||||
The `GtkClipboard` API has been removed, and replaced by #GdkClipboard.
|
||||
There is not direct 1:1 mapping between the old an the new API, so it cannot
|
||||
be a mechanical replacement; the new API is based on object types and #GValue
|
||||
like object properties, instead of opaque identifiers, so it should be easier
|
||||
to use.
|
||||
|
||||
For instance, the example below copies the contents of an entry into the
|
||||
clipboard:
|
||||
|
||||
```
|
||||
static void
|
||||
copy_text (GtkWidget *widget)
|
||||
{
|
||||
GtkEditable *editable = GTK_EDITABLE (widget);
|
||||
|
||||
// Initialize a GValue with the contents of the widget
|
||||
GValue value = G_VALUE_INIT;
|
||||
g_value_init (&value, G_TYPE_STRING);
|
||||
g_value_set_string (&value, gtk_editable_get_text (editable));
|
||||
|
||||
// Store the value in the clipboard object
|
||||
GdkClipboard *clipboard = gtk_widget_get_clipboard (widget);
|
||||
gdk_clipboard_set_value (clipboard, &value);
|
||||
|
||||
g_value_unset (&value);
|
||||
}
|
||||
```
|
||||
|
||||
whereas the example below pastes the contents into the entry:
|
||||
|
||||
```
|
||||
static void
|
||||
paste_text (GtkWidget *widget)
|
||||
{
|
||||
GtkEditable *editable = GTK_EDITABLE (widget);
|
||||
|
||||
// Initialize a GValue to receive text
|
||||
GValue value = G_VALUE_INIT;
|
||||
g_value_init (&value, G_TYPE_STRING);
|
||||
|
||||
// Get the content provider for the clipboard, and ask it for text
|
||||
GdkClipboard *clipboard = gtk_widget_get_clipboard (widget);
|
||||
GdkContentProvider *provider = gdk_clipboard_get_content (clipboard);
|
||||
|
||||
// If the content provider does not contain text, we are not interested
|
||||
if (!gdk_content_provider_get_value (provider, &value, NULL))
|
||||
return;
|
||||
|
||||
const char *str = g_value_get_string (&value);
|
||||
|
||||
gtk_editable_set_text (editable, str);
|
||||
|
||||
g_value_unset (&value);
|
||||
}
|
||||
```
|
||||
|
||||
The convenience API for specific target types in `GtkClipboard` has been
|
||||
replaced by their corresponding GType:
|
||||
|
||||
| GtkClipboard | GType |
|
||||
| ----------------------------------- | ---------------------- |
|
||||
| `gtk_clipboard_request_text()` | `G_TYPE_STRING` |
|
||||
| `gtk_clipboard_request_rich_text()` | `GTK_TYPE_TEXT_BUFFER` |
|
||||
| `gtk_clipboard_request_image()` | `GDK_TYPE_PIXBUF` |
|
||||
| `gtk_clipboard_request_uris()` |` GDK_TYPE_FILE_LIST` |
|
||||
|
||||
**Note**: Support for rich text serialization across different processes
|
||||
for #GtkTextBuffer is not available any more.
|
||||
|
||||
If you are copying the contents of an image, it is recommended to use
|
||||
GDK_TYPE_PAINTABLE instead of GDK_TYPE_PIXBUF, to minimize the amount of
|
||||
potential copies.
|
||||
|
||||
### Stop using `gtk_get_current_...` APIs
|
||||
|
||||
The function gtk_get_current_event() and its variants have been
|
||||
replaced by equivalent event controller APIs:
|
||||
@@ -448,6 +522,25 @@ option. You should always review the resulting changes.
|
||||
The <requires> tag now supports for the 'lib' attribute the
|
||||
'gtk' value only, instead of the 'gtk+' one previously.
|
||||
|
||||
### Adapt to GtkBuilder API changes
|
||||
|
||||
gtk_builder_connect_signals() no longer exists. Instead, signals are
|
||||
always connected automatically. If you need to add user data to your
|
||||
signals, gtk_builder_set_current_object() must be called. An important
|
||||
caveat is that you have to do this before loading any XML. This means if
|
||||
you need to use gtk_builder_set_current_object(), you can no longer use
|
||||
gtk_builder_new_from_file(), gtk_builder_new_from_resource(), or
|
||||
gtk_builder_new_from_string(). Instead, you must use vanilla gtk_builder_new(),
|
||||
then call gtk_builder_set_current_object(), then load the XML using
|
||||
gtk_builder_add_from_file(), gtk_builder_add_from_resource(), or
|
||||
gtk_builder_add_from_string(). You must check the return value for
|
||||
failure and manually abort with g_error() if something went wrong.
|
||||
|
||||
You only have to worry about this if you were previously using
|
||||
gtk_builder_connect_signals(). If you are using templates, then
|
||||
gtk_widget_init_template() will call gtk_builder_set_current_object()
|
||||
for you, so templates work like before.
|
||||
|
||||
### Adapt to event controller API changes
|
||||
|
||||
A few changes to the event controller and #GtkGesture APIs
|
||||
@@ -458,6 +551,23 @@ Another is that #GtkGestureMultiPress has been renamed to #GtkGestureClick,
|
||||
and has lost its area property. A #GtkEventControllerFocus has been
|
||||
split off from #GtkEventcontrollerKey.
|
||||
|
||||
In GTK 3, #GtkEventController:widget was a construct-only property, so
|
||||
a #GtkWidget was provided whenever constructing a #GtkEventController.
|
||||
In GTK 4, #GtkEventController:widget is now read-only. Use
|
||||
gtk_widget_add_controller() to add an event controller to a widget.
|
||||
|
||||
In GTK 3, widgets did not own their event controllers, and event
|
||||
controllers did not own their widgets, so developers were responsible
|
||||
for manually keeping event controllers alive for the lifetime of their
|
||||
associated widgets. In GTK 4, widgets own their event controllers.
|
||||
gtk_widget_add_controller() takes ownership of the event controller, so
|
||||
there is no longer any need to store a reference to the event controller
|
||||
after it has been added to a widget.
|
||||
|
||||
Although not normally needed, an event controller could be removed from
|
||||
a widget in GTK 3 by destroying the event controller with g_object_unref().
|
||||
In GTK 4, you must use gtk_widget_remove_controller().
|
||||
|
||||
### Focus handling changes
|
||||
|
||||
The semantics of the #GtkWidget:can-focus property have changed.
|
||||
@@ -751,7 +861,8 @@ to get it.
|
||||
The ::size-allocate signal has been removed, since it is easy
|
||||
to misuse. If you need to learn about sizing changes of custom
|
||||
drawing widgets, use the #GtkDrawingArea::resize or #GtkGLArea::resize
|
||||
signals.
|
||||
signals. If you want to track the size of toplevel windows, use
|
||||
property notification for #GtkWindow:default-width and #GtkWindow:default-height.
|
||||
|
||||
### Switch to GtkWidget's children APIs
|
||||
|
||||
@@ -968,6 +1079,11 @@ that wants to override the default handling, you can provide an
|
||||
implementation of the default.activate action in your widgets' action
|
||||
groups.
|
||||
|
||||
### Stop using gtk_widget_grab_default()
|
||||
|
||||
The function gtk_widget_grab_default() has been removed. If you need
|
||||
to mark a widget as default, use gtk_window_set_default_widget() directly.
|
||||
|
||||
### Stop setting ::has-default and ::has-focus in .ui files
|
||||
|
||||
The special handling for the ::has-default and ::has-focus properties
|
||||
@@ -1062,7 +1178,7 @@ to start a drag manually, call gdk_drag_begin().
|
||||
The ::drag-data-get signal has been replaced by the #GtkDragSource::prepare
|
||||
signal, which returns a #GdkContentProvider for the drag operation.
|
||||
|
||||
The destination-side Drag-and-Drop apis in GTK 4 have also been changed
|
||||
The destination-side Drag-and-Drop API in GTK 4 have also been changed
|
||||
to use an event controller, #GtkDropTarget. Instead of calling
|
||||
gtk_drag_dest_set() and connecting to #GtkWidget signals, you create
|
||||
a #GtkDropTarget object, attach it to the widget with
|
||||
@@ -1157,6 +1273,11 @@ shows a #GtkFileChooserNative dialog when clicked; once the file selection
|
||||
has completed, you can update the label of the #GtkButton with the selected
|
||||
file.
|
||||
|
||||
### Adapt to changed GtkSettings properties
|
||||
|
||||
In GTK 3 the #GtkSettings:gtk-cursor-aspect-ratio property of #GtkSettings was
|
||||
a float. In GTK 4 this has been changed to a double.
|
||||
|
||||
## Changes to consider after the switch
|
||||
|
||||
GTK 4 has a number of new features that you may want to take
|
||||
|
||||
@@ -97,11 +97,11 @@ the question you have, this list is a good place to start.
|
||||
#define N_(x) x
|
||||
#define C_(ctx,x) pgettext (ctx, x)
|
||||
|
||||
You use N_() (N stands for no-op) to mark a string for translation in
|
||||
You use `N_()` (N stands for no-op) to mark a string for translation in
|
||||
a location where a function call to gettext() is not allowed, such as
|
||||
in an array initializer. You eventually have to call gettext() on the
|
||||
string to actually fetch the translation. _() both marks the string for
|
||||
translation and actually translates it. The C_() macro (C stands for
|
||||
string to actually fetch the translation. `_()` both marks the string for
|
||||
translation and actually translates it. The `C_()` macro (C stands for
|
||||
context) adds an additional context to the string that is marked for
|
||||
translation, which can help to disambiguate short strings that might
|
||||
need different translations in different parts of your program.
|
||||
@@ -190,7 +190,7 @@ the question you have, this list is a good place to start.
|
||||
encode string literals in UTF-8 by using octal or hexadecimal escapes
|
||||
like `\212` or `\xa8` to encode each byte. This is portable, but
|
||||
modifying the escaped strings is not very convenient. Be careful when
|
||||
mixing hexadecimal escapes with ordinary text; `"\xa8abcd" is a string
|
||||
mixing hexadecimal escapes with ordinary text; `"\xa8abcd"` is a string
|
||||
of length 1 !
|
||||
|
||||
- Runtime conversion
|
||||
|
||||
@@ -182,6 +182,7 @@ G_GNUC_UNUSED static inline void
|
||||
gdk_array(splice) (GdkArray *self,
|
||||
gsize pos,
|
||||
gsize removed,
|
||||
gboolean stolen,
|
||||
_T_ *additions,
|
||||
gsize added)
|
||||
{
|
||||
@@ -192,8 +193,9 @@ gdk_array(splice) (GdkArray *self,
|
||||
g_assert (pos + removed <= size);
|
||||
remaining = size - pos - removed;
|
||||
|
||||
gdk_array(free_elements) (gdk_array(index) (self, pos),
|
||||
gdk_array(index) (self, pos + removed));
|
||||
if (!stolen)
|
||||
gdk_array(free_elements) (gdk_array(index) (self, pos),
|
||||
gdk_array(index) (self, pos + removed));
|
||||
|
||||
gdk_array(reserve) (self, size - removed + added);
|
||||
|
||||
@@ -225,9 +227,9 @@ gdk_array(set_size) (GdkArray *self,
|
||||
{
|
||||
gsize old_size = gdk_array(get_size) (self);
|
||||
if (new_size > old_size)
|
||||
gdk_array(splice) (self, old_size, 0, NULL, new_size - old_size);
|
||||
gdk_array(splice) (self, old_size, 0, FALSE, NULL, new_size - old_size);
|
||||
else
|
||||
gdk_array(splice) (self, new_size, old_size - new_size, NULL, 0);
|
||||
gdk_array(splice) (self, new_size, old_size - new_size, FALSE, NULL, 0);
|
||||
}
|
||||
|
||||
G_GNUC_UNUSED static void
|
||||
@@ -241,6 +243,7 @@ gdk_array(append) (GdkArray *self,
|
||||
gdk_array(splice) (self,
|
||||
gdk_array(get_size) (self),
|
||||
0,
|
||||
FALSE,
|
||||
#ifdef GDK_ARRAY_BY_VALUE
|
||||
value,
|
||||
#else
|
||||
|
||||
@@ -611,17 +611,7 @@ _gdk_device_set_associated_device (GdkDevice *device,
|
||||
g_return_if_fail (GDK_IS_DEVICE (device));
|
||||
g_return_if_fail (associated == NULL || GDK_IS_DEVICE (associated));
|
||||
|
||||
if (device->associated == associated)
|
||||
return;
|
||||
|
||||
if (device->associated)
|
||||
{
|
||||
g_object_unref (device->associated);
|
||||
device->associated = NULL;
|
||||
}
|
||||
|
||||
if (associated)
|
||||
device->associated = g_object_ref (associated);
|
||||
g_set_object (&device->associated, associated);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -280,7 +280,7 @@ gdk_draw_context_get_surface (GdkDrawContext *context)
|
||||
* implementation must use gdk_draw_context_get_frame_region() to query the
|
||||
* region that must be drawn.
|
||||
*
|
||||
* When using GTK+, the widget system automatically places calls to
|
||||
* When using GTK, the widget system automatically places calls to
|
||||
* gdk_draw_context_begin_frame() and gdk_draw_context_end_frame() via the
|
||||
* use of #GskRenderers, so application code does not need to call these
|
||||
* functions explicitly.
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
GType
|
||||
@enum_name@_get_type (void)
|
||||
{
|
||||
static volatile gsize g_define_type_id__volatile = 0;
|
||||
static gsize g_define_type_id__volatile = 0;
|
||||
|
||||
if (g_once_init_enter (&g_define_type_id__volatile))
|
||||
{
|
||||
|
||||
@@ -210,7 +210,7 @@ gdk_event_init (GdkEvent *self)
|
||||
GType
|
||||
gdk_event_get_type (void)
|
||||
{
|
||||
static volatile gsize event_type__volatile;
|
||||
static gsize event_type__volatile;
|
||||
|
||||
if (g_once_init_enter (&event_type__volatile))
|
||||
{
|
||||
@@ -374,7 +374,7 @@ static GType gdk_event_types[GDK_EVENT_LAST];
|
||||
GType \
|
||||
type_name ## _get_type (void) \
|
||||
{ \
|
||||
static volatile gsize gdk_define_event_type_id__volatile; \
|
||||
static gsize gdk_define_event_type_id__volatile; \
|
||||
if (g_once_init_enter (&gdk_define_event_type_id__volatile)) \
|
||||
{ \
|
||||
GType gdk_define_event_type_id = \
|
||||
@@ -452,7 +452,7 @@ gdk_event_init_types_once (void)
|
||||
void
|
||||
gdk_event_init_types (void)
|
||||
{
|
||||
static volatile gsize event_types__volatile;
|
||||
static gsize event_types__volatile;
|
||||
|
||||
if (g_once_init_enter (&event_types__volatile))
|
||||
{
|
||||
@@ -1138,6 +1138,22 @@ gdk_event_get_axes (GdkEvent *event,
|
||||
return GDK_EVENT_GET_CLASS (event)->get_axes (event, axes, n_axes);
|
||||
}
|
||||
|
||||
double *
|
||||
gdk_event_dup_axes (GdkEvent *event)
|
||||
{
|
||||
double *axes;
|
||||
guint n_axes;
|
||||
|
||||
if (gdk_event_get_axes (event, &axes, &n_axes))
|
||||
{
|
||||
double *axes_copy = g_memdup (axes, n_axes * sizeof (double));
|
||||
|
||||
return axes_copy;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_event_get_event_type:
|
||||
* @event: a #GdkEvent
|
||||
|
||||
@@ -603,6 +603,8 @@ void _gdk_event_queue_handle_motion_compression (GdkDisplay *display);
|
||||
void gdk_event_queue_handle_scroll_compression (GdkDisplay *display);
|
||||
void _gdk_event_queue_flush (GdkDisplay *display);
|
||||
|
||||
double * gdk_event_dup_axes (GdkEvent *event);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
@@ -107,6 +107,9 @@ make_program (GdkGLContextProgram *program,
|
||||
|
||||
glLinkProgram (program->program);
|
||||
|
||||
glDetachShader (program->program, vertex_shader);
|
||||
glDetachShader (program->program, fragment_shader);
|
||||
|
||||
glDeleteShader (vertex_shader);
|
||||
glDeleteShader (fragment_shader);
|
||||
|
||||
|
||||
@@ -30,6 +30,37 @@
|
||||
* Popups are positioned relative to their parent surface.
|
||||
* The GdkPopupLayout struct contains information that is
|
||||
* necessary to do so.
|
||||
*
|
||||
* The positioning requires a negotiation with the windowing system,
|
||||
* since it depends on external constraints, such as the position of
|
||||
* the parent surface, and the screen dimensions.
|
||||
*
|
||||
* The basic ingredients are a rectangle on the parent surface,
|
||||
* and the anchor on both that rectangle and the popup. The anchors
|
||||
* specify a side or corner to place next to each other.
|
||||
*
|
||||
* 
|
||||
*
|
||||
* For cases where placing the anchors next to each other would make
|
||||
* the popup extend offscreen, the layout includes some hints for how
|
||||
* to resolve this problem. The hints may suggest to flip the anchor
|
||||
* position to the other side, or to 'slide' the popup along a side,
|
||||
* or to resize it.
|
||||
*
|
||||
* 
|
||||
*
|
||||
* 
|
||||
*
|
||||
* These hints may be combined.
|
||||
*
|
||||
* Ultimatively, it is up to the windowing system to determine the position
|
||||
* and size of the popup. You can learn about the result by calling
|
||||
* gdk_popup_get_position_x(), gdk_popup_get_position_y(),
|
||||
* gdk_popup_get_rect_anchor() and gdk_popup_get_surface_anchor() after the
|
||||
* popup has been presented. This can be used to adjust the rendering. For
|
||||
* example, GtkPopover changes its arrow position accordingly. But you have
|
||||
* to be careful avoid changing the size of the popover, or it has to be
|
||||
* presented again.
|
||||
*/
|
||||
|
||||
struct _GdkPopupLayout
|
||||
|
||||
@@ -436,9 +436,10 @@ gdk_seat_tool_removed (GdkSeat *seat,
|
||||
}
|
||||
|
||||
GdkDeviceTool *
|
||||
gdk_seat_get_tool (GdkSeat *seat,
|
||||
guint64 serial,
|
||||
guint64 hw_id)
|
||||
gdk_seat_get_tool (GdkSeat *seat,
|
||||
guint64 serial,
|
||||
guint64 hw_id,
|
||||
GdkDeviceToolType type)
|
||||
{
|
||||
GdkDeviceTool *match = NULL;
|
||||
GList *tools, *l;
|
||||
@@ -449,7 +450,7 @@ gdk_seat_get_tool (GdkSeat *seat,
|
||||
{
|
||||
GdkDeviceTool *tool = l->data;
|
||||
|
||||
if (tool->serial == serial && tool->hw_id == hw_id)
|
||||
if (tool->serial == serial && tool->hw_id == hw_id && tool->type == type)
|
||||
{
|
||||
match = tool;
|
||||
break;
|
||||
|
||||
@@ -49,7 +49,7 @@ struct _GdkSeatDefaultPrivate
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (GdkSeatDefault, gdk_seat_default, GDK_TYPE_SEAT)
|
||||
|
||||
static void
|
||||
gdk_seat_dispose (GObject *object)
|
||||
gdk_seat_default_dispose (GObject *object)
|
||||
{
|
||||
GdkSeatDefault *seat = GDK_SEAT_DEFAULT (object);
|
||||
GdkSeatDefaultPrivate *priv = gdk_seat_default_get_instance_private (seat);
|
||||
@@ -79,11 +79,7 @@ gdk_seat_dispose (GObject *object)
|
||||
g_object_unref (l->data);
|
||||
}
|
||||
|
||||
if (priv->tools)
|
||||
{
|
||||
g_ptr_array_unref (priv->tools);
|
||||
priv->tools = NULL;
|
||||
}
|
||||
g_clear_pointer (&priv->tools, g_ptr_array_unref);
|
||||
|
||||
g_list_free (priv->physical_pointers);
|
||||
g_list_free (priv->physical_keyboards);
|
||||
@@ -307,7 +303,7 @@ gdk_seat_default_class_init (GdkSeatDefaultClass *klass)
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GdkSeatClass *seat_class = GDK_SEAT_CLASS (klass);
|
||||
|
||||
object_class->dispose = gdk_seat_dispose;
|
||||
object_class->dispose = gdk_seat_default_dispose;
|
||||
|
||||
seat_class->get_capabilities = gdk_seat_default_get_capabilities;
|
||||
|
||||
@@ -442,7 +438,7 @@ gdk_seat_default_remove_tool (GdkSeatDefault *seat,
|
||||
|
||||
priv = gdk_seat_default_get_instance_private (seat);
|
||||
|
||||
if (tool != gdk_seat_get_tool (GDK_SEAT (seat), tool->serial, tool->hw_id))
|
||||
if (tool != gdk_seat_get_tool (GDK_SEAT (seat), tool->serial, tool->hw_id, tool->type))
|
||||
return;
|
||||
|
||||
g_signal_emit_by_name (seat, "tool-removed", tool);
|
||||
|
||||
@@ -75,9 +75,10 @@ void gdk_seat_tool_removed (GdkSeat *seat,
|
||||
GdkDeviceTool *tool);
|
||||
|
||||
GdkDeviceTool *
|
||||
gdk_seat_get_tool (GdkSeat *seat,
|
||||
guint64 serial,
|
||||
guint64 hw_id);
|
||||
gdk_seat_get_tool (GdkSeat *seat,
|
||||
guint64 serial,
|
||||
guint64 hw_id,
|
||||
GdkDeviceToolType type);
|
||||
|
||||
GdkGrabStatus gdk_seat_grab (GdkSeat *seat,
|
||||
GdkSurface *surface,
|
||||
|
||||
@@ -92,6 +92,7 @@ enum {
|
||||
PROP_MAPPED,
|
||||
PROP_WIDTH,
|
||||
PROP_HEIGHT,
|
||||
PROP_SCALE_FACTOR,
|
||||
LAST_PROP
|
||||
};
|
||||
|
||||
@@ -551,6 +552,13 @@ gdk_surface_class_init (GdkSurfaceClass *klass)
|
||||
0, G_MAXINT, 0,
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
properties[PROP_SCALE_FACTOR] =
|
||||
g_param_spec_int ("scale-factor",
|
||||
P_("Scale factor"),
|
||||
P_("Scale factor"),
|
||||
1, G_MAXINT, 1,
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
g_object_class_install_properties (object_class, LAST_PROP, properties);
|
||||
|
||||
/**
|
||||
@@ -782,6 +790,10 @@ gdk_surface_get_property (GObject *object,
|
||||
g_value_set_int (value, surface->height);
|
||||
break;
|
||||
|
||||
case PROP_SCALE_FACTOR:
|
||||
g_value_set_int (value, gdk_surface_get_scale_factor (surface));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
@@ -2545,8 +2557,7 @@ gdk_surface_get_frame_clock (GdkSurface *surface)
|
||||
* value can be used to determine whether to use a pixel resource
|
||||
* with higher resolution data.
|
||||
*
|
||||
* The scale of a surface may change during runtime, if this happens
|
||||
* a configure event will be sent to the toplevel surface.
|
||||
* The scale of a surface may change during runtime.
|
||||
*
|
||||
* Returns: the scale factor
|
||||
*/
|
||||
@@ -2949,8 +2960,8 @@ gdk_surface_request_motion (GdkSurface *surface)
|
||||
* gdk_surface_translate_coordinates:
|
||||
* @from: the origin surface
|
||||
* @to: the target surface
|
||||
* @x: coordinates to translate
|
||||
* @y: coordinates to translate
|
||||
* @x: (inout): coordinates to translate
|
||||
* @y: (inout): coordinates to translate
|
||||
*
|
||||
* Translates the given coordinates from being
|
||||
* relative to the @from surface to being relative
|
||||
@@ -2969,9 +2980,18 @@ gdk_surface_translate_coordinates (GdkSurface *from,
|
||||
double *x,
|
||||
double *y)
|
||||
{
|
||||
double in_x, in_y, out_x, out_y;
|
||||
int x1, y1, x2, y2;
|
||||
GdkSurface *f, *t;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_SURFACE (from), FALSE);
|
||||
g_return_val_if_fail (GDK_IS_SURFACE (to), FALSE);
|
||||
g_return_val_if_fail (x != NULL, FALSE);
|
||||
g_return_val_if_fail (y != NULL, FALSE);
|
||||
|
||||
in_x = *x;
|
||||
in_y = *y;
|
||||
|
||||
x1 = 0;
|
||||
y1 = 0;
|
||||
f = from;
|
||||
@@ -2995,8 +3015,11 @@ gdk_surface_translate_coordinates (GdkSurface *from,
|
||||
if (f != t)
|
||||
return FALSE;
|
||||
|
||||
*x += x1 - x2;
|
||||
*y += y1 - y2;
|
||||
out_x = in_x + (x1 - x2);
|
||||
out_y = in_y + (y1 - y2);
|
||||
|
||||
*x = out_x;
|
||||
*y = out_y;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -316,9 +316,9 @@ gdk_texture_new_for_pixbuf (GdkPixbuf *pixbuf)
|
||||
* @resource_path: the path of the resource file
|
||||
*
|
||||
* Creates a new texture by loading an image from a resource.
|
||||
* The file format is detected automatically, and can be any
|
||||
* format that is supported by the gdk-pixbuf library, such as
|
||||
* JPEG or PNG.
|
||||
* The file format is detected automatically.
|
||||
* The supported formats are PNG and JPEG, though more formats might be
|
||||
* available.
|
||||
*
|
||||
* It is a fatal error if @resource_path does not specify a valid
|
||||
* image resource and the program will abort if that happens.
|
||||
@@ -352,9 +352,9 @@ gdk_texture_new_from_resource (const char *resource_path)
|
||||
* @error: Return location for an error
|
||||
*
|
||||
* Creates a new texture by loading an image from a file.
|
||||
* The file format is detected automatically, and can be any
|
||||
* format that is supported by the gdk-pixbuf library, such as
|
||||
* JPEG or PNG.
|
||||
* The file format is detected automatically.
|
||||
* The supported formats are PNG and JPEG, though more formats might be
|
||||
* available.
|
||||
*
|
||||
* If %NULL is returned, then @error will be set.
|
||||
*
|
||||
|
||||
@@ -67,7 +67,7 @@ void gdk_toplevel_layout_set_fullscreen (GdkToplevelLayout *l
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gdk_toplevel_layout_get_maximized (GdkToplevelLayout *layout,
|
||||
gboolean *maximize);
|
||||
gboolean *maximized);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gdk_toplevel_layout_get_fullscreen (GdkToplevelLayout *layout,
|
||||
|
||||
@@ -78,6 +78,14 @@
|
||||
*/
|
||||
#define GDK_VERSION_4_0 (G_ENCODE_VERSION (4, 0))
|
||||
|
||||
/**
|
||||
* GDK_VERSION_4_2:
|
||||
*
|
||||
* A macro that evaluates to the 4.2 version of GDK, in a format
|
||||
* that can be used by the C pre-processor.
|
||||
*/
|
||||
#define GDK_VERSION_4_2 (G_ENCODE_VERSION (4, 2))
|
||||
|
||||
|
||||
/* evaluates to the current stable version; for development cycles,
|
||||
* this means the next stable target, with a hard backstop to the
|
||||
@@ -175,4 +183,19 @@
|
||||
# define GDK_DEPRECATED_IN_4_0_FOR(f) _GDK_EXTERN
|
||||
#endif
|
||||
|
||||
|
||||
#if GDK_VERSION_MAX_ALLOWED < GDK_VERSION_4_2
|
||||
# define GDK_AVAILABLE_IN_4_2 GDK_UNAVAILABLE(4, 2)
|
||||
#else
|
||||
# define GDK_AVAILABLE_IN_4_2 _GDK_EXTERN
|
||||
#endif
|
||||
|
||||
#if GDK_VERSION_MIN_REQUIRED >= GDK_VERSION_4_2
|
||||
# define GDK_DEPRECATED_IN_4_2 GDK_DEPRECATED
|
||||
# define GDK_DEPRECATED_IN_4_2_FOR(f) GDK_DEPRECATED_FOR(f)
|
||||
#else
|
||||
# define GDK_DEPRECATED_IN_4_2 _GDK_EXTERN
|
||||
# define GDK_DEPRECATED_IN_4_2_FOR(f) _GDK_EXTERN
|
||||
#endif
|
||||
|
||||
#endif /* __GDK_VERSION_MACROS_H__ */
|
||||
|
||||
@@ -210,8 +210,10 @@ gdk_vulkan_strerror (VkResult result)
|
||||
return "An unknown error has occurred; either the application has provided invalid input, or an implementation failure has occurred.";
|
||||
#endif
|
||||
#if VK_HEADER_VERSION >= 135
|
||||
#if VK_HEADER_VERSION < 162
|
||||
case VK_ERROR_INCOMPATIBLE_VERSION_KHR:
|
||||
return "Acceleration structure serialized with version as the version information is not compatible with device.";
|
||||
return "This error was removed by the Vulkan gods.";
|
||||
#endif
|
||||
case VK_THREAD_IDLE_KHR:
|
||||
return "A deferred operation is not complete but there is currently no work for this thread to do at the time of this call.";
|
||||
case VK_THREAD_DONE_KHR:
|
||||
|
||||
@@ -38,6 +38,10 @@
|
||||
#include "gdkmonitorprivate.h"
|
||||
#include "gdksurfaceprivate.h"
|
||||
|
||||
#ifndef AVAILABLE_MAC_OS_X_VERSION_10_15_AND_LATER
|
||||
typedef NSString *CALayerContentsGravity;
|
||||
#endif
|
||||
|
||||
@implementation GdkMacosWindow
|
||||
|
||||
-(BOOL)windowShouldClose:(id)sender
|
||||
@@ -466,7 +470,7 @@
|
||||
|
||||
inTrackManualResize = YES;
|
||||
|
||||
mouse_location = [self convertPointToScreen:[self mouseLocationOutsideOfEventStream]];
|
||||
mouse_location = convert_nspoint_to_screen (self, [self mouseLocationOutsideOfEventStream]);
|
||||
mdx = initialResizeLocation.x - mouse_location.x;
|
||||
mdy = initialResizeLocation.y - mouse_location.y;
|
||||
|
||||
@@ -588,7 +592,7 @@
|
||||
}
|
||||
|
||||
initialResizeFrame = [self frame];
|
||||
initialResizeLocation = [self convertPointToScreen:[self mouseLocationOutsideOfEventStream]];
|
||||
initialResizeLocation = convert_nspoint_to_screen (self, [self mouseLocationOutsideOfEventStream]);
|
||||
}
|
||||
|
||||
-(NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
|
||||
|
||||
@@ -27,6 +27,10 @@
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#ifndef AVAILABLE_MAC_OS_X_VERSION_10_13_AND_LATER
|
||||
typedef NSString *NSPasteboardType;
|
||||
#endif
|
||||
|
||||
#define GDK_TYPE_MACOS_CLIPBOARD (_gdk_macos_clipboard_get_type())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (GdkMacosClipboard, _gdk_macos_clipboard, GDK, MACOS_CLIPBOARD, GdkClipboard)
|
||||
|
||||
@@ -40,8 +40,56 @@ typedef struct
|
||||
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)
|
||||
{
|
||||
@@ -56,17 +104,17 @@ _gdk_macos_clipboard_from_ns_type (NSPasteboardType type)
|
||||
{
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
|
||||
|
||||
if ([type isEqualToString:NSPasteboardTypeString] ||
|
||||
[type isEqualToString:NSStringPboardType])
|
||||
if ([type isEqualToString:PTYPE(STRING)] ||
|
||||
[type isEqualToString:PTYPE(PBOARD)])
|
||||
return g_intern_string ("text/plain;charset=utf-8");
|
||||
else if ([type isEqualToString:NSPasteboardTypeURL] ||
|
||||
[type isEqualToString:NSPasteboardTypeFileURL])
|
||||
else if ([type isEqualToString:PTYPE(URL)] ||
|
||||
[type isEqualToString:PTYPE(FILE_URL)])
|
||||
return g_intern_string ("text/uri-list");
|
||||
else if ([type isEqualToString:NSPasteboardTypeColor])
|
||||
else if ([type isEqualToString:PTYPE(COLOR)])
|
||||
return g_intern_string ("application/x-color");
|
||||
else if ([type isEqualToString:NSPasteboardTypeTIFF])
|
||||
else if ([type isEqualToString:PTYPE(TIFF)])
|
||||
return g_intern_string ("image/tiff");
|
||||
else if ([type isEqualToString:NSPasteboardTypePNG])
|
||||
else if ([type isEqualToString:PTYPE(PNG)])
|
||||
return g_intern_string ("image/png");
|
||||
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS;
|
||||
@@ -83,25 +131,25 @@ _gdk_macos_clipboard_to_ns_type (const char *mime_type,
|
||||
|
||||
if (g_strcmp0 (mime_type, "text/plain;charset=utf-8") == 0)
|
||||
{
|
||||
return NSPasteboardTypeString;
|
||||
return PTYPE(STRING);
|
||||
}
|
||||
else if (g_strcmp0 (mime_type, "text/uri-list") == 0)
|
||||
{
|
||||
if (alternate)
|
||||
*alternate = NSPasteboardTypeURL;
|
||||
return NSPasteboardTypeFileURL;
|
||||
*alternate = PTYPE(URL);
|
||||
return PTYPE(FILE_URL);
|
||||
}
|
||||
else if (g_strcmp0 (mime_type, "application/x-color") == 0)
|
||||
{
|
||||
return NSPasteboardTypeColor;
|
||||
return PTYPE(COLOR);
|
||||
}
|
||||
else if (g_strcmp0 (mime_type, "image/tiff") == 0)
|
||||
{
|
||||
return NSPasteboardTypeTIFF;
|
||||
return PTYPE(TIFF);
|
||||
}
|
||||
else if (g_strcmp0 (mime_type, "image/png") == 0)
|
||||
{
|
||||
return NSPasteboardTypePNG;
|
||||
return PTYPE(PNG);
|
||||
}
|
||||
|
||||
return nil;
|
||||
@@ -220,7 +268,7 @@ _gdk_macos_clipboard_read_async (GdkClipboard *clipboard,
|
||||
{
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
|
||||
|
||||
if ([[self->pasteboard types] containsObject:NSPasteboardTypeFileURL])
|
||||
if ([[self->pasteboard types] containsObject:PTYPE(FILE_URL)])
|
||||
{
|
||||
GString *str = g_string_new (NULL);
|
||||
NSArray *files = [self->pasteboard propertyListForType:NSFilenamesPboardType];
|
||||
@@ -267,12 +315,12 @@ _gdk_macos_clipboard_read_async (GdkClipboard *clipboard,
|
||||
}
|
||||
else if (strcmp (mime_type, "image/tiff") == 0)
|
||||
{
|
||||
NSData *data = [self->pasteboard dataForType:NSPasteboardTypeTIFF];
|
||||
NSData *data = [self->pasteboard dataForType:PTYPE(TIFF)];
|
||||
stream = create_stream_from_nsdata (data);
|
||||
}
|
||||
else if (strcmp (mime_type, "image/png") == 0)
|
||||
{
|
||||
NSData *data = [self->pasteboard dataForType:NSPasteboardTypePNG];
|
||||
NSData *data = [self->pasteboard dataForType:PTYPE(PNG)];
|
||||
stream = create_stream_from_nsdata (data);
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "gdkmacosdisplay-private.h"
|
||||
#include "gdkmacoskeymap-private.h"
|
||||
#include "gdkmacossurface-private.h"
|
||||
#include "gdkmacosseat-private.h"
|
||||
|
||||
#define GDK_MOD2_MASK (1 << 4)
|
||||
#define GRIP_WIDTH 15
|
||||
@@ -205,6 +206,9 @@ fill_button_event (GdkMacosDisplay *display,
|
||||
GdkSeat *seat;
|
||||
GdkEventType type;
|
||||
GdkModifierType state;
|
||||
GdkDevice *pointer = NULL;
|
||||
GdkDeviceTool *tool = NULL;
|
||||
double *axes = NULL;
|
||||
|
||||
g_assert (GDK_IS_MACOS_DISPLAY (display));
|
||||
g_assert (GDK_IS_MACOS_SURFACE (surface));
|
||||
@@ -241,16 +245,22 @@ fill_button_event (GdkMacosDisplay *display,
|
||||
y < 0 || y > GDK_SURFACE (surface)->height))
|
||||
return NULL;
|
||||
|
||||
if (([nsevent subtype] == NSEventSubtypeTabletPoint) &&
|
||||
_gdk_macos_seat_get_tablet (GDK_MACOS_SEAT (seat), &pointer, &tool))
|
||||
axes = _gdk_macos_seat_get_tablet_axes_from_nsevent (GDK_MACOS_SEAT (seat), nsevent);
|
||||
else
|
||||
pointer = gdk_seat_get_pointer (seat);
|
||||
|
||||
return gdk_button_event_new (type,
|
||||
GDK_SURFACE (surface),
|
||||
gdk_seat_get_pointer (seat),
|
||||
NULL,
|
||||
pointer,
|
||||
tool,
|
||||
get_time_from_ns_event (nsevent),
|
||||
state,
|
||||
get_mouse_button_from_ns_event (nsevent),
|
||||
x,
|
||||
y,
|
||||
NULL);
|
||||
axes);
|
||||
}
|
||||
|
||||
static GdkEvent *
|
||||
@@ -557,6 +567,9 @@ fill_motion_event (GdkMacosDisplay *display,
|
||||
{
|
||||
GdkSeat *seat;
|
||||
GdkModifierType state;
|
||||
GdkDevice *pointer = NULL;
|
||||
GdkDeviceTool *tool = NULL;
|
||||
double *axes = NULL;
|
||||
|
||||
g_assert (GDK_IS_MACOS_SURFACE (surface));
|
||||
g_assert (nsevent != NULL);
|
||||
@@ -566,14 +579,20 @@ fill_motion_event (GdkMacosDisplay *display,
|
||||
state = get_keyboard_modifiers_from_ns_event (nsevent) |
|
||||
_gdk_macos_display_get_current_mouse_modifiers (display);
|
||||
|
||||
if (([nsevent subtype] == NSEventSubtypeTabletPoint) &&
|
||||
_gdk_macos_seat_get_tablet (GDK_MACOS_SEAT (seat), &pointer, &tool))
|
||||
axes = _gdk_macos_seat_get_tablet_axes_from_nsevent (GDK_MACOS_SEAT (seat), nsevent);
|
||||
else
|
||||
pointer = gdk_seat_get_pointer (seat);
|
||||
|
||||
return gdk_motion_event_new (GDK_SURFACE (surface),
|
||||
gdk_seat_get_pointer (seat),
|
||||
NULL,
|
||||
pointer,
|
||||
tool,
|
||||
get_time_from_ns_event (nsevent),
|
||||
state,
|
||||
x,
|
||||
y,
|
||||
NULL);
|
||||
axes);
|
||||
}
|
||||
|
||||
static GdkEvent *
|
||||
@@ -700,7 +719,7 @@ get_surface_point_from_screen_point (GdkSurface *surface,
|
||||
NSPoint point;
|
||||
|
||||
nswindow = _gdk_macos_surface_get_native (GDK_MACOS_SURFACE (surface));
|
||||
point = [nswindow convertPointFromScreen:screen_point];
|
||||
point = convert_nspoint_from_screen (nswindow, screen_point);
|
||||
|
||||
*x = point.x;
|
||||
*y = surface->height - point.y;
|
||||
@@ -762,7 +781,7 @@ get_surface_from_ns_event (GdkMacosDisplay *self,
|
||||
GdkSurface *surface = NULL;
|
||||
NSWindow *nswindow = [nsevent window];
|
||||
|
||||
if (nswindow)
|
||||
if (GDK_IS_MACOS_WINDOW (nswindow))
|
||||
{
|
||||
GdkMacosBaseView *view;
|
||||
NSPoint point, view_point;
|
||||
@@ -821,7 +840,7 @@ get_surface_from_ns_event (GdkMacosDisplay *self,
|
||||
}
|
||||
else
|
||||
{
|
||||
*screen_point = [(GdkMacosWindow *)[nsevent window] convertPointToScreen:point];
|
||||
*screen_point = convert_nspoint_to_screen ([nsevent window], point);
|
||||
*x = point.x;
|
||||
*y = surface->height - point.y;
|
||||
}
|
||||
@@ -974,11 +993,11 @@ find_surface_for_ns_event (GdkMacosDisplay *self,
|
||||
g_assert (x != NULL);
|
||||
g_assert (y != NULL);
|
||||
|
||||
view = (GdkMacosBaseView *)[[nsevent window] contentView];
|
||||
|
||||
if (!(surface = get_surface_from_ns_event (self, nsevent, &point, x, y)))
|
||||
return NULL;
|
||||
|
||||
view = (GdkMacosBaseView *)[GDK_MACOS_SURFACE (surface)->window contentView];
|
||||
|
||||
_gdk_macos_display_from_display_coords (self, point.x, point.y, &x_tmp, &y_tmp);
|
||||
|
||||
switch ((int)[nsevent type])
|
||||
@@ -1051,6 +1070,23 @@ _gdk_macos_display_translate (GdkMacosDisplay *self,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* We need to register the proximity event from any point on the screen
|
||||
* to properly register the devices
|
||||
* FIXME: is there a better way to detect if a tablet has been plugged?
|
||||
*/
|
||||
if (event_type == NSEventTypeTabletProximity)
|
||||
{
|
||||
GdkSeat *seat = gdk_display_get_default_seat (GDK_DISPLAY (self));
|
||||
|
||||
_gdk_macos_seat_handle_tablet_tool_event (GDK_MACOS_SEAT (seat), nsevent);
|
||||
|
||||
/* FIXME: we might want to cache this proximity event and propagate it
|
||||
* but proximity events in gdk work at a window level while on macos
|
||||
* works at a screen level. For now we just skip them.
|
||||
*/
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(surface = find_surface_for_ns_event (self, nsevent, &x, &y)))
|
||||
return NULL;
|
||||
|
||||
|
||||
@@ -547,6 +547,20 @@ _gdk_macos_display_surface_resigned_key (GdkMacosDisplay *self,
|
||||
_gdk_macos_display_clear_sorting (self);
|
||||
}
|
||||
|
||||
/* Raises a transient window.
|
||||
*/
|
||||
static void
|
||||
raise_transient (GdkMacosSurface *surface)
|
||||
{
|
||||
GdkMacosSurface *parent_surface = GDK_MACOS_SURFACE (GDK_SURFACE (surface)->transient_for);
|
||||
|
||||
NSWindow *parent = _gdk_macos_surface_get_native (parent_surface);
|
||||
NSWindow *window = _gdk_macos_surface_get_native (surface);
|
||||
|
||||
[parent removeChildWindow:window];
|
||||
[parent addChildWindow:window ordered:NSWindowAbove];
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_macos_display_surface_became_main (GdkMacosDisplay *self,
|
||||
GdkMacosSurface *surface)
|
||||
@@ -559,6 +573,9 @@ _gdk_macos_display_surface_became_main (GdkMacosDisplay *self,
|
||||
|
||||
g_queue_push_head_link (&self->main_surfaces, &surface->main);
|
||||
|
||||
if (GDK_SURFACE (surface)->transient_for)
|
||||
raise_transient (surface);
|
||||
|
||||
_gdk_macos_display_clear_sorting (self);
|
||||
}
|
||||
|
||||
|
||||
@@ -145,6 +145,7 @@ GetSubpixelLayout (CGDirectDisplayID screen_id)
|
||||
static char *
|
||||
GetLocalizedName (NSScreen *screen)
|
||||
{
|
||||
#ifdef AVAILABLE_MAC_OS_X_VERSION_10_15_AND_LATER
|
||||
GDK_BEGIN_MACOS_ALLOC_POOL;
|
||||
|
||||
NSString *str;
|
||||
@@ -158,6 +159,9 @@ GetLocalizedName (NSScreen *screen)
|
||||
GDK_END_MACOS_ALLOC_POOL;
|
||||
|
||||
return g_steal_pointer (&name);
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
static char *
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <AppKit/AppKit.h>
|
||||
|
||||
#include "gdkmacosdisplay.h"
|
||||
#include "gdkmacosseat.h"
|
||||
|
||||
#include "gdkseatprivate.h"
|
||||
|
||||
@@ -30,6 +31,16 @@ G_BEGIN_DECLS
|
||||
|
||||
GdkSeat *_gdk_macos_seat_new (GdkMacosDisplay *display);
|
||||
|
||||
void _gdk_macos_seat_handle_tablet_tool_event (GdkMacosSeat *seat,
|
||||
NSEvent *nsevent);
|
||||
|
||||
gboolean _gdk_macos_seat_get_tablet (GdkMacosSeat *seat,
|
||||
GdkDevice **device,
|
||||
GdkDeviceTool **tool);
|
||||
|
||||
double *_gdk_macos_seat_get_tablet_axes_from_nsevent (GdkMacosSeat *seat,
|
||||
NSEvent *nsevent);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_MACOS_SEAT_PRIVATE_H__ */
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright © 2020 Red Hat, Inc.
|
||||
* Copyright © 2021 Amazon.com, Inc. and its affiliates. All Rights Reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -22,42 +23,605 @@
|
||||
#include <gdk/gdk.h>
|
||||
|
||||
#include "gdkdeviceprivate.h"
|
||||
#include "gdkseatdefaultprivate.h"
|
||||
#include "gdkdevicetoolprivate.h"
|
||||
|
||||
#include "gdkmacosdevice.h"
|
||||
#include "gdkmacosseat-private.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
NSUInteger device_id;
|
||||
char *name;
|
||||
|
||||
GdkDevice *logical_device;
|
||||
GdkDevice *stylus_device;
|
||||
GdkSeat *seat;
|
||||
|
||||
GdkDeviceTool *current_tool;
|
||||
|
||||
int axis_indices[GDK_AXIS_LAST];
|
||||
double axes[GDK_AXIS_LAST];
|
||||
} GdkMacosTabletData;
|
||||
|
||||
struct _GdkMacosSeat
|
||||
{
|
||||
GdkSeat parent_instance;
|
||||
|
||||
GdkMacosDisplay *display;
|
||||
|
||||
GdkDevice *logical_pointer;
|
||||
GdkDevice *logical_keyboard;
|
||||
|
||||
GdkMacosTabletData *current_tablet;
|
||||
GPtrArray *tablets;
|
||||
GPtrArray *tools;
|
||||
};
|
||||
|
||||
struct _GdkMacosSeatClass
|
||||
{
|
||||
GdkSeatClass parent_class;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (GdkMacosSeat, gdk_macos_seat, GDK_TYPE_SEAT)
|
||||
|
||||
#define KEYBOARD_EVENTS (GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | \
|
||||
GDK_FOCUS_CHANGE_MASK)
|
||||
#define TOUCH_EVENTS (GDK_TOUCH_MASK)
|
||||
#define POINTER_EVENTS (GDK_POINTER_MOTION_MASK | \
|
||||
GDK_BUTTON_PRESS_MASK | \
|
||||
GDK_BUTTON_RELEASE_MASK | \
|
||||
GDK_SCROLL_MASK | GDK_SMOOTH_SCROLL_MASK | \
|
||||
GDK_ENTER_NOTIFY_MASK | \
|
||||
GDK_LEAVE_NOTIFY_MASK | \
|
||||
GDK_PROXIMITY_IN_MASK | \
|
||||
GDK_PROXIMITY_OUT_MASK)
|
||||
|
||||
static void
|
||||
gdk_macos_tablet_data_free (gpointer user_data)
|
||||
{
|
||||
GdkMacosTabletData *tablet = user_data;
|
||||
|
||||
gdk_seat_device_removed (GDK_SEAT (tablet->seat), tablet->stylus_device);
|
||||
gdk_seat_device_removed (GDK_SEAT (tablet->seat), tablet->logical_device);
|
||||
|
||||
_gdk_device_set_associated_device (tablet->logical_device, NULL);
|
||||
_gdk_device_set_associated_device (tablet->stylus_device, NULL);
|
||||
|
||||
g_object_unref (tablet->logical_device);
|
||||
g_object_unref (tablet->stylus_device);
|
||||
|
||||
g_free (tablet->name);
|
||||
g_free (tablet);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_seat_dispose (GObject *object)
|
||||
{
|
||||
GdkMacosSeat *self = GDK_MACOS_SEAT (object);
|
||||
|
||||
if (self->logical_pointer)
|
||||
{
|
||||
gdk_seat_device_removed (GDK_SEAT (self), self->logical_pointer);
|
||||
g_clear_object (&self->logical_pointer);
|
||||
}
|
||||
|
||||
if (self->logical_keyboard)
|
||||
{
|
||||
gdk_seat_device_removed (GDK_SEAT (self), self->logical_keyboard);
|
||||
g_clear_object (&self->logical_pointer);
|
||||
}
|
||||
|
||||
g_clear_pointer (&self->tablets, g_ptr_array_unref);
|
||||
g_clear_pointer (&self->tools, g_ptr_array_unref);
|
||||
|
||||
G_OBJECT_CLASS (gdk_macos_seat_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static GdkSeatCapabilities
|
||||
gdk_macos_seat_get_capabilities (GdkSeat *seat)
|
||||
{
|
||||
GdkMacosSeat *self = GDK_MACOS_SEAT (seat);
|
||||
GdkSeatCapabilities caps = 0;
|
||||
|
||||
if (self->logical_pointer)
|
||||
caps |= GDK_SEAT_CAPABILITY_POINTER;
|
||||
if (self->logical_keyboard)
|
||||
caps |= GDK_SEAT_CAPABILITY_KEYBOARD;
|
||||
|
||||
return caps;
|
||||
}
|
||||
|
||||
static GdkGrabStatus
|
||||
gdk_macos_seat_grab (GdkSeat *seat,
|
||||
GdkSurface *surface,
|
||||
GdkSeatCapabilities capabilities,
|
||||
gboolean owner_events,
|
||||
GdkCursor *cursor,
|
||||
GdkEvent *event,
|
||||
GdkSeatGrabPrepareFunc prepare_func,
|
||||
gpointer prepare_func_data)
|
||||
{
|
||||
GdkMacosSeat *self = GDK_MACOS_SEAT (seat);
|
||||
guint32 evtime = event ? gdk_event_get_time (event) : GDK_CURRENT_TIME;
|
||||
GdkGrabStatus status = GDK_GRAB_SUCCESS;
|
||||
gboolean was_visible;
|
||||
|
||||
was_visible = gdk_surface_get_mapped (surface);
|
||||
|
||||
if (prepare_func)
|
||||
(prepare_func) (seat, surface, prepare_func_data);
|
||||
|
||||
if (!gdk_surface_get_mapped (surface))
|
||||
{
|
||||
g_critical ("Surface %p has not been mapped in GdkSeatGrabPrepareFunc",
|
||||
surface);
|
||||
return GDK_GRAB_NOT_VIEWABLE;
|
||||
}
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
|
||||
|
||||
if (capabilities & GDK_SEAT_CAPABILITY_ALL_POINTING)
|
||||
{
|
||||
/* ALL_POINTING spans 3 capabilities; get the mask for the ones we have */
|
||||
GdkEventMask pointer_evmask = 0;
|
||||
|
||||
/* We let tablet styli take over the pointer cursor */
|
||||
if (capabilities & (GDK_SEAT_CAPABILITY_POINTER |
|
||||
GDK_SEAT_CAPABILITY_TABLET_STYLUS))
|
||||
{
|
||||
pointer_evmask |= POINTER_EVENTS;
|
||||
}
|
||||
|
||||
if (capabilities & GDK_SEAT_CAPABILITY_TOUCH)
|
||||
pointer_evmask |= TOUCH_EVENTS;
|
||||
|
||||
status = gdk_device_grab (self->logical_pointer, surface,
|
||||
owner_events,
|
||||
pointer_evmask, cursor,
|
||||
evtime);
|
||||
}
|
||||
|
||||
if (status == GDK_GRAB_SUCCESS &&
|
||||
capabilities & GDK_SEAT_CAPABILITY_KEYBOARD)
|
||||
{
|
||||
status = gdk_device_grab (self->logical_keyboard, surface,
|
||||
owner_events,
|
||||
KEYBOARD_EVENTS, cursor,
|
||||
evtime);
|
||||
|
||||
if (status != GDK_GRAB_SUCCESS)
|
||||
{
|
||||
if (capabilities & ~GDK_SEAT_CAPABILITY_KEYBOARD)
|
||||
gdk_device_ungrab (self->logical_pointer, evtime);
|
||||
}
|
||||
}
|
||||
|
||||
if (status != GDK_GRAB_SUCCESS && !was_visible)
|
||||
gdk_surface_hide (surface);
|
||||
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_seat_ungrab (GdkSeat *seat)
|
||||
{
|
||||
GdkMacosSeat *self = GDK_MACOS_SEAT (seat);
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
|
||||
gdk_device_ungrab (self->logical_pointer, GDK_CURRENT_TIME);
|
||||
gdk_device_ungrab (self->logical_keyboard, GDK_CURRENT_TIME);
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS;
|
||||
}
|
||||
|
||||
static GdkDevice *
|
||||
gdk_macos_seat_get_logical_device (GdkSeat *seat,
|
||||
GdkSeatCapabilities capability)
|
||||
{
|
||||
GdkMacosSeat *self = GDK_MACOS_SEAT (seat);
|
||||
|
||||
/* There must be only one flag set */
|
||||
switch ((guint) capability)
|
||||
{
|
||||
case GDK_SEAT_CAPABILITY_POINTER:
|
||||
case GDK_SEAT_CAPABILITY_TOUCH:
|
||||
return self->logical_pointer;
|
||||
case GDK_SEAT_CAPABILITY_KEYBOARD:
|
||||
return self->logical_keyboard;
|
||||
default:
|
||||
g_warning ("Unhandled capability %x", capability);
|
||||
break;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static GList *
|
||||
gdk_macos_seat_get_devices (GdkSeat *seat,
|
||||
GdkSeatCapabilities capabilities)
|
||||
{
|
||||
GdkMacosSeat *self = GDK_MACOS_SEAT (seat);
|
||||
GList *physical_devices = NULL;
|
||||
|
||||
if (self->logical_pointer && (capabilities & GDK_SEAT_CAPABILITY_POINTER))
|
||||
physical_devices = g_list_prepend (physical_devices, self->logical_pointer);
|
||||
|
||||
if (self->logical_keyboard && (capabilities & GDK_SEAT_CAPABILITY_KEYBOARD))
|
||||
physical_devices = g_list_prepend (physical_devices, self->logical_keyboard);
|
||||
|
||||
if (capabilities & GDK_SEAT_CAPABILITY_TABLET_STYLUS)
|
||||
{
|
||||
for (guint i = 0; i < self->tablets->len; i++)
|
||||
{
|
||||
GdkMacosTabletData *tablet = g_ptr_array_index (self->tablets, i);
|
||||
|
||||
physical_devices = g_list_prepend (physical_devices, tablet->stylus_device);
|
||||
}
|
||||
}
|
||||
|
||||
return physical_devices;
|
||||
}
|
||||
|
||||
static GList *
|
||||
gdk_macos_seat_get_tools (GdkSeat *seat)
|
||||
{
|
||||
GdkMacosSeat *self = GDK_MACOS_SEAT (seat);
|
||||
GdkDeviceTool *tool;
|
||||
GList *tools = NULL;
|
||||
|
||||
for (guint i = 0; i < self->tools->len; i++)
|
||||
{
|
||||
tool = g_ptr_array_index (self->tools, i);
|
||||
tools = g_list_prepend (tools, tool);
|
||||
}
|
||||
|
||||
return tools;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_seat_class_init (GdkMacosSeatClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GdkSeatClass *seat_class = GDK_SEAT_CLASS (klass);
|
||||
|
||||
object_class->dispose = gdk_macos_seat_dispose;
|
||||
|
||||
seat_class->get_capabilities = gdk_macos_seat_get_capabilities;
|
||||
seat_class->grab = gdk_macos_seat_grab;
|
||||
seat_class->ungrab = gdk_macos_seat_ungrab;
|
||||
seat_class->get_logical_device = gdk_macos_seat_get_logical_device;
|
||||
seat_class->get_devices = gdk_macos_seat_get_devices;
|
||||
seat_class->get_tools = gdk_macos_seat_get_tools;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_seat_init (GdkMacosSeat *self)
|
||||
{
|
||||
self->tablets = g_ptr_array_new_with_free_func (gdk_macos_tablet_data_free);
|
||||
self->tools = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
|
||||
}
|
||||
|
||||
static void
|
||||
init_devices (GdkMacosSeat *self)
|
||||
{
|
||||
/* pointer */
|
||||
self->logical_pointer = g_object_new (GDK_TYPE_MACOS_DEVICE,
|
||||
"name", "Core Pointer",
|
||||
"source", GDK_SOURCE_MOUSE,
|
||||
"has-cursor", TRUE,
|
||||
"display", self->display,
|
||||
"seat", self,
|
||||
NULL);
|
||||
|
||||
/* keyboard */
|
||||
self->logical_keyboard = g_object_new (GDK_TYPE_MACOS_DEVICE,
|
||||
"name", "Core Keyboard",
|
||||
"source", GDK_SOURCE_KEYBOARD,
|
||||
"has-cursor", FALSE,
|
||||
"display", self->display,
|
||||
"seat", self,
|
||||
NULL);
|
||||
|
||||
/* link both */
|
||||
_gdk_device_set_associated_device (self->logical_pointer, self->logical_keyboard);
|
||||
_gdk_device_set_associated_device (self->logical_keyboard, self->logical_pointer);
|
||||
|
||||
gdk_seat_device_added (GDK_SEAT (self), self->logical_pointer);
|
||||
gdk_seat_device_added (GDK_SEAT (self), self->logical_keyboard);
|
||||
}
|
||||
|
||||
GdkSeat *
|
||||
_gdk_macos_seat_new (GdkMacosDisplay *display)
|
||||
{
|
||||
GdkDevice *core_keyboard;
|
||||
GdkDevice *core_pointer;
|
||||
GdkSeat *seat;
|
||||
GdkMacosSeat *self;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_MACOS_DISPLAY (display), NULL);
|
||||
|
||||
core_pointer = g_object_new (GDK_TYPE_MACOS_DEVICE,
|
||||
"name", "Core Pointer",
|
||||
"source", GDK_SOURCE_MOUSE,
|
||||
"has-cursor", TRUE,
|
||||
"display", display,
|
||||
NULL);
|
||||
core_keyboard = g_object_new (GDK_TYPE_MACOS_DEVICE,
|
||||
"name", "Core Keyboard",
|
||||
"source", GDK_SOURCE_KEYBOARD,
|
||||
self = g_object_new (GDK_TYPE_MACOS_SEAT,
|
||||
"display", display,
|
||||
NULL);
|
||||
|
||||
self->display = display;
|
||||
|
||||
init_devices (self);
|
||||
|
||||
return g_steal_pointer (&self);
|
||||
}
|
||||
|
||||
static GdkDeviceToolType
|
||||
get_device_tool_type_from_nsevent (NSEvent *nsevent)
|
||||
{
|
||||
GdkDeviceToolType tool_type;
|
||||
|
||||
switch ([nsevent pointingDeviceType])
|
||||
{
|
||||
case NSPointingDeviceTypePen:
|
||||
tool_type = GDK_DEVICE_TOOL_TYPE_PEN;
|
||||
break;
|
||||
case NSPointingDeviceTypeEraser:
|
||||
tool_type = GDK_DEVICE_TOOL_TYPE_ERASER;
|
||||
break;
|
||||
case NSPointingDeviceTypeCursor:
|
||||
tool_type = GDK_DEVICE_TOOL_TYPE_MOUSE;
|
||||
break;
|
||||
case NSPointingDeviceTypeUnknown:
|
||||
default:
|
||||
tool_type = GDK_DEVICE_TOOL_TYPE_UNKNOWN;
|
||||
}
|
||||
|
||||
return tool_type;
|
||||
}
|
||||
|
||||
static GdkAxisFlags
|
||||
get_device_tool_axes_from_nsevent (NSEvent *nsevent)
|
||||
{
|
||||
/* TODO: do we need to be smarter about the capabilities? */
|
||||
return GDK_AXIS_FLAG_XTILT | GDK_AXIS_FLAG_YTILT | GDK_AXIS_FLAG_PRESSURE |
|
||||
GDK_AXIS_FLAG_ROTATION;
|
||||
}
|
||||
|
||||
static GdkMacosTabletData *
|
||||
create_tablet_data_from_nsevent (GdkMacosSeat *self,
|
||||
NSEvent *nsevent)
|
||||
{
|
||||
GdkMacosTabletData *tablet;
|
||||
GdkDisplay *display = gdk_seat_get_display (GDK_SEAT (self));
|
||||
GdkDevice *logical_device, *stylus_device;
|
||||
char *logical_name;
|
||||
char *vid, *pid;
|
||||
|
||||
tablet = g_new0 (GdkMacosTabletData, 1);
|
||||
tablet->seat = GDK_SEAT (self);
|
||||
tablet->device_id = [nsevent deviceID];
|
||||
/* FIXME: find a better name */
|
||||
tablet->name = g_strdup_printf ("Tablet %lu", [nsevent deviceID]);
|
||||
|
||||
vid = g_strdup_printf ("%.4lx", [nsevent vendorID]);
|
||||
pid = g_strdup_printf ("%.4lx", [nsevent tabletID]);
|
||||
|
||||
logical_name = g_strdup_printf ("Logical pointer for %s", tablet->name);
|
||||
logical_device = g_object_new (GDK_TYPE_MACOS_DEVICE,
|
||||
"name", logical_name,
|
||||
"source", GDK_SOURCE_MOUSE,
|
||||
"has-cursor", TRUE,
|
||||
"display", display,
|
||||
"seat", self,
|
||||
NULL);
|
||||
|
||||
stylus_device = g_object_new (GDK_TYPE_MACOS_DEVICE,
|
||||
"name", tablet->name,
|
||||
"source", GDK_SOURCE_PEN,
|
||||
"has-cursor", FALSE,
|
||||
"display", display,
|
||||
"seat", self,
|
||||
"vendor-id", vid,
|
||||
"product-id", pid,
|
||||
NULL);
|
||||
|
||||
_gdk_device_set_associated_device (GDK_DEVICE (core_pointer),
|
||||
GDK_DEVICE (core_keyboard));
|
||||
_gdk_device_set_associated_device (GDK_DEVICE (core_keyboard),
|
||||
GDK_DEVICE (core_pointer));
|
||||
tablet->logical_device = logical_device;
|
||||
tablet->stylus_device = stylus_device;
|
||||
|
||||
seat = gdk_seat_default_new_for_logical_pair (core_pointer, core_keyboard);
|
||||
_gdk_device_set_associated_device (logical_device, self->logical_keyboard);
|
||||
_gdk_device_set_associated_device (stylus_device, logical_device);
|
||||
|
||||
g_object_unref (core_pointer);
|
||||
g_object_unref (core_keyboard);
|
||||
gdk_seat_device_added (GDK_SEAT (self), logical_device);
|
||||
gdk_seat_device_added (GDK_SEAT (self), stylus_device);
|
||||
|
||||
return g_steal_pointer (&seat);
|
||||
g_free (logical_name);
|
||||
g_free (vid);
|
||||
g_free (pid);
|
||||
|
||||
return tablet;
|
||||
}
|
||||
|
||||
static GdkMacosTabletData *
|
||||
get_tablet_data_from_nsevent (GdkMacosSeat *self,
|
||||
NSEvent *nsevent)
|
||||
{
|
||||
GdkMacosTabletData *tablet = NULL;
|
||||
|
||||
for (guint i = 0; i < self->tablets->len; i++)
|
||||
{
|
||||
GdkMacosTabletData *t = g_ptr_array_index (self->tablets, i);
|
||||
|
||||
if (t->device_id == [nsevent deviceID])
|
||||
{
|
||||
tablet = t;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!tablet)
|
||||
tablet = create_tablet_data_from_nsevent (self, nsevent);
|
||||
|
||||
return tablet;
|
||||
}
|
||||
|
||||
static void
|
||||
device_tablet_clone_tool_axes (GdkMacosTabletData *tablet,
|
||||
GdkDeviceTool *tool)
|
||||
{
|
||||
int axis_pos;
|
||||
|
||||
g_object_freeze_notify (G_OBJECT (tablet->stylus_device));
|
||||
_gdk_device_reset_axes (tablet->stylus_device);
|
||||
|
||||
_gdk_device_add_axis (tablet->stylus_device, GDK_AXIS_X, 0, 0, 0);
|
||||
_gdk_device_add_axis (tablet->stylus_device, GDK_AXIS_Y, 0, 0, 0);
|
||||
|
||||
if (tool->tool_axes & (GDK_AXIS_FLAG_XTILT | GDK_AXIS_FLAG_YTILT))
|
||||
{
|
||||
axis_pos = _gdk_device_add_axis (tablet->stylus_device,
|
||||
GDK_AXIS_XTILT, -1.0, 1.0, 0);
|
||||
tablet->axis_indices[GDK_AXIS_XTILT] = axis_pos;
|
||||
|
||||
axis_pos = _gdk_device_add_axis (tablet->stylus_device,
|
||||
GDK_AXIS_YTILT, -1.0, 1.0, 0);
|
||||
tablet->axis_indices[GDK_AXIS_YTILT] = axis_pos;
|
||||
}
|
||||
|
||||
if (tool->tool_axes & GDK_AXIS_FLAG_PRESSURE)
|
||||
{
|
||||
axis_pos = _gdk_device_add_axis (tablet->stylus_device,
|
||||
GDK_AXIS_PRESSURE, 0.0, 1.0, 0);
|
||||
tablet->axis_indices[GDK_AXIS_PRESSURE] = axis_pos;
|
||||
}
|
||||
|
||||
if (tool->tool_axes & GDK_AXIS_FLAG_ROTATION)
|
||||
{
|
||||
axis_pos = _gdk_device_add_axis (tablet->stylus_device,
|
||||
GDK_AXIS_ROTATION, 0.0, 1.0, 0);
|
||||
tablet->axis_indices[GDK_AXIS_ROTATION] = axis_pos;
|
||||
}
|
||||
|
||||
g_object_thaw_notify (G_OBJECT (tablet->stylus_device));
|
||||
}
|
||||
|
||||
static void
|
||||
mimic_device_axes (GdkDevice *logical,
|
||||
GdkDevice *physical)
|
||||
{
|
||||
double axis_min, axis_max, axis_resolution;
|
||||
GdkAxisUse axis_use;
|
||||
int axis_count;
|
||||
|
||||
g_object_freeze_notify (G_OBJECT (logical));
|
||||
_gdk_device_reset_axes (logical);
|
||||
axis_count = gdk_device_get_n_axes (physical);
|
||||
|
||||
for (int i = 0; i < axis_count; i++)
|
||||
{
|
||||
_gdk_device_get_axis_info (physical, i, &axis_use, &axis_min,
|
||||
&axis_max, &axis_resolution);
|
||||
_gdk_device_add_axis (logical, axis_use, axis_min,
|
||||
axis_max, axis_resolution);
|
||||
}
|
||||
|
||||
g_object_thaw_notify (G_OBJECT (logical));
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_macos_seat_handle_tablet_tool_event (GdkMacosSeat *seat,
|
||||
NSEvent *nsevent)
|
||||
{
|
||||
GdkDeviceToolType tool_type;
|
||||
GdkMacosTabletData *tablet;
|
||||
GdkDeviceTool *tool;
|
||||
|
||||
g_return_if_fail (GDK_IS_MACOS_SEAT (seat));
|
||||
g_return_if_fail (nsevent != NULL);
|
||||
|
||||
tablet = get_tablet_data_from_nsevent (seat, nsevent);
|
||||
|
||||
tool_type = get_device_tool_type_from_nsevent (nsevent);
|
||||
|
||||
if (tool_type == GDK_DEVICE_TOOL_TYPE_UNKNOWN)
|
||||
{
|
||||
g_warning ("Unknown device tool detected");
|
||||
return;
|
||||
}
|
||||
|
||||
tool = gdk_seat_get_tool (GDK_SEAT (seat), [nsevent tabletID], [nsevent deviceID], tool_type);
|
||||
|
||||
if ([nsevent isEnteringProximity])
|
||||
{
|
||||
if (!tool)
|
||||
{
|
||||
tool = gdk_device_tool_new ([nsevent tabletID], [nsevent vendorID], tool_type,
|
||||
get_device_tool_axes_from_nsevent (nsevent));
|
||||
g_ptr_array_add (seat->tools, tool);
|
||||
}
|
||||
|
||||
gdk_device_update_tool (tablet->stylus_device, tool);
|
||||
tablet->current_tool = tool;
|
||||
device_tablet_clone_tool_axes (tablet, tool);
|
||||
mimic_device_axes (tablet->logical_device, tablet->stylus_device);
|
||||
seat->current_tablet = tablet;
|
||||
}
|
||||
else
|
||||
{
|
||||
gdk_device_update_tool (tablet->stylus_device, NULL);
|
||||
tablet->current_tool = NULL;
|
||||
seat->current_tablet = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gdk_macos_seat_get_tablet (GdkMacosSeat *seat,
|
||||
GdkDevice **logical_device,
|
||||
GdkDeviceTool **tool)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_MACOS_SEAT (seat), FALSE);
|
||||
|
||||
if (!seat->current_tablet)
|
||||
return FALSE;
|
||||
|
||||
*logical_device = seat->current_tablet->logical_device;
|
||||
*tool = seat->current_tablet->current_tool;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
double *
|
||||
_gdk_macos_seat_get_tablet_axes_from_nsevent (GdkMacosSeat *seat,
|
||||
NSEvent *nsevent)
|
||||
{
|
||||
GdkMacosTabletData *tablet;
|
||||
int axis_index;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_MACOS_SEAT (seat), NULL);
|
||||
g_return_val_if_fail (nsevent != NULL, NULL);
|
||||
|
||||
tablet = seat->current_tablet;
|
||||
if (!tablet || !tablet->current_tool)
|
||||
return NULL;
|
||||
|
||||
if (tablet->current_tool->tool_axes & (GDK_AXIS_FLAG_XTILT | GDK_AXIS_FLAG_YTILT))
|
||||
{
|
||||
axis_index = tablet->axis_indices[GDK_AXIS_XTILT];
|
||||
_gdk_device_translate_axis (tablet->stylus_device, axis_index,
|
||||
[nsevent tilt].x, &tablet->axes[GDK_AXIS_XTILT]);
|
||||
|
||||
axis_index = tablet->axis_indices[GDK_AXIS_YTILT];
|
||||
_gdk_device_translate_axis (tablet->stylus_device, axis_index,
|
||||
[nsevent tilt].y, &tablet->axes[GDK_AXIS_YTILT]);
|
||||
}
|
||||
|
||||
if (tablet->current_tool->tool_axes & GDK_AXIS_FLAG_PRESSURE)
|
||||
{
|
||||
axis_index = tablet->axis_indices[GDK_AXIS_PRESSURE];
|
||||
_gdk_device_translate_axis (tablet->stylus_device, axis_index,
|
||||
[nsevent pressure], &tablet->axes[GDK_AXIS_PRESSURE]);
|
||||
}
|
||||
|
||||
if (tablet->current_tool->tool_axes & GDK_AXIS_FLAG_ROTATION)
|
||||
{
|
||||
axis_index = tablet->axis_indices[GDK_AXIS_ROTATION];
|
||||
_gdk_device_translate_axis (tablet->stylus_device, axis_index,
|
||||
[nsevent rotation], &tablet->axes[GDK_AXIS_ROTATION]);
|
||||
}
|
||||
|
||||
return g_memdup (tablet->axes,
|
||||
sizeof (double) * GDK_AXIS_LAST);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright © 2021 Amazon.com, Inc. and its affiliates. All Rights Reserved.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined (__GDKMACOS_H_INSIDE__) && !defined (GTK_COMPILATION)
|
||||
#error "Only <gdk/macos/gdkmacos.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GDK_TYPE_MACOS_SEAT (gdk_macos_seat_get_type ())
|
||||
#define GDK_MACOS_SEAT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDK_TYPE_MACOS_SEAT, GdkMacosSeat))
|
||||
#define GDK_IS_MACOS_SEAT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDK_TYPE_MACOS_SEAT))
|
||||
|
||||
typedef struct _GdkMacosSeat GdkMacosSeat;
|
||||
typedef struct _GdkMacosSeatClass GdkMacosSeatClass;
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GType gdk_macos_seat_get_type (void) G_GNUC_CONST;
|
||||
|
||||
G_END_DECLS
|
||||
@@ -61,6 +61,7 @@ struct _GdkMacosSurface
|
||||
gint64 pending_frame_counter;
|
||||
|
||||
guint did_initial_present : 1;
|
||||
guint geometry_dirty : 1;
|
||||
};
|
||||
|
||||
struct _GdkMacosSurfaceClass
|
||||
|
||||
@@ -150,6 +150,12 @@ _gdk_macos_surface_set_shadow (GdkMacosSurface *surface,
|
||||
|
||||
g_assert (GDK_IS_MACOS_SURFACE (self));
|
||||
|
||||
if (self->shadow_top == top &&
|
||||
self->shadow_right == right &&
|
||||
self->shadow_bottom == bottom &&
|
||||
self->shadow_left == left)
|
||||
return;
|
||||
|
||||
self->shadow_top = top;
|
||||
self->shadow_right = right;
|
||||
self->shadow_bottom = bottom;
|
||||
|
||||
@@ -81,7 +81,7 @@ _gdk_macos_toplevel_surface_unmaximize (GdkMacosToplevelSurface *self)
|
||||
[window zoom:window];
|
||||
}
|
||||
|
||||
static gboolean
|
||||
static void
|
||||
_gdk_macos_toplevel_surface_present (GdkToplevel *toplevel,
|
||||
GdkToplevelLayout *layout)
|
||||
{
|
||||
@@ -97,7 +97,7 @@ _gdk_macos_toplevel_surface_present (GdkToplevel *toplevel,
|
||||
GdkSurfaceHints mask;
|
||||
NSWindowStyleMask style_mask;
|
||||
gboolean maximize;
|
||||
gboolean fullscreen
|
||||
gboolean fullscreen;
|
||||
|
||||
g_assert (GDK_IS_MACOS_TOPLEVEL_SURFACE (self));
|
||||
g_assert (GDK_IS_MACOS_WINDOW (nswindow));
|
||||
@@ -107,6 +107,7 @@ _gdk_macos_toplevel_surface_present (GdkToplevel *toplevel,
|
||||
style_mask = [nswindow styleMask];
|
||||
|
||||
monitor = gdk_display_get_monitor_at_surface (display, surface);
|
||||
|
||||
if (monitor)
|
||||
{
|
||||
GdkRectangle workarea;
|
||||
@@ -158,13 +159,11 @@ _gdk_macos_toplevel_surface_present (GdkToplevel *toplevel,
|
||||
[nswindow setStyleMask:style_mask];
|
||||
|
||||
if (size.shadow.is_valid)
|
||||
{
|
||||
_gdk_macos_surface_set_shadow (GDK_MACOS_SURFACE (surface),
|
||||
size.shadow.top,
|
||||
size.shadow.right,
|
||||
size.shadow.bottom,
|
||||
size.shadow.left);
|
||||
}
|
||||
_gdk_macos_surface_set_shadow (GDK_MACOS_SURFACE (surface),
|
||||
size.shadow.top,
|
||||
size.shadow.right,
|
||||
size.shadow.bottom,
|
||||
size.shadow.left);
|
||||
|
||||
_gdk_macos_surface_set_geometry_hints (GDK_MACOS_SURFACE (self), &geometry, mask);
|
||||
gdk_surface_constrain_size (&geometry, mask, width, height, &width, &height);
|
||||
@@ -230,8 +229,6 @@ _gdk_macos_toplevel_surface_present (GdkToplevel *toplevel,
|
||||
_gdk_macos_surface_show (GDK_MACOS_SURFACE (self));
|
||||
|
||||
GDK_MACOS_SURFACE (self)->did_initial_present = TRUE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -373,6 +370,87 @@ _gdk_macos_toplevel_surface_hide (GdkSurface *surface)
|
||||
GDK_SURFACE_CLASS (_gdk_macos_toplevel_surface_parent_class)->hide (surface);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_gdk_macos_toplevel_surface_compute_size (GdkSurface *surface)
|
||||
{
|
||||
GdkMacosToplevelSurface *self = (GdkMacosToplevelSurface *)surface;
|
||||
NSWindow *nswindow = _gdk_macos_surface_get_native (GDK_MACOS_SURFACE (self));
|
||||
GdkToplevelSize size;
|
||||
GdkDisplay *display;
|
||||
GdkMonitor *monitor;
|
||||
int bounds_width, bounds_height;
|
||||
int width, height;
|
||||
GdkGeometry geometry;
|
||||
GdkSurfaceHints mask;
|
||||
NSWindowStyleMask style_mask;
|
||||
|
||||
g_assert (GDK_IS_MACOS_TOPLEVEL_SURFACE (self));
|
||||
|
||||
if (!GDK_MACOS_SURFACE (surface)->geometry_dirty)
|
||||
return FALSE;
|
||||
|
||||
GDK_MACOS_SURFACE (surface)->geometry_dirty = FALSE;
|
||||
|
||||
display = gdk_surface_get_display (surface);
|
||||
monitor = gdk_display_get_monitor_at_surface (display, surface);
|
||||
style_mask = [nswindow styleMask];
|
||||
|
||||
if (monitor)
|
||||
{
|
||||
GdkRectangle workarea;
|
||||
|
||||
gdk_macos_monitor_get_workarea (monitor, &workarea);
|
||||
bounds_width = workarea.width;
|
||||
bounds_height = workarea.height;
|
||||
}
|
||||
else
|
||||
{
|
||||
bounds_width = G_MAXINT;
|
||||
bounds_height = G_MAXINT;
|
||||
}
|
||||
|
||||
gdk_toplevel_size_init (&size, bounds_width, bounds_height);
|
||||
gdk_toplevel_notify_compute_size (GDK_TOPLEVEL (surface), &size);
|
||||
|
||||
g_warn_if_fail (size.width > 0);
|
||||
g_warn_if_fail (size.height > 0);
|
||||
|
||||
width = size.width;
|
||||
height = size.height;
|
||||
|
||||
if (style_mask & NSWindowStyleMaskResizable)
|
||||
{
|
||||
geometry.min_width = size.min_width;
|
||||
geometry.min_height = size.min_height;
|
||||
mask = GDK_HINT_MIN_SIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
geometry.max_width = geometry.min_width = width;
|
||||
geometry.max_height = geometry.min_height = height;
|
||||
mask = GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE;
|
||||
}
|
||||
|
||||
if (size.shadow.is_valid)
|
||||
_gdk_macos_surface_set_shadow (GDK_MACOS_SURFACE (surface),
|
||||
size.shadow.top,
|
||||
size.shadow.right,
|
||||
size.shadow.bottom,
|
||||
size.shadow.left);
|
||||
|
||||
_gdk_macos_surface_set_geometry_hints (GDK_MACOS_SURFACE (self), &geometry, mask);
|
||||
gdk_surface_constrain_size (&geometry, mask, width, height, &width, &height);
|
||||
_gdk_macos_surface_resize (GDK_MACOS_SURFACE (self), width, height);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_macos_toplevel_surface_request_layout (GdkSurface *surface)
|
||||
{
|
||||
GDK_MACOS_SURFACE (surface)->geometry_dirty = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_macos_toplevel_surface_destroy (GdkSurface *surface,
|
||||
gboolean foreign_destroy)
|
||||
@@ -506,6 +584,8 @@ _gdk_macos_toplevel_surface_class_init (GdkMacosToplevelSurfaceClass *klass)
|
||||
|
||||
surface_class->destroy = _gdk_macos_toplevel_surface_destroy;
|
||||
surface_class->hide = _gdk_macos_toplevel_surface_hide;
|
||||
surface_class->compute_size = _gdk_macos_toplevel_surface_compute_size;
|
||||
surface_class->request_layout = _gdk_macos_toplevel_surface_request_layout;
|
||||
|
||||
gdk_toplevel_install_properties (object_class, LAST_PROP);
|
||||
}
|
||||
|
||||
@@ -40,5 +40,36 @@ struct _GdkPoint
|
||||
};
|
||||
typedef struct _GdkPoint GdkPoint;
|
||||
|
||||
static inline NSPoint
|
||||
convert_nspoint_from_screen (NSWindow *window,
|
||||
NSPoint point)
|
||||
{
|
||||
#ifdef AVAILABLE_MAC_OS_X_VERSION_10_15_AND_LATER
|
||||
return [window convertPointFromScreen:point];
|
||||
#else
|
||||
/* Apple documentation claims that convertPointFromScreen is available
|
||||
* on 10.12+. However, that doesn't seem to be the case when using it.
|
||||
* Instead, we'll just use it on modern 10.15 systems and fallback to
|
||||
* converting using rects on older systems.
|
||||
*/
|
||||
return [window convertRectFromScreen:NSMakeRect (point.x, point.y, 0, 0)].origin;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline NSPoint
|
||||
convert_nspoint_to_screen (NSWindow *window,
|
||||
NSPoint point)
|
||||
{
|
||||
#ifdef AVAILABLE_MAC_OS_X_VERSION_10_15_AND_LATER
|
||||
return [window convertPointToScreen:point];
|
||||
#else
|
||||
/* Apple documentation claims that convertPointToScreen is available
|
||||
* on 10.12+. However, that doesn't seem to be the case when using it.
|
||||
* Instead, we'll just use it on modern 10.15 systems and fallback to
|
||||
* converting using rects on older systems.
|
||||
*/
|
||||
return [window convertRectToScreen:NSMakeRect (point.x, point.y, 0, 0)].origin;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* __GDK_MACOS_UTILS_PRIVATE_H__ */
|
||||
|
||||
@@ -33,6 +33,7 @@ gdk_macos_public_headers = files([
|
||||
'gdkmacosglcontext.h',
|
||||
'gdkmacoskeymap.h',
|
||||
'gdkmacosmonitor.h',
|
||||
'gdkmacosseat.h',
|
||||
'gdkmacossurface.h',
|
||||
])
|
||||
|
||||
|
||||
@@ -2357,6 +2357,9 @@ touch_handle_down (void *data,
|
||||
|
||||
_gdk_wayland_display_update_serial (display, serial);
|
||||
|
||||
if (!wl_surface)
|
||||
return;
|
||||
|
||||
touch = gdk_wayland_seat_add_touch (seat, id, wl_surface);
|
||||
touch->x = wl_fixed_to_double (x);
|
||||
touch->y = wl_fixed_to_double (y);
|
||||
@@ -2404,6 +2407,9 @@ touch_handle_up (void *data,
|
||||
_gdk_wayland_display_update_serial (display, serial);
|
||||
|
||||
touch = gdk_wayland_seat_get_touch (seat, id);
|
||||
if (!touch)
|
||||
return;
|
||||
|
||||
event = gdk_touch_event_new (GDK_TOUCH_END,
|
||||
GDK_SLOT_TO_EVENT_SEQUENCE (touch->id),
|
||||
touch->surface,
|
||||
@@ -2442,6 +2448,9 @@ touch_handle_motion (void *data,
|
||||
GdkEvent *event;
|
||||
|
||||
touch = gdk_wayland_seat_get_touch (seat, id);
|
||||
if (!touch)
|
||||
return;
|
||||
|
||||
touch->x = wl_fixed_to_double (x);
|
||||
touch->y = wl_fixed_to_double (y);
|
||||
|
||||
@@ -3381,9 +3390,14 @@ tablet_tool_handle_proximity_in (void *data,
|
||||
GdkWaylandTabletData *tablet = zwp_tablet_v2_get_user_data (wp_tablet);
|
||||
GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (tablet->seat);
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (seat->display);
|
||||
GdkSurface *surface = wl_surface_get_user_data (wsurface);
|
||||
GdkSurface *surface;
|
||||
GdkEvent *event;
|
||||
|
||||
if (!wsurface)
|
||||
return;
|
||||
|
||||
surface = wl_surface_get_user_data (wsurface);
|
||||
|
||||
if (!surface)
|
||||
return;
|
||||
if (!GDK_IS_SURFACE (surface))
|
||||
@@ -3427,6 +3441,9 @@ tablet_tool_handle_proximity_out (void *data,
|
||||
GdkWaylandTabletData *tablet = tool->current_tablet;
|
||||
GdkEvent *event;
|
||||
|
||||
if (!tablet)
|
||||
return;
|
||||
|
||||
GDK_SEAT_NOTE (tool->seat, EVENTS,
|
||||
g_message ("proximity out, seat %p, tool %d", tool->seat,
|
||||
gdk_device_tool_get_tool_type (tool->tool)));
|
||||
@@ -3490,7 +3507,7 @@ tablet_tool_handle_down (void *data,
|
||||
GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (tool->seat);
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (seat->display);
|
||||
|
||||
if (!tablet->pointer_info.focus)
|
||||
if (!tablet || !tablet->pointer_info.focus)
|
||||
return;
|
||||
|
||||
_gdk_wayland_display_update_serial (display_wayland, serial);
|
||||
@@ -3507,7 +3524,7 @@ tablet_tool_handle_up (void *data,
|
||||
GdkWaylandTabletToolData *tool = data;
|
||||
GdkWaylandTabletData *tablet = tool->current_tablet;
|
||||
|
||||
if (!tablet->pointer_info.focus)
|
||||
if (!tablet || !tablet->pointer_info.focus)
|
||||
return;
|
||||
|
||||
tablet_create_button_event_frame (tablet, GDK_BUTTON_RELEASE, GDK_BUTTON_PRIMARY);
|
||||
@@ -3524,6 +3541,9 @@ tablet_tool_handle_motion (void *data,
|
||||
GdkWaylandTabletData *tablet = tool->current_tablet;
|
||||
GdkEvent *event;
|
||||
|
||||
if (!tablet)
|
||||
return;
|
||||
|
||||
tablet->pointer_info.surface_x = wl_fixed_to_double (sx);
|
||||
tablet->pointer_info.surface_y = wl_fixed_to_double (sy);
|
||||
|
||||
@@ -3551,7 +3571,12 @@ tablet_tool_handle_pressure (void *data,
|
||||
{
|
||||
GdkWaylandTabletToolData *tool = data;
|
||||
GdkWaylandTabletData *tablet = tool->current_tablet;
|
||||
int axis_index = tablet->axis_indices[GDK_AXIS_PRESSURE];
|
||||
int axis_index;
|
||||
|
||||
if (!tablet)
|
||||
return;
|
||||
|
||||
axis_index = tablet->axis_indices[GDK_AXIS_PRESSURE];
|
||||
|
||||
_gdk_device_translate_axis (tablet->stylus_device, axis_index,
|
||||
pressure, &tablet->axes[GDK_AXIS_PRESSURE]);
|
||||
@@ -3568,7 +3593,12 @@ tablet_tool_handle_distance (void *data,
|
||||
{
|
||||
GdkWaylandTabletToolData *tool = data;
|
||||
GdkWaylandTabletData *tablet = tool->current_tablet;
|
||||
int axis_index = tablet->axis_indices[GDK_AXIS_DISTANCE];
|
||||
int axis_index;
|
||||
|
||||
if (!tablet)
|
||||
return;
|
||||
|
||||
axis_index = tablet->axis_indices[GDK_AXIS_DISTANCE];
|
||||
|
||||
_gdk_device_translate_axis (tablet->stylus_device, axis_index,
|
||||
distance, &tablet->axes[GDK_AXIS_DISTANCE]);
|
||||
@@ -3586,8 +3616,14 @@ tablet_tool_handle_tilt (void *data,
|
||||
{
|
||||
GdkWaylandTabletToolData *tool = data;
|
||||
GdkWaylandTabletData *tablet = tool->current_tablet;
|
||||
int xtilt_axis_index = tablet->axis_indices[GDK_AXIS_XTILT];
|
||||
int ytilt_axis_index = tablet->axis_indices[GDK_AXIS_YTILT];
|
||||
int xtilt_axis_index;
|
||||
int ytilt_axis_index;
|
||||
|
||||
if (!tablet)
|
||||
return;
|
||||
|
||||
xtilt_axis_index = tablet->axis_indices[GDK_AXIS_XTILT];
|
||||
ytilt_axis_index = tablet->axis_indices[GDK_AXIS_YTILT];
|
||||
|
||||
_gdk_device_translate_axis (tablet->stylus_device, xtilt_axis_index,
|
||||
wl_fixed_to_double (xtilt),
|
||||
@@ -3614,7 +3650,7 @@ tablet_tool_handle_button (void *data,
|
||||
GdkEventType evtype;
|
||||
guint n_button;
|
||||
|
||||
if (!tablet->pointer_info.focus)
|
||||
if (!tablet || !tablet->pointer_info.focus)
|
||||
return;
|
||||
|
||||
tablet->pointer_info.press_serial = serial;
|
||||
@@ -3645,7 +3681,12 @@ tablet_tool_handle_rotation (void *data,
|
||||
{
|
||||
GdkWaylandTabletToolData *tool = data;
|
||||
GdkWaylandTabletData *tablet = tool->current_tablet;
|
||||
int axis_index = tablet->axis_indices[GDK_AXIS_ROTATION];
|
||||
int axis_index;
|
||||
|
||||
if (!tablet)
|
||||
return;
|
||||
|
||||
axis_index = tablet->axis_indices[GDK_AXIS_ROTATION];
|
||||
|
||||
_gdk_device_translate_axis (tablet->stylus_device, axis_index,
|
||||
wl_fixed_to_double (degrees),
|
||||
@@ -3664,7 +3705,12 @@ tablet_tool_handle_slider (void *data,
|
||||
{
|
||||
GdkWaylandTabletToolData *tool = data;
|
||||
GdkWaylandTabletData *tablet = tool->current_tablet;
|
||||
int axis_index = tablet->axis_indices[GDK_AXIS_SLIDER];
|
||||
int axis_index;
|
||||
|
||||
if (!tablet)
|
||||
return;
|
||||
|
||||
axis_index = tablet->axis_indices[GDK_AXIS_SLIDER];
|
||||
|
||||
_gdk_device_translate_axis (tablet->stylus_device, axis_index,
|
||||
position, &tablet->axes[GDK_AXIS_SLIDER]);
|
||||
@@ -3682,9 +3728,14 @@ tablet_tool_handle_wheel (void *data,
|
||||
{
|
||||
GdkWaylandTabletToolData *tool = data;
|
||||
GdkWaylandTabletData *tablet = tool->current_tablet;
|
||||
GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (tablet->seat);
|
||||
GdkWaylandSeat *seat;
|
||||
GdkEvent *event;
|
||||
|
||||
if (!tablet)
|
||||
return;
|
||||
|
||||
seat = GDK_WAYLAND_SEAT (tablet->seat);
|
||||
|
||||
GDK_SEAT_NOTE (seat, EVENTS,
|
||||
g_message ("tablet tool %d wheel %d/%d",
|
||||
gdk_device_tool_get_tool_type (tool->tool), degrees, clicks));
|
||||
@@ -3724,6 +3775,9 @@ tablet_tool_handle_frame (void *data,
|
||||
GdkWaylandTabletData *tablet = tool->current_tablet;
|
||||
GdkEvent *frame_event;
|
||||
|
||||
if (!tablet)
|
||||
return;
|
||||
|
||||
GDK_SEAT_NOTE (tablet->seat, EVENTS,
|
||||
g_message ("tablet frame, time %d", time));
|
||||
|
||||
@@ -4312,6 +4366,9 @@ pointer_surface_update_scale (GdkDevice *device)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!pointer->pointer_surface_outputs)
|
||||
return;
|
||||
|
||||
scale = 1;
|
||||
for (l = pointer->pointer_surface_outputs; l != NULL; l = l->next)
|
||||
{
|
||||
@@ -4319,6 +4376,8 @@ pointer_surface_update_scale (GdkDevice *device)
|
||||
scale = MAX (scale, output_scale);
|
||||
}
|
||||
|
||||
if (pointer->current_output_scale == scale)
|
||||
return;
|
||||
pointer->current_output_scale = scale;
|
||||
|
||||
gdk_wayland_device_update_surface_cursor (device);
|
||||
|
||||
@@ -94,7 +94,7 @@
|
||||
|
||||
#define MIN_SYSTEM_BELL_DELAY_MS 20
|
||||
|
||||
#define GTK_SHELL1_VERSION 3
|
||||
#define GTK_SHELL1_VERSION 4
|
||||
#define OUTPUT_VERSION_WITH_DONE 2
|
||||
#define NO_XDG_OUTPUT_DONE_SINCE_VERSION 3
|
||||
|
||||
@@ -1350,21 +1350,23 @@ _gdk_wayland_display_create_shm_surface (GdkWaylandDisplay *display,
|
||||
data->buffer = NULL;
|
||||
data->scale = scale;
|
||||
|
||||
stride = cairo_format_stride_for_width (CAIRO_FORMAT_ARGB32, width*scale);
|
||||
stride = cairo_format_stride_for_width (CAIRO_FORMAT_ARGB32, width * scale);
|
||||
|
||||
data->pool = create_shm_pool (display->shm,
|
||||
height*scale*stride,
|
||||
height * scale * stride,
|
||||
&data->buf_length,
|
||||
&data->buf);
|
||||
if (G_UNLIKELY (data->pool == NULL))
|
||||
g_error ("Unable to create shared memory pool");
|
||||
|
||||
surface = cairo_image_surface_create_for_data (data->buf,
|
||||
CAIRO_FORMAT_ARGB32,
|
||||
width*scale,
|
||||
height*scale,
|
||||
width * scale,
|
||||
height * scale,
|
||||
stride);
|
||||
|
||||
data->buffer = wl_shm_pool_create_buffer (data->pool, 0,
|
||||
width*scale, height*scale,
|
||||
width * scale, height * scale,
|
||||
stride, WL_SHM_FORMAT_ARGB8888);
|
||||
|
||||
cairo_surface_set_user_data (surface, &gdk_wayland_shm_surface_cairo_key,
|
||||
@@ -1836,6 +1838,7 @@ settings_portal_changed (GDBusProxy *proxy,
|
||||
char *a = g_variant_print (value, FALSE);
|
||||
g_debug ("Using changed portal setting %s %s: %s", namespace, name, a);
|
||||
g_free (a);
|
||||
entry->valid = TRUE;
|
||||
apply_portal_setting (entry, value, display);
|
||||
gdk_display_setting_changed (display, entry->setting);
|
||||
}
|
||||
|
||||
@@ -242,14 +242,22 @@ gdk_wayland_gl_context_end_frame (GdkDrawContext *draw_context,
|
||||
gdk_profiler_add_mark (GDK_PROFILER_CURRENT_TIME, 0, "wayland", "swap buffers");
|
||||
if (display_wayland->have_egl_swap_buffers_with_damage)
|
||||
{
|
||||
EGLint stack_rects[4 * 4]; /* 4 rects */
|
||||
EGLint *heap_rects = NULL;
|
||||
int i, j, n_rects = cairo_region_num_rectangles (painted);
|
||||
EGLint *rects = g_new (EGLint, n_rects * 4);
|
||||
cairo_rectangle_int_t rect;
|
||||
int surface_height = gdk_surface_get_height (surface);
|
||||
int scale = gdk_surface_get_scale_factor (surface);
|
||||
EGLint *rects;
|
||||
|
||||
if (n_rects < G_N_ELEMENTS (stack_rects) / 4)
|
||||
rects = (EGLint *)&stack_rects;
|
||||
else
|
||||
heap_rects = rects = g_new (EGLint, n_rects * 4);
|
||||
|
||||
for (i = 0, j = 0; i < n_rects; i++)
|
||||
{
|
||||
cairo_rectangle_int_t rect;
|
||||
|
||||
cairo_region_get_rectangle (painted, i, &rect);
|
||||
rects[j++] = rect.x * scale;
|
||||
rects[j++] = (surface_height - rect.height - rect.y) * scale;
|
||||
@@ -257,7 +265,7 @@ gdk_wayland_gl_context_end_frame (GdkDrawContext *draw_context,
|
||||
rects[j++] = rect.height * scale;
|
||||
}
|
||||
eglSwapBuffersWithDamageEXT (display_wayland->egl_display, egl_surface, rects, n_rects);
|
||||
g_free (rects);
|
||||
g_free (heap_rects);
|
||||
}
|
||||
else
|
||||
eglSwapBuffers (display_wayland->egl_display, egl_surface);
|
||||
@@ -293,27 +301,27 @@ gdk_wayland_get_display (GdkWaylandDisplay *display_wayland)
|
||||
if (epoxy_has_egl_extension (NULL, "EGL_KHR_platform_base"))
|
||||
{
|
||||
PFNEGLGETPLATFORMDISPLAYPROC getPlatformDisplay =
|
||||
(void *) eglGetProcAddress ("eglGetPlatformDisplay");
|
||||
(void *) eglGetProcAddress ("eglGetPlatformDisplay");
|
||||
|
||||
if (getPlatformDisplay)
|
||||
dpy = getPlatformDisplay (EGL_PLATFORM_WAYLAND_EXT,
|
||||
display_wayland->wl_display,
|
||||
NULL);
|
||||
dpy = getPlatformDisplay (EGL_PLATFORM_WAYLAND_EXT,
|
||||
display_wayland->wl_display,
|
||||
NULL);
|
||||
if (dpy)
|
||||
return dpy;
|
||||
return dpy;
|
||||
}
|
||||
|
||||
if (epoxy_has_egl_extension (NULL, "EGL_EXT_platform_base"))
|
||||
{
|
||||
PFNEGLGETPLATFORMDISPLAYEXTPROC getPlatformDisplay =
|
||||
(void *) eglGetProcAddress ("eglGetPlatformDisplayEXT");
|
||||
(void *) eglGetProcAddress ("eglGetPlatformDisplayEXT");
|
||||
|
||||
if (getPlatformDisplay)
|
||||
dpy = getPlatformDisplay (EGL_PLATFORM_WAYLAND_EXT,
|
||||
display_wayland->wl_display,
|
||||
NULL);
|
||||
dpy = getPlatformDisplay (EGL_PLATFORM_WAYLAND_EXT,
|
||||
display_wayland->wl_display,
|
||||
NULL);
|
||||
if (dpy)
|
||||
return dpy;
|
||||
return dpy;
|
||||
}
|
||||
|
||||
return eglGetDisplay ((EGLNativeDisplayType) display_wayland->wl_display);
|
||||
@@ -386,7 +394,7 @@ find_eglconfig_for_surface (GdkSurface *surface,
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
|
||||
EGLint attrs[MAX_EGL_ATTRS];
|
||||
EGLint count;
|
||||
EGLConfig *configs;
|
||||
EGLConfig config;
|
||||
int i = 0;
|
||||
|
||||
attrs[i++] = EGL_SURFACE_TYPE;
|
||||
@@ -407,39 +415,26 @@ find_eglconfig_for_surface (GdkSurface *surface,
|
||||
attrs[i++] = EGL_NONE;
|
||||
g_assert (i < MAX_EGL_ATTRS);
|
||||
|
||||
if (!eglChooseConfig (display_wayland->egl_display, attrs, NULL, 0, &count) || count < 1)
|
||||
{
|
||||
g_set_error_literal (error, GDK_GL_ERROR,
|
||||
GDK_GL_ERROR_UNSUPPORTED_FORMAT,
|
||||
_("No available configurations for the given pixel format"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
configs = g_new (EGLConfig, count);
|
||||
|
||||
if (!eglChooseConfig (display_wayland->egl_display, attrs, configs, count, &count) || count < 1)
|
||||
{
|
||||
g_set_error_literal (error, GDK_GL_ERROR,
|
||||
GDK_GL_ERROR_UNSUPPORTED_FORMAT,
|
||||
_("No available configurations for the given pixel format"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Pick first valid configuration i guess? */
|
||||
if (!eglChooseConfig (display_wayland->egl_display, attrs, &config, 1, &count) || count < 1)
|
||||
{
|
||||
g_set_error_literal (error, GDK_GL_ERROR,
|
||||
GDK_GL_ERROR_UNSUPPORTED_FORMAT,
|
||||
_("No available configurations for the given pixel format"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (egl_config_out != NULL)
|
||||
*egl_config_out = configs[0];
|
||||
|
||||
g_free (configs);
|
||||
g_assert (egl_config_out);
|
||||
*egl_config_out = config;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
GdkGLContext *
|
||||
gdk_wayland_surface_create_gl_context (GdkSurface *surface,
|
||||
gboolean attached,
|
||||
GdkGLContext *share,
|
||||
GError **error)
|
||||
gboolean attached,
|
||||
GdkGLContext *share,
|
||||
GError **error)
|
||||
{
|
||||
GdkDisplay *display = gdk_surface_get_display (surface);
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
|
||||
@@ -526,10 +521,10 @@ gdk_wayland_display_make_gl_context_current (GdkDisplay *display,
|
||||
else
|
||||
{
|
||||
if (display_wayland->have_egl_surfaceless_context)
|
||||
egl_surface = EGL_NO_SURFACE;
|
||||
egl_surface = EGL_NO_SURFACE;
|
||||
else
|
||||
egl_surface = gdk_wayland_surface_get_dummy_egl_surface (surface,
|
||||
context_wayland->egl_config);
|
||||
egl_surface = gdk_wayland_surface_get_dummy_egl_surface (surface,
|
||||
context_wayland->egl_config);
|
||||
}
|
||||
|
||||
if (!eglMakeCurrent (display_wayland->egl_display, egl_surface,
|
||||
|
||||
@@ -389,10 +389,13 @@ gdk_wayland_surface_update_size (GdkSurface *surface,
|
||||
int scale)
|
||||
{
|
||||
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
|
||||
gboolean width_changed, height_changed, scale_changed;
|
||||
|
||||
if ((surface->width == width) &&
|
||||
(surface->height == height) &&
|
||||
(impl->scale == scale))
|
||||
width_changed = surface->width != width;
|
||||
height_changed = surface->height != height;
|
||||
scale_changed = impl->scale != scale;
|
||||
|
||||
if (!width_changed && !height_changed && !scale_changed)
|
||||
return;
|
||||
|
||||
surface->width = width;
|
||||
@@ -405,6 +408,13 @@ gdk_wayland_surface_update_size (GdkSurface *surface,
|
||||
wl_surface_set_buffer_scale (impl->display_server.wl_surface, scale);
|
||||
|
||||
gdk_surface_invalidate_rect (surface, NULL);
|
||||
|
||||
if (width_changed)
|
||||
g_object_notify (G_OBJECT (surface), "width");
|
||||
if (height_changed)
|
||||
g_object_notify (G_OBJECT (surface), "height");
|
||||
if (scale_changed)
|
||||
g_object_notify (G_OBJECT (surface), "scale-factor");
|
||||
}
|
||||
|
||||
static const char *
|
||||
@@ -2213,6 +2223,24 @@ gdk_wayland_toplevel_announce_csd (GdkToplevel *toplevel)
|
||||
ORG_KDE_KWIN_SERVER_DECORATION_MANAGER_MODE_CLIENT);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_wayland_toplevel_announce_ssd (GdkToplevel *toplevel)
|
||||
{
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (GDK_SURFACE (toplevel)));
|
||||
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (toplevel);
|
||||
|
||||
g_return_if_fail (GDK_IS_WAYLAND_TOPLEVEL (toplevel));
|
||||
|
||||
if (!display_wayland->server_decoration_manager)
|
||||
return;
|
||||
impl->display_server.server_decoration =
|
||||
org_kde_kwin_server_decoration_manager_create (display_wayland->server_decoration_manager,
|
||||
impl->display_server.wl_surface);
|
||||
if (impl->display_server.server_decoration)
|
||||
org_kde_kwin_server_decoration_request_mode (impl->display_server.server_decoration,
|
||||
ORG_KDE_KWIN_SERVER_DECORATION_MANAGER_MODE_SERVER);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gdk_wayland_toplevel_inhibit_idle (GdkToplevel *toplevel)
|
||||
{
|
||||
@@ -2939,7 +2967,11 @@ gdk_wayland_surface_hide_surface (GdkSurface *surface)
|
||||
|
||||
if (impl->display_server.gtk_surface)
|
||||
{
|
||||
gtk_surface1_destroy (impl->display_server.gtk_surface);
|
||||
if (display_wayland->gtk_shell_version >=
|
||||
GTK_SURFACE1_RELEASE_SINCE_VERSION)
|
||||
gtk_surface1_release (impl->display_server.gtk_surface);
|
||||
else
|
||||
gtk_surface1_destroy (impl->display_server.gtk_surface);
|
||||
impl->display_server.gtk_surface = NULL;
|
||||
impl->application.was_set = FALSE;
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ void gdk_wayland_toplevel_set_dbus_properties (GdkTopl
|
||||
const char *unique_bus_name);
|
||||
|
||||
void gdk_wayland_toplevel_announce_csd (GdkToplevel *toplevel);
|
||||
void gdk_wayland_toplevel_announce_ssd (GdkToplevel *toplevel);
|
||||
|
||||
gboolean gdk_wayland_toplevel_inhibit_idle (GdkToplevel *toplevel);
|
||||
void gdk_wayland_toplevel_uninhibit_idle (GdkToplevel *toplevel);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<protocol name="gtk">
|
||||
|
||||
<interface name="gtk_shell1" version="3">
|
||||
<interface name="gtk_shell1" version="4">
|
||||
<description summary="gtk specific extensions">
|
||||
gtk_shell is a protocol extension providing additional features for
|
||||
clients implementing it.
|
||||
@@ -35,7 +35,7 @@
|
||||
</request>
|
||||
</interface>
|
||||
|
||||
<interface name="gtk_surface1" version="3">
|
||||
<interface name="gtk_surface1" version="4">
|
||||
<request name="set_dbus_properties">
|
||||
<arg name="application_id" type="string" allow-null="true"/>
|
||||
<arg name="app_menu_path" type="string" allow-null="true"/>
|
||||
@@ -82,6 +82,9 @@
|
||||
<request name="request_focus" since="3">
|
||||
<arg name="startup_id" type="string" allow-null="true"/>
|
||||
</request>
|
||||
|
||||
<!-- Version 4 additions -->
|
||||
<request name="release" type="destructor" since="4"/>
|
||||
</interface>
|
||||
|
||||
</protocol>
|
||||
|
||||
@@ -31,46 +31,6 @@
|
||||
|
||||
G_DEFINE_TYPE (GdkWin32CairoContext, gdk_win32_cairo_context, GDK_TYPE_CAIRO_CONTEXT)
|
||||
|
||||
static cairo_surface_t *
|
||||
create_cairo_surface_for_layered_window (GdkWin32Surface *impl,
|
||||
int width,
|
||||
int height,
|
||||
int scale)
|
||||
{
|
||||
if (width > impl->dib_width ||
|
||||
height > impl->dib_height)
|
||||
{
|
||||
cairo_surface_t *new_cache;
|
||||
|
||||
impl->dib_width = MAX (impl->dib_width, MAX (width, 1));
|
||||
impl->dib_height = MAX (impl->dib_height, MAX (height, 1));
|
||||
/* Create larger cache surface, copy old cache surface over it */
|
||||
new_cache = cairo_win32_surface_create_with_dib (CAIRO_FORMAT_ARGB32,
|
||||
impl->dib_width,
|
||||
impl->dib_height);
|
||||
|
||||
if (impl->cache_surface)
|
||||
{
|
||||
cairo_t *cr = cairo_create (new_cache);
|
||||
cairo_set_source_surface (cr, impl->cache_surface, 0, 0);
|
||||
cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
|
||||
cairo_paint (cr);
|
||||
cairo_destroy (cr);
|
||||
cairo_surface_flush (new_cache);
|
||||
|
||||
cairo_surface_destroy (impl->cache_surface);
|
||||
}
|
||||
|
||||
impl->cache_surface = new_cache;
|
||||
|
||||
cairo_surface_set_device_scale (impl->cache_surface,
|
||||
scale,
|
||||
scale);
|
||||
}
|
||||
|
||||
return cairo_surface_reference (impl->cache_surface);
|
||||
}
|
||||
|
||||
static cairo_surface_t *
|
||||
create_cairo_surface_for_surface (GdkSurface *surface,
|
||||
int scale)
|
||||
@@ -114,22 +74,11 @@ gdk_win32_cairo_context_begin_frame (GdkDrawContext *draw_context,
|
||||
width = MAX (width, 1);
|
||||
height = MAX (height, 1);
|
||||
|
||||
if (self->layered)
|
||||
self->window_surface = create_cairo_surface_for_layered_window (impl, width, height, scale);
|
||||
else
|
||||
self->window_surface = create_cairo_surface_for_surface (surface, scale);
|
||||
self->window_surface = create_cairo_surface_for_surface (surface, scale);
|
||||
|
||||
if (self->layered ||
|
||||
!self->double_buffered)
|
||||
{
|
||||
/* Layered windows paint on the window_surface (which is itself
|
||||
* an in-memory cache that the window maintains, since layered windows
|
||||
* do not support incremental redraws.
|
||||
* Non-double-buffered windows paint on the window surface directly
|
||||
* as well.
|
||||
*/
|
||||
self->paint_surface = cairo_surface_reference (self->window_surface);
|
||||
}
|
||||
if (!self->double_buffered)
|
||||
/* Non-double-buffered windows paint on the window surface directly */
|
||||
self->paint_surface = cairo_surface_reference (self->window_surface);
|
||||
else
|
||||
{
|
||||
if (width > self->db_width ||
|
||||
@@ -153,11 +102,10 @@ gdk_win32_cairo_context_begin_frame (GdkDrawContext *draw_context,
|
||||
}
|
||||
|
||||
/* Clear the paint region.
|
||||
* For non-double-buffered and for layered rendering we must
|
||||
* clear it, otherwise semi-transparent pixels will "add up"
|
||||
* with each repaint.
|
||||
* For double-buffered rendering we must clear the old pixels
|
||||
* from the DB cache surface that we're going to use as a buffer.
|
||||
* For non-double-buffered rendering we must clear it, otherwise
|
||||
* semi-transparent pixels will "add up" with each repaint.
|
||||
* We must also clear the old pixels from the DB cache surface
|
||||
* that we're going to use as a buffer.
|
||||
*/
|
||||
cr = cairo_create (self->paint_surface);
|
||||
cairo_set_source_rgba (cr, 0, 0, 0, 00);
|
||||
@@ -184,12 +132,10 @@ gdk_win32_cairo_context_end_frame (GdkDrawContext *draw_context,
|
||||
* to be here.
|
||||
*/
|
||||
|
||||
/* Layered windows have their own, special copying section
|
||||
* further down. For double-buffered windows we need to blit
|
||||
/* For double-buffered windows we need to blit
|
||||
* the DB buffer contents into the window itself.
|
||||
*/
|
||||
if (!self->layered &&
|
||||
self->double_buffered)
|
||||
if (self->double_buffered)
|
||||
{
|
||||
cairo_t *cr;
|
||||
|
||||
@@ -207,18 +153,6 @@ gdk_win32_cairo_context_end_frame (GdkDrawContext *draw_context,
|
||||
|
||||
cairo_surface_flush (self->window_surface);
|
||||
|
||||
/* Update layered window, updating its contents, size and position
|
||||
* in one call.
|
||||
*/
|
||||
if (self->layered)
|
||||
{
|
||||
RECT client_rect;
|
||||
|
||||
/* Get the position/size of the window that GDK wants. */
|
||||
_gdk_win32_get_window_client_area_rect (surface, scale, &client_rect);
|
||||
_gdk_win32_update_layered_window_from_cache (surface, &client_rect, TRUE, TRUE, TRUE);
|
||||
}
|
||||
|
||||
g_clear_pointer (&self->paint_surface, cairo_surface_destroy);
|
||||
g_clear_pointer (&self->window_surface, cairo_surface_destroy);
|
||||
}
|
||||
|
||||
@@ -44,10 +44,6 @@ struct _GdkWin32CairoContext
|
||||
* code that is unaffected by this flag.
|
||||
*/
|
||||
guint double_buffered : 1;
|
||||
/* Re-set to the same value as GdkSurfaceImplWin32->layered
|
||||
* every frame (since layeredness can change at runtime).
|
||||
*/
|
||||
guint layered : 1;
|
||||
|
||||
/* The a surface for double-buffering. We keep it
|
||||
* around between repaints, and only re-allocate it
|
||||
@@ -56,12 +52,11 @@ struct _GdkWin32CairoContext
|
||||
int db_width;
|
||||
int db_height;
|
||||
|
||||
/* Surface for the window DC (in non-layered mode).
|
||||
* A reference of the cache surface (in layered mode). */
|
||||
/* Surface for the window DC */
|
||||
cairo_surface_t *window_surface;
|
||||
/* A reference to db_surface (when double-buffering).
|
||||
* When not using double-buffering or in layered mode
|
||||
* this is a reference to window_surface.
|
||||
* When not using double-buffering this is a reference
|
||||
* to window_surface.
|
||||
*/
|
||||
cairo_surface_t *paint_surface;
|
||||
};
|
||||
|
||||
@@ -2113,7 +2113,6 @@ gdk_drag_anim_timeout (gpointer data)
|
||||
(drag->start_y - drag->util_data.last_y) * t -
|
||||
drag->hot_y);
|
||||
gdk_win32_surface_move (drag->drag_surface, x, y);
|
||||
gdk_win32_surface_set_opacity (drag->drag_surface, 1.0 - f);
|
||||
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
@@ -1495,15 +1495,6 @@ handle_dpi_changed (GdkSurface *window,
|
||||
|
||||
monitor = gdk_display_get_monitor_at_surface (display, window);
|
||||
gdk_monitor_set_scale_factor (monitor, impl->surface_scale);
|
||||
|
||||
if (impl->layered)
|
||||
{
|
||||
/* We only need to set the cairo surface device scale here ourselves for layered windows */
|
||||
if (impl->cache_surface != NULL)
|
||||
cairo_surface_set_device_scale (impl->cache_surface,
|
||||
impl->surface_scale,
|
||||
impl->surface_scale);
|
||||
}
|
||||
}
|
||||
|
||||
_gdk_win32_adjust_client_rect (window, rect);
|
||||
@@ -1721,8 +1712,8 @@ _gdk_win32_surface_fill_min_max_info (GdkSurface *window,
|
||||
mmi->ptMaxSize.y = nearest_info.rcWork.bottom - nearest_info.rcWork.top;
|
||||
}
|
||||
|
||||
mmi->ptMaxTrackSize.x = GetSystemMetrics (SM_CXVIRTUALSCREEN) + impl->margins_x * impl->surface_scale;
|
||||
mmi->ptMaxTrackSize.y = GetSystemMetrics (SM_CYVIRTUALSCREEN) + impl->margins_y * impl->surface_scale;
|
||||
mmi->ptMaxTrackSize.x = GetSystemMetrics (SM_CXVIRTUALSCREEN) + impl->shadow_x * impl->surface_scale;
|
||||
mmi->ptMaxTrackSize.y = GetSystemMetrics (SM_CYVIRTUALSCREEN) + impl->shadow_y * impl->surface_scale;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
@@ -2354,9 +2345,7 @@ gdk_event_translate (MSG *msg,
|
||||
|
||||
|
||||
if (impl->drag_move_resize_context.op != GDK_WIN32_DRAGOP_NONE)
|
||||
{
|
||||
gdk_win32_surface_do_move_resize_drag (window, current_root_x, current_root_y);
|
||||
}
|
||||
gdk_win32_surface_do_move_resize_drag (window, current_root_x, current_root_y);
|
||||
else if (_gdk_input_ignore_core == 0)
|
||||
{
|
||||
current_x = (gint16) GET_X_LPARAM (msg->lParam) / impl->surface_scale;
|
||||
@@ -2835,6 +2824,16 @@ gdk_event_translate (MSG *msg,
|
||||
else
|
||||
unset_bits |= GDK_TOPLEVEL_STATE_MAXIMIZED;
|
||||
|
||||
/*
|
||||
* If we are minizing, pause all surface layout computations, and re-start the
|
||||
* computation once we are coming out of a minimized state
|
||||
*/
|
||||
if (!(old_state & GDK_TOPLEVEL_STATE_MINIMIZED) && set_bits & GDK_TOPLEVEL_STATE_MINIMIZED)
|
||||
gdk_surface_freeze_updates (window);
|
||||
|
||||
if (old_state & GDK_TOPLEVEL_STATE_MINIMIZED && unset_bits & GDK_TOPLEVEL_STATE_MINIMIZED)
|
||||
gdk_surface_thaw_updates (window);
|
||||
|
||||
gdk_surface_set_is_mapped (window, !!IsWindowVisible (msg->hwnd));
|
||||
gdk_synthesize_surface_state (window, unset_bits, set_bits);
|
||||
|
||||
|
||||
@@ -88,19 +88,6 @@ _gdk_win32_gl_context_dispose (GObject *gobject)
|
||||
#endif
|
||||
}
|
||||
|
||||
if (surface != NULL)
|
||||
{
|
||||
GdkWin32Surface *impl = GDK_WIN32_SURFACE (surface);
|
||||
|
||||
if (impl->suppress_layered > 0)
|
||||
impl->suppress_layered--;
|
||||
|
||||
/* If we don't have any surface that forces layered windows off,
|
||||
* trigger update_style_bits() to enable layered windows again
|
||||
*/
|
||||
if (impl->suppress_layered == 0)
|
||||
_gdk_win32_surface_update_style_bits (surface);
|
||||
}
|
||||
G_OBJECT_CLASS (gdk_win32_gl_context_parent_class)->dispose (gobject);
|
||||
}
|
||||
|
||||
@@ -1001,17 +988,6 @@ gdk_win32_gl_context_realize (GdkGLContext *context,
|
||||
/* set whether we are using GLES */
|
||||
gdk_gl_context_set_use_es (context, use_es);
|
||||
|
||||
/* OpenGL does not work with WS_EX_LAYERED enabled, so we need to
|
||||
* disable WS_EX_LAYERED when we acquire a valid HGLRC
|
||||
*/
|
||||
impl->suppress_layered++;
|
||||
|
||||
/* if this is the first time a GL context is acquired for the surface,
|
||||
* disable layered windows by triggering update_style_bits()
|
||||
*/
|
||||
if (impl->suppress_layered == 1)
|
||||
_gdk_win32_surface_update_style_bits (surface);
|
||||
|
||||
/* Ensure that any other context is created with a legacy bit set */
|
||||
gdk_gl_context_set_is_legacy (context, legacy_bit);
|
||||
|
||||
|
||||
@@ -351,7 +351,6 @@ _gdk_win32_surface_exstyle_to_string (LONG style)
|
||||
BIT (CONTEXTHELP);
|
||||
BIT (CONTROLPARENT);
|
||||
BIT (DLGMODALFRAME);
|
||||
BIT (LAYERED);
|
||||
BIT (LAYOUTRTL);
|
||||
BIT (LEFTSCROLLBAR);
|
||||
BIT (MDICHILD);
|
||||
|
||||
@@ -53,6 +53,10 @@
|
||||
#include <math.h>
|
||||
|
||||
static void gdk_surface_win32_finalize (GObject *object);
|
||||
static void compute_toplevel_size (GdkSurface *surface,
|
||||
gboolean update_geometry,
|
||||
int *width,
|
||||
int *height);
|
||||
|
||||
static gpointer parent_class = NULL;
|
||||
static GSList *modal_window_stack = NULL;
|
||||
@@ -271,7 +275,6 @@ _gdk_win32_adjust_client_rect (GdkSurface *window,
|
||||
gboolean
|
||||
_gdk_win32_surface_enable_transparency (GdkSurface *window)
|
||||
{
|
||||
GdkWin32Surface *impl;
|
||||
DWM_BLURBEHIND blur_behind;
|
||||
HRGN empty_region;
|
||||
HRESULT call_result;
|
||||
@@ -280,12 +283,6 @@ _gdk_win32_surface_enable_transparency (GdkSurface *window)
|
||||
if (window == NULL || GDK_SURFACE_HWND (window) == NULL)
|
||||
return FALSE;
|
||||
|
||||
impl = GDK_WIN32_SURFACE (window);
|
||||
|
||||
/* layered windows don't need blurbehind for transparency */
|
||||
if (impl->layered)
|
||||
return TRUE;
|
||||
|
||||
if (!gdk_display_is_composited (gdk_surface_get_display (window)))
|
||||
return FALSE;
|
||||
|
||||
@@ -522,9 +519,6 @@ _gdk_win32_display_create_surface (GdkDisplay *display,
|
||||
surface->width = width;
|
||||
surface->height = height;
|
||||
|
||||
impl->layered = FALSE;
|
||||
impl->layered_opacity = 1.0;
|
||||
|
||||
impl->surface_scale = _gdk_win32_display_get_monitor_scale_factor (display_win32, NULL, NULL, NULL);
|
||||
impl->unscaled_width = width * impl->surface_scale;
|
||||
impl->unscaled_height = height * impl->surface_scale;
|
||||
@@ -1100,6 +1094,8 @@ gdk_win32_surface_resize (GdkSurface *window,
|
||||
outer_rect.bottom - outer_rect.top,
|
||||
SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER));
|
||||
window->resize_count += 1;
|
||||
|
||||
gdk_surface_request_layout (window);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1160,8 +1156,6 @@ gdk_win32_surface_move_resize_internal (GdkSurface *window,
|
||||
{
|
||||
GdkWin32Surface *surface = GDK_WIN32_SURFACE (window);
|
||||
|
||||
surface->inhibit_configure = TRUE;
|
||||
|
||||
/* We ignore changes to the window being moved or resized by the
|
||||
user, as we don't want to fight the user */
|
||||
if (GDK_SURFACE_HWND (window) == _modal_move_resize_window)
|
||||
@@ -1186,8 +1180,6 @@ gdk_win32_surface_move_resize_internal (GdkSurface *window,
|
||||
}
|
||||
|
||||
out:
|
||||
surface->inhibit_configure = FALSE;
|
||||
|
||||
gdk_surface_request_layout (window);
|
||||
}
|
||||
|
||||
@@ -1228,10 +1220,10 @@ gdk_win32_surface_layout_popup (GdkSurface *surface,
|
||||
gdk_surface_layout_popup_helper (surface,
|
||||
width,
|
||||
height,
|
||||
impl->margins.left,
|
||||
impl->margins.right,
|
||||
impl->margins.top,
|
||||
impl->margins.bottom,
|
||||
impl->shadow.left,
|
||||
impl->shadow.right,
|
||||
impl->shadow.top,
|
||||
impl->shadow.bottom,
|
||||
monitor,
|
||||
&bounds,
|
||||
layout,
|
||||
@@ -1256,11 +1248,24 @@ gdk_win32_surface_layout_popup (GdkSurface *surface,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
maybe_notify_mapped (GdkSurface *surface)
|
||||
{
|
||||
if (surface->destroyed)
|
||||
return;
|
||||
|
||||
if (!GDK_SURFACE_IS_MAPPED (surface))
|
||||
{
|
||||
gdk_surface_set_is_mapped (surface, TRUE);
|
||||
gdk_surface_invalidate_rect (surface, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
show_popup (GdkSurface *surface)
|
||||
{
|
||||
gdk_win32_surface_raise (surface);
|
||||
gdk_surface_set_is_mapped (surface, TRUE);
|
||||
maybe_notify_mapped (surface);
|
||||
show_window_internal (surface, FALSE, FALSE);
|
||||
gdk_surface_invalidate_rect (surface, NULL);
|
||||
}
|
||||
@@ -1746,11 +1751,6 @@ update_single_bit (LONG *style,
|
||||
* Returns TRUE if window has no decorations.
|
||||
* Usually it means CSD windows, because GTK
|
||||
* calls gdk_surface_set_decorations (window, 0);
|
||||
* This is used to decide whether a toplevel should
|
||||
* be made layered, thus it
|
||||
* only returns TRUE for toplevels (until GTK minimal
|
||||
* system requirements are lifted to Windows 8 or newer,
|
||||
* because only toplevels can be layered).
|
||||
*/
|
||||
gboolean
|
||||
_gdk_win32_surface_lacks_wm_decorations (GdkSurface *window)
|
||||
@@ -1844,27 +1844,6 @@ _gdk_win32_surface_update_style_bits (GdkSurface *window)
|
||||
new_exstyle &= ~WS_EX_TOOLWINDOW;
|
||||
}
|
||||
|
||||
/* We can get away with using layered windows
|
||||
* only when no decorations are needed. It can mean
|
||||
* CSD or borderless non-CSD windows (tooltips?).
|
||||
*
|
||||
* If this window cannot use layered windows, disable it always.
|
||||
* This currently applies to windows using OpenGL, which
|
||||
* does not work with layered windows.
|
||||
*/
|
||||
if (impl->suppress_layered == 0)
|
||||
{
|
||||
if (_gdk_win32_surface_lacks_wm_decorations (window))
|
||||
impl->layered = g_strcmp0 (g_getenv ("GDK_WIN32_LAYERED"), "0") != 0;
|
||||
}
|
||||
else
|
||||
impl->layered = FALSE;
|
||||
|
||||
if (impl->layered)
|
||||
new_exstyle |= WS_EX_LAYERED;
|
||||
else
|
||||
new_exstyle &= ~WS_EX_LAYERED;
|
||||
|
||||
if (get_effective_window_decorations (window, &decorations))
|
||||
{
|
||||
all = (decorations & GDK_DECOR_ALL);
|
||||
@@ -2294,6 +2273,7 @@ snap_up (GdkSurface *window)
|
||||
impl = GDK_WIN32_SURFACE (window);
|
||||
|
||||
impl->snap_state = GDK_WIN32_AEROSNAP_STATE_FULLUP;
|
||||
impl->resized = FALSE;
|
||||
|
||||
stash_window (window, impl);
|
||||
|
||||
@@ -2304,10 +2284,18 @@ snap_up (GdkSurface *window)
|
||||
y = 0;
|
||||
height = maxysize;
|
||||
|
||||
x = x - impl->margins.left;
|
||||
y = y - impl->margins.top;
|
||||
width += impl->margins_x;
|
||||
height += impl->margins_y;
|
||||
x = x - impl->shadow.left;
|
||||
y = y - impl->shadow.top;
|
||||
width += impl->shadow_x;
|
||||
height += impl->shadow_y;
|
||||
|
||||
/* XXX: FIXME, AeroSnap snap_up() not really working well,
|
||||
*
|
||||
* * The snap_up() puts the window at the top left corner.
|
||||
* * Without the following call, the height maximizes but we see a spew of
|
||||
* "GdkToplevelSize: geometry size (x,y) exceeds bounds" warnings
|
||||
*/
|
||||
compute_toplevel_size (window, TRUE, &width, &height);
|
||||
|
||||
gdk_win32_surface_move_resize (window, x, y, width, height);
|
||||
}
|
||||
@@ -2323,6 +2311,7 @@ snap_left (GdkSurface *window,
|
||||
impl = GDK_WIN32_SURFACE (window);
|
||||
|
||||
impl->snap_state = GDK_WIN32_AEROSNAP_STATE_HALFLEFT;
|
||||
impl->resized = FALSE;
|
||||
|
||||
gdk_win32_monitor_get_workarea (snap_monitor, &rect);
|
||||
|
||||
@@ -2330,10 +2319,10 @@ snap_left (GdkSurface *window,
|
||||
|
||||
rect.width = rect.width / 2;
|
||||
|
||||
rect.x = rect.x - impl->margins.left;
|
||||
rect.y = rect.y - impl->margins.top;
|
||||
rect.width = rect.width + impl->margins_x;
|
||||
rect.height = rect.height + impl->margins_y;
|
||||
rect.x = rect.x - impl->shadow.left;
|
||||
rect.y = rect.y - impl->shadow.top;
|
||||
rect.width = rect.width + impl->shadow_x;
|
||||
rect.height = rect.height + impl->shadow_y;
|
||||
|
||||
gdk_win32_surface_move_resize (window,
|
||||
rect.x, rect.y,
|
||||
@@ -2351,6 +2340,7 @@ snap_right (GdkSurface *window,
|
||||
impl = GDK_WIN32_SURFACE (window);
|
||||
|
||||
impl->snap_state = GDK_WIN32_AEROSNAP_STATE_HALFRIGHT;
|
||||
impl->resized = FALSE;
|
||||
|
||||
gdk_win32_monitor_get_workarea (snap_monitor, &rect);
|
||||
|
||||
@@ -2359,10 +2349,10 @@ snap_right (GdkSurface *window,
|
||||
rect.width = rect.width / 2;
|
||||
rect.x += rect.width;
|
||||
|
||||
rect.x = rect.x - impl->margins.left;
|
||||
rect.y = rect.y - impl->margins.top;
|
||||
rect.width = rect.width + impl->margins_x;
|
||||
rect.height = rect.height + impl->margins_y;
|
||||
rect.x = rect.x - impl->shadow.left;
|
||||
rect.y = rect.y - impl->shadow.top;
|
||||
rect.width = rect.width + impl->shadow_x;
|
||||
rect.height = rect.height + impl->shadow_y;
|
||||
|
||||
gdk_win32_surface_move_resize (window,
|
||||
rect.x, rect.y,
|
||||
@@ -3502,10 +3492,10 @@ setup_drag_move_resize_context (GdkSurface *window,
|
||||
*/
|
||||
if (op == GDK_WIN32_DRAGOP_MOVE && !maximized)
|
||||
{
|
||||
swx += impl->margins.left / impl->surface_scale;
|
||||
swy += impl->margins.top / impl->surface_scale;
|
||||
swwidth -= impl->margins_x;
|
||||
swheight -= impl->margins_y;
|
||||
swx += impl->shadow.left / impl->surface_scale;
|
||||
swy += impl->shadow.top / impl->surface_scale;
|
||||
swwidth -= impl->shadow_x;
|
||||
swheight -= impl->shadow_y;
|
||||
}
|
||||
|
||||
pointer_outside_of_window = root_x < swx || root_x > swx + swwidth ||
|
||||
@@ -3555,23 +3545,23 @@ setup_drag_move_resize_context (GdkSurface *window,
|
||||
unmax_width = placement.rcNormalPosition.right - placement.rcNormalPosition.left;
|
||||
unmax_height = placement.rcNormalPosition.bottom - placement.rcNormalPosition.top;
|
||||
|
||||
shadow_unmax_width = unmax_width - impl->margins_x * impl->surface_scale;
|
||||
shadow_unmax_height = unmax_height - impl->margins_y * impl->surface_scale;
|
||||
shadow_unmax_width = unmax_width - impl->shadow_x * impl->surface_scale;
|
||||
shadow_unmax_height = unmax_height - impl->shadow_y * impl->surface_scale;
|
||||
|
||||
if (offsetx * impl->surface_scale < (shadow_unmax_width / 2) &&
|
||||
offsety * impl->surface_scale < (shadow_unmax_height / 2))
|
||||
{
|
||||
placement.rcNormalPosition.top = (root_y - offsety + impl->margins.top - _gdk_offset_y) * impl->surface_scale;
|
||||
placement.rcNormalPosition.top = (root_y - offsety + impl->shadow.top - _gdk_offset_y) * impl->surface_scale;
|
||||
placement.rcNormalPosition.bottom = placement.rcNormalPosition.top + unmax_height;
|
||||
|
||||
if (left_half)
|
||||
{
|
||||
placement.rcNormalPosition.left = (root_x - offsetx + impl->margins.left - _gdk_offset_x) * impl->surface_scale;
|
||||
placement.rcNormalPosition.left = (root_x - offsetx + impl->shadow.left - _gdk_offset_x) * impl->surface_scale;
|
||||
placement.rcNormalPosition.right = placement.rcNormalPosition.left + unmax_width;
|
||||
}
|
||||
else
|
||||
{
|
||||
placement.rcNormalPosition.right = (root_x + offsetx + impl->margins.right - _gdk_offset_x) * impl->surface_scale;
|
||||
placement.rcNormalPosition.right = (root_x + offsetx + impl->shadow.right - _gdk_offset_x) * impl->surface_scale;
|
||||
placement.rcNormalPosition.left = placement.rcNormalPosition.right - unmax_width;
|
||||
}
|
||||
}
|
||||
@@ -3582,7 +3572,7 @@ setup_drag_move_resize_context (GdkSurface *window,
|
||||
(_gdk_offset_x * impl->surface_scale);
|
||||
|
||||
if (offsety * impl->surface_scale < shadow_unmax_height / 2)
|
||||
placement.rcNormalPosition.top = (root_y - offsety + impl->margins.top - _gdk_offset_y) * impl->surface_scale;
|
||||
placement.rcNormalPosition.top = (root_y - offsety + impl->shadow.top - _gdk_offset_y) * impl->surface_scale;
|
||||
else
|
||||
placement.rcNormalPosition.top = (root_y * impl->surface_scale) -
|
||||
(unmax_height / 2) -
|
||||
@@ -3609,18 +3599,18 @@ setup_drag_move_resize_context (GdkSurface *window,
|
||||
|
||||
if (op == GDK_WIN32_DRAGOP_MOVE)
|
||||
{
|
||||
snew_pos.width -= impl->margins_x;
|
||||
snew_pos.height -= impl->margins_y;
|
||||
snew_pos.width -= impl->shadow_x;
|
||||
snew_pos.height -= impl->shadow_y;
|
||||
}
|
||||
|
||||
if (offsetx < snew_pos.width / 2 && offsety < snew_pos.height / 2)
|
||||
{
|
||||
new_pos.y = root_y - offsety + impl->margins.top / impl->surface_scale;
|
||||
new_pos.y = root_y - offsety + impl->shadow.top / impl->surface_scale;
|
||||
|
||||
if (left_half)
|
||||
new_pos.x = root_x - offsetx + impl->margins.left / impl->surface_scale;
|
||||
new_pos.x = root_x - offsetx + impl->shadow.left / impl->surface_scale;
|
||||
else
|
||||
new_pos.x = root_x + offsetx + impl->margins.left / impl->surface_scale - new_pos.width;
|
||||
new_pos.x = root_x + offsetx + impl->shadow.left / impl->surface_scale - new_pos.width;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -3785,67 +3775,6 @@ gdk_win32_get_window_size_and_position_from_client_rect (GdkSurface *window,
|
||||
window_size->cy = window_rect->bottom - window_rect->top;
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_win32_update_layered_window_from_cache (GdkSurface *surface,
|
||||
RECT *client_rect,
|
||||
gboolean do_move,
|
||||
gboolean do_resize,
|
||||
gboolean do_paint)
|
||||
{
|
||||
POINT window_position;
|
||||
SIZE window_size;
|
||||
BLENDFUNCTION blender;
|
||||
HDC hdc;
|
||||
SIZE *window_size_ptr;
|
||||
POINT source_point = { 0, 0 };
|
||||
POINT *source_point_ptr;
|
||||
GdkWin32Surface *impl = GDK_WIN32_SURFACE (surface);
|
||||
|
||||
gdk_win32_get_window_size_and_position_from_client_rect (surface,
|
||||
client_rect,
|
||||
&window_size,
|
||||
&window_position);
|
||||
|
||||
blender.BlendOp = AC_SRC_OVER;
|
||||
blender.BlendFlags = 0;
|
||||
blender.AlphaFormat = AC_SRC_ALPHA;
|
||||
blender.SourceConstantAlpha = impl->layered_opacity * 255;
|
||||
|
||||
/* Strictly speaking, we don't need to supply hdc, source_point and
|
||||
* window_size to just move the window. However, without these arguments
|
||||
* the window moves but does not update its contents on Windows 7 when
|
||||
* desktop composition is off. This forces us to provide hdc and
|
||||
* source_point. window_size is here to avoid the function
|
||||
* inexplicably failing with error 317.
|
||||
*/
|
||||
hdc = cairo_win32_surface_get_dc (impl->cache_surface);
|
||||
window_size_ptr = &window_size;
|
||||
source_point_ptr = &source_point;
|
||||
|
||||
if (gdk_display_is_composited (gdk_surface_get_display (surface)))
|
||||
{
|
||||
if (!do_paint)
|
||||
hdc = NULL;
|
||||
if (!do_resize)
|
||||
window_size_ptr = NULL;
|
||||
if (!do_move)
|
||||
source_point_ptr = NULL;
|
||||
}
|
||||
|
||||
/* Don't use UpdateLayeredWindow on minimized windows */
|
||||
if (IsIconic (GDK_SURFACE_HWND (surface)))
|
||||
API_CALL (SetWindowPos, (GDK_SURFACE_HWND (surface),
|
||||
SWP_NOZORDER_SPECIFIED,
|
||||
window_position.x, window_position.y,
|
||||
window_size.cx, window_size.cy,
|
||||
SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOREDRAW));
|
||||
else
|
||||
API_CALL (UpdateLayeredWindow, (GDK_SURFACE_HWND (surface), NULL,
|
||||
&window_position, window_size_ptr,
|
||||
hdc, source_point_ptr,
|
||||
0, &blender, ULW_ALPHA));
|
||||
}
|
||||
|
||||
void
|
||||
gdk_win32_surface_do_move_resize_drag (GdkSurface *window,
|
||||
int x,
|
||||
@@ -4015,42 +3944,47 @@ gdk_win32_surface_do_move_resize_drag (GdkSurface *window,
|
||||
rect.top != new_rect.top ||
|
||||
rect.bottom != new_rect.bottom))
|
||||
{
|
||||
if (GDK_IS_TOPLEVEL (window))
|
||||
{
|
||||
int scale = impl->surface_scale;
|
||||
|
||||
impl->unscaled_width = new_rect.right - new_rect.left;
|
||||
impl->unscaled_height = new_rect.bottom - new_rect.top;
|
||||
impl->next_layout.configured_width = (impl->unscaled_width + scale - 1) / scale;
|
||||
impl->next_layout.configured_height = (impl->unscaled_height + scale - 1) / scale;
|
||||
impl->resized = TRUE;
|
||||
}
|
||||
|
||||
context->native_move_resize_pending = TRUE;
|
||||
gdk_surface_request_layout (window);
|
||||
}
|
||||
else if (context->op == GDK_WIN32_DRAGOP_MOVE &&
|
||||
(rect.left != new_rect.left ||
|
||||
rect.top != new_rect.top))
|
||||
{
|
||||
SIZE window_size;
|
||||
POINT window_position;
|
||||
|
||||
context->native_move_resize_pending = FALSE;
|
||||
|
||||
gdk_surface_request_layout (window);
|
||||
|
||||
if (impl->layered)
|
||||
{
|
||||
_gdk_win32_update_layered_window_from_cache (window, &new_rect, TRUE, FALSE, FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
SIZE window_size;
|
||||
POINT window_position;
|
||||
gdk_win32_get_window_size_and_position_from_client_rect (window,
|
||||
&new_rect,
|
||||
&window_size,
|
||||
&window_position);
|
||||
|
||||
gdk_win32_get_window_size_and_position_from_client_rect (window,
|
||||
&new_rect,
|
||||
&window_size,
|
||||
&window_position);
|
||||
|
||||
API_CALL (SetWindowPos, (GDK_SURFACE_HWND (window),
|
||||
SWP_NOZORDER_SPECIFIED,
|
||||
window_position.x, window_position.y,
|
||||
0, 0,
|
||||
SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE));
|
||||
}
|
||||
API_CALL (SetWindowPos, (GDK_SURFACE_HWND (window),
|
||||
SWP_NOZORDER_SPECIFIED,
|
||||
window_position.x, window_position.y,
|
||||
0, 0,
|
||||
SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE));
|
||||
}
|
||||
|
||||
if (context->op == GDK_WIN32_DRAGOP_RESIZE ||
|
||||
context->op == GDK_WIN32_DRAGOP_MOVE)
|
||||
handle_aerosnap_move_resize (window, context, x, y);
|
||||
|
||||
gdk_surface_request_layout (window);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -4159,6 +4093,7 @@ gdk_win32_surface_minimize (GdkSurface *window)
|
||||
static void
|
||||
gdk_win32_surface_maximize (GdkSurface *window)
|
||||
{
|
||||
GdkWin32Surface *impl;
|
||||
|
||||
g_return_if_fail (GDK_IS_SURFACE (window));
|
||||
|
||||
@@ -4169,6 +4104,9 @@ gdk_win32_surface_maximize (GdkSurface *window)
|
||||
GDK_SURFACE_HWND (window),
|
||||
_gdk_win32_surface_state_to_string (window->state)));
|
||||
|
||||
impl = GDK_WIN32_SURFACE (window);
|
||||
impl->resized = FALSE;
|
||||
|
||||
if (GDK_SURFACE_IS_MAPPED (window))
|
||||
GtkShowWindow (window, SW_MAXIMIZE);
|
||||
else
|
||||
@@ -4313,61 +4251,6 @@ gdk_win32_surface_lookup_for_display (GdkDisplay *display,
|
||||
return (GdkSurface*) gdk_win32_handle_table_lookup (anid);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_win32_surface_set_opacity (GdkSurface *window,
|
||||
double opacity)
|
||||
{
|
||||
LONG exstyle;
|
||||
typedef BOOL (WINAPI *PFN_SetLayeredWindowAttributes) (HWND, COLORREF, BYTE, DWORD);
|
||||
PFN_SetLayeredWindowAttributes setLayeredWindowAttributes = NULL;
|
||||
GdkWin32Surface *impl;
|
||||
|
||||
g_return_if_fail (GDK_IS_SURFACE (window));
|
||||
|
||||
if (GDK_SURFACE_DESTROYED (window))
|
||||
return;
|
||||
|
||||
if (opacity < 0)
|
||||
opacity = 0;
|
||||
else if (opacity > 1)
|
||||
opacity = 1;
|
||||
|
||||
impl = GDK_WIN32_SURFACE (window);
|
||||
|
||||
if (impl->layered)
|
||||
{
|
||||
if (impl->layered_opacity != opacity)
|
||||
{
|
||||
RECT window_rect;
|
||||
|
||||
impl->layered_opacity = opacity;
|
||||
|
||||
_gdk_win32_get_window_client_area_rect (window, impl->surface_scale, &window_rect);
|
||||
_gdk_win32_update_layered_window_from_cache (window, &window_rect, TRUE, TRUE, TRUE);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
exstyle = GetWindowLong (GDK_SURFACE_HWND (window), GWL_EXSTYLE);
|
||||
|
||||
if (!(exstyle & WS_EX_LAYERED))
|
||||
SetWindowLong (GDK_SURFACE_HWND (window),
|
||||
GWL_EXSTYLE,
|
||||
exstyle | WS_EX_LAYERED);
|
||||
|
||||
setLayeredWindowAttributes =
|
||||
(PFN_SetLayeredWindowAttributes)GetProcAddress (GetModuleHandle ("user32.dll"), "SetLayeredWindowAttributes");
|
||||
|
||||
if (setLayeredWindowAttributes)
|
||||
{
|
||||
API_CALL (setLayeredWindowAttributes, (GDK_SURFACE_HWND (window),
|
||||
0,
|
||||
opacity * 0xff,
|
||||
LWA_ALPHA));
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
gdk_win32_surface_is_win32 (GdkSurface *window)
|
||||
{
|
||||
@@ -4447,9 +4330,6 @@ GtkShowWindow (GdkSurface *window,
|
||||
if (IsWindowVisible (hwnd))
|
||||
break;
|
||||
|
||||
if ((WS_EX_LAYERED & GetWindowLongPtr (hwnd, GWL_EXSTYLE)) != WS_EX_LAYERED)
|
||||
break;
|
||||
|
||||
/* Window was hidden, will be shown. Erase it, GDK will repaint soon,
|
||||
* but not soon enough, so it's possible to see old content before
|
||||
* the next redraw, unless we erase the window first.
|
||||
@@ -4514,17 +4394,17 @@ gdk_win32_surface_set_shadow_width (GdkSurface *window,
|
||||
"left %d, top %d, right %d, bottom %d\n",
|
||||
window, left, top, right, bottom));
|
||||
|
||||
impl->zero_margins = left == 0 && right == 0 && top == 0 && bottom == 0;
|
||||
impl->zero_shadow = left == 0 && right == 0 && top == 0 && bottom == 0;
|
||||
|
||||
if (impl->zero_margins)
|
||||
if (impl->zero_shadow)
|
||||
return;
|
||||
|
||||
impl->margins.left = left;
|
||||
impl->margins.right = right * impl->surface_scale;
|
||||
impl->margins.top = top;
|
||||
impl->margins.bottom = bottom * impl->surface_scale;
|
||||
impl->margins_x = left + right;
|
||||
impl->margins_y = top + bottom;
|
||||
impl->shadow.left = left;
|
||||
impl->shadow.right = right * impl->surface_scale;
|
||||
impl->shadow.top = top;
|
||||
impl->shadow.bottom = bottom * impl->surface_scale;
|
||||
impl->shadow_x = left + right;
|
||||
impl->shadow_y = top + bottom;
|
||||
}
|
||||
|
||||
|
||||
@@ -4597,6 +4477,118 @@ gdk_win32_surface_set_input_region (GdkSurface *window,
|
||||
*/
|
||||
}
|
||||
|
||||
static void
|
||||
compute_toplevel_size (GdkSurface *surface,
|
||||
gboolean update_geometry,
|
||||
int *width,
|
||||
int *height)
|
||||
{
|
||||
GdkDisplay *display = gdk_surface_get_display (surface);
|
||||
GdkMonitor *monitor;
|
||||
GdkToplevelSize size;
|
||||
int bounds_width, bounds_height;
|
||||
GdkWin32Surface *impl = GDK_WIN32_SURFACE (surface);
|
||||
|
||||
monitor = gdk_display_get_monitor_at_surface (display, surface);
|
||||
if (monitor)
|
||||
{
|
||||
GdkRectangle workarea;
|
||||
|
||||
gdk_win32_monitor_get_workarea (monitor, &workarea);
|
||||
bounds_width = workarea.width;
|
||||
bounds_height = workarea.height;
|
||||
}
|
||||
else
|
||||
{
|
||||
bounds_width = G_MAXINT;
|
||||
bounds_height = G_MAXINT;
|
||||
}
|
||||
|
||||
gdk_toplevel_size_init (&size, bounds_width, bounds_height);
|
||||
gdk_toplevel_notify_compute_size (GDK_TOPLEVEL (surface), &size);
|
||||
g_warn_if_fail (size.width > 0);
|
||||
g_warn_if_fail (size.height > 0);
|
||||
*width = size.width;
|
||||
*height = size.height;
|
||||
|
||||
if (size.shadow.is_valid)
|
||||
{
|
||||
gdk_win32_surface_set_shadow_width (surface,
|
||||
size.shadow.left,
|
||||
size.shadow.right,
|
||||
size.shadow.top,
|
||||
size.shadow.bottom);
|
||||
}
|
||||
|
||||
if (update_geometry)
|
||||
{
|
||||
GdkGeometry geometry;
|
||||
GdkSurfaceHints mask;
|
||||
GdkToplevelLayout *layout = impl->toplevel_layout;
|
||||
|
||||
if (gdk_toplevel_layout_get_resizable (layout))
|
||||
{
|
||||
geometry.min_width = size.min_width;
|
||||
geometry.min_height = size.min_height;
|
||||
mask = GDK_HINT_MIN_SIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
geometry.max_width = geometry.min_width = *width;
|
||||
geometry.max_height = geometry.min_height = *height;
|
||||
mask = GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE;
|
||||
}
|
||||
gdk_win32_surface_set_geometry_hints (surface, &geometry, mask);
|
||||
gdk_surface_constrain_size (&geometry, mask, *width, *height, width, height);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_win32_surface_request_layout (GdkSurface *surface)
|
||||
{
|
||||
GdkWin32Surface *impl = GDK_WIN32_SURFACE (surface);
|
||||
int scale = impl->surface_scale;
|
||||
RECT rect;
|
||||
|
||||
if (GDK_IS_TOPLEVEL (surface) && impl->resized)
|
||||
{
|
||||
surface->width = impl->next_layout.configured_width;
|
||||
surface->height = impl->next_layout.configured_height;
|
||||
}
|
||||
else
|
||||
{
|
||||
_gdk_win32_get_window_rect (surface, &rect);
|
||||
|
||||
impl->unscaled_width = rect.right - rect.left;
|
||||
impl->unscaled_height = rect.bottom - rect.top;
|
||||
|
||||
impl->next_layout.configured_width = (impl->unscaled_width + scale - 1) / scale;
|
||||
impl->next_layout.configured_height = (impl->unscaled_height + scale - 1) / scale;
|
||||
surface->x = rect.left / scale;
|
||||
surface->y = rect.top / scale;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_gdk_win32_surface_compute_size (GdkSurface *surface)
|
||||
{
|
||||
GdkWin32Surface *impl = GDK_WIN32_SURFACE (surface);
|
||||
int width, height;
|
||||
|
||||
if (GDK_IS_TOPLEVEL (surface))
|
||||
compute_toplevel_size (surface, TRUE, &width, &height);
|
||||
|
||||
if (!impl->resized)
|
||||
{
|
||||
surface->width = impl->next_layout.configured_width;
|
||||
surface->height = impl->next_layout.configured_height;
|
||||
|
||||
_gdk_surface_update_size (surface);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_win32_surface_class_init (GdkWin32SurfaceClass *klass)
|
||||
{
|
||||
@@ -4623,6 +4615,8 @@ gdk_win32_surface_class_init (GdkWin32SurfaceClass *klass)
|
||||
impl_class->create_gl_context = _gdk_win32_surface_create_gl_context;
|
||||
impl_class->get_scale_factor = _gdk_win32_surface_get_scale_factor;
|
||||
impl_class->get_unscaled_size = _gdk_win32_surface_get_unscaled_size;
|
||||
impl_class->request_layout = _gdk_win32_surface_request_layout;
|
||||
impl_class->compute_size = _gdk_win32_surface_compute_size;
|
||||
}
|
||||
|
||||
HGDIOBJ
|
||||
@@ -4912,75 +4906,18 @@ gdk_win32_toplevel_class_init (GdkWin32ToplevelClass *class)
|
||||
}
|
||||
|
||||
static void
|
||||
show_surface (GdkSurface *surface)
|
||||
{
|
||||
gboolean was_mapped;
|
||||
|
||||
if (surface->destroyed)
|
||||
return;
|
||||
|
||||
was_mapped = GDK_SURFACE_IS_MAPPED (surface);
|
||||
|
||||
if (!was_mapped)
|
||||
gdk_surface_set_is_mapped (surface, TRUE);
|
||||
|
||||
gdk_win32_surface_show (surface, FALSE);
|
||||
|
||||
if (!was_mapped)
|
||||
gdk_surface_invalidate_rect (surface, NULL);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_win32_toplevel_present (GdkToplevel *toplevel,
|
||||
GdkToplevelLayout *layout)
|
||||
{
|
||||
GdkSurface *surface = GDK_SURFACE (toplevel);
|
||||
GdkDisplay *display = gdk_surface_get_display (surface);
|
||||
GdkMonitor *monitor;
|
||||
GdkToplevelSize size;
|
||||
int bounds_width, bounds_height;
|
||||
GdkWin32Surface *impl = GDK_WIN32_SURFACE (surface);
|
||||
int width, height;
|
||||
GdkGeometry geometry;
|
||||
GdkSurfaceHints mask;
|
||||
gboolean maximize;
|
||||
gboolean fullscreen;
|
||||
|
||||
monitor = gdk_display_get_monitor_at_surface (display, surface);
|
||||
if (monitor)
|
||||
{
|
||||
GdkRectangle workarea;
|
||||
|
||||
gdk_win32_monitor_get_workarea (monitor, &workarea);
|
||||
bounds_width = workarea.width;
|
||||
bounds_height = workarea.height;
|
||||
}
|
||||
else
|
||||
{
|
||||
bounds_width = G_MAXINT;
|
||||
bounds_height = G_MAXINT;
|
||||
}
|
||||
|
||||
gdk_toplevel_size_init (&size, bounds_width, bounds_height);
|
||||
gdk_toplevel_notify_compute_size (toplevel, &size);
|
||||
g_warn_if_fail (size.width > 0);
|
||||
g_warn_if_fail (size.height > 0);
|
||||
width = size.width;
|
||||
height = size.height;
|
||||
|
||||
if (gdk_toplevel_layout_get_resizable (layout))
|
||||
{
|
||||
geometry.min_width = size.min_width;
|
||||
geometry.min_height = size.min_height;
|
||||
mask = GDK_HINT_MIN_SIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
geometry.max_width = geometry.min_width = width;
|
||||
geometry.max_height = geometry.min_height = height;
|
||||
mask = GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE;
|
||||
}
|
||||
gdk_win32_surface_set_geometry_hints (surface, &geometry, mask);
|
||||
gdk_surface_constrain_size (&geometry, mask, width, height, &width, &height);
|
||||
g_clear_pointer (&impl->toplevel_layout, gdk_toplevel_layout_unref);
|
||||
impl->toplevel_layout = gdk_toplevel_layout_copy (layout);
|
||||
compute_toplevel_size (surface, FALSE, &width, &height);
|
||||
gdk_win32_surface_resize (surface, width, height);
|
||||
|
||||
if (gdk_toplevel_layout_get_maximized (layout, &maximize))
|
||||
@@ -4999,18 +4936,8 @@ gdk_win32_toplevel_present (GdkToplevel *toplevel,
|
||||
gdk_win32_surface_unfullscreen (surface);
|
||||
}
|
||||
|
||||
show_surface (surface);
|
||||
|
||||
if (size.shadow.is_valid)
|
||||
{
|
||||
gdk_win32_surface_set_shadow_width (surface,
|
||||
size.shadow.left,
|
||||
size.shadow.right,
|
||||
size.shadow.top,
|
||||
size.shadow.bottom);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
gdk_win32_surface_show (surface, FALSE);
|
||||
maybe_notify_mapped (surface);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -5093,8 +5020,9 @@ gdk_win32_drag_surface_present (GdkDragSurface *drag_surface,
|
||||
{
|
||||
GdkSurface *surface = GDK_SURFACE (drag_surface);
|
||||
|
||||
gdk_win32_surface_resize (surface, width, height);
|
||||
show_surface (surface);
|
||||
gdk_win32_surface_resize (surface, width, height);
|
||||
gdk_win32_surface_show (surface, FALSE);
|
||||
maybe_notify_mapped (surface);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -5185,7 +5113,6 @@ gdk_win32_surface_apply_queued_move_resize (GdkSurface *surface,
|
||||
RECT
|
||||
gdk_win32_surface_handle_queued_move_resize (GdkDrawContext *draw_context)
|
||||
{
|
||||
GdkWin32CairoContext *cairo_ctx = NULL;
|
||||
GdkSurface *surface;
|
||||
GdkWin32Surface *impl;
|
||||
int scale;
|
||||
@@ -5195,23 +5122,16 @@ gdk_win32_surface_handle_queued_move_resize (GdkDrawContext *draw_context)
|
||||
impl = GDK_WIN32_SURFACE (surface);
|
||||
scale = gdk_surface_get_scale_factor (surface);
|
||||
|
||||
if (GDK_IS_WIN32_CAIRO_CONTEXT (draw_context))
|
||||
{
|
||||
cairo_ctx = GDK_WIN32_CAIRO_CONTEXT (draw_context);
|
||||
cairo_ctx->layered = impl->layered;
|
||||
}
|
||||
|
||||
gdk_win32_surface_get_queued_window_rect (surface, scale, &queued_window_rect);
|
||||
|
||||
/* Apply queued resizes for non-double-buffered and non-layered windows
|
||||
/* Apply queued resizes for non-double-buffered windows
|
||||
* before painting them (we paint on the window DC directly,
|
||||
* it must have the right size).
|
||||
* Due to some poorly-undetstood issue delayed
|
||||
* resizing of double-buffered windows can produce weird
|
||||
* artefacts, so these are also resized before we paint.
|
||||
*/
|
||||
if (impl->drag_move_resize_context.native_move_resize_pending &&
|
||||
(cairo_ctx == NULL || !cairo_ctx->layered))
|
||||
if (impl->drag_move_resize_context.native_move_resize_pending)
|
||||
{
|
||||
impl->drag_move_resize_context.native_move_resize_pending = FALSE;
|
||||
gdk_win32_surface_apply_queued_move_resize (surface, queued_window_rect);
|
||||
|
||||
@@ -265,25 +265,18 @@ struct _GdkWin32Surface
|
||||
int initial_y;
|
||||
|
||||
/* left/right/top/bottom width of the shadow/resize-grip around the window */
|
||||
RECT margins;
|
||||
RECT shadow;
|
||||
|
||||
/* left+right and top+bottom from @margins */
|
||||
int margins_x;
|
||||
int margins_y;
|
||||
/* left+right and top+bottom from @shadow */
|
||||
int shadow_x;
|
||||
int shadow_y;
|
||||
|
||||
/* Set to TRUE when GTK tells us that margins are 0 everywhere.
|
||||
* We don't actually set margins to 0, we just set this bit.
|
||||
/* Set to TRUE when GTK tells us that shadow are 0 everywhere.
|
||||
* We don't actually set shadow to 0, we just set this bit.
|
||||
*/
|
||||
guint zero_margins : 1;
|
||||
guint zero_shadow : 1;
|
||||
guint inhibit_configure : 1;
|
||||
|
||||
/* Set to TRUE if window is using true layered mode adjustments
|
||||
* via UpdateLayeredWindow().
|
||||
* Layered windows that get SetLayeredWindowAttributes() called
|
||||
* on them are not true layered windows.
|
||||
*/
|
||||
guint layered : 1;
|
||||
|
||||
/* If TRUE, the @temp_styles is set to the styles that were temporarily
|
||||
* added to this window.
|
||||
*/
|
||||
@@ -309,12 +302,6 @@ struct _GdkWin32Surface
|
||||
int dib_width;
|
||||
int dib_height;
|
||||
|
||||
/* If the client wants uniformly-transparent window,
|
||||
* we remember the opacity value here and apply it
|
||||
* during UpdateLayredWindow() call, for layered windows.
|
||||
*/
|
||||
double layered_opacity;
|
||||
|
||||
HDC hdc;
|
||||
int hdc_count;
|
||||
HBITMAP saved_dc_bitmap; /* Original bitmap for dc */
|
||||
@@ -340,9 +327,6 @@ struct _GdkWin32Surface
|
||||
/* Enable all decorations? */
|
||||
gboolean decorate_all;
|
||||
|
||||
/* No. of windows to force layered windows off */
|
||||
guint suppress_layered;
|
||||
|
||||
/* Temporary styles that this window got for the purpose of
|
||||
* handling WM_SYSMENU.
|
||||
* They are removed at the first opportunity (usually WM_INITMENU).
|
||||
@@ -354,6 +338,13 @@ struct _GdkWin32Surface
|
||||
int unscaled_width;
|
||||
int unscaled_height;
|
||||
|
||||
GdkToplevelLayout *toplevel_layout;
|
||||
struct {
|
||||
int configured_width;
|
||||
int configured_height;
|
||||
} next_layout;
|
||||
gboolean resized;
|
||||
|
||||
#ifdef GDK_WIN32_ENABLE_EGL
|
||||
EGLSurface egl_surface;
|
||||
EGLSurface egl_dummy_surface;
|
||||
@@ -375,11 +366,6 @@ int _gdk_win32_surface_get_scale_factor (GdkSurface *window);
|
||||
void _gdk_win32_get_window_client_area_rect (GdkSurface *window,
|
||||
int scale,
|
||||
RECT *rect);
|
||||
void _gdk_win32_update_layered_window_from_cache (GdkSurface *window,
|
||||
RECT *client_rect,
|
||||
gboolean do_move,
|
||||
gboolean do_resize,
|
||||
gboolean do_paint);
|
||||
|
||||
void gdk_win32_surface_move (GdkSurface *surface,
|
||||
int x,
|
||||
|
||||
@@ -63,12 +63,6 @@ gdk_win32_vulkan_context_create_surface (GdkVulkanContext *context,
|
||||
NULL,
|
||||
surface);
|
||||
|
||||
if (result == VK_SUCCESS)
|
||||
win32_surface->suppress_layered ++;
|
||||
|
||||
if (win32_surface->suppress_layered == 1)
|
||||
_gdk_win32_surface_update_style_bits (window);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -1097,15 +1097,16 @@ handle_property_change (GdkX11DeviceManagerXI2 *device_manager,
|
||||
if (ev->what != XIPropertyDeleted &&
|
||||
device_get_tool_serial_and_id (device, &serial_id, &tool_id))
|
||||
{
|
||||
GdkDeviceToolType tool_type;
|
||||
|
||||
seat = gdk_device_get_seat (device);
|
||||
tool = gdk_seat_get_tool (seat, serial_id, tool_id);
|
||||
tool_type = device_get_tool_type (device);
|
||||
|
||||
if (!tool && serial_id > 0)
|
||||
if (tool_type != GDK_DEVICE_TOOL_TYPE_UNKNOWN)
|
||||
{
|
||||
GdkDeviceToolType tool_type;
|
||||
tool = gdk_seat_get_tool (seat, serial_id, tool_id, tool_type);
|
||||
|
||||
tool_type = device_get_tool_type (device);
|
||||
if (tool_type != GDK_DEVICE_TOOL_TYPE_UNKNOWN)
|
||||
if (!tool && serial_id > 0)
|
||||
{
|
||||
tool = gdk_device_tool_new (serial_id, tool_id, tool_type, 0);
|
||||
gdk_seat_default_add_tool (GDK_SEAT_DEFAULT (seat), tool);
|
||||
@@ -1716,19 +1717,49 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
|
||||
scroll_valuators_changed (GDK_X11_DEVICE_XI2 (source_device),
|
||||
&xev->valuators, &delta_x, &delta_y))
|
||||
{
|
||||
GdkModifierType state;
|
||||
|
||||
GDK_DISPLAY_NOTE (display, EVENTS,
|
||||
g_message ("smooth scroll: \n\tdevice: %u\n\tsource device: %u\n\twindow %ld\n\tdeltas: %f %f",
|
||||
xev->deviceid, xev->sourceid,
|
||||
xev->event, delta_x, delta_y));
|
||||
|
||||
event = gdk_scroll_event_new (surface,
|
||||
device,
|
||||
NULL,
|
||||
xev->time,
|
||||
_gdk_x11_device_xi2_translate_state (&xev->mods, &xev->buttons, &xev->group),
|
||||
delta_x,
|
||||
delta_y,
|
||||
delta_x == 0.0 && delta_y == 0.0);
|
||||
state = _gdk_x11_device_xi2_translate_state (&xev->mods, &xev->buttons, &xev->group);
|
||||
|
||||
if (gdk_device_get_source (source_device) != GDK_SOURCE_TOUCHPAD &&
|
||||
((delta_x == 0.0 && ABS (delta_y) == 1.0) ||
|
||||
(ABS (delta_x) == 1.0 && delta_y == 0.0)))
|
||||
{
|
||||
GdkScrollDirection direction;
|
||||
|
||||
if (delta_x > 0)
|
||||
direction = GDK_SCROLL_RIGHT;
|
||||
else if (delta_x < 0)
|
||||
direction = GDK_SCROLL_LEFT;
|
||||
else if (delta_y > 0)
|
||||
direction = GDK_SCROLL_DOWN;
|
||||
else
|
||||
direction = GDK_SCROLL_UP;
|
||||
|
||||
event = gdk_scroll_event_new_discrete (surface,
|
||||
device,
|
||||
NULL,
|
||||
xev->time,
|
||||
state,
|
||||
direction,
|
||||
FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
event = gdk_scroll_event_new (surface,
|
||||
device,
|
||||
NULL,
|
||||
xev->time,
|
||||
state,
|
||||
delta_x,
|
||||
delta_y,
|
||||
delta_x == 0.0 && delta_y == 0.0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -291,7 +291,7 @@ compute_toplevel_size (GdkSurface *surface,
|
||||
GdkGeometry geometry;
|
||||
GdkSurfaceHints mask;
|
||||
|
||||
if (gdk_toplevel_layout_get_resizable (impl->toplevel_layout))
|
||||
if (!impl->toplevel_layout || gdk_toplevel_layout_get_resizable (impl->toplevel_layout))
|
||||
{
|
||||
geometry.min_width = size.min_width;
|
||||
geometry.min_height = size.min_height;
|
||||
@@ -2013,6 +2013,8 @@ _gdk_x11_surface_set_surface_scale (GdkSurface *surface,
|
||||
surface->height * impl->surface_scale);
|
||||
|
||||
gdk_surface_invalidate_rect (surface, NULL);
|
||||
|
||||
g_object_notify (G_OBJECT (surface), "scale-factor");
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -149,10 +149,10 @@ render_glyph (GlyphCacheKey *key,
|
||||
glyph_info.glyph = key->data.glyph;
|
||||
glyph_info.geometry.width = value->draw_width * 1024;
|
||||
if (glyph_info.glyph & PANGO_GLYPH_UNKNOWN_FLAG)
|
||||
glyph_info.geometry.x_offset = 0;
|
||||
glyph_info.geometry.x_offset = 250 * key->data.xshift;
|
||||
else
|
||||
glyph_info.geometry.x_offset = - value->draw_x * 1024;
|
||||
glyph_info.geometry.y_offset = - value->draw_y * 1024;
|
||||
glyph_info.geometry.x_offset = 250 * key->data.xshift - value->draw_x * 1024;
|
||||
glyph_info.geometry.y_offset = 250 * key->data.yshift - value->draw_y * 1024;
|
||||
|
||||
glyph_string.num_glyphs = 1;
|
||||
glyph_string.glyphs = &glyph_info;
|
||||
|
||||
@@ -1452,6 +1452,7 @@ render_linear_gradient_node (GskGLRenderer *self,
|
||||
ops_set_linear_gradient (builder,
|
||||
n_color_stops,
|
||||
stops,
|
||||
gsk_render_node_get_node_type (node) == GSK_REPEATING_LINEAR_GRADIENT_NODE,
|
||||
builder->dx + start->x,
|
||||
builder->dy + start->y,
|
||||
builder->dx + end->x,
|
||||
@@ -1485,6 +1486,7 @@ render_radial_gradient_node (GskGLRenderer *self,
|
||||
ops_set_radial_gradient (builder,
|
||||
n_color_stops,
|
||||
stops,
|
||||
gsk_render_node_get_node_type (node) == GSK_REPEATING_RADIAL_GRADIENT_NODE,
|
||||
builder->dx + center->x,
|
||||
builder->dy + center->y,
|
||||
start, end,
|
||||
@@ -1510,7 +1512,7 @@ render_conic_gradient_node (GskGLRenderer *self,
|
||||
{
|
||||
const GskColorStop *stops = gsk_conic_gradient_node_get_color_stops (node, NULL);
|
||||
const graphene_point_t *center = gsk_conic_gradient_node_get_center (node);
|
||||
const float rotation = gsk_conic_gradient_node_get_rotation (node);
|
||||
const float angle = gsk_conic_gradient_node_get_angle (node);
|
||||
|
||||
ops_set_program (builder, &self->programs->conic_gradient_program);
|
||||
ops_set_conic_gradient (builder,
|
||||
@@ -1518,7 +1520,7 @@ render_conic_gradient_node (GskGLRenderer *self,
|
||||
stops,
|
||||
builder->dx + center->x,
|
||||
builder->dy + center->y,
|
||||
rotation);
|
||||
angle);
|
||||
|
||||
load_vertex_data (ops_draw (builder, NULL), &node->bounds, builder);
|
||||
}
|
||||
@@ -1554,7 +1556,7 @@ rounded_inner_rect_contains_rect (const GskRoundedRect *rounded,
|
||||
MAX (rounded->corner[GSK_CORNER_BOTTOM_LEFT].height,
|
||||
rounded->corner[GSK_CORNER_BOTTOM_RIGHT].height);
|
||||
|
||||
return graphene_rect_contains_rect (&inner, rect);
|
||||
return _graphene_rect_contains_rect (&inner, rect);
|
||||
}
|
||||
|
||||
/* Current clip is NOT rounded but new one is definitely! */
|
||||
@@ -1644,8 +1646,8 @@ render_clipped_child (GskGLRenderer *self,
|
||||
/* well fuck */
|
||||
const float scale_x = builder->scale_x;
|
||||
const float scale_y = builder->scale_y;
|
||||
const GskRoundedRect scaled_clip = GSK_ROUNDED_RECT_INIT (clip->origin.x * scale_x,
|
||||
clip->origin.y * scale_y,
|
||||
const GskRoundedRect scaled_clip = GSK_ROUNDED_RECT_INIT ((builder->dx + clip->origin.x) * scale_x,
|
||||
(builder->dy + clip->origin.y) * scale_y,
|
||||
clip->size.width * scale_x,
|
||||
clip->size.height * scale_y);
|
||||
gboolean is_offscreen;
|
||||
@@ -1746,7 +1748,6 @@ render_rounded_clip_node (GskGLRenderer *self,
|
||||
}
|
||||
else
|
||||
{
|
||||
GskRoundedRect scaled_clip;
|
||||
gboolean is_offscreen;
|
||||
TextureRegion region;
|
||||
/* NOTE: We are *not* transforming the clip by the current modelview here.
|
||||
@@ -1755,19 +1756,7 @@ render_rounded_clip_node (GskGLRenderer *self,
|
||||
*
|
||||
* We do, however, apply the scale factor to the child clip of course.
|
||||
*/
|
||||
scaled_clip.bounds.origin.x = clip->bounds.origin.x * scale_x;
|
||||
scaled_clip.bounds.origin.y = clip->bounds.origin.y * scale_y;
|
||||
scaled_clip.bounds.size.width = clip->bounds.size.width * scale_x;
|
||||
scaled_clip.bounds.size.height = clip->bounds.size.height * scale_y;
|
||||
|
||||
/* Increase corner radius size by scale factor */
|
||||
for (i = 0; i < 4; i ++)
|
||||
{
|
||||
scaled_clip.corner[i].width = clip->corner[i].width * scale_x;
|
||||
scaled_clip.corner[i].height = clip->corner[i].height * scale_y;
|
||||
}
|
||||
|
||||
ops_push_clip (builder, &scaled_clip);
|
||||
ops_push_clip (builder, &transformed_clip);
|
||||
if (!add_offscreen_ops (self, builder, &node->bounds,
|
||||
child,
|
||||
®ion, &is_offscreen,
|
||||
@@ -1779,7 +1768,8 @@ render_rounded_clip_node (GskGLRenderer *self,
|
||||
ops_set_program (builder, &self->programs->blit_program);
|
||||
ops_set_texture (builder, region.texture_id);
|
||||
|
||||
load_offscreen_vertex_data (ops_draw (builder, NULL), node, builder);
|
||||
load_vertex_data_with_region (ops_draw (builder, NULL), &node->bounds, builder,
|
||||
®ion, is_offscreen);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1824,6 +1814,7 @@ blur_texture (GskGLRenderer *self,
|
||||
float blur_radius_x,
|
||||
float blur_radius_y)
|
||||
{
|
||||
const GskRoundedRect new_clip = GSK_ROUNDED_RECT_INIT (0, 0, texture_to_blur_width, texture_to_blur_height);
|
||||
int pass1_texture_id, pass1_render_target;
|
||||
int pass2_texture_id, pass2_render_target;
|
||||
int prev_render_target;
|
||||
@@ -1850,17 +1841,16 @@ blur_texture (GskGLRenderer *self,
|
||||
GL_NEAREST, GL_NEAREST,
|
||||
&pass2_texture_id, &pass2_render_target);
|
||||
|
||||
init_projection_matrix (&item_proj,
|
||||
&GRAPHENE_RECT_INIT (0, 0, texture_to_blur_width, texture_to_blur_height));
|
||||
init_projection_matrix (&item_proj, &new_clip.bounds);
|
||||
|
||||
ops_set_program (builder, &self->programs->blur_program);
|
||||
prev_projection = ops_set_projection (builder, &item_proj);
|
||||
ops_set_modelview (builder, NULL);
|
||||
prev_viewport = ops_set_viewport (builder, &GRAPHENE_RECT_INIT (0, 0, texture_to_blur_width, texture_to_blur_height));
|
||||
ops_push_clip (builder, &GSK_ROUNDED_RECT_INIT (0, 0, texture_to_blur_width, texture_to_blur_height));
|
||||
prev_viewport = ops_set_viewport (builder, &new_clip.bounds);
|
||||
ops_push_clip (builder, &new_clip);
|
||||
|
||||
prev_render_target = ops_set_render_target (builder, pass1_render_target);
|
||||
ops_begin (builder, OP_CLEAR);
|
||||
ops_set_program (builder, &self->programs->blur_program);
|
||||
|
||||
op = ops_begin (builder, OP_CHANGE_BLUR);
|
||||
op->size.width = texture_to_blur_width;
|
||||
@@ -1871,7 +1861,7 @@ blur_texture (GskGLRenderer *self,
|
||||
ops_set_texture (builder, region->texture_id);
|
||||
|
||||
load_vertex_data_with_region (ops_draw (builder, NULL),
|
||||
&GRAPHENE_RECT_INIT (0, 0, texture_to_blur_width, texture_to_blur_height),
|
||||
&new_clip.bounds,
|
||||
builder, region,
|
||||
FALSE);
|
||||
#if 0
|
||||
@@ -1893,7 +1883,7 @@ blur_texture (GskGLRenderer *self,
|
||||
ops_set_render_target (builder, pass2_render_target);
|
||||
ops_begin (builder, OP_CLEAR);
|
||||
load_vertex_data_with_region (ops_draw (builder, NULL), /* render pass 2 */
|
||||
&GRAPHENE_RECT_INIT (0, 0, texture_to_blur_width, texture_to_blur_height),
|
||||
&new_clip.bounds,
|
||||
builder, region,
|
||||
FALSE);
|
||||
|
||||
@@ -2940,10 +2930,15 @@ static inline void
|
||||
apply_color_matrix_op (const Program *program,
|
||||
const OpColorMatrix *op)
|
||||
{
|
||||
float mat[16];
|
||||
OP_PRINT (" -> Color Matrix");
|
||||
graphene_matrix_to_float (op->matrix, mat);
|
||||
glUniformMatrix4fv (program->color_matrix.color_matrix_location, 1, GL_FALSE, mat);
|
||||
OP_PRINT (" -> Color matrix. Send matrix: %d. Send offset: %d.",
|
||||
op->matrix.send, op->offset.send);
|
||||
|
||||
if (op->matrix.send)
|
||||
{
|
||||
float mat[16];
|
||||
graphene_matrix_to_float (op->matrix.value, mat);
|
||||
glUniformMatrix4fv (program->color_matrix.color_matrix_location, 1, GL_FALSE, mat);
|
||||
}
|
||||
|
||||
if (op->offset.send)
|
||||
{
|
||||
@@ -3048,14 +3043,19 @@ apply_linear_gradient_op (const Program *program,
|
||||
op->n_color_stops.value * 5,
|
||||
(float *)op->color_stops.value);
|
||||
|
||||
glUniform2f (program->linear_gradient.start_point_location, op->start_point[0], op->start_point[1]);
|
||||
glUniform2f (program->linear_gradient.end_point_location, op->end_point[0], op->end_point[1]);
|
||||
glUniform4f (program->linear_gradient.points_location,
|
||||
op->start_point[0], op->start_point[1],
|
||||
op->end_point[0] - op->start_point[0], op->end_point[1] - op->start_point[1]);
|
||||
glUniform1i (program->linear_gradient.repeat_location, op->repeat);
|
||||
}
|
||||
|
||||
static inline void
|
||||
apply_radial_gradient_op (const Program *program,
|
||||
const OpRadialGradient *op)
|
||||
{
|
||||
float scale;
|
||||
float bias;
|
||||
|
||||
OP_PRINT (" -> Radial gradient");
|
||||
if (op->n_color_stops.send)
|
||||
glUniform1i (program->radial_gradient.num_color_stops_location, op->n_color_stops.value);
|
||||
@@ -3065,16 +3065,23 @@ apply_radial_gradient_op (const Program *program,
|
||||
op->n_color_stops.value * 5,
|
||||
(float *)op->color_stops.value);
|
||||
|
||||
glUniform1f (program->radial_gradient.start_location, op->start);
|
||||
glUniform1f (program->radial_gradient.end_location, op->end);
|
||||
glUniform2f (program->radial_gradient.radius_location, op->radius[0], op->radius[1]);
|
||||
glUniform2f (program->radial_gradient.center_location, op->center[0], op->center[1]);
|
||||
scale = 1.0f / (op->end - op->start);
|
||||
bias = -op->start * scale;
|
||||
|
||||
glUniform1i (program->radial_gradient.repeat_location, op->repeat);
|
||||
glUniform2f (program->radial_gradient.range_location, scale, bias);
|
||||
glUniform4f (program->radial_gradient.geometry_location,
|
||||
op->center[0], op->center[1],
|
||||
1.0f / op->radius[0], 1.0f / op->radius[1]);
|
||||
}
|
||||
|
||||
static inline void
|
||||
apply_conic_gradient_op (const Program *program,
|
||||
const OpConicGradient *op)
|
||||
{
|
||||
float bias;
|
||||
float scale;
|
||||
|
||||
OP_PRINT (" -> Conic gradient");
|
||||
if (op->n_color_stops.send)
|
||||
glUniform1i (program->conic_gradient.num_color_stops_location, op->n_color_stops.value);
|
||||
@@ -3084,8 +3091,9 @@ apply_conic_gradient_op (const Program *program,
|
||||
op->n_color_stops.value * 5,
|
||||
(float *)op->color_stops.value);
|
||||
|
||||
glUniform1f (program->conic_gradient.rotation_location, op->rotation);
|
||||
glUniform2f (program->conic_gradient.center_location, op->center[0], op->center[1]);
|
||||
scale = 0.5f * M_1_PI;
|
||||
bias = op->angle * scale + 2.0f;
|
||||
glUniform4f (program->conic_gradient.geometry_location, op->center[0], op->center[1], scale, bias);
|
||||
}
|
||||
|
||||
static inline void
|
||||
@@ -3199,6 +3207,7 @@ static inline void
|
||||
apply_repeat_op (const Program *program,
|
||||
const OpRepeat *op)
|
||||
{
|
||||
OP_PRINT (" -> Repeat");
|
||||
glUniform4fv (program->repeat.child_bounds_location, 1, op->child_bounds);
|
||||
glUniform4fv (program->repeat.texture_rect_location, 1, op->texture_rect);
|
||||
}
|
||||
@@ -3374,22 +3383,20 @@ gsk_gl_renderer_create_programs (GskGLRenderer *self,
|
||||
/* linear gradient */
|
||||
INIT_PROGRAM_UNIFORM_LOCATION (linear_gradient, color_stops);
|
||||
INIT_PROGRAM_UNIFORM_LOCATION (linear_gradient, num_color_stops);
|
||||
INIT_PROGRAM_UNIFORM_LOCATION (linear_gradient, start_point);
|
||||
INIT_PROGRAM_UNIFORM_LOCATION (linear_gradient, end_point);
|
||||
INIT_PROGRAM_UNIFORM_LOCATION (linear_gradient, repeat);
|
||||
INIT_PROGRAM_UNIFORM_LOCATION (linear_gradient, points);
|
||||
|
||||
/* radial gradient */
|
||||
INIT_PROGRAM_UNIFORM_LOCATION (radial_gradient, color_stops);
|
||||
INIT_PROGRAM_UNIFORM_LOCATION (radial_gradient, num_color_stops);
|
||||
INIT_PROGRAM_UNIFORM_LOCATION (radial_gradient, center);
|
||||
INIT_PROGRAM_UNIFORM_LOCATION (radial_gradient, start);
|
||||
INIT_PROGRAM_UNIFORM_LOCATION (radial_gradient, end);
|
||||
INIT_PROGRAM_UNIFORM_LOCATION (radial_gradient, radius);
|
||||
INIT_PROGRAM_UNIFORM_LOCATION (radial_gradient, repeat);
|
||||
INIT_PROGRAM_UNIFORM_LOCATION (radial_gradient, geometry);
|
||||
INIT_PROGRAM_UNIFORM_LOCATION (radial_gradient, range);
|
||||
|
||||
/* conic gradient */
|
||||
INIT_PROGRAM_UNIFORM_LOCATION (conic_gradient, color_stops);
|
||||
INIT_PROGRAM_UNIFORM_LOCATION (conic_gradient, num_color_stops);
|
||||
INIT_PROGRAM_UNIFORM_LOCATION (conic_gradient, center);
|
||||
INIT_PROGRAM_UNIFORM_LOCATION (conic_gradient, rotation);
|
||||
INIT_PROGRAM_UNIFORM_LOCATION (conic_gradient, geometry);
|
||||
|
||||
/* blur */
|
||||
INIT_PROGRAM_UNIFORM_LOCATION (blur, blur_radius);
|
||||
@@ -3735,10 +3742,12 @@ gsk_gl_renderer_add_render_ops (GskGLRenderer *self,
|
||||
break;
|
||||
|
||||
case GSK_LINEAR_GRADIENT_NODE:
|
||||
case GSK_REPEATING_LINEAR_GRADIENT_NODE:
|
||||
render_linear_gradient_node (self, node, builder);
|
||||
break;
|
||||
|
||||
case GSK_RADIAL_GRADIENT_NODE:
|
||||
case GSK_REPEATING_RADIAL_GRADIENT_NODE:
|
||||
render_radial_gradient_node (self, node, builder);
|
||||
break;
|
||||
|
||||
@@ -3805,8 +3814,6 @@ gsk_gl_renderer_add_render_ops (GskGLRenderer *self,
|
||||
render_gl_shader_node (self, node, builder);
|
||||
break;
|
||||
|
||||
case GSK_REPEATING_LINEAR_GRADIENT_NODE:
|
||||
case GSK_REPEATING_RADIAL_GRADIENT_NODE:
|
||||
case GSK_CAIRO_NODE:
|
||||
default:
|
||||
{
|
||||
@@ -3824,9 +3831,9 @@ add_offscreen_ops (GskGLRenderer *self,
|
||||
gboolean *is_offscreen,
|
||||
guint flags)
|
||||
{
|
||||
float width, height;
|
||||
const float dx = builder->dx;
|
||||
const float dy = builder->dy;
|
||||
float scaled_width, scaled_height;
|
||||
float scale_x;
|
||||
float scale_y;
|
||||
int render_target;
|
||||
@@ -3839,6 +3846,7 @@ add_offscreen_ops (GskGLRenderer *self,
|
||||
int filter;
|
||||
GskTextureKey key;
|
||||
int cached_id;
|
||||
graphene_rect_t viewport;
|
||||
|
||||
if (node_is_invisible (child_node))
|
||||
{
|
||||
@@ -3881,8 +3889,6 @@ add_offscreen_ops (GskGLRenderer *self,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
width = bounds->size.width;
|
||||
height = bounds->size.height;
|
||||
scale_x = builder->scale_x;
|
||||
scale_y = builder->scale_y;
|
||||
|
||||
@@ -3893,23 +3899,23 @@ add_offscreen_ops (GskGLRenderer *self,
|
||||
{
|
||||
const int max_texture_size = gsk_gl_driver_get_max_texture_size (self->gl_driver);
|
||||
|
||||
width = ceilf (width * scale_x);
|
||||
if (width > max_texture_size)
|
||||
scaled_width = ceilf (bounds->size.width * scale_x);
|
||||
if (scaled_width > max_texture_size)
|
||||
{
|
||||
scale_x *= (float)max_texture_size / width;
|
||||
width = max_texture_size;
|
||||
scale_x *= (float)max_texture_size / scaled_width;
|
||||
scaled_width = max_texture_size;
|
||||
}
|
||||
|
||||
height = ceilf (height * scale_y);
|
||||
if (height > max_texture_size)
|
||||
scaled_height = ceilf (bounds->size.height * scale_y);
|
||||
if (scaled_height > max_texture_size)
|
||||
{
|
||||
scale_y *= (float)max_texture_size / height;
|
||||
height = max_texture_size;
|
||||
scale_y *= (float)max_texture_size / scaled_height;
|
||||
scaled_height = max_texture_size;
|
||||
}
|
||||
}
|
||||
|
||||
gsk_gl_driver_create_render_target (self->gl_driver,
|
||||
width, height,
|
||||
scaled_width, scaled_height,
|
||||
filter, filter,
|
||||
&texture_id, &render_target);
|
||||
if (gdk_gl_context_has_debug (self->gl_context))
|
||||
@@ -3924,30 +3930,24 @@ add_offscreen_ops (GskGLRenderer *self,
|
||||
render_target);
|
||||
}
|
||||
|
||||
init_projection_matrix (&item_proj,
|
||||
&GRAPHENE_RECT_INIT (
|
||||
bounds->origin.x * scale_x,
|
||||
bounds->origin.y * scale_y,
|
||||
width, height
|
||||
));
|
||||
ops_transform_bounds_modelview (builder, bounds, &viewport);
|
||||
/* Code above will scale the size with the scale we use in the render ops,
|
||||
* but for the viewport size, we need our own size limited by the texture size */
|
||||
viewport.size.width = scaled_width;
|
||||
viewport.size.height = scaled_height;
|
||||
|
||||
init_projection_matrix (&item_proj, &viewport);
|
||||
prev_render_target = ops_set_render_target (builder, render_target);
|
||||
/* Clear since we use this rendertarget for the first time */
|
||||
ops_begin (builder, OP_CLEAR);
|
||||
prev_projection = ops_set_projection (builder, &item_proj);
|
||||
ops_set_modelview (builder, gsk_transform_scale (NULL, scale_x, scale_y));
|
||||
prev_viewport = ops_set_viewport (builder,
|
||||
&GRAPHENE_RECT_INIT (bounds->origin.x * scale_x,
|
||||
bounds->origin.y * scale_y,
|
||||
width, height));
|
||||
prev_viewport = ops_set_viewport (builder, &viewport);
|
||||
if (flags & RESET_CLIP)
|
||||
ops_push_clip (builder,
|
||||
&GSK_ROUNDED_RECT_INIT (bounds->origin.x * scale_x,
|
||||
bounds->origin.y * scale_y,
|
||||
width, height));
|
||||
ops_push_clip (builder, &GSK_ROUNDED_RECT_INIT_FROM_RECT (viewport));
|
||||
|
||||
builder->dx = 0;
|
||||
builder->dy = 0;
|
||||
builder->dx = dx;
|
||||
builder->dy = dy;
|
||||
|
||||
prev_opacity = ops_set_opacity (builder, 1.0);
|
||||
|
||||
@@ -3962,7 +3962,7 @@ add_offscreen_ops (GskGLRenderer *self,
|
||||
g_type_name_from_instance ((GTypeInstance *) child_node),
|
||||
child_node,
|
||||
k ++),
|
||||
width, height);
|
||||
scaled_width, scaled_height);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -14,27 +14,28 @@ rect_equal (const graphene_rect_t *a,
|
||||
return memcmp (a, b, sizeof (graphene_rect_t)) == 0;
|
||||
}
|
||||
|
||||
static inline gboolean G_GNUC_PURE
|
||||
static inline bool G_GNUC_PURE
|
||||
rounded_rect_equal (const GskRoundedRect *r1,
|
||||
const GskRoundedRect *r2)
|
||||
{
|
||||
int i;
|
||||
if (r1 == r2)
|
||||
return true;
|
||||
|
||||
if (!r1)
|
||||
return FALSE;
|
||||
return false;
|
||||
|
||||
if (r1->bounds.origin.x != r2->bounds.origin.x ||
|
||||
r1->bounds.origin.y != r2->bounds.origin.y ||
|
||||
r1->bounds.size.width != r2->bounds.size.width ||
|
||||
r1->bounds.size.height != r2->bounds.size.height)
|
||||
return FALSE;
|
||||
return false;
|
||||
|
||||
for (i = 0; i < 4; i ++)
|
||||
for (int i = 0; i < 4; i ++)
|
||||
if (r1->corner[i].width != r2->corner[i].width ||
|
||||
r1->corner[i].height != r2->corner[i].height)
|
||||
return FALSE;
|
||||
return false;
|
||||
|
||||
return TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline gboolean G_GNUC_PURE
|
||||
@@ -208,10 +209,9 @@ ops_free (RenderOpBuilder *builder)
|
||||
|
||||
void
|
||||
ops_set_program (RenderOpBuilder *builder,
|
||||
Program *program)
|
||||
Program *program)
|
||||
{
|
||||
OpProgram *op;
|
||||
ProgramState *program_state = NULL;
|
||||
|
||||
if (builder->current_program == program)
|
||||
return;
|
||||
@@ -220,86 +220,6 @@ ops_set_program (RenderOpBuilder *builder,
|
||||
op->program = program;
|
||||
|
||||
builder->current_program = program;
|
||||
|
||||
program_state = &program->state;
|
||||
|
||||
if (memcmp (&builder->current_projection, &program_state->projection, sizeof (graphene_matrix_t)) != 0)
|
||||
{
|
||||
OpMatrix *opm;
|
||||
|
||||
opm = ops_begin (builder, OP_CHANGE_PROJECTION);
|
||||
opm->matrix = builder->current_projection;
|
||||
program_state->projection = builder->current_projection;
|
||||
}
|
||||
|
||||
if (program_state->modelview == NULL ||
|
||||
!gsk_transform_equal (builder->current_modelview, program_state->modelview))
|
||||
{
|
||||
OpMatrix *opm;
|
||||
|
||||
opm = ops_begin (builder, OP_CHANGE_MODELVIEW);
|
||||
gsk_transform_to_matrix (builder->current_modelview, &opm->matrix);
|
||||
gsk_transform_unref (program_state->modelview);
|
||||
program_state->modelview = gsk_transform_ref (builder->current_modelview);
|
||||
}
|
||||
|
||||
if (!rect_equal (&builder->current_viewport, &program_state->viewport))
|
||||
{
|
||||
OpViewport *opv;
|
||||
|
||||
opv = ops_begin (builder, OP_CHANGE_VIEWPORT);
|
||||
opv->viewport = builder->current_viewport;
|
||||
program_state->viewport = builder->current_viewport;
|
||||
}
|
||||
|
||||
if (!rounded_rect_equal (builder->current_clip, &program_state->clip))
|
||||
{
|
||||
OpClip *opc;
|
||||
|
||||
opc = ops_begin (builder, OP_CHANGE_CLIP);
|
||||
opc->clip = *builder->current_clip;
|
||||
opc->send_corners = !rounded_rect_corners_equal (builder->current_clip, &program_state->clip);
|
||||
program_state->clip = *builder->current_clip;
|
||||
}
|
||||
|
||||
if (program_state->opacity != builder->current_opacity)
|
||||
{
|
||||
OpOpacity *opo;
|
||||
|
||||
opo = ops_begin (builder, OP_CHANGE_OPACITY);
|
||||
opo->opacity = builder->current_opacity;
|
||||
program_state->opacity = builder->current_opacity;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ops_set_clip (RenderOpBuilder *builder,
|
||||
const GskRoundedRect *clip)
|
||||
{
|
||||
ProgramState *current_program_state = get_current_program_state (builder);
|
||||
OpClip *op;
|
||||
|
||||
if (current_program_state &&
|
||||
rounded_rect_equal (¤t_program_state->clip, clip))
|
||||
return;
|
||||
|
||||
if (!(op = op_buffer_peek_tail_checked (&builder->render_ops, OP_CHANGE_CLIP)))
|
||||
{
|
||||
op = op_buffer_add (&builder->render_ops, OP_CHANGE_CLIP);
|
||||
op->send_corners = !current_program_state ||
|
||||
!rounded_rect_corners_equal (¤t_program_state->clip, clip);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If the op before sent the corners, this one needs, too */
|
||||
op->send_corners |= !current_program_state ||
|
||||
!rounded_rect_corners_equal (¤t_program_state->clip, clip);
|
||||
}
|
||||
|
||||
op->clip = *clip;
|
||||
|
||||
if (current_program_state)
|
||||
current_program_state->clip = *clip;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -318,7 +238,6 @@ ops_push_clip (RenderOpBuilder *self,
|
||||
g_array_append_val (self->clip_stack, entry);
|
||||
self->current_clip = &g_array_index (self->clip_stack, ClipStackEntry, self->clip_stack->len - 1).rect;
|
||||
self->clip_is_rectilinear = entry.is_rectilinear;
|
||||
ops_set_clip (self, clip);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -336,7 +255,6 @@ ops_pop_clip (RenderOpBuilder *self)
|
||||
{
|
||||
self->current_clip = &head->rect;
|
||||
self->clip_is_rectilinear = head->is_rectilinear;
|
||||
ops_set_clip (self, &head->rect);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -352,32 +270,6 @@ ops_has_clip (RenderOpBuilder *self)
|
||||
self->clip_stack->len > 1;
|
||||
}
|
||||
|
||||
static void
|
||||
ops_set_modelview_internal (RenderOpBuilder *builder,
|
||||
GskTransform *transform)
|
||||
{
|
||||
ProgramState *current_program_state = get_current_program_state (builder);
|
||||
OpMatrix *op;
|
||||
|
||||
#if 0
|
||||
XXX This is not possible if we want pop() to work.
|
||||
if (builder->current_program &&
|
||||
gsk_transform_equal (builder->current_program_state->modelview, transform))
|
||||
return;
|
||||
#endif
|
||||
|
||||
if (!(op = op_buffer_peek_tail_checked (&builder->render_ops, OP_CHANGE_MODELVIEW)))
|
||||
op = op_buffer_add (&builder->render_ops, OP_CHANGE_MODELVIEW);
|
||||
|
||||
gsk_transform_to_matrix (transform, &op->matrix);
|
||||
|
||||
if (builder->current_program != NULL)
|
||||
{
|
||||
gsk_transform_unref (current_program_state->modelview);
|
||||
current_program_state->modelview = gsk_transform_ref (transform);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ops_set_modelview:
|
||||
* @builder
|
||||
@@ -410,7 +302,6 @@ ops_set_modelview (RenderOpBuilder *builder,
|
||||
builder->current_modelview = entry->transform;
|
||||
builder->scale_x = entry->metadata.scale_x;
|
||||
builder->scale_y = entry->metadata.scale_y;
|
||||
ops_set_modelview_internal (builder, entry->transform);
|
||||
}
|
||||
|
||||
/* This sets the given modelview to the one we get when multiplying
|
||||
@@ -456,7 +347,6 @@ ops_push_modelview (RenderOpBuilder *builder,
|
||||
builder->scale_x = entry->metadata.scale_x;
|
||||
builder->scale_y = entry->metadata.scale_y;
|
||||
builder->current_modelview = entry->transform;
|
||||
ops_set_modelview_internal (builder, entry->transform);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -480,7 +370,6 @@ ops_pop_modelview (RenderOpBuilder *builder)
|
||||
builder->scale_x = head->metadata.scale_x;
|
||||
builder->scale_y = head->metadata.scale_y;
|
||||
builder->current_modelview = head->transform;
|
||||
ops_set_modelview_internal (builder, head->transform);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -492,17 +381,7 @@ graphene_matrix_t
|
||||
ops_set_projection (RenderOpBuilder *builder,
|
||||
const graphene_matrix_t *projection)
|
||||
{
|
||||
ProgramState *current_program_state = get_current_program_state (builder);
|
||||
graphene_matrix_t prev_mv;
|
||||
OpMatrix *op;
|
||||
|
||||
if (!(op = op_buffer_peek_tail_checked (&builder->render_ops, OP_CHANGE_PROJECTION)))
|
||||
op = op_buffer_add (&builder->render_ops, OP_CHANGE_PROJECTION);
|
||||
|
||||
op->matrix = *projection;
|
||||
|
||||
if (builder->current_program != NULL)
|
||||
current_program_state->projection = *projection;
|
||||
|
||||
prev_mv = builder->current_projection;
|
||||
builder->current_projection = *projection;
|
||||
@@ -518,9 +397,8 @@ ops_set_viewport (RenderOpBuilder *builder,
|
||||
OpViewport *op;
|
||||
graphene_rect_t prev_viewport;
|
||||
|
||||
if (current_program_state != NULL &&
|
||||
rect_equal (¤t_program_state->viewport, viewport))
|
||||
return current_program_state->viewport;
|
||||
if (rect_equal (&builder->current_viewport, viewport))
|
||||
return *viewport;
|
||||
|
||||
op = ops_begin (builder, OP_CHANGE_VIEWPORT);
|
||||
op->viewport = *viewport;
|
||||
@@ -586,24 +464,14 @@ float
|
||||
ops_set_opacity (RenderOpBuilder *builder,
|
||||
float opacity)
|
||||
{
|
||||
ProgramState *current_program_state = get_current_program_state (builder);
|
||||
OpOpacity *op;
|
||||
float prev_opacity;
|
||||
|
||||
if (builder->current_opacity == opacity)
|
||||
return opacity;
|
||||
|
||||
if (!(op = op_buffer_peek_tail_checked (&builder->render_ops, OP_CHANGE_OPACITY)))
|
||||
op = op_buffer_add (&builder->render_ops, OP_CHANGE_OPACITY);
|
||||
|
||||
op->opacity = opacity;
|
||||
|
||||
prev_opacity = builder->current_opacity;
|
||||
builder->current_opacity = opacity;
|
||||
|
||||
if (builder->current_program != NULL)
|
||||
current_program_state->opacity = opacity;
|
||||
|
||||
return prev_opacity;
|
||||
}
|
||||
|
||||
@@ -666,30 +534,30 @@ ops_set_color_matrix (RenderOpBuilder *builder,
|
||||
const graphene_vec4_t *offset)
|
||||
{
|
||||
ProgramState *current_program_state = get_current_program_state (builder);
|
||||
const bool offset_equal = graphene_vec4_equal (offset, ¤t_program_state->color_matrix.offset);
|
||||
const bool matrix_equal = graphene_matrix_equal_fast (matrix,
|
||||
¤t_program_state->color_matrix.matrix);
|
||||
OpColorMatrix *op;
|
||||
bool offset_equal;
|
||||
|
||||
offset_equal = memcmp (offset,
|
||||
¤t_program_state->color_matrix.offset,
|
||||
sizeof (graphene_vec4_t)) == 0;
|
||||
|
||||
if (memcmp (matrix,
|
||||
¤t_program_state->color_matrix.matrix,
|
||||
sizeof (graphene_matrix_t)) == 0 &&
|
||||
offset_equal)
|
||||
if (offset_equal && matrix_equal)
|
||||
return;
|
||||
|
||||
current_program_state->color_matrix.matrix = *matrix;
|
||||
|
||||
op = ops_begin (builder, OP_CHANGE_COLOR_MATRIX);
|
||||
op->matrix = matrix;
|
||||
|
||||
if (!matrix_equal)
|
||||
{
|
||||
current_program_state->color_matrix.matrix = *matrix;
|
||||
op->matrix.value = matrix;
|
||||
op->matrix.send = TRUE;
|
||||
}
|
||||
else
|
||||
op->matrix.send = FALSE;
|
||||
|
||||
if (!offset_equal)
|
||||
{
|
||||
current_program_state->color_matrix.offset = *offset;
|
||||
op->offset.value = offset;
|
||||
op->offset.send = TRUE;
|
||||
|
||||
current_program_state->color_matrix.offset = *offset;
|
||||
}
|
||||
else
|
||||
op->offset.send = FALSE;
|
||||
@@ -755,8 +623,58 @@ GskQuadVertex *
|
||||
ops_draw (RenderOpBuilder *builder,
|
||||
const GskQuadVertex vertex_data[GL_N_VERTICES])
|
||||
{
|
||||
ProgramState *program_state = get_current_program_state (builder);
|
||||
OpDraw *op;
|
||||
|
||||
if (memcmp (&builder->current_projection, &program_state->projection, sizeof (graphene_matrix_t)) != 0)
|
||||
{
|
||||
OpMatrix *opm;
|
||||
|
||||
opm = ops_begin (builder, OP_CHANGE_PROJECTION);
|
||||
opm->matrix = builder->current_projection;
|
||||
program_state->projection = builder->current_projection;
|
||||
}
|
||||
|
||||
if (program_state->modelview == NULL ||
|
||||
!gsk_transform_equal (builder->current_modelview, program_state->modelview))
|
||||
{
|
||||
OpMatrix *opm;
|
||||
|
||||
opm = ops_begin (builder, OP_CHANGE_MODELVIEW);
|
||||
gsk_transform_to_matrix (builder->current_modelview, &opm->matrix);
|
||||
gsk_transform_unref (program_state->modelview);
|
||||
program_state->modelview = gsk_transform_ref (builder->current_modelview);
|
||||
}
|
||||
|
||||
if (!rect_equal (&builder->current_viewport, &program_state->viewport))
|
||||
{
|
||||
OpViewport *opv;
|
||||
|
||||
opv = ops_begin (builder, OP_CHANGE_VIEWPORT);
|
||||
opv->viewport = builder->current_viewport;
|
||||
program_state->viewport = builder->current_viewport;
|
||||
}
|
||||
|
||||
if (!rounded_rect_equal (builder->current_clip, &program_state->clip))
|
||||
{
|
||||
OpClip *opc;
|
||||
|
||||
opc = ops_begin (builder, OP_CHANGE_CLIP);
|
||||
opc->clip = *builder->current_clip;
|
||||
opc->send_corners = !rounded_rect_corners_equal (builder->current_clip, &program_state->clip);
|
||||
program_state->clip = *builder->current_clip;
|
||||
}
|
||||
|
||||
if (program_state->opacity != builder->current_opacity)
|
||||
{
|
||||
OpOpacity *opo;
|
||||
|
||||
opo = ops_begin (builder, OP_CHANGE_OPACITY);
|
||||
opo->opacity = builder->current_opacity;
|
||||
program_state->opacity = builder->current_opacity;
|
||||
}
|
||||
|
||||
/* TODO: Did the additions above break the following optimization? */
|
||||
if ((op = op_buffer_peek_tail_checked (&builder->render_ops, OP_DRAW)))
|
||||
{
|
||||
op->vao_size += GL_N_VERTICES;
|
||||
@@ -941,6 +859,7 @@ void
|
||||
ops_set_linear_gradient (RenderOpBuilder *self,
|
||||
guint n_color_stops,
|
||||
const GskColorStop *color_stops,
|
||||
gboolean repeat,
|
||||
float start_x,
|
||||
float start_y,
|
||||
float end_x,
|
||||
@@ -994,6 +913,7 @@ ops_set_linear_gradient (RenderOpBuilder *self,
|
||||
sizeof (GskColorStop) * real_n_color_stops);
|
||||
}
|
||||
|
||||
op->repeat = repeat;
|
||||
op->start_point[0] = start_x;
|
||||
op->start_point[1] = start_y;
|
||||
op->end_point[0] = end_x;
|
||||
@@ -1004,6 +924,7 @@ void
|
||||
ops_set_radial_gradient (RenderOpBuilder *self,
|
||||
guint n_color_stops,
|
||||
const GskColorStop *color_stops,
|
||||
gboolean repeat,
|
||||
float center_x,
|
||||
float center_y,
|
||||
float start,
|
||||
@@ -1027,6 +948,7 @@ ops_set_radial_gradient (RenderOpBuilder *self,
|
||||
op->radius[1] = vradius;
|
||||
op->start = start;
|
||||
op->end = end;
|
||||
op->repeat = repeat;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1035,7 +957,7 @@ ops_set_conic_gradient (RenderOpBuilder *self,
|
||||
const GskColorStop *color_stops,
|
||||
float center_x,
|
||||
float center_y,
|
||||
float rotation)
|
||||
float angle)
|
||||
{
|
||||
const guint real_n_color_stops = MIN (GL_MAX_GRADIENT_STOPS, n_color_stops);
|
||||
OpConicGradient *op;
|
||||
@@ -1049,6 +971,6 @@ ops_set_conic_gradient (RenderOpBuilder *self,
|
||||
op->color_stops.send = true;
|
||||
op->center[0] = center_x;
|
||||
op->center[1] = center_y;
|
||||
op->rotation = rotation;
|
||||
op->angle = angle;
|
||||
}
|
||||
|
||||
|
||||
@@ -118,22 +118,20 @@ struct _Program
|
||||
struct {
|
||||
int num_color_stops_location;
|
||||
int color_stops_location;
|
||||
int start_point_location;
|
||||
int end_point_location;
|
||||
int points_location;
|
||||
int repeat_location;
|
||||
} linear_gradient;
|
||||
struct {
|
||||
int num_color_stops_location;
|
||||
int color_stops_location;
|
||||
int center_location;
|
||||
int start_location;
|
||||
int end_location;
|
||||
int radius_location;
|
||||
int geometry_location;
|
||||
int range_location;
|
||||
int repeat_location;
|
||||
} radial_gradient;
|
||||
struct {
|
||||
int num_color_stops_location;
|
||||
int color_stops_location;
|
||||
int center_location;
|
||||
int rotation_location;
|
||||
int geometry_location;
|
||||
} conic_gradient;
|
||||
struct {
|
||||
int blur_radius_location;
|
||||
@@ -319,6 +317,7 @@ void ops_set_unblurred_outset_shadow (RenderOpBuilder *se
|
||||
void ops_set_linear_gradient (RenderOpBuilder *self,
|
||||
guint n_color_stops,
|
||||
const GskColorStop *color_stops,
|
||||
gboolean repeat,
|
||||
float start_x,
|
||||
float start_y,
|
||||
float end_x,
|
||||
@@ -326,6 +325,7 @@ void ops_set_linear_gradient (RenderOpBuilder *self,
|
||||
void ops_set_radial_gradient (RenderOpBuilder *self,
|
||||
guint n_color_stops,
|
||||
const GskColorStop *color_stops,
|
||||
gboolean repeat,
|
||||
float center_x,
|
||||
float center_y,
|
||||
float start,
|
||||
@@ -337,7 +337,7 @@ void ops_set_conic_gradient (RenderOpBuilder *self,
|
||||
const GskColorStop *color_stops,
|
||||
float center_x,
|
||||
float center_y,
|
||||
float rotation);
|
||||
float angle);
|
||||
|
||||
GskQuadVertex * ops_draw (RenderOpBuilder *builder,
|
||||
const GskQuadVertex vertex_data[GL_N_VERTICES]);
|
||||
|
||||
@@ -64,8 +64,10 @@ prepend_line_numbers (char *code,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
check_shader_error (int shader_id,
|
||||
GError **error)
|
||||
check_shader_error (int shader_id,
|
||||
int shader_type,
|
||||
const char *resource_path,
|
||||
GError **error)
|
||||
{
|
||||
int status;
|
||||
int log_len;
|
||||
@@ -91,7 +93,9 @@ check_shader_error (int shader_id,
|
||||
prepend_line_numbers (code, s);
|
||||
|
||||
g_set_error (error, GDK_GL_ERROR, GDK_GL_ERROR_COMPILATION_FAILED,
|
||||
"Compilation failure in shader.\nSource Code: %s\n\nError Message:\n%s\n\n",
|
||||
"Compilation failure in %s shader %s.\nSource Code:\n%s\n\nError Message:\n%s\n\n",
|
||||
(shader_type == GL_FRAGMENT_SHADER ? "fragment" : "vertex"),
|
||||
resource_path,
|
||||
s->str,
|
||||
buffer);
|
||||
|
||||
@@ -184,7 +188,7 @@ gsk_gl_shader_builder_create_program (GskGLShaderBuilder *self,
|
||||
});
|
||||
glCompileShader (vertex_id);
|
||||
|
||||
if (!check_shader_error (vertex_id, error))
|
||||
if (!check_shader_error (vertex_id, GL_VERTEX_SHADER, resource_path, error))
|
||||
{
|
||||
glDeleteShader (vertex_id);
|
||||
goto out;
|
||||
@@ -218,20 +222,22 @@ gsk_gl_shader_builder_create_program (GskGLShaderBuilder *self,
|
||||
});
|
||||
glCompileShader (fragment_id);
|
||||
|
||||
if (!check_shader_error (fragment_id, error))
|
||||
if (!check_shader_error (fragment_id, GL_FRAGMENT_SHADER, resource_path, error))
|
||||
{
|
||||
glDeleteShader (fragment_id);
|
||||
goto out;
|
||||
}
|
||||
|
||||
print_shader_info ("Fragment shader", vertex_id, resource_path);
|
||||
print_shader_info ("Fragment shader", fragment_id, resource_path);
|
||||
|
||||
program_id = glCreateProgram ();
|
||||
glAttachShader (program_id, vertex_id);
|
||||
glAttachShader (program_id, fragment_id);
|
||||
glBindAttribLocation (program_id, 0, "aPosition");
|
||||
glBindAttribLocation (program_id, 1, "vUv");
|
||||
glBindAttribLocation (program_id, 1, "aUv");
|
||||
glLinkProgram (program_id);
|
||||
glDetachShader (program_id, vertex_id);
|
||||
glDetachShader (program_id, fragment_id);
|
||||
|
||||
glGetProgramiv (program_id, GL_LINK_STATUS, &status);
|
||||
if (status == GL_FALSE)
|
||||
@@ -252,14 +258,9 @@ gsk_gl_shader_builder_create_program (GskGLShaderBuilder *self,
|
||||
|
||||
glDeleteProgram (program_id);
|
||||
program_id = -1;
|
||||
|
||||
goto out;
|
||||
}
|
||||
|
||||
glDetachShader (program_id, vertex_id);
|
||||
glDeleteShader (vertex_id);
|
||||
|
||||
glDetachShader (program_id, fragment_id);
|
||||
glDeleteShader (fragment_id);
|
||||
|
||||
out:
|
||||
|
||||
@@ -53,6 +53,7 @@ typedef struct { GskRoundedRect value; guint send: 1; guint send_corners: 1; } R
|
||||
typedef struct { const GdkRGBA *value; guint send: 1; } RGBAUniformValue;
|
||||
typedef struct { const graphene_vec4_t *value; guint send: 1; } Vec4UniformValue;
|
||||
typedef struct { const GskColorStop *value; guint send: 1; } ColorStopUniformValue;
|
||||
typedef struct { const graphene_matrix_t *value; guint send: 1; } MatrixUniformValue;
|
||||
|
||||
/* OpNode are allocated within OpBuffer.pos, but we keep
|
||||
* a secondary index into the locations of that buffer
|
||||
@@ -145,6 +146,7 @@ typedef struct
|
||||
IntUniformValue n_color_stops;
|
||||
float start_point[2];
|
||||
float end_point[2];
|
||||
gboolean repeat;
|
||||
} OpLinearGradient;
|
||||
|
||||
typedef struct
|
||||
@@ -155,6 +157,7 @@ typedef struct
|
||||
float end;
|
||||
float radius[2];
|
||||
float center[2];
|
||||
gboolean repeat;
|
||||
} OpRadialGradient;
|
||||
|
||||
typedef struct
|
||||
@@ -162,12 +165,12 @@ typedef struct
|
||||
ColorStopUniformValue color_stops;
|
||||
IntUniformValue n_color_stops;
|
||||
float center[2];
|
||||
float rotation;
|
||||
float angle;
|
||||
} OpConicGradient;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const graphene_matrix_t *matrix;
|
||||
MatrixUniformValue matrix;
|
||||
Vec4UniformValue offset;
|
||||
} OpColorMatrix;
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ static guint gsk_debug_flags;
|
||||
static void
|
||||
init_debug_flags (void)
|
||||
{
|
||||
static volatile gsize gsk_debug_flags__set;
|
||||
static gsize gsk_debug_flags__set;
|
||||
|
||||
if (g_once_init_enter (&gsk_debug_flags__set))
|
||||
{
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
GType
|
||||
@enum_name@_get_type (void)
|
||||
{
|
||||
static volatile gsize g_define_type_id__volatile = 0;
|
||||
static gsize g_define_type_id__volatile = 0;
|
||||
|
||||
if (g_once_init_enter (&g_define_type_id__volatile))
|
||||
{
|
||||
|
||||
@@ -184,7 +184,7 @@ gsk_render_node_init (GskRenderNode *self)
|
||||
GType
|
||||
gsk_render_node_get_type (void)
|
||||
{
|
||||
static volatile gsize render_node_type__volatile;
|
||||
static gsize render_node_type__volatile;
|
||||
|
||||
if (g_once_init_enter (&render_node_type__volatile))
|
||||
{
|
||||
|
||||
@@ -257,6 +257,8 @@ const graphene_point_t * gsk_conic_gradient_node_get_center (GskRenderNo
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
float gsk_conic_gradient_node_get_rotation (GskRenderNode *node);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
float gsk_conic_gradient_node_get_angle (GskRenderNode *node);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gsize gsk_conic_gradient_node_get_n_color_stops (GskRenderNode *node);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
const GskColorStop * gsk_conic_gradient_node_get_color_stops (GskRenderNode *node,
|
||||
|
||||
@@ -782,6 +782,7 @@ struct _GskConicGradientNode
|
||||
|
||||
graphene_point_t center;
|
||||
float rotation;
|
||||
float angle;
|
||||
|
||||
gsize n_stops;
|
||||
GskColorStop *stops;
|
||||
@@ -1023,6 +1024,12 @@ gsk_conic_gradient_node_new (const graphene_rect_t *bounds,
|
||||
self->stops = g_malloc_n (n_color_stops, sizeof (GskColorStop));
|
||||
memcpy (self->stops, color_stops, n_color_stops * sizeof (GskColorStop));
|
||||
|
||||
self->angle = 90.f - self->rotation;
|
||||
self->angle = G_PI * self->angle / 180.f;
|
||||
self->angle = fmodf (self->angle, 2.f * G_PI);
|
||||
if (self->angle < 0.f)
|
||||
self->angle += 2.f * G_PI;
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
@@ -1095,6 +1102,26 @@ gsk_conic_gradient_node_get_rotation (GskRenderNode *node)
|
||||
return self->rotation;
|
||||
}
|
||||
|
||||
/**
|
||||
* gsk_conic_gradient_node_get_angle:
|
||||
* @node: (type GskConicGradientNode): a #GskRenderNode for a conic gradient
|
||||
*
|
||||
* Retrieves the angle for the gradient in radians, normalized in [0, 2 * PI]
|
||||
*
|
||||
* The angle is starting at the top and going clockwise, as expressed
|
||||
* in the css specification:
|
||||
* angle = 90 - gsk_conic_gradient_node_get_rotation()
|
||||
*
|
||||
* Returns: the angle for the gradient
|
||||
*/
|
||||
float
|
||||
gsk_conic_gradient_node_get_angle (GskRenderNode *node)
|
||||
{
|
||||
GskConicGradientNode *self = (GskConicGradientNode *) node;
|
||||
|
||||
return self->angle;
|
||||
}
|
||||
|
||||
/*** GSK_BORDER_NODE ***/
|
||||
|
||||
/**
|
||||
@@ -1263,15 +1290,22 @@ gsk_border_node_diff (GskRenderNode *node1,
|
||||
gdk_rgba_equal (&self1->border_color[0], &self2->border_color[0]))
|
||||
return;
|
||||
|
||||
if (gsk_rounded_rect_equal (&self1->outline, &self2->outline) &&
|
||||
/* Different uniformity -> diff impossible */
|
||||
if (self1->uniform ^ self2->uniform)
|
||||
{
|
||||
gsk_render_node_diff_impossible (node1, node2, region);
|
||||
return;
|
||||
}
|
||||
|
||||
if (self1->border_width[0] == self2->border_width[0] &&
|
||||
self1->border_width[1] == self2->border_width[1] &&
|
||||
self1->border_width[2] == self2->border_width[2] &&
|
||||
self1->border_width[3] == self2->border_width[3] &&
|
||||
gdk_rgba_equal (&self1->border_color[0], &self2->border_color[0]) &&
|
||||
gdk_rgba_equal (&self1->border_color[1], &self2->border_color[1]) &&
|
||||
gdk_rgba_equal (&self1->border_color[2], &self2->border_color[2]) &&
|
||||
gdk_rgba_equal (&self1->border_color[3], &self2->border_color[3]) &&
|
||||
self1->border_width[0] == self2->border_width[0] &&
|
||||
self1->border_width[1] == self2->border_width[1] &&
|
||||
self1->border_width[2] == self2->border_width[2] &&
|
||||
self1->border_width[3] == self2->border_width[3])
|
||||
gsk_rounded_rect_equal (&self1->outline, &self2->outline))
|
||||
return;
|
||||
|
||||
gsk_render_node_diff_impossible (node1, node2, region);
|
||||
@@ -2755,6 +2789,16 @@ gsk_transform_node_draw (GskRenderNode *node,
|
||||
ctm.xx, ctm.yx,
|
||||
ctm.xy, ctm.yy,
|
||||
ctm.x0, ctm.y0));
|
||||
if (xx * yy == xy * yx)
|
||||
{
|
||||
/* broken matrix here. This can happen during transitions
|
||||
* (like when flipping an axis at the point where scale == 0)
|
||||
* and just means that nothing should be drawn.
|
||||
* But Cairo thows lots of ugly errors instead of silently
|
||||
* going on. So We silently go on.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
cairo_transform (cr, &ctm);
|
||||
|
||||
gsk_render_node_draw (self->child, cr);
|
||||
@@ -5632,7 +5676,7 @@ gsk_render_node_init_types_once (void)
|
||||
void
|
||||
gsk_render_node_init_types (void)
|
||||
{
|
||||
static volatile gsize register_types__volatile;
|
||||
static gsize register_types__volatile;
|
||||
|
||||
if (g_once_init_enter (®ister_types__volatile))
|
||||
{
|
||||
|
||||
@@ -688,10 +688,18 @@ create_ascii_glyphs (PangoFont *font)
|
||||
glyph_string = pango_glyph_string_new ();
|
||||
for (i = MIN_ASCII_GLYPH; i < MAX_ASCII_GLYPH; i++)
|
||||
{
|
||||
pango_shape ((char[2]) { i, 0 },
|
||||
1,
|
||||
¬_a_hack,
|
||||
glyph_string);
|
||||
const char text[2] = { i, 0 };
|
||||
PangoShapeFlags flags = 0;
|
||||
|
||||
if (cairo_version () < CAIRO_VERSION_ENCODE (1, 17, 4))
|
||||
flags = PANGO_SHAPE_ROUND_POSITIONS;
|
||||
|
||||
pango_shape_with_flags (text, 1,
|
||||
text, 1,
|
||||
¬_a_hack,
|
||||
glyph_string,
|
||||
flags);
|
||||
|
||||
if (glyph_string->num_glyphs != 1)
|
||||
{
|
||||
pango_glyph_string_free (glyph_string);
|
||||
@@ -1386,7 +1394,7 @@ parse_cairo_node (GtkCssParser *parser)
|
||||
if (surface != NULL)
|
||||
{
|
||||
cairo_t *cr = gsk_cairo_node_get_draw_context (node);
|
||||
cairo_set_source_surface (cr, surface, 0, 0);
|
||||
cairo_set_source_surface (cr, surface, bounds.origin.x, bounds.origin.y);
|
||||
cairo_paint (cr);
|
||||
cairo_destroy (cr);
|
||||
}
|
||||
@@ -2304,6 +2312,84 @@ base64_encode_with_linebreaks (const guchar *data,
|
||||
return out;
|
||||
}
|
||||
|
||||
void
|
||||
gsk_text_node_serialize_glyphs (GskRenderNode *node,
|
||||
GString *p)
|
||||
{
|
||||
const guint n_glyphs = gsk_text_node_get_num_glyphs (node);
|
||||
const PangoGlyphInfo *glyphs = gsk_text_node_get_glyphs (node, NULL);
|
||||
PangoFont *font = gsk_text_node_get_font (node);
|
||||
GString *str;
|
||||
guint i, j;
|
||||
PangoGlyphString *ascii;
|
||||
|
||||
ascii = create_ascii_glyphs (font);
|
||||
str = g_string_new ("");
|
||||
|
||||
for (i = 0; i < n_glyphs; i++)
|
||||
{
|
||||
if (ascii)
|
||||
{
|
||||
for (j = 0; j < ascii->num_glyphs; j++)
|
||||
{
|
||||
if (glyphs[i].glyph == ascii->glyphs[j].glyph &&
|
||||
glyphs[i].geometry.width == ascii->glyphs[j].geometry.width &&
|
||||
glyphs[i].geometry.x_offset == 0 &&
|
||||
glyphs[i].geometry.y_offset == 0 &&
|
||||
glyphs[i].attr.is_cluster_start)
|
||||
{
|
||||
g_string_append_c (str, j + MIN_ASCII_GLYPH);
|
||||
break;
|
||||
}
|
||||
else if (glyphs[i].glyph == ascii->glyphs[j].glyph)
|
||||
{
|
||||
if (glyphs[i].geometry.width != ascii->glyphs[j].geometry.width)
|
||||
g_print ("not ascii because of width (%d != %d)\n",
|
||||
glyphs[i].geometry.width,
|
||||
ascii->glyphs[j].geometry.width);
|
||||
if (glyphs[i].geometry.x_offset != 0 ||
|
||||
glyphs[i].geometry.y_offset != 0)
|
||||
g_print ("not ascii because of offset\n");
|
||||
if (!glyphs[i].attr.is_cluster_start)
|
||||
g_print ("not ascii because of cluster\n");
|
||||
}
|
||||
}
|
||||
if (j != ascii->num_glyphs)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (str->len)
|
||||
{
|
||||
g_string_append_printf (p, "\"%s\", ", str->str);
|
||||
g_string_set_size (str, 0);
|
||||
}
|
||||
|
||||
g_string_append_printf (p, "%u %g",
|
||||
glyphs[i].glyph,
|
||||
(double) glyphs[i].geometry.width / PANGO_SCALE);
|
||||
if (!glyphs[i].attr.is_cluster_start ||
|
||||
glyphs[i].geometry.x_offset != 0 ||
|
||||
glyphs[i].geometry.y_offset != 0)
|
||||
{
|
||||
g_string_append_printf (p, " %g %g",
|
||||
(double) glyphs[i].geometry.x_offset / PANGO_SCALE,
|
||||
(double) glyphs[i].geometry.y_offset / PANGO_SCALE);
|
||||
if (!glyphs[i].attr.is_cluster_start)
|
||||
g_string_append (p, " same-cluster");
|
||||
}
|
||||
|
||||
if (i + 1 < n_glyphs)
|
||||
g_string_append (p, ", ");
|
||||
}
|
||||
|
||||
if (str->len)
|
||||
g_string_append_printf (p, "\"%s\"", str->str);
|
||||
|
||||
g_string_free (str, TRUE);
|
||||
if (ascii)
|
||||
pango_glyph_string_free (ascii);
|
||||
}
|
||||
|
||||
static void
|
||||
render_node_print (Printer *p,
|
||||
GskRenderNode *node)
|
||||
@@ -2631,16 +2717,11 @@ render_node_print (Printer *p,
|
||||
|
||||
case GSK_TEXT_NODE:
|
||||
{
|
||||
const guint n_glyphs = gsk_text_node_get_num_glyphs (node);
|
||||
const PangoGlyphInfo *glyphs = gsk_text_node_get_glyphs (node, NULL);
|
||||
const graphene_point_t *offset = gsk_text_node_get_offset (node);
|
||||
const GdkRGBA *color = gsk_text_node_get_color (node);
|
||||
PangoFont *font = gsk_text_node_get_font (node);
|
||||
PangoFontDescription *desc;
|
||||
char *font_name;
|
||||
GString *str;
|
||||
guint i, j;
|
||||
PangoGlyphString *ascii = create_ascii_glyphs (font);
|
||||
|
||||
start_node (p, "text");
|
||||
|
||||
@@ -2650,61 +2731,14 @@ render_node_print (Printer *p,
|
||||
_indent (p);
|
||||
desc = pango_font_describe (font);
|
||||
font_name = pango_font_description_to_string (desc);
|
||||
if (ascii == NULL)
|
||||
g_print ("\"%s\" has no ascii table\n", font_name);
|
||||
g_string_append_printf (p->str, "font: \"%s\";\n", font_name);
|
||||
g_free (font_name);
|
||||
pango_font_description_free (desc);
|
||||
|
||||
_indent (p);
|
||||
str = g_string_new (NULL);
|
||||
g_string_append (p->str, "glyphs: ");
|
||||
for (i = 0; i < n_glyphs; i++)
|
||||
{
|
||||
if (ascii)
|
||||
{
|
||||
for (j = 0; j < ascii->num_glyphs; j++)
|
||||
{
|
||||
if (glyphs[i].glyph == ascii->glyphs[j].glyph &&
|
||||
glyphs[i].geometry.width == ascii->glyphs[j].geometry.width &&
|
||||
glyphs[i].geometry.x_offset == 0 &&
|
||||
glyphs[i].geometry.y_offset == 0 &&
|
||||
glyphs[i].attr.is_cluster_start)
|
||||
{
|
||||
g_string_append_c (str, j + MIN_ASCII_GLYPH);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (j != ascii->num_glyphs)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (str->len)
|
||||
{
|
||||
g_string_append_printf (p->str, "\"%s\", ", str->str);
|
||||
g_string_set_size (str, 0);
|
||||
}
|
||||
|
||||
g_string_append_printf (p->str, "%u %g",
|
||||
glyphs[i].glyph,
|
||||
(double) glyphs[i].geometry.width / PANGO_SCALE);
|
||||
if (!glyphs[i].attr.is_cluster_start ||
|
||||
glyphs[i].geometry.x_offset != 0 ||
|
||||
glyphs[i].geometry.y_offset != 0)
|
||||
{
|
||||
g_string_append_printf (p->str, "%g %g",
|
||||
(double) glyphs[i].geometry.x_offset / PANGO_SCALE,
|
||||
(double) glyphs[i].geometry.y_offset / PANGO_SCALE);
|
||||
if (!glyphs[i].attr.is_cluster_start)
|
||||
g_string_append (p->str, " same-cluster");
|
||||
}
|
||||
|
||||
if (i + 1 < n_glyphs)
|
||||
g_string_append (p->str, ", ");
|
||||
}
|
||||
|
||||
if (str->len)
|
||||
g_string_append_printf (p->str, "\"%s\"", str->str);
|
||||
gsk_text_node_serialize_glyphs (node, p->str);
|
||||
|
||||
g_string_append_c (p->str, ';');
|
||||
g_string_append_c (p->str, '\n');
|
||||
@@ -2713,10 +2747,6 @@ render_node_print (Printer *p,
|
||||
append_point_param (p, "offset", offset);
|
||||
|
||||
end_node (p);
|
||||
|
||||
g_string_free (str, TRUE);
|
||||
if (ascii)
|
||||
pango_glyph_string_free (ascii);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
@@ -96,6 +96,9 @@ void gsk_render_node_diff_impossible (GskRenderNode
|
||||
|
||||
bool gsk_border_node_get_uniform (GskRenderNode *self);
|
||||
|
||||
void gsk_text_node_serialize_glyphs (GskRenderNode *self,
|
||||
GString *str);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GSK_RENDER_NODE_PRIVATE_H__ */
|
||||
|
||||
@@ -7,6 +7,16 @@
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GSK_ROUNDED_RECT_INIT_FROM_RECT(_r) \
|
||||
(GskRoundedRect) { .bounds = _r, \
|
||||
.corner = { \
|
||||
GRAPHENE_SIZE_INIT(0, 0),\
|
||||
GRAPHENE_SIZE_INIT(0, 0),\
|
||||
GRAPHENE_SIZE_INIT(0, 0),\
|
||||
GRAPHENE_SIZE_INIT(0, 0),\
|
||||
}}
|
||||
|
||||
|
||||
gboolean gsk_rounded_rect_is_circular (const GskRoundedRect *self);
|
||||
|
||||
void gsk_rounded_rect_path (const GskRoundedRect *self,
|
||||
|
||||