Skip to content

Commit 8773dc1

Browse files
JWWTSLdeepin-bot[bot]
authored andcommitted
fix: Optimize tab focus navigation in Remote Management
log: setCurrentIndex(...) is called synchronously within the focusOut slot, which triggers setFocus() on the newly selected ItemWidget. Although Qt's focus transfer doesn't actually complete until after focusOutEvent finishes, calling setFocus() synchronously inside a slot is an established pattern already used by existing lambdas in this codebase (the original code also directly called m_pushButton->setFocus() in the slot), so it should be stable. If focus jittering or recursion occurs during testing, fall back to using QMetaObject::invokeMethod(..., Qt::QueuedConnection) for deferred execution. pms: bug-283743
1 parent d3a23b2 commit 8773dc1

3 files changed

Lines changed: 66 additions & 8 deletions

File tree

src/remotemanage/remotemanagementpanel.cpp

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,9 @@ void RemoteManagementPanel::setFocusInPanel()
4747
qCDebug(remotemanage) << "list widget is visible, setting focus";
4848
// 列表显示
4949
/******** Modify by ut000610 daizhengwen 2020-07-27:bug#39775 Begin***************/
50-
// 将焦点设置在列表里的第一项
51-
m_listWidget->setCurrentIndex(0);
50+
// 将焦点设置在列表里的第一个可聚焦项
51+
int idx = m_listWidget->firstFocusableIndex();
52+
m_listWidget->setCurrentIndex(idx >= 0 ? idx : 0);
5253
/********************* Modify by ut000610 daizhengwen End ************************/
5354
} else {
5455
qCDebug(remotemanage) << "setting focus on add button";
@@ -330,21 +331,36 @@ void RemoteManagementPanel::initUI()
330331
});
331332
connect(m_listWidget, &ListView::focusOut, this, [ = ](Qt::FocusReason type) {
332333
qCDebug(remotemanage) << "Lambda: list widget focus out signal received";
333-
if (Qt::TabFocusReason == type || Qt::NoFocusReason == type) {
334-
qCDebug(remotemanage) << "tab or no focus reason, setting focus to add button";
335-
// 下一个 或 列表为空, 焦点定位到添加按钮上
334+
if (Qt::TabFocusReason == type) {
335+
int next = m_listWidget->nextFocusableIndex(m_listWidget->currentIndex());
336+
if (next >= 0) {
337+
m_listWidget->setCurrentIndex(next);
338+
return;
339+
}
340+
// 已到末项或列表空 → 跳到 Add Server
336341
m_pushButton->setFocus();
337342
m_listWidget->clearIndex();
338343
qCInfo(remotemanage) << "set focus on add pushButton";
339344
} else if (Qt::BacktabFocusReason == type) {
340345
qCDebug(remotemanage) << "back tab focus reason";
341-
// 判断是否可见,可见设置焦点
346+
int prev = m_listWidget->prevFocusableIndex(m_listWidget->currentIndex());
347+
if (prev >= 0) {
348+
m_listWidget->setCurrentIndex(prev);
349+
return;
350+
}
351+
// 已到首项 → 回搜索框(如可见)
342352
if (m_searchEdit->isVisible()) {
343353
qCDebug(remotemanage) << "search edit is visible, setting focus";
344354
m_searchEdit->lineEdit()->setFocus();
345355
m_listWidget->clearIndex();
346-
qCInfo(remotemanage) << "set focus on add search edit";
356+
qCInfo(remotemanage) << "set focus on search edit";
347357
}
358+
} else if (Qt::NoFocusReason == type) {
359+
qCDebug(remotemanage) << "no focus reason, setting focus to add button";
360+
// 列表为空或索引无效 → 跳到 Add Server
361+
m_pushButton->setFocus();
362+
m_listWidget->clearIndex();
363+
qCInfo(remotemanage) << "set focus on add pushButton";
348364
}
349365
});
350366

src/views/listview.cpp

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,39 @@ int ListView::getNextIndex(int index)
225225
}
226226
}
227227

228+
static bool isFocusableItemType(ItemFuncType t)
229+
{
230+
return t != ItemFuncType_GroupLabel && t != ItemFuncType_ItemLabel;
231+
}
232+
233+
int ListView::firstFocusableIndex()
234+
{
235+
for (int i = 0; i < m_itemList.count(); ++i)
236+
if (isFocusableItemType(m_itemList.at(i)->getFuncType())) return i;
237+
return -1;
238+
}
239+
240+
int ListView::lastFocusableIndex()
241+
{
242+
for (int i = m_itemList.count() - 1; i >= 0; --i)
243+
if (isFocusableItemType(m_itemList.at(i)->getFuncType())) return i;
244+
return -1;
245+
}
246+
247+
int ListView::nextFocusableIndex(int from)
248+
{
249+
for (int i = from + 1; i < m_itemList.count(); ++i)
250+
if (isFocusableItemType(m_itemList.at(i)->getFuncType())) return i;
251+
return -1;
252+
}
253+
254+
int ListView::prevFocusableIndex(int from)
255+
{
256+
for (int i = from - 1; i >= 0; --i)
257+
if (isFocusableItemType(m_itemList.at(i)->getFuncType())) return i;
258+
return -1;
259+
}
260+
228261
void ListView::setCurrentIndex(int currentIndex)
229262
{
230263
qCDebug(views) << "ListView::setCurrentIndex() entered, index:" << currentIndex;
@@ -698,7 +731,8 @@ void ListView::focusInEvent(QFocusEvent *event)
698731

699732
if (event->reason() == Qt::TabFocusReason) {
700733
qCDebug(views) << "Branch: TabFocusReason";
701-
setCurrentIndex(0);
734+
int idx = firstFocusableIndex();
735+
setCurrentIndex(idx >= 0 ? idx : 0);
702736
} else {
703737
qCDebug(views) << "Branch: not TabFocusReason";
704738
setCurrentIndex(m_currentIndex);

src/views/listview.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,14 @@ class ListView : public DScrollArea
117117
* @return
118118
*/
119119
int getNextIndex(int index);
120+
/** @brief 第一个可聚焦项(跳过 GroupLabel/ItemLabel)的 index,无则 -1 */
121+
int firstFocusableIndex();
122+
/** @brief 最后一个可聚焦项的 index,无则 -1 */
123+
int lastFocusableIndex();
124+
/** @brief from 之后下一个可聚焦项 index,无则 -1 */
125+
int nextFocusableIndex(int from);
126+
/** @brief from 之前上一个可聚焦项 index,无则 -1 */
127+
int prevFocusableIndex(int from);
120128
/**
121129
* @brief 设置当前焦点
122130
* @author ut000610 戴正文

0 commit comments

Comments
 (0)