[wayland] ShellClient can reference an internal QWindow

If the ShellClient got created for a Qt internal window, we try to
find the QWindow and if we get one, we use the geometry directly as
it got set by KWin in the first place.

Also a windowId() is added to ShellClient which can be used by the
effect system to find an EffectWindow. If it's an internal QWindow
we just use that window id. For other clients we still need some
smart solution.
This commit is contained in:
Martin Gräßlin 2015-05-18 14:51:40 +02:00
parent 31cc2628cc
commit 7d152991c7
5 changed files with 72 additions and 1 deletions

View file

@ -1032,6 +1032,13 @@ EffectWindow* EffectsHandlerImpl::findWindow(WId id) const
return w->effectWindow();
if (Unmanaged* w = Workspace::self()->findUnmanaged(id))
return w->effectWindow();
#if HAVE_WAYLAND
if (waylandServer()) {
if (ShellClient *w = waylandServer()->findClient(id)) {
return w->effectWindow();
}
}
#endif
return NULL;
}

View file

@ -22,10 +22,13 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "wayland_server.h"
#include "virtualdesktops.h"
#include <KWayland/Client/surface.h>
#include <KWayland/Server/shell_interface.h>
#include <KWayland/Server/surface_interface.h>
#include <KWayland/Server/buffer_interface.h>
#include <QWindow>
using namespace KWayland::Server;
namespace KWin
@ -36,6 +39,8 @@ ShellClient::ShellClient(ShellSurfaceInterface *surface)
, m_shellSurface(surface)
{
setSurface(surface->surface());
findInternalWindow();
createWindowId();
setupCompositing();
if (surface->surface()->buffer()) {
setReadyForPainting();
@ -43,7 +48,11 @@ ShellClient::ShellClient(ShellSurfaceInterface *surface)
} else {
ready_for_painting = false;
}
setGeometry(QRect(QPoint(0, 0), m_clientSize));
if (m_internalWindow) {
setGeometry(m_internalWindow->geometry());
} else {
setGeometry(QRect(QPoint(0, 0), m_clientSize));
}
setDesktop(VirtualDesktopManager::self()->current());
@ -329,4 +338,31 @@ bool ShellClient::wantsInput() const
return true;
}
void ShellClient::createWindowId()
{
if (m_internalWindow) {
m_windowId = m_internalWindow->winId();
}
// TODO: create internal window ids
}
void ShellClient::findInternalWindow()
{
if (m_shellSurface->client() != waylandServer()->qtConnection()) {
return;
}
const QWindowList windows = kwinApp()->topLevelWindows();
for (QWindow *w: windows) {
QScopedPointer<KWayland::Client::Surface> s(KWayland::Client::Surface::fromWindow(w));
if (!s) {
continue;
}
if (s->id() != surface()->id()) {
continue;
}
m_internalWindow = w;
return;
}
}
}

View file

@ -87,6 +87,10 @@ public:
bool userCanSetNoBorder() const override;
bool wantsInput() const override;
quint32 windowId() const {
return m_windowId;
}
protected:
void addDamage(const QRegion &damage) override;
bool belongsToSameApplication(const AbstractClient *other, bool active_hack) const override;
@ -94,11 +98,15 @@ protected:
private:
void setGeometry(const QRect &rect);
void destroyClient();
void createWindowId();
void findInternalWindow();
static void deleteClient(ShellClient *c);
KWayland::Server::ShellSurfaceInterface *m_shellSurface;
QSize m_clientSize;
bool m_closing = false;
quint32 m_windowId = 0;
QWindow *m_internalWindow = nullptr;
};
}

View file

@ -261,4 +261,20 @@ void WaylandServer::dispatch()
m_display->dispatchEvents(0);
}
ShellClient *WaylandServer::findClient(quint32 id) const
{
if (id == 0) {
return nullptr;
}
auto it = std::find_if(m_clients.constBegin(), m_clients.constEnd(),
[id] (ShellClient *c) {
return c->windowId() == id;
}
);
if (it == m_clients.constEnd()) {
return nullptr;
}
return *it;
}
}

View file

@ -75,6 +75,7 @@ public:
return m_clients;
}
void removeClient(ShellClient *c);
ShellClient *findClient(quint32 id) const;
AbstractBackend *backend() const {
return m_backend;
@ -97,6 +98,9 @@ public:
KWayland::Server::ClientConnection *xWaylandConnection() const {
return m_xwaylandConnection;
}
KWayland::Server::ClientConnection *qtConnection() const {
return m_qtConnection;
}
KWayland::Server::ClientConnection *internalConnection() const {
return m_internalConnection.server;
}