Changeset View
Changeset View
Standalone View
Standalone View
plugins/declarative/kwinnested/kwinnested.cpp
- This file was added.
1 | /******************************************************************** | ||||
---|---|---|---|---|---|
2 | Copyright (C) 2016 Bhavisha Dhruve <bhavishadhruve@gmail.com> | ||||
3 | | ||||
4 | This program is free software; you can redistribute it and/or modify | ||||
5 | it under the terms of the GNU General Public License as published by | ||||
6 | the Free Software Foundation; either version 2 of the License, or | ||||
7 | (at your option) any later version. | ||||
8 | | ||||
9 | This program is distributed in the hope that it will be useful, | ||||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||
12 | GNU General Public License for more details. | ||||
13 | | ||||
14 | You should have received a copy of the GNU General Public License | ||||
15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||||
16 | *********************************************************************/ | ||||
17 | | ||||
18 | #include "config-kwin.h" | ||||
19 | #include "kwinnested.h" | ||||
20 | #include <KWayland/Server/display.h> | ||||
21 | #include <KWayland/Server/seat_interface.h> | ||||
22 | #include <KWayland/Server/compositor_interface.h> | ||||
23 | #include <KWayland/Server/shell_interface.h> | ||||
24 | #include <KWayland/Server/surface_interface.h> | ||||
25 | #include <KWayland/Server/buffer_interface.h> | ||||
26 | | ||||
27 | #include <QCoreApplication> | ||||
28 | #include <QElapsedTimer> | ||||
29 | #include <QTimer> | ||||
30 | #include <QProcess> | ||||
31 | #include <QSGSimpleTextureNode> | ||||
32 | #include <QQuickWindow> | ||||
33 | | ||||
34 | // system | ||||
35 | #include <unistd.h> | ||||
36 | #include <sys/types.h> | ||||
37 | #include <sys/socket.h> | ||||
38 | #include <kwindowsystem.h> | ||||
39 | | ||||
40 | using namespace KWayland::Server; | ||||
41 | | ||||
42 | KWinNested::KWinNested(QQuickItem *parent) | ||||
43 | : QQuickItem(parent) | ||||
44 | , m_timeSinceStart(new QElapsedTimer) | ||||
45 | { | ||||
46 | setFlag(QQuickItem::ItemHasContents, true); | ||||
47 | this->setAcceptedMouseButtons(Qt::AllButtons); | ||||
48 | setFlag(QQuickItem::ItemAcceptsInputMethod, true); | ||||
49 | setFlag(QQuickItem::ItemIsFocusScope, true); | ||||
50 | this->setAcceptHoverEvents(true); | ||||
51 | m_timeSinceStart->start(); | ||||
52 | | ||||
53 | } | ||||
54 | | ||||
55 | KWinNested::~KWinNested() | ||||
56 | { | ||||
57 | if (m_texture) { | ||||
58 | delete(m_texture); | ||||
59 | } | ||||
60 | stop(); | ||||
61 | } | ||||
62 | | ||||
63 | void KWinNested::start() | ||||
64 | { | ||||
65 | Q_ASSERT(!m_display); | ||||
66 | m_display = new Display(this); | ||||
67 | m_display->start(Display::StartMode::ConnectClientsOnly); | ||||
68 | m_display->createShm(); | ||||
69 | m_display->createCompositor()->create(); | ||||
70 | m_seat = m_display->createSeat(m_display); | ||||
71 | m_seat->setHasPointer(true); | ||||
72 | m_seat->setHasKeyboard(true); | ||||
73 | m_seat->setHasTouch(true); | ||||
74 | m_seat->create(); | ||||
75 | m_shell = m_display->createShell(m_display); | ||||
76 | m_shell->create(); | ||||
77 | connect(m_shell, &ShellInterface::surfaceCreated, this, | ||||
78 | [this] (ShellSurfaceInterface *shellSurface) { | ||||
79 | m_surface = shellSurface->surface(); | ||||
80 | m_seat->setFocusedKeyboardSurface(m_surface); | ||||
81 | m_seat->setFocusedPointerSurface(m_surface); | ||||
82 | connect(m_surface, &SurfaceInterface::damaged, this, | ||||
83 | [this] () { | ||||
84 | update(); | ||||
85 | m_surface->frameRendered(m_timeSinceStart->elapsed()); | ||||
86 | } | ||||
87 | ); | ||||
88 | } | ||||
89 | ); | ||||
90 | // output | ||||
91 | auto output = m_display->createOutput(m_display); | ||||
92 | const QSize size(height(), width()); | ||||
93 | output->setGlobalPosition(QPoint(0, 0)); | ||||
94 | output->setPhysicalSize(size / 3.8); | ||||
95 | output->addMode(size); | ||||
96 | output->create(); | ||||
97 | | ||||
98 | int sx[2]; | ||||
99 | if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, sx) < 0) { | ||||
100 | return; | ||||
101 | } | ||||
102 | m_display->createClient(sx[0]); | ||||
103 | int socket = dup(sx[1]); | ||||
104 | if (socket == -1) { | ||||
105 | return; | ||||
106 | } | ||||
107 | m_kwinWaylandProcess = new QProcess(this); | ||||
108 | m_kwinWaylandProcess->setProcessChannelMode(QProcess::ForwardedChannels); | ||||
109 | QProcessEnvironment environment = QProcessEnvironment::systemEnvironment(); | ||||
110 | environment.insert(QStringLiteral("WAYLAND_SOCKET"), QString::fromUtf8(QByteArray::number(socket))); | ||||
111 | environment.insert(QStringLiteral("KWIN_COMPOSE"), QStringLiteral("Q")); | ||||
112 | m_kwinWaylandProcess->setProcessEnvironment(environment); | ||||
113 | m_kwinWaylandProcess->setProcessChannelMode(QProcess::ForwardedChannels); | ||||
114 | QStringList arguments{QStringLiteral("--xwayland"), | ||||
115 | QStringLiteral("--lockscreen"), | ||||
116 | QStringLiteral("--socket"), m_socketName, | ||||
117 | QStringLiteral("--width"), QString::number(width()), | ||||
118 | QStringLiteral("--height"), QString::number(height()), | ||||
119 | QStringLiteral("kate")}; | ||||
120 | m_kwinWaylandProcess->start(QStringLiteral(KWIN_WAYLAND_BINARY_PATH), arguments); | ||||
121 | } | ||||
122 | | ||||
123 | QSGNode *KWinNested::updatePaintNode(QSGNode *node, UpdatePaintNodeData *) | ||||
124 | { | ||||
125 | if (!m_surface) { | ||||
126 | return node; | ||||
127 | } | ||||
128 | if (m_surface->buffer() == nullptr) { | ||||
129 | return node; | ||||
130 | } | ||||
131 | QSGSimpleTextureNode *n = static_cast<QSGSimpleTextureNode *>(node); | ||||
132 | if (!n) { | ||||
133 | n = new QSGSimpleTextureNode(); | ||||
134 | } | ||||
135 | delete(m_texture); | ||||
136 | m_texture = nullptr; | ||||
137 | m_texture = window()->createTextureFromImage(m_surface->buffer()->data()); | ||||
138 | n->setTexture(m_texture); | ||||
139 | n->setRect(boundingRect()); | ||||
140 | return n; | ||||
141 | } | ||||
142 | | ||||
143 | void KWinNested::mousePressEvent(QMouseEvent *event) | ||||
144 | { | ||||
145 | if (m_seat != nullptr) { | ||||
146 | m_seat->setTimestamp(event->timestamp()); | ||||
147 | m_seat->pointerButtonPressed(event->button()); | ||||
148 | } | ||||
149 | } | ||||
150 | | ||||
151 | void KWinNested::mouseReleaseEvent(QMouseEvent *event) | ||||
152 | { | ||||
153 | if (m_seat != nullptr) { | ||||
154 | m_seat->setTimestamp(event->timestamp()); | ||||
155 | m_seat->pointerButtonReleased(event->button()); | ||||
156 | } | ||||
157 | } | ||||
158 | | ||||
159 | void KWinNested::keyPressEvent(QKeyEvent *event) | ||||
160 | { | ||||
161 | if (m_seat != nullptr) { | ||||
162 | m_seat->setTimestamp(event->timestamp()); | ||||
163 | const int magicOffset = KWindowSystem:: isPlatformX11() ? 8 : 0; | ||||
164 | m_seat->keyPressed(event->nativeScanCode() - magicOffset); | ||||
165 | } | ||||
166 | } | ||||
167 | | ||||
168 | void KWinNested::keyReleaseEvent(QKeyEvent *event) | ||||
169 | { | ||||
170 | if (m_seat != nullptr) { | ||||
171 | m_seat->setTimestamp(event->timestamp()); | ||||
172 | const int magicOffset = KWindowSystem:: isPlatformX11() ? 8 : 0; | ||||
173 | m_seat->keyReleased(event->nativeScanCode() - magicOffset); | ||||
174 | } | ||||
175 | } | ||||
176 | | ||||
177 | void KWinNested::hoverMoveEvent(QHoverEvent *event) | ||||
178 | { | ||||
179 | if (m_seat != nullptr) { | ||||
180 | m_seat->setTimestamp(event->timestamp()); | ||||
181 | m_seat->setPointerPos(event->pos()); | ||||
182 | } | ||||
183 | } | ||||
184 | | ||||
185 | void KWinNested::wheelEvent(QWheelEvent *event) | ||||
186 | { | ||||
187 | if (m_seat != nullptr) { | ||||
188 | m_seat->setTimestamp(event->timestamp()); | ||||
189 | const Qt::Orientation orientation = event->angleDelta().x() == 0 ? Qt::Vertical : Qt::Horizontal; | ||||
190 | m_seat->pointerAxis(orientation, orientation == Qt::Horizontal ? event->angleDelta().x() : event->angleDelta().y()); | ||||
191 | } | ||||
192 | } | ||||
193 | | ||||
194 | void KWinNested::stop() | ||||
195 | { | ||||
196 | m_kwinWaylandProcess->terminate(); | ||||
197 | } |