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.
This commit is contained in:
Martin Gräßlin 2013-06-26 10:25:17 +02:00
parent 1617deabb8
commit 940d9fb513
2 changed files with 95 additions and 25 deletions

View file

@ -34,6 +34,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "client.h" #include "client.h"
#include "cursor.h" #include "cursor.h"
#include "effects.h" #include "effects.h"
#include "input.h"
#include "main.h"
#include "screens.h" #include "screens.h"
#include "utils.h" #include "utils.h"
#include "workspace.h" #include "workspace.h"
@ -547,6 +549,42 @@ void WindowBasedEdge::doUpdateBlocking()
m_approachWindow.map(); 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 * ScreenEdges
@ -654,7 +692,7 @@ void ScreenEdges::setActionForBorder(ElectricBorder border, ElectricBorderAction
} }
if (*oldValue == ElectricActionNone) { if (*oldValue == ElectricActionNone) {
// have to reserve // have to reserve
for (QList<WindowBasedEdge*>::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) { if ((*it)->border() == border) {
(*it)->reserve(); (*it)->reserve();
} }
@ -662,7 +700,7 @@ void ScreenEdges::setActionForBorder(ElectricBorder border, ElectricBorderAction
} }
if (newValue == ElectricActionNone) { if (newValue == ElectricActionNone) {
// have to unreserve // have to unreserve
for (QList<WindowBasedEdge*>::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) { if ((*it)->border() == border) {
(*it)->unreserve(); (*it)->unreserve();
} }
@ -670,7 +708,7 @@ void ScreenEdges::setActionForBorder(ElectricBorder border, ElectricBorderAction
} }
*oldValue = newValue; *oldValue = newValue;
// update action on all Edges for given border // update action on all Edges for given border
for (QList<WindowBasedEdge*>::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) { if ((*it)->border() == border) {
(*it)->setAction(newValue); (*it)->setAction(newValue);
} }
@ -801,7 +839,7 @@ static bool isBottomScreen(const QRect &screen, const QRect &fullArea)
void ScreenEdges::recreateEdges() void ScreenEdges::recreateEdges()
{ {
QList<WindowBasedEdge*> oldEdges(m_edges); QList<Edge*> oldEdges(m_edges);
m_edges.clear(); m_edges.clear();
const QRect fullArea(0, 0, displayWidth(), displayHeight()); const QRect fullArea(0, 0, displayWidth(), displayHeight());
for (int i=0; i<screens()->count(); ++i) { for (int i=0; i<screens()->count(); ++i) {
@ -824,12 +862,12 @@ void ScreenEdges::recreateEdges()
} }
} }
// copy over the effect/script reservations from the old edges // copy over the effect/script reservations from the old edges
for (QList<WindowBasedEdge*>::iterator it = m_edges.begin(); it != m_edges.end(); ++it) { for (auto it = m_edges.begin(); it != m_edges.end(); ++it) {
WindowBasedEdge *edge = *it; Edge *edge = *it;
for (QList<WindowBasedEdge*>::const_iterator oldIt = oldEdges.constBegin(); for (auto oldIt = oldEdges.constBegin();
oldIt != oldEdges.constEnd(); oldIt != oldEdges.constEnd();
++oldIt) { ++oldIt) {
WindowBasedEdge *oldEdge = *oldIt; Edge *oldEdge = *oldIt;
if (oldEdge->client()) { if (oldEdge->client()) {
// show the client again and don't recreate the edge // show the client again and don't recreate the edge
oldEdge->client()->showOnScreenEdge(); oldEdge->client()->showOnScreenEdge();
@ -896,9 +934,14 @@ void ScreenEdges::createHorizontalEdge(ElectricBorder border, const QRect &scree
m_edges << createEdge(border, x, y, width, 1); 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->setBorder(border);
edge->setGeometry(QRect(x, y, width, height)); edge->setGeometry(QRect(x, y, width, height));
if (createAction) { if (createAction) {
@ -957,8 +1000,8 @@ void ScreenEdges::reserveDesktopSwitching(bool isToReserve, Qt::Orientations o)
{ {
if (!o) if (!o)
return; return;
for (QList<WindowBasedEdge*>::iterator it = m_edges.begin(); it != m_edges.end(); ++it) { for (auto it = m_edges.begin(); it != m_edges.end(); ++it) {
WindowBasedEdge *edge = *it; Edge *edge = *it;
if (edge->isCorner()) { if (edge->isCorner()) {
isToReserve ? edge->reserve() : edge->unreserve(); isToReserve ? edge->reserve() : edge->unreserve();
} else { } else {
@ -974,7 +1017,7 @@ void ScreenEdges::reserveDesktopSwitching(bool isToReserve, Qt::Orientations o)
void ScreenEdges::reserve(ElectricBorder border, QObject *object, const char *slot) void ScreenEdges::reserve(ElectricBorder border, QObject *object, const char *slot)
{ {
for (QList<WindowBasedEdge*>::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) { if ((*it)->border() == border) {
(*it)->reserve(object, slot); (*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) void ScreenEdges::unreserve(ElectricBorder border, QObject *object)
{ {
for (QList<WindowBasedEdge*>::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) { if ((*it)->border() == border) {
(*it)->unreserve(object); (*it)->unreserve(object);
} }
@ -1076,7 +1119,7 @@ void ScreenEdges::createEdgeForClient(Client *client, ElectricBorder border)
} }
if (width > 0 && height > 0) { 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); edge->setClient(client);
m_edges.append(edge); m_edges.append(edge);
if (client->isHiddenInternal()) { if (client->isHiddenInternal()) {
@ -1111,7 +1154,7 @@ void ScreenEdges::deleteEdgeForClient(Client* c)
void ScreenEdges::check(const QPoint &pos, const QDateTime &now, bool forceNoPushBack) void ScreenEdges::check(const QPoint &pos, const QDateTime &now, bool forceNoPushBack)
{ {
bool activatedForClient = false; bool activatedForClient = false;
for (QList<WindowBasedEdge*>::iterator it = m_edges.begin(); it != m_edges.end(); ++it) { for (auto it = m_edges.begin(); it != m_edges.end(); ++it) {
if (!(*it)->isReserved()) { if (!(*it)->isReserved()) {
continue; continue;
} }
@ -1150,8 +1193,11 @@ bool ScreenEdges::handleEnterNotifiy(xcb_window_t window, const QPoint &point, c
{ {
bool activated = false; bool activated = false;
bool activatedForClient = false; bool activatedForClient = false;
for (QList<WindowBasedEdge*>::iterator it = m_edges.begin(); it != m_edges.end(); ++it) { for (auto it = m_edges.begin(); it != m_edges.end(); ++it) {
WindowBasedEdge *edge = *it; WindowBasedEdge *edge = dynamic_cast<WindowBasedEdge*>(*it);
if (!edge) {
continue;
}
if (!edge->isReserved()) { if (!edge->isReserved()) {
continue; 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) bool ScreenEdges::handleDndNotify(xcb_window_t window, const QPoint &point)
{ {
for (QList<WindowBasedEdge*>::iterator it = m_edges.begin(); it != m_edges.end(); ++it) { for (auto it = m_edges.begin(); it != m_edges.end(); ++it) {
WindowBasedEdge *edge = *it; WindowBasedEdge *edge = dynamic_cast<WindowBasedEdge*>(*it);
if (!edge) {
continue;
}
if (edge->isReserved() && edge->window() == window) { if (edge->isReserved() && edge->window() == window) {
updateXTime(); updateXTime();
edge->check(point, QDateTime::fromMSecsSinceEpoch(xTime()), true); edge->check(point, QDateTime::fromMSecsSinceEpoch(xTime()), true);
@ -1201,15 +1250,19 @@ void ScreenEdges::ensureOnTop()
QVector< xcb_window_t > ScreenEdges::windows() const QVector< xcb_window_t > ScreenEdges::windows() const
{ {
QVector<xcb_window_t> wins; QVector<xcb_window_t> wins;
for (QList<WindowBasedEdge*>::const_iterator it = m_edges.constBegin(); for (auto it = m_edges.constBegin();
it != m_edges.constEnd(); it != m_edges.constEnd();
++it) { ++it) {
xcb_window_t w = (*it)->window(); WindowBasedEdge *edge = dynamic_cast<WindowBasedEdge*>(*it);
if (!edge) {
continue;
}
xcb_window_t w = edge->window();
if (w != XCB_WINDOW_NONE) { if (w != XCB_WINDOW_NONE) {
wins.append(w); wins.append(w);
} }
// TODO: lambda // TODO: lambda
w = (*it)->approachWindow(); w = edge->approachWindow();
if (w != XCB_WINDOW_NONE) { if (w != XCB_WINDOW_NONE) {
wins.append(w); wins.append(w);
} }

View file

@ -66,6 +66,7 @@ public:
const QHash<QObject *, QByteArray> &callBacks() const; const QHash<QObject *, QByteArray> &callBacks() const;
void startApproaching(); void startApproaching();
void stopApproaching(); void stopApproaching();
bool isApproaching() const;
void setClient(Client *client); void setClient(Client *client);
Client *client() const; Client *client() const;
@ -143,6 +144,17 @@ private:
Xcb::Window m_approachWindow; 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. * @short Class for controlling screen edges.
* *
@ -344,7 +356,7 @@ private:
void setReActivationThreshold(int threshold); void setReActivationThreshold(int threshold);
void createHorizontalEdge(ElectricBorder border, const QRect &screen, const QRect &fullArea); void createHorizontalEdge(ElectricBorder border, const QRect &screen, const QRect &fullArea);
void createVerticalEdge(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); void setActionForBorder(ElectricBorder border, ElectricBorderAction *oldValue, ElectricBorderAction newValue);
ElectricBorderAction actionForEdge(Edge *edge) const; ElectricBorderAction actionForEdge(Edge *edge) const;
bool handleEnterNotifiy(xcb_window_t window, const QPoint &point, const QDateTime &timestamp); bool handleEnterNotifiy(xcb_window_t window, const QPoint &point, const QDateTime &timestamp);
@ -358,7 +370,7 @@ private:
int m_timeThreshold; int m_timeThreshold;
int m_reactivateThreshold; int m_reactivateThreshold;
Qt::Orientations m_virtualDesktopLayout; Qt::Orientations m_virtualDesktopLayout;
QList<WindowBasedEdge*> m_edges; QList<Edge*> m_edges;
KSharedConfig::Ptr m_config; KSharedConfig::Ptr m_config;
ElectricBorderAction m_actionTopLeft; ElectricBorderAction m_actionTopLeft;
ElectricBorderAction m_actionTop; ElectricBorderAction m_actionTop;
@ -473,6 +485,11 @@ inline Client *Edge::client() const
return m_client; return m_client;
} }
inline bool Edge::isApproaching() const
{
return m_approaching;
}
/********************************************************** /**********************************************************
* Inlines WindowBasedEdge * Inlines WindowBasedEdge
*********************************************************/ *********************************************************/