关闭倒数第二个窗口后,最后一个窗口无法获取焦点的问题求助
问题排查与修复建议
核心问题分析
当链表仅剩两个窗口时,关闭倒数第二个窗口后,剩余的唯一窗口无法获取焦点。现有代码的焦点赋值逻辑存在两处关键问题:
- 仅修改了
focused变量,但未调用窗口系统的API(如X11的XSetInputFocus)主动将焦点同步到系统层面; - 原焦点切换逻辑不合理——无论被删除节点的位置,都将焦点设为链表表头,不符合窗口管理的常规预期(关闭当前窗口后,焦点应优先移至下一个窗口,而非强制回到第一个)。
代码修复方案
修复后的remove_client函数
void remove_client(Window win) { if (!clients) return; Client *prev = NULL, *curr = clients; while (curr) { if (curr->win == win) { Client *next_node = curr->next; // 解除当前节点的链表链接 if (prev) { prev->next = next_node; } else { clients = next_node; } // 更新焦点并同步到系统 if (focused == curr) { // 优先选择下一个节点,无下一个则回退到上一个节点 focused = next_node ? next_node : prev; // 关键:调用窗口系统API设置焦点(以X11为例,需替换为对应系统的API) if (focused) { XSetInputFocus(dpy, focused->win, RevertToParent, CurrentTime); } } free(curr); return; } prev = curr; curr = curr->next; } }
修复说明
- 焦点切换逻辑优化:删除当前焦点窗口时,优先将焦点移至下一个窗口,无下一个窗口时再回退到上一个节点,覆盖所有边界场景;
- 新增系统焦点同步:修改
focused变量后,主动调用窗口系统API将焦点应用到实际窗口,确保系统层面的焦点状态与代码变量一致。
额外排查点
- 检查事件循环或其他模块是否存在覆盖
focused变量的逻辑,导致焦点被意外重置; - 确认剩余窗口处于已映射状态(即已显示在屏幕上),部分窗口管理逻辑会忽略未映射的窗口;
- 测试删除最后一个窗口的场景,验证焦点是否能正确回退到上一个窗口。
内容的提问来源于stack exchange,提问作者Philip Simonson
相关产品推荐
相关产品推荐

