Compare commits
557 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d1bf21ea43 | |||
| 10efc3cb0d | |||
| ed67e424f2 | |||
| e9370d1dc8 | |||
| 0e09bb75b5 | |||
| 185f82c2ad | |||
| eebc70bf27 | |||
| cef3293184 | |||
| 089cccc929 | |||
| fc8b70cbdf | |||
| 6789ff7443 | |||
| 8eaddde310 | |||
| 67f27409e0 | |||
| 334333f779 | |||
| 74d43defc5 | |||
| caa1c0e4e5 | |||
| 61dd680b02 | |||
| 6671c20632 | |||
| 0603dbb466 | |||
| 46c12b2c92 | |||
| d3f46bcb16 | |||
| 728f0e13a8 | |||
| 23f49038e3 | |||
| f6fe5d37a5 | |||
| 6ba7c50a7a | |||
| bec88ded5f | |||
| b0e3d03831 | |||
| cae257c9dc | |||
| 8fe3e09cfc | |||
| 8352dee082 | |||
| cbd9715c3c | |||
| 0ac6144369 | |||
| 37f9af5805 | |||
| 4090306fd7 | |||
| e6e4f9e630 | |||
| 1ce49e48b2 | |||
| 7f295eeb32 | |||
| 04496cc535 | |||
| 92a8e10789 | |||
| aa89959942 | |||
| bae1a43710 | |||
| a4b522f6d7 | |||
| 01cb9b5ae6 | |||
| 208e115368 | |||
| 2b566f0633 | |||
| da8f634b25 | |||
| 9bad0a2d5e | |||
| 1a73728e04 | |||
| ab45bde94c | |||
| 93e1f7f1ec | |||
| 62768629f2 | |||
| 7521de1d61 | |||
| 292be6c4bb | |||
| 10b5f8a0d6 | |||
| c3b3f4711d | |||
| 71e2821578 | |||
| fde4431559 | |||
| d45b11e8ea | |||
| ff06d5d59f | |||
| ef95b58500 | |||
| 70ef77a4c2 | |||
| 2800dc356b | |||
| e658e3c449 | |||
| b3fcfa4bbc | |||
| 4601d3aee4 | |||
| 64eedbfaf4 | |||
| 4a55c527d7 | |||
| aa3e6bb0a3 | |||
| 4039153ca7 | |||
| 068df4874a | |||
| e23b4dd21b | |||
| a94baf4c3d | |||
| a1a2f8ab56 | |||
| 2db8f64ca7 | |||
| 15d9b3c7d6 | |||
| 1b789197e5 | |||
| 28337d68a3 | |||
| f82eb198f2 | |||
| 720e335246 | |||
| b8e78f83ce | |||
| 079ee4e31e | |||
| f8200470da | |||
| c3c759cbdd | |||
| e1422d73b1 | |||
| 6c4cc93121 | |||
| ee79334a52 | |||
| dfbcc0849b | |||
| 34038aaf7d | |||
| 0e48d8d7e3 | |||
| 78a0cdde83 | |||
| c2e6fcc92d | |||
| 466619f7c1 | |||
| 2f30e12de7 | |||
| bfe7a57b76 | |||
| f9d82e965e | |||
| 8d654527ab | |||
| 661f23d337 | |||
| 1650b4b205 | |||
| 102341ae9f | |||
| 2d67c74ea2 | |||
| 7f8efb6b8d | |||
| bac491b0b5 | |||
| 1284a804f1 | |||
| 60ec8dbd69 | |||
| 4d40300d8a | |||
| a174568ef9 | |||
| 7520524aed | |||
| 02381e49d7 | |||
| ae8fde9630 | |||
| 3c83854962 | |||
| 4067e46e20 | |||
| d81f58bc09 | |||
| 6b980e5ce8 | |||
| 660cbee51e | |||
| a12769a2c4 | |||
| 20be04f7ac | |||
| cdab711ec2 | |||
| 595531eba5 | |||
| 90ca7fb3c9 | |||
| 1e72dac839 | |||
| 25d01b7610 | |||
| 0f871584fc | |||
| d34f4416bd | |||
| 36315cbe2b | |||
| 1234b46d3b | |||
| c4d8575c30 | |||
| dceed915e8 | |||
| 49374551e8 | |||
| 888fe92051 | |||
| e7679635b0 | |||
| d90efbd9be | |||
| 0d0c9c918e | |||
| aca83684ed | |||
| d4376ec0db | |||
| 41a2f5cdc0 | |||
| 7e2917e19c | |||
| 3935a4a44a | |||
| 1900fc2f80 | |||
| 4f54fcd288 | |||
| d5657e2c55 | |||
| d1b90752ca | |||
| 26d61e2abc | |||
| 378ed797a4 | |||
| 876a2e6225 | |||
| cac1c7cd22 | |||
| 8d04980f38 | |||
| 6efcbf4634 | |||
| 5cccc2d975 | |||
| 36b4cd11b6 | |||
| df1e6dc45d | |||
| 599ab80c63 | |||
| 23c7e6e13b | |||
| 1382e54ef6 | |||
| 53fc584988 | |||
| 3567a74dd8 | |||
| 9a4e328928 | |||
| c71dca236c | |||
| a752e33838 | |||
| b5a2d29538 | |||
| e9d4b0dda0 | |||
| 7e732caa1e | |||
| bcdbb93296 | |||
| 97d3024701 | |||
| 9e949209a1 | |||
| 543b7defec | |||
| f7713bde1a | |||
| 499af07d2c | |||
| b4acfaee1c | |||
| c6d2d97774 | |||
| d74b01636b | |||
| 9ff2a9ab9b | |||
| 7691c94a37 | |||
| 659292f9ba | |||
| e2218cbb4d | |||
| 93c4359ec0 | |||
| 82c199db00 | |||
| 79fc2631c5 | |||
| f6a82cb658 | |||
| 26e9919bf6 | |||
| b4e110920a | |||
| ff46ea64c4 | |||
| 4868656ebb | |||
| 2dee749632 | |||
| ec4d27a4fc | |||
| fe19b20492 | |||
| 94f86a2fb6 | |||
| 3a8fab6879 | |||
| b04bd31718 | |||
| d450cbe517 | |||
| d86ce85267 | |||
| a4066188a2 | |||
| b81b9311f6 | |||
| 15817973d7 | |||
| 71aa479d16 | |||
| 998f4f32cc | |||
| 944a75659c | |||
| bc1ab236bd | |||
| adf9578e9c | |||
| b541ad48d1 | |||
| 557c3d1d62 | |||
| da4769ec81 | |||
| fe14b9d311 | |||
| 71d7054ff7 | |||
| 6128492cc0 | |||
| 7912714337 | |||
| 0c4a627199 | |||
| a8c83fe3bc | |||
| 2f176b566e | |||
| de31fdcc68 | |||
| 7303854310 | |||
| d4e2d05cd9 | |||
| 2169161312 | |||
| 635591c4d6 | |||
| c77ea5101e | |||
| 3e1214bda4 | |||
| 92ba4bf396 | |||
| 1fa2969a05 | |||
| 712721b60a | |||
| 01eb5d41cf | |||
| 88730e81c1 | |||
| a9c8b879a4 | |||
| 4ba89f25b8 | |||
| 447ab4ad0e | |||
| 47959b5b4a | |||
| 66b533408d | |||
| f67bf8d892 | |||
| af747315d7 | |||
| 90e8d7ff1a | |||
| 21f8098261 | |||
| d4f62b44d4 | |||
| 6d6d76ecbb | |||
| 43a8655ad0 | |||
| df9fe56264 | |||
| bfa763a24a | |||
| c70d23b61f | |||
| 7773c423aa | |||
| 0ba8d3f87e | |||
| 906eba7288 | |||
| d7196e5ea8 | |||
| a14e5778ff | |||
| 547ea8b073 | |||
| 5aa878d8e5 | |||
| 854343f8aa | |||
| 72ab4c46ed | |||
| 1308bc6131 | |||
| aeecafc11e | |||
| 5b8eca222c | |||
| e6676432cd | |||
| 1e72ea5a92 | |||
| 8c97f0832c | |||
| f9fe28cece | |||
| f64f335bd6 | |||
| 6baf287c5f | |||
| 6930749ad5 | |||
| 98e5fc81ed | |||
| d2ae457378 | |||
| 26119e5fc0 | |||
| 37477a1210 | |||
| 0952c11bec | |||
| eff4d45c09 | |||
| dc5fcd28fd | |||
| 49a14a25b3 | |||
| 50889d7629 | |||
| 9673b5a749 | |||
| 50cbb8f9a2 | |||
| 813965fbc5 | |||
| 42a69cce2a | |||
| 51198cb1e9 | |||
| fa68804a5b | |||
| ae0c559c21 | |||
| 0e14822a22 | |||
| 3177a3b42b | |||
| 247ed3d14a | |||
| a1aecd26d5 | |||
| accb8e3173 | |||
| 1a4e368c7e | |||
| 100ee4ce16 | |||
| 32e972e95b | |||
| 78cc9113c1 | |||
| cb32ff5b18 | |||
| bfad7693bf | |||
| 71bcecbc8d | |||
| 30835d7a86 | |||
| 0fc99afa25 | |||
| 8c0b11998d | |||
| fa70d08387 | |||
| a6c3887736 | |||
| 414cd74d20 | |||
| 27dad4b90a | |||
| c721959d31 | |||
| bf4290a330 | |||
| 1b1dee86a5 | |||
| 44aa328dc3 | |||
| e024a542b0 | |||
| 8d87d1b2a4 | |||
| 77f32a69c0 | |||
| 1dc428dc3e | |||
| 9b0eec55aa | |||
| d6c45d0e17 | |||
| 42d4e6de51 | |||
| 5e673e94de | |||
| b1a34e0b0c | |||
| d3a564d4f9 | |||
| a7a10aa63f | |||
| 8bbaa7d092 | |||
| 4fe7b3ec25 | |||
| ca6794b2d8 | |||
| 9c84f7645e | |||
| c714739759 | |||
| 536da7a15c | |||
| 191433bf0a | |||
| 25879ea37e | |||
| 610f52b125 | |||
| 242b76a771 | |||
| 3a70781d40 | |||
| 399356833d | |||
| 3d53204c75 | |||
| 3aa742d715 | |||
| a1aa4a970d | |||
| a0a18a7b02 | |||
| b69790a776 | |||
| da651ca7fc | |||
| 35fee660ff | |||
| 416e6b9cdd | |||
| 915d0b39a9 | |||
| d9a3e07b7f | |||
| a926f217d7 | |||
| 4334f9613b | |||
| ae5a29be4f | |||
| c3503fcc84 | |||
| 222c6c66ab | |||
| 3fb5890e69 | |||
| 5b13ae1b2e | |||
| 728d6cd538 | |||
| 3377dc7d40 | |||
| eaabc3722e | |||
| 3cfd1e1f52 | |||
| 475a4c8262 | |||
| 8b74d5f966 | |||
| b7cb281879 | |||
| 550b7fe8b2 | |||
| dfea8c31d9 | |||
| c3280c6b3c | |||
| a3ff6e279c | |||
| 8627a9a569 | |||
| d03bf414ce | |||
| 98bf543af2 | |||
| 6a60ce7cd4 | |||
| ed9b3f5057 | |||
| 0ec077bcdc | |||
| 27d38eca9a | |||
| 4ac8889d64 | |||
| 86ef0e6094 | |||
| 9a2382bebc | |||
| fa69e5f42d | |||
| 162243c7ce | |||
| 316aa85b8d | |||
| ba8c18019d | |||
| d8fb8db37c | |||
| 71c64e650d | |||
| 23db350889 | |||
| 3c6d96980f | |||
| 4c7944175f | |||
| 8c7846733a | |||
| 58b3145c90 | |||
| da7a511aa2 | |||
| 86da4e0c97 | |||
| c22d4a6657 | |||
| 39db784704 | |||
| 0f5ae95460 | |||
| 59397005fa | |||
| 41c3e9873c | |||
| 7b3c387af9 | |||
| a0cdd25bd4 | |||
| c26525f87c | |||
| 5b0a14410d | |||
| f1f5cbd88e | |||
| 1ce5494ffd | |||
| 5edac966e4 | |||
| 850768270f | |||
| c7df3b9e97 | |||
| b94955e614 | |||
| 238bb38249 | |||
| c8dbe02850 | |||
| 84337f7758 | |||
| a3c8214fb5 | |||
| 9216fe2cc0 | |||
| 60a714a25f | |||
| d7d6098281 | |||
| 79757da2a9 | |||
| bfe0f7dd4d | |||
| 86d38e6ae2 | |||
| b64d888288 | |||
| 94befed65f | |||
| d70fa89bdf | |||
| 782bbca52c | |||
| 392e52187d | |||
| 57cc7dce81 | |||
| d0cf3007c6 | |||
| 48768bd3ae | |||
| 19b8013618 | |||
| fa2ae10599 | |||
| 48de9796c2 | |||
| fcd083af14 | |||
| 88eaffc207 | |||
| 85315ea457 | |||
| 5ec5359981 | |||
| 7b6f627666 | |||
| 953d35b225 | |||
| 659b23b7c6 | |||
| 1a878b2b88 | |||
| b189d842dd | |||
| 22391f42b8 | |||
| c3b9f56121 | |||
| 07e06fb4dd | |||
| 935691f94c | |||
| 4d6f110ca2 | |||
| 9227d9c30f | |||
| 508036f745 | |||
| 9c9805dff8 | |||
| 8b0001876b | |||
| ef340ea616 | |||
| db1cb04896 | |||
| 4f81b5cd91 | |||
| f297e9198d | |||
| b56ce02e0c | |||
| aae92380a1 | |||
| c06a593b57 | |||
| ac69c05a31 | |||
| bfe201d70a | |||
| 1282cac99d | |||
| 784b236964 | |||
| f8206f18b1 | |||
| 523d5121d3 | |||
| a048da02d5 | |||
| 4d30400987 | |||
| f56a5ee260 | |||
| 891d4e9da3 | |||
| 8780cde919 | |||
| 56f6ac5fcc | |||
| 03b97b0a8b | |||
| 3d30790280 | |||
| 20ecaaa0e1 | |||
| b201438b39 | |||
| dca64da1fe | |||
| ca34428d17 | |||
| 5f13ee0afe | |||
| d11cde0c1c | |||
| 052b7d0ca7 | |||
| 22960c5c20 | |||
| d68898a033 | |||
| 5c6aa76979 | |||
| abefce0961 | |||
| 2ca1fe61a4 | |||
| d3316a37ed | |||
| 6fd951e53d | |||
| 35adc7ed04 | |||
| 52eb7b23cb | |||
| 6f4ebce914 | |||
| 40295441d1 | |||
| d2fe033c21 | |||
| e3c03e98f9 | |||
| 85d34932f3 | |||
| a0818f5bae | |||
| de3e97309f | |||
| d07bfbec1d | |||
| 89f3273651 | |||
| a612a42c11 | |||
| ddb9bae3d4 | |||
| a8c12a4c96 | |||
| b31a80cd64 | |||
| 6748c7116d | |||
| d13b9f797a | |||
| 0b1ca619a7 | |||
| 16ac1a12fc | |||
| 6fee66a9aa | |||
| aec4dc9387 | |||
| 0a9e2d6ed7 | |||
| 395b30dcfe | |||
| 326d101a57 | |||
| 02a02fac56 | |||
| 7ab4c9a68b | |||
| 19a740e277 | |||
| cae5e60113 | |||
| c87b21351c | |||
| f25a5f21fc | |||
| bda6c5ec2b | |||
| 51cef47835 | |||
| f8b7bd6dd6 | |||
| 72b047b084 | |||
| 72eb09f8e8 | |||
| 7647208fba | |||
| 8f325b475b | |||
| ac7dd63b02 | |||
| a7b93d62d5 | |||
| 985e17772b | |||
| 856fb75413 | |||
| 138f104fa4 | |||
| 79e512ab0b | |||
| 91343251b9 | |||
| ecd6b0b9a4 | |||
| de6498f18c | |||
| f89aeecc4f | |||
| eec24a0982 | |||
| a4ab1cfebe | |||
| ba845fa7b2 | |||
| 2a89189f1a | |||
| 0165cce645 | |||
| 6c5489ab25 | |||
| b933d57632 | |||
| c4f8eb7ec9 | |||
| 7208c97c7d | |||
| 69e7ab649c | |||
| 59dfeaceff | |||
| de8329b3ce | |||
| 4d410489c5 | |||
| 4ffe5a4954 | |||
| 850a086adb | |||
| 76b7f2704c | |||
| b8af685a43 | |||
| 50c4fbff72 | |||
| 0bbe4150a8 | |||
| 6da446c1be | |||
| 8f44694d2c | |||
| cf7f7df10c | |||
| 1d62a010ef | |||
| 46cf2849d2 | |||
| 811c7f2266 | |||
| a84b41abfd | |||
| dab79f5d77 | |||
| e792e077fa | |||
| 67be62aeaf | |||
| ba31560970 | |||
| cfd21b0991 | |||
| ebda6125a4 | |||
| a1757170da | |||
| 13f6790fdb | |||
| bd4b55ddbf | |||
| 2560af284d | |||
| 0f0dad24f4 | |||
| 9536d3aeaa | |||
| 9cfda52d22 | |||
| 628d94936a | |||
| a91de44755 | |||
| 0cb78a9808 | |||
| d955636da5 | |||
| f4c366044b | |||
| 847d378fea | |||
| fab2558747 | |||
| 0ac222fab2 | |||
| 6f6b5faaa2 | |||
| ddb7cab4ac | |||
| d4943ef2fb | |||
| 4c10134295 | |||
| 75a9f8dc92 | |||
| 9459be11a9 | |||
| b01f371ce6 |
+3
-1
@@ -36,7 +36,7 @@ fedora-meson:
|
||||
- "_build/testsuite/reftests/output"
|
||||
|
||||
debian-meson:
|
||||
image: registry.gitlab.gnome.org/gnome/gtk/debian-gtk3:v1
|
||||
image: registry.gitlab.gnome.org/gnome/gtk/debian-gtk3:v2
|
||||
stage: build
|
||||
variables:
|
||||
EXTRA_MESON_FLAGS: "-Ddefault_library=both"
|
||||
@@ -79,6 +79,8 @@ msys2-mingw64-meson:
|
||||
name: "gtk3-${env:CI_JOB_NAME}-${env:CI_COMMIT_REF_NAME}"
|
||||
paths:
|
||||
- "_build/meson-logs"
|
||||
- "_build/gdk/libgdk-3-0.dll"
|
||||
- "_build/gtk/libgtk-3-0.dll"
|
||||
|
||||
msys2-mingw64-autotools:
|
||||
when: manual
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM debian:buster
|
||||
FROM debian:bullseye
|
||||
|
||||
RUN apt-get update -qq && apt-get install --no-install-recommends -qq -y \
|
||||
adwaita-icon-theme \
|
||||
|
||||
@@ -15,7 +15,7 @@ meson \
|
||||
-Dx11_backend=true \
|
||||
-Dwayland_backend=true \
|
||||
-Dxinerama=yes \
|
||||
-Dprint_backends="file,lpr,test,cloudprint,cups" \
|
||||
-Dprint_backends="file,lpr,test,cups" \
|
||||
${EXTRA_MESON_FLAGS:-} \
|
||||
_build
|
||||
|
||||
|
||||
@@ -1,3 +1,364 @@
|
||||
Overview of Changes in GTK+ 3.24.31, 20-12-2021
|
||||
===============================================
|
||||
|
||||
* input:
|
||||
- Fix a crash with touch on GtkScale
|
||||
|
||||
* clipboard:
|
||||
- Avoid a double-free
|
||||
|
||||
* css:
|
||||
- Avoid a crash with radial gradients
|
||||
|
||||
* GtkFileChooser:
|
||||
- Don't leak search results
|
||||
|
||||
* GtkTextView:
|
||||
- Support css letterspacing
|
||||
|
||||
* Wayland:
|
||||
- Reset position when hiding popups
|
||||
- Ignore globals we did not bind ourselves
|
||||
- Avoid infinite loops when hiding surfaces
|
||||
- Avoid clipboard-related lockups
|
||||
|
||||
* X11:
|
||||
- Trap errors while doing XRANDR calls
|
||||
- Support touchpad gestures with XI 2.4
|
||||
|
||||
* win32:
|
||||
- Some OpenGL setup fixes
|
||||
- Fall back to GLES for OpenGL
|
||||
- Fix MinGW autotools build
|
||||
- Fix building on Windows 11
|
||||
- Support building with Visual Studio 2022
|
||||
- Improve DND across monitors
|
||||
- Rewrite keymap handling code
|
||||
|
||||
* macOS:
|
||||
- Accept NSPasteboardTypeFileURL drops
|
||||
- Build on macOS 12
|
||||
- Fix display on macOS 12
|
||||
- Fix keyboard layout notifications
|
||||
- Fix a crash
|
||||
- Improve performance on Big Sur
|
||||
|
||||
* Translation updates:
|
||||
Basque
|
||||
Brazilian Portuguese
|
||||
Chinese (China)
|
||||
Chinese (Taiwan)
|
||||
Croatian
|
||||
Czech
|
||||
Danish
|
||||
Dutch
|
||||
Finnish
|
||||
French
|
||||
Friulian
|
||||
Galician
|
||||
German
|
||||
Hungarian
|
||||
Icelandic
|
||||
Italian
|
||||
Kazakh
|
||||
Korean
|
||||
Latvian
|
||||
Occitan
|
||||
Persian
|
||||
Russian
|
||||
Serbian
|
||||
Spanish
|
||||
Swedish
|
||||
|
||||
|
||||
Overview of Changes in GTK+ 3.24.30
|
||||
===================================
|
||||
|
||||
* Input:
|
||||
- Ignore NoSymbol key events (happens with some XKB options)
|
||||
- Fix incomplete reset in some cases
|
||||
|
||||
* GtkEmojiChooser:
|
||||
- Update data from CLDR 39
|
||||
- Support translated keywords for multiple languages
|
||||
- Allow inserting multiple Emoji with Ctrl
|
||||
- Match keywords for search
|
||||
- Fix a memory leak
|
||||
|
||||
* GtkFileChooser:
|
||||
- Accessibility improvements
|
||||
|
||||
* GtkTreeView
|
||||
- Fix an accessibility-related memory leak
|
||||
- Fix assertion failures in some cases
|
||||
|
||||
* Printing:
|
||||
- Remove the Google Cloud Print backend, since the
|
||||
service was shut down
|
||||
|
||||
* Wayland:
|
||||
- Work with pointer-gestures v1 protocol
|
||||
|
||||
* Win32:
|
||||
- Fix using GL with Mesa drivers
|
||||
- Add support for Windows Pointer Input stack
|
||||
|
||||
* MacOS:
|
||||
- Fix a crash with Drag-and-Drop
|
||||
|
||||
* Translation updates:
|
||||
Belarusian
|
||||
Brazilian Portuguese
|
||||
British English
|
||||
Catalan
|
||||
Indonesian
|
||||
Lithuanian
|
||||
Nepali
|
||||
Norwegian Bokmål
|
||||
Occitan
|
||||
Portuguese
|
||||
Romanian
|
||||
Russian
|
||||
Serbian
|
||||
Slovenian
|
||||
Spanish
|
||||
Turkish
|
||||
Ukrainian
|
||||
|
||||
|
||||
Overview of Changes in GTK+ 3.24.29
|
||||
===================================
|
||||
|
||||
* Input:
|
||||
- Look for a Compose file in the right place (~/.config/gtk-3.0)
|
||||
- Revert some Compose sequence changes (mainly around dead
|
||||
acute and apostrophe)
|
||||
- Consume all key events during preedit, to avoid unexpected
|
||||
interactions
|
||||
- Ignore more modifiers during preedit, to allow using 3rd and
|
||||
5th level choosers
|
||||
- Fix handling of cursor positions in non-ASCII preedit text
|
||||
|
||||
* GtkSpinButton:
|
||||
- Interpret localized digits
|
||||
|
||||
* GtkScale:
|
||||
- Fix sporadic criticals
|
||||
|
||||
* GtkScrolledWindow:
|
||||
- Cancel overshoot on size changes
|
||||
- Avoid criticals with non-overlay scrollbars
|
||||
|
||||
* GtkFileChooser:
|
||||
- Handle smb mounts better
|
||||
|
||||
* GtkListBox:
|
||||
- Fix extending multi-selections
|
||||
|
||||
* Fix a possible crash in gtk_show_uri
|
||||
|
||||
* Wayland:
|
||||
- Improve font settings fallback
|
||||
|
||||
* X11:
|
||||
- Avoid log spam on exit
|
||||
- Don't beep on untrusted displays
|
||||
|
||||
* OS X:
|
||||
- Fix building on OS X 10.11
|
||||
- Add gdk-quartz-cocoa-access.h with api that provides
|
||||
access to native objects
|
||||
|
||||
* Translation updates:
|
||||
Dutch
|
||||
Nepali
|
||||
Swedish
|
||||
|
||||
|
||||
Overview of Changes in GTK+ 3.24.28
|
||||
===================================
|
||||
|
||||
* Input:
|
||||
- Improve dead key handling
|
||||
|
||||
* CSS:
|
||||
- Fix rendering of scaled text shadows
|
||||
|
||||
* Wayland:
|
||||
- Fix matching of accelerators with multiple layouts
|
||||
|
||||
* X11:
|
||||
- Trap errors from the COW
|
||||
|
||||
* Build:
|
||||
- Make gtk3-update-icon-cache output reproducible
|
||||
|
||||
* Translation updates:
|
||||
Serbian
|
||||
|
||||
|
||||
Overview of Changes in GTK+ 3.24.27
|
||||
===================================
|
||||
|
||||
* Input: Ensure preedit-start and preedit-end
|
||||
are emitted properly
|
||||
|
||||
* GtkScrolledWindow:
|
||||
- Revert a change that broke touch scrolling
|
||||
|
||||
* Theme:
|
||||
- Fix a problem with size changes in SSD decorations
|
||||
that caused mutter crashes
|
||||
- Use transparent black for window border in the dark theme
|
||||
|
||||
* Windows:
|
||||
- Memory leak fixes
|
||||
- Fix unresponsive windows after tablet input
|
||||
- Add support for wheel and rotation axes
|
||||
|
||||
* Translation updates:
|
||||
Belarusian
|
||||
German
|
||||
Kazakh
|
||||
Korean
|
||||
Latvian
|
||||
Turkish
|
||||
|
||||
|
||||
Overview of Changes in GTK+ 3.24.26
|
||||
===================================
|
||||
|
||||
* Input:
|
||||
- Fix a few oversights in Compose file parsing
|
||||
- Fine-tune Compose preedit display
|
||||
|
||||
* Theme:
|
||||
- Fine-tune scrollbar size and transitions
|
||||
- Reinstate invisible borders for tiled windows
|
||||
|
||||
* Wayland:
|
||||
- Fix a problem with font settings not being found
|
||||
|
||||
* Translation updates
|
||||
French
|
||||
Hungarian
|
||||
Turkish
|
||||
|
||||
|
||||
Overview of Changes in GTK+ 3.24.25
|
||||
===================================
|
||||
|
||||
* Settings:
|
||||
- Make cursor aspect ratio setting work
|
||||
|
||||
* Broadway:
|
||||
- Fix touchscreen event handling
|
||||
- Support Android / Chrome on-screen keyboard
|
||||
|
||||
* Windows:
|
||||
- Fix issues with Intel graphics drivers
|
||||
- Avoid UAC for gtk-update-icon-cache
|
||||
|
||||
* Wayland:
|
||||
- Avoid crashes with tablet input
|
||||
- Add api to support clients with subsurfaces better
|
||||
|
||||
* Inspector:
|
||||
- Make the inspector available in non-debug builds
|
||||
|
||||
* Theme:
|
||||
- Make scrollbars larger
|
||||
- Disable shadows on maximized, fullscreen and tiled windows
|
||||
|
||||
* Printing:
|
||||
- Support Avahi-discovered printers better
|
||||
|
||||
* Input:
|
||||
- Show preedit for compose sequences
|
||||
- Support long compose sequences
|
||||
- Support compose sequences producing multiple characters
|
||||
|
||||
* Translation updates
|
||||
Belarusian
|
||||
British English
|
||||
Catalan
|
||||
Friulian
|
||||
Galician
|
||||
Japanese
|
||||
Persian
|
||||
Serbian
|
||||
|
||||
|
||||
Overview of Changes in GTK+ 3.24.24
|
||||
===================================
|
||||
|
||||
* GtkColorChooser:
|
||||
- Update the default color palette
|
||||
|
||||
* GtkFontChooser:
|
||||
- Fix family-only mode to return regular style
|
||||
|
||||
* GtkTreeView:
|
||||
- Don't set focus-on-click for header buttons
|
||||
|
||||
* Accessibility:
|
||||
- Implement scrollSubstringTo
|
||||
- Add a11y support to GtkPlug/GtkSocket
|
||||
|
||||
* Printing:
|
||||
- Allow the lpr backend to print pdf and ps files
|
||||
|
||||
* Theme:
|
||||
- Update gesture graphics
|
||||
- Update HighContrast css
|
||||
|
||||
* Wayland:
|
||||
- Support the primary-selection-unstable-v1 protocol
|
||||
|
||||
* X11:
|
||||
- Fix a crash with parent-relative backgrounds
|
||||
|
||||
* Broadway:
|
||||
- Set modifier state of scroll events
|
||||
|
||||
* Build:
|
||||
- Fix pc file generation on NixOS
|
||||
|
||||
* OS X:
|
||||
- Restore command-key bindings
|
||||
|
||||
* Windows:
|
||||
- Fix meson build with epoxy subproject
|
||||
|
||||
* Translation updates:
|
||||
Basque
|
||||
Brazilian Portuguese
|
||||
British English
|
||||
Catalan
|
||||
Croatian
|
||||
Czech
|
||||
French
|
||||
Galician
|
||||
German
|
||||
Greek
|
||||
Hebrew
|
||||
Hungarian
|
||||
Indonesian
|
||||
Italian
|
||||
Kazakh
|
||||
Latvian
|
||||
Lithuanian
|
||||
Persian
|
||||
Polish
|
||||
Portuguese
|
||||
Slovak
|
||||
Slovenian
|
||||
Spanish
|
||||
Swedish
|
||||
Turkish
|
||||
Ukrainian
|
||||
|
||||
|
||||
Overview of Changes in GTK+ 3.24.23
|
||||
===================================
|
||||
|
||||
|
||||
+90
-8
@@ -15,6 +15,8 @@ the same compiler is used for at least GDK-Pixbuf, Pango, atk and glib
|
||||
so that crashes and errors caused by different CRTs can be avoided. Currently
|
||||
building with Visual Studio 2008 or later is supported, either via Visual Studio
|
||||
project files or via the Meson build system, as described in the below sections.
|
||||
For Visual Studio 2008, 2010, a special setup making use of the Windows 8.0 SDK
|
||||
is required, see at the bottom of this document for guidance.
|
||||
Interchanging between Visual Studio 2015, 2017 and 2019 builds should be fine
|
||||
as they use the same CRT (UCRT) DLLs.
|
||||
|
||||
@@ -175,6 +177,27 @@ instance the makefile.msc files might not produce identically named
|
||||
DLLs and import libraries as the "autoconfiscated" makefiles and
|
||||
libtool do. If this bothers you, you will have to fix the makefiles.
|
||||
|
||||
If desiring to build binaries for ARM64 (aarch64), one needs to use the
|
||||
Visual Studio 2017 or 2019 solution files, or use Meson with a
|
||||
cross-compilation file, with a Windows 10 SDK that supports ARM64
|
||||
builds. At this point, building the introspection files is not supported
|
||||
for ARM64 builds, and you will need a Python interpreter and
|
||||
glib-compile-resources binaries that run on the build machine. For Visual Studio
|
||||
2017 ARM64 builds, do also check the Directory.Build.props file in $(srcroot)/win32/vs15
|
||||
indicates a Windows 10 SDK version that supports ARM64 builds exists on the build machine.
|
||||
|
||||
For building ARM64 binaries with the Visual Studio projects, prior to the build,
|
||||
you may need to update gtk3-gen-srcs.props to pass in the variables GLIB_MKENUMS,
|
||||
GLIB_GENMARSHAL, GDBUS_CODEGEN and/or GLIB_COMPILE_RESOURCES in the nmake command line
|
||||
indicated by <GenerateRequiredSourcesBase> so that they point to the glib-mkenums,
|
||||
glib-genmarshal, gdbus-codegen and glib-compile-resources that will run on the build
|
||||
machine. You may also need to update gtk3-version-paths.props to update PythonDir to
|
||||
the installation of the Python interpreter that will run on the build machine. To carry
|
||||
out the actual build using the solution files, use the "Configuration Manager" to add the
|
||||
ARM64 build configs by copying the settings from the x64 configs, and then build the solution.
|
||||
The build instructions for such builds otherwise follow the standard Win32 (x86) and
|
||||
x64 builds, but you need to ensure that you have ARM64 builds of the various dependencies.
|
||||
|
||||
3) Using Meson (for Visual Studio and MinGW builds)
|
||||
---
|
||||
|
||||
@@ -265,6 +288,73 @@ If you are building with Visual Studio 2008, note the following items as well:
|
||||
- The more modern visual style for the print dialog is not applied for Visual
|
||||
Studio 2008 builds. Any solutions to this is really appreciated.
|
||||
|
||||
Support for pre-2012 Visual Studio
|
||||
==================================
|
||||
|
||||
This release of GTK+ requires at least the Windows 8.0 SDK in order to be built
|
||||
successfully using Visual Studio, which means that building with Visual Studio
|
||||
2008 or 2010 is possible only with a special setup and must be done in the
|
||||
command line with Ninja. Please see
|
||||
https://devblogs.microsoft.com/cppblog/using-the-windows-software-development-kit-sdk-for-windows-8-consumer-preview-with-visual-studio-2010/
|
||||
for references; basically, assuming that your Windows 8.0 SDK is installed in
|
||||
`C:\Program Files (x86)\Windows Kits\8.0` (`$(WIN8SDKDIR)` in short), you need
|
||||
to ensure the following before invoking Meson to configure the build:
|
||||
|
||||
- Your `%INCLUDE%` must not include the Windows 7.0/7.1 SDK include directories,
|
||||
and `$(WIN8SDKDIR)\include\um`, `$(WIN8SDKDIR)\include\um\share` and
|
||||
`$(WIN8SDKDIR)\include\winrt` (in this order) must be before your stock
|
||||
Visual Studio 2008/2010 header directories. If you have the DirectX SDK installed,
|
||||
you should remove its include directory from your `%INCLUDE%` as well.
|
||||
- You must replace the Windows 7.0/7.1 SDK library directory in `%LIB%` with the
|
||||
Windows 8.0 SDK library directory, i.e. `$(WIN8SDKDIR)\lib\win8\um\[x86|x64]`.
|
||||
If you have the DirectX SDK installed, you should remove its library directory
|
||||
from your `%INCLUDE%` as well.
|
||||
- You must replace the Windows 7.0/7.1 SDK tools directory from your `%PATH%` with
|
||||
the Windows 8.0 SDK tools directory, i.e. `$(WIN8SDKDIR)\bin\[x86|x64]`.
|
||||
If you have the DirectX SDK installed, you should remove its utility directory
|
||||
from your `%PATH%` as well.
|
||||
|
||||
The Windows 8.0 SDK headers may contain an `roapi.h` that cannot be used under plain
|
||||
C, so to remedy that, change the following lines (around lines 55-57):
|
||||
|
||||
// RegisterActivationFactory/RevokeActivationFactory registration cookie
|
||||
typedef struct {} *RO_REGISTRATION_COOKIE;
|
||||
// RegisterActivationFactory/DllGetActivationFactory callback
|
||||
|
||||
to
|
||||
|
||||
// RegisterActivationFactory/RevokeActivationFactory registration cookie
|
||||
#ifdef __cplusplus
|
||||
typedef struct {} *RO_REGISTRATION_COOKIE;
|
||||
#else
|
||||
typedef struct _RO_REGISTRATION_COOKIE *RO_REGISTRATION_COOKIE; /* make this header includable in C files */
|
||||
#endif
|
||||
// RegisterActivationFactory/DllGetActivationFactory callback
|
||||
|
||||
This follows what is done in the Windows 8.1 SDK, which contains an `roapi.h`
|
||||
that is usable under plain C. Please note that you might need to copy that file
|
||||
into a location that is in your `%INCLUDE%` which precedes the include path for the
|
||||
Windows 8.0 SDK headers, if you do not have administrative privileges.
|
||||
|
||||
Visual Studio 2008 hacks
|
||||
========================
|
||||
|
||||
- You need to run the following lines from your build directory, to embed the
|
||||
manifests that are generated during the build, assuming the built binaries
|
||||
are installed to `$(PREFIX)`, after a successful build/installation:
|
||||
|
||||
```cmd
|
||||
> for /r %f in (*.dll.manifest) do if exist $(PREFIX)\bin\%~nf mt /manifest %f (PREFIX)\bin\%~nf;2
|
||||
> for /r %f in (*.exe.manifest) do if exist $(PREFIX)\bin\%~nf mt /manifest %f (PREFIX)\bin\%~nf;1
|
||||
```
|
||||
|
||||
|
||||
- If building for amd64/x86_64/x64, sometimes the compilation of sources may seem to hang, which
|
||||
is caused by an optimization issue in the 2008 x64 compiler. You need to use Task Manager to
|
||||
remove all running instances of `cl.exe`, which will cause the build process to terminate. Update
|
||||
the build flags of the sources that hang on compilation by changing its `"/O2"` flag to `"/O1"`
|
||||
in `build.ninja`, and retry the build, where things should continue to build normally.
|
||||
|
||||
Using GTK+ on Win32
|
||||
===================
|
||||
|
||||
@@ -281,13 +371,5 @@ cases, but not in general. Sorry. If you have all GTK+ and GDK calls
|
||||
in the same thread, it might work. Otherwise, probably not at
|
||||
all. Possible ways to fix this are being investigated.
|
||||
|
||||
Wintab
|
||||
======
|
||||
|
||||
The tablet support uses the Wintab API. The Wintab development kit is
|
||||
no longer required. The wintab.h header file is bundled with GTK+
|
||||
sources. Unfortunately it seems that only Wacom tablets come with
|
||||
support for the Wintab API nowadays.
|
||||
|
||||
--Tor Lillqvist <tml@iki.fi>, <tml@novell.com>
|
||||
--Updated by Fan, Chun-wei <fanc999@yahoo.com.tw>
|
||||
|
||||
@@ -44,6 +44,9 @@
|
||||
/* Define to 1 if you have the `flockfile' function. */
|
||||
#mesondefine HAVE_FLOCKFILE
|
||||
|
||||
/* Define to 1 if you have the `fmin' function. */
|
||||
#mesondefine HAVE_FMIN
|
||||
|
||||
/* Define to 1 if you have the <ftw.h> header file. */
|
||||
#mesondefine HAVE_FTW_H
|
||||
|
||||
@@ -241,6 +244,9 @@
|
||||
/* Define to 1 if XInput 2.2 is available */
|
||||
#mesondefine XINPUT_2_2
|
||||
|
||||
/* Define to 1 if XInput 2.4 is available */
|
||||
#mesondefine XINPUT_2_4
|
||||
|
||||
/* Enable large inode numbers on Mac OS X 10.5. */
|
||||
#ifndef _DARWIN_USE_64_BIT_INODE
|
||||
# define _DARWIN_USE_64_BIT_INODE 1
|
||||
|
||||
@@ -52,6 +52,11 @@
|
||||
/* Define to 1 if you have the `flockfile' function. */
|
||||
#undef HAVE_FLOCKFILE
|
||||
|
||||
/* Define to 1 if you have the `fmin' function. */
|
||||
#if !defined (_MSC_VER) || (_MSC_VER >= 1800)
|
||||
# define HAVE_FMIN 1
|
||||
#endif
|
||||
|
||||
/* Define to 1 if you have the <ftw.h> header file. */
|
||||
/* #undef HAVE_FTW_H */
|
||||
|
||||
@@ -139,6 +144,11 @@
|
||||
#define HAVE_ROUND 1
|
||||
#endif
|
||||
|
||||
/* Define to 1 if SetupDiGetDevicePropertyW() is available */
|
||||
#ifdef _MSC_VER
|
||||
#define HAVE_SETUP_DI_GET_DEVICE_PROPERTY_W 1
|
||||
#endif
|
||||
|
||||
/* Define to 1 if sincos() is available */
|
||||
/* #undef HAVE_SINCOS */
|
||||
|
||||
@@ -290,6 +300,9 @@
|
||||
/* Define to 1 if XInput 2.2 is available */
|
||||
/* #undef XINPUT_2_2 */
|
||||
|
||||
/* Define to 1 if XInput 2.4 is available */
|
||||
/* #undef XINPUT_2_4 */
|
||||
|
||||
/* Define to 1 if the X Window System is missing or not being used. */
|
||||
/* #undef X_DISPLAY_MISSING */
|
||||
|
||||
|
||||
+41
-47
@@ -10,8 +10,8 @@
|
||||
|
||||
m4_define([gtk_major_version], [3])
|
||||
m4_define([gtk_minor_version], [24])
|
||||
m4_define([gtk_micro_version], [23])
|
||||
m4_define([gtk_interface_age], [19])
|
||||
m4_define([gtk_micro_version], [31])
|
||||
m4_define([gtk_interface_age], [27])
|
||||
m4_define([gtk_binary_age],
|
||||
[m4_eval(100 * gtk_minor_version + gtk_micro_version)])
|
||||
m4_define([gtk_version],
|
||||
@@ -439,7 +439,8 @@ fi
|
||||
|
||||
PKG_PROG_PKG_CONFIG
|
||||
|
||||
WAYLAND_DEPENDENCIES="wayland-client >= wayland_required_version wayland-protocols >= wayland_protocols_required_version xkbcommon >= 0.2.0 wayland-cursor >= wayland_required_version wayland-egl"
|
||||
WAYLAND_RUNTIME_DEPENDENCIES="wayland-client >= wayland_required_version xkbcommon >= 0.2.0 wayland-cursor >= wayland_required_version wayland-egl"
|
||||
WAYLAND_DEPENDENCIES="wayland-protocols >= wayland_protocols_required_version $WAYLAND_RUNTIME_DEPENDENCIES"
|
||||
if test "$enable_wayland_backend" = "maybe" ; then
|
||||
AC_PATH_PROG([WAYLAND_SCANNER],[wayland-scanner],[no])
|
||||
PKG_CHECK_EXISTS($WAYLAND_DEPENDENCIES, [have_wayland_deps=yes], [have_wayland_deps=no])
|
||||
@@ -460,7 +461,7 @@ if test "$enable_wayland_backend" = "yes"; then
|
||||
GDK_WINDOWING="$GDK_WINDOWING
|
||||
#define GDK_WINDOWING_WAYLAND"
|
||||
backend_immodules="$backend_immodules,wayland"
|
||||
WAYLAND_PACKAGES="$WAYLAND_DEPENDENCIES"
|
||||
WAYLAND_PACKAGES="$WAYLAND_RUNTIME_DEPENDENCIES"
|
||||
AC_PATH_PROG([WAYLAND_SCANNER],[wayland-scanner],[no])
|
||||
AS_IF([test "x$WAYLAND_SCANNER" = "xno"],
|
||||
[AC_MSG_ERROR([Could not find wayland-scanner in your PATH, required for parsing wayland extension protocols])])
|
||||
@@ -843,7 +844,7 @@ AC_TYPE_UID_T
|
||||
# Check for round(), rint(), isnan() and isinf()
|
||||
# Check for log2(), exp2(), nearbyint() and trunc()
|
||||
AC_CHECK_LIB(m,round,,)
|
||||
AC_CHECK_FUNCS(round rint nearbyint sincos exp2 log2 trunc)
|
||||
AC_CHECK_FUNCS(round rint nearbyint sincos exp2 log2 trunc fmin)
|
||||
AC_CHECK_DECLS([isnan, isinf], [], [], [[#include <math.h>]])
|
||||
|
||||
AC_MSG_CHECKING(whether to build dynamic modules)
|
||||
@@ -1166,13 +1167,23 @@ if test "x$enable_x11_backend" = xyes; then
|
||||
AC_DEFINE(XINPUT_2_2, 1, [Define to 1 if XInput 2.2 is available]),
|
||||
have_xinput2_2=no,
|
||||
[[#include <X11/extensions/XInput2.h>]])])
|
||||
LIBS="$gtk_save_LIBS"
|
||||
|
||||
if test "x$have_xinput2_2" = "xyes"; then
|
||||
X_EXTENSIONS="$X_EXTENSIONS XI2.2"
|
||||
else
|
||||
X_EXTENSIONS="$X_EXTENSIONS XI2"
|
||||
fi
|
||||
|
||||
AC_CHECK_MEMBER([XIGesturePinchEvent.type],
|
||||
have_xinput2_4=yes
|
||||
AC_DEFINE(XINPUT_2_4, 1, [Define to 1 if XInput 2.4 is available]),
|
||||
have_xinput2_4=no,
|
||||
[[#include <X11/extensions/XInput2.h>]])
|
||||
|
||||
if test "x$have_xinput2_4" = "xyes"; then
|
||||
X_EXTENSIONS="$X_EXTENSIONS XI2.4"
|
||||
fi
|
||||
LIBS="$gtk_save_LIBS"
|
||||
fi
|
||||
|
||||
AS_IF([test "x$have_xinput2" != "xyes"],
|
||||
@@ -1394,17 +1405,35 @@ fi
|
||||
##################################################
|
||||
# Check for harfbuzz and pangoft2
|
||||
##################################################
|
||||
|
||||
PKG_CHECK_MODULES(GTK_FONT_CHOOSER_WIDGET,
|
||||
harfbuzz >= 0.9 pangoft2,
|
||||
harfbuzz >= 2.2.0 pango >= 1.44.0,
|
||||
build_font_demo=yes,
|
||||
build_font_demo=no)
|
||||
|
||||
PKG_CHECK_MODULES(GTK_FONT_CHOOSER_WIDGET_FT,
|
||||
harfbuzz >= 0.9 pangoft2,
|
||||
build_font_demo_ft=yes,
|
||||
build_font_demo_ft=no)
|
||||
|
||||
if test "x$build_font_demo" = xno; then
|
||||
if test "x$build_font_demo_ft" = xyes; then
|
||||
build_font_demo=yes
|
||||
else
|
||||
build_font_demo=no
|
||||
fi
|
||||
fi
|
||||
|
||||
AM_CONDITIONAL(BUILD_FONT_DEMO, [ test "x$build_font_demo" = xyes ])
|
||||
if test "x$build_font_demo" = xyes; then
|
||||
AC_DEFINE([HAVE_HARFBUZZ], 1, [defines whether we have HarfBuzz])
|
||||
AC_DEFINE([HAVE_PANGOFT], 1, [defines whether we have pangoft2])
|
||||
GTK_DEP_CFLAGS="$GTK_DEP_CFLAGS $GTK_FONT_CHOOSER_WIDGET_CFLAGS"
|
||||
GTK_DEP_LIBS="$GTK_DEP_LIBS $GTK_FONT_CHOOSER_WIDGET_LIBS"
|
||||
if test "x$build_font_demo_ft" = xyes; then
|
||||
AC_DEFINE([HAVE_PANGOFT], 1, [defines whether we have pangoft2])
|
||||
GTK_DEP_CFLAGS="$GTK_DEP_CFLAGS $GTK_FONT_CHOOSER_WIDGET_FT_CFLAGS"
|
||||
GTK_DEP_LIBS="$GTK_DEP_LIBS $GTK_FONT_CHOOSER_WIDGET_FT_LIBS"
|
||||
else
|
||||
GTK_DEP_CFLAGS="$GTK_DEP_CFLAGS $GTK_FONT_CHOOSER_WIDGET_CFLAGS"
|
||||
GTK_DEP_LIBS="$GTK_DEP_LIBS $GTK_FONT_CHOOSER_WIDGET_LIBS"
|
||||
fi
|
||||
fi
|
||||
|
||||
if $PKG_CONFIG --exists x11; then
|
||||
@@ -1576,38 +1605,6 @@ fi
|
||||
|
||||
AM_CONDITIONAL(HAVE_TRACKER3, test "x$have_tracker3" = "xyes")
|
||||
|
||||
# Checks to see if we should compile with cloudprint backend for GTK+
|
||||
#
|
||||
|
||||
AC_ARG_ENABLE(cloudprint,
|
||||
[AS_HELP_STRING([--disable-cloudprint],
|
||||
[disable cloudprint print backend])],,
|
||||
[enable_cloudprint=auto])
|
||||
|
||||
if test "x$enable_cloudprint" = "xno"; then
|
||||
AM_CONDITIONAL(HAVE_CLOUDPRINT, false)
|
||||
else
|
||||
PKG_CHECK_MODULES(REST, [rest-0.7], have_rest=yes, have_rest=no)
|
||||
PKG_CHECK_MODULES(JSON_GLIB, [json-glib-1.0], have_json_glib=yes, have_json_glib=no)
|
||||
if test "x$have_rest" = "xyes" -a "x$have_json_glib" = "xyes"; then
|
||||
PRINT_BACKENDS="$PRINT_BACKENDS cloudprint"
|
||||
have_cloudprint=yes
|
||||
fi
|
||||
AM_CONDITIONAL(HAVE_CLOUDPRINT, test "x$have_cloudprint" = "xyes")
|
||||
fi
|
||||
|
||||
if test "x$enable_cloudprint" = "xyes" -a "x$have_rest" = "xno"; then
|
||||
AC_MSG_ERROR([
|
||||
*** rest not found.
|
||||
])
|
||||
fi
|
||||
|
||||
if test "x$enable_cloudprint" = "xyes" -a "x$have_json_glib" = "xno"; then
|
||||
AC_MSG_ERROR([
|
||||
*** json-glib not found.
|
||||
])
|
||||
fi
|
||||
|
||||
gtk_save_cppflags="$CPPFLAGS"
|
||||
CPPFLAGS="$CPPFLAGS $GTK_DEP_CFLAGS $GDK_DEP_CFLAGS"
|
||||
|
||||
@@ -1650,9 +1647,6 @@ fi
|
||||
if test "$have_papi" != "yes" -a "$have_cups" != "yes"; then
|
||||
GTK_PRINT_BACKENDS="$GTK_PRINT_BACKENDS,lpr"
|
||||
fi
|
||||
if test "$have_cloudprint" = "yes"; then
|
||||
GTK_PRINT_BACKENDS="$GTK_PRINT_BACKENDS,cloudprint"
|
||||
fi
|
||||
AC_SUBST(GTK_PRINT_BACKENDS)
|
||||
|
||||
################################################################
|
||||
@@ -1975,6 +1969,7 @@ win32/vs12/Makefile
|
||||
win32/vs14/Makefile
|
||||
win32/vs15/Makefile
|
||||
win32/vs16/Makefile
|
||||
win32/vs17/Makefile
|
||||
gdk/Makefile
|
||||
gdk/broadway/Makefile
|
||||
gdk/x11/Makefile
|
||||
@@ -1994,7 +1989,6 @@ modules/Makefile
|
||||
modules/input/Makefile
|
||||
modules/printbackends/Makefile
|
||||
modules/printbackends/cups/Makefile
|
||||
modules/printbackends/cloudprint/Makefile
|
||||
modules/printbackends/lpr/Makefile
|
||||
modules/printbackends/file/Makefile
|
||||
modules/printbackends/papi/Makefile
|
||||
|
||||
@@ -1,87 +1,15 @@
|
||||
## Makefile.am for gtk+/demos
|
||||
include $(top_srcdir)/Makefile.decl
|
||||
|
||||
## These should be in the order you want them to appear in the
|
||||
## demo app, which means alphabetized by demo title, not filename
|
||||
demos_base = \
|
||||
application_demo.c \
|
||||
assistant.c \
|
||||
builder.c \
|
||||
button_box.c \
|
||||
changedisplay.c \
|
||||
clipboard.c \
|
||||
colorsel.c \
|
||||
combobox.c \
|
||||
css_accordion.c \
|
||||
css_basics.c \
|
||||
css_blendmodes.c \
|
||||
css_multiplebgs.c \
|
||||
css_pixbufs.c \
|
||||
css_shadows.c \
|
||||
cursors.c \
|
||||
dialog.c \
|
||||
drawingarea.c \
|
||||
editable_cells.c \
|
||||
entry_buffer.c \
|
||||
entry_completion.c \
|
||||
event_axes.c \
|
||||
expander.c \
|
||||
filtermodel.c \
|
||||
fishbowl.c \
|
||||
foreigndrawing.c \
|
||||
gestures.c \
|
||||
glarea.c \
|
||||
headerbar.c \
|
||||
hypertext.c \
|
||||
iconview.c \
|
||||
iconview_edit.c \
|
||||
images.c \
|
||||
infobar.c \
|
||||
links.c \
|
||||
listbox.c \
|
||||
flowbox.c \
|
||||
list_store.c \
|
||||
markup.c \
|
||||
menus.c \
|
||||
modelbutton.c \
|
||||
offscreen_window.c \
|
||||
offscreen_window2.c \
|
||||
overlay.c \
|
||||
overlay2.c \
|
||||
paint.c \
|
||||
panes.c \
|
||||
pickers.c \
|
||||
pixbufs.c \
|
||||
popover.c \
|
||||
printing.c \
|
||||
revealer.c \
|
||||
rotated_text.c \
|
||||
scale.c \
|
||||
search_entry.c \
|
||||
search_entry2.c \
|
||||
shortcuts.c \
|
||||
sidebar.c \
|
||||
sizegroup.c \
|
||||
spinbutton.c \
|
||||
spinner.c \
|
||||
stack.c \
|
||||
tabs.c \
|
||||
textmask.c \
|
||||
textview.c \
|
||||
textscroll.c \
|
||||
theming_style_classes.c \
|
||||
toolpalette.c \
|
||||
transparent.c \
|
||||
tree_store.c
|
||||
include $(srcdir)/demos-sources.mak
|
||||
|
||||
demos_opt =
|
||||
|
||||
if BUILD_FONT_DEMO
|
||||
demos_opt += font_features.c
|
||||
demos_opt += $(font_features_demo)
|
||||
endif
|
||||
|
||||
if OS_UNIX
|
||||
demos_opt += pagesetup.c
|
||||
demos_opt += $(page_setup_demo)
|
||||
endif
|
||||
|
||||
demos = $(demos_base) $(demos_opt)
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
## These should be in the order you want them to appear in the
|
||||
## demo app, which means alphabetized by demo title, not filename
|
||||
demos_base = \
|
||||
application_demo.c \
|
||||
assistant.c \
|
||||
builder.c \
|
||||
button_box.c \
|
||||
changedisplay.c \
|
||||
clipboard.c \
|
||||
colorsel.c \
|
||||
combobox.c \
|
||||
css_accordion.c \
|
||||
css_basics.c \
|
||||
css_blendmodes.c \
|
||||
css_multiplebgs.c \
|
||||
css_pixbufs.c \
|
||||
css_shadows.c \
|
||||
cursors.c \
|
||||
dialog.c \
|
||||
drawingarea.c \
|
||||
editable_cells.c \
|
||||
entry_buffer.c \
|
||||
entry_completion.c \
|
||||
event_axes.c \
|
||||
expander.c \
|
||||
filtermodel.c \
|
||||
fishbowl.c \
|
||||
foreigndrawing.c \
|
||||
gestures.c \
|
||||
glarea.c \
|
||||
headerbar.c \
|
||||
hypertext.c \
|
||||
iconview.c \
|
||||
iconview_edit.c \
|
||||
images.c \
|
||||
infobar.c \
|
||||
links.c \
|
||||
listbox.c \
|
||||
flowbox.c \
|
||||
list_store.c \
|
||||
markup.c \
|
||||
menus.c \
|
||||
modelbutton.c \
|
||||
offscreen_window.c \
|
||||
offscreen_window2.c \
|
||||
overlay.c \
|
||||
overlay2.c \
|
||||
paint.c \
|
||||
panes.c \
|
||||
pickers.c \
|
||||
pixbufs.c \
|
||||
popover.c \
|
||||
printing.c \
|
||||
revealer.c \
|
||||
rotated_text.c \
|
||||
scale.c \
|
||||
search_entry.c \
|
||||
search_entry2.c \
|
||||
shortcuts.c \
|
||||
sidebar.c \
|
||||
sizegroup.c \
|
||||
spinbutton.c \
|
||||
spinner.c \
|
||||
stack.c \
|
||||
tabs.c \
|
||||
textmask.c \
|
||||
textview.c \
|
||||
textscroll.c \
|
||||
theming_style_classes.c \
|
||||
toolpalette.c \
|
||||
transparent.c \
|
||||
tree_store.c
|
||||
|
||||
font_features_demo = font_features.c
|
||||
page_setup_demo = pagesetup.c
|
||||
@@ -9,10 +9,23 @@
|
||||
*/
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#if PANGO_VERSION_CHECK(1,44,0)
|
||||
# if !HB_VERSION_ATLEAST(2,2,0)
|
||||
# define FONT_FEATURES_USE_PANGOFT2 1
|
||||
# endif
|
||||
#else
|
||||
# define FONT_FEATURES_USE_PANGOFT2 1
|
||||
#endif
|
||||
|
||||
#ifdef FONT_FEATURES_USE_PANGOFT2
|
||||
#include <pango/pangofc-font.h>
|
||||
#include <hb.h>
|
||||
#include <hb-ot.h>
|
||||
#include <hb-ft.h>
|
||||
#else
|
||||
#include <hb-ot.h>
|
||||
#endif
|
||||
|
||||
static GtkWidget *label;
|
||||
static GtkWidget *settings;
|
||||
@@ -205,19 +218,32 @@ static void
|
||||
update_script_combo (void)
|
||||
{
|
||||
GtkListStore *store;
|
||||
hb_font_t *hb_font;
|
||||
hb_font_t *hb_font = NULL;
|
||||
gint i, j, k, l;
|
||||
FT_Face ft_face;
|
||||
PangoFont *pango_font;
|
||||
GHashTable *tags;
|
||||
GHashTableIter iter;
|
||||
TagPair *pair;
|
||||
gboolean cleanup_hb_face = FALSE;
|
||||
|
||||
#ifdef FONT_FEATURES_USE_PANGOFT2
|
||||
FT_Face ft_face;
|
||||
#endif
|
||||
|
||||
store = gtk_list_store_new (4, G_TYPE_STRING, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT);
|
||||
|
||||
pango_font = get_pango_font ();
|
||||
ft_face = pango_fc_font_lock_face (PANGO_FC_FONT (pango_font)),
|
||||
hb_font = hb_ft_font_create (ft_face, NULL);
|
||||
|
||||
#ifdef FONT_FEATURES_USE_PANGOFT2
|
||||
if (PANGO_IS_FC_FONT (pango_font))
|
||||
{
|
||||
ft_face = pango_fc_font_lock_face (PANGO_FC_FONT (pango_font)),
|
||||
hb_font = hb_ft_font_create (ft_face, NULL);
|
||||
cleanup_hb_face = TRUE;
|
||||
}
|
||||
#else
|
||||
hb_font = pango_font_get_hb_font (pango_font);
|
||||
#endif
|
||||
|
||||
tags = g_hash_table_new_full (tag_pair_hash, tag_pair_equal, g_free, NULL);
|
||||
|
||||
@@ -264,10 +290,15 @@ update_script_combo (void)
|
||||
}
|
||||
}
|
||||
|
||||
hb_face_destroy (hb_face);
|
||||
if (cleanup_hb_face)
|
||||
hb_face_destroy (hb_face);
|
||||
}
|
||||
|
||||
pango_fc_font_unlock_face (PANGO_FC_FONT (pango_font));
|
||||
#ifdef FONT_FEATURES_USE_PANGOFT2
|
||||
if (PANGO_IS_FC_FONT (pango_font))
|
||||
pango_fc_font_unlock_face (PANGO_FC_FONT (pango_font));
|
||||
#endif
|
||||
|
||||
g_object_unref (pango_font);
|
||||
|
||||
g_hash_table_iter_init (&iter, tags);
|
||||
@@ -346,8 +377,12 @@ update_features (void)
|
||||
GtkTreeIter iter;
|
||||
guint script_index, lang_index;
|
||||
PangoFont *pango_font;
|
||||
hb_font_t *hb_font = NULL;
|
||||
gboolean cleanup_hb_face = FALSE;
|
||||
|
||||
#ifdef FONT_FEATURES_USE_PANGOFT2
|
||||
FT_Face ft_face;
|
||||
hb_font_t *hb_font;
|
||||
#endif
|
||||
|
||||
for (i = 0; i < num_features; i++)
|
||||
gtk_widget_set_opacity (icon[i], 0);
|
||||
@@ -364,8 +399,17 @@ update_features (void)
|
||||
-1);
|
||||
|
||||
pango_font = get_pango_font ();
|
||||
ft_face = pango_fc_font_lock_face (PANGO_FC_FONT (pango_font)),
|
||||
hb_font = hb_ft_font_create (ft_face, NULL);
|
||||
|
||||
#ifdef FONT_FEATURES_USE_PANGOFT2
|
||||
if (PANGO_IS_FC_FONT (pango_font))
|
||||
{
|
||||
ft_face = pango_fc_font_lock_face (PANGO_FC_FONT (pango_font)),
|
||||
hb_font = hb_ft_font_create (ft_face, NULL);
|
||||
cleanup_hb_face = TRUE;
|
||||
}
|
||||
#else
|
||||
hb_font = pango_font_get_hb_font (pango_font);
|
||||
#endif
|
||||
|
||||
if (hb_font)
|
||||
{
|
||||
@@ -397,10 +441,15 @@ update_features (void)
|
||||
}
|
||||
}
|
||||
|
||||
hb_face_destroy (hb_face);
|
||||
if (cleanup_hb_face)
|
||||
hb_face_destroy (hb_face);
|
||||
}
|
||||
|
||||
pango_fc_font_unlock_face (PANGO_FC_FONT (pango_font));
|
||||
#ifdef FONT_FEATURES_USE_PANGOFT2
|
||||
if (PANGO_IS_FC_FONT (pango_font))
|
||||
pango_fc_font_unlock_face (PANGO_FC_FONT (pango_font));
|
||||
#endif
|
||||
|
||||
g_object_unref (pango_font);
|
||||
}
|
||||
|
||||
|
||||
@@ -160,7 +160,7 @@ do_gestures (GtkWidget *do_widget)
|
||||
gtk_container_add (GTK_CONTAINER (window), drawing_area);
|
||||
gtk_widget_add_events (drawing_area,
|
||||
GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
|
||||
GDK_POINTER_MOTION_MASK | GDK_TOUCH_MASK);
|
||||
GDK_POINTER_MOTION_MASK | GDK_TOUCH_MASK | GDK_TOUCHPAD_GESTURE_MASK);
|
||||
|
||||
g_signal_connect (drawing_area, "draw",
|
||||
G_CALLBACK (drawing_area_draw), NULL);
|
||||
|
||||
@@ -76,7 +76,13 @@ demos = files([
|
||||
|
||||
gtkdemo_deps = [libgtk_dep]
|
||||
|
||||
if harfbuzz_dep.found() and pangoft_dep.found()
|
||||
if pango_dep.version().version_compare('>=1.44.0') and harfbuzz_dep.found() and cc.has_header_symbol(
|
||||
'hb-ot.h',
|
||||
'hb_ot_var_get_axis_count',
|
||||
dependencies: harfbuzz_dep
|
||||
)
|
||||
demos += files('font_features.c')
|
||||
elif harfbuzz_dep.found() and pangoft_dep.found()
|
||||
demos += files('font_features.c')
|
||||
gtkdemo_deps += [harfbuzz_dep, pangoft_dep]
|
||||
endif
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
Name=Icon Browser
|
||||
Comment=An application that shows themed icons
|
||||
Exec=gtk3-icon-browser
|
||||
Icon=gtk3-icon-browser
|
||||
Terminal=false
|
||||
Type=Application
|
||||
StartupNotify=true
|
||||
|
||||
@@ -1279,6 +1279,8 @@ GdkWaylandWindowExported
|
||||
gdk_wayland_window_export_handle
|
||||
gdk_wayland_window_unexport_handle
|
||||
gdk_wayland_window_set_transient_for_exported
|
||||
gdk_wayland_window_add_frame_callback_surface
|
||||
gdk_wayland_window_remove_frame_callback_surface
|
||||
|
||||
<SUBSECTION Standard>
|
||||
GDK_TYPE_WAYLAND_DEVICE
|
||||
|
||||
@@ -503,14 +503,19 @@ if get_option('man') and xsltproc.found()
|
||||
[ 'gtk-update-icon-cache', '1', ],
|
||||
[ 'gtk-encode-symbolic-svg', '1', ],
|
||||
[ 'gtk-launch', '1', ],
|
||||
[ 'gtk3-demo', '1', ],
|
||||
[ 'gtk3-demo-application', '1', ],
|
||||
[ 'gtk3-widget-factory', '1', ],
|
||||
[ 'gtk3-icon-browser', '1', ],
|
||||
[ 'gtk-builder-tool', '1', ],
|
||||
[ 'gtk-query-settings', '1', ],
|
||||
]
|
||||
|
||||
if get_option('demos')
|
||||
man_files += [
|
||||
[ 'gtk3-demo', '1', ],
|
||||
[ 'gtk3-demo-application', '1', ],
|
||||
[ 'gtk3-widget-factory', '1', ],
|
||||
[ 'gtk3-icon-browser', '1', ],
|
||||
]
|
||||
endif
|
||||
|
||||
if broadway_enabled
|
||||
man_files += [[ 'broadwayd', '1', ]]
|
||||
endif
|
||||
|
||||
@@ -20,12 +20,8 @@ Getting help with GTK+
|
||||
<title>Filing a bug report or feature request</title>
|
||||
|
||||
<para>
|
||||
If you encounter a bug, misfeature, or missing feature in GTK+, please
|
||||
file a bug report on
|
||||
<ulink url="https://bugzilla.gnome.org">https://bugzilla.gnome.org</ulink>.
|
||||
We'd also appreciate reports of incomplete or misleading information in
|
||||
the GTK+ documentation; file those against the "docs" component of the "gtk+"
|
||||
product in Bugzilla.
|
||||
If you encounter a bug, misfeature, or missing feature in GTK, please
|
||||
file a bug report on <ulink url="https://gitlab.gnome.org/GNOME/gtk/issues">GitLab</ulink>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
@@ -37,103 +33,38 @@ discussed, we'll add a note to that effect in the report.
|
||||
|
||||
<para>
|
||||
The bug tracker should definitely be used for feature requests, it's
|
||||
not only for bugs. We track all GTK+ development in Bugzilla, so it's
|
||||
the way to be sure the GTK+ developers won't forget about an issue.
|
||||
not only for bugs. We track all GTK development in GitLab, so it's
|
||||
the way to be sure the GTK developers won't forget about an issue.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Just make sure that any issue filed is actionable, and contains clear
|
||||
instructions on how to reproduce an issue, and the conditions to close
|
||||
the bug report or feature request. Non-actionable, or user support
|
||||
questions will be directed to Discourse.
|
||||
</para>
|
||||
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
<title>Submitting Patches</title>
|
||||
<title>Contributing</title>
|
||||
|
||||
<para>
|
||||
If you develop a bugfix or enhancement for GTK+, please file that in
|
||||
Bugzilla as well. Bugzilla allows you to attach files; please attach a
|
||||
patch generated by the <command>diff</command> utility, using the
|
||||
<option>-u</option> option to make the patch more readable. All patches
|
||||
must be offered under the terms of the GNU LGPL license, so be sure you
|
||||
are authorized to give us the patch under those terms.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
If you want to discuss your patch before or after developing it, mail
|
||||
<ulink url="mailto:gtk-devel-list@gnome.org">gtk-devel-list@gnome.org</ulink>.
|
||||
But be sure to file the Bugzilla report as well; if the patch is only on the
|
||||
list and not in Bugzilla, it's likely to slip through the cracks.
|
||||
Please, follow the instructions outlined in the
|
||||
<ulink url="https://gitlab.gnome.org/GNOME/gtk/-/blob/master/CONTRIBUTING.md">Contribution Guide</ulink> available in the GTK
|
||||
source code repository.
|
||||
</para>
|
||||
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
<title>Mailing lists</title>
|
||||
<title>User support</title>
|
||||
|
||||
<para>
|
||||
There are several mailing lists dedicated to GTK+ and related
|
||||
libraries. Discussion of GLib, Pango, and ATK in addition to GTK+
|
||||
proper is welcome on these lists. You can subscribe or view the
|
||||
archives of these lists on
|
||||
<ulink url="https://mail.gnome.org">http://mail.gnome.org</ulink>.
|
||||
If you aren't subscribed to the list, any message you post to
|
||||
the list will be held for manual moderation, which might take
|
||||
some days to happen.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<variablelist>
|
||||
|
||||
<varlistentry>
|
||||
<term><ulink url="mailto:gtk-list@gnome.org">gtk-list@gnome.org</ulink></term>
|
||||
<listitem><para>
|
||||
gtk-list covers general GTK+ topics; questions about using GTK+ in programs,
|
||||
GTK+ from a user standpoint, announcements of GTK+-related projects
|
||||
such as themes or GTK+ modules would all be on-topic. The bulk of the
|
||||
traffic consists of GTK+ programming questions.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><ulink url="mailto:gtk-app-devel-list@gnome.org">gtk-app-devel-list@gnome.org</ulink></term>
|
||||
<listitem><para>
|
||||
gtk-app-devel-list covers writing applications in GTK+. It's narrower
|
||||
in scope than gtk-list, but the two lists overlap quite a
|
||||
bit. gtk-app-devel-list is a good place to ask questions about GTK+
|
||||
programming. </para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><ulink url="mailto:gtk-devel-list@gnome.org">gtk-devel-list@gnome.org</ulink></term>
|
||||
<listitem><para>
|
||||
gtk-devel-list is for discussion of work on GTK+ itself, it is
|
||||
<emphasis>not</emphasis> for
|
||||
asking questions about how to use GTK+ in applications. gtk-devel-list
|
||||
is appropriate for discussion of patches, bugs, proposed features,
|
||||
and so on.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><ulink url="mailto:gtk-i18n-list@gnome.org">gtk-i18n-list@gnome.org</ulink></term>
|
||||
<listitem><para>
|
||||
gtk-i18n-list is for discussion of internationalization in GTK+;
|
||||
Pango is the main focus of the list. Questions about the details of
|
||||
using Pango, and discussion of proposed Pango patches or features, are
|
||||
all on topic.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><ulink url="mailto:gtk-doc-list@gnome.org">gtk-doc-list@gnome.org</ulink></term>
|
||||
<listitem><para>
|
||||
gtk-doc-list is for discussion of the <application>gtk-doc</application>
|
||||
documentation system (used to document GTK+), and for work on the GTK+
|
||||
documentation.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
If you have questions about building, using, or contributing to GTK, please
|
||||
open a topic on <ulink url="https://discourse.gnome.org/tag/gtk">Discourse</ulink>.
|
||||
</para>
|
||||
|
||||
</refsect1>
|
||||
|
||||
|
||||
</refentry>
|
||||
|
||||
@@ -134,9 +134,9 @@ additional environment variables.
|
||||
<title><envar>GTK_DEBUG</envar></title>
|
||||
|
||||
<para>
|
||||
Unless GTK+ has been configured with <option>--enable-debug=no</option>,
|
||||
this variable can be set to a list of debug options, which cause GTK+
|
||||
to print out different types of debugging information.
|
||||
This variable can be set to a list of debug options, which cause GTK to
|
||||
print out different types of debugging information. Some of these options
|
||||
are only available when GTK has been configured with <option>--enable-debug=yes</option>.
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>actions</term>
|
||||
|
||||
@@ -5,7 +5,7 @@ app10_resources = gnome.compile_resources(
|
||||
source_dir: '.'
|
||||
)
|
||||
|
||||
app10_schemas = gnome.compile_schemas()
|
||||
app10_schemas = gnome.compile_schemas(depend_files: files(['org.gtk.exampleapp.gschema.xml']))
|
||||
|
||||
|
||||
app10 = executable(
|
||||
@@ -21,3 +21,5 @@ app10 = executable(
|
||||
app10_schemas,
|
||||
dependencies: libgtk_dep
|
||||
)
|
||||
|
||||
install_data('org.gtk.exampleapp.gschema.xml', install_dir: gtk_schemasdir)
|
||||
|
||||
@@ -5,7 +5,7 @@ app5_resources = gnome.compile_resources(
|
||||
source_dir: '.'
|
||||
)
|
||||
|
||||
app5_schemas = gnome.compile_schemas()
|
||||
app5_schemas = gnome.compile_schemas(depend_files: files(['org.gtk.exampleapp.gschema.xml']))
|
||||
|
||||
|
||||
app5 = executable(
|
||||
@@ -19,3 +19,5 @@ app5 = executable(
|
||||
app5_schemas,
|
||||
dependencies: libgtk_dep
|
||||
)
|
||||
|
||||
install_data('org.gtk.exampleapp.gschema.xml', install_dir: gtk_schemasdir)
|
||||
|
||||
@@ -5,7 +5,7 @@ app6_resources = gnome.compile_resources(
|
||||
source_dir: '.'
|
||||
)
|
||||
|
||||
app6_schemas = gnome.compile_schemas()
|
||||
app6_schemas = gnome.compile_schemas(depend_files: files(['org.gtk.exampleapp.gschema.xml']))
|
||||
|
||||
|
||||
app6 = executable(
|
||||
@@ -21,3 +21,5 @@ app6 = executable(
|
||||
app6_schemas,
|
||||
dependencies: libgtk_dep
|
||||
)
|
||||
|
||||
install_data('org.gtk.exampleapp.gschema.xml', install_dir: gtk_schemasdir)
|
||||
|
||||
@@ -5,7 +5,7 @@ app7_resources = gnome.compile_resources(
|
||||
source_dir: '.'
|
||||
)
|
||||
|
||||
app7_schemas = gnome.compile_schemas()
|
||||
app7_schemas = gnome.compile_schemas(depend_files: files(['org.gtk.exampleapp.gschema.xml']))
|
||||
|
||||
|
||||
app7 = executable(
|
||||
@@ -21,3 +21,5 @@ app7 = executable(
|
||||
app7_schemas,
|
||||
dependencies: libgtk_dep
|
||||
)
|
||||
|
||||
install_data('org.gtk.exampleapp.gschema.xml', install_dir: gtk_schemasdir)
|
||||
|
||||
@@ -5,7 +5,7 @@ app8_resources = gnome.compile_resources(
|
||||
source_dir: '.'
|
||||
)
|
||||
|
||||
app8_schemas = gnome.compile_schemas()
|
||||
app8_schemas = gnome.compile_schemas(depend_files: files(['org.gtk.exampleapp.gschema.xml']))
|
||||
|
||||
|
||||
app8 = executable(
|
||||
@@ -21,3 +21,5 @@ app8 = executable(
|
||||
app8_schemas,
|
||||
dependencies: libgtk_dep
|
||||
)
|
||||
|
||||
install_data('org.gtk.exampleapp.gschema.xml', install_dir: gtk_schemasdir)
|
||||
|
||||
@@ -5,7 +5,7 @@ app9_resources = gnome.compile_resources(
|
||||
source_dir: '.'
|
||||
)
|
||||
|
||||
app9_schemas = gnome.compile_schemas()
|
||||
app9_schemas = gnome.compile_schemas(depend_files: files(['org.gtk.exampleapp.gschema.xml']))
|
||||
|
||||
|
||||
app9 = executable(
|
||||
@@ -21,3 +21,5 @@ app9 = executable(
|
||||
app9_schemas,
|
||||
dependencies: libgtk_dep
|
||||
)
|
||||
|
||||
install_data('org.gtk.exampleapp.gschema.xml', install_dir: gtk_schemasdir)
|
||||
|
||||
+11
-51
@@ -1,5 +1,7 @@
|
||||
## Makefile.am for gtk+/gdk
|
||||
include $(top_srcdir)/Makefile.decl
|
||||
include gdk-pub-headers.mak
|
||||
|
||||
-include $(INTROSPECTION_MAKEFILE)
|
||||
INTROSPECTION_GIRS =
|
||||
INTROSPECTION_SCANNER_ENV = \
|
||||
@@ -63,54 +65,10 @@ LDADD = \
|
||||
#
|
||||
# setup source file variables
|
||||
#
|
||||
#
|
||||
# GDK header files for public installation (non-generated)
|
||||
#
|
||||
#
|
||||
gdk_public_h_sources = \
|
||||
gdk.h \
|
||||
gdk-autocleanup.h \
|
||||
gdkapplaunchcontext.h \
|
||||
gdkcairo.h \
|
||||
gdkcursor.h \
|
||||
gdkdevice.h \
|
||||
gdkdevicepad.h \
|
||||
gdkdevicetool.h \
|
||||
gdkdevicemanager.h \
|
||||
gdkdisplay.h \
|
||||
gdkdisplaymanager.h \
|
||||
gdkdnd.h \
|
||||
gdkdrawingcontext.h \
|
||||
gdkevents.h \
|
||||
gdkframetimings.h \
|
||||
gdkglcontext.h \
|
||||
gdkkeys.h \
|
||||
gdkkeysyms.h \
|
||||
gdkkeysyms-compat.h \
|
||||
gdkmain.h \
|
||||
gdkmonitor.h \
|
||||
gdkpango.h \
|
||||
gdkframeclock.h \
|
||||
gdkpixbuf.h \
|
||||
gdkprivate.h \
|
||||
gdkproperty.h \
|
||||
gdkrectangle.h \
|
||||
gdkrgba.h \
|
||||
gdkscreen.h \
|
||||
gdkseat.h \
|
||||
gdkselection.h \
|
||||
gdktestutils.h \
|
||||
gdkthreads.h \
|
||||
gdktypes.h \
|
||||
gdkvisual.h \
|
||||
gdkwindow.h
|
||||
|
||||
deprecated_h_sources = \
|
||||
deprecated/gdkcolor.h
|
||||
|
||||
gdk_h_sources = \
|
||||
$(gdk_public_h_sources) \
|
||||
$(deprecated_h_sources)
|
||||
$(gdk_deprecated_h_sources)
|
||||
|
||||
gdk_private_headers = \
|
||||
gdk-private.h \
|
||||
@@ -201,7 +159,7 @@ gdkinclude_HEADERS = $(gdk_public_h_sources)
|
||||
nodist_gdkinclude_HEADERS = gdkconfig.h gdkenumtypes.h gdkversionmacros.h
|
||||
|
||||
deprecatedincludedir = $(includedir)/gtk-3.0/gdk/deprecated
|
||||
deprecatedinclude_HEADERS = $(deprecated_h_sources)
|
||||
deprecatedinclude_HEADERS = $(gdk_deprecated_h_sources)
|
||||
|
||||
common_sources = \
|
||||
$(gdk_private_headers) \
|
||||
@@ -499,14 +457,13 @@ gdkresources.c: gdk.gresource.xml $(resource_files)
|
||||
# ------------------- MSVC Build Items ----------------
|
||||
MSVCPROJS = gdk-3
|
||||
|
||||
gdk_3_FILES = $(libgdk_3_la_SOURCES)
|
||||
gdk_3_FILES = $(gdk_c_sources)
|
||||
gdk_3_EXCLUDES = dummy
|
||||
gdk_3_HEADERS_DIR = $(gdkincludedir)
|
||||
|
||||
gdk_3_HEADERS_INST = \
|
||||
$(gdkinclude_HEADERS) \
|
||||
$(deprecatedinclude_HEADERS) \
|
||||
$(nodist_gdkinclude_HEADERS)
|
||||
$(deprecatedinclude_HEADERS)
|
||||
|
||||
gdk_3_HEADERS_EXCLUDES = dummy
|
||||
|
||||
@@ -518,7 +475,9 @@ MSVC_INTROSPECT_GIRS = Gdk-3.0.gir GdkWin32-3.0.gir
|
||||
|
||||
BASE_MSVC_GIR_CFLAGS = \
|
||||
$(GDK_CFLAGS_DEFINES) \
|
||||
-I.. -I../gdk -I../gdk/win32
|
||||
-I'./vs$$$$(VSVER)/$$$$(CFG)/$$$$(PLAT)/obj/gdk-3' -I.. \
|
||||
-I'./vs$$$$(VSVER)/$$$$(CFG)/$$$$(PLAT)/obj/gdk-3/gdk' -I../gdk \
|
||||
-I../gdk/win32
|
||||
|
||||
INTROSPECTION_INTERMEDIATE_ITEMS = \
|
||||
$(top_builddir)/win32/Gdk-3.0.gir.msvc.introspect \
|
||||
@@ -526,7 +485,8 @@ INTROSPECTION_INTERMEDIATE_ITEMS = \
|
||||
$(top_builddir)/win32/GdkWin32-3.0.gir.msvc.introspect \
|
||||
$(top_builddir)/win32/GdkWin32_3_0_gir_list
|
||||
|
||||
Gdk_3_0_gir_MSVC_FILES = $(introspection_files)
|
||||
Gdk_3_0_gir_MSVC_FILES = $(filter-out gdkkeysyms-compat.h, $(gdk_h_sources)) \
|
||||
$(gdk_c_sources) \
|
||||
Gdk_3_0_gir_MSVC_EXPORT_PACKAGES = $(Gdk_3_0_gir_EXPORT_PACKAGES)
|
||||
Gdk_3_0_gir_MSVC_INCLUDE_GIRS = $(Gdk_3_0_gir_INCLUDES)
|
||||
Gdk_3_0_gir_MSVC_LIBS = gdk-3.0
|
||||
|
||||
+142
-20
@@ -1,3 +1,27 @@
|
||||
/* check if we are on Android and using Chrome */
|
||||
var isAndroidChrome = false;
|
||||
{
|
||||
var ua = navigator.userAgent.toLowerCase();
|
||||
if (ua.indexOf("android") > -1 && ua.indexOf("chrom") > -1) {
|
||||
isAndroidChrome = true;
|
||||
}
|
||||
}
|
||||
/* check for the passive option for Event listener */
|
||||
let passiveSupported = false;
|
||||
try {
|
||||
const options = {
|
||||
get passive() { // This function will be called when the browser
|
||||
// attempts to access the passive property.
|
||||
passiveSupported = true;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
window.addEventListener("test", null, options);
|
||||
window.removeEventListener("test", null, options);
|
||||
} catch(err) {
|
||||
passiveSupported = false;
|
||||
}
|
||||
/* Helper functions for debugging */
|
||||
var logDiv = null;
|
||||
function log(str) {
|
||||
@@ -10,6 +34,25 @@ function log(str) {
|
||||
logDiv.appendChild(document.createTextNode(str));
|
||||
logDiv.appendChild(document.createElement('br'));
|
||||
}
|
||||
/* Helper functions for touch identifier to make it unique on Android */
|
||||
var globalTouchIdentifier = Math.round(Date.now() / 1000);
|
||||
function touchIdentifierStart(tId)
|
||||
{
|
||||
if (isAndroidChrome) {
|
||||
if (tId == 0) {
|
||||
return ++globalTouchIdentifier;
|
||||
}
|
||||
return globalTouchIdentifier + tId;
|
||||
}
|
||||
return tId;
|
||||
}
|
||||
function touchIdentifier(tId)
|
||||
{
|
||||
if (isAndroidChrome) {
|
||||
return globalTouchIdentifier + tId;
|
||||
}
|
||||
return tId;
|
||||
}
|
||||
|
||||
function getStackTrace()
|
||||
{
|
||||
@@ -91,6 +134,7 @@ grab.window = null;
|
||||
grab.ownerEvents = false;
|
||||
grab.implicit = false;
|
||||
var keyDownList = [];
|
||||
var inputList = [];
|
||||
var lastSerial = 0;
|
||||
var lastX = 0;
|
||||
var lastY = 0;
|
||||
@@ -223,6 +267,7 @@ function cmdSetTransientFor(id, parentId)
|
||||
{
|
||||
var surface = surfaces[id];
|
||||
|
||||
if (surface === undefined) return;
|
||||
if (surface.transientParent == parentId)
|
||||
return;
|
||||
|
||||
@@ -253,8 +298,9 @@ function moveToHelper(surface, position) {
|
||||
|
||||
for (var cid in surfaces) {
|
||||
var child = surfaces[cid];
|
||||
if (child.transientParent == surface.id)
|
||||
if (child.transientParent == surface.id) {
|
||||
moveToHelper(child, stackingOrder.indexOf(surface) + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -269,6 +315,13 @@ function cmdDeleteSurface(id)
|
||||
stackingOrder.splice(i, 1);
|
||||
var canvas = surface.canvas;
|
||||
canvas.parentNode.removeChild(canvas);
|
||||
if (id == windowWithMouse) {
|
||||
windowWithMouse = 0;
|
||||
}
|
||||
if (id == realWindowWithMouse) {
|
||||
realWindowWithMouse = 0;
|
||||
firstTouchDownId = null;
|
||||
}
|
||||
delete surfaces[id];
|
||||
}
|
||||
|
||||
@@ -307,6 +360,7 @@ function cmdRaiseSurface(id)
|
||||
{
|
||||
var surface = surfaces[id];
|
||||
|
||||
if (surface === undefined) return;
|
||||
moveToHelper(surface);
|
||||
restackWindows();
|
||||
}
|
||||
@@ -315,6 +369,7 @@ function cmdLowerSurface(id)
|
||||
{
|
||||
var surface = surfaces[id];
|
||||
|
||||
if (surface === undefined) return;
|
||||
moveToHelper(surface, 0);
|
||||
restackWindows();
|
||||
}
|
||||
@@ -520,6 +575,7 @@ function cmdPutBuffer(id, w, h, compressed)
|
||||
var data = inflate.decompress();
|
||||
|
||||
var imageData = decodeBuffer (context, surface.imageData, w, h, data, debugDecoding);
|
||||
context.imageSmoothingEnabled = false;
|
||||
context.putImageData(imageData, 0, 0);
|
||||
|
||||
if (debugDecoding)
|
||||
@@ -776,8 +832,15 @@ function getEffectiveEventTarget (id) {
|
||||
function updateKeyboardStatus() {
|
||||
if (fakeInput != null && showKeyboardChanged) {
|
||||
showKeyboardChanged = false;
|
||||
if (showKeyboard)
|
||||
if (showKeyboard) {
|
||||
if (isAndroidChrome) {
|
||||
fakeInput.blur();
|
||||
fakeInput.value = ' '.repeat(80); // TODO: Should be exchange with broadway server
|
||||
// to bring real value here.
|
||||
}
|
||||
fakeInput.focus();
|
||||
//if (isAndroidChrome) fakeInput.click();
|
||||
}
|
||||
else
|
||||
fakeInput.blur();
|
||||
}
|
||||
@@ -2329,6 +2392,19 @@ function pushKeyEvent(fev) {
|
||||
keyDownList.push(fev);
|
||||
}
|
||||
|
||||
function copyInputEvent(ev) {
|
||||
var members = ['inputType', 'data'], i, obj = {};
|
||||
for (i = 0; i < members.length; i++) {
|
||||
if (typeof ev[members[i]] !== "undefined")
|
||||
obj[members[i]] = ev[members[i]];
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
function pushInputEvent(fev) {
|
||||
inputList.push(fev);
|
||||
}
|
||||
|
||||
function getKeyEvent(keyCode, pop) {
|
||||
var i, fev = null;
|
||||
for (i = keyDownList.length-1; i >= 0; i--) {
|
||||
@@ -2366,8 +2442,9 @@ function handleKeyDown(e) {
|
||||
// If it is a key or key combination that might trigger
|
||||
// browser behaviors or it has no corresponding keyPress
|
||||
// event, then send it immediately
|
||||
if (!ignoreKeyEvent(ev))
|
||||
if (!ignoreKeyEvent(ev)) {
|
||||
sendInput("k", [keysym, lastState]);
|
||||
}
|
||||
suppress = true;
|
||||
}
|
||||
|
||||
@@ -2411,8 +2488,9 @@ function handleKeyPress(e) {
|
||||
}
|
||||
|
||||
// Send the translated keysym
|
||||
if (keysym > 0)
|
||||
if (keysym > 0) {
|
||||
sendInput ("k", [keysym, lastState]);
|
||||
}
|
||||
|
||||
// Stop keypress events just in case
|
||||
return cancelEvent(ev);
|
||||
@@ -2427,11 +2505,45 @@ function handleKeyUp(e) {
|
||||
keysym = fev.keysym;
|
||||
else {
|
||||
//log("Key event (keyCode = " + ev.keyCode + ") not found on keyDownList");
|
||||
if (isAndroidChrome && (ev.keyCode == 229)) {
|
||||
var i, fev = null, len = inputList.length, str;
|
||||
for (i = 0; i < len; i++) {
|
||||
fev = inputList[i];
|
||||
switch(fev.inputType) {
|
||||
case "deleteContentBackward":
|
||||
sendInput ("k", [65288, lastState]);
|
||||
sendInput ("K", [65288, lastState]);
|
||||
break;
|
||||
case "insertText":
|
||||
if (fev.data !== undefined) {
|
||||
for (let sym of fev.data) {
|
||||
sendInput ("k", [sym.codePointAt(0), lastState]);
|
||||
sendInput ("K", [sym.codePointAt(0), lastState]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
inputList.splice(0, len);
|
||||
}
|
||||
keysym = 0;
|
||||
}
|
||||
|
||||
if (keysym > 0)
|
||||
if (keysym > 0) {
|
||||
sendInput ("K", [keysym, lastState]);
|
||||
}
|
||||
return cancelEvent(ev);
|
||||
}
|
||||
|
||||
function handleInput (e) {
|
||||
var fev = null, ev = (e ? e : window.event), keysym = null, suppress = false;
|
||||
|
||||
fev = copyInputEvent(ev);
|
||||
pushInputEvent(fev);
|
||||
|
||||
// Stop keypress events just in case
|
||||
return cancelEvent(ev);
|
||||
}
|
||||
|
||||
@@ -2450,6 +2562,11 @@ function onKeyUp (ev) {
|
||||
return handleKeyUp(ev);
|
||||
}
|
||||
|
||||
function onInput (ev) {
|
||||
updateForEvent(ev);
|
||||
return handleInput(ev);
|
||||
}
|
||||
|
||||
function cancelEvent(ev)
|
||||
{
|
||||
ev = ev ? ev : window.event;
|
||||
@@ -2481,13 +2598,14 @@ function onMouseWheel(ev)
|
||||
}
|
||||
|
||||
function onTouchStart(ev) {
|
||||
event.preventDefault();
|
||||
ev.preventDefault();
|
||||
|
||||
updateKeyboardStatus();
|
||||
updateForEvent(ev);
|
||||
|
||||
for (var i = 0; i < ev.changedTouches.length; i++) {
|
||||
var touch = ev.changedTouches.item(i);
|
||||
var touchId = touchIdentifierStart(touch.identifier);
|
||||
|
||||
var origId = getSurfaceId(touch);
|
||||
var id = getEffectiveEventTarget (origId);
|
||||
@@ -2495,7 +2613,7 @@ function onTouchStart(ev) {
|
||||
var isEmulated = 0;
|
||||
|
||||
if (firstTouchDownId == null) {
|
||||
firstTouchDownId = touch.identifier;
|
||||
firstTouchDownId = touchId;
|
||||
isEmulated = 1;
|
||||
|
||||
if (realWindowWithMouse != origId || id != windowWithMouse) {
|
||||
@@ -2510,52 +2628,54 @@ function onTouchStart(ev) {
|
||||
}
|
||||
}
|
||||
|
||||
sendInput ("t", [0, id, touch.identifier, isEmulated, pos.rootX, pos.rootY, pos.winX, pos.winY, lastState]);
|
||||
sendInput ("t", [0, id, touchId, isEmulated, pos.rootX, pos.rootY, pos.winX, pos.winY, lastState]);
|
||||
}
|
||||
}
|
||||
|
||||
function onTouchMove(ev) {
|
||||
event.preventDefault();
|
||||
ev.preventDefault();
|
||||
|
||||
updateKeyboardStatus();
|
||||
updateForEvent(ev);
|
||||
|
||||
for (var i = 0; i < ev.changedTouches.length; i++) {
|
||||
var touch = ev.changedTouches.item(i);
|
||||
var touchId = touchIdentifier(touch.identifier);
|
||||
|
||||
var origId = getSurfaceId(touch);
|
||||
var id = getEffectiveEventTarget (origId);
|
||||
var pos = getPositionsFromEvent(touch, id);
|
||||
|
||||
var isEmulated = 0;
|
||||
if (firstTouchDownId == touch.identifier) {
|
||||
if (firstTouchDownId == touchId) {
|
||||
isEmulated = 1;
|
||||
}
|
||||
|
||||
sendInput ("t", [1, id, touch.identifier, isEmulated, pos.rootX, pos.rootY, pos.winX, pos.winY, lastState]);
|
||||
sendInput ("t", [1, id, touchId, isEmulated, pos.rootX, pos.rootY, pos.winX, pos.winY, lastState]);
|
||||
}
|
||||
}
|
||||
|
||||
function onTouchEnd(ev) {
|
||||
event.preventDefault();
|
||||
ev.preventDefault();
|
||||
|
||||
updateKeyboardStatus();
|
||||
updateForEvent(ev);
|
||||
|
||||
for (var i = 0; i < ev.changedTouches.length; i++) {
|
||||
var touch = ev.changedTouches.item(i);
|
||||
var touchId = touchIdentifier(touch.identifier);
|
||||
|
||||
var origId = getSurfaceId(touch);
|
||||
var id = getEffectiveEventTarget (origId);
|
||||
var pos = getPositionsFromEvent(touch, id);
|
||||
|
||||
var isEmulated = 0;
|
||||
if (firstTouchDownId == touch.identifier) {
|
||||
if (firstTouchDownId == touchId) {
|
||||
isEmulated = 1;
|
||||
firstTouchDownId = null;
|
||||
}
|
||||
|
||||
sendInput ("t", [2, id, touch.identifier, isEmulated, pos.rootX, pos.rootY, pos.winX, pos.winY, lastState]);
|
||||
sendInput ("t", [2, id, touchId, isEmulated, pos.rootX, pos.rootY, pos.winX, pos.winY, lastState]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2572,11 +2692,11 @@ function setupDocument(document)
|
||||
document.onkeyup = onKeyUp;
|
||||
|
||||
if (document.addEventListener) {
|
||||
document.addEventListener('DOMMouseScroll', onMouseWheel, false);
|
||||
document.addEventListener('mousewheel', onMouseWheel, false);
|
||||
document.addEventListener('touchstart', onTouchStart, false);
|
||||
document.addEventListener('touchmove', onTouchMove, false);
|
||||
document.addEventListener('touchend', onTouchEnd, false);
|
||||
document.addEventListener('DOMMouseScroll', onMouseWheel, passiveSupported ? { passive: false, capture: false } : false);
|
||||
document.addEventListener('mousewheel', onMouseWheel, passiveSupported ? { passive: false, capture: false } : false);
|
||||
document.addEventListener('touchstart', onTouchStart, passiveSupported ? { passive: false, capture: false } : false);
|
||||
document.addEventListener('touchmove', onTouchMove, passiveSupported ? { passive: false, capture: false } : false);
|
||||
document.addEventListener('touchend', onTouchEnd, passiveSupported ? { passive: false, capture: false } : false);
|
||||
} else if (document.attachEvent) {
|
||||
element.attachEvent("onmousewheel", onMouseWheel);
|
||||
}
|
||||
@@ -2630,12 +2750,14 @@ function connect()
|
||||
};
|
||||
|
||||
var iOS = /(iPad|iPhone|iPod)/g.test( navigator.userAgent );
|
||||
if (iOS) {
|
||||
if (iOS || isAndroidChrome) {
|
||||
fakeInput = document.createElement("input");
|
||||
fakeInput.type = "text";
|
||||
fakeInput.style.position = "absolute";
|
||||
fakeInput.style.left = "-1000px";
|
||||
fakeInput.style.top = "-1000px";
|
||||
document.body.appendChild(fakeInput);
|
||||
if (isAndroidChrome)
|
||||
fakeInput.addEventListener('input', onInput, passiveSupported ? { passive: false, capture: false } : false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,7 +109,7 @@ _gdk_broadway_display_open (const gchar *display_name)
|
||||
broadway_display->server = _gdk_broadway_server_new (display_name, &error);
|
||||
if (broadway_display->server == NULL)
|
||||
{
|
||||
g_printerr ("Unable to init server: %s\n", error->message);
|
||||
GDK_NOTE (MISC, g_message ("Unable to init Broadway server: %s\n", error->message));
|
||||
g_error_free (error);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -224,6 +224,7 @@ _gdk_broadway_events_got_input (BroadwayInputMsg *message)
|
||||
event->scroll.y = message->pointer.win_y;
|
||||
event->scroll.x_root = message->pointer.root_x;
|
||||
event->scroll.y_root = message->pointer.root_y;
|
||||
event->scroll.state = message->pointer.state;
|
||||
event->scroll.direction = message->scroll.dir == 0 ? GDK_SCROLL_UP : GDK_SCROLL_DOWN;
|
||||
gdk_event_set_device (event, device_manager->core_pointer);
|
||||
gdk_event_set_seat (event, gdk_device_get_seat (device_manager->core_pointer));
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
#
|
||||
# GDK header files for public installation (non-generated)
|
||||
#
|
||||
#
|
||||
gdk_public_h_sources = \
|
||||
gdk.h \
|
||||
gdk-autocleanup.h \
|
||||
gdkapplaunchcontext.h \
|
||||
gdkcairo.h \
|
||||
gdkcursor.h \
|
||||
gdkdevice.h \
|
||||
gdkdevicepad.h \
|
||||
gdkdevicetool.h \
|
||||
gdkdevicemanager.h \
|
||||
gdkdisplay.h \
|
||||
gdkdisplaymanager.h \
|
||||
gdkdnd.h \
|
||||
gdkdrawingcontext.h \
|
||||
gdkevents.h \
|
||||
gdkframetimings.h \
|
||||
gdkglcontext.h \
|
||||
gdkkeys.h \
|
||||
gdkkeysyms.h \
|
||||
gdkkeysyms-compat.h \
|
||||
gdkmain.h \
|
||||
gdkmonitor.h \
|
||||
gdkpango.h \
|
||||
gdkframeclock.h \
|
||||
gdkpixbuf.h \
|
||||
gdkprivate.h \
|
||||
gdkproperty.h \
|
||||
gdkrectangle.h \
|
||||
gdkrgba.h \
|
||||
gdkscreen.h \
|
||||
gdkseat.h \
|
||||
gdkselection.h \
|
||||
gdktestutils.h \
|
||||
gdkthreads.h \
|
||||
gdktypes.h \
|
||||
gdkvisual.h \
|
||||
gdkwindow.h
|
||||
|
||||
gdk_deprecated_h_sources = \
|
||||
deprecated/gdkcolor.h
|
||||
+17
-17
@@ -370,7 +370,7 @@ gdk_cairo_draw_from_gl (cairo_t *cr,
|
||||
paint_data = gdk_gl_context_get_paint_data (paint_context);
|
||||
|
||||
if (paint_data->tmp_framebuffer == 0)
|
||||
glGenFramebuffersEXT (1, &paint_data->tmp_framebuffer);
|
||||
glGenFramebuffers (1, &paint_data->tmp_framebuffer);
|
||||
|
||||
if (source_type == GL_RENDERBUFFER)
|
||||
{
|
||||
@@ -423,10 +423,10 @@ gdk_cairo_draw_from_gl (cairo_t *cr,
|
||||
/* Create a framebuffer with the source renderbuffer and
|
||||
make it the current target for reads */
|
||||
framebuffer = paint_data->tmp_framebuffer;
|
||||
glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, framebuffer);
|
||||
glFramebufferRenderbufferEXT (GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
|
||||
GL_RENDERBUFFER_EXT, source);
|
||||
glBindFramebufferEXT (GL_DRAW_FRAMEBUFFER_EXT, 0);
|
||||
glBindFramebuffer (GL_FRAMEBUFFER, framebuffer);
|
||||
glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
|
||||
GL_RENDERBUFFER, source);
|
||||
glBindFramebuffer (GL_DRAW_FRAMEBUFFER, 0);
|
||||
|
||||
/* Translate to impl coords */
|
||||
cairo_region_translate (clip_region, dx, dy);
|
||||
@@ -481,11 +481,11 @@ gdk_cairo_draw_from_gl (cairo_t *cr,
|
||||
{
|
||||
int clipped_src_x = x + (dest.x - dx * window_scale);
|
||||
int clipped_src_y = y + (height - dest.height - (dest.y - dy * window_scale));
|
||||
glBlitFramebufferEXT(clipped_src_x, clipped_src_y,
|
||||
(clipped_src_x + dest.width), (clipped_src_y + dest.height),
|
||||
dest.x, FLIP_Y(dest.y + dest.height),
|
||||
dest.x + dest.width, FLIP_Y(dest.y),
|
||||
GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||
glBlitFramebuffer (clipped_src_x, clipped_src_y,
|
||||
(clipped_src_x + dest.width), (clipped_src_y + dest.height),
|
||||
dest.x, FLIP_Y(dest.y + dest.height),
|
||||
dest.x + dest.width, FLIP_Y(dest.y),
|
||||
GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||
if (impl_window->current_paint.flushed_region)
|
||||
{
|
||||
cairo_rectangle_int_t flushed_rect;
|
||||
@@ -505,7 +505,7 @@ gdk_cairo_draw_from_gl (cairo_t *cr,
|
||||
|
||||
glDisable (GL_SCISSOR_TEST);
|
||||
|
||||
glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, 0);
|
||||
glBindFramebuffer (GL_FRAMEBUFFER, 0);
|
||||
|
||||
#undef FLIP_Y
|
||||
|
||||
@@ -671,19 +671,19 @@ gdk_cairo_draw_from_gl (cairo_t *cr,
|
||||
cairo_surface_set_device_scale (image, buffer_scale, buffer_scale);
|
||||
|
||||
framebuffer = paint_data->tmp_framebuffer;
|
||||
glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, framebuffer);
|
||||
glBindFramebuffer (GL_FRAMEBUFFER, framebuffer);
|
||||
|
||||
if (source_type == GL_RENDERBUFFER)
|
||||
{
|
||||
/* Create a framebuffer with the source renderbuffer and
|
||||
make it the current target for reads */
|
||||
glFramebufferRenderbufferEXT (GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
|
||||
GL_RENDERBUFFER_EXT, source);
|
||||
glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
|
||||
GL_RENDERBUFFER, source);
|
||||
}
|
||||
else
|
||||
{
|
||||
glFramebufferTexture2DEXT (GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
|
||||
GL_TEXTURE_2D, source, 0);
|
||||
glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
|
||||
GL_TEXTURE_2D, source, 0);
|
||||
}
|
||||
|
||||
glPixelStorei (GL_PACK_ALIGNMENT, 4);
|
||||
@@ -699,7 +699,7 @@ gdk_cairo_draw_from_gl (cairo_t *cr,
|
||||
|
||||
glPixelStorei (GL_PACK_ROW_LENGTH, 0);
|
||||
|
||||
glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, 0);
|
||||
glBindFramebuffer (GL_FRAMEBUFFER, 0);
|
||||
|
||||
cairo_surface_mark_dirty (image);
|
||||
|
||||
|
||||
@@ -288,6 +288,7 @@ gdk_pixbuf_get_from_surface (cairo_surface_t *surface,
|
||||
if (cairo_surface_status (surface) || dest == NULL)
|
||||
{
|
||||
cairo_surface_destroy (surface);
|
||||
g_clear_object (&dest);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -43,7 +43,8 @@ struct _GdkSeatDefaultPrivate
|
||||
GDK_ENTER_NOTIFY_MASK | \
|
||||
GDK_LEAVE_NOTIFY_MASK | \
|
||||
GDK_PROXIMITY_IN_MASK | \
|
||||
GDK_PROXIMITY_OUT_MASK)
|
||||
GDK_PROXIMITY_OUT_MASK | \
|
||||
GDK_TOUCHPAD_GESTURE_MASK)
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (GdkSeatDefault, gdk_seat_default, GDK_TYPE_SEAT)
|
||||
|
||||
|
||||
+2
-2
@@ -1286,7 +1286,7 @@ get_native_device_event_mask (GdkWindow *private,
|
||||
if (gdk_window_is_toplevel (private) ||
|
||||
mask & GDK_BUTTON_PRESS_MASK)
|
||||
mask |=
|
||||
GDK_TOUCH_MASK |
|
||||
GDK_TOUCH_MASK | GDK_TOUCHPAD_GESTURE_MASK |
|
||||
GDK_POINTER_MOTION_MASK |
|
||||
GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
|
||||
GDK_SCROLL_MASK;
|
||||
@@ -10200,7 +10200,7 @@ gdk_window_create_similar_surface (GdkWindow * window,
|
||||
* gdk_window_create_similar_image_surface:
|
||||
* @window: (nullable): window to make new surface similar to, or
|
||||
* %NULL if none
|
||||
* @format: (type int): the format for the new surface
|
||||
* @format: the format for the new surface
|
||||
* @width: width of the new surface
|
||||
* @height: height of the new surface
|
||||
* @scale: the scale of the new surface, or 0 to use same as @window
|
||||
|
||||
@@ -803,8 +803,7 @@ update_context_from_dragging_info (id <NSDraggingInfo> sender)
|
||||
|
||||
gdk_event_free (event);
|
||||
|
||||
g_object_unref (_gdk_quartz_drag_source_context);
|
||||
_gdk_quartz_drag_source_context = NULL;
|
||||
_gdk_quartz_drag_source_context_destroy_gtk_only ();
|
||||
}
|
||||
|
||||
#ifdef AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER
|
||||
|
||||
@@ -289,6 +289,24 @@
|
||||
gdk_screen_get_rgba_visual (_gdk_screen);
|
||||
}
|
||||
|
||||
- (void) viewWillDraw
|
||||
{
|
||||
/* MacOS 11 (Big Sur) has added a new, dynamic "accent" as default.
|
||||
* This uses a 10-bit colorspace so every GIMP drawing operation
|
||||
* has the additional cost of an 8-bit (ARGB) to 10-bit conversion.
|
||||
* Let's disable this mode to regain the lost performance.
|
||||
*/
|
||||
if(gdk_quartz_osx_version() >= GDK_OSX_BIGSUR)
|
||||
{
|
||||
#if MAC_OS_X_VERSION_MIN_REQUIRED >= 101200
|
||||
CALayer* layer = self.layer;
|
||||
layer.contentsFormat = kCAContentsFormatRGBA8Uint;
|
||||
#endif
|
||||
}
|
||||
|
||||
[super viewWillDraw];
|
||||
}
|
||||
|
||||
-(void)drawRect: (NSRect)rect
|
||||
{
|
||||
GdkRectangle gdk_rect;
|
||||
@@ -416,7 +434,7 @@
|
||||
{
|
||||
if (GDK_WINDOW_DESTROYED (gdk_window))
|
||||
return;
|
||||
|
||||
|
||||
[super setFrame: frame];
|
||||
|
||||
if ([self window])
|
||||
|
||||
@@ -60,6 +60,7 @@ libgdkinclude_HEADERS = \
|
||||
gdkquartz.h
|
||||
|
||||
libgdkquartzinclude_HEADERS = \
|
||||
gdkquartz-cocoa-access.h \
|
||||
gdkquartz-gtk-only.h \
|
||||
gdkquartzcursor.h \
|
||||
gdkquartzdevice-core.h \
|
||||
|
||||
@@ -32,6 +32,8 @@
|
||||
#include "gdkdisplay-quartz.h"
|
||||
#include "gdkmonitor-quartz.h"
|
||||
#include "gdkglcontext-quartz.h"
|
||||
#include "gdkinternal-quartz.h"
|
||||
#include "gdkwindow.h"
|
||||
|
||||
/* Note about coordinates: There are three coordinate systems at play:
|
||||
*
|
||||
@@ -452,10 +454,29 @@ static GdkMonitor *
|
||||
gdk_quartz_display_get_monitor_at_window (GdkDisplay *display,
|
||||
GdkWindow *window)
|
||||
{
|
||||
GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
|
||||
NSWindow *nswindow = impl->toplevel;
|
||||
NSScreen *screen = [nswindow screen];
|
||||
GdkWindowImplQuartz *impl = NULL;
|
||||
NSWindow *nswindow = NULL;
|
||||
NSScreen *screen = NULL;
|
||||
GdkMonitor *monitor = NULL;
|
||||
GdkWindow *onscreen_window = window;
|
||||
|
||||
/*
|
||||
* This stops crashes when there is no NSWindow available on
|
||||
* an offscreen window which occurs for children of children
|
||||
* of an onscreen window (children of an onscreen window do
|
||||
* have NSWindow set)
|
||||
* https://gitlab.gnome.org/GNOME/gimp/-/issues/7608
|
||||
*/
|
||||
while (onscreen_window && onscreen_window->window_type == GDK_WINDOW_OFFSCREEN)
|
||||
onscreen_window = onscreen_window->parent;
|
||||
|
||||
if (!onscreen_window)
|
||||
return NULL;
|
||||
|
||||
impl = GDK_WINDOW_IMPL_QUARTZ (onscreen_window->impl);
|
||||
nswindow = impl->toplevel;
|
||||
screen = [nswindow screen];
|
||||
|
||||
if (screen)
|
||||
{
|
||||
GdkQuartzDisplay *quartz_display = GDK_QUARTZ_DISPLAY (display);
|
||||
|
||||
@@ -20,12 +20,13 @@
|
||||
#ifndef __GDK_QUARTZ_DISPLAY__
|
||||
#define __GDK_QUARTZ_DISPLAY__
|
||||
|
||||
#include <AppKit/AppKit.h>
|
||||
|
||||
#include "gdkdisplayprivate.h"
|
||||
#include "gdkkeys.h"
|
||||
#include "gdkwindow.h"
|
||||
#include "gdkinternals.h"
|
||||
#include "gdkmain.h"
|
||||
#include "gdkinternal-quartz.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
||||
@@ -59,6 +59,14 @@ _gdk_quartz_window_drag_begin (GdkWindow *window,
|
||||
return _gdk_quartz_drag_source_context;
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_quartz_drag_source_context_destroy_gtk_only ()
|
||||
{
|
||||
if (_gdk_quartz_drag_source_context)
|
||||
g_object_unref (_gdk_quartz_drag_source_context);
|
||||
_gdk_quartz_drag_source_context = NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_quartz_drag_context_drag_motion (GdkDragContext *context,
|
||||
GdkWindow *dest_window,
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
#include "gdkquartzglcontext.h"
|
||||
#include "gdkquartzwindow.h"
|
||||
#include "gdkprivate-quartz.h"
|
||||
#include "gdkquartz-gtk-only.h"
|
||||
#include "gdkquartz-cocoa-access.h"
|
||||
|
||||
#include "gdkinternals.h"
|
||||
|
||||
|
||||
@@ -29,28 +29,26 @@ GdkWindow *_gdk_root = NULL;
|
||||
GdkOSXVersion
|
||||
gdk_quartz_osx_version (void)
|
||||
{
|
||||
static gint32 minor = GDK_OSX_UNSUPPORTED;
|
||||
static gint32 vkey = GDK_OSX_UNSUPPORTED;
|
||||
|
||||
if (minor == GDK_OSX_UNSUPPORTED)
|
||||
if (vkey == GDK_OSX_UNSUPPORTED)
|
||||
{
|
||||
#if MAC_OS_X_VERSION_MIN_REQUIRED < 101000
|
||||
OSErr err = Gestalt (gestaltSystemVersionMinor, (SInt32*)&minor);
|
||||
OSErr err = Gestalt (gestaltSystemVersionMinor, (SInt32*)&vkey);
|
||||
|
||||
g_return_val_if_fail (err == noErr, GDK_OSX_UNSUPPORTED);
|
||||
#else
|
||||
NSOperatingSystemVersion version;
|
||||
|
||||
version = [[NSProcessInfo processInfo] operatingSystemVersion];
|
||||
minor = version.minorVersion;
|
||||
if (version.majorVersion == 11)
|
||||
minor += 16;
|
||||
vkey = version.majorVersion == 10 ? version.minorVersion : version.majorVersion + 5;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (minor < GDK_OSX_MIN)
|
||||
if (vkey < GDK_OSX_MIN)
|
||||
return GDK_OSX_UNSUPPORTED;
|
||||
else if (minor > GDK_OSX_CURRENT)
|
||||
else if (vkey > GDK_OSX_CURRENT)
|
||||
return GDK_OSX_NEW;
|
||||
else
|
||||
return minor;
|
||||
return vkey;
|
||||
}
|
||||
|
||||
@@ -42,16 +42,16 @@ typedef float CGFloat;
|
||||
#define GDK_QUARTZ_ALLOC_POOL NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]
|
||||
#define GDK_QUARTZ_RELEASE_POOL [pool release]
|
||||
|
||||
#include <gdk/gdkprivate.h>
|
||||
#include <gdk/quartz/gdkquartz.h>
|
||||
#include <gdk/quartz/gdkdevicemanager-core-quartz.h>
|
||||
#include <gdk/quartz/gdkdnd-quartz.h>
|
||||
#include <gdk/quartz/gdkscreen-quartz.h>
|
||||
#include <gdk/quartz/gdkwindow-quartz.h>
|
||||
#include "../gdkprivate.h"
|
||||
#include "gdkquartz.h"
|
||||
#include "gdkdevicemanager-core-quartz.h"
|
||||
#include "gdkdnd-quartz.h"
|
||||
#include "gdkscreen-quartz.h"
|
||||
#include "gdkwindow-quartz.h"
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
|
||||
#include "config.h"
|
||||
#include <config.h>
|
||||
|
||||
extern GdkDisplay *_gdk_display;
|
||||
extern GdkScreen *_gdk_screen;
|
||||
@@ -75,7 +75,7 @@ typedef enum {
|
||||
GDK_QUARTZ_EVENT_SUBTYPE_EVENTLOOP
|
||||
} GdkQuartzEventSubType;
|
||||
|
||||
#if MAC_OS_X_VERSION_MIN_REQUIRED >= 10130
|
||||
#if MAC_OS_X_VERSION_MIN_REQUIRED >= 101300
|
||||
#define GDK_QUARTZ_EVENT_TABLET_PROXIMITY NSEventTypeTabletProximity
|
||||
#define GDK_QUARTZ_EVENT_SUBTYPE_TABLET_PROXIMITY NSEventSubtypeTabletProximity
|
||||
#define GDK_QUARTZ_EVENT_SUBTYPE_TABLET_POINT NSEventSubtypeTabletPoint
|
||||
|
||||
@@ -812,13 +812,13 @@ input_sources_changed_notification (CFNotificationCenterRef center,
|
||||
static void
|
||||
gdk_quartz_keymap_init (GdkQuartzKeymap *keymap)
|
||||
{
|
||||
update_keymap ();
|
||||
CFNotificationCenterAddObserver (CFNotificationCenterGetDistributedCenter (),
|
||||
keymap,
|
||||
input_sources_changed_notification,
|
||||
CFSTR ("AppleSelectedInputSourcesChangedNotification"),
|
||||
NULL,
|
||||
CFNotificationSuspensionBehaviorDeliverImmediately);
|
||||
update_keymap ();
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
#include "gdkmonitor-quartz.h"
|
||||
#include "gdkdisplay-quartz.h"
|
||||
#include "gdkinternal-quartz.h"
|
||||
|
||||
G_DEFINE_TYPE (GdkQuartzMonitor, gdk_quartz_monitor, GDK_TYPE_MONITOR)
|
||||
|
||||
|
||||
@@ -20,12 +20,12 @@
|
||||
|
||||
#include <glib.h>
|
||||
#include <gio/gio.h>
|
||||
#include <AppKit/AppKit.h>
|
||||
|
||||
#include "gdkmonitorprivate.h"
|
||||
|
||||
#include "gdkquartzmonitor.h"
|
||||
#include "gdkprivate-quartz.h"
|
||||
#include "gdkinternal-quartz.h"
|
||||
|
||||
struct _GdkQuartzMonitor
|
||||
{
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
/* gdkquartz-gtk-only.h
|
||||
*
|
||||
* Copyright (C) 2005-2007 Imendio AB
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GDK_QUARTZ_COCOA_ACCESS_H__
|
||||
#define __GDK_QUARTZ_COCOA_ACCESS_H__
|
||||
|
||||
#ifndef __OBJC__
|
||||
#error "This header declares Cocoa types and can be included only from source files compiled with Objective-C."
|
||||
#endif
|
||||
|
||||
#include <AppKit/AppKit.h>
|
||||
#include <gdk/gdk.h>
|
||||
#include "gdkquartz.h"
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
NSEvent *gdk_quartz_event_get_nsevent (GdkEvent *event);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
NSWindow *gdk_quartz_window_get_nswindow (GdkWindow *window);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
NSView *gdk_quartz_window_get_nsview (GdkWindow *window);
|
||||
|
||||
#endif
|
||||
@@ -38,13 +38,5 @@ NSString *gdk_quartz_atom_to_pasteboard_type_libgtk_only (GdkAtom
|
||||
/* Utilities */
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
NSImage *gdk_quartz_pixbuf_to_ns_image_libgtk_only (GdkPixbuf *pixbuf);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
NSEvent *gdk_quartz_event_get_nsevent (GdkEvent *event);
|
||||
|
||||
/* Window */
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
NSWindow *gdk_quartz_window_get_nswindow (GdkWindow *window);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
NSView *gdk_quartz_window_get_nsview (GdkWindow *window);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -42,7 +42,8 @@ typedef enum
|
||||
GDK_OSX_MOJAVE = 14,
|
||||
GDK_OSX_CATALINA = 15,
|
||||
GDK_OSX_BIGSUR = 16,
|
||||
GDK_OSX_CURRENT = 15,
|
||||
GDK_OSX_MONTEREY = 17,
|
||||
GDK_OSX_CURRENT = 17,
|
||||
GDK_OSX_NEW = 99
|
||||
} GdkOSXVersion;
|
||||
|
||||
|
||||
@@ -51,6 +51,9 @@ id gdk_quartz_drag_context_get_dragging_info_libgtk_only (GdkDragContext
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkDragContext *gdk_quartz_drag_source_context_libgtk_only (void);
|
||||
|
||||
GDK_AVAILABLE_IN_3_24
|
||||
void _gdk_quartz_drag_source_context_destroy_gtk_only ();
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_QUARTZ_DRAG_CONTEXT_H__ */
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#include "gdkprivate-quartz.h"
|
||||
#include "gdkdisplay-quartz.h"
|
||||
#include "gdkmonitor-quartz.h"
|
||||
|
||||
#include "gdkinternal-quartz.h"
|
||||
|
||||
/* A couple of notes about this file are in order. In GDK, a
|
||||
* GdkScreen can contain multiple monitors. A GdkScreen has an
|
||||
|
||||
@@ -180,6 +180,7 @@ _gdk_quartz_display_text_property_to_utf8_list (GdkDisplay *display,
|
||||
#define GDK_QUARTZ_STRING_PBOARD_TYPE NSStringPboardType
|
||||
#define GDK_QUARTZ_TIFF_PBOARD_TYPE NSTIFFPboardType
|
||||
#else
|
||||
#define GDK_QUARTZ_FILE_PBOARD_TYPE NSPasteboardTypeFileURL
|
||||
#define GDK_QUARTZ_URL_PBOARD_TYPE NSPasteboardTypeURL
|
||||
#define GDK_QUARTZ_COLOR_PBOARD_TYPE NSPasteboardTypeColor
|
||||
#define GDK_QUARTZ_STRING_PBOARD_TYPE NSPasteboardTypeString
|
||||
@@ -197,6 +198,10 @@ gdk_quartz_pasteboard_type_to_atom_libgtk_only (NSString *type)
|
||||
return gdk_atom_intern_static_string ("application/x-color");
|
||||
else if ([type isEqualToString:GDK_QUARTZ_URL_PBOARD_TYPE])
|
||||
return gdk_atom_intern_static_string ("text/uri-list");
|
||||
#if MAC_OS_X_VERSION_MIN_REQUIRED >= 101400
|
||||
else if ([type isEqualToString:GDK_QUARTZ_FILE_PBOARD_TYPE])
|
||||
return gdk_atom_intern_static_string ("text/uri-list");
|
||||
#endif
|
||||
else
|
||||
return gdk_atom_intern ([type UTF8String], FALSE);
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <gdkinternals.h>
|
||||
|
||||
#include "gdkquartz-gtk-only.h"
|
||||
#include "gdkquartz-cocoa-access.h"
|
||||
#include <gdkquartzutils.h>
|
||||
|
||||
NSImage *
|
||||
|
||||
@@ -30,7 +30,8 @@
|
||||
#include "gdkquartzglcontext.h"
|
||||
#include "gdkquartzscreen.h"
|
||||
#include "gdkquartzcursor.h"
|
||||
#include "gdkquartz-gtk-only.h"
|
||||
#include "gdkquartz-cocoa-access.h"
|
||||
#include "gdkinternal-quartz.h"
|
||||
|
||||
#include <Carbon/Carbon.h>
|
||||
#include <AvailabilityMacros.h>
|
||||
@@ -161,8 +162,16 @@ gdk_window_impl_quartz_get_context (GdkWindowImplQuartz *window_impl,
|
||||
*/
|
||||
if (window_impl->in_paint_rect_count == 0)
|
||||
{
|
||||
if (![window_impl->view lockFocusIfCanDraw])
|
||||
return NULL;
|
||||
/* The NSView focus-locking API set was deprecated in MacOS 10.14 and
|
||||
* has a significant cost in MacOS 11 - every lock/unlock seems to
|
||||
* trigger a drawRect: call for the entire window. To return the
|
||||
* lost performance, do not use the locking API in MacOS 11+
|
||||
*/
|
||||
if(gdk_quartz_osx_version() < GDK_OSX_BIGSUR)
|
||||
{
|
||||
if (![window_impl->view lockFocusIfCanDraw])
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED < 101000
|
||||
cg_context = [[NSGraphicsContext currentContext] graphicsPort];
|
||||
@@ -182,8 +191,7 @@ gdk_window_impl_quartz_get_context (GdkWindowImplQuartz *window_impl,
|
||||
* in gdk_quartz_ref_cairo_surface () */
|
||||
scale = CGContextConvertSizeToDeviceSpace (cg_context,
|
||||
CGSizeMake (1.0, 1.0));
|
||||
CGContextScaleCTM (cg_context, 1.0 / scale.width, 1.0 / scale.height);
|
||||
|
||||
CGContextScaleCTM (cg_context, 1.0 / fabs(scale.width), 1.0 / fabs(scale.height));
|
||||
return cg_context;
|
||||
}
|
||||
|
||||
@@ -201,7 +209,15 @@ gdk_window_impl_quartz_release_context (GdkWindowImplQuartz *window_impl,
|
||||
if (window_impl->in_paint_rect_count == 0)
|
||||
{
|
||||
_gdk_quartz_window_flush (window_impl);
|
||||
[window_impl->view unlockFocus];
|
||||
|
||||
/* As per gdk_window_impl_quartz_get_context(), the NSView
|
||||
* focus-locking API set was deprecated in MacOS 10.14 and has
|
||||
* a significant cost in MacOS 11 - every lock/unlock seems to
|
||||
* trigger a drawRect: call for the entire window. To return the
|
||||
* lost performance, do not use the locking API in MacOS 11+
|
||||
*/
|
||||
if(gdk_quartz_osx_version() < GDK_OSX_BIGSUR)
|
||||
[window_impl->view unlockFocus];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -879,6 +895,7 @@ _gdk_quartz_display_create_window_impl (GdkDisplay *display,
|
||||
NULL));
|
||||
|
||||
impl->view = NULL;
|
||||
impl->toplevel = NULL;
|
||||
|
||||
if (attributes_mask & GDK_WA_TYPE_HINT)
|
||||
{
|
||||
@@ -2228,7 +2245,7 @@ _gdk_quartz_window_set_collection_behavior (NSWindow *nswindow,
|
||||
GdkWindowTypeHint hint)
|
||||
{
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 10110
|
||||
#if MAC_OS_X_VERSION_MIN_REQUIRED >= 101100
|
||||
#define GDK_QUARTZ_ALLOWS_TILING NSWindowCollectionBehaviorFullScreenAllowsTiling
|
||||
#define GDK_QUARTZ_DISALLOWS_TILING NSWindowCollectionBehaviorFullScreenDisallowsTiling
|
||||
#else
|
||||
@@ -2441,11 +2458,14 @@ gdk_quartz_window_set_decorations (GdkWindow *window,
|
||||
|
||||
impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
|
||||
|
||||
if (decorations == 0 || GDK_WINDOW_TYPE (window) == GDK_WINDOW_TEMP ||
|
||||
if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TEMP ||
|
||||
impl->type_hint == GDK_WINDOW_TYPE_HINT_SPLASHSCREEN )
|
||||
{
|
||||
new_mask = GDK_QUARTZ_BORDERLESS_WINDOW;
|
||||
}
|
||||
else if (decorations == 0) {
|
||||
new_mask = GDK_QUARTZ_BORDERLESS_WINDOW | GDK_QUARTZ_MINIATURIZABLE_WINDOW;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* FIXME: Honor other GDK_DECOR_* flags. */
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
#import <gdk/quartz/GdkQuartzView.h>
|
||||
#import <gdk/quartz/GdkQuartzNSWindow.h>
|
||||
#include "gdk/gdkwindowimpl.h"
|
||||
#include "gdkinternal-quartz.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ gdk_quartz_sources = files(
|
||||
)
|
||||
|
||||
gdk_quartz_public_headers = files(
|
||||
'gdkquartz-cocoa-access.h',
|
||||
'gdkquartzcursor.h',
|
||||
'gdkquartzdevice-core.h',
|
||||
'gdkquartzdevicemanager-core.h',
|
||||
@@ -47,8 +48,9 @@ core_graphics_dep = dependency('appleframeworks', modules : 'CoreGraphics', requ
|
||||
appkit_dep = dependency('appleframeworks', modules : 'AppKit', required : true)
|
||||
cocoa_dep = dependency('appleframeworks', modules : 'Cocoa', required : true)
|
||||
carbon_dep = dependency('appleframeworks', modules : 'Carbon', required : true)
|
||||
quartzcore_dep = dependency('appleframeworks', modules : 'QuartzCore', required : true)
|
||||
|
||||
gdk_quartz_deps = [ core_graphics_dep, appkit_dep, cocoa_dep, carbon_dep ]
|
||||
gdk_quartz_deps = [ core_graphics_dep, appkit_dep, cocoa_dep, carbon_dep, quartzcore_dep ]
|
||||
|
||||
libgdk_quartz = static_library('gdk-quartz',
|
||||
gdk_quartz_sources, gdkconfig, gdkenum_h,
|
||||
|
||||
@@ -2195,6 +2195,7 @@ deliver_key_event (GdkWaylandSeat *seat,
|
||||
struct xkb_keymap *xkb_keymap;
|
||||
GdkKeymap *keymap;
|
||||
xkb_keysym_t sym;
|
||||
int layout;
|
||||
guint delay, interval, timeout;
|
||||
gint64 begin_time, now;
|
||||
|
||||
@@ -2207,6 +2208,7 @@ deliver_key_event (GdkWaylandSeat *seat,
|
||||
xkb_keymap = _gdk_wayland_keymap_get_xkb_keymap (keymap);
|
||||
|
||||
sym = xkb_state_key_get_one_sym (xkb_state, key);
|
||||
layout = xkb_state_key_get_layout (xkb_state, key);
|
||||
if (sym == XKB_KEY_NoSymbol)
|
||||
return;
|
||||
|
||||
@@ -2220,7 +2222,7 @@ deliver_key_event (GdkWaylandSeat *seat,
|
||||
gdk_event_set_seat (event, GDK_SEAT (seat));
|
||||
event->key.time = time_;
|
||||
event->key.state = device_get_modifiers (seat->master_pointer);
|
||||
event->key.group = 0;
|
||||
event->key.group = layout;
|
||||
event->key.hardware_keycode = key;
|
||||
gdk_event_set_scancode (event, key);
|
||||
event->key.keyval = sym;
|
||||
@@ -2506,6 +2508,9 @@ touch_handle_down (void *data,
|
||||
|
||||
_gdk_wayland_display_update_serial (display, serial);
|
||||
|
||||
if (!wl_surface)
|
||||
return;
|
||||
|
||||
touch = gdk_wayland_seat_add_touch (seat, id, wl_surface);
|
||||
touch->x = wl_fixed_to_double (x);
|
||||
touch->y = wl_fixed_to_double (y);
|
||||
@@ -2541,6 +2546,9 @@ touch_handle_up (void *data,
|
||||
_gdk_wayland_display_update_serial (display, serial);
|
||||
|
||||
touch = gdk_wayland_seat_get_touch (seat, id);
|
||||
if (!touch)
|
||||
return;
|
||||
|
||||
event = _create_touch_event (seat, touch, GDK_TOUCH_END, time);
|
||||
|
||||
GDK_NOTE (EVENTS,
|
||||
@@ -2567,6 +2575,9 @@ touch_handle_motion (void *data,
|
||||
GdkEvent *event;
|
||||
|
||||
touch = gdk_wayland_seat_get_touch (seat, id);
|
||||
if (!touch)
|
||||
return;
|
||||
|
||||
touch->x = wl_fixed_to_double (x);
|
||||
touch->y = wl_fixed_to_double (y);
|
||||
|
||||
@@ -3680,19 +3691,21 @@ tablet_tool_handle_proximity_in (void *data,
|
||||
struct zwp_tablet_tool_v2 *wp_tablet_tool,
|
||||
uint32_t serial,
|
||||
struct zwp_tablet_v2 *wp_tablet,
|
||||
struct wl_surface *surface)
|
||||
struct wl_surface *wl_surface)
|
||||
{
|
||||
GdkWaylandTabletToolData *tool = data;
|
||||
GdkWaylandTabletData *tablet = zwp_tablet_v2_get_user_data (wp_tablet);
|
||||
GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (tablet->seat);
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (seat->display);
|
||||
GdkWindow *window = wl_surface_get_user_data (surface);
|
||||
GdkWindow *window;
|
||||
GdkEvent *event;
|
||||
|
||||
if (!surface)
|
||||
return;
|
||||
if (!wl_surface)
|
||||
return;
|
||||
|
||||
window = wl_surface_get_user_data (wl_surface);
|
||||
if (!GDK_IS_WINDOW (window))
|
||||
return;
|
||||
return;
|
||||
|
||||
tool->current_tablet = tablet;
|
||||
tablet->current_tool = tool;
|
||||
@@ -3731,6 +3744,9 @@ tablet_tool_handle_proximity_out (void *data,
|
||||
GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (tool->seat);
|
||||
#endif
|
||||
|
||||
if (!tablet)
|
||||
return;
|
||||
|
||||
GDK_NOTE (EVENTS,
|
||||
g_message ("proximity out, seat %p, tool %d", seat,
|
||||
gdk_device_tool_get_tool_type (tool->tool)));
|
||||
@@ -3787,7 +3803,7 @@ tablet_tool_handle_down (void *data,
|
||||
GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (tool->seat);
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (seat->display);
|
||||
|
||||
if (!tablet->pointer_info.focus)
|
||||
if (!tablet || !tablet->pointer_info.focus)
|
||||
return;
|
||||
|
||||
_gdk_wayland_display_update_serial (display_wayland, serial);
|
||||
@@ -3804,7 +3820,7 @@ tablet_tool_handle_up (void *data,
|
||||
GdkWaylandTabletToolData *tool = data;
|
||||
GdkWaylandTabletData *tablet = tool->current_tablet;
|
||||
|
||||
if (!tablet->pointer_info.focus)
|
||||
if (!tablet || !tablet->pointer_info.focus)
|
||||
return;
|
||||
|
||||
tablet_create_button_event_frame (tablet, GDK_BUTTON_RELEASE, GDK_BUTTON_PRIMARY);
|
||||
@@ -3823,6 +3839,9 @@ tablet_tool_handle_motion (void *data,
|
||||
GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (seat->display);
|
||||
GdkEvent *event;
|
||||
|
||||
if (!tablet)
|
||||
return;
|
||||
|
||||
tablet->pointer_info.surface_x = wl_fixed_to_double (sx);
|
||||
tablet->pointer_info.surface_y = wl_fixed_to_double (sy);
|
||||
|
||||
@@ -3855,7 +3874,12 @@ tablet_tool_handle_pressure (void *data,
|
||||
{
|
||||
GdkWaylandTabletToolData *tool = data;
|
||||
GdkWaylandTabletData *tablet = tool->current_tablet;
|
||||
gint axis_index = tablet->axis_indices[GDK_AXIS_PRESSURE];
|
||||
gint axis_index;
|
||||
|
||||
if (!tablet)
|
||||
return;
|
||||
|
||||
axis_index = tablet->axis_indices[GDK_AXIS_PRESSURE];
|
||||
|
||||
_gdk_device_translate_axis (tablet->current_device, axis_index,
|
||||
pressure, &tablet->axes[axis_index]);
|
||||
@@ -3872,7 +3896,12 @@ tablet_tool_handle_distance (void *data,
|
||||
{
|
||||
GdkWaylandTabletToolData *tool = data;
|
||||
GdkWaylandTabletData *tablet = tool->current_tablet;
|
||||
gint axis_index = tablet->axis_indices[GDK_AXIS_DISTANCE];
|
||||
gint axis_index;
|
||||
|
||||
if (!tablet)
|
||||
return;
|
||||
|
||||
axis_index = tablet->axis_indices[GDK_AXIS_DISTANCE];
|
||||
|
||||
_gdk_device_translate_axis (tablet->current_device, axis_index,
|
||||
distance, &tablet->axes[axis_index]);
|
||||
@@ -3890,8 +3919,14 @@ tablet_tool_handle_tilt (void *data,
|
||||
{
|
||||
GdkWaylandTabletToolData *tool = data;
|
||||
GdkWaylandTabletData *tablet = tool->current_tablet;
|
||||
gint xtilt_axis_index = tablet->axis_indices[GDK_AXIS_XTILT];
|
||||
gint ytilt_axis_index = tablet->axis_indices[GDK_AXIS_YTILT];
|
||||
gint xtilt_axis_index;
|
||||
gint ytilt_axis_index;
|
||||
|
||||
if (!tablet)
|
||||
return;
|
||||
|
||||
xtilt_axis_index = tablet->axis_indices[GDK_AXIS_XTILT];
|
||||
ytilt_axis_index = tablet->axis_indices[GDK_AXIS_YTILT];
|
||||
|
||||
_gdk_device_translate_axis (tablet->current_device, xtilt_axis_index,
|
||||
wl_fixed_to_double (xtilt),
|
||||
@@ -3918,7 +3953,7 @@ tablet_tool_handle_button (void *data,
|
||||
GdkEventType evtype;
|
||||
guint n_button;
|
||||
|
||||
if (!tablet->pointer_info.focus)
|
||||
if (!tablet || !tablet->pointer_info.focus)
|
||||
return;
|
||||
|
||||
tablet->pointer_info.press_serial = serial;
|
||||
@@ -3949,7 +3984,12 @@ tablet_tool_handle_rotation (void *data,
|
||||
{
|
||||
GdkWaylandTabletToolData *tool = data;
|
||||
GdkWaylandTabletData *tablet = tool->current_tablet;
|
||||
gint axis_index = tablet->axis_indices[GDK_AXIS_ROTATION];
|
||||
gint axis_index;
|
||||
|
||||
if (!tablet)
|
||||
return;
|
||||
|
||||
axis_index = tablet->axis_indices[GDK_AXIS_ROTATION];
|
||||
|
||||
_gdk_device_translate_axis (tablet->current_device, axis_index,
|
||||
wl_fixed_to_double (degrees),
|
||||
@@ -3968,7 +4008,12 @@ tablet_tool_handle_slider (void *data,
|
||||
{
|
||||
GdkWaylandTabletToolData *tool = data;
|
||||
GdkWaylandTabletData *tablet = tool->current_tablet;
|
||||
gint axis_index = tablet->axis_indices[GDK_AXIS_SLIDER];
|
||||
gint axis_index;
|
||||
|
||||
if (!tablet)
|
||||
return;
|
||||
|
||||
axis_index = tablet->axis_indices[GDK_AXIS_SLIDER];
|
||||
|
||||
_gdk_device_translate_axis (tablet->current_device, axis_index,
|
||||
position, &tablet->axes[axis_index]);
|
||||
@@ -3986,9 +4031,12 @@ tablet_tool_handle_wheel (void *data,
|
||||
{
|
||||
GdkWaylandTabletToolData *tool = data;
|
||||
GdkWaylandTabletData *tablet = tool->current_tablet;
|
||||
GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (tablet->seat);
|
||||
GdkWaylandSeat *seat;
|
||||
GdkEvent *event;
|
||||
|
||||
if (!tablet)
|
||||
return;
|
||||
|
||||
GDK_NOTE (EVENTS,
|
||||
g_message ("tablet tool %d wheel %d/%d",
|
||||
gdk_device_tool_get_tool_type (tool->tool), degrees, clicks));
|
||||
@@ -3996,6 +4044,8 @@ tablet_tool_handle_wheel (void *data,
|
||||
if (clicks == 0)
|
||||
return;
|
||||
|
||||
seat = GDK_WAYLAND_SEAT (tablet->seat);
|
||||
|
||||
/* Send smooth event */
|
||||
event = create_scroll_event (seat, &tablet->pointer_info,
|
||||
tablet->master, tablet->current_device, FALSE);
|
||||
@@ -4021,6 +4071,9 @@ tablet_tool_handle_frame (void *data,
|
||||
GdkWaylandTabletData *tablet = tool->current_tablet;
|
||||
GdkEvent *frame_event;
|
||||
|
||||
if (!tablet)
|
||||
return;
|
||||
|
||||
GDK_NOTE (EVENTS,
|
||||
g_message ("tablet frame, time %d", time));
|
||||
|
||||
@@ -4644,6 +4697,9 @@ pointer_surface_update_scale (GdkDevice *device)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!pointer->pointer_surface_outputs)
|
||||
return;
|
||||
|
||||
scale = 1;
|
||||
for (l = pointer->pointer_surface_outputs; l != NULL; l = l->next)
|
||||
{
|
||||
@@ -4653,6 +4709,8 @@ pointer_surface_update_scale (GdkDevice *device)
|
||||
scale = MAX (scale, output_scale);
|
||||
}
|
||||
|
||||
if (pointer->current_output_scale == scale)
|
||||
return;
|
||||
pointer->current_output_scale = scale;
|
||||
|
||||
if (pointer->cursor)
|
||||
|
||||
@@ -84,7 +84,7 @@
|
||||
|
||||
#define MIN_SYSTEM_BELL_DELAY_MS 20
|
||||
|
||||
#define GTK_SHELL1_VERSION 3
|
||||
#define GTK_SHELL1_VERSION 4
|
||||
|
||||
static void _gdk_wayland_display_load_cursor_theme (GdkWaylandDisplay *display_wayland);
|
||||
|
||||
@@ -124,10 +124,6 @@ xdg_wm_base_ping (void *data,
|
||||
struct xdg_wm_base *xdg_wm_base,
|
||||
uint32_t serial)
|
||||
{
|
||||
GdkWaylandDisplay *display_wayland = data;
|
||||
|
||||
_gdk_wayland_display_update_serial (display_wayland, serial);
|
||||
|
||||
GDK_NOTE (EVENTS,
|
||||
g_message ("ping, shell %p, serial %u\n", xdg_wm_base, serial));
|
||||
|
||||
@@ -434,26 +430,19 @@ gdk_registry_handle_global (void *data,
|
||||
}
|
||||
else if (strcmp (interface, "wl_seat") == 0)
|
||||
{
|
||||
SeatAddedClosure *closure;
|
||||
static const char *required_device_manager_globals[] = {
|
||||
"wl_compositor",
|
||||
"wl_data_device_manager",
|
||||
NULL
|
||||
};
|
||||
|
||||
if (has_required_globals (display_wayland,
|
||||
required_device_manager_globals))
|
||||
_gdk_wayland_display_add_seat (display_wayland, id, version);
|
||||
else
|
||||
{
|
||||
SeatAddedClosure *closure;
|
||||
|
||||
closure = g_new0 (SeatAddedClosure, 1);
|
||||
closure->base.handler = seat_added_closure_run;
|
||||
closure->base.required_globals = required_device_manager_globals;
|
||||
closure->id = id;
|
||||
closure->version = version;
|
||||
postpone_on_globals_closure (display_wayland, &closure->base);
|
||||
}
|
||||
closure = g_new0 (SeatAddedClosure, 1);
|
||||
closure->base.handler = seat_added_closure_run;
|
||||
closure->base.required_globals = required_device_manager_globals;
|
||||
closure->id = id;
|
||||
closure->version = version;
|
||||
postpone_on_globals_closure (display_wayland, &closure->base);
|
||||
}
|
||||
else if (strcmp (interface, "wl_data_device_manager") == 0)
|
||||
{
|
||||
@@ -467,12 +456,12 @@ gdk_registry_handle_global (void *data,
|
||||
display_wayland->subcompositor =
|
||||
wl_registry_bind (display_wayland->wl_registry, id, &wl_subcompositor_interface, 1);
|
||||
}
|
||||
else if (strcmp (interface, "zwp_pointer_gestures_v1") == 0 &&
|
||||
version == GDK_ZWP_POINTER_GESTURES_V1_VERSION)
|
||||
else if (strcmp (interface, "zwp_pointer_gestures_v1") == 0)
|
||||
{
|
||||
display_wayland->pointer_gestures =
|
||||
wl_registry_bind (display_wayland->wl_registry,
|
||||
id, &zwp_pointer_gestures_v1_interface, version);
|
||||
id, &zwp_pointer_gestures_v1_interface,
|
||||
MIN (version, GDK_ZWP_POINTER_GESTURES_V1_VERSION));
|
||||
}
|
||||
else if (strcmp (interface, "gtk_primary_selection_device_manager") == 0)
|
||||
{
|
||||
@@ -533,8 +522,6 @@ gdk_registry_handle_global (void *data,
|
||||
|
||||
g_hash_table_insert (display_wayland->known_globals,
|
||||
GUINT_TO_POINTER (id), g_strdup (interface));
|
||||
|
||||
process_on_globals_closures (display_wayland);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -625,8 +612,13 @@ _gdk_wayland_display_open (const gchar *display_name)
|
||||
|
||||
display_wayland->wl_registry = wl_display_get_registry (display_wayland->wl_display);
|
||||
wl_registry_add_listener (display_wayland->wl_registry, ®istry_listener, display_wayland);
|
||||
if (wl_display_roundtrip (display_wayland->wl_display) < 0)
|
||||
{
|
||||
g_object_unref (display);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
_gdk_wayland_display_async_roundtrip (display_wayland);
|
||||
process_on_globals_closures (display_wayland);
|
||||
|
||||
/* Wait for initializing to complete. This means waiting for all
|
||||
* asynchrounous roundtrips that were triggered during initial roundtrip. */
|
||||
|
||||
@@ -380,15 +380,11 @@ update_xft_settings (GdkScreen *screen)
|
||||
}
|
||||
else
|
||||
{
|
||||
GSettingsSchemaSource *source;
|
||||
GSettingsSchema *schema;
|
||||
TranslationEntry *entry;
|
||||
|
||||
source = g_settings_schema_source_get_default ();
|
||||
schema = g_settings_schema_source_lookup (source,
|
||||
"org.gnome.desktop.interface",
|
||||
FALSE);
|
||||
entry = find_translation_entry_by_schema ("org.gnome.desktop.interface", "font-antialiasing");
|
||||
|
||||
if (schema && g_settings_schema_has_key (schema, "font-antialiasing"))
|
||||
if (entry && entry->valid)
|
||||
{
|
||||
settings = g_hash_table_lookup (screen_wayland->settings,
|
||||
"org.gnome.desktop.interface");
|
||||
@@ -546,19 +542,20 @@ static TranslationEntry translations[] = {
|
||||
{ FALSE, "org.gnome.desktop.privacy", "remember-recent-files", "gtk-recent-files-enabled", G_TYPE_BOOLEAN, { .b = TRUE } },
|
||||
{ FALSE, WM_SETTINGS_SCHEMA, "button-layout", "gtk-decoration-layout", G_TYPE_STRING, { .s = "menu:close" } },
|
||||
{ FALSE, CLASSIC_WM_SETTINGS_SCHEMA, "button-layout", "gtk-decoration-layout", G_TYPE_STRING, { .s = "menu:close" } },
|
||||
{ FALSE, "org.gnome.desktop.interface", "font-antialiasing", "gtk-xft-antialias", G_TYPE_NONE, { .i = 0 } },
|
||||
{ FALSE, "org.gnome.desktop.interface", "font-hinting", "gtk-xft-hinting", G_TYPE_NONE, { .i = 0 } },
|
||||
{ FALSE, "org.gnome.desktop.interface", "font-hinting", "gtk-xft-hintstyle", G_TYPE_NONE, { .i = 0 } },
|
||||
{ FALSE, "org.gnome.desktop.interface", "font-antialiasing", "gtk-xft-antialias", G_TYPE_NONE, { .i = 1 } },
|
||||
{ FALSE, "org.gnome.desktop.interface", "font-hinting", "gtk-xft-hinting", G_TYPE_NONE, { .i = 1 } },
|
||||
{ FALSE, "org.gnome.desktop.interface", "font-hinting", "gtk-xft-hintstyle", G_TYPE_NONE, { .i = 1 } },
|
||||
{ FALSE, "org.gnome.desktop.interface", "font-rgba-order", "gtk-xft-rgba", G_TYPE_NONE, { .i = 0 } },
|
||||
{ FALSE, "org.gnome.settings-daemon.plugins.xsettings", "antialiasing", "gtk-xft-antialias", G_TYPE_NONE, { .i = 0 } },
|
||||
{ FALSE, "org.gnome.settings-daemon.plugins.xsettings", "hinting", "gtk-xft-hinting", G_TYPE_NONE, { .i = 0 } },
|
||||
{ FALSE, "org.gnome.settings-daemon.plugins.xsettings", "hinting", "gtk-xft-hintstyle", G_TYPE_NONE, { .i = 0 } },
|
||||
{ FALSE, "org.gnome.settings-daemon.plugins.xsettings", "antialiasing", "gtk-xft-antialias", G_TYPE_NONE, { .i = 1 } },
|
||||
{ FALSE, "org.gnome.settings-daemon.plugins.xsettings", "hinting", "gtk-xft-hinting", G_TYPE_NONE, { .i = 1 } },
|
||||
{ FALSE, "org.gnome.settings-daemon.plugins.xsettings", "hinting", "gtk-xft-hintstyle", G_TYPE_NONE, { .i = 1 } },
|
||||
{ FALSE, "org.gnome.settings-daemon.plugins.xsettings", "rgba-order", "gtk-xft-rgba", G_TYPE_NONE, { .i = 0 } },
|
||||
{ FALSE, "org.gnome.desktop.interface", "text-scaling-factor", "gtk-xft-dpi" , G_TYPE_NONE, { .i = 0 } },
|
||||
{ FALSE, "org.gnome.desktop.wm.preferences", "action-double-click-titlebar", "gtk-titlebar-double-click", G_TYPE_STRING, { .s = "toggle-maximize" } },
|
||||
{ FALSE, "org.gnome.desktop.wm.preferences", "action-middle-click-titlebar", "gtk-titlebar-middle-click", G_TYPE_STRING, { .s = "none" } },
|
||||
{ FALSE, "org.gnome.desktop.wm.preferences", "action-right-click-titlebar", "gtk-titlebar-right-click", G_TYPE_STRING, { .s = "menu" } },
|
||||
{ FALSE, "org.gnome.desktop.a11y", "always-show-text-caret", "gtk-keynav-use-caret", G_TYPE_BOOLEAN, { .b = FALSE } },
|
||||
{ FALSE, "org.gnome.desktop.a11y.interface", "high-contrast", "high-contrast", G_TYPE_NONE, { .b = FALSE } },
|
||||
{ FALSE, "org.gnome.fontconfig", "serial", "gtk-fontconfig-timestamp", G_TYPE_INT, { .i = 0 } }
|
||||
};
|
||||
|
||||
@@ -606,6 +603,13 @@ find_translation_entry_by_setting (const gchar *setting)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
high_contrast_changed (GdkScreen *screen)
|
||||
{
|
||||
notify_setting (screen, "gtk-theme-name");
|
||||
notify_setting (screen, "gtk-icon-theme-name");
|
||||
}
|
||||
|
||||
static void
|
||||
settings_changed (GSettings *settings,
|
||||
const gchar *key,
|
||||
@@ -619,6 +623,8 @@ settings_changed (GSettings *settings,
|
||||
{
|
||||
if (entry->type != G_TYPE_NONE)
|
||||
notify_setting (screen, entry->setting);
|
||||
else if (strcmp (key, "high-contrast") == 0)
|
||||
high_contrast_changed (screen);
|
||||
else
|
||||
update_xft_settings (screen);
|
||||
}
|
||||
@@ -749,6 +755,14 @@ init_settings (GdkScreen *screen)
|
||||
goto fallback;
|
||||
}
|
||||
|
||||
if (g_variant_n_children (ret) == 0)
|
||||
{
|
||||
g_debug ("Received no portal settings");
|
||||
g_clear_pointer (&ret, g_variant_unref);
|
||||
|
||||
goto fallback;
|
||||
}
|
||||
|
||||
g_variant_get (ret, "(a{sa{sv}})", &iter);
|
||||
|
||||
while (g_variant_iter_loop (iter, "{s@a{sv}}", &schema, &val))
|
||||
@@ -765,6 +779,7 @@ init_settings (GdkScreen *screen)
|
||||
char *a = g_variant_print (v, FALSE);
|
||||
g_debug ("Using portal setting for %s %s: %s\n", schema, key, a);
|
||||
g_free (a);
|
||||
entry->valid = TRUE;
|
||||
apply_portal_setting (entry, v, screen);
|
||||
}
|
||||
else
|
||||
@@ -992,6 +1007,32 @@ set_decoration_layout_from_entry (GdkScreen *screen,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
set_theme_from_entry (GdkScreen *screen,
|
||||
TranslationEntry *entry,
|
||||
GValue *value)
|
||||
{
|
||||
GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (screen);
|
||||
GSettings *settings = NULL;
|
||||
GSettingsSchema *schema = NULL;
|
||||
gboolean hc = FALSE;
|
||||
|
||||
settings = (GSettings *)g_hash_table_lookup (screen_wayland->settings, "org.gnome.desktop.a11y.interface");
|
||||
|
||||
if (settings)
|
||||
g_object_get (settings, "settings-schema", &schema, NULL);
|
||||
|
||||
if (schema && g_settings_schema_has_key (schema, "high-contrast"))
|
||||
hc = g_settings_get_boolean (settings, "high-contrast");
|
||||
|
||||
g_clear_pointer (&schema, g_settings_schema_unref);
|
||||
|
||||
if (hc)
|
||||
g_value_set_static_string (value, "HighContrast");
|
||||
else
|
||||
set_value_from_entry (screen, entry, value);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
set_capability_setting (GdkScreen *screen,
|
||||
GValue *value,
|
||||
@@ -1023,6 +1064,9 @@ gdk_wayland_screen_get_setting (GdkScreen *screen,
|
||||
{
|
||||
if (strcmp (name, "gtk-decoration-layout") == 0)
|
||||
set_decoration_layout_from_entry (screen, entry, value);
|
||||
else if (strcmp (name, "gtk-theme-name") == 0 ||
|
||||
strcmp (name, "gtk-icon-theme-name") == 0)
|
||||
set_theme_from_entry (screen, entry, value);
|
||||
else
|
||||
set_value_from_entry (screen, entry, value);
|
||||
return TRUE;
|
||||
@@ -1633,7 +1677,21 @@ output_handle_geometry (void *data,
|
||||
|
||||
monitor->x = x;
|
||||
monitor->y = y;
|
||||
gdk_monitor_set_physical_size (GDK_MONITOR (monitor), physical_width, physical_height);
|
||||
|
||||
switch (transform)
|
||||
{
|
||||
case WL_OUTPUT_TRANSFORM_90:
|
||||
case WL_OUTPUT_TRANSFORM_270:
|
||||
case WL_OUTPUT_TRANSFORM_FLIPPED_90:
|
||||
case WL_OUTPUT_TRANSFORM_FLIPPED_270:
|
||||
gdk_monitor_set_physical_size (GDK_MONITOR (monitor),
|
||||
physical_height, physical_width);
|
||||
break;
|
||||
default:
|
||||
gdk_monitor_set_physical_size (GDK_MONITOR (monitor),
|
||||
physical_width, physical_height);
|
||||
}
|
||||
|
||||
gdk_monitor_set_subpixel_layout (GDK_MONITOR (monitor), subpixel);
|
||||
gdk_monitor_set_manufacturer (GDK_MONITOR (monitor), make);
|
||||
gdk_monitor_set_model (GDK_MONITOR (monitor), model);
|
||||
|
||||
@@ -100,7 +100,7 @@ struct _GdkWaylandSelection
|
||||
|
||||
/* Source-side data */
|
||||
GPtrArray *stored_selections; /* Array of StoredSelection */
|
||||
GdkAtom current_request_selection;
|
||||
StoredSelection *current_request_selection;
|
||||
GArray *source_targets;
|
||||
GdkAtom requested_target;
|
||||
|
||||
@@ -858,7 +858,12 @@ gdk_wayland_selection_reset_selection (GdkWaylandSelection *wayland_selection,
|
||||
stored_selection = g_ptr_array_index (wayland_selection->stored_selections, i);
|
||||
|
||||
if (stored_selection->selection_atom == selection)
|
||||
g_ptr_array_remove_index_fast (wayland_selection->stored_selections, i);
|
||||
{
|
||||
if (wayland_selection->current_request_selection == stored_selection)
|
||||
wayland_selection->current_request_selection = NULL;
|
||||
|
||||
g_ptr_array_remove_index_fast (wayland_selection->stored_selections, i);
|
||||
}
|
||||
else
|
||||
i++;
|
||||
}
|
||||
@@ -877,21 +882,10 @@ gdk_wayland_selection_store (GdkWindow *window,
|
||||
|
||||
if (type == gdk_atom_intern_static_string ("NULL"))
|
||||
return;
|
||||
if (selection->current_request_selection == GDK_NONE)
|
||||
if (!selection->current_request_selection)
|
||||
return;
|
||||
|
||||
stored_selection =
|
||||
gdk_wayland_selection_find_stored_selection (selection, window,
|
||||
selection->current_request_selection,
|
||||
type);
|
||||
|
||||
if (!stored_selection)
|
||||
{
|
||||
stored_selection = stored_selection_new (selection, window,
|
||||
selection->current_request_selection,
|
||||
type);
|
||||
g_ptr_array_add (selection->stored_selections, stored_selection);
|
||||
}
|
||||
stored_selection = selection->current_request_selection;
|
||||
|
||||
if ((mode == GDK_PROP_MODE_PREPEND ||
|
||||
mode == GDK_PROP_MODE_REPLACE) &&
|
||||
@@ -915,7 +909,7 @@ gdk_wayland_selection_store (GdkWindow *window,
|
||||
}
|
||||
|
||||
/* Handle the next GDK_SELECTION_REQUEST / store, if any */
|
||||
selection->current_request_selection = GDK_NONE;
|
||||
selection->current_request_selection = NULL;
|
||||
gdk_wayland_selection_handle_next_request (selection);
|
||||
}
|
||||
|
||||
@@ -979,7 +973,7 @@ gdk_wayland_selection_handle_next_request (GdkWaylandSelection *wayland_selectio
|
||||
gdk_wayland_selection_emit_request (stored_selection->source,
|
||||
stored_selection->selection_atom,
|
||||
stored_selection->type);
|
||||
wayland_selection->current_request_selection = stored_selection->selection_atom;
|
||||
wayland_selection->current_request_selection = stored_selection;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1023,7 +1017,7 @@ gdk_wayland_selection_request_target (GdkWaylandSelection *wayland_selection,
|
||||
|
||||
write_data = async_write_data_new (stored_selection, fd);
|
||||
|
||||
if (wayland_selection->current_request_selection == GDK_NONE)
|
||||
if (!wayland_selection->current_request_selection)
|
||||
gdk_wayland_selection_handle_next_request (wayland_selection);
|
||||
|
||||
return TRUE;
|
||||
@@ -1435,13 +1429,29 @@ _gdk_wayland_display_set_selection_owner (GdkDisplay *display,
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_wayland_display_send_selection_notify (GdkDisplay *dispay,
|
||||
_gdk_wayland_display_send_selection_notify (GdkDisplay *display,
|
||||
GdkWindow *requestor,
|
||||
GdkAtom selection,
|
||||
GdkAtom target,
|
||||
GdkAtom property,
|
||||
guint32 time)
|
||||
{
|
||||
GdkWaylandSelection *wayland_selection;
|
||||
|
||||
if (property != GDK_NONE)
|
||||
return;
|
||||
|
||||
wayland_selection = gdk_wayland_display_get_selection (display);
|
||||
|
||||
if (!wayland_selection->current_request_selection)
|
||||
return;
|
||||
|
||||
g_ptr_array_remove_fast (wayland_selection->stored_selections,
|
||||
wayland_selection->current_request_selection);
|
||||
|
||||
/* Handle the next GDK_SELECTION_REQUEST / store, if any */
|
||||
wayland_selection->current_request_selection = NULL;
|
||||
gdk_wayland_selection_handle_next_request (wayland_selection);
|
||||
}
|
||||
|
||||
gint
|
||||
|
||||
@@ -87,6 +87,14 @@ void gdk_wayland_window_announce_csd (GdkWindow *window);
|
||||
GDK_AVAILABLE_IN_3_24
|
||||
void gdk_wayland_window_announce_ssd (GdkWindow *window);
|
||||
|
||||
GDK_AVAILABLE_IN_3_24
|
||||
void gdk_wayland_window_add_frame_callback_surface (GdkWindow *window,
|
||||
struct wl_surface *surface);
|
||||
|
||||
GDK_AVAILABLE_IN_3_24
|
||||
void gdk_wayland_window_remove_frame_callback_surface (GdkWindow *window,
|
||||
struct wl_surface *surface);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_WAYLAND_WINDOW_H__ */
|
||||
|
||||
@@ -236,6 +236,9 @@ struct _GdkWindowImplWayland
|
||||
|
||||
struct zxdg_imported_v1 *imported_transient_for;
|
||||
GHashTable *shortcuts_inhibitors;
|
||||
|
||||
struct wl_callback *surface_callback;
|
||||
GHashTable *frame_callback_surfaces;
|
||||
};
|
||||
|
||||
struct _GdkWindowImplWaylandClass
|
||||
@@ -572,9 +575,25 @@ frame_callback (void *data,
|
||||
GdkFrameClock *clock = gdk_window_get_frame_clock (window);
|
||||
GdkFrameTimings *timings;
|
||||
|
||||
GDK_NOTE (EVENTS,
|
||||
g_message ("frame %p", window));
|
||||
if (callback == impl->surface_callback)
|
||||
{
|
||||
impl->surface_callback = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
GHashTableIter iter;
|
||||
gpointer surface_callback;
|
||||
|
||||
g_hash_table_iter_init (&iter, impl->frame_callback_surfaces);
|
||||
while (g_hash_table_iter_next (&iter, NULL, &surface_callback))
|
||||
{
|
||||
if (callback == surface_callback)
|
||||
{
|
||||
g_hash_table_iter_replace (&iter, NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
wl_callback_destroy (callback);
|
||||
|
||||
if (GDK_WINDOW_DESTROYED (window))
|
||||
@@ -583,6 +602,9 @@ frame_callback (void *data,
|
||||
if (!impl->awaiting_frame)
|
||||
return;
|
||||
|
||||
GDK_NOTE (EVENTS,
|
||||
g_message ("frame %p", window));
|
||||
|
||||
impl->awaiting_frame = FALSE;
|
||||
_gdk_frame_clock_thaw (clock);
|
||||
|
||||
@@ -660,6 +682,8 @@ on_frame_clock_after_paint (GdkFrameClock *clock,
|
||||
{
|
||||
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
|
||||
struct wl_callback *callback;
|
||||
GHashTableIter iter;
|
||||
gpointer surface, surface_callback;
|
||||
|
||||
if (!impl->pending_commit)
|
||||
return;
|
||||
@@ -667,8 +691,6 @@ on_frame_clock_after_paint (GdkFrameClock *clock,
|
||||
if (window->update_freeze_count > 0)
|
||||
return;
|
||||
|
||||
callback = wl_surface_frame (impl->display_server.wl_surface);
|
||||
wl_callback_add_listener (callback, &frame_listener, window);
|
||||
_gdk_frame_clock_freeze (clock);
|
||||
|
||||
/* Before we commit a new buffer, make sure we've backfilled
|
||||
@@ -677,6 +699,24 @@ on_frame_clock_after_paint (GdkFrameClock *clock,
|
||||
if (impl->pending_buffer_attached)
|
||||
read_back_cairo_surface (window);
|
||||
|
||||
if (impl->surface_callback == NULL)
|
||||
{
|
||||
callback = wl_surface_frame (impl->display_server.wl_surface);
|
||||
wl_callback_add_listener (callback, &frame_listener, window);
|
||||
impl->surface_callback = callback;
|
||||
}
|
||||
|
||||
g_hash_table_iter_init (&iter, impl->frame_callback_surfaces);
|
||||
while (g_hash_table_iter_next (&iter, &surface, &surface_callback))
|
||||
{
|
||||
if (surface_callback)
|
||||
continue;
|
||||
|
||||
callback = wl_surface_frame (surface);
|
||||
wl_callback_add_listener (callback, &frame_listener, window);
|
||||
g_hash_table_iter_replace (&iter, callback);
|
||||
}
|
||||
|
||||
/* From this commit forward, we can't write to the buffer,
|
||||
* it's "live". In the future, if we need to stage more changes
|
||||
* we have to allocate a new staging buffer and draw to it instead.
|
||||
@@ -756,6 +796,8 @@ _gdk_wayland_display_create_window_impl (GdkDisplay *display,
|
||||
impl->wrapper = GDK_WINDOW (window);
|
||||
impl->shortcuts_inhibitors = g_hash_table_new (NULL, NULL);
|
||||
impl->using_csd = TRUE;
|
||||
impl->surface_callback = NULL;
|
||||
impl->frame_callback_surfaces = g_hash_table_new (NULL, NULL);
|
||||
|
||||
if (window->width > 65535)
|
||||
{
|
||||
@@ -1067,6 +1109,7 @@ gdk_window_impl_wayland_finalize (GObject *object)
|
||||
g_clear_pointer (&impl->staged_updates_region, cairo_region_destroy);
|
||||
|
||||
g_clear_pointer (&impl->shortcuts_inhibitors, g_hash_table_unref);
|
||||
g_clear_pointer (&impl->frame_callback_surfaces, g_hash_table_unref);
|
||||
|
||||
G_OBJECT_CLASS (_gdk_window_impl_wayland_parent_class)->finalize (object);
|
||||
}
|
||||
@@ -1156,6 +1199,7 @@ gdk_wayland_window_maybe_configure (GdkWindow *window,
|
||||
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
|
||||
gboolean is_xdg_popup;
|
||||
gboolean is_visible;
|
||||
gboolean size_changed;
|
||||
|
||||
impl->unconfigured_width = calculate_width_without_margin (window, width);
|
||||
impl->unconfigured_height = calculate_height_without_margin (window, height);
|
||||
@@ -1163,9 +1207,8 @@ gdk_wayland_window_maybe_configure (GdkWindow *window,
|
||||
if (should_inhibit_resize (window))
|
||||
return;
|
||||
|
||||
if (window->width == width &&
|
||||
window->height == height &&
|
||||
impl->scale == scale)
|
||||
size_changed = (window->width != width || window->height != height);
|
||||
if (!size_changed && impl->scale == scale)
|
||||
return;
|
||||
|
||||
/* For xdg_popup using an xdg_positioner, there is a race condition if
|
||||
@@ -1179,6 +1222,7 @@ gdk_wayland_window_maybe_configure (GdkWindow *window,
|
||||
|
||||
if (is_xdg_popup &&
|
||||
is_visible &&
|
||||
size_changed &&
|
||||
!impl->initial_configure_received &&
|
||||
!impl->configuring_popup)
|
||||
gdk_window_hide (window);
|
||||
@@ -1187,6 +1231,7 @@ gdk_wayland_window_maybe_configure (GdkWindow *window,
|
||||
|
||||
if (is_xdg_popup &&
|
||||
is_visible &&
|
||||
size_changed &&
|
||||
!impl->initial_configure_received &&
|
||||
!impl->configuring_popup)
|
||||
gdk_window_show (window);
|
||||
@@ -1349,6 +1394,9 @@ gdk_wayland_window_sync_margin (GdkWindow *window)
|
||||
return;
|
||||
|
||||
gdk_wayland_window_get_window_geometry (window, &geometry);
|
||||
|
||||
g_return_if_fail (geometry.width > 0 && geometry.height > 0);
|
||||
|
||||
gdk_window_set_geometry_hints (window,
|
||||
&impl->geometry_hints,
|
||||
impl->geometry_mask);
|
||||
@@ -1474,6 +1522,14 @@ surface_enter (void *data,
|
||||
{
|
||||
GdkWindow *window = GDK_WINDOW (data);
|
||||
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
|
||||
GdkWaylandDisplay *display_wayland =
|
||||
GDK_WAYLAND_DISPLAY (gdk_window_get_display (window));
|
||||
gboolean output_is_unmanaged;
|
||||
|
||||
output_is_unmanaged =
|
||||
_gdk_wayland_screen_get_output_scale (display_wayland->screen, output) == 0;
|
||||
if (output_is_unmanaged)
|
||||
return;
|
||||
|
||||
GDK_NOTE (EVENTS,
|
||||
g_message ("surface enter, window %p output %p", window, output));
|
||||
@@ -3284,6 +3340,12 @@ gdk_wayland_window_hide_surface (GdkWindow *window)
|
||||
impl->display_server.xdg_popup = NULL;
|
||||
display_wayland->current_popups =
|
||||
g_list_remove (display_wayland->current_popups, window);
|
||||
|
||||
if (impl->position_method == POSITION_METHOD_MOVE_TO_RECT)
|
||||
{
|
||||
window->x = 0;
|
||||
window->y = 0;
|
||||
}
|
||||
}
|
||||
if (impl->display_server.xdg_surface)
|
||||
{
|
||||
@@ -3306,6 +3368,12 @@ gdk_wayland_window_hide_surface (GdkWindow *window)
|
||||
impl->display_server.zxdg_popup_v6 = NULL;
|
||||
display_wayland->current_popups =
|
||||
g_list_remove (display_wayland->current_popups, window);
|
||||
|
||||
if (impl->position_method == POSITION_METHOD_MOVE_TO_RECT)
|
||||
{
|
||||
window->x = 0;
|
||||
window->y = 0;
|
||||
}
|
||||
}
|
||||
if (impl->display_server.zxdg_surface_v6)
|
||||
{
|
||||
@@ -3332,7 +3400,11 @@ gdk_wayland_window_hide_surface (GdkWindow *window)
|
||||
|
||||
if (impl->display_server.gtk_surface)
|
||||
{
|
||||
gtk_surface1_destroy (impl->display_server.gtk_surface);
|
||||
if (display_wayland->gtk_shell_version >=
|
||||
GTK_SURFACE1_RELEASE_SINCE_VERSION)
|
||||
gtk_surface1_release (impl->display_server.gtk_surface);
|
||||
else
|
||||
gtk_surface1_destroy (impl->display_server.gtk_surface);
|
||||
impl->display_server.gtk_surface = NULL;
|
||||
impl->application.was_set = FALSE;
|
||||
}
|
||||
@@ -3345,6 +3417,7 @@ gdk_wayland_window_hide_surface (GdkWindow *window)
|
||||
|
||||
wl_surface_destroy (impl->display_server.wl_surface);
|
||||
impl->display_server.wl_surface = NULL;
|
||||
impl->surface_callback = NULL;
|
||||
|
||||
g_slist_free (impl->display_server.outputs);
|
||||
impl->display_server.outputs = NULL;
|
||||
@@ -5390,3 +5463,71 @@ gdk_wayland_window_restore_shortcuts (GdkWindow *window,
|
||||
g_hash_table_remove (impl->shortcuts_inhibitors, seat);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_wayland_window_add_frame_callback_surface:
|
||||
* @window: the #GdkWindow requesting callbacks
|
||||
* @surface: the wl_surface to add
|
||||
*
|
||||
* Add @surface to a list of surfaces for which frame callback
|
||||
* listeners will get set up, additionally to the one of @window.
|
||||
*
|
||||
* This is useful when clients use subsurfaces independently of GDK.
|
||||
* For example if a client creates a subsurface that covers @window
|
||||
* entirely. If this subsurface is opaque, Wayland compositors may not
|
||||
* emit callbacks for the surface of @window any more.
|
||||
* Adding the covering subsurface via this function ensures the
|
||||
* @window will continue to update.
|
||||
*
|
||||
* A single callback is sufficient to trigger the next update. If more
|
||||
* than one are triggered, the later ones will get ignored.
|
||||
*
|
||||
* Before @surface gets destroyed it must get removed again using
|
||||
* gdk_wayland_window_remove_frame_callback_surface().
|
||||
*
|
||||
* Note that the client is responsible to commit the @surface.
|
||||
* One way to archive this is to always commit after the
|
||||
* #GdkSurface::after-paint signal was triggered.
|
||||
*
|
||||
* Since: 3.24.25
|
||||
*/
|
||||
void
|
||||
gdk_wayland_window_add_frame_callback_surface (GdkWindow *window,
|
||||
struct wl_surface *surface)
|
||||
{
|
||||
GdkWindowImplWayland *impl;
|
||||
|
||||
g_return_if_fail (GDK_IS_WAYLAND_WINDOW (window));
|
||||
g_return_if_fail (GDK_IS_WINDOW_IMPL_WAYLAND (window->impl));
|
||||
g_return_if_fail (surface != NULL);
|
||||
|
||||
impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
|
||||
|
||||
g_hash_table_insert (impl->frame_callback_surfaces, surface, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_wayland_window_remove_frame_callback_surface:
|
||||
* @window: the #GdkWindow requesting callbacks
|
||||
* @surface: the surface to remove
|
||||
*
|
||||
* Remove @surface from the list of surfaces again that got added via
|
||||
* gdk_wayland_window_add_frame_callback_surface().
|
||||
*
|
||||
* This function must be called before @surface gets destroyed.
|
||||
*
|
||||
* Since: 3.24.25
|
||||
*/
|
||||
void
|
||||
gdk_wayland_window_remove_frame_callback_surface (GdkWindow *window,
|
||||
struct wl_surface *surface)
|
||||
{
|
||||
GdkWindowImplWayland *impl;
|
||||
|
||||
g_return_if_fail (GDK_IS_WAYLAND_WINDOW (window));
|
||||
g_return_if_fail (GDK_IS_WINDOW_IMPL_WAYLAND (window->impl));
|
||||
g_return_if_fail (surface != NULL);
|
||||
|
||||
impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
|
||||
|
||||
g_hash_table_remove (impl->frame_callback_surfaces, surface);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<protocol name="gtk">
|
||||
|
||||
<interface name="gtk_shell1" version="3">
|
||||
<interface name="gtk_shell1" version="4">
|
||||
<description summary="gtk specific extensions">
|
||||
gtk_shell is a protocol extension providing additional features for
|
||||
clients implementing it.
|
||||
@@ -35,7 +35,7 @@
|
||||
</request>
|
||||
</interface>
|
||||
|
||||
<interface name="gtk_surface1" version="3">
|
||||
<interface name="gtk_surface1" version="4">
|
||||
<request name="set_dbus_properties">
|
||||
<arg name="application_id" type="string" allow-null="true"/>
|
||||
<arg name="app_menu_path" type="string" allow-null="true"/>
|
||||
@@ -82,6 +82,9 @@
|
||||
<request name="request_focus" since="3">
|
||||
<arg name="startup_id" type="string" allow-null="true"/>
|
||||
</request>
|
||||
|
||||
<!-- Version 4 additions -->
|
||||
<request name="release" type="destructor" since="4"/>
|
||||
</interface>
|
||||
|
||||
</protocol>
|
||||
|
||||
+14
-1
@@ -21,7 +21,10 @@ if WIN32_GLES
|
||||
AM_CPPFLAGS += "-DGDK_WIN32_ENABLE_EGL=1"
|
||||
endif #WIN32_GLES
|
||||
|
||||
LDADDS = $(GDK_DEP_LIBS)
|
||||
libgdk_win32_DEP_LIBS = \
|
||||
-lhid
|
||||
|
||||
LDADDS = $(libgdk_win32_DEP_LIBS) $(GDK_DEP_LIBS)
|
||||
|
||||
noinst_LTLIBRARIES = libgdk-win32.la
|
||||
|
||||
@@ -40,6 +43,8 @@ libgdk_win32_la_SOURCES = \
|
||||
gdkdevice-virtual.h \
|
||||
gdkdevice-win32.c \
|
||||
gdkdevice-win32.h \
|
||||
gdkdevice-winpointer.c \
|
||||
gdkdevice-winpointer.h \
|
||||
gdkdevice-wintab.c \
|
||||
gdkdevice-wintab.h \
|
||||
gdkdisplay-win32.c \
|
||||
@@ -52,6 +57,9 @@ libgdk_win32_la_SOURCES = \
|
||||
gdkglcontext-win32.h \
|
||||
gdkglobals-win32.c \
|
||||
gdkkeys-win32.c \
|
||||
gdkkeys-win32.h \
|
||||
gdkkeys-win32-impl.c \
|
||||
gdkkeys-win32-impl-wow64.c \
|
||||
gdkmain-win32.c \
|
||||
gdkmonitor-win32.c \
|
||||
gdkmonitor-win32.h \
|
||||
@@ -78,9 +86,14 @@ libgdk_win32_la_SOURCES = \
|
||||
gdkwindow-win32.c \
|
||||
gdkwindow-win32.h \
|
||||
pktdef.h \
|
||||
winpointer.h \
|
||||
wintab.h \
|
||||
xcursors.h
|
||||
|
||||
libgdk_win32_la_LIBADD = \
|
||||
$(LDADDS) \
|
||||
$(NULL)
|
||||
|
||||
libgdkinclude_HEADERS = \
|
||||
gdkwin32.h
|
||||
|
||||
|
||||
+54
-72
@@ -117,40 +117,47 @@ gdk_device_win32_query_state (GdkDevice *device,
|
||||
impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
|
||||
|
||||
hwnd = GDK_WINDOW_HWND (window);
|
||||
GetCursorPos (&point);
|
||||
_gdk_win32_get_cursor_pos (&point);
|
||||
|
||||
if (root_x)
|
||||
*root_x = point.x / impl->window_scale;
|
||||
*root_x = (point.x + _gdk_offset_x) / impl->window_scale;
|
||||
|
||||
if (root_y)
|
||||
*root_y = point.y / impl->window_scale;
|
||||
|
||||
ScreenToClient (hwnd, &point);
|
||||
|
||||
if (win_x)
|
||||
*win_x = point.x / impl->window_scale;
|
||||
|
||||
if (win_y)
|
||||
*win_y = point.y / impl->window_scale;
|
||||
*root_y = (point.y + _gdk_offset_y) / impl->window_scale;
|
||||
|
||||
if (window == gdk_screen_get_root_window (screen))
|
||||
{
|
||||
if (win_x)
|
||||
*win_x += _gdk_offset_x;
|
||||
*win_x = (point.x + _gdk_offset_x) / impl->window_scale;
|
||||
|
||||
if (win_y)
|
||||
*win_y += _gdk_offset_y;
|
||||
*win_y = (point.y + _gdk_offset_y) / impl->window_scale;
|
||||
}
|
||||
else
|
||||
{
|
||||
ScreenToClient (hwnd, &point);
|
||||
|
||||
if (root_x)
|
||||
*root_x += _gdk_offset_x;
|
||||
if (win_x)
|
||||
*win_x = point.x / impl->window_scale;
|
||||
|
||||
if (root_y)
|
||||
*root_y += _gdk_offset_y;
|
||||
if (win_y)
|
||||
*win_y = point.y / impl->window_scale;
|
||||
}
|
||||
|
||||
if (child_window)
|
||||
{
|
||||
hwndc = ChildWindowFromPoint (hwnd, point);
|
||||
if (window == gdk_screen_get_root_window (screen))
|
||||
{
|
||||
/* Always use WindowFromPoint when searching from the root window.
|
||||
* Only WindowFromPoint is able to look through transparent
|
||||
* layered windows.
|
||||
*/
|
||||
hwndc = GetAncestor (WindowFromPoint (point), GA_ROOT);
|
||||
}
|
||||
else
|
||||
{
|
||||
hwndc = ChildWindowFromPoint (hwnd, point);
|
||||
}
|
||||
|
||||
if (hwndc && hwndc != hwnd)
|
||||
*child_window = gdk_win32_handle_table_lookup (hwndc);
|
||||
@@ -201,71 +208,46 @@ _gdk_device_win32_window_at_position (GdkDevice *device,
|
||||
GdkWindow *window = NULL;
|
||||
GdkWindowImplWin32 *impl = NULL;
|
||||
POINT screen_pt, client_pt;
|
||||
HWND hwnd, hwndc;
|
||||
HWND hwnd;
|
||||
RECT rect;
|
||||
|
||||
GetCursorPos (&screen_pt);
|
||||
if (!_gdk_win32_get_cursor_pos (&screen_pt))
|
||||
return NULL;
|
||||
|
||||
hwnd = WindowFromPoint (screen_pt);
|
||||
|
||||
if (get_toplevel)
|
||||
{
|
||||
/* Only consider visible children of the desktop to avoid the various
|
||||
* non-visible windows you often find on a running Windows box. These
|
||||
* might overlap our windows and cause our walk to fail. As we assume
|
||||
* WindowFromPoint() can find our windows, we follow similar logic
|
||||
* here, and ignore invisible and disabled windows.
|
||||
*/
|
||||
hwnd = GetDesktopWindow ();
|
||||
do {
|
||||
window = gdk_win32_handle_table_lookup (hwnd);
|
||||
|
||||
if (window != NULL &&
|
||||
GDK_WINDOW_TYPE (window) != GDK_WINDOW_ROOT &&
|
||||
GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN)
|
||||
break;
|
||||
|
||||
screen_to_client (hwnd, screen_pt, &client_pt);
|
||||
hwndc = ChildWindowFromPointEx (hwnd, client_pt, CWP_SKIPDISABLED |
|
||||
CWP_SKIPINVISIBLE);
|
||||
|
||||
/* Verify that we're really inside the client area of the window */
|
||||
if (hwndc != hwnd)
|
||||
{
|
||||
GetClientRect (hwndc, &rect);
|
||||
screen_to_client (hwndc, screen_pt, &client_pt);
|
||||
if (!PtInRect (&rect, client_pt))
|
||||
hwndc = hwnd;
|
||||
}
|
||||
|
||||
} while (hwndc != hwnd && (hwnd = hwndc, 1));
|
||||
|
||||
/* Use WindowFromPoint instead of ChildWindowFromPoint(Ex).
|
||||
* Only WindowFromPoint is able to look through transparent
|
||||
* layered windows.
|
||||
*/
|
||||
hwnd = GetAncestor (hwnd, GA_ROOT);
|
||||
}
|
||||
else
|
||||
|
||||
/* Verify that we're really inside the client area of the window */
|
||||
GetClientRect (hwnd, &rect);
|
||||
screen_to_client (hwnd, screen_pt, &client_pt);
|
||||
if (!PtInRect (&rect, client_pt))
|
||||
hwnd = NULL;
|
||||
|
||||
if (!get_toplevel && hwnd == NULL)
|
||||
{
|
||||
hwnd = WindowFromPoint (screen_pt);
|
||||
/* If we didn't hit any window, return the root window */
|
||||
/* note that the root window ain't a toplevel window */
|
||||
window = gdk_get_default_root_window ();
|
||||
impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
|
||||
|
||||
/* Verify that we're really inside the client area of the window */
|
||||
GetClientRect (hwnd, &rect);
|
||||
screen_to_client (hwnd, screen_pt, &client_pt);
|
||||
if (!PtInRect (&rect, client_pt))
|
||||
hwnd = NULL;
|
||||
if (win_x)
|
||||
*win_x = (screen_pt.x + _gdk_offset_x) / impl->window_scale;
|
||||
if (win_y)
|
||||
*win_y = (screen_pt.y + _gdk_offset_y) / impl->window_scale;
|
||||
|
||||
/* If we didn't hit any window at that point, return the desktop */
|
||||
if (hwnd == NULL)
|
||||
{
|
||||
window = gdk_get_default_root_window ();
|
||||
impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
|
||||
|
||||
if (win_x)
|
||||
*win_x = (screen_pt.x + _gdk_offset_x) / impl->window_scale;
|
||||
if (win_y)
|
||||
*win_y = (screen_pt.y + _gdk_offset_y) / impl->window_scale;
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
window = gdk_win32_handle_table_lookup (hwnd);
|
||||
return window;
|
||||
}
|
||||
|
||||
window = gdk_win32_handle_table_lookup (hwnd);
|
||||
|
||||
if (window && (win_x || win_y))
|
||||
{
|
||||
impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
|
||||
|
||||
@@ -0,0 +1,317 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2020 the GTK team
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <gdk/gdkwindow.h>
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include "gdkwin32.h"
|
||||
#include "gdkdevice-winpointer.h"
|
||||
|
||||
G_DEFINE_TYPE (GdkDeviceWinpointer, gdk_device_winpointer, GDK_TYPE_DEVICE)
|
||||
|
||||
static GdkModifierType
|
||||
get_keyboard_mask (void)
|
||||
{
|
||||
GdkModifierType mask;
|
||||
BYTE kbd[256];
|
||||
|
||||
GetKeyboardState (kbd);
|
||||
mask = 0;
|
||||
if (kbd[VK_SHIFT] & 0x80)
|
||||
mask |= GDK_SHIFT_MASK;
|
||||
if (kbd[VK_CAPITAL] & 0x80)
|
||||
mask |= GDK_LOCK_MASK;
|
||||
if (kbd[VK_CONTROL] & 0x80)
|
||||
mask |= GDK_CONTROL_MASK;
|
||||
if (kbd[VK_MENU] & 0x80)
|
||||
mask |= GDK_MOD1_MASK;
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_device_winpointer_get_history (GdkDevice *device,
|
||||
GdkWindow *window,
|
||||
guint32 start,
|
||||
guint32 stop,
|
||||
GdkTimeCoord ***events,
|
||||
gint *n_events)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_device_winpointer_get_state (GdkDevice *device,
|
||||
GdkWindow *window,
|
||||
gdouble *axes,
|
||||
GdkModifierType *mask)
|
||||
{
|
||||
GdkDeviceWinpointer *device_winpointer = GDK_DEVICE_WINPOINTER (device);
|
||||
|
||||
if (mask)
|
||||
{
|
||||
*mask = get_keyboard_mask ();
|
||||
*mask |= device_winpointer->last_button_mask;
|
||||
}
|
||||
|
||||
if (axes)
|
||||
{
|
||||
gsize size = sizeof (double) * device_winpointer->num_axes;
|
||||
memcpy (axes, device_winpointer->last_axis_data, size);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_device_winpointer_set_window_cursor (GdkDevice *device,
|
||||
GdkWindow *window,
|
||||
GdkCursor *cursor)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_device_winpointer_warp (GdkDevice *device,
|
||||
GdkScreen *screen,
|
||||
gdouble x,
|
||||
gdouble y)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_device_winpointer_query_state (GdkDevice *device,
|
||||
GdkWindow *window,
|
||||
GdkWindow **root_window,
|
||||
GdkWindow **child_window,
|
||||
gdouble *root_x,
|
||||
gdouble *root_y,
|
||||
gdouble *win_x,
|
||||
gdouble *win_y,
|
||||
GdkModifierType *mask)
|
||||
{
|
||||
GdkDeviceWinpointer *device_winpointer = GDK_DEVICE_WINPOINTER (device);
|
||||
GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
|
||||
GdkScreen *screen = gdk_window_get_screen (window);
|
||||
HWND hwnd = GDK_WINDOW_HWND (window);
|
||||
HWND hwndc = NULL;
|
||||
POINT point;
|
||||
|
||||
_gdk_win32_get_cursor_pos (&point);
|
||||
|
||||
if (root_x)
|
||||
*root_x = (point.x + _gdk_offset_x) / impl->window_scale;
|
||||
|
||||
if (root_y)
|
||||
*root_y = (point.y + _gdk_offset_y) / impl->window_scale;
|
||||
|
||||
if (window == gdk_screen_get_root_window (screen))
|
||||
{
|
||||
if (win_x)
|
||||
*win_x = (point.x + _gdk_offset_x) / impl->window_scale;
|
||||
|
||||
if (win_y)
|
||||
*win_y = (point.y + _gdk_offset_y) / impl->window_scale;
|
||||
}
|
||||
else
|
||||
{
|
||||
ScreenToClient (hwnd, &point);
|
||||
|
||||
if (win_x)
|
||||
*win_x = point.x / impl->window_scale;
|
||||
|
||||
if (win_y)
|
||||
*win_y = point.y / impl->window_scale;
|
||||
}
|
||||
|
||||
if (child_window)
|
||||
{
|
||||
if (window == gdk_screen_get_root_window (screen))
|
||||
{
|
||||
/* Always use WindowFromPoint when searching from the root window.
|
||||
* Only WindowFromPoint is able to look through transparent
|
||||
* layered windows.
|
||||
*/
|
||||
hwndc = GetAncestor (WindowFromPoint (point), GA_ROOT);
|
||||
}
|
||||
else
|
||||
{
|
||||
hwndc = ChildWindowFromPoint (hwnd, point);
|
||||
}
|
||||
|
||||
if (hwndc && hwndc != hwnd)
|
||||
*child_window = gdk_win32_handle_table_lookup (hwndc);
|
||||
else
|
||||
*child_window = NULL; /* Direct child unknown to gdk */
|
||||
}
|
||||
|
||||
if (root_window)
|
||||
*root_window = gdk_screen_get_root_window (screen);
|
||||
|
||||
if (mask)
|
||||
{
|
||||
*mask = get_keyboard_mask ();
|
||||
*mask |= device_winpointer->last_button_mask;
|
||||
}
|
||||
}
|
||||
|
||||
static GdkGrabStatus
|
||||
gdk_device_winpointer_grab (GdkDevice *device,
|
||||
GdkWindow *window,
|
||||
gboolean owner_events,
|
||||
GdkEventMask event_mask,
|
||||
GdkWindow *confine_to,
|
||||
GdkCursor *cursor,
|
||||
guint32 time_)
|
||||
{
|
||||
return GDK_GRAB_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_device_winpointer_ungrab (GdkDevice *device,
|
||||
guint32 time_)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
screen_to_client (HWND hwnd, POINT screen_pt, POINT *client_pt)
|
||||
{
|
||||
*client_pt = screen_pt;
|
||||
ScreenToClient (hwnd, client_pt);
|
||||
}
|
||||
|
||||
GdkWindow *
|
||||
_gdk_device_winpointer_window_at_position (GdkDevice *device,
|
||||
gdouble *win_x,
|
||||
gdouble *win_y,
|
||||
GdkModifierType *mask,
|
||||
gboolean get_toplevel)
|
||||
{
|
||||
GdkDeviceWinpointer *device_winpointer = GDK_DEVICE_WINPOINTER (device);
|
||||
GdkWindow *window = NULL;
|
||||
GdkWindowImplWin32 *impl = NULL;
|
||||
POINT screen_pt, client_pt;
|
||||
HWND hwnd;
|
||||
RECT rect;
|
||||
|
||||
if (!_gdk_win32_get_cursor_pos (&screen_pt))
|
||||
return NULL;
|
||||
|
||||
hwnd = WindowFromPoint (screen_pt);
|
||||
|
||||
if (get_toplevel)
|
||||
{
|
||||
/* Use WindowFromPoint instead of ChildWindowFromPoint(Ex).
|
||||
* Only WindowFromPoint is able to look through transparent
|
||||
* layered windows.
|
||||
*/
|
||||
hwnd = GetAncestor (hwnd, GA_ROOT);
|
||||
}
|
||||
|
||||
/* Verify that we're really inside the client area of the window */
|
||||
GetClientRect (hwnd, &rect);
|
||||
screen_to_client (hwnd, screen_pt, &client_pt);
|
||||
if (!PtInRect (&rect, client_pt))
|
||||
hwnd = NULL;
|
||||
|
||||
if (!get_toplevel && hwnd == NULL)
|
||||
{
|
||||
/* If we didn't hit any window, return the root window */
|
||||
/* note that the root window ain't a toplevel window */
|
||||
window = gdk_get_default_root_window ();
|
||||
impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
|
||||
|
||||
if (win_x)
|
||||
*win_x = (screen_pt.x + _gdk_offset_x) / impl->window_scale;
|
||||
if (win_y)
|
||||
*win_y = (screen_pt.y + _gdk_offset_y) / impl->window_scale;
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
window = gdk_win32_handle_table_lookup (hwnd);
|
||||
|
||||
if (window && (win_x || win_y))
|
||||
{
|
||||
impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
|
||||
|
||||
if (win_x)
|
||||
*win_x = client_pt.x / impl->window_scale;
|
||||
if (win_y)
|
||||
*win_y = client_pt.y / impl->window_scale;
|
||||
}
|
||||
|
||||
if (mask)
|
||||
{
|
||||
*mask = get_keyboard_mask ();
|
||||
*mask |= device_winpointer->last_button_mask;
|
||||
}
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_device_winpointer_select_window_events (GdkDevice *device,
|
||||
GdkWindow *window,
|
||||
GdkEventMask event_mask)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_device_winpointer_init (GdkDeviceWinpointer *device_winpointer)
|
||||
{
|
||||
device_winpointer->device_handle = NULL;
|
||||
device_winpointer->start_cursor_id = 0;
|
||||
device_winpointer->end_cursor_id = 0;
|
||||
|
||||
device_winpointer->origin_x = 0;
|
||||
device_winpointer->origin_y = 0;
|
||||
device_winpointer->scale_x = 0.0;
|
||||
device_winpointer->scale_y = 0.0;
|
||||
|
||||
device_winpointer->last_axis_data = NULL;
|
||||
device_winpointer->num_axes = 0;
|
||||
device_winpointer->last_button_mask = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_device_winpointer_finalize (GObject *object)
|
||||
{
|
||||
GdkDeviceWinpointer *device_winpointer = GDK_DEVICE_WINPOINTER (object);
|
||||
|
||||
g_free (device_winpointer->last_axis_data);
|
||||
|
||||
G_OBJECT_CLASS (gdk_device_winpointer_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_device_winpointer_class_init (GdkDeviceWinpointerClass *klass)
|
||||
{
|
||||
GdkDeviceClass *device_class = GDK_DEVICE_CLASS (klass);
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->finalize = gdk_device_winpointer_finalize;
|
||||
device_class->get_history = gdk_device_winpointer_get_history;
|
||||
device_class->get_state = gdk_device_winpointer_get_state;
|
||||
device_class->set_window_cursor = gdk_device_winpointer_set_window_cursor;
|
||||
device_class->warp = gdk_device_winpointer_warp;
|
||||
device_class->query_state = gdk_device_winpointer_query_state;
|
||||
device_class->grab = gdk_device_winpointer_grab;
|
||||
device_class->ungrab = gdk_device_winpointer_ungrab;
|
||||
device_class->window_at_position = _gdk_device_winpointer_window_at_position;
|
||||
device_class->select_window_events = gdk_device_winpointer_select_window_events;
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2020 the GTK team
|
||||
*
|
||||
* 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_DEVICE_WINPOINTER_H__
|
||||
#define __GDK_DEVICE_WINPOINTER_H__
|
||||
|
||||
#include <gdk/gdkdeviceprivate.h>
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GDK_TYPE_DEVICE_WINPOINTER (gdk_device_winpointer_get_type ())
|
||||
#define GDK_DEVICE_WINPOINTER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDK_TYPE_DEVICE_WINPOINTER, GdkDeviceWinpointer))
|
||||
#define GDK_DEVICE_WINPOINTER_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), GDK_TYPE_DEVICE_WINPOINTER, GdkDeviceWinpointerClass))
|
||||
#define GDK_IS_DEVICE_WINPOINTER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDK_TYPE_DEVICE_WINPOINTER))
|
||||
#define GDK_IS_DEVICE_WINPOINTER_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), GDK_TYPE_DEVICE_WINPOINTER))
|
||||
#define GDK_DEVICE_WINPOINTER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDK_TYPE_DEVICE_WINPOINTER, GdkDeviceWinpointerClass))
|
||||
|
||||
typedef struct _GdkDeviceWinpointer GdkDeviceWinpointer;
|
||||
typedef struct _GdkDeviceWinpointerClass GdkDeviceWinpointerClass;
|
||||
|
||||
struct _GdkDeviceWinpointer
|
||||
{
|
||||
GdkDevice parent_instance;
|
||||
|
||||
HANDLE device_handle;
|
||||
UINT32 start_cursor_id;
|
||||
UINT32 end_cursor_id;
|
||||
|
||||
int origin_x;
|
||||
int origin_y;
|
||||
double scale_x;
|
||||
double scale_y;
|
||||
|
||||
double *last_axis_data;
|
||||
unsigned num_axes;
|
||||
GdkModifierType last_button_mask;
|
||||
};
|
||||
|
||||
struct _GdkDeviceWinpointerClass
|
||||
{
|
||||
GdkDeviceClass parent_class;
|
||||
};
|
||||
|
||||
GType gdk_device_winpointer_get_type (void) G_GNUC_CONST;
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_DEVICE_WINPOINTER_H__ */
|
||||
@@ -128,29 +128,31 @@ gdk_device_wintab_query_state (GdkDevice *device,
|
||||
impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
|
||||
|
||||
hwnd = GDK_WINDOW_HWND (window);
|
||||
GetCursorPos (&point);
|
||||
_gdk_win32_get_cursor_pos (&point);
|
||||
|
||||
if (root_x)
|
||||
*root_x = point.x / impl->window_scale;
|
||||
*root_x = (point.x + _gdk_offset_x) / impl->window_scale;
|
||||
|
||||
if (root_y)
|
||||
*root_y = point.y / impl->window_scale;
|
||||
*root_y = (point.y + _gdk_offset_y) / impl->window_scale;
|
||||
|
||||
ScreenToClient (hwnd, &point);
|
||||
|
||||
if (win_x)
|
||||
*win_x = point.x / impl->window_scale;
|
||||
|
||||
if (win_y)
|
||||
*win_y = point.y / impl->window_scale;
|
||||
|
||||
if (window == gdk_get_default_root_window ())
|
||||
if (window == gdk_screen_get_root_window (screen))
|
||||
{
|
||||
if (win_x)
|
||||
*win_x += _gdk_offset_x;
|
||||
*win_x = (point.x + _gdk_offset_x) / impl->window_scale;
|
||||
|
||||
if (win_y)
|
||||
*win_y += _gdk_offset_y;
|
||||
*win_y = (point.y + _gdk_offset_y) / impl->window_scale;
|
||||
}
|
||||
else
|
||||
{
|
||||
ScreenToClient (hwnd, &point);
|
||||
|
||||
if (win_x)
|
||||
*win_x = point.x / impl->window_scale;
|
||||
|
||||
if (win_y)
|
||||
*win_y = point.y / impl->window_scale;
|
||||
}
|
||||
|
||||
if (child_window)
|
||||
|
||||
@@ -49,8 +49,8 @@ struct _GdkDeviceWintab
|
||||
UINT cursor;
|
||||
/* The cursor's CSR_PKTDATA */
|
||||
WTPKT pktdata;
|
||||
/* Azimuth and altitude axis */
|
||||
AXIS orientation_axes[2];
|
||||
/* Azimuth, altitude and twist axis */
|
||||
AXIS orientation_axes[3];
|
||||
};
|
||||
|
||||
struct _GdkDeviceWintabClass
|
||||
|
||||
+1551
-195
File diff suppressed because it is too large
Load Diff
@@ -41,6 +41,8 @@ struct _GdkDeviceManagerWin32
|
||||
/* Fake slave devices */
|
||||
GdkDevice *system_pointer;
|
||||
GdkDevice *system_keyboard;
|
||||
|
||||
GList *winpointer_devices;
|
||||
GList *wintab_devices;
|
||||
|
||||
/* Bumped up every time a wintab device enters the proximity
|
||||
@@ -57,11 +59,31 @@ struct _GdkDeviceManagerWin32Class
|
||||
|
||||
GType gdk_device_manager_win32_get_type (void) G_GNUC_CONST;
|
||||
|
||||
void _gdk_input_set_tablet_active (void);
|
||||
gboolean gdk_input_other_event (GdkDisplay *display,
|
||||
GdkEvent *event,
|
||||
MSG *msg,
|
||||
GdkWindow *window);
|
||||
typedef void
|
||||
(*crossing_cb_t)(GdkDisplay *display,
|
||||
GdkDevice *device,
|
||||
GdkWindow *window,
|
||||
POINT *screen_pt,
|
||||
guint32 time_);
|
||||
|
||||
void gdk_winpointer_initialize_window (GdkWindow *window);
|
||||
gboolean gdk_winpointer_should_forward_message (MSG *msg);
|
||||
void gdk_winpointer_input_events (GdkDisplay *display,
|
||||
GdkWindow *window,
|
||||
crossing_cb_t crossing_cb,
|
||||
MSG *msg);
|
||||
gboolean gdk_winpointer_get_message_info (GdkDisplay *display,
|
||||
MSG *msg,
|
||||
GdkDevice **device,
|
||||
guint32 *time_);
|
||||
void gdk_winpointer_interaction_ended (MSG *msg);
|
||||
void gdk_winpointer_finalize_window (GdkWindow *window);
|
||||
|
||||
void _gdk_wintab_set_tablet_active (void);
|
||||
gboolean gdk_wintab_input_events (GdkDisplay *display,
|
||||
GdkEvent *event,
|
||||
MSG *msg,
|
||||
GdkWindow *window);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
@@ -31,10 +31,6 @@
|
||||
#include "gdkmonitor-win32.h"
|
||||
#include "gdkwin32.h"
|
||||
|
||||
#ifdef GDK_WIN32_ENABLE_EGL
|
||||
# include <epoxy/egl.h>
|
||||
#endif
|
||||
|
||||
#include "gdkwin32langnotification.h"
|
||||
|
||||
#ifndef IMAGE_FILE_MACHINE_ARM64
|
||||
@@ -1038,38 +1034,71 @@ _gdk_win32_enable_hidpi (GdkWin32Display *display)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_win32_check_on_arm64 (GdkWin32Display *display)
|
||||
gboolean
|
||||
_gdk_win32_check_processor (GdkWin32ProcessorCheckType check_type)
|
||||
{
|
||||
static gsize checked = 0;
|
||||
static gboolean is_arm64 = FALSE;
|
||||
static gboolean is_wow64 = FALSE;
|
||||
|
||||
if (g_once_init_enter (&checked))
|
||||
{
|
||||
gboolean fallback_wow64_check = FALSE;
|
||||
HMODULE kernel32 = LoadLibraryW (L"kernel32.dll");
|
||||
|
||||
if (kernel32 != NULL)
|
||||
{
|
||||
display->cpu_funcs.isWow64Process2 =
|
||||
typedef BOOL (WINAPI *funcIsWow64Process2) (HANDLE, USHORT *, USHORT *);
|
||||
|
||||
funcIsWow64Process2 isWow64Process2 =
|
||||
(funcIsWow64Process2) GetProcAddress (kernel32, "IsWow64Process2");
|
||||
|
||||
if (display->cpu_funcs.isWow64Process2 != NULL)
|
||||
if (isWow64Process2 != NULL)
|
||||
{
|
||||
USHORT proc_cpu = 0;
|
||||
USHORT native_cpu = 0;
|
||||
|
||||
display->cpu_funcs.isWow64Process2 (GetCurrentProcess (),
|
||||
&proc_cpu,
|
||||
&native_cpu);
|
||||
isWow64Process2 (GetCurrentProcess (), &proc_cpu, &native_cpu);
|
||||
|
||||
if (native_cpu == IMAGE_FILE_MACHINE_ARM64)
|
||||
display->running_on_arm64 = TRUE;
|
||||
is_arm64 = TRUE;
|
||||
|
||||
if (proc_cpu != IMAGE_FILE_MACHINE_UNKNOWN)
|
||||
is_wow64 = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
fallback_wow64_check = TRUE;
|
||||
}
|
||||
|
||||
FreeLibrary (kernel32);
|
||||
}
|
||||
else
|
||||
{
|
||||
fallback_wow64_check = TRUE;
|
||||
}
|
||||
|
||||
if (fallback_wow64_check)
|
||||
IsWow64Process (GetCurrentProcess (), &is_wow64);
|
||||
|
||||
g_once_init_leave (&checked, 1);
|
||||
}
|
||||
|
||||
switch (check_type)
|
||||
{
|
||||
case GDK_WIN32_ARM64:
|
||||
return is_arm64;
|
||||
break;
|
||||
|
||||
case GDK_WIN32_WOW64:
|
||||
return is_wow64;
|
||||
break;
|
||||
|
||||
default:
|
||||
g_warning ("unknown CPU check type");
|
||||
return FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1080,7 +1109,6 @@ gdk_win32_display_init (GdkWin32Display *display)
|
||||
display->monitors = g_ptr_array_new_with_free_func (g_object_unref);
|
||||
|
||||
_gdk_win32_enable_hidpi (display);
|
||||
_gdk_win32_check_on_arm64 (display);
|
||||
|
||||
/* if we have DPI awareness, set up fixed scale if set */
|
||||
if (display->dpi_aware_type != PROCESS_DPI_UNAWARE &&
|
||||
@@ -1299,7 +1327,7 @@ gdk_win32_display_class_init (GdkWin32DisplayClass *klass)
|
||||
display_class->convert_selection = _gdk_win32_display_convert_selection;
|
||||
display_class->text_property_to_utf8_list = _gdk_win32_display_text_property_to_utf8_list;
|
||||
display_class->utf8_to_string_target = _gdk_win32_display_utf8_to_string_target;
|
||||
display_class->make_gl_context_current = _gdk_win32_display_make_gl_context_current;
|
||||
display_class->make_gl_context_current = gdk_win32_display_make_gl_context_current;
|
||||
|
||||
display_class->get_n_monitors = gdk_win32_display_get_n_monitors;
|
||||
display_class->get_monitor = gdk_win32_display_get_monitor;
|
||||
|
||||
@@ -18,10 +18,7 @@
|
||||
*/
|
||||
|
||||
#include "gdkdisplayprivate.h"
|
||||
|
||||
#ifdef GDK_WIN32_ENABLE_EGL
|
||||
# include <epoxy/egl.h>
|
||||
#endif
|
||||
#include "gdkglcontext-win32.h"
|
||||
|
||||
#ifndef __GDK_DISPLAY__WIN32_H__
|
||||
#define __GDK_DISPLAY__WIN32_H__
|
||||
@@ -33,6 +30,15 @@ typedef enum _GdkWin32ProcessDpiAwareness {
|
||||
PROCESS_PER_MONITOR_DPI_AWARE = 2
|
||||
} GdkWin32ProcessDpiAwareness;
|
||||
|
||||
/* Define values for GL type used */
|
||||
typedef enum _GdkWin32GLContextType
|
||||
{
|
||||
GDK_WIN32_GL_PENDING,
|
||||
GDK_WIN32_GL_NONE,
|
||||
GDK_WIN32_GL_WGL,
|
||||
GDK_WIN32_GL_EGL
|
||||
} GdkWin32GLContextType;
|
||||
|
||||
/* APIs from shcore.dll */
|
||||
typedef HRESULT (WINAPI *funcSetProcessDpiAwareness) (GdkWin32ProcessDpiAwareness value);
|
||||
typedef HRESULT (WINAPI *funcGetProcessDpiAwareness) (HANDLE handle,
|
||||
@@ -60,13 +66,6 @@ typedef struct _GdkWin32User32DPIFuncs
|
||||
funcIsProcessDPIAware isDpiAwareFunc;
|
||||
} GdkWin32User32DPIFuncs;
|
||||
|
||||
/* Detect running architecture */
|
||||
typedef BOOL (WINAPI *funcIsWow64Process2) (HANDLE, USHORT *, USHORT *);
|
||||
typedef struct _GdkWin32KernelCPUFuncs
|
||||
{
|
||||
funcIsWow64Process2 isWow64Process2;
|
||||
} GdkWin32KernelCPUFuncs;
|
||||
|
||||
struct _GdkWin32Display
|
||||
{
|
||||
GdkDisplay display;
|
||||
@@ -81,33 +80,33 @@ struct _GdkWin32Display
|
||||
HWND hwnd;
|
||||
HWND clipboard_hwnd;
|
||||
|
||||
/* WGL/OpenGL Items */
|
||||
guint have_wgl : 1;
|
||||
/* OpenGL Items */
|
||||
GdkWin32GLContextType gl_type;
|
||||
guint gl_version;
|
||||
HWND gl_hwnd;
|
||||
|
||||
#ifdef GDK_WIN32_ENABLE_EGL
|
||||
/* EGL (Angle) Items */
|
||||
guint have_egl : 1;
|
||||
guint egl_version;
|
||||
EGLDisplay egl_disp;
|
||||
HDC hdc_egl_temp;
|
||||
#endif
|
||||
|
||||
GPtrArray *monitors;
|
||||
|
||||
/* WGL Items */
|
||||
guint hasWglARBCreateContext : 1;
|
||||
guint hasWglEXTSwapControl : 1;
|
||||
guint hasWglOMLSyncControl : 1;
|
||||
guint hasWglARBPixelFormat : 1;
|
||||
guint hasWglARBmultisample : 1;
|
||||
|
||||
/* compensate around Intel OpenGL driver issues on blitting, see issue #3487 */
|
||||
guint needIntelGLWorkaround : 1;
|
||||
|
||||
/* EGL (Angle) Items */
|
||||
HDC hdc_egl_temp;
|
||||
|
||||
#ifdef GDK_WIN32_ENABLE_EGL
|
||||
EGLDisplay egl_disp;
|
||||
EGLConfig egl_config;
|
||||
guint hasEglKHRCreateContext : 1;
|
||||
guint hasEglSurfacelessContext : 1;
|
||||
EGLint egl_min_swap_interval;
|
||||
#endif
|
||||
|
||||
GPtrArray *monitors;
|
||||
|
||||
/* HiDPI Items */
|
||||
guint have_at_least_win81 : 1;
|
||||
GdkWin32ProcessDpiAwareness dpi_aware_type;
|
||||
@@ -118,8 +117,6 @@ struct _GdkWin32Display
|
||||
GdkWin32User32DPIFuncs user32_dpi_funcs;
|
||||
|
||||
/* Running CPU items */
|
||||
guint running_on_arm64 : 1;
|
||||
GdkWin32KernelCPUFuncs cpu_funcs;
|
||||
};
|
||||
|
||||
struct _GdkWin32DisplayClass
|
||||
|
||||
+60
-82
@@ -588,8 +588,8 @@ idroptarget_dragenter (LPDROPTARGET This,
|
||||
|
||||
ctx->context->suggested_action = get_suggested_action (grfKeyState);
|
||||
set_data_object (&sel_win32->dnd_data_object_target, pDataObj);
|
||||
pt_x = pt.x / context_win32->scale + _gdk_offset_x;
|
||||
pt_y = pt.y / context_win32->scale + _gdk_offset_y;
|
||||
pt_x = (pt.x + _gdk_offset_x) / context_win32->scale;
|
||||
pt_y = (pt.y + _gdk_offset_y) / context_win32->scale;
|
||||
dnd_event_put (GDK_DRAG_ENTER, ctx->context, pt_x, pt_y, TRUE);
|
||||
dnd_event_put (GDK_DRAG_MOTION, ctx->context, pt_x, pt_y, TRUE);
|
||||
context_win32->last_key_state = grfKeyState;
|
||||
@@ -611,8 +611,8 @@ idroptarget_dragover (LPDROPTARGET This,
|
||||
{
|
||||
target_drag_context *ctx = (target_drag_context *) This;
|
||||
GdkWin32DragContext *context_win32 = GDK_WIN32_DRAG_CONTEXT (ctx->context);
|
||||
gint pt_x = pt.x / context_win32->scale + _gdk_offset_x;
|
||||
gint pt_y = pt.y / context_win32->scale + _gdk_offset_y;
|
||||
gint pt_x = (pt.x + _gdk_offset_x) / context_win32->scale;
|
||||
gint pt_y = (pt.y + _gdk_offset_y) / context_win32->scale;
|
||||
|
||||
ctx->context->suggested_action = get_suggested_action (grfKeyState);
|
||||
|
||||
@@ -664,8 +664,8 @@ idroptarget_drop (LPDROPTARGET This,
|
||||
{
|
||||
target_drag_context *ctx = (target_drag_context *) This;
|
||||
GdkWin32DragContext *context_win32 = GDK_WIN32_DRAG_CONTEXT (ctx->context);
|
||||
gint pt_x = pt.x / context_win32->scale + _gdk_offset_x;
|
||||
gint pt_y = pt.y / context_win32->scale + _gdk_offset_y;
|
||||
gint pt_x = (pt.x + _gdk_offset_x) / context_win32->scale;
|
||||
gint pt_y = (pt.y + _gdk_offset_y) / context_win32->scale;
|
||||
GdkWin32Selection *sel_win32 = _gdk_win32_selection_get ();
|
||||
|
||||
GDK_NOTE (DND, g_print ("idroptarget_drop %p ", This));
|
||||
@@ -774,6 +774,7 @@ send_change_events (GdkDragContext *context,
|
||||
GdkWin32DragContext *context_win32 = GDK_WIN32_DRAG_CONTEXT (context);
|
||||
POINT pt;
|
||||
POINT pt_client;
|
||||
HMONITOR monitor = NULL;
|
||||
gboolean changed = FALSE;
|
||||
HWND hwnd = GDK_WINDOW_HWND (context->source_window);
|
||||
LPARAM lparam;
|
||||
@@ -784,13 +785,31 @@ send_change_events (GdkDragContext *context,
|
||||
if (!API_CALL (GetCursorPos, (&pt)))
|
||||
return FALSE;
|
||||
|
||||
/* Move the DND IPC window to the monitor the cursor is currently on.
|
||||
This esures that OLE2 DND works correctly even if the DPI awareness
|
||||
isn't per-monitor.
|
||||
*/
|
||||
monitor = MonitorFromPoint (pt, MONITOR_DEFAULTTONEAREST);
|
||||
if (monitor != context_win32->last_monitor)
|
||||
{
|
||||
MONITORINFO mi;
|
||||
|
||||
mi.cbSize = sizeof(mi);
|
||||
if (GetMonitorInfoW (monitor, &mi))
|
||||
{
|
||||
MoveWindow (hwnd, mi.rcWork.left, mi.rcWork.top, 1, 1, FALSE);
|
||||
}
|
||||
|
||||
context_win32->last_monitor = monitor;
|
||||
}
|
||||
|
||||
pt_client = pt;
|
||||
|
||||
if (!API_CALL (ScreenToClient, (hwnd, &pt_client)))
|
||||
return FALSE;
|
||||
|
||||
pt_x = pt.x / context_win32->scale + _gdk_offset_x;
|
||||
pt_y = pt.y / context_win32->scale + _gdk_offset_y;
|
||||
pt_x = (pt.x + _gdk_offset_x) / context_win32->scale;
|
||||
pt_y = (pt.y + _gdk_offset_y) / context_win32->scale;
|
||||
|
||||
if (pt_x != context_win32->last_x || pt_y != context_win32->last_y ||
|
||||
key_state != context_win32->last_key_state)
|
||||
@@ -909,8 +928,8 @@ idropsource_givefeedback (LPDROPSOURCE This,
|
||||
else if (ctx->context->dest_window == NULL)
|
||||
ctx->context->dest_window = g_object_ref (gdk_get_default_root_window ());
|
||||
|
||||
context_win32->last_x = pt.x / context_win32->scale + _gdk_offset_x;
|
||||
context_win32->last_y = pt.y / context_win32->scale + _gdk_offset_y;
|
||||
context_win32->last_x = (pt.x + _gdk_offset_x) / context_win32->scale;
|
||||
context_win32->last_y = (pt.y + _gdk_offset_y) / context_win32->scale;
|
||||
|
||||
e = gdk_event_new (GDK_DRAG_STATUS);
|
||||
|
||||
@@ -1708,8 +1727,8 @@ gdk_dropfiles_filter (GdkXEvent *xev,
|
||||
DragQueryPoint (hdrop, &pt);
|
||||
ClientToScreen (msg->hwnd, &pt);
|
||||
|
||||
event->dnd.x_root = pt.x / context_win32->scale + _gdk_offset_x;
|
||||
event->dnd.y_root = pt.y / context_win32->scale + _gdk_offset_y;
|
||||
event->dnd.x_root = (pt.x + _gdk_offset_x) / context_win32->scale;
|
||||
event->dnd.y_root = (pt.y + _gdk_offset_y) / context_win32->scale;
|
||||
event->dnd.time = _gdk_win32_get_next_tick (msg->time);
|
||||
|
||||
nfiles = DragQueryFile (hdrop, 0xFFFFFFFF, NULL, 0);
|
||||
@@ -2204,43 +2223,6 @@ _gdk_win32_window_get_drag_protocol (GdkWindow *window,
|
||||
return protocol;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
gint x;
|
||||
gint y;
|
||||
HWND ignore;
|
||||
HWND result;
|
||||
} find_window_enum_arg;
|
||||
|
||||
static BOOL CALLBACK
|
||||
find_window_enum_proc (HWND hwnd,
|
||||
LPARAM lparam)
|
||||
{
|
||||
RECT rect;
|
||||
POINT tl, br;
|
||||
find_window_enum_arg *a = (find_window_enum_arg *) lparam;
|
||||
|
||||
if (hwnd == a->ignore)
|
||||
return TRUE;
|
||||
|
||||
if (!IsWindowVisible (hwnd))
|
||||
return TRUE;
|
||||
|
||||
tl.x = tl.y = 0;
|
||||
ClientToScreen (hwnd, &tl);
|
||||
GetClientRect (hwnd, &rect);
|
||||
br.x = rect.right;
|
||||
br.y = rect.bottom;
|
||||
ClientToScreen (hwnd, &br);
|
||||
|
||||
if (a->x >= tl.x && a->y >= tl.y && a->x < br.x && a->y < br.y)
|
||||
{
|
||||
a->result = hwnd;
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GdkWindow *
|
||||
gdk_win32_drag_context_find_window (GdkDragContext *context,
|
||||
GdkWindow *drag_window,
|
||||
@@ -2250,51 +2232,47 @@ gdk_win32_drag_context_find_window (GdkDragContext *context,
|
||||
GdkDragProtocol *protocol)
|
||||
{
|
||||
GdkWin32DragContext *context_win32 = GDK_WIN32_DRAG_CONTEXT (context);
|
||||
GdkWindow *dest_window, *dw;
|
||||
find_window_enum_arg a;
|
||||
GdkWindow *toplevel = NULL;
|
||||
HWND hwnd = NULL;
|
||||
POINT pt;
|
||||
|
||||
a.x = x_root * context_win32->scale - _gdk_offset_x;
|
||||
a.y = y_root * context_win32->scale - _gdk_offset_y;
|
||||
a.ignore = drag_window ? GDK_WINDOW_HWND (drag_window) : NULL;
|
||||
a.result = NULL;
|
||||
pt.x = x_root * context_win32->scale - _gdk_offset_x;
|
||||
pt.y = y_root * context_win32->scale - _gdk_offset_y;
|
||||
|
||||
GDK_NOTE (DND,
|
||||
g_print ("gdk_drag_find_window_real: %p %+d%+d\n",
|
||||
(drag_window ? GDK_WINDOW_HWND (drag_window) : NULL),
|
||||
a.x, a.y));
|
||||
g_print ("gdk_drag_find_window_real: %+d%+d\n",
|
||||
(int) pt.x, (int) pt.y));
|
||||
|
||||
EnumWindows (find_window_enum_proc, (LPARAM) &a);
|
||||
hwnd = WindowFromPoint (pt);
|
||||
|
||||
if (a.result == NULL)
|
||||
dest_window = NULL;
|
||||
else
|
||||
if (hwnd)
|
||||
{
|
||||
dw = gdk_win32_handle_table_lookup (a.result);
|
||||
if (dw)
|
||||
GdkWindow *window = gdk_win32_handle_table_lookup (hwnd);
|
||||
|
||||
if (window)
|
||||
{
|
||||
dest_window = gdk_window_get_toplevel (dw);
|
||||
g_object_ref (dest_window);
|
||||
toplevel = gdk_window_get_toplevel (window);
|
||||
g_object_ref (toplevel);
|
||||
}
|
||||
else
|
||||
dest_window = gdk_win32_window_foreign_new_for_display (gdk_screen_get_display (screen), a.result);
|
||||
|
||||
if (use_ole2_dnd)
|
||||
*protocol = GDK_DRAG_PROTO_OLE2;
|
||||
else if (context->source_window)
|
||||
*protocol = GDK_DRAG_PROTO_LOCAL;
|
||||
else
|
||||
*protocol = GDK_DRAG_PROTO_WIN32_DROPFILES;
|
||||
toplevel = gdk_win32_window_foreign_new_for_display (gdk_screen_get_display (screen), hwnd);
|
||||
}
|
||||
|
||||
GDK_NOTE (DND,
|
||||
g_print ("gdk_drag_find_window: %p %+d%+d: %p: %p %s\n",
|
||||
(drag_window ? GDK_WINDOW_HWND (drag_window) : NULL),
|
||||
x_root, y_root,
|
||||
a.result,
|
||||
(dest_window ? GDK_WINDOW_HWND (dest_window) : NULL),
|
||||
_gdk_win32_drag_protocol_to_string (*protocol)));
|
||||
if (use_ole2_dnd)
|
||||
*protocol = GDK_DRAG_PROTO_OLE2;
|
||||
else if (context->source_window)
|
||||
*protocol = GDK_DRAG_PROTO_LOCAL;
|
||||
else
|
||||
*protocol = GDK_DRAG_PROTO_WIN32_DROPFILES;
|
||||
|
||||
return dest_window;
|
||||
GDK_NOTE (DND,
|
||||
g_print ("gdk_drag_find_window: %+d%+d: %p: %p %s\n",
|
||||
x_root, y_root,
|
||||
hwnd,
|
||||
(toplevel ? GDK_WINDOW_HWND (toplevel) : NULL),
|
||||
_gdk_win32_drag_protocol_to_string (*protocol)));
|
||||
|
||||
return toplevel;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
||||
+341
-75
@@ -19,7 +19,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
|
||||
* Modified by the GTK+ Team and others 1997-2020. 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/.
|
||||
@@ -54,6 +54,7 @@
|
||||
#include "gdkglcontext-win32.h"
|
||||
#include "gdkdevicemanager-win32.h"
|
||||
#include "gdkdeviceprivate.h"
|
||||
#include "gdkdevice-virtual.h"
|
||||
#include "gdkdevice-wintab.h"
|
||||
#include "gdkwin32dnd.h"
|
||||
#include "gdkdisplay-win32.h"
|
||||
@@ -61,6 +62,8 @@
|
||||
#include "gdkdndprivate.h"
|
||||
|
||||
#include <windowsx.h>
|
||||
#include <tpcshrd.h>
|
||||
#include "winpointer.h"
|
||||
|
||||
#ifdef G_WITH_CYGWIN
|
||||
#include <fcntl.h>
|
||||
@@ -153,6 +156,10 @@ static int both_shift_pressed[2]; /* to store keycodes for shift keys */
|
||||
static HHOOK keyboard_hook = NULL;
|
||||
static UINT aerosnap_message;
|
||||
|
||||
static gboolean pen_touch_input;
|
||||
static POINT pen_touch_cursor_position;
|
||||
static LONG last_digitizer_time;
|
||||
|
||||
static void
|
||||
track_mouse_event (DWORD dwFlags,
|
||||
HWND hwnd)
|
||||
@@ -187,6 +194,18 @@ _gdk_win32_get_next_tick (gulong suggested_tick)
|
||||
return cur_tick = suggested_tick;
|
||||
}
|
||||
|
||||
BOOL
|
||||
_gdk_win32_get_cursor_pos (LPPOINT lpPoint)
|
||||
{
|
||||
if (pen_touch_input)
|
||||
{
|
||||
*lpPoint = pen_touch_cursor_position;
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
return GetCursorPos (lpPoint);
|
||||
}
|
||||
|
||||
static void
|
||||
generate_focus_event (GdkDeviceManager *device_manager,
|
||||
GdkWindow *window,
|
||||
@@ -228,6 +247,7 @@ generate_grab_broken_event (GdkDeviceManager *device_manager,
|
||||
{
|
||||
device = GDK_DEVICE_MANAGER_WIN32 (device_manager)->core_pointer;
|
||||
source_device = GDK_DEVICE_MANAGER_WIN32 (device_manager)->system_pointer;
|
||||
_gdk_device_virtual_set_active (device, source_device);
|
||||
}
|
||||
|
||||
event->grab_broken.window = window;
|
||||
@@ -635,11 +655,9 @@ build_key_event_state (GdkEvent *event,
|
||||
BYTE *key_state)
|
||||
{
|
||||
GdkWin32Keymap *keymap;
|
||||
keymap = GDK_WIN32_KEYMAP (_gdk_win32_display_get_keymap (_gdk_display));
|
||||
|
||||
event->key.state = 0;
|
||||
|
||||
if (key_state[VK_SHIFT] & 0x80)
|
||||
event->key.state |= GDK_SHIFT_MASK;
|
||||
event->key.state = _gdk_win32_keymap_get_mod_mask (keymap);
|
||||
|
||||
if (key_state[VK_CAPITAL] & 0x01)
|
||||
event->key.state |= GDK_LOCK_MASK;
|
||||
@@ -655,26 +673,7 @@ build_key_event_state (GdkEvent *event,
|
||||
if (key_state[VK_XBUTTON2] & 0x80)
|
||||
event->key.state |= GDK_BUTTON5_MASK;
|
||||
|
||||
keymap = GDK_WIN32_KEYMAP (_gdk_win32_display_get_keymap (_gdk_display));
|
||||
event->key.group = _gdk_win32_keymap_get_active_group (keymap);
|
||||
|
||||
if (_gdk_win32_keymap_has_altgr (keymap) &&
|
||||
(key_state[VK_LCONTROL] & 0x80) &&
|
||||
(key_state[VK_RMENU] & 0x80))
|
||||
{
|
||||
event->key.state |= GDK_MOD2_MASK;
|
||||
if (key_state[VK_RCONTROL] & 0x80)
|
||||
event->key.state |= GDK_CONTROL_MASK;
|
||||
if (key_state[VK_LMENU] & 0x80)
|
||||
event->key.state |= GDK_MOD1_MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (key_state[VK_CONTROL] & 0x80)
|
||||
event->key.state |= GDK_CONTROL_MASK;
|
||||
if (key_state[VK_MENU] & 0x80)
|
||||
event->key.state |= GDK_MOD1_MASK;
|
||||
}
|
||||
}
|
||||
|
||||
static gint
|
||||
@@ -1237,6 +1236,7 @@ do_show_window (GdkWindow *window, gboolean hide_window)
|
||||
|
||||
static void
|
||||
send_crossing_event (GdkDisplay *display,
|
||||
GdkDevice *source_device,
|
||||
GdkWindow *window,
|
||||
GdkEventType type,
|
||||
GdkCrossingMode mode,
|
||||
@@ -1271,7 +1271,7 @@ send_crossing_event (GdkDisplay *display,
|
||||
event = gdk_event_new (type);
|
||||
event->crossing.window = window;
|
||||
event->crossing.subwindow = subwindow;
|
||||
event->crossing.time = _gdk_win32_get_next_tick (time_);
|
||||
event->crossing.time = time_;
|
||||
event->crossing.x = pt.x / impl->window_scale;
|
||||
event->crossing.y = pt.y / impl->window_scale;
|
||||
event->crossing.x_root = (screen_pt->x + _gdk_offset_x) / impl->window_scale;
|
||||
@@ -1283,9 +1283,11 @@ send_crossing_event (GdkDisplay *display,
|
||||
event->crossing.focus = FALSE;
|
||||
event->crossing.state = mask;
|
||||
gdk_event_set_device (event, device_manager->core_pointer);
|
||||
gdk_event_set_source_device (event, device_manager->system_pointer);
|
||||
gdk_event_set_source_device (event, source_device);
|
||||
gdk_event_set_seat (event, gdk_device_get_seat (device_manager->core_pointer));
|
||||
|
||||
_gdk_device_virtual_set_active (device_manager->core_pointer, source_device);
|
||||
|
||||
_gdk_win32_append_event (event);
|
||||
}
|
||||
|
||||
@@ -1336,6 +1338,7 @@ find_common_ancestor (GdkWindow *win1,
|
||||
|
||||
void
|
||||
synthesize_crossing_events (GdkDisplay *display,
|
||||
GdkDevice *source_device,
|
||||
GdkWindow *src,
|
||||
GdkWindow *dest,
|
||||
GdkCrossingMode mode,
|
||||
@@ -1370,6 +1373,7 @@ synthesize_crossing_events (GdkDisplay *display,
|
||||
else
|
||||
notify_type = GDK_NOTIFY_ANCESTOR;
|
||||
send_crossing_event (display,
|
||||
source_device,
|
||||
a, GDK_LEAVE_NOTIFY,
|
||||
mode,
|
||||
notify_type,
|
||||
@@ -1389,6 +1393,7 @@ synthesize_crossing_events (GdkDisplay *display,
|
||||
while (win != c && win->window_type != GDK_WINDOW_ROOT)
|
||||
{
|
||||
send_crossing_event (display,
|
||||
source_device,
|
||||
win, GDK_LEAVE_NOTIFY,
|
||||
mode,
|
||||
notify_type,
|
||||
@@ -1431,6 +1436,7 @@ synthesize_crossing_events (GdkDisplay *display,
|
||||
next = b;
|
||||
|
||||
send_crossing_event (display,
|
||||
source_device,
|
||||
win, GDK_ENTER_NOTIFY,
|
||||
mode,
|
||||
notify_type,
|
||||
@@ -1450,6 +1456,7 @@ synthesize_crossing_events (GdkDisplay *display,
|
||||
notify_type = GDK_NOTIFY_INFERIOR;
|
||||
|
||||
send_crossing_event (display,
|
||||
source_device,
|
||||
b, GDK_ENTER_NOTIFY,
|
||||
mode,
|
||||
notify_type,
|
||||
@@ -1459,6 +1466,27 @@ synthesize_crossing_events (GdkDisplay *display,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
make_crossing_event (GdkDisplay *display,
|
||||
GdkDevice *device,
|
||||
GdkWindow *window,
|
||||
POINT *screen_pt,
|
||||
guint32 time_)
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_print (" mouse_window %p -> %p",
|
||||
mouse_window ? GDK_WINDOW_HWND (mouse_window) : NULL,
|
||||
window ? GDK_WINDOW_HWND (window) : NULL));
|
||||
synthesize_crossing_events (display,
|
||||
device,
|
||||
mouse_window, window,
|
||||
GDK_CROSSING_NORMAL,
|
||||
screen_pt,
|
||||
0, /* TODO: Set right mask */
|
||||
time_,
|
||||
FALSE);
|
||||
g_set_object (&mouse_window, window);
|
||||
}
|
||||
|
||||
/* The check_extended flag controls whether to check if the windows want
|
||||
* events from extended input devices and if the message should be skipped
|
||||
* because an extended input device is active
|
||||
@@ -1579,8 +1607,8 @@ _gdk_win32_get_window_rect (GdkWindow *window,
|
||||
if (gdk_window_get_parent (window) == gdk_get_default_root_window ())
|
||||
{
|
||||
ClientToScreen (hwnd, &point);
|
||||
point.x += _gdk_offset_x * window_impl->window_scale;
|
||||
point.y += _gdk_offset_y * window_impl->window_scale;
|
||||
point.x += _gdk_offset_x;
|
||||
point.y += _gdk_offset_y;
|
||||
}
|
||||
|
||||
rect->left = point.x;
|
||||
@@ -1838,7 +1866,7 @@ generate_button_event (GdkEventType type,
|
||||
GdkWindow *window,
|
||||
MSG *msg)
|
||||
{
|
||||
GdkEvent *event = gdk_event_new (type);
|
||||
GdkEvent *event;
|
||||
GdkDeviceManagerWin32 *device_manager;
|
||||
GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
|
||||
|
||||
@@ -1847,6 +1875,7 @@ generate_button_event (GdkEventType type,
|
||||
|
||||
device_manager = GDK_DEVICE_MANAGER_WIN32 (gdk_display_get_device_manager (gdk_display_get_default ()));
|
||||
|
||||
event = gdk_event_new (type);
|
||||
event->button.window = window;
|
||||
event->button.time = _gdk_win32_get_next_tick (msg->time);
|
||||
event->button.x = current_x = (gint16) GET_X_LPARAM (msg->lParam) / impl->window_scale;
|
||||
@@ -1860,6 +1889,8 @@ generate_button_event (GdkEventType type,
|
||||
gdk_event_set_source_device (event, device_manager->system_pointer);
|
||||
gdk_event_set_seat (event, gdk_device_get_seat (device_manager->core_pointer));
|
||||
|
||||
_gdk_device_virtual_set_active (device_manager->core_pointer, device_manager->system_pointer);
|
||||
|
||||
_gdk_win32_append_event (event);
|
||||
}
|
||||
|
||||
@@ -2103,6 +2134,8 @@ gdk_event_translate (MSG *msg,
|
||||
GdkDeviceGrabInfo *pointer_grab = NULL;
|
||||
GdkWindow *grab_window = NULL;
|
||||
|
||||
crossing_cb_t crossing_cb = NULL;
|
||||
|
||||
gint button;
|
||||
GdkAtom target;
|
||||
|
||||
@@ -2599,6 +2632,8 @@ gdk_event_translate (MSG *msg,
|
||||
g_print (" (%d,%d)",
|
||||
GET_X_LPARAM (msg->lParam), GET_Y_LPARAM (msg->lParam)));
|
||||
|
||||
pen_touch_input = FALSE;
|
||||
|
||||
g_set_object (&window, find_window_for_mouse_event (window, msg));
|
||||
/* TODO_CSW?: there used to some synthesize and propagate */
|
||||
if (GDK_WINDOW_DESTROYED (window))
|
||||
@@ -2638,6 +2673,8 @@ gdk_event_translate (MSG *msg,
|
||||
g_print (" (%d,%d)",
|
||||
GET_X_LPARAM (msg->lParam), GET_Y_LPARAM (msg->lParam)));
|
||||
|
||||
pen_touch_input = FALSE;
|
||||
|
||||
g_set_object (&window, find_window_for_mouse_event (window, msg));
|
||||
|
||||
if (pointer_grab != NULL && pointer_grab->implicit)
|
||||
@@ -2664,11 +2701,12 @@ gdk_event_translate (MSG *msg,
|
||||
}
|
||||
|
||||
synthesize_crossing_events (display,
|
||||
device_manager_win32->system_pointer,
|
||||
native_window, new_window,
|
||||
GDK_CROSSING_UNGRAB,
|
||||
&msg->pt,
|
||||
0, /* TODO: Set right mask */
|
||||
msg->time,
|
||||
_gdk_win32_get_next_tick (msg->time),
|
||||
FALSE);
|
||||
g_set_object (&mouse_window, new_window);
|
||||
mouse_window_ignored_leave = NULL;
|
||||
@@ -2694,6 +2732,13 @@ gdk_event_translate (MSG *msg,
|
||||
(gpointer) msg->wParam,
|
||||
GET_X_LPARAM (msg->lParam), GET_Y_LPARAM (msg->lParam)));
|
||||
|
||||
if (_gdk_win32_tablet_input_api == GDK_WIN32_TABLET_INPUT_API_WINPOINTER &&
|
||||
( (msg->time - last_digitizer_time) < 200 ||
|
||||
-(msg->time - last_digitizer_time) < 200 ))
|
||||
break;
|
||||
|
||||
pen_touch_input = FALSE;
|
||||
|
||||
new_window = window;
|
||||
|
||||
if (pointer_grab != NULL)
|
||||
@@ -2721,15 +2766,16 @@ gdk_event_translate (MSG *msg,
|
||||
|
||||
if (mouse_window != new_window)
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_print (" mouse_sinwod %p -> %p",
|
||||
GDK_NOTE (EVENTS, g_print (" mouse_window %p -> %p",
|
||||
mouse_window ? GDK_WINDOW_HWND (mouse_window) : NULL,
|
||||
new_window ? GDK_WINDOW_HWND (new_window) : NULL));
|
||||
synthesize_crossing_events (display,
|
||||
device_manager_win32->system_pointer,
|
||||
mouse_window, new_window,
|
||||
GDK_CROSSING_NORMAL,
|
||||
&msg->pt,
|
||||
0, /* TODO: Set right mask */
|
||||
msg->time,
|
||||
_gdk_win32_get_next_tick (msg->time),
|
||||
FALSE);
|
||||
g_set_object (&mouse_window, new_window);
|
||||
mouse_window_ignored_leave = NULL;
|
||||
@@ -2781,6 +2827,8 @@ gdk_event_translate (MSG *msg,
|
||||
gdk_event_set_source_device (event, device_manager_win32->system_pointer);
|
||||
gdk_event_set_seat (event, gdk_device_get_seat (device_manager_win32->core_pointer));
|
||||
|
||||
_gdk_device_virtual_set_active (device_manager_win32->core_pointer, device_manager_win32->system_pointer);
|
||||
|
||||
_gdk_win32_append_event (event);
|
||||
}
|
||||
|
||||
@@ -2791,12 +2839,17 @@ gdk_event_translate (MSG *msg,
|
||||
GDK_NOTE (EVENTS,
|
||||
g_print (" (%d,%d)",
|
||||
GET_X_LPARAM (msg->lParam), GET_Y_LPARAM (msg->lParam)));
|
||||
|
||||
pen_touch_input = FALSE;
|
||||
|
||||
break;
|
||||
|
||||
case WM_MOUSELEAVE:
|
||||
GDK_NOTE (EVENTS, g_print (" %d (%ld,%ld)",
|
||||
HIWORD (msg->wParam), msg->pt.x, msg->pt.y));
|
||||
|
||||
pen_touch_input = FALSE;
|
||||
|
||||
new_window = NULL;
|
||||
hwnd = WindowFromPoint (msg->pt);
|
||||
ignore_leave = FALSE;
|
||||
@@ -2822,11 +2875,12 @@ gdk_event_translate (MSG *msg,
|
||||
|
||||
if (!ignore_leave)
|
||||
synthesize_crossing_events (display,
|
||||
device_manager_win32->system_pointer,
|
||||
mouse_window, new_window,
|
||||
GDK_CROSSING_NORMAL,
|
||||
&msg->pt,
|
||||
0, /* TODO: Set right mask */
|
||||
msg->time,
|
||||
_gdk_win32_get_next_tick (msg->time),
|
||||
FALSE);
|
||||
g_set_object (&mouse_window, new_window);
|
||||
mouse_window_ignored_leave = ignore_leave ? new_window : NULL;
|
||||
@@ -2835,6 +2889,215 @@ gdk_event_translate (MSG *msg,
|
||||
return_val = TRUE;
|
||||
break;
|
||||
|
||||
case WM_POINTERDOWN:
|
||||
if (_gdk_win32_tablet_input_api != GDK_WIN32_TABLET_INPUT_API_WINPOINTER ||
|
||||
gdk_winpointer_should_forward_message (msg))
|
||||
{
|
||||
return_val = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (IS_POINTER_PRIMARY_WPARAM (msg->wParam))
|
||||
{
|
||||
current_root_x = pen_touch_cursor_position.x = GET_X_LPARAM (msg->lParam);
|
||||
current_root_y = pen_touch_cursor_position.y = GET_Y_LPARAM (msg->lParam);
|
||||
pen_touch_input = TRUE;
|
||||
last_digitizer_time = msg->time;
|
||||
}
|
||||
|
||||
if (pointer_grab != NULL &&
|
||||
!pointer_grab->implicit &&
|
||||
!pointer_grab->owner_events)
|
||||
g_set_object (&window, pointer_grab->native_window);
|
||||
|
||||
if (IS_POINTER_PRIMARY_WPARAM (msg->wParam) && mouse_window != window)
|
||||
crossing_cb = make_crossing_event;
|
||||
|
||||
gdk_winpointer_input_events (display, window, crossing_cb, msg);
|
||||
|
||||
*ret_valp = 0;
|
||||
return_val = TRUE;
|
||||
break;
|
||||
|
||||
case WM_POINTERUP:
|
||||
if (_gdk_win32_tablet_input_api != GDK_WIN32_TABLET_INPUT_API_WINPOINTER ||
|
||||
gdk_winpointer_should_forward_message (msg))
|
||||
{
|
||||
return_val = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (IS_POINTER_PRIMARY_WPARAM (msg->wParam))
|
||||
{
|
||||
current_root_x = pen_touch_cursor_position.x = GET_X_LPARAM (msg->lParam);
|
||||
current_root_y = pen_touch_cursor_position.y = GET_Y_LPARAM (msg->lParam);
|
||||
pen_touch_input = TRUE;
|
||||
last_digitizer_time = msg->time;
|
||||
}
|
||||
|
||||
if (pointer_grab != NULL &&
|
||||
!pointer_grab->implicit &&
|
||||
!pointer_grab->owner_events)
|
||||
g_set_object (&window, pointer_grab->native_window);
|
||||
|
||||
gdk_winpointer_input_events (display, window, NULL, msg);
|
||||
|
||||
impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
|
||||
if (impl->drag_move_resize_context.op != GDK_WIN32_DRAGOP_NONE)
|
||||
{
|
||||
gdk_win32_window_end_move_resize_drag (window);
|
||||
}
|
||||
|
||||
*ret_valp = 0;
|
||||
return_val = TRUE;
|
||||
break;
|
||||
|
||||
case WM_POINTERUPDATE:
|
||||
if (_gdk_win32_tablet_input_api != GDK_WIN32_TABLET_INPUT_API_WINPOINTER ||
|
||||
gdk_winpointer_should_forward_message (msg))
|
||||
{
|
||||
return_val = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (IS_POINTER_PRIMARY_WPARAM (msg->wParam))
|
||||
{
|
||||
current_root_x = pen_touch_cursor_position.x = GET_X_LPARAM (msg->lParam);
|
||||
current_root_y = pen_touch_cursor_position.y = GET_Y_LPARAM (msg->lParam);
|
||||
pen_touch_input = TRUE;
|
||||
last_digitizer_time = msg->time;
|
||||
}
|
||||
|
||||
if (pointer_grab != NULL &&
|
||||
!pointer_grab->implicit &&
|
||||
!pointer_grab->owner_events)
|
||||
g_set_object (&window, pointer_grab->native_window);
|
||||
|
||||
if (IS_POINTER_PRIMARY_WPARAM (msg->wParam) && mouse_window != window)
|
||||
crossing_cb = make_crossing_event;
|
||||
|
||||
impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
|
||||
|
||||
if (impl->drag_move_resize_context.op != GDK_WIN32_DRAGOP_NONE)
|
||||
{
|
||||
gdk_win32_window_do_move_resize_drag (window, current_root_x, current_root_y);
|
||||
}
|
||||
else
|
||||
{
|
||||
gdk_winpointer_input_events (display, window, crossing_cb, msg);
|
||||
}
|
||||
|
||||
*ret_valp = 0;
|
||||
return_val = TRUE;
|
||||
break;
|
||||
|
||||
case WM_NCPOINTERUPDATE:
|
||||
if (_gdk_win32_tablet_input_api != GDK_WIN32_TABLET_INPUT_API_WINPOINTER ||
|
||||
gdk_winpointer_should_forward_message (msg))
|
||||
{
|
||||
return_val = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (IS_POINTER_PRIMARY_WPARAM (msg->wParam))
|
||||
{
|
||||
current_root_x = pen_touch_cursor_position.x = GET_X_LPARAM (msg->lParam);
|
||||
current_root_y = pen_touch_cursor_position.y = GET_Y_LPARAM (msg->lParam);
|
||||
pen_touch_input = TRUE;
|
||||
last_digitizer_time = msg->time;
|
||||
}
|
||||
|
||||
if (IS_POINTER_PRIMARY_WPARAM (msg->wParam) &&
|
||||
!IS_POINTER_INCONTACT_WPARAM (msg->wParam) &&
|
||||
mouse_window != NULL)
|
||||
{
|
||||
GdkDevice *event_device = NULL;
|
||||
guint32 event_time = 0;
|
||||
|
||||
if (gdk_winpointer_get_message_info (display, msg, &event_device, &event_time))
|
||||
{
|
||||
make_crossing_event(display,
|
||||
event_device,
|
||||
NULL,
|
||||
&pen_touch_cursor_position,
|
||||
event_time);
|
||||
}
|
||||
}
|
||||
|
||||
return_val = FALSE; /* forward to DefWindowProc */
|
||||
break;
|
||||
|
||||
case WM_POINTERENTER:
|
||||
if (_gdk_win32_tablet_input_api != GDK_WIN32_TABLET_INPUT_API_WINPOINTER ||
|
||||
gdk_winpointer_should_forward_message (msg))
|
||||
{
|
||||
return_val = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (IS_POINTER_PRIMARY_WPARAM (msg->wParam))
|
||||
{
|
||||
current_root_x = pen_touch_cursor_position.x = GET_X_LPARAM (msg->lParam);
|
||||
current_root_y = pen_touch_cursor_position.y = GET_Y_LPARAM (msg->lParam);
|
||||
pen_touch_input = TRUE;
|
||||
last_digitizer_time = msg->time;
|
||||
}
|
||||
|
||||
if (pointer_grab != NULL &&
|
||||
!pointer_grab->implicit &&
|
||||
!pointer_grab->owner_events)
|
||||
g_set_object (&window, pointer_grab->native_window);
|
||||
|
||||
if (IS_POINTER_NEW_WPARAM (msg->wParam))
|
||||
{
|
||||
gdk_winpointer_input_events (display, window, NULL, msg);
|
||||
}
|
||||
|
||||
*ret_valp = 0;
|
||||
return_val = TRUE;
|
||||
break;
|
||||
|
||||
case WM_POINTERLEAVE:
|
||||
if (_gdk_win32_tablet_input_api != GDK_WIN32_TABLET_INPUT_API_WINPOINTER ||
|
||||
gdk_winpointer_should_forward_message (msg))
|
||||
{
|
||||
return_val = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (IS_POINTER_PRIMARY_WPARAM (msg->wParam))
|
||||
{
|
||||
current_root_x = pen_touch_cursor_position.x = GET_X_LPARAM (msg->lParam);
|
||||
current_root_y = pen_touch_cursor_position.y = GET_Y_LPARAM (msg->lParam);
|
||||
pen_touch_input = TRUE;
|
||||
last_digitizer_time = msg->time;
|
||||
}
|
||||
|
||||
if (!IS_POINTER_INRANGE_WPARAM (msg->wParam))
|
||||
{
|
||||
gdk_winpointer_input_events (display, window, NULL, msg);
|
||||
}
|
||||
else if (IS_POINTER_PRIMARY_WPARAM (msg->wParam) && mouse_window != NULL)
|
||||
{
|
||||
GdkDevice *event_device = NULL;
|
||||
guint32 event_time = 0;
|
||||
|
||||
if (gdk_winpointer_get_message_info (display, msg, &event_device, &event_time))
|
||||
{
|
||||
make_crossing_event(display,
|
||||
event_device,
|
||||
NULL,
|
||||
&pen_touch_cursor_position,
|
||||
event_time);
|
||||
}
|
||||
}
|
||||
|
||||
gdk_winpointer_interaction_ended (msg);
|
||||
|
||||
*ret_valp = 0;
|
||||
return_val = TRUE;
|
||||
break;
|
||||
|
||||
case WM_MOUSEWHEEL:
|
||||
case WM_MOUSEHWHEEL:
|
||||
GDK_NOTE (EVENTS, g_print (" %d", (short) HIWORD (msg->wParam)));
|
||||
@@ -2913,6 +3176,8 @@ gdk_event_translate (MSG *msg,
|
||||
gdk_event_set_seat (event, gdk_device_get_seat (device_manager_win32->core_pointer));
|
||||
gdk_event_set_pointer_emulated (event, FALSE);
|
||||
|
||||
_gdk_device_virtual_set_active (device_manager_win32->core_pointer, device_manager_win32->system_pointer);
|
||||
|
||||
_gdk_win32_append_event (gdk_event_copy (event));
|
||||
|
||||
/* Append the discrete version too */
|
||||
@@ -2931,44 +3196,6 @@ gdk_event_translate (MSG *msg,
|
||||
return_val = TRUE;
|
||||
break;
|
||||
|
||||
case WM_HSCROLL:
|
||||
/* Just print more debugging information, don't actually handle it. */
|
||||
GDK_NOTE (EVENTS,
|
||||
(g_print (" %s",
|
||||
(LOWORD (msg->wParam) == SB_ENDSCROLL ? "ENDSCROLL" :
|
||||
(LOWORD (msg->wParam) == SB_LEFT ? "LEFT" :
|
||||
(LOWORD (msg->wParam) == SB_RIGHT ? "RIGHT" :
|
||||
(LOWORD (msg->wParam) == SB_LINELEFT ? "LINELEFT" :
|
||||
(LOWORD (msg->wParam) == SB_LINERIGHT ? "LINERIGHT" :
|
||||
(LOWORD (msg->wParam) == SB_PAGELEFT ? "PAGELEFT" :
|
||||
(LOWORD (msg->wParam) == SB_PAGERIGHT ? "PAGERIGHT" :
|
||||
(LOWORD (msg->wParam) == SB_THUMBPOSITION ? "THUMBPOSITION" :
|
||||
(LOWORD (msg->wParam) == SB_THUMBTRACK ? "THUMBTRACK" :
|
||||
"???")))))))))),
|
||||
(LOWORD (msg->wParam) == SB_THUMBPOSITION ||
|
||||
LOWORD (msg->wParam) == SB_THUMBTRACK) ?
|
||||
(g_print (" %d", HIWORD (msg->wParam)), 0) : 0));
|
||||
break;
|
||||
|
||||
case WM_VSCROLL:
|
||||
/* Just print more debugging information, don't actually handle it. */
|
||||
GDK_NOTE (EVENTS,
|
||||
(g_print (" %s",
|
||||
(LOWORD (msg->wParam) == SB_ENDSCROLL ? "ENDSCROLL" :
|
||||
(LOWORD (msg->wParam) == SB_BOTTOM ? "BOTTOM" :
|
||||
(LOWORD (msg->wParam) == SB_TOP ? "TOP" :
|
||||
(LOWORD (msg->wParam) == SB_LINEDOWN ? "LINDOWN" :
|
||||
(LOWORD (msg->wParam) == SB_LINEUP ? "LINEUP" :
|
||||
(LOWORD (msg->wParam) == SB_PAGEDOWN ? "PAGEDOWN" :
|
||||
(LOWORD (msg->wParam) == SB_PAGEUP ? "PAGEUP" :
|
||||
(LOWORD (msg->wParam) == SB_THUMBPOSITION ? "THUMBPOSITION" :
|
||||
(LOWORD (msg->wParam) == SB_THUMBTRACK ? "THUMBTRACK" :
|
||||
"???")))))))))),
|
||||
(LOWORD (msg->wParam) == SB_THUMBPOSITION ||
|
||||
LOWORD (msg->wParam) == SB_THUMBTRACK) ?
|
||||
(g_print (" %d", HIWORD (msg->wParam)), 0) : 0));
|
||||
break;
|
||||
|
||||
case WM_MOUSEACTIVATE:
|
||||
{
|
||||
if (gdk_window_get_window_type (window) == GDK_WINDOW_TEMP
|
||||
@@ -2987,6 +3214,17 @@ gdk_event_translate (MSG *msg,
|
||||
|
||||
break;
|
||||
|
||||
case WM_POINTERACTIVATE:
|
||||
if (gdk_window_get_window_type (window) == GDK_WINDOW_TEMP ||
|
||||
!window->accept_focus ||
|
||||
_gdk_modal_blocked (gdk_window_get_toplevel (window)))
|
||||
{
|
||||
*ret_valp = PA_NOACTIVATE;
|
||||
return_val = TRUE;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case WM_KILLFOCUS:
|
||||
if (keyboard_grab != NULL &&
|
||||
!GDK_WINDOW_DESTROYED (keyboard_grab->window) &&
|
||||
@@ -3089,7 +3327,7 @@ gdk_event_translate (MSG *msg,
|
||||
do_show_window (window, msg->wParam == SC_MINIMIZE ? TRUE : FALSE);
|
||||
|
||||
if (msg->wParam == SC_RESTORE)
|
||||
_gdk_win32_window_invalidate_egl_framebuffer (window);
|
||||
gdk_win32_window_invalidate_egl_framebuffer (window);
|
||||
break;
|
||||
case SC_MAXIMIZE:
|
||||
impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
|
||||
@@ -3177,7 +3415,7 @@ gdk_event_translate (MSG *msg,
|
||||
{
|
||||
MINMAXINFO our_mmi;
|
||||
|
||||
_gdk_win32_window_invalidate_egl_framebuffer (window);
|
||||
gdk_win32_window_invalidate_egl_framebuffer (window);
|
||||
|
||||
if (_gdk_win32_window_fill_min_max_info (window, &our_mmi))
|
||||
{
|
||||
@@ -3565,6 +3803,14 @@ gdk_event_translate (MSG *msg,
|
||||
return_val = TRUE;
|
||||
break;
|
||||
|
||||
case WM_DESTROY:
|
||||
/* we have to call RemoveProp before the window is destroyed */
|
||||
if (_gdk_win32_tablet_input_api == GDK_WIN32_TABLET_INPUT_API_WINPOINTER)
|
||||
gdk_winpointer_finalize_window (window);
|
||||
|
||||
return_val = FALSE;
|
||||
break;
|
||||
|
||||
case WM_NCDESTROY:
|
||||
if ((pointer_grab != NULL && pointer_grab -> window == window) ||
|
||||
(keyboard_grab && keyboard_grab -> window == window))
|
||||
@@ -3734,14 +3980,21 @@ gdk_event_translate (MSG *msg,
|
||||
* instead
|
||||
*/
|
||||
if (LOWORD(msg->wParam) != WA_INACTIVE)
|
||||
_gdk_input_set_tablet_active ();
|
||||
{
|
||||
if (_gdk_win32_tablet_input_api == GDK_WIN32_TABLET_INPUT_API_WINTAB)
|
||||
_gdk_wintab_set_tablet_active ();
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_ACTIVATEAPP:
|
||||
GDK_NOTE (EVENTS, g_print (" %s thread: %" G_GINT64_FORMAT,
|
||||
msg->wParam ? "YES" : "NO",
|
||||
(gint64) msg->lParam));
|
||||
|
||||
// Clear graphics tablet state
|
||||
_gdk_input_ignore_core = 0;
|
||||
break;
|
||||
|
||||
case WM_NCHITTEST:
|
||||
/* TODO: pass all messages to DwmDefWindowProc() first! */
|
||||
return_val = handle_nchittest (msg->hwnd, window,
|
||||
@@ -3770,17 +4023,30 @@ gdk_event_translate (MSG *msg,
|
||||
HIWORD (msg->lParam)));
|
||||
/* Fall through */
|
||||
wintab:
|
||||
if (_gdk_win32_tablet_input_api != GDK_WIN32_TABLET_INPUT_API_WINTAB)
|
||||
break;
|
||||
|
||||
event = gdk_event_new (GDK_NOTHING);
|
||||
event->any.window = window;
|
||||
g_object_ref (window);
|
||||
|
||||
if (gdk_input_other_event (display, event, msg, window))
|
||||
if (gdk_wintab_input_events (display, event, msg, window))
|
||||
_gdk_win32_append_event (event);
|
||||
else
|
||||
gdk_event_free (event);
|
||||
|
||||
break;
|
||||
|
||||
case WM_TABLET_QUERYSYSTEMGESTURESTATUS:
|
||||
|
||||
*ret_valp = TABLET_DISABLE_PRESSANDHOLD |
|
||||
TABLET_DISABLE_PENTAPFEEDBACK |
|
||||
TABLET_DISABLE_PENBARRELFEEDBACK |
|
||||
TABLET_DISABLE_FLICKS |
|
||||
TABLET_DISABLE_FLICKFALLBACKKEYS;
|
||||
|
||||
return_val = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
done:
|
||||
|
||||
+852
-647
File diff suppressed because it is too large
Load Diff
@@ -32,62 +32,25 @@
|
||||
#include "gdkdisplayprivate.h"
|
||||
#include "gdkvisual.h"
|
||||
#include "gdkwindow.h"
|
||||
#include "gdkinternals.h"
|
||||
#include "gdkmain.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
struct _GdkWin32GLContext
|
||||
{
|
||||
GdkGLContext parent_instance;
|
||||
|
||||
/* WGL Context Items */
|
||||
HGLRC hglrc;
|
||||
HDC gl_hdc;
|
||||
guint need_alpha_bits : 1;
|
||||
|
||||
/* other items */
|
||||
guint is_attached : 1;
|
||||
guint do_frame_sync : 1;
|
||||
guint do_blit_swap : 1;
|
||||
|
||||
#ifdef GDK_WIN32_ENABLE_EGL
|
||||
/* EGL (Angle) Context Items */
|
||||
EGLContext egl_context;
|
||||
EGLConfig egl_config;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct _GdkWin32GLContextClass
|
||||
{
|
||||
GdkGLContextClass parent_class;
|
||||
};
|
||||
void
|
||||
gdk_win32_window_invalidate_egl_framebuffer (GdkWindow *window);
|
||||
|
||||
GdkGLContext *
|
||||
_gdk_win32_window_create_gl_context (GdkWindow *window,
|
||||
gboolean attached,
|
||||
GdkGLContext *share,
|
||||
GError **error);
|
||||
gdk_win32_window_create_gl_context (GdkWindow *window,
|
||||
gboolean attached,
|
||||
GdkGLContext *share,
|
||||
GError **error);
|
||||
|
||||
void
|
||||
_gdk_win32_window_invalidate_for_new_frame (GdkWindow *window,
|
||||
cairo_region_t *update_area);
|
||||
|
||||
void
|
||||
_gdk_win32_gl_context_end_frame (GdkGLContext *context,
|
||||
cairo_region_t *painted,
|
||||
cairo_region_t *damage);
|
||||
gdk_win32_window_invalidate_for_new_frame (GdkWindow *window,
|
||||
cairo_region_t *update_area);
|
||||
|
||||
gboolean
|
||||
_gdk_win32_display_make_gl_context_current (GdkDisplay *display,
|
||||
GdkGLContext *context);
|
||||
|
||||
gboolean
|
||||
_gdk_win32_gl_context_realize (GdkGLContext *context,
|
||||
GError **error);
|
||||
|
||||
void
|
||||
_gdk_win32_window_invalidate_egl_framebuffer (GdkWindow *window);
|
||||
gdk_win32_display_make_gl_context_current (GdkDisplay *display,
|
||||
GdkGLContext *context);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
@@ -36,12 +36,12 @@ HINSTANCE _gdk_dll_hinstance;
|
||||
HINSTANCE _gdk_app_hmodule;
|
||||
|
||||
gint _gdk_input_ignore_core;
|
||||
GdkWin32TabletInputAPI _gdk_win32_tablet_input_api;
|
||||
|
||||
HKL _gdk_input_locale;
|
||||
gboolean _gdk_input_locale_is_ime = FALSE;
|
||||
UINT _gdk_input_codepage;
|
||||
|
||||
gint _gdk_input_ignore_wintab = FALSE;
|
||||
gint _gdk_max_colors = 0;
|
||||
|
||||
GdkWin32ModalOpKind _modal_operation_in_progress = GDK_WIN32_MODAL_OP_NONE;
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Philip Zander
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _WIN64
|
||||
#define GDK_WIN32_COMPILE_FOR_WOW64 1
|
||||
#include "gdkkeys-win32-impl.c"
|
||||
#endif
|
||||
@@ -0,0 +1,548 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Philip Zander
|
||||
* Copyright (c) 2018 Microsoft
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/* NOTE: When compiling the 32-bit version of the library, in addition to being
|
||||
* compiled as a regular source file, this file is also included by
|
||||
* gdkkeys-win32-impl-wow64.c to generate an alternate version of the code
|
||||
* intended for running on a 64-bit kernel. Because of the way keyboard layout
|
||||
* DLLs work on Windows, we have to generate two versions and decide at runtime
|
||||
* which code path to execute. You can read more about the specifics below, in
|
||||
* the section about KBD_LONG_POINTER. */
|
||||
|
||||
#include "gdkkeys-win32.h"
|
||||
|
||||
#ifndef GDK_WIN32_COMPILE_FOR_WOW64
|
||||
#define GDK_WIN32_COMPILE_FOR_WOW64 0
|
||||
#endif
|
||||
|
||||
/* This is our equivalent of the KBD_LONG_POINTER macro in Microsoft's kbd.h.
|
||||
*
|
||||
* A KBD_LONG_POINTER represents a pointer native to the *host*.
|
||||
* I.e. 32 bits on 32-bit Windows and 64 bits on 64-bit Windows.
|
||||
*
|
||||
* This is *not* the same as the the bitness of the application, since it is
|
||||
* possible to execute 32-bit binaries on either a 32-bit *or* a 64-bit host.
|
||||
* On a 64-bit host, KBD_LONG_PTR will be 64-bits, even if the application
|
||||
* itself is 32-bit. (Whereas on a 32-bit host, it will be 32-bit.)
|
||||
*
|
||||
* For clarity, here is an overview of the bit-size of KBD_LONG_POINTER on all
|
||||
* possible host & app combinations:
|
||||
*
|
||||
* Host 32 64
|
||||
* App +-----------
|
||||
* 32 | 32 64
|
||||
* 64 | - 64
|
||||
*
|
||||
* In the official MS headers, KBD_LONG_POINTER is implemented via a macro
|
||||
* which expands to the attribute `__ptr64` if the keyboard driver is
|
||||
* compiled for a 64 bit host. Unfortunately, `__ptr64` is only
|
||||
* supported by MSVC. We use a union here as a workaround.
|
||||
*
|
||||
* For all KBD_LONG_POINTERs, we define an alias starting with "KLP".
|
||||
* Our naming schema (inspired by the Windows headers) is thus the following:
|
||||
* - FOO: The type FOO itself
|
||||
* - PFOO: Regular pointer to the type FOO
|
||||
* - KLPFOO: Keyboard Long Pointer to the type FOO
|
||||
*/
|
||||
|
||||
#if GDK_WIN32_COMPILE_FOR_WOW64
|
||||
#define DEFINE_KBD_LONG_POINTER(type) \
|
||||
typedef union { \
|
||||
P##type ptr; \
|
||||
UINT64 _align; \
|
||||
} KLP##type
|
||||
#else
|
||||
#define DEFINE_KBD_LONG_POINTER(type) \
|
||||
typedef union { \
|
||||
P##type ptr; \
|
||||
} KLP##type
|
||||
#endif
|
||||
|
||||
DEFINE_KBD_LONG_POINTER (USHORT);
|
||||
DEFINE_KBD_LONG_POINTER (VOID);
|
||||
|
||||
/* Driver definitions
|
||||
* See
|
||||
* https://github.com/microsoft/windows-rs/blob/0.28.0/crates/deps/sys/src/Windows/Win32/UI/Input/KeyboardAndMouse/mod.rs
|
||||
*
|
||||
* For more information on how these structures work, see also:
|
||||
* https://github.com/microsoft/Windows-driver-samples/tree/f0adcda012820b1cd44a8b3a1953baf478029738/input/layout
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
BYTE Vk;
|
||||
BYTE ModBits;
|
||||
} VK_TO_BIT, *PVK_TO_BIT;
|
||||
|
||||
DEFINE_KBD_LONG_POINTER (VK_TO_BIT);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
KLPVK_TO_BIT pVkToBit;
|
||||
WORD wMaxModBits;
|
||||
BYTE ModNumber[1];
|
||||
} MODIFIERS, *PMODIFIERS;
|
||||
|
||||
DEFINE_KBD_LONG_POINTER (MODIFIERS);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
BYTE Vsc;
|
||||
USHORT Vk;
|
||||
} VSC_VK, *PVSC_VK;
|
||||
|
||||
DEFINE_KBD_LONG_POINTER (VSC_VK);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
BYTE Vk;
|
||||
BYTE Vsc;
|
||||
} VK_VSC, *PVK_VSC;
|
||||
|
||||
DEFINE_KBD_LONG_POINTER (VK_VSC);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
BYTE VirtualKey;
|
||||
BYTE Attributes;
|
||||
WCHAR wch[1];
|
||||
} VK_TO_WCHARS, *PVK_TO_WCHARS;
|
||||
|
||||
DEFINE_KBD_LONG_POINTER (VK_TO_WCHARS);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
KLPVK_TO_WCHARS pVkToWchars;
|
||||
BYTE nModifications;
|
||||
BYTE cbSize;
|
||||
} VK_TO_WCHAR_TABLE, *PVK_TO_WCHAR_TABLE;
|
||||
|
||||
DEFINE_KBD_LONG_POINTER (VK_TO_WCHAR_TABLE);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
DWORD dwBoth;
|
||||
WCHAR wchComposed;
|
||||
USHORT uFlags;
|
||||
} DEADKEY, *PDEADKEY;
|
||||
|
||||
DEFINE_KBD_LONG_POINTER (DEADKEY);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
KLPMODIFIERS pCharModifiers;
|
||||
KLPVK_TO_WCHAR_TABLE pVkToWcharTable;
|
||||
KLPDEADKEY pDeadKey;
|
||||
KLPVOID pKeyNames;
|
||||
KLPVOID pKeyNamesExt;
|
||||
KLPVOID pKeyNamesDead;
|
||||
KLPUSHORT pusVSCtoVK;
|
||||
BYTE bMaxVSCtoVK;
|
||||
KLPVSC_VK pVSCtoVK_E0;
|
||||
KLPVSC_VK pVSCtoVK_E1;
|
||||
DWORD fLocaleFlags;
|
||||
BYTE nLgMaxd;
|
||||
BYTE cbLgEntry;
|
||||
KLPVOID pLigature;
|
||||
} KBDTABLES, *PKBDTABLES;
|
||||
|
||||
DEFINE_KBD_LONG_POINTER (KBDTABLES);
|
||||
|
||||
/* End of declarations */
|
||||
|
||||
static BYTE
|
||||
keystate_to_modbits (GdkWin32KeymapLayoutInfo *info,
|
||||
const BYTE keystate[256])
|
||||
{
|
||||
PKBDTABLES tables = (PKBDTABLES) info->tables;
|
||||
PVK_TO_BIT vk_to_bit;
|
||||
BYTE result = 0;
|
||||
int i;
|
||||
|
||||
g_return_val_if_fail (tables != NULL, 0);
|
||||
|
||||
vk_to_bit = tables->pCharModifiers.ptr->pVkToBit.ptr;
|
||||
|
||||
for (i = 0; vk_to_bit[i].Vk != 0; ++i)
|
||||
if (keystate[vk_to_bit[i].Vk] & 0x80)
|
||||
result |= vk_to_bit[i].ModBits;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static BYTE
|
||||
modbits_to_level (GdkWin32KeymapLayoutInfo *info,
|
||||
BYTE modbits)
|
||||
{
|
||||
PKBDTABLES tables = (PKBDTABLES) info->tables;
|
||||
PMODIFIERS modifiers;
|
||||
|
||||
g_return_val_if_fail (tables != NULL, 0);
|
||||
|
||||
modifiers = tables->pCharModifiers.ptr;
|
||||
if (modbits > modifiers->wMaxModBits)
|
||||
return 0;
|
||||
|
||||
return modifiers->ModNumber[modbits];
|
||||
}
|
||||
|
||||
#define POPCOUNT(b) (!!(b & 0x01) + !!(b & 0x02) + !!(b & 0x04) + !!(b & 0x08) + \
|
||||
!!(b & 0x10) + !!(b & 0x20) + !!(b & 0x40) + !!(b & 0x80))
|
||||
|
||||
/*
|
||||
* vk_to_char_fuzzy:
|
||||
*
|
||||
* For a given key and keystate, return the best-fit character and the
|
||||
* modifiers used to produce it. Note that not all modifiers need to be used,
|
||||
* because some modifier combination aren't actually mapped in the keyboard
|
||||
* layout (for example the Ctrl key typically has no effect, unless used in
|
||||
* combination with Alt). Such modifiers will not be consumed.
|
||||
*
|
||||
* 'Best-fit' means 'consume as many modifiers as possibe'.
|
||||
*
|
||||
* For example (assuming a neutral keystate):
|
||||
*
|
||||
* - Shift + a -> 'A', consumed_mod_bits: [Shift]
|
||||
* - Ctrl + a -> 'a', consumed_mod_bits: []
|
||||
* - Ctrl + Shift + a -> 'A', consumed_mod_bits: [Shift]
|
||||
*
|
||||
* If capslock is active, the result could be:
|
||||
*
|
||||
* - Shift + a -> 'a', consumed_mod_bits: [Shift]
|
||||
*
|
||||
* The caller can supply additional modifiers to be added to the
|
||||
* keystate in `extra_mod_bits`.
|
||||
*
|
||||
* If the key combination results in a dead key, `is_dead` will be set to TRUE,
|
||||
* otherwise it will be set to FALSE.
|
||||
*/
|
||||
static WCHAR
|
||||
vk_to_char_fuzzy (GdkWin32KeymapLayoutInfo *info,
|
||||
const BYTE keystate[256],
|
||||
BYTE extra_mod_bits,
|
||||
BYTE *consumed_mod_bits,
|
||||
gboolean *is_dead,
|
||||
BYTE vk)
|
||||
{
|
||||
PKBDTABLES tables = (PKBDTABLES) info->tables;
|
||||
|
||||
PVK_TO_WCHAR_TABLE wch_tables;
|
||||
PVK_TO_WCHAR_TABLE wch_table;
|
||||
PVK_TO_WCHARS entry;
|
||||
|
||||
int table_index;
|
||||
int entry_index;
|
||||
int n_levels;
|
||||
int entry_size;
|
||||
|
||||
/* Initialize with defaults */
|
||||
if (consumed_mod_bits)
|
||||
*consumed_mod_bits = 0;
|
||||
if (is_dead)
|
||||
*is_dead = FALSE;
|
||||
|
||||
g_return_val_if_fail (tables != NULL, WCH_NONE);
|
||||
|
||||
wch_tables = tables->pVkToWcharTable.ptr;
|
||||
|
||||
table_index = info->vk_lookup_table[vk].table;
|
||||
entry_index = info->vk_lookup_table[vk].index;
|
||||
|
||||
if (table_index == -1 || entry_index == -1)
|
||||
return WCH_NONE;
|
||||
|
||||
wch_table = &wch_tables[table_index];
|
||||
|
||||
n_levels = wch_table->nModifications;
|
||||
entry_size = wch_table->cbSize;
|
||||
|
||||
entry = (PVK_TO_WCHARS) ((PBYTE) wch_table->pVkToWchars.ptr
|
||||
+ entry_size*entry_index);
|
||||
|
||||
if (entry->VirtualKey == vk)
|
||||
{
|
||||
BYTE modbits;
|
||||
WCHAR best_char = WCH_NONE;
|
||||
BYTE best_modifiers = 0;
|
||||
int best_score = -1;
|
||||
gboolean best_is_dead = FALSE;
|
||||
int level;
|
||||
|
||||
/* Add modbits of currently pressed keys. */
|
||||
modbits = keystate_to_modbits (info, keystate);
|
||||
/* Add modbits supplied by caller. */
|
||||
modbits |= extra_mod_bits;
|
||||
|
||||
/* Take toggled keys into account. For example, capslock normally inverts the
|
||||
* state of KBDSHIFT (with some exceptions). */
|
||||
|
||||
/* Key supporting capslock */
|
||||
if ((entry->Attributes & CAPLOK) &&
|
||||
/* Ignore capslock if any modifiers other than shift are pressed.
|
||||
* E.g. on the German layout, CapsLock + AltGr + q is the same as
|
||||
* AltGr + q ('@'), but NOT the same as Shift + AltGr + q (not mapped). */
|
||||
!(modbits & ~KBDSHIFT) &&
|
||||
(keystate[VK_CAPITAL] & 0x01))
|
||||
modbits ^= KBDSHIFT;
|
||||
|
||||
/* Key supporting combination of capslock + altgr */
|
||||
if ((entry->Attributes & CAPLOKALTGR) &&
|
||||
(modbits & KBDALTGR) &&
|
||||
(keystate[VK_CAPITAL] & 0x01))
|
||||
modbits ^= KBDSHIFT;
|
||||
|
||||
/* In the Swiss German layout, CapsLock + key is different from Shift + key
|
||||
* for some keys. For such keys, Capslock toggles the KBDCTRL bit. */
|
||||
if ((entry->Attributes & SGCAPS) &&
|
||||
(keystate[VK_CAPITAL] & 0x01))
|
||||
modbits ^= KBDCTRL;
|
||||
|
||||
/* I'm not totally sure how kanalok behaves, for now I assume that there
|
||||
* aren't any special cases. */
|
||||
if ((entry->Attributes & KANALOK) &&
|
||||
(keystate[VK_KANA] & 0x01))
|
||||
modbits ^= KBDKANA;
|
||||
|
||||
/* We try to find the entry with the most matching modifiers */
|
||||
for (level = 0; level < n_levels; ++level)
|
||||
{
|
||||
BYTE candidate_modbits = info->level_to_modbits[level];
|
||||
gboolean candidate_is_dead = FALSE;
|
||||
WCHAR c;
|
||||
int score;
|
||||
|
||||
if (candidate_modbits & ~modbits)
|
||||
continue;
|
||||
|
||||
c = entry->wch[level];
|
||||
if (c == WCH_DEAD)
|
||||
{
|
||||
/* Next entry contains the undead keys */
|
||||
PVK_TO_WCHARS next_entry;
|
||||
next_entry = (PVK_TO_WCHARS) ((PBYTE) wch_table->pVkToWchars.ptr
|
||||
+ entry_size * (entry_index + 1));
|
||||
c = next_entry->wch[level];
|
||||
candidate_is_dead = TRUE;
|
||||
}
|
||||
|
||||
if (c == WCH_DEAD || c == WCH_LGTR || c == WCH_NONE)
|
||||
continue;
|
||||
|
||||
score = POPCOUNT (candidate_modbits & modbits);
|
||||
if (score > best_score)
|
||||
{
|
||||
best_score = score;
|
||||
best_char = c;
|
||||
best_modifiers = candidate_modbits;
|
||||
best_is_dead = candidate_is_dead;
|
||||
}
|
||||
}
|
||||
|
||||
if (consumed_mod_bits)
|
||||
*consumed_mod_bits = best_modifiers;
|
||||
|
||||
if (is_dead)
|
||||
*is_dead = best_is_dead;
|
||||
|
||||
return best_char;
|
||||
}
|
||||
|
||||
return WCH_NONE;
|
||||
}
|
||||
|
||||
static void
|
||||
init_vk_lookup_table (GdkWin32KeymapLayoutInfo *info)
|
||||
{
|
||||
PKBDTABLES tables = (PKBDTABLES) info->tables;
|
||||
PVK_TO_WCHAR_TABLE wch_tables;
|
||||
PMODIFIERS modifiers;
|
||||
int i, vk, table_idx;
|
||||
|
||||
g_return_if_fail (tables != NULL);
|
||||
|
||||
wch_tables = tables->pVkToWcharTable.ptr;
|
||||
|
||||
/* Initialize empty table */
|
||||
memset (info->vk_lookup_table, -1, sizeof (info->vk_lookup_table));
|
||||
|
||||
/* Initialize level -> modbits lookup table */
|
||||
memset (info->level_to_modbits, 0, sizeof(info->level_to_modbits));
|
||||
info->max_level = 0;
|
||||
|
||||
modifiers = tables->pCharModifiers.ptr;
|
||||
for (i = 0; i <= modifiers->wMaxModBits; ++i)
|
||||
{
|
||||
if (modifiers->ModNumber[i] != SHFT_INVALID &&
|
||||
modifiers->ModNumber[i] != 0 /* Workaround for buggy layouts*/)
|
||||
{
|
||||
if (modifiers->ModNumber[i] > info->max_level)
|
||||
info->max_level = modifiers->ModNumber[i];
|
||||
info->level_to_modbits[modifiers->ModNumber[i]] = i;
|
||||
}
|
||||
}
|
||||
|
||||
info->max_modbit_value = modifiers->wMaxModBits;
|
||||
|
||||
/* For convenience, we add 256 identity-mapped entries corresponding to the VKs.
|
||||
* This allows us to return a pointer to them from the `gdk_keysym_to_key_entry`
|
||||
* function.
|
||||
*/
|
||||
|
||||
for (vk = 0; vk < 256; ++vk)
|
||||
{
|
||||
GdkWin32KeymapKeyEntry key_entry = {0};
|
||||
key_entry.vk = vk;
|
||||
key_entry.mod_bits = 0;
|
||||
key_entry.next = -1;
|
||||
g_array_append_val (info->key_entries, key_entry);
|
||||
}
|
||||
|
||||
/* Special entry for ISO_Left_Tab */
|
||||
{
|
||||
GdkWin32KeymapKeyEntry key_entry = {0};
|
||||
key_entry.vk = VK_TAB;
|
||||
key_entry.mod_bits = KBDSHIFT;
|
||||
key_entry.next = -1;
|
||||
g_array_append_val (info->key_entries, key_entry);
|
||||
}
|
||||
|
||||
/* Initialize generic vk <-> char tables */
|
||||
|
||||
for (table_idx = 0; ; ++table_idx)
|
||||
{
|
||||
PVK_TO_WCHAR_TABLE wch_table = &wch_tables[table_idx];
|
||||
int entry_size;
|
||||
int n_levels;
|
||||
int entry_idx;
|
||||
|
||||
if (wch_table->pVkToWchars.ptr == NULL)
|
||||
break;
|
||||
|
||||
entry_size = wch_table->cbSize;
|
||||
n_levels = wch_table->nModifications;
|
||||
|
||||
for (entry_idx = 0; ; ++entry_idx)
|
||||
{
|
||||
PVK_TO_WCHARS entry;
|
||||
int level;
|
||||
|
||||
entry = (PVK_TO_WCHARS) ((PBYTE) wch_table->pVkToWchars.ptr
|
||||
+ entry_size * entry_idx);
|
||||
|
||||
if (entry->VirtualKey == 0)
|
||||
break;
|
||||
|
||||
/* Lookup table to find entry for a VK in O(1). */
|
||||
|
||||
info->vk_lookup_table[entry->VirtualKey].table = table_idx;
|
||||
info->vk_lookup_table[entry->VirtualKey].index = entry_idx;
|
||||
|
||||
/* Create reverse lookup entries to find a VK+modifier combinations
|
||||
* that results in a given character. */
|
||||
for (level = 0; level < n_levels; ++level)
|
||||
{
|
||||
GdkWin32KeymapKeyEntry key_entry = {0};
|
||||
WCHAR c = entry->wch[level];
|
||||
int inserted_idx;
|
||||
gintptr next_idx;
|
||||
|
||||
key_entry.vk = entry->VirtualKey;
|
||||
key_entry.mod_bits = info->level_to_modbits[level];
|
||||
|
||||
/* There can be multiple combinations that produce the same character.
|
||||
* We store all of them in a linked list.
|
||||
* Check if we already have an entry for the character, so we can chain
|
||||
* them together. */
|
||||
if (g_hash_table_lookup_extended (info->reverse_lookup_table,
|
||||
GINT_TO_POINTER (c),
|
||||
NULL, (gpointer*)&next_idx))
|
||||
{
|
||||
key_entry.next = next_idx;
|
||||
}
|
||||
else
|
||||
{
|
||||
key_entry.next = -1;
|
||||
}
|
||||
|
||||
/* We store the KeyEntry in an array. In the hash table we only store
|
||||
* the index. */
|
||||
|
||||
g_array_append_val (info->key_entries, key_entry);
|
||||
inserted_idx = info->key_entries->len - 1;
|
||||
|
||||
g_hash_table_insert (info->reverse_lookup_table,
|
||||
GINT_TO_POINTER (c),
|
||||
GINT_TO_POINTER (inserted_idx));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
load_layout_dll (const char *dll,
|
||||
GdkWin32KeymapLayoutInfo *info)
|
||||
{
|
||||
typedef KLPKBDTABLES (*KbdLayerDescriptor)(VOID);
|
||||
|
||||
HMODULE lib;
|
||||
KbdLayerDescriptor func;
|
||||
KLPKBDTABLES tables;
|
||||
|
||||
g_return_val_if_fail (dll != NULL, FALSE);
|
||||
|
||||
lib = LoadLibraryA (dll);
|
||||
if (lib == NULL)
|
||||
goto fail1;
|
||||
|
||||
func = (KbdLayerDescriptor) GetProcAddress (lib, "KbdLayerDescriptor");
|
||||
if (func == NULL)
|
||||
goto fail2;
|
||||
|
||||
tables = func();
|
||||
|
||||
info->lib = lib;
|
||||
info->tables = (PKBDTABLES) tables.ptr;
|
||||
|
||||
return TRUE;
|
||||
|
||||
fail2:
|
||||
FreeLibrary (lib);
|
||||
fail1:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#if GDK_WIN32_COMPILE_FOR_WOW64
|
||||
#define GDK_WIN32_KEYMAP_IMPL_NAME gdkwin32_keymap_impl_wow64
|
||||
#else
|
||||
#define GDK_WIN32_KEYMAP_IMPL_NAME gdkwin32_keymap_impl
|
||||
#endif
|
||||
|
||||
const GdkWin32KeymapImpl GDK_WIN32_KEYMAP_IMPL_NAME =
|
||||
{
|
||||
load_layout_dll,
|
||||
init_vk_lookup_table,
|
||||
keystate_to_modbits,
|
||||
modbits_to_level,
|
||||
vk_to_char_fuzzy
|
||||
};
|
||||
+652
-1289
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,168 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Philip Zander
|
||||
* Copyright (c) 2018 Microsoft
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <glib.h>
|
||||
#include <windows.h>
|
||||
|
||||
/* For lookup table VK -> chars */
|
||||
typedef struct
|
||||
{
|
||||
int table;
|
||||
int index;
|
||||
} GdkWin32KeymapTableAndIndex;
|
||||
|
||||
/* For reverse lookup char -> VKs */
|
||||
typedef struct
|
||||
{
|
||||
BYTE mod_bits;
|
||||
BYTE vk;
|
||||
|
||||
/* Index of next KeyEntry. -1 if there is no next entry. */
|
||||
int next;
|
||||
} GdkWin32KeymapKeyEntry;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
HKL handle;
|
||||
|
||||
/* Keyboard layout identifier */
|
||||
char name[KL_NAMELENGTH];
|
||||
|
||||
/* Path of the layout DLL */
|
||||
char *file;
|
||||
|
||||
/* Handle of the layout DLL */
|
||||
HINSTANCE lib;
|
||||
|
||||
/* The actual conversion tables provided by the layout DLL.
|
||||
*
|
||||
* This is a pointer to a KBDTABLES structure. The exact definition
|
||||
* of this structure depends on the kernel on which the executable
|
||||
* run and can in general only be determined at runtime. That's why
|
||||
* we have to use a generic gpointer instead of the actual type here.
|
||||
*
|
||||
* See comment on GdkWin32KeymapImpl below for more information. */
|
||||
gpointer tables;
|
||||
|
||||
/* VK -> chars lookup table so we don't have to do a linear scan
|
||||
* every time we look up a key. */
|
||||
GdkWin32KeymapTableAndIndex vk_lookup_table[256];
|
||||
|
||||
/* List of entries for reverse (char ->VKs) lookup. */
|
||||
GArray *key_entries;
|
||||
|
||||
/* Reverse lookup table (char -> VKs). Key: Unichar. Value: int.
|
||||
* The value is used to index into the key_entries array. The key_entries
|
||||
* array can contain multiple consecutive entries for a given char.
|
||||
* The end of the list for the char is marked by a key entry that has
|
||||
* mod_bits and vk set to 0xFF. */
|
||||
GHashTable *reverse_lookup_table;
|
||||
|
||||
/* Map level to modbits */
|
||||
BYTE level_to_modbits[256];
|
||||
|
||||
/* Max Number of levels */
|
||||
BYTE max_level;
|
||||
|
||||
/* Maximum possible value of a modbits bitset. */
|
||||
BYTE max_modbit_value;
|
||||
|
||||
} GdkWin32KeymapLayoutInfo;
|
||||
|
||||
/* Some keyboard driver constants
|
||||
* See https://github.com/microsoft/windows-rs/blob/0.28.0/crates/deps/sys/src/Windows/Win32/UI/Input/KeyboardAndMouse/mod.rs
|
||||
*/
|
||||
|
||||
/* Modifier bits */
|
||||
#define KBDBASE 0x00
|
||||
#define KBDSHIFT 0x01
|
||||
#define KBDCTRL 0x02
|
||||
#define KBDALT 0x04
|
||||
#define KBDKANA 0x08
|
||||
#define KBDROYA 0x10
|
||||
#define KBDLOYA 0x20
|
||||
#define KBDGRPSELTAP 0x80
|
||||
|
||||
#define KBDALTGR (KBDCTRL| KBDALT)
|
||||
|
||||
/* */
|
||||
#define SHFT_INVALID 0x0F
|
||||
|
||||
/* Char table constants */
|
||||
#define WCH_NONE 0xF000
|
||||
#define WCH_DEAD 0xF001
|
||||
#define WCH_LGTR 0xF002
|
||||
|
||||
/* Char table flags */
|
||||
#define CAPLOK 0x01
|
||||
#define SGCAPS 0x02
|
||||
#define CAPLOKALTGR 0x04
|
||||
#define KANALOK 0x08
|
||||
#define GRPSELTAP 0x80
|
||||
|
||||
/* IMPORTANT:
|
||||
*
|
||||
* Keyboard layout DLLs are dependent on the host architecture.
|
||||
*
|
||||
* - 32 bit systems have just one 32 bit DLL in System32.
|
||||
* - 64 bit systems contain two versions of each layout DLL: One in System32
|
||||
* for 64-bit applications, and one in SysWOW64 for 32-bit applications.
|
||||
*
|
||||
* Here comes the tricky part:
|
||||
*
|
||||
* The 32-bit DLL in SysWOW64 is *not* identical to the DLL you would find
|
||||
* on a true 32 bit system, because all the pointers there are declared with
|
||||
* the attribute `__ptr64` (which means they are 64 bits wide, but only the
|
||||
* lower 32 bits are used).
|
||||
*
|
||||
* This leads to the following problems:
|
||||
*
|
||||
* (1) GCC does not support `__ptr64`
|
||||
* (2) When compiling the 32-bit library, we need two versions of the same code
|
||||
* and decide at run-time which one to execute, because we can't know at
|
||||
* compile time whether we will be running on a true 32-bit system, or on
|
||||
* WOW64.
|
||||
*
|
||||
* To solve this problem, we generate code for both cases (see
|
||||
* gdkkeys-win32-impl.c + gdkkeys-win32-impl-wow64.c) and encapsulate
|
||||
* the resulting functions in a struct of type GdkWin32KeymapImpl,
|
||||
* allowing us to select the correct implementation at runtime.
|
||||
*
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
gboolean (*load_layout_dll) (const char *dll,
|
||||
GdkWin32KeymapLayoutInfo *info);
|
||||
void (*init_vk_lookup_table) (GdkWin32KeymapLayoutInfo *info);
|
||||
BYTE (*keystate_to_modbits) (GdkWin32KeymapLayoutInfo *info,
|
||||
const BYTE keystate[256]);
|
||||
BYTE (*modbits_to_level) (GdkWin32KeymapLayoutInfo *info,
|
||||
BYTE modbits);
|
||||
WCHAR (*vk_to_char_fuzzy) (GdkWin32KeymapLayoutInfo *info,
|
||||
const BYTE keystate[256],
|
||||
BYTE extra_mod_bits,
|
||||
BYTE *consumed_mod_bits,
|
||||
gboolean *is_dead,
|
||||
BYTE vk);
|
||||
} GdkWin32KeymapImpl;
|
||||
@@ -49,23 +49,6 @@
|
||||
|
||||
static gboolean gdk_synchronize = FALSE;
|
||||
|
||||
static gboolean dummy;
|
||||
|
||||
const GOptionEntry _gdk_windowing_args[] = {
|
||||
{ "sync", 0, 0, G_OPTION_ARG_NONE, &gdk_synchronize,
|
||||
/* Description of --sync in --help output */ N_("Don't batch GDI requests"), NULL },
|
||||
{ "no-wintab", 0, 0, G_OPTION_ARG_NONE, &_gdk_input_ignore_wintab,
|
||||
/* Description of --no-wintab in --help output */ N_("Don't use the Wintab API for tablet support"), NULL },
|
||||
{ "ignore-wintab", 0, 0, G_OPTION_ARG_NONE, &_gdk_input_ignore_wintab,
|
||||
/* Description of --ignore-wintab in --help output */ N_("Same as --no-wintab"), NULL },
|
||||
{ "use-wintab", 0, 0, G_OPTION_ARG_NONE, &dummy,
|
||||
/* Description of --use-wintab in --help output */ N_("Do use the Wintab API [default]"), NULL },
|
||||
{ "max-colors", 0, 0, G_OPTION_ARG_INT, &_gdk_max_colors,
|
||||
/* Description of --max-colors=COLORS in --help output */ N_("Size of the palette in 8 bit mode"),
|
||||
/* Placeholder in --max-colors=COLORS in --help output */ N_("COLORS") },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
BOOL WINAPI
|
||||
DllMain (HINSTANCE hinstDLL,
|
||||
DWORD dwReason,
|
||||
@@ -81,11 +64,6 @@ _gdk_win32_windowing_init (void)
|
||||
{
|
||||
gchar buf[10];
|
||||
|
||||
if (getenv ("GDK_IGNORE_WINTAB") != NULL)
|
||||
_gdk_input_ignore_wintab = TRUE;
|
||||
else if (getenv ("GDK_USE_WINTAB") != NULL)
|
||||
_gdk_input_ignore_wintab = FALSE;
|
||||
|
||||
if (gdk_synchronize)
|
||||
GdiSetBatchLimit (1);
|
||||
|
||||
|
||||
@@ -523,7 +523,7 @@ populate_monitor_devices_from_display_config (GPtrArray *monitors)
|
||||
|
||||
refresh = &dispconf_paths[path_index].targetInfo.refreshRate;
|
||||
gdk_monitor_set_refresh_rate (mon,
|
||||
refresh->Numerator * 1000 / refresh->Denominator);
|
||||
refresh->Numerator * (UINT64) 1000 / refresh->Denominator);
|
||||
}
|
||||
|
||||
g_free (dispconf_paths);
|
||||
@@ -618,7 +618,7 @@ enum_monitor (HMONITOR hmonitor,
|
||||
GdkWin32Monitor *w32mon;
|
||||
GdkMonitor *mon;
|
||||
GdkRectangle rect;
|
||||
guint scale;
|
||||
int scale;
|
||||
|
||||
memset (&dd_monitor, 0, sizeof (dd_monitor));
|
||||
dd_monitor.cb = sizeof (dd_monitor);
|
||||
@@ -888,13 +888,15 @@ _gdk_win32_display_get_monitor_list (GdkWin32Display *win32_display)
|
||||
{
|
||||
GdkWin32Monitor *m;
|
||||
GdkRectangle rect;
|
||||
int scale;
|
||||
|
||||
m = g_ptr_array_index (data.monitors, i);
|
||||
gdk_monitor_get_geometry (GDK_MONITOR (m), &rect);
|
||||
scale = gdk_monitor_get_scale_factor (GDK_MONITOR (m));
|
||||
|
||||
/* Calculate offset */
|
||||
gdk_monitor_get_geometry (GDK_MONITOR (m), &rect);
|
||||
_gdk_offset_x = MAX (_gdk_offset_x, -rect.x);
|
||||
_gdk_offset_y = MAX (_gdk_offset_y, -rect.y);
|
||||
_gdk_offset_x = MAX (_gdk_offset_x, -rect.x * scale);
|
||||
_gdk_offset_y = MAX (_gdk_offset_y, -rect.y * scale);
|
||||
}
|
||||
|
||||
GDK_NOTE (MISC, g_print ("Multi-monitor offset: (%d,%d)\n",
|
||||
@@ -905,16 +907,19 @@ _gdk_win32_display_get_monitor_list (GdkWin32Display *win32_display)
|
||||
{
|
||||
GdkWin32Monitor *m;
|
||||
GdkRectangle rect;
|
||||
int scale = 0;
|
||||
|
||||
m = g_ptr_array_index (data.monitors, i);
|
||||
|
||||
gdk_monitor_get_geometry (GDK_MONITOR (m), &rect);
|
||||
rect.x += _gdk_offset_x;
|
||||
rect.y += _gdk_offset_y;
|
||||
scale = gdk_monitor_get_scale_factor (GDK_MONITOR (m));
|
||||
|
||||
rect.x += _gdk_offset_x / scale;
|
||||
rect.y += _gdk_offset_y / scale;
|
||||
gdk_monitor_set_position (GDK_MONITOR (m), rect.x, rect.y);
|
||||
|
||||
m->work_rect.x += _gdk_offset_x;
|
||||
m->work_rect.y += _gdk_offset_y;
|
||||
m->work_rect.x += _gdk_offset_x / scale;
|
||||
m->work_rect.y += _gdk_offset_y / scale;
|
||||
|
||||
GDK_NOTE (MISC, g_print ("Monitor %d: %dx%d@%+d%+d\n", i,
|
||||
rect.width, rect.height, rect.x, rect.y));
|
||||
|
||||
@@ -163,10 +163,18 @@ struct _GdkColormapPrivateWin32
|
||||
GdkColorInfo *info;
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
GDK_WIN32_TABLET_INPUT_API_NONE = 0,
|
||||
GDK_WIN32_TABLET_INPUT_API_WINTAB,
|
||||
GDK_WIN32_TABLET_INPUT_API_WINPOINTER
|
||||
} GdkWin32TabletInputAPI;
|
||||
|
||||
GType _gdk_gc_win32_get_type (void);
|
||||
|
||||
gulong _gdk_win32_get_next_tick (gulong suggested_tick);
|
||||
|
||||
BOOL _gdk_win32_get_cursor_pos (LPPOINT lpPoint);
|
||||
|
||||
void _gdk_window_init_position (GdkWindow *window);
|
||||
void _gdk_window_move_resize_child (GdkWindow *window,
|
||||
gint x,
|
||||
@@ -262,6 +270,8 @@ void _gdk_other_api_failed (const gchar *where,
|
||||
#define WIN32_GDI_FAILED(api) WIN32_API_FAILED (api)
|
||||
#define OTHER_API_FAILED(api) _gdk_other_api_failed (G_STRLOC, api)
|
||||
|
||||
#define WIN32_API_FAILED_LOG_ONCE(api) G_STMT_START { static gboolean logged = 0; if (!logged) { _gdk_win32_api_failed (G_STRLOC , api); logged = 1; }} G_STMT_END
|
||||
|
||||
/* These two macros call a GDI or other Win32 API and if the return
|
||||
* value is zero or NULL, print a warning message. The majority of GDI
|
||||
* calls return zero or NULL on failure. The value of the macros is nonzero
|
||||
@@ -287,6 +297,7 @@ extern HINSTANCE _gdk_dll_hinstance;
|
||||
extern HINSTANCE _gdk_app_hmodule;
|
||||
|
||||
extern gint _gdk_input_ignore_core;
|
||||
extern GdkWin32TabletInputAPI _gdk_win32_tablet_input_api;
|
||||
|
||||
/* These are thread specific, but GDK/win32 works OK only when invoked
|
||||
* from a single thread anyway.
|
||||
@@ -326,7 +337,6 @@ void _gdk_win32_end_modal_call (GdkWin32ModalOpKind kind);
|
||||
|
||||
|
||||
/* Options */
|
||||
extern gboolean _gdk_input_ignore_wintab;
|
||||
extern gint _gdk_max_colors;
|
||||
|
||||
#define GDK_WIN32_COLORMAP_DATA(cmap) ((GdkColormapPrivateWin32 *) GDK_COLORMAP (cmap)->windowing_data)
|
||||
@@ -441,6 +451,7 @@ guint8 _gdk_win32_keymap_get_active_group (GdkWin32Keymap *keymap);
|
||||
guint8 _gdk_win32_keymap_get_rshift_scancode (GdkWin32Keymap *keymap);
|
||||
void _gdk_win32_keymap_set_active_layout (GdkWin32Keymap *keymap,
|
||||
HKL hkl);
|
||||
GdkModifierType _gdk_win32_keymap_get_mod_mask (GdkWin32Keymap *keymap);
|
||||
|
||||
|
||||
GdkKeymap *_gdk_win32_display_get_keymap (GdkDisplay *display);
|
||||
@@ -531,4 +542,12 @@ void _gdk_win32_windowing_init (void);
|
||||
void _gdk_dnd_init (void);
|
||||
void _gdk_events_init (GdkDisplay *display);
|
||||
|
||||
typedef enum _GdkWin32ProcessorCheckType
|
||||
{
|
||||
GDK_WIN32_ARM64,
|
||||
GDK_WIN32_WOW64,
|
||||
} GdkWin32ProcessorCheckType;
|
||||
|
||||
gboolean _gdk_win32_check_processor (GdkWin32ProcessorCheckType check_type);
|
||||
|
||||
#endif /* __GDK_PRIVATE_WIN32_H__ */
|
||||
|
||||
@@ -55,6 +55,15 @@ struct _GdkWin32DragContext
|
||||
gint start_x; /* Coordinates of the drag start, in GDK space */
|
||||
gint start_y;
|
||||
DWORD last_key_state; /* Key state from last event */
|
||||
HMONITOR last_monitor; /* While dragging we keep track of the monitor the cursor
|
||||
is currently on. As the cursor moves between monitors,
|
||||
we move the invisible dnd ipc window to the top-left
|
||||
corner of the current monitor, because OLE2 does not
|
||||
work correctly if the source window and the dest window
|
||||
are on monitors with different scales (say one is 125%
|
||||
and the other 100%) and the drag-initiating application
|
||||
(effectively driving the DND) is not per-monitor DPI aware
|
||||
*/
|
||||
|
||||
/* Just like context->targets, but an array, and with format IDs
|
||||
* stored inside.
|
||||
|
||||
+108
-97
@@ -303,10 +303,10 @@ gdk_win32_window_get_queued_window_rect (GdkWindow *window,
|
||||
_gdk_win32_adjust_client_rect (window, &window_rect);
|
||||
|
||||
/* Convert GDK screen coordinates to W32 desktop coordinates */
|
||||
window_rect.left -= _gdk_offset_x * impl->window_scale;
|
||||
window_rect.right -= _gdk_offset_x * impl->window_scale;
|
||||
window_rect.top -= _gdk_offset_y * impl->window_scale;
|
||||
window_rect.bottom -= _gdk_offset_y * impl->window_scale;
|
||||
window_rect.left -= _gdk_offset_x;
|
||||
window_rect.right -= _gdk_offset_x;
|
||||
window_rect.top -= _gdk_offset_y;
|
||||
window_rect.bottom -= _gdk_offset_y;
|
||||
|
||||
*return_window_rect = window_rect;
|
||||
}
|
||||
@@ -555,7 +555,6 @@ RegisterGdkClass (GdkWindowType wtype, GdkWindowTypeHint wtype_hint)
|
||||
static ATOM klassTOPLEVEL = 0;
|
||||
static ATOM klassCHILD = 0;
|
||||
static ATOM klassTEMP = 0;
|
||||
static ATOM klassTEMPSHADOW = 0;
|
||||
static HICON hAppIcon = NULL;
|
||||
static HICON hAppIconSm = NULL;
|
||||
static WNDCLASSEXW wcl;
|
||||
@@ -652,34 +651,16 @@ RegisterGdkClass (GdkWindowType wtype, GdkWindowTypeHint wtype_hint)
|
||||
break;
|
||||
|
||||
case GDK_WINDOW_TEMP:
|
||||
if ((wtype_hint == GDK_WINDOW_TYPE_HINT_MENU) ||
|
||||
(wtype_hint == GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU) ||
|
||||
(wtype_hint == GDK_WINDOW_TYPE_HINT_POPUP_MENU))
|
||||
if (klassTEMP == 0)
|
||||
{
|
||||
if (klassTEMPSHADOW == 0)
|
||||
{
|
||||
wcl.lpszClassName = L"gdkWindowTempShadow";
|
||||
wcl.style |= CS_SAVEBITS;
|
||||
wcl.style |= 0x00020000; /* CS_DROPSHADOW */
|
||||
|
||||
ONCE_PER_CLASS ();
|
||||
klassTEMPSHADOW = RegisterClassExW (&wcl);
|
||||
}
|
||||
|
||||
klass = klassTEMPSHADOW;
|
||||
wcl.lpszClassName = L"gdkWindowTemp";
|
||||
wcl.style |= CS_SAVEBITS;
|
||||
ONCE_PER_CLASS ();
|
||||
klassTEMP = RegisterClassExW (&wcl);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (klassTEMP == 0)
|
||||
{
|
||||
wcl.lpszClassName = L"gdkWindowTemp";
|
||||
wcl.style |= CS_SAVEBITS;
|
||||
ONCE_PER_CLASS ();
|
||||
klassTEMP = RegisterClassExW (&wcl);
|
||||
}
|
||||
|
||||
klass = klassTEMP;
|
||||
}
|
||||
klass = klassTEMP;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -860,8 +841,8 @@ _gdk_win32_display_create_window_impl (GdkDisplay *display,
|
||||
|
||||
AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
|
||||
|
||||
real_x = (window->x - offset_x) * impl->window_scale;
|
||||
real_y = (window->y - offset_y) * impl->window_scale;
|
||||
real_x = window->x * impl->window_scale - offset_x;
|
||||
real_y = window->y * impl->window_scale - offset_y;
|
||||
|
||||
if (window->window_type == GDK_WINDOW_TOPLEVEL)
|
||||
{
|
||||
@@ -885,8 +866,8 @@ _gdk_win32_display_create_window_impl (GdkDisplay *display,
|
||||
window_width = impl->unscaled_width;
|
||||
window_height = impl->unscaled_height;
|
||||
/* use given position for initial placement, native coordinates */
|
||||
x = (window->x + window->parent->abs_x - offset_x) * impl->window_scale;
|
||||
y = (window->y + window->parent->abs_y - offset_y) * impl->window_scale;
|
||||
x = (window->x + window->parent->abs_x) * impl->window_scale;
|
||||
y = (window->y + window->parent->abs_y) * impl->window_scale;
|
||||
}
|
||||
|
||||
if (attributes_mask & GDK_WA_TITLE)
|
||||
@@ -904,13 +885,13 @@ _gdk_win32_display_create_window_impl (GdkDisplay *display,
|
||||
if (impl->type_hint == GDK_WINDOW_TYPE_HINT_UTILITY)
|
||||
dwExStyle |= WS_EX_TOOLWINDOW;
|
||||
|
||||
/* WS_EX_TRANSPARENT means "try draw this window last, and ignore input".
|
||||
* It's the last part we're after. We don't want DND indicator to accept
|
||||
* input, because that will make it a potential drop target, and if it's
|
||||
* under the mouse cursor, this will kill any DND.
|
||||
/* WS_EX_LAYERED | WS_EX_TRANSPARENT makes the window transparent w.r.t.
|
||||
* pointer input: the system will direct all pointer input to the window
|
||||
* below. We don't want a DND indicator to accept pointer input, because
|
||||
* that will make it a potential drop target.
|
||||
*/
|
||||
if (impl->type_hint == GDK_WINDOW_TYPE_HINT_DND)
|
||||
dwExStyle |= WS_EX_TRANSPARENT;
|
||||
dwExStyle |= WS_EX_LAYERED | WS_EX_TRANSPARENT;
|
||||
|
||||
klass = RegisterGdkClass (window->window_type, impl->type_hint);
|
||||
|
||||
@@ -971,8 +952,8 @@ _gdk_win32_display_create_window_impl (GdkDisplay *display,
|
||||
GDK_NOTE (MISC, g_print ("... \"%s\" %dx%d@%+d%+d %p = %p\n",
|
||||
title,
|
||||
window_width, window_height,
|
||||
window->x - offset_x,
|
||||
window->y - offset_y,
|
||||
window->x,
|
||||
window->y,
|
||||
hparent,
|
||||
GDK_WINDOW_HWND (window)));
|
||||
|
||||
@@ -994,6 +975,9 @@ _gdk_win32_display_create_window_impl (GdkDisplay *display,
|
||||
if (attributes_mask & GDK_WA_CURSOR)
|
||||
gdk_window_set_cursor (window, attributes->cursor);
|
||||
|
||||
if (_gdk_win32_tablet_input_api == GDK_WIN32_TABLET_INPUT_API_WINPOINTER)
|
||||
gdk_winpointer_initialize_window (window);
|
||||
|
||||
_gdk_win32_window_enable_transparency (window);
|
||||
}
|
||||
|
||||
@@ -1293,10 +1277,10 @@ show_window_internal (GdkWindow *window,
|
||||
|
||||
exstyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
|
||||
|
||||
/* Use SetWindowPos to show transparent windows so automatic redraws
|
||||
* in other windows can be suppressed.
|
||||
/* If we have to show an input-only window,
|
||||
* redraws can be safely skipped.
|
||||
*/
|
||||
if (exstyle & WS_EX_TRANSPARENT)
|
||||
if (window->input_only)
|
||||
{
|
||||
UINT flags = SWP_SHOWWINDOW | SWP_NOREDRAW | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER;
|
||||
|
||||
@@ -1354,8 +1338,8 @@ show_window_internal (GdkWindow *window,
|
||||
{
|
||||
GdkWindow *owner = window_impl->transient_owner;
|
||||
/* Center on transient parent */
|
||||
center_on_rect.left = (owner->x - _gdk_offset_x) * window_impl->window_scale;
|
||||
center_on_rect.top = (owner->y - _gdk_offset_y) * window_impl->window_scale;
|
||||
center_on_rect.left = owner->x * window_impl->window_scale - _gdk_offset_x;
|
||||
center_on_rect.top = owner->y * window_impl->window_scale - _gdk_offset_y;
|
||||
center_on_rect.right = center_on_rect.left + owner->width * window_impl->window_scale;
|
||||
center_on_rect.bottom = center_on_rect.top + owner->height * window_impl->window_scale;
|
||||
|
||||
@@ -1432,7 +1416,6 @@ show_window_internal (GdkWindow *window,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (window->state & GDK_WINDOW_STATE_FULLSCREEN)
|
||||
{
|
||||
gdk_window_fullscreen (window);
|
||||
@@ -1505,10 +1488,10 @@ gdk_win32_window_hide (GdkWindow *window)
|
||||
if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TOPLEVEL)
|
||||
ShowOwnedPopups (GDK_WINDOW_HWND (window), FALSE);
|
||||
|
||||
/* Use SetWindowPos to hide transparent windows so automatic redraws
|
||||
* in other windows can be suppressed.
|
||||
/* If we have to hide an input-only window,
|
||||
* readraws can be safely skipped.
|
||||
*/
|
||||
if (GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE) & WS_EX_TRANSPARENT)
|
||||
if (window->input_only)
|
||||
{
|
||||
SetWindowPos (GDK_WINDOW_HWND (window), SWP_NOZORDER_SPECIFIED,
|
||||
0, 0, 0, 0,
|
||||
@@ -1568,13 +1551,13 @@ gdk_win32_window_move (GdkWindow *window,
|
||||
GDK_NOTE (MISC, g_print ("... SetWindowPos(%p,NULL,%d,%d,0,0,"
|
||||
"NOACTIVATE|NOSIZE|NOZORDER)\n",
|
||||
GDK_WINDOW_HWND (window),
|
||||
(x - _gdk_offset_x) * impl->window_scale,
|
||||
(y - _gdk_offset_y) * impl->window_scale));
|
||||
x * impl->window_scale - _gdk_offset_x,
|
||||
y * impl->window_scale - _gdk_offset_y));
|
||||
|
||||
API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window),
|
||||
SWP_NOZORDER_SPECIFIED,
|
||||
(x - _gdk_offset_x) * impl->window_scale,
|
||||
(y - _gdk_offset_y) * impl->window_scale,
|
||||
x * impl->window_scale - _gdk_offset_x,
|
||||
y * impl->window_scale - _gdk_offset_y,
|
||||
0, 0,
|
||||
SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER));
|
||||
}
|
||||
@@ -1667,15 +1650,15 @@ gdk_win32_window_move_resize_internal (GdkWindow *window,
|
||||
GDK_NOTE (MISC, g_print ("... SetWindowPos(%p,NULL,%d,%d,%ld,%ld,"
|
||||
"NOACTIVATE|NOZORDER)\n",
|
||||
GDK_WINDOW_HWND (window),
|
||||
(x - _gdk_offset_x) * impl->window_scale,
|
||||
(y - _gdk_offset_y) * impl->window_scale,
|
||||
x * impl->window_scale - _gdk_offset_x,
|
||||
y * impl->window_scale - _gdk_offset_y,
|
||||
outer_rect.right - outer_rect.left,
|
||||
outer_rect.bottom - outer_rect.top));
|
||||
|
||||
API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window),
|
||||
SWP_NOZORDER_SPECIFIED,
|
||||
(x - _gdk_offset_x) * impl->window_scale,
|
||||
(y - _gdk_offset_y) * impl->window_scale,
|
||||
x * impl->window_scale - _gdk_offset_x,
|
||||
y * impl->window_scale - _gdk_offset_y,
|
||||
outer_rect.right - outer_rect.left,
|
||||
outer_rect.bottom - outer_rect.top,
|
||||
SWP_NOACTIVATE | SWP_NOZORDER));
|
||||
@@ -1706,7 +1689,7 @@ gdk_win32_window_move_resize (GdkWindow *window,
|
||||
}
|
||||
else
|
||||
{
|
||||
_gdk_win32_window_invalidate_egl_framebuffer (window);
|
||||
gdk_win32_window_invalidate_egl_framebuffer (window);
|
||||
if (with_move)
|
||||
{
|
||||
gdk_win32_window_move_resize_internal (window, x, y, width, height);
|
||||
@@ -2337,10 +2320,10 @@ gdk_win32_window_get_geometry (GdkWindow *window,
|
||||
|
||||
if (gdk_screen_get_root_window (screen) == parent)
|
||||
{
|
||||
rect.left += _gdk_offset_x * impl->window_scale;
|
||||
rect.top += _gdk_offset_y * impl->window_scale;
|
||||
rect.right += _gdk_offset_x * impl->window_scale;
|
||||
rect.bottom += _gdk_offset_y * impl->window_scale;
|
||||
rect.left += _gdk_offset_x;
|
||||
rect.top += _gdk_offset_y;
|
||||
rect.right += _gdk_offset_x;
|
||||
rect.bottom += _gdk_offset_y;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2437,19 +2420,19 @@ gdk_win32_window_get_frame_extents (GdkWindow *window,
|
||||
hwnd = GDK_WINDOW_HWND (window);
|
||||
API_CALL (GetWindowRect, (hwnd, &r));
|
||||
|
||||
/* Initialize to real, unscaled size */
|
||||
rect->x = r.left + _gdk_offset_x * impl->window_scale;
|
||||
rect->y = r.top + _gdk_offset_y * impl->window_scale;
|
||||
/* Initialize GdkRectangle to unscaled coordinates */
|
||||
rect->x = r.left + _gdk_offset_x;
|
||||
rect->y = r.top + _gdk_offset_y;
|
||||
rect->width = (r.right - r.left);
|
||||
rect->height = (r.bottom - r.top);
|
||||
|
||||
/* Extend width and height to ensure that they cover the real size when de-scaled,
|
||||
* and replace everyting with scaled values
|
||||
* and replace everything with scaled values
|
||||
*/
|
||||
rect->width = (rect->width + rect->x % impl->window_scale + impl->window_scale - 1) / impl->window_scale;
|
||||
rect->height = (rect->height + rect->y % impl->window_scale + impl->window_scale - 1) / impl->window_scale;
|
||||
rect->x = r.left / impl->window_scale + _gdk_offset_x;
|
||||
rect->y = r.top / impl->window_scale + _gdk_offset_y;
|
||||
rect->x = r.left / impl->window_scale;
|
||||
rect->y = r.top / impl->window_scale;
|
||||
|
||||
GDK_NOTE (MISC, g_print ("gdk_window_get_frame_extents: %p: %ldx%ld@%+ld%+ld\n",
|
||||
GDK_WINDOW_HWND (window),
|
||||
@@ -2803,6 +2786,7 @@ _gdk_win32_window_update_style_bits (GdkWindow *window)
|
||||
GdkWindowImplWin32 *impl = (GdkWindowImplWin32 *)window->impl;
|
||||
GdkWMDecoration decorations;
|
||||
LONG old_style, new_style, old_exstyle, new_exstyle;
|
||||
gboolean needs_basic_layering = FALSE;
|
||||
gboolean all;
|
||||
RECT rect, before, after;
|
||||
gboolean was_topmost;
|
||||
@@ -2858,7 +2842,18 @@ _gdk_win32_window_update_style_bits (GdkWindow *window)
|
||||
else
|
||||
impl->layered = FALSE;
|
||||
|
||||
if (impl->layered)
|
||||
/* DND windows need to have the WS_EX_TRANSPARENT | WS_EX_LAYERED styles
|
||||
* set so to behave in input passthrough mode. That's essential for DND
|
||||
* indicators.
|
||||
*/
|
||||
if (!impl->layered &&
|
||||
GDK_WINDOW_HWND (window) != NULL &&
|
||||
impl->type_hint == GDK_WINDOW_TYPE_HINT_DND)
|
||||
{
|
||||
needs_basic_layering = TRUE;
|
||||
}
|
||||
|
||||
if (impl->layered || needs_basic_layering)
|
||||
new_exstyle |= WS_EX_LAYERED;
|
||||
else
|
||||
new_exstyle &= ~WS_EX_LAYERED;
|
||||
@@ -2875,6 +2870,19 @@ _gdk_win32_window_update_style_bits (GdkWindow *window)
|
||||
update_single_bit (&new_style, all, decorations & GDK_DECOR_MAXIMIZE, WS_MAXIMIZEBOX);
|
||||
}
|
||||
|
||||
if (needs_basic_layering)
|
||||
{
|
||||
/* SetLayeredWindowAttributes may have been already called, e.g. to set an opacity level.
|
||||
* We only have to call the API in case it has never been called before on the window.
|
||||
*/
|
||||
if (SetLastError(0),
|
||||
!GetLayeredWindowAttributes (GDK_WINDOW_HWND (window), NULL, NULL, NULL) &&
|
||||
GetLastError() == 0)
|
||||
{
|
||||
API_CALL (SetLayeredWindowAttributes, (GDK_WINDOW_HWND (window), 0, 255, LWA_ALPHA));
|
||||
}
|
||||
}
|
||||
|
||||
if (old_style == new_style && old_exstyle == new_exstyle )
|
||||
{
|
||||
GDK_NOTE (MISC, g_print ("_gdk_win32_window_update_style_bits: %p: no change\n",
|
||||
@@ -3953,8 +3961,8 @@ redraw_indicator (gpointer user_data)
|
||||
|
||||
last_draw = draw_indicator (context, context->draw_timestamp);
|
||||
|
||||
window_position.x = (context->indicator_window_rect.x - _gdk_offset_x) * impl->window_scale;
|
||||
window_position.y = (context->indicator_window_rect.y - _gdk_offset_y) * impl->window_scale;
|
||||
window_position.x = context->indicator_window_rect.x * impl->window_scale - _gdk_offset_x;
|
||||
window_position.y = context->indicator_window_rect.y * impl->window_scale - _gdk_offset_y;
|
||||
window_size.cx = context->indicator_window_rect.width * impl->window_scale;
|
||||
window_size.cy = context->indicator_window_rect.height * impl->window_scale;
|
||||
|
||||
@@ -4611,8 +4619,8 @@ setup_drag_move_resize_context (GdkWindow *window,
|
||||
GDK_NOTE (MISC, g_print ("W32 WM unmaximized window placement is %ld x %ld @ %ld : %ld\n",
|
||||
placement.rcNormalPosition.right - placement.rcNormalPosition.left,
|
||||
placement.rcNormalPosition.bottom - placement.rcNormalPosition.top,
|
||||
placement.rcNormalPosition.left + _gdk_offset_x * impl->window_scale,
|
||||
placement.rcNormalPosition.top + _gdk_offset_y * impl->window_scale));
|
||||
placement.rcNormalPosition.left + _gdk_offset_x,
|
||||
placement.rcNormalPosition.top + _gdk_offset_y));
|
||||
|
||||
unmax_width = placement.rcNormalPosition.right - placement.rcNormalPosition.left;
|
||||
unmax_height = placement.rcNormalPosition.bottom - placement.rcNormalPosition.top;
|
||||
@@ -4623,17 +4631,17 @@ setup_drag_move_resize_context (GdkWindow *window,
|
||||
if (offsetx * impl->window_scale < (shadow_unmax_width / 2) &&
|
||||
offsety * impl->window_scale < (shadow_unmax_height / 2))
|
||||
{
|
||||
placement.rcNormalPosition.top = (root_y - offsety + impl->margins.top - _gdk_offset_y) * impl->window_scale;
|
||||
placement.rcNormalPosition.top = (root_y - offsety + impl->margins.top) * impl->window_scale - _gdk_offset_y;
|
||||
placement.rcNormalPosition.bottom = placement.rcNormalPosition.top + unmax_height;
|
||||
|
||||
if (left_half)
|
||||
{
|
||||
placement.rcNormalPosition.left = (root_x - offsetx + impl->margins.left - _gdk_offset_x) * impl->window_scale;
|
||||
placement.rcNormalPosition.left = (root_x - offsetx + impl->margins.left) * impl->window_scale - _gdk_offset_x;
|
||||
placement.rcNormalPosition.right = placement.rcNormalPosition.left + unmax_width;
|
||||
}
|
||||
else
|
||||
{
|
||||
placement.rcNormalPosition.right = (root_x + offsetx + impl->margins.right - _gdk_offset_x) * impl->window_scale;
|
||||
placement.rcNormalPosition.right = (root_x + offsetx + impl->margins.right) * impl->window_scale - _gdk_offset_x;
|
||||
placement.rcNormalPosition.left = placement.rcNormalPosition.right - unmax_width;
|
||||
}
|
||||
}
|
||||
@@ -4641,22 +4649,22 @@ setup_drag_move_resize_context (GdkWindow *window,
|
||||
{
|
||||
placement.rcNormalPosition.left = (root_x * impl->window_scale) -
|
||||
(unmax_width / 2) -
|
||||
(_gdk_offset_x * impl->window_scale);
|
||||
_gdk_offset_x;
|
||||
|
||||
if (offsety * impl->window_scale < shadow_unmax_height / 2)
|
||||
placement.rcNormalPosition.top = (root_y - offsety + impl->margins.top - _gdk_offset_y) * impl->window_scale;
|
||||
placement.rcNormalPosition.top = (root_y - offsety + impl->margins.top) * impl->window_scale - _gdk_offset_y;
|
||||
else
|
||||
placement.rcNormalPosition.top = (root_y * impl->window_scale) -
|
||||
(unmax_height / 2) -
|
||||
(_gdk_offset_y * impl->window_scale);
|
||||
_gdk_offset_y;
|
||||
|
||||
placement.rcNormalPosition.right = placement.rcNormalPosition.left + unmax_width;
|
||||
placement.rcNormalPosition.bottom = placement.rcNormalPosition.top + unmax_height;
|
||||
}
|
||||
|
||||
GDK_NOTE (MISC, g_print ("Unmaximized window will be at %ld : %ld\n",
|
||||
placement.rcNormalPosition.left + _gdk_offset_x * impl->window_scale,
|
||||
placement.rcNormalPosition.top + _gdk_offset_y * impl->window_scale));
|
||||
placement.rcNormalPosition.left + _gdk_offset_x,
|
||||
placement.rcNormalPosition.top + _gdk_offset_y));
|
||||
|
||||
API_CALL (SetWindowPlacement, (GDK_WINDOW_HWND (window), &placement));
|
||||
}
|
||||
@@ -4774,7 +4782,7 @@ gdk_win32_window_end_move_resize_drag (GdkWindow *window)
|
||||
GdkW32DragMoveResizeContext *context = &impl->drag_move_resize_context;
|
||||
|
||||
if (context->op == GDK_WIN32_DRAGOP_RESIZE)
|
||||
_gdk_win32_window_invalidate_egl_framebuffer (window);
|
||||
gdk_win32_window_invalidate_egl_framebuffer (window);
|
||||
|
||||
context->op = GDK_WIN32_DRAGOP_NONE;
|
||||
|
||||
@@ -4839,10 +4847,10 @@ gdk_win32_get_window_size_and_position_from_client_rect (GdkWindow *window,
|
||||
_gdk_win32_adjust_client_rect (window, window_rect);
|
||||
|
||||
/* Convert GDK screen coordinates to W32 desktop coordinates */
|
||||
window_rect->left -= _gdk_offset_x * impl->window_scale;
|
||||
window_rect->right -= _gdk_offset_x * impl->window_scale;
|
||||
window_rect->top -= _gdk_offset_y * impl->window_scale;
|
||||
window_rect->bottom -= _gdk_offset_y * impl->window_scale;
|
||||
window_rect->left -= _gdk_offset_x;
|
||||
window_rect->right -= _gdk_offset_x;
|
||||
window_rect->top -= _gdk_offset_y;
|
||||
window_rect->bottom -= _gdk_offset_y;
|
||||
|
||||
window_position->x = window_rect->left;
|
||||
window_position->y = window_rect->top;
|
||||
@@ -5295,7 +5303,7 @@ gdk_win32_window_unmaximize (GdkWindow *window)
|
||||
GDK_WINDOW_HWND (window),
|
||||
_gdk_win32_window_state_to_string (window->state)));
|
||||
|
||||
_gdk_win32_window_invalidate_egl_framebuffer (window);
|
||||
gdk_win32_window_invalidate_egl_framebuffer (window);
|
||||
|
||||
if (GDK_WINDOW_IS_MAPPED (window))
|
||||
GtkShowWindow (window, SW_RESTORE);
|
||||
@@ -5392,7 +5400,7 @@ gdk_win32_window_unfullscreen (GdkWindow *window)
|
||||
|
||||
impl->hint_flags = fi->hint_flags;
|
||||
SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE, fi->style);
|
||||
_gdk_win32_window_invalidate_egl_framebuffer (window);
|
||||
gdk_win32_window_invalidate_egl_framebuffer (window);
|
||||
API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), HWND_NOTOPMOST,
|
||||
fi->r.left, fi->r.top,
|
||||
fi->r.right - fi->r.left, fi->r.bottom - fi->r.top,
|
||||
@@ -5814,13 +5822,13 @@ gdk_win32_window_show_window_menu (GdkWindow *window,
|
||||
}
|
||||
|
||||
gdk_event_get_root_coords (event, &event_x, &event_y);
|
||||
x = event_x - _gdk_offset_x;
|
||||
y = event_y - _gdk_offset_y;
|
||||
x = event_x * impl->window_scale - _gdk_offset_x;
|
||||
y = event_y * impl->window_scale - _gdk_offset_y;
|
||||
|
||||
SendMessage (GDK_WINDOW_HWND (window),
|
||||
WM_SYSMENU,
|
||||
0,
|
||||
MAKELPARAM (x * impl->window_scale, y * impl->window_scale));
|
||||
MAKELPARAM (x, y));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -6295,8 +6303,8 @@ gdk_window_impl_win32_class_init (GdkWindowImplWin32Class *klass)
|
||||
impl_class->get_property = _gdk_win32_window_get_property;
|
||||
impl_class->change_property = _gdk_win32_window_change_property;
|
||||
impl_class->delete_property = _gdk_win32_window_delete_property;
|
||||
impl_class->create_gl_context = _gdk_win32_window_create_gl_context;
|
||||
impl_class->invalidate_for_new_frame = _gdk_win32_window_invalidate_for_new_frame;
|
||||
impl_class->create_gl_context = gdk_win32_window_create_gl_context;
|
||||
impl_class->invalidate_for_new_frame = gdk_win32_window_invalidate_for_new_frame;
|
||||
impl_class->get_scale_factor = _gdk_win32_window_get_scale_factor;
|
||||
impl_class->get_unscaled_size = _gdk_win32_window_get_unscaled_size;
|
||||
}
|
||||
@@ -6320,8 +6328,8 @@ gdk_win32_window_get_handle (GdkWindow *window)
|
||||
#ifdef GDK_WIN32_ENABLE_EGL
|
||||
EGLSurface
|
||||
_gdk_win32_window_get_egl_surface (GdkWindow *window,
|
||||
EGLConfig config,
|
||||
gboolean is_dummy)
|
||||
EGLConfig config,
|
||||
gboolean is_dummy)
|
||||
{
|
||||
EGLSurface surface;
|
||||
GdkWin32Display *display = GDK_WIN32_DISPLAY (gdk_window_get_display (window));
|
||||
@@ -6341,7 +6349,10 @@ _gdk_win32_window_get_egl_surface (GdkWindow *window,
|
||||
else
|
||||
{
|
||||
if (impl->egl_surface == EGL_NO_SURFACE)
|
||||
impl->egl_surface = eglCreateWindowSurface (display->egl_disp, config, display->gl_hwnd, NULL);
|
||||
impl->egl_surface = eglCreateWindowSurface (display->egl_disp,
|
||||
config,
|
||||
GDK_WINDOW_HWND (window),
|
||||
NULL);
|
||||
|
||||
return impl->egl_surface;
|
||||
}
|
||||
|
||||
@@ -26,15 +26,12 @@
|
||||
#define __GDK_WINDOW_WIN32_H__
|
||||
|
||||
#include "gdk/win32/gdkprivate-win32.h"
|
||||
#include "gdk/win32/gdkglcontext-win32.h"
|
||||
#include "gdk/gdkwindowimpl.h"
|
||||
#include "gdk/gdkcursor.h"
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#ifdef GDK_WIN32_ENABLE_EGL
|
||||
#include <epoxy/egl.h>
|
||||
#endif
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/* Window implementation for Win32
|
||||
|
||||
@@ -30,9 +30,13 @@ all: \
|
||||
gdk-win32.lib \
|
||||
gdk.res
|
||||
|
||||
gdk_win32_DEPS = \
|
||||
hid.lib
|
||||
|
||||
gdk_win32_OBJECTS = \
|
||||
gdkcursor-win32.obj \
|
||||
gdkdevice-win32.obj \
|
||||
gdkdevice-winpointer.obj \
|
||||
gdkdevice-wintab.obj \
|
||||
gdkdevicemanager-win32.obj \
|
||||
gdkdnd-win32.obj \
|
||||
@@ -43,6 +47,8 @@ gdk_win32_OBJECTS = \
|
||||
gdkglobals-win32.obj \
|
||||
gdkinput.obj \
|
||||
gdkkeys-win32.obj \
|
||||
gdkkeys-win32-impl.obj \
|
||||
gdkkeys-win32-impl-wow64.obj \
|
||||
gdkmain-win32.obj \
|
||||
gdkproperty-win32.obj \
|
||||
gdkscreen-win32.obj \
|
||||
@@ -61,7 +67,7 @@ gdk.res : rc\gdk.rc
|
||||
rc -DBUILDNUMBER=0 -r -fo gdk.res rc\gdk.rc
|
||||
|
||||
gdk-win32.lib : $(gdk_win32_OBJECTS)
|
||||
lib -out:gdk-win32.lib $(gdk_win32_OBJECTS)
|
||||
lib -out:gdk-win32.lib $(gdk_win32_DEPS) $(gdk_win32_OBJECTS)
|
||||
|
||||
clean::
|
||||
del *.obj
|
||||
|
||||
@@ -3,6 +3,7 @@ gdk_win32_sources = files(
|
||||
'gdkdevicemanager-win32.c',
|
||||
'gdkdevice-virtual.c',
|
||||
'gdkdevice-win32.c',
|
||||
'gdkdevice-winpointer.c',
|
||||
'gdkdevice-wintab.c',
|
||||
'gdkdisplay-win32.c',
|
||||
'gdkdisplaymanager-win32.c',
|
||||
@@ -12,6 +13,8 @@ gdk_win32_sources = files(
|
||||
'gdkglcontext-win32.c',
|
||||
'gdkglobals-win32.c',
|
||||
'gdkkeys-win32.c',
|
||||
'gdkkeys-win32-impl.c',
|
||||
'gdkkeys-win32-impl-wow64.c',
|
||||
'gdkmain-win32.c',
|
||||
'gdkmonitor-win32.c',
|
||||
'gdkproperty-win32.c',
|
||||
@@ -47,7 +50,8 @@ install_headers(gdk_win32_public_headers, subdir: 'gtk-3.0/gdk/win32')
|
||||
install_headers('gdkwin32.h', subdir: 'gtk-3.0/gdk')
|
||||
|
||||
gdk_win32_deps = [ # FIXME
|
||||
pangowin32_dep
|
||||
pangowin32_dep,
|
||||
meson.get_compiler('c').find_library('hid')
|
||||
]
|
||||
|
||||
libgdk_win32 = static_library('gdk-win32',
|
||||
|
||||
@@ -0,0 +1,324 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2021 the GTK team
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
/* This code is derived from portions provided by the mingw-w64 project
|
||||
* (mingw-w64.org), originally licensed under the Zope Public License
|
||||
* (ZPL) version 2.1, with modifications made on May 12, 2021.
|
||||
* Legal notice of the Zope Public License version 2.1 follows:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions in source code must retain the accompanying copyright
|
||||
* notice, this list of conditions, and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the accompanying
|
||||
* copyright notice, this list of conditions, and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Names of the copyright holders must not be used to endorse or promote
|
||||
* products derived from this software without prior written permission
|
||||
* from the copyright holders.
|
||||
* 4. The right to distribute this software or to use it for any purpose does
|
||||
* not give you the right to use Servicemarks (sm) or Trademarks (tm) of
|
||||
* the copyright holders. Use of them is covered by separate agreement
|
||||
* with the copyright holders.
|
||||
* 5. If any files are modified, you must cause the modified files to carry
|
||||
* prominent notices stating that you changed the files and the date of
|
||||
* any change.
|
||||
*/
|
||||
|
||||
#ifndef POINTER_FLAG_NONE
|
||||
|
||||
#include <windows.h>
|
||||
#include <tchar.h>
|
||||
|
||||
#define WM_POINTERDEVICECHANGE 0x238
|
||||
#define WM_POINTERDEVICEINRANGE 0x239
|
||||
#define WM_POINTERDEVICEOUTOFRANGE 0x23a
|
||||
|
||||
#define WM_NCPOINTERUPDATE 0x0241
|
||||
#define WM_NCPOINTERDOWN 0x0242
|
||||
#define WM_NCPOINTERUP 0x0243
|
||||
#define WM_POINTERUPDATE 0x0245
|
||||
#define WM_POINTERDOWN 0x0246
|
||||
#define WM_POINTERUP 0x0247
|
||||
#define WM_POINTERENTER 0x0249
|
||||
#define WM_POINTERLEAVE 0x024a
|
||||
#define WM_POINTERACTIVATE 0x024b
|
||||
#define WM_POINTERCAPTURECHANGED 0x024c
|
||||
#define WM_TOUCHHITTESTING 0x024d
|
||||
#define WM_POINTERWHEEL 0x024e
|
||||
#define WM_POINTERHWHEEL 0x024f
|
||||
#define DM_POINTERHITTEST 0x0250
|
||||
#define WM_POINTERROUTEDTO 0x0251
|
||||
#define WM_POINTERROUTEDAWAY 0x0252
|
||||
#define WM_POINTERROUTEDRELEASED 0x0253
|
||||
|
||||
#define POINTER_FLAG_NONE 0x00000000
|
||||
#define POINTER_FLAG_NEW 0x00000001
|
||||
#define POINTER_FLAG_INRANGE 0x00000002
|
||||
#define POINTER_FLAG_INCONTACT 0x00000004
|
||||
#define POINTER_FLAG_FIRSTBUTTON 0x00000010
|
||||
#define POINTER_FLAG_SECONDBUTTON 0x00000020
|
||||
#define POINTER_FLAG_THIRDBUTTON 0x00000040
|
||||
#define POINTER_FLAG_FOURTHBUTTON 0x00000080
|
||||
#define POINTER_FLAG_FIFTHBUTTON 0x00000100
|
||||
#define POINTER_FLAG_PRIMARY 0x00002000
|
||||
#define POINTER_FLAG_CONFIDENCE 0x00004000
|
||||
#define POINTER_FLAG_CANCELED 0x00008000
|
||||
#define POINTER_FLAG_DOWN 0x00010000
|
||||
#define POINTER_FLAG_UPDATE 0x00020000
|
||||
#define POINTER_FLAG_UP 0x00040000
|
||||
#define POINTER_FLAG_WHEEL 0x00080000
|
||||
#define POINTER_FLAG_HWHEEL 0x00100000
|
||||
#define POINTER_FLAG_CAPTURECHANGED 0x00200000
|
||||
#define POINTER_FLAG_HASTRANSFORM 0x00400000
|
||||
|
||||
#define POINTER_MOD_SHIFT (0x0004)
|
||||
#define POINTER_MOD_CTRL (0x0008)
|
||||
|
||||
#define TOUCH_FLAG_NONE 0x00000000
|
||||
|
||||
#define TOUCH_MASK_NONE 0x00000000
|
||||
#define TOUCH_MASK_CONTACTAREA 0x00000001
|
||||
#define TOUCH_MASK_ORIENTATION 0x00000002
|
||||
#define TOUCH_MASK_PRESSURE 0x00000004
|
||||
|
||||
#define PEN_FLAG_NONE 0x00000000
|
||||
#define PEN_FLAG_BARREL 0x00000001
|
||||
#define PEN_FLAG_INVERTED 0x00000002
|
||||
#define PEN_FLAG_ERASER 0x00000004
|
||||
|
||||
#define PEN_MASK_NONE 0x00000000
|
||||
#define PEN_MASK_PRESSURE 0x00000001
|
||||
#define PEN_MASK_ROTATION 0x00000002
|
||||
#define PEN_MASK_TILT_X 0x00000004
|
||||
#define PEN_MASK_TILT_Y 0x00000008
|
||||
|
||||
#define POINTER_MESSAGE_FLAG_NEW 0x00000001
|
||||
#define POINTER_MESSAGE_FLAG_INRANGE 0x00000002
|
||||
#define POINTER_MESSAGE_FLAG_INCONTACT 0x00000004
|
||||
#define POINTER_MESSAGE_FLAG_FIRSTBUTTON 0x00000010
|
||||
#define POINTER_MESSAGE_FLAG_SECONDBUTTON 0x00000020
|
||||
#define POINTER_MESSAGE_FLAG_THIRDBUTTON 0x00000040
|
||||
#define POINTER_MESSAGE_FLAG_FOURTHBUTTON 0x00000080
|
||||
#define POINTER_MESSAGE_FLAG_FIFTHBUTTON 0x00000100
|
||||
#define POINTER_MESSAGE_FLAG_PRIMARY 0x00002000
|
||||
#define POINTER_MESSAGE_FLAG_CONFIDENCE 0x00004000
|
||||
#define POINTER_MESSAGE_FLAG_CANCELED 0x00008000
|
||||
|
||||
#define GET_POINTERID_WPARAM(wParam) (LOWORD (wParam))
|
||||
#define IS_POINTER_FLAG_SET_WPARAM(wParam, flag) (((DWORD)HIWORD (wParam) &(flag)) == (flag))
|
||||
#define IS_POINTER_NEW_WPARAM(wParam) IS_POINTER_FLAG_SET_WPARAM (wParam, POINTER_MESSAGE_FLAG_NEW)
|
||||
#define IS_POINTER_INRANGE_WPARAM(wParam) IS_POINTER_FLAG_SET_WPARAM (wParam, POINTER_MESSAGE_FLAG_INRANGE)
|
||||
#define IS_POINTER_INCONTACT_WPARAM(wParam) IS_POINTER_FLAG_SET_WPARAM (wParam, POINTER_MESSAGE_FLAG_INCONTACT)
|
||||
#define IS_POINTER_FIRSTBUTTON_WPARAM(wParam) IS_POINTER_FLAG_SET_WPARAM (wParam, POINTER_MESSAGE_FLAG_FIRSTBUTTON)
|
||||
#define IS_POINTER_SECONDBUTTON_WPARAM(wParam) IS_POINTER_FLAG_SET_WPARAM (wParam, POINTER_MESSAGE_FLAG_SECONDBUTTON)
|
||||
#define IS_POINTER_THIRDBUTTON_WPARAM(wParam) IS_POINTER_FLAG_SET_WPARAM (wParam, POINTER_MESSAGE_FLAG_THIRDBUTTON)
|
||||
#define IS_POINTER_FOURTHBUTTON_WPARAM(wParam) IS_POINTER_FLAG_SET_WPARAM (wParam, POINTER_MESSAGE_FLAG_FOURTHBUTTON)
|
||||
#define IS_POINTER_FIFTHBUTTON_WPARAM(wParam) IS_POINTER_FLAG_SET_WPARAM (wParam, POINTER_MESSAGE_FLAG_FIFTHBUTTON)
|
||||
#define IS_POINTER_PRIMARY_WPARAM(wParam) IS_POINTER_FLAG_SET_WPARAM (wParam, POINTER_MESSAGE_FLAG_PRIMARY)
|
||||
#define HAS_POINTER_CONFIDENCE_WPARAM(wParam) IS_POINTER_FLAG_SET_WPARAM (wParam, POINTER_MESSAGE_FLAG_CONFIDENCE)
|
||||
#define IS_POINTER_CANCELED_WPARAM(wParam) IS_POINTER_FLAG_SET_WPARAM (wParam, POINTER_MESSAGE_FLAG_CANCELED)
|
||||
|
||||
#define PA_ACTIVATE MA_ACTIVATE
|
||||
#define PA_NOACTIVATE MA_NOACTIVATE
|
||||
|
||||
#ifndef GC_ALLGESTURES
|
||||
#define GC_ALLGESTURES 0x1
|
||||
#endif
|
||||
|
||||
typedef DWORD POINTER_INPUT_TYPE;
|
||||
typedef UINT32 POINTER_FLAGS;
|
||||
typedef UINT32 TOUCH_FLAGS;
|
||||
typedef UINT32 TOUCH_MASK;
|
||||
typedef UINT32 PEN_FLAGS;
|
||||
typedef UINT32 PEN_MASK;
|
||||
|
||||
enum tagPOINTER_INPUT_TYPE {
|
||||
PT_POINTER = 0x00000001,
|
||||
PT_TOUCH = 0x00000002,
|
||||
PT_PEN = 0x00000003,
|
||||
PT_MOUSE = 0x00000004,
|
||||
PT_TOUCHPAD = 0x00000005
|
||||
};
|
||||
|
||||
typedef enum tagFEEDBACK_TYPE {
|
||||
FEEDBACK_TOUCH_CONTACTVISUALIZATION = 1,
|
||||
FEEDBACK_PEN_BARRELVISUALIZATION = 2,
|
||||
FEEDBACK_PEN_TAP = 3,
|
||||
FEEDBACK_PEN_DOUBLETAP = 4,
|
||||
FEEDBACK_PEN_PRESSANDHOLD = 5,
|
||||
FEEDBACK_PEN_RIGHTTAP = 6,
|
||||
FEEDBACK_TOUCH_TAP = 7,
|
||||
FEEDBACK_TOUCH_DOUBLETAP = 8,
|
||||
FEEDBACK_TOUCH_PRESSANDHOLD = 9,
|
||||
FEEDBACK_TOUCH_RIGHTTAP = 10,
|
||||
FEEDBACK_GESTURE_PRESSANDTAP = 11,
|
||||
FEEDBACK_MAX = 0xffffffff
|
||||
} FEEDBACK_TYPE;
|
||||
|
||||
typedef enum tagPOINTER_BUTTON_CHANGE_TYPE {
|
||||
POINTER_CHANGE_NONE,
|
||||
POINTER_CHANGE_FIRSTBUTTON_DOWN,
|
||||
POINTER_CHANGE_FIRSTBUTTON_UP,
|
||||
POINTER_CHANGE_SECONDBUTTON_DOWN,
|
||||
POINTER_CHANGE_SECONDBUTTON_UP,
|
||||
POINTER_CHANGE_THIRDBUTTON_DOWN,
|
||||
POINTER_CHANGE_THIRDBUTTON_UP,
|
||||
POINTER_CHANGE_FOURTHBUTTON_DOWN,
|
||||
POINTER_CHANGE_FOURTHBUTTON_UP,
|
||||
POINTER_CHANGE_FIFTHBUTTON_DOWN,
|
||||
POINTER_CHANGE_FIFTHBUTTON_UP,
|
||||
} POINTER_BUTTON_CHANGE_TYPE;
|
||||
|
||||
typedef struct tagPOINTER_INFO {
|
||||
POINTER_INPUT_TYPE pointerType;
|
||||
UINT32 pointerId;
|
||||
UINT32 frameId;
|
||||
POINTER_FLAGS pointerFlags;
|
||||
HANDLE sourceDevice;
|
||||
HWND hwndTarget;
|
||||
POINT ptPixelLocation;
|
||||
POINT ptHimetricLocation;
|
||||
POINT ptPixelLocationRaw;
|
||||
POINT ptHimetricLocationRaw;
|
||||
DWORD dwTime;
|
||||
UINT32 historyCount;
|
||||
INT32 InputData;
|
||||
DWORD dwKeyStates;
|
||||
UINT64 PerformanceCount;
|
||||
POINTER_BUTTON_CHANGE_TYPE ButtonChangeType;
|
||||
} POINTER_INFO;
|
||||
|
||||
typedef struct tagPOINTER_TOUCH_INFO {
|
||||
POINTER_INFO pointerInfo;
|
||||
TOUCH_FLAGS touchFlags;
|
||||
TOUCH_MASK touchMask;
|
||||
RECT rcContact;
|
||||
RECT rcContactRaw;
|
||||
UINT32 orientation;
|
||||
UINT32 pressure;
|
||||
} POINTER_TOUCH_INFO;
|
||||
|
||||
typedef struct tagPOINTER_PEN_INFO {
|
||||
POINTER_INFO pointerInfo;
|
||||
PEN_FLAGS penFlags;
|
||||
PEN_MASK penMask;
|
||||
UINT32 pressure;
|
||||
UINT32 rotation;
|
||||
INT32 tiltX;
|
||||
INT32 tiltY;
|
||||
} POINTER_PEN_INFO;
|
||||
|
||||
typedef enum {
|
||||
POINTER_FEEDBACK_DEFAULT = 1,
|
||||
POINTER_FEEDBACK_INDIRECT = 2,
|
||||
POINTER_FEEDBACK_NONE = 3
|
||||
} POINTER_FEEDBACK_MODE;
|
||||
|
||||
typedef struct tagUSAGE_PROPERTIES {
|
||||
USHORT level;
|
||||
USHORT page;
|
||||
USHORT usage;
|
||||
INT32 logicalMinimum;
|
||||
INT32 logicalMaximum;
|
||||
USHORT unit;
|
||||
USHORT exponent;
|
||||
BYTE count;
|
||||
INT32 physicalMinimum;
|
||||
INT32 physicalMaximum;
|
||||
} USAGE_PROPERTIES, *PUSAGE_PROPERTIES;
|
||||
|
||||
typedef struct tagPOINTER_TYPE_INFO {
|
||||
POINTER_INPUT_TYPE type;
|
||||
union {
|
||||
POINTER_TOUCH_INFO touchInfo;
|
||||
POINTER_PEN_INFO penInfo;
|
||||
} DUMMYUNIONNAME;
|
||||
} POINTER_TYPE_INFO, *PPOINTER_TYPE_INFO;
|
||||
|
||||
#define POINTER_DEVICE_PRODUCT_STRING_MAX 520
|
||||
#define PDC_ARRIVAL 0x001
|
||||
#define PDC_REMOVAL 0x002
|
||||
#define PDC_ORIENTATION_0 0x004
|
||||
#define PDC_ORIENTATION_90 0x008
|
||||
#define PDC_ORIENTATION_180 0x010
|
||||
#define PDC_ORIENTATION_270 0x020
|
||||
#define PDC_MODE_DEFAULT 0x040
|
||||
#define PDC_MODE_CENTERED 0x080
|
||||
#define PDC_MAPPING_CHANGE 0x100
|
||||
#define PDC_RESOLUTION 0x200
|
||||
#define PDC_ORIGIN 0x400
|
||||
#define PDC_MODE_ASPECTRATIOPRESERVED 0x800
|
||||
|
||||
typedef enum tagPOINTER_DEVICE_TYPE {
|
||||
POINTER_DEVICE_TYPE_INTEGRATED_PEN = 0x00000001,
|
||||
POINTER_DEVICE_TYPE_EXTERNAL_PEN = 0x00000002,
|
||||
POINTER_DEVICE_TYPE_TOUCH = 0x00000003,
|
||||
POINTER_DEVICE_TYPE_TOUCH_PAD = 0x00000004,
|
||||
POINTER_DEVICE_TYPE_MAX = 0xffffffff
|
||||
} POINTER_DEVICE_TYPE;
|
||||
|
||||
typedef struct tagPOINTER_DEVICE_INFO {
|
||||
DWORD displayOrientation;
|
||||
HANDLE device;
|
||||
POINTER_DEVICE_TYPE pointerDeviceType;
|
||||
HMONITOR monitor;
|
||||
ULONG startingCursorId;
|
||||
USHORT maxActiveContacts;
|
||||
WCHAR productString[POINTER_DEVICE_PRODUCT_STRING_MAX];
|
||||
} POINTER_DEVICE_INFO;
|
||||
|
||||
typedef struct tagPOINTER_DEVICE_PROPERTY {
|
||||
INT32 logicalMin;
|
||||
INT32 logicalMax;
|
||||
INT32 physicalMin;
|
||||
INT32 physicalMax;
|
||||
UINT32 unit;
|
||||
UINT32 unitExponent;
|
||||
USHORT usagePageId;
|
||||
USHORT usageId;
|
||||
} POINTER_DEVICE_PROPERTY;
|
||||
|
||||
typedef enum tagPOINTER_DEVICE_CURSOR_TYPE {
|
||||
POINTER_DEVICE_CURSOR_TYPE_UNKNOWN = 0x00000000,
|
||||
POINTER_DEVICE_CURSOR_TYPE_TIP = 0x00000001,
|
||||
POINTER_DEVICE_CURSOR_TYPE_ERASER = 0x00000002,
|
||||
POINTER_DEVICE_CURSOR_TYPE_MAX = 0xffffffff
|
||||
} POINTER_DEVICE_CURSOR_TYPE;
|
||||
|
||||
typedef struct tagPOINTER_DEVICE_CURSOR_INFO {
|
||||
UINT32 cursorId;
|
||||
POINTER_DEVICE_CURSOR_TYPE cursor;
|
||||
} POINTER_DEVICE_CURSOR_INFO;
|
||||
|
||||
#endif /* POINTER_FLAG_NONE */
|
||||
|
||||
#if WINVER < 0x0601
|
||||
|
||||
typedef struct tagGESTURECONFIG {
|
||||
DWORD dwID;
|
||||
DWORD dwWant;
|
||||
DWORD dwBlock;
|
||||
} GESTURECONFIG,*PGESTURECONFIG;
|
||||
|
||||
#endif /* WINVER < 0x0601 */
|
||||
|
||||
#ifndef MICROSOFT_TABLETPENSERVICE_PROPERTY
|
||||
#define MICROSOFT_TABLETPENSERVICE_PROPERTY _T("MicrosoftTabletPenServiceProperty")
|
||||
#endif
|
||||
@@ -45,6 +45,9 @@ get_display_name (GFile *file,
|
||||
if (name == NULL)
|
||||
{
|
||||
name = g_file_get_basename (file);
|
||||
if (name == NULL)
|
||||
name = g_file_get_uri (file);
|
||||
|
||||
if (!g_utf8_validate (name, -1, NULL))
|
||||
{
|
||||
tmp = name;
|
||||
|
||||
+44
-1
@@ -61,7 +61,6 @@ struct _GdkX11DeviceXI2Class
|
||||
|
||||
G_DEFINE_TYPE (GdkX11DeviceXI2, gdk_x11_device_xi2, GDK_TYPE_DEVICE)
|
||||
|
||||
|
||||
static void gdk_x11_device_xi2_finalize (GObject *object);
|
||||
static void gdk_x11_device_xi2_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
@@ -762,6 +761,20 @@ _gdk_x11_device_xi2_translate_event_mask (GdkX11DeviceManagerXI2 *device_manager
|
||||
}
|
||||
#endif /* XINPUT_2_2 */
|
||||
|
||||
#ifdef XINPUT_2_4
|
||||
/* XInput 2.4 includes multitouch support */
|
||||
if (minor >= 4 &&
|
||||
event_mask & GDK_TOUCHPAD_GESTURE_MASK)
|
||||
{
|
||||
XISetMask (mask, XI_GesturePinchBegin);
|
||||
XISetMask (mask, XI_GesturePinchUpdate);
|
||||
XISetMask (mask, XI_GesturePinchEnd);
|
||||
XISetMask (mask, XI_GestureSwipeBegin);
|
||||
XISetMask (mask, XI_GestureSwipeUpdate);
|
||||
XISetMask (mask, XI_GestureSwipeEnd);
|
||||
}
|
||||
#endif
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
||||
@@ -810,6 +823,36 @@ _gdk_x11_device_xi2_translate_state (XIModifierState *mods_state,
|
||||
return state;
|
||||
}
|
||||
|
||||
#ifdef XINPUT_2_4
|
||||
guint
|
||||
_gdk_x11_device_xi2_gesture_type_to_phase (int evtype, int flags)
|
||||
{
|
||||
switch (evtype)
|
||||
{
|
||||
case XI_GesturePinchBegin:
|
||||
case XI_GestureSwipeBegin:
|
||||
return GDK_TOUCHPAD_GESTURE_PHASE_BEGIN;
|
||||
|
||||
case XI_GesturePinchUpdate:
|
||||
case XI_GestureSwipeUpdate:
|
||||
return GDK_TOUCHPAD_GESTURE_PHASE_UPDATE;
|
||||
|
||||
case XI_GesturePinchEnd:
|
||||
if (flags & XIGesturePinchEventCancelled)
|
||||
return GDK_TOUCHPAD_GESTURE_PHASE_CANCEL;
|
||||
return GDK_TOUCHPAD_GESTURE_PHASE_END;
|
||||
|
||||
case XI_GestureSwipeEnd:
|
||||
if (flags & XIGestureSwipeEventCancelled)
|
||||
return GDK_TOUCHPAD_GESTURE_PHASE_CANCEL;
|
||||
return GDK_TOUCHPAD_GESTURE_PHASE_END;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
return GDK_TOUCHPAD_GESTURE_PHASE_END;
|
||||
}
|
||||
}
|
||||
#endif /* XINPUT_2_4 */
|
||||
|
||||
void
|
||||
_gdk_x11_device_xi2_add_scroll_valuator (GdkX11DeviceXI2 *device,
|
||||
guint n_valuator,
|
||||
|
||||
@@ -48,14 +48,15 @@ _gdk_x11_device_manager_new (GdkDisplay *display)
|
||||
int major, minor;
|
||||
|
||||
major = 2;
|
||||
minor = 3;
|
||||
minor = 4;
|
||||
|
||||
if (!_gdk_disable_multidevice &&
|
||||
XIQueryVersion (xdisplay, &major, &minor) != BadRequest)
|
||||
{
|
||||
GdkX11DeviceManagerXI2 *device_manager_xi2;
|
||||
|
||||
GDK_NOTE (INPUT, g_message ("Creating XI2 device manager"));
|
||||
GDK_NOTE (INPUT, g_message ("Creating XI2 (version %d.%d) device manager",
|
||||
major, minor));
|
||||
|
||||
device_manager_xi2 = g_object_new (GDK_TYPE_X11_DEVICE_MANAGER_XI2,
|
||||
"display", display,
|
||||
|
||||
@@ -1335,6 +1335,26 @@ get_event_window (GdkEventTranslator *translator,
|
||||
}
|
||||
}
|
||||
break;
|
||||
#ifdef XINPUT_2_4
|
||||
case XI_GesturePinchBegin:
|
||||
case XI_GesturePinchUpdate:
|
||||
case XI_GesturePinchEnd:
|
||||
{
|
||||
XIGesturePinchEvent *xev = (XIGesturePinchEvent *) ev;
|
||||
|
||||
window = gdk_x11_window_lookup_for_display (display, xev->event);
|
||||
}
|
||||
break;
|
||||
case XI_GestureSwipeBegin:
|
||||
case XI_GestureSwipeUpdate:
|
||||
case XI_GestureSwipeEnd:
|
||||
{
|
||||
XIGestureSwipeEvent *xev = (XIGestureSwipeEvent *) ev;
|
||||
|
||||
window = gdk_x11_window_lookup_for_display (display, xev->event);
|
||||
}
|
||||
break;
|
||||
#endif /* XINPUT_2_4 */
|
||||
case XI_Enter:
|
||||
case XI_Leave:
|
||||
case XI_FocusIn:
|
||||
@@ -1950,6 +1970,144 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
|
||||
break;
|
||||
#endif /* XINPUT_2_2 */
|
||||
|
||||
#ifdef XINPUT_2_4
|
||||
case XI_GesturePinchBegin:
|
||||
case XI_GesturePinchUpdate:
|
||||
case XI_GesturePinchEnd:
|
||||
{
|
||||
XIGesturePinchEvent *xev = (XIGesturePinchEvent *) ev;
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
const char* event_name = "";
|
||||
switch (xev->evtype)
|
||||
{
|
||||
case XI_GesturePinchBegin:
|
||||
event_name = "begin";
|
||||
break;
|
||||
case XI_GesturePinchUpdate:
|
||||
event_name = "update";
|
||||
break;
|
||||
case XI_GesturePinchEnd:
|
||||
event_name = "end";
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
GDK_NOTE(EVENTS,
|
||||
g_message ("pinch gesture %s:\twindow %ld\n\tfinger_count: %u%s",
|
||||
event_name,
|
||||
xev->event,
|
||||
xev->detail,
|
||||
xev->flags & XIGesturePinchEventCancelled ? "\n\tcancelled" : ""));
|
||||
|
||||
event->touchpad_pinch.type = GDK_TOUCHPAD_PINCH;
|
||||
event->touchpad_pinch.phase =
|
||||
_gdk_x11_device_xi2_gesture_type_to_phase (xev->evtype, xev->flags);
|
||||
event->touchpad_pinch.window = window;
|
||||
event->touchpad_pinch.time = xev->time;
|
||||
event->touchpad_pinch.x = (gdouble) xev->event_x / scale;
|
||||
event->touchpad_pinch.y = (gdouble) xev->event_y / scale;
|
||||
event->touchpad_pinch.x_root = (gdouble) xev->root_x / scale;
|
||||
event->touchpad_pinch.y_root = (gdouble) xev->root_y / scale;
|
||||
event->touchpad_pinch.dx = xev->delta_x;
|
||||
event->touchpad_pinch.dy = xev->delta_y;
|
||||
event->touchpad_pinch.scale = xev->scale;
|
||||
event->touchpad_pinch.angle_delta = xev->delta_angle * G_PI / 180;
|
||||
event->touchpad_pinch.n_fingers = xev->detail;
|
||||
|
||||
device = g_hash_table_lookup (device_manager->id_table,
|
||||
GUINT_TO_POINTER (xev->deviceid));
|
||||
gdk_event_set_device (event, device);
|
||||
|
||||
source_device = g_hash_table_lookup (device_manager->id_table,
|
||||
GUINT_TO_POINTER (xev->sourceid));
|
||||
gdk_event_set_source_device (event, source_device);
|
||||
gdk_event_set_seat (event, gdk_device_get_seat (device));
|
||||
|
||||
event->touchpad_pinch.state = _gdk_x11_device_xi2_translate_state (&xev->mods, NULL, &xev->group);
|
||||
|
||||
if (xev->evtype == XI_GesturePinchBegin || xev->evtype == XI_GesturePinchEnd)
|
||||
{
|
||||
if (!set_screen_from_root (display, event, xev->root))
|
||||
{
|
||||
return_val = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ev->evtype == XI_GesturePinchBegin)
|
||||
set_user_time (event);
|
||||
}
|
||||
break;
|
||||
|
||||
case XI_GestureSwipeBegin:
|
||||
case XI_GestureSwipeUpdate:
|
||||
case XI_GestureSwipeEnd:
|
||||
{
|
||||
XIGestureSwipeEvent *xev = (XIGestureSwipeEvent *) ev;
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
const char* event_name = "";
|
||||
switch (xev->evtype)
|
||||
{
|
||||
case XI_GestureSwipeBegin:
|
||||
event_name = "begin";
|
||||
break;
|
||||
case XI_GestureSwipeUpdate:
|
||||
event_name = "update";
|
||||
break;
|
||||
case XI_GestureSwipeEnd:
|
||||
event_name = "end";
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
GDK_NOTE(EVENTS,
|
||||
g_message ("swipe gesture %s:\twindow %ld\n\tfinger_count: %u%s",
|
||||
event_name,
|
||||
xev->event,
|
||||
xev->detail,
|
||||
xev->flags & XIGestureSwipeEventCancelled ? "\n\tcancelled" : ""));
|
||||
|
||||
event->touchpad_swipe.type = GDK_TOUCHPAD_SWIPE;
|
||||
event->touchpad_pinch.phase =
|
||||
_gdk_x11_device_xi2_gesture_type_to_phase (xev->evtype, xev->flags);
|
||||
event->touchpad_swipe.window = window;
|
||||
event->touchpad_swipe.time = xev->time;
|
||||
event->touchpad_swipe.x = (gdouble) xev->event_x / scale;
|
||||
event->touchpad_swipe.y = (gdouble) xev->event_y / scale;
|
||||
event->touchpad_swipe.x_root = (gdouble) xev->root_x / scale;
|
||||
event->touchpad_swipe.y_root = (gdouble) xev->root_y / scale;
|
||||
event->touchpad_swipe.dx = xev->delta_x;
|
||||
event->touchpad_swipe.dy = xev->delta_y;
|
||||
event->touchpad_swipe.n_fingers = xev->detail;
|
||||
|
||||
device = g_hash_table_lookup (device_manager->id_table,
|
||||
GUINT_TO_POINTER (xev->deviceid));
|
||||
gdk_event_set_device (event, device);
|
||||
|
||||
source_device = g_hash_table_lookup (device_manager->id_table,
|
||||
GUINT_TO_POINTER (xev->sourceid));
|
||||
gdk_event_set_source_device (event, source_device);
|
||||
gdk_event_set_seat (event, gdk_device_get_seat (device));
|
||||
|
||||
event->touchpad_swipe.state = _gdk_x11_device_xi2_translate_state (&xev->mods, NULL, &xev->group);
|
||||
|
||||
if (xev->evtype == XI_GestureSwipeBegin || xev->evtype == XI_GestureSwipeEnd)
|
||||
{
|
||||
if (!set_screen_from_root (display, event, xev->root))
|
||||
{
|
||||
return_val = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ev->evtype == XI_GestureSwipeBegin)
|
||||
set_user_time (event);
|
||||
}
|
||||
break;
|
||||
#endif /* XINPUT_2_4 */
|
||||
|
||||
case XI_Enter:
|
||||
case XI_Leave:
|
||||
{
|
||||
@@ -2078,7 +2236,8 @@ gdk_x11_device_manager_xi2_get_handled_events (GdkEventTranslator *translator)
|
||||
GDK_BUTTON3_MOTION_MASK |
|
||||
GDK_BUTTON_MOTION_MASK |
|
||||
GDK_FOCUS_CHANGE_MASK |
|
||||
GDK_TOUCH_MASK);
|
||||
GDK_TOUCH_MASK |
|
||||
GDK_TOUCHPAD_GESTURE_MASK);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -1964,6 +1964,9 @@ _gdk_x11_display_update_grab_info_ungrab (GdkDisplay *display,
|
||||
static void
|
||||
gdk_x11_display_beep (GdkDisplay *display)
|
||||
{
|
||||
if (!GDK_X11_DISPLAY (display)->trusted_client)
|
||||
return;
|
||||
|
||||
#ifdef HAVE_XKB
|
||||
XkbBell (GDK_DISPLAY_XDISPLAY (display), None, 0, None);
|
||||
#else
|
||||
|
||||
@@ -634,12 +634,14 @@ gdk_window_cache_new (GdkScreen *screen)
|
||||
*/
|
||||
if (gdk_screen_is_composited (screen))
|
||||
{
|
||||
gdk_x11_display_error_trap_push (GDK_X11_SCREEN (screen)->display);
|
||||
cow = XCompositeGetOverlayWindow (xdisplay, GDK_WINDOW_XID (root_window));
|
||||
gdk_window_cache_add (result, cow, 0, 0,
|
||||
gdk_x11_screen_get_width (screen) * GDK_X11_SCREEN(screen)->window_scale,
|
||||
gdk_x11_screen_get_height (screen) * GDK_X11_SCREEN(screen)->window_scale,
|
||||
TRUE);
|
||||
XCompositeReleaseOverlayWindow (xdisplay, GDK_WINDOW_XID (root_window));
|
||||
gdk_x11_display_error_trap_pop_ignored (GDK_X11_SCREEN (screen)->display);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
+6
-17
@@ -240,24 +240,13 @@ gdk_x_io_error (Display *display)
|
||||
/* This is basically modelled after the code in XLib. We need
|
||||
* an explicit error handler here, so we can disable our atexit()
|
||||
* which would otherwise cause a nice segfault.
|
||||
* We fprintf(stderr, instead of g_warning() because g_warning()
|
||||
* could possibly be redirected to a dialog
|
||||
* We g_debug() instead of g_warning(), because g_warning()
|
||||
* could possibly be redirected to the log
|
||||
*/
|
||||
if (errno == EPIPE)
|
||||
{
|
||||
g_message ("The application '%s' lost its connection to the display %s;\n"
|
||||
"most likely the X server was shut down or you killed/destroyed\n"
|
||||
"the application.\n",
|
||||
g_get_prgname (),
|
||||
display ? DisplayString (display) : gdk_get_display_arg_name ());
|
||||
}
|
||||
else
|
||||
{
|
||||
g_message ("%s: Fatal IO error %d (%s) on X server %s.\n",
|
||||
g_get_prgname (),
|
||||
errno, g_strerror (errno),
|
||||
display ? DisplayString (display) : gdk_get_display_arg_name ());
|
||||
}
|
||||
g_debug ("%s: Fatal IO error %d (%s) on X server %s.\n",
|
||||
g_get_prgname (),
|
||||
errno, g_strerror (errno),
|
||||
display ? DisplayString (display) : gdk_get_display_arg_name ());
|
||||
|
||||
_exit (1);
|
||||
}
|
||||
|
||||
@@ -230,6 +230,11 @@ guchar * _gdk_x11_device_xi2_translate_event_mask (GdkX11DeviceManagerXI2 *devic
|
||||
guint _gdk_x11_device_xi2_translate_state (XIModifierState *mods_state,
|
||||
XIButtonState *buttons_state,
|
||||
XIGroupState *group_state);
|
||||
|
||||
#ifdef XINPUT_2_4
|
||||
guint _gdk_x11_device_xi2_gesture_type_to_phase (int evtype, int flags);
|
||||
#endif
|
||||
|
||||
gint _gdk_x11_device_xi2_get_id (GdkX11DeviceXI2 *device);
|
||||
void _gdk_device_xi2_unset_scroll_valuators (GdkX11DeviceXI2 *device);
|
||||
|
||||
|
||||
+10
-1
@@ -568,9 +568,18 @@ init_randr15 (GdkScreen *screen, gboolean *changed)
|
||||
|
||||
if (output_info->crtc)
|
||||
{
|
||||
XRRCrtcInfo *crtc = XRRGetCrtcInfo (x11_screen->xdisplay, resources, output_info->crtc);
|
||||
XRRCrtcInfo *crtc;
|
||||
int j;
|
||||
|
||||
gdk_x11_display_error_trap_push (display);
|
||||
crtc = XRRGetCrtcInfo (x11_screen->xdisplay, resources,
|
||||
output_info->crtc);
|
||||
if (gdk_x11_display_error_trap_pop (display))
|
||||
{
|
||||
XRRFreeOutputInfo (output_info);
|
||||
continue;
|
||||
}
|
||||
|
||||
for (j = 0; j < resources->nmode; j++)
|
||||
{
|
||||
XRRModeInfo *xmode = &resources->modes[j];
|
||||
|
||||
+23
-3
@@ -3025,12 +3025,29 @@ G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
|
||||
if (pattern == parent_relative_pattern)
|
||||
{
|
||||
GdkWindow *parent;
|
||||
Window xroot, xparent, *xchildren;
|
||||
guint nxchildren, xparent_depth;
|
||||
XWindowAttributes xattrs;
|
||||
|
||||
if (!XQueryTree (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
|
||||
&xroot, &xparent, &xchildren, &nxchildren))
|
||||
{
|
||||
XSetWindowBackgroundPixmap (GDK_WINDOW_XDISPLAY (window),
|
||||
GDK_WINDOW_XID (window), None);
|
||||
return;
|
||||
}
|
||||
|
||||
if (xchildren)
|
||||
XFree (xchildren);
|
||||
|
||||
if (xparent) {
|
||||
XGetWindowAttributes (GDK_WINDOW_XDISPLAY (window), xparent, &xattrs);
|
||||
xparent_depth = xattrs.depth;
|
||||
}
|
||||
|
||||
/* X throws BadMatch if the parent has a different depth when
|
||||
* using ParentRelative */
|
||||
parent = gdk_window_get_parent (window);
|
||||
if (parent != NULL && window->depth == parent->depth &&
|
||||
if (xparent && window->depth == xparent_depth &&
|
||||
cairo_pattern_status (pattern) == CAIRO_STATUS_SUCCESS)
|
||||
{
|
||||
XSetWindowBackgroundPixmap (GDK_WINDOW_XDISPLAY (window),
|
||||
@@ -5455,6 +5472,9 @@ gdk_x11_window_beep (GdkWindow *window)
|
||||
|
||||
display = GDK_WINDOW_DISPLAY (window);
|
||||
|
||||
if (!GDK_X11_DISPLAY (display)->trusted_client)
|
||||
return FALSE;
|
||||
|
||||
#ifdef HAVE_XKB
|
||||
if (GDK_X11_DISPLAY (display)->use_xkb)
|
||||
{
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user