Compare commits
435 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| eccbd4fe5f | |||
| 3b967f1242 | |||
| 1a4c988a22 | |||
| d936a9ae89 | |||
| 67e6d1087e | |||
| 29bafd1e15 | |||
| 65697e3324 | |||
| bceca277ea | |||
| 16c8fb52df | |||
| d702bfe7b7 | |||
| 596c9a3c0b | |||
| c675d1c9e1 | |||
| bd490ed511 | |||
| bcf180642d | |||
| 5882e22f89 | |||
| 6f25168db3 | |||
| 2a4b5862ae | |||
| 7037ff8f3d | |||
| 1c9a486d60 | |||
| eb9284e9ca | |||
| 77e3b72b15 | |||
| 05cb7e7412 | |||
| 299422994a | |||
| b1d90cc171 | |||
| af2207bc0b | |||
| 522bbc182d | |||
| 65233726f8 | |||
| 19227d9789 | |||
| 8915d60900 | |||
| ed52c029a0 | |||
| 7b1201cd4d | |||
| 3f940715e4 | |||
| f6225901e8 | |||
| eff4b6377d | |||
| a18647af0e | |||
| c7df0c907a | |||
| b74407a343 | |||
| cd5c39834d | |||
| 574a25b09c | |||
| 6e0b13b81f | |||
| bea8025fb5 | |||
| 965d0e04d1 | |||
| d7c54920ee | |||
| 33a8108f19 | |||
| 78d254370c | |||
| 377ec33069 | |||
| 2952ba07e1 | |||
| 62b7ea7611 | |||
| c9eca55c5e | |||
| 435bc269e9 | |||
| 0d2a7f876b | |||
| 737400ddbc | |||
| 134e159bc9 | |||
| 6f0b47681b | |||
| d53981fdbb | |||
| e09beee62a | |||
| 724ec3ca92 | |||
| 3ce6a710a3 | |||
| e41596d6a1 | |||
| 0fa4d54316 | |||
| e7cbb7a76c | |||
| b2a23a9a90 | |||
| 6878c2bae0 | |||
| 5b8f1aa2ee | |||
| 6b4a82224c | |||
| 1f30b7742b | |||
| 54e7a94d70 | |||
| f1919c706f | |||
| 26b17473aa | |||
| 99eee5cea9 | |||
| 074a0014c1 | |||
| 091cac00b2 | |||
| 175e3d751d | |||
| 83e9361005 | |||
| 17bb1248b5 | |||
| 8211e79be9 | |||
| d5282862e5 | |||
| 26b6d18563 | |||
| 31fb5cc2d4 | |||
| 90301c6813 | |||
| ccdf50aafd | |||
| af5c80248d | |||
| 1d81a58cf1 | |||
| 09cec2e6a1 | |||
| efed2641f4 | |||
| 97a5ca74d2 | |||
| 5b5b215dea | |||
| 7a06859f38 | |||
| 24fa104b61 | |||
| 89861faa04 | |||
| 5fd94e2027 | |||
| 1f4d02740e | |||
| 0023b9036b | |||
| 89d1f8c3ca | |||
| 7d9364655d | |||
| 86d2fcef16 | |||
| 5f8543fe81 | |||
| aae7816557 | |||
| 6fbf13965c | |||
| 484e330e4a | |||
| f27ecde1e2 | |||
| c06d1a69ae | |||
| cf9deb7cf5 | |||
| 40beb69487 | |||
| f1cadee196 | |||
| f6594ff073 | |||
| 478fdaa632 | |||
| 6c472ed2b8 | |||
| 30942c4e3d | |||
| bf7d1e7b5a | |||
| 92e21c3f1c | |||
| 8880d27460 | |||
| 59d50be737 | |||
| 6d73443131 | |||
| fe3796ed5b | |||
| 89f7b974f2 | |||
| 0ae958d45b | |||
| 3d1fdf77dc | |||
| 0ae71cacb4 | |||
| 218d635ca2 | |||
| 7553d0c471 | |||
| f4880f5df5 | |||
| 3ccdad76de | |||
| e464c08545 | |||
| 56e95ddfc8 | |||
| 65052a5d6c | |||
| 1364eb2f62 | |||
| aa8ada3fed | |||
| 3643a9fe86 | |||
| 25f4bb2e17 | |||
| 3b62d9c027 | |||
| c92938b378 | |||
| c98313016e | |||
| e43839114d | |||
| b6c1786165 | |||
| 3a40555202 | |||
| ff604e1906 | |||
| 34974a8a66 | |||
| 7c15daf99e | |||
| b9467a4dc7 | |||
| 5a1c37a8c8 | |||
| b75bc8aa64 | |||
| ed4c08d9b3 | |||
| 929cdd9259 | |||
| 78049f452a | |||
| cf2ef4863b | |||
| 2bd348558e | |||
| 0f6d83bb5f | |||
| 7e20232607 | |||
| dcc55e3a73 | |||
| 59fd48cee0 | |||
| c848b9014b | |||
| 1e16cb088a | |||
| f4cf43359d | |||
| 6c8a5f5e2f | |||
| da64d687d1 | |||
| aab803b7ae | |||
| 936aba884a | |||
| e1200230c4 | |||
| d3ad816d63 | |||
| eea1388cf4 | |||
| f3747d1776 | |||
| 6277f2fccc | |||
| 931b0b3752 | |||
| 6f3e608331 | |||
| cc4b3798e5 | |||
| 8634a51aa5 | |||
| 7420f9c34a | |||
| 1a7c280ebb | |||
| 4bb6e70d01 | |||
| 2bd9b42479 | |||
| b8127670df | |||
| 3a1ef7aa2c | |||
| 8dd26b6b8a | |||
| 0526775ff4 | |||
| 1ad406e15d | |||
| 249f6a85b3 | |||
| 32edf29c0a | |||
| 4f7171885f | |||
| b1eedbeb58 | |||
| a98f857a82 | |||
| b9770fa752 | |||
| 52d4bcf1be | |||
| fe3b5ba545 | |||
| 33f034d0d7 | |||
| 2516f1142d | |||
| ec37e1e462 | |||
| 79180f62d7 | |||
| 5cd4ec510d | |||
| ea95aea246 | |||
| e13d242320 | |||
| c21063e71e | |||
| 477ad2505b | |||
| 91bbe6ef95 | |||
| 34fcfb154a | |||
| 28815bc7e4 | |||
| 8eaa8aaaf8 | |||
| 491829a2b5 | |||
| 28be1c5d3a | |||
| 65ff19d149 | |||
| 3da6e83609 | |||
| 2a7e4ae7f6 | |||
| cc878ec00f | |||
| 1f5649e1ce | |||
| ca19b940ce | |||
| 3f70d20bb3 | |||
| 304e06541e | |||
| c91371951a | |||
| 6e59c5c843 | |||
| f5a8b79cfb | |||
| c723893f09 | |||
| a247529bc8 | |||
| 51b2759eb1 | |||
| fed2db1493 | |||
| 77ff83cdd1 | |||
| 37fee8c52f | |||
| 08c84bc830 | |||
| 9b6f822f15 | |||
| 70fb29e81a | |||
| 0e26e95b00 | |||
| ba1c5cf43f | |||
| f3821031e0 | |||
| e37f4d0ea6 | |||
| b26087845d | |||
| 891b343197 | |||
| 8727b0708e | |||
| 1932a50d36 | |||
| 5a5da91785 | |||
| de2e0f451f | |||
| 8400d8e75d | |||
| 50eb11a2a0 | |||
| e8f898508a | |||
| 638a3c142c | |||
| ecdad20827 | |||
| 5cd8e0f7f1 | |||
| 83696639a7 | |||
| 1aa1610611 | |||
| 0c87b62251 | |||
| 69f12ed6a5 | |||
| a8db330341 | |||
| 2681f7c7af | |||
| 836b5a217a | |||
| 802c426d89 | |||
| 7c3eadf169 | |||
| 6c6fd13034 | |||
| 4ce217b1a5 | |||
| 2656f5b4eb | |||
| bc8ecef605 | |||
| 33eb72a69b | |||
| 21be06310c | |||
| 6e27e79c8b | |||
| e2d821fa59 | |||
| 8d001e3573 | |||
| f6afa3d03f | |||
| 3286221870 | |||
| f4e32f29e1 | |||
| 226e0eadf0 | |||
| 1f58e0ed6b | |||
| 1ee5c2cac4 | |||
| 97fb1c7757 | |||
| dff9a5a195 | |||
| b9fb2f0933 | |||
| 0791924bf7 | |||
| 90870194ff | |||
| c593f86ac6 | |||
| ad3ded7ba0 | |||
| 3f9b8f25d8 | |||
| 8ad38e5ae5 | |||
| 0cd2946676 | |||
| 5473d13470 | |||
| 31ccb7ca70 | |||
| dba1926a42 | |||
| b1b12a239f | |||
| 44ce36bef5 | |||
| 84d2150077 | |||
| 3f61360fa1 | |||
| 7fb9f21ee0 | |||
| d733078766 | |||
| cb6e48e22b | |||
| f39ae35e4b | |||
| daea92ea00 | |||
| b98c7214ef | |||
| 3412d18dc2 | |||
| 3bc8ab91a2 | |||
| f9d5869774 | |||
| 20ccb53c42 | |||
| f9a589c7fd | |||
| ddd044f283 | |||
| 3569348f9c | |||
| 9e8e3eb0ca | |||
| 87121998a2 | |||
| 68d6c51dbc | |||
| 4551aef081 | |||
| 0249bd4f8a | |||
| b11c69b4a8 | |||
| 84351ba9e5 | |||
| 9a1da43890 | |||
| c78ba42051 | |||
| e0730bc118 | |||
| 7d9a8a6ec0 | |||
| 07e0411b98 | |||
| b66e4cd64c | |||
| 254feda16b | |||
| c6471ee874 | |||
| 261b8c7ee6 | |||
| f58f0732c2 | |||
| c5a4a26f06 | |||
| faff08193a | |||
| 3046358d38 | |||
| e81f033ece | |||
| 5c608fe070 | |||
| a2db956492 | |||
| 8d51038cb1 | |||
| 86c86e0860 | |||
| 324f5472a2 | |||
| c20360dd98 | |||
| 1b6252ebf0 | |||
| b4c8ba4de7 | |||
| ad34f731e9 | |||
| 198207f1ff | |||
| 6120f11ed3 | |||
| 0a440a804f | |||
| 117fc68195 | |||
| f310609a66 | |||
| 8001c7d972 | |||
| 023b695422 | |||
| ec6ce0707a | |||
| f37573f8dc | |||
| 49f8b571b9 | |||
| e1cd996617 | |||
| 24cc721bc6 | |||
| d41580adfc | |||
| 3ab65b7da2 | |||
| 79238b0d8f | |||
| 2e0a56665a | |||
| 76826cfa2f | |||
| 37671d2bd0 | |||
| 04d24b7cd2 | |||
| 085d34cbb0 | |||
| 46143492a2 | |||
| a475d72d47 | |||
| a8f712b09a | |||
| 2fb202187c | |||
| 207c0b32b4 | |||
| 35f60dc918 | |||
| 1cd9396154 | |||
| de73ac980f | |||
| acaec5f186 | |||
| c8589a9a2f | |||
| a31e5f7a8c | |||
| e0a01ba174 | |||
| 98e076b51e | |||
| f3db19d694 | |||
| 607502ef43 | |||
| acddc317da | |||
| 7f99c1e588 | |||
| 5f3e5a0406 | |||
| 23080d47b5 | |||
| f0d2f99239 | |||
| e7b9ecc99a | |||
| dce8c11b07 | |||
| 7ccec19501 | |||
| 93b643c44d | |||
| 21616f6e2e | |||
| 8157004068 | |||
| 8d69bda27a | |||
| dbdb81f411 | |||
| 28fbcf6abe | |||
| 1fd339c46f | |||
| b830bdca37 | |||
| 45bc4ed321 | |||
| 3988847a05 | |||
| 9c862d7736 | |||
| d99ae4b6c2 | |||
| 96f9cbcabf | |||
| 3597f7e8b1 | |||
| 38227dc972 | |||
| aa50e92c65 | |||
| 753ad64cbc | |||
| 3fb44ae651 | |||
| 76fb80f46c | |||
| 684b6459f1 | |||
| 904a9d0c98 | |||
| 32e256e5ab | |||
| d4d46e8125 | |||
| 661720ef8b | |||
| 013591d68d | |||
| a938c14d11 | |||
| d6cc10ea74 | |||
| f25832455f | |||
| 42ea95c54e | |||
| 46e7b44ffa | |||
| a27737b04e | |||
| bd2d07e671 | |||
| fde21b57cd | |||
| 637bd13f3f | |||
| eadd90c22e | |||
| 279cb5717c | |||
| b91fbfd5a0 | |||
| 88086ea91a | |||
| 0842d084dd | |||
| 838b25177f | |||
| b39d0cec3c | |||
| f0c72bdc3b | |||
| 427d216081 | |||
| dc8b5f75a4 | |||
| b6f2969872 | |||
| 6eed78e3de | |||
| c4aa060118 | |||
| 0bf4c2420d | |||
| aac2556762 | |||
| f813bc1823 | |||
| ca233ad9ae | |||
| e6631a7b66 | |||
| fbe0e32813 | |||
| 2594593de2 | |||
| ef982b7d46 | |||
| 0432b850c5 | |||
| 1b362d1f01 | |||
| 7ce968f297 | |||
| 0e15b4a367 | |||
| de0942b0b8 | |||
| b804235aea | |||
| 6bc32a3d5d | |||
| 5e24454764 | |||
| d9cf0ff684 | |||
| 5b78a3048f | |||
| 676ac380cd | |||
| dce2c58799 | |||
| f3d1666394 | |||
| 8af0782261 | |||
| 7a45768efe | |||
| 3a56da60dd | |||
| 896104939b | |||
| 8385543e1c |
+4
-2
@@ -13,7 +13,7 @@ stages:
|
||||
- subprojects/pango/
|
||||
|
||||
fedora-x86_64:
|
||||
image: registry.gitlab.gnome.org/gnome/gtk/master:v3
|
||||
image: registry.gitlab.gnome.org/gnome/gtk/master:v5
|
||||
stage: build
|
||||
script:
|
||||
- bash -x ./.gitlab-ci/test-docker.sh
|
||||
@@ -26,6 +26,8 @@ fedora-x86_64:
|
||||
paths:
|
||||
- "${CI_PROJECT_DIR}/_build/meson-logs"
|
||||
- "${CI_PROJECT_DIR}/_build/report.xml"
|
||||
- "${CI_PROJECT_DIR}/_build/report.html"
|
||||
- "${CI_PROJECT_DIR}/_build/testsuite/reftests/output/*.png"
|
||||
cache:
|
||||
key: "$CI_JOB_NAME"
|
||||
<<: *cache-paths
|
||||
@@ -99,7 +101,7 @@ flatpak-master:icon-browser:
|
||||
<<: *flatpak-master
|
||||
|
||||
pages:
|
||||
image: registry.gitlab.gnome.org/gnome/gtk/master:v3
|
||||
image: registry.gitlab.gnome.org/gnome/gtk/master:v4
|
||||
stage: deploy
|
||||
script:
|
||||
- meson -Ddocumentation=true _build .
|
||||
|
||||
@@ -11,6 +11,7 @@ RUN dnf -y install \
|
||||
ccache \
|
||||
colord-devel \
|
||||
cups-devel \
|
||||
dejavu-sans-mono-fonts \
|
||||
desktop-file-utils \
|
||||
elfutils-libelf-devel \
|
||||
fribidi-devel \
|
||||
@@ -72,6 +73,8 @@ RUN dnf -y install \
|
||||
|
||||
RUN pip3 install meson==0.50.0
|
||||
|
||||
RUN pip3 install jinja2
|
||||
|
||||
ARG HOST_USER_ID=5555
|
||||
ENV HOST_USER_ID ${HOST_USER_ID}
|
||||
RUN useradd -u $HOST_USER_ID -ms /bin/bash user
|
||||
|
||||
Executable
+363
@@ -0,0 +1,363 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# Turns a Mason testlog.json file into an HTML report
|
||||
#
|
||||
# Copyright 2019 GNOME Foundation
|
||||
#
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
#
|
||||
# Original author: Emmanuele Bassi
|
||||
|
||||
import argparse
|
||||
import datetime
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
from jinja2 import Template
|
||||
|
||||
REPORT_TEMPLATE = '''
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>{{ report.project_name }} Test Report</title>
|
||||
<meta charset="utf-8" />
|
||||
<style type="text/css">
|
||||
body {
|
||||
background: white;
|
||||
color: #333;
|
||||
font-family: 'Cantarell', sans-serif;
|
||||
}
|
||||
|
||||
h1 {
|
||||
color: #333333;
|
||||
font-size: 1.9em;
|
||||
font-weight: normal;
|
||||
margin-bottom: 1em;
|
||||
border-bottom: 1px solid #333333;
|
||||
}
|
||||
|
||||
header {
|
||||
position: fixed;
|
||||
padding-bottom: 12px;
|
||||
margin-bottom: 24px;
|
||||
background: rgba(255, 255, 255, 0.85);
|
||||
box-shadow: 0 0 1px rgba(0, 0, 0, 0.15);
|
||||
z-index: 500;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
color: rgba(0, 0, 0, 0.3);
|
||||
transform: translateY(0px);
|
||||
transition: .2s background-color, color;
|
||||
box-sizing: border-box;
|
||||
display: block;
|
||||
visibility: visible;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
article {
|
||||
padding-top: 200px;
|
||||
margin: 2em;
|
||||
}
|
||||
|
||||
div.report-meta {
|
||||
width: auto;
|
||||
border: 1px solid #ccc;
|
||||
padding: .5em 2em;
|
||||
color: #3c3c3c;
|
||||
}
|
||||
|
||||
span.result {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
span.pass {
|
||||
color: rgb(51, 209, 122);
|
||||
}
|
||||
|
||||
span.skip {
|
||||
color: rgb(255, 163, 72);
|
||||
}
|
||||
|
||||
span.fail {
|
||||
color: rgb(224, 27, 36);
|
||||
}
|
||||
|
||||
span.xfail {
|
||||
color: rgb(163, 71, 186);
|
||||
}
|
||||
|
||||
div.result {
|
||||
border-top: 1px solid #c0c0c0;
|
||||
padding-top: 1em;
|
||||
padding-bottom: 1em;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
div.result h4 {
|
||||
border-bottom: 1px solid #c0c0c0;
|
||||
margin-bottom: 0.7em;
|
||||
}
|
||||
|
||||
pre {
|
||||
color: #fafafa;
|
||||
background-color: black;
|
||||
border-radius: 6px;
|
||||
box-shadow: 0px 5px 8px 0px rgba(0, 0, 0, 0.25);
|
||||
font-family: monospace;
|
||||
line-height: 1.2em;
|
||||
border: none;
|
||||
padding: 10px 1em;
|
||||
font-size: 0.9em;
|
||||
overflow: auto;
|
||||
white-space: pre;
|
||||
word-break: normal;
|
||||
word-wrap: normal;
|
||||
}
|
||||
|
||||
ul.passed li {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
ul.passed li:after {
|
||||
content: ",";
|
||||
}
|
||||
|
||||
ul.passed li:last-child:after {
|
||||
content: "";
|
||||
}
|
||||
|
||||
ul.images {
|
||||
padding-bottom: 1em;
|
||||
}
|
||||
|
||||
ul.images li {
|
||||
display: inline;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<h1>{{ report.project_name }} :: Test Reports</h1>
|
||||
<div class="report-meta">
|
||||
<p><strong>Branch:</strong> {{ report.branch_name }}</p>
|
||||
<p><strong>Date:</strong> <time datetime="{{ report.date.isoformat() }}">{{ report.locale_date }}</time></p>
|
||||
{% if report.job_id %}<p><strong>Job ID:</strong> {{ report.job_id }}</p>{% endif %}
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<div class="summary">
|
||||
<h3>Summary</h3>
|
||||
<ul>
|
||||
<li><strong>Total units:</strong> {{ report.total_units }}</li>
|
||||
<li><strong>Passed:</strong> {{ report.total_successes }}</li>
|
||||
<li><strong>Failed:</strong> {{ report.total_failures }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{% for suite_result in report.results_list %}
|
||||
<section>
|
||||
<div class="result">
|
||||
<h3>Suite: {{ suite_result.suite_name }}</h3>
|
||||
<ul>
|
||||
<li><strong>Units:</strong> {{ suite_result.n_units }}</li>
|
||||
<li><strong>Passed:</strong> {{ suite_result.n_successes }}</li>
|
||||
<li><strong>Failed:</strong> {{ suite_result.n_failures }}</li>
|
||||
</ul>
|
||||
|
||||
<div class="successes">
|
||||
<h4>Passed</h4>
|
||||
<ul class="passed">
|
||||
{% for success in suite_result.successes if success.result == 'OK' %}
|
||||
<li>{{ success.name }} - result: <span class="result pass">{{ success.result }}</li>
|
||||
{% else %}
|
||||
<li>None</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
<h4>Skipped</h4>
|
||||
<ul>
|
||||
{% for success in suite_result.successes if success.result == 'SKIP' %}
|
||||
<li>{{ success.name }} - result: <span class="result skip">{{ success.result }}</li>
|
||||
{% else %}
|
||||
<li>None</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
<h4>Expected failures</h4>
|
||||
<ul>
|
||||
{% for success in suite_result.successes if success.result == 'EXPECTEDFAIL' %}
|
||||
<li>{{ success.name }} - result: <span class="result xfail">{{ success.result }}</span><br/>
|
||||
{% if success.stdout %}
|
||||
Output: <pre>{{ success.stdout }}</pre>
|
||||
{% endif %}
|
||||
{% if success.image_data is defined %}
|
||||
<ul class="images">
|
||||
<li><img alt="ref" src="{{ success.image_data.ref }}" /></li>
|
||||
<li><img alt="out" src="{{ success.image_data.out }}" /></li>
|
||||
<li><img alt="diff" src="{{ success.image_data.diff }}" /></li>
|
||||
</ul>
|
||||
{% endif %}
|
||||
</li>
|
||||
{% else %}
|
||||
<li>None</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="failures">
|
||||
<h4>Failed</h4>
|
||||
<ul class="failed">
|
||||
{% for failure in suite_result.failures if failure.result == 'FAIL' %}
|
||||
<li>{{ failure.name }} - result: <span class="result fail">{{ failure.result }}</span><br/>
|
||||
{% if failure.stdout %}
|
||||
Output: <pre>{{ failure.stdout }}</pre>
|
||||
{% endif %}
|
||||
{% if failure.image_data is defined %}
|
||||
<ul class="images">
|
||||
<li><img alt="ref" src="{{ failure.image_data.ref }}" /></li>
|
||||
<li><img alt="out" src="{{ failure.image_data.out }}" /></li>
|
||||
<li><img alt="diff" src="{{ failure.image_data.diff }}" /></li>
|
||||
</ul>
|
||||
{% endif %}
|
||||
</li>
|
||||
{% else %}
|
||||
<li>None</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
<h4>Timed out</h4>
|
||||
<ul class="failed">
|
||||
{% for failure in suite_result.failures if failure.result == 'TIMEOUT' %}
|
||||
<li>{{ failure.name }} - result: <span class="result fail">{{ failure.result }}</span><br/>
|
||||
{% if failure.stdout %}
|
||||
Output: <pre>{{ failure.stdout }}</pre>
|
||||
{% endif %}
|
||||
</li>
|
||||
{% else %}
|
||||
<li>None</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
{% endfor %}
|
||||
|
||||
</article>
|
||||
</body>
|
||||
</html>
|
||||
'''
|
||||
|
||||
aparser = argparse.ArgumentParser(description='Turns a Meson test log into an HTML report')
|
||||
aparser.add_argument('--project-name', metavar='NAME',
|
||||
help='The project name',
|
||||
default='Unknown')
|
||||
aparser.add_argument('--job-id', metavar='ID',
|
||||
help='The job ID for the report',
|
||||
default=None)
|
||||
aparser.add_argument('--branch', metavar='NAME',
|
||||
help='Branch of the project being tested',
|
||||
default='master')
|
||||
aparser.add_argument('--output', metavar='FILE',
|
||||
help='The output HTML file, stdout by default',
|
||||
type=argparse.FileType('w', encoding='UTF-8'),
|
||||
default=sys.stdout)
|
||||
aparser.add_argument('--reftest-suite', metavar='NAME',
|
||||
help='The name of the reftests suite',
|
||||
default='reftest')
|
||||
aparser.add_argument('--reftest-output-dir', metavar='DIR',
|
||||
help='The output directory for reftests data',
|
||||
default=None)
|
||||
aparser.add_argument('infile', metavar='FILE',
|
||||
help='The input testlog.json, stdin by default',
|
||||
type=argparse.FileType('r', encoding='UTF-8'),
|
||||
default=sys.stdin)
|
||||
|
||||
args = aparser.parse_args()
|
||||
|
||||
outfile = args.output
|
||||
|
||||
suites = {}
|
||||
for line in args.infile:
|
||||
data = json.loads(line)
|
||||
(full_suite, unit_name) = data['name'].split(' / ')
|
||||
(project_name, suite_name) = full_suite.split(':')
|
||||
|
||||
unit = {
|
||||
'project-name': project_name,
|
||||
'suite': suite_name,
|
||||
'name': unit_name,
|
||||
'duration': data['duration'],
|
||||
'returncode': data['returncode'],
|
||||
'result': data['result'],
|
||||
'stdout': data['stdout'],
|
||||
}
|
||||
|
||||
if args.reftest_output_dir is not None and suite_name == args.reftest_suite:
|
||||
filename = unit_name.split(' ')[1]
|
||||
basename = os.path.splitext(filename)[0]
|
||||
|
||||
image_data = {
|
||||
'ref': os.path.join(args.reftest_output_dir, '{}.ref.png'.format(basename)),
|
||||
'out': os.path.join(args.reftest_output_dir, '{}.out.png'.format(basename)),
|
||||
'diff': os.path.join(args.reftest_output_dir, '{}.diff.png'.format(basename)),
|
||||
}
|
||||
|
||||
unit['image_data'] = image_data
|
||||
|
||||
units = suites.setdefault(full_suite, [])
|
||||
units.append(unit)
|
||||
|
||||
report = {}
|
||||
report['date'] = datetime.datetime.utcnow()
|
||||
report['locale_date'] = report['date'].strftime("%c")
|
||||
report['project_name'] = args.project_name
|
||||
report['job_id'] = args.job_id
|
||||
report['branch_name'] = args.branch
|
||||
report['total_successes'] = 0
|
||||
report['total_failures'] = 0
|
||||
report['total_units'] = 0
|
||||
report['results_list'] = []
|
||||
|
||||
for name, units in suites.items():
|
||||
(project_name, suite_name) = name.split(':')
|
||||
print('Processing {} suite {}:'.format(project_name, suite_name))
|
||||
|
||||
def if_failed(unit):
|
||||
if unit['result'] in ['FAIL', 'TIMEOUT']:
|
||||
return True
|
||||
return False
|
||||
|
||||
def if_succeded(unit):
|
||||
if unit['result'] in ['OK', 'EXPECTEDFAIL', 'SKIP']:
|
||||
return True
|
||||
return False
|
||||
|
||||
successes = list(filter(if_succeded, units))
|
||||
failures = list(filter(if_failed, units))
|
||||
|
||||
n_units = len(units)
|
||||
n_successes = len(successes)
|
||||
n_failures = len(failures)
|
||||
|
||||
report['total_units'] += n_units
|
||||
report['total_successes'] += n_successes
|
||||
report['total_failures'] += n_failures
|
||||
print(' - {}: {} total, {} pass, {} fail'.format(suite_name, n_units, n_successes, n_failures))
|
||||
|
||||
suite_report = {
|
||||
'suite_name': suite_name,
|
||||
'n_units': n_units,
|
||||
'successes': successes,
|
||||
'n_successes': n_successes,
|
||||
'failures': failures,
|
||||
'n_failures': n_failures,
|
||||
}
|
||||
report['results_list'].append(suite_report)
|
||||
|
||||
template = Template(REPORT_TEMPLATE)
|
||||
outfile.write(template.render({'report': report}))
|
||||
@@ -1,5 +1,13 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# Turns a Meson testlog.json file into a JUnit XML report
|
||||
#
|
||||
# Copyright 2019 GNOME Foundation
|
||||
#
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
#
|
||||
# Original author: Emmanuele Bassi
|
||||
|
||||
import argparse
|
||||
import datetime
|
||||
import json
|
||||
@@ -19,11 +27,11 @@ aparser.add_argument('--branch', metavar='NAME',
|
||||
default='master')
|
||||
aparser.add_argument('--output', metavar='FILE',
|
||||
help='The output file, stdout by default',
|
||||
type=argparse.FileType('w'),
|
||||
type=argparse.FileType('w', encoding='UTF-8'),
|
||||
default=sys.stdout)
|
||||
aparser.add_argument('infile', metavar='FILE',
|
||||
help='The input testlog.json, stdin by default',
|
||||
type=argparse.FileType('r'),
|
||||
type=argparse.FileType('r', encoding='UTF-8'),
|
||||
default=sys.stdin)
|
||||
|
||||
args = aparser.parse_args()
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
set -e
|
||||
|
||||
TAG="registry.gitlab.gnome.org/gnome/gtk/master:v3"
|
||||
TAG="registry.gitlab.gnome.org/gnome/gtk/master:v4"
|
||||
|
||||
sudo docker build --build-arg HOST_USER_ID="$UID" --tag "${TAG}" \
|
||||
--file "Dockerfile" .
|
||||
|
||||
@@ -16,6 +16,7 @@ meson \
|
||||
-Dwayland-backend=true \
|
||||
-Dbroadway-backend=true \
|
||||
-Dvulkan=yes \
|
||||
--werror \
|
||||
_build $srcdir
|
||||
unset CCACHE_DISABLE
|
||||
|
||||
@@ -32,17 +33,23 @@ xvfb-run -a -s "-screen 0 1024x768x24" \
|
||||
--print-errorlogs \
|
||||
--suite=gtk \
|
||||
--no-suite=gtk:gsk \
|
||||
--no-suite=gtk:reftest \
|
||||
--no-suite=gtk:a11y
|
||||
|
||||
# Save the exit code
|
||||
exit_code=$?
|
||||
|
||||
# We always want to run the report generator
|
||||
# We always want to run the report generators
|
||||
$srcdir/.gitlab-ci/meson-junit-report.py \
|
||||
--project-name=gtk \
|
||||
--job-id="${CI_JOB_NAME}" \
|
||||
--output=report.xml \
|
||||
meson-logs/testlog.json
|
||||
|
||||
$srcdir/.gitlab-ci/meson-html-report.py \
|
||||
--project-name=GTK \
|
||||
--job-id="${CI_JOB_NAME}" \
|
||||
--reftest-output-dir="testsuite/reftests/output" \
|
||||
--output=report.html \
|
||||
meson-logs/testlog.json
|
||||
|
||||
exit $exit_code
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
- Which version of GTK you are using
|
||||
- What operating system and version
|
||||
- For Linux, which distribution
|
||||
- If you built GTK+ yourself, the list of options used to configure the build
|
||||
- If you built GTK yourself, the list of options used to configure the build
|
||||
-->
|
||||
|
||||
## Additional information
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
- Which version of GTK you are using
|
||||
- What operating system and version
|
||||
- for Linux, which distribution
|
||||
- If you built GTK+ yourself, the list of options used to configure the build
|
||||
- If you built GTK yourself, the list of options used to configure the build
|
||||
-->
|
||||
|
||||
## Warnings
|
||||
|
||||
@@ -12,13 +12,13 @@ Overview of Changes in GTK+ 3.96.0
|
||||
* The use of global coordinates in GDK apis has been reduced. This
|
||||
work is still incomplete
|
||||
|
||||
* Events have been simplified and are just used for input
|
||||
- expose events have been replaced by a GdkSurface::render signal
|
||||
- configure events have been replaced by a GdkSurface::size-changed signal
|
||||
- map events have been replaced by a GdkSurface::mapped property
|
||||
- gdk_event_handler_set has been replaced by a GdkSurface::event signal
|
||||
- key events no longer contain a string
|
||||
- events on unmapped widgets are ignored
|
||||
* Events have been simplified and are used just for input
|
||||
- expose events have been replaced by a GdkSurface::render signal
|
||||
- configure events have been replaced by a GdkSurface::size-changed signal
|
||||
- map events have been replaced by a GdkSurface::mapped property
|
||||
- gdk_event_handler_set has been replaced by a GdkSurface::event signal
|
||||
- key events no longer contain a string
|
||||
- events on unmapped widgets are ignored
|
||||
|
||||
* Warping the pointer is no longer supported
|
||||
|
||||
@@ -36,11 +36,11 @@ Overview of Changes in GTK+ 3.96.0
|
||||
|
||||
* A number of list models have been introduced, for internal use
|
||||
and as public api:
|
||||
- GtkMapListModel
|
||||
- GtkSliceListModel
|
||||
- GtkSortListModel
|
||||
- GtkSelectionModel
|
||||
- GtkSingleSelection
|
||||
- GtkMapListModel
|
||||
- GtkSliceListModel
|
||||
- GtkSortListModel
|
||||
- GtkSelectionModel
|
||||
- GtkSingleSelection
|
||||
|
||||
* Support for tabular menus and combo boxes has been dropped
|
||||
|
||||
@@ -70,9 +70,13 @@ Overview of Changes in GTK+ 3.96.0
|
||||
|
||||
* GtkWidget can now use a GtkLayoutManager for size allocation.
|
||||
Layout managers can optionally use layout children holding layout
|
||||
properties. GtkBinLayout, GtkBoxLayout, GtkGridLayout, GtkFixedLayout
|
||||
and GtkCustomLayout are currently available, more layout manager
|
||||
implementations will appear in the future.
|
||||
properties. A number of layout managers are available:
|
||||
- GtkBinLayout
|
||||
- GtkBoxLayout
|
||||
- GtkGridLayout
|
||||
- GtkFixedLayout
|
||||
- GtkCustomLayout
|
||||
More layout manager implementations will appear in the future.
|
||||
|
||||
* GtkAssistant, GtkStack and GtkNotebook now have publicly
|
||||
accessible page objects for their children. The page objects
|
||||
@@ -82,8 +86,11 @@ Overview of Changes in GTK+ 3.96.0
|
||||
child properties have been removed, converted to regular properties,
|
||||
moved to layout properties or moved to child meta objects.
|
||||
|
||||
* GtkListBox has gained a ::show-separators property that gets
|
||||
translated into a CSS style class.
|
||||
|
||||
* A number of X11-specific GtkWindow and GdkSurface apis have been
|
||||
removed
|
||||
removed or changed to backend APIs.
|
||||
|
||||
* GtkBuilder can specify object-valued properties inline.
|
||||
|
||||
|
||||
@@ -13,19 +13,22 @@ show_parsing_error (GtkCssProvider *provider,
|
||||
const GError *error,
|
||||
GtkTextBuffer *buffer)
|
||||
{
|
||||
const GtkCssLocation *start_location, *end_location;
|
||||
GtkTextIter start, end;
|
||||
const char *tag_name;
|
||||
|
||||
start_location = gtk_css_section_get_start_location (section);
|
||||
gtk_text_buffer_get_iter_at_line_index (buffer,
|
||||
&start,
|
||||
gtk_css_section_get_start_line (section),
|
||||
gtk_css_section_get_start_position (section));
|
||||
start_location->lines,
|
||||
start_location->line_bytes);
|
||||
end_location = gtk_css_section_get_end_location (section);
|
||||
gtk_text_buffer_get_iter_at_line_index (buffer,
|
||||
&end,
|
||||
gtk_css_section_get_end_line (section),
|
||||
gtk_css_section_get_end_position (section));
|
||||
end_location->lines,
|
||||
end_location->line_bytes);
|
||||
|
||||
if (g_error_matches (error, GTK_CSS_PROVIDER_ERROR, GTK_CSS_PROVIDER_ERROR_DEPRECATED))
|
||||
if (error->domain == GTK_CSS_PARSER_WARNING)
|
||||
tag_name = "warning";
|
||||
else
|
||||
tag_name = "error";
|
||||
|
||||
@@ -13,19 +13,23 @@ show_parsing_error (GtkCssProvider *provider,
|
||||
const GError *error,
|
||||
GtkTextBuffer *buffer)
|
||||
{
|
||||
const GtkCssLocation *start_location, *end_location;
|
||||
GtkTextIter start, end;
|
||||
const char *tag_name;
|
||||
|
||||
start_location = gtk_css_section_get_start_location (section);
|
||||
gtk_text_buffer_get_iter_at_line_index (buffer,
|
||||
&start,
|
||||
gtk_css_section_get_start_line (section),
|
||||
gtk_css_section_get_start_position (section));
|
||||
start_location->lines,
|
||||
start_location->line_bytes);
|
||||
end_location = gtk_css_section_get_end_location (section);
|
||||
gtk_text_buffer_get_iter_at_line_index (buffer,
|
||||
&end,
|
||||
gtk_css_section_get_end_line (section),
|
||||
gtk_css_section_get_end_position (section));
|
||||
end_location->lines,
|
||||
end_location->line_bytes);
|
||||
|
||||
if (g_error_matches (error, GTK_CSS_PROVIDER_ERROR, GTK_CSS_PROVIDER_ERROR_DEPRECATED))
|
||||
|
||||
if (error->domain == GTK_CSS_PARSER_WARNING)
|
||||
tag_name = "warning";
|
||||
else
|
||||
tag_name = "error";
|
||||
|
||||
@@ -12,19 +12,23 @@ show_parsing_error (GtkCssProvider *provider,
|
||||
const GError *error,
|
||||
GtkTextBuffer *buffer)
|
||||
{
|
||||
const GtkCssLocation *start_location, *end_location;
|
||||
GtkTextIter start, end;
|
||||
const char *tag_name;
|
||||
|
||||
start_location = gtk_css_section_get_start_location (section);
|
||||
gtk_text_buffer_get_iter_at_line_index (buffer,
|
||||
&start,
|
||||
gtk_css_section_get_start_line (section),
|
||||
gtk_css_section_get_start_position (section));
|
||||
start_location->lines,
|
||||
start_location->line_bytes);
|
||||
end_location = gtk_css_section_get_end_location (section);
|
||||
gtk_text_buffer_get_iter_at_line_index (buffer,
|
||||
&end,
|
||||
gtk_css_section_get_end_line (section),
|
||||
gtk_css_section_get_end_position (section));
|
||||
end_location->lines,
|
||||
end_location->line_bytes);
|
||||
|
||||
if (g_error_matches (error, GTK_CSS_PROVIDER_ERROR, GTK_CSS_PROVIDER_ERROR_DEPRECATED))
|
||||
|
||||
if (error->domain == GTK_CSS_PARSER_WARNING)
|
||||
tag_name = "warning";
|
||||
else
|
||||
tag_name = "error";
|
||||
|
||||
@@ -11,19 +11,22 @@ show_parsing_error (GtkCssProvider *provider,
|
||||
const GError *error,
|
||||
GtkTextBuffer *buffer)
|
||||
{
|
||||
const GtkCssLocation *start_location, *end_location;
|
||||
GtkTextIter start, end;
|
||||
const char *tag_name;
|
||||
|
||||
start_location = gtk_css_section_get_start_location (section);
|
||||
gtk_text_buffer_get_iter_at_line_index (buffer,
|
||||
&start,
|
||||
gtk_css_section_get_start_line (section),
|
||||
gtk_css_section_get_start_position (section));
|
||||
start_location->lines,
|
||||
start_location->line_bytes);
|
||||
end_location = gtk_css_section_get_end_location (section);
|
||||
gtk_text_buffer_get_iter_at_line_index (buffer,
|
||||
&end,
|
||||
gtk_css_section_get_end_line (section),
|
||||
gtk_css_section_get_end_position (section));
|
||||
end_location->lines,
|
||||
end_location->line_bytes);
|
||||
|
||||
if (g_error_matches (error, GTK_CSS_PROVIDER_ERROR, GTK_CSS_PROVIDER_ERROR_DEPRECATED))
|
||||
if (error->domain == GTK_CSS_PARSER_WARNING)
|
||||
tag_name = "warning";
|
||||
else
|
||||
tag_name = "error";
|
||||
|
||||
@@ -243,7 +243,7 @@ pressed_cb (GtkGesture *gesture,
|
||||
GtkWidget *child;
|
||||
|
||||
widget = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (gesture));
|
||||
child = gtk_widget_pick (widget, x, y);
|
||||
child = gtk_widget_pick (widget, x, y, GTK_PICK_DEFAULT);
|
||||
|
||||
if (gtk_gesture_single_get_current_button (GTK_GESTURE_SINGLE (gesture)) == GDK_BUTTON_SECONDARY)
|
||||
{
|
||||
@@ -320,7 +320,7 @@ released_cb (GtkGesture *gesture,
|
||||
GtkWidget *child;
|
||||
|
||||
widget = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (gesture));
|
||||
child = gtk_widget_pick (widget, x, y);
|
||||
child = gtk_widget_pick (widget, x, y, 0);
|
||||
|
||||
if (gtk_gesture_single_get_current_button (GTK_GESTURE_SINGLE (gesture)) == GDK_BUTTON_PRIMARY)
|
||||
{
|
||||
|
||||
@@ -31,6 +31,7 @@ do_expander (GtkWidget *do_widget)
|
||||
GtkWidget *toplevel;
|
||||
GtkWidget *area;
|
||||
GtkWidget *expander;
|
||||
GtkWidget *label;
|
||||
GtkWidget *sw;
|
||||
GtkWidget *tv;
|
||||
GtkTextBuffer *buffer;
|
||||
@@ -50,13 +51,19 @@ do_expander (GtkWidget *do_widget)
|
||||
|
||||
area = gtk_message_dialog_get_message_area (GTK_MESSAGE_DIALOG (window));
|
||||
|
||||
label = gtk_widget_get_last_child (area);
|
||||
gtk_label_set_line_wrap (GTK_LABEL (label), FALSE);
|
||||
gtk_widget_set_vexpand (label, FALSE);
|
||||
|
||||
expander = gtk_expander_new ("Details:");
|
||||
gtk_widget_set_vexpand (expander, TRUE);
|
||||
sw = gtk_scrolled_window_new (NULL, NULL);
|
||||
gtk_scrolled_window_set_min_content_height (GTK_SCROLLED_WINDOW (sw), 100);
|
||||
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw), GTK_SHADOW_IN);
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
|
||||
GTK_POLICY_NEVER,
|
||||
GTK_POLICY_AUTOMATIC);
|
||||
gtk_scrolled_window_set_propagate_natural_height (GTK_SCROLLED_WINDOW (sw), TRUE);
|
||||
|
||||
tv = gtk_text_view_new ();
|
||||
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (tv));
|
||||
|
||||
@@ -495,7 +495,11 @@ update_script_combo (void)
|
||||
gboolean have_active = FALSE;
|
||||
|
||||
lang = gtk_font_chooser_get_language (GTK_FONT_CHOOSER (font));
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
active = hb_ot_tag_from_language (hb_language_from_string (lang, -1));
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
|
||||
g_free (lang);
|
||||
|
||||
store = gtk_list_store_new (4, G_TYPE_STRING, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT);
|
||||
|
||||
+36
-6
@@ -45,22 +45,43 @@ activate_about (GSimpleAction *action,
|
||||
"The GTK Team",
|
||||
NULL
|
||||
};
|
||||
char *version;
|
||||
GString *s;
|
||||
|
||||
s = g_string_new ("");
|
||||
|
||||
g_string_append (s, "System libraries\n");
|
||||
g_string_append_printf (s, "\tGLib\t%d.%d.%d\n",
|
||||
glib_major_version,
|
||||
glib_minor_version,
|
||||
glib_micro_version);
|
||||
g_string_append_printf (s, "\tGTK\t%d.%d.%d\n",
|
||||
gtk_get_major_version (),
|
||||
gtk_get_minor_version (),
|
||||
gtk_get_micro_version ());
|
||||
g_string_append_printf (s, "\nA link can apppear here: <http://www.gtk.org>");
|
||||
|
||||
version = g_strdup_printf ("%s\nRunning against GTK %d.%d.%d",
|
||||
PACKAGE_VERSION,
|
||||
gtk_get_major_version (),
|
||||
gtk_get_minor_version (),
|
||||
gtk_get_micro_version ());
|
||||
|
||||
gtk_show_about_dialog (GTK_WINDOW (gtk_application_get_active_window (app)),
|
||||
"program-name", "GTK Demo",
|
||||
"version", g_strdup_printf ("%s,\nRunning against GTK %d.%d.%d",
|
||||
PACKAGE_VERSION,
|
||||
gtk_get_major_version (),
|
||||
gtk_get_minor_version (),
|
||||
gtk_get_micro_version ()),
|
||||
"copyright", "(C) 1997-2013 The GTK Team",
|
||||
"version", version,
|
||||
"copyright", "© 1997—2019 The GTK Team",
|
||||
"license-type", GTK_LICENSE_LGPL_2_1,
|
||||
"website", "http://www.gtk.org",
|
||||
"comments", "Program to demonstrate GTK widgets",
|
||||
"authors", authors,
|
||||
"logo-icon-name", "org.gtk.Demo4",
|
||||
"title", "About GTK Demo",
|
||||
"system-information", s->str,
|
||||
NULL);
|
||||
|
||||
g_string_free (s, TRUE);
|
||||
g_free (version);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -84,6 +105,14 @@ activate_quit (GSimpleAction *action,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
activate_inspector (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
{
|
||||
gtk_window_set_interactive_debugging (TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
window_closed_cb (GtkWidget *window, gpointer data)
|
||||
{
|
||||
@@ -1200,6 +1229,7 @@ main (int argc, char **argv)
|
||||
static GActionEntry app_entries[] = {
|
||||
{ "about", activate_about, NULL, NULL, NULL },
|
||||
{ "quit", activate_quit, NULL, NULL, NULL },
|
||||
{ "inspector", activate_inspector, NULL, NULL, NULL },
|
||||
};
|
||||
|
||||
/* Most code in gtk-demo is intended to be exemplary, but not
|
||||
|
||||
@@ -1,5 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<menu id="gear_menu">
|
||||
<section>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">_Inspector</attribute>
|
||||
<attribute name="action">app.inspector</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">_About GTK Demo</attribute>
|
||||
<attribute name="action">app.about</attribute>
|
||||
</item>
|
||||
</section>
|
||||
</menu>
|
||||
<object class="GtkTreeStore" id="treestore">
|
||||
<columns>
|
||||
<column type="gchararray"/>
|
||||
@@ -35,6 +47,13 @@
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child type="end">
|
||||
<object class="GtkMenuButton" id="gear_menu_button">
|
||||
<property name="valign">center</property>
|
||||
<property name="menu-model">gear_menu</property>
|
||||
<property name="icon-name">open-menu-symbolic</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
|
||||
+1
-17
@@ -70,12 +70,6 @@ change_orientation (GtkWidget *button,
|
||||
parent = gtk_widget_get_parent (menubar);
|
||||
orientation = gtk_orientable_get_orientation (GTK_ORIENTABLE (parent));
|
||||
gtk_orientable_set_orientation (GTK_ORIENTABLE (parent), 1 - orientation);
|
||||
|
||||
if (orientation == GTK_ORIENTATION_VERTICAL)
|
||||
g_object_set (menubar, "pack-direction", GTK_PACK_DIRECTION_TTB, NULL);
|
||||
else
|
||||
g_object_set (menubar, "pack-direction", GTK_PACK_DIRECTION_LTR, NULL);
|
||||
|
||||
}
|
||||
|
||||
static GtkWidget *window = NULL;
|
||||
@@ -107,51 +101,41 @@ do_menus (GtkWidget *do_widget)
|
||||
|
||||
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
||||
gtk_container_add (GTK_CONTAINER (window), box);
|
||||
gtk_widget_show (box);
|
||||
|
||||
box1 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
||||
gtk_container_add (GTK_CONTAINER (box), box1);
|
||||
gtk_widget_show (box1);
|
||||
|
||||
menubar = gtk_menu_bar_new ();
|
||||
gtk_widget_set_hexpand (menubar, TRUE);
|
||||
gtk_container_add (GTK_CONTAINER (box1), menubar);
|
||||
gtk_widget_show (menubar);
|
||||
|
||||
menu = create_menu (2);
|
||||
|
||||
menuitem = gtk_menu_item_new_with_label ("test\nline2");
|
||||
gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), menu);
|
||||
gtk_menu_shell_append (GTK_MENU_SHELL (menubar), menuitem);
|
||||
gtk_widget_show (menuitem);
|
||||
|
||||
menuitem = gtk_menu_item_new_with_label ("foo");
|
||||
gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), create_menu (3));
|
||||
gtk_menu_shell_append (GTK_MENU_SHELL (menubar), menuitem);
|
||||
gtk_widget_show (menuitem);
|
||||
|
||||
menuitem = gtk_menu_item_new_with_label ("bar");
|
||||
gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), create_menu (4));
|
||||
gtk_menu_shell_append (GTK_MENU_SHELL (menubar), menuitem);
|
||||
gtk_widget_show (menuitem);
|
||||
|
||||
box2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10);
|
||||
gtk_container_add (GTK_CONTAINER (box1), box2);
|
||||
gtk_widget_show (box2);
|
||||
|
||||
button = gtk_button_new_with_label ("Flip");
|
||||
g_signal_connect (button, "clicked",
|
||||
G_CALLBACK (change_orientation), menubar);
|
||||
gtk_container_add (GTK_CONTAINER (box2), button);
|
||||
gtk_widget_show (button);
|
||||
|
||||
button = gtk_button_new_with_label ("Close");
|
||||
g_signal_connect_swapped (button, "clicked",
|
||||
G_CALLBACK(gtk_widget_destroy), window);
|
||||
gtk_container_add (GTK_CONTAINER (box2), button);
|
||||
gtk_widget_set_can_default (button, TRUE);
|
||||
gtk_widget_grab_default (button);
|
||||
gtk_widget_show (button);
|
||||
gtk_window_set_default_widget (GTK_WINDOW (window), button);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
|
||||
@@ -57,7 +57,7 @@ do_overlay (GtkWidget *do_widget)
|
||||
|
||||
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10);
|
||||
gtk_overlay_add_overlay (GTK_OVERLAY (overlay), vbox);
|
||||
gtk_widget_set_can_pick (vbox, FALSE);
|
||||
gtk_widget_set_can_target (vbox, FALSE);
|
||||
gtk_widget_set_halign (vbox, GTK_ALIGN_CENTER);
|
||||
gtk_widget_set_valign (vbox, GTK_ALIGN_CENTER);
|
||||
|
||||
|
||||
@@ -66,13 +66,13 @@ do_overlay2 (GtkWidget *do_widget)
|
||||
|
||||
image = gtk_picture_new_for_resource ("/overlay2/decor1.png");
|
||||
gtk_overlay_add_overlay (GTK_OVERLAY (overlay), image);
|
||||
gtk_widget_set_can_pick (image, FALSE);
|
||||
gtk_widget_set_can_target (image, FALSE);
|
||||
gtk_widget_set_halign (image, GTK_ALIGN_START);
|
||||
gtk_widget_set_valign (image, GTK_ALIGN_START);
|
||||
|
||||
image = gtk_picture_new_for_resource ("/overlay2/decor2.png");
|
||||
gtk_overlay_add_overlay (GTK_OVERLAY (overlay), image);
|
||||
gtk_widget_set_can_pick (image, FALSE);
|
||||
gtk_widget_set_can_target (image, FALSE);
|
||||
gtk_widget_set_halign (image, GTK_ALIGN_END);
|
||||
gtk_widget_set_valign (image, GTK_ALIGN_END);
|
||||
|
||||
|
||||
@@ -76,8 +76,7 @@ do_password_entry (GtkWidget *do_widget)
|
||||
gtk_widget_set_sensitive (button, FALSE);
|
||||
gtk_header_bar_pack_end (GTK_HEADER_BAR (header), button);
|
||||
|
||||
gtk_widget_set_can_default (button, TRUE);
|
||||
gtk_window_set_default (GTK_WINDOW (window), button);
|
||||
gtk_window_set_default_widget (GTK_WINDOW (window), button);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
|
||||
@@ -228,7 +228,7 @@ puzzle_button_pressed (GtkGestureMultiPress *gesture,
|
||||
int l, t, i;
|
||||
int pos;
|
||||
|
||||
child = gtk_widget_pick (grid, x, y);
|
||||
child = gtk_widget_pick (grid, x, y, GTK_PICK_DEFAULT);
|
||||
|
||||
if (!child)
|
||||
{
|
||||
|
||||
@@ -99,8 +99,7 @@ do_tagged_entry (GtkWidget *do_widget)
|
||||
g_signal_connect_swapped (button, "clicked", G_CALLBACK (gtk_widget_destroy), window);
|
||||
gtk_header_bar_pack_end (GTK_HEADER_BAR (header), button);
|
||||
|
||||
gtk_widget_set_can_default (button, TRUE);
|
||||
gtk_window_set_default (GTK_WINDOW (window), button);
|
||||
gtk_window_set_default_widget (GTK_WINDOW (window), button);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
|
||||
@@ -205,6 +205,7 @@ add_context (IconBrowserWindow *win,
|
||||
g_hash_table_insert (win->contexts, c->id, c);
|
||||
|
||||
row = gtk_label_new (name);
|
||||
gtk_label_set_xalign (GTK_LABEL (row), 0);
|
||||
g_object_set_data (G_OBJECT (row), "context", c);
|
||||
gtk_widget_show (row);
|
||||
g_object_set (row, "margin", 10, NULL);
|
||||
|
||||
@@ -121,6 +121,7 @@
|
||||
<property name="hide-on-close">1</property>
|
||||
<child internal-child="content_area">
|
||||
<object class="GtkBox">
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkGrid">
|
||||
<property name="margin">10</property>
|
||||
|
||||
@@ -227,7 +227,7 @@ activate_about (GSimpleAction *action,
|
||||
gtk_show_about_dialog (GTK_WINDOW (gtk_application_get_active_window (app)),
|
||||
"program-name", "GTK Widget Factory",
|
||||
"version", version,
|
||||
"copyright", "(C) 1997-2013 The GTK Team",
|
||||
"copyright", "© 1997—2019 The GTK Team",
|
||||
"license-type", GTK_LICENSE_LGPL_2_1,
|
||||
"website", "http://www.gtk.org",
|
||||
"comments", "Program to demonstrate GTK themes and widgets",
|
||||
@@ -262,6 +262,14 @@ activate_quit (GSimpleAction *action,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
activate_inspector (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
{
|
||||
gtk_window_set_interactive_debugging (TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
spin_value_changed (GtkAdjustment *adjustment, GtkWidget *label)
|
||||
{
|
||||
@@ -1935,6 +1943,7 @@ main (int argc, char *argv[])
|
||||
static GActionEntry app_entries[] = {
|
||||
{ "about", activate_about, NULL, NULL, NULL },
|
||||
{ "quit", activate_quit, NULL, NULL, NULL },
|
||||
{ "inspector", activate_inspector, NULL, NULL, NULL },
|
||||
{ "main", NULL, "s", "'steak'", NULL },
|
||||
{ "wine", NULL, NULL, "false", NULL },
|
||||
{ "beer", NULL, NULL, "false", NULL },
|
||||
|
||||
@@ -16,6 +16,10 @@
|
||||
</item>
|
||||
</section>
|
||||
<section>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">_Inspector</attribute>
|
||||
<attribute name="action">app.inspector</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">_Keyboard Shortcuts</attribute>
|
||||
<attribute name="action">win.show-help-overlay</attribute>
|
||||
@@ -2876,6 +2880,17 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
<child>
|
||||
<object class="GtkNotebook">
|
||||
<property name="show-border">0</property>
|
||||
<child type="action-end">
|
||||
<object class="GtkMenuButton">
|
||||
<property name="valign">center</property>
|
||||
<property name="popover">notebook_info_popover2</property>
|
||||
<property name="icon-name">emblem-important-symbolic</property>
|
||||
<property name="relief">none</property>
|
||||
<style>
|
||||
<class name="circular"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkNotebookPage">
|
||||
<property name="tab-expand">1</property>
|
||||
@@ -3139,6 +3154,7 @@ bad things might happen.</property>
|
||||
<property name="use-header-bar">1</property>
|
||||
<property name="title" translatable="yes">Zelda</property>
|
||||
<property name="hide-on-close">1</property>
|
||||
<property name="default-widget">act_action_dialog</property>
|
||||
<child internal-child="content_area">
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
@@ -3160,8 +3176,6 @@ bad things might happen.</property>
|
||||
</child>
|
||||
<child type="action">
|
||||
<object class="GtkButton" id="act_action_dialog">
|
||||
<property name="can-default">1</property>
|
||||
<property name="has-default">1</property>
|
||||
<property name="label" translatable="yes">_Act</property>
|
||||
<property name="use-underline">1</property>
|
||||
</object>
|
||||
@@ -3299,6 +3313,7 @@ bad things might happen.</property>
|
||||
<property name="use-header-bar">1</property>
|
||||
<property name="title" translatable="yes">Choose one</property>
|
||||
<property name="hide-on-close">1</property>
|
||||
<property name="default-widget">select_selection_dialog</property>
|
||||
<child internal-child="content_area">
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
@@ -3320,8 +3335,6 @@ bad things might happen.</property>
|
||||
</child>
|
||||
<child type="action">
|
||||
<object class="GtkButton" id="select_selection_dialog">
|
||||
<property name="can-default">1</property>
|
||||
<property name="has-default">1</property>
|
||||
<property name="label" translatable="yes">_Select</property>
|
||||
<property name="use-underline">1</property>
|
||||
</object>
|
||||
@@ -3382,6 +3395,7 @@ bad things might happen.</property>
|
||||
<layout>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">1</property>
|
||||
<property name="column-span">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
@@ -3394,22 +3408,52 @@ bad things might happen.</property>
|
||||
<layout>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">0</property>
|
||||
<property name="column-span">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkExpander">
|
||||
<child type="label">
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Extra Info</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry">
|
||||
<property name="placeholder-text">Tell me anything…</property>
|
||||
</object>
|
||||
</child>
|
||||
<layout>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">2</property>
|
||||
<property name="column-span">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuButton">
|
||||
<property name="halign">end</property>
|
||||
<property name="icon-name">emblem-system-symbolic</property>
|
||||
<property name="menu-model">gear_menu</property>
|
||||
<layout>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">3</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="open_popover_button">
|
||||
<property name="halign">end</property>
|
||||
<property name="halign">fill</property>
|
||||
<property name="label">_Open</property>
|
||||
<property name="use-underline">1</property>
|
||||
<property name="sensitive">0</property>
|
||||
<property name="can-default">1</property>
|
||||
<style>
|
||||
<class name="suggested-action"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">2</property>
|
||||
<property name="left-attach">2</property>
|
||||
<property name="top-attach">3</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
@@ -3435,8 +3479,9 @@ bad things might happen.</property>
|
||||
</widgets>
|
||||
</object>
|
||||
<object class="GtkPopover" id="notebook_info_popover">
|
||||
<property name="modal">0</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="notebook_info_label">
|
||||
<object class="GtkLabel">
|
||||
<property name="label">No updates at this time</property>
|
||||
<accessibility>
|
||||
<role type="static"/>
|
||||
@@ -3444,4 +3489,39 @@ bad things might happen.</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<object class="GtkPopover" id="notebook_info_popover3">
|
||||
<property name="modal">0</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">You're in too deep!</property>
|
||||
<accessibility>
|
||||
<role type="static"/>
|
||||
</accessibility>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<object class="GtkPopover" id="notebook_info_popover2">
|
||||
<property name="modal">0</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="orientation">horizontal</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Hidden gems:</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuButton">
|
||||
<property name="valign">center</property>
|
||||
<property name="popover">notebook_info_popover3</property>
|
||||
<property name="icon-name">emblem-important-symbolic</property>
|
||||
<property name="relief">none</property>
|
||||
<style>
|
||||
<class name="circular"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
||||
|
||||
@@ -231,10 +231,9 @@ gdk_surface_get_scale_factor
|
||||
gdk_surface_set_opaque_region
|
||||
gdk_surface_create_gl_context
|
||||
gdk_surface_create_vulkan_context
|
||||
gdk_surface_create_cairo_context
|
||||
|
||||
<SUBSECTION>
|
||||
gdk_surface_invalidate_rect
|
||||
gdk_surface_invalidate_region
|
||||
gdk_surface_queue_expose
|
||||
gdk_surface_freeze_updates
|
||||
gdk_surface_thaw_updates
|
||||
@@ -262,9 +261,6 @@ gdk_surface_get_modal_hint
|
||||
gdk_surface_set_type_hint
|
||||
gdk_surface_get_type_hint
|
||||
gdk_surface_set_shadow_width
|
||||
gdk_surface_set_skip_taskbar_hint
|
||||
gdk_surface_set_skip_pager_hint
|
||||
gdk_surface_set_urgency_hint
|
||||
gdk_surface_get_position
|
||||
gdk_surface_get_root_origin
|
||||
gdk_surface_get_frame_extents
|
||||
@@ -280,8 +276,6 @@ gdk_surface_peek_children
|
||||
gdk_surface_set_icon_name
|
||||
gdk_surface_set_transient_for
|
||||
gdk_surface_set_startup_id
|
||||
gdk_surface_set_group
|
||||
gdk_surface_get_group
|
||||
gdk_surface_set_decorations
|
||||
gdk_surface_get_decorations
|
||||
GdkWMDecoration
|
||||
@@ -995,7 +989,6 @@ gdk_wayland_device_get_wl_seat
|
||||
gdk_wayland_display_get_wl_compositor
|
||||
gdk_wayland_display_get_wl_display
|
||||
gdk_wayland_display_query_registry
|
||||
gdk_wayland_surface_new_subsurface
|
||||
gdk_wayland_surface_get_wl_surface
|
||||
GdkWaylandSurfaceExported
|
||||
gdk_wayland_surface_export_handle
|
||||
|
||||
@@ -62,6 +62,7 @@ gsk_outset_shadow_node_get_spread
|
||||
gsk_outset_shadow_node_get_blur_radius
|
||||
gsk_cairo_node_new
|
||||
gsk_cairo_node_get_draw_context
|
||||
gsk_cairo_node_peek_surface
|
||||
gsk_container_node_new
|
||||
gsk_container_node_get_n_children
|
||||
gsk_container_node_get_child
|
||||
@@ -88,6 +89,7 @@ GskShadow
|
||||
gsk_shadow_node_new
|
||||
gsk_shadow_node_peek_shadow
|
||||
gsk_shadow_node_get_n_shadows
|
||||
gsk_shadow_node_get_child
|
||||
GskBlendMode
|
||||
gsk_blend_node_new
|
||||
gsk_blend_node_get_bottom_child
|
||||
@@ -103,6 +105,7 @@ gsk_text_node_peek_glyphs
|
||||
gsk_text_node_peek_color
|
||||
gsk_text_node_get_x
|
||||
gsk_text_node_get_y
|
||||
gsk_text_node_get_num_glyphs
|
||||
gsk_blur_node_new
|
||||
gsk_blur_node_get_child
|
||||
gsk_blur_node_get_radius
|
||||
@@ -152,6 +155,8 @@ gsk_transform_get_category
|
||||
<SUBSECTION>
|
||||
gsk_transform_print
|
||||
gsk_transform_to_string
|
||||
gsk_transform_parse
|
||||
<SUBSECTION>
|
||||
gsk_transform_to_matrix
|
||||
gsk_transform_to_2d
|
||||
gsk_transform_to_affine
|
||||
@@ -160,6 +165,7 @@ gsk_transform_to_translate
|
||||
gsk_transform_transform
|
||||
gsk_transform_invert
|
||||
gsk_transform_matrix
|
||||
gsk_transform_matrix_with_category
|
||||
gsk_transform_translate
|
||||
gsk_transform_translate_3d
|
||||
gsk_transform_rotate
|
||||
|
||||
@@ -0,0 +1,373 @@
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
|
||||
]>
|
||||
<refentry id="chap-actions">
|
||||
<refmeta>
|
||||
<refentrytitle>The GTK Action Model</refentrytitle>
|
||||
<manvolnum>3</manvolnum>
|
||||
<refmiscinfo>GTK Library</refmiscinfo>
|
||||
</refmeta>
|
||||
|
||||
<refnamediv>
|
||||
<refname>The GTK Action Model</refname>
|
||||
<refpurpose>
|
||||
How actions are used in GTK
|
||||
</refpurpose>
|
||||
</refnamediv>
|
||||
|
||||
|
||||
<refsect1 id="actions-overview">
|
||||
<title>Overview of actions in GTK</title>
|
||||
|
||||
<para>
|
||||
This chapter describes in detail how GTK uses actions to connect
|
||||
activatable UI elements to callbacks. GTK inherits the underlying
|
||||
architecture of GAction and GMenu for describing abstract actions
|
||||
and menus from the GIO library.
|
||||
</para>
|
||||
|
||||
<refsect2>
|
||||
<title>Basics about actions</title>
|
||||
|
||||
<para>
|
||||
A GAction is essentially a way to tell the toolkit about a
|
||||
piece of functionality in your program, and to give it a name.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Actions are purely functional. They do not contain any
|
||||
presentational information.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
An action has four pieces of information associated with it:
|
||||
<itemizedlist>
|
||||
<listitem><para>
|
||||
a name as an identifier (usually all-lowercase, untranslated
|
||||
English string)
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
an enabled flag indicating if the action can be activated or
|
||||
not (like the "sensitive" property on widgets)
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
an optional state value, for stateful actions (like a boolean
|
||||
for toggles)
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
an optional parameter type, used when activating the action
|
||||
</para></listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
An action supports two operations. You can activate it, which
|
||||
requires passing a parameter of the correct type
|
||||
And you can request to change the actions state (for stateful
|
||||
actions) to a new state value of the correct type.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Here are some rules about an action:
|
||||
<itemizedlist>
|
||||
<listitem><para>
|
||||
the name is immutable (in the sense that it will never
|
||||
change) and it is never %NULL
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
the enabled flag can change
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
the parameter type is immutable
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
the parameter type is optional: it can be %NULL
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
if the parameter type is %NULL then action activation must
|
||||
be done without a parameter (ie: a %NULL GVariant pointer)
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
if the parameter type is non-%NULL then the parameter must
|
||||
have this type
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
the state can change, but it cannot change type
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
if the action was stateful when it was created, it will
|
||||
always have a state and it will always have exactly the same
|
||||
type (such as boolean or string)
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
if the action was stateless when it was created, it can never
|
||||
have a state
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
you can only request state changes on stateful actions and it
|
||||
is only possible to request that the state change to a value
|
||||
of the same type as the existing state
|
||||
</para></listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
An action does not have any sort of presentational information
|
||||
such as a label, an icon or a way of creating a widget from it.
|
||||
</para>
|
||||
|
||||
</refsect2>
|
||||
|
||||
<refsect2>
|
||||
<title>Action state and parameters</title>
|
||||
|
||||
<para>
|
||||
Most actions in your application will be stateless actions with
|
||||
no parameters. These typically appear as menu items with no
|
||||
special decoration. An example is "quit".
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Stateful actions are used to represent an action which has a
|
||||
closely-associated state of some kind. A good example is a
|
||||
"fullscreen" action. For this case, you'd expect to see a
|
||||
checkmark next to the menu item when the fullscreen option
|
||||
is active. This is usually called a toggle action, and it has
|
||||
a boolean state. By convention, toggle actions have no parameter
|
||||
type for activation: activating the action always toggles the
|
||||
state.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Another common case is to have an action representing a
|
||||
enumeration of possible values of a given type (typically
|
||||
string). This is often called a radio action and is usually
|
||||
represented in the user interface with radio buttons or radio
|
||||
menu items, or sometimes a combobox. A good example is
|
||||
"text-justify" with possible values "left", "center", and
|
||||
"right". By convention, these types of actions have a parameter
|
||||
type equal to their state type, and activating them with a
|
||||
particular parameter value is equivalent to changing their
|
||||
state to that value.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
This approach to handling radio buttons is different than many
|
||||
other action systems such as GtkAction. With GAction, there is
|
||||
only one action for "text-justify" and "left", "center" and
|
||||
"right" are possible states on that action. There are not three
|
||||
separate "justify-left", "justify-center" and "justify-right"
|
||||
actions.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The final common type of action is a stateless action with a
|
||||
parameter. This is typically used for actions like
|
||||
"open-bookmark" where the parameter to the action would be
|
||||
the identifier of the bookmark to open.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Because some types of actions cannot be invoked without a
|
||||
parameter, it is often important to specify a parameter when
|
||||
referring to the action from a place where it will be invoked
|
||||
(such as from a radio button that sets the state to a particular
|
||||
value or from a menu item that opens a specific bookmark). In
|
||||
these contexts, the value used for the action parameter is
|
||||
typically called the target of the action.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Even though toggle actions have a state, they do not have a
|
||||
parameter. Therefore, a target value is not needed when
|
||||
referring to them — they will always be toggled on activation.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Most APIs that allow using a GAction (such as GMenuModel and
|
||||
GtkActionable) allow use of detailed action names. This is a
|
||||
convenient way of specifying an action name and an action target
|
||||
with a single string.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
In the case that the action target is a string with no unusual
|
||||
characters (ie: only alpha-numeric, plus '-' and '.') then you
|
||||
can use a detailed action name of the form "justify::left" to
|
||||
specify the justify action with a target of left.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
In the case that the action target is not a string, or contains
|
||||
unusual characters, you can use the more general format
|
||||
"action-name(5)", where the "5" here is any valid text-format
|
||||
GVariant (ie: a string that can be parsed by g_variant_parse()).
|
||||
Another example is "open-bookmark('http://gnome.org/')".
|
||||
</para>
|
||||
|
||||
<para>
|
||||
You can convert between detailed action names and split-out
|
||||
action names and target values using g_action_parse_detailed_action_name()
|
||||
and g_action_print_detailed_action_name() but usually you will
|
||||
not need to. Most APIs will provide both ways of specifying
|
||||
actions with targets.
|
||||
</para>
|
||||
|
||||
</refsect2>
|
||||
|
||||
<refsect2>
|
||||
<title>Action scopes</title>
|
||||
|
||||
<para>
|
||||
Actions are always scoped to a particular object on which they
|
||||
operate.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
In GTK, actions are typically scoped to either an application
|
||||
or a window, but any widget can have actions associated with it.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Actions scoped to windows should be the actions that
|
||||
specifically impact that window. These are actions like
|
||||
"fullscreen" and "close", or in the case that a window contains
|
||||
a document, "save" and "print".
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Actions that impact the application as a whole rather than one
|
||||
specific window are scoped to the application. These are actions
|
||||
like "about" and "preferences".
|
||||
</para>
|
||||
|
||||
<para>
|
||||
If a particular action is scoped to a window then it is scoped
|
||||
to a specific window. Another way of saying this: if your
|
||||
application has a "fullscreen" action that applies to windows
|
||||
and it has three windows, then it will have three fullscreen
|
||||
actions: one for each window.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Having a separate action per-window allows for each window to
|
||||
have a separate state for each instance of the action as well
|
||||
as being able to control the enabled state of the action on a
|
||||
per-window basis.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Actions are added to their relevant scope (application or
|
||||
window) either using the GActionMap interface, or by using
|
||||
gtk_widget_insert_action_group().
|
||||
</para>
|
||||
|
||||
</refsect2>
|
||||
|
||||
<refsect2>
|
||||
<title>Action groups and action maps</title>
|
||||
|
||||
<para>
|
||||
Actions rarely occurs in isolation. It is common to have groups
|
||||
of related actions, which are represented by instances of the
|
||||
GActionGroup interface.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Action maps are a variant of action groups that allow to change
|
||||
the name of the action as it is looked up. In GTK, the convention
|
||||
is to add a prefix to the action name to indicate the scope of
|
||||
the actions, such as "app." for the actions with application scope
|
||||
or "win." for those with window scope.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
When referring to actions on a GActionMap only the name of the
|
||||
action itself is used (ie: "quit", not "app.quit"). The
|
||||
"app.quit" form is only used when referring to actions from
|
||||
places like a GMenu or GtkActionable widget where the scope
|
||||
of the action is not already known.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
GtkApplication and GtkApplicationWindow implement the GActionMap
|
||||
interface, so you can just add actions directly to them. For
|
||||
other widgets, use gtk_widget_insert_action_group() to add
|
||||
actions to it.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
If you want to insert several actions at the same time, it is
|
||||
typically faster and easier to use GActionEntry.
|
||||
</para>
|
||||
|
||||
</refsect2>
|
||||
|
||||
<refsect2>
|
||||
<title>Connecting actions to widgets</title>
|
||||
|
||||
<para>
|
||||
Any widget that implements the GtkActionable interface can
|
||||
be connected to an action just by setting the ::action-name
|
||||
property. If the action has a parameter, you will also need
|
||||
to set the ::action-target property.
|
||||
Widgets that implement GtkAction include GtkSwitch, GtkButton,
|
||||
GtkMenuItem and their respective subclasses.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Another of obtaining widgets that are connected to actions is
|
||||
to create a menu using a GMenu menu model. GMenu provides an
|
||||
abstract way to describe typical menus: nested groups of items
|
||||
where each item can have a label, and icon, and an action.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Typical uses of GMenu inside GTK are to set up an application
|
||||
menu or menubar with gtk_application_set_app_menu() or
|
||||
gtk_application_set_menubar(). Another, maybe more common use
|
||||
is to create a popover for a menubutton, using
|
||||
gtk_menu_button_set_menu_model().
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Unlike traditional menus, those created from menu models don't
|
||||
have keyboard accelerators associated with menu items. Instead,
|
||||
GtkApplication offers the gtk_application_set_accels_for_action()
|
||||
API to associate keyboard shortcuts with actions.
|
||||
</para>
|
||||
</refsect2>
|
||||
|
||||
<refsect2>
|
||||
<title>Activation</title>
|
||||
|
||||
<para>
|
||||
When a widget with a connected action is activated, GTK finds
|
||||
the action to activate by walking up the widget hierarchy,
|
||||
looking for a matching action, ending up at the GtkApplication.
|
||||
</para>
|
||||
</refsect2>
|
||||
|
||||
<refsect2>
|
||||
<title>Built-in Actions</title>
|
||||
|
||||
<para>
|
||||
GTK uses actions for its own purposes in a number places. These
|
||||
built-in actions can sometimes be activated by applications, and
|
||||
you should avoid naming conflicts with them when creating your
|
||||
own actions.
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>default.activate</term>
|
||||
<listitem><para>Activates the default widget in a context
|
||||
(typically a GtkWindow, GtkDialog or GtkPopover)
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</para>
|
||||
|
||||
</refsect2>
|
||||
|
||||
</refsect1>
|
||||
</refentry>
|
||||
@@ -12,7 +12,7 @@
|
||||
<refnamediv>
|
||||
<refname>The GTK Drawing Model</refname>
|
||||
<refpurpose>
|
||||
The GTK drawing model in detail
|
||||
How widgets draw
|
||||
</refpurpose>
|
||||
</refnamediv>
|
||||
|
||||
|
||||
@@ -24,8 +24,9 @@
|
||||
<xi:include href="xml/getting_started.xml"/>
|
||||
<xi:include href="resources.sgml" />
|
||||
<xi:include href="xml/question_index.sgml" />
|
||||
<xi:include href="drawing-model.xml" />
|
||||
<xi:include href="xml/drawing-model.xml" />
|
||||
<xi:include href="xml/input-handling.xml" />
|
||||
<xi:include href="xml/actions.xml" />
|
||||
</part>
|
||||
|
||||
<part id="gtkobjects">
|
||||
|
||||
@@ -362,6 +362,8 @@ gtk_list_box_get_selected_row
|
||||
GtkListBoxForeachFunc
|
||||
gtk_list_box_selected_foreach
|
||||
gtk_list_box_get_selected_rows
|
||||
gtk_list_box_set_show_separators
|
||||
gtk_list_box_get_show_separators
|
||||
|
||||
gtk_list_box_set_selection_mode
|
||||
gtk_list_box_get_selection_mode
|
||||
@@ -1777,7 +1779,6 @@ GtkMenu
|
||||
GtkArrowPlacement
|
||||
gtk_menu_new
|
||||
gtk_menu_new_from_model
|
||||
gtk_menu_set_display
|
||||
gtk_menu_reorder_child
|
||||
gtk_menu_popup_at_rect
|
||||
gtk_menu_popup_at_widget
|
||||
@@ -1819,11 +1820,6 @@ gtk_menu_get_type
|
||||
GtkMenuBar
|
||||
gtk_menu_bar_new
|
||||
gtk_menu_bar_new_from_model
|
||||
GtkPackDirection
|
||||
gtk_menu_bar_set_pack_direction
|
||||
gtk_menu_bar_get_pack_direction
|
||||
gtk_menu_bar_set_child_pack_direction
|
||||
gtk_menu_bar_get_child_pack_direction
|
||||
<SUBSECTION Standard>
|
||||
GTK_MENU_BAR
|
||||
GTK_IS_MENU_BAR
|
||||
@@ -4436,13 +4432,10 @@ gtk_widget_event
|
||||
gtk_widget_activate
|
||||
gtk_widget_is_focus
|
||||
gtk_widget_grab_focus
|
||||
gtk_widget_grab_default
|
||||
gtk_widget_set_name
|
||||
gtk_widget_get_name
|
||||
gtk_widget_set_sensitive
|
||||
gtk_widget_set_parent
|
||||
gtk_widget_set_parent_surface
|
||||
gtk_widget_get_parent_surface
|
||||
gtk_widget_get_toplevel
|
||||
gtk_widget_get_root
|
||||
gtk_widget_get_ancestor
|
||||
@@ -4507,16 +4500,15 @@ gtk_widget_compute_bounds
|
||||
gtk_widget_compute_transform
|
||||
gtk_widget_compute_point
|
||||
gtk_widget_contains
|
||||
GtkPickFlags
|
||||
gtk_widget_pick
|
||||
gtk_widget_get_can_default
|
||||
gtk_widget_set_can_default
|
||||
gtk_widget_get_can_focus
|
||||
gtk_widget_set_can_focus
|
||||
gtk_widget_get_focus_on_click
|
||||
gtk_widget_set_focus_on_click
|
||||
gtk_widget_set_focus_child
|
||||
gtk_widget_get_can_pick
|
||||
gtk_widget_set_can_pick
|
||||
gtk_widget_get_can_target
|
||||
gtk_widget_set_can_target
|
||||
gtk_widget_get_has_surface
|
||||
gtk_widget_set_has_surface
|
||||
gtk_widget_get_sensitive
|
||||
@@ -4542,13 +4534,15 @@ gtk_widget_get_realized
|
||||
gtk_widget_get_mapped
|
||||
gtk_widget_device_is_shadowed
|
||||
gtk_widget_get_modifier_mask
|
||||
gtk_widget_insert_action_group
|
||||
gtk_widget_get_opacity
|
||||
gtk_widget_set_opacity
|
||||
gtk_widget_get_overflow
|
||||
gtk_widget_set_overflow
|
||||
gtk_widget_insert_action_group
|
||||
gtk_widget_list_action_prefixes
|
||||
gtk_widget_get_action_group
|
||||
gtk_widget_activate_action
|
||||
gtk_widget_activate_default
|
||||
gtk_widget_measure
|
||||
gtk_widget_snapshot_child
|
||||
gtk_widget_get_next_sibling
|
||||
@@ -4651,8 +4645,6 @@ gtk_window_set_resizable
|
||||
gtk_window_get_resizable
|
||||
gtk_window_add_accel_group
|
||||
gtk_window_remove_accel_group
|
||||
gtk_window_activate_focus
|
||||
gtk_window_activate_default
|
||||
gtk_window_set_modal
|
||||
gtk_window_set_default_size
|
||||
gtk_window_set_hide_on_close
|
||||
@@ -4675,7 +4667,7 @@ gtk_window_propagate_key_event
|
||||
gtk_window_get_focus
|
||||
gtk_window_set_focus
|
||||
gtk_window_get_default_widget
|
||||
gtk_window_set_default
|
||||
gtk_window_set_default_widget
|
||||
gtk_window_present
|
||||
gtk_window_present_with_time
|
||||
gtk_window_close
|
||||
@@ -4696,9 +4688,6 @@ gtk_window_set_decorated
|
||||
gtk_window_set_deletable
|
||||
gtk_window_set_mnemonic_modifier
|
||||
gtk_window_set_type_hint
|
||||
gtk_window_set_skip_taskbar_hint
|
||||
gtk_window_set_skip_pager_hint
|
||||
gtk_window_set_urgency_hint
|
||||
gtk_window_set_accept_focus
|
||||
gtk_window_set_focus_on_map
|
||||
gtk_window_set_startup_id
|
||||
@@ -4715,9 +4704,6 @@ gtk_window_get_title
|
||||
gtk_window_get_transient_for
|
||||
gtk_window_get_attached_to
|
||||
gtk_window_get_type_hint
|
||||
gtk_window_get_skip_taskbar_hint
|
||||
gtk_window_get_skip_pager_hint
|
||||
gtk_window_get_urgency_hint
|
||||
gtk_window_get_accept_focus
|
||||
gtk_window_get_focus_on_map
|
||||
gtk_window_get_group
|
||||
@@ -5078,27 +5064,28 @@ gtk_border_get_type
|
||||
<FILE>gtkcssprovider</FILE>
|
||||
<TITLE>GtkCssProvider</TITLE>
|
||||
GtkCssProvider
|
||||
gtk_css_provider_get_named
|
||||
gtk_css_provider_load_named
|
||||
gtk_css_provider_load_from_data
|
||||
gtk_css_provider_load_from_file
|
||||
gtk_css_provider_load_from_path
|
||||
gtk_css_provider_load_from_resource
|
||||
gtk_css_provider_new
|
||||
gtk_css_provider_to_string
|
||||
GTK_CSS_PROVIDER_ERROR
|
||||
GtkCssProviderError
|
||||
GTK_CSS_PARSER_ERROR
|
||||
GtkCssParserError
|
||||
GtkCssParserWarning
|
||||
<SUBSECTION>
|
||||
GtkCssLocation
|
||||
GtkCssSection
|
||||
GtkCssSectionType
|
||||
gtk_css_section_get_end_line
|
||||
gtk_css_section_get_end_position
|
||||
gtk_css_section_get_file
|
||||
gtk_css_section_get_parent
|
||||
gtk_css_section_get_section_type
|
||||
gtk_css_section_get_start_line
|
||||
gtk_css_section_get_start_position
|
||||
gtk_css_section_new
|
||||
gtk_css_section_ref
|
||||
gtk_css_section_unref
|
||||
gtk_css_section_print
|
||||
gtk_css_section_to_string
|
||||
gtk_css_section_get_file
|
||||
gtk_css_section_get_parent
|
||||
gtk_css_section_get_start_location
|
||||
gtk_css_section_get_end_location
|
||||
<SUBSECTION Standard>
|
||||
GTK_TYPE_CSS_PROVIDER
|
||||
GTK_CSS_PROVIDER
|
||||
|
||||
@@ -4,15 +4,15 @@
|
||||
]>
|
||||
<refentry id="chap-input-handling">
|
||||
<refmeta>
|
||||
<refentrytitle>The GTK Input and Event Handling Model</refentrytitle>
|
||||
<refentrytitle>The GTK Input Model</refentrytitle>
|
||||
<manvolnum>3</manvolnum>
|
||||
<refmiscinfo>GTK Library</refmiscinfo>
|
||||
</refmeta>
|
||||
|
||||
<refnamediv>
|
||||
<refname>The GTK Input and Event Handling Model</refname>
|
||||
<refname>The GTK Input Model</refname>
|
||||
<refpurpose>
|
||||
GTK input and event handling in detail
|
||||
input and event handling in detail
|
||||
</refpurpose>
|
||||
</refnamediv>
|
||||
|
||||
@@ -52,13 +52,12 @@
|
||||
with any pointing device or keyboard.
|
||||
</para>
|
||||
|
||||
<!-- input events: button, touch, key, motion, etc -->
|
||||
<para>
|
||||
When a user interacts with an input device (e.g. moves a mouse or presses
|
||||
a key on the keyboard), GTK receives events from the windowing system.
|
||||
These are typically directed at a specific window - for pointer events,
|
||||
the window under the pointer (grabs complicate this), for keyboard events,
|
||||
the window with the keyboard focus.
|
||||
These are typically directed at a specific surface - for pointer events,
|
||||
the surface under the pointer (grabs complicate this), for keyboard events,
|
||||
the surface with the keyboard focus.
|
||||
</para>
|
||||
<para>
|
||||
GDK translates these raw windowing system events into #GdkEvents.
|
||||
@@ -81,9 +80,10 @@
|
||||
</simplelist>
|
||||
</para>
|
||||
<para>
|
||||
When GTK is initialized, it sets up an event handler function with
|
||||
gdk_event_handler_set(), which receives all of these input events
|
||||
(as well as others, for instance window management related events).
|
||||
When GTK creates a GdkSurface, it connects to the ::event signal
|
||||
on it, which receives all of these input events. Surfaces have
|
||||
have signals and properties, e.g. to deal with window management
|
||||
related events.
|
||||
</para>
|
||||
</refsect2>
|
||||
|
||||
@@ -91,8 +91,8 @@
|
||||
<title>Event propagation</title>
|
||||
|
||||
<para>
|
||||
For widgets which have a #GdkSurface set, events are received from the
|
||||
windowing system and passed to gtk_main_do_event(). See its documentation
|
||||
The function which initially receives input events on the GTK
|
||||
side is gtk_main_do_event(). See its documentation
|
||||
for details of what it does: compression of enter/leave events,
|
||||
identification of the widget receiving the event, pushing the event onto a
|
||||
stack for gtk_get_current_event(), and propagating the event to the
|
||||
@@ -120,62 +120,55 @@
|
||||
|
||||
<para>
|
||||
An event is propagated to a widget using gtk_propagate_event().
|
||||
Propagation differs between event types: key events (%GDK_KEY_PRESS,
|
||||
%GDK_KEY_RELEASE) are delivered to the top-level #GtkWindow; other events
|
||||
are propagated down and up the widget hierarchy in three phases (see
|
||||
#GtkPropagationPhase).
|
||||
Propagation goes down and up the widget hierarchy in three phases
|
||||
(see #GtkPropagationPhase) towards a target widget.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
For key events, the top-level window’s default #GtkWindow::key-press-event
|
||||
and #GtkWindow::key-release-event signal handlers handle mnemonics and
|
||||
accelerators first. Other key presses are then passed to
|
||||
gtk_window_propagate_key_event() which propagates the event upwards from
|
||||
the window’s current focus widget (gtk_window_get_focus()) to the
|
||||
top-level.
|
||||
For key events, the top-level window gets a first shot at activating
|
||||
mnemonics and accelerators. If that does not consume the events,
|
||||
the target widget for event propagation is window's current focus
|
||||
widget (see gtk_window_get_focus()).
|
||||
</para>
|
||||
|
||||
<para>
|
||||
For other events, in the first phase (the “capture” phase) the event is
|
||||
delivered to each widget from the top-most (for example, the top-level
|
||||
For pointer events, the target widget is determined by picking
|
||||
the widget at the events coordinates (see gtk_window_pick()).
|
||||
</para>
|
||||
|
||||
<para>In the first phase (the “capture” phase) the event is
|
||||
delivered to each widget from the top-most (the top-level
|
||||
#GtkWindow or grab widget) down to the target #GtkWidget.
|
||||
<link linkend="event-controllers-and-gestures">Gestures</link> that are
|
||||
attached with %GTK_PHASE_CAPTURE get a chance to react to the event.
|
||||
<link linkend="event-controllers-and-gestures">Event
|
||||
controllers</link> that are attached with %GTK_PHASE_CAPTURE
|
||||
get a chance to react to the event.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
After the “capture” phase, the widget that was intended to be the
|
||||
destination of the event will run gestures attached to it with
|
||||
%GTK_PHASE_TARGET. This is known as the “target” phase, and only
|
||||
happens on that widget.
|
||||
destination of the event will run event controllers attached to
|
||||
it with %GTK_PHASE_TARGET. This is known as the “target” phase,
|
||||
and only happens on that widget.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Next, the #GtkWidget::event signal is emitted.
|
||||
Handling these signals was the primary way to handle input in GTK widgets
|
||||
before gestures were introduced. The signal is emitted from
|
||||
the target widget up to the top-level, as part of the “bubble” phase.
|
||||
In the last phase (the “bubble” phase), the event is delivered
|
||||
to each widget from the target to the top-most, and event
|
||||
controllers attached with %GTK_PHASE_BUBBLE are run.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The default handlers for the event signals send the event
|
||||
to gestures that are attached with %GTK_PHASE_BUBBLE. Therefore,
|
||||
gestures in the “bubble” phase are only used if the widget does
|
||||
not have its own event handlers, or takes care to chain up to the
|
||||
default #GtkWidget handlers.
|
||||
Events are not delivered to a widget which is insensitive or
|
||||
unmapped.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Events are not delivered to a widget which is insensitive or unmapped.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Any time during the propagation phase, a widget may indicate that a
|
||||
received event was consumed and propagation should therefore be stopped.
|
||||
In traditional event handlers, this is hinted by returning %GDK_EVENT_STOP.
|
||||
If gestures are used, this may happen when the widget tells the gesture
|
||||
to claim the event touch sequence (or the pointer events) for its own. See the
|
||||
"gesture states" section below to know more of the latter.
|
||||
Any time during the propagation phase, a controller may indicate
|
||||
that a received event was consumed and propagation should
|
||||
therefore be stopped. If gestures are used, this may happen
|
||||
when the gesture claims the event touch sequence (or the
|
||||
pointer events) for its own. See the “gesture states” section
|
||||
below to learn more about gestures and sequences.
|
||||
</para>
|
||||
</refsect2>
|
||||
|
||||
@@ -183,27 +176,10 @@
|
||||
<title>Touch events</title>
|
||||
|
||||
<para>
|
||||
Touch events are emitted as events of type %GDK_TOUCH_BEGIN, %GDK_TOUCH_UPDATE or
|
||||
%GDK_TOUCH_END, those events contain an “event sequence” that univocally identifies
|
||||
the physical touch until it is lifted from the device.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
On some windowing platforms, multitouch devices perform pointer emulation, this works
|
||||
by granting a “pointer emulating” hint to one of the currently interacting touch
|
||||
sequences, which will be reported on every #GdkEventTouch event from that sequence. By
|
||||
default, if a widget didn't request touch events by setting %GDK_TOUCH_MASK on its
|
||||
event mask and didn't override #GtkWidget::touch-event, GTK will transform these
|
||||
“pointer emulating” events into semantically similar #GdkEventButton and #GdkEventMotion
|
||||
events. Depending on %GDK_TOUCH_MASK being in the event mask or not, non-pointer-emulating
|
||||
sequences could still trigger gestures or just get filtered out, regardless of the widget
|
||||
not handling those directly.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
If the widget sets %GDK_TOUCH_MASK on its event mask and doesn't chain up on
|
||||
#GtkWidget::touch-event, only touch events will be received, and no pointer emulation
|
||||
will be performed.
|
||||
Touch events are emitted as events of type %GDK_TOUCH_BEGIN,
|
||||
%GDK_TOUCH_UPDATE or %GDK_TOUCH_END, those events contain an
|
||||
“event sequence” that univocally identifies the physical touch
|
||||
until it is lifted from the device.
|
||||
</para>
|
||||
</refsect2>
|
||||
|
||||
@@ -211,43 +187,66 @@
|
||||
<title>Grabs</title>
|
||||
|
||||
<para>
|
||||
Grabs are a method to claim all input events from a device, they happen
|
||||
either implicitly on pointer and touch devices, or explicitly. Implicit grabs
|
||||
happen on user interaction, when a #GdkEventButtonPress happens, all events from
|
||||
then on, until after the corresponding #GdkEventButtonRelease, will be reported
|
||||
to the widget that got the first event. Likewise, on touch events, every
|
||||
#GdkEventSequence will deliver only events to the widget that received its
|
||||
%GDK_TOUCH_BEGIN event.
|
||||
Grabs are a method to claim all input events from a device,
|
||||
they happen either implicitly on pointer and touch devices,
|
||||
or explicitly. Implicit grabs happen on user interaction, when
|
||||
a #GdkEventButtonPress happens, all events from then on, until
|
||||
after the corresponding #GdkEventButtonRelease, will be reported
|
||||
to the widget that got the first event. Likewise, on touch events,
|
||||
every #GdkEventSequence will deliver only events to the widget
|
||||
that received its %GDK_TOUCH_BEGIN event.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Explicit grabs happen programatically (both activation and deactivation),
|
||||
and can be either system-wide (GDK grabs) or application-wide (GTK grabs).
|
||||
On the windowing platforms that support it, GDK grabs will prevent any
|
||||
interaction with any other application/window/widget than the grabbing one,
|
||||
whereas GTK grabs will be effective only within the application (across all
|
||||
its windows), still allowing for interaction with other applications.
|
||||
Explicit grabs happen programatically (both activation and
|
||||
deactivation), and can be either system-wide (GDK grabs) or
|
||||
application-wide (GTK grabs). On the windowing platforms that
|
||||
support it, GDK grabs will prevent any interaction with any other
|
||||
application/window/widget than the grabbing one, whereas GTK grabs
|
||||
will be effective only within the application (across all its
|
||||
windows), still allowing for interaction with other applications.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
But one important aspect of grabs is that they may potentially happen at any
|
||||
point somewhere else, even while the pointer/touch device is already grabbed.
|
||||
This makes it necessary for widgets to handle the cancellation of any ongoing
|
||||
interaction. Depending on whether a GTK or GDK grab is causing this, the
|
||||
widget will respectively receive a #GtkWidget::grab-notify signal, or a
|
||||
But one important aspect of grabs is that they may potentially
|
||||
happen at any point somewhere else, even while the pointer/touch
|
||||
device is already grabbed. This makes it necessary for widgets to
|
||||
handle the cancellation of any ongoing interaction. Depending on
|
||||
whether a GTK or GDK grab is causing this, the widget will
|
||||
respectively receive a #GtkWidget::grab-notify signal, or a
|
||||
#GdkEventGrabBroken event.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
On gestures, these signals are handled automatically, causing the gesture
|
||||
to cancel all tracked pointer/touch events, and signal the end of recognition.
|
||||
On gestures, these signals are handled automatically, causing the
|
||||
gesture to cancel all tracked pointer/touch events, and signal
|
||||
the end of recognition.
|
||||
</para>
|
||||
</refsect2>
|
||||
|
||||
<refsect2>
|
||||
<title>Keyboard input</title>
|
||||
|
||||
<!-- focus, tab, directional navigation -->
|
||||
<para>
|
||||
Every #GtkWindow maintains a single focus location (in
|
||||
the ::focus-widget property). The focus widget is the
|
||||
target widget for key events sent to the window. Only
|
||||
widgets which have ::can-focus set to %TRUE can become
|
||||
the focus. Typically these are input controls such as
|
||||
entries or text fields, but e.g. buttons can take the
|
||||
focus too.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Input widgets can be given the focus by clicking on them,
|
||||
but focus can also be moved around with certain key
|
||||
events (this is known as “keyboard navigation”). GTK
|
||||
reserves the Tab key to move the focus to the next location,
|
||||
and Shift-Tab to move it back to the previous one. In addition
|
||||
many containers allow “directional navigation” with the
|
||||
arrow keys.
|
||||
</para>
|
||||
|
||||
<!-- mnemonics, accelerators, bindings -->
|
||||
</refsect2>
|
||||
|
||||
@@ -255,37 +254,43 @@
|
||||
<title>Event controllers and gestures</title>
|
||||
|
||||
<para>
|
||||
Event controllers are standalone objects that can perform specific actions
|
||||
upon received #GdkEvents. These are tied to a #GtkWidget, and can be told of
|
||||
the event propagation phase at which they will manage the events.
|
||||
Event controllers are standalone objects that can perform
|
||||
specific actions upon received #GdkEvents. These are tied
|
||||
to a #GtkWidget, and can be told of the event propagation
|
||||
phase at which they will manage the events.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Gestures are a set of specific controllers that are prepared to handle pointer
|
||||
and/or touch events, each gestures implementation attempts to recognize specific
|
||||
actions out the received events, notifying of the state/progress accordingly to
|
||||
let the widget react to those. On multi-touch gestures, every interacting touch
|
||||
sequence will be tracked independently.
|
||||
Gestures are a set of specific controllers that are prepared
|
||||
to handle pointer and/or touch events, each gesture
|
||||
implementation attempts to recognize specific actions out the
|
||||
received events, notifying of the state/progress accordingly to
|
||||
let the widget react to those. On multi-touch gestures, every
|
||||
interacting touch sequence will be tracked independently.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Being gestures “simple” units, it is not uncommon to tie several together to
|
||||
perform higher level actions, grouped gestures handle the same event sequences
|
||||
simultaneously, and those sequences share a same state across all grouped
|
||||
Since gestures are “simple” units, it is not uncommon to tie
|
||||
several together to perform higher level actions, grouped
|
||||
gestures handle the same event sequences simultaneously, and
|
||||
those sequences share a same state across all grouped
|
||||
gestures. Some examples of grouping may be:
|
||||
|
||||
<simplelist>
|
||||
<member>
|
||||
A “drag” and a “swipe” gestures may want grouping. The former will report
|
||||
events as the dragging happens, the latter will tell the swipe X/Y velocities
|
||||
only after gesture has finished.
|
||||
A “drag” and a “swipe” gestures may want grouping.
|
||||
The former will report events as the dragging happens,
|
||||
the latter will tell the swipe X/Y velocities only after
|
||||
recognition has finished.
|
||||
</member>
|
||||
<member>
|
||||
Grouping a “drag” gesture with a “pan” gesture will only effectively allow
|
||||
dragging in the panning orientation, as both gestures share state.
|
||||
Grouping a “drag” gesture with a “pan” gesture will only
|
||||
effectively allow dragging in the panning orientation, as
|
||||
both gestures share state.
|
||||
</member>
|
||||
<member>
|
||||
If “press” and “long press” are wanted simultaneously, those would need grouping.
|
||||
If “press” and “long press” are wanted simultaneously,
|
||||
those would need grouping.
|
||||
</member>
|
||||
</simplelist>
|
||||
</para>
|
||||
@@ -294,34 +299,39 @@
|
||||
<refsect2>
|
||||
<title>Gesture states</title>
|
||||
<para>
|
||||
Gestures have a notion of “state” for each individual touch sequence. When events
|
||||
from a touch sequence are first received, the touch sequence will have “none” state,
|
||||
this means the touch sequence is being handled by the gesture to possibly trigger
|
||||
Gestures have a notion of “state” for each individual touch
|
||||
sequence. When events from a touch sequence are first received,
|
||||
the touch sequence will have “none” state, this means the touch
|
||||
sequence is being handled by the gesture to possibly trigger
|
||||
actions, but the event propagation will not be stopped.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
When the gesture enters recognition, or at a later point in time, the widget may
|
||||
choose to claim the touch sequences (individually or as a group), hence stopping
|
||||
event propagation after the event is run through every gesture in that widget and
|
||||
propagation phase. Anytime this happens, the touch sequences are cancelled downwards
|
||||
the propagation chain, to let these know that no further events will be sent.
|
||||
When the gesture enters recognition, or at a later point in time,
|
||||
the widget may choose to claim the touch sequences (individually
|
||||
or as a group), hence stopping event propagation after the event
|
||||
is run through every gesture in that widget and propagation phase.
|
||||
Anytime this happens, the touch sequences are cancelled downwards
|
||||
the propagation chain, to let these know that no further events
|
||||
will be sent.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Alternatively, or at a later point in time, the widget may choose to deny the touch
|
||||
sequences, thus letting those go through again in event propagation. When this happens
|
||||
in the capture phase, and if there are no other claiming gestures in the widget,
|
||||
Alternatively, or at a later point in time, the widget may choose
|
||||
to deny the touch sequences, thus letting those go through again
|
||||
in event propagation. When this happens in the capture phase, and
|
||||
if there are no other claiming gestures in the widget,
|
||||
a %GDK_TOUCH_BEGIN/%GDK_BUTTON_PRESS event will be emulated and
|
||||
propagated downwards, in order to preserve consistency.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Grouped gestures always share the same state for a given touch sequence, so setting
|
||||
the state on one does transfer the state to the others. They also are mutually exclusive,
|
||||
within a widget there may be only one gesture group claiming a given sequence. If
|
||||
another gesture group claims later that same sequence, the first group will deny the
|
||||
sequence.
|
||||
Grouped gestures always share the same state for a given touch
|
||||
sequence, so setting the state on one does transfer the state to
|
||||
the others. They also are mutually exclusive, within a widget
|
||||
there may be only one gesture group claiming a given sequence.
|
||||
If another gesture group claims later that same sequence, the
|
||||
first group will deny the sequence.
|
||||
</para>
|
||||
</refsect2>
|
||||
|
||||
|
||||
@@ -333,6 +333,7 @@ images = [
|
||||
]
|
||||
|
||||
content_files = [
|
||||
'actions.xml',
|
||||
'broadway.xml',
|
||||
'building.sgml',
|
||||
'compiling.sgml',
|
||||
@@ -368,6 +369,7 @@ content_files = [
|
||||
]
|
||||
|
||||
expand_content_files = [
|
||||
'actions.xml',
|
||||
'compiling.sgml',
|
||||
'drawing-model.xml',
|
||||
'glossary.xml',
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
compared to GTK 3.x. Thankfully, most of the changes are not hard
|
||||
to adapt to and there are a number of steps that you can take to
|
||||
prepare your GTK 3.x application for the switch to GTK 4. After
|
||||
that, there's a small number of adjustments that you may have to do
|
||||
that, there's a number of adjustments that you may have to do
|
||||
when you actually switch your application to build against GTK 4.
|
||||
</para>
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
The steps outlined in the following sections assume that your
|
||||
application is working with GTK 3.24, which is the final stable
|
||||
release of GTK 3.x. It includes all the necessary APIs and tools
|
||||
to help you port your application to GTK 4. If you are still using
|
||||
to help you port your application to GTK 4. If you are using
|
||||
an older version of GTK 3.x, you should first get your application
|
||||
to build and work with the latest minor release in the 3.24 series.
|
||||
</para>
|
||||
@@ -84,9 +84,9 @@
|
||||
</para>
|
||||
<para>
|
||||
GTK 4 also removes the GDK_WA_VISUAL flag, and always uses
|
||||
an RGBA visual for windows. To prepare your code for this,
|
||||
use gdk_window_set_visual (gdk_screen_get_rgba_visual ()) after
|
||||
creating your window.
|
||||
an RGBA visual for windows. To prepare your code for this, use
|
||||
<literal>gdk_window_set_visual (gdk_screen_get_rgba_visual ())</literal>
|
||||
after creating your window.
|
||||
</para>
|
||||
<para>
|
||||
GTK 4 also removes the GDK_WA_WMCLASS flag. If you need this
|
||||
@@ -110,7 +110,7 @@
|
||||
<section>
|
||||
<title>Stop using GtkBox:padding, GtkBox:fill and GtkBox:expand</title>
|
||||
<para>
|
||||
GTK4 removes these #GtkBox child properties, so you should not use them.
|
||||
GTK 4 removes these #GtkBox child properties, so you should not use them.
|
||||
You can replace GtkBox:padding using the #GtkWidget:margin properties
|
||||
on your #GtkBox child widgets.
|
||||
</para>
|
||||
@@ -172,35 +172,30 @@
|
||||
<section>
|
||||
<title>Stop using GtkWidget event signals</title>
|
||||
<para>
|
||||
Event controllers and #GtkGestures replace event signals in GTK 4. They
|
||||
have been backported to GTK 3.x so you can prepare for this change.
|
||||
Event controllers and #GtkGestures replace event signals in GTK 4.
|
||||
They have been backported to GTK 3.x so you can prepare for this change.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Set a proper app_id</title>
|
||||
<title>Set a proper application ID</title>
|
||||
<para>
|
||||
In GTK4 we want the application's #GApplication
|
||||
In GTK 4 we want the application's #GApplication
|
||||
'application-id' (and therefore the D-Bus name), the desktop
|
||||
file basename and Wayland's xdg-shell app_id to match. In
|
||||
order to achieve this with GTK3 call g_set_prgname() with the same
|
||||
application id you passed to #GtkApplication. Rename your
|
||||
desktop files to match the application id if needed.
|
||||
order to achieve this with GTK 3.x call g_set_prgname() with the same
|
||||
application ID you passed to #GtkApplication. Rename your
|
||||
desktop files to match the application ID if needed.
|
||||
</para>
|
||||
<para>
|
||||
The call to g_set_prgname() can be removed once you fully migrated
|
||||
to GTK4.
|
||||
to GTK 4.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Stop using GtkBox's pack-type child property</title>
|
||||
<para>
|
||||
In order to improve performance and simplify the widget, GtkBox lost its
|
||||
'pack-type' child property. In GTK4, every GtkBox instance has a simple
|
||||
list of child widgets that it allocates from start to end.
|
||||
The old behavior of pack-type=END can be emulated by simply making the
|
||||
box child in the center hexpand and right-align the ones at the end.
|
||||
You should be aware that changing the application ID makes your
|
||||
application appear as a new, different app to application installers.
|
||||
You should consult the appstream documentation for best practices
|
||||
around renaming applications.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
@@ -216,6 +211,17 @@
|
||||
have been either impossible or impractical.
|
||||
</para>
|
||||
|
||||
<section>
|
||||
<title>Convert your ui files</title>
|
||||
|
||||
<para>
|
||||
A number of the changes outlined below affect .ui files. The
|
||||
gtk4-builder-tool simplify command can perform many of the
|
||||
necessary changes automatically, when called with the --3to4
|
||||
option. You should always review the resulting changes.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Stop using GdkScreen</title>
|
||||
<para>
|
||||
@@ -301,9 +307,9 @@
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Adapt to coordinate api changes</title>
|
||||
<title>Adapt to coordinate API changes</title>
|
||||
<para>
|
||||
A number of coordinate apis in GTK 3 had _double variants:
|
||||
A number of coordinate APIs in GTK 3 had _double variants:
|
||||
gdk_device_get_position(), gdk_device_get_surface_at_position(),
|
||||
gdk_surface_get_device_position(). These have been changed to use
|
||||
doubles, and the _double variants have been removed. Update your
|
||||
@@ -395,6 +401,10 @@
|
||||
their #GError argument. If you want to handle CSS loading errors,
|
||||
use the #GtkCssProvider::parsing-error signal instead.
|
||||
</para>
|
||||
<para>
|
||||
gtk_css_provider_get_named() has been replaced by
|
||||
gtk_css_provider_load_named().
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
@@ -411,7 +421,7 @@
|
||||
<para>
|
||||
GTK 3 used five different virtual functions in GtkWidget to
|
||||
implement size requisition, namely the gtk_widget_get_preferred_width()
|
||||
family of functions. To simplify widget implementations, GTK4 uses
|
||||
family of functions. To simplify widget implementations, GTK 4 uses
|
||||
only one virtual function, GtkWidgetClass::measure() that widgets
|
||||
have to implement.
|
||||
</para>
|
||||
@@ -640,7 +650,7 @@
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Adapt to changes in the API of GtkEntry, GtkSearchEntry adn GtkSpinButton</title>
|
||||
<title>Adapt to changes in the API of GtkEntry, GtkSearchEntry and GtkSpinButton</title>
|
||||
<para>
|
||||
The GtkEditable has been made more useful, and the core functionality of
|
||||
GtkEntry has been broken out as a GtkText widget. GtkEntry, GtkSearchEntry,
|
||||
@@ -675,6 +685,77 @@
|
||||
of the existing GtkFixed container widget.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Adapt to search entry changes</title>
|
||||
<para>
|
||||
The way search entries are connected to global events has changed;
|
||||
gtk_search_entry_handle_event() has been dropped and replaced by
|
||||
gtk_search_entry_set_key_capture_widget() and
|
||||
gtk_event_controller_key_forward().
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Stop using child properties</title>
|
||||
<para>
|
||||
GtkContainer no longer provides facilities for defining and using
|
||||
child properties. If you have custom widgets using child properties,
|
||||
they will have to be converted either to layout properties provided
|
||||
by a layout manager (if they are layout-related), or handled in
|
||||
some other way. One possibility is to use child meta objects,
|
||||
as seen with GtkAssistantPage, GtkStackPage and the like.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Stop using tabular menus</title>
|
||||
<para>
|
||||
Tabular menus were rarely used and complicated the menu code,
|
||||
so they have been removed. If you need complex layout in menu-like
|
||||
popups, consider using a #GtkPopover instead.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Stop using gtk_menu_set_display()</title>
|
||||
<para>
|
||||
This function has been removed. Menus should always be
|
||||
attached to a widget and get their display that way.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Stop using gtk_window_activate_default()</title>
|
||||
<para>
|
||||
The handling of default widgets has been changed, and activating
|
||||
the default now works by calling gtk_widget_activate_default()
|
||||
on the widget that caused the activation.
|
||||
</para>
|
||||
<para>
|
||||
If you have a custom widget that wants to override the default
|
||||
handling, you can provide an implementation of the default.activate
|
||||
action in your widgets' action groups.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Stop setting ::has-default and ::has-focus in .ui files</title>
|
||||
<para>
|
||||
The special handling for the ::has-default and ::has-focus properties
|
||||
has been removed. If you want to define the initial focus or the
|
||||
the default widget in a .ui file, set the ::default-widget or
|
||||
::focus-widget properties of the toplevel window.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Stop using the GtkWidget::display-changed signal</title>
|
||||
<para>
|
||||
To track the current display, use the GtkWidget::root property
|
||||
instead.
|
||||
</para>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
</chapter>
|
||||
|
||||
@@ -79,12 +79,30 @@ Use a GdkPixbuf in combination with GtkImage to display images.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>graphene</term>
|
||||
<listitem><para>
|
||||
This is a small library which provides vector and matrix datatypes
|
||||
and operations. graphene provides optimized implementations using
|
||||
various SIMD instruction sets such as SSE.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>GDK</term>
|
||||
<listitem><para>
|
||||
GDK is the abstraction layer that allows GTK to support multiple
|
||||
windowing systems. GDK provides window system facilities on X11, Windows,
|
||||
and OS X.
|
||||
windowing systems. GDK provides window system facilities on Wayland,
|
||||
X11, Windows, and OS X.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>GSK</term>
|
||||
<listitem><para>
|
||||
GSK is a library for creating a scene graph from render nodes,
|
||||
and rendering it using different rendering APIs. GSK provides renderers
|
||||
for OpenGL, Vulkan and cairo.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
|
||||
@@ -473,24 +473,6 @@ gdk_broadway_surface_set_modal_hint (GdkSurface *surface,
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_broadway_surface_set_skip_taskbar_hint (GdkSurface *surface,
|
||||
gboolean skips_taskbar)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_broadway_surface_set_skip_pager_hint (GdkSurface *surface,
|
||||
gboolean skips_pager)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_broadway_surface_set_urgency_hint (GdkSurface *surface,
|
||||
gboolean urgent)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_broadway_surface_set_geometry_hints (GdkSurface *surface,
|
||||
const GdkGeometry *geometry,
|
||||
@@ -800,22 +782,6 @@ gdk_broadway_surface_set_keep_below (GdkSurface *surface, gboolean setting)
|
||||
|
||||
}
|
||||
|
||||
static GdkSurface *
|
||||
gdk_broadway_surface_get_group (GdkSurface *surface)
|
||||
{
|
||||
if (GDK_SURFACE_DESTROYED (surface) ||
|
||||
!SURFACE_IS_TOPLEVEL (surface))
|
||||
return NULL;
|
||||
|
||||
return surface;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_broadway_surface_set_group (GdkSurface *surface,
|
||||
GdkSurface *leader)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_broadway_surface_set_decorations (GdkSurface *surface,
|
||||
GdkWMDecoration decorations)
|
||||
@@ -1356,9 +1322,6 @@ gdk_surface_impl_broadway_class_init (GdkSurfaceImplBroadwayClass *klass)
|
||||
impl_class->set_type_hint = gdk_broadway_surface_set_type_hint;
|
||||
impl_class->get_type_hint = gdk_broadway_surface_get_type_hint;
|
||||
impl_class->set_modal_hint = gdk_broadway_surface_set_modal_hint;
|
||||
impl_class->set_skip_taskbar_hint = gdk_broadway_surface_set_skip_taskbar_hint;
|
||||
impl_class->set_skip_pager_hint = gdk_broadway_surface_set_skip_pager_hint;
|
||||
impl_class->set_urgency_hint = gdk_broadway_surface_set_urgency_hint;
|
||||
impl_class->set_geometry_hints = gdk_broadway_surface_set_geometry_hints;
|
||||
impl_class->set_title = gdk_broadway_surface_set_title;
|
||||
impl_class->set_startup_id = gdk_broadway_surface_set_startup_id;
|
||||
@@ -1378,8 +1341,6 @@ gdk_surface_impl_broadway_class_init (GdkSurfaceImplBroadwayClass *klass)
|
||||
impl_class->unfullscreen = gdk_broadway_surface_unfullscreen;
|
||||
impl_class->set_keep_above = gdk_broadway_surface_set_keep_above;
|
||||
impl_class->set_keep_below = gdk_broadway_surface_set_keep_below;
|
||||
impl_class->get_group = gdk_broadway_surface_get_group;
|
||||
impl_class->set_group = gdk_broadway_surface_set_group;
|
||||
impl_class->set_decorations = gdk_broadway_surface_set_decorations;
|
||||
impl_class->get_decorations = gdk_broadway_surface_get_decorations;
|
||||
impl_class->set_functions = gdk_broadway_surface_set_functions;
|
||||
|
||||
@@ -145,6 +145,7 @@ static const GDebugKey gdk_debug_keys[] = {
|
||||
{ "gl-texture-rect", GDK_DEBUG_GL_TEXTURE_RECT },
|
||||
{ "gl-legacy", GDK_DEBUG_GL_LEGACY },
|
||||
{ "gl-gles", GDK_DEBUG_GL_GLES },
|
||||
{ "gl-debug", GDK_DEBUG_GL_DEBUG },
|
||||
{ "vulkan-disable", GDK_DEBUG_VULKAN_DISABLE },
|
||||
{ "vulkan-validate", GDK_DEBUG_VULKAN_VALIDATE }
|
||||
};
|
||||
|
||||
+36
-3
@@ -146,15 +146,48 @@ gdk_event_class_init (GdkEventClass *klass)
|
||||
g_object_class_install_properties (object_class, N_PROPS, event_props);
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_event_emit (GdkEvent *event)
|
||||
gboolean
|
||||
check_event_sanity (GdkEvent *event)
|
||||
{
|
||||
GdkDisplay *display;
|
||||
GdkSurface *surface;
|
||||
GdkDevice *device;
|
||||
|
||||
display = gdk_event_get_display (event);
|
||||
surface = gdk_event_get_surface (event);
|
||||
device = gdk_event_get_device (event);
|
||||
|
||||
if (gdk_event_get_event_type (event) == GDK_NOTHING)
|
||||
{
|
||||
g_warning ("Ignoring GDK_NOTHING events; they're good for nothing");
|
||||
return;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (surface && display != gdk_surface_get_display (surface))
|
||||
{
|
||||
char *type = g_enum_to_string (GDK_TYPE_EVENT_TYPE, event->any.type);
|
||||
g_warning ("Event of type %s with mismatched surface display", type);
|
||||
g_free (type);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (device && display != gdk_device_get_display (device))
|
||||
{
|
||||
char *type = g_enum_to_string (GDK_TYPE_EVENT_TYPE, event->any.type);
|
||||
g_warning ("Event of type %s with mismatched device display", type);
|
||||
g_free (type);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_event_emit (GdkEvent *event)
|
||||
{
|
||||
if (!check_event_sanity (event))
|
||||
return;
|
||||
|
||||
if (gdk_drag_handle_source_event (event))
|
||||
return;
|
||||
|
||||
|
||||
@@ -645,5 +645,7 @@ void gdk_event_set_related_target (GdkEvent *event,
|
||||
GObject *user_data);
|
||||
GObject * gdk_event_get_related_target (const GdkEvent *event);
|
||||
|
||||
gboolean check_event_sanity (GdkEvent *event);
|
||||
|
||||
|
||||
#endif /* __GDK_EVENTS_PRIVATE_H__ */
|
||||
|
||||
+14
-22
@@ -38,9 +38,6 @@
|
||||
|
||||
struct _GdkFrameClockIdlePrivate
|
||||
{
|
||||
GTimer *timer;
|
||||
/* timer_base is used to avoid ever going backward */
|
||||
gint64 timer_base;
|
||||
gint64 frame_time;
|
||||
gint64 min_next_frame_time;
|
||||
gint64 sleep_serial;
|
||||
@@ -161,22 +158,12 @@ compute_frame_time (GdkFrameClockIdle *idle)
|
||||
{
|
||||
GdkFrameClockIdlePrivate *priv = idle->priv;
|
||||
gint64 computed_frame_time;
|
||||
gint64 elapsed;
|
||||
|
||||
elapsed = g_get_monotonic_time () + priv->timer_base;
|
||||
if (elapsed < priv->frame_time)
|
||||
{
|
||||
/* clock went backward. adapt to that by forevermore increasing
|
||||
* timer_base. For now, assume we've gone forward in time 1ms.
|
||||
*/
|
||||
/* hmm. just fix GTimer? */
|
||||
computed_frame_time = g_get_monotonic_time ();
|
||||
|
||||
/* ensure monotonicity of frame time */
|
||||
if (computed_frame_time <= priv->frame_time)
|
||||
computed_frame_time = priv->frame_time + 1;
|
||||
priv->timer_base += (priv->frame_time - elapsed) + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
computed_frame_time = elapsed;
|
||||
}
|
||||
|
||||
return computed_frame_time;
|
||||
}
|
||||
@@ -399,7 +386,8 @@ gdk_frame_clock_paint_idle (void *data)
|
||||
_gdk_frame_clock_emit_before_paint (clock);
|
||||
priv->phase = GDK_FRAME_CLOCK_PHASE_UPDATE;
|
||||
}
|
||||
/* fallthrough */
|
||||
G_GNUC_FALLTHROUGH;
|
||||
|
||||
case GDK_FRAME_CLOCK_PHASE_UPDATE:
|
||||
if (priv->freeze_count == 0)
|
||||
{
|
||||
@@ -410,7 +398,8 @@ gdk_frame_clock_paint_idle (void *data)
|
||||
_gdk_frame_clock_emit_update (clock);
|
||||
}
|
||||
}
|
||||
/* fallthrough */
|
||||
G_GNUC_FALLTHROUGH;
|
||||
|
||||
case GDK_FRAME_CLOCK_PHASE_LAYOUT:
|
||||
if (priv->freeze_count == 0)
|
||||
{
|
||||
@@ -440,7 +429,8 @@ gdk_frame_clock_paint_idle (void *data)
|
||||
if (iter == 5)
|
||||
g_warning ("gdk-frame-clock: layout continuously requested, giving up after 4 tries");
|
||||
}
|
||||
/* fallthrough */
|
||||
G_GNUC_FALLTHROUGH;
|
||||
|
||||
case GDK_FRAME_CLOCK_PHASE_PAINT:
|
||||
if (priv->freeze_count == 0)
|
||||
{
|
||||
@@ -460,7 +450,8 @@ gdk_frame_clock_paint_idle (void *data)
|
||||
_gdk_frame_clock_emit_paint (clock);
|
||||
}
|
||||
}
|
||||
/* fallthrough */
|
||||
G_GNUC_FALLTHROUGH;
|
||||
|
||||
case GDK_FRAME_CLOCK_PHASE_AFTER_PAINT:
|
||||
if (priv->freeze_count == 0)
|
||||
{
|
||||
@@ -475,7 +466,8 @@ gdk_frame_clock_paint_idle (void *data)
|
||||
timings->frame_end_time = g_get_monotonic_time ();
|
||||
#endif /* G_ENABLE_DEBUG */
|
||||
}
|
||||
/* fallthrough */
|
||||
G_GNUC_FALLTHROUGH;
|
||||
|
||||
case GDK_FRAME_CLOCK_PHASE_RESUME_EVENTS:
|
||||
default:
|
||||
;
|
||||
|
||||
@@ -105,6 +105,8 @@ typedef struct {
|
||||
guint use_texture_rectangle : 1;
|
||||
guint has_gl_framebuffer_blit : 1;
|
||||
guint has_frame_terminator : 1;
|
||||
guint has_khr_debug : 1;
|
||||
guint use_khr_debug : 1;
|
||||
guint has_unpack_subimage : 1;
|
||||
guint has_debug_output : 1;
|
||||
guint extensions_checked : 1;
|
||||
@@ -114,6 +116,8 @@ typedef struct {
|
||||
|
||||
int use_es;
|
||||
|
||||
int max_debug_label_length;
|
||||
|
||||
GdkGLContextPaintData *paint_data;
|
||||
} GdkGLContextPrivate;
|
||||
|
||||
@@ -434,6 +438,87 @@ gdk_gl_context_has_frame_terminator (GdkGLContext *context)
|
||||
return priv->has_frame_terminator;
|
||||
}
|
||||
|
||||
void
|
||||
gdk_gl_context_push_debug_group (GdkGLContext *context,
|
||||
const char *message)
|
||||
{
|
||||
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
|
||||
|
||||
if (priv->use_khr_debug)
|
||||
glPushDebugGroupKHR (GL_DEBUG_SOURCE_APPLICATION, 0, -1, message);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_gl_context_push_debug_group_printf (GdkGLContext *context,
|
||||
const char *format,
|
||||
...)
|
||||
{
|
||||
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
|
||||
gchar *message;
|
||||
va_list args;
|
||||
|
||||
if (priv->use_khr_debug)
|
||||
{
|
||||
int msg_len;
|
||||
|
||||
va_start (args, format);
|
||||
message = g_strdup_vprintf (format, args);
|
||||
va_end (args);
|
||||
|
||||
msg_len = MIN (priv->max_debug_label_length, strlen (message) - 1);
|
||||
glPushDebugGroupKHR (GL_DEBUG_SOURCE_APPLICATION, 0, msg_len, message);
|
||||
g_free (message);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gdk_gl_context_pop_debug_group (GdkGLContext *context)
|
||||
{
|
||||
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
|
||||
|
||||
if (priv->use_khr_debug)
|
||||
glPopDebugGroupKHR ();
|
||||
}
|
||||
|
||||
void
|
||||
gdk_gl_context_label_object (GdkGLContext *context,
|
||||
guint identifier,
|
||||
guint name,
|
||||
const char *label)
|
||||
{
|
||||
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
|
||||
|
||||
if (priv->use_khr_debug)
|
||||
glObjectLabel (identifier, name, -1, label);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_gl_context_label_object_printf (GdkGLContext *context,
|
||||
guint identifier,
|
||||
guint name,
|
||||
const char *format,
|
||||
...)
|
||||
{
|
||||
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
|
||||
gchar *message;
|
||||
va_list args;
|
||||
|
||||
if (priv->use_khr_debug)
|
||||
{
|
||||
int msg_len;
|
||||
|
||||
va_start (args, format);
|
||||
message = g_strdup_vprintf (format, args);
|
||||
va_end (args);
|
||||
|
||||
msg_len = MIN (priv->max_debug_label_length, strlen (message) - 1);
|
||||
|
||||
glObjectLabel (identifier, name, msg_len, message);
|
||||
g_free (message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
gboolean
|
||||
gdk_gl_context_has_unpack_subimage (GdkGLContext *context)
|
||||
{
|
||||
@@ -896,6 +981,7 @@ gdk_gl_context_check_extensions (GdkGLContext *context)
|
||||
priv->has_frame_terminator = FALSE;
|
||||
|
||||
priv->has_unpack_subimage = epoxy_has_gl_extension ("GL_EXT_unpack_subimage");
|
||||
priv->has_khr_debug = epoxy_has_gl_extension ("GL_KHR_debug");
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -905,6 +991,7 @@ gdk_gl_context_check_extensions (GdkGLContext *context)
|
||||
priv->has_gl_framebuffer_blit = epoxy_has_gl_extension ("GL_EXT_framebuffer_blit");
|
||||
priv->has_frame_terminator = epoxy_has_gl_extension ("GL_GREMEDY_frame_terminator");
|
||||
priv->has_unpack_subimage = TRUE;
|
||||
priv->has_khr_debug = epoxy_has_gl_extension ("GL_KHR_debug");
|
||||
|
||||
/* We asked for a core profile, but we didn't get one, so we're in legacy mode */
|
||||
if (priv->gl_version < 32)
|
||||
@@ -913,6 +1000,11 @@ gdk_gl_context_check_extensions (GdkGLContext *context)
|
||||
|
||||
display = gdk_draw_context_get_display (GDK_DRAW_CONTEXT (context));
|
||||
|
||||
if (priv->has_khr_debug && GDK_DISPLAY_DEBUG_CHECK (display, GL_DEBUG))
|
||||
{
|
||||
priv->use_khr_debug = TRUE;
|
||||
glGetIntegerv (GL_MAX_LABEL_LENGTH, &priv->max_debug_label_length);
|
||||
}
|
||||
if (!priv->use_es && GDK_DISPLAY_DEBUG_CHECK (display, GL_TEXTURE_RECT))
|
||||
priv->use_texture_rectangle = TRUE;
|
||||
else if (has_npot)
|
||||
@@ -930,6 +1022,7 @@ gdk_gl_context_check_extensions (GdkGLContext *context)
|
||||
" - GL_ARB_texture_rectangle: %s\n"
|
||||
" - GL_EXT_framebuffer_blit: %s\n"
|
||||
" - GL_GREMEDY_frame_terminator: %s\n"
|
||||
" - GL_KHR_debug: %s\n"
|
||||
"* Using texture rectangle: %s",
|
||||
priv->use_es ? "OpenGL ES" : "OpenGL",
|
||||
priv->gl_version / 10, priv->gl_version % 10,
|
||||
@@ -939,6 +1032,7 @@ gdk_gl_context_check_extensions (GdkGLContext *context)
|
||||
has_texture_rectangle ? "yes" : "no",
|
||||
priv->has_gl_framebuffer_blit ? "yes" : "no",
|
||||
priv->has_frame_terminator ? "yes" : "no",
|
||||
priv->has_khr_debug ? "yes" : "no",
|
||||
priv->use_texture_rectangle ? "yes" : "no"));
|
||||
|
||||
priv->extensions_checked = TRUE;
|
||||
|
||||
@@ -90,7 +90,21 @@ gboolean gdk_gl_context_use_texture_rectangle (GdkGLContext
|
||||
gboolean gdk_gl_context_has_framebuffer_blit (GdkGLContext *context);
|
||||
gboolean gdk_gl_context_has_frame_terminator (GdkGLContext *context);
|
||||
gboolean gdk_gl_context_has_unpack_subimage (GdkGLContext *context);
|
||||
|
||||
void gdk_gl_context_push_debug_group (GdkGLContext *context,
|
||||
const char *message);
|
||||
void gdk_gl_context_push_debug_group_printf (GdkGLContext *context,
|
||||
const gchar *format,
|
||||
...) G_GNUC_PRINTF (2, 3);
|
||||
void gdk_gl_context_pop_debug_group (GdkGLContext *context);
|
||||
void gdk_gl_context_label_object (GdkGLContext *context,
|
||||
guint identifier,
|
||||
guint name,
|
||||
const char *label);
|
||||
void gdk_gl_context_label_object_printf (GdkGLContext *context,
|
||||
guint identifier,
|
||||
guint name,
|
||||
const char *format,
|
||||
...) G_GNUC_PRINTF (4, 5);
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_GL_CONTEXT_PRIVATE_H__ */
|
||||
|
||||
+7
-3
@@ -63,8 +63,9 @@ typedef enum {
|
||||
GDK_DEBUG_GL_TEXTURE_RECT = 1 << 14,
|
||||
GDK_DEBUG_GL_LEGACY = 1 << 15,
|
||||
GDK_DEBUG_GL_GLES = 1 << 16,
|
||||
GDK_DEBUG_VULKAN_DISABLE = 1 << 17,
|
||||
GDK_DEBUG_VULKAN_VALIDATE = 1 << 18
|
||||
GDK_DEBUG_GL_DEBUG = 1 << 17,
|
||||
GDK_DEBUG_VULKAN_DISABLE = 1 << 18,
|
||||
GDK_DEBUG_VULKAN_VALIDATE = 1 << 19
|
||||
} GdkDebugFlags;
|
||||
|
||||
extern guint _gdk_debug_flags;
|
||||
@@ -131,7 +132,6 @@ struct _GdkSurfaceAttr
|
||||
gint height;
|
||||
GdkSurfaceSurfaceClass wclass;
|
||||
GdkSurfaceType surface_type;
|
||||
GdkSurfaceTypeHint type_hint;
|
||||
};
|
||||
|
||||
struct _GdkSurface
|
||||
@@ -283,6 +283,10 @@ GdkSurface* gdk_surface_new (GdkDisplay *display,
|
||||
GdkSurfaceAttr *attributes);
|
||||
void _gdk_surface_destroy (GdkSurface *surface,
|
||||
gboolean foreign_destroy);
|
||||
void gdk_surface_invalidate_rect (GdkSurface *surface,
|
||||
const GdkRectangle *rect);
|
||||
void gdk_surface_invalidate_region (GdkSurface *surface,
|
||||
const cairo_region_t *region);
|
||||
void _gdk_surface_clear_update_area (GdkSurface *surface);
|
||||
void _gdk_surface_update_size (GdkSurface *surface);
|
||||
gboolean _gdk_surface_update_viewable (GdkSurface *surface);
|
||||
|
||||
+183
-1
@@ -23,7 +23,9 @@
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "gdkrgba.h"
|
||||
|
||||
#include "gdkrgbaprivate.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <math.h>
|
||||
@@ -393,3 +395,183 @@ gdk_rgba_to_string (const GdkRGBA *rgba)
|
||||
alpha);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
parse_color_channel_value (GtkCssParser *parser,
|
||||
double *value,
|
||||
gboolean is_percentage)
|
||||
{
|
||||
if (is_percentage)
|
||||
{
|
||||
if (!gtk_css_parser_consume_percentage (parser, value))
|
||||
return FALSE;
|
||||
|
||||
*value = CLAMP (*value, 0.0, 100.0) / 100.0;
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!gtk_css_parser_consume_number (parser, value))
|
||||
return FALSE;
|
||||
|
||||
*value = CLAMP (*value, 0.0, 255.0) / 255.0;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
static guint
|
||||
parse_color_channel (GtkCssParser *parser,
|
||||
guint arg,
|
||||
gpointer data)
|
||||
{
|
||||
GdkRGBA *rgba = data;
|
||||
|
||||
switch (arg)
|
||||
{
|
||||
case 0:
|
||||
/* We abuse rgba->alpha to store if we use percentages or numbers */
|
||||
if (gtk_css_token_is (gtk_css_parser_get_token (parser), GTK_CSS_TOKEN_PERCENTAGE))
|
||||
rgba->alpha = 1.0;
|
||||
else
|
||||
rgba->alpha = 0.0;
|
||||
|
||||
if (!parse_color_channel_value (parser, &rgba->red, rgba->alpha != 0.0))
|
||||
return 0;
|
||||
return 1;
|
||||
|
||||
case 1:
|
||||
if (!parse_color_channel_value (parser, &rgba->green, rgba->alpha != 0.0))
|
||||
return 0;
|
||||
return 1;
|
||||
|
||||
case 2:
|
||||
if (!parse_color_channel_value (parser, &rgba->blue, rgba->alpha != 0.0))
|
||||
return 0;
|
||||
return 1;
|
||||
|
||||
case 3:
|
||||
if (!gtk_css_parser_consume_number (parser, &rgba->alpha))
|
||||
return 0;
|
||||
|
||||
rgba->alpha = CLAMP (rgba->alpha, 0.0, 1.0);
|
||||
return 1;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
rgba_init_chars (GdkRGBA *rgba,
|
||||
const char s[8])
|
||||
{
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
if (!g_ascii_isxdigit (s[i]))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
rgba->red = (g_ascii_xdigit_value (s[0]) * 16 + g_ascii_xdigit_value (s[1])) / 255.0;
|
||||
rgba->green = (g_ascii_xdigit_value (s[2]) * 16 + g_ascii_xdigit_value (s[3])) / 255.0;
|
||||
rgba->blue = (g_ascii_xdigit_value (s[4]) * 16 + g_ascii_xdigit_value (s[5])) / 255.0;
|
||||
rgba->alpha = (g_ascii_xdigit_value (s[6]) * 16 + g_ascii_xdigit_value (s[7])) / 255.0;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gdk_rgba_parser_parse (GtkCssParser *parser,
|
||||
GdkRGBA *rgba)
|
||||
{
|
||||
const GtkCssToken *token;
|
||||
|
||||
token = gtk_css_parser_get_token (parser);
|
||||
if (gtk_css_token_is_function (token, "rgb"))
|
||||
{
|
||||
if (!gtk_css_parser_consume_function (parser, 3, 3, parse_color_channel, rgba))
|
||||
return FALSE;
|
||||
|
||||
rgba->alpha = 1.0;
|
||||
return TRUE;
|
||||
}
|
||||
else if (gtk_css_token_is_function (token, "rgba"))
|
||||
{
|
||||
return gtk_css_parser_consume_function (parser, 4, 4, parse_color_channel, rgba);
|
||||
}
|
||||
else if (gtk_css_token_is (token, GTK_CSS_TOKEN_HASH_ID) ||
|
||||
gtk_css_token_is (token, GTK_CSS_TOKEN_HASH_UNRESTRICTED))
|
||||
{
|
||||
const char *s = token->string.string;
|
||||
|
||||
switch (strlen (s))
|
||||
{
|
||||
case 3:
|
||||
if (!rgba_init_chars (rgba, (char[8]) {s[0], s[0], s[1], s[1], s[2], s[2], 'F', 'F' }))
|
||||
{
|
||||
gtk_css_parser_error_value (parser, "Hash code is not a valid hex color.");
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
case 4:
|
||||
if (!rgba_init_chars (rgba, (char[8]) {s[0], s[0], s[1], s[1], s[2], s[2], s[3], s[3] }))
|
||||
{
|
||||
gtk_css_parser_error_value (parser, "Hash code is not a valid hex color.");
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
case 6:
|
||||
if (!rgba_init_chars (rgba, (char[8]) {s[0], s[1], s[2], s[3], s[4], s[5], 'F', 'F' }))
|
||||
{
|
||||
gtk_css_parser_error_value (parser, "Hash code is not a valid hex color.");
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
case 8:
|
||||
if (!rgba_init_chars (rgba, s))
|
||||
{
|
||||
gtk_css_parser_error_value (parser, "Hash code is not a valid hex color.");
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
gtk_css_parser_error_value (parser, "Hash code is not a valid hex color.");
|
||||
return FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
gtk_css_parser_consume_token (parser);
|
||||
return TRUE;
|
||||
}
|
||||
else if (gtk_css_token_is (token, GTK_CSS_TOKEN_IDENT))
|
||||
{
|
||||
if (gtk_css_token_is_ident (token, "transparent"))
|
||||
{
|
||||
*rgba = (GdkRGBA) { 0, 0, 0, 0 };
|
||||
}
|
||||
else if (gdk_rgba_parse (rgba, token->string.string))
|
||||
{
|
||||
/* everything's fine */
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_css_parser_error_syntax (parser, "\"%s\" is not a valid color name.", token->string.string);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gtk_css_parser_consume_token (parser);
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_css_parser_error_syntax (parser, "Expected a valid color.");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2010, Red Hat, Inc
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GDK_RGBA_PRIVATE_H__
|
||||
#define __GDK_RGBA_PRIVATE_H__
|
||||
|
||||
#include "gdkrgba.h"
|
||||
|
||||
#include <gtk/css/gtkcss.h>
|
||||
|
||||
#include "gtk/css/gtkcssparserprivate.h"
|
||||
|
||||
|
||||
gboolean gdk_rgba_parser_parse (GtkCssParser *parser,
|
||||
GdkRGBA *rgba);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif
|
||||
@@ -293,6 +293,7 @@ gdk_seat_grab (GdkSeat *seat,
|
||||
|
||||
g_return_val_if_fail (GDK_IS_SEAT (seat), GDK_GRAB_FAILED);
|
||||
g_return_val_if_fail (GDK_IS_SURFACE (surface), GDK_GRAB_FAILED);
|
||||
g_return_val_if_fail (gdk_surface_get_display (surface) == gdk_seat_get_display (seat), GDK_GRAB_FAILED);
|
||||
|
||||
capabilities &= GDK_SEAT_CAPABILITY_ALL;
|
||||
g_return_val_if_fail (capabilities != GDK_SEAT_CAPABILITY_NONE, GDK_GRAB_FAILED);
|
||||
|
||||
+17
-93
@@ -107,6 +107,7 @@ enum {
|
||||
PROP_0,
|
||||
PROP_CURSOR,
|
||||
PROP_DISPLAY,
|
||||
PROP_FRAME_CLOCK,
|
||||
PROP_STATE,
|
||||
PROP_MAPPED,
|
||||
LAST_PROP
|
||||
@@ -268,6 +269,13 @@ gdk_surface_class_init (GdkSurfaceClass *klass)
|
||||
GDK_TYPE_DISPLAY,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
properties[PROP_FRAME_CLOCK] =
|
||||
g_param_spec_object ("frame-clock",
|
||||
P_("Frame Clock"),
|
||||
P_("Frame Clock"),
|
||||
GDK_TYPE_FRAME_CLOCK,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
properties[PROP_STATE] =
|
||||
g_param_spec_flags ("state",
|
||||
P_("State"),
|
||||
@@ -462,6 +470,10 @@ gdk_surface_set_property (GObject *object,
|
||||
g_assert (surface->display != NULL);
|
||||
break;
|
||||
|
||||
case PROP_FRAME_CLOCK:
|
||||
gdk_surface_set_frame_clock (surface, GDK_FRAME_CLOCK (g_value_get_object (value)));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
@@ -486,6 +498,10 @@ gdk_surface_get_property (GObject *object,
|
||||
g_value_set_object (value, surface->display);
|
||||
break;
|
||||
|
||||
case PROP_FRAME_CLOCK:
|
||||
g_value_set_object (value, surface->frame_clock);
|
||||
break;
|
||||
|
||||
case PROP_STATE:
|
||||
g_value_set_flags (value, surface->state);
|
||||
break;
|
||||
@@ -4118,61 +4134,6 @@ gdk_surface_set_modal_hint (GdkSurface *surface,
|
||||
GDK_SURFACE_IMPL_GET_CLASS (surface->impl)->set_modal_hint (surface, modal);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_surface_set_skip_taskbar_hint:
|
||||
* @surface: a toplevel #GdkSurface
|
||||
* @skips_taskbar: %TRUE to skip the taskbar
|
||||
*
|
||||
* Toggles whether a surface should appear in a task list or surface
|
||||
* list. If a surface’s semantic type as specified with
|
||||
* gdk_surface_set_type_hint() already fully describes the surface, this
|
||||
* function should not be called in addition,
|
||||
* instead you should allow the surface to be treated according to
|
||||
* standard policy for its semantic type.
|
||||
**/
|
||||
void
|
||||
gdk_surface_set_skip_taskbar_hint (GdkSurface *surface,
|
||||
gboolean skips_taskbar)
|
||||
{
|
||||
GDK_SURFACE_IMPL_GET_CLASS (surface->impl)->set_skip_taskbar_hint (surface, skips_taskbar);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_surface_set_skip_pager_hint:
|
||||
* @surface: a toplevel #GdkSurface
|
||||
* @skips_pager: %TRUE to skip the pager
|
||||
*
|
||||
* Toggles whether a surface should appear in a pager (workspace
|
||||
* switcher, or other desktop utility program that displays a small
|
||||
* thumbnail representation of the surfaces on the desktop). If a
|
||||
* surface’s semantic type as specified with gdk_surface_set_type_hint()
|
||||
* already fully describes the surface, this function should
|
||||
* not be called in addition, instead you should
|
||||
* allow the surface to be treated according to standard policy for
|
||||
* its semantic type.
|
||||
**/
|
||||
void
|
||||
gdk_surface_set_skip_pager_hint (GdkSurface *surface,
|
||||
gboolean skips_pager)
|
||||
{
|
||||
GDK_SURFACE_IMPL_GET_CLASS (surface->impl)->set_skip_pager_hint (surface, skips_pager);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_surface_set_urgency_hint:
|
||||
* @surface: a toplevel #GdkSurface
|
||||
* @urgent: %TRUE if the surface is urgent
|
||||
*
|
||||
* Toggles whether a surface needs the user's
|
||||
* urgent attention.
|
||||
**/
|
||||
void
|
||||
gdk_surface_set_urgency_hint (GdkSurface *surface,
|
||||
gboolean urgent)
|
||||
{
|
||||
GDK_SURFACE_IMPL_GET_CLASS (surface->impl)->set_urgency_hint (surface, urgent);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_surface_set_geometry_hints:
|
||||
* @surface: a toplevel #GdkSurface
|
||||
@@ -4259,7 +4220,7 @@ gdk_surface_set_startup_id (GdkSurface *surface,
|
||||
**/
|
||||
void
|
||||
gdk_surface_set_transient_for (GdkSurface *surface,
|
||||
GdkSurface *parent)
|
||||
GdkSurface *parent)
|
||||
{
|
||||
surface->transient_for = parent;
|
||||
|
||||
@@ -4683,43 +4644,6 @@ gdk_surface_set_keep_below (GdkSurface *surface,
|
||||
GDK_SURFACE_IMPL_GET_CLASS (surface->impl)->set_keep_below (surface, setting);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_surface_get_group:
|
||||
* @surface: a toplevel #GdkSurface
|
||||
*
|
||||
* Returns the group leader surface for @surface. See gdk_surface_set_group().
|
||||
*
|
||||
* Returns: (transfer none): the group leader surface for @surface
|
||||
**/
|
||||
GdkSurface *
|
||||
gdk_surface_get_group (GdkSurface *surface)
|
||||
{
|
||||
return GDK_SURFACE_IMPL_GET_CLASS (surface->impl)->get_group (surface);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_surface_set_group:
|
||||
* @surface: a toplevel #GdkSurface
|
||||
* @leader: (allow-none): group leader surface, or %NULL to restore the default group leader surface
|
||||
*
|
||||
* Sets the group leader surface for @surface. By default,
|
||||
* GDK sets the group leader for all toplevel surfaces
|
||||
* to a global surface implicitly created by GDK. With this function
|
||||
* you can override this default.
|
||||
*
|
||||
* The group leader surface allows the window manager to distinguish
|
||||
* all surfaces that belong to a single application. It may for example
|
||||
* allow users to minimize/unminimize all surfaces belonging to an
|
||||
* application at once. You should only set a non-default group surface
|
||||
* if your application pretends to be multiple applications.
|
||||
**/
|
||||
void
|
||||
gdk_surface_set_group (GdkSurface *surface,
|
||||
GdkSurface *leader)
|
||||
{
|
||||
GDK_SURFACE_IMPL_GET_CLASS (surface->impl)->set_group (surface, leader);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_surface_set_decorations:
|
||||
* @surface: a toplevel #GdkSurface
|
||||
|
||||
@@ -555,16 +555,6 @@ GDK_AVAILABLE_IN_ALL
|
||||
void gdk_surface_set_modal_hint (GdkSurface *surface,
|
||||
gboolean modal);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_surface_set_skip_taskbar_hint (GdkSurface *surface,
|
||||
gboolean skips_taskbar);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_surface_set_skip_pager_hint (GdkSurface *surface,
|
||||
gboolean skips_pager);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_surface_set_urgency_hint (GdkSurface *surface,
|
||||
gboolean urgent);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_surface_set_geometry_hints (GdkSurface *surface,
|
||||
const GdkGeometry *geometry,
|
||||
@@ -663,11 +653,6 @@ GDK_AVAILABLE_IN_ALL
|
||||
void gdk_surface_set_icon_name (GdkSurface *surface,
|
||||
const gchar *name);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_surface_set_group (GdkSurface *surface,
|
||||
GdkSurface *leader);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkSurface* gdk_surface_get_group (GdkSurface *surface);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_surface_set_decorations (GdkSurface *surface,
|
||||
GdkWMDecoration decorations);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
@@ -755,12 +740,6 @@ void gdk_surface_begin_move_drag_for_device (GdkSurface *surface,
|
||||
/* Interface for dirty-region queueing */
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_surface_queue_expose (GdkSurface *surface);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_surface_invalidate_rect (GdkSurface *surface,
|
||||
const GdkRectangle *rect);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_surface_invalidate_region (GdkSurface *surface,
|
||||
const cairo_region_t *region);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_surface_freeze_updates (GdkSurface *surface);
|
||||
|
||||
@@ -125,12 +125,6 @@ struct _GdkSurfaceImplClass
|
||||
GdkSurfaceTypeHint (* get_type_hint) (GdkSurface *surface);
|
||||
void (* set_modal_hint) (GdkSurface *surface,
|
||||
gboolean modal);
|
||||
void (* set_skip_taskbar_hint) (GdkSurface *surface,
|
||||
gboolean skips_taskbar);
|
||||
void (* set_skip_pager_hint) (GdkSurface *surface,
|
||||
gboolean skips_pager);
|
||||
void (* set_urgency_hint) (GdkSurface *surface,
|
||||
gboolean urgent);
|
||||
void (* set_geometry_hints) (GdkSurface *surface,
|
||||
const GdkGeometry *geometry,
|
||||
GdkSurfaceHints geom_mask);
|
||||
@@ -165,9 +159,6 @@ struct _GdkSurfaceImplClass
|
||||
gboolean setting);
|
||||
void (* set_keep_below) (GdkSurface *surface,
|
||||
gboolean setting);
|
||||
GdkSurface * (* get_group) (GdkSurface *surface);
|
||||
void (* set_group) (GdkSurface *surface,
|
||||
GdkSurface *leader);
|
||||
void (* set_decorations) (GdkSurface *surface,
|
||||
GdkWMDecoration decorations);
|
||||
gboolean (* get_decorations) (GdkSurface *surface,
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#if !defined (__GDK_H_INSIDE__) && !defined (GDK_COMPILATION)
|
||||
#if !defined (__GDK_H_INSIDE__) && !defined (__GTK_CSS_H_INSIDE__) && !defined (GDK_COMPILATION) && !defined (GTK_CSS_COMPILATION)
|
||||
#error "Only <gdk/gdk.h> can be included directly."
|
||||
#endif
|
||||
|
||||
|
||||
@@ -194,6 +194,10 @@ gdk_vulkan_strerror (VkResult result)
|
||||
case VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT:
|
||||
return "Invalid DRM format modifier plane layout";
|
||||
#endif
|
||||
#if VK_HEADER_VERSION >= 97
|
||||
case VK_ERROR_INVALID_DEVICE_ADDRESS_EXT:
|
||||
return "Invalid device address";
|
||||
#endif
|
||||
|
||||
case VK_RESULT_RANGE_SIZE:
|
||||
case VK_RESULT_MAX_ENUM:
|
||||
|
||||
+3
-2
@@ -224,7 +224,8 @@ endif
|
||||
# FIXME: might have to add '-xobjective-c' to c_args for quartz backend?
|
||||
libgdk = static_library('gdk',
|
||||
sources: [gdk_sources, gdk_backends_gen_headers, gdkconfig],
|
||||
dependencies: gdk_deps,
|
||||
dependencies: gdk_deps + [libgtk_css_dep],
|
||||
link_with: [libgtk_css, ],
|
||||
include_directories: [confinc, gdkx11_inc, wlinc],
|
||||
c_args: [
|
||||
'-DGDK_COMPILATION',
|
||||
@@ -239,4 +240,4 @@ libgdk = static_library('gdk',
|
||||
libgdk_dep = declare_dependency(
|
||||
sources: ['gdk.h', gdkconfig, gdkenum_h],
|
||||
include_directories: [confinc, gdkx11_inc, wlinc],
|
||||
dependencies: gdk_deps)
|
||||
dependencies: gdk_deps + [libgtk_css_dep])
|
||||
|
||||
@@ -1618,17 +1618,6 @@ gdk_surface_quartz_get_device_state (GdkSurface *window,
|
||||
x, y, mask) != NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_quartz_surface_set_urgency_hint (GdkSurface *window,
|
||||
gboolean urgent)
|
||||
{
|
||||
if (GDK_SURFACE_DESTROYED (window) ||
|
||||
!SURFACE_IS_TOPLEVEL (window))
|
||||
return;
|
||||
|
||||
/* FIXME: Implement */
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_quartz_surface_set_geometry_hints (GdkSurface *window,
|
||||
const GdkGeometry *geometry,
|
||||
@@ -1997,28 +1986,6 @@ gdk_quartz_surface_set_modal_hint (GdkSurface *window,
|
||||
/* FIXME: Implement */
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_quartz_surface_set_skip_taskbar_hint (GdkSurface *window,
|
||||
gboolean skips_taskbar)
|
||||
{
|
||||
if (GDK_SURFACE_DESTROYED (window) ||
|
||||
!SURFACE_IS_TOPLEVEL (window))
|
||||
return;
|
||||
|
||||
/* FIXME: Implement */
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_quartz_surface_set_skip_pager_hint (GdkSurface *window,
|
||||
gboolean skips_pager)
|
||||
{
|
||||
if (GDK_SURFACE_DESTROYED (window) ||
|
||||
!SURFACE_IS_TOPLEVEL (window))
|
||||
return;
|
||||
|
||||
/* FIXME: Implement */
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_quartz_surface_begin_resize_drag (GdkSurface *window,
|
||||
GdkSurfaceEdge edge,
|
||||
@@ -2617,27 +2584,6 @@ gdk_quartz_surface_set_keep_below (GdkSurface *window,
|
||||
[impl->toplevel setLevel: level - (setting ? 1 : 0)];
|
||||
}
|
||||
|
||||
static GdkSurface *
|
||||
gdk_quartz_surface_get_group (GdkSurface *window)
|
||||
{
|
||||
g_return_val_if_fail (GDK_SURFACE_TYPE (window) != GDK_SURFACE_CHILD, NULL);
|
||||
|
||||
if (GDK_SURFACE_DESTROYED (window) ||
|
||||
!SURFACE_IS_TOPLEVEL (window))
|
||||
return NULL;
|
||||
|
||||
/* FIXME: Implement */
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_quartz_surface_set_group (GdkSurface *window,
|
||||
GdkSurface *leader)
|
||||
{
|
||||
/* FIXME: Implement */
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_quartz_surface_destroy_notify (GdkSurface *window)
|
||||
{
|
||||
@@ -2738,9 +2684,6 @@ gdk_surface_impl_quartz_class_init (GdkSurfaceImplQuartzClass *klass)
|
||||
impl_class->set_type_hint = gdk_quartz_surface_set_type_hint;
|
||||
impl_class->get_type_hint = gdk_quartz_surface_get_type_hint;
|
||||
impl_class->set_modal_hint = gdk_quartz_surface_set_modal_hint;
|
||||
impl_class->set_skip_taskbar_hint = gdk_quartz_surface_set_skip_taskbar_hint;
|
||||
impl_class->set_skip_pager_hint = gdk_quartz_surface_set_skip_pager_hint;
|
||||
impl_class->set_urgency_hint = gdk_quartz_surface_set_urgency_hint;
|
||||
impl_class->set_geometry_hints = gdk_quartz_surface_set_geometry_hints;
|
||||
impl_class->set_title = gdk_quartz_surface_set_title;
|
||||
impl_class->set_startup_id = gdk_quartz_surface_set_startup_id;
|
||||
@@ -2760,8 +2703,6 @@ gdk_surface_impl_quartz_class_init (GdkSurfaceImplQuartzClass *klass)
|
||||
impl_class->unfullscreen = gdk_quartz_surface_unfullscreen;
|
||||
impl_class->set_keep_above = gdk_quartz_surface_set_keep_above;
|
||||
impl_class->set_keep_below = gdk_quartz_surface_set_keep_below;
|
||||
impl_class->get_group = gdk_quartz_surface_get_group;
|
||||
impl_class->set_group = gdk_quartz_surface_set_group;
|
||||
impl_class->set_decorations = gdk_quartz_surface_set_decorations;
|
||||
impl_class->get_decorations = gdk_quartz_surface_get_decorations;
|
||||
impl_class->set_functions = gdk_quartz_surface_set_functions;
|
||||
|
||||
@@ -169,14 +169,7 @@ _gdk_wayland_cursor_get_buffer (GdkWaylandDisplay *display,
|
||||
struct wl_cursor *c;
|
||||
|
||||
if (g_str_equal (gdk_cursor_get_name (cursor), "none"))
|
||||
{
|
||||
*hotspot_x = 0;
|
||||
*hotspot_y = 0;
|
||||
*width = 0;
|
||||
*height = 0;
|
||||
*scale = 1;
|
||||
return NULL;
|
||||
}
|
||||
goto none;
|
||||
|
||||
c = gdk_wayland_cursor_load_for_name (display,
|
||||
_gdk_wayland_display_get_scaled_cursor_theme (display, desired_scale),
|
||||
@@ -250,6 +243,13 @@ _gdk_wayland_cursor_get_buffer (GdkWaylandDisplay *display,
|
||||
width, height,
|
||||
scale);
|
||||
|
||||
none:
|
||||
*hotspot_x = 0;
|
||||
*hotspot_y = 0;
|
||||
*width = 0;
|
||||
*height = 0;
|
||||
*scale = 1;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
+113
-49
@@ -103,6 +103,7 @@ struct _GdkWaylandPointerData {
|
||||
uint32_t grab_time;
|
||||
|
||||
struct wl_surface *pointer_surface;
|
||||
guint cursor_is_default: 1;
|
||||
GdkCursor *cursor;
|
||||
guint cursor_timeout_id;
|
||||
guint cursor_image_index;
|
||||
@@ -284,6 +285,10 @@ struct _GdkWaylandDevicePadClass
|
||||
};
|
||||
|
||||
static void gdk_wayland_device_pad_iface_init (GdkDevicePadInterface *iface);
|
||||
static void init_pointer_data (GdkWaylandPointerData *pointer_data,
|
||||
GdkDisplay *display_wayland,
|
||||
GdkDevice *master);
|
||||
static void pointer_surface_update_scale (GdkDevice *device);
|
||||
|
||||
#define GDK_TYPE_WAYLAND_DEVICE_PAD (gdk_wayland_device_pad_get_type ())
|
||||
GType gdk_wayland_device_pad_get_type (void);
|
||||
@@ -482,9 +487,9 @@ gdk_wayland_device_update_surface_cursor (GdkDevice *device)
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_device_set_surface_cursor (GdkDevice *device,
|
||||
GdkSurface *surface,
|
||||
GdkCursor *cursor)
|
||||
gdk_wayland_device_set_surface_cursor (GdkDevice *device,
|
||||
GdkSurface *surface,
|
||||
GdkCursor *cursor)
|
||||
{
|
||||
GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (gdk_device_get_seat (device));
|
||||
GdkWaylandPointerData *pointer = GDK_WAYLAND_DEVICE (device)->pointer;
|
||||
@@ -495,26 +500,35 @@ gdk_wayland_device_set_surface_cursor (GdkDevice *device,
|
||||
if (seat->grab_cursor)
|
||||
cursor = seat->grab_cursor;
|
||||
|
||||
if (cursor == NULL)
|
||||
cursor = gdk_cursor_new_from_name ("default", NULL);
|
||||
else
|
||||
cursor = g_object_ref (cursor);
|
||||
|
||||
if (pointer->cursor != NULL &&
|
||||
cursor != NULL &&
|
||||
gdk_cursor_equal (cursor, pointer->cursor))
|
||||
return;
|
||||
|
||||
if (cursor == NULL)
|
||||
{
|
||||
g_object_unref (cursor);
|
||||
return;
|
||||
if (!pointer->cursor_is_default)
|
||||
{
|
||||
g_clear_object (&pointer->cursor);
|
||||
pointer->cursor = gdk_cursor_new_from_name ("default", NULL);
|
||||
pointer->cursor_is_default = TRUE;
|
||||
|
||||
gdk_wayland_pointer_stop_cursor_animation (pointer);
|
||||
gdk_wayland_device_update_surface_cursor (device);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Nothing to do, we'already using the default cursor */
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
g_set_object (&pointer->cursor, cursor);
|
||||
pointer->cursor_is_default = FALSE;
|
||||
|
||||
gdk_wayland_pointer_stop_cursor_animation (pointer);
|
||||
|
||||
if (pointer->cursor)
|
||||
g_object_unref (pointer->cursor);
|
||||
|
||||
pointer->cursor = cursor;
|
||||
|
||||
gdk_wayland_device_update_surface_cursor (device);
|
||||
gdk_wayland_pointer_stop_cursor_animation (pointer);
|
||||
gdk_wayland_device_update_surface_cursor (device);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1994,7 +2008,7 @@ keyboard_handle_leave (void *data,
|
||||
|
||||
GDK_DISPLAY_NOTE (seat->display, EVENTS,
|
||||
g_message ("focus out, seat %p surface %p",
|
||||
seat, seat->keyboard_focus));
|
||||
seat, event->any.surface));
|
||||
|
||||
_gdk_wayland_display_deliver_event (seat->display, event);
|
||||
}
|
||||
@@ -2119,10 +2133,11 @@ deliver_key_event (GdkWaylandSeat *seat,
|
||||
_gdk_wayland_display_deliver_event (seat->display, event);
|
||||
|
||||
GDK_DISPLAY_NOTE (seat->display, EVENTS,
|
||||
g_message ("keyboard %s event%s, code %d, sym %d, "
|
||||
g_message ("keyboard %s event%s, surface %p, code %d, sym %d, "
|
||||
"mods 0x%x",
|
||||
(state ? "press" : "release"),
|
||||
(from_key_repeat ? " (repeat)" : ""),
|
||||
event->any.surface,
|
||||
event->key.hardware_keycode, event->key.keyval,
|
||||
event->key.state));
|
||||
|
||||
@@ -2877,6 +2892,8 @@ tablet_handle_done (void *data,
|
||||
NULL);
|
||||
|
||||
tablet->master = master;
|
||||
init_pointer_data (&tablet->pointer_info, display, tablet->master);
|
||||
|
||||
tablet->stylus_device = stylus_device;
|
||||
tablet->eraser_device = eraser_device;
|
||||
|
||||
@@ -3488,6 +3505,11 @@ tablet_tool_handle_proximity_in (void *data,
|
||||
gdk_event_set_source_device (event, tablet->current_device);
|
||||
gdk_event_set_device_tool (event, tool->tool);
|
||||
|
||||
tablet->pointer_info.pointer_surface_outputs =
|
||||
g_slist_append (tablet->pointer_info.pointer_surface_outputs,
|
||||
gdk_wayland_surface_get_wl_output (surface));
|
||||
pointer_surface_update_scale (tablet->master);
|
||||
|
||||
GDK_DISPLAY_NOTE (seat->display, EVENTS,
|
||||
g_message ("proximity in, seat %p surface %p tool %d",
|
||||
seat, tablet->pointer_info.focus,
|
||||
@@ -3515,7 +3537,11 @@ tablet_tool_handle_proximity_out (void *data,
|
||||
|
||||
gdk_wayland_pointer_stop_cursor_animation (&tablet->pointer_info);
|
||||
|
||||
gdk_wayland_device_update_surface_cursor (tablet->master);
|
||||
tablet->pointer_info.pointer_surface_outputs =
|
||||
g_slist_remove (tablet->pointer_info.pointer_surface_outputs,
|
||||
gdk_wayland_surface_get_wl_output (tablet->pointer_info.focus));
|
||||
pointer_surface_update_scale (tablet->master);
|
||||
|
||||
g_object_unref (tablet->pointer_info.focus);
|
||||
tablet->pointer_info.focus = NULL;
|
||||
|
||||
@@ -4315,14 +4341,11 @@ tablet_seat_handle_tablet_added (void *data,
|
||||
struct zwp_tablet_v2 *wp_tablet)
|
||||
{
|
||||
GdkWaylandSeat *seat = data;
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (seat->display);
|
||||
GdkWaylandTabletData *tablet;
|
||||
|
||||
tablet = g_new0 (GdkWaylandTabletData, 1);
|
||||
tablet->seat = GDK_SEAT (seat);
|
||||
tablet->pointer_info.current_output_scale = 1;
|
||||
tablet->pointer_info.pointer_surface =
|
||||
wl_compositor_create_surface (display_wayland->compositor);
|
||||
|
||||
tablet->wp_tablet = wp_tablet;
|
||||
|
||||
seat->tablets = g_list_prepend (seat->tablets, tablet);
|
||||
@@ -4439,7 +4462,15 @@ pointer_surface_update_scale (GdkDevice *device)
|
||||
void
|
||||
gdk_wayland_seat_update_cursor_scale (GdkWaylandSeat *seat)
|
||||
{
|
||||
GList *l;
|
||||
|
||||
pointer_surface_update_scale (seat->master_pointer);
|
||||
|
||||
for (l = seat->tablets; l; l = l->next)
|
||||
{
|
||||
GdkWaylandTabletData *tablet = l->data;
|
||||
pointer_surface_update_scale (tablet->master);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -4448,16 +4479,28 @@ pointer_surface_enter (void *data,
|
||||
struct wl_output *output)
|
||||
|
||||
{
|
||||
GdkWaylandSeat *seat = data;
|
||||
GdkDevice *device = data;
|
||||
GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (gdk_device_get_seat (device));
|
||||
GdkWaylandTabletData *tablet;
|
||||
|
||||
GDK_DISPLAY_NOTE (seat->display, EVENTS,
|
||||
g_message ("pointer surface of seat %p entered output %p",
|
||||
seat, output));
|
||||
|
||||
seat->pointer_info.pointer_surface_outputs =
|
||||
g_slist_append (seat->pointer_info.pointer_surface_outputs, output);
|
||||
tablet = gdk_wayland_seat_find_tablet (seat, device);
|
||||
|
||||
pointer_surface_update_scale (seat->master_pointer);
|
||||
if (tablet)
|
||||
{
|
||||
tablet->pointer_info.pointer_surface_outputs =
|
||||
g_slist_append (seat->pointer_info.pointer_surface_outputs, output);
|
||||
}
|
||||
else
|
||||
{
|
||||
seat->pointer_info.pointer_surface_outputs =
|
||||
g_slist_append (seat->pointer_info.pointer_surface_outputs, output);
|
||||
}
|
||||
|
||||
pointer_surface_update_scale (device);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -4465,16 +4508,28 @@ pointer_surface_leave (void *data,
|
||||
struct wl_surface *wl_surface,
|
||||
struct wl_output *output)
|
||||
{
|
||||
GdkWaylandSeat *seat = data;
|
||||
GdkDevice *device = data;
|
||||
GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (gdk_device_get_seat (device));
|
||||
GdkWaylandTabletData *tablet;
|
||||
|
||||
GDK_DISPLAY_NOTE (seat->display, EVENTS,
|
||||
g_message ("pointer surface of seat %p left output %p",
|
||||
seat, output));
|
||||
|
||||
seat->pointer_info.pointer_surface_outputs =
|
||||
g_slist_remove (seat->pointer_info.pointer_surface_outputs, output);
|
||||
tablet = gdk_wayland_seat_find_tablet (seat, device);
|
||||
|
||||
pointer_surface_update_scale (seat->master_pointer);
|
||||
if (tablet)
|
||||
{
|
||||
tablet->pointer_info.pointer_surface_outputs =
|
||||
g_slist_remove (seat->pointer_info.pointer_surface_outputs, output);
|
||||
}
|
||||
else
|
||||
{
|
||||
seat->pointer_info.pointer_surface_outputs =
|
||||
g_slist_remove (seat->pointer_info.pointer_surface_outputs, output);
|
||||
}
|
||||
|
||||
pointer_surface_update_scale (device);
|
||||
}
|
||||
|
||||
static const struct wl_surface_listener pointer_surface_listener = {
|
||||
@@ -4842,6 +4897,23 @@ gdk_wayland_seat_init (GdkWaylandSeat *seat)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
init_pointer_data (GdkWaylandPointerData *pointer_data,
|
||||
GdkDisplay *display,
|
||||
GdkDevice *master)
|
||||
{
|
||||
GdkWaylandDisplay *display_wayland;
|
||||
|
||||
display_wayland = GDK_WAYLAND_DISPLAY (display);
|
||||
|
||||
pointer_data->current_output_scale = 1;
|
||||
pointer_data->pointer_surface =
|
||||
wl_compositor_create_surface (display_wayland->compositor);
|
||||
wl_surface_add_listener (pointer_data->pointer_surface,
|
||||
&pointer_surface_listener,
|
||||
master);
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_wayland_display_create_seat (GdkWaylandDisplay *display_wayland,
|
||||
guint32 id,
|
||||
@@ -4880,14 +4952,8 @@ _gdk_wayland_display_create_seat (GdkWaylandDisplay *display_wayland,
|
||||
wl_data_device_add_listener (seat->data_device,
|
||||
&data_device_listener, seat);
|
||||
|
||||
seat->pointer_info.current_output_scale = 1;
|
||||
seat->pointer_info.pointer_surface =
|
||||
wl_compositor_create_surface (display_wayland->compositor);
|
||||
wl_surface_add_listener (seat->pointer_info.pointer_surface,
|
||||
&pointer_surface_listener,
|
||||
seat);
|
||||
|
||||
init_devices (seat);
|
||||
init_pointer_data (&seat->pointer_info, display, seat->master_pointer);
|
||||
|
||||
if (display_wayland->tablet_manager)
|
||||
{
|
||||
@@ -4962,31 +5028,29 @@ _gdk_wayland_device_get_implicit_grab_serial (GdkWaylandDevice *device,
|
||||
}
|
||||
}
|
||||
|
||||
return GDK_WAYLAND_SEAT (seat)->pointer_info.press_serial;
|
||||
return GDK_WAYLAND_SEAT (seat)->pointer_info.press_serial;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
_gdk_wayland_seat_get_last_implicit_grab_serial (GdkSeat *seat,
|
||||
_gdk_wayland_seat_get_last_implicit_grab_serial (GdkWaylandSeat *seat,
|
||||
GdkEventSequence **sequence)
|
||||
{
|
||||
GdkWaylandSeat *wayland_seat;
|
||||
GdkWaylandTouchData *touch;
|
||||
GHashTableIter iter;
|
||||
GList *l;
|
||||
uint32_t serial;
|
||||
|
||||
wayland_seat = GDK_WAYLAND_SEAT (seat);
|
||||
g_hash_table_iter_init (&iter, wayland_seat->touches);
|
||||
g_hash_table_iter_init (&iter, seat->touches);
|
||||
|
||||
if (sequence)
|
||||
*sequence = NULL;
|
||||
|
||||
serial = wayland_seat->keyboard_key_serial;
|
||||
serial = seat->keyboard_key_serial;
|
||||
|
||||
if (wayland_seat->pointer_info.press_serial > serial)
|
||||
serial = wayland_seat->pointer_info.press_serial;
|
||||
if (seat->pointer_info.press_serial > serial)
|
||||
serial = seat->pointer_info.press_serial;
|
||||
|
||||
for (l = wayland_seat->tablets; l; l = l->next)
|
||||
for (l = seat->tablets; l; l = l->next)
|
||||
{
|
||||
GdkWaylandTabletData *tablet = l->data;
|
||||
|
||||
|
||||
@@ -396,6 +396,8 @@ static void gdk_wayland_display_add_output (GdkWaylandDisplay *display_wa
|
||||
guint32 version);
|
||||
static void gdk_wayland_display_remove_output (GdkWaylandDisplay *display_wayland,
|
||||
guint32 id);
|
||||
static void gdk_wayland_display_init_xdg_output (GdkWaylandDisplay *display_wayland);
|
||||
static void gdk_wayland_display_get_xdg_output (GdkWaylandMonitor *monitor);
|
||||
|
||||
static void
|
||||
gdk_registry_handle_global (void *data,
|
||||
@@ -527,6 +529,13 @@ gdk_registry_handle_global (void *data,
|
||||
&server_decoration_listener,
|
||||
display_wayland);
|
||||
}
|
||||
else if (strcmp(interface, "zxdg_output_manager_v1") == 0)
|
||||
{
|
||||
display_wayland->xdg_output_manager =
|
||||
wl_registry_bind (registry, id, &zxdg_output_manager_v1_interface, 1);
|
||||
gdk_wayland_display_init_xdg_output (display_wayland);
|
||||
_gdk_wayland_display_async_roundtrip (display_wayland);
|
||||
}
|
||||
|
||||
g_hash_table_insert (display_wayland->known_globals,
|
||||
GUINT_TO_POINTER (id), g_strdup (interface));
|
||||
@@ -2170,6 +2179,123 @@ update_scale (GdkDisplay *display)
|
||||
g_list_free (seats);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_display_init_xdg_output (GdkWaylandDisplay *display_wayland)
|
||||
{
|
||||
int i;
|
||||
|
||||
GDK_NOTE (MISC,
|
||||
g_message ("init xdg-output support, %d monitor(s) already present",
|
||||
display_wayland->monitors->len));
|
||||
|
||||
for (i = 0; i < display_wayland->monitors->len; i++)
|
||||
gdk_wayland_display_get_xdg_output (display_wayland->monitors->pdata[i]);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
display_has_xdg_output_support (GdkWaylandDisplay *display_wayland)
|
||||
{
|
||||
return (display_wayland->xdg_output_manager != NULL);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
monitor_has_xdg_output (GdkWaylandMonitor *monitor)
|
||||
{
|
||||
return (monitor->xdg_output != NULL);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
should_update_monitor (GdkWaylandMonitor *monitor)
|
||||
{
|
||||
return (GDK_MONITOR (monitor)->geometry.width != 0 &&
|
||||
monitor->version < OUTPUT_VERSION_WITH_DONE);
|
||||
}
|
||||
|
||||
static void
|
||||
apply_monitor_change (GdkWaylandMonitor *monitor)
|
||||
{
|
||||
GDK_NOTE (MISC,
|
||||
g_message ("monitor %d changed position %d %d, size %d %d",
|
||||
monitor->id,
|
||||
monitor->x, monitor->y,
|
||||
monitor->width, monitor->height));
|
||||
|
||||
gdk_monitor_set_position (GDK_MONITOR (monitor), monitor->x, monitor->y);
|
||||
gdk_monitor_set_size (GDK_MONITOR (monitor), monitor->width, monitor->height);
|
||||
monitor->wl_output_done = FALSE;
|
||||
monitor->xdg_output_done = FALSE;
|
||||
|
||||
update_scale (GDK_MONITOR (monitor)->display);
|
||||
}
|
||||
|
||||
static void
|
||||
xdg_output_handle_logical_position (void *data,
|
||||
struct zxdg_output_v1 *xdg_output,
|
||||
int32_t x,
|
||||
int32_t y)
|
||||
{
|
||||
GdkWaylandMonitor *monitor = (GdkWaylandMonitor *) data;
|
||||
|
||||
GDK_NOTE (MISC,
|
||||
g_message ("handle logical position xdg-output %d, position %d %d",
|
||||
monitor->id, x, y));
|
||||
monitor->x = x;
|
||||
monitor->y = y;
|
||||
}
|
||||
|
||||
static void
|
||||
xdg_output_handle_logical_size (void *data,
|
||||
struct zxdg_output_v1 *xdg_output,
|
||||
int32_t width,
|
||||
int32_t height)
|
||||
{
|
||||
GdkWaylandMonitor *monitor = (GdkWaylandMonitor *) data;
|
||||
|
||||
GDK_NOTE (MISC,
|
||||
g_message ("handle logical size xdg-output %d, size %d %d",
|
||||
monitor->id, width, height));
|
||||
monitor->width = width;
|
||||
monitor->height = height;
|
||||
}
|
||||
|
||||
static void
|
||||
xdg_output_handle_done (void *data,
|
||||
struct zxdg_output_v1 *xdg_output)
|
||||
{
|
||||
GdkWaylandMonitor *monitor = (GdkWaylandMonitor *) data;
|
||||
|
||||
GDK_NOTE (MISC,
|
||||
g_message ("handle done xdg-output %d", monitor->id));
|
||||
|
||||
monitor->xdg_output_done = TRUE;
|
||||
if (monitor->wl_output_done)
|
||||
apply_monitor_change (monitor);
|
||||
}
|
||||
|
||||
static const struct zxdg_output_v1_listener xdg_output_listener = {
|
||||
xdg_output_handle_logical_position,
|
||||
xdg_output_handle_logical_size,
|
||||
xdg_output_handle_done,
|
||||
};
|
||||
|
||||
static void
|
||||
gdk_wayland_display_get_xdg_output (GdkWaylandMonitor *monitor)
|
||||
{
|
||||
GdkDisplay *display = GDK_MONITOR (monitor)->display;
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
|
||||
|
||||
GDK_NOTE (MISC,
|
||||
g_message ("get xdg-output for monitor %d", monitor->id));
|
||||
|
||||
monitor->xdg_output =
|
||||
zxdg_output_manager_v1_get_xdg_output (display_wayland->xdg_output_manager,
|
||||
monitor->output);
|
||||
|
||||
zxdg_output_v1_add_listener (monitor->xdg_output,
|
||||
&xdg_output_listener,
|
||||
monitor);
|
||||
}
|
||||
|
||||
static void
|
||||
output_handle_geometry (void *data,
|
||||
struct wl_output *wl_output,
|
||||
@@ -2188,13 +2314,17 @@ output_handle_geometry (void *data,
|
||||
g_message ("handle geometry output %d, position %d %d, phys. size %d %d, subpixel layout %s, manufacturer %s, model %s, transform %s",
|
||||
monitor->id, x, y, physical_width, physical_height, subpixel_to_string (subpixel), make, model, transform_to_string (transform)));
|
||||
|
||||
gdk_monitor_set_position (GDK_MONITOR (monitor), x, y);
|
||||
monitor->x = x;
|
||||
monitor->y = y;
|
||||
gdk_monitor_set_physical_size (GDK_MONITOR (monitor), physical_width, physical_height);
|
||||
gdk_monitor_set_subpixel_layout (GDK_MONITOR (monitor), subpixel);
|
||||
gdk_monitor_set_manufacturer (GDK_MONITOR (monitor), make);
|
||||
gdk_monitor_set_model (GDK_MONITOR (monitor), model);
|
||||
|
||||
if (GDK_MONITOR (monitor)->geometry.width != 0 && monitor->version < OUTPUT_VERSION_WITH_DONE)
|
||||
if (should_update_monitor (monitor) || !monitor_has_xdg_output (monitor))
|
||||
apply_monitor_change (monitor);
|
||||
|
||||
if (should_update_monitor (monitor))
|
||||
update_scale (GDK_MONITOR (monitor)->display);
|
||||
}
|
||||
|
||||
@@ -2203,19 +2333,14 @@ output_handle_done (void *data,
|
||||
struct wl_output *wl_output)
|
||||
{
|
||||
GdkWaylandMonitor *monitor = (GdkWaylandMonitor *)data;
|
||||
GdkDisplay *display = gdk_monitor_get_display (GDK_MONITOR (monitor));
|
||||
|
||||
GDK_NOTE (MISC,
|
||||
g_message ("handle done output %d", monitor->id));
|
||||
|
||||
if (!monitor->added)
|
||||
{
|
||||
monitor->added = TRUE;
|
||||
g_ptr_array_add (GDK_WAYLAND_DISPLAY (display)->monitors, monitor);
|
||||
gdk_display_monitor_added (display, GDK_MONITOR (monitor));
|
||||
}
|
||||
monitor->wl_output_done = TRUE;
|
||||
|
||||
update_scale (display);
|
||||
if (!monitor_has_xdg_output (monitor) || monitor->xdg_output_done)
|
||||
apply_monitor_change (monitor);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -2232,6 +2357,9 @@ output_handle_scale (void *data,
|
||||
GDK_NOTE (MISC,
|
||||
g_message ("handle scale output %d, scale %d", monitor->id, scale));
|
||||
|
||||
if (monitor_has_xdg_output (monitor))
|
||||
return;
|
||||
|
||||
gdk_monitor_get_geometry (GDK_MONITOR (monitor), &previous_geometry);
|
||||
previous_scale = gdk_monitor_get_scale_factor (GDK_MONITOR (monitor));
|
||||
|
||||
@@ -2239,10 +2367,11 @@ output_handle_scale (void *data,
|
||||
height = previous_geometry.height * previous_scale;
|
||||
|
||||
gdk_monitor_set_scale_factor (GDK_MONITOR (monitor), scale);
|
||||
gdk_monitor_set_size (GDK_MONITOR (monitor), width / scale, height / scale);
|
||||
monitor->width = width / scale;
|
||||
monitor->height = height / scale;
|
||||
|
||||
if (GDK_MONITOR (monitor)->geometry.width != 0 && monitor->version < OUTPUT_VERSION_WITH_DONE)
|
||||
update_scale (GDK_MONITOR (monitor)->display);
|
||||
if (should_update_monitor (monitor))
|
||||
apply_monitor_change (monitor);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -2264,11 +2393,12 @@ output_handle_mode (void *data,
|
||||
return;
|
||||
|
||||
scale = gdk_monitor_get_scale_factor (GDK_MONITOR (monitor));
|
||||
gdk_monitor_set_size (GDK_MONITOR (monitor), width / scale, height / scale);
|
||||
monitor->width = width / scale;
|
||||
monitor->height = height / scale;
|
||||
gdk_monitor_set_refresh_rate (GDK_MONITOR (monitor), refresh);
|
||||
|
||||
if (width != 0 && monitor->version < OUTPUT_VERSION_WITH_DONE)
|
||||
update_scale (GDK_MONITOR (monitor)->display);
|
||||
if (should_update_monitor (monitor) || !monitor_has_xdg_output (monitor))
|
||||
apply_monitor_change (monitor);
|
||||
}
|
||||
|
||||
static const struct wl_output_listener output_listener =
|
||||
@@ -2295,13 +2425,17 @@ gdk_wayland_display_add_output (GdkWaylandDisplay *display_wayland,
|
||||
monitor->output = output;
|
||||
monitor->version = version;
|
||||
|
||||
if (monitor->version < OUTPUT_VERSION_WITH_DONE)
|
||||
{
|
||||
g_ptr_array_add (display_wayland->monitors, monitor);
|
||||
gdk_display_monitor_added (GDK_DISPLAY (display_wayland), GDK_MONITOR (monitor));
|
||||
}
|
||||
g_ptr_array_add (display_wayland->monitors, monitor);
|
||||
gdk_display_monitor_added (GDK_DISPLAY (display_wayland), GDK_MONITOR (monitor));
|
||||
|
||||
wl_output_add_listener (output, &output_listener, monitor);
|
||||
|
||||
GDK_NOTE (MISC,
|
||||
g_message ("xdg_output_manager %p",
|
||||
display_wayland->xdg_output_manager));
|
||||
|
||||
if (display_has_xdg_output_support (display_wayland))
|
||||
gdk_wayland_display_get_xdg_output (monitor);
|
||||
}
|
||||
|
||||
struct wl_output *
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include <gdk/wayland/xdg-foreign-unstable-v1-client-protocol.h>
|
||||
#include <gdk/wayland/keyboard-shortcuts-inhibit-unstable-v1-client-protocol.h>
|
||||
#include <gdk/wayland/server-decoration-client-protocol.h>
|
||||
#include <gdk/wayland/xdg-output-unstable-v1-client-protocol.h>
|
||||
|
||||
#include <glib.h>
|
||||
#include <gdk/gdkkeys.h>
|
||||
@@ -109,6 +110,7 @@ struct _GdkWaylandDisplay
|
||||
struct zxdg_importer_v1 *xdg_importer;
|
||||
struct zwp_keyboard_shortcuts_inhibit_manager_v1 *keyboard_shortcuts_inhibit;
|
||||
struct org_kde_kwin_server_decoration_manager *server_decoration_manager;
|
||||
struct zxdg_output_manager_v1 *xdg_output_manager;
|
||||
|
||||
GList *async_roundtrips;
|
||||
|
||||
|
||||
@@ -151,6 +151,9 @@ _gdk_wayland_display_deliver_event (GdkDisplay *display,
|
||||
{
|
||||
GList *node;
|
||||
|
||||
if (!check_event_sanity (event))
|
||||
g_warning ("Snap! delivering insane events\n");
|
||||
|
||||
node = _gdk_event_queue_append (display, event);
|
||||
_gdk_windowing_got_event (display, node, event,
|
||||
_gdk_display_get_next_serial (display));
|
||||
|
||||
@@ -30,6 +30,15 @@ struct _GdkWaylandMonitor {
|
||||
guint32 version;
|
||||
struct wl_output *output;
|
||||
gboolean added;
|
||||
|
||||
struct zxdg_output_v1 *xdg_output;
|
||||
/* Size and position, can be either from wl_output or xdg_output */
|
||||
int32_t x;
|
||||
int32_t y;
|
||||
int32_t width;
|
||||
int32_t height;
|
||||
gboolean wl_output_done;
|
||||
gboolean xdg_output_done;
|
||||
};
|
||||
|
||||
struct _GdkWaylandMonitorClass {
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include <gdk/gdkcursor.h>
|
||||
#include <gdk/wayland/gdkwayland.h>
|
||||
#include <gdk/wayland/gdkdisplay-wayland.h>
|
||||
#include <gdk/wayland/gdkseat-wayland.h>
|
||||
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
|
||||
@@ -138,7 +139,7 @@ void _gdk_wayland_display_remove_seat (GdkWaylandDisplay *displa
|
||||
GdkKeymap *_gdk_wayland_device_get_keymap (GdkDevice *device);
|
||||
uint32_t _gdk_wayland_device_get_implicit_grab_serial(GdkWaylandDevice *device,
|
||||
const GdkEvent *event);
|
||||
uint32_t _gdk_wayland_seat_get_last_implicit_grab_serial (GdkSeat *seat,
|
||||
uint32_t _gdk_wayland_seat_get_last_implicit_grab_serial (GdkWaylandSeat *seat,
|
||||
GdkEventSequence **seqence);
|
||||
struct wl_data_device * gdk_wayland_device_get_data_device (GdkDevice *gdk_device);
|
||||
void gdk_wayland_device_set_selection (GdkDevice *gdk_device,
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include "gdkdeviceprivate.h"
|
||||
#include "gdkprivate-wayland.h"
|
||||
#include "gdkmonitor-wayland.h"
|
||||
#include "gdkseat-wayland.h"
|
||||
#include <wayland/xdg-shell-unstable-v6-client-protocol.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
@@ -861,7 +862,7 @@ gdk_wayland_surface_update_dialogs (GdkSurface *surface)
|
||||
GdkSurface *w = l->data;
|
||||
GdkSurfaceImplWayland *impl;
|
||||
|
||||
if (!GDK_IS_SURFACE_IMPL_WAYLAND(w->impl))
|
||||
if (!GDK_IS_SURFACE_IMPL_WAYLAND (w->impl))
|
||||
continue;
|
||||
|
||||
impl = GDK_SURFACE_IMPL_WAYLAND (w->impl);
|
||||
@@ -2185,14 +2186,12 @@ create_simple_positioner (GdkSurface *surface,
|
||||
static void
|
||||
gdk_wayland_surface_create_xdg_popup (GdkSurface *surface,
|
||||
GdkSurface *parent,
|
||||
struct wl_seat *seat)
|
||||
GdkWaylandSeat *grab_input_seat)
|
||||
{
|
||||
GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface));
|
||||
GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
|
||||
GdkSurfaceImplWayland *parent_impl = GDK_SURFACE_IMPL_WAYLAND (parent->impl);
|
||||
gpointer positioner;
|
||||
GdkSeat *gdk_seat;
|
||||
guint32 serial;
|
||||
|
||||
if (!impl->display_server.wl_surface)
|
||||
return;
|
||||
@@ -2210,10 +2209,11 @@ gdk_wayland_surface_create_xdg_popup (GdkSurface *surface,
|
||||
g_warning ("Can't map popup, already mapped");
|
||||
return;
|
||||
}
|
||||
if ((display->current_popups &&
|
||||
g_list_last (display->current_popups)->data != parent) ||
|
||||
(!display->current_popups &&
|
||||
!is_realized_toplevel (parent)))
|
||||
if (grab_input_seat &&
|
||||
((display->current_popups &&
|
||||
g_list_last (display->current_popups)->data != parent) ||
|
||||
(!display->current_popups &&
|
||||
!is_realized_toplevel (parent))))
|
||||
{
|
||||
g_warning ("Tried to map a popup with a non-top most parent");
|
||||
return;
|
||||
@@ -2264,10 +2264,13 @@ gdk_wayland_surface_create_xdg_popup (GdkSurface *surface,
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
if (seat)
|
||||
if (grab_input_seat)
|
||||
{
|
||||
gdk_seat = gdk_display_get_default_seat (GDK_DISPLAY (display));
|
||||
serial = _gdk_wayland_seat_get_last_implicit_grab_serial (gdk_seat, NULL);
|
||||
struct wl_seat *seat;
|
||||
guint32 serial;
|
||||
|
||||
seat = gdk_wayland_seat_get_wl_seat (GDK_SEAT (grab_input_seat));
|
||||
serial = _gdk_wayland_seat_get_last_implicit_grab_serial (grab_input_seat, NULL);
|
||||
|
||||
switch (display->shell_variant)
|
||||
{
|
||||
@@ -2288,7 +2291,7 @@ gdk_wayland_surface_create_xdg_popup (GdkSurface *surface,
|
||||
display->current_popups = g_list_append (display->current_popups, surface);
|
||||
}
|
||||
|
||||
static struct wl_seat *
|
||||
static GdkWaylandSeat *
|
||||
find_grab_input_seat (GdkSurface *surface,
|
||||
GdkSurface *transient_for)
|
||||
{
|
||||
@@ -2301,7 +2304,7 @@ find_grab_input_seat (GdkSurface *surface,
|
||||
* grab before showing the popup surface.
|
||||
*/
|
||||
if (impl->grab_input_seat)
|
||||
return gdk_wayland_seat_get_wl_seat (impl->grab_input_seat);
|
||||
return GDK_WAYLAND_SEAT (impl->grab_input_seat);
|
||||
|
||||
/* HACK: GtkMenu grabs a special surface known as the "grab transfer surface"
|
||||
* and then transfers the grab over to the correct surface later. Look for
|
||||
@@ -2314,7 +2317,7 @@ find_grab_input_seat (GdkSurface *surface,
|
||||
{
|
||||
tmp_impl = GDK_SURFACE_IMPL_WAYLAND (attached_grab_surface->impl);
|
||||
if (tmp_impl->grab_input_seat)
|
||||
return gdk_wayland_seat_get_wl_seat (tmp_impl->grab_input_seat);
|
||||
return GDK_WAYLAND_SEAT (tmp_impl->grab_input_seat);
|
||||
}
|
||||
|
||||
while (transient_for)
|
||||
@@ -2322,7 +2325,7 @@ find_grab_input_seat (GdkSurface *surface,
|
||||
tmp_impl = GDK_SURFACE_IMPL_WAYLAND (transient_for->impl);
|
||||
|
||||
if (tmp_impl->grab_input_seat)
|
||||
return gdk_wayland_seat_get_wl_seat (tmp_impl->grab_input_seat);
|
||||
return GDK_WAYLAND_SEAT (tmp_impl->grab_input_seat);
|
||||
|
||||
transient_for = tmp_impl->transient_for;
|
||||
}
|
||||
@@ -2418,7 +2421,7 @@ gdk_wayland_surface_map (GdkSurface *surface)
|
||||
if (should_map_as_popup (surface))
|
||||
{
|
||||
gboolean create_fallback = FALSE;
|
||||
struct wl_seat *grab_input_seat;
|
||||
GdkWaylandSeat *grab_input_seat;
|
||||
|
||||
/* Popup menus can appear without a transient parent, which means they
|
||||
* cannot be positioned properly on Wayland. This attempts to guess the
|
||||
@@ -2492,8 +2495,8 @@ gdk_wayland_surface_map (GdkSurface *surface)
|
||||
if (!create_fallback)
|
||||
{
|
||||
gdk_wayland_surface_create_xdg_popup (surface,
|
||||
transient_for,
|
||||
grab_input_seat);
|
||||
transient_for,
|
||||
grab_input_seat);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -3063,24 +3066,6 @@ gdk_wayland_surface_set_modal_hint (GdkSurface *surface,
|
||||
maybe_set_gtk_surface_modal (surface);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_surface_set_skip_taskbar_hint (GdkSurface *surface,
|
||||
gboolean skips_taskbar)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_surface_set_skip_pager_hint (GdkSurface *surface,
|
||||
gboolean skips_pager)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_surface_set_urgency_hint (GdkSurface *surface,
|
||||
gboolean urgent)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_surface_set_geometry_hints (GdkSurface *surface,
|
||||
const GdkGeometry *geometry,
|
||||
@@ -3517,18 +3502,6 @@ gdk_wayland_surface_set_keep_below (GdkSurface *surface,
|
||||
{
|
||||
}
|
||||
|
||||
static GdkSurface *
|
||||
gdk_wayland_surface_get_group (GdkSurface *surface)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_surface_set_group (GdkSurface *surface,
|
||||
GdkSurface *leader)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_surface_set_decorations (GdkSurface *surface,
|
||||
GdkWMDecoration decorations)
|
||||
@@ -3611,7 +3584,7 @@ gdk_wayland_surface_begin_resize_drag (GdkSurface *surface,
|
||||
if (!is_realized_toplevel (surface))
|
||||
return;
|
||||
|
||||
serial = _gdk_wayland_seat_get_last_implicit_grab_serial (gdk_device_get_seat (device),
|
||||
serial = _gdk_wayland_seat_get_last_implicit_grab_serial (GDK_WAYLAND_SEAT (gdk_device_get_seat (device)),
|
||||
&sequence);
|
||||
|
||||
switch (display_wayland->shell_variant)
|
||||
@@ -3662,7 +3635,7 @@ gdk_wayland_surface_begin_move_drag (GdkSurface *surface,
|
||||
if (!is_realized_toplevel (surface))
|
||||
return;
|
||||
|
||||
serial = _gdk_wayland_seat_get_last_implicit_grab_serial (gdk_device_get_seat (device),
|
||||
serial = _gdk_wayland_seat_get_last_implicit_grab_serial (GDK_WAYLAND_SEAT (gdk_device_get_seat (device)),
|
||||
&sequence);
|
||||
switch (display_wayland->shell_variant)
|
||||
{
|
||||
@@ -3846,9 +3819,6 @@ _gdk_surface_impl_wayland_class_init (GdkSurfaceImplWaylandClass *klass)
|
||||
impl_class->set_type_hint = gdk_wayland_surface_set_type_hint;
|
||||
impl_class->get_type_hint = gdk_wayland_surface_get_type_hint;
|
||||
impl_class->set_modal_hint = gdk_wayland_surface_set_modal_hint;
|
||||
impl_class->set_skip_taskbar_hint = gdk_wayland_surface_set_skip_taskbar_hint;
|
||||
impl_class->set_skip_pager_hint = gdk_wayland_surface_set_skip_pager_hint;
|
||||
impl_class->set_urgency_hint = gdk_wayland_surface_set_urgency_hint;
|
||||
impl_class->set_geometry_hints = gdk_wayland_surface_set_geometry_hints;
|
||||
impl_class->set_title = gdk_wayland_surface_set_title;
|
||||
impl_class->set_startup_id = gdk_wayland_surface_set_startup_id;
|
||||
@@ -3869,8 +3839,6 @@ _gdk_surface_impl_wayland_class_init (GdkSurfaceImplWaylandClass *klass)
|
||||
impl_class->unfullscreen = gdk_wayland_surface_unfullscreen;
|
||||
impl_class->set_keep_above = gdk_wayland_surface_set_keep_above;
|
||||
impl_class->set_keep_below = gdk_wayland_surface_set_keep_below;
|
||||
impl_class->get_group = gdk_wayland_surface_get_group;
|
||||
impl_class->set_group = gdk_wayland_surface_set_group;
|
||||
impl_class->set_decorations = gdk_wayland_surface_set_decorations;
|
||||
impl_class->get_decorations = gdk_wayland_surface_get_decorations;
|
||||
impl_class->set_functions = gdk_wayland_surface_set_functions;
|
||||
|
||||
@@ -58,6 +58,7 @@ proto_sources = [
|
||||
['tablet', 'unstable', 'v2', ],
|
||||
['keyboard-shortcuts-inhibit', 'unstable', 'v1', ],
|
||||
['server-decoration', 'private' ],
|
||||
['xdg-output', 'unstable', 'v1', ],
|
||||
]
|
||||
|
||||
gdk_wayland_gen_headers = []
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
|
||||
G_DEFINE_TYPE (GdkWin32CairoContext, gdk_win32_cairo_context, GDK_TYPE_CAIRO_CONTEXT)
|
||||
|
||||
static void
|
||||
void
|
||||
gdk_win32_surface_get_queued_window_rect (GdkSurface *surface,
|
||||
gint scale,
|
||||
RECT *return_window_rect)
|
||||
@@ -53,7 +53,7 @@ gdk_win32_surface_get_queued_window_rect (GdkSurface *surface,
|
||||
*return_window_rect = window_rect;
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
gdk_win32_surface_apply_queued_move_resize (GdkSurface *surface,
|
||||
RECT window_rect)
|
||||
{
|
||||
|
||||
@@ -2830,8 +2830,8 @@ gdk_event_translate (MSG *msg,
|
||||
{
|
||||
generate_grab_broken_event (_gdk_device_manager, keyboard_grab->surface, TRUE, NULL);
|
||||
}
|
||||
G_GNUC_FALLTHROUGH;
|
||||
|
||||
/* fallthrough */
|
||||
case WM_SETFOCUS:
|
||||
if (keyboard_grab != NULL &&
|
||||
!keyboard_grab->owner_events)
|
||||
|
||||
@@ -166,6 +166,27 @@ gdk_win32_gl_context_begin_frame (GdkDrawContext *draw_context,
|
||||
{
|
||||
GdkGLContext *context = GDK_GL_CONTEXT (draw_context);
|
||||
GdkSurface *surface;
|
||||
GdkSurfaceImplWin32 *impl;
|
||||
RECT queued_window_rect;
|
||||
|
||||
surface = gdk_gl_context_get_surface (context);
|
||||
impl = GDK_SURFACE_IMPL_WIN32 (surface->impl);
|
||||
|
||||
gdk_win32_surface_get_queued_window_rect (surface,
|
||||
gdk_surface_get_scale_factor (surface),
|
||||
&queued_window_rect);
|
||||
|
||||
/* Apply queued resizes GL windows before painting them
|
||||
* (we paint on the window DC directly, it must have the right size).
|
||||
* Due to some poorly-understood issue delayed
|
||||
* resizing of double-buffered windows can produce weird
|
||||
* artefacts, so these are also resized before we paint.
|
||||
*/
|
||||
if (impl->drag_move_resize_context.native_move_resize_pending)
|
||||
{
|
||||
impl->drag_move_resize_context.native_move_resize_pending = FALSE;
|
||||
gdk_win32_surface_apply_queued_move_resize (surface, queued_window_rect);
|
||||
}
|
||||
|
||||
GDK_DRAW_CONTEXT_CLASS (gdk_win32_gl_context_parent_class)->begin_frame (draw_context, update_area);
|
||||
if (gdk_gl_context_get_shared_context (context))
|
||||
@@ -176,7 +197,6 @@ gdk_win32_gl_context_begin_frame (GdkDrawContext *draw_context,
|
||||
|
||||
/* If nothing else is known, repaint everything so that the back
|
||||
buffer is fully up-to-date for the swapbuffer */
|
||||
surface = gdk_gl_context_get_surface (context);
|
||||
cairo_region_union_rectangle (update_area, &(GdkRectangle) {
|
||||
0, 0,
|
||||
gdk_surface_get_width (surface),
|
||||
|
||||
+13
-103
@@ -731,9 +731,6 @@ _gdk_win32_display_create_surface_impl (GdkDisplay *display,
|
||||
return;
|
||||
}
|
||||
|
||||
// if (!from_set_skip_taskbar_hint && window->surface_type == GDK_SURFACE_TEMP)
|
||||
// gdk_surface_set_skip_taskbar_hint (window, TRUE);
|
||||
|
||||
_gdk_win32_surface_enable_transparency (window);
|
||||
|
||||
frame_clock = gdk_surface_get_frame_clock (window);
|
||||
@@ -1407,9 +1404,9 @@ gdk_win32_surface_lower (GdkSurface *window)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
gdk_win32_surface_set_urgency_hint (GdkSurface *window,
|
||||
gboolean urgent)
|
||||
gboolean urgent)
|
||||
{
|
||||
FLASHWINFO flashwinfo;
|
||||
typedef BOOL (WINAPI *PFN_FlashWindowEx) (FLASHWINFO*);
|
||||
@@ -1503,8 +1500,6 @@ get_effective_window_decorations (GdkSurface *window,
|
||||
|
||||
case GDK_SURFACE_TYPE_HINT_TOOLBAR:
|
||||
case GDK_SURFACE_TYPE_HINT_UTILITY:
|
||||
gdk_surface_set_skip_taskbar_hint (window, TRUE);
|
||||
gdk_surface_set_skip_pager_hint (window, TRUE);
|
||||
*decoration = (GDK_DECOR_ALL | GDK_DECOR_MINIMIZE | GDK_DECOR_MAXIMIZE);
|
||||
return TRUE;
|
||||
|
||||
@@ -2071,32 +2066,6 @@ gdk_win32_surface_set_icon_name (GdkSurface *window,
|
||||
#endif
|
||||
}
|
||||
|
||||
static GdkSurface *
|
||||
gdk_win32_surface_get_group (GdkSurface *window)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_SURFACE (window), NULL);
|
||||
|
||||
if (GDK_SURFACE_DESTROYED (window))
|
||||
return NULL;
|
||||
|
||||
g_warning ("gdk_surface_get_group not yet implemented");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_win32_surface_set_group (GdkSurface *window,
|
||||
GdkSurface *leader)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_SURFACE (window));
|
||||
g_return_if_fail (leader == NULL || GDK_IS_SURFACE (leader));
|
||||
|
||||
if (GDK_SURFACE_DESTROYED (window) || GDK_SURFACE_DESTROYED (leader))
|
||||
return;
|
||||
|
||||
g_warning ("gdk_surface_set_group not implemented");
|
||||
}
|
||||
|
||||
static void
|
||||
update_single_bit (LONG *style,
|
||||
gboolean all,
|
||||
@@ -3865,8 +3834,8 @@ setup_drag_move_resize_context (GdkSurface *window,
|
||||
GdkSurfaceEdge edge,
|
||||
GdkDevice *device,
|
||||
gint button,
|
||||
gint root_x,
|
||||
gint root_y,
|
||||
gint x,
|
||||
gint y,
|
||||
guint32 timestamp)
|
||||
{
|
||||
RECT rect;
|
||||
@@ -3874,6 +3843,9 @@ setup_drag_move_resize_context (GdkSurface *window,
|
||||
GdkSurface *pointer_window;
|
||||
GdkSurfaceImplWin32 *impl = GDK_SURFACE_IMPL_WIN32 (window->impl);
|
||||
gboolean maximized = gdk_surface_get_state (window) & GDK_SURFACE_STATE_MAXIMIZED;
|
||||
gint root_x, root_y;
|
||||
|
||||
gdk_win32_surface_get_root_coords (window, x, y, &root_x, &root_y);
|
||||
|
||||
/* Before we drag, we need to undo any maximization or snapping.
|
||||
* AeroSnap behaviour:
|
||||
@@ -4507,8 +4479,8 @@ gdk_win32_surface_begin_resize_drag (GdkSurface *window,
|
||||
GdkSurfaceEdge edge,
|
||||
GdkDevice *device,
|
||||
gint button,
|
||||
gint root_x,
|
||||
gint root_y,
|
||||
gint x,
|
||||
gint y,
|
||||
guint32 timestamp)
|
||||
{
|
||||
GdkSurfaceImplWin32 *impl;
|
||||
@@ -4536,15 +4508,15 @@ gdk_win32_surface_begin_resize_drag (GdkSurface *window,
|
||||
|
||||
setup_drag_move_resize_context (window, &impl->drag_move_resize_context,
|
||||
GDK_WIN32_DRAGOP_RESIZE, edge, device,
|
||||
button, root_x, root_y, timestamp);
|
||||
button, x, y, timestamp);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_win32_surface_begin_move_drag (GdkSurface *window,
|
||||
GdkDevice *device,
|
||||
gint button,
|
||||
gint root_x,
|
||||
gint root_y,
|
||||
gint x,
|
||||
gint y,
|
||||
guint32 timestamp)
|
||||
{
|
||||
GdkSurfaceImplWin32 *impl;
|
||||
@@ -4571,7 +4543,7 @@ gdk_win32_surface_begin_move_drag (GdkSurface *window,
|
||||
|
||||
setup_drag_move_resize_context (window, &impl->drag_move_resize_context,
|
||||
GDK_WIN32_DRAGOP_MOVE, GDK_SURFACE_EDGE_NORTH_WEST,
|
||||
device, button, root_x, root_y, timestamp);
|
||||
device, button, x, y, timestamp);
|
||||
}
|
||||
|
||||
|
||||
@@ -4890,63 +4862,6 @@ gdk_win32_surface_set_modal_hint (GdkSurface *window,
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_win32_surface_set_skip_taskbar_hint (GdkSurface *window,
|
||||
gboolean skips_taskbar)
|
||||
{
|
||||
static GdkSurface *owner = NULL;
|
||||
//GdkSurfaceAttr wa;
|
||||
|
||||
g_return_if_fail (GDK_IS_SURFACE (window));
|
||||
|
||||
GDK_NOTE (MISC, g_print ("gdk_surface_set_skip_taskbar_hint: %p: %s, doing nothing\n",
|
||||
GDK_SURFACE_HWND (window),
|
||||
skips_taskbar ? "YES" : "NO"));
|
||||
|
||||
// ### TODO: Need to figure out what to do here.
|
||||
return;
|
||||
|
||||
if (skips_taskbar)
|
||||
{
|
||||
#if 0
|
||||
if (owner == NULL)
|
||||
{
|
||||
wa.surface_type = GDK_SURFACE_TEMP;
|
||||
wa.wclass = GDK_INPUT_OUTPUT;
|
||||
wa.width = wa.height = 1;
|
||||
owner = gdk_surface_new_internal (NULL, &wa, 0, TRUE);
|
||||
}
|
||||
#endif
|
||||
|
||||
SetWindowLongPtr (GDK_SURFACE_HWND (window), GWLP_HWNDPARENT, (LONG_PTR) GDK_SURFACE_HWND (owner));
|
||||
|
||||
#if 0 /* Should we also turn off the minimize and maximize buttons? */
|
||||
SetWindowLong (GDK_SURFACE_HWND (window), GWL_STYLE,
|
||||
GetWindowLong (GDK_SURFACE_HWND (window), GWL_STYLE) & ~(WS_MINIMIZEBOX|WS_MAXIMIZEBOX|WS_SYSMENU));
|
||||
|
||||
SetWindowPos (GDK_SURFACE_HWND (window), SWP_NOZORDER_SPECIFIED,
|
||||
0, 0, 0, 0,
|
||||
SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOMOVE |
|
||||
SWP_NOREPOSITION | SWP_NOSIZE | SWP_NOZORDER);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
SetWindowLongPtr (GDK_SURFACE_HWND (window), GWLP_HWNDPARENT, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_win32_surface_set_skip_pager_hint (GdkSurface *window,
|
||||
gboolean skips_pager)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_SURFACE (window));
|
||||
|
||||
GDK_NOTE (MISC, g_print ("gdk_surface_set_skip_pager_hint: %p: %s, doing nothing\n",
|
||||
GDK_SURFACE_HWND (window),
|
||||
skips_pager ? "YES" : "NO"));
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_win32_surface_set_type_hint (GdkSurface *window,
|
||||
GdkSurfaceTypeHint hint)
|
||||
@@ -5311,9 +5226,6 @@ gdk_surface_impl_win32_class_init (GdkSurfaceImplWin32Class *klass)
|
||||
impl_class->set_type_hint = gdk_win32_surface_set_type_hint;
|
||||
impl_class->get_type_hint = gdk_win32_surface_get_type_hint;
|
||||
impl_class->set_modal_hint = gdk_win32_surface_set_modal_hint;
|
||||
impl_class->set_skip_taskbar_hint = gdk_win32_surface_set_skip_taskbar_hint;
|
||||
impl_class->set_skip_pager_hint = gdk_win32_surface_set_skip_pager_hint;
|
||||
impl_class->set_urgency_hint = gdk_win32_surface_set_urgency_hint;
|
||||
impl_class->set_geometry_hints = gdk_win32_surface_set_geometry_hints;
|
||||
impl_class->set_title = gdk_win32_surface_set_title;
|
||||
//impl_class->set_startup_id = gdk_x11_surface_set_startup_id;
|
||||
@@ -5333,8 +5245,6 @@ gdk_surface_impl_win32_class_init (GdkSurfaceImplWin32Class *klass)
|
||||
impl_class->unfullscreen = gdk_win32_surface_unfullscreen;
|
||||
impl_class->set_keep_above = gdk_win32_surface_set_keep_above;
|
||||
impl_class->set_keep_below = gdk_win32_surface_set_keep_below;
|
||||
impl_class->get_group = gdk_win32_surface_get_group;
|
||||
impl_class->set_group = gdk_win32_surface_set_group;
|
||||
impl_class->set_decorations = gdk_win32_surface_set_decorations;
|
||||
impl_class->get_decorations = gdk_win32_surface_get_decorations;
|
||||
impl_class->set_functions = gdk_win32_surface_set_functions;
|
||||
|
||||
@@ -384,6 +384,15 @@ void _gdk_win32_update_layered_window_from_cache (GdkSurface *window,
|
||||
gboolean do_paint);
|
||||
|
||||
|
||||
void
|
||||
gdk_win32_surface_get_queued_window_rect (GdkSurface *surface,
|
||||
gint scale,
|
||||
RECT *return_window_rect);
|
||||
|
||||
void
|
||||
gdk_win32_surface_apply_queued_move_resize (GdkSurface *surface,
|
||||
RECT window_rect);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_SURFACE_WIN32_H__ */
|
||||
|
||||
@@ -50,6 +50,10 @@ typedef struct _GdkWin32SurfaceClass GdkWin32SurfaceClass;
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GType gdk_win32_surface_get_type (void);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_win32_surface_set_urgency_hint (GdkSurface *surface,
|
||||
gboolean urgent);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_X11_SURFACE_H__ */
|
||||
|
||||
@@ -31,8 +31,8 @@
|
||||
|
||||
|
||||
|
||||
#define APPEARS_FOCUSED(toplevel) \
|
||||
((toplevel)->has_focus || (toplevel)->has_focus_window || (toplevel)->has_pointer_focus)
|
||||
#define HAS_FOCUS(toplevel) \
|
||||
((toplevel)->has_focus || (toplevel)->has_pointer_focus)
|
||||
|
||||
static void gdk_x11_device_manager_core_finalize (GObject *object);
|
||||
static void gdk_x11_device_manager_core_constructed (GObject *object);
|
||||
@@ -752,7 +752,7 @@ _gdk_device_manager_core_handle_focus (GdkSurface *surface,
|
||||
if (toplevel->focus_window == original)
|
||||
return;
|
||||
|
||||
had_focus = APPEARS_FOCUSED (toplevel);
|
||||
had_focus = HAS_FOCUS (toplevel);
|
||||
x11_screen = GDK_X11_SCREEN (GDK_SURFACE_SCREEN (surface));
|
||||
|
||||
switch (detail)
|
||||
@@ -775,8 +775,8 @@ _gdk_device_manager_core_handle_focus (GdkSurface *surface,
|
||||
#endif /* XINPUT_2 */
|
||||
mode != NotifyUngrab)
|
||||
toplevel->has_pointer_focus = (focus_in) ? FALSE : TRUE;
|
||||
G_GNUC_FALLTHROUGH;
|
||||
|
||||
/* fall through */
|
||||
case NotifyNonlinear:
|
||||
case NotifyNonlinearVirtual:
|
||||
if (mode != NotifyGrab &&
|
||||
@@ -814,7 +814,7 @@ _gdk_device_manager_core_handle_focus (GdkSurface *surface,
|
||||
break;
|
||||
}
|
||||
|
||||
if (APPEARS_FOCUSED (toplevel) != had_focus)
|
||||
if (HAS_FOCUS (toplevel) != had_focus)
|
||||
{
|
||||
GdkEvent *event;
|
||||
|
||||
|
||||
@@ -2110,8 +2110,8 @@ _gdk_x11_surface_drag_begin (GdkSurface *surface,
|
||||
x11_drag->protocol = GDK_DRAG_PROTO_XDND;
|
||||
x11_drag->actions = actions;
|
||||
x11_drag->ipc_surface = ipc_surface;
|
||||
if (gdk_surface_get_group (surface))
|
||||
gdk_surface_set_group (x11_drag->ipc_surface, surface);
|
||||
if (gdk_x11_surface_get_group (surface))
|
||||
gdk_x11_surface_set_group (x11_drag->ipc_surface, surface);
|
||||
gdk_surface_show (x11_drag->ipc_surface);
|
||||
|
||||
x11_drag->drag_surface = create_drag_surface (display);
|
||||
|
||||
@@ -36,8 +36,8 @@ static void gdk_event_source_finalize (GSource *source);
|
||||
|
||||
static GQuark quark_needs_enter = 0;
|
||||
|
||||
#define APPEARS_FOCUSED(toplevel) \
|
||||
((toplevel)->has_focus || (toplevel)->has_focus_window || (toplevel)->has_pointer_focus)
|
||||
#define HAS_FOCUS(toplevel) \
|
||||
((toplevel)->has_focus || (toplevel)->has_pointer_focus)
|
||||
|
||||
struct _GdkEventSource
|
||||
{
|
||||
@@ -108,10 +108,10 @@ handle_focus_change (GdkEventCrossing *event)
|
||||
if (!event->focus || toplevel->has_focus_window)
|
||||
return;
|
||||
|
||||
had_focus = APPEARS_FOCUSED (toplevel);
|
||||
had_focus = HAS_FOCUS (toplevel);
|
||||
toplevel->has_pointer_focus = focus_in;
|
||||
|
||||
if (APPEARS_FOCUSED (toplevel) != had_focus)
|
||||
if (HAS_FOCUS (toplevel) != had_focus)
|
||||
{
|
||||
GdkEvent *focus_event;
|
||||
|
||||
|
||||
+41
-14
@@ -1867,9 +1867,17 @@ gdk_x11_surface_set_modal_hint (GdkSurface *surface,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
/**
|
||||
* gdk_x11_surface_set_skip_taskbar_hint:
|
||||
* @surface: (type GdkX11Surface): a native #GdkSurface
|
||||
* @skips_taskbar: %TRUE to skip taskbars
|
||||
*
|
||||
* Sets a hint on @surface that taskbars should not
|
||||
* display it. See the EWMH for details.
|
||||
*/
|
||||
void
|
||||
gdk_x11_surface_set_skip_taskbar_hint (GdkSurface *surface,
|
||||
gboolean skips_taskbar)
|
||||
gboolean skips_taskbar)
|
||||
{
|
||||
GdkToplevelX11 *toplevel;
|
||||
|
||||
@@ -1888,9 +1896,17 @@ gdk_x11_surface_set_skip_taskbar_hint (GdkSurface *surface,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
/**
|
||||
* gdk_x11_surface_set_skip_pager_hint:
|
||||
* @surface: (type GdkX11Surface): a #GdkSurface
|
||||
* @skips_pager: %TRUE to skip pagers
|
||||
*
|
||||
* Sets a hint on @surface that pagers should not
|
||||
* display it. See the EWMH for details.
|
||||
*/
|
||||
void
|
||||
gdk_x11_surface_set_skip_pager_hint (GdkSurface *surface,
|
||||
gboolean skips_pager)
|
||||
gboolean skips_pager)
|
||||
{
|
||||
GdkToplevelX11 *toplevel;
|
||||
|
||||
@@ -1909,9 +1925,17 @@ gdk_x11_surface_set_skip_pager_hint (GdkSurface *surface,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
/**
|
||||
* gdk_x11_surface_set_urgency_hint:
|
||||
* @surface: (type GdkX11Surface): a native #GdkSurface
|
||||
* @urgent: %TRUE to indicate urgenct attention needed
|
||||
*
|
||||
* Sets a hint on @surface that it needs user attention.
|
||||
* See the ICCCM for details.
|
||||
*/
|
||||
void
|
||||
gdk_x11_surface_set_urgency_hint (GdkSurface *surface,
|
||||
gboolean urgent)
|
||||
gboolean urgent)
|
||||
{
|
||||
GdkToplevelX11 *toplevel;
|
||||
|
||||
@@ -3363,7 +3387,7 @@ gdk_x11_surface_set_keep_below (GdkSurface *surface, gboolean setting)
|
||||
setting ? GDK_SURFACE_STATE_BELOW : 0);
|
||||
}
|
||||
|
||||
static GdkSurface *
|
||||
GdkSurface *
|
||||
gdk_x11_surface_get_group (GdkSurface *surface)
|
||||
{
|
||||
GdkToplevelX11 *toplevel;
|
||||
@@ -3377,9 +3401,17 @@ gdk_x11_surface_get_group (GdkSurface *surface)
|
||||
return toplevel->group_leader;
|
||||
}
|
||||
|
||||
static void
|
||||
/**
|
||||
* gdk_x11_surface_set_group:
|
||||
* @surface: (type GdkX11Surface): a native #GdkSurface
|
||||
* @leader: a #GdkSurface
|
||||
*
|
||||
* Sets the group leader of @surface to be @leader.
|
||||
* See the ICCCM for details.
|
||||
*/
|
||||
void
|
||||
gdk_x11_surface_set_group (GdkSurface *surface,
|
||||
GdkSurface *leader)
|
||||
GdkSurface *leader)
|
||||
{
|
||||
GdkToplevelX11 *toplevel;
|
||||
|
||||
@@ -4658,9 +4690,6 @@ gdk_surface_impl_x11_class_init (GdkSurfaceImplX11Class *klass)
|
||||
impl_class->set_type_hint = gdk_x11_surface_set_type_hint;
|
||||
impl_class->get_type_hint = gdk_x11_surface_get_type_hint;
|
||||
impl_class->set_modal_hint = gdk_x11_surface_set_modal_hint;
|
||||
impl_class->set_skip_taskbar_hint = gdk_x11_surface_set_skip_taskbar_hint;
|
||||
impl_class->set_skip_pager_hint = gdk_x11_surface_set_skip_pager_hint;
|
||||
impl_class->set_urgency_hint = gdk_x11_surface_set_urgency_hint;
|
||||
impl_class->set_geometry_hints = gdk_x11_surface_set_geometry_hints;
|
||||
impl_class->set_title = gdk_x11_surface_set_title;
|
||||
impl_class->set_startup_id = gdk_x11_surface_set_startup_id;
|
||||
@@ -4682,8 +4711,6 @@ gdk_surface_impl_x11_class_init (GdkSurfaceImplX11Class *klass)
|
||||
impl_class->unfullscreen = gdk_x11_surface_unfullscreen;
|
||||
impl_class->set_keep_above = gdk_x11_surface_set_keep_above;
|
||||
impl_class->set_keep_below = gdk_x11_surface_set_keep_below;
|
||||
impl_class->get_group = gdk_x11_surface_get_group;
|
||||
impl_class->set_group = gdk_x11_surface_set_group;
|
||||
impl_class->set_decorations = gdk_x11_surface_set_decorations;
|
||||
impl_class->get_decorations = gdk_x11_surface_get_decorations;
|
||||
impl_class->set_functions = gdk_x11_surface_set_functions;
|
||||
|
||||
@@ -105,6 +105,23 @@ GDK_AVAILABLE_IN_ALL
|
||||
GdkSurface *gdk_x11_surface_lookup_for_display (GdkDisplay *display,
|
||||
Window window);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_x11_surface_set_skip_taskbar_hint (GdkSurface *surface,
|
||||
gboolean skips_taskbar);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_x11_surface_set_skip_pager_hint (GdkSurface *surface,
|
||||
gboolean skips_pager);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_x11_surface_set_urgency_hint (GdkSurface *surface,
|
||||
gboolean urgent);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_x11_surface_set_group (GdkSurface *surface,
|
||||
GdkSurface *leader);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkSurface * gdk_x11_surface_get_group (GdkSurface *surface);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_X11_SURFACE_H__ */
|
||||
|
||||
+22
-1
@@ -4,6 +4,7 @@
|
||||
|
||||
#include "gskdebugprivate.h"
|
||||
#include "gskprofilerprivate.h"
|
||||
#include "gdk/gdkglcontextprivate.h"
|
||||
#include "gdk/gdktextureprivate.h"
|
||||
#include "gdk/gdkgltextureprivate.h"
|
||||
|
||||
@@ -206,6 +207,12 @@ gsk_gl_driver_begin_frame (GskGLDriver *self)
|
||||
#endif
|
||||
}
|
||||
|
||||
gboolean
|
||||
gsk_gl_driver_in_frame (GskGLDriver *self)
|
||||
{
|
||||
return self->in_frame;
|
||||
}
|
||||
|
||||
void
|
||||
gsk_gl_driver_end_frame (GskGLDriver *self)
|
||||
{
|
||||
@@ -292,6 +299,13 @@ gsk_gl_driver_collect_textures (GskGLDriver *self)
|
||||
return old_size - g_hash_table_size (self->textures);
|
||||
}
|
||||
|
||||
|
||||
GdkGLContext *
|
||||
gsk_gl_driver_get_gl_context (GskGLDriver *self)
|
||||
{
|
||||
return self->gl_context;
|
||||
}
|
||||
|
||||
int
|
||||
gsk_gl_driver_get_max_texture_size (GskGLDriver *self)
|
||||
{
|
||||
@@ -531,6 +545,9 @@ gsk_gl_driver_get_texture_for_texture (GskGLDriver *self,
|
||||
surface,
|
||||
min_filter,
|
||||
mag_filter);
|
||||
gdk_gl_context_label_object_printf (self->gl_context, GL_TEXTURE, t->texture_id,
|
||||
"GdkTexture<%p> %d", texture, t->texture_id);
|
||||
|
||||
cairo_surface_destroy (surface);
|
||||
|
||||
return t->texture_id;
|
||||
@@ -633,7 +650,11 @@ gsk_gl_driver_create_render_target (GskGLDriver *self,
|
||||
glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, t->texture_id, 0);
|
||||
|
||||
if (add_depth_buffer || add_stencil_buffer)
|
||||
glGenRenderbuffersEXT (1, &depth_stencil_buffer_id);
|
||||
{
|
||||
glGenRenderbuffersEXT (1, &depth_stencil_buffer_id);
|
||||
gdk_gl_context_label_object_printf (self->gl_context, GL_RENDERBUFFER, depth_stencil_buffer_id,
|
||||
"%s buffer for %d", add_depth_buffer ? "Depth" : "Stencil", texture_id);
|
||||
}
|
||||
else
|
||||
depth_stencil_buffer_id = 0;
|
||||
|
||||
|
||||
@@ -23,12 +23,13 @@ typedef struct {
|
||||
|
||||
|
||||
GskGLDriver * gsk_gl_driver_new (GdkGLContext *context);
|
||||
GdkGLContext *gsk_gl_driver_get_gl_context (GskGLDriver *driver);
|
||||
|
||||
int gsk_gl_driver_get_max_texture_size (GskGLDriver *driver);
|
||||
|
||||
void gsk_gl_driver_begin_frame (GskGLDriver *driver);
|
||||
void gsk_gl_driver_end_frame (GskGLDriver *driver);
|
||||
|
||||
gboolean gsk_gl_driver_in_frame (GskGLDriver *driver);
|
||||
int gsk_gl_driver_get_texture_for_texture (GskGLDriver *driver,
|
||||
GdkTexture *texture,
|
||||
int min_filter,
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
#include "gskdebugprivate.h"
|
||||
#include "gskprivate.h"
|
||||
|
||||
#include "gdk/gdkglcontextprivate.h"
|
||||
|
||||
#include <graphene.h>
|
||||
#include <cairo.h>
|
||||
#include <epoxy/gl.h>
|
||||
@@ -260,10 +262,15 @@ upload_dirty_glyph (GskGLGlyphCache *self,
|
||||
|
||||
g_assert (atlas->pending_glyph.key != NULL);
|
||||
|
||||
gdk_gl_context_push_debug_group_printf (gsk_gl_driver_get_gl_context (self->gl_driver),
|
||||
"Uploading glyph %d", atlas->pending_glyph.key->glyph);
|
||||
|
||||
render_glyph (atlas, &atlas->pending_glyph, ®ion);
|
||||
|
||||
gsk_gl_image_upload_regions (atlas->image, self->gl_driver, 1, ®ion);
|
||||
|
||||
gdk_gl_context_pop_debug_group (gsk_gl_driver_get_gl_context (self->gl_driver));
|
||||
|
||||
g_free (region.data);
|
||||
|
||||
atlas->pending_glyph.key = NULL;
|
||||
@@ -345,6 +352,9 @@ gsk_gl_glyph_cache_get_glyph_image (GskGLGlyphCache *self,
|
||||
{
|
||||
atlas->image = g_new0 (GskGLImage, 1);
|
||||
gsk_gl_image_create (atlas->image, self->gl_driver, atlas->width, atlas->height);
|
||||
gdk_gl_context_label_object_printf (gsk_gl_driver_get_gl_context (self->gl_driver),
|
||||
GL_TEXTURE, atlas->image->texture_id,
|
||||
"Glyph atlas %d", atlas->image->texture_id);
|
||||
}
|
||||
|
||||
if (atlas->pending_glyph.key != NULL)
|
||||
|
||||
+156
-28
@@ -20,6 +20,7 @@
|
||||
#include "gskprivate.h"
|
||||
|
||||
#include "gdk/gdkgltextureprivate.h"
|
||||
#include "gdk/gdkglcontextprivate.h"
|
||||
|
||||
#include <epoxy/gl.h>
|
||||
#include <cairo-ft.h>
|
||||
@@ -325,9 +326,11 @@ struct _GskGLRenderer
|
||||
Program unblurred_outset_shadow_program;
|
||||
Program border_program;
|
||||
Program cross_fade_program;
|
||||
Program blend_program;
|
||||
};
|
||||
};
|
||||
|
||||
RenderOpBuilder op_builder;
|
||||
GArray *render_ops;
|
||||
|
||||
GskGLGlyphCache glyph_cache;
|
||||
@@ -477,12 +480,14 @@ render_fallback_node (GskGLRenderer *self,
|
||||
texture_id = gsk_gl_driver_create_texture (self->gl_driver,
|
||||
surface_width,
|
||||
surface_height);
|
||||
|
||||
gsk_gl_driver_bind_source_texture (self->gl_driver, texture_id);
|
||||
gsk_gl_driver_init_texture_with_surface (self->gl_driver,
|
||||
texture_id,
|
||||
surface,
|
||||
GL_NEAREST, GL_NEAREST);
|
||||
gdk_gl_context_label_object_printf (self->gl_context, GL_TEXTURE, texture_id,
|
||||
"Fallback %s %d", node->node_class->type_name, texture_id);
|
||||
|
||||
|
||||
cairo_surface_destroy (surface);
|
||||
|
||||
@@ -1215,13 +1220,14 @@ render_color_matrix_node (GskGLRenderer *self,
|
||||
const float min_y = builder->dy + node->bounds.origin.y;
|
||||
const float max_x = min_x + node->bounds.size.width;
|
||||
const float max_y = min_y + node->bounds.size.height;
|
||||
GskRenderNode *child = gsk_color_matrix_node_get_child (node);
|
||||
int texture_id;
|
||||
gboolean is_offscreen;
|
||||
|
||||
/* Pass min_x/max_x/min_y/max_y without builder->dx/dy! */
|
||||
add_offscreen_ops (self, builder,
|
||||
&node->bounds,
|
||||
gsk_color_matrix_node_get_child (node),
|
||||
child,
|
||||
&texture_id, &is_offscreen,
|
||||
RESET_CLIP | RESET_OPACITY);
|
||||
|
||||
@@ -1428,7 +1434,11 @@ render_outset_shadow_node (GskGLRenderer *self,
|
||||
texture_id = gsk_gl_driver_create_texture (self->gl_driver, texture_width, texture_height);
|
||||
gsk_gl_driver_bind_source_texture (self->gl_driver, texture_id);
|
||||
gsk_gl_driver_init_texture_empty (self->gl_driver, texture_id);
|
||||
gdk_gl_context_label_object_printf (self->gl_context, GL_TEXTURE, texture_id,
|
||||
"Outset Shadow Temp %d", texture_id);
|
||||
render_target = gsk_gl_driver_create_render_target (self->gl_driver, texture_id, FALSE, FALSE);
|
||||
gdk_gl_context_label_object_printf (self->gl_context, GL_FRAMEBUFFER, render_target,
|
||||
"Outset Shadow FB Temp %d", render_target);
|
||||
|
||||
|
||||
graphene_matrix_init_ortho (&item_proj,
|
||||
@@ -1461,7 +1471,11 @@ render_outset_shadow_node (GskGLRenderer *self,
|
||||
blurred_texture_id = gsk_gl_driver_create_permanent_texture (self->gl_driver, texture_width, texture_height);
|
||||
gsk_gl_driver_bind_source_texture (self->gl_driver, blurred_texture_id);
|
||||
gsk_gl_driver_init_texture_empty (self->gl_driver, blurred_texture_id);
|
||||
gdk_gl_context_label_object_printf (self->gl_context, GL_TEXTURE, blurred_texture_id,
|
||||
"Outset Shadow Cache %d", blurred_texture_id);
|
||||
blurred_render_target = gsk_gl_driver_create_render_target (self->gl_driver, blurred_texture_id, TRUE, TRUE);
|
||||
gdk_gl_context_label_object_printf (self->gl_context, GL_FRAMEBUFFER, render_target,
|
||||
"Outset Shadow Cache FB %d", render_target);
|
||||
|
||||
ops_set_render_target (builder, blurred_render_target);
|
||||
ops_pop_clip (builder);
|
||||
@@ -1887,6 +1901,54 @@ render_cross_fade_node (GskGLRenderer *self,
|
||||
ops_draw (builder, vertex_data);
|
||||
}
|
||||
|
||||
static inline void
|
||||
render_blend_node (GskGLRenderer *self,
|
||||
GskRenderNode *node,
|
||||
RenderOpBuilder *builder)
|
||||
{
|
||||
GskRenderNode *top_child = gsk_blend_node_get_top_child (node);
|
||||
GskRenderNode *bottom_child = gsk_blend_node_get_bottom_child (node);
|
||||
const float min_x = builder->dx + node->bounds.origin.x;
|
||||
const float min_y = builder->dy + node->bounds.origin.y;
|
||||
const float max_x = min_x + node->bounds.size.width;
|
||||
const float max_y = min_y + node->bounds.size.height;
|
||||
int top_texture_id;
|
||||
int bottom_texture_id;
|
||||
gboolean is_offscreen1, is_offscreen2;
|
||||
RenderOp op;
|
||||
const GskQuadVertex vertex_data[GL_N_VERTICES] = {
|
||||
{ { min_x, min_y }, { 0, 1 }, },
|
||||
{ { min_x, max_y }, { 0, 0 }, },
|
||||
{ { max_x, min_y }, { 1, 1 }, },
|
||||
|
||||
{ { max_x, max_y }, { 1, 0 }, },
|
||||
{ { min_x, max_y }, { 0, 0 }, },
|
||||
{ { max_x, min_y }, { 1, 1 }, },
|
||||
};
|
||||
|
||||
/* TODO: We create 2 textures here as big as the blend node, but both the
|
||||
* start and the end node might be a lot smaller than that. */
|
||||
add_offscreen_ops (self, builder,
|
||||
&node->bounds,
|
||||
bottom_child,
|
||||
&bottom_texture_id, &is_offscreen1,
|
||||
FORCE_OFFSCREEN | RESET_CLIP);
|
||||
|
||||
add_offscreen_ops (self, builder,
|
||||
&node->bounds,
|
||||
top_child,
|
||||
&top_texture_id, &is_offscreen2,
|
||||
FORCE_OFFSCREEN | RESET_CLIP);
|
||||
|
||||
ops_set_program (builder, &self->blend_program);
|
||||
ops_set_texture (builder, bottom_texture_id);
|
||||
op.op = OP_CHANGE_BLEND;
|
||||
op.blend.source2 = top_texture_id;
|
||||
op.blend.mode = gsk_blend_node_get_blend_mode (node);
|
||||
ops_add (builder, &op);
|
||||
ops_draw (builder, vertex_data);
|
||||
}
|
||||
|
||||
static inline void
|
||||
apply_viewport_op (const Program *program,
|
||||
const RenderOp *op)
|
||||
@@ -2161,6 +2223,18 @@ apply_cross_fade_op (const Program *program,
|
||||
glUniform1f (program->cross_fade.progress_location, op->cross_fade.progress);
|
||||
}
|
||||
|
||||
static inline void
|
||||
apply_blend_op (const Program *program,
|
||||
const RenderOp *op)
|
||||
{
|
||||
/* End texture id */
|
||||
glUniform1i (program->blend.source2_location, 1);
|
||||
glActiveTexture (GL_TEXTURE0 + 1);
|
||||
glBindTexture (GL_TEXTURE_2D, op->blend.source2);
|
||||
/* progress */
|
||||
glUniform1i (program->blend.mode_location, op->blend.mode);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_gl_renderer_dispose (GObject *gobject)
|
||||
{
|
||||
@@ -2193,6 +2267,7 @@ gsk_gl_renderer_create_programs (GskGLRenderer *self,
|
||||
{ "unblurred outset shadow", "unblurred_outset_shadow.fs.glsl" },
|
||||
{ "border", "border.fs.glsl" },
|
||||
{ "cross fade", "cross_fade.fs.glsl" },
|
||||
{ "blend", "blend.fs.glsl" },
|
||||
};
|
||||
|
||||
builder = gsk_shader_builder_new ();
|
||||
@@ -2323,6 +2398,10 @@ gsk_gl_renderer_create_programs (GskGLRenderer *self,
|
||||
INIT_PROGRAM_UNIFORM_LOCATION (cross_fade, progress);
|
||||
INIT_PROGRAM_UNIFORM_LOCATION (cross_fade, source2);
|
||||
|
||||
/* blend */
|
||||
INIT_PROGRAM_UNIFORM_LOCATION (blend, source2);
|
||||
INIT_PROGRAM_UNIFORM_LOCATION (blend, mode);
|
||||
|
||||
g_object_unref (builder);
|
||||
return TRUE;
|
||||
}
|
||||
@@ -2504,9 +2583,11 @@ gsk_gl_renderer_add_render_ops (GskGLRenderer *self,
|
||||
break;
|
||||
|
||||
case GSK_DEBUG_NODE:
|
||||
ops_push_debug_group (builder, gsk_debug_node_get_message (node));
|
||||
gsk_gl_renderer_add_render_ops (self,
|
||||
gsk_debug_node_get_child (node),
|
||||
builder);
|
||||
ops_pop_debug_group (builder);
|
||||
break;
|
||||
|
||||
case GSK_COLOR_NODE:
|
||||
@@ -2573,8 +2654,11 @@ gsk_gl_renderer_add_render_ops (GskGLRenderer *self,
|
||||
render_cross_fade_node (self, node, builder);
|
||||
break;
|
||||
|
||||
case GSK_REPEATING_LINEAR_GRADIENT_NODE:
|
||||
case GSK_BLEND_NODE:
|
||||
render_blend_node (self, node, builder);
|
||||
break;
|
||||
|
||||
case GSK_REPEATING_LINEAR_GRADIENT_NODE:
|
||||
case GSK_REPEAT_NODE:
|
||||
case GSK_CAIRO_NODE:
|
||||
default:
|
||||
@@ -2640,9 +2724,14 @@ add_offscreen_ops (GskGLRenderer *self,
|
||||
}
|
||||
|
||||
texture_id = gsk_gl_driver_create_texture (self->gl_driver, width, height);
|
||||
gdk_gl_context_label_object_printf (self->gl_context, GL_TEXTURE, texture_id,
|
||||
"Offscreen<%s> %d", child_node->node_class->type_name, texture_id);
|
||||
|
||||
gsk_gl_driver_bind_source_texture (self->gl_driver, texture_id);
|
||||
gsk_gl_driver_init_texture_empty (self->gl_driver, texture_id);
|
||||
render_target = gsk_gl_driver_create_render_target (self->gl_driver, texture_id, TRUE, TRUE);
|
||||
gdk_gl_context_label_object_printf (self->gl_context, GL_FRAMEBUFFER, render_target,
|
||||
"Offscreen<%s> FB %d", child_node->node_class->type_name, render_target);
|
||||
|
||||
graphene_matrix_init_ortho (&item_proj,
|
||||
bounds->origin.x * scale,
|
||||
@@ -2766,7 +2855,9 @@ gsk_gl_renderer_render_ops (GskGLRenderer *self,
|
||||
op->op == OP_CHANGE_VAO)
|
||||
continue;
|
||||
|
||||
if (op->op != OP_CHANGE_PROGRAM &&
|
||||
if (op->op != OP_PUSH_DEBUG_GROUP &&
|
||||
op->op != OP_POP_DEBUG_GROUP &&
|
||||
op->op != OP_CHANGE_PROGRAM &&
|
||||
op->op != OP_CHANGE_RENDER_TARGET &&
|
||||
op->op != OP_CLEAR &&
|
||||
program == NULL)
|
||||
@@ -2833,6 +2924,11 @@ gsk_gl_renderer_render_ops (GskGLRenderer *self,
|
||||
apply_cross_fade_op (program, op);
|
||||
break;
|
||||
|
||||
case OP_CHANGE_BLEND:
|
||||
g_assert (program == &self->blend_program);
|
||||
apply_blend_op (program, op);
|
||||
break;
|
||||
|
||||
case OP_CHANGE_LINEAR_GRADIENT:
|
||||
apply_linear_gradient_op (program, op);
|
||||
break;
|
||||
@@ -2871,6 +2967,14 @@ gsk_gl_renderer_render_ops (GskGLRenderer *self,
|
||||
dump_framebuffer (op->dump.filename, op->dump.width, op->dump.height);
|
||||
break;
|
||||
|
||||
case OP_PUSH_DEBUG_GROUP:
|
||||
gdk_gl_context_push_debug_group (self->gl_context, op->debug_group.text);
|
||||
break;
|
||||
|
||||
case OP_POP_DEBUG_GROUP:
|
||||
gdk_gl_context_pop_debug_group (self->gl_context);
|
||||
break;
|
||||
|
||||
default:
|
||||
g_warn_if_reached ();
|
||||
}
|
||||
@@ -2893,8 +2997,8 @@ gsk_gl_renderer_do_render (GskRenderer *renderer,
|
||||
int scale_factor)
|
||||
{
|
||||
GskGLRenderer *self = GSK_GL_RENDERER (renderer);
|
||||
RenderOpBuilder render_op_builder;
|
||||
graphene_matrix_t modelview, projection;
|
||||
gsize buffer_size;
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
GskProfiler *profiler;
|
||||
gint64 gpu_time, cpu_time;
|
||||
@@ -2910,6 +3014,8 @@ gsk_gl_renderer_do_render (GskRenderer *renderer,
|
||||
return;
|
||||
}
|
||||
|
||||
g_assert (gsk_gl_driver_in_frame (self->gl_driver));
|
||||
|
||||
/* Set up the modelview and projection matrices to fit our viewport */
|
||||
graphene_matrix_init_scale (&modelview, scale_factor, scale_factor, 1.0);
|
||||
graphene_matrix_init_ortho (&projection,
|
||||
@@ -2921,17 +3027,12 @@ gsk_gl_renderer_do_render (GskRenderer *renderer,
|
||||
ORTHO_FAR_PLANE);
|
||||
graphene_matrix_scale (&projection, 1, -1, 1);
|
||||
|
||||
gsk_gl_driver_begin_frame (self->gl_driver);
|
||||
gsk_gl_glyph_cache_begin_frame (&self->glyph_cache);
|
||||
gsk_gl_shadow_cache_begin_frame (&self->shadow_cache, self->gl_driver);
|
||||
|
||||
memset (&render_op_builder, 0, sizeof (render_op_builder));
|
||||
render_op_builder.renderer = self;
|
||||
render_op_builder.current_projection = projection;
|
||||
render_op_builder.current_viewport = *viewport;
|
||||
render_op_builder.current_opacity = 1.0f;
|
||||
render_op_builder.render_ops = self->render_ops;
|
||||
ops_set_modelview (&render_op_builder, &modelview,
|
||||
ops_set_projection (&self->op_builder, &projection);
|
||||
ops_set_viewport (&self->op_builder, viewport);
|
||||
ops_set_modelview (&self->op_builder, &modelview,
|
||||
scale_factor == 1 ? GSK_TRANSFORM_CATEGORY_IDENTITY : GSK_TRANSFORM_CATEGORY_2D_AFFINE);
|
||||
|
||||
/* Initial clip is self->render_region! */
|
||||
@@ -2942,13 +3043,13 @@ gsk_gl_renderer_do_render (GskRenderer *renderer,
|
||||
|
||||
cairo_region_get_extents (self->render_region, &render_extents);
|
||||
|
||||
ops_transform_bounds_modelview (&render_op_builder,
|
||||
ops_transform_bounds_modelview (&self->op_builder,
|
||||
&GRAPHENE_RECT_INIT (render_extents.x,
|
||||
render_extents.y,
|
||||
render_extents.width,
|
||||
render_extents.height),
|
||||
&transformed_render_region);
|
||||
ops_push_clip (&render_op_builder,
|
||||
ops_push_clip (&self->op_builder,
|
||||
&GSK_ROUNDED_RECT_INIT (transformed_render_region.origin.x,
|
||||
transformed_render_region.origin.y,
|
||||
transformed_render_region.size.width,
|
||||
@@ -2956,7 +3057,7 @@ gsk_gl_renderer_do_render (GskRenderer *renderer,
|
||||
}
|
||||
else
|
||||
{
|
||||
ops_push_clip (&render_op_builder,
|
||||
ops_push_clip (&self->op_builder,
|
||||
&GSK_ROUNDED_RECT_INIT (viewport->origin.x,
|
||||
viewport->origin.y,
|
||||
viewport->size.width,
|
||||
@@ -2964,15 +3065,18 @@ gsk_gl_renderer_do_render (GskRenderer *renderer,
|
||||
}
|
||||
|
||||
if (fbo_id != 0)
|
||||
ops_set_render_target (&render_op_builder, fbo_id);
|
||||
ops_set_render_target (&self->op_builder, fbo_id);
|
||||
|
||||
gsk_gl_renderer_add_render_ops (self, root, &render_op_builder);
|
||||
gdk_gl_context_push_debug_group (self->gl_context, "Adding render ops");
|
||||
gsk_gl_renderer_add_render_ops (self, root, &self->op_builder);
|
||||
gdk_gl_context_pop_debug_group (self->gl_context);
|
||||
|
||||
/* We correctly reset the state everywhere */
|
||||
g_assert_cmpint (render_op_builder.current_render_target, ==, fbo_id);
|
||||
ops_pop_modelview (&render_op_builder);
|
||||
ops_pop_clip (&render_op_builder);
|
||||
ops_finish (&render_op_builder);
|
||||
g_assert_cmpint (self->op_builder.current_render_target, ==, fbo_id);
|
||||
ops_pop_modelview (&self->op_builder);
|
||||
ops_pop_clip (&self->op_builder);
|
||||
buffer_size = self->op_builder.buffer_size;
|
||||
ops_finish (&self->op_builder);
|
||||
|
||||
/*g_message ("Ops: %u", self->render_ops->len);*/
|
||||
|
||||
@@ -2982,6 +3086,10 @@ gsk_gl_renderer_do_render (GskRenderer *renderer,
|
||||
gsk_profiler_timer_begin (profiler, self->profile_timers.cpu_time);
|
||||
#endif
|
||||
|
||||
/* Actually do the rendering */
|
||||
if (fbo_id != 0)
|
||||
glBindFramebuffer (GL_FRAMEBUFFER, fbo_id);
|
||||
|
||||
glViewport (0, 0, ceilf (viewport->size.width), ceilf (viewport->size.height));
|
||||
gsk_gl_renderer_setup_render_mode (self);
|
||||
gsk_gl_renderer_clear (self);
|
||||
@@ -2994,9 +3102,9 @@ gsk_gl_renderer_do_render (GskRenderer *renderer,
|
||||
glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glBlendEquation (GL_FUNC_ADD);
|
||||
|
||||
gsk_gl_renderer_render_ops (self, render_op_builder.buffer_size);
|
||||
|
||||
gsk_gl_driver_end_frame (self->gl_driver);
|
||||
gdk_gl_context_push_debug_group (self->gl_context, "Rendering ops");
|
||||
gsk_gl_renderer_render_ops (self, buffer_size);
|
||||
gdk_gl_context_pop_debug_group (self->gl_context);
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
gsk_profiler_counter_inc (profiler, self->profile_counters.frames);
|
||||
@@ -3024,6 +3132,9 @@ gsk_gl_renderer_render_texture (GskRenderer *renderer,
|
||||
|
||||
g_return_val_if_fail (self->gl_context != NULL, NULL);
|
||||
|
||||
gdk_gl_context_push_debug_group_printf (self->gl_context,
|
||||
"Render %s<%p> to texture", root->node_class->type_name, root);
|
||||
|
||||
width = ceilf (viewport->size.width);
|
||||
height = ceilf (viewport->size.height);
|
||||
|
||||
@@ -3035,6 +3146,9 @@ gsk_gl_renderer_render_texture (GskRenderer *renderer,
|
||||
glGenTextures (1, &texture_id);
|
||||
glBindTexture (GL_TEXTURE_2D, texture_id);
|
||||
|
||||
gdk_gl_context_label_object_printf (self->gl_context, GL_TEXTURE, texture_id,
|
||||
"Texture %s<%p> %d", root->node_class->type_name, root, texture_id);
|
||||
|
||||
if (gdk_gl_context_get_use_es (self->gl_context))
|
||||
glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||
else
|
||||
@@ -3042,12 +3156,11 @@ gsk_gl_renderer_render_texture (GskRenderer *renderer,
|
||||
|
||||
glGenFramebuffers (1, &fbo_id);
|
||||
glBindFramebuffer (GL_FRAMEBUFFER, fbo_id);
|
||||
gdk_gl_context_label_object_printf (self->gl_context, GL_FRAMEBUFFER, fbo_id,
|
||||
"FB %s<%p> %d", root->node_class->type_name, root, fbo_id);
|
||||
glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture_id, 0);
|
||||
g_assert_cmphex (glCheckFramebufferStatus (GL_FRAMEBUFFER), ==, GL_FRAMEBUFFER_COMPLETE);
|
||||
|
||||
gsk_gl_renderer_clear (self);
|
||||
gsk_gl_driver_end_frame (self->gl_driver);
|
||||
|
||||
/* Render the actual scene */
|
||||
gsk_gl_renderer_do_render (renderer, root, viewport, fbo_id, 1);
|
||||
|
||||
@@ -3056,6 +3169,10 @@ gsk_gl_renderer_render_texture (GskRenderer *renderer,
|
||||
width, height,
|
||||
NULL, NULL);
|
||||
|
||||
gsk_gl_driver_end_frame (self->gl_driver);
|
||||
|
||||
gdk_gl_context_pop_debug_group (self->gl_context);
|
||||
|
||||
gsk_gl_renderer_clear_tree (self);
|
||||
return texture;
|
||||
}
|
||||
@@ -3074,6 +3191,9 @@ gsk_gl_renderer_render (GskRenderer *renderer,
|
||||
if (self->gl_context == NULL)
|
||||
return;
|
||||
|
||||
gdk_gl_context_push_debug_group_printf (self->gl_context,
|
||||
"Render root node %p", root);
|
||||
|
||||
surface = gsk_renderer_get_surface (renderer);
|
||||
whole_surface = (GdkRectangle) {
|
||||
0, 0,
|
||||
@@ -3110,13 +3230,17 @@ gsk_gl_renderer_render (GskRenderer *renderer,
|
||||
viewport.size.width = gdk_surface_get_width (surface) * self->scale_factor;
|
||||
viewport.size.height = gdk_surface_get_height (surface) * self->scale_factor;
|
||||
|
||||
gsk_gl_driver_begin_frame (self->gl_driver);
|
||||
gsk_gl_renderer_do_render (renderer, root, &viewport, 0, self->scale_factor);
|
||||
gsk_gl_driver_end_frame (self->gl_driver);
|
||||
|
||||
gdk_gl_context_make_current (self->gl_context);
|
||||
gsk_gl_renderer_clear_tree (self);
|
||||
|
||||
gdk_draw_context_end_frame (GDK_DRAW_CONTEXT (self->gl_context));
|
||||
|
||||
gdk_gl_context_pop_debug_group (self->gl_context);
|
||||
|
||||
g_clear_pointer (&self->render_region, cairo_region_destroy);
|
||||
}
|
||||
|
||||
@@ -3141,6 +3265,10 @@ gsk_gl_renderer_init (GskGLRenderer *self)
|
||||
|
||||
self->render_ops = g_array_new (FALSE, FALSE, sizeof (RenderOp));
|
||||
|
||||
ops_init (&self->op_builder);
|
||||
self->op_builder.renderer = self;
|
||||
self->op_builder.render_ops = self->render_ops;
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
{
|
||||
GskProfiler *profiler = gsk_renderer_get_profiler (GSK_RENDERER (self));
|
||||
|
||||
@@ -12,9 +12,23 @@ ops_finish (RenderOpBuilder *builder)
|
||||
{
|
||||
if (builder->mv_stack)
|
||||
g_array_free (builder->mv_stack, TRUE);
|
||||
builder->mv_stack = NULL;
|
||||
|
||||
if (builder->clip_stack)
|
||||
g_array_free (builder->clip_stack, TRUE);
|
||||
builder->clip_stack = NULL;
|
||||
|
||||
builder->buffer_size = 0;
|
||||
builder->dx = 0;
|
||||
builder->dy = 0;
|
||||
builder->current_modelview = NULL;
|
||||
builder->current_clip = NULL;
|
||||
builder->current_render_target = 0;
|
||||
builder->current_texture = 0;
|
||||
builder->current_program = NULL;
|
||||
builder->current_program_state = NULL;
|
||||
graphene_matrix_init_identity (&builder->current_projection);
|
||||
builder->current_viewport = GRAPHENE_RECT_INIT (0, 0, 0, 0);
|
||||
}
|
||||
|
||||
static inline void
|
||||
@@ -44,6 +58,28 @@ ops_dump_framebuffer (RenderOpBuilder *builder,
|
||||
g_array_append_val (builder->render_ops, op);
|
||||
}
|
||||
|
||||
void
|
||||
ops_push_debug_group (RenderOpBuilder *builder,
|
||||
const char *text)
|
||||
{
|
||||
RenderOp op;
|
||||
|
||||
op.op = OP_PUSH_DEBUG_GROUP;
|
||||
strncpy (op.debug_group.text, text, sizeof(op.debug_group.text) - 1);
|
||||
op.debug_group.text[sizeof(op.debug_group.text) - 1] = 0; /* Ensure zero terminated */
|
||||
|
||||
g_array_append_val (builder->render_ops, op);
|
||||
}
|
||||
|
||||
void
|
||||
ops_pop_debug_group (RenderOpBuilder *builder)
|
||||
{
|
||||
RenderOp op;
|
||||
|
||||
op.op = OP_POP_DEBUG_GROUP;
|
||||
g_array_append_val (builder->render_ops, op);
|
||||
}
|
||||
|
||||
float
|
||||
ops_get_scale (const RenderOpBuilder *builder)
|
||||
{
|
||||
@@ -149,6 +185,22 @@ ops_transform_bounds_modelview (const RenderOpBuilder *builder,
|
||||
dst->origin.y += builder->dy * head->metadata.scale_y;
|
||||
}
|
||||
|
||||
void
|
||||
ops_init (RenderOpBuilder *builder)
|
||||
{
|
||||
int i;
|
||||
|
||||
memset (builder, 0, sizeof (*builder));
|
||||
|
||||
builder->current_opacity = 1.0f;
|
||||
|
||||
for (i = 0; i < GL_N_PROGRAMS; i ++)
|
||||
{
|
||||
builder->program_state[i].opacity = 1.0f;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
ops_set_program (RenderOpBuilder *builder,
|
||||
const Program *program)
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#include "gskrendernodeprivate.h"
|
||||
|
||||
#define GL_N_VERTICES 6
|
||||
#define GL_N_PROGRAMS 11
|
||||
#define GL_N_PROGRAMS 12
|
||||
|
||||
|
||||
|
||||
@@ -59,6 +59,9 @@ enum {
|
||||
OP_CLEAR = 21,
|
||||
OP_DRAW = 22,
|
||||
OP_DUMP_FRAMEBUFFER = 23,
|
||||
OP_PUSH_DEBUG_GROUP = 24,
|
||||
OP_POP_DEBUG_GROUP = 25,
|
||||
OP_CHANGE_BLEND = 26,
|
||||
};
|
||||
|
||||
typedef struct
|
||||
@@ -134,6 +137,10 @@ typedef struct
|
||||
int source2_location;
|
||||
int progress_location;
|
||||
} cross_fade;
|
||||
struct {
|
||||
int source2_location;
|
||||
int mode_location;
|
||||
} blend;
|
||||
};
|
||||
|
||||
} Program;
|
||||
@@ -212,11 +219,18 @@ typedef struct
|
||||
float progress;
|
||||
int source2;
|
||||
} cross_fade;
|
||||
struct {
|
||||
int source2;
|
||||
int mode;
|
||||
} blend;
|
||||
struct {
|
||||
char *filename;
|
||||
int width;
|
||||
int height;
|
||||
} dump;
|
||||
struct {
|
||||
char text[180]; /* Size of linear_gradient, so 'should be enough' without growing RenderOp */
|
||||
} debug_group;
|
||||
};
|
||||
} RenderOp;
|
||||
|
||||
@@ -277,6 +291,10 @@ void ops_dump_framebuffer (RenderOpBuilder *builder,
|
||||
const char *filename,
|
||||
int width,
|
||||
int height);
|
||||
void ops_init (RenderOpBuilder *builder);
|
||||
void ops_push_debug_group (RenderOpBuilder *builder,
|
||||
const char *text);
|
||||
void ops_pop_debug_group (RenderOpBuilder *builder);
|
||||
|
||||
void ops_finish (RenderOpBuilder *builder);
|
||||
void ops_push_modelview (RenderOpBuilder *builder,
|
||||
|
||||
+85
-28
@@ -514,6 +514,30 @@ gsk_border_node_finalize (GskRenderNode *node)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_border_node_mesh_add_patch (cairo_pattern_t *pattern,
|
||||
const GdkRGBA *color,
|
||||
double x0,
|
||||
double y0,
|
||||
double x1,
|
||||
double y1,
|
||||
double x2,
|
||||
double y2,
|
||||
double x3,
|
||||
double y3)
|
||||
{
|
||||
cairo_mesh_pattern_begin_patch (pattern);
|
||||
cairo_mesh_pattern_move_to (pattern, x0, y0);
|
||||
cairo_mesh_pattern_line_to (pattern, x1, y1);
|
||||
cairo_mesh_pattern_line_to (pattern, x2, y2);
|
||||
cairo_mesh_pattern_line_to (pattern, x3, y3);
|
||||
cairo_mesh_pattern_set_corner_color_rgba (pattern, 0, color->red, color->green, color->blue, color->alpha);
|
||||
cairo_mesh_pattern_set_corner_color_rgba (pattern, 1, color->red, color->green, color->blue, color->alpha);
|
||||
cairo_mesh_pattern_set_corner_color_rgba (pattern, 2, color->red, color->green, color->blue, color->alpha);
|
||||
cairo_mesh_pattern_set_corner_color_rgba (pattern, 3, color->red, color->green, color->blue, color->alpha);
|
||||
cairo_mesh_pattern_end_patch (pattern);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_border_node_draw (GskRenderNode *node,
|
||||
cairo_t *cr)
|
||||
@@ -537,59 +561,92 @@ gsk_border_node_draw (GskRenderNode *node,
|
||||
gdk_rgba_equal (&self->border_color[0], &self->border_color[3]))
|
||||
{
|
||||
gdk_cairo_set_source_rgba (cr, &self->border_color[0]);
|
||||
cairo_fill (cr);
|
||||
}
|
||||
else
|
||||
{
|
||||
const graphene_rect_t *bounds = &self->outline.bounds;
|
||||
/* distance to center "line":
|
||||
* +-------------------------+
|
||||
* | |
|
||||
* | |
|
||||
* | ---this-line--- |
|
||||
* | |
|
||||
* | |
|
||||
* +-------------------------+
|
||||
* That line is equidistant from all sides. It's either horiontal
|
||||
* or vertical, depending on if the rect is wider or taller.
|
||||
* We use the 4 sides spanned up by connecting the line to the corner
|
||||
* points to color the regions of the rectangle differently.
|
||||
* Note that the call to cairo_fill() will add the potential final
|
||||
* segment by closing the path, so we don't have to care.
|
||||
*/
|
||||
cairo_pattern_t *mesh;
|
||||
cairo_matrix_t mat;
|
||||
graphene_point_t tl, br;
|
||||
float scale;
|
||||
|
||||
cairo_clip (cr);
|
||||
mesh = cairo_pattern_create_mesh ();
|
||||
cairo_matrix_init_translate (&mat, -bounds->origin.x, -bounds->origin.y);
|
||||
cairo_pattern_set_matrix (mesh, &mat);
|
||||
|
||||
scale = MIN (bounds->size.width / (self->border_width[1] + self->border_width[3]),
|
||||
bounds->size.height / (self->border_width[0] + self->border_width[2]));
|
||||
graphene_point_init (&tl,
|
||||
self->border_width[3] * scale,
|
||||
self->border_width[0] * scale);
|
||||
graphene_point_init (&br,
|
||||
bounds->size.width - self->border_width[1] * scale,
|
||||
bounds->size.height - self->border_width[2] * scale);
|
||||
|
||||
/* Top */
|
||||
if (self->border_width[0] > 0)
|
||||
{
|
||||
cairo_move_to (cr, bounds->origin.x, bounds->origin.y);
|
||||
cairo_rel_line_to (cr, self->border_width[3], self->border_width[0]);
|
||||
cairo_rel_line_to (cr, bounds->size.width - self->border_width[3] - self->border_width[1], 0);
|
||||
cairo_rel_line_to (cr, self->border_width[1], - self->border_width[0]);
|
||||
gdk_cairo_set_source_rgba (cr, &self->border_color[0]);
|
||||
cairo_fill (cr);
|
||||
gsk_border_node_mesh_add_patch (mesh,
|
||||
&self->border_color[0],
|
||||
0, 0,
|
||||
tl.x, tl.y,
|
||||
br.x, tl.y,
|
||||
bounds->size.width, 0);
|
||||
}
|
||||
|
||||
/* Right */
|
||||
if (self->border_width[1] > 0)
|
||||
{
|
||||
cairo_move_to (cr, bounds->origin.x + bounds->size.width, bounds->origin.y);
|
||||
cairo_rel_line_to (cr, - self->border_width[1], self->border_width[0]);
|
||||
cairo_rel_line_to (cr, 0, bounds->size.height - self->border_width[0] - self->border_width[2]);
|
||||
cairo_rel_line_to (cr, self->border_width[1], self->border_width[2]);
|
||||
gdk_cairo_set_source_rgba (cr, &self->border_color[1]);
|
||||
cairo_fill (cr);
|
||||
gsk_border_node_mesh_add_patch (mesh,
|
||||
&self->border_color[1],
|
||||
bounds->size.width, 0,
|
||||
br.x, tl.y,
|
||||
br.x, br.y,
|
||||
bounds->size.width, bounds->size.height);
|
||||
}
|
||||
|
||||
/* Bottom */
|
||||
if (self->border_width[2] > 0)
|
||||
{
|
||||
cairo_move_to (cr, bounds->origin.x, bounds->origin.y + bounds->size.height);
|
||||
cairo_rel_line_to (cr, self->border_width[3], - self->border_width[2]);
|
||||
cairo_rel_line_to (cr, bounds->size.width - self->border_width[3] - self->border_width[1], 0);
|
||||
cairo_rel_line_to (cr, self->border_width[1], self->border_width[2]);
|
||||
gdk_cairo_set_source_rgba (cr, &self->border_color[2]);
|
||||
cairo_fill (cr);
|
||||
gsk_border_node_mesh_add_patch (mesh,
|
||||
&self->border_color[2],
|
||||
0, bounds->size.height,
|
||||
tl.x, br.y,
|
||||
br.x, br.y,
|
||||
bounds->size.width, bounds->size.height);
|
||||
}
|
||||
|
||||
/* Left */
|
||||
if (self->border_width[3] > 0)
|
||||
{
|
||||
cairo_move_to (cr, bounds->origin.x, bounds->origin.y);
|
||||
cairo_rel_line_to (cr, self->border_width[3], self->border_width[0]);
|
||||
cairo_rel_line_to (cr, 0, bounds->size.height - self->border_width[0] - self->border_width[2]);
|
||||
cairo_rel_line_to (cr, - self->border_width[3], self->border_width[2]);
|
||||
gdk_cairo_set_source_rgba (cr, &self->border_color[3]);
|
||||
cairo_fill (cr);
|
||||
gsk_border_node_mesh_add_patch (mesh,
|
||||
&self->border_color[3],
|
||||
0, 0,
|
||||
tl.x, tl.y,
|
||||
tl.x, br.y,
|
||||
0, bounds->size.height);
|
||||
}
|
||||
|
||||
cairo_set_source (cr, mesh);
|
||||
cairo_pattern_destroy (mesh);
|
||||
}
|
||||
|
||||
cairo_fill (cr);
|
||||
cairo_restore (cr);
|
||||
}
|
||||
|
||||
@@ -4318,10 +4375,10 @@ gsk_cross_fade_node_draw (GskRenderNode *node,
|
||||
{
|
||||
GskCrossFadeNode *self = (GskCrossFadeNode *) node;
|
||||
|
||||
cairo_push_group (cr);
|
||||
cairo_push_group_with_content (cr, CAIRO_CONTENT_COLOR_ALPHA);
|
||||
gsk_render_node_draw (self->start, cr);
|
||||
|
||||
cairo_push_group (cr);
|
||||
cairo_push_group_with_content (cr, CAIRO_CONTENT_COLOR_ALPHA);
|
||||
gsk_render_node_draw (self->end, cr);
|
||||
|
||||
cairo_pop_group_to_source (cr);
|
||||
|
||||
+13
-7
@@ -197,9 +197,10 @@ gsk_rounded_rect_offset (GskRoundedRect *self,
|
||||
}
|
||||
|
||||
static void
|
||||
border_radius_shrink (graphene_size_t *corner,
|
||||
double width,
|
||||
double height)
|
||||
border_radius_shrink (graphene_size_t *corner,
|
||||
double width,
|
||||
double height,
|
||||
const graphene_size_t *max)
|
||||
{
|
||||
if (corner->width > 0)
|
||||
corner->width -= width;
|
||||
@@ -211,6 +212,11 @@ border_radius_shrink (graphene_size_t *corner,
|
||||
corner->width = 0;
|
||||
corner->height = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
corner->width = MIN (corner->width, max->width);
|
||||
corner->height = MIN (corner->height, max->height);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -260,10 +266,10 @@ gsk_rounded_rect_shrink (GskRoundedRect *self,
|
||||
self->bounds.size.height -= top + bottom;
|
||||
}
|
||||
|
||||
border_radius_shrink (&self->corner[GSK_CORNER_TOP_LEFT], left, top);
|
||||
border_radius_shrink (&self->corner[GSK_CORNER_TOP_RIGHT], right, top);
|
||||
border_radius_shrink (&self->corner[GSK_CORNER_BOTTOM_RIGHT], right, bottom);
|
||||
border_radius_shrink (&self->corner[GSK_CORNER_BOTTOM_LEFT], left, bottom);
|
||||
border_radius_shrink (&self->corner[GSK_CORNER_TOP_LEFT], left, top, &self->bounds.size);
|
||||
border_radius_shrink (&self->corner[GSK_CORNER_TOP_RIGHT], right, top, &self->bounds.size);
|
||||
border_radius_shrink (&self->corner[GSK_CORNER_BOTTOM_RIGHT], right, bottom, &self->bounds.size);
|
||||
border_radius_shrink (&self->corner[GSK_CORNER_BOTTOM_LEFT], left, bottom, &self->bounds.size);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
+281
-31
@@ -19,7 +19,7 @@
|
||||
|
||||
|
||||
/**
|
||||
* SECTION:gsktransform
|
||||
* SECTION:GskTransform
|
||||
* @Title: GskTransform
|
||||
* @Short_description: A description for transform operations
|
||||
*
|
||||
@@ -42,8 +42,7 @@ typedef struct _GskTransformClass GskTransformClass;
|
||||
struct _GskTransform
|
||||
{
|
||||
const GskTransformClass *transform_class;
|
||||
|
||||
volatile int ref_count;
|
||||
|
||||
GskTransformCategory category;
|
||||
GskTransform *next;
|
||||
};
|
||||
@@ -113,10 +112,9 @@ gsk_transform_alloc (const GskTransformClass *transform_class,
|
||||
|
||||
g_return_val_if_fail (transform_class != NULL, NULL);
|
||||
|
||||
self = g_malloc0 (transform_class->struct_size);
|
||||
self = g_atomic_rc_box_alloc0 (transform_class->struct_size);
|
||||
|
||||
self->transform_class = transform_class;
|
||||
self->ref_count = 1;
|
||||
self->category = next ? MIN (category, next->category) : category;
|
||||
self->next = gsk_transform_is_identity (next) ? NULL : next;
|
||||
|
||||
@@ -312,15 +310,15 @@ gsk_matrix_transform_apply_affine (GskTransform *transform,
|
||||
break;
|
||||
|
||||
case GSK_TRANSFORM_CATEGORY_2D_AFFINE:
|
||||
*out_dx += *out_scale_x * graphene_matrix_get_value (&self->matrix, 3, 0);
|
||||
*out_dy += *out_scale_y * graphene_matrix_get_value (&self->matrix, 3, 1);
|
||||
*out_scale_x *= graphene_matrix_get_value (&self->matrix, 0, 0);
|
||||
*out_scale_y *= graphene_matrix_get_value (&self->matrix, 1, 1);
|
||||
*out_dx += *out_scale_x * graphene_matrix_get_x_translation (&self->matrix);
|
||||
*out_dy += *out_scale_y * graphene_matrix_get_y_translation (&self->matrix);
|
||||
*out_scale_x *= graphene_matrix_get_x_scale (&self->matrix);
|
||||
*out_scale_y *= graphene_matrix_get_y_scale (&self->matrix);
|
||||
break;
|
||||
|
||||
case GSK_TRANSFORM_CATEGORY_2D_TRANSLATE:
|
||||
*out_dx += *out_scale_x * graphene_matrix_get_value (&self->matrix, 3, 0);
|
||||
*out_dy += *out_scale_y * graphene_matrix_get_value (&self->matrix, 3, 1);
|
||||
*out_dx += *out_scale_x * graphene_matrix_get_x_translation (&self->matrix);
|
||||
*out_dy += *out_scale_y * graphene_matrix_get_y_translation (&self->matrix);
|
||||
break;
|
||||
|
||||
case GSK_TRANSFORM_CATEGORY_IDENTITY:
|
||||
@@ -347,8 +345,8 @@ gsk_matrix_transform_apply_translate (GskTransform *transform,
|
||||
break;
|
||||
|
||||
case GSK_TRANSFORM_CATEGORY_2D_TRANSLATE:
|
||||
*out_dx += graphene_matrix_get_value (&self->matrix, 3, 0);
|
||||
*out_dy += graphene_matrix_get_value (&self->matrix, 3, 1);
|
||||
*out_dx += graphene_matrix_get_x_translation (&self->matrix);
|
||||
*out_dy += graphene_matrix_get_y_translation (&self->matrix);
|
||||
break;
|
||||
|
||||
case GSK_TRANSFORM_CATEGORY_IDENTITY:
|
||||
@@ -421,8 +419,10 @@ gsk_matrix_transform_equal (GskTransform *first_transform,
|
||||
GskMatrixTransform *first = (GskMatrixTransform *) first_transform;
|
||||
GskMatrixTransform *second = (GskMatrixTransform *) second_transform;
|
||||
|
||||
/* Crude, but better than just returning FALSE */
|
||||
return memcmp (&first->matrix, &second->matrix, sizeof (graphene_matrix_t)) == 0;
|
||||
if (graphene_matrix_equal_fast (&first->matrix, &second->matrix))
|
||||
return TRUE;
|
||||
|
||||
return graphene_matrix_equal (&first->matrix, &second->matrix);
|
||||
}
|
||||
|
||||
static const GskTransformClass GSK_TRANSFORM_TRANSFORM_CLASS =
|
||||
@@ -735,7 +735,7 @@ gsk_rotate_transform_equal (GskTransform *first_transform,
|
||||
GskRotateTransform *first = (GskRotateTransform *) first_transform;
|
||||
GskRotateTransform *second = (GskRotateTransform *) second_transform;
|
||||
|
||||
return first->angle == second->angle;
|
||||
return G_APPROX_VALUE (first->angle, second->angle, 0.01f);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -837,8 +837,8 @@ gsk_rotate3d_transform_equal (GskTransform *first_transform,
|
||||
GskRotate3dTransform *first = (GskRotate3dTransform *) first_transform;
|
||||
GskRotate3dTransform *second = (GskRotate3dTransform *) second_transform;
|
||||
|
||||
return first->angle == second->angle
|
||||
&& graphene_vec3_equal (&first->axis, &second->axis);
|
||||
return G_APPROX_VALUE (first->angle, second->angle, 0.01f) &&
|
||||
graphene_vec3_equal (&first->axis, &second->axis);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -996,9 +996,9 @@ gsk_scale_transform_equal (GskTransform *first_transform,
|
||||
GskScaleTransform *first = (GskScaleTransform *) first_transform;
|
||||
GskScaleTransform *second = (GskScaleTransform *) second_transform;
|
||||
|
||||
return first->factor_x == second->factor_x
|
||||
&& first->factor_y == second->factor_y
|
||||
&& first->factor_z == second->factor_z;
|
||||
return G_APPROX_VALUE (first->factor_x, second->factor_x, 0.01f) &&
|
||||
G_APPROX_VALUE (first->factor_y, second->factor_y, 0.01f) &&
|
||||
G_APPROX_VALUE (first->factor_z, second->factor_z, 0.01f);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1150,7 +1150,7 @@ gsk_perspective_transform_equal (GskTransform *first_transform,
|
||||
GskPerspectiveTransform *first = (GskPerspectiveTransform *) first_transform;
|
||||
GskPerspectiveTransform *second = (GskPerspectiveTransform *) second_transform;
|
||||
|
||||
return first->depth == second->depth;
|
||||
return G_APPROX_VALUE (first->depth, second->depth, 0.001f);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1217,8 +1217,6 @@ gsk_transform_finalize (GskTransform *self)
|
||||
self->transform_class->finalize (self);
|
||||
|
||||
gsk_transform_unref (self->next);
|
||||
|
||||
g_free (self);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1235,9 +1233,7 @@ gsk_transform_ref (GskTransform *self)
|
||||
if (self == NULL)
|
||||
return NULL;
|
||||
|
||||
g_atomic_int_inc (&self->ref_count);
|
||||
|
||||
return self;
|
||||
return g_atomic_rc_box_acquire (self);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1255,8 +1251,7 @@ gsk_transform_unref (GskTransform *self)
|
||||
if (self == NULL)
|
||||
return;
|
||||
|
||||
if (g_atomic_int_dec_and_test (&self->ref_count))
|
||||
gsk_transform_finalize (self);
|
||||
g_atomic_rc_box_release_full (self, (GDestroyNotify) gsk_transform_finalize);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1264,8 +1259,8 @@ gsk_transform_unref (GskTransform *self)
|
||||
* @self: (allow-none): a #GskTransform
|
||||
* @string: The string to print into
|
||||
*
|
||||
* Converts @self into a string representation suitable for printing that
|
||||
* can later be parsed with gsk_transform_parse().
|
||||
* Converts @self into a human-readable string representation suitable
|
||||
* for printing that can later be parsed with gsk_transform_parse().
|
||||
**/
|
||||
void
|
||||
gsk_transform_print (GskTransform *self,
|
||||
@@ -1651,3 +1646,258 @@ gsk_transform_transform_bounds (GskTransform *self,
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static guint
|
||||
gsk_transform_parse_float (GtkCssParser *parser,
|
||||
guint n,
|
||||
gpointer data)
|
||||
{
|
||||
float *f = data;
|
||||
double d;
|
||||
|
||||
if (!gtk_css_parser_consume_number (parser, &d))
|
||||
return 0;
|
||||
|
||||
f[n] = d;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static guint
|
||||
gsk_transform_parse_scale (GtkCssParser *parser,
|
||||
guint n,
|
||||
gpointer data)
|
||||
{
|
||||
float *f = data;
|
||||
double d;
|
||||
|
||||
if (!gtk_css_parser_consume_number (parser, &d))
|
||||
return 0;
|
||||
|
||||
f[n] = d;
|
||||
f[1] = d;
|
||||
return 1;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gsk_transform_parser_parse (GtkCssParser *parser,
|
||||
GskTransform **out_transform)
|
||||
{
|
||||
const GtkCssToken *token;
|
||||
GskTransform *transform = NULL;
|
||||
float f[16] = { 0, };
|
||||
|
||||
token = gtk_css_parser_get_token (parser);
|
||||
if (gtk_css_token_is_ident (token, "none"))
|
||||
{
|
||||
gtk_css_parser_consume_token (parser);
|
||||
*out_transform = NULL;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
if (gtk_css_token_is_function (token, "matrix"))
|
||||
{
|
||||
graphene_matrix_t matrix;
|
||||
if (!gtk_css_parser_consume_function (parser, 6, 6, gsk_transform_parse_float, f))
|
||||
goto fail;
|
||||
|
||||
graphene_matrix_init_from_2d (&matrix, f[0], f[1], f[2], f[3], f[4], f[5]);
|
||||
transform = gsk_transform_matrix_with_category (transform,
|
||||
&matrix,
|
||||
GSK_TRANSFORM_CATEGORY_2D);
|
||||
}
|
||||
else if (gtk_css_token_is_function (token, "matrix3d"))
|
||||
{
|
||||
graphene_matrix_t matrix;
|
||||
if (!gtk_css_parser_consume_function (parser, 16, 16, gsk_transform_parse_float, f))
|
||||
goto fail;
|
||||
|
||||
graphene_matrix_init_from_float (&matrix, f);
|
||||
transform = gsk_transform_matrix (transform, &matrix);
|
||||
}
|
||||
else if (gtk_css_token_is_function (token, "perspective"))
|
||||
{
|
||||
if (!gtk_css_parser_consume_function (parser, 1, 1, gsk_transform_parse_float, f))
|
||||
goto fail;
|
||||
|
||||
transform = gsk_transform_perspective (transform, f[0]);
|
||||
}
|
||||
else if (gtk_css_token_is_function (token, "rotate") ||
|
||||
gtk_css_token_is_function (token, "rotateZ"))
|
||||
{
|
||||
if (!gtk_css_parser_consume_function (parser, 1, 1, gsk_transform_parse_float, f))
|
||||
goto fail;
|
||||
|
||||
transform = gsk_transform_rotate (transform, f[0]);
|
||||
}
|
||||
else if (gtk_css_token_is_function (token, "rotate3d"))
|
||||
{
|
||||
graphene_vec3_t axis;
|
||||
|
||||
if (!gtk_css_parser_consume_function (parser, 4, 4, gsk_transform_parse_float, f))
|
||||
goto fail;
|
||||
|
||||
graphene_vec3_init (&axis, f[0], f[1], f[2]);
|
||||
transform = gsk_transform_rotate_3d (transform, f[3], &axis);
|
||||
}
|
||||
else if (gtk_css_token_is_function (token, "rotateX"))
|
||||
{
|
||||
if (!gtk_css_parser_consume_function (parser, 1, 1, gsk_transform_parse_float, f))
|
||||
goto fail;
|
||||
|
||||
transform = gsk_transform_rotate_3d (transform, f[0], graphene_vec3_x_axis ());
|
||||
}
|
||||
else if (gtk_css_token_is_function (token, "rotateY"))
|
||||
{
|
||||
if (!gtk_css_parser_consume_function (parser, 1, 1, gsk_transform_parse_float, f))
|
||||
goto fail;
|
||||
|
||||
transform = gsk_transform_rotate_3d (transform, f[0], graphene_vec3_y_axis ());
|
||||
}
|
||||
else if (gtk_css_token_is_function (token, "scale"))
|
||||
{
|
||||
if (!gtk_css_parser_consume_function (parser, 1, 2, gsk_transform_parse_scale, f))
|
||||
goto fail;
|
||||
|
||||
transform = gsk_transform_scale (transform, f[0], f[1]);
|
||||
}
|
||||
else if (gtk_css_token_is_function (token, "scale3d"))
|
||||
{
|
||||
if (!gtk_css_parser_consume_function (parser, 3, 3, gsk_transform_parse_float, f))
|
||||
goto fail;
|
||||
|
||||
transform = gsk_transform_scale_3d (transform, f[0], f[1], f[2]);
|
||||
}
|
||||
else if (gtk_css_token_is_function (token, "scaleX"))
|
||||
{
|
||||
if (!gtk_css_parser_consume_function (parser, 1, 1, gsk_transform_parse_float, f))
|
||||
goto fail;
|
||||
|
||||
transform = gsk_transform_scale (transform, f[0], 1.f);
|
||||
}
|
||||
else if (gtk_css_token_is_function (token, "scaleY"))
|
||||
{
|
||||
if (!gtk_css_parser_consume_function (parser, 1, 1, gsk_transform_parse_float, f))
|
||||
goto fail;
|
||||
|
||||
transform = gsk_transform_scale (transform, 1.f, f[0]);
|
||||
}
|
||||
else if (gtk_css_token_is_function (token, "scaleZ"))
|
||||
{
|
||||
if (!gtk_css_parser_consume_function (parser, 1, 1, gsk_transform_parse_float, f))
|
||||
goto fail;
|
||||
|
||||
transform = gsk_transform_scale_3d (transform, 1.f, 1.f, f[0]);
|
||||
}
|
||||
else if (gtk_css_token_is_function (token, "translate"))
|
||||
{
|
||||
f[1] = 0.f;
|
||||
if (!gtk_css_parser_consume_function (parser, 1, 2, gsk_transform_parse_float, f))
|
||||
goto fail;
|
||||
|
||||
transform = gsk_transform_translate (transform, &GRAPHENE_POINT_INIT (f[0], f[1]));
|
||||
}
|
||||
else if (gtk_css_token_is_function (token, "translate3d"))
|
||||
{
|
||||
if (!gtk_css_parser_consume_function (parser, 3, 3, gsk_transform_parse_float, f))
|
||||
goto fail;
|
||||
|
||||
transform = gsk_transform_translate_3d (transform, &GRAPHENE_POINT3D_INIT (f[0], f[1], f[2]));
|
||||
}
|
||||
else if (gtk_css_token_is_function (token, "translateX"))
|
||||
{
|
||||
if (!gtk_css_parser_consume_function (parser, 1, 1, gsk_transform_parse_float, f))
|
||||
goto fail;
|
||||
|
||||
transform = gsk_transform_translate (transform, &GRAPHENE_POINT_INIT (f[0], 0.f));
|
||||
}
|
||||
else if (gtk_css_token_is_function (token, "translateY"))
|
||||
{
|
||||
if (!gtk_css_parser_consume_function (parser, 1, 1, gsk_transform_parse_float, f))
|
||||
goto fail;
|
||||
|
||||
transform = gsk_transform_translate (transform, &GRAPHENE_POINT_INIT (0.f, f[0]));
|
||||
}
|
||||
else if (gtk_css_token_is_function (token, "translateZ"))
|
||||
{
|
||||
if (!gtk_css_parser_consume_function (parser, 1, 1, gsk_transform_parse_float, f))
|
||||
goto fail;
|
||||
|
||||
transform = gsk_transform_translate_3d (transform, &GRAPHENE_POINT3D_INIT (0.f, 0.f, f[0]));
|
||||
}
|
||||
#if 0
|
||||
/* FIXME: add these */
|
||||
else if (gtk_css_token_is_function (token, "skew"))
|
||||
{
|
||||
}
|
||||
else if (gtk_css_token_is_function (token, "skewX"))
|
||||
{
|
||||
}
|
||||
else if (gtk_css_token_is_function (token, "skewY"))
|
||||
{
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
token = gtk_css_parser_get_token (parser);
|
||||
}
|
||||
|
||||
if (transform == NULL)
|
||||
{
|
||||
gtk_css_parser_error_syntax (parser, "Expected a transform");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
*out_transform = transform;
|
||||
return TRUE;
|
||||
|
||||
fail:
|
||||
gsk_transform_unref (transform);
|
||||
*out_transform = NULL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* gsk_transform_parse:
|
||||
* @string: the string to parse
|
||||
* @out_transform: (out): The location to put the transform in
|
||||
*
|
||||
* Parses the given @string into a transform and puts it in
|
||||
* @out_transform. Strings printed via gsk_transform_to_string()
|
||||
* can be read in again successfully using this function.
|
||||
*
|
||||
* If @string does not describe a valid transform, %FALSE is
|
||||
* returned and %NULL is put in @out_transform.
|
||||
*
|
||||
* Returns: %TRUE if @string described a valid transform.
|
||||
**/
|
||||
gboolean
|
||||
gsk_transform_parse (const char *string,
|
||||
GskTransform **out_transform)
|
||||
{
|
||||
GtkCssParser *parser;
|
||||
GBytes *bytes;
|
||||
gboolean result;
|
||||
|
||||
g_return_val_if_fail (string != NULL, FALSE);
|
||||
g_return_val_if_fail (out_transform != NULL, FALSE);
|
||||
|
||||
bytes = g_bytes_new_static (string, strlen (string));
|
||||
parser = gtk_css_parser_new_for_bytes (bytes, NULL, NULL, NULL, NULL, NULL);
|
||||
|
||||
result = gsk_transform_parser_parse (parser, out_transform);
|
||||
|
||||
if (result && !gtk_css_parser_has_token (parser, GTK_CSS_TOKEN_EOF))
|
||||
{
|
||||
g_clear_pointer (out_transform, gsk_transform_unref);
|
||||
result = FALSE;
|
||||
}
|
||||
gtk_css_parser_unref (parser);
|
||||
g_bytes_unref (bytes);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -46,6 +46,9 @@ void gsk_transform_print (GskTransform
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
char * gsk_transform_to_string (GskTransform *self);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gsk_transform_parse (const char *string,
|
||||
GskTransform **out_transform);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gsk_transform_to_matrix (GskTransform *self,
|
||||
graphene_matrix_t *out_matrix);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
|
||||
@@ -23,15 +23,21 @@
|
||||
|
||||
#include "gsktransform.h"
|
||||
|
||||
#include <gsk/gsk.h>
|
||||
#include "gsk/gskrendernodeprivate.h"
|
||||
|
||||
#include <gtk/css/gtkcss.h>
|
||||
#include "gtk/css/gtkcssparserprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
GskTransform * gsk_transform_matrix_with_category (GskTransform *next,
|
||||
const graphene_matrix_t*matrix,
|
||||
GskTransformCategory category);
|
||||
|
||||
gboolean gsk_transform_parser_parse (GtkCssParser *parser,
|
||||
GskTransform **out_transform);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GSK_TRANSFORM_PRIVATE_H__ */
|
||||
|
||||
@@ -11,6 +11,7 @@ gsk_private_gl_shaders = [
|
||||
'resources/glsl/unblurred_outset_shadow.fs.glsl',
|
||||
'resources/glsl/border.fs.glsl',
|
||||
'resources/glsl/cross_fade.fs.glsl',
|
||||
'resources/glsl/blend.fs.glsl',
|
||||
'resources/glsl/es2_common.fs.glsl',
|
||||
'resources/glsl/es2_common.vs.glsl',
|
||||
'resources/glsl/gl3_common.fs.glsl',
|
||||
|
||||
@@ -0,0 +1,287 @@
|
||||
uniform int u_mode;
|
||||
uniform sampler2D u_source2;
|
||||
|
||||
float
|
||||
combine (float source, float backdrop)
|
||||
{
|
||||
return source + backdrop * (1 - source);
|
||||
}
|
||||
|
||||
vec4
|
||||
composite (vec4 Cs, vec4 Cb, vec3 B)
|
||||
{
|
||||
float ao = Cs.a + Cb.a * (1 - Cs.a);
|
||||
vec3 Co = (Cs.a*(1 - Cb.a)*Cs.rgb + Cs.a*Cb.a*B + (1 - Cs.a)*Cb.a*Cb.rgb) / ao;
|
||||
return vec4(Co, ao);
|
||||
}
|
||||
|
||||
vec4
|
||||
normal (vec4 Cs, vec4 Cb)
|
||||
{
|
||||
return composite (Cs, Cb, Cs.rgb);
|
||||
}
|
||||
|
||||
vec4
|
||||
multiply (vec4 Cs, vec4 Cb)
|
||||
{
|
||||
return composite (Cs, Cb, Cs.rgb * Cb.rgb);
|
||||
}
|
||||
|
||||
vec4
|
||||
difference (vec4 Cs, vec4 Cb)
|
||||
{
|
||||
return composite (Cs, Cb, abs(Cs.rgb - Cb.rgb));
|
||||
}
|
||||
|
||||
vec4
|
||||
screen (vec4 Cs, vec4 Cb)
|
||||
{
|
||||
return composite (Cs, Cb, Cs.rgb + Cb.rgb - Cs.rgb * Cb.rgb);
|
||||
}
|
||||
|
||||
float
|
||||
hard_light (float source, float backdrop)
|
||||
{
|
||||
if (source <= 0.5)
|
||||
return 2 * backdrop * source;
|
||||
else
|
||||
return 2 * (backdrop + source - backdrop * source) - 1;
|
||||
}
|
||||
|
||||
vec4
|
||||
hard_light (vec4 Cs, vec4 Cb)
|
||||
{
|
||||
vec3 B = vec3 (hard_light (Cs.r, Cb.r),
|
||||
hard_light (Cs.g, Cb.g),
|
||||
hard_light (Cs.b, Cb.b));
|
||||
return composite (Cs, Cb, B);
|
||||
}
|
||||
|
||||
float
|
||||
soft_light (float source, float backdrop)
|
||||
{
|
||||
float db;
|
||||
|
||||
if (backdrop <= 0.25)
|
||||
db = ((16 * backdrop - 12) * backdrop + 4) * backdrop;
|
||||
else
|
||||
db = sqrt (backdrop);
|
||||
|
||||
if (source <= 0.5)
|
||||
return backdrop - (1 - 2 * source) * backdrop * (1 - backdrop);
|
||||
else
|
||||
return backdrop + (2 * source - 1) * (db - backdrop);
|
||||
}
|
||||
|
||||
vec4
|
||||
soft_light (vec4 Cs, vec4 Cb)
|
||||
{
|
||||
vec3 B = vec3 (soft_light (Cs.r, Cb.r),
|
||||
soft_light (Cs.g, Cb.g),
|
||||
soft_light (Cs.b, Cb.b));
|
||||
return composite (Cs, Cb, B);
|
||||
}
|
||||
|
||||
vec4
|
||||
overlay (vec4 Cs, vec4 Cb)
|
||||
{
|
||||
vec3 B = vec3 (hard_light (Cb.r, Cs.r),
|
||||
hard_light (Cb.g, Cs.g),
|
||||
hard_light (Cb.b, Cs.b));
|
||||
return composite (Cs, Cb, B);
|
||||
}
|
||||
|
||||
vec4
|
||||
darken (vec4 Cs, vec4 Cb)
|
||||
{
|
||||
vec3 B = min (Cs.rgb, Cb.rgb);
|
||||
return composite (Cs, Cb, B);
|
||||
}
|
||||
|
||||
vec4
|
||||
lighten (vec4 Cs, vec4 Cb)
|
||||
{
|
||||
vec3 B = max (Cs.rgb, Cb.rgb);
|
||||
return composite (Cs, Cb, B);
|
||||
}
|
||||
|
||||
float
|
||||
color_dodge (float source, float backdrop)
|
||||
{
|
||||
return (source == 1.0) ? source : min (backdrop / (1.0 - source), 1.0);
|
||||
}
|
||||
|
||||
vec4
|
||||
color_dodge (vec4 Cs, vec4 Cb)
|
||||
{
|
||||
vec3 B = vec3 (color_dodge (Cs.r, Cb.r),
|
||||
color_dodge (Cs.g, Cb.g),
|
||||
color_dodge (Cs.b, Cb.b));
|
||||
return composite (Cs, Cb, B);
|
||||
}
|
||||
|
||||
|
||||
float
|
||||
color_burn (float source, float backdrop)
|
||||
{
|
||||
return (source == 0.0) ? source : max ((1.0 - ((1.0 - backdrop) / source)), 0.0);
|
||||
}
|
||||
|
||||
vec4
|
||||
color_burn (vec4 Cs, vec4 Cb)
|
||||
{
|
||||
vec3 B = vec3 (color_burn (Cs.r, Cb.r),
|
||||
color_burn (Cs.g, Cb.g),
|
||||
color_burn (Cs.b, Cb.b));
|
||||
return composite (Cs, Cb, B);
|
||||
}
|
||||
|
||||
vec4
|
||||
exclusion (vec4 Cs, vec4 Cb)
|
||||
{
|
||||
vec3 B = Cb.rgb + Cs.rgb - 2.0 * Cb.rgb * Cs.rgb;
|
||||
return composite (Cs, Cb, B);
|
||||
}
|
||||
|
||||
float
|
||||
lum (vec3 c)
|
||||
{
|
||||
return 0.3 * c.r + 0.59 * c.g + 0.11 * c.b;
|
||||
}
|
||||
|
||||
vec3
|
||||
clip_color (vec3 c)
|
||||
{
|
||||
float l = lum (c);
|
||||
float n = min (c.r, min (c.g, c.b));
|
||||
float x = max (c.r, max (c.g, c.b));
|
||||
if (n < 0) c = l + (((c - l) * l) / (l - n));
|
||||
if (x > 1) c = l + (((c - l) * (1 - l)) / (x - l));
|
||||
return c;
|
||||
}
|
||||
|
||||
vec3
|
||||
set_lum (vec3 c, float l)
|
||||
{
|
||||
float d = l - lum (c);
|
||||
return clip_color (vec3 (c.r + d, c.g + d, c.b + d));
|
||||
}
|
||||
|
||||
float
|
||||
sat (vec3 c)
|
||||
{
|
||||
return max (c.r, max (c.g, c.b)) - min (c.r, min (c.g, c.b));
|
||||
}
|
||||
|
||||
vec3
|
||||
set_sat (vec3 c, float s)
|
||||
{
|
||||
float cmin = min (c.r, min (c.g, c.b));
|
||||
float cmax = max (c.r, max (c.g, c.b));
|
||||
vec3 res;
|
||||
|
||||
if (cmax == cmin)
|
||||
res = vec3 (0, 0, 0);
|
||||
else
|
||||
{
|
||||
if (c.r == cmax)
|
||||
{
|
||||
if (c.g == cmin)
|
||||
{
|
||||
res.b = ((c.b - cmin) * s) / (cmax - cmin);
|
||||
res.g = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
res.g = ((c.g - cmin) * s) / (cmax - cmin);
|
||||
res.b = 0;
|
||||
}
|
||||
res.r = s;
|
||||
}
|
||||
else if (c.g == cmax)
|
||||
{
|
||||
if (c.r == cmin)
|
||||
{
|
||||
res.b = ((c.b - cmin) * s) / (cmax - cmin);
|
||||
res.r = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
res.r = ((c.r - cmin) * s) / (cmax - cmin);
|
||||
res.b = 0;
|
||||
}
|
||||
res.g = s;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (c.r == cmin)
|
||||
{
|
||||
res.g = ((c.g - cmin) * s) / (cmax - cmin);
|
||||
res.r = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
res.r = ((c.r - cmin) * s) / (cmax - cmin);
|
||||
res.g = 0;
|
||||
}
|
||||
res.b = s;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
vec4
|
||||
color (vec4 Cs, vec4 Cb)
|
||||
{
|
||||
vec3 B = set_lum (Cs.rgb, lum (Cb.rgb));
|
||||
return composite (Cs, Cb, B);
|
||||
}
|
||||
|
||||
vec4
|
||||
hue (vec4 Cs, vec4 Cb)
|
||||
{
|
||||
vec3 B = set_lum (set_sat (Cs.rgb, sat (Cb.rgb)), lum (Cb.rgb));
|
||||
return composite (Cs, Cb, B);
|
||||
}
|
||||
|
||||
vec4
|
||||
saturation (vec4 Cs, vec4 Cb)
|
||||
{
|
||||
vec3 B = set_lum (set_sat (Cb.rgb, sat (Cs.rgb)), lum (Cb.rgb));
|
||||
return composite (Cs, Cb, B);
|
||||
}
|
||||
|
||||
vec4
|
||||
luminosity (vec4 Cs, vec4 Cb)
|
||||
{
|
||||
vec3 B = set_lum (Cb.rgb, lum (Cs.rgb));
|
||||
return composite (Cs, Cb, B);
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec4 bottom_color = Texture(u_source, vUv);
|
||||
vec4 top_color = Texture(u_source2, vUv);
|
||||
|
||||
vec4 result;
|
||||
switch(u_mode) {
|
||||
case 0: result = normal(bottom_color, top_color); break;
|
||||
case 1: result = multiply(bottom_color, top_color); break;
|
||||
case 2: result = screen(bottom_color, top_color); break;
|
||||
case 3: result = overlay(bottom_color, top_color); break;
|
||||
case 4: result = darken(bottom_color, top_color); break;
|
||||
case 5: result = lighten(bottom_color, top_color); break;
|
||||
case 6: result = color_dodge(bottom_color, top_color); break;
|
||||
case 7: result = color_burn(bottom_color, top_color); break;
|
||||
case 8: result = hard_light(bottom_color, top_color); break;
|
||||
case 9: result = soft_light(bottom_color, top_color); break;
|
||||
case 10: result = difference(bottom_color, top_color); break;
|
||||
case 11: result = exclusion(bottom_color, top_color); break;
|
||||
case 12: result = color(bottom_color, top_color); break;
|
||||
case 13: result = hue(bottom_color, top_color); break;
|
||||
case 14: result = saturation(bottom_color, top_color); break;
|
||||
case 15: result = luminosity(bottom_color, top_color); break;
|
||||
default: discard;
|
||||
}
|
||||
|
||||
setOutputColor(result * u_alpha);
|
||||
}
|
||||
@@ -6,7 +6,8 @@ void main() {
|
||||
vec4 source1 = Texture(u_source, vUv); // start child
|
||||
vec4 source2 = Texture(u_source2, vUv); // end child
|
||||
|
||||
float p = u_progress;
|
||||
vec4 color = ((1.0 - p) * source1) + (p * source2);
|
||||
float p_start = (1.0 - u_progress) * u_alpha;
|
||||
float p_end = u_progress * u_alpha;
|
||||
vec4 color = (p_start * source1) + (p_end * source2);
|
||||
setOutputColor(color);
|
||||
}
|
||||
|
||||
@@ -72,6 +72,7 @@ gsk_vulkan_clip_intersect_rect (GskVulkanClip *dest,
|
||||
*/
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
|
||||
@@ -42,6 +42,13 @@ gtk_cell_accessible_parent_get_type (void)
|
||||
return g_define_type_id__volatile;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_cell_accessible_parent_get_cell_extents:
|
||||
* @x: (out):
|
||||
* @y: (out):
|
||||
* @width: (out):
|
||||
* @height: (out):
|
||||
*/
|
||||
void
|
||||
gtk_cell_accessible_parent_get_cell_extents (GtkCellAccessibleParent *parent,
|
||||
GtkCellAccessible *cell,
|
||||
@@ -61,6 +68,10 @@ gtk_cell_accessible_parent_get_cell_extents (GtkCellAccessibleParent *parent,
|
||||
(iface->get_cell_extents) (parent, cell, x, y, width, height, coord_type);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_cell_accessible_parent_get_cell_area:
|
||||
* @cell_rect: (out):
|
||||
*/
|
||||
void
|
||||
gtk_cell_accessible_parent_get_cell_area (GtkCellAccessibleParent *parent,
|
||||
GtkCellAccessible *cell,
|
||||
@@ -188,6 +199,11 @@ gtk_cell_accessible_parent_update_relationset (GtkCellAccessibleParent *parent,
|
||||
(iface->update_relationset) (parent, cell, relationset);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_cell_accessible_parent_get_cell_position:
|
||||
* @row: (out):
|
||||
* @column: (out):
|
||||
*/
|
||||
void
|
||||
gtk_cell_accessible_parent_get_cell_position (GtkCellAccessibleParent *parent,
|
||||
GtkCellAccessible *cell,
|
||||
|
||||
@@ -614,7 +614,6 @@ static gboolean
|
||||
gtk_icon_view_item_accessible_grab_focus (AtkComponent *component)
|
||||
{
|
||||
GtkIconViewItemAccessible *item;
|
||||
GtkWidget *toplevel;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_ICON_VIEW_ITEM_ACCESSIBLE (component), FALSE);
|
||||
|
||||
@@ -624,13 +623,6 @@ gtk_icon_view_item_accessible_grab_focus (AtkComponent *component)
|
||||
|
||||
gtk_widget_grab_focus (item->widget);
|
||||
_gtk_icon_view_set_cursor_item (GTK_ICON_VIEW (item->widget), item->item, NULL);
|
||||
toplevel = gtk_widget_get_toplevel (GTK_WIDGET (item->widget));
|
||||
if (gtk_widget_is_toplevel (toplevel))
|
||||
{
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
gtk_window_present (GTK_WINDOW (toplevel));
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -557,7 +557,7 @@ gtk_widget_accessible_get_extents (AtkComponent *component,
|
||||
{
|
||||
*x = allocation.x;
|
||||
*y = allocation.y;
|
||||
surface = gtk_widget_get_parent_surface (widget);
|
||||
surface = gtk_widget_get_surface (gtk_widget_get_parent (widget));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
|
||||
* file for a list of people on the GTK+ Team. See the ChangeLog
|
||||
* files for a list of changes. These files are distributed with
|
||||
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
|
||||
*/
|
||||
|
||||
#ifndef __GTK_CSS_H__
|
||||
#define __GTK_CSS_H__
|
||||
|
||||
#define __GTK_CSS_H_INSIDE__
|
||||
|
||||
#include <glib.h>
|
||||
#include <gdk/gdkversionmacros.h>
|
||||
|
||||
#include <gtk/css/gtkcssenums.h>
|
||||
#include <gtk/css/gtkcssenumtypes.h>
|
||||
#include <gtk/css/gtkcsserror.h>
|
||||
#include <gtk/css/gtkcsslocation.h>
|
||||
#include <gtk/css/gtkcsssection.h>
|
||||
|
||||
#undef __GTK_CSS_H_INSIDE__
|
||||
|
||||
#endif /* __GTK_CSS_H__ */
|
||||
@@ -0,0 +1,77 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
|
||||
* file for a list of people on the GTK+ Team. See the ChangeLog
|
||||
* files for a list of changes. These files are distributed with
|
||||
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
|
||||
*/
|
||||
|
||||
#ifndef __GTK_CSS_ENUMS_H__
|
||||
#define __GTK_CSS_ENUMS_H__
|
||||
|
||||
#if !defined (__GTK_CSS_H_INSIDE__) && !defined (GTK_CSS_COMPILATION)
|
||||
#error "Only <gtk/css/gtkcss.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <glib.h>
|
||||
#include <gdk/gdkversionmacros.h>
|
||||
|
||||
/**
|
||||
* GtkCssParserError:
|
||||
* @GTK_CSS_PARSER_ERROR_FAILED: Unknown failure.
|
||||
* @GTK_CSS_PARSER_ERROR_SYNTAX: The given text does not form valid
|
||||
* syntax
|
||||
* @GTK_CSS_PARSER_ERROR_IMPORT: Failed to import a resource
|
||||
* @GTK_CSS_PARSER_ERROR_NAME: The given name has not been defined
|
||||
* @GTK_CSS_PARSER_ERROR_UNKNOWN_VALUE: The given value is not
|
||||
* correct
|
||||
*
|
||||
* Errors that can occur while parsing CSS.
|
||||
*
|
||||
* These errors are unexpected and will cause parts of the given CSS
|
||||
* to be ignored.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
GTK_CSS_PARSER_ERROR_FAILED,
|
||||
GTK_CSS_PARSER_ERROR_SYNTAX,
|
||||
GTK_CSS_PARSER_ERROR_IMPORT,
|
||||
GTK_CSS_PARSER_ERROR_NAME,
|
||||
GTK_CSS_PARSER_ERROR_UNKNOWN_VALUE
|
||||
} GtkCssParserError;
|
||||
|
||||
/**
|
||||
* GtkCssParserWarning:
|
||||
* @GTK_CSS_PARSER_WARNING_DEPRECATED: The given construct is
|
||||
* deprecated and will be removed in a future version
|
||||
* @GTK_CSS_PARSER_WARNING_SYNTAX: A syntax construct was used
|
||||
* that should be avoided
|
||||
*
|
||||
* Warnings that can occur while parsing CSS.
|
||||
*
|
||||
* Unlike #GtkCssParserErrors, warnings do not cause the parser to
|
||||
* skip any input, but they indicate issues that should be fixed.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
GTK_CSS_PARSER_WARNING_DEPRECATED,
|
||||
GTK_CSS_PARSER_WARNING_SYNTAX
|
||||
} GtkCssParserWarning;
|
||||
|
||||
#endif /* __GTK_CSS_ENUMS_H__ */
|
||||
@@ -0,0 +1,38 @@
|
||||
/*** BEGIN file-header ***/
|
||||
#include "config.h"
|
||||
#include "gtkcssenumtypes.h"
|
||||
#include <gtkcss.h>
|
||||
|
||||
/*** END file-header ***/
|
||||
|
||||
/*** BEGIN file-production ***/
|
||||
/* enumerations from "@basename@" */
|
||||
/*** END file-production ***/
|
||||
|
||||
/*** BEGIN value-header ***/
|
||||
GType
|
||||
@enum_name@_get_type (void)
|
||||
{
|
||||
static volatile gsize g_define_type_id__volatile = 0;
|
||||
|
||||
if (g_once_init_enter (&g_define_type_id__volatile))
|
||||
{
|
||||
static const G@Type@Value values[] = {
|
||||
/*** END value-header ***/
|
||||
|
||||
/*** BEGIN value-production ***/
|
||||
{ @VALUENAME@, "@VALUENAME@", "@valuenick@" },
|
||||
/*** END value-production ***/
|
||||
|
||||
/*** BEGIN value-tail ***/
|
||||
{ 0, NULL, NULL }
|
||||
};
|
||||
GType g_define_type_id =
|
||||
g_@type@_register_static (g_intern_static_string ("@EnumName@"), values);
|
||||
g_once_init_leave (&g_define_type_id__volatile, g_define_type_id);
|
||||
}
|
||||
|
||||
return g_define_type_id__volatile;
|
||||
}
|
||||
|
||||
/*** END value-tail ***/
|
||||
@@ -0,0 +1,29 @@
|
||||
/*** BEGIN file-header ***/
|
||||
#ifndef __GTK_CSS_ENUM_TYPES_H__
|
||||
#define __GTK_CSS_ENUM_TYPES_H__
|
||||
|
||||
#if !defined (__GTK_CSS_H_INSIDE__) && !defined (GTK_CSS_COMPILATION)
|
||||
#error "Only <gtk/css/gtkcss.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <glib-object.h>
|
||||
#include <gdk/gdkversionmacros.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
/*** END file-header ***/
|
||||
|
||||
/*** BEGIN file-production ***/
|
||||
|
||||
/* enumerations from "@basename@" */
|
||||
/*** END file-production ***/
|
||||
|
||||
/*** BEGIN value-header ***/
|
||||
GDK_AVAILABLE_IN_ALL GType @enum_name@_get_type (void) G_GNUC_CONST;
|
||||
#define @ENUMPREFIX@_TYPE_@ENUMSHORT@ (@enum_name@_get_type ())
|
||||
/*** END value-header ***/
|
||||
|
||||
/*** BEGIN file-tail ***/
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_CSS_ENUM_TYPES_H__ */
|
||||
/*** END file-tail ***/
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright © 2019 Benjamin Otte
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Benjamin Otte <otte@gnome.org>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gtkcsserror.h"
|
||||
|
||||
GQuark
|
||||
gtk_css_parser_error_quark (void)
|
||||
{
|
||||
return g_quark_from_static_string ("gtk-css-parser-error-quark");
|
||||
}
|
||||
|
||||
GQuark
|
||||
gtk_css_parser_warning_quark (void)
|
||||
{
|
||||
return g_quark_from_static_string ("gtk-css-parser-warning-quark");
|
||||
}
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright © 2019 Benjamin Otte
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Benjamin Otte <otte@gnome.org>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __GTK_CSS_ERROR_H__
|
||||
#define __GTK_CSS_ERROR_H__
|
||||
|
||||
#include <glib.h>
|
||||
#include <gdk/gdkversionmacros.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/**
|
||||
* GTK_CSS_PARSER_ERROR:
|
||||
*
|
||||
* Domain for #GtkCssParser errors.
|
||||
*/
|
||||
#define GTK_CSS_PARSER_ERROR (gtk_css_parser_error_quark ())
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GQuark gtk_css_parser_error_quark (void);
|
||||
|
||||
/**
|
||||
* GTK_CSS_PARSER_WARNING:
|
||||
*
|
||||
* Domain for #GtkCssParser warnings.
|
||||
*/
|
||||
#define GTK_CSS_PARSER_WARNING (gtk_css_parser_warning_quark ())
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GQuark gtk_css_parser_warning_quark (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_CSS_ERROR_H__ */
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user