1 | // Copyright (C) 2016 The Qt Company Ltd. |
---|---|
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only |
3 | |
4 | #include "qwaylandclipboard_p.h" |
5 | #include "qwaylanddisplay_p.h" |
6 | #include "qwaylandinputdevice_p.h" |
7 | #include "qwaylanddataoffer_p.h" |
8 | #include "qwaylanddatasource_p.h" |
9 | #include "qwaylanddatadevice_p.h" |
10 | #if QT_CONFIG(wayland_client_primary_selection) |
11 | #include "qwaylandprimaryselectionv1_p.h" |
12 | #endif |
13 | |
14 | QT_BEGIN_NAMESPACE |
15 | |
16 | namespace QtWaylandClient { |
17 | |
18 | QWaylandClipboard::QWaylandClipboard(QWaylandDisplay *display) |
19 | : mDisplay(display) |
20 | { |
21 | m_clientClipboard[QClipboard::Clipboard] = nullptr; |
22 | m_clientClipboard[QClipboard::Selection] = nullptr; |
23 | } |
24 | |
25 | QWaylandClipboard::~QWaylandClipboard() |
26 | { |
27 | if (m_clientClipboard[QClipboard::Clipboard] != m_clientClipboard[QClipboard::Selection]) |
28 | delete m_clientClipboard[QClipboard::Clipboard]; |
29 | delete m_clientClipboard[QClipboard::Selection]; |
30 | } |
31 | |
32 | QMimeData *QWaylandClipboard::mimeData(QClipboard::Mode mode) |
33 | { |
34 | auto *seat = mDisplay->currentInputDevice(); |
35 | if (!seat) |
36 | return &m_emptyData; |
37 | |
38 | switch (mode) { |
39 | case QClipboard::Clipboard: |
40 | if (auto *dataDevice = seat->dataDevice()) { |
41 | if (dataDevice->selectionSource()) |
42 | return m_clientClipboard[QClipboard::Clipboard]; |
43 | if (auto *offer = dataDevice->selectionOffer()) |
44 | return offer->mimeData(); |
45 | } |
46 | return &m_emptyData; |
47 | case QClipboard::Selection: |
48 | #if QT_CONFIG(wayland_client_primary_selection) |
49 | if (auto *selectionDevice = seat->primarySelectionDevice()) { |
50 | if (selectionDevice->selectionSource()) |
51 | return m_clientClipboard[QClipboard::Selection]; |
52 | if (auto *offer = selectionDevice->selectionOffer()) |
53 | return offer->mimeData(); |
54 | } |
55 | #endif |
56 | return &m_emptyData; |
57 | default: |
58 | return &m_emptyData; |
59 | } |
60 | } |
61 | |
62 | void QWaylandClipboard::setMimeData(QMimeData *data, QClipboard::Mode mode) |
63 | { |
64 | auto *seat = mDisplay->currentInputDevice(); |
65 | if (!seat) { |
66 | qCWarning(lcQpaWayland) << "Can't set clipboard contents with no wl_seats available"; |
67 | return; |
68 | } |
69 | |
70 | static const QString plain = QStringLiteral("text/plain"); |
71 | static const QString utf8 = QStringLiteral("text/plain;charset=utf-8"); |
72 | |
73 | if (data && data->hasFormat(mimetype: plain) && !data->hasFormat(mimetype: utf8)) |
74 | data->setData(mimetype: utf8, data: data->data(mimetype: plain)); |
75 | |
76 | if (m_clientClipboard[mode]) { |
77 | if (m_clientClipboard[QClipboard::Clipboard] != m_clientClipboard[QClipboard::Selection]) |
78 | delete m_clientClipboard[mode]; |
79 | m_clientClipboard[mode] = nullptr; |
80 | } |
81 | |
82 | m_clientClipboard[mode] = data; |
83 | |
84 | switch (mode) { |
85 | case QClipboard::Clipboard: |
86 | if (auto *dataDevice = seat->dataDevice()) { |
87 | dataDevice->setSelectionSource(data ? new QWaylandDataSource(mDisplay->dndSelectionHandler(), |
88 | m_clientClipboard[QClipboard::Clipboard]) : nullptr); |
89 | emitChanged(mode); |
90 | } |
91 | break; |
92 | case QClipboard::Selection: |
93 | #if QT_CONFIG(wayland_client_primary_selection) |
94 | if (auto *selectionDevice = seat->primarySelectionDevice()) { |
95 | selectionDevice->setSelectionSource(data ? new QWaylandPrimarySelectionSourceV1(mDisplay->primarySelectionManager(), |
96 | m_clientClipboard[QClipboard::Selection]) : nullptr); |
97 | emitChanged(mode); |
98 | } |
99 | #endif |
100 | break; |
101 | default: |
102 | break; |
103 | } |
104 | } |
105 | |
106 | bool QWaylandClipboard::supportsMode(QClipboard::Mode mode) const |
107 | { |
108 | #if QT_CONFIG(wayland_client_primary_selection) |
109 | if (mode == QClipboard::Selection) { |
110 | auto *seat = mDisplay->currentInputDevice(); |
111 | return seat && seat->primarySelectionDevice(); |
112 | } |
113 | #endif |
114 | return mode == QClipboard::Clipboard; |
115 | } |
116 | |
117 | bool QWaylandClipboard::ownsMode(QClipboard::Mode mode) const |
118 | { |
119 | QWaylandInputDevice *seat = mDisplay->currentInputDevice(); |
120 | if (!seat) |
121 | return false; |
122 | |
123 | switch (mode) { |
124 | case QClipboard::Clipboard: |
125 | return seat->dataDevice() && seat->dataDevice()->selectionSource() != nullptr; |
126 | #if QT_CONFIG(wayland_client_primary_selection) |
127 | case QClipboard::Selection: |
128 | return seat->primarySelectionDevice() && seat->primarySelectionDevice()->selectionSource() != nullptr; |
129 | #endif |
130 | default: |
131 | return false; |
132 | } |
133 | } |
134 | |
135 | } |
136 | |
137 | QT_END_NAMESPACE |
138 |