什么是url scheme handler?¶
在操作系统中,不同的应用之间可以相互拉起,但又不知道自己拉起的应用到底是谁。
比如说 你想拉起邮件客户端,但又不确定系统里安装了哪个邮件客户端,比如说你可能有thunderbird, 也可能是outlook。如何能无差别地拉起一个邮件客户端?
你可以这样:
xdg-open mailto:zhangfuwen@foxmail.com
mailto:zhangfuwen@foxmail.com就是一个url scheme。
系统里有一个映射关系,这个映射关系可能通过任何方式维护,在不同的操作系统可能不一样。或者同一个操作系统中也存在不同的机制。
Linux¶
1 通过desktop file声明¶
[Desktop Entry]
Version=1.0
Type=Application
Name=dnfurl
Exec=dnfurl %U
Terminal=false
NoDisplay=true
MimeType=x-scheme-handler/dnf
https://blog.kagesenshi.org/2021/02/custom-url-scheme-handler.html
显示每次查一下所有的desktop文件是不太可能的,其实OS会维护一个cache,可以通过命令更新:
cd /usr/share/applications/
update-desktop-database
2 直接修改cache文件¶
所谓的cache文件可能就是下面的几个文件:
/usr/share/applications/defaults.list
~/.local/share/applications/mimeapps.list
~/.config/mimeapps.list
我们修改文件可以直接达到效果:
sudo su
echo "x-scheme-handler/ddg=org.gnome.Totem.desktop" >> /usr/share/applications/defaults.list
xdg-open ddg:asdfadfl
以上代码可以打开totem,当然了,totem并不认识ddg:asdfadf1是什么,所以它会报错。
3 应用如何响应呢?¶
如果我们自己写一个应用,建立了映射关系,我们如何收到这个请求呢?
其实它就是做为命令行参数传给我们的应用的。
我们看看totem的desktop file:
➜ Code head /usr/share/applications/org.gnome.Totem.desktop
[Desktop Entry]
Name=Videos
Comment=Play movies
Exec=totem %U
Icon=org.gnome.Totem
DBusActivatable=true
````
可以看到Exec字段跟的是`totem %U`,这里的'%U'就是url list的意思,这个可以参考:https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html#exec-variables
# mime type
与url scheme handler 紧密相关的是mime type。
mime type的处理有一个通用的脚本,叫xdg-mime,它实际上是先检测一下DE,如果是kde就调用`kbuildsycoca`这个软件,如果是gnome就调用update-mime-database这个软件。
xdg-mine这个脚本是`xdg-utils`包的一部分,这个包里面只是几个脚本,可以通过`apt source xdg-utils`下载代码看一下,也可以在[github上直接看](https://github.com/freedesktop/xdg-utils/tree/master/scripts)。
## 4 update-mime-database
update-mime-database是一个可执行文件,它存在于包`shared-mime-info`里,可以通过`apt source shared-mime-info`查看代码,也可以[在github上直接查看](https://github.com/freedesktop/xdg-shared-mime-info/tree/master/src)。
它接受一个目录做为参数,这个目录就是存放mime定义文件的地方,这个目录包括:
里面通过一个xml文件描述了一些mime类型,主要是它的名字和识别方法,识别方法包括通过后缀名识别和通过文件头部识别两种方法。
举个例子:
cat ~/.local/share/mime/packages/view3dscene.xml
<!-- Gzip compressed -->
<glob pattern="*.wrz"/>
<glob pattern="*.wrl.gz"/>
## 5 update-mime-database代码
### 5.1 下载代码
找个目录,然后`apt source shared-mime-info`, 里面只有几个文件,`find . -name update-mime-database.c`得到结果`./shared-mime-info-2.2/src/update-mime-database.c
`。
打开它,`write_cache`函数是它写入cache文件的地方,
path = g_strconcat(mime_dir, "/mime.cache.new", NULL);
stream = fopen_gerror(path, error);
if (!stream)
goto out;
write_cache(stream);
if (!fclose_gerror(stream, error))
goto out;
if (!atomic_update(path, error))
goto out;
g_free(path);
}
写的cache文件的名字为`mime.cache`,存放在:
它们是二进制可映射到内存为map的文件格式,所以查询速度非常的快。
6 kbuildsycoca¶
kbuildsycoca是kservice的一部分,代码可以在这里看。
这里有一个文档,介绍了sycoca的用法。 sycoca的意思是system configuration cache,三个单词各取了两个字母。