Add a placement strategy for transient ShellClients

A transient ShellClient has an offset position to the parent surface.
Use this to position the ShellClient properly.

This fixes the random placement of menus.
icc-effect-5.14.5
Martin Gräßlin 2015-09-11 13:31:41 +02:00
parent 0935a60b38
commit a86a7e7b3c
6 changed files with 40 additions and 0 deletions

View File

@ -812,4 +812,14 @@ AbstractClient *AbstractClient::transientFor()
return m_transientFor;
}
bool AbstractClient::hasTransientPlacementHint() const
{
return false;
}
QPoint AbstractClient::transientPlacementHint() const
{
return QPoint();
}
}

View File

@ -247,6 +247,15 @@ public:
// TODO: remove boolean trap
virtual AbstractClient *findModal(bool allow_itself = false) = 0;
virtual bool isTransient() const;
/**
* @returns Whether there is a hint available to place the AbstractClient on it's parent, default @c false.
* @see transientPlacementHint
**/
virtual bool hasTransientPlacementHint() const;
/**
* @returns The recommended position of the transient in parent coordinates
**/
virtual QPoint transientPlacementHint() const;
const AbstractClient* transientFor() const;
AbstractClient* transientFor();
/**

View File

@ -72,6 +72,8 @@ void Placement::place(AbstractClient* c, QRect& area)
placeOnMainWindow(c, area); // on mainwindow, if any, otherwise centered
else if (c->isOnScreenDisplay() || c->isNotification())
placeOnScreenDisplay(c, area);
else if (c->isTransient() && c->hasTransientPlacementHint())
placeTransient(c);
else
place(c, area, options->placement());
}
@ -492,6 +494,12 @@ void Placement::placeOnScreenDisplay(AbstractClient* c, QRect& area)
c->move(QPoint(x, y));
}
void Placement::placeTransient(AbstractClient *c)
{
// TODO: apply sanity checks?
c->move(c->transientFor()->pos() + c->transientPlacementHint());
}
void Placement::placeDialog(AbstractClient* c, QRect& area, Policy nextPlacement)
{
placeOnMainWindow(c, area, nextPlacement);

View File

@ -92,6 +92,7 @@ private:
void place(AbstractClient* c, QRect& area, Policy policy, Policy nextPlacement = Unknown);
void placeUnderMouse(AbstractClient* c, QRect& area, Policy next = Unknown);
void placeOnMainWindow(AbstractClient* c, QRect& area, Policy next = Unknown);
void placeTransient(AbstractClient *c);
QRect checkArea(const AbstractClient*c, const QRect& area);
//CT needed for cascading+

View File

@ -726,4 +726,14 @@ void ShellClient::setTransient()
setTransientFor(waylandServer()->findClient(s.data()));
}
bool ShellClient::hasTransientPlacementHint() const
{
return isTransient() && transientFor() != nullptr;
}
QPoint ShellClient::transientPlacementHint() const
{
return m_shellSurface->transientOffset();
}
}

View File

@ -112,6 +112,8 @@ public:
bool isInitialPositionSet() const;
bool isTransient() const override;
bool hasTransientPlacementHint() const override;
QPoint transientPlacementHint() const override;
protected:
void addDamage(const QRegion &damage) override;