Compare commits
1054 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
73bea05c33 | ||
|
|
9eec8e9e45 | ||
|
|
2da2f7cf7f | ||
|
|
f0906e45f2 | ||
|
|
60399e05fb | ||
|
|
c88f865aa7 | ||
|
|
f464307f61 | ||
|
|
92a74adc8c | ||
|
|
0b312d878c | ||
|
|
4b5877972e | ||
|
|
6ba7b4ad73 | ||
|
|
0c3056b649 | ||
|
|
b4ba384d68 | ||
|
|
bce7b5807a | ||
|
|
7b15830fbc | ||
|
|
d40e55cf88 | ||
|
|
acd47daa3b | ||
|
|
0b7bf4c5d0 | ||
|
|
586dcb94d6 | ||
|
|
5db8a550db | ||
|
|
06afb5d354 | ||
|
|
42a309f1a5 | ||
|
|
e92e4c5728 | ||
|
|
8d771eb26c | ||
|
|
7aab4acecc | ||
|
|
23d8b6063c | ||
|
|
af831e488b | ||
|
|
11e90e4fa0 | ||
|
|
0b200e393f | ||
|
|
a18f52b7d4 | ||
|
|
65e6846500 | ||
|
|
eabe4fd79b | ||
|
|
bdac484224 | ||
|
|
dcbba58487 | ||
|
|
e0c3d09e50 | ||
|
|
cf11438f2f | ||
|
|
64891e11d4 | ||
|
|
447d79d908 | ||
|
|
d7dbefa664 | ||
|
|
3d4685fca3 | ||
|
|
ff83daa700 | ||
|
|
0ed327ba0e | ||
|
|
5fe9faf2e3 | ||
|
|
7b15c68cd0 | ||
|
|
75fed298b8 | ||
|
|
d21112a3ce | ||
|
|
083d023b6b | ||
|
|
89fc4efe6f | ||
|
|
7604eb1e39 | ||
|
|
fda50855c6 | ||
|
|
dd82df9e32 | ||
|
|
1a459c5dcd | ||
|
|
735f803c2f | ||
|
|
452d93c7ea | ||
|
|
c4f5358826 | ||
|
|
d3e181f7de | ||
|
|
cde32368f0 | ||
|
|
da82eb8e1c | ||
|
|
40e639fb6e | ||
|
|
e3a23a9a9d | ||
|
|
8558560030 | ||
|
|
52483b88ce | ||
|
|
2bb0d815ee | ||
|
|
887c743e3d | ||
|
|
3e5bbfb2a5 | ||
|
|
2ca86eb969 | ||
|
|
393dd5a838 | ||
|
|
baba8aa9a5 | ||
|
|
a27ae5362c | ||
|
|
e6d3c58ccf | ||
|
|
59320f4aa1 | ||
|
|
dc397fce3c | ||
|
|
317d4c8f8d | ||
|
|
8d4968afb2 | ||
|
|
519258c382 | ||
|
|
34693b0d9f | ||
|
|
919128d8c2 | ||
|
|
7f26ca0c32 | ||
|
|
42b14ce5f2 | ||
|
|
68cff22966 | ||
|
|
86a137b2ff | ||
|
|
65f51d2d16 | ||
|
|
e1dcbd4442 | ||
|
|
1722b39f92 | ||
|
|
96d6ff16b6 | ||
|
|
4962b76b47 | ||
|
|
981690b12e | ||
|
|
412e77d500 | ||
|
|
df1c6956b4 | ||
|
|
77e0b09efc | ||
|
|
1d6416c12b | ||
|
|
6b019d4dd0 | ||
|
|
ac18330f65 | ||
|
|
e93a5479de | ||
|
|
9d01189f2f | ||
|
|
3149f1c934 | ||
|
|
e5d3cc20d9 | ||
|
|
57f6effa1a | ||
|
|
584e9f93a4 | ||
|
|
41396e1344 | ||
|
|
36ed85cc9c | ||
|
|
d57594c709 | ||
|
|
5b888393e5 | ||
|
|
2f138ce93b | ||
|
|
a6d22b3af1 | ||
|
|
6479495fbf | ||
|
|
1ea2643aa9 | ||
|
|
a241b4480e | ||
|
|
f8231cf1a7 | ||
|
|
a730012006 | ||
|
|
977a69ab84 | ||
|
|
7e4d6b556c | ||
|
|
45ff81848f | ||
|
|
73afd4976a | ||
|
|
07c115a383 | ||
|
|
a9f658ab8f | ||
|
|
9c258a5441 | ||
|
|
7c0cf9e0c9 | ||
|
|
57ba5ad39e | ||
|
|
1ba946d3ba | ||
|
|
d43ddcb2e8 | ||
|
|
05e4079682 | ||
|
|
317209597d | ||
|
|
fad664c89e | ||
|
|
e3c4076b27 | ||
|
|
99f7cc1e61 | ||
|
|
154107696a | ||
|
|
1cdb6ada4e | ||
|
|
56607e8cfe | ||
|
|
94b47ce47a | ||
|
|
3594df7f87 | ||
|
|
c96113e6d8 | ||
|
|
69b1b4d95b | ||
|
|
3e766a4fe2 | ||
|
|
60a8367594 | ||
|
|
22b9cf1644 | ||
|
|
224a8390eb | ||
|
|
5fee68f80d | ||
|
|
41086f0756 | ||
|
|
78c153ae14 | ||
|
|
53c02a1e84 | ||
|
|
1523fecfe1 | ||
|
|
75821de2d7 | ||
|
|
91d2e1bc7f | ||
|
|
986fd9959d | ||
|
|
92b6c59f80 | ||
|
|
1860da7a1a | ||
|
|
09a0151233 | ||
|
|
c47759bd3d | ||
|
|
c543206d79 | ||
|
|
3523b02a35 | ||
|
|
f936d7a883 | ||
|
|
804caae32a | ||
|
|
bc09956d79 | ||
|
|
7104861614 | ||
|
|
22288d9854 | ||
|
|
7703aa5cd3 | ||
|
|
17896f9841 | ||
|
|
a67f82975e | ||
|
|
9bc9116d24 | ||
|
|
1ff47f246b | ||
|
|
2b1c09dd42 | ||
|
|
4559bbbb9a | ||
|
|
700c30d465 | ||
|
|
2d8a8e3575 | ||
|
|
9ea6bcb7b3 | ||
|
|
394e0ab3be | ||
|
|
fc533c6598 | ||
|
|
40709245ad | ||
|
|
1e6bad6c4f | ||
|
|
6d95ac9299 | ||
|
|
ce003f4eec | ||
|
|
f737131d27 | ||
|
|
f54c153775 | ||
|
|
f2436eaf7b | ||
|
|
2f9387630f | ||
|
|
c1895ad823 | ||
|
|
f60e5950dc | ||
|
|
5ae37c6d99 | ||
|
|
d91c612eab | ||
|
|
3894f04d0e | ||
|
|
a39d55e5b0 | ||
|
|
fc5966a347 | ||
|
|
55a4b4a174 | ||
|
|
045446c3da | ||
|
|
f0120700dc | ||
|
|
6b740c86f9 | ||
|
|
fb6de419f6 | ||
|
|
1e561035e2 | ||
|
|
0a23c4678f | ||
|
|
edc21ef202 | ||
|
|
2441409b34 | ||
|
|
ae01669737 | ||
|
|
21103ad811 | ||
|
|
6e5573f5bb | ||
|
|
e17d51df66 | ||
|
|
01f63c87b2 | ||
|
|
e449bd8459 | ||
|
|
edb69f0bb3 | ||
|
|
cf48d15c2c | ||
|
|
7cc49ba288 | ||
|
|
6809a78321 | ||
|
|
c1002b20ee | ||
|
|
fdf3ae31c6 | ||
|
|
f915c6bb5c | ||
|
|
659c1c41de | ||
|
|
8f2be7e840 | ||
|
|
14772602a0 | ||
|
|
93921f32bd | ||
|
|
812c8926ec | ||
|
|
b14bc4749e | ||
|
|
d56276f6d6 | ||
|
|
f1d44635bd | ||
|
|
de8cb17ee8 | ||
|
|
e69eb24b32 | ||
|
|
4a388b5540 | ||
|
|
25bedcd85d | ||
|
|
feb3d3b274 | ||
|
|
e191519d30 | ||
|
|
aa1921cbef | ||
|
|
e2abb0211c | ||
|
|
b024c9a743 | ||
|
|
91c60dcac0 | ||
|
|
66117d1017 | ||
|
|
177302cf4d | ||
|
|
d1fc90e8a2 | ||
|
|
da152ac37e | ||
|
|
29d4821e3d | ||
|
|
cbd03cda56 | ||
|
|
018bbd6774 | ||
|
|
e50e2136d2 | ||
|
|
a5eeb99f37 | ||
|
|
52cb3b2ec4 | ||
|
|
9ca55cb5bf | ||
|
|
bc4b2c142f | ||
|
|
b65d7c86d7 | ||
|
|
cc37c9c86c | ||
|
|
e41a4ced8b | ||
|
|
eb2699aa9f | ||
|
|
fcab393c3b | ||
|
|
8a6de521e7 | ||
|
|
88db5509a3 | ||
|
|
7538ff9798 | ||
|
|
c0a60ece97 | ||
|
|
c799b05f2a | ||
|
|
d468dd2f3b | ||
|
|
029fc0fdef | ||
|
|
c43737324a | ||
|
|
270e643c7b | ||
|
|
edd8d55b42 | ||
|
|
3b50f2e8b9 | ||
|
|
d4dd7969d6 | ||
|
|
a0bebefef8 | ||
|
|
42a4c62025 | ||
|
|
dd198cfc06 | ||
|
|
3ef96c445f | ||
|
|
d9c39f6795 | ||
|
|
aec7ca8200 | ||
|
|
f567bf62e1 | ||
|
|
1f00cdc7a6 | ||
|
|
dc875b6af9 | ||
|
|
e2873bc614 | ||
|
|
3e4bfa2bae | ||
|
|
9bbf09fb0a | ||
|
|
c874f65d95 | ||
|
|
8a12628af9 | ||
|
|
17e0618ff6 | ||
|
|
73d5f7061b | ||
|
|
ccbaa020ff | ||
|
|
a9c89fa23e | ||
|
|
36730537cc | ||
|
|
9456f6eea1 | ||
|
|
2c630a74cd | ||
|
|
9462b3fea2 | ||
|
|
d62313e75c | ||
|
|
023bf9aea7 | ||
|
|
4bc593c761 | ||
|
|
f47e6dda78 | ||
|
|
5c2d9d6f19 | ||
|
|
5efa8071d6 | ||
|
|
659832ccab | ||
|
|
913f6d4a4f | ||
|
|
cb386ec2a2 | ||
|
|
2f873052f9 | ||
|
|
60aceb984f | ||
|
|
9dbd79f2d8 | ||
|
|
0aabf47f09 | ||
|
|
2961cc44c5 | ||
|
|
46da364289 | ||
|
|
cb99370ce4 | ||
|
|
c2d1a21f9c | ||
|
|
edc6790fbb | ||
|
|
b0d7889b20 | ||
|
|
867f2de194 | ||
|
|
50e2a8239b | ||
|
|
42f9ea07e2 | ||
|
|
9b28153571 | ||
|
|
2e1e7e7265 | ||
|
|
7369ce58da | ||
|
|
c7a6d1e8bf | ||
|
|
17b40ca148 | ||
|
|
29d424ef91 | ||
|
|
27e9b87fbd | ||
|
|
f2ac5576c2 | ||
|
|
590a1c2f3a | ||
|
|
75b186eb62 | ||
|
|
998c787638 | ||
|
|
b2ab0b1fcb | ||
|
|
b19526489e | ||
|
|
856728ea10 | ||
|
|
df2fb3b520 | ||
|
|
48c650c102 | ||
|
|
ccf18c239d | ||
|
|
48b408e2c3 | ||
|
|
433de2849d | ||
|
|
94deb551aa | ||
|
|
9767b3a97e | ||
|
|
676e9ab127 | ||
|
|
5b15bc86a3 | ||
|
|
bad392eb2a | ||
|
|
278f976add | ||
|
|
f58ece72cf | ||
|
|
af3f34ca94 | ||
|
|
07a5cf4996 | ||
|
|
d808298b68 | ||
|
|
108b7025dc | ||
|
|
9822d2b6b2 | ||
|
|
a36594e754 | ||
|
|
c331e22f3a | ||
|
|
d077f113b2 | ||
|
|
1ab89b3908 | ||
|
|
c5da579cda | ||
|
|
38bbcb7411 | ||
|
|
3223f3e3b8 | ||
|
|
ba885e2ace | ||
|
|
9cc051ffa5 | ||
|
|
e8dd40ccca | ||
|
|
53263d3d27 | ||
|
|
71c935d1f4 | ||
|
|
5e07e216d3 | ||
|
|
88894b705b | ||
|
|
b8d01bf041 | ||
|
|
c636ea036a | ||
|
|
08099ed17d | ||
|
|
f0e8ee3c29 | ||
|
|
33a1cf203e | ||
|
|
5adce748cb | ||
|
|
21d39b6054 | ||
|
|
a2f30ac1ab | ||
|
|
3764b27bab | ||
|
|
8fb610915c | ||
|
|
16a7e3e3d8 | ||
|
|
47ea51efab | ||
|
|
50554bb92b | ||
|
|
0ea0fc9c7b | ||
|
|
206e837dde | ||
|
|
f43d0365dd | ||
|
|
72a557087c | ||
|
|
b59f9b97f3 | ||
|
|
a1f4735652 | ||
|
|
c5e372490d | ||
|
|
78e083b014 | ||
|
|
6ac723321f | ||
|
|
343b08f3e6 | ||
|
|
c8d1f23ff5 | ||
|
|
8a7fd71697 | ||
|
|
39fcfa4473 | ||
|
|
d188c6dbaf | ||
|
|
8aec0dc200 | ||
|
|
9053fd8335 | ||
|
|
a9720259f0 | ||
|
|
b012886294 | ||
|
|
5de26c684b | ||
|
|
b1d9259e7d | ||
|
|
89bba41fd7 | ||
|
|
248d7ec93c | ||
|
|
2be2912e43 | ||
|
|
2755ad19be | ||
|
|
156f99560d | ||
|
|
159e9de034 | ||
|
|
f679b0648b | ||
|
|
f1ffa6eae9 | ||
|
|
ec1b61494f | ||
|
|
cc561915b7 | ||
|
|
15707acb82 | ||
|
|
a8ce293bfc | ||
|
|
4eee322654 | ||
|
|
67ae05d855 | ||
|
|
5c535517b5 | ||
|
|
ded6bc04ff | ||
|
|
3e8179c66e | ||
|
|
3c21d6bf92 | ||
|
|
4c7af43eb3 | ||
|
|
5ce96d5f3b | ||
|
|
6b61cd1869 | ||
|
|
9bbf5966d3 | ||
|
|
bcb6cf04ed | ||
|
|
c9dbb30aff | ||
|
|
2c88797195 | ||
|
|
89a351fd66 | ||
|
|
e1d3d01e2f | ||
|
|
76a58c40db | ||
|
|
3b0ceeb09a | ||
|
|
f95e082186 | ||
|
|
df8e2bc0a0 | ||
|
|
42164fa8bb | ||
|
|
6016e17a38 | ||
|
|
b2de83efcb | ||
|
|
493f90499b | ||
|
|
8b71cff71d | ||
|
|
f9268e8137 | ||
|
|
b4b282dc81 | ||
|
|
d4d328f96f | ||
|
|
553eb55f8a | ||
|
|
9ea43096d4 | ||
|
|
e9ffe8f212 | ||
|
|
931be7d729 | ||
|
|
378bb481fa | ||
|
|
8f83c7e255 | ||
|
|
3c99b50d2c | ||
|
|
9fccbeaa75 | ||
|
|
d35bac452b | ||
|
|
d8c79e91a2 | ||
|
|
7f5a249056 | ||
|
|
70ce353a58 | ||
|
|
c0ede8d46e | ||
|
|
8f02ea39e5 | ||
|
|
8a8cd4e248 | ||
|
|
08d0575ed0 | ||
|
|
43476c09ed | ||
|
|
6123212a68 | ||
|
|
6106207b93 | ||
|
|
b5036faa2a | ||
|
|
56fd3af4d0 | ||
|
|
26beab6064 | ||
|
|
f41fe7b8e4 | ||
|
|
7d6797c9ed | ||
|
|
2e34d62111 | ||
|
|
6eda5deeff | ||
|
|
83b98738b6 | ||
|
|
a07455aa0d | ||
|
|
49a4d27245 | ||
|
|
ff59bf356b | ||
|
|
c6ce05b782 | ||
|
|
db77204a52 | ||
|
|
4c08d1643f | ||
|
|
592436503c | ||
|
|
1877bb8a27 | ||
|
|
67a5120b5b | ||
|
|
9d8f56edaa | ||
|
|
7ec9c5181d | ||
|
|
853ef43dae | ||
|
|
1fdf5b7cf8 | ||
|
|
0e3ed7a738 | ||
|
|
9c1a66518b | ||
|
|
280544b874 | ||
|
|
3c9687fcf1 | ||
|
|
f207402228 | ||
|
|
a080f1197a | ||
|
|
8f0b9bf5ae | ||
|
|
b74d3c2221 | ||
|
|
49b0ee21c1 | ||
|
|
481634930c | ||
|
|
d58c038fe8 | ||
|
|
056e9012d2 | ||
|
|
82e4690564 | ||
|
|
8dc2c4b24a | ||
|
|
3e913ff16e | ||
|
|
37702af22b | ||
|
|
12908ab863 | ||
|
|
4cb599f378 | ||
|
|
fe210fb0dd | ||
|
|
1fee30af36 | ||
|
|
3f329b2d0f | ||
|
|
1fd03acf9d | ||
|
|
a26c1a5f0d | ||
|
|
7a608bda27 | ||
|
|
c400dce0b1 | ||
|
|
5912b2d64a | ||
|
|
e38e8ed73e | ||
|
|
5088103d31 | ||
|
|
76b185e6f6 | ||
|
|
f3999f7ebf | ||
|
|
f8e7ecfde1 | ||
|
|
cc49e044a5 | ||
|
|
9205193147 | ||
|
|
124d689f45 | ||
|
|
d2a2591d28 | ||
|
|
64a1a1dd6b | ||
|
|
3b383569a4 | ||
|
|
c2fe438676 | ||
|
|
0ade146e26 | ||
|
|
ba266325d0 | ||
|
|
e6322e177e | ||
|
|
080a4cda49 | ||
|
|
6b63868641 | ||
|
|
cb710f1999 | ||
|
|
85bb9aaefc | ||
|
|
6c02017212 | ||
|
|
90bccf4e82 | ||
|
|
18db7ad470 | ||
|
|
468ddd4d49 | ||
|
|
ff4b5c8996 | ||
|
|
06aa640664 | ||
|
|
9f24229f82 | ||
|
|
214370ee23 | ||
|
|
217d817408 | ||
|
|
6dfaafc9f2 | ||
|
|
287de3844d | ||
|
|
878e4a34d3 | ||
|
|
b893dc9552 | ||
|
|
687b80a037 | ||
|
|
a8a98523db | ||
|
|
0a224964a6 | ||
|
|
0457c37847 | ||
|
|
037c0e4005 | ||
|
|
b9389d3784 | ||
|
|
86a3400f2e | ||
|
|
8245fd4beb | ||
|
|
f41cfd3caa | ||
|
|
07d6ef13c5 | ||
|
|
883e8328e0 | ||
|
|
c6d5816c95 | ||
|
|
f37c5ebd26 | ||
|
|
2c71825324 | ||
|
|
38ad56e6a1 | ||
|
|
84d698464c | ||
|
|
9363269ceb | ||
|
|
59eb9aeb73 | ||
|
|
d9109a0e92 | ||
|
|
f27c0c65b1 | ||
|
|
212f629876 | ||
|
|
05f2f3ba8c | ||
|
|
a66072f312 | ||
|
|
3ba582375d | ||
|
|
4c211f1872 | ||
|
|
2ceba0d31c | ||
|
|
95168e179c | ||
|
|
34959b58f4 | ||
|
|
2be51dc3b1 | ||
|
|
14bdf82e33 | ||
|
|
6b85d501f0 | ||
|
|
473aceea68 | ||
|
|
0621dbc745 | ||
|
|
8ea0a4fc50 | ||
|
|
94ef818c9a | ||
|
|
8112b49c36 | ||
|
|
58b9c3a6d4 | ||
|
|
4373743d4c | ||
|
|
58159552ba | ||
|
|
4bff24f83a | ||
|
|
f644925570 | ||
|
|
8a4fd3f2af | ||
|
|
b7130a1ce3 | ||
|
|
519a44d224 | ||
|
|
936034e07a | ||
|
|
ea43939f52 | ||
|
|
d8befc612f | ||
|
|
06ec4ec148 | ||
|
|
6fbcb967a0 | ||
|
|
82e0241c42 | ||
|
|
8e000c2dbf | ||
|
|
1f1aafd5c2 | ||
|
|
d314298644 | ||
|
|
3cbe3abf67 | ||
|
|
90ab8b8dd3 | ||
|
|
cb1dd66220 | ||
|
|
d033a099ae | ||
|
|
78d9e5e181 | ||
|
|
41270ba8c9 | ||
|
|
e2277438e9 | ||
|
|
b0936c913b | ||
|
|
4b05eb62c9 | ||
|
|
fbacf0cb65 | ||
|
|
05a53a1582 | ||
|
|
be5873a057 | ||
|
|
c97f46bf28 | ||
|
|
1d47882eab | ||
|
|
9dcbbb4300 | ||
|
|
c9eda02fa1 | ||
|
|
a37584a404 | ||
|
|
566f217f6f | ||
|
|
ca34c79443 | ||
|
|
4be6c5b197 | ||
|
|
7194196100 | ||
|
|
d9d2eb978d | ||
|
|
c8460c51bd | ||
|
|
b4d0235a05 | ||
|
|
a5d1f78bf2 | ||
|
|
9a7750e339 | ||
|
|
d7c4ac7d02 | ||
|
|
1a08be066e | ||
|
|
fe86aa5f6b | ||
|
|
34133ec1e8 | ||
|
|
a99a75827c | ||
|
|
3bfcc12ec0 | ||
|
|
382341e1bf | ||
|
|
44b0d8b330 | ||
|
|
62808722d2 | ||
|
|
f09338c8de | ||
|
|
ec91b2de10 | ||
|
|
5cd289dc1d | ||
|
|
299caaa383 | ||
|
|
0aa2a4ef14 | ||
|
|
331f1ee722 | ||
|
|
0f351508bc | ||
|
|
304527ab01 | ||
|
|
b3d778469a | ||
|
|
6f5210afea | ||
|
|
6b1de35c01 | ||
|
|
8fccfc7a3d | ||
|
|
6fd3645713 | ||
|
|
8e86e6325b | ||
|
|
2b41e72196 | ||
|
|
1a64eeb88e | ||
|
|
2f8eac2c0a | ||
|
|
aaba777ad0 | ||
|
|
a580547f47 | ||
|
|
00ee7ffa6a | ||
|
|
f02b7d55b1 | ||
|
|
bed709a322 | ||
|
|
b362eeefdf | ||
|
|
7b02498963 | ||
|
|
6fd53f28f3 | ||
|
|
fefc8b5a82 | ||
|
|
4fe976549e | ||
|
|
044ff82d0b | ||
|
|
feac1e5fba | ||
|
|
dd5455fcd2 | ||
|
|
315971f02d | ||
|
|
a092986af3 | ||
|
|
6633f4e02f | ||
|
|
ee8970f23d | ||
|
|
46f1e4c414 | ||
|
|
a853e27765 | ||
|
|
68985d42bb | ||
|
|
9146a21738 | ||
|
|
8c2128703b | ||
|
|
b2d9cae0ec | ||
|
|
11eb66298d | ||
|
|
0f67e46549 | ||
|
|
45397534eb | ||
|
|
ffa93b87f8 | ||
|
|
0fe37d1828 | ||
|
|
43839898b3 | ||
|
|
6f2848c311 | ||
|
|
38c17c1f79 | ||
|
|
b85aa10700 | ||
|
|
598c7d9cf4 | ||
|
|
3e9d858af1 | ||
|
|
6fd29e6600 | ||
|
|
b67636747b | ||
|
|
ea464c9874 | ||
|
|
0e9c4a3964 | ||
|
|
1b15f89dfd | ||
|
|
7192ff672e | ||
|
|
7a99e03888 | ||
|
|
be7a391a13 | ||
|
|
23aec81f1a | ||
|
|
738d962aca | ||
|
|
93bc97b7ec | ||
|
|
243bb57a27 | ||
|
|
4916ebd05e | ||
|
|
8bbf48eb64 | ||
|
|
56920092b9 | ||
|
|
672ab4fc35 | ||
|
|
52616dee8e | ||
|
|
905f021bbd | ||
|
|
55016ada92 | ||
|
|
3bfaaab4f7 | ||
|
|
9e83eb6501 | ||
|
|
ef1905a665 | ||
|
|
c44badd26a | ||
|
|
66ebc660b4 | ||
|
|
06e5da456f | ||
|
|
689486eae5 | ||
|
|
48dc6ecfe3 | ||
|
|
b9bc7d9166 | ||
|
|
63ee135a1e | ||
|
|
ca2aa52ba9 | ||
|
|
96d28738c9 | ||
|
|
e4b05e55e1 | ||
|
|
4a4a579fd9 | ||
|
|
df716e5c9f | ||
|
|
52000177d9 | ||
|
|
7d6257cb1e | ||
|
|
db0234ecb4 | ||
|
|
438fad803e | ||
|
|
82f8f878bc | ||
|
|
b0818f9535 | ||
|
|
c71cb35e9d | ||
|
|
5bf5d25bc1 | ||
|
|
45d6b3ba51 | ||
|
|
e4e1b9ccbe | ||
|
|
d50df7db37 | ||
|
|
7257d1c15f | ||
|
|
ea65abc7e2 | ||
|
|
915090f118 | ||
|
|
629dcd3dcf | ||
|
|
169172a9e0 | ||
|
|
0a3fad4d47 | ||
|
|
b666a767e4 | ||
|
|
ee2dd1acc7 | ||
|
|
4f36583898 | ||
|
|
21d40fc038 | ||
|
|
93ff65c685 | ||
|
|
7e7201745d | ||
|
|
50a986605c | ||
|
|
96994568fd | ||
|
|
b494d94bdb | ||
|
|
9d6ccc0fe0 | ||
|
|
a56e187352 | ||
|
|
dcdcc659ef | ||
|
|
ae8e844dec | ||
|
|
e566ba54d9 | ||
|
|
70732afb95 | ||
|
|
f2aed69f87 | ||
|
|
6bd96522e8 | ||
|
|
1e26c352d6 | ||
|
|
2de65ebd4d | ||
|
|
ed3d9aaaed | ||
|
|
27a3998c8f | ||
|
|
979c124e57 | ||
|
|
20ad839075 | ||
|
|
bed67edd2e | ||
|
|
6efcc02806 | ||
|
|
8a6dd2805f | ||
|
|
464219c0fa | ||
|
|
e602768794 | ||
|
|
262f2a1453 | ||
|
|
b408967278 | ||
|
|
1fd97fed91 | ||
|
|
fef179b625 | ||
|
|
87ac411c50 | ||
|
|
46a7aaac76 | ||
|
|
e14d6fe9d5 | ||
|
|
fb5b2d3d8e | ||
|
|
9dccdd1008 | ||
|
|
8e8a746cce | ||
|
|
ee71effe98 | ||
|
|
ce2c4f0f08 | ||
|
|
ef9dbf73cc | ||
|
|
3bed5334bf | ||
|
|
5dc940ead2 | ||
|
|
7872b41f16 | ||
|
|
be81f6b4ab | ||
|
|
1229032b4e | ||
|
|
ad73e2d07b | ||
|
|
6d80135342 | ||
|
|
c36a10da83 | ||
|
|
c30d09cef4 | ||
|
|
716e0b97bd | ||
|
|
ff862dc926 | ||
|
|
17c2a1cb4e | ||
|
|
895e640fd0 | ||
|
|
e8f5f86ad5 | ||
|
|
5055b41ee7 | ||
|
|
7efd08ca2e | ||
|
|
76b421e064 | ||
|
|
063e6baa0a | ||
|
|
9e5d412a8b | ||
|
|
fa9b634d8f | ||
|
|
d76379428d | ||
|
|
46509b6dd2 | ||
|
|
89dbf9cc81 | ||
|
|
c138aaabf3 | ||
|
|
7cef454c86 | ||
|
|
5cb8d15505 | ||
|
|
2aab55983d | ||
|
|
31714e5c1d | ||
|
|
96c351e792 | ||
|
|
edd57004d3 | ||
|
|
234d20641c | ||
|
|
dd802f21e7 | ||
|
|
dbbc990c72 | ||
|
|
3a6e772cba | ||
|
|
c9fa16fcfa | ||
|
|
07b04fbea9 | ||
|
|
1c633cbea2 | ||
|
|
2f685d5d2a | ||
|
|
0fdf2cc195 | ||
|
|
4f7d18a28f | ||
|
|
c77272a7d7 | ||
|
|
7a1004df73 | ||
|
|
0e86d2b345 | ||
|
|
2441bdb900 | ||
|
|
57679b7b7f | ||
|
|
37063e7a05 | ||
|
|
791dc7b9be | ||
|
|
ff24dfb2e7 | ||
|
|
4db60fa5a8 | ||
|
|
5301367630 | ||
|
|
9409b7ef7d | ||
|
|
afeb7f668b | ||
|
|
38b8da0f5f | ||
|
|
d029b62d23 | ||
|
|
1e9bdb4647 | ||
|
|
1d72024605 | ||
|
|
06570443b7 | ||
|
|
77f7caf18d | ||
|
|
8767ffde2f | ||
|
|
d58b7fa779 | ||
|
|
dcbf3f8879 | ||
|
|
30d8c8e17c | ||
|
|
b803bb5edb | ||
|
|
985a39d41f | ||
|
|
f846eec894 | ||
|
|
e7fc8ad1f5 | ||
|
|
95169ad54b | ||
|
|
ddb2e91a42 | ||
|
|
90357193c9 | ||
|
|
a336fe2850 | ||
|
|
fcb8e4cf37 | ||
|
|
b7b6c147f9 | ||
|
|
35ee82ca07 | ||
|
|
2dc56a6e9b | ||
|
|
e12ef76de5 | ||
|
|
536b05e35b | ||
|
|
1354854d23 | ||
|
|
2b062d60f2 | ||
|
|
c8bdb4c7fb | ||
|
|
80328e8a4f | ||
|
|
1138e3770b | ||
|
|
ec58013b22 | ||
|
|
70cb61fb71 | ||
|
|
8e6a0ec23d | ||
|
|
e2ab334636 | ||
|
|
dd0effe957 | ||
|
|
ac210c1765 | ||
|
|
c58e48e648 | ||
|
|
acdadab617 | ||
|
|
aa19194f7b | ||
|
|
9319a6e39b | ||
|
|
b41206abab | ||
|
|
07c3dc6b6f | ||
|
|
fa71a2a993 | ||
|
|
b997d1e892 | ||
|
|
4b71fba540 | ||
|
|
48d39c0a57 | ||
|
|
0aad053507 | ||
|
|
6ed14b2a5f | ||
|
|
c7df5ef957 | ||
|
|
a9013febcf | ||
|
|
815c430ba1 | ||
|
|
e94d5bf006 | ||
|
|
a00480f4a1 | ||
|
|
6da952100c | ||
|
|
df8588e9b7 | ||
|
|
fce9b35e4d | ||
|
|
6fd4421add | ||
|
|
7149bfd100 | ||
|
|
344ad0355e | ||
|
|
e7871fbc43 | ||
|
|
99d8dd751e | ||
|
|
22b1abb36d | ||
|
|
aa289d1023 | ||
|
|
ef51e02767 | ||
|
|
7118127139 | ||
|
|
2ce2afa036 | ||
|
|
5803dd765d | ||
|
|
6a310b5069 | ||
|
|
2caab68be9 | ||
|
|
4e2dbc1258 | ||
|
|
40eca1a68e | ||
|
|
98f937ba15 | ||
|
|
a70988ecd5 | ||
|
|
6f2ff620bd | ||
|
|
bd772610b1 | ||
|
|
de42b5bfae | ||
|
|
fcdd5173bd | ||
|
|
c419799313 | ||
|
|
c5973a630b | ||
|
|
e5a88b64b1 | ||
|
|
74f58a49b9 | ||
|
|
cff9d9f5eb | ||
|
|
ddd64f2918 | ||
|
|
9f06f53a59 | ||
|
|
4c00d7a306 | ||
|
|
88726e12f7 | ||
|
|
248bb148af | ||
|
|
49589e1da1 | ||
|
|
552267b93d | ||
|
|
855357f871 | ||
|
|
c83cba2322 | ||
|
|
20dcc31d19 | ||
|
|
29e6cc5808 | ||
|
|
4e6ee28bcb | ||
|
|
4b3247576a | ||
|
|
69edf17c2a | ||
|
|
d91a4ad1dd | ||
|
|
9b750ef69f | ||
|
|
0bf22ee3ce | ||
|
|
981ed22dff | ||
|
|
d40321ef63 | ||
|
|
c94996e8e8 | ||
|
|
4b19dd46dd | ||
|
|
942e841cbc | ||
|
|
e0a595273a | ||
|
|
92ca52822c | ||
|
|
f89dbce93c | ||
|
|
28f0e2eb2a | ||
|
|
47ac080565 | ||
|
|
afdf5cfde9 | ||
|
|
a4760bcff7 | ||
|
|
72e571a3de | ||
|
|
484c0fdd15 | ||
|
|
2636fb7c8d | ||
|
|
99c2936e90 | ||
|
|
66c74d6091 | ||
|
|
a43ba245e2 | ||
|
|
810d734eda | ||
|
|
687d6c5dc4 | ||
|
|
5e090c1fac | ||
|
|
ceb61e6600 | ||
|
|
ae60293c24 | ||
|
|
e411081c84 | ||
|
|
0682a5e45e | ||
|
|
4f751aa53d | ||
|
|
27fa51cfa6 | ||
|
|
2772ff624f | ||
|
|
69b160cfe8 | ||
|
|
ee7541c032 | ||
|
|
abf6068d91 | ||
|
|
9d5f3e787d | ||
|
|
ab2b9ba444 | ||
|
|
6ab1aff531 | ||
|
|
6012276093 | ||
|
|
9648cf226b | ||
|
|
56532a505d | ||
|
|
6bb2e5625a | ||
|
|
d57a5dffa1 | ||
|
|
1028ca0841 | ||
|
|
6dbe6b42c2 | ||
|
|
7611c3ea03 | ||
|
|
2fa9f934b6 | ||
|
|
e9fd7b7ed6 | ||
|
|
075e954b71 | ||
|
|
3f7122b3d2 | ||
|
|
35251c6d9c | ||
|
|
173594365c | ||
|
|
2fc44fb27d | ||
|
|
0264630c90 | ||
|
|
208769f70f | ||
|
|
c5bffb9fb5 | ||
|
|
c7afa5452b | ||
|
|
c7c6e83779 | ||
|
|
fcb6adaaaa | ||
|
|
9c12b58e32 | ||
|
|
6c8b505f93 | ||
|
|
8b228e7471 | ||
|
|
4ce07f41ca | ||
|
|
1bfd0e5e38 | ||
|
|
b962d37f79 | ||
|
|
c6ecf02a07 | ||
|
|
8b7d4b423c | ||
|
|
83dc126565 | ||
|
|
f2d3d7e710 | ||
|
|
f991428cb9 | ||
|
|
e2b4108377 | ||
|
|
c9cf7b1e08 | ||
|
|
4d865cd7ba | ||
|
|
a55458a84a | ||
|
|
66d8631c23 | ||
|
|
5c1ad88137 | ||
|
|
e230c9c6f0 | ||
|
|
6d24a2c942 | ||
|
|
5222dc0cd1 | ||
|
|
02c484e844 | ||
|
|
5face79cd0 | ||
|
|
51a72a9c53 | ||
|
|
f609d9cd59 | ||
|
|
3901c6ab91 | ||
|
|
da6f86bd79 | ||
|
|
42fd499af4 | ||
|
|
de5b88477a | ||
|
|
cd49a7f9e9 | ||
|
|
df025fcb88 | ||
|
|
bbb1404bd3 | ||
|
|
af2a172197 | ||
|
|
252b9fc39c | ||
|
|
6fc5e04d7c | ||
|
|
66f1fef083 | ||
|
|
645d4807c3 | ||
|
|
e2c360ada0 | ||
|
|
a463ead739 | ||
|
|
dbe5e57b8e | ||
|
|
99b99d7b23 | ||
|
|
787111a145 | ||
|
|
9a872f059f | ||
|
|
eadc94e0a1 | ||
|
|
f8855e892a | ||
|
|
27d05014e3 | ||
|
|
ebb58b7cbc | ||
|
|
7f6895a4bb | ||
|
|
80ae4c1a69 | ||
|
|
e72df9cd5f | ||
|
|
80ba529fb9 | ||
|
|
fd6b3ef5a0 | ||
|
|
4cd0a39794 | ||
|
|
5fbc510f94 | ||
|
|
600ab5ba5f | ||
|
|
ae92181d02 | ||
|
|
66910ed998 | ||
|
|
5371e4403e | ||
|
|
79375dd7dd | ||
|
|
6889609ab9 | ||
|
|
0bf87281e0 | ||
|
|
bc7bed7517 | ||
|
|
cfac6fd752 | ||
|
|
97c09c827b | ||
|
|
0370672886 | ||
|
|
2d062fedd9 | ||
|
|
c6a68f3de2 | ||
|
|
d6181b2335 | ||
|
|
d74e62886c | ||
|
|
d8505f09eb | ||
|
|
935c6aade0 | ||
|
|
a35c35f849 | ||
|
|
57518a2bb4 | ||
|
|
99a8202015 | ||
|
|
17c903e246 | ||
|
|
4de5d225db | ||
|
|
7741df9963 | ||
|
|
7ef54e9c53 | ||
|
|
12bb700c62 | ||
|
|
e3ba7250f1 | ||
|
|
54842095c3 | ||
|
|
d1aec0c3f1 | ||
|
|
00d5f72d6e | ||
|
|
15d01d4315 | ||
|
|
348e34f221 | ||
|
|
ce7b0656c0 | ||
|
|
fd0d360f9b | ||
|
|
f26cae3838 | ||
|
|
b8468af411 | ||
|
|
9fd7e319f3 | ||
|
|
80a8b59f24 | ||
|
|
b9d4da9cfe | ||
|
|
5bf5b58eb3 | ||
|
|
b2c227e9c5 | ||
|
|
d854228d58 | ||
|
|
a0c09bc2a9 | ||
|
|
aca3b2da58 | ||
|
|
604541863c | ||
|
|
fd9e0dd13a | ||
|
|
da535164b4 | ||
|
|
82d9570ed4 | ||
|
|
a619e8af4a | ||
|
|
25ec20d861 | ||
|
|
0579220546 | ||
|
|
031c37c7b0 | ||
|
|
860821114a | ||
|
|
73bba62d82 | ||
|
|
42249ce28e |
@@ -25,7 +25,7 @@ variables:
|
||||
BACKEND_FLAGS: "-Dx11-backend=true -Dwayland-backend=true -Dbroadway-backend=true"
|
||||
FEATURE_FLAGS: "-Dvulkan=enabled -Dcloudproviders=enabled"
|
||||
MESON_TEST_TIMEOUT_MULTIPLIER: 3
|
||||
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v35"
|
||||
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v36"
|
||||
FLATPAK_IMAGE: "registry.gitlab.gnome.org/gnome/gnome-runtime-images/gnome:master"
|
||||
|
||||
.only-default:
|
||||
@@ -88,7 +88,7 @@ fedora-x86_64:
|
||||
- meson compile -C _build
|
||||
- meson install -C _build
|
||||
- PKG_CONFIG_PATH=${CI_PROJECT_DIR}/_install/lib64/pkgconfig:${CI_PROJECT_DIR}/_install/share/pkgconfig meson setup _build_hello examples/hello
|
||||
- meson compile -C _build_hello
|
||||
- LD_LIBRARY_PATH=${CI_PROJECT_DIR}/_install/lib64 meson compile -C _build_hello
|
||||
- .gitlab-ci/run-tests.sh _build x11
|
||||
- .gitlab-ci/run-tests.sh _build wayland
|
||||
- .gitlab-ci/run-tests.sh _build waylandgles
|
||||
@@ -156,6 +156,11 @@ msys2-mingw64:
|
||||
variables:
|
||||
MSYSTEM: "MINGW64"
|
||||
CHERE_INVOKING: "yes"
|
||||
artifacts:
|
||||
when: always
|
||||
expose_as: 'Windows_DLL_MSYS2_64_bit_toolchain'
|
||||
paths:
|
||||
- "${CI_PROJECT_DIR}/_build/gtkdll.tar.gz"
|
||||
|
||||
macos:
|
||||
extends: .only-default
|
||||
@@ -167,7 +172,7 @@ macos:
|
||||
needs: []
|
||||
before_script:
|
||||
- bash .gitlab-ci/show-info-osx.sh
|
||||
- pip3 install --user meson==0.56
|
||||
- pip3 install --user meson==0.59
|
||||
- pip3 install --user ninja
|
||||
- export PATH=/Users/gitlabrunner/Library/Python/3.7/bin:$PATH
|
||||
- export MESON_FORCE_BACKTRACE=1
|
||||
|
||||
@@ -95,6 +95,8 @@ RUN dnf -y install \
|
||||
weston-libs \
|
||||
which \
|
||||
xorg-x11-server-Xvfb \
|
||||
&& dnf install -y 'dnf-command(builddep)' \
|
||||
&& dnf builddep -y wayland \
|
||||
&& dnf clean all
|
||||
|
||||
# Enable sudo for wheel users
|
||||
|
||||
@@ -5,8 +5,8 @@ call "C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliar
|
||||
@echo on
|
||||
|
||||
:: FIXME: make warnings fatal
|
||||
pip3 install --upgrade --user meson==0.56.2 || goto :error
|
||||
meson -Dmedia-gstreamer=disabled _build || goto :error
|
||||
pip3 install --upgrade --user meson==0.59 || goto :error
|
||||
meson -Ddebug=false -Dmedia-gstreamer=disabled _build || goto :error
|
||||
ninja -C _build || goto :error
|
||||
|
||||
goto :EOF
|
||||
|
||||
@@ -15,9 +15,9 @@ pacman --noconfirm -Suy
|
||||
pacman --noconfirm -S --needed \
|
||||
base-devel \
|
||||
git \
|
||||
mingw-w64-$MSYS2_ARCH-toolchain \
|
||||
mingw-w64-$MSYS2_ARCH-cc \
|
||||
mingw-w64-$MSYS2_ARCH-ccache \
|
||||
mingw-w64-$MSYS2_ARCH-pkg-config \
|
||||
mingw-w64-$MSYS2_ARCH-pkgconf \
|
||||
mingw-w64-$MSYS2_ARCH-gobject-introspection \
|
||||
mingw-w64-$MSYS2_ARCH-meson \
|
||||
mingw-w64-$MSYS2_ARCH-adwaita-icon-theme \
|
||||
@@ -30,8 +30,9 @@ pacman --noconfirm -S --needed \
|
||||
mingw-w64-$MSYS2_ARCH-libepoxy \
|
||||
mingw-w64-$MSYS2_ARCH-pango \
|
||||
mingw-w64-$MSYS2_ARCH-fribidi \
|
||||
mingw-w64-$MSYS2_ARCH-gst-plugins-bad \
|
||||
mingw-w64-$MSYS2_ARCH-shared-mime-info
|
||||
mingw-w64-$MSYS2_ARCH-gst-plugins-bad-libs \
|
||||
mingw-w64-$MSYS2_ARCH-shared-mime-info \
|
||||
mingw-w64-$MSYS2_ARCH-python-gobject
|
||||
|
||||
mkdir -p _ccache
|
||||
export CCACHE_BASEDIR="$(pwd)"
|
||||
@@ -72,3 +73,5 @@ unset CCACHE_DISABLE
|
||||
|
||||
ninja -C _build
|
||||
ccache --show-stats
|
||||
|
||||
tar zcf _build/gtkdll.tar.gz _build/gtk/libgtk*.dll
|
||||
|
||||
502
NEWS
502
NEWS
@@ -1,8 +1,506 @@
|
||||
Overview of Changes
|
||||
===================
|
||||
Overview of Changes in 4.6.8, 24-10-2022
|
||||
========================================
|
||||
|
||||
* Input:
|
||||
- Fix problems with input method interactions that caused
|
||||
dead keys not to work
|
||||
|
||||
* GtkText:
|
||||
- Respect the no-emoji input hint fully
|
||||
|
||||
* GtkNotebook:
|
||||
- Fix an infinite loop in accessibility code
|
||||
- Event handling fixes
|
||||
|
||||
* GtkFileChooser:
|
||||
- Restore ~ and .functionality
|
||||
|
||||
* GtkTreeView:
|
||||
- Event handling fixes
|
||||
|
||||
* GtkTreeListModel:
|
||||
- Prevent possible crashes with collapsed nodes
|
||||
|
||||
* GtkGridView:
|
||||
- Fix issues with rubberband selection
|
||||
|
||||
* GtkEmojiChooser:
|
||||
- Fix navigation with arrow keys when filtered
|
||||
|
||||
* GtkPopover:
|
||||
- Fix problems with focus when dismissing popovers
|
||||
- Fix problems with focusing editable labels in popovers
|
||||
|
||||
* GtkStackSidebar:
|
||||
- Improve accessible presentation
|
||||
|
||||
* Wayland:
|
||||
- Make gtk_launch_uri more robust
|
||||
- Make monitor bounds handling more robust
|
||||
- Prevent shrinking clients due to wrong toplevel bounds
|
||||
|
||||
* Flatpak:
|
||||
- Fix file DND with the FileTransfer portal
|
||||
|
||||
* Translation updates
|
||||
Brazilian Portuguese
|
||||
Croatian
|
||||
Czech
|
||||
Georgian
|
||||
German
|
||||
Hungarian
|
||||
Icelandic
|
||||
Lithuanian
|
||||
Polish
|
||||
Portuguese
|
||||
Serbian
|
||||
Slovenian
|
||||
Swedish
|
||||
Turkish
|
||||
|
||||
|
||||
Overview of Changes in 4.6.7, 17-08-2022
|
||||
========================================
|
||||
|
||||
* Miscellaneous memory leak fixes
|
||||
|
||||
* GtkTreeView:
|
||||
- Fix a problem with DND
|
||||
- Fix a problem with row selection
|
||||
|
||||
* GtkTreePopover:
|
||||
- Support scrolling
|
||||
|
||||
* GtkGridView:
|
||||
- Fix issues with rubberband selection
|
||||
|
||||
* GtkSnapshot:
|
||||
- Make GtkSnapshot work from bindings
|
||||
|
||||
* X11:
|
||||
- Fix preferred action for DND
|
||||
|
||||
* Windows:
|
||||
- Fix DND
|
||||
|
||||
* Translation updates
|
||||
Croatian
|
||||
Georgian
|
||||
Indonesian
|
||||
Russian
|
||||
Serbian
|
||||
Spanish
|
||||
|
||||
|
||||
Overview of Changes in 4.6.6, 02-07-2022
|
||||
========================================
|
||||
|
||||
* Fix translations in GTKs own ui files
|
||||
|
||||
* Wayland:
|
||||
- Fix a problem with the activation protocol
|
||||
- Don't force the HighContrast icontheme
|
||||
|
||||
* Windows:
|
||||
- Fix a problem with builtin icons if the
|
||||
hicolor icontheme is not installed
|
||||
|
||||
* Translation updates:
|
||||
Brazilian Portuguese
|
||||
Russian
|
||||
Turkish
|
||||
|
||||
|
||||
Overview of Changes in 4.6.5, 27-05-2022
|
||||
========================================
|
||||
|
||||
* GtkFileChooser:
|
||||
- Fix pasting text into the name field
|
||||
|
||||
* GtkText:
|
||||
- Remove an assertion that is sometimes hit
|
||||
|
||||
* Wayland:
|
||||
- Ensure that our cursor surfaces don't violate
|
||||
protocol constraints
|
||||
|
||||
* Accssibility:
|
||||
- Fix a problem in the accessibility tree
|
||||
|
||||
* Translation updates:
|
||||
Brazilian Portuguese
|
||||
German
|
||||
Persian
|
||||
Polish
|
||||
Portuguese
|
||||
Russian
|
||||
Swedish
|
||||
Turkish
|
||||
Ukrainian
|
||||
|
||||
|
||||
Overview of Changes in 4.6.4, 13-05-2022
|
||||
========================================
|
||||
|
||||
* GtkFileChooser:
|
||||
- Fix select button sensitivity in select_folder mode
|
||||
- Fix some fallout from list model porting
|
||||
|
||||
* GtkListView, GtkColumnView:
|
||||
- Optimize scrolling
|
||||
|
||||
* print-to-file:
|
||||
- Handle nonexisting files better in the dialog
|
||||
|
||||
* Avoid infinite loops in size allocation
|
||||
|
||||
* CSS:
|
||||
- Optimize a case of reparenting that is important in GtkListView
|
||||
|
||||
* GSK:
|
||||
- Check for half-float support before using it
|
||||
|
||||
* Wayland:
|
||||
- Ignore empty preedit updates This fixes a problem with
|
||||
textview scrolling
|
||||
- Freeze popups when hidden. This addresses a frame rate drop
|
||||
|
||||
* Translation updates
|
||||
Hebrew
|
||||
Nepali
|
||||
|
||||
|
||||
Overview of Changes in 4.6.3, 21-04-2022
|
||||
========================================
|
||||
|
||||
* GtkOverlay:
|
||||
- Bring back positional style classes
|
||||
|
||||
* GtkFileChooser:
|
||||
- Prevent unwanted completion popups
|
||||
- Fix small problems in save mode
|
||||
- Fix buildable suport of GtkFileFilter
|
||||
|
||||
* GtkPopover:
|
||||
- Fix button positions in right-to-left locales
|
||||
|
||||
* GtkLabel:
|
||||
- Fix small issues with link handling
|
||||
|
||||
* Tooltips:
|
||||
- Don't restrict the minimum tooltip length
|
||||
|
||||
* Theme:
|
||||
- Don't use opacity for overlay scrollbars
|
||||
- Fix selection text color in vertical spin buttons
|
||||
|
||||
* GSK:
|
||||
- Accept textures that are generated by webkit
|
||||
- Align offscreen rendering to the pixel grid
|
||||
|
||||
* Accessibility
|
||||
- Fix a crash in startup when orca is running
|
||||
|
||||
* Input:
|
||||
- Fix display changes in GtkIMMultiContext
|
||||
- Fix activating on-screen keyboards
|
||||
- Always propagate hold events in GtkEventControllerScroll
|
||||
|
||||
* Windows:
|
||||
- Fix a critical warning in clipboard handling
|
||||
- Report serial numbers for events
|
||||
|
||||
* MacOS:
|
||||
- Prevent fullscreen transition reentrancy
|
||||
|
||||
|
||||
* Translation updates
|
||||
British English
|
||||
Czech
|
||||
German
|
||||
Indonesian
|
||||
Latvian
|
||||
|
||||
|
||||
Overview of Changes in 4.6.2, 18-03-2022
|
||||
========================================
|
||||
|
||||
* GtkScrolledWindow:
|
||||
- Set scroll-to-focus on viewports
|
||||
- Avoid doubly triggering deceleration
|
||||
|
||||
* GtkEntry:
|
||||
- Stop cursor blinking on focus-out
|
||||
|
||||
* Emoji:
|
||||
- Update Emoji data to CLDR 40 and Unicode 14
|
||||
- Add more locales for Emoji data (da, de, en, es,
|
||||
fr hu, it, ko, lt, ms, nl, pl, pt, ru, s, uk zh)
|
||||
|
||||
* GDK
|
||||
- Optimize texture conversions on x86 and ARM
|
||||
- Use EGK_KHR_swap_buffers_with_damage if available
|
||||
|
||||
* GSK
|
||||
- Avoid clearing opaque regions
|
||||
- Support using a non-default framebuffer
|
||||
- Handle large viewports by tiling
|
||||
|
||||
* Wayland:
|
||||
- Prefer xdg-activation over gtk-shell
|
||||
- text protocol: Fix text caret location
|
||||
- text protocol: Use serials to control outbound messages
|
||||
|
||||
* Inspector:
|
||||
- Show app ID and resource path
|
||||
|
||||
* Demos:
|
||||
- widget-factory: Handle F11 to toggle fullscreen
|
||||
|
||||
* Tools:
|
||||
- gtk-builder-tool: Allow use without display
|
||||
|
||||
* Windows:
|
||||
- Fix preedit window placement on HiDPI
|
||||
- Build improvements
|
||||
- Fix fullscreen handling
|
||||
|
||||
* MacOS:
|
||||
- Fix scrolling with an external mouse
|
||||
- Fix kinetic scrolling with overshoot
|
||||
- Improve monitor detection
|
||||
- Many input handling fixes
|
||||
- Support OpenGL accelerated video playback
|
||||
- Support fullscreen
|
||||
- Improve interactive window resizing and moving
|
||||
- Fix backdrop state handling
|
||||
- Fix GtkFileChooserNative filtering
|
||||
- Use CALayer and IOSurface for rendering
|
||||
- Use per monitor CVDisplayLink to support mixed-rate monitors
|
||||
- Start applications in foreground
|
||||
- Fix cursor blink time
|
||||
|
||||
* Translation updates
|
||||
Basque
|
||||
Brazilian Portuguese
|
||||
Catalan
|
||||
Chinese (China)
|
||||
Croatian
|
||||
Czech
|
||||
Danish
|
||||
Finnish
|
||||
Galician
|
||||
German
|
||||
Hebrew
|
||||
Hungarian
|
||||
Italian
|
||||
Kazakh
|
||||
Korean
|
||||
Lithuanian
|
||||
Norwegian Bokmål
|
||||
Persian
|
||||
Poliah
|
||||
Portuguese
|
||||
Russian
|
||||
Slovak
|
||||
Slovenian
|
||||
Spanish
|
||||
Swedish
|
||||
Turkish
|
||||
Ukrainian
|
||||
|
||||
|
||||
Overview of Changes in 4.6.1, 11-02-2022
|
||||
========================================
|
||||
|
||||
* GtkFontChooser:
|
||||
- Stop using PangoFc api
|
||||
- Fix a crash
|
||||
- Use new HarfBuzz api
|
||||
|
||||
* GtkMenuButton:
|
||||
- Update accessible description
|
||||
|
||||
* GtkTextView:
|
||||
- Fix intra-widget dnd
|
||||
|
||||
* Printing:
|
||||
- Fix an fd leak
|
||||
|
||||
* Input:
|
||||
- Make sure input methods get focus-in events
|
||||
- Always flush events to avoid scroll event pileup
|
||||
- Support hold events
|
||||
- Update keysyms from libxkbcommon
|
||||
|
||||
* Theme:
|
||||
- Improve text selection legibility
|
||||
|
||||
* Introspection:
|
||||
- Add missing nullable annotations everywhere
|
||||
|
||||
* Build:
|
||||
- Make stack noexec again
|
||||
- Avoid symbol leaks
|
||||
- Drop unneeded script data
|
||||
|
||||
* Windows:
|
||||
- Stop using WM_SYNCPAINT
|
||||
- Relax check for GL 3.x legacy contexts
|
||||
- Use native apis for language names
|
||||
- Rewrite the keymap code
|
||||
- Use the GL renderer by default
|
||||
|
||||
* Wayland:
|
||||
- Fix support for the new high-contrast setting
|
||||
- Avoid redundant scale changes
|
||||
- Fix DND hotspot handling
|
||||
- Don't always restore the saved size when floating
|
||||
|
||||
* MacOS:
|
||||
- Various performance improvements
|
||||
|
||||
* Translation updates:
|
||||
Brazilian Portuguese
|
||||
Catalan
|
||||
Chinese (China)
|
||||
Galician
|
||||
Hebrew
|
||||
Japanese
|
||||
Lithuanian
|
||||
Persian
|
||||
Polish
|
||||
Portuguese
|
||||
Russian
|
||||
Slovenian
|
||||
Spanish
|
||||
Ukrainian
|
||||
|
||||
|
||||
Overview of Changes in 4.6.0, 30-12-2021
|
||||
========================================
|
||||
|
||||
* GtkProgressBar:
|
||||
- Fix handling of "inverted"
|
||||
|
||||
* GtkLabel:
|
||||
- Add a "natural wrap mode" property to influence how
|
||||
natural width is determined
|
||||
|
||||
* GtkTextView
|
||||
- Scroll insertion on-screen after undo / redo
|
||||
|
||||
* gsk:
|
||||
- Abort region diffing when changes are too complex
|
||||
|
||||
* gdk:
|
||||
- Avoid compressing discrete scroll events
|
||||
- Fix problems with hiding windows
|
||||
- Improve GL and GLES version checks
|
||||
|
||||
* Wayland:
|
||||
- Support new high-contrast setting
|
||||
|
||||
* Inspector:
|
||||
- Add DND inspection support
|
||||
|
||||
* build:
|
||||
- Avoid deprecated meson apis
|
||||
|
||||
* Translation updates
|
||||
Galician
|
||||
Portuguese
|
||||
Ukrainian
|
||||
|
||||
|
||||
Overview of Changes in 4.5.1, 16-12-2021
|
||||
========================================
|
||||
|
||||
* GtkWidget sizing has been rewritten to implement
|
||||
width-for-height more properly. This had some fallout,
|
||||
and some widgets may still not react kindly to the
|
||||
new way of doing things.
|
||||
|
||||
See https://blog.gtk.org/2021/12/03/sizable-news/
|
||||
for details, and please file issues if you notice fallout.
|
||||
|
||||
* Rename git `master` branch to `main`
|
||||
|
||||
* Css:
|
||||
- Fully support font-variant-caps
|
||||
- Fix a crash with gradients
|
||||
|
||||
* Make various widgets activatable:
|
||||
- GtkComboBox
|
||||
- GtkDropDown
|
||||
|
||||
* GtkPopover:
|
||||
- Make focus indicators not disappear
|
||||
|
||||
* GtkTextView:
|
||||
- Don't leave embedded children stranded when scrolling
|
||||
- Don't insert Emoji into non-editable textviews
|
||||
- Fix Emoji chooser positioning
|
||||
- Fix problems with pasting text
|
||||
- Improve scroll-to-mark behavior
|
||||
- Support right-aligned, centered and decimal tabs
|
||||
- Make child anchor replacement character settable
|
||||
- Provide more context to input methods
|
||||
|
||||
* GtkDragIcon:
|
||||
- Provide default icons for paintables and files
|
||||
|
||||
* GtkBuilder:
|
||||
- Speed up template precompilation
|
||||
|
||||
* Actions:
|
||||
- Reduce allocations during signal emissions
|
||||
- Avoid duplication and unnecessary recursion
|
||||
|
||||
* Inspector:
|
||||
- Show the selected im-module in the General tab
|
||||
- Add a clipboard viewer
|
||||
- Make the recorder record events too
|
||||
- Add a graph visualizing gtk_widget_measure()
|
||||
|
||||
* Gsk:
|
||||
- Fix hexbox rendering
|
||||
- Fix transformed linear gradient rendering
|
||||
|
||||
* Printing:
|
||||
- Fix dialog-less printing
|
||||
|
||||
* Windows:
|
||||
- Use the common EGL setup code
|
||||
- Respect GDK_DEBUG=gl-egl
|
||||
- Fix AeroSnap indicator and positioning
|
||||
|
||||
* X11:
|
||||
- Improve behavior of windows drags on headerbar controls
|
||||
- Trap errors for RANDR changes
|
||||
- Fix problems with drag icons
|
||||
|
||||
* Wayland:
|
||||
- Ensure we prefer the Wayland im-module over others
|
||||
|
||||
* Translation updates
|
||||
Basque
|
||||
Catalan
|
||||
Croatian
|
||||
Friulian
|
||||
Galician
|
||||
Hebrew
|
||||
Icelandic
|
||||
Italian
|
||||
Latvian
|
||||
Lithuanian
|
||||
Occitan
|
||||
Persian
|
||||
Portuguese
|
||||
Spanish
|
||||
Swedish
|
||||
Ukrainian
|
||||
|
||||
Overview of Changes in 4.5.0
|
||||
============================
|
||||
|
||||
|
||||
@@ -43,7 +43,8 @@
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "git",
|
||||
"url" : "https://gitlab.freedesktop.org/wayland/wayland.git"
|
||||
"url" : "https://gitlab.freedesktop.org/wayland/wayland.git",
|
||||
"branch" : "main"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -43,7 +43,8 @@
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "git",
|
||||
"url" : "https://gitlab.freedesktop.org/wayland/wayland.git"
|
||||
"url" : "https://gitlab.freedesktop.org/wayland/wayland.git",
|
||||
"branch" : "main"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -43,7 +43,8 @@
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "git",
|
||||
"url" : "https://gitlab.freedesktop.org/wayland/wayland.git"
|
||||
"url" : "https://gitlab.freedesktop.org/wayland/wayland.git",
|
||||
"branch" : "main"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -13,7 +13,7 @@ if 'DESTDIR' not in os.environ:
|
||||
|
||||
gtk_moduledir = os.path.join(gtk_libdir, 'gtk-' + gtk_api_version, gtk_abi_version)
|
||||
gtk_printmodule_dir = os.path.join(gtk_moduledir, 'printbackends')
|
||||
gtk_immodule_dir = os.path.join(gtk_moduledir, 'immodules')
|
||||
gtk_mediamodule_dir = os.path.join(gtk_moduledir, 'media')
|
||||
|
||||
print('Compiling GSettings schemas...')
|
||||
glib_compile_schemas = subprocess.check_output(['pkg-config',
|
||||
@@ -40,6 +40,6 @@ if 'DESTDIR' not in os.environ:
|
||||
gio_querymodules = 'gio-querymodules'
|
||||
subprocess.call([gio_querymodules, gtk_printmodule_dir])
|
||||
|
||||
print('Updating module cache for input methods...')
|
||||
os.makedirs(gtk_immodule_dir, exist_ok=True)
|
||||
subprocess.call([gio_querymodules, gtk_immodule_dir])
|
||||
print('Updating module cache for media backends...')
|
||||
os.makedirs(gtk_mediamodule_dir, exist_ok=True)
|
||||
subprocess.call([gio_querymodules, gtk_mediamodule_dir])
|
||||
|
||||
@@ -17,7 +17,7 @@ executable('gtk4-constraint-editor',
|
||||
c_args: common_cflags,
|
||||
dependencies: libgtk_dep,
|
||||
include_directories: confinc,
|
||||
gui_app: true,
|
||||
win_subsystem: 'windows',
|
||||
link_args: extra_demo_ldflags,
|
||||
install: false,
|
||||
)
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
/* Clipboard
|
||||
*
|
||||
* GdkClipboard is used for clipboard handling. This demo shows how to
|
||||
* copy and paste text to and from the clipboard.
|
||||
* copy and paste text, images, colors or files to and from the clipboard.
|
||||
*
|
||||
* It also shows how to transfer images via the clipboard or via
|
||||
* drag-and-drop, and how to make clipboard contents persist after
|
||||
* the application exits. Clipboard persistence requires a clipboard
|
||||
* manager to run.
|
||||
* You can also use Drag-And-Drop to copy the data from the source to the
|
||||
* target.
|
||||
*/
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
@@ -14,22 +12,103 @@
|
||||
#include <string.h>
|
||||
#include "demoimage.h"
|
||||
|
||||
static GtkWidget *window = NULL;
|
||||
static void
|
||||
copy_button_clicked (GtkStack *source_stack,
|
||||
gpointer user_data)
|
||||
{
|
||||
GdkClipboard *clipboard;
|
||||
const char *visible_child_name;
|
||||
GtkWidget *visible_child;
|
||||
|
||||
clipboard = gtk_widget_get_clipboard (GTK_WIDGET (source_stack));
|
||||
|
||||
visible_child = gtk_stack_get_visible_child (source_stack);
|
||||
visible_child_name = gtk_stack_get_visible_child_name (source_stack);
|
||||
|
||||
if (strcmp (visible_child_name, "Text") == 0)
|
||||
{
|
||||
gdk_clipboard_set_text (clipboard, gtk_editable_get_text (GTK_EDITABLE (visible_child)));
|
||||
}
|
||||
else if (strcmp (visible_child_name, "Image") == 0)
|
||||
{
|
||||
GtkWidget *child;
|
||||
|
||||
for (child = gtk_widget_get_first_child (visible_child); child; child = gtk_widget_get_next_sibling (child))
|
||||
{
|
||||
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (child)))
|
||||
{
|
||||
GtkWidget *image = gtk_widget_get_first_child (child);
|
||||
GdkPaintable *paintable = gtk_image_get_paintable (GTK_IMAGE (image));
|
||||
|
||||
if (GDK_IS_TEXTURE (paintable))
|
||||
gdk_clipboard_set (clipboard, GDK_TYPE_TEXTURE, paintable);
|
||||
else
|
||||
gdk_clipboard_set (clipboard, GDK_TYPE_PAINTABLE, paintable);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (strcmp (visible_child_name, "Color") == 0)
|
||||
{
|
||||
GdkRGBA color;
|
||||
|
||||
gtk_color_chooser_get_rgba (GTK_COLOR_CHOOSER (visible_child), &color);
|
||||
gdk_clipboard_set (clipboard, GDK_TYPE_RGBA, &color);
|
||||
}
|
||||
else if (strcmp (visible_child_name, "File") == 0)
|
||||
{
|
||||
gdk_clipboard_set (clipboard, G_TYPE_FILE, g_object_get_data (G_OBJECT (visible_child), "file"), NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_print ("TODO");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
copy_button_clicked (GtkWidget *button,
|
||||
gpointer user_data)
|
||||
present_value (GtkStack *dest_stack,
|
||||
const GValue *value)
|
||||
{
|
||||
GtkWidget *entry;
|
||||
GdkClipboard *clipboard;
|
||||
GtkWidget *child;
|
||||
|
||||
entry = GTK_WIDGET (user_data);
|
||||
if (G_VALUE_HOLDS (value, G_TYPE_FILE))
|
||||
{
|
||||
GFile *file;
|
||||
|
||||
/* Get the clipboard object */
|
||||
clipboard = gtk_widget_get_clipboard (entry);
|
||||
gtk_stack_set_visible_child_name (dest_stack, "File");
|
||||
child = gtk_stack_get_visible_child (dest_stack);
|
||||
|
||||
/* Set clipboard text */
|
||||
gdk_clipboard_set_text (clipboard, gtk_editable_get_text (GTK_EDITABLE (entry)));
|
||||
file = g_value_get_object (value);
|
||||
g_object_set (child, "label", g_file_peek_path (file), NULL);
|
||||
}
|
||||
else if (G_VALUE_HOLDS (value, GDK_TYPE_RGBA))
|
||||
{
|
||||
GdkRGBA *color;
|
||||
|
||||
gtk_stack_set_visible_child_name (dest_stack, "Color");
|
||||
child = gtk_widget_get_first_child (gtk_stack_get_visible_child (dest_stack));
|
||||
|
||||
color = g_value_get_boxed (value);
|
||||
g_object_set (child, "rgba", color, NULL);
|
||||
}
|
||||
else if (G_VALUE_HOLDS (value, GDK_TYPE_TEXTURE) ||
|
||||
G_VALUE_HOLDS (value, GDK_TYPE_PAINTABLE))
|
||||
{
|
||||
GdkPaintable *paintable;
|
||||
|
||||
gtk_stack_set_visible_child_name (dest_stack, "Image");
|
||||
child = gtk_stack_get_visible_child (dest_stack);
|
||||
|
||||
paintable = g_value_get_object (value);
|
||||
g_object_set (child, "paintable", paintable, NULL);
|
||||
}
|
||||
else if (G_VALUE_HOLDS (value, G_TYPE_STRING))
|
||||
{
|
||||
gtk_stack_set_visible_child_name (dest_stack, "Text");
|
||||
child = gtk_stack_get_visible_child (dest_stack);
|
||||
|
||||
gtk_label_set_label (GTK_LABEL (child), g_value_get_string (value));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -37,149 +116,259 @@ paste_received (GObject *source_object,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkStack *dest_stack = user_data;
|
||||
GdkClipboard *clipboard;
|
||||
GtkWidget *entry;
|
||||
char *text;
|
||||
const GValue *value;
|
||||
GError *error = NULL;
|
||||
|
||||
clipboard = GDK_CLIPBOARD (source_object);
|
||||
entry = GTK_WIDGET (user_data);
|
||||
|
||||
/* Get the resulting text of the read operation */
|
||||
text = gdk_clipboard_read_text_finish (clipboard, result, &error);
|
||||
|
||||
if (text)
|
||||
value = gdk_clipboard_read_value_finish (clipboard, result, &error);
|
||||
if (value)
|
||||
{
|
||||
/* Set the entry text */
|
||||
gtk_editable_set_text (GTK_EDITABLE (entry), text);
|
||||
g_free (text);
|
||||
present_value (dest_stack, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
GtkWidget *dialog;
|
||||
|
||||
/* Show an error about why pasting failed.
|
||||
* Usually you probably want to ignore such failures,
|
||||
* but for demonstration purposes, we show the error.
|
||||
*/
|
||||
dialog = gtk_message_dialog_new (GTK_WINDOW (window),
|
||||
GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_MODAL,
|
||||
GTK_MESSAGE_ERROR,
|
||||
GTK_BUTTONS_CLOSE,
|
||||
"Could not paste text: %s",
|
||||
error->message);
|
||||
g_signal_connect (dialog, "response",
|
||||
G_CALLBACK (gtk_window_destroy), NULL);
|
||||
gtk_widget_show (dialog);
|
||||
|
||||
g_print ("%s\n", error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
paste_button_clicked (GtkWidget *button,
|
||||
gpointer user_data)
|
||||
paste_button_clicked (GtkStack *dest_stack,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkWidget *entry;
|
||||
GdkClipboard *clipboard;
|
||||
GdkContentFormats *formats;
|
||||
|
||||
entry = GTK_WIDGET (user_data);
|
||||
clipboard = gtk_widget_get_clipboard (GTK_WIDGET (dest_stack));
|
||||
formats = gdk_clipboard_get_formats (clipboard);
|
||||
|
||||
/* Get the clipboard object */
|
||||
clipboard = gtk_widget_get_clipboard (entry);
|
||||
if (gdk_content_formats_contain_gtype (formats, GDK_TYPE_TEXTURE))
|
||||
gdk_clipboard_read_value_async (clipboard, GDK_TYPE_TEXTURE, 0, NULL, paste_received, dest_stack);
|
||||
else if (gdk_content_formats_contain_gtype (formats, GDK_TYPE_PAINTABLE))
|
||||
gdk_clipboard_read_value_async (clipboard, GDK_TYPE_PAINTABLE, 0, NULL, paste_received, dest_stack);
|
||||
else if (gdk_content_formats_contain_gtype (formats, GDK_TYPE_RGBA))
|
||||
gdk_clipboard_read_value_async (clipboard, GDK_TYPE_RGBA, 0, NULL, paste_received, dest_stack);
|
||||
else if (gdk_content_formats_contain_gtype (formats, G_TYPE_FILE))
|
||||
gdk_clipboard_read_value_async (clipboard, G_TYPE_FILE, 0, NULL, paste_received, dest_stack);
|
||||
else if (gdk_content_formats_contain_gtype (formats, G_TYPE_STRING))
|
||||
gdk_clipboard_read_value_async (clipboard, G_TYPE_STRING, 0, NULL, paste_received, dest_stack);
|
||||
}
|
||||
|
||||
/* Request the contents of the clipboard, contents_received will be
|
||||
called when we do get the contents.
|
||||
*/
|
||||
gdk_clipboard_read_text_async (clipboard, NULL, paste_received, entry);
|
||||
static void
|
||||
update_copy_button_sensitivity (GtkWidget *source_stack)
|
||||
{
|
||||
GtkButton *copy_button;
|
||||
const char *visible_child_name;
|
||||
GtkWidget *visible_child;
|
||||
gboolean sensitive;
|
||||
|
||||
copy_button = GTK_BUTTON (g_object_get_data (G_OBJECT (source_stack), "copy-button"));
|
||||
|
||||
visible_child = gtk_stack_get_visible_child (GTK_STACK (source_stack));
|
||||
visible_child_name = gtk_stack_get_visible_child_name (GTK_STACK (source_stack));
|
||||
if (strcmp (visible_child_name, "Text") == 0)
|
||||
{
|
||||
sensitive = strlen (gtk_editable_get_text (GTK_EDITABLE (visible_child))) > 0;
|
||||
}
|
||||
else if (strcmp (visible_child_name, "Color") == 0 ||
|
||||
strcmp (visible_child_name, "Image") == 0)
|
||||
{
|
||||
sensitive = TRUE;
|
||||
}
|
||||
else if (strcmp (visible_child_name, "File") == 0)
|
||||
{
|
||||
sensitive = g_object_get_data (G_OBJECT (visible_child), "file") != NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
sensitive = FALSE;
|
||||
}
|
||||
|
||||
gtk_widget_set_sensitive (GTK_WIDGET (copy_button), sensitive);
|
||||
}
|
||||
|
||||
static void
|
||||
source_changed_cb (GtkButton *copy_button,
|
||||
GParamSpec *pspec,
|
||||
GtkWidget *source_stack)
|
||||
{
|
||||
update_copy_button_sensitivity (source_stack);
|
||||
}
|
||||
|
||||
static void
|
||||
text_changed_cb (GtkButton *copy_button,
|
||||
GParamSpec *pspec,
|
||||
GtkWidget *entry)
|
||||
{
|
||||
update_copy_button_sensitivity (gtk_widget_get_ancestor (entry, GTK_TYPE_STACK));
|
||||
}
|
||||
|
||||
static void
|
||||
file_button_set_file (GtkButton *button,
|
||||
GFile *file)
|
||||
{
|
||||
gtk_label_set_label (GTK_LABEL (gtk_button_get_child (button)), g_file_peek_path (file));
|
||||
g_object_set_data_full (G_OBJECT (button), "file", g_object_ref (file), g_object_unref);
|
||||
}
|
||||
|
||||
static void
|
||||
file_chooser_response (GtkNativeDialog *dialog,
|
||||
int response,
|
||||
GtkButton *button)
|
||||
{
|
||||
gtk_native_dialog_hide (dialog);
|
||||
|
||||
if (response == GTK_RESPONSE_ACCEPT)
|
||||
{
|
||||
GFile *file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog));
|
||||
file_button_set_file (button, file);
|
||||
g_object_unref (file);
|
||||
|
||||
update_copy_button_sensitivity (gtk_widget_get_ancestor (GTK_WIDGET (button), GTK_TYPE_STACK));
|
||||
}
|
||||
|
||||
gtk_native_dialog_destroy (dialog);
|
||||
}
|
||||
|
||||
static void
|
||||
open_file_cb (GtkWidget *button)
|
||||
{
|
||||
GtkFileChooserNative *chooser;
|
||||
|
||||
chooser = gtk_file_chooser_native_new ("Choose a file",
|
||||
GTK_WINDOW (gtk_widget_get_ancestor (button, GTK_TYPE_WINDOW)),
|
||||
GTK_FILE_CHOOSER_ACTION_OPEN,
|
||||
"_Open",
|
||||
"_Cancel");
|
||||
|
||||
g_signal_connect (chooser, "response", G_CALLBACK (file_chooser_response), button);
|
||||
gtk_native_dialog_show (GTK_NATIVE_DIALOG (chooser));
|
||||
}
|
||||
|
||||
static void
|
||||
update_paste_button_sensitivity (GdkClipboard *clipboard,
|
||||
GtkWidget *paste_button)
|
||||
{
|
||||
GdkContentFormats *formats;
|
||||
gboolean sensitive = FALSE;
|
||||
|
||||
formats = gdk_clipboard_get_formats (clipboard);
|
||||
|
||||
if (gdk_content_formats_contain_gtype (formats, G_TYPE_FILE) ||
|
||||
gdk_content_formats_contain_gtype (formats, GDK_TYPE_RGBA) ||
|
||||
gdk_content_formats_contain_gtype (formats, GDK_TYPE_TEXTURE) ||
|
||||
gdk_content_formats_contain_gtype (formats, GDK_TYPE_PAINTABLE) ||
|
||||
gdk_content_formats_contain_gtype (formats, G_TYPE_STRING))
|
||||
sensitive = TRUE;
|
||||
|
||||
gtk_widget_set_sensitive (paste_button, sensitive);
|
||||
}
|
||||
|
||||
static void
|
||||
unset_clipboard_handler (gpointer data)
|
||||
{
|
||||
GdkClipboard *clipboard = gtk_widget_get_clipboard (GTK_WIDGET (data));
|
||||
|
||||
g_signal_handlers_disconnect_by_func (clipboard, update_paste_button_sensitivity, data);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
on_drop (GtkStack *dest_stack,
|
||||
const GValue *value,
|
||||
double x,
|
||||
double y,
|
||||
gpointer data)
|
||||
{
|
||||
present_value (dest_stack, value);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GdkContentProvider *
|
||||
drag_prepare (GtkDragSource *drag_source,
|
||||
double x,
|
||||
double y,
|
||||
gpointer data)
|
||||
{
|
||||
GtkWidget *button;
|
||||
GValue value = G_VALUE_INIT;
|
||||
|
||||
button = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (drag_source));
|
||||
|
||||
if (GTK_IS_TOGGLE_BUTTON (button))
|
||||
{
|
||||
GtkWidget *image = gtk_widget_get_first_child (button);
|
||||
GdkPaintable *paintable = gtk_image_get_paintable (GTK_IMAGE (image));
|
||||
|
||||
if (GDK_IS_TEXTURE (paintable))
|
||||
{
|
||||
g_value_init (&value, GDK_TYPE_TEXTURE);
|
||||
g_value_set_object (&value, paintable);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_value_init (&value, GDK_TYPE_PAINTABLE);
|
||||
g_value_set_object (&value, paintable);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GFile *file = g_object_get_data (G_OBJECT (button), "file");
|
||||
|
||||
if (file)
|
||||
{
|
||||
g_value_init (&value, G_TYPE_FILE);
|
||||
g_value_set_object (&value, file);
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return gdk_content_provider_new_for_value (&value);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
do_clipboard (GtkWidget *do_widget)
|
||||
{
|
||||
static GtkWidget *window = NULL;
|
||||
|
||||
if (!window)
|
||||
{
|
||||
GtkWidget *vbox, *hbox;
|
||||
GtkWidget *label;
|
||||
GtkWidget *entry, *button;
|
||||
GtkWidget *image;
|
||||
GtkBuilderScope *scope;
|
||||
GtkBuilder *builder;
|
||||
GtkWidget *button;
|
||||
|
||||
window = gtk_window_new ();
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Clipboard");
|
||||
scope = gtk_builder_cscope_new ();
|
||||
gtk_builder_cscope_add_callback_symbols (GTK_BUILDER_CSCOPE (scope),
|
||||
"copy_button_clicked", G_CALLBACK (copy_button_clicked),
|
||||
"paste_button_clicked", G_CALLBACK (paste_button_clicked),
|
||||
"source_changed_cb", G_CALLBACK (source_changed_cb),
|
||||
"text_changed_cb", G_CALLBACK (text_changed_cb),
|
||||
"open_file_cb", G_CALLBACK (open_file_cb),
|
||||
"on_drop", G_CALLBACK (on_drop),
|
||||
"drag_prepare", G_CALLBACK (drag_prepare),
|
||||
NULL);
|
||||
|
||||
builder = gtk_builder_new ();
|
||||
gtk_builder_set_scope (builder, scope);
|
||||
gtk_builder_add_from_resource (builder, "/clipboard/clipboard.ui", NULL);
|
||||
|
||||
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
|
||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
||||
gtk_window_set_display (GTK_WINDOW (window), gtk_widget_get_display (do_widget));
|
||||
|
||||
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
||||
gtk_widget_set_margin_start (vbox, 8);
|
||||
gtk_widget_set_margin_end (vbox, 8);
|
||||
gtk_widget_set_margin_top (vbox, 8);
|
||||
gtk_widget_set_margin_bottom (vbox, 8);
|
||||
button = GTK_WIDGET (gtk_builder_get_object (builder, "copy_button"));
|
||||
g_object_set_data (gtk_builder_get_object (builder, "source_stack"), "copy-button", button);
|
||||
|
||||
gtk_window_set_child (GTK_WINDOW (window), vbox);
|
||||
button = GTK_WIDGET (gtk_builder_get_object (builder, "paste_button"));
|
||||
g_signal_connect (gtk_widget_get_clipboard (button), "changed",
|
||||
G_CALLBACK (update_paste_button_sensitivity), button);
|
||||
g_object_set_data_full (G_OBJECT (button), "clipboard-handler", button, unset_clipboard_handler);
|
||||
|
||||
label = gtk_label_new ("\"Copy\" will copy the text\nin the entry to the clipboard");
|
||||
|
||||
gtk_box_append (GTK_BOX (vbox), label);
|
||||
|
||||
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
|
||||
gtk_widget_set_margin_start (hbox, 8);
|
||||
gtk_widget_set_margin_end (hbox, 8);
|
||||
gtk_widget_set_margin_top (hbox, 8);
|
||||
gtk_widget_set_margin_bottom (hbox, 8);
|
||||
gtk_box_append (GTK_BOX (vbox), hbox);
|
||||
|
||||
/* Create the first entry */
|
||||
entry = gtk_entry_new ();
|
||||
gtk_box_append (GTK_BOX (hbox), entry);
|
||||
|
||||
/* Create the button */
|
||||
button = gtk_button_new_with_mnemonic (_("_Copy"));
|
||||
gtk_box_append (GTK_BOX (hbox), button);
|
||||
g_signal_connect (button, "clicked",
|
||||
G_CALLBACK (copy_button_clicked), entry);
|
||||
|
||||
label = gtk_label_new ("\"Paste\" will paste the text from the clipboard to the entry");
|
||||
gtk_box_append (GTK_BOX (vbox), label);
|
||||
|
||||
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
|
||||
gtk_widget_set_margin_start (hbox, 8);
|
||||
gtk_widget_set_margin_end (hbox, 8);
|
||||
gtk_widget_set_margin_top (hbox, 8);
|
||||
gtk_widget_set_margin_bottom (hbox, 8);
|
||||
gtk_box_append (GTK_BOX (vbox), hbox);
|
||||
|
||||
/* Create the second entry */
|
||||
entry = gtk_entry_new ();
|
||||
gtk_box_append (GTK_BOX (hbox), entry);
|
||||
|
||||
/* Create the button */
|
||||
button = gtk_button_new_with_mnemonic (_("_Paste"));
|
||||
gtk_box_append (GTK_BOX (hbox), button);
|
||||
g_signal_connect (button, "clicked",
|
||||
G_CALLBACK (paste_button_clicked), entry);
|
||||
|
||||
label = gtk_label_new ("Images can be transferred via the clipboard, too");
|
||||
gtk_box_append (GTK_BOX (vbox), label);
|
||||
|
||||
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
|
||||
gtk_widget_set_margin_start (hbox, 8);
|
||||
gtk_widget_set_margin_end (hbox, 8);
|
||||
gtk_widget_set_margin_top (hbox, 8);
|
||||
gtk_widget_set_margin_bottom (hbox, 8);
|
||||
gtk_box_append (GTK_BOX (vbox), hbox);
|
||||
|
||||
/* Create the first image */
|
||||
image = demo_image_new ("dialog-warning");
|
||||
gtk_box_append (GTK_BOX (hbox), image);
|
||||
|
||||
/* Create the second image */
|
||||
image = demo_image_new ("process-stop");
|
||||
gtk_box_append (GTK_BOX (hbox), image);
|
||||
|
||||
/* Create the third image */
|
||||
image = demo_image_new ("weather-clear");
|
||||
gtk_box_append (GTK_BOX (hbox), image);
|
||||
g_object_unref (builder);
|
||||
g_object_unref (scope);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
|
||||
288
demos/gtk-demo/clipboard.ui
Normal file
288
demos/gtk-demo/clipboard.ui
Normal file
@@ -0,0 +1,288 @@
|
||||
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<object class="GtkWindow" id="window">
|
||||
<property name="resizable">1</property>
|
||||
<property name="title">Clipboard</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="margin-start">12</property>
|
||||
<property name="margin-end">12</property>
|
||||
<property name="margin-top">12</property>
|
||||
<property name="margin-bottom">12</property>
|
||||
<property name="spacing">12</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">“Copy” will copy the selected data the clipboard, “Paste” will show the current clipboard contents. You can also drag the data to the bottom.</property>
|
||||
<property name="wrap">1</property>
|
||||
<property name="max-width-chars">40</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="spacing">12</property>
|
||||
<child>
|
||||
<object class="GtkDropDown" id="source_chooser">
|
||||
<property name="valign">center</property>
|
||||
<property name="model">
|
||||
<object class="GtkStringList">
|
||||
<items>
|
||||
<item>Text</item>
|
||||
<item>Color</item>
|
||||
<item>Image</item>
|
||||
<item>File</item>
|
||||
</items>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkStack" id="source_stack">
|
||||
<signal name="notify::visible-child" handler="source_changed_cb" object="copy_button"/>
|
||||
<property name="vexpand">1</property>
|
||||
<binding name="visible-child-name">
|
||||
<lookup name="string" type="GtkStringObject">
|
||||
<lookup name="selected-item">
|
||||
source_chooser
|
||||
</lookup>
|
||||
</lookup>
|
||||
</binding>
|
||||
<child>
|
||||
<object class="GtkStackPage">
|
||||
<property name="name">Text</property>
|
||||
<property name="child">
|
||||
<object class="GtkEntry" id="source_text">
|
||||
<property name="valign">center</property>
|
||||
<signal name="notify::text" handler="text_changed_cb" object="copy_button"/>
|
||||
<property name="text">Copy this!</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkStackPage">
|
||||
<property name="name">Color</property>
|
||||
<property name="child">
|
||||
<object class="GtkColorButton" id="source_color">
|
||||
<property name="valign">center</property>
|
||||
<property name="rgba">purple</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkStackPage">
|
||||
<property name="name">Image</property>
|
||||
<property name="child">
|
||||
<object class="GtkBox">
|
||||
<property name="valign">center</property>
|
||||
<style>
|
||||
<class name="linked"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="GtkToggleButton" id="image_rose">
|
||||
<property name="active">1</property>
|
||||
<child>
|
||||
<object class="GtkDragSource">
|
||||
<signal name="prepare" handler="drag_prepare"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<style>
|
||||
<class name="large-icons"/>
|
||||
</style>
|
||||
<property name="paintable">resource:///transparent/portland-rose.jpg</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToggleButton" id="image_floppy">
|
||||
<property name="group">image_rose</property>
|
||||
<child>
|
||||
<object class="GtkDragSource">
|
||||
<signal name="prepare" handler="drag_prepare"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<style>
|
||||
<class name="large-icons"/>
|
||||
</style>
|
||||
<property name="paintable">resource:///images/floppybuddy.gif</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToggleButton" id="image_logo">
|
||||
<property name="group">image_floppy</property>
|
||||
<child>
|
||||
<object class="GtkDragSource">
|
||||
<signal name="prepare" handler="drag_prepare"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<style>
|
||||
<class name="large-icons"/>
|
||||
</style>
|
||||
<property name="paintable">resource:///images/org.gtk.Demo4.svg</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkStackPage">
|
||||
<property name="name">File</property>
|
||||
<property name="child">
|
||||
<object class="GtkButton" id="source_file">
|
||||
<child>
|
||||
<object class="GtkDragSource">
|
||||
<property name="propagation-phase">capture</property>
|
||||
<signal name="prepare" handler="drag_prepare"/>
|
||||
</object>
|
||||
</child>
|
||||
<property name="valign">center</property>
|
||||
<property name="child">
|
||||
<object class="GtkLabel">
|
||||
<property name="label">—</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="ellipsize">start</property>
|
||||
</object>
|
||||
</property>
|
||||
<signal name="clicked" handler="open_file_cb"/>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="copy_button">
|
||||
<property name="valign">center</property>
|
||||
<property name="label" translatable="yes">_Copy</property>
|
||||
<signal name="clicked" handler="copy_button_clicked" object="source_stack"/>
|
||||
<property name="use-underline">1</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparator">
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="spacing">12</property>
|
||||
<child>
|
||||
<object class="GtkDropTarget">
|
||||
<property name="actions">copy</property>
|
||||
<property name="formats">GdkTexture GdkPaintable GFile GdkRGBA gchararray</property>
|
||||
<signal name="drop" handler="on_drop" object="dest_stack"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="paste_button">
|
||||
<property name="label" translatable="yes">_Paste</property>
|
||||
<signal name="clicked" handler="paste_button_clicked" object="dest_stack"/>
|
||||
<property name="use-underline">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="xalign">0</property>
|
||||
<binding name="label">
|
||||
<lookup name="visible-child-name" type="GtkStack">
|
||||
dest_stack
|
||||
</lookup>
|
||||
</binding>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkStack" id="dest_stack">
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">center</property>
|
||||
<child>
|
||||
<object class="GtkStackPage">
|
||||
<property name="name"></property>
|
||||
<property name="child">
|
||||
<object class="GtkLabel">
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkStackPage">
|
||||
<property name="name">Text</property>
|
||||
<property name="child">
|
||||
<object class="GtkLabel">
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="ellipsize">end</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkStackPage">
|
||||
<property name="name">Image</property>
|
||||
<property name="child">
|
||||
<object class="GtkImage">
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">center</property>
|
||||
<style>
|
||||
<class name="large-icons"/>
|
||||
</style>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkStackPage">
|
||||
<property name="name">Color</property>
|
||||
<property name="child">
|
||||
<object class="GtkBox">
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">center</property>
|
||||
<child>
|
||||
<object class="GtkColorSwatch">
|
||||
<property name="accessible-role">img</property>
|
||||
<property name="can-focus">0</property>
|
||||
<property name="selectable">0</property>
|
||||
<property name="has-menu">0</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkStackPage">
|
||||
<property name="name">File</property>
|
||||
<property name="child">
|
||||
<object class="GtkLabel">
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="hexpand">1</property>
|
||||
<property name="ellipsize">start</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
||||
@@ -24,6 +24,7 @@ do_cursors (GtkWidget *do_widget)
|
||||
|
||||
builder = gtk_builder_new_from_resource ("/cursors/cursors.ui");
|
||||
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
|
||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
g_signal_connect (window, "destroy",
|
||||
@@ -34,9 +35,7 @@ do_cursors (GtkWidget *do_widget)
|
||||
if (!gtk_widget_get_visible (window))
|
||||
gtk_widget_show (window);
|
||||
else
|
||||
{
|
||||
gtk_window_destroy (GTK_WINDOW (window));
|
||||
}
|
||||
gtk_window_destroy (GTK_WINDOW (window));
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
<file>demo.ui</file>
|
||||
</gresource>
|
||||
<gresource prefix="/clipboard">
|
||||
<file>clipboard.ui</file>
|
||||
<file>demoimage.c</file>
|
||||
<file>demoimage.h</file>
|
||||
</gresource>
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
*/
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <pango/pangofc-font.h>
|
||||
#include <hb.h>
|
||||
#include <hb-ot.h>
|
||||
#include <glib/gi18n.h>
|
||||
|
||||
@@ -223,6 +223,7 @@ static void
|
||||
destroy_gear (struct gear *g)
|
||||
{
|
||||
g_free (g->strips);
|
||||
g_free (g->vertices);
|
||||
g_free (g);
|
||||
}
|
||||
|
||||
|
||||
@@ -18,15 +18,81 @@
|
||||
|
||||
#include "language-names.h"
|
||||
|
||||
#ifdef G_OS_WIN32
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#else
|
||||
|
||||
#ifndef ISO_CODES_PREFIX
|
||||
#define ISO_CODES_PREFIX "/usr"
|
||||
#endif
|
||||
|
||||
#define ISO_CODES_DATADIR ISO_CODES_PREFIX "/share/xml/iso-codes"
|
||||
#define ISO_CODES_LOCALESDIR ISO_CODES_PREFIX "/share/locale"
|
||||
#endif
|
||||
|
||||
static GHashTable *language_map;
|
||||
|
||||
#ifdef G_OS_WIN32
|
||||
/* if we are using native Windows use native Windows API for language names */
|
||||
static BOOL CALLBACK
|
||||
get_win32_all_locales_scripts (LPWSTR locale_w, DWORD flags, LPARAM param)
|
||||
{
|
||||
wchar_t *langname_w = NULL;
|
||||
wchar_t locale_abbrev_w[9];
|
||||
gchar *langname, *locale_abbrev, *locale, *p;
|
||||
gint i;
|
||||
const LCTYPE iso639_lctypes[] = { LOCALE_SISO639LANGNAME, LOCALE_SISO639LANGNAME2 };
|
||||
GHashTable *ht_scripts_langs = (GHashTable *) param;
|
||||
PangoLanguage *lang;
|
||||
|
||||
gint langname_size, locale_abbrev_size;
|
||||
langname_size = GetLocaleInfoEx (locale_w, LOCALE_SLOCALIZEDDISPLAYNAME, langname_w, 0);
|
||||
if (langname_size == 0)
|
||||
return FALSE;
|
||||
|
||||
langname_w = g_new0 (wchar_t, langname_size);
|
||||
|
||||
if (langname_size == 0)
|
||||
return FALSE;
|
||||
|
||||
GetLocaleInfoEx (locale_w, LOCALE_SLOCALIZEDDISPLAYNAME, langname_w, langname_size);
|
||||
langname = g_utf16_to_utf8 (langname_w, -1, NULL, NULL, NULL);
|
||||
locale = g_utf16_to_utf8 (locale_w, -1, NULL, NULL, NULL);
|
||||
p = strchr (locale, '-');
|
||||
lang = pango_language_from_string (locale);
|
||||
if (g_hash_table_lookup (ht_scripts_langs, lang) == NULL)
|
||||
g_hash_table_insert (ht_scripts_langs, lang, langname);
|
||||
|
||||
/*
|
||||
* Track 3+-letter ISO639-2/3 language codes as well (these have a max length of 9 including terminating NUL)
|
||||
* ISO639-2: iso639_lctypes[0] = LOCALE_SISO639LANGNAME
|
||||
* ISO639-3: iso639_lctypes[1] = LOCALE_SISO639LANGNAME2
|
||||
*/
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
locale_abbrev_size = GetLocaleInfoEx (locale_w, iso639_lctypes[i], locale_abbrev_w, 0);
|
||||
if (locale_abbrev_size > 0)
|
||||
{
|
||||
GetLocaleInfoEx (locale_w, iso639_lctypes[i], locale_abbrev_w, locale_abbrev_size);
|
||||
|
||||
locale_abbrev = g_utf16_to_utf8 (locale_abbrev_w, -1, NULL, NULL, NULL);
|
||||
lang = pango_language_from_string (locale_abbrev);
|
||||
if (g_hash_table_lookup (ht_scripts_langs, lang) == NULL)
|
||||
g_hash_table_insert (ht_scripts_langs, lang, langname);
|
||||
|
||||
g_free (locale_abbrev);
|
||||
}
|
||||
}
|
||||
|
||||
g_free (locale);
|
||||
g_free (langname_w);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#else /* non-Windows */
|
||||
|
||||
static char *
|
||||
get_first_item_in_semicolon_list (const char *list)
|
||||
{
|
||||
@@ -210,6 +276,7 @@ languages_variant_init (const char *variant)
|
||||
g_free (filename);
|
||||
g_free (buf);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
languages_init (void)
|
||||
@@ -218,8 +285,13 @@ languages_init (void)
|
||||
return;
|
||||
|
||||
language_map = g_hash_table_new_full (NULL, NULL, NULL, g_free);
|
||||
|
||||
#ifdef G_OS_WIN32
|
||||
g_return_if_fail (EnumSystemLocalesEx (&get_win32_all_locales_scripts, LOCALE_ALL, (LPARAM) language_map, NULL));
|
||||
#else
|
||||
languages_variant_init ("iso_639");
|
||||
languages_variant_init ("iso_639_3");
|
||||
#endif
|
||||
}
|
||||
|
||||
const char *
|
||||
|
||||
@@ -1040,7 +1040,7 @@ out:
|
||||
g_signal_connect_swapped (G_OBJECT (demo), "destroy", G_CALLBACK (g_application_quit), app);
|
||||
}
|
||||
else
|
||||
gtk_widget_show (GTK_WIDGET (window));
|
||||
gtk_window_present (GTK_WINDOW (window));
|
||||
|
||||
if (autoquit)
|
||||
g_timeout_add_seconds (1, auto_quit, app);
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">Save _As...</attribute>
|
||||
<attribute name="action">app.save-as</attribute>
|
||||
<attribute name="accel"><Control>s</attribute>
|
||||
<attribute name="accel"><Control><Shift>s</attribute>
|
||||
</item>
|
||||
</section>
|
||||
<section>
|
||||
|
||||
@@ -98,6 +98,7 @@ demos = files([
|
||||
'transparent.c',
|
||||
'tree_store.c',
|
||||
'video_player.c',
|
||||
'font_features.c',
|
||||
])
|
||||
|
||||
gtkdemo_deps = [ libgtk_dep, ]
|
||||
@@ -128,14 +129,9 @@ extra_demo_sources = files([
|
||||
'script-names.c',
|
||||
'unicode-names.c',
|
||||
'suggestionentry.c',
|
||||
'language-names.c',
|
||||
])
|
||||
|
||||
if harfbuzz_dep.found() and pangoft_dep.found()
|
||||
demos += files(['font_features.c'])
|
||||
extra_demo_sources += files(['language-names.c'])
|
||||
gtkdemo_deps += [ harfbuzz_dep, epoxy_dep ]
|
||||
endif
|
||||
|
||||
if os_unix
|
||||
demos += files('pagesetup.c')
|
||||
endif
|
||||
@@ -164,7 +160,7 @@ endif
|
||||
|
||||
ld = find_program('ld', required : false)
|
||||
|
||||
if build_machine.system() == 'linux' and objcopy.found() and objcopy_supports_add_symbol and ld.found()
|
||||
if not meson.is_cross_build() and build_machine.cpu_family() != 'arm' and build_machine.system() == 'linux' and objcopy.found() and objcopy_supports_add_symbol and ld.found()
|
||||
glib_compile_resources = find_program('glib-compile-resources')
|
||||
|
||||
# Create the resource blob
|
||||
@@ -174,6 +170,7 @@ if build_machine.system() == 'linux' and objcopy.found() and objcopy_supports_ad
|
||||
depfile : 'gtkdemo.gresource.d',
|
||||
command : [glib_compile_resources,
|
||||
'--generate',
|
||||
'--internal',
|
||||
'--target=@OUTPUT@',
|
||||
'--dependency-file=@DEPFILE@',
|
||||
'--sourcedir=' + meson.current_source_dir(),
|
||||
@@ -187,6 +184,7 @@ if build_machine.system() == 'linux' and objcopy.found() and objcopy_supports_ad
|
||||
depfile : 'gtkdemo_resources.c.d',
|
||||
command : [glib_compile_resources,
|
||||
'--generate-source',
|
||||
'--internal',
|
||||
'--target=@OUTPUT@',
|
||||
'--dependency-file=@DEPFILE@',
|
||||
'--sourcedir=' + meson.current_source_dir(),
|
||||
@@ -200,6 +198,7 @@ if build_machine.system() == 'linux' and objcopy.found() and objcopy_supports_ad
|
||||
input : gtkdemo_gresource,
|
||||
output : 'gtkdemo_resources.o',
|
||||
command : [ld,
|
||||
'-z', 'noexecstack',
|
||||
'-r',
|
||||
'-b','binary',
|
||||
'@INPUT@',
|
||||
@@ -210,6 +209,7 @@ if build_machine.system() == 'linux' and objcopy.found() and objcopy_supports_ad
|
||||
input : gtkdemo_resources_binary,
|
||||
output : 'gtkdemo_resources2.o',
|
||||
command : [objcopy,
|
||||
'--strip-all',
|
||||
'--add-symbol','_g_binary_gtkdemo_resource_data=.data:0',
|
||||
'@INPUT@',
|
||||
'@OUTPUT@'])
|
||||
@@ -242,7 +242,7 @@ executable('gtk4-demo',
|
||||
c_args: gtkdemo_args + demo_cflags,
|
||||
dependencies: gtkdemo_deps,
|
||||
include_directories: confinc,
|
||||
gui_app: true,
|
||||
win_subsystem: 'windows',
|
||||
link_args: extra_demo_ldflags,
|
||||
install: true,
|
||||
)
|
||||
@@ -252,7 +252,7 @@ executable('gtk4-demo-application',
|
||||
c_args: gtkdemo_args + common_cflags,
|
||||
dependencies: gtkdemo_deps,
|
||||
include_directories: confinc,
|
||||
gui_app: true,
|
||||
win_subsystem: 'windows',
|
||||
link_args: extra_demo_ldflags,
|
||||
install: true,
|
||||
)
|
||||
|
||||
@@ -16,7 +16,7 @@ executable('gtk4-icon-browser',
|
||||
c_args: common_cflags,
|
||||
dependencies: [ libgtk_dep, demo_conf_h ],
|
||||
include_directories: confinc,
|
||||
gui_app: true,
|
||||
win_subsystem: 'windows',
|
||||
link_args: extra_demo_ldflags,
|
||||
install: true,
|
||||
)
|
||||
|
||||
@@ -3,7 +3,7 @@ demo_profile = get_option('profile')
|
||||
|
||||
demo_conf_h = declare_dependency(
|
||||
sources: custom_target('demo-header',
|
||||
command: [gen_demo_header, meson.source_root(), demo_profile],
|
||||
command: [gen_demo_header, meson.project_source_root(), demo_profile],
|
||||
capture: true,
|
||||
output: 'demo_conf.h',
|
||||
build_by_default: true,
|
||||
|
||||
@@ -17,7 +17,7 @@ executable('gtk4-node-editor',
|
||||
c_args: [
|
||||
'-DNODE_EDITOR_SOURCE_DIR="@0@/../../testsuite/gsk/compare/"'.format(meson.current_source_dir())
|
||||
] + common_cflags,
|
||||
gui_app: true,
|
||||
win_subsystem: 'windows',
|
||||
link_args: extra_demo_ldflags,
|
||||
install: false,
|
||||
)
|
||||
|
||||
@@ -3,7 +3,7 @@ executable('gtk4-print-editor',
|
||||
c_args: common_cflags,
|
||||
dependencies: [ libgtk_dep, demo_conf_h ],
|
||||
include_directories: confinc,
|
||||
gui_app: true,
|
||||
win_subsystem: 'windows',
|
||||
link_args: extra_demo_ldflags,
|
||||
install: true,
|
||||
)
|
||||
|
||||
@@ -871,7 +871,7 @@ activate (GApplication *app)
|
||||
|
||||
update_ui ();
|
||||
|
||||
gtk_widget_show (main_window);
|
||||
gtk_window_present (GTK_WINDOW (main_window));
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -8,7 +8,7 @@ endif
|
||||
|
||||
ld = find_program('ld', required : false)
|
||||
|
||||
if build_machine.system() == 'linux' and objcopy.found() and objcopy_supports_add_symbol and ld.found()
|
||||
if not meson.is_cross_build() and build_machine.cpu_family() != 'arm' and build_machine.system() == 'linux' and objcopy.found() and objcopy_supports_add_symbol and ld.found()
|
||||
glib_compile_resources = find_program('glib-compile-resources')
|
||||
|
||||
# Create the resource blob
|
||||
@@ -18,6 +18,7 @@ if build_machine.system() == 'linux' and objcopy.found() and objcopy_supports_ad
|
||||
depfile: 'widgetfactory.gresource.d',
|
||||
command : [glib_compile_resources,
|
||||
'--generate',
|
||||
'--internal',
|
||||
'--target=@OUTPUT@',
|
||||
'--dependency-file=@DEPFILE@',
|
||||
'--sourcedir=' + meson.current_source_dir(),
|
||||
@@ -31,6 +32,7 @@ if build_machine.system() == 'linux' and objcopy.found() and objcopy_supports_ad
|
||||
depfile: 'widgetfactory_resources.c.d',
|
||||
command : [glib_compile_resources,
|
||||
'--generate-source',
|
||||
'--internal',
|
||||
'--target=@OUTPUT@',
|
||||
'--dependency-file=@DEPFILE@',
|
||||
'--sourcedir=' + meson.current_source_dir(),
|
||||
@@ -44,6 +46,7 @@ if build_machine.system() == 'linux' and objcopy.found() and objcopy_supports_ad
|
||||
input : widgetfactory_gresource,
|
||||
output : 'widgetfactory_resources.o',
|
||||
command : [ld,
|
||||
'-z', 'noexecstack',
|
||||
'-r',
|
||||
'-b','binary',
|
||||
'@INPUT@',
|
||||
@@ -54,6 +57,7 @@ if build_machine.system() == 'linux' and objcopy.found() and objcopy_supports_ad
|
||||
input : widgetfactory_resources_binary,
|
||||
output : 'widgetfactory_resources2.o',
|
||||
command : [objcopy,
|
||||
'--strip-all',
|
||||
'--add-symbol','_g_binary_widgetfactory_resource_data=.data:0',
|
||||
'@INPUT@',
|
||||
'@OUTPUT@'])
|
||||
@@ -74,7 +78,7 @@ executable('gtk4-widget-factory',
|
||||
c_args: common_cflags,
|
||||
dependencies: [ libgtk_dep, demo_conf_h ],
|
||||
include_directories: confinc,
|
||||
gui_app: true,
|
||||
win_subsystem: 'windows',
|
||||
link_args: extra_demo_ldflags,
|
||||
install: true,
|
||||
)
|
||||
|
||||
@@ -2053,6 +2053,7 @@ activate (GApplication *app)
|
||||
{ "win.open", { "<Control>o", NULL } },
|
||||
{ "win.record", { "<Control>r", NULL } },
|
||||
{ "win.lock", { "<Control>l", NULL } },
|
||||
{ "win.fullscreen", { "F11", NULL } },
|
||||
};
|
||||
struct {
|
||||
const char *action_and_target;
|
||||
@@ -2359,7 +2360,7 @@ activate (GApplication *app)
|
||||
model = (GMenuModel *)gtk_builder_get_object (builder, "new_style_context_menu_model");
|
||||
set_up_context_popover (widget, model);
|
||||
|
||||
gtk_widget_show (GTK_WIDGET (window));
|
||||
gtk_window_present (window);
|
||||
|
||||
g_object_unref (builder);
|
||||
}
|
||||
|
||||
@@ -479,7 +479,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
<child>
|
||||
<object class="GtkStackPage">
|
||||
<property name="name">page1</property>
|
||||
<property name="title" translatable="1">Page _1</property>
|
||||
<property name="title" translatable="yes">Page _1</property>
|
||||
<property name="use-underline">1</property>
|
||||
<property name="child">
|
||||
<object class="GtkBox" id="page1">
|
||||
@@ -497,7 +497,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
<property name="has-entry">1</property>
|
||||
<child internal-child="entry">
|
||||
<object class="GtkEntry" id="comboboxtext-entry">
|
||||
<property name="text" translatable="1">comboboxentry</property>
|
||||
<property name="text" translatable="yes">comboboxentry</property>
|
||||
</object>
|
||||
</child>
|
||||
<items>
|
||||
@@ -514,7 +514,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
<child internal-child="entry">
|
||||
<object class="GtkEntry" id="comboboxtext-entry2">
|
||||
<property name="invisible-char">•</property>
|
||||
<property name="text" translatable="1">comboboxentry</property>
|
||||
<property name="text" translatable="yes">comboboxentry</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
@@ -523,7 +523,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
<object class="GtkEntry" id="entry1">
|
||||
<property name="enable-emoji-completion">1</property>
|
||||
<property name="invisible_char">•</property>
|
||||
<property name="placeholder-text" translatable="1">Click icon to change mode</property>
|
||||
<property name="placeholder-text" translatable="yes">Click icon to change mode</property>
|
||||
<property name="secondary-icon-name">view-refresh-symbolic</property>
|
||||
<property name="secondary-icon-tooltip-text">Change mode</property>
|
||||
<signal name="icon-release" handler="on_entry_icon_release" swapped="no"/>
|
||||
@@ -532,7 +532,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
<child>
|
||||
<object class="GtkEntry" id="entry2">
|
||||
<property name="sensitive">0</property>
|
||||
<property name="text" translatable="1">entry</property>
|
||||
<property name="text" translatable="yes">entry</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@@ -543,7 +543,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
<child>
|
||||
<object class="GtkEntry" id="entry24">
|
||||
<property name="enable-emoji-completion">1</property>
|
||||
<property name="text" translatable="1">entry</property>
|
||||
<property name="text" translatable="yes">entry</property>
|
||||
<property name="hexpand">1</property>
|
||||
</object>
|
||||
</child>
|
||||
@@ -557,7 +557,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
<child>
|
||||
<object class="GtkPasswordEntry">
|
||||
<property name="show-peek-icon">1</property>
|
||||
<property name="placeholder-text" translatable="1">Password…</property>
|
||||
<property name="placeholder-text" translatable="yes">Password…</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@@ -612,13 +612,13 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
<property name="spacing">20</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label3">
|
||||
<property name="label" translatable="1">label</property>
|
||||
<property name="label" translatable="yes">label</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label4">
|
||||
<property name="sensitive">0</property>
|
||||
<property name="label" translatable="1">label</property>
|
||||
<property name="label" translatable="yes">label</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@@ -644,13 +644,13 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
<property name="row-spacing">6</property>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="checkbutton1">
|
||||
<property name="label" translatable="1">checkbutton</property>
|
||||
<property name="label" translatable="yes">checkbutton</property>
|
||||
<property name="active">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="checkbutton2">
|
||||
<property name="label" translatable="1">checkbutton</property>
|
||||
<property name="label" translatable="yes">checkbutton</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">1</property>
|
||||
@@ -659,7 +659,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="checkbutton3">
|
||||
<property name="label" translatable="1">checkbutton</property>
|
||||
<property name="label" translatable="yes">checkbutton</property>
|
||||
<property name="inconsistent">1</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
@@ -669,7 +669,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="checkbutton4">
|
||||
<property name="label" translatable="1">checkbutton</property>
|
||||
<property name="label" translatable="yes">checkbutton</property>
|
||||
<property name="sensitive">0</property>
|
||||
<property name="active">1</property>
|
||||
<layout>
|
||||
@@ -680,7 +680,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="checkbutton5">
|
||||
<property name="label" translatable="1">checkbutton</property>
|
||||
<property name="label" translatable="yes">checkbutton</property>
|
||||
<property name="sensitive">0</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
@@ -690,7 +690,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="checkbutton6">
|
||||
<property name="label" translatable="1">checkbutton</property>
|
||||
<property name="label" translatable="yes">checkbutton</property>
|
||||
<property name="sensitive">0</property>
|
||||
<property name="inconsistent">1</property>
|
||||
<layout>
|
||||
@@ -701,7 +701,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="radiobutton1">
|
||||
<property name="label" translatable="1">radiobutton</property>
|
||||
<property name="label" translatable="yes">radiobutton</property>
|
||||
<property name="active">1</property>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
@@ -711,7 +711,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton">
|
||||
<property name="label" translatable="1">radiobutton</property>
|
||||
<property name="label" translatable="yes">radiobutton</property>
|
||||
<property name="group">radiobutton1</property>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
@@ -721,7 +721,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="radiobutton3">
|
||||
<property name="label" translatable="1">radiobutton</property>
|
||||
<property name="label" translatable="yes">radiobutton</property>
|
||||
<property name="inconsistent">1</property>
|
||||
<property name="group">radiobutton1</property>
|
||||
<layout>
|
||||
@@ -732,7 +732,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="radiobutton4">
|
||||
<property name="label" translatable="1">radiobutton</property>
|
||||
<property name="label" translatable="yes">radiobutton</property>
|
||||
<property name="sensitive">0</property>
|
||||
<property name="active">1</property>
|
||||
<layout>
|
||||
@@ -743,7 +743,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="radiobutton5">
|
||||
<property name="label" translatable="1">radiobutton</property>
|
||||
<property name="label" translatable="yes">radiobutton</property>
|
||||
<property name="sensitive">0</property>
|
||||
<property name="group">radiobutton4</property>
|
||||
<layout>
|
||||
@@ -754,7 +754,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="radiobutton6">
|
||||
<property name="label" translatable="1">radiobutton</property>
|
||||
<property name="label" translatable="yes">radiobutton</property>
|
||||
<property name="sensitive">0</property>
|
||||
<property name="inconsistent">1</property>
|
||||
<property name="group">radiobutton4</property>
|
||||
@@ -809,27 +809,27 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
<property name="spacing">10</property>
|
||||
<child>
|
||||
<object class="GtkToggleButton" id="togglebutton1">
|
||||
<property name="label" translatable="1">togglebutton</property>
|
||||
<property name="label" translatable="yes">togglebutton</property>
|
||||
<property name="receives-default">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToggleButton" id="togglebutton2">
|
||||
<property name="label" translatable="1">togglebutton</property>
|
||||
<property name="label" translatable="yes">togglebutton</property>
|
||||
<property name="sensitive">0</property>
|
||||
<property name="receives-default">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToggleButton" id="togglebutton3">
|
||||
<property name="label" translatable="1">togglebutton</property>
|
||||
<property name="label" translatable="yes">togglebutton</property>
|
||||
<property name="receives-default">1</property>
|
||||
<property name="active">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToggleButton" id="togglebutton4">
|
||||
<property name="label" translatable="1">togglebutton</property>
|
||||
<property name="label" translatable="yes">togglebutton</property>
|
||||
<property name="sensitive">0</property>
|
||||
<property name="receives-default">1</property>
|
||||
<property name="active">1</property>
|
||||
@@ -874,7 +874,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLinkButton" id="linkbutton1">
|
||||
<property name="label" translatable="1">link button</property>
|
||||
<property name="label" translatable="yes">link button</property>
|
||||
<property name="receives-default">1</property>
|
||||
<property name="has-tooltip">1</property>
|
||||
<property name="has-frame">0</property>
|
||||
@@ -1061,7 +1061,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
<object class="GtkFrame">
|
||||
<child type="label">
|
||||
<object class="GtkLabel" id="label1">
|
||||
<property name="label" translatable="1"><b>Text Styles</b></property>
|
||||
<property name="label" translatable="yes"><b>Text Styles</b></property>
|
||||
<property name="use-markup">1</property>
|
||||
</object>
|
||||
</child>
|
||||
@@ -1176,7 +1176,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn" id="treeviewcolumn3">
|
||||
<property name="title" translatable="1">Cool</property>
|
||||
<property name="title" translatable="yes">Cool</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererToggle" id="cellrenderertoggle1"/>
|
||||
<attributes>
|
||||
@@ -1188,7 +1188,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn" id="treeviewcolumn4">
|
||||
<property name="title" translatable="1">Icon</property>
|
||||
<property name="title" translatable="yes">Icon</property>
|
||||
<property name="reorderable">1</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererPixbuf" id="cellrendererpixbuf1"/>
|
||||
@@ -1200,7 +1200,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn" id="treeviewcolumn1">
|
||||
<property name="title" translatable="1">Name</property>
|
||||
<property name="title" translatable="yes">Name</property>
|
||||
<property name="resizable">1</property>
|
||||
<property name="reorderable">1</property>
|
||||
<property name="sort-indicator">1</property>
|
||||
@@ -1217,7 +1217,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn" id="treeviewcolumn2">
|
||||
<property name="title" translatable="1">Nick</property>
|
||||
<property name="title" translatable="yes">Nick</property>
|
||||
<property name="resizable">1</property>
|
||||
<property name="reorderable">1</property>
|
||||
<property name="sort-indicator">1</property>
|
||||
@@ -1281,7 +1281,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
</property>
|
||||
<property name="tab">
|
||||
<object class="GtkLabel" id="label5">
|
||||
<property name="label" translatable="1">Sunset</property>
|
||||
<property name="label" translatable="yes">Sunset</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
@@ -1307,7 +1307,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
</property>
|
||||
<property name="tab">
|
||||
<object class="GtkLabel" id="label6">
|
||||
<property name="label" translatable="1">NYC</property>
|
||||
<property name="label" translatable="yes">NYC</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
@@ -1333,7 +1333,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
</property>
|
||||
<property name="tab">
|
||||
<object class="GtkLabel" id="label7">
|
||||
<property name="label" translatable="1">Beach</property>
|
||||
<property name="label" translatable="yes">Beach</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
@@ -1352,7 +1352,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
</property>
|
||||
<property name="tab">
|
||||
<object class="GtkLabel" id="label8">
|
||||
<property name="label" translatable="1">page 1</property>
|
||||
<property name="label" translatable="yes">page 1</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
@@ -1367,7 +1367,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
</property>
|
||||
<property name="tab">
|
||||
<object class="GtkLabel" id="label9">
|
||||
<property name="label" translatable="1">page 2</property>
|
||||
<property name="label" translatable="yes">page 2</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
@@ -1382,7 +1382,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
</property>
|
||||
<property name="tab">
|
||||
<object class="GtkLabel" id="label10">
|
||||
<property name="label" translatable="1">page 3</property>
|
||||
<property name="label" translatable="yes">page 3</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
@@ -1401,7 +1401,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
</property>
|
||||
<property name="tab">
|
||||
<object class="GtkLabel" id="label11">
|
||||
<property name="label" translatable="1">page 1</property>
|
||||
<property name="label" translatable="yes">page 1</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
@@ -1416,7 +1416,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
</property>
|
||||
<property name="tab">
|
||||
<object class="GtkLabel" id="label12">
|
||||
<property name="label" translatable="1">page 2</property>
|
||||
<property name="label" translatable="yes">page 2</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
@@ -1431,7 +1431,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
</property>
|
||||
<property name="tab">
|
||||
<object class="GtkLabel" id="label13">
|
||||
<property name="label" translatable="1">page 3</property>
|
||||
<property name="label" translatable="yes">page 3</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
@@ -1450,7 +1450,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
</property>
|
||||
<property name="tab">
|
||||
<object class="GtkLabel" id="label14">
|
||||
<property name="label" translatable="1">page 1</property>
|
||||
<property name="label" translatable="yes">page 1</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
@@ -1465,7 +1465,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
</property>
|
||||
<property name="tab">
|
||||
<object class="GtkLabel" id="label15">
|
||||
<property name="label" translatable="1">page 2</property>
|
||||
<property name="label" translatable="yes">page 2</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
@@ -1480,7 +1480,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
</property>
|
||||
<property name="tab">
|
||||
<object class="GtkLabel" id="label16">
|
||||
<property name="label" translatable="1">page 3</property>
|
||||
<property name="label" translatable="yes">page 3</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
@@ -1496,7 +1496,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
<child>
|
||||
<object class="GtkStackPage">
|
||||
<property name="name">page2</property>
|
||||
<property name="title" translatable="1">Page _2</property>
|
||||
<property name="title" translatable="yes">Page _2</property>
|
||||
<property name="use-underline">1</property>
|
||||
<property name="child">
|
||||
<object class="GtkOverlay" id="page2">
|
||||
@@ -1527,7 +1527,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="page2reset">
|
||||
<property name="valign">3</property>
|
||||
<property name="label" translatable="1">Reset</property>
|
||||
<property name="label" translatable="yes">Reset</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@@ -1700,7 +1700,7 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="1">Row 1</property>
|
||||
<property name="label" translatable="yes">Row 1</property>
|
||||
<property name="halign">1</property>
|
||||
<property name="valign">3</property>
|
||||
<property name="hexpand">1</property>
|
||||
@@ -1723,7 +1723,7 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="1">Row 2</property>
|
||||
<property name="label" translatable="yes">Row 2</property>
|
||||
<property name="halign">1</property>
|
||||
<property name="valign">3</property>
|
||||
<property name="hexpand">1</property>
|
||||
@@ -1747,7 +1747,7 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="1">Row 3</property>
|
||||
<property name="label" translatable="yes">Row 3</property>
|
||||
<property name="halign">1</property>
|
||||
<property name="valign">3</property>
|
||||
<property name="hexpand">1</property>
|
||||
@@ -1772,7 +1772,7 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="1">Row 4</property>
|
||||
<property name="label" translatable="yes">Row 4</property>
|
||||
<property name="halign">1</property>
|
||||
<property name="valign">3</property>
|
||||
<property name="hexpand">1</property>
|
||||
@@ -1797,7 +1797,7 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="1">Row 5</property>
|
||||
<property name="label" translatable="yes">Row 5</property>
|
||||
<property name="halign">1</property>
|
||||
<property name="valign">3</property>
|
||||
<property name="hexpand">1</property>
|
||||
@@ -1821,7 +1821,7 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="1">Row 6</property>
|
||||
<property name="label" translatable="yes">Row 6</property>
|
||||
<property name="halign">1</property>
|
||||
<property name="valign">3</property>
|
||||
<property name="hexpand">1</property>
|
||||
@@ -1843,7 +1843,7 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="1">Row 7</property>
|
||||
<property name="label" translatable="yes">Row 7</property>
|
||||
<property name="halign">1</property>
|
||||
<property name="valign">3</property>
|
||||
<property name="hexpand">1</property>
|
||||
@@ -1859,7 +1859,7 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="1">Row 8</property>
|
||||
<property name="label" translatable="yes">Row 8</property>
|
||||
<property name="halign">1</property>
|
||||
<property name="valign">3</property>
|
||||
<property name="hexpand">1</property>
|
||||
@@ -1896,16 +1896,16 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
</style>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="label" translatable="1">New</property>
|
||||
<property name="label" translatable="yes">New</property>
|
||||
<property name="icon-name">document-new</property>
|
||||
<property name="tooltip-text" translatable="1">Create a new document</property>
|
||||
<property name="tooltip-text" translatable="yes">Create a new document</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="label" translatable="1">Save</property>
|
||||
<property name="label" translatable="yes">Save</property>
|
||||
<property name="icon-name">document-save</property>
|
||||
<property name="tooltip-text" translatable="1">Save the current document</property>
|
||||
<property name="tooltip-text" translatable="yes">Save the current document</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@@ -1913,18 +1913,24 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="label" translatable="1">Search</property>
|
||||
<property name="label" translatable="yes">Search</property>
|
||||
<property name="icon-name">edit-find</property>
|
||||
<property name="action-name">win.search</property>
|
||||
<property name="tooltip-text" translatable="1">Search for it</property>
|
||||
<property name="tooltip-text" translatable="yes">Search for it</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="sensitive">0</property>
|
||||
<property name="label" translatable="1">Insert</property>
|
||||
<property name="label" translatable="yes">Insert</property>
|
||||
<property name="icon-name">insert-image</property>
|
||||
<property name="tooltip-text" translatable="1">Insert something</property>
|
||||
<property name="tooltip-text" translatable="yes">Insert something</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkColorButton">
|
||||
<property name="rgba">#9141AC</property>
|
||||
<property name="tooltip-text" translatable="yes">Select a color</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
@@ -2101,32 +2107,32 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
</child>
|
||||
<child type="label">
|
||||
<object class="GtkLabel" id="label19">
|
||||
<property name="label" translatable="1">Expander</property>
|
||||
<property name="label" translatable="yes">Expander</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="info_dialog_button">
|
||||
<property name="label" translatable="1">_Inform</property>
|
||||
<property name="label" translatable="yes">_Inform</property>
|
||||
<property name="use-underline">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="action_dialog_button">
|
||||
<property name="label" translatable="1">_Act</property>
|
||||
<property name="label" translatable="yes">_Act</property>
|
||||
<property name="use-underline">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="preference_dialog_button">
|
||||
<property name="label" translatable="1">_Configure</property>
|
||||
<property name="label" translatable="yes">_Configure</property>
|
||||
<property name="use-underline">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="selection_dialog_button">
|
||||
<property name="label" translatable="1">S_elect</property>
|
||||
<property name="label" translatable="yes">S_elect</property>
|
||||
<property name="use-underline">1</property>
|
||||
</object>
|
||||
</child>
|
||||
@@ -2141,7 +2147,7 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
<child>
|
||||
<object class="GtkStackPage">
|
||||
<property name="name">page3</property>
|
||||
<property name="title" translatable="1">Page _3</property>
|
||||
<property name="title" translatable="yes">Page _3</property>
|
||||
<property name="use-underline">1</property>
|
||||
<property name="child">
|
||||
<object class="GtkBox">
|
||||
@@ -2173,7 +2179,7 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn">
|
||||
<property name="title" translatable="1">Name</property>
|
||||
<property name="title" translatable="yes">Name</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText"/>
|
||||
<attributes>
|
||||
@@ -2184,7 +2190,7 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn">
|
||||
<property name="title" translatable="1">Birth</property>
|
||||
<property name="title" translatable="yes">Birth</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText"/>
|
||||
<attributes>
|
||||
@@ -2195,7 +2201,7 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn">
|
||||
<property name="title" translatable="1">Death</property>
|
||||
<property name="title" translatable="yes">Death</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText"/>
|
||||
<attributes>
|
||||
@@ -2213,7 +2219,7 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
<property name="selectable">1</property>
|
||||
<property name="halign">1</property>
|
||||
<property name="use-markup">1</property>
|
||||
<property name="label" translatable="1"><small>Data source: <a href="http://en.wikipedia.org/wiki/Charlemagne#Ancestry">Wikipedia</a></small></property>
|
||||
<property name="label" translatable="yes"><small>Data source: <a href="http://en.wikipedia.org/wiki/Charlemagne#Ancestry">Wikipedia</a></small></property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
@@ -2547,28 +2553,28 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
<object class="GtkButton" id="toolbutton1">
|
||||
<property name="icon-name">document-open-symbolic</property>
|
||||
<property name="focus-on-click">0</property>
|
||||
<property name="tooltip-text" translatable="1">Insert ⌘</property>
|
||||
<property name="tooltip-text" translatable="yes">Insert ⌘</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="toolbutton2">
|
||||
<property name="icon-name">send-to-symbolic</property>
|
||||
<property name="focus-on-click">0</property>
|
||||
<property name="tooltip-text" translatable="1">Insert ⚽</property>
|
||||
<property name="tooltip-text" translatable="yes">Insert ⚽</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="toolbutton3">
|
||||
<property name="icon-name">view-fullscreen-symbolic</property>
|
||||
<property name="focus-on-click">0</property>
|
||||
<property name="tooltip-text" translatable="1">Insert ⤢</property>
|
||||
<property name="tooltip-text" translatable="yes">Insert ⤢</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="toolbutton4">
|
||||
<property name="icon-name">star-new-symbolic</property>
|
||||
<property name="focus-on-click">0</property>
|
||||
<property name="tooltip-text" translatable="1">Insert ☆</property>
|
||||
<property name="tooltip-text" translatable="yes">Insert ☆</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
@@ -2596,7 +2602,7 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
<property name="sensitive">0</property>
|
||||
<property name="icon-name">edit-cut-symbolic</property>
|
||||
<property name="focus-on-click">0</property>
|
||||
<property name="tooltip-text" translatable="1">Cut</property>
|
||||
<property name="tooltip-text" translatable="yes">Cut</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@@ -2604,7 +2610,7 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
<property name="sensitive">0</property>
|
||||
<property name="icon-name">edit-copy-symbolic</property>
|
||||
<property name="focus-on-click">0</property>
|
||||
<property name="tooltip-text" translatable="1">Copy</property>
|
||||
<property name="tooltip-text" translatable="yes">Copy</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@@ -2612,7 +2618,7 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
<property name="sensitive">0</property>
|
||||
<property name="icon-name">edit-paste-symbolic</property>
|
||||
<property name="focus-on-click">0</property>
|
||||
<property name="tooltip-text" translatable="1">Paste</property>
|
||||
<property name="tooltip-text" translatable="yes">Paste</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
@@ -2623,7 +2629,7 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
<property name="valign">2</property>
|
||||
<property name="icon-name">edit-delete-symbolic</property>
|
||||
<property name="focus-on-click">0</property>
|
||||
<property name="tooltip-text" translatable="1">Delete</property>
|
||||
<property name="tooltip-text" translatable="yes">Delete</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
@@ -2709,7 +2715,7 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="1">Page 1</property>
|
||||
<property name="label" translatable="yes">Page 1</property>
|
||||
<property name="halign">3</property>
|
||||
<property name="hexpand">1</property>
|
||||
</object>
|
||||
@@ -2741,7 +2747,7 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="1">Page 2</property>
|
||||
<property name="label" translatable="yes">Page 2</property>
|
||||
<property name="halign">3</property>
|
||||
<property name="hexpand">1</property>
|
||||
</object>
|
||||
@@ -2775,7 +2781,7 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
</property>
|
||||
<property name="tab">
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="1">Page 3</property>
|
||||
<property name="label" translatable="yes">Page 3</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
@@ -2804,7 +2810,7 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
<child>
|
||||
<object class="GtkEntry">
|
||||
<property name="hexpand">1</property>
|
||||
<property name="placeholder-text" translatable="1">Name…</property>
|
||||
<property name="placeholder-text" translatable="yes">Name…</property>
|
||||
<property name="completion">name_completion</property>
|
||||
</object>
|
||||
</child>
|
||||
@@ -2812,7 +2818,7 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
<object class="GtkEntry">
|
||||
<property name="hexpand">1</property>
|
||||
<property name="show-emoji-icon">1</property>
|
||||
<property name="placeholder-text" translatable="1">Age…</property>
|
||||
<property name="placeholder-text" translatable="yes">Age…</property>
|
||||
<signal name="notify::text" handler="age_entry_changed"/>
|
||||
</object>
|
||||
</child>
|
||||
@@ -2845,7 +2851,7 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
</property>
|
||||
<property name="tab">
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="1">Page 1</property>
|
||||
<property name="label" translatable="yes">Page 1</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
@@ -2860,7 +2866,7 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
</property>
|
||||
<property name="tab">
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="1">Page 2</property>
|
||||
<property name="label" translatable="yes">Page 2</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
@@ -2873,7 +2879,7 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
</property>
|
||||
<property name="tab">
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="1">Page 3</property>
|
||||
<property name="label" translatable="yes">Page 3</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
@@ -2886,7 +2892,7 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
</property>
|
||||
<property name="tab">
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="1">Page 4</property>
|
||||
<property name="label" translatable="yes">Page 4</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
@@ -2899,7 +2905,7 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
</property>
|
||||
<property name="tab">
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="1">Page 5</property>
|
||||
<property name="label" translatable="yes">Page 5</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
@@ -2926,19 +2932,19 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
<property name="transient-for">window</property>
|
||||
<property name="resizable">0</property>
|
||||
<property name="modal">1</property>
|
||||
<property name="text" translatable="1">Do something?</property>
|
||||
<property name="secondary-text" translatable="1">If you don't do something,
|
||||
<property name="text" translatable="yes">Do something?</property>
|
||||
<property name="secondary-text" translatable="yes">If you don't do something,
|
||||
bad things might happen.</property>
|
||||
<property name="hide-on-close">1</property>
|
||||
<child type="action">
|
||||
<object class="GtkButton" id="cancel_info_dialog">
|
||||
<property name="label" translatable="1">_Cancel</property>
|
||||
<property name="label" translatable="yes">_Cancel</property>
|
||||
<property name="use-underline">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child type="action">
|
||||
<object class="GtkButton" id="doit_info_dialog">
|
||||
<property name="label" translatable="1">_Do It</property>
|
||||
<property name="label" translatable="yes">_Do It</property>
|
||||
<property name="use-underline">1</property>
|
||||
</object>
|
||||
</child>
|
||||
@@ -2952,7 +2958,7 @@ bad things might happen.</property>
|
||||
<property name="resizable">0</property>
|
||||
<property name="modal">1</property>
|
||||
<property name="use-header-bar">1</property>
|
||||
<property name="title" translatable="1">Zelda</property>
|
||||
<property name="title" translatable="yes">Zelda</property>
|
||||
<property name="hide-on-close">1</property>
|
||||
<property name="default-widget">act_action_dialog</property>
|
||||
<child internal-child="content_area">
|
||||
@@ -2963,20 +2969,20 @@ bad things might happen.</property>
|
||||
<property name="margin-end">20</property>
|
||||
<property name="margin-top">20</property>
|
||||
<property name="margin-bottom">20</property>
|
||||
<property name="label" translatable="1">To free the princess, you have to slay the dragon.</property>
|
||||
<property name="label" translatable="yes">To free the princess, you have to slay the dragon.</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child type="action">
|
||||
<object class="GtkButton" id="cancel_action_dialog">
|
||||
<property name="label" translatable="1">_Run</property>
|
||||
<property name="label" translatable="yes">_Run</property>
|
||||
<property name="use-underline">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child type="action">
|
||||
<object class="GtkButton" id="act_action_dialog">
|
||||
<property name="label" translatable="1">_Act</property>
|
||||
<property name="label" translatable="yes">_Act</property>
|
||||
<property name="use-underline">1</property>
|
||||
</object>
|
||||
</child>
|
||||
@@ -2990,7 +2996,7 @@ bad things might happen.</property>
|
||||
<property name="modal">1</property>
|
||||
<property name="resizable">0</property>
|
||||
<property name="use-header-bar">1</property>
|
||||
<property name="title" translatable="1">Settings</property>
|
||||
<property name="title" translatable="yes">Settings</property>
|
||||
<property name="hide-on-close">1</property>
|
||||
<child internal-child="content_area">
|
||||
<object class="GtkBox">
|
||||
@@ -3135,7 +3141,7 @@ bad things might happen.</property>
|
||||
<property name="transient-for">window</property>
|
||||
<property name="modal">1</property>
|
||||
<property name="use-header-bar">1</property>
|
||||
<property name="title" translatable="1">Choose one</property>
|
||||
<property name="title" translatable="yes">Choose one</property>
|
||||
<property name="hide-on-close">1</property>
|
||||
<property name="default-widget">select_selection_dialog</property>
|
||||
<child internal-child="content_area">
|
||||
@@ -3156,13 +3162,13 @@ bad things might happen.</property>
|
||||
</child>
|
||||
<child type="action">
|
||||
<object class="GtkButton" id="cancel_selection_dialog">
|
||||
<property name="label" translatable="1">_Cancel</property>
|
||||
<property name="label" translatable="yes">_Cancel</property>
|
||||
<property name="use-underline">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child type="action">
|
||||
<object class="GtkButton" id="select_selection_dialog">
|
||||
<property name="label" translatable="1">_Select</property>
|
||||
<property name="label" translatable="yes">_Select</property>
|
||||
<property name="use-underline">1</property>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
@@ -5,22 +5,23 @@ repository_url = "https://gitlab.gnome.org/GNOME/gtk.git"
|
||||
website_url = "https://www.gtk.org"
|
||||
authors = "GTK Development Team"
|
||||
logo_url = "gtk-logo.svg"
|
||||
license = "GPL-2.1-or-later"
|
||||
license = "LGPL-2.1-or-later"
|
||||
description = "The GTK toolkit"
|
||||
dependencies = [ "GObject-2.0" ]
|
||||
devhelp = true
|
||||
|
||||
[dependencies."GObject-2.0"]
|
||||
name = "GObject"
|
||||
description = "The base type system library"
|
||||
docs_url = "https://docs.gtk.org/gobject/"
|
||||
dependencies = ["Gdk-4.0"]
|
||||
|
||||
[dependencies."Gdk-4.0"]
|
||||
name = "GDK"
|
||||
description = "The GTK drawing kit"
|
||||
docs_url = "https://docs.gtk.org/gdk/"
|
||||
|
||||
[theme]
|
||||
name = "basic"
|
||||
show_index_summary = true
|
||||
|
||||
[source-location]
|
||||
base_url = "https://gitlab.gnome.org/GNOME/gtk/-/blob/master/"
|
||||
base_url = "https://gitlab.gnome.org/GNOME/gtk/-/blob/main/"
|
||||
|
||||
[extra]
|
||||
content_images = [
|
||||
|
||||
@@ -5,22 +5,22 @@ repository_url = "https://gitlab.gnome.org/GNOME/gtk.git"
|
||||
website_url = "https://www.gtk.org"
|
||||
authors = "GTK Development Team"
|
||||
logo_url = "gtk-logo.svg"
|
||||
license = "GPL-2.1-or-later"
|
||||
license = "LGPL-2.1-or-later"
|
||||
description = "The GTK toolkit"
|
||||
dependencies = [ "GObject-2.0" ]
|
||||
dependencies = ["Gdk-4.0"]
|
||||
devhelp = true
|
||||
|
||||
[dependencies."GObject-2.0"]
|
||||
name = "GObject"
|
||||
description = "The base type system library"
|
||||
docs_url = "https://docs.gtk.org/gobject/"
|
||||
[dependencies."Gdk-4.0"]
|
||||
name = "GDK"
|
||||
description = "The GTK drawing kit"
|
||||
docs_url = "https://docs.gtk.org/gdk4/"
|
||||
|
||||
[theme]
|
||||
name = "basic"
|
||||
show_index_summary = true
|
||||
|
||||
[source-location]
|
||||
base_url = "https://gitlab.gnome.org/GNOME/gtk/-/blob/master/"
|
||||
base_url = "https://gitlab.gnome.org/GNOME/gtk/-/blob/main/"
|
||||
|
||||
[extra]
|
||||
content_images = [
|
||||
|
||||
@@ -8,7 +8,7 @@ authors = "GTK Development Team"
|
||||
logo_url = "gtk-logo.svg"
|
||||
license = "LGPL-2.1-or-later"
|
||||
description = "The GTK toolkit"
|
||||
dependencies = [ "GObject-2.0", "cairo-1.0", "Pango-1.0", "GdkWayland-4.0", "GdkX11-4.0" ]
|
||||
dependencies = ["GObject-2.0", "Gio-2.0", "cairo-1.0", "Pango-1.0", "GdkPixbuf-2.0"]
|
||||
devhelp = true
|
||||
search_index = true
|
||||
|
||||
@@ -17,6 +17,11 @@ search_index = true
|
||||
description = "The base type system library"
|
||||
docs_url = "https://docs.gtk.org/gobject/"
|
||||
|
||||
[dependencies."Gio-2.0"]
|
||||
name = "GIO"
|
||||
description = "GObject Interfaces and Objects, Networking, IPC, and I/O"
|
||||
docs_url = "https://docs.gtk.org/gio/"
|
||||
|
||||
[dependencies."cairo-1.0"]
|
||||
name = "Cairo"
|
||||
description = "A 2D graphics library with support for multiple output devices"
|
||||
@@ -27,12 +32,19 @@ search_index = true
|
||||
description = "Text shaping and rendering"
|
||||
docs_url = "https://docs.gtk.org/Pango/"
|
||||
|
||||
[dependencies."GdkWayland-4.0"]
|
||||
[dependencies."GdkPixbuf-2.0"]
|
||||
name = "GdkPixbuf"
|
||||
description = "Image data loading"
|
||||
docs_url = "https://docs.gtk.org/gdk-pixbuf/"
|
||||
|
||||
related = ["GdkWayland-4.0", "GdkX11-4.0"]
|
||||
|
||||
[related."GdkWayland-4.0"]
|
||||
name = "GdkWayland"
|
||||
description = "GDK Wayland Backend"
|
||||
docs_url = "https://docs.gtk.org/gdk4-wayland/"
|
||||
|
||||
[dependencies."GdkX11-4.0"]
|
||||
[related."GdkX11-4.0"]
|
||||
name = "GdkX11"
|
||||
description = "GDK X11 Backend"
|
||||
docs_url = "https://docs.gtk.org/gdk4-x11/"
|
||||
@@ -43,7 +55,7 @@ show_index_summary = true
|
||||
show_class_hierarchy = true
|
||||
|
||||
[source-location]
|
||||
base_url = "https://gitlab.gnome.org/GNOME/gtk/-/blob/master/"
|
||||
base_url = "https://gitlab.gnome.org/GNOME/gtk/-/blob/main/"
|
||||
|
||||
[extra]
|
||||
content_files = [
|
||||
|
||||
@@ -8,25 +8,16 @@ authors = "GTK Development Team"
|
||||
logo_url = "gtk-logo.svg"
|
||||
license = "LGPL-2.1-or-later"
|
||||
description = "The GTK toolkit"
|
||||
dependencies = [ "GObject-2.0", "Graphene-1.0", "Pango-1.0", "Gdk-4.0" ]
|
||||
devhelp = true
|
||||
search_index = true
|
||||
|
||||
[dependencies."GObject-2.0"]
|
||||
name = "GObject"
|
||||
description = "The base type system library"
|
||||
docs_url = "https://docs.gtk.org/gobject/"
|
||||
dependencies = ["Graphene-1.0", "Gdk-4.0"]
|
||||
|
||||
[dependencies."Graphene-1.0"]
|
||||
name = "Graphene"
|
||||
description = "A thin layer of mathematical types for 3D libraries"
|
||||
docs_url = "https://ebassi.github.io/graphene/docs/"
|
||||
|
||||
[dependencies."Pango-1.0"]
|
||||
name = "Pango"
|
||||
description = "Text shaping and rendering"
|
||||
docs_url = "https://docs.gtk.org/Pango/"
|
||||
|
||||
[dependencies."Gdk-4.0"]
|
||||
name = "GDK"
|
||||
description = "The GTK windowing system abstraction"
|
||||
@@ -38,7 +29,7 @@ show_index_summary = true
|
||||
show_class_hierarchy = true
|
||||
|
||||
[source-location]
|
||||
base_url = "https://gitlab.gnome.org/GNOME/gtk/-/blob/master/"
|
||||
base_url = "https://gitlab.gnome.org/GNOME/gtk/-/blob/main/"
|
||||
|
||||
[extra]
|
||||
content_images = [
|
||||
|
||||
@@ -170,7 +170,7 @@ activate (GtkApplication *app,
|
||||
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
||||
gtk_widget_set_halign (box, GTK_ALIGN_CENTER);
|
||||
gtk_widget_set_valign (box, GTK_ALIGN_CENTER);
|
||||
|
||||
|
||||
gtk_window_set_child (GTK_WINDOW (window), box);
|
||||
|
||||
button = gtk_button_new_with_label ("Hello World");
|
||||
@@ -752,7 +752,7 @@ templates, resources, application menus, settings, [class@Gtk.HeaderBar], [class
|
||||
|
||||
The full, buildable sources for these examples can be found in the
|
||||
`examples` directory of the GTK source distribution, or
|
||||
[online](https://gitlab.gnome.org/GNOME/gtk/blob/master/examples) in the GTK
|
||||
[online](https://gitlab.gnome.org/GNOME/gtk/blob/main/examples) in the GTK
|
||||
source code repository. You can build each example separately by using make
|
||||
with the `Makefile.example` file. For more information, see the `README`
|
||||
included in the examples directory.
|
||||
@@ -972,7 +972,7 @@ example_app_window_class_init (ExampleAppWindowClass *class)
|
||||
...
|
||||
```
|
||||
|
||||
([full source](https://gitlab.gnome.org/GNOME/gtk/blob/master/examples/application2/exampleappwin.c))
|
||||
([full source](https://gitlab.gnome.org/GNOME/gtk/blob/main/examples/application2/exampleappwin.c))
|
||||
|
||||
You may have noticed that we used the `_from_resource()` variant of the function
|
||||
that sets a template. Now we need to use
|
||||
@@ -1043,7 +1043,7 @@ example_app_window_class_init (ExampleAppWindowClass *class)
|
||||
...
|
||||
```
|
||||
|
||||
([full source](https://gitlab.gnome.org/GNOME/gtk/blob/master/examples/application3/exampleappwin.c))
|
||||
([full source](https://gitlab.gnome.org/GNOME/gtk/blob/main/examples/application3/exampleappwin.c))
|
||||
|
||||
Now we revisit the `example_app_window_open()` function that is called for each
|
||||
commandline argument, and construct a GtkTextView that we then add as a page
|
||||
@@ -1087,7 +1087,7 @@ example_app_window_open (ExampleAppWindow *win,
|
||||
...
|
||||
```
|
||||
|
||||
([full source](https://gitlab.gnome.org/GNOME/gtk/blob/master/examples/application3/exampleappwin.c))
|
||||
([full source](https://gitlab.gnome.org/GNOME/gtk/blob/main/examples/application3/exampleappwin.c))
|
||||
|
||||
Lastly, we add a [class@Gtk.StackSwitcher] to the titlebar area in the UI file, and we
|
||||
tell it to display information about our stack.
|
||||
@@ -1188,7 +1188,7 @@ example_app_class_init (ExampleAppClass *class)
|
||||
...
|
||||
```
|
||||
|
||||
([full source](https://gitlab.gnome.org/GNOME/gtk/blob/master/examples/application4/exampleapp.c))
|
||||
([full source](https://gitlab.gnome.org/GNOME/gtk/blob/main/examples/application4/exampleapp.c))
|
||||
|
||||
Our preferences menu item does not do anything yet, but the Quit menu item
|
||||
is fully functional. Note that it can also be activated by the usual Ctrl-Q
|
||||
@@ -1258,7 +1258,7 @@ example_app_window_init (ExampleAppWindow *win)
|
||||
...
|
||||
```
|
||||
|
||||
([full source](https://gitlab.gnome.org/GNOME/gtk/blob/master/examples/application5/exampleappwin.c))
|
||||
([full source](https://gitlab.gnome.org/GNOME/gtk/blob/main/examples/application5/exampleappwin.c))
|
||||
|
||||
The code to connect the font setting is a little more involved, since there
|
||||
is no simple object property that it corresponds to, so we are not going to
|
||||
@@ -1429,7 +1429,7 @@ preferences_activated (GSimpleAction *action,
|
||||
...
|
||||
```
|
||||
|
||||
([full source](https://gitlab.gnome.org/GNOME/gtk/blob/master/examples/application6/exampleapp.c))
|
||||
([full source](https://gitlab.gnome.org/GNOME/gtk/blob/main/examples/application6/exampleapp.c))
|
||||
|
||||
After all this work, our application can now show a preference dialog
|
||||
like this:
|
||||
@@ -1549,7 +1549,7 @@ example_app_window_init (ExampleAppWindow *win)
|
||||
...
|
||||
```
|
||||
|
||||
([full source](https://gitlab.gnome.org/GNOME/gtk/blob/master/examples/application7/exampleappwin.c))
|
||||
([full source](https://gitlab.gnome.org/GNOME/gtk/blob/main/examples/application7/exampleappwin.c))
|
||||
|
||||
With the search bar, our application now looks like this:
|
||||
|
||||
@@ -1682,7 +1682,7 @@ example_app_window_init (ExampleAppWindow *win)
|
||||
...
|
||||
```
|
||||
|
||||
([full source](https://gitlab.gnome.org/GNOME/gtk/blob/master/examples/application8/exampleappwin.c))
|
||||
([full source](https://gitlab.gnome.org/GNOME/gtk/blob/main/examples/application8/exampleappwin.c))
|
||||
|
||||
What our application looks like now:
|
||||
|
||||
@@ -1760,10 +1760,10 @@ example_app_window_init (ExampleAppWindow *win)
|
||||
...
|
||||
```
|
||||
|
||||
([full source](https://gitlab.gnome.org/GNOME/gtk/blob/master/examples/application9/exampleappwin.c))
|
||||
([full source](https://gitlab.gnome.org/GNOME/gtk/blob/main/examples/application9/exampleappwin.c))
|
||||
|
||||
We also need a function that counts the lines of the currently active tab,
|
||||
and updates the `lines` label. See the [full source](https://gitlab.gnome.org/GNOME/gtk/blob/master/examples/application9/exampleappwin.c)
|
||||
and updates the `lines` label. See the [full source](https://gitlab.gnome.org/GNOME/gtk/blob/main/examples/application9/exampleappwin.c)
|
||||
if you are interested in the details.
|
||||
|
||||
This brings our example application to this appearance:
|
||||
|
||||
@@ -8,24 +8,10 @@ authors = "GTK Development Team"
|
||||
logo_url = "gtk-logo.svg"
|
||||
license = "LGPL-2.1-or-later"
|
||||
description = "The GTK toolkit"
|
||||
dependencies = [ "GObject-2.0", "Graphene-1.0", "Pango-1.0", "Gdk-4.0", "Gsk-4.0" ]
|
||||
devhelp = true
|
||||
search_index = true
|
||||
|
||||
[dependencies."GObject-2.0"]
|
||||
name = "GObject"
|
||||
description = "The base type system library"
|
||||
docs_url = "https://docs.gtk.org/gobject/"
|
||||
|
||||
[dependencies."Graphene-1.0"]
|
||||
name = "Graphene"
|
||||
description = "A thin layer of mathematical types for 3D libraries"
|
||||
docs_url = "https://ebassi.github.io/graphene/docs"
|
||||
|
||||
[dependencies."Pango-1.0"]
|
||||
name = "Pango"
|
||||
description = "Text shaping and rendering"
|
||||
docs_url = "https://docs.gtk.org/Pango/"
|
||||
dependencies = ["Gdk-4.0", "Gsk-4.0"]
|
||||
|
||||
[dependencies."Gdk-4.0"]
|
||||
name = "GDK"
|
||||
@@ -37,13 +23,35 @@ search_index = true
|
||||
description = "The GTK rendering abstraction"
|
||||
docs_url = "https://docs.gtk.org/gsk4/"
|
||||
|
||||
related = ["Pango-1.0", "Graphene-1.0", "GObject-2.0", "Gio-2.0"]
|
||||
|
||||
[related."GObject-2.0"]
|
||||
name = "GObject"
|
||||
description = "The base type system library"
|
||||
docs_url = "https://docs.gtk.org/gobject/"
|
||||
|
||||
[related."Gio-2.0"]
|
||||
name = "GIO"
|
||||
description = "GObject Interfaces and Objects, Networking, IPC, and I/O"
|
||||
docs_url = "https://docs.gtk.org/gio/"
|
||||
|
||||
[related."Graphene-1.0"]
|
||||
name = "Graphene"
|
||||
description = "A thin layer of mathematical types for 3D libraries"
|
||||
docs_url = "https://ebassi.github.io/graphene/docs"
|
||||
|
||||
[related."Pango-1.0"]
|
||||
name = "Pango"
|
||||
description = "Text shaping and rendering"
|
||||
docs_url = "https://docs.gtk.org/Pango/"
|
||||
|
||||
[theme]
|
||||
name = "basic"
|
||||
show_index_summary = true
|
||||
show_class_hierarchy = true
|
||||
|
||||
[source-location]
|
||||
base_url = "https://gitlab.gnome.org/GNOME/gtk/-/blob/master/"
|
||||
base_url = "https://gitlab.gnome.org/GNOME/gtk/-/blob/main/"
|
||||
|
||||
[extra]
|
||||
# The same order will be used when generating the index
|
||||
|
||||
@@ -42,7 +42,7 @@ univocally identifies events that are related to the same
|
||||
interaction.
|
||||
|
||||
When GTK creates a `GdkSurface`, it connects to the ::event
|
||||
signal on it, which receives all of these input events. Surfaces have
|
||||
signal on it, which receives all of these input events. Surfaces
|
||||
have signals and properties, e.g. to deal with window management
|
||||
related events.
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ if get_option('gtk_doc')
|
||||
)
|
||||
endif
|
||||
|
||||
rst2man = find_program('rst2man', required: false)
|
||||
rst2man = find_program('rst2man', 'rst2man.py', required: false)
|
||||
if get_option('man-pages') and not rst2man.found()
|
||||
error('No rst2man found, but man pages were explicitly enabled')
|
||||
endif
|
||||
|
||||
@@ -1276,6 +1276,15 @@ is provided in the form of a `GtkIconPaintable` (this can be checked with
|
||||
[method@Gtk.IconPaintable.is_symbolic]), you have to call
|
||||
[method@Gtk.IconPaintable.get_icon_name] and set the icon name on a `GtkImage`.
|
||||
|
||||
### Adapt to GtkImage changes
|
||||
`GtkPicture`'s behaviour was "split out" of `GtkImage` as the latter was covering
|
||||
too many use cases; if you're loading an icon, [class@Gtk.Image] in GTK3 and GTK4 are
|
||||
perfectly equivalent. If you are loading a more complex image asset, like a picture
|
||||
or a thumbnail, then [class@Gtk.Picture] is the appropriate widget.
|
||||
|
||||
One noteworthy distinction is that while `GtkImage` has its size computed by
|
||||
GTK, `GtkPicture` lets you decide about the size.
|
||||
|
||||
### Update to GtkFileChooser API changes
|
||||
|
||||
`GtkFileChooser` moved to a GFile-based API. If you need to convert a path
|
||||
@@ -1373,5 +1382,5 @@ a new family of widgets for this purpose that uses list models instead
|
||||
of tree models, and widgets instead of cell renderers.
|
||||
|
||||
To learn more about the new list widgets, you can read the [List Widget
|
||||
Overview](#ListWidget).
|
||||
Overview](https://docs.gtk.org/gtk4/section-list-widget.html).
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ GTK with your code applied, and run the test suite, on multiple platforms
|
||||
and architectures, and verify that nothing breaks. They also allow us to
|
||||
do proper code reviews, so we can iterate over the changes.
|
||||
|
||||
You should follow the [contribution guide](https://gitlab.gnome.org/GNOME/gtk/blob/master/CONTRIBUTING.md)
|
||||
You should follow the [contribution guide](https://gitlab.gnome.org/GNOME/gtk/blob/main/CONTRIBUTING.md)
|
||||
for GTK, available on GitLab.
|
||||
|
||||
If you want to discuss your approach before or after working on it,
|
||||
|
||||
@@ -286,7 +286,7 @@ requires that GTK is compiled with support for that backend.
|
||||
The following backends can be selected, provided they are
|
||||
included in the GDK libraries you are using:
|
||||
|
||||
`quartz`
|
||||
`macos`
|
||||
: Selects the native Quartz backend
|
||||
|
||||
`win32`
|
||||
@@ -336,9 +336,6 @@ using and the GDK backend supports them:
|
||||
`gl`
|
||||
: Selects the "gl" OpenGL renderer
|
||||
|
||||
`ngl`
|
||||
: Selects the "ngl" OpenGL renderer
|
||||
|
||||
`vulkan`
|
||||
: Selects the Vulkan renderer
|
||||
|
||||
@@ -375,7 +372,7 @@ library you are using:
|
||||
The `test` accessibility backend is recommended for test suites and remote
|
||||
continuous integration pipelines.
|
||||
|
||||
### `XDG_DTA_HOME`, `XDG_DATA_DIRS`
|
||||
### `XDG_DATA_HOME`, `XDG_DATA_DIRS`
|
||||
|
||||
GTK uses these environment variables to locate icon themes
|
||||
and MIME information. For more information, see the
|
||||
|
||||
@@ -354,6 +354,7 @@ typedef struct {
|
||||
|
||||
typedef union {
|
||||
BroadwayReplyBase base;
|
||||
BroadwayReplySync sync;
|
||||
BroadwayReplyEvent event;
|
||||
BroadwayReplyQueryMouse query_mouse;
|
||||
BroadwayReplyNewSurface new_surface;
|
||||
|
||||
@@ -219,11 +219,7 @@ static void
|
||||
client_handle_request (BroadwayClient *client,
|
||||
BroadwayRequest *request)
|
||||
{
|
||||
BroadwayReplyNewSurface reply_new_surface;
|
||||
BroadwayReplySync reply_sync;
|
||||
BroadwayReplyQueryMouse reply_query_mouse;
|
||||
BroadwayReplyGrabPointer reply_grab_pointer;
|
||||
BroadwayReplyUngrabPointer reply_ungrab_pointer;
|
||||
BroadwayReply reply;
|
||||
guint32 before_serial, now_serial;
|
||||
guint32 global_id;
|
||||
int fd;
|
||||
@@ -233,7 +229,7 @@ client_handle_request (BroadwayClient *client,
|
||||
switch (request->base.type)
|
||||
{
|
||||
case BROADWAY_REQUEST_NEW_SURFACE:
|
||||
reply_new_surface.id =
|
||||
reply.new_surface.id =
|
||||
broadway_server_new_surface (server, client->id,
|
||||
request->new_surface.x,
|
||||
request->new_surface.y,
|
||||
@@ -241,9 +237,9 @@ client_handle_request (BroadwayClient *client,
|
||||
request->new_surface.height);
|
||||
client->surfaces =
|
||||
g_list_prepend (client->surfaces,
|
||||
GUINT_TO_POINTER (reply_new_surface.id));
|
||||
GUINT_TO_POINTER (reply.new_surface.id));
|
||||
|
||||
send_reply (client, request, (BroadwayReply *)&reply_new_surface, sizeof (reply_new_surface),
|
||||
send_reply (client, request, &reply, sizeof (reply.new_surface),
|
||||
BROADWAY_REPLY_NEW_SURFACE);
|
||||
break;
|
||||
case BROADWAY_REQUEST_FLUSH:
|
||||
@@ -251,7 +247,7 @@ client_handle_request (BroadwayClient *client,
|
||||
break;
|
||||
case BROADWAY_REQUEST_SYNC:
|
||||
broadway_server_flush (server);
|
||||
send_reply (client, request, (BroadwayReply *)&reply_sync, sizeof (reply_sync),
|
||||
send_reply (client, request, &reply, sizeof (reply.sync),
|
||||
BROADWAY_REPLY_SYNC);
|
||||
break;
|
||||
case BROADWAY_REQUEST_ROUNDTRIP:
|
||||
@@ -261,11 +257,11 @@ client_handle_request (BroadwayClient *client,
|
||||
break;
|
||||
case BROADWAY_REQUEST_QUERY_MOUSE:
|
||||
broadway_server_query_mouse (server,
|
||||
&reply_query_mouse.surface,
|
||||
&reply_query_mouse.root_x,
|
||||
&reply_query_mouse.root_y,
|
||||
&reply_query_mouse.mask);
|
||||
send_reply (client, request, (BroadwayReply *)&reply_query_mouse, sizeof (reply_query_mouse),
|
||||
&reply.query_mouse.surface,
|
||||
&reply.query_mouse.root_x,
|
||||
&reply.query_mouse.root_y,
|
||||
&reply.query_mouse.mask);
|
||||
send_reply (client, request, &reply, sizeof (reply.query_mouse),
|
||||
BROADWAY_REPLY_QUERY_MOUSE);
|
||||
break;
|
||||
case BROADWAY_REQUEST_DESTROY_SURFACE:
|
||||
@@ -361,21 +357,21 @@ client_handle_request (BroadwayClient *client,
|
||||
request->move_resize.height);
|
||||
break;
|
||||
case BROADWAY_REQUEST_GRAB_POINTER:
|
||||
reply_grab_pointer.status =
|
||||
reply.grab_pointer.status =
|
||||
broadway_server_grab_pointer (server,
|
||||
client->id,
|
||||
request->grab_pointer.id,
|
||||
request->grab_pointer.owner_events,
|
||||
request->grab_pointer.event_mask,
|
||||
request->grab_pointer.time_);
|
||||
send_reply (client, request, (BroadwayReply *)&reply_grab_pointer, sizeof (reply_grab_pointer),
|
||||
send_reply (client, request, &reply, sizeof (reply.grab_pointer),
|
||||
BROADWAY_REPLY_GRAB_POINTER);
|
||||
break;
|
||||
case BROADWAY_REQUEST_UNGRAB_POINTER:
|
||||
reply_ungrab_pointer.status =
|
||||
reply.ungrab_pointer.status =
|
||||
broadway_server_ungrab_pointer (server,
|
||||
request->ungrab_pointer.time_);
|
||||
send_reply (client, request, (BroadwayReply *)&reply_ungrab_pointer, sizeof (reply_ungrab_pointer),
|
||||
send_reply (client, request, &reply, sizeof (reply.ungrab_pointer),
|
||||
BROADWAY_REPLY_UNGRAB_POINTER);
|
||||
break;
|
||||
case BROADWAY_REQUEST_FOCUS_SURFACE:
|
||||
|
||||
@@ -97,7 +97,7 @@ add_files (GDBusProxy *proxy,
|
||||
AddFileData *afd)
|
||||
{
|
||||
GUnixFDList *fd_list;
|
||||
GVariantBuilder fds;
|
||||
GVariantBuilder fds, options;
|
||||
int i;
|
||||
char *key;
|
||||
|
||||
@@ -146,9 +146,10 @@ add_files (GDBusProxy *proxy,
|
||||
|
||||
key = (char *)g_object_get_data (G_OBJECT (afd->task), "key");
|
||||
|
||||
g_variant_builder_init (&options, G_VARIANT_TYPE_VARDICT);
|
||||
g_dbus_proxy_call_with_unix_fd_list (proxy,
|
||||
"AddFiles",
|
||||
g_variant_new ("(sah)", key, &fds),
|
||||
g_variant_new ("(saha{sv})", key, &fds, &options),
|
||||
0, -1,
|
||||
fd_list,
|
||||
NULL,
|
||||
@@ -480,20 +481,36 @@ connection_closed (GDBusConnection *connection,
|
||||
}
|
||||
|
||||
static void
|
||||
got_proxy (GObject *source,
|
||||
GAsyncResult *result,
|
||||
gpointer data)
|
||||
finish_registration (void)
|
||||
{
|
||||
GError *error = NULL;
|
||||
gdk_content_register_serializer (G_TYPE_FILE,
|
||||
"application/vnd.portal.filetransfer",
|
||||
portal_file_serializer,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
file_transfer_proxy = g_dbus_proxy_new_for_bus_finish (result, &error);
|
||||
if (!file_transfer_proxy)
|
||||
{
|
||||
g_message ("Failed to get file transfer portal: %s", error->message);
|
||||
g_clear_error (&error);
|
||||
return;
|
||||
}
|
||||
gdk_content_register_serializer (GDK_TYPE_FILE_LIST,
|
||||
"application/vnd.portal.filetransfer",
|
||||
portal_file_serializer,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
gdk_content_register_deserializer ("application/vnd.portal.filetransfer",
|
||||
GDK_TYPE_FILE_LIST,
|
||||
portal_file_deserializer,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
gdk_content_register_deserializer ("application/vnd.portal.filetransfer",
|
||||
G_TYPE_FILE,
|
||||
portal_file_deserializer,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
/* FIXME: I missed up and used the wrong mime type here when
|
||||
* I implemented my own protocol. Keep these around for a while
|
||||
* so we can interoperate with existing flatpaks using GTK 4.6
|
||||
*/
|
||||
gdk_content_register_serializer (G_TYPE_FILE,
|
||||
"application/vnd.portal.files",
|
||||
portal_file_serializer,
|
||||
@@ -523,6 +540,21 @@ got_proxy (GObject *source,
|
||||
"closed", G_CALLBACK (connection_closed), NULL);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
proxy_has_owner (GDBusProxy *proxy)
|
||||
{
|
||||
char *owner;
|
||||
|
||||
owner = g_dbus_proxy_get_name_owner (proxy);
|
||||
if (owner)
|
||||
{
|
||||
g_free (owner);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
file_transfer_portal_register (void)
|
||||
{
|
||||
@@ -531,7 +563,8 @@ file_transfer_portal_register (void)
|
||||
if (!called)
|
||||
{
|
||||
called = TRUE;
|
||||
g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION,
|
||||
|
||||
file_transfer_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
|
||||
G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES
|
||||
| G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS
|
||||
| G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
|
||||
@@ -540,8 +573,13 @@ file_transfer_portal_register (void)
|
||||
"/org/freedesktop/portal/documents",
|
||||
"org.freedesktop.portal.FileTransfer",
|
||||
NULL,
|
||||
got_proxy,
|
||||
NULL);
|
||||
|
||||
if (file_transfer_proxy && !proxy_has_owner (file_transfer_proxy))
|
||||
g_clear_object (&file_transfer_proxy);
|
||||
|
||||
if (file_transfer_proxy)
|
||||
finish_registration ();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -31,8 +31,7 @@
|
||||
* `GdkAppLaunchContext` handles launching an application in a graphical context.
|
||||
*
|
||||
* It is an implementation of `GAppLaunchContext` that provides startup
|
||||
* notification and allows to launch applications on a specific screen
|
||||
* or workspace.
|
||||
* notification and allows to launch applications on a specific workspace.
|
||||
*
|
||||
* ## Launching an application
|
||||
*
|
||||
@@ -41,7 +40,6 @@
|
||||
*
|
||||
* context = gdk_display_get_app_launch_context (display);
|
||||
*
|
||||
* gdk_app_launch_context_set_display (display);
|
||||
* gdk_app_launch_context_set_timestamp (gdk_event_get_time (event));
|
||||
*
|
||||
* if (!g_app_info_launch_default_for_uri ("http://www.gtk.org", context, &error))
|
||||
@@ -196,6 +194,10 @@ gdk_app_launch_context_get_display (GdkAppLaunchContext *context)
|
||||
* This only works when running under a window manager that
|
||||
* supports multiple workspaces, as described in the
|
||||
* [Extended Window Manager Hints](http://www.freedesktop.org/Standards/wm-spec).
|
||||
* Specifically this sets the `_NET_WM_DESKTOP` property described
|
||||
* in that spec.
|
||||
*
|
||||
* This only works when using the X11 backend.
|
||||
*
|
||||
* When the workspace is not specified or @desktop is set to -1,
|
||||
* it is up to the window manager to pick one, typically it will
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
|
||||
typedef struct _Deserializer Deserializer;
|
||||
|
||||
struct _Deserializer
|
||||
struct _Deserializer
|
||||
{
|
||||
const char * mime_type; /* interned */
|
||||
GType type;
|
||||
@@ -264,7 +264,7 @@ gdk_content_deserializer_get_priority (GdkContentDeserializer *deserializer)
|
||||
*
|
||||
* This is the `GCancellable` that was passed to [func@Gdk.content_deserialize_async].
|
||||
*
|
||||
* Returns: (transfer none): the cancellable for the current operation
|
||||
* Returns: (transfer none) (nullable): the cancellable for the current operation
|
||||
*/
|
||||
GCancellable *
|
||||
gdk_content_deserializer_get_cancellable (GdkContentDeserializer *deserializer)
|
||||
@@ -407,8 +407,6 @@ gdk_content_register_deserializer (const char *mime_type,
|
||||
g_return_if_fail (mime_type != NULL);
|
||||
g_return_if_fail (deserialize != NULL);
|
||||
|
||||
init ();
|
||||
|
||||
deserializer = g_slice_new0 (Deserializer);
|
||||
|
||||
deserializer->mime_type = g_intern_string (mime_type);
|
||||
@@ -576,7 +574,7 @@ gdk_content_deserialize_async (GInputStream *stream,
|
||||
/**
|
||||
* gdk_content_deserialize_finish:
|
||||
* @result: the `GAsyncResult`
|
||||
* @value: return location for the result of the operation
|
||||
* @value: (out): return location for the result of the operation
|
||||
* @error: return location for an error
|
||||
*
|
||||
* Finishes a content deserialization operation.
|
||||
@@ -934,25 +932,6 @@ init (void)
|
||||
|
||||
formats = gdk_pixbuf_get_formats ();
|
||||
|
||||
/* Make sure png comes first */
|
||||
for (f = formats; f; f = f->next)
|
||||
{
|
||||
GdkPixbufFormat *fmt = f->data;
|
||||
char *name;
|
||||
|
||||
name = gdk_pixbuf_format_get_name (fmt);
|
||||
if (g_str_equal (name, "png"))
|
||||
{
|
||||
formats = g_slist_delete_link (formats, f);
|
||||
formats = g_slist_prepend (formats, fmt);
|
||||
|
||||
g_free (name);
|
||||
break;
|
||||
}
|
||||
|
||||
g_free (name);
|
||||
}
|
||||
|
||||
for (f = formats; f; f = f->next)
|
||||
{
|
||||
GdkPixbufFormat *fmt = f->data;
|
||||
|
||||
@@ -718,19 +718,33 @@ gdk_content_formats_builder_to_formats (GdkContentFormatsBuilder *builder)
|
||||
|
||||
g_return_val_if_fail (builder != NULL, NULL);
|
||||
|
||||
gtypes = g_new (GType, builder->n_gtypes + 1);
|
||||
i = builder->n_gtypes;
|
||||
gtypes[i--] = G_TYPE_INVALID;
|
||||
/* add backwards because most important type is last in the list */
|
||||
for (l = builder->gtypes; l; l = l->next)
|
||||
gtypes[i--] = GPOINTER_TO_SIZE (l->data);
|
||||
if (builder->n_gtypes > 0)
|
||||
{
|
||||
gtypes = g_new (GType, builder->n_gtypes + 1);
|
||||
i = builder->n_gtypes;
|
||||
gtypes[i--] = G_TYPE_INVALID;
|
||||
/* add backwards because most important type is last in the list */
|
||||
for (l = builder->gtypes; l; l = l->next)
|
||||
gtypes[i--] = GPOINTER_TO_SIZE (l->data);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtypes = NULL;
|
||||
}
|
||||
|
||||
mime_types = g_new (const char *, builder->n_mime_types + 1);
|
||||
i = builder->n_mime_types;
|
||||
mime_types[i--] = NULL;
|
||||
/* add backwards because most important type is last in the list */
|
||||
for (l = builder->mime_types; l; l = l->next)
|
||||
mime_types[i--] = l->data;
|
||||
if (builder->n_mime_types > 0)
|
||||
{
|
||||
mime_types = g_new (const char *, builder->n_mime_types + 1);
|
||||
i = builder->n_mime_types;
|
||||
mime_types[i--] = NULL;
|
||||
/* add backwards because most important type is last in the list */
|
||||
for (l = builder->mime_types; l; l = l->next)
|
||||
mime_types[i--] = l->data;
|
||||
}
|
||||
else
|
||||
{
|
||||
mime_types = NULL;
|
||||
}
|
||||
|
||||
result = gdk_content_formats_new_take (gtypes, builder->n_gtypes,
|
||||
mime_types, builder->n_mime_types);
|
||||
|
||||
@@ -342,7 +342,7 @@ gdk_content_provider_write_mime_type_finish (GdkContentProvider *provider,
|
||||
/**
|
||||
* gdk_content_provider_get_value:
|
||||
* @provider: a `GdkContentProvider`
|
||||
* @value: the `GValue` to fill
|
||||
* @value: (out caller-allocates): the `GValue` to fill
|
||||
* @error: a `GError` location to store the error occurring
|
||||
*
|
||||
* Gets the contents of @provider stored in @value.
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
|
||||
typedef struct _Serializer Serializer;
|
||||
|
||||
struct _Serializer
|
||||
struct _Serializer
|
||||
{
|
||||
const char * mime_type; /* interned */
|
||||
GType type;
|
||||
@@ -270,7 +270,7 @@ gdk_content_serializer_get_priority (GdkContentSerializer *serializer)
|
||||
*
|
||||
* This is the `GCancellable` that was passed to [func@content_serialize_async].
|
||||
*
|
||||
* Returns: (transfer none): the cancellable for the current operation
|
||||
* Returns: (transfer none) (nullable): the cancellable for the current operation
|
||||
*/
|
||||
GCancellable *
|
||||
gdk_content_serializer_get_cancellable (GdkContentSerializer *serializer)
|
||||
@@ -413,8 +413,6 @@ gdk_content_register_serializer (GType type,
|
||||
g_return_if_fail (mime_type != NULL);
|
||||
g_return_if_fail (serialize != NULL);
|
||||
|
||||
init ();
|
||||
|
||||
serializer = g_slice_new0 (Serializer);
|
||||
|
||||
serializer->mime_type = g_intern_string (mime_type);
|
||||
@@ -446,7 +444,7 @@ lookup_serializer (const char *mime_type,
|
||||
serializer->type == type)
|
||||
return serializer;
|
||||
}
|
||||
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -630,7 +628,7 @@ pixbuf_serializer (GdkContentSerializer *serializer)
|
||||
const GValue *value;
|
||||
GdkPixbuf *pixbuf;
|
||||
const char *name;
|
||||
|
||||
|
||||
name = gdk_content_serializer_get_user_data (serializer);
|
||||
value = gdk_content_serializer_get_value (serializer);
|
||||
|
||||
@@ -651,7 +649,7 @@ pixbuf_serializer (GdkContentSerializer *serializer)
|
||||
gdk_pixbuf_save_to_stream_async (pixbuf,
|
||||
gdk_content_serializer_get_output_stream (serializer),
|
||||
name,
|
||||
gdk_content_serializer_get_cancellable (serializer),
|
||||
gdk_content_serializer_get_cancellable (serializer),
|
||||
pixbuf_serializer_finish,
|
||||
serializer,
|
||||
g_str_equal (name, "png") ? "compression" : NULL, "2",
|
||||
@@ -823,7 +821,7 @@ file_uri_serializer (GdkContentSerializer *serializer)
|
||||
else if (G_VALUE_HOLDS (value, GDK_TYPE_FILE_LIST))
|
||||
{
|
||||
GSList *l;
|
||||
|
||||
|
||||
for (l = g_value_get_boxed (value); l; l = l->next)
|
||||
{
|
||||
uri = g_file_get_uri (l->data);
|
||||
@@ -867,7 +865,7 @@ file_text_serializer (GdkContentSerializer *serializer)
|
||||
{
|
||||
GString *str;
|
||||
GSList *l;
|
||||
|
||||
|
||||
str = g_string_new (NULL);
|
||||
|
||||
for (l = g_value_get_boxed (value); l; l = l->next)
|
||||
@@ -966,25 +964,6 @@ init (void)
|
||||
|
||||
formats = gdk_pixbuf_get_formats ();
|
||||
|
||||
/* Make sure png comes first */
|
||||
for (f = formats; f; f = f->next)
|
||||
{
|
||||
GdkPixbufFormat *fmt = f->data;
|
||||
char *name;
|
||||
|
||||
name = gdk_pixbuf_format_get_name (fmt);
|
||||
if (g_str_equal (name, "png"))
|
||||
{
|
||||
formats = g_slist_delete_link (formats, f);
|
||||
formats = g_slist_prepend (formats, fmt);
|
||||
|
||||
g_free (name);
|
||||
break;
|
||||
}
|
||||
|
||||
g_free (name);
|
||||
}
|
||||
|
||||
for (f = formats; f; f = f->next)
|
||||
{
|
||||
GdkPixbufFormat *fmt = f->data;
|
||||
|
||||
@@ -47,8 +47,7 @@
|
||||
* Cursors by themselves are not very interesting: they must be bound to a
|
||||
* window for users to see them. This is done with [method@Gdk.Surface.set_cursor]
|
||||
* or [method@Gdk.Surface.set_device_cursor]. Applications will typically
|
||||
* use higher-level GTK functions such as [method@Gtk.Widget.set_cursor]`
|
||||
* instead.
|
||||
* use higher-level GTK functions such as [method@Gtk.Widget.set_cursor] instead.
|
||||
*
|
||||
* Cursors are not bound to a given [class@Gdk.Display], so they can be shared.
|
||||
* However, the appearance of cursors may vary when used on different
|
||||
|
||||
@@ -1238,7 +1238,7 @@ gdk_device_get_num_touches (GdkDevice *device)
|
||||
*
|
||||
* Retrieves the current tool for @device.
|
||||
*
|
||||
* Returns: (transfer none): the `GdkDeviceTool`
|
||||
* Returns: (transfer none) (nullable): the `GdkDeviceTool`
|
||||
*/
|
||||
GdkDeviceTool *
|
||||
gdk_device_get_device_tool (GdkDevice *device)
|
||||
|
||||
@@ -1628,10 +1628,10 @@ gdk_display_check_egl_extensions (EGLDisplay egl_display,
|
||||
/* translators: Arguments are the number of missing extensions
|
||||
* followed by a comma-separated list of their names */
|
||||
g_dngettext (GETTEXT_PACKAGE,
|
||||
"EGL implementation is missing extension %2$s",
|
||||
"EGL implementation is missing %d extensions: %s",
|
||||
"EGL implementation is missing extension %s",
|
||||
"EGL implementation is missing %2$d extensions: %1$s",
|
||||
n_missing),
|
||||
(int) n_missing, missing->str);
|
||||
missing->str, (int) n_missing);
|
||||
|
||||
g_string_free (missing, TRUE);
|
||||
return FALSE;
|
||||
@@ -1721,12 +1721,12 @@ gdk_display_init_egl (GdkDisplay *self,
|
||||
|
||||
self->have_egl_buffer_age =
|
||||
epoxy_has_egl_extension (priv->egl_display, "EGL_EXT_buffer_age");
|
||||
self->have_egl_swap_buffers_with_damage =
|
||||
epoxy_has_egl_extension (priv->egl_display, "EGL_EXT_swap_buffers_with_damage");
|
||||
self->have_egl_no_config_context =
|
||||
epoxy_has_egl_extension (priv->egl_display, "EGL_KHR_no_config_context");
|
||||
self->have_egl_pixel_format_float =
|
||||
epoxy_has_egl_extension (priv->egl_display, "EGL_EXT_pixel_format_float");
|
||||
self->have_egl_win32_libangle =
|
||||
epoxy_has_egl_extension (priv->egl_display, "EGL_ANGLE_d3d_share_handle_client_buffer");
|
||||
|
||||
if (self->have_egl_no_config_context)
|
||||
priv->egl_config_high_depth = gdk_display_create_egl_config (self,
|
||||
|
||||
@@ -107,9 +107,9 @@ struct _GdkDisplay
|
||||
|
||||
/* egl info */
|
||||
guint have_egl_buffer_age : 1;
|
||||
guint have_egl_swap_buffers_with_damage : 1;
|
||||
guint have_egl_no_config_context : 1;
|
||||
guint have_egl_pixel_format_float : 1;
|
||||
guint have_egl_win32_libangle : 1;
|
||||
};
|
||||
|
||||
struct _GdkDisplayClass
|
||||
|
||||
265
gdk/gdkevents.c
265
gdk/gdkevents.c
@@ -19,7 +19,7 @@
|
||||
* Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
|
||||
* file for a list of people on the GTK+ Team. See the ChangeLog
|
||||
* files for a list of changes. These files are distributed with
|
||||
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
|
||||
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
@@ -522,7 +522,9 @@ _gdk_event_queue_find_first (GdkDisplay *display)
|
||||
if (pending_motion)
|
||||
return pending_motion;
|
||||
|
||||
if (event->event_type == GDK_MOTION_NOTIFY && (event->flags & GDK_EVENT_FLUSHED) == 0)
|
||||
if ((event->event_type == GDK_MOTION_NOTIFY ||
|
||||
(event->event_type == GDK_SCROLL && gdk_scroll_event_get_direction (event) == GDK_SCROLL_SMOOTH)) &&
|
||||
(event->flags & GDK_EVENT_FLUSHED) == 0)
|
||||
pending_motion = tmp_list;
|
||||
else
|
||||
return tmp_list;
|
||||
@@ -596,6 +598,9 @@ _gdk_event_unqueue (GdkDisplay *display)
|
||||
/*
|
||||
* If the last N events in the event queue are smooth scroll events
|
||||
* for the same surface and device, combine them into one.
|
||||
*
|
||||
* We give the remaining event a history with N items, and deltas
|
||||
* that are the sum over the history entries.
|
||||
*/
|
||||
void
|
||||
gdk_event_queue_handle_scroll_compression (GdkDisplay *display)
|
||||
@@ -605,7 +610,6 @@ gdk_event_queue_handle_scroll_compression (GdkDisplay *display)
|
||||
GdkDevice *device = NULL;
|
||||
GdkEvent *last_event = NULL;
|
||||
GList *scrolls = NULL;
|
||||
double delta_x, delta_y;
|
||||
GArray *history = NULL;
|
||||
GdkTimeCoord hist;
|
||||
|
||||
@@ -640,35 +644,42 @@ gdk_event_queue_handle_scroll_compression (GdkDisplay *display)
|
||||
l = l->prev;
|
||||
}
|
||||
|
||||
delta_x = delta_y = 0;
|
||||
|
||||
while (scrolls && scrolls->next != NULL)
|
||||
{
|
||||
GdkEvent *event = scrolls->data;
|
||||
GList *next = scrolls->next;
|
||||
double dx, dy;
|
||||
gboolean inherited = FALSE;
|
||||
|
||||
if (!history && ((GdkScrollEvent *)event)->history)
|
||||
{
|
||||
history = ((GdkScrollEvent *)event)->history;
|
||||
((GdkScrollEvent *)event)->history = NULL;
|
||||
inherited = TRUE;
|
||||
}
|
||||
|
||||
if (!history)
|
||||
history = g_array_new (FALSE, TRUE, sizeof (GdkTimeCoord));
|
||||
|
||||
gdk_scroll_event_get_deltas (event, &dx, &dy);
|
||||
delta_x += dx;
|
||||
delta_y += dy;
|
||||
if (!inherited)
|
||||
{
|
||||
gdk_scroll_event_get_deltas (event, &dx, &dy);
|
||||
|
||||
memset (&hist, 0, sizeof (GdkTimeCoord));
|
||||
hist.time = gdk_event_get_time (event);
|
||||
hist.flags = GDK_AXIS_FLAG_DELTA_X | GDK_AXIS_FLAG_DELTA_Y;
|
||||
hist.axes[GDK_AXIS_DELTA_X] = dx;
|
||||
hist.axes[GDK_AXIS_DELTA_Y] = dy;
|
||||
memset (&hist, 0, sizeof (GdkTimeCoord));
|
||||
hist.time = gdk_event_get_time (event);
|
||||
hist.flags = GDK_AXIS_FLAG_DELTA_X | GDK_AXIS_FLAG_DELTA_Y;
|
||||
hist.axes[GDK_AXIS_DELTA_X] = dx;
|
||||
hist.axes[GDK_AXIS_DELTA_Y] = dy;
|
||||
|
||||
g_array_append_val (history, hist);
|
||||
g_array_append_val (history, hist);
|
||||
}
|
||||
|
||||
gdk_event_unref (event);
|
||||
g_queue_delete_link (&display->queued_events, scrolls);
|
||||
scrolls = next;
|
||||
}
|
||||
|
||||
if (scrolls)
|
||||
if (scrolls && history)
|
||||
{
|
||||
GdkEvent *old_event, *event;
|
||||
double dx, dy;
|
||||
@@ -676,13 +687,29 @@ gdk_event_queue_handle_scroll_compression (GdkDisplay *display)
|
||||
old_event = scrolls->data;
|
||||
|
||||
gdk_scroll_event_get_deltas (old_event, &dx, &dy);
|
||||
|
||||
memset (&hist, 0, sizeof (GdkTimeCoord));
|
||||
hist.time = gdk_event_get_time (old_event);
|
||||
hist.flags = GDK_AXIS_FLAG_DELTA_X | GDK_AXIS_FLAG_DELTA_Y;
|
||||
hist.axes[GDK_AXIS_DELTA_X] = dx;
|
||||
hist.axes[GDK_AXIS_DELTA_Y] = dy;
|
||||
g_array_append_val (history, hist);
|
||||
|
||||
dx = dy = 0;
|
||||
for (int i = 0; i < history->len; i++)
|
||||
{
|
||||
GdkTimeCoord *val = &g_array_index (history, GdkTimeCoord, i);
|
||||
dx += val->axes[GDK_AXIS_DELTA_X];
|
||||
dy += val->axes[GDK_AXIS_DELTA_Y];
|
||||
}
|
||||
|
||||
event = gdk_scroll_event_new (surface,
|
||||
device,
|
||||
gdk_event_get_device_tool (old_event),
|
||||
gdk_event_get_time (old_event),
|
||||
gdk_event_get_modifier_state (old_event),
|
||||
delta_x + dx,
|
||||
delta_y + dy,
|
||||
dx,
|
||||
dy,
|
||||
gdk_scroll_event_is_stop (old_event));
|
||||
|
||||
((GdkScrollEvent *)event)->history = history;
|
||||
@@ -692,14 +719,6 @@ gdk_event_queue_handle_scroll_compression (GdkDisplay *display)
|
||||
|
||||
gdk_event_unref (old_event);
|
||||
}
|
||||
|
||||
if (g_queue_get_length (&display->queued_events) == 1 &&
|
||||
g_queue_peek_head_link (&display->queued_events) == scrolls)
|
||||
{
|
||||
GdkFrameClock *clock = gdk_surface_get_frame_clock (surface);
|
||||
if (clock) /* might be NULL if surface was destroyed */
|
||||
gdk_frame_clock_request_phase (clock, GDK_FRAME_CLOCK_PHASE_FLUSH_EVENTS);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -714,24 +733,41 @@ gdk_motion_event_push_history (GdkEvent *event,
|
||||
g_assert (GDK_IS_EVENT_TYPE (event, GDK_MOTION_NOTIFY));
|
||||
g_assert (GDK_IS_EVENT_TYPE (history_event, GDK_MOTION_NOTIFY));
|
||||
|
||||
if (!self->tool)
|
||||
return;
|
||||
if (G_UNLIKELY (!self->history))
|
||||
self->history = g_array_new (FALSE, TRUE, sizeof (GdkTimeCoord));
|
||||
|
||||
if (((GdkMotionEvent *)history_event)->history)
|
||||
{
|
||||
GArray *history = ((GdkMotionEvent *)history_event)->history;
|
||||
g_array_append_vals (self->history, history->data, history->len);
|
||||
}
|
||||
|
||||
tool = gdk_event_get_device_tool (history_event);
|
||||
|
||||
memset (&hist, 0, sizeof (GdkTimeCoord));
|
||||
hist.time = gdk_event_get_time (history_event);
|
||||
hist.flags = gdk_device_tool_get_axes (tool);
|
||||
|
||||
for (i = GDK_AXIS_X; i < GDK_AXIS_LAST; i++)
|
||||
gdk_event_get_axis (history_event, i, &hist.axes[i]);
|
||||
|
||||
if (G_UNLIKELY (!self->history))
|
||||
self->history = g_array_new (FALSE, TRUE, sizeof (GdkTimeCoord));
|
||||
if (tool)
|
||||
{
|
||||
hist.flags = gdk_device_tool_get_axes (tool);
|
||||
for (i = GDK_AXIS_X; i < GDK_AXIS_LAST; i++)
|
||||
gdk_event_get_axis (history_event, i, &hist.axes[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
hist.flags = GDK_AXIS_FLAG_X | GDK_AXIS_FLAG_Y;
|
||||
gdk_event_get_position (history_event, &hist.axes[GDK_AXIS_X], &hist.axes[GDK_AXIS_Y]);
|
||||
}
|
||||
|
||||
g_array_append_val (self->history, hist);
|
||||
}
|
||||
|
||||
/* If the last N events in the event queue are motion notify
|
||||
* events for the same surface, drop all but the last.
|
||||
*
|
||||
* If a button is held down or the device has a tool, then
|
||||
* we give the remaining events a history containing the N-1
|
||||
* dropped events.
|
||||
*/
|
||||
void
|
||||
_gdk_event_queue_handle_motion_compression (GdkDisplay *display)
|
||||
{
|
||||
@@ -741,9 +777,6 @@ _gdk_event_queue_handle_motion_compression (GdkDisplay *display)
|
||||
GdkDevice *pending_motion_device = NULL;
|
||||
GdkEvent *last_motion = NULL;
|
||||
|
||||
/* If the last N events in the event queue are motion notify
|
||||
* events for the same surface, drop all but the last */
|
||||
|
||||
tmp_list = g_queue_peek_tail_link (&display->queued_events);
|
||||
|
||||
while (tmp_list)
|
||||
@@ -780,26 +813,17 @@ _gdk_event_queue_handle_motion_compression (GdkDisplay *display)
|
||||
|
||||
if (last_motion != NULL)
|
||||
{
|
||||
GdkModifierType state = gdk_event_get_modifier_state (last_motion);
|
||||
|
||||
if (state &
|
||||
(GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK |
|
||||
GDK_BUTTON4_MASK | GDK_BUTTON5_MASK))
|
||||
gdk_motion_event_push_history (last_motion, pending_motions->data);
|
||||
if ((gdk_event_get_modifier_state (last_motion) &
|
||||
(GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK |
|
||||
GDK_BUTTON4_MASK | GDK_BUTTON5_MASK)) ||
|
||||
gdk_event_get_device_tool (last_motion) != NULL)
|
||||
gdk_motion_event_push_history (last_motion, pending_motions->data);
|
||||
}
|
||||
|
||||
gdk_event_unref (pending_motions->data);
|
||||
g_queue_delete_link (&display->queued_events, pending_motions);
|
||||
pending_motions = next;
|
||||
}
|
||||
|
||||
if (g_queue_get_length (&display->queued_events) == 1 &&
|
||||
g_queue_peek_head_link (&display->queued_events) == pending_motions)
|
||||
{
|
||||
GdkFrameClock *clock = gdk_surface_get_frame_clock (pending_motion_surface);
|
||||
if (clock) /* might be NULL if surface was destroyed */
|
||||
gdk_frame_clock_request_phase (clock, GDK_FRAME_CLOCK_PHASE_FLUSH_EVENTS);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@@ -903,6 +927,9 @@ gdk_event_get_pointer_emulated (GdkEvent *event)
|
||||
* Extract the axis value for a particular axis use from
|
||||
* an event structure.
|
||||
*
|
||||
* To find out which axes are used, use [method@Gdk.DeviceTool.get_axes]
|
||||
* on the device tool returned by [method@Gdk.Event.get_device_tool].
|
||||
*
|
||||
* Returns: %TRUE if the specified axis was found, otherwise %FALSE
|
||||
*/
|
||||
gboolean
|
||||
@@ -1129,6 +1156,9 @@ G_DEFINE_BOXED_TYPE (GdkEventSequence, gdk_event_sequence,
|
||||
*
|
||||
* Extracts all axis values from an event.
|
||||
*
|
||||
* To find out which axes are used, use [method@Gdk.DeviceTool.get_axes]
|
||||
* on the device tool returned by [method@Gdk.Event.get_device_tool].
|
||||
*
|
||||
* Returns: %TRUE on success, otherwise %FALSE
|
||||
*/
|
||||
gboolean
|
||||
@@ -1179,7 +1209,7 @@ gdk_event_get_event_type (GdkEvent *event)
|
||||
*
|
||||
* Extracts the surface associated with an event.
|
||||
*
|
||||
* Returns: (transfer none): The `GdkSurface` associated with the event
|
||||
* Returns: (transfer none) (nullable): The `GdkSurface` associated with the event
|
||||
*/
|
||||
GdkSurface *
|
||||
gdk_event_get_surface (GdkEvent *event)
|
||||
@@ -1734,7 +1764,7 @@ gdk_key_event_matches (GdkEvent *event,
|
||||
guint ev_keyval;
|
||||
int layout;
|
||||
int level;
|
||||
GdkModifierType consumed_modifiers;
|
||||
GdkModifierType ignored_modifiers;
|
||||
GdkModifierType shift_group_mask;
|
||||
gboolean group_mod_is_accel_mod = FALSE;
|
||||
const GdkModifierType mask = GDK_CONTROL_MASK |
|
||||
@@ -1753,7 +1783,23 @@ gdk_key_event_matches (GdkEvent *event,
|
||||
ev_keyval = self->translated[1].keyval;
|
||||
layout = self->translated[1].layout;
|
||||
level = self->translated[1].level;
|
||||
consumed_modifiers = self->translated[1].consumed;
|
||||
|
||||
/*
|
||||
* If a modifier is currently active (e.g. Shift is pressed) and was marked
|
||||
* as consumed, we ignore it for the purposes of matching shortcuts.
|
||||
* For example, when Ctrl+Shift+[plus/equals key] is translated into
|
||||
* Ctrl+plus on a keyboard where Shift+equals is the plus sign, we want
|
||||
* shortcuts for either <Control><Shift>plus or <Control>plus to match.
|
||||
* (See https://bugzilla.gnome.org/show_bug.cgi?id=100439)
|
||||
*
|
||||
* If a modifier is *not* currently active, the X11 backend can sometimes
|
||||
* mark it as consumed where the Wayland and Windows backends do not.
|
||||
* In this case, we still want to pay attention to its state.
|
||||
* For example, when Ctrl+x is translated into Ctrl+x, we only want to
|
||||
* trigger shortcuts for <Control>x, not for <Control><Shift>x.
|
||||
* (See https://gitlab.gnome.org/GNOME/gtk/-/issues/5095)
|
||||
*/
|
||||
ignored_modifiers = (self->translated[1].consumed & state);
|
||||
|
||||
/* if the group-toggling modifier is part of the default accel mod
|
||||
* mask, and it is active, disable it for matching
|
||||
@@ -1765,7 +1811,7 @@ gdk_key_event_matches (GdkEvent *event,
|
||||
if (mask & shift_group_mask)
|
||||
group_mod_is_accel_mod = TRUE;
|
||||
|
||||
if ((modifiers & ~consumed_modifiers & mask) == (state & ~consumed_modifiers & mask))
|
||||
if ((modifiers & ~ignored_modifiers & mask) == (state & ~ignored_modifiers & mask))
|
||||
{
|
||||
/* modifier match */
|
||||
GdkKeymapKey *keys;
|
||||
@@ -2431,6 +2477,14 @@ gdk_touchpad_event_get_state (GdkEvent *event)
|
||||
return self->state;
|
||||
}
|
||||
|
||||
static GdkEventSequence *
|
||||
gdk_touchpad_event_get_sequence (GdkEvent *event)
|
||||
{
|
||||
GdkTouchpadEvent *self = (GdkTouchpadEvent *) event;
|
||||
|
||||
return self->sequence;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_touchpad_event_get_position (GdkEvent *event,
|
||||
double *x,
|
||||
@@ -2450,7 +2504,7 @@ static const GdkEventTypeInfo gdk_touchpad_event_info = {
|
||||
NULL,
|
||||
gdk_touchpad_event_get_state,
|
||||
gdk_touchpad_event_get_position,
|
||||
NULL,
|
||||
gdk_touchpad_event_get_sequence,
|
||||
NULL,
|
||||
NULL,
|
||||
};
|
||||
@@ -2458,22 +2512,32 @@ static const GdkEventTypeInfo gdk_touchpad_event_info = {
|
||||
GDK_DEFINE_EVENT_TYPE (GdkTouchpadEvent, gdk_touchpad_event,
|
||||
&gdk_touchpad_event_info,
|
||||
GDK_EVENT_TYPE_SLOT (GDK_TOUCHPAD_SWIPE)
|
||||
GDK_EVENT_TYPE_SLOT (GDK_TOUCHPAD_PINCH))
|
||||
GDK_EVENT_TYPE_SLOT (GDK_TOUCHPAD_PINCH)
|
||||
GDK_EVENT_TYPE_SLOT (GDK_TOUCHPAD_HOLD))
|
||||
|
||||
GdkEvent *
|
||||
gdk_touchpad_event_new_swipe (GdkSurface *surface,
|
||||
GdkDevice *device,
|
||||
guint32 time,
|
||||
GdkModifierType state,
|
||||
GdkTouchpadGesturePhase phase,
|
||||
double x,
|
||||
double y,
|
||||
int n_fingers,
|
||||
double dx,
|
||||
double dy)
|
||||
gdk_touchpad_event_new_swipe (GdkSurface *surface,
|
||||
GdkEventSequence *sequence,
|
||||
GdkDevice *device,
|
||||
guint32 time,
|
||||
GdkModifierType state,
|
||||
GdkTouchpadGesturePhase phase,
|
||||
double x,
|
||||
double y,
|
||||
int n_fingers,
|
||||
double dx,
|
||||
double dy)
|
||||
{
|
||||
GdkTouchpadEvent *self = gdk_event_alloc (GDK_TOUCHPAD_SWIPE, surface, device, time);
|
||||
GdkTouchpadEvent *self;
|
||||
|
||||
g_return_val_if_fail (phase == GDK_TOUCHPAD_GESTURE_PHASE_BEGIN ||
|
||||
phase == GDK_TOUCHPAD_GESTURE_PHASE_END ||
|
||||
phase == GDK_TOUCHPAD_GESTURE_PHASE_UPDATE ||
|
||||
phase == GDK_TOUCHPAD_GESTURE_PHASE_CANCEL, NULL);
|
||||
|
||||
self = gdk_event_alloc (GDK_TOUCHPAD_SWIPE, surface, device, time);
|
||||
|
||||
self->sequence = sequence;
|
||||
self->state = state;
|
||||
self->phase = phase;
|
||||
self->x = x;
|
||||
@@ -2486,21 +2550,30 @@ gdk_touchpad_event_new_swipe (GdkSurface *surface,
|
||||
}
|
||||
|
||||
GdkEvent *
|
||||
gdk_touchpad_event_new_pinch (GdkSurface *surface,
|
||||
GdkDevice *device,
|
||||
guint32 time,
|
||||
GdkModifierType state,
|
||||
GdkTouchpadGesturePhase phase,
|
||||
double x,
|
||||
double y,
|
||||
int n_fingers,
|
||||
double dx,
|
||||
double dy,
|
||||
double scale,
|
||||
double angle_delta)
|
||||
gdk_touchpad_event_new_pinch (GdkSurface *surface,
|
||||
GdkEventSequence *sequence,
|
||||
GdkDevice *device,
|
||||
guint32 time,
|
||||
GdkModifierType state,
|
||||
GdkTouchpadGesturePhase phase,
|
||||
double x,
|
||||
double y,
|
||||
int n_fingers,
|
||||
double dx,
|
||||
double dy,
|
||||
double scale,
|
||||
double angle_delta)
|
||||
{
|
||||
GdkTouchpadEvent *self = gdk_event_alloc (GDK_TOUCHPAD_PINCH, surface, device, time);
|
||||
GdkTouchpadEvent *self;
|
||||
|
||||
g_return_val_if_fail (phase == GDK_TOUCHPAD_GESTURE_PHASE_BEGIN ||
|
||||
phase == GDK_TOUCHPAD_GESTURE_PHASE_END ||
|
||||
phase == GDK_TOUCHPAD_GESTURE_PHASE_UPDATE ||
|
||||
phase == GDK_TOUCHPAD_GESTURE_PHASE_CANCEL, NULL);
|
||||
|
||||
self = gdk_event_alloc (GDK_TOUCHPAD_PINCH, surface, device, time);
|
||||
|
||||
self->sequence = sequence;
|
||||
self->state = state;
|
||||
self->phase = phase;
|
||||
self->x = x;
|
||||
@@ -2514,6 +2587,27 @@ gdk_touchpad_event_new_pinch (GdkSurface *surface,
|
||||
return (GdkEvent *) self;
|
||||
}
|
||||
|
||||
GdkEvent *
|
||||
gdk_touchpad_event_new_hold (GdkSurface *surface,
|
||||
GdkDevice *device,
|
||||
guint32 time,
|
||||
GdkModifierType state,
|
||||
GdkTouchpadGesturePhase phase,
|
||||
double x,
|
||||
double y,
|
||||
int n_fingers)
|
||||
{
|
||||
GdkTouchpadEvent *self = gdk_event_alloc (GDK_TOUCHPAD_HOLD, surface, device, time);
|
||||
|
||||
self->state = state;
|
||||
self->phase = phase;
|
||||
self->x = x;
|
||||
self->y = y;
|
||||
self->n_fingers = n_fingers;
|
||||
|
||||
return (GdkEvent *) self;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_touchpad_event_get_gesture_phase:
|
||||
* @event: (type GdkTouchpadEvent): a touchpad event
|
||||
@@ -2529,7 +2623,8 @@ gdk_touchpad_event_get_gesture_phase (GdkEvent *event)
|
||||
|
||||
g_return_val_if_fail (GDK_IS_EVENT (event), 0);
|
||||
g_return_val_if_fail (GDK_IS_EVENT_TYPE (event, GDK_TOUCHPAD_PINCH) ||
|
||||
GDK_IS_EVENT_TYPE (event, GDK_TOUCHPAD_SWIPE), 0);
|
||||
GDK_IS_EVENT_TYPE (event, GDK_TOUCHPAD_SWIPE) ||
|
||||
GDK_IS_EVENT_TYPE (event, GDK_TOUCHPAD_HOLD), 0);
|
||||
|
||||
return self->phase;
|
||||
}
|
||||
@@ -2549,7 +2644,8 @@ gdk_touchpad_event_get_n_fingers (GdkEvent *event)
|
||||
|
||||
g_return_val_if_fail (GDK_IS_EVENT (event), 0);
|
||||
g_return_val_if_fail (GDK_IS_EVENT_TYPE (event, GDK_TOUCHPAD_PINCH) ||
|
||||
GDK_IS_EVENT_TYPE (event, GDK_TOUCHPAD_SWIPE), 0);
|
||||
GDK_IS_EVENT_TYPE (event, GDK_TOUCHPAD_SWIPE) ||
|
||||
GDK_IS_EVENT_TYPE (event, GDK_TOUCHPAD_HOLD), 0);
|
||||
|
||||
return self->n_fingers;
|
||||
}
|
||||
@@ -2907,7 +3003,8 @@ gdk_motion_event_new (GdkSurface *surface,
|
||||
* to the application because they occurred in the same frame as @event.
|
||||
*
|
||||
* Note that only motion and scroll events record history, and motion
|
||||
* events do it only if one of the mouse buttons is down.
|
||||
* events do it only if one of the mouse buttons is down, or the device
|
||||
* has a tool.
|
||||
*
|
||||
* Returns: (transfer container) (array length=out_n_coords) (nullable): an
|
||||
* array of time and coordinates
|
||||
|
||||
@@ -169,6 +169,8 @@ typedef struct _GdkTouchpadEvent GdkTouchpadEvent;
|
||||
* @GDK_PAD_RING: A tablet pad axis event from a "ring".
|
||||
* @GDK_PAD_STRIP: A tablet pad axis event from a "strip".
|
||||
* @GDK_PAD_GROUP_MODE: A tablet pad group mode change.
|
||||
* @GDK_TOUCHPAD_HOLD: A touchpad hold gesture event, the current state
|
||||
* is determined by its phase field. Since: 4.6
|
||||
* @GDK_EVENT_LAST: marks the end of the GdkEventType enumeration.
|
||||
*
|
||||
* Specifies the type of the event.
|
||||
@@ -203,6 +205,7 @@ typedef enum
|
||||
GDK_PAD_RING,
|
||||
GDK_PAD_STRIP,
|
||||
GDK_PAD_GROUP_MODE,
|
||||
GDK_TOUCHPAD_HOLD,
|
||||
GDK_EVENT_LAST /* helper variable for decls */
|
||||
} GdkEventType;
|
||||
|
||||
|
||||
@@ -209,7 +209,7 @@ struct _GdkTouchEvent
|
||||
* @pointer_emulated: whether the scroll event was the result of
|
||||
* a pointer emulation
|
||||
* @tool: a `GdkDeviceTool`
|
||||
* @history: (element-type GdkScrollHistory): array of times and deltas
|
||||
* @history: (element-type GdkTimeCoord): array of times and deltas
|
||||
* for other scroll events that were compressed before delivering the
|
||||
* current event
|
||||
*
|
||||
@@ -233,7 +233,7 @@ struct _GdkScrollEvent
|
||||
gboolean pointer_emulated;
|
||||
gboolean is_stop;
|
||||
GdkDeviceTool *tool;
|
||||
GArray *history; /* <GdkScrollHistory> */
|
||||
GArray *history; /* <GdkTimeCoord> */
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -402,6 +402,7 @@ struct _GdkTouchpadEvent
|
||||
{
|
||||
GdkEvent parent_instance;
|
||||
|
||||
GdkEventSequence *sequence;
|
||||
GdkModifierType state;
|
||||
gint8 phase;
|
||||
gint8 n_fingers;
|
||||
@@ -506,18 +507,20 @@ GdkEvent * gdk_touch_event_new (GdkEventType type,
|
||||
double *axes,
|
||||
gboolean emulating);
|
||||
|
||||
GdkEvent * gdk_touchpad_event_new_swipe (GdkSurface *surface,
|
||||
GdkDevice *device,
|
||||
guint32 time,
|
||||
GdkModifierType state,
|
||||
GdkEvent * gdk_touchpad_event_new_swipe (GdkSurface *surface,
|
||||
GdkEventSequence *sequence,
|
||||
GdkDevice *device,
|
||||
guint32 time,
|
||||
GdkModifierType state,
|
||||
GdkTouchpadGesturePhase phase,
|
||||
double x,
|
||||
double y,
|
||||
int n_fingers,
|
||||
double dx,
|
||||
double dy);
|
||||
double x,
|
||||
double y,
|
||||
int n_fingers,
|
||||
double dx,
|
||||
double dy);
|
||||
|
||||
GdkEvent * gdk_touchpad_event_new_pinch (GdkSurface *surface,
|
||||
GdkEventSequence *sequence,
|
||||
GdkDevice *device,
|
||||
guint32 time,
|
||||
GdkModifierType state,
|
||||
@@ -530,6 +533,15 @@ GdkEvent * gdk_touchpad_event_new_pinch (GdkSurface *surface,
|
||||
double scale,
|
||||
double angle_delta);
|
||||
|
||||
GdkEvent * gdk_touchpad_event_new_hold (GdkSurface *surface,
|
||||
GdkDevice *device,
|
||||
guint32 time,
|
||||
GdkModifierType state,
|
||||
GdkTouchpadGesturePhase phase,
|
||||
double x,
|
||||
double y,
|
||||
int n_fingers);
|
||||
|
||||
GdkEvent * gdk_pad_event_new_ring (GdkSurface *surface,
|
||||
GdkDevice *device,
|
||||
guint32 time,
|
||||
|
||||
@@ -373,6 +373,9 @@ gdk_frame_clock_flush_idle (void *data)
|
||||
else
|
||||
priv->phase = GDK_FRAME_CLOCK_PHASE_NONE;
|
||||
|
||||
g_clear_handle_id (&priv->paint_idle_id, g_source_remove);
|
||||
gdk_frame_clock_paint_idle (data);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
*
|
||||
* gdkglcontext.c: GL context abstraction
|
||||
*
|
||||
*
|
||||
* Copyright © 2014 Emmanuele Bassi
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
@@ -103,6 +103,7 @@ typedef struct {
|
||||
|
||||
guint has_khr_debug : 1;
|
||||
guint use_khr_debug : 1;
|
||||
guint has_half_float : 1;
|
||||
guint has_unpack_subimage : 1;
|
||||
guint has_debug_output : 1;
|
||||
guint extensions_checked : 1;
|
||||
@@ -117,6 +118,7 @@ typedef struct {
|
||||
|
||||
#ifdef HAVE_EGL
|
||||
EGLContext egl_context;
|
||||
EGLBoolean (*eglSwapBuffersWithDamage) (EGLDisplay, EGLSurface, const EGLint *, EGLint);
|
||||
#endif
|
||||
} GdkGLContextPrivate;
|
||||
|
||||
@@ -151,6 +153,12 @@ unmask_context (MaskedContext *mask)
|
||||
return GDK_GL_CONTEXT (GSIZE_TO_POINTER (GPOINTER_TO_SIZE (mask) & ~(gsize) 1));
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
mask_is_surfaceless (MaskedContext *mask)
|
||||
{
|
||||
return GPOINTER_TO_SIZE (mask) & (gsize) 1;
|
||||
}
|
||||
|
||||
static void
|
||||
unref_unmasked (gpointer data)
|
||||
{
|
||||
@@ -179,8 +187,7 @@ gdk_gl_context_dispose (GObject *gobject)
|
||||
|
||||
if (priv->egl_context != NULL)
|
||||
{
|
||||
GdkSurface *surface = gdk_gl_context_get_surface (context);
|
||||
GdkDisplay *display = gdk_surface_get_display (surface);
|
||||
GdkDisplay *display = gdk_draw_context_get_display (GDK_DRAW_CONTEXT (context));
|
||||
EGLDisplay *egl_display = gdk_display_get_egl_display (display);
|
||||
|
||||
if (eglGetCurrentContext () == priv->egl_context)
|
||||
@@ -273,7 +280,11 @@ gdk_gl_context_real_realize (GdkGLContext *context,
|
||||
int i = 0;
|
||||
G_GNUC_UNUSED gint64 start_time = GDK_PROFILER_CURRENT_TIME;
|
||||
|
||||
gdk_gl_context_get_required_version (context, &major, &minor);
|
||||
if (share != NULL)
|
||||
gdk_gl_context_get_required_version (share, &major, &minor);
|
||||
else
|
||||
gdk_gl_context_get_required_version (context, &major, &minor);
|
||||
|
||||
debug_bit = gdk_gl_context_get_debug_enabled (context);
|
||||
forward_bit = gdk_gl_context_get_forward_compatible (context);
|
||||
legacy_bit = GDK_DISPLAY_DEBUG_CHECK (display, GL_LEGACY) ||
|
||||
@@ -411,6 +422,11 @@ gdk_gl_context_real_realize (GdkGLContext *context,
|
||||
|
||||
gdk_gl_context_set_is_legacy (context, legacy_bit);
|
||||
|
||||
if (epoxy_has_egl_extension (egl_display, "EGL_KHR_swap_buffers_with_damage"))
|
||||
priv->eglSwapBuffersWithDamage = (gpointer)epoxy_eglGetProcAddress ("eglSwapBuffersWithDamageKHR");
|
||||
else if (epoxy_has_egl_extension (egl_display, "EGL_EXT_swap_buffers_with_damage"))
|
||||
priv->eglSwapBuffersWithDamage = (gpointer)epoxy_eglGetProcAddress ("eglSwapBuffersWithDamageEXT");
|
||||
|
||||
gdk_profiler_end_mark (start_time, "realize GdkWaylandGLContext", NULL);
|
||||
|
||||
return api;
|
||||
@@ -574,8 +590,8 @@ gdk_gl_context_real_begin_frame (GdkDrawContext *draw_context,
|
||||
glViewport (0, 0, ww, wh);
|
||||
|
||||
#ifdef HAVE_EGL
|
||||
if (priv->egl_context)
|
||||
glDrawBuffers (1, (GLenum[1]) { GL_BACK_LEFT });
|
||||
if (priv->egl_context && gdk_gl_context_check_version (context, 0, 0, 3, 0))
|
||||
glDrawBuffers (1, (GLenum[1]) { gdk_gl_context_get_use_es (context) ? GL_BACK : GL_BACK_LEFT });
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -599,7 +615,7 @@ gdk_gl_context_real_end_frame (GdkDrawContext *draw_context,
|
||||
|
||||
gdk_profiler_add_mark (GDK_PROFILER_CURRENT_TIME, 0, "EGL", "swap buffers");
|
||||
|
||||
if (display->have_egl_swap_buffers_with_damage)
|
||||
if (priv->eglSwapBuffersWithDamage)
|
||||
{
|
||||
EGLint stack_rects[4 * 4]; /* 4 rects */
|
||||
EGLint *heap_rects = NULL;
|
||||
@@ -623,7 +639,7 @@ gdk_gl_context_real_end_frame (GdkDrawContext *draw_context,
|
||||
rects[j++] = rect.width * scale;
|
||||
rects[j++] = rect.height * scale;
|
||||
}
|
||||
eglSwapBuffersWithDamageEXT (gdk_display_get_egl_display (display), egl_surface, rects, n_rects);
|
||||
priv->eglSwapBuffersWithDamage (gdk_display_get_egl_display (display), egl_surface, rects, n_rects);
|
||||
g_free (heap_rects);
|
||||
}
|
||||
else
|
||||
@@ -639,6 +655,12 @@ gdk_gl_context_surface_resized (GdkDrawContext *draw_context)
|
||||
gdk_gl_context_clear_old_updated_area (context);
|
||||
}
|
||||
|
||||
static guint
|
||||
gdk_gl_context_real_get_default_framebuffer (GdkGLContext *self)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_gl_context_class_init (GdkGLContextClass *klass)
|
||||
{
|
||||
@@ -650,6 +672,7 @@ gdk_gl_context_class_init (GdkGLContextClass *klass)
|
||||
klass->is_shared = gdk_gl_context_real_is_shared;
|
||||
klass->make_current = gdk_gl_context_real_make_current;
|
||||
klass->clear_current = gdk_gl_context_real_clear_current;
|
||||
klass->get_default_framebuffer = gdk_gl_context_real_get_default_framebuffer;
|
||||
|
||||
draw_context_class->begin_frame = gdk_gl_context_real_begin_frame;
|
||||
draw_context_class->end_frame = gdk_gl_context_real_end_frame;
|
||||
@@ -997,16 +1020,33 @@ gdk_gl_context_set_required_version (GdkGLContext *context,
|
||||
}
|
||||
|
||||
gboolean
|
||||
gdk_gl_context_check_version (GdkGLContext *context,
|
||||
int required_major,
|
||||
int required_minor)
|
||||
gdk_gl_context_check_version (GdkGLContext *self,
|
||||
int required_gl_major,
|
||||
int required_gl_minor,
|
||||
int required_gles_major,
|
||||
int required_gles_minor)
|
||||
{
|
||||
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
|
||||
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (self);
|
||||
|
||||
g_return_val_if_fail (GDK_IS_GL_CONTEXT (context), FALSE);
|
||||
g_return_val_if_fail (required_minor < 10, FALSE);
|
||||
g_return_val_if_fail (GDK_IS_GL_CONTEXT (self), FALSE);
|
||||
g_return_val_if_fail (required_gl_minor < 10, FALSE);
|
||||
g_return_val_if_fail (required_gles_minor < 10, FALSE);
|
||||
|
||||
return priv->gl_version >= required_major * 10 + required_minor;
|
||||
if (!gdk_gl_context_is_realized (self))
|
||||
return FALSE;
|
||||
|
||||
switch (priv->api)
|
||||
{
|
||||
case GDK_GL_API_GL:
|
||||
return priv->gl_version >= required_gl_major * 10 + required_gl_minor;
|
||||
|
||||
case GDK_GL_API_GLES:
|
||||
return priv->gl_version >= required_gles_major * 10 + required_gles_minor;
|
||||
|
||||
default:
|
||||
g_return_val_if_reached (FALSE);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1026,26 +1066,29 @@ gdk_gl_context_get_required_version (GdkGLContext *context,
|
||||
{
|
||||
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
|
||||
gboolean force_gles = FALSE;
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
GdkDisplay *display;
|
||||
#endif
|
||||
int default_major, default_minor;
|
||||
int maj, min;
|
||||
|
||||
g_return_if_fail (GDK_IS_GL_CONTEXT (context));
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
display = gdk_draw_context_get_display (GDK_DRAW_CONTEXT (context));
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
force_gles = GDK_DISPLAY_DEBUG_CHECK (display, GL_GLES);
|
||||
#endif
|
||||
|
||||
/* libANGLE on Windows at least requires GLES 3.0+ */
|
||||
if (display->have_egl_win32_libangle)
|
||||
force_gles = TRUE;
|
||||
|
||||
/* Default fallback values for uninitialised contexts; we
|
||||
* enforce a context version number of 3.2 for desktop GL,
|
||||
* and 2.0 for GLES
|
||||
*/
|
||||
if (gdk_gl_context_get_use_es (context) || force_gles)
|
||||
{
|
||||
default_major = 2;
|
||||
default_major = display->have_egl_win32_libangle ? 3 : 2;
|
||||
default_minor = 0;
|
||||
}
|
||||
else
|
||||
@@ -1323,6 +1366,7 @@ gl_debug_message_callback (GLenum source,
|
||||
const char *message_source;
|
||||
const char *message_type;
|
||||
const char *message_severity;
|
||||
GLogLevelFlags log_level;
|
||||
|
||||
if (severity == GL_DEBUG_SEVERITY_NOTIFICATION)
|
||||
return;
|
||||
@@ -1384,22 +1428,31 @@ gl_debug_message_callback (GLenum source,
|
||||
{
|
||||
case GL_DEBUG_SEVERITY_HIGH:
|
||||
message_severity = "High";
|
||||
log_level = G_LOG_LEVEL_CRITICAL;
|
||||
break;
|
||||
case GL_DEBUG_SEVERITY_MEDIUM:
|
||||
message_severity = "Medium";
|
||||
log_level = G_LOG_LEVEL_WARNING;
|
||||
break;
|
||||
case GL_DEBUG_SEVERITY_LOW:
|
||||
message_severity = "Low";
|
||||
log_level = G_LOG_LEVEL_MESSAGE;
|
||||
break;
|
||||
case GL_DEBUG_SEVERITY_NOTIFICATION:
|
||||
message_severity = "Notification";
|
||||
log_level = G_LOG_LEVEL_INFO;
|
||||
break;
|
||||
default:
|
||||
message_severity = "Unknown";
|
||||
log_level = G_LOG_LEVEL_MESSAGE;
|
||||
}
|
||||
|
||||
g_warning ("OPENGL:\n Source: %s\n Type: %s\n Severity: %s\n Message: %s",
|
||||
message_source, message_type, message_severity, message);
|
||||
/* There's no higher level function taking a log level argument... */
|
||||
g_log_structured_standard (G_LOG_DOMAIN, log_level,
|
||||
__FILE__, G_STRINGIFY (__LINE__),
|
||||
G_STRFUNC,
|
||||
"OPENGL:\n Source: %s\n Type: %s\n Severity: %s\n Message: %s",
|
||||
message_source, message_type, message_severity, message);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1490,18 +1543,23 @@ gdk_gl_context_check_extensions (GdkGLContext *context)
|
||||
glGetIntegerv (GL_MAX_LABEL_LENGTH, &priv->max_debug_label_length);
|
||||
}
|
||||
|
||||
priv->has_half_float = gdk_gl_context_check_version (context, 3, 0, 3, 0) ||
|
||||
epoxy_has_gl_extension ("OES_vertex_half_float");
|
||||
|
||||
GDK_DISPLAY_NOTE (gdk_draw_context_get_display (GDK_DRAW_CONTEXT (context)), OPENGL,
|
||||
g_message ("%s version: %d.%d (%s)\n"
|
||||
"* GLSL version: %s\n"
|
||||
"* Extensions checked:\n"
|
||||
" - GL_KHR_debug: %s\n"
|
||||
" - GL_EXT_unpack_subimage: %s",
|
||||
" - GL_EXT_unpack_subimage: %s\n"
|
||||
" - OES_vertex_half_float: %s",
|
||||
gdk_gl_context_get_use_es (context) ? "OpenGL ES" : "OpenGL",
|
||||
priv->gl_version / 10, priv->gl_version % 10,
|
||||
priv->is_legacy ? "legacy" : "core",
|
||||
glGetString (GL_SHADING_LANGUAGE_VERSION),
|
||||
priv->has_khr_debug ? "yes" : "no",
|
||||
priv->has_unpack_subimage ? "yes" : "no"));
|
||||
priv->has_unpack_subimage ? "yes" : "no",
|
||||
priv->has_half_float ? "yes" : "no"));
|
||||
|
||||
priv->extensions_checked = TRUE;
|
||||
}
|
||||
@@ -1655,6 +1713,31 @@ gdk_gl_context_clear_current (void)
|
||||
}
|
||||
}
|
||||
|
||||
/*<private>
|
||||
* gdk_gl_context_clear_current_if_surface:
|
||||
* @surface: surface to clear for
|
||||
*
|
||||
* Does a gdk_gl_context_clear_current() if the current context is attached
|
||||
* to @surface, leaves the current context alone otherwise.
|
||||
**/
|
||||
void
|
||||
gdk_gl_context_clear_current_if_surface (GdkSurface *surface)
|
||||
{
|
||||
MaskedContext *current;
|
||||
|
||||
current = g_private_get (&thread_current_context);
|
||||
if (current != NULL && !mask_is_surfaceless (current))
|
||||
{
|
||||
GdkGLContext *context = unmask_context (current);
|
||||
|
||||
if (gdk_gl_context_get_surface (context) != surface)
|
||||
return;
|
||||
|
||||
if (GDK_GL_CONTEXT_GET_CLASS (context)->clear_current (context))
|
||||
g_private_replace (&thread_current_context, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_gl_context_get_current:
|
||||
*
|
||||
@@ -1680,6 +1763,14 @@ gdk_gl_context_has_debug (GdkGLContext *self)
|
||||
return priv->debug_enabled || priv->use_khr_debug;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gdk_gl_context_has_vertex_half_float (GdkGLContext *self)
|
||||
{
|
||||
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (self);
|
||||
|
||||
return priv->has_half_float;
|
||||
}
|
||||
|
||||
/* This is currently private! */
|
||||
/* When using GL/ES, don't flip the 'R' and 'B' bits on Windows/ANGLE for glReadPixels() */
|
||||
gboolean
|
||||
@@ -1722,7 +1813,7 @@ gboolean
|
||||
gdk_gl_backend_can_be_used (GdkGLBackend backend_type,
|
||||
GError **error)
|
||||
{
|
||||
if (the_gl_backend_type == GDK_GL_NONE ||
|
||||
if (the_gl_backend_type == GDK_GL_NONE ||
|
||||
the_gl_backend_type == backend_type)
|
||||
return TRUE;
|
||||
|
||||
|
||||
@@ -71,6 +71,8 @@ struct _GdkGLContextClass
|
||||
|
||||
gboolean (* is_shared) (GdkGLContext *self,
|
||||
GdkGLContext *other);
|
||||
|
||||
guint (* get_default_framebuffer) (GdkGLContext *self);
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
@@ -99,6 +101,8 @@ gboolean gdk_gl_backend_can_be_used (GdkGLBackend
|
||||
GError **error);
|
||||
void gdk_gl_backend_use (GdkGLBackend backend_type);
|
||||
|
||||
void gdk_gl_context_clear_current_if_surface (GdkSurface *surface);
|
||||
|
||||
GdkGLContext * gdk_gl_context_new (GdkDisplay *display,
|
||||
GdkSurface *surface);
|
||||
|
||||
@@ -109,8 +113,10 @@ void gdk_gl_context_set_is_legacy (GdkGLContext
|
||||
gboolean is_legacy);
|
||||
|
||||
gboolean gdk_gl_context_check_version (GdkGLContext *context,
|
||||
int required_major,
|
||||
int required_minor);
|
||||
int required_gl_major,
|
||||
int required_gl_minor,
|
||||
int required_gles_major,
|
||||
int required_gles_minor);
|
||||
|
||||
gboolean gdk_gl_context_has_unpack_subimage (GdkGLContext *context);
|
||||
void gdk_gl_context_push_debug_group (GdkGLContext *context,
|
||||
@@ -133,6 +139,8 @@ gboolean gdk_gl_context_has_debug (GdkGLContext
|
||||
|
||||
gboolean gdk_gl_context_use_es_bgra (GdkGLContext *context);
|
||||
|
||||
gboolean gdk_gl_context_has_vertex_half_float (GdkGLContext *self) G_GNUC_PURE;
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_GL_CONTEXT_PRIVATE_H__ */
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "gdkgltextureprivate.h"
|
||||
|
||||
#include "gdkdisplayprivate.h"
|
||||
#include "gdkglcontextprivate.h"
|
||||
#include "gdkmemoryformatprivate.h"
|
||||
#include "gdkmemorytextureprivate.h"
|
||||
#include "gdktextureprivate.h"
|
||||
@@ -174,10 +175,19 @@ gdk_gl_texture_do_download (gpointer texture_,
|
||||
glGenFramebuffers (1, &fbo);
|
||||
glBindFramebuffer (GL_FRAMEBUFFER, fbo);
|
||||
glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, self->id, 0);
|
||||
glGetFramebufferParameteriv (GL_FRAMEBUFFER, GL_IMPLEMENTATION_COLOR_READ_FORMAT, &gl_read_format);
|
||||
glGetFramebufferParameteriv (GL_FRAMEBUFFER, GL_IMPLEMENTATION_COLOR_READ_TYPE, &gl_read_type);
|
||||
if (!gdk_gl_texture_find_format (gdk_gl_context_get_use_es (self->context), gl_read_format, gl_read_type, &actual_format))
|
||||
actual_format = GDK_MEMORY_R8G8B8A8_PREMULTIPLIED; /* pray */
|
||||
if (gdk_gl_context_check_version (self->context, 4, 3, 3, 1))
|
||||
{
|
||||
glGetFramebufferParameteriv (GL_FRAMEBUFFER, GL_IMPLEMENTATION_COLOR_READ_FORMAT, &gl_read_format);
|
||||
glGetFramebufferParameteriv (GL_FRAMEBUFFER, GL_IMPLEMENTATION_COLOR_READ_TYPE, &gl_read_type);
|
||||
if (!gdk_gl_texture_find_format (gdk_gl_context_get_use_es (self->context), gl_read_format, gl_read_type, &actual_format))
|
||||
actual_format = GDK_MEMORY_R8G8B8A8_PREMULTIPLIED; /* pray */
|
||||
}
|
||||
else
|
||||
{
|
||||
gl_read_format = GL_RGBA;
|
||||
gl_read_type = GL_UNSIGNED_BYTE;
|
||||
actual_format = GDK_MEMORY_R8G8B8A8_PREMULTIPLIED;
|
||||
}
|
||||
|
||||
if (download->format == actual_format &&
|
||||
(download->stride == expected_stride))
|
||||
@@ -305,9 +315,11 @@ gdk_gl_texture_determine_format (GdkGLTexture *self)
|
||||
GLint active_texture;
|
||||
GLint internal_format;
|
||||
|
||||
if (self->context != gdk_gl_context_get_current ())
|
||||
/* Abort if somebody else is GL-ing here... */
|
||||
if (self->context != gdk_gl_context_get_current () ||
|
||||
/* ... or glGetTexLevelParameter() isn't supported */
|
||||
!gdk_gl_context_check_version (self->context, 0, 0, 3, 1))
|
||||
{
|
||||
/* Somebody else is GL-ing here, abort! */
|
||||
texture->format = GDK_MEMORY_DEFAULT;
|
||||
return;
|
||||
}
|
||||
@@ -353,6 +365,42 @@ gdk_gl_texture_determine_format (GdkGLTexture *self)
|
||||
texture->format = GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED;
|
||||
break;
|
||||
|
||||
case GL_RGBA:
|
||||
{
|
||||
GLint red_size = 0;
|
||||
GLint green_size = 0;
|
||||
GLint blue_size = 0;
|
||||
GLint alpha_size = 0;
|
||||
GLint red_type = 0;
|
||||
GLint green_type = 0;
|
||||
GLint blue_type = 0;
|
||||
GLint alpha_type = 0;
|
||||
|
||||
glGetTexLevelParameteriv (GL_TEXTURE_2D, 0, GL_TEXTURE_RED_TYPE, &red_type);
|
||||
glGetTexLevelParameteriv (GL_TEXTURE_2D, 0, GL_TEXTURE_GREEN_TYPE, &green_type);
|
||||
glGetTexLevelParameteriv (GL_TEXTURE_2D, 0, GL_TEXTURE_BLUE_TYPE, &blue_type);
|
||||
glGetTexLevelParameteriv (GL_TEXTURE_2D, 0, GL_TEXTURE_ALPHA_TYPE, &alpha_type);
|
||||
|
||||
glGetTexLevelParameteriv (GL_TEXTURE_2D, 0, GL_TEXTURE_RED_SIZE, &red_size);
|
||||
glGetTexLevelParameteriv (GL_TEXTURE_2D, 0, GL_TEXTURE_GREEN_SIZE, &green_size);
|
||||
glGetTexLevelParameteriv (GL_TEXTURE_2D, 0, GL_TEXTURE_BLUE_SIZE, &blue_size);
|
||||
glGetTexLevelParameteriv (GL_TEXTURE_2D, 0, GL_TEXTURE_ALPHA_SIZE, &alpha_size);
|
||||
|
||||
#define CHECK_RGBA(rt,gt,bt,at,rs,gs,bs,as) \
|
||||
(red_type == rt && green_type == gt && blue_type == bt && alpha_type == at && \
|
||||
red_size == rs && green_size == gs && blue_size == bs && alpha_size == as)
|
||||
|
||||
if (CHECK_RGBA (GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 8))
|
||||
{
|
||||
texture->format = GDK_MEMORY_R8G8B8A8_PREMULTIPLIED;
|
||||
break;
|
||||
}
|
||||
|
||||
#undef CHECK_RGBA
|
||||
}
|
||||
|
||||
G_GNUC_FALLTHROUGH;
|
||||
|
||||
default:
|
||||
g_warning ("Texture in unexpected format 0x%X (%d). File a bug about adding it to GTK", internal_format, internal_format);
|
||||
/* fallback to the dumbest possible format
|
||||
@@ -380,7 +428,8 @@ gdk_gl_texture_determine_format (GdkGLTexture *self)
|
||||
* which will happen when the GdkTexture object is finalized, or due to
|
||||
* an explicit call of [method@Gdk.GLTexture.release].
|
||||
*
|
||||
* Return value: (transfer full): A newly-created `GdkTexture`
|
||||
* Return value: (transfer full) (type GdkGLTexture): A newly-created
|
||||
* `GdkTexture`
|
||||
*/
|
||||
GdkTexture *
|
||||
gdk_gl_texture_new (GdkGLContext *context,
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
* Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
|
||||
* file for a list of people on the GTK+ Team. See the ChangeLog
|
||||
* files for a list of changes. These files are distributed with
|
||||
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
|
||||
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
|
||||
*/
|
||||
|
||||
#ifndef __GDKINTL_H__
|
||||
@@ -27,10 +27,6 @@
|
||||
|
||||
#include <glib/gi18n-lib.h>
|
||||
|
||||
#ifdef ENABLE_NLS
|
||||
#define P_(String) dgettext(GETTEXT_PACKAGE "-properties",String)
|
||||
#else
|
||||
#define P_(String) (String)
|
||||
#endif
|
||||
#define P_(String) dgettext (GETTEXT_PACKAGE "-properties", String)
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
#!/usr/bin/env perl
|
||||
|
||||
# Updates https://gitlab.gnome.org/GNOME/gtk/tree/master/gdk/gdkkeysyms.h from upstream (X.org 7.x),
|
||||
# Updates https://gitlab.gnome.org/GNOME/gtk/tree/main/gdk/gdkkeysyms.h from upstream (X.org 7.x),
|
||||
# from https://cgit.freedesktop.org/xorg/proto/x11proto/plain/keysymdef.h
|
||||
#
|
||||
#
|
||||
# Author : Simos Xenitellis <simos at gnome dot org>.
|
||||
# Author : Bastien Nocera <hadess@hadess.net>
|
||||
# Version : 1.2
|
||||
#
|
||||
# Input : https://cgit.freedesktop.org/xorg/proto/x11proto/plain/keysymdef.h
|
||||
# Input : https://cgit.freedesktop.org/xorg/proto/x11proto/plain/XF86keysym.h
|
||||
# Output : https://gitlab.gnome.org/GNOME/gtk/tree/master/gdk/gdkkeysyms.h
|
||||
#
|
||||
# Output : https://gitlab.gnome.org/GNOME/gtk/tree/main/gdk/gdkkeysyms.h
|
||||
#
|
||||
# Notes : It downloads keysymdef.h from the Internet, if not found locally,
|
||||
# Notes : and creates an updated gdkkeysyms.h
|
||||
# Notes : This version updates the source of gdkkeysyms.h from CVS to the GIT server.
|
||||
@@ -24,7 +24,7 @@ if ( ! -f "keysymdef.h" )
|
||||
{
|
||||
print "Trying to download keysymdef.h from\n";
|
||||
print "http://cgit.freedesktop.org/xorg/proto/x11proto/plain/keysymdef.h\n";
|
||||
die "Unable to download keysymdef.h from http://cgit.freedesktop.org/xorg/proto/x11proto/plain/keysymdef.h\n"
|
||||
die "Unable to download keysymdef.h from http://cgit.freedesktop.org/xorg/proto/x11proto/plain/keysymdef.h\n"
|
||||
unless system("wget -c -O keysymdef.h \"http://cgit.freedesktop.org/xorg/proto/x11proto/plain/keysymdef.h\"") == 0;
|
||||
print " done.\n\n";
|
||||
}
|
||||
@@ -39,7 +39,7 @@ if ( ! -f "XF86keysym.h" )
|
||||
{
|
||||
print "Trying to download XF86keysym.h from\n";
|
||||
print "http://cgit.freedesktop.org/xorg/proto/x11proto/plain/XF86keysym.h\n";
|
||||
die "Unable to download keysymdef.h from http://cgit.freedesktop.org/xorg/proto/x11proto/plain/XF86keysym.h\n"
|
||||
die "Unable to download keysymdef.h from http://cgit.freedesktop.org/xorg/proto/x11proto/plain/XF86keysym.h\n"
|
||||
unless system("wget -c -O XF86keysym.h \"http://cgit.freedesktop.org/xorg/proto/x11proto/plain/XF86keysym.h\"") == 0;
|
||||
print " done.\n\n";
|
||||
}
|
||||
@@ -82,7 +82,7 @@ print OUT_GDKKEYSYMS $LICENSE_HEADER;
|
||||
print OUT_GDKKEYSYMS<<EOF;
|
||||
|
||||
/*
|
||||
* File auto-generated from script https://gitlab.gnome.org/GNOME/gtk/tree/master/gdk/gdkkeysyms-update.pl
|
||||
* File auto-generated from script https://gitlab.gnome.org/GNOME/gtk/tree/main/gdk/gdkkeysyms-update.pl
|
||||
* using the input file
|
||||
* http://cgit.freedesktop.org/xorg/proto/x11proto/plain/keysymdef.h
|
||||
* and
|
||||
@@ -111,7 +111,7 @@ while (<IN_KEYSYMDEF>)
|
||||
|
||||
$_ = $keysymelements[1];
|
||||
die "Internal error, was expecting \"XC_*\", found: $_\n" if ( ! /^XK_/ );
|
||||
|
||||
|
||||
$_ = $keysymelements[2];
|
||||
die "Internal error, was expecting \"0x*\", found: $_\n" if ( ! /^0x/ );
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
|
||||
/*
|
||||
* File auto-generated from script https://gitlab.gnome.org/GNOME/gtk/tree/master/gdk/gdkkeysyms-update.pl
|
||||
* File auto-generated from script https://gitlab.gnome.org/GNOME/gtk/tree/main/gdk/gdkkeysyms-update.pl
|
||||
* using the input file
|
||||
* http://cgit.freedesktop.org/xorg/proto/x11proto/plain/keysymdef.h
|
||||
* and
|
||||
|
||||
101
gdk/gdkkeyuni.c
101
gdk/gdkkeyuni.c
@@ -369,7 +369,7 @@ static const struct {
|
||||
{ 0x07a2, 0x0388 }, /* Greek_EPSILONaccent Έ GREEK CAPITAL LETTER EPSILON WITH TONOS */
|
||||
{ 0x07a3, 0x0389 }, /* Greek_ETAaccent Ή GREEK CAPITAL LETTER ETA WITH TONOS */
|
||||
{ 0x07a4, 0x038a }, /* Greek_IOTAaccent Ί GREEK CAPITAL LETTER IOTA WITH TONOS */
|
||||
{ 0x07a5, 0x03aa }, /* Greek_IOTAdieresis Ϊ GREEK CAPITAL LETTER IOTA WITH DIALYTIKA */
|
||||
{ 0x07a5, 0x03aa }, /* Greek_IOTAdiaeresis Ϊ GREEK CAPITAL LETTER IOTA WITH DIALYTIKA */
|
||||
{ 0x07a7, 0x038c }, /* Greek_OMICRONaccent Ό GREEK CAPITAL LETTER OMICRON WITH TONOS */
|
||||
{ 0x07a8, 0x038e }, /* Greek_UPSILONaccent Ύ GREEK CAPITAL LETTER UPSILON WITH TONOS */
|
||||
{ 0x07a9, 0x03ab }, /* Greek_UPSILONdieresis Ϋ GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA */
|
||||
@@ -436,22 +436,22 @@ static const struct {
|
||||
{ 0x07f7, 0x03c7 }, /* Greek_chi χ GREEK SMALL LETTER CHI */
|
||||
{ 0x07f8, 0x03c8 }, /* Greek_psi ψ GREEK SMALL LETTER PSI */
|
||||
{ 0x07f9, 0x03c9 }, /* Greek_omega ω GREEK SMALL LETTER OMEGA */
|
||||
/* 0x08a1 leftradical ? ??? */
|
||||
/* 0x08a2 topleftradical ? ??? */
|
||||
/* 0x08a3 horizconnector ? ??? */
|
||||
{ 0x08a1, 0x23b7 }, /* leftradical ⎷ ??? */
|
||||
{ 0x08a2, 0x250c }, /* topleftradical ┌ BOX DRAWINGS LIGHT DOWN AND RIGHT */
|
||||
{ 0x08a3, 0x2500 }, /* horizconnector ─ BOX DRAWINGS LIGHT HORIZONTAL */
|
||||
{ 0x08a4, 0x2320 }, /* topintegral ⌠ TOP HALF INTEGRAL */
|
||||
{ 0x08a5, 0x2321 }, /* botintegral ⌡ BOTTOM HALF INTEGRAL */
|
||||
{ 0x08a6, 0x2502 }, /* vertconnector │ BOX DRAWINGS LIGHT VERTICAL */
|
||||
/* 0x08a7 topleftsqbracket ? ??? */
|
||||
/* 0x08a8 botleftsqbracket ? ??? */
|
||||
/* 0x08a9 toprightsqbracket ? ??? */
|
||||
/* 0x08aa botrightsqbracket ? ??? */
|
||||
/* 0x08ab topleftparens ? ??? */
|
||||
/* 0x08ac botleftparens ? ??? */
|
||||
/* 0x08ad toprightparens ? ??? */
|
||||
/* 0x08ae botrightparens ? ??? */
|
||||
/* 0x08af leftmiddlecurlybrace ? ??? */
|
||||
/* 0x08b0 rightmiddlecurlybrace ? ??? */
|
||||
{ 0x08a7, 0x23a1 }, /* topleftsqbracket ⎡ ??? */
|
||||
{ 0x08a8, 0x23a3 }, /* botleftsqbracket ⎣ ??? */
|
||||
{ 0x08a9, 0x23a4 }, /* toprightsqbracket ⎤ ??? */
|
||||
{ 0x08aa, 0x23a6 }, /* botrightsqbracket ⎦ ??? */
|
||||
{ 0x08ab, 0x239b }, /* topleftparens ⎛ ??? */
|
||||
{ 0x08ac, 0x239d }, /* botleftparens ⎝ ??? */
|
||||
{ 0x08ad, 0x239e }, /* toprightparens ⎞ ??? */
|
||||
{ 0x08ae, 0x23a0 }, /* botrightparens ⎠ ??? */
|
||||
{ 0x08af, 0x23a8 }, /* leftmiddlecurlybrace ⎨ ??? */
|
||||
{ 0x08b0, 0x23ac }, /* rightmiddlecurlybrace ⎬ ??? */
|
||||
/* 0x08b1 topleftsummation ? ??? */
|
||||
/* 0x08b2 botleftsummation ? ??? */
|
||||
/* 0x08b3 topvertsummationconnector ? ??? */
|
||||
@@ -467,8 +467,8 @@ static const struct {
|
||||
{ 0x08c1, 0x221d }, /* variation ∝ PROPORTIONAL TO */
|
||||
{ 0x08c2, 0x221e }, /* infinity ∞ INFINITY */
|
||||
{ 0x08c5, 0x2207 }, /* nabla ∇ NABLA */
|
||||
{ 0x08c8, 0x2245 }, /* approximate ≅ APPROXIMATELY EQUAL TO */
|
||||
/* 0x08c9 similarequal ? ??? */
|
||||
{ 0x08c8, 0x223c }, /* approximate ∼ TILDE OPERATOR */
|
||||
{ 0x08c9, 0x2243 }, /* similarequal ≃ ASYMPTOTICALLY EQUAL TO */
|
||||
{ 0x08cd, 0x21d4 }, /* ifonlyif ⇔ LEFT RIGHT DOUBLE ARROW */
|
||||
{ 0x08ce, 0x21d2 }, /* implies ⇒ RIGHTWARDS DOUBLE ARROW */
|
||||
{ 0x08cf, 0x2261 }, /* identical ≡ IDENTICAL TO */
|
||||
@@ -485,7 +485,7 @@ static const struct {
|
||||
{ 0x08fc, 0x2191 }, /* uparrow ↑ UPWARDS ARROW */
|
||||
{ 0x08fd, 0x2192 }, /* rightarrow → RIGHTWARDS ARROW */
|
||||
{ 0x08fe, 0x2193 }, /* downarrow ↓ DOWNWARDS ARROW */
|
||||
{ 0x09df, 0x2422 }, /* blank ␢ BLANK SYMBOL */
|
||||
/* 0x09df blank ? ??? */
|
||||
{ 0x09e0, 0x25c6 }, /* soliddiamond ◆ BLACK DIAMOND */
|
||||
{ 0x09e1, 0x2592 }, /* checkerboard ▒ MEDIUM SHADE */
|
||||
{ 0x09e2, 0x2409 }, /* ht ␉ SYMBOL FOR HORIZONTAL TABULATION */
|
||||
@@ -499,11 +499,11 @@ static const struct {
|
||||
{ 0x09ec, 0x250c }, /* upleftcorner ┌ BOX DRAWINGS LIGHT DOWN AND RIGHT */
|
||||
{ 0x09ed, 0x2514 }, /* lowleftcorner └ BOX DRAWINGS LIGHT UP AND RIGHT */
|
||||
{ 0x09ee, 0x253c }, /* crossinglines ┼ BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL */
|
||||
/* 0x09ef horizlinescan1 ? ??? */
|
||||
/* 0x09f0 horizlinescan3 ? ??? */
|
||||
{ 0x09ef, 0x23ba }, /* horizlinescan1 ⎺ HORIZONTAL SCAN LINE-1 (Unicode 3.2 draft) */
|
||||
{ 0x09f0, 0x23bb }, /* horizlinescan3 ⎻ HORIZONTAL SCAN LINE-3 (Unicode 3.2 draft) */
|
||||
{ 0x09f1, 0x2500 }, /* horizlinescan5 ─ BOX DRAWINGS LIGHT HORIZONTAL */
|
||||
/* 0x09f2 horizlinescan7 ? ??? */
|
||||
/* 0x09f3 horizlinescan9 ? ??? */
|
||||
{ 0x09f2, 0x23bc }, /* horizlinescan7 ⎼ HORIZONTAL SCAN LINE-7 (Unicode 3.2 draft) */
|
||||
{ 0x09f3, 0x23bd }, /* horizlinescan9 ⎽ HORIZONTAL SCAN LINE-9 (Unicode 3.2 draft) */
|
||||
{ 0x09f4, 0x251c }, /* leftt ├ BOX DRAWINGS LIGHT VERTICAL AND RIGHT */
|
||||
{ 0x09f5, 0x2524 }, /* rightt ┤ BOX DRAWINGS LIGHT VERTICAL AND LEFT */
|
||||
{ 0x09f6, 0x2534 }, /* bott ┴ BOX DRAWINGS LIGHT UP AND HORIZONTAL */
|
||||
@@ -519,9 +519,9 @@ static const struct {
|
||||
{ 0x0aa8, 0x200a }, /* hairspace HAIR SPACE */
|
||||
{ 0x0aa9, 0x2014 }, /* emdash — EM DASH */
|
||||
{ 0x0aaa, 0x2013 }, /* endash – EN DASH */
|
||||
/* 0x0aac signifblank ? ??? */
|
||||
{ 0x0aac, 0x2423 }, /* signifblank ␣ OPEN BOX */
|
||||
{ 0x0aae, 0x2026 }, /* ellipsis … HORIZONTAL ELLIPSIS */
|
||||
/* 0x0aaf doubbaselinedot ? ??? */
|
||||
{ 0x0aaf, 0x2025 }, /* doubbaselinedot ‥ TWO DOT LEADER */
|
||||
{ 0x0ab0, 0x2153 }, /* onethird ⅓ VULGAR FRACTION ONE THIRD */
|
||||
{ 0x0ab1, 0x2154 }, /* twothirds ⅔ VULGAR FRACTION TWO THIRDS */
|
||||
{ 0x0ab2, 0x2155 }, /* onefifth ⅕ VULGAR FRACTION ONE FIFTH */
|
||||
@@ -532,9 +532,9 @@ static const struct {
|
||||
{ 0x0ab7, 0x215a }, /* fivesixths ⅚ VULGAR FRACTION FIVE SIXTHS */
|
||||
{ 0x0ab8, 0x2105 }, /* careof ℅ CARE OF */
|
||||
{ 0x0abb, 0x2012 }, /* figdash ‒ FIGURE DASH */
|
||||
{ 0x0abc, 0x2329 }, /* leftanglebracket 〈 LEFT-POINTING ANGLE BRACKET */
|
||||
{ 0x0abc, 0x27e8 }, /* leftanglebracket ⟨ MATHEMATICAL LEFT ANGLE BRACKET */
|
||||
{ 0x0abd, 0x002e }, /* decimalpoint . FULL STOP */
|
||||
{ 0x0abe, 0x232a }, /* rightanglebracket 〉 RIGHT-POINTING ANGLE BRACKET */
|
||||
{ 0x0abe, 0x27e9 }, /* rightanglebracket ⟩ MATHEMATICAL RIGHT ANGLE BRACKET */
|
||||
/* 0x0abf marker ? ??? */
|
||||
{ 0x0ac3, 0x215b }, /* oneeighth ⅛ VULGAR FRACTION ONE EIGHTH */
|
||||
{ 0x0ac4, 0x215c }, /* threeeighths ⅜ VULGAR FRACTION THREE EIGHTHS */
|
||||
@@ -546,12 +546,13 @@ static const struct {
|
||||
{ 0x0acc, 0x25c1 }, /* leftopentriangle ◁ WHITE LEFT-POINTING TRIANGLE */
|
||||
{ 0x0acd, 0x25b7 }, /* rightopentriangle ▷ WHITE RIGHT-POINTING TRIANGLE */
|
||||
{ 0x0ace, 0x25cb }, /* emopencircle ○ WHITE CIRCLE */
|
||||
{ 0x0acf, 0x25a1 }, /* emopenrectangle □ WHITE SQUARE */
|
||||
{ 0x0acf, 0x25af }, /* emopenrectangle ▯ WHITE VERTICAL RECTANGLE */
|
||||
{ 0x0ad0, 0x2018 }, /* leftsinglequotemark ‘ LEFT SINGLE QUOTATION MARK */
|
||||
{ 0x0ad1, 0x2019 }, /* rightsinglequotemark ’ RIGHT SINGLE QUOTATION MARK */
|
||||
{ 0x0ad2, 0x201c }, /* leftdoublequotemark “ LEFT DOUBLE QUOTATION MARK */
|
||||
{ 0x0ad3, 0x201d }, /* rightdoublequotemark ” RIGHT DOUBLE QUOTATION MARK */
|
||||
{ 0x0ad4, 0x211e }, /* prescription ℞ PRESCRIPTION TAKE */
|
||||
{ 0x0ad5, 0x2030 }, /* permille ‰ PER MILLE SIGN */
|
||||
{ 0x0ad6, 0x2032 }, /* minutes ′ PRIME */
|
||||
{ 0x0ad7, 0x2033 }, /* seconds ″ DOUBLE PRIME */
|
||||
{ 0x0ad9, 0x271d }, /* latincross ✝ LATIN CROSS */
|
||||
@@ -560,7 +561,7 @@ static const struct {
|
||||
{ 0x0adc, 0x25c0 }, /* filledlefttribullet ◀ BLACK LEFT-POINTING TRIANGLE */
|
||||
{ 0x0add, 0x25b6 }, /* filledrighttribullet ▶ BLACK RIGHT-POINTING TRIANGLE */
|
||||
{ 0x0ade, 0x25cf }, /* emfilledcircle ● BLACK CIRCLE */
|
||||
{ 0x0adf, 0x25a0 }, /* emfilledrect ■ BLACK SQUARE */
|
||||
{ 0x0adf, 0x25ae }, /* emfilledrect ▮ BLACK VERTICAL RECTANGLE */
|
||||
{ 0x0ae0, 0x25e6 }, /* enopencircbullet ◦ WHITE BULLET */
|
||||
{ 0x0ae1, 0x25ab }, /* enopensquarebullet ▫ WHITE SMALL SQUARE */
|
||||
{ 0x0ae2, 0x25ad }, /* openrectbullet ▭ WHITE RECTANGLE */
|
||||
@@ -805,15 +806,16 @@ static const struct {
|
||||
{ 0x0ef0, 0x3171 }, /* Hangul_SunkyeongeumMieum ㅱ HANGUL LETTER KAPYEOUNMIEUM */
|
||||
{ 0x0ef1, 0x3178 }, /* Hangul_SunkyeongeumPieub ㅸ HANGUL LETTER KAPYEOUNPIEUP */
|
||||
{ 0x0ef2, 0x317f }, /* Hangul_PanSios ㅿ HANGUL LETTER PANSIOS */
|
||||
/* 0x0ef3 Hangul_KkogjiDalrinIeung ? ??? */
|
||||
{ 0x0ef3, 0x3181 }, /* Hangul_KkogjiDalrinIeung ㆁ HANGUL LETTER YESIEUNG */
|
||||
{ 0x0ef4, 0x3184 }, /* Hangul_SunkyeongeumPhieuf ㆄ HANGUL LETTER KAPYEOUNPHIEUPH */
|
||||
{ 0x0ef5, 0x3186 }, /* Hangul_YeorinHieuh ㆆ HANGUL LETTER YEORINHIEUH */
|
||||
{ 0x0ef6, 0x318d }, /* Hangul_AraeA ㆍ HANGUL LETTER ARAEA */
|
||||
{ 0x0ef7, 0x318e }, /* Hangul_AraeAE ㆎ HANGUL LETTER ARAEAE */
|
||||
{ 0x0ef8, 0x11eb }, /* Hangul_J_PanSios ᇫ HANGUL JONGSEONG PANSIOS */
|
||||
/* 0x0ef9 Hangul_J_KkogjiDalrinIeung ? ??? */
|
||||
{ 0x0ef9, 0x11f0 }, /* Hangul_J_KkogjiDalrinIeung ᇰ HANGUL JONGSEONG YESIEUNG */
|
||||
{ 0x0efa, 0x11f9 }, /* Hangul_J_YeorinHieuh ᇹ HANGUL JONGSEONG YEORINHIEUH */
|
||||
{ 0x0eff, 0x20a9 }, /* Korean_Won ₩ WON SIGN */
|
||||
{ 0x13a4, 0x20ac }, /* Euro € EURO SIGN */
|
||||
{ 0x13bc, 0x0152 }, /* OE Œ LATIN CAPITAL LIGATURE OE */
|
||||
{ 0x13bd, 0x0153 }, /* oe œ LATIN SMALL LIGATURE OE */
|
||||
{ 0x13be, 0x0178 }, /* Ydiaeresis Ÿ LATIN CAPITAL LETTER Y WITH DIAERESIS */
|
||||
@@ -835,18 +837,13 @@ static const struct {
|
||||
/* Following items added to GTK, not in the xterm table */
|
||||
|
||||
/* A few ASCII control characters */
|
||||
#ifndef GDK_WINDOWING_WIN32
|
||||
|
||||
{ 0xFF08 /* Backspace */, '\b' },
|
||||
{ 0xFF09 /* Tab */, '\t' },
|
||||
#endif
|
||||
|
||||
{ 0xFF0A /* Linefeed */, '\n' },
|
||||
{ 0xFF0B /* Vert. Tab */, '\v' },
|
||||
|
||||
#ifndef GDK_WINDOWING_WIN32
|
||||
{ 0xFF0D /* Return */, '\r' },
|
||||
{ 0xFF1B /* Escape */, '\033' },
|
||||
#endif
|
||||
|
||||
/* Numeric keypad */
|
||||
|
||||
@@ -871,9 +868,7 @@ static const struct {
|
||||
|
||||
/* End numeric keypad */
|
||||
|
||||
#ifndef GDK_WINDOWING_WIN32
|
||||
{ 0xFFFF /* Delete */, '\177' }
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -1084,7 +1079,7 @@ static const struct {
|
||||
{ 0x07d7, 0x03a7 }, /* Greek_CHI Χ GREEK CAPITAL LETTER CHI */
|
||||
{ 0x07d8, 0x03a8 }, /* Greek_PSI Ψ GREEK CAPITAL LETTER PSI */
|
||||
{ 0x07d9, 0x03a9 }, /* Greek_OMEGA Ω GREEK CAPITAL LETTER OMEGA */
|
||||
{ 0x07a5, 0x03aa }, /* Greek_IOTAdieresis Ϊ GREEK CAPITAL LETTER IOTA WITH DIALYTIKA */
|
||||
{ 0x07a5, 0x03aa }, /* Greek_IOTAdiaeresis Ϊ GREEK CAPITAL LETTER IOTA WITH DIALYTIKA */
|
||||
{ 0x07a9, 0x03ab }, /* Greek_UPSILONdieresis Ϋ GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA */
|
||||
{ 0x07b1, 0x03ac }, /* Greek_alphaaccent ά GREEK SMALL LETTER ALPHA WITH TONOS */
|
||||
{ 0x07b2, 0x03ad }, /* Greek_epsilonaccent έ GREEK SMALL LETTER EPSILON WITH TONOS */
|
||||
@@ -1399,6 +1394,7 @@ static const struct {
|
||||
{ 0x0eed, 0x11c1 }, /* Hangul_J_Phieuf ᇁ HANGUL JONGSEONG PHIEUPH */
|
||||
{ 0x0eee, 0x11c2 }, /* Hangul_J_Hieuh ᇂ HANGUL JONGSEONG HIEUH */
|
||||
{ 0x0ef8, 0x11eb }, /* Hangul_J_PanSios ᇫ HANGUL JONGSEONG PANSIOS */
|
||||
{ 0x0ef9, 0x11f0 }, /* Hangul_J_KkogjiDalrinIeung ᇰ HANGUL JONGSEONG YESIEUNG */
|
||||
{ 0x0efa, 0x11f9 }, /* Hangul_J_YeorinHieuh ᇹ HANGUL JONGSEONG YEORINHIEUH */
|
||||
{ 0x0aa2, 0x2002 }, /* enspace EN SPACE */
|
||||
{ 0x0aa1, 0x2003 }, /* emspace EM SPACE */
|
||||
@@ -1422,7 +1418,9 @@ static const struct {
|
||||
{ 0x0af1, 0x2020 }, /* dagger † DAGGER */
|
||||
{ 0x0af2, 0x2021 }, /* doubledagger ‡ DOUBLE DAGGER */
|
||||
{ 0x0ae6, 0x2022 }, /* enfilledcircbullet • BULLET */
|
||||
{ 0x0aaf, 0x2025 }, /* doubbaselinedot ‥ TWO DOT LEADER */
|
||||
{ 0x0aae, 0x2026 }, /* ellipsis … HORIZONTAL ELLIPSIS */
|
||||
{ 0x0ad5, 0x2030 }, /* permille ‰ PER MILLE SIGN */
|
||||
{ 0x0ad6, 0x2032 }, /* minutes ′ PRIME */
|
||||
{ 0x0ad7, 0x2033 }, /* seconds ″ DOUBLE PRIME */
|
||||
{ 0x0afc, 0x2038 }, /* caret ‸ CARET */
|
||||
@@ -1480,7 +1478,8 @@ static const struct {
|
||||
{ 0x0bd6, 0x222a }, /* downshoe ∪ UNION */
|
||||
{ 0x08bf, 0x222b }, /* integral ∫ INTEGRAL */
|
||||
{ 0x08c0, 0x2234 }, /* therefore ∴ THEREFORE */
|
||||
{ 0x08c8, 0x2245 }, /* approximate ≅ APPROXIMATELY EQUAL TO */
|
||||
{ 0x08c8, 0x223c }, /* approximate ∼ TILDE OPERATOR */
|
||||
{ 0x08c9, 0x2243 }, /* similarequal ≃ ASYMPTOTICALLY EQUAL TO */
|
||||
{ 0x08bd, 0x2260 }, /* notequal ≠ NOT EQUAL TO */
|
||||
{ 0x08cf, 0x2261 }, /* identical ≡ IDENTICAL TO */
|
||||
{ 0x08bc, 0x2264 }, /* lessthanequal ≤ LESS-THAN OR EQUAL TO */
|
||||
@@ -1498,15 +1497,28 @@ static const struct {
|
||||
{ 0x0afa, 0x2315 }, /* telephonerecorder ⌕ TELEPHONE RECORDER */
|
||||
{ 0x08a4, 0x2320 }, /* topintegral ⌠ TOP HALF INTEGRAL */
|
||||
{ 0x08a5, 0x2321 }, /* botintegral ⌡ BOTTOM HALF INTEGRAL */
|
||||
{ 0x0abc, 0x2329 }, /* leftanglebracket 〈 LEFT-POINTING ANGLE BRACKET */
|
||||
{ 0x0abe, 0x232a }, /* rightanglebracket 〉 RIGHT-POINTING ANGLE BRACKET */
|
||||
{ 0x0bcc, 0x2395 }, /* quad ⎕ APL FUNCTIONAL SYMBOL QUAD (Unicode 3.0) */
|
||||
{ 0x08a7, 0x23a1 }, /* topleftsqbracket ⎡ ??? */
|
||||
{ 0x08a8, 0x23a3 }, /* botleftsqbracket ⎣ ??? */
|
||||
{ 0x08a9, 0x23a4 }, /* toprightsqbracket ⎤ ??? */
|
||||
{ 0x08aa, 0x23a6 }, /* botrightsqbracket ⎦ ??? */
|
||||
{ 0x08ab, 0x239b }, /* topleftparens ⎛ ??? */
|
||||
{ 0x08ac, 0x239d }, /* botleftparens ⎝ ??? */
|
||||
{ 0x08ad, 0x239e }, /* toprightparens ⎞ ??? */
|
||||
{ 0x08ae, 0x23a0 }, /* botrightparens ⎠ ??? */
|
||||
{ 0x08af, 0x23a8 }, /* leftmiddlecurlybrace ⎨ ??? */
|
||||
{ 0x08b0, 0x23ac }, /* rightmiddlecurlybrace ⎬ ??? */
|
||||
{ 0x08a1, 0x23b7 }, /* leftradical ⎷ ??? */
|
||||
{ 0x09ef, 0x23ba }, /* horizlinescan1 ⎺ HORIZONTAL SCAN LINE-1 (Unicode 3.2 draft) */
|
||||
{ 0x09f0, 0x23bb }, /* horizlinescan3 ⎻ HORIZONTAL SCAN LINE-3 (Unicode 3.2 draft) */
|
||||
{ 0x09f2, 0x23bc }, /* horizlinescan7 ⎼ HORIZONTAL SCAN LINE-7 (Unicode 3.2 draft) */
|
||||
{ 0x09f3, 0x23bd }, /* horizlinescan9 ⎽ HORIZONTAL SCAN LINE-9 (Unicode 3.2 draft) */
|
||||
{ 0x09e2, 0x2409 }, /* ht ␉ SYMBOL FOR HORIZONTAL TABULATION */
|
||||
{ 0x09e5, 0x240a }, /* lf ␊ SYMBOL FOR LINE FEED */
|
||||
{ 0x09e9, 0x240b }, /* vt ␋ SYMBOL FOR VERTICAL TABULATION */
|
||||
{ 0x09e3, 0x240c }, /* ff ␌ SYMBOL FOR FORM FEED */
|
||||
{ 0x09e4, 0x240d }, /* cr ␍ SYMBOL FOR CARRIAGE RETURN */
|
||||
{ 0x09df, 0x2422 }, /* blank ␢ BLANK SYMBOL */
|
||||
{ 0x0aac, 0x2423 }, /* signifblank ␣ OPEN BOX */
|
||||
{ 0x09e8, 0x2424 }, /* nl  SYMBOL FOR NEWLINE */
|
||||
{ 0x09f1, 0x2500 }, /* horizlinescan5 ─ BOX DRAWINGS LIGHT HORIZONTAL */
|
||||
{ 0x08a6, 0x2502 }, /* vertconnector │ BOX DRAWINGS LIGHT VERTICAL */
|
||||
@@ -1522,11 +1534,11 @@ static const struct {
|
||||
{ 0x09ee, 0x253c }, /* crossinglines ┼ BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL */
|
||||
{ 0x09e1, 0x2592 }, /* checkerboard ▒ MEDIUM SHADE */
|
||||
{ 0x0adf, 0x25a0 }, /* emfilledrect ■ BLACK SQUARE */
|
||||
{ 0x0acf, 0x25a1 }, /* emopenrectangle □ WHITE SQUARE */
|
||||
{ 0x0ae7, 0x25aa }, /* enfilledsqbullet ▪ BLACK SMALL SQUARE */
|
||||
{ 0x0ae1, 0x25ab }, /* enopensquarebullet ▫ WHITE SMALL SQUARE */
|
||||
{ 0x0adb, 0x25ac }, /* filledrectbullet ▬ BLACK RECTANGLE */
|
||||
{ 0x0ae2, 0x25ad }, /* openrectbullet ▭ WHITE RECTANGLE */
|
||||
{ 0x0acf, 0x25af }, /* emopenrectangle ▯ WHITE VERTICAL RECTANGLE */
|
||||
{ 0x0ae8, 0x25b2 }, /* filledtribulletup ▲ BLACK UP-POINTING TRIANGLE */
|
||||
{ 0x0ae3, 0x25b3 }, /* opentribulletup △ WHITE UP-POINTING TRIANGLE */
|
||||
{ 0x0add, 0x25b6 }, /* filledrighttribullet ▶ BLACK RIGHT-POINTING TRIANGLE */
|
||||
@@ -1556,6 +1568,8 @@ static const struct {
|
||||
{ 0x0af4, 0x2717 }, /* ballotcross ✗ BALLOT X */
|
||||
{ 0x0ad9, 0x271d }, /* latincross ✝ LATIN CROSS */
|
||||
{ 0x0af0, 0x2720 }, /* maltesecross ✠ MALTESE CROSS */
|
||||
{ 0x0abc, 0x27e8 }, /* leftanglebracket ⟨ MATHEMATICAL LEFT ANGLE BRACKET */
|
||||
{ 0x0abe, 0x27e9 }, /* rightanglebracket ⟩ MATHEMATICAL RIGHT ANGLE BRACKET */
|
||||
{ 0x04a4, 0x3001 }, /* kana_comma 、 IDEOGRAPHIC COMMA */
|
||||
{ 0x04a1, 0x3002 }, /* kana_fullstop 。 IDEOGRAPHIC FULL STOP */
|
||||
{ 0x04a2, 0x300c }, /* kana_openingbracket 「 LEFT CORNER BRACKET */
|
||||
@@ -1674,6 +1688,7 @@ static const struct {
|
||||
{ 0x0ef0, 0x3171 }, /* Hangul_SunkyeongeumMieum ㅱ HANGUL LETTER KAPYEOUNMIEUM */
|
||||
{ 0x0ef1, 0x3178 }, /* Hangul_SunkyeongeumPieub ㅸ HANGUL LETTER KAPYEOUNPIEUP */
|
||||
{ 0x0ef2, 0x317f }, /* Hangul_PanSios ㅿ HANGUL LETTER PANSIOS */
|
||||
{ 0x0ef3, 0x3181 }, /* Hangul_KkogjiDalrinIeung ㆁ HANGUL LETTER YESIEUNG */
|
||||
{ 0x0ef4, 0x3184 }, /* Hangul_SunkyeongeumPhieuf ㆄ HANGUL LETTER KAPYEOUNPHIEUPH */
|
||||
{ 0x0ef5, 0x3186 }, /* Hangul_YeorinHieuh ㆆ HANGUL LETTER YEORINHIEUH */
|
||||
{ 0x0ef6, 0x318d }, /* Hangul_AraeA ㆍ HANGUL LETTER ARAEA */
|
||||
|
||||
@@ -2,3 +2,4 @@ BOOLEAN:BOXED
|
||||
BOOLEAN:OBJECT
|
||||
BOOLEAN:POINTER
|
||||
VOID:POINTER,POINTER,BOOLEAN,BOOLEAN
|
||||
VOID:INT,INT
|
||||
|
||||
@@ -166,6 +166,54 @@ r32g32b32a32_float_from_float (guchar *dest,
|
||||
memcpy (dest, src, sizeof (float) * n * 4);
|
||||
}
|
||||
|
||||
#define PREMULTIPLY_FUNC(name, R1, G1, B1, A1, R2, G2, B2, A2) \
|
||||
static void \
|
||||
name (guchar *dest, \
|
||||
const guchar *src, \
|
||||
gsize n) \
|
||||
{ \
|
||||
for (; n > 0; n--) \
|
||||
{ \
|
||||
guchar a = src[A1]; \
|
||||
guint16 r = (guint16)src[R1] * a + 127; \
|
||||
guint16 g = (guint16)src[G1] * a + 127; \
|
||||
guint16 b = (guint16)src[B1] * a + 127; \
|
||||
dest[R2] = (r + (r >> 8) + 1) >> 8; \
|
||||
dest[G2] = (g + (g >> 8) + 1) >> 8; \
|
||||
dest[B2] = (b + (b >> 8) + 1) >> 8; \
|
||||
dest[A2] = a; \
|
||||
dest += 4; \
|
||||
src += 4; \
|
||||
} \
|
||||
}
|
||||
|
||||
PREMULTIPLY_FUNC(r8g8b8a8_to_r8g8b8a8_premultiplied, 0, 1, 2, 3, 0, 1, 2, 3)
|
||||
PREMULTIPLY_FUNC(r8g8b8a8_to_b8g8r8a8_premultiplied, 0, 1, 2, 3, 2, 1, 0, 3)
|
||||
PREMULTIPLY_FUNC(r8g8b8a8_to_a8r8g8b8_premultiplied, 0, 1, 2, 3, 1, 2, 3, 0)
|
||||
PREMULTIPLY_FUNC(r8g8b8a8_to_a8b8g8r8_premultiplied, 0, 1, 2, 3, 3, 2, 1, 0)
|
||||
|
||||
#define ADD_ALPHA_FUNC(name, R1, G1, B1, R2, G2, B2, A2) \
|
||||
static void \
|
||||
name (guchar *dest, \
|
||||
const guchar *src, \
|
||||
gsize n) \
|
||||
{ \
|
||||
for (; n > 0; n--) \
|
||||
{ \
|
||||
dest[R2] = src[R1]; \
|
||||
dest[G2] = src[G1]; \
|
||||
dest[B2] = src[B1]; \
|
||||
dest[A2] = 255; \
|
||||
dest += 4; \
|
||||
src += 3; \
|
||||
} \
|
||||
}
|
||||
|
||||
ADD_ALPHA_FUNC(r8g8b8_to_r8g8b8a8, 0, 1, 2, 0, 1, 2, 3)
|
||||
ADD_ALPHA_FUNC(r8g8b8_to_b8g8r8a8, 0, 1, 2, 2, 1, 0, 3)
|
||||
ADD_ALPHA_FUNC(r8g8b8_to_a8r8g8b8, 0, 1, 2, 1, 2, 3, 0)
|
||||
ADD_ALPHA_FUNC(r8g8b8_to_a8b8g8r8, 0, 1, 2, 3, 2, 1, 0)
|
||||
|
||||
struct _GdkMemoryFormatDescription
|
||||
{
|
||||
GdkMemoryAlpha alpha;
|
||||
@@ -475,10 +523,59 @@ gdk_memory_convert (guchar *dest_data,
|
||||
const GdkMemoryFormatDescription *src_desc = &memory_formats[src_format];
|
||||
float *tmp;
|
||||
gsize y;
|
||||
void (*func) (guchar *, const guchar *, gsize) = NULL;
|
||||
|
||||
g_assert (dest_format < GDK_MEMORY_N_FORMATS);
|
||||
g_assert (src_format < GDK_MEMORY_N_FORMATS);
|
||||
|
||||
if (src_format == GDK_MEMORY_R8G8B8A8 && dest_format == GDK_MEMORY_R8G8B8A8_PREMULTIPLIED)
|
||||
func = r8g8b8a8_to_r8g8b8a8_premultiplied;
|
||||
else if (src_format == GDK_MEMORY_B8G8R8A8 && dest_format == GDK_MEMORY_R8G8B8A8_PREMULTIPLIED)
|
||||
func = r8g8b8a8_to_b8g8r8a8_premultiplied;
|
||||
else if (src_format == GDK_MEMORY_R8G8B8A8 && dest_format == GDK_MEMORY_B8G8R8A8_PREMULTIPLIED)
|
||||
func = r8g8b8a8_to_b8g8r8a8_premultiplied;
|
||||
else if (src_format == GDK_MEMORY_B8G8R8A8 && dest_format == GDK_MEMORY_B8G8R8A8_PREMULTIPLIED)
|
||||
func = r8g8b8a8_to_r8g8b8a8_premultiplied;
|
||||
else if (src_format == GDK_MEMORY_R8G8B8A8 && dest_format == GDK_MEMORY_A8R8G8B8_PREMULTIPLIED)
|
||||
func = r8g8b8a8_to_a8r8g8b8_premultiplied;
|
||||
else if (src_format == GDK_MEMORY_B8G8R8A8 && dest_format == GDK_MEMORY_A8R8G8B8_PREMULTIPLIED)
|
||||
func = r8g8b8a8_to_a8b8g8r8_premultiplied;
|
||||
else if (src_format == GDK_MEMORY_R8G8B8 && dest_format == GDK_MEMORY_R8G8B8A8_PREMULTIPLIED)
|
||||
func = r8g8b8_to_r8g8b8a8;
|
||||
else if (src_format == GDK_MEMORY_B8G8R8 && dest_format == GDK_MEMORY_R8G8B8A8_PREMULTIPLIED)
|
||||
func = r8g8b8_to_b8g8r8a8;
|
||||
else if (src_format == GDK_MEMORY_R8G8B8 && dest_format == GDK_MEMORY_B8G8R8A8_PREMULTIPLIED)
|
||||
func = r8g8b8_to_b8g8r8a8;
|
||||
else if (src_format == GDK_MEMORY_B8G8R8 && dest_format == GDK_MEMORY_B8G8R8A8_PREMULTIPLIED)
|
||||
func = r8g8b8_to_r8g8b8a8;
|
||||
else if (src_format == GDK_MEMORY_R8G8B8 && dest_format == GDK_MEMORY_A8R8G8B8_PREMULTIPLIED)
|
||||
func = r8g8b8_to_a8r8g8b8;
|
||||
else if (src_format == GDK_MEMORY_B8G8R8 && dest_format == GDK_MEMORY_A8R8G8B8_PREMULTIPLIED)
|
||||
func = r8g8b8_to_a8b8g8r8;
|
||||
else if (src_format == GDK_MEMORY_R8G8B8 && dest_format == GDK_MEMORY_R8G8B8A8)
|
||||
func = r8g8b8_to_r8g8b8a8;
|
||||
else if (src_format == GDK_MEMORY_B8G8R8 && dest_format == GDK_MEMORY_R8G8B8A8)
|
||||
func = r8g8b8_to_b8g8r8a8;
|
||||
else if (src_format == GDK_MEMORY_R8G8B8 && dest_format == GDK_MEMORY_B8G8R8A8)
|
||||
func = r8g8b8_to_b8g8r8a8;
|
||||
else if (src_format == GDK_MEMORY_B8G8R8 && dest_format == GDK_MEMORY_B8G8R8A8)
|
||||
func = r8g8b8_to_r8g8b8a8;
|
||||
else if (src_format == GDK_MEMORY_R8G8B8 && dest_format == GDK_MEMORY_A8R8G8B8)
|
||||
func = r8g8b8_to_a8r8g8b8;
|
||||
else if (src_format == GDK_MEMORY_B8G8R8 && dest_format == GDK_MEMORY_A8R8G8B8)
|
||||
func = r8g8b8_to_a8b8g8r8;
|
||||
|
||||
if (func != NULL)
|
||||
{
|
||||
for (y = 0; y < height; y++)
|
||||
{
|
||||
func (dest_data, src_data, width);
|
||||
src_data += src_stride;
|
||||
dest_data += dest_stride;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
tmp = g_new (float, width * 4);
|
||||
|
||||
for (y = 0; y < height; y++)
|
||||
|
||||
@@ -133,10 +133,10 @@ gdk_memory_sanitize (GBytes *bytes,
|
||||
*
|
||||
* Creates a new texture for a blob of image data.
|
||||
*
|
||||
* The `GBytes` must contain @stride x @height pixels
|
||||
* The `GBytes` must contain @stride × @height pixels
|
||||
* in the given format.
|
||||
*
|
||||
* Returns: A newly-created `GdkTexture`
|
||||
* Returns: (type GdkMemoryTexture): A newly-created `GdkTexture`
|
||||
*/
|
||||
GdkTexture *
|
||||
gdk_memory_texture_new (int width,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2000 Red Hat, Inc.
|
||||
* Copyright (C) 2000 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -52,25 +52,25 @@ layout_iter_get_line_clip_region (PangoLayoutIter *iter,
|
||||
|
||||
i = 0;
|
||||
while (i < n_ranges)
|
||||
{
|
||||
{
|
||||
int *pixel_ranges = NULL;
|
||||
int n_pixel_ranges = 0;
|
||||
int j;
|
||||
|
||||
/* Note that get_x_ranges returns layout coordinates
|
||||
*/
|
||||
if (index_ranges[i*2+1] >= line->start_index &&
|
||||
index_ranges[i*2] < line->start_index + line->length)
|
||||
if (index_ranges[i*2+1] >= pango_layout_line_get_start_index (line) &&
|
||||
index_ranges[i*2] < pango_layout_line_get_start_index (line) + pango_layout_line_get_length (line))
|
||||
pango_layout_line_get_x_ranges (line,
|
||||
index_ranges[i*2],
|
||||
index_ranges[i*2+1],
|
||||
&pixel_ranges, &n_pixel_ranges);
|
||||
|
||||
|
||||
for (j = 0; j < n_pixel_ranges; j++)
|
||||
{
|
||||
GdkRectangle rect;
|
||||
int x_off, y_off;
|
||||
|
||||
|
||||
x_off = PANGO_PIXELS (pixel_ranges[2*j] - logical_rect.x);
|
||||
y_off = PANGO_PIXELS (baseline - logical_rect.y);
|
||||
|
||||
@@ -124,14 +124,14 @@ gdk_pango_layout_line_get_clip_region (PangoLayoutLine *line,
|
||||
{
|
||||
cairo_region_t *clip_region;
|
||||
PangoLayoutIter *iter;
|
||||
|
||||
|
||||
g_return_val_if_fail (line != NULL, NULL);
|
||||
g_return_val_if_fail (index_ranges != NULL, NULL);
|
||||
|
||||
|
||||
iter = pango_layout_get_iter (line->layout);
|
||||
while (pango_layout_iter_get_line_readonly (iter) != line)
|
||||
pango_layout_iter_next_line (iter);
|
||||
|
||||
|
||||
clip_region = layout_iter_get_line_clip_region(iter, x_origin, y_origin, index_ranges, n_ranges);
|
||||
|
||||
pango_layout_iter_free (iter);
|
||||
@@ -167,26 +167,26 @@ gdk_pango_layout_get_clip_region (PangoLayout *layout,
|
||||
const int *index_ranges,
|
||||
int n_ranges)
|
||||
{
|
||||
PangoLayoutIter *iter;
|
||||
PangoLayoutIter *iter;
|
||||
cairo_region_t *clip_region;
|
||||
|
||||
|
||||
g_return_val_if_fail (PANGO_IS_LAYOUT (layout), NULL);
|
||||
g_return_val_if_fail (index_ranges != NULL, NULL);
|
||||
|
||||
|
||||
clip_region = cairo_region_create ();
|
||||
|
||||
|
||||
iter = pango_layout_get_iter (layout);
|
||||
|
||||
|
||||
do
|
||||
{
|
||||
PangoRectangle logical_rect;
|
||||
cairo_region_t *line_region;
|
||||
int baseline;
|
||||
|
||||
pango_layout_iter_get_line_extents (iter, NULL, &logical_rect);
|
||||
baseline = pango_layout_iter_get_baseline (iter);
|
||||
|
||||
line_region = layout_iter_get_line_clip_region(iter,
|
||||
pango_layout_iter_get_line_extents (iter, NULL, &logical_rect);
|
||||
baseline = pango_layout_iter_get_baseline (iter);
|
||||
|
||||
line_region = layout_iter_get_line_clip_region(iter,
|
||||
x_origin + PANGO_PIXELS (logical_rect.x),
|
||||
y_origin + PANGO_PIXELS (baseline),
|
||||
index_ranges,
|
||||
|
||||
@@ -187,7 +187,7 @@ gdk_popup_get_rect_anchor (GdkPopup *popup)
|
||||
*
|
||||
* Returns the parent surface of a popup.
|
||||
*
|
||||
* Returns: (transfer none): the parent surface
|
||||
* Returns: (transfer none) (nullable): the parent surface
|
||||
*/
|
||||
GdkSurface *
|
||||
gdk_popup_get_parent (GdkPopup *popup)
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
((_GDK_RGBA_SELECT_COLOR(str, 0, 0) << 4) | _GDK_RGBA_SELECT_COLOR(str, 0, 1)) / 255., \
|
||||
((_GDK_RGBA_SELECT_COLOR(str, 1, 2) << 4) | _GDK_RGBA_SELECT_COLOR(str, 1, 3)) / 255., \
|
||||
((_GDK_RGBA_SELECT_COLOR(str, 2, 4) << 4) | _GDK_RGBA_SELECT_COLOR(str, 2, 5)) / 255., \
|
||||
((sizeof(str) % 4 == 1) ? ((_GDK_RGBA_SELECT_COLOR(str, 3, 6) << 4) | _GDK_RGBA_SELECT_COLOR(str, 3, 7)) : 0xFF) / 255 })
|
||||
((sizeof(str) % 4 == 1) ? ((_GDK_RGBA_SELECT_COLOR(str, 3, 6) << 4) | _GDK_RGBA_SELECT_COLOR(str, 3, 7)) : 0xFF) / 255. })
|
||||
|
||||
|
||||
gboolean gdk_rgba_parser_parse (GtkCssParser *parser,
|
||||
|
||||
@@ -605,11 +605,14 @@ gdk_surface_class_init (GdkSurfaceClass *klass)
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
_gdk_marshal_VOID__INT_INT,
|
||||
G_TYPE_NONE,
|
||||
2,
|
||||
G_TYPE_INT,
|
||||
G_TYPE_INT);
|
||||
g_signal_set_va_marshaller (signals[LAYOUT],
|
||||
G_OBJECT_CLASS_TYPE (object_class),
|
||||
_gdk_marshal_VOID__INT_INTv);
|
||||
|
||||
/**
|
||||
* GdkSurface::render:
|
||||
@@ -1092,6 +1095,7 @@ gdk_surface_set_egl_native_window (GdkSurface *self,
|
||||
|
||||
if (priv->egl_surface != NULL)
|
||||
{
|
||||
gdk_gl_context_clear_current_if_surface (self);
|
||||
eglDestroySurface (gdk_surface_get_display (self), priv->egl_surface);
|
||||
priv->egl_surface = NULL;
|
||||
}
|
||||
@@ -1120,7 +1124,8 @@ gdk_surface_ensure_egl_surface (GdkSurface *self,
|
||||
priv->egl_surface != NULL &&
|
||||
gdk_display_get_egl_config_high_depth (display) != gdk_display_get_egl_config (display))
|
||||
{
|
||||
eglDestroySurface (gdk_surface_get_display (self), priv->egl_surface);
|
||||
gdk_gl_context_clear_current_if_surface (self);
|
||||
eglDestroySurface (gdk_display_get_egl_display (display), priv->egl_surface);
|
||||
priv->egl_surface = NULL;
|
||||
}
|
||||
|
||||
@@ -2239,7 +2244,7 @@ _gdk_windowing_got_event (GdkDisplay *display,
|
||||
GdkEvent *event,
|
||||
gulong serial)
|
||||
{
|
||||
GdkSurface *event_surface;
|
||||
GdkSurface *event_surface = NULL;
|
||||
gboolean unlink_event = FALSE;
|
||||
GdkDeviceGrabInfo *button_release_grab;
|
||||
GdkPointerSurfaceInfo *pointer_info = NULL;
|
||||
@@ -2331,6 +2336,14 @@ _gdk_windowing_got_event (GdkDisplay *display,
|
||||
*/
|
||||
_gdk_event_queue_handle_motion_compression (display);
|
||||
gdk_event_queue_handle_scroll_compression (display);
|
||||
|
||||
if (event_surface)
|
||||
{
|
||||
GdkFrameClock *clock = gdk_surface_get_frame_clock (event_surface);
|
||||
|
||||
if (clock) /* might be NULL if surface was destroyed */
|
||||
gdk_frame_clock_request_phase (clock, GDK_FRAME_CLOCK_PHASE_FLUSH_EVENTS);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -25,14 +25,14 @@
|
||||
* multiple frames, and will be used for a long time.
|
||||
*
|
||||
* There are various ways to create `GdkTexture` objects from a
|
||||
* `GdkPixbuf`, or a Cairo surface, or other pixel data.
|
||||
* [class@GdkPixbuf.Pixbuf], or a Cairo surface, or other pixel data.
|
||||
*
|
||||
* The ownership of the pixel data is transferred to the `GdkTexture`
|
||||
* instance; you can only make a copy of it, via [method@Gdk.Texture.download].
|
||||
*
|
||||
* `GdkTexture` is an immutable object: That means you cannot change
|
||||
* anything about it other than increasing the reference count via
|
||||
* g_object_ref().
|
||||
* [method@GObject.Object.ref], and consequently, it is a thread-safe object.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
@@ -346,7 +346,7 @@ gdk_texture_init (GdkTexture *self)
|
||||
*
|
||||
* Creates a new texture object representing the surface.
|
||||
*
|
||||
* @surface must be an image surface with format CAIRO_FORMAT_ARGB32.
|
||||
* @surface must be an image surface with format `CAIRO_FORMAT_ARGB32`.
|
||||
*
|
||||
* Returns: a new `GdkTexture`
|
||||
*/
|
||||
@@ -384,7 +384,7 @@ gdk_texture_new_for_surface (cairo_surface_t *surface)
|
||||
* Creates a new texture object representing the `GdkPixbuf`.
|
||||
*
|
||||
* This function is threadsafe, so that you can e.g. use GTask
|
||||
* and g_task_run_in_thread() to avoid blocking the main thread
|
||||
* and [method@Gio.Task.run_in_thread] to avoid blocking the main thread
|
||||
* while loading a big image.
|
||||
*
|
||||
* Returns: a new `GdkTexture`
|
||||
@@ -430,7 +430,7 @@ gdk_texture_new_for_pixbuf (GdkPixbuf *pixbuf)
|
||||
* [ctor@Gdk.Texture.new_from_file] to load it.
|
||||
*
|
||||
* This function is threadsafe, so that you can e.g. use GTask
|
||||
* and g_task_run_in_thread() to avoid blocking the main thread
|
||||
* and [method@Gio.Task.run_in_thread] to avoid blocking the main thread
|
||||
* while loading a big image.
|
||||
*
|
||||
* Return value: A newly-created `GdkTexture`
|
||||
@@ -454,7 +454,7 @@ gdk_texture_new_from_resource (const char *resource_path)
|
||||
texture = NULL;
|
||||
|
||||
if (texture == NULL)
|
||||
g_error ("Resource path %s s not a valid image: %s", resource_path, error->message);
|
||||
g_error ("Resource path %s is not a valid image: %s", resource_path, error->message);
|
||||
|
||||
return texture;
|
||||
}
|
||||
@@ -472,7 +472,7 @@ gdk_texture_new_from_resource (const char *resource_path)
|
||||
* If %NULL is returned, then @error will be set.
|
||||
*
|
||||
* This function is threadsafe, so that you can e.g. use GTask
|
||||
* and g_task_run_in_thread() to avoid blocking the main thread
|
||||
* and [method@Gio.Task.run_in_thread] to avoid blocking the main thread
|
||||
* while loading a big image.
|
||||
*
|
||||
* Return value: A newly-created `GdkTexture`
|
||||
@@ -565,7 +565,7 @@ gdk_texture_new_from_bytes_pixbuf (GBytes *bytes,
|
||||
* If %NULL is returned, then @error will be set.
|
||||
*
|
||||
* This function is threadsafe, so that you can e.g. use GTask
|
||||
* and g_task_run_in_thread() to avoid blocking the main thread
|
||||
* and [method@Gio.Task.run_in_thread] to avoid blocking the main thread
|
||||
* while loading a big image.
|
||||
*
|
||||
* Return value: A newly-created `GdkTexture`
|
||||
@@ -611,7 +611,7 @@ gdk_texture_new_from_bytes (GBytes *bytes,
|
||||
* If %NULL is returned, then @error will be set.
|
||||
*
|
||||
* This function is threadsafe, so that you can e.g. use GTask
|
||||
* and g_task_run_in_thread() to avoid blocking the main thread
|
||||
* and [method@Gio.Task.run_in_thread] to avoid blocking the main thread
|
||||
* while loading a big image.
|
||||
*
|
||||
* Return value: A newly-created `GdkTexture`
|
||||
@@ -796,7 +796,7 @@ gdk_texture_get_render_data (GdkTexture *self,
|
||||
*
|
||||
* This is a utility function intended for debugging and testing.
|
||||
* If you want more control over formats, proper error handling or
|
||||
* want to store to a `GFile` or other location, you might want to
|
||||
* want to store to a [iface@Gio.File] or other location, you might want to
|
||||
* use [method@Gdk.Texture.save_to_png_bytes] or look into the
|
||||
* gdk-pixbuf library.
|
||||
*
|
||||
|
||||
@@ -89,10 +89,6 @@ GDK_AVAILABLE_IN_ALL
|
||||
void gdk_texture_download (GdkTexture *texture,
|
||||
guchar *data,
|
||||
gsize stride);
|
||||
GDK_AVAILABLE_IN_4_6
|
||||
void gdk_texture_download_float (GdkTexture *texture,
|
||||
float *data,
|
||||
gsize stride);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gdk_texture_save_to_png (GdkTexture *texture,
|
||||
const char *filename);
|
||||
|
||||
@@ -32,6 +32,9 @@ G_DEFINE_POINTER_TYPE (GdkToplevelSize, gdk_toplevel_size)
|
||||
#define UNCONFIGURED_WIDTH 400
|
||||
#define UNCONFIGURED_HEIGHT 300
|
||||
|
||||
#define DEFAULT_BOUNDS_WIDTH INT_MAX
|
||||
#define DEFAULT_BOUNDS_HEIGHT INT_MAX
|
||||
|
||||
void
|
||||
gdk_toplevel_size_init (GdkToplevelSize *size,
|
||||
int bounds_width,
|
||||
@@ -68,8 +71,15 @@ gdk_toplevel_size_get_bounds (GdkToplevelSize *size,
|
||||
g_return_if_fail (bounds_width);
|
||||
g_return_if_fail (bounds_height);
|
||||
|
||||
*bounds_width = size->bounds_width;
|
||||
*bounds_height = size->bounds_height;
|
||||
if (size->bounds_width > 0)
|
||||
*bounds_width = size->bounds_width;
|
||||
else
|
||||
*bounds_width = DEFAULT_BOUNDS_WIDTH;
|
||||
|
||||
if (size->bounds_height > 0)
|
||||
*bounds_height = size->bounds_height;
|
||||
else
|
||||
*bounds_height = DEFAULT_BOUNDS_HEIGHT;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -83,6 +83,8 @@
|
||||
*
|
||||
* A macro that evaluates to the 4.2 version of GDK, in a format
|
||||
* that can be used by the C pre-processor.
|
||||
*
|
||||
* Since: 4.2
|
||||
*/
|
||||
#define GDK_VERSION_4_2 (G_ENCODE_VERSION (4, 2))
|
||||
|
||||
@@ -91,6 +93,8 @@
|
||||
*
|
||||
* A macro that evaluates to the 4.4 version of GDK, in a format
|
||||
* that can be used by the C pre-processor.
|
||||
*
|
||||
* Since: 4.4
|
||||
*/
|
||||
#define GDK_VERSION_4_4 (G_ENCODE_VERSION (4, 4))
|
||||
|
||||
@@ -99,6 +103,8 @@
|
||||
*
|
||||
* A macro that evaluates to the 4.6 version of GDK, in a format
|
||||
* that can be used by the C pre-processor.
|
||||
*
|
||||
* Since: 4.6
|
||||
*/
|
||||
#define GDK_VERSION_4_6 (G_ENCODE_VERSION (4, 6))
|
||||
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gdkjpegprivate.h"
|
||||
|
||||
@@ -222,11 +222,7 @@ gdk_load_png (GBytes *bytes,
|
||||
case PNG_COLOR_TYPE_RGB_ALPHA:
|
||||
if (depth == 8)
|
||||
{
|
||||
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
|
||||
format = GDK_MEMORY_R8G8B8A8;
|
||||
#elif G_BYTE_ORDER == G_BIG_ENDIAN
|
||||
format = GDK_MEMORY_A8B8G8R8;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -236,11 +232,7 @@ gdk_load_png (GBytes *bytes,
|
||||
case PNG_COLOR_TYPE_RGB:
|
||||
if (depth == 8)
|
||||
{
|
||||
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
|
||||
format = GDK_MEMORY_R8G8B8;
|
||||
#elif G_BYTE_ORDER == G_BIG_ENDIAN
|
||||
format = GDK_MEMORY_B8G8R8;
|
||||
#endif
|
||||
}
|
||||
else if (depth == 16)
|
||||
{
|
||||
@@ -325,22 +317,14 @@ gdk_save_png (GdkTexture *texture)
|
||||
case GDK_MEMORY_A8R8G8B8:
|
||||
case GDK_MEMORY_R8G8B8A8:
|
||||
case GDK_MEMORY_A8B8G8R8:
|
||||
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
|
||||
format = GDK_MEMORY_R8G8B8A8;
|
||||
#elif G_BYTE_ORDER == G_BIG_ENDIAN
|
||||
format = GDK_MEMORY_A8B8G8R8;
|
||||
#endif
|
||||
png_format = PNG_COLOR_TYPE_RGB_ALPHA;
|
||||
depth = 8;
|
||||
break;
|
||||
|
||||
case GDK_MEMORY_R8G8B8:
|
||||
case GDK_MEMORY_B8G8R8:
|
||||
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
|
||||
format = GDK_MEMORY_R8G8B8;
|
||||
#elif G_BYTE_ORDER == G_BIG_ENDIAN
|
||||
format = GDK_MEMORY_B8G8R8;
|
||||
#endif
|
||||
png_format = PNG_COLOR_TYPE_RGB;
|
||||
depth = 8;
|
||||
break;
|
||||
|
||||
@@ -240,7 +240,7 @@ static const FormatData format_data[] = {
|
||||
[GDK_MEMORY_A8R8G8B8] = { GDK_MEMORY_R8G8B8A8, 8, 4, SAMPLEFORMAT_UINT, EXTRASAMPLE_UNASSALPHA },
|
||||
[GDK_MEMORY_R8G8B8A8] = { GDK_MEMORY_R8G8B8A8, 8, 4, SAMPLEFORMAT_UINT, EXTRASAMPLE_UNASSALPHA },
|
||||
[GDK_MEMORY_A8B8G8R8] = { GDK_MEMORY_R8G8B8A8, 8, 4, SAMPLEFORMAT_UINT, EXTRASAMPLE_UNASSALPHA },
|
||||
[GDK_MEMORY_R8G8B8] = { GDK_MEMORY_R8G8B8, 8, 3, SAMPLEFORMAT_UINT, 0 },
|
||||
[GDK_MEMORY_R8G8B8] = { GDK_MEMORY_R8G8B8, 8, 3, SAMPLEFORMAT_UINT, 0 },
|
||||
[GDK_MEMORY_B8G8R8] = { GDK_MEMORY_R8G8B8, 8, 3, SAMPLEFORMAT_UINT, 0 },
|
||||
[GDK_MEMORY_R16G16B16] = { GDK_MEMORY_R16G16B16, 16, 3, SAMPLEFORMAT_UINT, 0 },
|
||||
[GDK_MEMORY_R16G16B16A16_PREMULTIPLIED] = { GDK_MEMORY_R16G16B16A16_PREMULTIPLIED, 16, 4, SAMPLEFORMAT_UINT, EXTRASAMPLE_ASSOCALPHA },
|
||||
@@ -376,6 +376,13 @@ gdk_load_tiff (GBytes *input_bytes,
|
||||
G_GNUC_UNUSED gint64 before = GDK_PROFILER_CURRENT_TIME;
|
||||
|
||||
tif = tiff_open_read (input_bytes);
|
||||
if (!tif)
|
||||
{
|
||||
g_set_error_literal (error,
|
||||
GDK_TEXTURE_ERROR, GDK_TEXTURE_ERROR_CORRUPT_IMAGE,
|
||||
_("Could not load TIFF data"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
TIFFSetDirectory (tif, 0);
|
||||
|
||||
|
||||
@@ -45,7 +45,6 @@
|
||||
|
||||
options = (NSTrackingMouseEnteredAndExited |
|
||||
NSTrackingMouseMoved |
|
||||
NSTrackingInVisibleRect |
|
||||
NSTrackingActiveAlways);
|
||||
trackingArea = [[NSTrackingArea alloc] initWithRect:rect
|
||||
options:options
|
||||
@@ -57,9 +56,26 @@
|
||||
return self;
|
||||
}
|
||||
|
||||
-(void)setInputArea:(const cairo_rectangle_int_t *)area
|
||||
{
|
||||
NSRect rect = NSMakeRect (area->x, area->y, area->width, area->height);
|
||||
NSTrackingAreaOptions options;
|
||||
|
||||
[self removeTrackingArea:trackingArea];
|
||||
|
||||
options = (NSTrackingMouseEnteredAndExited |
|
||||
NSTrackingMouseMoved |
|
||||
NSTrackingActiveAlways);
|
||||
trackingArea = [[NSTrackingArea alloc] initWithRect:rect
|
||||
options:options
|
||||
owner:(id)self
|
||||
userInfo:nil];
|
||||
[self addTrackingArea:trackingArea];
|
||||
}
|
||||
|
||||
-(void)setOpaqueRegion:(cairo_region_t *)region
|
||||
{
|
||||
/* Do nothing */
|
||||
/* Handled in Subclass */
|
||||
}
|
||||
|
||||
-(BOOL)acceptsFirstMouse
|
||||
|
||||
@@ -42,5 +42,6 @@
|
||||
-(void)setNeedsInvalidateShadow: (BOOL)invalidate;
|
||||
-(NSTrackingArea *)trackingArea;
|
||||
-(void)setOpaqueRegion:(cairo_region_t *)region;
|
||||
-(void)setInputArea:(const cairo_rectangle_int_t *)area;
|
||||
|
||||
@end
|
||||
|
||||
@@ -1,201 +0,0 @@
|
||||
/* GdkMacosCairoSubview.c
|
||||
*
|
||||
* Copyright © 2020 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <CoreGraphics/CoreGraphics.h>
|
||||
#include <cairo-quartz.h>
|
||||
|
||||
|
||||
#import "GdkMacosCairoSubview.h"
|
||||
#import "GdkMacosCairoView.h"
|
||||
|
||||
#include "gdkmacossurface-private.h"
|
||||
|
||||
@implementation GdkMacosCairoSubview
|
||||
|
||||
-(void)dealloc
|
||||
{
|
||||
g_clear_pointer (&self->clip, cairo_region_destroy);
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
-(BOOL)isOpaque
|
||||
{
|
||||
return _isOpaque;
|
||||
}
|
||||
|
||||
-(BOOL)isFlipped
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
-(GdkSurface *)gdkSurface
|
||||
{
|
||||
return GDK_SURFACE ([(GdkMacosBaseView *)[self superview] gdkSurface]);
|
||||
}
|
||||
|
||||
-(void)drawRect:(NSRect)rect
|
||||
{
|
||||
CGContextRef cgContext;
|
||||
GdkSurface *gdk_surface;
|
||||
cairo_surface_t *dest;
|
||||
const NSRect *rects = NULL;
|
||||
NSView *root_view;
|
||||
NSInteger n_rects = 0;
|
||||
NSRect abs_bounds;
|
||||
cairo_t *cr;
|
||||
CGSize scale;
|
||||
int scale_factor;
|
||||
|
||||
if (self->cairoSurface == NULL)
|
||||
return;
|
||||
|
||||
/* Acquire everything we need to do translations, drawing, etc */
|
||||
gdk_surface = [self gdkSurface];
|
||||
scale_factor = gdk_surface_get_scale_factor (gdk_surface);
|
||||
root_view = [[self window] contentView];
|
||||
cgContext = [[NSGraphicsContext currentContext] CGContext];
|
||||
abs_bounds = [self convertRect:[self bounds] toView:root_view];
|
||||
|
||||
CGContextSaveGState (cgContext);
|
||||
|
||||
/* Translate scaling to remove HiDPI scaling from CGContext as
|
||||
* cairo will be doing that for us already.
|
||||
*/
|
||||
scale = CGSizeMake (1.0, 1.0);
|
||||
scale = CGContextConvertSizeToDeviceSpace (cgContext, scale);
|
||||
CGContextScaleCTM (cgContext, 1.0 / scale.width, 1.0 / scale.height);
|
||||
|
||||
/* Create the cairo surface to draw to the CGContext and translate
|
||||
* coordinates so we can pretend we are in the same coordinate system
|
||||
* as the GDK surface.
|
||||
*/
|
||||
dest = cairo_quartz_surface_create_for_cg_context (cgContext,
|
||||
gdk_surface->width * scale_factor,
|
||||
gdk_surface->height * scale_factor);
|
||||
cairo_surface_set_device_scale (dest, scale_factor, scale_factor);
|
||||
|
||||
/* Create cairo context and translate things into the origin of
|
||||
* the topmost contentView so that we just draw at 0,0 with a
|
||||
* clip region to paint the surface.
|
||||
*/
|
||||
cr = cairo_create (dest);
|
||||
cairo_translate (cr, -abs_bounds.origin.x, -abs_bounds.origin.y);
|
||||
|
||||
/* Apply the clip if provided one */
|
||||
if (self->clip != NULL)
|
||||
{
|
||||
cairo_rectangle_int_t area;
|
||||
|
||||
n_rects = cairo_region_num_rectangles (self->clip);
|
||||
for (guint i = 0; i < n_rects; i++)
|
||||
{
|
||||
cairo_region_get_rectangle (self->clip, i, &area);
|
||||
cairo_rectangle (cr, area.x, area.y, area.width, area.height);
|
||||
}
|
||||
|
||||
cairo_clip (cr);
|
||||
}
|
||||
|
||||
/* Clip the cairo context based on the rectangles to be drawn
|
||||
* within the bounding box :rect.
|
||||
*/
|
||||
[self getRectsBeingDrawn:&rects count:&n_rects];
|
||||
for (NSInteger i = 0; i < n_rects; i++)
|
||||
{
|
||||
NSRect area = [self convertRect:rects[i] toView:root_view];
|
||||
cairo_rectangle (cr,
|
||||
area.origin.x, area.origin.y,
|
||||
area.size.width, area.size.height);
|
||||
}
|
||||
cairo_clip (cr);
|
||||
|
||||
/* Now paint the surface (without blending) as we do not need
|
||||
* any compositing here. The transparent regions (like shadows)
|
||||
* are already on non-opaque layers.
|
||||
*/
|
||||
cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
|
||||
cairo_set_source_surface (cr, self->cairoSurface, 0, 0);
|
||||
cairo_paint (cr);
|
||||
|
||||
/* Cleanup state, flush the surface to the backing layer, and
|
||||
* restore GState for future use.
|
||||
*/
|
||||
cairo_destroy (cr);
|
||||
cairo_surface_flush (dest);
|
||||
cairo_surface_destroy (dest);
|
||||
CGContextRestoreGState (cgContext);
|
||||
}
|
||||
|
||||
-(void)setCairoSurface:(cairo_surface_t *)surface
|
||||
withDamage:(cairo_region_t *)region
|
||||
{
|
||||
if (surface != self->cairoSurface)
|
||||
{
|
||||
g_clear_pointer (&self->cairoSurface, cairo_surface_destroy);
|
||||
if (surface != NULL)
|
||||
self->cairoSurface = cairo_surface_reference (surface);
|
||||
}
|
||||
|
||||
if (region != NULL)
|
||||
{
|
||||
NSView *root_view = [[self window] contentView];
|
||||
NSRect abs_bounds = [self convertRect:[self bounds] toView:root_view];
|
||||
guint n_rects = cairo_region_num_rectangles (region);
|
||||
|
||||
for (guint i = 0; i < n_rects; i++)
|
||||
{
|
||||
cairo_rectangle_int_t rect;
|
||||
NSRect nsrect;
|
||||
|
||||
cairo_region_get_rectangle (region, i, &rect);
|
||||
nsrect = NSMakeRect (rect.x, rect.y, rect.width, rect.height);
|
||||
|
||||
if (NSIntersectsRect (abs_bounds, nsrect))
|
||||
{
|
||||
nsrect.origin.x -= abs_bounds.origin.x;
|
||||
nsrect.origin.y -= abs_bounds.origin.y;
|
||||
[self setNeedsDisplayInRect:nsrect];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (id view in [self subviews])
|
||||
[(GdkMacosCairoSubview *)view setCairoSurface:surface
|
||||
withDamage:region];
|
||||
}
|
||||
|
||||
-(void)setOpaque:(BOOL)opaque
|
||||
{
|
||||
self->_isOpaque = opaque;
|
||||
}
|
||||
|
||||
-(void)setClip:(cairo_region_t*)region
|
||||
{
|
||||
if (region != self->clip)
|
||||
{
|
||||
g_clear_pointer (&self->clip, cairo_region_destroy);
|
||||
if (region != NULL)
|
||||
self->clip = cairo_region_reference (region);
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -1,187 +0,0 @@
|
||||
/* GdkMacosCairoView.c
|
||||
*
|
||||
* Copyright © 2020 Red Hat, Inc.
|
||||
* Copyright © 2005-2007 Imendio AB
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <CoreGraphics/CoreGraphics.h>
|
||||
#include <cairo-quartz.h>
|
||||
|
||||
|
||||
#import "GdkMacosCairoView.h"
|
||||
#import "GdkMacosCairoSubview.h"
|
||||
|
||||
#include "gdkmacossurface-private.h"
|
||||
|
||||
@implementation GdkMacosCairoView
|
||||
|
||||
-(void)dealloc
|
||||
{
|
||||
g_clear_pointer (&self->opaque, g_ptr_array_unref);
|
||||
self->transparent = NULL;
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
-(BOOL)isOpaque
|
||||
{
|
||||
if ([self window])
|
||||
return [[self window] isOpaque];
|
||||
return YES;
|
||||
}
|
||||
|
||||
-(BOOL)isFlipped
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
-(void)setNeedsDisplay:(BOOL)needsDisplay
|
||||
{
|
||||
for (id child in [self subviews])
|
||||
[child setNeedsDisplay:needsDisplay];
|
||||
}
|
||||
|
||||
-(void)setCairoSurface:(cairo_surface_t *)cairoSurface
|
||||
withDamage:(cairo_region_t *)cairoRegion
|
||||
{
|
||||
for (id view in [self subviews])
|
||||
[(GdkMacosCairoSubview *)view setCairoSurface:cairoSurface
|
||||
withDamage:cairoRegion];
|
||||
}
|
||||
|
||||
-(void)removeOpaqueChildren
|
||||
{
|
||||
[[self->transparent subviews]
|
||||
makeObjectsPerformSelector:@selector(removeFromSuperview)];
|
||||
|
||||
if (self->opaque->len)
|
||||
g_ptr_array_remove_range (self->opaque, 0, self->opaque->len);
|
||||
}
|
||||
|
||||
-(void)setOpaqueRegion:(cairo_region_t *)region
|
||||
{
|
||||
cairo_region_t *transparent_clip;
|
||||
NSRect abs_bounds;
|
||||
guint n_rects;
|
||||
|
||||
if (region == NULL)
|
||||
return;
|
||||
|
||||
abs_bounds = [self convertRect:[self bounds] toView:nil];
|
||||
n_rects = cairo_region_num_rectangles (region);
|
||||
|
||||
/* First, we create a clip region for the transparent region to use so that
|
||||
* we dont end up exposing too much other than the corners on CSD.
|
||||
*/
|
||||
transparent_clip = cairo_region_create_rectangle (&(cairo_rectangle_int_t) {
|
||||
abs_bounds.origin.x, abs_bounds.origin.y,
|
||||
abs_bounds.size.width, abs_bounds.size.height
|
||||
});
|
||||
cairo_region_subtract (transparent_clip, region);
|
||||
[(GdkMacosCairoSubview *)self->transparent setClip:transparent_clip];
|
||||
cairo_region_destroy (transparent_clip);
|
||||
|
||||
/* The common case (at least for opaque windows and CSD) is that we will
|
||||
* have either one or two opaque rectangles. If we detect that the same
|
||||
* number of them are available as the previous, we can just resize the
|
||||
* previous ones to avoid adding/removing views at a fast rate while
|
||||
* resizing.
|
||||
*/
|
||||
if (n_rects == self->opaque->len)
|
||||
{
|
||||
for (guint i = 0; i < n_rects; i++)
|
||||
{
|
||||
GdkMacosCairoSubview *child;
|
||||
cairo_rectangle_int_t rect;
|
||||
|
||||
child = g_ptr_array_index (self->opaque, i);
|
||||
cairo_region_get_rectangle (region, i, &rect);
|
||||
|
||||
[child setFrame:NSMakeRect (rect.x - abs_bounds.origin.x,
|
||||
rect.y - abs_bounds.origin.y,
|
||||
rect.width,
|
||||
rect.height)];
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
[self removeOpaqueChildren];
|
||||
for (guint i = 0; i < n_rects; i++)
|
||||
{
|
||||
GdkMacosCairoSubview *child;
|
||||
cairo_rectangle_int_t rect;
|
||||
NSRect nsrect;
|
||||
|
||||
cairo_region_get_rectangle (region, i, &rect);
|
||||
nsrect = NSMakeRect (rect.x - abs_bounds.origin.x,
|
||||
rect.y - abs_bounds.origin.y,
|
||||
rect.width,
|
||||
rect.height);
|
||||
|
||||
child = [[GdkMacosCairoSubview alloc] initWithFrame:nsrect];
|
||||
[child setOpaque:YES];
|
||||
[child setWantsLayer:YES];
|
||||
[self->transparent addSubview:child];
|
||||
g_ptr_array_add (self->opaque, child);
|
||||
}
|
||||
}
|
||||
|
||||
-(NSView *)initWithFrame:(NSRect)frame
|
||||
{
|
||||
if ((self = [super initWithFrame:frame]))
|
||||
{
|
||||
/* An array to track all the opaque children placed into
|
||||
* the child self->transparent. This allows us to reuse them
|
||||
* when we receive a new opaque area instead of discarding
|
||||
* them on each draw.
|
||||
*/
|
||||
self->opaque = g_ptr_array_new ();
|
||||
|
||||
/* Setup our primary subview which will render all content that is not
|
||||
* within an opaque region (such as shadows for CSD windows). For opaque
|
||||
* windows, this will all be obscurred by other views, so it doesn't
|
||||
* matter much to have it here.
|
||||
*/
|
||||
self->transparent = [[GdkMacosCairoSubview alloc] initWithFrame:frame];
|
||||
[self addSubview:self->transparent];
|
||||
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
-(void)setFrame:(NSRect)rect
|
||||
{
|
||||
[super setFrame:rect];
|
||||
[self->transparent setFrame:NSMakeRect (0, 0, rect.size.width, rect.size.height)];
|
||||
}
|
||||
|
||||
-(BOOL)acceptsFirstMouse
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
-(BOOL)mouseDownCanMoveWindow
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -1,125 +0,0 @@
|
||||
/* GdkMacosGLView.c
|
||||
*
|
||||
* Copyright 2020 Christian Hergert <chergert@redhat.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <CoreGraphics/CoreGraphics.h>
|
||||
#include <OpenGL/gl.h>
|
||||
|
||||
#include "gdkmacossurface-private.h"
|
||||
|
||||
#import "GdkMacosGLView.h"
|
||||
|
||||
@implementation GdkMacosGLView
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
|
||||
-(void)lockFocus
|
||||
{
|
||||
NSOpenGLContext *context;
|
||||
|
||||
[super lockFocus];
|
||||
|
||||
context = [self openGLContext];
|
||||
|
||||
if ([context view] != self)
|
||||
[context setView: self];
|
||||
}
|
||||
|
||||
-(void)drawRect:(NSRect)rect
|
||||
{
|
||||
}
|
||||
|
||||
-(void)clearGLContext
|
||||
{
|
||||
if (_openGLContext != nil)
|
||||
[_openGLContext clearDrawable];
|
||||
|
||||
_openGLContext = nil;
|
||||
}
|
||||
|
||||
-(void)setOpenGLContext:(NSOpenGLContext*)context
|
||||
{
|
||||
if (_openGLContext != context)
|
||||
{
|
||||
if (_openGLContext != nil)
|
||||
[_openGLContext clearDrawable];
|
||||
|
||||
_openGLContext = context;
|
||||
|
||||
if (_openGLContext != nil)
|
||||
{
|
||||
[_openGLContext setView:self];
|
||||
[self setWantsLayer:YES];
|
||||
[self.layer setContentsGravity:kCAGravityBottomLeft];
|
||||
[_openGLContext update];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
-(NSOpenGLContext *)openGLContext
|
||||
{
|
||||
return _openGLContext;
|
||||
}
|
||||
|
||||
-(BOOL)isOpaque
|
||||
{
|
||||
if ([self window])
|
||||
return [[self window] isOpaque];
|
||||
return YES;
|
||||
}
|
||||
|
||||
-(BOOL)isFlipped
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
-(BOOL)acceptsFirstMouse
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
-(BOOL)mouseDownCanMoveWindow
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
-(void)invalidateRegion:(const cairo_region_t *)region
|
||||
{
|
||||
if (region != NULL)
|
||||
{
|
||||
guint n_rects = cairo_region_num_rectangles (region);
|
||||
|
||||
for (guint i = 0; i < n_rects; i++)
|
||||
{
|
||||
cairo_rectangle_int_t rect;
|
||||
NSRect nsrect;
|
||||
|
||||
cairo_region_get_rectangle (region, i, &rect);
|
||||
nsrect = NSMakeRect (rect.x, rect.y, rect.width, rect.height);
|
||||
|
||||
[self setNeedsDisplayInRect:nsrect];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
|
||||
@end
|
||||
386
gdk/macos/GdkMacosLayer.c
Normal file
386
gdk/macos/GdkMacosLayer.c
Normal file
@@ -0,0 +1,386 @@
|
||||
/* GdkMacosLayer.c
|
||||
*
|
||||
* Copyright © 2022 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#import "GdkMacosLayer.h"
|
||||
#import "GdkMacosTile.h"
|
||||
|
||||
@protocol CanSetContentsOpaque
|
||||
- (void)setContentsOpaque:(BOOL)mask;
|
||||
@end
|
||||
|
||||
@implementation GdkMacosLayer
|
||||
|
||||
#define TILE_MAX_SIZE 128
|
||||
#define TILE_EDGE_MAX_SIZE 512
|
||||
|
||||
static CGAffineTransform flipTransform;
|
||||
static gboolean hasFlipTransform;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GdkMacosTile *tile;
|
||||
cairo_rectangle_int_t cr_area;
|
||||
CGRect area;
|
||||
guint opaque : 1;
|
||||
} TileInfo;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const cairo_region_t *region;
|
||||
guint n_rects;
|
||||
guint iter;
|
||||
cairo_rectangle_int_t rect;
|
||||
cairo_rectangle_int_t stash;
|
||||
guint finished : 1;
|
||||
} Tiler;
|
||||
|
||||
static void
|
||||
tiler_init (Tiler *tiler,
|
||||
const cairo_region_t *region)
|
||||
{
|
||||
memset (tiler, 0, sizeof *tiler);
|
||||
|
||||
if (region == NULL)
|
||||
{
|
||||
tiler->finished = TRUE;
|
||||
return;
|
||||
}
|
||||
|
||||
tiler->region = region;
|
||||
tiler->n_rects = cairo_region_num_rectangles (region);
|
||||
|
||||
if (tiler->n_rects > 0)
|
||||
cairo_region_get_rectangle (region, 0, &tiler->rect);
|
||||
else
|
||||
tiler->finished = TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
tiler_next (Tiler *tiler,
|
||||
cairo_rectangle_int_t *tile,
|
||||
int max_size)
|
||||
{
|
||||
if (tiler->finished)
|
||||
return FALSE;
|
||||
|
||||
if (tiler->rect.width == 0 || tiler->rect.height == 0)
|
||||
{
|
||||
tiler->iter++;
|
||||
|
||||
if (tiler->iter >= tiler->n_rects)
|
||||
{
|
||||
tiler->finished = TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
cairo_region_get_rectangle (tiler->region, tiler->iter, &tiler->rect);
|
||||
}
|
||||
|
||||
/* If the next rectangle is too tall, slice the bottom off to
|
||||
* leave just the height we want into tiler->stash.
|
||||
*/
|
||||
if (tiler->rect.height > max_size)
|
||||
{
|
||||
tiler->stash = tiler->rect;
|
||||
tiler->stash.y += max_size;
|
||||
tiler->stash.height -= max_size;
|
||||
tiler->rect.height = max_size;
|
||||
}
|
||||
|
||||
/* Now we can take the next horizontal slice */
|
||||
tile->x = tiler->rect.x;
|
||||
tile->y = tiler->rect.y;
|
||||
tile->height = tiler->rect.height;
|
||||
tile->width = MIN (max_size, tiler->rect.width);
|
||||
|
||||
tiler->rect.x += tile->width;
|
||||
tiler->rect.width -= tile->width;
|
||||
|
||||
if (tiler->rect.width == 0)
|
||||
{
|
||||
tiler->rect = tiler->stash;
|
||||
tiler->stash.width = tiler->stash.height = 0;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static inline CGRect
|
||||
toCGRect (const cairo_rectangle_int_t *rect)
|
||||
{
|
||||
return CGRectMake (rect->x, rect->y, rect->width, rect->height);
|
||||
}
|
||||
|
||||
static inline cairo_rectangle_int_t
|
||||
fromCGRect (const CGRect rect)
|
||||
{
|
||||
return (cairo_rectangle_int_t) {
|
||||
rect.origin.x,
|
||||
rect.origin.y,
|
||||
rect.size.width,
|
||||
rect.size.height
|
||||
};
|
||||
}
|
||||
|
||||
-(id)init
|
||||
{
|
||||
if (!hasFlipTransform)
|
||||
{
|
||||
hasFlipTransform = TRUE;
|
||||
flipTransform = CGAffineTransformMakeScale (1, -1);
|
||||
}
|
||||
|
||||
self = [super init];
|
||||
|
||||
if (self == NULL)
|
||||
return NULL;
|
||||
|
||||
self->_layoutInvalid = TRUE;
|
||||
|
||||
[self setContentsGravity:kCAGravityCenter];
|
||||
[self setContentsScale:1.0f];
|
||||
[self setGeometryFlipped:YES];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
-(BOOL)isOpaque
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
-(void)_applyLayout:(GArray *)tiles
|
||||
{
|
||||
CGAffineTransform transform;
|
||||
GArray *prev;
|
||||
gboolean exhausted;
|
||||
guint j = 0;
|
||||
|
||||
if (self->_isFlipped)
|
||||
transform = flipTransform;
|
||||
else
|
||||
transform = CGAffineTransformIdentity;
|
||||
|
||||
prev = g_steal_pointer (&self->_tiles);
|
||||
self->_tiles = tiles;
|
||||
exhausted = prev == NULL;
|
||||
|
||||
/* Try to use existing CALayer to avoid creating new layers
|
||||
* as that can be rather expensive.
|
||||
*/
|
||||
for (guint i = 0; i < tiles->len; i++)
|
||||
{
|
||||
TileInfo *info = &g_array_index (tiles, TileInfo, i);
|
||||
|
||||
if (!exhausted)
|
||||
{
|
||||
TileInfo *other = NULL;
|
||||
|
||||
for (; j < prev->len; j++)
|
||||
{
|
||||
other = &g_array_index (prev, TileInfo, j);
|
||||
|
||||
if (other->opaque == info->opaque)
|
||||
{
|
||||
j++;
|
||||
break;
|
||||
}
|
||||
|
||||
other = NULL;
|
||||
}
|
||||
|
||||
if (other != NULL)
|
||||
{
|
||||
info->tile = g_steal_pointer (&other->tile);
|
||||
[info->tile setFrame:info->area];
|
||||
[info->tile setAffineTransform:transform];
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
info->tile = [GdkMacosTile layer];
|
||||
|
||||
[info->tile setAffineTransform:transform];
|
||||
[info->tile setContentsScale:1.0f];
|
||||
[info->tile setOpaque:info->opaque];
|
||||
[(id<CanSetContentsOpaque>)info->tile setContentsOpaque:info->opaque];
|
||||
[info->tile setFrame:info->area];
|
||||
|
||||
[self addSublayer:info->tile];
|
||||
}
|
||||
|
||||
/* Release all of our old layers */
|
||||
if (prev != NULL)
|
||||
{
|
||||
for (guint i = 0; i < prev->len; i++)
|
||||
{
|
||||
TileInfo *info = &g_array_index (prev, TileInfo, i);
|
||||
|
||||
if (info->tile != NULL)
|
||||
[info->tile removeFromSuperlayer];
|
||||
}
|
||||
|
||||
g_array_unref (prev);
|
||||
}
|
||||
}
|
||||
|
||||
-(void)layoutSublayers
|
||||
{
|
||||
Tiler tiler;
|
||||
GArray *ar;
|
||||
cairo_region_t *transparent;
|
||||
cairo_rectangle_int_t rect;
|
||||
int max_size;
|
||||
|
||||
if (!self->_inSwapBuffer)
|
||||
return;
|
||||
|
||||
self->_layoutInvalid = FALSE;
|
||||
|
||||
ar = g_array_sized_new (FALSE, FALSE, sizeof (TileInfo), 32);
|
||||
|
||||
rect = fromCGRect ([self bounds]);
|
||||
rect.x = rect.y = 0;
|
||||
|
||||
/* Calculate the transparent region (edges usually) */
|
||||
transparent = cairo_region_create_rectangle (&rect);
|
||||
if (self->_opaqueRegion)
|
||||
cairo_region_subtract (transparent, self->_opaqueRegion);
|
||||
|
||||
self->_opaque = cairo_region_is_empty (transparent);
|
||||
|
||||
/* If we have transparent borders around the opaque region, then
|
||||
* we are okay with a bit larger tiles since they don't change
|
||||
* all that much and are generally small in width.
|
||||
*/
|
||||
if (!self->_opaque &&
|
||||
self->_opaqueRegion &&
|
||||
!cairo_region_is_empty (self->_opaqueRegion))
|
||||
max_size = TILE_EDGE_MAX_SIZE;
|
||||
else
|
||||
max_size = TILE_MAX_SIZE;
|
||||
|
||||
/* Track transparent children */
|
||||
tiler_init (&tiler, transparent);
|
||||
while (tiler_next (&tiler, &rect, max_size))
|
||||
{
|
||||
TileInfo *info;
|
||||
|
||||
g_array_set_size (ar, ar->len+1);
|
||||
|
||||
info = &g_array_index (ar, TileInfo, ar->len-1);
|
||||
info->tile = NULL;
|
||||
info->opaque = FALSE;
|
||||
info->cr_area = rect;
|
||||
info->area = toCGRect (&info->cr_area);
|
||||
}
|
||||
|
||||
/* Track opaque children */
|
||||
tiler_init (&tiler, self->_opaqueRegion);
|
||||
while (tiler_next (&tiler, &rect, TILE_MAX_SIZE))
|
||||
{
|
||||
TileInfo *info;
|
||||
|
||||
g_array_set_size (ar, ar->len+1);
|
||||
|
||||
info = &g_array_index (ar, TileInfo, ar->len-1);
|
||||
info->tile = NULL;
|
||||
info->opaque = TRUE;
|
||||
info->cr_area = rect;
|
||||
info->area = toCGRect (&info->cr_area);
|
||||
}
|
||||
|
||||
cairo_region_destroy (transparent);
|
||||
|
||||
[self _applyLayout:g_steal_pointer (&ar)];
|
||||
[super layoutSublayers];
|
||||
}
|
||||
|
||||
-(void)setFrame:(NSRect)frame
|
||||
{
|
||||
if (frame.size.width != self.bounds.size.width ||
|
||||
frame.size.height != self.bounds.size.height)
|
||||
{
|
||||
self->_layoutInvalid = TRUE;
|
||||
[self setNeedsLayout];
|
||||
}
|
||||
|
||||
[super setFrame:frame];
|
||||
}
|
||||
|
||||
-(void)setOpaqueRegion:(const cairo_region_t *)opaqueRegion
|
||||
{
|
||||
g_clear_pointer (&self->_opaqueRegion, cairo_region_destroy);
|
||||
self->_opaqueRegion = cairo_region_copy (opaqueRegion);
|
||||
self->_layoutInvalid = TRUE;
|
||||
|
||||
[self setNeedsLayout];
|
||||
}
|
||||
|
||||
-(void)swapBuffer:(GdkMacosBuffer *)buffer withDamage:(const cairo_region_t *)damage
|
||||
{
|
||||
IOSurfaceRef ioSurface = _gdk_macos_buffer_get_native (buffer);
|
||||
gboolean flipped = _gdk_macos_buffer_get_flipped (buffer);
|
||||
double scale = _gdk_macos_buffer_get_device_scale (buffer);
|
||||
double width = _gdk_macos_buffer_get_width (buffer) / scale;
|
||||
double height = _gdk_macos_buffer_get_height (buffer) / scale;
|
||||
|
||||
if (flipped != self->_isFlipped)
|
||||
{
|
||||
self->_isFlipped = flipped;
|
||||
self->_layoutInvalid = TRUE;
|
||||
}
|
||||
|
||||
if (self->_layoutInvalid)
|
||||
{
|
||||
self->_inSwapBuffer = TRUE;
|
||||
[self layoutSublayers];
|
||||
self->_inSwapBuffer = FALSE;
|
||||
}
|
||||
|
||||
if (self->_tiles == NULL)
|
||||
return;
|
||||
|
||||
for (guint i = 0; i < self->_tiles->len; i++)
|
||||
{
|
||||
const TileInfo *info = &g_array_index (self->_tiles, TileInfo, i);
|
||||
cairo_region_overlap_t overlap;
|
||||
CGRect area;
|
||||
|
||||
overlap = cairo_region_contains_rectangle (damage, &info->cr_area);
|
||||
if (overlap == CAIRO_REGION_OVERLAP_OUT)
|
||||
continue;
|
||||
|
||||
area.origin.x = info->area.origin.x / width;
|
||||
area.size.width = info->area.size.width / width;
|
||||
area.size.height = info->area.size.height / height;
|
||||
|
||||
if (flipped)
|
||||
area.origin.y = (height - info->area.origin.y - info->area.size.height) / height;
|
||||
else
|
||||
area.origin.y = info->area.origin.y / height;
|
||||
|
||||
[info->tile swapBuffer:ioSurface withRect:area];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
44
gdk/macos/GdkMacosLayer.h
Normal file
44
gdk/macos/GdkMacosLayer.h
Normal file
@@ -0,0 +1,44 @@
|
||||
/* GdkMacosLayer.h
|
||||
*
|
||||
* Copyright © 2022 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#include <QuartzCore/QuartzCore.h>
|
||||
#include <IOSurface/IOSurface.h>
|
||||
|
||||
#include <cairo.h>
|
||||
#include <glib.h>
|
||||
|
||||
#include "gdkmacosbuffer-private.h"
|
||||
|
||||
#define GDK_IS_MACOS_LAYER(obj) ((obj) && [obj isKindOfClass:[GdkMacosLayer class]])
|
||||
|
||||
@interface GdkMacosLayer : CALayer
|
||||
{
|
||||
cairo_region_t *_opaqueRegion;
|
||||
GArray *_tiles;
|
||||
guint _opaque : 1;
|
||||
guint _layoutInvalid : 1;
|
||||
guint _inSwapBuffer : 1;
|
||||
guint _isFlipped : 1;
|
||||
};
|
||||
|
||||
-(void)setOpaqueRegion:(const cairo_region_t *)opaqueRegion;
|
||||
-(void)swapBuffer:(GdkMacosBuffer *)buffer withDamage:(const cairo_region_t *)damage;
|
||||
|
||||
@end
|
||||
@@ -1,7 +1,6 @@
|
||||
/* GdkMacosGLView.h
|
||||
/* GdkMacosTile.c
|
||||
*
|
||||
* Copyright © 2020 Red Hat, Inc.
|
||||
* Copyright © 2005-2007 Imendio AB
|
||||
* Copyright © 2022 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -19,23 +18,34 @@
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#include <cairo.h>
|
||||
#include "config.h"
|
||||
|
||||
#import "GdkMacosBaseView.h"
|
||||
#include <AppKit/AppKit.h>
|
||||
|
||||
#define GDK_IS_MACOS_GL_VIEW(obj) ((obj) && [obj isKindOfClass:[GdkMacosGLView class]])
|
||||
#import "GdkMacosTile.h"
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
@implementation GdkMacosTile
|
||||
|
||||
@interface GdkMacosGLView : GdkMacosBaseView
|
||||
-(id)init
|
||||
{
|
||||
NSOpenGLContext *_openGLContext;
|
||||
self = [super init];
|
||||
|
||||
[self setContentsScale:1.0];
|
||||
[self setEdgeAntialiasingMask:0];
|
||||
[self setDrawsAsynchronously:YES];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
-(void)setOpenGLContext:(NSOpenGLContext*)context;
|
||||
-(NSOpenGLContext *)openGLContext;
|
||||
-(void)invalidateRegion:(const cairo_region_t *)region;
|
||||
-(void)swapBuffer:(IOSurfaceRef)buffer withRect:(CGRect)rect
|
||||
{
|
||||
if G_LIKELY ([self contents] == (id)buffer)
|
||||
[(id<CanSetContentsChanged>)self setContentsChanged];
|
||||
else
|
||||
[self setContents:(id)buffer];
|
||||
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
if G_UNLIKELY (!CGRectEqualToRect ([self contentsRect], rect))
|
||||
self.contentsRect = rect;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -1,6 +1,6 @@
|
||||
/* GdkMacosCairoSubview.h
|
||||
/* GdkMacosTile.h
|
||||
*
|
||||
* Copyright © 2020 Red Hat, Inc.
|
||||
* Copyright © 2022 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -18,20 +18,20 @@
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#include <AppKit/AppKit.h>
|
||||
#include <QuartzCore/QuartzCore.h>
|
||||
|
||||
#define GDK_IS_MACOS_CAIRO_SUBVIEW(obj) ((obj) && [obj isKindOfClass:[GdkMacosCairoSubview class]])
|
||||
#include "gdkmacosbuffer-private.h"
|
||||
|
||||
@interface GdkMacosCairoSubview : NSView
|
||||
#define GDK_IS_MACOS_TILE(obj) ((obj) && [obj isKindOfClass:[GdkMacosTile class]])
|
||||
|
||||
@protocol CanSetContentsChanged
|
||||
-(void)setContentsChanged;
|
||||
@end
|
||||
|
||||
@interface GdkMacosTile : CALayer
|
||||
{
|
||||
BOOL _isOpaque;
|
||||
cairo_surface_t *cairoSurface;
|
||||
cairo_region_t *clip;
|
||||
}
|
||||
};
|
||||
|
||||
-(void)setOpaque:(BOOL)opaque;
|
||||
-(void)setCairoSurface:(cairo_surface_t *)cairoSurface
|
||||
withDamage:(cairo_region_t *)region;
|
||||
-(void)setClip:(cairo_region_t*)region;
|
||||
-(void)swapBuffer:(IOSurfaceRef)buffer withRect:(CGRect)rect;
|
||||
|
||||
@end
|
||||
100
gdk/macos/GdkMacosView.c
Normal file
100
gdk/macos/GdkMacosView.c
Normal file
@@ -0,0 +1,100 @@
|
||||
/* GdkMacosView.c
|
||||
*
|
||||
* Copyright 2022 Christian Hergert <chergert@redhat.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <CoreGraphics/CoreGraphics.h>
|
||||
|
||||
#import "GdkMacosLayer.h"
|
||||
#import "GdkMacosView.h"
|
||||
#import "GdkMacosWindow.h"
|
||||
|
||||
@implementation GdkMacosView
|
||||
|
||||
-(id)initWithFrame:(NSRect)frame
|
||||
{
|
||||
if ((self = [super initWithFrame:frame]))
|
||||
{
|
||||
GdkMacosLayer *layer = [GdkMacosLayer layer];
|
||||
|
||||
[self setLayerContentsRedrawPolicy:NSViewLayerContentsRedrawNever];
|
||||
[self setLayer:layer];
|
||||
[self setWantsLayer:YES];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
-(BOOL)isFlipped
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
-(BOOL)acceptsFirstMouse
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
-(BOOL)mouseDownCanMoveWindow
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
-(void)mouseDown:(NSEvent *)nsevent
|
||||
{
|
||||
if ([(GdkMacosWindow *)[self window] needsMouseDownQuirk])
|
||||
/* We should only hit this when we are trying to click through
|
||||
* the shadow of a window into another window. Just request
|
||||
* that the application not activate this window on mouseUp.
|
||||
* See gdkmacosdisplay-translate.c for the other half of this.
|
||||
*/
|
||||
[NSApp preventWindowOrdering];
|
||||
else
|
||||
[super mouseDown:nsevent];
|
||||
}
|
||||
|
||||
-(void)setFrame:(NSRect)rect
|
||||
{
|
||||
[super setFrame:rect];
|
||||
self->_nextFrameDirty = TRUE;
|
||||
}
|
||||
|
||||
-(void)setOpaqueRegion:(const cairo_region_t *)opaqueRegion
|
||||
{
|
||||
[(GdkMacosLayer *)[self layer] setOpaqueRegion:opaqueRegion];
|
||||
}
|
||||
|
||||
-(BOOL)wantsUpdateLayer
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
-(void)swapBuffer:(GdkMacosBuffer *)buffer withDamage:(const cairo_region_t *)damage
|
||||
{
|
||||
if (self->_nextFrameDirty)
|
||||
{
|
||||
self->_nextFrameDirty = FALSE;
|
||||
[[self layer] setFrame:[self frame]];
|
||||
}
|
||||
|
||||
[(GdkMacosLayer *)[self layer] swapBuffer:buffer withDamage:damage];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -1,7 +1,6 @@
|
||||
/* GdkMacosCairoView.h
|
||||
/* GdkMacosView.h
|
||||
*
|
||||
* Copyright © 2020 Red Hat, Inc.
|
||||
* Copyright © 2005-2007 Imendio AB
|
||||
* Copyright 2022 Christian Hergert <chergert@redhat.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -23,15 +22,17 @@
|
||||
|
||||
#import "GdkMacosBaseView.h"
|
||||
|
||||
#define GDK_IS_MACOS_CAIRO_VIEW(obj) ((obj) && [obj isKindOfClass:[GdkMacosCairoView class]])
|
||||
#include "gdkmacosbuffer-private.h"
|
||||
|
||||
@interface GdkMacosCairoView : GdkMacosBaseView
|
||||
#define GDK_IS_MACOS_VIEW(obj) ((obj) && [obj isKindOfClass:[GdkMacosView class]])
|
||||
|
||||
@interface GdkMacosView : GdkMacosBaseView
|
||||
{
|
||||
NSView *transparent;
|
||||
GPtrArray *opaque;
|
||||
NSRect _nextFrame;
|
||||
guint _nextFrameDirty : 1;
|
||||
}
|
||||
|
||||
-(void)setCairoSurface:(cairo_surface_t *)cairoSurface
|
||||
withDamage:(cairo_region_t *)region;
|
||||
-(void)setOpaqueRegion:(const cairo_region_t *)opaqueRegion;
|
||||
-(void)swapBuffer:(GdkMacosBuffer *)buffer withDamage:(const cairo_region_t *)damage;
|
||||
|
||||
@end
|
||||
@@ -24,8 +24,7 @@
|
||||
#include <gdk/gdk.h>
|
||||
|
||||
#import "GdkMacosBaseView.h"
|
||||
#import "GdkMacosCairoView.h"
|
||||
#import "GdkMacosGLView.h"
|
||||
#import "GdkMacosView.h"
|
||||
#import "GdkMacosWindow.h"
|
||||
|
||||
#include "gdkmacosclipboard-private.h"
|
||||
@@ -150,8 +149,7 @@ typedef NSString *CALayerContentsGravity;
|
||||
_gdk_macos_display_break_all_grabs (GDK_MACOS_DISPLAY (display), time);
|
||||
|
||||
/* Reset gravity */
|
||||
if (GDK_IS_MACOS_GL_VIEW ([self contentView]))
|
||||
[[[self contentView] layer] setContentsGravity:kCAGravityBottomLeft];
|
||||
[[[self contentView] layer] setContentsGravity:kCAGravityBottomLeft];
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -173,6 +171,11 @@ typedef NSString *CALayerContentsGravity;
|
||||
return inMove;
|
||||
}
|
||||
|
||||
- (BOOL)inFullscreenTransition;
|
||||
{
|
||||
return inFullscreenTransition;
|
||||
}
|
||||
|
||||
-(void)checkSendEnterNotify
|
||||
{
|
||||
/* When a new window has been created, and the mouse is in the window
|
||||
@@ -203,69 +206,20 @@ typedef NSString *CALayerContentsGravity;
|
||||
}
|
||||
}
|
||||
|
||||
-(void)windowDidUnmaximize
|
||||
{
|
||||
NSWindowStyleMask style_mask = [self styleMask];
|
||||
|
||||
gdk_synthesize_surface_state (GDK_SURFACE (gdk_surface), GDK_TOPLEVEL_STATE_MAXIMIZED, 0);
|
||||
|
||||
/* If we are using CSD, then we transitioned to an opaque
|
||||
* window while we were maximized. Now we need to drop that
|
||||
* as we are leaving maximized state.
|
||||
*/
|
||||
if ((style_mask & NSWindowStyleMaskTitled) == 0 && [self isOpaque])
|
||||
[self setOpaque:NO];
|
||||
}
|
||||
|
||||
-(void)windowDidMove:(NSNotification *)aNotification
|
||||
-(void)setFrame:(NSRect)frame display:(BOOL)display
|
||||
{
|
||||
NSRect contentRect = [self contentRectForFrameRect:frame];
|
||||
GdkSurface *surface = GDK_SURFACE (gdk_surface);
|
||||
gboolean maximized = (surface->state & GDK_TOPLEVEL_STATE_MAXIMIZED) != 0;
|
||||
|
||||
/* In case the window is changed when maximized remove the maximized state */
|
||||
if (maximized && !inMaximizeTransition && !NSEqualRects (lastMaximizedFrame, [self frame]))
|
||||
[self windowDidUnmaximize];
|
||||
if (maximized && !inMaximizeTransition && !NSEqualRects (lastMaximizedFrame, frame))
|
||||
{
|
||||
gdk_synthesize_surface_state (surface, GDK_TOPLEVEL_STATE_MAXIMIZED, 0);
|
||||
_gdk_surface_update_size (surface);
|
||||
}
|
||||
|
||||
_gdk_macos_surface_update_position (gdk_surface);
|
||||
_gdk_macos_surface_reposition_children (gdk_surface);
|
||||
|
||||
[self checkSendEnterNotify];
|
||||
}
|
||||
|
||||
-(void)windowDidResize:(NSNotification *)aNotification
|
||||
{
|
||||
NSRect content_rect;
|
||||
GdkSurface *surface;
|
||||
GdkDisplay *display;
|
||||
gboolean maximized;
|
||||
|
||||
surface = GDK_SURFACE (gdk_surface);
|
||||
display = gdk_surface_get_display (surface);
|
||||
|
||||
content_rect = [self contentRectForFrameRect:[self frame]];
|
||||
maximized = (surface->state & GDK_TOPLEVEL_STATE_MAXIMIZED) != 0;
|
||||
|
||||
/* see same in windowDidMove */
|
||||
if (maximized && !inMaximizeTransition && !NSEqualRects (lastMaximizedFrame, [self frame]))
|
||||
[self windowDidUnmaximize];
|
||||
|
||||
surface->width = content_rect.size.width;
|
||||
surface->height = content_rect.size.height;
|
||||
|
||||
/* Certain resize operations (e.g. going fullscreen), also move the
|
||||
* origin of the window.
|
||||
*/
|
||||
_gdk_macos_surface_update_position (GDK_MACOS_SURFACE (surface));
|
||||
|
||||
[[self contentView] setFrame:NSMakeRect (0, 0, surface->width, surface->height)];
|
||||
|
||||
_gdk_surface_update_size (surface);
|
||||
|
||||
gdk_surface_request_layout (surface);
|
||||
|
||||
_gdk_macos_surface_reposition_children (gdk_surface);
|
||||
|
||||
[self checkSendEnterNotify];
|
||||
[super setFrame:frame display:display];
|
||||
[[self contentView] setFrame:NSMakeRect (0, 0, contentRect.size.width, contentRect.size.height)];
|
||||
}
|
||||
|
||||
-(id)initWithContentRect:(NSRect)contentRect
|
||||
@@ -274,7 +228,7 @@ typedef NSString *CALayerContentsGravity;
|
||||
defer:(BOOL)flag
|
||||
screen:(NSScreen *)screen
|
||||
{
|
||||
GdkMacosCairoView *view;
|
||||
GdkMacosView *view;
|
||||
|
||||
self = [super initWithContentRect:contentRect
|
||||
styleMask:styleMask
|
||||
@@ -285,8 +239,9 @@ typedef NSString *CALayerContentsGravity;
|
||||
[self setAcceptsMouseMovedEvents:YES];
|
||||
[self setDelegate:(id<NSWindowDelegate>)self];
|
||||
[self setReleasedWhenClosed:YES];
|
||||
[self setPreservesContentDuringLiveResize:NO];
|
||||
|
||||
view = [[GdkMacosCairoView alloc] initWithFrame:contentRect];
|
||||
view = [[GdkMacosView alloc] initWithFrame:contentRect];
|
||||
[self setContentView:view];
|
||||
[view release];
|
||||
|
||||
@@ -303,7 +258,8 @@ typedef NSString *CALayerContentsGravity;
|
||||
|
||||
-(BOOL)canBecomeKeyWindow
|
||||
{
|
||||
return GDK_IS_TOPLEVEL (gdk_surface);
|
||||
return GDK_IS_TOPLEVEL (gdk_surface) ||
|
||||
(GDK_IS_POPUP (gdk_surface) && GDK_SURFACE (gdk_surface)->input_region != NULL);
|
||||
}
|
||||
|
||||
-(void)showAndMakeKey:(BOOL)makeKey
|
||||
@@ -311,9 +267,12 @@ typedef NSString *CALayerContentsGravity;
|
||||
inShowOrHide = YES;
|
||||
|
||||
if (makeKey && [self canBecomeKeyWindow])
|
||||
[self makeKeyAndOrderFront:nil];
|
||||
[self makeKeyAndOrderFront:self];
|
||||
else
|
||||
[self orderFront:nil];
|
||||
[self orderFront:self];
|
||||
|
||||
if (makeKey && [self canBecomeMainWindow])
|
||||
[self makeMainWindow];
|
||||
|
||||
inShowOrHide = NO;
|
||||
|
||||
@@ -411,12 +370,31 @@ typedef NSString *CALayerContentsGravity;
|
||||
windowFrame.origin.x = new_origin.x;
|
||||
windowFrame.origin.y = new_origin.y;
|
||||
|
||||
/* And now apply the frame to the window */
|
||||
[self setFrameOrigin:NSMakePoint(new_origin.x, new_origin.y)];
|
||||
[self setFrame:NSMakeRect (new_origin.x, new_origin.y,
|
||||
window_gdk.width, window_gdk.height)
|
||||
display:YES];
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
-(void)windowDidMove:(NSNotification *)notification
|
||||
{
|
||||
_gdk_macos_surface_configure ([self gdkSurface]);
|
||||
}
|
||||
|
||||
-(void)windowDidResize:(NSNotification *)notification
|
||||
{
|
||||
_gdk_macos_surface_configure (gdk_surface);
|
||||
|
||||
/* If we're using server-side decorations, this notification is coming
|
||||
* in from a display-side change. We need to request a layout in
|
||||
* addition to the configure event.
|
||||
*/
|
||||
if (GDK_IS_MACOS_TOPLEVEL_SURFACE (gdk_surface) &&
|
||||
GDK_MACOS_TOPLEVEL_SURFACE (gdk_surface)->decorated)
|
||||
gdk_surface_request_layout (GDK_SURFACE (gdk_surface));
|
||||
}
|
||||
|
||||
/* Used by gdkmacosdisplay-translate.c to decide if our sendEvent() handler
|
||||
* above will see the event or if it will be subjected to standard processing
|
||||
* by GDK.
|
||||
@@ -428,6 +406,7 @@ typedef NSString *CALayerContentsGravity;
|
||||
|
||||
-(void)beginManualMove
|
||||
{
|
||||
gboolean maximized = GDK_SURFACE (gdk_surface)->state & GDK_TOPLEVEL_STATE_MAXIMIZED;
|
||||
NSPoint initialMoveLocation;
|
||||
GdkPoint point;
|
||||
GdkMonitor *monitor;
|
||||
@@ -446,6 +425,13 @@ typedef NSString *CALayerContentsGravity;
|
||||
|
||||
initialMoveLocation = [NSEvent mouseLocation];
|
||||
|
||||
if (maximized)
|
||||
[self setFrame:NSMakeRect (initialMoveLocation.x - (int)lastUnmaximizedFrame.size.width/2,
|
||||
initialMoveLocation.y,
|
||||
lastUnmaximizedFrame.size.width,
|
||||
lastUnmaximizedFrame.size.height)
|
||||
display:YES];
|
||||
|
||||
_gdk_macos_display_from_display_coords ([self gdkDisplay],
|
||||
initialMoveLocation.x,
|
||||
initialMoveLocation.y,
|
||||
@@ -537,15 +523,7 @@ typedef NSString *CALayerContentsGravity;
|
||||
new_frame.size.height = min_size.height;
|
||||
}
|
||||
|
||||
/* We could also apply aspect ratio:
|
||||
new_frame.size.height = new_frame.size.width / [self aspectRatio].width * [self aspectRatio].height;
|
||||
*/
|
||||
|
||||
[self setFrame:new_frame display:YES];
|
||||
|
||||
/* Let the resizing be handled by GTK. */
|
||||
if (g_main_context_pending (NULL))
|
||||
g_main_context_iteration (NULL, FALSE);
|
||||
_gdk_macos_surface_user_resize ([self gdkSurface], new_frame);
|
||||
|
||||
inTrackManualResize = NO;
|
||||
|
||||
@@ -554,49 +532,46 @@ typedef NSString *CALayerContentsGravity;
|
||||
|
||||
-(void)beginManualResize:(GdkSurfaceEdge)edge
|
||||
{
|
||||
CALayerContentsGravity gravity = kCAGravityBottomLeft;
|
||||
|
||||
if (inMove || inManualMove || inManualResize)
|
||||
return;
|
||||
|
||||
inManualResize = YES;
|
||||
resizeEdge = edge;
|
||||
|
||||
if (GDK_IS_MACOS_GL_VIEW ([self contentView]))
|
||||
switch (edge)
|
||||
{
|
||||
CALayerContentsGravity gravity = kCAGravityBottomLeft;
|
||||
default:
|
||||
case GDK_SURFACE_EDGE_NORTH:
|
||||
gravity = kCAGravityTopLeft;
|
||||
break;
|
||||
|
||||
switch (edge)
|
||||
{
|
||||
default:
|
||||
case GDK_SURFACE_EDGE_NORTH:
|
||||
gravity = kCAGravityTopLeft;
|
||||
break;
|
||||
case GDK_SURFACE_EDGE_NORTH_WEST:
|
||||
gravity = kCAGravityTopRight;
|
||||
break;
|
||||
|
||||
case GDK_SURFACE_EDGE_NORTH_WEST:
|
||||
gravity = kCAGravityTopRight;
|
||||
break;
|
||||
case GDK_SURFACE_EDGE_SOUTH_WEST:
|
||||
case GDK_SURFACE_EDGE_WEST:
|
||||
gravity = kCAGravityBottomRight;
|
||||
break;
|
||||
|
||||
case GDK_SURFACE_EDGE_SOUTH_WEST:
|
||||
case GDK_SURFACE_EDGE_WEST:
|
||||
gravity = kCAGravityBottomRight;
|
||||
break;
|
||||
case GDK_SURFACE_EDGE_SOUTH:
|
||||
case GDK_SURFACE_EDGE_SOUTH_EAST:
|
||||
gravity = kCAGravityBottomLeft;
|
||||
break;
|
||||
|
||||
case GDK_SURFACE_EDGE_SOUTH:
|
||||
case GDK_SURFACE_EDGE_SOUTH_EAST:
|
||||
gravity = kCAGravityBottomLeft;
|
||||
break;
|
||||
case GDK_SURFACE_EDGE_EAST:
|
||||
gravity = kCAGravityBottomLeft;
|
||||
break;
|
||||
|
||||
case GDK_SURFACE_EDGE_EAST:
|
||||
gravity = kCAGravityBottomLeft;
|
||||
break;
|
||||
|
||||
case GDK_SURFACE_EDGE_NORTH_EAST:
|
||||
gravity = kCAGravityTopLeft;
|
||||
break;
|
||||
}
|
||||
|
||||
[[[self contentView] layer] setContentsGravity:gravity];
|
||||
case GDK_SURFACE_EDGE_NORTH_EAST:
|
||||
gravity = kCAGravityTopLeft;
|
||||
break;
|
||||
}
|
||||
|
||||
[[[self contentView] layer] setContentsGravity:gravity];
|
||||
|
||||
initialResizeFrame = [self frame];
|
||||
initialResizeLocation = convert_nspoint_to_screen (self, [self mouseLocationOutsideOfEventStream]);
|
||||
}
|
||||
@@ -710,7 +685,12 @@ typedef NSString *CALayerContentsGravity;
|
||||
is_opaque = (([self styleMask] & NSWindowStyleMaskTitled) != 0);
|
||||
|
||||
if (was_fullscreen != is_fullscreen)
|
||||
_gdk_macos_surface_update_fullscreen_state (gdk_surface);
|
||||
{
|
||||
if (was_fullscreen)
|
||||
[self setFrame:lastUnfullscreenFrame display:NO];
|
||||
|
||||
_gdk_macos_surface_update_fullscreen_state (gdk_surface);
|
||||
}
|
||||
|
||||
if (was_opaque != is_opaque)
|
||||
{
|
||||
@@ -760,7 +740,6 @@ typedef NSString *CALayerContentsGravity;
|
||||
if (state & GDK_TOPLEVEL_STATE_MAXIMIZED)
|
||||
{
|
||||
lastMaximizedFrame = newFrame;
|
||||
[self windowDidUnmaximize];
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -775,16 +754,7 @@ typedef NSString *CALayerContentsGravity;
|
||||
|
||||
-(void)windowDidEndLiveResize:(NSNotification *)aNotification
|
||||
{
|
||||
gboolean maximized = GDK_SURFACE (gdk_surface)->state & GDK_TOPLEVEL_STATE_MAXIMIZED;
|
||||
|
||||
inMaximizeTransition = NO;
|
||||
|
||||
/* Even if this is CSD, we want to be opaque while maximized
|
||||
* to speed up compositing by allowing the display server to
|
||||
* avoid costly blends.
|
||||
*/
|
||||
if (maximized)
|
||||
[self setOpaque:YES];
|
||||
}
|
||||
|
||||
-(NSSize)window:(NSWindow *)window willUseFullScreenContentSize:(NSSize)proposedSize
|
||||
@@ -794,16 +764,37 @@ typedef NSString *CALayerContentsGravity;
|
||||
|
||||
-(void)windowWillEnterFullScreen:(NSNotification *)aNotification
|
||||
{
|
||||
inFullscreenTransition = YES;
|
||||
lastUnfullscreenFrame = [self frame];
|
||||
}
|
||||
|
||||
-(void)windowDidEnterFullScreen:(NSNotification *)aNotification
|
||||
{
|
||||
inFullscreenTransition = NO;
|
||||
initialPositionKnown = NO;
|
||||
[self checkSendEnterNotify];
|
||||
}
|
||||
|
||||
-(void)windowWillExitFullScreen:(NSNotification *)aNotification
|
||||
{
|
||||
[self setFrame:lastUnfullscreenFrame display:YES];
|
||||
inFullscreenTransition = YES;
|
||||
}
|
||||
|
||||
-(void)windowDidExitFullScreen:(NSNotification *)aNotification
|
||||
{
|
||||
inFullscreenTransition = NO;
|
||||
initialPositionKnown = NO;
|
||||
[self checkSendEnterNotify];
|
||||
}
|
||||
|
||||
-(void)windowDidFailToEnterFullScreen:(NSNotification *)aNotification
|
||||
{
|
||||
inFullscreenTransition = NO;
|
||||
}
|
||||
|
||||
-(void)windowDidFailToExitFullScreen:(NSNotification *)aNotification
|
||||
{
|
||||
inFullscreenTransition = NO;
|
||||
}
|
||||
|
||||
-(void)windowDidChangeScreen:(NSNotification *)aNotification
|
||||
@@ -845,4 +836,15 @@ typedef NSString *CALayerContentsGravity;
|
||||
return NO;
|
||||
}
|
||||
|
||||
-(void)swapBuffer:(GdkMacosBuffer *)buffer withDamage:(const cairo_region_t *)damage
|
||||
{
|
||||
[(GdkMacosView *)[self contentView] swapBuffer:buffer withDamage:damage];
|
||||
}
|
||||
|
||||
-(BOOL)needsMouseDownQuirk
|
||||
{
|
||||
return GDK_IS_MACOS_TOPLEVEL_SURFACE (gdk_surface) &&
|
||||
!GDK_MACOS_TOPLEVEL_SURFACE (gdk_surface)->decorated;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -21,9 +21,11 @@
|
||||
|
||||
#import <AppKit/AppKit.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <IOSurface/IOSurface.h>
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
|
||||
#include "gdkmacosbuffer-private.h"
|
||||
#include "gdkmacosdisplay.h"
|
||||
#include "gdkmacossurface.h"
|
||||
#include "edgesnapping.h"
|
||||
@@ -51,6 +53,7 @@
|
||||
NSRect lastMaximizedFrame;
|
||||
NSRect lastUnfullscreenFrame;
|
||||
BOOL inMaximizeTransition;
|
||||
BOOL inFullscreenTransition;
|
||||
}
|
||||
|
||||
-(void)beginManualMove;
|
||||
@@ -66,5 +69,8 @@
|
||||
-(BOOL)trackManualMove;
|
||||
-(BOOL)trackManualResize;
|
||||
-(void)setDecorated:(BOOL)decorated;
|
||||
-(void)swapBuffer:(GdkMacosBuffer *)buffer withDamage:(const cairo_region_t *)damage;
|
||||
-(BOOL)needsMouseDownQuirk;
|
||||
-(BOOL)inFullscreenTransition;
|
||||
|
||||
@end
|
||||
|
||||
@@ -26,7 +26,10 @@
|
||||
|
||||
#include "gdkdisplaylinksource.h"
|
||||
|
||||
#include "gdkdebug.h"
|
||||
#include "gdkmacoseventsource-private.h"
|
||||
#include "gdkmacosmonitor-private.h"
|
||||
#include "gdk-private.h"
|
||||
|
||||
static gint64 host_to_frame_clock_time (gint64 val);
|
||||
|
||||
@@ -64,7 +67,7 @@ gdk_display_link_source_dispatch (GSource *source,
|
||||
|
||||
impl->needs_dispatch = FALSE;
|
||||
|
||||
if (callback != NULL)
|
||||
if (!impl->paused && callback != NULL)
|
||||
ret = callback (user_data);
|
||||
|
||||
return ret;
|
||||
@@ -75,7 +78,9 @@ gdk_display_link_source_finalize (GSource *source)
|
||||
{
|
||||
GdkDisplayLinkSource *impl = (GdkDisplayLinkSource *)source;
|
||||
|
||||
CVDisplayLinkStop (impl->display_link);
|
||||
if (!impl->paused)
|
||||
CVDisplayLinkStop (impl->display_link);
|
||||
|
||||
CVDisplayLinkRelease (impl->display_link);
|
||||
}
|
||||
|
||||
@@ -89,12 +94,18 @@ static GSourceFuncs gdk_display_link_source_funcs = {
|
||||
void
|
||||
gdk_display_link_source_pause (GdkDisplayLinkSource *source)
|
||||
{
|
||||
g_return_if_fail (source->paused == FALSE);
|
||||
|
||||
source->paused = TRUE;
|
||||
CVDisplayLinkStop (source->display_link);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_display_link_source_unpause (GdkDisplayLinkSource *source)
|
||||
{
|
||||
g_return_if_fail (source->paused == TRUE);
|
||||
|
||||
source->paused = FALSE;
|
||||
CVDisplayLinkStart (source->display_link);
|
||||
}
|
||||
|
||||
@@ -146,6 +157,7 @@ gdk_display_link_source_frame_cb (CVDisplayLinkRef display_link,
|
||||
|
||||
/**
|
||||
* gdk_display_link_source_new:
|
||||
* @display_id: the identifier of the monitor
|
||||
*
|
||||
* Creates a new `GSource` that will activate the dispatch function upon
|
||||
* notification from a CVDisplayLink that a new frame should be drawn.
|
||||
@@ -158,41 +170,61 @@ gdk_display_link_source_frame_cb (CVDisplayLinkRef display_link,
|
||||
* Returns: (transfer full): A newly created `GSource`
|
||||
*/
|
||||
GSource *
|
||||
gdk_display_link_source_new (void)
|
||||
gdk_display_link_source_new (CGDirectDisplayID display_id,
|
||||
CGDisplayModeRef mode)
|
||||
{
|
||||
GdkDisplayLinkSource *impl;
|
||||
GSource *source;
|
||||
CVReturn ret;
|
||||
double period;
|
||||
char *name;
|
||||
|
||||
source = g_source_new (&gdk_display_link_source_funcs, sizeof *impl);
|
||||
impl = (GdkDisplayLinkSource *)source;
|
||||
impl->display_id = display_id;
|
||||
impl->paused = TRUE;
|
||||
|
||||
/*
|
||||
* Create our link based on currently connected displays.
|
||||
* If there are multiple displays, this will be something that tries
|
||||
* to work for all of them. In the future, we may want to explore multiple
|
||||
* links based on the connected displays.
|
||||
/* Create DisplayLink for timing information for the display in
|
||||
* question so that we can produce graphics for that display at whatever
|
||||
* rate it can provide.
|
||||
*/
|
||||
ret = CVDisplayLinkCreateWithActiveCGDisplays (&impl->display_link);
|
||||
if (ret != kCVReturnSuccess)
|
||||
if (CVDisplayLinkCreateWithCGDisplay (display_id, &impl->display_link) != kCVReturnSuccess)
|
||||
{
|
||||
g_warning ("Failed to initialize CVDisplayLink!");
|
||||
return source;
|
||||
goto failure;
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine our nominal period between frames.
|
||||
*/
|
||||
period = CVDisplayLinkGetActualOutputVideoRefreshPeriod (impl->display_link);
|
||||
if (period == 0.0)
|
||||
period = 1.0 / 60.0;
|
||||
impl->refresh_interval = period * 1000000L;
|
||||
impl->refresh_rate = 1.0 / period * 1000L;
|
||||
impl->refresh_rate = CGDisplayModeGetRefreshRate (mode) * 1000.0;
|
||||
|
||||
/*
|
||||
* Wire up our callback to be executed within the high-priority thread.
|
||||
*/
|
||||
if (impl->refresh_rate == 0)
|
||||
{
|
||||
const CVTime time = CVDisplayLinkGetNominalOutputVideoRefreshPeriod (impl->display_link);
|
||||
if (!(time.flags & kCVTimeIsIndefinite))
|
||||
impl->refresh_rate = (double)time.timeScale / (double)time.timeValue * 1000.0;
|
||||
}
|
||||
|
||||
if (impl->refresh_rate != 0)
|
||||
{
|
||||
impl->refresh_interval = 1000000.0 / (double)impl->refresh_rate * 1000.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
double period = CVDisplayLinkGetActualOutputVideoRefreshPeriod (impl->display_link);
|
||||
|
||||
if (period == 0.0)
|
||||
period = 1.0 / 60.0;
|
||||
|
||||
impl->refresh_rate = 1.0 / period * 1000L;
|
||||
impl->refresh_interval = period * 1000000L;
|
||||
}
|
||||
|
||||
name = _gdk_macos_monitor_get_connector_name (display_id);
|
||||
GDK_NOTE (MISC,
|
||||
g_message ("Monitor \"%s\" discovered with Refresh Rate %d and Interval %"G_GINT64_FORMAT,
|
||||
name ? name : "unknown",
|
||||
impl->refresh_rate,
|
||||
impl->refresh_interval));
|
||||
g_free (name);
|
||||
|
||||
/* Wire up our callback to be executed within the high-priority thread. */
|
||||
CVDisplayLinkSetOutputCallback (impl->display_link,
|
||||
gdk_display_link_source_frame_cb,
|
||||
source);
|
||||
@@ -200,6 +232,10 @@ gdk_display_link_source_new (void)
|
||||
g_source_set_static_name (source, "[gdk] quartz frame clock");
|
||||
|
||||
return source;
|
||||
|
||||
failure:
|
||||
g_source_unref (source);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static gint64
|
||||
|
||||
@@ -30,17 +30,20 @@ G_BEGIN_DECLS
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GSource source;
|
||||
GSource source;
|
||||
|
||||
CVDisplayLinkRef display_link;
|
||||
gint64 refresh_interval;
|
||||
guint refresh_rate;
|
||||
CGDirectDisplayID display_id;
|
||||
CVDisplayLinkRef display_link;
|
||||
gint64 refresh_interval;
|
||||
guint refresh_rate;
|
||||
guint paused : 1;
|
||||
|
||||
volatile gint64 presentation_time;
|
||||
volatile guint needs_dispatch;
|
||||
volatile gint64 presentation_time;
|
||||
volatile guint needs_dispatch;
|
||||
} GdkDisplayLinkSource;
|
||||
|
||||
GSource *gdk_display_link_source_new (void);
|
||||
GSource *gdk_display_link_source_new (CGDirectDisplayID display_id,
|
||||
CGDisplayModeRef mode);
|
||||
void gdk_display_link_source_pause (GdkDisplayLinkSource *source);
|
||||
void gdk_display_link_source_unpause (GdkDisplayLinkSource *source);
|
||||
|
||||
|
||||
60
gdk/macos/gdkmacosbuffer-private.h
Normal file
60
gdk/macos/gdkmacosbuffer-private.h
Normal file
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright © 2021 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#ifndef __GDK_MACOS_BUFFER_PRIVATE_H__
|
||||
#define __GDK_MACOS_BUFFER_PRIVATE_H__
|
||||
|
||||
#include <CoreGraphics/CoreGraphics.h>
|
||||
#include <Foundation/Foundation.h>
|
||||
#include <IOSurface/IOSurface.h>
|
||||
|
||||
#include <cairo.h>
|
||||
#include <glib-object.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GDK_TYPE_MACOS_BUFFER (gdk_macos_buffer_get_type())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (GdkMacosBuffer, gdk_macos_buffer, GDK, MACOS_BUFFER, GObject)
|
||||
|
||||
GdkMacosBuffer *_gdk_macos_buffer_new (int width,
|
||||
int height,
|
||||
double device_scale,
|
||||
int bytes_per_element,
|
||||
int bits_per_pixel);
|
||||
IOSurfaceRef _gdk_macos_buffer_get_native (GdkMacosBuffer *self);
|
||||
void _gdk_macos_buffer_lock (GdkMacosBuffer *self);
|
||||
void _gdk_macos_buffer_unlock (GdkMacosBuffer *self);
|
||||
void _gdk_macos_buffer_read_lock (GdkMacosBuffer *self);
|
||||
void _gdk_macos_buffer_read_unlock (GdkMacosBuffer *self);
|
||||
guint _gdk_macos_buffer_get_width (GdkMacosBuffer *self);
|
||||
guint _gdk_macos_buffer_get_height (GdkMacosBuffer *self);
|
||||
guint _gdk_macos_buffer_get_stride (GdkMacosBuffer *self);
|
||||
double _gdk_macos_buffer_get_device_scale (GdkMacosBuffer *self);
|
||||
const cairo_region_t *_gdk_macos_buffer_get_damage (GdkMacosBuffer *self);
|
||||
void _gdk_macos_buffer_set_damage (GdkMacosBuffer *self,
|
||||
cairo_region_t *damage);
|
||||
gpointer _gdk_macos_buffer_get_data (GdkMacosBuffer *self);
|
||||
gboolean _gdk_macos_buffer_get_flipped (GdkMacosBuffer *self);
|
||||
void _gdk_macos_buffer_set_flipped (GdkMacosBuffer *self,
|
||||
gboolean flipped);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_MACOS_BUFFER_PRIVATE_H__ */
|
||||
310
gdk/macos/gdkmacosbuffer.c
Normal file
310
gdk/macos/gdkmacosbuffer.c
Normal file
@@ -0,0 +1,310 @@
|
||||
/*
|
||||
* Copyright © 2021 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <IOSurface/IOSurface.h>
|
||||
#include <Foundation/Foundation.h>
|
||||
#include <OpenGL/CGLIOSurface.h>
|
||||
#include <QuartzCore/QuartzCore.h>
|
||||
|
||||
#include "gdkmacosbuffer-private.h"
|
||||
|
||||
struct _GdkMacosBuffer
|
||||
{
|
||||
GObject parent_instance;
|
||||
cairo_region_t *damage;
|
||||
IOSurfaceRef surface;
|
||||
int lock_count;
|
||||
guint bytes_per_element;
|
||||
guint bits_per_pixel;
|
||||
guint width;
|
||||
guint height;
|
||||
guint stride;
|
||||
double device_scale;
|
||||
guint flipped : 1;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (GdkMacosBuffer, gdk_macos_buffer, G_TYPE_OBJECT)
|
||||
|
||||
static void
|
||||
gdk_macos_buffer_dispose (GObject *object)
|
||||
{
|
||||
GdkMacosBuffer *self = (GdkMacosBuffer *)object;
|
||||
|
||||
if (self->lock_count != 0)
|
||||
g_critical ("Attempt to dispose %s while lock is held",
|
||||
G_OBJECT_TYPE_NAME (self));
|
||||
|
||||
/* We could potentially force the unload of our surface here with
|
||||
* IOSurfaceSetPurgeable (self->surface, kIOSurfacePurgeableEmpty, NULL)
|
||||
* but that would cause it to empty when the layers may still be attached
|
||||
* to it. Better to just let it get GC'd by the system after they have
|
||||
* moved on to a new buffer.
|
||||
*/
|
||||
g_clear_pointer (&self->surface, CFRelease);
|
||||
g_clear_pointer (&self->damage, cairo_region_destroy);
|
||||
|
||||
G_OBJECT_CLASS (gdk_macos_buffer_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_buffer_class_init (GdkMacosBufferClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->dispose = gdk_macos_buffer_dispose;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_buffer_init (GdkMacosBuffer *self)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
add_int (CFMutableDictionaryRef dict,
|
||||
const CFStringRef key,
|
||||
int value)
|
||||
{
|
||||
CFNumberRef number = CFNumberCreate (NULL, kCFNumberIntType, &value);
|
||||
CFDictionaryAddValue (dict, key, number);
|
||||
CFRelease (number);
|
||||
}
|
||||
|
||||
static IOSurfaceRef
|
||||
create_surface (int width,
|
||||
int height,
|
||||
int bytes_per_element,
|
||||
guint *stride)
|
||||
{
|
||||
CFMutableDictionaryRef props;
|
||||
IOSurfaceRef ret;
|
||||
size_t bytes_per_row;
|
||||
size_t total_bytes;
|
||||
|
||||
props = CFDictionaryCreateMutable (kCFAllocatorDefault,
|
||||
16,
|
||||
&kCFTypeDictionaryKeyCallBacks,
|
||||
&kCFTypeDictionaryValueCallBacks);
|
||||
if (props == NULL)
|
||||
return NULL;
|
||||
|
||||
bytes_per_row = IOSurfaceAlignProperty (kIOSurfaceBytesPerRow, width * bytes_per_element);
|
||||
total_bytes = IOSurfaceAlignProperty (kIOSurfaceAllocSize, height * bytes_per_row);
|
||||
|
||||
add_int (props, kIOSurfaceAllocSize, total_bytes);
|
||||
add_int (props, kIOSurfaceBytesPerElement, bytes_per_element);
|
||||
add_int (props, kIOSurfaceBytesPerRow, bytes_per_row);
|
||||
add_int (props, kIOSurfaceHeight, height);
|
||||
add_int (props, kIOSurfacePixelFormat, (int)'BGRA');
|
||||
add_int (props, kIOSurfaceWidth, width);
|
||||
|
||||
ret = IOSurfaceCreate (props);
|
||||
|
||||
CFRelease (props);
|
||||
|
||||
*stride = bytes_per_row;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
GdkMacosBuffer *
|
||||
_gdk_macos_buffer_new (int width,
|
||||
int height,
|
||||
double device_scale,
|
||||
int bytes_per_element,
|
||||
int bits_per_pixel)
|
||||
{
|
||||
GdkMacosBuffer *self;
|
||||
|
||||
g_return_val_if_fail (width > 0, NULL);
|
||||
g_return_val_if_fail (height > 0, NULL);
|
||||
|
||||
self = g_object_new (GDK_TYPE_MACOS_BUFFER, NULL);
|
||||
self->bytes_per_element = bytes_per_element;
|
||||
self->bits_per_pixel = bits_per_pixel;
|
||||
self->surface = create_surface (width, height, bytes_per_element, &self->stride);
|
||||
self->width = width;
|
||||
self->height = height;
|
||||
self->device_scale = device_scale;
|
||||
self->lock_count = 0;
|
||||
|
||||
if (self->surface == NULL)
|
||||
g_clear_object (&self);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
IOSurfaceRef
|
||||
_gdk_macos_buffer_get_native (GdkMacosBuffer *self)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_MACOS_BUFFER (self), NULL);
|
||||
|
||||
return self->surface;
|
||||
}
|
||||
|
||||
/**
|
||||
* _gdk_macos_buffer_lock:
|
||||
*
|
||||
* This function matches the IOSurfaceLock() name but what it really
|
||||
* does is page the buffer back for the CPU to access from VRAM.
|
||||
*
|
||||
* Generally we don't want to do that, but we do need to in some
|
||||
* cases such as when we are rendering with Cairo. There might
|
||||
* be an opportunity later to avoid that, but since we are using
|
||||
* GL pretty much everywhere already, we don't try.
|
||||
*/
|
||||
void
|
||||
_gdk_macos_buffer_lock (GdkMacosBuffer *self)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_MACOS_BUFFER (self));
|
||||
g_return_if_fail (self->lock_count == 0);
|
||||
|
||||
self->lock_count++;
|
||||
|
||||
IOSurfaceLock (self->surface, 0, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_macos_buffer_unlock (GdkMacosBuffer *self)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_MACOS_BUFFER (self));
|
||||
g_return_if_fail (self->lock_count == 1);
|
||||
|
||||
self->lock_count--;
|
||||
|
||||
IOSurfaceUnlock (self->surface, 0, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* _gdk_macos_buffer_lock_readonly:
|
||||
*
|
||||
* Like _gdk_macos_buffer_lock() but uses the read-only flag to
|
||||
* indicate we are not interested in retrieving the updates from
|
||||
* the GPU before modifying the CPU-side cache.
|
||||
*
|
||||
* Must be used with _gdk_macos_buffer_unlock_readonly().
|
||||
*/
|
||||
void
|
||||
_gdk_macos_buffer_read_lock (GdkMacosBuffer *self)
|
||||
{
|
||||
kern_return_t ret;
|
||||
|
||||
g_return_if_fail (GDK_IS_MACOS_BUFFER (self));
|
||||
g_return_if_fail (self->lock_count == 0);
|
||||
|
||||
self->lock_count++;
|
||||
|
||||
ret = IOSurfaceLock (self->surface, kIOSurfaceLockReadOnly, NULL);
|
||||
|
||||
g_return_if_fail (ret == KERN_SUCCESS);
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_macos_buffer_read_unlock (GdkMacosBuffer *self)
|
||||
{
|
||||
kern_return_t ret;
|
||||
|
||||
g_return_if_fail (GDK_IS_MACOS_BUFFER (self));
|
||||
g_return_if_fail (self->lock_count == 1);
|
||||
|
||||
self->lock_count--;
|
||||
|
||||
ret = IOSurfaceUnlock (self->surface, kIOSurfaceLockReadOnly, NULL);
|
||||
|
||||
g_return_if_fail (ret == KERN_SUCCESS);
|
||||
}
|
||||
|
||||
guint
|
||||
_gdk_macos_buffer_get_width (GdkMacosBuffer *self)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_MACOS_BUFFER (self), 0);
|
||||
|
||||
return self->width;
|
||||
}
|
||||
|
||||
guint
|
||||
_gdk_macos_buffer_get_height (GdkMacosBuffer *self)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_MACOS_BUFFER (self), 0);
|
||||
|
||||
return self->height;
|
||||
}
|
||||
|
||||
guint
|
||||
_gdk_macos_buffer_get_stride (GdkMacosBuffer *self)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_MACOS_BUFFER (self), 0);
|
||||
|
||||
return self->stride;
|
||||
}
|
||||
|
||||
double
|
||||
_gdk_macos_buffer_get_device_scale (GdkMacosBuffer *self)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_MACOS_BUFFER (self), 1.0);
|
||||
|
||||
return self->device_scale;
|
||||
}
|
||||
|
||||
const cairo_region_t *
|
||||
_gdk_macos_buffer_get_damage (GdkMacosBuffer *self)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_MACOS_BUFFER (self), NULL);
|
||||
|
||||
return self->damage;
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_macos_buffer_set_damage (GdkMacosBuffer *self,
|
||||
cairo_region_t *damage)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_MACOS_BUFFER (self));
|
||||
|
||||
if (damage == self->damage)
|
||||
return;
|
||||
|
||||
g_clear_pointer (&self->damage, cairo_region_destroy);
|
||||
self->damage = cairo_region_copy (damage);
|
||||
}
|
||||
|
||||
gpointer
|
||||
_gdk_macos_buffer_get_data (GdkMacosBuffer *self)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_MACOS_BUFFER (self), NULL);
|
||||
|
||||
return IOSurfaceGetBaseAddress (self->surface);
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gdk_macos_buffer_get_flipped (GdkMacosBuffer *self)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_MACOS_BUFFER (self), FALSE);
|
||||
|
||||
return self->flipped;
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_macos_buffer_set_flipped (GdkMacosBuffer *self,
|
||||
gboolean flipped)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_MACOS_BUFFER (self));
|
||||
|
||||
self->flipped = !!flipped;
|
||||
}
|
||||
@@ -22,18 +22,17 @@
|
||||
|
||||
#include "gdkconfig.h"
|
||||
|
||||
#include <cairo.h>
|
||||
#include <QuartzCore/QuartzCore.h>
|
||||
#include <CoreGraphics/CoreGraphics.h>
|
||||
|
||||
#import "GdkMacosCairoView.h"
|
||||
|
||||
#include "gdkmacosbuffer-private.h"
|
||||
#include "gdkmacoscairocontext-private.h"
|
||||
#include "gdkmacossurface-private.h"
|
||||
|
||||
struct _GdkMacosCairoContext
|
||||
{
|
||||
GdkCairoContext parent_instance;
|
||||
|
||||
cairo_surface_t *window_surface;
|
||||
GdkCairoContext parent_instance;
|
||||
};
|
||||
|
||||
struct _GdkMacosCairoContextClass
|
||||
@@ -43,41 +42,150 @@ struct _GdkMacosCairoContextClass
|
||||
|
||||
G_DEFINE_TYPE (GdkMacosCairoContext, _gdk_macos_cairo_context, GDK_TYPE_CAIRO_CONTEXT)
|
||||
|
||||
static cairo_surface_t *
|
||||
create_cairo_surface_for_surface (GdkSurface *surface)
|
||||
{
|
||||
cairo_surface_t *cairo_surface;
|
||||
int scale;
|
||||
int width;
|
||||
int height;
|
||||
|
||||
g_assert (GDK_IS_MACOS_SURFACE (surface));
|
||||
|
||||
scale = gdk_surface_get_scale_factor (surface);
|
||||
width = scale * gdk_surface_get_width (surface);
|
||||
height = scale * gdk_surface_get_height (surface);
|
||||
|
||||
/* We use a cairo image surface here instead of a quartz surface because we
|
||||
* get strange artifacts with the quartz surface such as empty cross-fades
|
||||
* when hovering buttons. For performance, we want to be using GL rendering
|
||||
* so there isn't much point here as correctness is better.
|
||||
*/
|
||||
cairo_surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
|
||||
|
||||
if (cairo_surface != NULL)
|
||||
cairo_surface_set_device_scale (cairo_surface, scale, scale);
|
||||
|
||||
return cairo_surface;
|
||||
}
|
||||
|
||||
static cairo_t *
|
||||
_gdk_macos_cairo_context_cairo_create (GdkCairoContext *cairo_context)
|
||||
{
|
||||
GdkMacosCairoContext *self = (GdkMacosCairoContext *)cairo_context;
|
||||
const cairo_region_t *damage;
|
||||
cairo_surface_t *image_surface;
|
||||
GdkMacosBuffer *buffer;
|
||||
GdkSurface *surface;
|
||||
NSWindow *nswindow;
|
||||
cairo_t *cr;
|
||||
gpointer data;
|
||||
double scale;
|
||||
guint width;
|
||||
guint height;
|
||||
guint stride;
|
||||
gboolean opaque;
|
||||
|
||||
g_assert (GDK_IS_MACOS_CAIRO_CONTEXT (self));
|
||||
|
||||
return cairo_create (self->window_surface);
|
||||
surface = gdk_draw_context_get_surface (GDK_DRAW_CONTEXT (self));
|
||||
nswindow = _gdk_macos_surface_get_native (GDK_MACOS_SURFACE (surface));
|
||||
opaque = [nswindow isOpaque];
|
||||
|
||||
buffer = _gdk_macos_surface_get_buffer (GDK_MACOS_SURFACE (surface));
|
||||
damage = _gdk_macos_buffer_get_damage (buffer);
|
||||
width = _gdk_macos_buffer_get_width (buffer);
|
||||
height = _gdk_macos_buffer_get_height (buffer);
|
||||
scale = _gdk_macos_buffer_get_device_scale (buffer);
|
||||
stride = _gdk_macos_buffer_get_stride (buffer);
|
||||
data = _gdk_macos_buffer_get_data (buffer);
|
||||
|
||||
/* Instead of forcing cairo to do everything through a CGContext,
|
||||
* we just use an image surface backed by an IOSurfaceRef mapped
|
||||
* into user-space. We can then use pixman which is quite fast as
|
||||
* far as software rendering goes.
|
||||
*
|
||||
* Additionally, cairo_quartz_surface_t can't handle a number of
|
||||
* tricks that the GSK cairo renderer does with border nodes and
|
||||
* shadows, so an image surface is necessary for that.
|
||||
*
|
||||
* Since our IOSurfaceRef is width*scale-by-height*scale, we undo
|
||||
* the scaling using cairo_surface_set_device_scale() so the renderer
|
||||
* just thinks it's on a 2x scale surface for HiDPI.
|
||||
*/
|
||||
image_surface = cairo_image_surface_create_for_data (data,
|
||||
CAIRO_FORMAT_ARGB32,
|
||||
width,
|
||||
height,
|
||||
stride);
|
||||
cairo_surface_set_device_scale (image_surface, scale, scale);
|
||||
|
||||
/* The buffer should already be locked at this point, and will
|
||||
* be unlocked as part of end_frame.
|
||||
*/
|
||||
|
||||
if (!(cr = cairo_create (image_surface)))
|
||||
goto failure;
|
||||
|
||||
/* Clip to the current damage region */
|
||||
if (damage != NULL)
|
||||
{
|
||||
gdk_cairo_region (cr, damage);
|
||||
cairo_clip (cr);
|
||||
}
|
||||
|
||||
/* If we have some exposed transparent area in the damage region,
|
||||
* we need to clear the existing content first to leave an transparent
|
||||
* area for cairo. We use (surface_bounds or damage)-(opaque) to get
|
||||
* the smallest set of rectangles we need to clear as it's expensive.
|
||||
*/
|
||||
if (!opaque)
|
||||
{
|
||||
cairo_region_t *transparent;
|
||||
cairo_rectangle_int_t r = { 0, 0, width/scale, height/scale };
|
||||
|
||||
cairo_save (cr);
|
||||
|
||||
if (damage != NULL)
|
||||
cairo_region_get_extents (damage, &r);
|
||||
transparent = cairo_region_create_rectangle (&r);
|
||||
if (surface->opaque_region)
|
||||
cairo_region_subtract (transparent, surface->opaque_region);
|
||||
|
||||
if (!cairo_region_is_empty (transparent))
|
||||
{
|
||||
gdk_cairo_region (cr, transparent);
|
||||
cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
|
||||
cairo_fill (cr);
|
||||
}
|
||||
|
||||
cairo_region_destroy (transparent);
|
||||
cairo_restore (cr);
|
||||
}
|
||||
|
||||
failure:
|
||||
cairo_surface_destroy (image_surface);
|
||||
|
||||
return cr;
|
||||
}
|
||||
|
||||
static void
|
||||
copy_surface_data (GdkMacosBuffer *from,
|
||||
GdkMacosBuffer *to,
|
||||
const cairo_region_t *region,
|
||||
int scale)
|
||||
{
|
||||
const guint8 *from_base;
|
||||
guint8 *to_base;
|
||||
guint from_stride;
|
||||
guint to_stride;
|
||||
guint n_rects;
|
||||
|
||||
g_assert (GDK_IS_MACOS_BUFFER (from));
|
||||
g_assert (GDK_IS_MACOS_BUFFER (to));
|
||||
g_assert (region != NULL);
|
||||
g_assert (!cairo_region_is_empty (region));
|
||||
|
||||
from_base = _gdk_macos_buffer_get_data (from);
|
||||
from_stride = _gdk_macos_buffer_get_stride (from);
|
||||
|
||||
to_base = _gdk_macos_buffer_get_data (to);
|
||||
to_stride = _gdk_macos_buffer_get_stride (to);
|
||||
|
||||
n_rects = cairo_region_num_rectangles (region);
|
||||
|
||||
for (guint i = 0; i < n_rects; i++)
|
||||
{
|
||||
cairo_rectangle_int_t rect;
|
||||
int y2;
|
||||
|
||||
cairo_region_get_rectangle (region, i, &rect);
|
||||
|
||||
rect.y *= scale;
|
||||
rect.height *= scale;
|
||||
rect.x *= scale;
|
||||
rect.width *= scale;
|
||||
|
||||
y2 = rect.y + rect.height;
|
||||
|
||||
for (int y = rect.y; y < y2; y++)
|
||||
memcpy (&to_base[y * to_stride + rect.x * 4],
|
||||
&from_base[y * from_stride + rect.x * 4],
|
||||
rect.width * 4);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -86,28 +194,49 @@ _gdk_macos_cairo_context_begin_frame (GdkDrawContext *draw_context,
|
||||
cairo_region_t *region)
|
||||
{
|
||||
GdkMacosCairoContext *self = (GdkMacosCairoContext *)draw_context;
|
||||
GdkSurface *surface;
|
||||
NSWindow *nswindow;
|
||||
GdkMacosBuffer *buffer;
|
||||
GdkMacosSurface *surface;
|
||||
|
||||
g_assert (GDK_IS_MACOS_CAIRO_CONTEXT (self));
|
||||
|
||||
surface = gdk_draw_context_get_surface (draw_context);
|
||||
nswindow = _gdk_macos_surface_get_native (GDK_MACOS_SURFACE (surface));
|
||||
[CATransaction begin];
|
||||
[CATransaction setDisableActions:YES];
|
||||
|
||||
if (self->window_surface == NULL)
|
||||
surface = GDK_MACOS_SURFACE (gdk_draw_context_get_surface (draw_context));
|
||||
buffer = _gdk_macos_surface_get_buffer (surface);
|
||||
|
||||
_gdk_macos_buffer_set_damage (buffer, region);
|
||||
_gdk_macos_buffer_set_flipped (buffer, FALSE);
|
||||
|
||||
_gdk_macos_buffer_lock (buffer);
|
||||
|
||||
/* If there is damage that was on the previous frame that is not on
|
||||
* this frame, we need to copy that rendered region over to the back
|
||||
* buffer so that when swapping buffers, we still have that content.
|
||||
* This is done with a read-only lock on the IOSurface to avoid
|
||||
* invalidating the buffer contents.
|
||||
*/
|
||||
if (surface->front != NULL)
|
||||
{
|
||||
self->window_surface = create_cairo_surface_for_surface (surface);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (![nswindow isOpaque])
|
||||
const cairo_region_t *previous = _gdk_macos_buffer_get_damage (surface->front);
|
||||
|
||||
if (previous != NULL)
|
||||
{
|
||||
cairo_t *cr = cairo_create (self->window_surface);
|
||||
gdk_cairo_region (cr, region);
|
||||
cairo_set_source_rgba (cr, 0, 0, 0, 0);
|
||||
cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
|
||||
cairo_fill (cr);
|
||||
cairo_destroy (cr);
|
||||
cairo_region_t *copy;
|
||||
|
||||
copy = cairo_region_copy (previous);
|
||||
cairo_region_subtract (copy, region);
|
||||
|
||||
if (!cairo_region_is_empty (copy))
|
||||
{
|
||||
int scale = gdk_surface_get_scale_factor (GDK_SURFACE (surface));
|
||||
|
||||
_gdk_macos_buffer_read_lock (surface->front);
|
||||
copy_surface_data (surface->front, buffer, copy, scale);
|
||||
_gdk_macos_buffer_read_unlock (surface->front);
|
||||
}
|
||||
|
||||
cairo_region_destroy (copy);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -117,28 +246,27 @@ _gdk_macos_cairo_context_end_frame (GdkDrawContext *draw_context,
|
||||
cairo_region_t *painted)
|
||||
{
|
||||
GdkMacosCairoContext *self = (GdkMacosCairoContext *)draw_context;
|
||||
GdkSurface *surface;
|
||||
NSView *nsview;
|
||||
GdkMacosSurface *surface;
|
||||
GdkMacosBuffer *buffer;
|
||||
|
||||
g_assert (GDK_IS_MACOS_CAIRO_CONTEXT (self));
|
||||
g_assert (self->window_surface != NULL);
|
||||
|
||||
surface = gdk_draw_context_get_surface (draw_context);
|
||||
nsview = _gdk_macos_surface_get_view (GDK_MACOS_SURFACE (surface));
|
||||
surface = GDK_MACOS_SURFACE (gdk_draw_context_get_surface (draw_context));
|
||||
buffer = _gdk_macos_surface_get_buffer (surface);
|
||||
|
||||
if (GDK_IS_MACOS_CAIRO_VIEW (nsview))
|
||||
[(GdkMacosCairoView *)nsview setCairoSurface:self->window_surface
|
||||
withDamage:painted];
|
||||
_gdk_macos_buffer_unlock (buffer);
|
||||
|
||||
_gdk_macos_surface_swap_buffers (surface, painted);
|
||||
|
||||
[CATransaction commit];
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_macos_cairo_context_surface_resized (GdkDrawContext *draw_context)
|
||||
{
|
||||
GdkMacosCairoContext *self = (GdkMacosCairoContext *)draw_context;
|
||||
g_assert (GDK_IS_MACOS_CAIRO_CONTEXT (draw_context));
|
||||
|
||||
g_assert (GDK_IS_MACOS_CAIRO_CONTEXT (self));
|
||||
|
||||
g_clear_pointer (&self->window_surface, cairo_surface_destroy);
|
||||
/* Do nothing, next begin_frame will get new buffer */
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
105
gdk/macos/gdkmacosdisplay-feedback.c
Normal file
105
gdk/macos/gdkmacosdisplay-feedback.c
Normal file
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright © 2022 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <AppKit/AppKit.h>
|
||||
|
||||
#include "gdkmacosdisplay-private.h"
|
||||
#include "gdkmacossurface-private.h"
|
||||
|
||||
static void
|
||||
gdk_macos_display_user_defaults_changed_cb (CFNotificationCenterRef center,
|
||||
void *observer,
|
||||
CFStringRef name,
|
||||
const void *object,
|
||||
CFDictionaryRef userInfo)
|
||||
{
|
||||
GdkMacosDisplay *self = observer;
|
||||
|
||||
g_assert (GDK_IS_MACOS_DISPLAY (self));
|
||||
|
||||
_gdk_macos_display_reload_settings (self);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_display_monitors_changed_cb (CFNotificationCenterRef center,
|
||||
void *observer,
|
||||
CFStringRef name,
|
||||
const void *object,
|
||||
CFDictionaryRef userInfo)
|
||||
{
|
||||
GdkMacosDisplay *self = observer;
|
||||
|
||||
g_assert (GDK_IS_MACOS_DISPLAY (self));
|
||||
|
||||
_gdk_macos_display_reload_monitors (self);
|
||||
|
||||
/* Now we need to update all our surface positions since they
|
||||
* probably just changed origins.
|
||||
*/
|
||||
for (const GList *iter = _gdk_macos_display_get_surfaces (self);
|
||||
iter != NULL;
|
||||
iter = iter->next)
|
||||
{
|
||||
GdkMacosSurface *surface = iter->data;
|
||||
|
||||
g_assert (GDK_IS_MACOS_SURFACE (surface));
|
||||
|
||||
_gdk_macos_surface_monitor_changed (surface);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_gdk_macos_display_feedback_init (GdkMacosDisplay *self)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_MACOS_DISPLAY (self));
|
||||
|
||||
CFNotificationCenterAddObserver (CFNotificationCenterGetLocalCenter (),
|
||||
self,
|
||||
gdk_macos_display_monitors_changed_cb,
|
||||
CFSTR ("NSApplicationDidChangeScreenParametersNotification"),
|
||||
NULL,
|
||||
CFNotificationSuspensionBehaviorDeliverImmediately);
|
||||
|
||||
CFNotificationCenterAddObserver (CFNotificationCenterGetDistributedCenter (),
|
||||
self,
|
||||
gdk_macos_display_user_defaults_changed_cb,
|
||||
CFSTR ("NSUserDefaultsDidChangeNotification"),
|
||||
NULL,
|
||||
CFNotificationSuspensionBehaviorDeliverImmediately);
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_macos_display_feedback_destroy (GdkMacosDisplay *self)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_MACOS_DISPLAY (self));
|
||||
|
||||
CFNotificationCenterRemoveObserver (CFNotificationCenterGetDistributedCenter (),
|
||||
self,
|
||||
CFSTR ("NSApplicationDidChangeScreenParametersNotification"),
|
||||
NULL);
|
||||
|
||||
CFNotificationCenterRemoveObserver (CFNotificationCenterGetDistributedCenter (),
|
||||
self,
|
||||
CFSTR ("NSUserDefaultsDidChangeNotification"),
|
||||
NULL);
|
||||
|
||||
}
|
||||
@@ -43,6 +43,8 @@ G_BEGIN_DECLS
|
||||
#define GIC_FILTER_PASSTHRU 0
|
||||
#define GIC_FILTER_FILTERED 1
|
||||
|
||||
#define GDK_MACOS_EVENT_DROP (GdkEvent *)GSIZE_TO_POINTER(1)
|
||||
|
||||
struct _GdkMacosDisplay
|
||||
{
|
||||
GdkDisplay parent_instance;
|
||||
@@ -68,16 +70,6 @@ struct _GdkMacosDisplay
|
||||
*/
|
||||
GQueue sorted_surfaces;
|
||||
|
||||
/* Our CVDisplayLink based GSource which we use to freeze/thaw the
|
||||
* GdkFrameClock for the surface.
|
||||
*/
|
||||
GSource *frame_source;
|
||||
|
||||
/* A queue of surfaces which we know are awaiting frames to be drawn. This
|
||||
* uses the GdkMacosSurface.frame link.
|
||||
*/
|
||||
GQueue awaiting_frames;
|
||||
|
||||
/* The surface that is receiving keyboard events */
|
||||
GdkMacosSurface *keyboard_surface;
|
||||
|
||||
@@ -92,6 +84,14 @@ struct _GdkMacosDisplay
|
||||
int min_y;
|
||||
int max_x;
|
||||
int max_y;
|
||||
|
||||
/* A GSource to select a new main/key window */
|
||||
guint select_key_in_idle;
|
||||
|
||||
/* Note if we have a key window that is not a GdkMacosWindow
|
||||
* such as a NSPanel used for native dialogs.
|
||||
*/
|
||||
guint key_window_is_foregin : 1;
|
||||
};
|
||||
|
||||
struct _GdkMacosDisplayClass
|
||||
@@ -124,6 +124,8 @@ GdkMonitor *_gdk_macos_display_get_monitor_at_display_coords (GdkMacosDisp
|
||||
int y);
|
||||
GdkEvent *_gdk_macos_display_translate (GdkMacosDisplay *self,
|
||||
NSEvent *event);
|
||||
void _gdk_macos_display_feedback_init (GdkMacosDisplay *self);
|
||||
void _gdk_macos_display_feedback_destroy (GdkMacosDisplay *self);
|
||||
void _gdk_macos_display_break_all_grabs (GdkMacosDisplay *self,
|
||||
guint32 time);
|
||||
GdkModifierType _gdk_macos_display_get_current_keyboard_modifiers (GdkMacosDisplay *self);
|
||||
@@ -136,10 +138,6 @@ GdkMacosSurface *_gdk_macos_display_get_surface_at_display_coords (GdkMacosDisp
|
||||
void _gdk_macos_display_reload_monitors (GdkMacosDisplay *self);
|
||||
void _gdk_macos_display_surface_removed (GdkMacosDisplay *self,
|
||||
GdkMacosSurface *surface);
|
||||
void _gdk_macos_display_add_frame_callback (GdkMacosDisplay *self,
|
||||
GdkMacosSurface *surface);
|
||||
void _gdk_macos_display_remove_frame_callback (GdkMacosDisplay *self,
|
||||
GdkMacosSurface *surface);
|
||||
NSWindow *_gdk_macos_display_find_native_under_pointer (GdkMacosDisplay *self,
|
||||
int *x,
|
||||
int *y);
|
||||
@@ -155,7 +153,6 @@ void _gdk_macos_display_surface_resigned_key (GdkMacosDisp
|
||||
GdkMacosSurface *surface);
|
||||
void _gdk_macos_display_surface_became_key (GdkMacosDisplay *self,
|
||||
GdkMacosSurface *surface);
|
||||
int _gdk_macos_display_get_nominal_refresh_rate (GdkMacosDisplay *self);
|
||||
void _gdk_macos_display_clear_sorting (GdkMacosDisplay *self);
|
||||
const GList *_gdk_macos_display_get_surfaces (GdkMacosDisplay *self);
|
||||
void _gdk_macos_display_send_button_event (GdkMacosDisplay *self,
|
||||
@@ -174,6 +171,10 @@ void _gdk_macos_display_set_drag (GdkMacosDisp
|
||||
void _gdk_macos_display_set_drop (GdkMacosDisplay *self,
|
||||
NSInteger sequence_number,
|
||||
GdkDrop *drop);
|
||||
void _gdk_macos_display_position_surface (GdkMacosDisplay *self,
|
||||
GdkMacosSurface *surface,
|
||||
int *x,
|
||||
int *y);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ typedef struct
|
||||
const char *font_name;
|
||||
int xft_dpi;
|
||||
int double_click_time;
|
||||
int cursor_blink_timeout;
|
||||
int cursor_blink_time;
|
||||
guint enable_animations : 1;
|
||||
guint shell_shows_desktop : 1;
|
||||
guint shell_shows_menubar : 1;
|
||||
@@ -65,9 +65,9 @@ _gdk_macos_settings_load (GdkMacosSettings *settings)
|
||||
|
||||
ival = [defaults integerForKey:@"NSTextInsertionPointBlinkPeriod"];
|
||||
if (ival > 0)
|
||||
settings->cursor_blink_timeout = ival;
|
||||
settings->cursor_blink_time = ival;
|
||||
else
|
||||
settings->cursor_blink_timeout = 1000;
|
||||
settings->cursor_blink_time = 1000;
|
||||
|
||||
settings->primary_button_warps_slider =
|
||||
[[NSUserDefaults standardUserDefaults] boolForKey:@"AppleScrollerPagingBehavior"] == YES;
|
||||
@@ -124,9 +124,9 @@ _gdk_macos_display_get_setting (GdkMacosDisplay *self,
|
||||
g_value_set_int (value, current_settings.xft_dpi);
|
||||
ret = TRUE;
|
||||
}
|
||||
else if (strcmp (setting, "gtk-cursor-blink-timeout") == 0)
|
||||
else if (strcmp (setting, "gtk-cursor-blink-time") == 0)
|
||||
{
|
||||
g_value_set_int (value, current_settings.cursor_blink_timeout);
|
||||
g_value_set_int (value, current_settings.cursor_blink_time);
|
||||
ret = TRUE;
|
||||
}
|
||||
else if (strcmp (setting, "gtk-double-click-time") == 0)
|
||||
|
||||
@@ -211,6 +211,7 @@ fill_button_event (GdkMacosDisplay *display,
|
||||
GdkDevice *pointer = NULL;
|
||||
GdkDeviceTool *tool = NULL;
|
||||
double *axes = NULL;
|
||||
cairo_region_t *input_region;
|
||||
|
||||
g_assert (GDK_IS_MACOS_DISPLAY (display));
|
||||
g_assert (GDK_IS_MACOS_SURFACE (surface));
|
||||
@@ -218,6 +219,7 @@ fill_button_event (GdkMacosDisplay *display,
|
||||
seat = gdk_display_get_default_seat (GDK_DISPLAY (display));
|
||||
state = get_keyboard_modifiers_from_ns_event (nsevent) |
|
||||
_gdk_macos_display_get_current_mouse_modifiers (display);
|
||||
input_region = GDK_SURFACE (surface)->input_region;
|
||||
|
||||
switch ((int)[nsevent type])
|
||||
{
|
||||
@@ -244,7 +246,8 @@ fill_button_event (GdkMacosDisplay *display,
|
||||
*/
|
||||
if (type == GDK_BUTTON_PRESS &&
|
||||
(x < 0 || x > GDK_SURFACE (surface)->width ||
|
||||
y < 0 || y > GDK_SURFACE (surface)->height))
|
||||
y < 0 || y > GDK_SURFACE (surface)->height ||
|
||||
(input_region && !cairo_region_contains_point (input_region, x, y))))
|
||||
return NULL;
|
||||
|
||||
if (([nsevent subtype] == NSEventSubtypeTabletPoint) &&
|
||||
@@ -537,6 +540,7 @@ fill_pinch_event (GdkMacosDisplay *display,
|
||||
seat = gdk_display_get_default_seat (GDK_DISPLAY (display));
|
||||
|
||||
return gdk_touchpad_event_new_pinch (GDK_SURFACE (surface),
|
||||
NULL, /* FIXME make up sequences */
|
||||
gdk_seat_get_pointer (seat),
|
||||
get_time_from_ns_event (nsevent),
|
||||
get_keyboard_modifiers_from_ns_event (nsevent),
|
||||
@@ -608,6 +612,8 @@ fill_scroll_event (GdkMacosDisplay *self,
|
||||
GdkModifierType state;
|
||||
GdkDevice *pointer;
|
||||
GdkEvent *ret = NULL;
|
||||
NSEventPhase phase;
|
||||
NSEventPhase momentumPhase;
|
||||
GdkSeat *seat;
|
||||
double dx;
|
||||
double dy;
|
||||
@@ -615,11 +621,31 @@ fill_scroll_event (GdkMacosDisplay *self,
|
||||
g_assert (GDK_IS_MACOS_SURFACE (surface));
|
||||
g_assert (nsevent != NULL);
|
||||
|
||||
phase = [nsevent phase];
|
||||
momentumPhase = [nsevent momentumPhase];
|
||||
|
||||
/* Ignore kinetic scroll events from the display server as we already
|
||||
* handle those internally.
|
||||
*/
|
||||
if (phase == 0 && momentumPhase != 0)
|
||||
return GDK_MACOS_EVENT_DROP;
|
||||
|
||||
seat = gdk_display_get_default_seat (GDK_DISPLAY (self));
|
||||
pointer = gdk_seat_get_pointer (seat);
|
||||
state = _gdk_macos_display_get_current_mouse_modifiers (self) |
|
||||
_gdk_macos_display_get_current_keyboard_modifiers (self);
|
||||
|
||||
/* If we are starting a new phase, send a stop so any previous
|
||||
* scrolling immediately stops.
|
||||
*/
|
||||
if (phase == NSEventPhaseMayBegin)
|
||||
return gdk_scroll_event_new (GDK_SURFACE (surface),
|
||||
pointer,
|
||||
NULL,
|
||||
get_time_from_ns_event (nsevent),
|
||||
state,
|
||||
0.0, 0.0, TRUE);
|
||||
|
||||
dx = [nsevent deltaX];
|
||||
dy = [nsevent deltaY];
|
||||
|
||||
@@ -663,34 +689,32 @@ fill_scroll_event (GdkMacosDisplay *self,
|
||||
dy = 0.0;
|
||||
}
|
||||
|
||||
if (dx != 0.0 || dy != 0.0)
|
||||
if ((dx != 0.0 || dy != 0.0) && ![nsevent hasPreciseScrollingDeltas])
|
||||
{
|
||||
if ([nsevent hasPreciseScrollingDeltas])
|
||||
{
|
||||
GdkEvent *emulated;
|
||||
g_assert (ret == NULL);
|
||||
|
||||
emulated = gdk_scroll_event_new_discrete (GDK_SURFACE (surface),
|
||||
pointer,
|
||||
NULL,
|
||||
get_time_from_ns_event (nsevent),
|
||||
state,
|
||||
direction,
|
||||
TRUE);
|
||||
_gdk_event_queue_append (GDK_DISPLAY (self), emulated);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_assert (ret == NULL);
|
||||
ret = gdk_scroll_event_new_discrete (GDK_SURFACE (surface),
|
||||
pointer,
|
||||
NULL,
|
||||
get_time_from_ns_event (nsevent),
|
||||
state,
|
||||
direction,
|
||||
FALSE);
|
||||
}
|
||||
|
||||
ret = gdk_scroll_event_new (GDK_SURFACE (surface),
|
||||
pointer,
|
||||
NULL,
|
||||
get_time_from_ns_event (nsevent),
|
||||
state,
|
||||
dx,
|
||||
dy,
|
||||
FALSE);
|
||||
}
|
||||
if (phase == NSEventPhaseEnded || phase == NSEventPhaseCancelled)
|
||||
{
|
||||
/* The user must have released their fingers in a touchpad
|
||||
* scroll, so try to send a scroll is_stop event.
|
||||
*/
|
||||
if (ret != NULL)
|
||||
_gdk_event_queue_append (GDK_DISPLAY (self), g_steal_pointer (&ret));
|
||||
ret = gdk_scroll_event_new (GDK_SURFACE (surface),
|
||||
pointer,
|
||||
NULL,
|
||||
get_time_from_ns_event (nsevent),
|
||||
state,
|
||||
0.0, 0.0, TRUE);
|
||||
}
|
||||
|
||||
return g_steal_pointer (&ret);
|
||||
@@ -853,9 +877,9 @@ get_surface_from_ns_event (GdkMacosDisplay *self,
|
||||
|
||||
find_under_pointer:
|
||||
|
||||
if (!surface)
|
||||
if (surface == NULL && nswindow == NULL)
|
||||
{
|
||||
/* Fallback used when no NSSurface set. This happens e.g. when
|
||||
/* Fallback used when no NSWindow set. This happens e.g. when
|
||||
* we allow motion events without a window set in gdk_event_translate()
|
||||
* that occur immediately after the main menu bar was clicked/used.
|
||||
* This fallback will not return coordinates contained in a window's
|
||||
@@ -905,7 +929,13 @@ find_surface_for_mouse_event (GdkMacosDisplay *self,
|
||||
GdkDeviceGrabInfo *grab;
|
||||
GdkSeat *seat;
|
||||
|
||||
surface = get_surface_from_ns_event (self, nsevent, &point, x, y);
|
||||
/* Even if we had a surface window, it might be for something outside
|
||||
* the input region (shadow) which we might want to ignore. This is
|
||||
* handled for us deeper in the event unwrapping.
|
||||
*/
|
||||
if (!(surface = get_surface_from_ns_event (self, nsevent, &point, x, y)))
|
||||
return NULL;
|
||||
|
||||
display = gdk_surface_get_display (surface);
|
||||
seat = gdk_display_get_default_seat (GDK_DISPLAY (self));
|
||||
pointer = gdk_seat_get_pointer (seat);
|
||||
@@ -1007,11 +1037,6 @@ find_surface_for_ns_event (GdkMacosDisplay *self,
|
||||
g_assert (x != NULL);
|
||||
g_assert (y != NULL);
|
||||
|
||||
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])
|
||||
@@ -1036,7 +1061,9 @@ find_surface_for_ns_event (GdkMacosDisplay *self,
|
||||
/* Only handle our own entered/exited events, not the ones for the
|
||||
* titlebar buttons.
|
||||
*/
|
||||
if ([nsevent trackingArea] == [view trackingArea])
|
||||
if ((surface = get_surface_from_ns_event (self, nsevent, &point, x, y)) &&
|
||||
(view = (GdkMacosBaseView *)[GDK_MACOS_SURFACE (surface)->window contentView]) &&
|
||||
([nsevent trackingArea] == [view trackingArea]))
|
||||
return GDK_MACOS_SURFACE (surface);
|
||||
else
|
||||
return NULL;
|
||||
@@ -1059,6 +1086,7 @@ _gdk_macos_display_translate (GdkMacosDisplay *self,
|
||||
GdkMacosSurface *surface;
|
||||
GdkMacosWindow *window;
|
||||
NSEventType event_type;
|
||||
NSWindow *event_window;
|
||||
GdkEvent *ret = NULL;
|
||||
int x;
|
||||
int y;
|
||||
@@ -1101,6 +1129,15 @@ _gdk_macos_display_translate (GdkMacosDisplay *self,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* If the event was delivered to NSWindow that is foreign (or rather,
|
||||
* Cocoa native), then we should pass the event along to that window.
|
||||
*/
|
||||
if ((event_window = [nsevent window]) && !GDK_IS_MACOS_WINDOW (event_window))
|
||||
return NULL;
|
||||
|
||||
/* If we can't find a GdkSurface to deliver the event to, then we
|
||||
* should pass it along to the NSApp.
|
||||
*/
|
||||
if (!(surface = find_surface_for_ns_event (self, nsevent, &x, &y)))
|
||||
return NULL;
|
||||
|
||||
@@ -1132,15 +1169,31 @@ _gdk_macos_display_translate (GdkMacosDisplay *self,
|
||||
if (test_resize (nsevent, surface, x, y))
|
||||
return NULL;
|
||||
|
||||
if ((event_type == NSEventTypeRightMouseDown ||
|
||||
event_type == NSEventTypeOtherMouseDown ||
|
||||
event_type == NSEventTypeLeftMouseDown))
|
||||
if (event_type == NSEventTypeRightMouseDown ||
|
||||
event_type == NSEventTypeOtherMouseDown ||
|
||||
event_type == NSEventTypeLeftMouseDown)
|
||||
{
|
||||
if (![NSApp isActive])
|
||||
[NSApp activateIgnoringOtherApps:YES];
|
||||
|
||||
if (![window isKeyWindow])
|
||||
[window makeKeyWindow];
|
||||
{
|
||||
NSWindow *orig_window = [nsevent window];
|
||||
|
||||
/* To get NSApp to supress activating the window we might
|
||||
* have clicked through the shadow of, we need to dispatch
|
||||
* the event and handle it in GdkMacosView:mouseDown to call
|
||||
* [NSApp preventWindowOrdering]. Calling it here will not
|
||||
* do anything as the event is not registered.
|
||||
*/
|
||||
if (orig_window &&
|
||||
GDK_IS_MACOS_WINDOW (orig_window) &&
|
||||
[(GdkMacosWindow *)orig_window needsMouseDownQuirk])
|
||||
[NSApp sendEvent:nsevent];
|
||||
|
||||
[window showAndMakeKey:YES];
|
||||
_gdk_macos_display_clear_sorting (self);
|
||||
}
|
||||
}
|
||||
|
||||
switch ((int)event_type)
|
||||
@@ -1173,7 +1226,11 @@ _gdk_macos_display_translate (GdkMacosDisplay *self,
|
||||
GdkDevice *pointer = gdk_seat_get_pointer (seat);
|
||||
GdkDeviceGrabInfo *grab = _gdk_display_get_last_device_grab (GDK_DISPLAY (self), pointer);
|
||||
|
||||
if (grab == NULL)
|
||||
if ([(GdkMacosWindow *)window isInManualResizeOrMove])
|
||||
{
|
||||
ret = GDK_MACOS_EVENT_DROP;
|
||||
}
|
||||
else if (grab == NULL)
|
||||
{
|
||||
if (event_type == NSEventTypeMouseExited)
|
||||
[[NSCursor arrowCursor] set];
|
||||
|
||||
155
gdk/macos/gdkmacosdisplay-wm.c
Normal file
155
gdk/macos/gdkmacosdisplay-wm.c
Normal file
@@ -0,0 +1,155 @@
|
||||
/*
|
||||
* Copyright © 2022 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gdkmacosdisplay-private.h"
|
||||
#include "gdkmacosmonitor-private.h"
|
||||
#include "gdkmacossurface-private.h"
|
||||
#include "gdkmacostoplevelsurface-private.h"
|
||||
|
||||
#define WARP_OFFSET_X 15
|
||||
#define WARP_OFFSET_Y 15
|
||||
|
||||
static void
|
||||
_gdk_macos_display_position_toplevel_with_parent (GdkMacosDisplay *self,
|
||||
GdkMacosSurface *surface,
|
||||
GdkMacosSurface *parent,
|
||||
int *x,
|
||||
int *y)
|
||||
{
|
||||
GdkRectangle surface_rect;
|
||||
GdkRectangle parent_rect;
|
||||
GdkMonitor *monitor;
|
||||
|
||||
g_assert (GDK_IS_MACOS_DISPLAY (self));
|
||||
g_assert (GDK_IS_MACOS_TOPLEVEL_SURFACE (surface));
|
||||
g_assert (GDK_IS_MACOS_TOPLEVEL_SURFACE (parent));
|
||||
|
||||
monitor = _gdk_macos_surface_get_best_monitor (parent);
|
||||
|
||||
/* Try to center on top of the parent but also try to make the whole thing
|
||||
* visible in case that lands us under the topbar/panel/etc.
|
||||
*/
|
||||
parent_rect.x = parent->root_x + parent->shadow_left;
|
||||
parent_rect.y = parent->root_y + parent->shadow_top;
|
||||
parent_rect.width = GDK_SURFACE (parent)->width - parent->shadow_left - parent->shadow_right;
|
||||
parent_rect.height = GDK_SURFACE (parent)->height - parent->shadow_top - parent->shadow_bottom;
|
||||
|
||||
surface_rect.width = GDK_SURFACE (surface)->width - surface->shadow_left - surface->shadow_right;
|
||||
surface_rect.height = GDK_SURFACE (surface)->height - surface->shadow_top - surface->shadow_bottom;
|
||||
surface_rect.x = parent_rect.x + ((parent_rect.width - surface_rect.width) / 2);
|
||||
surface_rect.y = parent_rect.y + ((parent_rect.height - surface_rect.height) / 2);
|
||||
|
||||
_gdk_macos_monitor_clamp (GDK_MACOS_MONITOR (monitor), &surface_rect);
|
||||
|
||||
*x = surface_rect.x - surface->shadow_left;
|
||||
*y = surface_rect.y - surface->shadow_top;
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
has_surface_at_origin (const GList *surfaces,
|
||||
int x,
|
||||
int y)
|
||||
{
|
||||
for (const GList *iter = surfaces; iter; iter = iter->next)
|
||||
{
|
||||
GdkMacosSurface *surface = iter->data;
|
||||
|
||||
if (surface->root_x == x && surface->root_y == y)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_macos_display_position_toplevel (GdkMacosDisplay *self,
|
||||
GdkMacosSurface *surface,
|
||||
int *x,
|
||||
int *y)
|
||||
{
|
||||
cairo_rectangle_int_t surface_rect;
|
||||
GdkRectangle workarea;
|
||||
const GList *surfaces;
|
||||
GdkMonitor *monitor;
|
||||
CGPoint mouse;
|
||||
|
||||
g_assert (GDK_IS_MACOS_DISPLAY (self));
|
||||
g_assert (GDK_IS_MACOS_TOPLEVEL_SURFACE (surface));
|
||||
|
||||
mouse = [NSEvent mouseLocation];
|
||||
monitor = _gdk_macos_display_get_monitor_at_display_coords (self, mouse.x, mouse.y);
|
||||
gdk_macos_monitor_get_workarea (monitor, &workarea);
|
||||
|
||||
/* First place at top-left of current monitor */
|
||||
surface_rect.width = GDK_SURFACE (surface)->width - surface->shadow_left - surface->shadow_right;
|
||||
surface_rect.height = GDK_SURFACE (surface)->height - surface->shadow_top - surface->shadow_bottom;
|
||||
surface_rect.x = workarea.x + ((workarea.width - surface_rect.width) / 2);
|
||||
surface_rect.y = workarea.y + ((workarea.height - surface_rect.height) / 2);
|
||||
|
||||
_gdk_macos_monitor_clamp (GDK_MACOS_MONITOR (surface->best_monitor), &surface_rect);
|
||||
|
||||
*x = surface_rect.x - surface->shadow_left;
|
||||
*y = surface_rect.y - surface->shadow_top;
|
||||
|
||||
/* Try to see if there are any other surfaces at this origin and if so,
|
||||
* adjust until we get something better.
|
||||
*/
|
||||
surfaces = _gdk_macos_display_get_surfaces (self);
|
||||
while (has_surface_at_origin (surfaces, *x, *y))
|
||||
{
|
||||
*x += WARP_OFFSET_X;
|
||||
*y += WARP_OFFSET_Y;
|
||||
|
||||
/* If we reached the bottom right, just bail and try the workspace origin */
|
||||
if (*x + surface->shadow_left + WARP_OFFSET_X > workarea.x + workarea.width ||
|
||||
*y + surface->shadow_top + WARP_OFFSET_Y > workarea.y + workarea.height)
|
||||
{
|
||||
*x = workarea.x - surface->shadow_left;
|
||||
*y = workarea.y - surface->shadow_top;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*<private>
|
||||
* _gdk_macos_display_position_surface:
|
||||
*
|
||||
* Tries to position a window on a screen without landing in edges
|
||||
* and other weird areas the user can't use.
|
||||
*/
|
||||
void
|
||||
_gdk_macos_display_position_surface (GdkMacosDisplay *self,
|
||||
GdkMacosSurface *surface,
|
||||
int *x,
|
||||
int *y)
|
||||
{
|
||||
GdkSurface *transient_for;
|
||||
|
||||
g_return_if_fail (GDK_IS_MACOS_DISPLAY (self));
|
||||
g_return_if_fail (GDK_IS_MACOS_TOPLEVEL_SURFACE (surface));
|
||||
|
||||
transient_for = GDK_SURFACE (surface)->transient_for;
|
||||
|
||||
if (transient_for != NULL)
|
||||
_gdk_macos_display_position_toplevel_with_parent (self, surface, GDK_MACOS_SURFACE (transient_for), x, y);
|
||||
else
|
||||
_gdk_macos_display_position_toplevel (self, surface, x, y);
|
||||
}
|
||||
@@ -156,53 +156,13 @@ gdk_macos_display_update_bounds (GdkMacosDisplay *self)
|
||||
self->width = self->max_x - self->min_x;
|
||||
self->height = self->max_y - self->min_y;
|
||||
|
||||
GDK_NOTE (MISC,
|
||||
g_message ("Displays reconfigured to bounds %d,%d %dx%d",
|
||||
self->min_x, self->min_y, self->width, self->height));
|
||||
|
||||
GDK_END_MACOS_ALLOC_POOL;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_display_monitors_changed_cb (CFNotificationCenterRef center,
|
||||
void *observer,
|
||||
CFStringRef name,
|
||||
const void *object,
|
||||
CFDictionaryRef userInfo)
|
||||
{
|
||||
GdkMacosDisplay *self = observer;
|
||||
|
||||
g_assert (GDK_IS_MACOS_DISPLAY (self));
|
||||
|
||||
_gdk_macos_display_reload_monitors (self);
|
||||
|
||||
/* Now we need to update all our surface positions since they
|
||||
* probably just changed origins. We ignore the popup surfaces
|
||||
* since we can rely on the toplevel surfaces to handle that.
|
||||
*/
|
||||
for (const GList *iter = _gdk_macos_display_get_surfaces (self);
|
||||
iter != NULL;
|
||||
iter = iter->next)
|
||||
{
|
||||
GdkMacosSurface *surface = iter->data;
|
||||
|
||||
g_assert (GDK_IS_MACOS_SURFACE (surface));
|
||||
|
||||
if (GDK_IS_TOPLEVEL (surface))
|
||||
_gdk_macos_surface_update_position (surface);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_display_user_defaults_changed_cb (CFNotificationCenterRef center,
|
||||
void *observer,
|
||||
CFStringRef name,
|
||||
const void *object,
|
||||
CFDictionaryRef userInfo)
|
||||
{
|
||||
GdkMacosDisplay *self = observer;
|
||||
|
||||
g_assert (GDK_IS_MACOS_DISPLAY (self));
|
||||
|
||||
_gdk_macos_display_reload_settings (self);
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_macos_display_reload_monitors (GdkMacosDisplay *self)
|
||||
{
|
||||
@@ -275,52 +235,6 @@ gdk_macos_display_load_seat (GdkMacosDisplay *self)
|
||||
g_object_unref (seat);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_macos_display_frame_cb (gpointer data)
|
||||
{
|
||||
GdkMacosDisplay *self = data;
|
||||
GdkDisplayLinkSource *source;
|
||||
gint64 presentation_time;
|
||||
gint64 now;
|
||||
GList *iter;
|
||||
|
||||
g_assert (GDK_IS_MACOS_DISPLAY (self));
|
||||
|
||||
source = (GdkDisplayLinkSource *)self->frame_source;
|
||||
|
||||
presentation_time = source->presentation_time;
|
||||
now = g_source_get_time ((GSource *)source);
|
||||
|
||||
iter = self->awaiting_frames.head;
|
||||
|
||||
while (iter != NULL)
|
||||
{
|
||||
GdkMacosSurface *surface = iter->data;
|
||||
|
||||
g_assert (GDK_IS_MACOS_SURFACE (surface));
|
||||
|
||||
iter = iter->next;
|
||||
|
||||
_gdk_macos_display_remove_frame_callback (self, surface);
|
||||
_gdk_macos_surface_thaw (surface,
|
||||
source->presentation_time,
|
||||
source->refresh_interval);
|
||||
}
|
||||
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_display_load_display_link (GdkMacosDisplay *self)
|
||||
{
|
||||
self->frame_source = gdk_display_link_source_new ();
|
||||
g_source_set_callback (self->frame_source,
|
||||
gdk_macos_display_frame_cb,
|
||||
self,
|
||||
NULL);
|
||||
g_source_attach (self->frame_source, NULL);
|
||||
}
|
||||
|
||||
static const char *
|
||||
gdk_macos_display_get_name (GdkDisplay *display)
|
||||
{
|
||||
@@ -396,11 +310,15 @@ gdk_macos_display_queue_events (GdkDisplay *display)
|
||||
|
||||
g_return_if_fail (GDK_IS_MACOS_DISPLAY (self));
|
||||
|
||||
if ((nsevent = _gdk_macos_event_source_get_pending ()))
|
||||
while ((nsevent = _gdk_macos_event_source_get_pending ()))
|
||||
{
|
||||
GdkEvent *event = _gdk_macos_display_translate (self, nsevent);
|
||||
|
||||
if (event != NULL)
|
||||
if (event == GDK_MACOS_EVENT_DROP)
|
||||
{
|
||||
[nsevent release];
|
||||
}
|
||||
else if (event != NULL)
|
||||
{
|
||||
push_nsevent (event, nsevent);
|
||||
_gdk_windowing_got_event (GDK_DISPLAY (self),
|
||||
@@ -424,7 +342,6 @@ _gdk_macos_display_surface_added (GdkMacosDisplay *self,
|
||||
g_assert (GDK_IS_MACOS_SURFACE (surface));
|
||||
g_assert (!queue_contains (&self->sorted_surfaces, &surface->sorted));
|
||||
g_assert (!queue_contains (&self->main_surfaces, &surface->main));
|
||||
g_assert (!queue_contains (&self->awaiting_frames, &surface->frame));
|
||||
g_assert (surface->sorted.data == surface);
|
||||
g_assert (surface->main.data == surface);
|
||||
g_assert (surface->frame.data == surface);
|
||||
@@ -451,9 +368,6 @@ _gdk_macos_display_surface_removed (GdkMacosDisplay *self,
|
||||
if (queue_contains (&self->main_surfaces, &surface->main))
|
||||
_gdk_macos_display_surface_resigned_main (self, surface);
|
||||
|
||||
if (queue_contains (&self->awaiting_frames, &surface->frame))
|
||||
g_queue_unlink (&self->awaiting_frames, &surface->frame);
|
||||
|
||||
g_return_if_fail (self->keyboard_surface != surface);
|
||||
}
|
||||
|
||||
@@ -476,6 +390,21 @@ _gdk_macos_display_surface_became_key (GdkMacosDisplay *self,
|
||||
event = gdk_focus_event_new (GDK_SURFACE (surface), keyboard, TRUE);
|
||||
_gdk_event_queue_append (GDK_DISPLAY (self), event);
|
||||
|
||||
/* For each parent surface, we want them to look like they
|
||||
* are also still focused, so ensure they have that same
|
||||
* state associated with them.
|
||||
*/
|
||||
if (GDK_IS_POPUP (surface))
|
||||
{
|
||||
for (GdkSurface *parent = GDK_SURFACE (surface)->parent;
|
||||
parent != NULL;
|
||||
parent = parent->parent)
|
||||
{
|
||||
if (GDK_IS_TOPLEVEL (parent))
|
||||
gdk_synthesize_surface_state (parent, 0, GDK_TOPLEVEL_STATE_FOCUSED);
|
||||
}
|
||||
}
|
||||
|
||||
/* We just became the active window. Unlike X11, Mac OS X does
|
||||
* not send us motion events while the window does not have focus
|
||||
* ("is not key"). We send a dummy motion notify event now, so that
|
||||
@@ -484,6 +413,39 @@ _gdk_macos_display_surface_became_key (GdkMacosDisplay *self,
|
||||
gdk_surface_request_motion (GDK_SURFACE (surface));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
select_key_in_idle_cb (gpointer data)
|
||||
{
|
||||
GdkMacosDisplay *self = data;
|
||||
|
||||
g_assert (GDK_IS_MACOS_DISPLAY (self));
|
||||
|
||||
self->select_key_in_idle = 0;
|
||||
|
||||
/* Don't steal focus from NSPanel, etc */
|
||||
if (self->key_window_is_foregin)
|
||||
return G_SOURCE_REMOVE;
|
||||
|
||||
if (self->keyboard_surface == NULL)
|
||||
{
|
||||
const GList *surfaces = _gdk_macos_display_get_surfaces (self);
|
||||
|
||||
for (const GList *iter = surfaces; iter; iter = iter->next)
|
||||
{
|
||||
GdkMacosSurface *surface = iter->data;
|
||||
|
||||
if (GDK_SURFACE_IS_MAPPED (GDK_SURFACE (surface)) &&
|
||||
([surface->window styleMask] & NSWindowStyleMaskMiniaturizable) == 0)
|
||||
{
|
||||
[surface->window showAndMakeKey:YES];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_macos_display_surface_resigned_key (GdkMacosDisplay *self,
|
||||
GdkMacosSurface *surface)
|
||||
@@ -512,7 +474,25 @@ _gdk_macos_display_surface_resigned_key (GdkMacosDisplay *self,
|
||||
_gdk_display_get_next_serial (GDK_DISPLAY (self)));
|
||||
}
|
||||
|
||||
/* For each parent surface, we want them to look like they
|
||||
* are also still focused, so ensure they have that same
|
||||
* state associated with them.
|
||||
*/
|
||||
if (GDK_IS_POPUP (surface))
|
||||
{
|
||||
for (GdkSurface *parent = GDK_SURFACE (surface)->parent;
|
||||
parent != NULL;
|
||||
parent = parent->parent)
|
||||
{
|
||||
if (GDK_IS_TOPLEVEL (parent))
|
||||
gdk_synthesize_surface_state (parent, GDK_TOPLEVEL_STATE_FOCUSED, 0);
|
||||
}
|
||||
}
|
||||
|
||||
_gdk_macos_display_clear_sorting (self);
|
||||
|
||||
if (self->select_key_in_idle == 0)
|
||||
self->select_key_in_idle = g_idle_add (select_key_in_idle_cb, self);
|
||||
}
|
||||
|
||||
/* Raises a transient window.
|
||||
@@ -551,8 +531,6 @@ void
|
||||
_gdk_macos_display_surface_resigned_main (GdkMacosDisplay *self,
|
||||
GdkMacosSurface *surface)
|
||||
{
|
||||
GdkMacosSurface *new_surface = NULL;
|
||||
|
||||
g_return_if_fail (GDK_IS_MACOS_DISPLAY (self));
|
||||
g_return_if_fail (GDK_IS_MACOS_SURFACE (surface));
|
||||
|
||||
@@ -560,40 +538,6 @@ _gdk_macos_display_surface_resigned_main (GdkMacosDisplay *self,
|
||||
g_queue_unlink (&self->main_surfaces, &surface->main);
|
||||
|
||||
_gdk_macos_display_clear_sorting (self);
|
||||
|
||||
if (GDK_SURFACE (surface)->transient_for &&
|
||||
gdk_surface_get_mapped (GDK_SURFACE (surface)->transient_for))
|
||||
{
|
||||
new_surface = GDK_MACOS_SURFACE (GDK_SURFACE (surface)->transient_for);
|
||||
}
|
||||
else
|
||||
{
|
||||
const GList *surfaces = _gdk_macos_display_get_surfaces (self);
|
||||
|
||||
for (const GList *iter = surfaces; iter; iter = iter->next)
|
||||
{
|
||||
GdkMacosSurface *item = iter->data;
|
||||
|
||||
g_assert (GDK_IS_MACOS_SURFACE (item));
|
||||
|
||||
if (item == surface)
|
||||
continue;
|
||||
|
||||
if (GDK_SURFACE_IS_MAPPED (GDK_SURFACE (item)))
|
||||
{
|
||||
new_surface = item;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (new_surface != NULL)
|
||||
{
|
||||
NSWindow *nswindow = _gdk_macos_surface_get_native (new_surface);
|
||||
[nswindow makeKeyAndOrderFront:nswindow];
|
||||
}
|
||||
|
||||
_gdk_macos_display_clear_sorting (self);
|
||||
}
|
||||
|
||||
static GdkSurface *
|
||||
@@ -654,20 +598,12 @@ gdk_macos_display_finalize (GObject *object)
|
||||
{
|
||||
GdkMacosDisplay *self = (GdkMacosDisplay *)object;
|
||||
|
||||
CFNotificationCenterRemoveObserver (CFNotificationCenterGetDistributedCenter (),
|
||||
self,
|
||||
CFSTR ("NSApplicationDidChangeScreenParametersNotification"),
|
||||
NULL);
|
||||
|
||||
CFNotificationCenterRemoveObserver (CFNotificationCenterGetDistributedCenter (),
|
||||
self,
|
||||
CFSTR ("NSUserDefaultsDidChangeNotification"),
|
||||
NULL);
|
||||
_gdk_macos_display_feedback_destroy (self);
|
||||
|
||||
g_clear_handle_id (&self->select_key_in_idle, g_source_remove);
|
||||
g_clear_pointer (&self->active_drags, g_hash_table_unref);
|
||||
g_clear_pointer (&self->active_drops, g_hash_table_unref);
|
||||
g_clear_object (&GDK_DISPLAY (self)->clipboard);
|
||||
g_clear_pointer (&self->frame_source, g_source_unref);
|
||||
g_clear_object (&self->monitors);
|
||||
g_clear_pointer (&self->name, g_free);
|
||||
|
||||
@@ -726,7 +662,8 @@ _gdk_macos_display_open (const char *display_name)
|
||||
if (self != NULL)
|
||||
return NULL;
|
||||
|
||||
GDK_NOTE (MISC, g_message ("opening display %s", display_name ? display_name : ""));
|
||||
display_name = display_name ? display_name : "";
|
||||
GDK_NOTE (MISC, g_message ("opening display %s", display_name));
|
||||
|
||||
/* Make the current process a foreground application, i.e. an app
|
||||
* with a user interface, in case we're not running from a .app bundle
|
||||
@@ -741,24 +678,10 @@ _gdk_macos_display_open (const char *display_name)
|
||||
|
||||
gdk_macos_display_load_seat (self);
|
||||
gdk_macos_display_load_clipboard (self);
|
||||
|
||||
/* Load CVDisplayLink before monitors to access refresh rates */
|
||||
gdk_macos_display_load_display_link (self);
|
||||
_gdk_macos_display_reload_monitors (self);
|
||||
|
||||
CFNotificationCenterAddObserver (CFNotificationCenterGetLocalCenter (),
|
||||
self,
|
||||
gdk_macos_display_monitors_changed_cb,
|
||||
CFSTR ("NSApplicationDidChangeScreenParametersNotification"),
|
||||
NULL,
|
||||
CFNotificationSuspensionBehaviorDeliverImmediately);
|
||||
|
||||
CFNotificationCenterAddObserver (CFNotificationCenterGetDistributedCenter (),
|
||||
self,
|
||||
gdk_macos_display_user_defaults_changed_cb,
|
||||
CFSTR ("NSUserDefaultsDidChangeNotification"),
|
||||
NULL,
|
||||
CFNotificationSuspensionBehaviorDeliverImmediately);
|
||||
/* Initialize feedback from display server */
|
||||
_gdk_macos_display_feedback_init (self);
|
||||
|
||||
if (event_source == NULL)
|
||||
{
|
||||
@@ -770,6 +693,8 @@ _gdk_macos_display_open (const char *display_name)
|
||||
|
||||
gdk_display_emit_opened (GDK_DISPLAY (self));
|
||||
|
||||
[NSApp activateIgnoringOtherApps:YES];
|
||||
|
||||
return GDK_DISPLAY (self);
|
||||
}
|
||||
|
||||
@@ -810,6 +735,7 @@ _gdk_macos_display_get_monitor_at_coords (GdkMacosDisplay *self,
|
||||
int x,
|
||||
int y)
|
||||
{
|
||||
GdkMacosMonitor *best_match = NULL;
|
||||
guint n_monitors;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_MACOS_DISPLAY (self), NULL);
|
||||
@@ -819,12 +745,25 @@ _gdk_macos_display_get_monitor_at_coords (GdkMacosDisplay *self,
|
||||
for (guint i = 0; i < n_monitors; i++)
|
||||
{
|
||||
GdkMacosMonitor *monitor = get_monitor (self, i);
|
||||
const GdkRectangle *geom = &GDK_MONITOR (monitor)->geometry;
|
||||
|
||||
if (gdk_rectangle_contains_point (&GDK_MONITOR (monitor)->geometry, x, y))
|
||||
return GDK_MONITOR (monitor);
|
||||
if (x >= geom->x &&
|
||||
y >= geom->y &&
|
||||
x <= (geom->x + geom->width) &&
|
||||
y <= (geom->y + geom->height))
|
||||
{
|
||||
if (x <= geom->x + geom->width && y < geom->y + geom->height)
|
||||
return GDK_MONITOR (monitor);
|
||||
|
||||
/* Not an exact match as we're on a boundary, but there is
|
||||
* a good chance another monitor doesn't exist there so we
|
||||
* would want to still treat this as the best monitor.
|
||||
*/
|
||||
best_match = monitor;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return GDK_MONITOR (best_match);
|
||||
}
|
||||
|
||||
GdkMonitor *
|
||||
@@ -949,6 +888,14 @@ _gdk_macos_display_get_surface_at_coords (GdkMacosDisplay *self,
|
||||
*surface_x = x - GDK_MACOS_SURFACE (surface)->root_x;
|
||||
*surface_y = y - GDK_MACOS_SURFACE (surface)->root_y;
|
||||
|
||||
/* One last check to make sure that the x,y is within the input
|
||||
* region of the window. Otherwise we might send the event to the
|
||||
* wrong window because of window shadow.
|
||||
*/
|
||||
if (surface->input_region != NULL &&
|
||||
!cairo_region_contains_point (surface->input_region, *surface_x, *surface_y))
|
||||
continue;
|
||||
|
||||
return GDK_MACOS_SURFACE (surface);
|
||||
}
|
||||
}
|
||||
@@ -978,38 +925,6 @@ _gdk_macos_display_get_surface_at_display_coords (GdkMacosDisplay *self,
|
||||
return _gdk_macos_display_get_surface_at_coords (self, x_gdk, y_gdk, surface_x, surface_y);
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_macos_display_add_frame_callback (GdkMacosDisplay *self,
|
||||
GdkMacosSurface *surface)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_MACOS_DISPLAY (self));
|
||||
g_return_if_fail (GDK_IS_MACOS_SURFACE (surface));
|
||||
|
||||
if (!queue_contains (&self->awaiting_frames, &surface->frame))
|
||||
{
|
||||
g_queue_push_tail_link (&self->awaiting_frames, &surface->frame);
|
||||
|
||||
if (self->awaiting_frames.length == 1)
|
||||
gdk_display_link_source_unpause ((GdkDisplayLinkSource *)self->frame_source);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_macos_display_remove_frame_callback (GdkMacosDisplay *self,
|
||||
GdkMacosSurface *surface)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_MACOS_DISPLAY (self));
|
||||
g_return_if_fail (GDK_IS_MACOS_SURFACE (surface));
|
||||
|
||||
if (queue_contains (&self->awaiting_frames, &surface->frame))
|
||||
{
|
||||
g_queue_unlink (&self->awaiting_frames, &surface->frame);
|
||||
|
||||
if (self->awaiting_frames.length == 0)
|
||||
gdk_display_link_source_pause ((GdkDisplayLinkSource *)self->frame_source);
|
||||
}
|
||||
}
|
||||
|
||||
NSWindow *
|
||||
_gdk_macos_display_find_native_under_pointer (GdkMacosDisplay *self,
|
||||
int *x,
|
||||
@@ -1029,17 +944,6 @@ _gdk_macos_display_find_native_under_pointer (GdkMacosDisplay *self,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
_gdk_macos_display_get_nominal_refresh_rate (GdkMacosDisplay *self)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_MACOS_DISPLAY (self), 60 * 1000);
|
||||
|
||||
if (self->frame_source == NULL)
|
||||
return 60 * 1000;
|
||||
|
||||
return ((GdkDisplayLinkSource *)self->frame_source)->refresh_rate;
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_macos_display_clear_sorting (GdkMacosDisplay *self)
|
||||
{
|
||||
@@ -1061,11 +965,16 @@ _gdk_macos_display_get_surfaces (GdkMacosDisplay *self)
|
||||
NSArray *array = [NSApp orderedWindows];
|
||||
GQueue sorted = G_QUEUE_INIT;
|
||||
|
||||
self->key_window_is_foregin = FALSE;
|
||||
|
||||
for (id obj in array)
|
||||
{
|
||||
NSWindow *nswindow = (NSWindow *)obj;
|
||||
GdkMacosSurface *surface;
|
||||
|
||||
if ([nswindow isKeyWindow])
|
||||
self->key_window_is_foregin = !GDK_IS_MACOS_WINDOW (nswindow);
|
||||
|
||||
if (!GDK_IS_MACOS_WINDOW (nswindow))
|
||||
continue;
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user