Changeset View
Changeset View
Standalone View
Standalone View
xdgshellclient.cpp
Show First 20 Lines • Show All 83 Lines • ▼ Show 20 Line(s) | 83 | { | |||
---|---|---|---|---|---|
84 | setSurface(surface->surface()); | 84 | setSurface(surface->surface()); | ||
85 | m_requestGeometryBlockCounter++; | 85 | m_requestGeometryBlockCounter++; | ||
86 | init(); | 86 | init(); | ||
87 | connect(surface->surface(), &SurfaceInterface::committed, this, &XdgShellClient::finishInit); | 87 | connect(surface->surface(), &SurfaceInterface::committed, this, &XdgShellClient::finishInit); | ||
88 | } | 88 | } | ||
89 | 89 | | |||
90 | XdgShellClient::~XdgShellClient() = default; | 90 | XdgShellClient::~XdgShellClient() = default; | ||
91 | 91 | | |||
92 | template <class T> | 92 | void XdgShellClient::init() | ||
93 | void XdgShellClient::initSurface(T *shellSurface) | | |||
94 | { | 93 | { | ||
95 | m_caption = shellSurface->title().simplified(); | 94 | connect(this, &XdgShellClient::desktopFileNameChanged, this, &XdgShellClient::updateIcon); | ||
95 | createWindowId(); | ||||
96 | setupCompositing(); | ||||
97 | updateIcon(); | ||||
98 | SurfaceInterface *s = surface(); | ||||
99 | Q_ASSERT(s); | ||||
100 | doSetGeometry(QRect(QPoint(0, 0), m_clientSize)); | ||||
101 | if (waylandServer()->inputMethodConnection() == s->client()) { | ||||
102 | m_windowType = NET::OnScreenDisplay; | ||||
103 | } | ||||
104 | | ||||
105 | connect(s, &SurfaceInterface::sizeChanged, this, | ||||
106 | [this] { | ||||
107 | m_clientSize = surface()->size(); | ||||
108 | doSetGeometry(QRect(pos(), m_clientSize + QSize(borderLeft() + borderRight(), borderTop() + borderBottom()))); | ||||
109 | } | ||||
110 | ); | ||||
111 | connect(s, &SurfaceInterface::unmapped, this, &XdgShellClient::unmap); | ||||
112 | connect(s, &SurfaceInterface::unbound, this, &XdgShellClient::destroyClient); | ||||
113 | connect(s, &SurfaceInterface::destroyed, this, &XdgShellClient::destroyClient); | ||||
114 | if (m_xdgShellSurface) { | ||||
115 | m_caption = m_xdgShellSurface->title().simplified(); | ||||
96 | // delay till end of init | 116 | // delay till end of init | ||
97 | QTimer::singleShot(0, this, &XdgShellClient::updateCaption); | 117 | QTimer::singleShot(0, this, &XdgShellClient::updateCaption); | ||
98 | connect(shellSurface, &T::destroyed, this, &XdgShellClient::destroyClient); | 118 | connect(m_xdgShellSurface, &XdgShellSurfaceInterface::destroyed, this, &XdgShellClient::destroyClient); | ||
99 | connect(shellSurface, &T::titleChanged, this, | 119 | connect(m_xdgShellSurface, &XdgShellSurfaceInterface::titleChanged, this, | ||
100 | [this] (const QString &s) { | 120 | [this] (const QString &caption) { | ||
101 | const auto oldSuffix = m_captionSuffix; | 121 | const auto oldSuffix = m_captionSuffix; | ||
102 | m_caption = s.simplified(); | 122 | m_caption = caption.simplified(); | ||
103 | updateCaption(); | 123 | updateCaption(); | ||
104 | if (m_captionSuffix == oldSuffix) { | 124 | if (m_captionSuffix == oldSuffix) { | ||
105 | // don't emit caption change twice | 125 | // don't emit caption change twice | ||
106 | // it already got emitted by the changing suffix | 126 | // it already got emitted by the changing suffix | ||
107 | emit captionChanged(); | 127 | emit captionChanged(); | ||
108 | } | 128 | } | ||
109 | } | 129 | } | ||
110 | ); | 130 | ); | ||
111 | connect(shellSurface, &T::moveRequested, this, | 131 | | ||
132 | connect(m_xdgShellSurface, &XdgShellSurfaceInterface::moveRequested, this, | ||||
112 | [this] { | 133 | [this] { | ||
113 | // TODO: check the seat and serial | 134 | // TODO: check the seat and serial | ||
114 | performMouseCommand(Options::MouseMove, Cursor::pos()); | 135 | performMouseCommand(Options::MouseMove, Cursor::pos()); | ||
115 | } | 136 | } | ||
116 | ); | 137 | ); | ||
117 | 138 | | |||
118 | // determine the resource name, this is inspired from ICCCM 4.1.2.5 | 139 | connect(m_xdgShellSurface, &XdgShellSurfaceInterface::resizeRequested, this, | ||
119 | // the binary name of the invoked client | | |||
120 | QFileInfo info{shellSurface->client()->executablePath()}; | | |||
121 | QByteArray resourceName; | | |||
122 | if (info.exists()) { | | |||
123 | resourceName = info.fileName().toUtf8(); | | |||
124 | } | | |||
125 | setResourceClass(resourceName, shellSurface->windowClass()); | | |||
126 | setDesktopFileName(shellSurface->windowClass()); | | |||
127 | connect(shellSurface, &T::windowClassChanged, this, | | |||
128 | [this, resourceName] (const QByteArray &windowClass) { | | |||
129 | setResourceClass(resourceName, windowClass); | | |||
130 | if (m_isInitialized && supportsWindowRules()) { | | |||
131 | setupWindowRules(true); | | |||
132 | applyWindowRules(); | | |||
133 | } | | |||
134 | setDesktopFileName(windowClass); | | |||
135 | } | | |||
136 | ); | | |||
137 | connect(shellSurface, &T::resizeRequested, this, | | |||
138 | [this] (SeatInterface *seat, quint32 serial, Qt::Edges edges) { | 140 | [this] (SeatInterface *seat, quint32 serial, Qt::Edges edges) { | ||
139 | // TODO: check the seat and serial | 141 | // TODO: check the seat and serial | ||
140 | Q_UNUSED(seat) | 142 | Q_UNUSED(seat) | ||
141 | Q_UNUSED(serial) | 143 | Q_UNUSED(serial) | ||
142 | if (!isResizable() || isShade()) { | 144 | if (!isResizable() || isShade()) { | ||
143 | return; | 145 | return; | ||
144 | } | 146 | } | ||
145 | if (isMoveResize()) { | 147 | if (isMoveResize()) { | ||
Show All 13 Lines | 154 | auto toPosition = [edges] { | |||
159 | if (edges.testFlag(Qt::LeftEdge)) { | 161 | if (edges.testFlag(Qt::LeftEdge)) { | ||
160 | pos = Position(pos | PositionLeft); | 162 | pos = Position(pos | PositionLeft); | ||
161 | } else if (edges.testFlag(Qt::RightEdge)) { | 163 | } else if (edges.testFlag(Qt::RightEdge)) { | ||
162 | pos = Position(pos | PositionRight); | 164 | pos = Position(pos | PositionRight); | ||
163 | } | 165 | } | ||
164 | return pos; | 166 | return pos; | ||
165 | }; | 167 | }; | ||
166 | setMoveResizePointerMode(toPosition()); | 168 | setMoveResizePointerMode(toPosition()); | ||
167 | if (!startMoveResize()) | 169 | if (!startMoveResize()) { | ||
168 | setMoveResizePointerButtonDown(false); | 170 | setMoveResizePointerButtonDown(false); | ||
171 | } | ||||
169 | updateCursor(); | 172 | updateCursor(); | ||
170 | } | 173 | } | ||
171 | ); | 174 | ); | ||
172 | connect(shellSurface, &T::maximizedChanged, this, | 175 | | ||
176 | // Determine the resource name, this is inspired from ICCCM 4.1.2.5 | ||||
177 | // the binary name of the invoked client. | ||||
178 | QFileInfo info{m_xdgShellSurface->client()->executablePath()}; | ||||
179 | QByteArray resourceName; | ||||
180 | if (info.exists()) { | ||||
181 | resourceName = info.fileName().toUtf8(); | ||||
182 | } | ||||
183 | setResourceClass(resourceName, m_xdgShellSurface->windowClass()); | ||||
184 | setDesktopFileName(m_xdgShellSurface->windowClass()); | ||||
185 | connect(m_xdgShellSurface, &XdgShellSurfaceInterface::windowClassChanged, this, | ||||
186 | [this, resourceName] (const QByteArray &windowClass) { | ||||
187 | setResourceClass(resourceName, windowClass); | ||||
188 | if (m_isInitialized && supportsWindowRules()) { | ||||
189 | setupWindowRules(true); | ||||
190 | applyWindowRules(); | ||||
191 | } | ||||
192 | setDesktopFileName(windowClass); | ||||
193 | } | ||||
194 | ); | ||||
195 | | ||||
196 | connect(m_xdgShellSurface, &XdgShellSurfaceInterface::maximizedChanged, this, | ||||
173 | [this] (bool maximized) { | 197 | [this] (bool maximized) { | ||
174 | // If the maximized state of the client hasn't been changed due to a window | 198 | // If the maximized state of the client hasn't been changed due to a window | ||
175 | // rule or because the requested state is the same as the current, then the | 199 | // rule or because the requested state is the same as the current, then the | ||
176 | // compositor still has to send a configure event. | 200 | // compositor still has to send a configure event. | ||
177 | RequestGeometryBlocker blocker(this); | 201 | RequestGeometryBlocker blocker(this); | ||
178 | 202 | | |||
179 | maximize(maximized ? MaximizeFull : MaximizeRestore); | 203 | maximize(maximized ? MaximizeFull : MaximizeRestore); | ||
180 | } | 204 | } | ||
181 | ); | 205 | ); | ||
182 | // TODO: consider output! | 206 | // TODO: consider output! | ||
183 | connect(shellSurface, &T::fullscreenChanged, this, &XdgShellClient::clientFullScreenChanged); | 207 | connect(m_xdgShellSurface, &XdgShellSurfaceInterface::fullscreenChanged, this, &XdgShellClient::clientFullScreenChanged); | ||
184 | 208 | | |||
185 | connect(shellSurface, &T::transientForChanged, this, &XdgShellClient::setTransient); | 209 | connect(m_xdgShellSurface, &XdgShellSurfaceInterface::transientForChanged, this, &XdgShellClient::setTransient); | ||
186 | 210 | | |||
187 | connect(this, &XdgShellClient::geometryChanged, this, &XdgShellClient::updateClientOutputs); | 211 | connect(this, &XdgShellClient::geometryChanged, this, &XdgShellClient::updateClientOutputs); | ||
188 | connect(screens(), &Screens::changed, this, &XdgShellClient::updateClientOutputs); | 212 | connect(screens(), &Screens::changed, this, &XdgShellClient::updateClientOutputs); | ||
189 | } | | |||
190 | | ||||
191 | void XdgShellClient::init() | | |||
192 | { | | |||
193 | connect(this, &XdgShellClient::desktopFileNameChanged, this, &XdgShellClient::updateIcon); | | |||
194 | createWindowId(); | | |||
195 | setupCompositing(); | | |||
196 | updateIcon(); | | |||
197 | SurfaceInterface *s = surface(); | | |||
198 | Q_ASSERT(s); | | |||
199 | doSetGeometry(QRect(QPoint(0, 0), m_clientSize)); | | |||
200 | if (waylandServer()->inputMethodConnection() == s->client()) { | | |||
201 | m_windowType = NET::OnScreenDisplay; | | |||
202 | } | | |||
203 | | ||||
204 | connect(s, &SurfaceInterface::sizeChanged, this, | | |||
205 | [this] { | | |||
206 | m_clientSize = surface()->size(); | | |||
207 | doSetGeometry(QRect(pos(), m_clientSize + QSize(borderLeft() + borderRight(), borderTop() + borderBottom()))); | | |||
208 | } | | |||
209 | ); | | |||
210 | connect(s, &SurfaceInterface::unmapped, this, &XdgShellClient::unmap); | | |||
211 | connect(s, &SurfaceInterface::unbound, this, &XdgShellClient::destroyClient); | | |||
212 | connect(s, &SurfaceInterface::destroyed, this, &XdgShellClient::destroyClient); | | |||
213 | if (m_xdgShellSurface) { | | |||
214 | initSurface(m_xdgShellSurface); | | |||
215 | 213 | | |||
216 | auto global = static_cast<XdgShellInterface *>(m_xdgShellSurface->global()); | 214 | auto global = static_cast<XdgShellInterface *>(m_xdgShellSurface->global()); | ||
217 | connect(global, &XdgShellInterface::pingDelayed, | 215 | connect(global, &XdgShellInterface::pingDelayed, | ||
218 | this, [this](qint32 serial) { | 216 | this, [this](qint32 serial) { | ||
219 | auto it = m_pingSerials.find(serial); | 217 | auto it = m_pingSerials.find(serial); | ||
220 | if (it != m_pingSerials.end()) { | 218 | if (it != m_pingSerials.end()) { | ||
221 | qCDebug(KWIN_CORE) << "First ping timeout:" << caption(); | 219 | qCDebug(KWIN_CORE) << "First ping timeout:" << caption(); | ||
222 | setUnresponsive(true); | 220 | setUnresponsive(true); | ||
▲ Show 20 Lines • Show All 1704 Lines • Show Last 20 Lines |