Match Plasma panel edge areas for clicks and scrolling
This commit is contained in:
@@ -15,10 +15,11 @@ Other choices are screen brightness, keyboard backlight, virtual desktops, and
|
|||||||
normal widget behaviour. Actions use Plasma's existing shortcuts, including its
|
normal widget behaviour. Actions use Plasma's existing shortcuts, including its
|
||||||
usual volume/brightness steps and on-screen indicators.
|
usual volume/brightness steps and on-screen indicators.
|
||||||
|
|
||||||
For scrolling, applet areas extend through the panel's thickness, and the first
|
Clicks and scrolling use Plasma's panel content boundaries and live theme
|
||||||
and last visible items include the outer end padding. These areas follow the
|
padding. Outer-margin input belongs to the same widget as a normal panel click,
|
||||||
actual layout, without fixed pixel offsets. Interior gaps, explicit spacers,
|
including the launcher at a screen corner. Interior gaps, explicit spacers and
|
||||||
and unused Task Manager space remain empty. Click hit areas are unchanged.
|
unused Task Manager space remain empty. Widget clicks pass through to Plasma;
|
||||||
|
no synthetic clicks or fixed area-expansion offsets are used.
|
||||||
|
|
||||||
Left and middle clicks, and double clicks, on empty space can toggle mute, show
|
Left and middle clicks, and double clicks, on empty space can toggle mute, show
|
||||||
the desktop, open Overview, play/pause media, launch an installed application,
|
the desktop, open Overview, play/pause media, launch an installed application,
|
||||||
|
|||||||
@@ -2,28 +2,23 @@
|
|||||||
.pragma library
|
.pragma library
|
||||||
|
|
||||||
// Task Manager fills unused panel space. Only delegates are task buttons.
|
// Task Manager fills unused panel space. Only delegates are task buttons.
|
||||||
function hasTaskAt(item, x, y, vertical) {
|
function hasTaskAt(item, x, y) {
|
||||||
if (!item.visible) return false;
|
if (!item.visible) return false;
|
||||||
const point = item.mapFromItem(null, x, y);
|
const point = item.mapFromItem(null, x, y);
|
||||||
if (vertical === undefined) {
|
|
||||||
if (!item.contains(point)) return false;
|
if (!item.contains(point)) return false;
|
||||||
} else if (item.width <= 0 || item.height <= 0
|
|
||||||
|| (vertical ? point.y < 0 || point.y > item.height : point.x < 0 || point.x > item.width)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (item.tasksRoot !== undefined && item.isWindow !== undefined && item.index !== undefined) return true;
|
if (item.tasksRoot !== undefined && item.isWindow !== undefined && item.index !== undefined) return true;
|
||||||
for (const child of item.children) {
|
for (const child of item.children) {
|
||||||
if (hasTaskAt(child, x, y, vertical)) return true;
|
if (hasTaskAt(child, x, y)) return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function appletArea(child, x, y, vertical) {
|
function appletArea(child, x, y) {
|
||||||
const applet = child.applet;
|
const applet = child.applet;
|
||||||
const name = applet?.plasmoid?.pluginName;
|
const name = applet?.plasmoid?.pluginName;
|
||||||
if (!name) return "other";
|
if (!name) return "other";
|
||||||
if (name === "org.kde.plasma.taskmanager" || name === "org.kde.plasma.icontasks") {
|
if (name === "org.kde.plasma.taskmanager" || name === "org.kde.plasma.icontasks") {
|
||||||
return hasTaskAt(applet, x, y, vertical) ? "tasks" : "empty";
|
return hasTaskAt(applet, x, y) ? "tasks" : "empty";
|
||||||
}
|
}
|
||||||
if (name === "se.ajpanton.panelactions" || name === "org.kde.plasma.panelspacer"
|
if (name === "se.ajpanton.panelactions" || name === "org.kde.plasma.panelspacer"
|
||||||
|| name === "org.kde.plasma.marginsseparator") return "empty";
|
|| name === "org.kde.plasma.marginsseparator") return "empty";
|
||||||
@@ -34,8 +29,31 @@ function appletArea(child, x, y, vertical) {
|
|||||||
return "other";
|
return "other";
|
||||||
}
|
}
|
||||||
|
|
||||||
function areaAt(panelLayout, x, y) {
|
function panelViewFor(item) {
|
||||||
if (!panelLayout) return "";
|
for (let parent = item.parent; parent; parent = parent.parent) {
|
||||||
|
if (parent.containment && parent.leftPadding !== undefined
|
||||||
|
&& parent.rightPadding !== undefined && parent.topPadding !== undefined
|
||||||
|
&& parent.bottomPadding !== undefined) return parent;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function areaAt(panelLayout, x, y, panelView) {
|
||||||
|
if (!panelLayout || !panelView?.containment) return "";
|
||||||
|
// Match Plasma PanelView's containmentContainsPosition / positionAdjustedForContainment.
|
||||||
|
// Read the same live theme padding and containment origin, including floating offsets.
|
||||||
|
const containment = panelView.containment;
|
||||||
|
const origin = containment.mapToItem(null, 0, 0);
|
||||||
|
const left = origin.x + panelView.leftPadding;
|
||||||
|
const top = origin.y + panelView.topPadding;
|
||||||
|
const right = origin.x + containment.width - panelView.rightPadding;
|
||||||
|
const bottom = origin.y + containment.height - panelView.bottomPadding;
|
||||||
|
if (right <= left || bottom <= top) return "";
|
||||||
|
if (x < left || x >= right || y < top || y >= bottom) {
|
||||||
|
// The trailing boundary itself is outside Qt Quick's input area.
|
||||||
|
x = Math.max(left, Math.min(x, right - 1));
|
||||||
|
y = Math.max(top, Math.min(y, bottom - 1));
|
||||||
|
}
|
||||||
for (const child of panelLayout.children) {
|
for (const child of panelLayout.children) {
|
||||||
if (child.visible && child.contains(child.mapFromItem(null, x, y))) {
|
if (child.visible && child.contains(child.mapFromItem(null, x, y))) {
|
||||||
return appletArea(child, x, y);
|
return appletArea(child, x, y);
|
||||||
@@ -43,29 +61,3 @@ function areaAt(panelLayout, x, y) {
|
|||||||
}
|
}
|
||||||
return "empty";
|
return "empty";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Scrolling owns the full panel thickness and its outer end padding. Interior
|
|
||||||
// gaps and explicit spacers remain empty; clicks keep their exact hit testing.
|
|
||||||
function scrollAreaAt(panelLayout, x, y, vertical) {
|
|
||||||
if (!panelLayout) return "";
|
|
||||||
const point = panelLayout.mapFromItem(null, x, y);
|
|
||||||
const along = vertical ? point.y : point.x;
|
|
||||||
let first = null;
|
|
||||||
let last = null;
|
|
||||||
for (const child of panelLayout.children) {
|
|
||||||
if (!child.visible || child.width <= 0 || child.height <= 0) continue;
|
|
||||||
const a = child.mapToItem(panelLayout, 0, 0);
|
|
||||||
const b = child.mapToItem(panelLayout, child.width, child.height);
|
|
||||||
const start = vertical ? Math.min(a.y, b.y) : Math.min(a.x, b.x);
|
|
||||||
const end = vertical ? Math.max(a.y, b.y) : Math.max(a.x, b.x);
|
|
||||||
if (end <= start) continue;
|
|
||||||
if (along >= start && along < end) return appletArea(child, x, y, vertical);
|
|
||||||
if (!first || start < first.start) first = {child, start};
|
|
||||||
if (!last || end > last.end) last = {child, end};
|
|
||||||
}
|
|
||||||
const edge = first && along < first.start ? first : last && along >= last.end ? last : null;
|
|
||||||
if (!edge) return "empty";
|
|
||||||
const boundary = edge === first ? first.start : last.end;
|
|
||||||
const projected = panelLayout.mapToItem(null, vertical ? point.x : boundary, vertical ? boundary : point.y);
|
|
||||||
return appletArea(edge.child, projected.x, projected.y, vertical);
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import "areas.js" as Areas
|
|||||||
|
|
||||||
PlasmoidItem {
|
PlasmoidItem {
|
||||||
id: root
|
id: root
|
||||||
|
readonly property Item panelView: Areas.panelViewFor(root)
|
||||||
readonly property Item panelLayout: {
|
readonly property Item panelLayout: {
|
||||||
let item = root.parent;
|
let item = root.parent;
|
||||||
while (item) {
|
while (item) {
|
||||||
@@ -26,10 +27,8 @@ PlasmoidItem {
|
|||||||
preferredRepresentation: fullRepresentation
|
preferredRepresentation: fullRepresentation
|
||||||
PanelSettings { id: settings }
|
PanelSettings { id: settings }
|
||||||
PanelController {
|
PanelController {
|
||||||
active: root.panelLayout !== null && !(Plasmoid.containment.corona?.editMode ?? false)
|
active: root.panelLayout !== null && root.panelView !== null && !(Plasmoid.containment.corona?.editMode ?? false)
|
||||||
locateArea: (x, y, scrolling) => scrolling
|
locateArea: (x, y) => Areas.areaAt(root.panelLayout, x, y, root.panelView)
|
||||||
? Areas.scrollAreaAt(root.panelLayout, x, y, Plasmoid.formFactor === PlasmaCore.Types.Vertical)
|
|
||||||
: Areas.areaAt(root.panelLayout, x, y)
|
|
||||||
scrollActions: ({
|
scrollActions: ({
|
||||||
empty: settings.values.emptyAction,
|
empty: settings.values.emptyAction,
|
||||||
tasks: settings.values.tasksAction,
|
tasks: settings.values.tasksAction,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
Name: plasma-panel-actions
|
Name: plasma-panel-actions
|
||||||
Version: 0.1.0
|
Version: 0.1.0
|
||||||
Release: 9%{?dist}
|
Release: 10%{?dist}
|
||||||
Summary: Configurable panel scrolling and empty-space click actions
|
Summary: Configurable panel scrolling and empty-space click actions
|
||||||
License: MIT
|
License: MIT
|
||||||
URL: https://git.ajpanton.se/ajp_anton/fedora-tools
|
URL: https://git.ajpanton.se/ajp_anton/fedora-tools
|
||||||
@@ -47,6 +47,8 @@ install -Dpm 0644 %{SOURCE1} %{buildroot}%{_licensedir}/%{name}/LICENSE
|
|||||||
%{_sysconfdir}/xdg/autostart/se.ajpanton.plasma-panel-actions-autostart.desktop
|
%{_sysconfdir}/xdg/autostart/se.ajpanton.plasma-panel-actions-autostart.desktop
|
||||||
%{_datadir}/fedora-tools/settings/plasma-panel-actions.json
|
%{_datadir}/fedora-tools/settings/plasma-panel-actions.json
|
||||||
%changelog
|
%changelog
|
||||||
|
* Fri Sep 11 2026 fedora-tools contributors - 0.1.0-10
|
||||||
|
- Use Plasma's content boundaries for both clicks and scrolling at panel edges
|
||||||
* Wed Sep 09 2026 fedora-tools contributors - 0.1.0-9
|
* Wed Sep 09 2026 fedora-tools contributors - 0.1.0-9
|
||||||
- Assign panel scroll margins using applet geometry without changing clicks
|
- Assign panel scroll margins using applet geometry without changing clicks
|
||||||
* Mon Sep 07 2026 fedora-tools contributors - 0.1.0-8
|
* Mon Sep 07 2026 fedora-tools contributors - 0.1.0-8
|
||||||
|
|||||||
@@ -50,12 +50,14 @@ PanelController::~PanelController()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QString PanelController::areaAt(const QPointF &position, bool scrolling)
|
QString PanelController::areaAt(const QPointF &position)
|
||||||
{
|
{
|
||||||
|
// Dragging outside the panel must not project back onto one of its widgets.
|
||||||
|
if (!m_panel || !QRectF(0, 0, m_panel->width(), m_panel->height()).contains(position)) return {};
|
||||||
if (!m_locateArea.isCallable()) {
|
if (!m_locateArea.isCallable()) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
const QJSValue result = m_locateArea.call({position.x(), position.y(), scrolling});
|
const QJSValue result = m_locateArea.call({position.x(), position.y()});
|
||||||
if (result.isError()) {
|
if (result.isError()) {
|
||||||
qWarning() << "Panel Actions: could not identify panel area:" << result.toString();
|
qWarning() << "Panel Actions: could not identify panel area:" << result.toString();
|
||||||
return {};
|
return {};
|
||||||
@@ -74,7 +76,7 @@ bool PanelController::eventFilter(QObject *object, QEvent *event)
|
|||||||
}
|
}
|
||||||
if (event->type() == QEvent::Wheel) {
|
if (event->type() == QEvent::Wheel) {
|
||||||
auto *wheel = static_cast<QWheelEvent *>(event);
|
auto *wheel = static_cast<QWheelEvent *>(event);
|
||||||
const QString area = areaAt(wheel->position(), true);
|
const QString area = areaAt(wheel->position());
|
||||||
const QString action = m_scrollActions.value(area, QStringLiteral("normal")).toString();
|
const QString action = m_scrollActions.value(area, QStringLiteral("normal")).toString();
|
||||||
if (action == QLatin1String("normal") || action.isEmpty()) {
|
if (action == QLatin1String("normal") || action.isEmpty()) {
|
||||||
m_remainder = 0;
|
m_remainder = 0;
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ Q_SIGNALS:
|
|||||||
protected:
|
protected:
|
||||||
bool eventFilter(QObject *object, QEvent *event) override;
|
bool eventFilter(QObject *object, QEvent *event) override;
|
||||||
private:
|
private:
|
||||||
QString areaAt(const QPointF &position, bool scrolling = false);
|
QString areaAt(const QPointF &position);
|
||||||
QPointer<QQuickWindow> m_panel;
|
QPointer<QQuickWindow> m_panel;
|
||||||
bool m_active = false;
|
bool m_active = false;
|
||||||
QJSValue m_locateArea;
|
QJSValue m_locateArea;
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ public:
|
|||||||
bool event(QEvent *event) override
|
bool event(QEvent *event) override
|
||||||
{
|
{
|
||||||
if (event->type() == QEvent::Wheel || event->type() == QEvent::MouseButtonPress
|
if (event->type() == QEvent::Wheel || event->type() == QEvent::MouseButtonPress
|
||||||
|| event->type() == QEvent::MouseButtonRelease || event->type() == QEvent::MouseMove) {
|
|| event->type() == QEvent::MouseButtonRelease || event->type() == QEvent::MouseButtonDblClick || event->type() == QEvent::MouseMove) {
|
||||||
++delivered;
|
++delivered;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -31,6 +31,7 @@ class PanelControllerTest : public QObject
|
|||||||
private:
|
private:
|
||||||
static void setup(PanelController &controller, PanelWindow &window, QJSEngine &engine)
|
static void setup(PanelController &controller, PanelWindow &window, QJSEngine &engine)
|
||||||
{
|
{
|
||||||
|
window.resize(400, 40);
|
||||||
controller.setParentItem(window.contentItem());
|
controller.setParentItem(window.contentItem());
|
||||||
controller.setProperty("active", true);
|
controller.setProperty("active", true);
|
||||||
controller.setProperty("locateArea", QVariant::fromValue(engine.evaluate(
|
controller.setProperty("locateArea", QVariant::fromValue(engine.evaluate(
|
||||||
@@ -52,15 +53,15 @@ private:
|
|||||||
QCoreApplication::sendEvent(&window, &event);
|
QCoreApplication::sendEvent(&window, &event);
|
||||||
}
|
}
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
void scrollHitTestingDoesNotExpandClickTargets()
|
void clicksAndScrollsShareWidgetAreas()
|
||||||
{
|
{
|
||||||
QJSEngine engine;
|
QJSEngine engine;
|
||||||
PanelWindow window;
|
PanelWindow window;
|
||||||
PanelController controller;
|
PanelController controller;
|
||||||
setup(controller, window, engine);
|
setup(controller, window, engine);
|
||||||
controller.setLocateArea(engine.evaluate(u"(function(x,y,scrolling) { return scrolling ? 'launcher' : 'empty'; })"_s));
|
controller.setLocateArea(engine.evaluate(u"(function(x,y) { return 'launcher'; })"_s));
|
||||||
controller.setProperty("scrollActions", QVariantMap{{u"launcher"_s, u"brightness"_s}, {u"empty"_s, u"volume"_s}});
|
controller.setProperty("scrollActions", QVariantMap{{u"launcher"_s, u"brightness"_s}, {u"empty"_s, u"volume"_s}});
|
||||||
controller.setProperty("clickActions", QVariantMap{{u"leftClick"_s, u"mute"_s}});
|
controller.setProperty("clickActions", QVariantMap{{u"leftClick"_s, u"mute"_s}, {u"leftDoubleClick"_s, u"overview"_s}});
|
||||||
QSignalSpy scrolling(&controller, &PanelController::actionRequested);
|
QSignalSpy scrolling(&controller, &PanelController::actionRequested);
|
||||||
QSignalSpy clicking(&controller, &PanelController::clickRequested);
|
QSignalSpy clicking(&controller, &PanelController::clickRequested);
|
||||||
wheel(window, 120);
|
wheel(window, 120);
|
||||||
@@ -68,8 +69,11 @@ private Q_SLOTS:
|
|||||||
QCOMPARE(scrolling.first(), QVariantList({u"brightness"_s, 1}));
|
QCOMPARE(scrolling.first(), QVariantList({u"brightness"_s, 1}));
|
||||||
mouse(window, QEvent::MouseButtonPress, 20);
|
mouse(window, QEvent::MouseButtonPress, 20);
|
||||||
mouse(window, QEvent::MouseButtonRelease, 20);
|
mouse(window, QEvent::MouseButtonRelease, 20);
|
||||||
QCOMPARE(clicking.count(), 1);
|
mouse(window, QEvent::MouseButtonPress, 20);
|
||||||
QCOMPARE(clicking.first(), QVariantList({u"leftClick"_s}));
|
mouse(window, QEvent::MouseButtonDblClick, 20);
|
||||||
|
mouse(window, QEvent::MouseButtonRelease, 20);
|
||||||
|
QCOMPARE(clicking.count(), 0);
|
||||||
|
QCOMPARE(window.delivered, 5); // Plasma handles both clicks, including margin forwarding.
|
||||||
}
|
}
|
||||||
void wheelOverridesAndNormalBehaviour()
|
void wheelOverridesAndNormalBehaviour()
|
||||||
{
|
{
|
||||||
@@ -145,11 +149,24 @@ private Q_SLOTS:
|
|||||||
mouse(window, QEvent::MouseButtonRelease, 20);
|
mouse(window, QEvent::MouseButtonRelease, 20);
|
||||||
QCOMPARE(actions.count(), 0);
|
QCOMPARE(actions.count(), 0);
|
||||||
}
|
}
|
||||||
|
void releaseOutsidePanelDoesNotClick()
|
||||||
|
{
|
||||||
|
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, 1);
|
||||||
|
mouse(window, QEvent::MouseButtonRelease, -1);
|
||||||
|
QCOMPARE(actions.count(), 0);
|
||||||
|
}
|
||||||
void disabledAndOtherWindowsAreUntouched()
|
void disabledAndOtherWindowsAreUntouched()
|
||||||
{
|
{
|
||||||
QJSEngine engine;
|
QJSEngine engine;
|
||||||
PanelWindow window;
|
PanelWindow window;
|
||||||
PanelWindow popup;
|
PanelWindow popup;
|
||||||
|
popup.resize(400, 40);
|
||||||
PanelController controller;
|
PanelController controller;
|
||||||
setup(controller, window, engine);
|
setup(controller, window, engine);
|
||||||
QSignalSpy actions(&controller, &PanelController::actionRequested);
|
QSignalSpy actions(&controller, &PanelController::actionRequested);
|
||||||
|
|||||||
@@ -4,6 +4,12 @@ import QtTest
|
|||||||
import "../controller/contents/ui/areas.js" as Areas
|
import "../controller/contents/ui/areas.js" as Areas
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
|
id: scene
|
||||||
|
property Item containment: edges
|
||||||
|
property int leftPadding: edges.vertical ? 8 : 12
|
||||||
|
property int rightPadding: edges.vertical ? 8 : 14
|
||||||
|
property int topPadding: edges.vertical ? 12 : 8
|
||||||
|
property int bottomPadding: edges.vertical ? 14 : 8
|
||||||
width: 600
|
width: 600
|
||||||
height: 100
|
height: 100
|
||||||
Item {
|
Item {
|
||||||
@@ -94,68 +100,72 @@ Item {
|
|||||||
function init() {
|
function init() {
|
||||||
edges.vertical = false;
|
edges.vertical = false;
|
||||||
edges.reversed = false;
|
edges.reversed = false;
|
||||||
edges.scale = 1;
|
edges.x = 40;
|
||||||
launcher.visible = true;
|
launcher.visible = true;
|
||||||
}
|
}
|
||||||
function scrollAt(along, across) {
|
function areaAt(along, across) {
|
||||||
const p = edges.mapToItem(null, edges.vertical ? across : along, edges.vertical ? along : across);
|
const p = edges.mapToItem(null, edges.vertical ? across : along, edges.vertical ? along : across);
|
||||||
return Areas.scrollAreaAt(edges, p.x, p.y, edges.vertical);
|
return Areas.areaAt(edges, p.x, p.y, scene);
|
||||||
}
|
}
|
||||||
function test_scrollMargins_data() {
|
function test_panelMargins_data() {
|
||||||
return [
|
return [
|
||||||
{tag: "horizontal", vertical: false, scale: 1},
|
{tag: "horizontal", vertical: false, x: 40},
|
||||||
{tag: "vertical", vertical: true, scale: 1},
|
{tag: "vertical", vertical: true, x: 40},
|
||||||
{tag: "scaled", vertical: false, scale: 1.5},
|
{tag: "fractional-origin", vertical: false, x: 40.5},
|
||||||
{tag: "vertical-scaled", vertical: true, scale: 1.5}
|
{tag: "vertical-fractional-origin", vertical: true, x: 40.5}
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
function test_scrollMargins(data) {
|
function test_panelMargins(data) {
|
||||||
edges.vertical = data.vertical;
|
edges.vertical = data.vertical;
|
||||||
edges.scale = data.scale;
|
edges.x = data.x;
|
||||||
compare(scrollAt(-20, 58), "launcher"); // leading outer corner
|
compare(areaAt(-20, 58), "launcher"); // leading outer corner
|
||||||
compare(scrollAt(30, 2), "launcher"); // thickness padding above/beside icon
|
compare(areaAt(30, 2), "launcher"); // thickness padding above/beside icon
|
||||||
compare(scrollAt(420, 58), "clock"); // trailing outer corner
|
compare(areaAt(420, 58), "clock"); // trailing outer corner
|
||||||
compare(scrollAt(65, 58), "empty"); // internal gap
|
compare(areaAt(386, 52), "clock"); // exclusive bottom/right boundaries
|
||||||
compare(scrollAt(120, 58), "empty"); // explicit spacer
|
compare(areaAt(385.75, 51.75), "clock"); // fractional positions just inside
|
||||||
compare(scrollAt(200, 58), "empty");
|
compare(areaAt(65, 58), "empty"); // internal gap
|
||||||
|
compare(areaAt(120, 58), "empty"); // explicit spacer
|
||||||
|
compare(areaAt(200, 58), "empty");
|
||||||
edges.reversed = true; // physical order, not QObject child order
|
edges.reversed = true; // physical order, not QObject child order
|
||||||
compare(scrollAt(-20, 58), "clock");
|
compare(areaAt(-20, 58), "clock");
|
||||||
compare(scrollAt(420, 58), "launcher");
|
compare(areaAt(420, 58), "launcher");
|
||||||
}
|
}
|
||||||
function test_clickMarginsStayEmpty() {
|
function test_panelViewDiscovery() {
|
||||||
const p = edges.mapToItem(null, -20, 58);
|
compare(Areas.panelViewFor(launcher), scene);
|
||||||
compare(Areas.areaAt(edges, p.x, p.y), "empty");
|
|
||||||
compare(Areas.scrollAreaAt(edges, p.x, p.y, false), "launcher");
|
|
||||||
const inside = launcher.mapToItem(null, 10, 10);
|
const inside = launcher.mapToItem(null, 10, 10);
|
||||||
compare(Areas.areaAt(edges, inside.x, inside.y), "launcher");
|
compare(Areas.areaAt(edges, inside.x, inside.y, scene), "launcher");
|
||||||
|
compare(Areas.areaAt(edges, inside.x, inside.y, null), "");
|
||||||
}
|
}
|
||||||
function test_hiddenAndZeroSizeDoNotOwnPadding() {
|
function test_hiddenAndZeroSizeDoNotOwnPadding() {
|
||||||
launcher.visible = false;
|
launcher.visible = false;
|
||||||
compare(scrollAt(-20, 58), "empty"); // spacer becomes first
|
compare(areaAt(-20, 58), "empty"); // don't stretch the next widget into a real gap
|
||||||
compare(Areas.scrollAreaAt(null, 0, 0, false), "");
|
compare(Areas.areaAt(null, 0, 0, scene), "");
|
||||||
|
}
|
||||||
|
function taskArea(x, y) {
|
||||||
|
return Areas.areaAt(panel, x, y, {containment: panel,
|
||||||
|
leftPadding: 0, rightPadding: 0, topPadding: 0, bottomPadding: 0});
|
||||||
}
|
}
|
||||||
function test_taskThicknessPaddingKeepsUnusedSpaceEmpty() {
|
function test_taskThicknessPaddingKeepsUnusedSpaceEmpty() {
|
||||||
compare(Areas.scrollAreaAt(panel, 40, 65, false), "tasks");
|
compare(taskArea(40, 65), "tasks");
|
||||||
compare(Areas.scrollAreaAt(panel, 150, 65, false), "empty");
|
compare(taskArea(150, 65), "empty");
|
||||||
compare(Areas.areaAt(panel, 40, 65), "empty");
|
compare(taskArea(0, 65), "tasks");
|
||||||
compare(Areas.scrollAreaAt(panel, 0, 65, false), "tasks");
|
|
||||||
}
|
}
|
||||||
function test_taskButtonsVersusUnusedSpace() {
|
function test_taskButtonsVersusUnusedSpace() {
|
||||||
compare(Areas.areaAt(panel, 40, 30), "tasks");
|
compare(taskArea(40, 30), "tasks");
|
||||||
compare(Areas.areaAt(panel, 150, 30), "empty");
|
compare(taskArea(150, 30), "empty");
|
||||||
button.isWindow = false; // pinned launchers still count as buttons
|
button.isWindow = false; // pinned launchers still count as buttons
|
||||||
compare(Areas.areaAt(panel, 40, 30), "tasks");
|
compare(taskArea(40, 30), "tasks");
|
||||||
button.visible = false;
|
button.visible = false;
|
||||||
compare(Areas.areaAt(panel, 40, 30), "empty");
|
compare(taskArea(40, 30), "empty");
|
||||||
button.visible = true;
|
button.visible = true;
|
||||||
}
|
}
|
||||||
function test_trayAndUnrecognizedWidgetsKeepClicks() {
|
function test_trayAndUnrecognizedWidgetsKeepClicks() {
|
||||||
compare(Areas.areaAt(panel, 240, 30), "tray");
|
compare(taskArea(240, 30), "tray");
|
||||||
compare(Areas.areaAt(panel, 300, 30), "other");
|
compare(taskArea(300, 30), "other");
|
||||||
arbitraryWidget.visible = false;
|
arbitraryWidget.visible = false;
|
||||||
compare(Areas.areaAt(panel, 300, 30), "empty");
|
compare(taskArea(300, 30), "empty");
|
||||||
arbitraryWidget.visible = true;
|
arbitraryWidget.visible = true;
|
||||||
compare(Areas.areaAt(null, 40, 30), "");
|
compare(Areas.areaAt(null, 40, 30, scene), "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user