Commit 7d152991 authored by Martin Flöser's avatar Martin Flöser

[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.
parent 31cc2628
......@@ -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;
}
......
......@@ -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;
}
}
}
......@@ -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;
};
}
......
......@@ -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;
}
}
......@@ -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;
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment