Ovear's Blog

I'am Ovear,Ovear is me.

Theme Refrain made by Eiko

Proudly powered by WordPress

修改KDE Dolphin的默认视图/排序

前言

作为Linux桌面用户,近几年在使用Arch Linux + KDE作为日常操作系统时,我一直都对KDE挺满意的,虽然也遇到了大大小小不少Bug(但是比起Windows 11来说,感觉还是能好一些的);其中一个最主要的原因就是KDE通过一些调整,能够兼容大部分我从Windows上带来的习惯,换句现在流行的形容方式就是可切换性/兼容性更好。

文件管理器方面,Dolphin稍微调整过后还是比较顺手的;KDE自带的Dolphin可以设定两个视图记忆模式,一个是默认的“统一所有文件夹的显示风格”,另一个是我个人比较习惯的“单独记忆每个文件夹的显示风格”。

但是一直以来有一个比较难受的地方就是:虽然Dolphin会记忆每个文件夹的“显示风格”,主要就是排序和显示列表之类的,但是每次进入一个新的文件夹,或者未设定过的文件夹时,就会恢复默认的设定。这个默认的设定机缘巧合的情况下,被设定为了“按照修改时间倒叙排列”,导致每次进入文件夹时我都得手动调整一下,实在令人不爽;今天恰好有空就来解决一下这个问题。

TLDR:方案三最佳,方案一也可以,太闲了或者对你恰好有强迫症,或者实现有兴趣可以看看方案二。

方案一:直接修改设定解决

其实也没有太反直觉,遇到这个问题第一想法就是在Dolphin的设定调整回“统一所有文件夹的显示风格”,然后再切换一下文件夹的排序,再设定回“单独记忆每个文件夹的显示风格”就会发现之前的修改已经作为默认设定。

大功告成,事情就这么解决了;但是可能是因为闲的吧,也可能是因为强迫症发作,感觉这种方式不够优雅,想看看能不能有更方便的方式实现,于是就有了后文。

方案二:直接修改默认配置文件

尝试确认视图默认配置文件夹的位置

一顿搜索和第六感之后,确认了Dolphin的配置文件果然是~/.config/dolphinrc,但是其中没有我们需要的“默认视图配置”,应该是存在了其他的地方。

这样只能在文件夹中搜索看看有没有线索了;在使用“单独记忆每个文件夹的显示风格”时,Dolphin会在每个文件夹中生成一个.directory文件,如果自定义了排序列,其中就会使用SortRole项来记录。而我目前默认的设定就是根据“最后修改时间”来排序,所以理论上默认设定也会以这个格式存储。

又是一顿搜索之后,在~/.config/kdeglobals中找到了Sort by=Date,正以为大功告成时,发现这个设定项位于[KFileDialog Settings]子项之下。一顿修改测试之后,发现找错了地方,不是这个文件。

接下来就只能另想方法确认文件夹位置了。

通过inotifywait监听文件修改

既然确认了Dolphin会记录默认的视图配置,我们假定它会将配置写入到磁盘中。这时理论上我们就可以通过切换视图设置的选项,再修改排序依据来触发配置文件保存,这样只要监听文件的变化,就可以“轻易”(Flag)确认它存储配置的地方了。

话不多说,inotifywait -mrq ~/.config启动,一顿操作下来除了看到Dolphin确实会在修改视图的目录下创建.directory文件以外,好像就没有其他动作了。

不过还有一些看起来很可疑的/home/user/.config/ OPEN #22278943输出,但是用“inotifywait 井号”之类的关键词都没有搜到。于是为了节省看代码的时间,后续再研究,就直接问了AI;给出答复是inode number后续证明这个决定实在是太正确了,看了几个小时代码看的头晕脑胀,都没看出所以然,差点放弃了,最后又是在洗澡时灵光乍现,才最终找到原因的;对我这个曲折的折腾过程感兴趣的话可以看下一篇Blog)。

说起来也非常合理,毕竟软件的名字就叫做inotifywait,那么输出的奇怪数字是inode number的可能是确实很高。通过find -inum可以搜索对应inode number对应的文件;一搜果然没错,确实是inode number,但是对应的文件却是目录下的.directory,这下事情又回到原点。

后续又尝试通过inotifywait对整个home目录监测,但是没有反应,可能是出了什么bug(后期注:单纯是因为你太急了,又用了-q选项,导致每次使用递归选项-r时都会输出请耐心等待的提示给mute掉了),或者文件太多;结果还是走进了死胡同

后期PS2:事实上如果那时候多等一会,后续就不用折腾这么久了)没准还可以省了后续对着#开头文件输出浪费的大把时间(虽然大概率还是会瞎折腾去研究这个)。如果真的遇到了超出最大inotifywait的提示,可以通过修改内核选项fs.inotify.max_user_instancesfs.inotify.max_user_watches来增加上限。

通过源代码确认配置文件存储逻辑和位置

Dolphin是开源项目,在使用了搜索大法之后,我们就可以很轻易(真)的确定视图设置页面位于dolphin/src/settings/viewmodes/generalviewsettingspage.cpp。(我爱开源项目)

# https://github.com/KDE/dolphin/blob/41cde29f2e93987534c1654456a94ded1e4ae591/src/settings/viewmodes/generalviewsettingspage.cpp
void GeneralViewSettingsPage::applySettings()
{
    GeneralSettings *settings = GeneralSettings::self();
    ViewProperties props(m_url); // read current view properties
    const bool useGlobalViewProps = m_globalViewProps->isChecked();
    settings->setGlobalViewProps(useGlobalViewProps);
#if HAVE_BALOO
    settings->setShowToolTips(m_showToolTips->isChecked());
#endif
    settings->setShowSelectionToggle(m_showSelectionToggle->isChecked());
    settings->setRenameInline(m_renameInline->isChecked());
    settings->setHideXTrashFile(m_hideXtrashFiles->isChecked());
    settings->setAutoExpandFolders(m_autoExpandFolders->isChecked());
    settings->setBrowseThroughArchives(m_openArchivesAsFolder->isChecked());
    settings->save();
    if (useGlobalViewProps) {
        // Remember the global view properties by applying the current view properties.
        // It is important that GeneralSettings::globalViewProps() is set before
        // the class ViewProperties is used, as ViewProperties uses this setting
        // to find the destination folder for storing the view properties.
        ViewProperties globalProps(m_url);
        globalProps.setDirProperties(props);
    }
}

当我们选择使用全局视图设定时,就会进入useGlobalViewProps为true的选项,我们只要找到GeneralSettingssave逻辑就可以知道位置了。但是好巧不巧,DolphinGeneralSettings是自动生成的代码。不过我们还有ViewProperties这条线索;果然,在好运的加持下,我们转到src/views/viewproperties.cpp,一切就水落石出了。

# https://github.com/KDE/dolphin/blob/41cde29f2e93987534c1654456a94ded1e4ae591/src/views/viewproperties.cpp

ViewProperties::ViewProperties(const QUrl &url)
    : m_changedProps(false)
    , m_autoSave(true)
    , m_node(nullptr)
{
    GeneralSettings *settings = GeneralSettings::self();
    const bool useGlobalViewProps = settings->globalViewProps() || url.isEmpty();
    bool useSearchView = false;
    bool useTrashView = false;
    bool useRecentDocumentsView = false;
    bool useDownloadsView = false;

    // We try and save it to the file .directory in the directory being viewed.
    // If the directory is not writable by the user or the directory is not local,
    // we store the properties information in a local file.
    ...
    else if (useGlobalViewProps) {
        m_filePath = destinationDir(QStringLiteral("global"));
    }
    ...

    // If the .directory file does not exist or the timestamp is too old,
    // use default values instead.
    const bool useDefaultProps = (!useGlobalViewProps || useSearchView || useTrashView || useRecentDocumentsView || useDownloadsView)
        && (!QFile::exists(file) || (m_node->timestamp() < settings->viewPropsTimestamp()));
    ...
    else {
            // The global view-properties act as default for directories without
            // any view-property configuration. Constructing a ViewProperties
            // instance for an empty QUrl ensures that the global view-properties
            // are loaded.
            QUrl emptyUrl;
            ViewProperties defaultProps(emptyUrl);
            setDirProperties(defaultProps);

            m_changedProps = false;
        }
...
void ViewProperties::save()
{
    qCDebug(DolphinDebug) << "Saving view-properties to" << m_filePath;
    QDir dir;
    dir.mkpath(m_filePath);
    m_node->setVersion(CurrentViewPropertiesVersion);
    m_node->save();
    m_changedProps = false;
}
...
QString ViewProperties::destinationDir(const QString &subDir) const
{
    QString path = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
    path.append("/view_properties/").append(subDir);
    return path;
}

通过分析上述代码,我们能够看到代码在useGlobalViewProps=true时,也就是使用全局视图设定时,会将配置文件存储在QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)/view_properties/global/目录下。通过Qt的官方文档可以确认QStandardPaths::writableLocation对应的是/home/user/.local/share/APP_NAME/

所以全局视图设定配置文件的完整路径就是/home/user/.local/share/dolphin/view_properties/global,只要修改这个文件夹下的.directory就可以修改默认的视图设定。

(怎么会存在这个地方...早该想到的...感觉除了默认.config以外,.local这个目录也是格外受到各大应用的欢迎;挖个坑在这:过段时间空了看看能不能把目前常见的目录使用规范整理/翻译一下。)

根据日志和inotifywait进一步验证

代码中当保存视图配置文件时,会输出保存路径的调试信息,根据官方文档说明[1][2]使用QT_LOGGING_RULES='org.kde.dolphin=true'启动dolphin后就会有调试日志输出。

再用inotifywait监听/home/user/.local/share/作为双保险,启动dolphin修改视图排序依据后可以看到两边均有输出。

org.kde.dolphin: Saving view-properties to "/home/user/.local/share/dolphin/view_properties/global"

因此确认了我们的分析是正确的。

方案三:通过独立的“视图设定”页修改默认视图设定(最佳)

说起来也神奇,在搜索代码时还查到了一个叫做src/settings/viewpropertiesdialog.cpp的从未见过的窗口,其中就有一个“设定当前视图为默认视图”的功能[3],他们有做这个功能,实在是帮了大忙了。

调整视图显示风格窗口

这里有一个比较tricky的地方,因为官方文档还是旧版本的(开源项目嘛,文档一直是....非常滞后的),根据官方的操作可能找不到入口。

KDE Plasma的默认情况下是隐藏了菜单栏的,此时的入口就会比较隐蔽:汉堡菜单-更多-视图-调整显示风格

隐藏菜单栏时调整显示风格窗口的入口

这样显然有点不方便,这时可以通过快捷键Ctrl+M来临时显示菜单栏;这时候入口就会比较容易找到了:直接就在视图-调整显示风格

显示菜单栏时调整显示风格窗口的入口

尾巴

虽然Dolphin这样设定好处也是挺好的,但是作为一个Windows起手多年的用户,如果后续能够给一个选项,做到跟Windows一样根据上层文件夹的视图设定和默认设定来决定内部文件夹的默认视图就更好了。

小小的吐槽一下:后面还有寻找#开头文件的“奇异之旅”,没想到就这一件小事,引出来这么一大堆东西;这两天的时间都花在这上面了,有点头大。。。

参考文章

[1] Guidelines and HOWTOs/Debugging/Using Error Messages - KDE Community Wiki
[2] KDE/Debugging - Fedora Project Wiki
[3] Folder View Display Style

修改KDE Dolphin的默认视图/排序没有评论

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

© 2024 Ovear's Blog All rights reserved.