diff --git a/CMakeLists.txt b/CMakeLists.txt index ebad20aca9..7d3e7bde23 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -421,6 +421,7 @@ endif() if(HAVE_WAYLAND) set(kwin_KDEINIT_SRCS ${kwin_KDEINIT_SRCS} + abstract_backend.cpp screens_wayland.cpp screens_x11windowed.cpp wayland_backend.cpp diff --git a/abstract_backend.cpp b/abstract_backend.cpp new file mode 100644 index 0000000000..6ce90d71ee --- /dev/null +++ b/abstract_backend.cpp @@ -0,0 +1,46 @@ +/******************************************************************** + KWin - the KDE window manager + This file is part of the KDE project. + +Copyright (C) 2015 Martin Gräßlin + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*********************************************************************/ +#include "abstract_backend.h" +#include "wayland_server.h" + +namespace KWin +{ + +AbstractBackend::AbstractBackend(QObject *parent) + : QObject(parent) +{ + WaylandServer::self()->installBackend(this); +} + +AbstractBackend::~AbstractBackend() +{ + WaylandServer::self()->uninstallBackend(this); +} + +void AbstractBackend::installCursorFromServer() +{ +} + +void AbstractBackend::installCursorImage(Qt::CursorShape shape) +{ + Q_UNUSED(shape) +} + +} diff --git a/abstract_backend.h b/abstract_backend.h new file mode 100644 index 0000000000..9136f088b1 --- /dev/null +++ b/abstract_backend.h @@ -0,0 +1,42 @@ +/******************************************************************** + KWin - the KDE window manager + This file is part of the KDE project. + +Copyright (C) 2015 Martin Gräßlin + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*********************************************************************/ +#ifndef KWIN_ABSTRACT_BACKEND_H +#define KWIN_ABSTRACT_BACKEND_H +#include + +namespace KWin +{ + +class AbstractBackend : public QObject +{ + Q_OBJECT +public: + virtual ~AbstractBackend(); + + virtual void installCursorFromServer(); + virtual void installCursorImage(Qt::CursorShape shape); + +protected: + explicit AbstractBackend(QObject *parent = nullptr); +}; + +} + +#endif diff --git a/effects.cpp b/effects.cpp index 4555fb8347..20a8773044 100644 --- a/effects.cpp +++ b/effects.cpp @@ -56,7 +56,8 @@ along with this program. If not, see . #include "composite.h" #include "xcbutils.h" #if HAVE_WAYLAND -#include "wayland_backend.h" +#include "abstract_backend.h" +#include "wayland_server.h" #endif #include "decorations/decorationbridge.h" @@ -673,7 +674,7 @@ void EffectsHandlerImpl::startMouseInterception(Effect *effect, Qt::CursorShape } if (kwinApp()->operationMode() != Application::OperationModeX11) { #if HAVE_WAYLAND - if (Wayland::WaylandBackend *w = Wayland::WaylandBackend::self()) { + if (AbstractBackend *w = waylandServer()->backend()) { w->installCursorImage(shape); } #endif @@ -1171,8 +1172,10 @@ void EffectsHandlerImpl::defineCursor(Qt::CursorShape shape) { if (!m_mouseInterceptionWindow.isValid()) { #if HAVE_WAYLAND - if (Wayland::WaylandBackend *w = Wayland::WaylandBackend::self()) { - w->installCursorImage(shape); + if (waylandServer()) { + if (AbstractBackend *w = waylandServer()->backend()) { + w->installCursorImage(shape); + } } #endif return; diff --git a/input.cpp b/input.cpp index 1339405ed7..6a18617c7c 100644 --- a/input.cpp +++ b/input.cpp @@ -33,9 +33,8 @@ along with this program. If not, see . #include "libinput/connection.h" #endif #if HAVE_WAYLAND -#include "wayland_backend.h" +#include "abstract_backend.h" #include "wayland_server.h" -#include "x11windowed_backend.h" #include #endif // Qt @@ -256,25 +255,6 @@ static KWayland::Server::SeatInterface *findSeat() } #endif -template -static -void disconnectSeat(KWayland::Server::SeatInterface *seat) -{ - if (T *w = T::self()) { - QObject::disconnect(seat->focusedPointer()->cursor(), &KWayland::Server::Cursor::changed, w, &T::installCursorFromServer); - } -} - -template -static -void connectSeat(KWayland::Server::SeatInterface *seat) -{ - if (T *w = T::self()) { - w->installCursorFromServer(); - QObject::connect(seat->focusedPointer()->cursor(), &KWayland::Server::Cursor::changed, w, &T::installCursorFromServer); - } -} - void InputRedirection::updatePointerWindow() { // TODO: handle pointer grab aka popups @@ -288,14 +268,17 @@ void InputRedirection::updatePointerWindow() // disconnect old surface if (oldWindow) { disconnect(oldWindow.data(), &Toplevel::geometryChanged, this, &InputRedirection::updateFocusedPointerPosition); - disconnectSeat(seat); - disconnectSeat(seat); + if (AbstractBackend *b = waylandServer()->backend()) { + disconnect(seat->focusedPointer()->cursor(), &KWayland::Server::Cursor::changed, b, &AbstractBackend::installCursorFromServer); + } } if (t && t->surface()) { seat->setFocusedPointerSurface(t->surface(), t->pos()); connect(t, &Toplevel::geometryChanged, this, &InputRedirection::updateFocusedPointerPosition); - connectSeat(seat); - connectSeat(seat); + if (AbstractBackend *b = waylandServer()->backend()) { + b->installCursorFromServer(); + connect(seat->focusedPointer()->cursor(), &KWayland::Server::Cursor::changed, b, &AbstractBackend::installCursorFromServer); + } } else { seat->setFocusedPointerSurface(nullptr); t = nullptr; diff --git a/wayland_backend.cpp b/wayland_backend.cpp index f04d903ba0..b6cbbad8e2 100644 --- a/wayland_backend.cpp +++ b/wayland_backend.cpp @@ -354,7 +354,7 @@ WaylandBackend *WaylandBackend::create(QObject *parent) } WaylandBackend::WaylandBackend(QObject *parent) - : QObject(parent) + : AbstractBackend(parent) , m_display(nullptr) , m_eventQueue(new EventQueue(this)) , m_registry(new Registry(this)) diff --git a/wayland_backend.h b/wayland_backend.h index 337a9858fb..8a9bfaadc4 100644 --- a/wayland_backend.h +++ b/wayland_backend.h @@ -20,6 +20,7 @@ along with this program. If not, see . #ifndef KWIN_WAYLAND_BACKEND_H #define KWIN_WAYLAND_BACKEND_H // KWin +#include "abstract_backend.h" #include // Qt #include @@ -141,7 +142,7 @@ private: * It creates the connection to the Wayland Compositor, sets up the registry and creates * the Wayland surface and its shell mapping. */ -class KWIN_EXPORT WaylandBackend : public QObject +class KWIN_EXPORT WaylandBackend : public AbstractBackend { Q_OBJECT public: @@ -154,8 +155,8 @@ public: KWayland::Client::Surface *surface() const; QSize shellSurfaceSize() const; - void installCursorImage(Qt::CursorShape shape); - void installCursorFromServer(); + void installCursorImage(Qt::CursorShape shape) override; + void installCursorFromServer() override; protected: void connectNotify(const QMetaMethod &signal) override; diff --git a/wayland_server.cpp b/wayland_server.cpp index 8da86fd3b1..0df87b0226 100644 --- a/wayland_server.cpp +++ b/wayland_server.cpp @@ -113,4 +113,16 @@ int WaylandServer::createQtConnection() return sx[1]; } +void WaylandServer::installBackend(AbstractBackend *backend) +{ + Q_ASSERT(!m_backend); + m_backend = backend; +} + +void WaylandServer::uninstallBackend(AbstractBackend *backend) +{ + Q_ASSERT(m_backend == backend); + m_backend = nullptr; +} + } diff --git a/wayland_server.h b/wayland_server.h index 3bc120c657..2149cd6ec8 100644 --- a/wayland_server.h +++ b/wayland_server.h @@ -40,6 +40,8 @@ class OutputInterface; namespace KWin { +class AbstractBackend; + class KWIN_EXPORT WaylandServer : public QObject { Q_OBJECT @@ -61,6 +63,12 @@ public: return m_shell; } + AbstractBackend *backend() const { + return m_backend; + } + void installBackend(AbstractBackend *backend); + void uninstallBackend(AbstractBackend *backend); + /** * @returns file descriptor for Xwayland to connect to. **/ @@ -78,6 +86,7 @@ private: KWayland::Server::ShellInterface *m_shell = nullptr; KWayland::Server::ClientConnection *m_xwaylandConnection = nullptr; KWayland::Server::ClientConnection *m_qtConnection = nullptr; + AbstractBackend *m_backend = nullptr; KWIN_SINGLETON(WaylandServer) }; diff --git a/x11windowed_backend.cpp b/x11windowed_backend.cpp index d9f6ed3209..43d656dedf 100644 --- a/x11windowed_backend.cpp +++ b/x11windowed_backend.cpp @@ -51,7 +51,7 @@ X11WindowedBackend *X11WindowedBackend::create(const QString &display, const QSi } X11WindowedBackend::X11WindowedBackend(const QString &display, const QSize &size, QObject *parent) - : QObject(parent) + : AbstractBackend(parent) , m_size(size) { int screen = 0; diff --git a/x11windowed_backend.h b/x11windowed_backend.h index e93235d16a..799964b6a1 100644 --- a/x11windowed_backend.h +++ b/x11windowed_backend.h @@ -19,6 +19,7 @@ along with this program. If not, see . *********************************************************************/ #ifndef KWIN_X11WINDOWED_BACKEND_H #define KWIN_X11WINDOWED_BACKEND_H +#include "abstract_backend.h" #include @@ -33,7 +34,7 @@ typedef struct _XDisplay Display; namespace KWin { -class KWIN_EXPORT X11WindowedBackend : public QObject +class KWIN_EXPORT X11WindowedBackend : public AbstractBackend { Q_OBJECT Q_PROPERTY(QSize size READ size NOTIFY sizeChanged) @@ -62,7 +63,7 @@ public: return m_size; } - void installCursorFromServer(); + void installCursorFromServer() override; static X11WindowedBackend *self(); static X11WindowedBackend *create(const QString &display, const QSize &size, QObject *parent);