7#include "decoratedwindow.h"
8#include "decoration_p.h"
9#include "decorationbutton.h"
10#include "decorationsettings.h"
11#include "private/decoratedwindowprivate.h"
12#include "private/decorationbridge.h"
14#include <QCoreApplication>
23DecorationBridge *findBridge(
const QVariantList &args)
25 for (
const auto &arg : args) {
26 if (
auto bridge = arg.toMap().value(QStringLiteral(
"bridge")).value<DecorationBridge *>()) {
34class DecorationStateData :
public QSharedData
40DecorationState::DecorationState()
41 : d(new DecorationStateData)
45DecorationState::DecorationState(
const DecorationState &other)
50DecorationState::~DecorationState()
54std::shared_ptr<DecorationState> DecorationState::clone()
const
56 return std::make_shared<DecorationState>(*
this);
64void DecorationState::setBorders(
const QMarginsF &borders)
69Positioner::Positioner()
70 : d(new PositionerData)
74Positioner::Positioner(
const Positioner &other)
79Positioner::~Positioner()
93Decoration::Private::Private(
Decoration *deco,
const QVariantList &args)
94 : sectionUnderMouse(
Qt::NoSection)
95 , bridge(findBridge(args))
104 if (sectionUnderMouse == section) {
107 sectionUnderMouse = section;
108 Q_EMIT q->sectionUnderMouseChanged(sectionUnderMouse);
111void Decoration::Private::updateSectionUnderMouse(
const QPoint &mousePosition)
113 if (titleBar.toRect().contains(mousePosition)) {
117 const QSizeF size = q->size();
118 const QMarginsF borders = current->borders();
119 const int corner = 2 * settings->largeSpacing();
120 const bool left = mousePosition.
x() < borders.
left();
121 const bool top = mousePosition.
y() < borders.
top();
122 const bool bottom = mousePosition.
y() >= size.
height() - borders.
bottom();
125 if (top && mousePosition.
y() < titleBar.top() + corner) {
127 }
else if (mousePosition.
y() >= size.
height() - borders.
bottom() - corner && mousePosition.
y() >= titleBar.bottom()) {
135 if (top && mousePosition.
y() < titleBar.top() + corner) {
137 }
else if (mousePosition.
y() >= size.
height() - borders.
bottom() - corner && mousePosition.
y() >= titleBar.bottom()) {
145 if (mousePosition.
y() >= titleBar.bottom()) {
146 if (mousePosition.
x() < borders.
left() + corner) {
148 }
else if (mousePosition.
x() >= size.
width() - borders.
right() - corner) {
159 if (mousePosition.
y() < titleBar.top()) {
160 if (mousePosition.
x() < borders.
left() + corner) {
162 }
else if (mousePosition.
x() >= size.
width() - borders.
right() - corner) {
177 Q_ASSERT(!buttons.contains(button));
180 auto it = buttons.begin();
181 while (it != buttons.end()) {
183 it = buttons.erase(it);
193 , d(new Private(this, args))
197Decoration::~Decoration() =
default;
201 return d->client.get();
204void Decoration::requestClose()
206 d->client->d->requestClose();
209void Decoration::requestContextHelp()
211 d->client->d->requestContextHelp();
214void Decoration::requestMinimize()
216 d->client->d->requestMinimize();
219void Decoration::requestToggleOnAllDesktops()
221 d->client->d->requestToggleOnAllDesktops();
224void Decoration::requestToggleShade()
226 d->client->d->requestToggleShade();
229void Decoration::requestToggleKeepAbove()
231 d->client->d->requestToggleKeepAbove();
234void Decoration::requestToggleKeepBelow()
236 d->client->d->requestToggleKeepBelow();
239#if KDECORATIONS3_ENABLE_DEPRECATED_SINCE(5, 21)
248 d->client->d->requestShowWindowMenu(
rect);
251void Decoration::requestShowToolTip(
const QString &text)
253 d->client->d->requestShowToolTip(text);
256void Decoration::requestHideToolTip()
258 d->client->d->requestHideToolTip();
263 d->client->d->requestToggleMaximization(buttons);
266void Decoration::showApplicationMenu(
int actionId)
268 const auto it = std::find_if(d->buttons.constBegin(), d->buttons.constEnd(), [](DecorationButton *button) {
269 return button->type() == DecorationButtonType::ApplicationMenu;
271 if (it != d->buttons.constEnd()) {
272 requestShowApplicationMenu((*it)->geometry().toRect(), actionId);
276void Decoration::requestShowApplicationMenu(
const QRect &rect,
int actionId)
278 d->client->d->requestShowApplicationMenu(
rect, actionId);
281void Decoration::setBlurRegion(
const QRegion ®ion)
283 if (d->blurRegion != region) {
284 d->blurRegion = region;
285 Q_EMIT blurRegionChanged();
289void Decoration::setBorders(
const QMarginsF &borders)
291 if (d->next->borders() != borders) {
292 setState([borders](DecorationState *state) {
293 state->setBorders(borders);
298void Decoration::setResizeOnlyBorders(
const QMarginsF &borders)
300 if (d->resizeOnlyBorders != borders) {
301 d->resizeOnlyBorders = borders;
302 Q_EMIT resizeOnlyBordersChanged();
308 if (d->titleBar !=
rect) {
314void Decoration::setOpaque(
bool opaque)
316 if (d->opaque !=
opaque) {
322void Decoration::setShadow(
const std::shared_ptr<DecorationShadow> &shadow)
324 if (d->shadow !=
shadow) {
332 return d->blurRegion;
337 return d->current->borders();
340QMarginsF Decoration::resizeOnlyBorders()
const
342 return d->resizeOnlyBorders;
352 return d->sectionUnderMouse;
360bool Decoration::isOpaque()
const
365qreal Decoration::borderLeft()
const
367 return d->current->borders().left();
370qreal Decoration::resizeOnlyBorderLeft()
const
372 return d->resizeOnlyBorders.left();
375qreal Decoration::borderRight()
const
377 return d->current->borders().right();
380qreal Decoration::resizeOnlyBorderRight()
const
382 return d->resizeOnlyBorders.right();
385qreal Decoration::borderTop()
const
387 return d->current->borders().top();
390qreal Decoration::resizeOnlyBorderTop()
const
392 return d->resizeOnlyBorders.top();
395qreal Decoration::borderBottom()
const
397 return d->current->borders().bottom();
400qreal Decoration::resizeOnlyBorderBottom()
const
402 return d->resizeOnlyBorders.bottom();
405QSizeF Decoration::size()
const
407 const QMarginsF b = d->current->borders();
408 return QSizeF(d->client->width() + b.
left() + b.
right(), (d->client->isShaded() ? 0 : d->client->height()) + b.
top() + b.
bottom());
416bool Decoration::event(
QEvent *event)
418 switch (event->type()) {
420 hoverEnterEvent(
static_cast<QHoverEvent *
>(event));
423 hoverLeaveEvent(
static_cast<QHoverEvent *
>(event));
429 mousePressEvent(
static_cast<QMouseEvent *
>(event));
432 mouseReleaseEvent(
static_cast<QMouseEvent *
>(event));
445void Decoration::hoverEnterEvent(QHoverEvent *event)
447 for (DecorationButton *button : d->buttons) {
450 auto flooredPos = QPoint(std::floor(event->position().x()), std::floor(event->position().y()));
451 d->updateSectionUnderMouse(flooredPos);
454void Decoration::hoverLeaveEvent(QHoverEvent *event)
456 for (DecorationButton *button : d->buttons) {
462void Decoration::hoverMoveEvent(QHoverEvent *event)
464 for (DecorationButton *button : d->buttons) {
465 if (!button->isEnabled() || !button->isVisible()) {
468 const bool hovered = button->isHovered();
469 const bool contains = button->contains(event->position());
470 if (!hovered && contains) {
471 QHoverEvent e(
QEvent::HoverEnter, event->position(), event->oldPosF(), event->modifiers());
473 }
else if (hovered && !contains) {
474 QHoverEvent e(
QEvent::HoverLeave, event->position(), event->oldPosF(), event->modifiers());
476 }
else if (hovered && contains) {
480 auto flooredPos = QPoint(std::floor(event->position().x()), std::floor(event->position().y()));
481 d->updateSectionUnderMouse(flooredPos);
484void Decoration::mouseMoveEvent(QMouseEvent *event)
486 for (DecorationButton *button : d->buttons) {
487 if (button->isPressed()) {
495void Decoration::mousePressEvent(QMouseEvent *event)
497 for (DecorationButton *button : d->buttons) {
498 if (button->isHovered()) {
499 if (button->acceptedButtons().testFlag(event->button())) {
502 event->setAccepted(
true);
508void Decoration::mouseReleaseEvent(QMouseEvent *event)
510 for (DecorationButton *button : d->buttons) {
511 if (button->isPressed() && button->acceptedButtons().testFlag(event->button())) {
517 d->updateSectionUnderMouse(event->pos());
520void Decoration::wheelEvent(QWheelEvent *event)
522 for (DecorationButton *button : d->buttons) {
523 if (button->contains(event->position())) {
525 event->setAccepted(
true);
530void Decoration::update(
const QRectF &r)
535void Decoration::update()
552 return std::make_shared<DecorationState>();
573 callback(d->next.get());
574 Q_EMIT nextStateChanged(d->next);
579 if (d->current == state) {
583 const auto previous = d->current;
587 if (previous->borders() != state->borders()) {
591 Q_EMIT currentStateChanged(state);
596 if (
auto window =
dynamic_cast<DecoratedWindowPrivateV3 *
>(d->client->d.get())) {
597 window->popup(positioner, menu);
603#include "moc_decoration.cpp"
The Client which gets decorated.
Base class for the Decoration.
std::shared_ptr< DecorationState > currentState() const
Returns the currently applied state.
virtual std::shared_ptr< DecorationState > createState()
Create a state container.
DecoratedWindow * window() const
The DecoratedWindow for this Decoration.
QRectF titleBar
The titleBar is the area inside the Decoration containing all controls (e.g.
std::shared_ptr< DecorationState > nextState() const
Returns the next state, i.e.
void requestShowWindowMenu(const QRect &rect)
Decoration(QObject *parent, const QVariantList &args)
Constructor for the Decoration.
void setSettings(const std::shared_ptr< DecorationSettings > &settings)
Invoked by the framework to set the Settings for this Decoration before init is invoked.
QRegion blurRegion() const
The decoration's blur region in local coordinates.
QRectF rect() const
The decoration's geometry in local coordinates.
void apply(std::shared_ptr< DecorationState > state)
Qt::WindowFrameSection sectionUnderMouse
This property denotes the part of the Decoration which is currently under the mouse pointer.
void setTitleBar(const QRectF &rect)
An implementation has to invoke this method whenever the area containing the controls and caption cha...
std::shared_ptr< DecorationSettings > settings() const
void setState(std::function< void(DecorationState *state)> callback)
Notifies the framework that the decoration state has changed.
bool opaque
Whether the Decoration is fully opaque.
void popup(const Positioner &positioner, QMenu *menu)
Shows the given menu at the position specified by the positioner.
std::shared_ptr< DecorationShadow > shadow() const
DecorationShadow for this Decoration.
void setAnchorRect(const QRectF &rect)
Sets the anchor rectangle to rect.
QRectF anchorRect() const
Returns the anchor rectangle.
Framework for creating window decorations.
QCoreApplication * instance()
bool sendEvent(QObject *receiver, QEvent *event)
qreal bottom() const const
qreal right() const const
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
void destroyed(QObject *obj)
virtual bool event(QEvent *e)
QObject * parent() const const
bool isNull() const const
QRect toAlignedRect() const const
qreal height() const const
qreal width() const const
QTextStream & left(QTextStream &stream)
QTextStream & right(QTextStream &stream)