1 /*
2 SPDX-FileCopyrightText: 2014 Martin Gräßlin <mgraesslin@kde.org>
3
4 SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
5 */
6 #include "previewclient.h"
7 #include <KDecoration2/Decoration>
8 #include <KDecoration2/DecoratedClient>
9
10 #include <QDebug>
11 #include <QCoreApplication>
12 #include <QEvent>
13 #include <QModelIndex>
14
15 namespace KDecoration2
16 {
17 namespace Preview
18 {
19
PreviewClient(DecoratedClient * c,Decoration * decoration)20 PreviewClient::PreviewClient(DecoratedClient *c, Decoration *decoration)
21 : QObject(decoration)
22 , ApplicationMenuEnabledDecoratedClientPrivate(c, decoration)
23 , m_icon(QIcon::fromTheme(QStringLiteral("start-here-kde")))
24 , m_iconName(m_icon.name())
25 , m_palette(QStringLiteral("kdeglobals"))
26 , m_active(true)
27 , m_closeable(true)
28 , m_keepBelow(false)
29 , m_keepAbove(false)
30 , m_maximizable(true)
31 , m_maximizedHorizontally(false)
32 , m_maximizedVertically(false)
33 , m_minimizable(true)
34 , m_modal(false)
35 , m_movable(true)
36 , m_resizable(true)
37 , m_shadeable(true)
38 , m_shaded(false)
39 , m_providesContextHelp(false)
40 , m_desktop(1)
41 , m_width(0)
42 , m_height(0)
43 , m_bordersTopEdge(false)
44 , m_bordersLeftEdge(false)
45 , m_bordersRightEdge(false)
46 , m_bordersBottomEdge(false)
47 {
48 connect(this, &PreviewClient::captionChanged, c, &DecoratedClient::captionChanged);
49 connect(this, &PreviewClient::activeChanged, c, &DecoratedClient::activeChanged);
50 connect(this, &PreviewClient::closeableChanged, c, &DecoratedClient::closeableChanged);
51 connect(this, &PreviewClient::keepAboveChanged, c, &DecoratedClient::keepAboveChanged);
52 connect(this, &PreviewClient::keepBelowChanged, c, &DecoratedClient::keepBelowChanged);
53 connect(this, &PreviewClient::maximizableChanged, c, &DecoratedClient::maximizeableChanged);
54 connect(this, &PreviewClient::maximizedChanged, c, &DecoratedClient::maximizedChanged);
55 connect(this, &PreviewClient::maximizedVerticallyChanged, c, &DecoratedClient::maximizedVerticallyChanged);
56 connect(this, &PreviewClient::maximizedHorizontallyChanged, c, &DecoratedClient::maximizedHorizontallyChanged);
57 connect(this, &PreviewClient::minimizableChanged, c, &DecoratedClient::minimizeableChanged);
58 connect(this, &PreviewClient::movableChanged, c, &DecoratedClient::moveableChanged);
59 connect(this, &PreviewClient::onAllDesktopsChanged, c, &DecoratedClient::onAllDesktopsChanged);
60 connect(this, &PreviewClient::resizableChanged, c, &DecoratedClient::resizeableChanged);
61 connect(this, &PreviewClient::shadeableChanged, c, &DecoratedClient::shadeableChanged);
62 connect(this, &PreviewClient::shadedChanged, c, &DecoratedClient::shadedChanged);
63 connect(this, &PreviewClient::providesContextHelpChanged, c, &DecoratedClient::providesContextHelpChanged);
64 connect(this, &PreviewClient::onAllDesktopsChanged, c, &DecoratedClient::onAllDesktopsChanged);
65 connect(this, &PreviewClient::widthChanged, c, &DecoratedClient::widthChanged);
66 connect(this, &PreviewClient::heightChanged, c, &DecoratedClient::heightChanged);
67 connect(this, &PreviewClient::iconChanged, c, &DecoratedClient::iconChanged);
68 connect(this, &PreviewClient::paletteChanged, c, &DecoratedClient::paletteChanged);
69 connect(this, &PreviewClient::maximizedVerticallyChanged, this,
70 [this]() {
71 Q_EMIT maximizedChanged(isMaximized());
72 }
73 );
74 connect(this, &PreviewClient::maximizedHorizontallyChanged, this,
75 [this]() {
76 Q_EMIT maximizedChanged(isMaximized());
77 }
78 );
79 connect(this, &PreviewClient::iconNameChanged, this,
80 [this]() {
81 m_icon = QIcon::fromTheme(m_iconName);
82 Q_EMIT iconChanged(m_icon);
83 }
84 );
85 connect(this, &PreviewClient::desktopChanged, this,
86 [this]() {
87 Q_EMIT onAllDesktopsChanged(isOnAllDesktops());
88 }
89 );
90 connect(&m_palette, &KWin::Decoration::DecorationPalette::changed, this, [this]() {
91 Q_EMIT paletteChanged(m_palette.palette());
92 });
93 auto emitEdgesChanged = [this, c]() {
94 Q_EMIT c->adjacentScreenEdgesChanged(adjacentScreenEdges());
95 };
96 connect(this, &PreviewClient::bordersTopEdgeChanged, this, emitEdgesChanged);
97 connect(this, &PreviewClient::bordersLeftEdgeChanged, this, emitEdgesChanged);
98 connect(this, &PreviewClient::bordersRightEdgeChanged, this, emitEdgesChanged);
99 connect(this, &PreviewClient::bordersBottomEdgeChanged, this, emitEdgesChanged);
100 auto emitSizeChanged = [c]() {
101 Q_EMIT c->sizeChanged(c->size());
102 };
103 connect(this, &PreviewClient::widthChanged, this, emitSizeChanged);
104 connect(this, &PreviewClient::heightChanged, this, emitSizeChanged);
105
106 qApp->installEventFilter(this);
107 }
108
109 PreviewClient::~PreviewClient() = default;
110
setIcon(const QIcon & pixmap)111 void PreviewClient::setIcon(const QIcon &pixmap)
112 {
113 m_icon = pixmap;
114 Q_EMIT iconChanged(m_icon);
115 }
116
width() const117 int PreviewClient::width() const
118 {
119 return m_width;
120 }
121
height() const122 int PreviewClient::height() const
123 {
124 return m_height;
125 }
126
size() const127 QSize PreviewClient::size() const
128 {
129 return QSize(m_width, m_height);
130 }
131
caption() const132 QString PreviewClient::caption() const
133 {
134 return m_caption;
135 }
136
decorationId() const137 WId PreviewClient::decorationId() const
138 {
139 return 0;
140 }
141
desktop() const142 int PreviewClient::desktop() const
143 {
144 return m_desktop;
145 }
146
setDesktop(int desktop)147 void PreviewClient::setDesktop(int desktop)
148 {
149 if (desktop == 0) {
150 desktop = 1;
151 }
152 if (m_desktop == desktop) {
153 return;
154 }
155 m_desktop = desktop;
156 Q_EMIT desktopChanged(m_desktop);
157 }
158
icon() const159 QIcon PreviewClient::icon() const
160 {
161 return m_icon;
162 }
163
iconName() const164 QString PreviewClient::iconName() const
165 {
166 return m_iconName;
167 }
168
isActive() const169 bool PreviewClient::isActive() const
170 {
171 return m_active;
172 }
173
isCloseable() const174 bool PreviewClient::isCloseable() const
175 {
176 return m_closeable;
177 }
178
isKeepAbove() const179 bool PreviewClient::isKeepAbove() const
180 {
181 return m_keepAbove;
182 }
183
isKeepBelow() const184 bool PreviewClient::isKeepBelow() const
185 {
186 return m_keepBelow;
187 }
188
isMaximizeable() const189 bool PreviewClient::isMaximizeable() const
190 {
191 return m_maximizable;
192 }
193
isMaximized() const194 bool PreviewClient::isMaximized() const
195 {
196 return isMaximizedHorizontally() && isMaximizedVertically();
197 }
198
isMaximizedHorizontally() const199 bool PreviewClient::isMaximizedHorizontally() const
200 {
201 return m_maximizedHorizontally;
202 }
203
isMaximizedVertically() const204 bool PreviewClient::isMaximizedVertically() const
205 {
206 return m_maximizedVertically;
207 }
208
isMinimizeable() const209 bool PreviewClient::isMinimizeable() const
210 {
211 return m_minimizable;
212 }
213
isModal() const214 bool PreviewClient::isModal() const
215 {
216 return m_modal;
217 }
218
isMoveable() const219 bool PreviewClient::isMoveable() const
220 {
221 return m_movable;
222 }
223
isOnAllDesktops() const224 bool PreviewClient::isOnAllDesktops() const
225 {
226 return desktop() == -1;
227 }
228
isResizeable() const229 bool PreviewClient::isResizeable() const
230 {
231 return m_resizable;
232 }
233
isShadeable() const234 bool PreviewClient::isShadeable() const
235 {
236 return m_shadeable;
237 }
238
isShaded() const239 bool PreviewClient::isShaded() const
240 {
241 return m_shaded;
242 }
243
providesContextHelp() const244 bool PreviewClient::providesContextHelp() const
245 {
246 return m_providesContextHelp;
247 }
248
windowId() const249 WId PreviewClient::windowId() const
250 {
251 return 0;
252 }
253
palette() const254 QPalette PreviewClient::palette() const
255 {
256 return m_palette.palette();
257 }
258
color(ColorGroup group,ColorRole role) const259 QColor PreviewClient::color(ColorGroup group, ColorRole role) const
260 {
261 return m_palette.color(group, role);
262 }
263
adjacentScreenEdges() const264 Qt::Edges PreviewClient::adjacentScreenEdges() const
265 {
266 Qt::Edges edges;
267 if (m_bordersBottomEdge) {
268 edges |= Qt::BottomEdge;
269 }
270 if (m_bordersLeftEdge) {
271 edges |= Qt::LeftEdge;
272 }
273 if (m_bordersRightEdge) {
274 edges |= Qt::RightEdge;
275 }
276 if (m_bordersTopEdge) {
277 edges |= Qt::TopEdge;
278 }
279 return edges;
280 }
281
hasApplicationMenu() const282 bool PreviewClient::hasApplicationMenu() const
283 {
284 return true;
285 }
286
isApplicationMenuActive() const287 bool PreviewClient::isApplicationMenuActive() const
288 {
289 return false;
290 }
291
bordersBottomEdge() const292 bool PreviewClient::bordersBottomEdge() const
293 {
294 return m_bordersBottomEdge;
295 }
296
bordersLeftEdge() const297 bool PreviewClient::bordersLeftEdge() const
298 {
299 return m_bordersLeftEdge;
300 }
301
bordersRightEdge() const302 bool PreviewClient::bordersRightEdge() const
303 {
304 return m_bordersRightEdge;
305 }
306
bordersTopEdge() const307 bool PreviewClient::bordersTopEdge() const
308 {
309 return m_bordersTopEdge;
310 }
311
setBordersBottomEdge(bool enabled)312 void PreviewClient::setBordersBottomEdge(bool enabled)
313 {
314 if (m_bordersBottomEdge == enabled) {
315 return;
316 }
317 m_bordersBottomEdge = enabled;
318 Q_EMIT bordersBottomEdgeChanged(enabled);
319 }
320
setBordersLeftEdge(bool enabled)321 void PreviewClient::setBordersLeftEdge(bool enabled)
322 {
323 if (m_bordersLeftEdge == enabled) {
324 return;
325 }
326 m_bordersLeftEdge = enabled;
327 Q_EMIT bordersLeftEdgeChanged(enabled);
328 }
329
setBordersRightEdge(bool enabled)330 void PreviewClient::setBordersRightEdge(bool enabled)
331 {
332 if (m_bordersRightEdge == enabled) {
333 return;
334 }
335 m_bordersRightEdge = enabled;
336 Q_EMIT bordersRightEdgeChanged(enabled);
337 }
338
setBordersTopEdge(bool enabled)339 void PreviewClient::setBordersTopEdge(bool enabled)
340 {
341 if (m_bordersTopEdge == enabled) {
342 return;
343 }
344 m_bordersTopEdge = enabled;
345 Q_EMIT bordersTopEdgeChanged(enabled);
346 }
347
requestShowToolTip(const QString & text)348 void PreviewClient::requestShowToolTip(const QString &text)
349 {
350 Q_UNUSED(text);
351 }
352
requestHideToolTip()353 void PreviewClient::requestHideToolTip()
354 {
355 }
356
requestClose()357 void PreviewClient::requestClose()
358 {
359 Q_EMIT closeRequested();
360 }
361
requestContextHelp()362 void PreviewClient::requestContextHelp()
363 {
364 }
365
requestToggleMaximization(Qt::MouseButtons buttons)366 void PreviewClient::requestToggleMaximization(Qt::MouseButtons buttons)
367 {
368 if (buttons.testFlag(Qt::LeftButton)) {
369 const bool set = !isMaximized();
370 setMaximizedHorizontally(set);
371 setMaximizedVertically(set);
372 } else if (buttons.testFlag(Qt::RightButton)) {
373 setMaximizedHorizontally(!isMaximizedHorizontally());
374 } else if (buttons.testFlag(Qt::MiddleButton)) {
375 setMaximizedVertically(!isMaximizedVertically());
376 }
377 }
378
requestMinimize()379 void PreviewClient::requestMinimize()
380 {
381 Q_EMIT minimizeRequested();
382 }
383
requestToggleKeepAbove()384 void PreviewClient::requestToggleKeepAbove()
385 {
386 setKeepAbove(!isKeepAbove());
387 }
388
requestToggleKeepBelow()389 void PreviewClient::requestToggleKeepBelow()
390 {
391 setKeepBelow(!isKeepBelow());
392 }
393
requestShowWindowMenu(const QRect & rect)394 void PreviewClient::requestShowWindowMenu(const QRect &rect)
395 {
396 Q_UNUSED(rect)
397 Q_EMIT showWindowMenuRequested();
398 }
399
requestShowApplicationMenu(const QRect & rect,int actionId)400 void PreviewClient::requestShowApplicationMenu(const QRect &rect, int actionId)
401 {
402 Q_UNUSED(rect);
403 Q_UNUSED(actionId);
404 }
405
showApplicationMenu(int actionId)406 void PreviewClient::showApplicationMenu(int actionId)
407 {
408 Q_UNUSED(actionId)
409 }
410
requestToggleOnAllDesktops()411 void PreviewClient::requestToggleOnAllDesktops()
412 {
413 setDesktop(isOnAllDesktops() ? 1 : -1);
414 }
415
requestToggleShade()416 void PreviewClient::requestToggleShade()
417 {
418 setShaded(!isShaded());
419 }
420
421 #define SETTER(type, name, variable) \
422 void PreviewClient::name(type variable) \
423 { \
424 if (m_##variable == variable) { \
425 return; \
426 } \
427 m_##variable = variable; \
428 Q_EMIT variable##Changed(m_##variable); \
429 }
430
431 #define SETTER2(name, variable) SETTER(bool, name, variable)
432
433 SETTER(const QString &, setCaption, caption)
434 SETTER(const QString &, setIconName, iconName)
435 SETTER(int, setWidth, width)
436 SETTER(int, setHeight, height)
437
438 SETTER2(setActive, active)
439 SETTER2(setCloseable, closeable)
440 SETTER2(setMaximizable, maximizable)
441 SETTER2(setKeepBelow, keepBelow)
442 SETTER2(setKeepAbove, keepAbove)
443 SETTER2(setMaximizedHorizontally, maximizedHorizontally)
444 SETTER2(setMaximizedVertically, maximizedVertically)
445 SETTER2(setMinimizable, minimizable)
446 SETTER2(setModal, modal)
447 SETTER2(setMovable, movable)
448 SETTER2(setResizable, resizable)
449 SETTER2(setShadeable, shadeable)
450 SETTER2(setShaded, shaded)
451 SETTER2(setProvidesContextHelp, providesContextHelp)
452
453 #undef SETTER2
454 #undef SETTER
455
456 } // namespace Preview
457 } // namespace KDecoration2
458