1. 背景
因为工作和学习的原因,deepin-terminal成为我使用最频繁的工具。
但是很多我个人需要的功能,原创版本并没有给出。无奈最后只能自己改造一下了。
前后也是花了不少时间,零基础上手,卓有成效,不仅实现自己想要的功能,也写了两篇博客作为记录
- https://www.cnblogs.com/liwanliangblog/p/14348593.html
- https://www.cnblogs.com/liwanliangblog/p/14469250.html
同时使用备份源码的方式,在新的系统更新后,直接解压源码进行编译安装。
但是,在最新的几个版本20.2.2+中,发现之前的源码已经出现了很多bug,具体的bug也反馈在论坛上:
在虚拟机安装的最新版本,重新测试了反馈的bug,发现有些是系统的bug
- 截图复制,微信发送以后,切换到终端,双击复制,偶然出现无法复制的情况。能够复现
也有些可能是特性
- 如果某个标签页有输出内容,比如sudo apt update,或者有动作更新,比如ssh连接超时自动推出,标签页自动变更字体来提示用户
除了论坛帖子里面总结的bug,一些新的bug,我在自己编译的版本上稳定复现,但是新安装的系统没有这个问题,那应该是我修改的版本有问题了。
综上一些问题的出现,让自己使用deepin-terminal的体验变差了。
所以我决定再出发,重新整理代码修改和编译。并且这次不是用打包源码的方式,而是直接拉一个开发分支的方式,不仅能够及时合并主线的特性和bug修复,也能够更加方便地并入自己的修改。
日后有需要,也可以方便给官方主线提交pr。
本篇博客主要实现的特性见下:
- 双击复制可复制中文。
- 双击复制可指定可复制的特殊符号
- 光标下划线样式加粗
- 可设置终端启动时默认的目录
- 可设置一个翻译选中文本的脚本路径和快捷键
- 可使用快捷键设置终端和标签透明
- 可使用快捷键切换深浅主题
- 可使用快捷键打开设置界面
一些其他的默认修改:
- 默认双击复制时,英文逗号不作为分隔符
- 默认双击复制时,句末有英文逗号不复制该符号
一些想要实现的特性:
- 多行选中时,不选中行末空白
- 右键添加“使用文本编辑器打开选中文本”(其实已经实现,本版本懒得并入)
- 重新设计上下载功能(使用scp)
- 可设置的HistorySize
2. 开发前的准备
2.1 创建开发分支
deepin-terminal的官方github地址:https://github.com/linuxdeepin/deepin-terminal
但是国内访问github的速度大家都懂,索性直接使用gitee导入deepin-terminal的github仓库(自行操作,gitee官方有介绍)
然后使用gitee创建开发分支(这里创建分支,不会对github上面的官方仓库造成影响)。
我创建分支为liwldev,分支的起始分支为官方的dev分支
2.2 拉取代码并切换分支
注意!!!从步骤2.2开始,建议在虚拟机环境进行
创建了自己的liwldev分支之后,就可拉取代码了,这里拉取的是gitee的仓库代码
git clone git@gitee.com:yunweinote126/deepin-terminal.git
查看当前分支:git branch -a
,代码指向了master分支
切换分支:git checkout liwldev
,就切换到自己的分支了
2.3 部署开发环境
其实也没啥部署的,简单的几个小步骤而已,按照官方的readme即可
进入到源码目录:cd deepin-terminal
执行:sudo apt build-dep .
,直接安装需要的依赖
然后就可以修改源码了
修改了源码,就可以编译和安装
编译的操作:mkdir build && cd build && cmake .. && make
安装的操作:sudo make install
,默认安装在/usr/local/bin/deepin-terminal
强烈建议先卸载deepin-terminal,先sudo apt install konsole,暂时使用konsole终端,或者远程到主机后开发,因为一些特性需要重新安装
3. 正式开发
3.1 需修改第三方库代码的特性
以下特性需要修改第三方库代码:
- 双击可复制中文字符串(中文字符串以空格为分隔)
- 双击复制默认复制英文逗号。如果英文逗号在句尾,则不复制
- 光标下划线样式加粗
实现双击复制时,包括英文逗号
修改的代码:deepin-terminal/3rdparty/terminalwidget/lib/TerminalDisplay.cpp,约449行
,_wordCharacters(QLatin1String(":@-./_~"))
//修改为
,_wordCharacters(QLatin1String(":@-./_~,"))
实现双击复制,可复制中文
修改2个地方
修改的代码:deepin-terminal/3rdparty/terminalwidget/lib/TerminalDisplay.cpp,约2594行
原来的代码:
// find the start of the word
int x = bgnSel.x();
while ( ((x>0) || (bgnSel.y()>0 && (_lineProperties[bgnSel.y()-1] & LINE_WRAPPED) ))
&& (charClass(_image[i-1].character) == selClass)
)
修改为:
// find the start of the word
int x = bgnSel.x();
while ( ((x>0) || (bgnSel.y()>0 && (_lineProperties[bgnSel.y()-1] & LINE_WRAPPED) ))
&& (charClass(_image[i-1].character) == selClass || QChar( _image[i+1].character ) == QLatin1Char(' ') )
)//QChar( _image[i+1].character ) == QLatin1Char(' '),2021-08-26,liwl,通过调整字符前边界增加双击复制时对中文的支持
修改的代码:deepin-terminal/3rdparty/terminalwidget/lib/TerminalDisplay.cpp,约2614行
原来的代码:
// find the end of the word
i = loc( endSel.x(), endSel.y() );
x = endSel.x();
while( ((x<_usedColumns-1) || (endSel.y()<_usedLines-1 && (_lineProperties[endSel.y()] & LINE_WRAPPED) ))
&& ( charClass(_image[i+1].character) == selClass ))
修改为:
// find the end of the word
i = loc( endSel.x(), endSel.y() );
x = endSel.x();
while( ((x<_usedColumns-1) || (endSel.y()<_usedLines-1 && (_lineProperties[endSel.y()] & LINE_WRAPPED) ))
&& ( charClass(_image[i+1].character) == selClass || QChar( _image[i+1].character ) == QLatin1Char(' ') )
) //QChar( _image[i+1].character ) == QLatin1Char(' '),2021-08-26,liwl,通过调整字符后边界增加双击复制时对中文的支持
实现双击复制时,如果英文逗号在句尾则不复制该符号
修改的代码:deepin-terminal/3rdparty/terminalwidget/lib/TerminalDisplay.cpp,约2630行
原来的代码:
if ( ( QChar( _image[i].character ) == QLatin1Char('@') )
&& ( ( endSel.x() - bgnSel.x() ) > 0 ) )
endSel.setX( x - 1 );
修改为:
if ( ( QChar( _image[i].character ) == QLatin1Char('@') || QChar( _image[i].character) == QLatin1Char(',') )
&& ( ( endSel.x() - bgnSel.x() ) > 0 ) )
endSel.setX( x - 1 );
实现光标下滑线加粗
修改的代码:deepin-terminal/3rdparty/terminalwidget/lib/TerminalDisplay.cpp,约760行
原来的代码:
else if ( _cursorShape == Emulation::KeyboardCursorShape::UnderlineCursor )
painter.drawLine(QLineF(
QPointF(cursorRect.left(),
cursorRect.bottom()),
QPointF(cursorRect.right(),
cursorRect.bottom())));
修改为:
else if ( _cursorShape == Emulation::KeyboardCursorShape::UnderlineCursor )
{
for(int i = 0; i <= 3; ++i)
painter.drawLine(QLineF(
QPointF(cursorRect.left(),
cursorRect.bottom()+i),
QPointF(cursorRect.right(),
cursorRect.bottom()+i)));
}
3.2 需要修改deepin源码的特性
以下特性需要修改deepin-terminal的代码
- 增加设置选项的显示
- 增加“终端启动默认目录的”设置选项
- 增加“翻译脚本全路径”的设置选项
- 增加“双击可复制的特殊符号”的设置选项
- 增加快捷键选项”显示设置界面“
- 增加快捷键选项”深浅主题切换“
- 增加快捷键选项”终端透明“
- 增加快捷键选项”标签透明“
- 增加快捷键选项”翻译快捷键“
具体的流程:
- 修改默认配置文件default-config.json文件,增加需要的设置选项
- cmake和make操作后,修改deepin-terminal_zh_CN.ts文件,以便能够正常显示中文
- 在具体的代码中实现各部分功能
- 最后编译测试安装
增加设置选项的显示
修改的文件:deepin-terminal/src/assets/other/default-config.json,添加以下内容:
{
"key": "liwl",
"name": "Liwl",
"groups":[
{
"key": "terminal",
"name": "Terminal",
"options": [
{
"key": "default_dir_start",
"name": "Default dir start",
"type": "lineedit"
},
{
"key": "script_for_translate",
"name": "Script for translate",
"type": "lineedit"
},
{
"key": "double_click_select_special_sysmbol",
"name": "Double click select special sysmbol",
"type": "lineedit"
}
]
},
{
"key": "shortcuts",
"name": "Shortcuts",
"options": [
{
"key": "show_settings",
"name": "Show settings",
"type": "shortcut",
"default": "Ctrl+,"
},
{
"key": "dark_light_switch",
"name": "Dark light switch",
"type": "shortcut",
"default": "Alt+S"
},
{
"key": "terminal_transparency",
"name": "Terminal transparency",
"type": "shortcut",
"default": "Alt+R"
},
{
"key": "tab_transparency",
"name": "Tab transparency",
"type": "shortcut",
"default": "Alt+E"
},
{
"key": "translate_shortcut",
"name": "Translate shortcut",
"type": "shortcut",
"default": "Alt+F"
}
]
}
]
}
上面的配置搞定后,会在cmake和make过程中,自动生成设置界面。
接下来修改的文件:deepin-terminal/src/settingssettings_translation.cpp,修改如下:
//2021-08-26,liwl
//liwl.terminal
auto group_liwlName = QObject::tr("Liwl");
Q_UNUSED(group_liwlName)
auto default_dir_startName = QObject::tr("Default dir start");
Q_UNUSED(default_dir_startName);
auto script_for_translateName = QObject::tr("Script for translate");
Q_UNUSED(script_for_translateName);
auto double_click_select_special_sysmbolName = QObject::tr("Double click select special sysmbol");
Q_UNUSED(double_click_select_special_sysmbolName);
//2021-08-26,liwl
//liwl.shortcuts
auto show_settingsName = QObject::tr("Show settings");
Q_UNUSED(show_settingsName);
auto dark_light_switchName = QObject::tr("Dark light switch");
Q_UNUSED(dark_light_switchName);
auto terminal_transparencyName = QObject::tr("Terminal transparency");
Q_UNUSED(terminal_transparencyName);
auto table_transparencyName = QObject::tr("Tab transparency") ;
Q_UNUSED(table_transparencyName);
auto translate_shortcutName = QObject::tr("Translate shortcut");
Q_UNUSED(translate_shortcutName);
该部分内容主要是用来把对应文件里面的英文翻译为中文,否则设置界面只会显示出英文,而非中文。
但是,这一步通过make时发现无法自动更新deepin-terminal_zh_CN.ts内容,不知道为何
只能手动更新该文件了,deepin-terminal_zh_CN.ts添加如下内容,主要对应line行号!
<message>
<location filename="../src/settings/settings_translation.cpp" line="161"/>
<source>Liwl</source>
<translation>自定义</translation>
</message>
<message>
<location filename="../src/settings/settings_translation.cpp" line="163"/>
<source>Default dir start</source>
<translation>终端启动默认目录</translation>
</message>
<message>
<location filename="../src/settings/settings_translation.cpp" line="165"/>
<source>Script for translate</source>
<translation>翻译脚本全路径</translation>
</message>
<message>
<location filename="../src/settings/settings_translation.cpp" line="167"/>
<source>Double click select special sysmbol</source>
<translation>双击可复制的特殊符号</translation>
</message>
<message>
<location filename="../src/settings/settings_translation.cpp" line="171"/>
<source>Show settings</source>
<translation>显示设置界面</translation>
</message>
<message>
<location filename="../src/settings/settings_translation.cpp" line="173"/>
<source>Dark light switch</source>
<translation>深浅主题切换</translation>
</message>
<message>
<location filename="../src/settings/settings_translation.cpp" line="175"/>
<source>Terminal transparency</source>
<translation>终端透明</translation>
</message>
<message>
<location filename="../src/settings/settings_translation.cpp" line="177"/>
<source>Tab transparency</source>
<translation>标签透明</translation>
</message>
<message>
<location filename="../src/settings/settings_translation.cpp" line="179"/>
<source>Translate shortcut</source>
<translation>翻译快捷键</translation>
</message>
然后进行cmake && make && sudo make install
,设置界面将会增加如下图:
虽然设置界面更新了, 但是实际上功能还是没有的,对应的按键是没有任何作用的。
终端启动默认目录功能实现
deepin-terminal源码中,主要通过引入第三方库的qtermwidget.h头文件使用其定义的类的属性和方法。
deepin-terminal/src/views/termwidget.h,通过qtermwidget.h来的setWorkingDirectory方法来设置工作目录。
在termwidget.cpp的105左右,以下代码实现了对终端启动参数关于启动目录的判断和功能实现:
// WorkingDir
if (m_properties.contains(WorkingDir))
setWorkingDirectory(m_properties[WorkingDir].toString());
将其改为以下:
// WorkingDir
if (m_properties.contains(WorkingDir))
setWorkingDirectory(m_properties[WorkingDir].toString());
/*else{...},2021-08-27,liwl,yunweinote@126.com。这段代码会影响全局,比如桌面右键或者文管右键打开终端时,均以配置的默认路径启动*/
else{
QString default_work_diretory = Settings::instance()->workDirectory();
QFileInfo file(default_work_diretory);
if (file.exists())
setWorkingDirectory(default_work_diretory);
}
上述代码通过Settings::instance()->workDirectory()方法获取设置的启动默认目录,如果该目录不存在,那么就按照以前的方式,该从哪里启动就从哪里启动。
Settings::instance()->workDirectory(),这段必须是需要在settings.h里面声明,并且在settings.cpp里面实现的,否则必然报错(语法错误)。其主要作用是从用户设置中读取用户配置的目录。
先在settings.h里面声明该方法,修改文件deepin-terminal/src/settings/settings.h,添加以下内容:
/**
* @brief 设置终端启动默认目录
* @author liwl,yunweinote@126.com
* @return
*/
QString workDirectory() const;
然后在settings.cpp里面实现该方法,修改文件deepin-terminal/src/settings/settings.cpp,添加以下内容:
/*******************************************************************************
1. @函数: workDiretory
2. @作者: liwl,yunweinote@126.com
3. @日期: 2021-08-27
4. @说明: 设置界面获取启动初始目录
*******************************************************************************/
QString Settings::workDirectory() const
{
return settings->option("liwl.terminal.default_dir_start")->value().toString();
}
上面就完成了的就是deepin-terminal能够从配置文件读取“终端启动默认目录”的值,并且从配置的路径启动。但是如果用户修改了以后,就没法生效了。
需要做一个事件的绑定,在方法void Settings::initConnection()里面,参照其他代码,添加以下代码:
QPointer<DSettingsOption> workDirectory = settings->option("liwl.terminal.default_dir_start");
connect(workDirectory, &Dtk::Core::DSettingsOption::valueChanged, this, [ = ](QVariant value) {
emit workDirectoryChanged(value.toString());
});
上述代码的功能:如果监听到设置界面“终端启动默认目录“的设置值变化后,会触发一个workDirectoryChanged的信号。该信号也需要在settings.h里面声明。
signals:
...
...
void workDirectoryChanged(QString workDirectory);
上面就完成了“终端启动默认目录”的功能
但是,有一个非常重要的事情,就是我这里配置使用了liwl.terminal的自定义字符串,deepin-terminal没法解析这部分配置,所以需要做一下代码修改
修改文件:deepin-terminal/src/settings/setting.cpp,修改方法:void Settings::initConnection()
原来的代码:
void Settings::initConnection()
{
connect(settings, &Dtk::Core::DSettings::valueChanged, this, [ = ](const QString & key, const QVariant & value) {
Q_UNUSED(value)
if (key.contains("basic.interface.") || key.contains("advanced.cursor.") || key.contains("advanced.scroll.")
emit terminalSettingChanged(key);
else if (key.contains("shortcuts."))//liwl.shortcuts.在此范围内,2021-08-26,liwl
emit shortcutSettingChanged(key);
else
emit windowSettingChanged(key);
});
修改后的代码:
void Settings::initConnection()
{
connect(settings, &Dtk::Core::DSettings::valueChanged, this, [ = ](const QString & key, const QVariant & value) {
Q_UNUSED(value)
//2021-08-26,liwl,增加配置文件中对liwl.terminal的配置解析
if (key.contains("basic.interface.") || key.contains("advanced.cursor.") || key.contains("advanced.scroll.") || key.contains("liwl.terminal"))
emit terminalSettingChanged(key);
else if (key.contains("shortcuts."))//liwl.shortcuts.在此范围内,2021-08-26,liwl
emit shortcutSettingChanged(key);
else
emit windowSettingChanged(key);
});
上面这一部分的修改,那肯定是及其重要的,否则部分功能肯定是没法实现的。
当然如果参照deepin-terminal其他代码,不是用自定义配置内容,而是添加到别的配置里面也是可以的,比如我之前的那两篇博客就是如此。
参照上面的内容,就可以对【双击可复制的特殊符号】以及【翻译脚本全路径】功能,做同样的添加操作。
编辑文件deepin-terminal/src/settings/settings.cpp,添加以下内容:
/*************************2021-08-27,liwl,begin*************************************************/
/*******************************************************************************
1. @函数: scriptTranslate
2. @作者: liwl,yunweinote@126.com
3. @日期: 2021-08-27
4. @说明: 获取翻译脚本全路径
*******************************************************************************/
QString Settings::scriptTranslate() const
{
return settings->option("liwl.terminal.script_for_translate")->value().toString();
}
/*******************************************************************************
1. @函数: wordCharacters
2. @作者: liwl,yunweinote@126.com
3. @日期: 2021-08-27
4. @说明: 设置界面获取双击选中的特殊符号
*******************************************************************************/
QString Settings::wordCharacters() const
{
return settings->option("liwl.terminal.double_click_select_special_sysmbol")->value().toString();
}
/*******************************************************************************
1. @函数: workDiretory
2. @作者: liwl,yunweinote@126.com
3. @日期: 2021-08-27
4. @说明: 设置界面获取启动初始目录
*******************************************************************************/
QString Settings::workDirectory() const
{
return settings->option("liwl.terminal.default_dir_start")->value().toString();
}
编辑文件deepin-terminal/src/settings/settings.cpp,在方法void Settings::initConnection()里面添加以下代码:
QPointer<DSettingsOption> scriptTranslate = settings->option("liwl.terminal.script_for_translate");
connect(scriptTranslate, &Dtk::Core::DSettingsOption::valueChanged, this, [ = ](QVariant value) {
emit scriptTranslateChanged(value.toString());
});
QPointer<DSettingsOption> wordCharacters = settings->option("liwl.terminal.double_click_select_special_sysmbol");
connect(wordCharacters, &Dtk::Core::DSettingsOption::valueChanged, this, [ = ](QVariant value) {
emit wordCharactersChanged(value.toString());
});
QPointer<DSettingsOption> workDirectory = settings->option("liwl.terminal.default_dir_start");
connect(workDirectory, &Dtk::Core::DSettingsOption::valueChanged, this, [ = ](QVariant value) {
emit workDirectoryChanged(value.toString());
});
编辑文件deepin-terminal/src/settings/settings.h,添加上述方法和信号的声明,如下:
/**
* @brief 获取翻译脚本全路径
* @author liwl,yunweinote@126.com
* @return
*/
QString scriptTranslate() const;
/**
* @brief 获取双击可复制的特殊符号
* @author liwl,yunweinote@126.com
* @return
*/
QString wordCharacters() const;
/**
* @brief 设置终端启动默认目录
* @author liwl,yunweinote@126.com
* @return
*/
QString workDirectory() const;
5个特性快捷键的增加
这些实现大致相同,均是修改文件deepin-terminal/src/mainmanwindow.cpp内容。
添加【深浅主题切换】槽函数
/*
2021-08-27,liwl(yunweinote@126.com),这里添加自定义功能实现——深浅主题切换的功能实现
*/
inline void MainWindow::slotShortcutSwitchTheme()
{
if (Settings::instance()->colorScheme() == THEME_DARK)
{
Settings::instance()->setColorScheme(THEME_LIGHT);
Settings::instance()->setExtendColorScheme(THEME_NO);
DGuiApplicationHelper::instance()->setPaletteType(DGuiApplicationHelper::LightType);
emit DApplicationHelper::instance()->themeTypeChanged(DGuiApplicationHelper::LightType);
return;
}
if (Settings::instance()->colorScheme() == THEME_LIGHT)
{
Settings::instance()->setColorScheme(THEME_DARK);
Settings::instance()->setExtendColorScheme(THEME_NO);
DGuiApplicationHelper::instance()->setPaletteType(DGuiApplicationHelper::DarkType);
emit DApplicationHelper::instance()->themeTypeChanged(DGuiApplicationHelper::DarkType);
return ;
}
}
添加【终端透明】槽函数
inline void MainWindow::slotShortcutTerminalTransparency()
{
TermWidgetPage *page = currentPage();
if (page) {
if (Settings::instance()->settings->option("basic.interface.opacity")->value().toInt() == 100) {
page->setTerminalOpacity(0.8);
Settings::instance()->settings->option("basic.interface.opacity")->setValue(80);
}else{
page->setTerminalOpacity(1.0);
Settings::instance()->settings->option("basic.interface.opacity")->setValue(100);
}
page->focusCurrentTerm();
}
}
添加【标签透明】槽函数
inline void MainWindow::slotShortcutTabTransparent()
{
TermWidgetPage *page = currentPage();
if (page) {
if ( TAB_TRANSPARENT )
{
page->setTerminalOpacity(0.7);
TAB_TRANSPARENT = false;
}else{
page->setTerminalOpacity(1);
TAB_TRANSPARENT = true;
}
page->focusCurrentTerm();
}
}
添加【翻译快捷键】槽函数
inline void MainWindow::slotShortcutSelectTranslate()
{
QString rtn = "";
QString script = Settings::instance()->scriptTranslate();
QFileInfo file(script);
if (script.isEmpty())
rtn = "未设置脚本";
else if (!file.exists())
rtn = "设置脚本不存在";
else {
QString txt = selectedText();
QProcess p;
QString cmd = script + " " + txt;
p.start(cmd);
p.waitForStarted(60000);
p.waitForFinished(60000);
rtn = p.readAllStandardOutput();
if (rtn.isEmpty())
rtn = "脚本执行错误:1.是否具备可执行权限;2.是否选中翻译对象";
p.close();
}
DDialog dialog("",rtn,nullptr);
dialog.setIcon(DStyle().standardIcon(DStyle::SP_MessageBoxInformation));
dialog.exec();
}
槽函数实现以后,在方法void MainWindow::initShortcuts()里面,绑定信号与槽,添加以下内容:
/*
begin,liwl
2021-08-27,liwl,自定义功能实现:
快捷键"ctrl+,",启动设置界面
快捷键"Alt+F",深浅主题切换
快捷键"Alt+R",终端透明
*/
connect(createNewShotcut("liwl.shortcuts.show_settings"), &QShortcut::activated, Service::instance(), &Service::slotShowSettingsDialog);
connect(createNewShotcut("liwl.shortcuts.dark_light_switch"), &QShortcut::activated, this, &MainWindow::slotShortcutSwitchTheme);
connect(createNewShotcut("liwl.shortcuts.terminal_transparency"), &QShortcut::activated, this, &MainWindow::slotShortcutTerminalTransparency);
connect(createNewShotcut("liwl.shortcuts.tab_transparency"), &QShortcut::activated, this, &MainWindow::slotShortcutTabTransparent);
connect(createNewShotcut("liwl.shortcuts.translate_shortcut"), &QShortcut::activated, this,&MainWindow::slotShortcutSelectTranslate);
/*end,liwl*/
当然,上面的槽函数声明,需要添加在mainwindow.h里面,内容如下:
/*以下是自定义功能实现的方法声明begin,liwl*/
void slotShortcutSwitchTheme();
void slotShortcutTerminalTransparency();
void slotShortcutTabTransparent();
void slotShortcutSelectTranslate();
在槽函数inline void MainWindow::slotShortcutTabTransparent()里面,使用了变量TAB_TRANSPARENT,将其定义在mainwindow.cpp里面即可。
const int MainWindow::m_MinWidth = 450;
const int MainWindow::m_MinHeight = 250;
/*2021-08-27,liwl,*/
bool TAB_TRANSPARENT = true;
DWIDGET_USE_NAMESPACE
3.总结
花了2天时间,相当于在deepin-terminal 20.2.3系统上,重新做了以下代码规整和编译安装。在虚拟机里面搞好之后,把代码git到了自己的liwldev分支上,以便今后能够更加便捷地开发维护。
实际上可能很多人对于这个过程不太感兴趣,不过个人在这个过程中学习了很多,并且后期也会持续关注deepin-terminal的动态,希望deepin-terminal能够更加专业跟强大吧。
内容可能不太详尽,部分地方可能出现纰漏,如果有需要了解的同学,可以发送邮件交流!