上海滩正常球迷 發表於 2021-8-28 10:58:00

deepin-terminal再改造

<h1 id="1-背景">1. 背景</h1>
<p>因为工作和学习的原因,deepin-terminal成为我使用最频繁的工具。</p>
<p>但是很多我个人需要的功能,原创版本并没有给出。无奈最后只能自己改造一下了。</p>
<p>前后也是花了不少时间,零基础上手,卓有成效,不仅实现自己想要的功能,也写了两篇博客作为记录</p>
<ul>
<li>https://www.cnblogs.com/liwanliangblog/p/14348593.html</li>
<li>https://www.cnblogs.com/liwanliangblog/p/14469250.html</li>
</ul>
<p>同时使用备份源码的方式,在新的系统更新后,直接解压源码进行编译安装。</p>
<p>但是,在最新的几个版本20.2.2+中,发现之前的源码已经出现了很多bug,具体的bug也反馈在论坛上:</p>
<ul>
<li>https://bbs.deepin.org/zh/post/224502</li>
</ul>
<p>在虚拟机安装的最新版本,重新测试了反馈的bug,发现有些是系统的bug</p>
<ul>
<li>截图复制,微信发送以后,切换到终端,双击复制,偶然出现无法复制的情况。能够复现</li>
</ul>
<p>也有些可能是特性</p>
<ul>
<li>如果某个标签页有输出内容,比如sudo apt update,或者有动作更新,比如ssh连接超时自动推出,标签页自动变更字体来提示用户</li>
</ul>
<p>除了论坛帖子里面总结的bug,一些新的bug,我在自己编译的版本上稳定复现,但是新安装的系统没有这个问题,那应该是我修改的版本有问题了。</p>
<p>综上一些问题的出现,让自己使用deepin-terminal的体验变差了。</p>
<p>所以我决定再出发,重新整理代码修改和编译。并且这次不是用打包源码的方式,而是直接拉一个开发分支的方式,不仅能够及时合并主线的特性和bug修复,也能够更加方便地并入自己的修改。</p>
<p>日后有需要,也可以方便给官方主线提交pr。</p>
<p>本篇博客主要实现的特性见下:</p>
<ol>
<li>双击复制可复制中文。</li>
<li>双击复制可指定可复制的特殊符号</li>
<li>光标下划线样式加粗</li>
<li>可设置终端启动时默认的目录</li>
<li>可设置一个翻译选中文本的脚本路径和快捷键</li>
<li>可使用快捷键设置终端和标签透明</li>
<li>可使用快捷键切换深浅主题</li>
<li>可使用快捷键打开设置界面</li>
</ol>
<p>一些其他的默认修改:</p>
<ol>
<li>默认双击复制时,英文逗号不作为分隔符</li>
<li>默认双击复制时,句末有英文逗号不复制该符号</li>
</ol>
<p>一些想要实现的特性:</p>
<ol>
<li>多行选中时,不选中行末空白</li>
<li>右键添加“使用文本编辑器打开选中文本”(其实已经实现,本版本懒得并入)</li>
<li>重新设计上下载功能(使用scp)</li>
<li>可设置的HistorySize</li>
</ol>
<h1 id="2-开发前的准备">2. 开发前的准备</h1>
<h2 id="21-创建开发分支">2.1 创建开发分支</h2>
<p>deepin-terminal的官方github地址:https://github.com/linuxdeepin/deepin-terminal</p>
<p>但是国内访问github的速度大家都懂,索性直接使用gitee导入deepin-terminal的github仓库(自行操作,gitee官方有介绍)</p>
<p>然后使用gitee创建开发分支(这里创建分支,不会对github上面的官方仓库造成影响)。</p>
<p>我创建分支为liwldev,分支的起始分支为官方的dev分支</p>
<h2 id="22-拉取代码并切换分支">2.2 拉取代码并切换分支</h2>
<blockquote>
<p>注意!!!从步骤2.2开始,建议在虚拟机环境进行</p>
</blockquote>
<p>创建了自己的liwldev分支之后,就可拉取代码了,这里拉取的是gitee的仓库代码</p>
<p><code>git clone git@gitee.com:yunweinote126/deepin-terminal.git</code></p>
<p>查看当前分支:<code>git branch -a</code>,代码指向了master分支</p>
<p>切换分支:<code>git checkout liwldev</code>,就切换到自己的分支了</p>
<h2 id="23-部署开发环境">2.3 部署开发环境</h2>
<p>其实也没啥部署的,简单的几个小步骤而已,按照官方的readme即可</p>
<p>进入到源码目录:<code>cd deepin-terminal</code></p>
<p>执行:<code>sudo apt build-dep .</code>,直接安装需要的依赖</p>
<p>然后就可以修改源码了</p>
<p>修改了源码,就可以编译和安装</p>
<p>编译的操作:<code>mkdir build &amp;&amp; cd build &amp;&amp; cmake .. &amp;&amp; make </code></p>
<p>安装的操作:<code>sudo make install</code>,默认安装在<code>/usr/local/bin/deepin-terminal</code></p>
<blockquote>
<p>强烈建议先卸载deepin-terminal,先sudo apt install konsole,暂时使用konsole终端,或者远程到主机后开发,因为一些特性需要重新安装</p>
</blockquote>
<h2 id="3-正式开发">3. 正式开发</h2>
<h3 id="31-需修改第三方库代码的特性">3.1 需修改第三方库代码的特性</h3>
<p>以下特性需要修改第三方库代码:</p>
<ul>
<li>双击可复制中文字符串(中文字符串以空格为分隔)</li>
<li>双击复制默认复制英文逗号。如果英文逗号在句尾,则不复制</li>
<li>光标下划线样式加粗</li>
</ul>
<p><strong>实现双击复制时,包括英文逗号</strong></p>
<p>修改的代码:deepin-terminal/3rdparty/terminalwidget/lib/TerminalDisplay.cpp,约449行</p>
<pre><code class="language-cpp">,_wordCharacters(QLatin1String(":@-./_~"))
//修改为
,_wordCharacters(QLatin1String(":@-./_~,"))
</code></pre>
<p><strong>实现双击复制,可复制中文</strong></p>
<blockquote>
<p>修改2个地方</p>
</blockquote>
<p>修改的代码:deepin-terminal/3rdparty/terminalwidget/lib/TerminalDisplay.cpp,约2594行</p>
<p>原来的代码:</p>
<pre><code class="language-cpp"> // find the start of the word
int x = bgnSel.x();
while ( ((x&gt;0) || (bgnSel.y()&gt;0 &amp;&amp; (_lineProperties &amp; LINE_WRAPPED) ))
               &amp;&amp; (charClass(_image.character) == selClass)
      )
</code></pre>
<p>修改为:</p>
<pre><code class="language-cpp"> // find the start of the word
int x = bgnSel.x();
while ( ((x&gt;0) || (bgnSel.y()&gt;0 &amp;&amp; (_lineProperties &amp; LINE_WRAPPED) ))
               &amp;&amp; (charClass(_image.character) == selClass || QChar( _image.character ) == QLatin1Char('\0') )
      )//QChar( _image.character ) == QLatin1Char('\0'),2021-08-26,liwl,通过调整字符前边界增加双击复制时对中文的支持
</code></pre>
<p>修改的代码:deepin-terminal/3rdparty/terminalwidget/lib/TerminalDisplay.cpp,约2614行</p>
<p>原来的代码:</p>
<pre><code class="language-cpp"> // find the end of the word
i = loc( endSel.x(), endSel.y() );
x = endSel.x();
while( ((x&lt;_usedColumns-1) || (endSel.y()&lt;_usedLines-1 &amp;&amp; (_lineProperties &amp; LINE_WRAPPED) ))
               &amp;&amp; ( charClass(_image.character) == selClass))
</code></pre>
<p>修改为:</p>
<pre><code class="language-cpp">// find the end of the word
i = loc( endSel.x(), endSel.y() );
x = endSel.x();
while( ((x&lt;_usedColumns-1) || (endSel.y()&lt;_usedLines-1 &amp;&amp; (_lineProperties &amp; LINE_WRAPPED) ))
               &amp;&amp; ( charClass(_image.character) == selClass || QChar( _image.character ) == QLatin1Char('\0') )
      ) //QChar( _image.character ) == QLatin1Char('\0'),2021-08-26,liwl,通过调整字符后边界增加双击复制时对中文的支持
</code></pre>
<p><strong>实现双击复制时,如果英文逗号在句尾则不复制该符号</strong></p>
<p>修改的代码:deepin-terminal/3rdparty/terminalwidget/lib/TerminalDisplay.cpp,约2630行</p>
<p>原来的代码:</p>
<pre><code class="language-cpp"> if ( ( QChar( _image.character ) == QLatin1Char('@') )
                &amp;&amp; ( ( endSel.x() - bgnSel.x() ) &gt; 0 ) )
   endSel.setX( x - 1 );
</code></pre>
<p>修改为:</p>
<pre><code class="language-cpp"> if ( ( QChar( _image.character ) == QLatin1Char('@') || QChar( _image.character) == QLatin1Char(',') )
                &amp;&amp; ( ( endSel.x() - bgnSel.x() ) &gt; 0 ) )
   endSel.setX( x - 1 );
</code></pre>
<p><strong>实现光标下滑线加粗</strong></p>
<p>修改的代码:deepin-terminal/3rdparty/terminalwidget/lib/TerminalDisplay.cpp,约760行</p>
<p>原来的代码:</p>
<pre><code class="language-cpp"> else if ( _cursorShape == Emulation::KeyboardCursorShape::UnderlineCursor )
            painter.drawLine(QLineF(
                              QPointF(cursorRect.left(),
                                       cursorRect.bottom()),
                                     QPointF(cursorRect.right(),
                                       cursorRect.bottom())));
</code></pre>
<p>修改为:</p>
<pre><code class="language-cpp">else if ( _cursorShape == Emulation::KeyboardCursorShape::UnderlineCursor )
    {   
      for(int i = 0; i &lt;= 3; ++i)
            painter.drawLine(QLineF(
                                 QPointF(cursorRect.left(),
                                       cursorRect.bottom()+i),
                                 QPointF(cursorRect.right(),
                                       cursorRect.bottom()+i)));
    }
</code></pre>
<h3 id="32-需要修改deepin源码的特性">3.2 需要修改deepin源码的特性</h3>
<p>以下特性需要修改deepin-terminal的代码</p>
<ul>
<li>增加设置选项的显示</li>
<li>增加“终端启动默认目录的”设置选项</li>
<li>增加“翻译脚本全路径”的设置选项</li>
<li>增加“双击可复制的特殊符号”的设置选项</li>
<li>增加快捷键选项”显示设置界面“</li>
<li>增加快捷键选项”深浅主题切换“</li>
<li>增加快捷键选项”终端透明“</li>
<li>增加快捷键选项”标签透明“</li>
<li>增加快捷键选项”翻译快捷键“</li>
</ul>
<p>具体的流程:</p>
<ol>
<li>修改默认配置文件default-config.json文件,增加需要的设置选项</li>
<li>cmake和make操作后,修改deepin-terminal_zh_CN.ts文件,以便能够正常显示中文</li>
<li>在具体的代码中实现各部分功能</li>
<li>最后编译测试安装</li>
</ol>
<p><strong>增加设置选项的显示</strong></p>
<p>修改的文件:deepin-terminal/src/assets/other/default-config.json,添加以下内容:</p>
<pre><code class="language-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"
                        }
                  ]
                }
            ]
      }
</code></pre>
<p>上面的配置搞定后,会在cmake和make过程中,自动生成设置界面。</p>
<p>接下来修改的文件:deepin-terminal/src/settingssettings_translation.cpp,修改如下:</p>
<pre><code class="language-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);

</code></pre>
<p>该部分内容主要是用来把对应文件里面的英文翻译为中文,否则设置界面只会显示出英文,而非中文。</p>
<p><strong>但是,这一步通过make时发现无法自动更新deepin-terminal_zh_CN.ts内容,不知道为何</strong></p>
<p>只能手动更新该文件了,deepin-terminal_zh_CN.ts添加如下内容,主要对应line行号!</p>
<pre><code class="language-xml">    &lt;message&gt;
      &lt;location filename="../src/settings/settings_translation.cpp" line="161"/&gt;
      &lt;source&gt;Liwl&lt;/source&gt;
      &lt;translation&gt;自定义&lt;/translation&gt;
    &lt;/message&gt;
    &lt;message&gt;
      &lt;location filename="../src/settings/settings_translation.cpp" line="163"/&gt;
      &lt;source&gt;Default dir start&lt;/source&gt;
      &lt;translation&gt;终端启动默认目录&lt;/translation&gt;
    &lt;/message&gt;
    &lt;message&gt;
      &lt;location filename="../src/settings/settings_translation.cpp" line="165"/&gt;
      &lt;source&gt;Script for translate&lt;/source&gt;
      &lt;translation&gt;翻译脚本全路径&lt;/translation&gt;
    &lt;/message&gt;
    &lt;message&gt;
      &lt;location filename="../src/settings/settings_translation.cpp" line="167"/&gt;
      &lt;source&gt;Double click select special sysmbol&lt;/source&gt;
      &lt;translation&gt;双击可复制的特殊符号&lt;/translation&gt;
    &lt;/message&gt;
    &lt;message&gt;
      &lt;location filename="../src/settings/settings_translation.cpp" line="171"/&gt;
      &lt;source&gt;Show settings&lt;/source&gt;
      &lt;translation&gt;显示设置界面&lt;/translation&gt;
    &lt;/message&gt;
    &lt;message&gt;
      &lt;location filename="../src/settings/settings_translation.cpp" line="173"/&gt;
      &lt;source&gt;Dark light switch&lt;/source&gt;
      &lt;translation&gt;深浅主题切换&lt;/translation&gt;
    &lt;/message&gt;
    &lt;message&gt;
      &lt;location filename="../src/settings/settings_translation.cpp" line="175"/&gt;
      &lt;source&gt;Terminal transparency&lt;/source&gt;
      &lt;translation&gt;终端透明&lt;/translation&gt;
    &lt;/message&gt;
    &lt;message&gt;
      &lt;location filename="../src/settings/settings_translation.cpp" line="177"/&gt;
      &lt;source&gt;Tab transparency&lt;/source&gt;
      &lt;translation&gt;标签透明&lt;/translation&gt;
    &lt;/message&gt;
    &lt;message&gt;
      &lt;location filename="../src/settings/settings_translation.cpp" line="179"/&gt;
      &lt;source&gt;Translate shortcut&lt;/source&gt;
      &lt;translation&gt;翻译快捷键&lt;/translation&gt;
    &lt;/message&gt;
</code></pre>
<p>然后进行<code>cmake &amp;&amp; make &amp;&amp; sudo make install</code>,设置界面将会增加如下图:</p>
<p><img src="https://img2020.cnblogs.com/blog/597042/202108/597042-20210828135458677-1089941366.png"></p>
<p>虽然设置界面更新了, 但是实际上功能还是没有的,对应的按键是没有任何作用的。</p>
<p><strong>终端启动默认目录功能实现</strong></p>
<p>deepin-terminal源码中,主要通过引入第三方库的qtermwidget.h头文件使用其定义的类的属性和方法。</p>
<p>deepin-terminal/src/views/termwidget.h,通过qtermwidget.h来的setWorkingDirectory方法来设置工作目录。</p>
<p>在termwidget.cpp的105左右,以下代码实现了对终端启动参数关于启动目录的判断和功能实现:</p>
<pre><code class="language-cpp">    // WorkingDir
    if (m_properties.contains(WorkingDir))
      setWorkingDirectory(m_properties.toString());
</code></pre>
<p>将其改为以下:</p>
<pre><code class="language-cpp">    // WorkingDir
    if (m_properties.contains(WorkingDir))
      setWorkingDirectory(m_properties.toString());
    /*else{...},2021-08-27,liwl,yunweinote@126.com。这段代码会影响全局,比如桌面右键或者文管右键打开终端时,均以配置的默认路径启动*/
    else{
      QString default_work_diretory = Settings::instance()-&gt;workDirectory();
      QFileInfo file(default_work_diretory);
      if (file.exists())
            setWorkingDirectory(default_work_diretory);
    }
</code></pre>
<p>上述代码通过Settings::instance()-&gt;workDirectory()方法获取设置的启动默认目录,如果该目录不存在,那么就按照以前的方式,该从哪里启动就从哪里启动。</p>
<p>Settings::instance()-&gt;workDirectory(),这段必须是需要在settings.h里面声明,并且在settings.cpp里面实现的,否则必然报错(语法错误)。其主要作用是从用户设置中读取用户配置的目录。</p>
<p>先在settings.h里面声明该方法,修改文件deepin-terminal/src/settings/settings.h,添加以下内容:</p>
<pre><code class="language-cpp">    /**
   * @brief 设置终端启动默认目录
   * @author liwl,yunweinote@126.com
   * @return
   */
    QString workDirectory() const;
</code></pre>
<p>然后在settings.cpp里面实现该方法,修改文件deepin-terminal/src/settings/settings.cpp,添加以下内容:</p>
<pre><code class="language-cpp">/*******************************************************************************
   1. @函数:    workDiretory
   2. @作者:    liwl,yunweinote@126.com
   3. @日期:    2021-08-27
   4. @说明:    设置界面获取启动初始目录
*******************************************************************************/
QString Settings::workDirectory() const
{
    return settings-&gt;option("liwl.terminal.default_dir_start")-&gt;value().toString();
}
</code></pre>
<p>上面就完成了的就是deepin-terminal能够从配置文件读取“终端启动默认目录”的值,并且从配置的路径启动。但是如果用户修改了以后,就没法生效了。</p>
<p>需要做一个事件的绑定,在方法void Settings::initConnection()里面,参照其他代码,添加以下代码:</p>
<pre><code class="language-cpp">    QPointer&lt;DSettingsOption&gt; workDirectory = settings-&gt;option("liwl.terminal.default_dir_start");
    connect(workDirectory, &amp;Dtk::Core::DSettingsOption::valueChanged, this, [ = ](QVariant value) {
      emit workDirectoryChanged(value.toString());
    });
</code></pre>
<p>上述代码的功能:如果监听到设置界面“终端启动默认目录“的设置值变化后,会触发一个workDirectoryChanged的信号。<strong>该信号也需要在settings.h里面声明</strong>。</p>
<pre><code class="language-cpp">signals:
        ...
    ...
        void workDirectoryChanged(QString workDirectory);
</code></pre>
<p>上面就完成了“终端启动默认目录”的功能</p>
<p><strong>但是,有一个非常重要的事情,就是我这里配置使用了liwl.terminal的自定义字符串,deepin-terminal没法解析这部分配置,所以需要做一下代码修改</strong></p>
<p>修改文件:deepin-terminal/src/settings/setting.cpp,修改方法:void Settings::initConnection()</p>
<p>原来的代码:</p>
<pre><code class="language-cpp">void Settings::initConnection()
{
    connect(settings, &amp;Dtk::Core::DSettings::valueChanged, this, [ = ](const QString &amp; key, const QVariant &amp; 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);
    });
</code></pre>
<p>修改后的代码:</p>
<pre><code class="language-cpp">void Settings::initConnection()
{
    connect(settings, &amp;Dtk::Core::DSettings::valueChanged, this, [ = ](const QString &amp; key, const QVariant &amp; 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);
    });
</code></pre>
<p>上面这一部分的修改,那肯定是及其重要的,否则部分功能肯定是没法实现的。</p>
<p>当然如果参照deepin-terminal其他代码,不是用自定义配置内容,而是添加到别的配置里面也是可以的,比如我之前的那两篇博客就是如此。</p>
<p>参照上面的内容,就可以对【双击可复制的特殊符号】以及【翻译脚本全路径】功能,做同样的添加操作。</p>
<p>编辑文件deepin-terminal/src/settings/settings.cpp,添加以下内容:</p>
<pre><code class="language-cpp">/*************************2021-08-27,liwl,begin*************************************************/

/*******************************************************************************
1. @函数:    scriptTranslate
2. @作者:    liwl,yunweinote@126.com
3. @日期:    2021-08-27
4. @说明:    获取翻译脚本全路径
*******************************************************************************/
QString Settings::scriptTranslate() const
{
    return settings-&gt;option("liwl.terminal.script_for_translate")-&gt;value().toString();
}

/*******************************************************************************
   1. @函数:    wordCharacters
   2. @作者:    liwl,yunweinote@126.com
   3. @日期:    2021-08-27
   4. @说明:    设置界面获取双击选中的特殊符号

*******************************************************************************/
QString Settings::wordCharacters() const
{
    return settings-&gt;option("liwl.terminal.double_click_select_special_sysmbol")-&gt;value().toString();
}

/*******************************************************************************
   1. @函数:    workDiretory
   2. @作者:    liwl,yunweinote@126.com
   3. @日期:    2021-08-27
   4. @说明:    设置界面获取启动初始目录
*******************************************************************************/
QString Settings::workDirectory() const
{
    return settings-&gt;option("liwl.terminal.default_dir_start")-&gt;value().toString();
}
</code></pre>
<p>编辑文件deepin-terminal/src/settings/settings.cpp,在方法void Settings::initConnection()里面添加以下代码:</p>
<pre><code class="language-cpp">    QPointer&lt;DSettingsOption&gt; scriptTranslate = settings-&gt;option("liwl.terminal.script_for_translate");
    connect(scriptTranslate, &amp;Dtk::Core::DSettingsOption::valueChanged, this, [ = ](QVariant value) {
      emit scriptTranslateChanged(value.toString());
    });

    QPointer&lt;DSettingsOption&gt; wordCharacters = settings-&gt;option("liwl.terminal.double_click_select_special_sysmbol");
    connect(wordCharacters, &amp;Dtk::Core::DSettingsOption::valueChanged, this, [ = ](QVariant value) {
      emit wordCharactersChanged(value.toString());
    });

    QPointer&lt;DSettingsOption&gt; workDirectory = settings-&gt;option("liwl.terminal.default_dir_start");
    connect(workDirectory, &amp;Dtk::Core::DSettingsOption::valueChanged, this, [ = ](QVariant value) {
      emit workDirectoryChanged(value.toString());
    });
</code></pre>
<p>编辑文件deepin-terminal/src/settings/settings.h,添加上述方法和信号的声明,如下:</p>
<pre><code class="language-cpp">    /**
   * @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;
</code></pre>
<p><strong>5个特性快捷键的增加</strong></p>
<p>这些实现大致相同,均是修改文件deepin-terminal/src/mainmanwindow.cpp内容。</p>
<p>添加【深浅主题切换】槽函数</p>
<pre><code class="language-cpp">/*
    2021-08-27,liwl(yunweinote@126.com),这里添加自定义功能实现——深浅主题切换的功能实现
*/
inline void MainWindow::slotShortcutSwitchTheme()
{
    if (Settings::instance()-&gt;colorScheme() == THEME_DARK)
    {   
      Settings::instance()-&gt;setColorScheme(THEME_LIGHT);
      Settings::instance()-&gt;setExtendColorScheme(THEME_NO);
      DGuiApplicationHelper::instance()-&gt;setPaletteType(DGuiApplicationHelper::LightType);
      emit DApplicationHelper::instance()-&gt;themeTypeChanged(DGuiApplicationHelper::LightType);
      return;
    }   

    if (Settings::instance()-&gt;colorScheme() == THEME_LIGHT)
    {   
      Settings::instance()-&gt;setColorScheme(THEME_DARK);
      Settings::instance()-&gt;setExtendColorScheme(THEME_NO);
      DGuiApplicationHelper::instance()-&gt;setPaletteType(DGuiApplicationHelper::DarkType);
      emit DApplicationHelper::instance()-&gt;themeTypeChanged(DGuiApplicationHelper::DarkType);
      return ;
    }   
}

</code></pre>
<p>添加【终端透明】槽函数</p>
<pre><code class="language-cpp">inline void MainWindow::slotShortcutTerminalTransparency()
{
    TermWidgetPage *page = currentPage();
    if (page) {
      if (Settings::instance()-&gt;settings-&gt;option("basic.interface.opacity")-&gt;value().toInt() == 100) {
            page-&gt;setTerminalOpacity(0.8);
            Settings::instance()-&gt;settings-&gt;option("basic.interface.opacity")-&gt;setValue(80);
      }else{
            page-&gt;setTerminalOpacity(1.0);
            Settings::instance()-&gt;settings-&gt;option("basic.interface.opacity")-&gt;setValue(100);
      }   
      page-&gt;focusCurrentTerm();
    }
}
</code></pre>
<p>添加【标签透明】槽函数</p>
<pre><code class="language-cpp">inline void MainWindow::slotShortcutTabTransparent()
{
    TermWidgetPage *page = currentPage();
    if (page) {
      if ( TAB_TRANSPARENT )
      {   
            page-&gt;setTerminalOpacity(0.7);
            TAB_TRANSPARENT = false;
      }else{
            page-&gt;setTerminalOpacity(1);
            TAB_TRANSPARENT = true;
      }   
      page-&gt;focusCurrentTerm();
    }
}
</code></pre>
<p>添加【翻译快捷键】槽函数</p>
<pre><code class="language-cpp">inline void MainWindow::slotShortcutSelectTranslate()
{
    QString rtn = "";
    QString script = Settings::instance()-&gt;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();
}
</code></pre>
<p>槽函数实现以后,在方法void MainWindow::initShortcuts()里面,绑定信号与槽,添加以下内容:</p>
<pre><code class="language-cpp">    /*
      begin,liwl
      2021-08-27,liwl,自定义功能实现:
            快捷键"ctrl+,",启动设置界面
            快捷键"Alt+F",深浅主题切换
            快捷键"Alt+R",终端透明
    */
    connect(createNewShotcut("liwl.shortcuts.show_settings"), &amp;QShortcut::activated, Service::instance(), &amp;Service::slotShowSettingsDialog);
    connect(createNewShotcut("liwl.shortcuts.dark_light_switch"), &amp;QShortcut::activated, this, &amp;MainWindow::slotShortcutSwitchTheme);
    connect(createNewShotcut("liwl.shortcuts.terminal_transparency"), &amp;QShortcut::activated, this, &amp;MainWindow::slotShortcutTerminalTransparency);
    connect(createNewShotcut("liwl.shortcuts.tab_transparency"), &amp;QShortcut::activated, this, &amp;MainWindow::slotShortcutTabTransparent);
    connect(createNewShotcut("liwl.shortcuts.translate_shortcut"), &amp;QShortcut::activated, this,&amp;MainWindow::slotShortcutSelectTranslate);
    /*end,liwl*/
</code></pre>
<p>当然,上面的槽函数声明,需要添加在mainwindow.h里面,内容如下:</p>
<pre><code class="language-cpp">    /*以下是自定义功能实现的方法声明begin,liwl*/
    void slotShortcutSwitchTheme();
    void slotShortcutTerminalTransparency();
    void slotShortcutTabTransparent();
    void slotShortcutSelectTranslate();
</code></pre>
<p>在槽函数inline void MainWindow::slotShortcutTabTransparent()里面,使用了变量TAB_TRANSPARENT,将其定义在mainwindow.cpp里面即可。</p>
<pre><code class="language-cpp">const int MainWindow::m_MinWidth = 450;
const int MainWindow::m_MinHeight = 250;

/*2021-08-27,liwl,*/
bool TAB_TRANSPARENT = true;

DWIDGET_USE_NAMESPACE
</code></pre>
<h1 id="3总结">3.总结</h1>
<p>花了2天时间,相当于在deepin-terminal 20.2.3系统上,重新做了以下代码规整和编译安装。在虚拟机里面搞好之后,把代码git到了自己的liwldev分支上,以便今后能够更加便捷地开发维护。</p>
<p>实际上可能很多人对于这个过程不太感兴趣,不过个人在这个过程中学习了很多,并且后期也会持续关注deepin-terminal的动态,希望deepin-terminal能够更加专业跟强大吧。</p>
<p>内容可能不太详尽,部分地方可能出现纰漏,如果有需要了解的同学,可以发送邮件交流!</p><br><br>
来源:https://www.cnblogs.com/liwanliangblog/p/15196250.html
頁: [1]
查看完整版本: deepin-terminal再改造