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:
parent
f04fa44f34
commit
91064cb26a
3 changed files with 65 additions and 2 deletions
|
@ -9,6 +9,7 @@
|
||||||
*/
|
*/
|
||||||
#include "kwin_wayland_test.h"
|
#include "kwin_wayland_test.h"
|
||||||
#include "abstract_client.h"
|
#include "abstract_client.h"
|
||||||
|
#include "abstract_wayland_output.h"
|
||||||
#include "cursor.h"
|
#include "cursor.h"
|
||||||
#include "decorations/decorationbridge.h"
|
#include "decorations/decorationbridge.h"
|
||||||
#include "decorations/settings.h"
|
#include "decorations/settings.h"
|
||||||
|
@ -73,6 +74,7 @@ private Q_SLOTS:
|
||||||
|
|
||||||
void testMaximizedToFullscreen_data();
|
void testMaximizedToFullscreen_data();
|
||||||
void testMaximizedToFullscreen();
|
void testMaximizedToFullscreen();
|
||||||
|
void testFullscreenMultipleOutputs();
|
||||||
void testWindowOpensLargerThanScreen();
|
void testWindowOpensLargerThanScreen();
|
||||||
void testHidden();
|
void testHidden();
|
||||||
void testDesktopFileName();
|
void testDesktopFileName();
|
||||||
|
@ -626,6 +628,59 @@ void TestXdgShellClient::testMaximizedToFullscreen()
|
||||||
QVERIFY(Test::waitForWindowDestroyed(client));
|
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()
|
void TestXdgShellClient::testWindowOpensLargerThanScreen()
|
||||||
{
|
{
|
||||||
// this test creates a window which is as large as the screen, but is decorated
|
// this test creates a window which is as large as the screen, but is decorated
|
||||||
|
|
|
@ -9,7 +9,9 @@
|
||||||
SPDX-License-Identifier: GPL-2.0-or-later
|
SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
*/
|
*/
|
||||||
#include "xdgshellclient.h"
|
#include "xdgshellclient.h"
|
||||||
|
#include "abstract_wayland_output.h"
|
||||||
#include "deleted.h"
|
#include "deleted.h"
|
||||||
|
#include "platform.h"
|
||||||
#include "screenedge.h"
|
#include "screenedge.h"
|
||||||
#include "screens.h"
|
#include "screens.h"
|
||||||
#include "subsurfacemonitor.h"
|
#include "subsurfacemonitor.h"
|
||||||
|
@ -1060,7 +1062,8 @@ void XdgToplevelClient::handleUnmaximizeRequested()
|
||||||
|
|
||||||
void XdgToplevelClient::handleFullscreenRequested(OutputInterface *output)
|
void XdgToplevelClient::handleFullscreenRequested(OutputInterface *output)
|
||||||
{
|
{
|
||||||
Q_UNUSED(output)
|
m_fullScreenRequestedOutput = waylandServer()->findOutput(output);
|
||||||
|
|
||||||
if (m_isInitialized) {
|
if (m_isInitialized) {
|
||||||
setFullScreen(/* set */ true, /* user */ false);
|
setFullScreen(/* set */ true, /* user */ false);
|
||||||
scheduleConfigure(ConfigureRequired);
|
scheduleConfigure(ConfigureRequired);
|
||||||
|
@ -1071,6 +1074,7 @@ void XdgToplevelClient::handleFullscreenRequested(OutputInterface *output)
|
||||||
|
|
||||||
void XdgToplevelClient::handleUnfullscreenRequested()
|
void XdgToplevelClient::handleUnfullscreenRequested()
|
||||||
{
|
{
|
||||||
|
m_fullScreenRequestedOutput.clear();
|
||||||
if (m_isInitialized) {
|
if (m_isInitialized) {
|
||||||
setFullScreen(/* set */ false, /* user */ false);
|
setFullScreen(/* set */ false, /* user */ false);
|
||||||
scheduleConfigure(ConfigureRequired);
|
scheduleConfigure(ConfigureRequired);
|
||||||
|
@ -1560,8 +1564,10 @@ void XdgToplevelClient::setFullScreen(bool set, bool user)
|
||||||
updateDecoration(false, false);
|
updateDecoration(false, false);
|
||||||
|
|
||||||
if (set) {
|
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 {
|
} else {
|
||||||
|
m_fullScreenRequestedOutput.clear();
|
||||||
if (m_fullScreenGeometryRestore.isValid()) {
|
if (m_fullScreenGeometryRestore.isValid()) {
|
||||||
int currentScreen = screen();
|
int currentScreen = screen();
|
||||||
setFrameGeometry(QRect(m_fullScreenGeometryRestore.topLeft(),
|
setFrameGeometry(QRect(m_fullScreenGeometryRestore.topLeft(),
|
||||||
|
|
|
@ -29,6 +29,7 @@ class XdgToplevelDecorationV1Interface;
|
||||||
|
|
||||||
namespace KWin
|
namespace KWin
|
||||||
{
|
{
|
||||||
|
class AbstractOutput;
|
||||||
|
|
||||||
class XdgSurfaceConfigure
|
class XdgSurfaceConfigure
|
||||||
{
|
{
|
||||||
|
@ -216,6 +217,7 @@ private:
|
||||||
bool m_isInitialized = false;
|
bool m_isInitialized = false;
|
||||||
bool m_userNoBorder = false;
|
bool m_userNoBorder = false;
|
||||||
bool m_isTransient = false;
|
bool m_isTransient = false;
|
||||||
|
QPointer<AbstractOutput> m_fullScreenRequestedOutput;
|
||||||
};
|
};
|
||||||
|
|
||||||
class XdgPopupClient final : public XdgSurfaceClient
|
class XdgPopupClient final : public XdgSurfaceClient
|
||||||
|
|
Loading…
Reference in a new issue