From 940d9fb513bb276284da31b150df06e5acf023ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Wed, 26 Jun 2013 10:25:17 +0200 Subject: [PATCH] ScreenEdges which do not need X windows A new AreaBasedEdge is introduced which supports the Edge functionality by just connecting to the globalPointerChanged signal of InputRedirection. The AreaBasedEdges are used if KWin's operation mode is not X11 only. This unfortunately required to change the datatype of the list of edges in ScreenEdges. It used to be specific on the inheriting class. --- screenedge.cpp | 99 ++++++++++++++++++++++++++++++++++++++------------ screenedge.h | 21 ++++++++++- 2 files changed, 95 insertions(+), 25 deletions(-) diff --git a/screenedge.cpp b/screenedge.cpp index 3c3d1d3ee7..cf2f0727e1 100644 --- a/screenedge.cpp +++ b/screenedge.cpp @@ -34,6 +34,8 @@ along with this program. If not, see . #include "client.h" #include "cursor.h" #include "effects.h" +#include "input.h" +#include "main.h" #include "screens.h" #include "utils.h" #include "workspace.h" @@ -547,6 +549,42 @@ void WindowBasedEdge::doUpdateBlocking() m_approachWindow.map(); } } +/********************************************************** + * AreaBasedEdge + *********************************************************/ +AreaBasedEdge::AreaBasedEdge(ScreenEdges* parent) + : Edge(parent) +{ + connect(input(), SIGNAL(globalPointerChanged(QPointF)), SLOT(pointerPosChanged(QPointF))); +} + +AreaBasedEdge::~AreaBasedEdge() +{ +} + +void AreaBasedEdge::pointerPosChanged(const QPointF &pos) +{ + if (!isReserved()) { + return; + } + const QPoint p = pos.toPoint(); + if (approachGeometry().contains(p)) { + if (!isApproaching()) { + startApproaching(); + } else { + updateApproaching(p); + } + } else { + if (isApproaching()) { + stopApproaching(); + } + } + if (geometry().contains(p)) { + // we don't push the cursor back as pointer warping is not supported on Wayland + // TODO: this clearly needs improving + check(p, QDateTime(), true); + } +} /********************************************************** * ScreenEdges @@ -654,7 +692,7 @@ void ScreenEdges::setActionForBorder(ElectricBorder border, ElectricBorderAction } if (*oldValue == ElectricActionNone) { // have to reserve - for (QList::iterator it = m_edges.begin(); it != m_edges.end(); ++it) { + for (auto it = m_edges.begin(); it != m_edges.end(); ++it) { if ((*it)->border() == border) { (*it)->reserve(); } @@ -662,7 +700,7 @@ void ScreenEdges::setActionForBorder(ElectricBorder border, ElectricBorderAction } if (newValue == ElectricActionNone) { // have to unreserve - for (QList::iterator it = m_edges.begin(); it != m_edges.end(); ++it) { + for (auto it = m_edges.begin(); it != m_edges.end(); ++it) { if ((*it)->border() == border) { (*it)->unreserve(); } @@ -670,7 +708,7 @@ void ScreenEdges::setActionForBorder(ElectricBorder border, ElectricBorderAction } *oldValue = newValue; // update action on all Edges for given border - for (QList::iterator it = m_edges.begin(); it != m_edges.end(); ++it) { + for (auto it = m_edges.begin(); it != m_edges.end(); ++it) { if ((*it)->border() == border) { (*it)->setAction(newValue); } @@ -801,7 +839,7 @@ static bool isBottomScreen(const QRect &screen, const QRect &fullArea) void ScreenEdges::recreateEdges() { - QList oldEdges(m_edges); + QList oldEdges(m_edges); m_edges.clear(); const QRect fullArea(0, 0, displayWidth(), displayHeight()); for (int i=0; icount(); ++i) { @@ -824,12 +862,12 @@ void ScreenEdges::recreateEdges() } } // copy over the effect/script reservations from the old edges - for (QList::iterator it = m_edges.begin(); it != m_edges.end(); ++it) { - WindowBasedEdge *edge = *it; - for (QList::const_iterator oldIt = oldEdges.constBegin(); + for (auto it = m_edges.begin(); it != m_edges.end(); ++it) { + Edge *edge = *it; + for (auto oldIt = oldEdges.constBegin(); oldIt != oldEdges.constEnd(); ++oldIt) { - WindowBasedEdge *oldEdge = *oldIt; + Edge *oldEdge = *oldIt; if (oldEdge->client()) { // show the client again and don't recreate the edge oldEdge->client()->showOnScreenEdge(); @@ -896,9 +934,14 @@ void ScreenEdges::createHorizontalEdge(ElectricBorder border, const QRect &scree m_edges << createEdge(border, x, y, width, 1); } -WindowBasedEdge *ScreenEdges::createEdge(ElectricBorder border, int x, int y, int width, int height, bool createAction) +Edge *ScreenEdges::createEdge(ElectricBorder border, int x, int y, int width, int height, bool createAction) { - WindowBasedEdge *edge = new WindowBasedEdge(this); + Edge *edge; + if (kwinApp()->operationMode() == Application::OperationModeX11) { + edge = new WindowBasedEdge(this); + } else { + edge = new AreaBasedEdge(this); + } edge->setBorder(border); edge->setGeometry(QRect(x, y, width, height)); if (createAction) { @@ -957,8 +1000,8 @@ void ScreenEdges::reserveDesktopSwitching(bool isToReserve, Qt::Orientations o) { if (!o) return; - for (QList::iterator it = m_edges.begin(); it != m_edges.end(); ++it) { - WindowBasedEdge *edge = *it; + for (auto it = m_edges.begin(); it != m_edges.end(); ++it) { + Edge *edge = *it; if (edge->isCorner()) { isToReserve ? edge->reserve() : edge->unreserve(); } else { @@ -974,7 +1017,7 @@ void ScreenEdges::reserveDesktopSwitching(bool isToReserve, Qt::Orientations o) void ScreenEdges::reserve(ElectricBorder border, QObject *object, const char *slot) { - for (QList::iterator it = m_edges.begin(); it != m_edges.end(); ++it) { + for (auto it = m_edges.begin(); it != m_edges.end(); ++it) { if ((*it)->border() == border) { (*it)->reserve(object, slot); } @@ -983,7 +1026,7 @@ void ScreenEdges::reserve(ElectricBorder border, QObject *object, const char *sl void ScreenEdges::unreserve(ElectricBorder border, QObject *object) { - for (QList::iterator it = m_edges.begin(); it != m_edges.end(); ++it) { + for (auto it = m_edges.begin(); it != m_edges.end(); ++it) { if ((*it)->border() == border) { (*it)->unreserve(object); } @@ -1076,7 +1119,7 @@ void ScreenEdges::createEdgeForClient(Client *client, ElectricBorder border) } if (width > 0 && height > 0) { - WindowBasedEdge *edge = createEdge(border, x, y, width, height, false); + Edge *edge = createEdge(border, x, y, width, height, false); edge->setClient(client); m_edges.append(edge); if (client->isHiddenInternal()) { @@ -1111,7 +1154,7 @@ void ScreenEdges::deleteEdgeForClient(Client* c) void ScreenEdges::check(const QPoint &pos, const QDateTime &now, bool forceNoPushBack) { bool activatedForClient = false; - for (QList::iterator it = m_edges.begin(); it != m_edges.end(); ++it) { + for (auto it = m_edges.begin(); it != m_edges.end(); ++it) { if (!(*it)->isReserved()) { continue; } @@ -1150,8 +1193,11 @@ bool ScreenEdges::handleEnterNotifiy(xcb_window_t window, const QPoint &point, c { bool activated = false; bool activatedForClient = false; - for (QList::iterator it = m_edges.begin(); it != m_edges.end(); ++it) { - WindowBasedEdge *edge = *it; + for (auto it = m_edges.begin(); it != m_edges.end(); ++it) { + WindowBasedEdge *edge = dynamic_cast(*it); + if (!edge) { + continue; + } if (!edge->isReserved()) { continue; } @@ -1182,8 +1228,11 @@ bool ScreenEdges::handleEnterNotifiy(xcb_window_t window, const QPoint &point, c bool ScreenEdges::handleDndNotify(xcb_window_t window, const QPoint &point) { - for (QList::iterator it = m_edges.begin(); it != m_edges.end(); ++it) { - WindowBasedEdge *edge = *it; + for (auto it = m_edges.begin(); it != m_edges.end(); ++it) { + WindowBasedEdge *edge = dynamic_cast(*it); + if (!edge) { + continue; + } if (edge->isReserved() && edge->window() == window) { updateXTime(); edge->check(point, QDateTime::fromMSecsSinceEpoch(xTime()), true); @@ -1201,15 +1250,19 @@ void ScreenEdges::ensureOnTop() QVector< xcb_window_t > ScreenEdges::windows() const { QVector wins; - for (QList::const_iterator it = m_edges.constBegin(); + for (auto it = m_edges.constBegin(); it != m_edges.constEnd(); ++it) { - xcb_window_t w = (*it)->window(); + WindowBasedEdge *edge = dynamic_cast(*it); + if (!edge) { + continue; + } + xcb_window_t w = edge->window(); if (w != XCB_WINDOW_NONE) { wins.append(w); } // TODO: lambda - w = (*it)->approachWindow(); + w = edge->approachWindow(); if (w != XCB_WINDOW_NONE) { wins.append(w); } diff --git a/screenedge.h b/screenedge.h index d6db151ce0..524f4e2207 100644 --- a/screenedge.h +++ b/screenedge.h @@ -66,6 +66,7 @@ public: const QHash &callBacks() const; void startApproaching(); void stopApproaching(); + bool isApproaching() const; void setClient(Client *client); Client *client() const; @@ -143,6 +144,17 @@ private: Xcb::Window m_approachWindow; }; +class AreaBasedEdge : public Edge +{ + Q_OBJECT +public: + explicit AreaBasedEdge(ScreenEdges *parent); + virtual ~AreaBasedEdge(); + +private Q_SLOTS: + void pointerPosChanged(const QPointF &pos); +}; + /** * @short Class for controlling screen edges. * @@ -344,7 +356,7 @@ private: void setReActivationThreshold(int threshold); void createHorizontalEdge(ElectricBorder border, const QRect &screen, const QRect &fullArea); void createVerticalEdge(ElectricBorder border, const QRect &screen, const QRect &fullArea); - WindowBasedEdge *createEdge(ElectricBorder border, int x, int y, int width, int height, bool createAction = true); + Edge *createEdge(ElectricBorder border, int x, int y, int width, int height, bool createAction = true); void setActionForBorder(ElectricBorder border, ElectricBorderAction *oldValue, ElectricBorderAction newValue); ElectricBorderAction actionForEdge(Edge *edge) const; bool handleEnterNotifiy(xcb_window_t window, const QPoint &point, const QDateTime ×tamp); @@ -358,7 +370,7 @@ private: int m_timeThreshold; int m_reactivateThreshold; Qt::Orientations m_virtualDesktopLayout; - QList m_edges; + QList m_edges; KSharedConfig::Ptr m_config; ElectricBorderAction m_actionTopLeft; ElectricBorderAction m_actionTop; @@ -473,6 +485,11 @@ inline Client *Edge::client() const return m_client; } +inline bool Edge::isApproaching() const +{ + return m_approaching; +} + /********************************************************** * Inlines WindowBasedEdge *********************************************************/