Compare commits
1020 Commits
lrn/alignf
...
wip/ebassi
Author | SHA1 | Date | |
---|---|---|---|
|
258233efa9 | ||
|
59bf76dce1 | ||
|
44a2a49f31 | ||
|
69bc42f444 | ||
|
269535c844 | ||
|
c7f773f3e3 | ||
|
c6da0c9a7a | ||
|
d098cd5865 | ||
|
4dc8ab58a3 | ||
|
5680393f9d | ||
|
aadcec3d1e | ||
|
5fd936beef | ||
|
563b80d434 | ||
|
f4f0f0e6a0 | ||
|
ba9b0c6f7d | ||
|
3ce3de98da | ||
|
1cd934e105 | ||
|
dc1d3824a2 | ||
|
927e49ed86 | ||
|
d55fc8b7b1 | ||
|
e72d0a9118 | ||
|
8b14c8d0a8 | ||
|
913b4fcc49 | ||
|
fb7d033953 | ||
|
cfa440bbae | ||
|
7ac9fe3b60 | ||
|
b0a8b7da63 | ||
|
b2ff6e91cd | ||
|
b4d906c464 | ||
|
ae03caacc4 | ||
|
ec22646210 | ||
|
ba1644cba1 | ||
|
d11bc68b27 | ||
|
5720e406b9 | ||
|
b3f8f358b5 | ||
|
e458ea2f3d | ||
|
b6d8d3975e | ||
|
5e96129be1 | ||
|
0ef7d07880 | ||
|
545e95bb5c | ||
|
ca76675a69 | ||
|
16d4ce4d03 | ||
|
58e273d056 | ||
|
1c14285dee | ||
|
cd69570e78 | ||
|
52b9e4703b | ||
|
d7193eaf8b | ||
|
b52dea7a10 | ||
|
7bb5888272 | ||
|
4404afc9f3 | ||
|
dadac6a9e1 | ||
|
210a06174d | ||
|
f9a5a474f0 | ||
|
c51f1fda28 | ||
|
ea3d0c0f01 | ||
|
2c1198f6c2 | ||
|
9d3120cc1e | ||
|
66d3aa8101 | ||
|
0530637fef | ||
|
3d6bdb9af3 | ||
|
7e7c90961c | ||
|
3da9280a8a | ||
|
ed17a8ddd7 | ||
|
cd7e70680c | ||
|
a80007ac12 | ||
|
dc68d04c32 | ||
|
bd95e16372 | ||
|
c1e1e2da80 | ||
|
ea8f1469c1 | ||
|
1d3aa9207c | ||
|
b4f2a3416e | ||
|
3b46e2a558 | ||
|
480a04131c | ||
|
171a710a23 | ||
|
4f532a414c | ||
|
3f567781dd | ||
|
0397c8b628 | ||
|
3939824d11 | ||
|
d7cafca118 | ||
|
d10709c917 | ||
|
e9d4823c57 | ||
|
06d764d046 | ||
|
325badc3eb | ||
|
c665a1d5a5 | ||
|
c7f1a275ac | ||
|
a52989842e | ||
|
1df276f263 | ||
|
615f10f7c8 | ||
|
38cba6895a | ||
|
e95e045898 | ||
|
1b730dcf31 | ||
|
beb9ee6d4a | ||
|
8ce6d03c7b | ||
|
904202a636 | ||
|
7a0b6a3639 | ||
|
b465e04ae2 | ||
|
f67627875f | ||
|
8912dc226c | ||
|
12ac9f351e | ||
|
c4b4e90f98 | ||
|
fcf28ded42 | ||
|
1e69d248cb | ||
|
c49b29fa53 | ||
|
024220aee8 | ||
|
1423265610 | ||
|
89c48a08a0 | ||
|
c30968861f | ||
|
a8ac6f833c | ||
|
271acaff53 | ||
|
c35e0cba39 | ||
|
65240967e4 | ||
|
a99bd2a422 | ||
|
3ec2d5fa38 | ||
|
a0b5b39bbd | ||
|
ab52862a5d | ||
|
a350192ea2 | ||
|
cb0d8d6d90 | ||
|
86ad3e8f2a | ||
|
8f29a0633b | ||
|
7601bca758 | ||
|
3bbfff9280 | ||
|
5b049364dc | ||
|
7997bdc5d7 | ||
|
04aebda1e9 | ||
|
77792b6475 | ||
|
5612e84551 | ||
|
462193ae26 | ||
|
80a90a084e | ||
|
2f29cb9e6f | ||
|
67fdfca3ba | ||
|
284d909347 | ||
|
43ef4d7b53 | ||
|
3ce45508e1 | ||
|
57efdcfbbe | ||
|
df817bd118 | ||
|
82a1d4f280 | ||
|
80f2660838 | ||
|
edd4d2918a | ||
|
320d272ec8 | ||
|
72d09d22e9 | ||
|
a2a4603329 | ||
|
8de1ba2cc4 | ||
|
2644da106b | ||
|
4860410c4a | ||
|
4b3a94f382 | ||
|
d67dacedba | ||
|
e1feb1b712 | ||
|
e8670c89ae | ||
|
b4f918904c | ||
|
aead150ce2 | ||
|
fd47e57e4b | ||
|
1e129c1dd2 | ||
|
e0a7d28339 | ||
|
ad93806005 | ||
|
2b95a5daee | ||
|
0681c5d5bc | ||
|
b19926c079 | ||
|
692ed4f994 | ||
|
ad759307f8 | ||
|
fb6adaaa62 | ||
|
58a4ae94e9 | ||
|
9df9087a13 | ||
|
f8df527c68 | ||
|
71512cf9ad | ||
|
79cc8fb261 | ||
|
2831dbb110 | ||
|
933acb3682 | ||
|
574ebafa46 | ||
|
74dd05b45e | ||
|
3eb2cef421 | ||
|
94745241c2 | ||
|
538491efa1 | ||
|
6f8c4f873d | ||
|
7a4e9fa4d3 | ||
|
f3c704b82e | ||
|
a6a69dd567 | ||
|
8921c868a5 | ||
|
3f8598baa4 | ||
|
b5fd7b3211 | ||
|
e9fe9410e0 | ||
|
904fd5f1fc | ||
|
f598836d6c | ||
|
5907ff694f | ||
|
7c020bfaaa | ||
|
2bd02d9185 | ||
|
c0cf592336 | ||
|
12378f0afa | ||
|
5ea211bbb1 | ||
|
c17c18f1ae | ||
|
dbde7b68c0 | ||
|
95f06f6e75 | ||
|
a26edd59d1 | ||
|
dcd21e12cd | ||
|
e5efc84eda | ||
|
8035969860 | ||
|
e5f9bf2e9b | ||
|
0be4d31217 | ||
|
eebb849760 | ||
|
f92745aacf | ||
|
7aee30bfc2 | ||
|
ef751bc809 | ||
|
fe49f83982 | ||
|
059d9376da | ||
|
6466e53bfc | ||
|
b7963a06ab | ||
|
eeeefb40c7 | ||
|
97d8676b40 | ||
|
6e28d004ae | ||
|
8d7bf3ad0c | ||
|
d76a0feef6 | ||
|
08a07d4ae5 | ||
|
b42d99b37e | ||
|
ea487b2233 | ||
|
40ae5c1319 | ||
|
8c9c3e4426 | ||
|
d0f4fcb6fd | ||
|
4142d0a69a | ||
|
b061821f24 | ||
|
e0833e492c | ||
|
55faaf1aa1 | ||
|
7aa02b9e95 | ||
|
c65c6ba11f | ||
|
359d874ddb | ||
|
ade171a2ed | ||
|
1f1306a53b | ||
|
ce3d5fcb0a | ||
|
28bd56454d | ||
|
75deff035b | ||
|
87ee7e31a4 | ||
|
5a3ecb9703 | ||
|
e656f66720 | ||
|
0d47a6c970 | ||
|
39f8e1e137 | ||
|
d7c2e5844b | ||
|
edc4b2f7d0 | ||
|
b3ba2961d2 | ||
|
c2c1acc73e | ||
|
c44728282c | ||
|
85a002bf9f | ||
|
6eba544ad4 | ||
|
f610fbfc0e | ||
|
1e2d11cc62 | ||
|
f1e24ca30a | ||
|
1787f04097 | ||
|
671f69c6ca | ||
|
7b51de6bbd | ||
|
45b909f2c5 | ||
|
0b4ee06f8e | ||
|
797739198f | ||
|
0c017ff109 | ||
|
aad3686726 | ||
|
fe7a2635d0 | ||
|
2834b38d2c | ||
|
29563a33ba | ||
|
5936d7f8f2 | ||
|
481a78eee7 | ||
|
ac4134c298 | ||
|
145659af93 | ||
|
31b8e0f109 | ||
|
18199a3cef | ||
|
3194c39471 | ||
|
9d51a8f53a | ||
|
c37c86a9bf | ||
|
b4b30b4951 | ||
|
54830a2af3 | ||
|
9946dd2ab7 | ||
|
5028cb35bc | ||
|
48b569eae0 | ||
|
8099669466 | ||
|
1c465604d5 | ||
|
833442e1e2 | ||
|
1e39f999e3 | ||
|
e31187e1cf | ||
|
e457a7823c | ||
|
88c77eb7be | ||
|
f57d337fac | ||
|
60b0f48fbc | ||
|
4c6d60ce2b | ||
|
b4acf81609 | ||
|
62871400b1 | ||
|
c4b3337569 | ||
|
45e6e0cd04 | ||
|
98dd53c2c3 | ||
|
ad7eaf2bb8 | ||
|
ef82f1799f | ||
|
1729da8a3e | ||
|
a3ac3b61ef | ||
|
532a48aa92 | ||
|
f3674688bf | ||
|
dd6aa7b870 | ||
|
21d0e30903 | ||
|
3c73f70dae | ||
|
65fbd0af4e | ||
|
55b32c8a8f | ||
|
bb0e964f56 | ||
|
0f4a6bfbf8 | ||
|
4e884b6056 | ||
|
f252bbc02c | ||
|
9cbd3ac017 | ||
|
4bae7fb0fd | ||
|
b98f5a0823 | ||
|
00c29e1fbe | ||
|
de3e5be235 | ||
|
ae3e6d1949 | ||
|
114efa83c6 | ||
|
d15df65a9d | ||
|
e0a1311e5b | ||
|
48e88c6ea4 | ||
|
50c63fc39a | ||
|
1ca5b41571 | ||
|
cebf5ed46c | ||
|
1ca906008e | ||
|
dd69c4e0f2 | ||
|
cbb0d7ba69 | ||
|
cbdb744c40 | ||
|
10fef2fbb4 | ||
|
8e2fb9c2be | ||
|
f48ed12e78 | ||
|
66c0336ead | ||
|
0657a53940 | ||
|
eecd5823d0 | ||
|
99b769706c | ||
|
39843ebb3f | ||
|
52bcf7fd46 | ||
|
43997fb550 | ||
|
c59669d376 | ||
|
ac97d2be0c | ||
|
e9a67cc6d0 | ||
|
44655932c4 | ||
|
278f9a9eda | ||
|
a28c7e8839 | ||
|
77c8d2df00 | ||
|
aeca5858d8 | ||
|
89b96a864e | ||
|
26302cada5 | ||
|
42d064c62f | ||
|
273189fc1a | ||
|
d51abaea2e | ||
|
248708c282 | ||
|
0e2748006a | ||
|
e89bd7dfa2 | ||
|
2f6e998a27 | ||
|
7b7296410e | ||
|
d90e2733ea | ||
|
19bf502fde | ||
|
2b8e30a8ed | ||
|
4ad8dcebd8 | ||
|
a966b90e51 | ||
|
5b2a451e75 | ||
|
8105bde835 | ||
|
2329b62c14 | ||
|
1e1bed056f | ||
|
a0d83bdfa7 | ||
|
fa8190328d | ||
|
d19cba429d | ||
|
be2609a271 | ||
|
5bf009a203 | ||
|
93a89a371e | ||
|
60cb315be6 | ||
|
73728814b0 | ||
|
d4098099dd | ||
|
57ef793e6d | ||
|
58cdd5139e | ||
|
2c84049769 | ||
|
29c700d1c7 | ||
|
0d7c987b1a | ||
|
03679d4342 | ||
|
1a4b60fb36 | ||
|
05b2ae0f31 | ||
|
f211d71f74 | ||
|
691ab421fb | ||
|
9e3e9e83ef | ||
|
a0056d5ca8 | ||
|
f3e6d00db1 | ||
|
e55df03fe2 | ||
|
c8a13a2d8a | ||
|
6971e2923d | ||
|
231b76bdd1 | ||
|
57ba4048de | ||
|
545c5f18b2 | ||
|
5571217218 | ||
|
b92c328425 | ||
|
8bdcff3320 | ||
|
9ffd88012d | ||
|
563fb97f90 | ||
|
ee5708f543 | ||
|
b7bf04fabd | ||
|
b94b8ac38d | ||
|
afd69db678 | ||
|
f3834138f7 | ||
|
64b7c123cc | ||
|
fcb780ee13 | ||
|
65b795b861 | ||
|
64d97b233b | ||
|
db8474e5b1 | ||
|
5e8983883e | ||
|
59006e2e03 | ||
|
b6acc31d44 | ||
|
6d0fe46cba | ||
|
05e752e096 | ||
|
2237009983 | ||
|
417ac4ab43 | ||
|
4495eaae84 | ||
|
aba76fe8e9 | ||
|
867042f88f | ||
|
32ec7dec61 | ||
|
d6161e09cd | ||
|
4b5fb5ec79 | ||
|
4f70f72349 | ||
|
dd94129e27 | ||
|
63e5b827ed | ||
|
573c63973a | ||
|
1ce960c85b | ||
|
d7a5dcba0b | ||
|
a4b1c6b384 | ||
|
0edec9bcae | ||
|
7d12a843f2 | ||
|
867efe2e33 | ||
|
a121bfa7ec | ||
|
02758cd48d | ||
|
005f932d13 | ||
|
4e8c06eb7a | ||
|
ca9aa23619 | ||
|
ae2c765ffd | ||
|
ab9455ea1b | ||
|
89522e6923 | ||
|
506a4ddad5 | ||
|
272e4a0a9d | ||
|
16deffb48d | ||
|
a60e951941 | ||
|
05306470b0 | ||
|
803a8cf333 | ||
|
3e5746356e | ||
|
c9f1c56776 | ||
|
fc026b95dd | ||
|
2bb97bc136 | ||
|
d4d12171f4 | ||
|
21e484731a | ||
|
b82a32676b | ||
|
d7228ae025 | ||
|
04c02e9aec | ||
|
d6945d81f0 | ||
|
6d6559f982 | ||
|
b271db253f | ||
|
eb9f95e9fa | ||
|
d7a5723d66 | ||
|
72498b9e28 | ||
|
b904fc6ee0 | ||
|
9622ba8a0d | ||
|
3b8d206143 | ||
|
e027fc9272 | ||
|
ba6c5ef201 | ||
|
6a8013735d | ||
|
c3e72c4d7e | ||
|
a6c47cb3ab | ||
|
cc129e564a | ||
|
9fbcbc55d7 | ||
|
00a27c1e28 | ||
|
f5f6597abc | ||
|
fade0afbef | ||
|
0082675de8 | ||
|
ed8e784879 | ||
|
a4790b7eaa | ||
|
ed434519d2 | ||
|
4ed4b4fd6a | ||
|
369cb702e4 | ||
|
d246abd085 | ||
|
911627fa0b | ||
|
ec576088bb | ||
|
ab0b54db76 | ||
|
fb51f8be9a | ||
|
eb22c7c9c3 | ||
|
749ef4d71c | ||
|
f6fae1dd09 | ||
|
f21abba82f | ||
|
bf222a9292 | ||
|
96e465b6d9 | ||
|
016de68ceb | ||
|
d2178bcb94 | ||
|
f40eb8a1fe | ||
|
9e0f43e8cb | ||
|
3e4d7250a0 | ||
|
4ebd14c045 | ||
|
ca39b35e2f | ||
|
a32fb5b849 | ||
|
eed19c9269 | ||
|
e2d691bdb1 | ||
|
a73f961e65 | ||
|
a7aed5af4b | ||
|
220a51e7cb | ||
|
6df28420d7 | ||
|
081b45399f | ||
|
0874a54708 | ||
|
cd40ec2200 | ||
|
62b887e064 | ||
|
ce9ce8a5bc | ||
|
2322f38bf9 | ||
|
dcb6c9b4cf | ||
|
afdeffd820 | ||
|
10439aaefe | ||
|
d64467b334 | ||
|
099b967885 | ||
|
d13cd9cb67 | ||
|
79b87cc543 | ||
|
3c2aceba63 | ||
|
a01feae15b | ||
|
b4d4f73d9f | ||
|
c1de6219ed | ||
|
b364827a5b | ||
|
bbe362d015 | ||
|
08f32c6560 | ||
|
b3c8c8e592 | ||
|
ed36933232 | ||
|
a90fc088f2 | ||
|
ff6c4ed07e | ||
|
201f635559 | ||
|
59077e4843 | ||
|
3e6a473082 | ||
|
580d96620e | ||
|
61f50f2410 | ||
|
61b2f3c996 | ||
|
ab30850aad | ||
|
f5e04b59e9 | ||
|
c67bcf09b9 | ||
|
5eba0bc932 | ||
|
ff2ba52bc6 | ||
|
a822d6fce9 | ||
|
b749fe4270 | ||
|
933cb857cf | ||
|
dde535bbdf | ||
|
71b36db88d | ||
|
b5576397f7 | ||
|
4e86858405 | ||
|
14b21d78db | ||
|
35829a7272 | ||
|
0eb60fb03e | ||
|
94162197a1 | ||
|
877fffdd5e | ||
|
8669d31c30 | ||
|
e76d17a786 | ||
|
5ab90f1a80 | ||
|
5b1fd111d1 | ||
|
5596feae9b | ||
|
8fb8303ba0 | ||
|
06e4c3c991 | ||
|
f25f3b3c47 | ||
|
72ec8963d7 | ||
|
50d5666db0 | ||
|
e06044530f | ||
|
7ce7e5503f | ||
|
0ba307995d | ||
|
ce7956cd50 | ||
|
d29b378fa0 | ||
|
1129febd7d | ||
|
47928b9e14 | ||
|
01f17836ac | ||
|
7e919aaaa5 | ||
|
03a6420c37 | ||
|
375fbd4e47 | ||
|
813957a92f | ||
|
36ed4c2a29 | ||
|
8e78b53378 | ||
|
76ed6cf9d8 | ||
|
a8c6f222ed | ||
|
c5afea0c6b | ||
|
efa42a6932 | ||
|
5d1b2f627c | ||
|
8f6f980e49 | ||
|
25b3b90920 | ||
|
71762d3b28 | ||
|
f15224926a | ||
|
1570c41efa | ||
|
5e0f2d7d20 | ||
|
88743ab975 | ||
|
6f15447633 | ||
|
85f6995511 | ||
|
4d59a00074 | ||
|
2dbb1509d8 | ||
|
101c927c40 | ||
|
6d3eb18578 | ||
|
d301695ba1 | ||
|
ca8008e2c9 | ||
|
0d7b4ecb14 | ||
|
9a541d9b91 | ||
|
cdfde6673d | ||
|
7ef95734af | ||
|
de17e3b525 | ||
|
f8a971a7df | ||
|
e1a7629a85 | ||
|
7d3b8b0d09 | ||
|
fff2fabd7a | ||
|
73b45ec77e | ||
|
8f95a5980e | ||
|
87d33470ed | ||
|
002e48c469 | ||
|
f33549da91 | ||
|
f3f32b47cc | ||
|
2c5f2a2bcb | ||
|
b6d990af25 | ||
|
16171a232a | ||
|
031b5cad46 | ||
|
984274497d | ||
|
0cc0714312 | ||
|
766e2b1e63 | ||
|
c8be597b7f | ||
|
4497ac7d75 | ||
|
af21583d4d | ||
|
791da76ae1 | ||
|
d398c00d20 | ||
|
cb247276f5 | ||
|
c6141dffd2 | ||
|
755d8f8332 | ||
|
32de29bb68 | ||
|
540cb58169 | ||
|
a1a6e6a36a | ||
|
798ad9f62a | ||
|
ad6255a841 | ||
|
6adaf7c33d | ||
|
95a4eff6ba | ||
|
9675c99043 | ||
|
76d0e1e398 | ||
|
14408b7485 | ||
|
2a11baf6ea | ||
|
51d40ca023 | ||
|
5d9d73b090 | ||
|
5f7e093168 | ||
|
0f70e6d70a | ||
|
259be23ff2 | ||
|
337eedb513 | ||
|
185354555c | ||
|
29905d1ce6 | ||
|
73dd73c859 | ||
|
cfb0df14cc | ||
|
b343abfa51 | ||
|
5df4d27752 | ||
|
bbf5d142b3 | ||
|
1fbbaef49e | ||
|
d88268c142 | ||
|
49ae68c2c7 | ||
|
1d72e3e193 | ||
|
77c3ef48cf | ||
|
20deda2bd6 | ||
|
447b166ed3 | ||
|
1b230324ba | ||
|
806c659efe | ||
|
51873ebe37 | ||
|
827219e214 | ||
|
5c9b25c66e | ||
|
37e4ae2fbd | ||
|
14f86ae24d | ||
|
849ffebc21 | ||
|
7dabc2a42c | ||
|
bef8a3a0e9 | ||
|
31d2638088 | ||
|
40019517cf | ||
|
7a8f5ca970 | ||
|
4063c3dc31 | ||
|
96d0368290 | ||
|
9a0ec5b1e0 | ||
|
7b5a0a829a | ||
|
1030d9e5b1 | ||
|
0750b4fd28 | ||
|
1d4ce5a544 | ||
|
4b2d63167e | ||
|
6fe0a8c6b3 | ||
|
04eb7eef29 | ||
|
480a2c2770 | ||
|
f699fff6e0 | ||
|
4bc145549d | ||
|
cf7fa931d3 | ||
|
392b4d9ac5 | ||
|
3f126c7fc8 | ||
|
960717b273 | ||
|
5386cf89f2 | ||
|
b7d948af69 | ||
|
446b2e25d3 | ||
|
17b1e7bae9 | ||
|
9dc679370c | ||
|
033cf4bfb7 | ||
|
bf5f27c6d5 | ||
|
7a1073c3ae | ||
|
e2fd33f78a | ||
|
89f25d1484 | ||
|
3c8b3cbf41 | ||
|
410d4bca83 | ||
|
168523264c | ||
|
435f143e2e | ||
|
98ccb67277 | ||
|
2d83bb1b91 | ||
|
298b6ee81a | ||
|
5ce3520a2a | ||
|
9cc3e2c8ef | ||
|
034f89b17f | ||
|
1ea09a327a | ||
|
bc2f484ae9 | ||
|
228f813c43 | ||
|
17386b5cf7 | ||
|
288086b899 | ||
|
d148f26658 | ||
|
7ca6440f4d | ||
|
1172810768 | ||
|
9c827cbff4 | ||
|
da3aaf39b9 | ||
|
a8926c9d87 | ||
|
443f8ddf6b | ||
|
6a7de806dd | ||
|
19873e549a | ||
|
05ca6bc189 | ||
|
cbb1e74bb5 | ||
|
6afb6bb9d2 | ||
|
60afd056e0 | ||
|
4456b06853 | ||
|
2f72353e0e | ||
|
88af7b44aa | ||
|
a7cd1918a8 | ||
|
bcfd1bbd24 | ||
|
1a5e60be7c | ||
|
3ce3867403 | ||
|
00a61f92b6 | ||
|
986daa8225 | ||
|
e72ca43a32 | ||
|
f432c937cc | ||
|
1dd15b5237 | ||
|
5cdbbc6e61 | ||
|
0e2ac0ebf2 | ||
|
c73cb2c154 | ||
|
a756caa106 | ||
|
da22ba3b86 | ||
|
7a0a92f2b6 | ||
|
d927c3bee0 | ||
|
59c2efbcd6 | ||
|
94af080fb6 | ||
|
40841ec3be | ||
|
f69bb2fb2b | ||
|
db0b9f61ae | ||
|
63ab523146 | ||
|
b94c3166bf | ||
|
7030e08f9c | ||
|
2cc6a3ee5c | ||
|
3dd188fe7e | ||
|
d41603d82a | ||
|
f7aff03c72 | ||
|
a0b8e32462 | ||
|
50f76eb8cc | ||
|
9959ea98cd | ||
|
8ca3ac1970 | ||
|
27ba2411f0 | ||
|
a6920855ea | ||
|
c85e2401fa | ||
|
6fdcafc94a | ||
|
9bab218314 | ||
|
2854635850 | ||
|
a976aa9740 | ||
|
074eb2a19d | ||
|
96812450fa | ||
|
93c688cd93 | ||
|
53afc4a9d9 | ||
|
c96077590b | ||
|
6e47d0bf4a | ||
|
50b79ae0ab | ||
|
6b4709ea3c | ||
|
f3a83abb54 | ||
|
33166b7357 | ||
|
bb31ce1168 | ||
|
dbf32933bf | ||
|
af8fe182c8 | ||
|
731f0d4d01 | ||
|
e42373df89 | ||
|
da8050979e | ||
|
4dd1ff6dd2 | ||
|
8c403c43f0 | ||
|
2feb5c93ca | ||
|
9924a92e70 | ||
|
6c8988e445 | ||
|
9fb3b84253 | ||
|
3439862634 | ||
|
93c5455796 | ||
|
e665667bff | ||
|
3ca59b8701 | ||
|
fba0b359d4 | ||
|
e1b6496af7 | ||
|
14620423e8 | ||
|
55a1f8ccfd | ||
|
19afe454df | ||
|
7d842cb7fc | ||
|
3137d326c5 | ||
|
12464731f1 | ||
|
269a9d8528 | ||
|
c892d2767a | ||
|
c8e082f296 | ||
|
51981d562b | ||
|
51b77a425a | ||
|
ae3163b5e0 | ||
|
af93646b3e | ||
|
64f5afe608 | ||
|
fb98f939a5 | ||
|
7733f646d6 | ||
|
fd69f1cd79 | ||
|
ca94ff10ce | ||
|
9c3de51412 | ||
|
d9dcfffce3 | ||
|
dfd1372a9b | ||
|
f3c670ab0c | ||
|
8aa4b5150e | ||
|
ecaa16c367 | ||
|
2f8284a386 | ||
|
73cad1e784 | ||
|
0abd01e288 | ||
|
b80942ec88 | ||
|
165dab8265 | ||
|
73d736d800 | ||
|
88b4076fe5 | ||
|
36396093e6 | ||
|
faba0f0145 | ||
|
8755d884f3 | ||
|
010f4e90e3 | ||
|
0c76264953 | ||
|
d13843ee2a | ||
|
7869ffbb49 | ||
|
2f149c378a | ||
|
04367acf9b | ||
|
1a2052a40e | ||
|
e079fad1d5 | ||
|
bada3dbac6 | ||
|
9178423844 | ||
|
9df5171962 | ||
|
b3e91b7111 | ||
|
ffd89d29df | ||
|
686116ba61 | ||
|
7fa3183d7f | ||
|
176fd2fab3 | ||
|
419ee6a451 | ||
|
2c0d2d332f | ||
|
5f8fea08ff | ||
|
f92ec7ce41 | ||
|
ca08cf94d3 | ||
|
3d5dc16d63 | ||
|
7bfc3a5c74 | ||
|
a5414bc404 | ||
|
1d97b5fd3c | ||
|
aa09b0742e | ||
|
c5586f85fb | ||
|
3eb1b22651 | ||
|
4186a85359 | ||
|
aaf1e4995c | ||
|
e08e15ba51 | ||
|
7048362e6e | ||
|
5f0ed088e4 | ||
|
5c46c81067 | ||
|
c6fa3c446c | ||
|
f7ebff6aea | ||
|
8aeced2c91 | ||
|
e8fefd92c5 | ||
|
22390adf11 | ||
|
cf9121977f | ||
|
99099a1053 | ||
|
daba1a7eff | ||
|
f26359db13 | ||
|
945b844b7c | ||
|
f33655fa4e | ||
|
ee8ee313c8 | ||
|
33e113d607 | ||
|
a12d26155f | ||
|
cae382c829 | ||
|
0a5086d94f | ||
|
b103650cb0 | ||
|
337e602143 | ||
|
7ce25293b1 | ||
|
cd99f82e0c | ||
|
29fee2e808 | ||
|
417b1d8335 | ||
|
443a64a38e | ||
|
74455ae75c | ||
|
ec096b417c | ||
|
06bba15f62 | ||
|
c48be6ef96 | ||
|
0b1f0984f5 | ||
|
6918fb2e4e | ||
|
3caf8c86c9 | ||
|
8c8dc3aeab | ||
|
4d4ec2dbfb | ||
|
4f979469f1 | ||
|
87532f0ac3 | ||
|
0ace7ad219 | ||
|
a1bcbdd02a | ||
|
8e3bf65b3b | ||
|
de30a74cdf | ||
|
cbbb7604b6 | ||
|
9a91d3739d | ||
|
a2839d157f | ||
|
b3d424c2d7 | ||
|
bf3ea24489 | ||
|
997e8c1ae1 | ||
|
aa1f0cfd4f | ||
|
45a6146ca6 | ||
|
bc63001deb | ||
|
47b47f5835 | ||
|
1b2dccd143 | ||
|
7e09aa3caa | ||
|
6633d4130a | ||
|
a960641ace | ||
|
f982c9c8f8 | ||
|
a1cee7fa65 | ||
|
d0ebdf00f8 | ||
|
dd30a288f2 | ||
|
005781021e | ||
|
14f0a25531 | ||
|
8db379d85b | ||
|
6b65aaab21 | ||
|
905765eed6 | ||
|
e1206763a8 | ||
|
8a08a325be | ||
|
5e159e2ca0 | ||
|
392071b66d | ||
|
8ee4de804c | ||
|
dcf432d7d0 | ||
|
ea9d6f0a95 | ||
|
018a17fb8e | ||
|
895f381fd5 | ||
|
66bd54d14c | ||
|
ff38d38444 | ||
|
af749532fc | ||
|
7afa0badd8 | ||
|
4eb3a9faaa | ||
|
81e1dc9a66 | ||
|
c67fb57881 | ||
|
81171cc0a2 | ||
|
aa4e4dd0c7 | ||
|
7a9afc3a95 | ||
|
114ab8775a | ||
|
657ebd2a78 | ||
|
05bf87cf14 | ||
|
4aedf3d003 | ||
|
b1f384eec2 | ||
|
d02b185a87 | ||
|
6048b69145 | ||
|
4b85b5299a | ||
|
b00609c21c | ||
|
6d7cb2b781 | ||
|
a862ca41c5 | ||
|
314eaf7d10 | ||
|
316bd6a333 | ||
|
5b0a6a52c1 | ||
|
13ae11ee01 | ||
|
a05af1f0f3 | ||
|
b2dc303e5e | ||
|
2e27967814 | ||
|
18c3b725b4 | ||
|
6573d08b08 | ||
|
74a8ffc4a8 | ||
|
ac44353f9b | ||
|
6919d8c532 | ||
|
f247d268d4 | ||
|
841a29837e | ||
|
7554384b2d | ||
|
64313f4a4b | ||
|
34f556fc3e | ||
|
218b39fe01 | ||
|
70c8cfa480 | ||
|
501efeb6b9 | ||
|
a7d8127d59 | ||
|
beb4cb0e37 | ||
|
346ec706f7 | ||
|
d8274856de | ||
|
3756234708 | ||
|
2d6955285c | ||
|
10a0d6252e | ||
|
f8ddc42638 | ||
|
e9a9bb069f | ||
|
df79f02310 | ||
|
bd99ca2f04 | ||
|
889fcf64b6 | ||
|
3fadb536d9 | ||
|
fb0d8eacc3 | ||
|
fffb3161bc | ||
|
3be2cb8f63 | ||
|
8267605ba2 | ||
|
da4d8b7d94 | ||
|
01d4538223 | ||
|
da27627696 | ||
|
85e49a1051 | ||
|
798944cb26 | ||
|
5a319f66af | ||
|
2d7cfdd7ed | ||
|
35417a5a74 | ||
|
fdfbbc8246 | ||
|
b7f9a5419f | ||
|
6cfa799ca1 | ||
|
0db6ee9347 | ||
|
8a1106c639 | ||
|
6e085b3bf1 | ||
|
6bf88d90f3 | ||
|
fb4d76d380 | ||
|
dedc1ee1e5 | ||
|
fe76984e89 | ||
|
f6d70f7225 | ||
|
0b12fd9c1b | ||
|
7f8106f2a9 | ||
|
d3ffaa0236 | ||
|
1b208eb457 | ||
|
1528665662 | ||
|
751c1877b1 | ||
|
66e0060836 | ||
|
b2db7bb95b | ||
|
c5fa657631 | ||
|
bdf3b6f64d | ||
|
6033bc56b4 | ||
|
eefd2d6f10 | ||
|
daf72e2e96 | ||
|
7e98741793 | ||
|
d4693b2dc8 | ||
|
b1f934d3b0 | ||
|
fd4bfd5050 | ||
|
07d6c53346 | ||
|
479c341545 | ||
|
938448e0ef | ||
|
ef3427575f | ||
|
0c57e3131f | ||
|
b22f45b2f6 | ||
|
0d46081645 |
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/subprojects/*/
|
@@ -13,7 +13,7 @@ stages:
|
||||
- subprojects/pango/
|
||||
|
||||
fedora-x86_64:
|
||||
image: registry.gitlab.gnome.org/gnome/gtk/master:v1
|
||||
image: registry.gitlab.gnome.org/gnome/gtk/master:v2
|
||||
stage: build
|
||||
script:
|
||||
- bash -x ./.gitlab-ci/test-docker.sh
|
||||
@@ -44,7 +44,7 @@ msys2-mingw32:
|
||||
<<: *mingw-defaults
|
||||
|
||||
.flatpak-defaults: &flatpak-defaults
|
||||
image: registry.gitlab.com/alatiera/gnome-nightly-oci/gnome-master:latest
|
||||
image: registry.gitlab.gnome.org/gnome/gnome-runtime-images/gnome:master
|
||||
stage: flatpak
|
||||
artifacts:
|
||||
paths:
|
||||
@@ -64,7 +64,7 @@ flatpak:widget-factory:
|
||||
<<: *flatpak-defaults
|
||||
|
||||
pages:
|
||||
image: registry.gitlab.gnome.org/gnome/gtk/master:v1
|
||||
image: registry.gitlab.gnome.org/gnome/gtk/master:v2
|
||||
stage: deploy
|
||||
script:
|
||||
- meson -Ddocumentation=true _build .
|
||||
|
@@ -1,6 +1,7 @@
|
||||
FROM fedora:28
|
||||
FROM fedora:29
|
||||
|
||||
RUN dnf -y install \
|
||||
hicolor-icon-theme \
|
||||
adwaita-icon-theme \
|
||||
atk-devel \
|
||||
at-spi2-atk-devel \
|
||||
@@ -32,6 +33,7 @@ RUN dnf -y install \
|
||||
iso-codes \
|
||||
itstool \
|
||||
json-glib-devel \
|
||||
lcov \
|
||||
libattr-devel \
|
||||
libepoxy-devel \
|
||||
libffi-devel \
|
||||
@@ -68,7 +70,7 @@ RUN dnf -y install \
|
||||
xorg-x11-server-Xvfb \
|
||||
&& dnf clean all
|
||||
|
||||
RUN pip3 install meson
|
||||
RUN pip3 install meson==0.49.0
|
||||
|
||||
ARG HOST_USER_ID=5555
|
||||
ENV HOST_USER_ID ${HOST_USER_ID}
|
||||
|
@@ -2,7 +2,7 @@
|
||||
|
||||
set -e
|
||||
|
||||
TAG="registry.gitlab.gnome.org/gnome/gtk/master:v1"
|
||||
TAG="registry.gitlab.gnome.org/gnome/gtk/master:v2"
|
||||
|
||||
sudo docker build --build-arg HOST_USER_ID="$UID" --tag "${TAG}" \
|
||||
--file "Dockerfile" .
|
||||
|
245
CONTRIBUTING.md
245
CONTRIBUTING.md
@@ -1,31 +1,144 @@
|
||||
If you want to hack on the GTK+ project, you'll need to have the development
|
||||
tools appropriate for your operating system, including:
|
||||
# Contribution guidelines
|
||||
|
||||
Thank you for considering contributing to the GTK project!
|
||||
|
||||
These guidelines are meant for new contributors, regardless of their level
|
||||
of proficiency; following them allows the maintainers of the GTK project to
|
||||
more effectively evaluate your contribution, and provide prompt feedback to
|
||||
you. Additionally, by following these guidelines you clearly communicate
|
||||
that you respect the time and effort that the people developing GTK put into
|
||||
managing the project.
|
||||
|
||||
GTK is a complex free software GUI toolkit, and it would not exist without
|
||||
contributions from the free and open source software community. There are
|
||||
many things that we value:
|
||||
|
||||
- bug reporting and fixing
|
||||
- documentation and examples
|
||||
- tests
|
||||
- new features
|
||||
|
||||
Please, do not use the issue tracker for support questions. If you have
|
||||
questions on how to use GTK effectively, you can use:
|
||||
|
||||
- the `#gtk+` IRC channel on irc.gnome.org
|
||||
- the [gtk](https://mail.gnome.org/mailman/listinfo/gtk-list) mailing list,
|
||||
for general questions on GTK
|
||||
- the [gtk-app-devel](https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list)
|
||||
mailing list, for questions on application development with GTK
|
||||
- the [gtk-devel](https://mail.gnome.org/mailman/listinfo/gtk-devel-list)
|
||||
mailing list, for questions on developing GTK itself
|
||||
|
||||
You can also look at the GTK tag on [Stack
|
||||
Overflow](https://stackoverflow.com/questions/tagged/gtk).
|
||||
|
||||
The issue tracker is meant to be used for actionable issues only.
|
||||
|
||||
## How to report bugs
|
||||
|
||||
### Security issues
|
||||
|
||||
You should not open a new issue for security related questions.
|
||||
|
||||
When in doubt, send an email to the [security](mailto:security@gnome.org)
|
||||
mailing list.
|
||||
|
||||
### Bug reports
|
||||
|
||||
If you're reporting a bug make sure to list:
|
||||
|
||||
0. which version of GTK are you using?
|
||||
0. which operating system are you using?
|
||||
0. the necessary steps to reproduce the issue
|
||||
0. the expected outcome
|
||||
0. a description of the behavior; screenshots are also welcome
|
||||
0. a small, self-contained example exhibiting the behavior; if this
|
||||
is not available, try reproducing the issue using the GTK examples
|
||||
or interactive tests
|
||||
|
||||
If the issue includes a crash, you should also include:
|
||||
|
||||
0. the eventual warnings printed on the terminal
|
||||
0. a backtrace, obtained with tools such as GDB or LLDB
|
||||
|
||||
For small issues, such as:
|
||||
|
||||
- spelling/grammar fixes in the documentation
|
||||
- typo correction
|
||||
- comment clean ups
|
||||
- changes to metadata files (CI, `.gitignore`)
|
||||
- build system changes
|
||||
- source tree clean ups and reorganizations
|
||||
|
||||
You should directly open a merge request instead of filing a new issue.
|
||||
|
||||
### Features and enhancements
|
||||
|
||||
Feature discussion can be open ended and require high bandwidth channels; if
|
||||
you are proposing a new feature on the issue tracker, make sure to make
|
||||
an actionable proposal, and list:
|
||||
|
||||
0. what you're trying to achieve
|
||||
0. prior art, in other toolkits or applications
|
||||
0. design and theming changes
|
||||
|
||||
If you're proposing the integration of new features it helps to have
|
||||
multiple applications using shared or similar code, especially if they have
|
||||
iterated over it various times.
|
||||
|
||||
Each feature should also come fully documented, and with tests.
|
||||
|
||||
## Your first contribution
|
||||
|
||||
### Prerequisites
|
||||
|
||||
If you want to contribute to the GTK project, you will need to have the
|
||||
development tools appropriate for your operating system, including:
|
||||
|
||||
- Python 3.x
|
||||
- Meson
|
||||
- Ninja
|
||||
- Gettext (19.7 or newer)
|
||||
- a C99 compatible compiler
|
||||
- a [C99 compatible compiler](https://wiki.gnome.org/Projects/GLib/CompilerRequirements)
|
||||
|
||||
Up-to-date instructions about developing GNOME applications and libraries
|
||||
can be found here:
|
||||
can be found on [the GNOME Developer Center](https://developer.gnome.org).
|
||||
|
||||
* https://developer.gnome.org
|
||||
The GTK project uses GitLab for code hosting and for tracking issues. More
|
||||
information about using GitLab can be found [on the GNOME
|
||||
wiki](https://wiki.gnome.org/GitLab).
|
||||
|
||||
Information about using GitLab with GNOME can be found here:
|
||||
### Dependencies
|
||||
|
||||
* https://wiki.gnome.org/GitLab
|
||||
In order to get GTK from Git installed on your system, you need to have the
|
||||
required versions of all the software dependencies required by GTK; typically,
|
||||
this means a recent version of GLib, Cairo, Pango, and ATK, as well as the
|
||||
platform-specific dependencies for the windowing system you are using (Wayland,
|
||||
X11, Windows, or macOS).
|
||||
|
||||
In order to get Git GTK+ installed on your system, you need to have the
|
||||
required versions of all the GTK+ dependencies; typically, this means a
|
||||
recent version of GLib, Cairo, Pango, and ATK, as well as the platform
|
||||
specific dependencies for the windowing system you are using (Wayland, X11,
|
||||
Windows, or macOS).
|
||||
The core dependencies for GTK are:
|
||||
|
||||
- [GLib, GObject, and GIO](https://gitlab.gnome.org/GNOME/glib)
|
||||
- [Cairo](http://cairographics.org)
|
||||
- [Pango](https://gitlab.gnome.org/GNOME/pango)
|
||||
- [GdkPixbuf](https://gitlab.gnome.org/GNOME/gdk-pixbuf)
|
||||
- [Epoxy](https://github.com/anholt/libepoxy)
|
||||
- [ATK](https://gitlab.gnome.org/GNOME/atk)
|
||||
- [Graphene](https://github.com/ebassi/graphene)
|
||||
|
||||
GTK will attempt to download and build some of these dependencies if it
|
||||
cannot find them on your system.
|
||||
|
||||
Additionally, you may want to look at projects that create a development
|
||||
environment for you, like [jhbuild](https://wiki.gnome.org/HowDoI/Jhbuild)
|
||||
and [gvsbuild](https://github.com/wingtk/gvsbuild).
|
||||
|
||||
### Getting started
|
||||
|
||||
You should start by forking the GTK repository from the GitLab web UI, and
|
||||
cloning from your fork:
|
||||
|
||||
```ssh
|
||||
```sh
|
||||
$ git clone https://gitlab.gnome.org/yourusername/gtk.git
|
||||
$ cd gtk
|
||||
```
|
||||
@@ -38,7 +151,7 @@ $ git clone git@gitlab.gnome.org:GNOME/gtk.git
|
||||
$ cd gtk
|
||||
```
|
||||
|
||||
To compile the Git version of GTK+ on your system, you will need to
|
||||
To compile the Git version of GTK on your system, you will need to
|
||||
configure your build using Meson:
|
||||
|
||||
```sh
|
||||
@@ -47,11 +160,6 @@ $ cd _builddir
|
||||
$ ninja
|
||||
```
|
||||
|
||||
**Note**: For information about submitting patches and pushing changes
|
||||
to Git, see the `README.md` and `README.commits` files. In particular,
|
||||
don't, under any circumstances, push anything to Git before reading and
|
||||
understanding `README.commmits`.
|
||||
|
||||
Typically, you should work on your own branch:
|
||||
|
||||
```sh
|
||||
@@ -60,6 +168,99 @@ $ git checkout -b your-branch
|
||||
|
||||
Once you've finished working on the bug fix or feature, push the branch
|
||||
to the Git repository and open a new merge request, to let the GTK
|
||||
maintainers review your contribution. The [CODE-OWNERS](./docs-CODE-OWNERS)
|
||||
document contains the list of core contributors to GTK and the areas for
|
||||
which they are responsible.
|
||||
maintainers review your contribution.
|
||||
|
||||
### Code reviews
|
||||
|
||||
Each contribution is reviewed by the core developers of the GTK project.
|
||||
|
||||
The [CODE-OWNERS](./docs/CODE-OWNERS) document contains the list of core
|
||||
contributors to GTK and the areas for which they are responsible; you
|
||||
should ensure to receive their review and signoff on your changes.
|
||||
|
||||
### Commit messages
|
||||
|
||||
The expected format for git commit messages is as follows:
|
||||
|
||||
```plain
|
||||
Short explanation of the commit
|
||||
|
||||
Longer explanation explaining exactly what's changed, whether any
|
||||
external or private interfaces changed, what bugs were fixed (with bug
|
||||
tracker reference if applicable) and so forth. Be concise but not too
|
||||
brief.
|
||||
|
||||
Closes #1234
|
||||
```
|
||||
|
||||
- Always add a brief description of the commit to the _first_ line of
|
||||
the commit and terminate by two newlines (it will work without the
|
||||
second newline, but that is not nice for the interfaces).
|
||||
|
||||
- First line (the brief description) must only be one sentence and
|
||||
should start with a capital letter unless it starts with a lowercase
|
||||
symbol or identifier. Don't use a trailing period either. Don't exceed
|
||||
72 characters.
|
||||
|
||||
- The main description (the body) is normal prose and should use normal
|
||||
punctuation and capital letters where appropriate. Consider the commit
|
||||
message as an email sent to the developers (or yourself, six months
|
||||
down the line) detailing **why** you changed something. There's no need
|
||||
to specify the **how**: the changes can be inlined.
|
||||
|
||||
- When committing code on behalf of others use the `--author` option, e.g.
|
||||
`git commit -a --author "Joe Coder <joe@coder.org>"` and `--signoff`.
|
||||
|
||||
- If your commit is addressing an issue, use the
|
||||
[GitLab syntax](https://docs.gitlab.com/ce/user/project/issues/automatic_issue_closing.html)
|
||||
to automatically close the issue when merging the commit with the upstream
|
||||
repository:
|
||||
|
||||
```plain
|
||||
Closes #1234
|
||||
Fixes #1234
|
||||
Closes: https://gitlab.gnome.org/GNOME/gtk/issues/1234
|
||||
```
|
||||
|
||||
- If you have a merge request with multiple commits and none of them
|
||||
completely fixes an issue, you should add a reference to the issue in
|
||||
the commit message, e.g. `Bug: #1234`, and use the automatic issue
|
||||
closing syntax in the description of the merge request.
|
||||
|
||||
### Commit access to the GTK repository
|
||||
|
||||
GTK is part of the GNOME infrastructure. At the current time, any
|
||||
person with write access to the GNOME repository can merge changes to
|
||||
GTK. This is a good thing, in that it encourages many people to work
|
||||
on GTK, and progress can be made quickly. However, GTK is a fairly
|
||||
large and complicated project on which many other things depend, so to
|
||||
avoid unnecessary breakage, and to take advantage of the knowledge
|
||||
about GTK that has been built up over the years, we'd like to ask
|
||||
people committing to GTK to follow a few rules:
|
||||
|
||||
0. Ask first. If your changes are major, or could possibly break existing
|
||||
code, you should always ask. If your change is minor and you've been
|
||||
working on GTK for a while it probably isn't necessary to ask. But when
|
||||
in doubt, ask. Even if your change is correct, somebody may know a
|
||||
better way to do things. If you are making changes to GTK, you should
|
||||
be subscribed to the [gtk-devel](https://mail.gnome.org/mailman/listinfo/gtk-devel-list)
|
||||
mailing list; this is a good place to ask about intended changes.
|
||||
The `#gtk+` IRC channel on irc.gnome.org is also a good place to find GTK
|
||||
developers to discuss changes, but if you live outside of the EU/US time
|
||||
zones, an email to the gtk-devel mailing list is the most certain and
|
||||
preferred method.
|
||||
|
||||
0. Ask _first_.
|
||||
|
||||
0. Always write a meaningful commit message. Changes without a sufficient
|
||||
commit message will be reverted.
|
||||
|
||||
0. Never push to the `master` branch, or any stable branches, directly; you
|
||||
should always go through a merge request, to ensure that the code is
|
||||
tested on the CI infrastructure at the very least. A merge request is
|
||||
also the proper place to get a comprehensive code review from the core
|
||||
developers of GTK.
|
||||
|
||||
If you have been contributing to GTK for a while and you don't have commit
|
||||
access to the repository, you may ask to obtain it following the [GNOME account
|
||||
process](https://wiki.gnome.org/AccountsTeam/NewAccounts).
|
||||
|
8
NEWS
8
NEWS
@@ -27,8 +27,8 @@ Overview of Changes in GTK+ 3.94.0
|
||||
* Applications can now create their own GtkSnapshot objects for
|
||||
intermediate rendering.
|
||||
|
||||
* Widget event signals have been replaced by event controller, and
|
||||
some new event controllers have been introduced for this:
|
||||
* Widget event signals have been replaced by event controllers,
|
||||
and some new event controllers have been introduced for this:
|
||||
GtkEventControllerMotion
|
||||
GtkEventControllerKey
|
||||
GtkGestureStylus
|
||||
@@ -68,6 +68,10 @@ Overview of Changes in GTK+ 3.94.0
|
||||
gtk_widget_draw
|
||||
gtk_render_icon_surface
|
||||
|
||||
* Incomplete transitions:
|
||||
The ::event signal is not still there, but it will be removed
|
||||
The DND apis are not finalized yet
|
||||
|
||||
* Translation updates:
|
||||
Croatian
|
||||
Esperanto
|
||||
|
@@ -1,72 +0,0 @@
|
||||
GTK+ is part of the GNOME git repository. At the current time, any
|
||||
person with write access to the GNOME repository, can make changes to
|
||||
GTK+. This is a good thing, in that it encourages many people to work
|
||||
on GTK+, and progress can be made quickly. However, GTK+ is a fairly
|
||||
large and complicated package that many other things depend on, so to
|
||||
avoid unnecessary breakage, and to take advantage of the knowledge
|
||||
about GTK+ that has been built up over the years, we'd like to ask
|
||||
people committing to GTK+ to follow a few rules:
|
||||
|
||||
0) Ask first. If your changes are major, or could possibly break existing
|
||||
code, you should always ask. If your change is minor and you've
|
||||
been working on GTK+ for a while it probably isn't necessary
|
||||
to ask. But when in doubt, ask. Even if your change is correct,
|
||||
somebody may know a better way to do things.
|
||||
|
||||
If you are making changes to GTK+, you should be subscribed
|
||||
to gtk-devel-list@gnome.org. (Subscription address:
|
||||
gtk-devel-list-request@gnome.org.) This is a good place to ask
|
||||
about intended changes.
|
||||
|
||||
#gtk+ on GIMPNet (irc.gimp.org, irc.us.gimp.org, irc.eu.gimp.org, ...)
|
||||
is also a good place to find GTK+ developers to discuss changes with,
|
||||
however, email to gtk-devel-list is the most certain and preferred
|
||||
method.
|
||||
|
||||
1) Ask _first_.
|
||||
|
||||
2) With git, we no longer maintain a ChangeLog file, but you are expected
|
||||
to produce a meaningful commit message. Changes without a sufficient
|
||||
commit message will be reverted. See below for the expected format
|
||||
of commit messages.
|
||||
|
||||
Notes:
|
||||
|
||||
* When developing larger features or complicated bug fixes, it is
|
||||
advisable to work in a branch in your own cloned GTK+ repository.
|
||||
You may even consider making your repository publically available
|
||||
so that others can easily test and review your changes.
|
||||
|
||||
* The expected format for git commit messages is as follows:
|
||||
|
||||
=== begin example commit ===
|
||||
Short explanation of the commit
|
||||
|
||||
Longer explanation explaining exactly what's changed, whether any
|
||||
external or private interfaces changed, what bugs were fixed (with bug
|
||||
tracker reference if applicable) and so forth. Be concise but not too brief.
|
||||
=== end example commit ===
|
||||
|
||||
- Always add a brief description of the commit to the _first_ line of
|
||||
the commit and terminate by two newlines (it will work without the
|
||||
second newline, but that is not nice for the interfaces).
|
||||
|
||||
- First line (the brief description) must only be one sentence and
|
||||
should start with a capital letter unless it starts with a lowercase
|
||||
symbol or identifier. Don't use a trailing period either. Don't exceed
|
||||
72 characters.
|
||||
|
||||
- The main description (the body) is normal prose and should use normal
|
||||
punctuation and capital letters where appropriate. Normally, for patches
|
||||
sent to a mailing list it's copied from there.
|
||||
|
||||
- When committing code on behalf of others use the --author option, e.g.
|
||||
git commit -a --author "Joe Coder <joe@coder.org>" and --signoff.
|
||||
|
||||
|
||||
Owen Taylor
|
||||
13 Aug 1998
|
||||
17 Apr 2001
|
||||
|
||||
Matthias Clasen
|
||||
31 Mar 2009
|
@@ -31,6 +31,11 @@ Information about mailing lists can be found at
|
||||
|
||||
- http://www.gtk.org/mailing-lists.php
|
||||
|
||||
Nightly documentation can be found at
|
||||
- Gtk: https://gnome.pages.gitlab.gnome.org/gtk/gtk/
|
||||
- Gdk: https://gnome.pages.gitlab.gnome.org/gtk/gdk/
|
||||
- Gsk: https://gnome.pages.gitlab.gnome.org/gtk/gsk/
|
||||
|
||||
Building and installing
|
||||
-----------------------
|
||||
|
||||
|
@@ -5,7 +5,6 @@
|
||||
"sdk": "org.gnome.Sdk",
|
||||
"command": "gtk4-demo",
|
||||
"tags": ["devel", "development", "nightly"],
|
||||
"rename-desktop-file": "gtk4-demo.desktop",
|
||||
"rename-icon": "gtk4-demo",
|
||||
"desktop-file-name-prefix": "(Development) ",
|
||||
"finish-args": [
|
||||
|
@@ -5,7 +5,6 @@
|
||||
"sdk": "org.gnome.Sdk",
|
||||
"command": "gtk4-widget-factory",
|
||||
"tags": ["devel", "development", "nightly"],
|
||||
"rename-desktop-file": "gtk4-widget-factory.desktop",
|
||||
"rename-icon": "gtk4-widget-factory",
|
||||
"desktop-file-name-prefix": "(Development) ",
|
||||
"finish-args": [
|
||||
|
@@ -455,13 +455,16 @@ demo_application_window_constructed (GObject *object)
|
||||
}
|
||||
|
||||
static void
|
||||
demo_application_window_size_allocate (GtkWidget *widget,
|
||||
const GtkAllocation *allocation,
|
||||
int baseline)
|
||||
demo_application_window_size_allocate (GtkWidget *widget,
|
||||
int width,
|
||||
int height,
|
||||
int baseline)
|
||||
{
|
||||
DemoApplicationWindow *window = (DemoApplicationWindow *)widget;
|
||||
|
||||
GTK_WIDGET_CLASS (demo_application_window_parent_class)->size_allocate (widget, allocation,
|
||||
GTK_WIDGET_CLASS (demo_application_window_parent_class)->size_allocate (widget,
|
||||
width,
|
||||
height,
|
||||
baseline);
|
||||
|
||||
if (!window->maximized && !window->fullscreen)
|
||||
|
@@ -87,14 +87,14 @@ find_toplevel_at_pointer (GdkDisplay *display)
|
||||
return widget ? gtk_widget_get_toplevel (widget) : NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
release_event_cb (GtkWidget *widget,
|
||||
GdkEvent *event,
|
||||
gboolean *clicked)
|
||||
static void
|
||||
released_cb (GtkGestureMultiPress *gesture,
|
||||
guint n_press,
|
||||
gdouble x,
|
||||
gdouble y,
|
||||
gboolean *clicked)
|
||||
{
|
||||
if (gdk_event_get_event_type (event) == GDK_BUTTON_RELEASE)
|
||||
*clicked = TRUE;
|
||||
return TRUE;
|
||||
*clicked = TRUE;
|
||||
}
|
||||
|
||||
/* Asks the user to click on a window, then waits for them click
|
||||
@@ -132,10 +132,12 @@ query_for_toplevel (GdkDisplay *display,
|
||||
GDK_SEAT_CAPABILITY_ALL_POINTING,
|
||||
FALSE, cursor, NULL, NULL, NULL) == GDK_GRAB_SUCCESS)
|
||||
{
|
||||
GtkGesture *gesture = gtk_gesture_multi_press_new ();
|
||||
gboolean clicked = FALSE;
|
||||
|
||||
g_signal_connect (popup, "event",
|
||||
G_CALLBACK (release_event_cb), &clicked);
|
||||
g_signal_connect (gesture, "released",
|
||||
G_CALLBACK (released_cb), &clicked);
|
||||
gtk_widget_add_controller (popup, GTK_EVENT_CONTROLLER (gesture));
|
||||
|
||||
/* Process events until clicked is set by our button release event handler.
|
||||
* We pass in may_block=TRUE since we want to wait if there
|
||||
@@ -144,6 +146,8 @@ query_for_toplevel (GdkDisplay *display,
|
||||
while (!clicked)
|
||||
g_main_context_iteration (NULL, TRUE);
|
||||
|
||||
gdk_seat_ungrab (gdk_device_get_seat (device));
|
||||
|
||||
toplevel = find_toplevel_at_pointer (display);
|
||||
if (toplevel == popup)
|
||||
toplevel = NULL;
|
||||
|
@@ -120,7 +120,7 @@ get_image_paintable (GtkImage *image)
|
||||
|
||||
static void
|
||||
drag_begin (GtkWidget *widget,
|
||||
GdkDragContext *context,
|
||||
GdkDrag *drag,
|
||||
gpointer data)
|
||||
{
|
||||
GdkPaintable *paintable;
|
||||
@@ -128,17 +128,16 @@ drag_begin (GtkWidget *widget,
|
||||
paintable = get_image_paintable (GTK_IMAGE (widget));
|
||||
if (paintable)
|
||||
{
|
||||
gtk_drag_set_icon_paintable (context, paintable, -2, -2);
|
||||
gtk_drag_set_icon_paintable (drag, paintable, -2, -2);
|
||||
g_object_unref (paintable);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
drag_data_get (GtkWidget *widget,
|
||||
GdkDragContext *context,
|
||||
GdkDrag *drag,
|
||||
GtkSelectionData *selection_data,
|
||||
guint info,
|
||||
guint time,
|
||||
gpointer data)
|
||||
{
|
||||
GdkPaintable *paintable;
|
||||
@@ -150,9 +149,8 @@ drag_data_get (GtkWidget *widget,
|
||||
|
||||
static void
|
||||
drag_data_received (GtkWidget *widget,
|
||||
GdkDragContext *context,
|
||||
GdkDrop *drop,
|
||||
GtkSelectionData *selection_data,
|
||||
guint32 time,
|
||||
gpointer data)
|
||||
{
|
||||
if (gtk_selection_data_get_length (selection_data) > 0)
|
||||
|
@@ -144,7 +144,7 @@ create_capital_store (void)
|
||||
{ NULL, "Jackson" },
|
||||
{ NULL, "Jefferson City" },
|
||||
{ NULL, "Juneau" },
|
||||
{ "K - O" },
|
||||
{ "K - O", NULL },
|
||||
{ NULL, "Lansing" },
|
||||
{ NULL, "Lincoln" },
|
||||
{ NULL, "Little Rock" },
|
||||
@@ -154,7 +154,7 @@ create_capital_store (void)
|
||||
{ NULL, "Nashville" },
|
||||
{ NULL, "Oklahoma City" },
|
||||
{ NULL, "Olympia" },
|
||||
{ NULL, "P - S" },
|
||||
{ "P - S", NULL },
|
||||
{ NULL, "Phoenix" },
|
||||
{ NULL, "Pierre" },
|
||||
{ NULL, "Providence" },
|
||||
|
@@ -161,7 +161,6 @@
|
||||
<file>editable_cells.c</file>
|
||||
<file>entry_buffer.c</file>
|
||||
<file>entry_completion.c</file>
|
||||
<file>event_axes.c</file>
|
||||
<file>expander.c</file>
|
||||
<file>filtermodel.c</file>
|
||||
<file>fishbowl.c</file>
|
||||
|
@@ -1,666 +0,0 @@
|
||||
/* Touch and Drawing Tablets
|
||||
*
|
||||
* Demonstrates advanced handling of event information from exotic
|
||||
* input devices.
|
||||
*
|
||||
* On one hand, this snippet demonstrates management of drawing tablets,
|
||||
* those contain additional information for the pointer other than
|
||||
* X/Y coordinates. Tablet pads events are mapped to actions, which
|
||||
* are both defined and interpreted by the application.
|
||||
*
|
||||
* Input axes are dependent on hardware devices, on linux/unix you
|
||||
* can see the device axes through xinput list <device>. Each time
|
||||
* a different hardware device is used to move the pointer, the
|
||||
* master device will be updated to match the axes it provides,
|
||||
* these changes can be tracked through GdkDevice::changed, or
|
||||
* checking gdk_event_get_source_device().
|
||||
*
|
||||
* On the other hand, this demo handles basic multitouch events,
|
||||
* each event coming from an specific touchpoint will contain a
|
||||
* GdkEventSequence that's unique for its lifetime, so multiple
|
||||
* touchpoints can be tracked.
|
||||
*/
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
typedef struct {
|
||||
GdkDevice *last_source;
|
||||
GdkDeviceTool *last_tool;
|
||||
gdouble *axes;
|
||||
GdkRGBA color;
|
||||
gdouble x;
|
||||
gdouble y;
|
||||
} AxesInfo;
|
||||
|
||||
typedef struct {
|
||||
GHashTable *pointer_info; /* GdkDevice -> AxesInfo */
|
||||
GHashTable *touch_info; /* GdkEventSequence -> AxesInfo */
|
||||
} EventData;
|
||||
|
||||
const gchar *colors[] = {
|
||||
"black",
|
||||
"orchid",
|
||||
"fuchsia",
|
||||
"indigo",
|
||||
"thistle",
|
||||
"sienna",
|
||||
"azure",
|
||||
"plum",
|
||||
"lime",
|
||||
"navy",
|
||||
"maroon",
|
||||
"burlywood"
|
||||
};
|
||||
|
||||
static GtkPadActionEntry pad_actions[] = {
|
||||
{ GTK_PAD_ACTION_BUTTON, 1, -1, N_("Nuclear strike"), "pad.nuke" },
|
||||
{ GTK_PAD_ACTION_BUTTON, 2, -1, N_("Release siberian methane reserves"), "pad.heat" },
|
||||
{ GTK_PAD_ACTION_BUTTON, 3, -1, N_("Release solar flare"), "pad.fry" },
|
||||
{ GTK_PAD_ACTION_BUTTON, 4, -1, N_("De-stabilize Oort cloud"), "pad.fall" },
|
||||
{ GTK_PAD_ACTION_BUTTON, 5, -1, N_("Ignite WR-104"), "pad.burst" },
|
||||
{ GTK_PAD_ACTION_BUTTON, 6, -1, N_("Lart whoever asks about this button"), "pad.lart" },
|
||||
{ GTK_PAD_ACTION_RING, -1, -1, N_("Earth axial tilt"), "pad.tilt" },
|
||||
{ GTK_PAD_ACTION_STRIP, -1, -1, N_("Extent of weak nuclear force"), "pad.dissolve" },
|
||||
};
|
||||
|
||||
static const gchar *pad_action_results[] = {
|
||||
"☢",
|
||||
"♨",
|
||||
"☼",
|
||||
"☄",
|
||||
"⚡",
|
||||
"💫",
|
||||
"◑",
|
||||
"⚛"
|
||||
};
|
||||
|
||||
static guint cur_color = 0;
|
||||
static guint pad_action_timeout_id = 0;
|
||||
|
||||
static AxesInfo *
|
||||
axes_info_new (void)
|
||||
{
|
||||
AxesInfo *info;
|
||||
|
||||
info = g_new0 (AxesInfo, 1);
|
||||
gdk_rgba_parse (&info->color, colors[cur_color]);
|
||||
|
||||
cur_color = (cur_color + 1) % G_N_ELEMENTS (colors);
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
static EventData *
|
||||
event_data_new (void)
|
||||
{
|
||||
EventData *data;
|
||||
|
||||
data = g_new0 (EventData, 1);
|
||||
data->pointer_info = g_hash_table_new_full (NULL, NULL, NULL,
|
||||
(GDestroyNotify) g_free);
|
||||
data->touch_info = g_hash_table_new_full (NULL, NULL, NULL,
|
||||
(GDestroyNotify) g_free);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
static void
|
||||
event_data_free (EventData *data)
|
||||
{
|
||||
g_hash_table_destroy (data->pointer_info);
|
||||
g_hash_table_destroy (data->touch_info);
|
||||
g_free (data);
|
||||
}
|
||||
|
||||
static void
|
||||
update_axes_from_event (GdkEvent *event,
|
||||
EventData *data)
|
||||
{
|
||||
GdkDevice *device, *source_device;
|
||||
GdkEventSequence *sequence;
|
||||
GdkDeviceTool *tool;
|
||||
GdkEventType type;
|
||||
gdouble x, y;
|
||||
AxesInfo *info;
|
||||
|
||||
device = gdk_event_get_device (event);
|
||||
source_device = gdk_event_get_source_device (event);
|
||||
sequence = gdk_event_get_event_sequence (event);
|
||||
tool = gdk_event_get_device_tool (event);
|
||||
type = gdk_event_get_event_type (event);
|
||||
|
||||
if (type == GDK_TOUCH_END ||
|
||||
type == GDK_TOUCH_CANCEL)
|
||||
{
|
||||
g_hash_table_remove (data->touch_info, sequence);
|
||||
return;
|
||||
}
|
||||
else if (type == GDK_LEAVE_NOTIFY)
|
||||
{
|
||||
g_hash_table_remove (data->pointer_info, device);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!source_device)
|
||||
return;
|
||||
|
||||
if (!sequence)
|
||||
{
|
||||
info = g_hash_table_lookup (data->pointer_info, device);
|
||||
|
||||
if (!info)
|
||||
{
|
||||
info = axes_info_new ();
|
||||
g_hash_table_insert (data->pointer_info, device, info);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
info = g_hash_table_lookup (data->touch_info, sequence);
|
||||
|
||||
if (!info)
|
||||
{
|
||||
info = axes_info_new ();
|
||||
g_hash_table_insert (data->touch_info, sequence, info);
|
||||
}
|
||||
}
|
||||
|
||||
if (info->last_source != source_device)
|
||||
info->last_source = source_device;
|
||||
|
||||
if (info->last_tool != tool)
|
||||
info->last_tool = tool;
|
||||
|
||||
g_clear_pointer (&info->axes, g_free);
|
||||
|
||||
if (type == GDK_TOUCH_BEGIN ||
|
||||
type == GDK_TOUCH_UPDATE)
|
||||
{
|
||||
gboolean emulating_pointer;
|
||||
|
||||
gdk_event_get_touch_emulating_pointer (event, &emulating_pointer);
|
||||
if (sequence && emulating_pointer)
|
||||
g_hash_table_remove (data->pointer_info, device);
|
||||
}
|
||||
if (type == GDK_MOTION_NOTIFY ||
|
||||
type == GDK_BUTTON_PRESS ||
|
||||
type == GDK_BUTTON_RELEASE)
|
||||
{
|
||||
gdouble *axes;
|
||||
guint n_axes;
|
||||
|
||||
gdk_event_get_axes (event, &axes, &n_axes);
|
||||
info->axes = g_memdup (axes, sizeof (double) * n_axes);
|
||||
}
|
||||
|
||||
if (gdk_event_get_coords (event, &x, &y))
|
||||
{
|
||||
info->x = x;
|
||||
info->y = y;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
event_cb (GtkWidget *widget,
|
||||
GdkEvent *event,
|
||||
gpointer user_data)
|
||||
{
|
||||
update_axes_from_event (event, user_data);
|
||||
gtk_widget_queue_draw (widget);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
render_arrow (cairo_t *cr,
|
||||
gdouble x_diff,
|
||||
gdouble y_diff,
|
||||
const gchar *label)
|
||||
{
|
||||
cairo_save (cr);
|
||||
|
||||
cairo_set_source_rgb (cr, 0, 0, 0);
|
||||
cairo_new_path (cr);
|
||||
cairo_move_to (cr, 0, 0);
|
||||
cairo_line_to (cr, x_diff, y_diff);
|
||||
cairo_stroke (cr);
|
||||
|
||||
cairo_move_to (cr, x_diff, y_diff);
|
||||
cairo_show_text (cr, label);
|
||||
|
||||
cairo_restore (cr);
|
||||
}
|
||||
|
||||
static void
|
||||
draw_axes_info (cairo_t *cr,
|
||||
AxesInfo *info,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
gdouble pressure, tilt_x, tilt_y, distance, wheel, rotation, slider;
|
||||
GdkAxisFlags axes = gdk_device_get_axes (info->last_source);
|
||||
|
||||
cairo_save (cr);
|
||||
|
||||
cairo_set_line_width (cr, 1);
|
||||
gdk_cairo_set_source_rgba (cr, &info->color);
|
||||
|
||||
cairo_move_to (cr, 0, info->y);
|
||||
cairo_line_to (cr, width, info->y);
|
||||
cairo_move_to (cr, info->x, 0);
|
||||
cairo_line_to (cr, info->x, height);
|
||||
cairo_stroke (cr);
|
||||
|
||||
cairo_translate (cr, info->x, info->y);
|
||||
|
||||
if (!info->axes)
|
||||
{
|
||||
cairo_restore (cr);
|
||||
return;
|
||||
}
|
||||
|
||||
if (axes & GDK_AXIS_FLAG_PRESSURE)
|
||||
{
|
||||
cairo_pattern_t *pattern;
|
||||
|
||||
gdk_device_get_axis (info->last_source, info->axes, GDK_AXIS_PRESSURE,
|
||||
&pressure);
|
||||
|
||||
pattern = cairo_pattern_create_radial (0, 0, 0, 0, 0, 100);
|
||||
cairo_pattern_add_color_stop_rgba (pattern, pressure, 1, 0, 0, pressure);
|
||||
cairo_pattern_add_color_stop_rgba (pattern, 1, 0, 0, 1, 0);
|
||||
|
||||
cairo_set_source (cr, pattern);
|
||||
|
||||
cairo_arc (cr, 0, 0, 100, 0, 2 * G_PI);
|
||||
cairo_fill (cr);
|
||||
|
||||
cairo_pattern_destroy (pattern);
|
||||
}
|
||||
|
||||
if (axes & GDK_AXIS_FLAG_XTILT &&
|
||||
axes & GDK_AXIS_FLAG_YTILT)
|
||||
{
|
||||
gdk_device_get_axis (info->last_source, info->axes, GDK_AXIS_XTILT,
|
||||
&tilt_x);
|
||||
gdk_device_get_axis (info->last_source, info->axes, GDK_AXIS_YTILT,
|
||||
&tilt_y);
|
||||
|
||||
render_arrow (cr, tilt_x * 100, tilt_y * 100, "Tilt");
|
||||
}
|
||||
|
||||
if (axes & GDK_AXIS_FLAG_DISTANCE)
|
||||
{
|
||||
double dashes[] = { 5.0, 5.0 };
|
||||
cairo_text_extents_t extents;
|
||||
|
||||
gdk_device_get_axis (info->last_source, info->axes, GDK_AXIS_DISTANCE,
|
||||
&distance);
|
||||
|
||||
cairo_save (cr);
|
||||
|
||||
cairo_move_to (cr, distance * 100, 0);
|
||||
|
||||
cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
|
||||
cairo_set_dash (cr, dashes, 2, 0.0);
|
||||
cairo_arc (cr, 0, 0, distance * 100, 0, 2 * G_PI);
|
||||
cairo_stroke (cr);
|
||||
|
||||
cairo_move_to (cr, 0, -distance * 100);
|
||||
cairo_text_extents (cr, "Distance", &extents);
|
||||
cairo_rel_move_to (cr, -extents.width / 2, 0);
|
||||
cairo_show_text (cr, "Distance");
|
||||
|
||||
cairo_move_to (cr, 0, 0);
|
||||
|
||||
cairo_restore (cr);
|
||||
}
|
||||
|
||||
if (axes & GDK_AXIS_FLAG_WHEEL)
|
||||
{
|
||||
gdk_device_get_axis (info->last_source, info->axes, GDK_AXIS_WHEEL,
|
||||
&wheel);
|
||||
|
||||
cairo_save (cr);
|
||||
cairo_set_line_width (cr, 10);
|
||||
cairo_set_source_rgba (cr, 0, 0, 0, 0.5);
|
||||
|
||||
cairo_new_sub_path (cr);
|
||||
cairo_arc (cr, 0, 0, 100, 0, wheel * 2 * G_PI);
|
||||
cairo_stroke (cr);
|
||||
cairo_restore (cr);
|
||||
}
|
||||
|
||||
if (axes & GDK_AXIS_FLAG_ROTATION)
|
||||
{
|
||||
gdk_device_get_axis (info->last_source, info->axes, GDK_AXIS_ROTATION,
|
||||
&rotation);
|
||||
rotation *= 2 * G_PI;
|
||||
|
||||
cairo_save (cr);
|
||||
cairo_rotate (cr, - G_PI / 2);
|
||||
cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
|
||||
cairo_set_line_width (cr, 5);
|
||||
|
||||
cairo_new_sub_path (cr);
|
||||
cairo_arc (cr, 0, 0, 100, 0, rotation);
|
||||
cairo_stroke (cr);
|
||||
cairo_restore (cr);
|
||||
}
|
||||
|
||||
if (axes & GDK_AXIS_FLAG_SLIDER)
|
||||
{
|
||||
cairo_pattern_t *pattern, *mask;
|
||||
|
||||
gdk_device_get_axis (info->last_source, info->axes, GDK_AXIS_SLIDER,
|
||||
&slider);
|
||||
|
||||
cairo_save (cr);
|
||||
|
||||
cairo_move_to (cr, 0, -10);
|
||||
cairo_rel_line_to (cr, 0, -50);
|
||||
cairo_rel_line_to (cr, 10, 0);
|
||||
cairo_rel_line_to (cr, -5, 50);
|
||||
cairo_close_path (cr);
|
||||
|
||||
cairo_clip_preserve (cr);
|
||||
|
||||
pattern = cairo_pattern_create_linear (0, -10, 0, -60);
|
||||
cairo_pattern_add_color_stop_rgb (pattern, 0, 0, 1, 0);
|
||||
cairo_pattern_add_color_stop_rgb (pattern, 1, 1, 0, 0);
|
||||
cairo_set_source (cr, pattern);
|
||||
cairo_pattern_destroy (pattern);
|
||||
|
||||
mask = cairo_pattern_create_linear (0, -10, 0, -60);
|
||||
cairo_pattern_add_color_stop_rgba (mask, 0, 0, 0, 0, 1);
|
||||
cairo_pattern_add_color_stop_rgba (mask, slider, 0, 0, 0, 1);
|
||||
cairo_pattern_add_color_stop_rgba (mask, slider, 0, 0, 0, 0);
|
||||
cairo_pattern_add_color_stop_rgba (mask, 1, 0, 0, 0, 0);
|
||||
cairo_mask (cr, mask);
|
||||
cairo_pattern_destroy (mask);
|
||||
|
||||
cairo_set_source_rgb (cr, 0, 0, 0);
|
||||
cairo_stroke (cr);
|
||||
|
||||
cairo_restore (cr);
|
||||
}
|
||||
|
||||
cairo_restore (cr);
|
||||
}
|
||||
|
||||
static const gchar *
|
||||
tool_type_to_string (GdkDeviceToolType tool_type)
|
||||
{
|
||||
switch (tool_type)
|
||||
{
|
||||
case GDK_DEVICE_TOOL_TYPE_PEN:
|
||||
return "Pen";
|
||||
case GDK_DEVICE_TOOL_TYPE_ERASER:
|
||||
return "Eraser";
|
||||
case GDK_DEVICE_TOOL_TYPE_BRUSH:
|
||||
return "Brush";
|
||||
case GDK_DEVICE_TOOL_TYPE_PENCIL:
|
||||
return "Pencil";
|
||||
case GDK_DEVICE_TOOL_TYPE_AIRBRUSH:
|
||||
return "Airbrush";
|
||||
case GDK_DEVICE_TOOL_TYPE_MOUSE:
|
||||
return "Mouse";
|
||||
case GDK_DEVICE_TOOL_TYPE_LENS:
|
||||
return "Lens cursor";
|
||||
case GDK_DEVICE_TOOL_TYPE_UNKNOWN:
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
draw_device_info (GtkWidget *widget,
|
||||
cairo_t *cr,
|
||||
GdkEventSequence *sequence,
|
||||
gint *y,
|
||||
AxesInfo *info)
|
||||
{
|
||||
PangoLayout *layout;
|
||||
GString *string;
|
||||
gint height;
|
||||
|
||||
cairo_save (cr);
|
||||
|
||||
string = g_string_new (NULL);
|
||||
g_string_append_printf (string, "Source: %s",
|
||||
gdk_device_get_name (info->last_source));
|
||||
|
||||
if (sequence)
|
||||
g_string_append_printf (string, "\nSequence: %d",
|
||||
GPOINTER_TO_UINT (sequence));
|
||||
|
||||
if (info->last_tool)
|
||||
{
|
||||
const gchar *tool_type;
|
||||
guint64 serial;
|
||||
|
||||
tool_type = tool_type_to_string (gdk_device_tool_get_tool_type (info->last_tool));
|
||||
serial = gdk_device_tool_get_serial (info->last_tool);
|
||||
g_string_append_printf (string, "\nTool: %s", tool_type);
|
||||
|
||||
if (serial != 0)
|
||||
g_string_append_printf (string, ", Serial: %" G_GINT64_MODIFIER "x", serial);
|
||||
}
|
||||
|
||||
cairo_move_to (cr, 10, *y);
|
||||
layout = gtk_widget_create_pango_layout (widget, string->str);
|
||||
pango_cairo_show_layout (cr, layout);
|
||||
cairo_stroke (cr);
|
||||
|
||||
pango_layout_get_pixel_size (layout, NULL, &height);
|
||||
|
||||
gdk_cairo_set_source_rgba (cr, &info->color);
|
||||
cairo_set_line_width (cr, 10);
|
||||
cairo_move_to (cr, 0, *y);
|
||||
|
||||
*y = *y + height;
|
||||
cairo_line_to (cr, 0, *y);
|
||||
cairo_stroke (cr);
|
||||
|
||||
cairo_restore (cr);
|
||||
|
||||
g_object_unref (layout);
|
||||
g_string_free (string, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
draw_cb (GtkDrawingArea *da,
|
||||
cairo_t *cr,
|
||||
int width,
|
||||
int height,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkWidget *widget = GTK_WIDGET (da);
|
||||
EventData *data = user_data;
|
||||
AxesInfo *info;
|
||||
GHashTableIter iter;
|
||||
gpointer key, value;
|
||||
gint y = 0;
|
||||
|
||||
/* Draw Abs info */
|
||||
g_hash_table_iter_init (&iter, data->pointer_info);
|
||||
|
||||
while (g_hash_table_iter_next (&iter, NULL, &value))
|
||||
{
|
||||
info = value;
|
||||
draw_axes_info (cr, info, width, height);
|
||||
}
|
||||
|
||||
g_hash_table_iter_init (&iter, data->touch_info);
|
||||
|
||||
while (g_hash_table_iter_next (&iter, NULL, &value))
|
||||
{
|
||||
info = value;
|
||||
draw_axes_info (cr, info, width, height);
|
||||
}
|
||||
|
||||
/* Draw name, color legend and misc data */
|
||||
g_hash_table_iter_init (&iter, data->pointer_info);
|
||||
|
||||
while (g_hash_table_iter_next (&iter, NULL, &value))
|
||||
{
|
||||
info = value;
|
||||
draw_device_info (widget, cr, NULL, &y, info);
|
||||
}
|
||||
|
||||
g_hash_table_iter_init (&iter, data->touch_info);
|
||||
|
||||
while (g_hash_table_iter_next (&iter, &key, &value))
|
||||
{
|
||||
info = value;
|
||||
draw_device_info (widget, cr, key, &y, info);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
update_label_text (GtkWidget *label,
|
||||
const gchar *text)
|
||||
{
|
||||
gchar *markup = NULL;
|
||||
|
||||
if (text)
|
||||
markup = g_strdup_printf ("<span font='48.0'>%s</span>", text);
|
||||
gtk_label_set_markup (GTK_LABEL (label), markup);
|
||||
g_free (markup);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
reset_label_text_timeout_cb (gpointer user_data)
|
||||
{
|
||||
GtkWidget *label = user_data;
|
||||
|
||||
update_label_text (label, NULL);
|
||||
pad_action_timeout_id = 0;
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static void
|
||||
update_label_and_timeout (GtkWidget *label,
|
||||
const gchar *text)
|
||||
{
|
||||
if (pad_action_timeout_id)
|
||||
g_source_remove (pad_action_timeout_id);
|
||||
|
||||
update_label_text (label, text);
|
||||
pad_action_timeout_id = g_timeout_add (200, reset_label_text_timeout_cb, label);
|
||||
}
|
||||
|
||||
static void
|
||||
on_action_activate (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkWidget *label = user_data;
|
||||
const gchar *result;
|
||||
gchar *str;
|
||||
|
||||
result = g_object_get_data (G_OBJECT (action), "action-result");
|
||||
|
||||
if (!parameter)
|
||||
update_label_and_timeout (label, result);
|
||||
else
|
||||
{
|
||||
str = g_strdup_printf ("%s %.2f", result, g_variant_get_double (parameter));
|
||||
update_label_and_timeout (label, str);
|
||||
g_free (str);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
init_pad_controller (GtkWidget *window,
|
||||
GtkWidget *label)
|
||||
{
|
||||
GtkPadController *pad_controller;
|
||||
GSimpleActionGroup *action_group;
|
||||
GSimpleAction *action;
|
||||
gint i;
|
||||
|
||||
action_group = g_simple_action_group_new ();
|
||||
pad_controller = gtk_pad_controller_new (G_ACTION_GROUP (action_group),
|
||||
NULL);
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (pad_actions); i++)
|
||||
{
|
||||
if (pad_actions[i].type == GTK_PAD_ACTION_BUTTON)
|
||||
{
|
||||
action = g_simple_action_new (pad_actions[i].action_name, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
action = g_simple_action_new_stateful (pad_actions[i].action_name,
|
||||
G_VARIANT_TYPE_DOUBLE, NULL);
|
||||
}
|
||||
|
||||
g_signal_connect (action, "activate",
|
||||
G_CALLBACK (on_action_activate), label);
|
||||
g_object_set_data (G_OBJECT (action), "action-result",
|
||||
(gpointer) pad_action_results[i]);
|
||||
g_action_map_add_action (G_ACTION_MAP (action_group), G_ACTION (action));
|
||||
g_object_unref (action);
|
||||
}
|
||||
|
||||
gtk_pad_controller_set_action_entries (pad_controller, pad_actions,
|
||||
G_N_ELEMENTS (pad_actions));
|
||||
gtk_widget_add_controller (window, GTK_EVENT_CONTROLLER (pad_controller));
|
||||
|
||||
g_object_unref (action_group);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
do_event_axes (GtkWidget *toplevel)
|
||||
{
|
||||
static GtkWidget *window = NULL;
|
||||
EventData *event_data;
|
||||
GtkWidget *label;
|
||||
GtkWidget *overlay;
|
||||
GtkWidget *da;
|
||||
|
||||
if (!window)
|
||||
{
|
||||
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Touch and Drawing Tablets");
|
||||
|
||||
g_signal_connect (window, "destroy",
|
||||
G_CALLBACK (gtk_widget_destroyed), &window);
|
||||
|
||||
gtk_widget_set_support_multidevice (window, TRUE);
|
||||
|
||||
event_data = event_data_new ();
|
||||
g_object_set_data_full (G_OBJECT (window), "gtk-demo-event-data",
|
||||
event_data, (GDestroyNotify) event_data_free);
|
||||
|
||||
da = gtk_drawing_area_new ();
|
||||
gtk_drawing_area_set_content_width (GTK_DRAWING_AREA (da), 400);
|
||||
gtk_drawing_area_set_content_height (GTK_DRAWING_AREA (da), 400);
|
||||
gtk_drawing_area_set_draw_func (GTK_DRAWING_AREA (da), draw_cb, event_data, NULL);
|
||||
gtk_widget_set_can_focus (da, TRUE);
|
||||
gtk_widget_grab_focus (da);
|
||||
|
||||
g_signal_connect (da, "event",
|
||||
G_CALLBACK (event_cb), event_data);
|
||||
|
||||
label = gtk_label_new ("");
|
||||
gtk_widget_set_halign (label, GTK_ALIGN_START);
|
||||
gtk_widget_set_valign (label, GTK_ALIGN_START);
|
||||
gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
|
||||
|
||||
overlay = gtk_overlay_new ();
|
||||
gtk_container_add (GTK_CONTAINER (window), overlay);
|
||||
gtk_container_add (GTK_CONTAINER (overlay), da);
|
||||
gtk_overlay_add_overlay (GTK_OVERLAY (overlay), label);
|
||||
|
||||
init_pad_controller (da, label);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
gtk_widget_show (window);
|
||||
else
|
||||
gtk_widget_destroy (window);
|
||||
|
||||
return window;
|
||||
}
|
@@ -134,7 +134,9 @@ static GtkWidget *
|
||||
create_video (void)
|
||||
{
|
||||
GtkMediaStream *stream = gtk_media_file_new_for_resource ("/images/gtk-logo.webm");
|
||||
GtkWidget *w = gtk_image_new_from_paintable (GDK_PAINTABLE (stream));
|
||||
GtkWidget *w = gtk_picture_new_for_paintable (GDK_PAINTABLE (stream));
|
||||
|
||||
gtk_widget_set_size_request (w, 64, 64);
|
||||
gtk_media_stream_set_loop (stream, TRUE);
|
||||
gtk_media_stream_play (stream);
|
||||
g_object_unref (stream);
|
||||
|
@@ -128,9 +128,10 @@ gtk_fishbowl_measure (GtkWidget *widget,
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_fishbowl_size_allocate (GtkWidget *widget,
|
||||
const GtkAllocation *allocation,
|
||||
int baseline)
|
||||
gtk_fishbowl_size_allocate (GtkWidget *widget,
|
||||
int width,
|
||||
int height,
|
||||
int baseline)
|
||||
{
|
||||
GtkFishbowl *fishbowl = GTK_FISHBOWL (widget);
|
||||
GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
|
||||
@@ -147,8 +148,8 @@ gtk_fishbowl_size_allocate (GtkWidget *widget,
|
||||
continue;
|
||||
|
||||
gtk_widget_get_preferred_size (child->widget, &child_requisition, NULL);
|
||||
child_allocation.x = allocation->x + round (child->x * (allocation->width - child_requisition.width));
|
||||
child_allocation.y = allocation->y + round (child->y * (allocation->height - child_requisition.height));
|
||||
child_allocation.x = round (child->x * (width - child_requisition.width));
|
||||
child_allocation.y = round (child->y * (height - child_requisition.height));
|
||||
child_allocation.width = child_requisition.width;
|
||||
child_allocation.height = child_requisition.height;
|
||||
|
||||
|
@@ -135,55 +135,42 @@ static void set_cursor_if_appropriate (GtkTextView *text_view,
|
||||
gint x,
|
||||
gint y);
|
||||
|
||||
/* Links can also be activated by clicking or tapping.
|
||||
*/
|
||||
static gboolean
|
||||
event_cb (GtkWidget *text_view,
|
||||
GdkEvent *ev)
|
||||
static void
|
||||
released_cb (GtkGestureMultiPress *gesture,
|
||||
guint n_press,
|
||||
gdouble x,
|
||||
gdouble y,
|
||||
GtkWidget *text_view)
|
||||
{
|
||||
GtkTextIter start, end, iter;
|
||||
GtkTextBuffer *buffer;
|
||||
gdouble ex, ey;
|
||||
int x, y;
|
||||
GdkEventType type;
|
||||
int tx, ty;
|
||||
|
||||
type = gdk_event_get_event_type (ev);
|
||||
if (gtk_gesture_single_get_button (GTK_GESTURE_SINGLE (gesture)) > 1)
|
||||
return;
|
||||
|
||||
gdk_event_get_coords (ev, &ex, &ey);
|
||||
gtk_text_view_window_to_buffer_coords (GTK_TEXT_VIEW (text_view),
|
||||
GTK_TEXT_WINDOW_WIDGET,
|
||||
ex, ey, &x, &y);
|
||||
|
||||
if (type == GDK_BUTTON_RELEASE)
|
||||
{
|
||||
guint button;
|
||||
|
||||
gdk_event_get_button (ev, &button);
|
||||
if (button != GDK_BUTTON_PRIMARY)
|
||||
return FALSE;
|
||||
}
|
||||
else if (type == GDK_MOTION_NOTIFY)
|
||||
{
|
||||
set_cursor_if_appropriate (GTK_TEXT_VIEW (text_view), x, y);
|
||||
return FALSE;
|
||||
}
|
||||
else if (type == GDK_TOUCH_END)
|
||||
{
|
||||
}
|
||||
else
|
||||
return FALSE;
|
||||
x, y, &tx, &ty);
|
||||
|
||||
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_view));
|
||||
|
||||
/* we shouldn't follow a link if the user has selected something */
|
||||
gtk_text_buffer_get_selection_bounds (buffer, &start, &end);
|
||||
if (gtk_text_iter_get_offset (&start) != gtk_text_iter_get_offset (&end))
|
||||
return FALSE;
|
||||
return;
|
||||
|
||||
if (gtk_text_view_get_iter_at_location (GTK_TEXT_VIEW (text_view), &iter, x, y))
|
||||
follow_if_link (text_view, &iter);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
static void
|
||||
motion_cb (GtkEventControllerMotion *controller,
|
||||
gdouble x,
|
||||
gdouble y,
|
||||
GtkTextView *text_view)
|
||||
{
|
||||
set_cursor_if_appropriate (text_view, x, y);
|
||||
}
|
||||
|
||||
static gboolean hovering_over_link = FALSE;
|
||||
@@ -259,8 +246,16 @@ do_hypertext (GtkWidget *do_widget)
|
||||
controller = gtk_event_controller_key_new ();
|
||||
g_signal_connect (controller, "key-pressed", G_CALLBACK (key_pressed), view);
|
||||
gtk_widget_add_controller (view, controller);
|
||||
g_signal_connect (view, "event",
|
||||
G_CALLBACK (event_cb), NULL);
|
||||
|
||||
controller = GTK_EVENT_CONTROLLER (gtk_gesture_multi_press_new ());
|
||||
g_signal_connect (controller, "released",
|
||||
G_CALLBACK (released_cb), view);
|
||||
gtk_widget_add_controller (view, controller);
|
||||
|
||||
controller = gtk_event_controller_motion_new ();
|
||||
g_signal_connect (controller, "motion",
|
||||
G_CALLBACK (motion_cb), view);
|
||||
gtk_widget_add_controller (view, controller);
|
||||
|
||||
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
|
||||
|
||||
|
@@ -154,6 +154,7 @@
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="extra_buttons_box">
|
||||
<property name="visible">0</property>
|
||||
<property name="spacing">6</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="reply-button">
|
||||
|
@@ -831,15 +831,14 @@ load_file (const gchar *demoname,
|
||||
/* Skipping blank lines */
|
||||
while (g_ascii_isspace (*p))
|
||||
p++;
|
||||
if (*p)
|
||||
{
|
||||
p = lines[i];
|
||||
state++;
|
||||
/* Fall through */
|
||||
}
|
||||
else
|
||||
|
||||
if (!*p)
|
||||
break;
|
||||
|
||||
p = lines[i];
|
||||
state++;
|
||||
/* Fall through */
|
||||
|
||||
case 3:
|
||||
/* Reading program body */
|
||||
gtk_text_buffer_insert (source_buffer, &start, p, -1);
|
||||
|
@@ -16,6 +16,7 @@
|
||||
</columns>
|
||||
</object>
|
||||
<object class="GtkApplicationWindow" id="window">
|
||||
<style><class name="devel"/></style>
|
||||
<property name="default-width">800</property>
|
||||
<property name="default-height">600</property>
|
||||
<property name="title">GTK+ Demo</property>
|
||||
|
@@ -22,7 +22,6 @@ demos = files([
|
||||
'editable_cells.c',
|
||||
'entry_buffer.c',
|
||||
'entry_completion.c',
|
||||
'event_axes.c',
|
||||
'expander.c',
|
||||
'filtermodel.c',
|
||||
'fishbowl.c',
|
||||
@@ -130,7 +129,7 @@ foreach icon_size: [ '16x16', '22x22', '24x24', '32x32', '48x48', '256x256', ]
|
||||
endforeach
|
||||
|
||||
# desktop file
|
||||
install_data('gtk4-demo.desktop', install_dir: gtk_applicationsdir)
|
||||
install_data('org.gtk.Demo.desktop', install_dir: gtk_applicationsdir)
|
||||
|
||||
# GSettings
|
||||
install_data('org.gtk.Demo.gschema.xml', install_dir: gtk_schemasdir)
|
||||
|
@@ -3,14 +3,24 @@
|
||||
* Demonstrates practical handling of drawing tablets in a real world
|
||||
* usecase.
|
||||
*/
|
||||
#include <glib/gi18n.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
enum {
|
||||
COLOR_SET,
|
||||
N_SIGNALS
|
||||
};
|
||||
|
||||
static guint area_signals[N_SIGNALS] = { 0, };
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GtkWidget parent_instance;
|
||||
cairo_surface_t *surface;
|
||||
cairo_t *cr;
|
||||
GdkRGBA draw_color;
|
||||
GtkPadController *pad_controller;
|
||||
gdouble brush_size;
|
||||
} DrawingArea;
|
||||
|
||||
typedef struct
|
||||
@@ -18,8 +28,30 @@ typedef struct
|
||||
GtkWidgetClass parent_class;
|
||||
} DrawingAreaClass;
|
||||
|
||||
static GtkPadActionEntry pad_actions[] = {
|
||||
{ GTK_PAD_ACTION_BUTTON, 1, -1, N_("Black"), "pad.black" },
|
||||
{ GTK_PAD_ACTION_BUTTON, 2, -1, N_("Pink"), "pad.pink" },
|
||||
{ GTK_PAD_ACTION_BUTTON, 3, -1, N_("Green"), "pad.green" },
|
||||
{ GTK_PAD_ACTION_BUTTON, 4, -1, N_("Red"), "pad.red" },
|
||||
{ GTK_PAD_ACTION_BUTTON, 5, -1, N_("Purple"), "pad.purple" },
|
||||
{ GTK_PAD_ACTION_BUTTON, 6, -1, N_("Orange"), "pad.orange" },
|
||||
{ GTK_PAD_ACTION_STRIP, -1, -1, N_("Brush size"), "pad.brush_size" },
|
||||
};
|
||||
|
||||
static const gchar *pad_colors[] = {
|
||||
"black",
|
||||
"pink",
|
||||
"green",
|
||||
"red",
|
||||
"purple",
|
||||
"orange"
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (DrawingArea, drawing_area, GTK_TYPE_WIDGET)
|
||||
|
||||
static void drawing_area_set_color (DrawingArea *area,
|
||||
GdkRGBA *color);
|
||||
|
||||
static void
|
||||
drawing_area_ensure_surface (DrawingArea *area,
|
||||
gint width,
|
||||
@@ -52,15 +84,16 @@ drawing_area_ensure_surface (DrawingArea *area,
|
||||
}
|
||||
|
||||
static void
|
||||
drawing_area_size_allocate (GtkWidget *widget,
|
||||
const GtkAllocation *allocation,
|
||||
int baseline)
|
||||
drawing_area_size_allocate (GtkWidget *widget,
|
||||
int width,
|
||||
int height,
|
||||
int baseline)
|
||||
{
|
||||
DrawingArea *area = (DrawingArea *) widget;
|
||||
|
||||
drawing_area_ensure_surface (area, allocation->width, allocation->height);
|
||||
drawing_area_ensure_surface (area, width, height);
|
||||
|
||||
GTK_WIDGET_CLASS (drawing_area_parent_class)->size_allocate (widget, allocation, baseline);
|
||||
GTK_WIDGET_CLASS (drawing_area_parent_class)->size_allocate (widget, width, height, baseline);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -115,6 +148,82 @@ drawing_area_snapshot (GtkWidget *widget,
|
||||
cairo_destroy (cr);
|
||||
}
|
||||
|
||||
static void
|
||||
on_pad_button_activate (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
DrawingArea *area)
|
||||
{
|
||||
const gchar *color = g_object_get_data (G_OBJECT (action), "color");
|
||||
GdkRGBA rgba;
|
||||
|
||||
gdk_rgba_parse (&rgba, color);
|
||||
drawing_area_set_color (area, &rgba);
|
||||
}
|
||||
|
||||
static void
|
||||
on_pad_knob_change (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
DrawingArea *area)
|
||||
{
|
||||
gdouble value = g_variant_get_double (parameter);
|
||||
|
||||
area->brush_size = value;
|
||||
}
|
||||
|
||||
static void
|
||||
drawing_area_hierarchy_changed (GtkWidget *widget,
|
||||
GtkWidget *previous_toplevel)
|
||||
{
|
||||
DrawingArea *area = (DrawingArea *) widget;
|
||||
GSimpleActionGroup *action_group;
|
||||
GSimpleAction *action;
|
||||
GtkWidget *toplevel;
|
||||
gint i;
|
||||
|
||||
if (previous_toplevel && area->pad_controller)
|
||||
{
|
||||
gtk_widget_remove_controller (previous_toplevel,
|
||||
GTK_EVENT_CONTROLLER (area->pad_controller));
|
||||
area->pad_controller = NULL;
|
||||
}
|
||||
|
||||
toplevel = gtk_widget_get_toplevel (GTK_WIDGET (area));
|
||||
if (!GTK_IS_WINDOW (toplevel))
|
||||
return;
|
||||
|
||||
action_group = g_simple_action_group_new ();
|
||||
area->pad_controller = gtk_pad_controller_new (G_ACTION_GROUP (action_group),
|
||||
NULL);
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (pad_actions); i++)
|
||||
{
|
||||
if (pad_actions[i].type == GTK_PAD_ACTION_BUTTON)
|
||||
{
|
||||
action = g_simple_action_new (pad_actions[i].action_name, NULL);
|
||||
g_object_set_data (G_OBJECT (action), "color",
|
||||
(gpointer) pad_colors[i]);
|
||||
g_signal_connect (action, "activate",
|
||||
G_CALLBACK (on_pad_button_activate), area);
|
||||
}
|
||||
else
|
||||
{
|
||||
action = g_simple_action_new_stateful (pad_actions[i].action_name,
|
||||
G_VARIANT_TYPE_DOUBLE, NULL);
|
||||
g_signal_connect (action, "activate",
|
||||
G_CALLBACK (on_pad_knob_change), area);
|
||||
}
|
||||
|
||||
g_action_map_add_action (G_ACTION_MAP (action_group), G_ACTION (action));
|
||||
g_object_unref (action);
|
||||
}
|
||||
|
||||
gtk_pad_controller_set_action_entries (area->pad_controller, pad_actions,
|
||||
G_N_ELEMENTS (pad_actions));
|
||||
|
||||
gtk_widget_add_controller (toplevel,
|
||||
GTK_EVENT_CONTROLLER (area->pad_controller));
|
||||
}
|
||||
|
||||
static void
|
||||
drawing_area_class_init (DrawingAreaClass *klass)
|
||||
{
|
||||
@@ -124,6 +233,14 @@ drawing_area_class_init (DrawingAreaClass *klass)
|
||||
widget_class->snapshot = drawing_area_snapshot;
|
||||
widget_class->map = drawing_area_map;
|
||||
widget_class->unmap = drawing_area_unmap;
|
||||
widget_class->hierarchy_changed = drawing_area_hierarchy_changed;
|
||||
|
||||
area_signals[COLOR_SET] =
|
||||
g_signal_new ("color-set",
|
||||
G_TYPE_FROM_CLASS (widget_class),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
0, NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 1, GDK_TYPE_RGBA);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -135,12 +252,12 @@ drawing_area_apply_stroke (DrawingArea *area,
|
||||
{
|
||||
if (gdk_device_tool_get_tool_type (tool) == GDK_DEVICE_TOOL_TYPE_ERASER)
|
||||
{
|
||||
cairo_set_line_width (area->cr, 10 * pressure);
|
||||
cairo_set_line_width (area->cr, 10 * pressure * area->brush_size);
|
||||
cairo_set_operator (area->cr, CAIRO_OPERATOR_DEST_OUT);
|
||||
}
|
||||
else
|
||||
{
|
||||
cairo_set_line_width (area->cr, 4 * pressure);
|
||||
cairo_set_line_width (area->cr, 4 * pressure * area->brush_size);
|
||||
cairo_set_operator (area->cr, CAIRO_OPERATOR_SATURATE);
|
||||
}
|
||||
|
||||
@@ -148,8 +265,6 @@ drawing_area_apply_stroke (DrawingArea *area,
|
||||
area->draw_color.green, area->draw_color.blue,
|
||||
area->draw_color.alpha * pressure);
|
||||
|
||||
//cairo_set_source_rgba (area->cr, 0, 0, 0, pressure);
|
||||
|
||||
cairo_line_to (area->cr, x, y);
|
||||
cairo_stroke (area->cr);
|
||||
cairo_move_to (area->cr, x, y);
|
||||
@@ -225,11 +340,15 @@ drawing_area_new (void)
|
||||
return g_object_new (drawing_area_get_type (), NULL);
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
drawing_area_set_color (DrawingArea *area,
|
||||
GdkRGBA *color)
|
||||
{
|
||||
if (gdk_rgba_equal (&area->draw_color, color))
|
||||
return;
|
||||
|
||||
area->draw_color = *color;
|
||||
g_signal_emit (area, area_signals[COLOR_SET], 0, &area->draw_color);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -242,6 +361,14 @@ color_button_color_set (GtkColorButton *button,
|
||||
drawing_area_set_color (draw_area, &color);
|
||||
}
|
||||
|
||||
static void
|
||||
drawing_area_color_set (DrawingArea *area,
|
||||
GdkRGBA *color,
|
||||
GtkColorButton *button)
|
||||
{
|
||||
gtk_color_chooser_set_rgba (GTK_COLOR_CHOOSER (button), color);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
do_paint (GtkWidget *toplevel)
|
||||
{
|
||||
@@ -263,6 +390,8 @@ do_paint (GtkWidget *toplevel)
|
||||
colorbutton = gtk_color_button_new ();
|
||||
g_signal_connect (colorbutton, "color-set",
|
||||
G_CALLBACK (color_button_color_set), draw_area);
|
||||
g_signal_connect (draw_area, "color-set",
|
||||
G_CALLBACK (drawing_area_color_set), colorbutton);
|
||||
gtk_color_chooser_set_rgba (GTK_COLOR_CHOOSER (colorbutton),
|
||||
&(GdkRGBA) { 0, 0, 0, 1 });
|
||||
|
||||
|
@@ -55,10 +55,11 @@ create_complex_popover (GtkWidget *parent,
|
||||
}
|
||||
|
||||
static void
|
||||
entry_size_allocate_cb (GtkEntry *entry,
|
||||
const GtkAllocation *allocation,
|
||||
int baseline,
|
||||
gpointer user_data)
|
||||
entry_size_allocate_cb (GtkEntry *entry,
|
||||
int width,
|
||||
int height,
|
||||
int baseline,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkEntryIconPosition popover_pos;
|
||||
GtkPopover *popover = user_data;
|
||||
@@ -77,7 +78,6 @@ entry_size_allocate_cb (GtkEntry *entry,
|
||||
static void
|
||||
entry_icon_press_cb (GtkEntry *entry,
|
||||
GtkEntryIconPosition icon_pos,
|
||||
GdkEvent *event,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkWidget *popover = user_data;
|
||||
|
@@ -151,11 +151,10 @@ create_search_menu (GtkWidget *entry)
|
||||
static void
|
||||
icon_press_cb (GtkEntry *entry,
|
||||
gint position,
|
||||
GdkEventButton *event,
|
||||
gpointer data)
|
||||
{
|
||||
if (position == GTK_ENTRY_ICON_PRIMARY)
|
||||
gtk_menu_popup_at_pointer (GTK_MENU (menu), (GdkEvent *) event);
|
||||
gtk_menu_popup_at_pointer (GTK_MENU (menu), NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@@ -26,17 +26,6 @@ changed_cb (GtkEditable *editable)
|
||||
g_message ("changed: %s", text);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
window_event_cb (GtkWidget *widget,
|
||||
GdkEvent *event,
|
||||
GtkSearchBar *bar)
|
||||
{
|
||||
if (gdk_event_get_event_type (event) == GDK_KEY_PRESS)
|
||||
return gtk_search_bar_handle_event (bar, event);
|
||||
|
||||
return GDK_EVENT_PROPAGATE;
|
||||
}
|
||||
|
||||
static void
|
||||
search_changed (GtkSearchEntry *entry,
|
||||
GtkLabel *label)
|
||||
@@ -102,7 +91,7 @@ do_search_entry2 (GtkWidget *do_widget)
|
||||
gtk_box_pack_start (GTK_BOX (vbox), searchbar);
|
||||
|
||||
/* Hook the search bar to key presses */
|
||||
g_signal_connect (window, "event", G_CALLBACK (window_event_cb), searchbar);
|
||||
gtk_search_bar_set_key_capture_widget (GTK_SEARCH_BAR (searchbar), window);
|
||||
|
||||
/* Help */
|
||||
label = gtk_label_new ("Start Typing to search");
|
||||
|
@@ -295,6 +295,7 @@ start_puzzle (GdkPaintable *puzzle)
|
||||
grid = gtk_grid_new ();
|
||||
gtk_widget_set_can_focus (grid, TRUE);
|
||||
gtk_container_add (GTK_CONTAINER (frame), grid);
|
||||
gtk_aspect_frame_set (GTK_ASPECT_FRAME (frame), 0.5, 0.5, (float) gdk_paintable_get_intrinsic_aspect_ratio (puzzle), FALSE);
|
||||
|
||||
/* Add a key event controller so people can use the arrow
|
||||
* keys to move the puzzle */
|
||||
|
@@ -12,12 +12,10 @@ do_transparent (GtkWidget *do_widget)
|
||||
|
||||
if (!window)
|
||||
{
|
||||
GtkWidget *sw;
|
||||
GtkWidget *overlay;
|
||||
GtkWidget *button;
|
||||
GtkWidget *label;
|
||||
GtkWidget *box;
|
||||
GtkWidget *image;
|
||||
GtkWidget *picture;
|
||||
|
||||
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
@@ -54,17 +52,8 @@ do_transparent (GtkWidget *do_widget)
|
||||
gtk_overlay_add_overlay (GTK_OVERLAY (overlay), button);
|
||||
gtk_container_child_set (GTK_CONTAINER (overlay), button, "blur", 5.0, NULL);
|
||||
|
||||
sw = gtk_scrolled_window_new (NULL, NULL);
|
||||
sw = gtk_scrolled_window_new (NULL, NULL);
|
||||
gtk_container_add (GTK_CONTAINER (overlay), sw);
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
|
||||
GTK_POLICY_AUTOMATIC,
|
||||
GTK_POLICY_AUTOMATIC);
|
||||
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
||||
gtk_container_add (GTK_CONTAINER (sw), box);
|
||||
image = gtk_image_new_from_resource ("/transparent/portland-rose.jpg");
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (box), image);
|
||||
picture = gtk_picture_new_for_resource ("/transparent/portland-rose.jpg");
|
||||
gtk_container_add (GTK_CONTAINER (overlay), picture);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
|
@@ -376,10 +376,9 @@ search_mode_toggled (GObject *searchbar, GParamSpec *pspec, IconBrowserWindow *w
|
||||
|
||||
static void
|
||||
get_image_data (GtkWidget *widget,
|
||||
GdkDragContext *context,
|
||||
GdkDrag *drag,
|
||||
GtkSelectionData *selection,
|
||||
guint target_info,
|
||||
guint time,
|
||||
gpointer data)
|
||||
{
|
||||
GtkWidget *image;
|
||||
@@ -399,10 +398,9 @@ get_image_data (GtkWidget *widget,
|
||||
|
||||
static void
|
||||
get_scalable_image_data (GtkWidget *widget,
|
||||
GdkDragContext *context,
|
||||
GdkDrag *drag,
|
||||
GtkSelectionData *selection,
|
||||
guint target_info,
|
||||
guint time,
|
||||
gpointer data)
|
||||
{
|
||||
gchar *uris[2];
|
||||
|
@@ -17,4 +17,4 @@ executable('gtk4-icon-browser',
|
||||
link_args: extra_demo_ldflags,
|
||||
install: true)
|
||||
|
||||
install_data('gtk4-icon-browser.desktop', install_dir: gtk_applicationsdir)
|
||||
install_data('org.gtk.IconBrowser.desktop', install_dir: gtk_applicationsdir)
|
||||
|
@@ -6,6 +6,7 @@
|
||||
<property name="child-model">store</property>
|
||||
</object>
|
||||
<template class="IconBrowserWindow" parent="GtkApplicationWindow">
|
||||
<style><class name="devel"/></style>
|
||||
<property name="title" translatable="yes">Icon Browser</property>
|
||||
<property name="default-width">1024</property>
|
||||
<property name="default-height">768</property>
|
||||
|
@@ -1,19 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<!-- interface-requires gtk+ 3.0 -->
|
||||
<menu id="app-menu">
|
||||
<section>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">About</attribute>
|
||||
<attribute name="action">app.about</attribute>
|
||||
</item>
|
||||
</section>
|
||||
<section>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">_Quit</attribute>
|
||||
<attribute name="action">app.quit</attribute>
|
||||
<attribute name="accel"><Primary>q</attribute>
|
||||
</item>
|
||||
</section>
|
||||
</menu>
|
||||
</interface>
|
@@ -13,7 +13,7 @@ executable('gtk4-widget-factory',
|
||||
install: true)
|
||||
|
||||
# desktop file
|
||||
install_data('gtk4-widget-factory.desktop', install_dir: gtk_applicationsdir)
|
||||
install_data('org.gtk.WidgetFactory.desktop', install_dir: gtk_applicationsdir)
|
||||
|
||||
# icons
|
||||
icontheme_dir = join_paths(gtk_datadir, 'icons/hicolor')
|
||||
|
@@ -353,7 +353,6 @@ update_pulse_time (GtkAdjustment *adjustment, GtkWidget *widget)
|
||||
static void
|
||||
on_entry_icon_release (GtkEntry *entry,
|
||||
GtkEntryIconPosition icon_pos,
|
||||
GdkEvent *event,
|
||||
gpointer user_data)
|
||||
{
|
||||
if (icon_pos != GTK_ENTRY_ICON_SECONDARY)
|
||||
@@ -967,8 +966,8 @@ background_loaded_cb (GObject *source,
|
||||
return;
|
||||
}
|
||||
|
||||
child = gtk_image_new_from_pixbuf (pixbuf);
|
||||
gtk_widget_show (child);
|
||||
child = gtk_picture_new_for_pixbuf (pixbuf);
|
||||
gtk_widget_set_size_request (child, 110, 70);
|
||||
gtk_flow_box_insert (GTK_FLOW_BOX (bd->flowbox), child, -1);
|
||||
child = gtk_widget_get_parent (child);
|
||||
g_object_set_data_full (G_OBJECT (child), "filename", bd->filename, g_free);
|
||||
@@ -996,8 +995,7 @@ populate_flowbox (GtkWidget *flowbox)
|
||||
|
||||
pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, 110, 70);
|
||||
gdk_pixbuf_fill (pixbuf, 0xffffffff);
|
||||
child = gtk_image_new_from_pixbuf (pixbuf);
|
||||
gtk_widget_show (child);
|
||||
child = gtk_picture_new_for_pixbuf (pixbuf);
|
||||
gtk_flow_box_insert (GTK_FLOW_BOX (flowbox), child, -1);
|
||||
|
||||
location = "/usr/share/backgrounds/gnome";
|
||||
@@ -1082,7 +1080,7 @@ set_accel (GtkApplication *app, GtkWidget *widget)
|
||||
typedef struct
|
||||
{
|
||||
GtkTextView tv;
|
||||
GdkPixbuf *pixbuf;
|
||||
GdkTexture *texture;
|
||||
} MyTextView;
|
||||
|
||||
typedef GtkTextViewClass MyTextViewClass;
|
||||
@@ -1095,18 +1093,23 @@ my_text_view_init (MyTextView *tv)
|
||||
}
|
||||
|
||||
static void
|
||||
my_tv_draw_layer (GtkTextView *widget,
|
||||
GtkTextViewLayer layer,
|
||||
cairo_t *cr)
|
||||
my_tv_snapshot_layer (GtkTextView *widget,
|
||||
GtkTextViewLayer layer,
|
||||
GtkSnapshot *snapshot)
|
||||
{
|
||||
MyTextView *tv = (MyTextView *)widget;
|
||||
|
||||
if (layer == GTK_TEXT_VIEW_LAYER_BELOW_TEXT && tv->pixbuf)
|
||||
if (layer == GTK_TEXT_VIEW_LAYER_BELOW_TEXT && tv->texture)
|
||||
{
|
||||
cairo_save (cr);
|
||||
gdk_cairo_set_source_pixbuf (cr, tv->pixbuf, 0.0, 0.0);
|
||||
cairo_paint_with_alpha (cr, 0.333);
|
||||
cairo_restore (cr);
|
||||
gtk_snapshot_push_opacity (snapshot, 0.333);
|
||||
gtk_snapshot_append_texture (snapshot,
|
||||
tv->texture,
|
||||
&GRAPHENE_RECT_INIT(
|
||||
0, 0,
|
||||
gdk_texture_get_width (tv->texture),
|
||||
gdk_texture_get_height (tv->texture)
|
||||
));
|
||||
gtk_snapshot_pop (snapshot);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1115,7 +1118,7 @@ my_tv_finalize (GObject *object)
|
||||
{
|
||||
MyTextView *tv = (MyTextView *)object;
|
||||
|
||||
g_clear_object (&tv->pixbuf);
|
||||
g_clear_object (&tv->texture);
|
||||
|
||||
G_OBJECT_CLASS (my_text_view_parent_class)->finalize (object);
|
||||
}
|
||||
@@ -1127,20 +1130,24 @@ my_text_view_class_init (MyTextViewClass *class)
|
||||
GObjectClass *o_class = G_OBJECT_CLASS (class);
|
||||
|
||||
o_class->finalize = my_tv_finalize;
|
||||
tv_class->draw_layer = my_tv_draw_layer;
|
||||
tv_class->snapshot_layer = my_tv_snapshot_layer;
|
||||
}
|
||||
|
||||
static void
|
||||
my_text_view_set_background (MyTextView *tv, const gchar *filename)
|
||||
{
|
||||
GError *error = NULL;
|
||||
GFile *file;
|
||||
|
||||
g_clear_object (&tv->pixbuf);
|
||||
g_clear_object (&tv->texture);
|
||||
|
||||
if (filename == NULL)
|
||||
return;
|
||||
|
||||
tv->pixbuf = gdk_pixbuf_new_from_file (filename, &error);
|
||||
file = g_file_new_for_path (filename);
|
||||
tv->texture = gdk_texture_new_from_file (file, &error);
|
||||
g_object_unref (file);
|
||||
|
||||
if (error)
|
||||
{
|
||||
g_warning ("%s", error->message);
|
||||
|
@@ -6,9 +6,6 @@
|
||||
<gresource prefix="/org/gtk/WidgetFactory">
|
||||
<file>widget-factory.css</file>
|
||||
</gresource>
|
||||
<gresource prefix="/org/gtk/WidgetFactory/gtk">
|
||||
<file preprocess="xml-stripblanks">menus.ui</file>
|
||||
</gresource>
|
||||
<gresource prefix="/org/gtk/WidgetFactory/gtk">
|
||||
<file preprocess="xml-stripblanks">help-overlay.ui</file>
|
||||
</gresource>
|
||||
|
@@ -16,6 +16,16 @@
|
||||
<attribute name="action">win.transition</attribute>
|
||||
</item>
|
||||
</section>
|
||||
<section>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">_Keyboard Shortcuts</attribute>
|
||||
<attribute name="action">win.show-help-overlay</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">_About Widget Factory</attribute>
|
||||
<attribute name="action">app.about</attribute>
|
||||
</item>
|
||||
</section>
|
||||
</menu>
|
||||
<menu id="dinner_menu">
|
||||
<section>
|
||||
@@ -396,6 +406,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
</columns>
|
||||
</object>
|
||||
<object class="GtkApplicationWindow" id="window">
|
||||
<style><class name="devel"/></style>
|
||||
<property name="title">GTK+ Widget Factory</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar" id="headerbar1">
|
||||
@@ -2226,6 +2237,9 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
<property name="tooltip-text" translatable="yes">Save the current document</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparatorToolItem"/>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToolButton">
|
||||
<property name="label" translatable="yes">Search</property>
|
||||
|
@@ -71,7 +71,7 @@ straightforward manner.
|
||||
void gdk_drag_status (GdkDragContext *context,
|
||||
GdkDragAction action,
|
||||
guint32 time);
|
||||
void gdk_drop_finish (GdkDragContext *context,
|
||||
void gdk_drag_finish (GdkDragContext *context,
|
||||
gboolean success,
|
||||
guint32 time);
|
||||
GdkAtom gdk_drag_get_selection (GdkDragContext *context);
|
||||
|
@@ -171,7 +171,6 @@ gdk_rgba_get_type
|
||||
<FILE>gdksurface</FILE>
|
||||
GdkSurface
|
||||
GdkSurfaceType
|
||||
GdkSurfaceClass
|
||||
GdkSurfaceHints
|
||||
GdkGeometry
|
||||
GdkGravity
|
||||
@@ -194,7 +193,6 @@ gdk_surface_is_visible
|
||||
gdk_surface_is_viewable
|
||||
gdk_surface_is_input_only
|
||||
gdk_surface_get_state
|
||||
gdk_surface_withdraw
|
||||
gdk_surface_iconify
|
||||
gdk_surface_deiconify
|
||||
gdk_surface_stick
|
||||
@@ -282,8 +280,6 @@ gdk_surface_get_toplevel
|
||||
gdk_surface_get_children
|
||||
gdk_surface_get_children_with_user_data
|
||||
gdk_surface_peek_children
|
||||
gdk_surface_get_events
|
||||
gdk_surface_set_events
|
||||
gdk_surface_set_icon_name
|
||||
gdk_surface_set_transient_for
|
||||
gdk_surface_set_role
|
||||
@@ -301,8 +297,6 @@ gdk_surface_get_support_multidevice
|
||||
gdk_surface_set_support_multidevice
|
||||
gdk_surface_get_device_cursor
|
||||
gdk_surface_set_device_cursor
|
||||
gdk_surface_get_device_events
|
||||
gdk_surface_set_device_events
|
||||
|
||||
<SUBSECTION>
|
||||
gdk_surface_coords_from_parent
|
||||
@@ -652,7 +646,7 @@ gdk_event_get_scancode
|
||||
gdk_event_get_pointer_emulated
|
||||
gdk_event_get_crossing_detail
|
||||
gdk_event_get_crossing_mode
|
||||
gdk_event_get_drag_context
|
||||
gdk_event_get_drop
|
||||
gdk_event_get_focus_in
|
||||
gdk_event_get_grab_surface
|
||||
gdk_event_get_motion_history
|
||||
@@ -661,7 +655,6 @@ gdk_event_get_key_is_modifier
|
||||
gdk_event_get_pad_axis_value
|
||||
gdk_event_get_pad_button
|
||||
gdk_event_get_pad_group_mode
|
||||
gdk_event_get_string
|
||||
gdk_event_get_touch_emulating_pointer
|
||||
gdk_event_get_touchpad_angle_delta
|
||||
gdk_event_get_touchpad_deltas
|
||||
@@ -698,7 +691,7 @@ gdk_event_get_type
|
||||
|
||||
<SECTION>
|
||||
<FILE>gdkpaintable</FILE>
|
||||
<TITLE>GdkPaintable/TITLE>
|
||||
<TITLE>GdkPaintable</TITLE>
|
||||
GdkPaintable
|
||||
GdkPaintableFlags
|
||||
gdk_paintable_get_current_image
|
||||
@@ -779,38 +772,60 @@ gdk_cursor_get_type
|
||||
<SECTION>
|
||||
<TITLE>Drag and Drop</TITLE>
|
||||
<FILE>dnd</FILE>
|
||||
GdkDragContext
|
||||
GdkDrag
|
||||
GdkDrop
|
||||
GdkDragCancelReason
|
||||
gdk_drag_drop_done
|
||||
gdk_drag_begin
|
||||
gdk_drop_finish
|
||||
GdkDragAction
|
||||
gdk_drag_status
|
||||
GDK_ACTION_ALL
|
||||
|
||||
gdk_drag_context_get_display
|
||||
gdk_drag_context_get_actions
|
||||
gdk_drag_context_get_suggested_action
|
||||
gdk_drag_context_get_selected_action
|
||||
gdk_drag_context_get_formats
|
||||
gdk_drag_context_get_device
|
||||
gdk_drag_context_get_source_surface
|
||||
gdk_drag_context_get_dest_surface
|
||||
gdk_drag_context_get_drag_surface
|
||||
gdk_drag_context_set_hotspot
|
||||
gdk_drag_get_display
|
||||
gdk_drag_get_actions
|
||||
gdk_drag_get_suggested_action
|
||||
gdk_drag_get_selected_action
|
||||
gdk_drag_get_formats
|
||||
gdk_drag_get_device
|
||||
gdk_drag_get_drag_surface
|
||||
gdk_drag_set_hotspot
|
||||
|
||||
<SUBSECTION>
|
||||
gdk_drag_action_is_unique
|
||||
|
||||
<SUBSECTION>
|
||||
gdk_drop_get_display
|
||||
gdk_drop_get_device
|
||||
gdk_drop_get_surface
|
||||
gdk_drop_get_formats
|
||||
gdk_drop_get_actions
|
||||
gdk_drop_get_drag
|
||||
gdk_drop_status
|
||||
gdk_drop_finish
|
||||
gdk_drop_read_async
|
||||
gdk_drop_read_finish
|
||||
gdk_drop_read_value_async
|
||||
gdk_drop_read_value_finish
|
||||
gdk_drop_read_text_async
|
||||
gdk_drop_read_text_finish
|
||||
|
||||
<SUBSECTION Standard>
|
||||
GDK_DRAG_CONTEXT
|
||||
GDK_TYPE_DRAG_CONTEXT
|
||||
GDK_IS_DRAG_CONTEXT
|
||||
GDK_DRAG_CONTEXT_CLASS
|
||||
GDK_DRAG_CONTEXT_GET_CLASS
|
||||
GDK_IS_DRAG_CONTEXT_CLASS
|
||||
GDK_DRAG
|
||||
GDK_TYPE_DRAG
|
||||
GDK_IS_DRAG
|
||||
GDK_DRAG_CLASS
|
||||
GDK_DRAG_GET_CLASS
|
||||
GDK_IS_DRAG_CLASS
|
||||
GDK_TYPE_DRAG_ACTION
|
||||
GDK_TYPE_DRAG_PROTOCOL
|
||||
GDK_TYPE_DROP
|
||||
GDK_DROP
|
||||
GDK_IS_DROP
|
||||
|
||||
<SUBSECTION Private>
|
||||
GdkDragContextClass
|
||||
gdk_drag_context_get_type
|
||||
GdkDragClass
|
||||
gdk_drag_get_type
|
||||
GdkDropClass
|
||||
gdk_drop_get_type
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
@@ -853,7 +868,6 @@ gdk_x11_screen_lookup_visual
|
||||
gdk_x11_screen_supports_net_wm_hint
|
||||
gdk_x11_screen_get_number_of_desktops
|
||||
gdk_x11_screen_get_current_desktop
|
||||
gdk_x11_surface_foreign_new_for_display
|
||||
gdk_x11_surface_lookup_for_display
|
||||
gdk_x11_surface_get_xid
|
||||
gdk_x11_surface_set_theme_variant
|
||||
@@ -1250,6 +1264,7 @@ gdk_clipboard_get_type
|
||||
<SECTION>
|
||||
<FILE>gdkcontentprovider</FILE>
|
||||
GdkContentProvider
|
||||
GdkContentProviderClass
|
||||
gdk_content_provider_new_for_value
|
||||
gdk_content_provider_new_for_bytes
|
||||
gdk_content_provider_ref_formats
|
||||
@@ -1265,7 +1280,6 @@ GDK_CONTENT_PROVIDER_CLASS
|
||||
GDK_CONTENT_PROVIDER_GET_CLASS
|
||||
GDK_IS_CONTENT_PROVIDER
|
||||
GDK_IS_CONTENT_PROVIDER_CLASS
|
||||
GdkContentProviderClass
|
||||
gdk_content_provider_get_type
|
||||
</SECTION>
|
||||
|
||||
|
@@ -2,6 +2,7 @@ gdk_app_launch_context_get_type
|
||||
gdk_clipboard_get_type
|
||||
gdk_content_deserializer_get_type
|
||||
gdk_content_formats_get_type
|
||||
gdk_content_provider_get_type
|
||||
gdk_content_serializer_get_type
|
||||
gdk_cursor_get_type
|
||||
gdk_device_get_type
|
||||
@@ -9,7 +10,8 @@ gdk_device_pad_get_type
|
||||
gdk_device_tool_get_type
|
||||
gdk_display_get_type
|
||||
gdk_display_manager_get_type
|
||||
gdk_drag_context_get_type
|
||||
gdk_drag_get_type
|
||||
gdk_drop_get_type
|
||||
gdk_event_get_type
|
||||
gdk_frame_clock_get_type
|
||||
gdk_gl_context_get_type
|
||||
|
@@ -87,16 +87,22 @@ images = [
|
||||
'images/zoom_out_cursor.png',
|
||||
]
|
||||
|
||||
src_dir = [ gdkinc ]
|
||||
|
||||
if x11_enabled
|
||||
src_dir += [ gdkx11_inc ]
|
||||
endif
|
||||
|
||||
if wayland_enabled
|
||||
src_dir += [ gdkwayland_inc ]
|
||||
endif
|
||||
|
||||
configure_file(input: 'version.xml.in', output: 'version.xml', configuration: version_conf)
|
||||
|
||||
gnome.gtkdoc('gdk4',
|
||||
mode: 'none',
|
||||
main_xml: 'gdk4-docs.xml',
|
||||
src_dir: [
|
||||
gdkinc,
|
||||
gdkx11_inc,
|
||||
gdkwayland_inc,
|
||||
],
|
||||
src_dir: src_dir,
|
||||
dependencies: libgtk_dep,
|
||||
gobject_typesfile: join_paths(meson.current_source_dir(), 'gdk4.types'),
|
||||
scan_args: [
|
||||
|
@@ -44,7 +44,7 @@
|
||||
|
||||
<informalexample>
|
||||
<para>Create a new file with the following content named <filename>example-0.c.</filename></para>
|
||||
<programlisting><xi:include href="../../../../examples/window-default.c" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
|
||||
<programlisting><xi:include href="@SRC_DIR@/examples/window-default.c" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
|
||||
</informalexample>
|
||||
|
||||
<para>
|
||||
@@ -120,7 +120,7 @@
|
||||
here</ulink>.</para>
|
||||
|
||||
<para>Finally the window size is set using gtk_window_set_default_size and
|
||||
the window is then shown by GTK via gtk_widget_show_all().</para>
|
||||
the window is then shown by GTK via gtk_widget_show().</para>
|
||||
|
||||
<para>When you exit the window, by for example pressing the X,
|
||||
the g_application_run() in the main loop returns with a number
|
||||
@@ -153,7 +153,7 @@
|
||||
<example id="gtk-getting-started-hello-world">
|
||||
<title>Hello World in GTK+</title>
|
||||
<para>Create a new file with the following content named example-1.c.</para>
|
||||
<programlisting><xi:include href="../../../../examples/hello-world.c" parse="text">
|
||||
<programlisting><xi:include href="@SRC_DIR@/examples/hello-world.c" parse="text">
|
||||
<xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
|
||||
</example>
|
||||
|
||||
@@ -233,7 +233,7 @@
|
||||
<example id="gtk-getting-started-grid-packing">
|
||||
<title>Packing buttons</title>
|
||||
<para>Create a new file with the following content named example-2.c.</para>
|
||||
<programlisting><xi:include href="../../../../examples/grid-packing.c" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
|
||||
<programlisting><xi:include href="@SRC_DIR@/examples/grid-packing.c" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
|
||||
</example>
|
||||
<para>
|
||||
You can compile the program above with GCC using:
|
||||
@@ -257,9 +257,9 @@
|
||||
<example>
|
||||
<title>Packing buttons with GtkBuilder</title>
|
||||
<para>Create a new file with the following content named example-3.c.</para>
|
||||
<programlisting><xi:include href="../../../../examples/builder.c" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
|
||||
<programlisting><xi:include href="@SRC_DIR@/examples/builder.c" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
|
||||
<para>Create a new file with the following content named builder.ui.</para>
|
||||
<programlisting><xi:include href="../../../../examples/builder.ui" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
|
||||
<programlisting><xi:include href="@SRC_DIR@/examples/builder.ui" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
|
||||
</example>
|
||||
<para>
|
||||
You can compile the program above with GCC using:
|
||||
@@ -346,7 +346,7 @@
|
||||
of our application class.</para>
|
||||
|
||||
<informalexample>
|
||||
<programlisting><xi:include href="../../../../examples/application1/main.c" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
|
||||
<programlisting><xi:include href="@SRC_DIR@/examples/application1/main.c" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
|
||||
</informalexample>
|
||||
|
||||
<para>All the application logic is in the application class, which
|
||||
@@ -364,7 +364,7 @@
|
||||
GIO <ulink url="https://developer.gnome.org/gio/2.36/GApplication.html#GApplication.description">documentation</ulink>.</para>
|
||||
|
||||
<informalexample>
|
||||
<programlisting><xi:include href="../../../../examples/application1/exampleapp.c" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
|
||||
<programlisting><xi:include href="@SRC_DIR@/examples/application1/exampleapp.c" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
|
||||
</informalexample>
|
||||
|
||||
<para>Another important class that is part of the application support
|
||||
@@ -373,7 +373,7 @@
|
||||
window.</para>
|
||||
|
||||
<informalexample>
|
||||
<programlisting><xi:include href="../../../../examples/application1/exampleappwin.c" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
|
||||
<programlisting><xi:include href="@SRC_DIR@/examples/application1/exampleappwin.c" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
|
||||
</informalexample>
|
||||
|
||||
<para>As part of the initial setup of our application, we also
|
||||
@@ -388,7 +388,7 @@
|
||||
</informalfigure>
|
||||
|
||||
<informalexample>
|
||||
<programlisting><xi:include href="../../../../examples/application1/exampleapp.desktop" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
|
||||
<programlisting><xi:include href="@SRC_DIR@/examples/application1/org.gtk.exampleapp.desktop" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
|
||||
</informalexample>
|
||||
|
||||
<para>Note that <replaceable>@<!-- -->bindir@</replaceable> needs to be replaced
|
||||
@@ -420,7 +420,7 @@
|
||||
</para>
|
||||
|
||||
<informalexample>
|
||||
<programlisting><xi:include href="../../../../examples/application2/window.ui" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
|
||||
<programlisting><xi:include href="@SRC_DIR@/examples/application2/window.ui" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
|
||||
</informalexample>
|
||||
|
||||
<para>To make use of this file in our application, we revisit
|
||||
@@ -460,7 +460,7 @@ example_app_window_class_init (ExampleAppWindowClass *class)
|
||||
</para>
|
||||
|
||||
<informalexample>
|
||||
<programlisting><xi:include href="../../../../examples/application2/exampleapp.gresource.xml" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
|
||||
<programlisting><xi:include href="@SRC_DIR@/examples/application2/exampleapp.gresource.xml" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
|
||||
</informalexample>
|
||||
|
||||
<para>This file has to be converted into a C source file that will be
|
||||
@@ -488,23 +488,28 @@ example_app_window_class_init (ExampleAppWindowClass *class)
|
||||
<para>In this step, we make our application show the content of
|
||||
all the files that it is given on the commandline.</para>
|
||||
|
||||
<para>To this end, we add a private struct to our application
|
||||
<para>To this end, we add a member to the struct in application
|
||||
window subclass and keep a reference to the #GtkStack there.
|
||||
The gtk_widget_class_bind_template_child_private() function
|
||||
The first member of the struct should be the parent type from
|
||||
which the class is derived. Here, ExampleAppWindow is derived
|
||||
from GtkApplicationWindow.
|
||||
The gtk_widget_class_bind_template_child() function
|
||||
arranges things so that after instantiating the template, the
|
||||
@stack member of the private struct will point to the widget of
|
||||
@stack member of the struct will point to the widget of
|
||||
the same name from the template.</para>
|
||||
|
||||
<informalexample>
|
||||
<programlisting><![CDATA[
|
||||
...
|
||||
|
||||
struct _ExampleAppWindowPrivate
|
||||
struct _ExampleAppWindow
|
||||
{
|
||||
GtkApplicationWindow parent;
|
||||
|
||||
GtkWidget *stack;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE(ExampleAppWindow, example_app_window, GTK_TYPE_APPLICATION_WINDOW);
|
||||
G_DEFINE_TYPE (ExampleAppWindow, example_app_window, GTK_TYPE_APPLICATION_WINDOW)
|
||||
|
||||
...
|
||||
|
||||
@@ -513,7 +518,7 @@ example_app_window_class_init (ExampleAppWindowClass *class)
|
||||
{
|
||||
gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
|
||||
"/org/gtk/exampleapp/window.ui");
|
||||
gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (class), ExampleAppWindow, stack);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), ExampleAppWindow, stack);
|
||||
}
|
||||
|
||||
...
|
||||
@@ -533,25 +538,21 @@ void
|
||||
example_app_window_open (ExampleAppWindow *win,
|
||||
GFile *file)
|
||||
{
|
||||
ExampleAppWindowPrivate *priv;
|
||||
gchar *basename;
|
||||
GtkWidget *scrolled, *view;
|
||||
gchar *contents;
|
||||
gsize length;
|
||||
|
||||
priv = example_app_window_get_instance_private (win);
|
||||
basename = g_file_get_basename (file);
|
||||
|
||||
scrolled = gtk_scrolled_window_new (NULL, NULL);
|
||||
gtk_widget_show (scrolled);
|
||||
gtk_widget_set_hexpand (scrolled, TRUE);
|
||||
gtk_widget_set_vexpand (scrolled, TRUE);
|
||||
view = gtk_text_view_new ();
|
||||
gtk_text_view_set_editable (GTK_TEXT_VIEW (view), FALSE);
|
||||
gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (view), FALSE);
|
||||
gtk_widget_show (view);
|
||||
gtk_container_add (GTK_CONTAINER (scrolled), view);
|
||||
gtk_stack_add_titled (GTK_STACK (priv->stack), scrolled, basename, basename);
|
||||
gtk_stack_add_titled (GTK_STACK (win->stack), scrolled, basename, basename);
|
||||
|
||||
if (g_file_load_contents (file, NULL, &contents, &length, NULL, NULL))
|
||||
{
|
||||
@@ -598,7 +599,7 @@ example_app_window_open (ExampleAppWindow *win,
|
||||
in a ui file, and add it as a resource to our binary.</para>
|
||||
|
||||
<informalexample>
|
||||
<programlisting><xi:include href="../../../../examples/application4/app-menu.ui" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
|
||||
<programlisting><xi:include href="@SRC_DIR@/examples/application4/app-menu.ui" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
|
||||
</informalexample>
|
||||
|
||||
<para>To associate the app menu with the application, we have to call
|
||||
@@ -697,7 +698,7 @@ example_app_class_init (ExampleAppClass *class)
|
||||
GSettings requires a schema that describes our settings:</para>
|
||||
|
||||
<informalexample>
|
||||
<programlisting><xi:include href="../../../../examples/application5/org.gtk.exampleapp.gschema.xml" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
|
||||
<programlisting><xi:include href="@SRC_DIR@/examples/application5/org.gtk.exampleapp.gschema.xml" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
|
||||
</informalexample>
|
||||
|
||||
<para>Before we can make use of this schema in our application,
|
||||
@@ -718,14 +719,11 @@ example_app_class_init (ExampleAppClass *class)
|
||||
static void
|
||||
example_app_window_init (ExampleAppWindow *win)
|
||||
{
|
||||
ExampleAppWindowPrivate *priv;
|
||||
|
||||
priv = example_app_window_get_instance_private (win);
|
||||
gtk_widget_init_template (GTK_WIDGET (win));
|
||||
priv->settings = g_settings_new ("org.gtk.exampleapp");
|
||||
win->settings = g_settings_new ("org.gtk.exampleapp");
|
||||
|
||||
g_settings_bind (priv->settings, "transition",
|
||||
priv->stack, "transition-type",
|
||||
g_settings_bind (win->settings, "transition",
|
||||
win->stack, "transition-type",
|
||||
G_SETTINGS_BIND_DEFAULT);
|
||||
}
|
||||
|
||||
@@ -749,13 +747,13 @@ example_app_window_init (ExampleAppWindow *win)
|
||||
<para>Lets start with the template.</para>
|
||||
|
||||
<informalexample>
|
||||
<programlisting><xi:include href="../../../../examples/application6/prefs.ui" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
|
||||
<programlisting><xi:include href="@SRC_DIR@/examples/application6/prefs.ui" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
|
||||
</informalexample>
|
||||
|
||||
<para>Next comes the dialog subclass.</para>
|
||||
|
||||
<informalexample>
|
||||
<programlisting><xi:include href="../../../../examples/application6/exampleappprefs.c" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
|
||||
<programlisting><xi:include href="@SRC_DIR@/examples/application6/exampleappprefs.c" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
|
||||
</informalexample>
|
||||
|
||||
<para>Now we revisit the <literal>preferences_activated(<!-- -->)</literal> function in our
|
||||
@@ -807,7 +805,7 @@ preferences_activated (GSimpleAction *action,
|
||||
to slide out the search bar below the header bar.</para>
|
||||
|
||||
<informalexample>
|
||||
<programlisting><xi:include href="../../../../examples/application7/window.ui" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
|
||||
<programlisting><xi:include href="@SRC_DIR@/examples/application7/window.ui" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
|
||||
</informalexample>
|
||||
|
||||
<para>Implementing the search needs quite a few code changes that
|
||||
@@ -823,7 +821,6 @@ static void
|
||||
search_text_changed (GtkEntry *entry,
|
||||
ExampleAppWindow *win)
|
||||
{
|
||||
ExampleAppWindowPrivate *priv;
|
||||
const gchar *text;
|
||||
GtkWidget *tab;
|
||||
GtkWidget *view;
|
||||
@@ -835,9 +832,7 @@ search_text_changed (GtkEntry *entry,
|
||||
if (text[0] == '\0')
|
||||
return;
|
||||
|
||||
priv = example_app_window_get_instance_private (win);
|
||||
|
||||
tab = gtk_stack_get_visible_child (GTK_STACK (priv->stack));
|
||||
tab = gtk_stack_get_visible_child (GTK_STACK (win->stack));
|
||||
view = gtk_bin_get_child (GTK_BIN (tab));
|
||||
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
|
||||
|
||||
@@ -887,7 +882,7 @@ example_app_window_init (ExampleAppWindow *win)
|
||||
which demonstrates #GtkMenuButton, #GtkRevealer and #GtkListBox.</para>
|
||||
|
||||
<informalexample>
|
||||
<programlisting><xi:include href="../../../../examples/application8/window.ui" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
|
||||
<programlisting><xi:include href="@SRC_DIR@/examples/application8/window.ui" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
|
||||
</informalexample>
|
||||
|
||||
<para>The code to populate the sidebar with buttons for the words
|
||||
@@ -898,7 +893,7 @@ example_app_window_init (ExampleAppWindow *win)
|
||||
ui file.</para>
|
||||
|
||||
<informalexample>
|
||||
<programlisting><xi:include href="../../../../examples/application8/gears-menu.ui" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
|
||||
<programlisting><xi:include href="@SRC_DIR@/examples/application8/gears-menu.ui" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
|
||||
</informalexample>
|
||||
|
||||
<para>To connect the menuitem to the show-words setting, we use
|
||||
@@ -957,7 +952,7 @@ example_app_window_init (ExampleAppWindow *win)
|
||||
triggers the show-lines action:</para>
|
||||
|
||||
<informalexample>
|
||||
<programlisting><xi:include href="../../../../examples/application9/gears-menu.ui" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
|
||||
<programlisting><xi:include href="@SRC_DIR@/examples/application9/gears-menu.ui" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
|
||||
</informalexample>
|
||||
|
||||
<para>To make this menu item do something, we create a property
|
||||
@@ -978,12 +973,12 @@ example_app_window_init (ExampleAppWindow *win)
|
||||
{
|
||||
...
|
||||
|
||||
action = (GAction*) g_property_action_new ("show-lines", priv->lines, "visible");
|
||||
action = (GAction*) g_property_action_new ("show-lines", win->lines, "visible");
|
||||
g_action_map_add_action (G_ACTION_MAP (win), action);
|
||||
g_object_unref (action);
|
||||
|
||||
g_object_bind_property (priv->lines, "visible",
|
||||
priv->lines_label, "visible",
|
||||
g_object_bind_property (win->lines, "visible",
|
||||
win->lines_label, "visible",
|
||||
G_BINDING_DEFAULT);
|
||||
}
|
||||
|
||||
@@ -1017,7 +1012,7 @@ example_app_window_init (ExampleAppWindow *win)
|
||||
be a direct child of the window, and set its type to be titlebar.</para>
|
||||
|
||||
<informalexample>
|
||||
<programlisting><xi:include href="../../../../examples/application10/window.ui" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
|
||||
<programlisting><xi:include href="@SRC_DIR@/examples/application10/window.ui" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
|
||||
</informalexample>
|
||||
|
||||
<para>A small extra bonus of using a header bar is that we get
|
||||
@@ -1073,7 +1068,7 @@ example_app_window_init (ExampleAppWindow *win)
|
||||
<example id="gtk-getting-started-drawing">
|
||||
<title>Drawing in response to input</title>
|
||||
<para>Create a new file with the following content named example-4.c.</para>
|
||||
<programlisting><xi:include href="../../../../examples/drawing.c" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
|
||||
<programlisting><xi:include href="@SRC_DIR@/examples/drawing.c" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
|
||||
</example>
|
||||
<para>
|
||||
You can compile the program above with GCC using:
|
@@ -41,6 +41,16 @@
|
||||
<xi:include href="visual_index.xml" />
|
||||
</chapter>
|
||||
|
||||
<chapter id="Lists">
|
||||
<title>GListModel support</title>
|
||||
<xi:include href="xml/gtkfilterlistmodel.xml" />
|
||||
<xi:include href="xml/gtkflattenlistmodel.xml" />
|
||||
<xi:include href="xml/gtkmaplistmodel.xml" />
|
||||
<xi:include href="xml/gtkslicelistmodel.xml" />
|
||||
<xi:include href="xml/gtksortlistmodel.xml" />
|
||||
<xi:include href="xml/gtktreelistmodel.xml" />
|
||||
</chapter>
|
||||
|
||||
<chapter id="Application">
|
||||
<title>Application support</title>
|
||||
<xi:include href="xml/gtkapplication.xml" />
|
||||
@@ -152,6 +162,7 @@
|
||||
<chapter id="TreeWidgetObjects">
|
||||
<title>Tree, List and Icon Grid Widgets</title>
|
||||
<xi:include href="xml/tree_widget.sgml" />
|
||||
<xi:include href="xml/treeview_tutorial.xml" />
|
||||
<xi:include href="xml/gtktreemodel.xml" />
|
||||
<xi:include href="xml/gtktreeselection.xml" />
|
||||
<xi:include href="xml/gtktreeviewcolumn.xml" />
|
||||
@@ -301,6 +312,7 @@
|
||||
<title>Gestures and event handling</title>
|
||||
<xi:include href="xml/gtkeventcontroller.xml" />
|
||||
<xi:include href="xml/gtkeventcontrollerkey.xml" />
|
||||
<xi:include href="xml/gtkeventcontrollerlegacy.xml" />
|
||||
<xi:include href="xml/gtkeventcontrollerscroll.xml" />
|
||||
<xi:include href="xml/gtkeventcontrollermotion.xml" />
|
||||
<xi:include href="xml/gtkgesture.xml" />
|
||||
@@ -385,7 +397,6 @@
|
||||
<xi:include href="osx.sgml" />
|
||||
<xi:include href="broadway.xml" />
|
||||
<xi:include href="wayland.xml" />
|
||||
<xi:include href="mir.xml" />
|
||||
</part>
|
||||
|
||||
<xi:include href="glossary.xml" />
|
||||
|
@@ -679,8 +679,6 @@ gtk_combo_box_get_active_id
|
||||
gtk_combo_box_set_active_id
|
||||
gtk_combo_box_get_model
|
||||
gtk_combo_box_set_model
|
||||
gtk_combo_box_popup_for_device
|
||||
gtk_combo_box_popup
|
||||
gtk_combo_box_popdown
|
||||
gtk_combo_box_get_popup_accessible
|
||||
gtk_combo_box_get_row_separator_func
|
||||
@@ -760,9 +758,6 @@ gtk_container_child_set_valist
|
||||
gtk_container_child_notify
|
||||
gtk_container_child_notify_by_pspec
|
||||
gtk_container_forall
|
||||
gtk_container_get_focus_chain
|
||||
gtk_container_set_focus_chain
|
||||
gtk_container_unset_focus_chain
|
||||
gtk_container_class_find_child_property
|
||||
gtk_container_class_install_child_property
|
||||
gtk_container_class_install_child_properties
|
||||
@@ -1244,6 +1239,26 @@ GTK_TYPE_FILE_FILTER
|
||||
gtk_file_filter_get_type
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>gtkfilterlistmodel</FILE>
|
||||
<TITLE>GtkFilterListModel</TITLE>
|
||||
GtkFilterListModel
|
||||
gtk_filter_list_model_new
|
||||
gtk_filter_list_model_get_model
|
||||
gtk_filter_list_model_set_filter_func
|
||||
gtk_filter_list_model_has_filter
|
||||
gtk_filter_list_model_refilter
|
||||
<SUBSECTION Standard>
|
||||
GTK_FILTER_LIST_MODEL
|
||||
GTK_IS_FILTER_LIST_MODEL
|
||||
GTK_TYPE_FILTER_LIST_MODEL
|
||||
GTK_FILTER_LIST_MODEL_CLASS
|
||||
GTK_IS_FILTER_LIST_MODEL_CLASS
|
||||
GTK_FILTER_LIST_MODEL_GET_CLASS
|
||||
<SUBSECTION Private>
|
||||
gtk_filter_list_model_get_type
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>gtkfixed</FILE>
|
||||
<TITLE>GtkFixed</TITLE>
|
||||
@@ -1264,6 +1279,24 @@ GtkFixedChild
|
||||
gtk_fixed_get_type
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>gtkflattenlistmodel</FILE>
|
||||
<TITLE>GtkFlattenListModel</TITLE>
|
||||
GtkFlattenListModel
|
||||
gtk_flatten_list_model_new
|
||||
gtk_flatten_list_model_set_model
|
||||
gtk_flatten_list_model_get_model
|
||||
<SUBSECTION Standard>
|
||||
GTK_FLATTEN_LIST_MODEL
|
||||
GTK_IS_FLATTEN_LIST_MODEL
|
||||
GTK_TYPE_FLATTEN_LIST_MODEL
|
||||
GTK_FLATTEN_LIST_MODEL_CLASS
|
||||
GTK_IS_FLATTEN_LIST_MODEL_CLASS
|
||||
GTK_FLATTEN_LIST_MODEL_GET_CLASS
|
||||
<SUBSECTION Private>
|
||||
gtk_flatten_list_model_get_type
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>gtkfontbutton</FILE>
|
||||
<TITLE>GtkFontButton</TITLE>
|
||||
@@ -1711,6 +1744,27 @@ GtkLinkButtonPrivate
|
||||
gtk_link_button_get_type
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>gtkmaplistmodel</FILE>
|
||||
<TITLE>GtkMapListModel</TITLE>
|
||||
GtkMapListModel
|
||||
GtkMapListModelMapFunc
|
||||
gtk_map_list_model_new
|
||||
gtk_map_list_model_set_map_func
|
||||
gtk_map_list_model_set_model
|
||||
gtk_map_list_model_get_model
|
||||
gtk_map_list_model_has_map
|
||||
<SUBSECTION Standard>
|
||||
GTK_MAP_LIST_MODEL
|
||||
GTK_IS_MAP_LIST_MODEL
|
||||
GTK_TYPE_MAP_LIST_MODEL
|
||||
GTK_MAP_LIST_MODEL_CLASS
|
||||
GTK_IS_MAP_LIST_MODEL_CLASS
|
||||
GTK_MAP_LIST_MODEL_GET_CLASS
|
||||
<SUBSECTION Private>
|
||||
gtk_map_list_model_get_type
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>gtkmenu</FILE>
|
||||
<TITLE>GtkMenu</TITLE>
|
||||
@@ -1724,8 +1778,6 @@ gtk_menu_attach
|
||||
gtk_menu_popup_at_rect
|
||||
gtk_menu_popup_at_widget
|
||||
gtk_menu_popup_at_pointer
|
||||
gtk_menu_popup_for_device
|
||||
gtk_menu_popup
|
||||
gtk_menu_set_accel_group
|
||||
gtk_menu_get_accel_group
|
||||
gtk_menu_set_accel_path
|
||||
@@ -2541,6 +2593,51 @@ GtkSizeGroupPrivate
|
||||
gtk_size_group_get_type
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>gtkslicelistmodel</FILE>
|
||||
<TITLE>GtkSliceListModel</TITLE>
|
||||
GtkSliceListModel
|
||||
gtk_slice_list_model_new
|
||||
gtk_slice_list_model_new_for_type
|
||||
gtk_slice_list_model_set_model
|
||||
gtk_slice_list_model_get_model
|
||||
gtk_slice_list_model_set_offset
|
||||
gtk_slice_list_model_get_offset
|
||||
gtk_slice_list_model_set_size
|
||||
gtk_slice_list_model_get_size
|
||||
<SUBSECTION Standard>
|
||||
GTK_SLICE_LIST_MODEL
|
||||
GTK_IS_SLICE_LIST_MODEL
|
||||
GTK_TYPE_SLICE_LIST_MODEL
|
||||
GTK_SLICE_LIST_MODEL_CLASS
|
||||
GTK_IS_SLICE_LIST_MODEL_CLASS
|
||||
GTK_SLICE_LIST_MODEL_GET_CLASS
|
||||
<SUBSECTION Private>
|
||||
gtk_slice_list_model_get_type
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>gtksortlistmodel</FILE>
|
||||
<TITLE>GtkSortListModel</TITLE>
|
||||
GtkSortListModel
|
||||
gtk_sort_list_model_new
|
||||
gtk_sort_list_model_new_for_type
|
||||
gtk_sort_list_model_set_sort_func
|
||||
gtk_sort_list_model_has_sort
|
||||
gtk_sort_list_model_set_model
|
||||
gtk_sort_list_model_get_model
|
||||
gtk_sort_list_model_resort
|
||||
<SUBSECTION Standard>
|
||||
GTK_SORT_LIST_MODEL
|
||||
GTK_IS_SORT_LIST_MODEL
|
||||
GTK_TYPE_SORT_LIST_MODEL
|
||||
GTK_SORT_LIST_MODEL_CLASS
|
||||
GTK_IS_SORT_LIST_MODEL_CLASS
|
||||
GTK_SORT_LIST_MODEL_GET_CLASS
|
||||
<SUBSECTION Private>
|
||||
gtk_sort_list_model_get_type
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>gtkspinbutton</FILE>
|
||||
<TITLE>GtkSpinButton</TITLE>
|
||||
@@ -3275,6 +3372,49 @@ GTK_TOOLTIP
|
||||
gtk_tooltip_get_type
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>gtktreelistmodel</FILE>
|
||||
<TITLE>GtkTreeListModel</TITLE>
|
||||
GtkTreeListModel
|
||||
GtkTreeListRow
|
||||
GtkTreeListModelCreateModelFunc
|
||||
gtk_tree_list_model_new
|
||||
gtk_tree_list_model_get_model
|
||||
gtk_tree_list_model_get_passthrough
|
||||
gtk_tree_list_model_set_autoexpand
|
||||
gtk_tree_list_model_get_autoexpand
|
||||
gtk_tree_list_model_get_child_row
|
||||
gtk_tree_list_model_get_row
|
||||
|
||||
<SUBSECTION>
|
||||
gtk_tree_list_row_get_item
|
||||
gtk_tree_list_row_set_expanded
|
||||
gtk_tree_list_row_get_expanded
|
||||
gtk_tree_list_row_is_expandable
|
||||
gtk_tree_list_row_get_position
|
||||
gtk_tree_list_row_get_depth
|
||||
gtk_tree_list_row_get_children
|
||||
gtk_tree_list_row_get_parent
|
||||
gtk_tree_list_row_get_child_row
|
||||
|
||||
<SUBSECTION Standard>
|
||||
GTK_TREE_LIST_MODEL
|
||||
GTK_IS_TREE_LIST_MODEL
|
||||
GTK_TYPE_TREE_LIST_MODEL
|
||||
GTK_TREE_LIST_MODEL_CLASS
|
||||
GTK_IS_TREE_LIST_MODEL_CLASS
|
||||
GTK_TREE_LIST_MODEL_GET_CLASS
|
||||
GTK_TREE_LIST_ROW
|
||||
GTK_IS_TREE_LIST_ROW
|
||||
GTK_TYPE_TREE_LIST_ROW
|
||||
GTK_TREE_LIST_ROW_CLASS
|
||||
GTK_IS_TREE_LIST_ROW_CLASS
|
||||
GTK_TREE_LIST_ROW_GET_CLASS
|
||||
<SUBSECTION Private>
|
||||
gtk_tree_list_model_get_type
|
||||
gtk_tree_list_row_get_type
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>gtktreemodel</FILE>
|
||||
<TITLE>GtkTreeModel</TITLE>
|
||||
@@ -4281,7 +4421,6 @@ gtk_widget_list_accel_closures
|
||||
gtk_widget_can_activate_accel
|
||||
gtk_widget_event
|
||||
gtk_widget_activate
|
||||
gtk_widget_intersect
|
||||
gtk_widget_is_focus
|
||||
gtk_widget_grab_focus
|
||||
gtk_widget_grab_default
|
||||
@@ -4464,6 +4603,10 @@ gtk_widget_class_bind_template_callback
|
||||
gtk_widget_class_bind_template_callback_full
|
||||
gtk_widget_class_set_connect_func
|
||||
|
||||
<SUBSECTION>
|
||||
gtk_widget_observe_children
|
||||
gtk_widget_observe_controllers
|
||||
|
||||
<SUBSECTION Standard>
|
||||
GTK_WIDGET
|
||||
GTK_IS_WIDGET
|
||||
@@ -4507,6 +4650,7 @@ gtk_window_set_destroy_with_parent
|
||||
gtk_window_set_display
|
||||
gtk_window_is_active
|
||||
gtk_window_is_maximized
|
||||
gtk_window_get_toplevels
|
||||
gtk_window_list_toplevels
|
||||
gtk_window_add_mnemonic
|
||||
gtk_window_remove_mnemonic
|
||||
@@ -4865,7 +5009,6 @@ gtk_style_context_get_parent
|
||||
gtk_style_context_get_path
|
||||
gtk_style_context_get_property
|
||||
gtk_style_context_get_display
|
||||
gtk_style_context_get_frame_clock
|
||||
gtk_style_context_get_state
|
||||
gtk_style_context_get_valist
|
||||
gtk_style_context_get_section
|
||||
@@ -4888,7 +5031,6 @@ gtk_style_context_remove_class
|
||||
gtk_style_context_has_class
|
||||
gtk_style_context_list_classes
|
||||
gtk_style_context_set_display
|
||||
gtk_style_context_set_frame_clock
|
||||
gtk_style_context_set_state
|
||||
gtk_style_context_set_scale
|
||||
gtk_style_context_get_scale
|
||||
@@ -4909,12 +5051,10 @@ gtk_render_check
|
||||
gtk_render_expander
|
||||
gtk_render_focus
|
||||
gtk_render_frame
|
||||
gtk_render_frame_gap
|
||||
gtk_render_handle
|
||||
gtk_render_layout
|
||||
gtk_render_line
|
||||
gtk_render_option
|
||||
gtk_render_slider
|
||||
gtk_render_activity
|
||||
gtk_render_icon
|
||||
gtk_render_insertion_cursor
|
||||
@@ -4938,7 +5078,6 @@ gtk_border_get_type
|
||||
<FILE>gtkcssprovider</FILE>
|
||||
<TITLE>GtkCssProvider</TITLE>
|
||||
GtkCssProvider
|
||||
gtk_css_provider_get_default
|
||||
gtk_css_provider_get_named
|
||||
gtk_css_provider_load_from_data
|
||||
gtk_css_provider_load_from_file
|
||||
@@ -5015,6 +5154,7 @@ gtk_selection_data_get_type
|
||||
<TITLE>Drag and Drop</TITLE>
|
||||
GtkDestDefaults
|
||||
GtkDragResult
|
||||
|
||||
<SUBSECTION Destination Side>
|
||||
gtk_drag_dest_set
|
||||
gtk_drag_dest_unset
|
||||
@@ -5026,13 +5166,13 @@ gtk_drag_dest_add_image_targets
|
||||
gtk_drag_dest_add_uri_targets
|
||||
gtk_drag_dest_set_track_motion
|
||||
gtk_drag_dest_get_track_motion
|
||||
gtk_drag_finish
|
||||
gtk_drag_get_data
|
||||
gtk_drag_get_source_widget
|
||||
gtk_drag_highlight
|
||||
gtk_drag_unhighlight
|
||||
|
||||
<SUBSECTION Source Side>
|
||||
gtk_drag_begin_with_coordinates
|
||||
gtk_drag_begin
|
||||
gtk_drag_cancel
|
||||
gtk_drag_set_icon_widget
|
||||
gtk_drag_set_icon_paintable
|
||||
@@ -6017,6 +6157,8 @@ gtk_overlay_get_overlay_pass_through
|
||||
gtk_overlay_set_overlay_pass_through
|
||||
gtk_overlay_get_measure_overlay
|
||||
gtk_overlay_set_measure_overlay
|
||||
gtk_overlay_get_clip_overlay
|
||||
gtk_overlay_set_clip_overlay
|
||||
|
||||
<SUBSECTION Standard>
|
||||
GTK_TYPE_OVERLAY
|
||||
@@ -6462,9 +6604,27 @@ GTK_GESTURE_SINGLE_GET_CLASS
|
||||
gtk_gesture_single_get_type
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>gtkeventcontrollerlegacy</FILE>
|
||||
<TITLE>GtkEventControllerlegacy</TITLE>
|
||||
GtkEventControllerlegacy
|
||||
gtk_event_controller_legacy_new
|
||||
|
||||
<SUBSECTION Standard>
|
||||
GTK_TYPE_EVENT_CONTROLLER_LEGACY
|
||||
GTK_EVENT_CONTROLLER_LEGACY
|
||||
GTK_EVENT_CONTROLLER_LEGACY_CLASS
|
||||
GTK_IS_EVENT_CONTROLLER_LEGACY
|
||||
GTK_IS_EVENT_CONTROLLER_LEGACY_CLASS
|
||||
GTK_EVENT_CONTROLLER_LEGACY_GET_CLASS
|
||||
|
||||
<SUBSECTION Private>
|
||||
gtk_event_controller_legacy_get_type
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>gtkeventcontrollerscroll</FILE>
|
||||
<TITLE>GtkEventControlerScroll</TITLE>
|
||||
<TITLE>GtkEventControllerScroll</TITLE>
|
||||
GtkEventControllerScroll
|
||||
GtkEventControllerScrollFlags
|
||||
gtk_event_controller_scroll_new
|
||||
@@ -6485,7 +6645,7 @@ gtk_event_controller_scroll_get_type
|
||||
|
||||
<SECTION>
|
||||
<FILE>gtkeventcontrollermotion</FILE>
|
||||
<TITLE>GtkEventControlerMotion</TITLE>
|
||||
<TITLE>GtkEventControllerMotion</TITLE>
|
||||
GtkEventControllerMotion
|
||||
gtk_event_controller_motion_new
|
||||
|
||||
@@ -6503,7 +6663,7 @@ gtk_event_controller_motion_get_type
|
||||
|
||||
<SECTION>
|
||||
<FILE>gtkeventcontrollerkey</FILE>
|
||||
<TITLE>GtkEventControlerKey</TITLE>
|
||||
<TITLE>GtkEventControllerKey</TITLE>
|
||||
GtkEventControllerKey
|
||||
gtk_event_controller_key_new
|
||||
|
||||
|
@@ -54,6 +54,7 @@ gtk_entry_completion_get_type
|
||||
gtk_entry_get_type
|
||||
gtk_event_controller_get_type
|
||||
gtk_event_controller_key_get_type
|
||||
gtk_event_controller_legacy_get_type
|
||||
gtk_event_controller_motion_get_type
|
||||
gtk_event_controller_scroll_get_type
|
||||
gtk_expander_get_type
|
||||
@@ -118,6 +119,7 @@ gtk_page_setup_get_type
|
||||
@DISABLE_ON_W32@gtk_page_setup_unix_dialog_get_type
|
||||
gtk_paned_get_type
|
||||
gtk_paper_size_get_type
|
||||
gtk_picture_get_type
|
||||
gtk_popover_get_type
|
||||
gtk_popover_menu_get_type
|
||||
@DISABLE_ON_W32@gtk_printer_get_type
|
||||
|
@@ -179,41 +179,6 @@
|
||||
</para>
|
||||
</refsect2>
|
||||
|
||||
<refsect2 id="event-masks">
|
||||
<title>Event masks</title>
|
||||
|
||||
<para>
|
||||
Each widget instance has a basic event mask and another per input device,
|
||||
which determine the types of input event it receives. Each event mask set
|
||||
on a widget is added to the corresponding (basic or per-device) event mask
|
||||
for the widget’s #GdkSurface, and all child #GdkSurfaces.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Filtering events against event masks happens inside #GdkSurface, which
|
||||
exposes event masks to the windowing system to reduce the number of events
|
||||
GDK receives from it. On receiving an event, it is filtered against the
|
||||
#GdkSurface’s mask for the input device, if set. Otherwise, it is filtered
|
||||
against the #GdkSurface’s basic event mask.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
This means that widgets must add to the event mask for each event type
|
||||
they expect to receive, using gtk_widget_set_events() or
|
||||
gtk_widget_add_events() to preserve the existing mask. Widgets which are
|
||||
aware of floating devices should use gtk_widget_set_device_events() or
|
||||
gtk_widget_add_device_events(), and must explicitly enable the device
|
||||
using gtk_widget_set_device_enabled(). See the #GdkDeviceManager
|
||||
documentation for more information.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
All standard widgets set the event mask for all events they expect to
|
||||
receive, and it is not necessary to modify this. Masks should be set when
|
||||
implementing a new widget.
|
||||
</para>
|
||||
</refsect2>
|
||||
|
||||
<refsect2>
|
||||
<title>Touch events</title>
|
||||
|
||||
|
@@ -340,7 +340,6 @@ content_files = [
|
||||
'css-overview.xml',
|
||||
'css-properties.xml',
|
||||
'drawing-model.xml',
|
||||
'getting_started.xml',
|
||||
'glossary.xml',
|
||||
'gtk4-broadwayd.xml',
|
||||
'gtk4-builder-tool.xml',
|
||||
@@ -355,7 +354,6 @@ content_files = [
|
||||
'input-handling.xml',
|
||||
'migrating-2to4.xml',
|
||||
'migrating-3to4.xml',
|
||||
'mir.xml',
|
||||
'osx.sgml',
|
||||
'other_software.sgml',
|
||||
'overview.xml',
|
||||
@@ -364,6 +362,7 @@ content_files = [
|
||||
'running.sgml',
|
||||
'text_widget.sgml',
|
||||
'tree_widget.sgml',
|
||||
'treeview_tutorial.xml',
|
||||
'visual_index.xml',
|
||||
'wayland.xml',
|
||||
'windows.sgml',
|
||||
@@ -373,7 +372,6 @@ content_files = [
|
||||
expand_content_files = [
|
||||
'compiling.sgml',
|
||||
'drawing-model.xml',
|
||||
'getting_started.xml',
|
||||
'glossary.xml',
|
||||
'input-handling.xml',
|
||||
'migrating-2to4.xml',
|
||||
@@ -381,9 +379,11 @@ expand_content_files = [
|
||||
'question_index.sgml',
|
||||
'text_widget.sgml',
|
||||
'tree_widget.sgml',
|
||||
'treeview_tutorial.xml',
|
||||
]
|
||||
|
||||
configure_file(input: 'version.xml.in', output: 'version.xml', configuration: version_conf)
|
||||
configure_file(input: 'getting_started.xml.in', output: 'getting_started.xml', configuration: src_dir_conf)
|
||||
|
||||
types_conf = configuration_data()
|
||||
if os_win32
|
||||
|
@@ -20,11 +20,11 @@
|
||||
|
||||
<para>
|
||||
The steps outlined in the following sections assume that your
|
||||
application is working with GTK+ 3.22, which is the final stable
|
||||
application is working with GTK+ 3.24, which is the final stable
|
||||
release of GTK+ 3.x. It includes all the necessary APIs and tools
|
||||
to help you port your application to GTK+ 4. If you are still using
|
||||
an older version of GTK+ 3.x, you should first get your application
|
||||
to build and work with the latest minor release in the 3.22 series.
|
||||
to build and work with the latest minor release in the 3.24 series.
|
||||
</para>
|
||||
|
||||
<section>
|
||||
@@ -34,7 +34,7 @@
|
||||
widgets have been deprecated. These deprecations are clearly spelled
|
||||
out in the API reference, with hints about the recommended replacements.
|
||||
The API reference for GTK+ 3 also includes an
|
||||
<ulink url="https://developer.gnome.org/gtk3/3.22/api-index-deprecated.html">index</ulink> of all deprecated symbols.
|
||||
<ulink url="https://developer.gnome.org/gtk3/3.24/api-index-deprecated.html">index</ulink> of all deprecated symbols.
|
||||
</para>
|
||||
<para>
|
||||
To verify that your program does not use any deprecated symbols,
|
||||
@@ -79,13 +79,13 @@
|
||||
<title>Review your window creation flags</title>
|
||||
<para>
|
||||
GTK+ 4 removes the GDK_WA_CURSOR flag. Instead, just use
|
||||
gdk_surface_set_cursor() to set a cursor on the window after
|
||||
gdk_window_set_cursor() to set a cursor on the window after
|
||||
creating it.
|
||||
</para>
|
||||
<para>
|
||||
GTK+ 4 also removes the GDK_WA_VISUAL flag, and always uses
|
||||
an RGBA visual for windows. To prepare your code for this,
|
||||
use gdk_surface_set_visual (gdk_screen_get_rgba_visual ()) after
|
||||
use gdk_window_set_visual (gdk_screen_get_rgba_visual ()) after
|
||||
creating your window.
|
||||
</para>
|
||||
<para>
|
||||
@@ -169,6 +169,30 @@
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Stop using GtkWidget event signals</title>
|
||||
<para>
|
||||
Event controllers and #GtkGestures replace event signals in GTK+ 4. They
|
||||
have been backported to GTK+ 3.x so you can prepare for this change.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Set a proper app_id</title>
|
||||
<para>
|
||||
In GTK+4 we want the application's #GApplication
|
||||
'application-id' (and therefore the D-Bus name), the desktop
|
||||
file basename and Wayland's xdg-shell app_id to match. In
|
||||
order to achieve this with GTK+3 call g_set_prgname() with the same
|
||||
application id you passed to #GtkApplication. Rename your
|
||||
desktop files to match the application id if needed.
|
||||
</para>
|
||||
<para>
|
||||
The call to g_set_prgname() can be removed once you fully migrated
|
||||
to GTK+4.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
</section>
|
||||
|
||||
<section>
|
||||
@@ -262,6 +286,14 @@
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Stop using GtkEventBox</title>
|
||||
<para>
|
||||
GtkEventBox is no longer needed and has been removed.
|
||||
All widgets receive all events.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Adapt to GtkHeaderBar API changes</title>
|
||||
<para>
|
||||
@@ -311,6 +343,15 @@
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Adapt to GtkWidget's size allocation changes</title>
|
||||
<para>
|
||||
The #GtkWidget::size-allocate signal now takes the baseline as an
|
||||
argument, so you no longer need to call gtk_widget_get_allocated_baseline()
|
||||
to get it.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Switch to GtkWidget's children APIs</title>
|
||||
<para>
|
||||
@@ -391,6 +432,10 @@
|
||||
from ui files it run the command <command>gtk4-builder-tool simplify --replace</command>
|
||||
on them.
|
||||
</para>
|
||||
<para>
|
||||
The function gtk_widget_show_all(), the #GtkWidget::no-show-all property
|
||||
and its getter and setter have been removed in GTK+ 4, so you should stop using them.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
@@ -432,8 +477,7 @@
|
||||
<title>GtkWidget event signals are removed</title>
|
||||
<para>
|
||||
Event controllers and #GtkGestures have already been introduced in GTK+ 3 to handle
|
||||
input for many cases. In GTK+ 4, even more are available, such as #GtkEventControllerScroll
|
||||
and GtkEventControllerMotion, and the traditional widget signals for handling input,
|
||||
input for many cases. In GTK+ 4, the traditional widget signals for handling input,
|
||||
such as #GtkWidget::motion-event or #GtkWidget::event have been removed.
|
||||
</para>
|
||||
</section>
|
||||
|
@@ -1,35 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
|
||||
]>
|
||||
<refentry id="gtk-mir">
|
||||
<refmeta>
|
||||
<refentrytitle>Using GTK+ with Mir</refentrytitle>
|
||||
<manvolnum>3</manvolnum>
|
||||
<refmiscinfo>GTK Library</refmiscinfo>
|
||||
</refmeta>
|
||||
|
||||
<refnamediv>
|
||||
<refname>Using GTK+ with Mir</refname>
|
||||
<refpurpose>
|
||||
Mir-specific aspects of using GTK+
|
||||
</refpurpose>
|
||||
</refnamediv>
|
||||
|
||||
<refsect1>
|
||||
<title>Using GTK+ with Mir</title>
|
||||
|
||||
<para>
|
||||
The GDK Mir backend provides support for running GTK+ applications
|
||||
under Mir based display servers. To run your application in this way,
|
||||
select the Mir backend by setting <literal>GDK_BACKEND=mir</literal>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Currently, the Mir backend does not use any additional commandline
|
||||
options or environment variables.
|
||||
</para>
|
||||
|
||||
</refsect1>
|
||||
|
||||
</refentry>
|
@@ -435,11 +435,6 @@ nevertheless.
|
||||
<listitem><para>Selects the Wayland backend for connecting to Wayland display servers</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>mir</term>
|
||||
<listitem><para>Selects the Mir backend for connecting to Mir display servers</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
Since 3.10, this environment variable can contain a comma-separated list
|
||||
of backend names, which are tried in order. The list may also contain
|
||||
|
143
docs/reference/gtk/treeview_tutorial.xml
Normal file
143
docs/reference/gtk/treeview_tutorial.xml
Normal file
@@ -0,0 +1,143 @@
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
|
||||
]>
|
||||
<refentry id="TreeView-tutorial">
|
||||
<refmeta>
|
||||
<refentrytitle>TreeView Tutorial</refentrytitle>
|
||||
<manvolnum>3</manvolnum>
|
||||
<refmiscinfo>GTK Library</refmiscinfo>
|
||||
</refmeta>
|
||||
|
||||
<refnamediv>
|
||||
<refname>TreeView Tutorial</refname>
|
||||
<refpurpose>A tutorial on the use of GtkTreeModel, GtkTreeView, and friends</refpurpose>
|
||||
</refnamediv>
|
||||
|
||||
<refsect1>
|
||||
<title>Overview</title>
|
||||
<para>GtkTreeView is a widget that displays single- or multi-columned
|
||||
lists and trees.</para>
|
||||
|
||||
<para>The purpose of this tutorial is not to provide an exhaustive
|
||||
documentation of #GtkTreeView - that is what the API documentation is
|
||||
for, which should be read alongside with this tutorial. The goal is
|
||||
rather to present an introduction to the most commonly-used aspects
|
||||
of #GtkTreeView, and to demonstrate how the various #GtkTreeView
|
||||
components and concepts work together. Furthermore, an attempt has
|
||||
been made to shed some light on custom tree models and custom cell
|
||||
renderers, which seem to be often-mentioned, but rarely
|
||||
explained.</para>
|
||||
|
||||
<para>Developers looking for a quick and dirty introduction that
|
||||
teaches them everything they need to know in less than five paragraphs
|
||||
will not find it here. In the author's experience, developers who do
|
||||
not understand how the tree view and the models work together will run
|
||||
into problems once they try to modify the given examples, whereas
|
||||
developers who have worked with other toolkits that employ the
|
||||
Model/View/Controller-design will find that the API reference provides
|
||||
all the information they need to know in more condensed form anyway.
|
||||
Those who disagree may jump straight to the working example code of
|
||||
course.</para>
|
||||
|
||||
<para>Please note that the code examples in the following sections do
|
||||
not necessarily demonstrate how GtkTreeView is used best in a particular
|
||||
situation. There are different ways to achieve the same result, and the
|
||||
examples merely show those different ways, so that developers are able
|
||||
to decide which one is most suitable for the task at hand.</para>
|
||||
|
||||
<refsect2>
|
||||
<title>Components</title>
|
||||
|
||||
<para>The most important concept underlying #GtkTreeView is that of
|
||||
complete separation between data and how that data is displayed on
|
||||
the screen. This is commonly known as Model/View/Controller-design,
|
||||
or MVC. Data of various type (strings, numbers, images, etc.) is
|
||||
stored in a "model". The "view" is then told which data to display,
|
||||
where to display it, and how to display it. One of the advantages
|
||||
of this approach is that you can have multiple views that display
|
||||
the same data (a directory tree for example) in different ways, or
|
||||
in the same way multiple times, with only one copy of the underlying
|
||||
data. This avoids duplication of data and programming effort if the
|
||||
same data is re-used in different contexts. Also, when the data in
|
||||
the model is updated, all views automatically get updated as
|
||||
well.</para>
|
||||
|
||||
<para>So, while #GtkTreeModel is used to store data, there are other
|
||||
components that determine which data is displayed in the #GtkTreeView
|
||||
and how it is displayed. These components are #GtkTreeViewColumn and
|
||||
#GtkCellRenderer. A #GtkTreeView is made up of tree view columns.
|
||||
These are the columns that users perceive as columns. They have a
|
||||
clickable column header with a column title that can be hidden, and
|
||||
can be resized and sorted. Tree view columns do not display any data,
|
||||
they are only used as a device to represent the user-side of the tree
|
||||
view (sorting etc.) and serve as packing widgets for the components
|
||||
that do the actual rendering of data onto the screen, namely the
|
||||
#GtkCellRenderer family of objects. There are a number of different
|
||||
cell renderers that specialise in rendering certain data like
|
||||
strings, pixbufs, or toggle buttons. More on this later.</para>
|
||||
|
||||
<para>Cell renderers are packed into tree view columns to display data.
|
||||
A tree view column needs to contain at least one cell renderer, but can
|
||||
contain multiple cell renderers. For example, if one wanted to display
|
||||
a 'Filename' column where each filename has a little icon on the left
|
||||
indicating the file type, one would pack a GtkCellRendererPixbuf and a
|
||||
GtkCellRendererText into one tree view column. Packing renderers into a
|
||||
tree view column is similar to packing widgets into a #GtkBox.</para>
|
||||
</refsect2>
|
||||
|
||||
<refsect2>
|
||||
<title>GtkTreeModels for Data Storage: GtkListStore and GtkTreeStore</title>
|
||||
|
||||
<para>It is important to realise what #GtkTreeModel is and what it is
|
||||
not. #GtkTreeModel is basically just an 'interface' to the data store,
|
||||
meaning that it is a standardised set of functions that allows a
|
||||
#GtkTreeView widget (and the application programmer) to query certain
|
||||
characteristics of a data store, for example how many rows there are,
|
||||
which rows have children, and how many children a particular row has.
|
||||
It also provides functions to retrieve data from the data store, and
|
||||
tell the tree view what type of data is stored in the model. Every
|
||||
data store must implement the #GtkTreeModel interface and provide these
|
||||
functions. #GtkTreeModel itself only provides a way to query a data
|
||||
store's characteristics and to retrieve existing data, it does not
|
||||
provide a way to remove or add rows to the store or put data into the
|
||||
store. This is done using the specific store's functions.</para>
|
||||
|
||||
<para>GTK comes with two built-in data stores (models): #GtkListStore
|
||||
and #GtkTreeStore. As the names imply, #GtkListStore is used for simple
|
||||
lists of data items where items have no hierarchical parent-child
|
||||
relationships, and #GtkTreeStore is used for tree-like data structures,
|
||||
where items can have parent-child relationships. A list of files in a
|
||||
directory would be an example of a simple list structure, whereas a
|
||||
directory tree is an example for a tree structure. A list is basically
|
||||
just a special case of a tree with none of the items having any
|
||||
children, so one could use a tree store to maintain a simple list of
|
||||
items as well. The only reason #GtkListStore exists is in order to
|
||||
provide an easier interface that does not need to cater for
|
||||
child-parent relationships, and because a simple list model can be
|
||||
optimised for the special case where no children exist, which makes it
|
||||
faster and more efficient.</para>
|
||||
|
||||
<para>#GtkListStore and #GtkTreeStore should cater for most types of
|
||||
data an application developer might want to display in a #GtkTreeView.
|
||||
However, it should be noted that #GtkListStore and #GtkTreeStore have
|
||||
been designed to cater to a large number of potential use cases, and
|
||||
so are not overly optimized. If you already have your specialized data
|
||||
store; if you plan to store a lot of data; or if have a large number
|
||||
of rows, you should consider implementing your own custom model that
|
||||
stores and manipulates data your own way and implements the
|
||||
#GtkTreeModel interface. This will not only be more efficient, but
|
||||
probably also lead to saner code in the long run, and give you more
|
||||
control over your data. See below for more details on how to implement
|
||||
custom models.</para>
|
||||
|
||||
<para>Tree model implementations like #GtkListStore and #GtkTreeStore
|
||||
will take care of the view side for you once you have configured the
|
||||
#GtkTreeView to display what you want. If you change data in the store,
|
||||
the model will notify the tree view and your data display will be
|
||||
updated. If you add or remove rows, the model will also notify the
|
||||
store, and your row will appear in or disappear from the view as
|
||||
well.</para>
|
||||
</refsect2>
|
||||
|
||||
</refsect1>
|
@@ -12,6 +12,9 @@ docpath = join_paths(gtk_datadir, 'gtk-doc', 'html')
|
||||
version_conf = configuration_data()
|
||||
version_conf.set('GTK_VERSION', meson.project_version())
|
||||
|
||||
src_dir_conf = configuration_data()
|
||||
src_dir_conf.set('SRC_DIR', meson.source_root())
|
||||
|
||||
subdir('gdk')
|
||||
subdir('gsk')
|
||||
subdir('gtk')
|
||||
|
@@ -2,8 +2,8 @@ To make gnome-shell use the desktop file and icon for this example
|
||||
while running it uninstalled, do the following:
|
||||
|
||||
mkdir -p ~/.local/share/applications
|
||||
sed -e "s#@bindir@#$PWD#" exampleapp.desktop \
|
||||
> ~/.local/share/applications/lt-exampleapp.desktop
|
||||
sed -e "s#@bindir@#$PWD#" org.gtk.exampleapp.desktop \
|
||||
> ~/.local/share/applications/org.gtk.exampleapp.desktop
|
||||
|
||||
mkdir -p ~/.local/share/icons/hicolor/48x48/apps
|
||||
cp exampleapp.png ~/.local/share/icons/hicolor/48x48/apps
|
||||
|
@@ -1,16 +1,5 @@
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
static gboolean
|
||||
window_key_pressed (GtkEventController *controller,
|
||||
guint keyval,
|
||||
guint keycode,
|
||||
GdkModifierType state,
|
||||
GtkSearchBar *search_bar)
|
||||
{
|
||||
return gtk_search_bar_handle_event (search_bar,
|
||||
gtk_get_current_event ());
|
||||
}
|
||||
|
||||
static void
|
||||
activate_cb (GtkApplication *app,
|
||||
gpointer user_data)
|
||||
@@ -20,12 +9,12 @@ activate_cb (GtkApplication *app,
|
||||
GtkWidget *box;
|
||||
GtkWidget *entry;
|
||||
GtkWidget *menu_button;
|
||||
GtkEventController *controller;
|
||||
|
||||
window = gtk_application_window_new (app);
|
||||
gtk_widget_show (window);
|
||||
|
||||
search_bar = gtk_search_bar_new ();
|
||||
gtk_widget_set_valign (search_bar, GTK_ALIGN_START);
|
||||
gtk_container_add (GTK_CONTAINER (window), search_bar);
|
||||
gtk_widget_show (search_bar);
|
||||
|
||||
@@ -40,12 +29,7 @@ activate_cb (GtkApplication *app,
|
||||
gtk_box_pack_start (GTK_BOX (box), menu_button);
|
||||
|
||||
gtk_search_bar_connect_entry (GTK_SEARCH_BAR (search_bar), GTK_ENTRY (entry));
|
||||
|
||||
controller = gtk_event_controller_key_new ();
|
||||
g_object_set_data_full (G_OBJECT (window), "controller", controller, g_object_unref);
|
||||
g_signal_connect (controller, "key-pressed",
|
||||
G_CALLBACK (window_key_pressed), search_bar);
|
||||
gtk_widget_add_controller (window, controller);
|
||||
gtk_search_bar_set_key_capture_widget (GTK_SEARCH_BAR (search_bar), window);
|
||||
}
|
||||
|
||||
gint
|
||||
|
@@ -61,9 +61,6 @@ static GdkSurface * gdk_broadway_device_surface_at_position (GdkDevice *de
|
||||
gdouble *win_y,
|
||||
GdkModifierType *mask,
|
||||
gboolean get_toplevel);
|
||||
static void gdk_broadway_device_select_surface_events (GdkDevice *device,
|
||||
GdkSurface *surface,
|
||||
GdkEventMask event_mask);
|
||||
|
||||
|
||||
G_DEFINE_TYPE (GdkBroadwayDevice, gdk_broadway_device, GDK_TYPE_DEVICE)
|
||||
@@ -81,7 +78,6 @@ gdk_broadway_device_class_init (GdkBroadwayDeviceClass *klass)
|
||||
device_class->grab = gdk_broadway_device_grab;
|
||||
device_class->ungrab = gdk_broadway_device_ungrab;
|
||||
device_class->surface_at_position = gdk_broadway_device_surface_at_position;
|
||||
device_class->select_surface_events = gdk_broadway_device_select_surface_events;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -325,9 +321,3 @@ gdk_broadway_device_surface_at_position (GdkDevice *device,
|
||||
return surface;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_broadway_device_select_surface_events (GdkDevice *device,
|
||||
GdkSurface *surface,
|
||||
GdkEventMask event_mask)
|
||||
{
|
||||
}
|
||||
|
@@ -49,9 +49,6 @@ struct _GdkBroadwayDisplay
|
||||
/* Keyboard related information */
|
||||
GdkKeymap *keymap;
|
||||
|
||||
/* drag and drop information */
|
||||
GdkDragContext *current_dest_drag;
|
||||
|
||||
GdkBroadwayServer *server;
|
||||
|
||||
gpointer move_resize_data;
|
||||
|
@@ -24,7 +24,7 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gdkdndprivate.h"
|
||||
#include "gdkdragprivate.h"
|
||||
|
||||
#include "gdkinternals.h"
|
||||
#include "gdkproperty.h"
|
||||
@@ -34,56 +34,56 @@
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#define GDK_TYPE_BROADWAY_DRAG_CONTEXT (gdk_broadway_drag_context_get_type ())
|
||||
#define GDK_BROADWAY_DRAG_CONTEXT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_BROADWAY_DRAG_CONTEXT, GdkBroadwayDragContext))
|
||||
#define GDK_BROADWAY_DRAG_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_BROADWAY_DRAG_CONTEXT, GdkBroadwayDragContextClass))
|
||||
#define GDK_IS_BROADWAY_DRAG_CONTEXT(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_BROADWAY_DRAG_CONTEXT))
|
||||
#define GDK_IS_BROADWAY_DRAG_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_BROADWAY_DRAG_CONTEXT))
|
||||
#define GDK_BROADWAY_DRAG_CONTEXT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_BROADWAY_DRAG_CONTEXT, GdkBroadwayDragContextClass))
|
||||
#define GDK_TYPE_BROADWAY_DRAG (gdk_broadway_drag_get_type ())
|
||||
#define GDK_BROADWAY_DRAG(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_BROADWAY_DRAG, GdkBroadwayDrag))
|
||||
#define GDK_BROADWAY_DRAG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_BROADWAY_DRAG, GdkBroadwayDragClass))
|
||||
#define GDK_IS_BROADWAY_DRAG(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_BROADWAY_DRAG))
|
||||
#define GDK_IS_BROADWAY_DRAG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_BROADWAY_DRAG))
|
||||
#define GDK_BROADWAY_DRAG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_BROADWAY_DRAG, GdkBroadwayDragClass))
|
||||
|
||||
#ifdef GDK_COMPILATION
|
||||
typedef struct _GdkBroadwayDragContext GdkBroadwayDragContext;
|
||||
typedef struct _GdkBroadwayDrag GdkBroadwayDrag;
|
||||
#else
|
||||
typedef GdkDragContext GdkBroadwayDragContext;
|
||||
typedef GdkDrag GdkBroadwayDrag;
|
||||
#endif
|
||||
typedef struct _GdkBroadwayDragContextClass GdkBroadwayDragContextClass;
|
||||
typedef struct _GdkBroadwayDragClass GdkBroadwayDragClass;
|
||||
|
||||
GType gdk_broadway_drag_context_get_type (void);
|
||||
GType gdk_broadway_drag_get_type (void);
|
||||
|
||||
struct _GdkBroadwayDragContext {
|
||||
GdkDragContext context;
|
||||
struct _GdkBroadwayDrag {
|
||||
GdkDrag context;
|
||||
};
|
||||
|
||||
struct _GdkBroadwayDragContextClass
|
||||
struct _GdkBroadwayDragClass
|
||||
{
|
||||
GdkDragContextClass parent_class;
|
||||
GdkDragClass parent_class;
|
||||
};
|
||||
|
||||
static void gdk_broadway_drag_context_finalize (GObject *object);
|
||||
static void gdk_broadway_drag_finalize (GObject *object);
|
||||
|
||||
static GList *contexts;
|
||||
|
||||
G_DEFINE_TYPE (GdkBroadwayDragContext, gdk_broadway_drag_context, GDK_TYPE_DRAG_CONTEXT)
|
||||
G_DEFINE_TYPE (GdkBroadwayDrag, gdk_broadway_drag, GDK_TYPE_DRAG)
|
||||
|
||||
static void
|
||||
gdk_broadway_drag_context_init (GdkBroadwayDragContext *dragcontext)
|
||||
gdk_broadway_drag_init (GdkBroadwayDrag *dragcontext)
|
||||
{
|
||||
contexts = g_list_prepend (contexts, dragcontext);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_broadway_drag_context_finalize (GObject *object)
|
||||
gdk_broadway_drag_finalize (GObject *object)
|
||||
{
|
||||
GdkDragContext *context = GDK_DRAG_CONTEXT (object);
|
||||
GdkDrag *context = GDK_DRAG (object);
|
||||
|
||||
contexts = g_list_remove (contexts, context);
|
||||
|
||||
G_OBJECT_CLASS (gdk_broadway_drag_context_parent_class)->finalize (object);
|
||||
G_OBJECT_CLASS (gdk_broadway_drag_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
/* Drag Contexts */
|
||||
|
||||
GdkDragContext *
|
||||
GdkDrag *
|
||||
_gdk_broadway_surface_drag_begin (GdkSurface *surface,
|
||||
GdkDevice *device,
|
||||
GdkContentProvider *content,
|
||||
@@ -91,12 +91,12 @@ _gdk_broadway_surface_drag_begin (GdkSurface *surface,
|
||||
gint dx,
|
||||
gint dy)
|
||||
{
|
||||
GdkDragContext *new_context;
|
||||
GdkDrag *new_context;
|
||||
|
||||
g_return_val_if_fail (surface != NULL, NULL);
|
||||
g_return_val_if_fail (GDK_SURFACE_IS_BROADWAY (surface), NULL);
|
||||
|
||||
new_context = g_object_new (GDK_TYPE_BROADWAY_DRAG_CONTEXT,
|
||||
new_context = g_object_new (GDK_TYPE_BROADWAY_DRAG,
|
||||
"device", device,
|
||||
"content", content,
|
||||
NULL);
|
||||
@@ -104,38 +104,6 @@ _gdk_broadway_surface_drag_begin (GdkSurface *surface,
|
||||
return new_context;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_broadway_drag_context_drag_drop (GdkDragContext *context,
|
||||
guint32 time)
|
||||
{
|
||||
g_return_if_fail (context != NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_broadway_drag_context_drag_abort (GdkDragContext *context,
|
||||
guint32 time)
|
||||
{
|
||||
g_return_if_fail (context != NULL);
|
||||
}
|
||||
|
||||
/* Destination side */
|
||||
|
||||
static void
|
||||
gdk_broadway_drag_context_drag_status (GdkDragContext *context,
|
||||
GdkDragAction action,
|
||||
guint32 time)
|
||||
{
|
||||
g_return_if_fail (context != NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_broadway_drag_context_drop_finish (GdkDragContext *context,
|
||||
gboolean success,
|
||||
guint32 time)
|
||||
{
|
||||
g_return_if_fail (context != NULL);
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_broadway_surface_register_dnd (GdkSurface *surface)
|
||||
{
|
||||
@@ -147,15 +115,9 @@ _gdk_broadway_display_init_dnd (GdkDisplay *display)
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_broadway_drag_context_class_init (GdkBroadwayDragContextClass *klass)
|
||||
gdk_broadway_drag_class_init (GdkBroadwayDragClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GdkDragContextClass *context_class = GDK_DRAG_CONTEXT_CLASS (klass);
|
||||
|
||||
object_class->finalize = gdk_broadway_drag_context_finalize;
|
||||
|
||||
context_class->drag_status = gdk_broadway_drag_context_drag_status;
|
||||
context_class->drag_abort = gdk_broadway_drag_context_drag_abort;
|
||||
context_class->drag_drop = gdk_broadway_drag_context_drag_drop;
|
||||
context_class->drop_finish = gdk_broadway_drag_context_drop_finish;
|
||||
object_class->finalize = gdk_broadway_drag_finalize;
|
||||
}
|
||||
|
@@ -285,7 +285,6 @@ _gdk_broadway_events_got_input (BroadwayInputMsg *message)
|
||||
event->key.state = message->key.state;
|
||||
event->key.hardware_keycode = message->key.key;
|
||||
gdk_event_set_scancode (event, message->key.key);
|
||||
event->key.length = 0;
|
||||
gdk_event_set_device (event, gdk_seat_get_keyboard (seat));
|
||||
|
||||
node = _gdk_event_queue_append (display, event);
|
||||
|
@@ -46,7 +46,7 @@ void gdk_broadway_surface_set_nodes (GdkSurface *surface,
|
||||
GPtrArray *node_textures);
|
||||
|
||||
void _gdk_broadway_surface_register_dnd (GdkSurface *surface);
|
||||
GdkDragContext * _gdk_broadway_surface_drag_begin (GdkSurface *surface,
|
||||
GdkDrag * _gdk_broadway_surface_drag_begin (GdkSurface *surface,
|
||||
GdkDevice *device,
|
||||
GdkContentProvider *content,
|
||||
GdkDragAction actions,
|
||||
@@ -101,7 +101,6 @@ void _gdk_broadway_display_get_maximal_cursor_size (GdkDisplay *display,
|
||||
void _gdk_broadway_display_create_surface_impl (GdkDisplay *display,
|
||||
GdkSurface *surface,
|
||||
GdkSurface *real_parent,
|
||||
GdkEventMask event_mask,
|
||||
GdkSurfaceAttr *attributes);
|
||||
gint _gdk_broadway_display_text_property_to_utf8_list (GdkDisplay *display,
|
||||
GdkAtom encoding,
|
||||
|
@@ -207,7 +207,6 @@ void
|
||||
_gdk_broadway_display_create_surface_impl (GdkDisplay *display,
|
||||
GdkSurface *surface,
|
||||
GdkSurface *real_parent,
|
||||
GdkEventMask event_mask,
|
||||
GdkSurfaceAttr *attributes)
|
||||
{
|
||||
GdkSurfaceImplBroadway *impl;
|
||||
@@ -323,11 +322,7 @@ gdk_surface_broadway_show (GdkSurface *surface,
|
||||
impl = GDK_SURFACE_IMPL_BROADWAY (surface->impl);
|
||||
impl->visible = TRUE;
|
||||
|
||||
if (surface->event_mask & GDK_STRUCTURE_MASK)
|
||||
_gdk_make_event (GDK_SURFACE (surface), GDK_MAP, NULL, FALSE);
|
||||
|
||||
if (surface->parent && surface->parent->event_mask & GDK_SUBSTRUCTURE_MASK)
|
||||
_gdk_make_event (GDK_SURFACE (surface), GDK_MAP, NULL, FALSE);
|
||||
/* FIXME: update state ? */
|
||||
|
||||
broadway_display = GDK_BROADWAY_DISPLAY (gdk_surface_get_display (surface));
|
||||
if (_gdk_broadway_server_surface_show (broadway_display->server, impl->id))
|
||||
@@ -344,11 +339,7 @@ gdk_surface_broadway_hide (GdkSurface *surface)
|
||||
impl = GDK_SURFACE_IMPL_BROADWAY (surface->impl);
|
||||
impl->visible = FALSE;
|
||||
|
||||
if (surface->event_mask & GDK_STRUCTURE_MASK)
|
||||
_gdk_make_event (GDK_SURFACE (surface), GDK_UNMAP, NULL, FALSE);
|
||||
|
||||
if (surface->parent && surface->parent->event_mask & GDK_SUBSTRUCTURE_MASK)
|
||||
_gdk_make_event (GDK_SURFACE (surface), GDK_UNMAP, NULL, FALSE);
|
||||
/* FIXME: update state ? */
|
||||
|
||||
broadway_display = GDK_BROADWAY_DISPLAY (gdk_surface_get_display (surface));
|
||||
|
||||
@@ -620,24 +611,6 @@ gdk_surface_broadway_get_device_state (GdkSurface *surface,
|
||||
return child != NULL;
|
||||
}
|
||||
|
||||
static GdkEventMask
|
||||
gdk_surface_broadway_get_events (GdkSurface *surface)
|
||||
{
|
||||
if (GDK_SURFACE_DESTROYED (surface))
|
||||
return 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_surface_broadway_set_events (GdkSurface *surface,
|
||||
GdkEventMask event_mask)
|
||||
{
|
||||
if (!GDK_SURFACE_DESTROYED (surface))
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_surface_broadway_input_shape_combine_region (GdkSurface *surface,
|
||||
const cairo_region_t *shape_region,
|
||||
@@ -1359,8 +1332,6 @@ gdk_surface_impl_broadway_class_init (GdkSurfaceImplBroadwayClass *klass)
|
||||
impl_class->show = gdk_surface_broadway_show;
|
||||
impl_class->hide = gdk_surface_broadway_hide;
|
||||
impl_class->withdraw = gdk_surface_broadway_withdraw;
|
||||
impl_class->set_events = gdk_surface_broadway_set_events;
|
||||
impl_class->get_events = gdk_surface_broadway_get_events;
|
||||
impl_class->raise = gdk_surface_broadway_raise;
|
||||
impl_class->lower = gdk_surface_broadway_lower;
|
||||
impl_class->restack_toplevel = gdk_surface_broadway_restack_toplevel;
|
||||
|
@@ -43,8 +43,19 @@ clienthtml_h = custom_target('clienthtml.h',
|
||||
],
|
||||
)
|
||||
|
||||
broadwayjs_h = custom_target('broadwayjs.h',
|
||||
input : ['broadway.js'],
|
||||
output : 'broadwayjs.h',
|
||||
command : [
|
||||
gen_c_array,
|
||||
'--array-name=broadway_js',
|
||||
'--output=@OUTPUT@',
|
||||
'@INPUT0@',
|
||||
],
|
||||
)
|
||||
|
||||
libgdk_broadway = static_library('gdk-broadway',
|
||||
clienthtml_h,
|
||||
clienthtml_h, broadwayjs_h,
|
||||
gdk_broadway_sources, gdkconfig, gdkenum_h,
|
||||
include_directories: [confinc, gdkinc],
|
||||
c_args: [
|
||||
@@ -58,17 +69,6 @@ libgdk_broadway = static_library('gdk-broadway',
|
||||
|
||||
broadwayd_syslib = os_win32 ? find_library('ws2_32') : shmlib
|
||||
|
||||
broadwayjs_h = custom_target('broadwayjs.h',
|
||||
input : ['broadway.js'],
|
||||
output : 'broadwayjs.h',
|
||||
command : [
|
||||
gen_c_array,
|
||||
'--array-name=broadway_js',
|
||||
'--output=@OUTPUT@',
|
||||
'@INPUT0@',
|
||||
],
|
||||
)
|
||||
|
||||
executable('gtk4-broadwayd',
|
||||
clienthtml_h, broadwayjs_h,
|
||||
'broadwayd.c', 'broadway-server.c', 'broadway-output.c',
|
||||
|
@@ -23,12 +23,12 @@
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkAppLaunchContext, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkClipboard, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkContentProvider, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkCursor, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkDevice, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkDisplay, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkDisplayManager, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkDragContext, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkDrawingContext, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkDrag, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkDrawContext, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkFrameClock, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkGLContext, g_object_unref)
|
||||
|
@@ -32,5 +32,8 @@ void gdk_display_set_cursor_theme (GdkDisplay *display,
|
||||
const char *theme,
|
||||
int size);
|
||||
gboolean gdk_running_in_sandbox (void);
|
||||
gboolean gdk_should_use_portal (void);
|
||||
|
||||
const gchar * gdk_get_startup_notification_id (void);
|
||||
|
||||
#endif /* __GDK__PRIVATE_H__ */
|
||||
|
75
gdk/gdk.c
75
gdk/gdk.c
@@ -154,6 +154,36 @@ static const GDebugKey gdk_debug_keys[] = {
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef G_HAS_CONSTRUCTORS
|
||||
#ifdef G_DEFINE_CONSTRUCTOR_NEEDS_PRAGMA
|
||||
#pragma G_DEFINE_CONSTRUCTOR_PRAGMA_ARGS(stash_desktop_startup_notification_id)
|
||||
#endif
|
||||
G_DEFINE_CONSTRUCTOR(stash_desktop_startup_notification_id)
|
||||
#endif
|
||||
|
||||
static gchar *startup_notification_id = NULL;
|
||||
|
||||
static void
|
||||
stash_desktop_startup_notification_id (void)
|
||||
{
|
||||
const char *desktop_startup_id;
|
||||
|
||||
desktop_startup_id = g_getenv ("DESKTOP_STARTUP_ID");
|
||||
if (desktop_startup_id && *desktop_startup_id != '\0')
|
||||
{
|
||||
if (!g_utf8_validate (desktop_startup_id, -1, NULL))
|
||||
g_warning ("DESKTOP_STARTUP_ID contains invalid UTF-8");
|
||||
else
|
||||
startup_notification_id = g_strdup (desktop_startup_id ? desktop_startup_id : "");
|
||||
}
|
||||
|
||||
/* Clear the environment variable so it won't be inherited by
|
||||
* child processes and confuse things.
|
||||
*/
|
||||
g_unsetenv ("DESKTOP_STARTUP_ID");
|
||||
}
|
||||
|
||||
static gpointer
|
||||
register_resources (gpointer dummy G_GNUC_UNUSED)
|
||||
{
|
||||
@@ -186,6 +216,10 @@ gdk_pre_parse (void)
|
||||
G_N_ELEMENTS (gdk_debug_keys));
|
||||
}
|
||||
#endif /* G_ENABLE_DEBUG */
|
||||
|
||||
#ifndef G_HAS_CONSTRUCTORS
|
||||
stash_desktop_startup_notification_id ();
|
||||
#endif
|
||||
}
|
||||
|
||||
/*< private >
|
||||
@@ -216,17 +250,46 @@ gdk_display_open_default (void)
|
||||
return display;
|
||||
}
|
||||
|
||||
/*< private >
|
||||
*
|
||||
* gdk_get_startup_notification_id
|
||||
*
|
||||
* Returns the original value of the DESKTOP_STARTUP_ID environment
|
||||
* variable if it was defined and valid, or %NULL otherwise.
|
||||
*
|
||||
* Returns: (nullable) (transfer none): the original value of the
|
||||
* DESKTOP_STARTUP_ID environment variable, or %NULL.
|
||||
*/
|
||||
const gchar *
|
||||
gdk_get_startup_notification_id (void)
|
||||
{
|
||||
return startup_notification_id;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gdk_running_in_sandbox (void)
|
||||
{
|
||||
char *path;
|
||||
gboolean ret;
|
||||
return g_file_test ("/.flatpak-info", G_FILE_TEST_EXISTS);
|
||||
}
|
||||
|
||||
path = g_build_filename (g_get_user_runtime_dir (), "flatpak-info", NULL);
|
||||
ret = g_file_test (path, G_FILE_TEST_EXISTS);
|
||||
g_free (path);
|
||||
gboolean
|
||||
gdk_should_use_portal (void)
|
||||
{
|
||||
static const char *use_portal = NULL;
|
||||
|
||||
return ret;
|
||||
if (G_UNLIKELY (use_portal == NULL))
|
||||
{
|
||||
if (gdk_running_in_sandbox ())
|
||||
use_portal = "1";
|
||||
else
|
||||
{
|
||||
use_portal = g_getenv ("GTK_USE_PORTAL");
|
||||
if (!use_portal)
|
||||
use_portal = "";
|
||||
}
|
||||
}
|
||||
|
||||
return use_portal[0] == '1';
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -44,8 +44,9 @@
|
||||
#include <gdk/gdkdevicetool.h>
|
||||
#include <gdk/gdkdisplay.h>
|
||||
#include <gdk/gdkdisplaymanager.h>
|
||||
#include <gdk/gdkdnd.h>
|
||||
#include <gdk/gdkdrag.h>
|
||||
#include <gdk/gdkdrawcontext.h>
|
||||
#include <gdk/gdkdrop.h>
|
||||
#include <gdk/gdkenumtypes.h>
|
||||
#include <gdk/gdkevents.h>
|
||||
#include <gdk/gdkframeclock.h>
|
||||
|
@@ -716,8 +716,7 @@ file_uri_deserializer_finish (GObject *source,
|
||||
return;
|
||||
}
|
||||
|
||||
str = g_memory_output_stream_steal_data (G_MEMORY_OUTPUT_STREAM (
|
||||
g_filter_output_stream_get_base_stream (G_FILTER_OUTPUT_STREAM (stream))));
|
||||
str = g_memory_output_stream_steal_data (G_MEMORY_OUTPUT_STREAM (stream));
|
||||
uris = g_uri_list_extract_uris (str);
|
||||
g_free (str);
|
||||
|
||||
@@ -738,6 +737,8 @@ file_uri_deserializer_finish (GObject *source,
|
||||
g_value_take_boxed (value, g_slist_reverse (l));
|
||||
}
|
||||
g_strfreev (uris);
|
||||
|
||||
gdk_content_deserializer_return_success (deserializer);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@@ -895,8 +895,8 @@ init (void)
|
||||
gdk_content_register_serializer (G_TYPE_STRING,
|
||||
mime,
|
||||
string_serializer,
|
||||
mime,
|
||||
g_free);
|
||||
(gpointer) charset,
|
||||
NULL);
|
||||
}
|
||||
gdk_content_register_serializer (G_TYPE_STRING,
|
||||
"text/plain",
|
||||
|
@@ -61,12 +61,7 @@
|
||||
* the commonly available names that are shared with the CSS specification.
|
||||
* Other names may be available, depending on the platform in use.
|
||||
* Another option to create a cursor is to use gdk_cursor_new_from_texture()
|
||||
* and provide an image to use for the cursor. Depending on the #GdkDisplay
|
||||
* in use, the type of supported images may be limited. See
|
||||
* gdk_display_supports_cursor_alpha(),
|
||||
* gdk_display_supports_cursor_color(),
|
||||
* gdk_display_get_default_cursor_size() and
|
||||
* gdk_display_get_maximal_cursor_size() for the limitations that might apply.
|
||||
* and provide an image to use for the cursor.
|
||||
*
|
||||
* To ease work with unsupported cursors, a fallback cursor can be provided.
|
||||
* If a #GdkSurface cannot use a cursor because of the reasons mentioned above,
|
||||
@@ -346,18 +341,6 @@ gdk_cursor_new_from_name (const gchar *name,
|
||||
*
|
||||
* Creates a new cursor from a #GdkTexture.
|
||||
*
|
||||
* Not all GDK backends support RGBA cursors. If they are not
|
||||
* supported, a monochrome approximation will be displayed.
|
||||
* The functions gdk_display_supports_cursor_alpha() and
|
||||
* gdk_display_supports_cursor_color() can be used to determine
|
||||
* whether RGBA cursors are supported;
|
||||
* gdk_display_get_default_cursor_size() and
|
||||
* gdk_display_get_maximal_cursor_size() give information about
|
||||
* cursor sizes.
|
||||
*
|
||||
* On the X backend, support for RGBA cursors requires a
|
||||
* sufficently new version of the X Render extension.
|
||||
*
|
||||
* Returns: a new #GdkCursor.
|
||||
*/
|
||||
GdkCursor *
|
||||
|
@@ -112,9 +112,6 @@ struct _GdkDeviceClass
|
||||
double *win_y,
|
||||
GdkModifierType *mask,
|
||||
gboolean get_toplevel);
|
||||
void (* select_surface_events) (GdkDevice *device,
|
||||
GdkSurface *surface,
|
||||
GdkEventMask event_mask);
|
||||
};
|
||||
|
||||
void _gdk_device_set_associated_device (GdkDevice *device,
|
||||
|
@@ -47,8 +47,6 @@ typedef struct _GdkDeviceTool GdkDeviceTool;
|
||||
*
|
||||
* Indicates the specific type of tool being used being a tablet. Such as an
|
||||
* airbrush, pencil, etc.
|
||||
*
|
||||
* Since: 3.22
|
||||
*/
|
||||
typedef enum {
|
||||
GDK_DEVICE_TOOL_TYPE_UNKNOWN,
|
||||
|
@@ -492,8 +492,6 @@ gdk_display_put_event_nocopy (GdkDisplay *display,
|
||||
GdkEvent *event)
|
||||
{
|
||||
_gdk_event_queue_append (display, event);
|
||||
/* If the main loop is blocking in a different thread, wake it up */
|
||||
g_main_context_wakeup (NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -633,8 +631,7 @@ get_current_toplevel (GdkDisplay *display,
|
||||
pointer_surface = _gdk_device_surface_at_position (device, &x, &y, &state, TRUE);
|
||||
|
||||
if (pointer_surface != NULL &&
|
||||
(GDK_SURFACE_DESTROYED (pointer_surface) ||
|
||||
GDK_SURFACE_TYPE (pointer_surface) == GDK_SURFACE_FOREIGN))
|
||||
GDK_SURFACE_DESTROYED (pointer_surface))
|
||||
pointer_surface = NULL;
|
||||
|
||||
*x_out = round (x);
|
||||
@@ -1283,6 +1280,26 @@ gdk_display_notify_startup_complete (GdkDisplay *display,
|
||||
GDK_DISPLAY_GET_CLASS (display)->notify_startup_complete (display, startup_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_display_get_startup_notification_id:
|
||||
* @display: a #GdkDisplay
|
||||
*
|
||||
* Gets the startup notification ID for a Wayland display, or %NULL
|
||||
* if no ID has been defined.
|
||||
*
|
||||
* Returns: the startup notification ID for @display, or %NULL
|
||||
*/
|
||||
const gchar *
|
||||
gdk_display_get_startup_notification_id (GdkDisplay *display)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
|
||||
|
||||
if (GDK_DISPLAY_GET_CLASS (display)->get_startup_notification_id == NULL)
|
||||
return NULL;
|
||||
|
||||
return GDK_DISPLAY_GET_CLASS (display)->get_startup_notification_id (display);
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_display_pause_events (GdkDisplay *display)
|
||||
{
|
||||
@@ -1313,17 +1330,15 @@ _gdk_display_event_data_free (GdkDisplay *display,
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_display_create_surface_impl (GdkDisplay *display,
|
||||
GdkSurface *surface,
|
||||
GdkSurface *real_parent,
|
||||
GdkEventMask event_mask,
|
||||
GdkSurfaceAttr *attributes)
|
||||
gdk_display_create_surface_impl (GdkDisplay *display,
|
||||
GdkSurface *surface,
|
||||
GdkSurface *real_parent,
|
||||
GdkSurfaceAttr *attributes)
|
||||
{
|
||||
GDK_DISPLAY_GET_CLASS (display)->create_surface_impl (display,
|
||||
surface,
|
||||
real_parent,
|
||||
event_mask,
|
||||
attributes);
|
||||
surface,
|
||||
real_parent,
|
||||
attributes);
|
||||
}
|
||||
|
||||
GdkSurface *
|
||||
|
@@ -94,6 +94,8 @@ gboolean gdk_display_supports_input_shapes (GdkDisplay *display);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_display_notify_startup_complete (GdkDisplay *display,
|
||||
const gchar *startup_id);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
const gchar * gdk_display_get_startup_notification_id (GdkDisplay *display);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkAppLaunchContext *gdk_display_get_app_launch_context (GdkDisplay *display);
|
||||
|
@@ -136,6 +136,8 @@ struct _GdkDisplayClass
|
||||
|
||||
void (*notify_startup_complete) (GdkDisplay *display,
|
||||
const gchar *startup_id);
|
||||
const gchar * (*get_startup_notification_id) (GdkDisplay *display);
|
||||
|
||||
void (*event_data_copy) (GdkDisplay *display,
|
||||
const GdkEvent *event,
|
||||
GdkEvent *new_event);
|
||||
@@ -144,7 +146,6 @@ struct _GdkDisplayClass
|
||||
void (*create_surface_impl) (GdkDisplay *display,
|
||||
GdkSurface *surface,
|
||||
GdkSurface *real_parent,
|
||||
GdkEventMask event_mask,
|
||||
GdkSurfaceAttr *attributes);
|
||||
|
||||
GdkKeymap * (*get_keymap) (GdkDisplay *display);
|
||||
@@ -231,10 +232,9 @@ void _gdk_display_event_data_copy (GdkDisplay *display
|
||||
GdkEvent *new_event);
|
||||
void _gdk_display_event_data_free (GdkDisplay *display,
|
||||
GdkEvent *event);
|
||||
void _gdk_display_create_surface_impl (GdkDisplay *display,
|
||||
void gdk_display_create_surface_impl (GdkDisplay *display,
|
||||
GdkSurface *surface,
|
||||
GdkSurface *real_parent,
|
||||
GdkEventMask event_mask,
|
||||
GdkSurfaceAttr *attributes);
|
||||
GdkSurface * _gdk_display_create_surface (GdkDisplay *display);
|
||||
|
||||
|
954
gdk/gdkdnd.c
954
gdk/gdkdnd.c
@@ -1,954 +0,0 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 1995-1999 Peter Mattis, Spencer Kimball and Josh MacDonald
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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/.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gdkdndprivate.h"
|
||||
#include "gdkdisplay.h"
|
||||
#include "gdksurface.h"
|
||||
#include "gdkintl.h"
|
||||
#include "gdkcontentformats.h"
|
||||
#include "gdkcontentprovider.h"
|
||||
#include "gdkcontentserializer.h"
|
||||
#include "gdkcursor.h"
|
||||
#include "gdkenumtypes.h"
|
||||
#include "gdkeventsprivate.h"
|
||||
|
||||
typedef struct _GdkDragContextPrivate GdkDragContextPrivate;
|
||||
|
||||
struct _GdkDragContextPrivate
|
||||
{
|
||||
GdkDisplay *display;
|
||||
GdkDevice *device;
|
||||
GdkContentFormats *formats;
|
||||
};
|
||||
|
||||
static struct {
|
||||
GdkDragAction action;
|
||||
const gchar *name;
|
||||
GdkCursor *cursor;
|
||||
} drag_cursors[] = {
|
||||
{ GDK_ACTION_DEFAULT, NULL, NULL },
|
||||
{ GDK_ACTION_ASK, "dnd-ask", NULL },
|
||||
{ GDK_ACTION_COPY, "dnd-copy", NULL },
|
||||
{ GDK_ACTION_MOVE, "dnd-move", NULL },
|
||||
{ GDK_ACTION_LINK, "dnd-link", NULL },
|
||||
{ 0, "dnd-none", NULL },
|
||||
};
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_CONTENT,
|
||||
PROP_DEVICE,
|
||||
PROP_DISPLAY,
|
||||
PROP_FORMATS,
|
||||
N_PROPERTIES
|
||||
};
|
||||
|
||||
enum {
|
||||
CANCEL,
|
||||
DROP_PERFORMED,
|
||||
DND_FINISHED,
|
||||
ACTION_CHANGED,
|
||||
N_SIGNALS
|
||||
};
|
||||
|
||||
static GParamSpec *properties[N_PROPERTIES] = { NULL, };
|
||||
static guint signals[N_SIGNALS] = { 0 };
|
||||
static GList *contexts = NULL;
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (GdkDragContext, gdk_drag_context, G_TYPE_OBJECT)
|
||||
|
||||
/**
|
||||
* SECTION:dnd
|
||||
* @title: Drag And Drop
|
||||
* @short_description: Functions for controlling drag and drop handling
|
||||
*
|
||||
* These functions provide a low level interface for drag and drop.
|
||||
* The X backend of GDK supports both the Xdnd and Motif drag and drop
|
||||
* protocols transparently, the Win32 backend supports the WM_DROPFILES
|
||||
* protocol.
|
||||
*
|
||||
* GTK+ provides a higher level abstraction based on top of these functions,
|
||||
* and so they are not normally needed in GTK+ applications.
|
||||
* See the [Drag and Drop][gtk3-Drag-and-Drop] section of
|
||||
* the GTK+ documentation for more information.
|
||||
*/
|
||||
|
||||
/**
|
||||
* GdkDragContext:
|
||||
*
|
||||
* The GdkDragContext struct contains only private fields and
|
||||
* should not be accessed directly.
|
||||
*/
|
||||
|
||||
/**
|
||||
* gdk_drag_context_get_display:
|
||||
* @context: a #GdkDragContext
|
||||
*
|
||||
* Gets the #GdkDisplay that the drag context was created for.
|
||||
*
|
||||
* Returns: (transfer none): a #GdkDisplay
|
||||
**/
|
||||
GdkDisplay *
|
||||
gdk_drag_context_get_display (GdkDragContext *context)
|
||||
{
|
||||
GdkDragContextPrivate *priv = gdk_drag_context_get_instance_private (context);
|
||||
|
||||
g_return_val_if_fail (GDK_IS_DRAG_CONTEXT (context), NULL);
|
||||
|
||||
return priv->display;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_drag_context_get_formats:
|
||||
* @context: a #GdkDragContext
|
||||
*
|
||||
* Retrieves the formats supported by this context.
|
||||
*
|
||||
* Returns: (transfer none): a #GdkContentFormats
|
||||
**/
|
||||
GdkContentFormats *
|
||||
gdk_drag_context_get_formats (GdkDragContext *context)
|
||||
{
|
||||
GdkDragContextPrivate *priv = gdk_drag_context_get_instance_private (context);
|
||||
|
||||
g_return_val_if_fail (GDK_IS_DRAG_CONTEXT (context), NULL);
|
||||
|
||||
return priv->formats;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_drag_context_get_actions:
|
||||
* @context: a #GdkDragContext
|
||||
*
|
||||
* Determines the bitmask of actions proposed by the source if
|
||||
* gdk_drag_context_get_suggested_action() returns %GDK_ACTION_ASK.
|
||||
*
|
||||
* Returns: the #GdkDragAction flags
|
||||
**/
|
||||
GdkDragAction
|
||||
gdk_drag_context_get_actions (GdkDragContext *context)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_DRAG_CONTEXT (context), GDK_ACTION_DEFAULT);
|
||||
|
||||
return context->actions;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_drag_context_get_suggested_action:
|
||||
* @context: a #GdkDragContext
|
||||
*
|
||||
* Determines the suggested drag action of the context.
|
||||
*
|
||||
* Returns: a #GdkDragAction value
|
||||
**/
|
||||
GdkDragAction
|
||||
gdk_drag_context_get_suggested_action (GdkDragContext *context)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_DRAG_CONTEXT (context), 0);
|
||||
|
||||
return context->suggested_action;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_drag_context_get_selected_action:
|
||||
* @context: a #GdkDragContext
|
||||
*
|
||||
* Determines the action chosen by the drag destination.
|
||||
*
|
||||
* Returns: a #GdkDragAction value
|
||||
**/
|
||||
GdkDragAction
|
||||
gdk_drag_context_get_selected_action (GdkDragContext *context)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_DRAG_CONTEXT (context), 0);
|
||||
|
||||
return context->action;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_drag_context_get_source_surface:
|
||||
* @context: a #GdkDragContext
|
||||
*
|
||||
* Returns the #GdkSurface where the DND operation started.
|
||||
*
|
||||
* Returns: (transfer none): a #GdkSurface
|
||||
**/
|
||||
GdkSurface *
|
||||
gdk_drag_context_get_source_surface (GdkDragContext *context)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_DRAG_CONTEXT (context), NULL);
|
||||
|
||||
return context->source_surface;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_drag_context_get_dest_surface:
|
||||
* @context: a #GdkDragContext
|
||||
*
|
||||
* Returns the destination surface for the DND operation.
|
||||
*
|
||||
* Returns: (transfer none): a #GdkSurface
|
||||
**/
|
||||
GdkSurface *
|
||||
gdk_drag_context_get_dest_surface (GdkDragContext *context)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_DRAG_CONTEXT (context), NULL);
|
||||
|
||||
return context->dest_surface;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_drag_context_get_device:
|
||||
* @context: a #GdkDragContext
|
||||
*
|
||||
* Returns the #GdkDevice associated to the drag context.
|
||||
*
|
||||
* Returns: (transfer none): The #GdkDevice associated to @context.
|
||||
**/
|
||||
GdkDevice *
|
||||
gdk_drag_context_get_device (GdkDragContext *context)
|
||||
{
|
||||
GdkDragContextPrivate *priv = gdk_drag_context_get_instance_private (context);
|
||||
|
||||
g_return_val_if_fail (GDK_IS_DRAG_CONTEXT (context), NULL);
|
||||
|
||||
return priv->device;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_drag_context_init (GdkDragContext *context)
|
||||
{
|
||||
contexts = g_list_prepend (contexts, context);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_drag_context_set_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GdkDragContext *context = GDK_DRAG_CONTEXT (gobject);
|
||||
GdkDragContextPrivate *priv = gdk_drag_context_get_instance_private (context);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_CONTENT:
|
||||
context->content = g_value_dup_object (value);
|
||||
if (context->content)
|
||||
{
|
||||
g_assert (priv->formats == NULL);
|
||||
priv->formats = gdk_content_provider_ref_formats (context->content);
|
||||
}
|
||||
break;
|
||||
|
||||
case PROP_DEVICE:
|
||||
priv->device = g_value_dup_object (value);
|
||||
g_assert (priv->device != NULL);
|
||||
priv->display = gdk_device_get_display (priv->device);
|
||||
break;
|
||||
|
||||
case PROP_FORMATS:
|
||||
if (priv->formats)
|
||||
{
|
||||
GdkContentFormats *override = g_value_dup_boxed (value);
|
||||
if (override)
|
||||
{
|
||||
gdk_content_formats_unref (priv->formats);
|
||||
priv->formats = override;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
priv->formats = g_value_dup_boxed (value);
|
||||
g_assert (priv->formats != NULL);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_drag_context_get_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GdkDragContext *context = GDK_DRAG_CONTEXT (gobject);
|
||||
GdkDragContextPrivate *priv = gdk_drag_context_get_instance_private (context);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_CONTENT:
|
||||
g_value_set_object (value, context->content);
|
||||
break;
|
||||
|
||||
case PROP_DEVICE:
|
||||
g_value_set_object (value, priv->device);
|
||||
break;
|
||||
|
||||
case PROP_DISPLAY:
|
||||
g_value_set_object (value, priv->display);
|
||||
break;
|
||||
|
||||
case PROP_FORMATS:
|
||||
g_value_set_boxed (value, priv->formats);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_drag_context_finalize (GObject *object)
|
||||
{
|
||||
GdkDragContext *context = GDK_DRAG_CONTEXT (object);
|
||||
GdkDragContextPrivate *priv = gdk_drag_context_get_instance_private (context);
|
||||
|
||||
contexts = g_list_remove (contexts, context);
|
||||
|
||||
g_clear_object (&context->content);
|
||||
g_clear_pointer (&priv->formats, gdk_content_formats_unref);
|
||||
|
||||
if (context->source_surface)
|
||||
g_object_unref (context->source_surface);
|
||||
|
||||
if (context->dest_surface)
|
||||
g_object_unref (context->dest_surface);
|
||||
|
||||
G_OBJECT_CLASS (gdk_drag_context_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_drag_context_read_local_async (GdkDragContext *context,
|
||||
GdkContentFormats *formats,
|
||||
int io_priority,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
GTask *task;
|
||||
|
||||
task = g_task_new (context, cancellable, callback, user_data);
|
||||
g_task_set_priority (task, io_priority);
|
||||
g_task_set_source_tag (task, gdk_drag_context_read_local_async);
|
||||
|
||||
g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
|
||||
_("Reading not implemented."));
|
||||
g_object_unref (task);
|
||||
}
|
||||
|
||||
static GInputStream *
|
||||
gdk_drag_context_read_local_finish (GdkDragContext *context,
|
||||
const char **out_mime_type,
|
||||
GAsyncResult *result,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (g_task_is_valid (result, context), NULL);
|
||||
g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) == gdk_drag_context_read_local_async, NULL);
|
||||
|
||||
if (out_mime_type)
|
||||
*out_mime_type = g_task_get_task_data (G_TASK (result));
|
||||
|
||||
return g_task_propagate_pointer (G_TASK (result), error);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_drag_context_class_init (GdkDragContextClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->get_property = gdk_drag_context_get_property;
|
||||
object_class->set_property = gdk_drag_context_set_property;
|
||||
object_class->finalize = gdk_drag_context_finalize;
|
||||
|
||||
/**
|
||||
* GdkDragContext:content:
|
||||
*
|
||||
* The #GdkContentProvider or %NULL if the context is not a source-side
|
||||
* context.
|
||||
*/
|
||||
properties[PROP_CONTENT] =
|
||||
g_param_spec_object ("content",
|
||||
"Content",
|
||||
"The content being dragged",
|
||||
GDK_TYPE_CONTENT_PROVIDER,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
/**
|
||||
* GdkDragContext:device:
|
||||
*
|
||||
* The #GdkDevice that is performing the drag.
|
||||
*/
|
||||
properties[PROP_DEVICE] =
|
||||
g_param_spec_object ("device",
|
||||
"Device",
|
||||
"The device performing the drag",
|
||||
GDK_TYPE_DEVICE,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
/**
|
||||
* GdkDragContext:display:
|
||||
*
|
||||
* The #GdkDisplay that the drag context belongs to.
|
||||
*/
|
||||
properties[PROP_DISPLAY] =
|
||||
g_param_spec_object ("display",
|
||||
"Display",
|
||||
"Display this drag belongs to",
|
||||
GDK_TYPE_DISPLAY,
|
||||
G_PARAM_READABLE |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
/**
|
||||
* GdkDragContext:formats:
|
||||
*
|
||||
* The possible formats that the context can provide its data in.
|
||||
*/
|
||||
properties[PROP_FORMATS] =
|
||||
g_param_spec_boxed ("formats",
|
||||
"Formats",
|
||||
"The possible formats for data",
|
||||
GDK_TYPE_CONTENT_FORMATS,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
/**
|
||||
* GdkDragContext::cancel:
|
||||
* @context: The object on which the signal is emitted
|
||||
* @reason: The reason the context was cancelled
|
||||
*
|
||||
* The drag and drop operation was cancelled.
|
||||
*/
|
||||
signals[CANCEL] =
|
||||
g_signal_new (g_intern_static_string ("cancel"),
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GdkDragContextClass, cancel),
|
||||
NULL, NULL,
|
||||
g_cclosure_marshal_VOID__ENUM,
|
||||
G_TYPE_NONE, 1, GDK_TYPE_DRAG_CANCEL_REASON);
|
||||
|
||||
/**
|
||||
* GdkDragContext::drop-performed:
|
||||
* @context: The object on which the signal is emitted
|
||||
* @time: the time at which the drop happened.
|
||||
*
|
||||
* The drag and drop operation was performed on an accepting client.
|
||||
*/
|
||||
signals[DROP_PERFORMED] =
|
||||
g_signal_new (g_intern_static_string ("drop-performed"),
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GdkDragContextClass, drop_performed),
|
||||
NULL, NULL,
|
||||
g_cclosure_marshal_VOID__INT,
|
||||
G_TYPE_NONE, 1, G_TYPE_INT);
|
||||
|
||||
/**
|
||||
* GdkDragContext::dnd-finished:
|
||||
* @context: The object on which the signal is emitted
|
||||
*
|
||||
* The drag and drop operation was finished, the drag destination
|
||||
* finished reading all data. The drag source can now free all
|
||||
* miscellaneous data.
|
||||
*/
|
||||
signals[DND_FINISHED] =
|
||||
g_signal_new (g_intern_static_string ("dnd-finished"),
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GdkDragContextClass, dnd_finished),
|
||||
NULL, NULL,
|
||||
g_cclosure_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
/**
|
||||
* GdkDragContext::action-changed:
|
||||
* @context: The object on which the signal is emitted
|
||||
* @action: The action currently chosen
|
||||
*
|
||||
* A new action is being chosen for the drag and drop operation.
|
||||
*/
|
||||
signals[ACTION_CHANGED] =
|
||||
g_signal_new (g_intern_static_string ("action-changed"),
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GdkDragContextClass, action_changed),
|
||||
NULL, NULL,
|
||||
g_cclosure_marshal_VOID__FLAGS,
|
||||
G_TYPE_NONE, 1, GDK_TYPE_DRAG_ACTION);
|
||||
|
||||
g_object_class_install_properties (object_class, N_PROPERTIES, properties);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_drag_status:
|
||||
* @context: a #GdkDragContext
|
||||
* @action: the selected action which will be taken when a drop happens,
|
||||
* or 0 to indicate that a drop will not be accepted
|
||||
* @time_: the timestamp for this operation
|
||||
*
|
||||
* Selects one of the actions offered by the drag source.
|
||||
*
|
||||
* This function is called by the drag destination in response to
|
||||
* gdk_drag_motion() called by the drag source.
|
||||
*/
|
||||
void
|
||||
gdk_drag_status (GdkDragContext *context,
|
||||
GdkDragAction action,
|
||||
guint32 time_)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_DRAG_CONTEXT (context));
|
||||
|
||||
GDK_DRAG_CONTEXT_GET_CLASS (context)->drag_status (context, action, time_);
|
||||
}
|
||||
|
||||
/*
|
||||
* gdk_drag_abort:
|
||||
* @context: a #GdkDragContext
|
||||
* @time_: the timestamp for this operation
|
||||
*
|
||||
* Aborts a drag without dropping.
|
||||
*
|
||||
* This function is called by the drag source.
|
||||
*/
|
||||
void
|
||||
gdk_drag_abort (GdkDragContext *context,
|
||||
guint32 time_)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_DRAG_CONTEXT (context));
|
||||
|
||||
GDK_DRAG_CONTEXT_GET_CLASS (context)->drag_abort (context, time_);
|
||||
}
|
||||
|
||||
/*
|
||||
* gdk_drag_drop:
|
||||
* @context: a #GdkDragContext
|
||||
* @time_: the timestamp for this operation
|
||||
*
|
||||
* Drops on the current destination.
|
||||
*
|
||||
* This function is called by the drag source.
|
||||
*/
|
||||
void
|
||||
gdk_drag_drop (GdkDragContext *context,
|
||||
guint32 time_)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_DRAG_CONTEXT (context));
|
||||
|
||||
GDK_DRAG_CONTEXT_GET_CLASS (context)->drag_drop (context, time_);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_drop_finish:
|
||||
* @context: a #GdkDragContext
|
||||
* @success: %TRUE if the data was successfully received
|
||||
* @time_: the timestamp for this operation
|
||||
*
|
||||
* Ends the drag operation after a drop.
|
||||
*
|
||||
* This function is called by the drag destination.
|
||||
*/
|
||||
void
|
||||
gdk_drop_finish (GdkDragContext *context,
|
||||
gboolean success,
|
||||
guint32 time_)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_DRAG_CONTEXT (context));
|
||||
|
||||
GDK_DRAG_CONTEXT_GET_CLASS (context)->drop_finish (context, success, time_);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_drag_context_write_done (GObject *content,
|
||||
GAsyncResult *result,
|
||||
gpointer task)
|
||||
{
|
||||
GError *error = NULL;
|
||||
|
||||
if (gdk_content_provider_write_mime_type_finish (GDK_CONTENT_PROVIDER (content), result, &error))
|
||||
g_task_return_boolean (task, TRUE);
|
||||
else
|
||||
g_task_return_error (task, error);
|
||||
|
||||
g_object_unref (task);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_drag_context_write_serialize_done (GObject *content,
|
||||
GAsyncResult *result,
|
||||
gpointer task)
|
||||
{
|
||||
GError *error = NULL;
|
||||
|
||||
if (gdk_content_serialize_finish (result, &error))
|
||||
g_task_return_boolean (task, TRUE);
|
||||
else
|
||||
g_task_return_error (task, error);
|
||||
|
||||
g_object_unref (task);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_drag_context_write_async (GdkDragContext *context,
|
||||
const char *mime_type,
|
||||
GOutputStream *stream,
|
||||
int io_priority,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
GdkContentFormats *formats, *mime_formats;
|
||||
GTask *task;
|
||||
GType gtype;
|
||||
|
||||
g_return_if_fail (GDK_IS_DRAG_CONTEXT (context));
|
||||
g_return_if_fail (context->content);
|
||||
g_return_if_fail (mime_type != NULL);
|
||||
g_return_if_fail (mime_type == g_intern_string (mime_type));
|
||||
g_return_if_fail (G_IS_OUTPUT_STREAM (stream));
|
||||
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
|
||||
g_return_if_fail (callback != NULL);
|
||||
|
||||
task = g_task_new (context, cancellable, callback, user_data);
|
||||
g_task_set_priority (task, io_priority);
|
||||
g_task_set_source_tag (task, gdk_drag_context_write_async);
|
||||
|
||||
formats = gdk_content_provider_ref_formats (context->content);
|
||||
if (gdk_content_formats_contain_mime_type (formats, mime_type))
|
||||
{
|
||||
gdk_content_provider_write_mime_type_async (context->content,
|
||||
mime_type,
|
||||
stream,
|
||||
io_priority,
|
||||
cancellable,
|
||||
gdk_drag_context_write_done,
|
||||
task);
|
||||
gdk_content_formats_unref (formats);
|
||||
return;
|
||||
}
|
||||
|
||||
mime_formats = gdk_content_formats_new ((const gchar *[2]) { mime_type, NULL }, 1);
|
||||
mime_formats = gdk_content_formats_union_serialize_gtypes (mime_formats);
|
||||
gtype = gdk_content_formats_match_gtype (formats, mime_formats);
|
||||
if (gtype != G_TYPE_INVALID)
|
||||
{
|
||||
GValue value = G_VALUE_INIT;
|
||||
GError *error = NULL;
|
||||
|
||||
g_assert (gtype != G_TYPE_INVALID);
|
||||
|
||||
g_value_init (&value, gtype);
|
||||
if (gdk_content_provider_get_value (context->content, &value, &error))
|
||||
{
|
||||
gdk_content_serialize_async (stream,
|
||||
mime_type,
|
||||
&value,
|
||||
io_priority,
|
||||
cancellable,
|
||||
gdk_drag_context_write_serialize_done,
|
||||
g_object_ref (task));
|
||||
}
|
||||
else
|
||||
{
|
||||
g_task_return_error (task, error);
|
||||
}
|
||||
|
||||
g_value_unset (&value);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
|
||||
_("No compatible formats to transfer clipboard contents."));
|
||||
}
|
||||
|
||||
gdk_content_formats_unref (mime_formats);
|
||||
gdk_content_formats_unref (formats);
|
||||
g_object_unref (task);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gdk_drag_context_write_finish (GdkDragContext *context,
|
||||
GAsyncResult *result,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (g_task_is_valid (result, context), FALSE);
|
||||
g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) == gdk_drag_context_write_async, FALSE);
|
||||
|
||||
return g_task_propagate_boolean (G_TASK (result), error);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_drop_read_async:
|
||||
* @context: a #GdkDragContext
|
||||
* @mime_types: (array zero-terminated=1) (element-type utf8): pointer to an array of mime types
|
||||
* @io_priority: the io priority for the read operation
|
||||
* @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore
|
||||
* @callback: (scope async): a #GAsyncReadyCallback to call when the request is satisfied
|
||||
* @user_data: (closure): the data to pass to @callback
|
||||
*
|
||||
* Asynchronously read the dropped data from a DND context
|
||||
* in a format that complies with one of the mime types.
|
||||
*/
|
||||
void
|
||||
gdk_drop_read_async (GdkDragContext *context,
|
||||
const char **mime_types,
|
||||
int io_priority,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
GdkContentFormats *formats;
|
||||
|
||||
g_return_if_fail (GDK_IS_DRAG_CONTEXT (context));
|
||||
g_return_if_fail (mime_types != NULL && mime_types[0] != NULL);
|
||||
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
|
||||
g_return_if_fail (callback != NULL);
|
||||
|
||||
formats = gdk_content_formats_new (mime_types, g_strv_length ((char **) mime_types));
|
||||
|
||||
GDK_DRAG_CONTEXT_GET_CLASS (context)->read_async (context,
|
||||
formats,
|
||||
io_priority,
|
||||
cancellable,
|
||||
callback,
|
||||
user_data);
|
||||
|
||||
gdk_content_formats_unref (formats);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_drop_read_finish:
|
||||
* @context: a #GdkDragContext
|
||||
* @out_mime_type: (out) (type utf8): return location for the used mime type
|
||||
* @result: a #GAsyncResult
|
||||
* @error: (allow-none): location to store error information on failure, or %NULL
|
||||
*
|
||||
* Finishes an async drop read operation, see gdk_drop_read_async().
|
||||
*
|
||||
* Returns: (nullable) (transfer full): the #GInputStream, or %NULL
|
||||
*/
|
||||
GInputStream *
|
||||
gdk_drop_read_finish (GdkDragContext *context,
|
||||
const char **out_mime_type,
|
||||
GAsyncResult *result,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_DRAG_CONTEXT (context), NULL);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
||||
|
||||
if (g_async_result_is_tagged (result, gdk_drag_context_read_local_async))
|
||||
{
|
||||
return gdk_drag_context_read_local_finish (context, out_mime_type, result, error);
|
||||
}
|
||||
else
|
||||
{
|
||||
return GDK_DRAG_CONTEXT_GET_CLASS (context)->read_finish (context, out_mime_type, result, error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_drag_context_get_drag_surface:
|
||||
* @context: a #GdkDragContext
|
||||
*
|
||||
* Returns the surface on which the drag icon should be rendered
|
||||
* during the drag operation. Note that the surface may not be
|
||||
* available until the drag operation has begun. GDK will move
|
||||
* the surface in accordance with the ongoing drag operation.
|
||||
* The surface is owned by @context and will be destroyed when
|
||||
* the drag operation is over.
|
||||
*
|
||||
* Returns: (nullable) (transfer none): the drag surface, or %NULL
|
||||
*/
|
||||
GdkSurface *
|
||||
gdk_drag_context_get_drag_surface (GdkDragContext *context)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_DRAG_CONTEXT (context), NULL);
|
||||
|
||||
if (GDK_DRAG_CONTEXT_GET_CLASS (context)->get_drag_surface)
|
||||
return GDK_DRAG_CONTEXT_GET_CLASS (context)->get_drag_surface (context);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_drag_context_set_hotspot:
|
||||
* @context: a #GdkDragContext
|
||||
* @hot_x: x coordinate of the drag surface hotspot
|
||||
* @hot_y: y coordinate of the drag surface hotspot
|
||||
*
|
||||
* Sets the position of the drag surface that will be kept
|
||||
* under the cursor hotspot. Initially, the hotspot is at the
|
||||
* top left corner of the drag surface.
|
||||
*/
|
||||
void
|
||||
gdk_drag_context_set_hotspot (GdkDragContext *context,
|
||||
gint hot_x,
|
||||
gint hot_y)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_DRAG_CONTEXT (context));
|
||||
|
||||
if (GDK_DRAG_CONTEXT_GET_CLASS (context)->set_hotspot)
|
||||
GDK_DRAG_CONTEXT_GET_CLASS (context)->set_hotspot (context, hot_x, hot_y);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_drag_drop_done:
|
||||
* @context: a #GdkDragContext
|
||||
* @success: whether the drag was ultimatively successful
|
||||
*
|
||||
* Inform GDK if the drop ended successfully. Passing %FALSE
|
||||
* for @success may trigger a drag cancellation animation.
|
||||
*
|
||||
* This function is called by the drag source, and should
|
||||
* be the last call before dropping the reference to the
|
||||
* @context.
|
||||
*
|
||||
* The #GdkDragContext will only take the first gdk_drag_drop_done()
|
||||
* call as effective, if this function is called multiple times,
|
||||
* all subsequent calls will be ignored.
|
||||
*/
|
||||
void
|
||||
gdk_drag_drop_done (GdkDragContext *context,
|
||||
gboolean success)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_DRAG_CONTEXT (context));
|
||||
|
||||
if (context->drop_done)
|
||||
return;
|
||||
|
||||
context->drop_done = TRUE;
|
||||
|
||||
if (GDK_DRAG_CONTEXT_GET_CLASS (context)->drop_done)
|
||||
GDK_DRAG_CONTEXT_GET_CLASS (context)->drop_done (context, success);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_drag_context_set_cursor (GdkDragContext *context,
|
||||
GdkCursor *cursor)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_DRAG_CONTEXT (context));
|
||||
|
||||
if (GDK_DRAG_CONTEXT_GET_CLASS (context)->set_cursor)
|
||||
GDK_DRAG_CONTEXT_GET_CLASS (context)->set_cursor (context, cursor);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_drag_context_cancel (GdkDragContext *context,
|
||||
GdkDragCancelReason reason)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_DRAG_CONTEXT (context));
|
||||
|
||||
g_signal_emit (context, signals[CANCEL], 0, reason);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gdk_drag_context_handle_source_event (GdkEvent *event)
|
||||
{
|
||||
GdkDragContext *context;
|
||||
GList *l;
|
||||
|
||||
for (l = contexts; l; l = l->next)
|
||||
{
|
||||
context = l->data;
|
||||
|
||||
if (!context->is_source)
|
||||
continue;
|
||||
|
||||
if (!GDK_DRAG_CONTEXT_GET_CLASS (context)->handle_event)
|
||||
continue;
|
||||
|
||||
if (GDK_DRAG_CONTEXT_GET_CLASS (context)->handle_event (context, event))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
GdkCursor *
|
||||
gdk_drag_get_cursor (GdkDragContext *context,
|
||||
GdkDragAction action)
|
||||
{
|
||||
gint i;
|
||||
|
||||
for (i = 0 ; i < G_N_ELEMENTS (drag_cursors) - 1; i++)
|
||||
if (drag_cursors[i].action == action)
|
||||
break;
|
||||
|
||||
if (drag_cursors[i].cursor == NULL)
|
||||
drag_cursors[i].cursor = gdk_cursor_new_from_name (drag_cursors[i].name, NULL);
|
||||
|
||||
return drag_cursors[i].cursor;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_drag_context_commit_drag_status (GdkDragContext *context)
|
||||
{
|
||||
GdkDragContextClass *context_class;
|
||||
|
||||
g_return_if_fail (GDK_IS_DRAG_CONTEXT (context));
|
||||
g_return_if_fail (!context->is_source);
|
||||
|
||||
context_class = GDK_DRAG_CONTEXT_GET_CLASS (context);
|
||||
|
||||
if (context_class->commit_drag_status)
|
||||
context_class->commit_drag_status (context);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gdk_drag_context_handle_dest_event (GdkEvent *event)
|
||||
{
|
||||
GdkDragContext *context = NULL;
|
||||
|
||||
switch ((guint) event->any.type)
|
||||
{
|
||||
case GDK_DRAG_MOTION:
|
||||
case GDK_DROP_START:
|
||||
context = event->dnd.context;
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!context)
|
||||
return FALSE;
|
||||
|
||||
gdk_drag_context_commit_drag_status (context);
|
||||
return TRUE;;
|
||||
}
|
152
gdk/gdkdnd.h
152
gdk/gdkdnd.h
@@ -1,152 +0,0 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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/.
|
||||
*/
|
||||
|
||||
#ifndef __GDK_DND_H__
|
||||
#define __GDK_DND_H__
|
||||
|
||||
#if !defined (__GDK_H_INSIDE__) && !defined (GDK_COMPILATION)
|
||||
#error "Only <gdk/gdk.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <gdk/gdktypes.h>
|
||||
#include <gdk/gdkdevice.h>
|
||||
#include <gdk/gdkevents.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GDK_TYPE_DRAG_CONTEXT (gdk_drag_context_get_type ())
|
||||
#define GDK_DRAG_CONTEXT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_DRAG_CONTEXT, GdkDragContext))
|
||||
#define GDK_IS_DRAG_CONTEXT(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_DRAG_CONTEXT))
|
||||
|
||||
/**
|
||||
* GdkDragAction:
|
||||
* @GDK_ACTION_DEFAULT: Means nothing, and should not be used.
|
||||
* @GDK_ACTION_COPY: Copy the data.
|
||||
* @GDK_ACTION_MOVE: Move the data, i.e. first copy it, then delete
|
||||
* it from the source using the DELETE target of the X selection protocol.
|
||||
* @GDK_ACTION_LINK: Add a link to the data. Note that this is only
|
||||
* useful if source and destination agree on what it means.
|
||||
* @GDK_ACTION_PRIVATE: Special action which tells the source that the
|
||||
* destination will do something that the source doesn’t understand.
|
||||
* @GDK_ACTION_ASK: Ask the user what to do with the data.
|
||||
*
|
||||
* Used in #GdkDragContext to indicate what the destination
|
||||
* should do with the dropped data.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
GDK_ACTION_DEFAULT = 1 << 0,
|
||||
GDK_ACTION_COPY = 1 << 1,
|
||||
GDK_ACTION_MOVE = 1 << 2,
|
||||
GDK_ACTION_LINK = 1 << 3,
|
||||
GDK_ACTION_PRIVATE = 1 << 4,
|
||||
GDK_ACTION_ASK = 1 << 5
|
||||
} GdkDragAction;
|
||||
|
||||
/**
|
||||
* GdkDragCancelReason:
|
||||
* @GDK_DRAG_CANCEL_NO_TARGET: There is no suitable drop target.
|
||||
* @GDK_DRAG_CANCEL_USER_CANCELLED: Drag cancelled by the user
|
||||
* @GDK_DRAG_CANCEL_ERROR: Unspecified error.
|
||||
*
|
||||
* Used in #GdkDragContext to the reason of a cancelled DND operation.
|
||||
*
|
||||
* Since: 3.20
|
||||
*/
|
||||
typedef enum {
|
||||
GDK_DRAG_CANCEL_NO_TARGET,
|
||||
GDK_DRAG_CANCEL_USER_CANCELLED,
|
||||
GDK_DRAG_CANCEL_ERROR
|
||||
} GdkDragCancelReason;
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GType gdk_drag_context_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkDisplay * gdk_drag_context_get_display (GdkDragContext *context);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkDevice * gdk_drag_context_get_device (GdkDragContext *context);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkContentFormats *gdk_drag_context_get_formats (GdkDragContext *context);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkDragAction gdk_drag_context_get_actions (GdkDragContext *context);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkDragAction gdk_drag_context_get_suggested_action (GdkDragContext *context);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkDragAction gdk_drag_context_get_selected_action (GdkDragContext *context);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkSurface *gdk_drag_context_get_source_surface (GdkDragContext *context);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkSurface *gdk_drag_context_get_dest_surface (GdkDragContext *context);
|
||||
|
||||
/* Destination side */
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_drag_status (GdkDragContext *context,
|
||||
GdkDragAction action,
|
||||
guint32 time_);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_drop_finish (GdkDragContext *context,
|
||||
gboolean success,
|
||||
guint32 time_);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_drop_read_async (GdkDragContext *context,
|
||||
const char **mime_types,
|
||||
int io_priority,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GInputStream * gdk_drop_read_finish (GdkDragContext *context,
|
||||
const char **out_mime_type,
|
||||
GAsyncResult *result,
|
||||
GError **error);
|
||||
|
||||
/* Source side */
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkDragContext * gdk_drag_begin (GdkSurface *surface,
|
||||
GdkDevice *device,
|
||||
GdkContentProvider *content,
|
||||
GdkDragAction actions,
|
||||
gint dx,
|
||||
gint dy);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_drag_drop_done (GdkDragContext *context,
|
||||
gboolean success);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkSurface *gdk_drag_context_get_drag_surface (GdkDragContext *context);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_drag_context_set_hotspot (GdkDragContext *context,
|
||||
gint hot_x,
|
||||
gint hot_y);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_DND_H__ */
|
@@ -1,124 +0,0 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2010, 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/>.
|
||||
*/
|
||||
|
||||
#ifndef __GDK_DND_PRIVATE_H__
|
||||
#define __GDK_DND_PRIVATE_H__
|
||||
|
||||
#include "gdkdnd.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
||||
#define GDK_DRAG_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_DRAG_CONTEXT, GdkDragContextClass))
|
||||
#define GDK_IS_DRAG_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_DRAG_CONTEXT))
|
||||
#define GDK_DRAG_CONTEXT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_DRAG_CONTEXT, GdkDragContextClass))
|
||||
|
||||
typedef struct _GdkDragContextClass GdkDragContextClass;
|
||||
|
||||
|
||||
struct _GdkDragContextClass {
|
||||
GObjectClass parent_class;
|
||||
|
||||
void (*drag_status) (GdkDragContext *context,
|
||||
GdkDragAction action,
|
||||
guint32 time_);
|
||||
void (*drag_abort) (GdkDragContext *context,
|
||||
guint32 time_);
|
||||
void (*drag_drop) (GdkDragContext *context,
|
||||
guint32 time_);
|
||||
void (*drop_finish) (GdkDragContext *context,
|
||||
gboolean success,
|
||||
guint32 time_);
|
||||
void (* read_async) (GdkDragContext *context,
|
||||
GdkContentFormats *formats,
|
||||
int io_priority,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
GInputStream * (* read_finish) (GdkDragContext *context,
|
||||
const char **out_mime_type,
|
||||
GAsyncResult *result,
|
||||
GError **error);
|
||||
GdkSurface* (*get_drag_surface) (GdkDragContext *context);
|
||||
void (*set_hotspot) (GdkDragContext *context,
|
||||
gint hot_x,
|
||||
gint hot_y);
|
||||
void (*drop_done) (GdkDragContext *context,
|
||||
gboolean success);
|
||||
|
||||
void (*set_cursor) (GdkDragContext *context,
|
||||
GdkCursor *cursor);
|
||||
void (*cancel) (GdkDragContext *context,
|
||||
GdkDragCancelReason reason);
|
||||
void (*drop_performed) (GdkDragContext *context,
|
||||
guint32 time);
|
||||
void (*dnd_finished) (GdkDragContext *context);
|
||||
|
||||
gboolean (*handle_event) (GdkDragContext *context,
|
||||
const GdkEvent *event);
|
||||
void (*action_changed) (GdkDragContext *context,
|
||||
GdkDragAction action);
|
||||
|
||||
void (*commit_drag_status) (GdkDragContext *context);
|
||||
};
|
||||
|
||||
struct _GdkDragContext {
|
||||
GObject parent_instance;
|
||||
|
||||
/*< private >*/
|
||||
gboolean is_source;
|
||||
GdkSurface *source_surface;
|
||||
GdkSurface *dest_surface;
|
||||
GdkSurface *drag_surface;
|
||||
|
||||
GdkContentProvider *content;
|
||||
GdkDragAction actions;
|
||||
GdkDragAction suggested_action;
|
||||
GdkDragAction action;
|
||||
|
||||
guint drop_done : 1; /* Whether gdk_drag_drop_done() was performed */
|
||||
};
|
||||
|
||||
void gdk_drag_context_set_cursor (GdkDragContext *context,
|
||||
GdkCursor *cursor);
|
||||
void gdk_drag_context_cancel (GdkDragContext *context,
|
||||
GdkDragCancelReason reason);
|
||||
gboolean gdk_drag_context_handle_source_event (GdkEvent *event);
|
||||
gboolean gdk_drag_context_handle_dest_event (GdkEvent *event);
|
||||
GdkCursor * gdk_drag_get_cursor (GdkDragContext *context,
|
||||
GdkDragAction action);
|
||||
|
||||
void gdk_drag_abort (GdkDragContext *context,
|
||||
guint32 time_);
|
||||
void gdk_drag_drop (GdkDragContext *context,
|
||||
guint32 time_);
|
||||
|
||||
void gdk_drag_context_write_async (GdkDragContext *context,
|
||||
const char *mime_type,
|
||||
GOutputStream *stream,
|
||||
int io_priority,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
gboolean gdk_drag_context_write_finish (GdkDragContext *context,
|
||||
GAsyncResult *result,
|
||||
GError **error);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif
|
792
gdk/gdkdrag.c
Normal file
792
gdk/gdkdrag.c
Normal file
@@ -0,0 +1,792 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 1995-1999 Peter Mattis, Spencer Kimball and Josh MacDonald
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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/.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gdkdragprivate.h"
|
||||
#include "gdkdisplay.h"
|
||||
#include "gdksurface.h"
|
||||
#include "gdkintl.h"
|
||||
#include "gdkcontentformats.h"
|
||||
#include "gdkcontentprovider.h"
|
||||
#include "gdkcontentserializer.h"
|
||||
#include "gdkcursor.h"
|
||||
#include "gdkenumtypes.h"
|
||||
#include "gdkeventsprivate.h"
|
||||
|
||||
static struct {
|
||||
GdkDragAction action;
|
||||
const gchar *name;
|
||||
GdkCursor *cursor;
|
||||
} drag_cursors[] = {
|
||||
{ GDK_ACTION_ASK, "dnd-ask", NULL },
|
||||
{ GDK_ACTION_COPY, "dnd-copy", NULL },
|
||||
{ GDK_ACTION_MOVE, "dnd-move", NULL },
|
||||
{ GDK_ACTION_LINK, "dnd-link", NULL },
|
||||
{ 0, "dnd-none", NULL },
|
||||
};
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_CONTENT,
|
||||
PROP_DEVICE,
|
||||
PROP_DISPLAY,
|
||||
PROP_FORMATS,
|
||||
PROP_SELECTED_ACTION,
|
||||
PROP_ACTIONS,
|
||||
PROP_SURFACE,
|
||||
N_PROPERTIES
|
||||
};
|
||||
|
||||
enum {
|
||||
CANCEL,
|
||||
DROP_PERFORMED,
|
||||
DND_FINISHED,
|
||||
N_SIGNALS
|
||||
};
|
||||
|
||||
typedef struct _GdkDragPrivate GdkDragPrivate;
|
||||
|
||||
struct _GdkDragPrivate {
|
||||
GdkSurface *surface;
|
||||
|
||||
GdkDisplay *display;
|
||||
GdkDevice *device;
|
||||
GdkContentFormats *formats;
|
||||
GdkContentProvider *content;
|
||||
|
||||
GdkDragAction actions;
|
||||
GdkDragAction selected_action;
|
||||
|
||||
guint drop_done : 1; /* Whether gdk_drag_drop_done() was performed */
|
||||
};
|
||||
|
||||
static GParamSpec *properties[N_PROPERTIES] = { NULL, };
|
||||
static guint signals[N_SIGNALS] = { 0 };
|
||||
static GList *drags = NULL;
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GdkDrag, gdk_drag, G_TYPE_OBJECT)
|
||||
|
||||
/**
|
||||
* SECTION:dnd
|
||||
* @title: Drag And Drop
|
||||
* @short_description: Functions for controlling drag and drop handling
|
||||
*
|
||||
* These functions provide a low level interface for drag and drop.
|
||||
*
|
||||
* The GdkDrag object represents the source side of an ongoing DND operation.
|
||||
* It is created when a drag is started, and stays alive for duration of
|
||||
* the DND operation.
|
||||
*
|
||||
* The GdkDrop object represents the target side of an ongoing DND operation.
|
||||
*
|
||||
* GTK+ provides a higher level abstraction based on top of these functions,
|
||||
* and so they are not normally needed in GTK+ applications. See the
|
||||
* [Drag and Drop][gtk4-Drag-and-Drop] section of the GTK+ documentation
|
||||
* for more information.
|
||||
*/
|
||||
|
||||
/**
|
||||
* GdkDrag:
|
||||
*
|
||||
* The GdkDrag struct contains only private fields and
|
||||
* should not be accessed directly.
|
||||
*/
|
||||
|
||||
/**
|
||||
* gdk_drag_get_display:
|
||||
* @drag: a #GdkDrag
|
||||
*
|
||||
* Gets the #GdkDisplay that the drag object was created for.
|
||||
*
|
||||
* Returns: (transfer none): a #GdkDisplay
|
||||
**/
|
||||
GdkDisplay *
|
||||
gdk_drag_get_display (GdkDrag *drag)
|
||||
{
|
||||
GdkDragPrivate *priv = gdk_drag_get_instance_private (drag);
|
||||
|
||||
g_return_val_if_fail (GDK_IS_DRAG (drag), NULL);
|
||||
|
||||
return priv->display;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_drag_get_formats:
|
||||
* @drag: a #GdkDrag
|
||||
*
|
||||
* Retrieves the formats supported by this GdkDrag object.
|
||||
*
|
||||
* Returns: (transfer none): a #GdkContentFormats
|
||||
**/
|
||||
GdkContentFormats *
|
||||
gdk_drag_get_formats (GdkDrag *drag)
|
||||
{
|
||||
GdkDragPrivate *priv = gdk_drag_get_instance_private (drag);
|
||||
|
||||
g_return_val_if_fail (GDK_IS_DRAG (drag), NULL);
|
||||
|
||||
return priv->formats;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_drag_get_actions:
|
||||
* @drag: a #GdkDrag
|
||||
*
|
||||
* Determines the bitmask of possible actions proposed by the source.
|
||||
*
|
||||
* Returns: the #GdkDragAction flags
|
||||
**/
|
||||
GdkDragAction
|
||||
gdk_drag_get_actions (GdkDrag *drag)
|
||||
{
|
||||
GdkDragPrivate *priv = gdk_drag_get_instance_private (drag);
|
||||
|
||||
g_return_val_if_fail (GDK_IS_DRAG (drag), 0);
|
||||
|
||||
return priv->actions;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_drag_get_selected_action:
|
||||
* @drag: a #GdkDrag
|
||||
*
|
||||
* Determines the action chosen by the drag destination.
|
||||
*
|
||||
* Returns: a #GdkDragAction value
|
||||
**/
|
||||
GdkDragAction
|
||||
gdk_drag_get_selected_action (GdkDrag *drag)
|
||||
{
|
||||
GdkDragPrivate *priv = gdk_drag_get_instance_private (drag);
|
||||
|
||||
g_return_val_if_fail (GDK_IS_DRAG (drag), 0);
|
||||
|
||||
return priv->selected_action;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_drag_get_device:
|
||||
* @drag: a #GdkDrag
|
||||
*
|
||||
* Returns the #GdkDevice associated to the GdkDrag object.
|
||||
*
|
||||
* Returns: (transfer none): The #GdkDevice associated to @drag.
|
||||
**/
|
||||
GdkDevice *
|
||||
gdk_drag_get_device (GdkDrag *drag)
|
||||
{
|
||||
GdkDragPrivate *priv = gdk_drag_get_instance_private (drag);
|
||||
|
||||
g_return_val_if_fail (GDK_IS_DRAG (drag), NULL);
|
||||
|
||||
return priv->device;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_drag_init (GdkDrag *drag)
|
||||
{
|
||||
drags = g_list_prepend (drags, drag);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_drag_set_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GdkDrag *drag = GDK_DRAG (gobject);
|
||||
GdkDragPrivate *priv = gdk_drag_get_instance_private (drag);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_CONTENT:
|
||||
priv->content = g_value_dup_object (value);
|
||||
if (priv->content)
|
||||
{
|
||||
g_assert (priv->formats == NULL);
|
||||
priv->formats = gdk_content_provider_ref_formats (priv->content);
|
||||
}
|
||||
break;
|
||||
|
||||
case PROP_DEVICE:
|
||||
priv->device = g_value_dup_object (value);
|
||||
g_assert (priv->device != NULL);
|
||||
priv->display = gdk_device_get_display (priv->device);
|
||||
break;
|
||||
|
||||
case PROP_FORMATS:
|
||||
if (priv->formats)
|
||||
{
|
||||
GdkContentFormats *override = g_value_dup_boxed (value);
|
||||
if (override)
|
||||
{
|
||||
gdk_content_formats_unref (priv->formats);
|
||||
priv->formats = override;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
priv->formats = g_value_dup_boxed (value);
|
||||
g_assert (priv->formats != NULL);
|
||||
}
|
||||
break;
|
||||
|
||||
case PROP_SELECTED_ACTION:
|
||||
{
|
||||
GdkDragAction action = g_value_get_flags (value);
|
||||
gdk_drag_set_selected_action (drag, action);
|
||||
}
|
||||
break;
|
||||
|
||||
case PROP_ACTIONS:
|
||||
{
|
||||
GdkDragAction actions = g_value_get_flags (value);
|
||||
gdk_drag_set_actions (drag, actions);
|
||||
}
|
||||
break;
|
||||
|
||||
case PROP_SURFACE:
|
||||
priv->surface = g_value_dup_object (value);
|
||||
g_assert (priv->surface != NULL);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_drag_get_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GdkDrag *drag = GDK_DRAG (gobject);
|
||||
GdkDragPrivate *priv = gdk_drag_get_instance_private (drag);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_CONTENT:
|
||||
g_value_set_object (value, priv->content);
|
||||
break;
|
||||
|
||||
case PROP_DEVICE:
|
||||
g_value_set_object (value, priv->device);
|
||||
break;
|
||||
|
||||
case PROP_DISPLAY:
|
||||
g_value_set_object (value, priv->display);
|
||||
break;
|
||||
|
||||
case PROP_FORMATS:
|
||||
g_value_set_boxed (value, priv->formats);
|
||||
break;
|
||||
|
||||
case PROP_SELECTED_ACTION:
|
||||
g_value_set_flags (value, priv->selected_action);
|
||||
break;
|
||||
|
||||
case PROP_ACTIONS:
|
||||
g_value_set_flags (value, priv->actions);
|
||||
break;
|
||||
|
||||
case PROP_SURFACE:
|
||||
g_value_set_object (value, priv->surface);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_drag_finalize (GObject *object)
|
||||
{
|
||||
GdkDrag *drag = GDK_DRAG (object);
|
||||
GdkDragPrivate *priv = gdk_drag_get_instance_private (drag);
|
||||
|
||||
drags = g_list_remove (drags, drag);
|
||||
|
||||
g_clear_object (&priv->content);
|
||||
g_clear_pointer (&priv->formats, gdk_content_formats_unref);
|
||||
|
||||
g_clear_object (&priv->surface);
|
||||
|
||||
G_OBJECT_CLASS (gdk_drag_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_drag_class_init (GdkDragClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->get_property = gdk_drag_get_property;
|
||||
object_class->set_property = gdk_drag_set_property;
|
||||
object_class->finalize = gdk_drag_finalize;
|
||||
|
||||
/**
|
||||
* GdkDrag:content:
|
||||
*
|
||||
* The #GdkContentProvider.
|
||||
*/
|
||||
properties[PROP_CONTENT] =
|
||||
g_param_spec_object ("content",
|
||||
"Content",
|
||||
"The content being dragged",
|
||||
GDK_TYPE_CONTENT_PROVIDER,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
/**
|
||||
* GdkDrag:device:
|
||||
*
|
||||
* The #GdkDevice that is performing the drag.
|
||||
*/
|
||||
properties[PROP_DEVICE] =
|
||||
g_param_spec_object ("device",
|
||||
"Device",
|
||||
"The device performing the drag",
|
||||
GDK_TYPE_DEVICE,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
/**
|
||||
* GdkDrag:display:
|
||||
*
|
||||
* The #GdkDisplay that the drag belongs to.
|
||||
*/
|
||||
properties[PROP_DISPLAY] =
|
||||
g_param_spec_object ("display",
|
||||
"Display",
|
||||
"Display this drag belongs to",
|
||||
GDK_TYPE_DISPLAY,
|
||||
G_PARAM_READABLE |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
/**
|
||||
* GdkDrag:formats:
|
||||
*
|
||||
* The possible formats that the drag can provide its data in.
|
||||
*/
|
||||
properties[PROP_FORMATS] =
|
||||
g_param_spec_boxed ("formats",
|
||||
"Formats",
|
||||
"The possible formats for data",
|
||||
GDK_TYPE_CONTENT_FORMATS,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
properties[PROP_SELECTED_ACTION] =
|
||||
g_param_spec_flags ("selected-action",
|
||||
"Selected action",
|
||||
"The currently selected action",
|
||||
GDK_TYPE_DRAG_ACTION,
|
||||
0,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
properties[PROP_ACTIONS] =
|
||||
g_param_spec_flags ("actions",
|
||||
"Actions",
|
||||
"The possible actions",
|
||||
GDK_TYPE_DRAG_ACTION,
|
||||
0,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
properties[PROP_SURFACE] =
|
||||
g_param_spec_object ("surface",
|
||||
"Surface",
|
||||
"The surface where the drag originates",
|
||||
GDK_TYPE_SURFACE,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
/**
|
||||
* GdkDrag::cancel:
|
||||
* @drag: The object on which the signal is emitted
|
||||
* @reason: The reason the drag was cancelled
|
||||
*
|
||||
* The drag operation was cancelled.
|
||||
*/
|
||||
signals[CANCEL] =
|
||||
g_signal_new (g_intern_static_string ("cancel"),
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GdkDragClass, cancel),
|
||||
NULL, NULL,
|
||||
g_cclosure_marshal_VOID__ENUM,
|
||||
G_TYPE_NONE, 1, GDK_TYPE_DRAG_CANCEL_REASON);
|
||||
|
||||
/**
|
||||
* GdkDrag::drop-performed:
|
||||
* @drag: The object on which the signal is emitted
|
||||
*
|
||||
* The drag operation was performed on an accepting client.
|
||||
*/
|
||||
signals[DROP_PERFORMED] =
|
||||
g_signal_new (g_intern_static_string ("drop-performed"),
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GdkDragClass, drop_performed),
|
||||
NULL, NULL,
|
||||
g_cclosure_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
/**
|
||||
* GdkDrag::dnd-finished:
|
||||
* @drag: The object on which the signal is emitted
|
||||
*
|
||||
* The drag operation was finished, the destination
|
||||
* finished reading all data. The drag object can now
|
||||
* free all miscellaneous data.
|
||||
*/
|
||||
signals[DND_FINISHED] =
|
||||
g_signal_new (g_intern_static_string ("dnd-finished"),
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GdkDragClass, dnd_finished),
|
||||
NULL, NULL,
|
||||
g_cclosure_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
g_object_class_install_properties (object_class, N_PROPERTIES, properties);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_drag_write_done (GObject *content,
|
||||
GAsyncResult *result,
|
||||
gpointer task)
|
||||
{
|
||||
GError *error = NULL;
|
||||
|
||||
if (gdk_content_provider_write_mime_type_finish (GDK_CONTENT_PROVIDER (content), result, &error))
|
||||
g_task_return_boolean (task, TRUE);
|
||||
else
|
||||
g_task_return_error (task, error);
|
||||
|
||||
g_object_unref (task);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_drag_write_serialize_done (GObject *content,
|
||||
GAsyncResult *result,
|
||||
gpointer task)
|
||||
{
|
||||
GError *error = NULL;
|
||||
|
||||
if (gdk_content_serialize_finish (result, &error))
|
||||
g_task_return_boolean (task, TRUE);
|
||||
else
|
||||
g_task_return_error (task, error);
|
||||
|
||||
g_object_unref (task);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_drag_write_async (GdkDrag *drag,
|
||||
const char *mime_type,
|
||||
GOutputStream *stream,
|
||||
int io_priority,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
GdkDragPrivate *priv = gdk_drag_get_instance_private (drag);
|
||||
GdkContentFormats *formats, *mime_formats;
|
||||
GTask *task;
|
||||
GType gtype;
|
||||
|
||||
g_return_if_fail (GDK_IS_DRAG (drag));
|
||||
g_return_if_fail (priv->content);
|
||||
g_return_if_fail (mime_type != NULL);
|
||||
g_return_if_fail (mime_type == g_intern_string (mime_type));
|
||||
g_return_if_fail (G_IS_OUTPUT_STREAM (stream));
|
||||
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
|
||||
g_return_if_fail (callback != NULL);
|
||||
|
||||
task = g_task_new (drag, cancellable, callback, user_data);
|
||||
g_task_set_priority (task, io_priority);
|
||||
g_task_set_source_tag (task, gdk_drag_write_async);
|
||||
|
||||
formats = gdk_content_provider_ref_formats (priv->content);
|
||||
if (gdk_content_formats_contain_mime_type (formats, mime_type))
|
||||
{
|
||||
gdk_content_provider_write_mime_type_async (priv->content,
|
||||
mime_type,
|
||||
stream,
|
||||
io_priority,
|
||||
cancellable,
|
||||
gdk_drag_write_done,
|
||||
task);
|
||||
gdk_content_formats_unref (formats);
|
||||
return;
|
||||
}
|
||||
|
||||
mime_formats = gdk_content_formats_new ((const gchar *[2]) { mime_type, NULL }, 1);
|
||||
mime_formats = gdk_content_formats_union_serialize_gtypes (mime_formats);
|
||||
gtype = gdk_content_formats_match_gtype (formats, mime_formats);
|
||||
if (gtype != G_TYPE_INVALID)
|
||||
{
|
||||
GValue value = G_VALUE_INIT;
|
||||
GError *error = NULL;
|
||||
|
||||
g_assert (gtype != G_TYPE_INVALID);
|
||||
|
||||
g_value_init (&value, gtype);
|
||||
if (gdk_content_provider_get_value (priv->content, &value, &error))
|
||||
{
|
||||
gdk_content_serialize_async (stream,
|
||||
mime_type,
|
||||
&value,
|
||||
io_priority,
|
||||
cancellable,
|
||||
gdk_drag_write_serialize_done,
|
||||
g_object_ref (task));
|
||||
}
|
||||
else
|
||||
{
|
||||
g_task_return_error (task, error);
|
||||
}
|
||||
|
||||
g_value_unset (&value);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
|
||||
_("No compatible formats to transfer clipboard contents."));
|
||||
}
|
||||
|
||||
gdk_content_formats_unref (mime_formats);
|
||||
gdk_content_formats_unref (formats);
|
||||
g_object_unref (task);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gdk_drag_write_finish (GdkDrag *drag,
|
||||
GAsyncResult *result,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (g_task_is_valid (result, drag), FALSE);
|
||||
g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) == gdk_drag_write_async, FALSE);
|
||||
|
||||
return g_task_propagate_boolean (G_TASK (result), error);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_drag_set_actions (GdkDrag *drag,
|
||||
GdkDragAction actions)
|
||||
{
|
||||
GdkDragPrivate *priv = gdk_drag_get_instance_private (drag);
|
||||
|
||||
if (priv->actions == actions)
|
||||
return;
|
||||
|
||||
priv->actions = actions;
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (drag), properties[PROP_ACTIONS]);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_drag_set_selected_action (GdkDrag *drag,
|
||||
GdkDragAction action)
|
||||
{
|
||||
GdkDragPrivate *priv = gdk_drag_get_instance_private (drag);
|
||||
GdkCursor *cursor;
|
||||
|
||||
if (priv->selected_action == action)
|
||||
return;
|
||||
|
||||
priv->selected_action = action;
|
||||
|
||||
cursor = gdk_drag_get_cursor (drag, action);
|
||||
gdk_drag_set_cursor (drag, cursor);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (drag), properties[PROP_SELECTED_ACTION]);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_drag_get_drag_surface:
|
||||
* @drag: a #GdkDrag
|
||||
*
|
||||
* Returns the surface on which the drag icon should be rendered
|
||||
* during the drag operation. Note that the surface may not be
|
||||
* available until the drag operation has begun. GDK will move
|
||||
* the surface in accordance with the ongoing drag operation.
|
||||
* The surface is owned by @drag and will be destroyed when
|
||||
* the drag operation is over.
|
||||
*
|
||||
* Returns: (nullable) (transfer none): the drag surface, or %NULL
|
||||
*/
|
||||
GdkSurface *
|
||||
gdk_drag_get_drag_surface (GdkDrag *drag)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_DRAG (drag), NULL);
|
||||
|
||||
if (GDK_DRAG_GET_CLASS (drag)->get_drag_surface)
|
||||
return GDK_DRAG_GET_CLASS (drag)->get_drag_surface (drag);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_drag_set_hotspot:
|
||||
* @drag: a #GdkDrag
|
||||
* @hot_x: x coordinate of the drag surface hotspot
|
||||
* @hot_y: y coordinate of the drag surface hotspot
|
||||
*
|
||||
* Sets the position of the drag surface that will be kept
|
||||
* under the cursor hotspot. Initially, the hotspot is at the
|
||||
* top left corner of the drag surface.
|
||||
*/
|
||||
void
|
||||
gdk_drag_set_hotspot (GdkDrag *drag,
|
||||
gint hot_x,
|
||||
gint hot_y)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_DRAG (drag));
|
||||
|
||||
if (GDK_DRAG_GET_CLASS (drag)->set_hotspot)
|
||||
GDK_DRAG_GET_CLASS (drag)->set_hotspot (drag, hot_x, hot_y);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_drag_drop_done:
|
||||
* @drag: a #GdkDrag
|
||||
* @success: whether the drag was ultimatively successful
|
||||
*
|
||||
* Inform GDK if the drop ended successfully. Passing %FALSE
|
||||
* for @success may trigger a drag cancellation animation.
|
||||
*
|
||||
* This function is called by the drag source, and should
|
||||
* be the last call before dropping the reference to the
|
||||
* @drag.
|
||||
*
|
||||
* The #GdkDrag will only take the first gdk_drag_drop_done()
|
||||
* call as effective, if this function is called multiple times,
|
||||
* all subsequent calls will be ignored.
|
||||
*/
|
||||
void
|
||||
gdk_drag_drop_done (GdkDrag *drag,
|
||||
gboolean success)
|
||||
{
|
||||
GdkDragPrivate *priv = gdk_drag_get_instance_private (drag);
|
||||
|
||||
g_return_if_fail (GDK_IS_DRAG (drag));
|
||||
|
||||
if (priv->drop_done)
|
||||
return;
|
||||
|
||||
priv->drop_done = TRUE;
|
||||
|
||||
if (GDK_DRAG_GET_CLASS (drag)->drop_done)
|
||||
GDK_DRAG_GET_CLASS (drag)->drop_done (drag, success);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_drag_set_cursor (GdkDrag *drag,
|
||||
GdkCursor *cursor)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_DRAG (drag));
|
||||
|
||||
if (GDK_DRAG_GET_CLASS (drag)->set_cursor)
|
||||
GDK_DRAG_GET_CLASS (drag)->set_cursor (drag, cursor);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_drag_cancel (GdkDrag *drag,
|
||||
GdkDragCancelReason reason)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_DRAG (drag));
|
||||
|
||||
g_signal_emit (drag, signals[CANCEL], 0, reason);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gdk_drag_handle_source_event (GdkEvent *event)
|
||||
{
|
||||
GdkDrag *drag;
|
||||
GList *l;
|
||||
|
||||
for (l = drags; l; l = l->next)
|
||||
{
|
||||
drag = l->data;
|
||||
|
||||
if (!GDK_DRAG_GET_CLASS (drag)->handle_event)
|
||||
continue;
|
||||
|
||||
if (GDK_DRAG_GET_CLASS (drag)->handle_event (drag, event))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
GdkCursor *
|
||||
gdk_drag_get_cursor (GdkDrag *drag,
|
||||
GdkDragAction action)
|
||||
{
|
||||
gint i;
|
||||
|
||||
for (i = 0 ; i < G_N_ELEMENTS (drag_cursors) - 1; i++)
|
||||
if (drag_cursors[i].action == action)
|
||||
break;
|
||||
|
||||
if (drag_cursors[i].cursor == NULL)
|
||||
drag_cursors[i].cursor = gdk_cursor_new_from_name (drag_cursors[i].name, NULL);
|
||||
|
||||
return drag_cursors[i].cursor;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_drag_action_is_unique:
|
||||
* @action: a #GdkDragAction
|
||||
*
|
||||
* Checks if @action represents a single action or if it
|
||||
* includes multiple flags that can be selected from.
|
||||
*
|
||||
* When @action is 0 - ie no action was given, %TRUE
|
||||
* is returned.
|
||||
*
|
||||
* Returns: %TRUE if exactly one action was given
|
||||
**/
|
||||
gboolean
|
||||
gdk_drag_action_is_unique (GdkDragAction action)
|
||||
{
|
||||
return (action & (action - 1)) == 0;
|
||||
}
|
96
gdk/gdkdrag.h
Normal file
96
gdk/gdkdrag.h
Normal file
@@ -0,0 +1,96 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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/.
|
||||
*/
|
||||
|
||||
#ifndef __GDK_DND_H__
|
||||
#define __GDK_DND_H__
|
||||
|
||||
#if !defined (__GDK_H_INSIDE__) && !defined (GDK_COMPILATION)
|
||||
#error "Only <gdk/gdk.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <gdk/gdktypes.h>
|
||||
#include <gdk/gdkdevice.h>
|
||||
#include <gdk/gdkevents.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GDK_TYPE_DRAG (gdk_drag_get_type ())
|
||||
#define GDK_DRAG(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_DRAG, GdkDrag))
|
||||
#define GDK_IS_DRAG(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_DRAG))
|
||||
|
||||
/**
|
||||
* GdkDragCancelReason:
|
||||
* @GDK_DRAG_CANCEL_NO_TARGET: There is no suitable drop target.
|
||||
* @GDK_DRAG_CANCEL_USER_CANCELLED: Drag cancelled by the user
|
||||
* @GDK_DRAG_CANCEL_ERROR: Unspecified error.
|
||||
*
|
||||
* Used in #GdkDrag to the reason of a cancelled DND operation.
|
||||
*/
|
||||
typedef enum {
|
||||
GDK_DRAG_CANCEL_NO_TARGET,
|
||||
GDK_DRAG_CANCEL_USER_CANCELLED,
|
||||
GDK_DRAG_CANCEL_ERROR
|
||||
} GdkDragCancelReason;
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GType gdk_drag_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkDisplay * gdk_drag_get_display (GdkDrag *drag);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkDevice * gdk_drag_get_device (GdkDrag *drag);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkContentFormats *gdk_drag_get_formats (GdkDrag *drag);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkDragAction gdk_drag_get_actions (GdkDrag *drag);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkDragAction gdk_drag_get_selected_action (GdkDrag *drag);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gdk_drag_action_is_unique (GdkDragAction action);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkDrag * gdk_drag_begin (GdkSurface *surface,
|
||||
GdkDevice *device,
|
||||
GdkContentProvider *content,
|
||||
GdkDragAction actions,
|
||||
gint dx,
|
||||
gint dy);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_drag_drop_done (GdkDrag *drag,
|
||||
gboolean success);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkSurface *gdk_drag_get_drag_surface (GdkDrag *drag);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_drag_set_hotspot (GdkDrag *drag,
|
||||
gint hot_x,
|
||||
gint hot_y);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_DND_H__ */
|
86
gdk/gdkdragprivate.h
Normal file
86
gdk/gdkdragprivate.h
Normal file
@@ -0,0 +1,86 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2010, 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/>.
|
||||
*/
|
||||
|
||||
#ifndef __GDK_DND_PRIVATE_H__
|
||||
#define __GDK_DND_PRIVATE_H__
|
||||
|
||||
#include "gdkdrag.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
||||
#define GDK_DRAG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_DRAG, GdkDragClass))
|
||||
#define GDK_IS_DRAG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_DRAG))
|
||||
#define GDK_DRAG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_DRAG, GdkDragClass))
|
||||
|
||||
typedef struct _GdkDragClass GdkDragClass;
|
||||
|
||||
|
||||
struct _GdkDragClass {
|
||||
GObjectClass parent_class;
|
||||
|
||||
GdkSurface* (*get_drag_surface) (GdkDrag *drag);
|
||||
void (*set_hotspot) (GdkDrag *drag,
|
||||
gint hot_x,
|
||||
gint hot_y);
|
||||
void (*drop_done) (GdkDrag *drag,
|
||||
gboolean success);
|
||||
|
||||
void (*set_cursor) (GdkDrag *drag,
|
||||
GdkCursor *cursor);
|
||||
void (*cancel) (GdkDrag *drag,
|
||||
GdkDragCancelReason reason);
|
||||
void (*drop_performed) (GdkDrag *drag,
|
||||
guint32 time);
|
||||
void (*dnd_finished) (GdkDrag *drag);
|
||||
|
||||
gboolean (*handle_event) (GdkDrag *drag,
|
||||
const GdkEvent *event);
|
||||
};
|
||||
|
||||
struct _GdkDrag {
|
||||
GObject parent_instance;
|
||||
};
|
||||
|
||||
void gdk_drag_set_cursor (GdkDrag *drag,
|
||||
GdkCursor *cursor);
|
||||
void gdk_drag_set_actions (GdkDrag *drag,
|
||||
GdkDragAction actions);
|
||||
void gdk_drag_set_selected_action (GdkDrag *drag,
|
||||
GdkDragAction action);
|
||||
|
||||
void gdk_drag_cancel (GdkDrag *drag,
|
||||
GdkDragCancelReason reason);
|
||||
gboolean gdk_drag_handle_source_event (GdkEvent *event);
|
||||
GdkCursor * gdk_drag_get_cursor (GdkDrag *drag,
|
||||
GdkDragAction action);
|
||||
|
||||
void gdk_drag_write_async (GdkDrag *drag,
|
||||
const char *mime_type,
|
||||
GOutputStream *stream,
|
||||
int io_priority,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
gboolean gdk_drag_write_finish (GdkDrag *drag,
|
||||
GAsyncResult *result,
|
||||
GError **error);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif
|
990
gdk/gdkdrop.c
Normal file
990
gdk/gdkdrop.c
Normal file
@@ -0,0 +1,990 @@
|
||||
/*
|
||||
* Copyright © 2018 Benjamin Otte
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Benjamin Otte <otte@gnome.org>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gdkdropprivate.h"
|
||||
|
||||
#include "gdkcontentdeserializer.h"
|
||||
#include "gdkcontentformats.h"
|
||||
#include "gdkcontentprovider.h"
|
||||
#include "gdkcontentserializer.h"
|
||||
#include "gdkcursor.h"
|
||||
#include "gdkdisplay.h"
|
||||
#include "gdkenumtypes.h"
|
||||
#include "gdkeventsprivate.h"
|
||||
#include "gdkinternals.h"
|
||||
#include "gdkintl.h"
|
||||
#include "gdkpipeiostreamprivate.h"
|
||||
#include "gdksurface.h"
|
||||
|
||||
typedef struct _GdkDropPrivate GdkDropPrivate;
|
||||
|
||||
struct _GdkDropPrivate {
|
||||
GdkDevice *device;
|
||||
GdkDrag *drag;
|
||||
GdkContentFormats *formats;
|
||||
GdkSurface *surface;
|
||||
GdkDragAction actions;
|
||||
};
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_ACTIONS,
|
||||
PROP_DEVICE,
|
||||
PROP_DISPLAY,
|
||||
PROP_DRAG,
|
||||
PROP_FORMATS,
|
||||
PROP_SURFACE,
|
||||
N_PROPERTIES
|
||||
};
|
||||
|
||||
static GParamSpec *properties[N_PROPERTIES] = { NULL, };
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GdkDrop, gdk_drop, G_TYPE_OBJECT)
|
||||
|
||||
/**
|
||||
* GdkDrop:
|
||||
*
|
||||
* The GdkDrop struct contains only private fields and
|
||||
* should not be accessed directly.
|
||||
*/
|
||||
|
||||
static void
|
||||
gdk_drop_default_status (GdkDrop *self,
|
||||
GdkDragAction actions)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_drop_read_local_write_done (GObject *drag,
|
||||
GAsyncResult *result,
|
||||
gpointer stream)
|
||||
{
|
||||
/* we don't care about the error, we just want to clean up */
|
||||
gdk_drag_write_finish (GDK_DRAG (drag), result, NULL);
|
||||
|
||||
/* XXX: Do we need to close_async() here? */
|
||||
g_output_stream_close (stream, NULL, NULL);
|
||||
|
||||
g_object_unref (stream);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_drop_read_local_async (GdkDrop *self,
|
||||
GdkContentFormats *formats,
|
||||
int io_priority,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
GdkDropPrivate *priv = gdk_drop_get_instance_private (self);
|
||||
GdkContentFormats *content_formats;
|
||||
const char *mime_type;
|
||||
GTask *task;
|
||||
GdkContentProvider *content;
|
||||
|
||||
task = g_task_new (self, cancellable, callback, user_data);
|
||||
g_task_set_priority (task, io_priority);
|
||||
g_task_set_source_tag (task, gdk_drop_read_local_async);
|
||||
|
||||
if (priv->drag == NULL)
|
||||
{
|
||||
g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
|
||||
_("Drag’n’drop from other applications is not supported."));
|
||||
g_object_unref (task);
|
||||
return;
|
||||
}
|
||||
|
||||
g_object_get (priv->drag, "content", &content, NULL);
|
||||
content_formats = gdk_content_provider_ref_formats (content);
|
||||
g_object_unref (content);
|
||||
content_formats = gdk_content_formats_union_serialize_mime_types (content_formats);
|
||||
mime_type = gdk_content_formats_match_mime_type (content_formats, formats);
|
||||
|
||||
if (mime_type != NULL)
|
||||
{
|
||||
GOutputStream *output_stream;
|
||||
GIOStream *stream;
|
||||
|
||||
stream = gdk_pipe_io_stream_new ();
|
||||
output_stream = g_io_stream_get_output_stream (stream);
|
||||
gdk_drag_write_async (priv->drag,
|
||||
mime_type,
|
||||
output_stream,
|
||||
io_priority,
|
||||
cancellable,
|
||||
gdk_drop_read_local_write_done,
|
||||
g_object_ref (output_stream));
|
||||
g_task_set_task_data (task, (gpointer) mime_type, NULL);
|
||||
g_task_return_pointer (task, g_object_ref (g_io_stream_get_input_stream (stream)), g_object_unref);
|
||||
|
||||
g_object_unref (stream);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
|
||||
_("No compatible formats to transfer contents."));
|
||||
}
|
||||
|
||||
gdk_content_formats_unref (content_formats);
|
||||
g_object_unref (task);
|
||||
}
|
||||
|
||||
static GInputStream *
|
||||
gdk_drop_read_local_finish (GdkDrop *self,
|
||||
const char **out_mime_type,
|
||||
GAsyncResult *result,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (g_task_is_valid (result, self), NULL);
|
||||
g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) == gdk_drop_read_local_async, NULL);
|
||||
|
||||
if (out_mime_type)
|
||||
*out_mime_type = g_task_get_task_data (G_TASK (result));
|
||||
|
||||
return g_task_propagate_pointer (G_TASK (result), error);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_drop_set_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GdkDrop *self = GDK_DROP (gobject);
|
||||
GdkDropPrivate *priv = gdk_drop_get_instance_private (self);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_ACTIONS:
|
||||
gdk_drop_set_actions (self, g_value_get_flags (value));
|
||||
break;
|
||||
|
||||
case PROP_DEVICE:
|
||||
priv->device = g_value_dup_object (value);
|
||||
g_assert (priv->device != NULL);
|
||||
if (priv->surface)
|
||||
g_assert (gdk_surface_get_display (priv->surface) == gdk_device_get_display (priv->device));
|
||||
break;
|
||||
|
||||
case PROP_DRAG:
|
||||
priv->drag = g_value_dup_object (value);
|
||||
break;
|
||||
|
||||
case PROP_FORMATS:
|
||||
priv->formats = g_value_dup_boxed (value);
|
||||
g_assert (priv->formats != NULL);
|
||||
break;
|
||||
|
||||
case PROP_SURFACE:
|
||||
priv->surface = g_value_dup_object (value);
|
||||
g_assert (priv->surface != NULL);
|
||||
if (priv->device)
|
||||
g_assert (gdk_surface_get_display (priv->surface) == gdk_device_get_display (priv->device));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_drop_get_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GdkDrop *self = GDK_DROP (gobject);
|
||||
GdkDropPrivate *priv = gdk_drop_get_instance_private (self);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_ACTIONS:
|
||||
g_value_set_flags (value, priv->actions);
|
||||
break;
|
||||
|
||||
case PROP_DEVICE:
|
||||
g_value_set_object (value, priv->device);
|
||||
break;
|
||||
|
||||
case PROP_DISPLAY:
|
||||
g_value_set_object (value, gdk_device_get_display (priv->device));
|
||||
break;
|
||||
|
||||
case PROP_DRAG:
|
||||
g_value_set_object (value, priv->drag);
|
||||
break;
|
||||
|
||||
case PROP_FORMATS:
|
||||
g_value_set_boxed (value, priv->formats);
|
||||
break;
|
||||
|
||||
case PROP_SURFACE:
|
||||
g_value_set_object (value, priv->surface);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_drop_finalize (GObject *object)
|
||||
{
|
||||
GdkDrop *self = GDK_DROP (object);
|
||||
GdkDropPrivate *priv = gdk_drop_get_instance_private (self);
|
||||
|
||||
g_clear_object (&priv->device);
|
||||
g_clear_object (&priv->drag);
|
||||
|
||||
G_OBJECT_CLASS (gdk_drop_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_drop_class_init (GdkDropClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
klass->status = gdk_drop_default_status;
|
||||
|
||||
object_class->get_property = gdk_drop_get_property;
|
||||
object_class->set_property = gdk_drop_set_property;
|
||||
object_class->finalize = gdk_drop_finalize;
|
||||
|
||||
/**
|
||||
* GdkDrop:actions:
|
||||
*
|
||||
* The possible actions for this drop
|
||||
*/
|
||||
properties[PROP_ACTIONS] =
|
||||
g_param_spec_flags ("actions",
|
||||
"Actions",
|
||||
"The possible actions for this drop",
|
||||
GDK_TYPE_DRAG_ACTION,
|
||||
GDK_ACTION_ALL,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
/**
|
||||
* GdkDrop:device:
|
||||
*
|
||||
* The #GdkDevice performing the drop
|
||||
*/
|
||||
properties[PROP_DEVICE] =
|
||||
g_param_spec_object ("device",
|
||||
"Device",
|
||||
"The device performing the drop",
|
||||
GDK_TYPE_DEVICE,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
/**
|
||||
* GdkDrop:display:
|
||||
*
|
||||
* The #GdkDisplay that the drop belongs to.
|
||||
*/
|
||||
properties[PROP_DISPLAY] =
|
||||
g_param_spec_object ("display",
|
||||
"Display",
|
||||
"Display this drag belongs to",
|
||||
GDK_TYPE_DISPLAY,
|
||||
G_PARAM_READABLE |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
/**
|
||||
* GdkDrop:drag:
|
||||
*
|
||||
* The #GdkDrag that initiated this drop
|
||||
*/
|
||||
properties[PROP_DRAG] =
|
||||
g_param_spec_object ("drag",
|
||||
"Drag",
|
||||
"The drag that initiated this drop",
|
||||
GDK_TYPE_DRAG,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
/**
|
||||
* GdkDrop:formats:
|
||||
*
|
||||
* The possible formats that the drop can provide its data in.
|
||||
*/
|
||||
properties[PROP_FORMATS] =
|
||||
g_param_spec_boxed ("formats",
|
||||
"Formats",
|
||||
"The possible formats for data",
|
||||
GDK_TYPE_CONTENT_FORMATS,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
/**
|
||||
* GdkDrop:surface:
|
||||
*
|
||||
* The #GdkSurface the drop happens on
|
||||
*/
|
||||
properties[PROP_SURFACE] =
|
||||
g_param_spec_object ("surface",
|
||||
"Surface",
|
||||
"The surface the drop is happening on",
|
||||
GDK_TYPE_SURFACE,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
g_object_class_install_properties (object_class, N_PROPERTIES, properties);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_drop_init (GdkDrop *self)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_drop_get_display:
|
||||
* @self: a #GdkDrop
|
||||
*
|
||||
* Gets the #GdkDisplay that @self was created for.
|
||||
*
|
||||
* Returns: (transfer none): a #GdkDisplay
|
||||
**/
|
||||
GdkDisplay *
|
||||
gdk_drop_get_display (GdkDrop *self)
|
||||
{
|
||||
GdkDropPrivate *priv = gdk_drop_get_instance_private (self);
|
||||
|
||||
g_return_val_if_fail (GDK_IS_DROP (self), NULL);
|
||||
|
||||
return gdk_device_get_display (priv->device);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_drop_get_device:
|
||||
* @self: a #GdkDrop
|
||||
*
|
||||
* Returns the #GdkDevice performing the drop.
|
||||
*
|
||||
* Returns: (transfer none): The #GdkDevice performing the drop.
|
||||
**/
|
||||
GdkDevice *
|
||||
gdk_drop_get_device (GdkDrop *self)
|
||||
{
|
||||
GdkDropPrivate *priv = gdk_drop_get_instance_private (self);
|
||||
|
||||
g_return_val_if_fail (GDK_IS_DROP (self), NULL);
|
||||
|
||||
return priv->device;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_drop_get_formats:
|
||||
* @self: a #GdkDrop
|
||||
*
|
||||
* Returns the #GdkContentFormats that the drop offers the data
|
||||
* to be read in.
|
||||
*
|
||||
* Returns: (transfer none): The possible #GdkContentFormats
|
||||
**/
|
||||
GdkContentFormats *
|
||||
gdk_drop_get_formats (GdkDrop *self)
|
||||
{
|
||||
GdkDropPrivate *priv = gdk_drop_get_instance_private (self);
|
||||
|
||||
g_return_val_if_fail (GDK_IS_DROP (self), NULL);
|
||||
|
||||
return priv->formats;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_drop_get_surface:
|
||||
* @self: a #GdkDrop
|
||||
*
|
||||
* Returns the #GdkSurface performing the drop.
|
||||
*
|
||||
* Returns: (transfer none): The #GdkSurface performing the drop.
|
||||
**/
|
||||
GdkSurface *
|
||||
gdk_drop_get_surface (GdkDrop *self)
|
||||
{
|
||||
GdkDropPrivate *priv = gdk_drop_get_instance_private (self);
|
||||
|
||||
g_return_val_if_fail (GDK_IS_DROP (self), NULL);
|
||||
|
||||
return priv->surface;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_drop_get_actions:
|
||||
* @self: a #GdkDrop
|
||||
*
|
||||
* Returns the possible actions for this #GdkDrop. If this value
|
||||
* contains multiple actions - ie gdk_drag_action_is_unique()
|
||||
* returns %FALSE for the result - gdk_drag_finish() must choose
|
||||
* the action to use when accepting the drop.
|
||||
*
|
||||
* This value may change over the lifetime of the #GdkDrop both
|
||||
* as a response to source side actions as well as to calls to
|
||||
* gdk_drop_status() or gdk_drag_finish(). The source side will
|
||||
* not change this value anymore once a drop has started.
|
||||
*
|
||||
* Returns: The possible #GdkDragActions
|
||||
**/
|
||||
GdkDragAction
|
||||
gdk_drop_get_actions (GdkDrop *self)
|
||||
{
|
||||
GdkDropPrivate *priv = gdk_drop_get_instance_private (self);
|
||||
|
||||
g_return_val_if_fail (GDK_IS_DROP (self), 0);
|
||||
|
||||
return priv->actions;
|
||||
}
|
||||
|
||||
void
|
||||
gdk_drop_set_actions (GdkDrop *self,
|
||||
GdkDragAction actions)
|
||||
{
|
||||
GdkDropPrivate *priv = gdk_drop_get_instance_private (self);
|
||||
|
||||
g_return_if_fail (GDK_IS_DROP (self));
|
||||
g_return_if_fail ((actions & GDK_ACTION_ASK) == 0);
|
||||
|
||||
if (priv->actions == actions)
|
||||
return;
|
||||
|
||||
priv->actions = actions;
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_ACTIONS]);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_drop_get_drag:
|
||||
* @self: a #GdkDrop
|
||||
*
|
||||
* If this is an in-app drag-and-drop operation, returns the #GdkDrag
|
||||
* that corresponds to this drop.
|
||||
*
|
||||
* If it is not, %NULL is returned.
|
||||
*
|
||||
* Returns: (transfer none) (nullable): the corresponding #GdkDrag
|
||||
**/
|
||||
GdkDrag *
|
||||
gdk_drop_get_drag (GdkDrop *self)
|
||||
{
|
||||
GdkDropPrivate *priv = gdk_drop_get_instance_private (self);
|
||||
|
||||
g_return_val_if_fail (GDK_IS_DROP (self), 0);
|
||||
|
||||
return priv->drag;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_drop_status:
|
||||
* @self: a #GdkDrop
|
||||
* @actions: Supported actions of the destination, or 0 to indicate
|
||||
* that a drop will not be accepted
|
||||
*
|
||||
* Selects all actions that are potentially supported by the destination.
|
||||
*
|
||||
* When calling this function, do not restrict the passed in actions to
|
||||
* the ones provided by gdk_drop_get_actions(). Those actions may
|
||||
* change in the future, even depending on the actions you provide here.
|
||||
*
|
||||
* This function should be called by drag destinations in response to
|
||||
* %GDK_DRAG_ENTER or %GDK_DRAG_MOTION events. If the destination does
|
||||
* not yet know the exact actions it supports, it should set any possible
|
||||
* actions first and then later call this function again.
|
||||
*/
|
||||
void
|
||||
gdk_drop_status (GdkDrop *self,
|
||||
GdkDragAction actions)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_DROP (self));
|
||||
|
||||
GDK_DROP_GET_CLASS (self)->status (self, actions);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_drop_finish:
|
||||
* @self: a #GdkDrop
|
||||
* @action: the action performed by the destination or 0 if the drop
|
||||
* failed
|
||||
*
|
||||
* Ends the drag operation after a drop.
|
||||
*
|
||||
* The @action must be a single action selected from the actions
|
||||
* available via gdk_drop_get_actions().
|
||||
**/
|
||||
void
|
||||
gdk_drop_finish (GdkDrop *self,
|
||||
GdkDragAction action)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_DROP (self));
|
||||
g_return_if_fail (gdk_drag_action_is_unique (action));
|
||||
|
||||
GDK_DROP_GET_CLASS (self)->finish (self, action);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_drop_read_internal (GdkDrop *self,
|
||||
GdkContentFormats *formats,
|
||||
int io_priority,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
GdkDropPrivate *priv = gdk_drop_get_instance_private (self);
|
||||
|
||||
if (priv->drag)
|
||||
{
|
||||
gdk_drop_read_local_async (self,
|
||||
formats,
|
||||
io_priority,
|
||||
cancellable,
|
||||
callback,
|
||||
user_data);
|
||||
}
|
||||
else
|
||||
{
|
||||
GDK_DROP_GET_CLASS (self)->read_async (self,
|
||||
formats,
|
||||
io_priority,
|
||||
cancellable,
|
||||
callback,
|
||||
user_data);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_drop_read_async:
|
||||
* @self: a #GdkDrop
|
||||
* @mime_types: (array zero-terminated=1) (element-type utf8):
|
||||
* pointer to an array of mime types
|
||||
* @io_priority: the io priority for the read operation
|
||||
* @cancellable: (allow-none): optional #GCancellable object,
|
||||
* %NULL to ignore
|
||||
* @callback: (scope async): a #GAsyncReadyCallback to call when
|
||||
* the request is satisfied
|
||||
* @user_data: (closure): the data to pass to @callback
|
||||
*
|
||||
* Asynchronously read the dropped data from a #GdkDrop
|
||||
* in a format that complies with one of the mime types.
|
||||
*/
|
||||
void
|
||||
gdk_drop_read_async (GdkDrop *self,
|
||||
const char **mime_types,
|
||||
int io_priority,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
GdkContentFormats *formats;
|
||||
|
||||
g_return_if_fail (GDK_IS_DROP (self));
|
||||
g_return_if_fail (mime_types != NULL && mime_types[0] != NULL);
|
||||
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
|
||||
g_return_if_fail (callback != NULL);
|
||||
|
||||
formats = gdk_content_formats_new (mime_types, g_strv_length ((char **) mime_types));
|
||||
|
||||
gdk_drop_read_internal (self, formats, io_priority, cancellable, callback, user_data);
|
||||
|
||||
gdk_content_formats_unref (formats);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_drop_read_finish:
|
||||
* @self: a #GdkDrop
|
||||
* @out_mime_type: (out) (type utf8): return location for the used mime type
|
||||
* @result: a #GAsyncResult
|
||||
* @error: (allow-none): location to store error information on failure, or %NULL
|
||||
*
|
||||
* Finishes an async drop read operation, see gdk_drop_read_async().
|
||||
*
|
||||
* Returns: (nullable) (transfer full): the #GInputStream, or %NULL
|
||||
*/
|
||||
GInputStream *
|
||||
gdk_drop_read_finish (GdkDrop *self,
|
||||
const char **out_mime_type,
|
||||
GAsyncResult *result,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_DROP (self), NULL);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
||||
|
||||
if (g_async_result_is_tagged (result, gdk_drop_read_local_async))
|
||||
{
|
||||
return gdk_drop_read_local_finish (self, out_mime_type, result, error);
|
||||
}
|
||||
else
|
||||
{
|
||||
return GDK_DROP_GET_CLASS (self)->read_finish (self, out_mime_type, result, error);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_drop_read_value_done (GObject *source,
|
||||
GAsyncResult *result,
|
||||
gpointer data)
|
||||
{
|
||||
GTask *task = data;
|
||||
GError *error = NULL;
|
||||
GValue *value;
|
||||
|
||||
value = g_task_get_task_data (task);
|
||||
|
||||
if (!gdk_content_deserialize_finish (result, value, &error))
|
||||
g_task_return_error (task, error);
|
||||
else
|
||||
g_task_return_pointer (task, value, NULL);
|
||||
|
||||
g_object_unref (task);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_drop_read_value_got_stream (GObject *source,
|
||||
GAsyncResult *result,
|
||||
gpointer data)
|
||||
{
|
||||
GInputStream *stream;
|
||||
GError *error = NULL;
|
||||
GTask *task = data;
|
||||
const char *mime_type;
|
||||
|
||||
stream = gdk_drop_read_finish (GDK_DROP (source), &mime_type, result, &error);
|
||||
if (stream == NULL)
|
||||
{
|
||||
g_task_return_error (task, error);
|
||||
return;
|
||||
}
|
||||
|
||||
gdk_content_deserialize_async (stream,
|
||||
mime_type,
|
||||
G_VALUE_TYPE (g_task_get_task_data (task)),
|
||||
g_task_get_priority (task),
|
||||
g_task_get_cancellable (task),
|
||||
gdk_drop_read_value_done,
|
||||
task);
|
||||
g_object_unref (stream);
|
||||
}
|
||||
|
||||
static void
|
||||
free_value (gpointer value)
|
||||
{
|
||||
g_value_unset (value);
|
||||
g_slice_free (GValue, value);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_drop_read_value_internal (GdkDrop *self,
|
||||
GType type,
|
||||
gpointer source_tag,
|
||||
int io_priority,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
GdkDropPrivate *priv = gdk_drop_get_instance_private (self);
|
||||
GdkContentFormatsBuilder *builder;
|
||||
GdkContentFormats *formats;
|
||||
GValue *value;
|
||||
GTask *task;
|
||||
|
||||
task = g_task_new (self, cancellable, callback, user_data);
|
||||
g_task_set_priority (task, io_priority);
|
||||
g_task_set_source_tag (task, source_tag);
|
||||
value = g_slice_new0 (GValue);
|
||||
g_value_init (value, type);
|
||||
g_task_set_task_data (task, value, free_value);
|
||||
|
||||
if (priv->drag)
|
||||
{
|
||||
GError *error = NULL;
|
||||
GdkContentProvider *content;
|
||||
gboolean res;
|
||||
|
||||
g_object_get (priv->drag, "content", &content, NULL);
|
||||
|
||||
res = gdk_content_provider_get_value (content, value, &error);
|
||||
|
||||
g_object_unref (content);
|
||||
|
||||
if (res)
|
||||
{
|
||||
g_task_return_pointer (task, value, NULL);
|
||||
g_object_unref (task);
|
||||
return;
|
||||
}
|
||||
else if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED))
|
||||
{
|
||||
g_task_return_error (task, error);
|
||||
g_object_unref (task);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* fall through to regular stream transfer */
|
||||
g_clear_error (&error);
|
||||
}
|
||||
}
|
||||
|
||||
builder = gdk_content_formats_builder_new ();
|
||||
gdk_content_formats_builder_add_gtype (builder, type);
|
||||
formats = gdk_content_formats_builder_free_to_formats (builder);
|
||||
formats = gdk_content_formats_union_deserialize_mime_types (formats);
|
||||
|
||||
gdk_drop_read_internal (self,
|
||||
formats,
|
||||
io_priority,
|
||||
cancellable,
|
||||
gdk_drop_read_value_got_stream,
|
||||
task);
|
||||
|
||||
gdk_content_formats_unref (formats);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_drop_read_value_async:
|
||||
* @self: a #GdkDrop
|
||||
* @type: a #GType to read
|
||||
* @io_priority: the [I/O priority][io-priority]
|
||||
* of the request.
|
||||
* @cancellable: (nullable): optional #GCancellable object, %NULL to ignore.
|
||||
* @callback: (scope async): callback to call when the request is satisfied
|
||||
* @user_data: (closure): the data to pass to callback function
|
||||
*
|
||||
* Asynchronously request the drag operation's contents converted to the given
|
||||
* @type. When the operation is finished @callback will be called.
|
||||
* You can then call gdk_drop_read_value_finish() to get the resulting
|
||||
* #GValue.
|
||||
*
|
||||
* For local drag'n'drop operations that are available in the given #GType, the
|
||||
* value will be copied directly. Otherwise, GDK will try to use
|
||||
* gdk_content_deserialize_async() to convert the data.
|
||||
**/
|
||||
void
|
||||
gdk_drop_read_value_async (GdkDrop *self,
|
||||
GType type,
|
||||
int io_priority,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_DROP (self));
|
||||
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
|
||||
g_return_if_fail (callback != NULL);
|
||||
|
||||
gdk_drop_read_value_internal (self,
|
||||
type,
|
||||
gdk_drop_read_value_async,
|
||||
io_priority,
|
||||
cancellable,
|
||||
callback,
|
||||
user_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_drop_read_value_finish:
|
||||
* @self: a #GdkDrop
|
||||
* @result: a #GAsyncResult
|
||||
* @error: a #GError location to store the error occurring, or %NULL to
|
||||
* ignore.
|
||||
*
|
||||
* Finishes an async drop read started with
|
||||
* gdk_drop_read_value_async().
|
||||
*
|
||||
* Returns: (transfer none): a #GValue containing the result.
|
||||
**/
|
||||
const GValue *
|
||||
gdk_drop_read_value_finish (GdkDrop *self,
|
||||
GAsyncResult *result,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (g_task_is_valid (result, self), NULL);
|
||||
g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) == gdk_drop_read_value_async, NULL);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
||||
|
||||
return g_task_propagate_pointer (G_TASK (result), error);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_drop_read_text_async:
|
||||
* @self: a #GdkDrop
|
||||
* @cancellable: (nullable): optional #GCancellable object, %NULL to ignore.
|
||||
* @callback: (scope async): callback to call when the request is satisfied
|
||||
* @user_data: (closure): the data to pass to callback function
|
||||
*
|
||||
* Asynchronously request the drag operation's contents converted to a string.
|
||||
* When the operation is finished @callback will be called. You can then
|
||||
* call gdk_drop_read_text_finish() to get the result.
|
||||
*
|
||||
* This is a simple wrapper around gdk_drop_read_value_async(). Use
|
||||
* that function or gdk_drop_read_async() directly if you need more
|
||||
* control over the operation.
|
||||
**/
|
||||
void
|
||||
gdk_drop_read_text_async (GdkDrop *self,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_DROP (self));
|
||||
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
|
||||
g_return_if_fail (callback != NULL);
|
||||
|
||||
gdk_drop_read_value_internal (self,
|
||||
G_TYPE_STRING,
|
||||
gdk_drop_read_text_async,
|
||||
G_PRIORITY_DEFAULT,
|
||||
cancellable,
|
||||
callback,
|
||||
user_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_drop_read_text_finish:
|
||||
* @self: a #GdkDrop
|
||||
* @result: a #GAsyncResult
|
||||
* @error: a #GError location to store the error occurring, or %NULL to
|
||||
* ignore.
|
||||
*
|
||||
* Finishes an asynchronous read started with
|
||||
* gdk_drop_read_text_async().
|
||||
*
|
||||
* Returns: (transfer full) (nullable): a new string or %NULL on error.
|
||||
**/
|
||||
char *
|
||||
gdk_drop_read_text_finish (GdkDrop *self,
|
||||
GAsyncResult *result,
|
||||
GError **error)
|
||||
{
|
||||
const GValue *value;
|
||||
|
||||
g_return_val_if_fail (g_task_is_valid (result, self), NULL);
|
||||
g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) == gdk_drop_read_text_async, NULL);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
||||
|
||||
value = g_task_propagate_pointer (G_TASK (result), error);
|
||||
if (!value)
|
||||
return NULL;
|
||||
|
||||
return g_value_dup_string (value);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_drop_do_emit_event (GdkEvent *event,
|
||||
gboolean dont_queue)
|
||||
{
|
||||
if (dont_queue)
|
||||
{
|
||||
_gdk_event_emit (event);
|
||||
g_object_unref (event);
|
||||
}
|
||||
else
|
||||
{
|
||||
_gdk_event_queue_append (gdk_event_get_display (event), event);
|
||||
}
|
||||
}
|
||||
void
|
||||
gdk_drop_emit_enter_event (GdkDrop *self,
|
||||
gboolean dont_queue,
|
||||
guint32 time)
|
||||
{
|
||||
GdkDropPrivate *priv = gdk_drop_get_instance_private (self);
|
||||
GdkEvent *event;
|
||||
|
||||
event = gdk_event_new (GDK_DRAG_ENTER);
|
||||
event->any.surface = g_object_ref (priv->surface);
|
||||
event->dnd.drop = g_object_ref (self);
|
||||
event->dnd.time = time;
|
||||
gdk_event_set_device (event, priv->device);
|
||||
|
||||
gdk_drop_do_emit_event (event, dont_queue);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_drop_emit_motion_event (GdkDrop *self,
|
||||
gboolean dont_queue,
|
||||
double x_root,
|
||||
double y_root,
|
||||
guint32 time)
|
||||
{
|
||||
GdkDropPrivate *priv = gdk_drop_get_instance_private (self);
|
||||
GdkEvent *event;
|
||||
|
||||
event = gdk_event_new (GDK_DRAG_MOTION);
|
||||
event->any.surface = g_object_ref (priv->surface);
|
||||
event->dnd.drop = g_object_ref (self);
|
||||
event->dnd.time = time;
|
||||
event->dnd.x_root = x_root;
|
||||
event->dnd.y_root = y_root;
|
||||
gdk_event_set_device (event, priv->device);
|
||||
|
||||
gdk_drop_do_emit_event (event, dont_queue);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_drop_emit_leave_event (GdkDrop *self,
|
||||
gboolean dont_queue,
|
||||
guint32 time)
|
||||
{
|
||||
GdkDropPrivate *priv = gdk_drop_get_instance_private (self);
|
||||
GdkEvent *event;
|
||||
|
||||
event = gdk_event_new (GDK_DRAG_LEAVE);
|
||||
event->any.surface = g_object_ref (priv->surface);
|
||||
event->dnd.drop = g_object_ref (self);
|
||||
event->dnd.time = time;
|
||||
gdk_event_set_device (event, priv->device);
|
||||
|
||||
gdk_drop_do_emit_event (event, dont_queue);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_drop_emit_drop_event (GdkDrop *self,
|
||||
gboolean dont_queue,
|
||||
double x_root,
|
||||
double y_root,
|
||||
guint32 time)
|
||||
{
|
||||
GdkDropPrivate *priv = gdk_drop_get_instance_private (self);
|
||||
GdkEvent *event;
|
||||
|
||||
event = gdk_event_new (GDK_DROP_START);
|
||||
event->any.surface = g_object_ref (priv->surface);
|
||||
event->dnd.drop = g_object_ref (self);
|
||||
event->dnd.time = time;
|
||||
event->dnd.x_root = x_root;
|
||||
event->dnd.y_root = y_root;
|
||||
gdk_event_set_device (event, priv->device);
|
||||
|
||||
gdk_drop_do_emit_event (event, dont_queue);
|
||||
}
|
||||
|
98
gdk/gdkdrop.h
Normal file
98
gdk/gdkdrop.h
Normal file
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright © 2018 Benjamin Otte
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Benjamin Otte <otte@gnome.org>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __GDK_DROP_H__
|
||||
#define __GDK_DROP_H__
|
||||
|
||||
#if !defined (__GDK_H_INSIDE__) && !defined (GDK_COMPILATION)
|
||||
#error "Only <gdk/gdk.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <gdk/gdktypes.h>
|
||||
#include <gdk/gdkversionmacros.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkDrop, g_object_unref)
|
||||
|
||||
#define GDK_TYPE_DROP (gdk_drop_get_type ())
|
||||
#define GDK_DROP(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_DROP, GdkDrop))
|
||||
#define GDK_IS_DROP(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_DROP))
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GType gdk_drop_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkDisplay * gdk_drop_get_display (GdkDrop *self);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkDevice * gdk_drop_get_device (GdkDrop *self);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkSurface * gdk_drop_get_surface (GdkDrop *self);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkContentFormats * gdk_drop_get_formats (GdkDrop *self);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkDragAction gdk_drop_get_actions (GdkDrop *self);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkDrag * gdk_drop_get_drag (GdkDrop *self);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_drop_status (GdkDrop *self,
|
||||
GdkDragAction actions);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_drop_finish (GdkDrop *self,
|
||||
GdkDragAction action);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_drop_read_async (GdkDrop *self,
|
||||
const char **mime_types,
|
||||
int io_priority,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GInputStream * gdk_drop_read_finish (GdkDrop *self,
|
||||
const char **out_mime_type,
|
||||
GAsyncResult *result,
|
||||
GError **error);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_drop_read_value_async (GdkDrop *self,
|
||||
GType type,
|
||||
int io_priority,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
const GValue * gdk_drop_read_value_finish (GdkDrop *self,
|
||||
GAsyncResult *result,
|
||||
GError **error);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_drop_read_text_async (GdkDrop *self,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
char * gdk_drop_read_text_finish (GdkDrop *self,
|
||||
GAsyncResult *result,
|
||||
GError **error);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_DROP_H__ */
|
81
gdk/gdkdropprivate.h
Normal file
81
gdk/gdkdropprivate.h
Normal file
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright © 2018 Benjamin Otte
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Benjamin Otte <otte@gnome.org>
|
||||
*/
|
||||
|
||||
#ifndef __GDK_DROP_PRIVATE_H__
|
||||
#define __GDK_DROP_PRIVATE_H__
|
||||
|
||||
#include "gdkdrop.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
||||
#define GDK_DROP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_DROP, GdkDropClass))
|
||||
#define GDK_IS_DROP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_DROP))
|
||||
#define GDK_DROP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_DROP, GdkDropClass))
|
||||
|
||||
typedef struct _GdkDropClass GdkDropClass;
|
||||
|
||||
|
||||
struct _GdkDrop {
|
||||
GObject parent_instance;
|
||||
};
|
||||
|
||||
struct _GdkDropClass {
|
||||
GObjectClass parent_class;
|
||||
|
||||
void (* status) (GdkDrop *self,
|
||||
GdkDragAction actions);
|
||||
void (* finish) (GdkDrop *self,
|
||||
GdkDragAction action);
|
||||
|
||||
void (* read_async) (GdkDrop *self,
|
||||
GdkContentFormats *formats,
|
||||
int io_priority,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
GInputStream * (* read_finish) (GdkDrop *self,
|
||||
const char **out_mime_type,
|
||||
GAsyncResult *result,
|
||||
GError **error);
|
||||
};
|
||||
|
||||
void gdk_drop_set_actions (GdkDrop *self,
|
||||
GdkDragAction actions);
|
||||
|
||||
void gdk_drop_emit_enter_event (GdkDrop *self,
|
||||
gboolean dont_queue,
|
||||
guint32 time);
|
||||
void gdk_drop_emit_motion_event (GdkDrop *self,
|
||||
gboolean dont_queue,
|
||||
double x_root,
|
||||
double y_root,
|
||||
guint32 time);
|
||||
void gdk_drop_emit_leave_event (GdkDrop *self,
|
||||
gboolean dont_queue,
|
||||
guint32 time);
|
||||
void gdk_drop_emit_drop_event (GdkDrop *self,
|
||||
gboolean dont_queue,
|
||||
double x_root,
|
||||
double y_root,
|
||||
guint32 time);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif
|
@@ -28,7 +28,8 @@
|
||||
#include "gdkeventsprivate.h"
|
||||
#include "gdkinternals.h"
|
||||
#include "gdkdisplayprivate.h"
|
||||
#include "gdkdndprivate.h"
|
||||
#include "gdkdragprivate.h"
|
||||
#include "gdkdropprivate.h"
|
||||
#include "gdk-private.h"
|
||||
|
||||
#include <string.h>
|
||||
@@ -164,14 +165,14 @@ gdk_event_class_init (GdkEventClass *klass)
|
||||
void
|
||||
_gdk_event_emit (GdkEvent *event)
|
||||
{
|
||||
if (gdk_drag_context_handle_source_event (event))
|
||||
if (gdk_drag_handle_source_event (event))
|
||||
return;
|
||||
|
||||
if (gdk_surface_handle_event (event))
|
||||
return;
|
||||
|
||||
if (_gdk_event_func)
|
||||
(*_gdk_event_func) (event, _gdk_event_data);
|
||||
|
||||
if (gdk_drag_context_handle_dest_event (event))
|
||||
return;
|
||||
}
|
||||
|
||||
/*********************************************
|
||||
@@ -630,11 +631,6 @@ gdk_event_copy (const GdkEvent *event)
|
||||
|
||||
switch ((guint) event->any.type)
|
||||
{
|
||||
case GDK_KEY_PRESS:
|
||||
case GDK_KEY_RELEASE:
|
||||
new_event->key.string = g_strdup (event->key.string);
|
||||
break;
|
||||
|
||||
case GDK_ENTER_NOTIFY:
|
||||
case GDK_LEAVE_NOTIFY:
|
||||
if (event->crossing.child_surface != NULL)
|
||||
@@ -645,12 +641,7 @@ gdk_event_copy (const GdkEvent *event)
|
||||
case GDK_DRAG_LEAVE:
|
||||
case GDK_DRAG_MOTION:
|
||||
case GDK_DROP_START:
|
||||
g_object_ref (event->dnd.context);
|
||||
break;
|
||||
|
||||
case GDK_EXPOSE:
|
||||
if (event->expose.region)
|
||||
new_event->expose.region = cairo_region_copy (event->expose.region);
|
||||
g_object_ref (event->dnd.drop);
|
||||
break;
|
||||
|
||||
case GDK_BUTTON_PRESS:
|
||||
@@ -702,11 +693,6 @@ gdk_event_finalize (GObject *object)
|
||||
|
||||
switch ((guint) event->any.type)
|
||||
{
|
||||
case GDK_KEY_PRESS:
|
||||
case GDK_KEY_RELEASE:
|
||||
g_free (event->key.string);
|
||||
break;
|
||||
|
||||
case GDK_ENTER_NOTIFY:
|
||||
case GDK_LEAVE_NOTIFY:
|
||||
g_clear_object (&event->crossing.child_surface);
|
||||
@@ -716,8 +702,7 @@ gdk_event_finalize (GObject *object)
|
||||
case GDK_DRAG_LEAVE:
|
||||
case GDK_DRAG_MOTION:
|
||||
case GDK_DROP_START:
|
||||
if (event->dnd.context != NULL)
|
||||
g_object_unref (event->dnd.context);
|
||||
g_clear_object (&event->dnd.drop);
|
||||
break;
|
||||
|
||||
case GDK_BUTTON_PRESS:
|
||||
@@ -733,11 +718,6 @@ gdk_event_finalize (GObject *object)
|
||||
g_free (event->touch.axes);
|
||||
break;
|
||||
|
||||
case GDK_EXPOSE:
|
||||
if (event->expose.region)
|
||||
cairo_region_destroy (event->expose.region);
|
||||
break;
|
||||
|
||||
case GDK_MOTION_NOTIFY:
|
||||
g_clear_object (&event->motion.tool);
|
||||
g_free (event->motion.axes);
|
||||
@@ -835,9 +815,6 @@ gdk_event_get_time (const GdkEvent *event)
|
||||
case GDK_NOTHING:
|
||||
case GDK_DELETE:
|
||||
case GDK_DESTROY:
|
||||
case GDK_EXPOSE:
|
||||
case GDK_MAP:
|
||||
case GDK_UNMAP:
|
||||
case GDK_GRAB_BROKEN:
|
||||
case GDK_EVENT_LAST:
|
||||
default:
|
||||
@@ -911,9 +888,6 @@ gdk_event_get_state (const GdkEvent *event,
|
||||
case GDK_NOTHING:
|
||||
case GDK_DELETE:
|
||||
case GDK_DESTROY:
|
||||
case GDK_EXPOSE:
|
||||
case GDK_MAP:
|
||||
case GDK_UNMAP:
|
||||
case GDK_GRAB_BROKEN:
|
||||
case GDK_PAD_BUTTON_PRESS:
|
||||
case GDK_PAD_BUTTON_RELEASE:
|
||||
@@ -1309,37 +1283,6 @@ gdk_event_get_key_group (const GdkEvent *event,
|
||||
return fetched;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_event_get_string:
|
||||
* @event: a #GdkEvent
|
||||
* @string: (out) (transfer none): return location for the string
|
||||
*
|
||||
* Extracts a string from an event. The string is an
|
||||
* approximation of the keyval in a key event.
|
||||
*
|
||||
* Returns: %TRUE on success, otherwise %FALSE
|
||||
**/
|
||||
gboolean
|
||||
gdk_event_get_string (const GdkEvent *event,
|
||||
const char **string)
|
||||
{
|
||||
gboolean fetched = TRUE;
|
||||
|
||||
switch ((guint) event->any.type)
|
||||
{
|
||||
case GDK_KEY_PRESS:
|
||||
case GDK_KEY_RELEASE:
|
||||
*string = event->key.string;
|
||||
break;
|
||||
default:
|
||||
*string = NULL;
|
||||
fetched = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
return fetched;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_event_get_key_is_modifier:
|
||||
* @event: a #GdkEvent
|
||||
@@ -2061,17 +2004,15 @@ gdk_event_is_sent (const GdkEvent *event)
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_event_get_drag_context:
|
||||
* gdk_event_get_drop:
|
||||
* @event: a #GdkEvent
|
||||
* @context: (out) (transfer none): return location for the drag context
|
||||
*
|
||||
* Gets the drag context from a DND event.
|
||||
* Gets the #GdkDrop from a DND event.
|
||||
*
|
||||
* Returns: %TRUE on success, otherwise %FALSE
|
||||
* Returns: (transfer none) (nullable): the drop
|
||||
**/
|
||||
gboolean
|
||||
gdk_event_get_drag_context (const GdkEvent *event,
|
||||
GdkDragContext **context)
|
||||
GdkDrop *
|
||||
gdk_event_get_drop (const GdkEvent *event)
|
||||
{
|
||||
if (!event)
|
||||
return FALSE;
|
||||
@@ -2081,11 +2022,10 @@ gdk_event_get_drag_context (const GdkEvent *event,
|
||||
event->any.type == GDK_DRAG_MOTION ||
|
||||
event->any.type == GDK_DROP_START)
|
||||
{
|
||||
*context = event->dnd.context;
|
||||
return TRUE;
|
||||
return event->dnd.drop;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2510,8 +2450,6 @@ gdk_event_get_axes (GdkEvent *event,
|
||||
*
|
||||
* Returns: (transfer container) (element-type GdkTimeCoord) (nullable): a list
|
||||
* of time and coordinates
|
||||
*
|
||||
* Since: 3.94
|
||||
*/
|
||||
GList *
|
||||
gdk_event_get_motion_history (const GdkEvent *event)
|
||||
|
@@ -31,7 +31,7 @@
|
||||
|
||||
#include <gdk/gdkversionmacros.h>
|
||||
#include <gdk/gdktypes.h>
|
||||
#include <gdk/gdkdnd.h>
|
||||
#include <gdk/gdkdrag.h>
|
||||
#include <gdk/gdkdevice.h>
|
||||
#include <gdk/gdkdevicetool.h>
|
||||
|
||||
@@ -54,7 +54,7 @@ G_BEGIN_DECLS
|
||||
#define GDK_PRIORITY_EVENTS (G_PRIORITY_DEFAULT)
|
||||
|
||||
/**
|
||||
* GDK_PRIORITY_REDRAW:
|
||||
* GDK_PRIORITY_REDRAW: (value 120)
|
||||
*
|
||||
* This is the priority that the idle handler processing surface updates
|
||||
* is given in the
|
||||
@@ -67,8 +67,6 @@ G_BEGIN_DECLS
|
||||
*
|
||||
* Use this macro as the return value for continuing the propagation of
|
||||
* an event handler.
|
||||
*
|
||||
* Since: 3.4
|
||||
*/
|
||||
#define GDK_EVENT_PROPAGATE (FALSE)
|
||||
|
||||
@@ -77,8 +75,6 @@ G_BEGIN_DECLS
|
||||
*
|
||||
* Use this macro as the return value for stopping the propagation of
|
||||
* an event handler.
|
||||
*
|
||||
* Since: 3.4
|
||||
*/
|
||||
#define GDK_EVENT_STOP (TRUE)
|
||||
|
||||
@@ -87,8 +83,6 @@ G_BEGIN_DECLS
|
||||
*
|
||||
* The primary button. This is typically the left mouse button, or the
|
||||
* right button in a left-handed setup.
|
||||
*
|
||||
* Since: 3.4
|
||||
*/
|
||||
#define GDK_BUTTON_PRIMARY (1)
|
||||
|
||||
@@ -96,8 +90,6 @@ G_BEGIN_DECLS
|
||||
* GDK_BUTTON_MIDDLE:
|
||||
*
|
||||
* The middle button.
|
||||
*
|
||||
* Since: 3.4
|
||||
*/
|
||||
#define GDK_BUTTON_MIDDLE (2)
|
||||
|
||||
@@ -106,15 +98,12 @@ G_BEGIN_DECLS
|
||||
*
|
||||
* The secondary button. This is typically the right mouse button, or the
|
||||
* left button in a left-handed setup.
|
||||
*
|
||||
* Since: 3.4
|
||||
*/
|
||||
#define GDK_BUTTON_SECONDARY (3)
|
||||
|
||||
|
||||
|
||||
typedef struct _GdkEventAny GdkEventAny;
|
||||
typedef struct _GdkEventExpose GdkEventExpose;
|
||||
typedef struct _GdkEventMotion GdkEventMotion;
|
||||
typedef struct _GdkEventButton GdkEventButton;
|
||||
typedef struct _GdkEventTouch GdkEventTouch;
|
||||
@@ -155,8 +144,6 @@ typedef void (*GdkEventFunc) (GdkEvent *event,
|
||||
* hidden or destroyed, usually when the user clicks on a special icon in the
|
||||
* title bar.
|
||||
* @GDK_DESTROY: the surface has been destroyed.
|
||||
* @GDK_EXPOSE: all or part of the surface has become visible and needs to be
|
||||
* redrawn.
|
||||
* @GDK_MOTION_NOTIFY: the pointer (usually a mouse) has moved.
|
||||
* @GDK_BUTTON_PRESS: a mouse button has been pressed.
|
||||
* @GDK_BUTTON_RELEASE: a mouse button has been released.
|
||||
@@ -167,8 +154,6 @@ typedef void (*GdkEventFunc) (GdkEvent *event,
|
||||
* @GDK_FOCUS_CHANGE: the keyboard focus has entered or left the surface.
|
||||
* @GDK_CONFIGURE: the size, position or stacking order of the surface has changed.
|
||||
* Note that GTK+ discards these events for %GDK_SURFACE_CHILD surfaces.
|
||||
* @GDK_MAP: the surface has been mapped.
|
||||
* @GDK_UNMAP: the surface has been unmapped.
|
||||
* @GDK_PROXIMITY_IN: an input device has moved into contact with a sensing
|
||||
* surface (e.g. a touchscreen or graphics tablet).
|
||||
* @GDK_PROXIMITY_OUT: an input device has moved out of contact with a sensing
|
||||
@@ -216,7 +201,6 @@ typedef enum
|
||||
GDK_NOTHING,
|
||||
GDK_DELETE,
|
||||
GDK_DESTROY,
|
||||
GDK_EXPOSE,
|
||||
GDK_MOTION_NOTIFY,
|
||||
GDK_BUTTON_PRESS,
|
||||
GDK_BUTTON_RELEASE,
|
||||
@@ -226,8 +210,6 @@ typedef enum
|
||||
GDK_LEAVE_NOTIFY,
|
||||
GDK_FOCUS_CHANGE,
|
||||
GDK_CONFIGURE,
|
||||
GDK_MAP,
|
||||
GDK_UNMAP,
|
||||
GDK_PROXIMITY_IN,
|
||||
GDK_PROXIMITY_OUT,
|
||||
GDK_DRAG_ENTER,
|
||||
@@ -291,7 +273,7 @@ typedef enum
|
||||
* @GDK_SCROLL_LEFT: the surface is scrolled to the left.
|
||||
* @GDK_SCROLL_RIGHT: the surface is scrolled to the right.
|
||||
* @GDK_SCROLL_SMOOTH: the scrolling is determined by the delta values
|
||||
* in scroll events. See gdk_event_get_scroll_deltas(). Since: 3.4
|
||||
* in scroll events. See gdk_event_get_scroll_deltas()
|
||||
*
|
||||
* Specifies the direction for scroll events.
|
||||
*/
|
||||
@@ -421,9 +403,6 @@ gboolean gdk_event_get_key_is_modifier (const GdkEvent *event,
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gdk_event_get_key_group (const GdkEvent *event,
|
||||
guint *group);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gdk_event_get_string (const GdkEvent *event,
|
||||
const char **string);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gdk_event_get_scroll_direction (const GdkEvent *event,
|
||||
@@ -513,8 +492,7 @@ GDK_AVAILABLE_IN_ALL
|
||||
gboolean gdk_event_is_sent (const GdkEvent *event);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gdk_event_get_drag_context (const GdkEvent *event,
|
||||
GdkDragContext **context);
|
||||
GdkDrop * gdk_event_get_drop (const GdkEvent *event);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gdk_event_get_crossing_mode (const GdkEvent *event,
|
||||
|
@@ -26,7 +26,7 @@
|
||||
#define __GDK_EVENTS_PRIVATE_H__
|
||||
|
||||
#include <gdk/gdktypes.h>
|
||||
#include <gdk/gdkdnd.h>
|
||||
#include <gdk/gdkdrag.h>
|
||||
#include <gdk/gdkdevice.h>
|
||||
#include <gdk/gdkdevicetool.h>
|
||||
|
||||
@@ -63,23 +63,6 @@ struct _GdkEventAny
|
||||
GdkDisplay *display;
|
||||
};
|
||||
|
||||
/*
|
||||
* GdkEventExpose:
|
||||
* @type: the type of the event (%GDK_EXPOSE)
|
||||
* @surface: the surface which received the event.
|
||||
* @send_event: %TRUE if the event was sent explicitly.
|
||||
* @area: bounding box of @region.
|
||||
* @region: the region that needs to be redrawn.
|
||||
*
|
||||
* Generated when all or part of a surface becomes visible and needs to be
|
||||
* redrawn.
|
||||
*/
|
||||
struct _GdkEventExpose
|
||||
{
|
||||
GdkEventAny any;
|
||||
cairo_region_t *region;
|
||||
};
|
||||
|
||||
/*
|
||||
* GdkEventMotion:
|
||||
* @type: the type of the event.
|
||||
@@ -261,22 +244,10 @@ struct _GdkEventScroll
|
||||
* @keyval: the key that was pressed or released. See the
|
||||
* `gdk/gdkkeysyms.h` header file for a
|
||||
* complete list of GDK key codes.
|
||||
* @length: the length of @string.
|
||||
* @string: a string containing an approximation of the text that
|
||||
* would result from this keypress. The only correct way to handle text
|
||||
* input of text is using input methods (see #GtkIMContext), so this
|
||||
* field is deprecated and should never be used.
|
||||
* (gdk_unicode_to_keyval() provides a non-deprecated way of getting
|
||||
* an approximate translation for a key.) The string is encoded in the
|
||||
* encoding of the current locale (Note: this for backwards compatibility:
|
||||
* strings in GTK+ and GDK are typically in UTF-8.) and NUL-terminated.
|
||||
* In some cases, the translation of the key code will be a single
|
||||
* NUL byte, in which case looking at @length is necessary to distinguish
|
||||
* it from the an empty translation.
|
||||
* @hardware_keycode: the raw code of the key that was pressed or released.
|
||||
* @group: the keyboard group.
|
||||
* @is_modifier: a flag that indicates if @hardware_keycode is mapped to a
|
||||
* modifier. Since 2.10
|
||||
* modifier
|
||||
*
|
||||
* Describes a key press or key release event.
|
||||
*/
|
||||
@@ -286,8 +257,6 @@ struct _GdkEventKey
|
||||
guint32 time;
|
||||
guint state;
|
||||
guint keyval;
|
||||
gint length;
|
||||
gchar *string;
|
||||
guint16 hardware_keycode;
|
||||
guint16 key_scancode;
|
||||
guint8 group;
|
||||
@@ -414,8 +383,6 @@ struct _GdkEventProximity
|
||||
* is unmapped), or if the same application grabs the pointer or keyboard
|
||||
* again. Note that implicit grabs (which are initiated by button presses)
|
||||
* can also cause #GdkEventGrabBroken events.
|
||||
*
|
||||
* Since: 2.8
|
||||
*/
|
||||
struct _GdkEventGrabBroken {
|
||||
GdkEventAny any;
|
||||
@@ -430,7 +397,7 @@ struct _GdkEventGrabBroken {
|
||||
* %GDK_DRAG_MOTION or %GDK_DROP_START)
|
||||
* @surface: the surface which received the event.
|
||||
* @send_event: %TRUE if the event was sent explicitly.
|
||||
* @context: the #GdkDragContext for the current DND operation.
|
||||
* @drop: the #GdkDrop for the current DND operation.
|
||||
* @time: the time of the event in milliseconds.
|
||||
* @x_root: the x coordinate of the pointer relative to the root of the
|
||||
* screen, only set for %GDK_DRAG_MOTION and %GDK_DROP_START.
|
||||
@@ -441,7 +408,7 @@ struct _GdkEventGrabBroken {
|
||||
*/
|
||||
struct _GdkEventDND {
|
||||
GdkEventAny any;
|
||||
GdkDragContext *context;
|
||||
GdkDrop *drop;
|
||||
|
||||
guint32 time;
|
||||
gshort x_root, y_root;
|
||||
@@ -536,8 +503,6 @@ struct _GdkEventTouchpadPinch {
|
||||
* device may have different current modes.
|
||||
*
|
||||
* Generated during %GDK_SOURCE_TABLET_PAD button presses and releases.
|
||||
*
|
||||
* Since: 3.22
|
||||
*/
|
||||
struct _GdkEventPadButton {
|
||||
GdkEventAny any;
|
||||
@@ -562,8 +527,6 @@ struct _GdkEventPadButton {
|
||||
* @value: The current value for the given axis.
|
||||
*
|
||||
* Generated during %GDK_SOURCE_TABLET_PAD interaction with tactile sensors.
|
||||
*
|
||||
* Since: 3.22
|
||||
*/
|
||||
struct _GdkEventPadAxis {
|
||||
GdkEventAny any;
|
||||
@@ -587,8 +550,6 @@ struct _GdkEventPadAxis {
|
||||
* device may have different current modes.
|
||||
*
|
||||
* Generated during %GDK_SOURCE_TABLET_PAD mode switches in a group.
|
||||
*
|
||||
* Since: 3.22
|
||||
*/
|
||||
struct _GdkEventPadGroupMode {
|
||||
GdkEventAny any;
|
||||
@@ -601,7 +562,6 @@ struct _GdkEventPadGroupMode {
|
||||
* GdkEvent:
|
||||
* @type: the #GdkEventType
|
||||
* @any: a #GdkEventAny
|
||||
* @expose: a #GdkEventExpose
|
||||
* @motion: a #GdkEventMotion
|
||||
* @button: a #GdkEventButton
|
||||
* @touch: a #GdkEventTouch
|
||||
@@ -653,7 +613,6 @@ struct _GdkEventPadGroupMode {
|
||||
union _GdkEvent
|
||||
{
|
||||
GdkEventAny any;
|
||||
GdkEventExpose expose;
|
||||
GdkEventMotion motion;
|
||||
GdkEventButton button;
|
||||
GdkEventTouch touch;
|
||||
|
@@ -58,8 +58,6 @@ typedef struct _GdkFrameClockClass GdkFrameClockClass;
|
||||
* #GdkFrameClockPhase is used to represent the different paint clock
|
||||
* phases that can be requested. The elements of the enumeration
|
||||
* correspond to the signals of #GdkFrameClock.
|
||||
*
|
||||
* Since: 3.8
|
||||
**/
|
||||
typedef enum {
|
||||
GDK_FRAME_CLOCK_PHASE_NONE = 0,
|
||||
|
@@ -32,7 +32,7 @@
|
||||
#include "gdkdisplay.h"
|
||||
#include "gdkeventsprivate.h"
|
||||
#include "gdkenumtypes.h"
|
||||
#include "gdkdndprivate.h"
|
||||
#include "gdkdragprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@@ -150,7 +150,6 @@ struct _GdkSurface
|
||||
gint x;
|
||||
gint y;
|
||||
|
||||
GdkEventMask event_mask;
|
||||
guint8 surface_type;
|
||||
|
||||
guint8 resize_count;
|
||||
@@ -206,7 +205,6 @@ struct _GdkSurface
|
||||
cairo_region_t *input_shape;
|
||||
|
||||
GList *devices_inside;
|
||||
GHashTable *device_events;
|
||||
|
||||
GdkFrameClock *frame_clock; /* NULL to use from parent or default */
|
||||
|
||||
@@ -293,6 +291,8 @@ GdkGLContext * gdk_surface_get_paint_gl_context (GdkSurface *surface,
|
||||
void gdk_surface_get_unscaled_size (GdkSurface *surface,
|
||||
int *unscaled_width,
|
||||
int *unscaled_height);
|
||||
gboolean gdk_surface_handle_event (GdkEvent *event);
|
||||
|
||||
|
||||
/*****************************************
|
||||
* Interfaces provided by windowing code *
|
||||
|
@@ -50,8 +50,6 @@ typedef struct _GdkMonitorClass GdkMonitorClass;
|
||||
*
|
||||
* This enumeration describes how the red, green and blue components
|
||||
* of physical pixels on an output device are laid out.
|
||||
*
|
||||
* Since: 3.22
|
||||
*/
|
||||
typedef enum {
|
||||
GDK_SUBPIXEL_LAYOUT_UNKNOWN,
|
||||
|
@@ -643,8 +643,8 @@ gdk_paintable_new_empty (int intrinsic_width,
|
||||
{
|
||||
GdkEmptyPaintable *result;
|
||||
|
||||
g_return_val_if_fail (intrinsic_width < 0, NULL);
|
||||
g_return_val_if_fail (intrinsic_height < 0, NULL);
|
||||
g_return_val_if_fail (intrinsic_width >= 0, NULL);
|
||||
g_return_val_if_fail (intrinsic_height >= 0, NULL);
|
||||
|
||||
result = g_object_new (GDK_TYPE_EMPTY_PAINTABLE, NULL);
|
||||
|
||||
|
@@ -175,7 +175,7 @@ parse_rgb_value (const gchar *str,
|
||||
* - A RGBA color in the form “rgba(r,g,b,a)”
|
||||
*
|
||||
* Where “r”, “g”, “b” and “a” are respectively the red, green, blue and
|
||||
* alpha color values. In the last two cases, r g and b are either integers
|
||||
* alpha color values. In the last two cases, “r”, “g”, and “b” are either integers
|
||||
* in the range 0 to 255 or percentage values in the range 0% to 100%, and
|
||||
* a is a floating point value in the range 0 to 1.
|
||||
*
|
||||
@@ -353,18 +353,18 @@ gdk_rgba_equal (gconstpointer p1,
|
||||
* @rgba: a #GdkRGBA
|
||||
*
|
||||
* Returns a textual specification of @rgba in the form
|
||||
* `rgb (r, g, b)` or
|
||||
* `rgba (r, g, b, a)`,
|
||||
* `rgb(r,g,b)` or
|
||||
* `rgba(r g,b,a)`,
|
||||
* where “r”, “g”, “b” and “a” represent the red, green,
|
||||
* blue and alpha values respectively. r, g, and b are
|
||||
* represented as integers in the range 0 to 255, and a
|
||||
* is represented as floating point value in the range 0 to 1.
|
||||
* blue and alpha values respectively. “r”, “g”, and “b” are
|
||||
* represented as integers in the range 0 to 255, and “a”
|
||||
* is represented as a floating point value in the range 0 to 1.
|
||||
*
|
||||
* These string forms are string forms those supported by
|
||||
* These string forms are string forms that are supported by
|
||||
* the CSS3 colors module, and can be parsed by gdk_rgba_parse().
|
||||
*
|
||||
* Note that this string representation may lose some
|
||||
* precision, since r, g and b are represented as 8-bit
|
||||
* precision, since “r”, “g” and “b” are represented as 8-bit
|
||||
* integers. If this is a concern, you should use a
|
||||
* different representation.
|
||||
*
|
||||
|
@@ -434,14 +434,15 @@ gdk_seat_tool_removed (GdkSeat *seat,
|
||||
|
||||
GdkDeviceTool *
|
||||
gdk_seat_get_tool (GdkSeat *seat,
|
||||
guint64 serial)
|
||||
guint64 serial,
|
||||
guint64 hw_id)
|
||||
{
|
||||
GdkSeatClass *seat_class;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_SEAT (seat), NULL);
|
||||
|
||||
seat_class = GDK_SEAT_GET_CLASS (seat);
|
||||
return seat_class->get_tool (seat, serial);
|
||||
return seat_class->get_tool (seat, serial, hw_id);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -47,8 +47,6 @@ G_BEGIN_DECLS
|
||||
* @GDK_SEAT_CAPABILITY_ALL: The union of all capabilities
|
||||
*
|
||||
* Flags describing the seat capabilities.
|
||||
*
|
||||
* Since: 3.20
|
||||
*/
|
||||
typedef enum {
|
||||
GDK_SEAT_CAPABILITY_NONE = 0,
|
||||
@@ -71,8 +69,6 @@ typedef enum {
|
||||
* grabbed. A typical action would be ensuring the surface is
|
||||
* visible, although there's room for other initialization
|
||||
* actions.
|
||||
*
|
||||
* Since: 3.20
|
||||
*/
|
||||
typedef void (* GdkSeatGrabPrepareFunc) (GdkSeat *seat,
|
||||
GdkSurface *surface,
|
||||
|
@@ -282,7 +282,8 @@ gdk_seat_default_get_slaves (GdkSeat *seat,
|
||||
|
||||
static GdkDeviceTool *
|
||||
gdk_seat_default_get_tool (GdkSeat *seat,
|
||||
guint64 serial)
|
||||
guint64 serial,
|
||||
guint64 hw_id)
|
||||
{
|
||||
GdkSeatDefaultPrivate *priv;
|
||||
GdkDeviceTool *tool;
|
||||
@@ -297,7 +298,7 @@ gdk_seat_default_get_tool (GdkSeat *seat,
|
||||
{
|
||||
tool = g_ptr_array_index (priv->tools, i);
|
||||
|
||||
if (tool->serial == serial)
|
||||
if (tool->serial == serial && tool->hw_id == hw_id)
|
||||
return tool;
|
||||
}
|
||||
|
||||
@@ -457,8 +458,7 @@ gdk_seat_default_remove_tool (GdkSeatDefault *seat,
|
||||
|
||||
priv = gdk_seat_default_get_instance_private (seat);
|
||||
|
||||
if (tool != gdk_seat_get_tool (GDK_SEAT (seat),
|
||||
gdk_device_tool_get_serial (tool)))
|
||||
if (tool != gdk_seat_get_tool (GDK_SEAT (seat), tool->serial, tool->hw_id))
|
||||
return;
|
||||
|
||||
g_signal_emit_by_name (seat, "tool-removed", tool);
|
||||
|
@@ -57,7 +57,8 @@ struct _GdkSeatClass
|
||||
GdkSeatCapabilities capabilities);
|
||||
|
||||
GdkDeviceTool * (* get_tool) (GdkSeat *seat,
|
||||
guint64 serial);
|
||||
guint64 serial,
|
||||
guint64 tool_id);
|
||||
GList * (* get_master_pointers) (GdkSeat *seat,
|
||||
GdkSeatCapabilities capabilities);
|
||||
};
|
||||
@@ -74,6 +75,7 @@ void gdk_seat_tool_removed (GdkSeat *seat,
|
||||
|
||||
GdkDeviceTool *
|
||||
gdk_seat_get_tool (GdkSeat *seat,
|
||||
guint64 serial);
|
||||
guint64 serial,
|
||||
guint64 hw_id);
|
||||
|
||||
#endif /* __GDK_SEAT_PRIVATE_H__ */
|
||||
|
545
gdk/gdksurface.c
545
gdk/gdksurface.c
@@ -97,6 +97,8 @@
|
||||
|
||||
enum {
|
||||
MOVED_TO_RECT,
|
||||
SIZE_CHANGED,
|
||||
RENDER,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
@@ -105,6 +107,7 @@ enum {
|
||||
PROP_CURSOR,
|
||||
PROP_DISPLAY,
|
||||
PROP_STATE,
|
||||
PROP_MAPPED,
|
||||
LAST_PROP
|
||||
};
|
||||
|
||||
@@ -271,6 +274,13 @@ gdk_surface_class_init (GdkSurfaceClass *klass)
|
||||
GDK_TYPE_SURFACE_STATE, GDK_SURFACE_STATE_WITHDRAWN,
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
properties[PROP_MAPPED] =
|
||||
g_param_spec_boolean ("mapped",
|
||||
P_("Mapped"),
|
||||
P_("Mapped"),
|
||||
FALSE,
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
g_object_class_install_properties (object_class, LAST_PROP, properties);
|
||||
|
||||
/**
|
||||
@@ -310,6 +320,31 @@ gdk_surface_class_init (GdkSurfaceClass *klass)
|
||||
G_TYPE_POINTER,
|
||||
G_TYPE_BOOLEAN,
|
||||
G_TYPE_BOOLEAN);
|
||||
|
||||
signals[SIZE_CHANGED] =
|
||||
g_signal_new (g_intern_static_string ("size-changed"),
|
||||
G_OBJECT_CLASS_TYPE (object_class),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
G_TYPE_NONE,
|
||||
2,
|
||||
G_TYPE_INT,
|
||||
G_TYPE_INT);
|
||||
|
||||
signals[RENDER] =
|
||||
g_signal_new (g_intern_static_string ("render"),
|
||||
G_OBJECT_CLASS_TYPE (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0,
|
||||
g_signal_accumulator_true_handled,
|
||||
NULL,
|
||||
NULL,
|
||||
G_TYPE_BOOLEAN,
|
||||
1,
|
||||
CAIRO_GOBJECT_TYPE_REGION);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -321,9 +356,6 @@ seat_removed_cb (GdkDisplay *display,
|
||||
|
||||
surface->devices_inside = g_list_remove (surface->devices_inside, device);
|
||||
g_hash_table_remove (surface->device_cursor, device);
|
||||
|
||||
if (surface->device_events)
|
||||
g_hash_table_remove (surface->device_events, device);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -336,16 +368,8 @@ gdk_surface_finalize (GObject *object)
|
||||
|
||||
if (!GDK_SURFACE_DESTROYED (surface))
|
||||
{
|
||||
if (GDK_SURFACE_TYPE (surface) != GDK_SURFACE_FOREIGN)
|
||||
{
|
||||
g_warning ("losing last reference to undestroyed surface");
|
||||
_gdk_surface_destroy (surface, FALSE);
|
||||
}
|
||||
else
|
||||
/* We use TRUE here, to keep us from actually calling
|
||||
* XDestroyWindow() on the window
|
||||
*/
|
||||
_gdk_surface_destroy (surface, TRUE);
|
||||
g_warning ("losing last reference to undestroyed surface");
|
||||
_gdk_surface_destroy (surface, FALSE);
|
||||
}
|
||||
|
||||
if (surface->impl)
|
||||
@@ -369,9 +393,6 @@ gdk_surface_finalize (GObject *object)
|
||||
if (surface->device_cursor)
|
||||
g_hash_table_destroy (surface->device_cursor);
|
||||
|
||||
if (surface->device_events)
|
||||
g_hash_table_destroy (surface->device_events);
|
||||
|
||||
if (surface->devices_inside)
|
||||
g_list_free (surface->devices_inside);
|
||||
|
||||
@@ -430,18 +451,16 @@ gdk_surface_get_property (GObject *object,
|
||||
g_value_set_flags (value, surface->state);
|
||||
break;
|
||||
|
||||
case PROP_MAPPED:
|
||||
g_value_set_boolean (value, GDK_SURFACE_IS_MAPPED (surface));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_surface_is_subsurface (GdkSurface *surface)
|
||||
{
|
||||
return surface->surface_type == GDK_SURFACE_SUBSURFACE;
|
||||
}
|
||||
|
||||
static GdkSurface *
|
||||
gdk_surface_get_impl_surface (GdkSurface *surface)
|
||||
{
|
||||
@@ -530,10 +549,7 @@ recompute_visible_regions_internal (GdkSurface *private,
|
||||
old_abs_y = private->abs_y;
|
||||
|
||||
/* Update absolute position */
|
||||
if ((gdk_surface_has_impl (private) &&
|
||||
private->surface_type != GDK_SURFACE_SUBSURFACE) ||
|
||||
(gdk_surface_is_toplevel (private) &&
|
||||
private->surface_type == GDK_SURFACE_SUBSURFACE))
|
||||
if (gdk_surface_has_impl (private))
|
||||
{
|
||||
/* Native surfaces and toplevel subsurfaces start here */
|
||||
private->abs_x = 0;
|
||||
@@ -601,45 +617,6 @@ _gdk_surface_update_size (GdkSurface *surface)
|
||||
recompute_visible_regions (surface, FALSE);
|
||||
}
|
||||
|
||||
static GdkEventMask
|
||||
get_native_device_event_mask (GdkSurface *private,
|
||||
GdkDevice *device)
|
||||
{
|
||||
GdkEventMask event_mask;
|
||||
|
||||
if (device)
|
||||
event_mask = GPOINTER_TO_INT (g_hash_table_lookup (private->device_events, device));
|
||||
else
|
||||
event_mask = private->event_mask;
|
||||
|
||||
if (private->surface_type == GDK_SURFACE_FOREIGN)
|
||||
return event_mask;
|
||||
else
|
||||
{
|
||||
GdkEventMask mask;
|
||||
|
||||
mask = private->event_mask;
|
||||
|
||||
/* We need thse for all native surfaces so we can
|
||||
emulate events on children: */
|
||||
mask |=
|
||||
GDK_EXPOSURE_MASK |
|
||||
GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK |
|
||||
GDK_TOUCH_MASK |
|
||||
GDK_POINTER_MOTION_MASK |
|
||||
GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
|
||||
GDK_SCROLL_MASK;
|
||||
|
||||
return mask;
|
||||
}
|
||||
}
|
||||
|
||||
static GdkEventMask
|
||||
get_native_event_mask (GdkSurface *private)
|
||||
{
|
||||
return get_native_device_event_mask (private, NULL);
|
||||
}
|
||||
|
||||
GdkSurface*
|
||||
gdk_surface_new (GdkDisplay *display,
|
||||
GdkSurface *parent,
|
||||
@@ -647,7 +624,6 @@ gdk_surface_new (GdkDisplay *display,
|
||||
{
|
||||
GdkSurface *surface;
|
||||
gboolean native;
|
||||
GdkEventMask event_mask;
|
||||
|
||||
g_return_val_if_fail (attributes != NULL, NULL);
|
||||
|
||||
@@ -692,30 +668,13 @@ gdk_surface_new (GdkDisplay *display,
|
||||
if (parent != NULL)
|
||||
g_warning (G_STRLOC "Toplevel surfaces must be created without a parent");
|
||||
break;
|
||||
case GDK_SURFACE_SUBSURFACE:
|
||||
#ifdef GDK_WINDOWING_WAYLAND
|
||||
if (!GDK_IS_WAYLAND_DISPLAY (display))
|
||||
{
|
||||
g_warning (G_STRLOC "Subsurface surfaces can only be used on Wayland");
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case GDK_SURFACE_CHILD:
|
||||
if (GDK_SURFACE_TYPE (parent) == GDK_SURFACE_FOREIGN)
|
||||
{
|
||||
g_warning (G_STRLOC "Child surfaces must not be created as children of\n"
|
||||
"a surface of type GDK_SURFACE_FOREIGN");
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
g_warning (G_STRLOC "cannot make surfaces of type %d", surface->surface_type);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
surface->event_mask = GDK_ALL_EVENTS_MASK;
|
||||
|
||||
if (attributes->wclass == GDK_INPUT_OUTPUT)
|
||||
{
|
||||
surface->input_only = FALSE;
|
||||
@@ -738,17 +697,10 @@ gdk_surface_new (GdkDisplay *display,
|
||||
native = TRUE; /* Always use native surfaces for toplevels */
|
||||
}
|
||||
|
||||
#ifdef GDK_WINDOWING_WAYLAND
|
||||
if (surface->surface_type == GDK_SURFACE_SUBSURFACE)
|
||||
native = TRUE; /* Always use native windows for subsurfaces as well */
|
||||
#endif
|
||||
|
||||
if (native)
|
||||
{
|
||||
event_mask = get_native_event_mask (surface);
|
||||
|
||||
/* Create the impl */
|
||||
_gdk_display_create_surface_impl (display, surface, parent, event_mask, attributes);
|
||||
gdk_display_create_surface_impl (display, surface, parent, attributes);
|
||||
surface->impl_surface = surface;
|
||||
}
|
||||
else
|
||||
@@ -947,81 +899,69 @@ _gdk_surface_destroy_hierarchy (GdkSurface *surface,
|
||||
case GDK_SURFACE_TOPLEVEL:
|
||||
case GDK_SURFACE_CHILD:
|
||||
case GDK_SURFACE_TEMP:
|
||||
case GDK_SURFACE_FOREIGN:
|
||||
case GDK_SURFACE_SUBSURFACE:
|
||||
if (surface->surface_type == GDK_SURFACE_FOREIGN && !foreign_destroy)
|
||||
if (surface->parent)
|
||||
{
|
||||
if (surface->parent->children)
|
||||
surface->parent->children = g_list_remove_link (surface->parent->children, &surface->children_list_node);
|
||||
|
||||
if (!recursing &&
|
||||
GDK_SURFACE_IS_MAPPED (surface))
|
||||
{
|
||||
recompute_visible_regions (surface, FALSE);
|
||||
gdk_surface_invalidate_in_parent (surface);
|
||||
}
|
||||
}
|
||||
|
||||
if (surface->gl_paint_context)
|
||||
{
|
||||
/* Make sure to destroy if current */
|
||||
g_object_run_dispose (G_OBJECT (surface->gl_paint_context));
|
||||
g_object_unref (surface->gl_paint_context);
|
||||
surface->gl_paint_context = NULL;
|
||||
}
|
||||
|
||||
if (surface->frame_clock)
|
||||
{
|
||||
g_object_run_dispose (G_OBJECT (surface->frame_clock));
|
||||
gdk_surface_set_frame_clock (surface, NULL);
|
||||
}
|
||||
|
||||
tmp = surface->children;
|
||||
surface->children = NULL;
|
||||
/* No need to free children list, its all made up of in-struct nodes */
|
||||
|
||||
while (tmp)
|
||||
{
|
||||
temp_surface = tmp->data;
|
||||
tmp = tmp->next;
|
||||
|
||||
if (temp_surface)
|
||||
_gdk_surface_destroy_hierarchy (temp_surface,
|
||||
TRUE,
|
||||
recursing_native || gdk_surface_has_impl (surface),
|
||||
foreign_destroy);
|
||||
}
|
||||
|
||||
_gdk_surface_clear_update_area (surface);
|
||||
|
||||
impl_class = GDK_SURFACE_IMPL_GET_CLASS (surface->impl);
|
||||
|
||||
if (gdk_surface_has_impl (surface))
|
||||
impl_class->destroy (surface, recursing_native, foreign_destroy);
|
||||
else
|
||||
{
|
||||
if (surface->parent)
|
||||
{
|
||||
if (surface->parent->children)
|
||||
surface->parent->children = g_list_remove_link (surface->parent->children, &surface->children_list_node);
|
||||
|
||||
if (!recursing &&
|
||||
GDK_SURFACE_IS_MAPPED (surface))
|
||||
{
|
||||
recompute_visible_regions (surface, FALSE);
|
||||
gdk_surface_invalidate_in_parent (surface);
|
||||
}
|
||||
}
|
||||
|
||||
if (surface->gl_paint_context)
|
||||
{
|
||||
/* Make sure to destroy if current */
|
||||
g_object_run_dispose (G_OBJECT (surface->gl_paint_context));
|
||||
g_object_unref (surface->gl_paint_context);
|
||||
surface->gl_paint_context = NULL;
|
||||
}
|
||||
|
||||
if (surface->frame_clock)
|
||||
{
|
||||
g_object_run_dispose (G_OBJECT (surface->frame_clock));
|
||||
gdk_surface_set_frame_clock (surface, NULL);
|
||||
}
|
||||
|
||||
if (surface->surface_type == GDK_SURFACE_FOREIGN)
|
||||
g_assert (surface->children == NULL);
|
||||
else
|
||||
{
|
||||
tmp = surface->children;
|
||||
surface->children = NULL;
|
||||
/* No need to free children list, its all made up of in-struct nodes */
|
||||
|
||||
while (tmp)
|
||||
{
|
||||
temp_surface = tmp->data;
|
||||
tmp = tmp->next;
|
||||
|
||||
if (temp_surface)
|
||||
_gdk_surface_destroy_hierarchy (temp_surface,
|
||||
TRUE,
|
||||
recursing_native || gdk_surface_has_impl (surface),
|
||||
foreign_destroy);
|
||||
}
|
||||
}
|
||||
|
||||
_gdk_surface_clear_update_area (surface);
|
||||
|
||||
impl_class = GDK_SURFACE_IMPL_GET_CLASS (surface->impl);
|
||||
|
||||
if (gdk_surface_has_impl (surface))
|
||||
impl_class->destroy (surface, recursing_native, foreign_destroy);
|
||||
else
|
||||
{
|
||||
/* hide to make sure we repaint and break grabs */
|
||||
gdk_surface_hide (surface);
|
||||
}
|
||||
|
||||
surface->state |= GDK_SURFACE_STATE_WITHDRAWN;
|
||||
surface->parent = NULL;
|
||||
surface->destroyed = TRUE;
|
||||
|
||||
surface_remove_from_pointer_info (surface, display);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (surface), properties[PROP_STATE]);
|
||||
/* hide to make sure we repaint and break grabs */
|
||||
gdk_surface_hide (surface);
|
||||
}
|
||||
|
||||
surface->state |= GDK_SURFACE_STATE_WITHDRAWN;
|
||||
surface->parent = NULL;
|
||||
surface->destroyed = TRUE;
|
||||
|
||||
surface_remove_from_pointer_info (surface, display);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (surface), properties[PROP_STATE]);
|
||||
g_object_notify_by_pspec (G_OBJECT (surface), properties[PROP_MAPPED]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1209,10 +1149,7 @@ gdk_surface_get_parent (GdkSurface *surface)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_SURFACE (surface), NULL);
|
||||
|
||||
if (gdk_surface_is_subsurface (surface))
|
||||
return surface->transient_for;
|
||||
else
|
||||
return surface->parent;
|
||||
return surface->parent;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1232,8 +1169,7 @@ gdk_surface_get_toplevel (GdkSurface *surface)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_SURFACE (surface), NULL);
|
||||
|
||||
while (surface->surface_type == GDK_SURFACE_CHILD ||
|
||||
surface->surface_type == GDK_SURFACE_SUBSURFACE)
|
||||
while (surface->surface_type == GDK_SURFACE_CHILD)
|
||||
{
|
||||
if (gdk_surface_is_toplevel (surface))
|
||||
break;
|
||||
@@ -1693,20 +1629,13 @@ static void
|
||||
gdk_surface_process_updates_recurse (GdkSurface *surface,
|
||||
cairo_region_t *expose_region)
|
||||
{
|
||||
GdkEvent *event;
|
||||
gboolean handled;
|
||||
|
||||
if (surface->destroyed)
|
||||
return;
|
||||
|
||||
/* Paint the surface before the children, clipped to the surface region */
|
||||
|
||||
event = gdk_event_new (GDK_EXPOSE);
|
||||
event->any.surface = g_object_ref (surface);
|
||||
event->any.send_event = FALSE;
|
||||
event->expose.region = cairo_region_reference (expose_region);
|
||||
|
||||
_gdk_event_emit (event);
|
||||
g_object_unref (event);
|
||||
g_signal_emit (surface, signals[RENDER], 0, expose_region, &handled);
|
||||
}
|
||||
|
||||
/* Process and remove any invalid area on the native surface by creating
|
||||
@@ -2285,10 +2214,8 @@ _gdk_surface_update_viewable (GdkSurface *surface)
|
||||
{
|
||||
gboolean viewable;
|
||||
|
||||
if (surface->surface_type == GDK_SURFACE_FOREIGN)
|
||||
viewable = TRUE;
|
||||
else if (gdk_surface_is_toplevel (surface) ||
|
||||
surface->parent->viewable)
|
||||
if (gdk_surface_is_toplevel (surface) ||
|
||||
surface->parent->viewable)
|
||||
viewable = GDK_SURFACE_IS_MAPPED (surface);
|
||||
else
|
||||
viewable = FALSE;
|
||||
@@ -2328,6 +2255,7 @@ gdk_surface_show_internal (GdkSurface *surface, gboolean raise)
|
||||
{
|
||||
surface->state = 0;
|
||||
g_object_notify_by_pspec (G_OBJECT (surface), properties[PROP_STATE]);
|
||||
g_object_notify_by_pspec (G_OBJECT (surface), properties[PROP_MAPPED]);
|
||||
}
|
||||
|
||||
did_show = _gdk_surface_update_viewable (surface);
|
||||
@@ -2343,15 +2271,6 @@ gdk_surface_show_internal (GdkSurface *surface, gboolean raise)
|
||||
impl_class->show (surface, !did_show ? was_mapped : TRUE);
|
||||
}
|
||||
|
||||
if (!was_mapped && !gdk_surface_has_impl (surface))
|
||||
{
|
||||
if (surface->event_mask & GDK_STRUCTURE_MASK)
|
||||
_gdk_make_event (surface, GDK_MAP, NULL, FALSE);
|
||||
|
||||
if (surface->parent && surface->parent->event_mask & GDK_SUBSTRUCTURE_MASK)
|
||||
_gdk_make_event (surface, GDK_MAP, NULL, FALSE);
|
||||
}
|
||||
|
||||
if (!was_mapped || did_raise)
|
||||
{
|
||||
recompute_visible_regions (surface, FALSE);
|
||||
@@ -2387,7 +2306,7 @@ gdk_surface_show_unraised (GdkSurface *surface)
|
||||
* other surfaces with the same parent surface appear below @surface.
|
||||
* This is true whether or not the surfaces are visible.
|
||||
*
|
||||
* If @surface is a toplevel, the surface manager may choose to deny the
|
||||
* If @surface is a toplevel, the window manager may choose to deny the
|
||||
* request to move the surface in the Z-order, gdk_surface_raise() only
|
||||
* requests the restack, does not guarantee it.
|
||||
*/
|
||||
@@ -2608,6 +2527,7 @@ gdk_surface_hide (GdkSurface *surface)
|
||||
{
|
||||
surface->state = GDK_SURFACE_STATE_WITHDRAWN;
|
||||
g_object_notify_by_pspec (G_OBJECT (surface), properties[PROP_STATE]);
|
||||
g_object_notify_by_pspec (G_OBJECT (surface), properties[PROP_MAPPED]);
|
||||
}
|
||||
|
||||
if (was_mapped)
|
||||
@@ -2654,198 +2574,11 @@ G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
|
||||
recompute_visible_regions (surface, FALSE);
|
||||
|
||||
if (was_mapped && !gdk_surface_has_impl (surface))
|
||||
{
|
||||
if (surface->event_mask & GDK_STRUCTURE_MASK)
|
||||
_gdk_make_event (surface, GDK_UNMAP, NULL, FALSE);
|
||||
|
||||
if (surface->parent && surface->parent->event_mask & GDK_SUBSTRUCTURE_MASK)
|
||||
_gdk_make_event (surface, GDK_UNMAP, NULL, FALSE);
|
||||
}
|
||||
|
||||
/* Invalidate the rect */
|
||||
if (was_mapped)
|
||||
gdk_surface_invalidate_in_parent (surface);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_surface_withdraw:
|
||||
* @surface: a toplevel #GdkSurface
|
||||
*
|
||||
* Withdraws a surface (unmaps it and asks the surface manager to forget about it).
|
||||
* This function is not really useful as gdk_surface_hide() automatically
|
||||
* withdraws toplevel surfaces before hiding them.
|
||||
**/
|
||||
void
|
||||
gdk_surface_withdraw (GdkSurface *surface)
|
||||
{
|
||||
GdkSurfaceImplClass *impl_class;
|
||||
gboolean was_mapped;
|
||||
GdkGLContext *current_context;
|
||||
|
||||
g_return_if_fail (GDK_IS_SURFACE (surface));
|
||||
|
||||
if (surface->destroyed)
|
||||
return;
|
||||
|
||||
was_mapped = GDK_SURFACE_IS_MAPPED (surface);
|
||||
|
||||
if (gdk_surface_has_impl (surface))
|
||||
{
|
||||
impl_class = GDK_SURFACE_IMPL_GET_CLASS (surface->impl);
|
||||
impl_class->withdraw (surface);
|
||||
|
||||
if (was_mapped)
|
||||
{
|
||||
if (surface->event_mask & GDK_STRUCTURE_MASK)
|
||||
_gdk_make_event (surface, GDK_UNMAP, NULL, FALSE);
|
||||
|
||||
if (surface->parent && surface->parent->event_mask & GDK_SUBSTRUCTURE_MASK)
|
||||
_gdk_make_event (surface, GDK_UNMAP, NULL, FALSE);
|
||||
}
|
||||
|
||||
current_context = gdk_gl_context_get_current ();
|
||||
if (current_context != NULL && gdk_gl_context_get_surface (current_context) == surface)
|
||||
gdk_gl_context_clear_current ();
|
||||
|
||||
recompute_visible_regions (surface, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_surface_set_events:
|
||||
* @surface: a #GdkSurface
|
||||
* @event_mask: event mask for @surface
|
||||
*
|
||||
* The event mask for a surface determines which events will be reported
|
||||
* for that surface from all master input devices. For example, an event mask
|
||||
* including #GDK_BUTTON_PRESS_MASK means the surface should report button
|
||||
* press events. The event mask is the bitwise OR of values from the
|
||||
* #GdkEventMask enumeration.
|
||||
*
|
||||
* See the [input handling overview][event-masks] for details.
|
||||
**/
|
||||
void
|
||||
gdk_surface_set_events (GdkSurface *surface,
|
||||
GdkEventMask event_mask)
|
||||
{
|
||||
GdkSurfaceImplClass *impl_class;
|
||||
|
||||
g_return_if_fail (GDK_IS_SURFACE (surface));
|
||||
|
||||
if (surface->destroyed)
|
||||
return;
|
||||
|
||||
surface->event_mask = event_mask;
|
||||
|
||||
if (gdk_surface_has_impl (surface))
|
||||
{
|
||||
impl_class = GDK_SURFACE_IMPL_GET_CLASS (surface->impl);
|
||||
impl_class->set_events (surface,
|
||||
get_native_event_mask (surface));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_surface_get_events:
|
||||
* @surface: a #GdkSurface
|
||||
*
|
||||
* Gets the event mask for @surface for all master input devices. See
|
||||
* gdk_surface_set_events().
|
||||
*
|
||||
* Returns: event mask for @surface
|
||||
**/
|
||||
GdkEventMask
|
||||
gdk_surface_get_events (GdkSurface *surface)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_SURFACE (surface), 0);
|
||||
|
||||
if (surface->destroyed)
|
||||
return 0;
|
||||
|
||||
return surface->event_mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_surface_set_device_events:
|
||||
* @surface: a #GdkSurface
|
||||
* @device: #GdkDevice to enable events for.
|
||||
* @event_mask: event mask for @surface
|
||||
*
|
||||
* Sets the event mask for a given device (Normally a floating device, not
|
||||
* attached to any visible pointer) to @surface. For example, an event mask
|
||||
* including #GDK_BUTTON_PRESS_MASK means the surface should report button
|
||||
* press events. The event mask is the bitwise OR of values from the
|
||||
* #GdkEventMask enumeration.
|
||||
*
|
||||
* See the [input handling overview][event-masks] for details.
|
||||
**/
|
||||
void
|
||||
gdk_surface_set_device_events (GdkSurface *surface,
|
||||
GdkDevice *device,
|
||||
GdkEventMask event_mask)
|
||||
{
|
||||
GdkEventMask device_mask;
|
||||
GdkSurface *native;
|
||||
|
||||
g_return_if_fail (GDK_IS_SURFACE (surface));
|
||||
g_return_if_fail (GDK_IS_DEVICE (device));
|
||||
|
||||
if (GDK_SURFACE_DESTROYED (surface))
|
||||
return;
|
||||
|
||||
if (G_UNLIKELY (!surface->device_events))
|
||||
surface->device_events = g_hash_table_new (NULL, NULL);
|
||||
|
||||
if (event_mask == 0)
|
||||
{
|
||||
/* FIXME: unsetting events on a master device
|
||||
* would restore surface->event_mask
|
||||
*/
|
||||
g_hash_table_remove (surface->device_events, device);
|
||||
}
|
||||
else
|
||||
g_hash_table_insert (surface->device_events, device,
|
||||
GINT_TO_POINTER (event_mask));
|
||||
|
||||
native = gdk_surface_get_toplevel (surface);
|
||||
|
||||
device_mask = get_native_device_event_mask (surface, device);
|
||||
GDK_DEVICE_GET_CLASS (device)->select_surface_events (device, native, device_mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_surface_get_device_events:
|
||||
* @surface: a #GdkSurface.
|
||||
* @device: a #GdkDevice.
|
||||
*
|
||||
* Returns the event mask for @surface corresponding to an specific device.
|
||||
*
|
||||
* Returns: device event mask for @surface
|
||||
**/
|
||||
GdkEventMask
|
||||
gdk_surface_get_device_events (GdkSurface *surface,
|
||||
GdkDevice *device)
|
||||
{
|
||||
GdkEventMask mask;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_SURFACE (surface), 0);
|
||||
g_return_val_if_fail (GDK_IS_DEVICE (device), 0);
|
||||
|
||||
if (GDK_SURFACE_DESTROYED (surface))
|
||||
return 0;
|
||||
|
||||
if (!surface->device_events)
|
||||
return 0;
|
||||
|
||||
mask = GPOINTER_TO_INT (g_hash_table_lookup (surface->device_events, device));
|
||||
|
||||
/* FIXME: device could be controlled by surface->event_mask */
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_surface_move_resize_toplevel (GdkSurface *surface,
|
||||
gboolean with_move,
|
||||
@@ -3086,24 +2819,19 @@ gdk_surface_set_cursor_internal (GdkSurface *surface,
|
||||
GdkDevice *device,
|
||||
GdkCursor *cursor)
|
||||
{
|
||||
GdkPointerSurfaceInfo *pointer_info;
|
||||
GdkDisplay *display;
|
||||
|
||||
if (GDK_SURFACE_DESTROYED (surface))
|
||||
return;
|
||||
|
||||
g_assert (gdk_surface_get_display (surface) == gdk_device_get_display (device));
|
||||
|
||||
if (surface->surface_type == GDK_SURFACE_FOREIGN)
|
||||
GDK_DEVICE_GET_CLASS (device)->set_surface_cursor (device, surface, cursor);
|
||||
else
|
||||
{
|
||||
GdkPointerSurfaceInfo *pointer_info;
|
||||
GdkDisplay *display;
|
||||
display = gdk_surface_get_display (surface);
|
||||
pointer_info = _gdk_display_get_pointer_info (display, device);
|
||||
|
||||
display = gdk_surface_get_display (surface);
|
||||
pointer_info = _gdk_display_get_pointer_info (display, device);
|
||||
|
||||
if (_gdk_surface_event_parent_of (surface, pointer_info->surface_under_pointer))
|
||||
update_cursor (display, device);
|
||||
}
|
||||
if (_gdk_surface_event_parent_of (surface, pointer_info->surface_under_pointer))
|
||||
update_cursor (display, device);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3137,7 +2865,7 @@ gdk_surface_get_cursor (GdkSurface *surface)
|
||||
*
|
||||
* Note that @cursor must be for the same display as @surface.
|
||||
*
|
||||
* Use gdk_cursor_new_for_display() or gdk_cursor_new_from_texture() to
|
||||
* Use gdk_cursor_new_from_name() or gdk_cursor_new_from_texture() to
|
||||
* create the cursor. To make the cursor invisible, use %GDK_BLANK_CURSOR.
|
||||
* Passing %NULL for the @cursor argument to gdk_surface_set_cursor() means
|
||||
* that @surface will use the cursor of its parent surface. Most surfaces
|
||||
@@ -3224,7 +2952,7 @@ gdk_surface_get_device_cursor (GdkSurface *surface,
|
||||
* @cursor: a #GdkCursor
|
||||
*
|
||||
* Sets a specific #GdkCursor for a given device when it gets inside @surface.
|
||||
* Use gdk_cursor_new_for_display() or gdk_cursor_new_from_texture() to create
|
||||
* Use gdk_cursor_new_fromm_name() or gdk_cursor_new_from_texture() to create
|
||||
* the cursor. To make the cursor invisible, use %GDK_BLANK_CURSOR. Passing
|
||||
* %NULL for the @cursor argument to gdk_surface_set_cursor() means that
|
||||
* @surface will use the cursor of its parent surface. Most surfaces should
|
||||
@@ -3665,7 +3393,7 @@ gdk_surface_merge_child_input_shapes (GdkSurface *surface)
|
||||
* gdk_surface_get_modal_hint:
|
||||
* @surface: A toplevel #GdkSurface.
|
||||
*
|
||||
* Determines whether or not the surface manager is hinted that @surface
|
||||
* Determines whether or not the window manager is hinted that @surface
|
||||
* has modal behaviour.
|
||||
*
|
||||
* Returns: whether or not the surface has the modal hint set.
|
||||
@@ -4129,11 +3857,8 @@ _gdk_make_event (GdkSurface *surface,
|
||||
|
||||
case GDK_FOCUS_CHANGE:
|
||||
case GDK_CONFIGURE:
|
||||
case GDK_MAP:
|
||||
case GDK_UNMAP:
|
||||
case GDK_DELETE:
|
||||
case GDK_DESTROY:
|
||||
case GDK_EXPOSE:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -4647,7 +4372,7 @@ gdk_surface_set_transient_for (GdkSurface *surface,
|
||||
* @x: (out): return location for X position of surface frame
|
||||
* @y: (out): return location for Y position of surface frame
|
||||
*
|
||||
* Obtains the top-left corner of the surface manager frame in root
|
||||
* Obtains the top-left corner of the window manager frame in root
|
||||
* surface coordinates.
|
||||
*
|
||||
**/
|
||||
@@ -5360,10 +5085,10 @@ gdk_surface_register_dnd (GdkSurface *surface)
|
||||
*
|
||||
* This function is called by the drag source.
|
||||
*
|
||||
* Returns: (transfer full) (nullable): a newly created #GdkDragContext or
|
||||
* Returns: (transfer full) (nullable): a newly created #GdkDrag or
|
||||
* %NULL on error.
|
||||
*/
|
||||
GdkDragContext *
|
||||
GdkDrag *
|
||||
gdk_drag_begin (GdkSurface *surface,
|
||||
GdkDevice *device,
|
||||
GdkContentProvider *content,
|
||||
@@ -5687,6 +5412,7 @@ void
|
||||
gdk_surface_set_state (GdkSurface *surface,
|
||||
GdkSurfaceState new_state)
|
||||
{
|
||||
gboolean was_mapped, mapped;
|
||||
g_return_if_fail (GDK_IS_SURFACE (surface));
|
||||
|
||||
if (new_state == surface->state)
|
||||
@@ -5697,8 +5423,12 @@ gdk_surface_set_state (GdkSurface *surface,
|
||||
* inconsistent state to the user.
|
||||
*/
|
||||
|
||||
was_mapped = GDK_SURFACE_IS_MAPPED (surface);
|
||||
|
||||
surface->state = new_state;
|
||||
|
||||
mapped = GDK_SURFACE_IS_MAPPED (surface);
|
||||
|
||||
_gdk_surface_update_viewable (surface);
|
||||
|
||||
/* We only really send the event to toplevels, since
|
||||
@@ -5710,13 +5440,15 @@ gdk_surface_set_state (GdkSurface *surface,
|
||||
{
|
||||
case GDK_SURFACE_TOPLEVEL:
|
||||
case GDK_SURFACE_TEMP: /* ? */
|
||||
g_object_notify (G_OBJECT (surface), "state");
|
||||
g_object_notify_by_pspec (G_OBJECT (surface), properties[PROP_STATE]);
|
||||
break;
|
||||
case GDK_SURFACE_FOREIGN:
|
||||
case GDK_SURFACE_CHILD:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (was_mapped != mapped)
|
||||
g_object_notify_by_pspec (G_OBJECT (surface), properties[PROP_MAPPED]);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -5726,3 +5458,16 @@ gdk_synthesize_surface_state (GdkSurface *surface,
|
||||
{
|
||||
gdk_surface_set_state (surface, (surface->state | set_flags) & ~unset_flags);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gdk_surface_handle_event (GdkEvent *event)
|
||||
{
|
||||
if (gdk_event_get_event_type (event) == GDK_CONFIGURE)
|
||||
{
|
||||
g_signal_emit (gdk_event_get_surface (event), signals[SIZE_CHANGED], 0,
|
||||
event->configure.width, event->configure.height);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
@@ -43,12 +43,7 @@ typedef struct _GdkGeometry GdkGeometry;
|
||||
* GdkSurfaceType:
|
||||
* @GDK_SURFACE_TOPLEVEL: toplevel window (used to implement #GtkWindow)
|
||||
* @GDK_SURFACE_CHILD: child surface (used to implement e.g. #GtkEntry)
|
||||
* @GDK_SURFACE_TEMP: override redirect temporary surface (used to implement
|
||||
* #GtkMenu)
|
||||
* @GDK_SURFACE_FOREIGN: foreign surface (see gdk_surface_foreign_new())
|
||||
* @GDK_SURFACE_SUBSURFACE: subsurface; This surface is visually
|
||||
* tied to a toplevel, and is moved/stacked with it. Currently this window
|
||||
* type is only implemented in Wayland. Since 3.14
|
||||
* @GDK_SURFACE_TEMP: override redirect temporary surface (used to implement #GtkMenu)
|
||||
*
|
||||
* Describes the kind of surface.
|
||||
*/
|
||||
@@ -56,9 +51,7 @@ typedef enum
|
||||
{
|
||||
GDK_SURFACE_TOPLEVEL,
|
||||
GDK_SURFACE_CHILD,
|
||||
GDK_SURFACE_TEMP,
|
||||
GDK_SURFACE_FOREIGN,
|
||||
GDK_SURFACE_SUBSURFACE
|
||||
GDK_SURFACE_TEMP
|
||||
} GdkSurfaceType;
|
||||
|
||||
/* Size restriction enumeration.
|
||||
@@ -217,9 +210,6 @@ typedef enum
|
||||
*
|
||||
* In general, when multiple flags are set, flipping should take precedence over
|
||||
* sliding, which should take precedence over resizing.
|
||||
*
|
||||
* Since: 3.22
|
||||
* Stability: Unstable
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
@@ -266,8 +256,6 @@ typedef enum
|
||||
*
|
||||
* Indicates which monitor (in a multi-head setup) a surface should span over
|
||||
* when in fullscreen mode.
|
||||
*
|
||||
* Since: 3.8
|
||||
**/
|
||||
typedef enum
|
||||
{
|
||||
@@ -377,16 +365,15 @@ struct _GdkGeometry
|
||||
* @GDK_SURFACE_STATE_ABOVE: the surface is kept above other surfaces.
|
||||
* @GDK_SURFACE_STATE_BELOW: the surface is kept below other surfaces.
|
||||
* @GDK_SURFACE_STATE_FOCUSED: the surface is presented as focused (with active decorations).
|
||||
* @GDK_SURFACE_STATE_TILED: the surface is in a tiled state, Since 3.10. Since 3.91.2, this
|
||||
* is deprecated in favor of per-edge information.
|
||||
* @GDK_SURFACE_STATE_TOP_TILED: whether the top edge is tiled, Since 3.91.2
|
||||
* @GDK_SURFACE_STATE_TOP_RESIZABLE: whether the top edge is resizable, Since 3.91.2
|
||||
* @GDK_SURFACE_STATE_RIGHT_TILED: whether the right edge is tiled, Since 3.91.2
|
||||
* @GDK_SURFACE_STATE_RIGHT_RESIZABLE: whether the right edge is resizable, Since 3.91.2
|
||||
* @GDK_SURFACE_STATE_BOTTOM_TILED: whether the bottom edge is tiled, Since 3.91.2
|
||||
* @GDK_SURFACE_STATE_BOTTOM_RESIZABLE: whether the bottom edge is resizable, Since 3.91.2
|
||||
* @GDK_SURFACE_STATE_LEFT_TILED: whether the left edge is tiled, Since 3.91.2
|
||||
* @GDK_SURFACE_STATE_LEFT_RESIZABLE: whether the left edge is resizable, Since 3.91.2
|
||||
* @GDK_SURFACE_STATE_TILED: the surface is in a tiled state. Deprecated
|
||||
* @GDK_SURFACE_STATE_TOP_TILED: whether the top edge is tiled
|
||||
* @GDK_SURFACE_STATE_TOP_RESIZABLE: whether the top edge is resizable
|
||||
* @GDK_SURFACE_STATE_RIGHT_TILED: whether the right edge is tiled
|
||||
* @GDK_SURFACE_STATE_RIGHT_RESIZABLE: whether the right edge is resizable
|
||||
* @GDK_SURFACE_STATE_BOTTOM_TILED: whether the bottom edge is tiled
|
||||
* @GDK_SURFACE_STATE_BOTTOM_RESIZABLE: whether the bottom edge is resizable
|
||||
* @GDK_SURFACE_STATE_LEFT_TILED: whether the left edge is tiled
|
||||
* @GDK_SURFACE_STATE_LEFT_RESIZABLE: whether the left edge is resizable
|
||||
*
|
||||
* Specifies the state of a toplevel surface.
|
||||
*/
|
||||
@@ -468,8 +455,6 @@ void gdk_surface_show (GdkSurface *surface);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_surface_hide (GdkSurface *surface);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_surface_withdraw (GdkSurface *surface);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_surface_show_unraised (GdkSurface *surface);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_surface_move (GdkSurface *surface,
|
||||
@@ -685,19 +670,6 @@ GDK_AVAILABLE_IN_ALL
|
||||
GList * gdk_surface_get_children_with_user_data (GdkSurface *surface,
|
||||
gpointer user_data);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkEventMask gdk_surface_get_events (GdkSurface *surface);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_surface_set_events (GdkSurface *surface,
|
||||
GdkEventMask event_mask);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_surface_set_device_events (GdkSurface *surface,
|
||||
GdkDevice *device,
|
||||
GdkEventMask event_mask);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkEventMask gdk_surface_get_device_events (GdkSurface *surface,
|
||||
GdkDevice *device);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_surface_set_icon_list (GdkSurface *surface,
|
||||
GList *surfaces);
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user