Send output enter/leave events to surfaces
Summary: A surface has an API to know which screen(s) it's on, this is useful especially for knowing the scale it should render at. In practice Qt currently doesn't do anything with this information; but that's set to change. Test_helpers is changed as we need to create output objects in order for wl_surface to map them. Closes task T4467 Test Plan: Attached unit test. As mentioned above, it doesn't have any real world impact currently, so not a lot to test. Reviewers: #plasma, graesslin Reviewed By: #plasma, graesslin Subscribers: johanhelsing, graesslin, plasma-devel, kwin, #kwin Tags: #kwin Maniphest Tasks: T4467 Differential Revision: https://phabricator.kde.org/D7359
This commit is contained in:
parent
981662a6b5
commit
f0971532c9
3 changed files with 70 additions and 0 deletions
|
@ -29,6 +29,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#include <KWayland/Client/connection_thread.h>
|
#include <KWayland/Client/connection_thread.h>
|
||||||
#include <KWayland/Client/compositor.h>
|
#include <KWayland/Client/compositor.h>
|
||||||
#include <KWayland/Client/shell.h>
|
#include <KWayland/Client/shell.h>
|
||||||
|
#include <KWayland/Client/output.h>
|
||||||
#include <KWayland/Client/server_decoration.h>
|
#include <KWayland/Client/server_decoration.h>
|
||||||
#include <KWayland/Client/surface.h>
|
#include <KWayland/Client/surface.h>
|
||||||
#include <KWayland/Client/xdgshell.h>
|
#include <KWayland/Client/xdgshell.h>
|
||||||
|
@ -59,6 +60,8 @@ private Q_SLOTS:
|
||||||
void testMapUnmapMap();
|
void testMapUnmapMap();
|
||||||
void testDesktopPresenceChanged();
|
void testDesktopPresenceChanged();
|
||||||
void testTransientPositionAfterRemap();
|
void testTransientPositionAfterRemap();
|
||||||
|
void testWindowOutputs_data();
|
||||||
|
void testWindowOutputs();
|
||||||
void testMinimizeActiveWindow_data();
|
void testMinimizeActiveWindow_data();
|
||||||
void testMinimizeActiveWindow();
|
void testMinimizeActiveWindow();
|
||||||
void testFullscreen_data();
|
void testFullscreen_data();
|
||||||
|
@ -81,6 +84,8 @@ void TestShellClient::initTestCase()
|
||||||
{
|
{
|
||||||
qRegisterMetaType<KWin::ShellClient*>();
|
qRegisterMetaType<KWin::ShellClient*>();
|
||||||
qRegisterMetaType<KWin::AbstractClient*>();
|
qRegisterMetaType<KWin::AbstractClient*>();
|
||||||
|
qRegisterMetaType<KWayland::Client::Output*>();
|
||||||
|
|
||||||
QSignalSpy workspaceCreatedSpy(kwinApp(), &Application::workspaceCreated);
|
QSignalSpy workspaceCreatedSpy(kwinApp(), &Application::workspaceCreated);
|
||||||
QVERIFY(workspaceCreatedSpy.isValid());
|
QVERIFY(workspaceCreatedSpy.isValid());
|
||||||
kwinApp()->platform()->setInitialWindowSize(QSize(1280, 1024));
|
kwinApp()->platform()->setInitialWindowSize(QSize(1280, 1024));
|
||||||
|
@ -269,6 +274,52 @@ void TestShellClient::testTransientPositionAfterRemap()
|
||||||
QCOMPARE(transient->geometry(), QRect(c->geometry().topLeft() + QPoint(5, 10), QSize(50, 40)));
|
QCOMPARE(transient->geometry(), QRect(c->geometry().topLeft() + QPoint(5, 10), QSize(50, 40)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TestShellClient::testWindowOutputs_data()
|
||||||
|
{
|
||||||
|
QTest::addColumn<Test::ShellSurfaceType>("type");
|
||||||
|
|
||||||
|
QTest::newRow("wlShell") << Test::ShellSurfaceType::WlShell;
|
||||||
|
QTest::newRow("xdgShellV5") << Test::ShellSurfaceType::XdgShellV5;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestShellClient::testWindowOutputs()
|
||||||
|
{
|
||||||
|
QScopedPointer<Surface> surface(Test::createSurface());
|
||||||
|
QFETCH(Test::ShellSurfaceType, type);
|
||||||
|
QScopedPointer<QObject> shellSurface(Test::createShellSurface(type, surface.data()));
|
||||||
|
auto size = QSize(200,200);
|
||||||
|
|
||||||
|
QSignalSpy outputEnteredSpy(surface.data(), &Surface::outputEntered);
|
||||||
|
QSignalSpy outputLeftSpy(surface.data(), &Surface::outputLeft);
|
||||||
|
|
||||||
|
auto c = Test::renderAndWaitForShown(surface.data(), size, Qt::blue);
|
||||||
|
//move to be in the first screen
|
||||||
|
c->setGeometry(QRect(QPoint(100,100), size));
|
||||||
|
//we don't don't know where the compositor first placed this window,
|
||||||
|
//this might fire, it might not
|
||||||
|
outputEnteredSpy.wait(5);
|
||||||
|
outputEnteredSpy.clear();
|
||||||
|
|
||||||
|
QCOMPARE(surface->outputs().count(), 1);
|
||||||
|
QCOMPARE(surface->outputs().first()->globalPosition(), QPoint(0,0));
|
||||||
|
|
||||||
|
//move to overlapping both first and second screen
|
||||||
|
c->setGeometry(QRect(QPoint(1250,100), size));
|
||||||
|
QVERIFY(outputEnteredSpy.wait());
|
||||||
|
QCOMPARE(outputEnteredSpy.count(), 1);
|
||||||
|
QCOMPARE(outputLeftSpy.count(), 0);
|
||||||
|
QCOMPARE(surface->outputs().count(), 2);
|
||||||
|
QVERIFY(surface->outputs()[0] != surface->outputs()[1]);
|
||||||
|
|
||||||
|
//move entirely into second screen
|
||||||
|
c->setGeometry(QRect(QPoint(1400,100), size));
|
||||||
|
QVERIFY(outputLeftSpy.wait());
|
||||||
|
QCOMPARE(outputEnteredSpy.count(), 1);
|
||||||
|
QCOMPARE(outputLeftSpy.count(), 1);
|
||||||
|
QCOMPARE(surface->outputs().count(), 1);
|
||||||
|
QCOMPARE(surface->outputs().first()->globalPosition(), QPoint(1280,0));
|
||||||
|
}
|
||||||
|
|
||||||
void TestShellClient::testMinimizeActiveWindow_data()
|
void TestShellClient::testMinimizeActiveWindow_data()
|
||||||
{
|
{
|
||||||
QTest::addColumn<Test::ShellSurfaceType>("type");
|
QTest::addColumn<Test::ShellSurfaceType>("type");
|
||||||
|
|
|
@ -28,12 +28,14 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#include "workspace.h"
|
#include "workspace.h"
|
||||||
#include "virtualdesktops.h"
|
#include "virtualdesktops.h"
|
||||||
#include "workspace.h"
|
#include "workspace.h"
|
||||||
|
#include "screens.h"
|
||||||
#include "decorations/decorationbridge.h"
|
#include "decorations/decorationbridge.h"
|
||||||
#include "decorations/decoratedclient.h"
|
#include "decorations/decoratedclient.h"
|
||||||
#include <KDecoration2/Decoration>
|
#include <KDecoration2/Decoration>
|
||||||
#include <KDecoration2/DecoratedClient>
|
#include <KDecoration2/DecoratedClient>
|
||||||
|
|
||||||
#include <KWayland/Client/surface.h>
|
#include <KWayland/Client/surface.h>
|
||||||
|
#include <KWayland/Server/display.h>
|
||||||
#include <KWayland/Server/clientconnection.h>
|
#include <KWayland/Server/clientconnection.h>
|
||||||
#include <KWayland/Server/seat_interface.h>
|
#include <KWayland/Server/seat_interface.h>
|
||||||
#include <KWayland/Server/shell_interface.h>
|
#include <KWayland/Server/shell_interface.h>
|
||||||
|
@ -173,6 +175,9 @@ void ShellClient::initSurface(T *shellSurface)
|
||||||
connect(shellSurface, &T::fullscreenChanged, this, &ShellClient::clientFullScreenChanged);
|
connect(shellSurface, &T::fullscreenChanged, this, &ShellClient::clientFullScreenChanged);
|
||||||
|
|
||||||
connect(shellSurface, &T::transientForChanged, this, &ShellClient::setTransient);
|
connect(shellSurface, &T::transientForChanged, this, &ShellClient::setTransient);
|
||||||
|
|
||||||
|
connect(this, &ShellClient::geometryChanged, this, &ShellClient::updateClientOutputs);
|
||||||
|
connect(screens(), &Screens::changed, this, &ShellClient::updateClientOutputs);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShellClient::init()
|
void ShellClient::init()
|
||||||
|
@ -1522,4 +1527,17 @@ void ShellClient::popupDone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ShellClient::updateClientOutputs()
|
||||||
|
{
|
||||||
|
QVector<OutputInterface*> clientOutputs;
|
||||||
|
const auto outputs = waylandServer()->display()->outputs();
|
||||||
|
for (OutputInterface* output: qAsConst(outputs)) {
|
||||||
|
const QRect outputGeom(output->globalPosition(), output->pixelSize() / output->scale());
|
||||||
|
if (geometry().intersects(outputGeom)) {
|
||||||
|
clientOutputs << output;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
surface()->setOutputs(clientOutputs);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -185,6 +185,7 @@ private:
|
||||||
void markAsMapped();
|
void markAsMapped();
|
||||||
void setTransient();
|
void setTransient();
|
||||||
bool shouldExposeToWindowManagement();
|
bool shouldExposeToWindowManagement();
|
||||||
|
void updateClientOutputs();
|
||||||
KWayland::Server::XdgShellSurfaceInterface::States xdgSurfaceStates() const;
|
KWayland::Server::XdgShellSurfaceInterface::States xdgSurfaceStates() const;
|
||||||
void updateShowOnScreenEdge();
|
void updateShowOnScreenEdge();
|
||||||
static void deleteClient(ShellClient *c);
|
static void deleteClient(ShellClient *c);
|
||||||
|
|
Loading…
Reference in a new issue