6#include "popupplasmawindow.h"
8#include <kwindoweffects.h>
9#include <kwindowsystem.h>
12#include <QGuiApplication>
14#include <qnamespace.h>
15#include <qtmetamacros.h>
17#include "plasmashellwaylandintegration.h"
18#include "private/utils.h"
19#include "transientplacementhint_p.h"
24class PopupPlasmaWindowPrivate
27 PopupPlasmaWindowPrivate(PopupPlasmaWindow *_q);
29 void updateEffectivePopupDirection(
const QRect &anchorRect,
const QRect &relativePopupPosition);
30 void updateSlideEffect();
31 void updatePosition();
32 void updatePositionX11(
const QPoint &position);
33 void updatePositionWayland(
const QPoint &position);
34 void updateBorders(
const QRect &globalPosition);
35 void updateVisualParentWindow();
40 PopupPlasmaWindow::RemoveBorders m_removeBorderStrategy = PopupPlasmaWindow::Never;
41 bool m_needsReposition =
false;
42 bool m_floating =
false;
43 bool m_animated =
false;
49PopupPlasmaWindowPrivate::PopupPlasmaWindowPrivate(PopupPlasmaWindow *_q)
61void PopupPlasmaWindowPrivate::updateEffectivePopupDirection(
const QRect &anchorRect,
const QRect &relativePopupPosition)
65 if (relativePopupPosition.
center().
y() >= anchorRect.
center().
y()) {
72 if (relativePopupPosition.
center().
x() >= anchorRect.
center().
x()) {
79 if (effectivePopupDirection != m_effectivePopupDirection) {
80 Q_EMIT q->effectivePopupDirectionChanged();
81 m_effectivePopupDirection = effectivePopupDirection;
85void PopupPlasmaWindowPrivate::updateSlideEffect()
87 KWindowEffects::SlideFromLocation slideLocation = KWindowEffects::NoEdge;
92 switch (m_effectivePopupDirection) {
94 slideLocation = KWindowEffects::BottomEdge;
97 slideLocation = KWindowEffects::TopEdge;
100 slideLocation = KWindowEffects::RightEdge;
103 slideLocation = KWindowEffects::LeftEdge;
109void PopupPlasmaWindowPrivate::updatePosition()
111 m_needsReposition =
false;
113 if (!m_visualParent || !m_visualParent->window()) {
114 qCWarning(LOG_PLASMAQUICK) <<
"Exposed with no visual parent. Window positioning broken.";
117 q->setTransientParent(m_visualParent->window());
118 TransientPlacementHint placementHint;
119 QRectF parentAnchorRect =
QRectF(m_visualParent->mapToScene(
QPointF(0, 0)), m_visualParent->size());
125 parentAnchorRect.
setTop(0);
126 parentAnchorRect.
setBottom(m_visualParent->window()->height());
130 parentAnchorRect.
setRight(m_visualParent->window()->width());
134 placementHint.setParentAnchorArea(parentAnchorRect.
toRect());
135 placementHint.setParentAnchor(m_popupDirection);
136 placementHint.setPopupAnchor(PlasmaQuickPrivate::oppositeEdge(m_popupDirection));
137 placementHint.setFlipConstraintAdjustments(m_floating ?
Qt::Vertical :
Qt::Orientations());
138 placementHint.setMargin(m_margin);
140 const QRect popupPosition = TransientPlacementHelper::popupRect(q, placementHint);
142 QRect relativePopupPosition = popupPosition;
143 if (m_visualParent->window()) {
144 relativePopupPosition = relativePopupPosition.
translated(-m_visualParent->window()->position());
146 updateEffectivePopupDirection(parentAnchorRect.
toRect(), relativePopupPosition);
150 updatePositionX11(popupPosition.
topLeft());
152 updatePositionWayland(popupPosition.
topLeft());
155 updateBorders(popupPosition);
158void PopupPlasmaWindowPrivate::updatePositionX11(
const QPoint &position)
160 q->setPosition(position);
163void PopupPlasmaWindowPrivate::updatePositionWayland(
const QPoint &position)
167 q->setPosition(position);
172void PopupPlasmaWindowPrivate::updateBorders(
const QRect &globalPosition)
185 q->setBorders(enabledBorders);
189 if (m_removeBorderStrategy & PopupPlasmaWindow::AtScreenEdges) {
190 if (globalPosition.
top() <= screenGeometry.
top()) {
193 if (globalPosition.
bottom() >= screenGeometry.
bottom()) {
196 if (globalPosition.
left() <= screenGeometry.
left()) {
199 if (globalPosition.
right() >= screenGeometry.
right()) {
203 if (m_removeBorderStrategy & PopupPlasmaWindow::AtPanelEdges) {
204 switch (m_popupDirection) {
220 q->setBorders(enabledBorders);
223void PopupPlasmaWindowPrivate::updateVisualParentWindow()
225 if (m_visualParentWindow) {
230 m_visualParentWindow = m_visualParent ? m_visualParent->window() :
nullptr;
232 if (m_visualParentWindow) {
238PopupPlasmaWindow::PopupPlasmaWindow(
const QString &svgPrefix)
239 : PlasmaWindow(svgPrefix)
240 , d(new PopupPlasmaWindowPrivate(this))
244PopupPlasmaWindow::~PopupPlasmaWindow()
248void PopupPlasmaWindow::setVisualParent(
QQuickItem *item)
250 if (item == d->m_visualParent) {
254 if (d->m_visualParent) {
255 disconnect(d->m_visualParent, SIGNAL(windowChanged(
QQuickWindow *)),
this, SLOT(updateVisualParentWindow()));
258 d->m_visualParent = item;
259 d->updateVisualParentWindow();
261 if (d->m_visualParent) {
262 connect(d->m_visualParent, SIGNAL(windowChanged(
QQuickWindow *)),
this, SLOT(updateVisualParentWindow()));
265 Q_EMIT visualParentChanged();
266 queuePositionUpdate();
269QQuickItem *PopupPlasmaWindow::visualParent()
const
271 return d->m_visualParent;
274Qt::Edge PopupPlasmaWindow::popupDirection()
const
276 return d->m_popupDirection;
279void PopupPlasmaWindow::setPopupDirection(
Qt::Edge popupDirection)
281 if (popupDirection == d->m_popupDirection) {
284 d->m_popupDirection = popupDirection;
287 qCWarning(LOG_PLASMAQUICK) <<
"location should be set before showing popup window";
289 queuePositionUpdate();
291 Q_EMIT popupDirectionChanged();
294Qt::Edge PopupPlasmaWindow::effectivePopupDirection()
const
296 return d->m_effectivePopupDirection;
299bool PopupPlasmaWindow::floating()
const
301 return d->m_floating;
304void PopupPlasmaWindow::setFloating(
bool floating)
306 if (floating == d->m_floating) {
309 d->m_floating = floating;
310 queuePositionUpdate();
311 Q_EMIT floatingChanged();
314bool PopupPlasmaWindow::animated()
const
316 return d->m_animated;
319void PopupPlasmaWindow::setAnimated(
bool animated)
321 d->m_animated = animated;
322 queuePositionUpdate();
323 Q_EMIT animatedChanged();
326PopupPlasmaWindow::RemoveBorders PopupPlasmaWindow::removeBorderStrategy()
const
328 return d->m_removeBorderStrategy;
331void PopupPlasmaWindow::setRemoveBorderStrategy(PopupPlasmaWindow::RemoveBorders strategy)
333 if (d->m_removeBorderStrategy == strategy) {
337 d->m_removeBorderStrategy = strategy;
338 queuePositionUpdate();
339 Q_EMIT removeBorderStrategyChanged();
342int PopupPlasmaWindow::margin()
const
347void PopupPlasmaWindow::setMargin(
int margin)
349 if (d->m_margin == margin) {
353 d->m_margin = margin;
354 queuePositionUpdate();
355 Q_EMIT marginChanged();
358bool PopupPlasmaWindow::event(
QEvent *event)
360 switch (
event->type()) {
362 if (d->m_needsReposition) {
378void PopupPlasmaWindow::queuePositionUpdate()
380 d->m_needsReposition =
true;
384#include "moc_popupplasmawindow.cpp"
static bool isPlatformX11()
static bool isPlatformWayland()
static PlasmaShellWaylandIntegration * get(QWindow *window)
Returns the relevant PlasmaWaylandShellIntegration instance for this window creating one if needed.
AKONADI_CALENDAR_EXPORT KCalendarCore::Event::Ptr event(const Akonadi::Item &item)
void slideWindow(QWindow *window, SlideFromLocation location, int offset=-1)
The EdgeEventForwarder class This class forwards edge events to be replayed within the given margin T...
QScreen * screenAt(const QPoint &point)
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
bool disconnect(const QMetaObject::Connection &connection)
QPoint center() const const
QPoint topLeft() const const
QRect translated(const QPoint &offset) const const
QRect toRect() const const
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
virtual bool event(QEvent *ev) override