Park focus on a sink Item when leaving body
The previous clearBodyFocus() set focus = false on navRoot.activeFocusItem and called navRoot.forceActiveFocus(), which works for plain Rectangles but not for Controls 2 widgets like ComboBox: the combo keeps an internal focused child that the surrounding FocusScope happily restores, so the accent focus border on the Position/Center anchor dropdowns lingered after backing out to the sidebar. Add an invisible 1x1 navFocusSink Item inside navRoot and force focus onto it whenever the user leaves the body (h/Esc/Shift-Tab, category changes from sidebar nav, or panel reopens). The sink reliably owns activeFocus so every body control \u2014 ComboBox included \u2014 falls back to its unfocused style.
This commit is contained in:
@@ -30,7 +30,7 @@ Item {
|
|||||||
root.syncSidebarIndexFromCategory()
|
root.syncSidebarIndexFromCategory()
|
||||||
root.focusZone = "sidebar"
|
root.focusZone = "sidebar"
|
||||||
window.visible = true
|
window.visible = true
|
||||||
Qt.callLater(function() { if (navRoot) navRoot.forceActiveFocus() })
|
Qt.callLater(parkFocusOnSink)
|
||||||
}
|
}
|
||||||
|
|
||||||
function close() {
|
function close() {
|
||||||
@@ -108,17 +108,17 @@ Item {
|
|||||||
|
|
||||||
function exitBodyZone() {
|
function exitBodyZone() {
|
||||||
focusZone = "sidebar"
|
focusZone = "sidebar"
|
||||||
clearBodyFocus()
|
parkFocusOnSink()
|
||||||
if (navRoot) navRoot.forceActiveFocus()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Drop activeFocus from any body item so its focus ring goes away when
|
// Move activeFocus to a dedicated sink Item that lives outside the body
|
||||||
// the user backs out to the sidebar. Without this, FocusScope remembers
|
// tree. Just clearing focus on the previously focused descendant isn't
|
||||||
// the last focused descendant and the highlight lingers.
|
// enough — controls like ComboBox keep an internal focused child that
|
||||||
function clearBodyFocus() {
|
// FocusScope happily restores. Forcing focus onto a known sink reliably
|
||||||
if (!navRoot) return
|
// clears every body focus ring.
|
||||||
var afi = navRoot.activeFocusItem
|
function parkFocusOnSink() {
|
||||||
if (afi && afi !== navRoot) afi.focus = false
|
if (typeof navFocusSink !== "undefined" && navFocusSink) navFocusSink.forceActiveFocus()
|
||||||
|
else if (navRoot) navRoot.forceActiveFocus()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Walk the visible body subtree and collect any item with
|
// Walk the visible body subtree and collect any item with
|
||||||
@@ -181,7 +181,7 @@ Item {
|
|||||||
onActiveCategoryChanged: {
|
onActiveCategoryChanged: {
|
||||||
syncSidebarIndexFromCategory()
|
syncSidebarIndexFromCategory()
|
||||||
if (focusZone === "body") Qt.callLater(focusFirstBodyItem)
|
if (focusZone === "body") Qt.callLater(focusFirstBodyItem)
|
||||||
else clearBodyFocus()
|
else parkFocusOnSink()
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------- bundled defaults ---------------------------------------
|
// ---------------- bundled defaults ---------------------------------------
|
||||||
@@ -599,7 +599,7 @@ Item {
|
|||||||
onVisibleChanged: {
|
onVisibleChanged: {
|
||||||
if (!visible && !root.closingFromHost && root.shell && typeof root.shell.hide === "function")
|
if (!visible && !root.closingFromHost && root.shell && typeof root.shell.hide === "function")
|
||||||
root.shell.hide("omarchy.settings")
|
root.shell.hide("omarchy.settings")
|
||||||
if (visible) Qt.callLater(function() { if (navRoot) navRoot.forceActiveFocus() })
|
if (visible) Qt.callLater(root.parkFocusOnSink)
|
||||||
}
|
}
|
||||||
|
|
||||||
FocusScope {
|
FocusScope {
|
||||||
@@ -607,7 +607,17 @@ Item {
|
|||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
focus: true
|
focus: true
|
||||||
|
|
||||||
Component.onCompleted: forceActiveFocus()
|
Component.onCompleted: navFocusSink.forceActiveFocus()
|
||||||
|
|
||||||
|
// Invisible focus sink. When focus belongs to the sidebar (no
|
||||||
|
// specific body item focused), activeFocus lives on this 1px Item so
|
||||||
|
// body controls render their unfocused state cleanly.
|
||||||
|
Item {
|
||||||
|
id: navFocusSink
|
||||||
|
width: 1
|
||||||
|
height: 1
|
||||||
|
objectName: "navFocusSink"
|
||||||
|
}
|
||||||
|
|
||||||
Keys.priority: Keys.BeforeItem
|
Keys.priority: Keys.BeforeItem
|
||||||
Keys.onPressed: function(event) {
|
Keys.onPressed: function(event) {
|
||||||
|
|||||||
Reference in New Issue
Block a user