KWin
Loading...
Searching...
No Matches
internalwindow.cpp
Go to the documentation of this file.
1/*
2 KWin - the KDE window manager
3 This file is part of the KDE project.
4
5 SPDX-FileCopyrightText: 2019 Martin Flöser <mgraesslin@kde.org>
6 SPDX-FileCopyrightText: 2019 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
7
8 SPDX-License-Identifier: GPL-2.0-or-later
9*/
10#include "internalwindow.h"
12#include "scene/surfaceitem.h"
13#include "scene/windowitem.h"
14#include "workspace.h"
15
16#include <KDecoration2/Decoration>
17
18#include <QMouseEvent>
19#include <QWindow>
20
21Q_DECLARE_METATYPE(NET::WindowType)
22
23static const QByteArray s_skipClosePropertyName = QByteArrayLiteral("KWIN_SKIP_CLOSE_ANIMATION");
24static const QByteArray s_shadowEnabledPropertyName = QByteArrayLiteral("kwin_shadow_enabled");
25
26namespace KWin
27{
28
30 : m_handle(handle)
31 , m_internalWindowFlags(handle->flags())
32{
33 connect(m_handle, &QWindow::xChanged, this, &InternalWindow::updateInternalWindowGeometry);
34 connect(m_handle, &QWindow::yChanged, this, &InternalWindow::updateInternalWindowGeometry);
35 connect(m_handle, &QWindow::widthChanged, this, &InternalWindow::updateInternalWindowGeometry);
36 connect(m_handle, &QWindow::heightChanged, this, &InternalWindow::updateInternalWindowGeometry);
37 connect(m_handle, &QWindow::windowTitleChanged, this, &InternalWindow::setCaption);
38 connect(m_handle, &QWindow::opacityChanged, this, &InternalWindow::setOpacity);
39 connect(m_handle, &QWindow::destroyed, this, &InternalWindow::destroyWindow);
40
41 setCaption(m_handle->title());
42 setIcon(QIcon::fromTheme(QStringLiteral("kwin")));
43 setOnAllDesktops(true);
44 setOpacity(m_handle->opacity());
45 setSkipCloseAnimation(m_handle->property(s_skipClosePropertyName).toBool());
48
49 setMoveResizeGeometry(m_handle->geometry());
50 commitGeometry(m_handle->geometry());
51
52 updateDecoration(true);
53
54 m_handle->installEventFilter(this);
55}
56
60
61std::unique_ptr<WindowItem> InternalWindow::createItem(Scene *scene)
62{
63 return std::make_unique<WindowItemInternal>(this, scene);
64}
65
67{
68 return true;
69}
70
71bool InternalWindow::hitTest(const QPointF &point) const
72{
73 if (!Window::hitTest(point)) {
74 return false;
75 }
76
77 const QRegion mask = m_handle->mask();
78 if (!mask.isEmpty() && !mask.contains(mapToLocal(point).toPoint())) {
79 return false;
80 } else if (m_handle->property("outputOnly").toBool()) {
81 return false;
82 }
83
84 return true;
85}
86
87void InternalWindow::pointerEnterEvent(const QPointF &globalPos)
88{
90
91 QEnterEvent enterEvent(pos(), pos(), globalPos);
92 QCoreApplication::sendEvent(m_handle, &enterEvent);
93}
94
96{
97 if (!m_handle) {
98 return;
99 }
101
102 QEvent event(QEvent::Leave);
103 QCoreApplication::sendEvent(m_handle, &event);
104}
105
106bool InternalWindow::eventFilter(QObject *watched, QEvent *event)
107{
108 if (watched == m_handle && event->type() == QEvent::DynamicPropertyChange) {
109 QDynamicPropertyChangeEvent *pe = static_cast<QDynamicPropertyChangeEvent *>(event);
110 if (pe->propertyName() == s_skipClosePropertyName) {
111 setSkipCloseAnimation(m_handle->property(s_skipClosePropertyName).toBool());
112 }
113 if (pe->propertyName() == s_shadowEnabledPropertyName) {
114 updateShadow();
115 }
116 }
117 return false;
118}
119
121{
122 if (m_handle) {
123 return m_handle->devicePixelRatio();
124 }
125 return 1;
126}
127
129{
130 return m_captionNormal;
131}
132
134{
135 return m_captionSuffix;
136}
137
139{
140 return m_handle->minimumSize();
141}
142
144{
145 return m_handle->maximumSize();
146}
147
148NET::WindowType InternalWindow::windowType() const
149{
150 return NET::Normal;
151}
152
154{
155 // We don't kill our internal windows.
156}
157
159{
160 if (Window::isPopupWindow()) {
161 return true;
162 }
163 return m_internalWindowFlags.testFlag(Qt::Popup);
164}
165
167{
168 return QString();
169}
170
172{
173 if (m_handle) {
174 m_handle->hide();
175 }
176}
177
179{
180 return true;
181}
182
184{
185 return !m_internalWindowFlags.testFlag(Qt::BypassWindowManagerHint) && !m_internalWindowFlags.testFlag(Qt::Popup);
186}
187
189{
190 return !m_internalWindowFlags.testFlag(Qt::BypassWindowManagerHint) && !m_internalWindowFlags.testFlag(Qt::Popup);
191}
192
194{
195 return true;
196}
197
199{
200 return !m_internalWindowFlags.testFlag(Qt::BypassWindowManagerHint) && !m_internalWindowFlags.testFlag(Qt::Popup);
201}
202
204{
205 return m_userNoBorder || m_internalWindowFlags.testFlag(Qt::FramelessWindowHint) || m_internalWindowFlags.testFlag(Qt::Popup);
206}
207
209{
210 return !m_internalWindowFlags.testFlag(Qt::FramelessWindowHint) || m_internalWindowFlags.testFlag(Qt::Popup);
211}
212
214{
215 return false;
216}
217
219{
220 return true;
221}
222
224{
225 if (m_handle) {
226 return m_handle->property("org_kde_ksld_emergency").toBool();
227 }
228 return false;
229}
230
232{
233 if (m_handle) {
234 return m_handle->property("__kwin_outline").toBool();
235 }
236 return false;
237}
238
239QRectF InternalWindow::resizeWithChecks(const QRectF &geometry, const QSizeF &size)
240{
241 if (!m_handle) {
242 return geometry;
243 }
244 const QRectF area = workspace()->clientArea(WorkArea, this, geometry.center());
245 return QRectF(moveResizeGeometry().topLeft(), size.boundedTo(area.size()));
246}
247
249{
252 return;
253 }
254
255 const QSizeF requestedClientSize = frameSizeToClientSize(rect.size());
256 if (clientSize() == requestedClientSize) {
257 commitGeometry(rect);
258 } else {
259 requestGeometry(rect);
260 }
261}
262
264{
265 return nullptr;
266}
267
269{
270 return false;
271}
272
274{
275 if (!userCanSetNoBorder()) {
276 return;
277 }
278 if (m_userNoBorder == set) {
279 return;
280 }
281 m_userNoBorder = set;
282 updateDecoration(true);
283}
284
285void InternalWindow::createDecoration(const QRectF &oldGeometry)
286{
287 setDecoration(std::shared_ptr<KDecoration2::Decoration>(Workspace::self()->decorationBridge()->createDecoration(this)));
288 moveResize(QRectF(oldGeometry.topLeft(), clientSizeToFrameSize(clientSize())));
289}
290
291void InternalWindow::destroyDecoration()
292{
294 setDecoration(nullptr);
296}
297
298void InternalWindow::updateDecoration(bool check_workspace_pos, bool force)
299{
300 if (!force && isDecorated() == !noBorder()) {
301 return;
302 }
303
304 GeometryUpdatesBlocker blocker(this);
305
306 const QRectF oldFrameGeometry = frameGeometry();
307 if (force) {
308 destroyDecoration();
309 }
310
311 if (!noBorder()) {
312 createDecoration(oldFrameGeometry);
313 } else {
314 destroyDecoration();
315 }
316
317 updateShadow();
318
319 if (check_workspace_pos) {
320 checkWorkspacePosition(oldFrameGeometry);
321 }
322}
323
325{
326 updateDecoration(true, true);
327}
328
330{
331 m_handle->removeEventFilter(this);
332 m_handle->disconnect(this);
333
338 }
339
340 Q_EMIT closed();
341
343 m_handle = nullptr;
344
345 unref();
346}
347
349{
350 return !m_handle->flags().testFlag(Qt::WindowTransparentForInput) && m_handle->flags().testFlag(Qt::Popup) && !m_handle->flags().testFlag(Qt::ToolTip);
351}
352
354{
355 m_handle->close();
356}
357
359{
360 return m_graphicsBufferRef.buffer();
361}
362
364{
365 return m_graphicsBufferOrigin;
366}
367
369{
370 const QSize bufferSize = frame.buffer->size() / bufferScale();
371 QRectF geometry(pos(), clientSizeToFrameSize(bufferSize));
372 if (isInteractiveResize()) {
374 }
375
376 commitGeometry(geometry);
377 markAsMapped();
378
379 m_graphicsBufferRef = frame.buffer;
380 m_graphicsBufferOrigin = frame.bufferOrigin;
381
383}
384
386{
387 return m_handle;
388}
389
391{
392 return false;
393}
394
395bool InternalWindow::belongsToSameApplication(const Window *other, SameApplicationChecks checks) const
396{
397 const InternalWindow *otherInternal = qobject_cast<const InternalWindow *>(other);
398 if (!otherInternal) {
399 return false;
400 }
401 if (otherInternal == this) {
402 return true;
403 }
404 return otherInternal->handle()->isAncestorOf(handle()) || handle()->isAncestorOf(otherInternal->handle());
405}
406
408{
410}
411
413{
414 const QString suffix = shortcutCaptionSuffix();
415 if (m_captionSuffix != suffix) {
416 m_captionSuffix = suffix;
417 Q_EMIT captionChanged();
418 }
419}
420
421void InternalWindow::requestGeometry(const QRectF &rect)
422{
423 if (m_handle) {
424 m_handle->setGeometry(frameRectToClientRect(rect).toRect());
425 }
426}
427
428void InternalWindow::commitGeometry(const QRectF &rect)
429{
430 // The client geometry and the buffer geometry are the same.
431 const QRectF oldClientGeometry = m_clientGeometry;
432 const QRectF oldFrameGeometry = m_frameGeometry;
433 const Output *oldOutput = m_output;
434
436
440
441 if (oldClientGeometry == m_clientGeometry && oldFrameGeometry == m_frameGeometry) {
442 return;
443 }
444
445 m_output = workspace()->outputAt(rect.center());
446 syncGeometryToInternalWindow();
447
448 if (oldClientGeometry != m_clientGeometry) {
449 Q_EMIT bufferGeometryChanged(oldClientGeometry);
450 Q_EMIT clientGeometryChanged(oldClientGeometry);
451 }
452 if (oldFrameGeometry != m_frameGeometry) {
453 Q_EMIT frameGeometryChanged(oldFrameGeometry);
454 }
455 if (oldOutput != m_output) {
456 Q_EMIT outputChanged();
457 }
458}
459
460void InternalWindow::setCaption(const QString &caption)
461{
462 if (m_captionNormal == caption) {
463 return;
464 }
465
466 m_captionNormal = caption;
467 Q_EMIT captionNormalChanged();
468 Q_EMIT captionChanged();
469}
470
471void InternalWindow::markAsMapped()
472{
473 if (!ready_for_painting) {
477 }
478}
479
480void InternalWindow::syncGeometryToInternalWindow()
481{
482 if (m_handle->geometry() == frameRectToClientRect(frameGeometry())) {
483 return;
484 }
485
486 QTimer::singleShot(0, this, [this] {
487 requestGeometry(frameGeometry());
488 });
489}
490
491void InternalWindow::updateInternalWindowGeometry()
492{
494 const QRectF rect = clientRectToFrameRect(m_handle->geometry());
496 commitGeometry(rect);
497 }
498}
499
500}
501
502#include "moc_internalwindow.cpp"
virtual QSize size() const =0
GraphicsBuffer * buffer() const
bool isLockScreen() const override
bool isResizable() const override
void doInteractiveResizeSync(const QRectF &rect) override
void killWindow() override
QWindow * handle() const
void pointerLeaveEvent() override
void popupDone() override
void invalidateDecoration() override
bool eventFilter(QObject *watched, QEvent *event) override
bool isPlaceable() const override
void destroyWindow() override
bool isClient() const override
bool isMovableAcrossScreens() const override
bool hasPopupGrab() const override
bool isCloseable() const override
void updateCaption() override
void setNoBorder(bool set) override
bool isOutline() const override
bool belongsToSameApplication(const Window *other, SameApplicationChecks checks) const override
void moveResizeInternal(const QRectF &rect, MoveResizeMode mode) override
bool takeFocus() override
bool acceptsFocus() const override
NET::WindowType windowType() const override
QRectF resizeWithChecks(const QRectF &geometry, const QSizeF &size) override
QString windowRole() const override
InternalWindow(QWindow *handle)
bool isMovable() const override
QSizeF minSize() const override
bool noBorder() const override
GraphicsBufferOrigin graphicsBufferOrigin() const
Window * findModal(bool allow_itself=false) override
GraphicsBuffer * graphicsBuffer() const
void pointerEnterEvent(const QPointF &globalPos) override
QSizeF maxSize() const override
bool userCanSetNoBorder() const override
QString captionSuffix() const override
bool wantsInput() const override
bool isInternal() const override
void present(const InternalWindowFrame &frame)
QString captionNormal() const override
bool isPopupWindow() const override
std::unique_ptr< WindowItem > createItem(Scene *scene) override
bool hitTest(const QPointF &point) const override
void closeWindow() override
void addDamage(const QRegion &region)
void setOpacity(qreal opacity)
Definition window.cpp:196
virtual QSizeF clientSizeToFrameSize(const QSizeF &size) const
Definition window.cpp:3265
QPointF pos
Definition window.h:79
QRectF frameGeometry
Definition window.h:431
void frameGeometryAboutToChange()
QRectF m_bufferGeometry
Definition window.h:1727
QPointF mapToLocal(const QPointF &point) const
Definition window.cpp:399
QString shortcutCaptionSuffix() const
Definition window.cpp:3069
void moveResize(const QRectF &rect)
Definition window.cpp:3323
friend class GeometryUpdatesBlocker
Definition window.h:1792
void setDecoration(std::shared_ptr< KDecoration2::Decoration > decoration)
Definition window.cpp:2625
QSizeF size
Definition window.h:84
bool resize
Definition window.h:443
bool isInteractiveMoveResize() const
Definition window.h:1570
SurfaceItem * surfaceItem() const
Definition window.cpp:289
void unref()
Definition window.cpp:118
virtual void pointerEnterEvent(const QPointF &globalPos)
Definition window.cpp:2821
QRectF m_frameGeometry
Definition window.h:1725
virtual bool isPopupWindow() const
Definition window.h:2074
QRectF frameRectToClientRect(const QRectF &rect) const
Definition window.cpp:3272
void setOnAllDesktops(bool set)
Definition window.cpp:813
void clientGeometryChanged(const QRectF &oldGeometry)
QSizeF clientSize() const
Definition window.h:1872
bool isInteractiveResize() const
Definition window.h:1114
void interactiveMoveResizeFinished()
virtual void pointerLeaveEvent()
Definition window.cpp:2847
void outputChanged()
QRectF clientRectToFrameRect(const QRectF &rect) const
Definition window.cpp:3279
bool isDecorated() const
Definition window.h:1162
Output * m_output
Definition window.h:1724
virtual bool setupCompositing()
Definition window.cpp:207
void updateColorScheme()
Definition window.cpp:1053
virtual void leaveInteractiveMoveResize()
Definition window.cpp:2423
QString caption
Definition window.h:392
QRectF moveResizeGeometry() const
Definition window.cpp:3286
bool ready_for_painting
Definition window.h:1728
QRectF rect
Definition window.h:113
void bufferGeometryChanged(const QRectF &oldGeometry)
void setMoveResizeGeometry(const QRectF &geo)
Definition window.cpp:3291
void setReadyForPainting()
Definition window.cpp:228
void checkWorkspacePosition(QRectF oldGeometry=QRectF(), const VirtualDesktop *oldDesktop=nullptr)
Definition window.cpp:3661
void frameGeometryChanged(const QRectF &oldGeometry)
void updateShadow()
Definition window.cpp:264
void captionNormalChanged()
void setIcon(const QIcon &icon)
Definition window.cpp:493
virtual bool hitTest(const QPointF &point) const
Definition window.cpp:381
void setSkipCloseAnimation(bool set)
Definition window.cpp:333
bool areGeometryUpdatesBlocked() const
Definition window.h:2093
QRectF m_clientGeometry
Definition window.h:1726
void setPendingMoveResizeMode(MoveResizeMode mode)
Definition window.h:2113
virtual QSizeF frameSizeToClientSize(const QSizeF &size) const
Definition window.cpp:3258
Gravity interactiveMoveResizeGravity() const
Definition window.h:1616
void captionChanged()
void markAsDeleted()
Definition window.cpp:545
QRectF clientArea(clientAreaOption, const Output *output, const VirtualDesktop *desktop) const
void addInternalWindow(InternalWindow *window)
static Workspace * self()
Definition workspace.h:91
void removeInternalWindow(InternalWindow *window)
Output * outputAt(const QPointF &pos) const
Q_DECLARE_METATYPE(KWin::SwitchEvent::State)
GraphicsBufferOrigin
@ WorkArea
Definition globals.h:55
Workspace * workspace()
Definition workspace.h:830
QRectF gravitateGeometry(const QRectF &rect, const QRectF &bounds, Gravity gravity)
Definition common.cpp:246
GraphicsBufferOrigin bufferOrigin