(R7) Personal Blog2021-06-10T10:25:22+00:00http://roman-yagodin.github.ioRoman M. Yagodin & R7.Labsroman-yagodin@gmail.comО проекте Webdoctor2021-06-10T00:00:00+00:00http://roman-yagodin.github.io/2021/06/10/about-webdoctor-project<div class="sect1">
<h2 id="о-проекте-webdoctor">О проекте "Webdoctor"</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Ситуация довольно типичная - многие "ура"-специалисты готовы склепать сайт, но поддерживать и тянуть его - это тяжело и плохо оплачивается. Веб-студии также готовы вам помочь - обычно сделав новый сайт, дальнейшая поддержка которого влетит "в копеечку", поскольку размещен он на их хостинге и сделан с помощью их "особых" технологий и решений. В рамках проекта Webdoctor я занимаюсь "оживлением" заброшенных веб-проектов.</p>
</div>
<div class="paragraph">
<p>Я предлагаю простое решение:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>На первом этапе я оживляю ваш веб-сайт, решая насущные вопросы.</p>
</li>
<li>
<p>На втором этапе я передаю проект вам в полное управление.</p>
</li>
</ol>
</div>
<div class="paragraph">
<p>Если насущные вопросы не удается решить за осмысленное время, вы получаете набор конкретных рекомендаций относительно дальнейших действий.</p>
</div>
<div class="paragraph">
<p>Полная передача проекта заключается в полной передаче вам прав на управление доменными именами, хостингом DNS, хостингом сайта, исходным кодом и др. ресурсами, а также в обучении вас (или вашего человека) основам управления контентом на сайте, по необходимости - основам веб-технологий.</p>
</div>
<div class="paragraph">
<p>Таким образом, на выходе вы получаете фунционирующий веб-сайт и возможность его поддерживать самостоятельно - без завязки на любых третьх лиц - меня, "ура"-специалиста или веб-студию.</p>
</div>
<div class="paragraph">
<p>Если у вас есть заброшенный веб-сайт и вы хотите его оживить - пишите мне в Telegram <a href="tel:+79275308750">+79275308750</a> или на электронную почту <a href="mailto:roman.yagodin@gmail.com">roman.yagodin@gmail.com</a>. Мы договоримся о первичной консультации. Обычно она занимает около часа, стоимость фиксированная - 1000 р.</p>
</div>
</div>
</div>Install DNN 9 on Windows Server 2019 Core2020-08-08T00:00:00+00:00http://roman-yagodin.github.io/guide/2020/08/08/install-dnn9-on-windows-server-2019-core<div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>This guide describes the process of installing DNN 9 on Windows Server Core 2016/2019 VM for development purposes.
It is tested on DNN 8.0.4, DNN 9.6.2 and DNN 9.8.0. Some things are still missing or don’t have detailed description,
but I hope it still will be helpful, especially if you are new to the Windows Server Core administration.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="setup-virtualbox-vm-and-networking">Setup VirtualBox VM and networking</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Install <strong>Windows Server 2019 x64 Core</strong> on e.g. <strong>VirtualBox</strong> (out of scope of this post),
using 32 GB dynamic VDI disk, 1 GB of RAM and UEFI. You can tweak RAM size and resize virtual disk later.</p>
</div>
<div class="paragraph">
<p>You will need to configure host-only network interface, which will allow connections between virtual and host machines.
Of cause, there are more <a href="https://www.virtualbox.org/manual/ch06.html">virtual networking</a> options.</p>
</div>
<div class="paragraph">
<p>Assuming that DHCP server of host-only interface is configured to lease IP addresses starting with 192.168.56.101, you should add the following line to <code>/etc/hosts</code> (on Linux) or <code>C:\Windows\System32\drivers\etc\hosts</code> (on Windows):</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code>192.168.56.101 dnn980.hostname.local</code></pre>
</div>
</div>
<div class="paragraph">
<p>If you’ll need multilanguage website, it is good to have separate alias for each of target languages:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code>192.168.56.101 dnn980.hostname.local
192.168.56.101 de.dnn980.hostname.local
192.168.56.101 ru.dnn980.hostname.local
...</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="install-iis">Install IIS</h2>
<div class="sectionbody">
<div class="paragraph">
<p>List of currently installed features:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="powershell"><span class="n">Get-WindowsFeature</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Install IIS and ASP.NET:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="powershell"><span class="n">Install-WindowsFeature</span><span class="w"> </span><span class="nx">Web-Server</span><span class="w">
</span><span class="n">Install-WindowsFeature</span><span class="w"> </span><span class="nx">Web-Asp-Net45</span></code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="install-sql-server-expressdeveloper">Install SQL Server Express/Developer</h2>
<div class="sectionbody">
<div class="ulist">
<ul>
<li>
<p><a href="https://docs.microsoft.com/ru-ru/sql/database-engine/install-windows/install-sql-server-from-the-command-prompt?view=sql-server-2017" class="bare">https://docs.microsoft.com/ru-ru/sql/database-engine/install-windows/install-sql-server-from-the-command-prompt?view=sql-server-2017</a></p>
</li>
<li>
<p><a href="https://anikinsv.blogspot.com/2018/08/ms-sql.html" class="bare">https://anikinsv.blogspot.com/2018/08/ms-sql.html</a></p>
</li>
<li>
<p><a href="https://system-administrators.info/?p=6506" class="bare">https://system-administrators.info/?p=6506</a></p>
</li>
<li>
<p><a href="https://mssqltrek.com/2011/08/23/installing-sql-server-from-command-linecmd/" class="bare">https://mssqltrek.com/2011/08/23/installing-sql-server-from-command-linecmd/</a></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Get and run the SQL Express 2019 <strong>downloader</strong>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="powershell"><span class="n">wget</span><span class="w"> </span><span class="nx">https://go.microsoft.com/fwlink/</span><span class="nf">?</span><span class="nx">linkid</span><span class="o">=</span><span class="nx">866658</span><span class="w"> </span><span class="nt">-UseBasicParsing</span><span class="w"> </span><span class="nt">-OutFile</span><span class="w"> </span><span class="nx">sqlexpress.exe</span><span class="w">
</span><span class="o">.</span><span class="n">/sqlexpress.exe</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Proceed with GUI wizard from now to download <strong>real installer</strong>.</p>
</div>
<div class="paragraph">
<p>After downloading real installer, find and run <code>SETUP.EXE</code> - this will require some command-line switches.</p>
</div>
<div class="paragraph">
<p>Good old GUI wizard:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="shell">./SETUP.EXE /UIMODE<span class="o">=</span>EnableUIOnServerCore /Action<span class="o">=</span>Install</code></pre>
</div>
</div>
<div class="paragraph">
<p>Command-line:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="shell">./SETUP.EXE /Q /Action<span class="o">=</span>Install /SECURITYMODE<span class="o">=</span>SQL /SAPWD<span class="o">=</span><span class="s2">"MyP@</span><span class="nv">$$</span><span class="s2">w0rd"</span> /TCPENABLED<span class="o">=</span>1 /FEATURES<span class="o">=</span>SQLEngine /ADDCURRENTUSERASSQLADMIN</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="create-the-database-for-dnn">Create the database for DNN</h2>
<div class="sectionbody">
<div class="ulist">
<ul>
<li>
<p><a href="https://www.mssqltips.com/sqlservertip/6223/create-sql-server-database-with-powershell/" class="bare">https://www.mssqltips.com/sqlservertip/6223/create-sql-server-database-with-powershell/</a></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Create folder to store databases:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="powershell"><span class="n">mkdir</span><span class="w"> </span><span class="nx">C:\Databases</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Configure permissions:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="powershell"><span class="nv">$acl</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Get-Acl</span><span class="w"> </span><span class="s2">"C:\Databases"</span><span class="w">
</span><span class="nv">$accessRule</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">New-Object</span><span class="w"> </span><span class="nx">System.Security.AccessControl.FileSystemAccessRule</span><span class="p">(</span><span class="s2">"NT Service\MSSQLSERVER"</span><span class="p">,</span><span class="w"> </span><span class="s2">"FullControl"</span><span class="p">,</span><span class="w"> </span><span class="s2">"ContainerInherit,ObjectInherit"</span><span class="p">,</span><span class="w"> </span><span class="s2">"None"</span><span class="p">,</span><span class="w"> </span><span class="s2">"Allow"</span><span class="p">)</span><span class="w">
</span><span class="nv">$acl</span><span class="o">.</span><span class="nf">SetAccessRule</span><span class="p">(</span><span class="nv">$accessRule</span><span class="p">)</span><span class="w">
</span><span class="n">Set-Acl</span><span class="w"> </span><span class="s2">"C:\Databases"</span><span class="w"> </span><span class="nv">$acl</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Create the <code>CreateDnn980Database.sql</code> file somewhere:</p>
</div>
<div class="listingblock">
<div class="title">CreateDnn980Database.sql</div>
<div class="content">
<pre class="rouge highlight"><code data-lang="sql"><span class="n">use</span> <span class="n">master</span><span class="p">;</span>
<span class="k">go</span>
<span class="k">create</span> <span class="k">database</span> <span class="n">Dnn980</span>
<span class="k">on</span> <span class="p">(</span><span class="n">name</span> <span class="o">=</span> <span class="n">N</span><span class="s1">'Dnn980'</span><span class="p">,</span> <span class="n">filename</span> <span class="o">=</span> <span class="n">N</span><span class="s1">'C:</span><span class="se">\D</span><span class="s1">atabases</span><span class="se">\D</span><span class="s1">nn980.mdf'</span><span class="p">)</span>
<span class="n">log</span> <span class="k">on</span> <span class="p">(</span><span class="n">name</span> <span class="o">=</span> <span class="n">N</span><span class="s1">'Dnn980_log'</span><span class="p">,</span> <span class="n">filename</span> <span class="o">=</span> <span class="n">N</span><span class="s1">'C:</span><span class="se">\D</span><span class="s1">atabases</span><span class="se">\D</span><span class="s1">nn980_log.ldf'</span><span class="p">);</span>
<span class="k">go</span>
<span class="k">alter</span> <span class="k">authorization</span> <span class="k">on</span> <span class="k">database</span><span class="p">::</span><span class="n">Dnn980</span> <span class="k">to</span> <span class="n">sa</span>
<span class="k">go</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Execute it:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="powershell"><span class="n">Invoke-SqlCmd</span><span class="w"> </span><span class="nt">-ServerInstance</span><span class="w"> </span><span class="s2">"(local)"</span><span class="w"> </span><span class="nt">-InputFile</span><span class="w"> </span><span class="s2">"CreateDnn980Database.sql"</span></code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="configure-firewall">Configure firewall</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Get the current rules, e.g. related to ICMP:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="powershell"><span class="n">Get-NetFirewallRule</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">Where</span><span class="w"> </span><span class="nx">Name</span><span class="w"> </span><span class="o">-like</span><span class="w"> </span><span class="s2">"*ICMP*"</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Allow ping:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="powershell"><span class="n">Set-NetFirewallRule</span><span class="w"> </span><span class="nt">-Name</span><span class="w"> </span><span class="nx">FPS-ICMP4-ERQ-In</span><span class="w"> </span><span class="nt">-Enabled</span><span class="w"> </span><span class="nx">True</span><span class="w"> </span><span class="nt">-Profile</span><span class="w"> </span><span class="nx">Any</span><span class="w"> </span><span class="nt">-Action</span><span class="w"> </span><span class="nx">Allow</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Allow external connections to IIS via HTTP (port 80):</p>
</div>
<div class="paragraph">
<p>This is done by default by adding webserver role, rule names <code>IIS-WebServerRole-HTTP-In-TCP</code> and <code>IIS-WebServerRole-HTTPS-In-TCP</code>.</p>
</div>
<div class="paragraph">
<p>Allow inbound SMB for shared folders:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="powershell"><span class="n">Set-NetFirewallRule</span><span class="w"> </span><span class="nt">-Name</span><span class="w"> </span><span class="nx">FPS-SMB-In-TCP</span><span class="w"> </span><span class="nt">-Enabled</span><span class="w"> </span><span class="nx">True</span><span class="w"> </span><span class="nt">-Profile</span><span class="w"> </span><span class="nx">Any</span><span class="w"> </span><span class="nt">-Action</span><span class="w"> </span><span class="nx">Allow</span></code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="download-and-unpack-dnn">Download and unpack DNN</h2>
<div class="sectionbody">
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="powershell"><span class="n">wget</span><span class="w"> </span><span class="nx">https://github.com/dnnsoftware/Dnn.Platform/releases/download/v9.6.2/DNN_Platform_9.6.2_Install.zip</span><span class="w"> </span><span class="nt">-UseBasicParsing</span><span class="w"> </span><span class="nt">-OutFile</span><span class="w"> </span><span class="nx">dnn980.zip</span><span class="w">
</span><span class="n">Expand-Archive</span><span class="w"> </span><span class="nx">dnn980.zip</span><span class="w"> </span><span class="nt">-DestinationPath</span><span class="w"> </span><span class="nx">C:\Dnn980</span><span class="w">
</span><span class="n">rm</span><span class="w"> </span><span class="nx">dnn980.zip</span></code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="add-website-and-application-pool-in-iis">Add website and application pool in IIS</h2>
<div class="sectionbody">
<div class="ulist">
<ul>
<li>
<p><a href="https://www.itprotoday.com/powershell/managing-internet-information-services-iis-powershell-snap" class="bare">https://www.itprotoday.com/powershell/managing-internet-information-services-iis-powershell-snap</a></p>
</li>
<li>
<p><a href="https://docs.microsoft.com/ru-ru/powershell/module/iisadministration/New-IISSite?view=win10-ps" class="bare">https://docs.microsoft.com/ru-ru/powershell/module/iisadministration/New-IISSite?view=win10-ps</a></p>
</li>
<li>
<p><a href="https://octopus.com/blog/iis-powershell" class="bare">https://octopus.com/blog/iis-powershell</a></p>
</li>
</ul>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="powershell"><span class="n">Import-Module</span><span class="w"> </span><span class="nx">IISAdministration</span><span class="w">
</span><span class="n">New-IISSite</span><span class="w"> </span><span class="nt">-Name</span><span class="w"> </span><span class="nx">dnn980.hostname.local</span><span class="w"> </span><span class="nt">-BindingInformation</span><span class="w"> </span><span class="s2">"*:80:dnn980.hostname.local"</span><span class="w"> </span><span class="nt">-Protocol</span><span class="w"> </span><span class="nx">http</span><span class="w"> </span><span class="nt">-PhysicalPath</span><span class="w"> </span><span class="nx">C:\Dnn980</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>You can easily manipulate binding information for the website using <code>New-WebBinding</code> and <code>Remove-WebBinding</code> commandlets:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="powershell"><span class="n">Import-Module</span><span class="w"> </span><span class="nx">WebAdministration</span><span class="w">
</span><span class="n">Remove-WebBinding</span><span class="w"> </span><span class="nt">-Name</span><span class="w"> </span><span class="nx">dnn980.hostname.local</span><span class="w"> </span><span class="nt">-HostHeader</span><span class="w"> </span><span class="nx">dnn980.hostname.local</span><span class="w">
</span><span class="n">New-WebBinding</span><span class="w"> </span><span class="nt">-Name</span><span class="w"> </span><span class="nx">dnn980.hostname.local</span><span class="w"> </span><span class="nt">-port</span><span class="w"> </span><span class="nx">443</span><span class="w"> </span><span class="nt">-Protocol</span><span class="w"> </span><span class="nx">https</span><span class="w"> </span><span class="nt">-HostHeader</span><span class="w"> </span><span class="nx">dnn980.hostname.local</span></code></pre>
</div>
</div>
<div class="paragraph">
<p><strong>But this will not create the application pool for the new website!</strong></p>
</div>
<div class="paragraph">
<p>Create new application pool and bind it to the website:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="powershell"><span class="n">Import-Module</span><span class="w"> </span><span class="nx">WebAdministration</span><span class="w">
</span><span class="n">New-WebAppPool</span><span class="w"> </span><span class="nt">-Name</span><span class="w"> </span><span class="s2">"dnn980.hostname.local"</span><span class="w">
</span><span class="n">Set-ItemProperty</span><span class="w"> </span><span class="s2">"IIS:\Sites\dnn980.hostname.local"</span><span class="w"> </span><span class="nt">-Name</span><span class="w"> </span><span class="s2">"applicationPool"</span><span class="w"> </span><span class="nt">-Value</span><span class="w"> </span><span class="s2">"dnn980.hostname.local"</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Check:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="powershell"><span class="n">Import-Module</span><span class="w"> </span><span class="nx">WebAdministration</span><span class="w">
</span><span class="n">ls</span><span class="w"> </span><span class="s2">"IIS:\AppPools"</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>This will list all websites and corresponding application pools.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="configure-file-system-permissions">Configure file system permissions</h2>
<div class="sectionbody">
<div class="ulist">
<ul>
<li>
<p><a href="https://stackoverflow.com/questions/25779423/powershell-to-set-folder-permissions#25780422" class="bare">https://stackoverflow.com/questions/25779423/powershell-to-set-folder-permissions#25780422</a></p>
</li>
</ul>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="powershell"><span class="nv">$acl</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Get-Acl</span><span class="w"> </span><span class="s2">"C:\Dnn980"</span><span class="w">
</span><span class="nv">$accessRule</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">New-Object</span><span class="w"> </span><span class="nx">System.Security.AccessControl.FileSystemAccessRule</span><span class="p">(</span><span class="s2">"IIS_IUSRS"</span><span class="p">,</span><span class="w"> </span><span class="s2">"ReadAndExecute"</span><span class="p">,</span><span class="w"> </span><span class="s2">"ContainerInherit,ObjectInherit"</span><span class="p">,</span><span class="w"> </span><span class="s2">"None"</span><span class="p">,</span><span class="w"> </span><span class="s2">"Allow"</span><span class="p">)</span><span class="w">
</span><span class="nv">$acl</span><span class="o">.</span><span class="nf">SetAccessRule</span><span class="p">(</span><span class="nv">$accessRule</span><span class="p">)</span><span class="w">
</span><span class="n">Set-Acl</span><span class="w"> </span><span class="s2">"C:\Dnn980"</span><span class="w"> </span><span class="nv">$acl</span><span class="w">
</span><span class="nv">$accessRule</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">New-Object</span><span class="w"> </span><span class="nx">System.Security.AccessControl.FileSystemAccessRule</span><span class="p">(</span><span class="s2">"IIS APPPOOL\dnn980.hostname.local"</span><span class="p">,</span><span class="w"> </span><span class="s2">"FullControl"</span><span class="p">,</span><span class="w"> </span><span class="s2">"ContainerInherit,ObjectInherit"</span><span class="p">,</span><span class="w"> </span><span class="s2">"None"</span><span class="p">,</span><span class="w"> </span><span class="s2">"Allow"</span><span class="p">)</span><span class="w">
</span><span class="nv">$acl</span><span class="o">.</span><span class="nf">SetAccessRule</span><span class="p">(</span><span class="nv">$accessRule</span><span class="p">)</span><span class="w">
</span><span class="n">Set-Acl</span><span class="w"> </span><span class="s2">"C:\Dnn980"</span><span class="w"> </span><span class="nv">$acl</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Check:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="powershell"><span class="n">Get-Acl</span><span class="w"> </span><span class="s2">"C:\Dnn980"</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">Format-List</span></code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="share-website-folder">Share website folder</h2>
<div class="sectionbody">
<div class="paragraph">
<p>You will probably need the website folder to be accessible via share,
so you can setup automatic deployment of build output from IDE into it.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="powershell"><span class="n">Install-WindowsFeature</span><span class="w"> </span><span class="nx">FS-SMB1-SERVER</span><span class="w">
</span><span class="c"># Optional?</span><span class="w">
</span><span class="c"># Enable-WindowsOptionalFeature -Online -FeatureName smb1protocol</span><span class="w">
</span><span class="n">New-SMBShare</span><span class="w"> </span><span class="nt">-Name</span><span class="w"> </span><span class="s2">"Dnn980"</span><span class="w"> </span><span class="nt">-Path</span><span class="w"> </span><span class="s2">"C:\Dnn980"</span><span class="w"> </span><span class="nt">-FullAccess</span><span class="w"> </span><span class="s2">"Administrator"</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Test this by trying to access share by IP like that: <code>\\192.168.56.101\Dnn980</code>.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="run-dnn-install">Run DNN install</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Access http://dnn980.hostname.local from a web browser on host machine and follow installation wizard!</p>
</div>
<div class="paragraph">
<p>Database setup form fields:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Database Setup</dt>
<dd>
<p>Custom</p>
</dd>
<dt class="hdlist1">Database Type</dt>
<dd>
<p>SQL Server/SQL Server Express Database</p>
</dd>
<dt class="hdlist1">Server Name</dt>
<dd>
<p>(local)</p>
</dd>
<dt class="hdlist1">Database Name</dt>
<dd>
<p>Dnn980</p>
</dd>
<dt class="hdlist1">Database Username</dt>
<dd>
<p>sa</p>
</dd>
</dl>
</div>
</div>
</div>
<div class="sect1">
<h2 id="extra">Extra</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="install-far-file-manager">Install Far file manager</h3>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="powershell"><span class="n">wget</span><span class="w"> </span><span class="nx">far-manager.ru/files/Far_Manager_v3.0_build_4455.zip</span><span class="w"> </span><span class="nt">-UseBasicParsing</span><span class="w"> </span><span class="nt">-OutFile</span><span class="w"> </span><span class="nx">far.zip</span><span class="w">
</span><span class="n">Expand-Archive</span><span class="w"> </span><span class="nx">far.zip</span><span class="w"> </span><span class="nt">-DestinationPath</span><span class="w"> </span><span class="o">.</span><span class="w">
</span><span class="o">.</span><span class="n">/Far30b4455.x64.20151115.msi</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Now you will probably want to add <code>far</code> command to the <code>PATH</code>.</p>
</div>
<div class="ulist">
<ul>
<li>
<p><a href="https://stackoverflow.com/questions/9546324/adding-directory-to-path-environment-variable-in-windows" class="bare">https://stackoverflow.com/questions/9546324/adding-directory-to-path-environment-variable-in-windows</a></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Most simple way to do it is via <code>regedit</code>. User environment variables are at <code>HKCU\Environment</code>, system variables are at <code>HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment</code>.</p>
</div>
</div>
<div class="sect2">
<h3 id="multiple-console-windows">Multiple console windows</h3>
<div class="paragraph">
<p>Press <span class="keyseq"><kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>Del</kbd></span>, select <strong>Task Manager</strong>, then run <code>cmd.exe</code> or <code>powershell.exe</code> via <span class="menuseq"><b class="menu">File</b> <b class="caret">›</b> <b class="menuitem">Run new task</b></span> menu.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="todo">TODO</h2>
<div class="sectionbody">
<div class="ulist">
<ul>
<li>
<p>Separate initial configuration and adding new DNN instances</p>
</li>
<li>
<p>Create separate database owner for each database</p>
</li>
<li>
<p>Configure firewall to allow external connections to the SQL Server: <a href="https://docs.microsoft.com/en-us/sql/sql-server/install/configure-the-windows-firewall-to-allow-sql-server-access?view=sql-server-ver15" class="bare">https://docs.microsoft.com/en-us/sql/sql-server/install/configure-the-windows-firewall-to-allow-sql-server-access?view=sql-server-ver15</a></p>
</li>
<li>
<p>Further integration (probably out of scope):
<a href="https://github.com/roman-yagodin/vm-scripts">vm-scripts</a>, <code>/etc/fstab</code> entries for shares, deploy build output to the share, etc.</p>
</li>
</ul>
</div>
</div>
</div>Arcanum on Linux with Steam Play Proton2019-11-12T00:00:00+00:00http://roman-yagodin.github.io/guide/2019/11/12/arcanum-proton
<p>Celebrating recent update to <a href="http://terra-arcanum.com/drog/uap.html">Unofficial Arcanum Patch</a> after almost 10 years since the last one, I decided to write this post to guide you through the basics of install and setup process of famous <a href="https://store.steampowered.com/app/500810/Arcanum_Of_Steamworks_and_Magick_Obscura/">Arcanum: Of Steamworks and Magick Obscura</a> title on Linux with the Steam Play <a href="https://github.com/ValveSoftware/Proton">Proton</a>.</p>
<!-- more -->
<p><img src="/assets/images/arcanum-library.png" alt="Arcanum in Steam library" class="img-fluid" /></p>
<h2 id="proton-and-steam-play">Proton and Steam Play</h2>
<p><a href="https://github.com/ValveSoftware/Proton">Proton</a> is compatibility tool for <a href="https://steamcommunity.com/games/221410/announcements/detail/1696055855739350561">Steam Play</a> based mainly on <em>Wine</em> plus some other components like <em>DXVK</em>. It allows you to install and run Windows games via Steam client on “unsupported” platforms - almost like a native games. While you still can install any game from your Steam library on Linux with <a href="https://developer.valvesoftware.com/wiki/SteamCMD">steamcmd</a>, and then use <em>Wine</em>, <em>Winetricks</em> or e.g. <a href="https://www.playonlinux.com">PlayOnLinux</a> to run it, the <em>Proton</em> provides very refreshing and more straightforward alternative.</p>
<p>The <em>Proton</em> doesn’t looks very mature for the moment, but it contantly improves. User reports about various games are gathered in the <a href="https://www.protondb.com">ProtonDB</a> (its like the <a href="https://www.winehq.org">WineHQ</a> is for <em>Wine</em>), there you can find useful tips on how to setup your favorite game or which quirks to expect from it. You can also find the growing list of <a href="https://www.protondb.com/explore?page=0&selectedFilters=whitelisted">whitelisted</a> games there.</p>
<h2 id="general-sequence">General sequence</h2>
<ol>
<li>Install the game.</li>
<li>Setup <em>wineconsole</em>.</li>
<li>Install <em>Unofficial Arcanum Patch</em>.</li>
<li>Apply <em>HighRes</em> patch.</li>
<li>Play.</li>
</ol>
<h2 id="install-the-game">Install the game</h2>
<p>First of all, you need to enable Steam Play for all titles via <em>Steam client settings</em> / <em>Steam Play options</em>.</p>
<p>This will allow you to install (and run) Arcanum on Linux just like any other native Linux game from your Steam libary.</p>
<p><img src="/assets/images/arcanum-enable-steam-play.png" alt="Enable Steam play for all other titles" class="img-fluid" /></p>
<p>After that, you can install the game by just clicking <em>Install</em>.</p>
<p>After installing, run game once - just to create <code class="language-plaintext highlighter-rouge">$HOME/.local/share/Steam/steamapps/compatdata/500810</code> directory.
It will take some time, as Steam will need to download <em>Proton</em> and create wineprefix for the game.</p>
<p>Add symlink to the game install directory and place it inside the <code class="language-plaintext highlighter-rouge">$HOME/.local/share/Steam/steamapps/compatdata/500810/pfx/drive_c</code> directory:</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">ln</span> <span class="nt">-s</span> <span class="s2">"</span><span class="nv">$HOME</span><span class="s2">/.local/share/Steam/steamapps/common/Arcanum"</span> <span class="se">\</span>
<span class="s2">"</span><span class="nv">$HOME</span><span class="s2">/.local/share/Steam/steamapps/compatdata/500810/pfx/drive_c/Arcanum"</span>
</code></pre></div></div>
<p><strong>Note:</strong> I think there should be a better way to do that (without creating symlink), as <em>Proton</em> surely do need to merge the game install directory with wineprefix somehow.
If you know something about it, please drop a comment.</p>
<h2 id="setup-wineconsole">Setup wineconsole</h2>
<h3 id="wine-way">Wine way</h3>
<p><em>wineconsole</em> is the <em>Wine</em> console manager, used to run console commands and applications. We will need it to run <code class="language-plaintext highlighter-rouge">cmd.exe</code> shell in order to run some commands to setup the game.</p>
<p>Execute in the terminal emulator (replace <code class="language-plaintext highlighter-rouge">Proton 4.11</code> with actual <em>Proton</em> version):</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">env </span><span class="nv">WINEPREFIX</span><span class="o">=</span><span class="s2">"</span><span class="nv">$HOME</span><span class="s2">/.steam/steam/steamapps/compatdata/500810/pfx"</span> <span class="se">\</span>
<span class="nv">WINEPATH</span><span class="o">=</span><span class="s2">"</span><span class="nv">$HOME</span><span class="s2">/.local/share/Steam/steamapps/common/Proton 4.11/dist/bin/wine"</span> <span class="se">\</span>
wineconsole
</code></pre></div></div>
<p><img src="/assets/images/arcanum-wineconsole.png" alt="Arcanum folder via wineconsole" class="img-fluid" /></p>
<p>Feeling some nostalgia? It’s cool!</p>
<p><strong>Note:</strong> AFAIK this is not 100% safe way - but it will work the same for other games, which doesn’t have configurable launcher.</p>
<h3 id="sierralauncher-way">SierraLauncher way</h3>
<p>Backup <code class="language-plaintext highlighter-rouge">SierraLauncher.ini</code> into <code class="language-plaintext highlighter-rouge">original_SierraLauncher.ini</code></p>
<p>Create <code class="language-plaintext highlighter-rouge">cmd.bat</code> file with following content:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cmd.exe
</code></pre></div></div>
<p>Modify <code class="language-plaintext highlighter-rouge">SierraLauncher.ini</code></p>
<div class="language-ini highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nn">[Launcher]</span>
<span class="py">Name</span><span class="p">=</span><span class="s">Arcanum</span>
<span class="py">NumButtons</span><span class="p">=</span><span class="s">1</span>
<span class="py">GameManual</span><span class="p">=</span><span class="s">Manual.pdf</span>
<span class="py">Game1Name</span><span class="p">=</span><span class="s">Game</span>
<span class="py">Game1Prog</span><span class="p">=</span><span class="s">other</span>
<span class="py">Game1Path</span><span class="p">=</span><span class="se">\
</span><span class="s">Game1Exe=cmd.bat</span>
<span class="py">Game1Cmd</span><span class="p">=</span>
</code></pre></div></div>
<p>Now run the game - it will start <code class="language-plaintext highlighter-rouge">SierraLauncher.exe</code>, but then you click <em>Launch</em>, it will open <em>wineconsole</em> (<code class="language-plaintext highlighter-rouge">cmd.exe</code>) window instead.</p>
<p><strong>Note:</strong> Optionally you can create a <code class="language-plaintext highlighter-rouge">cmd_SierraLauncher.ini</code> file and make <code class="language-plaintext highlighter-rouge">SierraLauncher.ini</code> the symlink to it. This way you can switch between two <code class="language-plaintext highlighter-rouge">.ini</code> versions without copying files.</p>
<h2 id="install-unofficial-arcanum-patch">Install Unofficial Arcanum Patch</h2>
<p>Get latest and the greatest <a href="http://terra-arcanum.com/drog/uap.html">Unofficial Arcanum patch</a>.</p>
<p>Copy <em>UAP</em> installer to the Arcanum folder.</p>
<p>Run <em>wineconsole</em>, type some commands:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>C:
cd Arcanum
UAP1.5.1.exe
</code></pre></div></div>
<p><img src="/assets/images/arcanum-uap.png" alt="Arcanum: Unofficial patch installer" class="img-fluid" /></p>
<p>Choose things to install - it’s about your preference, but surely <em>HighRes</em> patch is greatly recommended.</p>
<p>About level cap remover - I think it’s more fun to just start again with different kind of character.</p>
<p>Proceed. Select proper install location carefully:</p>
<p><img src="/assets/images/arcanum-uap-install-path.png" alt="Arcanum: Unofficial patch install path" class="img-fluid" /></p>
<p>Done.</p>
<h2 id="apply-highres-patch">Apply HighRes patch</h2>
<p>Then you install <em>Unofficial patch</em>, the <em>HighRes</em> patch will be installed into <code class="language-plaintext highlighter-rouge">Arcanum/HighRes</code> directory, but not applied, as it will require some additional configuration. Let’s do it.</p>
<p>Open <em>HighRes</em> <code class="language-plaintext highlighter-rouge">config.ini</code> and modify it as you like:</p>
<div class="language-ini highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="py">Width</span> <span class="p">=</span> <span class="s">1920 // original: 800</span>
<span class="py">Height</span> <span class="p">=</span> <span class="s">1080 // original: 600</span>
<span class="py">DialogFont</span> <span class="p">=</span> <span class="s">2 // 0 = size 12, 1 = size 14, 2 = size 18</span>
</code></pre></div></div>
<p>Save changes.</p>
<p>Install patch. Open <em>wineconsole</em> again, type:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>C:
cd Arcanum\Arcanum\HighRes
_install.bat
exit
</code></pre></div></div>
<p><img src="/assets/images/arcanum-highres-applied.png" alt="Arcanum: HighRes patch applied" class="img-fluid" /></p>
<p>Done.</p>
<h2 id="play">Play</h2>
<p>If you started <em>wineconsole</em> from SierraLauncher, it’s time to restore the <code class="language-plaintext highlighter-rouge">SierraLauncher.ini</code> to its original state.</p>
<p>Now <strong>run Arcanum from your Steam library</strong> and have fun with such a great game!</p>
<p><img src="/assets/images/arcanum-in-game.png" alt="Arcanum: In game" class="img-fluid" /></p>
<p>For the first-timers I’d recommend to start with the <a href="http://terra-arcanum.com/downloads/arcanum/resources/arcanum_manual.zip">official manual</a> or the <a href="https://gamefaqs.gamespot.com/pc/914155-arcanum-of-steamworks-and-magick-obscura/faqs/64280">Spoiler-Free Character Creation Guide and Orientation (pre-UAP)</a>.</p>
<p>Please share your favorite resources for beginners in the comments!</p>
<h2 id="troubleshooting">Troubleshooting</h2>
<p>Unfortunately, you can experience graphics glitches (like one on the screenshot).</p>
<p><img src="/assets/images/arcanum-graphics-glitch-small.png" alt="Arcanum: Graphics glitch" class="img-fluid" /></p>
<p>The most simple way to fix it is to switch to the software rendering via <em>HighRes</em> <code class="language-plaintext highlighter-rouge">config.ini</code>:</p>
<div class="language-ini highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="py">Renderer</span> <span class="p">=</span> <span class="s">0 // 0 = software, 1 = hardware</span>
</code></pre></div></div>
<p>Repeat <em>HighRes</em> patch setup, but run <code class="language-plaintext highlighter-rouge">_uninstall.bat</code> first.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>C:
cd Arcanum\Arcanum\HighRes
_uninstall.bat
_install.bat
exit
</code></pre></div></div>
<h2 id="additional-tweaks">Additional tweaks</h2>
<p>Before switching to software renderer, you could also explore other possibilities by tweaking some options via <em>HighRes</em> <code class="language-plaintext highlighter-rouge">config.ini</code>, <a href="https://wiki.winehq.org/Useful_Registry_Keys">Wine</a> and/or <a href="https://github.com/ValveSoftware/Proton#runtime-config-options">Proton</a>. Feel free to share your glitches and the setup options which worked (not worked) for you in the comments.</p>
<h3 id="setting-arcanumexe-options-via-sierralauncherini">Setting Arcanum.exe options via SierraLauncher.ini</h3>
<p>This is an (almost) obsolete way to do it, as the <em>HighRes</em> patch allows you to set many options via <code class="language-plaintext highlighter-rouge">config.ini</code>. But still, let’s set <code class="language-plaintext highlighter-rouge">-doublebuffer</code> option:</p>
<div class="language-ini highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nn">[Launcher]</span>
<span class="py">Name</span><span class="p">=</span><span class="s">Arcanum</span>
<span class="py">NumButtons</span><span class="p">=</span><span class="s">1</span>
<span class="py">GameManual</span><span class="p">=</span><span class="s">Manual.pdf</span>
<span class="py">Game1Name</span><span class="p">=</span><span class="s">Game</span>
<span class="py">Game1Prog</span><span class="p">=</span><span class="s">other</span>
<span class="py">Game1Path</span><span class="p">=</span><span class="s">Arcanum</span><span class="se">\
</span><span class="s">Game1Exe=Arcanum.exe</span>
<span class="py">Game1Cmd</span><span class="p">=</span><span class="s">-doublebuffer</span>
</code></pre></div></div>
<p>See more <a href="https://terra-arcanum.com/forums/index.php?threads/arcanum-command-line-arguments.15208/">here</a>.</p>
<h3 id="setting-wine-options-via-regedit">Setting Wine options via regedit</h3>
<ol>
<li>Run <em>wineconsole</em>.</li>
<li>Type <code class="language-plaintext highlighter-rouge">regedit</code>.</li>
<li>Go to <code class="language-plaintext highlighter-rouge">HKEY_CURRENT_USER\Software\Wine\Direct3D</code> (if key not exists, create it).</li>
</ol>
<p>Here you can set number of <em>Wine</em> options, like:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>"DirectDrawRenderer"="gdi"
"OffscreenRenderingMode"="backbuffer"
</code></pre></div></div>
<p>See more <a href="https://wiki.winehq.org/Useful_Registry_Keys">here</a>.</p>
<h3 id="emulate-virtual-desktop">Emulate virtual desktop</h3>
<ol>
<li>Run <em>wineconsole</em>.</li>
<li>Type <code class="language-plaintext highlighter-rouge">winecfg</code>.</li>
<li>Go to <em>Graphics</em> tab.</li>
<li>Check <em>Emulate virtual desktop</em> option.</li>
<li>Set required values for screen width and height.</li>
<li>Ensure that same width and height values is set and also fullscreen is enabled in the <em>HighRes</em> <code class="language-plaintext highlighter-rouge">config.ini</code>.</li>
</ol>
<h2 id="finally-some-links">Finally, some links:</h2>
<ul>
<li><a href="http://terra-arcanum.com/drog/uap.html">Unofficial Arcanum patch</a></li>
<li><a href="https://www.protondb.com/app/500810">Arcanum entry in ProtonDB</a></li>
<li><a href="http://terra-arcanum.com">Terra Arcanum</a></li>
<li><a href="http://terra-arcanum.com/downloads/arcanum/resources/arcanum_manual.zip">Official Manual</a></li>
<li><a href="https://gamefaqs.gamespot.com/pc/914155-arcanum-of-steamworks-and-magick-obscura/faqs/64280">Spoiler-Free Character Creation Guide and Orientation (pre-UAP)</a></li>
<li><a href="https://github.com/ValveSoftware/Proton#runtime-config-options">Proton runtime config options</a></li>
<li><a href="https://wiki.winehq.org/Useful_Registry_Keys">Wine useful registry keys</a></li>
<li><a href="https://github.com/ValveSoftware/Proton">Proton code repository on GitHub</a></li>
<li><a href="https://www.protondb.com/explore?page=0&selectedFilters=whitelisted">“whitelisted” ProtonDB games</a></li>
<li><a href="https://terra-arcanum.com/forums/index.php?threads/arcanum-command-line-arguments.15208/">Arcanum.exe commandline arguments</a></li>
</ul>
<!-- Reference Links -->
Синхронизация GitHub с хранилищем Redmine2019-10-21T00:00:00+00:00http://roman-yagodin.github.io/how-to/2019/10/21/ru-sync-github-repository-with-redmine
<p>Описывается процесс настройки синхронизации репозитория исходного кода на GitHub с хранилищем в проекте Redmine с использованием плагина <a href="http://www.redmine.org/plugins/redmine_github_hook">Redmine GitHub Hook</a> на примере <a href="http://projects.volgau.com/projects/greenmine/repository">репозитория темы Greenmine</a>.</p>
<!-- more -->
<hr />
<h2 id="создание-зеркала">Создание зеркала</h2>
<p>Создаем зеркало публичного репозитория GitHub:</p>
<pre><code class="language-Shell">sudo -u redmine /bin/bash
cd /var/opt/redmine/repos
git clone --mirror https://github.com/volgau/redmine-theme-greenmine.git
</code></pre>
<p>Добавляем в проект новое хранилище, связанное с зеркалом репозитория, через меню <strong>Настройки проекта > Хранилища</strong>.</p>
<p><img src="/assets/images/ru-sync-github-repository-with-redmine-1.png" alt="Создание нового хранилища в Redmine" class="img-fluid" /></p>
<h2 id="настройка-синхронизации">Настройка синхронизации</h2>
<p>В настройках проекта на GitHub (меню <strong>Settings > Webhooks</strong>) добавляем новый webhook.</p>
<p><strong>Внимание!</strong> Параметр <strong>project_id</strong> в <strong>Payload URL</strong> устанавливаем равным идентификатору проекта, а не хранилища!</p>
<p>Если в проекте несколько хранилищ, то добавляем к URL параметр <strong>repository_id</strong>. Возможные форматы URL см. в <a href="https://github.com/koppen/redmine_github_hook#readme">readme плагина</a></p>
<p><img src="/assets/images/ru-sync-github-repository-with-redmine-2.png" alt="Добавляем webhook в GitHub" class="img-fluid" /></p>
<p>Если все настроено правильно, то все изменения состояния кода в удаленном репозитории на GitHub будут автоматически отражаться в локальном зеркале, а коммиты будет добавлены в <a href="http://projects.volgau.com/projects/greenmine/activity?from=2018-01-30">историю действий</a>.</p>
<p>Если что-то пошло не так (статус отправки изменений можно посмотреть в разделе <strong>Recent Deliveries</strong>), то лучше всего выполнить настройку сначала - проверить настройки на стороне Redmine, удалить и заново добавить webhook на GitHub.</p>
GTD with Simpletask2019-10-21T00:00:00+00:00http://roman-yagodin.github.io/guide/2019/10/21/gtd-with-simpletask
<p>This is a TL;DR guide of <em>Getting Things Done (GTD)</em> implementation using <a href="https://play.google.com/store/apps/details?id=nl.mpcjanssen.todotxtholo">Simpletask</a> app by <a href="http://mpcjanssen.nl/">Mark Janssen</a> as a core component of trusted system, heavily based on <a href="https://gist.github.com/alehandrof/9941620">Alex Armstrong’s work</a> including my thoughts and personal experience about it over past couple of years. The content is restructured to center on GTD-related things. Consider it incomplete and very eccentric.</p>
<!-- more -->
<blockquote>
<p><em>Simpletask</em> uses the <a href="http://todotxt.com/">todo.txt</a> syntax, but has sufficient differences and quirks of its own to be worth describing in detail – at least, that’s the story I’m going with. I actually began this guide as an exploration of my own trusted system. <em>Personal workflows are by definition eccentric</em>; I have included only what seems to me to be broadly useful.</p>
<p>This implementation of GTD covers the “standard” classifications: next actions by context, projects, somedays, agendas by person and meeting, etc. In a departure from strict GTD, each entry in these lists is also tagged with an area of focus, interest or responsibility. I find that the ability to slice the system by this extra dimension is worth the additional complexity at the processing and organizing stages. Limitations, issues and workarounds are discussed at the end.</p>
<p>– Alex Armstrong, the author of original guide.</p>
</blockquote>
<blockquote>
<p>Your system has to be easy enough (and complete enough) that you will be motivated to work it even when you have the flu. The system is only as good as what you’re willing to maintain when you don’t feel like it.</p>
<p>– David Allen, “<a href="http://www.davidco.com/newsletters/archive/0810b.html">Let the Lists Fall Where They May</a>”</p>
</blockquote>
<hr />
<h2 id="entries">Entries</h2>
<p>I refer to every line in your <code class="language-plaintext highlighter-rouge">todo.txt</code> as an “entry” to differentiate them from tasks. Simpletask takes a broader view of what constitutes a <code class="language-plaintext highlighter-rouge">todo.txt</code> file.
In <em>this</em> implementation the <code class="language-plaintext highlighter-rouge">todo.txt</code> format provides a large chunk of your trusted system.</p>
<p>Entries may belong to one list (<code class="language-plaintext highlighter-rouge">@something</code>) and they may have one or more tags (<code class="language-plaintext highlighter-rouge">+something</code>) assigned to them. They may also utilize due dates (<code class="language-plaintext highlighter-rouge">due:2014-04-2</code>), thresholds (<code class="language-plaintext highlighter-rouge">t:2014-04-3</code>), recurrance (<code class="language-plaintext highlighter-rouge">rec:1w</code>) and priorities (<code class="language-plaintext highlighter-rouge">(A)</code>, …, <code class="language-plaintext highlighter-rouge">(Z)</code>).</p>
<h2 id="lists-">Lists (<code class="language-plaintext highlighter-rouge">@</code>)</h2>
<p>Simpletasks collects all <code class="language-plaintext highlighter-rouge">@somethings</code> in your entries and calls them <em>lists</em>.</p>
<p>Lists hold all entries on the first four <em>Horizons of Focus</em>: from <em>Runway</em> to <em>30,000 feet</em>, or <em>Next Actions</em> to <em>Goals & Objectives</em>. If you find this format appropriate, you could feasibly include items from the remaining two altitudes: <em>Vision</em>, <em>Purpose</em> and <em>Principles</em>.</p>
<p><strong>Lists are mutually exclusive!</strong> If an entry can be placed in more than one list, you need to clarify either the entry or your lists.</p>
<h2 id="tags-">Tags (<code class="language-plaintext highlighter-rouge">+</code>)</h2>
<p>Simpletasks collects all <code class="language-plaintext highlighter-rouge">+somethings</code> in your entries and calls them <em>tags</em>.</p>
<p>Tags specify <em>areas of focus, interest or responsibility</em>, as well as <em>agendas for people or meetings</em>.</p>
<h2 id="inbox-capturecollect">Inbox (Capture/Collect)</h2>
<p>The inbox consists of <em>all entries that have not been assigned to a list</em>. They are typically not tagged, either. Although I will often revise entries before tagging and assigning them to another list, I generally preserve the original creation date.</p>
<p><strong>You don’t need a list called <code class="language-plaintext highlighter-rouge">@Inbox</code>!</strong> First of all, it will just slow you down at the collection phase. If you want to view just your <em>Inbox</em>, filter by <code class="language-plaintext highlighter-rouge">-</code> in the left drawer.</p>
<h2 id="next-actions--contexts-runway">Next Actions / Contexts (Runway)</h2>
<p><em>Next actions</em> are filed in lists that begin with an <em>at-sign</em> (<code class="language-plaintext highlighter-rouge">@</code>), one for each context. The <em>at-sign</em> is an established shorthand that reinforces the idea that the context (place or tool) is required for the action to be performed. More importantly, the <em>at-sign</em> makes these lists sort above the others, so you can find them more quickly.</p>
<p>The examples of GTD contexts are:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>@@agendas
@@anywhere
@@calls
@@computer / @@laptop
@@errands
@@home
@@office / @@work
</code></pre></div></div>
<p><strong>Уou may (and must) define your own contexts!</strong> By example, I like to have context <code class="language-plaintext highlighter-rouge">@@buy</code> - for any optional triffles I’d want to buy during accidental shopping; and also context <code class="language-plaintext highlighter-rouge">@@ingame</code> - it’s just like <code class="language-plaintext highlighter-rouge">@@computer</code>, but when you use it for fun.</p>
<p>Next actions are tagged with an area tag and, for entries relating to communication, an agenda tag (either a person or meeting).</p>
<h3 id="agendas">Agendas</h3>
<p>Agendas may be listed under <code class="language-plaintext highlighter-rouge">@@agendas</code> (for face-to-face and impromptu communications) or required context (e.g. <code class="language-plaintext highlighter-rouge">@@calls</code>, <code class="language-plaintext highlighter-rouge">@@computer</code>, etc.) but <em>not</em> both.</p>
<p>All tags that begin with a capital letter refer to agendas – that is, to people or meetings.</p>
<p>Example tags:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>+Mom
+JSmith
+StaffMeeting
</code></pre></div></div>
<p>Place agenda entries in the appropriate context list and then tag them with an area.</p>
<p>Example entries:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Tell +Bob about the party @@agendas +fun
Email +DevTeam re: new client @@online +work
</code></pre></div></div>
<p>People and meetings you refer to often can be added to a hidden entry (see below) for easy access.</p>
<h2 id="projects-10000-ft">Projects (10,000 ft)</h2>
<p>A list called <code class="language-plaintext highlighter-rouge">@Projects</code> with an entry for <strong>every multi-step outcome you are committed to completing within the next year</strong>. Each project entry is tagged with an area and, if applicable, an agenda.</p>
<p>For code-related project you could think of each milestone as of GTD project.</p>
<p>Examples:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Clean out the garage +household @Projects
Release R7.Documents module v1.11 +work @Projects
</code></pre></div></div>
<h2 id="somedaymaybe-incubate-runway10000-ft">Someday/Maybe (Incubate Runway/10,000 ft)</h2>
<p>A list called <code class="language-plaintext highlighter-rouge">@Someday</code> with an entry for every project (multi-step outcome) or single action you are incubating – i.e., that would like to periodically review but are not committed to moving on, yet. Each someday entry is tagged with an area and, if applicable, an agenda, allowing you to view potential commitments along with your current ones.</p>
<p>Example: <code class="language-plaintext highlighter-rouge">Learn to play the piano +creativity @Someday</code></p>
<p>You could feasibly have multiple Someday/Maybe lists like <code class="language-plaintext highlighter-rouge">@Someday-Soon</code> or even <code class="language-plaintext highlighter-rouge">@Someday-Never</code>, if you need the additional granularity.</p>
<p>Use the <code class="language-plaintext highlighter-rouge">@Someday-Never</code> to RIP things that you strongly doesn’t want and have strong reasons to not to do, but still need to remember sometimes.</p>
<h2 id="tickler-incubate-runway10000-ft">Tickler (Incubate Runway/10,000 ft)</h2>
<p>A list called <code class="language-plaintext highlighter-rouge">@Tickler</code> contains <strong>all tickled items which are not actions</strong>. Tickled items are all entries with a threshold date.</p>
<p>Tickled actions are not included in this list; they are placed under the appropriate context.</p>
<h2 id="waiting-for-runway">Waiting For (Runway)</h2>
<p>A list called <code class="language-plaintext highlighter-rouge">@WaitingFor</code> with an entry for each delegated action, tagged with both area and agenda.</p>
<p>Example: <code class="language-plaintext highlighter-rouge">+JSmith re: conference +consortium @WaitingFor</code></p>
<h2 id="areas-20000-ft">Areas (20,000 ft)</h2>
<p>A list called <code class="language-plaintext highlighter-rouge">@\_Areas</code> with entries identifying all your areas of focus, interest or responsibility. There is overlap between this horizon and the area tags (described below), but a 1-to-1 correspondence is not obligatory. How you set up this horizon depends on how you think about your life and how it makes sense to carve up your commitments.</p>
<p>Note: the underscore in front of this list is merely to have it sort to the bottom of your lists.</p>
<p>All lowercase tags refer to areas of focus, interest or responsibility. These generally relate to the <em>20,000 feet horizon</em>, but will probably be more granular. There’s no rule here; you will need as many areas as you need.</p>
<p>A word of warning, however: <strong>avoid making area tags too specific</strong> (so that they basically map to your projects). Most area tags will be somewhere between projects and areas (or approximately <em>25,000 feet</em>)</p>
<p>Examples:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>+gtd
+blog
+health
+household
</code></pre></div></div>
<p>Example entries:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Family +family @_Areas
Health, Vitality & Well-Being +health @_Areas
Profession, Self-improvement +profession +gtd @_Areas
Finances +finances @_Areas
Household +household @_Areas
Hobbies +blog +painting +rpg @_Areas
</code></pre></div></div>
<p>To make sure that these are always available, define them in your <code class="language-plaintext highlighter-rouge">@_Areas</code> entries or add them to a hidden entry (see below).</p>
<h2 id="goals--objectives-30000-ft">Goals & Objectives (30,000 ft)</h2>
<p>A list called <code class="language-plaintext highlighter-rouge">@\_Goals</code> with an entry for <strong>every outcome you are committed to completing within the next 2-5 years</strong>, tagged with an area and, if applicable, an agenda. Goals are treated basically as long-term projects.</p>
<p>Example: <code class="language-plaintext highlighter-rouge">Attain some promotion +career @\_Goals</code></p>
<hr />
<h2 id="other-features">Other Features</h2>
<h3 id="the-left-drawer">The Left Drawer</h3>
<p>The left drawer allows you to view your system by any combination of horizon, area and agenda. This is a rough sketch of how your left drawer should look:</p>
<ul>
<li>Lists
<ul>
<li>Inbox</li>
<li>Contexts</li>
<li>Higher Altitudes</li>
</ul>
</li>
<li>Tags
<ul>
<li>Agendas</li>
<li>Areas</li>
</ul>
</li>
</ul>
<p>The most frequently used ways to slice your system – contexts and areas – are the quickest to reach, being at at the top and bottom, respectively. Less used stuff – higher altitudes, agendas – is in the middle.</p>
<p>You can choose multiple lists and tags to slice your trusted system in various ways. For example, you can see all the <code class="language-plaintext highlighter-rouge">@@calls</code> you have to make for <code class="language-plaintext highlighter-rouge">+work</code>, the <code class="language-plaintext highlighter-rouge">@Projects</code> relating to your <code class="language-plaintext highlighter-rouge">+family</code> or all the <code class="language-plaintext highlighter-rouge">+fun</code> things you might do <code class="language-plaintext highlighter-rouge">@Someday</code>.</p>
<h3 id="hidden-entries">Hidden Entries</h3>
<p>These can serve as placeholders to preserve your lists and tags when they do not contain any items.</p>
<p>Examples:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>h:1 Contexts: @@agendas, @@anywhere, @@calls, @@computer, @@errands, @@home, @@office
h:1 Other Lists: @Projects, @Someday, @Tickler, @WaitingFor, @_Areas, @_Goals
h:1 Contacts: +Mom, +JSmith, etc.
</code></pre></div></div>
<p>Hidden entries can also be used to store some private entries which you wouldn’t like to be shown on your phone screen in public accidentally –
while it’s possibly better to have separate todo file for that.</p>
<h3 id="due-dates">Due Dates</h3>
<p>Per GTD, I only use due dates for the “hard landscape”, such as appointments, rather than estimations of when I’d like to do something. I also add them to projects to indicate deadlines (after which completion becomes moot).</p>
<p>For time-sensitive actions you could use prefix times like so: <code class="language-plaintext highlighter-rouge">[10:15] Taskname</code>. Or suffix times so: <code class="language-plaintext highlighter-rouge">due:2019-06-20 T10:15</code> - this looks almost like an <a href="https://www.w3.org/TR/NOTE-datetime">ISO datetime</a> (<code class="language-plaintext highlighter-rouge">2019-06-20T10:15</code>).</p>
<p>That said, I find Simpletask’s calendar integration to be really clunky, and I have begun adding items straight to the calendar, which I find problematic.</p>
<h3 id="threshold-dates">Threshold Dates</h3>
<p>Threshold dates allow you to incubate actions or reminders (tickled entries). Tickled actions are filed under the appropriate context. For reminders, you can use the <code class="language-plaintext highlighter-rouge">@Tickler</code> list.</p>
<h3 id="recurrence-dates">Recurrence Dates</h3>
<p>TBD.</p>
<h3 id="priorities">Priorities</h3>
<p>GTD does not (and should not) have a priority system. But I found useful to utilize the <code class="language-plaintext highlighter-rouge">todo.txt</code> priority syntax to help me filter several kinds of entries.</p>
<p>Entries with <code class="language-plaintext highlighter-rouge">(D)</code> priority are just general GT<u>D</u> hints that I like to keep above other entries in the context list.</p>
<p>Entries with <code class="language-plaintext highlighter-rouge">(C)</code> priority are generally recurring actions with due dates. I use them for things that need to be kept under periodic <u>c</u>ontrol.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>(D) Check current context lists
(D) Plan to complete within the next year @Projects
...
(C) Do weekly review rec:+1w due:2020-10-19
</code></pre></div></div>
<p>This leaves <code class="language-plaintext highlighter-rouge">(A)</code> and <code class="language-plaintext highlighter-rouge">(B)</code> priorities reserved for some “hot” actions that I plan (not would <em>like</em>) to do today or very soon.</p>
<p><strong>Projects and higher altitudes never have priorities.</strong></p>
<h2 id="saved-filters-the-right-drawer">Saved Filters (The Right Drawer)</h2>
<p>Saved filters allow you to bring up or review aspects of your GTD system. The ones I’ve found most useful are:</p>
<h3 id="common">Common</h3>
<p>Hide completed tasks and tasks with threshold date in future.</p>
<h3 id="starts-or-ends-withing-a-week">Starts or ends withing a week</h3>
<p>Shows any actions with due or treshold dates within 1 week in future from today.
This utilizes Simpletask Lua scripting.</p>
<script src="https://gist.github.com/roman-yagodin/4d6b3c8be8aac3a1de2c023da827560d.js"></script>
<h3 id="review">Review</h3>
<ul>
<li>Show all tasks (including complete and tasks with threshold in the future).</li>
<li>Sort with Completed on top - to avoid scrolling:</li>
</ul>
<p>Base state:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>x Completed entry 1
Entry 2
Entry 3
...
Entry 199
</code></pre></div></div>
<p>Completing entry 2 on review:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>x Completed entry 2
x Completed entry 1
Entry 3
...
Entry 199
</code></pre></div></div>
<h3 id="others">Others</h3>
<p>Work+Computer, Calendared, Completed, Groceries/ToBuy, Inbox</p>
<hr />
<h2 id="important-components-of-gtd-system">Important Components of GTD System</h2>
<h3 id="notes">Notes</h3>
<p>There are times when I clear my Inbox and some entries which do not require any actions, but looks like general information,
while still important (for some project or area) - I just move them to the <code class="language-plaintext highlighter-rouge">@Notes</code> list.</p>
<p>When reviewing my <code class="language-plaintext highlighter-rouge">@Notes</code> list, I could decide do I need to delete it or move to the note-taking application.
Currently I prefer <a href="https://simplenote.com/">Simplenote</a> for that - very nice addition to my trusted system.</p>
<h3 id="issue-trackers">Issue Trackers</h3>
<p>Then working on code project, I like to treat the project bugtracker as a public context list for the project,
still having an entry for it (or better - for a single milestone of it) in the <code class="language-plaintext highlighter-rouge">@Projects</code> list.</p>
<p>During review, I move entries which should go to the bugtracker, to the <code class="language-plaintext highlighter-rouge">@@bugtracker</code> list.
And during review of <code class="language-plaintext highlighter-rouge">@@bugtracker</code> list, I just create issues and remove entries from Simpletask,
effectively “forgeting” about them. But I will certainly will remember them again – then and where I resume work on the project.</p>
<table>
<thead>
<tr>
<th>Issue tracker term</th>
<th>GTD term</th>
</tr>
</thead>
<tbody>
<tr>
<td>new issues</td>
<td>inbox</td>
</tr>
<tr>
<td>backlog</td>
<td>someday/maybe list</td>
</tr>
<tr>
<td>repository (project)</td>
<td>context</td>
</tr>
<tr>
<td>commit</td>
<td>action</td>
</tr>
<tr>
<td>issue</td>
<td>project</td>
</tr>
<tr>
<td>milestone</td>
<td>project</td>
</tr>
</tbody>
</table>
<h3 id="email">Email</h3>
<p><a href="http://roman-yagodin.github.io/how-to/2019/06/21/blue-star-email-parsing-essay">“Blue star” email parsing essay</a> - Мanage your email inbox with 1 & ½ simple tricks.</p>
<hr />
<h2 id="tips--tricks">Tips & Tricks</h2>
<ul>
<li>Simpletask provides an option to automatically generate a creation date for new tasks. Use it.</li>
<li>You could make copy of entry (or entries) by sharing it. Press “Share” button and then select Simpletask as a target app.
This will produce a copy of entry with the <code class="language-plaintext highlighter-rouge">+background</code> tag.</li>
</ul>
<h2 id="issues--problems">Issues & Problems</h2>
<p>The following are known issues with the GTD implementation in this guide.</p>
<ul>
<li>
<p><strong>Inbox</strong>. I enter data straight into the <code class="language-plaintext highlighter-rouge">todo.txt</code> with Simpletask or a text editor. I haven’t experimented with using emails or other input, which is why I don’t discuss this at all. There are some <a href="https://ifttt.com/search/query/todo">ifttt recipes</a>, but I haven’t tried any of them.</p>
</li>
<li>
<p><strong>Calendar</strong>. You do not need a calendar with this system – at least insofar as your GTD system is concerned. Integration with an online calendar would be useful, but that is a feature that would need to be provided by Simpletask, or via something that can read the text file and populate the calendar.</p>
</li>
<li>
<p><strong>Reference System</strong>. This is outside the scope of a list maker such as Simpletask.</p>
</li>
<li>
<p><strong>Project Support</strong>. A subset of the Reference System that is related your active actions, projects, etc. There is no inherent</p>
</li>
</ul>
<p>I include these as “notes” (see above). For example: <code class="language-plaintext highlighter-rouge">2014-01-07 Complete Something or Other // Files in Dropbox > Projects > SomethingOrOther</code>.</p>
<ul>
<li>
<p><strong>Tickler</strong>. The tickler system does not work all that well when you try and making it into a list. I have yet to see a virtual solution to the tickler system that work reasonably well.</p>
</li>
<li>
<p><strong>Read/Review</strong>.</p>
<ul>
<li>
<p>“Must read” items go into the main system at the appropriate context – since I am committed to reading or reviewing them. This works very well for items that you can keep on your mobile device.</p>
<p>Example: <code class="language-plaintext highlighter-rouge">Read email from bank @@anywhere +finances</code>.</p>
</li>
<li>
<p>“Nice to read” things do not go into the main system. You might want to add some of these to your classify <code class="language-plaintext highlighter-rouge">@Someday</code> list, if you would like to review them weekly.</p>
</li>
</ul>
</li>
</ul>
<p>Since I don’t care much if anything falls through the cracks, they are housed in various systems: books and movies are in text files (in a custom format, but I might convert these to the <code class="language-plaintext highlighter-rouge">todo.txt</code> format as well), online articles are in a read-it-later service, etc.</p>
<ul>
<li>
<p><strong>Performance</strong>. Simpletask becomes quite slow if you are viewing many entries at once (over 200 on my phone). You might want to experiment with breaking off the <code class="language-plaintext highlighter-rouge">@Someday/Maybe</code> entries into their own todo file.</p>
<p>That said, my <code class="language-plaintext highlighter-rouge">todo.txt</code> is over 400 lines and, while not snappy, is still usable.</p>
</li>
</ul>
<h2 id="software">Software</h2>
<ul>
<li><a href="https://play.google.com/store/apps/developer?id=Mark+Janssen">Various Simpletask flavours</a></li>
<li><a href="https://simplenote.com">Simplenote</a></li>
</ul>
<h2 id="gtd-russian-glossary-wip">GTD Russian Glossary (WIP)</h2>
<table>
<thead>
<tr>
<th>GTD term</th>
<th>in Russian</th>
</tr>
</thead>
<tbody>
<tr>
<td>inbox</td>
<td>входящие</td>
</tr>
<tr>
<td>someday/maybe</td>
<td>копилка</td>
</tr>
<tr>
<td>waiting for</td>
<td>ждем</td>
</tr>
</tbody>
</table>
<!-- Reference Links -->
"Blue star" email parsing essay2019-06-21T00:00:00+00:00http://roman-yagodin.github.io/how-to/2019/06/21/blue-star-email-parsing-essay
<p>Many of us know very well how embarassing could be email routine at work -
it distracts you from the real work, makes you nervous and wasting tons of energy… on hating mail senders.
I hope this short essay will ease your pain, even a little.</p>
<!-- more -->
<p><span class="badge badge-secondary">1</span> Mark incoming mail with the “blue star” (Gmail) to separate from rest of the noise – this is your <em>Real Mail Inbox</em>.
Also this way you could see which mails are “new” (unreviewed) even if they are readed.</p>
<blockquote>
<p>Blue stars won’t bug you – they are not yellow - so won’t meld with rest of mail, and not red - so not very urgent, and not green - so not very relaxing…</p>
</blockquote>
<p><span class="badge badge-secondary">2</span> Now you need to do your work. I mean – do you already have something in your GTD? Even if you don’t do GTD…
This could autoresolve a number of potential issues with mail. Cause all people do errors and I hope that most of your “blue star” mail senders are people.</p>
<blockquote>
<p>But do they really people?.. Still you must give the Universe some time to clean things up…</p>
</blockquote>
<p><span class="badge badge-secondary">3</span> Tired doing work? Return to the mail. Read it, do quick replies, create tracker issues with backlinks to mail or <a href="https://github.com/mpcjanssen/simpletask-android">Simpletask</a> inbox entries – preferably “in bulk” to avoid thinking about a single thing too much. And only after that remove the “blue stars”.</p>
<p><span class="badge badge-secondary">4</span> And now you need to do your work again – which all is in your GTD (or anywhere else), but you can forget about mail for now.</p>
<blockquote>
<p>Just one thing at the time…</p>
</blockquote>
<p><span class="badge badge-secondary">5</span> Tired of work again? A quick trip to the mail!</p>
<blockquote>
<p>Scatter some blue stars!..</p>
</blockquote>
How to build Speed Dreams 2.2 on Linux2016-03-30T00:00:00+00:00http://roman-yagodin.github.io/compile-guide/2016/03/30/build-speed-dreams-linux
<p><a href="http://www.speed-dreams.org/">Speed Dreams</a> is a 3D cross-platform, open source motorsport simulation and racing game, a fork of the open racing car simulator Torcs, aiming to implement exciting new features, cars, tracks and AI opponents. Unfortunately, the <em>Speed Dreams</em> team do not provide binary release for Debian GNU/Linux. In this post I’ll try to give you the recipe on how to get latest <em>Speed Dreams</em> game running on your desktop.</p>
<!-- more -->
<p><img src="/assets/images/build-speed-dreams-linux.png" alt="Speed Dreams 2 starting screen" class="img-fluid" /></p>
<h2 id="step-1-get-source-tarballs">Step 1: Get source tarballs</h2>
<p>First you need to download <em>Speed Dreams</em> source tarballs from the <a href="https://sourceforge.net/projects/speed-dreams/files/2.2.0/">project page</a>.</p>
<p>These are files you will need (version and revision numbers may differ):</p>
<ul>
<li><code class="language-plaintext highlighter-rouge">speed-dreams-src-base-2.2.0-r6381.tar.xz</code> - core components of the game;</li>
<li><code class="language-plaintext highlighter-rouge">speed-dreams-src-hq-cars-and-tracks-2.2.0-r6381.tar.xz</code> - LS-GT1 and 36GP cars and AI drivers, HQ tracks;</li>
<li><code class="language-plaintext highlighter-rouge">speed-dreams-src-more-hq-cars-and-tracks-2.2.0-r6381.tar.xz</code> - TRB1 cars and AI drivers, more HQ tracks, and the Career mode;</li>
<li><code class="language-plaintext highlighter-rouge">speed-dreams-src-wip-cars-and-tracks-2.2.0-r6381.tar.xz</code> - work-in-progress MP5, LS-GT2 and RS cars and AI drivers, and many other tracks;</li>
<li><code class="language-plaintext highlighter-rouge">speed-dreams-src-unmaintained-2.2.0-r6381.tar.xz</code> - unmaintained Simu V2.1 engine and maybe something else, but do you really need this?</li>
</ul>
<p>Unpack <code class="language-plaintext highlighter-rouge">base</code> tarball first, then <code class="language-plaintext highlighter-rouge">hq-cars-and-tracks</code>, then <code class="language-plaintext highlighter-rouge">more-hq-cars-and-tracks</code>, etc. Choose to rewrite files / folders in the case of conflicts.</p>
<h2 id="step-2-install-development-libraries">Step 2: Install development libraries</h2>
<p>Second, install required development libraries. If you on <em>Debian</em> or <em>Ubuntu</em>, use following command:</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="nb">sudo </span>apt-get <span class="nb">install </span>build-essential <span class="se">\</span>
cmake <span class="se">\</span>
libplib-dev <span class="se">\</span>
alsoft-conf <span class="se">\</span>
libogg-dev <span class="se">\</span>
libenet-dev <span class="se">\</span>
libexpat1-dev <span class="se">\</span>
libpng12-dev <span class="se">\</span>
libjpeg8-dev <span class="se">\</span>
libplib-dev <span class="se">\</span>
libopenscenegraph-dev <span class="se">\</span>
libsdl2-dev</code></pre></figure>
<p>For other GNU/Linux distributions, consult with <em>Pre-requisites</em> section of <code class="language-plaintext highlighter-rouge">INSTALL.txt</code> file in the source folder.</p>
<p>Note that the <em>OpenSceneGraph</em> and <em>SDL 2</em> dependencies were introduced in the <em>Speed Dreams</em> 2.2.0. You don’t need them for 2.1.0 version.</p>
<h2 id="step-3-configure--build">Step 3: Configure & build</h2>
<p>Third step - create <code class="language-plaintext highlighter-rouge">build</code> subfolder <strong>inside</strong> the source folder, where you have extracted source tarballs. From this folder you need to invoke <code class="language-plaintext highlighter-rouge">cmake</code> with some options (see below).</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="nb">mkdir </span>build
<span class="nb">cd </span>build
cmake <span class="nt">-D</span> OPTION_OFFICIAL_ONLY:BOOL<span class="o">=</span>ON <span class="nt">-D</span> <span class="nv">PLIB_INCLUDE_DIR</span><span class="o">=</span><span class="s2">"/usr/include/plib"</span> ..</code></pre></figure>
<p>This will configure source, and if something required is missing you will see an error message. This generally means that you should install some missing dependencies (additional development libraries). In case of other problems, it’s time to read the manual - see <code class="language-plaintext highlighter-rouge">INSTALL.txt</code> file in the source folder.</p>
<p>If <code class="language-plaintext highlighter-rouge">cmake</code> finish without errors, it’s time to perform build and install:</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash">make
<span class="nb">sudo </span>make <span class="nb">install</span></code></pre></figure>
<p>This will install main executable to the <code class="language-plaintext highlighter-rouge">/usr/local/games/speed-dreams-2</code> and data files to the <code class="language-plaintext highlighter-rouge">/usr/local/share/games/speed-dreams-2</code>, so the game will be available system-wide.</p>
<h2 id="step-4-create-game-shortcut">Step 4: Create game shortcut</h2>
<p>Note that <em>Speed Dreams</em> install won’t create a shortcut (<em>FreeDesktop.org</em> <code class="language-plaintext highlighter-rouge">.desktop</code> file) anywhere. So now it’s your move to create one!</p>
<p>You generally would like to add shortcut with an icon. The source does not provide us with one, so let’s search over the Internet. I’ve got one from <a href="https://commons.wikimedia.org/wiki/File:Speed_Dreams_Icon.svg">Wikipedia</a>.</p>
<p>When you got the icon, copy it to <code class="language-plaintext highlighter-rouge">/usr/share/pixmaps/speed-dreams.svg</code>. Then create <code class="language-plaintext highlighter-rouge">speed-dreams-2.desktop</code> text file (see content below), copy it to <code class="language-plaintext highlighter-rouge">/usr/local/share/applications</code> folder and set executable flag (may or may not be required). These operations should require root access.</p>
<figure class="highlight"><pre><code class="language-ini" data-lang="ini"><span class="nn">[Desktop Entry]</span>
<span class="py">Encoding</span><span class="p">=</span><span class="s">UTF-8</span>
<span class="py">Version</span><span class="p">=</span><span class="s">1.0</span>
<span class="py">Type</span><span class="p">=</span><span class="s">Application</span>
<span class="py">Icon</span><span class="p">=</span><span class="s">speed-dreams</span>
<span class="py">Name</span><span class="p">=</span><span class="s">Speed Dreams</span>
<span class="py">Exec</span><span class="p">=</span><span class="s">speed-dreams-2</span>
<span class="py">Comment</span><span class="p">=</span><span class="s">Speed Dreams: an Open Motorsport Sim</span>
<span class="py">Categories</span><span class="p">=</span><span class="s">Game;SportsGame;Simulation</span></code></pre></figure>
<p>Now you should see <em>Speed Dreams</em> shortcut in the main menu of your desktop.</p>
<h2 id="step-5-enjoy-the-game">Step 5: Enjoy the game!</h2>
<p>It’s all about it, you know…</p>
<h2 id="upgrade-to-new-version">Upgrade to new version</h2>
<p>In order to safely upgrade your <em>Speed Dreams</em> installation to new version, you should uninstall old one first.</p>
<p>To do so, go to the <code class="language-plaintext highlighter-rouge">build</code> subfolder you’ve created inside the source folder, and invoke <code class="language-plaintext highlighter-rouge">sudo make uninstall</code>.
Then you can safely clear source folder, get & unpack source packages, configure and build.</p>
<h2 id="links">Links</h2>
<ul>
<li><a href="http://www.speed-dreams.org/">Speed Dreams official website</a></li>
<li><a href="https://sourceforge.net/projects/speed-dreams/">Speed Dreams project on SourceForge</a></li>
<li><a href="https://en.wikipedia.org/wiki/Speed_Dreams">Speed Dreams Wikipedia article</a></li>
<li><a href="http://www.playdeb.net/software/Speed%20Dreams">Speed Dreams on PlayDeb</a></li>
<li><a href="http://sourceforge.net/p/speed-dreams/discussion/865036/thread/7e2ee9af/">About missing PLIB headers</a></li>
</ul>
GTK decoration layout2015-05-24T00:00:00+00:00http://roman-yagodin.github.io/how-to/2015/05/24/gtk-decoration-layout
<p>Many great GNOME 3 applications are used widely across various desktop environments. Most of them use GTK+ client-side decorations (csd) instead of window manager borders, which makes them look as strangers outside GNOME Shell. In this post I want to show you how to tweak window buttons layout for csd-enabled applications.</p>
<!-- more -->
<p><img src="/assets/images/gtk-decoration-layout_01.png" alt="Classic window manager decorated window (Nemo) along with client-side decorated window (Nautilus)" class="img-fluid" /></p>
<p style="text-align:center">Classic window manager decorated window (Nemo) along with client-side decorated window (Nautilus).</p>
<h2 id="facts">Facts</h2>
<p>Since GTK+ 3.10, GtkHeaderBar widgets use <code class="language-plaintext highlighter-rouge">gtk-decoration-layout</code> setting value
to display window control buttons in the right place & order. Default value is
<code class="language-plaintext highlighter-rouge">menu:maximize,minimize,close</code> (format is the same as for window manager buttons layout).</p>
<h2 id="solution-for-cinnamon">Solution for Cinnamon</h2>
<p><em>Cinnamon</em> provide a way to override default <code class="language-plaintext highlighter-rouge">gtk-decoration-layout</code> setting value via <code class="language-plaintext highlighter-rouge">dconf</code> key <code class="language-plaintext highlighter-rouge">gtk-decoration-layout</code> in the <code class="language-plaintext highlighter-rouge">org.cinnamon.desktop.interface</code> section.</p>
<p>Let’s set close button + menu to the left, and minimize button to the right. You could use <code class="language-plaintext highlighter-rouge">dconf-editor</code> to change setting value from GUI. From command-line, it should be like this:</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash">gsettings <span class="nb">set </span>org.cinnamon.desktop.interface gtk-decoration-layout <span class="s1">'close,menu:minimize'</span></code></pre></figure>
<p>Note what some buttons names are not supported, these are: <strong>above</strong>, <strong>stick</strong>, <strong>shade</strong> and <strong>separator</strong>. Hopefully, this will change in the future GTK+ versions.</p>
<h2 id="more-common-way">More common way</h2>
<p>For desktop environments, which don’t override <code class="language-plaintext highlighter-rouge">gtk-decoration-layout</code> setting, just change (or define) it in <code class="language-plaintext highlighter-rouge">~/.config/gtk-3.0/setting.ini</code> like this:</p>
<figure class="highlight"><pre><code class="language-ini" data-lang="ini"><span class="nn">[Settings]</span>
<span class="py">gtk-theme-name</span><span class="p">=</span><span class="s">Adwaita</span>
<span class="err">...</span>
<span class="py">gtk-decoration-layout</span><span class="p">=</span><span class="s">close,menu:minimize</span></code></pre></figure>
<p>Session restart would be needed to apply changes. Also, if there are no <code class="language-plaintext highlighter-rouge">settings.ini</code> file, just create new one and add <code class="language-plaintext highlighter-rouge">[Settings]</code> line.</p>
<h2 id="results">Results</h2>
<p><img src="/assets/images/gtk-decoration-layout_02.png" alt="Classic window manager decorated window (Nemo) along with client-side decorated window (Nautilus) - after changes" class="img-fluid" /></p>
<p style="text-align:center">Classic window manager decorated window (Nemo) along with client-side decorated window (Nautilus) - after changes.</p>
<h2 id="useful-links">Useful links</h2>
<ul>
<li><a href="https://blogs.gnome.org/mclasen/2014/01/13/client-side-decorations-continued/">Client-side decoration, continued</a></li>
<li><a href="https://developer.gnome.org/gtk3/stable/GtkSettings.html#GtkSettings--gtk-decoration-layout">GTK3 documentation about gtk-decoration-layout setting</a></li>
<li><a href="/how-to/2014/10/22/muffin-window-buttons-layout/">Muffin Window Buttons Layout</a></li>
</ul>
Get HTML from GTK# clipboard2015-01-12T00:00:00+00:00http://roman-yagodin.github.io/how-to/2015/01/12/get-html-from-gtk-sharp-clipboard
<p>Developing a cross-platform application would never be easy job, but I consider GTK# framework as one of the solid options to provide cross-platform UI, though the lack of documentation is embarassing sometimes. In this post I want to show an example of using <code class="language-plaintext highlighter-rouge">Gtk.Clipboard</code> object to get HTML markup from the clipboard.</p>
<!-- more -->
<p><img src="/assets/images/get-html-from-gtk-sharp-clipboard_01.png" alt="Paste table from LibreOffice Writer to GTK# application as HTML" class="img-fluid" /></p>
<h2 id="problem">Problem</h2>
<p>GTK# documentation and examples do not provide excessive information about using <code class="language-plaintext highlighter-rouge">Gtk.Clipboard</code> object to get various types of content. To get text from clipboard, the <code class="language-plaintext highlighter-rouge">Gtk.Clipboard.WaitForText()</code> method could be used, but how to get, by example, HTML table from LibreOffice Writer document or formatted text from webpage?</p>
<h2 id="solution">Solution</h2>
<p>In this solution we:</p>
<ol>
<li>Create target using <code class="language-plaintext highlighter-rouge">Gdk.Atom.Intern()</code> method, passing MIME type string <code class="language-plaintext highlighter-rouge">text/html</code> to it.</li>
<li>Get selection object by using <code class="language-plaintext highlighter-rouge">Gtk.Clipboard.WaitForContents()</code> method for created target.</li>
<li>If the selection is not null, then it’s <code class="language-plaintext highlighter-rouge">Data</code> property generally contains UTF-8 encoded string with HTML markup.</li>
</ol>
<figure class="highlight"><pre><code class="language-c#" data-lang="c#"><span class="c1">// create clipboard object</span>
<span class="kt">var</span> <span class="n">clipboard</span> <span class="p">=</span> <span class="n">Gtk</span><span class="p">.</span><span class="n">Clipboard</span><span class="p">.</span><span class="nf">Get</span> <span class="p">(</span><span class="n">Gdk</span><span class="p">.</span><span class="n">Atom</span><span class="p">.</span><span class="nf">Intern</span> <span class="p">(</span><span class="s">"CLIPBOARD"</span><span class="p">,</span> <span class="k">true</span><span class="p">));</span>
<span class="c1">// create target using MIME type</span>
<span class="kt">var</span> <span class="n">target</span> <span class="p">=</span> <span class="n">Gdk</span><span class="p">.</span><span class="n">Atom</span><span class="p">.</span><span class="nf">Intern</span> <span class="p">(</span><span class="s">"text/html"</span><span class="p">,</span> <span class="k">true</span><span class="p">);</span>
<span class="c1">// trying to get HTML markup</span>
<span class="kt">var</span> <span class="n">selection</span> <span class="p">=</span> <span class="n">clipboard</span><span class="p">.</span><span class="nf">WaitForContents</span> <span class="p">(</span><span class="n">target</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">selection</span> <span class="p">!=</span> <span class="k">null</span><span class="p">)</span>
<span class="p">{</span>
<span class="c1">// data is UTF-8 encoded string</span>
<span class="n">textview1</span><span class="p">.</span><span class="n">Buffer</span><span class="p">.</span><span class="n">Text</span> <span class="p">=</span> <span class="n">System</span><span class="p">.</span><span class="n">Text</span><span class="p">.</span><span class="n">Encoding</span><span class="p">.</span><span class="n">UTF8</span><span class="p">.</span><span class="nf">GetString</span> <span class="p">(</span><span class="n">selection</span><span class="p">.</span><span class="n">Data</span><span class="p">,</span> <span class="m">0</span><span class="p">,</span> <span class="n">selection</span><span class="p">.</span><span class="n">Data</span><span class="p">.</span><span class="n">Length</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">else</span>
<span class="p">{</span>
<span class="n">textview1</span><span class="p">.</span><span class="n">Buffer</span><span class="p">.</span><span class="n">Text</span> <span class="p">=</span> <span class="s">"No selection"</span><span class="p">;</span>
<span class="p">}</span></code></pre></figure>
<p>The solution is currently tested only on Linux with Mono 3.10.</p>
<p>Note, that <code class="language-plaintext highlighter-rouge">Gtk.Clipboard.WaitForTargets()</code> method in the GTK# 2.12 seems to have broken interface. It defined as <code class="language-plaintext highlighter-rouge">bool WaitForTargets (Gdk.Atom targets, out int n_targets)</code>, but should be something like <code class="language-plaintext highlighter-rouge">bool WaitForTargets (Gdk.Atom [] targets, out int n_targets)</code> to return array of available targets. As a result, we can’t see what targets are available in the clipboard, but only a number of them:</p>
<figure class="highlight"><pre><code class="language-c#" data-lang="c#"><span class="c1">// create clipboard object</span>
<span class="kt">var</span> <span class="n">clipboard</span> <span class="p">=</span> <span class="n">Gtk</span><span class="p">.</span><span class="n">Clipboard</span><span class="p">.</span><span class="nf">Get</span> <span class="p">(</span><span class="n">Gdk</span><span class="p">.</span><span class="n">Atom</span><span class="p">.</span><span class="nf">Intern</span> <span class="p">(</span><span class="s">"CLIPBOARD"</span><span class="p">,</span> <span class="k">true</span><span class="p">));</span>
<span class="c1">// create dummy target</span>
<span class="kt">var</span> <span class="n">target</span> <span class="p">=</span> <span class="k">new</span> <span class="n">Gdk</span><span class="p">.</span><span class="nf">Atom</span> <span class="p">(</span><span class="n">IntPtr</span><span class="p">.</span><span class="n">Zero</span><span class="p">);</span>
<span class="kt">int</span> <span class="n">n_targets</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="n">clipboard</span><span class="p">.</span><span class="nf">WaitForTargets</span> <span class="p">(</span><span class="n">target</span><span class="p">,</span> <span class="k">out</span> <span class="n">n_targets</span><span class="p">))</span>
<span class="p">{</span>
<span class="c1">// for me, returns about 12 or 13 targets</span>
<span class="n">textview1</span><span class="p">.</span><span class="n">Buffer</span><span class="p">.</span><span class="n">Text</span> <span class="p">=</span> <span class="n">n_targets</span><span class="p">.</span><span class="nf">ToString</span> <span class="p">();</span>
<span class="p">}</span></code></pre></figure>
<h2 id="more-to-explore">More to Explore</h2>
<p>We got the basic example to work, but many things are need to be explored:</p>
<ul>
<li>Primary: the selection data encoding seems to not always UTF-8, so we need a way to determine the encoding.</li>
<li>Which other common MIME types are supported by <code class="language-plaintext highlighter-rouge">Gtk.Clipboard</code>?</li>
<li>How this code will behave on the different platforms?</li>
</ul>
Muffin window buttons layout2014-10-22T00:00:00+00:00http://roman-yagodin.github.io/how-to/2014/10/22/muffin-window-buttons-layout
<p>One of great things about Linux desktops is ability to customize window title buttons layout - according to your taste or regular job specifics. If you are using <em>Cinnamon</em>, this instruction is for you - but majority of things are same for <em>GNOME 3</em>, <em>GNOME Flashback</em>, <em>Cinnamon</em> and <em>MATE</em> - as they are using similar window managers, derived from <em>metacity</em> - default window manager in <em>GNOME 2</em>.</p>
<!-- more -->
<p><img src="/assets/images/muffin-window-buttons-layout_01.png" alt="Editing muffin buttons layout in dconf-editor" class="img-fluid" /></p>
<h2 id="desktop-environments-and-window-managers">Desktop environments and window managers</h2>
<p>Here are the desktops and default window managers:</p>
<table>
<thead>
<tr>
<th>DE</th>
<th>Default WM</th>
</tr>
</thead>
<tbody>
<tr>
<td>GNOME 2</td>
<td>metacity</td>
</tr>
<tr>
<td>MATE</td>
<td>marco (metacity fork)</td>
</tr>
<tr>
<td>GNOME 3</td>
<td>mutter = metacity + clutter</td>
</tr>
<tr>
<td>GNOME 3 Flashback</td>
<td>mutter</td>
</tr>
<tr>
<td>Cinnamon</td>
<td>muffin (mutter fork)</td>
</tr>
</tbody>
</table>
<h2 id="setting-up">Setting up</h2>
<p>Buttons layout and some other WM options are stored in the <em>dconf</em> keys. For <em>Cinnamon’s muffin</em>, we should
change value of the key <code class="language-plaintext highlighter-rouge">org.cinnamon.desktop.wm.preferences.button-layout</code> or the key <code class="language-plaintext highlighter-rouge">org.cinnamon.muffin.button-layout</code>
to override value of the first key.</p>
<p>Some other desktops:</p>
<ul>
<li><code class="language-plaintext highlighter-rouge">org.gnome.shell.overrides.button-layout</code> - for <em>GNOME 3</em></li>
<li><code class="language-plaintext highlighter-rouge">org.gnome.desktop.wm.preferences.button-layout</code> - said to work in <em>GNOME Flashback / Classic</em></li>
</ul>
<p>Here are list of button names:</p>
<ul>
<li><strong>stick</strong> - toggle “show on all workspaces”</li>
<li><strong>above</strong> - toggle “always on top”</li>
<li><strong>menu</strong> - window menu</li>
<li><strong>shade</strong> - toggle “roll / minimize to header”</li>
<li><strong>spacer</strong> - space between buttons</li>
<li><strong>close, maximize, minimize</strong>* - as they sounds</li>
</ul>
<p>Note what standard <em>Cinnamon</em> window settings do not have ability to add some buttons, like <strong>above</strong>, <del><strong>shade</strong></del> (present since 2.4) and also <strong>spacer</strong> -
so we should use <code class="language-plaintext highlighter-rouge">dconf-editor</code> for GUI or <code class="language-plaintext highlighter-rouge">gsettings set</code> command in the terminal to get things done.</p>
<p><img src="/assets/images/muffin-window-buttons-layout_04.png" alt="Editing muffin buttons layout in Cinnamon windows settings" class="img-fluid" /></p>
<h2 id="examples">Examples</h2>
<p>Value of <code class="language-plaintext highlighter-rouge">button-layout</code> key is a comma-separated list of button names, like <code class="language-plaintext highlighter-rouge">close:shade,minimize</code>. Colon (:) is used to distinguish left and right side.</p>
<p>Format of <code class="language-plaintext highlighter-rouge">gsettings</code> command:</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash">gsettings <span class="nb">set</span> <key> button-layout <value></code></pre></figure>
<p>Move all 3 default buttons to the left:</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash">gsettings <span class="nb">set </span>org.cinnamon.muffin button-layout <span class="s1">'close,maximize,minimize:'</span></code></pre></figure>
<p><img src="/assets/images/muffin-window-buttons-layout_02.png" alt="3 default buttons" /></p>
<p>My current layout:</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash">gsettings <span class="nb">set </span>org.cinnamon.muffin button-layout <span class="s1">'close,above:shade,minimize'</span></code></pre></figure>
<p><img src="/assets/images/muffin-window-buttons-layout_03.png" alt="My current buttons layout" /></p>
<h2 id="theme-issues">Theme issues</h2>
<ul>
<li>
<p>Some buttons could miss icons - it’s very common issue. By example, <em>Adwaita</em> theme have no icon for <strong>above</strong> button.</p>
</li>
<li>
<p>I also encounter problem with <strong>spacer</strong> button in both <em>Cinnamon 2.0</em> and <em>GNOME 3.8</em> with <em>Adwaita</em> theme - space is visible only if window is shaded (minimized to header). In normal state, spacer is not visible.</p>
</li>
</ul>
<h2 id="feedback">Feedback</h2>
<p>Let me know, if I’ve messed up with something! I would also want to know
about which button layouts you are using and what theme or WM issues you have encountered.</p>
Xamarin official Mono repositories for Linux2014-10-11T00:00:00+00:00http://roman-yagodin.github.io/how-to/2014/10/11/xamarin-official-mono-repositories-for-linux
<p><strong>Great news for all Mono developers on Linux!</strong> Recently <em>Xamarin</em> introduced <a href="http://www.mono-project.com/download/#download-lin">official Mono repositories for Linux</a> (Debian, Ubuntu, RedHat, SUSE and derivatives). Currently it contains Mono 3.10.0 and MonoDevelop 5.5.0 - a major improvement at least for Debian users (currently Mono 3.2.8, MonoDevelop 4.0.12 even in Sid).</p>
<!-- more -->
<p><img src="/assets/images/xamarin-official-mono-repositories-for-linux_01.png" alt="Xamarin Mono downloads page" class="img-fluid" /></p>
<h2 id="installation-in-debian">Installation in Debian</h2>
<p>Add repository line to your <code class="language-plaintext highlighter-rouge">sources.list</code> and install Xamarin <a href="http://download.mono-project.com/repo/xamarin.gpg">GPG key</a>. The most simple way to do that is using <em>software-properties-gtk</em> or <em>mintsources</em> (in case you are using Mint or LMDE). It also can be done from command line:</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="nb">sudo</span> <span class="nt">-i</span>
<span class="nb">echo</span> <span class="s2">"deb http://download.mono-project.com/repo/debian wheezy main"</span> <span class="o">></span> /etc/apt/sources.list.d/mono-xamarin.list
wget http://download.mono-project.com/repo/xamarin.gpg
apt-key add - < xamarin.gpg</code></pre></figure>
<p>Now we have to update apt cache and upgrade packages:</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="nb">sudo </span>apt-get update
<span class="nb">sudo </span>apt-get upgrade</code></pre></figure>
<p>Now get some tea (coffee) and sandwiches and wait… In case of problems check <a href="http://www.mono-project.com/docs/getting-started/install/linux/">official installation guide</a>.</p>
<hr />
<p><img src="/assets/images/xamarin-official-mono-repositories-for-linux_02.jpg" alt="MonoDevelop IDE 5.5 with GTK# designer and Mono 3.10" class="img-fluid" /></p>
Cinnamon panels in Expo and Overview2014-10-08T00:00:00+00:00http://roman-yagodin.github.io/how-to/2014/10/08/cinnamon-panels-in-expo-and-overview
<p>One of the things that I’ve liked in GNOME 3 is ability to manage workspaces, windows and run application from the overview mode, all beginning from one single gesture. So I’d like to my Cinnamon desktop behave somethat alike.</p>
<!-- more -->
<p><img src="/assets/images/cinnamon-panels-in-expo-and-overview_01.jpg" alt="Cinnamon expo mode with top panel" class="img-fluid" /></p>
<h2 id="problem">Problem</h2>
<p>Simpliest way to run applications in the Cinnamon is to use favorites and menu applets. But they are on the panel, and by default Cinnamon hides panels then entering expo and overview modes - so from expo you can manage only workspaces and windows, from overview - only windows, and can’t run an application (except from Alt+F2 command line) from both of modes.</p>
<h2 id="solution">Solution</h2>
<p>Luckily for us, most Cinnamon UI logic is defined by JavaScript files in the <code class="language-plaintext highlighter-rouge">/usr/share/cinnamon/js/ui/</code> directory. As you can guess, expo logic is in <code class="language-plaintext highlighter-rouge">expo.js</code> and overview is in <code class="language-plaintext highlighter-rouge">overview.js</code>. So what’s next?</p>
<p>1. Open script with superuser privileges in the text editor:</p>
<p>For expo:</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash">gksu gedit /usr/share/cinnamon/js/ui/expo.js</code></pre></figure>
<p>For overview:</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash">gksu gedit /usr/share/cinnamon/js/ui/overview.js</code></pre></figure>
<p>2. Find these two lines (marked as 1 and 2):</p>
<p>For expo:</p>
<figure class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="p">...</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">options</span> <span class="o">||</span> <span class="o">!</span><span class="nx">options</span><span class="p">.</span><span class="nx">toScale</span> <span class="p">)</span> <span class="p">{</span>
<span class="nx">Main</span><span class="p">.</span><span class="nx">enablePanels</span><span class="p">();</span> <span class="cm">/* 1 */</span>
<span class="nx">activeWorkspace</span><span class="p">.</span><span class="nx">overviewModeOff</span><span class="p">(</span><span class="kc">true</span><span class="p">,</span> <span class="kc">true</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">...</span>
<span class="k">this</span><span class="p">.</span><span class="nx">_gradient</span><span class="p">.</span><span class="nx">show</span><span class="p">();</span>
<span class="nx">Main</span><span class="p">.</span><span class="nx">disablePanels</span><span class="p">();</span> <span class="cm">/* 2 */</span></code></pre></figure>
<p>For overview:</p>
<figure class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="p">...</span>
<span class="k">this</span><span class="p">.</span><span class="nx">workspacesView</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">WorkspacesView</span><span class="p">.</span><span class="nx">WorkspacesView</span><span class="p">();</span>
<span class="nb">global</span><span class="p">.</span><span class="nx">overlay_group</span><span class="p">.</span><span class="nx">add_actor</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">workspacesView</span><span class="p">.</span><span class="nx">actor</span><span class="p">);</span>
<span class="nx">Main</span><span class="p">.</span><span class="nx">disablePanels</span><span class="p">();</span> <span class="cm">/* 1 */</span>
<span class="p">...</span>
<span class="k">this</span><span class="p">.</span><span class="nx">animationInProgress</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
<span class="k">this</span><span class="p">.</span><span class="nx">_hideInProgress</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
<span class="nx">Main</span><span class="p">.</span><span class="nx">enablePanels</span><span class="p">();</span> <span class="cm">/* 2 */</span></code></pre></figure>
<p>3. Comment out these lines and save the file:</p>
<p>For expo:</p>
<figure class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="p">...</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">options</span> <span class="o">||</span> <span class="o">!</span><span class="nx">options</span><span class="p">.</span><span class="nx">toScale</span> <span class="p">)</span> <span class="p">{</span>
<span class="c1">// Main.enablePanels(); /* 1 */</span>
<span class="nx">activeWorkspace</span><span class="p">.</span><span class="nx">overviewModeOff</span><span class="p">(</span><span class="kc">true</span><span class="p">,</span> <span class="kc">true</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">...</span>
<span class="k">this</span><span class="p">.</span><span class="nx">_gradient</span><span class="p">.</span><span class="nx">show</span><span class="p">();</span>
<span class="c1">// Main.disablePanels(); /* 2 */</span></code></pre></figure>
<p>For overview:</p>
<figure class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="p">...</span>
<span class="k">this</span><span class="p">.</span><span class="nx">workspacesView</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">WorkspacesView</span><span class="p">.</span><span class="nx">WorkspacesView</span><span class="p">();</span>
<span class="nb">global</span><span class="p">.</span><span class="nx">overlay_group</span><span class="p">.</span><span class="nx">add_actor</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">workspacesView</span><span class="p">.</span><span class="nx">actor</span><span class="p">);</span>
<span class="c1">// Main.disablePanels(); /* 1 */ </span>
<span class="p">...</span>
<span class="k">this</span><span class="p">.</span><span class="nx">animationInProgress</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
<span class="k">this</span><span class="p">.</span><span class="nx">_hideInProgress</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
<span class="c1">// Main.enablePanels(); /* 2 */</span></code></pre></figure>
<p>4. Now you need to restart Cinnamon. For this you can use entry in the <em>Troubleshooting</em> menu, or command line:</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash">killall cinnamon <span class="o">&&</span> cinnamon</code></pre></figure>
<p>5. In some cases expo and overview boxes could be partially overlapped with panels - it’s probably your case if you using top panel.
For both expo and overview, you need to change second parameter value of <code class="language-plaintext highlighter-rouge">set_position</code> function (Y offset).</p>
<p>For expo, edit <code class="language-plaintext highlighter-rouge">expo.js</code> again:</p>
<figure class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="k">this</span><span class="p">.</span><span class="nx">_expo</span><span class="p">.</span><span class="nx">actor</span><span class="p">.</span><span class="nx">set_position</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span> <span class="cm">/* change last 0 to the desired value */</span>
<span class="k">this</span><span class="p">.</span><span class="nx">_expo</span><span class="p">.</span><span class="nx">actor</span><span class="p">.</span><span class="nx">set_size</span><span class="p">((</span><span class="nx">primary</span><span class="p">.</span><span class="nx">width</span> <span class="o">-</span> <span class="nx">buttonWidth</span><span class="p">),</span> <span class="nx">primary</span><span class="p">.</span><span class="nx">height</span><span class="p">);</span></code></pre></figure>
<p>For overview, edit <code class="language-plaintext highlighter-rouge">workspacesView.js</code>:</p>
<figure class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="k">else</span> <span class="p">{</span>
<span class="nx">workspace</span><span class="p">.</span><span class="nx">actor</span><span class="p">.</span><span class="nx">set_position</span><span class="p">(</span><span class="nx">x</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span> <span class="cm">/* change 0 to the desired value */</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">w</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span>
<span class="k">this</span><span class="p">.</span><span class="nx">_updateVisibility</span><span class="p">();</span>
<span class="p">}</span></code></pre></figure>
<p>Offset value is related to the panel height, but you need to experiment with this to get desired result, as current Cinnamon theme
could greatly infuence it. In my case (<em>New Minty</em> theme), panel height is about 26, but value of 16 in the <code class="language-plaintext highlighter-rouge">expo.js</code> and 32 in <code class="language-plaintext highlighter-rouge">workspacesView.js</code> is fine.</p>
<hr />
<p><img src="/assets/images/cinnamon-panels-in-expo-and-overview_02.jpg" alt="Cinnamon overview (scale) mode with top panel" class="img-fluid" /></p>
<h2 id="acknowledgements">Acknowledgements</h2>
<p>This post mainly based on the solution, provided <a href="https://github.com/linuxmint/Cinnamon/issues/3001">here</a> by <a href="https://github.com/nfat">@nfat</a>.</p>