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.focusZone = "sidebar"
|
||||
window.visible = true
|
||||
Qt.callLater(function() { if (navRoot) navRoot.forceActiveFocus() })
|
||||
Qt.callLater(parkFocusOnSink)
|
||||
}
|
||||
|
||||
function close() {
|
||||
@@ -108,17 +108,17 @@ Item {
|
||||
|
||||
function exitBodyZone() {
|
||||
focusZone = "sidebar"
|
||||
clearBodyFocus()
|
||||
if (navRoot) navRoot.forceActiveFocus()
|
||||
parkFocusOnSink()
|
||||
}
|
||||
|
||||
// Drop activeFocus from any body item so its focus ring goes away when
|
||||
// the user backs out to the sidebar. Without this, FocusScope remembers
|
||||
// the last focused descendant and the highlight lingers.
|
||||
function clearBodyFocus() {
|
||||
if (!navRoot) return
|
||||
var afi = navRoot.activeFocusItem
|
||||
if (afi && afi !== navRoot) afi.focus = false
|
||||
// Move activeFocus to a dedicated sink Item that lives outside the body
|
||||
// tree. Just clearing focus on the previously focused descendant isn't
|
||||
// enough — controls like ComboBox keep an internal focused child that
|
||||
// FocusScope happily restores. Forcing focus onto a known sink reliably
|
||||
// clears every body focus ring.
|
||||
function parkFocusOnSink() {
|
||||
if (typeof navFocusSink !== "undefined" && navFocusSink) navFocusSink.forceActiveFocus()
|
||||
else if (navRoot) navRoot.forceActiveFocus()
|
||||
}
|
||||
|
||||
// Walk the visible body subtree and collect any item with
|
||||
@@ -181,7 +181,7 @@ Item {
|
||||
onActiveCategoryChanged: {
|
||||
syncSidebarIndexFromCategory()
|
||||
if (focusZone === "body") Qt.callLater(focusFirstBodyItem)
|
||||
else clearBodyFocus()
|
||||
else parkFocusOnSink()
|
||||
}
|
||||
|
||||
// ---------------- bundled defaults ---------------------------------------
|
||||
@@ -599,7 +599,7 @@ Item {
|
||||
onVisibleChanged: {
|
||||
if (!visible && !root.closingFromHost && root.shell && typeof root.shell.hide === "function")
|
||||
root.shell.hide("omarchy.settings")
|
||||
if (visible) Qt.callLater(function() { if (navRoot) navRoot.forceActiveFocus() })
|
||||
if (visible) Qt.callLater(root.parkFocusOnSink)
|
||||
}
|
||||
|
||||
FocusScope {
|
||||
@@ -607,7 +607,17 @@ Item {
|
||||
anchors.fill: parent
|
||||
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.onPressed: function(event) {
|
||||
|
||||
Reference in New Issue
Block a user