diff options
-rw-r--r-- | examples/qml-compositor/qml-compositor.qrc | 2 | ||||
-rw-r--r-- | examples/qml-compositor/qml/QmlCompositor/ContrastEffect.qml (renamed from examples/qml-compositor/qml/QmlCompositor/ShaderEffect.qml) | 10 | ||||
-rw-r--r-- | examples/qml-compositor/qml/QmlCompositor/WindowContainer.qml | 2 | ||||
-rw-r--r-- | examples/qwidget-compositor/qwidget-compositor.pro (renamed from examples/qwidget-compositor/qt-compositor.pro) | 0 | ||||
-rw-r--r-- | qt-compositor.pro | 2 | ||||
-rw-r--r-- | src/qt-compositor/wayland_wrapper/wlselection.cpp | 52 | ||||
-rw-r--r-- | src/qt-compositor/wayland_wrapper/wlselection.h | 3 | ||||
-rw-r--r-- | src/src.pro | 2 |
8 files changed, 54 insertions, 19 deletions
diff --git a/examples/qml-compositor/qml-compositor.qrc b/examples/qml-compositor/qml-compositor.qrc index 0dc86580c..0a3898fb2 100644 --- a/examples/qml-compositor/qml-compositor.qrc +++ b/examples/qml-compositor/qml-compositor.qrc @@ -3,7 +3,7 @@ <file>background.jpg</file> <file>qml/QmlCompositor/main.qml</file> <file>qml/QmlCompositor/compositor.js</file> - <file>qml/QmlCompositor/ShaderEffect.qml</file> + <file>qml/QmlCompositor/ContrastEffect.qml</file> <file>qml/QmlCompositor/WindowChrome.qml</file> <file>qml/QmlCompositor/WindowContainer.qml</file> </qresource> diff --git a/examples/qml-compositor/qml/QmlCompositor/ShaderEffect.qml b/examples/qml-compositor/qml/QmlCompositor/ContrastEffect.qml index eb2f80005..b832c7131 100644 --- a/examples/qml-compositor/qml/QmlCompositor/ShaderEffect.qml +++ b/examples/qml-compositor/qml/QmlCompositor/ContrastEffect.qml @@ -40,7 +40,7 @@ import QtQuick 2.0 -ShaderEffectItem { +ShaderEffect { property variant source: null; property color color: "#ffffff" property real blend; @@ -53,23 +53,23 @@ ShaderEffectItem { } property string vShader: " - uniform highp mat4 qt_ModelViewProjectionMatrix; + uniform highp mat4 qt_Matrix; attribute highp vec4 qt_Vertex; attribute highp vec2 qt_MultiTexCoord0; varying highp vec2 qt_TexCoord0; void main() { qt_TexCoord0 = qt_MultiTexCoord0; - gl_Position = qt_ModelViewProjectionMatrix * qt_Vertex; + gl_Position = qt_Matrix * qt_Vertex; } " property string vShaderInvertedY: " - uniform highp mat4 qt_ModelViewProjectionMatrix; + uniform highp mat4 qt_Matrix; attribute highp vec4 qt_Vertex; attribute highp vec2 qt_MultiTexCoord0; varying highp vec2 qt_TexCoord0; void main() { qt_TexCoord0 = vec2(0, 1) + qt_MultiTexCoord0 * vec2(1, -1); - gl_Position = qt_ModelViewProjectionMatrix * qt_Vertex; + gl_Position = qt_Matrix * qt_Vertex; } " diff --git a/examples/qml-compositor/qml/QmlCompositor/WindowContainer.qml b/examples/qml-compositor/qml/QmlCompositor/WindowContainer.qml index 9182f251d..b5683e90a 100644 --- a/examples/qml-compositor/qml/QmlCompositor/WindowContainer.qml +++ b/examples/qml-compositor/qml/QmlCompositor/WindowContainer.qml @@ -72,7 +72,7 @@ Item { NumberAnimation { easing.type: Easing.Linear; duration: 250; } } - ShaderEffect { + ContrastEffect { id: effect source: child anchors.fill: child diff --git a/examples/qwidget-compositor/qt-compositor.pro b/examples/qwidget-compositor/qwidget-compositor.pro index 353b34ca5..353b34ca5 100644 --- a/examples/qwidget-compositor/qt-compositor.pro +++ b/examples/qwidget-compositor/qwidget-compositor.pro diff --git a/qt-compositor.pro b/qt-compositor.pro new file mode 100644 index 000000000..8feb4aa44 --- /dev/null +++ b/qt-compositor.pro @@ -0,0 +1,2 @@ +TEMPLATE=subdirs +SUBDIRS=src diff --git a/src/qt-compositor/wayland_wrapper/wlselection.cpp b/src/qt-compositor/wayland_wrapper/wlselection.cpp index 8949e657f..929899cb0 100644 --- a/src/qt-compositor/wayland_wrapper/wlselection.cpp +++ b/src/qt-compositor/wayland_wrapper/wlselection.cpp @@ -43,8 +43,10 @@ #include <wayland-util.h> #include <string.h> #include <unistd.h> +#include <fcntl.h> #include <QtCore/QFile> #include <QtCore/QSocketNotifier> +#include <QtCore/private/qcore_unix_p.h> namespace Wayland { @@ -155,6 +157,7 @@ void Selection::retain() qWarning("Clipboard: Failed to create pipe"); return; } + fcntl(fd[0], F_SETFL, fcntl(fd[0], F_GETFL, 0) | O_NONBLOCK); wl_client_post_event(m_currentSelection->client, &m_currentSelection->resource.object, WL_SELECTION_SEND, mimeTypeBa.constData(), fd[1]); close(fd[1]); @@ -162,26 +165,53 @@ void Selection::retain() connect(m_retainedReadNotifier, SIGNAL(activated(int)), SLOT(readFromClient(int))); } -void Selection::finishReadFromClient() +void Selection::finishReadFromClient(bool exhausted) { if (m_retainedReadNotifier) { - int fd = m_retainedReadNotifier->socket(); - delete m_retainedReadNotifier; + if (exhausted) { + int fd = m_retainedReadNotifier->socket(); + delete m_retainedReadNotifier; + close(fd); + } else { + // Do not close the handle or destroy the read notifier here + // or else clients may SIGPIPE. + m_obsoleteRetainedReadNotifiers.append(m_retainedReadNotifier); + } m_retainedReadNotifier = 0; - close(fd); } } void Selection::readFromClient(int fd) { - char buf[256]; - int n = read(fd, buf, sizeof buf); + static char buf[4096]; + int obsCount = m_obsoleteRetainedReadNotifiers.count(); + for (int i = 0; i < obsCount; ++i) { + QSocketNotifier *sn = m_obsoleteRetainedReadNotifiers.at(i); + if (sn->socket() == fd) { + // Read and drop the data, stopping to read and closing the handle + // is not yet safe because that could kill the client with SIGPIPE + // when it still tries to write. + int n; + do { + n = QT_READ(fd, buf, sizeof buf); + } while (n > 0); + if (n != -1 || (errno != EAGAIN && errno != EWOULDBLOCK)) { + m_obsoleteRetainedReadNotifiers.removeAt(i); + delete sn; + close(fd); + } + return; + } + } + int n = QT_READ(fd, buf, sizeof buf); if (n <= 0) { - finishReadFromClient(); - QString mimeType = m_offerList.at(m_retainedReadIndex); - m_retainedData.setData(mimeType, m_retainedReadBuf); - ++m_retainedReadIndex; - retain(); + if (n != -1 || (errno != EAGAIN && errno != EWOULDBLOCK)) { + finishReadFromClient(true); + QString mimeType = m_offerList.at(m_retainedReadIndex); + m_retainedData.setData(mimeType, m_retainedReadBuf); + ++m_retainedReadIndex; + retain(); + } } else { m_retainedReadBuf.append(buf, n); } diff --git a/src/qt-compositor/wayland_wrapper/wlselection.h b/src/qt-compositor/wayland_wrapper/wlselection.h index 03468422f..2a9b083cc 100644 --- a/src/qt-compositor/wayland_wrapper/wlselection.h +++ b/src/qt-compositor/wayland_wrapper/wlselection.h @@ -86,13 +86,14 @@ private: static const struct wl_selection_offer_interface selectionOfferInterface; void retain(); - void finishReadFromClient(); + void finishReadFromClient(bool exhausted = false); QStringList m_offerList; struct wl_selection *m_currentSelection; struct wl_selection_offer *m_currentOffer; QMimeData m_retainedData; QSocketNotifier *m_retainedReadNotifier; + QList<QSocketNotifier *> m_obsoleteRetainedReadNotifiers; int m_retainedReadIndex; QByteArray m_retainedReadBuf; struct wl_selection *m_retainedSelection; diff --git a/src/src.pro b/src/src.pro new file mode 100644 index 000000000..d2dd7c8f2 --- /dev/null +++ b/src/src.pro @@ -0,0 +1,2 @@ +TEMPLATE=subdirs +SUBDIRS=qt-compositor |