Move geometry handling code from XdgSurfaceClient to WaylandClient
parent
a9fd5ac19f
commit
4296a38a30
|
@ -28,6 +28,13 @@ using namespace KWaylandServer;
|
|||
namespace KWin
|
||||
{
|
||||
|
||||
enum WaylandGeometryType {
|
||||
WaylandGeometryClient = 0x1,
|
||||
WaylandGeometryFrame = 0x2,
|
||||
WaylandGeometryBuffer = 0x4,
|
||||
};
|
||||
Q_DECLARE_FLAGS(WaylandGeometryTypes, WaylandGeometryType)
|
||||
|
||||
WaylandClient::WaylandClient(SurfaceInterface *surface)
|
||||
{
|
||||
// Note that we cannot setup compositing here because we may need to call visibleRect(),
|
||||
|
@ -332,4 +339,164 @@ void WaylandClient::internalHide()
|
|||
emit windowHidden(this);
|
||||
}
|
||||
|
||||
QRect WaylandClient::frameRectToBufferRect(const QRect &rect) const
|
||||
{
|
||||
return QRect(rect.topLeft(), surface()->size());
|
||||
}
|
||||
|
||||
QRect WaylandClient::requestedFrameGeometry() const
|
||||
{
|
||||
return m_requestedFrameGeometry;
|
||||
}
|
||||
|
||||
QPoint WaylandClient::requestedPos() const
|
||||
{
|
||||
return m_requestedFrameGeometry.topLeft();
|
||||
}
|
||||
|
||||
QSize WaylandClient::requestedSize() const
|
||||
{
|
||||
return m_requestedFrameGeometry.size();
|
||||
}
|
||||
|
||||
QRect WaylandClient::requestedClientGeometry() const
|
||||
{
|
||||
return m_requestedClientGeometry;
|
||||
}
|
||||
|
||||
QRect WaylandClient::bufferGeometry() const
|
||||
{
|
||||
return m_bufferGeometry;
|
||||
}
|
||||
|
||||
QSize WaylandClient::requestedClientSize() const
|
||||
{
|
||||
return requestedClientGeometry().size();
|
||||
}
|
||||
|
||||
void WaylandClient::setFrameGeometry(const QRect &rect, ForceGeometry_t force)
|
||||
{
|
||||
m_requestedFrameGeometry = rect;
|
||||
|
||||
if (isShade()) {
|
||||
if (m_requestedFrameGeometry.height() == borderTop() + borderBottom()) {
|
||||
qCDebug(KWIN_CORE) << "Passed shaded frame geometry to setFrameGeometry()";
|
||||
} else {
|
||||
m_requestedClientGeometry = frameRectToClientRect(m_requestedFrameGeometry);
|
||||
m_requestedFrameGeometry.setHeight(borderTop() + borderBottom());
|
||||
}
|
||||
} else {
|
||||
m_requestedClientGeometry = frameRectToClientRect(m_requestedFrameGeometry);
|
||||
}
|
||||
|
||||
if (areGeometryUpdatesBlocked()) {
|
||||
m_frameGeometry = m_requestedFrameGeometry;
|
||||
if (pendingGeometryUpdate() == PendingGeometryForced) {
|
||||
return;
|
||||
}
|
||||
if (force == ForceGeometrySet) {
|
||||
setPendingGeometryUpdate(PendingGeometryForced);
|
||||
} else {
|
||||
setPendingGeometryUpdate(PendingGeometryNormal);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
m_frameGeometry = frameGeometryBeforeUpdateBlocking();
|
||||
|
||||
if (requestedClientSize() != clientSize()) {
|
||||
requestGeometry(requestedFrameGeometry());
|
||||
} else {
|
||||
updateGeometry(requestedFrameGeometry());
|
||||
}
|
||||
}
|
||||
|
||||
void WaylandClient::move(int x, int y, ForceGeometry_t force)
|
||||
{
|
||||
Q_ASSERT(pendingGeometryUpdate() == PendingGeometryNone || areGeometryUpdatesBlocked());
|
||||
QPoint p(x, y);
|
||||
if (!areGeometryUpdatesBlocked() && p != rules()->checkPosition(p)) {
|
||||
qCDebug(KWIN_CORE) << "forced position fail:" << p << ":" << rules()->checkPosition(p);
|
||||
}
|
||||
m_requestedFrameGeometry.moveTopLeft(p);
|
||||
m_requestedClientGeometry.moveTopLeft(framePosToClientPos(p));
|
||||
if (force == NormalGeometrySet && m_frameGeometry.topLeft() == p) {
|
||||
return;
|
||||
}
|
||||
m_frameGeometry.moveTopLeft(m_requestedFrameGeometry.topLeft());
|
||||
if (areGeometryUpdatesBlocked()) {
|
||||
if (pendingGeometryUpdate() == PendingGeometryForced) {
|
||||
return;
|
||||
}
|
||||
if (force == ForceGeometrySet) {
|
||||
setPendingGeometryUpdate(PendingGeometryForced);
|
||||
} else {
|
||||
setPendingGeometryUpdate(PendingGeometryNormal);
|
||||
}
|
||||
return;
|
||||
}
|
||||
const QRect oldBufferGeometry = bufferGeometryBeforeUpdateBlocking();
|
||||
const QRect oldClientGeometry = clientGeometryBeforeUpdateBlocking();
|
||||
const QRect oldFrameGeometry = frameGeometryBeforeUpdateBlocking();
|
||||
m_clientGeometry.moveTopLeft(m_requestedClientGeometry.topLeft());
|
||||
m_bufferGeometry = frameRectToBufferRect(m_frameGeometry);
|
||||
updateGeometryBeforeUpdateBlocking();
|
||||
updateWindowRules(Rules::Position);
|
||||
screens()->setCurrent(this);
|
||||
workspace()->updateStackingOrder();
|
||||
emit bufferGeometryChanged(this, oldBufferGeometry);
|
||||
emit clientGeometryChanged(this, oldClientGeometry);
|
||||
emit frameGeometryChanged(this, oldFrameGeometry);
|
||||
addRepaintDuringGeometryUpdates();
|
||||
}
|
||||
|
||||
void WaylandClient::requestGeometry(const QRect &rect)
|
||||
{
|
||||
m_requestedFrameGeometry = rect;
|
||||
m_requestedClientGeometry = frameRectToClientRect(rect);
|
||||
}
|
||||
|
||||
void WaylandClient::updateGeometry(const QRect &rect)
|
||||
{
|
||||
const QRect oldClientGeometry = m_clientGeometry;
|
||||
const QRect oldFrameGeometry = m_frameGeometry;
|
||||
const QRect oldBufferGeometry = m_bufferGeometry;
|
||||
|
||||
m_clientGeometry = frameRectToClientRect(rect);
|
||||
m_frameGeometry = rect;
|
||||
m_bufferGeometry = frameRectToBufferRect(rect);
|
||||
|
||||
WaylandGeometryTypes changedGeometries;
|
||||
|
||||
if (m_clientGeometry != oldClientGeometry) {
|
||||
changedGeometries |= WaylandGeometryClient;
|
||||
}
|
||||
if (m_frameGeometry != oldFrameGeometry) {
|
||||
changedGeometries |= WaylandGeometryFrame;
|
||||
}
|
||||
if (m_bufferGeometry != oldBufferGeometry) {
|
||||
changedGeometries |= WaylandGeometryBuffer;
|
||||
}
|
||||
|
||||
if (!changedGeometries) {
|
||||
return;
|
||||
}
|
||||
|
||||
updateWindowRules(Rules::Position | Rules::Size);
|
||||
updateGeometryBeforeUpdateBlocking();
|
||||
|
||||
if (changedGeometries & WaylandGeometryBuffer) {
|
||||
emit bufferGeometryChanged(this, oldBufferGeometry);
|
||||
}
|
||||
if (changedGeometries & WaylandGeometryClient) {
|
||||
emit clientGeometryChanged(this, oldClientGeometry);
|
||||
}
|
||||
if (changedGeometries & WaylandGeometryFrame) {
|
||||
emit frameGeometryChanged(this, oldFrameGeometry);
|
||||
}
|
||||
emit geometryShapeChanged(this, oldFrameGeometry);
|
||||
|
||||
addRepaintDuringGeometryUpdates();
|
||||
}
|
||||
|
||||
} // namespace KWin
|
||||
|
|
|
@ -18,6 +18,7 @@ class WaylandClient : public AbstractClient
|
|||
public:
|
||||
WaylandClient(KWaylandServer::SurfaceInterface *surface);
|
||||
|
||||
QRect bufferGeometry() const override;
|
||||
QString captionNormal() const override;
|
||||
QString captionSuffix() const override;
|
||||
QStringList activities() const override;
|
||||
|
@ -34,12 +35,21 @@ public:
|
|||
void setOpacity(double opacity) override;
|
||||
AbstractClient *findModal(bool allow_itself = false) override;
|
||||
void resizeWithChecks(const QSize &size, ForceGeometry_t force = NormalGeometrySet) override;
|
||||
void setFrameGeometry(const QRect &rect, ForceGeometry_t force = NormalGeometrySet) override;
|
||||
using AbstractClient::move;
|
||||
void move(int x, int y, ForceGeometry_t force = NormalGeometrySet) override;
|
||||
void killWindow() override;
|
||||
QByteArray windowRole() const override;
|
||||
bool isShown(bool shaded_is_shown) const override;
|
||||
bool isHiddenInternal() const override;
|
||||
void hideClient(bool hide) override;
|
||||
|
||||
virtual QRect frameRectToBufferRect(const QRect &rect) const;
|
||||
QRect requestedFrameGeometry() const;
|
||||
QPoint requestedPos() const;
|
||||
QSize requestedSize() const;
|
||||
QRect requestedClientGeometry() const;
|
||||
QSize requestedClientSize() const;
|
||||
bool isHidden() const;
|
||||
|
||||
void updateDepth();
|
||||
|
@ -51,6 +61,9 @@ protected:
|
|||
void doSetActive() override;
|
||||
void updateCaption() override;
|
||||
|
||||
virtual void requestGeometry(const QRect &rect);
|
||||
virtual void updateGeometry(const QRect &rect);
|
||||
|
||||
private:
|
||||
void updateClientArea();
|
||||
void updateClientOutputs();
|
||||
|
@ -62,6 +75,9 @@ private:
|
|||
QString m_captionNormal;
|
||||
QString m_captionSuffix;
|
||||
double m_opacity = 1.0;
|
||||
QRect m_requestedFrameGeometry;
|
||||
QRect m_bufferGeometry;
|
||||
QRect m_requestedClientGeometry;
|
||||
quint32 m_windowId;
|
||||
bool m_isHidden = false;
|
||||
};
|
||||
|
|
|
@ -38,12 +38,6 @@ using namespace KWaylandServer;
|
|||
namespace KWin
|
||||
{
|
||||
|
||||
enum XdgSurfaceGeometryType {
|
||||
XdgSurfaceGeometryClient = 0x1,
|
||||
XdgSurfaceGeometryFrame = 0x2,
|
||||
XdgSurfaceGeometryBuffer = 0x4,
|
||||
};
|
||||
|
||||
XdgSurfaceClient::XdgSurfaceClient(XdgSurfaceInterface *shellSurface)
|
||||
: WaylandClient(shellSurface->surface())
|
||||
, m_shellSurface(shellSurface)
|
||||
|
@ -109,45 +103,15 @@ XdgSurfaceClient::~XdgSurfaceClient()
|
|||
qDeleteAll(m_configureEvents);
|
||||
}
|
||||
|
||||
QRect XdgSurfaceClient::requestedFrameGeometry() const
|
||||
{
|
||||
return m_requestedFrameGeometry;
|
||||
}
|
||||
|
||||
QPoint XdgSurfaceClient::requestedPos() const
|
||||
{
|
||||
return m_requestedFrameGeometry.topLeft();
|
||||
}
|
||||
|
||||
QSize XdgSurfaceClient::requestedSize() const
|
||||
{
|
||||
return m_requestedFrameGeometry.size();
|
||||
}
|
||||
|
||||
QRect XdgSurfaceClient::requestedClientGeometry() const
|
||||
{
|
||||
return m_requestedClientGeometry;
|
||||
}
|
||||
|
||||
QRect XdgSurfaceClient::inputGeometry() const
|
||||
{
|
||||
return isDecorated() ? AbstractClient::inputGeometry() : bufferGeometry();
|
||||
}
|
||||
|
||||
QRect XdgSurfaceClient::bufferGeometry() const
|
||||
{
|
||||
return m_bufferGeometry;
|
||||
}
|
||||
|
||||
QSize XdgSurfaceClient::requestedClientSize() const
|
||||
{
|
||||
return requestedClientGeometry().size();
|
||||
}
|
||||
|
||||
QMatrix4x4 XdgSurfaceClient::inputTransformation() const
|
||||
{
|
||||
QMatrix4x4 transformation;
|
||||
transformation.translate(-m_bufferGeometry.x(), -m_bufferGeometry.y());
|
||||
transformation.translate(-bufferGeometry().x(), -bufferGeometry().y());
|
||||
return transformation;
|
||||
}
|
||||
|
||||
|
@ -158,13 +122,13 @@ XdgSurfaceConfigure *XdgSurfaceClient::lastAcknowledgedConfigure() const
|
|||
|
||||
bool XdgSurfaceClient::stateCompare() const
|
||||
{
|
||||
if (m_requestedFrameGeometry != m_frameGeometry) {
|
||||
if (requestedFrameGeometry() != frameGeometry()) {
|
||||
return true;
|
||||
}
|
||||
if (m_requestedClientGeometry != m_clientGeometry) {
|
||||
if (requestedClientGeometry() != clientGeometry()) {
|
||||
return true;
|
||||
}
|
||||
if (m_requestedClientGeometry.isEmpty()) {
|
||||
if (requestedClientGeometry().isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -326,146 +290,13 @@ bool XdgSurfaceClient::isInitialPositionSet() const
|
|||
return m_plasmaShellSurface ? m_plasmaShellSurface->isPositionSet() : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the frame geometry of the XdgSurfaceClient to \a rect.
|
||||
*
|
||||
* Because geometry updates are asynchronous on Wayland, there are no any guarantees that
|
||||
* the frame geometry will be changed immediately. We may need to send a configure event to
|
||||
* the client if the current window geometry size and the requested window geometry size
|
||||
* don't match. frameGeometryChanged() will be emitted when the requested frame geometry
|
||||
* has been applied.
|
||||
*
|
||||
* Notice that the client may attach a buffer smaller than the one in the configure event.
|
||||
*/
|
||||
void XdgSurfaceClient::setFrameGeometry(const QRect &rect, ForceGeometry_t force)
|
||||
{
|
||||
m_requestedFrameGeometry = rect;
|
||||
|
||||
// XdgToplevelClient currently doesn't support shaded clients, but let's stick with
|
||||
// what X11Client does. Hopefully, one day we will be able to unify setFrameGeometry()
|
||||
// for all AbstractClient subclasses. It's going to be great!
|
||||
|
||||
if (isShade()) {
|
||||
if (m_requestedFrameGeometry.height() == borderTop() + borderBottom()) {
|
||||
qCDebug(KWIN_CORE) << "Passed shaded frame geometry to setFrameGeometry()";
|
||||
} else {
|
||||
m_requestedClientGeometry = frameRectToClientRect(m_requestedFrameGeometry);
|
||||
m_requestedFrameGeometry.setHeight(borderTop() + borderBottom());
|
||||
}
|
||||
} else {
|
||||
m_requestedClientGeometry = frameRectToClientRect(m_requestedFrameGeometry);
|
||||
}
|
||||
|
||||
if (areGeometryUpdatesBlocked()) {
|
||||
m_frameGeometry = m_requestedFrameGeometry;
|
||||
if (pendingGeometryUpdate() == PendingGeometryForced) {
|
||||
return;
|
||||
}
|
||||
if (force == ForceGeometrySet) {
|
||||
setPendingGeometryUpdate(PendingGeometryForced);
|
||||
} else {
|
||||
setPendingGeometryUpdate(PendingGeometryNormal);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
m_frameGeometry = frameGeometryBeforeUpdateBlocking();
|
||||
|
||||
// Notice that the window geometry size of (0, 0) has special meaning to xdg shell clients.
|
||||
// It basically says "pick whatever size you think is the best, dawg."
|
||||
|
||||
if (requestedClientSize() != clientSize()) {
|
||||
requestGeometry(requestedFrameGeometry());
|
||||
} else {
|
||||
updateGeometry(requestedFrameGeometry());
|
||||
}
|
||||
}
|
||||
|
||||
void XdgSurfaceClient::move(int x, int y, ForceGeometry_t force)
|
||||
{
|
||||
Q_ASSERT(pendingGeometryUpdate() == PendingGeometryNone || areGeometryUpdatesBlocked());
|
||||
QPoint p(x, y);
|
||||
if (!areGeometryUpdatesBlocked() && p != rules()->checkPosition(p)) {
|
||||
qCDebug(KWIN_CORE) << "forced position fail:" << p << ":" << rules()->checkPosition(p);
|
||||
}
|
||||
m_requestedFrameGeometry.moveTopLeft(p);
|
||||
m_requestedClientGeometry.moveTopLeft(framePosToClientPos(p));
|
||||
if (force == NormalGeometrySet && m_frameGeometry.topLeft() == p) {
|
||||
return;
|
||||
}
|
||||
m_frameGeometry.moveTopLeft(m_requestedFrameGeometry.topLeft());
|
||||
if (areGeometryUpdatesBlocked()) {
|
||||
if (pendingGeometryUpdate() == PendingGeometryForced) {
|
||||
return;
|
||||
}
|
||||
if (force == ForceGeometrySet) {
|
||||
setPendingGeometryUpdate(PendingGeometryForced);
|
||||
} else {
|
||||
setPendingGeometryUpdate(PendingGeometryNormal);
|
||||
}
|
||||
return;
|
||||
}
|
||||
m_clientGeometry.moveTopLeft(m_requestedClientGeometry.topLeft());
|
||||
m_bufferGeometry = frameRectToBufferRect(m_frameGeometry);
|
||||
updateWindowRules(Rules::Position);
|
||||
screens()->setCurrent(this);
|
||||
workspace()->updateStackingOrder();
|
||||
emit frameGeometryChanged(this, frameGeometryBeforeUpdateBlocking());
|
||||
addRepaintDuringGeometryUpdates();
|
||||
updateGeometryBeforeUpdateBlocking();
|
||||
}
|
||||
|
||||
void XdgSurfaceClient::requestGeometry(const QRect &rect)
|
||||
{
|
||||
m_requestedFrameGeometry = rect;
|
||||
m_requestedClientGeometry = frameRectToClientRect(rect);
|
||||
WaylandClient::requestGeometry(rect);
|
||||
|
||||
scheduleConfigure(); // Send the configure event later.
|
||||
}
|
||||
|
||||
void XdgSurfaceClient::updateGeometry(const QRect &rect)
|
||||
{
|
||||
const QRect oldClientGeometry = m_clientGeometry;
|
||||
const QRect oldFrameGeometry = m_frameGeometry;
|
||||
const QRect oldBufferGeometry = m_bufferGeometry;
|
||||
|
||||
m_clientGeometry = frameRectToClientRect(rect);
|
||||
m_frameGeometry = rect;
|
||||
m_bufferGeometry = frameRectToBufferRect(rect);
|
||||
|
||||
uint changedGeometries = 0;
|
||||
|
||||
if (m_clientGeometry != oldClientGeometry) {
|
||||
changedGeometries |= XdgSurfaceGeometryClient;
|
||||
}
|
||||
if (m_frameGeometry != oldFrameGeometry) {
|
||||
changedGeometries |= XdgSurfaceGeometryFrame;
|
||||
}
|
||||
if (m_bufferGeometry != oldBufferGeometry) {
|
||||
changedGeometries |= XdgSurfaceGeometryBuffer;
|
||||
}
|
||||
|
||||
if (!changedGeometries) {
|
||||
return;
|
||||
}
|
||||
|
||||
updateWindowRules(Rules::Position | Rules::Size);
|
||||
updateGeometryBeforeUpdateBlocking();
|
||||
|
||||
if (changedGeometries & XdgSurfaceGeometryBuffer) {
|
||||
emit bufferGeometryChanged(this, oldBufferGeometry);
|
||||
}
|
||||
if (changedGeometries & XdgSurfaceGeometryClient) {
|
||||
emit clientGeometryChanged(this, oldClientGeometry);
|
||||
}
|
||||
if (changedGeometries & XdgSurfaceGeometryFrame) {
|
||||
emit frameGeometryChanged(this, oldFrameGeometry);
|
||||
}
|
||||
emit geometryShapeChanged(this, oldFrameGeometry);
|
||||
|
||||
addRepaintDuringGeometryUpdates();
|
||||
}
|
||||
|
||||
/**
|
||||
* \internal
|
||||
* \todo We have to check the current frame geometry in checkWorskpacePosition().
|
||||
|
@ -492,8 +323,8 @@ QRect XdgSurfaceClient::frameRectToBufferRect(const QRect &rect) const
|
|||
|
||||
void XdgSurfaceClient::addDamage(const QRegion &damage)
|
||||
{
|
||||
const int offsetX = m_bufferGeometry.x() - m_frameGeometry.x();
|
||||
const int offsetY = m_bufferGeometry.y() - m_frameGeometry.y();
|
||||
const int offsetX = bufferGeometry().x() - frameGeometry().x();
|
||||
const int offsetY = bufferGeometry().y() - frameGeometry().y();
|
||||
repaints_region += damage.translated(offsetX, offsetY);
|
||||
Toplevel::addDamage(damage);
|
||||
}
|
||||
|
|
|
@ -53,26 +53,17 @@ public:
|
|||
explicit XdgSurfaceClient(KWaylandServer::XdgSurfaceInterface *shellSurface);
|
||||
~XdgSurfaceClient() override;
|
||||
|
||||
QRect frameRectToBufferRect(const QRect &rect) const override;
|
||||
QRect inputGeometry() const override;
|
||||
QRect bufferGeometry() const override;
|
||||
QMatrix4x4 inputTransformation() const override;
|
||||
void setFrameGeometry(const QRect &rect, ForceGeometry_t force = NormalGeometrySet) override;
|
||||
using AbstractClient::move;
|
||||
void move(int x, int y, ForceGeometry_t force = NormalGeometrySet) override;
|
||||
bool isInitialPositionSet() const override;
|
||||
void destroyClient() override;
|
||||
void setVirtualKeyboardGeometry(const QRect &geo) override;
|
||||
|
||||
QRect frameRectToBufferRect(const QRect &rect) const;
|
||||
QRect requestedFrameGeometry() const;
|
||||
QPoint requestedPos() const;
|
||||
QSize requestedSize() const;
|
||||
QRect requestedClientGeometry() const;
|
||||
QSize requestedClientSize() const;
|
||||
|
||||
virtual void installPlasmaShellSurface(KWaylandServer::PlasmaShellSurfaceInterface *shellSurface) = 0;
|
||||
|
||||
protected:
|
||||
void requestGeometry(const QRect &rect) override;
|
||||
void addDamage(const QRegion &damage) override;
|
||||
|
||||
virtual XdgSurfaceConfigure *sendRoleConfigure() const = 0;
|
||||
|
@ -82,8 +73,6 @@ protected:
|
|||
XdgSurfaceConfigure *lastAcknowledgedConfigure() const;
|
||||
void scheduleConfigure();
|
||||
void sendConfigure();
|
||||
void requestGeometry(const QRect &rect);
|
||||
void updateGeometry(const QRect &rect);
|
||||
|
||||
QPointer<KWaylandServer::PlasmaShellSurfaceInterface> m_plasmaShellSurface;
|
||||
|
||||
|
@ -104,9 +93,6 @@ private:
|
|||
QQueue<XdgSurfaceConfigure *> m_configureEvents;
|
||||
QScopedPointer<XdgSurfaceConfigure> m_lastAcknowledgedConfigure;
|
||||
QRect m_windowGeometry;
|
||||
QRect m_requestedFrameGeometry;
|
||||
QRect m_bufferGeometry;
|
||||
QRect m_requestedClientGeometry;
|
||||
bool m_haveNextWindowGeometry = false;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue