Merge branch 'Plasma/5.9'

This commit is contained in:
Martin Gräßlin 2017-02-14 07:37:00 +01:00
commit cf79de5f36
5 changed files with 191 additions and 27 deletions

View file

@ -16,7 +16,6 @@ endfunction()
integrationTest(NAME testStart SRCS start_test.cpp)
integrationTest(NAME testTransientNoInput SRCS transient_no_input_test.cpp)
integrationTest(NAME testQuickTiling SRCS quick_tiling_test.cpp)
integrationTest(NAME testDontCrashGlxgears SRCS dont_crash_glxgears.cpp)
integrationTest(NAME testLockScreen SRCS lockscreen.cpp)
integrationTest(NAME testDecorationInput SRCS decoration_input_test.cpp)
@ -56,6 +55,7 @@ if (XCB_ICCCM_FOUND)
integrationTest(NAME testXwaylandInput SRCS xwayland_input_test.cpp LIBS XCB::ICCCM)
integrationTest(NAME testWindowRules SRCS window_rules_test.cpp LIBS XCB::ICCCM)
integrationTest(NAME testX11Client SRCS x11_client_test.cpp LIBS XCB::ICCCM)
integrationTest(NAME testQuickTiling SRCS quick_tiling_test.cpp LIBS XCB::ICCCM)
if (KWIN_BUILD_ACTIVITIES)
integrationTest(NAME testActivities SRCS activities_test.cpp LIBS XCB::ICCCM)

View file

@ -20,6 +20,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "kwin_wayland_test.h"
#include "platform.h"
#include "abstract_client.h"
#include "client.h"
#include "cursor.h"
#include "screens.h"
#include "wayland_server.h"
@ -31,6 +32,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <KWayland/Client/shell.h>
#include <KWayland/Client/surface.h>
#include <netwm.h>
#include <xcb/xcb_icccm.h>
#include <linux/input.h>
Q_DECLARE_METATYPE(KWin::AbstractClient::QuickTileMode)
@ -56,6 +60,10 @@ private Q_SLOTS:
void testQuickTilingKeyboardMove();
void testQuickTilingPointerMove_data();
void testQuickTilingPointerMove();
void testX11QuickTiling_data();
void testX11QuickTiling();
void testX11QuickTilingAfterVertMaximize_data();
void testX11QuickTilingAfterVertMaximize();
private:
KWayland::Client::ConnectionThread *m_connection = nullptr;
@ -406,6 +414,181 @@ void QuickTilingTest::testQuickTilingPointerMove()
QTEST(c->quickTileMode(), "expectedMode");
}
struct XcbConnectionDeleter
{
static inline void cleanup(xcb_connection_t *pointer)
{
xcb_disconnect(pointer);
}
};
void QuickTilingTest::testX11QuickTiling_data()
{
QTest::addColumn<AbstractClient::QuickTileMode>("mode");
QTest::addColumn<QRect>("expectedGeometry");
#define FLAG(name) AbstractClient::QuickTileMode(AbstractClient::QuickTile##name)
QTest::newRow("left") << FLAG(Left) << QRect(0, 0, 640, 1024);
QTest::newRow("top") << FLAG(Top) << QRect(0, 0, 1280, 512);
QTest::newRow("right") << FLAG(Right) << QRect(640, 0, 640, 1024);
QTest::newRow("bottom") << FLAG(Bottom) << QRect(0, 512, 1280, 512);
QTest::newRow("top left") << (FLAG(Left) | FLAG(Top)) << QRect(0, 0, 640, 512);
QTest::newRow("top right") << (FLAG(Right) | FLAG(Top)) << QRect(640, 0, 640, 512);
QTest::newRow("bottom left") << (FLAG(Left) | FLAG(Bottom)) << QRect(0, 512, 640, 512);
QTest::newRow("bottom right") << (FLAG(Right) | FLAG(Bottom)) << QRect(640, 512, 640, 512);
QTest::newRow("maximize") << FLAG(Maximize) << QRect(0, 0, 1280, 1024);
#undef FLAG
}
void QuickTilingTest::testX11QuickTiling()
{
QScopedPointer<xcb_connection_t, XcbConnectionDeleter> c(xcb_connect(nullptr, nullptr));
QVERIFY(!xcb_connection_has_error(c.data()));
const QRect windowGeometry(0, 0, 100, 200);
xcb_window_t w = xcb_generate_id(c.data());
xcb_create_window(c.data(), XCB_COPY_FROM_PARENT, w, rootWindow(),
windowGeometry.x(),
windowGeometry.y(),
windowGeometry.width(),
windowGeometry.height(),
0, XCB_WINDOW_CLASS_INPUT_OUTPUT, XCB_COPY_FROM_PARENT, 0, nullptr);
xcb_size_hints_t hints;
memset(&hints, 0, sizeof(hints));
xcb_icccm_size_hints_set_position(&hints, 1, windowGeometry.x(), windowGeometry.y());
xcb_icccm_size_hints_set_size(&hints, 1, windowGeometry.width(), windowGeometry.height());
xcb_icccm_set_wm_normal_hints(c.data(), w, &hints);
xcb_map_window(c.data(), w);
xcb_flush(c.data());
// we should get a client for it
QSignalSpy windowCreatedSpy(workspace(), &Workspace::clientAdded);
QVERIFY(windowCreatedSpy.isValid());
QVERIFY(windowCreatedSpy.wait());
Client *client = windowCreatedSpy.first().first().value<Client*>();
QVERIFY(client);
QCOMPARE(client->window(), w);
// now quick tile
QSignalSpy quickTileChangedSpy(client, &AbstractClient::quickTileModeChanged);
QVERIFY(quickTileChangedSpy.isValid());
const QRect origGeo = client->geometry();
QFETCH(AbstractClient::QuickTileMode, mode);
client->setQuickTileMode(mode, true);
QCOMPARE(client->quickTileMode(), mode);
QTEST(client->geometry(), "expectedGeometry");
QCOMPARE(client->geometryRestore(), origGeo);
QEXPECT_FAIL("maximize", "For maximize we get two changed signals", Continue);
QCOMPARE(quickTileChangedSpy.count(), 1);
// and destroy the window again
xcb_unmap_window(c.data(), w);
xcb_destroy_window(c.data(), w);
xcb_flush(c.data());
c.reset();
QSignalSpy windowClosedSpy(client, &Client::windowClosed);
QVERIFY(windowClosedSpy.isValid());
QVERIFY(windowClosedSpy.wait());
}
void QuickTilingTest::testX11QuickTilingAfterVertMaximize_data()
{
QTest::addColumn<AbstractClient::QuickTileMode>("mode");
QTest::addColumn<QRect>("expectedGeometry");
#define FLAG(name) AbstractClient::QuickTileMode(AbstractClient::QuickTile##name)
QTest::newRow("left") << FLAG(Left) << QRect(0, 0, 640, 1024);
QTest::newRow("top") << FLAG(Top) << QRect(0, 0, 1280, 512);
QTest::newRow("right") << FLAG(Right) << QRect(640, 0, 640, 1024);
QTest::newRow("bottom") << FLAG(Bottom) << QRect(0, 512, 1280, 512);
QTest::newRow("top left") << (FLAG(Left) | FLAG(Top)) << QRect(0, 0, 640, 512);
QTest::newRow("top right") << (FLAG(Right) | FLAG(Top)) << QRect(640, 0, 640, 512);
QTest::newRow("bottom left") << (FLAG(Left) | FLAG(Bottom)) << QRect(0, 512, 640, 512);
QTest::newRow("bottom right") << (FLAG(Right) | FLAG(Bottom)) << QRect(640, 512, 640, 512);
QTest::newRow("maximize") << FLAG(Maximize) << QRect(0, 0, 1280, 1024);
#undef FLAG
}
void QuickTilingTest::testX11QuickTilingAfterVertMaximize()
{
QScopedPointer<xcb_connection_t, XcbConnectionDeleter> c(xcb_connect(nullptr, nullptr));
QVERIFY(!xcb_connection_has_error(c.data()));
const QRect windowGeometry(0, 0, 100, 200);
xcb_window_t w = xcb_generate_id(c.data());
xcb_create_window(c.data(), XCB_COPY_FROM_PARENT, w, rootWindow(),
windowGeometry.x(),
windowGeometry.y(),
windowGeometry.width(),
windowGeometry.height(),
0, XCB_WINDOW_CLASS_INPUT_OUTPUT, XCB_COPY_FROM_PARENT, 0, nullptr);
xcb_size_hints_t hints;
memset(&hints, 0, sizeof(hints));
xcb_icccm_size_hints_set_position(&hints, 1, windowGeometry.x(), windowGeometry.y());
xcb_icccm_size_hints_set_size(&hints, 1, windowGeometry.width(), windowGeometry.height());
xcb_icccm_set_wm_normal_hints(c.data(), w, &hints);
xcb_map_window(c.data(), w);
xcb_flush(c.data());
// we should get a client for it
QSignalSpy windowCreatedSpy(workspace(), &Workspace::clientAdded);
QVERIFY(windowCreatedSpy.isValid());
QVERIFY(windowCreatedSpy.wait());
Client *client = windowCreatedSpy.first().first().value<Client*>();
QVERIFY(client);
QCOMPARE(client->window(), w);
const QRect origGeo = client->geometry();
QCOMPARE(client->maximizeMode(), MaximizeRestore);
// vertically maximize the window
client->maximize(client->maximizeMode() ^ MaximizeVertical);
QCOMPARE(client->geometry().width(), origGeo.width());
QCOMPARE(client->height(), screens()->size(client->screen()).height());
QCOMPARE(client->geometryRestore(), origGeo);
// now quick tile
QSignalSpy quickTileChangedSpy(client, &AbstractClient::quickTileModeChanged);
QVERIFY(quickTileChangedSpy.isValid());
QFETCH(AbstractClient::QuickTileMode, mode);
client->setQuickTileMode(mode, true);
QEXPECT_FAIL("left", "Quick tiling not working", Continue);
QEXPECT_FAIL("right", "Quick tiling not working", Continue);
QEXPECT_FAIL("top", "Quick tiling not working", Continue);
QEXPECT_FAIL("bottom", "Quick tiling not working", Continue);
QEXPECT_FAIL("top left", "Quick tiling not working", Continue);
QEXPECT_FAIL("top right", "Quick tiling not working", Continue);
QEXPECT_FAIL("bottom left", "Quick tiling not working", Continue);
QEXPECT_FAIL("bottom right", "Quick tiling not working", Continue);
QCOMPARE(client->quickTileMode(), mode);
QEXPECT_FAIL("left", "Quick tiling not working", Continue);
QEXPECT_FAIL("right", "Quick tiling not working", Continue);
QEXPECT_FAIL("top", "Quick tiling not working", Continue);
QEXPECT_FAIL("bottom", "Quick tiling not working", Continue);
QEXPECT_FAIL("top left", "Quick tiling not working", Continue);
QEXPECT_FAIL("top right", "Quick tiling not working", Continue);
QEXPECT_FAIL("bottom left", "Quick tiling not working", Continue);
QEXPECT_FAIL("bottom right", "Quick tiling not working", Continue);
QTEST(client->geometry(), "expectedGeometry");
QEXPECT_FAIL("", "We get two changed events", Continue);
QCOMPARE(quickTileChangedSpy.count(), 1);
// and destroy the window again
xcb_unmap_window(c.data(), w);
xcb_destroy_window(c.data(), w);
xcb_flush(c.data());
c.reset();
QSignalSpy windowClosedSpy(client, &Client::windowClosed);
QVERIFY(windowClosedSpy.isValid());
QVERIFY(windowClosedSpy.wait());
}
}
WAYLANDTEST_MAIN(KWin::QuickTilingTest)

View file

@ -100,7 +100,10 @@ ConfigurationModule::ConfigurationModule(QWidget *parent, const QVariantList &ar
m_quickView->rootContext()->setContextProperty(QStringLiteral("decorationsModel"), m_proxyModel);
updateColors();
m_quickView->rootContext()->setContextProperty("_borderSizesIndex", 3); // 3 is normal
m_quickView->rootContext()->setContextProperty("configurationModule", this);
m_quickView->rootContext()->setContextProperty("leftButtons", m_leftButtons);
m_quickView->rootContext()->setContextProperty("rightButtons", m_rightButtons);
m_quickView->rootContext()->setContextProperty("availableButtons", m_availableButtons);
m_quickView->rootContext()->setContextProperty("titleFont", QFontDatabase::systemFont(QFontDatabase::TitleFont));
m_quickView->setResizeMode(QQuickView::SizeRootObjectToView);
m_quickView->setSource(QUrl::fromLocalFile(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("kwin/kcm_kwindecoration/main.qml"))));
@ -406,21 +409,6 @@ void ConfigurationModule::showKNS(const QString &config)
delete downloadDialog;
}
QAbstractItemModel *ConfigurationModule::leftButtons() const
{
return m_leftButtons;
}
QAbstractItemModel *ConfigurationModule::rightButtons() const
{
return m_rightButtons;
}
QAbstractItemModel *ConfigurationModule::availableButtons() const
{
return m_availableButtons;
}
bool ConfigurationModule::eventFilter(QObject *watched, QEvent *e)
{
if (watched != m_ui) {

View file

@ -47,17 +47,10 @@ public:
class ConfigurationModule : public KCModule
{
Q_OBJECT
Q_PROPERTY(QAbstractItemModel* leftButtons READ leftButtons CONSTANT)
Q_PROPERTY(QAbstractItemModel* rightButtons READ rightButtons CONSTANT)
Q_PROPERTY(QAbstractItemModel* availableButtons READ availableButtons CONSTANT)
public:
explicit ConfigurationModule(QWidget *parent = nullptr, const QVariantList &args = QVariantList());
virtual ~ConfigurationModule();
QAbstractItemModel *leftButtons() const;
QAbstractItemModel *rightButtons() const;
QAbstractItemModel *availableButtons() const;
bool eventFilter(QObject *watched, QEvent *e) override;
public Q_SLOTS:

View file

@ -63,7 +63,7 @@ Item {
id: leftButtonsView
anchors.left: parent.left;
height: buttonPreviewRow.height
model: configurationModule.leftButtons
model: leftButtons
key: "decoButtonLeft"
}
Item {
@ -81,7 +81,7 @@ Item {
id: rightButtonsView
anchors.right: parent.right;
height: buttonPreviewRow.height
model: configurationModule.rightButtons
model: rightButtons
key: "decoButtonRight"
}
DropArea {
@ -144,7 +144,7 @@ Item {
GridView {
id: availableGrid
Layout.fillWidth: true
model: configurationModule.availableButtons
model: availableButtons
interactive: false
cellWidth: iconLabel.implicitWidth
cellHeight: units.iconSizes.small + iCannotBelieveIDoThis.implicitHeight + 4*units.smallSpacing