You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

关闭倒数第二个窗口后,最后一个窗口无法获取焦点的问题求助

问题排查与修复建议

核心问题分析

当链表仅剩两个窗口时,关闭倒数第二个窗口后,剩余的唯一窗口无法获取焦点。现有代码的焦点赋值逻辑存在两处关键问题:

  1. 仅修改了focused变量,但未调用窗口系统的API(如X11的XSetInputFocus)主动将焦点同步到系统层面;
  2. 原焦点切换逻辑不合理——无论被删除节点的位置,都将焦点设为链表表头,不符合窗口管理的常规预期(关闭当前窗口后,焦点应优先移至下一个窗口,而非强制回到第一个)。

代码修复方案

修复后的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 11:33:21