6 #include "decoration.h"
7 #include "decoratedclient.h"
8 #include "decoration_p.h"
9 #include "decorationbutton.h"
10 #include "decorationsettings.h"
11 #include "private/decoratedclientprivate.h"
12 #include "private/decorationbridge.h"
14 #include <QCoreApplication>
15 #include <QHoverEvent>
21 DecorationBridge *findBridge(
const QVariantList &args)
23 for (
const auto &arg : args) {
24 if (
auto bridge = arg.toMap().value(QStringLiteral(
"bridge")).value<DecorationBridge *>()) {
32 Decoration::Private::Private(Decoration *deco,
const QVariantList &args)
34 , bridge(findBridge(args))
35 , client(
QSharedPointer<DecoratedClient>(new DecoratedClient(deco, bridge)))
44 if (sectionUnderMouse == section) {
47 sectionUnderMouse = section;
48 Q_EMIT q->sectionUnderMouseChanged(sectionUnderMouse);
51 void Decoration::Private::updateSectionUnderMouse(
const QPoint &mousePosition)
53 if (titleBar.contains(mousePosition)) {
57 const QSize size = q->size();
58 const int corner = 2 * settings->largeSpacing();
59 const bool left = mousePosition.
x() < borders.left();
60 const bool top = mousePosition.
y() < borders.top();
61 const bool bottom = size.
height() - mousePosition.
y() <= borders.bottom();
62 const bool right = size.
width() - mousePosition.
x() <= borders.right();
64 if (top && mousePosition.
y() < titleBar.top() + corner) {
66 }
else if (size.
height() - mousePosition.
y() <= borders.bottom() + corner && mousePosition.
y() > titleBar.bottom()) {
74 if (top && mousePosition.
y() < titleBar.top() + corner) {
76 }
else if (size.
height() - mousePosition.
y() <= borders.bottom() + corner && mousePosition.
y() > titleBar.bottom()) {
84 if (mousePosition.
y() > titleBar.bottom()) {
85 if (mousePosition.
x() < borders.left() + corner) {
87 }
else if (size.
width() - mousePosition.
x() <= borders.right() + corner) {
98 if (mousePosition.
y() < titleBar.top()) {
99 if (mousePosition.
x() < borders.left() + corner) {
101 }
else if (size.
width() - mousePosition.
x() <= borders.right() + corner) {
114 void Decoration::Private::addButton(DecorationButton *button)
116 Q_ASSERT(!buttons.contains(button));
119 auto it = buttons.begin();
120 while (it != buttons.end()) {
121 if (*it == static_cast<DecorationButton *>(o)) {
122 it = buttons.erase(it);
130 Decoration::Decoration(
QObject *parent,
const QVariantList &args)
132 , d(new Private(this, args))
134 connect(
this, &Decoration::bordersChanged,
this, [
this] {
139 Decoration::~Decoration() =
default;
143 Q_ASSERT(!d->settings.
isNull());
148 return d->client.toWeakRef();
151 #define DELEGATE(name) \
152 void Decoration::name() \
154 d->client->d->name(); \
157 DELEGATE(requestClose)
158 DELEGATE(requestContextHelp)
159 DELEGATE(requestMinimize)
160 DELEGATE(requestToggleOnAllDesktops)
161 DELEGATE(requestToggleShade)
162 DELEGATE(requestToggleKeepAbove)
163 DELEGATE(requestToggleKeepBelow)
167 #if KDECORATIONS2_ENABLE_DEPRECATED_SINCE(5, 21)
176 d->client->d->requestShowWindowMenu(
rect);
179 void Decoration::requestShowToolTip(
const QString &text)
181 d->client->d->requestShowToolTip(text);
184 void Decoration::requestHideToolTip()
186 d->client->d->requestHideToolTip();
191 d->client->d->requestToggleMaximization(buttons);
194 void Decoration::showApplicationMenu(
int actionId)
196 auto it = std::find_if(d->buttons.constBegin(), d->buttons.constEnd(), [](DecorationButton *button) {
197 return button->type() == DecorationButtonType::ApplicationMenu;
200 if (it != d->buttons.constEnd()) {
201 requestShowApplicationMenu((*it)->geometry().toRect(), actionId);
205 void Decoration::requestShowApplicationMenu(
const QRect &rect,
int actionId)
207 if (
auto *appMenuEnabledPrivate =
dynamic_cast<ApplicationMenuEnabledDecoratedClientPrivate *
>(d->client->d.
get())) {
208 appMenuEnabledPrivate->requestShowApplicationMenu(
rect, actionId);
212 #define DELEGATE(name, variableName, type, emitValue) \
213 void Decoration::name(type a) \
215 if (d->variableName == a) { \
218 d->variableName = a; \
219 Q_EMIT variableName##Changed(emitValue); \
222 DELEGATE(setBlurRegion, blurRegion,
const QRegion &, )
223 DELEGATE(setBorders, borders, const
QMargins &, )
224 DELEGATE(setResizeOnlyBorders, resizeOnlyBorders, const
QMargins &, )
225 DELEGATE(setTitleBar, titleBar, const
QRect &, )
226 DELEGATE(setOpaque, opaque,
bool, d->opaque)
227 DELEGATE(setShadow, shadow, const
QSharedPointer<DecorationShadow> &, d->shadow)
231 #define DELEGATE(name, type) \
232 type Decoration::name() const \
239 DELEGATE(resizeOnlyBorders,
QMargins)
240 DELEGATE(titleBar,
QRect)
246 bool Decoration::isOpaque()
const
251 #define BORDER(name, Name) \
252 int Decoration::border##Name() const \
254 return d->borders.name(); \
256 int Decoration::resizeOnlyBorder##Name() const \
258 return d->resizeOnlyBorders.name(); \
264 BORDER(bottom, Bottom)
267 QSize Decoration::size()
const
271 (d->client->isShaded() ? 0 : d->client->height()) + b.
top() + b.
bottom());
279 bool Decoration::event(
QEvent *event)
281 switch (event->type()) {
283 hoverEnterEvent(
static_cast<QHoverEvent *
>(event));
286 hoverLeaveEvent(
static_cast<QHoverEvent *
>(event));
292 mousePressEvent(
static_cast<QMouseEvent *
>(event));
295 mouseReleaseEvent(
static_cast<QMouseEvent *
>(event));
308 void Decoration::hoverEnterEvent(
QHoverEvent *event)
310 for (DecorationButton *button : d->buttons) {
313 d->updateSectionUnderMouse(
event->pos());
316 void Decoration::hoverLeaveEvent(
QHoverEvent *event)
318 for (DecorationButton *button : d->buttons) {
324 void Decoration::hoverMoveEvent(
QHoverEvent *event)
326 for (DecorationButton *button : d->buttons) {
327 if (!button->isEnabled() || !button->isVisible()) {
330 const bool hovered = button->isHovered();
331 const bool contains = button->contains(
event->posF());
332 if (!hovered && contains) {
335 }
else if (hovered && !contains) {
338 }
else if (hovered && contains) {
342 d->updateSectionUnderMouse(
event->pos());
345 void Decoration::mouseMoveEvent(
QMouseEvent *event)
347 for (DecorationButton *button : d->buttons) {
348 if (button->isPressed()) {
356 void Decoration::mousePressEvent(
QMouseEvent *event)
358 for (DecorationButton *button : d->buttons) {
359 if (button->isHovered()) {
360 if (button->acceptedButtons().testFlag(
event->button())) {
363 event->setAccepted(
true);
369 void Decoration::mouseReleaseEvent(
QMouseEvent *event)
371 for (DecorationButton *button : d->buttons) {
372 if (button->isPressed() && button->acceptedButtons().testFlag(
event->button())) {
378 d->updateSectionUnderMouse(
event->pos());
383 for (DecorationButton *button : d->buttons) {
384 if (button->contains(
event->position())) {
386 event->setAccepted(
true);
391 void Decoration::update(
const QRect &r)
396 void Decoration::update()