Make the open-panel mark find and fit its module
A center-anchored module is mounted twice: the copy that is drawn, and a zero-size placeholder holding its place in the flow beside the anchor. findPanelWidget returned whichever registered first, and that order is not stable across a live bar reconfiguration, so a panel could open anchored to the invisible copy -- mispositioned, with the drawn slot never lighting up and switchPanelFrom unable to find it again. The mark was also always 55% of the slot, which fits an icon but underlines only a fraction of a text label, and runs the full height of a multi-line module on a vertical bar. Modules can now say how long the mark should be along the bar; anything that does not answer keeps the old proportion. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
d4c835afb5
commit
6d4fa7acaf
@@ -406,15 +406,19 @@ Item {
|
||||
function findPanelWidget(pluginId) {
|
||||
var id = String(pluginId || "")
|
||||
if (!id) return null
|
||||
var candidates = []
|
||||
for (var i = 0; i < moduleSlots.length; i++) {
|
||||
var slot = moduleSlots[i]
|
||||
if (!slot || !slot.activeItem) continue
|
||||
if (slot.moduleName !== id) continue
|
||||
var item = slot.activeItem
|
||||
if (typeof item.open !== "function" || typeof item.close !== "function" || item.opened === undefined) continue
|
||||
return item
|
||||
candidates.push(slot)
|
||||
}
|
||||
return null
|
||||
// Anchored center modules are mounted twice; only the drawn copy can
|
||||
// anchor a popup or carry the open-panel mark. See BarModel.pickDrawnSlot.
|
||||
var chosen = BarModel.pickDrawnSlot(candidates)
|
||||
return chosen ? chosen.activeItem : null
|
||||
}
|
||||
|
||||
function summonBarWidget(pluginId) {
|
||||
@@ -1386,6 +1390,16 @@ Item {
|
||||
readonly property bool hovered: moduleHover.hovered
|
||||
readonly property bool dragSource: root.barDragSource === slot
|
||||
readonly property bool panelOpen: root.activePopout === slot.activeItem
|
||||
// Modules bigger than the mark they want (a text label in a padded slot,
|
||||
// a multi-line stack on a vertical bar) can say how long the open-panel
|
||||
// dot should be along the bar, so it tracks what the module paints
|
||||
// instead of a fraction of whatever slot it happens to fill.
|
||||
readonly property real panelIndicatorExtent: {
|
||||
var key = root.vertical ? "openPanelIndicatorHeight" : "openPanelIndicatorWidth"
|
||||
var hint = activeItem && key in activeItem ? activeItem[key] : undefined
|
||||
if (hint !== undefined && hint !== null && hint > 0) return Math.round(hint)
|
||||
return Math.max(Style.space(10), Math.round((root.vertical ? slot.height : slot.width) * 0.55))
|
||||
}
|
||||
implicitWidth: activeItem && activeItem.visible ? (root.vertical ? root.barSize : activeItem.implicitWidth) : 0
|
||||
implicitHeight: activeItem && activeItem.visible ? activeItem.implicitHeight : 0
|
||||
width: implicitWidth
|
||||
@@ -1455,8 +1469,12 @@ Item {
|
||||
opacity: slot.panelOpen && !slot.dragSource ? 0.9 : 0
|
||||
color: Color.accent
|
||||
radius: Math.min(width, height) / 2
|
||||
width: root.vertical ? Style.space(2) : Math.max(Style.space(10), Math.round(parent.width * 0.55))
|
||||
height: root.vertical ? Math.max(Style.space(10), Math.round(parent.height * 0.55)) : Style.space(2)
|
||||
width: root.vertical ? Style.space(2) : slot.panelIndicatorExtent
|
||||
height: root.vertical ? slot.panelIndicatorExtent : Style.space(2)
|
||||
// The mark sits on the module's inner edge — the one facing the
|
||||
// desktop — so it underlines a top bar, overlines a bottom one, and
|
||||
// points inward from a left or right one. It reads as pointing at the
|
||||
// panel that opens on that side.
|
||||
x: root.vertical
|
||||
? (root.position === "left" ? parent.width - width - inset : inset)
|
||||
: Math.round((parent.width - width) / 2)
|
||||
|
||||
@@ -96,8 +96,32 @@ function customModulePath(entry, home, configDir) {
|
||||
return source
|
||||
}
|
||||
|
||||
// A center module is mounted twice once an anchor is set: the copy that is
|
||||
// actually drawn, and a zero-size placeholder holding its place in the flow
|
||||
// beside the anchor. Panel routing has to pick the drawn one — it is the only
|
||||
// one that can anchor a popup, carry the open-panel mark, or be found again
|
||||
// by switchPanelFrom — and fall back to the placeholder only when nothing is
|
||||
// on screen. The order the two are registered in is not stable across a live
|
||||
// bar reconfiguration, so picking the first match is not good enough.
|
||||
function isDrawnSlot(slot) {
|
||||
return !!slot && slot.visible === true && slot.width > 0 && slot.height > 0
|
||||
}
|
||||
|
||||
function pickDrawnSlot(slots) {
|
||||
var placeholder = null
|
||||
var list = slots || []
|
||||
for (var i = 0; i < list.length; i++) {
|
||||
if (!list[i]) continue
|
||||
if (isDrawnSlot(list[i])) return list[i]
|
||||
if (!placeholder) placeholder = list[i]
|
||||
}
|
||||
return placeholder
|
||||
}
|
||||
|
||||
if (typeof module !== "undefined") {
|
||||
module.exports = {
|
||||
isDrawnSlot: isDrawnSlot,
|
||||
pickDrawnSlot: pickDrawnSlot,
|
||||
normalizePosition: normalizePosition,
|
||||
entrySettings: entrySettings,
|
||||
entryId: entryId,
|
||||
|
||||
Reference in New Issue
Block a user