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