Compare commits
308 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1cc3c019e6 | |||
| 319aa558a5 | |||
| 208769f70f | |||
| c5bffb9fb5 | |||
| c7afa5452b | |||
| c7c6e83779 | |||
| fcb6adaaaa | |||
| 9c12b58e32 | |||
| 6c8b505f93 | |||
| 8b228e7471 | |||
| 4ce07f41ca | |||
| 1bfd0e5e38 | |||
| b962d37f79 | |||
| c6ecf02a07 | |||
| 8b7d4b423c | |||
| 83dc126565 | |||
| f2d3d7e710 | |||
| f991428cb9 | |||
| c9cf7b1e08 | |||
| 4d865cd7ba | |||
| a55458a84a | |||
| 66d8631c23 | |||
| 5c1ad88137 | |||
| e230c9c6f0 | |||
| 6d24a2c942 | |||
| 5222dc0cd1 | |||
| 51a72a9c53 | |||
| f609d9cd59 | |||
| 3901c6ab91 | |||
| da6f86bd79 | |||
| 42fd499af4 | |||
| de5b88477a | |||
| cd49a7f9e9 | |||
| df025fcb88 | |||
| bbb1404bd3 | |||
| af2a172197 | |||
| 252b9fc39c | |||
| 6fc5e04d7c | |||
| 66f1fef083 | |||
| 645d4807c3 | |||
| e2c360ada0 | |||
| a463ead739 | |||
| dbe5e57b8e | |||
| 99b99d7b23 | |||
| 787111a145 | |||
| 9a872f059f | |||
| eadc94e0a1 | |||
| f8855e892a | |||
| 27d05014e3 | |||
| ebb58b7cbc | |||
| 7f6895a4bb | |||
| 80ae4c1a69 | |||
| e72df9cd5f | |||
| 80ba529fb9 | |||
| fd6b3ef5a0 | |||
| 4cd0a39794 | |||
| 5fbc510f94 | |||
| 600ab5ba5f | |||
| ae92181d02 | |||
| 66910ed998 | |||
| 5371e4403e | |||
| 79375dd7dd | |||
| 6889609ab9 | |||
| 0bf87281e0 | |||
| bc7bed7517 | |||
| cfac6fd752 | |||
| 97c09c827b | |||
| 0370672886 | |||
| 2d062fedd9 | |||
| c6a68f3de2 | |||
| d6181b2335 | |||
| d74e62886c | |||
| d8505f09eb | |||
| 935c6aade0 | |||
| a35c35f849 | |||
| 57518a2bb4 | |||
| 99a8202015 | |||
| 17c903e246 | |||
| 4de5d225db | |||
| 7741df9963 | |||
| 7ef54e9c53 | |||
| 12bb700c62 | |||
| e3ba7250f1 | |||
| 54842095c3 | |||
| d1aec0c3f1 | |||
| 00d5f72d6e | |||
| 15d01d4315 | |||
| 348e34f221 | |||
| ce7b0656c0 | |||
| fd0d360f9b | |||
| f26cae3838 | |||
| b8468af411 | |||
| 9fd7e319f3 | |||
| 80a8b59f24 | |||
| b9d4da9cfe | |||
| 5bf5b58eb3 | |||
| b2c227e9c5 | |||
| d854228d58 | |||
| a0c09bc2a9 | |||
| aca3b2da58 | |||
| 604541863c | |||
| fc67b5a8cf | |||
| ce1b970b46 | |||
| ceb77d6100 | |||
| 02579a1333 | |||
| 2f7fa10434 | |||
| 6be352f446 | |||
| 4d2be2e322 | |||
| d5c01098fd | |||
| d2bda8ea77 | |||
| c517e945de | |||
| e3a1a2e0c6 | |||
| b9c2a925e2 | |||
| 59238c6e73 | |||
| 652ab1ac72 | |||
| bdf879427c | |||
| 4058b80d56 | |||
| be949496ac | |||
| b57b12fdb7 | |||
| e64bb40d0b | |||
| c8d83b7a63 | |||
| 9539cc4a93 | |||
| 72cf304a86 | |||
| 67ad566188 | |||
| db46a8dd06 | |||
| fd9e0dd13a | |||
| 2611a996ff | |||
| 3e7618fef7 | |||
| 5b1b75b055 | |||
| f1612e36ee | |||
| bfd3d714b9 | |||
| 5a42ccc575 | |||
| b3b0321620 | |||
| e0deacd236 | |||
| f66172451d | |||
| e80238120e | |||
| 07cfdd8ca0 | |||
| ade7509b97 | |||
| 8d1956921d | |||
| 354fa6544a | |||
| 291c50202a | |||
| ce8faa2e90 | |||
| 50e4ca8593 | |||
| ddd5704c92 | |||
| 3ba6d2bd27 | |||
| cd9b730735 | |||
| f593f3da0a | |||
| e9d8bf96e0 | |||
| 6b3a612bbc | |||
| c742debea8 | |||
| cd60ec1576 | |||
| 95e6453823 | |||
| 7e0279b15c | |||
| 791f0d70ac | |||
| 0709dc7a6a | |||
| 15528599f4 | |||
| 031aab3ef6 | |||
| c990134e49 | |||
| 822508f33e | |||
| 358893aa84 | |||
| 344fac5aa7 | |||
| 27965d5fdc | |||
| c025bc5098 | |||
| 170bc0a8de | |||
| 891fd5c604 | |||
| 5b1cd335bb | |||
| eefb6a0dd4 | |||
| 9aaf54140f | |||
| c5786916f7 | |||
| b8e009eb05 | |||
| 256d226d4b | |||
| 7b3208092c | |||
| 1eb86d6394 | |||
| a0ca936e8d | |||
| de3c50a237 | |||
| 244ddea0ea | |||
| 6c94835f5d | |||
| 617566128d | |||
| 7bf772111c | |||
| 50e0893497 | |||
| 7459d430eb | |||
| 163616cc0a | |||
| e378dc4c28 | |||
| 4876028f29 | |||
| 22847563ce | |||
| 0996113d14 | |||
| f019e9d856 | |||
| 48b83d3e97 | |||
| c3211e32ae | |||
| c1790bf0d8 | |||
| 6690197673 | |||
| 384196efb1 | |||
| b801125797 | |||
| aecdd6f68f | |||
| 899cb44519 | |||
| 86175f043c | |||
| 74c6b8e9bc | |||
| d3347e64ba | |||
| 4c8081bafc | |||
| 5995e89a80 | |||
| b9bdbe9aae | |||
| c86789427d | |||
| 0852084884 | |||
| 96778fca92 | |||
| 0c53b608f9 | |||
| 27350ad71b | |||
| d9d220cfc9 | |||
| 2026256823 | |||
| 012baeb909 | |||
| 7249961aa4 | |||
| 3d77e526d6 | |||
| c4b2fe6ee5 | |||
| cea320af24 | |||
| a5bf0591ee | |||
| 22f5236943 | |||
| f84bcfbb97 | |||
| f36ee67226 | |||
| 615b8fc569 | |||
| ff3bb7f671 | |||
| 39e4e48fdc | |||
| 300a88922e | |||
| c003260d63 | |||
| 40c08954db | |||
| fd69b41748 | |||
| a2191c0a68 | |||
| c17451557f | |||
| b91dca9ad0 | |||
| 7586e535ff | |||
| 7859b88f19 | |||
| 7f7809f523 | |||
| b4c2d1dabb | |||
| 362e91c40b | |||
| acf6d47b6f | |||
| 0903ad48f0 | |||
| 46f8600b6a | |||
| fcb3638ac3 | |||
| e599b2548a | |||
| 98d14b4655 | |||
| 96f7e59832 | |||
| 061026f21f | |||
| 330e9a8424 | |||
| 1e47b1c610 | |||
| bf40b89b53 | |||
| 9f2dbf4fc5 | |||
| 235b0482dd | |||
| cbd332bc57 | |||
| fc8aa80e62 | |||
| 56404b7006 | |||
| 08d48201e9 | |||
| 76c4673944 | |||
| 0a31201c88 | |||
| afe94e303a | |||
| b004706009 | |||
| 129042425d | |||
| 81169d18c3 | |||
| cce6a603a6 | |||
| 1c6608f426 | |||
| fcdc5538cf | |||
| dd327bc8a6 | |||
| b878353f0b | |||
| 27d286eb7a | |||
| 01cf559d9d | |||
| 20fd760a52 | |||
| cca8ae04b6 | |||
| 60c45dac56 | |||
| 7bee4fa44b | |||
| 4c029af6cd | |||
| 1c6efea370 | |||
| 895dc94cc9 | |||
| 9f9479a50f | |||
| 13d559119f | |||
| 018388d321 | |||
| cf69d917c1 | |||
| 41599e5e90 | |||
| 1b2e69f6c0 | |||
| ee45869759 | |||
| 048fe84888 | |||
| 480031439f | |||
| dc9b145e27 | |||
| 0e27a49d1a | |||
| 4afd416840 | |||
| 25142abebf | |||
| 60d50bcb13 | |||
| 59f45aa30c | |||
| 14c32a7cf0 | |||
| 4c8e703803 | |||
| 8338e55549 | |||
| da72cfea40 | |||
| 0632e94e68 | |||
| 4a356ae331 | |||
| 4f4f2d169a | |||
| 577d520006 | |||
| 222d6f1db1 | |||
| 4ffa60be50 | |||
| 7da72d1295 | |||
| c9735e8ea9 | |||
| 8a7868d006 | |||
| c4e5242be0 | |||
| 935f7f19f3 | |||
| 5c9ae28937 | |||
| 8e27fc7f9b | |||
| e80d938ee5 | |||
| c87d1c2fb9 | |||
| c66d24b41a | |||
| 155b791d43 | |||
| 53acff167b | |||
| 96f63a6bf3 | |||
| 42249ce28e |
+17
-17
@@ -167,7 +167,7 @@ macos:
|
||||
needs: []
|
||||
before_script:
|
||||
- bash .gitlab-ci/show-info-osx.sh
|
||||
- pip3 install --user meson==0.56
|
||||
- pip3 install --user meson==0.59
|
||||
- pip3 install --user ninja
|
||||
- export PATH=/Users/gitlabrunner/Library/Python/3.7/bin:$PATH
|
||||
- export MESON_FORCE_BACKTRACE=1
|
||||
@@ -221,11 +221,11 @@ vs2017-x64:
|
||||
extends: .flatpak-defaults
|
||||
when: manual
|
||||
|
||||
# Only build Flatpak bundles automatically on master
|
||||
.flatpak-master:
|
||||
# Only build Flatpak bundles automatically on main
|
||||
.flatpak-main:
|
||||
extends: .flatpak-defaults
|
||||
only:
|
||||
- master
|
||||
- main
|
||||
|
||||
flatpak-manual:demo:
|
||||
extends: .flatpak-manual
|
||||
@@ -233,8 +233,8 @@ flatpak-manual:demo:
|
||||
variables:
|
||||
APPID: org.gtk.Demo4
|
||||
|
||||
flatpak-master:demo:
|
||||
extends: .flatpak-master
|
||||
flatpak-main:demo:
|
||||
extends: .flatpak-main
|
||||
needs: []
|
||||
variables:
|
||||
APPID: org.gtk.Demo4
|
||||
@@ -245,8 +245,8 @@ flatpak-manual:widget-factory:
|
||||
variables:
|
||||
APPID: org.gtk.WidgetFactory4
|
||||
|
||||
flatpak-master:widget-factory:
|
||||
extends: .flatpak-master
|
||||
flatpak-main:widget-factory:
|
||||
extends: .flatpak-main
|
||||
needs: []
|
||||
variables:
|
||||
APPID: org.gtk.WidgetFactory4
|
||||
@@ -257,8 +257,8 @@ flatpak-manual:icon-browser:
|
||||
variables:
|
||||
APPID: org.gtk.IconBrowser4
|
||||
|
||||
flatpak-master:icon-browser:
|
||||
extends: .flatpak-master
|
||||
flatpak-main:icon-browser:
|
||||
extends: .flatpak-main
|
||||
needs: []
|
||||
variables:
|
||||
APPID: org.gtk.IconBrowser4
|
||||
@@ -268,18 +268,18 @@ flatpak-master:icon-browser:
|
||||
# https://gitlab.gnome.org/GNOME/Initiatives/-/wikis/DevOps-with-Flatpak
|
||||
nightly demo:
|
||||
extends: '.publish_nightly'
|
||||
dependencies: ['flatpak-master:demo']
|
||||
needs: ['flatpak-master:demo']
|
||||
dependencies: ['flatpak-main:demo']
|
||||
needs: ['flatpak-main:demo']
|
||||
|
||||
nightly factory:
|
||||
extends: '.publish_nightly'
|
||||
dependencies: ['flatpak-master:widget-factory']
|
||||
needs: ['flatpak-master:widget-factory']
|
||||
dependencies: ['flatpak-main:widget-factory']
|
||||
needs: ['flatpak-main:widget-factory']
|
||||
|
||||
nightly icon-browser:
|
||||
extends: '.publish_nightly'
|
||||
dependencies: ['flatpak-master:icon-browser']
|
||||
needs: ['flatpak-master:icon-browser']
|
||||
dependencies: ['flatpak-main:icon-browser']
|
||||
needs: ['flatpak-main:icon-browser']
|
||||
|
||||
static-scan:
|
||||
image: $FEDORA_IMAGE
|
||||
@@ -346,4 +346,4 @@ publish-docs:
|
||||
- "curl -X POST -F token=${PAGES_TRIGGER_TOKEN} -F ref=docs-gtk-org https://gitlab.gnome.org/api/v4/projects/665/trigger/pipeline"
|
||||
only:
|
||||
refs:
|
||||
- master
|
||||
- main
|
||||
|
||||
@@ -43,6 +43,6 @@ flatpak build-bundle \
|
||||
${appid}
|
||||
|
||||
# to be consumed by the nightly publish jobs
|
||||
if [[ $CI_COMMIT_BRANCH == master ]]; then
|
||||
if [[ $CI_COMMIT_BRANCH == main ]]; then
|
||||
tar cf repo.tar ${repodir}
|
||||
fi
|
||||
|
||||
@@ -268,7 +268,7 @@ aparser.add_argument('--job-id', metavar='ID',
|
||||
default=None)
|
||||
aparser.add_argument('--branch', metavar='NAME',
|
||||
help='Branch of the project being tested',
|
||||
default='master')
|
||||
default='main')
|
||||
aparser.add_argument('--output', metavar='FILE',
|
||||
help='The output HTML file, stdout by default',
|
||||
type=argparse.FileType('w', encoding='UTF-8'),
|
||||
|
||||
@@ -27,7 +27,7 @@ aparser.add_argument('--job-id', metavar='ID',
|
||||
default='Unknown')
|
||||
aparser.add_argument('--branch', metavar='NAME',
|
||||
help='Branch of the project being tested',
|
||||
default='master')
|
||||
default='main')
|
||||
aparser.add_argument('--output', metavar='FILE',
|
||||
help='The output file, stdout by default',
|
||||
type=argparse.FileType('w', encoding='UTF-8'),
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
set -e
|
||||
|
||||
# We need to add a new remote for the upstream master, since this script could
|
||||
# We need to add a new remote for the upstream main, since this script could
|
||||
# be running in a personal fork of the repository which has out of date branches.
|
||||
if [ "${CI_PROJECT_NAMESPACE}" != "GNOME" ]; then
|
||||
echo "Retrieving the current upstream repository from ${CI_PROJECT_NAMESPACE}/${CI_PROJECT_NAME}..."
|
||||
@@ -16,7 +16,7 @@ fi
|
||||
|
||||
# Work out the newest common ancestor between the detached HEAD that this CI job
|
||||
# has checked out, and the upstream target branch (which will typically be
|
||||
# `upstream/master` or `upstream/gtk-3-24`).
|
||||
# `upstream/main` or `upstream/gtk-3-24`).
|
||||
#
|
||||
# `${CI_MERGE_REQUEST_TARGET_BRANCH_NAME}` is only defined if we’re running in
|
||||
# a merge request pipeline; fall back to `${CI_DEFAULT_BRANCH}` otherwise.
|
||||
@@ -36,7 +36,7 @@ exit_status=$?
|
||||
echo ""
|
||||
echo "Note that clang-format output is advisory and cannot always match the"
|
||||
echo "GTK coding style, documented at:"
|
||||
echo " https://gitlab.gnome.org/GNOME/gtk/blob/master/docs/CODING-STYLE"
|
||||
echo " https://gitlab.gnome.org/GNOME/gtk/blob/main/docs/CODING-STYLE"
|
||||
echo "Warnings from this tool can be ignored in favour of the documented "
|
||||
echo "coding style, or in favour of matching the style of existing"
|
||||
echo "surrounding code."
|
||||
|
||||
@@ -5,7 +5,7 @@ call "C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliar
|
||||
@echo on
|
||||
|
||||
:: FIXME: make warnings fatal
|
||||
pip3 install --upgrade --user meson==0.56.2 || goto :error
|
||||
pip3 install --upgrade --user meson==0.59 || goto :error
|
||||
meson -Dmedia-gstreamer=disabled _build || goto :error
|
||||
ninja -C _build || goto :error
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ if ! pkg-config --atleast-version=2.66.0 glib-2.0; then
|
||||
fi
|
||||
pkg-config --modversion glib-2.0
|
||||
|
||||
if ! pkg-config --atleast-version=1.49.1 pango; then
|
||||
if ! pkg-config --atleast-version=1.50.0 pango; then
|
||||
git clone https://gitlab.gnome.org/GNOME/pango.git _pango
|
||||
meson setup _pango_build _pango
|
||||
meson compile -C _pango_build
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<!--
|
||||
Please, read the CONTRIBUTING.md guide on how to file a new issue.
|
||||
|
||||
https://gitlab.gnome.org/GNOME/gtk/-/blob/master/CONTRIBUTING.md
|
||||
https://gitlab.gnome.org/GNOME/gtk/-/blob/main/CONTRIBUTING.md
|
||||
-->
|
||||
## Steps to reproduce
|
||||
<!--
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<!--
|
||||
Please, read the CONTRIBUTING.md guide on how to file a new issue.
|
||||
|
||||
https://gitlab.gnome.org/GNOME/gtk/-/blob/master/CONTRIBUTING.md
|
||||
https://gitlab.gnome.org/GNOME/gtk/-/blob/main/CONTRIBUTING.md
|
||||
-->
|
||||
|
||||
## Steps to reproduce
|
||||
|
||||
+1
-1
@@ -256,7 +256,7 @@ people committing to GTK to follow a few rules:
|
||||
0. Always write a meaningful commit message. Changes without a sufficient
|
||||
commit message will be reverted.
|
||||
|
||||
0. Never push to the `master` branch, or any stable branches, directly; you
|
||||
0. Never push to the `main` branch, or any stable branches, directly; you
|
||||
should always go through a merge request, to ensure that the code is
|
||||
tested on the CI infrastructure at the very least. A merge request is
|
||||
also the proper place to get a comprehensive code review from the core
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
Overview of Changes
|
||||
===================
|
||||
|
||||
* Rename git `master` branch to `main`
|
||||
|
||||
Overview of Changes in 4.5.0
|
||||
============================
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
GTK — The GTK toolkit
|
||||
=====================
|
||||
|
||||
[](https://gitlab.gnome.org/GNOME/gtk/-/commits/master)
|
||||
[](https://gitlab.gnome.org/GNOME/gtk/-/commits/main)
|
||||
|
||||
General information
|
||||
-------------------
|
||||
@@ -40,7 +40,7 @@ Nightly documentation can be found at
|
||||
|
||||
Nightly flatpaks of our demos can be installed from the
|
||||
[GNOME Nightly](https://wiki.gnome.org/Apps/Nightly) repository:
|
||||
- `flatpak remote-add --if-not-exists gnome-nightly https://nightly.gnome.org/gnome-nightly.flatpakrepo`
|
||||
- `flatpak remote-add --if-not-exists gnome-nightly https://nightly.gnome.org/gnome-nightly.flatpakrepo`
|
||||
- `flatpak install gnome-nightly org.gtk.Demo4`
|
||||
- `flatpak install gnome-nightly org.gtk.WidgetFactory4`
|
||||
- `flatpak install gnome-nightly org.gtk.IconBrowser4`
|
||||
@@ -116,6 +116,20 @@ docs/reference/gtk/html/gtk-building.html
|
||||
|
||||
Or [online](https://docs.gtk.org/gtk4/building.html)
|
||||
|
||||
Default branch renamed to `main`
|
||||
--------------------------------
|
||||
|
||||
The default development branch of GTK has been renamed to `main`.
|
||||
To update your local checkout, use:
|
||||
```sh
|
||||
git checkout master
|
||||
git branch -m master main
|
||||
git fetch
|
||||
git branch --unset-upstream
|
||||
git branch -u origin/main
|
||||
git symbolic-ref refs/remotes/origin/HEAD refs/remotes/origin/main
|
||||
```
|
||||
|
||||
How to report bugs
|
||||
------------------
|
||||
|
||||
|
||||
@@ -164,6 +164,21 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "pango",
|
||||
"buildsystem" : "meson",
|
||||
"builddir" : true,
|
||||
"config-opts" : [
|
||||
"--libdir=/app/lib"
|
||||
],
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "git",
|
||||
"url" : "https://gitlab.gnome.org/GNOME/pango.git",
|
||||
"branch" : "main"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "gtk",
|
||||
"buildsystem" : "meson",
|
||||
@@ -177,7 +192,8 @@
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "git",
|
||||
"url" : "https://gitlab.gnome.org/GNOME/gtk.git"
|
||||
"url" : "https://gitlab.gnome.org/GNOME/gtk.git",
|
||||
"branch" : "main"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -93,6 +93,21 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "pango",
|
||||
"buildsystem" : "meson",
|
||||
"builddir" : true,
|
||||
"config-opts" : [
|
||||
"--libdir=/app/lib"
|
||||
],
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "git",
|
||||
"url" : "https://gitlab.gnome.org/GNOME/pango.git",
|
||||
"branch" : "main"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "gtk",
|
||||
"buildsystem" : "meson",
|
||||
@@ -106,7 +121,8 @@
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "git",
|
||||
"url" : "https://gitlab.gnome.org/GNOME/gtk.git"
|
||||
"url" : "https://gitlab.gnome.org/GNOME/gtk.git",
|
||||
"branch" : "main"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -93,6 +93,21 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "pango",
|
||||
"buildsystem" : "meson",
|
||||
"builddir" : true,
|
||||
"config-opts" : [
|
||||
"--libdir=/app/lib"
|
||||
],
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "git",
|
||||
"url" : "https://gitlab.gnome.org/GNOME/pango.git",
|
||||
"branch" : "main"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "gtk",
|
||||
"buildsystem" : "meson",
|
||||
@@ -106,7 +121,8 @@
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "git",
|
||||
"url" : "https://gitlab.gnome.org/GNOME/gtk.git"
|
||||
"url" : "https://gitlab.gnome.org/GNOME/gtk.git",
|
||||
"branch" : "main"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
+316
-127
@@ -1,12 +1,10 @@
|
||||
/* Clipboard
|
||||
*
|
||||
* GdkClipboard is used for clipboard handling. This demo shows how to
|
||||
* copy and paste text to and from the clipboard.
|
||||
* copy and paste text, images, colors or files to and from the clipboard.
|
||||
*
|
||||
* It also shows how to transfer images via the clipboard or via
|
||||
* drag-and-drop, and how to make clipboard contents persist after
|
||||
* the application exits. Clipboard persistence requires a clipboard
|
||||
* manager to run.
|
||||
* You can also use Drag-And-Drop to copy the data from the source to the
|
||||
* target.
|
||||
*/
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
@@ -14,22 +12,103 @@
|
||||
#include <string.h>
|
||||
#include "demoimage.h"
|
||||
|
||||
static GtkWidget *window = NULL;
|
||||
static void
|
||||
copy_button_clicked (GtkStack *source_stack,
|
||||
gpointer user_data)
|
||||
{
|
||||
GdkClipboard *clipboard;
|
||||
const char *visible_child_name;
|
||||
GtkWidget *visible_child;
|
||||
|
||||
clipboard = gtk_widget_get_clipboard (GTK_WIDGET (source_stack));
|
||||
|
||||
visible_child = gtk_stack_get_visible_child (source_stack);
|
||||
visible_child_name = gtk_stack_get_visible_child_name (source_stack);
|
||||
|
||||
if (strcmp (visible_child_name, "Text") == 0)
|
||||
{
|
||||
gdk_clipboard_set_text (clipboard, gtk_editable_get_text (GTK_EDITABLE (visible_child)));
|
||||
}
|
||||
else if (strcmp (visible_child_name, "Image") == 0)
|
||||
{
|
||||
GtkWidget *child;
|
||||
|
||||
for (child = gtk_widget_get_first_child (visible_child); child; child = gtk_widget_get_next_sibling (child))
|
||||
{
|
||||
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (child)))
|
||||
{
|
||||
GtkWidget *image = gtk_widget_get_first_child (child);
|
||||
GdkPaintable *paintable = gtk_image_get_paintable (GTK_IMAGE (image));
|
||||
|
||||
if (GDK_IS_TEXTURE (paintable))
|
||||
gdk_clipboard_set (clipboard, GDK_TYPE_TEXTURE, paintable);
|
||||
else
|
||||
gdk_clipboard_set (clipboard, GDK_TYPE_PAINTABLE, paintable);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (strcmp (visible_child_name, "Color") == 0)
|
||||
{
|
||||
GdkRGBA color;
|
||||
|
||||
gtk_color_chooser_get_rgba (GTK_COLOR_CHOOSER (visible_child), &color);
|
||||
gdk_clipboard_set (clipboard, GDK_TYPE_RGBA, &color);
|
||||
}
|
||||
else if (strcmp (visible_child_name, "File") == 0)
|
||||
{
|
||||
gdk_clipboard_set (clipboard, G_TYPE_FILE, g_object_get_data (G_OBJECT (visible_child), "file"), NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_print ("TODO");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
copy_button_clicked (GtkWidget *button,
|
||||
gpointer user_data)
|
||||
present_value (GtkStack *dest_stack,
|
||||
const GValue *value)
|
||||
{
|
||||
GtkWidget *entry;
|
||||
GdkClipboard *clipboard;
|
||||
GtkWidget *child;
|
||||
|
||||
entry = GTK_WIDGET (user_data);
|
||||
if (G_VALUE_HOLDS (value, G_TYPE_FILE))
|
||||
{
|
||||
GFile *file;
|
||||
|
||||
/* Get the clipboard object */
|
||||
clipboard = gtk_widget_get_clipboard (entry);
|
||||
gtk_stack_set_visible_child_name (dest_stack, "File");
|
||||
child = gtk_stack_get_visible_child (dest_stack);
|
||||
|
||||
/* Set clipboard text */
|
||||
gdk_clipboard_set_text (clipboard, gtk_editable_get_text (GTK_EDITABLE (entry)));
|
||||
file = g_value_get_object (value);
|
||||
g_object_set (child, "label", g_file_peek_path (file), NULL);
|
||||
}
|
||||
else if (G_VALUE_HOLDS (value, GDK_TYPE_RGBA))
|
||||
{
|
||||
GdkRGBA *color;
|
||||
|
||||
gtk_stack_set_visible_child_name (dest_stack, "Color");
|
||||
child = gtk_widget_get_first_child (gtk_stack_get_visible_child (dest_stack));
|
||||
|
||||
color = g_value_get_boxed (value);
|
||||
g_object_set (child, "rgba", color, NULL);
|
||||
}
|
||||
else if (G_VALUE_HOLDS (value, GDK_TYPE_TEXTURE) ||
|
||||
G_VALUE_HOLDS (value, GDK_TYPE_PAINTABLE))
|
||||
{
|
||||
GdkPaintable *paintable;
|
||||
|
||||
gtk_stack_set_visible_child_name (dest_stack, "Image");
|
||||
child = gtk_stack_get_visible_child (dest_stack);
|
||||
|
||||
paintable = g_value_get_object (value);
|
||||
g_object_set (child, "paintable", paintable, NULL);
|
||||
}
|
||||
else if (G_VALUE_HOLDS (value, G_TYPE_STRING))
|
||||
{
|
||||
gtk_stack_set_visible_child_name (dest_stack, "Text");
|
||||
child = gtk_stack_get_visible_child (dest_stack);
|
||||
|
||||
gtk_label_set_label (GTK_LABEL (child), g_value_get_string (value));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -37,149 +116,259 @@ paste_received (GObject *source_object,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkStack *dest_stack = user_data;
|
||||
GdkClipboard *clipboard;
|
||||
GtkWidget *entry;
|
||||
char *text;
|
||||
const GValue *value;
|
||||
GError *error = NULL;
|
||||
|
||||
clipboard = GDK_CLIPBOARD (source_object);
|
||||
entry = GTK_WIDGET (user_data);
|
||||
|
||||
/* Get the resulting text of the read operation */
|
||||
text = gdk_clipboard_read_text_finish (clipboard, result, &error);
|
||||
|
||||
if (text)
|
||||
value = gdk_clipboard_read_value_finish (clipboard, result, &error);
|
||||
if (value)
|
||||
{
|
||||
/* Set the entry text */
|
||||
gtk_editable_set_text (GTK_EDITABLE (entry), text);
|
||||
g_free (text);
|
||||
present_value (dest_stack, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
GtkWidget *dialog;
|
||||
|
||||
/* Show an error about why pasting failed.
|
||||
* Usually you probably want to ignore such failures,
|
||||
* but for demonstration purposes, we show the error.
|
||||
*/
|
||||
dialog = gtk_message_dialog_new (GTK_WINDOW (window),
|
||||
GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_MODAL,
|
||||
GTK_MESSAGE_ERROR,
|
||||
GTK_BUTTONS_CLOSE,
|
||||
"Could not paste text: %s",
|
||||
error->message);
|
||||
g_signal_connect (dialog, "response",
|
||||
G_CALLBACK (gtk_window_destroy), NULL);
|
||||
gtk_widget_show (dialog);
|
||||
|
||||
g_print ("%s\n", error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
paste_button_clicked (GtkWidget *button,
|
||||
gpointer user_data)
|
||||
paste_button_clicked (GtkStack *dest_stack,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkWidget *entry;
|
||||
GdkClipboard *clipboard;
|
||||
GdkContentFormats *formats;
|
||||
|
||||
entry = GTK_WIDGET (user_data);
|
||||
clipboard = gtk_widget_get_clipboard (GTK_WIDGET (dest_stack));
|
||||
formats = gdk_clipboard_get_formats (clipboard);
|
||||
|
||||
/* Get the clipboard object */
|
||||
clipboard = gtk_widget_get_clipboard (entry);
|
||||
if (gdk_content_formats_contain_gtype (formats, GDK_TYPE_TEXTURE))
|
||||
gdk_clipboard_read_value_async (clipboard, GDK_TYPE_TEXTURE, 0, NULL, paste_received, dest_stack);
|
||||
else if (gdk_content_formats_contain_gtype (formats, GDK_TYPE_PAINTABLE))
|
||||
gdk_clipboard_read_value_async (clipboard, GDK_TYPE_PAINTABLE, 0, NULL, paste_received, dest_stack);
|
||||
else if (gdk_content_formats_contain_gtype (formats, GDK_TYPE_RGBA))
|
||||
gdk_clipboard_read_value_async (clipboard, GDK_TYPE_RGBA, 0, NULL, paste_received, dest_stack);
|
||||
else if (gdk_content_formats_contain_gtype (formats, G_TYPE_FILE))
|
||||
gdk_clipboard_read_value_async (clipboard, G_TYPE_FILE, 0, NULL, paste_received, dest_stack);
|
||||
else if (gdk_content_formats_contain_gtype (formats, G_TYPE_STRING))
|
||||
gdk_clipboard_read_value_async (clipboard, G_TYPE_STRING, 0, NULL, paste_received, dest_stack);
|
||||
}
|
||||
|
||||
/* Request the contents of the clipboard, contents_received will be
|
||||
called when we do get the contents.
|
||||
*/
|
||||
gdk_clipboard_read_text_async (clipboard, NULL, paste_received, entry);
|
||||
static void
|
||||
update_copy_button_sensitivity (GtkWidget *source_stack)
|
||||
{
|
||||
GtkButton *copy_button;
|
||||
const char *visible_child_name;
|
||||
GtkWidget *visible_child;
|
||||
gboolean sensitive;
|
||||
|
||||
copy_button = GTK_BUTTON (g_object_get_data (G_OBJECT (source_stack), "copy-button"));
|
||||
|
||||
visible_child = gtk_stack_get_visible_child (GTK_STACK (source_stack));
|
||||
visible_child_name = gtk_stack_get_visible_child_name (GTK_STACK (source_stack));
|
||||
if (strcmp (visible_child_name, "Text") == 0)
|
||||
{
|
||||
sensitive = strlen (gtk_editable_get_text (GTK_EDITABLE (visible_child))) > 0;
|
||||
}
|
||||
else if (strcmp (visible_child_name, "Color") == 0 ||
|
||||
strcmp (visible_child_name, "Image") == 0)
|
||||
{
|
||||
sensitive = TRUE;
|
||||
}
|
||||
else if (strcmp (visible_child_name, "File") == 0)
|
||||
{
|
||||
sensitive = g_object_get_data (G_OBJECT (visible_child), "file") != NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
sensitive = FALSE;
|
||||
}
|
||||
|
||||
gtk_widget_set_sensitive (GTK_WIDGET (copy_button), sensitive);
|
||||
}
|
||||
|
||||
static void
|
||||
source_changed_cb (GtkButton *copy_button,
|
||||
GParamSpec *pspec,
|
||||
GtkWidget *source_stack)
|
||||
{
|
||||
update_copy_button_sensitivity (source_stack);
|
||||
}
|
||||
|
||||
static void
|
||||
text_changed_cb (GtkButton *copy_button,
|
||||
GParamSpec *pspec,
|
||||
GtkWidget *entry)
|
||||
{
|
||||
update_copy_button_sensitivity (gtk_widget_get_ancestor (entry, GTK_TYPE_STACK));
|
||||
}
|
||||
|
||||
static void
|
||||
file_button_set_file (GtkButton *button,
|
||||
GFile *file)
|
||||
{
|
||||
gtk_label_set_label (GTK_LABEL (gtk_button_get_child (button)), g_file_peek_path (file));
|
||||
g_object_set_data_full (G_OBJECT (button), "file", g_object_ref (file), g_object_unref);
|
||||
}
|
||||
|
||||
static void
|
||||
file_chooser_response (GtkNativeDialog *dialog,
|
||||
int response,
|
||||
GtkButton *button)
|
||||
{
|
||||
gtk_native_dialog_hide (dialog);
|
||||
|
||||
if (response == GTK_RESPONSE_ACCEPT)
|
||||
{
|
||||
GFile *file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog));
|
||||
file_button_set_file (button, file);
|
||||
g_object_unref (file);
|
||||
|
||||
update_copy_button_sensitivity (gtk_widget_get_ancestor (GTK_WIDGET (button), GTK_TYPE_STACK));
|
||||
}
|
||||
|
||||
gtk_native_dialog_destroy (dialog);
|
||||
}
|
||||
|
||||
static void
|
||||
open_file_cb (GtkWidget *button)
|
||||
{
|
||||
GtkFileChooserNative *chooser;
|
||||
|
||||
chooser = gtk_file_chooser_native_new ("Choose a file",
|
||||
GTK_WINDOW (gtk_widget_get_ancestor (button, GTK_TYPE_WINDOW)),
|
||||
GTK_FILE_CHOOSER_ACTION_OPEN,
|
||||
"_Open",
|
||||
"_Cancel");
|
||||
|
||||
g_signal_connect (chooser, "response", G_CALLBACK (file_chooser_response), button);
|
||||
gtk_native_dialog_show (GTK_NATIVE_DIALOG (chooser));
|
||||
}
|
||||
|
||||
static void
|
||||
update_paste_button_sensitivity (GdkClipboard *clipboard,
|
||||
GtkWidget *paste_button)
|
||||
{
|
||||
GdkContentFormats *formats;
|
||||
gboolean sensitive = FALSE;
|
||||
|
||||
formats = gdk_clipboard_get_formats (clipboard);
|
||||
|
||||
if (gdk_content_formats_contain_gtype (formats, G_TYPE_FILE) ||
|
||||
gdk_content_formats_contain_gtype (formats, GDK_TYPE_RGBA) ||
|
||||
gdk_content_formats_contain_gtype (formats, GDK_TYPE_TEXTURE) ||
|
||||
gdk_content_formats_contain_gtype (formats, GDK_TYPE_PAINTABLE) ||
|
||||
gdk_content_formats_contain_gtype (formats, G_TYPE_STRING))
|
||||
sensitive = TRUE;
|
||||
|
||||
gtk_widget_set_sensitive (paste_button, sensitive);
|
||||
}
|
||||
|
||||
static void
|
||||
unset_clipboard_handler (gpointer data)
|
||||
{
|
||||
GdkClipboard *clipboard = gtk_widget_get_clipboard (GTK_WIDGET (data));
|
||||
|
||||
g_signal_handlers_disconnect_by_func (clipboard, update_paste_button_sensitivity, data);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
on_drop (GtkStack *dest_stack,
|
||||
const GValue *value,
|
||||
double x,
|
||||
double y,
|
||||
gpointer data)
|
||||
{
|
||||
present_value (dest_stack, value);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GdkContentProvider *
|
||||
drag_prepare (GtkDragSource *drag_source,
|
||||
double x,
|
||||
double y,
|
||||
gpointer data)
|
||||
{
|
||||
GtkWidget *button;
|
||||
GValue value = G_VALUE_INIT;
|
||||
|
||||
button = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (drag_source));
|
||||
|
||||
if (GTK_IS_TOGGLE_BUTTON (button))
|
||||
{
|
||||
GtkWidget *image = gtk_widget_get_first_child (button);
|
||||
GdkPaintable *paintable = gtk_image_get_paintable (GTK_IMAGE (image));
|
||||
|
||||
if (GDK_IS_TEXTURE (paintable))
|
||||
{
|
||||
g_value_init (&value, GDK_TYPE_TEXTURE);
|
||||
g_value_set_object (&value, paintable);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_value_init (&value, GDK_TYPE_PAINTABLE);
|
||||
g_value_set_object (&value, paintable);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GFile *file = g_object_get_data (G_OBJECT (button), "file");
|
||||
|
||||
if (file)
|
||||
{
|
||||
g_value_init (&value, G_TYPE_FILE);
|
||||
g_value_set_object (&value, file);
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return gdk_content_provider_new_for_value (&value);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
do_clipboard (GtkWidget *do_widget)
|
||||
{
|
||||
static GtkWidget *window = NULL;
|
||||
|
||||
if (!window)
|
||||
{
|
||||
GtkWidget *vbox, *hbox;
|
||||
GtkWidget *label;
|
||||
GtkWidget *entry, *button;
|
||||
GtkWidget *image;
|
||||
GtkBuilderScope *scope;
|
||||
GtkBuilder *builder;
|
||||
GtkWidget *button;
|
||||
|
||||
window = gtk_window_new ();
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Clipboard");
|
||||
scope = gtk_builder_cscope_new ();
|
||||
gtk_builder_cscope_add_callback_symbols (GTK_BUILDER_CSCOPE (scope),
|
||||
"copy_button_clicked", G_CALLBACK (copy_button_clicked),
|
||||
"paste_button_clicked", G_CALLBACK (paste_button_clicked),
|
||||
"source_changed_cb", G_CALLBACK (source_changed_cb),
|
||||
"text_changed_cb", G_CALLBACK (text_changed_cb),
|
||||
"open_file_cb", G_CALLBACK (open_file_cb),
|
||||
"on_drop", G_CALLBACK (on_drop),
|
||||
"drag_prepare", G_CALLBACK (drag_prepare),
|
||||
NULL);
|
||||
|
||||
builder = gtk_builder_new ();
|
||||
gtk_builder_set_scope (builder, scope);
|
||||
gtk_builder_add_from_resource (builder, "/clipboard/clipboard.ui", NULL);
|
||||
|
||||
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
|
||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
||||
gtk_window_set_display (GTK_WINDOW (window), gtk_widget_get_display (do_widget));
|
||||
|
||||
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
||||
gtk_widget_set_margin_start (vbox, 8);
|
||||
gtk_widget_set_margin_end (vbox, 8);
|
||||
gtk_widget_set_margin_top (vbox, 8);
|
||||
gtk_widget_set_margin_bottom (vbox, 8);
|
||||
button = GTK_WIDGET (gtk_builder_get_object (builder, "copy_button"));
|
||||
g_object_set_data (gtk_builder_get_object (builder, "source_stack"), "copy-button", button);
|
||||
|
||||
gtk_window_set_child (GTK_WINDOW (window), vbox);
|
||||
button = GTK_WIDGET (gtk_builder_get_object (builder, "paste_button"));
|
||||
g_signal_connect (gtk_widget_get_clipboard (button), "changed",
|
||||
G_CALLBACK (update_paste_button_sensitivity), button);
|
||||
g_object_set_data_full (G_OBJECT (button), "clipboard-handler", button, unset_clipboard_handler);
|
||||
|
||||
label = gtk_label_new ("\"Copy\" will copy the text\nin the entry to the clipboard");
|
||||
|
||||
gtk_box_append (GTK_BOX (vbox), label);
|
||||
|
||||
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
|
||||
gtk_widget_set_margin_start (hbox, 8);
|
||||
gtk_widget_set_margin_end (hbox, 8);
|
||||
gtk_widget_set_margin_top (hbox, 8);
|
||||
gtk_widget_set_margin_bottom (hbox, 8);
|
||||
gtk_box_append (GTK_BOX (vbox), hbox);
|
||||
|
||||
/* Create the first entry */
|
||||
entry = gtk_entry_new ();
|
||||
gtk_box_append (GTK_BOX (hbox), entry);
|
||||
|
||||
/* Create the button */
|
||||
button = gtk_button_new_with_mnemonic (_("_Copy"));
|
||||
gtk_box_append (GTK_BOX (hbox), button);
|
||||
g_signal_connect (button, "clicked",
|
||||
G_CALLBACK (copy_button_clicked), entry);
|
||||
|
||||
label = gtk_label_new ("\"Paste\" will paste the text from the clipboard to the entry");
|
||||
gtk_box_append (GTK_BOX (vbox), label);
|
||||
|
||||
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
|
||||
gtk_widget_set_margin_start (hbox, 8);
|
||||
gtk_widget_set_margin_end (hbox, 8);
|
||||
gtk_widget_set_margin_top (hbox, 8);
|
||||
gtk_widget_set_margin_bottom (hbox, 8);
|
||||
gtk_box_append (GTK_BOX (vbox), hbox);
|
||||
|
||||
/* Create the second entry */
|
||||
entry = gtk_entry_new ();
|
||||
gtk_box_append (GTK_BOX (hbox), entry);
|
||||
|
||||
/* Create the button */
|
||||
button = gtk_button_new_with_mnemonic (_("_Paste"));
|
||||
gtk_box_append (GTK_BOX (hbox), button);
|
||||
g_signal_connect (button, "clicked",
|
||||
G_CALLBACK (paste_button_clicked), entry);
|
||||
|
||||
label = gtk_label_new ("Images can be transferred via the clipboard, too");
|
||||
gtk_box_append (GTK_BOX (vbox), label);
|
||||
|
||||
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
|
||||
gtk_widget_set_margin_start (hbox, 8);
|
||||
gtk_widget_set_margin_end (hbox, 8);
|
||||
gtk_widget_set_margin_top (hbox, 8);
|
||||
gtk_widget_set_margin_bottom (hbox, 8);
|
||||
gtk_box_append (GTK_BOX (vbox), hbox);
|
||||
|
||||
/* Create the first image */
|
||||
image = demo_image_new ("dialog-warning");
|
||||
gtk_box_append (GTK_BOX (hbox), image);
|
||||
|
||||
/* Create the second image */
|
||||
image = demo_image_new ("process-stop");
|
||||
gtk_box_append (GTK_BOX (hbox), image);
|
||||
|
||||
/* Create the third image */
|
||||
image = demo_image_new ("weather-clear");
|
||||
gtk_box_append (GTK_BOX (hbox), image);
|
||||
g_object_unref (builder);
|
||||
g_object_unref (scope);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
|
||||
@@ -0,0 +1,288 @@
|
||||
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<object class="GtkWindow" id="window">
|
||||
<property name="resizable">1</property>
|
||||
<property name="title">Clipboard</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="margin-start">12</property>
|
||||
<property name="margin-end">12</property>
|
||||
<property name="margin-top">12</property>
|
||||
<property name="margin-bottom">12</property>
|
||||
<property name="spacing">12</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">“Copy” will copy the selected data the clipboard, “Paste” will show the current clipboard contents. You can also drag the data to the bottom.</property>
|
||||
<property name="wrap">1</property>
|
||||
<property name="max-width-chars">40</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="spacing">12</property>
|
||||
<child>
|
||||
<object class="GtkDropDown" id="source_chooser">
|
||||
<property name="valign">center</property>
|
||||
<property name="model">
|
||||
<object class="GtkStringList">
|
||||
<items>
|
||||
<item>Text</item>
|
||||
<item>Color</item>
|
||||
<item>Image</item>
|
||||
<item>File</item>
|
||||
</items>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkStack" id="source_stack">
|
||||
<signal name="notify::visible-child" handler="source_changed_cb" object="copy_button"/>
|
||||
<property name="vexpand">1</property>
|
||||
<binding name="visible-child-name">
|
||||
<lookup name="string" type="GtkStringObject">
|
||||
<lookup name="selected-item">
|
||||
source_chooser
|
||||
</lookup>
|
||||
</lookup>
|
||||
</binding>
|
||||
<child>
|
||||
<object class="GtkStackPage">
|
||||
<property name="name">Text</property>
|
||||
<property name="child">
|
||||
<object class="GtkEntry" id="source_text">
|
||||
<property name="valign">center</property>
|
||||
<signal name="notify::text" handler="text_changed_cb" object="copy_button"/>
|
||||
<property name="text">Copy this!</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkStackPage">
|
||||
<property name="name">Color</property>
|
||||
<property name="child">
|
||||
<object class="GtkColorButton" id="source_color">
|
||||
<property name="valign">center</property>
|
||||
<property name="rgba">purple</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkStackPage">
|
||||
<property name="name">Image</property>
|
||||
<property name="child">
|
||||
<object class="GtkBox">
|
||||
<property name="valign">center</property>
|
||||
<style>
|
||||
<class name="linked"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="GtkToggleButton" id="image_rose">
|
||||
<property name="active">1</property>
|
||||
<child>
|
||||
<object class="GtkDragSource">
|
||||
<signal name="prepare" handler="drag_prepare"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<style>
|
||||
<class name="large-icons"/>
|
||||
</style>
|
||||
<property name="paintable">resource:///transparent/portland-rose.jpg</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToggleButton" id="image_floppy">
|
||||
<property name="group">image_rose</property>
|
||||
<child>
|
||||
<object class="GtkDragSource">
|
||||
<signal name="prepare" handler="drag_prepare"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<style>
|
||||
<class name="large-icons"/>
|
||||
</style>
|
||||
<property name="paintable">resource:///images/floppybuddy.gif</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToggleButton" id="image_logo">
|
||||
<property name="group">image_floppy</property>
|
||||
<child>
|
||||
<object class="GtkDragSource">
|
||||
<signal name="prepare" handler="drag_prepare"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<style>
|
||||
<class name="large-icons"/>
|
||||
</style>
|
||||
<property name="paintable">resource:///images/org.gtk.Demo4.svg</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkStackPage">
|
||||
<property name="name">File</property>
|
||||
<property name="child">
|
||||
<object class="GtkButton" id="source_file">
|
||||
<child>
|
||||
<object class="GtkDragSource">
|
||||
<property name="propagation-phase">capture</property>
|
||||
<signal name="prepare" handler="drag_prepare"/>
|
||||
</object>
|
||||
</child>
|
||||
<property name="valign">center</property>
|
||||
<property name="child">
|
||||
<object class="GtkLabel">
|
||||
<property name="label">—</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="ellipsize">start</property>
|
||||
</object>
|
||||
</property>
|
||||
<signal name="clicked" handler="open_file_cb"/>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="copy_button">
|
||||
<property name="valign">center</property>
|
||||
<property name="label" translatable="yes">_Copy</property>
|
||||
<signal name="clicked" handler="copy_button_clicked" object="source_stack"/>
|
||||
<property name="use-underline">1</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparator">
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="spacing">12</property>
|
||||
<child>
|
||||
<object class="GtkDropTarget">
|
||||
<property name="actions">copy</property>
|
||||
<property name="formats">GdkTexture GdkPaintable GFile GdkRGBA gchararray</property>
|
||||
<signal name="drop" handler="on_drop" object="dest_stack"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="paste_button">
|
||||
<property name="label" translatable="yes">_Paste</property>
|
||||
<signal name="clicked" handler="paste_button_clicked" object="dest_stack"/>
|
||||
<property name="use-underline">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="xalign">0</property>
|
||||
<binding name="label">
|
||||
<lookup name="visible-child-name" type="GtkStack">
|
||||
dest_stack
|
||||
</lookup>
|
||||
</binding>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkStack" id="dest_stack">
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">center</property>
|
||||
<child>
|
||||
<object class="GtkStackPage">
|
||||
<property name="name"></property>
|
||||
<property name="child">
|
||||
<object class="GtkLabel">
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkStackPage">
|
||||
<property name="name">Text</property>
|
||||
<property name="child">
|
||||
<object class="GtkLabel">
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="ellipsize">end</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkStackPage">
|
||||
<property name="name">Image</property>
|
||||
<property name="child">
|
||||
<object class="GtkImage">
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">center</property>
|
||||
<style>
|
||||
<class name="large-icons"/>
|
||||
</style>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkStackPage">
|
||||
<property name="name">Color</property>
|
||||
<property name="child">
|
||||
<object class="GtkBox">
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">center</property>
|
||||
<child>
|
||||
<object class="GtkColorSwatch">
|
||||
<property name="accessible-role">img</property>
|
||||
<property name="can-focus">0</property>
|
||||
<property name="selectable">0</property>
|
||||
<property name="has-menu">0</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkStackPage">
|
||||
<property name="name">File</property>
|
||||
<property name="child">
|
||||
<object class="GtkLabel">
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="hexpand">1</property>
|
||||
<property name="ellipsize">start</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
||||
@@ -15,6 +15,7 @@
|
||||
<file>demo.ui</file>
|
||||
</gresource>
|
||||
<gresource prefix="/clipboard">
|
||||
<file>clipboard.ui</file>
|
||||
<file>demoimage.c</file>
|
||||
<file>demoimage.h</file>
|
||||
</gresource>
|
||||
|
||||
@@ -7,7 +7,8 @@
|
||||
* shows.
|
||||
*
|
||||
* We also demonstrate adding other things to a text view, such as
|
||||
* clickable icons.
|
||||
* clickable icons and widgets which can also replace a character
|
||||
* (try copying the ghost text).
|
||||
*/
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
@@ -113,7 +114,12 @@ show_page (GtkTextView *text_view,
|
||||
gtk_level_bar_set_value (GTK_LEVEL_BAR (child), 50);
|
||||
gtk_widget_set_size_request (child, 100, -1);
|
||||
gtk_text_view_add_child_at_anchor (text_view, child, anchor);
|
||||
gtk_text_buffer_insert (buffer, &iter, ".", -1);
|
||||
gtk_text_buffer_insert (buffer, &iter, " and labels with ", -1);
|
||||
anchor = gtk_text_child_anchor_new_with_replacement ("👻");
|
||||
gtk_text_buffer_insert_child_anchor (buffer, &iter, anchor);
|
||||
child = gtk_label_new ("ghost");
|
||||
gtk_text_view_add_child_at_anchor (text_view, child, anchor);
|
||||
gtk_text_buffer_insert (buffer, &iter, " text.", -1);
|
||||
}
|
||||
else if (page == 2)
|
||||
{
|
||||
|
||||
@@ -192,7 +192,7 @@ activate_about (GSimpleAction *action,
|
||||
glib_micro_version);
|
||||
g_string_append_printf (s, "\tPango\t%s\n",
|
||||
pango_version_string ());
|
||||
g_string_append_printf (s, "\tGTK\t%d.%d.%d\n",
|
||||
g_string_append_printf (s, "\tGTK \t%d.%d.%d\n",
|
||||
gtk_get_major_version (),
|
||||
gtk_get_minor_version (),
|
||||
gtk_get_micro_version ());
|
||||
|
||||
@@ -140,7 +140,7 @@ if os_unix
|
||||
demos += files('pagesetup.c')
|
||||
endif
|
||||
|
||||
librsvg_dep = dependency('librsvg-2.0', version: '>= 2.46.0', required: false)
|
||||
librsvg_dep = dependency('librsvg-2.0', version: '>= 2.52.0', required: false)
|
||||
|
||||
if librsvg_dep.found()
|
||||
demos += files('paintable_svg.c')
|
||||
@@ -228,7 +228,9 @@ endif
|
||||
# Use a subset of compiler flags
|
||||
demo_cflags = []
|
||||
foreach flag: common_cflags
|
||||
if flag not in ['-Werror=missing-prototypes', '-Werror=missing-declarations', '-fvisibility=hidden']
|
||||
if flag not in ['-Werror=missing-prototypes', '-Wmissing-prototypes',
|
||||
'-Werror=missing-declarations', '-Wmissing-declarations',
|
||||
'-fvisibility=hidden']
|
||||
demo_cflags += flag
|
||||
endif
|
||||
endforeach
|
||||
|
||||
@@ -47,22 +47,24 @@ static int
|
||||
svg_paintable_get_intrinsic_width (GdkPaintable *paintable)
|
||||
{
|
||||
SvgPaintable *self = SVG_PAINTABLE (paintable);
|
||||
RsvgDimensionData data;
|
||||
double width;
|
||||
|
||||
rsvg_handle_get_dimensions (self->handle, &data);
|
||||
if (!rsvg_handle_get_intrinsic_size_in_pixels (self->handle, &width, NULL))
|
||||
return 0;
|
||||
|
||||
return data.width;
|
||||
return ceil (width);
|
||||
}
|
||||
|
||||
static int
|
||||
svg_paintable_get_intrinsic_height (GdkPaintable *paintable)
|
||||
{
|
||||
SvgPaintable *self = SVG_PAINTABLE (paintable);
|
||||
RsvgDimensionData data;
|
||||
double height;
|
||||
|
||||
rsvg_handle_get_dimensions (self->handle, &data);
|
||||
if (!rsvg_handle_get_intrinsic_size_in_pixels (self->handle, NULL, &height))
|
||||
return 0;
|
||||
|
||||
return data.height;
|
||||
return ceil (height);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
+11
-5
@@ -1,6 +1,11 @@
|
||||
/* Text View/Tabs
|
||||
*
|
||||
* GtkTextView can position text at fixed positions, using tabs.
|
||||
* Tabs can specify alignment, and also allow aligning numbers
|
||||
* on the decimal point.
|
||||
*
|
||||
* The example here has three tabs, with left, numeric and right
|
||||
* alignment.
|
||||
*/
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
@@ -22,7 +27,7 @@ do_tabs (GtkWidget *do_widget)
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Tabs");
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
gtk_window_set_default_size (GTK_WINDOW (window), 330, 330);
|
||||
gtk_window_set_default_size (GTK_WINDOW (window), 330, 130);
|
||||
gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
|
||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
||||
|
||||
@@ -35,17 +40,18 @@ do_tabs (GtkWidget *do_widget)
|
||||
|
||||
tabs = pango_tab_array_new (3, TRUE);
|
||||
pango_tab_array_set_tab (tabs, 0, PANGO_TAB_LEFT, 0);
|
||||
pango_tab_array_set_tab (tabs, 1, PANGO_TAB_LEFT, 100);
|
||||
pango_tab_array_set_tab (tabs, 2, PANGO_TAB_LEFT, 200);
|
||||
pango_tab_array_set_tab (tabs, 1, PANGO_TAB_DECIMAL, 150);
|
||||
pango_tab_array_set_decimal_point (tabs, 1, '.');
|
||||
pango_tab_array_set_tab (tabs, 2, PANGO_TAB_RIGHT, 290);
|
||||
gtk_text_view_set_tabs (GTK_TEXT_VIEW (view), tabs);
|
||||
pango_tab_array_free (tabs);
|
||||
|
||||
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
|
||||
gtk_text_buffer_set_text (buffer, "one\ttwo\tthree\nfour\tfive\tsix\nseven\teight\tnine", -1);
|
||||
gtk_text_buffer_set_text (buffer, "one\t2.0\tthree\nfour\t5.555\tsix\nseven\t88.88\tnine", -1);
|
||||
|
||||
sw = gtk_scrolled_window_new ();
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
|
||||
GTK_POLICY_AUTOMATIC,
|
||||
GTK_POLICY_NEVER,
|
||||
GTK_POLICY_AUTOMATIC);
|
||||
gtk_window_set_child (GTK_WINDOW (window), sw);
|
||||
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), view);
|
||||
|
||||
@@ -72,7 +72,7 @@ about_activated (GSimpleAction *action,
|
||||
glib_micro_version);
|
||||
g_string_append_printf (s, "\tPango\t%s\n",
|
||||
pango_version_string ());
|
||||
g_string_append_printf (s, "\tGTK\t%d.%d.%d\n",
|
||||
g_string_append_printf (s, "\tGTK \t%d.%d.%d\n",
|
||||
gtk_get_major_version (),
|
||||
gtk_get_minor_version (),
|
||||
gtk_get_micro_version ());
|
||||
|
||||
@@ -79,7 +79,7 @@ activate_about (GSimpleAction *action,
|
||||
glib_micro_version);
|
||||
g_string_append_printf (s, "\tPango\t%s\n",
|
||||
pango_version_string ());
|
||||
g_string_append_printf (s, "\tGTK\t%d.%d.%d\n",
|
||||
g_string_append_printf (s, "\tGTK \t%d.%d.%d\n",
|
||||
gtk_get_major_version (),
|
||||
gtk_get_minor_version (),
|
||||
gtk_get_micro_version ());
|
||||
|
||||
@@ -336,12 +336,39 @@ text_view_query_tooltip_cb (GtkWidget *widget,
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
load_bytes (NodeEditorWindow *self,
|
||||
GBytes *bytes);
|
||||
|
||||
static void
|
||||
load_error (NodeEditorWindow *self,
|
||||
const char *error_message)
|
||||
{
|
||||
PangoLayout *layout;
|
||||
GtkSnapshot *snapshot;
|
||||
GskRenderNode *node;
|
||||
GBytes *bytes;
|
||||
|
||||
layout = gtk_widget_create_pango_layout (GTK_WIDGET (self), error_message);
|
||||
pango_layout_set_width (layout, 300 * PANGO_SCALE);
|
||||
snapshot = gtk_snapshot_new ();
|
||||
gtk_snapshot_append_layout (snapshot, layout, &(GdkRGBA) { 0.7, 0.13, 0.13, 1.0 });
|
||||
node = gtk_snapshot_free_to_node (snapshot);
|
||||
bytes = gsk_render_node_serialize (node);
|
||||
|
||||
load_bytes (self, bytes);
|
||||
|
||||
gsk_render_node_unref (node);
|
||||
g_object_unref (layout);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
load_bytes (NodeEditorWindow *self,
|
||||
GBytes *bytes)
|
||||
{
|
||||
if (!g_utf8_validate (g_bytes_get_data (bytes, NULL), g_bytes_get_size (bytes), NULL))
|
||||
{
|
||||
load_error (self, "Invalid UTF-8");
|
||||
g_bytes_unref (bytes);
|
||||
return FALSE;
|
||||
}
|
||||
@@ -359,11 +386,16 @@ static gboolean
|
||||
load_file_contents (NodeEditorWindow *self,
|
||||
GFile *file)
|
||||
{
|
||||
GError *error = NULL;
|
||||
GBytes *bytes;
|
||||
|
||||
bytes = g_file_load_bytes (file, NULL, NULL, NULL);
|
||||
bytes = g_file_load_bytes (file, NULL, NULL, &error);
|
||||
if (bytes == NULL)
|
||||
return FALSE;
|
||||
{
|
||||
load_error (self, error->message);
|
||||
g_clear_error (&error);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return load_bytes (self, bytes);
|
||||
}
|
||||
@@ -473,17 +505,18 @@ node_editor_window_load (NodeEditorWindow *self,
|
||||
{
|
||||
GError *error = NULL;
|
||||
|
||||
g_clear_object (&self->file_monitor);
|
||||
|
||||
if (!load_file_contents (self, file))
|
||||
return FALSE;
|
||||
|
||||
g_clear_object (&self->file_monitor);
|
||||
self->file_monitor = g_file_monitor_file (file, G_FILE_MONITOR_NONE, NULL, &error);
|
||||
|
||||
|
||||
if (error)
|
||||
{
|
||||
g_warning ("couldn't monitor file: %s", error->message);
|
||||
g_error_free (error);
|
||||
g_clear_object (&self->file_monitor);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -161,9 +161,10 @@
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkPaned">
|
||||
<property name="shrink-start-child">false</property>
|
||||
<property name="shrink-end-child">false</property>
|
||||
<property name="position">400</property>
|
||||
<child>
|
||||
<property name="start-child">
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="hscrollbar-policy">never</property>
|
||||
<property name="hexpand">1</property>
|
||||
@@ -184,8 +185,8 @@
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
</property>
|
||||
<property name="end-child">
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
@@ -231,7 +232,7 @@
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
|
||||
@@ -42,7 +42,7 @@ update_statusbar (void)
|
||||
const char *print_str;
|
||||
|
||||
gtk_statusbar_pop (GTK_STATUSBAR (statusbar), 0);
|
||||
|
||||
|
||||
gtk_text_buffer_get_iter_at_mark (buffer,
|
||||
&iter,
|
||||
gtk_text_buffer_get_insert (buffer));
|
||||
@@ -56,7 +56,7 @@ update_statusbar (void)
|
||||
GtkPrintOperation *op = active_prints->data;
|
||||
print_str = gtk_print_operation_get_status_string (op);
|
||||
}
|
||||
|
||||
|
||||
msg = g_strdup_printf ("%d, %d%s %s",
|
||||
row, col,
|
||||
file_changed?" - Modified":"",
|
||||
@@ -188,10 +188,10 @@ save_file (GFile *save_filename)
|
||||
"Error saving to file %s:\n%s",
|
||||
display_name,
|
||||
error->message);
|
||||
|
||||
|
||||
g_signal_connect (error_dialog, "response", G_CALLBACK (gtk_window_destroy), NULL);
|
||||
gtk_widget_show (error_dialog);
|
||||
|
||||
|
||||
g_error_free (error);
|
||||
g_object_unref (info);
|
||||
}
|
||||
@@ -229,7 +229,7 @@ begin_print (GtkPrintOperation *operation,
|
||||
pango_font_description_free (desc);
|
||||
|
||||
pango_layout_set_width (print_data->layout, width * PANGO_SCALE);
|
||||
|
||||
|
||||
pango_layout_set_text (print_data->layout, print_data->text, -1);
|
||||
|
||||
num_lines = pango_layout_get_line_count (print_data->layout);
|
||||
@@ -241,7 +241,7 @@ begin_print (GtkPrintOperation *operation,
|
||||
{
|
||||
PangoRectangle ink_rect, logical_rect;
|
||||
double line_height;
|
||||
|
||||
|
||||
layout_line = pango_layout_get_line (print_data->layout, line);
|
||||
pango_layout_line_get_extents (layout_line, &ink_rect, &logical_rect);
|
||||
|
||||
@@ -258,7 +258,7 @@ begin_print (GtkPrintOperation *operation,
|
||||
|
||||
page_breaks = g_list_reverse (page_breaks);
|
||||
gtk_print_operation_set_n_pages (operation, g_list_length (page_breaks) + 1);
|
||||
|
||||
|
||||
print_data->page_breaks = page_breaks;
|
||||
}
|
||||
|
||||
@@ -287,11 +287,11 @@ draw_page (GtkPrintOperation *operation,
|
||||
end = pango_layout_get_line_count (print_data->layout);
|
||||
else
|
||||
end = GPOINTER_TO_INT (pagebreak->data);
|
||||
|
||||
|
||||
cr = gtk_print_context_get_cairo_context (context);
|
||||
|
||||
cairo_set_source_rgb (cr, 0, 0, 0);
|
||||
|
||||
|
||||
i = 0;
|
||||
start_pos = 0;
|
||||
iter = pango_layout_get_iter (print_data->layout);
|
||||
@@ -307,12 +307,12 @@ draw_page (GtkPrintOperation *operation,
|
||||
|
||||
pango_layout_iter_get_line_extents (iter, NULL, &logical_rect);
|
||||
baseline = pango_layout_iter_get_baseline (iter);
|
||||
|
||||
|
||||
if (i == start)
|
||||
start_pos = logical_rect.y / 1024.0;
|
||||
|
||||
|
||||
cairo_move_to (cr, logical_rect.x / 1024.0, baseline / 1024.0 - start_pos);
|
||||
|
||||
|
||||
pango_cairo_show_layout_line (cr, line);
|
||||
}
|
||||
i++;
|
||||
@@ -383,9 +383,9 @@ print_done (GtkPrintOperation *op,
|
||||
{
|
||||
|
||||
GtkWidget *error_dialog;
|
||||
|
||||
|
||||
gtk_print_operation_get_error (op, &error);
|
||||
|
||||
|
||||
error_dialog = gtk_message_dialog_new (GTK_WINDOW (main_window),
|
||||
GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||
GTK_MESSAGE_ERROR,
|
||||
@@ -405,13 +405,13 @@ print_done (GtkPrintOperation *op,
|
||||
g_free (print_data->text);
|
||||
g_free (print_data->font);
|
||||
g_free (print_data);
|
||||
|
||||
|
||||
if (!gtk_print_operation_is_finished (op))
|
||||
{
|
||||
g_object_ref (op);
|
||||
active_prints = g_list_append (active_prints, op);
|
||||
update_statusbar ();
|
||||
|
||||
|
||||
/* This ref is unref:ed when we get the final state change */
|
||||
g_signal_connect (op, "status_changed",
|
||||
G_CALLBACK (status_changed_cb), NULL);
|
||||
@@ -628,7 +628,7 @@ activate_about (GSimpleAction *action,
|
||||
glib_micro_version);
|
||||
g_string_append_printf (sysinfo, "\tPango\t%s\n",
|
||||
pango_version_string ());
|
||||
g_string_append_printf (sysinfo, "\tGTK\t%d.%d.%d\n",
|
||||
g_string_append_printf (sysinfo, "\tGTK \t%d.%d.%d\n",
|
||||
gtk_get_major_version (),
|
||||
gtk_get_minor_version (),
|
||||
gtk_get_micro_version ());
|
||||
|
||||
@@ -78,6 +78,21 @@ change_theme_state (GSimpleAction *action,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
change_fullscreen (GSimpleAction *action,
|
||||
GVariant *state,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkWindow *window = user_data;
|
||||
|
||||
if (g_variant_get_boolean (state))
|
||||
gtk_window_fullscreen (window);
|
||||
else
|
||||
gtk_window_unfullscreen (window);
|
||||
|
||||
g_simple_action_set_state (action, state);
|
||||
}
|
||||
|
||||
static GtkWidget *page_stack;
|
||||
|
||||
static void
|
||||
@@ -283,7 +298,7 @@ activate_about (GSimpleAction *action,
|
||||
glib_micro_version);
|
||||
g_string_append_printf (s, "\tPango\t%s\n",
|
||||
pango_version_string ());
|
||||
g_string_append_printf (s, "\tGTK\t%d.%d.%d\n",
|
||||
g_string_append_printf (s, "\tGTK \t%d.%d.%d\n",
|
||||
gtk_get_major_version (),
|
||||
gtk_get_minor_version (),
|
||||
gtk_get_micro_version ());
|
||||
@@ -384,7 +399,7 @@ print_operation_done (GtkPrintOperation *op,
|
||||
g_clear_error (&error);
|
||||
break;
|
||||
case GTK_PRINT_OPERATION_RESULT_APPLY:
|
||||
break;
|
||||
break;
|
||||
case GTK_PRINT_OPERATION_RESULT_CANCEL:
|
||||
g_print ("Printing was canceled\n");
|
||||
break;
|
||||
@@ -2012,11 +2027,12 @@ activate (GApplication *app)
|
||||
GMenuModel *model;
|
||||
static GActionEntry win_entries[] = {
|
||||
{ "dark", NULL, NULL, "false", change_dark_state },
|
||||
{ "theme", NULL, "s", "'current'", change_theme_state },
|
||||
{ "theme", NULL, "s", "'current'", change_theme_state },
|
||||
{ "transition", NULL, NULL, "true", change_transition_state },
|
||||
{ "search", activate_search, NULL, NULL, NULL },
|
||||
{ "delete", activate_delete, NULL, NULL, NULL },
|
||||
{ "busy", get_busy, NULL, NULL, NULL },
|
||||
{ "fullscreen", NULL, NULL, "false", change_fullscreen },
|
||||
{ "background", activate_background, NULL, NULL, NULL },
|
||||
{ "open", activate_open, NULL, NULL, NULL },
|
||||
{ "record", activate_record, NULL, NULL, NULL },
|
||||
@@ -2182,7 +2198,7 @@ activate (GApplication *app)
|
||||
g_object_set_data (G_OBJECT (window), "searchbar", widget);
|
||||
|
||||
widget = (GtkWidget *)gtk_builder_get_object (builder, "infobar");
|
||||
g_signal_connect (widget, "response", G_CALLBACK (info_bar_response), NULL);
|
||||
g_signal_connect (widget, "response", G_CALLBACK (info_bar_response), NULL);
|
||||
g_object_set_data (G_OBJECT (window), "infobar", widget);
|
||||
|
||||
dialog = (GtkWidget *)gtk_builder_get_object (builder, "info_dialog");
|
||||
|
||||
@@ -6,6 +6,10 @@
|
||||
<attribute name="label" translatable="yes">Get Busy</attribute>
|
||||
<attribute name="action">win.busy</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">Fullscreen</attribute>
|
||||
<attribute name="action">win.fullscreen</attribute>
|
||||
</item>
|
||||
<submenu>
|
||||
<attribute name="label" translatable="yes">Style</attribute>
|
||||
<section>
|
||||
@@ -2923,7 +2927,7 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
<property name="resizable">0</property>
|
||||
<property name="modal">1</property>
|
||||
<property name="text" translatable="1">Do something?</property>
|
||||
<property name="secondary-text" translatable="1">If you do something,
|
||||
<property name="secondary-text" translatable="1">If you don't do something,
|
||||
bad things might happen.</property>
|
||||
<property name="hide-on-close">1</property>
|
||||
<child type="action">
|
||||
|
||||
@@ -3,6 +3,7 @@ version = "@version@"
|
||||
browse_url = "https://gitlab.gnome.org/GNOME/gtk/"
|
||||
repository_url = "https://gitlab.gnome.org/GNOME/gtk.git"
|
||||
website_url = "https://www.gtk.org"
|
||||
docs_url = "https://docs.gtk.org/gdk4/"
|
||||
authors = "GTK Development Team"
|
||||
logo_url = "gtk-logo.svg"
|
||||
license = "LGPL-2.1-or-later"
|
||||
|
||||
@@ -33,7 +33,7 @@ calls to different backends, and error out on unsupported windowing systems:
|
||||
else
|
||||
#endif
|
||||
#ifdef GDK_WINDOWING_WAYLAND
|
||||
if (GTK_IS_WAYLAND_DISPLAY (display))
|
||||
if (GDK_IS_WAYLAND_DISPLAY (display))
|
||||
{
|
||||
// make Wayland-specific calls here
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ calls to different backends, and error out on unsupported windowing systems:
|
||||
#endif
|
||||
|
||||
#ifdef GDK_WINDOWING_WAYLAND
|
||||
if (GTK_IS_WAYLAND_DISPLAY (display))
|
||||
if (GDK_IS_WAYLAND_DISPLAY (display))
|
||||
{
|
||||
// make Wayland-specific calls here
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ calls to different backends, and error out on unsupported windowing systems:
|
||||
else
|
||||
#endif
|
||||
#ifdef GDK_WINDOWING_WAYLAND
|
||||
if (GTK_IS_WAYLAND_DISPLAY (display))
|
||||
if (GDK_IS_WAYLAND_DISPLAY (display))
|
||||
{
|
||||
// make Wayland-specific calls here
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ version = "@version@"
|
||||
browse_url = "https://gitlab.gnome.org/GNOME/gtk/"
|
||||
repository_url = "https://gitlab.gnome.org/GNOME/gtk.git"
|
||||
website_url = "https://www.gtk.org"
|
||||
docs_url = "https://docs.gtk.org/gsk4/"
|
||||
authors = "GTK Development Team"
|
||||
logo_url = "gtk-logo.svg"
|
||||
license = "LGPL-2.1-or-later"
|
||||
|
||||
@@ -16,6 +16,7 @@ SYNOPSIS
|
||||
| **gtk4-builder-tool** enumerate <FILE>
|
||||
| **gtk4-builder-tool** simplify [OPTIONS...] <FILE>
|
||||
| **gtk4-builder-tool** preview [OPTIONS...] <FILE>
|
||||
| **gtk4-builder-tool** precompile [OPTIONS...] <FILE>
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
@@ -83,3 +84,10 @@ to do manual fixups after the initial conversion.
|
||||
``--3to4``
|
||||
|
||||
Transform a GTK 3 UI definition file to the equivalent GTK 4 definitions.
|
||||
|
||||
Precompilation
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
The ``precompile`` command creates a more compact, and faster to load compiled
|
||||
form of the ui file that is understood by GtkBuilder. The output is written
|
||||
to a file with the extension ``.precompiled``.
|
||||
|
||||
@@ -3,6 +3,7 @@ version = "@version@"
|
||||
browse_url = "https://gitlab.gnome.org/GNOME/gtk/"
|
||||
repository_url = "https://gitlab.gnome.org/GNOME/gtk.git"
|
||||
website_url = "https://www.gtk.org"
|
||||
docs_url = "https://docs.gtk.org/gtk4/"
|
||||
authors = "GTK Development Team"
|
||||
logo_url = "gtk-logo.svg"
|
||||
license = "LGPL-2.1-or-later"
|
||||
|
||||
@@ -315,7 +315,7 @@ have been added to `GdkDisplay`.
|
||||
|
||||
The root window is an X11-centric concept that is no longer exposed in the
|
||||
backend-neutral GDK API. If you need to interact with the X11 root window,
|
||||
you can use [method@GdkX11.Display.get_xrootwindow] to get its XID.
|
||||
you can use [`method@GdkX11.Display.get_xrootwindow`] to get its XID.
|
||||
|
||||
### Stop using `GdkVisual`
|
||||
|
||||
@@ -333,9 +333,9 @@ had replacements in GTK 3 and were deprecated in favor of `GdkSeat`.
|
||||
|
||||
In GTK 4, the two roles of a standalone toplevel window and of a popup that
|
||||
is placed relative to a parent window have been separated out into two
|
||||
interfaces, [class@Gdk.Toplevel] and [class@Gdk.Popup]. Surfaces
|
||||
implementing these interfaces are created with [ctor@Gdk.Surface.new_toplevel]
|
||||
and [ctor@Gdk.Surface.new_popup], respectively, and they are presented on
|
||||
interfaces, [iface@Gdk.Toplevel] and [iface@Gdk.Popup]. Surfaces
|
||||
implementing these interfaces are created with [`ctor@Gdk.Surface.new_toplevel`]
|
||||
and [`ctor@Gdk.Surface.new_popup`], respectively, and they are presented on
|
||||
screen using [method@Gdk.Toplevel.present] and [method@Gdk.Popup.present].
|
||||
The `present()` functions take parameters in the form of an auxiliary layout
|
||||
struct, [struct@Gdk.PopupLayout] or [struct@Gdk.ToplevelLayout].
|
||||
@@ -362,9 +362,9 @@ windows, you you will have to use Xlib apis.
|
||||
|
||||
A number of minor API cleanups have happened in `GdkSurface`
|
||||
as well. For example, `gdk_surface_input_shape_combine_region()`
|
||||
has been renamed to [method@Gdk.Surface.set_input_region], and
|
||||
has been renamed to [`method@Gdk.Surface.set_input_region`], and
|
||||
`gdk_surface_begin_resize_drag()` has been renamed to
|
||||
[method@Gdk.Toplevel.begin_resize].
|
||||
[`method@Gdk.Toplevel.begin_resize`].
|
||||
|
||||
### The "iconified" window state has been renamed to "minimized"
|
||||
|
||||
@@ -388,7 +388,7 @@ have accessors that you will have to use.
|
||||
|
||||
Event compression is always enabled in GTK 4, for both motion and
|
||||
scroll events. If you need to see the uncoalesced motion or scroll
|
||||
history, use [method@Gdk.Event.get_history] on the latest event.
|
||||
history, use [`method@Gdk.Event.get_history`] on the latest event.
|
||||
|
||||
### Stop using grabs
|
||||
|
||||
@@ -410,8 +410,8 @@ have been removed. Update your code accordingly.
|
||||
Any APIs that deal with global (or root) coordinates have been
|
||||
removed in GTK 4, since not all backends support them. You should
|
||||
replace your use of such APIs with surface-relative equivalents.
|
||||
Examples of this are `gdk_surface_get_origin()`, `gdk_surface_move()`
|
||||
or `gdk_event_get_root_coords()`.
|
||||
Examples of such removed APIs are `gdk_window_get_origin()`,
|
||||
`gdk_window_move()` or `gdk_event_get_root_coords()`.
|
||||
|
||||
### Adapt to `GdkKeymap` API changes
|
||||
|
||||
@@ -1054,7 +1054,7 @@ Observing widget contents and widget size is now done by using the
|
||||
|
||||
### Monitor handling has changed
|
||||
|
||||
Instead of a monitor number, [class@Gdk.Monitor] is now used throughout.
|
||||
Instead of a monitor number, [class@Gdk.Monitor] is now used throughout.
|
||||
[method@Gdk.Display.get_monitors] returns the list of monitors that can be queried
|
||||
or observed for monitors to pass to APIs like [method@Gtk.Window.fullscreen_on_monitor].
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ the question you have, this list is a good place to start.
|
||||
(most of it about GTK 2.x and 3.x, but still somewhat applicable). This
|
||||
reference manual also contains a introductory
|
||||
[Getting Started](#gtk-getting-started) part.
|
||||
|
||||
|
||||
More documentation ranging from whitepapers to online books can be found at
|
||||
the [GNOME developer's site](https://developer.gnome.org). After studying these
|
||||
materials you should be well prepared to come back to this reference manual for details.
|
||||
@@ -93,11 +93,11 @@ the question you have, this list is a good place to start.
|
||||
|
||||
`gi18n.h` provides the following shorthand macros for convenience.
|
||||
Conventionally, people define macros as follows for convenience:
|
||||
|
||||
|
||||
#define _(x) gettext (x)
|
||||
#define N_(x) x
|
||||
#define C_(ctx,x) pgettext (ctx, x)
|
||||
|
||||
|
||||
You use `N_()` (N stands for no-op) to mark a string for translation in
|
||||
a location where a function call to gettext() is not allowed, such as
|
||||
in an array initializer. You eventually have to call gettext() on the
|
||||
@@ -205,14 +205,14 @@ the question you have, this list is a good place to start.
|
||||
Here is an example showing the three approaches using the copyright
|
||||
sign © which has Unicode and ISO-8859-1 codepoint 169 and is represented
|
||||
in UTF-8 by the two bytes 194, 169, or `"\302\251"` as a string literal:
|
||||
|
||||
|
||||
g_print ("direct UTF-8: ©");
|
||||
g_print ("escaped UTF-8: \302\251");
|
||||
text = g_convert ("runtime conversion: ©", -1,
|
||||
"ISO-8859-1", "UTF-8", NULL, NULL, NULL);
|
||||
g_print (text);
|
||||
g_free (text);
|
||||
|
||||
|
||||
If you are using gettext() to localize your application, you need
|
||||
to call bind_textdomain_codeset() to ensure that translated strings
|
||||
are returned in UTF-8 encoding.
|
||||
@@ -432,10 +432,10 @@ the question you have, this list is a good place to start.
|
||||
|
||||
26. How do I associate some data with a row in the tree?
|
||||
|
||||
Remember that the [class@Gtk.TreeModel] columns don't necessarily have to be
|
||||
Remember that the [iface@Gtk.TreeModel] columns don't necessarily have to be
|
||||
displayed. So you can put non-user-visible data in your model just
|
||||
like any other data, and retrieve it with [method@Gtk.TreeModel.get].
|
||||
See the [tree widget overview](#TreeWidget).
|
||||
See the [tree widget overview](#TreeWidget).
|
||||
|
||||
27. How do I put an image and some text in the same column?
|
||||
|
||||
@@ -447,7 +447,7 @@ the question you have, this list is a good place to start.
|
||||
28. I can set data easily on my [class@Gtk.TreeStore] or [class@Gtk.ListStore] models using
|
||||
[method@Gtk.ListStore.set] and [method@Gtk.TreeStore.set], but can't read it back?
|
||||
|
||||
Both the [class@Gtk.TreeStore] and the [class@Gtk.ListStore] implement the [class@Gtk.TreeModel]
|
||||
Both the [class@Gtk.TreeStore] and the [class@Gtk.ListStore] implement the [iface@Gtk.TreeModel]
|
||||
interface. As a consequence, you can use any function this interface
|
||||
implements. The easiest way to read a set of data back is to use
|
||||
[method@Gtk.TreeModel.get].
|
||||
|
||||
@@ -133,7 +133,7 @@ gtk_text_buffer_set_text (buffer, "Hello, this is some text", -1);
|
||||
provider = gtk_css_provider_new ();
|
||||
gtk_css_provider_load_from_data (provider,
|
||||
"textview {"
|
||||
" font: 15 serif;"
|
||||
" font: 15px serif;"
|
||||
" color: green;"
|
||||
"}",
|
||||
-1);
|
||||
@@ -149,9 +149,9 @@ gtk_text_view_set_left_margin (GTK_TEXT_VIEW (view), 30);
|
||||
tag = gtk_text_buffer_create_tag (buffer, "blue_foreground",
|
||||
"foreground", "blue",
|
||||
NULL);
|
||||
gtk_text_buffer_get_iter_at_offset (buffer, &start, 7);
|
||||
gtk_text_buffer_get_iter_at_offset (buffer, &end, 12);
|
||||
gtk_text_buffer_apply_tag (buffer, tag, &start, &end);
|
||||
gtk_text_buffer_get_iter_at_offset (buffer, &start, 7);
|
||||
gtk_text_buffer_get_iter_at_offset (buffer, &end, 12);
|
||||
gtk_text_buffer_apply_tag (buffer, tag, &start, &end);
|
||||
```
|
||||
|
||||
The `gtk4-demo` application that comes with
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
|
||||
typedef struct _Deserializer Deserializer;
|
||||
|
||||
struct _Deserializer
|
||||
struct _Deserializer
|
||||
{
|
||||
const char * mime_type; /* interned */
|
||||
GType type;
|
||||
@@ -934,25 +934,6 @@ init (void)
|
||||
|
||||
formats = gdk_pixbuf_get_formats ();
|
||||
|
||||
/* Make sure png comes first */
|
||||
for (f = formats; f; f = f->next)
|
||||
{
|
||||
GdkPixbufFormat *fmt = f->data;
|
||||
char *name;
|
||||
|
||||
name = gdk_pixbuf_format_get_name (fmt);
|
||||
if (g_str_equal (name, "png"))
|
||||
{
|
||||
formats = g_slist_delete_link (formats, f);
|
||||
formats = g_slist_prepend (formats, fmt);
|
||||
|
||||
g_free (name);
|
||||
break;
|
||||
}
|
||||
|
||||
g_free (name);
|
||||
}
|
||||
|
||||
for (f = formats; f; f = f->next)
|
||||
{
|
||||
GdkPixbufFormat *fmt = f->data;
|
||||
|
||||
+26
-12
@@ -718,19 +718,33 @@ gdk_content_formats_builder_to_formats (GdkContentFormatsBuilder *builder)
|
||||
|
||||
g_return_val_if_fail (builder != NULL, NULL);
|
||||
|
||||
gtypes = g_new (GType, builder->n_gtypes + 1);
|
||||
i = builder->n_gtypes;
|
||||
gtypes[i--] = G_TYPE_INVALID;
|
||||
/* add backwards because most important type is last in the list */
|
||||
for (l = builder->gtypes; l; l = l->next)
|
||||
gtypes[i--] = GPOINTER_TO_SIZE (l->data);
|
||||
if (builder->n_gtypes > 0)
|
||||
{
|
||||
gtypes = g_new (GType, builder->n_gtypes + 1);
|
||||
i = builder->n_gtypes;
|
||||
gtypes[i--] = G_TYPE_INVALID;
|
||||
/* add backwards because most important type is last in the list */
|
||||
for (l = builder->gtypes; l; l = l->next)
|
||||
gtypes[i--] = GPOINTER_TO_SIZE (l->data);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtypes = NULL;
|
||||
}
|
||||
|
||||
mime_types = g_new (const char *, builder->n_mime_types + 1);
|
||||
i = builder->n_mime_types;
|
||||
mime_types[i--] = NULL;
|
||||
/* add backwards because most important type is last in the list */
|
||||
for (l = builder->mime_types; l; l = l->next)
|
||||
mime_types[i--] = l->data;
|
||||
if (builder->n_mime_types > 0)
|
||||
{
|
||||
mime_types = g_new (const char *, builder->n_mime_types + 1);
|
||||
i = builder->n_mime_types;
|
||||
mime_types[i--] = NULL;
|
||||
/* add backwards because most important type is last in the list */
|
||||
for (l = builder->mime_types; l; l = l->next)
|
||||
mime_types[i--] = l->data;
|
||||
}
|
||||
else
|
||||
{
|
||||
mime_types = NULL;
|
||||
}
|
||||
|
||||
result = gdk_content_formats_new_take (gtypes, builder->n_gtypes,
|
||||
mime_types, builder->n_mime_types);
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
|
||||
typedef struct _Serializer Serializer;
|
||||
|
||||
struct _Serializer
|
||||
struct _Serializer
|
||||
{
|
||||
const char * mime_type; /* interned */
|
||||
GType type;
|
||||
@@ -446,7 +446,7 @@ lookup_serializer (const char *mime_type,
|
||||
serializer->type == type)
|
||||
return serializer;
|
||||
}
|
||||
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -630,7 +630,7 @@ pixbuf_serializer (GdkContentSerializer *serializer)
|
||||
const GValue *value;
|
||||
GdkPixbuf *pixbuf;
|
||||
const char *name;
|
||||
|
||||
|
||||
name = gdk_content_serializer_get_user_data (serializer);
|
||||
value = gdk_content_serializer_get_value (serializer);
|
||||
|
||||
@@ -651,7 +651,7 @@ pixbuf_serializer (GdkContentSerializer *serializer)
|
||||
gdk_pixbuf_save_to_stream_async (pixbuf,
|
||||
gdk_content_serializer_get_output_stream (serializer),
|
||||
name,
|
||||
gdk_content_serializer_get_cancellable (serializer),
|
||||
gdk_content_serializer_get_cancellable (serializer),
|
||||
pixbuf_serializer_finish,
|
||||
serializer,
|
||||
g_str_equal (name, "png") ? "compression" : NULL, "2",
|
||||
@@ -823,7 +823,7 @@ file_uri_serializer (GdkContentSerializer *serializer)
|
||||
else if (G_VALUE_HOLDS (value, GDK_TYPE_FILE_LIST))
|
||||
{
|
||||
GSList *l;
|
||||
|
||||
|
||||
for (l = g_value_get_boxed (value); l; l = l->next)
|
||||
{
|
||||
uri = g_file_get_uri (l->data);
|
||||
@@ -867,7 +867,7 @@ file_text_serializer (GdkContentSerializer *serializer)
|
||||
{
|
||||
GString *str;
|
||||
GSList *l;
|
||||
|
||||
|
||||
str = g_string_new (NULL);
|
||||
|
||||
for (l = g_value_get_boxed (value); l; l = l->next)
|
||||
@@ -966,25 +966,6 @@ init (void)
|
||||
|
||||
formats = gdk_pixbuf_get_formats ();
|
||||
|
||||
/* Make sure png comes first */
|
||||
for (f = formats; f; f = f->next)
|
||||
{
|
||||
GdkPixbufFormat *fmt = f->data;
|
||||
char *name;
|
||||
|
||||
name = gdk_pixbuf_format_get_name (fmt);
|
||||
if (g_str_equal (name, "png"))
|
||||
{
|
||||
formats = g_slist_delete_link (formats, f);
|
||||
formats = g_slist_prepend (formats, fmt);
|
||||
|
||||
g_free (name);
|
||||
break;
|
||||
}
|
||||
|
||||
g_free (name);
|
||||
}
|
||||
|
||||
for (f = formats; f; f = f->next)
|
||||
{
|
||||
GdkPixbufFormat *fmt = f->data;
|
||||
|
||||
@@ -132,6 +132,8 @@ gdk_device_class_init (GdkDeviceClass *klass)
|
||||
* GdkDevice:source: (attributes org.gtk.Property.get=gdk_device_get_source)
|
||||
*
|
||||
* Source type for the device.
|
||||
*
|
||||
* Deprecated: 4.6: Use GdkDeviceTool:tool-type instead
|
||||
*/
|
||||
device_props[PROP_SOURCE] =
|
||||
g_param_spec_enum ("source",
|
||||
@@ -596,6 +598,8 @@ gdk_device_get_has_cursor (GdkDevice *device)
|
||||
* Determines the type of the device.
|
||||
*
|
||||
* Returns: a `GdkInputSource`
|
||||
*
|
||||
* Deprecated: 4.6: Use gdk_device_tool_get_tool_type() instead
|
||||
*/
|
||||
GdkInputSource
|
||||
gdk_device_get_source (GdkDevice *device)
|
||||
|
||||
+1
-1
@@ -92,7 +92,7 @@ GDK_AVAILABLE_IN_ALL
|
||||
GdkDisplay * gdk_device_get_display (GdkDevice *device);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkSeat * gdk_device_get_seat (GdkDevice *device);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GDK_DEPRECATED_IN_4_6_FOR(gdk_device_tool_get_tool_type)
|
||||
GdkDeviceTool * gdk_device_get_device_tool (GdkDevice *device);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
|
||||
+29
-25
@@ -1438,31 +1438,6 @@ describe_egl_config (EGLDisplay egl_display,
|
||||
}
|
||||
#endif
|
||||
|
||||
/*<private>
|
||||
* gdk_display_get_egl_display:
|
||||
* @self: a display
|
||||
*
|
||||
* Retrieves the EGL display connection object for the given GDK display.
|
||||
*
|
||||
* This function returns `NULL` if GL is not supported or GDK is using
|
||||
* a different OpenGL framework than EGL.
|
||||
*
|
||||
* Returns: (nullable): the EGL display object
|
||||
*/
|
||||
gpointer
|
||||
gdk_display_get_egl_display (GdkDisplay *self)
|
||||
{
|
||||
GdkDisplayPrivate *priv = gdk_display_get_instance_private (self);
|
||||
|
||||
g_return_val_if_fail (GDK_IS_DISPLAY (self), NULL);
|
||||
|
||||
if (!priv->egl_display &&
|
||||
!gdk_display_prepare_gl (self, NULL))
|
||||
return NULL;
|
||||
|
||||
return priv->egl_display;
|
||||
}
|
||||
|
||||
gpointer
|
||||
gdk_display_get_egl_config (GdkDisplay *self)
|
||||
{
|
||||
@@ -1789,6 +1764,35 @@ gdk_display_init_egl (GdkDisplay *self,
|
||||
}
|
||||
#endif
|
||||
|
||||
/*<private>
|
||||
* gdk_display_get_egl_display:
|
||||
* @self: a display
|
||||
*
|
||||
* Retrieves the EGL display connection object for the given GDK display.
|
||||
*
|
||||
* This function returns `NULL` if GL is not supported or GDK is using
|
||||
* a different OpenGL framework than EGL.
|
||||
*
|
||||
* Returns: (nullable): the EGL display object
|
||||
*/
|
||||
gpointer
|
||||
gdk_display_get_egl_display (GdkDisplay *self)
|
||||
{
|
||||
GdkDisplayPrivate *priv = gdk_display_get_instance_private (self);
|
||||
|
||||
g_return_val_if_fail (GDK_IS_DISPLAY (self), NULL);
|
||||
|
||||
#ifdef HAVE_EGL
|
||||
if (!priv->egl_display &&
|
||||
!gdk_display_prepare_gl (self, NULL))
|
||||
return NULL;
|
||||
|
||||
return priv->egl_display;
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
GdkDebugFlags
|
||||
gdk_display_get_debug_flags (GdkDisplay *display)
|
||||
{
|
||||
|
||||
@@ -105,7 +105,7 @@ struct _GdkDeleteEvent
|
||||
* GdkMotionEvent:
|
||||
* @state: (type GdkModifierType): a bit-mask representing the state of
|
||||
* the modifier keys (e.g. Control, Shift and Alt) set during the motion
|
||||
* event. See [enum@Gdk.ModifierType]
|
||||
* event. See [flags@Gdk.ModifierType]
|
||||
* @x: the x coordinate of the pointer relative to the surface.
|
||||
* @y: the y coordinate of the pointer relative to the surface.
|
||||
* @axes: @x, @y translated to the axes of @device, or %NULL if @device is
|
||||
@@ -132,7 +132,7 @@ struct _GdkMotionEvent
|
||||
* GdkButtonEvent:
|
||||
* @state: (type GdkModifierType): a bit-mask representing the state of
|
||||
* the modifier keys (e.g. Control, Shift and Alt) and the pointer
|
||||
* buttons. See [enum@Gdk.ModifierType]
|
||||
* buttons. See [flags@Gdk.ModifierType]
|
||||
* @button: the button which was pressed or released, numbered from 1 to 5.
|
||||
* Normally button 1 is the left mouse button, 2 is the middle button,
|
||||
* and 3 is the right button. On 2-button mice, the middle button can
|
||||
@@ -162,7 +162,7 @@ struct _GdkButtonEvent
|
||||
* GdkTouchEvent:
|
||||
* @state: (type GdkModifierType): a bit-mask representing the state of
|
||||
* the modifier keys (e.g. Control, Shift and Alt) and the pointer
|
||||
* buttons. See [enum@Gdk.ModifierType]
|
||||
* buttons. See [flags@Gdk.ModifierType]
|
||||
* @x: the x coordinate of the pointer relative to the surface
|
||||
* @y: the y coordinate of the pointer relative to the surface
|
||||
* @axes: @x, @y translated to the axes of the event's device, or %NULL
|
||||
@@ -200,7 +200,7 @@ struct _GdkTouchEvent
|
||||
* @y: the y coordinate of the pointer relative to the surface.
|
||||
* @state: (type GdkModifierType): a bit-mask representing the state of
|
||||
* the modifier keys (e.g. Control, Shift and Alt) and the pointer
|
||||
* buttons. See [enum@Gdk.ModifierType]
|
||||
* buttons. See [flags@Gdk.ModifierType]
|
||||
* @direction: the direction to scroll to (one of %GDK_SCROLL_UP,
|
||||
* %GDK_SCROLL_DOWN, %GDK_SCROLL_LEFT, %GDK_SCROLL_RIGHT or
|
||||
* %GDK_SCROLL_SMOOTH).
|
||||
@@ -256,7 +256,7 @@ typedef struct {
|
||||
* GdkKeyEvent:
|
||||
* @state: (type GdkModifierType): a bit-mask representing the state of
|
||||
* the modifier keys (e.g. Control, Shift and Alt) and the pointer
|
||||
* buttons. See [enum@Gdk.ModifierType]
|
||||
* buttons. See [flags@Gdk.ModifierType]
|
||||
* @keycode: the raw code of the key that was pressed or released.
|
||||
* @translated: the result of translating @keycode. First with the full
|
||||
* @state, then while ignoring Caps Lock.
|
||||
@@ -277,7 +277,7 @@ struct _GdkKeyEvent
|
||||
* GdkCrossingEvent:
|
||||
* @state: (type GdkModifierType): a bit-mask representing the state of
|
||||
* the modifier keys (e.g. Control, Shift and Alt) and the pointer
|
||||
* buttons. See [enum@Gdk.ModifierType]
|
||||
* buttons. See [flags@Gdk.ModifierType]
|
||||
* @mode: the crossing mode (%GDK_CROSSING_NORMAL, %GDK_CROSSING_GRAB,
|
||||
* %GDK_CROSSING_UNGRAB, %GDK_CROSSING_GTK_GRAB, %GDK_CROSSING_GTK_UNGRAB or
|
||||
* %GDK_CROSSING_STATE_CHANGED). %GDK_CROSSING_GTK_GRAB, %GDK_CROSSING_GTK_UNGRAB,
|
||||
@@ -383,7 +383,7 @@ struct _GdkDNDEvent
|
||||
* GdkTouchpadEvent:
|
||||
* @state: (type GdkModifierType): a bit-mask representing the state of
|
||||
* the modifier keys (e.g. Control, Shift and Alt) and the pointer
|
||||
* buttons. See [enum@Gdk.ModifierType]
|
||||
* buttons. See [flags@Gdk.ModifierType]
|
||||
* @phase: (type GdkTouchpadGesturePhase): the current phase of the gesture
|
||||
* @n_fingers: The number of fingers triggering the pinch
|
||||
* @time: the time of the event in milliseconds
|
||||
|
||||
@@ -2,3 +2,4 @@ BOOLEAN:BOXED
|
||||
BOOLEAN:OBJECT
|
||||
BOOLEAN:POINTER
|
||||
VOID:POINTER,POINTER,BOOLEAN,BOOLEAN
|
||||
VOID:INT,INT
|
||||
|
||||
+7
-4
@@ -58,8 +58,8 @@
|
||||
* It’s a low-level object, used to implement high-level objects
|
||||
* such as [class@Gtk.Window] or [class@Gtk.Dialog] in GTK.
|
||||
*
|
||||
* The surfaces you see in practice are either [class@Gdk.Toplevel] or
|
||||
* [class@Gdk.Popup], and those interfaces provide much of the required
|
||||
* The surfaces you see in practice are either [iface@Gdk.Toplevel] or
|
||||
* [iface@Gdk.Popup], and those interfaces provide much of the required
|
||||
* API to interact with these surfaces. Other, more specialized surface
|
||||
* types exist, but you will rarely interact with them directly.
|
||||
*/
|
||||
@@ -605,11 +605,14 @@ gdk_surface_class_init (GdkSurfaceClass *klass)
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
_gdk_marshal_VOID__INT_INT,
|
||||
G_TYPE_NONE,
|
||||
2,
|
||||
G_TYPE_INT,
|
||||
G_TYPE_INT);
|
||||
g_signal_set_va_marshaller (signals[LAYOUT],
|
||||
G_OBJECT_CLASS_TYPE (object_class),
|
||||
_gdk_marshal_VOID__INT_INTv);
|
||||
|
||||
/**
|
||||
* GdkSurface::render:
|
||||
@@ -2099,7 +2102,7 @@ gdk_surface_get_root_coords (GdkSurface *surface,
|
||||
*root_y = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
GDK_SURFACE_GET_CLASS (surface)->get_root_coords (surface, x, y, root_x, root_y);
|
||||
}
|
||||
|
||||
|
||||
+1
-44
@@ -28,8 +28,7 @@
|
||||
* `GdkPixbuf`, or a Cairo surface, or other pixel data.
|
||||
*
|
||||
* The ownership of the pixel data is transferred to the `GdkTexture`
|
||||
* instance; you can only make a copy of it, via [method@Gdk.Texture.download]
|
||||
* or [method@Gdk.Texture.download_float].
|
||||
* instance; you can only make a copy of it, via [method@Gdk.Texture.download].
|
||||
*
|
||||
* `GdkTexture` is an immutable object: That means you cannot change
|
||||
* anything about it other than increasing the reference count via
|
||||
@@ -743,48 +742,6 @@ gdk_texture_download (GdkTexture *texture,
|
||||
stride);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_texture_download_float:
|
||||
* @texture: a `GdkTexture`
|
||||
* @data: (array): pointer to enough memory to be filled with the
|
||||
* downloaded data of @texture
|
||||
* @stride: rowstride in elements, will usually be equal to
|
||||
* gdk_texture_get_width() * 4
|
||||
*
|
||||
* Downloads the @texture into local memory in a high dynamic range format.
|
||||
*
|
||||
* This may be an expensive operation, as the actual texture data
|
||||
* may reside on a GPU or on a remote display server and because the data
|
||||
* may need to be upsampled if it was not already available in this
|
||||
* format.
|
||||
*
|
||||
* You may want to use [method@Gdk.Texture.download] instead if you don't
|
||||
* need high dynamic range support.
|
||||
*
|
||||
* The data format of the downloaded data is equivalent to
|
||||
* GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED, so every downloaded
|
||||
* pixel requires 16 bytes of memory.
|
||||
*
|
||||
* Note that the caller is responsible to provide sufficiently
|
||||
* aligned memory to access the resulting data directly as floats.
|
||||
*
|
||||
* Since: 4.6
|
||||
*/
|
||||
void
|
||||
gdk_texture_download_float (GdkTexture *texture,
|
||||
float *data,
|
||||
gsize stride)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_TEXTURE (texture));
|
||||
g_return_if_fail (data != NULL);
|
||||
g_return_if_fail (stride >= gdk_texture_get_width (texture) * 4);
|
||||
|
||||
gdk_texture_do_download (texture,
|
||||
GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED,
|
||||
(guchar *) data,
|
||||
stride);
|
||||
}
|
||||
|
||||
GdkMemoryFormat
|
||||
gdk_texture_get_format (GdkTexture *self)
|
||||
{
|
||||
|
||||
@@ -89,10 +89,6 @@ GDK_AVAILABLE_IN_ALL
|
||||
void gdk_texture_download (GdkTexture *texture,
|
||||
guchar *data,
|
||||
gsize stride);
|
||||
GDK_AVAILABLE_IN_4_6
|
||||
void gdk_texture_download_float (GdkTexture *texture,
|
||||
float *data,
|
||||
gsize stride);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gdk_texture_save_to_png (GdkTexture *texture,
|
||||
const char *filename);
|
||||
|
||||
@@ -727,6 +727,13 @@ gdk_toplevel_begin_move (GdkToplevel *toplevel,
|
||||
timestamp);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_toplevel_titlebar_gesture:
|
||||
* @toplevel: a `GdkToplevel`
|
||||
* @gesture: a `GdkTitlebarGesture`
|
||||
*
|
||||
* Since: 4.4
|
||||
*/
|
||||
gboolean
|
||||
gdk_toplevel_titlebar_gesture (GdkToplevel *toplevel,
|
||||
GdkTitlebarGesture gesture)
|
||||
|
||||
@@ -115,6 +115,14 @@ typedef enum
|
||||
GDK_TOPLEVEL_STATE_LEFT_RESIZABLE = 1 << 15
|
||||
} GdkToplevelState;
|
||||
|
||||
/**
|
||||
* GdkTitlebarGesture:
|
||||
* @GDK_TITLEBAR_GESTURE_DOUBLE_CLICK:
|
||||
* @GDK_TITLEBAR_GESTURE_RIGHT_CLICK:
|
||||
* @GDK_TITLEBAR_GESTURE_MIDDLE_CLICK:
|
||||
*
|
||||
* Since: 4.4
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
GDK_TITLEBAR_GESTURE_DOUBLE_CLICK = 1,
|
||||
|
||||
@@ -251,7 +251,7 @@ gdk_load_png (GBytes *bytes,
|
||||
png_destroy_read_struct (&png, &info, NULL);
|
||||
g_set_error (error,
|
||||
GDK_TEXTURE_ERROR, GDK_TEXTURE_ERROR_UNSUPPORTED_CONTENT,
|
||||
_("Unsupportd color type %u in png image"), color_type);
|
||||
_("Unsupported color type %u in png image"), color_type);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -240,7 +240,7 @@ static const FormatData format_data[] = {
|
||||
[GDK_MEMORY_A8R8G8B8] = { GDK_MEMORY_R8G8B8A8, 8, 4, SAMPLEFORMAT_UINT, EXTRASAMPLE_UNASSALPHA },
|
||||
[GDK_MEMORY_R8G8B8A8] = { GDK_MEMORY_R8G8B8A8, 8, 4, SAMPLEFORMAT_UINT, EXTRASAMPLE_UNASSALPHA },
|
||||
[GDK_MEMORY_A8B8G8R8] = { GDK_MEMORY_R8G8B8A8, 8, 4, SAMPLEFORMAT_UINT, EXTRASAMPLE_UNASSALPHA },
|
||||
[GDK_MEMORY_R8G8B8] = { GDK_MEMORY_R8G8B8, 8, 3, SAMPLEFORMAT_UINT, 0 },
|
||||
[GDK_MEMORY_R8G8B8] = { GDK_MEMORY_R8G8B8, 8, 3, SAMPLEFORMAT_UINT, 0 },
|
||||
[GDK_MEMORY_B8G8R8] = { GDK_MEMORY_R8G8B8, 8, 3, SAMPLEFORMAT_UINT, 0 },
|
||||
[GDK_MEMORY_R16G16B16] = { GDK_MEMORY_R16G16B16, 16, 3, SAMPLEFORMAT_UINT, 0 },
|
||||
[GDK_MEMORY_R16G16B16A16_PREMULTIPLIED] = { GDK_MEMORY_R16G16B16A16_PREMULTIPLIED, 16, 4, SAMPLEFORMAT_UINT, EXTRASAMPLE_ASSOCALPHA },
|
||||
@@ -376,6 +376,13 @@ gdk_load_tiff (GBytes *input_bytes,
|
||||
G_GNUC_UNUSED gint64 before = GDK_PROFILER_CURRENT_TIME;
|
||||
|
||||
tif = tiff_open_read (input_bytes);
|
||||
if (!tif)
|
||||
{
|
||||
g_set_error_literal (error,
|
||||
GDK_TEXTURE_ERROR, GDK_TEXTURE_ERROR_CORRUPT_IMAGE,
|
||||
_("Could not load TIFF data"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
TIFFSetDirectory (tif, 0);
|
||||
|
||||
|
||||
@@ -3606,6 +3606,10 @@ tablet_tool_handle_proximity_out (void *data,
|
||||
g_object_unref (tablet->pointer_info.focus);
|
||||
tablet->pointer_info.focus = NULL;
|
||||
|
||||
tablet->pointer_info.button_modifiers &=
|
||||
~(GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK |
|
||||
GDK_BUTTON4_MASK | GDK_BUTTON5_MASK);
|
||||
|
||||
gdk_device_update_tool (tablet->stylus_device, NULL);
|
||||
g_clear_object (&tablet->pointer_info.cursor);
|
||||
}
|
||||
@@ -3621,7 +3625,6 @@ tablet_create_button_event_frame (GdkWaylandTabletData *tablet,
|
||||
GdkEventType evtype,
|
||||
guint button)
|
||||
{
|
||||
GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (tablet->seat);
|
||||
GdkEvent *event;
|
||||
|
||||
event = gdk_button_event_new (evtype,
|
||||
@@ -3629,7 +3632,7 @@ tablet_create_button_event_frame (GdkWaylandTabletData *tablet,
|
||||
tablet->logical_device,
|
||||
tablet->current_tool->tool,
|
||||
tablet->pointer_info.time,
|
||||
device_get_modifiers (seat->logical_pointer),
|
||||
device_get_modifiers (tablet->logical_device),
|
||||
button,
|
||||
tablet->pointer_info.surface_x,
|
||||
tablet->pointer_info.surface_y,
|
||||
|
||||
@@ -104,8 +104,6 @@ struct _GdkWaylandSurface
|
||||
|
||||
struct gtk_surface1 *gtk_surface;
|
||||
struct wl_egl_window *egl_window;
|
||||
struct zxdg_exported_v1 *xdg_exported;
|
||||
struct org_kde_kwin_server_decoration *server_decoration;
|
||||
} display_server;
|
||||
|
||||
struct wl_event_queue *event_queue;
|
||||
@@ -224,17 +222,8 @@ struct _GdkWaylandSurface
|
||||
|
||||
int state_freeze_count;
|
||||
|
||||
struct {
|
||||
GdkWaylandToplevelExported callback;
|
||||
gpointer user_data;
|
||||
GDestroyNotify destroy_func;
|
||||
} exported;
|
||||
|
||||
struct zxdg_imported_v1 *imported_transient_for;
|
||||
GHashTable *shortcuts_inhibitors;
|
||||
|
||||
struct zwp_idle_inhibitor_v1 *idle_inhibitor;
|
||||
size_t idle_inhibitor_refcount;
|
||||
};
|
||||
|
||||
typedef struct _GdkWaylandSurfaceClass GdkWaylandSurfaceClass;
|
||||
@@ -250,6 +239,18 @@ struct _GdkWaylandToplevel
|
||||
GdkWaylandSurface parent_instance;
|
||||
|
||||
GdkWaylandToplevel *transient_for;
|
||||
|
||||
struct org_kde_kwin_server_decoration *server_decoration;
|
||||
struct zxdg_exported_v1 *xdg_exported;
|
||||
|
||||
struct {
|
||||
GdkWaylandToplevelExported callback;
|
||||
gpointer user_data;
|
||||
GDestroyNotify destroy_func;
|
||||
} exported;
|
||||
|
||||
struct zwp_idle_inhibitor_v1 *idle_inhibitor;
|
||||
size_t idle_inhibitor_refcount;
|
||||
};
|
||||
|
||||
typedef struct
|
||||
@@ -329,7 +330,7 @@ static void update_popup_layout_state (GdkSurface *surface,
|
||||
int height,
|
||||
GdkPopupLayout *layout);
|
||||
|
||||
static gboolean gdk_wayland_surface_is_exported (GdkWaylandSurface *impl);
|
||||
static gboolean gdk_wayland_toplevel_is_exported (GdkWaylandToplevel *wayland_toplevel);
|
||||
|
||||
static void configure_toplevel_geometry (GdkSurface *surface);
|
||||
|
||||
@@ -988,9 +989,6 @@ gdk_wayland_surface_finalize (GObject *object)
|
||||
|
||||
impl = GDK_WAYLAND_SURFACE (object);
|
||||
|
||||
if (gdk_wayland_surface_is_exported (impl))
|
||||
gdk_wayland_toplevel_unexport_handle (GDK_TOPLEVEL (impl));
|
||||
|
||||
g_free (impl->title);
|
||||
|
||||
g_free (impl->application.application_id);
|
||||
@@ -1028,8 +1026,7 @@ is_realized_popup (GdkWaylandSurface *impl)
|
||||
impl->display_server.zxdg_popup_v6);
|
||||
}
|
||||
|
||||
static void gdk_wayland_surface_show (GdkSurface *surface,
|
||||
gboolean already_mapped);
|
||||
static void gdk_wayland_surface_show (GdkSurface *surface);
|
||||
static void gdk_wayland_surface_hide (GdkSurface *surface);
|
||||
|
||||
static void
|
||||
@@ -1062,7 +1059,7 @@ gdk_wayland_surface_maybe_resize (GdkSurface *surface,
|
||||
gdk_wayland_surface_update_size (surface, width, height, scale);
|
||||
|
||||
if (is_xdg_popup && is_visible && !impl->initial_configure_received)
|
||||
gdk_wayland_surface_show (surface, FALSE);
|
||||
gdk_wayland_surface_show (surface);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -2238,57 +2235,62 @@ void
|
||||
gdk_wayland_toplevel_announce_csd (GdkToplevel *toplevel)
|
||||
{
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (GDK_SURFACE (toplevel)));
|
||||
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (toplevel);
|
||||
GdkWaylandToplevel *toplevel_wayland;
|
||||
|
||||
g_return_if_fail (GDK_IS_WAYLAND_TOPLEVEL (toplevel));
|
||||
toplevel_wayland = GDK_WAYLAND_TOPLEVEL (toplevel);
|
||||
|
||||
if (!display_wayland->server_decoration_manager)
|
||||
return;
|
||||
impl->display_server.server_decoration =
|
||||
org_kde_kwin_server_decoration_manager_create (display_wayland->server_decoration_manager,
|
||||
impl->display_server.wl_surface);
|
||||
if (impl->display_server.server_decoration)
|
||||
org_kde_kwin_server_decoration_request_mode (impl->display_server.server_decoration,
|
||||
ORG_KDE_KWIN_SERVER_DECORATION_MANAGER_MODE_CLIENT);
|
||||
toplevel_wayland->server_decoration =
|
||||
org_kde_kwin_server_decoration_manager_create (display_wayland->server_decoration_manager,
|
||||
gdk_wayland_surface_get_wl_surface (GDK_SURFACE (toplevel_wayland)));
|
||||
if (toplevel_wayland->server_decoration)
|
||||
org_kde_kwin_server_decoration_request_mode (toplevel_wayland->server_decoration,
|
||||
ORG_KDE_KWIN_SERVER_DECORATION_MANAGER_MODE_CLIENT);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_wayland_toplevel_announce_ssd (GdkToplevel *toplevel)
|
||||
{
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (GDK_SURFACE (toplevel)));
|
||||
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (toplevel);
|
||||
GdkWaylandToplevel *toplevel_wayland;
|
||||
|
||||
g_return_if_fail (GDK_IS_WAYLAND_TOPLEVEL (toplevel));
|
||||
toplevel_wayland = GDK_WAYLAND_TOPLEVEL (toplevel);
|
||||
|
||||
if (!display_wayland->server_decoration_manager)
|
||||
return;
|
||||
impl->display_server.server_decoration =
|
||||
org_kde_kwin_server_decoration_manager_create (display_wayland->server_decoration_manager,
|
||||
impl->display_server.wl_surface);
|
||||
if (impl->display_server.server_decoration)
|
||||
org_kde_kwin_server_decoration_request_mode (impl->display_server.server_decoration,
|
||||
ORG_KDE_KWIN_SERVER_DECORATION_MANAGER_MODE_SERVER);
|
||||
toplevel_wayland->server_decoration =
|
||||
org_kde_kwin_server_decoration_manager_create (display_wayland->server_decoration_manager,
|
||||
gdk_wayland_surface_get_wl_surface (GDK_SURFACE (toplevel_wayland)));
|
||||
if (toplevel_wayland->server_decoration)
|
||||
org_kde_kwin_server_decoration_request_mode (toplevel_wayland->server_decoration,
|
||||
ORG_KDE_KWIN_SERVER_DECORATION_MANAGER_MODE_SERVER);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gdk_wayland_toplevel_inhibit_idle (GdkToplevel *toplevel)
|
||||
{
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (GDK_SURFACE (toplevel)));
|
||||
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (toplevel);
|
||||
GdkWaylandToplevel *wayland_toplevel;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_WAYLAND_TOPLEVEL (toplevel), FALSE);
|
||||
wayland_toplevel = GDK_WAYLAND_TOPLEVEL (toplevel);
|
||||
|
||||
if (!display_wayland->idle_inhibit_manager)
|
||||
return FALSE;
|
||||
|
||||
if (!impl->idle_inhibitor)
|
||||
if (!wayland_toplevel->idle_inhibitor)
|
||||
{
|
||||
g_assert (impl->idle_inhibitor_refcount == 0);
|
||||
impl->idle_inhibitor =
|
||||
zwp_idle_inhibit_manager_v1_create_inhibitor (display_wayland->idle_inhibit_manager,
|
||||
impl->display_server.wl_surface);
|
||||
g_assert (wayland_toplevel->idle_inhibitor &&
|
||||
wayland_toplevel->idle_inhibitor_refcount > 0);
|
||||
|
||||
wayland_toplevel->idle_inhibitor =
|
||||
zwp_idle_inhibit_manager_v1_create_inhibitor (display_wayland->idle_inhibit_manager,
|
||||
gdk_wayland_surface_get_wl_surface (GDK_SURFACE (wayland_toplevel)));
|
||||
}
|
||||
++impl->idle_inhibitor_refcount;
|
||||
++wayland_toplevel->idle_inhibitor_refcount;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -2296,14 +2298,19 @@ gdk_wayland_toplevel_inhibit_idle (GdkToplevel *toplevel)
|
||||
void
|
||||
gdk_wayland_toplevel_uninhibit_idle (GdkToplevel *toplevel)
|
||||
{
|
||||
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (toplevel);
|
||||
GdkWaylandToplevel *wayland_toplevel;
|
||||
|
||||
g_return_if_fail (GDK_IS_WAYLAND_TOPLEVEL (toplevel));
|
||||
wayland_toplevel = GDK_WAYLAND_TOPLEVEL (toplevel);
|
||||
|
||||
g_assert (impl->idle_inhibitor && impl->idle_inhibitor_refcount > 0);
|
||||
g_assert (wayland_toplevel->idle_inhibitor &&
|
||||
wayland_toplevel->idle_inhibitor_refcount > 0);
|
||||
|
||||
if (--impl->idle_inhibitor_refcount == 0)
|
||||
g_clear_pointer (&impl->idle_inhibitor, zwp_idle_inhibitor_v1_destroy);
|
||||
if (--wayland_toplevel->idle_inhibitor_refcount == 0)
|
||||
{
|
||||
g_clear_pointer (&wayland_toplevel->idle_inhibitor,
|
||||
zwp_idle_inhibitor_v1_destroy);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -2850,8 +2857,7 @@ gdk_wayland_surface_map_toplevel (GdkSurface *surface)
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_surface_show (GdkSurface *surface,
|
||||
gboolean already_mapped)
|
||||
gdk_wayland_surface_show (GdkSurface *surface)
|
||||
{
|
||||
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
|
||||
|
||||
@@ -4420,13 +4426,13 @@ xdg_exported_handle (void *data,
|
||||
const char *handle)
|
||||
{
|
||||
GdkToplevel *toplevel = data;
|
||||
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (toplevel);
|
||||
GdkWaylandToplevel *wayland_toplevel = GDK_WAYLAND_TOPLEVEL (toplevel);
|
||||
|
||||
impl->exported.callback (toplevel, handle, impl->exported.user_data);
|
||||
if (impl->exported.destroy_func)
|
||||
wayland_toplevel->exported.callback (toplevel, handle, wayland_toplevel->exported.user_data);
|
||||
if (wayland_toplevel->exported.destroy_func)
|
||||
{
|
||||
g_clear_pointer (&impl->exported.user_data,
|
||||
impl->exported.destroy_func);
|
||||
g_clear_pointer (&wayland_toplevel->exported.user_data,
|
||||
wayland_toplevel->exported.destroy_func);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4450,9 +4456,9 @@ static const struct zxdg_exported_v1_listener xdg_exported_listener = {
|
||||
*/
|
||||
|
||||
static gboolean
|
||||
gdk_wayland_surface_is_exported (GdkWaylandSurface *impl)
|
||||
gdk_wayland_toplevel_is_exported (GdkWaylandToplevel *wayland_toplevel)
|
||||
{
|
||||
return !!impl->display_server.xdg_exported;
|
||||
return !!wayland_toplevel->xdg_exported;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -4489,7 +4495,8 @@ gdk_wayland_toplevel_export_handle (GdkToplevel *toplevel,
|
||||
gpointer user_data,
|
||||
GDestroyNotify destroy_func)
|
||||
{
|
||||
GdkWaylandSurface *impl;
|
||||
GdkWaylandToplevel *wayland_toplevel;
|
||||
GdkSurface *surface;
|
||||
GdkWaylandDisplay *display_wayland;
|
||||
GdkDisplay *display = gdk_surface_get_display (GDK_SURFACE (toplevel));
|
||||
struct zxdg_exported_v1 *xdg_exported;
|
||||
@@ -4497,10 +4504,11 @@ gdk_wayland_toplevel_export_handle (GdkToplevel *toplevel,
|
||||
g_return_val_if_fail (GDK_IS_WAYLAND_TOPLEVEL (toplevel), FALSE);
|
||||
g_return_val_if_fail (GDK_IS_WAYLAND_DISPLAY (display), FALSE);
|
||||
|
||||
impl = GDK_WAYLAND_SURFACE (toplevel);
|
||||
wayland_toplevel = GDK_WAYLAND_TOPLEVEL (toplevel);
|
||||
surface = GDK_SURFACE (toplevel);
|
||||
display_wayland = GDK_WAYLAND_DISPLAY (display);
|
||||
|
||||
g_return_val_if_fail (!impl->display_server.xdg_exported, FALSE);
|
||||
g_return_val_if_fail (!wayland_toplevel->xdg_exported, FALSE);
|
||||
|
||||
if (!display_wayland->xdg_exporter)
|
||||
{
|
||||
@@ -4508,14 +4516,16 @@ gdk_wayland_toplevel_export_handle (GdkToplevel *toplevel,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
xdg_exported = zxdg_exporter_v1_export (display_wayland->xdg_exporter,
|
||||
impl->display_server.wl_surface);
|
||||
zxdg_exported_v1_add_listener (xdg_exported, &xdg_exported_listener, impl);
|
||||
xdg_exported =
|
||||
zxdg_exporter_v1_export (display_wayland->xdg_exporter,
|
||||
gdk_wayland_surface_get_wl_surface (surface));
|
||||
zxdg_exported_v1_add_listener (xdg_exported, &xdg_exported_listener,
|
||||
wayland_toplevel);
|
||||
|
||||
impl->display_server.xdg_exported = xdg_exported;
|
||||
impl->exported.callback = callback;
|
||||
impl->exported.user_data = user_data;
|
||||
impl->exported.destroy_func = destroy_func;
|
||||
wayland_toplevel->xdg_exported = xdg_exported;
|
||||
wayland_toplevel->exported.callback = callback;
|
||||
wayland_toplevel->exported.user_data = user_data;
|
||||
wayland_toplevel->exported.destroy_func = destroy_func;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -4536,20 +4546,20 @@ gdk_wayland_toplevel_export_handle (GdkToplevel *toplevel,
|
||||
void
|
||||
gdk_wayland_toplevel_unexport_handle (GdkToplevel *toplevel)
|
||||
{
|
||||
GdkWaylandSurface *impl;
|
||||
GdkWaylandToplevel *wayland_toplevel;
|
||||
|
||||
g_return_if_fail (GDK_IS_WAYLAND_TOPLEVEL (toplevel));
|
||||
|
||||
impl = GDK_WAYLAND_SURFACE (toplevel);
|
||||
wayland_toplevel = GDK_WAYLAND_TOPLEVEL (toplevel);
|
||||
|
||||
g_return_if_fail (impl->display_server.xdg_exported);
|
||||
g_return_if_fail (wayland_toplevel->xdg_exported);
|
||||
|
||||
g_clear_pointer (&impl->display_server.xdg_exported,
|
||||
g_clear_pointer (&wayland_toplevel->xdg_exported,
|
||||
zxdg_exported_v1_destroy);
|
||||
if (impl->exported.destroy_func)
|
||||
if (wayland_toplevel->exported.destroy_func)
|
||||
{
|
||||
g_clear_pointer (&impl->exported.user_data,
|
||||
impl->exported.destroy_func);
|
||||
g_clear_pointer (&wayland_toplevel->exported.user_data,
|
||||
wayland_toplevel->exported.destroy_func);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4925,6 +4935,21 @@ gdk_wayland_toplevel_get_property (GObject *object,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_toplevel_finalize (GObject *object)
|
||||
{
|
||||
GdkWaylandToplevel *wayland_toplevel;
|
||||
|
||||
g_return_if_fail (GDK_IS_WAYLAND_TOPLEVEL (object));
|
||||
|
||||
wayland_toplevel = GDK_WAYLAND_TOPLEVEL (object);
|
||||
|
||||
if (gdk_wayland_toplevel_is_exported (wayland_toplevel))
|
||||
gdk_wayland_toplevel_unexport_handle (GDK_TOPLEVEL (wayland_toplevel));
|
||||
|
||||
G_OBJECT_CLASS (gdk_wayland_toplevel_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_toplevel_class_init (GdkWaylandToplevelClass *class)
|
||||
{
|
||||
@@ -4932,6 +4957,7 @@ gdk_wayland_toplevel_class_init (GdkWaylandToplevelClass *class)
|
||||
|
||||
object_class->get_property = gdk_wayland_toplevel_get_property;
|
||||
object_class->set_property = gdk_wayland_toplevel_set_property;
|
||||
object_class->finalize = gdk_wayland_toplevel_finalize;
|
||||
|
||||
gdk_toplevel_install_properties (object_class, 1);
|
||||
}
|
||||
@@ -4977,7 +5003,7 @@ gdk_wayland_toplevel_present (GdkToplevel *toplevel,
|
||||
g_clear_pointer (&impl->toplevel.layout, gdk_toplevel_layout_unref);
|
||||
impl->toplevel.layout = gdk_toplevel_layout_copy (layout);
|
||||
|
||||
gdk_wayland_surface_show (surface, FALSE);
|
||||
gdk_wayland_surface_show (surface);
|
||||
|
||||
if (!pending_configure)
|
||||
{
|
||||
@@ -5125,7 +5151,7 @@ gdk_wayland_drag_surface_present (GdkDragSurface *drag_surface,
|
||||
GdkSurface *surface = GDK_SURFACE (drag_surface);
|
||||
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
|
||||
|
||||
gdk_wayland_surface_show (surface, FALSE);
|
||||
gdk_wayland_surface_show (surface);
|
||||
|
||||
impl->next_layout.configured_width = width;
|
||||
impl->next_layout.configured_height = height;
|
||||
|
||||
@@ -100,15 +100,6 @@ gdk_device_win32_query_state (GdkDevice *device,
|
||||
if (win_y)
|
||||
*win_y = point.y / scale;
|
||||
|
||||
if (window)
|
||||
{
|
||||
if (win_x)
|
||||
*win_x += _gdk_offset_x;
|
||||
|
||||
if (win_y)
|
||||
*win_y += _gdk_offset_y;
|
||||
}
|
||||
|
||||
if (hwnd && child_window)
|
||||
{
|
||||
hwndc = ChildWindowFromPoint (hwnd, point);
|
||||
|
||||
@@ -91,15 +91,6 @@ gdk_device_winpointer_query_state (GdkDevice *device,
|
||||
if (win_y)
|
||||
*win_y = point.y / scale;
|
||||
|
||||
if (!window)
|
||||
{
|
||||
if (win_x)
|
||||
*win_x += _gdk_offset_x;
|
||||
|
||||
if (win_y)
|
||||
*win_y += _gdk_offset_y;
|
||||
}
|
||||
|
||||
if (hwnd && child_window)
|
||||
{
|
||||
hwndc = ChildWindowFromPoint (hwnd, point);
|
||||
|
||||
@@ -99,15 +99,6 @@ gdk_device_wintab_query_state (GdkDevice *device,
|
||||
if (win_y)
|
||||
*win_y = point.y / scale;
|
||||
|
||||
if (!window)
|
||||
{
|
||||
if (win_x)
|
||||
*win_x += _gdk_offset_x;
|
||||
|
||||
if (win_y)
|
||||
*win_y += _gdk_offset_y;
|
||||
}
|
||||
|
||||
if (hwnd && child_window)
|
||||
{
|
||||
hwndc = ChildWindowFromPoint (hwnd, point);
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
#include <dwmapi.h>
|
||||
|
||||
#include "gdkwin32langnotification.h"
|
||||
#ifdef GDK_WIN32_ENABLE_EGL
|
||||
#ifdef HAVE_EGL
|
||||
# include <epoxy/egl.h>
|
||||
#endif
|
||||
|
||||
@@ -645,14 +645,6 @@ gdk_win32_display_dispose (GObject *object)
|
||||
{
|
||||
GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (object);
|
||||
|
||||
#ifdef GDK_WIN32_ENABLE_EGL
|
||||
if (display_win32->egl_disp != EGL_NO_DISPLAY)
|
||||
{
|
||||
eglTerminate (display_win32->egl_disp);
|
||||
display_win32->egl_disp = EGL_NO_DISPLAY;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (display_win32->hwnd != NULL)
|
||||
{
|
||||
if (display_win32->dummy_context_wgl.hglrc != NULL)
|
||||
@@ -1146,23 +1138,54 @@ gdk_win32_display_get_setting (GdkDisplay *display,
|
||||
return _gdk_win32_get_setting (name, value);
|
||||
}
|
||||
|
||||
#ifndef EGL_PLATFORM_ANGLE_ANGLE
|
||||
#define EGL_PLATFORM_ANGLE_ANGLE 0x3202
|
||||
#endif
|
||||
|
||||
static gboolean
|
||||
gdk_win32_display_init_gl_backend (GdkDisplay *display,
|
||||
GError **error)
|
||||
{
|
||||
gboolean result = FALSE;
|
||||
GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (display);
|
||||
|
||||
/* No env vars set, do the regular GL initialization, first WGL and then EGL,
|
||||
if (display_win32->dummy_context_wgl.hdc == NULL)
|
||||
display_win32->dummy_context_wgl.hdc = GetDC (display_win32->hwnd);
|
||||
|
||||
/*
|
||||
* No env vars set, do the regular GL initialization, first WGL and then EGL,
|
||||
* as WGL is the more tried-and-tested configuration.
|
||||
*/
|
||||
|
||||
result = gdk_win32_display_init_wgl (display, error);
|
||||
#ifdef HAVE_EGL
|
||||
/*
|
||||
* Disable defaulting to EGL for now, since shaders need to be fixed for
|
||||
* usage against libANGLE EGL. EGL is used more as a compatibility layer
|
||||
* on Windows rather than being a native citizen on Windows
|
||||
*/
|
||||
if (_gdk_debug_flags & GDK_DEBUG_GL_EGL)
|
||||
result = gdk_display_init_egl (display,
|
||||
EGL_PLATFORM_ANGLE_ANGLE,
|
||||
display_win32->dummy_context_wgl.hdc,
|
||||
FALSE,
|
||||
error);
|
||||
#endif
|
||||
|
||||
#ifdef GDK_WIN32_ENABLE_EGL
|
||||
if (!result)
|
||||
{
|
||||
g_clear_error (error);
|
||||
result = gdk_win32_display_init_egl (display, error);
|
||||
result = gdk_win32_display_init_wgl (display, error);
|
||||
}
|
||||
|
||||
#ifdef HAVE_EGL
|
||||
if (!result)
|
||||
{
|
||||
g_clear_error (error);
|
||||
result = gdk_display_init_egl (display,
|
||||
EGL_PLATFORM_ANGLE_ANGLE,
|
||||
display_win32->dummy_context_wgl.hdc,
|
||||
TRUE,
|
||||
error);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1179,13 +1202,12 @@ gdk_win32_display_init_gl (GdkDisplay *display,
|
||||
if (!gdk_win32_display_init_gl_backend (display, error))
|
||||
return NULL;
|
||||
|
||||
#ifdef GDK_WIN32_ENABLE_EGL
|
||||
if (display_win32->egl_disp)
|
||||
gl_context = g_object_new (GDK_TYPE_WIN32_GL_CONTEXT_EGL, "display", display, NULL);
|
||||
else
|
||||
#endif
|
||||
if (display_win32->wgl_pixel_format != 0)
|
||||
gl_context = g_object_new (GDK_TYPE_WIN32_GL_CONTEXT_WGL, "display", display, NULL);
|
||||
#ifdef HAVE_EGL
|
||||
else if (gdk_display_get_egl_display (display))
|
||||
gl_context = g_object_new (GDK_TYPE_WIN32_GL_CONTEXT_EGL, "display", display, NULL);
|
||||
#endif
|
||||
|
||||
g_return_val_if_fail (gl_context != NULL, NULL);
|
||||
|
||||
@@ -1203,23 +1225,9 @@ gdk_win32_display_init_gl (GdkDisplay *display,
|
||||
gpointer
|
||||
gdk_win32_display_get_egl_display (GdkDisplay *display)
|
||||
{
|
||||
#ifdef GDK_WIN32_ENABLE_EGL
|
||||
GdkWin32Display *display_win32;
|
||||
#endif
|
||||
|
||||
g_return_val_if_fail (GDK_IS_WIN32_DISPLAY (display), NULL);
|
||||
|
||||
#ifdef GDK_WIN32_ENABLE_EGL
|
||||
display_win32 = GDK_WIN32_DISPLAY (display);
|
||||
|
||||
if (display_win32->wgl_pixel_format != 0)
|
||||
return NULL;
|
||||
|
||||
return display_win32->egl_disp;
|
||||
#else
|
||||
/* no EGL support */
|
||||
return NULL;
|
||||
#endif
|
||||
return gdk_display_get_egl_display (display);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#include "gdkwin32screen.h"
|
||||
#include "gdkwin32cursor.h"
|
||||
|
||||
#ifdef GDK_WIN32_ENABLE_EGL
|
||||
#ifdef HAVE_EGL
|
||||
# include <epoxy/egl.h>
|
||||
#endif
|
||||
|
||||
@@ -135,14 +135,6 @@ struct _GdkWin32Display
|
||||
int wgl_pixel_format;
|
||||
guint gl_version;
|
||||
|
||||
#ifdef GDK_WIN32_ENABLE_EGL
|
||||
/* EGL (Angle) Items */
|
||||
guint egl_version;
|
||||
EGLDisplay egl_disp;
|
||||
EGLConfig egl_config;
|
||||
HDC hdc_egl_temp;
|
||||
#endif
|
||||
|
||||
GListModel *monitors;
|
||||
|
||||
guint hasWglARBCreateContext : 1;
|
||||
@@ -151,7 +143,7 @@ struct _GdkWin32Display
|
||||
guint hasWglARBPixelFormat : 1;
|
||||
guint hasWglARBmultisample : 1;
|
||||
|
||||
#ifdef GDK_WIN32_ENABLE_EGL
|
||||
#ifdef HAVE_EGL
|
||||
guint hasEglKHRCreateContext : 1;
|
||||
guint hasEglSurfacelessContext : 1;
|
||||
EGLint egl_min_swap_interval;
|
||||
|
||||
@@ -2082,8 +2082,8 @@ gdk_dnd_handle_motion_event (GdkDrag *drag,
|
||||
API_CALL (PostThreadMessage, (clipdrop->dnd_thread_id,
|
||||
WM_MOUSEMOVE,
|
||||
key_state,
|
||||
MAKELPARAM (x_root * drag_win32->scale - _gdk_offset_x,
|
||||
y_root * drag_win32->scale - _gdk_offset_y)));
|
||||
MAKELPARAM (x_root * drag_win32->scale,
|
||||
y_root * drag_win32->scale)));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -425,14 +425,9 @@ set_source_actions_helper (GdkDrop *drop,
|
||||
return actions;
|
||||
}
|
||||
|
||||
/* Utility function to translate win32 screen coordinates to
|
||||
* client coordinates (i.e. relative to the surface origin)
|
||||
*
|
||||
* Note that input is expected to be:
|
||||
* a) NOT scaled by dpi_scale
|
||||
* b) NOT translated by the GDK screen offset (gdk_offset_x / y)
|
||||
*
|
||||
* This utility function preserves subpixel precision
|
||||
/* Utility function to translate screen coordinates to surface-relative
|
||||
* coordinates. This routine only works with pixel values that aren't
|
||||
* scaled by any GDK DPI scale factor.
|
||||
*/
|
||||
static void
|
||||
unscaled_screen_to_client (GdkSurface* surface,
|
||||
@@ -514,8 +509,8 @@ idroptarget_dragenter (LPDROPTARGET This,
|
||||
grfKeyState);
|
||||
|
||||
set_data_object (&ctx->data_object, pDataObj);
|
||||
pt_x = pt.x / drop_win32->scale + _gdk_offset_x;
|
||||
pt_y = pt.y / drop_win32->scale + _gdk_offset_y;
|
||||
pt_x = pt.x / drop_win32->scale;
|
||||
pt_y = pt.y / drop_win32->scale;
|
||||
|
||||
unscaled_screen_to_client (ctx->surface, pt.x, pt.y, &x, &y);
|
||||
x /= drop_win32->scale;
|
||||
@@ -554,8 +549,8 @@ idroptarget_dragover (LPDROPTARGET This,
|
||||
{
|
||||
drop_target_context *ctx = (drop_target_context *) This;
|
||||
GdkWin32Drop *drop_win32 = GDK_WIN32_DROP (ctx->drop);
|
||||
int pt_x = pt.x / drop_win32->scale + _gdk_offset_x;
|
||||
int pt_y = pt.y / drop_win32->scale + _gdk_offset_y;
|
||||
int pt_x = pt.x / drop_win32->scale;
|
||||
int pt_y = pt.y / drop_win32->scale;
|
||||
GdkDragAction source_actions;
|
||||
GdkDragAction dest_actions;
|
||||
|
||||
@@ -624,8 +619,6 @@ idroptarget_drop (LPDROPTARGET This,
|
||||
{
|
||||
drop_target_context *ctx = (drop_target_context *) This;
|
||||
GdkWin32Drop *drop_win32 = GDK_WIN32_DROP (ctx->drop);
|
||||
int pt_x = pt.x / drop_win32->scale + _gdk_offset_x;
|
||||
int pt_y = pt.y / drop_win32->scale + _gdk_offset_y;
|
||||
double x = 0.0;
|
||||
double y = 0.0;
|
||||
GdkDragAction dest_action;
|
||||
|
||||
@@ -1291,13 +1291,12 @@ make_crossing_event (GdkDevice *physical_device,
|
||||
}
|
||||
|
||||
/* Acquires actual client area size of the underlying native window.
|
||||
* Rectangle is in GDK screen coordinates (_gdk_offset_* is added).
|
||||
* Returns FALSE if configure events should be inhibited,
|
||||
* TRUE otherwise.
|
||||
*/
|
||||
gboolean
|
||||
_gdk_win32_get_window_rect (GdkSurface *window,
|
||||
RECT *rect)
|
||||
RECT *rect)
|
||||
{
|
||||
RECT client_rect;
|
||||
POINT point;
|
||||
@@ -1312,11 +1311,7 @@ _gdk_win32_get_window_rect (GdkSurface *window,
|
||||
|
||||
/* top level windows need screen coords */
|
||||
if (GDK_IS_TOPLEVEL (window))
|
||||
{
|
||||
ClientToScreen (hwnd, &point);
|
||||
point.x += _gdk_offset_x * impl->surface_scale;
|
||||
point.y += _gdk_offset_y * impl->surface_scale;
|
||||
}
|
||||
ClientToScreen (hwnd, &point);
|
||||
|
||||
rect->left = point.x;
|
||||
rect->top = point.y;
|
||||
@@ -2410,15 +2405,15 @@ gdk_event_translate (MSG *msg,
|
||||
impl = GDK_WIN32_SURFACE (window);
|
||||
|
||||
/* If we haven't moved, don't create any GDK event. Windows
|
||||
* sends WM_MOUSEMOVE messages after a new window is shows under
|
||||
* sends WM_MOUSEMOVE messages after a new window is shown under
|
||||
* the mouse, even if the mouse hasn't moved. This disturbs gtk.
|
||||
*/
|
||||
if ((msg->pt.x + _gdk_offset_x) / impl->surface_scale == current_root_x &&
|
||||
(msg->pt.y + _gdk_offset_y) / impl->surface_scale == current_root_y)
|
||||
break;
|
||||
if (msg->pt.x / impl->surface_scale == current_root_x &&
|
||||
msg->pt.y / impl->surface_scale == current_root_y)
|
||||
break;
|
||||
|
||||
current_root_x = (msg->pt.x + _gdk_offset_x) / impl->surface_scale;
|
||||
current_root_y = (msg->pt.y + _gdk_offset_y) / impl->surface_scale;
|
||||
current_root_x = msg->pt.x / impl->surface_scale;
|
||||
current_root_y = msg->pt.y / impl->surface_scale;
|
||||
|
||||
if (impl->drag_move_resize_context.op != GDK_WIN32_DRAGOP_NONE)
|
||||
gdk_win32_surface_do_move_resize_drag (window, current_root_x, current_root_y);
|
||||
|
||||
@@ -53,30 +53,6 @@ typedef struct _GdkWin32GLContextClass GdkWin32GLContextEGLClass;
|
||||
|
||||
G_DEFINE_TYPE (GdkWin32GLContextEGL, gdk_win32_gl_context_egl, GDK_TYPE_WIN32_GL_CONTEXT)
|
||||
|
||||
static void
|
||||
gdk_win32_gl_context_egl_dispose (GObject *gobject)
|
||||
{
|
||||
GdkGLContext *context = GDK_GL_CONTEXT (gobject);
|
||||
GdkWin32GLContextEGL *context_egl = GDK_WIN32_GL_CONTEXT_EGL (gobject);
|
||||
GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (gdk_gl_context_get_display (context));
|
||||
GdkSurface *surface = gdk_gl_context_get_surface (context);
|
||||
|
||||
if (display_win32 != NULL)
|
||||
{
|
||||
if (eglGetCurrentContext () == context_egl->egl_context)
|
||||
eglMakeCurrent(display_win32->egl_disp, EGL_NO_SURFACE, EGL_NO_SURFACE,
|
||||
EGL_NO_CONTEXT);
|
||||
|
||||
GDK_NOTE (OPENGL, g_message ("Destroying EGL (ANGLE) context"));
|
||||
|
||||
eglDestroyContext (display_win32->egl_disp,
|
||||
context_egl->egl_context);
|
||||
context_egl->egl_context = EGL_NO_CONTEXT;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (gdk_win32_gl_context_egl_parent_class)->dispose (gobject);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_egl_force_redraw (GdkSurface *surface)
|
||||
{
|
||||
@@ -109,7 +85,7 @@ gdk_win32_gl_context_egl_end_frame (GdkDrawContext *draw_context,
|
||||
GdkGLContext *context = GDK_GL_CONTEXT (draw_context);
|
||||
GdkWin32GLContextEGL *context_egl = GDK_WIN32_GL_CONTEXT_EGL (context);
|
||||
GdkSurface *surface = gdk_gl_context_get_surface (context);
|
||||
GdkWin32Display *display_win32 = (GDK_WIN32_DISPLAY (gdk_gl_context_get_display (context)));
|
||||
GdkDisplay *display = gdk_gl_context_get_display (context);
|
||||
cairo_rectangle_int_t whole_window;
|
||||
EGLSurface egl_surface;
|
||||
|
||||
@@ -122,7 +98,7 @@ gdk_win32_gl_context_egl_end_frame (GdkDrawContext *draw_context,
|
||||
gdk_surface_get_height (surface)
|
||||
};
|
||||
|
||||
egl_surface = gdk_win32_surface_get_egl_surface (surface, display_win32->egl_config, FALSE);
|
||||
egl_surface = gdk_surface_get_egl_surface (surface);
|
||||
|
||||
if (is_egl_force_redraw (surface))
|
||||
{
|
||||
@@ -135,338 +111,7 @@ gdk_win32_gl_context_egl_end_frame (GdkDrawContext *draw_context,
|
||||
reset_egl_force_redraw (surface);
|
||||
}
|
||||
|
||||
eglSwapBuffers (display_win32->egl_disp, egl_surface);
|
||||
}
|
||||
|
||||
#ifndef EGL_PLATFORM_ANGLE_ANGLE
|
||||
#define EGL_PLATFORM_ANGLE_ANGLE 0x3202
|
||||
#endif
|
||||
|
||||
#ifndef EGL_PLATFORM_ANGLE_TYPE_ANGLE
|
||||
#define EGL_PLATFORM_ANGLE_TYPE_ANGLE 0x3203
|
||||
#endif
|
||||
|
||||
#ifndef EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE
|
||||
#define EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE 0x3208
|
||||
#endif
|
||||
|
||||
static EGLDisplay
|
||||
gdk_win32_get_egl_display (GdkWin32Display *display)
|
||||
{
|
||||
EGLDisplay disp;
|
||||
|
||||
if (epoxy_has_egl_extension (NULL, "EGL_EXT_platform_base"))
|
||||
{
|
||||
PFNEGLGETPLATFORMDISPLAYEXTPROC getPlatformDisplay = (void *) eglGetProcAddress ("eglGetPlatformDisplayEXT");
|
||||
if (getPlatformDisplay)
|
||||
{
|
||||
EGLint disp_attr[] = {EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, EGL_NONE};
|
||||
|
||||
disp = getPlatformDisplay (EGL_PLATFORM_ANGLE_ANGLE, display->hdc_egl_temp, disp_attr);
|
||||
|
||||
if (disp != EGL_NO_DISPLAY)
|
||||
return disp;
|
||||
}
|
||||
}
|
||||
|
||||
return eglGetDisplay (display->hdc_egl_temp);
|
||||
}
|
||||
|
||||
#define MAX_EGL_ATTRS 30
|
||||
|
||||
static gboolean
|
||||
find_eglconfig_for_window (GdkWin32Display *display,
|
||||
EGLConfig *egl_config_out,
|
||||
EGLint *min_swap_interval_out,
|
||||
GError **error)
|
||||
{
|
||||
EGLint attrs[MAX_EGL_ATTRS];
|
||||
EGLint count;
|
||||
EGLConfig *configs, chosen_config;
|
||||
|
||||
int i = 0;
|
||||
|
||||
EGLDisplay egl_disp = display->egl_disp;
|
||||
|
||||
attrs[i++] = EGL_CONFORMANT;
|
||||
attrs[i++] = EGL_OPENGL_ES2_BIT;
|
||||
attrs[i++] = EGL_SURFACE_TYPE;
|
||||
attrs[i++] = EGL_WINDOW_BIT;
|
||||
|
||||
attrs[i++] = EGL_COLOR_BUFFER_TYPE;
|
||||
attrs[i++] = EGL_RGB_BUFFER;
|
||||
|
||||
attrs[i++] = EGL_RED_SIZE;
|
||||
attrs[i++] = 1;
|
||||
attrs[i++] = EGL_GREEN_SIZE;
|
||||
attrs[i++] = 1;
|
||||
attrs[i++] = EGL_BLUE_SIZE;
|
||||
attrs[i++] = 1;
|
||||
attrs[i++] = EGL_ALPHA_SIZE;
|
||||
attrs[i++] = 1;
|
||||
|
||||
attrs[i++] = EGL_NONE;
|
||||
g_assert (i < MAX_EGL_ATTRS);
|
||||
|
||||
if (!eglChooseConfig (display->egl_disp, attrs, NULL, 0, &count) || count < 1)
|
||||
{
|
||||
g_set_error_literal (error, GDK_GL_ERROR,
|
||||
GDK_GL_ERROR_UNSUPPORTED_FORMAT,
|
||||
_("No available configurations for the given pixel format"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
configs = g_new (EGLConfig, count);
|
||||
|
||||
if (!eglChooseConfig (display->egl_disp, attrs, configs, count, &count) || count < 1)
|
||||
{
|
||||
g_set_error_literal (error, GDK_GL_ERROR,
|
||||
GDK_GL_ERROR_UNSUPPORTED_FORMAT,
|
||||
_("No available configurations for the given pixel format"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Pick first valid configuration i guess? */
|
||||
chosen_config = configs[0];
|
||||
|
||||
if (!eglGetConfigAttrib (display->egl_disp, chosen_config,
|
||||
EGL_MIN_SWAP_INTERVAL, min_swap_interval_out))
|
||||
{
|
||||
g_set_error_literal (error, GDK_GL_ERROR,
|
||||
GDK_GL_ERROR_NOT_AVAILABLE,
|
||||
"Could not retrieve the minimum swap interval");
|
||||
g_free (configs);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (egl_config_out != NULL)
|
||||
*egl_config_out = chosen_config;
|
||||
|
||||
g_free (configs);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gdk_win32_display_init_egl (GdkDisplay *display,
|
||||
GError **error)
|
||||
{
|
||||
GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (display);
|
||||
int best_idx = 0;
|
||||
EGLDisplay egl_disp;
|
||||
|
||||
if (!gdk_gl_backend_can_be_used (GDK_GL_EGL, error))
|
||||
return FALSE;
|
||||
|
||||
if (display_win32->egl_disp != EGL_NO_DISPLAY)
|
||||
return TRUE;
|
||||
|
||||
egl_disp = gdk_win32_get_egl_display (display_win32);
|
||||
|
||||
if (egl_disp == EGL_NO_DISPLAY)
|
||||
return FALSE;
|
||||
|
||||
if (!eglInitialize (egl_disp, NULL, NULL))
|
||||
{
|
||||
eglTerminate (egl_disp);
|
||||
egl_disp = EGL_NO_DISPLAY;
|
||||
g_set_error_literal (error, GDK_GL_ERROR,
|
||||
GDK_GL_ERROR_NOT_AVAILABLE,
|
||||
_("No GL implementation is available"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
display_win32->egl_disp = egl_disp;
|
||||
display_win32->egl_version = epoxy_egl_version (egl_disp);
|
||||
|
||||
eglBindAPI (EGL_OPENGL_ES_API);
|
||||
|
||||
display_win32->hasEglSurfacelessContext =
|
||||
epoxy_has_egl_extension (egl_disp, "EGL_KHR_surfaceless_context");
|
||||
|
||||
GDK_NOTE (OPENGL,
|
||||
g_print ("EGL API version %d.%d found\n"
|
||||
" - Vendor: %s\n"
|
||||
" - Checked extensions:\n"
|
||||
"\t* EGL_KHR_surfaceless_context: %s\n",
|
||||
display_win32->egl_version / 10,
|
||||
display_win32->egl_version % 10,
|
||||
eglQueryString (display_win32->egl_disp, EGL_VENDOR),
|
||||
display_win32->hasEglSurfacelessContext ? "yes" : "no"));
|
||||
|
||||
return find_eglconfig_for_window (display_win32, &display_win32->egl_config,
|
||||
&display_win32->egl_min_swap_interval, error);
|
||||
}
|
||||
|
||||
#define N_EGL_ATTRS 16
|
||||
|
||||
static EGLContext
|
||||
create_egl_context (EGLDisplay display,
|
||||
EGLConfig config,
|
||||
GdkGLContext *share,
|
||||
int flags,
|
||||
int major,
|
||||
int minor,
|
||||
gboolean *is_legacy)
|
||||
{
|
||||
EGLContext ctx;
|
||||
EGLint context_attribs[N_EGL_ATTRS];
|
||||
int i = 0;
|
||||
|
||||
/* ANGLE does not support the GL_OES_vertex_array_object extension, so we need to use ES3 directly */
|
||||
context_attribs[i++] = EGL_CONTEXT_CLIENT_VERSION;
|
||||
context_attribs[i++] = 3;
|
||||
|
||||
/* Specify the flags */
|
||||
context_attribs[i++] = EGL_CONTEXT_FLAGS_KHR;
|
||||
context_attribs[i++] = flags;
|
||||
|
||||
context_attribs[i++] = EGL_NONE;
|
||||
g_assert (i < N_EGL_ATTRS);
|
||||
|
||||
ctx = eglCreateContext (display,
|
||||
config,
|
||||
share != NULL ? GDK_WIN32_GL_CONTEXT_EGL (share)->egl_context
|
||||
: EGL_NO_CONTEXT,
|
||||
context_attribs);
|
||||
|
||||
if (ctx != EGL_NO_CONTEXT)
|
||||
GDK_NOTE (OPENGL, g_message ("Created EGL context[%p]", ctx));
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_win32_gl_context_egl_realize (GdkGLContext *context,
|
||||
GError **error)
|
||||
{
|
||||
GdkWin32GLContextEGL *context_egl = GDK_WIN32_GL_CONTEXT_EGL (context);
|
||||
|
||||
gboolean debug_bit, compat_bit, legacy_bit;
|
||||
gboolean use_es = FALSE;
|
||||
EGLContext egl_context;
|
||||
EGLContext ctx;
|
||||
|
||||
/* request flags and specific versions for core (3.2+) WGL context */
|
||||
int flags = 0;
|
||||
int major = 0;
|
||||
int minor = 0;
|
||||
|
||||
GdkSurface *surface = gdk_gl_context_get_surface (context);
|
||||
GdkWin32Surface *impl = GDK_WIN32_SURFACE (surface);
|
||||
GdkDisplay *display = gdk_gl_context_get_display (context);
|
||||
GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (display);
|
||||
GdkGLContext *share = gdk_display_get_gl_context (display);
|
||||
|
||||
gdk_gl_context_get_required_version (context, &major, &minor);
|
||||
debug_bit = gdk_gl_context_get_debug_enabled (context);
|
||||
compat_bit = gdk_gl_context_get_forward_compatible (context);
|
||||
|
||||
/*
|
||||
* A legacy context cannot be shared with core profile ones, so this means we
|
||||
* must stick to a legacy context if the shared context is a legacy context
|
||||
*/
|
||||
|
||||
/* if GDK_GL_LEGACY is set, we default to a legacy context */
|
||||
legacy_bit = GDK_DISPLAY_DEBUG_CHECK (display, GL_LEGACY) ?
|
||||
TRUE :
|
||||
share != NULL && gdk_gl_context_is_legacy (share);
|
||||
|
||||
use_es = GDK_DISPLAY_DEBUG_CHECK (display, GL_GLES) ||
|
||||
(share != NULL && gdk_gl_context_get_use_es (share));
|
||||
|
||||
if (debug_bit)
|
||||
flags |= EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR;
|
||||
if (compat_bit)
|
||||
flags |= EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR;
|
||||
|
||||
GDK_NOTE (OPENGL, g_message ("Creating EGL context version %d.%d (debug:%s, forward:%s, legacy:%s)",
|
||||
major, minor,
|
||||
debug_bit ? "yes" : "no",
|
||||
compat_bit ? "yes" : "no",
|
||||
legacy_bit ? "yes" : "no"));
|
||||
|
||||
ctx = create_egl_context (display_win32->egl_disp,
|
||||
display_win32->egl_config,
|
||||
share,
|
||||
flags,
|
||||
major,
|
||||
minor,
|
||||
&legacy_bit);
|
||||
|
||||
if (ctx == EGL_NO_CONTEXT)
|
||||
{
|
||||
g_set_error_literal (error, GDK_GL_ERROR,
|
||||
GDK_GL_ERROR_NOT_AVAILABLE,
|
||||
_("Unable to create a GL context"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
GDK_NOTE (OPENGL, g_print ("Created EGL context[%p]\n", ctx));
|
||||
|
||||
context_egl->egl_context = ctx;
|
||||
|
||||
/* We are using GLES here */
|
||||
gdk_gl_context_set_use_es (context, TRUE);
|
||||
|
||||
/* Ensure that any other context is created with a legacy bit set */
|
||||
gdk_gl_context_set_is_legacy (context, legacy_bit);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_win32_gl_context_egl_clear_current (GdkGLContext *context)
|
||||
{
|
||||
GdkDisplay *display = gdk_gl_context_get_display (context);
|
||||
GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (display);
|
||||
|
||||
if (display_win32->egl_disp != EGL_NO_DISPLAY)
|
||||
return eglMakeCurrent (display_win32->egl_disp,
|
||||
EGL_NO_SURFACE,
|
||||
EGL_NO_SURFACE,
|
||||
EGL_NO_CONTEXT);
|
||||
else
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_win32_gl_context_egl_make_current (GdkGLContext *context,
|
||||
gboolean surfaceless)
|
||||
{
|
||||
GdkWin32GLContextEGL *context_egl = GDK_WIN32_GL_CONTEXT_EGL (context);
|
||||
GdkDisplay *display = gdk_gl_context_get_display (context);
|
||||
GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (display);
|
||||
GdkSurface *surface;
|
||||
|
||||
gboolean do_frame_sync = FALSE;
|
||||
|
||||
EGLSurface egl_surface;
|
||||
|
||||
surface = gdk_gl_context_get_surface (context);
|
||||
|
||||
if (!surfaceless)
|
||||
egl_surface = gdk_win32_surface_get_egl_surface (surface, display_win32->egl_config, FALSE);
|
||||
else
|
||||
{
|
||||
if (display_win32->hasEglSurfacelessContext)
|
||||
egl_surface = EGL_NO_SURFACE;
|
||||
else
|
||||
egl_surface = gdk_win32_surface_get_egl_surface (surface, display_win32->egl_config, TRUE);
|
||||
}
|
||||
|
||||
if (!eglMakeCurrent (display_win32->egl_disp,
|
||||
egl_surface,
|
||||
egl_surface,
|
||||
context_egl->egl_context))
|
||||
return FALSE;
|
||||
|
||||
if (display_win32->egl_min_swap_interval == 0)
|
||||
eglSwapInterval (display_win32->egl_disp, 0);
|
||||
else
|
||||
g_debug ("Can't disable GL swap interval");
|
||||
|
||||
return TRUE;
|
||||
eglSwapBuffers (gdk_display_get_egl_display (display), egl_surface);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -484,18 +129,11 @@ gdk_win32_gl_context_egl_class_init (GdkWin32GLContextClass *klass)
|
||||
{
|
||||
GdkGLContextClass *context_class = GDK_GL_CONTEXT_CLASS(klass);
|
||||
GdkDrawContextClass *draw_context_class = GDK_DRAW_CONTEXT_CLASS(klass);
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
context_class->backend_type = GDK_GL_EGL;
|
||||
|
||||
context_class->realize = gdk_win32_gl_context_egl_realize;
|
||||
context_class->make_current = gdk_win32_gl_context_egl_make_current;
|
||||
context_class->clear_current = gdk_win32_gl_context_egl_clear_current;
|
||||
|
||||
draw_context_class->begin_frame = gdk_win32_gl_context_egl_begin_frame;
|
||||
draw_context_class->end_frame = gdk_win32_gl_context_egl_end_frame;
|
||||
|
||||
gobject_class->dispose = gdk_win32_gl_context_egl_dispose;
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -226,9 +226,6 @@ gdk_init_dummy_wgl_context (GdkWin32Display *display_win32)
|
||||
gboolean set_pixel_format_result = FALSE;
|
||||
int best_idx = 0;
|
||||
|
||||
if (display_win32->dummy_context_wgl.hdc == NULL)
|
||||
display_win32->dummy_context_wgl.hdc = GetDC (display_win32->hwnd);
|
||||
|
||||
memset (&pfd, 0, sizeof (PIXELFORMATDESCRIPTOR));
|
||||
|
||||
best_idx = get_wgl_pfd (display_win32->dummy_context_wgl.hdc, &pfd, NULL);
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
#include <cairo.h>
|
||||
#include <epoxy/wgl.h>
|
||||
|
||||
#ifdef GDK_WIN32_ENABLE_EGL
|
||||
#ifdef HAVE_EGL
|
||||
# include <epoxy/egl.h>
|
||||
#endif
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
#include <epoxy/gl.h>
|
||||
#include <epoxy/wgl.h>
|
||||
|
||||
#ifdef GDK_WIN32_ENABLE_EGL
|
||||
#ifdef HAVE_EGL
|
||||
# include <epoxy/egl.h>
|
||||
#endif
|
||||
|
||||
|
||||
@@ -30,8 +30,6 @@
|
||||
GdkDisplay *_gdk_display = NULL;
|
||||
GdkDeviceManagerWin32 *_gdk_device_manager = NULL;
|
||||
|
||||
int _gdk_offset_x, _gdk_offset_y;
|
||||
|
||||
HDC _gdk_display_hdc;
|
||||
HINSTANCE _gdk_dll_hinstance;
|
||||
HINSTANCE _gdk_app_hmodule;
|
||||
|
||||
@@ -563,7 +563,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);
|
||||
@@ -673,9 +673,6 @@ enum_monitor (HMONITOR hmonitor,
|
||||
HMONITOR hmonitor;
|
||||
POINT pt;
|
||||
|
||||
/* Not subtracting _gdk_offset_x and _gdk_offset_y because they will only
|
||||
* be added later on, in _gdk_win32_display_get_monitor_list().
|
||||
*/
|
||||
pt.x = w32mon->work_rect.x + w32mon->work_rect.width / 2;
|
||||
pt.y = w32mon->work_rect.y + w32mon->work_rect.height / 2;
|
||||
hmonitor = MonitorFromPoint (pt, MONITOR_DEFAULTTONEAREST);
|
||||
@@ -772,45 +769,6 @@ _gdk_win32_display_get_monitor_list (GdkWin32Display *win32_display)
|
||||
prune_monitors (&data);
|
||||
}
|
||||
|
||||
_gdk_offset_x = G_MININT;
|
||||
_gdk_offset_y = G_MININT;
|
||||
|
||||
for (i = 0; i < data.monitors->len; i++)
|
||||
{
|
||||
GdkWin32Monitor *m;
|
||||
GdkRectangle rect;
|
||||
|
||||
m = g_ptr_array_index (data.monitors, i);
|
||||
|
||||
/* 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_NOTE (MISC, g_print ("Multi-monitor offset: (%d,%d)\n",
|
||||
_gdk_offset_x, _gdk_offset_y));
|
||||
|
||||
/* Translate monitor coords into GDK coordinate space */
|
||||
for (i = 0; i < data.monitors->len; i++)
|
||||
{
|
||||
GdkWin32Monitor *m;
|
||||
GdkRectangle rect;
|
||||
|
||||
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;
|
||||
gdk_monitor_set_geometry (GDK_MONITOR (m), &rect);
|
||||
|
||||
m->work_rect.x += _gdk_offset_x;
|
||||
m->work_rect.y += _gdk_offset_y;
|
||||
|
||||
GDK_NOTE (MISC, g_print ("Monitor %d: %dx%d@%+d%+d\n", i,
|
||||
rect.width, rect.height, rect.x, rect.y));
|
||||
}
|
||||
|
||||
return data.monitors;
|
||||
}
|
||||
|
||||
|
||||
@@ -258,13 +258,6 @@ extern GdkDisplay *_gdk_display;
|
||||
|
||||
extern GdkDeviceManagerWin32 *_gdk_device_manager;
|
||||
|
||||
/* Offsets to add to Windows coordinates (which are relative to the
|
||||
* primary monitor's origin, and thus might be negative for monitors
|
||||
* to the left and/or above the primary monitor) to get GDK
|
||||
* coordinates, which should be non-negative on the whole screen.
|
||||
*/
|
||||
extern int _gdk_offset_x, _gdk_offset_y;
|
||||
|
||||
extern HDC _gdk_display_hdc;
|
||||
extern HINSTANCE _gdk_dll_hinstance;
|
||||
extern HINSTANCE _gdk_app_hmodule;
|
||||
|
||||
+55
-135
@@ -473,7 +473,6 @@ _gdk_win32_display_create_surface (GdkDisplay *display,
|
||||
wchar_t *wtitle;
|
||||
int window_width, window_height;
|
||||
int window_x, window_y;
|
||||
int offset_x = 0, offset_y = 0;
|
||||
int real_x = 0, real_y = 0;
|
||||
GdkFrameClock *frame_clock;
|
||||
|
||||
@@ -528,8 +527,6 @@ _gdk_win32_display_create_surface (GdkDisplay *display,
|
||||
dwExStyle = 0;
|
||||
owner = NULL;
|
||||
|
||||
offset_x = _gdk_offset_x;
|
||||
offset_y = _gdk_offset_y;
|
||||
/* MSDN: We need WS_CLIPCHILDREN and WS_CLIPSIBLINGS for GL Context Creation */
|
||||
dwStyle = WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
|
||||
|
||||
@@ -561,8 +558,8 @@ _gdk_win32_display_create_surface (GdkDisplay *display,
|
||||
|
||||
AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
|
||||
|
||||
real_x = (x - offset_x) * impl->surface_scale;
|
||||
real_y = (y - offset_y) * impl->surface_scale;
|
||||
real_x = x * impl->surface_scale;
|
||||
real_y = y * impl->surface_scale;
|
||||
|
||||
if (surface_type == GDK_SURFACE_TOPLEVEL)
|
||||
{
|
||||
@@ -627,8 +624,8 @@ _gdk_win32_display_create_surface (GdkDisplay *display,
|
||||
GDK_NOTE (MISC, g_print ("... \"%s\" %dx%d@%+d%+d %p = %p\n",
|
||||
title,
|
||||
window_width, window_height,
|
||||
surface->x - offset_x,
|
||||
surface->y - offset_y,
|
||||
surface->x,
|
||||
surface->y,
|
||||
owner,
|
||||
hwndNew));
|
||||
|
||||
@@ -641,6 +638,7 @@ _gdk_win32_display_create_surface (GdkDisplay *display,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gdk_surface_set_egl_native_window (surface, (void *) impl->handle);
|
||||
if (display_win32->tablet_input_api == GDK_WIN32_TABLET_INPUT_API_WINPOINTER)
|
||||
gdk_winpointer_initialize_surface (surface);
|
||||
|
||||
@@ -688,22 +686,6 @@ gdk_win32_surface_destroy (GdkSurface *window,
|
||||
gdk_win32_surface_set_transient_for (child, NULL);
|
||||
}
|
||||
|
||||
#ifdef GDK_WIN32_ENABLE_EGL
|
||||
GdkWin32Display *display = GDK_WIN32_DISPLAY (gdk_surface_get_display (window));
|
||||
|
||||
/* Get rid of any EGLSurfaces that we might have created */
|
||||
if (surface->egl_surface != EGL_NO_SURFACE)
|
||||
{
|
||||
eglDestroySurface (display->egl_disp, surface->egl_surface);
|
||||
surface->egl_surface = EGL_NO_SURFACE;
|
||||
}
|
||||
if (surface->egl_dummy_surface != EGL_NO_SURFACE)
|
||||
{
|
||||
eglDestroySurface (display->egl_disp, surface->egl_dummy_surface);
|
||||
surface->egl_dummy_surface = EGL_NO_SURFACE;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Remove ourself from our transient owner */
|
||||
if (surface->transient_owner != NULL)
|
||||
{
|
||||
@@ -712,6 +694,7 @@ gdk_win32_surface_destroy (GdkSurface *window,
|
||||
|
||||
if (!foreign_destroy)
|
||||
{
|
||||
gdk_surface_set_egl_native_window (window, NULL);
|
||||
window->destroyed = TRUE;
|
||||
DestroyWindow (GDK_SURFACE_HWND (window));
|
||||
}
|
||||
@@ -864,8 +847,8 @@ show_window_internal (GdkSurface *window,
|
||||
{
|
||||
GdkSurface *owner = surface->transient_owner;
|
||||
/* Center on transient parent */
|
||||
center_on_rect.left = (owner->x - _gdk_offset_x) * surface->surface_scale;
|
||||
center_on_rect.top = (owner->y - _gdk_offset_y) * surface->surface_scale;
|
||||
center_on_rect.left = owner->x * surface->surface_scale;
|
||||
center_on_rect.top = owner->y * surface->surface_scale;
|
||||
center_on_rect.right = center_on_rect.left + owner->width * surface->surface_scale;
|
||||
center_on_rect.bottom = center_on_rect.top + owner->height * surface->surface_scale;
|
||||
|
||||
@@ -1047,13 +1030,13 @@ gdk_win32_surface_do_move (GdkSurface *window,
|
||||
GDK_NOTE (MISC, g_print ("... SetWindowPos(%p,NULL,%d,%d,0,0,"
|
||||
"NOACTIVATE|NOSIZE|NOZORDER)\n",
|
||||
GDK_SURFACE_HWND (window),
|
||||
(x - _gdk_offset_x) * impl->surface_scale,
|
||||
(y - _gdk_offset_y) * impl->surface_scale));
|
||||
x * impl->surface_scale,
|
||||
y * impl->surface_scale));
|
||||
|
||||
API_CALL (SetWindowPos, (GDK_SURFACE_HWND (window),
|
||||
SWP_NOZORDER_SPECIFIED,
|
||||
(x - _gdk_offset_x) * impl->surface_scale,
|
||||
(y - _gdk_offset_y) * impl->surface_scale,
|
||||
x * impl->surface_scale,
|
||||
y * impl->surface_scale,
|
||||
0, 0,
|
||||
SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER));
|
||||
}
|
||||
@@ -1133,15 +1116,15 @@ gdk_win32_surface_do_move_resize (GdkSurface *window,
|
||||
GDK_NOTE (MISC, g_print ("... SetWindowPos(%p,NULL,%d,%d,%ld,%ld,"
|
||||
"NOACTIVATE|NOZORDER)\n",
|
||||
GDK_SURFACE_HWND (window),
|
||||
(x - _gdk_offset_x) * impl->surface_scale,
|
||||
(y - _gdk_offset_y) * impl->surface_scale,
|
||||
x * impl->surface_scale,
|
||||
y * impl->surface_scale,
|
||||
outer_rect.right - outer_rect.left,
|
||||
outer_rect.bottom - outer_rect.top));
|
||||
|
||||
API_CALL (SetWindowPos, (GDK_SURFACE_HWND (window),
|
||||
SWP_NOZORDER_SPECIFIED,
|
||||
(x - _gdk_offset_x) * impl->surface_scale,
|
||||
(y - _gdk_offset_y) * impl->surface_scale,
|
||||
x * impl->surface_scale,
|
||||
y * impl->surface_scale,
|
||||
outer_rect.right - outer_rect.left,
|
||||
outer_rect.bottom - outer_rect.top,
|
||||
SWP_NOACTIVATE | SWP_NOZORDER));
|
||||
@@ -1681,14 +1664,6 @@ gdk_win32_surface_get_geometry (GdkSurface *window,
|
||||
|
||||
rect.right = pt.x;
|
||||
rect.bottom = pt.y;
|
||||
|
||||
if (parent == NULL)
|
||||
{
|
||||
rect.left += _gdk_offset_x * impl->surface_scale;
|
||||
rect.top += _gdk_offset_y * impl->surface_scale;
|
||||
rect.right += _gdk_offset_x * impl->surface_scale;
|
||||
rect.bottom += _gdk_offset_y * impl->surface_scale;
|
||||
}
|
||||
}
|
||||
|
||||
if (x)
|
||||
@@ -1727,16 +1702,16 @@ gdk_win32_surface_get_root_coords (GdkSurface *window,
|
||||
ty = pt.y;
|
||||
|
||||
if (root_x)
|
||||
*root_x = (tx + _gdk_offset_x) / impl->surface_scale;
|
||||
*root_x = tx / impl->surface_scale;
|
||||
if (root_y)
|
||||
*root_y = (ty + _gdk_offset_y) / impl->surface_scale;
|
||||
*root_y = ty / impl->surface_scale;
|
||||
|
||||
GDK_NOTE (MISC, g_print ("gdk_win32_surface_get_root_coords: %p: %+d%+d %+d%+d\n",
|
||||
GDK_SURFACE_HWND (window),
|
||||
x * impl->surface_scale,
|
||||
y * impl->surface_scale,
|
||||
(tx + _gdk_offset_x) / impl->surface_scale,
|
||||
(ty + _gdk_offset_y) / impl->surface_scale));
|
||||
tx / impl->surface_scale,
|
||||
ty / impl->surface_scale));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -2302,95 +2277,87 @@ stash_window (GdkSurface *window,
|
||||
}
|
||||
|
||||
static void
|
||||
snap_up (GdkSurface *window)
|
||||
snap_up (GdkSurface *surface)
|
||||
{
|
||||
SHORT maxysize;
|
||||
int x, y;
|
||||
int width, height;
|
||||
GdkWin32Surface *impl;
|
||||
|
||||
impl = GDK_WIN32_SURFACE (window);
|
||||
impl = GDK_WIN32_SURFACE (surface);
|
||||
|
||||
impl->snap_state = GDK_WIN32_AEROSNAP_STATE_FULLUP;
|
||||
|
||||
stash_window (window, impl);
|
||||
stash_window (surface, impl);
|
||||
|
||||
maxysize = GetSystemMetrics (SM_CYVIRTUALSCREEN) / impl->surface_scale;
|
||||
x = y = 0;
|
||||
width = gdk_surface_get_width (window);
|
||||
width = gdk_surface_get_width (surface);
|
||||
|
||||
y = 0;
|
||||
height = maxysize;
|
||||
|
||||
x = x - impl->shadow.left;
|
||||
y = y - impl->shadow.top;
|
||||
x = surface->x - impl->shadow.left / impl->surface_scale;
|
||||
y = y - impl->shadow.top / impl->surface_scale;
|
||||
width += impl->shadow_x;
|
||||
height += impl->shadow_y;
|
||||
|
||||
/* XXX: FIXME, AeroSnap snap_up() not really working well,
|
||||
*
|
||||
* * The snap_up() puts the window at the top left corner.
|
||||
* * Without the following call, the height maximizes but we see a spew of
|
||||
* "GdkToplevelSize: geometry size (x,y) exceeds bounds" warnings
|
||||
*/
|
||||
compute_toplevel_size (window, TRUE, &width, &height);
|
||||
|
||||
gdk_win32_surface_move_resize (window, x, y, width, height);
|
||||
gdk_win32_surface_move_resize (surface, x, y, width, height);
|
||||
}
|
||||
|
||||
static void
|
||||
snap_left (GdkSurface *window,
|
||||
snap_left (GdkSurface *surface,
|
||||
GdkMonitor *monitor,
|
||||
GdkMonitor *snap_monitor)
|
||||
{
|
||||
GdkRectangle rect;
|
||||
GdkWin32Surface *impl;
|
||||
|
||||
impl = GDK_WIN32_SURFACE (window);
|
||||
impl = GDK_WIN32_SURFACE (surface);
|
||||
|
||||
impl->snap_state = GDK_WIN32_AEROSNAP_STATE_HALFLEFT;
|
||||
|
||||
gdk_win32_monitor_get_workarea (snap_monitor, &rect);
|
||||
|
||||
stash_window (window, impl);
|
||||
stash_window (surface, impl);
|
||||
|
||||
rect.width = rect.width / 2;
|
||||
|
||||
rect.x = rect.x - impl->shadow.left;
|
||||
rect.y = rect.y - impl->shadow.top;
|
||||
rect.x = rect.x - impl->shadow.left / impl->surface_scale;
|
||||
rect.y = rect.y - impl->shadow.top / impl->surface_scale;
|
||||
rect.width = rect.width + impl->shadow_x;
|
||||
rect.height = rect.height + impl->shadow_y;
|
||||
|
||||
gdk_win32_surface_move_resize (window,
|
||||
gdk_win32_surface_move_resize (surface,
|
||||
rect.x, rect.y,
|
||||
rect.width, rect.height);
|
||||
}
|
||||
|
||||
static void
|
||||
snap_right (GdkSurface *window,
|
||||
snap_right (GdkSurface *surface,
|
||||
GdkMonitor *monitor,
|
||||
GdkMonitor *snap_monitor)
|
||||
{
|
||||
GdkRectangle rect;
|
||||
GdkWin32Surface *impl;
|
||||
|
||||
impl = GDK_WIN32_SURFACE (window);
|
||||
impl = GDK_WIN32_SURFACE (surface);
|
||||
|
||||
impl->snap_state = GDK_WIN32_AEROSNAP_STATE_HALFRIGHT;
|
||||
|
||||
gdk_win32_monitor_get_workarea (snap_monitor, &rect);
|
||||
|
||||
stash_window (window, impl);
|
||||
stash_window (surface, impl);
|
||||
|
||||
rect.width = rect.width / 2;
|
||||
rect.x += rect.width;
|
||||
|
||||
rect.x = rect.x - impl->shadow.left;
|
||||
rect.y = rect.y - impl->shadow.top;
|
||||
rect.x = rect.x - impl->shadow.left / impl->surface_scale;
|
||||
rect.y = rect.y - impl->shadow.top / impl->surface_scale;
|
||||
rect.width = rect.width + impl->shadow_x;
|
||||
rect.height = rect.height + impl->shadow_y;
|
||||
|
||||
gdk_win32_surface_move_resize (window,
|
||||
gdk_win32_surface_move_resize (surface,
|
||||
rect.x, rect.y,
|
||||
rect.width, rect.height);
|
||||
}
|
||||
@@ -2883,8 +2850,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->surface_scale;
|
||||
window_position.y = (context->indicator_window_rect.y - _gdk_offset_y) * impl->surface_scale;
|
||||
window_position.x = context->indicator_window_rect.x * impl->surface_scale;
|
||||
window_position.y = context->indicator_window_rect.y * impl->surface_scale;
|
||||
window_size.cx = context->indicator_window_rect.width * impl->surface_scale;
|
||||
window_size.cy = context->indicator_window_rect.height * impl->surface_scale;
|
||||
|
||||
@@ -3021,6 +2988,7 @@ update_fullup_indicator (GdkSurface *window,
|
||||
to.height = gdk_surface_get_height (window);
|
||||
|
||||
to.y = 0;
|
||||
to.x = window->x;
|
||||
to.height = maxysize;
|
||||
from = context->indicator_target;
|
||||
|
||||
@@ -3173,6 +3141,7 @@ start_indicator (GdkSurface *window,
|
||||
end_size.height = workarea.height;
|
||||
break;
|
||||
case GDK_WIN32_AEROSNAP_STATE_FULLUP:
|
||||
start_size.x = end_size.x = window->x;
|
||||
end_size.y = 0;
|
||||
end_size.height = maxysize;
|
||||
break;
|
||||
@@ -3575,8 +3544,8 @@ setup_drag_move_resize_context (GdkSurface *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->surface_scale,
|
||||
placement.rcNormalPosition.top + _gdk_offset_y * impl->surface_scale));
|
||||
placement.rcNormalPosition.left,
|
||||
placement.rcNormalPosition.top));
|
||||
|
||||
unmax_width = placement.rcNormalPosition.right - placement.rcNormalPosition.left;
|
||||
unmax_height = placement.rcNormalPosition.bottom - placement.rcNormalPosition.top;
|
||||
@@ -3587,40 +3556,36 @@ setup_drag_move_resize_context (GdkSurface *window,
|
||||
if (offsetx * impl->surface_scale < (shadow_unmax_width / 2) &&
|
||||
offsety * impl->surface_scale < (shadow_unmax_height / 2))
|
||||
{
|
||||
placement.rcNormalPosition.top = (root_y - offsety + impl->shadow.top - _gdk_offset_y) * impl->surface_scale;
|
||||
placement.rcNormalPosition.top = (root_y - offsety + impl->shadow.top) * impl->surface_scale;
|
||||
placement.rcNormalPosition.bottom = placement.rcNormalPosition.top + unmax_height;
|
||||
|
||||
if (left_half)
|
||||
{
|
||||
placement.rcNormalPosition.left = (root_x - offsetx + impl->shadow.left - _gdk_offset_x) * impl->surface_scale;
|
||||
placement.rcNormalPosition.left = (root_x - offsetx + impl->shadow.left) * impl->surface_scale;
|
||||
placement.rcNormalPosition.right = placement.rcNormalPosition.left + unmax_width;
|
||||
}
|
||||
else
|
||||
{
|
||||
placement.rcNormalPosition.right = (root_x + offsetx + impl->shadow.right - _gdk_offset_x) * impl->surface_scale;
|
||||
placement.rcNormalPosition.right = (root_x + offsetx + impl->shadow.right) * impl->surface_scale;
|
||||
placement.rcNormalPosition.left = placement.rcNormalPosition.right - unmax_width;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
placement.rcNormalPosition.left = (root_x * impl->surface_scale) -
|
||||
(unmax_width / 2) -
|
||||
(_gdk_offset_x * impl->surface_scale);
|
||||
placement.rcNormalPosition.left = root_x * impl->surface_scale - unmax_width / 2;
|
||||
|
||||
if (offsety * impl->surface_scale < shadow_unmax_height / 2)
|
||||
placement.rcNormalPosition.top = (root_y - offsety + impl->shadow.top - _gdk_offset_y) * impl->surface_scale;
|
||||
placement.rcNormalPosition.top = (root_y - offsety + impl->shadow.top) * impl->surface_scale;
|
||||
else
|
||||
placement.rcNormalPosition.top = (root_y * impl->surface_scale) -
|
||||
(unmax_height / 2) -
|
||||
(_gdk_offset_y * impl->surface_scale);
|
||||
placement.rcNormalPosition.top = root_y * impl->surface_scale - unmax_height / 2;
|
||||
|
||||
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->surface_scale,
|
||||
placement.rcNormalPosition.top + _gdk_offset_y * impl->surface_scale));
|
||||
placement.rcNormalPosition.left,
|
||||
placement.rcNormalPosition.top));
|
||||
|
||||
API_CALL (SetWindowPlacement, (GDK_SURFACE_HWND (window), &placement));
|
||||
}
|
||||
@@ -3678,7 +3643,7 @@ setup_drag_move_resize_context (GdkSurface *window,
|
||||
* the titlebar is, if any.
|
||||
*/
|
||||
root_y = wy + wheight / 2;
|
||||
SetCursorPos (root_x - _gdk_offset_x, root_y - _gdk_offset_y);
|
||||
SetCursorPos (root_x, root_y);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3799,12 +3764,6 @@ gdk_win32_get_window_size_and_position_from_client_rect (GdkSurface *window,
|
||||
/* Turn client area into window area */
|
||||
_gdk_win32_adjust_client_rect (window, window_rect);
|
||||
|
||||
/* Convert GDK screen coordinates to W32 desktop coordinates */
|
||||
window_rect->left -= _gdk_offset_x * impl->surface_scale;
|
||||
window_rect->right -= _gdk_offset_x * impl->surface_scale;
|
||||
window_rect->top -= _gdk_offset_y * impl->surface_scale;
|
||||
window_rect->bottom -= _gdk_offset_y * impl->surface_scale;
|
||||
|
||||
window_position->x = window_rect->left;
|
||||
window_position->y = window_rect->top;
|
||||
window_size->cx = window_rect->right - window_rect->left;
|
||||
@@ -5053,39 +5012,6 @@ gdk_win32_drag_surface_iface_init (GdkDragSurfaceInterface *iface)
|
||||
iface->present = gdk_win32_drag_surface_present;
|
||||
}
|
||||
|
||||
#ifdef GDK_WIN32_ENABLE_EGL
|
||||
EGLSurface
|
||||
gdk_win32_surface_get_egl_surface (GdkSurface *surface,
|
||||
EGLConfig config,
|
||||
gboolean is_dummy)
|
||||
{
|
||||
GdkWin32Display *display = GDK_WIN32_DISPLAY (gdk_surface_get_display (surface));
|
||||
GdkWin32Surface *impl = GDK_WIN32_SURFACE (surface);
|
||||
|
||||
if (is_dummy)
|
||||
{
|
||||
if (impl->egl_dummy_surface == EGL_NO_SURFACE)
|
||||
{
|
||||
EGLint attribs[] = {EGL_WIDTH, 1, EGL_WIDTH, 1, EGL_NONE};
|
||||
impl->egl_dummy_surface = eglCreatePbufferSurface (display->egl_disp,
|
||||
config,
|
||||
attribs);
|
||||
}
|
||||
return impl->egl_dummy_surface;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (impl->egl_surface == EGL_NO_SURFACE)
|
||||
impl->egl_surface = eglCreateWindowSurface (display->egl_disp,
|
||||
config,
|
||||
GDK_SURFACE_HWND (surface),
|
||||
NULL);
|
||||
|
||||
return impl->egl_surface;
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
gdk_win32_surface_get_queued_window_rect (GdkSurface *surface,
|
||||
@@ -5100,12 +5026,6 @@ gdk_win32_surface_get_queued_window_rect (GdkSurface *surface,
|
||||
/* Turn client area into window area */
|
||||
_gdk_win32_adjust_client_rect (surface, &window_rect);
|
||||
|
||||
/* Convert GDK screen coordinates to W32 desktop coordinates */
|
||||
window_rect.left -= _gdk_offset_x * impl->surface_scale;
|
||||
window_rect.right -= _gdk_offset_x * impl->surface_scale;
|
||||
window_rect.top -= _gdk_offset_y * impl->surface_scale;
|
||||
window_rect.bottom -= _gdk_offset_y * impl->surface_scale;
|
||||
|
||||
*return_window_rect = window_rect;
|
||||
}
|
||||
|
||||
@@ -5170,7 +5090,7 @@ _gdk_win32_surface_invalidate_egl_framebuffer (GdkSurface *surface)
|
||||
* as we need to re-acquire the EGL surfaces that we rendered to upload to Cairo explicitly,
|
||||
* using gdk_window_invalidate_rect (), when we maximize or restore or use aerosnap
|
||||
*/
|
||||
#ifdef GDK_WIN32_ENABLE_EGL
|
||||
#ifdef HAVE_EGL
|
||||
if (surface->gl_paint_context != NULL && gdk_gl_context_get_use_es (surface->gl_paint_context))
|
||||
{
|
||||
GdkWin32Surface *impl = GDK_WIN32_SURFACE (surface);
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#ifdef GDK_WIN32_ENABLE_EGL
|
||||
#ifdef HAVE_EGL
|
||||
# include <epoxy/egl.h>
|
||||
#endif
|
||||
|
||||
@@ -338,9 +338,7 @@ struct _GdkWin32Surface
|
||||
RECT configured_rect;
|
||||
} next_layout;
|
||||
|
||||
#ifdef GDK_WIN32_ENABLE_EGL
|
||||
EGLSurface egl_surface;
|
||||
EGLSurface egl_dummy_surface;
|
||||
#ifdef HAVE_EGL
|
||||
guint egl_force_redraw_all : 1;
|
||||
#endif
|
||||
};
|
||||
@@ -373,7 +371,7 @@ void gdk_win32_surface_move_resize (GdkSurface *window,
|
||||
RECT
|
||||
gdk_win32_surface_handle_queued_move_resize (GdkDrawContext *draw_context);
|
||||
|
||||
#ifdef GDK_WIN32_ENABLE_EGL
|
||||
#ifdef HAVE_EGL
|
||||
EGLSurface gdk_win32_surface_get_egl_surface (GdkSurface *surface,
|
||||
EGLConfig config,
|
||||
gboolean is_dummy);
|
||||
|
||||
@@ -46,10 +46,7 @@ gdk_win32_public_headers = files([
|
||||
|
||||
install_headers(gdk_win32_public_headers, 'gdkwin32.h', subdir: 'gtk-4.0/gdk/win32/')
|
||||
|
||||
GDK_WIN32_EGL_CFLAGS = []
|
||||
|
||||
if have_egl
|
||||
GDK_WIN32_EGL_CFLAGS = ['-DGDK_WIN32_ENABLE_EGL']
|
||||
gdk_win32_sources += ['gdkglcontext-win32-egl.c']
|
||||
endif
|
||||
|
||||
@@ -67,6 +64,6 @@ libgdk_win32 = static_library('gdk-win32',
|
||||
'-DINSIDE_GDK_WIN32',
|
||||
'-D_WIN32_WINNT=0x0601',
|
||||
'-DWINVER=0x0601',
|
||||
] + GDK_WIN32_EGL_CFLAGS,
|
||||
],
|
||||
dependencies: [ gdk_deps, gdk_win32_deps ],
|
||||
)
|
||||
|
||||
@@ -76,11 +76,30 @@ print_atoms (GdkX11Clipboard *cb,
|
||||
});
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_x11_clipboard_default_output_closed (GObject *stream,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
GError *error = NULL;
|
||||
|
||||
if (!g_output_stream_close_finish (G_OUTPUT_STREAM (stream), result, &error))
|
||||
{
|
||||
GDK_NOTE (CLIPBOARD,
|
||||
g_printerr ("-------: failed to close stream: %s\n",
|
||||
error->message));
|
||||
g_error_free (error);
|
||||
}
|
||||
|
||||
g_object_unref (stream);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_x11_clipboard_default_output_done (GObject *clipboard,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
GOutputStream *stream = user_data;
|
||||
GError *error = NULL;
|
||||
|
||||
if (!gdk_clipboard_write_finish (GDK_CLIPBOARD (clipboard), result, &error))
|
||||
@@ -90,6 +109,12 @@ gdk_x11_clipboard_default_output_done (GObject *clipboard,
|
||||
GDK_X11_CLIPBOARD (clipboard)->selection, error->message));
|
||||
g_error_free (error);
|
||||
}
|
||||
|
||||
g_output_stream_close_async (stream,
|
||||
G_PRIORITY_DEFAULT,
|
||||
NULL,
|
||||
gdk_x11_clipboard_default_output_closed,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -103,8 +128,7 @@ gdk_x11_clipboard_default_output_handler (GOutputStream *stream,
|
||||
G_PRIORITY_DEFAULT,
|
||||
NULL,
|
||||
gdk_x11_clipboard_default_output_done,
|
||||
NULL);
|
||||
g_object_unref (stream);
|
||||
stream);
|
||||
}
|
||||
|
||||
static GInputStream *
|
||||
|
||||
+26
-2
@@ -1612,11 +1612,30 @@ gdk_x11_drag_set_hotspot (GdkDrag *drag,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_x11_drag_default_output_closed (GObject *stream,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
GError *error = NULL;
|
||||
|
||||
if (!g_output_stream_close_finish (G_OUTPUT_STREAM (stream), result, &error))
|
||||
{
|
||||
GDK_NOTE (DND,
|
||||
g_printerr ("failed to close stream: %s\n",
|
||||
error->message));
|
||||
g_error_free (error);
|
||||
}
|
||||
|
||||
g_object_unref (stream);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_x11_drag_default_output_done (GObject *drag,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
GOutputStream *stream = user_data;
|
||||
GError *error = NULL;
|
||||
|
||||
if (!gdk_drag_write_finish (GDK_DRAG (drag), result, &error))
|
||||
@@ -1624,6 +1643,12 @@ gdk_x11_drag_default_output_done (GObject *drag,
|
||||
GDK_DISPLAY_NOTE (gdk_drag_get_display (GDK_DRAG (drag)), DND, g_printerr ("failed to write stream: %s\n", error->message));
|
||||
g_error_free (error);
|
||||
}
|
||||
|
||||
g_output_stream_close_async (stream,
|
||||
G_PRIORITY_DEFAULT,
|
||||
NULL,
|
||||
gdk_x11_drag_default_output_closed,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1637,8 +1662,7 @@ gdk_x11_drag_default_output_handler (GOutputStream *stream,
|
||||
G_PRIORITY_DEFAULT,
|
||||
NULL,
|
||||
gdk_x11_drag_default_output_done,
|
||||
NULL);
|
||||
g_object_unref (stream);
|
||||
stream);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
||||
+10
-1
@@ -492,9 +492,18 @@ init_randr15 (GdkX11Screen *x11_screen)
|
||||
|
||||
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];
|
||||
|
||||
@@ -57,7 +57,8 @@ struct _GdkX11SelectionOutputStreamPrivate {
|
||||
GTask *pending_task;
|
||||
|
||||
guint incr : 1;
|
||||
guint delete_pending : 1;
|
||||
guint sent_end_of_stream : 1;
|
||||
guint delete_pending : 1; /* owns a reference */
|
||||
};
|
||||
|
||||
struct _GdkX11PendingSelectionNotify
|
||||
@@ -176,12 +177,16 @@ gdk_x11_selection_output_stream_needs_flush_unlocked (GdkX11SelectionOutputStrea
|
||||
{
|
||||
GdkX11SelectionOutputStreamPrivate *priv = gdk_x11_selection_output_stream_get_instance_private (stream);
|
||||
|
||||
if (priv->data->len == 0 && priv->notify == NULL)
|
||||
if (priv->sent_end_of_stream)
|
||||
return FALSE;
|
||||
|
||||
if (g_output_stream_is_closing (G_OUTPUT_STREAM (stream)))
|
||||
if (g_output_stream_is_closing (G_OUTPUT_STREAM (stream)) ||
|
||||
g_output_stream_is_closed (G_OUTPUT_STREAM (stream)))
|
||||
return TRUE;
|
||||
|
||||
if (priv->data->len == 0 && priv->notify == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (priv->flush_requested)
|
||||
return TRUE;
|
||||
|
||||
@@ -284,6 +289,8 @@ gdk_x11_selection_output_stream_perform_flush (GdkX11SelectionOutputStream *stre
|
||||
g_byte_array_remove_range (priv->data, 0, n_elements * element_size);
|
||||
if (priv->data->len < element_size)
|
||||
priv->flush_requested = FALSE;
|
||||
if (!priv->incr || n_elements == 0)
|
||||
priv->sent_end_of_stream = TRUE;
|
||||
}
|
||||
|
||||
if (priv->notify)
|
||||
@@ -292,6 +299,7 @@ gdk_x11_selection_output_stream_perform_flush (GdkX11SelectionOutputStream *stre
|
||||
priv->notify = NULL;
|
||||
}
|
||||
|
||||
g_object_ref (stream);
|
||||
priv->delete_pending = TRUE;
|
||||
g_cond_broadcast (&priv->cond);
|
||||
g_mutex_unlock (&priv->mutex);
|
||||
@@ -494,60 +502,6 @@ gdk_x11_selection_output_stream_flush_finish (GOutputStream *stream,
|
||||
return g_task_propagate_boolean (G_TASK (result), error);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_x11_selection_output_stream_invoke_close (gpointer stream)
|
||||
{
|
||||
GdkX11SelectionOutputStreamPrivate *priv = gdk_x11_selection_output_stream_get_instance_private (stream);
|
||||
|
||||
GDK_X11_DISPLAY (priv->display)->streams = g_slist_remove (GDK_X11_DISPLAY (priv->display)->streams, stream);
|
||||
g_signal_handlers_disconnect_by_func (priv->display,
|
||||
gdk_x11_selection_output_stream_xevent,
|
||||
stream);
|
||||
g_object_unref (stream);
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_x11_selection_output_stream_close (GOutputStream *stream,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
g_main_context_invoke (NULL, gdk_x11_selection_output_stream_invoke_close, g_object_ref (stream));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_x11_selection_output_stream_close_async (GOutputStream *stream,
|
||||
int io_priority,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
GTask *task;
|
||||
|
||||
task = g_task_new (stream, cancellable, callback, user_data);
|
||||
g_task_set_source_tag (task, gdk_x11_selection_output_stream_close_async);
|
||||
g_task_set_priority (task, io_priority);
|
||||
|
||||
gdk_x11_selection_output_stream_invoke_close (stream);
|
||||
g_task_return_boolean (task, TRUE);
|
||||
|
||||
g_object_unref (task);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_x11_selection_output_stream_close_finish (GOutputStream *stream,
|
||||
GAsyncResult *result,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (g_task_is_valid (result, stream), FALSE);
|
||||
g_return_val_if_fail (g_async_result_is_tagged (result, gdk_x11_selection_output_stream_close_async), FALSE);
|
||||
|
||||
return g_task_propagate_boolean (G_TASK (result), error);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_x11_selection_output_stream_finalize (GObject *object)
|
||||
{
|
||||
@@ -557,6 +511,13 @@ gdk_x11_selection_output_stream_finalize (GObject *object)
|
||||
/* not sending a notify is terrible */
|
||||
g_assert (priv->notify == NULL);
|
||||
|
||||
GDK_DISPLAY_NOTE (priv->display, SELECTION, g_printerr ("%s:%s: finalizing\n",
|
||||
priv->selection, priv->target));
|
||||
GDK_X11_DISPLAY (priv->display)->streams = g_slist_remove (GDK_X11_DISPLAY (priv->display)->streams, stream);
|
||||
g_signal_handlers_disconnect_by_func (priv->display,
|
||||
gdk_x11_selection_output_stream_xevent,
|
||||
stream);
|
||||
|
||||
g_byte_array_unref (priv->data);
|
||||
g_cond_clear (&priv->cond);
|
||||
g_mutex_clear (&priv->mutex);
|
||||
@@ -579,14 +540,11 @@ gdk_x11_selection_output_stream_class_init (GdkX11SelectionOutputStreamClass *kl
|
||||
|
||||
output_stream_class->write_fn = gdk_x11_selection_output_stream_write;
|
||||
output_stream_class->flush = gdk_x11_selection_output_stream_flush;
|
||||
output_stream_class->close_fn = gdk_x11_selection_output_stream_close;
|
||||
|
||||
output_stream_class->write_async = gdk_x11_selection_output_stream_write_async;
|
||||
output_stream_class->write_finish = gdk_x11_selection_output_stream_write_finish;
|
||||
output_stream_class->flush_async = gdk_x11_selection_output_stream_flush_async;
|
||||
output_stream_class->flush_finish = gdk_x11_selection_output_stream_flush_finish;
|
||||
output_stream_class->close_async = gdk_x11_selection_output_stream_close_async;
|
||||
output_stream_class->close_finish = gdk_x11_selection_output_stream_close_finish;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -628,6 +586,7 @@ gdk_x11_selection_output_stream_xevent (GdkDisplay *display,
|
||||
if (gdk_x11_selection_output_stream_needs_flush (stream) &&
|
||||
gdk_x11_selection_output_stream_can_flush (stream))
|
||||
gdk_x11_selection_output_stream_perform_flush (stream);
|
||||
g_object_unref (stream); /* from unsetting the delete_pending */
|
||||
return FALSE;
|
||||
|
||||
default:
|
||||
|
||||
+20
-9
@@ -28,10 +28,11 @@
|
||||
#include "gskglcompilerprivate.h"
|
||||
#include "gskglprogramprivate.h"
|
||||
|
||||
#define SHADER_VERSION_GLES 100
|
||||
#define SHADER_VERSION_GL2_LEGACY 110
|
||||
#define SHADER_VERSION_GL3_LEGACY 130
|
||||
#define SHADER_VERSION_GL3 150
|
||||
#define SHADER_VERSION_GLES "100"
|
||||
#define SHADER_VERSION_GLES3 "300 es"
|
||||
#define SHADER_VERSION_GL2_LEGACY "110"
|
||||
#define SHADER_VERSION_GL3_LEGACY "130"
|
||||
#define SHADER_VERSION_GL3 "150"
|
||||
|
||||
struct _GskGLCompiler
|
||||
{
|
||||
@@ -49,7 +50,7 @@ struct _GskGLCompiler
|
||||
|
||||
GArray *attrib_locations;
|
||||
|
||||
int glsl_version;
|
||||
const char *glsl_version;
|
||||
|
||||
guint gl3 : 1;
|
||||
guint gles : 1;
|
||||
@@ -98,7 +99,7 @@ gsk_gl_compiler_class_init (GskGLCompilerClass *klass)
|
||||
static void
|
||||
gsk_gl_compiler_init (GskGLCompiler *self)
|
||||
{
|
||||
self->glsl_version = 150;
|
||||
self->glsl_version = "150";
|
||||
self->attrib_locations = g_array_new (FALSE, FALSE, sizeof (GskGLProgramAttrib));
|
||||
self->all_preamble = g_bytes_ref (empty_bytes);
|
||||
self->vertex_preamble = g_bytes_ref (empty_bytes);
|
||||
@@ -127,8 +128,18 @@ gsk_gl_compiler_new (GskGLDriver *driver,
|
||||
|
||||
if (gdk_gl_context_get_use_es (context))
|
||||
{
|
||||
self->glsl_version = SHADER_VERSION_GLES;
|
||||
self->gles = TRUE;
|
||||
int maj, min;
|
||||
|
||||
/* for OpenGL/ES 3.0+, use "300 es" as our shader version */
|
||||
gdk_gl_context_get_version (context, &maj, &min);
|
||||
|
||||
if (maj >= 3)
|
||||
self->glsl_version = SHADER_VERSION_GLES3;
|
||||
else
|
||||
{
|
||||
self->glsl_version = SHADER_VERSION_GLES;
|
||||
self->gles = TRUE;
|
||||
}
|
||||
}
|
||||
else if (gdk_gl_context_is_legacy (context))
|
||||
{
|
||||
@@ -546,7 +557,7 @@ gsk_gl_compiler_compile (GskGLCompiler *self,
|
||||
|
||||
gsk_gl_command_queue_make_current (self->driver->command_queue);
|
||||
|
||||
g_snprintf (version, sizeof version, "#version %d\n", self->glsl_version);
|
||||
g_snprintf (version, sizeof version, "#version %s\n", self->glsl_version);
|
||||
|
||||
if (self->debug_shaders)
|
||||
debug = "#define GSK_DEBUG 1\n";
|
||||
|
||||
+11
-15
@@ -161,25 +161,27 @@ gsk_gl_glyph_library_create_surface (GskGLGlyphLibrary *self,
|
||||
|
||||
static void
|
||||
render_glyph (cairo_surface_t *surface,
|
||||
const cairo_scaled_font_t *scaled_font,
|
||||
const GskGLGlyphKey *key,
|
||||
const GskGLGlyphValue *value)
|
||||
{
|
||||
cairo_t *cr;
|
||||
cairo_glyph_t glyph;
|
||||
PangoGlyphString glyph_string;
|
||||
PangoGlyphInfo glyph_info;
|
||||
|
||||
g_assert (surface != NULL);
|
||||
g_assert (scaled_font != NULL);
|
||||
|
||||
cr = cairo_create (surface);
|
||||
cairo_set_scaled_font (cr, scaled_font);
|
||||
cairo_set_source_rgba (cr, 1, 1, 1, 1);
|
||||
|
||||
glyph.index = key->glyph;
|
||||
glyph.x = 0.25 * key->xshift - value->ink_rect.x;
|
||||
glyph.y = 0.25 * key->yshift - value->ink_rect.y;
|
||||
glyph_info.glyph = key->glyph;
|
||||
glyph_info.geometry.width = value->ink_rect.width * 1024;
|
||||
glyph_info.geometry.x_offset = 0.25 * key->xshift - value->ink_rect.x * 1024;
|
||||
glyph_info.geometry.y_offset = 0.25 * key->yshift - value->ink_rect.y * 1024;
|
||||
|
||||
cairo_show_glyphs (cr, &glyph, 1);
|
||||
glyph_string.num_glyphs = 1;
|
||||
glyph_string.glyphs = &glyph_info;
|
||||
|
||||
pango_cairo_show_glyph_string (cr, key->font, &glyph_string);
|
||||
cairo_destroy (cr);
|
||||
|
||||
cairo_surface_flush (surface);
|
||||
@@ -198,7 +200,6 @@ gsk_gl_glyph_library_upload_glyph (GskGLGlyphLibrary *self,
|
||||
{
|
||||
GskGLTextureLibrary *tl = (GskGLTextureLibrary *)self;
|
||||
G_GNUC_UNUSED gint64 start_time = GDK_PROFILER_CURRENT_TIME;
|
||||
cairo_scaled_font_t *scaled_font;
|
||||
cairo_surface_t *surface;
|
||||
guchar *pixel_data;
|
||||
guchar *free_data = NULL;
|
||||
@@ -211,11 +212,6 @@ gsk_gl_glyph_library_upload_glyph (GskGLGlyphLibrary *self,
|
||||
g_assert (key != NULL);
|
||||
g_assert (value != NULL);
|
||||
|
||||
scaled_font = pango_cairo_font_get_scaled_font ((PangoCairoFont *)key->font);
|
||||
if G_UNLIKELY (scaled_font == NULL ||
|
||||
cairo_scaled_font_status (scaled_font) != CAIRO_STATUS_SUCCESS)
|
||||
return;
|
||||
|
||||
stride = cairo_format_stride_for_width (CAIRO_FORMAT_ARGB32, width);
|
||||
|
||||
gdk_gl_context_push_debug_group_printf (gdk_gl_context_get_current (),
|
||||
@@ -223,7 +219,7 @@ gsk_gl_glyph_library_upload_glyph (GskGLGlyphLibrary *self,
|
||||
key->glyph);
|
||||
|
||||
surface = gsk_gl_glyph_library_create_surface (self, stride, width, height, uwidth, uheight);
|
||||
render_glyph (surface, scaled_font, key, value);
|
||||
render_glyph (surface, key, value);
|
||||
|
||||
texture_id = GSK_GL_TEXTURE_ATLAS_ENTRY_TEXTURE (value);
|
||||
|
||||
|
||||
+66
-15
@@ -245,6 +245,47 @@ gsk_rounded_rect_shrink_to_minimum (GskRoundedRect *self)
|
||||
self->corner[1].height + self->corner[2].height);
|
||||
}
|
||||
|
||||
static inline gboolean G_GNUC_PURE
|
||||
node_supports_2d_transform (const GskRenderNode *node)
|
||||
{
|
||||
switch ((int)gsk_render_node_get_node_type (node))
|
||||
{
|
||||
case GSK_COLOR_NODE:
|
||||
case GSK_OPACITY_NODE:
|
||||
case GSK_COLOR_MATRIX_NODE:
|
||||
case GSK_TEXTURE_NODE:
|
||||
case GSK_CROSS_FADE_NODE:
|
||||
case GSK_LINEAR_GRADIENT_NODE:
|
||||
case GSK_REPEATING_LINEAR_GRADIENT_NODE:
|
||||
case GSK_CONIC_GRADIENT_NODE:
|
||||
case GSK_RADIAL_GRADIENT_NODE:
|
||||
case GSK_REPEATING_RADIAL_GRADIENT_NODE:
|
||||
case GSK_DEBUG_NODE:
|
||||
case GSK_TEXT_NODE:
|
||||
case GSK_CAIRO_NODE:
|
||||
case GSK_BLEND_NODE:
|
||||
case GSK_BLUR_NODE:
|
||||
return TRUE;
|
||||
|
||||
case GSK_SHADOW_NODE:
|
||||
return node_supports_2d_transform (gsk_shadow_node_get_child (node));
|
||||
|
||||
case GSK_TRANSFORM_NODE:
|
||||
return node_supports_2d_transform (gsk_transform_node_get_child (node));
|
||||
|
||||
case GSK_CONTAINER_NODE:
|
||||
for (guint i = 0, p = gsk_container_node_get_n_children (node); i < p; i++)
|
||||
{
|
||||
if (!node_supports_2d_transform (gsk_container_node_get_child (node, i)))
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static inline gboolean G_GNUC_PURE
|
||||
node_supports_transform (const GskRenderNode *node)
|
||||
{
|
||||
@@ -257,24 +298,26 @@ node_supports_transform (const GskRenderNode *node)
|
||||
|
||||
switch ((int)gsk_render_node_get_node_type (node))
|
||||
{
|
||||
case GSK_COLOR_NODE:
|
||||
case GSK_OPACITY_NODE:
|
||||
case GSK_COLOR_MATRIX_NODE:
|
||||
case GSK_TEXTURE_NODE:
|
||||
case GSK_CROSS_FADE_NODE:
|
||||
case GSK_LINEAR_GRADIENT_NODE:
|
||||
case GSK_DEBUG_NODE:
|
||||
case GSK_TEXT_NODE:
|
||||
return TRUE;
|
||||
case GSK_COLOR_NODE:
|
||||
case GSK_OPACITY_NODE:
|
||||
case GSK_COLOR_MATRIX_NODE:
|
||||
case GSK_TEXTURE_NODE:
|
||||
case GSK_CROSS_FADE_NODE:
|
||||
case GSK_DEBUG_NODE:
|
||||
case GSK_TEXT_NODE:
|
||||
case GSK_CAIRO_NODE:
|
||||
case GSK_BLEND_NODE:
|
||||
case GSK_BLUR_NODE:
|
||||
return TRUE;
|
||||
|
||||
case GSK_SHADOW_NODE:
|
||||
return node_supports_transform (gsk_shadow_node_get_child (node));
|
||||
case GSK_SHADOW_NODE:
|
||||
return node_supports_transform (gsk_shadow_node_get_child (node));
|
||||
|
||||
case GSK_TRANSFORM_NODE:
|
||||
return node_supports_transform (gsk_transform_node_get_child (node));
|
||||
case GSK_TRANSFORM_NODE:
|
||||
return node_supports_transform (gsk_transform_node_get_child (node));
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2017,6 +2060,14 @@ gsk_gl_render_job_visit_transform_node (GskGLRenderJob *job,
|
||||
break;
|
||||
|
||||
case GSK_TRANSFORM_CATEGORY_2D:
|
||||
if (node_supports_2d_transform (child))
|
||||
{
|
||||
gsk_gl_render_job_push_modelview (job, transform);
|
||||
gsk_gl_render_job_visit_node (job, child);
|
||||
gsk_gl_render_job_pop_modelview (job);
|
||||
return;
|
||||
}
|
||||
G_GNUC_FALLTHROUGH;
|
||||
case GSK_TRANSFORM_CATEGORY_3D:
|
||||
case GSK_TRANSFORM_CATEGORY_ANY:
|
||||
case GSK_TRANSFORM_CATEGORY_UNKNOWN:
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
uniform vec4 u_geometry;
|
||||
|
||||
_NOPERSPECTIVE_ _OUT_ vec2 coord;
|
||||
_OUT_ vec2 coord;
|
||||
|
||||
void main() {
|
||||
gl_Position = u_projection * (u_modelview * vec4(aPosition, 0.0, 1.0));
|
||||
@@ -29,7 +29,7 @@ uniform highp int u_num_color_stops; // Why? Because it works like this.
|
||||
uniform vec4 u_geometry;
|
||||
uniform float u_color_stops[MAX_COLOR_STOPS * 5];
|
||||
|
||||
_NOPERSPECTIVE_ _IN_ vec2 coord;
|
||||
_IN_ vec2 coord;
|
||||
|
||||
float get_offset(int index) {
|
||||
// u_color_stops[5 * index] makes Intel Windows driver crash.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// linear_gradient.glsl
|
||||
uniform vec4 u_points;
|
||||
|
||||
_NOPERSPECTIVE_ _OUT_ vec4 info;
|
||||
_OUT_ vec4 info;
|
||||
|
||||
void main() {
|
||||
gl_Position = u_projection * (u_modelview * vec4(aPosition, 0.0, 1.0));
|
||||
@@ -53,7 +53,7 @@ uniform highp int u_num_color_stops; // Why? Because it works like this.
|
||||
uniform float u_color_stops[MAX_COLOR_STOPS * 5];
|
||||
uniform bool u_repeat;
|
||||
|
||||
_NOPERSPECTIVE_ _IN_ vec4 info;
|
||||
_IN_ vec4 info;
|
||||
|
||||
float get_offset(int index) {
|
||||
// u_color_stops[5 * index] makes Intel Windows driver crash.
|
||||
|
||||
@@ -5,12 +5,10 @@ precision highp float;
|
||||
#if defined(GSK_GLES) || defined(GSK_LEGACY)
|
||||
#define _OUT_ varying
|
||||
#define _IN_ varying
|
||||
#define _NOPERSPECTIVE_
|
||||
#define _GSK_ROUNDED_RECT_UNIFORM_ vec4[3]
|
||||
#else
|
||||
#define _OUT_ out
|
||||
#define _IN_ in
|
||||
#define _NOPERSPECTIVE_ noperspective
|
||||
#define _GSK_ROUNDED_RECT_UNIFORM_ GskRoundedRect
|
||||
#endif
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
uniform vec4 u_geometry;
|
||||
|
||||
_NOPERSPECTIVE_ _OUT_ vec2 coord;
|
||||
_OUT_ vec2 coord;
|
||||
|
||||
void main() {
|
||||
gl_Position = u_projection * (u_modelview * vec4(aPosition, 0.0, 1.0));
|
||||
@@ -32,7 +32,7 @@ uniform bool u_repeat;
|
||||
uniform vec2 u_range;
|
||||
uniform float u_color_stops[MAX_COLOR_STOPS * 5];
|
||||
|
||||
_NOPERSPECTIVE_ _IN_ vec2 coord;
|
||||
_IN_ vec2 coord;
|
||||
|
||||
float get_offset(int index) {
|
||||
// u_color_stops[5 * index] makes Intel Windows driver crash.
|
||||
|
||||
+1
-1
@@ -494,7 +494,7 @@ GskRenderNode * gsk_text_node_new (PangoFont
|
||||
const graphene_point_t *offset);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
PangoFont * gsk_text_node_get_font (const GskRenderNode *node) G_GNUC_PURE;
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GDK_AVAILABLE_IN_4_2
|
||||
gboolean gsk_text_node_has_color_glyphs (const GskRenderNode *node) G_GNUC_PURE;
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
guint gsk_text_node_get_num_glyphs (const GskRenderNode *node) G_GNUC_PURE;
|
||||
|
||||
+10
-12
@@ -828,18 +828,14 @@ project (double angle,
|
||||
{
|
||||
double x, y;
|
||||
|
||||
x = radius * cos (angle);
|
||||
y = radius * sin (angle);
|
||||
if (copysign (x, 1.0) > copysign (y, 1.0))
|
||||
{
|
||||
*x_out = copysign (radius, x);
|
||||
*y_out = y * radius / copysign (x, 1.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
*x_out = x * radius / copysign (y, 1.0);
|
||||
*y_out = copysign (radius, y);
|
||||
}
|
||||
#ifdef HAVE_SINCOS
|
||||
sincos (angle, &y, &x);
|
||||
#else
|
||||
x = cos (angle);
|
||||
y = sin (angle);
|
||||
#endif
|
||||
*x_out = radius * x;
|
||||
*y_out = radius * y;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -4547,6 +4543,8 @@ gsk_text_node_get_font (const GskRenderNode *node)
|
||||
* Checks whether the text @node has color glyphs.
|
||||
*
|
||||
* Returns: %TRUE if the text node has color glyphs
|
||||
*
|
||||
* Since: 4.2
|
||||
*/
|
||||
gboolean
|
||||
gsk_text_node_has_color_glyphs (const GskRenderNode *node)
|
||||
|
||||
@@ -44,6 +44,16 @@ pango_variant_to_string (PangoVariant variant)
|
||||
return "normal";
|
||||
case PANGO_VARIANT_SMALL_CAPS:
|
||||
return "small_caps";
|
||||
case PANGO_VARIANT_ALL_SMALL_CAPS:
|
||||
return "all_small_caps";
|
||||
case PANGO_VARIANT_PETITE_CAPS:
|
||||
return "petite_caps";
|
||||
case PANGO_VARIANT_ALL_PETITE_CAPS:
|
||||
return "all_petite_caps";
|
||||
case PANGO_VARIANT_UNICASE:
|
||||
return "unicase";
|
||||
case PANGO_VARIANT_TITLE_CAPS:
|
||||
return "title_caps";
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ for f in get_files('theme/Default/assets-hc', '.svg'):
|
||||
xml += ' <file preprocess=\'xml-stripblanks\'>theme/Default/assets-hc/{0}</file>\n'.format(f)
|
||||
|
||||
for f in get_files('ui', '.ui'):
|
||||
xml += ' <file>ui/{0}</file>\n'.format(f)
|
||||
xml += ' <file alias="ui/{0}">ui/{0}.precompiled</file>\n'.format(f)
|
||||
|
||||
xml += '\n'
|
||||
|
||||
|
||||
+1
-1
@@ -494,7 +494,7 @@ out:
|
||||
* “`<Ctrl>minus`” instead of “`<Ctrl>-`”.
|
||||
*
|
||||
* Modifiers are enclosed in angular brackets `<>`, and match the
|
||||
* [enum@Gdk.ModifierType] mask:
|
||||
* [flags@Gdk.ModifierType] mask:
|
||||
*
|
||||
* - `<Shift>` for `GDK_SHIFT_MASK`
|
||||
* - `<Ctrl>` for `GDK_CONTROL_MASK`
|
||||
|
||||
+16
-11
@@ -945,6 +945,7 @@ gtk_action_muxer_register_observer (GtkActionObservable *observable,
|
||||
gboolean enabled;
|
||||
const GVariantType *parameter_type;
|
||||
GVariant *state;
|
||||
gboolean is_duplicate;
|
||||
|
||||
if (!muxer->observed_actions)
|
||||
muxer->observed_actions = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, gtk_action_muxer_free_action);
|
||||
@@ -961,22 +962,26 @@ gtk_action_muxer_register_observer (GtkActionObservable *observable,
|
||||
g_hash_table_insert (muxer->observed_actions, action->fullname, action);
|
||||
}
|
||||
|
||||
is_duplicate = g_slist_find (action->watchers, observer) != NULL;
|
||||
action->watchers = g_slist_prepend (action->watchers, observer);
|
||||
g_object_weak_ref (G_OBJECT (observer), gtk_action_muxer_weak_notify, action);
|
||||
|
||||
if (action_muxer_query_action (muxer, name,
|
||||
&enabled, ¶meter_type,
|
||||
NULL, NULL, &state, TRUE))
|
||||
if (!is_duplicate)
|
||||
{
|
||||
gtk_action_muxer_action_added (muxer, name, parameter_type, enabled, state);
|
||||
g_clear_pointer (&state, g_variant_unref);
|
||||
}
|
||||
if (action_muxer_query_action (muxer, name,
|
||||
&enabled, ¶meter_type,
|
||||
NULL, NULL, &state, TRUE))
|
||||
{
|
||||
gtk_action_muxer_action_added (muxer, name, parameter_type, enabled, state);
|
||||
g_clear_pointer (&state, g_variant_unref);
|
||||
}
|
||||
|
||||
if (muxer->parent)
|
||||
{
|
||||
gtk_action_observable_register_observer (GTK_ACTION_OBSERVABLE (muxer->parent),
|
||||
name,
|
||||
GTK_ACTION_OBSERVER (muxer));
|
||||
if (muxer->parent)
|
||||
{
|
||||
gtk_action_observable_register_observer (GTK_ACTION_OBSERVABLE (muxer->parent),
|
||||
name,
|
||||
GTK_ACTION_OBSERVER (muxer));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -93,7 +93,7 @@
|
||||
*
|
||||
* ## A simple application
|
||||
*
|
||||
* [A simple example](https://gitlab.gnome.org/GNOME/gtk/tree/master/examples/bp/bloatpad.c)
|
||||
* [A simple example](https://gitlab.gnome.org/GNOME/gtk/tree/main/examples/bp/bloatpad.c)
|
||||
* is available in the GTK source code repository
|
||||
*
|
||||
* `GtkApplication` optionally registers with a session manager of the
|
||||
@@ -671,7 +671,7 @@ gtk_application_class_init (GtkApplicationClass *class)
|
||||
* If `application_id` is not %NULL, then it must be valid. See
|
||||
* `g_application_id_is_valid()`.
|
||||
*
|
||||
* If no application ID is given then some features (most notably application
|
||||
* If no application ID is given then some features (most notably application
|
||||
* uniqueness) will be disabled.
|
||||
*
|
||||
* Returns: a new `GtkApplication` instance
|
||||
@@ -806,7 +806,7 @@ gtk_application_get_window_by_id (GtkApplication *application,
|
||||
|
||||
g_return_val_if_fail (GTK_IS_APPLICATION (application), NULL);
|
||||
|
||||
for (l = priv->windows; l != NULL; l = l->next)
|
||||
for (l = priv->windows; l != NULL; l = l->next)
|
||||
{
|
||||
if (GTK_IS_APPLICATION_WINDOW (l->data) &&
|
||||
gtk_application_window_get_id (GTK_APPLICATION_WINDOW (l->data)) == id)
|
||||
|
||||
+230
-76
@@ -256,11 +256,104 @@ gtk_box_layout_compute_size (GtkBoxLayout *self,
|
||||
static void
|
||||
gtk_box_layout_compute_opposite_size (GtkBoxLayout *self,
|
||||
GtkWidget *widget,
|
||||
int for_size,
|
||||
int *minimum,
|
||||
int *natural,
|
||||
int *min_baseline,
|
||||
int *nat_baseline)
|
||||
{
|
||||
GtkWidget *child;
|
||||
int largest_min = 0, largest_nat = 0;
|
||||
|
||||
for (child = gtk_widget_get_first_child (widget);
|
||||
child != NULL;
|
||||
child = gtk_widget_get_next_sibling (child))
|
||||
{
|
||||
int child_min = 0;
|
||||
int child_nat = 0;
|
||||
|
||||
if (!gtk_widget_should_layout (child))
|
||||
continue;
|
||||
|
||||
gtk_widget_measure (child,
|
||||
OPPOSITE_ORIENTATION (self->orientation),
|
||||
-1,
|
||||
&child_min, &child_nat,
|
||||
NULL, NULL);
|
||||
|
||||
largest_min = MAX (largest_min, child_min);
|
||||
largest_nat = MAX (largest_nat, child_nat);
|
||||
}
|
||||
|
||||
*minimum = largest_min;
|
||||
*natural = largest_nat;
|
||||
}
|
||||
|
||||
static int
|
||||
distribute_remaining_size (GtkRequestedSize *sizes,
|
||||
gsize n_sizes,
|
||||
GtkOrientation orientation,
|
||||
int available,
|
||||
int min,
|
||||
int max)
|
||||
{
|
||||
int total_size = 0;
|
||||
gsize i;
|
||||
|
||||
if (n_sizes == 0)
|
||||
return available;
|
||||
|
||||
for (i = 0; i < n_sizes; i++)
|
||||
{
|
||||
gtk_widget_measure (sizes[i].data,
|
||||
orientation,
|
||||
min,
|
||||
&sizes[i].minimum_size, &sizes[i].natural_size,
|
||||
NULL, NULL);
|
||||
total_size += sizes[i].minimum_size;
|
||||
}
|
||||
|
||||
if (total_size <= available)
|
||||
return available - total_size;
|
||||
|
||||
/* total_size > available happens when we last ran for values too big,
|
||||
* rerun for the correct value min == max in that case */
|
||||
while (min < max || total_size > available)
|
||||
{
|
||||
int test;
|
||||
|
||||
if (max == G_MAXINT)
|
||||
test = min * 2;
|
||||
else
|
||||
test = (min + max) / 2;
|
||||
|
||||
total_size = 0;
|
||||
for (i = 0; i < n_sizes; i++)
|
||||
{
|
||||
gtk_widget_measure (sizes[i].data,
|
||||
orientation,
|
||||
test,
|
||||
&sizes[i].minimum_size, &sizes[i].natural_size,
|
||||
NULL, NULL);
|
||||
total_size += sizes[i].minimum_size;
|
||||
}
|
||||
|
||||
if (total_size > available)
|
||||
min = test + 1;
|
||||
else
|
||||
max = test;
|
||||
}
|
||||
|
||||
return available - total_size;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_box_layout_compute_opposite_size_for_size (GtkBoxLayout *self,
|
||||
GtkWidget *widget,
|
||||
int for_size,
|
||||
int *minimum,
|
||||
int *natural,
|
||||
int *min_baseline,
|
||||
int *nat_baseline)
|
||||
{
|
||||
GtkWidget *child;
|
||||
int nvis_children;
|
||||
@@ -270,13 +363,12 @@ gtk_box_layout_compute_opposite_size (GtkBoxLayout *self,
|
||||
int computed_minimum_below = 0, computed_natural_below = 0;
|
||||
int computed_minimum_baseline = -1, computed_natural_baseline = -1;
|
||||
GtkRequestedSize *sizes;
|
||||
int extra_space, size_given_to_child, i;
|
||||
int children_minimum_size = 0;
|
||||
int available, size_given_to_child, i;
|
||||
int child_size, child_minimum, child_natural;
|
||||
int child_minimum_baseline, child_natural_baseline;
|
||||
int n_extra_widgets = 0;
|
||||
int spacing;
|
||||
gboolean have_baseline;
|
||||
gboolean have_baseline = FALSE;
|
||||
|
||||
count_expand_children (widget, self->orientation, &nvis_children, &nexpand_children);
|
||||
|
||||
@@ -285,78 +377,132 @@ gtk_box_layout_compute_opposite_size (GtkBoxLayout *self,
|
||||
|
||||
spacing = get_spacing (self, gtk_widget_get_css_node (widget));
|
||||
sizes = g_newa (GtkRequestedSize, nvis_children);
|
||||
extra_space = MAX (0, for_size - (nvis_children - 1) * spacing);
|
||||
|
||||
/* Retrieve desired size for visible children */
|
||||
for (i = 0, child = _gtk_widget_get_first_child (widget);
|
||||
child != NULL;
|
||||
child = _gtk_widget_get_next_sibling (child))
|
||||
{
|
||||
if (!gtk_widget_should_layout (child))
|
||||
continue;
|
||||
|
||||
gtk_widget_measure (child,
|
||||
self->orientation,
|
||||
-1,
|
||||
&sizes[i].minimum_size, &sizes[i].natural_size,
|
||||
NULL, NULL);
|
||||
|
||||
children_minimum_size += sizes[i].minimum_size;
|
||||
i += 1;
|
||||
}
|
||||
g_assert ((nvis_children - 1) * spacing <= for_size);
|
||||
available = for_size - (nvis_children - 1) * spacing;
|
||||
|
||||
if (self->homogeneous)
|
||||
{
|
||||
/* We still need to run the above loop to populate the minimum sizes for
|
||||
* children that aren't going to fill.
|
||||
*/
|
||||
size_given_to_child = available / nvis_children;
|
||||
n_extra_widgets = available % nvis_children;
|
||||
|
||||
size_given_to_child = extra_space / nvis_children;
|
||||
n_extra_widgets = extra_space % nvis_children;
|
||||
for (child = _gtk_widget_get_first_child (widget);
|
||||
child != NULL;
|
||||
child = _gtk_widget_get_next_sibling (child))
|
||||
{
|
||||
if (!gtk_widget_should_layout (child))
|
||||
continue;
|
||||
|
||||
child_size = size_given_to_child;
|
||||
if (n_extra_widgets)
|
||||
{
|
||||
child_size++;
|
||||
n_extra_widgets--;
|
||||
}
|
||||
|
||||
child_minimum_baseline = child_natural_baseline = -1;
|
||||
/* Assign the child's position. */
|
||||
gtk_widget_measure (child,
|
||||
OPPOSITE_ORIENTATION (self->orientation),
|
||||
child_size,
|
||||
&child_minimum, &child_natural,
|
||||
&child_minimum_baseline, &child_natural_baseline);
|
||||
|
||||
if (child_minimum_baseline >= 0)
|
||||
{
|
||||
have_baseline = TRUE;
|
||||
computed_minimum_below = MAX (computed_minimum_below, child_minimum - child_minimum_baseline);
|
||||
computed_natural_below = MAX (computed_natural_below, child_natural - child_natural_baseline);
|
||||
computed_minimum_above = MAX (computed_minimum_above, child_minimum_baseline);
|
||||
computed_natural_above = MAX (computed_natural_above, child_natural_baseline);
|
||||
}
|
||||
else
|
||||
{
|
||||
computed_minimum = MAX (computed_minimum, child_minimum);
|
||||
computed_natural = MAX (computed_natural, child_natural);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int min_size = 0, child_min_size;
|
||||
int n_inconstant = 0;
|
||||
|
||||
/* Retrieve desired size for visible children */
|
||||
for (i = 0, child = _gtk_widget_get_first_child (widget);
|
||||
child != NULL;
|
||||
child = _gtk_widget_get_next_sibling (child))
|
||||
{
|
||||
if (!gtk_widget_should_layout (child))
|
||||
continue;
|
||||
|
||||
if (gtk_widget_get_request_mode (child) == GTK_SIZE_REQUEST_CONSTANT_SIZE)
|
||||
{
|
||||
gtk_widget_measure (child,
|
||||
self->orientation,
|
||||
-1,
|
||||
&sizes[i].minimum_size, &sizes[i].natural_size,
|
||||
NULL, NULL);
|
||||
sizes[i].data = child;
|
||||
g_assert (available >= sizes[i].minimum_size);
|
||||
available -= sizes[i].minimum_size;
|
||||
i++;
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_widget_measure (child,
|
||||
OPPOSITE_ORIENTATION (self->orientation),
|
||||
-1,
|
||||
&child_min_size, NULL,
|
||||
NULL, NULL);
|
||||
min_size = MAX (min_size, child_min_size);
|
||||
n_inconstant++;
|
||||
sizes[nvis_children - n_inconstant].data = child;
|
||||
}
|
||||
}
|
||||
|
||||
available = distribute_remaining_size (sizes + nvis_children - n_inconstant,
|
||||
n_inconstant,
|
||||
self->orientation,
|
||||
available,
|
||||
min_size,
|
||||
G_MAXINT);
|
||||
|
||||
/* Bring children up to size first */
|
||||
extra_space -= children_minimum_size;
|
||||
extra_space = MAX (0, extra_space);
|
||||
extra_space = gtk_distribute_natural_allocation (extra_space, nvis_children, sizes);
|
||||
available = gtk_distribute_natural_allocation (available, nvis_children, sizes);
|
||||
|
||||
/* Calculate space which hasn't distributed yet,
|
||||
* and is available for expanding children.
|
||||
*/
|
||||
if (nexpand_children > 0)
|
||||
{
|
||||
size_given_to_child = extra_space / nexpand_children;
|
||||
n_extra_widgets = extra_space % nexpand_children;
|
||||
size_given_to_child = available / nexpand_children;
|
||||
n_extra_widgets = available % nexpand_children;
|
||||
}
|
||||
else
|
||||
{
|
||||
size_given_to_child = 0;
|
||||
}
|
||||
}
|
||||
|
||||
have_baseline = FALSE;
|
||||
for (i = 0, child = _gtk_widget_get_first_child (widget);
|
||||
child != NULL;
|
||||
child = _gtk_widget_get_next_sibling (child))
|
||||
{
|
||||
if (!gtk_widget_should_layout (child))
|
||||
continue;
|
||||
|
||||
/* Assign the child's size. */
|
||||
if (self->homogeneous)
|
||||
i = 0;
|
||||
n_inconstant = 0;
|
||||
for (child = _gtk_widget_get_first_child (widget);
|
||||
child != NULL;
|
||||
child = _gtk_widget_get_next_sibling (child))
|
||||
{
|
||||
child_size = size_given_to_child;
|
||||
if (!gtk_widget_should_layout (child))
|
||||
continue;
|
||||
|
||||
if (n_extra_widgets > 0)
|
||||
if (sizes[i].data == child)
|
||||
{
|
||||
child_size++;
|
||||
n_extra_widgets--;
|
||||
child_size = sizes[i].minimum_size;
|
||||
i++;
|
||||
}
|
||||
else
|
||||
{
|
||||
n_inconstant++;
|
||||
g_assert (sizes[nvis_children - n_inconstant].data == child);
|
||||
child_size = sizes[nvis_children - n_inconstant].minimum_size;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
child_size = sizes[i].minimum_size;
|
||||
|
||||
if (gtk_widget_compute_expand (child, self->orientation))
|
||||
{
|
||||
@@ -368,30 +514,29 @@ gtk_box_layout_compute_opposite_size (GtkBoxLayout *self,
|
||||
n_extra_widgets--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
child_minimum_baseline = child_natural_baseline = -1;
|
||||
/* Assign the child's position. */
|
||||
gtk_widget_measure (child,
|
||||
OPPOSITE_ORIENTATION (self->orientation),
|
||||
child_size,
|
||||
&child_minimum, &child_natural,
|
||||
&child_minimum_baseline, &child_natural_baseline);
|
||||
child_minimum_baseline = child_natural_baseline = -1;
|
||||
/* Assign the child's position. */
|
||||
gtk_widget_measure (child,
|
||||
OPPOSITE_ORIENTATION (self->orientation),
|
||||
child_size,
|
||||
&child_minimum, &child_natural,
|
||||
&child_minimum_baseline, &child_natural_baseline);
|
||||
|
||||
if (child_minimum_baseline >= 0)
|
||||
{
|
||||
have_baseline = TRUE;
|
||||
computed_minimum_below = MAX (computed_minimum_below, child_minimum - child_minimum_baseline);
|
||||
computed_natural_below = MAX (computed_natural_below, child_natural - child_natural_baseline);
|
||||
computed_minimum_above = MAX (computed_minimum_above, child_minimum_baseline);
|
||||
computed_natural_above = MAX (computed_natural_above, child_natural_baseline);
|
||||
if (child_minimum_baseline >= 0)
|
||||
{
|
||||
have_baseline = TRUE;
|
||||
computed_minimum_below = MAX (computed_minimum_below, child_minimum - child_minimum_baseline);
|
||||
computed_natural_below = MAX (computed_natural_below, child_natural - child_natural_baseline);
|
||||
computed_minimum_above = MAX (computed_minimum_above, child_minimum_baseline);
|
||||
computed_natural_above = MAX (computed_natural_above, child_natural_baseline);
|
||||
}
|
||||
else
|
||||
{
|
||||
computed_minimum = MAX (computed_minimum, child_minimum);
|
||||
computed_natural = MAX (computed_natural, child_natural);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
computed_minimum = MAX (computed_minimum, child_minimum);
|
||||
computed_natural = MAX (computed_natural, child_natural);
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
|
||||
if (have_baseline)
|
||||
@@ -437,9 +582,18 @@ gtk_box_layout_measure (GtkLayoutManager *layout_manager,
|
||||
|
||||
if (self->orientation != orientation)
|
||||
{
|
||||
gtk_box_layout_compute_opposite_size (self, widget, for_size,
|
||||
minimum, natural,
|
||||
min_baseline, nat_baseline);
|
||||
if (for_size < 0)
|
||||
{
|
||||
gtk_box_layout_compute_opposite_size (self, widget,
|
||||
minimum, natural,
|
||||
min_baseline, nat_baseline);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_box_layout_compute_opposite_size_for_size (self, widget, for_size,
|
||||
minimum, natural,
|
||||
min_baseline, nat_baseline);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
+1
-1
@@ -2816,7 +2816,7 @@ _gtk_builder_get_template_type (GtkBuilder *builder)
|
||||
* Creates a closure to invoke the function called @function_name.
|
||||
*
|
||||
* This is using the create_closure() implementation of @builder's
|
||||
* [class@Gtk.BuilderScope].
|
||||
* [iface@Gtk.BuilderScope].
|
||||
*
|
||||
* If no closure could be created, %NULL will be returned and @error
|
||||
* will be set.
|
||||
|
||||
+335
-151
@@ -27,100 +27,228 @@
|
||||
|
||||
typedef enum
|
||||
{
|
||||
RECORD_TYPE_ELEMENT,
|
||||
RECORD_TYPE_END_ELEMENT,
|
||||
RECORD_TYPE_TEXT,
|
||||
} RecordTreeType;
|
||||
RECORD_TYPE_ELEMENT,
|
||||
RECORD_TYPE_END_ELEMENT,
|
||||
RECORD_TYPE_TEXT,
|
||||
} RecordDataType;
|
||||
|
||||
typedef struct RecordDataTree RecordDataTree;
|
||||
/* All strings are owned by the string chunk */
|
||||
typedef struct {
|
||||
/* Must be first for g_slice_free_chain() */
|
||||
GList link;
|
||||
|
||||
/* All strings are owned by the string table */
|
||||
struct RecordDataTree {
|
||||
RecordDataTree *parent;
|
||||
RecordTreeType type;
|
||||
const char *string;
|
||||
int len;
|
||||
int count;
|
||||
int offset;
|
||||
int text_offset;
|
||||
gboolean include_len;
|
||||
} RecordDataString;
|
||||
|
||||
typedef struct {
|
||||
RecordDataType type;
|
||||
GList link;
|
||||
} RecordDataNode;
|
||||
|
||||
typedef struct RecordDataElement RecordDataElement;
|
||||
|
||||
struct RecordDataElement {
|
||||
RecordDataNode base;
|
||||
|
||||
RecordDataElement *parent;
|
||||
GQueue children;
|
||||
int n_attributes;
|
||||
const char *data;
|
||||
const char **attributes;
|
||||
const char **values;
|
||||
GList *children;
|
||||
gboolean preserve_whitespace;
|
||||
RecordDataString *name;
|
||||
RecordDataString *attributes[];
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
char *string;
|
||||
int count;
|
||||
int offset;
|
||||
} RecordDataString;
|
||||
RecordDataNode base;
|
||||
|
||||
static RecordDataTree *
|
||||
record_data_tree_new (RecordDataTree *parent,
|
||||
RecordTreeType type,
|
||||
const char *data)
|
||||
{
|
||||
RecordDataTree *tree = g_slice_new0 (RecordDataTree);
|
||||
|
||||
tree->parent = parent;
|
||||
tree->type = type;
|
||||
tree->data = data;
|
||||
|
||||
if (parent)
|
||||
parent->children = g_list_prepend (parent->children, tree);
|
||||
|
||||
return tree;
|
||||
}
|
||||
|
||||
static void
|
||||
record_data_tree_free (RecordDataTree *tree)
|
||||
{
|
||||
g_list_free_full (tree->children, (GDestroyNotify)record_data_tree_free);
|
||||
g_free (tree->attributes);
|
||||
g_free (tree->values);
|
||||
g_slice_free (RecordDataTree, tree);
|
||||
}
|
||||
|
||||
static void
|
||||
record_data_string_free (RecordDataString *s)
|
||||
{
|
||||
g_free (s->string);
|
||||
g_slice_free (RecordDataString, s);
|
||||
}
|
||||
|
||||
static const char *
|
||||
record_data_string_lookup (GHashTable *strings,
|
||||
const char *str,
|
||||
gssize len)
|
||||
{
|
||||
char *copy = NULL;
|
||||
RecordDataString *s;
|
||||
|
||||
if (len >= 0)
|
||||
{
|
||||
/* Ensure str is zero terminated */
|
||||
copy = g_strndup (str, len);
|
||||
str = copy;
|
||||
}
|
||||
|
||||
s = g_hash_table_lookup (strings, str);
|
||||
if (s)
|
||||
{
|
||||
g_free (copy);
|
||||
s->count++;
|
||||
return s->string;
|
||||
}
|
||||
|
||||
s = g_slice_new (RecordDataString);
|
||||
s->string = copy ? copy : g_strdup (str);
|
||||
s->count = 1;
|
||||
|
||||
g_hash_table_insert (strings, s->string, s);
|
||||
return s->string;
|
||||
}
|
||||
RecordDataString *string;
|
||||
} RecordDataText;
|
||||
|
||||
typedef struct {
|
||||
GHashTable *strings;
|
||||
RecordDataTree *root;
|
||||
RecordDataTree *current;
|
||||
GStringChunk *chunks;
|
||||
GQueue string_list;
|
||||
RecordDataElement *root;
|
||||
RecordDataElement *current;
|
||||
} RecordData;
|
||||
|
||||
static gpointer
|
||||
record_data_node_new (RecordDataElement *parent,
|
||||
RecordDataType type,
|
||||
gsize size)
|
||||
{
|
||||
RecordDataNode *node = g_slice_alloc0 (size);
|
||||
|
||||
node->type = type;
|
||||
node->link.data = node;
|
||||
|
||||
if (parent)
|
||||
g_queue_push_tail_link (&parent->children, &node->link);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
text_is_important (const char *name)
|
||||
{
|
||||
const char *elements[] = {
|
||||
"property",
|
||||
"attribute",
|
||||
"col",
|
||||
"action-widget",
|
||||
"item",
|
||||
"mime-type",
|
||||
"pattern",
|
||||
"suffix",
|
||||
"mark",
|
||||
NULL
|
||||
};
|
||||
|
||||
return g_strv_contains (elements, name);
|
||||
}
|
||||
|
||||
static RecordDataElement *
|
||||
record_data_element_new (RecordDataElement *parent,
|
||||
RecordDataString *name,
|
||||
gsize n_attributes)
|
||||
{
|
||||
RecordDataElement *element;
|
||||
|
||||
element = record_data_node_new (parent,
|
||||
RECORD_TYPE_ELEMENT,
|
||||
sizeof (RecordDataElement) +
|
||||
sizeof (RecordDataString) * n_attributes);
|
||||
element->parent = parent;
|
||||
element->name = name;
|
||||
element->preserve_whitespace = name && text_is_important (name->string);
|
||||
element->n_attributes = n_attributes;
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
static void
|
||||
record_data_element_append_text (RecordDataElement *parent,
|
||||
RecordDataString *string)
|
||||
{
|
||||
RecordDataText *text;
|
||||
|
||||
text = record_data_node_new (parent,
|
||||
RECORD_TYPE_TEXT,
|
||||
sizeof (RecordDataText));
|
||||
text->string = string;
|
||||
}
|
||||
|
||||
static void
|
||||
record_data_node_free (RecordDataNode *node)
|
||||
{
|
||||
GList *l, *next;
|
||||
RecordDataText *text;
|
||||
RecordDataElement *element;
|
||||
|
||||
switch (node->type)
|
||||
{
|
||||
case RECORD_TYPE_ELEMENT:
|
||||
element = (RecordDataElement *)node;
|
||||
|
||||
l = element->children.head;
|
||||
while (l)
|
||||
{
|
||||
next = l->next;
|
||||
record_data_node_free (l->data);
|
||||
l = next;
|
||||
}
|
||||
|
||||
g_slice_free1 (sizeof (RecordDataElement) +
|
||||
sizeof (RecordDataString) * element->n_attributes, element);
|
||||
break;
|
||||
case RECORD_TYPE_TEXT:
|
||||
text = (RecordDataText *)node;
|
||||
g_slice_free (RecordDataText, text);
|
||||
break;
|
||||
case RECORD_TYPE_END_ELEMENT:
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
record_data_string_equal (gconstpointer _a,
|
||||
gconstpointer _b)
|
||||
{
|
||||
const RecordDataString *a = _a;
|
||||
const RecordDataString *b = _b;
|
||||
|
||||
return a->len == b->len &&
|
||||
memcmp (a->string, b->string, a->len) == 0;
|
||||
}
|
||||
|
||||
/* Copied from g_bytes_hash() */
|
||||
static guint
|
||||
record_data_string_hash (gconstpointer _a)
|
||||
{
|
||||
const RecordDataString *a = _a;
|
||||
const signed char *p, *e;
|
||||
guint32 h = 5381;
|
||||
|
||||
for (p = (signed char *)a->string, e = (signed char *)a->string + a->len; p != e; p++)
|
||||
h = (h << 5) + h + *p;
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
static int
|
||||
record_data_string_compare (gconstpointer _a,
|
||||
gconstpointer _b,
|
||||
gpointer user_data)
|
||||
{
|
||||
const RecordDataString *a = _a;
|
||||
const RecordDataString *b = _b;
|
||||
|
||||
return b->count - a->count;
|
||||
}
|
||||
|
||||
static RecordDataString *
|
||||
record_data_string_lookup (RecordData *data,
|
||||
const char *str,
|
||||
gssize len)
|
||||
{
|
||||
RecordDataString *s, tmp;
|
||||
gboolean include_len = len >= 0;
|
||||
|
||||
if (len < 0)
|
||||
len = strlen (str);
|
||||
|
||||
tmp.string = str;
|
||||
tmp.len = len;
|
||||
|
||||
s = g_hash_table_lookup (data->strings, &tmp);
|
||||
if (s)
|
||||
{
|
||||
s->count++;
|
||||
s->include_len |= include_len;
|
||||
return s;
|
||||
}
|
||||
|
||||
s = g_slice_new (RecordDataString);
|
||||
/* The string is zero terminated */
|
||||
s->string = g_string_chunk_insert_len (data->chunks, str, len);
|
||||
s->len = len;
|
||||
s->count = 1;
|
||||
s->include_len = include_len;
|
||||
s->link.data = s;
|
||||
s->link.next = NULL;
|
||||
s->link.prev = NULL;
|
||||
|
||||
g_hash_table_add (data->strings, s);
|
||||
g_queue_push_tail_link (&data->string_list, &s->link);
|
||||
return s;
|
||||
}
|
||||
|
||||
static void
|
||||
record_start_element (GMarkupParseContext *context,
|
||||
const char *element_name,
|
||||
@@ -131,21 +259,20 @@ record_start_element (GMarkupParseContext *context,
|
||||
{
|
||||
gsize n_attrs = g_strv_length ((char **)names);
|
||||
RecordData *data = user_data;
|
||||
RecordDataTree *child;
|
||||
RecordDataElement *child;
|
||||
RecordDataString *name, **attr_names, **attr_values;
|
||||
int i;
|
||||
|
||||
child = record_data_tree_new (data->current, RECORD_TYPE_ELEMENT,
|
||||
record_data_string_lookup (data->strings, element_name, -1));
|
||||
name = record_data_string_lookup (data, element_name, -1);
|
||||
child = record_data_element_new (data->current, name, n_attrs);
|
||||
data->current = child;
|
||||
|
||||
child->n_attributes = n_attrs;
|
||||
child->attributes = g_new (const char *, n_attrs);
|
||||
child->values = g_new (const char *, n_attrs);
|
||||
|
||||
attr_names = &child->attributes[0];
|
||||
attr_values = &child->attributes[n_attrs];
|
||||
for (i = 0; i < n_attrs; i++)
|
||||
{
|
||||
child->attributes[i] = record_data_string_lookup (data->strings, names[i], -1);
|
||||
child->values[i] = record_data_string_lookup (data->strings, values[i], -1);
|
||||
attr_names[i] = record_data_string_lookup (data, names[i], -1);
|
||||
attr_values[i] = record_data_string_lookup (data, values[i], -1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -160,6 +287,23 @@ record_end_element (GMarkupParseContext *context,
|
||||
data->current = data->current->parent;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_whitespace (const char *text,
|
||||
gsize text_len)
|
||||
{
|
||||
const char *end;
|
||||
const char *p;
|
||||
|
||||
end = text + text_len;
|
||||
for (p = text; p < end; p = g_utf8_next_char (p))
|
||||
{
|
||||
if (!g_unichar_isspace (g_utf8_get_char (p)))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
record_text (GMarkupParseContext *context,
|
||||
const char *text,
|
||||
@@ -168,9 +312,16 @@ record_text (GMarkupParseContext *context,
|
||||
GError **error)
|
||||
{
|
||||
RecordData *data = user_data;
|
||||
RecordDataString *string;
|
||||
|
||||
record_data_tree_new (data->current, RECORD_TYPE_TEXT,
|
||||
record_data_string_lookup (data->strings, text, text_len));
|
||||
if (text_len == 0)
|
||||
return;
|
||||
|
||||
if (!data->current->preserve_whitespace && is_whitespace (text, text_len))
|
||||
return;
|
||||
|
||||
string = record_data_string_lookup (data, text, text_len);
|
||||
record_data_element_append_text (data->current, string);
|
||||
}
|
||||
|
||||
static const GMarkupParser record_parser =
|
||||
@@ -182,16 +333,6 @@ static const GMarkupParser record_parser =
|
||||
NULL, // error, fails immediately
|
||||
};
|
||||
|
||||
static int
|
||||
compare_string (gconstpointer _a,
|
||||
gconstpointer _b)
|
||||
{
|
||||
const RecordDataString *a = _a;
|
||||
const RecordDataString *b = _b;
|
||||
|
||||
return b->count - a->count;
|
||||
}
|
||||
|
||||
static void
|
||||
marshal_uint32 (GString *str,
|
||||
guint32 v)
|
||||
@@ -240,54 +381,60 @@ marshal_uint32 (GString *str,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
marshal_string (GString *marshaled,
|
||||
GHashTable *strings,
|
||||
const char *string)
|
||||
static int
|
||||
marshal_uint32_len (guint32 v)
|
||||
{
|
||||
RecordDataString *s;
|
||||
if (v < 128)
|
||||
return 1;
|
||||
|
||||
s = g_hash_table_lookup (strings, string);
|
||||
g_assert (s != NULL);
|
||||
if (v < (1<<14))
|
||||
return 2;
|
||||
|
||||
marshal_uint32 (marshaled, s->offset);
|
||||
if (v < (1<<21))
|
||||
return 3;
|
||||
|
||||
if (v < (1<<28))
|
||||
return 4;
|
||||
|
||||
return 5;
|
||||
}
|
||||
|
||||
static void
|
||||
marshal_tree (GString *marshaled,
|
||||
GHashTable *strings,
|
||||
RecordDataTree *tree)
|
||||
RecordDataNode *node)
|
||||
{
|
||||
GList *l;
|
||||
int i;
|
||||
RecordDataText *text;
|
||||
RecordDataElement *element;
|
||||
RecordDataString **attr_names, **attr_values;
|
||||
|
||||
/* Special case the root */
|
||||
if (tree->parent == NULL)
|
||||
{
|
||||
for (l = g_list_last (tree->children); l != NULL; l = l->prev)
|
||||
marshal_tree (marshaled, strings, l->data);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (tree->type)
|
||||
switch (node->type)
|
||||
{
|
||||
case RECORD_TYPE_ELEMENT:
|
||||
element = (RecordDataElement *)node;
|
||||
|
||||
marshal_uint32 (marshaled, RECORD_TYPE_ELEMENT);
|
||||
marshal_string (marshaled, strings, tree->data);
|
||||
marshal_uint32 (marshaled, tree->n_attributes);
|
||||
for (i = 0; i < tree->n_attributes; i++)
|
||||
marshal_uint32 (marshaled, element->name->offset);
|
||||
marshal_uint32 (marshaled, element->n_attributes);
|
||||
|
||||
attr_names = &element->attributes[0];
|
||||
attr_values = &element->attributes[element->n_attributes];
|
||||
for (i = 0; i < element->n_attributes; i++)
|
||||
{
|
||||
marshal_string (marshaled, strings, tree->attributes[i]);
|
||||
marshal_string (marshaled, strings, tree->values[i]);
|
||||
marshal_uint32 (marshaled, attr_names[i]->offset);
|
||||
marshal_uint32 (marshaled, attr_values[i]->offset);
|
||||
}
|
||||
for (l = g_list_last (tree->children); l != NULL; l = l->prev)
|
||||
marshal_tree (marshaled, strings, l->data);
|
||||
|
||||
for (l = element->children.head; l != NULL; l = l->next)
|
||||
marshal_tree (marshaled, l->data);
|
||||
|
||||
marshal_uint32 (marshaled, RECORD_TYPE_END_ELEMENT);
|
||||
break;
|
||||
case RECORD_TYPE_TEXT:
|
||||
text = (RecordDataText *)node;
|
||||
marshal_uint32 (marshaled, RECORD_TYPE_TEXT);
|
||||
marshal_string (marshaled, strings, tree->data);
|
||||
marshal_uint32 (marshaled, text->string->text_offset);
|
||||
break;
|
||||
case RECORD_TYPE_END_ELEMENT:
|
||||
default:
|
||||
@@ -295,6 +442,17 @@ marshal_tree (GString *marshaled,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
marshal_root (GString *marshaled,
|
||||
RecordDataNode *node)
|
||||
{
|
||||
GList *l;
|
||||
RecordDataElement *element = (RecordDataElement *)node;
|
||||
|
||||
for (l = element->children.head; l != NULL; l = l->next)
|
||||
marshal_tree (marshaled, l->data);
|
||||
}
|
||||
|
||||
/**
|
||||
* _gtk_buildable_parser_precompile:
|
||||
* @text: chunk of text to parse
|
||||
@@ -313,20 +471,22 @@ _gtk_buildable_parser_precompile (const char *text,
|
||||
{
|
||||
GMarkupParseContext *ctx;
|
||||
RecordData data = { 0 };
|
||||
GList *string_table, *l;
|
||||
GList *l;
|
||||
GString *marshaled;
|
||||
int offset;
|
||||
|
||||
data.strings = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify)record_data_string_free);
|
||||
data.root = record_data_tree_new (NULL, RECORD_TYPE_ELEMENT, NULL);
|
||||
data.strings = g_hash_table_new (record_data_string_hash, record_data_string_equal);
|
||||
data.chunks = g_string_chunk_new (512);
|
||||
data.root = record_data_element_new (NULL, NULL, 0);
|
||||
data.current = data.root;
|
||||
|
||||
ctx = g_markup_parse_context_new (&record_parser, G_MARKUP_TREAT_CDATA_AS_TEXT,
|
||||
&data, NULL);
|
||||
ctx = g_markup_parse_context_new (&record_parser, G_MARKUP_TREAT_CDATA_AS_TEXT, &data, NULL);
|
||||
|
||||
if (!g_markup_parse_context_parse (ctx, text, text_len, error))
|
||||
if (!g_markup_parse_context_parse (ctx, text, text_len, error) ||
|
||||
!g_markup_parse_context_end_parse (ctx, error))
|
||||
{
|
||||
record_data_tree_free (data.root);
|
||||
record_data_node_free (&data.root->base);
|
||||
g_string_chunk_free (data.chunks);
|
||||
g_hash_table_destroy (data.strings);
|
||||
g_markup_parse_context_free (ctx);
|
||||
return NULL;
|
||||
@@ -334,34 +494,45 @@ _gtk_buildable_parser_precompile (const char *text,
|
||||
|
||||
g_markup_parse_context_free (ctx);
|
||||
|
||||
string_table = g_hash_table_get_values (data.strings);
|
||||
|
||||
string_table = g_list_sort (string_table, compare_string);
|
||||
g_queue_sort (&data.string_list, record_data_string_compare, NULL);
|
||||
|
||||
offset = 0;
|
||||
for (l = string_table; l != NULL; l = l->next)
|
||||
for (l = data.string_list.head; l != NULL; l = l->next)
|
||||
{
|
||||
RecordDataString *s = l->data;
|
||||
|
||||
if (s->include_len)
|
||||
{
|
||||
s->text_offset = offset;
|
||||
offset += marshal_uint32_len (s->len);
|
||||
}
|
||||
|
||||
s->offset = offset;
|
||||
offset += strlen (s->string) + 1;
|
||||
offset += s->len + 1;
|
||||
}
|
||||
|
||||
marshaled = g_string_new ("");
|
||||
marshaled = g_string_sized_new (4 + offset + 32);
|
||||
/* Magic marker */
|
||||
g_string_append_len (marshaled, "GBU\0", 4);
|
||||
marshal_uint32 (marshaled, offset);
|
||||
|
||||
for (l = string_table; l != NULL; l = l->next)
|
||||
for (l = data.string_list.head; l != NULL; l = l->next)
|
||||
{
|
||||
RecordDataString *s = l->data;
|
||||
g_string_append_len (marshaled, s->string, strlen (s->string) + 1);
|
||||
|
||||
if (s->include_len)
|
||||
marshal_uint32 (marshaled, s->len);
|
||||
|
||||
g_string_append_len (marshaled, s->string, s->len + 1);
|
||||
}
|
||||
|
||||
g_list_free (string_table);
|
||||
marshal_root (marshaled, &data.root->base);
|
||||
|
||||
marshal_tree (marshaled, data.strings, data.root);
|
||||
|
||||
record_data_tree_free (data.root);
|
||||
g_slice_free_chain (RecordDataString,
|
||||
(RecordDataString *)data.string_list.head,
|
||||
link.next);
|
||||
record_data_node_free (&data.root->base);
|
||||
g_string_chunk_free (data.chunks);
|
||||
g_hash_table_destroy (data.strings);
|
||||
|
||||
return g_string_free_to_bytes (marshaled);
|
||||
@@ -412,6 +583,18 @@ demarshal_string (const char **tree,
|
||||
return strings + offset;
|
||||
}
|
||||
|
||||
static const char *
|
||||
demarshal_text (const char **tree,
|
||||
const char *strings,
|
||||
guint32 *len)
|
||||
{
|
||||
guint32 offset = demarshal_uint32 (tree);
|
||||
const char *str = strings + offset;
|
||||
|
||||
*len = demarshal_uint32 (&str);
|
||||
return str;
|
||||
}
|
||||
|
||||
static void
|
||||
propagate_error (GtkBuildableParseContext *context,
|
||||
GError **dest,
|
||||
@@ -489,14 +672,15 @@ replay_text (GtkBuildableParseContext *context,
|
||||
const char *strings,
|
||||
GError **error)
|
||||
{
|
||||
guint32 len;
|
||||
const char *text;
|
||||
GError *tmp_error = NULL;
|
||||
|
||||
text = demarshal_string (tree, strings);
|
||||
text = demarshal_text (tree, strings, &len);
|
||||
|
||||
(*context->internal_callbacks->text) (NULL,
|
||||
text,
|
||||
strlen (text),
|
||||
len,
|
||||
context,
|
||||
&tmp_error);
|
||||
|
||||
|
||||
+8
-8
@@ -24,7 +24,7 @@
|
||||
*
|
||||
* An abstract class for laying out `GtkCellRenderer`s
|
||||
*
|
||||
* The `GtkCellArea` is an abstract class for [class@Gtk.CellLayout]
|
||||
* The `GtkCellArea` is an abstract class for [iface@Gtk.CellLayout]
|
||||
* widgets (also referred to as "layouting widgets") to interface with
|
||||
* an arbitrary number of [class@Gtk.CellRenderer]s and interact with the user
|
||||
* for a given [iface@Gtk.TreeModel] row.
|
||||
@@ -979,7 +979,7 @@ gtk_cell_area_real_add (GtkCellArea *area,
|
||||
g_type_name (G_TYPE_FROM_INSTANCE (area)));
|
||||
}
|
||||
|
||||
static void
|
||||
static void
|
||||
gtk_cell_area_real_remove (GtkCellArea *area,
|
||||
GtkCellRenderer *renderer)
|
||||
{
|
||||
@@ -1727,8 +1727,8 @@ gtk_cell_area_foreach_alloc (GtkCellArea *area,
|
||||
g_return_if_fail (cell_area != NULL);
|
||||
g_return_if_fail (callback != NULL);
|
||||
|
||||
GTK_CELL_AREA_GET_CLASS (area)->foreach_alloc (area, context, widget,
|
||||
cell_area, background_area,
|
||||
GTK_CELL_AREA_GET_CLASS (area)->foreach_alloc (area, context, widget,
|
||||
cell_area, background_area,
|
||||
callback, callback_data);
|
||||
}
|
||||
|
||||
@@ -2018,7 +2018,7 @@ gtk_cell_area_get_preferred_width (GtkCellArea *area,
|
||||
g_return_if_fail (GTK_IS_CELL_AREA (area));
|
||||
g_return_if_fail (GTK_IS_WIDGET (widget));
|
||||
|
||||
GTK_CELL_AREA_GET_CLASS (area)->get_preferred_width (area, context, widget,
|
||||
GTK_CELL_AREA_GET_CLASS (area)->get_preferred_width (area, context, widget,
|
||||
minimum_width, natural_width);
|
||||
}
|
||||
|
||||
@@ -2090,7 +2090,7 @@ gtk_cell_area_get_preferred_height (GtkCellArea *area,
|
||||
g_return_if_fail (GTK_IS_CELL_AREA (area));
|
||||
g_return_if_fail (GTK_IS_WIDGET (widget));
|
||||
|
||||
GTK_CELL_AREA_GET_CLASS (area)->get_preferred_height (area, context, widget,
|
||||
GTK_CELL_AREA_GET_CLASS (area)->get_preferred_height (area, context, widget,
|
||||
minimum_height, natural_height);
|
||||
}
|
||||
|
||||
@@ -3369,7 +3369,7 @@ gtk_cell_area_stop_editing (GtkCellArea *area,
|
||||
gtk_cell_renderer_stop_editing (priv->edited_cell, canceled);
|
||||
|
||||
/* When editing is explicitly halted either
|
||||
* the "editing-canceled" signal is emitted on the cell
|
||||
* the "editing-canceled" signal is emitted on the cell
|
||||
* renderer or the "editing-done" signal on the GtkCellEditable widget
|
||||
*/
|
||||
if (!canceled)
|
||||
@@ -3527,7 +3527,7 @@ _gtk_cell_area_set_cell_data_func_with_proxy (GtkCellArea *area,
|
||||
|
||||
/* Note we do not take a reference to the proxy, the proxy is a GtkCellLayout
|
||||
* that is forwarding its implementation to a delegate GtkCellArea therefore
|
||||
* its life-cycle is longer than the area's life cycle.
|
||||
* its life-cycle is longer than the area's life cycle.
|
||||
*/
|
||||
if (info)
|
||||
{
|
||||
|
||||
@@ -37,10 +37,7 @@ typedef struct _GtkCellRendererAccel GtkCellRendererAccel;
|
||||
* @GTK_CELL_RENDERER_ACCEL_MODE_GTK: GTK accelerators mode
|
||||
* @GTK_CELL_RENDERER_ACCEL_MODE_OTHER: Other accelerator mode
|
||||
*
|
||||
* Determines if the edited accelerators are GTK accelerators. If
|
||||
* they are, consumed modifiers are suppressed, only accelerators
|
||||
* accepted by GTK are allowed, and the accelerators are rendered
|
||||
* in the same way as they are in menus.
|
||||
* The available modes for [property@Gtk.CellRendererAccel:accel-mode].
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
|
||||
@@ -296,6 +296,7 @@ gtk_color_button_init (GtkColorButton *button)
|
||||
"accessible-role", GTK_ACCESSIBLE_ROLE_IMG,
|
||||
"selectable", FALSE,
|
||||
"has-menu", FALSE,
|
||||
"can-drag", FALSE,
|
||||
NULL);
|
||||
gtk_widget_set_can_focus (button->swatch, FALSE);
|
||||
gtk_widget_remove_css_class (button->swatch, "activatable");
|
||||
|
||||
+42
-13
@@ -65,6 +65,7 @@ struct _GtkColorSwatch
|
||||
|
||||
GtkWidget *popover;
|
||||
GtkDropTarget *dest;
|
||||
GtkDragSource *source;
|
||||
};
|
||||
|
||||
struct _GtkColorSwatchClass
|
||||
@@ -81,7 +82,8 @@ enum
|
||||
PROP_RGBA,
|
||||
PROP_SELECTABLE,
|
||||
PROP_HAS_MENU,
|
||||
PROP_CAN_DROP
|
||||
PROP_CAN_DROP,
|
||||
PROP_CAN_DRAG
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (GtkColorSwatch, gtk_color_swatch, GTK_TYPE_WIDGET)
|
||||
@@ -429,6 +431,9 @@ swatch_get_property (GObject *object,
|
||||
case PROP_CAN_DROP:
|
||||
g_value_set_boolean (value, swatch->dest != NULL);
|
||||
break;
|
||||
case PROP_CAN_DRAG:
|
||||
g_value_set_boolean (value, swatch->source != NULL);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
@@ -457,6 +462,9 @@ swatch_set_property (GObject *object,
|
||||
case PROP_CAN_DROP:
|
||||
gtk_color_swatch_set_can_drop (swatch, g_value_get_boolean (value));
|
||||
break;
|
||||
case PROP_CAN_DRAG:
|
||||
gtk_color_swatch_set_can_drag (swatch, g_value_get_boolean (value));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
@@ -470,7 +478,7 @@ swatch_finalize (GObject *object)
|
||||
|
||||
g_free (swatch->icon);
|
||||
gtk_widget_unparent (swatch->overlay_widget);
|
||||
|
||||
|
||||
G_OBJECT_CLASS (gtk_color_swatch_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
@@ -512,11 +520,14 @@ gtk_color_swatch_class_init (GtkColorSwatchClass *class)
|
||||
g_object_class_install_property (object_class, PROP_CAN_DROP,
|
||||
g_param_spec_boolean ("can-drop", P_("Can Drop"), P_("Whether the swatch should accept drops"),
|
||||
FALSE, GTK_PARAM_READWRITE));
|
||||
g_object_class_install_property (object_class, PROP_CAN_DRAG,
|
||||
g_param_spec_boolean ("can-drag", P_("Can Drag"), P_("Whether the swatch should allow drags"),
|
||||
TRUE, GTK_PARAM_READWRITE));
|
||||
|
||||
/**
|
||||
* GtkColorSwatch|menu.popup:
|
||||
*
|
||||
* Opens the context menu.
|
||||
* Opens the context menu.
|
||||
*/
|
||||
gtk_widget_class_install_action (widget_class, "menu.popup", NULL, swatch_popup_menu);
|
||||
|
||||
@@ -568,6 +579,8 @@ gtk_color_swatch_init (GtkColorSwatch *swatch)
|
||||
G_CALLBACK (key_controller_key_pressed), swatch);
|
||||
gtk_widget_add_controller (GTK_WIDGET (swatch), controller);
|
||||
|
||||
gtk_color_swatch_set_can_drag (swatch, TRUE);
|
||||
|
||||
gtk_widget_add_css_class (GTK_WIDGET (swatch), "activatable");
|
||||
|
||||
swatch->overlay_widget = g_object_new (GTK_TYPE_IMAGE,
|
||||
@@ -598,18 +611,10 @@ void
|
||||
gtk_color_swatch_set_rgba (GtkColorSwatch *swatch,
|
||||
const GdkRGBA *color)
|
||||
{
|
||||
if (!swatch->has_color)
|
||||
{
|
||||
GtkDragSource *source;
|
||||
|
||||
source = gtk_drag_source_new ();
|
||||
g_signal_connect (source, "prepare", G_CALLBACK (gtk_color_swatch_drag_prepare), swatch);
|
||||
|
||||
gtk_widget_add_controller (GTK_WIDGET (swatch), GTK_EVENT_CONTROLLER (source));
|
||||
}
|
||||
|
||||
swatch->has_color = TRUE;
|
||||
swatch->color = *color;
|
||||
if (swatch->source)
|
||||
gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (swatch->source), GTK_PHASE_CAPTURE);
|
||||
|
||||
if (INTENSITY (swatch->color.red, swatch->color.green, swatch->color.blue) > 0.5)
|
||||
{
|
||||
@@ -681,6 +686,30 @@ gtk_color_swatch_set_can_drop (GtkColorSwatch *swatch,
|
||||
g_object_notify (G_OBJECT (swatch), "can-drop");
|
||||
}
|
||||
|
||||
void
|
||||
gtk_color_swatch_set_can_drag (GtkColorSwatch *swatch,
|
||||
gboolean can_drag)
|
||||
{
|
||||
if (can_drag == (swatch->source != NULL))
|
||||
return;
|
||||
|
||||
if (can_drag && !swatch->source)
|
||||
{
|
||||
swatch->source = gtk_drag_source_new ();
|
||||
g_signal_connect (swatch->source, "prepare", G_CALLBACK (gtk_color_swatch_drag_prepare), swatch);
|
||||
gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (swatch->source),
|
||||
swatch->has_color ? GTK_PHASE_CAPTURE : GTK_PHASE_NONE);
|
||||
gtk_widget_add_controller (GTK_WIDGET (swatch), GTK_EVENT_CONTROLLER (swatch->source));
|
||||
}
|
||||
if (!can_drag && swatch->source)
|
||||
{
|
||||
gtk_widget_remove_controller (GTK_WIDGET (swatch), GTK_EVENT_CONTROLLER (swatch->source));
|
||||
swatch->source = NULL;
|
||||
}
|
||||
|
||||
g_object_notify (G_OBJECT (swatch), "can-drag");
|
||||
}
|
||||
|
||||
void
|
||||
gtk_color_swatch_set_use_alpha (GtkColorSwatch *swatch,
|
||||
gboolean use_alpha)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user