Add configurable Plasma panel scroll and click actions
This commit is contained in:
@@ -0,0 +1,19 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
#include <QtQuickTest/quicktest.h>
|
||||
#include <QQmlContext>
|
||||
#include <QQmlEngine>
|
||||
#include <QTemporaryDir>
|
||||
|
||||
class TestSetup : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
TestSetup() { qputenv("XDG_CONFIG_HOME", m_config.path().toUtf8()); }
|
||||
Q_INVOKABLE QString i18n(const QString &text) { return text; }
|
||||
public Q_SLOTS:
|
||||
void qmlEngineAvailable(QQmlEngine *engine) { engine->rootContext()->setContextObject(this); }
|
||||
private:
|
||||
QTemporaryDir m_config;
|
||||
};
|
||||
QUICK_TEST_MAIN_WITH_SETUP(panelareas, TestSetup)
|
||||
#include "quicktest.moc"
|
||||
@@ -0,0 +1,238 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
#include "panelcontroller.h"
|
||||
#include <QJSEngine>
|
||||
#include <QMouseEvent>
|
||||
#include <QQuickWindow>
|
||||
#include <QSignalSpy>
|
||||
#include <QTest>
|
||||
#include <QWheelEvent>
|
||||
#include <QStyleHints>
|
||||
|
||||
using namespace Qt::StringLiterals;
|
||||
|
||||
class PanelWindow : public QQuickWindow
|
||||
{
|
||||
public:
|
||||
int delivered = 0;
|
||||
bool event(QEvent *event) override
|
||||
{
|
||||
if (event->type() == QEvent::Wheel || event->type() == QEvent::MouseButtonPress
|
||||
|| event->type() == QEvent::MouseButtonRelease || event->type() == QEvent::MouseMove) {
|
||||
++delivered;
|
||||
return true;
|
||||
}
|
||||
return QQuickWindow::event(event);
|
||||
}
|
||||
};
|
||||
|
||||
class PanelControllerTest : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
static void setup(PanelController &controller, PanelWindow &window, QJSEngine &engine)
|
||||
{
|
||||
controller.setParentItem(window.contentItem());
|
||||
controller.setProperty("active", true);
|
||||
controller.setProperty("locateArea", QVariant::fromValue(engine.evaluate(
|
||||
u"(function(x,y) { return x < 100 ? 'empty' : 'tasks'; })"_s)));
|
||||
controller.setProperty("scrollActions", QVariantMap{{u"empty"_s, u"volume"_s}, {u"tasks"_s, u"brightness"_s}});
|
||||
}
|
||||
static void wheel(PanelWindow &window, int delta, int x = 20, bool pixels = false)
|
||||
{
|
||||
QWheelEvent event(QPointF(x, 10), QPointF(x, 10),
|
||||
pixels ? QPoint(0, delta) : QPoint(), pixels ? QPoint() : QPoint(0, delta),
|
||||
Qt::NoButton, Qt::NoModifier, Qt::NoScrollPhase, false);
|
||||
QCoreApplication::sendEvent(&window, &event);
|
||||
}
|
||||
static void mouse(PanelWindow &window, QEvent::Type type, int x, Qt::MouseButton button = Qt::LeftButton)
|
||||
{
|
||||
QMouseEvent event(type, QPointF(x, 10), QPointF(x, 10),
|
||||
type == QEvent::MouseMove ? Qt::NoButton : button,
|
||||
type == QEvent::MouseButtonRelease ? Qt::NoButton : button, Qt::NoModifier);
|
||||
QCoreApplication::sendEvent(&window, &event);
|
||||
}
|
||||
private Q_SLOTS:
|
||||
void wheelOverridesAndNormalBehaviour()
|
||||
{
|
||||
QJSEngine engine;
|
||||
PanelWindow window;
|
||||
PanelController controller;
|
||||
setup(controller, window, engine);
|
||||
QSignalSpy actions(&controller, &PanelController::actionRequested);
|
||||
wheel(window, 120);
|
||||
wheel(window, -120, 150);
|
||||
QCOMPARE(actions.count(), 2);
|
||||
QCOMPARE(actions.at(0), QVariantList({u"volume"_s, 1}));
|
||||
QCOMPARE(actions.at(1), QVariantList({u"brightness"_s, -1}));
|
||||
QCOMPARE(window.delivered, 0);
|
||||
controller.setProperty("scrollActions", QVariantMap{{u"empty"_s, u"normal"_s}});
|
||||
wheel(window, 120);
|
||||
QCOMPARE(window.delivered, 1);
|
||||
QCOMPARE(actions.count(), 2);
|
||||
}
|
||||
void smoothScrollingAndAreaChanges()
|
||||
{
|
||||
QJSEngine engine;
|
||||
PanelWindow window;
|
||||
PanelController controller;
|
||||
setup(controller, window, engine);
|
||||
QSignalSpy actions(&controller, &PanelController::actionRequested);
|
||||
wheel(window, 60);
|
||||
QCOMPARE(actions.count(), 0);
|
||||
wheel(window, 60);
|
||||
QCOMPARE(actions.count(), 1);
|
||||
wheel(window, 60);
|
||||
wheel(window, 60, 150);
|
||||
QCOMPARE(actions.count(), 1); // partial gestures cannot cross areas
|
||||
wheel(window, 60, 150);
|
||||
QCOMPARE(actions.count(), 2);
|
||||
wheel(window, 20, 20, true);
|
||||
QCOMPARE(actions.count(), 2);
|
||||
wheel(window, 20, 20, true);
|
||||
QCOMPARE(actions.count(), 3);
|
||||
}
|
||||
void onlyEmptySpaceClicksAreOverridden()
|
||||
{
|
||||
QJSEngine engine;
|
||||
PanelWindow window;
|
||||
PanelController controller;
|
||||
setup(controller, window, engine);
|
||||
controller.setProperty("clickActions", QVariantMap{{u"leftClick"_s, u"mute"_s}});
|
||||
QSignalSpy actions(&controller, &PanelController::clickRequested);
|
||||
mouse(window, QEvent::MouseButtonPress, 20);
|
||||
QCOMPARE(actions.count(), 0);
|
||||
mouse(window, QEvent::MouseButtonRelease, 20);
|
||||
QCOMPARE(actions.count(), 1);
|
||||
QCOMPARE(actions.at(0), QVariantList({u"leftClick"_s}));
|
||||
QCOMPARE(window.delivered, 0);
|
||||
mouse(window, QEvent::MouseButtonPress, 150);
|
||||
mouse(window, QEvent::MouseButtonRelease, 150);
|
||||
mouse(window, QEvent::MouseButtonPress, 20, Qt::RightButton);
|
||||
mouse(window, QEvent::MouseButtonRelease, 20, Qt::RightButton);
|
||||
QCOMPARE(window.delivered, 4);
|
||||
QCOMPARE(actions.count(), 1);
|
||||
}
|
||||
void draggingCancelsClickEvenWhenReturning()
|
||||
{
|
||||
QJSEngine engine;
|
||||
PanelWindow window;
|
||||
PanelController controller;
|
||||
setup(controller, window, engine);
|
||||
controller.setProperty("clickActions", QVariantMap{{u"leftClick"_s, u"mute"_s}});
|
||||
QSignalSpy actions(&controller, &PanelController::clickRequested);
|
||||
mouse(window, QEvent::MouseButtonPress, 20);
|
||||
mouse(window, QEvent::MouseMove, 80);
|
||||
mouse(window, QEvent::MouseMove, 20);
|
||||
mouse(window, QEvent::MouseButtonRelease, 20);
|
||||
QCOMPARE(actions.count(), 0);
|
||||
}
|
||||
void disabledAndOtherWindowsAreUntouched()
|
||||
{
|
||||
QJSEngine engine;
|
||||
PanelWindow window;
|
||||
PanelWindow popup;
|
||||
PanelController controller;
|
||||
setup(controller, window, engine);
|
||||
QSignalSpy actions(&controller, &PanelController::actionRequested);
|
||||
wheel(popup, 120);
|
||||
QCOMPARE(popup.delivered, 1);
|
||||
controller.setProperty("active", false);
|
||||
wheel(window, 120);
|
||||
QCOMPARE(window.delivered, 1);
|
||||
QCOMPARE(actions.count(), 0);
|
||||
controller.setParentItem(popup.contentItem());
|
||||
controller.setProperty("active", true);
|
||||
wheel(window, 120);
|
||||
QCOMPARE(window.delivered, 2);
|
||||
wheel(popup, 120);
|
||||
QCOMPARE(actions.count(), 1);
|
||||
}
|
||||
void doubleClicks_data()
|
||||
{
|
||||
QTest::addColumn<int>("button");
|
||||
QTest::addColumn<QString>("singleSlot");
|
||||
QTest::addColumn<QString>("doubleSlot");
|
||||
QTest::addColumn<bool>("precedingPress");
|
||||
QTest::newRow("left") << int(Qt::LeftButton) << u"leftClick"_s << u"leftDoubleClick"_s << false;
|
||||
QTest::newRow("middle") << int(Qt::MiddleButton) << u"middleClick"_s << u"middleDoubleClick"_s << false;
|
||||
QTest::newRow("qt-window-left") << int(Qt::LeftButton) << u"leftClick"_s << u"leftDoubleClick"_s << true;
|
||||
QTest::newRow("qt-window-middle") << int(Qt::MiddleButton) << u"middleClick"_s << u"middleDoubleClick"_s << true;
|
||||
}
|
||||
void doubleClicks()
|
||||
{
|
||||
QFETCH(int, button);
|
||||
QFETCH(QString, singleSlot);
|
||||
QFETCH(QString, doubleSlot);
|
||||
QFETCH(bool, precedingPress);
|
||||
const auto mouseButton = Qt::MouseButton(button);
|
||||
QJSEngine engine;
|
||||
PanelWindow window;
|
||||
PanelController controller;
|
||||
setup(controller, window, engine);
|
||||
controller.setProperty("clickActions", QVariantMap{{singleSlot, u"mute"_s}, {doubleSlot, u"application"_s}});
|
||||
QSignalSpy actions(&controller, &PanelController::clickRequested);
|
||||
mouse(window, QEvent::MouseButtonPress, 20, mouseButton);
|
||||
mouse(window, QEvent::MouseButtonRelease, 20, mouseButton);
|
||||
QCOMPARE(actions.count(), 0);
|
||||
// QGuiApplication sends both Press and DblClick for the second down.
|
||||
if (precedingPress) mouse(window, QEvent::MouseButtonPress, 20, mouseButton);
|
||||
mouse(window, QEvent::MouseButtonDblClick, 20, mouseButton);
|
||||
mouse(window, QEvent::MouseButtonRelease, 20, mouseButton);
|
||||
QCOMPARE(actions.count(), 1);
|
||||
QCOMPARE(actions.at(0), QVariantList({doubleSlot}));
|
||||
QTest::qWait(QGuiApplication::styleHints()->mouseDoubleClickInterval() + 30);
|
||||
QCOMPARE(actions.count(), 1); // no single-click action after the double
|
||||
|
||||
mouse(window, QEvent::MouseButtonPress, 20, mouseButton);
|
||||
mouse(window, QEvent::MouseButtonRelease, 20, mouseButton);
|
||||
QCOMPARE(actions.count(), 1);
|
||||
QTRY_COMPARE(actions.count(), 2);
|
||||
QCOMPARE(actions.at(1), QVariantList({singleSlot}));
|
||||
}
|
||||
void distantClicksDoNotCombine()
|
||||
{
|
||||
QJSEngine engine;
|
||||
PanelWindow window;
|
||||
PanelController controller;
|
||||
setup(controller, window, engine);
|
||||
controller.setProperty("clickActions", QVariantMap{{u"leftClick"_s, u"mute"_s}, {u"leftDoubleClick"_s, u"overview"_s}});
|
||||
QSignalSpy actions(&controller, &PanelController::clickRequested);
|
||||
mouse(window, QEvent::MouseButtonPress, 10);
|
||||
mouse(window, QEvent::MouseButtonRelease, 10);
|
||||
mouse(window, QEvent::MouseButtonPress, 90);
|
||||
mouse(window, QEvent::MouseButtonRelease, 90);
|
||||
QTRY_COMPARE(actions.count(), 2);
|
||||
QCOMPARE(actions.at(0), QVariantList({u"leftClick"_s}));
|
||||
QCOMPARE(actions.at(1), QVariantList({u"leftClick"_s}));
|
||||
}
|
||||
void doubleOnlyAndDisablingPendingClicks()
|
||||
{
|
||||
QJSEngine engine;
|
||||
PanelWindow window;
|
||||
PanelController controller;
|
||||
setup(controller, window, engine);
|
||||
controller.setProperty("clickActions", QVariantMap{{u"leftDoubleClick"_s, u"command"_s}});
|
||||
QSignalSpy actions(&controller, &PanelController::clickRequested);
|
||||
mouse(window, QEvent::MouseButtonPress, 20);
|
||||
mouse(window, QEvent::MouseButtonRelease, 20);
|
||||
// Some platforms deliver the second press without a DblClick event.
|
||||
mouse(window, QEvent::MouseButtonPress, 20);
|
||||
mouse(window, QEvent::MouseButtonRelease, 20);
|
||||
QCOMPARE(actions.count(), 1);
|
||||
QCOMPARE(actions.at(0), QVariantList({u"leftDoubleClick"_s}));
|
||||
mouse(window, QEvent::MouseButtonPress, 20);
|
||||
mouse(window, QEvent::MouseButtonRelease, 20);
|
||||
mouse(window, QEvent::MouseButtonPress, 20);
|
||||
mouse(window, QEvent::MouseMove, 80);
|
||||
mouse(window, QEvent::MouseMove, 20);
|
||||
mouse(window, QEvent::MouseButtonRelease, 20);
|
||||
QCOMPARE(actions.count(), 1); // dragging the second press cancels the double
|
||||
mouse(window, QEvent::MouseButtonPress, 20);
|
||||
mouse(window, QEvent::MouseButtonRelease, 20);
|
||||
controller.setProperty("active", false);
|
||||
QTest::qWait(QGuiApplication::styleHints()->mouseDoubleClickInterval() + 30);
|
||||
QCOMPARE(actions.count(), 1);
|
||||
}
|
||||
};
|
||||
QTEST_MAIN(PanelControllerTest)
|
||||
#include "test-panelcontroller.moc"
|
||||
@@ -0,0 +1,62 @@
|
||||
#!/usr/bin/env bash
|
||||
# SPDX-License-Identifier: MIT
|
||||
# Run in a Fedora build environment with the application's dependencies.
|
||||
set -euo pipefail
|
||||
if (( $# != 2 )); then
|
||||
printf 'Usage: %s OLD_RPM NEW_RPM\n' "$0" >&2
|
||||
exit 2
|
||||
fi
|
||||
old_rpm=$(realpath "$1")
|
||||
new_rpm=$(realpath "$2")
|
||||
work=$(mktemp -d)
|
||||
trap 'rm -rf -- "$work"' EXIT
|
||||
mkdir -p "$work/root" "$work/runtime"
|
||||
export XDG_CONFIG_HOME="$work/config" XDG_CACHE_HOME="$work/cache"
|
||||
export XDG_DATA_HOME="$work/data" XDG_DATA_DIRS="$work/root/usr/share:/usr/share"
|
||||
export XDG_RUNTIME_DIR="$work/runtime"
|
||||
export QT_QPA_PLATFORM=offscreen QT_QUICK_BACKEND=software
|
||||
unset QML_DISABLE_DISK_CACHE QML_FORCE_DISK_CACHE QML_DISK_CACHE_PATH QML_DISK_CACHE
|
||||
|
||||
launch_settings() {
|
||||
if timeout 3s dbus-run-session -- "$work/root/usr/bin/plasma-panel-actions" --settings > "$work/launch.log" 2>&1; then
|
||||
printf 'Settings exited before the test timeout.\n' >&2
|
||||
cat "$work/launch.log" >&2
|
||||
exit 1
|
||||
else
|
||||
status=$?
|
||||
if (( status != 124 )); then
|
||||
cat "$work/launch.log" >&2
|
||||
exit "$status"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
cache_for() {
|
||||
for file in "$XDG_CACHE_HOME"/plasma-panel-actions/qmlcache/*.qmlc; do
|
||||
[[ -f $file ]] || continue
|
||||
if strings -el "$file" | grep -Fx "file://$1" > /dev/null; then
|
||||
printf '%s\n' "$file"
|
||||
return
|
||||
fi
|
||||
done
|
||||
printf 'No QML cache was generated for %s\n' "$1" >&2
|
||||
return 1
|
||||
}
|
||||
|
||||
rpm2cpio "$old_rpm" | (cd "$work/root" && cpio -idm --quiet)
|
||||
launch_settings
|
||||
old_ui="$work/root/usr/share/plasma-panel-actions/ConfigGeneral.qml"
|
||||
old_cache=$(cache_for "$old_ui")
|
||||
old_checksum=$(sha256sum "$old_cache")
|
||||
|
||||
# Extract over the same location and keep the old cache intact. Changing
|
||||
# the staging directory would hide the cache-collision regression.
|
||||
rpm2cpio "$new_rpm" | (cd "$work/root" && cpio -idmu --quiet)
|
||||
new_ui="$work/root$(rpm -qpl "$new_rpm" | grep '/ConfigGeneral.qml$')"
|
||||
[[ $(stat -c %Y "$old_ui") == "$(stat -c %Y "$new_ui")" ]]
|
||||
launch_settings
|
||||
new_cache=$(cache_for "$new_ui")
|
||||
[[ $new_cache != "$old_cache" ]]
|
||||
[[ $(sha256sum "$old_cache") == "$old_checksum" ]]
|
||||
strings -el "$new_cache" | grep -Fx twinFormLayouts > /dev/null
|
||||
printf 'PASS: updated settings loaded with identical source timestamps and the old cache intact.\n'
|
||||
@@ -0,0 +1,46 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
#include "settings.h"
|
||||
#include <QTemporaryDir>
|
||||
#include <QTest>
|
||||
|
||||
class SettingsTest : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private Q_SLOTS:
|
||||
void savesWithoutAWidget()
|
||||
{
|
||||
QTemporaryDir directory;
|
||||
QVERIFY(directory.isValid());
|
||||
qputenv("XDG_CONFIG_HOME", directory.path().toUtf8());
|
||||
Settings settings;
|
||||
auto values = settings.values();
|
||||
QCOMPARE(values.value(QStringLiteral("spacerLength")).toInt(), 48);
|
||||
QCOMPARE(values.value(QStringLiteral("tasksAction")).toString(), QStringLiteral("volume"));
|
||||
values[QStringLiteral("tasksAction")] = QStringLiteral("normal");
|
||||
values[QStringLiteral("spacerLength")] = 128;
|
||||
QVERIFY(settings.save(values));
|
||||
Settings reopened;
|
||||
QCOMPARE(reopened.values(), values);
|
||||
auto invalid = values;
|
||||
invalid[QStringLiteral("tasksAction")] = QStringLiteral("invalid");
|
||||
QVERIFY(!settings.save(invalid));
|
||||
QCOMPARE(settings.values(), values);
|
||||
auto launch = values;
|
||||
launch[QStringLiteral("leftDoubleClick")] = QStringLiteral("command");
|
||||
QVERIFY(!settings.save(launch)); // empty command cannot be enabled
|
||||
launch[QStringLiteral("leftDoubleClickCommand")] = QStringLiteral("true");
|
||||
QVERIFY(settings.save(launch));
|
||||
QCOMPARE(settings.values(), launch);
|
||||
launch[QStringLiteral("middleDoubleClick")] = QStringLiteral("application");
|
||||
QVERIFY(!settings.save(launch));
|
||||
launch[QStringLiteral("middleDoubleClickApplication")] = QStringLiteral("org.kde.plasma-systemmonitor.desktop");
|
||||
QVERIFY(settings.save(launch));
|
||||
QCOMPARE(settings.values(), launch);
|
||||
invalid = values;
|
||||
invalid[QStringLiteral("spacerLength")] = -1;
|
||||
QVERIFY(!settings.save(invalid));
|
||||
QCOMPARE(settings.values(), launch);
|
||||
}
|
||||
};
|
||||
QTEST_GUILESS_MAIN(SettingsTest)
|
||||
#include "test-settings.moc"
|
||||
@@ -0,0 +1,72 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
import QtQuick
|
||||
import QtTest
|
||||
import "../controller/contents/ui/areas.js" as Areas
|
||||
|
||||
Item {
|
||||
width: 600
|
||||
height: 100
|
||||
Item {
|
||||
id: panel
|
||||
x: 30
|
||||
y: 20
|
||||
width: 500
|
||||
height: 40
|
||||
Item {
|
||||
width: 200
|
||||
height: 40
|
||||
property alias applet: tasks
|
||||
Item {
|
||||
id: tasks
|
||||
anchors.fill: parent
|
||||
property QtObject plasmoid: QtObject { property string pluginName: "org.kde.plasma.taskmanager" }
|
||||
Item {
|
||||
id: button
|
||||
width: 80
|
||||
height: 40
|
||||
property Item tasksRoot: tasks
|
||||
property bool isWindow: true
|
||||
property int index: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
Item {
|
||||
x: 200
|
||||
width: 60
|
||||
height: 40
|
||||
property QtObject applet: QtObject {
|
||||
property QtObject plasmoid: QtObject { property string pluginName: "org.kde.plasma.systemtray" }
|
||||
}
|
||||
}
|
||||
Item {
|
||||
id: arbitraryWidget
|
||||
x: 260
|
||||
width: 60
|
||||
height: 40
|
||||
property QtObject applet: QtObject {
|
||||
property QtObject plasmoid: QtObject { property string pluginName: "third.party.widget" }
|
||||
}
|
||||
}
|
||||
}
|
||||
TestCase {
|
||||
name: "PanelAreas"
|
||||
when: windowShown
|
||||
function test_taskButtonsVersusUnusedSpace() {
|
||||
compare(Areas.areaAt(panel, 40, 30), "tasks");
|
||||
compare(Areas.areaAt(panel, 150, 30), "empty");
|
||||
button.isWindow = false; // pinned launchers still count as buttons
|
||||
compare(Areas.areaAt(panel, 40, 30), "tasks");
|
||||
button.visible = false;
|
||||
compare(Areas.areaAt(panel, 40, 30), "empty");
|
||||
button.visible = true;
|
||||
}
|
||||
function test_trayAndUnrecognizedWidgetsKeepClicks() {
|
||||
compare(Areas.areaAt(panel, 240, 30), "tray");
|
||||
compare(Areas.areaAt(panel, 300, 30), "other");
|
||||
arbitraryWidget.visible = false;
|
||||
compare(Areas.areaAt(panel, 300, 30), "empty");
|
||||
arbitraryWidget.visible = true;
|
||||
compare(Areas.areaAt(null, 40, 30), "");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
import QtQuick
|
||||
import QtTest
|
||||
|
||||
TestCase {
|
||||
name: "PanelConfiguration"
|
||||
function test_savedValuesAndDefaults() {
|
||||
const component = Qt.createComponent("../src/ConfigGeneral.qml");
|
||||
compare(component.status, Component.Ready, component.errorString());
|
||||
const config = component.createObject(this, {
|
||||
width: 600, height: 800,
|
||||
cfg_emptyAction: "brightness", cfg_tasksAction: "normal",
|
||||
cfg_launcherAction: "volume", cfg_clockAction: "keyboard",
|
||||
cfg_trayAction: "desktops", cfg_otherAction: "normal",
|
||||
cfg_leftClick: "mute", cfg_middleClick: "overview",
|
||||
cfg_leftDoubleClick: "command", cfg_leftDoubleClickCommand: "true",
|
||||
cfg_middleDoubleClick: "application", cfg_middleDoubleClickApplication: "test.desktop",
|
||||
applications: [{text: "Test application", value: "test.desktop"}],
|
||||
cfg_spacerLength: 100
|
||||
});
|
||||
verify(config !== null);
|
||||
compare(findChild(config, "emptyAction").currentValue, "brightness");
|
||||
compare(findChild(config, "tasksAction").currentValue, "normal");
|
||||
compare(findChild(config, "leftDoubleClick").currentValue, "command");
|
||||
compare(findChild(config, "leftDoubleClickCommand").text, "true");
|
||||
compare(findChild(config, "middleDoubleClickApplication").currentValue, "test.desktop");
|
||||
config.cfg_emptyAction = "keyboard";
|
||||
compare(findChild(config, "emptyAction").currentValue, "keyboard");
|
||||
findChild(config, "restoreDefaults").clicked();
|
||||
for (const area of ["empty", "tasks", "launcher", "clock", "tray", "other"]) {
|
||||
compare(config["cfg_" + area + "Action"], "volume");
|
||||
compare(findChild(config, area + "Action").currentValue, "volume");
|
||||
}
|
||||
compare(config.cfg_leftClick, "normal");
|
||||
compare(config.cfg_middleClick, "normal");
|
||||
compare(config.cfg_leftDoubleClick, "normal");
|
||||
compare(config.cfg_middleDoubleClick, "normal");
|
||||
compare(config.cfg_leftDoubleClickCommand, "");
|
||||
compare(config.cfg_middleDoubleClickApplication, "");
|
||||
compare(config.cfg_spacerLength, 48);
|
||||
config.destroy();
|
||||
component.destroy();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
import QtQuick
|
||||
import QtTest
|
||||
import se.ajpanton.panelactions 1.0
|
||||
|
||||
TestCase {
|
||||
name: "PanelPlugin"
|
||||
PanelController { id: controller }
|
||||
PanelSettings { id: panelSettings }
|
||||
function test_loadsInstalledTypes() {
|
||||
verify(controller !== null);
|
||||
verify(panelSettings.values.emptyAction !== undefined);
|
||||
}
|
||||
function test_widgetComponentsCompile() {
|
||||
for (const path of ["../package/contents/ui/main.qml", "../controller/contents/ui/main.qml"]) {
|
||||
const component = Qt.createComponent(path);
|
||||
compare(component.status, Component.Ready, component.errorString());
|
||||
component.destroy();
|
||||
}
|
||||
}
|
||||
function test_settingsWindowWithoutWidget() {
|
||||
const component = Qt.createComponent("../src/SettingsWindow.qml");
|
||||
compare(component.status, Component.Ready, component.errorString());
|
||||
const window = component.createObject(null);
|
||||
verify(window !== null);
|
||||
tryCompare(window, "visible", true);
|
||||
const form = findChild(window, "settingsForm");
|
||||
verify(form !== null);
|
||||
compare(form.cfg_tasksAction, panelSettings.values.tasksAction);
|
||||
compare(findChild(form, "tasksAction").currentValue, panelSettings.values.tasksAction);
|
||||
window.width = 600;
|
||||
window.height = 400;
|
||||
const save = findChild(window, "saveSettings");
|
||||
const page = window.pageStack.currentItem;
|
||||
tryVerify(() => page.flickable.contentHeight > page.flickable.height);
|
||||
tryVerify(() => {
|
||||
const position = save.mapToItem(window.contentItem, 0, 0);
|
||||
return position.y >= 0 && position.y + save.height <= window.height;
|
||||
});
|
||||
const saveY = save.mapToItem(window.contentItem, 0, 0).y;
|
||||
page.flickable.contentY = page.flickable.contentHeight - page.flickable.height;
|
||||
compare(save.mapToItem(window.contentItem, 0, 0).y, saveY);
|
||||
form.cfg_tasksAction = "brightness";
|
||||
save.clicked();
|
||||
compare(panelSettings.values.tasksAction, "brightness");
|
||||
window.close();
|
||||
window.destroy();
|
||||
component.destroy();
|
||||
}
|
||||
function test_clickDetailsWrap() {
|
||||
const component = Qt.createComponent("../src/SettingsWindow.qml");
|
||||
compare(component.status, Component.Ready, component.errorString());
|
||||
const window = component.createObject(null);
|
||||
verify(window !== null);
|
||||
const form = findChild(window, "settingsForm");
|
||||
form.cfg_leftClick = "application";
|
||||
form.applications = [{text: "A moderately long application name", value: "test.desktop"}];
|
||||
form.cfg_leftClickApplication = "test.desktop";
|
||||
form.cfg_middleClick = "command";
|
||||
const action = findChild(form, "leftClick");
|
||||
const application = findChild(form, "leftClickApplication");
|
||||
const middleAction = findChild(form, "middleClick");
|
||||
const command = findChild(form, "middleClickCommand");
|
||||
const scrollAction = findChild(form, "emptyAction");
|
||||
window.minimumWidth = 320;
|
||||
for (const width of [760, 360, 900]) {
|
||||
window.width = width;
|
||||
if (width === 360) {
|
||||
tryVerify(() => application.y >= action.y + action.height);
|
||||
tryVerify(() => command.y >= middleAction.y + middleAction.height);
|
||||
} else {
|
||||
tryVerify(() => application.x >= action.x + action.width && application.y === action.y);
|
||||
tryVerify(() => command.x >= middleAction.x + middleAction.width && command.y === middleAction.y);
|
||||
}
|
||||
verify(application.x + application.width <= application.parent.width);
|
||||
verify(command.x + command.width <= command.parent.width);
|
||||
tryCompare(application, "width", Math.min(application.implicitWidth, application.parent.width));
|
||||
tryVerify(() => Math.abs(command.x + command.width - command.parent.width) < 1);
|
||||
tryVerify(() => Math.abs(scrollAction.mapToItem(form, 0, 0).x - action.mapToItem(form, 0, 0).x) <= 1);
|
||||
}
|
||||
window.close();
|
||||
window.destroy();
|
||||
component.destroy();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user