[ Content contribution] 关于火狐浏览器窗口在任务栏归属异常问题的调研与修复
Tofloor
poster avatar
燕戏竹林
deepin
2026-10-10 10:33
Author

linyaps应用窗口在任务栏不与固定图标分组——一例空白图标的完整调研

环境:deepin 25 / dde-shell 2.0.52 / dde-application-manager 1.2.59 / linglong-bin 1.14.3,X11 会话
现象:linglong 安装的 Firefox(org.mozilla.firefox-nal)启动后,窗口不归属任务栏已固定的图标,而是挂在一个新的空白图标下。

TL;DR

罪魁祸首是 ~/.local/share/applications/userapp-Firefox-JNPJN3.desktop——GIO 在注册默认浏览器时生成的残留桌面文件:NoDisplay=true、没有 Icon=、没有 StartupWMClass、Name=Firefox。

dde-shell dock 的窗口归组逻辑在 DESKTOPID / STARTUPWMCLASS 相继落空后,会按 Name 兜底匹配(MatchFixedString,忽略大小写),"firefox" 命中了 userapp-Firefox-JNPJN3(Name=Firefox)。该文件无图标 → 出现空白图标;而 cgroups 兜底(本可正确识别)因前置匹配成功而永远不会被执行。删除该残留文件即恢复。

归组流程(源码:dde-shell panels/dock/taskmanager)

flowchart TD A[新窗口事件] --> B["identifies = [WM_CLASS instance, WM_CLASS class, pid]
Firefox = [Navigator, firefox, pid]"] B --> C{"按 DESKTOPID 匹配
应用模型"} C -- "无 desktop id 叫 firefox/Navigator" --> D{"按 STARTUPWMCLASS 匹配"} D -- "相关 desktop 文件该字段全为空" --> E{"按 NAME 匹配
忽略大小写"} E -- "firefox ≈ Firefox 命中
userapp-Firefox-JNPJN3(NoDisplay、无图标)" --> F["归入空白图标 ❌
cgroups 兜底不再执行"] E -- 未命中 --> G{"cgroups 兜底
AM Identify(pidfd)"} G -- "org.mozilla.www.firefox-nal" --> H["归入固定图标 ✅"]

应用模型来自 AM 的 GetManagedObjects(applets/dde-apps/amappitemmodel.cpp),不过滤 NoDisplay,因此这个不该露面的 userapp 也在候选池里。

取证过程

  1. 窗口 WM_CLASS:
flowchart LR W["Firefox 窗口"] -->|WM_CLASS| C1["instance=Navigator, class=firefox"] W -->|_NET_WM_PID| P["pid(linglong crashhelper 模式下为已退出的父进程)"] P -->|/proc/pid/cgroup| U["app-DDE-org.mozilla.www.firefox-nal@*.service"]
  1. AM 的 D-Bus 对象树里同时存在正确应用与"幽灵应用":
/org/desktopspec/ApplicationManager1/org_2emozilla_2ewww_2efirefox_2dnal        ← 正确
/org/desktopspec/ApplicationManager1/userapp_2dFirefox_2dJNPJN3                 ← 幽灵:Icons={}, Name=Firefox
  1. 幽灵文件本体(~/.local/share/applications/userapp-Firefox-JNPJN3.desktop):
[Desktop Entry]
Type=Application
NoDisplay=true
Exec=/opt/apps/org.mozilla.firefox-nal/files/bin/firefox-nal/firefox-bin %u
Name=Firefox
Comment=Custom definition for Firefox
  1. 端到端验证 AM cgroups 识别链路(传入窗口 pid 的 pidfd 调 org.desktopspec.ApplicationManager1.Identify),返回 org.mozilla.www.firefox-nal 及正确实例路径——AM 侧识别完全正常,问题只出在 dock 的匹配顺序与候选池。

根因时序

sequenceDiagram participant G as GIO/默认应用设置 participant AM as dde-application-manager participant DS as dde-shell dock G->>G: 注册 Firefox 为默认处理器
生成 userapp-Firefox-JNPJN3.desktop(无 Icon) AM->>AM: 扫描用户应用目录,导出 userapp(不过滤 NoDisplay) DS->>DS: 窗口 identifies=[Navigator, firefox, pid] DS->>DS: NAME 兜底命中 userapp(无图标)→ 空白图标 Note over DS: cgroups 兜底(结果正确)被短路

修复

用户级删除残留文件(建议先备份):

cp ~/.local/share/applications/userapp-Firefox-JNPJN3.desktop /tmp/
rm ~/.local/share/applications/userapp-Firefox-JNPJN3.desktop

AM 监听该目录会自动重载,dock 模型即时更新。删除后 NAME 兜底命中唯一候选 org.mozilla.www.firefox-nal(AM 导出的 Name 为 default: Firefox,本地化键缺失时回退 default),窗口归入固定图标;pid 可用时 cgroups 兜底同样命中。

初次删除仅是治标——删除后文件又复现了,见下一节"复发与根治"。

复发与根治(重要)

首次修复后问题复现:删除的 userapp-Firefox-*.desktop 又被生成了(随机后缀变化:JNPJN3 → TT06W3)。写入者是 Firefox 自己的"设为默认浏览器"弹窗:

sequenceDiagram participant FF as Firefox(linglong 版) participant G as GIO participant M as ~/.config/mimeapps.list FF->>G: IsDefaultBrowser:x-scheme-handler/http 的默认是 firefox.desktop 吗? G->>M: 查不到 firefox.desktop(编译期 ID,主机上不存在) G-->>FF: 不是默认 → 弹"设为默认"提示 FF->>G: 用户点击"设为默认" G->>G: 找不到 firefox.desktop → create_from_commandline 兜底 G->>M: 生成 userapp-Firefox-<随机>.desktop(无 Icon、NoDisplay) Note over M: 每点一次生成一个 → 空白图标问题复发

修复方案(用户级):

  1. ~/.config/mimeapps.list 中所有指向 userapp-Firefox-*.desktop 的项改为 org.mozilla.www.firefox-nal.desktop(真身,GIO 可见)。
  2. 删除已生成的 userapp-Firefox-*.desktop。
  3. 在 Firefox profile 写入 user.js:user_pref("browser.shell.checkDefaultBrowser", false); —— Firefox 不再检查/提示默认浏览器,生成循环彻底终止。系统默认浏览器由 mimeapps.list 决定,仍指向 linglong Firefox,点链接唤起不受影响。

已试过并放弃的方案:补一个 ~/.local/share/applications/firefox.desktop 占位条目让 Firefox 认可默认身份。它能止住 userapp 生成,但与 dock 存在结构性冲突:dock 匹配第一优先级是 DESKTOPID,占位 ID firefox 与窗口 WM_CLASS class 名 "firefox" 精确相等 → 窗口被抢归到占位条目(带 firefox 图标,表现为"又一个新火狐图标")。除非 Firefox 接受其他 ID(版本相关,不可依赖),否则此路不通。

验证结果:gio mime x-scheme-handler/http、text/html → org.mozilla.www.firefox-nal.desktop;AM 对象树仅剩真身条目;dock 匹配链 DESKTOPID/STARTUPWMCLASS 落空后由 NAME(Firefox,唯一候选)或 cgroups 兜底归入固定图标。

给上游的两点建议

  1. dde-shell dock:DockCombineModel 的 NAME/ICONNAME 兜底匹配应跳过 NoDisplay=true 的应用(或至少跳过无 Icon 的条目);NoDisplay 本义就是"不作为应用呈现"。
  2. dde-application-manager:评估是否向消费者导出 NoDisplay 应用对象,或在 AppList/ObjectManager 中提供过滤能力;同时 linglong 应用桌面文件补 StartupWMClass(如 firefox)可让归组走更可靠的 DESKTOPID/STARTUPWMCLASS 路径。

关键词:linyaps, linglong, ll-cli, firefox, dde-shell, dock, 任务栏, 分组, userapp, NoDisplay, StartupWMClass

Reply Favorite View the author
All Replies
avatar
神末shenmo
deepin
Spark-App
Q&A Team
2026-10-10 10:41
#1

GXDE这边的做法是fallback到启动参数/进程名匹配,也就是只要是firefox就都放到一起

在gxde-daemon的dock-daemon类,这块是我写的

供参考

https://gitee.com/GXDE-OS/gxde-daemon/tree/master/plugins/dock

Reply View the author
avatar
燕戏竹林
deepin
2026-10-10 10:45
#2
神末shenmo:

GXDE这边的做法是fallback到启动参数/进程名匹配,也就是只要是firefox就都放到一起

在gxde-daemon的dock-daemon类,这块是我写的

供参考

https://gitee.com/GXDE-OS/gxde-daemon/tree/master/plugins/dock

准确来说更像是firefox的石山,设为默认应用只是简单粗爆的建一个图标而不是改桌面配置。

当然这也不能全怪火狐,Linux桌面太碎片化了。

好吧,收回“firefox的石山”的判断,哪边都错joy

Reply View the author
avatar
deepin-superuser
deepin
2026-10-10 11:50
#3
燕戏竹林:

准确来说更像是firefox的石山,设为默认应用只是简单粗爆的建一个图标而不是改桌面配置。

当然这也不能全怪火狐,Linux桌面太碎片化了。

好吧,收回“firefox的石山”的判断,哪边都错joy

我更觉得是deepin的问题,修改包名改出来的吧

Reply View the author
avatar
神末shenmo
deepin
Spark-App
Q&A Team
2026-10-10 12:05
#4
deepin-superuser:

我更觉得是deepin的问题,修改包名改出来的吧

原版ff也有这个问题

deepin没做特调

Reply View the author