Compare commits
576 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| dc89a16469 | |||
| cc141caaeb | |||
| ccf2d65ff7 | |||
| 4c4a36f56d | |||
| a7a45f0ff6 | |||
| 392be8ee50 | |||
| b904fc6ee0 | |||
| 9622ba8a0d | |||
| 3b8d206143 | |||
| e027fc9272 | |||
| ba6c5ef201 | |||
| 6a8013735d | |||
| c3e72c4d7e | |||
| a6c47cb3ab | |||
| cc129e564a | |||
| 9fbcbc55d7 | |||
| 00a27c1e28 | |||
| f5f6597abc | |||
| fade0afbef | |||
| 0082675de8 | |||
| ed8e784879 | |||
| ed434519d2 | |||
| 4ed4b4fd6a | |||
| 369cb702e4 | |||
| d246abd085 | |||
| 911627fa0b | |||
| ec576088bb | |||
| ab0b54db76 | |||
| fb51f8be9a | |||
| eb22c7c9c3 | |||
| 749ef4d71c | |||
| f6fae1dd09 | |||
| f21abba82f | |||
| bf222a9292 | |||
| 96e465b6d9 | |||
| 016de68ceb | |||
| d2178bcb94 | |||
| f40eb8a1fe | |||
| 9e0f43e8cb | |||
| 3e4d7250a0 | |||
| 4ebd14c045 | |||
| ca39b35e2f | |||
| a32fb5b849 | |||
| eed19c9269 | |||
| e2d691bdb1 | |||
| a73f961e65 | |||
| a7aed5af4b | |||
| 220a51e7cb | |||
| 6df28420d7 | |||
| 081b45399f | |||
| 0874a54708 | |||
| cd40ec2200 | |||
| 62b887e064 | |||
| ce9ce8a5bc | |||
| 2322f38bf9 | |||
| dcb6c9b4cf | |||
| afdeffd820 | |||
| 10439aaefe | |||
| d64467b334 | |||
| 099b967885 | |||
| d13cd9cb67 | |||
| 79b87cc543 | |||
| 3c2aceba63 | |||
| a01feae15b | |||
| b4d4f73d9f | |||
| c1de6219ed | |||
| b364827a5b | |||
| bbe362d015 | |||
| 08f32c6560 | |||
| b3c8c8e592 | |||
| ed36933232 | |||
| a90fc088f2 | |||
| ff6c4ed07e | |||
| 201f635559 | |||
| 59077e4843 | |||
| 3e6a473082 | |||
| 580d96620e | |||
| 61f50f2410 | |||
| 61b2f3c996 | |||
| ab30850aad | |||
| f5e04b59e9 | |||
| c67bcf09b9 | |||
| 5eba0bc932 | |||
| ff2ba52bc6 | |||
| a822d6fce9 | |||
| b749fe4270 | |||
| 933cb857cf | |||
| dde535bbdf | |||
| 71b36db88d | |||
| b5576397f7 | |||
| 4e86858405 | |||
| 14b21d78db | |||
| 35829a7272 | |||
| 0eb60fb03e | |||
| 94162197a1 | |||
| 877fffdd5e | |||
| 8669d31c30 | |||
| e76d17a786 | |||
| 5ab90f1a80 | |||
| 5b1fd111d1 | |||
| 5596feae9b | |||
| 8fb8303ba0 | |||
| 06e4c3c991 | |||
| f25f3b3c47 | |||
| 72ec8963d7 | |||
| 50d5666db0 | |||
| e06044530f | |||
| 7ce7e5503f | |||
| 0ba307995d | |||
| ce7956cd50 | |||
| d29b378fa0 | |||
| 1129febd7d | |||
| 47928b9e14 | |||
| 01f17836ac | |||
| 7e919aaaa5 | |||
| 03a6420c37 | |||
| 375fbd4e47 | |||
| 813957a92f | |||
| 36ed4c2a29 | |||
| 8e78b53378 | |||
| 76ed6cf9d8 | |||
| a8c6f222ed | |||
| c5afea0c6b | |||
| efa42a6932 | |||
| 5d1b2f627c | |||
| 8f6f980e49 | |||
| 25b3b90920 | |||
| 71762d3b28 | |||
| f15224926a | |||
| 1570c41efa | |||
| 5e0f2d7d20 | |||
| 88743ab975 | |||
| 6f15447633 | |||
| 85f6995511 | |||
| 4d59a00074 | |||
| 2dbb1509d8 | |||
| 101c927c40 | |||
| 6d3eb18578 | |||
| d301695ba1 | |||
| ca8008e2c9 | |||
| 0d7b4ecb14 | |||
| 9a541d9b91 | |||
| cdfde6673d | |||
| 7ef95734af | |||
| de17e3b525 | |||
| f8a971a7df | |||
| e1a7629a85 | |||
| 7d3b8b0d09 | |||
| fff2fabd7a | |||
| 73b45ec77e | |||
| 8f95a5980e | |||
| 87d33470ed | |||
| 002e48c469 | |||
| f33549da91 | |||
| f3f32b47cc | |||
| 2c5f2a2bcb | |||
| b6d990af25 | |||
| 16171a232a | |||
| 031b5cad46 | |||
| 984274497d | |||
| 0cc0714312 | |||
| 766e2b1e63 | |||
| c8be597b7f | |||
| 4497ac7d75 | |||
| af21583d4d | |||
| 791da76ae1 | |||
| d398c00d20 | |||
| cb247276f5 | |||
| c6141dffd2 | |||
| 755d8f8332 | |||
| 32de29bb68 | |||
| 540cb58169 | |||
| a1a6e6a36a | |||
| 798ad9f62a | |||
| ad6255a841 | |||
| 6adaf7c33d | |||
| 95a4eff6ba | |||
| 9675c99043 | |||
| 76d0e1e398 | |||
| 14408b7485 | |||
| 2a11baf6ea | |||
| 51d40ca023 | |||
| 5d9d73b090 | |||
| 5f7e093168 | |||
| 0f70e6d70a | |||
| 259be23ff2 | |||
| 337eedb513 | |||
| 185354555c | |||
| 29905d1ce6 | |||
| 73dd73c859 | |||
| cfb0df14cc | |||
| b343abfa51 | |||
| 5df4d27752 | |||
| bbf5d142b3 | |||
| 1fbbaef49e | |||
| d88268c142 | |||
| 49ae68c2c7 | |||
| 1d72e3e193 | |||
| 77c3ef48cf | |||
| 20deda2bd6 | |||
| 447b166ed3 | |||
| 1b230324ba | |||
| 806c659efe | |||
| 51873ebe37 | |||
| 827219e214 | |||
| 5c9b25c66e | |||
| 37e4ae2fbd | |||
| 14f86ae24d | |||
| 849ffebc21 | |||
| 7dabc2a42c | |||
| bef8a3a0e9 | |||
| 31d2638088 | |||
| 40019517cf | |||
| 7a8f5ca970 | |||
| 4063c3dc31 | |||
| 96d0368290 | |||
| 9a0ec5b1e0 | |||
| 7b5a0a829a | |||
| 1030d9e5b1 | |||
| 0750b4fd28 | |||
| 1d4ce5a544 | |||
| 4b2d63167e | |||
| 6fe0a8c6b3 | |||
| 04eb7eef29 | |||
| 480a2c2770 | |||
| f699fff6e0 | |||
| 4bc145549d | |||
| cf7fa931d3 | |||
| 392b4d9ac5 | |||
| 3f126c7fc8 | |||
| 960717b273 | |||
| 5386cf89f2 | |||
| b7d948af69 | |||
| 446b2e25d3 | |||
| 17b1e7bae9 | |||
| 9dc679370c | |||
| 033cf4bfb7 | |||
| bf5f27c6d5 | |||
| 7a1073c3ae | |||
| e2fd33f78a | |||
| 89f25d1484 | |||
| 3c8b3cbf41 | |||
| 410d4bca83 | |||
| 168523264c | |||
| 435f143e2e | |||
| 98ccb67277 | |||
| 2d83bb1b91 | |||
| 298b6ee81a | |||
| 5ce3520a2a | |||
| 9cc3e2c8ef | |||
| 034f89b17f | |||
| 1ea09a327a | |||
| bc2f484ae9 | |||
| 228f813c43 | |||
| 17386b5cf7 | |||
| 288086b899 | |||
| d148f26658 | |||
| 7ca6440f4d | |||
| 1172810768 | |||
| 9c827cbff4 | |||
| da3aaf39b9 | |||
| a8926c9d87 | |||
| 443f8ddf6b | |||
| 6a7de806dd | |||
| 19873e549a | |||
| 05ca6bc189 | |||
| cbb1e74bb5 | |||
| 6afb6bb9d2 | |||
| 60afd056e0 | |||
| 4456b06853 | |||
| 2f72353e0e | |||
| 88af7b44aa | |||
| a7cd1918a8 | |||
| bcfd1bbd24 | |||
| 1a5e60be7c | |||
| 3ce3867403 | |||
| 00a61f92b6 | |||
| 986daa8225 | |||
| e72ca43a32 | |||
| f432c937cc | |||
| 1dd15b5237 | |||
| 5cdbbc6e61 | |||
| 0e2ac0ebf2 | |||
| c73cb2c154 | |||
| a756caa106 | |||
| da22ba3b86 | |||
| 7a0a92f2b6 | |||
| d927c3bee0 | |||
| 59c2efbcd6 | |||
| 94af080fb6 | |||
| 40841ec3be | |||
| f69bb2fb2b | |||
| db0b9f61ae | |||
| 63ab523146 | |||
| b94c3166bf | |||
| 7030e08f9c | |||
| 2cc6a3ee5c | |||
| 3dd188fe7e | |||
| d41603d82a | |||
| f7aff03c72 | |||
| a0b8e32462 | |||
| 50f76eb8cc | |||
| 9959ea98cd | |||
| 8ca3ac1970 | |||
| 27ba2411f0 | |||
| a6920855ea | |||
| c85e2401fa | |||
| 6fdcafc94a | |||
| 9bab218314 | |||
| 2854635850 | |||
| a976aa9740 | |||
| 074eb2a19d | |||
| 96812450fa | |||
| 93c688cd93 | |||
| 53afc4a9d9 | |||
| c96077590b | |||
| 6e47d0bf4a | |||
| 50b79ae0ab | |||
| 6b4709ea3c | |||
| f3a83abb54 | |||
| 33166b7357 | |||
| bb31ce1168 | |||
| dbf32933bf | |||
| af8fe182c8 | |||
| 731f0d4d01 | |||
| e42373df89 | |||
| da8050979e | |||
| 4dd1ff6dd2 | |||
| 8c403c43f0 | |||
| 2feb5c93ca | |||
| 9924a92e70 | |||
| 6c8988e445 | |||
| 9fb3b84253 | |||
| 3439862634 | |||
| 93c5455796 | |||
| e665667bff | |||
| 3ca59b8701 | |||
| fba0b359d4 | |||
| e1b6496af7 | |||
| 14620423e8 | |||
| 55a1f8ccfd | |||
| 19afe454df | |||
| 7d842cb7fc | |||
| 3137d326c5 | |||
| 12464731f1 | |||
| 269a9d8528 | |||
| c892d2767a | |||
| c8e082f296 | |||
| 51981d562b | |||
| 51b77a425a | |||
| ae3163b5e0 | |||
| af93646b3e | |||
| 64f5afe608 | |||
| fb98f939a5 | |||
| 7733f646d6 | |||
| fd69f1cd79 | |||
| ca94ff10ce | |||
| 9c3de51412 | |||
| d9dcfffce3 | |||
| dfd1372a9b | |||
| f3c670ab0c | |||
| 8aa4b5150e | |||
| ecaa16c367 | |||
| 2f8284a386 | |||
| 73cad1e784 | |||
| 0abd01e288 | |||
| b80942ec88 | |||
| 165dab8265 | |||
| 73d736d800 | |||
| 88b4076fe5 | |||
| 36396093e6 | |||
| faba0f0145 | |||
| 8755d884f3 | |||
| 010f4e90e3 | |||
| 0c76264953 | |||
| d13843ee2a | |||
| 7869ffbb49 | |||
| 2f149c378a | |||
| 04367acf9b | |||
| 1a2052a40e | |||
| e079fad1d5 | |||
| bada3dbac6 | |||
| 9178423844 | |||
| 9df5171962 | |||
| b3e91b7111 | |||
| ffd89d29df | |||
| 686116ba61 | |||
| 7fa3183d7f | |||
| 176fd2fab3 | |||
| 419ee6a451 | |||
| 2c0d2d332f | |||
| 5f8fea08ff | |||
| f92ec7ce41 | |||
| ca08cf94d3 | |||
| 3d5dc16d63 | |||
| 7bfc3a5c74 | |||
| a5414bc404 | |||
| 1d97b5fd3c | |||
| aa09b0742e | |||
| c5586f85fb | |||
| 3eb1b22651 | |||
| 4186a85359 | |||
| aaf1e4995c | |||
| e08e15ba51 | |||
| 7048362e6e | |||
| 5f0ed088e4 | |||
| 5c46c81067 | |||
| c6fa3c446c | |||
| f7ebff6aea | |||
| 8aeced2c91 | |||
| e8fefd92c5 | |||
| 22390adf11 | |||
| cf9121977f | |||
| 99099a1053 | |||
| daba1a7eff | |||
| f26359db13 | |||
| 945b844b7c | |||
| f33655fa4e | |||
| ee8ee313c8 | |||
| 33e113d607 | |||
| a12d26155f | |||
| cae382c829 | |||
| 0a5086d94f | |||
| b103650cb0 | |||
| 337e602143 | |||
| 7ce25293b1 | |||
| cd99f82e0c | |||
| 29fee2e808 | |||
| 417b1d8335 | |||
| 443a64a38e | |||
| 74455ae75c | |||
| ec096b417c | |||
| 06bba15f62 | |||
| c48be6ef96 | |||
| 0b1f0984f5 | |||
| 6918fb2e4e | |||
| 3caf8c86c9 | |||
| 8c8dc3aeab | |||
| 4d4ec2dbfb | |||
| 4f979469f1 | |||
| 87532f0ac3 | |||
| 0ace7ad219 | |||
| a1bcbdd02a | |||
| 8e3bf65b3b | |||
| de30a74cdf | |||
| cbbb7604b6 | |||
| 9a91d3739d | |||
| a2839d157f | |||
| b3d424c2d7 | |||
| bf3ea24489 | |||
| 997e8c1ae1 | |||
| aa1f0cfd4f | |||
| 45a6146ca6 | |||
| bc63001deb | |||
| 47b47f5835 | |||
| 1b2dccd143 | |||
| 7e09aa3caa | |||
| 6633d4130a | |||
| a960641ace | |||
| f982c9c8f8 | |||
| a1cee7fa65 | |||
| d0ebdf00f8 | |||
| dd30a288f2 | |||
| 005781021e | |||
| 14f0a25531 | |||
| 8db379d85b | |||
| 6b65aaab21 | |||
| 905765eed6 | |||
| e1206763a8 | |||
| 8a08a325be | |||
| 5e159e2ca0 | |||
| 392071b66d | |||
| 8ee4de804c | |||
| dcf432d7d0 | |||
| ea9d6f0a95 | |||
| 018a17fb8e | |||
| 895f381fd5 | |||
| 66bd54d14c | |||
| ff38d38444 | |||
| af749532fc | |||
| 7afa0badd8 | |||
| 4eb3a9faaa | |||
| 81e1dc9a66 | |||
| c67fb57881 | |||
| 81171cc0a2 | |||
| aa4e4dd0c7 | |||
| 7a9afc3a95 | |||
| 114ab8775a | |||
| 657ebd2a78 | |||
| 05bf87cf14 | |||
| 4aedf3d003 | |||
| b1f384eec2 | |||
| d02b185a87 | |||
| 6048b69145 | |||
| 4b85b5299a | |||
| b00609c21c | |||
| 6d7cb2b781 | |||
| a862ca41c5 | |||
| 314eaf7d10 | |||
| 316bd6a333 | |||
| 5b0a6a52c1 | |||
| 13ae11ee01 | |||
| a05af1f0f3 | |||
| b2dc303e5e | |||
| 2e27967814 | |||
| 18c3b725b4 | |||
| 6573d08b08 | |||
| 74a8ffc4a8 | |||
| ac44353f9b | |||
| 6919d8c532 | |||
| f247d268d4 | |||
| 841a29837e | |||
| 7554384b2d | |||
| 64313f4a4b | |||
| 34f556fc3e | |||
| 218b39fe01 | |||
| 70c8cfa480 | |||
| 501efeb6b9 | |||
| a7d8127d59 | |||
| beb4cb0e37 | |||
| 346ec706f7 | |||
| d8274856de | |||
| 3756234708 | |||
| 2d6955285c | |||
| 10a0d6252e | |||
| f8ddc42638 | |||
| e9a9bb069f | |||
| df79f02310 | |||
| bd99ca2f04 | |||
| 889fcf64b6 | |||
| 3fadb536d9 | |||
| fb0d8eacc3 | |||
| fffb3161bc | |||
| 3be2cb8f63 | |||
| 8267605ba2 | |||
| da4d8b7d94 | |||
| 01d4538223 | |||
| da27627696 | |||
| 85e49a1051 | |||
| 798944cb26 | |||
| 5a319f66af | |||
| 2d7cfdd7ed | |||
| 35417a5a74 | |||
| fdfbbc8246 | |||
| 0db6ee9347 | |||
| 8a1106c639 | |||
| 6e085b3bf1 | |||
| 6bf88d90f3 | |||
| fb4d76d380 | |||
| dedc1ee1e5 | |||
| fe76984e89 | |||
| f6d70f7225 | |||
| 0b12fd9c1b | |||
| 7f8106f2a9 | |||
| d3ffaa0236 | |||
| 1b208eb457 | |||
| 1528665662 | |||
| 751c1877b1 | |||
| 66e0060836 | |||
| b2db7bb95b | |||
| c5fa657631 | |||
| bdf3b6f64d | |||
| 6033bc56b4 | |||
| eefd2d6f10 | |||
| daf72e2e96 | |||
| 7e98741793 | |||
| d4693b2dc8 | |||
| b1f934d3b0 | |||
| fd4bfd5050 | |||
| 07d6c53346 | |||
| 479c341545 | |||
| 938448e0ef | |||
| ef3427575f | |||
| 0c57e3131f | |||
| b22f45b2f6 | |||
| 0d46081645 |
+1
-1
@@ -44,7 +44,7 @@ msys2-mingw32:
|
||||
<<: *mingw-defaults
|
||||
|
||||
.flatpak-defaults: &flatpak-defaults
|
||||
image: registry.gitlab.com/alatiera/gnome-nightly-oci/gnome-master:latest
|
||||
image: registry.gitlab.gnome.org/gnome/gnome-runtime-images/gnome:master
|
||||
stage: flatpak
|
||||
artifacts:
|
||||
paths:
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
FROM fedora:28
|
||||
|
||||
RUN dnf -y install \
|
||||
hicolor-icon-theme \
|
||||
adwaita-icon-theme \
|
||||
atk-devel \
|
||||
at-spi2-atk-devel \
|
||||
|
||||
+3
-3
@@ -48,9 +48,9 @@ $ ninja
|
||||
```
|
||||
|
||||
**Note**: For information about submitting patches and pushing changes
|
||||
to Git, see the `README.md` and `README.commits` files. In particular,
|
||||
to Git, see the [README.md](./README.md) and [README.commits.md](./README.commits.md) files. In particular,
|
||||
don't, under any circumstances, push anything to Git before reading and
|
||||
understanding `README.commmits`.
|
||||
understanding [README.commits.md](./README.commits.md).
|
||||
|
||||
Typically, you should work on your own branch:
|
||||
|
||||
@@ -60,6 +60,6 @@ $ git checkout -b your-branch
|
||||
|
||||
Once you've finished working on the bug fix or feature, push the branch
|
||||
to the Git repository and open a new merge request, to let the GTK
|
||||
maintainers review your contribution. The [CODE-OWNERS](./docs-CODE-OWNERS)
|
||||
maintainers review your contribution. The [CODE-OWNERS](./docs/CODE-OWNERS)
|
||||
document contains the list of core contributors to GTK and the areas for
|
||||
which they are responsible.
|
||||
|
||||
@@ -27,8 +27,8 @@ Overview of Changes in GTK+ 3.94.0
|
||||
* Applications can now create their own GtkSnapshot objects for
|
||||
intermediate rendering.
|
||||
|
||||
* Widget event signals have been replaced by event controller, and
|
||||
some new event controllers have been introduced for this:
|
||||
* Widget event signals have been replaced by event controllers,
|
||||
and some new event controllers have been introduced for this:
|
||||
GtkEventControllerMotion
|
||||
GtkEventControllerKey
|
||||
GtkGestureStylus
|
||||
@@ -68,6 +68,10 @@ Overview of Changes in GTK+ 3.94.0
|
||||
gtk_widget_draw
|
||||
gtk_render_icon_surface
|
||||
|
||||
* Incomplete transitions:
|
||||
The ::event signal is not still there, but it will be removed
|
||||
The DND apis are not finalized yet
|
||||
|
||||
* Translation updates:
|
||||
Croatian
|
||||
Esperanto
|
||||
|
||||
@@ -7,25 +7,23 @@ avoid unnecessary breakage, and to take advantage of the knowledge
|
||||
about GTK+ that has been built up over the years, we'd like to ask
|
||||
people committing to GTK+ to follow a few rules:
|
||||
|
||||
0) Ask first. If your changes are major, or could possibly break existing
|
||||
0. Ask first. If your changes are major, or could possibly break existing
|
||||
code, you should always ask. If your change is minor and you've
|
||||
been working on GTK+ for a while it probably isn't necessary
|
||||
to ask. But when in doubt, ask. Even if your change is correct,
|
||||
somebody may know a better way to do things.
|
||||
|
||||
If you are making changes to GTK+, you should be subscribed
|
||||
to gtk-devel-list@gnome.org. (Subscription address:
|
||||
gtk-devel-list-request@gnome.org.) This is a good place to ask
|
||||
about intended changes.
|
||||
|
||||
#gtk+ on GIMPNet (irc.gimp.org, irc.us.gimp.org, irc.eu.gimp.org, ...)
|
||||
is also a good place to find GTK+ developers to discuss changes with,
|
||||
however, email to gtk-devel-list is the most certain and preferred
|
||||
method.
|
||||
|
||||
1) Ask _first_.
|
||||
0. Ask _first_.
|
||||
|
||||
2) With git, we no longer maintain a ChangeLog file, but you are expected
|
||||
0. With git, we no longer maintain a ChangeLog file, but you are expected
|
||||
to produce a meaningful commit message. Changes without a sufficient
|
||||
commit message will be reverted. See below for the expected format
|
||||
of commit messages.
|
||||
@@ -39,13 +37,13 @@ Notes:
|
||||
|
||||
* The expected format for git commit messages is as follows:
|
||||
|
||||
=== begin example commit ===
|
||||
```
|
||||
Short explanation of the commit
|
||||
|
||||
Longer explanation explaining exactly what's changed, whether any
|
||||
external or private interfaces changed, what bugs were fixed (with bug
|
||||
tracker reference if applicable) and so forth. Be concise but not too brief.
|
||||
=== end example commit ===
|
||||
```
|
||||
|
||||
- Always add a brief description of the commit to the _first_ line of
|
||||
the commit and terminate by two newlines (it will work without the
|
||||
@@ -60,8 +58,8 @@ tracker reference if applicable) and so forth. Be concise but not too brief.
|
||||
punctuation and capital letters where appropriate. Normally, for patches
|
||||
sent to a mailing list it's copied from there.
|
||||
|
||||
- When committing code on behalf of others use the --author option, e.g.
|
||||
git commit -a --author "Joe Coder <joe@coder.org>" and --signoff.
|
||||
- When committing code on behalf of others use the `--author` option, e.g.
|
||||
`git commit -a --author "Joe Coder <joe@coder.org>"` and `--signoff`.
|
||||
|
||||
|
||||
Owen Taylor
|
||||
@@ -70,3 +68,4 @@ Owen Taylor
|
||||
|
||||
Matthias Clasen
|
||||
31 Mar 2009
|
||||
|
||||
@@ -31,6 +31,11 @@ Information about mailing lists can be found at
|
||||
|
||||
- http://www.gtk.org/mailing-lists.php
|
||||
|
||||
Nightly documentation can be found at
|
||||
- Gtk: https://gnome.pages.gitlab.gnome.org/gtk/gtk/
|
||||
- Gdk: https://gnome.pages.gitlab.gnome.org/gtk/gdk/
|
||||
- Gsk: https://gnome.pages.gitlab.gnome.org/gtk/gsk/
|
||||
|
||||
Building and installing
|
||||
-----------------------
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
"sdk": "org.gnome.Sdk",
|
||||
"command": "gtk4-demo",
|
||||
"tags": ["devel", "development", "nightly"],
|
||||
"rename-desktop-file": "gtk4-demo.desktop",
|
||||
"rename-icon": "gtk4-demo",
|
||||
"desktop-file-name-prefix": "(Development) ",
|
||||
"finish-args": [
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
"sdk": "org.gnome.Sdk",
|
||||
"command": "gtk4-widget-factory",
|
||||
"tags": ["devel", "development", "nightly"],
|
||||
"rename-desktop-file": "gtk4-widget-factory.desktop",
|
||||
"rename-icon": "gtk4-widget-factory",
|
||||
"desktop-file-name-prefix": "(Development) ",
|
||||
"finish-args": [
|
||||
|
||||
@@ -87,14 +87,14 @@ find_toplevel_at_pointer (GdkDisplay *display)
|
||||
return widget ? gtk_widget_get_toplevel (widget) : NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
release_event_cb (GtkWidget *widget,
|
||||
GdkEvent *event,
|
||||
gboolean *clicked)
|
||||
static void
|
||||
released_cb (GtkGestureMultiPress *gesture,
|
||||
guint n_press,
|
||||
gdouble x,
|
||||
gdouble y,
|
||||
gboolean *clicked)
|
||||
{
|
||||
if (gdk_event_get_event_type (event) == GDK_BUTTON_RELEASE)
|
||||
*clicked = TRUE;
|
||||
return TRUE;
|
||||
*clicked = TRUE;
|
||||
}
|
||||
|
||||
/* Asks the user to click on a window, then waits for them click
|
||||
@@ -132,10 +132,12 @@ query_for_toplevel (GdkDisplay *display,
|
||||
GDK_SEAT_CAPABILITY_ALL_POINTING,
|
||||
FALSE, cursor, NULL, NULL, NULL) == GDK_GRAB_SUCCESS)
|
||||
{
|
||||
GtkGesture *gesture = gtk_gesture_multi_press_new ();
|
||||
gboolean clicked = FALSE;
|
||||
|
||||
g_signal_connect (popup, "event",
|
||||
G_CALLBACK (release_event_cb), &clicked);
|
||||
g_signal_connect (gesture, "released",
|
||||
G_CALLBACK (released_cb), &clicked);
|
||||
gtk_widget_add_controller (popup, GTK_EVENT_CONTROLLER (gesture));
|
||||
|
||||
/* Process events until clicked is set by our button release event handler.
|
||||
* We pass in may_block=TRUE since we want to wait if there
|
||||
@@ -144,6 +146,8 @@ query_for_toplevel (GdkDisplay *display,
|
||||
while (!clicked)
|
||||
g_main_context_iteration (NULL, TRUE);
|
||||
|
||||
gdk_seat_ungrab (gdk_device_get_seat (device));
|
||||
|
||||
toplevel = find_toplevel_at_pointer (display);
|
||||
if (toplevel == popup)
|
||||
toplevel = NULL;
|
||||
|
||||
@@ -120,7 +120,7 @@ get_image_paintable (GtkImage *image)
|
||||
|
||||
static void
|
||||
drag_begin (GtkWidget *widget,
|
||||
GdkDragContext *context,
|
||||
GdkDrag *drag,
|
||||
gpointer data)
|
||||
{
|
||||
GdkPaintable *paintable;
|
||||
@@ -128,17 +128,16 @@ drag_begin (GtkWidget *widget,
|
||||
paintable = get_image_paintable (GTK_IMAGE (widget));
|
||||
if (paintable)
|
||||
{
|
||||
gtk_drag_set_icon_paintable (context, paintable, -2, -2);
|
||||
gtk_drag_set_icon_paintable (drag, paintable, -2, -2);
|
||||
g_object_unref (paintable);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
drag_data_get (GtkWidget *widget,
|
||||
GdkDragContext *context,
|
||||
GdkDrag *drag,
|
||||
GtkSelectionData *selection_data,
|
||||
guint info,
|
||||
guint time,
|
||||
gpointer data)
|
||||
{
|
||||
GdkPaintable *paintable;
|
||||
@@ -150,9 +149,8 @@ drag_data_get (GtkWidget *widget,
|
||||
|
||||
static void
|
||||
drag_data_received (GtkWidget *widget,
|
||||
GdkDragContext *context,
|
||||
GdkDrop *drop,
|
||||
GtkSelectionData *selection_data,
|
||||
guint32 time,
|
||||
gpointer data)
|
||||
{
|
||||
if (gtk_selection_data_get_length (selection_data) > 0)
|
||||
|
||||
@@ -161,7 +161,6 @@
|
||||
<file>editable_cells.c</file>
|
||||
<file>entry_buffer.c</file>
|
||||
<file>entry_completion.c</file>
|
||||
<file>event_axes.c</file>
|
||||
<file>expander.c</file>
|
||||
<file>filtermodel.c</file>
|
||||
<file>fishbowl.c</file>
|
||||
|
||||
@@ -1,666 +0,0 @@
|
||||
/* Touch and Drawing Tablets
|
||||
*
|
||||
* Demonstrates advanced handling of event information from exotic
|
||||
* input devices.
|
||||
*
|
||||
* On one hand, this snippet demonstrates management of drawing tablets,
|
||||
* those contain additional information for the pointer other than
|
||||
* X/Y coordinates. Tablet pads events are mapped to actions, which
|
||||
* are both defined and interpreted by the application.
|
||||
*
|
||||
* Input axes are dependent on hardware devices, on linux/unix you
|
||||
* can see the device axes through xinput list <device>. Each time
|
||||
* a different hardware device is used to move the pointer, the
|
||||
* master device will be updated to match the axes it provides,
|
||||
* these changes can be tracked through GdkDevice::changed, or
|
||||
* checking gdk_event_get_source_device().
|
||||
*
|
||||
* On the other hand, this demo handles basic multitouch events,
|
||||
* each event coming from an specific touchpoint will contain a
|
||||
* GdkEventSequence that's unique for its lifetime, so multiple
|
||||
* touchpoints can be tracked.
|
||||
*/
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
typedef struct {
|
||||
GdkDevice *last_source;
|
||||
GdkDeviceTool *last_tool;
|
||||
gdouble *axes;
|
||||
GdkRGBA color;
|
||||
gdouble x;
|
||||
gdouble y;
|
||||
} AxesInfo;
|
||||
|
||||
typedef struct {
|
||||
GHashTable *pointer_info; /* GdkDevice -> AxesInfo */
|
||||
GHashTable *touch_info; /* GdkEventSequence -> AxesInfo */
|
||||
} EventData;
|
||||
|
||||
const gchar *colors[] = {
|
||||
"black",
|
||||
"orchid",
|
||||
"fuchsia",
|
||||
"indigo",
|
||||
"thistle",
|
||||
"sienna",
|
||||
"azure",
|
||||
"plum",
|
||||
"lime",
|
||||
"navy",
|
||||
"maroon",
|
||||
"burlywood"
|
||||
};
|
||||
|
||||
static GtkPadActionEntry pad_actions[] = {
|
||||
{ GTK_PAD_ACTION_BUTTON, 1, -1, N_("Nuclear strike"), "pad.nuke" },
|
||||
{ GTK_PAD_ACTION_BUTTON, 2, -1, N_("Release siberian methane reserves"), "pad.heat" },
|
||||
{ GTK_PAD_ACTION_BUTTON, 3, -1, N_("Release solar flare"), "pad.fry" },
|
||||
{ GTK_PAD_ACTION_BUTTON, 4, -1, N_("De-stabilize Oort cloud"), "pad.fall" },
|
||||
{ GTK_PAD_ACTION_BUTTON, 5, -1, N_("Ignite WR-104"), "pad.burst" },
|
||||
{ GTK_PAD_ACTION_BUTTON, 6, -1, N_("Lart whoever asks about this button"), "pad.lart" },
|
||||
{ GTK_PAD_ACTION_RING, -1, -1, N_("Earth axial tilt"), "pad.tilt" },
|
||||
{ GTK_PAD_ACTION_STRIP, -1, -1, N_("Extent of weak nuclear force"), "pad.dissolve" },
|
||||
};
|
||||
|
||||
static const gchar *pad_action_results[] = {
|
||||
"☢",
|
||||
"♨",
|
||||
"☼",
|
||||
"☄",
|
||||
"⚡",
|
||||
"💫",
|
||||
"◑",
|
||||
"⚛"
|
||||
};
|
||||
|
||||
static guint cur_color = 0;
|
||||
static guint pad_action_timeout_id = 0;
|
||||
|
||||
static AxesInfo *
|
||||
axes_info_new (void)
|
||||
{
|
||||
AxesInfo *info;
|
||||
|
||||
info = g_new0 (AxesInfo, 1);
|
||||
gdk_rgba_parse (&info->color, colors[cur_color]);
|
||||
|
||||
cur_color = (cur_color + 1) % G_N_ELEMENTS (colors);
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
static EventData *
|
||||
event_data_new (void)
|
||||
{
|
||||
EventData *data;
|
||||
|
||||
data = g_new0 (EventData, 1);
|
||||
data->pointer_info = g_hash_table_new_full (NULL, NULL, NULL,
|
||||
(GDestroyNotify) g_free);
|
||||
data->touch_info = g_hash_table_new_full (NULL, NULL, NULL,
|
||||
(GDestroyNotify) g_free);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
static void
|
||||
event_data_free (EventData *data)
|
||||
{
|
||||
g_hash_table_destroy (data->pointer_info);
|
||||
g_hash_table_destroy (data->touch_info);
|
||||
g_free (data);
|
||||
}
|
||||
|
||||
static void
|
||||
update_axes_from_event (GdkEvent *event,
|
||||
EventData *data)
|
||||
{
|
||||
GdkDevice *device, *source_device;
|
||||
GdkEventSequence *sequence;
|
||||
GdkDeviceTool *tool;
|
||||
GdkEventType type;
|
||||
gdouble x, y;
|
||||
AxesInfo *info;
|
||||
|
||||
device = gdk_event_get_device (event);
|
||||
source_device = gdk_event_get_source_device (event);
|
||||
sequence = gdk_event_get_event_sequence (event);
|
||||
tool = gdk_event_get_device_tool (event);
|
||||
type = gdk_event_get_event_type (event);
|
||||
|
||||
if (type == GDK_TOUCH_END ||
|
||||
type == GDK_TOUCH_CANCEL)
|
||||
{
|
||||
g_hash_table_remove (data->touch_info, sequence);
|
||||
return;
|
||||
}
|
||||
else if (type == GDK_LEAVE_NOTIFY)
|
||||
{
|
||||
g_hash_table_remove (data->pointer_info, device);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!source_device)
|
||||
return;
|
||||
|
||||
if (!sequence)
|
||||
{
|
||||
info = g_hash_table_lookup (data->pointer_info, device);
|
||||
|
||||
if (!info)
|
||||
{
|
||||
info = axes_info_new ();
|
||||
g_hash_table_insert (data->pointer_info, device, info);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
info = g_hash_table_lookup (data->touch_info, sequence);
|
||||
|
||||
if (!info)
|
||||
{
|
||||
info = axes_info_new ();
|
||||
g_hash_table_insert (data->touch_info, sequence, info);
|
||||
}
|
||||
}
|
||||
|
||||
if (info->last_source != source_device)
|
||||
info->last_source = source_device;
|
||||
|
||||
if (info->last_tool != tool)
|
||||
info->last_tool = tool;
|
||||
|
||||
g_clear_pointer (&info->axes, g_free);
|
||||
|
||||
if (type == GDK_TOUCH_BEGIN ||
|
||||
type == GDK_TOUCH_UPDATE)
|
||||
{
|
||||
gboolean emulating_pointer;
|
||||
|
||||
gdk_event_get_touch_emulating_pointer (event, &emulating_pointer);
|
||||
if (sequence && emulating_pointer)
|
||||
g_hash_table_remove (data->pointer_info, device);
|
||||
}
|
||||
if (type == GDK_MOTION_NOTIFY ||
|
||||
type == GDK_BUTTON_PRESS ||
|
||||
type == GDK_BUTTON_RELEASE)
|
||||
{
|
||||
gdouble *axes;
|
||||
guint n_axes;
|
||||
|
||||
gdk_event_get_axes (event, &axes, &n_axes);
|
||||
info->axes = g_memdup (axes, sizeof (double) * n_axes);
|
||||
}
|
||||
|
||||
if (gdk_event_get_coords (event, &x, &y))
|
||||
{
|
||||
info->x = x;
|
||||
info->y = y;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
event_cb (GtkWidget *widget,
|
||||
GdkEvent *event,
|
||||
gpointer user_data)
|
||||
{
|
||||
update_axes_from_event (event, user_data);
|
||||
gtk_widget_queue_draw (widget);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
render_arrow (cairo_t *cr,
|
||||
gdouble x_diff,
|
||||
gdouble y_diff,
|
||||
const gchar *label)
|
||||
{
|
||||
cairo_save (cr);
|
||||
|
||||
cairo_set_source_rgb (cr, 0, 0, 0);
|
||||
cairo_new_path (cr);
|
||||
cairo_move_to (cr, 0, 0);
|
||||
cairo_line_to (cr, x_diff, y_diff);
|
||||
cairo_stroke (cr);
|
||||
|
||||
cairo_move_to (cr, x_diff, y_diff);
|
||||
cairo_show_text (cr, label);
|
||||
|
||||
cairo_restore (cr);
|
||||
}
|
||||
|
||||
static void
|
||||
draw_axes_info (cairo_t *cr,
|
||||
AxesInfo *info,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
gdouble pressure, tilt_x, tilt_y, distance, wheel, rotation, slider;
|
||||
GdkAxisFlags axes = gdk_device_get_axes (info->last_source);
|
||||
|
||||
cairo_save (cr);
|
||||
|
||||
cairo_set_line_width (cr, 1);
|
||||
gdk_cairo_set_source_rgba (cr, &info->color);
|
||||
|
||||
cairo_move_to (cr, 0, info->y);
|
||||
cairo_line_to (cr, width, info->y);
|
||||
cairo_move_to (cr, info->x, 0);
|
||||
cairo_line_to (cr, info->x, height);
|
||||
cairo_stroke (cr);
|
||||
|
||||
cairo_translate (cr, info->x, info->y);
|
||||
|
||||
if (!info->axes)
|
||||
{
|
||||
cairo_restore (cr);
|
||||
return;
|
||||
}
|
||||
|
||||
if (axes & GDK_AXIS_FLAG_PRESSURE)
|
||||
{
|
||||
cairo_pattern_t *pattern;
|
||||
|
||||
gdk_device_get_axis (info->last_source, info->axes, GDK_AXIS_PRESSURE,
|
||||
&pressure);
|
||||
|
||||
pattern = cairo_pattern_create_radial (0, 0, 0, 0, 0, 100);
|
||||
cairo_pattern_add_color_stop_rgba (pattern, pressure, 1, 0, 0, pressure);
|
||||
cairo_pattern_add_color_stop_rgba (pattern, 1, 0, 0, 1, 0);
|
||||
|
||||
cairo_set_source (cr, pattern);
|
||||
|
||||
cairo_arc (cr, 0, 0, 100, 0, 2 * G_PI);
|
||||
cairo_fill (cr);
|
||||
|
||||
cairo_pattern_destroy (pattern);
|
||||
}
|
||||
|
||||
if (axes & GDK_AXIS_FLAG_XTILT &&
|
||||
axes & GDK_AXIS_FLAG_YTILT)
|
||||
{
|
||||
gdk_device_get_axis (info->last_source, info->axes, GDK_AXIS_XTILT,
|
||||
&tilt_x);
|
||||
gdk_device_get_axis (info->last_source, info->axes, GDK_AXIS_YTILT,
|
||||
&tilt_y);
|
||||
|
||||
render_arrow (cr, tilt_x * 100, tilt_y * 100, "Tilt");
|
||||
}
|
||||
|
||||
if (axes & GDK_AXIS_FLAG_DISTANCE)
|
||||
{
|
||||
double dashes[] = { 5.0, 5.0 };
|
||||
cairo_text_extents_t extents;
|
||||
|
||||
gdk_device_get_axis (info->last_source, info->axes, GDK_AXIS_DISTANCE,
|
||||
&distance);
|
||||
|
||||
cairo_save (cr);
|
||||
|
||||
cairo_move_to (cr, distance * 100, 0);
|
||||
|
||||
cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
|
||||
cairo_set_dash (cr, dashes, 2, 0.0);
|
||||
cairo_arc (cr, 0, 0, distance * 100, 0, 2 * G_PI);
|
||||
cairo_stroke (cr);
|
||||
|
||||
cairo_move_to (cr, 0, -distance * 100);
|
||||
cairo_text_extents (cr, "Distance", &extents);
|
||||
cairo_rel_move_to (cr, -extents.width / 2, 0);
|
||||
cairo_show_text (cr, "Distance");
|
||||
|
||||
cairo_move_to (cr, 0, 0);
|
||||
|
||||
cairo_restore (cr);
|
||||
}
|
||||
|
||||
if (axes & GDK_AXIS_FLAG_WHEEL)
|
||||
{
|
||||
gdk_device_get_axis (info->last_source, info->axes, GDK_AXIS_WHEEL,
|
||||
&wheel);
|
||||
|
||||
cairo_save (cr);
|
||||
cairo_set_line_width (cr, 10);
|
||||
cairo_set_source_rgba (cr, 0, 0, 0, 0.5);
|
||||
|
||||
cairo_new_sub_path (cr);
|
||||
cairo_arc (cr, 0, 0, 100, 0, wheel * 2 * G_PI);
|
||||
cairo_stroke (cr);
|
||||
cairo_restore (cr);
|
||||
}
|
||||
|
||||
if (axes & GDK_AXIS_FLAG_ROTATION)
|
||||
{
|
||||
gdk_device_get_axis (info->last_source, info->axes, GDK_AXIS_ROTATION,
|
||||
&rotation);
|
||||
rotation *= 2 * G_PI;
|
||||
|
||||
cairo_save (cr);
|
||||
cairo_rotate (cr, - G_PI / 2);
|
||||
cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
|
||||
cairo_set_line_width (cr, 5);
|
||||
|
||||
cairo_new_sub_path (cr);
|
||||
cairo_arc (cr, 0, 0, 100, 0, rotation);
|
||||
cairo_stroke (cr);
|
||||
cairo_restore (cr);
|
||||
}
|
||||
|
||||
if (axes & GDK_AXIS_FLAG_SLIDER)
|
||||
{
|
||||
cairo_pattern_t *pattern, *mask;
|
||||
|
||||
gdk_device_get_axis (info->last_source, info->axes, GDK_AXIS_SLIDER,
|
||||
&slider);
|
||||
|
||||
cairo_save (cr);
|
||||
|
||||
cairo_move_to (cr, 0, -10);
|
||||
cairo_rel_line_to (cr, 0, -50);
|
||||
cairo_rel_line_to (cr, 10, 0);
|
||||
cairo_rel_line_to (cr, -5, 50);
|
||||
cairo_close_path (cr);
|
||||
|
||||
cairo_clip_preserve (cr);
|
||||
|
||||
pattern = cairo_pattern_create_linear (0, -10, 0, -60);
|
||||
cairo_pattern_add_color_stop_rgb (pattern, 0, 0, 1, 0);
|
||||
cairo_pattern_add_color_stop_rgb (pattern, 1, 1, 0, 0);
|
||||
cairo_set_source (cr, pattern);
|
||||
cairo_pattern_destroy (pattern);
|
||||
|
||||
mask = cairo_pattern_create_linear (0, -10, 0, -60);
|
||||
cairo_pattern_add_color_stop_rgba (mask, 0, 0, 0, 0, 1);
|
||||
cairo_pattern_add_color_stop_rgba (mask, slider, 0, 0, 0, 1);
|
||||
cairo_pattern_add_color_stop_rgba (mask, slider, 0, 0, 0, 0);
|
||||
cairo_pattern_add_color_stop_rgba (mask, 1, 0, 0, 0, 0);
|
||||
cairo_mask (cr, mask);
|
||||
cairo_pattern_destroy (mask);
|
||||
|
||||
cairo_set_source_rgb (cr, 0, 0, 0);
|
||||
cairo_stroke (cr);
|
||||
|
||||
cairo_restore (cr);
|
||||
}
|
||||
|
||||
cairo_restore (cr);
|
||||
}
|
||||
|
||||
static const gchar *
|
||||
tool_type_to_string (GdkDeviceToolType tool_type)
|
||||
{
|
||||
switch (tool_type)
|
||||
{
|
||||
case GDK_DEVICE_TOOL_TYPE_PEN:
|
||||
return "Pen";
|
||||
case GDK_DEVICE_TOOL_TYPE_ERASER:
|
||||
return "Eraser";
|
||||
case GDK_DEVICE_TOOL_TYPE_BRUSH:
|
||||
return "Brush";
|
||||
case GDK_DEVICE_TOOL_TYPE_PENCIL:
|
||||
return "Pencil";
|
||||
case GDK_DEVICE_TOOL_TYPE_AIRBRUSH:
|
||||
return "Airbrush";
|
||||
case GDK_DEVICE_TOOL_TYPE_MOUSE:
|
||||
return "Mouse";
|
||||
case GDK_DEVICE_TOOL_TYPE_LENS:
|
||||
return "Lens cursor";
|
||||
case GDK_DEVICE_TOOL_TYPE_UNKNOWN:
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
draw_device_info (GtkWidget *widget,
|
||||
cairo_t *cr,
|
||||
GdkEventSequence *sequence,
|
||||
gint *y,
|
||||
AxesInfo *info)
|
||||
{
|
||||
PangoLayout *layout;
|
||||
GString *string;
|
||||
gint height;
|
||||
|
||||
cairo_save (cr);
|
||||
|
||||
string = g_string_new (NULL);
|
||||
g_string_append_printf (string, "Source: %s",
|
||||
gdk_device_get_name (info->last_source));
|
||||
|
||||
if (sequence)
|
||||
g_string_append_printf (string, "\nSequence: %d",
|
||||
GPOINTER_TO_UINT (sequence));
|
||||
|
||||
if (info->last_tool)
|
||||
{
|
||||
const gchar *tool_type;
|
||||
guint64 serial;
|
||||
|
||||
tool_type = tool_type_to_string (gdk_device_tool_get_tool_type (info->last_tool));
|
||||
serial = gdk_device_tool_get_serial (info->last_tool);
|
||||
g_string_append_printf (string, "\nTool: %s", tool_type);
|
||||
|
||||
if (serial != 0)
|
||||
g_string_append_printf (string, ", Serial: %" G_GINT64_MODIFIER "x", serial);
|
||||
}
|
||||
|
||||
cairo_move_to (cr, 10, *y);
|
||||
layout = gtk_widget_create_pango_layout (widget, string->str);
|
||||
pango_cairo_show_layout (cr, layout);
|
||||
cairo_stroke (cr);
|
||||
|
||||
pango_layout_get_pixel_size (layout, NULL, &height);
|
||||
|
||||
gdk_cairo_set_source_rgba (cr, &info->color);
|
||||
cairo_set_line_width (cr, 10);
|
||||
cairo_move_to (cr, 0, *y);
|
||||
|
||||
*y = *y + height;
|
||||
cairo_line_to (cr, 0, *y);
|
||||
cairo_stroke (cr);
|
||||
|
||||
cairo_restore (cr);
|
||||
|
||||
g_object_unref (layout);
|
||||
g_string_free (string, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
draw_cb (GtkDrawingArea *da,
|
||||
cairo_t *cr,
|
||||
int width,
|
||||
int height,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkWidget *widget = GTK_WIDGET (da);
|
||||
EventData *data = user_data;
|
||||
AxesInfo *info;
|
||||
GHashTableIter iter;
|
||||
gpointer key, value;
|
||||
gint y = 0;
|
||||
|
||||
/* Draw Abs info */
|
||||
g_hash_table_iter_init (&iter, data->pointer_info);
|
||||
|
||||
while (g_hash_table_iter_next (&iter, NULL, &value))
|
||||
{
|
||||
info = value;
|
||||
draw_axes_info (cr, info, width, height);
|
||||
}
|
||||
|
||||
g_hash_table_iter_init (&iter, data->touch_info);
|
||||
|
||||
while (g_hash_table_iter_next (&iter, NULL, &value))
|
||||
{
|
||||
info = value;
|
||||
draw_axes_info (cr, info, width, height);
|
||||
}
|
||||
|
||||
/* Draw name, color legend and misc data */
|
||||
g_hash_table_iter_init (&iter, data->pointer_info);
|
||||
|
||||
while (g_hash_table_iter_next (&iter, NULL, &value))
|
||||
{
|
||||
info = value;
|
||||
draw_device_info (widget, cr, NULL, &y, info);
|
||||
}
|
||||
|
||||
g_hash_table_iter_init (&iter, data->touch_info);
|
||||
|
||||
while (g_hash_table_iter_next (&iter, &key, &value))
|
||||
{
|
||||
info = value;
|
||||
draw_device_info (widget, cr, key, &y, info);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
update_label_text (GtkWidget *label,
|
||||
const gchar *text)
|
||||
{
|
||||
gchar *markup = NULL;
|
||||
|
||||
if (text)
|
||||
markup = g_strdup_printf ("<span font='48.0'>%s</span>", text);
|
||||
gtk_label_set_markup (GTK_LABEL (label), markup);
|
||||
g_free (markup);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
reset_label_text_timeout_cb (gpointer user_data)
|
||||
{
|
||||
GtkWidget *label = user_data;
|
||||
|
||||
update_label_text (label, NULL);
|
||||
pad_action_timeout_id = 0;
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static void
|
||||
update_label_and_timeout (GtkWidget *label,
|
||||
const gchar *text)
|
||||
{
|
||||
if (pad_action_timeout_id)
|
||||
g_source_remove (pad_action_timeout_id);
|
||||
|
||||
update_label_text (label, text);
|
||||
pad_action_timeout_id = g_timeout_add (200, reset_label_text_timeout_cb, label);
|
||||
}
|
||||
|
||||
static void
|
||||
on_action_activate (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkWidget *label = user_data;
|
||||
const gchar *result;
|
||||
gchar *str;
|
||||
|
||||
result = g_object_get_data (G_OBJECT (action), "action-result");
|
||||
|
||||
if (!parameter)
|
||||
update_label_and_timeout (label, result);
|
||||
else
|
||||
{
|
||||
str = g_strdup_printf ("%s %.2f", result, g_variant_get_double (parameter));
|
||||
update_label_and_timeout (label, str);
|
||||
g_free (str);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
init_pad_controller (GtkWidget *window,
|
||||
GtkWidget *label)
|
||||
{
|
||||
GtkPadController *pad_controller;
|
||||
GSimpleActionGroup *action_group;
|
||||
GSimpleAction *action;
|
||||
gint i;
|
||||
|
||||
action_group = g_simple_action_group_new ();
|
||||
pad_controller = gtk_pad_controller_new (G_ACTION_GROUP (action_group),
|
||||
NULL);
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (pad_actions); i++)
|
||||
{
|
||||
if (pad_actions[i].type == GTK_PAD_ACTION_BUTTON)
|
||||
{
|
||||
action = g_simple_action_new (pad_actions[i].action_name, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
action = g_simple_action_new_stateful (pad_actions[i].action_name,
|
||||
G_VARIANT_TYPE_DOUBLE, NULL);
|
||||
}
|
||||
|
||||
g_signal_connect (action, "activate",
|
||||
G_CALLBACK (on_action_activate), label);
|
||||
g_object_set_data (G_OBJECT (action), "action-result",
|
||||
(gpointer) pad_action_results[i]);
|
||||
g_action_map_add_action (G_ACTION_MAP (action_group), G_ACTION (action));
|
||||
g_object_unref (action);
|
||||
}
|
||||
|
||||
gtk_pad_controller_set_action_entries (pad_controller, pad_actions,
|
||||
G_N_ELEMENTS (pad_actions));
|
||||
gtk_widget_add_controller (window, GTK_EVENT_CONTROLLER (pad_controller));
|
||||
|
||||
g_object_unref (action_group);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
do_event_axes (GtkWidget *toplevel)
|
||||
{
|
||||
static GtkWidget *window = NULL;
|
||||
EventData *event_data;
|
||||
GtkWidget *label;
|
||||
GtkWidget *overlay;
|
||||
GtkWidget *da;
|
||||
|
||||
if (!window)
|
||||
{
|
||||
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Touch and Drawing Tablets");
|
||||
|
||||
g_signal_connect (window, "destroy",
|
||||
G_CALLBACK (gtk_widget_destroyed), &window);
|
||||
|
||||
gtk_widget_set_support_multidevice (window, TRUE);
|
||||
|
||||
event_data = event_data_new ();
|
||||
g_object_set_data_full (G_OBJECT (window), "gtk-demo-event-data",
|
||||
event_data, (GDestroyNotify) event_data_free);
|
||||
|
||||
da = gtk_drawing_area_new ();
|
||||
gtk_drawing_area_set_content_width (GTK_DRAWING_AREA (da), 400);
|
||||
gtk_drawing_area_set_content_height (GTK_DRAWING_AREA (da), 400);
|
||||
gtk_drawing_area_set_draw_func (GTK_DRAWING_AREA (da), draw_cb, event_data, NULL);
|
||||
gtk_widget_set_can_focus (da, TRUE);
|
||||
gtk_widget_grab_focus (da);
|
||||
|
||||
g_signal_connect (da, "event",
|
||||
G_CALLBACK (event_cb), event_data);
|
||||
|
||||
label = gtk_label_new ("");
|
||||
gtk_widget_set_halign (label, GTK_ALIGN_START);
|
||||
gtk_widget_set_valign (label, GTK_ALIGN_START);
|
||||
gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
|
||||
|
||||
overlay = gtk_overlay_new ();
|
||||
gtk_container_add (GTK_CONTAINER (window), overlay);
|
||||
gtk_container_add (GTK_CONTAINER (overlay), da);
|
||||
gtk_overlay_add_overlay (GTK_OVERLAY (overlay), label);
|
||||
|
||||
init_pad_controller (da, label);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
gtk_widget_show (window);
|
||||
else
|
||||
gtk_widget_destroy (window);
|
||||
|
||||
return window;
|
||||
}
|
||||
@@ -134,7 +134,9 @@ static GtkWidget *
|
||||
create_video (void)
|
||||
{
|
||||
GtkMediaStream *stream = gtk_media_file_new_for_resource ("/images/gtk-logo.webm");
|
||||
GtkWidget *w = gtk_image_new_from_paintable (GDK_PAINTABLE (stream));
|
||||
GtkWidget *w = gtk_picture_new_for_paintable (GDK_PAINTABLE (stream));
|
||||
|
||||
gtk_widget_set_size_request (w, 64, 64);
|
||||
gtk_media_stream_set_loop (stream, TRUE);
|
||||
gtk_media_stream_play (stream);
|
||||
g_object_unref (stream);
|
||||
|
||||
+29
-34
@@ -135,55 +135,42 @@ static void set_cursor_if_appropriate (GtkTextView *text_view,
|
||||
gint x,
|
||||
gint y);
|
||||
|
||||
/* Links can also be activated by clicking or tapping.
|
||||
*/
|
||||
static gboolean
|
||||
event_cb (GtkWidget *text_view,
|
||||
GdkEvent *ev)
|
||||
static void
|
||||
released_cb (GtkGestureMultiPress *gesture,
|
||||
guint n_press,
|
||||
gdouble x,
|
||||
gdouble y,
|
||||
GtkWidget *text_view)
|
||||
{
|
||||
GtkTextIter start, end, iter;
|
||||
GtkTextBuffer *buffer;
|
||||
gdouble ex, ey;
|
||||
int x, y;
|
||||
GdkEventType type;
|
||||
int tx, ty;
|
||||
|
||||
type = gdk_event_get_event_type (ev);
|
||||
if (gtk_gesture_single_get_button (GTK_GESTURE_SINGLE (gesture)) > 1)
|
||||
return;
|
||||
|
||||
gdk_event_get_coords (ev, &ex, &ey);
|
||||
gtk_text_view_window_to_buffer_coords (GTK_TEXT_VIEW (text_view),
|
||||
GTK_TEXT_WINDOW_WIDGET,
|
||||
ex, ey, &x, &y);
|
||||
|
||||
if (type == GDK_BUTTON_RELEASE)
|
||||
{
|
||||
guint button;
|
||||
|
||||
gdk_event_get_button (ev, &button);
|
||||
if (button != GDK_BUTTON_PRIMARY)
|
||||
return FALSE;
|
||||
}
|
||||
else if (type == GDK_MOTION_NOTIFY)
|
||||
{
|
||||
set_cursor_if_appropriate (GTK_TEXT_VIEW (text_view), x, y);
|
||||
return FALSE;
|
||||
}
|
||||
else if (type == GDK_TOUCH_END)
|
||||
{
|
||||
}
|
||||
else
|
||||
return FALSE;
|
||||
x, y, &tx, &ty);
|
||||
|
||||
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_view));
|
||||
|
||||
/* we shouldn't follow a link if the user has selected something */
|
||||
gtk_text_buffer_get_selection_bounds (buffer, &start, &end);
|
||||
if (gtk_text_iter_get_offset (&start) != gtk_text_iter_get_offset (&end))
|
||||
return FALSE;
|
||||
return;
|
||||
|
||||
if (gtk_text_view_get_iter_at_location (GTK_TEXT_VIEW (text_view), &iter, x, y))
|
||||
follow_if_link (text_view, &iter);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
static void
|
||||
motion_cb (GtkEventControllerMotion *controller,
|
||||
gdouble x,
|
||||
gdouble y,
|
||||
GtkTextView *text_view)
|
||||
{
|
||||
set_cursor_if_appropriate (text_view, x, y);
|
||||
}
|
||||
|
||||
static gboolean hovering_over_link = FALSE;
|
||||
@@ -259,8 +246,16 @@ do_hypertext (GtkWidget *do_widget)
|
||||
controller = gtk_event_controller_key_new ();
|
||||
g_signal_connect (controller, "key-pressed", G_CALLBACK (key_pressed), view);
|
||||
gtk_widget_add_controller (view, controller);
|
||||
g_signal_connect (view, "event",
|
||||
G_CALLBACK (event_cb), NULL);
|
||||
|
||||
controller = GTK_EVENT_CONTROLLER (gtk_gesture_multi_press_new ());
|
||||
g_signal_connect (controller, "released",
|
||||
G_CALLBACK (released_cb), view);
|
||||
gtk_widget_add_controller (view, controller);
|
||||
|
||||
controller = gtk_event_controller_motion_new ();
|
||||
g_signal_connect (controller, "motion",
|
||||
G_CALLBACK (motion_cb), view);
|
||||
gtk_widget_add_controller (view, controller);
|
||||
|
||||
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
|
||||
|
||||
|
||||
@@ -154,6 +154,7 @@
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="extra_buttons_box">
|
||||
<property name="visible">0</property>
|
||||
<property name="spacing">6</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="reply-button">
|
||||
|
||||
@@ -22,7 +22,6 @@ demos = files([
|
||||
'editable_cells.c',
|
||||
'entry_buffer.c',
|
||||
'entry_completion.c',
|
||||
'event_axes.c',
|
||||
'expander.c',
|
||||
'filtermodel.c',
|
||||
'fishbowl.c',
|
||||
@@ -130,7 +129,7 @@ foreach icon_size: [ '16x16', '22x22', '24x24', '32x32', '48x48', '256x256', ]
|
||||
endforeach
|
||||
|
||||
# desktop file
|
||||
install_data('gtk4-demo.desktop', install_dir: gtk_applicationsdir)
|
||||
install_data('org.gtk.Demo.desktop', install_dir: gtk_applicationsdir)
|
||||
|
||||
# GSettings
|
||||
install_data('org.gtk.Demo.gschema.xml', install_dir: gtk_schemasdir)
|
||||
|
||||
+133
-5
@@ -3,14 +3,24 @@
|
||||
* Demonstrates practical handling of drawing tablets in a real world
|
||||
* usecase.
|
||||
*/
|
||||
#include <glib/gi18n.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
enum {
|
||||
COLOR_SET,
|
||||
N_SIGNALS
|
||||
};
|
||||
|
||||
static guint area_signals[N_SIGNALS] = { 0, };
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GtkWidget parent_instance;
|
||||
cairo_surface_t *surface;
|
||||
cairo_t *cr;
|
||||
GdkRGBA draw_color;
|
||||
GtkPadController *pad_controller;
|
||||
gdouble brush_size;
|
||||
} DrawingArea;
|
||||
|
||||
typedef struct
|
||||
@@ -18,8 +28,30 @@ typedef struct
|
||||
GtkWidgetClass parent_class;
|
||||
} DrawingAreaClass;
|
||||
|
||||
static GtkPadActionEntry pad_actions[] = {
|
||||
{ GTK_PAD_ACTION_BUTTON, 1, -1, N_("Black"), "pad.black" },
|
||||
{ GTK_PAD_ACTION_BUTTON, 2, -1, N_("Pink"), "pad.pink" },
|
||||
{ GTK_PAD_ACTION_BUTTON, 3, -1, N_("Green"), "pad.green" },
|
||||
{ GTK_PAD_ACTION_BUTTON, 4, -1, N_("Red"), "pad.red" },
|
||||
{ GTK_PAD_ACTION_BUTTON, 5, -1, N_("Purple"), "pad.purple" },
|
||||
{ GTK_PAD_ACTION_BUTTON, 6, -1, N_("Orange"), "pad.orange" },
|
||||
{ GTK_PAD_ACTION_STRIP, -1, -1, N_("Brush size"), "pad.brush_size" },
|
||||
};
|
||||
|
||||
static const gchar *pad_colors[] = {
|
||||
"black",
|
||||
"pink",
|
||||
"green",
|
||||
"red",
|
||||
"purple",
|
||||
"orange"
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (DrawingArea, drawing_area, GTK_TYPE_WIDGET)
|
||||
|
||||
static void drawing_area_set_color (DrawingArea *area,
|
||||
GdkRGBA *color);
|
||||
|
||||
static void
|
||||
drawing_area_ensure_surface (DrawingArea *area,
|
||||
gint width,
|
||||
@@ -115,6 +147,82 @@ drawing_area_snapshot (GtkWidget *widget,
|
||||
cairo_destroy (cr);
|
||||
}
|
||||
|
||||
static void
|
||||
on_pad_button_activate (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
DrawingArea *area)
|
||||
{
|
||||
const gchar *color = g_object_get_data (G_OBJECT (action), "color");
|
||||
GdkRGBA rgba;
|
||||
|
||||
gdk_rgba_parse (&rgba, color);
|
||||
drawing_area_set_color (area, &rgba);
|
||||
}
|
||||
|
||||
static void
|
||||
on_pad_knob_change (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
DrawingArea *area)
|
||||
{
|
||||
gdouble value = g_variant_get_double (parameter);
|
||||
|
||||
area->brush_size = value;
|
||||
}
|
||||
|
||||
static void
|
||||
drawing_area_hierarchy_changed (GtkWidget *widget,
|
||||
GtkWidget *previous_toplevel)
|
||||
{
|
||||
DrawingArea *area = (DrawingArea *) widget;
|
||||
GSimpleActionGroup *action_group;
|
||||
GSimpleAction *action;
|
||||
GtkWidget *toplevel;
|
||||
gint i;
|
||||
|
||||
if (previous_toplevel && area->pad_controller)
|
||||
{
|
||||
gtk_widget_remove_controller (previous_toplevel,
|
||||
GTK_EVENT_CONTROLLER (area->pad_controller));
|
||||
area->pad_controller = NULL;
|
||||
}
|
||||
|
||||
toplevel = gtk_widget_get_toplevel (GTK_WIDGET (area));
|
||||
if (!GTK_IS_WINDOW (toplevel))
|
||||
return;
|
||||
|
||||
action_group = g_simple_action_group_new ();
|
||||
area->pad_controller = gtk_pad_controller_new (G_ACTION_GROUP (action_group),
|
||||
NULL);
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (pad_actions); i++)
|
||||
{
|
||||
if (pad_actions[i].type == GTK_PAD_ACTION_BUTTON)
|
||||
{
|
||||
action = g_simple_action_new (pad_actions[i].action_name, NULL);
|
||||
g_object_set_data (G_OBJECT (action), "color",
|
||||
(gpointer) pad_colors[i]);
|
||||
g_signal_connect (action, "activate",
|
||||
G_CALLBACK (on_pad_button_activate), area);
|
||||
}
|
||||
else
|
||||
{
|
||||
action = g_simple_action_new_stateful (pad_actions[i].action_name,
|
||||
G_VARIANT_TYPE_DOUBLE, NULL);
|
||||
g_signal_connect (action, "activate",
|
||||
G_CALLBACK (on_pad_knob_change), area);
|
||||
}
|
||||
|
||||
g_action_map_add_action (G_ACTION_MAP (action_group), G_ACTION (action));
|
||||
g_object_unref (action);
|
||||
}
|
||||
|
||||
gtk_pad_controller_set_action_entries (area->pad_controller, pad_actions,
|
||||
G_N_ELEMENTS (pad_actions));
|
||||
|
||||
gtk_widget_add_controller (toplevel,
|
||||
GTK_EVENT_CONTROLLER (area->pad_controller));
|
||||
}
|
||||
|
||||
static void
|
||||
drawing_area_class_init (DrawingAreaClass *klass)
|
||||
{
|
||||
@@ -124,6 +232,14 @@ drawing_area_class_init (DrawingAreaClass *klass)
|
||||
widget_class->snapshot = drawing_area_snapshot;
|
||||
widget_class->map = drawing_area_map;
|
||||
widget_class->unmap = drawing_area_unmap;
|
||||
widget_class->hierarchy_changed = drawing_area_hierarchy_changed;
|
||||
|
||||
area_signals[COLOR_SET] =
|
||||
g_signal_new ("color-set",
|
||||
G_TYPE_FROM_CLASS (widget_class),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
0, NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 1, GDK_TYPE_RGBA);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -135,12 +251,12 @@ drawing_area_apply_stroke (DrawingArea *area,
|
||||
{
|
||||
if (gdk_device_tool_get_tool_type (tool) == GDK_DEVICE_TOOL_TYPE_ERASER)
|
||||
{
|
||||
cairo_set_line_width (area->cr, 10 * pressure);
|
||||
cairo_set_line_width (area->cr, 10 * pressure * area->brush_size);
|
||||
cairo_set_operator (area->cr, CAIRO_OPERATOR_DEST_OUT);
|
||||
}
|
||||
else
|
||||
{
|
||||
cairo_set_line_width (area->cr, 4 * pressure);
|
||||
cairo_set_line_width (area->cr, 4 * pressure * area->brush_size);
|
||||
cairo_set_operator (area->cr, CAIRO_OPERATOR_SATURATE);
|
||||
}
|
||||
|
||||
@@ -148,8 +264,6 @@ drawing_area_apply_stroke (DrawingArea *area,
|
||||
area->draw_color.green, area->draw_color.blue,
|
||||
area->draw_color.alpha * pressure);
|
||||
|
||||
//cairo_set_source_rgba (area->cr, 0, 0, 0, pressure);
|
||||
|
||||
cairo_line_to (area->cr, x, y);
|
||||
cairo_stroke (area->cr);
|
||||
cairo_move_to (area->cr, x, y);
|
||||
@@ -225,11 +339,15 @@ drawing_area_new (void)
|
||||
return g_object_new (drawing_area_get_type (), NULL);
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
drawing_area_set_color (DrawingArea *area,
|
||||
GdkRGBA *color)
|
||||
{
|
||||
if (gdk_rgba_equal (&area->draw_color, color))
|
||||
return;
|
||||
|
||||
area->draw_color = *color;
|
||||
g_signal_emit (area, area_signals[COLOR_SET], 0, &area->draw_color);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -242,6 +360,14 @@ color_button_color_set (GtkColorButton *button,
|
||||
drawing_area_set_color (draw_area, &color);
|
||||
}
|
||||
|
||||
static void
|
||||
drawing_area_color_set (DrawingArea *area,
|
||||
GdkRGBA *color,
|
||||
GtkColorButton *button)
|
||||
{
|
||||
gtk_color_chooser_set_rgba (GTK_COLOR_CHOOSER (button), color);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
do_paint (GtkWidget *toplevel)
|
||||
{
|
||||
@@ -263,6 +389,8 @@ do_paint (GtkWidget *toplevel)
|
||||
colorbutton = gtk_color_button_new ();
|
||||
g_signal_connect (colorbutton, "color-set",
|
||||
G_CALLBACK (color_button_color_set), draw_area);
|
||||
g_signal_connect (draw_area, "color-set",
|
||||
G_CALLBACK (drawing_area_color_set), colorbutton);
|
||||
gtk_color_chooser_set_rgba (GTK_COLOR_CHOOSER (colorbutton),
|
||||
&(GdkRGBA) { 0, 0, 0, 1 });
|
||||
|
||||
|
||||
@@ -77,7 +77,6 @@ entry_size_allocate_cb (GtkEntry *entry,
|
||||
static void
|
||||
entry_icon_press_cb (GtkEntry *entry,
|
||||
GtkEntryIconPosition icon_pos,
|
||||
GdkEvent *event,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkWidget *popover = user_data;
|
||||
|
||||
@@ -151,11 +151,10 @@ create_search_menu (GtkWidget *entry)
|
||||
static void
|
||||
icon_press_cb (GtkEntry *entry,
|
||||
gint position,
|
||||
GdkEventButton *event,
|
||||
gpointer data)
|
||||
{
|
||||
if (position == GTK_ENTRY_ICON_PRIMARY)
|
||||
gtk_menu_popup_at_pointer (GTK_MENU (menu), (GdkEvent *) event);
|
||||
gtk_menu_popup_at_pointer (GTK_MENU (menu), NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -26,17 +26,6 @@ changed_cb (GtkEditable *editable)
|
||||
g_message ("changed: %s", text);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
window_event_cb (GtkWidget *widget,
|
||||
GdkEvent *event,
|
||||
GtkSearchBar *bar)
|
||||
{
|
||||
if (gdk_event_get_event_type (event) == GDK_KEY_PRESS)
|
||||
return gtk_search_bar_handle_event (bar, event);
|
||||
|
||||
return GDK_EVENT_PROPAGATE;
|
||||
}
|
||||
|
||||
static void
|
||||
search_changed (GtkSearchEntry *entry,
|
||||
GtkLabel *label)
|
||||
@@ -102,7 +91,7 @@ do_search_entry2 (GtkWidget *do_widget)
|
||||
gtk_box_pack_start (GTK_BOX (vbox), searchbar);
|
||||
|
||||
/* Hook the search bar to key presses */
|
||||
g_signal_connect (window, "event", G_CALLBACK (window_event_cb), searchbar);
|
||||
gtk_search_bar_set_key_capture_widget (GTK_SEARCH_BAR (searchbar), window);
|
||||
|
||||
/* Help */
|
||||
label = gtk_label_new ("Start Typing to search");
|
||||
|
||||
@@ -295,6 +295,7 @@ start_puzzle (GdkPaintable *puzzle)
|
||||
grid = gtk_grid_new ();
|
||||
gtk_widget_set_can_focus (grid, TRUE);
|
||||
gtk_container_add (GTK_CONTAINER (frame), grid);
|
||||
gtk_aspect_frame_set (GTK_ASPECT_FRAME (frame), 0.5, 0.5, (float) gdk_paintable_get_intrinsic_aspect_ratio (puzzle), FALSE);
|
||||
|
||||
/* Add a key event controller so people can use the arrow
|
||||
* keys to move the puzzle */
|
||||
|
||||
@@ -376,10 +376,9 @@ search_mode_toggled (GObject *searchbar, GParamSpec *pspec, IconBrowserWindow *w
|
||||
|
||||
static void
|
||||
get_image_data (GtkWidget *widget,
|
||||
GdkDragContext *context,
|
||||
GdkDrag *drag,
|
||||
GtkSelectionData *selection,
|
||||
guint target_info,
|
||||
guint time,
|
||||
gpointer data)
|
||||
{
|
||||
GtkWidget *image;
|
||||
@@ -399,10 +398,9 @@ get_image_data (GtkWidget *widget,
|
||||
|
||||
static void
|
||||
get_scalable_image_data (GtkWidget *widget,
|
||||
GdkDragContext *context,
|
||||
GdkDrag *drag,
|
||||
GtkSelectionData *selection,
|
||||
guint target_info,
|
||||
guint time,
|
||||
gpointer data)
|
||||
{
|
||||
gchar *uris[2];
|
||||
|
||||
@@ -17,4 +17,4 @@ executable('gtk4-icon-browser',
|
||||
link_args: extra_demo_ldflags,
|
||||
install: true)
|
||||
|
||||
install_data('gtk4-icon-browser.desktop', install_dir: gtk_applicationsdir)
|
||||
install_data('org.gtk.IconBrowser.desktop', install_dir: gtk_applicationsdir)
|
||||
|
||||
@@ -13,7 +13,7 @@ executable('gtk4-widget-factory',
|
||||
install: true)
|
||||
|
||||
# desktop file
|
||||
install_data('gtk4-widget-factory.desktop', install_dir: gtk_applicationsdir)
|
||||
install_data('org.gtk.WidgetFactory.desktop', install_dir: gtk_applicationsdir)
|
||||
|
||||
# icons
|
||||
icontheme_dir = join_paths(gtk_datadir, 'icons/hicolor')
|
||||
|
||||
@@ -353,7 +353,6 @@ update_pulse_time (GtkAdjustment *adjustment, GtkWidget *widget)
|
||||
static void
|
||||
on_entry_icon_release (GtkEntry *entry,
|
||||
GtkEntryIconPosition icon_pos,
|
||||
GdkEvent *event,
|
||||
gpointer user_data)
|
||||
{
|
||||
if (icon_pos != GTK_ENTRY_ICON_SECONDARY)
|
||||
@@ -967,8 +966,8 @@ background_loaded_cb (GObject *source,
|
||||
return;
|
||||
}
|
||||
|
||||
child = gtk_image_new_from_pixbuf (pixbuf);
|
||||
gtk_widget_show (child);
|
||||
child = gtk_picture_new_for_pixbuf (pixbuf);
|
||||
gtk_widget_set_size_request (child, 110, 70);
|
||||
gtk_flow_box_insert (GTK_FLOW_BOX (bd->flowbox), child, -1);
|
||||
child = gtk_widget_get_parent (child);
|
||||
g_object_set_data_full (G_OBJECT (child), "filename", bd->filename, g_free);
|
||||
@@ -996,8 +995,7 @@ populate_flowbox (GtkWidget *flowbox)
|
||||
|
||||
pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, 110, 70);
|
||||
gdk_pixbuf_fill (pixbuf, 0xffffffff);
|
||||
child = gtk_image_new_from_pixbuf (pixbuf);
|
||||
gtk_widget_show (child);
|
||||
child = gtk_picture_new_for_pixbuf (pixbuf);
|
||||
gtk_flow_box_insert (GTK_FLOW_BOX (flowbox), child, -1);
|
||||
|
||||
location = "/usr/share/backgrounds/gnome";
|
||||
@@ -1082,7 +1080,7 @@ set_accel (GtkApplication *app, GtkWidget *widget)
|
||||
typedef struct
|
||||
{
|
||||
GtkTextView tv;
|
||||
GdkPixbuf *pixbuf;
|
||||
GdkTexture *texture;
|
||||
} MyTextView;
|
||||
|
||||
typedef GtkTextViewClass MyTextViewClass;
|
||||
@@ -1095,18 +1093,23 @@ my_text_view_init (MyTextView *tv)
|
||||
}
|
||||
|
||||
static void
|
||||
my_tv_draw_layer (GtkTextView *widget,
|
||||
GtkTextViewLayer layer,
|
||||
cairo_t *cr)
|
||||
my_tv_snapshot_layer (GtkTextView *widget,
|
||||
GtkTextViewLayer layer,
|
||||
GtkSnapshot *snapshot)
|
||||
{
|
||||
MyTextView *tv = (MyTextView *)widget;
|
||||
|
||||
if (layer == GTK_TEXT_VIEW_LAYER_BELOW_TEXT && tv->pixbuf)
|
||||
if (layer == GTK_TEXT_VIEW_LAYER_BELOW_TEXT && tv->texture)
|
||||
{
|
||||
cairo_save (cr);
|
||||
gdk_cairo_set_source_pixbuf (cr, tv->pixbuf, 0.0, 0.0);
|
||||
cairo_paint_with_alpha (cr, 0.333);
|
||||
cairo_restore (cr);
|
||||
gtk_snapshot_push_opacity (snapshot, 0.333);
|
||||
gtk_snapshot_append_texture (snapshot,
|
||||
tv->texture,
|
||||
&GRAPHENE_RECT_INIT(
|
||||
0, 0,
|
||||
gdk_texture_get_width (tv->texture),
|
||||
gdk_texture_get_height (tv->texture)
|
||||
));
|
||||
gtk_snapshot_pop (snapshot);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1115,7 +1118,7 @@ my_tv_finalize (GObject *object)
|
||||
{
|
||||
MyTextView *tv = (MyTextView *)object;
|
||||
|
||||
g_clear_object (&tv->pixbuf);
|
||||
g_clear_object (&tv->texture);
|
||||
|
||||
G_OBJECT_CLASS (my_text_view_parent_class)->finalize (object);
|
||||
}
|
||||
@@ -1127,20 +1130,24 @@ my_text_view_class_init (MyTextViewClass *class)
|
||||
GObjectClass *o_class = G_OBJECT_CLASS (class);
|
||||
|
||||
o_class->finalize = my_tv_finalize;
|
||||
tv_class->draw_layer = my_tv_draw_layer;
|
||||
tv_class->snapshot_layer = my_tv_snapshot_layer;
|
||||
}
|
||||
|
||||
static void
|
||||
my_text_view_set_background (MyTextView *tv, const gchar *filename)
|
||||
{
|
||||
GError *error = NULL;
|
||||
GFile *file;
|
||||
|
||||
g_clear_object (&tv->pixbuf);
|
||||
g_clear_object (&tv->texture);
|
||||
|
||||
if (filename == NULL)
|
||||
return;
|
||||
|
||||
tv->pixbuf = gdk_pixbuf_new_from_file (filename, &error);
|
||||
file = g_file_new_for_path (filename);
|
||||
tv->texture = gdk_texture_new_from_file (file, &error);
|
||||
g_object_unref (file);
|
||||
|
||||
if (error)
|
||||
{
|
||||
g_warning ("%s", error->message);
|
||||
|
||||
@@ -2226,6 +2226,9 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
<property name="tooltip-text" translatable="yes">Save the current document</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparatorToolItem"/>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToolButton">
|
||||
<property name="label" translatable="yes">Search</property>
|
||||
@@ -3580,4 +3583,4 @@ bad things might happen.</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
||||
</interface>
|
||||
@@ -71,7 +71,7 @@ straightforward manner.
|
||||
void gdk_drag_status (GdkDragContext *context,
|
||||
GdkDragAction action,
|
||||
guint32 time);
|
||||
void gdk_drop_finish (GdkDragContext *context,
|
||||
void gdk_drag_finish (GdkDragContext *context,
|
||||
gboolean success,
|
||||
guint32 time);
|
||||
GdkAtom gdk_drag_get_selection (GdkDragContext *context);
|
||||
|
||||
@@ -171,7 +171,6 @@ gdk_rgba_get_type
|
||||
<FILE>gdksurface</FILE>
|
||||
GdkSurface
|
||||
GdkSurfaceType
|
||||
GdkSurfaceClass
|
||||
GdkSurfaceHints
|
||||
GdkGeometry
|
||||
GdkGravity
|
||||
@@ -194,7 +193,6 @@ gdk_surface_is_visible
|
||||
gdk_surface_is_viewable
|
||||
gdk_surface_is_input_only
|
||||
gdk_surface_get_state
|
||||
gdk_surface_withdraw
|
||||
gdk_surface_iconify
|
||||
gdk_surface_deiconify
|
||||
gdk_surface_stick
|
||||
@@ -282,8 +280,6 @@ gdk_surface_get_toplevel
|
||||
gdk_surface_get_children
|
||||
gdk_surface_get_children_with_user_data
|
||||
gdk_surface_peek_children
|
||||
gdk_surface_get_events
|
||||
gdk_surface_set_events
|
||||
gdk_surface_set_icon_name
|
||||
gdk_surface_set_transient_for
|
||||
gdk_surface_set_role
|
||||
@@ -301,8 +297,6 @@ gdk_surface_get_support_multidevice
|
||||
gdk_surface_set_support_multidevice
|
||||
gdk_surface_get_device_cursor
|
||||
gdk_surface_set_device_cursor
|
||||
gdk_surface_get_device_events
|
||||
gdk_surface_set_device_events
|
||||
|
||||
<SUBSECTION>
|
||||
gdk_surface_coords_from_parent
|
||||
@@ -652,7 +646,7 @@ gdk_event_get_scancode
|
||||
gdk_event_get_pointer_emulated
|
||||
gdk_event_get_crossing_detail
|
||||
gdk_event_get_crossing_mode
|
||||
gdk_event_get_drag_context
|
||||
gdk_event_get_drop
|
||||
gdk_event_get_focus_in
|
||||
gdk_event_get_grab_surface
|
||||
gdk_event_get_motion_history
|
||||
@@ -661,7 +655,6 @@ gdk_event_get_key_is_modifier
|
||||
gdk_event_get_pad_axis_value
|
||||
gdk_event_get_pad_button
|
||||
gdk_event_get_pad_group_mode
|
||||
gdk_event_get_string
|
||||
gdk_event_get_touch_emulating_pointer
|
||||
gdk_event_get_touchpad_angle_delta
|
||||
gdk_event_get_touchpad_deltas
|
||||
@@ -698,7 +691,7 @@ gdk_event_get_type
|
||||
|
||||
<SECTION>
|
||||
<FILE>gdkpaintable</FILE>
|
||||
<TITLE>GdkPaintable/TITLE>
|
||||
<TITLE>GdkPaintable</TITLE>
|
||||
GdkPaintable
|
||||
GdkPaintableFlags
|
||||
gdk_paintable_get_current_image
|
||||
@@ -779,38 +772,60 @@ gdk_cursor_get_type
|
||||
<SECTION>
|
||||
<TITLE>Drag and Drop</TITLE>
|
||||
<FILE>dnd</FILE>
|
||||
GdkDragContext
|
||||
GdkDrag
|
||||
GdkDrop
|
||||
GdkDragCancelReason
|
||||
gdk_drag_drop_done
|
||||
gdk_drag_begin
|
||||
gdk_drop_finish
|
||||
GdkDragAction
|
||||
gdk_drag_status
|
||||
GDK_ACTION_ALL
|
||||
|
||||
gdk_drag_context_get_display
|
||||
gdk_drag_context_get_actions
|
||||
gdk_drag_context_get_suggested_action
|
||||
gdk_drag_context_get_selected_action
|
||||
gdk_drag_context_get_formats
|
||||
gdk_drag_context_get_device
|
||||
gdk_drag_context_get_source_surface
|
||||
gdk_drag_context_get_dest_surface
|
||||
gdk_drag_context_get_drag_surface
|
||||
gdk_drag_context_set_hotspot
|
||||
gdk_drag_get_display
|
||||
gdk_drag_get_actions
|
||||
gdk_drag_get_suggested_action
|
||||
gdk_drag_get_selected_action
|
||||
gdk_drag_get_formats
|
||||
gdk_drag_get_device
|
||||
gdk_drag_get_drag_surface
|
||||
gdk_drag_set_hotspot
|
||||
|
||||
<SUBSECTION>
|
||||
gdk_drag_action_is_unique
|
||||
|
||||
<SUBSECTION>
|
||||
gdk_drop_get_display
|
||||
gdk_drop_get_device
|
||||
gdk_drop_get_surface
|
||||
gdk_drop_get_formats
|
||||
gdk_drop_get_actions
|
||||
gdk_drop_get_drag
|
||||
gdk_drop_status
|
||||
gdk_drop_finish
|
||||
gdk_drop_read_async
|
||||
gdk_drop_read_finish
|
||||
gdk_drop_read_value_async
|
||||
gdk_drop_read_value_finish
|
||||
gdk_drop_read_text_async
|
||||
gdk_drop_read_text_finish
|
||||
|
||||
<SUBSECTION Standard>
|
||||
GDK_DRAG_CONTEXT
|
||||
GDK_TYPE_DRAG_CONTEXT
|
||||
GDK_IS_DRAG_CONTEXT
|
||||
GDK_DRAG_CONTEXT_CLASS
|
||||
GDK_DRAG_CONTEXT_GET_CLASS
|
||||
GDK_IS_DRAG_CONTEXT_CLASS
|
||||
GDK_DRAG
|
||||
GDK_TYPE_DRAG
|
||||
GDK_IS_DRAG
|
||||
GDK_DRAG_CLASS
|
||||
GDK_DRAG_GET_CLASS
|
||||
GDK_IS_DRAG_CLASS
|
||||
GDK_TYPE_DRAG_ACTION
|
||||
GDK_TYPE_DRAG_PROTOCOL
|
||||
GDK_TYPE_DROP
|
||||
GDK_DROP
|
||||
GDK_IS_DROP
|
||||
|
||||
<SUBSECTION Private>
|
||||
GdkDragContextClass
|
||||
gdk_drag_context_get_type
|
||||
GdkDragClass
|
||||
gdk_drag_get_type
|
||||
GdkDropClass
|
||||
gdk_drop_get_type
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
@@ -853,7 +868,6 @@ gdk_x11_screen_lookup_visual
|
||||
gdk_x11_screen_supports_net_wm_hint
|
||||
gdk_x11_screen_get_number_of_desktops
|
||||
gdk_x11_screen_get_current_desktop
|
||||
gdk_x11_surface_foreign_new_for_display
|
||||
gdk_x11_surface_lookup_for_display
|
||||
gdk_x11_surface_get_xid
|
||||
gdk_x11_surface_set_theme_variant
|
||||
@@ -1250,6 +1264,7 @@ gdk_clipboard_get_type
|
||||
<SECTION>
|
||||
<FILE>gdkcontentprovider</FILE>
|
||||
GdkContentProvider
|
||||
GdkContentProviderClass
|
||||
gdk_content_provider_new_for_value
|
||||
gdk_content_provider_new_for_bytes
|
||||
gdk_content_provider_ref_formats
|
||||
@@ -1265,7 +1280,6 @@ GDK_CONTENT_PROVIDER_CLASS
|
||||
GDK_CONTENT_PROVIDER_GET_CLASS
|
||||
GDK_IS_CONTENT_PROVIDER
|
||||
GDK_IS_CONTENT_PROVIDER_CLASS
|
||||
GdkContentProviderClass
|
||||
gdk_content_provider_get_type
|
||||
</SECTION>
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ gdk_app_launch_context_get_type
|
||||
gdk_clipboard_get_type
|
||||
gdk_content_deserializer_get_type
|
||||
gdk_content_formats_get_type
|
||||
gdk_content_provider_get_type
|
||||
gdk_content_serializer_get_type
|
||||
gdk_cursor_get_type
|
||||
gdk_device_get_type
|
||||
@@ -9,7 +10,8 @@ gdk_device_pad_get_type
|
||||
gdk_device_tool_get_type
|
||||
gdk_display_get_type
|
||||
gdk_display_manager_get_type
|
||||
gdk_drag_context_get_type
|
||||
gdk_drag_get_type
|
||||
gdk_drop_get_type
|
||||
gdk_event_get_type
|
||||
gdk_frame_clock_get_type
|
||||
gdk_gl_context_get_type
|
||||
|
||||
@@ -87,16 +87,22 @@ images = [
|
||||
'images/zoom_out_cursor.png',
|
||||
]
|
||||
|
||||
src_dir = [ gdkinc ]
|
||||
|
||||
if x11_enabled
|
||||
src_dir += [ gdkx11_inc ]
|
||||
endif
|
||||
|
||||
if wayland_enabled
|
||||
src_dir += [ gdkwayland_inc ]
|
||||
endif
|
||||
|
||||
configure_file(input: 'version.xml.in', output: 'version.xml', configuration: version_conf)
|
||||
|
||||
gnome.gtkdoc('gdk4',
|
||||
mode: 'none',
|
||||
main_xml: 'gdk4-docs.xml',
|
||||
src_dir: [
|
||||
gdkinc,
|
||||
gdkx11_inc,
|
||||
gdkwayland_inc,
|
||||
],
|
||||
src_dir: src_dir,
|
||||
dependencies: libgtk_dep,
|
||||
gobject_typesfile: join_paths(meson.current_source_dir(), 'gdk4.types'),
|
||||
scan_args: [
|
||||
|
||||
@@ -120,7 +120,7 @@
|
||||
here</ulink>.</para>
|
||||
|
||||
<para>Finally the window size is set using gtk_window_set_default_size and
|
||||
the window is then shown by GTK via gtk_widget_show_all().</para>
|
||||
the window is then shown by GTK via gtk_widget_show().</para>
|
||||
|
||||
<para>When you exit the window, by for example pressing the X,
|
||||
the g_application_run() in the main loop returns with a number
|
||||
@@ -388,7 +388,7 @@
|
||||
</informalfigure>
|
||||
|
||||
<informalexample>
|
||||
<programlisting><xi:include href="../../../../examples/application1/exampleapp.desktop" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
|
||||
<programlisting><xi:include href="../../../../examples/application1/org.gtk.exampleapp.desktop" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
|
||||
</informalexample>
|
||||
|
||||
<para>Note that <replaceable>@<!-- -->bindir@</replaceable> needs to be replaced
|
||||
@@ -488,23 +488,28 @@ example_app_window_class_init (ExampleAppWindowClass *class)
|
||||
<para>In this step, we make our application show the content of
|
||||
all the files that it is given on the commandline.</para>
|
||||
|
||||
<para>To this end, we add a private struct to our application
|
||||
<para>To this end, we add a member to the struct in application
|
||||
window subclass and keep a reference to the #GtkStack there.
|
||||
The gtk_widget_class_bind_template_child_private() function
|
||||
The first member of the struct should be the parent type from
|
||||
which the class is derived. Here, ExampleAppWindow is derived
|
||||
from GtkApplicationWindow.
|
||||
The gtk_widget_class_bind_template_child() function
|
||||
arranges things so that after instantiating the template, the
|
||||
@stack member of the private struct will point to the widget of
|
||||
@stack member of the struct will point to the widget of
|
||||
the same name from the template.</para>
|
||||
|
||||
<informalexample>
|
||||
<programlisting><![CDATA[
|
||||
...
|
||||
|
||||
struct _ExampleAppWindowPrivate
|
||||
struct _ExampleAppWindow
|
||||
{
|
||||
GtkApplicationWindow parent;
|
||||
|
||||
GtkWidget *stack;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE(ExampleAppWindow, example_app_window, GTK_TYPE_APPLICATION_WINDOW);
|
||||
G_DEFINE_TYPE (ExampleAppWindow, example_app_window, GTK_TYPE_APPLICATION_WINDOW)
|
||||
|
||||
...
|
||||
|
||||
@@ -513,7 +518,7 @@ example_app_window_class_init (ExampleAppWindowClass *class)
|
||||
{
|
||||
gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
|
||||
"/org/gtk/exampleapp/window.ui");
|
||||
gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (class), ExampleAppWindow, stack);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), ExampleAppWindow, stack);
|
||||
}
|
||||
|
||||
...
|
||||
@@ -533,25 +538,21 @@ void
|
||||
example_app_window_open (ExampleAppWindow *win,
|
||||
GFile *file)
|
||||
{
|
||||
ExampleAppWindowPrivate *priv;
|
||||
gchar *basename;
|
||||
GtkWidget *scrolled, *view;
|
||||
gchar *contents;
|
||||
gsize length;
|
||||
|
||||
priv = example_app_window_get_instance_private (win);
|
||||
basename = g_file_get_basename (file);
|
||||
|
||||
scrolled = gtk_scrolled_window_new (NULL, NULL);
|
||||
gtk_widget_show (scrolled);
|
||||
gtk_widget_set_hexpand (scrolled, TRUE);
|
||||
gtk_widget_set_vexpand (scrolled, TRUE);
|
||||
view = gtk_text_view_new ();
|
||||
gtk_text_view_set_editable (GTK_TEXT_VIEW (view), FALSE);
|
||||
gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (view), FALSE);
|
||||
gtk_widget_show (view);
|
||||
gtk_container_add (GTK_CONTAINER (scrolled), view);
|
||||
gtk_stack_add_titled (GTK_STACK (priv->stack), scrolled, basename, basename);
|
||||
gtk_stack_add_titled (GTK_STACK (win->stack), scrolled, basename, basename);
|
||||
|
||||
if (g_file_load_contents (file, NULL, &contents, &length, NULL, NULL))
|
||||
{
|
||||
@@ -718,14 +719,11 @@ example_app_class_init (ExampleAppClass *class)
|
||||
static void
|
||||
example_app_window_init (ExampleAppWindow *win)
|
||||
{
|
||||
ExampleAppWindowPrivate *priv;
|
||||
|
||||
priv = example_app_window_get_instance_private (win);
|
||||
gtk_widget_init_template (GTK_WIDGET (win));
|
||||
priv->settings = g_settings_new ("org.gtk.exampleapp");
|
||||
win->settings = g_settings_new ("org.gtk.exampleapp");
|
||||
|
||||
g_settings_bind (priv->settings, "transition",
|
||||
priv->stack, "transition-type",
|
||||
g_settings_bind (win->settings, "transition",
|
||||
win->stack, "transition-type",
|
||||
G_SETTINGS_BIND_DEFAULT);
|
||||
}
|
||||
|
||||
@@ -823,7 +821,6 @@ static void
|
||||
search_text_changed (GtkEntry *entry,
|
||||
ExampleAppWindow *win)
|
||||
{
|
||||
ExampleAppWindowPrivate *priv;
|
||||
const gchar *text;
|
||||
GtkWidget *tab;
|
||||
GtkWidget *view;
|
||||
@@ -835,9 +832,7 @@ search_text_changed (GtkEntry *entry,
|
||||
if (text[0] == '\0')
|
||||
return;
|
||||
|
||||
priv = example_app_window_get_instance_private (win);
|
||||
|
||||
tab = gtk_stack_get_visible_child (GTK_STACK (priv->stack));
|
||||
tab = gtk_stack_get_visible_child (GTK_STACK (win->stack));
|
||||
view = gtk_bin_get_child (GTK_BIN (tab));
|
||||
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
|
||||
|
||||
@@ -978,12 +973,12 @@ example_app_window_init (ExampleAppWindow *win)
|
||||
{
|
||||
...
|
||||
|
||||
action = (GAction*) g_property_action_new ("show-lines", priv->lines, "visible");
|
||||
action = (GAction*) g_property_action_new ("show-lines", win->lines, "visible");
|
||||
g_action_map_add_action (G_ACTION_MAP (win), action);
|
||||
g_object_unref (action);
|
||||
|
||||
g_object_bind_property (priv->lines, "visible",
|
||||
priv->lines_label, "visible",
|
||||
g_object_bind_property (win->lines, "visible",
|
||||
win->lines_label, "visible",
|
||||
G_BINDING_DEFAULT);
|
||||
}
|
||||
|
||||
|
||||
@@ -385,7 +385,6 @@
|
||||
<xi:include href="osx.sgml" />
|
||||
<xi:include href="broadway.xml" />
|
||||
<xi:include href="wayland.xml" />
|
||||
<xi:include href="mir.xml" />
|
||||
</part>
|
||||
|
||||
<xi:include href="glossary.xml" />
|
||||
|
||||
@@ -679,8 +679,6 @@ gtk_combo_box_get_active_id
|
||||
gtk_combo_box_set_active_id
|
||||
gtk_combo_box_get_model
|
||||
gtk_combo_box_set_model
|
||||
gtk_combo_box_popup_for_device
|
||||
gtk_combo_box_popup
|
||||
gtk_combo_box_popdown
|
||||
gtk_combo_box_get_popup_accessible
|
||||
gtk_combo_box_get_row_separator_func
|
||||
@@ -760,9 +758,6 @@ gtk_container_child_set_valist
|
||||
gtk_container_child_notify
|
||||
gtk_container_child_notify_by_pspec
|
||||
gtk_container_forall
|
||||
gtk_container_get_focus_chain
|
||||
gtk_container_set_focus_chain
|
||||
gtk_container_unset_focus_chain
|
||||
gtk_container_class_find_child_property
|
||||
gtk_container_class_install_child_property
|
||||
gtk_container_class_install_child_properties
|
||||
@@ -1724,8 +1719,6 @@ gtk_menu_attach
|
||||
gtk_menu_popup_at_rect
|
||||
gtk_menu_popup_at_widget
|
||||
gtk_menu_popup_at_pointer
|
||||
gtk_menu_popup_for_device
|
||||
gtk_menu_popup
|
||||
gtk_menu_set_accel_group
|
||||
gtk_menu_get_accel_group
|
||||
gtk_menu_set_accel_path
|
||||
@@ -4865,7 +4858,6 @@ gtk_style_context_get_parent
|
||||
gtk_style_context_get_path
|
||||
gtk_style_context_get_property
|
||||
gtk_style_context_get_display
|
||||
gtk_style_context_get_frame_clock
|
||||
gtk_style_context_get_state
|
||||
gtk_style_context_get_valist
|
||||
gtk_style_context_get_section
|
||||
@@ -4888,7 +4880,6 @@ gtk_style_context_remove_class
|
||||
gtk_style_context_has_class
|
||||
gtk_style_context_list_classes
|
||||
gtk_style_context_set_display
|
||||
gtk_style_context_set_frame_clock
|
||||
gtk_style_context_set_state
|
||||
gtk_style_context_set_scale
|
||||
gtk_style_context_get_scale
|
||||
@@ -4909,12 +4900,10 @@ gtk_render_check
|
||||
gtk_render_expander
|
||||
gtk_render_focus
|
||||
gtk_render_frame
|
||||
gtk_render_frame_gap
|
||||
gtk_render_handle
|
||||
gtk_render_layout
|
||||
gtk_render_line
|
||||
gtk_render_option
|
||||
gtk_render_slider
|
||||
gtk_render_activity
|
||||
gtk_render_icon
|
||||
gtk_render_insertion_cursor
|
||||
@@ -4938,7 +4927,6 @@ gtk_border_get_type
|
||||
<FILE>gtkcssprovider</FILE>
|
||||
<TITLE>GtkCssProvider</TITLE>
|
||||
GtkCssProvider
|
||||
gtk_css_provider_get_default
|
||||
gtk_css_provider_get_named
|
||||
gtk_css_provider_load_from_data
|
||||
gtk_css_provider_load_from_file
|
||||
@@ -5015,6 +5003,7 @@ gtk_selection_data_get_type
|
||||
<TITLE>Drag and Drop</TITLE>
|
||||
GtkDestDefaults
|
||||
GtkDragResult
|
||||
|
||||
<SUBSECTION Destination Side>
|
||||
gtk_drag_dest_set
|
||||
gtk_drag_dest_unset
|
||||
@@ -5026,13 +5015,13 @@ gtk_drag_dest_add_image_targets
|
||||
gtk_drag_dest_add_uri_targets
|
||||
gtk_drag_dest_set_track_motion
|
||||
gtk_drag_dest_get_track_motion
|
||||
gtk_drag_finish
|
||||
gtk_drag_get_data
|
||||
gtk_drag_get_source_widget
|
||||
gtk_drag_highlight
|
||||
gtk_drag_unhighlight
|
||||
|
||||
<SUBSECTION Source Side>
|
||||
gtk_drag_begin_with_coordinates
|
||||
gtk_drag_begin
|
||||
gtk_drag_cancel
|
||||
gtk_drag_set_icon_widget
|
||||
gtk_drag_set_icon_paintable
|
||||
@@ -6017,6 +6006,8 @@ gtk_overlay_get_overlay_pass_through
|
||||
gtk_overlay_set_overlay_pass_through
|
||||
gtk_overlay_get_measure_overlay
|
||||
gtk_overlay_set_measure_overlay
|
||||
gtk_overlay_get_clip_overlay
|
||||
gtk_overlay_set_clip_overlay
|
||||
|
||||
<SUBSECTION Standard>
|
||||
GTK_TYPE_OVERLAY
|
||||
@@ -6464,7 +6455,7 @@ gtk_gesture_single_get_type
|
||||
|
||||
<SECTION>
|
||||
<FILE>gtkeventcontrollerscroll</FILE>
|
||||
<TITLE>GtkEventControlerScroll</TITLE>
|
||||
<TITLE>GtkEventControllerScroll</TITLE>
|
||||
GtkEventControllerScroll
|
||||
GtkEventControllerScrollFlags
|
||||
gtk_event_controller_scroll_new
|
||||
@@ -6485,7 +6476,7 @@ gtk_event_controller_scroll_get_type
|
||||
|
||||
<SECTION>
|
||||
<FILE>gtkeventcontrollermotion</FILE>
|
||||
<TITLE>GtkEventControlerMotion</TITLE>
|
||||
<TITLE>GtkEventControllerMotion</TITLE>
|
||||
GtkEventControllerMotion
|
||||
gtk_event_controller_motion_new
|
||||
|
||||
@@ -6503,7 +6494,7 @@ gtk_event_controller_motion_get_type
|
||||
|
||||
<SECTION>
|
||||
<FILE>gtkeventcontrollerkey</FILE>
|
||||
<TITLE>GtkEventControlerKey</TITLE>
|
||||
<TITLE>GtkEventControllerKey</TITLE>
|
||||
GtkEventControllerKey
|
||||
gtk_event_controller_key_new
|
||||
|
||||
|
||||
@@ -118,6 +118,7 @@ gtk_page_setup_get_type
|
||||
@DISABLE_ON_W32@gtk_page_setup_unix_dialog_get_type
|
||||
gtk_paned_get_type
|
||||
gtk_paper_size_get_type
|
||||
gtk_picture_get_type
|
||||
gtk_popover_get_type
|
||||
gtk_popover_menu_get_type
|
||||
@DISABLE_ON_W32@gtk_printer_get_type
|
||||
|
||||
@@ -179,41 +179,6 @@
|
||||
</para>
|
||||
</refsect2>
|
||||
|
||||
<refsect2 id="event-masks">
|
||||
<title>Event masks</title>
|
||||
|
||||
<para>
|
||||
Each widget instance has a basic event mask and another per input device,
|
||||
which determine the types of input event it receives. Each event mask set
|
||||
on a widget is added to the corresponding (basic or per-device) event mask
|
||||
for the widget’s #GdkSurface, and all child #GdkSurfaces.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Filtering events against event masks happens inside #GdkSurface, which
|
||||
exposes event masks to the windowing system to reduce the number of events
|
||||
GDK receives from it. On receiving an event, it is filtered against the
|
||||
#GdkSurface’s mask for the input device, if set. Otherwise, it is filtered
|
||||
against the #GdkSurface’s basic event mask.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
This means that widgets must add to the event mask for each event type
|
||||
they expect to receive, using gtk_widget_set_events() or
|
||||
gtk_widget_add_events() to preserve the existing mask. Widgets which are
|
||||
aware of floating devices should use gtk_widget_set_device_events() or
|
||||
gtk_widget_add_device_events(), and must explicitly enable the device
|
||||
using gtk_widget_set_device_enabled(). See the #GdkDeviceManager
|
||||
documentation for more information.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
All standard widgets set the event mask for all events they expect to
|
||||
receive, and it is not necessary to modify this. Masks should be set when
|
||||
implementing a new widget.
|
||||
</para>
|
||||
</refsect2>
|
||||
|
||||
<refsect2>
|
||||
<title>Touch events</title>
|
||||
|
||||
|
||||
@@ -355,7 +355,6 @@ content_files = [
|
||||
'input-handling.xml',
|
||||
'migrating-2to4.xml',
|
||||
'migrating-3to4.xml',
|
||||
'mir.xml',
|
||||
'osx.sgml',
|
||||
'other_software.sgml',
|
||||
'overview.xml',
|
||||
|
||||
@@ -20,11 +20,11 @@
|
||||
|
||||
<para>
|
||||
The steps outlined in the following sections assume that your
|
||||
application is working with GTK+ 3.22, which is the final stable
|
||||
application is working with GTK+ 3.24, which is the final stable
|
||||
release of GTK+ 3.x. It includes all the necessary APIs and tools
|
||||
to help you port your application to GTK+ 4. If you are still using
|
||||
an older version of GTK+ 3.x, you should first get your application
|
||||
to build and work with the latest minor release in the 3.22 series.
|
||||
to build and work with the latest minor release in the 3.24 series.
|
||||
</para>
|
||||
|
||||
<section>
|
||||
@@ -34,7 +34,7 @@
|
||||
widgets have been deprecated. These deprecations are clearly spelled
|
||||
out in the API reference, with hints about the recommended replacements.
|
||||
The API reference for GTK+ 3 also includes an
|
||||
<ulink url="https://developer.gnome.org/gtk3/3.22/api-index-deprecated.html">index</ulink> of all deprecated symbols.
|
||||
<ulink url="https://developer.gnome.org/gtk3/3.24/api-index-deprecated.html">index</ulink> of all deprecated symbols.
|
||||
</para>
|
||||
<para>
|
||||
To verify that your program does not use any deprecated symbols,
|
||||
@@ -79,13 +79,13 @@
|
||||
<title>Review your window creation flags</title>
|
||||
<para>
|
||||
GTK+ 4 removes the GDK_WA_CURSOR flag. Instead, just use
|
||||
gdk_surface_set_cursor() to set a cursor on the window after
|
||||
gdk_window_set_cursor() to set a cursor on the window after
|
||||
creating it.
|
||||
</para>
|
||||
<para>
|
||||
GTK+ 4 also removes the GDK_WA_VISUAL flag, and always uses
|
||||
an RGBA visual for windows. To prepare your code for this,
|
||||
use gdk_surface_set_visual (gdk_screen_get_rgba_visual ()) after
|
||||
use gdk_window_set_visual (gdk_screen_get_rgba_visual ()) after
|
||||
creating your window.
|
||||
</para>
|
||||
<para>
|
||||
@@ -169,6 +169,30 @@
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Stop using GtkWidget event signals</title>
|
||||
<para>
|
||||
Event controllers and #GtkGestures replace event signals in GTK+ 4. They
|
||||
have been backported to GTK+ 3.x so you can prepare for this change.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Set a proper app_id</title>
|
||||
<para>
|
||||
In GTK+4 we want the application's #GApplication
|
||||
'application-id' (and therefore the D-Bus name), the desktop
|
||||
file basename and Wayland's xdg-shell app_id to match. In
|
||||
order to achieve this with GTK+3 call g_set_prgname() with the same
|
||||
application id you passed to #GtkApplication. Rename your
|
||||
desktop files to match the application id if needed.
|
||||
</para>
|
||||
<para>
|
||||
The call to g_set_prgname() can be removed once you fully migrated
|
||||
to GTK+4.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
</section>
|
||||
|
||||
<section>
|
||||
@@ -262,6 +286,14 @@
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Stop using GtkEventBox</title>
|
||||
<para>
|
||||
GtkEventBox is no longer needed and has been removed.
|
||||
All widgets receive all events.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Adapt to GtkHeaderBar API changes</title>
|
||||
<para>
|
||||
@@ -311,6 +343,15 @@
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Adapt to GtkWidget's size allocation changes</title>
|
||||
<para>
|
||||
The #GtkWidget::size-allocate signal now takes the baseline as an
|
||||
argument, so you no longer need to call gtk_widget_get_allocated_baseline()
|
||||
to get it.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Switch to GtkWidget's children APIs</title>
|
||||
<para>
|
||||
@@ -391,6 +432,10 @@
|
||||
from ui files it run the command <command>gtk4-builder-tool simplify --replace</command>
|
||||
on them.
|
||||
</para>
|
||||
<para>
|
||||
The function gtk_widget_show_all(), the #GtkWidget::no-show-all property
|
||||
and its getter and setter have been removed in GTK+ 4, so you should stop using them.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
@@ -432,8 +477,7 @@
|
||||
<title>GtkWidget event signals are removed</title>
|
||||
<para>
|
||||
Event controllers and #GtkGestures have already been introduced in GTK+ 3 to handle
|
||||
input for many cases. In GTK+ 4, even more are available, such as #GtkEventControllerScroll
|
||||
and GtkEventControllerMotion, and the traditional widget signals for handling input,
|
||||
input for many cases. In GTK+ 4, the traditional widget signals for handling input,
|
||||
such as #GtkWidget::motion-event or #GtkWidget::event have been removed.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
|
||||
]>
|
||||
<refentry id="gtk-mir">
|
||||
<refmeta>
|
||||
<refentrytitle>Using GTK+ with Mir</refentrytitle>
|
||||
<manvolnum>3</manvolnum>
|
||||
<refmiscinfo>GTK Library</refmiscinfo>
|
||||
</refmeta>
|
||||
|
||||
<refnamediv>
|
||||
<refname>Using GTK+ with Mir</refname>
|
||||
<refpurpose>
|
||||
Mir-specific aspects of using GTK+
|
||||
</refpurpose>
|
||||
</refnamediv>
|
||||
|
||||
<refsect1>
|
||||
<title>Using GTK+ with Mir</title>
|
||||
|
||||
<para>
|
||||
The GDK Mir backend provides support for running GTK+ applications
|
||||
under Mir based display servers. To run your application in this way,
|
||||
select the Mir backend by setting <literal>GDK_BACKEND=mir</literal>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Currently, the Mir backend does not use any additional commandline
|
||||
options or environment variables.
|
||||
</para>
|
||||
|
||||
</refsect1>
|
||||
|
||||
</refentry>
|
||||
@@ -435,11 +435,6 @@ nevertheless.
|
||||
<listitem><para>Selects the Wayland backend for connecting to Wayland display servers</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>mir</term>
|
||||
<listitem><para>Selects the Mir backend for connecting to Mir display servers</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
Since 3.10, this environment variable can contain a comma-separated list
|
||||
of backend names, which are tried in order. The list may also contain
|
||||
|
||||
@@ -2,8 +2,8 @@ To make gnome-shell use the desktop file and icon for this example
|
||||
while running it uninstalled, do the following:
|
||||
|
||||
mkdir -p ~/.local/share/applications
|
||||
sed -e "s#@bindir@#$PWD#" exampleapp.desktop \
|
||||
> ~/.local/share/applications/lt-exampleapp.desktop
|
||||
sed -e "s#@bindir@#$PWD#" org.gtk.exampleapp.desktop \
|
||||
> ~/.local/share/applications/org.gtk.exampleapp.desktop
|
||||
|
||||
mkdir -p ~/.local/share/icons/hicolor/48x48/apps
|
||||
cp exampleapp.png ~/.local/share/icons/hicolor/48x48/apps
|
||||
|
||||
+2
-18
@@ -1,16 +1,5 @@
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
static gboolean
|
||||
window_key_pressed (GtkEventController *controller,
|
||||
guint keyval,
|
||||
guint keycode,
|
||||
GdkModifierType state,
|
||||
GtkSearchBar *search_bar)
|
||||
{
|
||||
return gtk_search_bar_handle_event (search_bar,
|
||||
gtk_get_current_event ());
|
||||
}
|
||||
|
||||
static void
|
||||
activate_cb (GtkApplication *app,
|
||||
gpointer user_data)
|
||||
@@ -20,12 +9,12 @@ activate_cb (GtkApplication *app,
|
||||
GtkWidget *box;
|
||||
GtkWidget *entry;
|
||||
GtkWidget *menu_button;
|
||||
GtkEventController *controller;
|
||||
|
||||
window = gtk_application_window_new (app);
|
||||
gtk_widget_show (window);
|
||||
|
||||
search_bar = gtk_search_bar_new ();
|
||||
gtk_widget_set_valign (search_bar, GTK_ALIGN_START);
|
||||
gtk_container_add (GTK_CONTAINER (window), search_bar);
|
||||
gtk_widget_show (search_bar);
|
||||
|
||||
@@ -40,12 +29,7 @@ activate_cb (GtkApplication *app,
|
||||
gtk_box_pack_start (GTK_BOX (box), menu_button);
|
||||
|
||||
gtk_search_bar_connect_entry (GTK_SEARCH_BAR (search_bar), GTK_ENTRY (entry));
|
||||
|
||||
controller = gtk_event_controller_key_new ();
|
||||
g_object_set_data_full (G_OBJECT (window), "controller", controller, g_object_unref);
|
||||
g_signal_connect (controller, "key-pressed",
|
||||
G_CALLBACK (window_key_pressed), search_bar);
|
||||
gtk_widget_add_controller (window, controller);
|
||||
gtk_search_bar_set_key_capture_widget (GTK_SEARCH_BAR (search_bar), window);
|
||||
}
|
||||
|
||||
gint
|
||||
|
||||
@@ -61,9 +61,6 @@ static GdkSurface * gdk_broadway_device_surface_at_position (GdkDevice *de
|
||||
gdouble *win_y,
|
||||
GdkModifierType *mask,
|
||||
gboolean get_toplevel);
|
||||
static void gdk_broadway_device_select_surface_events (GdkDevice *device,
|
||||
GdkSurface *surface,
|
||||
GdkEventMask event_mask);
|
||||
|
||||
|
||||
G_DEFINE_TYPE (GdkBroadwayDevice, gdk_broadway_device, GDK_TYPE_DEVICE)
|
||||
@@ -81,7 +78,6 @@ gdk_broadway_device_class_init (GdkBroadwayDeviceClass *klass)
|
||||
device_class->grab = gdk_broadway_device_grab;
|
||||
device_class->ungrab = gdk_broadway_device_ungrab;
|
||||
device_class->surface_at_position = gdk_broadway_device_surface_at_position;
|
||||
device_class->select_surface_events = gdk_broadway_device_select_surface_events;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -325,9 +321,3 @@ gdk_broadway_device_surface_at_position (GdkDevice *device,
|
||||
return surface;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_broadway_device_select_surface_events (GdkDevice *device,
|
||||
GdkSurface *surface,
|
||||
GdkEventMask event_mask)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -49,9 +49,6 @@ struct _GdkBroadwayDisplay
|
||||
/* Keyboard related information */
|
||||
GdkKeymap *keymap;
|
||||
|
||||
/* drag and drop information */
|
||||
GdkDragContext *current_dest_drag;
|
||||
|
||||
GdkBroadwayServer *server;
|
||||
|
||||
gpointer move_resize_data;
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gdkdndprivate.h"
|
||||
#include "gdkdragprivate.h"
|
||||
|
||||
#include "gdkinternals.h"
|
||||
#include "gdkproperty.h"
|
||||
@@ -34,56 +34,56 @@
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#define GDK_TYPE_BROADWAY_DRAG_CONTEXT (gdk_broadway_drag_context_get_type ())
|
||||
#define GDK_BROADWAY_DRAG_CONTEXT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_BROADWAY_DRAG_CONTEXT, GdkBroadwayDragContext))
|
||||
#define GDK_BROADWAY_DRAG_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_BROADWAY_DRAG_CONTEXT, GdkBroadwayDragContextClass))
|
||||
#define GDK_IS_BROADWAY_DRAG_CONTEXT(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_BROADWAY_DRAG_CONTEXT))
|
||||
#define GDK_IS_BROADWAY_DRAG_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_BROADWAY_DRAG_CONTEXT))
|
||||
#define GDK_BROADWAY_DRAG_CONTEXT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_BROADWAY_DRAG_CONTEXT, GdkBroadwayDragContextClass))
|
||||
#define GDK_TYPE_BROADWAY_DRAG (gdk_broadway_drag_get_type ())
|
||||
#define GDK_BROADWAY_DRAG(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_BROADWAY_DRAG, GdkBroadwayDrag))
|
||||
#define GDK_BROADWAY_DRAG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_BROADWAY_DRAG, GdkBroadwayDragClass))
|
||||
#define GDK_IS_BROADWAY_DRAG(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_BROADWAY_DRAG))
|
||||
#define GDK_IS_BROADWAY_DRAG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_BROADWAY_DRAG))
|
||||
#define GDK_BROADWAY_DRAG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_BROADWAY_DRAG, GdkBroadwayDragClass))
|
||||
|
||||
#ifdef GDK_COMPILATION
|
||||
typedef struct _GdkBroadwayDragContext GdkBroadwayDragContext;
|
||||
typedef struct _GdkBroadwayDrag GdkBroadwayDrag;
|
||||
#else
|
||||
typedef GdkDragContext GdkBroadwayDragContext;
|
||||
typedef GdkDrag GdkBroadwayDrag;
|
||||
#endif
|
||||
typedef struct _GdkBroadwayDragContextClass GdkBroadwayDragContextClass;
|
||||
typedef struct _GdkBroadwayDragClass GdkBroadwayDragClass;
|
||||
|
||||
GType gdk_broadway_drag_context_get_type (void);
|
||||
GType gdk_broadway_drag_get_type (void);
|
||||
|
||||
struct _GdkBroadwayDragContext {
|
||||
GdkDragContext context;
|
||||
struct _GdkBroadwayDrag {
|
||||
GdkDrag context;
|
||||
};
|
||||
|
||||
struct _GdkBroadwayDragContextClass
|
||||
struct _GdkBroadwayDragClass
|
||||
{
|
||||
GdkDragContextClass parent_class;
|
||||
GdkDragClass parent_class;
|
||||
};
|
||||
|
||||
static void gdk_broadway_drag_context_finalize (GObject *object);
|
||||
static void gdk_broadway_drag_finalize (GObject *object);
|
||||
|
||||
static GList *contexts;
|
||||
|
||||
G_DEFINE_TYPE (GdkBroadwayDragContext, gdk_broadway_drag_context, GDK_TYPE_DRAG_CONTEXT)
|
||||
G_DEFINE_TYPE (GdkBroadwayDrag, gdk_broadway_drag, GDK_TYPE_DRAG)
|
||||
|
||||
static void
|
||||
gdk_broadway_drag_context_init (GdkBroadwayDragContext *dragcontext)
|
||||
gdk_broadway_drag_init (GdkBroadwayDrag *dragcontext)
|
||||
{
|
||||
contexts = g_list_prepend (contexts, dragcontext);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_broadway_drag_context_finalize (GObject *object)
|
||||
gdk_broadway_drag_finalize (GObject *object)
|
||||
{
|
||||
GdkDragContext *context = GDK_DRAG_CONTEXT (object);
|
||||
GdkDrag *context = GDK_DRAG (object);
|
||||
|
||||
contexts = g_list_remove (contexts, context);
|
||||
|
||||
G_OBJECT_CLASS (gdk_broadway_drag_context_parent_class)->finalize (object);
|
||||
G_OBJECT_CLASS (gdk_broadway_drag_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
/* Drag Contexts */
|
||||
|
||||
GdkDragContext *
|
||||
GdkDrag *
|
||||
_gdk_broadway_surface_drag_begin (GdkSurface *surface,
|
||||
GdkDevice *device,
|
||||
GdkContentProvider *content,
|
||||
@@ -91,12 +91,12 @@ _gdk_broadway_surface_drag_begin (GdkSurface *surface,
|
||||
gint dx,
|
||||
gint dy)
|
||||
{
|
||||
GdkDragContext *new_context;
|
||||
GdkDrag *new_context;
|
||||
|
||||
g_return_val_if_fail (surface != NULL, NULL);
|
||||
g_return_val_if_fail (GDK_SURFACE_IS_BROADWAY (surface), NULL);
|
||||
|
||||
new_context = g_object_new (GDK_TYPE_BROADWAY_DRAG_CONTEXT,
|
||||
new_context = g_object_new (GDK_TYPE_BROADWAY_DRAG,
|
||||
"device", device,
|
||||
"content", content,
|
||||
NULL);
|
||||
@@ -104,38 +104,6 @@ _gdk_broadway_surface_drag_begin (GdkSurface *surface,
|
||||
return new_context;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_broadway_drag_context_drag_drop (GdkDragContext *context,
|
||||
guint32 time)
|
||||
{
|
||||
g_return_if_fail (context != NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_broadway_drag_context_drag_abort (GdkDragContext *context,
|
||||
guint32 time)
|
||||
{
|
||||
g_return_if_fail (context != NULL);
|
||||
}
|
||||
|
||||
/* Destination side */
|
||||
|
||||
static void
|
||||
gdk_broadway_drag_context_drag_status (GdkDragContext *context,
|
||||
GdkDragAction action,
|
||||
guint32 time)
|
||||
{
|
||||
g_return_if_fail (context != NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_broadway_drag_context_drop_finish (GdkDragContext *context,
|
||||
gboolean success,
|
||||
guint32 time)
|
||||
{
|
||||
g_return_if_fail (context != NULL);
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_broadway_surface_register_dnd (GdkSurface *surface)
|
||||
{
|
||||
@@ -147,15 +115,9 @@ _gdk_broadway_display_init_dnd (GdkDisplay *display)
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_broadway_drag_context_class_init (GdkBroadwayDragContextClass *klass)
|
||||
gdk_broadway_drag_class_init (GdkBroadwayDragClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GdkDragContextClass *context_class = GDK_DRAG_CONTEXT_CLASS (klass);
|
||||
|
||||
object_class->finalize = gdk_broadway_drag_context_finalize;
|
||||
|
||||
context_class->drag_status = gdk_broadway_drag_context_drag_status;
|
||||
context_class->drag_abort = gdk_broadway_drag_context_drag_abort;
|
||||
context_class->drag_drop = gdk_broadway_drag_context_drag_drop;
|
||||
context_class->drop_finish = gdk_broadway_drag_context_drop_finish;
|
||||
object_class->finalize = gdk_broadway_drag_finalize;
|
||||
}
|
||||
|
||||
@@ -285,7 +285,6 @@ _gdk_broadway_events_got_input (BroadwayInputMsg *message)
|
||||
event->key.state = message->key.state;
|
||||
event->key.hardware_keycode = message->key.key;
|
||||
gdk_event_set_scancode (event, message->key.key);
|
||||
event->key.length = 0;
|
||||
gdk_event_set_device (event, gdk_seat_get_keyboard (seat));
|
||||
|
||||
node = _gdk_event_queue_append (display, event);
|
||||
|
||||
@@ -46,7 +46,7 @@ void gdk_broadway_surface_set_nodes (GdkSurface *surface,
|
||||
GPtrArray *node_textures);
|
||||
|
||||
void _gdk_broadway_surface_register_dnd (GdkSurface *surface);
|
||||
GdkDragContext * _gdk_broadway_surface_drag_begin (GdkSurface *surface,
|
||||
GdkDrag * _gdk_broadway_surface_drag_begin (GdkSurface *surface,
|
||||
GdkDevice *device,
|
||||
GdkContentProvider *content,
|
||||
GdkDragAction actions,
|
||||
@@ -101,7 +101,6 @@ void _gdk_broadway_display_get_maximal_cursor_size (GdkDisplay *display,
|
||||
void _gdk_broadway_display_create_surface_impl (GdkDisplay *display,
|
||||
GdkSurface *surface,
|
||||
GdkSurface *real_parent,
|
||||
GdkEventMask event_mask,
|
||||
GdkSurfaceAttr *attributes);
|
||||
gint _gdk_broadway_display_text_property_to_utf8_list (GdkDisplay *display,
|
||||
GdkAtom encoding,
|
||||
|
||||
@@ -207,7 +207,6 @@ void
|
||||
_gdk_broadway_display_create_surface_impl (GdkDisplay *display,
|
||||
GdkSurface *surface,
|
||||
GdkSurface *real_parent,
|
||||
GdkEventMask event_mask,
|
||||
GdkSurfaceAttr *attributes)
|
||||
{
|
||||
GdkSurfaceImplBroadway *impl;
|
||||
@@ -323,11 +322,7 @@ gdk_surface_broadway_show (GdkSurface *surface,
|
||||
impl = GDK_SURFACE_IMPL_BROADWAY (surface->impl);
|
||||
impl->visible = TRUE;
|
||||
|
||||
if (surface->event_mask & GDK_STRUCTURE_MASK)
|
||||
_gdk_make_event (GDK_SURFACE (surface), GDK_MAP, NULL, FALSE);
|
||||
|
||||
if (surface->parent && surface->parent->event_mask & GDK_SUBSTRUCTURE_MASK)
|
||||
_gdk_make_event (GDK_SURFACE (surface), GDK_MAP, NULL, FALSE);
|
||||
/* FIXME: update state ? */
|
||||
|
||||
broadway_display = GDK_BROADWAY_DISPLAY (gdk_surface_get_display (surface));
|
||||
if (_gdk_broadway_server_surface_show (broadway_display->server, impl->id))
|
||||
@@ -344,11 +339,7 @@ gdk_surface_broadway_hide (GdkSurface *surface)
|
||||
impl = GDK_SURFACE_IMPL_BROADWAY (surface->impl);
|
||||
impl->visible = FALSE;
|
||||
|
||||
if (surface->event_mask & GDK_STRUCTURE_MASK)
|
||||
_gdk_make_event (GDK_SURFACE (surface), GDK_UNMAP, NULL, FALSE);
|
||||
|
||||
if (surface->parent && surface->parent->event_mask & GDK_SUBSTRUCTURE_MASK)
|
||||
_gdk_make_event (GDK_SURFACE (surface), GDK_UNMAP, NULL, FALSE);
|
||||
/* FIXME: update state ? */
|
||||
|
||||
broadway_display = GDK_BROADWAY_DISPLAY (gdk_surface_get_display (surface));
|
||||
|
||||
@@ -620,24 +611,6 @@ gdk_surface_broadway_get_device_state (GdkSurface *surface,
|
||||
return child != NULL;
|
||||
}
|
||||
|
||||
static GdkEventMask
|
||||
gdk_surface_broadway_get_events (GdkSurface *surface)
|
||||
{
|
||||
if (GDK_SURFACE_DESTROYED (surface))
|
||||
return 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_surface_broadway_set_events (GdkSurface *surface,
|
||||
GdkEventMask event_mask)
|
||||
{
|
||||
if (!GDK_SURFACE_DESTROYED (surface))
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_surface_broadway_input_shape_combine_region (GdkSurface *surface,
|
||||
const cairo_region_t *shape_region,
|
||||
@@ -1359,8 +1332,6 @@ gdk_surface_impl_broadway_class_init (GdkSurfaceImplBroadwayClass *klass)
|
||||
impl_class->show = gdk_surface_broadway_show;
|
||||
impl_class->hide = gdk_surface_broadway_hide;
|
||||
impl_class->withdraw = gdk_surface_broadway_withdraw;
|
||||
impl_class->set_events = gdk_surface_broadway_set_events;
|
||||
impl_class->get_events = gdk_surface_broadway_get_events;
|
||||
impl_class->raise = gdk_surface_broadway_raise;
|
||||
impl_class->lower = gdk_surface_broadway_lower;
|
||||
impl_class->restack_toplevel = gdk_surface_broadway_restack_toplevel;
|
||||
|
||||
+12
-12
@@ -43,8 +43,19 @@ clienthtml_h = custom_target('clienthtml.h',
|
||||
],
|
||||
)
|
||||
|
||||
broadwayjs_h = custom_target('broadwayjs.h',
|
||||
input : ['broadway.js'],
|
||||
output : 'broadwayjs.h',
|
||||
command : [
|
||||
gen_c_array,
|
||||
'--array-name=broadway_js',
|
||||
'--output=@OUTPUT@',
|
||||
'@INPUT0@',
|
||||
],
|
||||
)
|
||||
|
||||
libgdk_broadway = static_library('gdk-broadway',
|
||||
clienthtml_h,
|
||||
clienthtml_h, broadwayjs_h,
|
||||
gdk_broadway_sources, gdkconfig, gdkenum_h,
|
||||
include_directories: [confinc, gdkinc],
|
||||
c_args: [
|
||||
@@ -58,17 +69,6 @@ libgdk_broadway = static_library('gdk-broadway',
|
||||
|
||||
broadwayd_syslib = os_win32 ? find_library('ws2_32') : shmlib
|
||||
|
||||
broadwayjs_h = custom_target('broadwayjs.h',
|
||||
input : ['broadway.js'],
|
||||
output : 'broadwayjs.h',
|
||||
command : [
|
||||
gen_c_array,
|
||||
'--array-name=broadway_js',
|
||||
'--output=@OUTPUT@',
|
||||
'@INPUT0@',
|
||||
],
|
||||
)
|
||||
|
||||
executable('gtk4-broadwayd',
|
||||
clienthtml_h, broadwayjs_h,
|
||||
'broadwayd.c', 'broadway-server.c', 'broadway-output.c',
|
||||
|
||||
@@ -23,12 +23,12 @@
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkAppLaunchContext, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkClipboard, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkContentProvider, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkCursor, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkDevice, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkDisplay, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkDisplayManager, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkDragContext, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkDrawingContext, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkDrag, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkDrawContext, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkFrameClock, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkGLContext, g_object_unref)
|
||||
|
||||
@@ -33,4 +33,6 @@ void gdk_display_set_cursor_theme (GdkDisplay *display,
|
||||
int size);
|
||||
gboolean gdk_running_in_sandbox (void);
|
||||
|
||||
const gchar * gdk_get_startup_notification_id (void);
|
||||
|
||||
#endif /* __GDK__PRIVATE_H__ */
|
||||
|
||||
@@ -154,6 +154,36 @@ static const GDebugKey gdk_debug_keys[] = {
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef G_HAS_CONSTRUCTORS
|
||||
#ifdef G_DEFINE_CONSTRUCTOR_NEEDS_PRAGMA
|
||||
#pragma G_DEFINE_CONSTRUCTOR_PRAGMA_ARGS(stash_desktop_startup_notification_id)
|
||||
#endif
|
||||
G_DEFINE_CONSTRUCTOR(stash_desktop_startup_notification_id)
|
||||
#endif
|
||||
|
||||
static gchar *startup_notification_id = NULL;
|
||||
|
||||
static void
|
||||
stash_desktop_startup_notification_id (void)
|
||||
{
|
||||
const char *desktop_startup_id;
|
||||
|
||||
desktop_startup_id = g_getenv ("DESKTOP_STARTUP_ID");
|
||||
if (desktop_startup_id && *desktop_startup_id != '\0')
|
||||
{
|
||||
if (!g_utf8_validate (desktop_startup_id, -1, NULL))
|
||||
g_warning ("DESKTOP_STARTUP_ID contains invalid UTF-8");
|
||||
else
|
||||
startup_notification_id = g_strdup (desktop_startup_id ? desktop_startup_id : "");
|
||||
}
|
||||
|
||||
/* Clear the environment variable so it won't be inherited by
|
||||
* child processes and confuse things.
|
||||
*/
|
||||
g_unsetenv ("DESKTOP_STARTUP_ID");
|
||||
}
|
||||
|
||||
static gpointer
|
||||
register_resources (gpointer dummy G_GNUC_UNUSED)
|
||||
{
|
||||
@@ -186,6 +216,10 @@ gdk_pre_parse (void)
|
||||
G_N_ELEMENTS (gdk_debug_keys));
|
||||
}
|
||||
#endif /* G_ENABLE_DEBUG */
|
||||
|
||||
#ifndef G_HAS_CONSTRUCTORS
|
||||
stash_desktop_startup_notification_id ();
|
||||
#endif
|
||||
}
|
||||
|
||||
/*< private >
|
||||
@@ -216,6 +250,22 @@ gdk_display_open_default (void)
|
||||
return display;
|
||||
}
|
||||
|
||||
/*< private >
|
||||
*
|
||||
* gdk_get_startup_notification_id
|
||||
*
|
||||
* Returns the original value of the DESKTOP_STARTUP_ID environment
|
||||
* variable if it was defined and valid, or %NULL otherwise.
|
||||
*
|
||||
* Returns: (nullable) (transfer none): the original value of the
|
||||
* DESKTOP_STARTUP_ID environment variable, or %NULL.
|
||||
*/
|
||||
const gchar *
|
||||
gdk_get_startup_notification_id (void)
|
||||
{
|
||||
return startup_notification_id;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gdk_running_in_sandbox (void)
|
||||
{
|
||||
|
||||
@@ -44,8 +44,9 @@
|
||||
#include <gdk/gdkdevicetool.h>
|
||||
#include <gdk/gdkdisplay.h>
|
||||
#include <gdk/gdkdisplaymanager.h>
|
||||
#include <gdk/gdkdnd.h>
|
||||
#include <gdk/gdkdrag.h>
|
||||
#include <gdk/gdkdrawcontext.h>
|
||||
#include <gdk/gdkdrop.h>
|
||||
#include <gdk/gdkenumtypes.h>
|
||||
#include <gdk/gdkevents.h>
|
||||
#include <gdk/gdkframeclock.h>
|
||||
|
||||
@@ -716,8 +716,7 @@ file_uri_deserializer_finish (GObject *source,
|
||||
return;
|
||||
}
|
||||
|
||||
str = g_memory_output_stream_steal_data (G_MEMORY_OUTPUT_STREAM (
|
||||
g_filter_output_stream_get_base_stream (G_FILTER_OUTPUT_STREAM (stream))));
|
||||
str = g_memory_output_stream_steal_data (G_MEMORY_OUTPUT_STREAM (stream));
|
||||
uris = g_uri_list_extract_uris (str);
|
||||
g_free (str);
|
||||
|
||||
@@ -738,6 +737,8 @@ file_uri_deserializer_finish (GObject *source,
|
||||
g_value_take_boxed (value, g_slist_reverse (l));
|
||||
}
|
||||
g_strfreev (uris);
|
||||
|
||||
gdk_content_deserializer_return_success (deserializer);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -895,8 +895,8 @@ init (void)
|
||||
gdk_content_register_serializer (G_TYPE_STRING,
|
||||
mime,
|
||||
string_serializer,
|
||||
mime,
|
||||
g_free);
|
||||
(gpointer) charset,
|
||||
NULL);
|
||||
}
|
||||
gdk_content_register_serializer (G_TYPE_STRING,
|
||||
"text/plain",
|
||||
|
||||
+1
-18
@@ -61,12 +61,7 @@
|
||||
* the commonly available names that are shared with the CSS specification.
|
||||
* Other names may be available, depending on the platform in use.
|
||||
* Another option to create a cursor is to use gdk_cursor_new_from_texture()
|
||||
* and provide an image to use for the cursor. Depending on the #GdkDisplay
|
||||
* in use, the type of supported images may be limited. See
|
||||
* gdk_display_supports_cursor_alpha(),
|
||||
* gdk_display_supports_cursor_color(),
|
||||
* gdk_display_get_default_cursor_size() and
|
||||
* gdk_display_get_maximal_cursor_size() for the limitations that might apply.
|
||||
* and provide an image to use for the cursor.
|
||||
*
|
||||
* To ease work with unsupported cursors, a fallback cursor can be provided.
|
||||
* If a #GdkSurface cannot use a cursor because of the reasons mentioned above,
|
||||
@@ -346,18 +341,6 @@ gdk_cursor_new_from_name (const gchar *name,
|
||||
*
|
||||
* Creates a new cursor from a #GdkTexture.
|
||||
*
|
||||
* Not all GDK backends support RGBA cursors. If they are not
|
||||
* supported, a monochrome approximation will be displayed.
|
||||
* The functions gdk_display_supports_cursor_alpha() and
|
||||
* gdk_display_supports_cursor_color() can be used to determine
|
||||
* whether RGBA cursors are supported;
|
||||
* gdk_display_get_default_cursor_size() and
|
||||
* gdk_display_get_maximal_cursor_size() give information about
|
||||
* cursor sizes.
|
||||
*
|
||||
* On the X backend, support for RGBA cursors requires a
|
||||
* sufficently new version of the X Render extension.
|
||||
*
|
||||
* Returns: a new #GdkCursor.
|
||||
*/
|
||||
GdkCursor *
|
||||
|
||||
@@ -112,9 +112,6 @@ struct _GdkDeviceClass
|
||||
double *win_y,
|
||||
GdkModifierType *mask,
|
||||
gboolean get_toplevel);
|
||||
void (* select_surface_events) (GdkDevice *device,
|
||||
GdkSurface *surface,
|
||||
GdkEventMask event_mask);
|
||||
};
|
||||
|
||||
void _gdk_device_set_associated_device (GdkDevice *device,
|
||||
|
||||
@@ -47,8 +47,6 @@ typedef struct _GdkDeviceTool GdkDeviceTool;
|
||||
*
|
||||
* Indicates the specific type of tool being used being a tablet. Such as an
|
||||
* airbrush, pencil, etc.
|
||||
*
|
||||
* Since: 3.22
|
||||
*/
|
||||
typedef enum {
|
||||
GDK_DEVICE_TOOL_TYPE_UNKNOWN,
|
||||
|
||||
+28
-13
@@ -492,8 +492,6 @@ gdk_display_put_event_nocopy (GdkDisplay *display,
|
||||
GdkEvent *event)
|
||||
{
|
||||
_gdk_event_queue_append (display, event);
|
||||
/* If the main loop is blocking in a different thread, wake it up */
|
||||
g_main_context_wakeup (NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -633,8 +631,7 @@ get_current_toplevel (GdkDisplay *display,
|
||||
pointer_surface = _gdk_device_surface_at_position (device, &x, &y, &state, TRUE);
|
||||
|
||||
if (pointer_surface != NULL &&
|
||||
(GDK_SURFACE_DESTROYED (pointer_surface) ||
|
||||
GDK_SURFACE_TYPE (pointer_surface) == GDK_SURFACE_FOREIGN))
|
||||
GDK_SURFACE_DESTROYED (pointer_surface))
|
||||
pointer_surface = NULL;
|
||||
|
||||
*x_out = round (x);
|
||||
@@ -1283,6 +1280,26 @@ gdk_display_notify_startup_complete (GdkDisplay *display,
|
||||
GDK_DISPLAY_GET_CLASS (display)->notify_startup_complete (display, startup_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_display_get_startup_notification_id:
|
||||
* @display: a #GdkDisplay
|
||||
*
|
||||
* Gets the startup notification ID for a Wayland display, or %NULL
|
||||
* if no ID has been defined.
|
||||
*
|
||||
* Returns: the startup notification ID for @display, or %NULL
|
||||
*/
|
||||
const gchar *
|
||||
gdk_display_get_startup_notification_id (GdkDisplay *display)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
|
||||
|
||||
if (GDK_DISPLAY_GET_CLASS (display)->get_startup_notification_id == NULL)
|
||||
return NULL;
|
||||
|
||||
return GDK_DISPLAY_GET_CLASS (display)->get_startup_notification_id (display);
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_display_pause_events (GdkDisplay *display)
|
||||
{
|
||||
@@ -1313,17 +1330,15 @@ _gdk_display_event_data_free (GdkDisplay *display,
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_display_create_surface_impl (GdkDisplay *display,
|
||||
GdkSurface *surface,
|
||||
GdkSurface *real_parent,
|
||||
GdkEventMask event_mask,
|
||||
GdkSurfaceAttr *attributes)
|
||||
gdk_display_create_surface_impl (GdkDisplay *display,
|
||||
GdkSurface *surface,
|
||||
GdkSurface *real_parent,
|
||||
GdkSurfaceAttr *attributes)
|
||||
{
|
||||
GDK_DISPLAY_GET_CLASS (display)->create_surface_impl (display,
|
||||
surface,
|
||||
real_parent,
|
||||
event_mask,
|
||||
attributes);
|
||||
surface,
|
||||
real_parent,
|
||||
attributes);
|
||||
}
|
||||
|
||||
GdkSurface *
|
||||
|
||||
@@ -94,6 +94,8 @@ gboolean gdk_display_supports_input_shapes (GdkDisplay *display);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_display_notify_startup_complete (GdkDisplay *display,
|
||||
const gchar *startup_id);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
const gchar * gdk_display_get_startup_notification_id (GdkDisplay *display);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkAppLaunchContext *gdk_display_get_app_launch_context (GdkDisplay *display);
|
||||
|
||||
@@ -136,6 +136,8 @@ struct _GdkDisplayClass
|
||||
|
||||
void (*notify_startup_complete) (GdkDisplay *display,
|
||||
const gchar *startup_id);
|
||||
const gchar * (*get_startup_notification_id) (GdkDisplay *display);
|
||||
|
||||
void (*event_data_copy) (GdkDisplay *display,
|
||||
const GdkEvent *event,
|
||||
GdkEvent *new_event);
|
||||
@@ -144,7 +146,6 @@ struct _GdkDisplayClass
|
||||
void (*create_surface_impl) (GdkDisplay *display,
|
||||
GdkSurface *surface,
|
||||
GdkSurface *real_parent,
|
||||
GdkEventMask event_mask,
|
||||
GdkSurfaceAttr *attributes);
|
||||
|
||||
GdkKeymap * (*get_keymap) (GdkDisplay *display);
|
||||
@@ -231,10 +232,9 @@ void _gdk_display_event_data_copy (GdkDisplay *display
|
||||
GdkEvent *new_event);
|
||||
void _gdk_display_event_data_free (GdkDisplay *display,
|
||||
GdkEvent *event);
|
||||
void _gdk_display_create_surface_impl (GdkDisplay *display,
|
||||
void gdk_display_create_surface_impl (GdkDisplay *display,
|
||||
GdkSurface *surface,
|
||||
GdkSurface *real_parent,
|
||||
GdkEventMask event_mask,
|
||||
GdkSurfaceAttr *attributes);
|
||||
GdkSurface * _gdk_display_create_surface (GdkDisplay *display);
|
||||
|
||||
|
||||
-954
@@ -1,954 +0,0 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 1995-1999 Peter Mattis, Spencer Kimball and Josh MacDonald
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
|
||||
* file for a list of people on the GTK+ Team. See the ChangeLog
|
||||
* files for a list of changes. These files are distributed with
|
||||
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gdkdndprivate.h"
|
||||
#include "gdkdisplay.h"
|
||||
#include "gdksurface.h"
|
||||
#include "gdkintl.h"
|
||||
#include "gdkcontentformats.h"
|
||||
#include "gdkcontentprovider.h"
|
||||
#include "gdkcontentserializer.h"
|
||||
#include "gdkcursor.h"
|
||||
#include "gdkenumtypes.h"
|
||||
#include "gdkeventsprivate.h"
|
||||
|
||||
typedef struct _GdkDragContextPrivate GdkDragContextPrivate;
|
||||
|
||||
struct _GdkDragContextPrivate
|
||||
{
|
||||
GdkDisplay *display;
|
||||
GdkDevice *device;
|
||||
GdkContentFormats *formats;
|
||||
};
|
||||
|
||||
static struct {
|
||||
GdkDragAction action;
|
||||
const gchar *name;
|
||||
GdkCursor *cursor;
|
||||
} drag_cursors[] = {
|
||||
{ GDK_ACTION_DEFAULT, NULL, NULL },
|
||||
{ GDK_ACTION_ASK, "dnd-ask", NULL },
|
||||
{ GDK_ACTION_COPY, "dnd-copy", NULL },
|
||||
{ GDK_ACTION_MOVE, "dnd-move", NULL },
|
||||
{ GDK_ACTION_LINK, "dnd-link", NULL },
|
||||
{ 0, "dnd-none", NULL },
|
||||
};
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_CONTENT,
|
||||
PROP_DEVICE,
|
||||
PROP_DISPLAY,
|
||||
PROP_FORMATS,
|
||||
N_PROPERTIES
|
||||
};
|
||||
|
||||
enum {
|
||||
CANCEL,
|
||||
DROP_PERFORMED,
|
||||
DND_FINISHED,
|
||||
ACTION_CHANGED,
|
||||
N_SIGNALS
|
||||
};
|
||||
|
||||
static GParamSpec *properties[N_PROPERTIES] = { NULL, };
|
||||
static guint signals[N_SIGNALS] = { 0 };
|
||||
static GList *contexts = NULL;
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (GdkDragContext, gdk_drag_context, G_TYPE_OBJECT)
|
||||
|
||||
/**
|
||||
* SECTION:dnd
|
||||
* @title: Drag And Drop
|
||||
* @short_description: Functions for controlling drag and drop handling
|
||||
*
|
||||
* These functions provide a low level interface for drag and drop.
|
||||
* The X backend of GDK supports both the Xdnd and Motif drag and drop
|
||||
* protocols transparently, the Win32 backend supports the WM_DROPFILES
|
||||
* protocol.
|
||||
*
|
||||
* GTK+ provides a higher level abstraction based on top of these functions,
|
||||
* and so they are not normally needed in GTK+ applications.
|
||||
* See the [Drag and Drop][gtk3-Drag-and-Drop] section of
|
||||
* the GTK+ documentation for more information.
|
||||
*/
|
||||
|
||||
/**
|
||||
* GdkDragContext:
|
||||
*
|
||||
* The GdkDragContext struct contains only private fields and
|
||||
* should not be accessed directly.
|
||||
*/
|
||||
|
||||
/**
|
||||
* gdk_drag_context_get_display:
|
||||
* @context: a #GdkDragContext
|
||||
*
|
||||
* Gets the #GdkDisplay that the drag context was created for.
|
||||
*
|
||||
* Returns: (transfer none): a #GdkDisplay
|
||||
**/
|
||||
GdkDisplay *
|
||||
gdk_drag_context_get_display (GdkDragContext *context)
|
||||
{
|
||||
GdkDragContextPrivate *priv = gdk_drag_context_get_instance_private (context);
|
||||
|
||||
g_return_val_if_fail (GDK_IS_DRAG_CONTEXT (context), NULL);
|
||||
|
||||
return priv->display;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_drag_context_get_formats:
|
||||
* @context: a #GdkDragContext
|
||||
*
|
||||
* Retrieves the formats supported by this context.
|
||||
*
|
||||
* Returns: (transfer none): a #GdkContentFormats
|
||||
**/
|
||||
GdkContentFormats *
|
||||
gdk_drag_context_get_formats (GdkDragContext *context)
|
||||
{
|
||||
GdkDragContextPrivate *priv = gdk_drag_context_get_instance_private (context);
|
||||
|
||||
g_return_val_if_fail (GDK_IS_DRAG_CONTEXT (context), NULL);
|
||||
|
||||
return priv->formats;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_drag_context_get_actions:
|
||||
* @context: a #GdkDragContext
|
||||
*
|
||||
* Determines the bitmask of actions proposed by the source if
|
||||
* gdk_drag_context_get_suggested_action() returns %GDK_ACTION_ASK.
|
||||
*
|
||||
* Returns: the #GdkDragAction flags
|
||||
**/
|
||||
GdkDragAction
|
||||
gdk_drag_context_get_actions (GdkDragContext *context)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_DRAG_CONTEXT (context), GDK_ACTION_DEFAULT);
|
||||
|
||||
return context->actions;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_drag_context_get_suggested_action:
|
||||
* @context: a #GdkDragContext
|
||||
*
|
||||
* Determines the suggested drag action of the context.
|
||||
*
|
||||
* Returns: a #GdkDragAction value
|
||||
**/
|
||||
GdkDragAction
|
||||
gdk_drag_context_get_suggested_action (GdkDragContext *context)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_DRAG_CONTEXT (context), 0);
|
||||
|
||||
return context->suggested_action;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_drag_context_get_selected_action:
|
||||
* @context: a #GdkDragContext
|
||||
*
|
||||
* Determines the action chosen by the drag destination.
|
||||
*
|
||||
* Returns: a #GdkDragAction value
|
||||
**/
|
||||
GdkDragAction
|
||||
gdk_drag_context_get_selected_action (GdkDragContext *context)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_DRAG_CONTEXT (context), 0);
|
||||
|
||||
return context->action;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_drag_context_get_source_surface:
|
||||
* @context: a #GdkDragContext
|
||||
*
|
||||
* Returns the #GdkSurface where the DND operation started.
|
||||
*
|
||||
* Returns: (transfer none): a #GdkSurface
|
||||
**/
|
||||
GdkSurface *
|
||||
gdk_drag_context_get_source_surface (GdkDragContext *context)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_DRAG_CONTEXT (context), NULL);
|
||||
|
||||
return context->source_surface;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_drag_context_get_dest_surface:
|
||||
* @context: a #GdkDragContext
|
||||
*
|
||||
* Returns the destination surface for the DND operation.
|
||||
*
|
||||
* Returns: (transfer none): a #GdkSurface
|
||||
**/
|
||||
GdkSurface *
|
||||
gdk_drag_context_get_dest_surface (GdkDragContext *context)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_DRAG_CONTEXT (context), NULL);
|
||||
|
||||
return context->dest_surface;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_drag_context_get_device:
|
||||
* @context: a #GdkDragContext
|
||||
*
|
||||
* Returns the #GdkDevice associated to the drag context.
|
||||
*
|
||||
* Returns: (transfer none): The #GdkDevice associated to @context.
|
||||
**/
|
||||
GdkDevice *
|
||||
gdk_drag_context_get_device (GdkDragContext *context)
|
||||
{
|
||||
GdkDragContextPrivate *priv = gdk_drag_context_get_instance_private (context);
|
||||
|
||||
g_return_val_if_fail (GDK_IS_DRAG_CONTEXT (context), NULL);
|
||||
|
||||
return priv->device;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_drag_context_init (GdkDragContext *context)
|
||||
{
|
||||
contexts = g_list_prepend (contexts, context);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_drag_context_set_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GdkDragContext *context = GDK_DRAG_CONTEXT (gobject);
|
||||
GdkDragContextPrivate *priv = gdk_drag_context_get_instance_private (context);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_CONTENT:
|
||||
context->content = g_value_dup_object (value);
|
||||
if (context->content)
|
||||
{
|
||||
g_assert (priv->formats == NULL);
|
||||
priv->formats = gdk_content_provider_ref_formats (context->content);
|
||||
}
|
||||
break;
|
||||
|
||||
case PROP_DEVICE:
|
||||
priv->device = g_value_dup_object (value);
|
||||
g_assert (priv->device != NULL);
|
||||
priv->display = gdk_device_get_display (priv->device);
|
||||
break;
|
||||
|
||||
case PROP_FORMATS:
|
||||
if (priv->formats)
|
||||
{
|
||||
GdkContentFormats *override = g_value_dup_boxed (value);
|
||||
if (override)
|
||||
{
|
||||
gdk_content_formats_unref (priv->formats);
|
||||
priv->formats = override;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
priv->formats = g_value_dup_boxed (value);
|
||||
g_assert (priv->formats != NULL);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_drag_context_get_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GdkDragContext *context = GDK_DRAG_CONTEXT (gobject);
|
||||
GdkDragContextPrivate *priv = gdk_drag_context_get_instance_private (context);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_CONTENT:
|
||||
g_value_set_object (value, context->content);
|
||||
break;
|
||||
|
||||
case PROP_DEVICE:
|
||||
g_value_set_object (value, priv->device);
|
||||
break;
|
||||
|
||||
case PROP_DISPLAY:
|
||||
g_value_set_object (value, priv->display);
|
||||
break;
|
||||
|
||||
case PROP_FORMATS:
|
||||
g_value_set_boxed (value, priv->formats);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_drag_context_finalize (GObject *object)
|
||||
{
|
||||
GdkDragContext *context = GDK_DRAG_CONTEXT (object);
|
||||
GdkDragContextPrivate *priv = gdk_drag_context_get_instance_private (context);
|
||||
|
||||
contexts = g_list_remove (contexts, context);
|
||||
|
||||
g_clear_object (&context->content);
|
||||
g_clear_pointer (&priv->formats, gdk_content_formats_unref);
|
||||
|
||||
if (context->source_surface)
|
||||
g_object_unref (context->source_surface);
|
||||
|
||||
if (context->dest_surface)
|
||||
g_object_unref (context->dest_surface);
|
||||
|
||||
G_OBJECT_CLASS (gdk_drag_context_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_drag_context_read_local_async (GdkDragContext *context,
|
||||
GdkContentFormats *formats,
|
||||
int io_priority,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
GTask *task;
|
||||
|
||||
task = g_task_new (context, cancellable, callback, user_data);
|
||||
g_task_set_priority (task, io_priority);
|
||||
g_task_set_source_tag (task, gdk_drag_context_read_local_async);
|
||||
|
||||
g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
|
||||
_("Reading not implemented."));
|
||||
g_object_unref (task);
|
||||
}
|
||||
|
||||
static GInputStream *
|
||||
gdk_drag_context_read_local_finish (GdkDragContext *context,
|
||||
const char **out_mime_type,
|
||||
GAsyncResult *result,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (g_task_is_valid (result, context), NULL);
|
||||
g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) == gdk_drag_context_read_local_async, NULL);
|
||||
|
||||
if (out_mime_type)
|
||||
*out_mime_type = g_task_get_task_data (G_TASK (result));
|
||||
|
||||
return g_task_propagate_pointer (G_TASK (result), error);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_drag_context_class_init (GdkDragContextClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->get_property = gdk_drag_context_get_property;
|
||||
object_class->set_property = gdk_drag_context_set_property;
|
||||
object_class->finalize = gdk_drag_context_finalize;
|
||||
|
||||
/**
|
||||
* GdkDragContext:content:
|
||||
*
|
||||
* The #GdkContentProvider or %NULL if the context is not a source-side
|
||||
* context.
|
||||
*/
|
||||
properties[PROP_CONTENT] =
|
||||
g_param_spec_object ("content",
|
||||
"Content",
|
||||
"The content being dragged",
|
||||
GDK_TYPE_CONTENT_PROVIDER,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
/**
|
||||
* GdkDragContext:device:
|
||||
*
|
||||
* The #GdkDevice that is performing the drag.
|
||||
*/
|
||||
properties[PROP_DEVICE] =
|
||||
g_param_spec_object ("device",
|
||||
"Device",
|
||||
"The device performing the drag",
|
||||
GDK_TYPE_DEVICE,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
/**
|
||||
* GdkDragContext:display:
|
||||
*
|
||||
* The #GdkDisplay that the drag context belongs to.
|
||||
*/
|
||||
properties[PROP_DISPLAY] =
|
||||
g_param_spec_object ("display",
|
||||
"Display",
|
||||
"Display this drag belongs to",
|
||||
GDK_TYPE_DISPLAY,
|
||||
G_PARAM_READABLE |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
/**
|
||||
* GdkDragContext:formats:
|
||||
*
|
||||
* The possible formats that the context can provide its data in.
|
||||
*/
|
||||
properties[PROP_FORMATS] =
|
||||
g_param_spec_boxed ("formats",
|
||||
"Formats",
|
||||
"The possible formats for data",
|
||||
GDK_TYPE_CONTENT_FORMATS,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
/**
|
||||
* GdkDragContext::cancel:
|
||||
* @context: The object on which the signal is emitted
|
||||
* @reason: The reason the context was cancelled
|
||||
*
|
||||
* The drag and drop operation was cancelled.
|
||||
*/
|
||||
signals[CANCEL] =
|
||||
g_signal_new (g_intern_static_string ("cancel"),
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GdkDragContextClass, cancel),
|
||||
NULL, NULL,
|
||||
g_cclosure_marshal_VOID__ENUM,
|
||||
G_TYPE_NONE, 1, GDK_TYPE_DRAG_CANCEL_REASON);
|
||||
|
||||
/**
|
||||
* GdkDragContext::drop-performed:
|
||||
* @context: The object on which the signal is emitted
|
||||
* @time: the time at which the drop happened.
|
||||
*
|
||||
* The drag and drop operation was performed on an accepting client.
|
||||
*/
|
||||
signals[DROP_PERFORMED] =
|
||||
g_signal_new (g_intern_static_string ("drop-performed"),
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GdkDragContextClass, drop_performed),
|
||||
NULL, NULL,
|
||||
g_cclosure_marshal_VOID__INT,
|
||||
G_TYPE_NONE, 1, G_TYPE_INT);
|
||||
|
||||
/**
|
||||
* GdkDragContext::dnd-finished:
|
||||
* @context: The object on which the signal is emitted
|
||||
*
|
||||
* The drag and drop operation was finished, the drag destination
|
||||
* finished reading all data. The drag source can now free all
|
||||
* miscellaneous data.
|
||||
*/
|
||||
signals[DND_FINISHED] =
|
||||
g_signal_new (g_intern_static_string ("dnd-finished"),
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GdkDragContextClass, dnd_finished),
|
||||
NULL, NULL,
|
||||
g_cclosure_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
/**
|
||||
* GdkDragContext::action-changed:
|
||||
* @context: The object on which the signal is emitted
|
||||
* @action: The action currently chosen
|
||||
*
|
||||
* A new action is being chosen for the drag and drop operation.
|
||||
*/
|
||||
signals[ACTION_CHANGED] =
|
||||
g_signal_new (g_intern_static_string ("action-changed"),
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GdkDragContextClass, action_changed),
|
||||
NULL, NULL,
|
||||
g_cclosure_marshal_VOID__FLAGS,
|
||||
G_TYPE_NONE, 1, GDK_TYPE_DRAG_ACTION);
|
||||
|
||||
g_object_class_install_properties (object_class, N_PROPERTIES, properties);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_drag_status:
|
||||
* @context: a #GdkDragContext
|
||||
* @action: the selected action which will be taken when a drop happens,
|
||||
* or 0 to indicate that a drop will not be accepted
|
||||
* @time_: the timestamp for this operation
|
||||
*
|
||||
* Selects one of the actions offered by the drag source.
|
||||
*
|
||||
* This function is called by the drag destination in response to
|
||||
* gdk_drag_motion() called by the drag source.
|
||||
*/
|
||||
void
|
||||
gdk_drag_status (GdkDragContext *context,
|
||||
GdkDragAction action,
|
||||
guint32 time_)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_DRAG_CONTEXT (context));
|
||||
|
||||
GDK_DRAG_CONTEXT_GET_CLASS (context)->drag_status (context, action, time_);
|
||||
}
|
||||
|
||||
/*
|
||||
* gdk_drag_abort:
|
||||
* @context: a #GdkDragContext
|
||||
* @time_: the timestamp for this operation
|
||||
*
|
||||
* Aborts a drag without dropping.
|
||||
*
|
||||
* This function is called by the drag source.
|
||||
*/
|
||||
void
|
||||
gdk_drag_abort (GdkDragContext *context,
|
||||
guint32 time_)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_DRAG_CONTEXT (context));
|
||||
|
||||
GDK_DRAG_CONTEXT_GET_CLASS (context)->drag_abort (context, time_);
|
||||
}
|
||||
|
||||
/*
|
||||
* gdk_drag_drop:
|
||||
* @context: a #GdkDragContext
|
||||
* @time_: the timestamp for this operation
|
||||
*
|
||||
* Drops on the current destination.
|
||||
*
|
||||
* This function is called by the drag source.
|
||||
*/
|
||||
void
|
||||
gdk_drag_drop (GdkDragContext *context,
|
||||
guint32 time_)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_DRAG_CONTEXT (context));
|
||||
|
||||
GDK_DRAG_CONTEXT_GET_CLASS (context)->drag_drop (context, time_);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_drop_finish:
|
||||
* @context: a #GdkDragContext
|
||||
* @success: %TRUE if the data was successfully received
|
||||
* @time_: the timestamp for this operation
|
||||
*
|
||||
* Ends the drag operation after a drop.
|
||||
*
|
||||
* This function is called by the drag destination.
|
||||
*/
|
||||
void
|
||||
gdk_drop_finish (GdkDragContext *context,
|
||||
gboolean success,
|
||||
guint32 time_)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_DRAG_CONTEXT (context));
|
||||
|
||||
GDK_DRAG_CONTEXT_GET_CLASS (context)->drop_finish (context, success, time_);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_drag_context_write_done (GObject *content,
|
||||
GAsyncResult *result,
|
||||
gpointer task)
|
||||
{
|
||||
GError *error = NULL;
|
||||
|
||||
if (gdk_content_provider_write_mime_type_finish (GDK_CONTENT_PROVIDER (content), result, &error))
|
||||
g_task_return_boolean (task, TRUE);
|
||||
else
|
||||
g_task_return_error (task, error);
|
||||
|
||||
g_object_unref (task);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_drag_context_write_serialize_done (GObject *content,
|
||||
GAsyncResult *result,
|
||||
gpointer task)
|
||||
{
|
||||
GError *error = NULL;
|
||||
|
||||
if (gdk_content_serialize_finish (result, &error))
|
||||
g_task_return_boolean (task, TRUE);
|
||||
else
|
||||
g_task_return_error (task, error);
|
||||
|
||||
g_object_unref (task);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_drag_context_write_async (GdkDragContext *context,
|
||||
const char *mime_type,
|
||||
GOutputStream *stream,
|
||||
int io_priority,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
GdkContentFormats *formats, *mime_formats;
|
||||
GTask *task;
|
||||
GType gtype;
|
||||
|
||||
g_return_if_fail (GDK_IS_DRAG_CONTEXT (context));
|
||||
g_return_if_fail (context->content);
|
||||
g_return_if_fail (mime_type != NULL);
|
||||
g_return_if_fail (mime_type == g_intern_string (mime_type));
|
||||
g_return_if_fail (G_IS_OUTPUT_STREAM (stream));
|
||||
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
|
||||
g_return_if_fail (callback != NULL);
|
||||
|
||||
task = g_task_new (context, cancellable, callback, user_data);
|
||||
g_task_set_priority (task, io_priority);
|
||||
g_task_set_source_tag (task, gdk_drag_context_write_async);
|
||||
|
||||
formats = gdk_content_provider_ref_formats (context->content);
|
||||
if (gdk_content_formats_contain_mime_type (formats, mime_type))
|
||||
{
|
||||
gdk_content_provider_write_mime_type_async (context->content,
|
||||
mime_type,
|
||||
stream,
|
||||
io_priority,
|
||||
cancellable,
|
||||
gdk_drag_context_write_done,
|
||||
task);
|
||||
gdk_content_formats_unref (formats);
|
||||
return;
|
||||
}
|
||||
|
||||
mime_formats = gdk_content_formats_new ((const gchar *[2]) { mime_type, NULL }, 1);
|
||||
mime_formats = gdk_content_formats_union_serialize_gtypes (mime_formats);
|
||||
gtype = gdk_content_formats_match_gtype (formats, mime_formats);
|
||||
if (gtype != G_TYPE_INVALID)
|
||||
{
|
||||
GValue value = G_VALUE_INIT;
|
||||
GError *error = NULL;
|
||||
|
||||
g_assert (gtype != G_TYPE_INVALID);
|
||||
|
||||
g_value_init (&value, gtype);
|
||||
if (gdk_content_provider_get_value (context->content, &value, &error))
|
||||
{
|
||||
gdk_content_serialize_async (stream,
|
||||
mime_type,
|
||||
&value,
|
||||
io_priority,
|
||||
cancellable,
|
||||
gdk_drag_context_write_serialize_done,
|
||||
g_object_ref (task));
|
||||
}
|
||||
else
|
||||
{
|
||||
g_task_return_error (task, error);
|
||||
}
|
||||
|
||||
g_value_unset (&value);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
|
||||
_("No compatible formats to transfer clipboard contents."));
|
||||
}
|
||||
|
||||
gdk_content_formats_unref (mime_formats);
|
||||
gdk_content_formats_unref (formats);
|
||||
g_object_unref (task);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gdk_drag_context_write_finish (GdkDragContext *context,
|
||||
GAsyncResult *result,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (g_task_is_valid (result, context), FALSE);
|
||||
g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) == gdk_drag_context_write_async, FALSE);
|
||||
|
||||
return g_task_propagate_boolean (G_TASK (result), error);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_drop_read_async:
|
||||
* @context: a #GdkDragContext
|
||||
* @mime_types: (array zero-terminated=1) (element-type utf8): pointer to an array of mime types
|
||||
* @io_priority: the io priority for the read operation
|
||||
* @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore
|
||||
* @callback: (scope async): a #GAsyncReadyCallback to call when the request is satisfied
|
||||
* @user_data: (closure): the data to pass to @callback
|
||||
*
|
||||
* Asynchronously read the dropped data from a DND context
|
||||
* in a format that complies with one of the mime types.
|
||||
*/
|
||||
void
|
||||
gdk_drop_read_async (GdkDragContext *context,
|
||||
const char **mime_types,
|
||||
int io_priority,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
GdkContentFormats *formats;
|
||||
|
||||
g_return_if_fail (GDK_IS_DRAG_CONTEXT (context));
|
||||
g_return_if_fail (mime_types != NULL && mime_types[0] != NULL);
|
||||
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
|
||||
g_return_if_fail (callback != NULL);
|
||||
|
||||
formats = gdk_content_formats_new (mime_types, g_strv_length ((char **) mime_types));
|
||||
|
||||
GDK_DRAG_CONTEXT_GET_CLASS (context)->read_async (context,
|
||||
formats,
|
||||
io_priority,
|
||||
cancellable,
|
||||
callback,
|
||||
user_data);
|
||||
|
||||
gdk_content_formats_unref (formats);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_drop_read_finish:
|
||||
* @context: a #GdkDragContext
|
||||
* @out_mime_type: (out) (type utf8): return location for the used mime type
|
||||
* @result: a #GAsyncResult
|
||||
* @error: (allow-none): location to store error information on failure, or %NULL
|
||||
*
|
||||
* Finishes an async drop read operation, see gdk_drop_read_async().
|
||||
*
|
||||
* Returns: (nullable) (transfer full): the #GInputStream, or %NULL
|
||||
*/
|
||||
GInputStream *
|
||||
gdk_drop_read_finish (GdkDragContext *context,
|
||||
const char **out_mime_type,
|
||||
GAsyncResult *result,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_DRAG_CONTEXT (context), NULL);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
||||
|
||||
if (g_async_result_is_tagged (result, gdk_drag_context_read_local_async))
|
||||
{
|
||||
return gdk_drag_context_read_local_finish (context, out_mime_type, result, error);
|
||||
}
|
||||
else
|
||||
{
|
||||
return GDK_DRAG_CONTEXT_GET_CLASS (context)->read_finish (context, out_mime_type, result, error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_drag_context_get_drag_surface:
|
||||
* @context: a #GdkDragContext
|
||||
*
|
||||
* Returns the surface on which the drag icon should be rendered
|
||||
* during the drag operation. Note that the surface may not be
|
||||
* available until the drag operation has begun. GDK will move
|
||||
* the surface in accordance with the ongoing drag operation.
|
||||
* The surface is owned by @context and will be destroyed when
|
||||
* the drag operation is over.
|
||||
*
|
||||
* Returns: (nullable) (transfer none): the drag surface, or %NULL
|
||||
*/
|
||||
GdkSurface *
|
||||
gdk_drag_context_get_drag_surface (GdkDragContext *context)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_DRAG_CONTEXT (context), NULL);
|
||||
|
||||
if (GDK_DRAG_CONTEXT_GET_CLASS (context)->get_drag_surface)
|
||||
return GDK_DRAG_CONTEXT_GET_CLASS (context)->get_drag_surface (context);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_drag_context_set_hotspot:
|
||||
* @context: a #GdkDragContext
|
||||
* @hot_x: x coordinate of the drag surface hotspot
|
||||
* @hot_y: y coordinate of the drag surface hotspot
|
||||
*
|
||||
* Sets the position of the drag surface that will be kept
|
||||
* under the cursor hotspot. Initially, the hotspot is at the
|
||||
* top left corner of the drag surface.
|
||||
*/
|
||||
void
|
||||
gdk_drag_context_set_hotspot (GdkDragContext *context,
|
||||
gint hot_x,
|
||||
gint hot_y)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_DRAG_CONTEXT (context));
|
||||
|
||||
if (GDK_DRAG_CONTEXT_GET_CLASS (context)->set_hotspot)
|
||||
GDK_DRAG_CONTEXT_GET_CLASS (context)->set_hotspot (context, hot_x, hot_y);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_drag_drop_done:
|
||||
* @context: a #GdkDragContext
|
||||
* @success: whether the drag was ultimatively successful
|
||||
*
|
||||
* Inform GDK if the drop ended successfully. Passing %FALSE
|
||||
* for @success may trigger a drag cancellation animation.
|
||||
*
|
||||
* This function is called by the drag source, and should
|
||||
* be the last call before dropping the reference to the
|
||||
* @context.
|
||||
*
|
||||
* The #GdkDragContext will only take the first gdk_drag_drop_done()
|
||||
* call as effective, if this function is called multiple times,
|
||||
* all subsequent calls will be ignored.
|
||||
*/
|
||||
void
|
||||
gdk_drag_drop_done (GdkDragContext *context,
|
||||
gboolean success)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_DRAG_CONTEXT (context));
|
||||
|
||||
if (context->drop_done)
|
||||
return;
|
||||
|
||||
context->drop_done = TRUE;
|
||||
|
||||
if (GDK_DRAG_CONTEXT_GET_CLASS (context)->drop_done)
|
||||
GDK_DRAG_CONTEXT_GET_CLASS (context)->drop_done (context, success);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_drag_context_set_cursor (GdkDragContext *context,
|
||||
GdkCursor *cursor)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_DRAG_CONTEXT (context));
|
||||
|
||||
if (GDK_DRAG_CONTEXT_GET_CLASS (context)->set_cursor)
|
||||
GDK_DRAG_CONTEXT_GET_CLASS (context)->set_cursor (context, cursor);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_drag_context_cancel (GdkDragContext *context,
|
||||
GdkDragCancelReason reason)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_DRAG_CONTEXT (context));
|
||||
|
||||
g_signal_emit (context, signals[CANCEL], 0, reason);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gdk_drag_context_handle_source_event (GdkEvent *event)
|
||||
{
|
||||
GdkDragContext *context;
|
||||
GList *l;
|
||||
|
||||
for (l = contexts; l; l = l->next)
|
||||
{
|
||||
context = l->data;
|
||||
|
||||
if (!context->is_source)
|
||||
continue;
|
||||
|
||||
if (!GDK_DRAG_CONTEXT_GET_CLASS (context)->handle_event)
|
||||
continue;
|
||||
|
||||
if (GDK_DRAG_CONTEXT_GET_CLASS (context)->handle_event (context, event))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
GdkCursor *
|
||||
gdk_drag_get_cursor (GdkDragContext *context,
|
||||
GdkDragAction action)
|
||||
{
|
||||
gint i;
|
||||
|
||||
for (i = 0 ; i < G_N_ELEMENTS (drag_cursors) - 1; i++)
|
||||
if (drag_cursors[i].action == action)
|
||||
break;
|
||||
|
||||
if (drag_cursors[i].cursor == NULL)
|
||||
drag_cursors[i].cursor = gdk_cursor_new_from_name (drag_cursors[i].name, NULL);
|
||||
|
||||
return drag_cursors[i].cursor;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_drag_context_commit_drag_status (GdkDragContext *context)
|
||||
{
|
||||
GdkDragContextClass *context_class;
|
||||
|
||||
g_return_if_fail (GDK_IS_DRAG_CONTEXT (context));
|
||||
g_return_if_fail (!context->is_source);
|
||||
|
||||
context_class = GDK_DRAG_CONTEXT_GET_CLASS (context);
|
||||
|
||||
if (context_class->commit_drag_status)
|
||||
context_class->commit_drag_status (context);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gdk_drag_context_handle_dest_event (GdkEvent *event)
|
||||
{
|
||||
GdkDragContext *context = NULL;
|
||||
|
||||
switch ((guint) event->any.type)
|
||||
{
|
||||
case GDK_DRAG_MOTION:
|
||||
case GDK_DROP_START:
|
||||
context = event->dnd.context;
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!context)
|
||||
return FALSE;
|
||||
|
||||
gdk_drag_context_commit_drag_status (context);
|
||||
return TRUE;;
|
||||
}
|
||||
-152
@@ -1,152 +0,0 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
|
||||
* file for a list of people on the GTK+ Team. See the ChangeLog
|
||||
* files for a list of changes. These files are distributed with
|
||||
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
|
||||
*/
|
||||
|
||||
#ifndef __GDK_DND_H__
|
||||
#define __GDK_DND_H__
|
||||
|
||||
#if !defined (__GDK_H_INSIDE__) && !defined (GDK_COMPILATION)
|
||||
#error "Only <gdk/gdk.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <gdk/gdktypes.h>
|
||||
#include <gdk/gdkdevice.h>
|
||||
#include <gdk/gdkevents.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GDK_TYPE_DRAG_CONTEXT (gdk_drag_context_get_type ())
|
||||
#define GDK_DRAG_CONTEXT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_DRAG_CONTEXT, GdkDragContext))
|
||||
#define GDK_IS_DRAG_CONTEXT(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_DRAG_CONTEXT))
|
||||
|
||||
/**
|
||||
* GdkDragAction:
|
||||
* @GDK_ACTION_DEFAULT: Means nothing, and should not be used.
|
||||
* @GDK_ACTION_COPY: Copy the data.
|
||||
* @GDK_ACTION_MOVE: Move the data, i.e. first copy it, then delete
|
||||
* it from the source using the DELETE target of the X selection protocol.
|
||||
* @GDK_ACTION_LINK: Add a link to the data. Note that this is only
|
||||
* useful if source and destination agree on what it means.
|
||||
* @GDK_ACTION_PRIVATE: Special action which tells the source that the
|
||||
* destination will do something that the source doesn’t understand.
|
||||
* @GDK_ACTION_ASK: Ask the user what to do with the data.
|
||||
*
|
||||
* Used in #GdkDragContext to indicate what the destination
|
||||
* should do with the dropped data.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
GDK_ACTION_DEFAULT = 1 << 0,
|
||||
GDK_ACTION_COPY = 1 << 1,
|
||||
GDK_ACTION_MOVE = 1 << 2,
|
||||
GDK_ACTION_LINK = 1 << 3,
|
||||
GDK_ACTION_PRIVATE = 1 << 4,
|
||||
GDK_ACTION_ASK = 1 << 5
|
||||
} GdkDragAction;
|
||||
|
||||
/**
|
||||
* GdkDragCancelReason:
|
||||
* @GDK_DRAG_CANCEL_NO_TARGET: There is no suitable drop target.
|
||||
* @GDK_DRAG_CANCEL_USER_CANCELLED: Drag cancelled by the user
|
||||
* @GDK_DRAG_CANCEL_ERROR: Unspecified error.
|
||||
*
|
||||
* Used in #GdkDragContext to the reason of a cancelled DND operation.
|
||||
*
|
||||
* Since: 3.20
|
||||
*/
|
||||
typedef enum {
|
||||
GDK_DRAG_CANCEL_NO_TARGET,
|
||||
GDK_DRAG_CANCEL_USER_CANCELLED,
|
||||
GDK_DRAG_CANCEL_ERROR
|
||||
} GdkDragCancelReason;
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GType gdk_drag_context_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkDisplay * gdk_drag_context_get_display (GdkDragContext *context);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkDevice * gdk_drag_context_get_device (GdkDragContext *context);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkContentFormats *gdk_drag_context_get_formats (GdkDragContext *context);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkDragAction gdk_drag_context_get_actions (GdkDragContext *context);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkDragAction gdk_drag_context_get_suggested_action (GdkDragContext *context);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkDragAction gdk_drag_context_get_selected_action (GdkDragContext *context);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkSurface *gdk_drag_context_get_source_surface (GdkDragContext *context);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkSurface *gdk_drag_context_get_dest_surface (GdkDragContext *context);
|
||||
|
||||
/* Destination side */
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_drag_status (GdkDragContext *context,
|
||||
GdkDragAction action,
|
||||
guint32 time_);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_drop_finish (GdkDragContext *context,
|
||||
gboolean success,
|
||||
guint32 time_);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_drop_read_async (GdkDragContext *context,
|
||||
const char **mime_types,
|
||||
int io_priority,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GInputStream * gdk_drop_read_finish (GdkDragContext *context,
|
||||
const char **out_mime_type,
|
||||
GAsyncResult *result,
|
||||
GError **error);
|
||||
|
||||
/* Source side */
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkDragContext * gdk_drag_begin (GdkSurface *surface,
|
||||
GdkDevice *device,
|
||||
GdkContentProvider *content,
|
||||
GdkDragAction actions,
|
||||
gint dx,
|
||||
gint dy);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_drag_drop_done (GdkDragContext *context,
|
||||
gboolean success);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkSurface *gdk_drag_context_get_drag_surface (GdkDragContext *context);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_drag_context_set_hotspot (GdkDragContext *context,
|
||||
gint hot_x,
|
||||
gint hot_y);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_DND_H__ */
|
||||
@@ -1,124 +0,0 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2010, Red Hat, Inc
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GDK_DND_PRIVATE_H__
|
||||
#define __GDK_DND_PRIVATE_H__
|
||||
|
||||
#include "gdkdnd.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
||||
#define GDK_DRAG_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_DRAG_CONTEXT, GdkDragContextClass))
|
||||
#define GDK_IS_DRAG_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_DRAG_CONTEXT))
|
||||
#define GDK_DRAG_CONTEXT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_DRAG_CONTEXT, GdkDragContextClass))
|
||||
|
||||
typedef struct _GdkDragContextClass GdkDragContextClass;
|
||||
|
||||
|
||||
struct _GdkDragContextClass {
|
||||
GObjectClass parent_class;
|
||||
|
||||
void (*drag_status) (GdkDragContext *context,
|
||||
GdkDragAction action,
|
||||
guint32 time_);
|
||||
void (*drag_abort) (GdkDragContext *context,
|
||||
guint32 time_);
|
||||
void (*drag_drop) (GdkDragContext *context,
|
||||
guint32 time_);
|
||||
void (*drop_finish) (GdkDragContext *context,
|
||||
gboolean success,
|
||||
guint32 time_);
|
||||
void (* read_async) (GdkDragContext *context,
|
||||
GdkContentFormats *formats,
|
||||
int io_priority,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
GInputStream * (* read_finish) (GdkDragContext *context,
|
||||
const char **out_mime_type,
|
||||
GAsyncResult *result,
|
||||
GError **error);
|
||||
GdkSurface* (*get_drag_surface) (GdkDragContext *context);
|
||||
void (*set_hotspot) (GdkDragContext *context,
|
||||
gint hot_x,
|
||||
gint hot_y);
|
||||
void (*drop_done) (GdkDragContext *context,
|
||||
gboolean success);
|
||||
|
||||
void (*set_cursor) (GdkDragContext *context,
|
||||
GdkCursor *cursor);
|
||||
void (*cancel) (GdkDragContext *context,
|
||||
GdkDragCancelReason reason);
|
||||
void (*drop_performed) (GdkDragContext *context,
|
||||
guint32 time);
|
||||
void (*dnd_finished) (GdkDragContext *context);
|
||||
|
||||
gboolean (*handle_event) (GdkDragContext *context,
|
||||
const GdkEvent *event);
|
||||
void (*action_changed) (GdkDragContext *context,
|
||||
GdkDragAction action);
|
||||
|
||||
void (*commit_drag_status) (GdkDragContext *context);
|
||||
};
|
||||
|
||||
struct _GdkDragContext {
|
||||
GObject parent_instance;
|
||||
|
||||
/*< private >*/
|
||||
gboolean is_source;
|
||||
GdkSurface *source_surface;
|
||||
GdkSurface *dest_surface;
|
||||
GdkSurface *drag_surface;
|
||||
|
||||
GdkContentProvider *content;
|
||||
GdkDragAction actions;
|
||||
GdkDragAction suggested_action;
|
||||
GdkDragAction action;
|
||||
|
||||
guint drop_done : 1; /* Whether gdk_drag_drop_done() was performed */
|
||||
};
|
||||
|
||||
void gdk_drag_context_set_cursor (GdkDragContext *context,
|
||||
GdkCursor *cursor);
|
||||
void gdk_drag_context_cancel (GdkDragContext *context,
|
||||
GdkDragCancelReason reason);
|
||||
gboolean gdk_drag_context_handle_source_event (GdkEvent *event);
|
||||
gboolean gdk_drag_context_handle_dest_event (GdkEvent *event);
|
||||
GdkCursor * gdk_drag_get_cursor (GdkDragContext *context,
|
||||
GdkDragAction action);
|
||||
|
||||
void gdk_drag_abort (GdkDragContext *context,
|
||||
guint32 time_);
|
||||
void gdk_drag_drop (GdkDragContext *context,
|
||||
guint32 time_);
|
||||
|
||||
void gdk_drag_context_write_async (GdkDragContext *context,
|
||||
const char *mime_type,
|
||||
GOutputStream *stream,
|
||||
int io_priority,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
gboolean gdk_drag_context_write_finish (GdkDragContext *context,
|
||||
GAsyncResult *result,
|
||||
GError **error);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif
|
||||
+792
@@ -0,0 +1,792 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 1995-1999 Peter Mattis, Spencer Kimball and Josh MacDonald
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
|
||||
* file for a list of people on the GTK+ Team. See the ChangeLog
|
||||
* files for a list of changes. These files are distributed with
|
||||
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gdkdragprivate.h"
|
||||
#include "gdkdisplay.h"
|
||||
#include "gdksurface.h"
|
||||
#include "gdkintl.h"
|
||||
#include "gdkcontentformats.h"
|
||||
#include "gdkcontentprovider.h"
|
||||
#include "gdkcontentserializer.h"
|
||||
#include "gdkcursor.h"
|
||||
#include "gdkenumtypes.h"
|
||||
#include "gdkeventsprivate.h"
|
||||
|
||||
static struct {
|
||||
GdkDragAction action;
|
||||
const gchar *name;
|
||||
GdkCursor *cursor;
|
||||
} drag_cursors[] = {
|
||||
{ GDK_ACTION_ASK, "dnd-ask", NULL },
|
||||
{ GDK_ACTION_COPY, "dnd-copy", NULL },
|
||||
{ GDK_ACTION_MOVE, "dnd-move", NULL },
|
||||
{ GDK_ACTION_LINK, "dnd-link", NULL },
|
||||
{ 0, "dnd-none", NULL },
|
||||
};
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_CONTENT,
|
||||
PROP_DEVICE,
|
||||
PROP_DISPLAY,
|
||||
PROP_FORMATS,
|
||||
PROP_SELECTED_ACTION,
|
||||
PROP_ACTIONS,
|
||||
PROP_SURFACE,
|
||||
N_PROPERTIES
|
||||
};
|
||||
|
||||
enum {
|
||||
CANCEL,
|
||||
DROP_PERFORMED,
|
||||
DND_FINISHED,
|
||||
N_SIGNALS
|
||||
};
|
||||
|
||||
typedef struct _GdkDragPrivate GdkDragPrivate;
|
||||
|
||||
struct _GdkDragPrivate {
|
||||
GdkSurface *surface;
|
||||
|
||||
GdkDisplay *display;
|
||||
GdkDevice *device;
|
||||
GdkContentFormats *formats;
|
||||
GdkContentProvider *content;
|
||||
|
||||
GdkDragAction actions;
|
||||
GdkDragAction selected_action;
|
||||
|
||||
guint drop_done : 1; /* Whether gdk_drag_drop_done() was performed */
|
||||
};
|
||||
|
||||
static GParamSpec *properties[N_PROPERTIES] = { NULL, };
|
||||
static guint signals[N_SIGNALS] = { 0 };
|
||||
static GList *drags = NULL;
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GdkDrag, gdk_drag, G_TYPE_OBJECT)
|
||||
|
||||
/**
|
||||
* SECTION:dnd
|
||||
* @title: Drag And Drop
|
||||
* @short_description: Functions for controlling drag and drop handling
|
||||
*
|
||||
* These functions provide a low level interface for drag and drop.
|
||||
*
|
||||
* The GdkDrag object represents the source side of an ongoing DND operation.
|
||||
* It is created when a drag is started, and stays alive for duration of
|
||||
* the DND operation.
|
||||
*
|
||||
* The GdkDrop object represents the target side of an ongoing DND operation.
|
||||
*
|
||||
* GTK+ provides a higher level abstraction based on top of these functions,
|
||||
* and so they are not normally needed in GTK+ applications. See the
|
||||
* [Drag and Drop][gtk4-Drag-and-Drop] section of the GTK+ documentation
|
||||
* for more information.
|
||||
*/
|
||||
|
||||
/**
|
||||
* GdkDrag:
|
||||
*
|
||||
* The GdkDrag struct contains only private fields and
|
||||
* should not be accessed directly.
|
||||
*/
|
||||
|
||||
/**
|
||||
* gdk_drag_get_display:
|
||||
* @drag: a #GdkDrag
|
||||
*
|
||||
* Gets the #GdkDisplay that the drag object was created for.
|
||||
*
|
||||
* Returns: (transfer none): a #GdkDisplay
|
||||
**/
|
||||
GdkDisplay *
|
||||
gdk_drag_get_display (GdkDrag *drag)
|
||||
{
|
||||
GdkDragPrivate *priv = gdk_drag_get_instance_private (drag);
|
||||
|
||||
g_return_val_if_fail (GDK_IS_DRAG (drag), NULL);
|
||||
|
||||
return priv->display;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_drag_get_formats:
|
||||
* @drag: a #GdkDrag
|
||||
*
|
||||
* Retrieves the formats supported by this GdkDrag object.
|
||||
*
|
||||
* Returns: (transfer none): a #GdkContentFormats
|
||||
**/
|
||||
GdkContentFormats *
|
||||
gdk_drag_get_formats (GdkDrag *drag)
|
||||
{
|
||||
GdkDragPrivate *priv = gdk_drag_get_instance_private (drag);
|
||||
|
||||
g_return_val_if_fail (GDK_IS_DRAG (drag), NULL);
|
||||
|
||||
return priv->formats;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_drag_get_actions:
|
||||
* @drag: a #GdkDrag
|
||||
*
|
||||
* Determines the bitmask of possible actions proposed by the source.
|
||||
*
|
||||
* Returns: the #GdkDragAction flags
|
||||
**/
|
||||
GdkDragAction
|
||||
gdk_drag_get_actions (GdkDrag *drag)
|
||||
{
|
||||
GdkDragPrivate *priv = gdk_drag_get_instance_private (drag);
|
||||
|
||||
g_return_val_if_fail (GDK_IS_DRAG (drag), 0);
|
||||
|
||||
return priv->actions;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_drag_get_selected_action:
|
||||
* @drag: a #GdkDrag
|
||||
*
|
||||
* Determines the action chosen by the drag destination.
|
||||
*
|
||||
* Returns: a #GdkDragAction value
|
||||
**/
|
||||
GdkDragAction
|
||||
gdk_drag_get_selected_action (GdkDrag *drag)
|
||||
{
|
||||
GdkDragPrivate *priv = gdk_drag_get_instance_private (drag);
|
||||
|
||||
g_return_val_if_fail (GDK_IS_DRAG (drag), 0);
|
||||
|
||||
return priv->selected_action;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_drag_get_device:
|
||||
* @drag: a #GdkDrag
|
||||
*
|
||||
* Returns the #GdkDevice associated to the GdkDrag object.
|
||||
*
|
||||
* Returns: (transfer none): The #GdkDevice associated to @drag.
|
||||
**/
|
||||
GdkDevice *
|
||||
gdk_drag_get_device (GdkDrag *drag)
|
||||
{
|
||||
GdkDragPrivate *priv = gdk_drag_get_instance_private (drag);
|
||||
|
||||
g_return_val_if_fail (GDK_IS_DRAG (drag), NULL);
|
||||
|
||||
return priv->device;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_drag_init (GdkDrag *drag)
|
||||
{
|
||||
drags = g_list_prepend (drags, drag);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_drag_set_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GdkDrag *drag = GDK_DRAG (gobject);
|
||||
GdkDragPrivate *priv = gdk_drag_get_instance_private (drag);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_CONTENT:
|
||||
priv->content = g_value_dup_object (value);
|
||||
if (priv->content)
|
||||
{
|
||||
g_assert (priv->formats == NULL);
|
||||
priv->formats = gdk_content_provider_ref_formats (priv->content);
|
||||
}
|
||||
break;
|
||||
|
||||
case PROP_DEVICE:
|
||||
priv->device = g_value_dup_object (value);
|
||||
g_assert (priv->device != NULL);
|
||||
priv->display = gdk_device_get_display (priv->device);
|
||||
break;
|
||||
|
||||
case PROP_FORMATS:
|
||||
if (priv->formats)
|
||||
{
|
||||
GdkContentFormats *override = g_value_dup_boxed (value);
|
||||
if (override)
|
||||
{
|
||||
gdk_content_formats_unref (priv->formats);
|
||||
priv->formats = override;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
priv->formats = g_value_dup_boxed (value);
|
||||
g_assert (priv->formats != NULL);
|
||||
}
|
||||
break;
|
||||
|
||||
case PROP_SELECTED_ACTION:
|
||||
{
|
||||
GdkDragAction action = g_value_get_flags (value);
|
||||
gdk_drag_set_selected_action (drag, action);
|
||||
}
|
||||
break;
|
||||
|
||||
case PROP_ACTIONS:
|
||||
{
|
||||
GdkDragAction actions = g_value_get_flags (value);
|
||||
gdk_drag_set_actions (drag, actions);
|
||||
}
|
||||
break;
|
||||
|
||||
case PROP_SURFACE:
|
||||
priv->surface = g_value_dup_object (value);
|
||||
g_assert (priv->surface != NULL);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_drag_get_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GdkDrag *drag = GDK_DRAG (gobject);
|
||||
GdkDragPrivate *priv = gdk_drag_get_instance_private (drag);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_CONTENT:
|
||||
g_value_set_object (value, priv->content);
|
||||
break;
|
||||
|
||||
case PROP_DEVICE:
|
||||
g_value_set_object (value, priv->device);
|
||||
break;
|
||||
|
||||
case PROP_DISPLAY:
|
||||
g_value_set_object (value, priv->display);
|
||||
break;
|
||||
|
||||
case PROP_FORMATS:
|
||||
g_value_set_boxed (value, priv->formats);
|
||||
break;
|
||||
|
||||
case PROP_SELECTED_ACTION:
|
||||
g_value_set_flags (value, priv->selected_action);
|
||||
break;
|
||||
|
||||
case PROP_ACTIONS:
|
||||
g_value_set_flags (value, priv->actions);
|
||||
break;
|
||||
|
||||
case PROP_SURFACE:
|
||||
g_value_set_object (value, priv->surface);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_drag_finalize (GObject *object)
|
||||
{
|
||||
GdkDrag *drag = GDK_DRAG (object);
|
||||
GdkDragPrivate *priv = gdk_drag_get_instance_private (drag);
|
||||
|
||||
drags = g_list_remove (drags, drag);
|
||||
|
||||
g_clear_object (&priv->content);
|
||||
g_clear_pointer (&priv->formats, gdk_content_formats_unref);
|
||||
|
||||
g_clear_object (&priv->surface);
|
||||
|
||||
G_OBJECT_CLASS (gdk_drag_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_drag_class_init (GdkDragClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->get_property = gdk_drag_get_property;
|
||||
object_class->set_property = gdk_drag_set_property;
|
||||
object_class->finalize = gdk_drag_finalize;
|
||||
|
||||
/**
|
||||
* GdkDrag:content:
|
||||
*
|
||||
* The #GdkContentProvider.
|
||||
*/
|
||||
properties[PROP_CONTENT] =
|
||||
g_param_spec_object ("content",
|
||||
"Content",
|
||||
"The content being dragged",
|
||||
GDK_TYPE_CONTENT_PROVIDER,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
/**
|
||||
* GdkDrag:device:
|
||||
*
|
||||
* The #GdkDevice that is performing the drag.
|
||||
*/
|
||||
properties[PROP_DEVICE] =
|
||||
g_param_spec_object ("device",
|
||||
"Device",
|
||||
"The device performing the drag",
|
||||
GDK_TYPE_DEVICE,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
/**
|
||||
* GdkDrag:display:
|
||||
*
|
||||
* The #GdkDisplay that the drag belongs to.
|
||||
*/
|
||||
properties[PROP_DISPLAY] =
|
||||
g_param_spec_object ("display",
|
||||
"Display",
|
||||
"Display this drag belongs to",
|
||||
GDK_TYPE_DISPLAY,
|
||||
G_PARAM_READABLE |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
/**
|
||||
* GdkDrag:formats:
|
||||
*
|
||||
* The possible formats that the drag can provide its data in.
|
||||
*/
|
||||
properties[PROP_FORMATS] =
|
||||
g_param_spec_boxed ("formats",
|
||||
"Formats",
|
||||
"The possible formats for data",
|
||||
GDK_TYPE_CONTENT_FORMATS,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
properties[PROP_SELECTED_ACTION] =
|
||||
g_param_spec_flags ("selected-action",
|
||||
"Selected action",
|
||||
"The currently selected action",
|
||||
GDK_TYPE_DRAG_ACTION,
|
||||
0,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
properties[PROP_ACTIONS] =
|
||||
g_param_spec_flags ("actions",
|
||||
"Actions",
|
||||
"The possible actions",
|
||||
GDK_TYPE_DRAG_ACTION,
|
||||
0,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
properties[PROP_SURFACE] =
|
||||
g_param_spec_object ("surface",
|
||||
"Surface",
|
||||
"The surface where the drag originates",
|
||||
GDK_TYPE_SURFACE,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
/**
|
||||
* GdkDrag::cancel:
|
||||
* @drag: The object on which the signal is emitted
|
||||
* @reason: The reason the drag was cancelled
|
||||
*
|
||||
* The drag operation was cancelled.
|
||||
*/
|
||||
signals[CANCEL] =
|
||||
g_signal_new (g_intern_static_string ("cancel"),
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GdkDragClass, cancel),
|
||||
NULL, NULL,
|
||||
g_cclosure_marshal_VOID__ENUM,
|
||||
G_TYPE_NONE, 1, GDK_TYPE_DRAG_CANCEL_REASON);
|
||||
|
||||
/**
|
||||
* GdkDrag::drop-performed:
|
||||
* @drag: The object on which the signal is emitted
|
||||
*
|
||||
* The drag operation was performed on an accepting client.
|
||||
*/
|
||||
signals[DROP_PERFORMED] =
|
||||
g_signal_new (g_intern_static_string ("drop-performed"),
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GdkDragClass, drop_performed),
|
||||
NULL, NULL,
|
||||
g_cclosure_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
/**
|
||||
* GdkDrag::dnd-finished:
|
||||
* @drag: The object on which the signal is emitted
|
||||
*
|
||||
* The drag operation was finished, the destination
|
||||
* finished reading all data. The drag object can now
|
||||
* free all miscellaneous data.
|
||||
*/
|
||||
signals[DND_FINISHED] =
|
||||
g_signal_new (g_intern_static_string ("dnd-finished"),
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GdkDragClass, dnd_finished),
|
||||
NULL, NULL,
|
||||
g_cclosure_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
g_object_class_install_properties (object_class, N_PROPERTIES, properties);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_drag_write_done (GObject *content,
|
||||
GAsyncResult *result,
|
||||
gpointer task)
|
||||
{
|
||||
GError *error = NULL;
|
||||
|
||||
if (gdk_content_provider_write_mime_type_finish (GDK_CONTENT_PROVIDER (content), result, &error))
|
||||
g_task_return_boolean (task, TRUE);
|
||||
else
|
||||
g_task_return_error (task, error);
|
||||
|
||||
g_object_unref (task);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_drag_write_serialize_done (GObject *content,
|
||||
GAsyncResult *result,
|
||||
gpointer task)
|
||||
{
|
||||
GError *error = NULL;
|
||||
|
||||
if (gdk_content_serialize_finish (result, &error))
|
||||
g_task_return_boolean (task, TRUE);
|
||||
else
|
||||
g_task_return_error (task, error);
|
||||
|
||||
g_object_unref (task);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_drag_write_async (GdkDrag *drag,
|
||||
const char *mime_type,
|
||||
GOutputStream *stream,
|
||||
int io_priority,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
GdkDragPrivate *priv = gdk_drag_get_instance_private (drag);
|
||||
GdkContentFormats *formats, *mime_formats;
|
||||
GTask *task;
|
||||
GType gtype;
|
||||
|
||||
g_return_if_fail (GDK_IS_DRAG (drag));
|
||||
g_return_if_fail (priv->content);
|
||||
g_return_if_fail (mime_type != NULL);
|
||||
g_return_if_fail (mime_type == g_intern_string (mime_type));
|
||||
g_return_if_fail (G_IS_OUTPUT_STREAM (stream));
|
||||
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
|
||||
g_return_if_fail (callback != NULL);
|
||||
|
||||
task = g_task_new (drag, cancellable, callback, user_data);
|
||||
g_task_set_priority (task, io_priority);
|
||||
g_task_set_source_tag (task, gdk_drag_write_async);
|
||||
|
||||
formats = gdk_content_provider_ref_formats (priv->content);
|
||||
if (gdk_content_formats_contain_mime_type (formats, mime_type))
|
||||
{
|
||||
gdk_content_provider_write_mime_type_async (priv->content,
|
||||
mime_type,
|
||||
stream,
|
||||
io_priority,
|
||||
cancellable,
|
||||
gdk_drag_write_done,
|
||||
task);
|
||||
gdk_content_formats_unref (formats);
|
||||
return;
|
||||
}
|
||||
|
||||
mime_formats = gdk_content_formats_new ((const gchar *[2]) { mime_type, NULL }, 1);
|
||||
mime_formats = gdk_content_formats_union_serialize_gtypes (mime_formats);
|
||||
gtype = gdk_content_formats_match_gtype (formats, mime_formats);
|
||||
if (gtype != G_TYPE_INVALID)
|
||||
{
|
||||
GValue value = G_VALUE_INIT;
|
||||
GError *error = NULL;
|
||||
|
||||
g_assert (gtype != G_TYPE_INVALID);
|
||||
|
||||
g_value_init (&value, gtype);
|
||||
if (gdk_content_provider_get_value (priv->content, &value, &error))
|
||||
{
|
||||
gdk_content_serialize_async (stream,
|
||||
mime_type,
|
||||
&value,
|
||||
io_priority,
|
||||
cancellable,
|
||||
gdk_drag_write_serialize_done,
|
||||
g_object_ref (task));
|
||||
}
|
||||
else
|
||||
{
|
||||
g_task_return_error (task, error);
|
||||
}
|
||||
|
||||
g_value_unset (&value);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
|
||||
_("No compatible formats to transfer clipboard contents."));
|
||||
}
|
||||
|
||||
gdk_content_formats_unref (mime_formats);
|
||||
gdk_content_formats_unref (formats);
|
||||
g_object_unref (task);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gdk_drag_write_finish (GdkDrag *drag,
|
||||
GAsyncResult *result,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (g_task_is_valid (result, drag), FALSE);
|
||||
g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) == gdk_drag_write_async, FALSE);
|
||||
|
||||
return g_task_propagate_boolean (G_TASK (result), error);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_drag_set_actions (GdkDrag *drag,
|
||||
GdkDragAction actions)
|
||||
{
|
||||
GdkDragPrivate *priv = gdk_drag_get_instance_private (drag);
|
||||
|
||||
if (priv->actions == actions)
|
||||
return;
|
||||
|
||||
priv->actions = actions;
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (drag), properties[PROP_ACTIONS]);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_drag_set_selected_action (GdkDrag *drag,
|
||||
GdkDragAction action)
|
||||
{
|
||||
GdkDragPrivate *priv = gdk_drag_get_instance_private (drag);
|
||||
GdkCursor *cursor;
|
||||
|
||||
if (priv->selected_action == action)
|
||||
return;
|
||||
|
||||
priv->selected_action = action;
|
||||
|
||||
cursor = gdk_drag_get_cursor (drag, action);
|
||||
gdk_drag_set_cursor (drag, cursor);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (drag), properties[PROP_SELECTED_ACTION]);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_drag_get_drag_surface:
|
||||
* @drag: a #GdkDrag
|
||||
*
|
||||
* Returns the surface on which the drag icon should be rendered
|
||||
* during the drag operation. Note that the surface may not be
|
||||
* available until the drag operation has begun. GDK will move
|
||||
* the surface in accordance with the ongoing drag operation.
|
||||
* The surface is owned by @drag and will be destroyed when
|
||||
* the drag operation is over.
|
||||
*
|
||||
* Returns: (nullable) (transfer none): the drag surface, or %NULL
|
||||
*/
|
||||
GdkSurface *
|
||||
gdk_drag_get_drag_surface (GdkDrag *drag)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_DRAG (drag), NULL);
|
||||
|
||||
if (GDK_DRAG_GET_CLASS (drag)->get_drag_surface)
|
||||
return GDK_DRAG_GET_CLASS (drag)->get_drag_surface (drag);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_drag_set_hotspot:
|
||||
* @drag: a #GdkDrag
|
||||
* @hot_x: x coordinate of the drag surface hotspot
|
||||
* @hot_y: y coordinate of the drag surface hotspot
|
||||
*
|
||||
* Sets the position of the drag surface that will be kept
|
||||
* under the cursor hotspot. Initially, the hotspot is at the
|
||||
* top left corner of the drag surface.
|
||||
*/
|
||||
void
|
||||
gdk_drag_set_hotspot (GdkDrag *drag,
|
||||
gint hot_x,
|
||||
gint hot_y)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_DRAG (drag));
|
||||
|
||||
if (GDK_DRAG_GET_CLASS (drag)->set_hotspot)
|
||||
GDK_DRAG_GET_CLASS (drag)->set_hotspot (drag, hot_x, hot_y);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_drag_drop_done:
|
||||
* @drag: a #GdkDrag
|
||||
* @success: whether the drag was ultimatively successful
|
||||
*
|
||||
* Inform GDK if the drop ended successfully. Passing %FALSE
|
||||
* for @success may trigger a drag cancellation animation.
|
||||
*
|
||||
* This function is called by the drag source, and should
|
||||
* be the last call before dropping the reference to the
|
||||
* @drag.
|
||||
*
|
||||
* The #GdkDrag will only take the first gdk_drag_drop_done()
|
||||
* call as effective, if this function is called multiple times,
|
||||
* all subsequent calls will be ignored.
|
||||
*/
|
||||
void
|
||||
gdk_drag_drop_done (GdkDrag *drag,
|
||||
gboolean success)
|
||||
{
|
||||
GdkDragPrivate *priv = gdk_drag_get_instance_private (drag);
|
||||
|
||||
g_return_if_fail (GDK_IS_DRAG (drag));
|
||||
|
||||
if (priv->drop_done)
|
||||
return;
|
||||
|
||||
priv->drop_done = TRUE;
|
||||
|
||||
if (GDK_DRAG_GET_CLASS (drag)->drop_done)
|
||||
GDK_DRAG_GET_CLASS (drag)->drop_done (drag, success);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_drag_set_cursor (GdkDrag *drag,
|
||||
GdkCursor *cursor)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_DRAG (drag));
|
||||
|
||||
if (GDK_DRAG_GET_CLASS (drag)->set_cursor)
|
||||
GDK_DRAG_GET_CLASS (drag)->set_cursor (drag, cursor);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_drag_cancel (GdkDrag *drag,
|
||||
GdkDragCancelReason reason)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_DRAG (drag));
|
||||
|
||||
g_signal_emit (drag, signals[CANCEL], 0, reason);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gdk_drag_handle_source_event (GdkEvent *event)
|
||||
{
|
||||
GdkDrag *drag;
|
||||
GList *l;
|
||||
|
||||
for (l = drags; l; l = l->next)
|
||||
{
|
||||
drag = l->data;
|
||||
|
||||
if (!GDK_DRAG_GET_CLASS (drag)->handle_event)
|
||||
continue;
|
||||
|
||||
if (GDK_DRAG_GET_CLASS (drag)->handle_event (drag, event))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
GdkCursor *
|
||||
gdk_drag_get_cursor (GdkDrag *drag,
|
||||
GdkDragAction action)
|
||||
{
|
||||
gint i;
|
||||
|
||||
for (i = 0 ; i < G_N_ELEMENTS (drag_cursors) - 1; i++)
|
||||
if (drag_cursors[i].action == action)
|
||||
break;
|
||||
|
||||
if (drag_cursors[i].cursor == NULL)
|
||||
drag_cursors[i].cursor = gdk_cursor_new_from_name (drag_cursors[i].name, NULL);
|
||||
|
||||
return drag_cursors[i].cursor;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_drag_action_is_unique:
|
||||
* @action: a #GdkDragAction
|
||||
*
|
||||
* Checks if @action represents a single action or if it
|
||||
* includes multiple flags that can be selected from.
|
||||
*
|
||||
* When @action is 0 - ie no action was given, %TRUE
|
||||
* is returned.
|
||||
*
|
||||
* Returns: %TRUE if exactly one action was given
|
||||
**/
|
||||
gboolean
|
||||
gdk_drag_action_is_unique (GdkDragAction action)
|
||||
{
|
||||
return (action & (action - 1)) == 0;
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
|
||||
* file for a list of people on the GTK+ Team. See the ChangeLog
|
||||
* files for a list of changes. These files are distributed with
|
||||
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
|
||||
*/
|
||||
|
||||
#ifndef __GDK_DND_H__
|
||||
#define __GDK_DND_H__
|
||||
|
||||
#if !defined (__GDK_H_INSIDE__) && !defined (GDK_COMPILATION)
|
||||
#error "Only <gdk/gdk.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <gdk/gdktypes.h>
|
||||
#include <gdk/gdkdevice.h>
|
||||
#include <gdk/gdkevents.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GDK_TYPE_DRAG (gdk_drag_get_type ())
|
||||
#define GDK_DRAG(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_DRAG, GdkDrag))
|
||||
#define GDK_IS_DRAG(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_DRAG))
|
||||
|
||||
/**
|
||||
* GdkDragCancelReason:
|
||||
* @GDK_DRAG_CANCEL_NO_TARGET: There is no suitable drop target.
|
||||
* @GDK_DRAG_CANCEL_USER_CANCELLED: Drag cancelled by the user
|
||||
* @GDK_DRAG_CANCEL_ERROR: Unspecified error.
|
||||
*
|
||||
* Used in #GdkDrag to the reason of a cancelled DND operation.
|
||||
*/
|
||||
typedef enum {
|
||||
GDK_DRAG_CANCEL_NO_TARGET,
|
||||
GDK_DRAG_CANCEL_USER_CANCELLED,
|
||||
GDK_DRAG_CANCEL_ERROR
|
||||
} GdkDragCancelReason;
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GType gdk_drag_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkDisplay * gdk_drag_get_display (GdkDrag *drag);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkDevice * gdk_drag_get_device (GdkDrag *drag);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkContentFormats *gdk_drag_get_formats (GdkDrag *drag);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkDragAction gdk_drag_get_actions (GdkDrag *drag);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkDragAction gdk_drag_get_selected_action (GdkDrag *drag);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gdk_drag_action_is_unique (GdkDragAction action);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkDrag * gdk_drag_begin (GdkSurface *surface,
|
||||
GdkDevice *device,
|
||||
GdkContentProvider *content,
|
||||
GdkDragAction actions,
|
||||
gint dx,
|
||||
gint dy);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_drag_drop_done (GdkDrag *drag,
|
||||
gboolean success);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkSurface *gdk_drag_get_drag_surface (GdkDrag *drag);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_drag_set_hotspot (GdkDrag *drag,
|
||||
gint hot_x,
|
||||
gint hot_y);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_DND_H__ */
|
||||
@@ -0,0 +1,86 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2010, Red Hat, Inc
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GDK_DND_PRIVATE_H__
|
||||
#define __GDK_DND_PRIVATE_H__
|
||||
|
||||
#include "gdkdrag.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
||||
#define GDK_DRAG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_DRAG, GdkDragClass))
|
||||
#define GDK_IS_DRAG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_DRAG))
|
||||
#define GDK_DRAG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_DRAG, GdkDragClass))
|
||||
|
||||
typedef struct _GdkDragClass GdkDragClass;
|
||||
|
||||
|
||||
struct _GdkDragClass {
|
||||
GObjectClass parent_class;
|
||||
|
||||
GdkSurface* (*get_drag_surface) (GdkDrag *drag);
|
||||
void (*set_hotspot) (GdkDrag *drag,
|
||||
gint hot_x,
|
||||
gint hot_y);
|
||||
void (*drop_done) (GdkDrag *drag,
|
||||
gboolean success);
|
||||
|
||||
void (*set_cursor) (GdkDrag *drag,
|
||||
GdkCursor *cursor);
|
||||
void (*cancel) (GdkDrag *drag,
|
||||
GdkDragCancelReason reason);
|
||||
void (*drop_performed) (GdkDrag *drag,
|
||||
guint32 time);
|
||||
void (*dnd_finished) (GdkDrag *drag);
|
||||
|
||||
gboolean (*handle_event) (GdkDrag *drag,
|
||||
const GdkEvent *event);
|
||||
};
|
||||
|
||||
struct _GdkDrag {
|
||||
GObject parent_instance;
|
||||
};
|
||||
|
||||
void gdk_drag_set_cursor (GdkDrag *drag,
|
||||
GdkCursor *cursor);
|
||||
void gdk_drag_set_actions (GdkDrag *drag,
|
||||
GdkDragAction actions);
|
||||
void gdk_drag_set_selected_action (GdkDrag *drag,
|
||||
GdkDragAction action);
|
||||
|
||||
void gdk_drag_cancel (GdkDrag *drag,
|
||||
GdkDragCancelReason reason);
|
||||
gboolean gdk_drag_handle_source_event (GdkEvent *event);
|
||||
GdkCursor * gdk_drag_get_cursor (GdkDrag *drag,
|
||||
GdkDragAction action);
|
||||
|
||||
void gdk_drag_write_async (GdkDrag *drag,
|
||||
const char *mime_type,
|
||||
GOutputStream *stream,
|
||||
int io_priority,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
gboolean gdk_drag_write_finish (GdkDrag *drag,
|
||||
GAsyncResult *result,
|
||||
GError **error);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif
|
||||
+990
@@ -0,0 +1,990 @@
|
||||
/*
|
||||
* Copyright © 2018 Benjamin Otte
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Benjamin Otte <otte@gnome.org>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gdkdropprivate.h"
|
||||
|
||||
#include "gdkcontentdeserializer.h"
|
||||
#include "gdkcontentformats.h"
|
||||
#include "gdkcontentprovider.h"
|
||||
#include "gdkcontentserializer.h"
|
||||
#include "gdkcursor.h"
|
||||
#include "gdkdisplay.h"
|
||||
#include "gdkenumtypes.h"
|
||||
#include "gdkeventsprivate.h"
|
||||
#include "gdkinternals.h"
|
||||
#include "gdkintl.h"
|
||||
#include "gdkpipeiostreamprivate.h"
|
||||
#include "gdksurface.h"
|
||||
|
||||
typedef struct _GdkDropPrivate GdkDropPrivate;
|
||||
|
||||
struct _GdkDropPrivate {
|
||||
GdkDevice *device;
|
||||
GdkDrag *drag;
|
||||
GdkContentFormats *formats;
|
||||
GdkSurface *surface;
|
||||
GdkDragAction actions;
|
||||
};
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_ACTIONS,
|
||||
PROP_DEVICE,
|
||||
PROP_DISPLAY,
|
||||
PROP_DRAG,
|
||||
PROP_FORMATS,
|
||||
PROP_SURFACE,
|
||||
N_PROPERTIES
|
||||
};
|
||||
|
||||
static GParamSpec *properties[N_PROPERTIES] = { NULL, };
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GdkDrop, gdk_drop, G_TYPE_OBJECT)
|
||||
|
||||
/**
|
||||
* GdkDrop:
|
||||
*
|
||||
* The GdkDrop struct contains only private fields and
|
||||
* should not be accessed directly.
|
||||
*/
|
||||
|
||||
static void
|
||||
gdk_drop_default_status (GdkDrop *self,
|
||||
GdkDragAction actions)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_drop_read_local_write_done (GObject *drag,
|
||||
GAsyncResult *result,
|
||||
gpointer stream)
|
||||
{
|
||||
/* we don't care about the error, we just want to clean up */
|
||||
gdk_drag_write_finish (GDK_DRAG (drag), result, NULL);
|
||||
|
||||
/* XXX: Do we need to close_async() here? */
|
||||
g_output_stream_close (stream, NULL, NULL);
|
||||
|
||||
g_object_unref (stream);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_drop_read_local_async (GdkDrop *self,
|
||||
GdkContentFormats *formats,
|
||||
int io_priority,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
GdkDropPrivate *priv = gdk_drop_get_instance_private (self);
|
||||
GdkContentFormats *content_formats;
|
||||
const char *mime_type;
|
||||
GTask *task;
|
||||
GdkContentProvider *content;
|
||||
|
||||
task = g_task_new (self, cancellable, callback, user_data);
|
||||
g_task_set_priority (task, io_priority);
|
||||
g_task_set_source_tag (task, gdk_drop_read_local_async);
|
||||
|
||||
if (priv->drag == NULL)
|
||||
{
|
||||
g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
|
||||
_("Drag'n'drop from other applications is not supported."));
|
||||
g_object_unref (task);
|
||||
return;
|
||||
}
|
||||
|
||||
g_object_get (priv->drag, "content", &content, NULL);
|
||||
content_formats = gdk_content_provider_ref_formats (content);
|
||||
g_object_unref (content);
|
||||
content_formats = gdk_content_formats_union_serialize_mime_types (content_formats);
|
||||
mime_type = gdk_content_formats_match_mime_type (content_formats, formats);
|
||||
|
||||
if (mime_type != NULL)
|
||||
{
|
||||
GOutputStream *output_stream;
|
||||
GIOStream *stream;
|
||||
|
||||
stream = gdk_pipe_io_stream_new ();
|
||||
output_stream = g_io_stream_get_output_stream (stream);
|
||||
gdk_drag_write_async (priv->drag,
|
||||
mime_type,
|
||||
output_stream,
|
||||
io_priority,
|
||||
cancellable,
|
||||
gdk_drop_read_local_write_done,
|
||||
g_object_ref (output_stream));
|
||||
g_task_set_task_data (task, (gpointer) mime_type, NULL);
|
||||
g_task_return_pointer (task, g_object_ref (g_io_stream_get_input_stream (stream)), g_object_unref);
|
||||
|
||||
g_object_unref (stream);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
|
||||
_("No compatible formats to transfer contents."));
|
||||
}
|
||||
|
||||
gdk_content_formats_unref (content_formats);
|
||||
g_object_unref (task);
|
||||
}
|
||||
|
||||
static GInputStream *
|
||||
gdk_drop_read_local_finish (GdkDrop *self,
|
||||
const char **out_mime_type,
|
||||
GAsyncResult *result,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (g_task_is_valid (result, self), NULL);
|
||||
g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) == gdk_drop_read_local_async, NULL);
|
||||
|
||||
if (out_mime_type)
|
||||
*out_mime_type = g_task_get_task_data (G_TASK (result));
|
||||
|
||||
return g_task_propagate_pointer (G_TASK (result), error);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_drop_set_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GdkDrop *self = GDK_DROP (gobject);
|
||||
GdkDropPrivate *priv = gdk_drop_get_instance_private (self);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_ACTIONS:
|
||||
gdk_drop_set_actions (self, g_value_get_flags (value));
|
||||
break;
|
||||
|
||||
case PROP_DEVICE:
|
||||
priv->device = g_value_dup_object (value);
|
||||
g_assert (priv->device != NULL);
|
||||
if (priv->surface)
|
||||
g_assert (gdk_surface_get_display (priv->surface) == gdk_device_get_display (priv->device));
|
||||
break;
|
||||
|
||||
case PROP_DRAG:
|
||||
priv->drag = g_value_dup_object (value);
|
||||
break;
|
||||
|
||||
case PROP_FORMATS:
|
||||
priv->formats = g_value_dup_boxed (value);
|
||||
g_assert (priv->formats != NULL);
|
||||
break;
|
||||
|
||||
case PROP_SURFACE:
|
||||
priv->surface = g_value_dup_object (value);
|
||||
g_assert (priv->surface != NULL);
|
||||
if (priv->device)
|
||||
g_assert (gdk_surface_get_display (priv->surface) == gdk_device_get_display (priv->device));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_drop_get_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GdkDrop *self = GDK_DROP (gobject);
|
||||
GdkDropPrivate *priv = gdk_drop_get_instance_private (self);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_ACTIONS:
|
||||
g_value_set_flags (value, priv->actions);
|
||||
break;
|
||||
|
||||
case PROP_DEVICE:
|
||||
g_value_set_object (value, priv->device);
|
||||
break;
|
||||
|
||||
case PROP_DISPLAY:
|
||||
g_value_set_object (value, gdk_device_get_display (priv->device));
|
||||
break;
|
||||
|
||||
case PROP_DRAG:
|
||||
g_value_set_object (value, priv->drag);
|
||||
break;
|
||||
|
||||
case PROP_FORMATS:
|
||||
g_value_set_boxed (value, priv->formats);
|
||||
break;
|
||||
|
||||
case PROP_SURFACE:
|
||||
g_value_set_object (value, priv->surface);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_drop_finalize (GObject *object)
|
||||
{
|
||||
GdkDrop *self = GDK_DROP (object);
|
||||
GdkDropPrivate *priv = gdk_drop_get_instance_private (self);
|
||||
|
||||
g_clear_object (&priv->device);
|
||||
g_clear_object (&priv->drag);
|
||||
|
||||
G_OBJECT_CLASS (gdk_drop_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_drop_class_init (GdkDropClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
klass->status = gdk_drop_default_status;
|
||||
|
||||
object_class->get_property = gdk_drop_get_property;
|
||||
object_class->set_property = gdk_drop_set_property;
|
||||
object_class->finalize = gdk_drop_finalize;
|
||||
|
||||
/**
|
||||
* GdkDrop:actions:
|
||||
*
|
||||
* The possible actions for this drop
|
||||
*/
|
||||
properties[PROP_ACTIONS] =
|
||||
g_param_spec_flags ("actions",
|
||||
"Actions",
|
||||
"The possible actions for this drop",
|
||||
GDK_TYPE_DRAG_ACTION,
|
||||
GDK_ACTION_ALL,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
/**
|
||||
* GdkDrop:device:
|
||||
*
|
||||
* The #GdkDevice performing the drop
|
||||
*/
|
||||
properties[PROP_DEVICE] =
|
||||
g_param_spec_object ("device",
|
||||
"Device",
|
||||
"The device performing the drop",
|
||||
GDK_TYPE_DEVICE,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
/**
|
||||
* GdkDrop:display:
|
||||
*
|
||||
* The #GdkDisplay that the drop belongs to.
|
||||
*/
|
||||
properties[PROP_DISPLAY] =
|
||||
g_param_spec_object ("display",
|
||||
"Display",
|
||||
"Display this drag belongs to",
|
||||
GDK_TYPE_DISPLAY,
|
||||
G_PARAM_READABLE |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
/**
|
||||
* GdkDrop:drag:
|
||||
*
|
||||
* The #GdkDrag that initiated this drop
|
||||
*/
|
||||
properties[PROP_DRAG] =
|
||||
g_param_spec_object ("drag",
|
||||
"Drag",
|
||||
"The drag that initiated this drop",
|
||||
GDK_TYPE_DRAG,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
/**
|
||||
* GdkDrop:formats:
|
||||
*
|
||||
* The possible formats that the drop can provide its data in.
|
||||
*/
|
||||
properties[PROP_FORMATS] =
|
||||
g_param_spec_boxed ("formats",
|
||||
"Formats",
|
||||
"The possible formats for data",
|
||||
GDK_TYPE_CONTENT_FORMATS,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
/**
|
||||
* GdkDrop:surface:
|
||||
*
|
||||
* The #GdkSurface the drop happens on
|
||||
*/
|
||||
properties[PROP_SURFACE] =
|
||||
g_param_spec_object ("surface",
|
||||
"Surface",
|
||||
"The surface the drop is happening on",
|
||||
GDK_TYPE_SURFACE,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
g_object_class_install_properties (object_class, N_PROPERTIES, properties);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_drop_init (GdkDrop *self)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_drop_get_display:
|
||||
* @self: a #GdkDrop
|
||||
*
|
||||
* Gets the #GdkDisplay that @self was created for.
|
||||
*
|
||||
* Returns: (transfer none): a #GdkDisplay
|
||||
**/
|
||||
GdkDisplay *
|
||||
gdk_drop_get_display (GdkDrop *self)
|
||||
{
|
||||
GdkDropPrivate *priv = gdk_drop_get_instance_private (self);
|
||||
|
||||
g_return_val_if_fail (GDK_IS_DROP (self), NULL);
|
||||
|
||||
return gdk_device_get_display (priv->device);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_drop_get_device:
|
||||
* @self: a #GdkDrop
|
||||
*
|
||||
* Returns the #GdkDevice performing the drop.
|
||||
*
|
||||
* Returns: (transfer none): The #GdkDevice performing the drop.
|
||||
**/
|
||||
GdkDevice *
|
||||
gdk_drop_get_device (GdkDrop *self)
|
||||
{
|
||||
GdkDropPrivate *priv = gdk_drop_get_instance_private (self);
|
||||
|
||||
g_return_val_if_fail (GDK_IS_DROP (self), NULL);
|
||||
|
||||
return priv->device;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_drop_get_formats:
|
||||
* @self: a #GdkDrop
|
||||
*
|
||||
* Returns the #GdkContentFormats that the drop offers the data
|
||||
* to be read in.
|
||||
*
|
||||
* Returns: (transfer none): The possible #GdkContentFormats
|
||||
**/
|
||||
GdkContentFormats *
|
||||
gdk_drop_get_formats (GdkDrop *self)
|
||||
{
|
||||
GdkDropPrivate *priv = gdk_drop_get_instance_private (self);
|
||||
|
||||
g_return_val_if_fail (GDK_IS_DROP (self), NULL);
|
||||
|
||||
return priv->formats;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_drop_get_surface:
|
||||
* @self: a #GdkDrop
|
||||
*
|
||||
* Returns the #GdkSurface performing the drop.
|
||||
*
|
||||
* Returns: (transfer none): The #GdkSurface performing the drop.
|
||||
**/
|
||||
GdkSurface *
|
||||
gdk_drop_get_surface (GdkDrop *self)
|
||||
{
|
||||
GdkDropPrivate *priv = gdk_drop_get_instance_private (self);
|
||||
|
||||
g_return_val_if_fail (GDK_IS_DROP (self), NULL);
|
||||
|
||||
return priv->surface;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_drop_get_actions:
|
||||
* @self: a #GdkDrop
|
||||
*
|
||||
* Returns the possible actions for this #GdkDrop. If this value
|
||||
* contains multiple actions - ie gdk_drag_action_is_unique()
|
||||
* returns %FALSE for the result - gdk_drag_finish() must choose
|
||||
* the action to use when accepting the drop.
|
||||
*
|
||||
* This value may change over the lifetime of the #GdkDrop both
|
||||
* as a response to source side actions as well as to calls to
|
||||
* gdk_drop_status() or gdk_drag_finish(). The source side will
|
||||
* not change this value anymore once a drop has started.
|
||||
*
|
||||
* Returns: The possible #GdkDragActions
|
||||
**/
|
||||
GdkDragAction
|
||||
gdk_drop_get_actions (GdkDrop *self)
|
||||
{
|
||||
GdkDropPrivate *priv = gdk_drop_get_instance_private (self);
|
||||
|
||||
g_return_val_if_fail (GDK_IS_DROP (self), 0);
|
||||
|
||||
return priv->actions;
|
||||
}
|
||||
|
||||
void
|
||||
gdk_drop_set_actions (GdkDrop *self,
|
||||
GdkDragAction actions)
|
||||
{
|
||||
GdkDropPrivate *priv = gdk_drop_get_instance_private (self);
|
||||
|
||||
g_return_if_fail (GDK_IS_DROP (self));
|
||||
g_return_if_fail ((actions & GDK_ACTION_ASK) == 0);
|
||||
|
||||
if (priv->actions == actions)
|
||||
return;
|
||||
|
||||
priv->actions = actions;
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_ACTIONS]);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_drop_get_drag:
|
||||
* @self: a #GdkDrop
|
||||
*
|
||||
* If this is an in-app drag-and-drop operation, returns the #GdkDrag
|
||||
* that corresponds to this drop.
|
||||
*
|
||||
* If it is not, %NULL is returned.
|
||||
*
|
||||
* Returns: (transfer none) (nullable): the corresponding #GdkDrag
|
||||
**/
|
||||
GdkDrag *
|
||||
gdk_drop_get_drag (GdkDrop *self)
|
||||
{
|
||||
GdkDropPrivate *priv = gdk_drop_get_instance_private (self);
|
||||
|
||||
g_return_val_if_fail (GDK_IS_DROP (self), 0);
|
||||
|
||||
return priv->drag;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_drop_status:
|
||||
* @self: a #GdkDrop
|
||||
* @actions: Supported actions of the destination, or 0 to indicate
|
||||
* that a drop will not be accepted
|
||||
*
|
||||
* Selects all actions that are potentially supported by the destination.
|
||||
*
|
||||
* When calling this function, do not restrict the passed in actions to
|
||||
* the ones provided by gdk_drop_get_actions(). Those actions may
|
||||
* change in the future, even depending on the actions you provide here.
|
||||
*
|
||||
* This function should be called by drag destinations in response to
|
||||
* %GDK_DRAG_ENTER or %GDK_DRAG_MOTION events. If the destination does
|
||||
* not yet know the exact actions it supports, it should set any possible
|
||||
* actions first and then later call this function again.
|
||||
*/
|
||||
void
|
||||
gdk_drop_status (GdkDrop *self,
|
||||
GdkDragAction actions)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_DROP (self));
|
||||
|
||||
GDK_DROP_GET_CLASS (self)->status (self, actions);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_drop_finish:
|
||||
* @self: a #GdkDrop
|
||||
* @action: the action performed by the destination or 0 if the drop
|
||||
* failed
|
||||
*
|
||||
* Ends the drag operation after a drop.
|
||||
*
|
||||
* The @action must be a single action selected from the actions
|
||||
* available via gdk_drop_get_actions().
|
||||
**/
|
||||
void
|
||||
gdk_drop_finish (GdkDrop *self,
|
||||
GdkDragAction action)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_DROP (self));
|
||||
g_return_if_fail (gdk_drag_action_is_unique (action));
|
||||
|
||||
GDK_DROP_GET_CLASS (self)->finish (self, action);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_drop_read_internal (GdkDrop *self,
|
||||
GdkContentFormats *formats,
|
||||
int io_priority,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
GdkDropPrivate *priv = gdk_drop_get_instance_private (self);
|
||||
|
||||
if (priv->drag)
|
||||
{
|
||||
gdk_drop_read_local_async (self,
|
||||
formats,
|
||||
io_priority,
|
||||
cancellable,
|
||||
callback,
|
||||
user_data);
|
||||
}
|
||||
else
|
||||
{
|
||||
GDK_DROP_GET_CLASS (self)->read_async (self,
|
||||
formats,
|
||||
io_priority,
|
||||
cancellable,
|
||||
callback,
|
||||
user_data);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_drop_read_async:
|
||||
* @self: a #GdkDrop
|
||||
* @mime_types: (array zero-terminated=1) (element-type utf8):
|
||||
* pointer to an array of mime types
|
||||
* @io_priority: the io priority for the read operation
|
||||
* @cancellable: (allow-none): optional #GCancellable object,
|
||||
* %NULL to ignore
|
||||
* @callback: (scope async): a #GAsyncReadyCallback to call when
|
||||
* the request is satisfied
|
||||
* @user_data: (closure): the data to pass to @callback
|
||||
*
|
||||
* Asynchronously read the dropped data from a #GdkDrop
|
||||
* in a format that complies with one of the mime types.
|
||||
*/
|
||||
void
|
||||
gdk_drop_read_async (GdkDrop *self,
|
||||
const char **mime_types,
|
||||
int io_priority,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
GdkContentFormats *formats;
|
||||
|
||||
g_return_if_fail (GDK_IS_DROP (self));
|
||||
g_return_if_fail (mime_types != NULL && mime_types[0] != NULL);
|
||||
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
|
||||
g_return_if_fail (callback != NULL);
|
||||
|
||||
formats = gdk_content_formats_new (mime_types, g_strv_length ((char **) mime_types));
|
||||
|
||||
gdk_drop_read_internal (self, formats, io_priority, cancellable, callback, user_data);
|
||||
|
||||
gdk_content_formats_unref (formats);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_drop_read_finish:
|
||||
* @self: a #GdkDrop
|
||||
* @out_mime_type: (out) (type utf8): return location for the used mime type
|
||||
* @result: a #GAsyncResult
|
||||
* @error: (allow-none): location to store error information on failure, or %NULL
|
||||
*
|
||||
* Finishes an async drop read operation, see gdk_drop_read_async().
|
||||
*
|
||||
* Returns: (nullable) (transfer full): the #GInputStream, or %NULL
|
||||
*/
|
||||
GInputStream *
|
||||
gdk_drop_read_finish (GdkDrop *self,
|
||||
const char **out_mime_type,
|
||||
GAsyncResult *result,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_DROP (self), NULL);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
||||
|
||||
if (g_async_result_is_tagged (result, gdk_drop_read_local_async))
|
||||
{
|
||||
return gdk_drop_read_local_finish (self, out_mime_type, result, error);
|
||||
}
|
||||
else
|
||||
{
|
||||
return GDK_DROP_GET_CLASS (self)->read_finish (self, out_mime_type, result, error);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_drop_read_value_done (GObject *source,
|
||||
GAsyncResult *result,
|
||||
gpointer data)
|
||||
{
|
||||
GTask *task = data;
|
||||
GError *error = NULL;
|
||||
GValue *value;
|
||||
|
||||
value = g_task_get_task_data (task);
|
||||
|
||||
if (!gdk_content_deserialize_finish (result, value, &error))
|
||||
g_task_return_error (task, error);
|
||||
else
|
||||
g_task_return_pointer (task, value, NULL);
|
||||
|
||||
g_object_unref (task);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_drop_read_value_got_stream (GObject *source,
|
||||
GAsyncResult *result,
|
||||
gpointer data)
|
||||
{
|
||||
GInputStream *stream;
|
||||
GError *error = NULL;
|
||||
GTask *task = data;
|
||||
const char *mime_type;
|
||||
|
||||
stream = gdk_drop_read_finish (GDK_DROP (source), &mime_type, result, &error);
|
||||
if (stream == NULL)
|
||||
{
|
||||
g_task_return_error (task, error);
|
||||
return;
|
||||
}
|
||||
|
||||
gdk_content_deserialize_async (stream,
|
||||
mime_type,
|
||||
G_VALUE_TYPE (g_task_get_task_data (task)),
|
||||
g_task_get_priority (task),
|
||||
g_task_get_cancellable (task),
|
||||
gdk_drop_read_value_done,
|
||||
task);
|
||||
g_object_unref (stream);
|
||||
}
|
||||
|
||||
static void
|
||||
free_value (gpointer value)
|
||||
{
|
||||
g_value_unset (value);
|
||||
g_slice_free (GValue, value);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_drop_read_value_internal (GdkDrop *self,
|
||||
GType type,
|
||||
gpointer source_tag,
|
||||
int io_priority,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
GdkDropPrivate *priv = gdk_drop_get_instance_private (self);
|
||||
GdkContentFormatsBuilder *builder;
|
||||
GdkContentFormats *formats;
|
||||
GValue *value;
|
||||
GTask *task;
|
||||
|
||||
task = g_task_new (self, cancellable, callback, user_data);
|
||||
g_task_set_priority (task, io_priority);
|
||||
g_task_set_source_tag (task, source_tag);
|
||||
value = g_slice_new0 (GValue);
|
||||
g_value_init (value, type);
|
||||
g_task_set_task_data (task, value, free_value);
|
||||
|
||||
if (priv->drag)
|
||||
{
|
||||
GError *error = NULL;
|
||||
GdkContentProvider *content;
|
||||
gboolean res;
|
||||
|
||||
g_object_get (priv->drag, "content", &content, NULL);
|
||||
|
||||
res = gdk_content_provider_get_value (content, value, &error);
|
||||
|
||||
g_object_unref (content);
|
||||
|
||||
if (res)
|
||||
{
|
||||
g_task_return_pointer (task, value, NULL);
|
||||
g_object_unref (task);
|
||||
return;
|
||||
}
|
||||
else if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED))
|
||||
{
|
||||
g_task_return_error (task, error);
|
||||
g_object_unref (task);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* fall through to regular stream transfer */
|
||||
g_clear_error (&error);
|
||||
}
|
||||
}
|
||||
|
||||
builder = gdk_content_formats_builder_new ();
|
||||
gdk_content_formats_builder_add_gtype (builder, type);
|
||||
formats = gdk_content_formats_builder_free_to_formats (builder);
|
||||
formats = gdk_content_formats_union_deserialize_mime_types (formats);
|
||||
|
||||
gdk_drop_read_internal (self,
|
||||
formats,
|
||||
io_priority,
|
||||
cancellable,
|
||||
gdk_drop_read_value_got_stream,
|
||||
task);
|
||||
|
||||
gdk_content_formats_unref (formats);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_drop_read_value_async:
|
||||
* @self: a #GdkDrop
|
||||
* @type: a #GType to read
|
||||
* @io_priority: the [I/O priority][io-priority]
|
||||
* of the request.
|
||||
* @cancellable: (nullable): optional #GCancellable object, %NULL to ignore.
|
||||
* @callback: (scope async): callback to call when the request is satisfied
|
||||
* @user_data: (closure): the data to pass to callback function
|
||||
*
|
||||
* Asynchronously request the drag operation's contents converted to the given
|
||||
* @type. When the operation is finished @callback will be called.
|
||||
* You can then call gdk_drop_read_value_finish() to get the resulting
|
||||
* #GValue.
|
||||
*
|
||||
* For local drag'n'drop operations that are available in the given #GType, the
|
||||
* value will be copied directly. Otherwise, GDK will try to use
|
||||
* gdk_content_deserialize_async() to convert the data.
|
||||
**/
|
||||
void
|
||||
gdk_drop_read_value_async (GdkDrop *self,
|
||||
GType type,
|
||||
int io_priority,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_DROP (self));
|
||||
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
|
||||
g_return_if_fail (callback != NULL);
|
||||
|
||||
gdk_drop_read_value_internal (self,
|
||||
type,
|
||||
gdk_drop_read_value_async,
|
||||
io_priority,
|
||||
cancellable,
|
||||
callback,
|
||||
user_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_drop_read_value_finish:
|
||||
* @self: a #GdkDrop
|
||||
* @result: a #GAsyncResult
|
||||
* @error: a #GError location to store the error occurring, or %NULL to
|
||||
* ignore.
|
||||
*
|
||||
* Finishes an async drop read started with
|
||||
* gdk_drop_read_value_async().
|
||||
*
|
||||
* Returns: (transfer none): a #GValue containing the result.
|
||||
**/
|
||||
const GValue *
|
||||
gdk_drop_read_value_finish (GdkDrop *self,
|
||||
GAsyncResult *result,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (g_task_is_valid (result, self), NULL);
|
||||
g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) == gdk_drop_read_value_async, NULL);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
||||
|
||||
return g_task_propagate_pointer (G_TASK (result), error);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_drop_read_text_async:
|
||||
* @self: a #GdkDrop
|
||||
* @cancellable: (nullable): optional #GCancellable object, %NULL to ignore.
|
||||
* @callback: (scope async): callback to call when the request is satisfied
|
||||
* @user_data: (closure): the data to pass to callback function
|
||||
*
|
||||
* Asynchronously request the drag operation's contents converted to a string.
|
||||
* When the operation is finished @callback will be called. You can then
|
||||
* call gdk_drop_read_text_finish() to get the result.
|
||||
*
|
||||
* This is a simple wrapper around gdk_drop_read_value_async(). Use
|
||||
* that function or gdk_drop_read_async() directly if you need more
|
||||
* control over the operation.
|
||||
**/
|
||||
void
|
||||
gdk_drop_read_text_async (GdkDrop *self,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_DROP (self));
|
||||
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
|
||||
g_return_if_fail (callback != NULL);
|
||||
|
||||
gdk_drop_read_value_internal (self,
|
||||
G_TYPE_STRING,
|
||||
gdk_drop_read_text_async,
|
||||
G_PRIORITY_DEFAULT,
|
||||
cancellable,
|
||||
callback,
|
||||
user_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_drop_read_text_finish:
|
||||
* @self: a #GdkDrop
|
||||
* @result: a #GAsyncResult
|
||||
* @error: a #GError location to store the error occurring, or %NULL to
|
||||
* ignore.
|
||||
*
|
||||
* Finishes an asynchronous read started with
|
||||
* gdk_drop_read_text_async().
|
||||
*
|
||||
* Returns: (transfer full) (nullable): a new string or %NULL on error.
|
||||
**/
|
||||
char *
|
||||
gdk_drop_read_text_finish (GdkDrop *self,
|
||||
GAsyncResult *result,
|
||||
GError **error)
|
||||
{
|
||||
const GValue *value;
|
||||
|
||||
g_return_val_if_fail (g_task_is_valid (result, self), NULL);
|
||||
g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) == gdk_drop_read_text_async, NULL);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
||||
|
||||
value = g_task_propagate_pointer (G_TASK (result), error);
|
||||
if (!value)
|
||||
return NULL;
|
||||
|
||||
return g_value_dup_string (value);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_drop_do_emit_event (GdkEvent *event,
|
||||
gboolean dont_queue)
|
||||
{
|
||||
if (dont_queue)
|
||||
{
|
||||
_gdk_event_emit (event);
|
||||
g_object_unref (event);
|
||||
}
|
||||
else
|
||||
{
|
||||
_gdk_event_queue_append (gdk_event_get_display (event), event);
|
||||
}
|
||||
}
|
||||
void
|
||||
gdk_drop_emit_enter_event (GdkDrop *self,
|
||||
gboolean dont_queue,
|
||||
guint32 time)
|
||||
{
|
||||
GdkDropPrivate *priv = gdk_drop_get_instance_private (self);
|
||||
GdkEvent *event;
|
||||
|
||||
event = gdk_event_new (GDK_DRAG_ENTER);
|
||||
event->any.surface = g_object_ref (priv->surface);
|
||||
event->dnd.drop = g_object_ref (self);
|
||||
event->dnd.time = time;
|
||||
gdk_event_set_device (event, priv->device);
|
||||
|
||||
gdk_drop_do_emit_event (event, dont_queue);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_drop_emit_motion_event (GdkDrop *self,
|
||||
gboolean dont_queue,
|
||||
double x_root,
|
||||
double y_root,
|
||||
guint32 time)
|
||||
{
|
||||
GdkDropPrivate *priv = gdk_drop_get_instance_private (self);
|
||||
GdkEvent *event;
|
||||
|
||||
event = gdk_event_new (GDK_DRAG_MOTION);
|
||||
event->any.surface = g_object_ref (priv->surface);
|
||||
event->dnd.drop = g_object_ref (self);
|
||||
event->dnd.time = time;
|
||||
event->dnd.x_root = x_root;
|
||||
event->dnd.y_root = y_root;
|
||||
gdk_event_set_device (event, priv->device);
|
||||
|
||||
gdk_drop_do_emit_event (event, dont_queue);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_drop_emit_leave_event (GdkDrop *self,
|
||||
gboolean dont_queue,
|
||||
guint32 time)
|
||||
{
|
||||
GdkDropPrivate *priv = gdk_drop_get_instance_private (self);
|
||||
GdkEvent *event;
|
||||
|
||||
event = gdk_event_new (GDK_DRAG_LEAVE);
|
||||
event->any.surface = g_object_ref (priv->surface);
|
||||
event->dnd.drop = g_object_ref (self);
|
||||
event->dnd.time = time;
|
||||
gdk_event_set_device (event, priv->device);
|
||||
|
||||
gdk_drop_do_emit_event (event, dont_queue);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_drop_emit_drop_event (GdkDrop *self,
|
||||
gboolean dont_queue,
|
||||
double x_root,
|
||||
double y_root,
|
||||
guint32 time)
|
||||
{
|
||||
GdkDropPrivate *priv = gdk_drop_get_instance_private (self);
|
||||
GdkEvent *event;
|
||||
|
||||
event = gdk_event_new (GDK_DROP_START);
|
||||
event->any.surface = g_object_ref (priv->surface);
|
||||
event->dnd.drop = g_object_ref (self);
|
||||
event->dnd.time = time;
|
||||
event->dnd.x_root = x_root;
|
||||
event->dnd.y_root = y_root;
|
||||
gdk_event_set_device (event, priv->device);
|
||||
|
||||
gdk_drop_do_emit_event (event, dont_queue);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright © 2018 Benjamin Otte
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Benjamin Otte <otte@gnome.org>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __GDK_DROP_H__
|
||||
#define __GDK_DROP_H__
|
||||
|
||||
#if !defined (__GDK_H_INSIDE__) && !defined (GDK_COMPILATION)
|
||||
#error "Only <gdk/gdk.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <gdk/gdktypes.h>
|
||||
#include <gdk/gdkversionmacros.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkDrop, g_object_unref)
|
||||
|
||||
#define GDK_TYPE_DROP (gdk_drop_get_type ())
|
||||
#define GDK_DROP(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_DROP, GdkDrop))
|
||||
#define GDK_IS_DROP(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_DROP))
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GType gdk_drop_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkDisplay * gdk_drop_get_display (GdkDrop *self);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkDevice * gdk_drop_get_device (GdkDrop *self);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkSurface * gdk_drop_get_surface (GdkDrop *self);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkContentFormats * gdk_drop_get_formats (GdkDrop *self);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkDragAction gdk_drop_get_actions (GdkDrop *self);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkDrag * gdk_drop_get_drag (GdkDrop *self);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_drop_status (GdkDrop *self,
|
||||
GdkDragAction actions);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_drop_finish (GdkDrop *self,
|
||||
GdkDragAction action);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_drop_read_async (GdkDrop *self,
|
||||
const char **mime_types,
|
||||
int io_priority,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GInputStream * gdk_drop_read_finish (GdkDrop *self,
|
||||
const char **out_mime_type,
|
||||
GAsyncResult *result,
|
||||
GError **error);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_drop_read_value_async (GdkDrop *self,
|
||||
GType type,
|
||||
int io_priority,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
const GValue * gdk_drop_read_value_finish (GdkDrop *self,
|
||||
GAsyncResult *result,
|
||||
GError **error);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_drop_read_text_async (GdkDrop *self,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
char * gdk_drop_read_text_finish (GdkDrop *self,
|
||||
GAsyncResult *result,
|
||||
GError **error);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_DROP_H__ */
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright © 2018 Benjamin Otte
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Benjamin Otte <otte@gnome.org>
|
||||
*/
|
||||
|
||||
#ifndef __GDK_DROP_PRIVATE_H__
|
||||
#define __GDK_DROP_PRIVATE_H__
|
||||
|
||||
#include "gdkdrop.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
||||
#define GDK_DROP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_DROP, GdkDropClass))
|
||||
#define GDK_IS_DROP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_DROP))
|
||||
#define GDK_DROP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_DROP, GdkDropClass))
|
||||
|
||||
typedef struct _GdkDropClass GdkDropClass;
|
||||
|
||||
|
||||
struct _GdkDrop {
|
||||
GObject parent_instance;
|
||||
};
|
||||
|
||||
struct _GdkDropClass {
|
||||
GObjectClass parent_class;
|
||||
|
||||
void (* status) (GdkDrop *self,
|
||||
GdkDragAction actions);
|
||||
void (* finish) (GdkDrop *self,
|
||||
GdkDragAction action);
|
||||
|
||||
void (* read_async) (GdkDrop *self,
|
||||
GdkContentFormats *formats,
|
||||
int io_priority,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
GInputStream * (* read_finish) (GdkDrop *self,
|
||||
const char **out_mime_type,
|
||||
GAsyncResult *result,
|
||||
GError **error);
|
||||
};
|
||||
|
||||
void gdk_drop_set_actions (GdkDrop *self,
|
||||
GdkDragAction actions);
|
||||
|
||||
void gdk_drop_emit_enter_event (GdkDrop *self,
|
||||
gboolean dont_queue,
|
||||
guint32 time);
|
||||
void gdk_drop_emit_motion_event (GdkDrop *self,
|
||||
gboolean dont_queue,
|
||||
double x_root,
|
||||
double y_root,
|
||||
guint32 time);
|
||||
void gdk_drop_emit_leave_event (GdkDrop *self,
|
||||
gboolean dont_queue,
|
||||
guint32 time);
|
||||
void gdk_drop_emit_drop_event (GdkDrop *self,
|
||||
gboolean dont_queue,
|
||||
double x_root,
|
||||
double y_root,
|
||||
guint32 time);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif
|
||||
+15
-77
@@ -28,7 +28,8 @@
|
||||
#include "gdkeventsprivate.h"
|
||||
#include "gdkinternals.h"
|
||||
#include "gdkdisplayprivate.h"
|
||||
#include "gdkdndprivate.h"
|
||||
#include "gdkdragprivate.h"
|
||||
#include "gdkdropprivate.h"
|
||||
#include "gdk-private.h"
|
||||
|
||||
#include <string.h>
|
||||
@@ -164,14 +165,14 @@ gdk_event_class_init (GdkEventClass *klass)
|
||||
void
|
||||
_gdk_event_emit (GdkEvent *event)
|
||||
{
|
||||
if (gdk_drag_context_handle_source_event (event))
|
||||
if (gdk_drag_handle_source_event (event))
|
||||
return;
|
||||
|
||||
if (gdk_surface_handle_event (event))
|
||||
return;
|
||||
|
||||
if (_gdk_event_func)
|
||||
(*_gdk_event_func) (event, _gdk_event_data);
|
||||
|
||||
if (gdk_drag_context_handle_dest_event (event))
|
||||
return;
|
||||
}
|
||||
|
||||
/*********************************************
|
||||
@@ -630,11 +631,6 @@ gdk_event_copy (const GdkEvent *event)
|
||||
|
||||
switch ((guint) event->any.type)
|
||||
{
|
||||
case GDK_KEY_PRESS:
|
||||
case GDK_KEY_RELEASE:
|
||||
new_event->key.string = g_strdup (event->key.string);
|
||||
break;
|
||||
|
||||
case GDK_ENTER_NOTIFY:
|
||||
case GDK_LEAVE_NOTIFY:
|
||||
if (event->crossing.child_surface != NULL)
|
||||
@@ -645,12 +641,7 @@ gdk_event_copy (const GdkEvent *event)
|
||||
case GDK_DRAG_LEAVE:
|
||||
case GDK_DRAG_MOTION:
|
||||
case GDK_DROP_START:
|
||||
g_object_ref (event->dnd.context);
|
||||
break;
|
||||
|
||||
case GDK_EXPOSE:
|
||||
if (event->expose.region)
|
||||
new_event->expose.region = cairo_region_copy (event->expose.region);
|
||||
g_object_ref (event->dnd.drop);
|
||||
break;
|
||||
|
||||
case GDK_BUTTON_PRESS:
|
||||
@@ -702,11 +693,6 @@ gdk_event_finalize (GObject *object)
|
||||
|
||||
switch ((guint) event->any.type)
|
||||
{
|
||||
case GDK_KEY_PRESS:
|
||||
case GDK_KEY_RELEASE:
|
||||
g_free (event->key.string);
|
||||
break;
|
||||
|
||||
case GDK_ENTER_NOTIFY:
|
||||
case GDK_LEAVE_NOTIFY:
|
||||
g_clear_object (&event->crossing.child_surface);
|
||||
@@ -716,8 +702,7 @@ gdk_event_finalize (GObject *object)
|
||||
case GDK_DRAG_LEAVE:
|
||||
case GDK_DRAG_MOTION:
|
||||
case GDK_DROP_START:
|
||||
if (event->dnd.context != NULL)
|
||||
g_object_unref (event->dnd.context);
|
||||
g_clear_object (&event->dnd.drop);
|
||||
break;
|
||||
|
||||
case GDK_BUTTON_PRESS:
|
||||
@@ -733,11 +718,6 @@ gdk_event_finalize (GObject *object)
|
||||
g_free (event->touch.axes);
|
||||
break;
|
||||
|
||||
case GDK_EXPOSE:
|
||||
if (event->expose.region)
|
||||
cairo_region_destroy (event->expose.region);
|
||||
break;
|
||||
|
||||
case GDK_MOTION_NOTIFY:
|
||||
g_clear_object (&event->motion.tool);
|
||||
g_free (event->motion.axes);
|
||||
@@ -835,9 +815,6 @@ gdk_event_get_time (const GdkEvent *event)
|
||||
case GDK_NOTHING:
|
||||
case GDK_DELETE:
|
||||
case GDK_DESTROY:
|
||||
case GDK_EXPOSE:
|
||||
case GDK_MAP:
|
||||
case GDK_UNMAP:
|
||||
case GDK_GRAB_BROKEN:
|
||||
case GDK_EVENT_LAST:
|
||||
default:
|
||||
@@ -911,9 +888,6 @@ gdk_event_get_state (const GdkEvent *event,
|
||||
case GDK_NOTHING:
|
||||
case GDK_DELETE:
|
||||
case GDK_DESTROY:
|
||||
case GDK_EXPOSE:
|
||||
case GDK_MAP:
|
||||
case GDK_UNMAP:
|
||||
case GDK_GRAB_BROKEN:
|
||||
case GDK_PAD_BUTTON_PRESS:
|
||||
case GDK_PAD_BUTTON_RELEASE:
|
||||
@@ -1309,37 +1283,6 @@ gdk_event_get_key_group (const GdkEvent *event,
|
||||
return fetched;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_event_get_string:
|
||||
* @event: a #GdkEvent
|
||||
* @string: (out) (transfer none): return location for the string
|
||||
*
|
||||
* Extracts a string from an event. The string is an
|
||||
* approximation of the keyval in a key event.
|
||||
*
|
||||
* Returns: %TRUE on success, otherwise %FALSE
|
||||
**/
|
||||
gboolean
|
||||
gdk_event_get_string (const GdkEvent *event,
|
||||
const char **string)
|
||||
{
|
||||
gboolean fetched = TRUE;
|
||||
|
||||
switch ((guint) event->any.type)
|
||||
{
|
||||
case GDK_KEY_PRESS:
|
||||
case GDK_KEY_RELEASE:
|
||||
*string = event->key.string;
|
||||
break;
|
||||
default:
|
||||
*string = NULL;
|
||||
fetched = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
return fetched;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_event_get_key_is_modifier:
|
||||
* @event: a #GdkEvent
|
||||
@@ -2061,17 +2004,15 @@ gdk_event_is_sent (const GdkEvent *event)
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_event_get_drag_context:
|
||||
* gdk_event_get_drop:
|
||||
* @event: a #GdkEvent
|
||||
* @context: (out) (transfer none): return location for the drag context
|
||||
*
|
||||
* Gets the drag context from a DND event.
|
||||
* Gets the #GdkDrop from a DND event.
|
||||
*
|
||||
* Returns: %TRUE on success, otherwise %FALSE
|
||||
* Returns: (transfer none) (nullable): the drop
|
||||
**/
|
||||
gboolean
|
||||
gdk_event_get_drag_context (const GdkEvent *event,
|
||||
GdkDragContext **context)
|
||||
GdkDrop *
|
||||
gdk_event_get_drop (const GdkEvent *event)
|
||||
{
|
||||
if (!event)
|
||||
return FALSE;
|
||||
@@ -2081,11 +2022,10 @@ gdk_event_get_drag_context (const GdkEvent *event,
|
||||
event->any.type == GDK_DRAG_MOTION ||
|
||||
event->any.type == GDK_DROP_START)
|
||||
{
|
||||
*context = event->dnd.context;
|
||||
return TRUE;
|
||||
return event->dnd.drop;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2510,8 +2450,6 @@ gdk_event_get_axes (GdkEvent *event,
|
||||
*
|
||||
* Returns: (transfer container) (element-type GdkTimeCoord) (nullable): a list
|
||||
* of time and coordinates
|
||||
*
|
||||
* Since: 3.94
|
||||
*/
|
||||
GList *
|
||||
gdk_event_get_motion_history (const GdkEvent *event)
|
||||
|
||||
+3
-25
@@ -31,7 +31,7 @@
|
||||
|
||||
#include <gdk/gdkversionmacros.h>
|
||||
#include <gdk/gdktypes.h>
|
||||
#include <gdk/gdkdnd.h>
|
||||
#include <gdk/gdkdrag.h>
|
||||
#include <gdk/gdkdevice.h>
|
||||
#include <gdk/gdkdevicetool.h>
|
||||
|
||||
@@ -67,8 +67,6 @@ G_BEGIN_DECLS
|
||||
*
|
||||
* Use this macro as the return value for continuing the propagation of
|
||||
* an event handler.
|
||||
*
|
||||
* Since: 3.4
|
||||
*/
|
||||
#define GDK_EVENT_PROPAGATE (FALSE)
|
||||
|
||||
@@ -77,8 +75,6 @@ G_BEGIN_DECLS
|
||||
*
|
||||
* Use this macro as the return value for stopping the propagation of
|
||||
* an event handler.
|
||||
*
|
||||
* Since: 3.4
|
||||
*/
|
||||
#define GDK_EVENT_STOP (TRUE)
|
||||
|
||||
@@ -87,8 +83,6 @@ G_BEGIN_DECLS
|
||||
*
|
||||
* The primary button. This is typically the left mouse button, or the
|
||||
* right button in a left-handed setup.
|
||||
*
|
||||
* Since: 3.4
|
||||
*/
|
||||
#define GDK_BUTTON_PRIMARY (1)
|
||||
|
||||
@@ -96,8 +90,6 @@ G_BEGIN_DECLS
|
||||
* GDK_BUTTON_MIDDLE:
|
||||
*
|
||||
* The middle button.
|
||||
*
|
||||
* Since: 3.4
|
||||
*/
|
||||
#define GDK_BUTTON_MIDDLE (2)
|
||||
|
||||
@@ -106,15 +98,12 @@ G_BEGIN_DECLS
|
||||
*
|
||||
* The secondary button. This is typically the right mouse button, or the
|
||||
* left button in a left-handed setup.
|
||||
*
|
||||
* Since: 3.4
|
||||
*/
|
||||
#define GDK_BUTTON_SECONDARY (3)
|
||||
|
||||
|
||||
|
||||
typedef struct _GdkEventAny GdkEventAny;
|
||||
typedef struct _GdkEventExpose GdkEventExpose;
|
||||
typedef struct _GdkEventMotion GdkEventMotion;
|
||||
typedef struct _GdkEventButton GdkEventButton;
|
||||
typedef struct _GdkEventTouch GdkEventTouch;
|
||||
@@ -155,8 +144,6 @@ typedef void (*GdkEventFunc) (GdkEvent *event,
|
||||
* hidden or destroyed, usually when the user clicks on a special icon in the
|
||||
* title bar.
|
||||
* @GDK_DESTROY: the surface has been destroyed.
|
||||
* @GDK_EXPOSE: all or part of the surface has become visible and needs to be
|
||||
* redrawn.
|
||||
* @GDK_MOTION_NOTIFY: the pointer (usually a mouse) has moved.
|
||||
* @GDK_BUTTON_PRESS: a mouse button has been pressed.
|
||||
* @GDK_BUTTON_RELEASE: a mouse button has been released.
|
||||
@@ -167,8 +154,6 @@ typedef void (*GdkEventFunc) (GdkEvent *event,
|
||||
* @GDK_FOCUS_CHANGE: the keyboard focus has entered or left the surface.
|
||||
* @GDK_CONFIGURE: the size, position or stacking order of the surface has changed.
|
||||
* Note that GTK+ discards these events for %GDK_SURFACE_CHILD surfaces.
|
||||
* @GDK_MAP: the surface has been mapped.
|
||||
* @GDK_UNMAP: the surface has been unmapped.
|
||||
* @GDK_PROXIMITY_IN: an input device has moved into contact with a sensing
|
||||
* surface (e.g. a touchscreen or graphics tablet).
|
||||
* @GDK_PROXIMITY_OUT: an input device has moved out of contact with a sensing
|
||||
@@ -216,7 +201,6 @@ typedef enum
|
||||
GDK_NOTHING,
|
||||
GDK_DELETE,
|
||||
GDK_DESTROY,
|
||||
GDK_EXPOSE,
|
||||
GDK_MOTION_NOTIFY,
|
||||
GDK_BUTTON_PRESS,
|
||||
GDK_BUTTON_RELEASE,
|
||||
@@ -226,8 +210,6 @@ typedef enum
|
||||
GDK_LEAVE_NOTIFY,
|
||||
GDK_FOCUS_CHANGE,
|
||||
GDK_CONFIGURE,
|
||||
GDK_MAP,
|
||||
GDK_UNMAP,
|
||||
GDK_PROXIMITY_IN,
|
||||
GDK_PROXIMITY_OUT,
|
||||
GDK_DRAG_ENTER,
|
||||
@@ -291,7 +273,7 @@ typedef enum
|
||||
* @GDK_SCROLL_LEFT: the surface is scrolled to the left.
|
||||
* @GDK_SCROLL_RIGHT: the surface is scrolled to the right.
|
||||
* @GDK_SCROLL_SMOOTH: the scrolling is determined by the delta values
|
||||
* in scroll events. See gdk_event_get_scroll_deltas(). Since: 3.4
|
||||
* in scroll events. See gdk_event_get_scroll_deltas()
|
||||
*
|
||||
* Specifies the direction for scroll events.
|
||||
*/
|
||||
@@ -421,9 +403,6 @@ gboolean gdk_event_get_key_is_modifier (const GdkEvent *event,
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gdk_event_get_key_group (const GdkEvent *event,
|
||||
guint *group);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gdk_event_get_string (const GdkEvent *event,
|
||||
const char **string);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gdk_event_get_scroll_direction (const GdkEvent *event,
|
||||
@@ -513,8 +492,7 @@ GDK_AVAILABLE_IN_ALL
|
||||
gboolean gdk_event_is_sent (const GdkEvent *event);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gdk_event_get_drag_context (const GdkEvent *event,
|
||||
GdkDragContext **context);
|
||||
GdkDrop * gdk_event_get_drop (const GdkEvent *event);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gdk_event_get_crossing_mode (const GdkEvent *event,
|
||||
|
||||
+4
-45
@@ -26,7 +26,7 @@
|
||||
#define __GDK_EVENTS_PRIVATE_H__
|
||||
|
||||
#include <gdk/gdktypes.h>
|
||||
#include <gdk/gdkdnd.h>
|
||||
#include <gdk/gdkdrag.h>
|
||||
#include <gdk/gdkdevice.h>
|
||||
#include <gdk/gdkdevicetool.h>
|
||||
|
||||
@@ -63,23 +63,6 @@ struct _GdkEventAny
|
||||
GdkDisplay *display;
|
||||
};
|
||||
|
||||
/*
|
||||
* GdkEventExpose:
|
||||
* @type: the type of the event (%GDK_EXPOSE)
|
||||
* @surface: the surface which received the event.
|
||||
* @send_event: %TRUE if the event was sent explicitly.
|
||||
* @area: bounding box of @region.
|
||||
* @region: the region that needs to be redrawn.
|
||||
*
|
||||
* Generated when all or part of a surface becomes visible and needs to be
|
||||
* redrawn.
|
||||
*/
|
||||
struct _GdkEventExpose
|
||||
{
|
||||
GdkEventAny any;
|
||||
cairo_region_t *region;
|
||||
};
|
||||
|
||||
/*
|
||||
* GdkEventMotion:
|
||||
* @type: the type of the event.
|
||||
@@ -261,22 +244,10 @@ struct _GdkEventScroll
|
||||
* @keyval: the key that was pressed or released. See the
|
||||
* `gdk/gdkkeysyms.h` header file for a
|
||||
* complete list of GDK key codes.
|
||||
* @length: the length of @string.
|
||||
* @string: a string containing an approximation of the text that
|
||||
* would result from this keypress. The only correct way to handle text
|
||||
* input of text is using input methods (see #GtkIMContext), so this
|
||||
* field is deprecated and should never be used.
|
||||
* (gdk_unicode_to_keyval() provides a non-deprecated way of getting
|
||||
* an approximate translation for a key.) The string is encoded in the
|
||||
* encoding of the current locale (Note: this for backwards compatibility:
|
||||
* strings in GTK+ and GDK are typically in UTF-8.) and NUL-terminated.
|
||||
* In some cases, the translation of the key code will be a single
|
||||
* NUL byte, in which case looking at @length is necessary to distinguish
|
||||
* it from the an empty translation.
|
||||
* @hardware_keycode: the raw code of the key that was pressed or released.
|
||||
* @group: the keyboard group.
|
||||
* @is_modifier: a flag that indicates if @hardware_keycode is mapped to a
|
||||
* modifier. Since 2.10
|
||||
* modifier
|
||||
*
|
||||
* Describes a key press or key release event.
|
||||
*/
|
||||
@@ -286,8 +257,6 @@ struct _GdkEventKey
|
||||
guint32 time;
|
||||
guint state;
|
||||
guint keyval;
|
||||
gint length;
|
||||
gchar *string;
|
||||
guint16 hardware_keycode;
|
||||
guint16 key_scancode;
|
||||
guint8 group;
|
||||
@@ -414,8 +383,6 @@ struct _GdkEventProximity
|
||||
* is unmapped), or if the same application grabs the pointer or keyboard
|
||||
* again. Note that implicit grabs (which are initiated by button presses)
|
||||
* can also cause #GdkEventGrabBroken events.
|
||||
*
|
||||
* Since: 2.8
|
||||
*/
|
||||
struct _GdkEventGrabBroken {
|
||||
GdkEventAny any;
|
||||
@@ -430,7 +397,7 @@ struct _GdkEventGrabBroken {
|
||||
* %GDK_DRAG_MOTION or %GDK_DROP_START)
|
||||
* @surface: the surface which received the event.
|
||||
* @send_event: %TRUE if the event was sent explicitly.
|
||||
* @context: the #GdkDragContext for the current DND operation.
|
||||
* @drop: the #GdkDrop for the current DND operation.
|
||||
* @time: the time of the event in milliseconds.
|
||||
* @x_root: the x coordinate of the pointer relative to the root of the
|
||||
* screen, only set for %GDK_DRAG_MOTION and %GDK_DROP_START.
|
||||
@@ -441,7 +408,7 @@ struct _GdkEventGrabBroken {
|
||||
*/
|
||||
struct _GdkEventDND {
|
||||
GdkEventAny any;
|
||||
GdkDragContext *context;
|
||||
GdkDrop *drop;
|
||||
|
||||
guint32 time;
|
||||
gshort x_root, y_root;
|
||||
@@ -536,8 +503,6 @@ struct _GdkEventTouchpadPinch {
|
||||
* device may have different current modes.
|
||||
*
|
||||
* Generated during %GDK_SOURCE_TABLET_PAD button presses and releases.
|
||||
*
|
||||
* Since: 3.22
|
||||
*/
|
||||
struct _GdkEventPadButton {
|
||||
GdkEventAny any;
|
||||
@@ -562,8 +527,6 @@ struct _GdkEventPadButton {
|
||||
* @value: The current value for the given axis.
|
||||
*
|
||||
* Generated during %GDK_SOURCE_TABLET_PAD interaction with tactile sensors.
|
||||
*
|
||||
* Since: 3.22
|
||||
*/
|
||||
struct _GdkEventPadAxis {
|
||||
GdkEventAny any;
|
||||
@@ -587,8 +550,6 @@ struct _GdkEventPadAxis {
|
||||
* device may have different current modes.
|
||||
*
|
||||
* Generated during %GDK_SOURCE_TABLET_PAD mode switches in a group.
|
||||
*
|
||||
* Since: 3.22
|
||||
*/
|
||||
struct _GdkEventPadGroupMode {
|
||||
GdkEventAny any;
|
||||
@@ -601,7 +562,6 @@ struct _GdkEventPadGroupMode {
|
||||
* GdkEvent:
|
||||
* @type: the #GdkEventType
|
||||
* @any: a #GdkEventAny
|
||||
* @expose: a #GdkEventExpose
|
||||
* @motion: a #GdkEventMotion
|
||||
* @button: a #GdkEventButton
|
||||
* @touch: a #GdkEventTouch
|
||||
@@ -653,7 +613,6 @@ struct _GdkEventPadGroupMode {
|
||||
union _GdkEvent
|
||||
{
|
||||
GdkEventAny any;
|
||||
GdkEventExpose expose;
|
||||
GdkEventMotion motion;
|
||||
GdkEventButton button;
|
||||
GdkEventTouch touch;
|
||||
|
||||
@@ -58,8 +58,6 @@ typedef struct _GdkFrameClockClass GdkFrameClockClass;
|
||||
* #GdkFrameClockPhase is used to represent the different paint clock
|
||||
* phases that can be requested. The elements of the enumeration
|
||||
* correspond to the signals of #GdkFrameClock.
|
||||
*
|
||||
* Since: 3.8
|
||||
**/
|
||||
typedef enum {
|
||||
GDK_FRAME_CLOCK_PHASE_NONE = 0,
|
||||
|
||||
+3
-3
@@ -32,7 +32,7 @@
|
||||
#include "gdkdisplay.h"
|
||||
#include "gdkeventsprivate.h"
|
||||
#include "gdkenumtypes.h"
|
||||
#include "gdkdndprivate.h"
|
||||
#include "gdkdragprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@@ -150,7 +150,6 @@ struct _GdkSurface
|
||||
gint x;
|
||||
gint y;
|
||||
|
||||
GdkEventMask event_mask;
|
||||
guint8 surface_type;
|
||||
|
||||
guint8 resize_count;
|
||||
@@ -206,7 +205,6 @@ struct _GdkSurface
|
||||
cairo_region_t *input_shape;
|
||||
|
||||
GList *devices_inside;
|
||||
GHashTable *device_events;
|
||||
|
||||
GdkFrameClock *frame_clock; /* NULL to use from parent or default */
|
||||
|
||||
@@ -293,6 +291,8 @@ GdkGLContext * gdk_surface_get_paint_gl_context (GdkSurface *surface,
|
||||
void gdk_surface_get_unscaled_size (GdkSurface *surface,
|
||||
int *unscaled_width,
|
||||
int *unscaled_height);
|
||||
gboolean gdk_surface_handle_event (GdkEvent *event);
|
||||
|
||||
|
||||
/*****************************************
|
||||
* Interfaces provided by windowing code *
|
||||
|
||||
@@ -50,8 +50,6 @@ typedef struct _GdkMonitorClass GdkMonitorClass;
|
||||
*
|
||||
* This enumeration describes how the red, green and blue components
|
||||
* of physical pixels on an output device are laid out.
|
||||
*
|
||||
* Since: 3.22
|
||||
*/
|
||||
typedef enum {
|
||||
GDK_SUBPIXEL_LAYOUT_UNKNOWN,
|
||||
|
||||
+2
-2
@@ -643,8 +643,8 @@ gdk_paintable_new_empty (int intrinsic_width,
|
||||
{
|
||||
GdkEmptyPaintable *result;
|
||||
|
||||
g_return_val_if_fail (intrinsic_width < 0, NULL);
|
||||
g_return_val_if_fail (intrinsic_height < 0, NULL);
|
||||
g_return_val_if_fail (intrinsic_width >= 0, NULL);
|
||||
g_return_val_if_fail (intrinsic_height >= 0, NULL);
|
||||
|
||||
result = g_object_new (GDK_TYPE_EMPTY_PAINTABLE, NULL);
|
||||
|
||||
|
||||
@@ -47,8 +47,6 @@ G_BEGIN_DECLS
|
||||
* @GDK_SEAT_CAPABILITY_ALL: The union of all capabilities
|
||||
*
|
||||
* Flags describing the seat capabilities.
|
||||
*
|
||||
* Since: 3.20
|
||||
*/
|
||||
typedef enum {
|
||||
GDK_SEAT_CAPABILITY_NONE = 0,
|
||||
@@ -71,8 +69,6 @@ typedef enum {
|
||||
* grabbed. A typical action would be ensuring the surface is
|
||||
* visible, although there's room for other initialization
|
||||
* actions.
|
||||
*
|
||||
* Since: 3.20
|
||||
*/
|
||||
typedef void (* GdkSeatGrabPrepareFunc) (GdkSeat *seat,
|
||||
GdkSurface *surface,
|
||||
|
||||
+145
-400
@@ -97,6 +97,8 @@
|
||||
|
||||
enum {
|
||||
MOVED_TO_RECT,
|
||||
SIZE_CHANGED,
|
||||
RENDER,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
@@ -105,6 +107,7 @@ enum {
|
||||
PROP_CURSOR,
|
||||
PROP_DISPLAY,
|
||||
PROP_STATE,
|
||||
PROP_MAPPED,
|
||||
LAST_PROP
|
||||
};
|
||||
|
||||
@@ -271,6 +274,13 @@ gdk_surface_class_init (GdkSurfaceClass *klass)
|
||||
GDK_TYPE_SURFACE_STATE, GDK_SURFACE_STATE_WITHDRAWN,
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
properties[PROP_MAPPED] =
|
||||
g_param_spec_boolean ("mapped",
|
||||
P_("Mapped"),
|
||||
P_("Mapped"),
|
||||
FALSE,
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
g_object_class_install_properties (object_class, LAST_PROP, properties);
|
||||
|
||||
/**
|
||||
@@ -310,6 +320,31 @@ gdk_surface_class_init (GdkSurfaceClass *klass)
|
||||
G_TYPE_POINTER,
|
||||
G_TYPE_BOOLEAN,
|
||||
G_TYPE_BOOLEAN);
|
||||
|
||||
signals[SIZE_CHANGED] =
|
||||
g_signal_new (g_intern_static_string ("size-changed"),
|
||||
G_OBJECT_CLASS_TYPE (object_class),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
G_TYPE_NONE,
|
||||
2,
|
||||
G_TYPE_INT,
|
||||
G_TYPE_INT);
|
||||
|
||||
signals[RENDER] =
|
||||
g_signal_new (g_intern_static_string ("render"),
|
||||
G_OBJECT_CLASS_TYPE (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0,
|
||||
g_signal_accumulator_true_handled,
|
||||
NULL,
|
||||
NULL,
|
||||
G_TYPE_BOOLEAN,
|
||||
1,
|
||||
CAIRO_GOBJECT_TYPE_REGION);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -321,9 +356,6 @@ seat_removed_cb (GdkDisplay *display,
|
||||
|
||||
surface->devices_inside = g_list_remove (surface->devices_inside, device);
|
||||
g_hash_table_remove (surface->device_cursor, device);
|
||||
|
||||
if (surface->device_events)
|
||||
g_hash_table_remove (surface->device_events, device);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -336,16 +368,8 @@ gdk_surface_finalize (GObject *object)
|
||||
|
||||
if (!GDK_SURFACE_DESTROYED (surface))
|
||||
{
|
||||
if (GDK_SURFACE_TYPE (surface) != GDK_SURFACE_FOREIGN)
|
||||
{
|
||||
g_warning ("losing last reference to undestroyed surface");
|
||||
_gdk_surface_destroy (surface, FALSE);
|
||||
}
|
||||
else
|
||||
/* We use TRUE here, to keep us from actually calling
|
||||
* XDestroyWindow() on the window
|
||||
*/
|
||||
_gdk_surface_destroy (surface, TRUE);
|
||||
g_warning ("losing last reference to undestroyed surface");
|
||||
_gdk_surface_destroy (surface, FALSE);
|
||||
}
|
||||
|
||||
if (surface->impl)
|
||||
@@ -369,9 +393,6 @@ gdk_surface_finalize (GObject *object)
|
||||
if (surface->device_cursor)
|
||||
g_hash_table_destroy (surface->device_cursor);
|
||||
|
||||
if (surface->device_events)
|
||||
g_hash_table_destroy (surface->device_events);
|
||||
|
||||
if (surface->devices_inside)
|
||||
g_list_free (surface->devices_inside);
|
||||
|
||||
@@ -430,18 +451,16 @@ gdk_surface_get_property (GObject *object,
|
||||
g_value_set_flags (value, surface->state);
|
||||
break;
|
||||
|
||||
case PROP_MAPPED:
|
||||
g_value_set_boolean (value, GDK_SURFACE_IS_MAPPED (surface));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_surface_is_subsurface (GdkSurface *surface)
|
||||
{
|
||||
return surface->surface_type == GDK_SURFACE_SUBSURFACE;
|
||||
}
|
||||
|
||||
static GdkSurface *
|
||||
gdk_surface_get_impl_surface (GdkSurface *surface)
|
||||
{
|
||||
@@ -530,10 +549,7 @@ recompute_visible_regions_internal (GdkSurface *private,
|
||||
old_abs_y = private->abs_y;
|
||||
|
||||
/* Update absolute position */
|
||||
if ((gdk_surface_has_impl (private) &&
|
||||
private->surface_type != GDK_SURFACE_SUBSURFACE) ||
|
||||
(gdk_surface_is_toplevel (private) &&
|
||||
private->surface_type == GDK_SURFACE_SUBSURFACE))
|
||||
if (gdk_surface_has_impl (private))
|
||||
{
|
||||
/* Native surfaces and toplevel subsurfaces start here */
|
||||
private->abs_x = 0;
|
||||
@@ -601,45 +617,6 @@ _gdk_surface_update_size (GdkSurface *surface)
|
||||
recompute_visible_regions (surface, FALSE);
|
||||
}
|
||||
|
||||
static GdkEventMask
|
||||
get_native_device_event_mask (GdkSurface *private,
|
||||
GdkDevice *device)
|
||||
{
|
||||
GdkEventMask event_mask;
|
||||
|
||||
if (device)
|
||||
event_mask = GPOINTER_TO_INT (g_hash_table_lookup (private->device_events, device));
|
||||
else
|
||||
event_mask = private->event_mask;
|
||||
|
||||
if (private->surface_type == GDK_SURFACE_FOREIGN)
|
||||
return event_mask;
|
||||
else
|
||||
{
|
||||
GdkEventMask mask;
|
||||
|
||||
mask = private->event_mask;
|
||||
|
||||
/* We need thse for all native surfaces so we can
|
||||
emulate events on children: */
|
||||
mask |=
|
||||
GDK_EXPOSURE_MASK |
|
||||
GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK |
|
||||
GDK_TOUCH_MASK |
|
||||
GDK_POINTER_MOTION_MASK |
|
||||
GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
|
||||
GDK_SCROLL_MASK;
|
||||
|
||||
return mask;
|
||||
}
|
||||
}
|
||||
|
||||
static GdkEventMask
|
||||
get_native_event_mask (GdkSurface *private)
|
||||
{
|
||||
return get_native_device_event_mask (private, NULL);
|
||||
}
|
||||
|
||||
GdkSurface*
|
||||
gdk_surface_new (GdkDisplay *display,
|
||||
GdkSurface *parent,
|
||||
@@ -647,7 +624,6 @@ gdk_surface_new (GdkDisplay *display,
|
||||
{
|
||||
GdkSurface *surface;
|
||||
gboolean native;
|
||||
GdkEventMask event_mask;
|
||||
|
||||
g_return_val_if_fail (attributes != NULL, NULL);
|
||||
|
||||
@@ -692,30 +668,13 @@ gdk_surface_new (GdkDisplay *display,
|
||||
if (parent != NULL)
|
||||
g_warning (G_STRLOC "Toplevel surfaces must be created without a parent");
|
||||
break;
|
||||
case GDK_SURFACE_SUBSURFACE:
|
||||
#ifdef GDK_WINDOWING_WAYLAND
|
||||
if (!GDK_IS_WAYLAND_DISPLAY (display))
|
||||
{
|
||||
g_warning (G_STRLOC "Subsurface surfaces can only be used on Wayland");
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case GDK_SURFACE_CHILD:
|
||||
if (GDK_SURFACE_TYPE (parent) == GDK_SURFACE_FOREIGN)
|
||||
{
|
||||
g_warning (G_STRLOC "Child surfaces must not be created as children of\n"
|
||||
"a surface of type GDK_SURFACE_FOREIGN");
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
g_warning (G_STRLOC "cannot make surfaces of type %d", surface->surface_type);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
surface->event_mask = GDK_ALL_EVENTS_MASK;
|
||||
|
||||
if (attributes->wclass == GDK_INPUT_OUTPUT)
|
||||
{
|
||||
surface->input_only = FALSE;
|
||||
@@ -738,17 +697,10 @@ gdk_surface_new (GdkDisplay *display,
|
||||
native = TRUE; /* Always use native surfaces for toplevels */
|
||||
}
|
||||
|
||||
#ifdef GDK_WINDOWING_WAYLAND
|
||||
if (surface->surface_type == GDK_SURFACE_SUBSURFACE)
|
||||
native = TRUE; /* Always use native windows for subsurfaces as well */
|
||||
#endif
|
||||
|
||||
if (native)
|
||||
{
|
||||
event_mask = get_native_event_mask (surface);
|
||||
|
||||
/* Create the impl */
|
||||
_gdk_display_create_surface_impl (display, surface, parent, event_mask, attributes);
|
||||
gdk_display_create_surface_impl (display, surface, parent, attributes);
|
||||
surface->impl_surface = surface;
|
||||
}
|
||||
else
|
||||
@@ -947,81 +899,69 @@ _gdk_surface_destroy_hierarchy (GdkSurface *surface,
|
||||
case GDK_SURFACE_TOPLEVEL:
|
||||
case GDK_SURFACE_CHILD:
|
||||
case GDK_SURFACE_TEMP:
|
||||
case GDK_SURFACE_FOREIGN:
|
||||
case GDK_SURFACE_SUBSURFACE:
|
||||
if (surface->surface_type == GDK_SURFACE_FOREIGN && !foreign_destroy)
|
||||
if (surface->parent)
|
||||
{
|
||||
if (surface->parent->children)
|
||||
surface->parent->children = g_list_remove_link (surface->parent->children, &surface->children_list_node);
|
||||
|
||||
if (!recursing &&
|
||||
GDK_SURFACE_IS_MAPPED (surface))
|
||||
{
|
||||
recompute_visible_regions (surface, FALSE);
|
||||
gdk_surface_invalidate_in_parent (surface);
|
||||
}
|
||||
}
|
||||
|
||||
if (surface->gl_paint_context)
|
||||
{
|
||||
/* Make sure to destroy if current */
|
||||
g_object_run_dispose (G_OBJECT (surface->gl_paint_context));
|
||||
g_object_unref (surface->gl_paint_context);
|
||||
surface->gl_paint_context = NULL;
|
||||
}
|
||||
|
||||
if (surface->frame_clock)
|
||||
{
|
||||
g_object_run_dispose (G_OBJECT (surface->frame_clock));
|
||||
gdk_surface_set_frame_clock (surface, NULL);
|
||||
}
|
||||
|
||||
tmp = surface->children;
|
||||
surface->children = NULL;
|
||||
/* No need to free children list, its all made up of in-struct nodes */
|
||||
|
||||
while (tmp)
|
||||
{
|
||||
temp_surface = tmp->data;
|
||||
tmp = tmp->next;
|
||||
|
||||
if (temp_surface)
|
||||
_gdk_surface_destroy_hierarchy (temp_surface,
|
||||
TRUE,
|
||||
recursing_native || gdk_surface_has_impl (surface),
|
||||
foreign_destroy);
|
||||
}
|
||||
|
||||
_gdk_surface_clear_update_area (surface);
|
||||
|
||||
impl_class = GDK_SURFACE_IMPL_GET_CLASS (surface->impl);
|
||||
|
||||
if (gdk_surface_has_impl (surface))
|
||||
impl_class->destroy (surface, recursing_native, foreign_destroy);
|
||||
else
|
||||
{
|
||||
if (surface->parent)
|
||||
{
|
||||
if (surface->parent->children)
|
||||
surface->parent->children = g_list_remove_link (surface->parent->children, &surface->children_list_node);
|
||||
|
||||
if (!recursing &&
|
||||
GDK_SURFACE_IS_MAPPED (surface))
|
||||
{
|
||||
recompute_visible_regions (surface, FALSE);
|
||||
gdk_surface_invalidate_in_parent (surface);
|
||||
}
|
||||
}
|
||||
|
||||
if (surface->gl_paint_context)
|
||||
{
|
||||
/* Make sure to destroy if current */
|
||||
g_object_run_dispose (G_OBJECT (surface->gl_paint_context));
|
||||
g_object_unref (surface->gl_paint_context);
|
||||
surface->gl_paint_context = NULL;
|
||||
}
|
||||
|
||||
if (surface->frame_clock)
|
||||
{
|
||||
g_object_run_dispose (G_OBJECT (surface->frame_clock));
|
||||
gdk_surface_set_frame_clock (surface, NULL);
|
||||
}
|
||||
|
||||
if (surface->surface_type == GDK_SURFACE_FOREIGN)
|
||||
g_assert (surface->children == NULL);
|
||||
else
|
||||
{
|
||||
tmp = surface->children;
|
||||
surface->children = NULL;
|
||||
/* No need to free children list, its all made up of in-struct nodes */
|
||||
|
||||
while (tmp)
|
||||
{
|
||||
temp_surface = tmp->data;
|
||||
tmp = tmp->next;
|
||||
|
||||
if (temp_surface)
|
||||
_gdk_surface_destroy_hierarchy (temp_surface,
|
||||
TRUE,
|
||||
recursing_native || gdk_surface_has_impl (surface),
|
||||
foreign_destroy);
|
||||
}
|
||||
}
|
||||
|
||||
_gdk_surface_clear_update_area (surface);
|
||||
|
||||
impl_class = GDK_SURFACE_IMPL_GET_CLASS (surface->impl);
|
||||
|
||||
if (gdk_surface_has_impl (surface))
|
||||
impl_class->destroy (surface, recursing_native, foreign_destroy);
|
||||
else
|
||||
{
|
||||
/* hide to make sure we repaint and break grabs */
|
||||
gdk_surface_hide (surface);
|
||||
}
|
||||
|
||||
surface->state |= GDK_SURFACE_STATE_WITHDRAWN;
|
||||
surface->parent = NULL;
|
||||
surface->destroyed = TRUE;
|
||||
|
||||
surface_remove_from_pointer_info (surface, display);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (surface), properties[PROP_STATE]);
|
||||
/* hide to make sure we repaint and break grabs */
|
||||
gdk_surface_hide (surface);
|
||||
}
|
||||
|
||||
surface->state |= GDK_SURFACE_STATE_WITHDRAWN;
|
||||
surface->parent = NULL;
|
||||
surface->destroyed = TRUE;
|
||||
|
||||
surface_remove_from_pointer_info (surface, display);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (surface), properties[PROP_STATE]);
|
||||
g_object_notify_by_pspec (G_OBJECT (surface), properties[PROP_MAPPED]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1209,10 +1149,7 @@ gdk_surface_get_parent (GdkSurface *surface)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_SURFACE (surface), NULL);
|
||||
|
||||
if (gdk_surface_is_subsurface (surface))
|
||||
return surface->transient_for;
|
||||
else
|
||||
return surface->parent;
|
||||
return surface->parent;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1232,8 +1169,7 @@ gdk_surface_get_toplevel (GdkSurface *surface)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_SURFACE (surface), NULL);
|
||||
|
||||
while (surface->surface_type == GDK_SURFACE_CHILD ||
|
||||
surface->surface_type == GDK_SURFACE_SUBSURFACE)
|
||||
while (surface->surface_type == GDK_SURFACE_CHILD)
|
||||
{
|
||||
if (gdk_surface_is_toplevel (surface))
|
||||
break;
|
||||
@@ -1693,20 +1629,13 @@ static void
|
||||
gdk_surface_process_updates_recurse (GdkSurface *surface,
|
||||
cairo_region_t *expose_region)
|
||||
{
|
||||
GdkEvent *event;
|
||||
gboolean handled;
|
||||
|
||||
if (surface->destroyed)
|
||||
return;
|
||||
|
||||
/* Paint the surface before the children, clipped to the surface region */
|
||||
|
||||
event = gdk_event_new (GDK_EXPOSE);
|
||||
event->any.surface = g_object_ref (surface);
|
||||
event->any.send_event = FALSE;
|
||||
event->expose.region = cairo_region_reference (expose_region);
|
||||
|
||||
_gdk_event_emit (event);
|
||||
g_object_unref (event);
|
||||
g_signal_emit (surface, signals[RENDER], 0, expose_region, &handled);
|
||||
}
|
||||
|
||||
/* Process and remove any invalid area on the native surface by creating
|
||||
@@ -2285,10 +2214,8 @@ _gdk_surface_update_viewable (GdkSurface *surface)
|
||||
{
|
||||
gboolean viewable;
|
||||
|
||||
if (surface->surface_type == GDK_SURFACE_FOREIGN)
|
||||
viewable = TRUE;
|
||||
else if (gdk_surface_is_toplevel (surface) ||
|
||||
surface->parent->viewable)
|
||||
if (gdk_surface_is_toplevel (surface) ||
|
||||
surface->parent->viewable)
|
||||
viewable = GDK_SURFACE_IS_MAPPED (surface);
|
||||
else
|
||||
viewable = FALSE;
|
||||
@@ -2328,6 +2255,7 @@ gdk_surface_show_internal (GdkSurface *surface, gboolean raise)
|
||||
{
|
||||
surface->state = 0;
|
||||
g_object_notify_by_pspec (G_OBJECT (surface), properties[PROP_STATE]);
|
||||
g_object_notify_by_pspec (G_OBJECT (surface), properties[PROP_MAPPED]);
|
||||
}
|
||||
|
||||
did_show = _gdk_surface_update_viewable (surface);
|
||||
@@ -2343,15 +2271,6 @@ gdk_surface_show_internal (GdkSurface *surface, gboolean raise)
|
||||
impl_class->show (surface, !did_show ? was_mapped : TRUE);
|
||||
}
|
||||
|
||||
if (!was_mapped && !gdk_surface_has_impl (surface))
|
||||
{
|
||||
if (surface->event_mask & GDK_STRUCTURE_MASK)
|
||||
_gdk_make_event (surface, GDK_MAP, NULL, FALSE);
|
||||
|
||||
if (surface->parent && surface->parent->event_mask & GDK_SUBSTRUCTURE_MASK)
|
||||
_gdk_make_event (surface, GDK_MAP, NULL, FALSE);
|
||||
}
|
||||
|
||||
if (!was_mapped || did_raise)
|
||||
{
|
||||
recompute_visible_regions (surface, FALSE);
|
||||
@@ -2387,7 +2306,7 @@ gdk_surface_show_unraised (GdkSurface *surface)
|
||||
* other surfaces with the same parent surface appear below @surface.
|
||||
* This is true whether or not the surfaces are visible.
|
||||
*
|
||||
* If @surface is a toplevel, the surface manager may choose to deny the
|
||||
* If @surface is a toplevel, the window manager may choose to deny the
|
||||
* request to move the surface in the Z-order, gdk_surface_raise() only
|
||||
* requests the restack, does not guarantee it.
|
||||
*/
|
||||
@@ -2608,6 +2527,7 @@ gdk_surface_hide (GdkSurface *surface)
|
||||
{
|
||||
surface->state = GDK_SURFACE_STATE_WITHDRAWN;
|
||||
g_object_notify_by_pspec (G_OBJECT (surface), properties[PROP_STATE]);
|
||||
g_object_notify_by_pspec (G_OBJECT (surface), properties[PROP_MAPPED]);
|
||||
}
|
||||
|
||||
if (was_mapped)
|
||||
@@ -2654,198 +2574,11 @@ G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
|
||||
recompute_visible_regions (surface, FALSE);
|
||||
|
||||
if (was_mapped && !gdk_surface_has_impl (surface))
|
||||
{
|
||||
if (surface->event_mask & GDK_STRUCTURE_MASK)
|
||||
_gdk_make_event (surface, GDK_UNMAP, NULL, FALSE);
|
||||
|
||||
if (surface->parent && surface->parent->event_mask & GDK_SUBSTRUCTURE_MASK)
|
||||
_gdk_make_event (surface, GDK_UNMAP, NULL, FALSE);
|
||||
}
|
||||
|
||||
/* Invalidate the rect */
|
||||
if (was_mapped)
|
||||
gdk_surface_invalidate_in_parent (surface);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_surface_withdraw:
|
||||
* @surface: a toplevel #GdkSurface
|
||||
*
|
||||
* Withdraws a surface (unmaps it and asks the surface manager to forget about it).
|
||||
* This function is not really useful as gdk_surface_hide() automatically
|
||||
* withdraws toplevel surfaces before hiding them.
|
||||
**/
|
||||
void
|
||||
gdk_surface_withdraw (GdkSurface *surface)
|
||||
{
|
||||
GdkSurfaceImplClass *impl_class;
|
||||
gboolean was_mapped;
|
||||
GdkGLContext *current_context;
|
||||
|
||||
g_return_if_fail (GDK_IS_SURFACE (surface));
|
||||
|
||||
if (surface->destroyed)
|
||||
return;
|
||||
|
||||
was_mapped = GDK_SURFACE_IS_MAPPED (surface);
|
||||
|
||||
if (gdk_surface_has_impl (surface))
|
||||
{
|
||||
impl_class = GDK_SURFACE_IMPL_GET_CLASS (surface->impl);
|
||||
impl_class->withdraw (surface);
|
||||
|
||||
if (was_mapped)
|
||||
{
|
||||
if (surface->event_mask & GDK_STRUCTURE_MASK)
|
||||
_gdk_make_event (surface, GDK_UNMAP, NULL, FALSE);
|
||||
|
||||
if (surface->parent && surface->parent->event_mask & GDK_SUBSTRUCTURE_MASK)
|
||||
_gdk_make_event (surface, GDK_UNMAP, NULL, FALSE);
|
||||
}
|
||||
|
||||
current_context = gdk_gl_context_get_current ();
|
||||
if (current_context != NULL && gdk_gl_context_get_surface (current_context) == surface)
|
||||
gdk_gl_context_clear_current ();
|
||||
|
||||
recompute_visible_regions (surface, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_surface_set_events:
|
||||
* @surface: a #GdkSurface
|
||||
* @event_mask: event mask for @surface
|
||||
*
|
||||
* The event mask for a surface determines which events will be reported
|
||||
* for that surface from all master input devices. For example, an event mask
|
||||
* including #GDK_BUTTON_PRESS_MASK means the surface should report button
|
||||
* press events. The event mask is the bitwise OR of values from the
|
||||
* #GdkEventMask enumeration.
|
||||
*
|
||||
* See the [input handling overview][event-masks] for details.
|
||||
**/
|
||||
void
|
||||
gdk_surface_set_events (GdkSurface *surface,
|
||||
GdkEventMask event_mask)
|
||||
{
|
||||
GdkSurfaceImplClass *impl_class;
|
||||
|
||||
g_return_if_fail (GDK_IS_SURFACE (surface));
|
||||
|
||||
if (surface->destroyed)
|
||||
return;
|
||||
|
||||
surface->event_mask = event_mask;
|
||||
|
||||
if (gdk_surface_has_impl (surface))
|
||||
{
|
||||
impl_class = GDK_SURFACE_IMPL_GET_CLASS (surface->impl);
|
||||
impl_class->set_events (surface,
|
||||
get_native_event_mask (surface));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_surface_get_events:
|
||||
* @surface: a #GdkSurface
|
||||
*
|
||||
* Gets the event mask for @surface for all master input devices. See
|
||||
* gdk_surface_set_events().
|
||||
*
|
||||
* Returns: event mask for @surface
|
||||
**/
|
||||
GdkEventMask
|
||||
gdk_surface_get_events (GdkSurface *surface)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_SURFACE (surface), 0);
|
||||
|
||||
if (surface->destroyed)
|
||||
return 0;
|
||||
|
||||
return surface->event_mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_surface_set_device_events:
|
||||
* @surface: a #GdkSurface
|
||||
* @device: #GdkDevice to enable events for.
|
||||
* @event_mask: event mask for @surface
|
||||
*
|
||||
* Sets the event mask for a given device (Normally a floating device, not
|
||||
* attached to any visible pointer) to @surface. For example, an event mask
|
||||
* including #GDK_BUTTON_PRESS_MASK means the surface should report button
|
||||
* press events. The event mask is the bitwise OR of values from the
|
||||
* #GdkEventMask enumeration.
|
||||
*
|
||||
* See the [input handling overview][event-masks] for details.
|
||||
**/
|
||||
void
|
||||
gdk_surface_set_device_events (GdkSurface *surface,
|
||||
GdkDevice *device,
|
||||
GdkEventMask event_mask)
|
||||
{
|
||||
GdkEventMask device_mask;
|
||||
GdkSurface *native;
|
||||
|
||||
g_return_if_fail (GDK_IS_SURFACE (surface));
|
||||
g_return_if_fail (GDK_IS_DEVICE (device));
|
||||
|
||||
if (GDK_SURFACE_DESTROYED (surface))
|
||||
return;
|
||||
|
||||
if (G_UNLIKELY (!surface->device_events))
|
||||
surface->device_events = g_hash_table_new (NULL, NULL);
|
||||
|
||||
if (event_mask == 0)
|
||||
{
|
||||
/* FIXME: unsetting events on a master device
|
||||
* would restore surface->event_mask
|
||||
*/
|
||||
g_hash_table_remove (surface->device_events, device);
|
||||
}
|
||||
else
|
||||
g_hash_table_insert (surface->device_events, device,
|
||||
GINT_TO_POINTER (event_mask));
|
||||
|
||||
native = gdk_surface_get_toplevel (surface);
|
||||
|
||||
device_mask = get_native_device_event_mask (surface, device);
|
||||
GDK_DEVICE_GET_CLASS (device)->select_surface_events (device, native, device_mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_surface_get_device_events:
|
||||
* @surface: a #GdkSurface.
|
||||
* @device: a #GdkDevice.
|
||||
*
|
||||
* Returns the event mask for @surface corresponding to an specific device.
|
||||
*
|
||||
* Returns: device event mask for @surface
|
||||
**/
|
||||
GdkEventMask
|
||||
gdk_surface_get_device_events (GdkSurface *surface,
|
||||
GdkDevice *device)
|
||||
{
|
||||
GdkEventMask mask;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_SURFACE (surface), 0);
|
||||
g_return_val_if_fail (GDK_IS_DEVICE (device), 0);
|
||||
|
||||
if (GDK_SURFACE_DESTROYED (surface))
|
||||
return 0;
|
||||
|
||||
if (!surface->device_events)
|
||||
return 0;
|
||||
|
||||
mask = GPOINTER_TO_INT (g_hash_table_lookup (surface->device_events, device));
|
||||
|
||||
/* FIXME: device could be controlled by surface->event_mask */
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_surface_move_resize_toplevel (GdkSurface *surface,
|
||||
gboolean with_move,
|
||||
@@ -3086,24 +2819,19 @@ gdk_surface_set_cursor_internal (GdkSurface *surface,
|
||||
GdkDevice *device,
|
||||
GdkCursor *cursor)
|
||||
{
|
||||
GdkPointerSurfaceInfo *pointer_info;
|
||||
GdkDisplay *display;
|
||||
|
||||
if (GDK_SURFACE_DESTROYED (surface))
|
||||
return;
|
||||
|
||||
g_assert (gdk_surface_get_display (surface) == gdk_device_get_display (device));
|
||||
|
||||
if (surface->surface_type == GDK_SURFACE_FOREIGN)
|
||||
GDK_DEVICE_GET_CLASS (device)->set_surface_cursor (device, surface, cursor);
|
||||
else
|
||||
{
|
||||
GdkPointerSurfaceInfo *pointer_info;
|
||||
GdkDisplay *display;
|
||||
display = gdk_surface_get_display (surface);
|
||||
pointer_info = _gdk_display_get_pointer_info (display, device);
|
||||
|
||||
display = gdk_surface_get_display (surface);
|
||||
pointer_info = _gdk_display_get_pointer_info (display, device);
|
||||
|
||||
if (_gdk_surface_event_parent_of (surface, pointer_info->surface_under_pointer))
|
||||
update_cursor (display, device);
|
||||
}
|
||||
if (_gdk_surface_event_parent_of (surface, pointer_info->surface_under_pointer))
|
||||
update_cursor (display, device);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3137,7 +2865,7 @@ gdk_surface_get_cursor (GdkSurface *surface)
|
||||
*
|
||||
* Note that @cursor must be for the same display as @surface.
|
||||
*
|
||||
* Use gdk_cursor_new_for_display() or gdk_cursor_new_from_texture() to
|
||||
* Use gdk_cursor_new_from_name() or gdk_cursor_new_from_texture() to
|
||||
* create the cursor. To make the cursor invisible, use %GDK_BLANK_CURSOR.
|
||||
* Passing %NULL for the @cursor argument to gdk_surface_set_cursor() means
|
||||
* that @surface will use the cursor of its parent surface. Most surfaces
|
||||
@@ -3224,7 +2952,7 @@ gdk_surface_get_device_cursor (GdkSurface *surface,
|
||||
* @cursor: a #GdkCursor
|
||||
*
|
||||
* Sets a specific #GdkCursor for a given device when it gets inside @surface.
|
||||
* Use gdk_cursor_new_for_display() or gdk_cursor_new_from_texture() to create
|
||||
* Use gdk_cursor_new_fromm_name() or gdk_cursor_new_from_texture() to create
|
||||
* the cursor. To make the cursor invisible, use %GDK_BLANK_CURSOR. Passing
|
||||
* %NULL for the @cursor argument to gdk_surface_set_cursor() means that
|
||||
* @surface will use the cursor of its parent surface. Most surfaces should
|
||||
@@ -3665,7 +3393,7 @@ gdk_surface_merge_child_input_shapes (GdkSurface *surface)
|
||||
* gdk_surface_get_modal_hint:
|
||||
* @surface: A toplevel #GdkSurface.
|
||||
*
|
||||
* Determines whether or not the surface manager is hinted that @surface
|
||||
* Determines whether or not the window manager is hinted that @surface
|
||||
* has modal behaviour.
|
||||
*
|
||||
* Returns: whether or not the surface has the modal hint set.
|
||||
@@ -4129,11 +3857,8 @@ _gdk_make_event (GdkSurface *surface,
|
||||
|
||||
case GDK_FOCUS_CHANGE:
|
||||
case GDK_CONFIGURE:
|
||||
case GDK_MAP:
|
||||
case GDK_UNMAP:
|
||||
case GDK_DELETE:
|
||||
case GDK_DESTROY:
|
||||
case GDK_EXPOSE:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -4647,7 +4372,7 @@ gdk_surface_set_transient_for (GdkSurface *surface,
|
||||
* @x: (out): return location for X position of surface frame
|
||||
* @y: (out): return location for Y position of surface frame
|
||||
*
|
||||
* Obtains the top-left corner of the surface manager frame in root
|
||||
* Obtains the top-left corner of the window manager frame in root
|
||||
* surface coordinates.
|
||||
*
|
||||
**/
|
||||
@@ -5360,10 +5085,10 @@ gdk_surface_register_dnd (GdkSurface *surface)
|
||||
*
|
||||
* This function is called by the drag source.
|
||||
*
|
||||
* Returns: (transfer full) (nullable): a newly created #GdkDragContext or
|
||||
* Returns: (transfer full) (nullable): a newly created #GdkDrag or
|
||||
* %NULL on error.
|
||||
*/
|
||||
GdkDragContext *
|
||||
GdkDrag *
|
||||
gdk_drag_begin (GdkSurface *surface,
|
||||
GdkDevice *device,
|
||||
GdkContentProvider *content,
|
||||
@@ -5687,6 +5412,7 @@ void
|
||||
gdk_surface_set_state (GdkSurface *surface,
|
||||
GdkSurfaceState new_state)
|
||||
{
|
||||
gboolean was_mapped, mapped;
|
||||
g_return_if_fail (GDK_IS_SURFACE (surface));
|
||||
|
||||
if (new_state == surface->state)
|
||||
@@ -5697,8 +5423,12 @@ gdk_surface_set_state (GdkSurface *surface,
|
||||
* inconsistent state to the user.
|
||||
*/
|
||||
|
||||
was_mapped = GDK_SURFACE_IS_MAPPED (surface);
|
||||
|
||||
surface->state = new_state;
|
||||
|
||||
mapped = GDK_SURFACE_IS_MAPPED (surface);
|
||||
|
||||
_gdk_surface_update_viewable (surface);
|
||||
|
||||
/* We only really send the event to toplevels, since
|
||||
@@ -5710,13 +5440,15 @@ gdk_surface_set_state (GdkSurface *surface,
|
||||
{
|
||||
case GDK_SURFACE_TOPLEVEL:
|
||||
case GDK_SURFACE_TEMP: /* ? */
|
||||
g_object_notify (G_OBJECT (surface), "state");
|
||||
g_object_notify_by_pspec (G_OBJECT (surface), properties[PROP_STATE]);
|
||||
break;
|
||||
case GDK_SURFACE_FOREIGN:
|
||||
case GDK_SURFACE_CHILD:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (was_mapped != mapped)
|
||||
g_object_notify_by_pspec (G_OBJECT (surface), properties[PROP_MAPPED]);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -5726,3 +5458,16 @@ gdk_synthesize_surface_state (GdkSurface *surface,
|
||||
{
|
||||
gdk_surface_set_state (surface, (surface->state | set_flags) & ~unset_flags);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gdk_surface_handle_event (GdkEvent *event)
|
||||
{
|
||||
if (gdk_event_get_event_type (event) == GDK_CONFIGURE)
|
||||
{
|
||||
g_signal_emit (gdk_event_get_surface (event), signals[SIZE_CHANGED], 0,
|
||||
event->configure.width, event->configure.height);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
+11
-39
@@ -43,12 +43,7 @@ typedef struct _GdkGeometry GdkGeometry;
|
||||
* GdkSurfaceType:
|
||||
* @GDK_SURFACE_TOPLEVEL: toplevel window (used to implement #GtkWindow)
|
||||
* @GDK_SURFACE_CHILD: child surface (used to implement e.g. #GtkEntry)
|
||||
* @GDK_SURFACE_TEMP: override redirect temporary surface (used to implement
|
||||
* #GtkMenu)
|
||||
* @GDK_SURFACE_FOREIGN: foreign surface (see gdk_surface_foreign_new())
|
||||
* @GDK_SURFACE_SUBSURFACE: subsurface; This surface is visually
|
||||
* tied to a toplevel, and is moved/stacked with it. Currently this window
|
||||
* type is only implemented in Wayland. Since 3.14
|
||||
* @GDK_SURFACE_TEMP: override redirect temporary surface (used to implement #GtkMenu)
|
||||
*
|
||||
* Describes the kind of surface.
|
||||
*/
|
||||
@@ -56,9 +51,7 @@ typedef enum
|
||||
{
|
||||
GDK_SURFACE_TOPLEVEL,
|
||||
GDK_SURFACE_CHILD,
|
||||
GDK_SURFACE_TEMP,
|
||||
GDK_SURFACE_FOREIGN,
|
||||
GDK_SURFACE_SUBSURFACE
|
||||
GDK_SURFACE_TEMP
|
||||
} GdkSurfaceType;
|
||||
|
||||
/* Size restriction enumeration.
|
||||
@@ -217,9 +210,6 @@ typedef enum
|
||||
*
|
||||
* In general, when multiple flags are set, flipping should take precedence over
|
||||
* sliding, which should take precedence over resizing.
|
||||
*
|
||||
* Since: 3.22
|
||||
* Stability: Unstable
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
@@ -266,8 +256,6 @@ typedef enum
|
||||
*
|
||||
* Indicates which monitor (in a multi-head setup) a surface should span over
|
||||
* when in fullscreen mode.
|
||||
*
|
||||
* Since: 3.8
|
||||
**/
|
||||
typedef enum
|
||||
{
|
||||
@@ -377,16 +365,15 @@ struct _GdkGeometry
|
||||
* @GDK_SURFACE_STATE_ABOVE: the surface is kept above other surfaces.
|
||||
* @GDK_SURFACE_STATE_BELOW: the surface is kept below other surfaces.
|
||||
* @GDK_SURFACE_STATE_FOCUSED: the surface is presented as focused (with active decorations).
|
||||
* @GDK_SURFACE_STATE_TILED: the surface is in a tiled state, Since 3.10. Since 3.91.2, this
|
||||
* is deprecated in favor of per-edge information.
|
||||
* @GDK_SURFACE_STATE_TOP_TILED: whether the top edge is tiled, Since 3.91.2
|
||||
* @GDK_SURFACE_STATE_TOP_RESIZABLE: whether the top edge is resizable, Since 3.91.2
|
||||
* @GDK_SURFACE_STATE_RIGHT_TILED: whether the right edge is tiled, Since 3.91.2
|
||||
* @GDK_SURFACE_STATE_RIGHT_RESIZABLE: whether the right edge is resizable, Since 3.91.2
|
||||
* @GDK_SURFACE_STATE_BOTTOM_TILED: whether the bottom edge is tiled, Since 3.91.2
|
||||
* @GDK_SURFACE_STATE_BOTTOM_RESIZABLE: whether the bottom edge is resizable, Since 3.91.2
|
||||
* @GDK_SURFACE_STATE_LEFT_TILED: whether the left edge is tiled, Since 3.91.2
|
||||
* @GDK_SURFACE_STATE_LEFT_RESIZABLE: whether the left edge is resizable, Since 3.91.2
|
||||
* @GDK_SURFACE_STATE_TILED: the surface is in a tiled state. Deprecated
|
||||
* @GDK_SURFACE_STATE_TOP_TILED: whether the top edge is tiled
|
||||
* @GDK_SURFACE_STATE_TOP_RESIZABLE: whether the top edge is resizable
|
||||
* @GDK_SURFACE_STATE_RIGHT_TILED: whether the right edge is tiled
|
||||
* @GDK_SURFACE_STATE_RIGHT_RESIZABLE: whether the right edge is resizable
|
||||
* @GDK_SURFACE_STATE_BOTTOM_TILED: whether the bottom edge is tiled
|
||||
* @GDK_SURFACE_STATE_BOTTOM_RESIZABLE: whether the bottom edge is resizable
|
||||
* @GDK_SURFACE_STATE_LEFT_TILED: whether the left edge is tiled
|
||||
* @GDK_SURFACE_STATE_LEFT_RESIZABLE: whether the left edge is resizable
|
||||
*
|
||||
* Specifies the state of a toplevel surface.
|
||||
*/
|
||||
@@ -468,8 +455,6 @@ void gdk_surface_show (GdkSurface *surface);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_surface_hide (GdkSurface *surface);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_surface_withdraw (GdkSurface *surface);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_surface_show_unraised (GdkSurface *surface);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_surface_move (GdkSurface *surface,
|
||||
@@ -685,19 +670,6 @@ GDK_AVAILABLE_IN_ALL
|
||||
GList * gdk_surface_get_children_with_user_data (GdkSurface *surface,
|
||||
gpointer user_data);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkEventMask gdk_surface_get_events (GdkSurface *surface);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_surface_set_events (GdkSurface *surface,
|
||||
GdkEventMask event_mask);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_surface_set_device_events (GdkSurface *surface,
|
||||
GdkDevice *device,
|
||||
GdkEventMask event_mask);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkEventMask gdk_surface_get_device_events (GdkSurface *surface,
|
||||
GdkDevice *device);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_surface_set_icon_list (GdkSurface *surface,
|
||||
GList *surfaces);
|
||||
|
||||
@@ -76,10 +76,6 @@ struct _GdkSurfaceImplClass
|
||||
gint rect_anchor_dx,
|
||||
gint rect_anchor_dy);
|
||||
|
||||
GdkEventMask (* get_events) (GdkSurface *surface);
|
||||
void (* set_events) (GdkSurface *surface,
|
||||
GdkEventMask event_mask);
|
||||
|
||||
void (* get_geometry) (GdkSurface *surface,
|
||||
gint *x,
|
||||
gint *y,
|
||||
@@ -197,7 +193,7 @@ struct _GdkSurfaceImplClass
|
||||
gdouble opacity);
|
||||
void (* destroy_notify) (GdkSurface *surface);
|
||||
void (* register_dnd) (GdkSurface *surface);
|
||||
GdkDragContext * (*drag_begin) (GdkSurface *surface,
|
||||
GdkDrag * (*drag_begin) (GdkSurface *surface,
|
||||
GdkDevice *device,
|
||||
GdkContentProvider*content,
|
||||
GdkDragAction actions,
|
||||
|
||||
+46
-30
@@ -123,7 +123,8 @@ typedef struct _GdkContentProvider GdkContentProvider;
|
||||
typedef struct _GdkCursor GdkCursor;
|
||||
typedef struct _GdkTexture GdkTexture;
|
||||
typedef struct _GdkDevice GdkDevice;
|
||||
typedef struct _GdkDragContext GdkDragContext;
|
||||
typedef struct _GdkDrag GdkDrag;
|
||||
typedef struct _GdkDrop GdkDrop;
|
||||
|
||||
typedef struct _GdkClipboard GdkClipboard;
|
||||
typedef struct _GdkDisplayManager GdkDisplayManager;
|
||||
@@ -195,9 +196,9 @@ typedef enum
|
||||
* @GDK_MODIFIER_RESERVED_23_MASK: A reserved bit flag; do not use in your own code
|
||||
* @GDK_MODIFIER_RESERVED_24_MASK: A reserved bit flag; do not use in your own code
|
||||
* @GDK_MODIFIER_RESERVED_25_MASK: A reserved bit flag; do not use in your own code
|
||||
* @GDK_SUPER_MASK: the Super modifier. Since 2.10
|
||||
* @GDK_HYPER_MASK: the Hyper modifier. Since 2.10
|
||||
* @GDK_META_MASK: the Meta modifier. Since 2.10
|
||||
* @GDK_SUPER_MASK: the Super modifier
|
||||
* @GDK_HYPER_MASK: the Hyper modifier
|
||||
* @GDK_META_MASK: the Meta modifier
|
||||
* @GDK_MODIFIER_RESERVED_29_MASK: A reserved bit flag; do not use in your own code
|
||||
* @GDK_RELEASE_MASK: not used in GDK itself. GTK+ uses it to differentiate
|
||||
* between (keyval, modifiers) pairs from key press and release events.
|
||||
@@ -209,7 +210,7 @@ typedef enum
|
||||
*
|
||||
* Like the X Window System, GDK supports 8 modifier keys and 5 mouse buttons.
|
||||
*
|
||||
* Since 2.10, GDK recognizes which of the Meta, Super or Hyper keys are mapped
|
||||
* GDK recognizes which of the Meta, Super or Hyper keys are mapped
|
||||
* to Mod2 - Mod5, and indicates this by setting %GDK_SUPER_MASK,
|
||||
* %GDK_HYPER_MASK or %GDK_META_MASK in the state field of key events.
|
||||
*
|
||||
@@ -298,8 +299,6 @@ typedef enum
|
||||
* invoking menu shortcuts (accelerators), whereas on Apple computers
|
||||
* it’s the Command key (which correspond to %GDK_CONTROL_MASK and
|
||||
* %GDK_MOD2_MASK, respectively).
|
||||
*
|
||||
* Since: 3.4
|
||||
**/
|
||||
typedef enum
|
||||
{
|
||||
@@ -321,7 +320,7 @@ typedef enum
|
||||
* @GDK_GRAB_NOT_VIEWABLE: the grab surface or the @confine_to surface are not
|
||||
* viewable.
|
||||
* @GDK_GRAB_FROZEN: the resource is frozen by an active grab of another client.
|
||||
* @GDK_GRAB_FAILED: the grab failed for some other reason. Since 3.16
|
||||
* @GDK_GRAB_FAILED: the grab failed for some other reason
|
||||
*
|
||||
* Returned by gdk_device_grab() to indicate success or the reason for the
|
||||
* failure of the grab attempt.
|
||||
@@ -370,13 +369,12 @@ typedef enum
|
||||
* @GDK_PROPERTY_CHANGE_MASK: receive property change events
|
||||
* @GDK_PROXIMITY_IN_MASK: receive proximity in events
|
||||
* @GDK_PROXIMITY_OUT_MASK: receive proximity out events
|
||||
* @GDK_SUBSTRUCTURE_MASK: receive events about surface configuration changes of
|
||||
* child surfaces
|
||||
* @GDK_SUBSTRUCTURE_MASK: receive events about surface configuration changes of child surfaces
|
||||
* @GDK_SCROLL_MASK: receive scroll events
|
||||
* @GDK_TOUCH_MASK: receive touch events. Since 3.4
|
||||
* @GDK_SMOOTH_SCROLL_MASK: receive smooth scrolling events. Since 3.4
|
||||
@GDK_TOUCHPAD_GESTURE_MASK: receive touchpad gesture events. Since 3.18
|
||||
* @GDK_TABLET_PAD_MASK: receive tablet pad events. Since 3.22
|
||||
* @GDK_TOUCH_MASK: receive touch events
|
||||
* @GDK_SMOOTH_SCROLL_MASK: receive smooth scrolling events
|
||||
@GDK_TOUCHPAD_GESTURE_MASK: receive touchpad gesture events
|
||||
* @GDK_TABLET_PAD_MASK: receive tablet pad events
|
||||
* @GDK_ALL_EVENTS_MASK: the combination of all the above event masks.
|
||||
*
|
||||
* A set of bit-flags to indicate which events a surface is to receive.
|
||||
@@ -386,11 +384,6 @@ typedef enum
|
||||
* See the [input handling overview][chap-input-handling] for details of
|
||||
* [event masks][event-masks] and [event propagation][event-propagation].
|
||||
*
|
||||
* Since GTK 3.8, motion events are already compressed by default, independent
|
||||
* of this mechanism. This compression can be disabled with
|
||||
* gdk_surface_set_event_compression(). See the documentation of that function
|
||||
* for details.
|
||||
*
|
||||
* If %GDK_TOUCH_MASK is enabled, the surface will receive touch events
|
||||
* from touch-enabled devices. Those will come as sequences of #GdkEventTouch
|
||||
* with type %GDK_TOUCH_UPDATE, enclosed by two events with
|
||||
@@ -431,12 +424,10 @@ typedef enum
|
||||
* @GDK_GL_ERROR_NOT_AVAILABLE: OpenGL support is not available
|
||||
* @GDK_GL_ERROR_UNSUPPORTED_FORMAT: The requested visual format is not supported
|
||||
* @GDK_GL_ERROR_UNSUPPORTED_PROFILE: The requested profile is not supported
|
||||
* @GDK_GL_ERROR_COMPILATION_FAILED: The shader compilation failed (available since 3.22)
|
||||
* @GDK_GL_ERROR_LINK_FAILED: The shader linking failed (available since 3.22)
|
||||
* @GDK_GL_ERROR_COMPILATION_FAILED: The shader compilation failed
|
||||
* @GDK_GL_ERROR_LINK_FAILED: The shader linking failed
|
||||
*
|
||||
* Error enumeration for #GdkGLContext.
|
||||
*
|
||||
* Since: 3.16
|
||||
*/
|
||||
typedef enum {
|
||||
GDK_GL_ERROR_NOT_AVAILABLE,
|
||||
@@ -453,8 +444,6 @@ typedef enum {
|
||||
* @GDK_VULKAN_ERROR_NOT_AVAILABLE: Vulkan support is not available on this Surface
|
||||
*
|
||||
* Error enumeration for #GdkVulkanContext.
|
||||
*
|
||||
* Since: 3.90
|
||||
*/
|
||||
typedef enum {
|
||||
GDK_VULKAN_ERROR_UNSUPPORTED,
|
||||
@@ -518,9 +507,9 @@ typedef enum
|
||||
* @GDK_AXIS_XTILT: the axis is used for x tilt information.
|
||||
* @GDK_AXIS_YTILT: the axis is used for y tilt information.
|
||||
* @GDK_AXIS_WHEEL: the axis is used for wheel information.
|
||||
* @GDK_AXIS_DISTANCE: the axis is used for pen/tablet distance information. (Since: 3.22)
|
||||
* @GDK_AXIS_ROTATION: the axis is used for pen rotation information. (Since: 3.22)
|
||||
* @GDK_AXIS_SLIDER: the axis is used for pen slider information. (Since: 3.22)
|
||||
* @GDK_AXIS_DISTANCE: the axis is used for pen/tablet distance information
|
||||
* @GDK_AXIS_ROTATION: the axis is used for pen rotation information
|
||||
* @GDK_AXIS_SLIDER: the axis is used for pen slider information
|
||||
* @GDK_AXIS_LAST: a constant equal to the numerically highest axis value.
|
||||
*
|
||||
* An enumeration describing the way in which a device
|
||||
@@ -559,8 +548,6 @@ typedef enum
|
||||
* @GDK_AXIS_FLAG_SLIDER: Slider axis is present
|
||||
*
|
||||
* Flags describing the current capabilities of a device/tool.
|
||||
*
|
||||
* Since: 3.22
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
@@ -575,6 +562,35 @@ typedef enum
|
||||
GDK_AXIS_FLAG_SLIDER = 1 << GDK_AXIS_SLIDER,
|
||||
} GdkAxisFlags;
|
||||
|
||||
/**
|
||||
* GdkDragAction:
|
||||
* @GDK_ACTION_COPY: Copy the data.
|
||||
* @GDK_ACTION_MOVE: Move the data, i.e. first copy it, then delete
|
||||
* it from the source using the DELETE target of the X selection protocol.
|
||||
* @GDK_ACTION_LINK: Add a link to the data. Note that this is only
|
||||
* useful if source and destination agree on what it means.
|
||||
* @GDK_ACTION_ASK: Ask the user what to do with the data.
|
||||
*
|
||||
* Used in #GdkDrag to indicate what the destination
|
||||
* should do with the dropped data.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
GDK_ACTION_COPY = 1 << 0,
|
||||
GDK_ACTION_MOVE = 1 << 1,
|
||||
GDK_ACTION_LINK = 1 << 2,
|
||||
GDK_ACTION_ASK = 1 << 3
|
||||
} GdkDragAction;
|
||||
|
||||
/**
|
||||
* GDK_ACTION_ALL:
|
||||
*
|
||||
* Defines all possible DND actions. This can be used in gdk_drop_status()
|
||||
* messages when any drop can be accepted or a more specific drop method
|
||||
* is not yet known.
|
||||
*/
|
||||
#define GDK_ACTION_ALL (GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK)
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_TYPES_H__ */
|
||||
|
||||
+4
-2
@@ -15,8 +15,9 @@ gdk_public_sources = files([
|
||||
'gdkdevicetool.c',
|
||||
'gdkdisplay.c',
|
||||
'gdkdisplaymanager.c',
|
||||
'gdkdnd.c',
|
||||
'gdkdrag.c',
|
||||
'gdkdrawcontext.c',
|
||||
'gdkdrop.c',
|
||||
'gdkevents.c',
|
||||
'gdkframeclock.c',
|
||||
'gdkframeclockidle.c',
|
||||
@@ -64,8 +65,9 @@ gdk_public_headers = files([
|
||||
'gdkdevicetool.h',
|
||||
'gdkdisplay.h',
|
||||
'gdkdisplaymanager.h',
|
||||
'gdkdnd.h',
|
||||
'gdkdrag.h',
|
||||
'gdkdrawcontext.h',
|
||||
'gdkdrop.h',
|
||||
'gdkevents.h',
|
||||
'gdkframeclock.h',
|
||||
'gdkframetimings.h',
|
||||
|
||||
@@ -527,16 +527,6 @@ drag_operation_to_drag_action (NSDragOperation operation)
|
||||
/* GDK and Quartz drag operations do not map 1:1.
|
||||
* This mapping represents about the best that we
|
||||
* can come up.
|
||||
*
|
||||
* Note that NSDragOperationPrivate and GDK_ACTION_PRIVATE
|
||||
* have almost opposite meanings: the GDK one means that the
|
||||
* destination is solely responsible for the action; the Quartz
|
||||
* one means that the source and destination will agree
|
||||
* privately on the action. NSOperationGeneric is close in meaning
|
||||
* to GDK_ACTION_PRIVATE but there is a problem: it will be
|
||||
* sent for any ordinary drag, and likely not understood
|
||||
* by any intra-widget drag (since the source & dest are the
|
||||
* same).
|
||||
*/
|
||||
|
||||
if (operation & NSDragOperationGeneric)
|
||||
@@ -569,11 +559,13 @@ drag_action_to_drag_operation (GdkDragAction action)
|
||||
static void
|
||||
update_context_from_dragging_info (id <NSDraggingInfo> sender)
|
||||
{
|
||||
GdkDragAction action;
|
||||
|
||||
g_assert (current_context != NULL);
|
||||
|
||||
GDK_QUARTZ_DRAG_CONTEXT (current_context)->dragging_info = sender;
|
||||
current_context->suggested_action = drag_operation_to_drag_action ([sender draggingSourceOperationMask]);
|
||||
current_context->actions = current_context->suggested_action;
|
||||
action = drag_operation_to_drag_action ([sender draggingSourceOperationMask]);
|
||||
gdk_drag_context_set_actions (current_context, action, action);
|
||||
}
|
||||
|
||||
- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
|
||||
|
||||
@@ -76,9 +76,6 @@ static GdkSurface * gdk_quartz_device_core_surface_at_position (GdkDevice
|
||||
gdouble *win_y,
|
||||
GdkModifierType *mask,
|
||||
gboolean get_toplevel);
|
||||
static void gdk_quartz_device_core_select_surface_events (GdkDevice *device,
|
||||
GdkSurface *window,
|
||||
GdkEventMask event_mask);
|
||||
|
||||
|
||||
G_DEFINE_TYPE (GdkQuartzDeviceCore, gdk_quartz_device_core, GDK_TYPE_DEVICE)
|
||||
@@ -96,7 +93,6 @@ gdk_quartz_device_core_class_init (GdkQuartzDeviceCoreClass *klass)
|
||||
device_class->grab = gdk_quartz_device_core_grab;
|
||||
device_class->ungrab = gdk_quartz_device_core_ungrab;
|
||||
device_class->surface_at_position = gdk_quartz_device_core_surface_at_position;
|
||||
device_class->select_surface_events = gdk_quartz_device_core_select_surface_events;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -349,10 +345,3 @@ gdk_quartz_device_core_surface_at_position (GdkDevice *device,
|
||||
return found_window;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_quartz_device_core_select_surface_events (GdkDevice *device,
|
||||
GdkSurface *window,
|
||||
GdkEventMask event_mask)
|
||||
{
|
||||
/* The mask is set in the common code. */
|
||||
}
|
||||
|
||||
@@ -65,7 +65,6 @@ void _gdk_quartz_display_after_process_all_updates (GdkDisplay *display);
|
||||
void _gdk_quartz_display_create_surface_impl (GdkDisplay *display,
|
||||
GdkSurface *window,
|
||||
GdkSurface *real_parent,
|
||||
GdkEventMask event_mask,
|
||||
GdkSurfaceAttr *attributes);
|
||||
|
||||
/* Display methods - keymap */
|
||||
|
||||
@@ -46,7 +46,6 @@ _gdk_quartz_surface_drag_begin (GdkSurface *window,
|
||||
_gdk_quartz_drag_source_context = g_object_new (GDK_TYPE_QUARTZ_DRAG_CONTEXT,
|
||||
"device", device,
|
||||
NULL);
|
||||
_gdk_quartz_drag_source_context->is_source = TRUE;
|
||||
|
||||
_gdk_quartz_drag_source_context->source_surface = window;
|
||||
g_object_ref (window);
|
||||
@@ -70,22 +69,6 @@ gdk_quartz_drag_context_drag_abort (GdkDragContext *context,
|
||||
/* FIXME: Implement */
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_quartz_drag_context_drag_status (GdkDragContext *context,
|
||||
GdkDragAction action,
|
||||
guint32 time)
|
||||
{
|
||||
context->action = action;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_quartz_drag_context_drop_finish (GdkDragContext *context,
|
||||
gboolean success,
|
||||
guint32 time)
|
||||
{
|
||||
/* FIXME: Implement */
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_quartz_surface_register_dnd (GdkSurface *window)
|
||||
{
|
||||
@@ -117,8 +100,6 @@ gdk_quartz_drag_context_class_init (GdkQuartzDragContextClass *klass)
|
||||
|
||||
object_class->finalize = gdk_quartz_drag_context_finalize;
|
||||
|
||||
context_class->drag_status = gdk_quartz_drag_context_drag_status;
|
||||
context_class->drag_abort = gdk_quartz_drag_context_drag_abort;
|
||||
context_class->drag_drop = gdk_quartz_drag_context_drag_drop;
|
||||
context_class->drop_finish = gdk_quartz_drag_context_drop_finish;
|
||||
}
|
||||
|
||||
@@ -1113,8 +1113,6 @@ fill_key_event (GdkSurface *window,
|
||||
{
|
||||
GdkEventPrivate *priv;
|
||||
GdkQuartzDeviceManagerCore *device_manager;
|
||||
gchar buf[7];
|
||||
gunichar c = 0;
|
||||
|
||||
priv = (GdkEventPrivate *) event;
|
||||
priv->windowing_data = [nsevent retain];
|
||||
@@ -1189,44 +1187,6 @@ fill_key_event (GdkSurface *window,
|
||||
gdk_keymap_add_virtual_modifiers (gdk_display_get_keymap (_gdk_display),
|
||||
&event->key.state);
|
||||
|
||||
event->key.string = NULL;
|
||||
|
||||
/* Fill in ->string since apps depend on it, taken from the x11 backend. */
|
||||
if (event->key.keyval != GDK_KEY_VoidSymbol)
|
||||
c = gdk_keyval_to_unicode (event->key.keyval);
|
||||
|
||||
if (c)
|
||||
{
|
||||
gsize bytes_written;
|
||||
gint len;
|
||||
|
||||
len = g_unichar_to_utf8 (c, buf);
|
||||
buf[len] = '\0';
|
||||
|
||||
event->key.string = g_locale_from_utf8 (buf, len,
|
||||
NULL, &bytes_written,
|
||||
NULL);
|
||||
if (event->key.string)
|
||||
event->key.length = bytes_written;
|
||||
}
|
||||
else if (event->key.keyval == GDK_KEY_Escape)
|
||||
{
|
||||
event->key.length = 1;
|
||||
event->key.string = g_strdup ("\033");
|
||||
}
|
||||
else if (event->key.keyval == GDK_KEY_Return ||
|
||||
event->key.keyval == GDK_KEY_KP_Enter)
|
||||
{
|
||||
event->key.length = 1;
|
||||
event->key.string = g_strdup ("\r");
|
||||
}
|
||||
|
||||
if (!event->key.string)
|
||||
{
|
||||
event->key.length = 0;
|
||||
event->key.string = g_strdup ("");
|
||||
}
|
||||
|
||||
GDK_NOTE(EVENTS,
|
||||
g_message ("key %s:\t\twindow: %p key: %12s %d",
|
||||
type == GDK_KEY_PRESS ? "press" : "release",
|
||||
|
||||
@@ -731,7 +731,6 @@ void
|
||||
_gdk_quartz_display_create_surface_impl (GdkDisplay *display,
|
||||
GdkSurface *window,
|
||||
GdkSurface *real_parent,
|
||||
GdkEventMask event_mask,
|
||||
GdkSurfaceAttr *attributes)
|
||||
{
|
||||
GdkSurfaceImplQuartz *impl;
|
||||
@@ -1615,22 +1614,6 @@ gdk_surface_quartz_get_device_state (GdkSurface *window,
|
||||
x, y, mask) != NULL;
|
||||
}
|
||||
|
||||
static GdkEventMask
|
||||
gdk_surface_quartz_get_events (GdkSurface *window)
|
||||
{
|
||||
if (GDK_SURFACE_DESTROYED (window))
|
||||
return 0;
|
||||
else
|
||||
return window->event_mask;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_surface_quartz_set_events (GdkSurface *window,
|
||||
GdkEventMask event_mask)
|
||||
{
|
||||
/* The mask is set in the common code. */
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_quartz_surface_set_urgency_hint (GdkSurface *window,
|
||||
gboolean urgent)
|
||||
@@ -2746,8 +2729,6 @@ gdk_surface_impl_quartz_class_init (GdkSurfaceImplQuartzClass *klass)
|
||||
impl_class->show = gdk_surface_quartz_show;
|
||||
impl_class->hide = gdk_surface_quartz_hide;
|
||||
impl_class->withdraw = gdk_surface_quartz_withdraw;
|
||||
impl_class->set_events = gdk_surface_quartz_set_events;
|
||||
impl_class->get_events = gdk_surface_quartz_get_events;
|
||||
impl_class->raise = gdk_surface_quartz_raise;
|
||||
impl_class->lower = gdk_surface_quartz_lower;
|
||||
impl_class->restack_toplevel = gdk_surface_quartz_restack_toplevel;
|
||||
|
||||
@@ -52,13 +52,13 @@ static void
|
||||
gdk_wayland_clipboard_discard_offer (GdkWaylandClipboard *cb)
|
||||
{
|
||||
g_clear_pointer (&cb->offer_formats, gdk_content_formats_unref);
|
||||
g_clear_pointer (&cb->offer, (GDestroyNotify) wl_data_offer_destroy);
|
||||
g_clear_pointer (&cb->offer, wl_data_offer_destroy);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_clipboard_discard_source (GdkWaylandClipboard *cb)
|
||||
{
|
||||
g_clear_pointer (&cb->source, (GDestroyNotify) wl_data_source_destroy);
|
||||
g_clear_pointer (&cb->source, wl_data_source_destroy);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
+59
-146
@@ -34,6 +34,7 @@
|
||||
#include "gdkdeviceprivate.h"
|
||||
#include "gdkdevicepadprivate.h"
|
||||
#include "gdkdevicetoolprivate.h"
|
||||
#include "gdkdropprivate.h"
|
||||
#include "gdkprimary-wayland.h"
|
||||
#include "gdkseatprivate.h"
|
||||
#include "pointer-gestures-unstable-v1-client-protocol.h"
|
||||
@@ -246,10 +247,8 @@ struct _GdkWaylandSeat
|
||||
GdkClipboard *clipboard;
|
||||
GdkClipboard *primary_clipboard;
|
||||
struct wl_data_device *data_device;
|
||||
GdkDragContext *drop_context;
|
||||
|
||||
/* Source/dest for non-local dnd */
|
||||
GdkSurface *foreign_dnd_surface;
|
||||
GdkDrag *drag;
|
||||
GdkDrop *drop;
|
||||
|
||||
/* Some tracking on gesture events */
|
||||
guint gesture_n_fingers;
|
||||
@@ -864,13 +863,6 @@ gdk_wayland_device_surface_at_position (GdkDevice *device,
|
||||
return pointer->focus;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_device_select_surface_events (GdkDevice *device,
|
||||
GdkSurface *surface,
|
||||
GdkEventMask event_mask)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_device_class_init (GdkWaylandDeviceClass *klass)
|
||||
{
|
||||
@@ -884,7 +876,6 @@ gdk_wayland_device_class_init (GdkWaylandDeviceClass *klass)
|
||||
device_class->grab = gdk_wayland_device_grab;
|
||||
device_class->ungrab = gdk_wayland_device_ungrab;
|
||||
device_class->surface_at_position = gdk_wayland_device_surface_at_position;
|
||||
device_class->select_surface_events = gdk_wayland_device_select_surface_events;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1096,7 +1087,7 @@ gdk_wayland_seat_discard_pending_offer (GdkWaylandSeat *seat)
|
||||
gdk_content_formats_unref (ignore);
|
||||
seat->pending_builder = NULL;
|
||||
}
|
||||
g_clear_pointer (&seat->pending_offer, (GDestroyNotify) wl_data_offer_destroy);
|
||||
g_clear_pointer (&seat->pending_offer, wl_data_offer_destroy);
|
||||
seat->pending_source_actions = 0;
|
||||
seat->pending_action = 0;
|
||||
}
|
||||
@@ -1140,8 +1131,6 @@ data_offer_source_actions (void *data,
|
||||
uint32_t source_actions)
|
||||
{
|
||||
GdkWaylandSeat *seat = data;
|
||||
GdkDragContext *drop_context;
|
||||
GdkDevice *device;
|
||||
|
||||
if (offer == seat->pending_offer)
|
||||
{
|
||||
@@ -1149,15 +1138,16 @@ data_offer_source_actions (void *data,
|
||||
return;
|
||||
}
|
||||
|
||||
device = gdk_seat_get_pointer (GDK_SEAT (seat));
|
||||
drop_context = gdk_wayland_device_get_drop_context (device);
|
||||
if (drop_context == NULL)
|
||||
if (seat->drop == NULL)
|
||||
return;
|
||||
|
||||
drop_context->actions = gdk_wayland_actions_to_gdk_actions (source_actions);
|
||||
gdk_wayland_drop_set_source_actions (seat->drop, source_actions);
|
||||
|
||||
_gdk_wayland_drag_context_emit_event (drop_context, GDK_DRAG_MOTION,
|
||||
GDK_CURRENT_TIME);
|
||||
gdk_drop_emit_motion_event (seat->drop,
|
||||
FALSE,
|
||||
seat->pointer_info.surface_x,
|
||||
seat->pointer_info.surface_y,
|
||||
GDK_CURRENT_TIME);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1166,8 +1156,6 @@ data_offer_action (void *data,
|
||||
uint32_t action)
|
||||
{
|
||||
GdkWaylandSeat *seat = data;
|
||||
GdkDragContext *drop_context;
|
||||
GdkDevice *device;
|
||||
|
||||
if (offer == seat->pending_offer)
|
||||
{
|
||||
@@ -1175,15 +1163,16 @@ data_offer_action (void *data,
|
||||
return;
|
||||
}
|
||||
|
||||
device = gdk_seat_get_pointer (GDK_SEAT (seat));
|
||||
drop_context = gdk_wayland_device_get_drop_context (device);
|
||||
if (drop_context == NULL)
|
||||
if (seat->drop == NULL)
|
||||
return;
|
||||
|
||||
drop_context->action = gdk_wayland_actions_to_gdk_actions (action);
|
||||
gdk_wayland_drop_set_action (seat->drop, action);
|
||||
|
||||
_gdk_wayland_drag_context_emit_event (drop_context, GDK_DRAG_MOTION,
|
||||
GDK_CURRENT_TIME);
|
||||
gdk_drop_emit_motion_event (seat->drop,
|
||||
FALSE,
|
||||
seat->pointer_info.surface_x,
|
||||
seat->pointer_info.surface_y,
|
||||
GDK_CURRENT_TIME);
|
||||
}
|
||||
|
||||
static const struct wl_data_offer_listener data_offer_listener = {
|
||||
@@ -1225,7 +1214,7 @@ data_device_enter (void *data,
|
||||
struct wl_data_offer *offer)
|
||||
{
|
||||
GdkWaylandSeat *seat = data;
|
||||
GdkSurface *dest_surface, *dnd_owner;
|
||||
GdkSurface *dest_surface;
|
||||
GdkContentFormats *formats;
|
||||
GdkDevice *device;
|
||||
|
||||
@@ -1265,22 +1254,13 @@ data_device_enter (void *data,
|
||||
seat->pending_builder = NULL;
|
||||
seat->pending_offer = NULL;
|
||||
|
||||
seat->drop_context = _gdk_wayland_drop_context_new (device, formats, offer);
|
||||
|
||||
dnd_owner = seat->foreign_dnd_surface;
|
||||
|
||||
_gdk_wayland_drag_context_set_source_surface (seat->drop_context, dnd_owner);
|
||||
|
||||
_gdk_wayland_drag_context_set_dest_surface (seat->drop_context,
|
||||
dest_surface, serial);
|
||||
_gdk_wayland_drag_context_set_coords (seat->drop_context,
|
||||
wl_fixed_to_double (x),
|
||||
wl_fixed_to_double (y));
|
||||
seat->drop = gdk_wayland_drop_new (device, seat->drag, formats, dest_surface, offer, serial);
|
||||
|
||||
gdk_wayland_seat_discard_pending_offer (seat);
|
||||
|
||||
_gdk_wayland_drag_context_emit_event (seat->drop_context, GDK_DRAG_ENTER,
|
||||
GDK_CURRENT_TIME);
|
||||
gdk_drop_emit_enter_event (seat->drop,
|
||||
FALSE,
|
||||
GDK_CURRENT_TIME);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1292,18 +1272,17 @@ data_device_leave (void *data,
|
||||
GDK_DISPLAY_NOTE (seat->display, EVENTS,
|
||||
g_message ("data device leave, data device %p", data_device));
|
||||
|
||||
if (seat->drop_context == NULL)
|
||||
if (seat->drop == NULL)
|
||||
return;
|
||||
|
||||
g_object_unref (seat->pointer_info.focus);
|
||||
seat->pointer_info.focus = NULL;
|
||||
|
||||
_gdk_wayland_drag_context_set_coords (seat->drop_context, -1, -1);
|
||||
_gdk_wayland_drag_context_emit_event (seat->drop_context, GDK_DRAG_LEAVE,
|
||||
GDK_CURRENT_TIME);
|
||||
_gdk_wayland_drag_context_set_dest_surface (seat->drop_context, NULL, 0);
|
||||
gdk_drop_emit_leave_event (seat->drop,
|
||||
FALSE,
|
||||
GDK_CURRENT_TIME);
|
||||
|
||||
g_clear_object (&seat->drop_context);
|
||||
g_clear_object (&seat->drop);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1319,18 +1298,18 @@ data_device_motion (void *data,
|
||||
g_message ("data device motion, data_device = %p, time = %d, x = %f, y = %f",
|
||||
data_device, time, wl_fixed_to_double (x), wl_fixed_to_double (y)));
|
||||
|
||||
if (seat->drop_context == NULL)
|
||||
if (seat->drop == NULL)
|
||||
return;
|
||||
|
||||
/* Update pointer state, so device state queries work during DnD */
|
||||
seat->pointer_info.surface_x = wl_fixed_to_double (x);
|
||||
seat->pointer_info.surface_y = wl_fixed_to_double (y);
|
||||
|
||||
_gdk_wayland_drag_context_set_coords (seat->drop_context,
|
||||
wl_fixed_to_double (x),
|
||||
wl_fixed_to_double (y));
|
||||
_gdk_wayland_drag_context_emit_event (seat->drop_context,
|
||||
GDK_DRAG_MOTION, time);
|
||||
gdk_drop_emit_motion_event (seat->drop,
|
||||
FALSE,
|
||||
seat->pointer_info.surface_x,
|
||||
seat->pointer_info.surface_y,
|
||||
time);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1342,8 +1321,11 @@ data_device_drop (void *data,
|
||||
GDK_DISPLAY_NOTE (seat->display, EVENTS,
|
||||
g_message ("data device drop, data device %p", data_device));
|
||||
|
||||
_gdk_wayland_drag_context_emit_event (seat->drop_context,
|
||||
GDK_DROP_START, GDK_CURRENT_TIME);
|
||||
gdk_drop_emit_drop_event (seat->drop,
|
||||
FALSE,
|
||||
seat->pointer_info.surface_x,
|
||||
seat->pointer_info.surface_y,
|
||||
GDK_CURRENT_TIME);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -2027,73 +2009,6 @@ keyboard_handle_leave (void *data,
|
||||
|
||||
static gboolean keyboard_repeat (gpointer data);
|
||||
|
||||
static void
|
||||
translate_keyboard_string (GdkEventKey *event)
|
||||
{
|
||||
gunichar c = 0;
|
||||
gchar buf[7];
|
||||
|
||||
/* Fill in event->string crudely, since various programs
|
||||
* depend on it.
|
||||
*/
|
||||
event->string = NULL;
|
||||
|
||||
if (event->keyval != GDK_KEY_VoidSymbol)
|
||||
c = gdk_keyval_to_unicode (event->keyval);
|
||||
|
||||
if (c)
|
||||
{
|
||||
gsize bytes_written;
|
||||
gint len;
|
||||
|
||||
/* Apply the control key - Taken from Xlib */
|
||||
if (event->state & GDK_CONTROL_MASK)
|
||||
{
|
||||
if ((c >= '@' && c < '\177') || c == ' ')
|
||||
c &= 0x1F;
|
||||
else if (c == '2')
|
||||
{
|
||||
event->string = g_memdup ("\0\0", 2);
|
||||
event->length = 1;
|
||||
buf[0] = '\0';
|
||||
return;
|
||||
}
|
||||
else if (c >= '3' && c <= '7')
|
||||
c -= ('3' - '\033');
|
||||
else if (c == '8')
|
||||
c = '\177';
|
||||
else if (c == '/')
|
||||
c = '_' & 0x1F;
|
||||
}
|
||||
|
||||
len = g_unichar_to_utf8 (c, buf);
|
||||
buf[len] = '\0';
|
||||
|
||||
event->string = g_locale_from_utf8 (buf, len,
|
||||
NULL, &bytes_written,
|
||||
NULL);
|
||||
if (event->string)
|
||||
event->length = bytes_written;
|
||||
}
|
||||
else if (event->keyval == GDK_KEY_Escape)
|
||||
{
|
||||
event->length = 1;
|
||||
event->string = g_strdup ("\033");
|
||||
}
|
||||
else if (event->keyval == GDK_KEY_Return ||
|
||||
event->keyval == GDK_KEY_KP_Enter)
|
||||
{
|
||||
event->length = 1;
|
||||
event->string = g_strdup ("\r");
|
||||
}
|
||||
|
||||
if (!event->string)
|
||||
{
|
||||
event->length = 0;
|
||||
event->string = g_strdup ("");
|
||||
}
|
||||
}
|
||||
|
||||
static GSettings *
|
||||
get_keyboard_settings (GdkWaylandSeat *seat)
|
||||
{
|
||||
@@ -2209,17 +2124,15 @@ deliver_key_event (GdkWaylandSeat *seat,
|
||||
event->key.keyval = sym;
|
||||
event->key.is_modifier = _gdk_wayland_keymap_key_is_modifier (keymap, key);
|
||||
|
||||
translate_keyboard_string (&event->key);
|
||||
|
||||
_gdk_wayland_display_deliver_event (seat->display, event);
|
||||
|
||||
GDK_DISPLAY_NOTE (seat->display, EVENTS,
|
||||
g_message ("keyboard %s event%s, code %d, sym %d, "
|
||||
"string %s, mods 0x%x",
|
||||
"mods 0x%x",
|
||||
(state ? "press" : "release"),
|
||||
(from_key_repeat ? " (repeat)" : ""),
|
||||
event->key.hardware_keycode, event->key.keyval,
|
||||
event->key.string, event->key.state));
|
||||
event->key.state));
|
||||
|
||||
if (!xkb_keymap_key_repeats (xkb_keymap, key))
|
||||
return;
|
||||
@@ -4097,7 +4010,7 @@ tablet_pad_group_handle_buttons (void *data,
|
||||
uint32_t *p;
|
||||
|
||||
GDK_DISPLAY_NOTE (seat->display, EVENTS,
|
||||
g_message ("tablet pad group handle buttons, pad group = %p, n_buttons = %ld",
|
||||
g_message ("tablet pad group handle buttons, pad group = %p, n_buttons = %" G_GSIZE_FORMAT,
|
||||
wp_tablet_pad_group, buttons->size));
|
||||
|
||||
wl_array_for_each (p, buttons)
|
||||
@@ -4531,6 +4444,12 @@ pointer_surface_update_scale (GdkDevice *device)
|
||||
gdk_wayland_device_update_surface_cursor (device);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_wayland_seat_update_cursor_scale (GdkWaylandSeat *seat)
|
||||
{
|
||||
pointer_surface_update_scale (seat->master_pointer);
|
||||
}
|
||||
|
||||
static void
|
||||
pointer_surface_enter (void *data,
|
||||
struct wl_surface *wl_surface,
|
||||
@@ -4571,12 +4490,6 @@ static const struct wl_surface_listener pointer_surface_listener = {
|
||||
pointer_surface_leave
|
||||
};
|
||||
|
||||
static GdkSurface *
|
||||
create_foreign_dnd_surface (GdkDisplay *display)
|
||||
{
|
||||
return gdk_surface_new_popup (display, &(GdkRectangle) { 0, 0, 1, 1 });
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_pointer_data_finalize (GdkWaylandPointerData *pointer)
|
||||
{
|
||||
@@ -4606,11 +4519,11 @@ gdk_wayland_seat_finalize (GObject *object)
|
||||
gdk_wayland_pointer_data_finalize (&seat->pointer_info);
|
||||
/* FIXME: destroy data_device */
|
||||
g_clear_object (&seat->keyboard_settings);
|
||||
g_clear_object (&seat->drop_context);
|
||||
g_clear_object (&seat->drag);
|
||||
g_clear_object (&seat->drop);
|
||||
g_clear_object (&seat->clipboard);
|
||||
g_clear_object (&seat->primary_clipboard);
|
||||
g_hash_table_destroy (seat->touches);
|
||||
gdk_surface_destroy (seat->foreign_dnd_surface);
|
||||
zwp_tablet_seat_v2_destroy (seat->wp_tablet_seat);
|
||||
stop_key_repeat (seat);
|
||||
|
||||
@@ -4952,7 +4865,6 @@ _gdk_wayland_display_create_seat (GdkWaylandDisplay *display_wayland,
|
||||
seat->keymap = _gdk_wayland_keymap_new (display);
|
||||
seat->display = display;
|
||||
seat->touches = g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify) g_free);
|
||||
seat->foreign_dnd_surface = create_foreign_dnd_surface (display);
|
||||
seat->wl_seat = wl_seat;
|
||||
|
||||
wl_seat_add_listener (seat->wl_seat, &seat_listener, seat);
|
||||
@@ -5146,6 +5058,15 @@ gdk_wayland_seat_set_global_cursor (GdkSeat *seat,
|
||||
NULL);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_wayland_seat_set_drag (GdkSeat *seat,
|
||||
GdkDrag *drag)
|
||||
{
|
||||
GdkWaylandSeat *wayland_seat = GDK_WAYLAND_SEAT (seat);
|
||||
|
||||
g_set_object (&wayland_seat->drag, drag);
|
||||
}
|
||||
|
||||
struct wl_data_device *
|
||||
gdk_wayland_device_get_data_device (GdkDevice *gdk_device)
|
||||
{
|
||||
@@ -5189,14 +5110,6 @@ gdk_wayland_seat_get_wl_seat (GdkSeat *seat)
|
||||
return GDK_WAYLAND_SEAT (seat)->wl_seat;
|
||||
}
|
||||
|
||||
GdkDragContext *
|
||||
gdk_wayland_device_get_drop_context (GdkDevice *device)
|
||||
{
|
||||
GdkSeat *seat = gdk_device_get_seat (device);
|
||||
|
||||
return GDK_WAYLAND_SEAT (seat)->drop_context;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_wayland_device_get_node_path:
|
||||
* @device: a #GdkDevice
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#include "gdkdisplay.h"
|
||||
#include "gdkdisplay-wayland.h"
|
||||
#include "gdkmonitor-wayland.h"
|
||||
#include "gdkseat-wayland.h"
|
||||
#include "gdkinternals.h"
|
||||
#include "gdkdeviceprivate.h"
|
||||
#include "gdkkeysprivate.h"
|
||||
@@ -54,6 +55,8 @@
|
||||
|
||||
#include "wm-button-layout-translation.h"
|
||||
|
||||
#include "gdk/gdk-private.h"
|
||||
|
||||
/**
|
||||
* SECTION:wayland_interaction
|
||||
* @Short_description: Wayland backend-specific functions
|
||||
@@ -666,8 +669,6 @@ _gdk_wayland_display_open (const gchar *display_name)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
display_wayland->selection = gdk_wayland_selection_new ();
|
||||
|
||||
gdk_display_emit_opened (display);
|
||||
|
||||
return display;
|
||||
@@ -693,12 +694,6 @@ gdk_wayland_display_dispose (GObject *object)
|
||||
display_wayland->event_source = NULL;
|
||||
}
|
||||
|
||||
if (display_wayland->selection)
|
||||
{
|
||||
gdk_wayland_selection_free (display_wayland->selection);
|
||||
display_wayland->selection = NULL;
|
||||
}
|
||||
|
||||
g_list_free_full (display_wayland->async_roundtrips, (GDestroyNotify) wl_callback_destroy);
|
||||
|
||||
if (display_wayland->known_globals)
|
||||
@@ -817,19 +812,9 @@ gdk_wayland_display_make_default (GdkDisplay *display)
|
||||
g_free (display_wayland->startup_notification_id);
|
||||
display_wayland->startup_notification_id = NULL;
|
||||
|
||||
startup_id = g_getenv ("DESKTOP_STARTUP_ID");
|
||||
if (startup_id && *startup_id != '\0')
|
||||
{
|
||||
if (!g_utf8_validate (startup_id, -1, NULL))
|
||||
g_warning ("DESKTOP_STARTUP_ID contains invalid UTF-8");
|
||||
else
|
||||
display_wayland->startup_notification_id = g_strdup (startup_id);
|
||||
|
||||
/* Clear the environment variable so it won't be inherited by
|
||||
* child processes and confuse things.
|
||||
*/
|
||||
g_unsetenv ("DESKTOP_STARTUP_ID");
|
||||
}
|
||||
startup_id = gdk_get_startup_notification_id ();
|
||||
if (startup_id)
|
||||
display_wayland->startup_notification_id = g_strdup (startup_id);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -865,6 +850,21 @@ gdk_wayland_display_get_next_serial (GdkDisplay *display)
|
||||
return ++serial;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_wayland_display_get_startup_notification_id:
|
||||
* @display: (type GdkX11Display): a #GdkDisplay
|
||||
*
|
||||
* Gets the startup notification ID for a Wayland display, or %NULL
|
||||
* if no ID has been defined.
|
||||
*
|
||||
* Returns: the startup notification ID for @display, or %NULL
|
||||
*/
|
||||
const gchar *
|
||||
gdk_wayland_display_get_startup_notification_id (GdkDisplay *display)
|
||||
{
|
||||
return GDK_WAYLAND_DISPLAY (display)->startup_notification_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_wayland_display_set_startup_notification_id:
|
||||
* @display: (type GdkWaylandDisplay): a #GdkDisplay
|
||||
@@ -1013,6 +1013,7 @@ gdk_wayland_display_class_init (GdkWaylandDisplayClass *class)
|
||||
display_class->supports_input_shapes = gdk_wayland_display_supports_input_shapes;
|
||||
display_class->get_app_launch_context = _gdk_wayland_display_get_app_launch_context;
|
||||
display_class->get_next_serial = gdk_wayland_display_get_next_serial;
|
||||
display_class->get_startup_notification_id = gdk_wayland_display_get_startup_notification_id;
|
||||
display_class->notify_startup_complete = gdk_wayland_display_notify_startup_complete;
|
||||
display_class->create_surface_impl = _gdk_wayland_display_create_surface_impl;
|
||||
display_class->get_keymap = _gdk_wayland_display_get_keymap;
|
||||
@@ -1218,6 +1219,9 @@ open_shared_memory (void)
|
||||
|
||||
if (force_shm_open)
|
||||
{
|
||||
#if defined (__FreeBSD__)
|
||||
ret = shm_open (SHM_ANON, O_CREAT | O_EXCL | O_RDWR | O_CLOEXEC, 0600);
|
||||
#else
|
||||
char name[NAME_MAX - 1] = "";
|
||||
|
||||
sprintf (name, "/gdk-wayland-%x", g_random_int ());
|
||||
@@ -1228,6 +1232,7 @@ open_shared_memory (void)
|
||||
shm_unlink (name);
|
||||
else if (errno == EEXIST)
|
||||
continue;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
while (ret < 0 && errno == EINTR);
|
||||
@@ -1356,15 +1361,6 @@ _gdk_wayland_is_shm_surface (cairo_surface_t *surface)
|
||||
return cairo_surface_get_user_data (surface, &gdk_wayland_shm_surface_cairo_key) != NULL;
|
||||
}
|
||||
|
||||
GdkWaylandSelection *
|
||||
gdk_wayland_display_get_selection (GdkDisplay *display)
|
||||
{
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
|
||||
|
||||
return display_wayland->selection;
|
||||
}
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GSD_FONT_ANTIALIASING_MODE_NONE,
|
||||
@@ -1888,9 +1884,20 @@ transform_to_string (int transform)
|
||||
static void
|
||||
update_scale (GdkDisplay *display)
|
||||
{
|
||||
GList *seats;
|
||||
GList *l;
|
||||
|
||||
g_list_foreach (gdk_wayland_display_get_toplevel_surfaces (display),
|
||||
(GFunc)gdk_wayland_surface_update_scale,
|
||||
NULL);
|
||||
seats = gdk_display_list_seats (display);
|
||||
for (l = seats; l; l = l->next)
|
||||
{
|
||||
GdkSeat *seat = l->data;
|
||||
|
||||
gdk_wayland_seat_update_cursor_scale (GDK_WAYLAND_SEAT (seat));
|
||||
}
|
||||
g_list_free (seats);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -139,8 +139,6 @@ struct _GdkWaylandDisplay
|
||||
|
||||
struct xkb_context *xkb_context;
|
||||
|
||||
GdkWaylandSelection *selection;
|
||||
|
||||
GPtrArray *monitors;
|
||||
|
||||
gint64 last_bell_time_ms;
|
||||
|
||||
@@ -1,589 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2010 Intel Corporation
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gdkdndprivate.h"
|
||||
|
||||
#include "gdkinternals.h"
|
||||
#include "gdkproperty.h"
|
||||
#include "gdkprivate-wayland.h"
|
||||
#include "gdkcontentformats.h"
|
||||
#include "gdkdisplay-wayland.h"
|
||||
#include "gdkintl.h"
|
||||
#include "gdkseat-wayland.h"
|
||||
|
||||
#include "gdkdeviceprivate.h"
|
||||
|
||||
#include <glib-unix.h>
|
||||
#include <gio/gunixinputstream.h>
|
||||
#include <gio/gunixoutputstream.h>
|
||||
#include <string.h>
|
||||
|
||||
#define GDK_TYPE_WAYLAND_DRAG_CONTEXT (gdk_wayland_drag_context_get_type ())
|
||||
#define GDK_WAYLAND_DRAG_CONTEXT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_WAYLAND_DRAG_CONTEXT, GdkWaylandDragContext))
|
||||
#define GDK_WAYLAND_DRAG_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_WAYLAND_DRAG_CONTEXT, GdkWaylandDragContextClass))
|
||||
#define GDK_IS_WAYLAND_DRAG_CONTEXT(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_WAYLAND_DRAG_CONTEXT))
|
||||
#define GDK_IS_WAYLAND_DRAG_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_WAYLAND_DRAG_CONTEXT))
|
||||
#define GDK_WAYLAND_DRAG_CONTEXT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_WAYLAND_DRAG_CONTEXT, GdkWaylandDragContextClass))
|
||||
|
||||
typedef struct _GdkWaylandDragContext GdkWaylandDragContext;
|
||||
typedef struct _GdkWaylandDragContextClass GdkWaylandDragContextClass;
|
||||
|
||||
struct _GdkWaylandDragContext
|
||||
{
|
||||
GdkDragContext context;
|
||||
GdkSurface *dnd_surface;
|
||||
struct wl_surface *dnd_wl_surface;
|
||||
struct wl_data_source *data_source;
|
||||
struct wl_data_offer *offer;
|
||||
GdkDragAction selected_action;
|
||||
uint32_t serial;
|
||||
gdouble x;
|
||||
gdouble y;
|
||||
gint hot_x;
|
||||
gint hot_y;
|
||||
};
|
||||
|
||||
struct _GdkWaylandDragContextClass
|
||||
{
|
||||
GdkDragContextClass parent_class;
|
||||
};
|
||||
|
||||
static GList *contexts;
|
||||
|
||||
GType gdk_wayland_drag_context_get_type (void);
|
||||
|
||||
G_DEFINE_TYPE (GdkWaylandDragContext, gdk_wayland_drag_context, GDK_TYPE_DRAG_CONTEXT)
|
||||
|
||||
static void
|
||||
gdk_wayland_drag_context_finalize (GObject *object)
|
||||
{
|
||||
GdkWaylandDragContext *wayland_context = GDK_WAYLAND_DRAG_CONTEXT (object);
|
||||
GdkDragContext *context = GDK_DRAG_CONTEXT (object);
|
||||
GdkSurface *dnd_surface;
|
||||
|
||||
contexts = g_list_remove (contexts, context);
|
||||
|
||||
if (context->is_source)
|
||||
{
|
||||
gdk_drag_context_set_cursor (context, NULL);
|
||||
}
|
||||
|
||||
g_clear_pointer (&wayland_context->data_source, (GDestroyNotify) wl_data_source_destroy);
|
||||
g_clear_pointer (&wayland_context->offer, (GDestroyNotify) wl_data_offer_destroy);
|
||||
|
||||
dnd_surface = wayland_context->dnd_surface;
|
||||
|
||||
G_OBJECT_CLASS (gdk_wayland_drag_context_parent_class)->finalize (object);
|
||||
|
||||
if (dnd_surface)
|
||||
gdk_surface_destroy (dnd_surface);
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_wayland_drag_context_emit_event (GdkDragContext *context,
|
||||
GdkEventType type,
|
||||
guint32 time_)
|
||||
{
|
||||
GdkSurface *surface;
|
||||
GdkEvent *event;
|
||||
|
||||
switch ((guint) type)
|
||||
{
|
||||
case GDK_DRAG_ENTER:
|
||||
case GDK_DRAG_LEAVE:
|
||||
case GDK_DRAG_MOTION:
|
||||
case GDK_DROP_START:
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
if (context->is_source)
|
||||
surface = gdk_drag_context_get_source_surface (context);
|
||||
else
|
||||
surface = gdk_drag_context_get_dest_surface (context);
|
||||
|
||||
event = gdk_event_new (type);
|
||||
event->any.surface = g_object_ref (surface);
|
||||
event->dnd.context = g_object_ref (context);
|
||||
event->dnd.time = time_;
|
||||
event->dnd.x_root = GDK_WAYLAND_DRAG_CONTEXT (context)->x;
|
||||
event->dnd.y_root = GDK_WAYLAND_DRAG_CONTEXT (context)->y;
|
||||
gdk_event_set_device (event, gdk_drag_context_get_device (context));
|
||||
|
||||
gdk_display_put_event (gdk_surface_get_display (surface), event);
|
||||
g_object_unref (event);
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
gdk_to_wl_actions (GdkDragAction action)
|
||||
{
|
||||
uint32_t dnd_actions = 0;
|
||||
|
||||
if (action & (GDK_ACTION_COPY | GDK_ACTION_LINK | GDK_ACTION_PRIVATE))
|
||||
dnd_actions |= WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY;
|
||||
if (action & GDK_ACTION_MOVE)
|
||||
dnd_actions |= WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE;
|
||||
if (action & GDK_ACTION_ASK)
|
||||
dnd_actions |= WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK;
|
||||
|
||||
return dnd_actions;
|
||||
}
|
||||
|
||||
void
|
||||
gdk_wayland_drag_context_set_action (GdkDragContext *context,
|
||||
GdkDragAction action)
|
||||
{
|
||||
context->suggested_action = context->action = action;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_drag_context_drag_abort (GdkDragContext *context,
|
||||
guint32 time)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_drag_context_drag_drop (GdkDragContext *context,
|
||||
guint32 time)
|
||||
{
|
||||
}
|
||||
|
||||
/* Destination side */
|
||||
|
||||
static void
|
||||
gdk_wayland_drop_context_set_status (GdkDragContext *context,
|
||||
gboolean accepted)
|
||||
{
|
||||
GdkWaylandDragContext *context_wayland = GDK_WAYLAND_DRAG_CONTEXT (context);
|
||||
|
||||
if (!context->dest_surface)
|
||||
return;
|
||||
|
||||
if (accepted)
|
||||
{
|
||||
const char *const *mimetypes;
|
||||
gsize i, n_mimetypes;
|
||||
|
||||
mimetypes = gdk_content_formats_get_mime_types (gdk_drag_context_get_formats (context), &n_mimetypes);
|
||||
for (i = 0; i < n_mimetypes; i++)
|
||||
{
|
||||
if (mimetypes[i] != g_intern_static_string ("DELETE"))
|
||||
break;
|
||||
}
|
||||
|
||||
if (i < n_mimetypes)
|
||||
{
|
||||
wl_data_offer_accept (context_wayland->offer, context_wayland->serial, mimetypes[i]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
wl_data_offer_accept (context_wayland->offer, context_wayland->serial, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_drag_context_commit_status (GdkDragContext *context)
|
||||
{
|
||||
GdkWaylandDragContext *wayland_context = GDK_WAYLAND_DRAG_CONTEXT (context);
|
||||
GdkDisplay *display;
|
||||
uint32_t dnd_actions, all_actions = 0;
|
||||
|
||||
display = gdk_device_get_display (gdk_drag_context_get_device (context));
|
||||
|
||||
dnd_actions = gdk_to_wl_actions (wayland_context->selected_action);
|
||||
|
||||
if (dnd_actions != 0)
|
||||
all_actions = WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY |
|
||||
WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE |
|
||||
WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK;
|
||||
|
||||
if (GDK_WAYLAND_DISPLAY (display)->data_device_manager_version >=
|
||||
WL_DATA_OFFER_SET_ACTIONS_SINCE_VERSION)
|
||||
wl_data_offer_set_actions (wayland_context->offer, all_actions, dnd_actions);
|
||||
|
||||
gdk_wayland_drop_context_set_status (context, wayland_context->selected_action != 0);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_drag_context_drag_status (GdkDragContext *context,
|
||||
GdkDragAction action,
|
||||
guint32 time_)
|
||||
{
|
||||
GdkWaylandDragContext *wayland_context;
|
||||
|
||||
wayland_context = GDK_WAYLAND_DRAG_CONTEXT (context);
|
||||
wayland_context->selected_action = action;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_drag_context_drop_finish (GdkDragContext *context,
|
||||
gboolean success,
|
||||
guint32 time)
|
||||
{
|
||||
GdkWaylandDragContext *wayland_context = GDK_WAYLAND_DRAG_CONTEXT (context);
|
||||
GdkDisplay *display = gdk_device_get_display (gdk_drag_context_get_device (context));
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
|
||||
|
||||
if (success && wayland_context->selected_action &&
|
||||
wayland_context->selected_action != GDK_ACTION_ASK)
|
||||
{
|
||||
gdk_wayland_drag_context_commit_status (context);
|
||||
|
||||
if (display_wayland->data_device_manager_version >=
|
||||
WL_DATA_OFFER_FINISH_SINCE_VERSION)
|
||||
wl_data_offer_finish (wayland_context->offer);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_drag_context_read_async (GdkDragContext *context,
|
||||
GdkContentFormats *formats,
|
||||
int io_priority,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
GdkWaylandDragContext *wayland_context = GDK_WAYLAND_DRAG_CONTEXT (context);
|
||||
GdkDisplay *display;
|
||||
GInputStream *stream;
|
||||
const char *mime_type;
|
||||
int pipe_fd[2];
|
||||
GError *error = NULL;
|
||||
GTask *task;
|
||||
|
||||
display = gdk_drag_context_get_display (context),
|
||||
task = g_task_new (context, cancellable, callback, user_data);
|
||||
g_task_set_priority (task, io_priority);
|
||||
g_task_set_source_tag (task, gdk_wayland_drag_context_read_async);
|
||||
|
||||
GDK_DISPLAY_NOTE (display, DND, char *s = gdk_content_formats_to_string (formats);
|
||||
g_message ("%p: read for %s", context, s);
|
||||
g_free (s); );
|
||||
mime_type = gdk_content_formats_match_mime_type (formats,
|
||||
gdk_drag_context_get_formats (context));
|
||||
if (mime_type == NULL)
|
||||
{
|
||||
g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
|
||||
_("No compatible transfer format found"));
|
||||
return;
|
||||
}
|
||||
|
||||
g_task_set_task_data (task, (gpointer) mime_type, NULL);
|
||||
|
||||
if (!g_unix_open_pipe (pipe_fd, FD_CLOEXEC, &error))
|
||||
{
|
||||
g_task_return_error (task, error);
|
||||
return;
|
||||
}
|
||||
|
||||
wl_data_offer_receive (wayland_context->offer, mime_type, pipe_fd[1]);
|
||||
stream = g_unix_input_stream_new (pipe_fd[0], TRUE);
|
||||
close (pipe_fd[1]);
|
||||
g_task_return_pointer (task, stream, g_object_unref);
|
||||
}
|
||||
|
||||
static GInputStream *
|
||||
gdk_wayland_drag_context_read_finish (GdkDragContext *context,
|
||||
const char **out_mime_type,
|
||||
GAsyncResult *result,
|
||||
GError **error)
|
||||
{
|
||||
GTask *task;
|
||||
|
||||
g_return_val_if_fail (g_task_is_valid (result, G_OBJECT (context)), NULL);
|
||||
task = G_TASK (result);
|
||||
g_return_val_if_fail (g_task_get_source_tag (task) == gdk_wayland_drag_context_read_async, NULL);
|
||||
|
||||
if (out_mime_type)
|
||||
*out_mime_type = g_task_get_task_data (task);
|
||||
|
||||
return g_task_propagate_pointer (task, error);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_drag_context_init (GdkWaylandDragContext *context_wayland)
|
||||
{
|
||||
GdkDragContext *context;
|
||||
|
||||
context = GDK_DRAG_CONTEXT (context_wayland);
|
||||
contexts = g_list_prepend (contexts, context);
|
||||
|
||||
context->action = GDK_ACTION_COPY;
|
||||
context->suggested_action = GDK_ACTION_COPY;
|
||||
context->actions = GDK_ACTION_COPY | GDK_ACTION_MOVE;
|
||||
}
|
||||
|
||||
static GdkSurface *
|
||||
gdk_wayland_drag_context_get_drag_surface (GdkDragContext *context)
|
||||
{
|
||||
return GDK_WAYLAND_DRAG_CONTEXT (context)->dnd_surface;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_drag_context_set_hotspot (GdkDragContext *context,
|
||||
gint hot_x,
|
||||
gint hot_y)
|
||||
{
|
||||
GdkWaylandDragContext *context_wayland = GDK_WAYLAND_DRAG_CONTEXT (context);
|
||||
gint prev_hot_x = context_wayland->hot_x;
|
||||
gint prev_hot_y = context_wayland->hot_y;
|
||||
const GdkRectangle damage_rect = { .width = 1, .height = 1 };
|
||||
|
||||
context_wayland->hot_x = hot_x;
|
||||
context_wayland->hot_y = hot_y;
|
||||
|
||||
if (prev_hot_x == hot_x && prev_hot_y == hot_y)
|
||||
return;
|
||||
|
||||
_gdk_wayland_surface_offset_next_wl_buffer (context_wayland->dnd_surface,
|
||||
-hot_x, -hot_y);
|
||||
gdk_surface_invalidate_rect (context_wayland->dnd_surface, &damage_rect);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_drag_context_set_cursor (GdkDragContext *context,
|
||||
GdkCursor *cursor)
|
||||
{
|
||||
GdkDevice *device = gdk_drag_context_get_device (context);
|
||||
|
||||
gdk_wayland_seat_set_global_cursor (gdk_device_get_seat (device), cursor);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_drag_context_action_changed (GdkDragContext *context,
|
||||
GdkDragAction action)
|
||||
{
|
||||
GdkCursor *cursor;
|
||||
|
||||
cursor = gdk_drag_get_cursor (context, action);
|
||||
gdk_drag_context_set_cursor (context, cursor);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_drag_context_drop_performed (GdkDragContext *context,
|
||||
guint32 time_)
|
||||
{
|
||||
gdk_drag_context_set_cursor (context, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_drag_context_cancel (GdkDragContext *context,
|
||||
GdkDragCancelReason reason)
|
||||
{
|
||||
gdk_drag_context_set_cursor (context, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_drag_context_drop_done (GdkDragContext *context,
|
||||
gboolean success)
|
||||
{
|
||||
GdkWaylandDragContext *context_wayland = GDK_WAYLAND_DRAG_CONTEXT (context);
|
||||
|
||||
if (success)
|
||||
{
|
||||
if (context_wayland->dnd_surface)
|
||||
gdk_surface_hide (context_wayland->dnd_surface);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_drag_context_class_init (GdkWaylandDragContextClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GdkDragContextClass *context_class = GDK_DRAG_CONTEXT_CLASS (klass);
|
||||
|
||||
object_class->finalize = gdk_wayland_drag_context_finalize;
|
||||
|
||||
context_class->drag_status = gdk_wayland_drag_context_drag_status;
|
||||
context_class->drag_abort = gdk_wayland_drag_context_drag_abort;
|
||||
context_class->drag_drop = gdk_wayland_drag_context_drag_drop;
|
||||
context_class->drop_finish = gdk_wayland_drag_context_drop_finish;
|
||||
context_class->drop_finish = gdk_wayland_drag_context_drop_finish;
|
||||
context_class->read_async = gdk_wayland_drag_context_read_async;
|
||||
context_class->read_finish = gdk_wayland_drag_context_read_finish;
|
||||
context_class->get_drag_surface = gdk_wayland_drag_context_get_drag_surface;
|
||||
context_class->set_hotspot = gdk_wayland_drag_context_set_hotspot;
|
||||
context_class->drop_done = gdk_wayland_drag_context_drop_done;
|
||||
context_class->set_cursor = gdk_wayland_drag_context_set_cursor;
|
||||
context_class->action_changed = gdk_wayland_drag_context_action_changed;
|
||||
context_class->drop_performed = gdk_wayland_drag_context_drop_performed;
|
||||
context_class->cancel = gdk_wayland_drag_context_cancel;
|
||||
context_class->commit_drag_status = gdk_wayland_drag_context_commit_status;
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_wayland_surface_register_dnd (GdkSurface *surface)
|
||||
{
|
||||
}
|
||||
|
||||
static GdkSurface *
|
||||
create_dnd_surface (GdkDisplay *display)
|
||||
{
|
||||
GdkSurface *surface;
|
||||
|
||||
surface = gdk_surface_new_popup (display, &(GdkRectangle) { 0, 0, 100, 100 });
|
||||
|
||||
gdk_surface_set_type_hint (surface, GDK_SURFACE_TYPE_HINT_DND);
|
||||
|
||||
return surface;
|
||||
}
|
||||
|
||||
GdkDragContext *
|
||||
_gdk_wayland_surface_drag_begin (GdkSurface *surface,
|
||||
GdkDevice *device,
|
||||
GdkContentProvider *content,
|
||||
GdkDragAction actions,
|
||||
gint dx,
|
||||
gint dy)
|
||||
{
|
||||
GdkWaylandDragContext *context_wayland;
|
||||
GdkDragContext *context;
|
||||
GdkWaylandDisplay *display_wayland;
|
||||
const char *const *mimetypes;
|
||||
gsize i, n_mimetypes;
|
||||
|
||||
display_wayland = GDK_WAYLAND_DISPLAY (gdk_device_get_display (device));
|
||||
|
||||
context_wayland = g_object_new (GDK_TYPE_WAYLAND_DRAG_CONTEXT,
|
||||
"device", device,
|
||||
"content", content,
|
||||
NULL);
|
||||
context = GDK_DRAG_CONTEXT (context_wayland);
|
||||
context->source_surface = g_object_ref (surface);
|
||||
context->is_source = TRUE;
|
||||
|
||||
context_wayland->dnd_surface = create_dnd_surface (gdk_surface_get_display (surface));
|
||||
context_wayland->dnd_wl_surface = gdk_wayland_surface_get_wl_surface (context_wayland->dnd_surface);
|
||||
context_wayland->data_source =
|
||||
gdk_wayland_selection_get_data_source (surface);
|
||||
|
||||
mimetypes = gdk_content_formats_get_mime_types (gdk_drag_context_get_formats (context), &n_mimetypes);
|
||||
for (i = 0; i < n_mimetypes; i++)
|
||||
{
|
||||
wl_data_source_offer (context_wayland->data_source, mimetypes[i]);
|
||||
}
|
||||
|
||||
if (display_wayland->data_device_manager_version >=
|
||||
WL_DATA_SOURCE_SET_ACTIONS_SINCE_VERSION)
|
||||
{
|
||||
wl_data_source_set_actions (context_wayland->data_source,
|
||||
gdk_to_wl_actions (actions));
|
||||
}
|
||||
|
||||
wl_data_device_start_drag (gdk_wayland_device_get_data_device (device),
|
||||
context_wayland->data_source,
|
||||
gdk_wayland_surface_get_wl_surface (surface),
|
||||
context_wayland->dnd_wl_surface,
|
||||
_gdk_wayland_display_get_serial (display_wayland));
|
||||
|
||||
gdk_seat_ungrab (gdk_device_get_seat (device));
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
|
||||
GdkDragContext *
|
||||
_gdk_wayland_drop_context_new (GdkDevice *device,
|
||||
GdkContentFormats *formats,
|
||||
struct wl_data_offer *offer)
|
||||
{
|
||||
GdkWaylandDragContext *context_wayland;
|
||||
GdkDragContext *context;
|
||||
|
||||
context_wayland = g_object_new (GDK_TYPE_WAYLAND_DRAG_CONTEXT,
|
||||
"device", device,
|
||||
"formats", formats,
|
||||
NULL);
|
||||
context = GDK_DRAG_CONTEXT (context_wayland);
|
||||
context->is_source = FALSE;
|
||||
context_wayland->offer = offer;
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_wayland_drag_context_set_coords (GdkDragContext *context,
|
||||
gdouble x,
|
||||
gdouble y)
|
||||
{
|
||||
GdkWaylandDragContext *context_wayland;
|
||||
|
||||
context_wayland = GDK_WAYLAND_DRAG_CONTEXT (context);
|
||||
context_wayland->x = x;
|
||||
context_wayland->y = y;
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_wayland_drag_context_set_source_surface (GdkDragContext *context,
|
||||
GdkSurface *surface)
|
||||
{
|
||||
if (context->source_surface)
|
||||
g_object_unref (context->source_surface);
|
||||
|
||||
context->source_surface = surface ? g_object_ref (surface) : NULL;
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_wayland_drag_context_set_dest_surface (GdkDragContext *context,
|
||||
GdkSurface *dest_surface,
|
||||
uint32_t serial)
|
||||
{
|
||||
if (context->dest_surface)
|
||||
g_object_unref (context->dest_surface);
|
||||
|
||||
context->dest_surface = dest_surface ? g_object_ref (dest_surface) : NULL;
|
||||
GDK_WAYLAND_DRAG_CONTEXT (context)->serial = serial;
|
||||
}
|
||||
|
||||
GdkDragContext *
|
||||
gdk_wayland_drag_context_lookup_by_data_source (struct wl_data_source *source)
|
||||
{
|
||||
GList *l;
|
||||
|
||||
for (l = contexts; l; l = l->next)
|
||||
{
|
||||
GdkWaylandDragContext *wayland_context = l->data;
|
||||
|
||||
if (wayland_context->data_source == source)
|
||||
return l->data;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GdkDragContext *
|
||||
gdk_wayland_drag_context_lookup_by_source_surface (GdkSurface *surface)
|
||||
{
|
||||
GList *l;
|
||||
|
||||
for (l = contexts; l; l = l->next)
|
||||
{
|
||||
if (surface == gdk_drag_context_get_source_surface (l->data))
|
||||
return l->data;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct wl_data_source *
|
||||
gdk_wayland_drag_context_get_data_source (GdkDragContext *context)
|
||||
{
|
||||
return GDK_WAYLAND_DRAG_CONTEXT (context)->data_source;
|
||||
}
|
||||
@@ -0,0 +1,409 @@
|
||||
/*
|
||||
* Copyright © 2010 Intel Corporation
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gdkdragprivate.h"
|
||||
|
||||
#include "gdkinternals.h"
|
||||
#include "gdkproperty.h"
|
||||
#include "gdkprivate-wayland.h"
|
||||
#include "gdkcontentformats.h"
|
||||
#include "gdkdisplay-wayland.h"
|
||||
#include "gdkintl.h"
|
||||
#include "gdkseat-wayland.h"
|
||||
|
||||
#include "gdkdeviceprivate.h"
|
||||
|
||||
#include <glib-unix.h>
|
||||
#include <gio/gunixinputstream.h>
|
||||
#include <gio/gunixoutputstream.h>
|
||||
#include <string.h>
|
||||
|
||||
#define GDK_TYPE_WAYLAND_DRAG (gdk_wayland_drag_get_type ())
|
||||
#define GDK_WAYLAND_DRAG(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_WAYLAND_DRAG, GdkWaylandDrag))
|
||||
#define GDK_WAYLAND_DRAG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_WAYLAND_DRAG, GdkWaylandDragClass))
|
||||
#define GDK_IS_WAYLAND_DRAG(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_WAYLAND_DRAG))
|
||||
#define GDK_IS_WAYLAND_DRAG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_WAYLAND_DRAG))
|
||||
#define GDK_WAYLAND_DRAG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_WAYLAND_DRAG, GdkWaylandDragClass))
|
||||
|
||||
typedef struct _GdkWaylandDrag GdkWaylandDrag;
|
||||
typedef struct _GdkWaylandDragClass GdkWaylandDragClass;
|
||||
|
||||
struct _GdkWaylandDrag
|
||||
{
|
||||
GdkDrag drag;
|
||||
GdkSurface *dnd_surface;
|
||||
struct wl_surface *dnd_wl_surface;
|
||||
struct wl_data_source *data_source;
|
||||
struct wl_data_offer *offer;
|
||||
uint32_t serial;
|
||||
gint hot_x;
|
||||
gint hot_y;
|
||||
};
|
||||
|
||||
struct _GdkWaylandDragClass
|
||||
{
|
||||
GdkDragClass parent_class;
|
||||
};
|
||||
|
||||
static GList *drags;
|
||||
|
||||
GType gdk_wayland_drag_get_type (void);
|
||||
|
||||
G_DEFINE_TYPE (GdkWaylandDrag, gdk_wayland_drag, GDK_TYPE_DRAG)
|
||||
|
||||
static void
|
||||
gdk_wayland_drag_finalize (GObject *object)
|
||||
{
|
||||
GdkWaylandDrag *wayland_drag = GDK_WAYLAND_DRAG (object);
|
||||
GdkDrag *drag = GDK_DRAG (object);
|
||||
GdkSurface *dnd_surface;
|
||||
|
||||
drags = g_list_remove (drags, drag);
|
||||
|
||||
gdk_drag_set_cursor (drag, NULL);
|
||||
|
||||
g_clear_pointer (&wayland_drag->data_source, wl_data_source_destroy);
|
||||
g_clear_pointer (&wayland_drag->offer, wl_data_offer_destroy);
|
||||
|
||||
dnd_surface = wayland_drag->dnd_surface;
|
||||
|
||||
G_OBJECT_CLASS (gdk_wayland_drag_parent_class)->finalize (object);
|
||||
|
||||
if (dnd_surface)
|
||||
gdk_surface_destroy (dnd_surface);
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
gdk_to_wl_actions (GdkDragAction action)
|
||||
{
|
||||
uint32_t dnd_actions = 0;
|
||||
|
||||
if (action & (GDK_ACTION_COPY | GDK_ACTION_LINK))
|
||||
dnd_actions |= WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY;
|
||||
if (action & GDK_ACTION_MOVE)
|
||||
dnd_actions |= WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE;
|
||||
if (action & GDK_ACTION_ASK)
|
||||
dnd_actions |= WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK;
|
||||
|
||||
return dnd_actions;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_drag_init (GdkWaylandDrag *drag_wayland)
|
||||
{
|
||||
GdkDrag *drag;
|
||||
|
||||
drag = GDK_DRAG (drag_wayland);
|
||||
drags = g_list_prepend (drags, drag);
|
||||
|
||||
gdk_drag_set_selected_action (drag, GDK_ACTION_COPY);
|
||||
}
|
||||
|
||||
static GdkSurface *
|
||||
gdk_wayland_drag_get_drag_surface (GdkDrag *drag)
|
||||
{
|
||||
return GDK_WAYLAND_DRAG (drag)->dnd_surface;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_drag_set_hotspot (GdkDrag *drag,
|
||||
gint hot_x,
|
||||
gint hot_y)
|
||||
{
|
||||
GdkWaylandDrag *drag_wayland = GDK_WAYLAND_DRAG (drag);
|
||||
gint prev_hot_x = drag_wayland->hot_x;
|
||||
gint prev_hot_y = drag_wayland->hot_y;
|
||||
const GdkRectangle damage_rect = { .width = 1, .height = 1 };
|
||||
|
||||
drag_wayland->hot_x = hot_x;
|
||||
drag_wayland->hot_y = hot_y;
|
||||
|
||||
if (prev_hot_x == hot_x && prev_hot_y == hot_y)
|
||||
return;
|
||||
|
||||
_gdk_wayland_surface_offset_next_wl_buffer (drag_wayland->dnd_surface,
|
||||
-hot_x, -hot_y);
|
||||
gdk_surface_invalidate_rect (drag_wayland->dnd_surface, &damage_rect);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_drag_set_cursor (GdkDrag *drag,
|
||||
GdkCursor *cursor)
|
||||
{
|
||||
GdkDevice *device = gdk_drag_get_device (drag);
|
||||
|
||||
if (device != NULL)
|
||||
gdk_wayland_seat_set_global_cursor (gdk_device_get_seat (device), cursor);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_drag_drop_performed (GdkDrag *drag,
|
||||
guint32 time_)
|
||||
{
|
||||
gdk_drag_set_cursor (drag, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_drag_cancel (GdkDrag *drag,
|
||||
GdkDragCancelReason reason)
|
||||
{
|
||||
gdk_drag_set_cursor (drag, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_drag_drop_done (GdkDrag *drag,
|
||||
gboolean success)
|
||||
{
|
||||
GdkWaylandDrag *drag_wayland = GDK_WAYLAND_DRAG (drag);
|
||||
GdkDevice *device = gdk_drag_get_device (drag);
|
||||
|
||||
gdk_wayland_seat_set_drag (gdk_device_get_seat (device), drag);
|
||||
|
||||
if (success)
|
||||
{
|
||||
if (drag_wayland->dnd_surface)
|
||||
gdk_surface_hide (drag_wayland->dnd_surface);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_drag_class_init (GdkWaylandDragClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GdkDragClass *drag_class = GDK_DRAG_CLASS (klass);
|
||||
|
||||
object_class->finalize = gdk_wayland_drag_finalize;
|
||||
|
||||
drag_class->get_drag_surface = gdk_wayland_drag_get_drag_surface;
|
||||
drag_class->set_hotspot = gdk_wayland_drag_set_hotspot;
|
||||
drag_class->drop_done = gdk_wayland_drag_drop_done;
|
||||
drag_class->set_cursor = gdk_wayland_drag_set_cursor;
|
||||
drag_class->drop_performed = gdk_wayland_drag_drop_performed;
|
||||
drag_class->cancel = gdk_wayland_drag_cancel;
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_wayland_surface_register_dnd (GdkSurface *surface)
|
||||
{
|
||||
}
|
||||
|
||||
static GdkSurface *
|
||||
create_dnd_surface (GdkDisplay *display)
|
||||
{
|
||||
GdkSurface *surface;
|
||||
|
||||
surface = gdk_surface_new_popup (display, &(GdkRectangle) { 0, 0, 100, 100 });
|
||||
|
||||
gdk_surface_set_type_hint (surface, GDK_SURFACE_TYPE_HINT_DND);
|
||||
|
||||
return surface;
|
||||
}
|
||||
|
||||
static inline GdkDragAction
|
||||
_wl_to_gdk_actions (uint32_t dnd_actions)
|
||||
{
|
||||
GdkDragAction actions = 0;
|
||||
|
||||
if (dnd_actions & WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY)
|
||||
actions |= GDK_ACTION_COPY;
|
||||
if (dnd_actions & WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE)
|
||||
actions |= GDK_ACTION_MOVE;
|
||||
if (dnd_actions & WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK)
|
||||
actions |= GDK_ACTION_ASK;
|
||||
|
||||
return actions;
|
||||
}
|
||||
|
||||
static void
|
||||
data_source_target (void *data,
|
||||
struct wl_data_source *source,
|
||||
const char *mime_type)
|
||||
{
|
||||
GDK_NOTE (EVENTS,
|
||||
g_message ("data source target, source = %p, mime_type = %s",
|
||||
source, mime_type));
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_drag_write_done (GObject *drag,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
GError *error = NULL;
|
||||
|
||||
if (!gdk_drag_write_finish (GDK_DRAG (drag), result, &error))
|
||||
{
|
||||
GDK_DISPLAY_NOTE (gdk_drag_get_display (GDK_DRAG (drag)), DND, g_message ("%p: failed to write stream: %s", drag, error->message));
|
||||
g_error_free (error);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
data_source_send (void *data,
|
||||
struct wl_data_source *source,
|
||||
const char *mime_type,
|
||||
int32_t fd)
|
||||
{
|
||||
GdkDrag *drag = data;
|
||||
GOutputStream *stream;
|
||||
|
||||
GDK_DISPLAY_NOTE (gdk_drag_get_display (drag), DND, g_message ("%p: data source send request for %s on fd %d\n",
|
||||
source, mime_type, fd));
|
||||
|
||||
//mime_type = gdk_intern_mime_type (mime_type);
|
||||
mime_type = g_intern_string (mime_type);
|
||||
stream = g_unix_output_stream_new (fd, TRUE);
|
||||
|
||||
gdk_drag_write_async (drag,
|
||||
mime_type,
|
||||
stream,
|
||||
G_PRIORITY_DEFAULT,
|
||||
NULL,
|
||||
gdk_wayland_drag_write_done,
|
||||
drag);
|
||||
g_object_unref (stream);
|
||||
}
|
||||
|
||||
static void
|
||||
data_source_cancelled (void *data,
|
||||
struct wl_data_source *source)
|
||||
{
|
||||
GdkDrag *drag = data;
|
||||
|
||||
GDK_DISPLAY_NOTE (gdk_drag_get_display (drag), EVENTS,
|
||||
g_message ("data source cancelled, source = %p", source));
|
||||
|
||||
gdk_drag_cancel (drag, GDK_DRAG_CANCEL_ERROR);
|
||||
}
|
||||
|
||||
static void
|
||||
data_source_dnd_drop_performed (void *data,
|
||||
struct wl_data_source *source)
|
||||
{
|
||||
GdkDrag *drag = data;
|
||||
|
||||
g_signal_emit_by_name (drag, "drop-performed");
|
||||
}
|
||||
|
||||
static void
|
||||
data_source_dnd_finished (void *data,
|
||||
struct wl_data_source *source)
|
||||
{
|
||||
GdkDrag *drag = data;
|
||||
|
||||
g_signal_emit_by_name (drag, "dnd-finished");
|
||||
}
|
||||
|
||||
static void
|
||||
data_source_action (void *data,
|
||||
struct wl_data_source *source,
|
||||
uint32_t action)
|
||||
{
|
||||
GdkDrag *drag = data;
|
||||
|
||||
GDK_DISPLAY_NOTE (gdk_drag_get_display (drag), EVENTS,
|
||||
g_message ("data source action, source = %p action=%x",
|
||||
source, action));
|
||||
|
||||
gdk_drag_set_selected_action (drag, _wl_to_gdk_actions (action));
|
||||
}
|
||||
|
||||
static const struct wl_data_source_listener data_source_listener = {
|
||||
data_source_target,
|
||||
data_source_send,
|
||||
data_source_cancelled,
|
||||
data_source_dnd_drop_performed,
|
||||
data_source_dnd_finished,
|
||||
data_source_action,
|
||||
};
|
||||
|
||||
static void
|
||||
gdk_wayland_drag_create_data_source (GdkDrag *drag)
|
||||
{
|
||||
GdkWaylandDrag *drag_wayland = GDK_WAYLAND_DRAG (drag);
|
||||
GdkDisplay *display = gdk_drag_get_display (drag);
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
|
||||
const char *const *mimetypes;
|
||||
gsize i, n_mimetypes;
|
||||
|
||||
drag_wayland->data_source = wl_data_device_manager_create_data_source (display_wayland->data_device_manager);
|
||||
wl_data_source_add_listener (drag_wayland->data_source,
|
||||
&data_source_listener,
|
||||
drag);
|
||||
|
||||
mimetypes = gdk_content_formats_get_mime_types (gdk_drag_get_formats (drag), &n_mimetypes);
|
||||
for (i = 0; i < n_mimetypes; i++)
|
||||
{
|
||||
wl_data_source_offer (drag_wayland->data_source, mimetypes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
GdkDrag *
|
||||
_gdk_wayland_surface_drag_begin (GdkSurface *surface,
|
||||
GdkDevice *device,
|
||||
GdkContentProvider *content,
|
||||
GdkDragAction actions,
|
||||
gint dx,
|
||||
gint dy)
|
||||
{
|
||||
GdkWaylandDrag *drag_wayland;
|
||||
GdkDrag *drag;
|
||||
GdkSeat *seat;
|
||||
GdkWaylandDisplay *display_wayland;
|
||||
GdkCursor *cursor;
|
||||
|
||||
display_wayland = GDK_WAYLAND_DISPLAY (gdk_device_get_display (device));
|
||||
seat = gdk_device_get_seat (device);
|
||||
|
||||
drag_wayland = g_object_new (GDK_TYPE_WAYLAND_DRAG,
|
||||
"surface", surface,
|
||||
"device", device,
|
||||
"content", content,
|
||||
"actions", actions,
|
||||
NULL);
|
||||
|
||||
drag = GDK_DRAG (drag_wayland);
|
||||
|
||||
drag_wayland->dnd_surface = create_dnd_surface (gdk_surface_get_display (surface));
|
||||
drag_wayland->dnd_wl_surface = gdk_wayland_surface_get_wl_surface (drag_wayland->dnd_surface);
|
||||
|
||||
gdk_wayland_drag_create_data_source (drag);
|
||||
|
||||
if (display_wayland->data_device_manager_version >=
|
||||
WL_DATA_SOURCE_SET_ACTIONS_SINCE_VERSION)
|
||||
{
|
||||
wl_data_source_set_actions (drag_wayland->data_source,
|
||||
gdk_to_wl_actions (actions));
|
||||
}
|
||||
|
||||
gdk_wayland_seat_set_drag (seat, drag);
|
||||
|
||||
wl_data_device_start_drag (gdk_wayland_device_get_data_device (device),
|
||||
drag_wayland->data_source,
|
||||
gdk_wayland_surface_get_wl_surface (surface),
|
||||
drag_wayland->dnd_wl_surface,
|
||||
_gdk_wayland_display_get_serial (display_wayland));
|
||||
|
||||
cursor = gdk_drag_get_cursor (drag, gdk_drag_get_selected_action (drag));
|
||||
gdk_drag_set_cursor (drag, cursor);
|
||||
|
||||
gdk_seat_ungrab (seat);
|
||||
|
||||
return drag;
|
||||
}
|
||||
@@ -0,0 +1,325 @@
|
||||
/*
|
||||
* Copyright © 2010 Intel Corporation
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gdkdropprivate.h"
|
||||
|
||||
#include "gdkinternals.h"
|
||||
#include "gdkproperty.h"
|
||||
#include "gdkprivate-wayland.h"
|
||||
#include "gdkcontentformats.h"
|
||||
#include "gdkdisplay-wayland.h"
|
||||
#include "gdkintl.h"
|
||||
#include "gdkseat-wayland.h"
|
||||
|
||||
#include "gdkdeviceprivate.h"
|
||||
|
||||
#include <glib-unix.h>
|
||||
#include <gio/gunixinputstream.h>
|
||||
#include <gio/gunixoutputstream.h>
|
||||
#include <string.h>
|
||||
|
||||
#define GDK_TYPE_WAYLAND_DROP (gdk_wayland_drop_get_type ())
|
||||
#define GDK_WAYLAND_DROP(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_WAYLAND_DROP, GdkWaylandDrop))
|
||||
#define GDK_WAYLAND_DROP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_WAYLAND_DROP, GdkWaylandDropClass))
|
||||
#define GDK_IS_WAYLAND_DROP(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_WAYLAND_DROP))
|
||||
#define GDK_IS_WAYLAND_DROP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_WAYLAND_DROP))
|
||||
#define GDK_WAYLAND_DROP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_WAYLAND_DROP, GdkWaylandDropClass))
|
||||
|
||||
typedef struct _GdkWaylandDrop GdkWaylandDrop;
|
||||
typedef struct _GdkWaylandDropClass GdkWaylandDropClass;
|
||||
|
||||
struct _GdkWaylandDrop
|
||||
{
|
||||
GdkDrop drop;
|
||||
|
||||
struct wl_data_offer *offer;
|
||||
uint32_t source_actions;
|
||||
uint32_t action;
|
||||
GdkDragAction selected_action;
|
||||
uint32_t serial;
|
||||
};
|
||||
|
||||
struct _GdkWaylandDropClass
|
||||
{
|
||||
GdkDropClass parent_class;
|
||||
};
|
||||
|
||||
GType gdk_wayland_drop_get_type (void);
|
||||
|
||||
G_DEFINE_TYPE (GdkWaylandDrop, gdk_wayland_drop, GDK_TYPE_DROP)
|
||||
|
||||
static void
|
||||
gdk_wayland_drop_finalize (GObject *object)
|
||||
{
|
||||
GdkWaylandDrop *wayland_drop = GDK_WAYLAND_DROP (object);
|
||||
|
||||
g_clear_pointer (&wayland_drop->offer, wl_data_offer_destroy);
|
||||
|
||||
G_OBJECT_CLASS (gdk_wayland_drop_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
gdk_to_wl_actions (GdkDragAction action)
|
||||
{
|
||||
uint32_t dnd_actions = 0;
|
||||
|
||||
if (action & (GDK_ACTION_COPY | GDK_ACTION_LINK))
|
||||
dnd_actions |= WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY;
|
||||
if (action & GDK_ACTION_MOVE)
|
||||
dnd_actions |= WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE;
|
||||
if (action & GDK_ACTION_ASK)
|
||||
dnd_actions |= WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK;
|
||||
|
||||
return dnd_actions;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_drop_drop_set_status (GdkWaylandDrop *drop_wayland,
|
||||
gboolean accepted)
|
||||
{
|
||||
if (accepted)
|
||||
{
|
||||
const char *const *mimetypes;
|
||||
gsize i, n_mimetypes;
|
||||
|
||||
mimetypes = gdk_content_formats_get_mime_types (gdk_drop_get_formats (GDK_DROP (drop_wayland)), &n_mimetypes);
|
||||
for (i = 0; i < n_mimetypes; i++)
|
||||
{
|
||||
if (mimetypes[i] != g_intern_static_string ("DELETE"))
|
||||
break;
|
||||
}
|
||||
|
||||
if (i < n_mimetypes)
|
||||
{
|
||||
wl_data_offer_accept (drop_wayland->offer, drop_wayland->serial, mimetypes[i]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
wl_data_offer_accept (drop_wayland->offer, drop_wayland->serial, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_drop_commit_status (GdkWaylandDrop *wayland_drop)
|
||||
{
|
||||
GdkDisplay *display;
|
||||
uint32_t dnd_actions;
|
||||
|
||||
display = gdk_drop_get_display (GDK_DROP (wayland_drop));
|
||||
|
||||
dnd_actions = gdk_to_wl_actions (wayland_drop->selected_action);
|
||||
|
||||
if (GDK_WAYLAND_DISPLAY (display)->data_device_manager_version >=
|
||||
WL_DATA_OFFER_SET_ACTIONS_SINCE_VERSION)
|
||||
{
|
||||
if (gdk_drag_action_is_unique (wayland_drop->selected_action))
|
||||
{
|
||||
wl_data_offer_set_actions (wayland_drop->offer, dnd_actions, dnd_actions);
|
||||
}
|
||||
else
|
||||
{
|
||||
wl_data_offer_set_actions (wayland_drop->offer,
|
||||
dnd_actions | WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK,
|
||||
WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK);
|
||||
}
|
||||
}
|
||||
|
||||
gdk_wayland_drop_drop_set_status (wayland_drop, wayland_drop->selected_action != 0);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_drop_status (GdkDrop *drop,
|
||||
GdkDragAction action)
|
||||
{
|
||||
GdkWaylandDrop *wayland_drop;
|
||||
|
||||
wayland_drop = GDK_WAYLAND_DROP (drop);
|
||||
wayland_drop->selected_action = action;
|
||||
|
||||
gdk_wayland_drop_commit_status (wayland_drop);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_drop_finish (GdkDrop *drop,
|
||||
GdkDragAction action)
|
||||
{
|
||||
GdkWaylandDrop *wayland_drop = GDK_WAYLAND_DROP (drop);
|
||||
GdkDisplay *display = gdk_drop_get_display (drop);
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
|
||||
|
||||
wayland_drop->selected_action = action;
|
||||
|
||||
if (action)
|
||||
{
|
||||
gdk_wayland_drop_commit_status (wayland_drop);
|
||||
|
||||
if (display_wayland->data_device_manager_version >=
|
||||
WL_DATA_OFFER_FINISH_SINCE_VERSION)
|
||||
wl_data_offer_finish (wayland_drop->offer);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_drop_read_async (GdkDrop *drop,
|
||||
GdkContentFormats *formats,
|
||||
int io_priority,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
GdkWaylandDrop *wayland_drop = GDK_WAYLAND_DROP (drop);
|
||||
GdkDisplay *display;
|
||||
GInputStream *stream;
|
||||
const char *mime_type;
|
||||
int pipe_fd[2];
|
||||
GError *error = NULL;
|
||||
GTask *task;
|
||||
|
||||
display = gdk_drop_get_display (drop),
|
||||
task = g_task_new (drop, cancellable, callback, user_data);
|
||||
g_task_set_priority (task, io_priority);
|
||||
g_task_set_source_tag (task, gdk_wayland_drop_read_async);
|
||||
|
||||
GDK_DISPLAY_NOTE (display, DND, char *s = gdk_content_formats_to_string (formats);
|
||||
g_message ("%p: read for %s", drop, s);
|
||||
g_free (s); );
|
||||
mime_type = gdk_content_formats_match_mime_type (formats,
|
||||
gdk_drop_get_formats (drop));
|
||||
if (mime_type == NULL)
|
||||
{
|
||||
g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
|
||||
_("No compatible transfer format found"));
|
||||
return;
|
||||
}
|
||||
|
||||
g_task_set_task_data (task, (gpointer) mime_type, NULL);
|
||||
|
||||
if (!g_unix_open_pipe (pipe_fd, FD_CLOEXEC, &error))
|
||||
{
|
||||
g_task_return_error (task, error);
|
||||
return;
|
||||
}
|
||||
|
||||
wl_data_offer_receive (wayland_drop->offer, mime_type, pipe_fd[1]);
|
||||
stream = g_unix_input_stream_new (pipe_fd[0], TRUE);
|
||||
close (pipe_fd[1]);
|
||||
g_task_return_pointer (task, stream, g_object_unref);
|
||||
}
|
||||
|
||||
static GInputStream *
|
||||
gdk_wayland_drop_read_finish (GdkDrop *drop,
|
||||
const char **out_mime_type,
|
||||
GAsyncResult *result,
|
||||
GError **error)
|
||||
{
|
||||
GTask *task;
|
||||
|
||||
g_return_val_if_fail (g_task_is_valid (result, G_OBJECT (drop)), NULL);
|
||||
task = G_TASK (result);
|
||||
g_return_val_if_fail (g_task_get_source_tag (task) == gdk_wayland_drop_read_async, NULL);
|
||||
|
||||
if (out_mime_type)
|
||||
*out_mime_type = g_task_get_task_data (task);
|
||||
|
||||
return g_task_propagate_pointer (task, error);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_drop_class_init (GdkWaylandDropClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GdkDropClass *drop_class = GDK_DROP_CLASS (klass);
|
||||
|
||||
object_class->finalize = gdk_wayland_drop_finalize;
|
||||
|
||||
drop_class->status = gdk_wayland_drop_status;
|
||||
drop_class->finish = gdk_wayland_drop_finish;
|
||||
drop_class->read_async = gdk_wayland_drop_read_async;
|
||||
drop_class->read_finish = gdk_wayland_drop_read_finish;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_drop_init (GdkWaylandDrop *drop)
|
||||
{
|
||||
}
|
||||
|
||||
GdkDrop *
|
||||
gdk_wayland_drop_new (GdkDevice *device,
|
||||
GdkDrag *drag,
|
||||
GdkContentFormats *formats,
|
||||
GdkSurface *surface,
|
||||
struct wl_data_offer *offer,
|
||||
uint32_t serial)
|
||||
|
||||
{
|
||||
GdkWaylandDrop *drop;
|
||||
|
||||
drop = g_object_new (GDK_TYPE_WAYLAND_DROP,
|
||||
"device", device,
|
||||
"drag", drag,
|
||||
"formats", formats,
|
||||
"surface", surface,
|
||||
NULL);
|
||||
drop->offer = offer;
|
||||
drop->serial = serial;
|
||||
|
||||
return GDK_DROP (drop);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_drop_update_actions (GdkWaylandDrop *drop)
|
||||
{
|
||||
GdkDragAction gdk_actions = 0;
|
||||
uint32_t wl_actions;
|
||||
|
||||
if (drop->action & WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK)
|
||||
wl_actions = drop->source_actions;
|
||||
else
|
||||
wl_actions = drop->action;
|
||||
|
||||
if (wl_actions & WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY)
|
||||
gdk_actions |= GDK_ACTION_COPY;
|
||||
if (wl_actions & WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE)
|
||||
gdk_actions |= GDK_ACTION_MOVE;
|
||||
|
||||
gdk_drop_set_actions (GDK_DROP (drop), gdk_actions);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_wayland_drop_set_source_actions (GdkDrop *drop,
|
||||
uint32_t source_actions)
|
||||
{
|
||||
GdkWaylandDrop *wayland_drop = GDK_WAYLAND_DROP (drop);
|
||||
|
||||
wayland_drop->source_actions = source_actions;
|
||||
|
||||
gdk_wayland_drop_update_actions (wayland_drop);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_wayland_drop_set_action (GdkDrop *drop,
|
||||
uint32_t action)
|
||||
{
|
||||
GdkWaylandDrop *wayland_drop = GDK_WAYLAND_DROP (drop);
|
||||
|
||||
wayland_drop->action = action;
|
||||
|
||||
gdk_wayland_drop_update_actions (wayland_drop);
|
||||
}
|
||||
|
||||
@@ -62,20 +62,20 @@ gdk_wayland_primary_discard_pending (GdkWaylandPrimary *cb)
|
||||
gdk_content_formats_unref (ignore);
|
||||
cb->pending_builder = NULL;
|
||||
}
|
||||
g_clear_pointer (&cb->pending, (GDestroyNotify) gtk_primary_selection_offer_destroy);
|
||||
g_clear_pointer (&cb->pending, gtk_primary_selection_offer_destroy);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_primary_discard_offer (GdkWaylandPrimary *cb)
|
||||
{
|
||||
g_clear_pointer (&cb->offer_formats, gdk_content_formats_unref);
|
||||
g_clear_pointer (&cb->offer, (GDestroyNotify) gtk_primary_selection_offer_destroy);
|
||||
g_clear_pointer (&cb->offer, gtk_primary_selection_offer_destroy);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_primary_discard_source (GdkWaylandPrimary *cb)
|
||||
{
|
||||
g_clear_pointer (&cb->source, (GDestroyNotify) wl_data_source_destroy);
|
||||
g_clear_pointer (&cb->source, gtk_primary_selection_source_destroy);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user