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 *********************************************************/