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 "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<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) {
(*it)->reserve();
}
@ -662,7 +700,7 @@ void ScreenEdges::setActionForBorder(ElectricBorder border, ElectricBorderAction
}
if (newValue == ElectricActionNone) {
// 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) {
(*it)->unreserve();
}
@ -670,7 +708,7 @@ void ScreenEdges::setActionForBorder(ElectricBorder border, ElectricBorderAction
}
*oldValue = newValue;
// 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) {
(*it)->setAction(newValue);
}
@ -801,7 +839,7 @@ static bool isBottomScreen(const QRect &screen, const QRect &fullArea)
void ScreenEdges::recreateEdges()
{
QList<WindowBasedEdge*> oldEdges(m_edges);
QList<Edge*> oldEdges(m_edges);
m_edges.clear();
const QRect fullArea(0, 0, displayWidth(), displayHeight());
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
for (QList<WindowBasedEdge*>::iterator it = m_edges.begin(); it != m_edges.end(); ++it) {
WindowBasedEdge *edge = *it;
for (QList<WindowBasedEdge*>::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<WindowBasedEdge*>::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<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) {
(*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<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) {
(*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<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()) {
continue;
}
@ -1150,8 +1193,11 @@ bool ScreenEdges::handleEnterNotifiy(xcb_window_t window, const QPoint &point, c
{
bool activated = false;
bool activatedForClient = false;
for (QList<WindowBasedEdge*>::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<WindowBasedEdge*>(*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<WindowBasedEdge*>::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<WindowBasedEdge*>(*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<xcb_window_t> wins;
for (QList<WindowBasedEdge*>::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<WindowBasedEdge*>(*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);
}

View file

@ -66,6 +66,7 @@ public:
const QHash<QObject *, QByteArray> &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 &timestamp);
@ -358,7 +370,7 @@ private:
int m_timeThreshold;
int m_reactivateThreshold;
Qt::Orientations m_virtualDesktopLayout;
QList<WindowBasedEdge*> m_edges;
QList<Edge*> 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
*********************************************************/