Merge branch 'Plasma/5.8'

This commit is contained in:
Martin Gräßlin 2016-10-05 07:50:33 +02:00
commit 73dd1b9e46
18 changed files with 187 additions and 6 deletions

View file

@ -1627,4 +1627,12 @@ QRect AbstractClient::iconGeometry() const
return candidateGeom.translated(candidatePanel->pos());
}
QRect AbstractClient::inputGeometry() const
{
if (isDecorated()) {
return Toplevel::inputGeometry() + decoration()->resizeOnlyBorders();
}
return Toplevel::inputGeometry();
}
}

View file

@ -578,6 +578,8 @@ public:
*/
virtual void showContextHelp();
QRect inputGeometry() const override;
// TODO: remove boolean trap
static bool belongToSameApplication(const AbstractClient* c1, const AbstractClient* c2, bool active_hack = false);

View file

@ -52,6 +52,7 @@ private Q_SLOTS:
void testWaylandClient_data();
void testWaylandClient();
void testInternalWindow();
void testClosingDebugConsole();
};
void DebugConsoleTest::initTestCase()
@ -502,6 +503,28 @@ void DebugConsoleTest::testInternalWindow()
QCOMPARE(rowsRemovedSpy.first().first().value<QModelIndex>(), internalTopLevelIndex);
}
void DebugConsoleTest::testClosingDebugConsole()
{
// this test verifies that the DebugConsole gets destroyed when closing the window
// BUG: 369858
DebugConsole *console = new DebugConsole;
QSignalSpy destroyedSpy(console, &QObject::destroyed);
QVERIFY(destroyedSpy.isValid());
QSignalSpy clientAddedSpy(waylandServer(), &WaylandServer::shellClientAdded);
QVERIFY(clientAddedSpy.isValid());
console->show();
QCOMPARE(console->windowHandle()->isVisible(), true);
QTRY_COMPARE(clientAddedSpy.count(), 1);
ShellClient *c = clientAddedSpy.first().first().value<ShellClient*>();
QVERIFY(c->isInternal());
QCOMPARE(c->internalWindow(), console->windowHandle());
QVERIFY(c->isDecorated());
c->closeWindow();
QVERIFY(destroyedSpy.wait());
}
}
WAYLANDTEST_MAIN(KWin::DebugConsoleTest)

View file

@ -70,6 +70,8 @@ private Q_SLOTS:
void testPressToMove();
void testTapToMove_data();
void testTapToMove();
void testResizeOutsideWindow_data();
void testResizeOutsideWindow();
private:
AbstractClient *showWindow(Test::ShellSurfaceType type);
@ -498,6 +500,69 @@ void DecorationInputTest::testTapToMove()
QCOMPARE(c->pos(), oldPos + offset2 + offset3);
}
void DecorationInputTest::testResizeOutsideWindow_data()
{
QTest::addColumn<Test::ShellSurfaceType>("type");
QTest::addColumn<Qt::Edge>("edge");
QTest::addColumn<Qt::CursorShape>("expectedCursor");
QTest::newRow("wlShell - left") << Test::ShellSurfaceType::WlShell << Qt::LeftEdge << Qt::SizeHorCursor;
QTest::newRow("xdgShellV5 - left") << Test::ShellSurfaceType::XdgShellV5 << Qt::LeftEdge << Qt::SizeHorCursor;
QTest::newRow("wlShell - right") << Test::ShellSurfaceType::WlShell << Qt::RightEdge << Qt::SizeHorCursor;
QTest::newRow("xdgShellV5 - right") << Test::ShellSurfaceType::XdgShellV5 << Qt::RightEdge << Qt::SizeHorCursor;
QTest::newRow("wlShell - bottom") << Test::ShellSurfaceType::WlShell << Qt::BottomEdge << Qt::SizeVerCursor;
QTest::newRow("xdgShellV5 - bottom") << Test::ShellSurfaceType::XdgShellV5 << Qt::BottomEdge << Qt::SizeVerCursor;
}
void DecorationInputTest::testResizeOutsideWindow()
{
// this test verifies that one can resize the window outside the decoration with NoSideBorder
// first adjust config
kwinApp()->config()->group("org.kde.kdecoration2").writeEntry("BorderSize", QStringLiteral("None"));
kwinApp()->config()->sync();
workspace()->slotReconfigure();
// now create window
QFETCH(Test::ShellSurfaceType, type);
AbstractClient *c = showWindow(type);
QVERIFY(c);
QVERIFY(c->isDecorated());
QVERIFY(!c->noBorder());
c->move(screens()->geometry(0).center() - QPoint(c->width()/2, c->height()/2));
QVERIFY(c->geometry() != c->inputGeometry());
QVERIFY(c->inputGeometry().contains(c->geometry()));
QSignalSpy startMoveResizedSpy(c, &AbstractClient::clientStartUserMovedResized);
QVERIFY(startMoveResizedSpy.isValid());
// go to border
quint32 timestamp = 1;
QFETCH(Qt::Edge, edge);
switch (edge) {
case Qt::LeftEdge:
MOTION(QPoint(c->geometry().x() -1, c->geometry().center().y()));
break;
case Qt::RightEdge:
MOTION(QPoint(c->geometry().x() + c->geometry().width() +1, c->geometry().center().y()));
break;
case Qt::BottomEdge:
MOTION(QPoint(c->geometry().center().x(), c->geometry().y() + c->geometry().height() + 1));
break;
default:
break;
}
QVERIFY(!c->geometry().contains(KWin::Cursor::pos()));
// pressing should trigger resize
PRESS;
QVERIFY(!c->isResize());
QVERIFY(startMoveResizedSpy.wait());
QVERIFY(c->isResize());
RELEASE;
QVERIFY(!c->isResize());
}
}
WAYLANDTEST_MAIN(KWin::DecorationInputTest)

View file

@ -26,6 +26,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "wayland_server.h"
#include "workspace.h"
#include <KWayland/Server/seat_interface.h>
#include <KGlobalAccel>
#include <linux/input.h>
@ -43,6 +45,7 @@ private Q_SLOTS:
void cleanup();
void testConsumedShift();
void testRepeatedTrigger();
};
void GlobalShortcutsTest::initTestCase()
@ -96,5 +99,43 @@ void GlobalShortcutsTest::testConsumedShift()
kwinApp()->platform()->keyboardKeyReleased(KEY_LEFTSHIFT, timestamp++);
}
void GlobalShortcutsTest::testRepeatedTrigger()
{
// this test verifies that holding a key, triggers repeated global shortcut
// in addition pressing another key should stop triggering the shortcut
QScopedPointer<QAction> action(new QAction(nullptr));
action->setProperty("componentName", QStringLiteral(KWIN_NAME));
action->setObjectName(QStringLiteral("globalshortcuts-test-consumed-shift"));
QSignalSpy triggeredSpy(action.data(), &QAction::triggered);
QVERIFY(triggeredSpy.isValid());
KGlobalAccel::self()->setShortcut(action.data(), QList<QKeySequence>{Qt::Key_Percent}, KGlobalAccel::NoAutoloading);
input()->registerShortcut(Qt::Key_Percent, action.data());
// we need to configure the key repeat first. It is only enabled on libinput
waylandServer()->seat()->setKeyRepeatInfo(25, 300);
// press shift+5
quint32 timestamp = 0;
kwinApp()->platform()->keyboardKeyPressed(KEY_WAKEUP, timestamp++);
kwinApp()->platform()->keyboardKeyPressed(KEY_LEFTSHIFT, timestamp++);
QCOMPARE(input()->keyboardModifiers(), Qt::ShiftModifier);
kwinApp()->platform()->keyboardKeyPressed(KEY_5, timestamp++);
QTRY_COMPARE(triggeredSpy.count(), 1);
// and should repeat
QVERIFY(triggeredSpy.wait());
QVERIFY(triggeredSpy.wait());
// now release the key
kwinApp()->platform()->keyboardKeyReleased(KEY_5, timestamp++);
QEXPECT_FAIL("", "BUG 369091", Continue);
QVERIFY(!triggeredSpy.wait(500));
kwinApp()->platform()->keyboardKeyReleased(KEY_WAKEUP, timestamp++);
QVERIFY(!triggeredSpy.wait(500));
// release shift
kwinApp()->platform()->keyboardKeyReleased(KEY_LEFTSHIFT, timestamp++);
}
WAYLANDTEST_MAIN(GlobalShortcutsTest)
#include "globalshortcuts_test.moc"

View file

@ -536,6 +536,22 @@ void DebugConsole::initGLTab()
m_ui->openGLExtensionsLabel->setText(extensionsString(openGLExtensions()));
}
void DebugConsole::showEvent(QShowEvent *event)
{
QWidget::showEvent(event);
// delay the connection to the show event as in ctor the windowHandle returns null
connect(windowHandle(), &QWindow::visibleChanged, this,
[this] (bool visible) {
if (visible) {
// ignore
return;
}
deleteLater();
}
);
}
DebugConsoleDelegate::DebugConsoleDelegate(QObject *parent)
: QStyledItemDelegate(parent)
{

View file

@ -94,13 +94,16 @@ public:
QString displayText(const QVariant &value, const QLocale &locale) const override;
};
class DebugConsole : public QWidget
class KWIN_EXPORT DebugConsole : public QWidget
{
Q_OBJECT
public:
DebugConsole();
virtual ~DebugConsole();
protected:
void showEvent(QShowEvent *event) override;
private:
void initGLTab();

View file

@ -1451,7 +1451,7 @@ Toplevel *InputRedirection::findToplevel(const QPoint &pos)
continue;
}
}
if (t->geometry().contains(pos) && acceptsInput(t, pos)) {
if (t->inputGeometry().contains(pos) && acceptsInput(t, pos)) {
return t;
}
} while (it != stacking.begin());

View file

@ -29,6 +29,7 @@
"Description[uk]": "Обробляти через вузол DRM.",
"Description[x-test]": "xxRender through drm node.xx",
"Description[zh_CN]": "通过 drm 结点渲染。",
"Description[zh_TW]": "透過 drm 節點成像。",
"Id": "KWinWaylandDrmBackend",
"Name": "drm",
"Name[ca@valencia]": "DRM",

View file

@ -29,6 +29,7 @@
"Description[uk]": "Обробляти до буфера кадрів.",
"Description[x-test]": "xxRender to framebuffer.xx",
"Description[zh_CN]": "渲染到帧缓冲。",
"Description[zh_TW]": "成像至 framebuffer。",
"Id": "KWinWaylandFbdevBackend",
"Name": "framebuffer",
"Name[ca@valencia]": "Framebuffer",
@ -44,7 +45,8 @@
"Name[sr@latin]": "Kadrobafer",
"Name[sr]": "Кадробафер",
"Name[sv]": "rambuffer",
"Name[x-test]": "xxframebufferxx"
"Name[x-test]": "xxframebufferxx",
"Name[zh_TW]": "影格緩衝區framebuffer"
},
"input": false
}

View file

@ -27,6 +27,7 @@
"Description[uk]": "Обробляти за допомогою апаратного засобу композиції через libhybris.",
"Description[x-test]": "xxRender through hwcomposer through libhybris.xx",
"Description[zh_CN]": "使用 libhybris 通过 hwcomposer 渲染。",
"Description[zh_TW]": "透過 libhybris 成像到 hwcomposer。",
"Id": "KWinWaylandHwcomposerBackend",
"Name": "hwcomposer",
"Name[pl]": "sprzętowy kompozytor",

View file

@ -29,6 +29,7 @@
"Description[uk]": "Обробляти до віртуального буфера кадрів.",
"Description[x-test]": "xxRender to a virtual framebuffer.xx",
"Description[zh_CN]": "渲染到虚拟帧缓冲。",
"Description[zh_TW]": "成像到虛擬影格緩衝區。",
"Id": "KWinWaylandVirtualBackend",
"Name": "virtual",
"Name[ca@valencia]": "Virtual",
@ -45,7 +46,8 @@
"Name[sr@latin]": "Virtuelno",
"Name[sr]": "Виртуелно",
"Name[sv]": "virtuell",
"Name[x-test]": "xxvirtualxx"
"Name[x-test]": "xxvirtualxx",
"Name[zh_TW]": "虛擬"
},
"input": true
}

View file

@ -27,6 +27,7 @@
"Description[uk]": "Обробляти у вкладене вікно запущеного засобу композиції Wayland.",
"Description[x-test]": "xxRender to a nested window on running Wayland compositor.xx",
"Description[zh_CN]": "渲染到 Wayland 混成器上的嵌套窗口中",
"Description[zh_TW]": "成像到執行中的 Wayland 的巢狀視窗。",
"Id": "KWinWaylandWaylandBackend",
"Name": "wayland",
"Name[ca@valencia]": "Wayland",

View file

@ -181,8 +181,10 @@ bool EglOnXBackend::initRenderingContext()
setHavePlatformBase(havePlatformBase);
if (havePlatformBase) {
// Make sure that the X11 platform is supported
if (!hasClientExtension(QByteArrayLiteral("EGL_EXT_platform_x11"))) {
qCWarning(KWIN_CORE) << "EGL_EXT_platform_base is supported, but EGL_EXT_platform_x11 is not. Cannot create EGLDisplay on X11";
if (!hasClientExtension(QByteArrayLiteral("EGL_EXT_platform_x11")) &&
!hasClientExtension(QByteArrayLiteral("EGL_KHR_platform_x11"))) {
qCWarning(KWIN_CORE) << "EGL_EXT_platform_base is supported, but neither EGL_EXT_platform_x11 nor EGL_KHR_platform_x11 is supported."
<< "Cannot create EGLDisplay on X11";
return false;
}

View file

@ -25,6 +25,7 @@
"Description[uk]": "Додаток платформи для окремого x11 у kwin_x11.",
"Description[x-test]": "xxPlatform plugin for standalone x11 in kwin_x11.xx",
"Description[zh_CN]": "kwin_x11 中的独立 x11 的平台插件",
"Description[zh_TW]": "在 kwin_x11 中供 standalone 的 x11 使用的平臺外掛程式。",
"Id": "KWinX11Platform",
"Name": "x11-standalone",
"Name[ca@valencia]": "X11-autònoma",

View file

@ -28,6 +28,7 @@
"Description[uk]": "Обробляти у вкладене вікно системи керування вікнами X11.",
"Description[x-test]": "xxRender to a nested window on X11 windowing system.xx",
"Description[zh_CN]": "渲染到 X11 窗口系统上的嵌套窗口中",
"Description[zh_TW]": "成像到 X11 視窗系統的巢狀視窗。",
"Id": "KWinWaylandX11Backend",
"Name": "x11",
"Name[ca@valencia]": "X11",

View file

@ -538,5 +538,10 @@ quint32 Toplevel::windowId() const
return window();
}
QRect Toplevel::inputGeometry() const
{
return geometry();
}
} // namespace

View file

@ -219,6 +219,13 @@ public:
**/
virtual quint32 windowId() const;
QRect geometry() const;
/**
* The geometry of the Toplevel which accepts input events. This might be larger
* than the actual geometry, e.g. to support resizing outside the window.
*
* Default implementation returns same as geometry.
**/
virtual QRect inputGeometry() const;
QSize size() const;
QPoint pos() const;
QRect rect() const;