KWin
Loading...
Searching...
No Matches
onscreennotification.cpp
Go to the documentation of this file.
1/*
2 SPDX-FileCopyrightText: 2016 Martin Graesslin <mgraesslin@kde.org>
3
4 SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
5
6*/
8
9#include <config-kwin.h>
10
11#include "input.h"
12#include "input_event.h"
13#include "input_event_spy.h"
14
15#include <QPropertyAnimation>
16#include <QQmlComponent>
17#include <QQmlContext>
18#include <QQmlEngine>
19#include <QQuickWindow>
20#include <QStandardPaths>
21#include <QTimer>
22
23#include <KConfigGroup>
24
25#include <functional>
26
27namespace KWin
28{
29
31{
32public:
34
35 void pointerEvent(MouseEvent *event) override;
36
37private:
38 OnScreenNotification *m_parent;
39};
40
45
47{
48 if (event->type() != QEvent::MouseMove) {
49 return;
50 }
51
52 m_parent->setContainsPointer(m_parent->geometry().contains(event->globalPos()));
53}
54
56 : QObject(parent)
57 , m_timer(new QTimer(this))
58{
59 m_timer->setSingleShot(true);
60 connect(m_timer, &QTimer::timeout, this, std::bind(&OnScreenNotification::setVisible, this, false));
61 connect(this, &OnScreenNotification::visibleChanged, this, [this]() {
62 if (m_visible) {
63 show();
64 } else {
65 m_timer->stop();
66 m_spy.reset();
67 m_containsPointer = false;
68 }
69 });
70}
71
73{
74 if (QQuickWindow *w = qobject_cast<QQuickWindow *>(m_mainItem.get())) {
75 w->hide();
76 w->destroy();
77 }
78}
79
80void OnScreenNotification::setConfig(KSharedConfigPtr config)
81{
82 m_config = config;
83}
84
85void OnScreenNotification::setEngine(QQmlEngine *engine)
86{
87 m_qmlEngine = engine;
88}
89
91{
92 return m_visible;
93}
94
96{
97 if (m_visible == visible) {
98 return;
99 }
100 m_visible = visible;
101 Q_EMIT visibleChanged();
102}
103
105{
106 return m_message;
107}
108
109void OnScreenNotification::setMessage(const QString &message)
110{
111 if (m_message == message) {
112 return;
113 }
114 m_message = message;
115 Q_EMIT messageChanged();
116}
117
119{
120 return m_iconName;
121}
122
123void OnScreenNotification::setIconName(const QString &iconName)
124{
125 if (m_iconName == iconName) {
126 return;
127 }
128 m_iconName = iconName;
129 Q_EMIT iconNameChanged();
130}
131
133{
134 return m_timer->interval();
135}
136
138{
139 if (m_timer->interval() == timeout) {
140 return;
141 }
142 m_timer->setInterval(timeout);
143 Q_EMIT timeoutChanged();
144}
145
146void OnScreenNotification::show()
147{
148 Q_ASSERT(m_visible);
149 ensureQmlContext();
150 ensureQmlComponent();
151 createInputSpy();
152 if (m_timer->interval() != 0) {
153 m_timer->start();
154 }
155}
156
157void OnScreenNotification::ensureQmlContext()
158{
159 Q_ASSERT(m_qmlEngine);
160 if (m_qmlContext) {
161 return;
162 }
163 m_qmlContext = std::make_unique<QQmlContext>(m_qmlEngine);
164 m_qmlContext->setContextProperty(QStringLiteral("osd"), this);
165}
166
167void OnScreenNotification::ensureQmlComponent()
168{
169 Q_ASSERT(m_config);
170 Q_ASSERT(m_qmlEngine);
171 if (m_qmlComponent) {
172 return;
173 }
174 m_qmlComponent = std::make_unique<QQmlComponent>(m_qmlEngine);
175 const QString fileName = QStandardPaths::locate(QStandardPaths::GenericDataLocation,
176 m_config->group(QStringLiteral("OnScreenNotification")).readEntry("QmlPath", QStringLiteral("kwin/onscreennotification/plasma/main.qml")));
177 if (fileName.isEmpty()) {
178 return;
179 }
180 m_qmlComponent->loadUrl(QUrl::fromLocalFile(fileName));
181 if (!m_qmlComponent->isError()) {
182 m_mainItem.reset(m_qmlComponent->create(m_qmlContext.get()));
183 } else {
184 m_qmlComponent.reset();
185 }
186}
187
188void OnScreenNotification::createInputSpy()
189{
190 Q_ASSERT(!m_spy);
191 if (auto w = qobject_cast<QQuickWindow *>(m_mainItem.get())) {
192 m_spy = std::make_unique<OnScreenNotificationInputEventSpy>(this);
193 input()->installInputEventSpy(m_spy.get());
194 if (!m_animation) {
195 m_animation = new QPropertyAnimation(w, "opacity", this);
196 m_animation->setStartValue(1.0);
197 m_animation->setEndValue(0.0);
198 m_animation->setDuration(250);
199 m_animation->setEasingCurve(QEasingCurve::InOutCubic);
200 }
201 }
202}
203
205{
206 if (QQuickWindow *w = qobject_cast<QQuickWindow *>(m_mainItem.get())) {
207 return w->geometry();
208 }
209 return QRect();
210}
211
213{
214 if (m_containsPointer == contains) {
215 return;
216 }
217 m_containsPointer = contains;
218 if (!m_animation) {
219 return;
220 }
221 m_animation->setDirection(m_containsPointer ? QAbstractAnimation::Forward : QAbstractAnimation::Backward);
222 m_animation->start();
223}
224
226{
227 if (QQuickWindow *w = qobject_cast<QQuickWindow *>(m_mainItem.get())) {
228 w->setProperty("KWIN_SKIP_CLOSE_ANIMATION", skip);
229 }
230}
231
232} // namespace KWin
233
234#include "moc_onscreennotification.cpp"
void installInputEventSpy(InputEventSpy *spy)
void setConfig(KSharedConfigPtr config)
void setEngine(QQmlEngine *engine)
void setIconName(const QString &iconName)
OnScreenNotification(QObject *parent=nullptr)
void setMessage(const QString &message)
OnScreenNotificationInputEventSpy(OnScreenNotification *parent)
void pointerEvent(MouseEvent *event) override
InputRedirection * input()
Definition input.h:549