[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:
parent
31cc2628cc
commit
7d152991c7
5 changed files with 72 additions and 1 deletions
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue