Compare commits
518 Commits
3.3.8
...
multitouch
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5b2be2f6f1 | ||
|
|
b51662cafa | ||
|
|
a328313885 | ||
|
|
8528385c80 | ||
|
|
c7eba11400 | ||
|
|
2cb50c9af2 | ||
|
|
bc5e401de4 | ||
|
|
fb99b5eeb4 | ||
|
|
d6e23b0924 | ||
|
|
42c0d95791 | ||
|
|
6d7ac9e87e | ||
|
|
607a1e8fc5 | ||
|
|
02eeed70bd | ||
|
|
849661a573 | ||
|
|
ca84ac7a6a | ||
|
|
8d421b2af2 | ||
|
|
b2776581da | ||
|
|
f7eb9edb9b | ||
|
|
fe87311f51 | ||
|
|
c38159d4d7 | ||
|
|
075911ccfd | ||
|
|
20a5364a5f | ||
|
|
4a3037574d | ||
|
|
fee9840d52 | ||
|
|
10bd4f8a72 | ||
|
|
1d986aa8a4 | ||
|
|
33790437ce | ||
|
|
239f52d543 | ||
|
|
f2d71d3da5 | ||
|
|
61e625d9a6 | ||
|
|
9e3330c90b | ||
|
|
108c831e23 | ||
|
|
77f071b5ff | ||
|
|
fb35e29a19 | ||
|
|
b1f4497697 | ||
|
|
29569e6049 | ||
|
|
c201145d02 | ||
|
|
eb214aae74 | ||
|
|
fbef4384aa | ||
|
|
88909ac9b2 | ||
|
|
84d9872a26 | ||
|
|
576ba1a03d | ||
|
|
bb448f619c | ||
|
|
9827003e06 | ||
|
|
14100b867c | ||
|
|
5926e3cfec | ||
|
|
e09d7b5456 | ||
|
|
c9b8f866df | ||
|
|
eea525ac89 | ||
|
|
76e7a9e5b7 | ||
|
|
5a523e500b | ||
|
|
33ea7850c9 | ||
|
|
9856a2faeb | ||
|
|
a19c4b207c | ||
|
|
264739e6ad | ||
|
|
10b4eaa10b | ||
|
|
be21cc53bc | ||
|
|
cda35f142f | ||
|
|
5c98ea081e | ||
|
|
78866ca13d | ||
|
|
d4382300b4 | ||
|
|
7ef01e70f7 | ||
|
|
10316b6ab2 | ||
|
|
e11d9904bc | ||
|
|
f1d33f76c7 | ||
|
|
fe72a8192d | ||
|
|
bf543ac8f4 | ||
|
|
93f7a97f01 | ||
|
|
cc188dffa9 | ||
|
|
33e3b9ddbb | ||
|
|
8c4b0b66b8 | ||
|
|
2781c9544b | ||
|
|
4765dde5cf | ||
|
|
658b0e8092 | ||
|
|
0e5d05f8e0 | ||
|
|
f1570c5c92 | ||
|
|
e042c53caa | ||
|
|
a7b6859561 | ||
|
|
14235c9c17 | ||
|
|
6a6bed8e04 | ||
|
|
7a07995944 | ||
|
|
62afe5cda6 | ||
|
|
95f6b7fa82 | ||
|
|
ae2438df90 | ||
|
|
fafb78e38e | ||
|
|
4068758bb8 | ||
|
|
bb87595220 | ||
|
|
001a1517da | ||
|
|
76b285f475 | ||
|
|
0b796299c1 | ||
|
|
5d2af3e13d | ||
|
|
15d2f1697d | ||
|
|
460a54ce15 | ||
|
|
3ab0ccf643 | ||
|
|
cebd79e7eb | ||
|
|
4e321365cf | ||
|
|
1b088606f7 | ||
|
|
7bf410f927 | ||
|
|
5476f09d35 | ||
|
|
a49c9a27fb | ||
|
|
e5a3cf5a36 | ||
|
|
59a0f62079 | ||
|
|
fbbd6b2c2e | ||
|
|
d77977aa62 | ||
|
|
da35350ee3 | ||
|
|
40996af9c1 | ||
|
|
7e29b38bd4 | ||
|
|
c1b86a5eab | ||
|
|
68587c203c | ||
|
|
80e08d1b1b | ||
|
|
0a05318277 | ||
|
|
5c187245a4 | ||
|
|
739059cc91 | ||
|
|
86e966b944 | ||
|
|
ef08d3975c | ||
|
|
c50007b33a | ||
|
|
9f20e16683 | ||
|
|
4f2ce2f7b6 | ||
|
|
a404a56254 | ||
|
|
7a59b443ee | ||
|
|
127bfd71d7 | ||
|
|
35341511b9 | ||
|
|
65888ac515 | ||
|
|
313f51d1f8 | ||
|
|
5ddf0f4e5f | ||
|
|
5e726db14e | ||
|
|
705dde471f | ||
|
|
d83640dc34 | ||
|
|
ed20c3255b | ||
|
|
0a189935ad | ||
|
|
1f5681e419 | ||
|
|
8dd4a0adf1 | ||
|
|
dcec8dfdde | ||
|
|
8e85702dca | ||
|
|
b58d50a0da | ||
|
|
1578585c08 | ||
|
|
a18b3f2ed4 | ||
|
|
039eb8dc04 | ||
|
|
5f0c4fc20f | ||
|
|
04b36dabd0 | ||
|
|
cfe65a0d6c | ||
|
|
ccf7867c35 | ||
|
|
bf89bc624b | ||
|
|
392fdff8e5 | ||
|
|
444f562955 | ||
|
|
db8555ed31 | ||
|
|
cc1b29cd67 | ||
|
|
a0b4ab109d | ||
|
|
87d979f498 | ||
|
|
f9be52cb2f | ||
|
|
fae1be06cd | ||
|
|
e1a625aa78 | ||
|
|
347328adb0 | ||
|
|
cb775a6a6d | ||
|
|
6c2b7a9441 | ||
|
|
bef12c003c | ||
|
|
19da38b811 | ||
|
|
453aecd346 | ||
|
|
2d57c5c374 | ||
|
|
c2426516c4 | ||
|
|
18ea4825cf | ||
|
|
1f698e4f62 | ||
|
|
49a23acd89 | ||
|
|
80f0feda98 | ||
|
|
06b34b3fc1 | ||
|
|
92322a63f5 | ||
|
|
5e77e1c117 | ||
|
|
6dbb4d6384 | ||
|
|
988cbb6300 | ||
|
|
1cbaca6c60 | ||
|
|
2abe72283e | ||
|
|
126e941466 | ||
|
|
51c6e8329d | ||
|
|
91b4781ae9 | ||
|
|
92618eb8e2 | ||
|
|
9cc827fcd1 | ||
|
|
40974b1463 | ||
|
|
dc1929a9de | ||
|
|
57e057df60 | ||
|
|
32f1a5ad83 | ||
|
|
1f05f94885 | ||
|
|
05e2124f24 | ||
|
|
1fd311803a | ||
|
|
7f44feab19 | ||
|
|
3a7ed2e7bd | ||
|
|
bad24bc119 | ||
|
|
5aaeaa7b81 | ||
|
|
bcc4186388 | ||
|
|
74a53b542b | ||
|
|
9da3d8b7b9 | ||
|
|
73944c6e81 | ||
|
|
a9c2a586b1 | ||
|
|
83de34882b | ||
|
|
1ccedc5fa4 | ||
|
|
33e54e45be | ||
|
|
46187037a3 | ||
|
|
ae132c0a1a | ||
|
|
4c61f1f663 | ||
|
|
4e37d56d51 | ||
|
|
8f201d62d9 | ||
|
|
d7cff0797e | ||
|
|
ed5aa953d5 | ||
|
|
cb128cc6e9 | ||
|
|
23a5f7a22c | ||
|
|
03a2b338ee | ||
|
|
c5cfb6e02b | ||
|
|
1f68d7d827 | ||
|
|
6ed16b5b41 | ||
|
|
43ffb8521d | ||
|
|
1f7cc92219 | ||
|
|
3f92e24cb7 | ||
|
|
cc127c64a9 | ||
|
|
327e36e360 | ||
|
|
f2aaffaf07 | ||
|
|
cd300835d7 | ||
|
|
e56adaebea | ||
|
|
dbbe4c12fa | ||
|
|
296cd814e5 | ||
|
|
5bd4c234fb | ||
|
|
4226551fff | ||
|
|
bdb8931bda | ||
|
|
3a35895a00 | ||
|
|
d3b30bff0c | ||
|
|
2a8d3f78e9 | ||
|
|
ff1f5de62f | ||
|
|
1720e8ebf3 | ||
|
|
8178578359 | ||
|
|
8d1565df94 | ||
|
|
9161119329 | ||
|
|
9b81322409 | ||
|
|
e1bf3b6650 | ||
|
|
efccf87961 | ||
|
|
2c24e3cb6a | ||
|
|
ce8212c5a8 | ||
|
|
ea6ac7131e | ||
|
|
e06ccb0fbb | ||
|
|
021f5e0365 | ||
|
|
759765114f | ||
|
|
3b6e316e74 | ||
|
|
e2bde55277 | ||
|
|
abdbe207fe | ||
|
|
a04fa5300a | ||
|
|
8dc9866e2a | ||
|
|
4b200a0429 | ||
|
|
713c532940 | ||
|
|
a3b097639f | ||
|
|
42c2d51ad9 | ||
|
|
2d972058ab | ||
|
|
842d3ac53d | ||
|
|
90e65f30ab | ||
|
|
a96c122fa4 | ||
|
|
194a48bd4a | ||
|
|
01193bcae2 | ||
|
|
3827d75f64 | ||
|
|
bf8d9ceb2f | ||
|
|
315ac9413b | ||
|
|
6130c65470 | ||
|
|
da30c8253b | ||
|
|
5e587229c8 | ||
|
|
24db6d7a6f | ||
|
|
5fe947640c | ||
|
|
07f8336dbd | ||
|
|
00a810ae04 | ||
|
|
f90ff5d50b | ||
|
|
a4559f1e19 | ||
|
|
f33fe5b677 | ||
|
|
e2339f5ebd | ||
|
|
3b1d8beab0 | ||
|
|
5e3c2524f8 | ||
|
|
6d430ad713 | ||
|
|
db2eb85e4a | ||
|
|
cdc6e82720 | ||
|
|
7de0672650 | ||
|
|
251cffb638 | ||
|
|
5d9736fe13 | ||
|
|
b21dd67d60 | ||
|
|
fed1cfb122 | ||
|
|
6723feae8a | ||
|
|
c525fe27f3 | ||
|
|
56f8cf91e0 | ||
|
|
71efe31f16 | ||
|
|
41e98b14d3 | ||
|
|
72ede43928 | ||
|
|
b4c31b070f | ||
|
|
bc95f03f37 | ||
|
|
c2512d1c03 | ||
|
|
63865720b7 | ||
|
|
a0f6fc137b | ||
|
|
afcd3c9f70 | ||
|
|
9a2ea96a1b | ||
|
|
de1b5e67b6 | ||
|
|
20c3f95e7b | ||
|
|
33864064f4 | ||
|
|
75eddfffbb | ||
|
|
6a381b0c1d | ||
|
|
9e14789b63 | ||
|
|
137bab8710 | ||
|
|
9ec7d6b68e | ||
|
|
ac9a94b7af | ||
|
|
40a89fccb5 | ||
|
|
33961154b6 | ||
|
|
c2a6dcc73c | ||
|
|
b5d5e6427a | ||
|
|
81465d2d97 | ||
|
|
cb625d21b4 | ||
|
|
af200feb0e | ||
|
|
bd05c1f959 | ||
|
|
c064bdb00c | ||
|
|
a45b3df9d0 | ||
|
|
68f51ee980 | ||
|
|
aa390b5e57 | ||
|
|
8971d5ed74 | ||
|
|
022e17afbc | ||
|
|
fb0c53a0ed | ||
|
|
6b2f10321f | ||
|
|
b5b9965283 | ||
|
|
610ea728b2 | ||
|
|
57386285fa | ||
|
|
35db0819ff | ||
|
|
fa3544e744 | ||
|
|
f855238cc7 | ||
|
|
8cdbebae71 | ||
|
|
1484208b4c | ||
|
|
bc1a689e55 | ||
|
|
e84af235ee | ||
|
|
f2352a5f35 | ||
|
|
2fdadb053c | ||
|
|
f1c73fcc0c | ||
|
|
cc83986eb8 | ||
|
|
3c4b8a676f | ||
|
|
cfebd1ec06 | ||
|
|
1eeafcf569 | ||
|
|
ceed732d65 | ||
|
|
2434dbc10a | ||
|
|
82b739c490 | ||
|
|
1979d048d3 | ||
|
|
d56ac0d4df | ||
|
|
2e901752b1 | ||
|
|
811e848832 | ||
|
|
5df9b0188a | ||
|
|
f22c986102 | ||
|
|
0c140daff2 | ||
|
|
a63ff72406 | ||
|
|
82c2dad178 | ||
|
|
762ea4793f | ||
|
|
a81ac3d5cd | ||
|
|
9551f542bd | ||
|
|
893807bee0 | ||
|
|
bd8fefb20e | ||
|
|
032e8f9f9b | ||
|
|
6ba33e7af5 | ||
|
|
e4c2d9b259 | ||
|
|
4c8e9ee6b6 | ||
|
|
c8786c3b97 | ||
|
|
5e5e8367ce | ||
|
|
f7e0ce3b28 | ||
|
|
25affd4766 | ||
|
|
c2fb315878 | ||
|
|
9fa764abec | ||
|
|
05f14af24c | ||
|
|
6b04c0f828 | ||
|
|
21e20b0d5b | ||
|
|
4dd9a73c8a | ||
|
|
95f5ca062b | ||
|
|
d61a84bb3a | ||
|
|
2ae2c443d0 | ||
|
|
623b5192cc | ||
|
|
c0ee68b7fe | ||
|
|
26ff536069 | ||
|
|
aa16f469bc | ||
|
|
65e6248542 | ||
|
|
cf7f0cb27a | ||
|
|
ec6b36add5 | ||
|
|
a8211b75b2 | ||
|
|
00325e992b | ||
|
|
c598a9501f | ||
|
|
1bbd2c48c5 | ||
|
|
821365af15 | ||
|
|
93523e70a0 | ||
|
|
4675ed27fd | ||
|
|
9d7a722b38 | ||
|
|
44135ba2eb | ||
|
|
8abc74680d | ||
|
|
0e395ea5a2 | ||
|
|
8dab59e5c9 | ||
|
|
5ec36a015c | ||
|
|
2cbe088674 | ||
|
|
dd2bbd1b85 | ||
|
|
a5b189093b | ||
|
|
4b90ba2701 | ||
|
|
d140411698 | ||
|
|
3ca795d447 | ||
|
|
8275a20026 | ||
|
|
5b2c1ee828 | ||
|
|
9afe13bf91 | ||
|
|
0481fbf7ce | ||
|
|
4041accda3 | ||
|
|
36242f8035 | ||
|
|
25231e36a2 | ||
|
|
26da21f352 | ||
|
|
f663d4c82e | ||
|
|
50c5bf97ea | ||
|
|
f01cef05c8 | ||
|
|
9b6ae2e9d5 | ||
|
|
4497ac6b58 | ||
|
|
585a6652d5 | ||
|
|
7a080413ad | ||
|
|
12e661c801 | ||
|
|
b2eadbc723 | ||
|
|
aae9a71986 | ||
|
|
1cf1fbdbbf | ||
|
|
c32fedc264 | ||
|
|
3c486ee96d | ||
|
|
80b414efc2 | ||
|
|
f7c6c97710 | ||
|
|
67c3bf7b02 | ||
|
|
349b1eff03 | ||
|
|
4e41b5c5fd | ||
|
|
f20551e2ed | ||
|
|
f84ec775d8 | ||
|
|
99c903ec04 | ||
|
|
15711a3bf7 | ||
|
|
0453f91f02 | ||
|
|
594903ecde | ||
|
|
59a1434557 | ||
|
|
73449a4e28 | ||
|
|
38d869cb8e | ||
|
|
c7756f0410 | ||
|
|
203f600373 | ||
|
|
76420c4793 | ||
|
|
d088e729e5 | ||
|
|
6e9b06028c | ||
|
|
7f2b08c04d | ||
|
|
2dbfa88459 | ||
|
|
f8e9d264da | ||
|
|
c5d9c6f27c | ||
|
|
e796f3a4e7 | ||
|
|
ffd6dab8aa | ||
|
|
f11e5a3f4d | ||
|
|
bc5d8da0c6 | ||
|
|
2890ac842f | ||
|
|
7a39912cae | ||
|
|
0fb61e883e | ||
|
|
78d2ac2cb6 | ||
|
|
e0d32d9456 | ||
|
|
90b991dd13 | ||
|
|
3ca7ec693f | ||
|
|
96cfd3f8c7 | ||
|
|
dbd66a8f02 | ||
|
|
4c1a45f9ab | ||
|
|
7c1717886a | ||
|
|
e2750a4f5e | ||
|
|
eed307713b | ||
|
|
c76cccd437 | ||
|
|
d00368cac9 | ||
|
|
fe1907708c | ||
|
|
8da4c2affa | ||
|
|
fd4f701c50 | ||
|
|
104d9cab37 | ||
|
|
fa6ad2ca04 | ||
|
|
1e869311c1 | ||
|
|
38f395481c | ||
|
|
7d56c052d4 | ||
|
|
d818bdc297 | ||
|
|
4240bfb74a | ||
|
|
e7d6400149 | ||
|
|
1819543e1e | ||
|
|
1ae4b1ecc1 | ||
|
|
0d9d3025c6 | ||
|
|
8599c98780 | ||
|
|
2f3ffd5fde | ||
|
|
080f8740f2 | ||
|
|
d0393d7376 | ||
|
|
4c2e53a468 | ||
|
|
3104e5d2c1 | ||
|
|
0363a7a2e3 | ||
|
|
5c10f8ce8c | ||
|
|
1326466309 | ||
|
|
31e89b44da | ||
|
|
880daf8bb2 | ||
|
|
e34589ddea | ||
|
|
bf7779bfb7 | ||
|
|
a9614a39a4 | ||
|
|
5df87d06d4 | ||
|
|
835e37f08f | ||
|
|
c06887c9f0 | ||
|
|
0c514dc7dd | ||
|
|
d5656b6139 | ||
|
|
d9f1ac1c9c | ||
|
|
15b4198a80 | ||
|
|
391cd36a5b | ||
|
|
691a94214a | ||
|
|
284ff06ef6 | ||
|
|
d80bad037f | ||
|
|
7ec927a386 | ||
|
|
681871dd9e | ||
|
|
4b7ec2be82 | ||
|
|
0ea1924494 | ||
|
|
b9190c7fe9 | ||
|
|
fa17e23ce7 | ||
|
|
dbabff0846 | ||
|
|
637e6688da | ||
|
|
70cf23a729 | ||
|
|
ba9546ff32 | ||
|
|
60317cbf1a | ||
|
|
ed8e7d1793 | ||
|
|
4c79e25915 | ||
|
|
29641ecd07 | ||
|
|
1839caa7b7 | ||
|
|
9770184643 | ||
|
|
345d865ac6 | ||
|
|
d6f9eb1ff8 | ||
|
|
27f3c3c031 | ||
|
|
b9509ec15d | ||
|
|
85fcd50b3f | ||
|
|
626c08a847 | ||
|
|
dba9c2e5a7 | ||
|
|
299a4eca28 |
@@ -10,7 +10,7 @@ TEST_PROGS =
|
||||
### testing rules
|
||||
|
||||
# Xvfb based test rules
|
||||
XVFB = Xvfb -ac -noreset -screen 0 800x600x16
|
||||
XVFB = Xvfb -ac -noreset -screen 0 1024x768x16
|
||||
XIDS = 101 102 103 104 105 106 107 197 199 211 223 227 293 307 308 309 310 311 \
|
||||
491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 \
|
||||
991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 \
|
||||
@@ -29,7 +29,7 @@ endif
|
||||
XVFB_START = \
|
||||
${XVFB} -help 2>/dev/null 1>&2 \
|
||||
&& XID=`for id in $(XIDS) ; do test -e /tmp/.X$$id-lock || { echo $$id; exit 0; }; done; exit 1` \
|
||||
&& { ${XVFB} :$$XID -screen 0 800x600x16 -nolisten tcp -auth /dev/null >/dev/null 2>&1 & \
|
||||
&& { ${XVFB} :$$XID -nolisten tcp -auth /dev/null >/dev/null 2>&1 & \
|
||||
trap "kill -15 $$! " 0 HUP INT QUIT TRAP USR1 PIPE TERM ; } \
|
||||
|| { echo "Gtk+Tests:ERROR: Failed to start Xvfb environment for X11 target tests."; exit 1; } \
|
||||
&& DISPLAY=:$$XID && export DISPLAY
|
||||
|
||||
48
NEWS
48
NEWS
@@ -1,3 +1,51 @@
|
||||
Overview of Changes in GTK+ 3.3.14
|
||||
==================================
|
||||
|
||||
* Theming
|
||||
- Fixes for border handling in GtkEntry,
|
||||
GtkCellRendererText, GtkComboBox
|
||||
- Parse values more carefully, supporting
|
||||
percentages, angles
|
||||
- Implement CSS linear-gradient syntax
|
||||
- Support background-size
|
||||
- Support a gtk.gresource file in themes
|
||||
|
||||
* Bugs fixed
|
||||
543520 Cups custom options are not sent properly
|
||||
649121 Crash in GtkAppChooserDialog packagekit button
|
||||
669176 Regression: atk-add-key-event-listener doesn't work
|
||||
|
||||
* Updated translations
|
||||
Galician
|
||||
Norwegian bokmål
|
||||
Spanish
|
||||
|
||||
|
||||
Overview of Changes in GTK+ 3.3.10
|
||||
==================================
|
||||
|
||||
* GtkApplication:
|
||||
- Move application menu handling over from GIO
|
||||
- Fix resize grip positioning in GtkApplicationWindow
|
||||
|
||||
* Wayland:
|
||||
- Make combo boxes work
|
||||
- Make key modifiers work like on X11
|
||||
- Make mouse buttons work correctly
|
||||
|
||||
* Quartz:
|
||||
- Make key modifiers work more like they do on X11
|
||||
|
||||
* Printing:
|
||||
- Fix handling of custom cups options
|
||||
|
||||
* Accessibility:
|
||||
- Bring key snooping support back for now
|
||||
|
||||
* Translation updates:
|
||||
Spanish
|
||||
|
||||
|
||||
Overview of Changes in GTK+ 3.3.8
|
||||
=================================
|
||||
|
||||
|
||||
13
configure.ac
13
configure.ac
@@ -10,7 +10,7 @@
|
||||
|
||||
m4_define([gtk_major_version], [3])
|
||||
m4_define([gtk_minor_version], [3])
|
||||
m4_define([gtk_micro_version], [8])
|
||||
m4_define([gtk_micro_version], [15])
|
||||
m4_define([gtk_interface_age], [0])
|
||||
m4_define([gtk_binary_age],
|
||||
[m4_eval(100 * gtk_minor_version + gtk_micro_version)])
|
||||
@@ -39,11 +39,11 @@ AC_CONFIG_AUX_DIR([build-aux])
|
||||
m4_define([gtk_binary_version], [3.0.0])
|
||||
|
||||
# required versions of other packages
|
||||
m4_define([glib_required_version], [2.31.10])
|
||||
m4_define([glib_required_version], [2.31.14])
|
||||
m4_define([pango_required_version], [1.29.0])
|
||||
m4_define([atk_required_version], [2.1.5])
|
||||
m4_define([cairo_required_version], [1.10.0])
|
||||
m4_define([gdk_pixbuf_required_version], [2.23.5])
|
||||
m4_define([gdk_pixbuf_required_version], [2.25.2])
|
||||
m4_define([introspection_required_version], [0.10.1])
|
||||
GLIB_REQUIRED_VERSION=glib_required_version
|
||||
PANGO_REQUIRED_VERSION=pango_required_version
|
||||
@@ -935,7 +935,7 @@ if test "x$enable_x11_backend" = xyes; then
|
||||
have_base_x_pc=true
|
||||
X_PACKAGES="$X_PACKAGES x11 xext"
|
||||
x_libs="`$PKG_CONFIG --libs x11 xext`"
|
||||
X_CFLAGS="`$PKG_CONFIG --cflags x11 xext`"
|
||||
X_CFLAGS="`$PKG_CONFIG --cflags x11 xext` -DXINPUT2_1_USE_UNSTABLE_PROTOCOL -DXINPUT2_2_USE_UNSTABLE_PROTOCOL"
|
||||
|
||||
# Strip out any .la files that pkg-config might give us (this happens
|
||||
# with -uninstalled.pc files)
|
||||
@@ -1126,6 +1126,10 @@ if test "x$enable_x11_backend" = xyes; then
|
||||
AC_DEFINE(XINPUT_2, 1, [Define to 1 if XInput 2.0 is available]),
|
||||
X_EXTENSIONS="$X_EXTENSIONS XInput")
|
||||
|
||||
gtk_save_LIBS="$LIBS"
|
||||
LIBS="$LIBS -lXi"
|
||||
AC_CHECK_FUNC(XIAllowTouchEvents, AC_DEFINE(XINPUT_2_2, 1, [Define to 1 if XInput 2.2 is available]))
|
||||
LIBS="$gtk_save_LIBS"
|
||||
else
|
||||
AC_DEFINE(XINPUT_NONE, 1,
|
||||
[Define to 1 if no XInput should be used])
|
||||
@@ -1748,6 +1752,7 @@ demos/Makefile
|
||||
demos/gtk-demo/Makefile
|
||||
demos/gtk-demo/geninclude.pl
|
||||
demos/pixbuf-demo/Makefile
|
||||
demos/widget-factory/Makefile
|
||||
examples/Makefile
|
||||
tests/Makefile
|
||||
tests/a11y/Makefile
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
## Makefile.am for gtk+/demos
|
||||
include $(top_srcdir)/Makefile.decl
|
||||
|
||||
SUBDIRS = gtk-demo pixbuf-demo
|
||||
SUBDIRS = gtk-demo widget-factory pixbuf-demo
|
||||
|
||||
-include $(top_srcdir)/git.mk
|
||||
|
||||
@@ -29,6 +29,7 @@ demos = \
|
||||
links.c \
|
||||
list_store.c \
|
||||
menus.c \
|
||||
multitouch.c \
|
||||
offscreen_window.c \
|
||||
offscreen_window2.c \
|
||||
overlay.c \
|
||||
@@ -77,7 +78,13 @@ EXTRA_DIST += \
|
||||
application.ui \
|
||||
menus.ui \
|
||||
gtk-logo-24.png \
|
||||
gtk-logo-48.png
|
||||
gtk-logo-48.png \
|
||||
org.gtk.Demo.gschema.xml
|
||||
|
||||
gsettings_SCHEMAS = \
|
||||
org.gtk.Demo.gschema.xml
|
||||
|
||||
@GSETTINGS_RULES@
|
||||
|
||||
demos.h: @REBUILD@ $(demos) geninclude.pl
|
||||
$(AM_V_GEN) (here=`pwd` ; cd $(srcdir) && $(PERL) $$here/geninclude.pl $(demos)) > demos.h
|
||||
|
||||
@@ -96,7 +96,6 @@ activate_about (GSimpleAction *action,
|
||||
{
|
||||
GtkWidget *window = user_data;
|
||||
GdkPixbuf *pixbuf;
|
||||
GInputStream *stream;
|
||||
|
||||
const gchar *authors[] = {
|
||||
"Peter Mattis",
|
||||
@@ -114,9 +113,7 @@ activate_about (GSimpleAction *action,
|
||||
NULL
|
||||
};
|
||||
|
||||
stream = g_resources_open_stream ("/logos/gtk-logo-48.png", 0, NULL);
|
||||
pixbuf = gdk_pixbuf_new_from_stream (stream, NULL, NULL);
|
||||
g_object_unref (stream);
|
||||
pixbuf = gdk_pixbuf_new_from_resource ("/logos/gtk-logo-48.png", NULL);
|
||||
|
||||
gtk_show_about_dialog (GTK_WINDOW (window),
|
||||
"program-name", "GTK+ Code Demos",
|
||||
@@ -168,7 +165,6 @@ register_stock_icons (void)
|
||||
GdkPixbuf *pixbuf;
|
||||
GtkIconFactory *factory;
|
||||
GtkIconSet *icon_set;
|
||||
GInputStream *stream;
|
||||
|
||||
static GtkStockItem items[] = {
|
||||
{ "demo-gtk-logo", "_GTK!", 0, 0, NULL }
|
||||
@@ -181,9 +177,7 @@ register_stock_icons (void)
|
||||
factory = gtk_icon_factory_new ();
|
||||
gtk_icon_factory_add_default (factory);
|
||||
|
||||
stream = g_resources_open_stream ("/logos/gtk-logo-24.png", 0, NULL);
|
||||
pixbuf = gdk_pixbuf_new_from_stream (stream, NULL, NULL);
|
||||
g_object_unref (stream);
|
||||
pixbuf = gdk_pixbuf_new_from_resource ("/logos/gtk-logo-24.png", NULL);
|
||||
|
||||
icon_set = gtk_icon_set_new_from_pixbuf (pixbuf);
|
||||
gtk_icon_factory_add (factory, "demo-gtk-logo", icon_set);
|
||||
@@ -280,10 +274,10 @@ static GActionEntry app_entries[] = {
|
||||
|
||||
static GActionEntry win_entries[] = {
|
||||
{ "titlebar", activate_toggle, NULL, "false", change_titlebar_state },
|
||||
{ "color", activate_radio, "s", "'red'", change_radio_state },
|
||||
{ "shape", activate_radio, "s", "'oval'", change_radio_state },
|
||||
{ "bold", activate_toggle, NULL, "false", NULL },
|
||||
{ "about", activate_about, NULL, NULL, NULL },
|
||||
{ "file1", activate_action, NULL, NULL, NULL },
|
||||
{ "logo", activate_action, NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
@@ -323,6 +317,8 @@ activate (GApplication *app)
|
||||
GtkWidget *message;
|
||||
GtkWidget *button;
|
||||
GtkWidget *infobar;
|
||||
GtkWidget *menutool;
|
||||
GMenuModel *toolmenu;
|
||||
GtkTextBuffer *buffer;
|
||||
|
||||
window = gtk_application_window_new (GTK_APPLICATION (app));
|
||||
@@ -343,12 +339,17 @@ activate (GApplication *app)
|
||||
message = (GtkWidget *)gtk_builder_get_object (builder, "message");
|
||||
button = (GtkWidget *)gtk_builder_get_object (builder, "button");
|
||||
infobar = (GtkWidget *)gtk_builder_get_object (builder, "infobar");
|
||||
menutool = (GtkWidget *)gtk_builder_get_object (builder, "menutool");
|
||||
toolmenu = (GMenuModel *)gtk_builder_get_object (builder, "toolmenu");
|
||||
|
||||
g_object_set_data (G_OBJECT (window), "message", message);
|
||||
g_object_set_data (G_OBJECT (window), "infobar", infobar);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (window), grid);
|
||||
|
||||
gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (menutool),
|
||||
gtk_menu_new_from_model (toolmenu));
|
||||
|
||||
gtk_widget_grab_focus (contents);
|
||||
g_signal_connect (button, "clicked", G_CALLBACK (clicked_cb), infobar);
|
||||
|
||||
@@ -370,17 +371,24 @@ int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
GtkApplication *app;
|
||||
GSettings *settings;
|
||||
GAction *action;
|
||||
|
||||
gtk_init (NULL, NULL);
|
||||
|
||||
register_stock_icons ();
|
||||
|
||||
app = gtk_application_new ("org.gtk.Demo", 0);
|
||||
settings = g_settings_new ("org.gtk.Demo");
|
||||
|
||||
g_action_map_add_action_entries (G_ACTION_MAP (app),
|
||||
app_entries, G_N_ELEMENTS (app_entries),
|
||||
app);
|
||||
|
||||
action = g_settings_create_action (settings, "color");
|
||||
|
||||
g_action_map_add_action (G_ACTION_MAP (app), action);
|
||||
|
||||
g_signal_connect (app, "startup", G_CALLBACK (startup), NULL);
|
||||
g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<gresources>
|
||||
<gresource prefix="/logos">
|
||||
<file>gtk-logo-24.png</file>
|
||||
<file>gtk-logo-48.png</file>
|
||||
<file preprocess="to-pixdata">gtk-logo-24.png</file>
|
||||
<file preprocess="to-pixdata">gtk-logo-48.png</file>
|
||||
</gresource>
|
||||
<gresource prefix="/ui">
|
||||
<file>application.ui</file>
|
||||
<file>menus.ui</file>
|
||||
<file preprocess="xml-stripblanks">application.ui</file>
|
||||
<file preprocess="xml-stripblanks">menus.ui</file>
|
||||
</gresource>
|
||||
</gresources>
|
||||
|
||||
@@ -7,18 +7,8 @@
|
||||
<property name="halign">fill</property>
|
||||
<property name="hexpand">True</property>
|
||||
<child>
|
||||
<object class="GtkMenuToolButton" id="menu">
|
||||
<object class="GtkMenuToolButton" id="menutool">
|
||||
<property name="stock-id">gtk-open</property>
|
||||
<child type="menu">
|
||||
<object class="GtkMenu" id="m">
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="file">
|
||||
<property name="visible">True</property>
|
||||
<property name="label">File1</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@@ -28,8 +18,7 @@
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparatorToolItem" id="sep">
|
||||
</object>
|
||||
<object class="GtkSeparatorToolItem" id="sep"/>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToolButton" id="logo">
|
||||
@@ -106,4 +95,10 @@
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<menu id="toolmenu">
|
||||
<item>
|
||||
<attribute name="label">File1</attribute>
|
||||
<attribute name="action">win.file1</attribute>
|
||||
</item>
|
||||
</menu>
|
||||
</interface>
|
||||
|
||||
@@ -23,14 +23,14 @@ apply_changes_gradually (gpointer data)
|
||||
if (fraction < 1.0)
|
||||
{
|
||||
gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (progress_bar), fraction);
|
||||
return TRUE;
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Close automatically once changes are fully applied. */
|
||||
gtk_widget_destroy (assistant);
|
||||
assistant = NULL;
|
||||
return FALSE;
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -172,7 +172,7 @@ button_press (GtkWidget *widget,
|
||||
GtkWidget *menu;
|
||||
GtkWidget *item;
|
||||
|
||||
if (button->button != 3)
|
||||
if (button->button != GDK_BUTTON_SECONDARY)
|
||||
return FALSE;
|
||||
|
||||
menu = gtk_menu_new ();
|
||||
|
||||
@@ -36,26 +36,17 @@ change_color_callback (GtkWidget *button,
|
||||
{
|
||||
GtkWidget *dialog;
|
||||
GtkColorSelection *colorsel;
|
||||
GtkColorSelectionDialog *selection_dialog;
|
||||
GtkColorChooserDialog *selection_dialog;
|
||||
gint response;
|
||||
|
||||
dialog = gtk_color_selection_dialog_new ("Changing color");
|
||||
|
||||
gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (window));
|
||||
|
||||
selection_dialog = GTK_COLOR_SELECTION_DIALOG (dialog);
|
||||
colorsel = GTK_COLOR_SELECTION (gtk_color_selection_dialog_get_color_selection (selection_dialog));
|
||||
|
||||
gtk_color_selection_set_previous_rgba (colorsel, &color);
|
||||
gtk_color_selection_set_current_rgba (colorsel, &color);
|
||||
gtk_color_selection_set_has_palette (colorsel, TRUE);
|
||||
dialog = gtk_color_chooser_dialog_new ("Changing color", GTK_WINDOW (window));
|
||||
gtk_color_chooser_set_rgba (GTK_COLOR_CHOOSER (dialog), &color);
|
||||
|
||||
response = gtk_dialog_run (GTK_DIALOG (dialog));
|
||||
|
||||
if (response == GTK_RESPONSE_OK)
|
||||
{
|
||||
gtk_color_selection_get_current_rgba (colorsel, &color);
|
||||
|
||||
gtk_color_chooser_get_rgba (GTK_COLOR_CHOOSER (dialog), &color);
|
||||
gtk_widget_override_background_color (da, 0, &color);
|
||||
}
|
||||
|
||||
|
||||
@@ -97,7 +97,7 @@ scribble_button_press_event (GtkWidget *widget,
|
||||
if (surface == NULL)
|
||||
return FALSE; /* paranoia check, in case we haven't gotten a configure event */
|
||||
|
||||
if (event->button == 1)
|
||||
if (event->button == GDK_BUTTON_PRIMARY)
|
||||
draw_brush (widget, event->x, event->y);
|
||||
|
||||
/* We've handled the event, stop processing */
|
||||
|
||||
@@ -144,7 +144,7 @@ event_after (GtkWidget *text_view,
|
||||
|
||||
event = (GdkEventButton *)ev;
|
||||
|
||||
if (event->button != 1)
|
||||
if (event->button != GDK_BUTTON_PRIMARY)
|
||||
return FALSE;
|
||||
|
||||
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_view));
|
||||
|
||||
@@ -60,7 +60,7 @@ spinner_timeout (gpointer data)
|
||||
guint pulse;
|
||||
|
||||
if (model == NULL)
|
||||
return FALSE;
|
||||
return G_SOURCE_REMOVE;
|
||||
|
||||
gtk_tree_model_get_iter_first (model, &iter);
|
||||
gtk_tree_model_get (model, &iter,
|
||||
@@ -77,7 +77,7 @@ spinner_timeout (gpointer data)
|
||||
COLUMN_ACTIVE, TRUE,
|
||||
-1);
|
||||
|
||||
return TRUE;
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
static GtkTreeModel *
|
||||
|
||||
@@ -2,39 +2,106 @@
|
||||
<interface>
|
||||
<menu id="appmenu">
|
||||
<section>
|
||||
<item label="_New" action="app.new" accel="<Primary>n"/>
|
||||
<item label="_Open" action="app.open"/>
|
||||
<item label="_Save" action="app.save" accel="<Primary>s"/>
|
||||
<item label="Save _As..." action="app.save-as" accel="<Primary>s"/>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">_New</attribute>
|
||||
<attribute name="action">app.new</attribute>
|
||||
<attribute name="accel"><Primary>n</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">_Open</attribute>
|
||||
<attribute name="action">app.open</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">_Save</attribute>
|
||||
<attribute name="action">app.save</attribute>
|
||||
<attribute name="accel"><Primary>s</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">Save _As...</attribute>
|
||||
<attribute name="action">app.save-as</attribute>
|
||||
<attribute name="accel"><Primary>s</attribute>
|
||||
</item>
|
||||
</section>
|
||||
<section>
|
||||
<item label="_Quit" action="app.quit" accel="<Primary>q"/>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">_Quit</attribute>
|
||||
<attribute name="action">app.quit</attribute>
|
||||
<attribute name="accel"><Primary>q</attribute>
|
||||
</item>
|
||||
</section>
|
||||
</menu>
|
||||
<menu id="menubar">
|
||||
<submenu label="_Preferences">
|
||||
<submenu>
|
||||
<attribute name="label" translatable="yes">_Preferences</attribute>
|
||||
<section>
|
||||
<item label="_Prefer Dark Theme" action="app.dark"/>
|
||||
<item label="_Hide Titlebar when maximized" action="win.titlebar"/>
|
||||
<submenu label="_Color">
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">_Prefer Dark Theme</attribute>
|
||||
<attribute name="action">app.dark</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">_Hide Titlebar when maximized</attribute>
|
||||
<attribute name="action">win.titlebar</attribute>
|
||||
</item>
|
||||
<submenu>
|
||||
<attribute name="label" translatable="yes">_Color</attribute>
|
||||
<section>
|
||||
<item label="_Red" action="win.color" target="red" accel="<Primary>r"/>
|
||||
<item label="_Green" action="win.color" target="green" accel="<Primary>g"/>
|
||||
<item label="_Blue" action="win.color" target="blue" accel="<Primary>b"/>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">_Red</attribute>
|
||||
<attribute name="action">app.color</attribute>
|
||||
<attribute name="target">red</attribute>
|
||||
<attribute name="accel"><Primary>r</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">_Green</attribute>
|
||||
<attribute name="action">app.color</attribute>
|
||||
<attribute name="target">green</attribute>
|
||||
<attribute name="accel"><Primary>g</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">_Blue</attribute>
|
||||
<attribute name="action">app.color</attribute>
|
||||
<attribute name="target">blue</attribute>
|
||||
<attribute name="accel"><Primary>b</attribute>
|
||||
</item>
|
||||
</section>
|
||||
</submenu>
|
||||
<submenu label="_Shape">
|
||||
<submenu>
|
||||
<attribute name="label" translatable="yes">_Shape</attribute>
|
||||
<section>
|
||||
<item label="_Square" action="win.shape" target="square" accel="<Primary>s"/>
|
||||
<item label="_Rectangle" action="win.shape" target="rectangle" accel="<Primary>r"/>
|
||||
<item label="_Oval" action="win.shape" target="oval" accel="<Primary>o"/>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">_Square</attribute>
|
||||
<attribute name="action">win.shape</attribute>
|
||||
<attribute name="target">square</attribute>
|
||||
<attribute name="accel"><Primary>s</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">_Rectangle</attribute>
|
||||
<attribute name="action">win.shape</attribute>
|
||||
<attribute name="target">rectangle</attribute>
|
||||
<attribute name="accel"><Primary>r</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">_Oval</attribute>
|
||||
<attribute name="action">win.shape</attribute>
|
||||
<attribute name="target">oval</attribute>
|
||||
<attribute name="accel"><Primary>o</attribute>
|
||||
</item>
|
||||
</section>
|
||||
</submenu>
|
||||
<item label="_Bold" action="win.bold" accel="<Primary>b"/>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">_Bold</attribute>
|
||||
<attribute name="action">win.bold</attribute>
|
||||
<attribute name="accel"><Primary>b</attribute>
|
||||
</item>
|
||||
</section>
|
||||
</submenu>
|
||||
<submenu label="_Help">
|
||||
<item label="_About" action="win.about" accel="<Primary>a"/>
|
||||
<submenu>
|
||||
<attribute name="label" translatable="yes">_Help</attribute>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">_About</attribute>
|
||||
<attribute name="action">win.about</attribute>
|
||||
<attribute name="accel"><Primary>a</attribute>
|
||||
</item>
|
||||
</submenu>
|
||||
</menu>
|
||||
</interface>
|
||||
|
||||
698
demos/gtk-demo/multitouch.c
Normal file
698
demos/gtk-demo/multitouch.c
Normal file
@@ -0,0 +1,698 @@
|
||||
/* Multitouch
|
||||
*
|
||||
* Demonstrates some general multitouch event handling,
|
||||
* using GdkTouchCluster in order to get grouped motion
|
||||
* events for the touches within a cluster. Each of the
|
||||
* created rectangles has one of those GdkTouchCluster
|
||||
* objects.
|
||||
*
|
||||
* Touch events are also enabled on additional widgets,
|
||||
* enabling simultaneous touch interaction on those. Not
|
||||
* all widgets are prepared for multitouch interaction,
|
||||
* as there are constraints that not all widgets may
|
||||
* apply to.
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include "demo-common.h"
|
||||
|
||||
#define RECT_BORDER_WIDTH 6
|
||||
|
||||
static GtkWidget *window = NULL;
|
||||
static GtkWidget *area = NULL;
|
||||
static GtkWidget *red = NULL;
|
||||
static GtkWidget *green = NULL;
|
||||
static GtkWidget *blue = NULL;
|
||||
static GtkWidget *alpha = NULL;
|
||||
|
||||
static GQueue *shapes = NULL;
|
||||
|
||||
typedef struct {
|
||||
GdkTouchCluster *cluster;
|
||||
GdkRGBA color;
|
||||
|
||||
gdouble angle;
|
||||
gdouble zoom;
|
||||
|
||||
gdouble center_x;
|
||||
gdouble center_y;
|
||||
|
||||
gdouble x;
|
||||
gdouble y;
|
||||
gdouble width;
|
||||
gdouble height;
|
||||
|
||||
gdouble base_zoom;
|
||||
gdouble base_angle;
|
||||
gdouble initial_distance;
|
||||
gdouble initial_angle;
|
||||
|
||||
GdkPoint points[4];
|
||||
} ShapeInfo;
|
||||
|
||||
static void
|
||||
calculate_rotated_point (gdouble angle,
|
||||
gdouble zoom,
|
||||
gdouble center_x,
|
||||
gdouble center_y,
|
||||
gdouble point_x,
|
||||
gdouble point_y,
|
||||
gdouble *ret_x,
|
||||
gdouble *ret_y)
|
||||
{
|
||||
gdouble distance, xd, yd, ang;
|
||||
|
||||
if (angle == 0)
|
||||
{
|
||||
*ret_x = point_x;
|
||||
*ret_y = point_y;
|
||||
return;
|
||||
}
|
||||
|
||||
xd = center_x - point_x;
|
||||
yd = center_y - point_y;
|
||||
|
||||
if (xd == 0 && yd == 0)
|
||||
{
|
||||
*ret_x = center_x;
|
||||
*ret_y = center_y;
|
||||
return;
|
||||
}
|
||||
|
||||
distance = sqrt ((xd * xd) + (yd * yd));
|
||||
distance *= zoom;
|
||||
|
||||
ang = atan2 (xd, yd);
|
||||
|
||||
/* Invert angle */
|
||||
ang = (2 * G_PI) - ang;
|
||||
|
||||
/* Shift it 270° */
|
||||
ang += 3 * (G_PI / 2);
|
||||
|
||||
/* And constraint it to 0°-360° */
|
||||
ang = fmod (ang, 2 * G_PI);
|
||||
ang += angle;
|
||||
|
||||
*ret_x = center_x + (distance * cos (ang));
|
||||
*ret_y = center_y + (distance * sin (ang));
|
||||
}
|
||||
|
||||
static void
|
||||
shape_info_allocate_input_rect (ShapeInfo *info)
|
||||
{
|
||||
gint width, height, i;
|
||||
|
||||
width = info->width;
|
||||
height = info->height;
|
||||
|
||||
/* Top/left */
|
||||
info->points[0].x = info->x - info->center_x;
|
||||
info->points[0].y = info->y - info->center_y;
|
||||
|
||||
/* Top/right */
|
||||
info->points[1].x = info->x - info->center_x + width;
|
||||
info->points[1].y = info->y - info->center_y;
|
||||
|
||||
/* Bottom/right */
|
||||
info->points[2].x = info->x - info->center_x + width;
|
||||
info->points[2].y = info->y - info->center_y + height;
|
||||
|
||||
/* Bottom/left */
|
||||
info->points[3].x = info->x - info->center_x;
|
||||
info->points[3].y = info->y - info->center_y + height;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
gdouble ret_x, ret_y;
|
||||
|
||||
calculate_rotated_point (info->angle,
|
||||
info->zoom,
|
||||
info->x,
|
||||
info->y,
|
||||
(gdouble) info->points[i].x,
|
||||
(gdouble) info->points[i].y,
|
||||
&ret_x,
|
||||
&ret_y);
|
||||
|
||||
info->points[i].x = (gint) ret_x;
|
||||
info->points[i].y = (gint) ret_y;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
shape_info_bounding_rect (ShapeInfo *info,
|
||||
GdkRectangle *rect)
|
||||
{
|
||||
gint i, left, right, top, bottom;
|
||||
|
||||
left = top = G_MAXINT;
|
||||
right = bottom = 0;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
if (info->points[i].x < left)
|
||||
left = info->points[i].x;
|
||||
|
||||
if (info->points[i].x > right)
|
||||
right = info->points[i].x;
|
||||
|
||||
if (info->points[i].y < top)
|
||||
top = info->points[i].y;
|
||||
|
||||
if (info->points[i].y > bottom)
|
||||
bottom = info->points[i].y;
|
||||
}
|
||||
|
||||
rect->x = left - 20;
|
||||
rect->y = top - 20;
|
||||
rect->width = right - left + 40;
|
||||
rect->height = bottom - top + 40;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
shape_info_point_in (ShapeInfo *info,
|
||||
gint x,
|
||||
gint y)
|
||||
{
|
||||
GdkPoint *left, *right, *top, *bottom;
|
||||
gint i;
|
||||
|
||||
left = right = top = bottom = NULL;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
GdkPoint *p = &info->points[i];
|
||||
|
||||
if (!left ||
|
||||
p->x < left->x ||
|
||||
(p->x == left->x && p->y > left->y))
|
||||
left = p;
|
||||
|
||||
if (!right ||
|
||||
p->x > right->x ||
|
||||
(p->x == right->x && p->y < right->y))
|
||||
right = p;
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
GdkPoint *p = &info->points[i];
|
||||
|
||||
if (p == left || p == right)
|
||||
continue;
|
||||
|
||||
if (!top ||
|
||||
p->y < top->y)
|
||||
top = p;
|
||||
|
||||
if (!bottom ||
|
||||
p->y > bottom->y)
|
||||
bottom = p;
|
||||
}
|
||||
|
||||
g_assert (left && right && top && bottom);
|
||||
|
||||
if (x < left->x ||
|
||||
x > right->x ||
|
||||
y < top->y ||
|
||||
y > bottom->y)
|
||||
return FALSE;
|
||||
|
||||
/* Check whether point is above the sides
|
||||
* between leftmost and topmost, and
|
||||
* topmost and rightmost corners.
|
||||
*/
|
||||
if (x <= top->x)
|
||||
{
|
||||
if (left->y - ((left->y - top->y) * (((gdouble) x - left->x) / (top->x - left->x))) > y)
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (top->y + ((right->y - top->y) * (((gdouble) x - top->x) / (right->x - top->x))) > y)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Check whether point is below the sides
|
||||
* between leftmost and bottom, and
|
||||
* bottom and rightmost corners.
|
||||
*/
|
||||
if (x <= bottom->x)
|
||||
{
|
||||
if (left->y + ((bottom->y - left->y) * (((gdouble) x - left->x) / (bottom->x - left->x))) < y)
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bottom->y - ((bottom->y - right->y) * (((gdouble) x - bottom->x) / (right->x - bottom->x))) < y)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static ShapeInfo *
|
||||
shape_info_new (gdouble x,
|
||||
gdouble y,
|
||||
gdouble width,
|
||||
gdouble height,
|
||||
GdkRGBA *color)
|
||||
{
|
||||
ShapeInfo *info;
|
||||
|
||||
info = g_slice_new0 (ShapeInfo);
|
||||
info->cluster = NULL;
|
||||
info->color = *color;
|
||||
|
||||
info->x = x;
|
||||
info->y = y;
|
||||
info->width = width;
|
||||
info->height = height;
|
||||
|
||||
info->angle = 0;
|
||||
info->zoom = 1;
|
||||
|
||||
info->base_zoom = 1;
|
||||
info->base_angle = 0;
|
||||
info->initial_distance = 0;
|
||||
info->initial_angle = 0;
|
||||
|
||||
shape_info_allocate_input_rect (info);
|
||||
|
||||
g_queue_push_tail (shapes, info);
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
static void
|
||||
shape_info_free (ShapeInfo *info)
|
||||
{
|
||||
g_slice_free (ShapeInfo, info);
|
||||
}
|
||||
|
||||
static void
|
||||
shape_info_draw (cairo_t *cr,
|
||||
ShapeInfo *info)
|
||||
{
|
||||
cairo_save (cr);
|
||||
|
||||
cairo_translate (cr,
|
||||
info->points[0].x + RECT_BORDER_WIDTH / 2,
|
||||
info->points[0].y + RECT_BORDER_WIDTH / 2);
|
||||
|
||||
cairo_scale (cr, info->zoom, info->zoom);
|
||||
cairo_rotate (cr, info->angle);
|
||||
|
||||
cairo_rectangle (cr, 0, 0,
|
||||
info->width - RECT_BORDER_WIDTH,
|
||||
info->height - RECT_BORDER_WIDTH);
|
||||
gdk_cairo_set_source_rgba (cr, &info->color);
|
||||
cairo_fill_preserve (cr);
|
||||
|
||||
cairo_set_line_width (cr, RECT_BORDER_WIDTH);
|
||||
cairo_set_source_rgb (cr, 0, 0, 0);
|
||||
cairo_stroke (cr);
|
||||
|
||||
cairo_restore (cr);
|
||||
}
|
||||
|
||||
static void
|
||||
shape_update_scales (ShapeInfo *info)
|
||||
{
|
||||
gtk_range_set_value (GTK_RANGE (red), info->color.red);
|
||||
gtk_range_set_value (GTK_RANGE (green), info->color.green);
|
||||
gtk_range_set_value (GTK_RANGE (blue), info->color.blue);
|
||||
gtk_range_set_value (GTK_RANGE (alpha), info->color.alpha);
|
||||
}
|
||||
|
||||
static void
|
||||
range_value_changed_cb (GtkRange *range,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
GdkRectangle rect;
|
||||
ShapeInfo *shape;
|
||||
gdouble value;
|
||||
|
||||
widget = GTK_WIDGET (range);
|
||||
shape = g_queue_peek_head (shapes);
|
||||
|
||||
if (!shape)
|
||||
return;
|
||||
|
||||
value = gtk_range_get_value (range);
|
||||
|
||||
if (widget == red)
|
||||
shape->color.red = value;
|
||||
else if (widget == green)
|
||||
shape->color.green = value;
|
||||
else if (widget == blue)
|
||||
shape->color.blue = value;
|
||||
else if (widget == alpha)
|
||||
shape->color.alpha = value;
|
||||
|
||||
shape_info_bounding_rect (shape, &rect);
|
||||
gdk_window_invalidate_rect (gtk_widget_get_window (area),
|
||||
&rect, FALSE);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
draw_cb (GtkWidget *widget,
|
||||
cairo_t *cr,
|
||||
gpointer user_data)
|
||||
{
|
||||
GList *l;
|
||||
|
||||
cairo_save (cr);
|
||||
|
||||
cairo_set_source_rgb (cr, 1, 1, 1);
|
||||
cairo_paint (cr);
|
||||
|
||||
for (l = shapes->tail; l; l = l->prev)
|
||||
shape_info_draw (cr, l->data);
|
||||
|
||||
cairo_restore (cr);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
button_press_cb (GtkWidget *widget,
|
||||
GdkEvent *event,
|
||||
gpointer user_data)
|
||||
{
|
||||
ShapeInfo *shape = NULL;
|
||||
guint touch_id;
|
||||
|
||||
if (gdk_event_get_touch_id (event, &touch_id))
|
||||
{
|
||||
GList *l;
|
||||
|
||||
for (l = shapes->tail; l; l = l->prev)
|
||||
{
|
||||
ShapeInfo *info = l->data;
|
||||
|
||||
if (shape_info_point_in (info,
|
||||
(gint) event->button.x,
|
||||
(gint) event->button.y))
|
||||
shape = info;
|
||||
}
|
||||
|
||||
if (!shape)
|
||||
return FALSE;
|
||||
|
||||
/* Put on top */
|
||||
g_queue_remove (shapes, shape);
|
||||
g_queue_push_head (shapes, shape);
|
||||
|
||||
shape_update_scales (shape);
|
||||
|
||||
if (!shape->cluster)
|
||||
shape->cluster = gdk_window_create_touch_cluster (gtk_widget_get_window (widget),
|
||||
gdk_event_get_device (event));
|
||||
else if (gdk_touch_cluster_get_n_touches (shape->cluster) == 0)
|
||||
{
|
||||
/* Only change cluster device if there were no touches */
|
||||
gdk_touch_cluster_set_device (shape->cluster,
|
||||
gdk_event_get_device (event));
|
||||
}
|
||||
|
||||
gdk_touch_cluster_add_touch (shape->cluster, touch_id);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
multitouch_cb (GtkWidget *widget,
|
||||
GdkEvent *event,
|
||||
gpointer user_data)
|
||||
{
|
||||
ShapeInfo *info = NULL;
|
||||
gboolean new_center = FALSE;
|
||||
gboolean new_position = FALSE;
|
||||
gdouble event_x, event_y;
|
||||
cairo_region_t *region;
|
||||
GdkRectangle rect;
|
||||
GList *l;
|
||||
|
||||
for (l = shapes->head; l; l = l->next)
|
||||
{
|
||||
ShapeInfo *shape = l->data;
|
||||
|
||||
if (event->multitouch.group == shape->cluster)
|
||||
{
|
||||
info = shape;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!info)
|
||||
return FALSE;
|
||||
|
||||
shape_info_bounding_rect (info, &rect);
|
||||
region = cairo_region_create_rectangle ((cairo_rectangle_int_t *) &rect);
|
||||
|
||||
if (event->multitouch.n_events == 1)
|
||||
{
|
||||
/* Update center if we just got to
|
||||
* this situation from either way */
|
||||
if (event->type == GDK_MULTITOUCH_ADDED ||
|
||||
event->type == GDK_MULTITOUCH_REMOVED)
|
||||
new_center = TRUE;
|
||||
|
||||
event_x = event->multitouch.events[0]->x;
|
||||
event_y = event->multitouch.events[0]->y;
|
||||
new_position = TRUE;
|
||||
}
|
||||
else if (event->multitouch.n_events == 2)
|
||||
{
|
||||
gdouble distance, angle;
|
||||
|
||||
gdk_events_get_center ((GdkEvent *) event->multitouch.events[0],
|
||||
(GdkEvent *) event->multitouch.events[1],
|
||||
&event_x, &event_y);
|
||||
|
||||
gdk_events_get_distance ((GdkEvent *) event->multitouch.events[0],
|
||||
(GdkEvent *) event->multitouch.events[1],
|
||||
&distance);
|
||||
|
||||
gdk_events_get_angle ((GdkEvent *) event->multitouch.events[0],
|
||||
(GdkEvent *) event->multitouch.events[1],
|
||||
&angle);
|
||||
|
||||
if (event->type == GDK_MULTITOUCH_ADDED)
|
||||
{
|
||||
/* Second touch was just added, update base zoom/angle */
|
||||
info->base_zoom = info->zoom;
|
||||
info->base_angle = info->angle;
|
||||
info->initial_angle = angle;
|
||||
info->initial_distance = distance;
|
||||
new_center = TRUE;
|
||||
}
|
||||
|
||||
info->zoom = MAX (info->base_zoom * (distance / info->initial_distance), 1.0);
|
||||
info->angle = info->base_angle + (angle - info->initial_angle);
|
||||
new_position = TRUE;
|
||||
}
|
||||
|
||||
if (new_center)
|
||||
{
|
||||
gdouble origin_x, origin_y;
|
||||
|
||||
origin_x = info->x - info->center_x;
|
||||
origin_y = info->y - info->center_y;
|
||||
|
||||
calculate_rotated_point (- info->angle,
|
||||
1 / info->zoom,
|
||||
info->x - origin_x,
|
||||
info->y - origin_y,
|
||||
event_x - origin_x,
|
||||
event_y - origin_y,
|
||||
&info->center_x,
|
||||
&info->center_y);
|
||||
}
|
||||
|
||||
if (new_position)
|
||||
{
|
||||
info->x = event_x;
|
||||
info->y = event_y;
|
||||
}
|
||||
|
||||
shape_info_allocate_input_rect (info);
|
||||
|
||||
shape_info_bounding_rect (info, &rect);
|
||||
cairo_region_union_rectangle (region, (cairo_rectangle_int_t *) &rect);
|
||||
gdk_window_invalidate_region (gtk_widget_get_window (widget), region, FALSE);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
window_destroyed_cb (GtkWidget *widget,
|
||||
gpointer user_data)
|
||||
{
|
||||
g_queue_foreach (shapes, (GFunc) shape_info_free, NULL);
|
||||
g_queue_free (shapes);
|
||||
|
||||
shapes = NULL;
|
||||
window = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
new_rectangle_clicked_cb (GtkButton *button,
|
||||
gpointer user_data)
|
||||
{
|
||||
GdkRectangle rect;
|
||||
ShapeInfo *info;
|
||||
GdkRGBA color;
|
||||
|
||||
color.red = color.green = color.blue = color.alpha = 0.5;
|
||||
info = shape_info_new (0, 0, 100, 150, &color);
|
||||
|
||||
shape_info_bounding_rect (info, &rect);
|
||||
gdk_window_invalidate_rect (gtk_widget_get_window (area), &rect, FALSE);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
create_drawing_area (void)
|
||||
{
|
||||
area = gtk_drawing_area_new ();
|
||||
|
||||
gtk_widget_add_events (area,
|
||||
GDK_TOUCH_MASK |
|
||||
GDK_POINTER_MOTION_MASK |
|
||||
GDK_BUTTON_PRESS_MASK |
|
||||
GDK_BUTTON_RELEASE_MASK);
|
||||
|
||||
gtk_widget_set_size_request (area, 600, 600);
|
||||
|
||||
g_signal_connect (area, "draw",
|
||||
G_CALLBACK (draw_cb), NULL);
|
||||
g_signal_connect (area, "button-press-event",
|
||||
G_CALLBACK (button_press_cb), NULL);
|
||||
g_signal_connect (area, "multitouch-event",
|
||||
G_CALLBACK (multitouch_cb), NULL);
|
||||
|
||||
return area;
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
create_scale (void)
|
||||
{
|
||||
GtkWidget *scale;
|
||||
|
||||
scale = gtk_scale_new_with_range (GTK_ORIENTATION_VERTICAL, 0, 1, 0.01);
|
||||
gtk_range_set_inverted (GTK_RANGE (scale), TRUE);
|
||||
|
||||
gtk_widget_set_vexpand (scale, TRUE);
|
||||
gtk_widget_set_margin_left (scale, 15);
|
||||
gtk_widget_set_margin_right (scale, 15);
|
||||
|
||||
gtk_widget_add_events (scale, GDK_TOUCH_MASK);
|
||||
|
||||
g_signal_connect (scale, "value-changed",
|
||||
G_CALLBACK (range_value_changed_cb), NULL);
|
||||
return scale;
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
create_window (void)
|
||||
{
|
||||
GtkWidget *grid, *label, *button;
|
||||
|
||||
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Multitouch demo");
|
||||
g_signal_connect (window, "destroy",
|
||||
G_CALLBACK (window_destroyed_cb), NULL);
|
||||
|
||||
grid = gtk_grid_new ();
|
||||
gtk_container_add (GTK_CONTAINER (window), grid);
|
||||
|
||||
area = create_drawing_area ();
|
||||
gtk_grid_attach (GTK_GRID (grid),
|
||||
area, 0, 0, 1, 3);
|
||||
gtk_widget_set_hexpand (area, TRUE);
|
||||
gtk_widget_set_vexpand (area, TRUE);
|
||||
|
||||
/* "red" label/scale */
|
||||
label = gtk_label_new ("Red");
|
||||
gtk_widget_set_vexpand (label, FALSE);
|
||||
gtk_grid_attach (GTK_GRID (grid),
|
||||
label, 1, 0, 1, 1);
|
||||
|
||||
red = create_scale ();
|
||||
gtk_grid_attach (GTK_GRID (grid),
|
||||
red, 1, 1, 1, 1);
|
||||
|
||||
/* "green" label/scale */
|
||||
label = gtk_label_new ("Green");
|
||||
gtk_widget_set_vexpand (label, FALSE);
|
||||
gtk_grid_attach (GTK_GRID (grid),
|
||||
label, 2, 0, 1, 1);
|
||||
|
||||
green = create_scale ();
|
||||
gtk_grid_attach (GTK_GRID (grid),
|
||||
green, 2, 1, 1, 1);
|
||||
|
||||
/* "blue" label/scale */
|
||||
label = gtk_label_new ("Blue");
|
||||
gtk_widget_set_vexpand (label, FALSE);
|
||||
gtk_grid_attach (GTK_GRID (grid),
|
||||
label, 3, 0, 1, 1);
|
||||
|
||||
blue = create_scale ();
|
||||
gtk_grid_attach (GTK_GRID (grid),
|
||||
blue, 3, 1, 1, 1);
|
||||
|
||||
/* "alpha" label/scale */
|
||||
label = gtk_label_new ("Alpha");
|
||||
gtk_widget_set_vexpand (label, FALSE);
|
||||
gtk_grid_attach (GTK_GRID (grid),
|
||||
label, 4, 0, 1, 1);
|
||||
|
||||
alpha = create_scale ();
|
||||
gtk_grid_attach (GTK_GRID (grid),
|
||||
alpha, 4, 1, 1, 1);
|
||||
|
||||
/* button */
|
||||
button = gtk_button_new_from_stock (GTK_STOCK_NEW);
|
||||
gtk_widget_add_events (button, GDK_TOUCH_MASK);
|
||||
gtk_grid_attach (GTK_GRID (grid),
|
||||
button, 1, 2, 4, 1);
|
||||
gtk_widget_set_vexpand (button, FALSE);
|
||||
|
||||
g_signal_connect (button, "clicked",
|
||||
G_CALLBACK (new_rectangle_clicked_cb), NULL);
|
||||
|
||||
gtk_widget_show_all (grid);
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
do_multitouch (GtkWidget *do_widget)
|
||||
{
|
||||
if (!shapes)
|
||||
shapes = g_queue_new ();
|
||||
|
||||
if (!window)
|
||||
window = create_window ();
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
gtk_widget_show (window);
|
||||
else
|
||||
{
|
||||
gtk_widget_destroy (window);
|
||||
window = NULL;
|
||||
|
||||
g_queue_foreach (shapes, (GFunc) shape_info_free, NULL);
|
||||
g_queue_free (shapes);
|
||||
shapes = NULL;
|
||||
}
|
||||
|
||||
return window;
|
||||
}
|
||||
17
demos/gtk-demo/org.gtk.Demo.gschema.xml
Normal file
17
demos/gtk-demo/org.gtk.Demo.gschema.xml
Normal file
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<schemalist>
|
||||
|
||||
<enum id='org.gtk.Demo.Color'>
|
||||
<value nick='red' value='0'/>
|
||||
<value nick='green' value='1'/>
|
||||
<value nick='blue' value='2'/>
|
||||
</enum>
|
||||
|
||||
<schema id='org.gtk.Demo' path='/org/gtk/Demo/'>
|
||||
<key name='color' enum='org.gtk.Demo.Color'>
|
||||
<default>'red'</default>
|
||||
</key>
|
||||
</schema>
|
||||
|
||||
</schemalist>
|
||||
@@ -180,7 +180,7 @@ timeout (gpointer data)
|
||||
GDK_THREADS_LEAVE ();
|
||||
|
||||
frame_num++;
|
||||
return TRUE;
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
static guint timeout_id;
|
||||
|
||||
@@ -29,8 +29,7 @@ static gboolean
|
||||
search_progress (gpointer data)
|
||||
{
|
||||
gtk_entry_progress_pulse (GTK_ENTRY (data));
|
||||
|
||||
return TRUE;
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -49,7 +49,7 @@ scroll_to_end (GtkTextView *textview)
|
||||
if (count > 150)
|
||||
count = 0;
|
||||
|
||||
return TRUE;
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
/* Scroll to the bottom of the buffer.
|
||||
@@ -100,7 +100,7 @@ scroll_to_bottom (GtkTextView *textview)
|
||||
if (count > 40)
|
||||
count = 0;
|
||||
|
||||
return TRUE;
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
static guint
|
||||
|
||||
@@ -350,7 +350,7 @@ interactive_canvas_real_drag_leave (gpointer data)
|
||||
gtk_widget_queue_draw (widget);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
31
demos/widget-factory/Makefile.am
Normal file
31
demos/widget-factory/Makefile.am
Normal file
@@ -0,0 +1,31 @@
|
||||
include $(top_srcdir)/Makefile.decl
|
||||
|
||||
bin_PROGRAMS = gtk3-widget-factory
|
||||
|
||||
gtk3_widget_factory_SOURCES = \
|
||||
widget-factory.c \
|
||||
widget_factory_resources.c
|
||||
|
||||
BUILT_SOURCES = \
|
||||
widget_factory_resources.c
|
||||
|
||||
gtk3_widget_factory_DEPENDENCIES = \
|
||||
$(top_builddir)/gtk/libgtk-3.la
|
||||
|
||||
gtk3_widget_factory_CPPFLAGS = \
|
||||
-I$(top_srcdir) \
|
||||
$(GTK_DEBUG_FLAGS) \
|
||||
$(GTK_DEP_CFLAGS)
|
||||
|
||||
gtk3_widget_factory_LDADD = \
|
||||
$(top_builddir)/gdk/libgdk-3.la \
|
||||
$(top_builddir)/gtk/libgtk-3.la \
|
||||
$(GTK_DEP_LIBS)
|
||||
|
||||
widget_factory_resources.c: widget-factory.gresource.xml $(shell $(GLIB_COMPILE_RESOURCES) --generate-dependencies $(srcdir)/widget-factory.gresource.xml)
|
||||
$(AM_V_GEN) $(GLIB_COMPILE_RESOURCES) --target=$@ --sourcedir=$(srcdir) --generate-source $<
|
||||
|
||||
EXTRA_DIST += \
|
||||
widget-factory.ui \
|
||||
widget-factory.gresource.xml \
|
||||
gtk-logo-256.png
|
||||
BIN
demos/widget-factory/gtk-logo-256.png
Normal file
BIN
demos/widget-factory/gtk-logo-256.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 10 KiB |
@@ -22,6 +22,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
static void
|
||||
@@ -35,6 +36,37 @@ dark_toggled (GtkCheckMenuItem *item, gpointer data)
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
show_about (GtkMenuItem *item, GtkWidget *window)
|
||||
{
|
||||
GdkPixbuf *pixbuf;
|
||||
const gchar *authors[] = {
|
||||
"Andrea Cimitan",
|
||||
"Cosimo Cecchi",
|
||||
NULL
|
||||
};
|
||||
|
||||
pixbuf = gdk_pixbuf_new_from_resource ("/logos/gtk-logo-256.png", NULL);
|
||||
|
||||
gtk_show_about_dialog (GTK_WINDOW (window),
|
||||
"program-name", "GTK+ Widget Factory",
|
||||
"version", g_strdup_printf ("%s,\nRunning against GTK+ %d.%d.%d",
|
||||
PACKAGE_VERSION,
|
||||
gtk_get_major_version (),
|
||||
gtk_get_minor_version (),
|
||||
gtk_get_micro_version ()),
|
||||
"copyright", "(C) 1997-2009 The GTK+ Team",
|
||||
"license-type", GTK_LICENSE_LGPL_2_1,
|
||||
"website", "http://www.gtk.org",
|
||||
"comments", "Program to demonstrate GTK+ themes and widgets",
|
||||
"authors", authors,
|
||||
"logo", pixbuf,
|
||||
"title", "About GTK+ Widget Factory",
|
||||
NULL);
|
||||
|
||||
g_object_unref (pixbuf);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
@@ -49,7 +81,7 @@ main (int argc, char *argv[])
|
||||
dark = TRUE;
|
||||
|
||||
builder = gtk_builder_new ();
|
||||
gtk_builder_add_from_file (builder, "./widget-factory.ui", NULL);
|
||||
gtk_builder_add_from_resource (builder, "/ui/widget-factory.ui", NULL);
|
||||
|
||||
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
|
||||
gtk_builder_connect_signals (builder, NULL);
|
||||
@@ -58,6 +90,9 @@ main (int argc, char *argv[])
|
||||
g_signal_connect (widget, "toggled", G_CALLBACK (dark_toggled), NULL);
|
||||
gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (widget), dark);
|
||||
|
||||
widget = (GtkWidget*) gtk_builder_get_object (builder, "aboutmenuitem");
|
||||
g_signal_connect (widget, "activate", G_CALLBACK (show_about), window);
|
||||
|
||||
g_object_unref (G_OBJECT (builder));
|
||||
|
||||
gtk_widget_show (window);
|
||||
9
demos/widget-factory/widget-factory.gresource.xml
Normal file
9
demos/widget-factory/widget-factory.gresource.xml
Normal file
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<gresources>
|
||||
<gresource prefix="/logos">
|
||||
<file>gtk-logo-256.png</file>
|
||||
</gresource>
|
||||
<gresource prefix="/ui">
|
||||
<file preprocess="xml-stripblanks">widget-factory.ui</file>
|
||||
</gresource>
|
||||
</gresources>
|
||||
@@ -54,6 +54,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus. </property>
|
||||
<object class="GtkAccelGroup" id="accelgroup1"/>
|
||||
<object class="GtkWindow" id="window">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="title">GTK+ Widget Factory</property>
|
||||
<signal name="destroy" handler="gtk_main_quit" swapped="no"/>
|
||||
<signal name="delete-event" handler="gtk_false" swapped="no"/>
|
||||
<child>
|
||||
@@ -390,7 +391,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus. </property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="imagemenuitem10">
|
||||
<object class="GtkImageMenuItem" id="aboutmenuitem">
|
||||
<property name="label">gtk-about</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
@@ -33,6 +33,7 @@
|
||||
<xi:include href="xml/windows.xml" />
|
||||
<xi:include href="xml/events.xml" />
|
||||
<xi:include href="xml/event_structs.xml" />
|
||||
<xi:include href="xml/touchcluster.xml" />
|
||||
<xi:include href="xml/keys.xml" />
|
||||
<xi:include href="xml/selections.xml" />
|
||||
<xi:include href="xml/dnd.xml" />
|
||||
|
||||
@@ -759,6 +759,9 @@ GDK_PRIORITY_EVENTS
|
||||
GDK_PRIORITY_REDRAW
|
||||
GDK_EVENT_PROPAGATE
|
||||
GDK_EVENT_STOP
|
||||
GDK_BUTTON_PRIMARY
|
||||
GDK_BUTTON_MIDDLE
|
||||
GDK_BUTTON_SECONDARY
|
||||
|
||||
<SUBSECTION>
|
||||
gdk_events_pending
|
||||
@@ -778,11 +781,13 @@ gdk_event_get_root_coords
|
||||
gdk_event_get_scroll_direction
|
||||
gdk_event_get_state
|
||||
gdk_event_get_time
|
||||
gdk_event_get_touch_id
|
||||
gdk_event_request_motions
|
||||
gdk_events_get_angle
|
||||
gdk_events_get_center
|
||||
gdk_events_get_distance
|
||||
gdk_event_triggers_context_menu
|
||||
gdk_event_get_touch_id
|
||||
|
||||
<SUBSECTION>
|
||||
gdk_event_handler_set
|
||||
@@ -830,6 +835,7 @@ GdkEventWindowState
|
||||
GdkEventSetting
|
||||
GdkEventOwnerChange
|
||||
GdkEventGrabBroken
|
||||
GdkEventMultiTouch
|
||||
|
||||
<SUBSECTION>
|
||||
GdkScrollDirection
|
||||
@@ -857,6 +863,29 @@ gdk_event_get_type
|
||||
gdk_owner_change_get_type
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<TITLE>Multitouch</TITLE>
|
||||
<FILE>touchcluster</FILE>
|
||||
GdkTouchCluster
|
||||
gdk_touch_cluster_add_touch
|
||||
gdk_touch_cluster_remove_touch
|
||||
gdk_touch_cluster_remove_all
|
||||
gdk_touch_cluster_set_device
|
||||
gdk_touch_cluster_get_device
|
||||
gdk_touch_cluster_get_touches
|
||||
|
||||
<SUBSECTION>
|
||||
gdk_window_create_touch_cluster
|
||||
gdk_window_remove_touch_cluster
|
||||
|
||||
<SUBSECTION Standard>
|
||||
GDK_TYPE_TOUCH_CLUSTER
|
||||
|
||||
<SUBSECTION Private>
|
||||
gdk_touch_cluster_get_type
|
||||
</SECTION>
|
||||
|
||||
|
||||
<SECTION>
|
||||
<TITLE>Cursors</TITLE>
|
||||
<FILE>cursors</FILE>
|
||||
|
||||
@@ -9,5 +9,6 @@ gdk_display_manager_get_type
|
||||
gdk_drag_context_get_type
|
||||
gdk_keymap_get_type
|
||||
gdk_screen_get_type
|
||||
gdk_touch_cluster_get_type
|
||||
gdk_visual_get_type
|
||||
gdk_window_get_type
|
||||
|
||||
@@ -119,6 +119,7 @@ content_files = \
|
||||
running.sgml \
|
||||
building.sgml \
|
||||
compiling.sgml \
|
||||
device-interaction-patterns.xml \
|
||||
drawing-model.xml \
|
||||
glossary.xml \
|
||||
migrating-2to3.xml \
|
||||
@@ -142,6 +143,7 @@ content_files = \
|
||||
overview.xml
|
||||
|
||||
expand_content_files = \
|
||||
device-interaction-patterns.xml \
|
||||
drawing-model.xml \
|
||||
getting_started.xml \
|
||||
glossary.xml \
|
||||
@@ -287,6 +289,7 @@ HTML_IMAGES = \
|
||||
$(srcdir)/images/check-button.png \
|
||||
$(srcdir)/images/color-button.png \
|
||||
$(srcdir)/images/colorsel.png \
|
||||
$(srcdir)/images/colorchooser.png \
|
||||
$(srcdir)/images/combo-box.png \
|
||||
$(srcdir)/images/combo-box-entry.png \
|
||||
$(srcdir)/images/entry.png \
|
||||
@@ -296,6 +299,7 @@ HTML_IMAGES = \
|
||||
$(srcdir)/images/filechooser.png \
|
||||
$(srcdir)/images/font-button.png \
|
||||
$(srcdir)/images/fontsel.png \
|
||||
$(srcdir)/images/fontchooser.png \
|
||||
$(srcdir)/images/frame.png \
|
||||
$(srcdir)/images/icon-view.png \
|
||||
$(srcdir)/images/image.png \
|
||||
|
||||
578
docs/reference/gtk/device-interaction-patterns.xml
Normal file
578
docs/reference/gtk/device-interaction-patterns.xml
Normal file
@@ -0,0 +1,578 @@
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
|
||||
]>
|
||||
<chapter id="gtk-device-interaction-patterns">
|
||||
<title>Multitouch and other device interaction patterns</title>
|
||||
|
||||
<para>
|
||||
Depending on the platform, GTK+ is able to handle a wide range of input
|
||||
devices. Those are offered to applications in a 2-level hierarchy, with
|
||||
virtual devices (or master devices) representing the visual cursors
|
||||
displayed in the screen, which are each controlled by a number of physical
|
||||
devices (or slave devices). Those devices can respectively be retrieved
|
||||
from an input event with gdk_event_get_device() and
|
||||
gdk_event_get_source_device().
|
||||
</para>
|
||||
|
||||
<para>
|
||||
In X11, GTK+ uses XInput2 for input events, which caters for a fully dynamic
|
||||
device hierarchy, and support for multiple virtual pointer/keyboard pairs.
|
||||
</para>
|
||||
|
||||
<example>
|
||||
<title>Listing and modifying the device hierarchy</title>
|
||||
<programlisting>
|
||||
carlos@sacarino:~$ xinput list
|
||||
⎡ Virtual core pointer id=2 [master pointer (3)]
|
||||
⎜ ↳ Virtual core XTEST pointer id=4 [slave pointer (2)]
|
||||
⎜ ↳ Wacom ISDv4 E6 Pen stylus id=10 [slave pointer (2)]
|
||||
⎜ ↳ Wacom ISDv4 E6 Finger touch id=11 [slave pointer (2)]
|
||||
⎜ ↳ SynPS/2 Synaptics TouchPad id=13 [slave pointer (2)]
|
||||
⎜ ↳ TPPS/2 IBM TrackPoint id=14 [slave pointer (2)]
|
||||
⎜ ↳ Wacom ISDv4 E6 Pen eraser id=16 [slave pointer (2)]
|
||||
⎣ Virtual core keyboard id=3 [master keyboard (2)]
|
||||
↳ Virtual core XTEST keyboard id=5 [slave keyboard (3)]
|
||||
↳ Power Button id=6 [slave keyboard (3)]
|
||||
↳ Video Bus id=7 [slave keyboard (3)]
|
||||
↳ Sleep Button id=8 [slave keyboard (3)]
|
||||
↳ Integrated Camera id=9 [slave keyboard (3)]
|
||||
↳ AT Translated Set 2 keyboard id=12 [slave keyboard (3)]
|
||||
↳ ThinkPad Extra Buttons id=15 [slave keyboard (3)]
|
||||
|
||||
carlos@sacarino:~$ xinput create-master eek
|
||||
carlos@sacarino:~$ xinput list
|
||||
...
|
||||
⎡ eek pointer id=17 [master pointer (18)]
|
||||
⎜ ↳ eek XTEST pointer id=19 [slave pointer (17)]
|
||||
⎣ eek keyboard id=18 [master keyboard (17)]
|
||||
↳ eek XTEST keyboard id=20 [slave keyboard (18)]
|
||||
|
||||
carlos@sacarino:~$ xinput reattach 10 17
|
||||
carlos@sacarino:~$ xinput list
|
||||
...
|
||||
⎡ eek pointer id=17 [master pointer (18)]
|
||||
⎜ ↳ Wacom ISDv4 E6 Pen stylus id=10 [slave pointer (17)]
|
||||
⎜ ↳ eek XTEST pointer id=19 [slave pointer (17)]
|
||||
⎣ eek keyboard id=18 [master keyboard (17)]
|
||||
↳ eek XTEST keyboard id=20 [slave keyboard (18)]
|
||||
</programlisting>
|
||||
</example>
|
||||
|
||||
<para>
|
||||
Anytime a virtual device is added or removed, or a physical device
|
||||
is attached to another virtual device, or left floating (detached
|
||||
from any virtual device), #GdkDeviceManager will emit the corresponding
|
||||
#GdkDeviceManager::device-added, #GdkDeviceManager::device-removed, or
|
||||
#GdkDeviceManager::device-changed signals.
|
||||
</para>
|
||||
|
||||
<section id="gtk-device-patterns-client-pointer">
|
||||
<title>The client pointer</title>
|
||||
|
||||
<para>
|
||||
In X11, Under the presence of multiple virtual pointers, GDK and XInput2
|
||||
use the "client pointer" principle to allow several legacy applications
|
||||
to interact simultaneously with different virtual pointer/keyboard pairs,
|
||||
it would be usually set by the window manager for a focused window, so
|
||||
different application windows could operate on different client pointers.
|
||||
gdk_device_manager_get_client_pointer() may be called to get the client
|
||||
pointer #GdkDevice
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Under the hood, X11 uses the client pointer (or its paired keyboard) to
|
||||
satisfy core calls such as XGrabPointer/Keyboard, XQueryPointer and
|
||||
others that have been superseded by XInput2.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
In platforms without multidevice features, gdk_device_manager_get_client_pointer()
|
||||
will return the only virtual pointer available.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id="gtk-device-patterns-simple">
|
||||
<title>Simple device handling</title>
|
||||
|
||||
<para>
|
||||
There are applications that could have little gain in knowing about
|
||||
multiple devices, although there are situations where a device could
|
||||
be needed (i.e. popping up a menu on the pointer coordinates).
|
||||
</para>
|
||||
|
||||
<para>
|
||||
For such applications, the client pointer may be a good enough
|
||||
approximation for these operations. Under the presence of multiple
|
||||
device pairs, this gives a behavior that is most similar to that
|
||||
of legacy applications (i.e. gtk+2).
|
||||
</para>
|
||||
|
||||
<example>
|
||||
<title>Getting the client pointer and keyboard</title>
|
||||
<programlisting>
|
||||
GdkDisplay *display;
|
||||
GdkDeviceManager *device_manager;
|
||||
GdkDevice *client_pointer, client_keyboard;
|
||||
|
||||
display = gdk_display_get_default ();
|
||||
device_manager = gdk_display_get_device_manager (display);
|
||||
client_pointer = gdk_device_manager_get_client_pointer (device_manager);
|
||||
|
||||
/* Or if we need a keyboard too */
|
||||
client_keyboard = gdk_device_get_associated_device (client_pointer);
|
||||
</programlisting>
|
||||
</example>
|
||||
</section>
|
||||
|
||||
<section id="gtk-device-patterns-multiple-devices">
|
||||
<title>Dealing with multiple devices</title>
|
||||
|
||||
<para>
|
||||
There may be several usecases to deal with multiple devices, including,
|
||||
but not limited to:
|
||||
</para>
|
||||
|
||||
<orderedlist>
|
||||
<listitem>
|
||||
Retrieving advanced information from an input device: i.e. stylus pressure/tilt
|
||||
in drawing applications.
|
||||
</listitem>
|
||||
<listitem>
|
||||
Receiving events from a dedicated input device: i.e. joysticks in games.
|
||||
</listitem>
|
||||
<listitem>
|
||||
Collaborative interfaces, handling simultaneous input from multiple users.
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
|
||||
<para>
|
||||
However, the patterns to make them work are very similar.
|
||||
</para>
|
||||
|
||||
<section>
|
||||
<title>Event handling</title>
|
||||
|
||||
<para>
|
||||
Each device will emit its own event stream, this means
|
||||
that you will need to check the GdkEvent you get in
|
||||
your event handlers
|
||||
</para>
|
||||
|
||||
<example>
|
||||
<title>Reacting differently to devices</title>
|
||||
<programlisting>
|
||||
static gboolean
|
||||
my_widget_motion_notify (GtkWidget *widget,
|
||||
GdkEventMotion *event)
|
||||
{
|
||||
GdkDevice *device, *source_device;
|
||||
|
||||
device = gdk_event_get_device ((GdkEvent *) event);
|
||||
source_device = gdk_event_get_source_device ((GdkEvent *) event);
|
||||
|
||||
g_print ("Motion event by '%s', coming from HW device '%s'\n",
|
||||
gdk_device_get_name (device),
|
||||
gdk_device_get_name (source_device));
|
||||
|
||||
/* Handle touch devices differently */
|
||||
if (gdk_device_get_source (source_device) == GDK_SOURCE_TOUCH)
|
||||
{
|
||||
...
|
||||
}
|
||||
else
|
||||
{
|
||||
...
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
</programlisting>
|
||||
</example>
|
||||
|
||||
<para>
|
||||
The mechanism above could also be used for fine grained event discarding
|
||||
(i.e. so rubberband selection doesn't jump to another pointer entering
|
||||
the widget for example)
|
||||
</para>
|
||||
|
||||
<example>
|
||||
<title>Reacting differently to devices</title>
|
||||
<programlisting>
|
||||
static gboolean
|
||||
my_widget_button_press (Gtkwidget *widget,
|
||||
GdkEventButton *event)
|
||||
{
|
||||
GET_PRIV(widget)->current_pointer = gdk_event_get_device ((GdkEvent *) event);
|
||||
...
|
||||
}
|
||||
|
||||
static gboolean
|
||||
my_widget_button_release (Gtkwidget *widget,
|
||||
GdkEventButton *event)
|
||||
{
|
||||
GET_PRIV(widget)->current_pointer = NULL;
|
||||
...
|
||||
}
|
||||
|
||||
static gboolean
|
||||
my_widget_motion_notify (Gtkwidget *widget,
|
||||
GdkEventMotion *event)
|
||||
{
|
||||
if (gdk_event_get_device (event) !=
|
||||
GET_PRIV(widget)->current_pointer)
|
||||
return FALSE;
|
||||
|
||||
...
|
||||
}
|
||||
</programlisting>
|
||||
</example>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Grabs</title>
|
||||
|
||||
<para>
|
||||
Grabs are a mechanism to coerce a device into sending events to
|
||||
a window, but with multidevice there's an other side of the coin,
|
||||
how other devices are supposed to interact while the grab is in
|
||||
effect.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The GdkGrabOwnership enum passed to gdk_device_grab() may be used
|
||||
to block other devices' interaction. %GDK_OWNERSHIP_NONE applies
|
||||
no restrictions, allowing other devices to interact, even with
|
||||
the grab window. %GDK_OWNERSHIP_WINDOW blocks other devices from
|
||||
interacting with the grab window, but they'll still be able to
|
||||
interact with the rest of the application, whereas
|
||||
%GDK_OWNERSHIP_APPLICATION will render the whole application
|
||||
insensitive to input from other devices. Different devices may
|
||||
have simultaneous grabs on the same or different windows.
|
||||
</para>
|
||||
|
||||
<example>
|
||||
<title>Grabbing as a result of an input event</title>
|
||||
<programlisting>
|
||||
gboolean
|
||||
my_widget_button_press (GtkWidget *widget,
|
||||
GdkEventButton *event)
|
||||
{
|
||||
GdkDevice *pointer, *keyboard;
|
||||
|
||||
pointer = gdk_event_get_device ((GdkEvent *) event);
|
||||
keyboard = gdk_device_get_associated_device (pointer);
|
||||
|
||||
/* Grab both keyboard/pointer, other devices will be
|
||||
* unable to interact with the widget window meanwhile
|
||||
*/
|
||||
gdk_device_grab (pointer,
|
||||
gtk_widget_get_window (widget),
|
||||
GDK_OWNERSHIP_WINDOW,
|
||||
...);
|
||||
gdk_device_grab (keyboard,
|
||||
gtk_widget_get_window (widget),
|
||||
GDK_OWNERSHIP_WINDOW,
|
||||
...);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
</programlisting>
|
||||
</example>
|
||||
|
||||
<para>
|
||||
For GTK+ grabs, there's only a boolean value, equivalent to
|
||||
%GDK_OWNERSHIP_NONE and %GDK_OWNERSHIP_WINDOW, but the mechanism
|
||||
is quite similar.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Once the device is grabbed, there may be different situations
|
||||
that could break the grabs, so the widget needs to listen to
|
||||
#GdkGrabBrokenEvent and the #GtkWidget::grab-notify signal to
|
||||
handle these situations.
|
||||
</para>
|
||||
|
||||
<example>
|
||||
<title>Handling broken grabs</title>
|
||||
<programlisting>
|
||||
static gboolean
|
||||
my_widget_grab_broken (GtkWidget *widget,
|
||||
GdkEventGrabBroken *event)
|
||||
{
|
||||
MyWidgetPrivate *priv = GET_PRIV (widget);
|
||||
|
||||
if (gdk_event_get_device (event) == priv->grab_pointer)
|
||||
{
|
||||
/* Undo state */
|
||||
...
|
||||
priv->grab_pointer = NULL;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
my_widget_grab_notify (GtkWidget *widget,
|
||||
gboolean was_grabbed)
|
||||
{
|
||||
MyWidgetPrivate *priv = GET_PRIV (widget);
|
||||
|
||||
if (gtk_widget_device_is_shadowed (widget, priv->grab_device))
|
||||
{
|
||||
/* Device was "shadowed" by another widget's grab,
|
||||
* release and undo state
|
||||
*/
|
||||
...
|
||||
priv->grab_pointer = NULL;
|
||||
}
|
||||
}
|
||||
</programlisting>
|
||||
</example>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Handling multipointer</title>
|
||||
|
||||
<para>
|
||||
Widgets do react by default to every virtual device, although
|
||||
by default they are set in a compatibility mode that makes them
|
||||
behave better with multiple pointers, without necessarily
|
||||
being multipointer aware.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
This compatibility mode most notably disables per-device
|
||||
enter/leave events, so these are stacked, and the crossing
|
||||
events are only emitted when the first pointer enters the
|
||||
window, and after the last pointer leaves it. This behavior
|
||||
is controlled through gtk_widget_set_support_multidevice()
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Reading device axis values</title>
|
||||
|
||||
<para>
|
||||
Button and motion events provide further information about
|
||||
the device axes' current state. Note the device axes are
|
||||
hardware and driver dependent, therefore the set of axes
|
||||
is not set in stone, although there are a few more common ones.
|
||||
</para>
|
||||
|
||||
<example>
|
||||
<title>Getting to know the axes provided by a device</title>
|
||||
<programlisting>
|
||||
carlos@sacarino:~$ xinput list "Wacom ISDv4 E6 Pen stylus" |grep "Label"
|
||||
Label: Abs X
|
||||
Label: Abs Y
|
||||
Label: Abs Pressure
|
||||
Label: Abs Tilt X
|
||||
Label: Abs Tilt Y
|
||||
Label: Abs Wheel
|
||||
</programlisting>
|
||||
</example>
|
||||
|
||||
<example>
|
||||
<title>Getting an axis value</title>
|
||||
<programlisting>
|
||||
gboolean
|
||||
my_widget_motion_notify (GtkWidget *widget,
|
||||
GdkEventMotion *event)
|
||||
{
|
||||
GdkAtom *label_atom;
|
||||
gdouble pressure;
|
||||
|
||||
label_atom = gdk_atom_intern_static_string ("Abs Pressure");
|
||||
gdk_device_get_axis_value (gdk_event_get_device ((GdkEvent *) event),
|
||||
event->axes, label_atom, &pressure);
|
||||
|
||||
/* Do something with pressure */
|
||||
...
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
</programlisting>
|
||||
</example>
|
||||
|
||||
<para>
|
||||
All pointer devices report axes information, master and slave. to
|
||||
achieve this, master pointers modify their list of axes at runtime
|
||||
to reflect those of the currently routed slave, emitting
|
||||
#GdkDevice::changed as the routed slave device changes.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Dealing with slave (or floating) devices</title>
|
||||
|
||||
<para>
|
||||
By default, GTK+ listens to all master devices, and typically
|
||||
all slave devices will be attached to a master device. so
|
||||
gdk_event_get_source_device() is the recommended way to deal
|
||||
with the physical device triggering the event.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
In more specialized setups, some devices could be floating
|
||||
(i.e. tablets that don't route events through any virtual
|
||||
pointer, but are expected to interact with drawing applications).
|
||||
In that case, such specialized applications could want to interact
|
||||
directly with the device. To do so, the device must be enabled,
|
||||
and the widget wanting its events needs to add the event mask.
|
||||
</para>
|
||||
|
||||
<example>
|
||||
<title>Enabling events for a slave device</title>
|
||||
<programlisting>
|
||||
GdkDevice *device;
|
||||
|
||||
/* Gets the first device found with the given GdkInputSource */
|
||||
device = get_device (gtk_widget_get_display (widget),
|
||||
GDK_SOURCE_PEN);
|
||||
gdk_device_set_mode (device, GDK_MODE_SCREEN);
|
||||
gtk_widget_add_device_events (widget, device,
|
||||
GDK_BUTTON_PRESS_MASK |
|
||||
GDK_BUTTON_RELEASE_MASK |
|
||||
GDK_POINTER_MOTION_MASK);
|
||||
</programlisting>
|
||||
</example>
|
||||
|
||||
<para>
|
||||
After these calls, the widget would specifically receive events
|
||||
from the physical device, regardless of it being floating or
|
||||
connected to a master device. In this second case, and if you
|
||||
want exclusive control of the device, you can temporarily detach
|
||||
the stylus device from its master by doing a GDK grab on it.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
For events coming directly from slave devices, both
|
||||
gdk_event_get_device() and gdk_event_get_source_device() will
|
||||
return the same device of type %GDK_DEVICE_TYPE_SLAVE or
|
||||
%GDK_DEVICE_TYPE_FLOATING.
|
||||
</para>
|
||||
|
||||
<note>
|
||||
This is less useful than it used to be in GTK+2/XInput1, at least
|
||||
for attached slaves, as there is gdk_event_get_source_device(),
|
||||
and master devices' events provide axes information.
|
||||
</note>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section id="gtk-device-patterns-multitouch-widgets">
|
||||
<title>Multitouch in GTK+ widgets</title>
|
||||
|
||||
<para>
|
||||
Since version 3.4, GTK+ offers support for multitouch devices through a new
|
||||
set of events and higher level tools like #GdkTouchCluster and
|
||||
#GtkGesturesInterpreter.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
If the widget does not have %GDK_TOUCH_MASK set in the event mask, it will
|
||||
only be allowed to interact with the touch emulating pointer events, and will
|
||||
only receive pointer events.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
If the widget does have %GDK_TOUCH_MASK enabled, it will be able to receive
|
||||
events of type %GDK_TOUCH_PRESS, %GDK_TOUCH_RELEASE and %GDK_TOUCH_MOTION,
|
||||
which will be respectively emitted through the #GtkWidget::button-press-event,
|
||||
#GtkWidget::button-release-event and #GtkWidget::motion-notify-event signals.
|
||||
There may be multiple, simultaneous sequences of events, those will be
|
||||
recognized and referenced by their touch ID. See gdk_event_get_touch_id().
|
||||
</para>
|
||||
|
||||
<para>
|
||||
#GtkWidget<!-- -->s may create GdkTouchCluster<!-- -->s via
|
||||
gdk_window_create_touch_cluster(), those may be used to group
|
||||
touch events together, which are notified through #GdkEventMultitouch,
|
||||
this event will be emitted in #GtkWidget<!-- -->s through the
|
||||
#GtkWidget::multitouch-event signal.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Widgets may also handle gestures being performed on them,
|
||||
gtk_widget_enable_gesture() and gtk_widget_disable_gesture() are
|
||||
provided as a simple API, although widgets may also create a
|
||||
#GtkGesturesInterpreter and feed it events directly.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id="gtk-device-patterns-multitouch">
|
||||
<title>Multitouch across a widget hierarchy</title>
|
||||
|
||||
<para>
|
||||
Fully touch driven applications might not want to confine multitouch
|
||||
operations within a single widget, but rather offer simultaneous
|
||||
interaction with multiple widgets.
|
||||
</para>
|
||||
<para>
|
||||
GTK+ is able to provide such experience, although it does not enable
|
||||
%GDK_TOUCH_MASK by default on its stock widgets. If a widget meets the
|
||||
following requirements, it is ready to be used in a multitouch UI:
|
||||
</para>
|
||||
|
||||
<orderedlist>
|
||||
<listitem>
|
||||
The widget handles #GtkWidget::button-press-event, #GtkWidget::button-release-event
|
||||
and #GtkWidget::motion-notify-event, and does something meaningful while the button 1
|
||||
is pressed. If any explicit check on the event type being %GDK_BUTTON_PRESS,
|
||||
%GDK_BUTTON_RELEASE or %GDK_MOTION_NOTIFY is performed, the event types
|
||||
%GDK_TOUCH_PRESS, %GDK_TOUCH_RELEASE or %GDK_TOUCH_MOTION also need to be handled.
|
||||
</listitem>
|
||||
<listitem>
|
||||
The widget relies on the implicit grab as long as the button press/touch is active,
|
||||
GDK or GTK+ grabs would break the implicit grabs other touch sequences may have on
|
||||
other widgets.
|
||||
</listitem>
|
||||
<listitem>
|
||||
The widget does not require (or opts out) keyboard interaction while a touch is
|
||||
active on it. Touch interaction does not necessarily bring the keyboard focus with it.
|
||||
</listitem>
|
||||
<listitem>
|
||||
If the widget is only meant to interact with one touch sequence at a time (i.e.
|
||||
buttons), it has to be able to discern and reject operations on any later touch
|
||||
sequence as long as the touch it is interacting with remains active.
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
|
||||
<para>
|
||||
If a widget meets those requirements, enabling %GDK_TOUCH_MASK on it will suffice
|
||||
to make it handle multitouch events in a way that doesn't disrupt other touch
|
||||
operations.
|
||||
</para>
|
||||
|
||||
<example>
|
||||
<title>Enabling touch events on a widget</title>
|
||||
<programlisting>
|
||||
gtk_widget_add_events (widget, GDK_TOUCH_MASK);
|
||||
</programlisting>
|
||||
</example>
|
||||
|
||||
<note>
|
||||
Not all GTK+ stock widgets are immediately suitable for handling touch
|
||||
events, there could be even design reasons on some of those which render
|
||||
them unsuitable.
|
||||
</note>
|
||||
</section>
|
||||
|
||||
<section id="gtk-device-patterns-recommendations">
|
||||
<title>Recommendations</title>
|
||||
|
||||
<orderedlist>
|
||||
<listitem>
|
||||
Device operations often come up as a result of input events, favor
|
||||
gdk_event_get_device() and gtk_get_current_event_device() before
|
||||
gdk_device_manager_get_client_pointer().
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
Store the devices the widget is currently interacting with, handle
|
||||
GdkEventGrabBroken and #GtkWidget::grab-notify to undo/nullify these.
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
</section>
|
||||
</chapter>
|
||||
@@ -68,6 +68,12 @@
|
||||
<xi:include href="xml/gtkstyle.xml" />
|
||||
</part>
|
||||
|
||||
<part id="multitouch-and-multidevice">
|
||||
<title>Interacting with input devices</title>
|
||||
<xi:include href="xml/device-interaction-patterns.xml" />
|
||||
<xi:include href="xml/gtkgesturesinterpreter.xml" />
|
||||
</part>
|
||||
|
||||
<part id="gtkobjects">
|
||||
<title>GTK+ Widgets and Objects</title>
|
||||
|
||||
@@ -209,18 +215,22 @@
|
||||
|
||||
<chapter id="SelectorWidgets">
|
||||
<title>Selectors (Color/File/Font)</title>
|
||||
<xi:include href="xml/gtkcolorchooser.xml" />
|
||||
<xi:include href="xml/gtkcolorbutton.xml" />
|
||||
<xi:include href="xml/gtkcolorseldlg.xml" />
|
||||
<xi:include href="xml/gtkcolorchooserwidget.xml" />
|
||||
<xi:include href="xml/gtkcolorchooserdialog.xml" />
|
||||
<xi:include href="xml/gtkcolorsel.xml" />
|
||||
<xi:include href="xml/gtkcolorseldlg.xml" />
|
||||
<xi:include href="xml/gtkhsv.xml" />
|
||||
<xi:include href="xml/gtkfilechooser.xml" />
|
||||
<xi:include href="xml/gtkfilechooserbutton.xml" />
|
||||
<xi:include href="xml/gtkfilechooserdialog.xml" />
|
||||
<xi:include href="xml/gtkfilechooserwidget.xml" />
|
||||
<xi:include href="xml/gtkfilefilter.xml" />
|
||||
<xi:include href="xml/gtkfontbutton.xml" />
|
||||
<xi:include href="xml/gtkfontchooser.xml" />
|
||||
<xi:include href="xml/gtkfontchooserdlg.xml" />
|
||||
<xi:include href="xml/gtkfontbutton.xml" />
|
||||
<xi:include href="xml/gtkfontchooserwidget.xml" />
|
||||
<xi:include href="xml/gtkfontchooserdialog.xml" />
|
||||
<xi:include href="xml/gtkfontsel.xml" />
|
||||
<xi:include href="xml/gtkfontseldlg.xml" />
|
||||
</chapter>
|
||||
|
||||
@@ -37,6 +37,7 @@ gtk_about_dialog_get_logo
|
||||
gtk_about_dialog_set_logo
|
||||
gtk_about_dialog_get_logo_icon_name
|
||||
gtk_about_dialog_set_logo_icon_name
|
||||
gtk_about_dialog_add_credit_section
|
||||
gtk_show_about_dialog
|
||||
<SUBSECTION Standard>
|
||||
GTK_ABOUT_DIALOG
|
||||
@@ -1534,7 +1535,7 @@ gtk_font_chooser_widget_get_type
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>gtkfontchooserdlg</FILE>
|
||||
<FILE>gtkfontchooserdialog</FILE>
|
||||
<TITLE>GtkFontChooserDialog</TITLE>
|
||||
GtkFontChooserDialog
|
||||
gtk_font_chooser_dialog_new
|
||||
@@ -1578,6 +1579,51 @@ GtkFramePrivate
|
||||
gtk_frame_get_type
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>gtkgesturesinterpreter</FILE>
|
||||
<TITLE>GtkGesturesInterpreter</TITLE>
|
||||
GtkGesturesInterpreter
|
||||
GtkGestureType
|
||||
gtk_gestures_interpreter_new
|
||||
gtk_gestures_interpreter_add_gesture
|
||||
gtk_gestures_interpreter_remove_gesture
|
||||
gtk_gestures_interpreter_feed_event
|
||||
gtk_gestures_interpreter_finish
|
||||
gtk_gestures_interpreter_get_n_active_strokes
|
||||
|
||||
<SUBSECTION Gestures>
|
||||
GtkGestureStroke
|
||||
gtk_gesture_stroke_new
|
||||
gtk_gesture_stroke_copy
|
||||
gtk_gesture_stroke_free
|
||||
gtk_gesture_stroke_append_vector
|
||||
gtk_gesture_stroke_get_n_vectors
|
||||
gtk_gesture_stroke_get_vector
|
||||
GtkGesture
|
||||
GtkGestureFlags
|
||||
gtk_gesture_new
|
||||
gtk_gesture_copy
|
||||
gtk_gesture_free
|
||||
gtk_gesture_add_stroke
|
||||
gtk_gesture_get_n_strokes
|
||||
gtk_gesture_get_stroke
|
||||
gtk_gesture_get_flags
|
||||
gtk_gesture_register
|
||||
gtk_gesture_register_static
|
||||
gtk_gesture_lookup
|
||||
|
||||
<SUBSECTION Standard>
|
||||
GTK_GESTURES_INTERPRETER
|
||||
GTK_IS_GESTURES_INTERPRETER
|
||||
GTK_TYPE_GESTURES_INTERPRETER
|
||||
GTK_IS_GESTURES_INTERPRETER_CLASS
|
||||
GTK_GESTURES_INTERPRETER_GET_CLASS
|
||||
<SUBSECTION Private>
|
||||
gtk_gestures_interpreter_get_type
|
||||
gtk_gesture_stroke_get_type
|
||||
gtk_gesture_get_type
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>gtkhandlebox</FILE>
|
||||
<TITLE>GtkHandleBox</TITLE>
|
||||
@@ -2059,6 +2105,7 @@ gtk_link_button_get_type
|
||||
<TITLE>GtkMenu</TITLE>
|
||||
GtkMenu
|
||||
gtk_menu_new
|
||||
gtk_menu_new_from_model
|
||||
gtk_menu_set_screen
|
||||
gtk_menu_reorder_child
|
||||
gtk_menu_attach
|
||||
@@ -2103,6 +2150,7 @@ gtk_menu_get_type
|
||||
<TITLE>GtkMenuBar</TITLE>
|
||||
GtkMenuBar
|
||||
gtk_menu_bar_new
|
||||
gtk_menu_bar_new_from_model
|
||||
GtkPackDirection
|
||||
gtk_menu_bar_set_pack_direction
|
||||
gtk_menu_bar_get_pack_direction
|
||||
@@ -2936,6 +2984,9 @@ gtk_scrolled_window_get_min_content_width
|
||||
gtk_scrolled_window_set_min_content_width
|
||||
gtk_scrolled_window_get_min_content_height
|
||||
gtk_scrolled_window_set_min_content_height
|
||||
GtkKineticScrollingFlags
|
||||
gtk_scrolled_window_set_kinetic_scrolling
|
||||
gtk_scrolled_window_get_kinetic_scrolling
|
||||
|
||||
<SUBSECTION Standard>
|
||||
GTK_SCROLLED_WINDOW
|
||||
@@ -5025,6 +5076,7 @@ GtkAllocation
|
||||
GtkSelectionData
|
||||
GtkWidgetAuxInfo
|
||||
GtkWidgetHelpType
|
||||
GtkCapturedEventFlags
|
||||
gtk_widget_new
|
||||
gtk_widget_destroy
|
||||
gtk_widget_in_destruction
|
||||
@@ -5210,6 +5262,7 @@ gtk_widget_get_mapped
|
||||
gtk_widget_get_requisition
|
||||
gtk_widget_device_is_shadowed
|
||||
gtk_widget_get_modifier_mask
|
||||
gtk_widget_release_captured_events
|
||||
|
||||
<SUBSECTION>
|
||||
gtk_widget_get_path
|
||||
@@ -5259,6 +5312,10 @@ gtk_widget_set_vexpand_set
|
||||
gtk_widget_queue_compute_expand
|
||||
gtk_widget_compute_expand
|
||||
|
||||
<SUBSECTION Gestures>
|
||||
gtk_widget_enable_gesture
|
||||
gtk_widget_disable_gesture
|
||||
|
||||
<SUBSECTION Standard>
|
||||
GTK_WIDGET
|
||||
GTK_IS_WIDGET
|
||||
@@ -7295,3 +7352,61 @@ GtkOverlayClass
|
||||
gtk_overlay_get_type
|
||||
GtkOverlayPrivate
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>gtkcolorchooser</FILE>
|
||||
<TITLE>GtkColorChooser</TITLE>
|
||||
GtkColorChooser
|
||||
gtk_color_chooser_get_rgba
|
||||
gtk_color_chooser_set_rgba
|
||||
gtk_color_chooser_get_use_alpha
|
||||
gtk_color_chooser_set_use_alpha
|
||||
gtk_color_chooser_add_palette
|
||||
|
||||
<SUBSECTION Standard>
|
||||
GTK_TYPE_COLOR_CHOOSER
|
||||
GTK_COLOR_CHOOSER
|
||||
GTK_IS_COLOR_CHOOSER
|
||||
GTK_COLOR_CHOOSER_GET_IFACE
|
||||
|
||||
<SUBSECTION Private>
|
||||
gtk_color_chooser_get_type
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>gtkcolorchooserwidget</FILE>
|
||||
<TITLE>GtkColorChooserWidget</TITLE>
|
||||
GtkColorChooserWidget
|
||||
gtk_color_chooser_widget_new
|
||||
|
||||
<SUBSECTION Standard>
|
||||
GTK_TYPE_COLOR_CHOOSER_WIDGET
|
||||
GTK_COLOR_CHOOSER_WIDGET
|
||||
GTK_COLOR_CHOOSER_WIDGET_CLASS
|
||||
GTK_IS_COLOR_CHOOSER_WIDGET
|
||||
GTK_IS_COLOR_CHOOSER_WIDGET_CLASS
|
||||
GTK_COLOR_CHOOSER_WIDGET_GET_CLASS
|
||||
|
||||
<SUBSECTION Private>
|
||||
gtk_color_chooser_widget_get_type
|
||||
GtkColorChooserWidgetPrivate
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>gtkcolorchooserdialog</FILE>
|
||||
<TITLE>GtkColorChooserDialog</TITLE>
|
||||
GtkColorChooserDialog
|
||||
gtk_color_chooser_dialog_new
|
||||
|
||||
<SUBSECTION Standard>
|
||||
GTK_TYPE_COLOR_CHOOSER_DIALOG
|
||||
GTK_COLOR_CHOOSER_DIALOG
|
||||
GTK_COLOR_CHOOSER_DIALOG_CLASS
|
||||
GTK_IS_COLOR_CHOOSER_DIALOG
|
||||
GTK_IS_COLOR_CHOOSER_DIALOG_CLASS
|
||||
GTK_COLOR_CHOOSER_DIALOG_GET_CLASS
|
||||
|
||||
<SUBSECTION Private>
|
||||
GtkColorChooserDialogPrivate
|
||||
gtk_color_chooser_dialog_get_type
|
||||
</SECTION>
|
||||
|
||||
@@ -47,6 +47,9 @@ gtk_check_button_get_type
|
||||
gtk_check_menu_item_get_type
|
||||
gtk_clipboard_get_type
|
||||
gtk_color_button_get_type
|
||||
gtk_color_chooser_get_type
|
||||
gtk_color_chooser_dialog_get_type
|
||||
gtk_color_chooser_widget_get_type
|
||||
gtk_color_selection_dialog_get_type
|
||||
gtk_color_selection_get_type
|
||||
gtk_combo_box_get_type
|
||||
@@ -74,6 +77,7 @@ gtk_font_chooser_widget_get_type
|
||||
gtk_font_selection_dialog_get_type
|
||||
gtk_font_selection_get_type
|
||||
gtk_frame_get_type
|
||||
gtk_gestures_interpreter_get_type
|
||||
gtk_grid_get_type
|
||||
gtk_handle_box_get_type
|
||||
gtk_hbox_get_type
|
||||
|
||||
BIN
docs/reference/gtk/images/colorchooser.png
Normal file
BIN
docs/reference/gtk/images/colorchooser.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 16 KiB |
BIN
docs/reference/gtk/images/fontchooser.png
Normal file
BIN
docs/reference/gtk/images/fontchooser.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 62 KiB |
@@ -121,9 +121,9 @@ Here's a simple example:
|
||||
do_small_part_of_task ();
|
||||
|
||||
if (task_complete)
|
||||
return FALSE; /* removes the idle handler */
|
||||
return G_SOURCE_REMOVE; /* removes the idle handler */
|
||||
else
|
||||
return TRUE; /* runs the idle handler again */
|
||||
return G_SOURCE_CONTINUE; /* runs the idle handler again */
|
||||
}
|
||||
|
||||
g_idle_add (my_idle_handler, NULL);
|
||||
|
||||
@@ -135,4 +135,10 @@
|
||||
<link linkend="GtkSwitch">
|
||||
<inlinegraphic fileref="switch.png" format="PNG"></inlinegraphic>
|
||||
</link>
|
||||
<link linkend="GtkColorChooserDialog">
|
||||
<inlinegraphic fileref="colorchooser.png" format="PNG"></inlinegraphic>
|
||||
</link>
|
||||
<link linkend="GtkFontChooserDialog">
|
||||
<inlinegraphic fileref="fontchooser.png" format="PNG"></inlinegraphic>
|
||||
</link>
|
||||
</para>
|
||||
|
||||
@@ -1154,6 +1154,33 @@ create_appchooserdialog (void)
|
||||
return info;
|
||||
}
|
||||
|
||||
static WidgetInfo *
|
||||
create_fontchooserdialog (void)
|
||||
{
|
||||
WidgetInfo *info;
|
||||
GtkWidget *widget;
|
||||
|
||||
widget = gtk_font_chooser_dialog_new ("Font Chooser Dialog", NULL);
|
||||
gtk_window_set_default_size (GTK_WINDOW (widget), 200, 300);
|
||||
info = new_widget_info ("fontchooser", widget, ASIS);
|
||||
info->include_decorations = TRUE;
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
static WidgetInfo *
|
||||
create_colorchooserdialog (void)
|
||||
{
|
||||
WidgetInfo *info;
|
||||
GtkWidget *widget;
|
||||
|
||||
widget = gtk_color_chooser_dialog_new ("Color Chooser Dialog", NULL);
|
||||
info = new_widget_info ("colorchooser", widget, ASIS);
|
||||
info->include_decorations = TRUE;
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
GList *
|
||||
get_all_widgets (void)
|
||||
{
|
||||
@@ -1204,6 +1231,8 @@ get_all_widgets (void)
|
||||
retval = g_list_prepend (retval, create_appchooserbutton ());
|
||||
retval = g_list_prepend (retval, create_appchooserdialog ());
|
||||
retval = g_list_prepend (retval, create_lockbutton ());
|
||||
retval = g_list_prepend (retval, create_fontchooserdialog ());
|
||||
retval = g_list_prepend (retval, create_colorchooserdialog ());
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
@@ -275,25 +275,50 @@ bloat_pad_startup (GApplication *application)
|
||||
"<interface>"
|
||||
" <menu id='app-menu'>"
|
||||
" <section>"
|
||||
" <item label='_New Window' action='app.new' accel='<Primary>n'/>"
|
||||
" <item>"
|
||||
" <attribute name='label' translatable='yes'>_New Window</attribute>"
|
||||
" <attribute name='action'>app.new</attribute>"
|
||||
" <attribute name='accel'><Primary>n</attribute>"
|
||||
" </item>"
|
||||
" </section>"
|
||||
" <section>"
|
||||
" <item label='_About Bloatpad' action='app.about'/>"
|
||||
" <item>"
|
||||
" <attribute name='label' translatable='yes'>_About Bloatpad</attribute>"
|
||||
" <attribute name='action'>app.about</attribute>"
|
||||
" </item>"
|
||||
" </section>"
|
||||
" <section>"
|
||||
" <item label='_Quit' action='app.quit' accel='<Primary>q'/>"
|
||||
" <item>"
|
||||
" <attribute name='label' translatable='yes'>_Quit</attribute>"
|
||||
" <attribute name='action'>app.quit</attribute>"
|
||||
" <attribute name='accel'><Primary>q</attribute>"
|
||||
" </item>"
|
||||
" </section>"
|
||||
" </menu>"
|
||||
" <menu id='menubar'>"
|
||||
" <submenu label='_Edit'>"
|
||||
" <submenu>"
|
||||
" <attribute name='label' translatable='yes'>_Edit</attribute>"
|
||||
" <section>"
|
||||
" <item label='_Copy' action='win.copy' accel='<Primary>c'/>"
|
||||
" <item label='_Paste' action='win.paste' accel='<Primary>v'/>"
|
||||
" <item>"
|
||||
" <attribute name='label' translatable='yes'>_Copy</attribute>"
|
||||
" <attribute name='action'>win.copy</attribute>"
|
||||
" <attribute name='accel'><Primary>c</attribute>"
|
||||
" </item>"
|
||||
" <item>"
|
||||
" <attribute name='label' translatable='yes'>_Parse</attribute>"
|
||||
" <attribute name='action'>win.parse</attribute>"
|
||||
" <attribute name='accel'><Primary>v</attribute>"
|
||||
" </item>"
|
||||
" </section>"
|
||||
" </submenu>"
|
||||
" <submenu label='_View'>"
|
||||
" <submenu>"
|
||||
" <attribute name='label' translatable='yes'>_View</attribute>"
|
||||
" <section>"
|
||||
" <item label='_Fullscreen' action='win.fullscreen'/>"
|
||||
" <item>"
|
||||
" <attribute name='label' translatable='yes'>_Fullscreen</attribute>"
|
||||
" <attribute name='action'>win.fullscreen</attribute>"
|
||||
" <attribute name='accel'>F11</attribute>"
|
||||
" </item>"
|
||||
" </section>"
|
||||
" </submenu>"
|
||||
" </menu>"
|
||||
@@ -337,6 +362,8 @@ bloat_pad_new (void)
|
||||
|
||||
g_type_init ();
|
||||
|
||||
g_set_application_name ("Bloatpad");
|
||||
|
||||
bloat_pad = g_object_new (bloat_pad_get_type (),
|
||||
"application-id", "org.gtk.Test.bloatpad",
|
||||
"flags", G_APPLICATION_HANDLES_OPEN,
|
||||
@@ -356,9 +383,12 @@ main (int argc, char **argv)
|
||||
int status;
|
||||
|
||||
bloat_pad = bloat_pad_new ();
|
||||
|
||||
gtk_application_add_accelerator (GTK_APPLICATION (bloat_pad),
|
||||
"F11", "win.fullscreen", NULL);
|
||||
|
||||
status = g_application_run (G_APPLICATION (bloat_pad), argc, argv);
|
||||
|
||||
g_object_unref (bloat_pad);
|
||||
|
||||
return status;
|
||||
|
||||
@@ -86,11 +86,11 @@ button_press_event_cb (GtkWidget *widget,
|
||||
if (surface == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (event->button == 1)
|
||||
if (event->button == GDK_BUTTON_PRIMARY)
|
||||
{
|
||||
draw_brush (widget, event->x, event->y);
|
||||
}
|
||||
else if (event->button == 3)
|
||||
else if (event->button == GDK_BUTTON_SECONDARY)
|
||||
{
|
||||
clear_surface ();
|
||||
gtk_widget_queue_draw (widget);
|
||||
|
||||
@@ -88,6 +88,7 @@ gdk_public_h_sources = \
|
||||
gdkselection.h \
|
||||
gdktestutils.h \
|
||||
gdkthreads.h \
|
||||
gdktouchcluster.h \
|
||||
gdktypes.h \
|
||||
gdkvisual.h \
|
||||
gdkwindow.h
|
||||
@@ -130,6 +131,7 @@ gdk_c_sources = \
|
||||
gdkrgba.c \
|
||||
gdkscreen.c \
|
||||
gdkselection.c \
|
||||
gdktouchcluster.c \
|
||||
gdkvisual.c \
|
||||
gdkwindow.c \
|
||||
gdkwindowimpl.c
|
||||
|
||||
@@ -362,7 +362,7 @@ parse_input (BroadwayInput *input)
|
||||
gsize len, payload_len;
|
||||
BroadwayWSOpCode code;
|
||||
gboolean is_mask, fin;
|
||||
guchar *buf, *data;
|
||||
guchar *buf, *data, *mask;
|
||||
|
||||
buf = input->buffer->data;
|
||||
len = input->buffer->len;
|
||||
@@ -391,6 +391,16 @@ parse_input (BroadwayInput *input)
|
||||
payload_len = GUINT64_FROM_BE( *(guint64 *) data );
|
||||
data += 8;
|
||||
}
|
||||
|
||||
mask = NULL;
|
||||
if (is_mask)
|
||||
{
|
||||
if (data - buf + 4 > len)
|
||||
return;
|
||||
mask = data;
|
||||
data += 4;
|
||||
}
|
||||
|
||||
if (data - buf + payload_len > len)
|
||||
return; /* wait to accumulate more */
|
||||
|
||||
@@ -398,8 +408,7 @@ parse_input (BroadwayInput *input)
|
||||
{
|
||||
gsize i;
|
||||
for (i = 0; i < payload_len; i++)
|
||||
data[i + 4] ^= data[i%4];
|
||||
data += 4;
|
||||
data[i] ^= mask[i%4];
|
||||
}
|
||||
|
||||
switch (code) {
|
||||
@@ -413,7 +422,11 @@ parse_input (BroadwayInput *input)
|
||||
#endif
|
||||
}
|
||||
else
|
||||
parse_input_message (input, (char *)data);
|
||||
{
|
||||
char *terminated = g_strndup((char *)data, payload_len);
|
||||
parse_input_message (input, terminated);
|
||||
g_free (terminated);
|
||||
}
|
||||
break;
|
||||
case BROADWAY_WS_CNX_PING:
|
||||
broadway_output_pong (broadway_display->output);
|
||||
@@ -474,7 +487,7 @@ process_input_idle_cb (GdkBroadwayDisplay *display)
|
||||
{
|
||||
display->process_input_idle = 0;
|
||||
process_input_messages (display);
|
||||
return FALSE;
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1003,7 +1016,7 @@ got_http_request_line (GInputStream *stream,
|
||||
/* Protect against overflow in request length */
|
||||
if (request->request->len > 1024 * 5)
|
||||
{
|
||||
send_error (request, 400, "Request to long");
|
||||
send_error (request, 400, "Request too long");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -895,7 +895,7 @@ gdk_threads_add_idle (GSourceFunc function,
|
||||
*
|
||||
* self->timeout_id = 0;
|
||||
*
|
||||
* return FALSE;
|
||||
* return G_SOURCE_REMOVE;
|
||||
* }
|
||||
*
|
||||
* static void some_widget_do_stuff_later (SomeWidget *self)
|
||||
|
||||
@@ -53,6 +53,7 @@
|
||||
#include <gdk/gdkselection.h>
|
||||
#include <gdk/gdktestutils.h>
|
||||
#include <gdk/gdkthreads.h>
|
||||
#include <gdk/gdktouchcluster.h>
|
||||
#include <gdk/gdktypes.h>
|
||||
#include <gdk/gdkvisual.h>
|
||||
#include <gdk/gdkwindow.h>
|
||||
|
||||
@@ -168,6 +168,7 @@ gdk_event_get_scroll_direction
|
||||
gdk_event_get_source_device
|
||||
gdk_event_get_state
|
||||
gdk_event_get_time
|
||||
gdk_event_get_touch_id
|
||||
gdk_event_get_type
|
||||
gdk_event_handler_set
|
||||
gdk_event_mask_get_type
|
||||
@@ -327,6 +328,11 @@ gdk_threads_enter
|
||||
gdk_threads_init
|
||||
gdk_threads_leave
|
||||
gdk_threads_set_lock_functions
|
||||
gdk_touch_cluster_add_touch
|
||||
gdk_touch_cluster_get_device
|
||||
gdk_touch_cluster_get_type G_GNUC_CONST
|
||||
gdk_touch_cluster_list_touches
|
||||
gdk_touch_cluster_remove_touch
|
||||
gdk_unicode_to_keyval
|
||||
gdk_utf8_to_string_target
|
||||
gdk_visibility_state_get_type
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
* screen or workspace.
|
||||
* <example>
|
||||
* <title>Launching an application</title>
|
||||
* <informalexample>
|
||||
* <programlisting>
|
||||
* GdkAppLaunchContext *context;
|
||||
*
|
||||
@@ -51,6 +52,7 @@
|
||||
*
|
||||
* g_object_unref (context);
|
||||
* </programlisting>
|
||||
* </informalexample>
|
||||
* </example>
|
||||
*/
|
||||
|
||||
|
||||
@@ -61,6 +61,7 @@ typedef enum
|
||||
* of a stylus on a graphics tablet.
|
||||
* @GDK_SOURCE_CURSOR: the device is a graphics tablet "puck" or similar device.
|
||||
* @GDK_SOURCE_KEYBOARD: the device is a keyboard.
|
||||
* @GDK_SOURCE_TOUCH: the device is a touch capable device.
|
||||
*
|
||||
* An enumeration describing the type of an input device in general terms.
|
||||
*/
|
||||
@@ -70,7 +71,8 @@ typedef enum
|
||||
GDK_SOURCE_PEN,
|
||||
GDK_SOURCE_ERASER,
|
||||
GDK_SOURCE_CURSOR,
|
||||
GDK_SOURCE_KEYBOARD
|
||||
GDK_SOURCE_KEYBOARD,
|
||||
GDK_SOURCE_TOUCH
|
||||
} GdkInputSource;
|
||||
|
||||
/**
|
||||
|
||||
148
gdk/gdkdisplay.c
148
gdk/gdkdisplay.c
@@ -188,6 +188,7 @@ gdk_display_init (GdkDisplay *display)
|
||||
display->double_click_time = 250;
|
||||
display->double_click_distance = 5;
|
||||
|
||||
display->touch_implicit_grabs = g_array_new (FALSE, FALSE, sizeof (GdkTouchGrabInfo));
|
||||
display->device_grabs = g_hash_table_new (NULL, NULL);
|
||||
display->motion_hint_info = g_hash_table_new_full (NULL, NULL, NULL,
|
||||
(GDestroyNotify) g_free);
|
||||
@@ -236,6 +237,8 @@ gdk_display_finalize (GObject *object)
|
||||
NULL);
|
||||
g_hash_table_destroy (display->device_grabs);
|
||||
|
||||
g_array_free (display->touch_implicit_grabs, TRUE);
|
||||
|
||||
g_hash_table_destroy (display->motion_hint_info);
|
||||
g_hash_table_destroy (display->pointers_info);
|
||||
g_hash_table_destroy (display->multiple_click_info);
|
||||
@@ -694,6 +697,81 @@ _gdk_display_add_device_grab (GdkDisplay *display,
|
||||
return info;
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_display_break_touch_grabs (GdkDisplay *display,
|
||||
GdkDevice *device,
|
||||
GdkWindow *new_grab_window)
|
||||
{
|
||||
guint i = 0;
|
||||
|
||||
while (i < display->touch_implicit_grabs->len)
|
||||
{
|
||||
GdkTouchGrabInfo *info;
|
||||
|
||||
info = &g_array_index (display->touch_implicit_grabs,
|
||||
GdkTouchGrabInfo, i);
|
||||
|
||||
if (info->device == device &&
|
||||
info->window != new_grab_window)
|
||||
{
|
||||
generate_grab_broken_event (GDK_WINDOW (info->window),
|
||||
device, TRUE, new_grab_window);
|
||||
_gdk_window_finish_touch_id (info->window, device, info->touch_id);
|
||||
g_array_remove_index_fast (display->touch_implicit_grabs, i);
|
||||
}
|
||||
else
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_display_add_touch_grab (GdkDisplay *display,
|
||||
GdkDevice *device,
|
||||
guint touch_id,
|
||||
GdkWindow *window,
|
||||
GdkWindow *native_window,
|
||||
GdkEventMask event_mask,
|
||||
unsigned long serial,
|
||||
guint32 time)
|
||||
{
|
||||
GdkTouchGrabInfo info;
|
||||
|
||||
info.device = device;
|
||||
info.touch_id = touch_id;
|
||||
info.window = g_object_ref (window);
|
||||
info.native_window = g_object_ref (native_window);
|
||||
info.serial = serial;
|
||||
info.event_mask = event_mask;
|
||||
info.time = time;
|
||||
|
||||
g_array_append_val (display->touch_implicit_grabs, info);
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gdk_display_end_touch_grab (GdkDisplay *display,
|
||||
GdkDevice *device,
|
||||
guint touch_id)
|
||||
{
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < display->touch_implicit_grabs->len; i++)
|
||||
{
|
||||
GdkTouchGrabInfo *info;
|
||||
|
||||
info = &g_array_index (display->touch_implicit_grabs,
|
||||
GdkTouchGrabInfo, i);
|
||||
|
||||
if (info->device == device &&
|
||||
info->touch_id == touch_id)
|
||||
{
|
||||
g_array_remove_index_fast (display->touch_implicit_grabs, i);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* _gdk_synthesize_crossing_events only works inside one toplevel.
|
||||
This function splits things into two calls if needed, converting the
|
||||
coordinates to the right toplevel */
|
||||
@@ -897,15 +975,25 @@ switch_to_pointer_grab (GdkDisplay *display,
|
||||
|
||||
if (grab == NULL) /* Ungrabbed, send events */
|
||||
{
|
||||
pointer_window = NULL;
|
||||
if (new_toplevel)
|
||||
{
|
||||
/* Find (possibly virtual) child window */
|
||||
pointer_window =
|
||||
_gdk_window_find_descendant_at (new_toplevel,
|
||||
x, y,
|
||||
NULL, NULL);
|
||||
}
|
||||
/* If the source device is a touch device, do not
|
||||
* propagate any enter event yet, until one is
|
||||
* synthesized when needed.
|
||||
*/
|
||||
if (source_device &&
|
||||
gdk_device_get_source (source_device) == GDK_SOURCE_TOUCH)
|
||||
info->need_touch_press_enter = TRUE;
|
||||
|
||||
pointer_window = NULL;
|
||||
|
||||
if (new_toplevel &&
|
||||
!info->need_touch_press_enter)
|
||||
{
|
||||
/* Find (possibly virtual) child window */
|
||||
pointer_window =
|
||||
_gdk_window_find_descendant_at (new_toplevel,
|
||||
x, y,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
if (pointer_window != last_grab->window)
|
||||
synthesize_crossing_events (display, device, source_device,
|
||||
@@ -964,12 +1052,15 @@ _gdk_display_device_grab_update (GdkDisplay *display,
|
||||
next_grab = NULL; /* Actually its not yet active */
|
||||
}
|
||||
|
||||
if (next_grab)
|
||||
_gdk_display_break_touch_grabs (display, device, next_grab->window);
|
||||
|
||||
if ((next_grab == NULL && current_grab->implicit_ungrab) ||
|
||||
(next_grab != NULL && current_grab->window != next_grab->window))
|
||||
generate_grab_broken_event (GDK_WINDOW (current_grab->window),
|
||||
(next_grab != NULL && current_grab->window != next_grab->window))
|
||||
generate_grab_broken_event (GDK_WINDOW (current_grab->window),
|
||||
device,
|
||||
current_grab->implicit,
|
||||
next_grab? next_grab->window : NULL);
|
||||
current_grab->implicit,
|
||||
next_grab? next_grab->window : NULL);
|
||||
|
||||
/* Remove old grab */
|
||||
grabs = g_list_delete_link (grabs, grabs);
|
||||
@@ -1028,6 +1119,34 @@ _gdk_display_has_device_grab (GdkDisplay *display,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GdkTouchGrabInfo *
|
||||
_gdk_display_has_touch_grab (GdkDisplay *display,
|
||||
GdkDevice *device,
|
||||
guint touch_id,
|
||||
gulong serial)
|
||||
{
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < display->touch_implicit_grabs->len; i++)
|
||||
{
|
||||
GdkTouchGrabInfo *info;
|
||||
|
||||
info = &g_array_index (display->touch_implicit_grabs,
|
||||
GdkTouchGrabInfo, i);
|
||||
|
||||
if (info->device == device &&
|
||||
info->touch_id == touch_id)
|
||||
{
|
||||
if (serial >= info->serial)
|
||||
return info;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Returns true if last grab was ended
|
||||
* If if_child is non-NULL, end the grab only if the grabbed
|
||||
* window is the same as if_child or a descendant of it */
|
||||
@@ -1120,6 +1239,9 @@ _gdk_display_get_pointer_info (GdkDisplay *display,
|
||||
{
|
||||
GdkPointerWindowInfo *info;
|
||||
|
||||
if (device && gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD)
|
||||
device = gdk_device_get_associated_device (device);
|
||||
|
||||
if (G_UNLIKELY (!device))
|
||||
return NULL;
|
||||
|
||||
|
||||
@@ -60,6 +60,19 @@ typedef struct
|
||||
guint implicit : 1;
|
||||
} GdkDeviceGrabInfo;
|
||||
|
||||
/* Tracks information about a touch implicit grab on this display */
|
||||
typedef struct
|
||||
{
|
||||
GdkDevice *device;
|
||||
guint touch_id;
|
||||
|
||||
GdkWindow *window;
|
||||
GdkWindow *native_window;
|
||||
gulong serial;
|
||||
guint event_mask;
|
||||
guint32 time;
|
||||
} GdkTouchGrabInfo;
|
||||
|
||||
/* Tracks information about which window and position the pointer last was in.
|
||||
* This is useful when we need to synthesize events later.
|
||||
* Note that we track toplevel_under_pointer using enter/leave events,
|
||||
@@ -75,6 +88,8 @@ typedef struct
|
||||
gdouble toplevel_x, toplevel_y;
|
||||
guint32 state;
|
||||
guint32 button;
|
||||
GdkDevice *last_slave;
|
||||
guint need_touch_press_enter : 1;
|
||||
} GdkPointerWindowInfo;
|
||||
|
||||
typedef struct
|
||||
@@ -103,6 +118,7 @@ struct _GdkDisplay
|
||||
guint closed : 1; /* Whether this display has been closed */
|
||||
guint ignore_core_events : 1; /* Don't send core motion and button event */
|
||||
|
||||
GArray *touch_implicit_grabs;
|
||||
GHashTable *device_grabs;
|
||||
GHashTable *motion_hint_info;
|
||||
GdkDeviceManager *device_manager;
|
||||
@@ -260,6 +276,21 @@ gboolean _gdk_display_end_device_grab (GdkDisplay *display
|
||||
gboolean _gdk_display_check_grab_ownership (GdkDisplay *display,
|
||||
GdkDevice *device,
|
||||
gulong serial);
|
||||
void _gdk_display_add_touch_grab (GdkDisplay *display,
|
||||
GdkDevice *device,
|
||||
guint touch_id,
|
||||
GdkWindow *window,
|
||||
GdkWindow *native_window,
|
||||
GdkEventMask event_mask,
|
||||
unsigned long serial_start,
|
||||
guint32 time);
|
||||
GdkTouchGrabInfo * _gdk_display_has_touch_grab (GdkDisplay *display,
|
||||
GdkDevice *device,
|
||||
guint touch_id,
|
||||
gulong serial);
|
||||
gboolean _gdk_display_end_touch_grab (GdkDisplay *display,
|
||||
GdkDevice *device,
|
||||
guint touch_id);
|
||||
void _gdk_display_enable_motion_hints (GdkDisplay *display,
|
||||
GdkDevice *device);
|
||||
GdkPointerWindowInfo * _gdk_display_get_pointer_info (GdkDisplay *display,
|
||||
|
||||
256
gdk/gdkevents.c
256
gdk/gdkevents.c
@@ -445,6 +445,7 @@ gdk_event_new (GdkEventType type)
|
||||
switch (type)
|
||||
{
|
||||
case GDK_MOTION_NOTIFY:
|
||||
case GDK_TOUCH_MOTION:
|
||||
new_event->motion.x = 0.;
|
||||
new_event->motion.y = 0.;
|
||||
new_event->motion.x_root = 0.;
|
||||
@@ -454,6 +455,8 @@ gdk_event_new (GdkEventType type)
|
||||
case GDK_2BUTTON_PRESS:
|
||||
case GDK_3BUTTON_PRESS:
|
||||
case GDK_BUTTON_RELEASE:
|
||||
case GDK_TOUCH_PRESS:
|
||||
case GDK_TOUCH_RELEASE:
|
||||
new_event->button.x = 0.;
|
||||
new_event->button.y = 0.;
|
||||
new_event->button.x_root = 0.;
|
||||
@@ -487,7 +490,31 @@ gdk_event_is_allocated (const GdkEvent *event)
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_gdk_event_set_pointer_emulated (GdkEvent *event,
|
||||
gboolean emulated)
|
||||
{
|
||||
if (gdk_event_is_allocated (event))
|
||||
{
|
||||
GdkEventPrivate *private = (GdkEventPrivate *) event;
|
||||
|
||||
if (emulated)
|
||||
private->flags |= GDK_EVENT_POINTER_EMULATED;
|
||||
else
|
||||
private->flags &= ~(GDK_EVENT_POINTER_EMULATED);
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gdk_event_get_pointer_emulated (GdkEvent *event)
|
||||
{
|
||||
if (gdk_event_is_allocated (event))
|
||||
return (((GdkEventPrivate *) event)->flags & GDK_EVENT_POINTER_EMULATED) != 0;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_event_copy:
|
||||
* @event: a #GdkEvent
|
||||
@@ -558,12 +585,15 @@ gdk_event_copy (const GdkEvent *event)
|
||||
case GDK_2BUTTON_PRESS:
|
||||
case GDK_3BUTTON_PRESS:
|
||||
case GDK_BUTTON_RELEASE:
|
||||
case GDK_TOUCH_PRESS:
|
||||
case GDK_TOUCH_RELEASE:
|
||||
if (event->button.axes)
|
||||
new_event->button.axes = g_memdup (event->button.axes,
|
||||
sizeof (gdouble) * gdk_device_get_n_axes (event->button.device));
|
||||
break;
|
||||
|
||||
case GDK_MOTION_NOTIFY:
|
||||
case GDK_TOUCH_MOTION:
|
||||
if (event->motion.axes)
|
||||
new_event->motion.axes = g_memdup (event->motion.axes,
|
||||
sizeof (gdouble) * gdk_device_get_n_axes (event->motion.device));
|
||||
@@ -583,6 +613,22 @@ gdk_event_copy (const GdkEvent *event)
|
||||
g_object_ref (new_event->selection.requestor);
|
||||
break;
|
||||
|
||||
case GDK_MULTITOUCH_ADDED:
|
||||
case GDK_MULTITOUCH_REMOVED:
|
||||
case GDK_MULTITOUCH_UPDATED:
|
||||
{
|
||||
GdkEventMotion **motion_events;
|
||||
guint i;
|
||||
|
||||
motion_events = g_new0 (GdkEventMotion*, event->multitouch.n_events);
|
||||
|
||||
for (i = 0; i < event->multitouch.n_events; i++)
|
||||
motion_events[i] = (GdkEventMotion *) gdk_event_copy ((GdkEvent *) event->multitouch.events[i]);
|
||||
|
||||
new_event->multitouch.events = motion_events;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -639,6 +685,8 @@ gdk_event_free (GdkEvent *event)
|
||||
case GDK_2BUTTON_PRESS:
|
||||
case GDK_3BUTTON_PRESS:
|
||||
case GDK_BUTTON_RELEASE:
|
||||
case GDK_TOUCH_PRESS:
|
||||
case GDK_TOUCH_RELEASE:
|
||||
g_free (event->button.axes);
|
||||
break;
|
||||
|
||||
@@ -649,6 +697,7 @@ gdk_event_free (GdkEvent *event)
|
||||
break;
|
||||
|
||||
case GDK_MOTION_NOTIFY:
|
||||
case GDK_TOUCH_MOTION:
|
||||
g_free (event->motion.axes);
|
||||
break;
|
||||
|
||||
@@ -668,6 +717,20 @@ gdk_event_free (GdkEvent *event)
|
||||
g_object_unref (event->selection.requestor);
|
||||
break;
|
||||
|
||||
case GDK_MULTITOUCH_ADDED:
|
||||
case GDK_MULTITOUCH_REMOVED:
|
||||
case GDK_MULTITOUCH_UPDATED:
|
||||
if (event->multitouch.events)
|
||||
{
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < event->multitouch.n_events; i++)
|
||||
gdk_event_free ((GdkEvent *) event->multitouch.events[i]);
|
||||
|
||||
g_free (event->multitouch.events);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -696,11 +759,14 @@ gdk_event_get_time (const GdkEvent *event)
|
||||
switch (event->type)
|
||||
{
|
||||
case GDK_MOTION_NOTIFY:
|
||||
case GDK_TOUCH_MOTION:
|
||||
return event->motion.time;
|
||||
case GDK_BUTTON_PRESS:
|
||||
case GDK_2BUTTON_PRESS:
|
||||
case GDK_3BUTTON_PRESS:
|
||||
case GDK_BUTTON_RELEASE:
|
||||
case GDK_TOUCH_PRESS:
|
||||
case GDK_TOUCH_RELEASE:
|
||||
return event->button.time;
|
||||
case GDK_SCROLL:
|
||||
return event->scroll.time;
|
||||
@@ -726,6 +792,10 @@ gdk_event_get_time (const GdkEvent *event)
|
||||
case GDK_DROP_START:
|
||||
case GDK_DROP_FINISHED:
|
||||
return event->dnd.time;
|
||||
case GDK_MULTITOUCH_ADDED:
|
||||
case GDK_MULTITOUCH_REMOVED:
|
||||
case GDK_MULTITOUCH_UPDATED:
|
||||
return event->multitouch.time;
|
||||
case GDK_CLIENT_EVENT:
|
||||
case GDK_VISIBILITY_NOTIFY:
|
||||
case GDK_CONFIGURE:
|
||||
@@ -771,12 +841,15 @@ gdk_event_get_state (const GdkEvent *event,
|
||||
switch (event->type)
|
||||
{
|
||||
case GDK_MOTION_NOTIFY:
|
||||
case GDK_TOUCH_MOTION:
|
||||
*state = event->motion.state;
|
||||
return TRUE;
|
||||
case GDK_BUTTON_PRESS:
|
||||
case GDK_2BUTTON_PRESS:
|
||||
case GDK_3BUTTON_PRESS:
|
||||
case GDK_BUTTON_RELEASE:
|
||||
case GDK_TOUCH_PRESS:
|
||||
case GDK_TOUCH_RELEASE:
|
||||
*state = event->button.state;
|
||||
return TRUE;
|
||||
case GDK_SCROLL:
|
||||
@@ -790,6 +863,11 @@ gdk_event_get_state (const GdkEvent *event,
|
||||
case GDK_LEAVE_NOTIFY:
|
||||
*state = event->crossing.state;
|
||||
return TRUE;
|
||||
case GDK_MULTITOUCH_ADDED:
|
||||
case GDK_MULTITOUCH_REMOVED:
|
||||
case GDK_MULTITOUCH_UPDATED:
|
||||
*state = event->multitouch.state;
|
||||
return TRUE;
|
||||
case GDK_PROPERTY_NOTIFY:
|
||||
case GDK_VISIBILITY_NOTIFY:
|
||||
case GDK_CLIENT_EVENT:
|
||||
@@ -865,10 +943,13 @@ gdk_event_get_coords (const GdkEvent *event,
|
||||
case GDK_2BUTTON_PRESS:
|
||||
case GDK_3BUTTON_PRESS:
|
||||
case GDK_BUTTON_RELEASE:
|
||||
case GDK_TOUCH_PRESS:
|
||||
case GDK_TOUCH_RELEASE:
|
||||
x = event->button.x;
|
||||
y = event->button.y;
|
||||
break;
|
||||
case GDK_MOTION_NOTIFY:
|
||||
case GDK_TOUCH_MOTION:
|
||||
x = event->motion.x;
|
||||
y = event->motion.y;
|
||||
break;
|
||||
@@ -908,6 +989,7 @@ gdk_event_get_root_coords (const GdkEvent *event,
|
||||
switch (event->type)
|
||||
{
|
||||
case GDK_MOTION_NOTIFY:
|
||||
case GDK_TOUCH_MOTION:
|
||||
x = event->motion.x_root;
|
||||
y = event->motion.y_root;
|
||||
break;
|
||||
@@ -919,6 +1001,8 @@ gdk_event_get_root_coords (const GdkEvent *event,
|
||||
case GDK_2BUTTON_PRESS:
|
||||
case GDK_3BUTTON_PRESS:
|
||||
case GDK_BUTTON_RELEASE:
|
||||
case GDK_TOUCH_PRESS:
|
||||
case GDK_TOUCH_RELEASE:
|
||||
x = event->button.x_root;
|
||||
y = event->button.y_root;
|
||||
break;
|
||||
@@ -1162,7 +1246,8 @@ gdk_event_get_axis (const GdkEvent *event,
|
||||
|
||||
switch (event->type)
|
||||
{
|
||||
case GDK_MOTION_NOTIFY:
|
||||
case GDK_MOTION_NOTIFY:
|
||||
case GDK_TOUCH_MOTION:
|
||||
x = event->motion.x;
|
||||
y = event->motion.y;
|
||||
break;
|
||||
@@ -1172,6 +1257,8 @@ gdk_event_get_axis (const GdkEvent *event,
|
||||
break;
|
||||
case GDK_BUTTON_PRESS:
|
||||
case GDK_BUTTON_RELEASE:
|
||||
case GDK_TOUCH_PRESS:
|
||||
case GDK_TOUCH_RELEASE:
|
||||
x = event->button.x;
|
||||
y = event->button.y;
|
||||
break;
|
||||
@@ -1193,12 +1280,15 @@ gdk_event_get_axis (const GdkEvent *event,
|
||||
return TRUE;
|
||||
}
|
||||
else if (event->type == GDK_BUTTON_PRESS ||
|
||||
event->type == GDK_BUTTON_RELEASE)
|
||||
event->type == GDK_BUTTON_RELEASE ||
|
||||
event->type == GDK_TOUCH_PRESS ||
|
||||
event->type == GDK_TOUCH_RELEASE)
|
||||
{
|
||||
device = event->button.device;
|
||||
axes = event->button.axes;
|
||||
}
|
||||
else if (event->type == GDK_MOTION_NOTIFY)
|
||||
else if (event->type == GDK_MOTION_NOTIFY ||
|
||||
event->type == GDK_TOUCH_MOTION)
|
||||
{
|
||||
device = event->motion.device;
|
||||
axes = event->motion.axes;
|
||||
@@ -1235,12 +1325,15 @@ gdk_event_set_device (GdkEvent *event,
|
||||
switch (event->type)
|
||||
{
|
||||
case GDK_MOTION_NOTIFY:
|
||||
case GDK_TOUCH_MOTION:
|
||||
event->motion.device = device;
|
||||
break;
|
||||
case GDK_BUTTON_PRESS:
|
||||
case GDK_2BUTTON_PRESS:
|
||||
case GDK_3BUTTON_PRESS:
|
||||
case GDK_BUTTON_RELEASE:
|
||||
case GDK_TOUCH_PRESS:
|
||||
case GDK_TOUCH_RELEASE:
|
||||
event->button.device = device;
|
||||
break;
|
||||
case GDK_SCROLL:
|
||||
@@ -1250,6 +1343,10 @@ gdk_event_set_device (GdkEvent *event,
|
||||
case GDK_PROXIMITY_OUT:
|
||||
event->proximity.device = device;
|
||||
break;
|
||||
case GDK_MULTITOUCH_ADDED:
|
||||
case GDK_MULTITOUCH_REMOVED:
|
||||
case GDK_MULTITOUCH_UPDATED:
|
||||
event->multitouch.device = device;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -1282,17 +1379,24 @@ gdk_event_get_device (const GdkEvent *event)
|
||||
switch (event->type)
|
||||
{
|
||||
case GDK_MOTION_NOTIFY:
|
||||
case GDK_TOUCH_MOTION:
|
||||
return event->motion.device;
|
||||
case GDK_BUTTON_PRESS:
|
||||
case GDK_2BUTTON_PRESS:
|
||||
case GDK_3BUTTON_PRESS:
|
||||
case GDK_BUTTON_RELEASE:
|
||||
case GDK_TOUCH_PRESS:
|
||||
case GDK_TOUCH_RELEASE:
|
||||
return event->button.device;
|
||||
case GDK_SCROLL:
|
||||
return event->scroll.device;
|
||||
case GDK_PROXIMITY_IN:
|
||||
case GDK_PROXIMITY_OUT:
|
||||
return event->proximity.device;
|
||||
case GDK_MULTITOUCH_ADDED:
|
||||
case GDK_MULTITOUCH_REMOVED:
|
||||
case GDK_MULTITOUCH_UPDATED:
|
||||
return event->multitouch.device;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -1301,10 +1405,13 @@ gdk_event_get_device (const GdkEvent *event)
|
||||
switch (event->type)
|
||||
{
|
||||
case GDK_MOTION_NOTIFY:
|
||||
case GDK_TOUCH_MOTION:
|
||||
case GDK_BUTTON_PRESS:
|
||||
case GDK_2BUTTON_PRESS:
|
||||
case GDK_3BUTTON_PRESS:
|
||||
case GDK_BUTTON_RELEASE:
|
||||
case GDK_TOUCH_PRESS:
|
||||
case GDK_TOUCH_RELEASE:
|
||||
case GDK_ENTER_NOTIFY:
|
||||
case GDK_LEAVE_NOTIFY:
|
||||
case GDK_FOCUS_CHANGE:
|
||||
@@ -1320,6 +1427,9 @@ gdk_event_get_device (const GdkEvent *event)
|
||||
case GDK_GRAB_BROKEN:
|
||||
case GDK_KEY_PRESS:
|
||||
case GDK_KEY_RELEASE:
|
||||
case GDK_MULTITOUCH_ADDED:
|
||||
case GDK_MULTITOUCH_REMOVED:
|
||||
case GDK_MULTITOUCH_UPDATED:
|
||||
{
|
||||
GdkDisplay *display;
|
||||
GdkDeviceManager *device_manager;
|
||||
@@ -1460,7 +1570,7 @@ gdk_event_request_motions (const GdkEventMotion *event)
|
||||
* also trigger a context menu if this modifier is pressed.
|
||||
*
|
||||
* This function should always be used instead of simply checking for
|
||||
* event->button == 3.
|
||||
* event->button == %GDK_BUTTON_SECONDARY.
|
||||
*
|
||||
* Returns: %TRUE if the event should trigger a context menu.
|
||||
*
|
||||
@@ -1479,7 +1589,7 @@ gdk_event_triggers_context_menu (const GdkEvent *event)
|
||||
|
||||
g_return_val_if_fail (GDK_IS_WINDOW (bevent->window), FALSE);
|
||||
|
||||
if (bevent->button == 3 &&
|
||||
if (bevent->button == GDK_BUTTON_SECONDARY &&
|
||||
! (bevent->state & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK)))
|
||||
return TRUE;
|
||||
|
||||
@@ -1489,7 +1599,7 @@ gdk_event_triggers_context_menu (const GdkEvent *event)
|
||||
GDK_MODIFIER_INTENT_CONTEXT_MENU);
|
||||
|
||||
if (modifier != 0 &&
|
||||
bevent->button == 1 &&
|
||||
bevent->button == GDK_BUTTON_PRIMARY &&
|
||||
! (bevent->state & (GDK_BUTTON2_MASK | GDK_BUTTON3_MASK)) &&
|
||||
(bevent->state & modifier))
|
||||
return TRUE;
|
||||
@@ -1686,6 +1796,138 @@ gdk_event_get_screen (const GdkEvent *event)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_event_get_touch_id:
|
||||
* @event: a #GdkEvent
|
||||
* @touch_id: return location of the touch ID of a touch event
|
||||
*
|
||||
* If @event if of type %GDK_TOUCH_MOTION, %GDK_TOUCH_PRESS or
|
||||
* %GDK_TOUCH_RELEASE, fills in @touch_id and returns %TRUE,
|
||||
* else it returns %FALSE.
|
||||
*
|
||||
* Returns: %TRUE if the touch ID can be extracted from @event.
|
||||
*
|
||||
* Since: 3.4
|
||||
**/
|
||||
gboolean
|
||||
gdk_event_get_touch_id (const GdkEvent *event,
|
||||
guint *touch_id)
|
||||
{
|
||||
if (!event)
|
||||
return FALSE;
|
||||
|
||||
if (event->type == GDK_TOUCH_MOTION)
|
||||
{
|
||||
if (touch_id)
|
||||
*touch_id = event->motion.touch_id;
|
||||
return TRUE;
|
||||
}
|
||||
else if (event->type == GDK_TOUCH_PRESS ||
|
||||
event->type == GDK_TOUCH_RELEASE)
|
||||
{
|
||||
if (touch_id)
|
||||
*touch_id = event->button.touch_id;
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (touch_id)
|
||||
*touch_id = 0;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_event_get_touch_area:
|
||||
* @event: a #GdkEvent
|
||||
*
|
||||
* This function takes a #GdkEvent coming from a touch device
|
||||
* (eg. gdk_event_get_source_device() returns a device of type
|
||||
* %GDK_SOURCE_TOUCH), and returns the area covered by the touch
|
||||
* as a #cairo_region_t. or %NULL if the device doesn't provide
|
||||
* this information, or the touch area information couldn't be
|
||||
* extracted from the event.
|
||||
*
|
||||
* <note><warning>Not all touch capable devices provide this
|
||||
* information, so provide fallbacks to this function returning
|
||||
* %NULL, even if the window receiving events is only meant
|
||||
* to react to touch events.</warning></note>
|
||||
*
|
||||
* Returns: (transfer full): the touch region, or %NULL if unavailable
|
||||
*
|
||||
* Since: 3.4
|
||||
**/
|
||||
cairo_region_t *
|
||||
gdk_event_get_touch_area (GdkEvent *event)
|
||||
{
|
||||
gdouble *axes, minor_axis, major_axis, orientation_axis;
|
||||
GdkAtom major, minor, orientation;
|
||||
GdkDevice *device;
|
||||
|
||||
g_return_val_if_fail (event != NULL, NULL);
|
||||
|
||||
device = gdk_event_get_source_device (event);
|
||||
|
||||
if (!device)
|
||||
return NULL;
|
||||
|
||||
if (event->type == GDK_MOTION_NOTIFY ||
|
||||
event->type == GDK_TOUCH_MOTION)
|
||||
axes = event->motion.axes;
|
||||
else if (event->type == GDK_BUTTON_PRESS ||
|
||||
event->type == GDK_2BUTTON_PRESS ||
|
||||
event->type == GDK_3BUTTON_PRESS ||
|
||||
event->type == GDK_BUTTON_RELEASE)
|
||||
axes = event->button.axes;
|
||||
else
|
||||
return NULL;
|
||||
|
||||
major = gdk_atom_intern_static_string ("Abs MT Touch Major");
|
||||
minor = gdk_atom_intern_static_string ("Abs MT Touch Minor");
|
||||
orientation = gdk_atom_intern_static_string ("Abs MT Orientation");
|
||||
|
||||
if (gdk_device_get_axis_value (device, axes, major, &major_axis) &&
|
||||
gdk_device_get_axis_value (device, axes, minor, &minor_axis) &&
|
||||
gdk_device_get_axis_value (device, axes, orientation, &orientation_axis))
|
||||
{
|
||||
cairo_rectangle_int_t rect;
|
||||
GdkScreen *screen;
|
||||
gdouble x, y;
|
||||
|
||||
/* FIXME: We're assuming the device is mapped to a single screen,
|
||||
* could lead to stretched/shrinked shapes in multimonitor, although
|
||||
* that'd be an unusual setup for touchscreens.
|
||||
*/
|
||||
screen = gdk_window_get_screen (event->any.window);
|
||||
gdk_event_get_coords (event, &x, &y);
|
||||
|
||||
if (orientation_axis == 0)
|
||||
{
|
||||
/* Orientation is horizontal */
|
||||
rect.width = (gint) gdk_screen_get_width (screen) * major_axis;
|
||||
rect.height = (gint) gdk_screen_get_height (screen) * minor_axis;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Orientation is vertical */
|
||||
rect.height = (gint) gdk_screen_get_height (screen) * major_axis;
|
||||
rect.width = (gint) gdk_screen_get_width (screen) * minor_axis;
|
||||
}
|
||||
|
||||
/* Something is wrong here */
|
||||
if (rect.width == 0 ||
|
||||
rect.height == 0)
|
||||
return NULL;
|
||||
|
||||
rect.x = x - rect.width / 2;
|
||||
rect.y = y - rect.height / 2;
|
||||
|
||||
return cairo_region_create_rectangle (&rect);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_set_show_events:
|
||||
* @show_events: %TRUE to output event debugging information.
|
||||
|
||||
139
gdk/gdkevents.h
139
gdk/gdkevents.h
@@ -35,6 +35,7 @@
|
||||
#include <gdk/gdktypes.h>
|
||||
#include <gdk/gdkdnd.h>
|
||||
#include <gdk/gdkdevice.h>
|
||||
#include <gdk/gdktouchcluster.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@@ -94,6 +95,37 @@ G_BEGIN_DECLS
|
||||
*/
|
||||
#define GDK_EVENT_STOP (TRUE)
|
||||
|
||||
/**
|
||||
* GDK_BUTTON_PRIMARY:
|
||||
*
|
||||
* 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)
|
||||
|
||||
/**
|
||||
* GDK_BUTTON_MIDDLE:
|
||||
*
|
||||
* The middle button.
|
||||
*
|
||||
* Since: 3.4
|
||||
*/
|
||||
#define GDK_BUTTON_MIDDLE (2)
|
||||
|
||||
/**
|
||||
* GDK_BUTTON_SECONDARY:
|
||||
*
|
||||
* 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 _GdkEventVisibility GdkEventVisibility;
|
||||
@@ -112,6 +144,7 @@ typedef struct _GdkEventDND GdkEventDND;
|
||||
typedef struct _GdkEventWindowState GdkEventWindowState;
|
||||
typedef struct _GdkEventSetting GdkEventSetting;
|
||||
typedef struct _GdkEventGrabBroken GdkEventGrabBroken;
|
||||
typedef struct _GdkEventMultiTouch GdkEventMultiTouch;
|
||||
|
||||
typedef union _GdkEvent GdkEvent;
|
||||
|
||||
@@ -232,6 +265,18 @@ typedef GdkFilterReturn (*GdkFilterFunc) (GdkXEvent *xevent,
|
||||
* was added in 2.8.
|
||||
* @GDK_DAMAGE: the content of the window has been changed. This event type
|
||||
* was added in 2.14.
|
||||
* @GDK_TOUCH_MOTION: A touch device has been updated. This event type was
|
||||
* added in 3.4.
|
||||
* @GDK_TOUCH_PRESS: A new touch stream has just started. This event type was
|
||||
* added in 3.4.
|
||||
* @GDK_TOUCH_RELEASE: A touch stream has finished. This event type was
|
||||
* added in 3.4.
|
||||
* @GDK_MULTITOUCH_ADDED: A touch ID was added to a #GdkTouchCluster. This
|
||||
* event type was added in 3.4.
|
||||
* @GDK_MULTITOUCH_UPDATED: A touch within a #GdkTouchCluster has been updated.
|
||||
* This event type was added in 3.4.
|
||||
* @GDK_MULTITOUCH_REMOVED: A touch ID was removed from a #GdkTouchCluster. This
|
||||
* event type was added in 3.4.
|
||||
* @GDK_EVENT_LAST: marks the end of the GdkEventType enumeration. Added in 2.18
|
||||
*
|
||||
* Specifies the type of the event.
|
||||
@@ -279,6 +324,12 @@ typedef enum
|
||||
GDK_OWNER_CHANGE = 34,
|
||||
GDK_GRAB_BROKEN = 35,
|
||||
GDK_DAMAGE = 36,
|
||||
GDK_TOUCH_MOTION = 37,
|
||||
GDK_TOUCH_PRESS = 38,
|
||||
GDK_TOUCH_RELEASE = 39,
|
||||
GDK_MULTITOUCH_ADDED = 40,
|
||||
GDK_MULTITOUCH_UPDATED = 41,
|
||||
GDK_MULTITOUCH_REMOVED = 42,
|
||||
GDK_EVENT_LAST /* helper variable for decls */
|
||||
} GdkEventType;
|
||||
|
||||
@@ -354,6 +405,13 @@ typedef enum
|
||||
* @GDK_CROSSING_GTK_UNGRAB: crossing because a GTK+ grab is deactivated.
|
||||
* @GDK_CROSSING_STATE_CHANGED: crossing because a GTK+ widget changed
|
||||
* state (e.g. sensitivity).
|
||||
* @GDK_CROSSING_TOUCH_PRESS: crossing because a touch device was pressed,
|
||||
* this event is synthetic as the pointer might have not left the window.
|
||||
* @GDK_CROSSING_TOUCH_RELEASE: crossing because a touch device was released.
|
||||
* this event is synthetic as the pointer might have not left the window.
|
||||
* @GDK_CROSSING_DEVICE_SWITCH: crossing because of a device switch (i.e.
|
||||
* a mouse taking control of the pointer after a touch device), this event
|
||||
* is synthetic as the pointer didn't leave the window.
|
||||
*
|
||||
* Specifies the crossing mode for #GdkEventCrossing.
|
||||
*/
|
||||
@@ -364,7 +422,10 @@ typedef enum
|
||||
GDK_CROSSING_UNGRAB,
|
||||
GDK_CROSSING_GTK_GRAB,
|
||||
GDK_CROSSING_GTK_UNGRAB,
|
||||
GDK_CROSSING_STATE_CHANGED
|
||||
GDK_CROSSING_STATE_CHANGED,
|
||||
GDK_CROSSING_TOUCH_PRESS,
|
||||
GDK_CROSSING_TOUCH_RELEASE,
|
||||
GDK_CROSSING_DEVICE_SWITCH
|
||||
} GdkCrossingMode;
|
||||
|
||||
/**
|
||||
@@ -521,8 +582,13 @@ struct _GdkEventVisibility
|
||||
* screen.
|
||||
* @y_root: the y coordinate of the pointer relative to the root of the
|
||||
* screen.
|
||||
* @touch_id: touch ID, only meaningful if event is of type %GDK_TOUCH_MOTION.
|
||||
*
|
||||
* Generated when the pointer moves.
|
||||
* Generated when the pointer/touch moves.
|
||||
*
|
||||
* If the event has a type of %GDK_TOUCH_MOTION, this event will
|
||||
* pertain to a sequence identified by gdk_event_get_touch_id().
|
||||
* With multitouch devices, there may be several ongoing sequences.
|
||||
*/
|
||||
struct _GdkEventMotion
|
||||
{
|
||||
@@ -537,12 +603,63 @@ struct _GdkEventMotion
|
||||
gint16 is_hint;
|
||||
GdkDevice *device;
|
||||
gdouble x_root, y_root;
|
||||
guint touch_id;
|
||||
};
|
||||
|
||||
/**
|
||||
* GdkEventMultiTouch:
|
||||
* @type: the type of the event (%GDK_MULTITOUCH_ADDED, %GDK_MULTITOUCH_UPDATED
|
||||
* or %GDK_MULTITOUCH_REMOVED).
|
||||
* @window: the window which received the event.
|
||||
* @send_event: %TRUE if the event was sent explicitly (e.g. using
|
||||
* <function>XSendEvent</function>).
|
||||
* @time: the time of the event in milliseconds.
|
||||
* @state: (type GdkModifierType): a bit-mask representing the state of
|
||||
* the modifier keys (e.g. Control, Shift and Alt) and the pointer
|
||||
* buttons. See #GdkModifierType.
|
||||
* @device: the device where the event originated.
|
||||
* @group: the #GdkTouchCluster containing the touches that generated this event
|
||||
* @events: an array of events of type %GDK_TOUCH_MOTION for the touches in @group
|
||||
* @updated_touch_id: the touch ID that caused this event to be generated
|
||||
* @n_events: the number of events in @events
|
||||
* @n_updated_event: the index in @events of the event corresponding to
|
||||
* @updated_touch_id, or -1 for %GDK_MULTITOUCH_REMOVED events.
|
||||
*
|
||||
* Used for multitouch events. The @type field will be one of
|
||||
* %GDK_MULTITOUCH_ADDED, %GDK_MULTITOUCH_UPDATED or
|
||||
* %GDK_MULTITOUCH_REMOVED.
|
||||
*
|
||||
* Multitouch events group the events from the touches in a
|
||||
* #GdkTouchCluster, so one of these events is generated
|
||||
* whenever a touch ID generates a new event, or a touch ID
|
||||
* is added or removed.
|
||||
*
|
||||
* For any given touch ID, %GDK_MULTITOUCH_ADDED and
|
||||
* %GDK_MULTITOUCH_REMOVED events are always paired,
|
||||
* with any number of %GDK_MULTITOUCH_UPDATED
|
||||
* events in between. The minimum event stream is an
|
||||
* added/removed pair.
|
||||
*/
|
||||
struct _GdkEventMultiTouch
|
||||
{
|
||||
GdkEventType type;
|
||||
GdkWindow *window;
|
||||
gint8 send_event;
|
||||
guint32 time;
|
||||
guint state;
|
||||
GdkDevice *device;
|
||||
GdkTouchCluster *group;
|
||||
GdkEventMotion **events;
|
||||
guint updated_touch_id;
|
||||
gint8 n_events;
|
||||
gint8 n_updated_event;
|
||||
};
|
||||
|
||||
/**
|
||||
* GdkEventButton:
|
||||
* @type: the type of the event (%GDK_BUTTON_PRESS, %GDK_2BUTTON_PRESS,
|
||||
* %GDK_3BUTTON_PRESS or %GDK_BUTTON_RELEASE).
|
||||
* %GDK_3BUTTON_PRESS, %GDK_BUTTON_RELEASE, %GDK_TOUCH_PRESS or
|
||||
* %GDK_TOUCH_RELEASE).
|
||||
* @window: the window which received the event.
|
||||
* @send_event: %TRUE if the event was sent explicitly (e.g. using
|
||||
* <function>XSendEvent</function>).
|
||||
@@ -563,10 +680,13 @@ struct _GdkEventMotion
|
||||
* screen.
|
||||
* @y_root: the y coordinate of the pointer relative to the root of the
|
||||
* screen.
|
||||
* @touch_id: touch ID, only meaningful if event is of type %GDK_TOUCH_PRESS
|
||||
* or %GDK_TOUCH_RELEASE.
|
||||
*
|
||||
* Used for button press and button release events. The
|
||||
* @type field will be one of %GDK_BUTTON_PRESS,
|
||||
* %GDK_2BUTTON_PRESS, %GDK_3BUTTON_PRESS, and %GDK_BUTTON_RELEASE.
|
||||
* %GDK_2BUTTON_PRESS, %GDK_3BUTTON_PRESS, %GDK_BUTTON_RELEASE,
|
||||
* %GDK_TOUCH_PRESS and %GDK_TOUCH_RELEASE.
|
||||
*
|
||||
* Double and triple-clicks result in a sequence of events being received.
|
||||
* For double-clicks the order of events will be:
|
||||
@@ -598,6 +718,11 @@ struct _GdkEventMotion
|
||||
* For a double click to occur, the second button press must occur within
|
||||
* 1/4 of a second of the first. For a triple click to occur, the third
|
||||
* button press must also occur within 1/2 second of the first button press.
|
||||
*
|
||||
* If the event has a type of %GDK_TOUCH_PRESS or %GDK_TOUCH_RELEASE,
|
||||
* this event will pertain to a sequence identified by
|
||||
* gdk_event_get_touch_id(). With multitouch devices, there may be
|
||||
* several ongoing sequences.
|
||||
*/
|
||||
struct _GdkEventButton
|
||||
{
|
||||
@@ -612,6 +737,7 @@ struct _GdkEventButton
|
||||
guint button;
|
||||
GdkDevice *device;
|
||||
gdouble x_root, y_root;
|
||||
guint touch_id;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -1055,6 +1181,7 @@ union _GdkEvent
|
||||
GdkEventWindowState window_state;
|
||||
GdkEventSetting setting;
|
||||
GdkEventGrabBroken grab_broken;
|
||||
GdkEventMultiTouch multitouch;
|
||||
};
|
||||
|
||||
GType gdk_event_get_type (void) G_GNUC_CONST;
|
||||
@@ -1119,6 +1246,10 @@ void gdk_event_set_screen (GdkEvent *event,
|
||||
GdkScreen *screen);
|
||||
GdkScreen *gdk_event_get_screen (const GdkEvent *event);
|
||||
|
||||
gboolean gdk_event_get_touch_id (const GdkEvent *event,
|
||||
guint *touch_id);
|
||||
cairo_region_t * gdk_event_get_touch_area (GdkEvent *event);
|
||||
|
||||
void gdk_set_show_events (gboolean show_events);
|
||||
gboolean gdk_get_show_events (void);
|
||||
|
||||
|
||||
@@ -150,7 +150,13 @@ typedef enum
|
||||
/* Following flag is set for events on the event queue during
|
||||
* translation and cleared afterwards.
|
||||
*/
|
||||
GDK_EVENT_PENDING = 1 << 0
|
||||
GDK_EVENT_PENDING = 1 << 0,
|
||||
|
||||
/* The following flag is set for:
|
||||
* 1) touch events emulating pointer events
|
||||
* 2) pointer events being emulated by a touch sequence.
|
||||
*/
|
||||
GDK_EVENT_POINTER_EMULATED = 1 << 1
|
||||
} GdkEventFlags;
|
||||
|
||||
struct _GdkEventPrivate
|
||||
@@ -260,6 +266,12 @@ struct _GdkWindow
|
||||
gulong device_changed_handler_id;
|
||||
|
||||
guint num_offscreen_children;
|
||||
|
||||
/* Store of latest per-touch events, keys are
|
||||
* GdkDevices, values are hashtables of touchID/info
|
||||
*/
|
||||
GHashTable *touch_event_tracker;
|
||||
GList *touch_clusters;
|
||||
};
|
||||
|
||||
#define GDK_WINDOW_TYPE(d) (((GDK_WINDOW (d)))->window_type)
|
||||
@@ -275,6 +287,10 @@ GdkEvent* _gdk_event_unqueue (GdkDisplay *display);
|
||||
void _gdk_event_filter_unref (GdkWindow *window,
|
||||
GdkEventFilter *filter);
|
||||
|
||||
void _gdk_event_set_pointer_emulated (GdkEvent *event,
|
||||
gboolean emulated);
|
||||
gboolean _gdk_event_get_pointer_emulated (GdkEvent *event);
|
||||
|
||||
void _gdk_event_emit (GdkEvent *event);
|
||||
GList* _gdk_event_queue_find_first (GdkDisplay *display);
|
||||
void _gdk_event_queue_remove_link (GdkDisplay *display,
|
||||
@@ -318,6 +334,9 @@ gboolean _gdk_window_update_viewable (GdkWindow *window);
|
||||
|
||||
void _gdk_window_process_updates_recurse (GdkWindow *window,
|
||||
cairo_region_t *expose_region);
|
||||
gboolean _gdk_window_finish_touch_id (GdkWindow *window,
|
||||
GdkDevice *device,
|
||||
guint touch_id);
|
||||
|
||||
void _gdk_screen_close (GdkScreen *screen);
|
||||
|
||||
|
||||
@@ -145,19 +145,12 @@ _gdk_offscreen_window_create_surface (GdkWindow *offscreen,
|
||||
{
|
||||
cairo_surface_t *similar;
|
||||
cairo_surface_t *surface;
|
||||
cairo_content_t content = CAIRO_CONTENT_COLOR;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_OFFSCREEN_WINDOW (offscreen->impl), NULL);
|
||||
|
||||
similar = _gdk_window_ref_cairo_surface (offscreen->parent);
|
||||
|
||||
if (gdk_window_get_visual (offscreen) ==
|
||||
gdk_screen_get_rgba_visual (gdk_window_get_screen (offscreen)))
|
||||
{
|
||||
content = CAIRO_CONTENT_COLOR_ALPHA;
|
||||
}
|
||||
|
||||
surface = cairo_surface_create_similar (similar, content, width, height);
|
||||
surface = cairo_surface_create_similar (similar, CAIRO_CONTENT_COLOR_ALPHA, width, height);
|
||||
|
||||
cairo_surface_destroy (similar);
|
||||
|
||||
|
||||
448
gdk/gdktouchcluster.c
Normal file
448
gdk/gdktouchcluster.c
Normal file
@@ -0,0 +1,448 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2011 Carlos Garnacho <carlosg@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gdktouchcluster.h"
|
||||
#include "gdkintl.h"
|
||||
|
||||
/**
|
||||
* SECTION:touchcluster
|
||||
* @Short_description: Multitouch handling
|
||||
* @Title: Multitouch
|
||||
* @See_also: #GdkEventMultiTouch
|
||||
*
|
||||
* #GdkTouchCluster is an object that gathers touch IDs from a
|
||||
* #GdkDevice, in order to send #GdkEventMultiTouch events
|
||||
* whenever a touch ID that is contained in the cluster sends
|
||||
* an event.
|
||||
*
|
||||
* #GdkTouchCluster<!-- -->s are always associated to a window,
|
||||
* you need to create them through gdk_window_create_touch_cluster(),
|
||||
* and free them through gdk_window_remove_touch_cluster().
|
||||
*
|
||||
* Touch IDs from devices can be obtained from %GDK_TOUCH_PRESS,
|
||||
* %GDK_TOUCH_MOTION or %GDK_TOUCH_RELEASE events through
|
||||
* gdk_event_get_touch_id(), and then be added via
|
||||
* gdk_touch_cluster_add_touch(). Note that touch IDs are
|
||||
* very transient, and they must be dealt with as such.
|
||||
* touch IDs must not be stored after a GDK_TOUCH_RELEASE,
|
||||
* and should always be retrieved from the events being
|
||||
* currently received.
|
||||
*
|
||||
* <example>
|
||||
* <title>Adding touch IDs to a cluster in a GTK+ widget</title>
|
||||
* <programlisting>
|
||||
* static gboolean
|
||||
* widget_button_press (GtkWidget *widget,
|
||||
* GdkEvent *event)
|
||||
* {
|
||||
* guint touch_id;
|
||||
*
|
||||
* if (gdk_event_get_touch_id (event, &touch_id))
|
||||
* {
|
||||
* /<!-- -->* It is a touch event, delegate processing
|
||||
* * to the multitouch event handler
|
||||
* *<!-- -->/
|
||||
* gdk_touch_cluster_add_touch (priv->touch_cluster, touch_id);
|
||||
* return TRUE;
|
||||
* }
|
||||
*
|
||||
* /<!-- -->* Normal button processing *<!-- -->/
|
||||
* ...
|
||||
* }
|
||||
* </programlisting>
|
||||
* </example>
|
||||
*
|
||||
* Anytime a touch ID is within a cluster, no %GDK_TOUCH_PRESS,
|
||||
* %GDK_TOUCH_MOTION or %GDK_TOUCH_RELEASE events will happen
|
||||
* for the individual touch. The event will be available instead
|
||||
* as part of the #GdkMultitouchEvent that will be emitted. This
|
||||
* will hold true until gdk_touch_cluster_remove_touch() is
|
||||
* called for it. Note that GTK+ will automatically take a
|
||||
* touch ID out of any cluster if %GDK_TOUCH_RELEASE is gotten
|
||||
* internally.
|
||||
*
|
||||
* <example>
|
||||
* <title>Typical multitouch event handler</title>
|
||||
* <programlisting>
|
||||
* static gboolean
|
||||
* widget_multitouch_event (GtkWidget *widget,
|
||||
* GdkEvent *event)
|
||||
* {
|
||||
* if (event->type == GDK_MULTITOUCH_ADDED ||
|
||||
* event->type == GDK_MULTITOUCH_REMOVED)
|
||||
* {
|
||||
* /<!-- -->* Update control mode based
|
||||
* * on the current number of touches
|
||||
* *<!-- -->/
|
||||
* priv->control_mode = update_control_mode (event->multitouch.n_events);
|
||||
* }
|
||||
* else
|
||||
* {
|
||||
* /<!-- -->* A touch ID in the cluster has updated
|
||||
* * its coordinates, update widget based on the
|
||||
* * current control mode.
|
||||
* *<!-- -->/
|
||||
* update_view (widget, priv->control_mode,
|
||||
* event->multitouch.events,
|
||||
* event->multitouch.n_events);
|
||||
* }
|
||||
*
|
||||
* return TRUE;
|
||||
* }
|
||||
* </programlisting>
|
||||
* </example>
|
||||
*/
|
||||
|
||||
typedef struct GdkTouchClusterPrivate GdkTouchClusterPrivate;
|
||||
|
||||
struct GdkTouchClusterPrivate
|
||||
{
|
||||
GdkDevice *device;
|
||||
GArray *touches;
|
||||
};
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_DEVICE
|
||||
};
|
||||
|
||||
enum {
|
||||
TOUCH_ADDED,
|
||||
TOUCH_REMOVED,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static guint signals [LAST_SIGNAL] = { 0 };
|
||||
|
||||
static void gdk_touch_cluster_finalize (GObject *object);
|
||||
static void gdk_touch_cluster_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec);
|
||||
static void gdk_touch_cluster_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec);
|
||||
|
||||
|
||||
G_DEFINE_TYPE (GdkTouchCluster, gdk_touch_cluster, G_TYPE_OBJECT)
|
||||
|
||||
static void
|
||||
gdk_touch_cluster_class_init (GdkTouchClusterClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->finalize = gdk_touch_cluster_finalize;
|
||||
object_class->get_property = gdk_touch_cluster_get_property;
|
||||
object_class->set_property = gdk_touch_cluster_set_property;
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_DEVICE,
|
||||
g_param_spec_object ("device",
|
||||
P_("Device"),
|
||||
P_("Device attached to the cluster"),
|
||||
GDK_TYPE_DEVICE,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
|
||||
signals[TOUCH_ADDED] =
|
||||
g_signal_new (g_intern_static_string ("touch-added"),
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GdkTouchClusterClass, touch_added),
|
||||
NULL, NULL,
|
||||
g_cclosure_marshal_VOID__UINT,
|
||||
G_TYPE_NONE, 1, G_TYPE_UINT);
|
||||
signals[TOUCH_REMOVED] =
|
||||
g_signal_new (g_intern_static_string ("touch-removed"),
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GdkTouchClusterClass, touch_removed),
|
||||
NULL, NULL,
|
||||
g_cclosure_marshal_VOID__UINT,
|
||||
G_TYPE_NONE, 1, G_TYPE_UINT);
|
||||
|
||||
g_type_class_add_private (object_class, sizeof (GdkTouchClusterPrivate));
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_touch_cluster_init (GdkTouchCluster *cluster)
|
||||
{
|
||||
GdkTouchClusterPrivate *priv;
|
||||
|
||||
priv = cluster->priv = G_TYPE_INSTANCE_GET_PRIVATE (cluster,
|
||||
GDK_TYPE_TOUCH_CLUSTER,
|
||||
GdkTouchClusterPrivate);
|
||||
priv->touches = g_array_new (FALSE, FALSE, sizeof (guint));
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_touch_cluster_finalize (GObject *object)
|
||||
{
|
||||
GdkTouchClusterPrivate *priv;
|
||||
|
||||
priv = GDK_TOUCH_CLUSTER (object)->priv;
|
||||
g_array_free (priv->touches, TRUE);
|
||||
|
||||
G_OBJECT_CLASS (gdk_touch_cluster_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_touch_cluster_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_DEVICE:
|
||||
gdk_touch_cluster_set_device (GDK_TOUCH_CLUSTER (object),
|
||||
g_value_get_object (value));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_touch_cluster_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GdkTouchClusterPrivate *priv;
|
||||
|
||||
priv = GDK_TOUCH_CLUSTER (object)->priv;
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_DEVICE:
|
||||
g_value_set_object (value, priv->device);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_touch_cluster_add_touch:
|
||||
* @cluster: a #GdkTouchCluster
|
||||
* @touch_id: a touch ID from a touch event
|
||||
*
|
||||
* Adds a touch ID to @cluster, so it will generate a
|
||||
* %GDK_MULTITOUCH_ADDED event, followed by %GDK_MULTITOUCH_UPDATED
|
||||
* events whenever this touch ID is updated.
|
||||
*
|
||||
* If @touch_id already pertained to another #GdkTouchCluster, it
|
||||
* will be removed from it, generating a %GDK_MULTITOUCH_REMOVED
|
||||
* for that another cluster.
|
||||
*
|
||||
* Since: 3.4
|
||||
**/
|
||||
void
|
||||
gdk_touch_cluster_add_touch (GdkTouchCluster *cluster,
|
||||
guint touch_id)
|
||||
{
|
||||
GdkTouchClusterPrivate *priv;
|
||||
gint i;
|
||||
|
||||
g_return_if_fail (GDK_IS_TOUCH_CLUSTER (cluster));
|
||||
|
||||
priv = cluster->priv;
|
||||
|
||||
for (i = 0; i < priv->touches->len; i++)
|
||||
{
|
||||
if (touch_id == g_array_index (priv->touches, guint, i))
|
||||
return;
|
||||
}
|
||||
|
||||
g_array_append_val (priv->touches, touch_id);
|
||||
g_signal_emit (cluster, signals [TOUCH_ADDED], 0, touch_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_touch_cluster_remove_touch:
|
||||
* @cluster: a #GdkTouchCluster
|
||||
* @touch_id: a touch ID from a touch event
|
||||
*
|
||||
* Removes a touch ID from @cluster, generating a %GDK_MULTITOUCH_REMOVED
|
||||
* event for @cluster, and causing any further input from @touch_id
|
||||
* to be reported trough %GDK_TOUCH_MOTION events.
|
||||
*
|
||||
* <note><para>
|
||||
* Note that GTK+ automatically removes a touch ID from any cluster
|
||||
* if a %GDK_TOUCH_RELEASE event is gotten internally.
|
||||
* </para></note>
|
||||
*
|
||||
* Since: 3.4
|
||||
**/
|
||||
void
|
||||
gdk_touch_cluster_remove_touch (GdkTouchCluster *cluster,
|
||||
guint touch_id)
|
||||
{
|
||||
GdkTouchClusterPrivate *priv;
|
||||
gint i;
|
||||
|
||||
g_return_if_fail (GDK_IS_TOUCH_CLUSTER (cluster));
|
||||
|
||||
priv = cluster->priv;
|
||||
|
||||
for (i = 0; i < priv->touches->len; i++)
|
||||
{
|
||||
if (touch_id == g_array_index (priv->touches, guint, i))
|
||||
{
|
||||
g_array_remove_index_fast (priv->touches, i);
|
||||
g_signal_emit (cluster, signals [TOUCH_REMOVED], 0, touch_id);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_touch_cluster_remove_all:
|
||||
* @cluster: a #GdkTouchCluster
|
||||
*
|
||||
* Removes all touch IDs from @cluster.
|
||||
*
|
||||
* Since: 3.4
|
||||
**/
|
||||
void
|
||||
gdk_touch_cluster_remove_all (GdkTouchCluster *cluster)
|
||||
{
|
||||
GdkTouchClusterPrivate *priv;
|
||||
guint touch_id;
|
||||
gint i;
|
||||
|
||||
g_return_if_fail (GDK_IS_TOUCH_CLUSTER (cluster));
|
||||
|
||||
priv = cluster->priv;
|
||||
|
||||
for (i = priv->touches->len - 1; i >= 0; i--)
|
||||
{
|
||||
touch_id = g_array_index (priv->touches, guint, i);
|
||||
g_signal_emit (cluster, signals [TOUCH_REMOVED], 0, touch_id);
|
||||
g_array_remove_index_fast (priv->touches, i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* gdk_touch_cluster_get_touches:
|
||||
* @cluster: a #GdkTouchCluster
|
||||
* @length: return location for the number of touches returned
|
||||
*
|
||||
* Returns the list of touches as an array of @guint.
|
||||
*
|
||||
* Returns: (transfer full) (array zero-terminated=0 length=length) (element-type uint): A list of touch IDs.
|
||||
*
|
||||
* Since: 3.4
|
||||
**/
|
||||
guint *
|
||||
gdk_touch_cluster_get_touches (GdkTouchCluster *cluster,
|
||||
gint *len)
|
||||
{
|
||||
GdkTouchClusterPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_TOUCH_CLUSTER (cluster), NULL);
|
||||
|
||||
priv = cluster->priv;
|
||||
|
||||
if (len)
|
||||
*len = (gint) priv->touches->len;
|
||||
|
||||
return g_memdup (priv->touches->data,
|
||||
sizeof (guint) * priv->touches->len);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_touch_cluster_get_n_touches:
|
||||
* @cluster: a #GdkTouchCluster
|
||||
*
|
||||
* Returns the number of touches contained in @cluster.
|
||||
*
|
||||
* Returns: The number of touches.
|
||||
*
|
||||
* Since: 3.4
|
||||
**/
|
||||
gint
|
||||
gdk_touch_cluster_get_n_touches (GdkTouchCluster *cluster)
|
||||
{
|
||||
GdkTouchClusterPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_TOUCH_CLUSTER (cluster), 0);
|
||||
|
||||
priv = cluster->priv;
|
||||
return (gint) priv->touches->len;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_touch_cluster_set_device:
|
||||
* @cluster: a #GdkTouchCluster
|
||||
* @device: a #GdkDevice
|
||||
*
|
||||
* Sets the current device associated to @cluster, all contained
|
||||
* touch IDs must pertain to this device. As a consequence,
|
||||
* gdk_touch_cluster_remove_all() will be called on @cluster
|
||||
* if the current device changes.
|
||||
*
|
||||
* Since: 3.4
|
||||
**/
|
||||
void
|
||||
gdk_touch_cluster_set_device (GdkTouchCluster *cluster,
|
||||
GdkDevice *device)
|
||||
{
|
||||
GdkTouchClusterPrivate *priv;
|
||||
|
||||
g_return_if_fail (GDK_IS_TOUCH_CLUSTER (cluster));
|
||||
g_return_if_fail (!device || GDK_IS_DEVICE (device));
|
||||
|
||||
priv = cluster->priv;
|
||||
|
||||
if (priv->device != device)
|
||||
gdk_touch_cluster_remove_all (cluster);
|
||||
|
||||
priv->device = device;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_touch_cluster_get_device:
|
||||
* @cluster: a #GdkTouchCluster
|
||||
*
|
||||
* Returns the slave/floating device this touch cluster pertains to,
|
||||
* only touch IDs from this device can be included in @cluster.
|
||||
* the #GdkDevice will typically have the %GDK_SOURCE_TOUCH input source.
|
||||
*
|
||||
* Returns: (transfer none): The #GdkDevice generating the contained touch IDs
|
||||
*
|
||||
* Since: 3.4
|
||||
**/
|
||||
GdkDevice *
|
||||
gdk_touch_cluster_get_device (GdkTouchCluster *cluster)
|
||||
{
|
||||
GdkTouchClusterPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_TOUCH_CLUSTER (cluster), NULL);
|
||||
|
||||
priv = cluster->priv;
|
||||
return priv->device;
|
||||
}
|
||||
71
gdk/gdktouchcluster.h
Normal file
71
gdk/gdktouchcluster.h
Normal file
@@ -0,0 +1,71 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2011 Carlos Garnacho <carlosg@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GDK_TOUCH_CLUSTER_H__
|
||||
#define __GDK_TOUCH_CLUSTER_H__
|
||||
|
||||
#include <glib-object.h>
|
||||
#include <gdk/gdkdevice.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GDK_TYPE_TOUCH_CLUSTER (gdk_touch_cluster_get_type ())
|
||||
#define GDK_TOUCH_CLUSTER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDK_TYPE_TOUCH_CLUSTER, GdkTouchCluster))
|
||||
#define GDK_IS_TOUCH_CLUSTER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDK_TYPE_TOUCH_CLUSTER))
|
||||
|
||||
typedef struct _GdkTouchCluster GdkTouchCluster;
|
||||
typedef struct _GdkTouchClusterClass GdkTouchClusterClass;
|
||||
|
||||
struct _GdkTouchCluster
|
||||
{
|
||||
GObject parent_instance;
|
||||
gpointer priv;
|
||||
};
|
||||
|
||||
struct _GdkTouchClusterClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
|
||||
void (* touch_added) (GdkTouchCluster *cluster,
|
||||
guint touch_id);
|
||||
void (* touch_removed) (GdkTouchCluster *cluster,
|
||||
guint touch_id);
|
||||
|
||||
gpointer padding[16];
|
||||
};
|
||||
|
||||
GType gdk_touch_cluster_get_type (void) G_GNUC_CONST;
|
||||
|
||||
void gdk_touch_cluster_add_touch (GdkTouchCluster *cluster,
|
||||
guint touch_id);
|
||||
void gdk_touch_cluster_remove_touch (GdkTouchCluster *cluster,
|
||||
guint touch_id);
|
||||
void gdk_touch_cluster_remove_all (GdkTouchCluster *cluster);
|
||||
|
||||
guint * gdk_touch_cluster_get_touches (GdkTouchCluster *cluster,
|
||||
gint *length);
|
||||
gint gdk_touch_cluster_get_n_touches (GdkTouchCluster *cluster);
|
||||
|
||||
void gdk_touch_cluster_set_device (GdkTouchCluster *cluster,
|
||||
GdkDevice *device);
|
||||
GdkDevice * gdk_touch_cluster_get_device (GdkTouchCluster *cluster);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_TOUCH_CLUSTER_H__ */
|
||||
@@ -350,6 +350,7 @@ typedef enum
|
||||
* @GDK_SUBSTRUCTURE_MASK: receive events about window configuration changes of
|
||||
* child windows
|
||||
* @GDK_SCROLL_MASK: receive scroll events
|
||||
* @GDK_TOUCH_MASK: receive (multi)touch events
|
||||
* @GDK_ALL_EVENTS_MASK: the combination of all the above event masks.
|
||||
*
|
||||
* A set of bit-flags to indicate which events a window is to receive.
|
||||
@@ -365,6 +366,13 @@ typedef enum
|
||||
* some of which are marked as a hint (the is_hint member is %TRUE).
|
||||
* To receive more motion events after a motion hint event, the application
|
||||
* needs to asks for more, by calling gdk_event_request_motions().
|
||||
*
|
||||
* If %GDK_TOUCH_MASK is enabled, the window will receive (multi)touch events
|
||||
* from touch-enabled devices. Those will come as sequences #GdkEventMotion
|
||||
* with type %GDK_TOUCH_MOTION, enclosed by 2 #GdkEventButton events with
|
||||
* type %GDK_TOUCH_PRESS / %GDK_TOUCH_RELEASE. gdk_event_get_touch_id() will
|
||||
* return the touch ID on those events, so different sequences may be
|
||||
* distinguished.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
@@ -389,7 +397,8 @@ typedef enum
|
||||
GDK_PROXIMITY_OUT_MASK = 1 << 19,
|
||||
GDK_SUBSTRUCTURE_MASK = 1 << 20,
|
||||
GDK_SCROLL_MASK = 1 << 21,
|
||||
GDK_ALL_EVENTS_MASK = 0x3FFFFE
|
||||
GDK_TOUCH_MASK = 1 << 22,
|
||||
GDK_ALL_EVENTS_MASK = 0x3FFFFF
|
||||
} GdkEventMask;
|
||||
|
||||
/**
|
||||
|
||||
819
gdk/gdkwindow.c
819
gdk/gdkwindow.c
File diff suppressed because it is too large
Load Diff
@@ -33,6 +33,7 @@
|
||||
|
||||
#include <gdk/gdktypes.h>
|
||||
#include <gdk/gdkevents.h>
|
||||
#include <gdk/gdktouchcluster.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@@ -878,6 +879,12 @@ void gdk_window_set_support_multidevice (GdkWindow *window,
|
||||
gboolean support_multidevice);
|
||||
gboolean gdk_window_get_support_multidevice (GdkWindow *window);
|
||||
|
||||
/* Multitouch support */
|
||||
GdkTouchCluster * gdk_window_create_touch_cluster (GdkWindow *window,
|
||||
GdkDevice *device);
|
||||
void gdk_window_remove_touch_cluster (GdkWindow *window,
|
||||
GdkTouchCluster *cluster);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_WINDOW_H__ */
|
||||
|
||||
@@ -180,7 +180,7 @@ create_builtin_cursor (GdkCursorType cursor_type)
|
||||
|
||||
cursor = gdk_quartz_cursor_new_from_nscursor (nscursor, GDK_CURSOR_IS_PIXMAP);
|
||||
|
||||
cached_xcursors[cursor_type] = gdk_cursor_ref (cursor);
|
||||
cached_xcursors[cursor_type] = g_object_ref (cursor);
|
||||
|
||||
GDK_QUARTZ_RELEASE_POOL;
|
||||
|
||||
@@ -243,7 +243,7 @@ _gdk_quartz_display_get_cursor_for_type (GdkDisplay *display,
|
||||
case GDK_BLANK_CURSOR:
|
||||
return create_blank_cursor ();
|
||||
default:
|
||||
return gdk_cursor_ref (create_builtin_cursor (cursor_type));
|
||||
return g_object_ref (create_builtin_cursor (cursor_type));
|
||||
}
|
||||
|
||||
[nscursor retain];
|
||||
|
||||
@@ -963,6 +963,13 @@ fill_key_event (GdkWindow *window,
|
||||
|
||||
event->key.state |= _gdk_quartz_events_get_current_mouse_modifiers ();
|
||||
|
||||
/* The X11 backend adds the first virtual modifier MOD2..MOD5 are
|
||||
* mapped to. Since we only have one virtual modifier in the quartz
|
||||
* backend, calling the standard function will do.
|
||||
*/
|
||||
gdk_keymap_add_virtual_modifiers (gdk_keymap_get_for_display (_gdk_display),
|
||||
&event->key.state);
|
||||
|
||||
event->key.string = NULL;
|
||||
|
||||
/* Fill in ->string since apps depend on it, taken from the x11 backend. */
|
||||
|
||||
@@ -1630,7 +1630,18 @@ gdk_window_quartz_restack_toplevel (GdkWindow *window,
|
||||
GdkWindow *sibling,
|
||||
gboolean above)
|
||||
{
|
||||
/* FIXME: Implement this */
|
||||
GdkWindowImplQuartz *impl;
|
||||
gint sibling_num;
|
||||
|
||||
impl = GDK_WINDOW_IMPL_QUARTZ (sibling->impl);
|
||||
sibling_num = [impl->toplevel windowNumber];
|
||||
|
||||
impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
|
||||
|
||||
if (above)
|
||||
[impl->toplevel orderWindow:NSWindowAbove relativeTo:sibling_num];
|
||||
else
|
||||
[impl->toplevel orderWindow:NSWindowBelow relativeTo:sibling_num];
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -378,6 +378,19 @@ input_handle_button(void *data, struct wl_input_device *input_device,
|
||||
GdkDisplayWayland *display = GDK_DISPLAY_WAYLAND (device->display);
|
||||
GdkEvent *event;
|
||||
uint32_t modifier;
|
||||
int gdk_button;
|
||||
|
||||
switch (button) {
|
||||
case 273:
|
||||
gdk_button = 3;
|
||||
break;
|
||||
case 274:
|
||||
gdk_button = 2;
|
||||
break;
|
||||
default:
|
||||
gdk_button = button - 271;
|
||||
break;
|
||||
}
|
||||
|
||||
device->time = time;
|
||||
event = gdk_event_new (state ? GDK_BUTTON_PRESS : GDK_BUTTON_RELEASE);
|
||||
@@ -390,10 +403,10 @@ input_handle_button(void *data, struct wl_input_device *input_device,
|
||||
event->button.y_root = (gdouble) device->y;
|
||||
event->button.axes = NULL;
|
||||
event->button.state = device->modifiers;
|
||||
event->button.button = button - 271;
|
||||
event->button.button = gdk_button;
|
||||
gdk_event_set_screen (event, display->screen);
|
||||
|
||||
modifier = 1 << (8 + button - 272);
|
||||
modifier = 1 << (8 + gdk_button - 1);
|
||||
if (state)
|
||||
device->modifiers |= modifier;
|
||||
else
|
||||
@@ -1019,7 +1032,7 @@ gdk_wayland_device_get_selection_type_atoms (GdkDevice *gdk_device,
|
||||
|
||||
device = GDK_DEVICE_CORE (gdk_device)->device;
|
||||
|
||||
if (device->selection_offer->types->len == 0)
|
||||
if (!device->selection_offer || device->selection_offer->types->len == 0)
|
||||
{
|
||||
*atoms_out = NULL;
|
||||
return 0;
|
||||
|
||||
@@ -515,12 +515,10 @@ gdk_wayland_keymap_add_virtual_modifiers (GdkKeymap *keymap,
|
||||
|
||||
wayland_keymap = GDK_WAYLAND_KEYMAP (keymap);
|
||||
|
||||
for (i = 3; i < 8; i++)
|
||||
for (i = 4; i < 8; i++)
|
||||
{
|
||||
if ((1 << i) & *state)
|
||||
{
|
||||
if (wayland_keymap->modmap[i] & GDK_MOD1_MASK)
|
||||
*state |= GDK_MOD1_MASK;
|
||||
if (wayland_keymap->modmap[i] & GDK_SUPER_MASK)
|
||||
*state |= GDK_SUPER_MASK;
|
||||
if (wayland_keymap->modmap[i] & GDK_HYPER_MASK)
|
||||
@@ -540,7 +538,7 @@ gdk_wayland_keymap_map_virtual_modifiers (GdkKeymap *keymap,
|
||||
};
|
||||
int i, j;
|
||||
GdkWaylandKeymap *wayland_keymap;
|
||||
gboolean retval;
|
||||
gboolean retval = TRUE;
|
||||
|
||||
wayland_keymap = GDK_WAYLAND_KEYMAP (keymap);
|
||||
|
||||
@@ -548,7 +546,7 @@ gdk_wayland_keymap_map_virtual_modifiers (GdkKeymap *keymap,
|
||||
{
|
||||
if (*state & vmods[j])
|
||||
{
|
||||
for (i = 3; i < 8; i++)
|
||||
for (i = 4; i < 8; i++)
|
||||
{
|
||||
if (wayland_keymap->modmap[i] & vmods[j])
|
||||
{
|
||||
|
||||
@@ -45,10 +45,6 @@
|
||||
#define GDK_WINDOW_IS_WAYLAND(win) (GDK_IS_WINDOW_IMPL_WAYLAND (((GdkWindow *)win)->impl))
|
||||
|
||||
GType _gdk_wayland_window_get_type (void);
|
||||
void _gdk_wayland_window_update_size (GdkWindow *window,
|
||||
int32_t width,
|
||||
int32_t height,
|
||||
uint32_t edges);
|
||||
void _gdk_wayland_window_add_focus (GdkWindow *window);
|
||||
void _gdk_wayland_window_remove_focus (GdkWindow *window);
|
||||
|
||||
|
||||
@@ -157,15 +157,15 @@ _gdk_wayland_window_remove_focus (GdkWindow *window)
|
||||
}
|
||||
|
||||
/**
|
||||
* _gdk_wayland_window_update_size:
|
||||
* gdk_wayland_window_update_size:
|
||||
* @drawable: a #GdkDrawableImplWayland.
|
||||
*
|
||||
* Updates the state of the drawable (in particular the drawable's
|
||||
* cairo surface) when its size has changed.
|
||||
**/
|
||||
void
|
||||
_gdk_wayland_window_update_size (GdkWindow *window,
|
||||
int32_t width, int32_t height, uint32_t edges)
|
||||
static void
|
||||
gdk_wayland_window_update_size (GdkWindow *window,
|
||||
int32_t width, int32_t height, uint32_t edges)
|
||||
{
|
||||
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
|
||||
GdkRectangle area;
|
||||
@@ -436,6 +436,33 @@ gdk_wayland_window_ref_cairo_surface (GdkWindow *window)
|
||||
return impl->cairo_surface;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_window_configure (GdkWindow *window,
|
||||
int width, int height, int edges)
|
||||
{
|
||||
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
|
||||
GdkDisplay *display;
|
||||
GdkEvent *event;
|
||||
|
||||
display = gdk_window_get_display (window);
|
||||
|
||||
/* TODO: Only generate a configure event if width or height have actually
|
||||
* changed?
|
||||
*/
|
||||
event = gdk_event_new (GDK_CONFIGURE);
|
||||
event->configure.window = window;
|
||||
event->configure.send_event = FALSE;
|
||||
event->configure.width = width;
|
||||
event->configure.height = height;
|
||||
|
||||
_gdk_window_update_size (window);
|
||||
gdk_wayland_window_update_size (window, width, height, edges);
|
||||
|
||||
g_object_ref(window);
|
||||
|
||||
_gdk_wayland_display_deliver_event (display, event);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_window_set_user_time (GdkWindow *window, guint32 user_time)
|
||||
{
|
||||
@@ -477,10 +504,6 @@ shell_surface_handle_configure(void *data,
|
||||
{
|
||||
GdkWindow *window = GDK_WINDOW (data);
|
||||
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
|
||||
GdkDisplay *display;
|
||||
GdkEvent *event;
|
||||
|
||||
display = gdk_window_get_display (window);
|
||||
|
||||
gdk_window_constrain_size (&impl->geometry_hints,
|
||||
impl->geometry_mask,
|
||||
@@ -489,21 +512,7 @@ shell_surface_handle_configure(void *data,
|
||||
&width,
|
||||
&height);
|
||||
|
||||
/* TODO: Only generate a configure event if width or height have actually
|
||||
* changed?
|
||||
*/
|
||||
event = gdk_event_new (GDK_CONFIGURE);
|
||||
event->configure.window = window;
|
||||
event->configure.send_event = FALSE;
|
||||
event->configure.width = width;
|
||||
event->configure.height = height;
|
||||
|
||||
_gdk_window_update_size (window);
|
||||
_gdk_wayland_window_update_size (window, width, height, edges);
|
||||
|
||||
g_object_ref(window);
|
||||
|
||||
_gdk_wayland_display_deliver_event (display, event);
|
||||
gdk_wayland_window_configure (window, width, height, edges);
|
||||
}
|
||||
|
||||
static const struct wl_shell_surface_listener shell_surface_listener = {
|
||||
@@ -637,7 +646,11 @@ gdk_window_wayland_move_resize (GdkWindow *window,
|
||||
window->x = x;
|
||||
window->y = y;
|
||||
|
||||
_gdk_wayland_window_update_size (window, width, height, 0);
|
||||
/* If this function is called with width and height = -1 then that means
|
||||
* just move the window - don't update its size
|
||||
*/
|
||||
if (width > 0 && height > 0)
|
||||
gdk_wayland_window_configure (window, width, height, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -806,6 +819,7 @@ gdk_wayland_window_destroy (GdkWindow *window,
|
||||
{
|
||||
if (GDK_WINDOW_IMPL_WAYLAND (window->impl)->surface)
|
||||
wl_surface_destroy(GDK_WINDOW_IMPL_WAYLAND (window->impl)->surface);
|
||||
wl_shell_surface_destroy(GDK_WINDOW_IMPL_WAYLAND (window->impl)->shell_surface);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1503,7 +1503,11 @@ gdk_win32_window_raise (GdkWindow *window)
|
||||
0, 0, 0, 0,
|
||||
SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE));
|
||||
else if (window->accept_focus)
|
||||
API_CALL (BringWindowToTop, (GDK_WINDOW_HWND (window)));
|
||||
/* Do not wrap this in an API_CALL macro as SetForegroundWindow might
|
||||
* fail when for example dragging a window belonging to a different
|
||||
* application at the time of a gtk_window_present() call due to focus
|
||||
* stealing prevention. */
|
||||
SetForegroundWindow (GDK_WINDOW_HWND (window));
|
||||
else
|
||||
API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), HWND_TOP,
|
||||
0, 0, 0, 0,
|
||||
|
||||
@@ -7,6 +7,8 @@ libgdkx11includedir = $(includedir)/gtk-3.0/gdk/x11
|
||||
AM_CPPFLAGS = \
|
||||
-DG_LOG_DOMAIN=\"Gdk\" \
|
||||
-DGDK_COMPILATION \
|
||||
-DXINPUT2_2_USE_UNSTABLE_PROTOCOL \
|
||||
-DXINPUT2_1_USE_UNSTABLE_PROTOCOL \
|
||||
-I$(top_srcdir) \
|
||||
-I$(top_srcdir)/gdk \
|
||||
-I$(top_builddir)/gdk \
|
||||
|
||||
@@ -221,7 +221,7 @@ startup_timeout (void *data)
|
||||
std->timeout_id = g_timeout_add_seconds ((min_timeout + 500)/1000, startup_timeout, std);
|
||||
|
||||
/* always remove this one, but we may have reinstalled another one. */
|
||||
return FALSE;
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -388,6 +388,7 @@ gdk_x11_device_xi2_grab (GdkDevice *device,
|
||||
guint32 time_)
|
||||
{
|
||||
GdkX11DeviceXI2 *device_xi2 = GDK_X11_DEVICE_XI2 (device);
|
||||
GdkX11DeviceManagerXI2 *device_manager_xi2;
|
||||
GdkDisplay *display;
|
||||
XIEventMask mask;
|
||||
Window xwindow;
|
||||
@@ -395,6 +396,7 @@ gdk_x11_device_xi2_grab (GdkDevice *device,
|
||||
gint status;
|
||||
|
||||
display = gdk_device_get_display (device);
|
||||
device_manager_xi2 = GDK_X11_DEVICE_MANAGER_XI2 (gdk_display_get_device_manager (display));
|
||||
|
||||
/* FIXME: confine_to is actually unused */
|
||||
|
||||
@@ -409,7 +411,9 @@ gdk_x11_device_xi2_grab (GdkDevice *device,
|
||||
}
|
||||
|
||||
mask.deviceid = device_xi2->device_id;
|
||||
mask.mask = _gdk_x11_device_xi2_translate_event_mask (event_mask, &mask.mask_len);
|
||||
mask.mask = _gdk_x11_device_xi2_translate_event_mask (device_manager_xi2,
|
||||
event_mask,
|
||||
&mask.mask_len);
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (_gdk_debug_flags & GDK_DEBUG_NOGRABS)
|
||||
@@ -625,10 +629,17 @@ gdk_x11_device_xi2_select_window_events (GdkDevice *device,
|
||||
GdkEventMask event_mask)
|
||||
{
|
||||
GdkX11DeviceXI2 *device_xi2 = GDK_X11_DEVICE_XI2 (device);
|
||||
GdkX11DeviceManagerXI2 *device_manager_xi2;
|
||||
GdkDisplay *display;
|
||||
XIEventMask evmask;
|
||||
|
||||
display = gdk_device_get_display (device);
|
||||
device_manager_xi2 = GDK_X11_DEVICE_MANAGER_XI2 (gdk_display_get_device_manager (display));
|
||||
|
||||
evmask.deviceid = device_xi2->device_id;
|
||||
evmask.mask = _gdk_x11_device_xi2_translate_event_mask (event_mask, &evmask.mask_len);
|
||||
evmask.mask = _gdk_x11_device_xi2_translate_event_mask (device_manager_xi2,
|
||||
event_mask,
|
||||
&evmask.mask_len);
|
||||
|
||||
XISelectEvents (GDK_WINDOW_XDISPLAY (window),
|
||||
GDK_WINDOW_XID (window),
|
||||
@@ -638,10 +649,14 @@ gdk_x11_device_xi2_select_window_events (GdkDevice *device,
|
||||
}
|
||||
|
||||
guchar *
|
||||
_gdk_x11_device_xi2_translate_event_mask (GdkEventMask event_mask,
|
||||
gint *len)
|
||||
_gdk_x11_device_xi2_translate_event_mask (GdkX11DeviceManagerXI2 *device_manager_xi2,
|
||||
GdkEventMask event_mask,
|
||||
gint *len)
|
||||
{
|
||||
guchar *mask;
|
||||
gint minor;
|
||||
|
||||
g_object_get (device_manager_xi2, "minor", &minor, NULL);
|
||||
|
||||
*len = XIMaskLen (XI_LASTEVENT);
|
||||
mask = g_new0 (guchar, *len);
|
||||
@@ -690,6 +705,17 @@ _gdk_x11_device_xi2_translate_event_mask (GdkEventMask event_mask,
|
||||
XISetMask (mask, XI_FocusOut);
|
||||
}
|
||||
|
||||
#ifdef XINPUT_2_2
|
||||
/* XInput 2.2 includes multitouch support */
|
||||
if (minor >= 2 &&
|
||||
event_mask & GDK_TOUCH_MASK)
|
||||
{
|
||||
XISetMask (mask, XI_TouchBegin);
|
||||
XISetMask (mask, XI_TouchUpdate);
|
||||
XISetMask (mask, XI_TouchEnd);
|
||||
}
|
||||
#endif /* XINPUT_2_2 */
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
||||
@@ -742,7 +768,7 @@ _gdk_x11_device_xi2_translate_state (XIModifierState *mods_state,
|
||||
{
|
||||
gint group;
|
||||
|
||||
group = group_state->base + group_state->latched + group_state->locked;
|
||||
group = group_state->base | group_state->latched | group_state->locked;
|
||||
|
||||
/* FIXME: do we need the XKB complications for this ? */
|
||||
group = CLAMP(group, 0, 3);
|
||||
|
||||
@@ -54,7 +54,11 @@ _gdk_x11_device_manager_new (GdkDisplay *display)
|
||||
int major, minor;
|
||||
|
||||
major = 2;
|
||||
#ifdef XINPUT_2_2
|
||||
minor = 2;
|
||||
#else
|
||||
minor = 0;
|
||||
#endif /* XINPUT_2_2 */
|
||||
|
||||
if (!_gdk_disable_multidevice &&
|
||||
XIQueryVersion (xdisplay, &major, &minor) != BadRequest)
|
||||
@@ -66,6 +70,8 @@ _gdk_x11_device_manager_new (GdkDisplay *display)
|
||||
device_manager_xi2 = g_object_new (GDK_TYPE_X11_DEVICE_MANAGER_XI2,
|
||||
"display", display,
|
||||
"opcode", opcode,
|
||||
"major", major,
|
||||
"minor", minor,
|
||||
NULL);
|
||||
|
||||
return GDK_DEVICE_MANAGER (device_manager_xi2);
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "gdkprivate-x11.h"
|
||||
#include "gdkintl.h"
|
||||
#include "gdkkeysyms.h"
|
||||
#include "gdkinternals.h"
|
||||
|
||||
#ifdef XINPUT_2
|
||||
|
||||
@@ -49,6 +50,8 @@ struct _GdkX11DeviceManagerXI2
|
||||
GList *devices;
|
||||
|
||||
gint opcode;
|
||||
gint major;
|
||||
gint minor;
|
||||
};
|
||||
|
||||
struct _GdkX11DeviceManagerXI2Class
|
||||
@@ -96,7 +99,9 @@ static GdkWindow * gdk_x11_device_manager_xi2_get_window (GdkEventTra
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_OPCODE
|
||||
PROP_OPCODE,
|
||||
PROP_MAJOR,
|
||||
PROP_MINOR
|
||||
};
|
||||
|
||||
static void
|
||||
@@ -120,6 +125,20 @@ gdk_x11_device_manager_xi2_class_init (GdkX11DeviceManagerXI2Class *klass)
|
||||
P_("Opcode for XInput2 requests"),
|
||||
0, G_MAXINT, 0,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_MAJOR,
|
||||
g_param_spec_int ("major",
|
||||
P_("Major"),
|
||||
P_("Major version number"),
|
||||
0, G_MAXINT, 0,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_MINOR,
|
||||
g_param_spec_int ("minor",
|
||||
P_("Minor"),
|
||||
P_("Minor version number"),
|
||||
0, G_MAXINT, 0,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -148,8 +167,10 @@ _gdk_x11_device_manager_xi2_select_events (GdkDeviceManager *device_manager,
|
||||
static void
|
||||
translate_valuator_class (GdkDisplay *display,
|
||||
GdkDevice *device,
|
||||
XIValuatorClassInfo *info,
|
||||
gint n_valuator)
|
||||
Atom valuator_label,
|
||||
gdouble min,
|
||||
gdouble max,
|
||||
gdouble resolution)
|
||||
{
|
||||
static gboolean initialized = FALSE;
|
||||
static Atom label_atoms [GDK_AXIS_LAST] = { 0 };
|
||||
@@ -170,24 +191,19 @@ translate_valuator_class (GdkDisplay *display,
|
||||
|
||||
for (i = GDK_AXIS_IGNORE; i < GDK_AXIS_LAST; i++)
|
||||
{
|
||||
if (label_atoms[i] == info->label)
|
||||
if (label_atoms[i] == valuator_label)
|
||||
{
|
||||
use = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (info->label != None)
|
||||
label = gdk_x11_xatom_to_atom_for_display (display, info->label);
|
||||
if (valuator_label != None)
|
||||
label = gdk_x11_xatom_to_atom_for_display (display, valuator_label);
|
||||
else
|
||||
label = GDK_NONE;
|
||||
|
||||
_gdk_device_add_axis (device,
|
||||
label,
|
||||
use,
|
||||
info->min,
|
||||
info->max,
|
||||
info->resolution);
|
||||
_gdk_device_add_axis (device, label, use, min, max, resolution);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -196,7 +212,7 @@ translate_device_classes (GdkDisplay *display,
|
||||
XIAnyClassInfo **classes,
|
||||
guint n_classes)
|
||||
{
|
||||
gint i, n_valuator = 0;
|
||||
gint i;
|
||||
|
||||
g_object_freeze_notify (G_OBJECT (device));
|
||||
|
||||
@@ -218,10 +234,14 @@ translate_device_classes (GdkDisplay *display,
|
||||
}
|
||||
break;
|
||||
case XIValuatorClass:
|
||||
translate_valuator_class (display, device,
|
||||
(XIValuatorClassInfo *) class_info,
|
||||
n_valuator);
|
||||
n_valuator++;
|
||||
{
|
||||
XIValuatorClassInfo *valuator_info = (XIValuatorClassInfo *) class_info;
|
||||
translate_valuator_class (display, device,
|
||||
valuator_info->label,
|
||||
valuator_info->min,
|
||||
valuator_info->max,
|
||||
valuator_info->resolution);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* Ignore */
|
||||
@@ -232,6 +252,27 @@ translate_device_classes (GdkDisplay *display,
|
||||
g_object_thaw_notify (G_OBJECT (device));
|
||||
}
|
||||
|
||||
static gint
|
||||
count_device_touches (XIAnyClassInfo **classes,
|
||||
guint n_classes)
|
||||
{
|
||||
#ifdef XINPUT_2_2
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < n_classes; i++)
|
||||
{
|
||||
XITouchClassInfo *valuator_info = (XITouchClassInfo *) classes[i];
|
||||
|
||||
if (valuator_info->type != XITouchClass)
|
||||
continue;
|
||||
|
||||
return valuator_info->num_touches;
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static GdkDevice *
|
||||
create_device (GdkDeviceManager *device_manager,
|
||||
GdkDisplay *display,
|
||||
@@ -244,6 +285,9 @@ create_device (GdkDeviceManager *device_manager,
|
||||
|
||||
if (dev->use == XIMasterKeyboard || dev->use == XISlaveKeyboard)
|
||||
input_source = GDK_SOURCE_KEYBOARD;
|
||||
else if (dev->use == XISlavePointer &&
|
||||
count_device_touches (dev->classes, dev->num_classes) > 0)
|
||||
input_source = GDK_SOURCE_TOUCH;
|
||||
else
|
||||
{
|
||||
gchar *tmp_name;
|
||||
@@ -254,6 +298,10 @@ create_device (GdkDeviceManager *device_manager,
|
||||
input_source = GDK_SOURCE_ERASER;
|
||||
else if (strstr (tmp_name, "cursor"))
|
||||
input_source = GDK_SOURCE_CURSOR;
|
||||
else if (strstr (tmp_name, "finger") ||
|
||||
(strstr (tmp_name, "touch") &&
|
||||
!strstr (tmp_name, "touchpad")))
|
||||
input_source = GDK_SOURCE_TOUCH;
|
||||
else if (strstr (tmp_name, "wacom") ||
|
||||
strstr (tmp_name, "pen"))
|
||||
input_source = GDK_SOURCE_PEN;
|
||||
@@ -408,6 +456,8 @@ gdk_x11_device_manager_xi2_constructed (GObject *object)
|
||||
display = gdk_device_manager_get_display (GDK_DEVICE_MANAGER (object));
|
||||
xdisplay = GDK_DISPLAY_XDISPLAY (display);
|
||||
|
||||
g_assert (device_manager->major == 2);
|
||||
|
||||
masters = g_hash_table_new (NULL, NULL);
|
||||
slaves = g_hash_table_new (NULL, NULL);
|
||||
|
||||
@@ -533,6 +583,12 @@ gdk_x11_device_manager_xi2_set_property (GObject *object,
|
||||
case PROP_OPCODE:
|
||||
device_manager->opcode = g_value_get_int (value);
|
||||
break;
|
||||
case PROP_MAJOR:
|
||||
device_manager->major = g_value_get_int (value);
|
||||
break;
|
||||
case PROP_MINOR:
|
||||
device_manager->minor = g_value_get_int (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
@@ -554,6 +610,12 @@ gdk_x11_device_manager_xi2_get_property (GObject *object,
|
||||
case PROP_OPCODE:
|
||||
g_value_set_int (value, device_manager->opcode);
|
||||
break;
|
||||
case PROP_MAJOR:
|
||||
g_value_set_int (value, device_manager->major);
|
||||
break;
|
||||
case PROP_MINOR:
|
||||
g_value_set_int (value, device_manager->minor);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
@@ -823,6 +885,11 @@ get_event_window (GdkEventTranslator *translator,
|
||||
case XI_ButtonPress:
|
||||
case XI_ButtonRelease:
|
||||
case XI_Motion:
|
||||
#ifdef XINPUT_2_2
|
||||
case XI_TouchUpdate:
|
||||
case XI_TouchBegin:
|
||||
case XI_TouchEnd:
|
||||
#endif /* XINPUT_2_2 */
|
||||
{
|
||||
XIDeviceEvent *xev = (XIDeviceEvent *) ev;
|
||||
|
||||
@@ -1043,56 +1110,55 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
|
||||
break;
|
||||
case XI_ButtonPress:
|
||||
case XI_ButtonRelease:
|
||||
#ifdef XINPUT_2_2
|
||||
case XI_TouchBegin:
|
||||
case XI_TouchEnd:
|
||||
#endif /* XINPUT_2_2 */
|
||||
{
|
||||
XIDeviceEvent *xev = (XIDeviceEvent *) ev;
|
||||
GdkDevice *source_device;
|
||||
|
||||
switch (xev->detail)
|
||||
if (ev->evtype == XI_ButtonPress &&
|
||||
(xev->detail >= 4 && xev->detail <= 7))
|
||||
{
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
case 7:
|
||||
/* Button presses of button 4-7 are scroll events */
|
||||
if (ev->evtype == XI_ButtonPress)
|
||||
{
|
||||
event->scroll.type = GDK_SCROLL;
|
||||
/* Button presses of button 4-7 are scroll events */
|
||||
event->scroll.type = GDK_SCROLL;
|
||||
|
||||
if (xev->detail == 4)
|
||||
event->scroll.direction = GDK_SCROLL_UP;
|
||||
else if (xev->detail == 5)
|
||||
event->scroll.direction = GDK_SCROLL_DOWN;
|
||||
else if (xev->detail == 6)
|
||||
event->scroll.direction = GDK_SCROLL_LEFT;
|
||||
else
|
||||
event->scroll.direction = GDK_SCROLL_RIGHT;
|
||||
if (xev->detail == 4)
|
||||
event->scroll.direction = GDK_SCROLL_UP;
|
||||
else if (xev->detail == 5)
|
||||
event->scroll.direction = GDK_SCROLL_DOWN;
|
||||
else if (xev->detail == 6)
|
||||
event->scroll.direction = GDK_SCROLL_LEFT;
|
||||
else
|
||||
event->scroll.direction = GDK_SCROLL_RIGHT;
|
||||
|
||||
event->scroll.window = window;
|
||||
event->scroll.time = xev->time;
|
||||
event->scroll.x = (gdouble) xev->event_x;
|
||||
event->scroll.y = (gdouble) xev->event_y;
|
||||
event->scroll.x_root = (gdouble) xev->root_x;
|
||||
event->scroll.y_root = (gdouble) xev->root_y;
|
||||
event->scroll.window = window;
|
||||
event->scroll.time = xev->time;
|
||||
event->scroll.x = (gdouble) xev->event_x;
|
||||
event->scroll.y = (gdouble) xev->event_y;
|
||||
event->scroll.x_root = (gdouble) xev->root_x;
|
||||
event->scroll.y_root = (gdouble) xev->root_y;
|
||||
|
||||
event->scroll.device = g_hash_table_lookup (device_manager->id_table,
|
||||
GUINT_TO_POINTER (xev->deviceid));
|
||||
event->scroll.device = g_hash_table_lookup (device_manager->id_table,
|
||||
GUINT_TO_POINTER (xev->deviceid));
|
||||
|
||||
source_device = g_hash_table_lookup (device_manager->id_table,
|
||||
GUINT_TO_POINTER (xev->sourceid));
|
||||
gdk_event_set_source_device (event, source_device);
|
||||
source_device = g_hash_table_lookup (device_manager->id_table,
|
||||
GUINT_TO_POINTER (xev->sourceid));
|
||||
gdk_event_set_source_device (event, source_device);
|
||||
|
||||
event->scroll.state = _gdk_x11_device_xi2_translate_state (&xev->mods, &xev->buttons, &xev->group);
|
||||
break;
|
||||
}
|
||||
/* Button presses of button 4-7 are scroll events, so ignore the release */
|
||||
else if (ev->evtype == XI_ButtonRelease)
|
||||
{
|
||||
return_val = FALSE;
|
||||
break;
|
||||
}
|
||||
/* else (XI_ButtonRelease) fall thru */
|
||||
default:
|
||||
event->button.type = (ev->evtype == XI_ButtonPress) ? GDK_BUTTON_PRESS : GDK_BUTTON_RELEASE;
|
||||
event->scroll.state = _gdk_x11_device_xi2_translate_state (&xev->mods, &xev->buttons, &xev->group);
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef XINPUT_2_2
|
||||
if (ev->evtype == XI_TouchBegin)
|
||||
event->button.type = GDK_TOUCH_PRESS;
|
||||
else if (ev->evtype == XI_TouchEnd)
|
||||
event->button.type = GDK_TOUCH_RELEASE;
|
||||
else
|
||||
#endif /* XINPUT_2_2 */
|
||||
event->button.type = (ev->evtype == XI_ButtonPress) ? GDK_BUTTON_PRESS : GDK_BUTTON_RELEASE;
|
||||
|
||||
event->button.window = window;
|
||||
event->button.time = xev->time;
|
||||
@@ -1124,9 +1190,25 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
|
||||
}
|
||||
|
||||
event->button.state = _gdk_x11_device_xi2_translate_state (&xev->mods, &xev->buttons, &xev->group);
|
||||
event->button.button = xev->detail;
|
||||
|
||||
if (ev->evtype == XI_TouchBegin)
|
||||
event->button.state |= GDK_BUTTON1_MASK;
|
||||
|
||||
#ifdef XINPUT_2_2
|
||||
if (ev->evtype == XI_TouchBegin ||
|
||||
ev->evtype == XI_TouchEnd)
|
||||
{
|
||||
event->button.button = 1;
|
||||
event->button.touch_id = xev->detail;
|
||||
}
|
||||
else
|
||||
#endif /* XINPUT_2_2 */
|
||||
event->button.button = xev->detail;
|
||||
}
|
||||
|
||||
if (xev->flags & (XIPointerEmulated | XITouchEmulatingPointer))
|
||||
_gdk_event_set_pointer_emulated (event, TRUE);
|
||||
|
||||
if (return_val == FALSE)
|
||||
break;
|
||||
|
||||
@@ -1142,11 +1224,25 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
|
||||
break;
|
||||
}
|
||||
case XI_Motion:
|
||||
#ifdef XINPUT_2_2
|
||||
case XI_TouchUpdate:
|
||||
#endif /* XINPUT_2_2 */
|
||||
{
|
||||
XIDeviceEvent *xev = (XIDeviceEvent *) ev;
|
||||
GdkDevice *source_device;
|
||||
|
||||
event->motion.type = GDK_MOTION_NOTIFY;
|
||||
if (ev->evtype == XI_Motion)
|
||||
{
|
||||
event->motion.touch_id = 0;
|
||||
event->motion.type = GDK_MOTION_NOTIFY;
|
||||
}
|
||||
#ifdef XINPUT_2_2
|
||||
else
|
||||
{
|
||||
event->motion.touch_id = xev->detail;
|
||||
event->motion.type = GDK_TOUCH_MOTION;
|
||||
}
|
||||
#endif
|
||||
|
||||
event->motion.window = window;
|
||||
|
||||
@@ -1165,6 +1261,12 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
|
||||
|
||||
event->motion.state = _gdk_x11_device_xi2_translate_state (&xev->mods, &xev->buttons, &xev->group);
|
||||
|
||||
if (ev->evtype == XI_TouchUpdate)
|
||||
event->motion.state |= GDK_BUTTON1_MASK;
|
||||
|
||||
if (xev->flags & (XIPointerEmulated | XITouchEmulatingPointer))
|
||||
_gdk_event_set_pointer_emulated (event, TRUE);
|
||||
|
||||
/* There doesn't seem to be motion hints in XI */
|
||||
event->motion.is_hint = FALSE;
|
||||
|
||||
@@ -1280,7 +1382,8 @@ gdk_x11_device_manager_xi2_get_handled_events (GdkEventTranslator *translator)
|
||||
GDK_BUTTON2_MOTION_MASK |
|
||||
GDK_BUTTON3_MOTION_MASK |
|
||||
GDK_BUTTON_MOTION_MASK |
|
||||
GDK_FOCUS_CHANGE_MASK);
|
||||
GDK_FOCUS_CHANGE_MASK |
|
||||
GDK_TOUCH_MASK);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1294,7 +1397,9 @@ gdk_x11_device_manager_xi2_select_window_events (GdkEventTranslator *translator,
|
||||
device_manager = GDK_DEVICE_MANAGER (translator);
|
||||
|
||||
event_mask.deviceid = XIAllMasterDevices;
|
||||
event_mask.mask = _gdk_x11_device_xi2_translate_event_mask (evmask, &event_mask.mask_len);
|
||||
event_mask.mask = _gdk_x11_device_xi2_translate_event_mask (GDK_X11_DEVICE_MANAGER_XI2 (device_manager),
|
||||
evmask,
|
||||
&event_mask.mask_len);
|
||||
|
||||
_gdk_x11_device_manager_xi2_select_events (device_manager, window, &event_mask);
|
||||
g_free (event_mask.mask);
|
||||
|
||||
@@ -1579,9 +1579,12 @@ device_grab_update_callback (GdkDisplay *display,
|
||||
gpointer data,
|
||||
gulong serial)
|
||||
{
|
||||
GdkPointerWindowInfo *pointer_info;
|
||||
GdkDevice *device = data;
|
||||
|
||||
_gdk_display_device_grab_update (display, device, NULL, serial);
|
||||
pointer_info = _gdk_display_get_pointer_info (display, device);
|
||||
_gdk_display_device_grab_update (display, device,
|
||||
pointer_info->last_slave, serial);
|
||||
}
|
||||
|
||||
#define XSERVER_TIME_IS_LATER(time1, time2) \
|
||||
|
||||
@@ -131,6 +131,8 @@ struct _GdkX11Display
|
||||
GdkWindow *active_offscreen_window;
|
||||
|
||||
GSList *error_traps;
|
||||
|
||||
gint wm_moveresize_button;
|
||||
};
|
||||
|
||||
struct _GdkX11DisplayClass
|
||||
|
||||
@@ -247,8 +247,9 @@ void _gdk_x11_device_xi_translate_axes (GdkDevice *device,
|
||||
#endif
|
||||
|
||||
#ifdef XINPUT_2
|
||||
guchar * _gdk_x11_device_xi2_translate_event_mask (GdkEventMask event_mask,
|
||||
gint *len);
|
||||
guchar * _gdk_x11_device_xi2_translate_event_mask (GdkX11DeviceManagerXI2 *device_manager_xi2,
|
||||
GdkEventMask event_mask,
|
||||
gint *len);
|
||||
guint _gdk_x11_device_xi2_translate_state (XIModifierState *mods_state,
|
||||
XIButtonState *buttons_state,
|
||||
XIGroupState *group_state);
|
||||
|
||||
@@ -4020,6 +4020,85 @@ gdk_window_x11_set_static_gravities (GdkWindow *window,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* From the WM spec */
|
||||
#define _NET_WM_MOVERESIZE_SIZE_TOPLEFT 0
|
||||
#define _NET_WM_MOVERESIZE_SIZE_TOP 1
|
||||
#define _NET_WM_MOVERESIZE_SIZE_TOPRIGHT 2
|
||||
#define _NET_WM_MOVERESIZE_SIZE_RIGHT 3
|
||||
#define _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT 4
|
||||
#define _NET_WM_MOVERESIZE_SIZE_BOTTOM 5
|
||||
#define _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT 6
|
||||
#define _NET_WM_MOVERESIZE_SIZE_LEFT 7
|
||||
#define _NET_WM_MOVERESIZE_MOVE 8 /* movement only */
|
||||
#define _NET_WM_MOVERESIZE_SIZE_KEYBOARD 9 /* size via keyboard */
|
||||
#define _NET_WM_MOVERESIZE_MOVE_KEYBOARD 10 /* move via keyboard */
|
||||
#define _NET_WM_MOVERESIZE_CANCEL 11 /* cancel operation */
|
||||
|
||||
static void
|
||||
wmspec_send_message (GdkDisplay *display,
|
||||
GdkWindow *window,
|
||||
gint root_x,
|
||||
gint root_y,
|
||||
gint action,
|
||||
gint button)
|
||||
{
|
||||
XClientMessageEvent xclient;
|
||||
|
||||
memset (&xclient, 0, sizeof (xclient));
|
||||
xclient.type = ClientMessage;
|
||||
xclient.window = GDK_WINDOW_XID (window);
|
||||
xclient.message_type =
|
||||
gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_MOVERESIZE");
|
||||
xclient.format = 32;
|
||||
xclient.data.l[0] = root_x;
|
||||
xclient.data.l[1] = root_y;
|
||||
xclient.data.l[2] = action;
|
||||
xclient.data.l[3] = button;
|
||||
xclient.data.l[4] = 1; /* source indication */
|
||||
|
||||
XSendEvent (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XROOTWIN (window), False,
|
||||
SubstructureRedirectMask | SubstructureNotifyMask,
|
||||
(XEvent *)&xclient);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
handle_wmspec_button_release (GdkDisplay *display,
|
||||
XEvent *xevent)
|
||||
{
|
||||
GdkX11Display *display_x11 = GDK_X11_DISPLAY (display);
|
||||
GdkWindow *window;
|
||||
|
||||
#if defined (HAVE_XGENERICEVENTS) && defined (XINPUT_2)
|
||||
XIEvent *xiev = (XIEvent *) xevent->xcookie.data;
|
||||
XIDeviceEvent *xidev = (XIDeviceEvent *) xiev;
|
||||
|
||||
if (xevent->xany.type == GenericEvent)
|
||||
window = gdk_x11_window_lookup_for_display (display, xidev->event);
|
||||
else
|
||||
#endif
|
||||
window = gdk_x11_window_lookup_for_display (display, xevent->xany.window);
|
||||
|
||||
if (display_x11->wm_moveresize_button != 0 && window != NULL)
|
||||
{
|
||||
if ((xevent->xany.type == ButtonRelease &&
|
||||
xevent->xbutton.button == display_x11->wm_moveresize_button)
|
||||
#if defined (HAVE_XGENERICEVENTS) && defined (XINPUT_2)
|
||||
||
|
||||
(xevent->xany.type == GenericEvent &&
|
||||
xiev->evtype == XI_ButtonRelease &&
|
||||
xidev->detail == display_x11->wm_moveresize_button)
|
||||
#endif
|
||||
)
|
||||
{
|
||||
display_x11->wm_moveresize_button = 0;
|
||||
wmspec_send_message (display, window, 0, 0, _NET_WM_MOVERESIZE_CANCEL, 0);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
wmspec_moveresize (GdkWindow *window,
|
||||
gint direction,
|
||||
@@ -4030,64 +4109,14 @@ wmspec_moveresize (GdkWindow *window,
|
||||
guint32 timestamp)
|
||||
{
|
||||
GdkDisplay *display = GDK_WINDOW_DISPLAY (window);
|
||||
|
||||
XClientMessageEvent xclient;
|
||||
|
||||
/* Release passive grab */
|
||||
gdk_device_ungrab (device, timestamp);
|
||||
GDK_X11_DISPLAY (display)->wm_moveresize_button = button;
|
||||
|
||||
memset (&xclient, 0, sizeof (xclient));
|
||||
xclient.type = ClientMessage;
|
||||
xclient.window = GDK_WINDOW_XID (window);
|
||||
xclient.message_type =
|
||||
gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_MOVERESIZE");
|
||||
xclient.format = 32;
|
||||
xclient.data.l[0] = root_x;
|
||||
xclient.data.l[1] = root_y;
|
||||
xclient.data.l[2] = direction;
|
||||
xclient.data.l[3] = button;
|
||||
xclient.data.l[4] = 1; /* source indication */
|
||||
|
||||
XSendEvent (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XROOTWIN (window), False,
|
||||
SubstructureRedirectMask | SubstructureNotifyMask,
|
||||
(XEvent *)&xclient);
|
||||
wmspec_send_message (display, window, root_x, root_y, direction, button);
|
||||
}
|
||||
|
||||
typedef struct _MoveResizeData MoveResizeData;
|
||||
|
||||
struct _MoveResizeData
|
||||
{
|
||||
GdkDisplay *display;
|
||||
|
||||
GdkWindow *moveresize_window;
|
||||
GdkWindow *moveresize_emulation_window;
|
||||
gboolean is_resize;
|
||||
GdkWindowEdge resize_edge;
|
||||
GdkDevice *device;
|
||||
gint moveresize_button;
|
||||
gint moveresize_x;
|
||||
gint moveresize_y;
|
||||
gint moveresize_orig_x;
|
||||
gint moveresize_orig_y;
|
||||
gint moveresize_orig_width;
|
||||
gint moveresize_orig_height;
|
||||
GdkWindowHints moveresize_geom_mask;
|
||||
GdkGeometry moveresize_geometry;
|
||||
Time moveresize_process_time;
|
||||
XEvent *moveresize_pending_event;
|
||||
};
|
||||
|
||||
/* From the WM spec */
|
||||
#define _NET_WM_MOVERESIZE_SIZE_TOPLEFT 0
|
||||
#define _NET_WM_MOVERESIZE_SIZE_TOP 1
|
||||
#define _NET_WM_MOVERESIZE_SIZE_TOPRIGHT 2
|
||||
#define _NET_WM_MOVERESIZE_SIZE_RIGHT 3
|
||||
#define _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT 4
|
||||
#define _NET_WM_MOVERESIZE_SIZE_BOTTOM 5
|
||||
#define _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT 6
|
||||
#define _NET_WM_MOVERESIZE_SIZE_LEFT 7
|
||||
#define _NET_WM_MOVERESIZE_MOVE 8
|
||||
|
||||
static void
|
||||
wmspec_resize_drag (GdkWindow *window,
|
||||
GdkWindowEdge edge,
|
||||
@@ -4145,6 +4174,30 @@ wmspec_resize_drag (GdkWindow *window,
|
||||
wmspec_moveresize (window, direction, device, button, root_x, root_y, timestamp);
|
||||
}
|
||||
|
||||
typedef struct _MoveResizeData MoveResizeData;
|
||||
|
||||
struct _MoveResizeData
|
||||
{
|
||||
GdkDisplay *display;
|
||||
|
||||
GdkWindow *moveresize_window;
|
||||
GdkWindow *moveresize_emulation_window;
|
||||
gboolean is_resize;
|
||||
GdkWindowEdge resize_edge;
|
||||
GdkDevice *device;
|
||||
gint moveresize_button;
|
||||
gint moveresize_x;
|
||||
gint moveresize_y;
|
||||
gint moveresize_orig_x;
|
||||
gint moveresize_orig_y;
|
||||
gint moveresize_orig_width;
|
||||
gint moveresize_orig_height;
|
||||
GdkWindowHints moveresize_geom_mask;
|
||||
GdkGeometry moveresize_geometry;
|
||||
Time moveresize_process_time;
|
||||
XEvent *moveresize_pending_event;
|
||||
};
|
||||
|
||||
static MoveResizeData *
|
||||
get_move_resize_data (GdkDisplay *display,
|
||||
gboolean create)
|
||||
@@ -4324,6 +4377,9 @@ _gdk_x11_moveresize_handle_event (XEvent *event)
|
||||
GdkDisplay *display = gdk_x11_lookup_xdisplay (event->xany.display);
|
||||
MoveResizeData *mv_resize = get_move_resize_data (display, FALSE);
|
||||
|
||||
if (handle_wmspec_button_release (display, event))
|
||||
return TRUE;
|
||||
|
||||
if (!mv_resize || !mv_resize->moveresize_window)
|
||||
return FALSE;
|
||||
|
||||
@@ -4405,6 +4461,8 @@ _gdk_x11_moveresize_configure_done (GdkDisplay *display,
|
||||
XEvent *tmp_event;
|
||||
MoveResizeData *mv_resize = get_move_resize_data (display, FALSE);
|
||||
|
||||
GDK_X11_DISPLAY (display)->wm_moveresize_button = 0;
|
||||
|
||||
if (!mv_resize || window != mv_resize->moveresize_window)
|
||||
return FALSE;
|
||||
|
||||
|
||||
@@ -145,6 +145,8 @@ endif
|
||||
# by configure)
|
||||
|
||||
deprecated_h_sources = \
|
||||
deprecated/gtkcolorsel.h \
|
||||
deprecated/gtkcolorseldialog.h \
|
||||
deprecated/gtkfontsel.h \
|
||||
deprecated/gtkhandlebox.h \
|
||||
deprecated/gtkhbbox.h \
|
||||
@@ -153,6 +155,7 @@ deprecated_h_sources = \
|
||||
deprecated/gtkhscale.h \
|
||||
deprecated/gtkhscrollbar.h \
|
||||
deprecated/gtkhseparator.h \
|
||||
deprecated/gtkhsv.h \
|
||||
deprecated/gtkstyle.h \
|
||||
deprecated/gtkrc.h \
|
||||
deprecated/gtktable.h \
|
||||
@@ -215,8 +218,10 @@ gtk_public_h_sources = \
|
||||
gtkcheckmenuitem.h \
|
||||
gtkclipboard.h \
|
||||
gtkcolorbutton.h \
|
||||
gtkcolorsel.h \
|
||||
gtkcolorseldialog.h \
|
||||
gtkcolorchooser.h \
|
||||
gtkcolorchooserwidget.h \
|
||||
gtkcolorchooserdialog.h \
|
||||
gtkcolorutils.h \
|
||||
gtkcombobox.h \
|
||||
gtkcomboboxtext.h \
|
||||
gtkcontainer.h \
|
||||
@@ -244,9 +249,9 @@ gtk_public_h_sources = \
|
||||
gtkfontchooserdialog.h \
|
||||
gtkfontchooserwidget.h \
|
||||
gtkframe.h \
|
||||
gtkgesturesinterpreter.h \
|
||||
gtkgradient.h \
|
||||
gtkgrid.h \
|
||||
gtkhsv.h \
|
||||
gtkiconfactory.h \
|
||||
gtkicontheme.h \
|
||||
gtkiconview.h \
|
||||
@@ -410,10 +415,16 @@ gtk_private_h_sources = \
|
||||
gtkbuilderprivate.h \
|
||||
gtkbuttonprivate.h \
|
||||
gtkcellareaboxcontextprivate.h \
|
||||
gtkcolorswatchprivate.h \
|
||||
gtkcoloreditorprivate.h \
|
||||
gtkcolorplaneprivate.h \
|
||||
gtkcolorscaleprivate.h \
|
||||
gtkcolorchooserprivate.h \
|
||||
gtkcontainerprivate.h \
|
||||
gtkcsscomputedvaluesprivate.h \
|
||||
gtkcsscustompropertyprivate.h \
|
||||
gtkcssimagegradientprivate.h \
|
||||
gtkcssimagelinearprivate.h \
|
||||
gtkcssimageprivate.h \
|
||||
gtkcssimageurlprivate.h \
|
||||
gtkcssimagewin32private.h \
|
||||
@@ -505,6 +516,8 @@ gtk_private_h_sources = \
|
||||
|
||||
# GTK+ C sources to build the library from
|
||||
deprecated_c_sources = \
|
||||
deprecated/gtkcolorsel.c \
|
||||
deprecated/gtkcolorseldialog.c \
|
||||
deprecated/gtkfontsel.c \
|
||||
deprecated/gtkhandlebox.c \
|
||||
deprecated/gtkhbbox.c \
|
||||
@@ -513,6 +526,7 @@ deprecated_c_sources = \
|
||||
deprecated/gtkhscale.c \
|
||||
deprecated/gtkhscrollbar.c \
|
||||
deprecated/gtkhseparator.c \
|
||||
deprecated/gtkhsv.c \
|
||||
deprecated/gtkrc.c \
|
||||
deprecated/gtkstyle.c \
|
||||
deprecated/gtktable.c \
|
||||
@@ -567,6 +581,7 @@ gtk_base_c_sources = \
|
||||
gtkbuildable.c \
|
||||
gtkbuilder.c \
|
||||
gtkbuilderparser.c \
|
||||
gtkbuilder-menus.c \
|
||||
gtkbutton.c \
|
||||
gtkcalendar.c \
|
||||
gtkcellarea.c \
|
||||
@@ -588,8 +603,14 @@ gtk_base_c_sources = \
|
||||
gtkcheckbutton.c \
|
||||
gtkcheckmenuitem.c \
|
||||
gtkcolorbutton.c \
|
||||
gtkcolorsel.c \
|
||||
gtkcolorseldialog.c \
|
||||
gtkcolorchooser.c \
|
||||
gtkcolorchooserwidget.c \
|
||||
gtkcolorchooserdialog.c \
|
||||
gtkcoloreditor.c \
|
||||
gtkcolorplane.c \
|
||||
gtkcolorscale.c \
|
||||
gtkcolorswatch.c \
|
||||
gtkcolorutils.c \
|
||||
gtkcombobox.c \
|
||||
gtkcomboboxtext.c \
|
||||
gtkcontainer.c \
|
||||
@@ -597,6 +618,7 @@ gtk_base_c_sources = \
|
||||
gtkcsscustomproperty.c \
|
||||
gtkcssimage.c \
|
||||
gtkcssimagegradient.c \
|
||||
gtkcssimagelinear.c \
|
||||
gtkcssimageurl.c \
|
||||
gtkcssimagewin32.c \
|
||||
gtkcsslookup.c \
|
||||
@@ -636,9 +658,9 @@ gtk_base_c_sources = \
|
||||
gtkfontchooserutils.c \
|
||||
gtkfontchooserwidget.c \
|
||||
gtkframe.c \
|
||||
gtkgesturesinterpreter.c \
|
||||
gtkgradient.c \
|
||||
gtkgrid.c \
|
||||
gtkhsv.c \
|
||||
gtkiconcache.c \
|
||||
gtkiconcachevalidator.c \
|
||||
gtkiconfactory.c \
|
||||
@@ -946,6 +968,12 @@ EXTRA_DIST += $(gtk_private_h_sources) $(gtk_extra_sources)
|
||||
EXTRA_DIST += $(gtk_built_sources)
|
||||
EXTRA_DIST += $(STOCK_ICONS)
|
||||
|
||||
|
||||
pkgdatadir=$(datadir)/gtk-$(GTK_API_VERSION)
|
||||
pkgdata_DATA = gtkbuilder.rng
|
||||
|
||||
EXTRA_DIST += gtkbuilder.rnc gtkbuilder.rng
|
||||
|
||||
DND_CURSORS = \
|
||||
cursor_dnd_ask.png \
|
||||
cursor_dnd_copy.png \
|
||||
@@ -995,10 +1023,10 @@ gtktypebuiltins.c: @REBUILD@ $(gtk_public_h_sources) $(deprecated_h_sources) gtk
|
||||
&& rm -f xgen-gtbc
|
||||
|
||||
gtkresources.h: gtk.gresource.xml
|
||||
$(AM_V_GEN) $(GLIB_COMPILE_RESOURCES) gtk.gresource.xml \
|
||||
$(AM_V_GEN) $(GLIB_COMPILE_RESOURCES) $(srcdir)/gtk.gresource.xml \
|
||||
--target=$@ --sourcedir=$(srcdir) --c-name _gtk --generate-header --manual-register
|
||||
gtkresources.c: gtk.gresource.xml gtk-default.css gtk-win32.css $(DND_CURSORS)
|
||||
$(AM_V_GEN) $(GLIB_COMPILE_RESOURCES) gtk.gresource.xml \
|
||||
$(AM_V_GEN) $(GLIB_COMPILE_RESOURCES) $(srcdir)/gtk.gresource.xml \
|
||||
--target=$@ --sourcedir=$(srcdir) --c-name _gtk --generate-source --manual-register
|
||||
|
||||
gtkprivatetypebuiltins.h: stamp-gtkprivatetypebuiltins.h
|
||||
@@ -1099,8 +1127,6 @@ dist-hook: ../build/win32/vs9/gtk.vcproj ../build/win32/vs10/gtk.vcxproj ../buil
|
||||
|
||||
# Install a RC file for the default GTK+ theme, and key themes
|
||||
install-data-local: install-ms-lib install-def-file install-mac-key-theme
|
||||
$(mkdir_p) $(DESTDIR)$(datadir)/themes/Raleigh/gtk-3.0
|
||||
$(INSTALL_DATA) $(srcdir)/gtk.css.raleigh $(DESTDIR)$(datadir)/themes/Raleigh/gtk-3.0/gtk.css
|
||||
$(mkdir_p) $(DESTDIR)$(datadir)/themes/Default/gtk-3.0
|
||||
$(INSTALL_DATA) $(srcdir)/gtk-keys.css.default $(DESTDIR)$(datadir)/themes/Default/gtk-3.0/gtk-keys.css
|
||||
$(mkdir_p) $(DESTDIR)$(datadir)/themes/Emacs/gtk-3.0
|
||||
@@ -1542,7 +1568,6 @@ EXTRA_DIST += \
|
||||
gtkprint-win32.h \
|
||||
gtkprint-win32.c \
|
||||
gtksearchenginequartz.h \
|
||||
gtk.css.raleigh \
|
||||
gtk.gresource.xml \
|
||||
gtk-default.css \
|
||||
gtk-keys.css.default \
|
||||
@@ -1555,10 +1580,12 @@ EXTRA_DIST += \
|
||||
gtktypebuiltins.h.template \
|
||||
gtkprivatetypebuiltins.c.template \
|
||||
gtkprivatetypebuiltins.h.template \
|
||||
org.gtk.Settings.FileChooser.gschema.xml
|
||||
org.gtk.Settings.FileChooser.gschema.xml \
|
||||
org.gtk.Settings.ColorChooser.gschema.xml
|
||||
|
||||
gsettings_SCHEMAS = \
|
||||
org.gtk.Settings.FileChooser.gschema.xml
|
||||
org.gtk.Settings.FileChooser.gschema.xml \
|
||||
org.gtk.Settings.ColorChooser.gschema.xml
|
||||
|
||||
@GSETTINGS_RULES@
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ gail_c_sources = \
|
||||
gtkcellaccessible.c \
|
||||
gtkcellaccessibleparent.c \
|
||||
gtkcheckmenuitemaccessible.c \
|
||||
gtkcolorswatchaccessible.c \
|
||||
gtkcomboboxaccessible.c \
|
||||
gtkcontaineraccessible.c \
|
||||
gtkcontainercellaccessible.c \
|
||||
@@ -59,6 +60,7 @@ gail_private_h_sources = \
|
||||
gtkcellaccessible.h \
|
||||
gtkcellaccessibleparent.h \
|
||||
gtkcheckmenuitemaccessible.h \
|
||||
gtkcolorswatchaccessible.h \
|
||||
gtkcomboboxaccessible.h \
|
||||
gtkcontaineraccessible.h \
|
||||
gtkcontainercellaccessible.h \
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
|
||||
static GHashTable *listener_list = NULL;
|
||||
static gint listener_idx = 1;
|
||||
static GSList *key_listener_list = NULL;
|
||||
|
||||
typedef struct _GailUtilListenerInfo GailUtilListenerInfo;
|
||||
typedef struct _GailKeyEventInfo GailKeyEventInfo;
|
||||
@@ -318,6 +319,115 @@ gail_util_remove_global_event_listener (guint remove_listener)
|
||||
}
|
||||
}
|
||||
|
||||
static AtkKeyEventStruct *
|
||||
atk_key_event_from_gdk_event_key (GdkEventKey *key)
|
||||
{
|
||||
AtkKeyEventStruct *event = g_new0 (AtkKeyEventStruct, 1);
|
||||
switch (key->type)
|
||||
{
|
||||
case GDK_KEY_PRESS:
|
||||
event->type = ATK_KEY_EVENT_PRESS;
|
||||
break;
|
||||
case GDK_KEY_RELEASE:
|
||||
event->type = ATK_KEY_EVENT_RELEASE;
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
return NULL;
|
||||
}
|
||||
event->state = key->state;
|
||||
event->keyval = key->keyval;
|
||||
event->length = key->length;
|
||||
if (key->string && key->string [0] &&
|
||||
(key->state & GDK_CONTROL_MASK ||
|
||||
g_unichar_isgraph (g_utf8_get_char (key->string))))
|
||||
{
|
||||
event->string = key->string;
|
||||
}
|
||||
else if (key->type == GDK_KEY_PRESS ||
|
||||
key->type == GDK_KEY_RELEASE)
|
||||
{
|
||||
event->string = gdk_keyval_name (key->keyval);
|
||||
}
|
||||
event->keycode = key->hardware_keycode;
|
||||
event->timestamp = key->time;
|
||||
#ifdef GAIL_DEBUG
|
||||
g_print ("GailKey:\tsym %u\n\tmods %x\n\tcode %u\n\ttime %lx\n",
|
||||
(unsigned int) event->keyval,
|
||||
(unsigned int) event->state,
|
||||
(unsigned int) event->keycode,
|
||||
(unsigned long int) event->timestamp);
|
||||
#endif
|
||||
return event;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
AtkKeySnoopFunc func;
|
||||
gpointer data;
|
||||
guint key;
|
||||
} KeyEventListener;
|
||||
|
||||
gboolean
|
||||
_gail_util_key_snooper (GtkWidget *the_widget,
|
||||
GdkEventKey *event)
|
||||
{
|
||||
GSList *l;
|
||||
AtkKeyEventStruct *atk_event;
|
||||
gboolean result;
|
||||
|
||||
atk_event = atk_key_event_from_gdk_event_key (event);
|
||||
|
||||
result = FALSE;
|
||||
|
||||
for (l = key_listener_list; l; l = l->next)
|
||||
{
|
||||
KeyEventListener *listener = l->data;
|
||||
|
||||
result |= listener->func (atk_event, listener->data);
|
||||
}
|
||||
g_free (atk_event);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static guint
|
||||
gail_util_add_key_event_listener (AtkKeySnoopFunc listener_func,
|
||||
gpointer listener_data)
|
||||
{
|
||||
static guint key = 0;
|
||||
KeyEventListener *listener;
|
||||
|
||||
key++;
|
||||
|
||||
listener = g_slice_new0 (KeyEventListener);
|
||||
listener->func = listener_func;
|
||||
listener->data = listener_data;
|
||||
listener->key = key;
|
||||
|
||||
key_listener_list = g_slist_append (key_listener_list, listener);
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
static void
|
||||
gail_util_remove_key_event_listener (guint listener_key)
|
||||
{
|
||||
GSList *l;
|
||||
|
||||
for (l = key_listener_list; l; l = l->next)
|
||||
{
|
||||
KeyEventListener *listener = l->data;
|
||||
|
||||
if (listener->key == listener_key)
|
||||
{
|
||||
g_slice_free (KeyEventListener, listener);
|
||||
key_listener_list = g_slist_delete_link (key_listener_list, l);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static AtkObject *
|
||||
gail_util_get_root (void)
|
||||
{
|
||||
@@ -351,6 +461,8 @@ _gail_util_install (void)
|
||||
|
||||
atk_class->add_global_event_listener = gail_util_add_global_event_listener;
|
||||
atk_class->remove_global_event_listener = gail_util_remove_global_event_listener;
|
||||
atk_class->add_key_event_listener = gail_util_add_key_event_listener;
|
||||
atk_class->remove_key_event_listener = gail_util_remove_key_event_listener;
|
||||
atk_class->get_root = gail_util_get_root;
|
||||
atk_class->get_toolkit_name = gail_util_get_toolkit_name;
|
||||
atk_class->get_toolkit_version = gail_util_get_toolkit_version;
|
||||
|
||||
@@ -26,6 +26,9 @@ G_BEGIN_DECLS
|
||||
|
||||
void _gail_util_install (void);
|
||||
|
||||
gboolean _gail_util_key_snooper (GtkWidget *the_widget,
|
||||
GdkEventKey *event);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GAIL_UTIL_H__ */
|
||||
|
||||
104
gtk/a11y/gtkcolorswatchaccessible.c
Normal file
104
gtk/a11y/gtkcolorswatchaccessible.c
Normal file
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright 2012 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, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include "gtkcolorswatchaccessible.h"
|
||||
|
||||
static void atk_action_interface_init (AtkActionIface *iface);
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (GtkColorSwatchAccessible, _gtk_color_swatch_accessible, GTK_TYPE_WIDGET_ACCESSIBLE,
|
||||
G_IMPLEMENT_INTERFACE (ATK_TYPE_ACTION, atk_action_interface_init))
|
||||
|
||||
static void
|
||||
_gtk_color_swatch_accessible_class_init (GtkColorSwatchAccessibleClass *klass)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
_gtk_color_swatch_accessible_init (GtkColorSwatchAccessible *scale)
|
||||
{
|
||||
}
|
||||
|
||||
static gint
|
||||
gtk_color_swatch_accessible_get_n_actions (AtkAction *action)
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
|
||||
static const gchar *
|
||||
gtk_color_swatch_accessible_get_keybinding (AtkAction *action,
|
||||
gint i)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const gchar *
|
||||
gtk_color_swatch_accessible_get_name (AtkAction *action,
|
||||
gint i)
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
case 0: return "select";
|
||||
case 1: return "activate";
|
||||
case 2: return "customize";
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_color_swatch_accessible_do_action (AtkAction *action,
|
||||
gint i)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
|
||||
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (action));
|
||||
if (widget == NULL)
|
||||
return FALSE;
|
||||
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
gtk_widget_set_state_flags (widget, GTK_STATE_FLAG_SELECTED, FALSE);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
g_signal_emit_by_name (widget, "activate");
|
||||
break;
|
||||
|
||||
case 2:
|
||||
g_signal_emit_by_name (widget, "customize");
|
||||
break;
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
atk_action_interface_init (AtkActionIface *iface)
|
||||
{
|
||||
iface->do_action = gtk_color_swatch_accessible_do_action;
|
||||
iface->get_n_actions = gtk_color_swatch_accessible_get_n_actions;
|
||||
iface->get_keybinding = gtk_color_swatch_accessible_get_keybinding;
|
||||
iface->get_name = gtk_color_swatch_accessible_get_name;
|
||||
}
|
||||
51
gtk/a11y/gtkcolorswatchaccessible.h
Normal file
51
gtk/a11y/gtkcolorswatchaccessible.h
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 2012, Red Hat, Inc
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GTK_COLOR_SWATCH_ACCESSIBLE_H__
|
||||
#define __GTK_COLOR_SWATCH_ACCESSIBLE_H__
|
||||
|
||||
#include "gtkwidgetaccessible.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GTK_TYPE_COLOR_SWATCH_ACCESSIBLE (_gtk_color_swatch_accessible_get_type ())
|
||||
#define GTK_COLOR_SWATCH_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_COLOR_SWATCH_ACCESSIBLE, GtkColorSwatchAccessible))
|
||||
#define GTK_COLOR_SWATCH_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_COLOR_SWATCH_ACCESSIBLE, GtkColorSwatchAccessibleClass))
|
||||
#define GTK_IS_COLOR_SWATCH_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_COLOR_SWATCH_ACCESSIBLE))
|
||||
#define GTK_IS_COLOR_SWATCH_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_COLOR_SWATCH_ACCESSIBLE))
|
||||
#define GTK_COLOR_SWATCH_ACCESSIBLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_COLOR_SWATCH_ACCESSIBLE, GtkColorSwatchAccessibleClass))
|
||||
|
||||
typedef struct _GtkColorSwatchAccessible GtkColorSwatchAccessible;
|
||||
typedef struct _GtkColorSwatchAccessibleClass GtkColorSwatchAccessibleClass;
|
||||
|
||||
struct _GtkColorSwatchAccessible
|
||||
{
|
||||
GtkWidgetAccessible parent;
|
||||
};
|
||||
|
||||
struct _GtkColorSwatchAccessibleClass
|
||||
{
|
||||
GtkWidgetAccessibleClass parent_class;
|
||||
};
|
||||
|
||||
GType _gtk_color_swatch_accessible_get_type (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_COLOR_SWATCH_ACCESSIBLE_H__ */
|
||||
@@ -45,13 +45,6 @@ struct _GtkTreeViewAccessibleCellInfo
|
||||
GtkTreeViewAccessible *view;
|
||||
};
|
||||
|
||||
/* signal handling */
|
||||
|
||||
static void cursor_changed (GtkTreeView *tree_view,
|
||||
GtkTreeViewAccessible *accessible);
|
||||
static gboolean focus_in (GtkWidget *widget);
|
||||
static gboolean focus_out (GtkWidget *widget);
|
||||
|
||||
/* Misc */
|
||||
|
||||
static int cell_info_get_index (GtkTreeView *tree_view,
|
||||
@@ -59,25 +52,13 @@ static int cell_info_get_index (GtkTreeView
|
||||
static gboolean is_cell_showing (GtkTreeView *tree_view,
|
||||
GdkRectangle *cell_rect);
|
||||
|
||||
static void cell_destroyed (gpointer data);
|
||||
static void cell_info_new (GtkTreeViewAccessible *accessible,
|
||||
GtkTreeModel *tree_model,
|
||||
static void cell_info_new (GtkTreeViewAccessible *accessible,
|
||||
GtkRBTree *tree,
|
||||
GtkRBNode *node,
|
||||
GtkTreeViewColumn *tv_col,
|
||||
GtkCellAccessible *cell);
|
||||
static gint get_column_number (GtkTreeView *tree_view,
|
||||
GtkTreeViewColumn *column);
|
||||
static gint get_focus_index (GtkTreeView *tree_view);
|
||||
static gint get_index (GtkTreeView *tree_view,
|
||||
GtkTreePath *path,
|
||||
gint actual_column);
|
||||
static void count_rows (GtkTreeModel *model,
|
||||
GtkTreeIter *iter,
|
||||
GtkTreePath *end_path,
|
||||
gint *count,
|
||||
gint level,
|
||||
gint depth);
|
||||
|
||||
static gboolean get_rbtree_column_from_index (GtkTreeView *tree_view,
|
||||
gint index,
|
||||
@@ -116,12 +97,8 @@ gtk_tree_view_accessible_get_data_quark (void)
|
||||
static void
|
||||
cell_info_free (GtkTreeViewAccessibleCellInfo *cell_info)
|
||||
{
|
||||
if (cell_info->cell)
|
||||
{
|
||||
g_object_steal_qdata (G_OBJECT (cell_info->cell),
|
||||
gtk_tree_view_accessible_get_data_quark ());
|
||||
gtk_accessible_set_widget (GTK_ACCESSIBLE (cell_info->cell), NULL);
|
||||
}
|
||||
gtk_accessible_set_widget (GTK_ACCESSIBLE (cell_info->cell), NULL);
|
||||
g_object_unref (cell_info->cell);
|
||||
|
||||
g_free (cell_info);
|
||||
}
|
||||
@@ -166,7 +143,6 @@ gtk_tree_view_accessible_initialize (AtkObject *obj,
|
||||
ATK_OBJECT_CLASS (_gtk_tree_view_accessible_parent_class)->initialize (obj, data);
|
||||
|
||||
accessible = GTK_TREE_VIEW_ACCESSIBLE (obj);
|
||||
accessible->focus_cell = NULL;
|
||||
|
||||
accessible->cell_infos = g_hash_table_new_full (cell_info_hash,
|
||||
cell_info_equal, NULL, (GDestroyNotify) cell_info_free);
|
||||
@@ -175,13 +151,6 @@ gtk_tree_view_accessible_initialize (AtkObject *obj,
|
||||
tree_view = GTK_TREE_VIEW (widget);
|
||||
tree_model = gtk_tree_view_get_model (tree_view);
|
||||
|
||||
g_signal_connect (tree_view, "cursor-changed",
|
||||
G_CALLBACK (cursor_changed), accessible);
|
||||
g_signal_connect (tree_view, "focus-in-event",
|
||||
G_CALLBACK (focus_in), NULL);
|
||||
g_signal_connect (tree_view, "focus-out-event",
|
||||
G_CALLBACK (focus_out), NULL);
|
||||
|
||||
if (tree_model)
|
||||
{
|
||||
if (gtk_tree_model_get_flags (tree_model) & GTK_TREE_MODEL_LIST_ONLY)
|
||||
@@ -248,11 +217,7 @@ gtk_tree_view_accessible_widget_unset (GtkAccessible *gtkaccessible)
|
||||
{
|
||||
GtkTreeViewAccessible *accessible = GTK_TREE_VIEW_ACCESSIBLE (gtkaccessible);
|
||||
|
||||
if (accessible->focus_cell)
|
||||
{
|
||||
g_object_unref (accessible->focus_cell);
|
||||
accessible->focus_cell = NULL;
|
||||
}
|
||||
g_hash_table_remove_all (accessible->cell_infos);
|
||||
|
||||
GTK_ACCESSIBLE_CLASS (_gtk_tree_view_accessible_parent_class)->widget_unset (gtkaccessible);
|
||||
}
|
||||
@@ -387,6 +352,94 @@ peek_cell (GtkTreeViewAccessible *accessible,
|
||||
return cell_info->cell;
|
||||
}
|
||||
|
||||
static GtkCellAccessible *
|
||||
create_cell (GtkTreeView *treeview,
|
||||
GtkTreeViewAccessible *accessible,
|
||||
GtkRBTree *tree,
|
||||
GtkRBNode *node,
|
||||
GtkTreeViewColumn *column)
|
||||
{
|
||||
GtkCellRenderer *renderer;
|
||||
AtkObject *parent;
|
||||
GList *renderer_list;
|
||||
GList *l;
|
||||
GtkContainerCellAccessible *container = NULL;
|
||||
GtkCellAccessible *cell;
|
||||
|
||||
renderer_list = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (column));
|
||||
|
||||
/* If there is not exactly one renderer in the list,
|
||||
* make a container
|
||||
*/
|
||||
if (renderer_list == NULL || renderer_list->next)
|
||||
{
|
||||
GtkCellAccessible *container_cell;
|
||||
|
||||
container = _gtk_container_cell_accessible_new ();
|
||||
|
||||
container_cell = GTK_CELL_ACCESSIBLE (container);
|
||||
_gtk_cell_accessible_initialise (container_cell, GTK_WIDGET (treeview), ATK_OBJECT (accessible));
|
||||
|
||||
/* The GtkTreeViewAccessibleCellInfo structure for the container will
|
||||
* be before the ones for the cells so that the first one we find for
|
||||
* a position will be for the container
|
||||
*/
|
||||
cell_info_new (accessible, tree, node, column, container_cell);
|
||||
parent = ATK_OBJECT (container);
|
||||
}
|
||||
else
|
||||
parent = ATK_OBJECT (accessible);
|
||||
|
||||
cell = NULL;
|
||||
|
||||
for (l = renderer_list; l; l = l->next)
|
||||
{
|
||||
renderer = GTK_CELL_RENDERER (l->data);
|
||||
|
||||
cell = GTK_CELL_ACCESSIBLE (_gtk_renderer_cell_accessible_new (renderer));
|
||||
|
||||
/* Create the GtkTreeViewAccessibleCellInfo for this cell */
|
||||
if (parent == ATK_OBJECT (accessible))
|
||||
cell_info_new (accessible, tree, node, column, cell);
|
||||
|
||||
_gtk_cell_accessible_initialise (cell, GTK_WIDGET (treeview), parent);
|
||||
|
||||
if (container)
|
||||
_gtk_container_cell_accessible_add_child (container, cell);
|
||||
}
|
||||
g_list_free (renderer_list);
|
||||
if (container)
|
||||
cell = GTK_CELL_ACCESSIBLE (container);
|
||||
|
||||
set_cell_data (treeview, accessible, cell);
|
||||
_gtk_cell_accessible_update_cache (cell);
|
||||
|
||||
if (gtk_tree_view_get_expander_column (treeview) == column)
|
||||
{
|
||||
AtkRelationSet *relation_set;
|
||||
AtkRelation* relation;
|
||||
AtkObject *parent_node;
|
||||
|
||||
relation_set = atk_object_ref_relation_set (ATK_OBJECT (cell));
|
||||
|
||||
if (tree->parent_tree)
|
||||
{
|
||||
parent_node = ATK_OBJECT (peek_cell (accessible, tree->parent_tree, tree->parent_node, column));
|
||||
if (parent_node == NULL)
|
||||
parent_node = ATK_OBJECT (create_cell (treeview, accessible, tree->parent_tree, tree->parent_node, column));
|
||||
}
|
||||
else
|
||||
parent_node = ATK_OBJECT (accessible);
|
||||
relation = atk_relation_new (&parent_node, 1, ATK_RELATION_NODE_CHILD_OF);
|
||||
atk_relation_set_add (relation_set, relation);
|
||||
atk_object_add_relationship (parent_node, ATK_RELATION_NODE_PARENT_OF, ATK_OBJECT (cell));
|
||||
g_object_unref (relation);
|
||||
g_object_unref (relation_set);
|
||||
}
|
||||
|
||||
return cell;
|
||||
}
|
||||
|
||||
static AtkObject *
|
||||
gtk_tree_view_accessible_ref_child (AtkObject *obj,
|
||||
gint i)
|
||||
@@ -395,18 +448,10 @@ gtk_tree_view_accessible_ref_child (AtkObject *obj,
|
||||
GtkTreeViewAccessible *accessible;
|
||||
GtkCellAccessible *cell;
|
||||
GtkTreeView *tree_view;
|
||||
GtkTreeModel *tree_model;
|
||||
GtkCellRenderer *renderer;
|
||||
GtkTreeViewColumn *tv_col;
|
||||
GtkTreePath *path;
|
||||
GtkRBTree *tree;
|
||||
GtkRBNode *node;
|
||||
AtkObject *child;
|
||||
AtkObject *parent;
|
||||
GList *renderer_list;
|
||||
GList *l;
|
||||
GtkContainerCellAccessible *container = NULL;
|
||||
gint focus_index;
|
||||
|
||||
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
|
||||
if (widget == NULL)
|
||||
@@ -431,109 +476,10 @@ gtk_tree_view_accessible_ref_child (AtkObject *obj,
|
||||
return NULL;
|
||||
|
||||
cell = peek_cell (accessible, tree, node, tv_col);
|
||||
if (cell)
|
||||
return g_object_ref (cell);
|
||||
if (cell == NULL)
|
||||
cell = create_cell (tree_view, accessible, tree, node, tv_col);
|
||||
|
||||
if (accessible->focus_cell == NULL)
|
||||
focus_index = get_focus_index (tree_view);
|
||||
else
|
||||
focus_index = -1;
|
||||
|
||||
path = _gtk_tree_path_new_from_rbtree (tree, node);
|
||||
tree_model = gtk_tree_view_get_model (tree_view);
|
||||
|
||||
renderer_list = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (tv_col));
|
||||
|
||||
/* If there is not exactly one renderer in the list,
|
||||
* make a container
|
||||
*/
|
||||
if (renderer_list == NULL || renderer_list->next)
|
||||
{
|
||||
GtkCellAccessible *container_cell;
|
||||
|
||||
container = _gtk_container_cell_accessible_new ();
|
||||
|
||||
container_cell = GTK_CELL_ACCESSIBLE (container);
|
||||
_gtk_cell_accessible_initialise (container_cell, widget, ATK_OBJECT (accessible));
|
||||
|
||||
/* The GtkTreeViewAccessibleCellInfo structure for the container will
|
||||
* be before the ones for the cells so that the first one we find for
|
||||
* a position will be for the container
|
||||
*/
|
||||
cell_info_new (accessible, tree_model, tree, node, tv_col, container_cell);
|
||||
parent = ATK_OBJECT (container);
|
||||
}
|
||||
else
|
||||
parent = ATK_OBJECT (accessible);
|
||||
|
||||
child = NULL;
|
||||
|
||||
for (l = renderer_list; l; l = l->next)
|
||||
{
|
||||
renderer = GTK_CELL_RENDERER (l->data);
|
||||
|
||||
child = _gtk_renderer_cell_accessible_new (renderer);
|
||||
|
||||
cell = GTK_CELL_ACCESSIBLE (child);
|
||||
|
||||
/* Create the GtkTreeViewAccessibleCellInfo for this cell */
|
||||
if (parent == ATK_OBJECT (accessible))
|
||||
cell_info_new (accessible, tree_model, tree, node, tv_col, cell);
|
||||
|
||||
_gtk_cell_accessible_initialise (cell, widget, parent);
|
||||
|
||||
if (container)
|
||||
_gtk_container_cell_accessible_add_child (container, cell);
|
||||
|
||||
_gtk_cell_accessible_add_state (cell, ATK_STATE_FOCUSABLE, FALSE);
|
||||
if (focus_index == i)
|
||||
{
|
||||
accessible->focus_cell = g_object_ref (cell);
|
||||
_gtk_cell_accessible_add_state (cell, ATK_STATE_FOCUSED, FALSE);
|
||||
g_signal_emit_by_name (accessible, "active-descendant-changed", cell);
|
||||
}
|
||||
}
|
||||
g_list_free (renderer_list);
|
||||
if (container)
|
||||
child = ATK_OBJECT (container);
|
||||
|
||||
set_cell_data (tree_view, accessible, GTK_CELL_ACCESSIBLE (child));
|
||||
_gtk_cell_accessible_update_cache (GTK_CELL_ACCESSIBLE (child));
|
||||
|
||||
if (gtk_tree_view_get_expander_column (tree_view) == tv_col)
|
||||
{
|
||||
AtkRelationSet *relation_set;
|
||||
AtkObject *accessible_array[1];
|
||||
AtkRelation* relation;
|
||||
AtkObject *parent_node;
|
||||
|
||||
relation_set = atk_object_ref_relation_set (ATK_OBJECT (child));
|
||||
|
||||
gtk_tree_path_up (path);
|
||||
if (gtk_tree_path_get_depth (path) == 0)
|
||||
parent_node = obj;
|
||||
else
|
||||
{
|
||||
gint parent_index;
|
||||
|
||||
parent_index = get_index (tree_view, path, i % get_n_columns (tree_view));
|
||||
parent_node = atk_object_ref_accessible_child (obj, parent_index);
|
||||
}
|
||||
accessible_array[0] = parent_node;
|
||||
relation = atk_relation_new (accessible_array, 1,
|
||||
ATK_RELATION_NODE_CHILD_OF);
|
||||
atk_relation_set_add (relation_set, relation);
|
||||
atk_object_add_relationship (parent_node, ATK_RELATION_NODE_PARENT_OF, child);
|
||||
g_object_unref (relation);
|
||||
g_object_unref (relation_set);
|
||||
}
|
||||
gtk_tree_path_free (path);
|
||||
|
||||
/* We do not increase the reference count here; when g_object_unref()
|
||||
* is called for the cell then cell_destroyed() is called and this
|
||||
* removes the cell from the cache.
|
||||
*/
|
||||
return child;
|
||||
return g_object_ref (cell);
|
||||
}
|
||||
|
||||
static AtkStateSet*
|
||||
@@ -584,46 +530,6 @@ _gtk_tree_view_accessible_init (GtkTreeViewAccessible *view)
|
||||
{
|
||||
}
|
||||
|
||||
gint
|
||||
get_focus_index (GtkTreeView *tree_view)
|
||||
{
|
||||
GtkTreePath *focus_path;
|
||||
GtkTreeViewColumn *focus_column;
|
||||
gint index;
|
||||
|
||||
gtk_tree_view_get_cursor (tree_view, &focus_path, &focus_column);
|
||||
if (focus_path && focus_column)
|
||||
index = get_index (tree_view, focus_path,
|
||||
get_column_number (tree_view, focus_column));
|
||||
else
|
||||
index = -1;
|
||||
|
||||
if (focus_path)
|
||||
gtk_tree_path_free (focus_path);
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
/* This function returns a reference to the accessible object
|
||||
* for the cell in the treeview which has focus, if any
|
||||
*/
|
||||
static AtkObject *
|
||||
gtk_tree_view_accessible_ref_focus_cell (GtkTreeView *tree_view)
|
||||
{
|
||||
AtkObject *focus_cell = NULL;
|
||||
AtkObject *atk_obj;
|
||||
gint focus_index;
|
||||
|
||||
focus_index = get_focus_index (tree_view);
|
||||
if (focus_index >= 0)
|
||||
{
|
||||
atk_obj = gtk_widget_get_accessible (GTK_WIDGET (tree_view));
|
||||
focus_cell = atk_object_ref_accessible_child (atk_obj, focus_index);
|
||||
}
|
||||
|
||||
return focus_cell;
|
||||
}
|
||||
|
||||
/* atkcomponent.h */
|
||||
|
||||
static AtkObject *
|
||||
@@ -635,10 +541,12 @@ gtk_tree_view_accessible_ref_accessible_at_point (AtkComponent *component,
|
||||
GtkWidget *widget;
|
||||
GtkTreeView *tree_view;
|
||||
GtkTreePath *path;
|
||||
GtkTreeViewColumn *tv_column;
|
||||
GtkTreeViewColumn *column;
|
||||
gint x_pos, y_pos;
|
||||
gint bx, by;
|
||||
gboolean ret_val;
|
||||
GtkCellAccessible *cell;
|
||||
GtkRBTree *tree;
|
||||
GtkRBNode *node;
|
||||
|
||||
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (component));
|
||||
if (widget == NULL)
|
||||
@@ -648,21 +556,22 @@ gtk_tree_view_accessible_ref_accessible_at_point (AtkComponent *component,
|
||||
|
||||
atk_component_get_extents (component, &x_pos, &y_pos, NULL, NULL, coord_type);
|
||||
gtk_tree_view_convert_widget_to_bin_window_coords (tree_view, x, y, &bx, &by);
|
||||
ret_val = gtk_tree_view_get_path_at_pos (tree_view,
|
||||
bx - x_pos, by - y_pos,
|
||||
&path, &tv_column, NULL, NULL);
|
||||
if (ret_val)
|
||||
if (!gtk_tree_view_get_path_at_pos (tree_view,
|
||||
bx - x_pos, by - y_pos,
|
||||
&path, &column, NULL, NULL))
|
||||
return NULL;
|
||||
|
||||
if (_gtk_tree_view_find_node (tree_view, path, &tree, &node))
|
||||
{
|
||||
gint index, column;
|
||||
|
||||
column = get_column_number (tree_view, tv_column);
|
||||
index = get_index (tree_view, path, column);
|
||||
gtk_tree_path_free (path);
|
||||
|
||||
return gtk_tree_view_accessible_ref_child (ATK_OBJECT (component), index);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
cell = peek_cell (GTK_TREE_VIEW_ACCESSIBLE (component), tree, node, column);
|
||||
if (cell == NULL)
|
||||
cell = create_cell (tree_view, GTK_TREE_VIEW_ACCESSIBLE (component), tree, node, column);
|
||||
|
||||
return g_object_ref (cell);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1434,89 +1343,6 @@ gtk_cell_accessible_parent_interface_init (GtkCellAccessibleParentIface *iface)
|
||||
iface->edit = gtk_tree_view_accessible_edit;
|
||||
}
|
||||
|
||||
/* signal handling */
|
||||
|
||||
static void
|
||||
cursor_changed (GtkTreeView *tree_view,
|
||||
GtkTreeViewAccessible *accessible)
|
||||
{
|
||||
AtkObject *cell;
|
||||
|
||||
cell = gtk_tree_view_accessible_ref_focus_cell (tree_view);
|
||||
if (cell)
|
||||
{
|
||||
if (cell != accessible->focus_cell)
|
||||
{
|
||||
if (accessible->focus_cell)
|
||||
{
|
||||
_gtk_cell_accessible_remove_state (GTK_CELL_ACCESSIBLE (accessible->focus_cell), ATK_STATE_ACTIVE, FALSE);
|
||||
_gtk_cell_accessible_remove_state (GTK_CELL_ACCESSIBLE (accessible->focus_cell), ATK_STATE_FOCUSED, FALSE);
|
||||
g_object_unref (accessible->focus_cell);
|
||||
accessible->focus_cell = cell;
|
||||
}
|
||||
|
||||
if (gtk_widget_has_focus (GTK_WIDGET (tree_view)))
|
||||
{
|
||||
_gtk_cell_accessible_add_state (GTK_CELL_ACCESSIBLE (cell), ATK_STATE_ACTIVE, FALSE);
|
||||
_gtk_cell_accessible_add_state (GTK_CELL_ACCESSIBLE (cell), ATK_STATE_FOCUSED, FALSE);
|
||||
}
|
||||
|
||||
g_signal_emit_by_name (accessible, "active-descendant-changed", cell);
|
||||
}
|
||||
else
|
||||
g_object_unref (cell);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
focus_in (GtkWidget *widget)
|
||||
{
|
||||
GtkTreeView *tree_view;
|
||||
GtkTreeViewAccessible *accessible;
|
||||
AtkStateSet *state_set;
|
||||
AtkObject *cell;
|
||||
|
||||
tree_view = GTK_TREE_VIEW (widget);
|
||||
accessible = GTK_TREE_VIEW_ACCESSIBLE (gtk_widget_get_accessible (widget));
|
||||
|
||||
if (accessible->focus_cell == NULL)
|
||||
{
|
||||
cell = gtk_tree_view_accessible_ref_focus_cell (tree_view);
|
||||
if (cell)
|
||||
{
|
||||
state_set = atk_object_ref_state_set (cell);
|
||||
if (state_set)
|
||||
{
|
||||
if (!atk_state_set_contains_state (state_set, ATK_STATE_FOCUSED))
|
||||
{
|
||||
_gtk_cell_accessible_add_state (GTK_CELL_ACCESSIBLE (cell), ATK_STATE_ACTIVE, FALSE);
|
||||
accessible->focus_cell = cell;
|
||||
_gtk_cell_accessible_add_state (GTK_CELL_ACCESSIBLE (cell), ATK_STATE_FOCUSED, FALSE);
|
||||
g_signal_emit_by_name (accessible, "active-descendant-changed", cell);
|
||||
}
|
||||
g_object_unref (state_set);
|
||||
}
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
focus_out (GtkWidget *widget)
|
||||
{
|
||||
GtkTreeViewAccessible *accessible;
|
||||
|
||||
accessible = GTK_TREE_VIEW_ACCESSIBLE (gtk_widget_get_accessible (widget));
|
||||
if (accessible->focus_cell)
|
||||
{
|
||||
_gtk_cell_accessible_remove_state (GTK_CELL_ACCESSIBLE (accessible->focus_cell), ATK_STATE_ACTIVE, FALSE);
|
||||
_gtk_cell_accessible_remove_state (GTK_CELL_ACCESSIBLE (accessible->focus_cell), ATK_STATE_FOCUSED, FALSE);
|
||||
g_object_unref (accessible->focus_cell);
|
||||
accessible->focus_cell = NULL;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_tree_view_accessible_reorder (GtkTreeView *treeview)
|
||||
{
|
||||
@@ -1571,16 +1397,6 @@ is_cell_showing (GtkTreeView *tree_view,
|
||||
|
||||
/* Misc Private */
|
||||
|
||||
static void
|
||||
cell_destroyed (gpointer data)
|
||||
{
|
||||
GtkTreeViewAccessibleCellInfo *cell_info = data;
|
||||
|
||||
cell_info->cell = NULL;
|
||||
|
||||
g_hash_table_remove (cell_info->view->cell_infos, cell_info);
|
||||
}
|
||||
|
||||
static int
|
||||
cell_info_get_index (GtkTreeView *tree_view,
|
||||
GtkTreeViewAccessibleCellInfo *info)
|
||||
@@ -1596,7 +1412,6 @@ cell_info_get_index (GtkTreeView *tree_view,
|
||||
|
||||
static void
|
||||
cell_info_new (GtkTreeViewAccessible *accessible,
|
||||
GtkTreeModel *tree_model,
|
||||
GtkRBTree *tree,
|
||||
GtkRBNode *node,
|
||||
GtkTreeViewColumn *tv_col,
|
||||
@@ -1609,13 +1424,12 @@ cell_info_new (GtkTreeViewAccessible *accessible,
|
||||
cell_info->tree = tree;
|
||||
cell_info->node = node;
|
||||
cell_info->cell_col_ref = tv_col;
|
||||
cell_info->cell = cell;
|
||||
cell_info->cell = g_object_ref (cell);
|
||||
cell_info->view = accessible;
|
||||
|
||||
g_object_set_qdata_full (G_OBJECT (cell),
|
||||
gtk_tree_view_accessible_get_data_quark (),
|
||||
cell_info,
|
||||
cell_destroyed);
|
||||
g_object_set_qdata (G_OBJECT (cell),
|
||||
gtk_tree_view_accessible_get_data_quark (),
|
||||
cell_info);
|
||||
|
||||
g_hash_table_replace (accessible->cell_infos, cell_info, cell_info);
|
||||
}
|
||||
@@ -1650,93 +1464,6 @@ get_column_number (GtkTreeView *treeview,
|
||||
return number;
|
||||
}
|
||||
|
||||
static gint
|
||||
get_index (GtkTreeView *tree_view,
|
||||
GtkTreePath *path,
|
||||
gint actual_column)
|
||||
{
|
||||
gint depth = 0;
|
||||
gint index = 1;
|
||||
gint *indices = NULL;
|
||||
|
||||
if (path)
|
||||
{
|
||||
depth = gtk_tree_path_get_depth (path);
|
||||
indices = gtk_tree_path_get_indices (path);
|
||||
}
|
||||
|
||||
if (depth > 1)
|
||||
{
|
||||
GtkTreePath *copy_path;
|
||||
GtkTreeModel *model;
|
||||
|
||||
model = gtk_tree_view_get_model (tree_view);
|
||||
copy_path = gtk_tree_path_copy (path);
|
||||
gtk_tree_path_up (copy_path);
|
||||
count_rows (model, NULL, copy_path, &index, 0, depth);
|
||||
gtk_tree_path_free (copy_path);
|
||||
}
|
||||
|
||||
if (path)
|
||||
index += indices[depth - 1];
|
||||
index *= get_n_columns (tree_view);
|
||||
index += actual_column;
|
||||
return index;
|
||||
}
|
||||
|
||||
/* The function count_rows counts the number of rows starting at iter
|
||||
* and ending at end_path. The value of level is the depth of iter and
|
||||
* the value of depth is the depth of end_path. Rows at depth before
|
||||
* end_path are counted. This functions counts rows which are not visible
|
||||
* because an ancestor is collapsed.
|
||||
*/
|
||||
static void
|
||||
count_rows (GtkTreeModel *model,
|
||||
GtkTreeIter *iter,
|
||||
GtkTreePath *end_path,
|
||||
gint *count,
|
||||
gint level,
|
||||
gint depth)
|
||||
{
|
||||
GtkTreeIter child_iter;
|
||||
|
||||
if (!model)
|
||||
return;
|
||||
|
||||
level++;
|
||||
*count += gtk_tree_model_iter_n_children (model, iter);
|
||||
|
||||
if (gtk_tree_model_get_flags (model) & GTK_TREE_MODEL_LIST_ONLY)
|
||||
return;
|
||||
|
||||
if (level >= depth)
|
||||
return;
|
||||
|
||||
if (gtk_tree_model_iter_children (model, &child_iter, iter))
|
||||
{
|
||||
gboolean ret_val = TRUE;
|
||||
|
||||
while (ret_val)
|
||||
{
|
||||
if (level == depth - 1)
|
||||
{
|
||||
GtkTreePath *iter_path;
|
||||
gboolean finished = FALSE;
|
||||
|
||||
iter_path = gtk_tree_model_get_path (model, &child_iter);
|
||||
if (end_path && gtk_tree_path_compare (iter_path, end_path) >= 0)
|
||||
finished = TRUE;
|
||||
gtk_tree_path_free (iter_path);
|
||||
if (finished)
|
||||
break;
|
||||
}
|
||||
if (gtk_tree_model_iter_has_child (model, &child_iter))
|
||||
count_rows (model, &child_iter, end_path, count, level, depth);
|
||||
ret_val = gtk_tree_model_iter_next (model, &child_iter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
get_rbtree_column_from_index (GtkTreeView *tree_view,
|
||||
gint index,
|
||||
@@ -2080,6 +1807,60 @@ _gtk_tree_view_accessible_toggle_visibility (GtkTreeView *treeview,
|
||||
id);
|
||||
}
|
||||
|
||||
GtkTreeViewColumn *
|
||||
get_effective_focus_column (GtkTreeView *treeview,
|
||||
GtkTreeViewColumn *column)
|
||||
{
|
||||
if (column == NULL)
|
||||
column = get_visible_column (treeview, 0);
|
||||
|
||||
return column;
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_tree_view_accessible_update_focus_column (GtkTreeView *treeview,
|
||||
GtkTreeViewColumn *old_focus,
|
||||
GtkTreeViewColumn *new_focus)
|
||||
{
|
||||
GtkTreeViewAccessible *accessible;
|
||||
AtkObject *obj;
|
||||
GtkRBTree *cursor_tree;
|
||||
GtkRBNode *cursor_node;
|
||||
GtkCellAccessible *cell;
|
||||
|
||||
old_focus = get_effective_focus_column (treeview, old_focus);
|
||||
new_focus = get_effective_focus_column (treeview, new_focus);
|
||||
if (old_focus == new_focus)
|
||||
return;
|
||||
|
||||
obj = _gtk_widget_peek_accessible (GTK_WIDGET (treeview));
|
||||
if (obj == NULL)
|
||||
return;
|
||||
|
||||
accessible = GTK_TREE_VIEW_ACCESSIBLE (obj);
|
||||
|
||||
if (!_gtk_tree_view_get_cursor_node (treeview, &cursor_tree, &cursor_node))
|
||||
return;
|
||||
|
||||
if (old_focus)
|
||||
{
|
||||
cell = peek_cell (accessible, cursor_tree, cursor_node, old_focus);
|
||||
if (cell != NULL)
|
||||
_gtk_cell_accessible_state_changed (cell, GTK_CELL_RENDERER_FOCUSED, 0);
|
||||
}
|
||||
|
||||
if (new_focus)
|
||||
{
|
||||
cell = peek_cell (accessible, cursor_tree, cursor_node, new_focus);
|
||||
if (cell != NULL)
|
||||
_gtk_cell_accessible_state_changed (cell, 0, GTK_CELL_RENDERER_FOCUSED);
|
||||
else
|
||||
cell = create_cell (treeview, accessible, cursor_tree, cursor_node, new_focus);
|
||||
|
||||
g_signal_emit_by_name (accessible, "active-descendant-changed", cell);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_tree_view_accessible_add_state (GtkTreeView *treeview,
|
||||
GtkRBTree *tree,
|
||||
@@ -2096,6 +1877,28 @@ _gtk_tree_view_accessible_add_state (GtkTreeView *treeview,
|
||||
|
||||
accessible = GTK_TREE_VIEW_ACCESSIBLE (obj);
|
||||
|
||||
if (state == GTK_CELL_RENDERER_FOCUSED)
|
||||
{
|
||||
GtkTreeViewColumn *focus_column;
|
||||
|
||||
focus_column = get_effective_focus_column (treeview, _gtk_tree_view_get_focus_column (treeview));
|
||||
|
||||
if (focus_column)
|
||||
{
|
||||
GtkCellAccessible *cell;
|
||||
|
||||
cell = peek_cell (accessible, tree, node, focus_column);
|
||||
if (cell != NULL)
|
||||
_gtk_cell_accessible_state_changed (cell, 0, state);
|
||||
else
|
||||
cell = create_cell (treeview, accessible, tree, node, focus_column);
|
||||
|
||||
g_signal_emit_by_name (accessible, "active-descendant-changed", cell);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < gtk_tree_view_get_n_columns (treeview); i++)
|
||||
{
|
||||
GtkCellAccessible *cell = peek_cell (accessible,
|
||||
@@ -2128,6 +1931,25 @@ _gtk_tree_view_accessible_remove_state (GtkTreeView *treeview,
|
||||
|
||||
accessible = GTK_TREE_VIEW_ACCESSIBLE (obj);
|
||||
|
||||
if (state == GTK_CELL_RENDERER_FOCUSED)
|
||||
{
|
||||
GtkTreeViewColumn *focus_column;
|
||||
|
||||
focus_column = get_effective_focus_column (treeview, _gtk_tree_view_get_focus_column (treeview));
|
||||
|
||||
if (focus_column)
|
||||
{
|
||||
GtkCellAccessible *cell = peek_cell (accessible,
|
||||
tree, node,
|
||||
focus_column);
|
||||
|
||||
if (cell != NULL)
|
||||
_gtk_cell_accessible_state_changed (cell, 0, state);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < gtk_tree_view_get_n_columns (treeview); i++)
|
||||
{
|
||||
GtkCellAccessible *cell = peek_cell (accessible,
|
||||
|
||||
@@ -40,7 +40,6 @@ struct _GtkTreeViewAccessible
|
||||
GtkContainerAccessible parent;
|
||||
|
||||
GHashTable *cell_infos;
|
||||
AtkObject *focus_cell;
|
||||
};
|
||||
|
||||
struct _GtkTreeViewAccessibleClass
|
||||
@@ -74,6 +73,10 @@ void _gtk_tree_view_accessible_reorder_column(GtkTreeView *tree
|
||||
void _gtk_tree_view_accessible_toggle_visibility
|
||||
(GtkTreeView *treeview,
|
||||
GtkTreeViewColumn *column);
|
||||
void _gtk_tree_view_accessible_update_focus_column
|
||||
(GtkTreeView *treeview,
|
||||
GtkTreeViewColumn *old_focus,
|
||||
GtkTreeViewColumn *new_focus);
|
||||
|
||||
void _gtk_tree_view_accessible_add_state (GtkTreeView *treeview,
|
||||
GtkRBTree *tree,
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#define GDK_DISABLE_DEPRECATION_WARNINGS
|
||||
|
||||
#include "gtkcolorsel.h"
|
||||
|
||||
#include <math.h>
|
||||
@@ -37,6 +39,7 @@
|
||||
#include "gtkhsv.h"
|
||||
#include "gtkwindow.h"
|
||||
#include "gtkselection.h"
|
||||
#include "gtkcolorutils.h"
|
||||
#include "gtkdnd.h"
|
||||
#include "gtkdrawingarea.h"
|
||||
#include "gtkframe.h"
|
||||
@@ -62,7 +65,7 @@
|
||||
|
||||
/**
|
||||
* SECTION:gtkcolorsel
|
||||
* @Short_description: A widget used to select a color
|
||||
* @Short_description: Deprecated widget used to select a color
|
||||
* @Title: GtkColorSelection
|
||||
*
|
||||
* The #GtkColorSelection is a widget that is used to select
|
||||
@@ -1553,7 +1556,7 @@ palette_release (GtkWidget *drawing_area,
|
||||
|
||||
gtk_widget_grab_focus (drawing_area);
|
||||
|
||||
if (event->button == 1 &&
|
||||
if (event->button == GDK_BUTTON_PRIMARY &&
|
||||
g_object_get_data (G_OBJECT (drawing_area),
|
||||
"gtk-colorsel-have-pointer") != NULL)
|
||||
{
|
||||
@@ -1816,7 +1819,7 @@ mouse_release (GtkWidget *invisible,
|
||||
{
|
||||
/* GtkColorSelection *colorsel = data; */
|
||||
|
||||
if (event->button != 1)
|
||||
if (event->button != GDK_BUTTON_PRIMARY)
|
||||
return FALSE;
|
||||
|
||||
grab_color_at_pointer (gdk_event_get_screen ((GdkEvent *) event),
|
||||
@@ -1912,7 +1915,7 @@ mouse_press (GtkWidget *invisible,
|
||||
GdkEventButton *event,
|
||||
gpointer data)
|
||||
{
|
||||
if (event->type == GDK_BUTTON_PRESS && event->button == 1)
|
||||
if (event->type == GDK_BUTTON_PRESS && event->button == GDK_BUTTON_PRIMARY)
|
||||
{
|
||||
g_signal_connect (invisible, "motion-notify-event",
|
||||
G_CALLBACK (mouse_motion), data);
|
||||
@@ -3068,7 +3071,7 @@ gtk_color_selection_palette_to_string (const GdkColor *colors,
|
||||
* tries to modify the palette in a color selection.
|
||||
*
|
||||
* This function should save the new palette contents, and update
|
||||
* the #GtkSettings::gtk-color-palette GtkSettings property so all
|
||||
* the #GtkSettings:gtk-color-palette GtkSettings property so all
|
||||
* GtkColorSelection widgets will be modified.
|
||||
*
|
||||
* Return value: the previous change palette hook (that was replaced)
|
||||
@@ -89,51 +89,67 @@ struct _GtkColorSelectionClass
|
||||
/* ColorSelection */
|
||||
|
||||
GType gtk_color_selection_get_type (void) G_GNUC_CONST;
|
||||
GDK_DEPRECATED_FOR(gtk_color_chooser_widget_new)
|
||||
GtkWidget *gtk_color_selection_new (void);
|
||||
GDK_DEPRECATED_FOR(gtk_color_chooser_get_use_alpha)
|
||||
gboolean gtk_color_selection_get_has_opacity_control (GtkColorSelection *colorsel);
|
||||
GDK_DEPRECATED_FOR(gtk_color_chooser_set_use_alpha)
|
||||
void gtk_color_selection_set_has_opacity_control (GtkColorSelection *colorsel,
|
||||
gboolean has_opacity);
|
||||
GDK_DEPRECATED
|
||||
gboolean gtk_color_selection_get_has_palette (GtkColorSelection *colorsel);
|
||||
GDK_DEPRECATED
|
||||
void gtk_color_selection_set_has_palette (GtkColorSelection *colorsel,
|
||||
gboolean has_palette);
|
||||
|
||||
|
||||
GDK_DEPRECATED_FOR(gtk_color_chooser_set_rgba)
|
||||
void gtk_color_selection_set_current_alpha (GtkColorSelection *colorsel,
|
||||
guint16 alpha);
|
||||
GDK_DEPRECATED_FOR(gtk_color_chooser_get_rgba)
|
||||
guint16 gtk_color_selection_get_current_alpha (GtkColorSelection *colorsel);
|
||||
GDK_DEPRECATED
|
||||
void gtk_color_selection_set_previous_alpha (GtkColorSelection *colorsel,
|
||||
guint16 alpha);
|
||||
GDK_DEPRECATED
|
||||
guint16 gtk_color_selection_get_previous_alpha (GtkColorSelection *colorsel);
|
||||
|
||||
GDK_DEPRECATED_FOR(gtk_color_chooser_set_rgba)
|
||||
void gtk_color_selection_set_current_rgba (GtkColorSelection *colorsel,
|
||||
const GdkRGBA *rgba);
|
||||
GDK_DEPRECATED_FOR(gtk_color_chooser_get_rgba)
|
||||
void gtk_color_selection_get_current_rgba (GtkColorSelection *colorsel,
|
||||
GdkRGBA *rgba);
|
||||
GDK_DEPRECATED
|
||||
void gtk_color_selection_set_previous_rgba (GtkColorSelection *colorsel,
|
||||
const GdkRGBA *rgba);
|
||||
GDK_DEPRECATED
|
||||
void gtk_color_selection_get_previous_rgba (GtkColorSelection *colorsel,
|
||||
GdkRGBA *rgba);
|
||||
|
||||
GDK_DEPRECATED
|
||||
gboolean gtk_color_selection_is_adjusting (GtkColorSelection *colorsel);
|
||||
|
||||
GDK_DEPRECATED
|
||||
gboolean gtk_color_selection_palette_from_string (const gchar *str,
|
||||
GdkColor **colors,
|
||||
gint *n_colors);
|
||||
GDK_DEPRECATED
|
||||
gchar* gtk_color_selection_palette_to_string (const GdkColor *colors,
|
||||
gint n_colors);
|
||||
|
||||
GtkColorSelectionChangePaletteWithScreenFunc gtk_color_selection_set_change_palette_with_screen_hook (GtkColorSelectionChangePaletteWithScreenFunc func);
|
||||
|
||||
GDK_DEPRECATED_FOR(gtk_color_selection_set_current_rgba)
|
||||
GDK_DEPRECATED_FOR(gtk_color_chooser_set_rgba)
|
||||
void gtk_color_selection_set_current_color (GtkColorSelection *colorsel,
|
||||
const GdkColor *color);
|
||||
GDK_DEPRECATED_FOR(gtk_color_selection_get_current_rgba)
|
||||
GDK_DEPRECATED_FOR(gtk_color_chooser_get_rgba)
|
||||
void gtk_color_selection_get_current_color (GtkColorSelection *colorsel,
|
||||
GdkColor *color);
|
||||
GDK_DEPRECATED_FOR(gtk_color_selection_set_previous_rgba)
|
||||
GDK_DEPRECATED
|
||||
void gtk_color_selection_set_previous_color (GtkColorSelection *colorsel,
|
||||
const GdkColor *color);
|
||||
GDK_DEPRECATED_FOR(gtk_color_selection_get_previous_rgba)
|
||||
GDK_DEPRECATED
|
||||
void gtk_color_selection_get_previous_color (GtkColorSelection *colorsel,
|
||||
GdkColor *color);
|
||||
|
||||
@@ -24,6 +24,10 @@
|
||||
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
#define GDK_DISABLE_DEPRECATION_WARNINGS
|
||||
|
||||
|
||||
#include <string.h>
|
||||
#include <glib.h>
|
||||
#include "gtkcolorseldialog.h"
|
||||
@@ -36,7 +40,7 @@
|
||||
|
||||
/**
|
||||
* SECTION:gtkcolorseldlg
|
||||
* @Short_description: A standard dialog box for selecting a color
|
||||
* @Short_description: Deprecated dialog box for selecting a color
|
||||
* @Title: GtkColorSelectionDialog
|
||||
*
|
||||
* The #GtkColorSelectionDialog provides a standard dialog which
|
||||
@@ -32,7 +32,7 @@
|
||||
#define __GTK_COLOR_SELECTION_DIALOG_H__
|
||||
|
||||
#include <gtk/gtkdialog.h>
|
||||
#include <gtk/gtkcolorsel.h>
|
||||
#include <gtk/deprecated/gtkcolorsel.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@@ -71,7 +71,9 @@ struct _GtkColorSelectionDialogClass
|
||||
|
||||
/* ColorSelectionDialog */
|
||||
GType gtk_color_selection_dialog_get_type (void) G_GNUC_CONST;
|
||||
GDK_DEPRECATED_FOR(gtk_color_chooser_dialog_new)
|
||||
GtkWidget* gtk_color_selection_dialog_new (const gchar *title);
|
||||
GDK_DEPRECATED_FOR(GtkColorChooser)
|
||||
GtkWidget* gtk_color_selection_dialog_get_color_selection (GtkColorSelectionDialog *colorsel);
|
||||
|
||||
|
||||
@@ -1635,7 +1635,7 @@ gtk_font_selection_set_preview_text (GtkFontSelection *fontsel,
|
||||
|
||||
/**
|
||||
* SECTION:gtkfontseldlg
|
||||
* @Short_description: A dialog box for selecting fonts
|
||||
* @Short_description: Deprecated dialog box for selecting fonts
|
||||
* @Title: GtkFontSelectionDialog
|
||||
* @See_also: #GtkFontSelection, #GtkDialog, #GtkFontChooserDialog
|
||||
*
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
* very quick and easy change. If you have derived your own classes from
|
||||
* GtkHBox, you can simply change the inheritance to derive directly
|
||||
* from #GtkBox. No further changes are needed, since the default
|
||||
* value of the #GtkOrientable::orientation property is
|
||||
* value of the #GtkOrientable:orientation property is
|
||||
* %GTK_ORIENTATION_HORIZONTAL.
|
||||
* If you want your code to be future-proof, the recommendation is to
|
||||
* switch to #GtkGrid, since #GtkBox is going to be deprecated in favor
|
||||
@@ -84,7 +84,7 @@ gtk_hbox_init (GtkHBox *hbox)
|
||||
* Returns: a new #GtkHBox.
|
||||
*
|
||||
* Deprecated: 3.2: You can use gtk_box_new() with %GTK_ORIENTATION_HORIZONTAL instead,
|
||||
* wich is a very quick and easy change. But the recommendation is to switch to
|
||||
* which is a quick and easy change. But the recommendation is to switch to
|
||||
* #GtkGrid, since #GtkBox is going to go away eventually.
|
||||
* See <xref linkend="gtk-migrating-GtkGrid"/>.
|
||||
*/
|
||||
|
||||
@@ -31,6 +31,8 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#define GDK_DISABLE_DEPRECATION_WARNINGS
|
||||
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
@@ -52,6 +54,9 @@
|
||||
* intuitive way. Moving the selection around the outer ring changes the hue,
|
||||
* and moving the selection point inside the inner triangle changes value and
|
||||
* saturation.
|
||||
*
|
||||
* #GtkHSV has been deprecated together with #GtkColorSelection, where
|
||||
* it was used.
|
||||
*/
|
||||
|
||||
|
||||
@@ -723,7 +728,7 @@ gtk_hsv_button_press (GtkWidget *widget,
|
||||
GtkHSVPrivate *priv = hsv->priv;
|
||||
double x, y;
|
||||
|
||||
if (priv->mode != DRAG_NONE || event->button != 1)
|
||||
if (priv->mode != DRAG_NONE || event->button != GDK_BUTTON_PRIMARY)
|
||||
return FALSE;
|
||||
|
||||
x = event->x;
|
||||
@@ -773,7 +778,7 @@ gtk_hsv_button_release (GtkWidget *widget,
|
||||
DragMode mode;
|
||||
gdouble x, y;
|
||||
|
||||
if (priv->mode == DRAG_NONE || event->button != 1)
|
||||
if (priv->mode == DRAG_NONE || event->button != GDK_BUTTON_PRIMARY)
|
||||
return FALSE;
|
||||
|
||||
/* Set the drag mode to DRAG_NONE so that signal handlers for "catched"
|
||||
@@ -1454,84 +1459,6 @@ gtk_hsv_is_adjusting (GtkHSV *hsv)
|
||||
return priv->mode != DRAG_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_hsv_to_rgb:
|
||||
* @h: Hue
|
||||
* @s: Saturation
|
||||
* @v: Value
|
||||
* @r: (out): Return value for the red component
|
||||
* @g: (out): Return value for the green component
|
||||
* @b: (out): Return value for the blue component
|
||||
*
|
||||
* Converts a color from HSV space to RGB.
|
||||
* Input values must be in the [0.0, 1.0] range;
|
||||
* output values will be in the same range.
|
||||
*
|
||||
* Since: 2.14
|
||||
*/
|
||||
void
|
||||
gtk_hsv_to_rgb (gdouble h,
|
||||
gdouble s,
|
||||
gdouble v,
|
||||
gdouble *r,
|
||||
gdouble *g,
|
||||
gdouble *b)
|
||||
{
|
||||
g_return_if_fail (h >= 0.0 && h <= 1.0);
|
||||
g_return_if_fail (s >= 0.0 && s <= 1.0);
|
||||
g_return_if_fail (v >= 0.0 && v <= 1.0);
|
||||
|
||||
hsv_to_rgb (&h, &s, &v);
|
||||
|
||||
if (r)
|
||||
*r = h;
|
||||
|
||||
if (g)
|
||||
*g = s;
|
||||
|
||||
if (b)
|
||||
*b = v;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_rgb_to_hsv:
|
||||
* @r: Red
|
||||
* @g: Green
|
||||
* @b: Blue
|
||||
* @h: (out): Return value for the hue component
|
||||
* @s: (out): Return value for the saturation component
|
||||
* @v: (out): Return value for the value component
|
||||
*
|
||||
* Converts a color from RGB space to HSV.
|
||||
* Input values must be in the [0.0, 1.0] range;
|
||||
* output values will be in the same range.
|
||||
*
|
||||
* Since: 2.14
|
||||
*/
|
||||
void
|
||||
gtk_rgb_to_hsv (gdouble r,
|
||||
gdouble g,
|
||||
gdouble b,
|
||||
gdouble *h,
|
||||
gdouble *s,
|
||||
gdouble *v)
|
||||
{
|
||||
g_return_if_fail (r >= 0.0 && r <= 1.0);
|
||||
g_return_if_fail (g >= 0.0 && g <= 1.0);
|
||||
g_return_if_fail (b >= 0.0 && b <= 1.0);
|
||||
|
||||
rgb_to_hsv (&r, &g, &b);
|
||||
|
||||
if (h)
|
||||
*h = r;
|
||||
|
||||
if (s)
|
||||
*s = g;
|
||||
|
||||
if (v)
|
||||
*v = b;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_hsv_move (GtkHSV *hsv,
|
||||
GtkDirectionType dir)
|
||||
@@ -80,37 +80,29 @@ struct _GtkHSVClass
|
||||
|
||||
|
||||
GType gtk_hsv_get_type (void) G_GNUC_CONST;
|
||||
GDK_DEPRECATED
|
||||
GtkWidget* gtk_hsv_new (void);
|
||||
GDK_DEPRECATED
|
||||
void gtk_hsv_set_color (GtkHSV *hsv,
|
||||
double h,
|
||||
double s,
|
||||
double v);
|
||||
GDK_DEPRECATED
|
||||
void gtk_hsv_get_color (GtkHSV *hsv,
|
||||
gdouble *h,
|
||||
gdouble *s,
|
||||
gdouble *v);
|
||||
GDK_DEPRECATED
|
||||
void gtk_hsv_set_metrics (GtkHSV *hsv,
|
||||
gint size,
|
||||
gint ring_width);
|
||||
GDK_DEPRECATED
|
||||
void gtk_hsv_get_metrics (GtkHSV *hsv,
|
||||
gint *size,
|
||||
gint *ring_width);
|
||||
GDK_DEPRECATED
|
||||
gboolean gtk_hsv_is_adjusting (GtkHSV *hsv);
|
||||
|
||||
/* Convert colors between the RGB and HSV color spaces */
|
||||
void gtk_hsv_to_rgb (gdouble h,
|
||||
gdouble s,
|
||||
gdouble v,
|
||||
gdouble *r,
|
||||
gdouble *g,
|
||||
gdouble *b);
|
||||
void gtk_rgb_to_hsv (gdouble r,
|
||||
gdouble g,
|
||||
gdouble b,
|
||||
gdouble *h,
|
||||
gdouble *s,
|
||||
gdouble *v);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_HSV_H__ */
|
||||
@@ -49,7 +49,7 @@
|
||||
* GtkVBox has been deprecated. You can use #GtkBox instead, which is a
|
||||
* very quick and easy change. If you have derived your own classes from
|
||||
* GtkVBox, you can simply change the inheritance to derive directly
|
||||
* from #GtkBox, and set the #GtkOrientable::orientation property to
|
||||
* from #GtkBox, and set the #GtkOrientable:orientation property to
|
||||
* %GTK_ORIENTATION_VERTICAL in your instance init function, with a
|
||||
* call like:
|
||||
* |[
|
||||
@@ -88,7 +88,7 @@ gtk_vbox_init (GtkVBox *vbox)
|
||||
* Returns: a new #GtkVBox.
|
||||
*
|
||||
* Deprecated: 3.2: You can use gtk_box_new() with %GTK_ORIENTATION_VERTICAL instead,
|
||||
* wich is a very quick and easy change. But the recommendation is to switch to
|
||||
* which is a quick and easy change. But the recommendation is to switch to
|
||||
* #GtkGrid, since #GtkBox is going to go away eventually.
|
||||
* See <xref linkend="gtk-migrating-GtkGrid"/>.
|
||||
*/
|
||||
|
||||
@@ -18,11 +18,12 @@
|
||||
@define-color error_bg_color rgb (237, 54, 54);
|
||||
|
||||
* {
|
||||
background-color: @bg_color;
|
||||
color: @fg_color;
|
||||
border-color: shade (@bg_color, 0.6);
|
||||
padding: 2;
|
||||
border-width: 0;
|
||||
}
|
||||
|
||||
GtkWindow, .button, .slider {
|
||||
background-color: @bg_color;
|
||||
}
|
||||
|
||||
*:prelight {
|
||||
@@ -120,7 +121,7 @@ GtkTreeView.view.expander:selected:prelight {
|
||||
background-color: alpha (@fg_color, 0.25);
|
||||
border-color: @fg_color;
|
||||
border-style: solid;
|
||||
border-width: 1;
|
||||
border-width: 1px;
|
||||
}
|
||||
|
||||
.tooltip,
|
||||
@@ -128,14 +129,14 @@ GtkTreeView.view.expander:selected:prelight {
|
||||
background-color: @tooltip_bg_color;
|
||||
color: @tooltip_fg_color;
|
||||
border-color: @tooltip_fg_color;
|
||||
border-width: 1;
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
}
|
||||
|
||||
.button,
|
||||
.slider {
|
||||
border-style: outset;
|
||||
border-width: 2;
|
||||
border-width: 2px;
|
||||
}
|
||||
|
||||
.button:active {
|
||||
@@ -153,13 +154,13 @@ GtkTreeView.view.expander:selected:prelight {
|
||||
.trough {
|
||||
background-color: darker (@bg_color);
|
||||
border-style: inset;
|
||||
border-width: 1;
|
||||
border-width: 1px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.entry {
|
||||
border-style: inset;
|
||||
border-width: 2;
|
||||
border-width: 2px;
|
||||
background-color: @base_color;
|
||||
color: @text_color;
|
||||
}
|
||||
@@ -180,7 +181,7 @@ GtkTreeView.view.expander:selected:prelight {
|
||||
border-color: shade (@selected_bg_color, 0.7);
|
||||
color: @selected_fg_color;
|
||||
border-style: outset;
|
||||
border-width: 1;
|
||||
border-width: 1px;
|
||||
}
|
||||
|
||||
GtkCheckButton:hover,
|
||||
@@ -194,7 +195,7 @@ GtkRadioButton:selected {
|
||||
.cell.check, .cell.radio,
|
||||
.cell.check:hover, .cell.radio:hover {
|
||||
border-style: solid;
|
||||
border-width: 1;
|
||||
border-width: 1px;
|
||||
background-color: @base_color;
|
||||
border-color: @fg_color;
|
||||
}
|
||||
@@ -224,22 +225,22 @@ GtkRadioButton:selected {
|
||||
|
||||
.popup {
|
||||
border-style: outset;
|
||||
border-width: 1;
|
||||
border-width: 1px;
|
||||
}
|
||||
|
||||
.viewport {
|
||||
border-style: inset;
|
||||
border-width: 2;
|
||||
border-width: 2px;
|
||||
}
|
||||
|
||||
.notebook {
|
||||
border-style: outset;
|
||||
border-width: 1;
|
||||
border-width: 1px;
|
||||
}
|
||||
|
||||
.frame {
|
||||
border-style: inset;
|
||||
border-width: 1;
|
||||
border-width: 1px;
|
||||
}
|
||||
|
||||
GtkScrolledWindow.frame {
|
||||
@@ -250,7 +251,7 @@ GtkScrolledWindow.frame {
|
||||
.menubar,
|
||||
.toolbar {
|
||||
border-style: outset;
|
||||
border-width: 1;
|
||||
border-width: 1px;
|
||||
}
|
||||
|
||||
.menu:hover,
|
||||
@@ -263,7 +264,7 @@ GtkScrolledWindow.frame {
|
||||
}
|
||||
|
||||
GtkSpinButton.button {
|
||||
border-width: 1;
|
||||
border-width: 1px;
|
||||
}
|
||||
|
||||
.scale.slider:hover,
|
||||
@@ -329,9 +330,9 @@ GtkLabel:selected:focused {
|
||||
color: #fff;
|
||||
}
|
||||
GtkCalendar.view {
|
||||
border-width: 1;
|
||||
border-width: 1px;
|
||||
border-style: inset;
|
||||
padding: 1;
|
||||
padding: 1px;
|
||||
}
|
||||
|
||||
GtkCalendar.view:inconsistent {
|
||||
@@ -341,7 +342,7 @@ GtkCalendar.view:inconsistent {
|
||||
GtkCalendar.header {
|
||||
background-color: @bg_color;
|
||||
border-style: outset;
|
||||
border-width: 2;
|
||||
border-width: 2px;
|
||||
}
|
||||
|
||||
GtkCalendar.highlight {
|
||||
@@ -359,5 +360,11 @@ GtkCalendar.button:hover {
|
||||
|
||||
.menu * {
|
||||
border-width: 0;
|
||||
padding: 2;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
.press-and-hold {
|
||||
background-color: alpha (@bg_color, 0.5);
|
||||
color: alpha (lighter (@selected_bg_color), 0.8);
|
||||
border-width: 10;
|
||||
}
|
||||
|
||||
@@ -1,14 +1,123 @@
|
||||
@define-color bg_color -gtk-win32-color(button, 15);
|
||||
@define-color text_color -gtk-win32-color(button, 18);
|
||||
@define-color base_color #fff;
|
||||
@define-color selected_bg_color -gtk-win32-color(button, 13);
|
||||
@define-color selected_fg_color -gtk-win32-color(button, 14);
|
||||
@define-color info_fg_color rgb (181, 171, 156);
|
||||
@define-color info_bg_color rgb (252, 252, 189);
|
||||
@define-color warning_fg_color rgb (173, 120, 41);
|
||||
@define-color warning_bg_color rgb (250, 173, 61);
|
||||
@define-color question_fg_color rgb (97, 122, 214);
|
||||
@define-color question_bg_color rgb (138, 173, 212);
|
||||
@define-color error_fg_color rgb (166, 38, 38);
|
||||
@define-color error_bg_color rgb (237, 54, 54);
|
||||
|
||||
GtkWindow,
|
||||
GtkViewport {
|
||||
background-color: @bg_color;
|
||||
}
|
||||
|
||||
* {
|
||||
color: -gtk-win32-color(button, 9);
|
||||
-GtkWidget-link-color: -gtk-win32-color(button, 26);
|
||||
-GtkWidget-visited-link-color: -gtk-win32-color(button, 26);
|
||||
border-color: shade (@bg_color, 0.6);
|
||||
}
|
||||
|
||||
GtkFrame {
|
||||
border-width: 2px;
|
||||
border-style: solid;
|
||||
background-color: transparent;
|
||||
border-image: -gtk-win32-theme-part(button, 4 1) 2 2 2 2 stretch;
|
||||
}
|
||||
|
||||
*:insensitive {
|
||||
color: -gtk-win32-color(button, 17);
|
||||
}
|
||||
|
||||
*:selected,
|
||||
*:selected:focus {
|
||||
background-color: @selected_bg_color;
|
||||
color: @selected_fg_color;
|
||||
}
|
||||
|
||||
.info {
|
||||
background-color: @info_bg_color;
|
||||
color: @info_fg_color;
|
||||
}
|
||||
|
||||
.warning {
|
||||
background-color: @warning_bg_color;
|
||||
color: @warning_fg_color;
|
||||
}
|
||||
|
||||
.question {
|
||||
background-color: @question_bg_color;
|
||||
color: @question_fg_color;
|
||||
}
|
||||
|
||||
.error {
|
||||
background-color: @error_bg_color;
|
||||
color: @error_fg_color;
|
||||
}
|
||||
|
||||
.highlight {
|
||||
background-color: @selected_bg_color;
|
||||
color: @selected_fg_color;
|
||||
}
|
||||
|
||||
.light-area-focus {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.dark-area-focus {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.view {
|
||||
border-width: 0;
|
||||
border-radius: 0;
|
||||
background-color: @base_color;
|
||||
color: @text_color;
|
||||
}
|
||||
|
||||
.view:selected {
|
||||
background-color: shade (@bg_color, 0.9);
|
||||
color: @fg_color;
|
||||
}
|
||||
|
||||
.view:selected:focused {
|
||||
background-color: @selected_bg_color;
|
||||
color: @selected_fg_color;
|
||||
}
|
||||
|
||||
.tooltip {
|
||||
background-color: -gtk-win32-color(button, 24);
|
||||
color: -gtk-win32-color(button, 23);
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
}
|
||||
|
||||
.tooltip * {
|
||||
color: -gtk-win32-color(button, 23);
|
||||
}
|
||||
|
||||
GtkAssistant .sidebar .highlight {
|
||||
font: bold;
|
||||
color: -gtk-win32-color(button, 9);
|
||||
}
|
||||
|
||||
/* Buttons */
|
||||
|
||||
.button {
|
||||
color: -gtk-win32-color(button, 18);
|
||||
background-color: transparent;
|
||||
background-image: -gtk-win32-theme-part(button, 1 1);
|
||||
border-width: 0;
|
||||
-GtkWidget-focus-line-width: 1;
|
||||
-GtkWidget-focus-padding: 3;
|
||||
-GtkButton-interior-focuse: true;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
.button:insensitive {
|
||||
@@ -227,6 +336,7 @@
|
||||
background-color: black;
|
||||
border-width: 0;
|
||||
background-image: -gtk-win32-theme-part(edit, 1 1);
|
||||
padding: 2px;
|
||||
}
|
||||
.entry:insensitive {
|
||||
background-image: -gtk-win32-theme-part(edit, 1 4);
|
||||
@@ -240,7 +350,7 @@
|
||||
.spinbutton.button,
|
||||
.spinbutton.button:focused {
|
||||
background-color: transparent;
|
||||
border-width: 1 1 0 0;
|
||||
border-width: 1px 1px 0 0;
|
||||
border-style: none;
|
||||
background-image: -gtk-win32-theme-part(spin, 1 1);
|
||||
color: rgba(0, 0, 0, 0);
|
||||
@@ -265,7 +375,7 @@
|
||||
|
||||
.spinbutton.button.bottom,
|
||||
.spinbutton.button.bottom:focused {
|
||||
border-width: 0 1 1 0;
|
||||
border-width: 0 1px 1px 0;
|
||||
background-image: -gtk-win32-theme-part(spin, 2 1);
|
||||
color: rgba(0, 0, 0, 0);
|
||||
}
|
||||
@@ -462,6 +572,7 @@ GtkEntry.progressbar {
|
||||
|
||||
GtkProgressBar.progressbar.pulse,
|
||||
GtkEntry.progressbar.pulse {
|
||||
background-color: transparent;
|
||||
background-image: -gtk-win32-theme-part(progress, 8 1);
|
||||
}
|
||||
|
||||
@@ -479,28 +590,43 @@ GtkProgressBar.trough.vertical {
|
||||
|
||||
/* Menus */
|
||||
|
||||
.menu {
|
||||
background-color: -gtk-win32-color(button, 4);
|
||||
border-color: shade (-gtk-win32-color(button, 4), 0.6);
|
||||
border-style: solid;
|
||||
border-width: 1px;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
.menuitem {
|
||||
color: -gtk-win32-color(button, 7);
|
||||
}
|
||||
|
||||
.menubar {
|
||||
background-color: transparent;
|
||||
border-width: 0;
|
||||
background-image: -gtk-win32-theme-part(menu, 7 1);
|
||||
}
|
||||
|
||||
.menubar .menuitem {
|
||||
.menubar > .menuitem {
|
||||
background-color: transparent;
|
||||
border-width: 0;
|
||||
background-image: -gtk-win32-theme-part(menu, 8 1);
|
||||
padding: 3px 5px;
|
||||
}
|
||||
|
||||
.menubar .menuitem:prelight {
|
||||
.menubar > .menuitem:prelight {
|
||||
background-color: transparent;
|
||||
border-width: 0;
|
||||
background-image: -gtk-win32-theme-part(menu, 8 3);
|
||||
}
|
||||
|
||||
.menuitem:prelight {
|
||||
background-color: transparent;
|
||||
background-image: -gtk-win32-theme-part(menu, 14 2);
|
||||
}
|
||||
|
||||
.menuitem:prelight:insensitive {
|
||||
background-image: -gtk-win32-theme-part(menu, 14 4);
|
||||
}
|
||||
|
||||
.menuitem.radio,
|
||||
@@ -588,8 +714,8 @@ GtkComboBox.combobox-entry .button:insensitive {
|
||||
/* Notebook */
|
||||
|
||||
.notebook {
|
||||
background-color: transparent;
|
||||
border-width: 1 3 2 2;
|
||||
background-color: @base_color;
|
||||
border-width: 1px 3px 2px 2px;
|
||||
border-style: solid;
|
||||
background-origin: padding-box;
|
||||
background-clip: border-box;
|
||||
@@ -607,7 +733,7 @@ GtkComboBox.combobox-entry .button:insensitive {
|
||||
|
||||
.notebook tab:active {
|
||||
background-image: -gtk-win32-theme-part(tab, 1 3, margins(0 0 -1 0));
|
||||
padding: 4;
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
.notebook tab:last-child {
|
||||
@@ -673,3 +799,27 @@ column-header .button:active:focus,
|
||||
column-header .button:active:prelight:focus {
|
||||
background-image: -gtk-win32-theme-part(header, 1 3);
|
||||
}
|
||||
|
||||
GtkSwitch {
|
||||
font: bold condensed 10;
|
||||
color: -gtk-win32-color(button, 18);
|
||||
}
|
||||
|
||||
GtkSwitch.slider {
|
||||
padding: 4px;
|
||||
background-color: transparent;
|
||||
background-image: -gtk-win32-theme-part(scrollbar, 2 1, over (8 1));
|
||||
border-width: 0;
|
||||
}
|
||||
|
||||
GtkSwitch.trough:insensitive {
|
||||
background-image: -gtk-win32-theme-part(button, 1 4);
|
||||
}
|
||||
|
||||
GtkSwitch.trough {
|
||||
background-image: -gtk-win32-theme-part(button, 1 1);
|
||||
}
|
||||
|
||||
GtkSwitch.trough:active {
|
||||
background-image: -gtk-win32-theme-part(button, 1 2);
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
/*
|
||||
* This theme is the default theme if no other theme is selected.
|
||||
*/
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<gresources>
|
||||
<gresource prefix="/org/gtk/libgtk">
|
||||
<file>gtk-default.css</file>
|
||||
<file alias="Raleigh.css">gtk-default.css</file>
|
||||
<file>gtk-win32.css</file>
|
||||
<file alias="cursor/dnd-ask.png">cursor_dnd_ask.png</file>
|
||||
<file alias="cursor/dnd-link.png">cursor_dnd_link.png</file>
|
||||
|
||||
11
gtk/gtk.h
11
gtk/gtk.h
@@ -78,8 +78,10 @@
|
||||
#include <gtk/gtkcheckmenuitem.h>
|
||||
#include <gtk/gtkclipboard.h>
|
||||
#include <gtk/gtkcolorbutton.h>
|
||||
#include <gtk/gtkcolorsel.h>
|
||||
#include <gtk/gtkcolorseldialog.h>
|
||||
#include <gtk/gtkcolorchooser.h>
|
||||
#include <gtk/gtkcolorchooserdialog.h>
|
||||
#include <gtk/gtkcolorchooserwidget.h>
|
||||
#include <gtk/gtkcolorutils.h>
|
||||
#include <gtk/gtkcombobox.h>
|
||||
#include <gtk/gtkcomboboxtext.h>
|
||||
#include <gtk/gtkcontainer.h>
|
||||
@@ -107,9 +109,9 @@
|
||||
#include <gtk/gtkfontchooserdialog.h>
|
||||
#include <gtk/gtkfontchooserwidget.h>
|
||||
#include <gtk/gtkframe.h>
|
||||
#include <gtk/gtkgesturesinterpreter.h>
|
||||
#include <gtk/gtkgradient.h>
|
||||
#include <gtk/gtkgrid.h>
|
||||
#include <gtk/gtkhsv.h>
|
||||
#include <gtk/gtkiconfactory.h>
|
||||
#include <gtk/gtkicontheme.h>
|
||||
#include <gtk/gtkiconview.h>
|
||||
@@ -223,11 +225,14 @@
|
||||
#include <gtk/gtkwidgetpath.h>
|
||||
#include <gtk/gtkwindow.h>
|
||||
|
||||
#include <gtk/deprecated/gtkcolorsel.h>
|
||||
#include <gtk/deprecated/gtkcolorseldialog.h>
|
||||
#include <gtk/deprecated/gtkfontsel.h>
|
||||
#include <gtk/deprecated/gtkhandlebox.h>
|
||||
#include <gtk/deprecated/gtkhbbox.h>
|
||||
#include <gtk/deprecated/gtkhbox.h>
|
||||
#include <gtk/deprecated/gtkhpaned.h>
|
||||
#include <gtk/deprecated/gtkhsv.h>
|
||||
#include <gtk/deprecated/gtkhscale.h>
|
||||
#include <gtk/deprecated/gtkhscrollbar.h>
|
||||
#include <gtk/deprecated/gtkhseparator.h>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/* This list defines the GTK+ ABI. It is used to generate the gtk.def
|
||||
* file.
|
||||
*/
|
||||
gtk_about_dialog_add_credit_section
|
||||
gtk_about_dialog_get_artists
|
||||
gtk_about_dialog_get_authors
|
||||
gtk_about_dialog_get_comments
|
||||
@@ -604,6 +605,15 @@ gtk_color_button_set_color
|
||||
gtk_color_button_set_rgba
|
||||
gtk_color_button_set_title
|
||||
gtk_color_button_set_use_alpha
|
||||
gtk_color_chooser_dialog_get_type
|
||||
gtk_color_chooser_dialog_new
|
||||
gtk_color_chooser_get_color
|
||||
gtk_color_chooser_get_show_alpha
|
||||
gtk_color_chooser_get_type
|
||||
gtk_color_chooser_set_color
|
||||
gtk_color_chooser_set_show_alpha
|
||||
gtk_color_chooser_widget_get_type
|
||||
gtk_color_chooser_widget_new
|
||||
gtk_color_selection_dialog_get_color_selection
|
||||
gtk_color_selection_dialog_get_type
|
||||
gtk_color_selection_dialog_new
|
||||
@@ -1533,6 +1543,7 @@ gtk_menu_bar_get_child_pack_direction
|
||||
gtk_menu_bar_get_pack_direction
|
||||
gtk_menu_bar_get_type
|
||||
gtk_menu_bar_new
|
||||
gtk_menu_bar_new_from_model
|
||||
gtk_menu_bar_set_child_pack_direction
|
||||
gtk_menu_bar_set_pack_direction
|
||||
gtk_menu_detach
|
||||
@@ -1569,6 +1580,7 @@ gtk_menu_item_set_use_underline
|
||||
gtk_menu_item_toggle_size_allocate
|
||||
gtk_menu_item_toggle_size_request
|
||||
gtk_menu_new
|
||||
gtk_menu_new_from_model
|
||||
gtk_menu_popdown
|
||||
gtk_menu_popup
|
||||
gtk_menu_popup_for_device
|
||||
|
||||
@@ -103,7 +103,7 @@ static GdkColor default_visited_link_color = { 0, 0x5555, 0x1a1a, 0x8b8b };
|
||||
/* Translators: this is the license preamble; the string at the end
|
||||
* contains the URL of the license.
|
||||
*/
|
||||
static const gchar *gtk_license_preamble = N_("This program comes with ABSOLUTELY NO WARRANTY; for details, visit <a href=\"%s\">%s</a>");
|
||||
static const gchar *gtk_license_preamble = N_("This program comes with ABSOLUTELY NO WARRANTY;\nfor details, visit <a href=\"%s\">%s</a>");
|
||||
|
||||
/* URLs for each GtkLicense type; keep in the same order as the enumeration */
|
||||
static const gchar *gtk_license_urls[] = {
|
||||
@@ -122,6 +122,12 @@ static const gchar *gtk_license_urls[] = {
|
||||
"http://opensource.org/licenses/artistic-license-2.0.php"
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
gchar *heading;
|
||||
gchar **people;
|
||||
} CreditSection;
|
||||
|
||||
struct _GtkAboutDialogPrivate
|
||||
{
|
||||
gchar *name;
|
||||
@@ -137,6 +143,9 @@ struct _GtkAboutDialogPrivate
|
||||
gchar **documenters;
|
||||
gchar **artists;
|
||||
|
||||
|
||||
GSList *credit_sections;
|
||||
|
||||
gint credits_page;
|
||||
gint license_page;
|
||||
|
||||
@@ -163,6 +172,8 @@ struct _GtkAboutDialogPrivate
|
||||
guint wrap_license : 1;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#define GTK_ABOUT_DIALOG_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_ABOUT_DIALOG, GtkAboutDialogPrivate))
|
||||
|
||||
|
||||
@@ -561,6 +572,7 @@ update_credits_button_visibility (GtkAboutDialog *about)
|
||||
show = (priv->authors != NULL ||
|
||||
priv->documenters != NULL ||
|
||||
priv->artists != NULL ||
|
||||
priv->credit_sections != NULL ||
|
||||
(priv->translator_credits != NULL &&
|
||||
strcmp (priv->translator_credits, "translator_credits") &&
|
||||
strcmp (priv->translator_credits, "translator-credits")));
|
||||
@@ -775,6 +787,15 @@ gtk_about_dialog_init (GtkAboutDialog *about)
|
||||
gtk_about_dialog_set_logo (about, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
destroy_credit_section (gpointer data)
|
||||
{
|
||||
CreditSection *cs = data;
|
||||
g_free (cs->heading);
|
||||
g_strfreev (cs->people);
|
||||
g_slice_free (CreditSection, data);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_about_dialog_finalize (GObject *object)
|
||||
{
|
||||
@@ -794,6 +815,8 @@ gtk_about_dialog_finalize (GObject *object)
|
||||
g_strfreev (priv->documenters);
|
||||
g_strfreev (priv->artists);
|
||||
|
||||
g_slist_free_full (priv->credit_sections, destroy_credit_section);
|
||||
|
||||
g_slist_foreach (priv->visited_links, (GFunc)g_free, NULL);
|
||||
g_slist_free (priv->visited_links);
|
||||
|
||||
@@ -1942,7 +1965,7 @@ text_view_event_after (GtkWidget *text_view,
|
||||
|
||||
button_event = (GdkEventButton *)event;
|
||||
|
||||
if (button_event->button != 1)
|
||||
if (button_event->button != GDK_BUTTON_PRIMARY)
|
||||
return FALSE;
|
||||
|
||||
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_view));
|
||||
@@ -2357,7 +2380,7 @@ create_credits_page (GtkAboutDialog *about)
|
||||
priv->credits_page = gtk_notebook_append_page (GTK_NOTEBOOK (priv->notebook), page_vbox, NULL);
|
||||
|
||||
sw = gtk_scrolled_window_new (NULL, NULL);
|
||||
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw), GTK_SHADOW_NONE);
|
||||
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw), GTK_SHADOW_IN);
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
|
||||
GTK_POLICY_NEVER,
|
||||
GTK_POLICY_AUTOMATIC);
|
||||
@@ -2366,7 +2389,7 @@ create_credits_page (GtkAboutDialog *about)
|
||||
grid = gtk_grid_new ();
|
||||
gtk_container_set_border_width (GTK_CONTAINER (grid), 5);
|
||||
gtk_orientable_set_orientation (GTK_ORIENTABLE (grid), GTK_ORIENTATION_VERTICAL);
|
||||
gtk_grid_set_column_spacing (GTK_GRID (grid), 2);
|
||||
gtk_grid_set_column_spacing (GTK_GRID (grid), 8);
|
||||
gtk_grid_set_row_spacing (GTK_GRID (grid), 12);
|
||||
gtk_widget_set_halign (grid, GTK_ALIGN_CENTER);
|
||||
gtk_widget_set_valign (grid, GTK_ALIGN_START);
|
||||
@@ -2393,6 +2416,16 @@ create_credits_page (GtkAboutDialog *about)
|
||||
if (priv->artists != NULL)
|
||||
add_credits_section (about, GTK_GRID (grid), &row, _("Artwork by"), priv->artists);
|
||||
|
||||
if (priv->credit_sections != NULL)
|
||||
{
|
||||
GSList *cs;
|
||||
for (cs = priv->credit_sections; cs != NULL; cs = cs->next)
|
||||
{
|
||||
CreditSection *section = cs->data;
|
||||
add_credits_section (about, GTK_GRID (grid), &row, section->heading, section->people);
|
||||
}
|
||||
}
|
||||
|
||||
gtk_widget_show_all (sw);
|
||||
}
|
||||
|
||||
@@ -2422,7 +2455,6 @@ create_license_page (GtkAboutDialog *about)
|
||||
priv->license_page = gtk_notebook_append_page (GTK_NOTEBOOK (priv->notebook), page_vbox, NULL);
|
||||
|
||||
sw = gtk_scrolled_window_new (NULL, NULL);
|
||||
gtk_container_set_border_width (GTK_CONTAINER (sw), 5);
|
||||
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw), GTK_SHADOW_IN);
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
|
||||
GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
|
||||
@@ -2627,3 +2659,35 @@ gtk_about_dialog_get_license_type (GtkAboutDialog *about)
|
||||
|
||||
return about->priv->license_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_about_dialog_add_credit_section:
|
||||
* @about: A #GtkAboutDialog
|
||||
* @section_name: The name of the section
|
||||
* @people: The people who belong to that section
|
||||
*
|
||||
* Creates a new section in the Credits page.
|
||||
*
|
||||
* Since: 3.4
|
||||
*/
|
||||
void
|
||||
gtk_about_dialog_add_credit_section (GtkAboutDialog *about,
|
||||
const gchar *section_name,
|
||||
const gchar **people)
|
||||
{
|
||||
GtkAboutDialogPrivate *priv;
|
||||
CreditSection *new_entry;
|
||||
|
||||
g_return_if_fail (GTK_IS_ABOUT_DIALOG (about));
|
||||
g_return_if_fail (section_name != NULL);
|
||||
g_return_if_fail (people != NULL);
|
||||
|
||||
priv = about->priv;
|
||||
|
||||
new_entry = g_slice_new (CreditSection);
|
||||
new_entry->heading = g_strdup ((gchar *)section_name);
|
||||
new_entry->people = g_strdupv ((gchar **)people);
|
||||
|
||||
priv->credit_sections = g_slist_append (priv->credit_sections, new_entry);
|
||||
update_credits_button_visibility (about);
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user