Match Plasma panel edge areas for clicks and scrolling
This commit is contained in:
@@ -2,28 +2,23 @@
|
||||
.pragma library
|
||||
|
||||
// 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;
|
||||
const point = item.mapFromItem(null, x, y);
|
||||
if (vertical === undefined) {
|
||||
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.contains(point)) return false;
|
||||
if (item.tasksRoot !== undefined && item.isWindow !== undefined && item.index !== undefined) return true;
|
||||
for (const child of item.children) {
|
||||
if (hasTaskAt(child, x, y, vertical)) return true;
|
||||
if (hasTaskAt(child, x, y)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function appletArea(child, x, y, vertical) {
|
||||
function appletArea(child, x, y) {
|
||||
const applet = child.applet;
|
||||
const name = applet?.plasmoid?.pluginName;
|
||||
if (!name) return "other";
|
||||
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"
|
||||
|| name === "org.kde.plasma.marginsseparator") return "empty";
|
||||
@@ -34,8 +29,31 @@ function appletArea(child, x, y, vertical) {
|
||||
return "other";
|
||||
}
|
||||
|
||||
function areaAt(panelLayout, x, y) {
|
||||
if (!panelLayout) return "";
|
||||
function panelViewFor(item) {
|
||||
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) {
|
||||
if (child.visible && child.contains(child.mapFromItem(null, x, y))) {
|
||||
return appletArea(child, x, y);
|
||||
@@ -43,29 +61,3 @@ function areaAt(panelLayout, x, y) {
|
||||
}
|
||||
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 {
|
||||
id: root
|
||||
readonly property Item panelView: Areas.panelViewFor(root)
|
||||
readonly property Item panelLayout: {
|
||||
let item = root.parent;
|
||||
while (item) {
|
||||
@@ -26,10 +27,8 @@ PlasmoidItem {
|
||||
preferredRepresentation: fullRepresentation
|
||||
PanelSettings { id: settings }
|
||||
PanelController {
|
||||
active: root.panelLayout !== null && !(Plasmoid.containment.corona?.editMode ?? false)
|
||||
locateArea: (x, y, scrolling) => scrolling
|
||||
? Areas.scrollAreaAt(root.panelLayout, x, y, Plasmoid.formFactor === PlasmaCore.Types.Vertical)
|
||||
: Areas.areaAt(root.panelLayout, x, y)
|
||||
active: root.panelLayout !== null && root.panelView !== null && !(Plasmoid.containment.corona?.editMode ?? false)
|
||||
locateArea: (x, y) => Areas.areaAt(root.panelLayout, x, y, root.panelView)
|
||||
scrollActions: ({
|
||||
empty: settings.values.emptyAction,
|
||||
tasks: settings.values.tasksAction,
|
||||
|
||||
Reference in New Issue
Block a user