xdgshellclient: Support set_fullscreen argument

xdgshell allows clients to specify which output should we fill on
set_fullscreen. This change takes this request into consideration
instead of ignoring it.
This commit is contained in:
Aleix Pol 2020-11-23 19:24:37 +01:00 committed by Aleix Pol Gonzalez
parent f04fa44f34
commit 91064cb26a
3 changed files with 65 additions and 2 deletions

View file

@ -9,6 +9,7 @@
*/
#include "kwin_wayland_test.h"
#include "abstract_client.h"
#include "abstract_wayland_output.h"
#include "cursor.h"
#include "decorations/decorationbridge.h"
#include "decorations/settings.h"
@ -73,6 +74,7 @@ private Q_SLOTS:
void testMaximizedToFullscreen_data();
void testMaximizedToFullscreen();
void testFullscreenMultipleOutputs();
void testWindowOpensLargerThanScreen();
void testHidden();
void testDesktopFileName();
@ -626,6 +628,59 @@ void TestXdgShellClient::testMaximizedToFullscreen()
QVERIFY(Test::waitForWindowDestroyed(client));
}
void TestXdgShellClient::testFullscreenMultipleOutputs()
{
// this test verifies that kwin will place fullscreen windows in the outputs its instructed to
for (int i = 0; i < screens()->count(); ++i) {
XdgShellSurface::States states;
QSharedPointer<Surface> surface(Test::createSurface());
QSharedPointer<XdgShellSurface> shellSurface(Test::createXdgShellStableSurface(surface.data()));
QVERIFY(surface);
QVERIFY(shellSurface);
auto client = Test::renderAndWaitForShown(surface.data(), QSize(100, 50), Qt::blue);
QVERIFY(client);
QVERIFY(client->isActive());
QVERIFY(!client->isFullScreen());
QCOMPARE(client->clientSize(), QSize(100, 50));
QVERIFY(!client->isDecorated());
QSignalSpy fullscreenChangedSpy(client, &AbstractClient::fullScreenChanged);
QVERIFY(fullscreenChangedSpy.isValid());
QSignalSpy frameGeometryChangedSpy(client, &AbstractClient::frameGeometryChanged);
QVERIFY(frameGeometryChangedSpy.isValid());
QSignalSpy configureRequestedSpy(shellSurface.data(), &XdgShellSurface::configureRequested);
QVERIFY(configureRequestedSpy.isValid());
// Wait for the compositor to send a configure event with the Activated state.
QVERIFY(configureRequestedSpy.wait());
QCOMPARE(configureRequestedSpy.count(), 1);
states = configureRequestedSpy.last().at(1).value<XdgShellSurface::States>();
QVERIFY(states & XdgShellSurface::State::Activated);
// Ask the compositor to show the window in full screen mode.
shellSurface->setFullscreen(true, Test::waylandOutputs()[i]);
QVERIFY(configureRequestedSpy.wait());
QCOMPARE(configureRequestedSpy.count(), 2);
QCOMPARE(configureRequestedSpy.last().at(0).value<QSize>(), screens()->size(i));
shellSurface->ackConfigure(configureRequestedSpy.last().at(2).value<quint32>());
Test::render(surface.data(), configureRequestedSpy.last().at(0).value<QSize>(), Qt::red);
QVERIFY(!fullscreenChangedSpy.isEmpty() || fullscreenChangedSpy.wait());
QCOMPARE(fullscreenChangedSpy.count(), 1);
QVERIFY(!frameGeometryChangedSpy.isEmpty() || frameGeometryChangedSpy.wait());
QVERIFY(client->isFullScreen());
QCOMPARE(client->frameGeometry(), screens()->geometry(i));
}
}
void TestXdgShellClient::testWindowOpensLargerThanScreen()
{
// this test creates a window which is as large as the screen, but is decorated

View file

@ -9,7 +9,9 @@
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "xdgshellclient.h"
#include "abstract_wayland_output.h"
#include "deleted.h"
#include "platform.h"
#include "screenedge.h"
#include "screens.h"
#include "subsurfacemonitor.h"
@ -1060,7 +1062,8 @@ void XdgToplevelClient::handleUnmaximizeRequested()
void XdgToplevelClient::handleFullscreenRequested(OutputInterface *output)
{
Q_UNUSED(output)
m_fullScreenRequestedOutput = waylandServer()->findOutput(output);
if (m_isInitialized) {
setFullScreen(/* set */ true, /* user */ false);
scheduleConfigure(ConfigureRequired);
@ -1071,6 +1074,7 @@ void XdgToplevelClient::handleFullscreenRequested(OutputInterface *output)
void XdgToplevelClient::handleUnfullscreenRequested()
{
m_fullScreenRequestedOutput.clear();
if (m_isInitialized) {
setFullScreen(/* set */ false, /* user */ false);
scheduleConfigure(ConfigureRequired);
@ -1560,8 +1564,10 @@ void XdgToplevelClient::setFullScreen(bool set, bool user)
updateDecoration(false, false);
if (set) {
setFrameGeometry(workspace()->clientArea(FullScreenArea, this));
const int screen = m_fullScreenRequestedOutput ? kwinApp()->platform()->enabledOutputs().indexOf(m_fullScreenRequestedOutput) : screens()->number(frameGeometry().center());
setFrameGeometry(workspace()->clientArea(FullScreenArea, screen, desktop()));
} else {
m_fullScreenRequestedOutput.clear();
if (m_fullScreenGeometryRestore.isValid()) {
int currentScreen = screen();
setFrameGeometry(QRect(m_fullScreenGeometryRestore.topLeft(),

View file

@ -29,6 +29,7 @@ class XdgToplevelDecorationV1Interface;
namespace KWin
{
class AbstractOutput;
class XdgSurfaceConfigure
{
@ -216,6 +217,7 @@ private:
bool m_isInitialized = false;
bool m_userNoBorder = false;
bool m_isTransient = false;
QPointer<AbstractOutput> m_fullScreenRequestedOutput;
};
class XdgPopupClient final : public XdgSurfaceClient