0x20/Sat, 04 Jun 2016 00:00:00 +0600Copying script output to a logfile/posts/2016/Jun/copying-script-output-to-a-logfile.html<p>Sometimes there's a need to redirect <tt class="docutils literal">stdout</tt> and <tt class="docutils literal">stderr</tt> streams of a shell script to a logfile while preserving its output in the terminal. In such cases I used to wrap relevant portions of the script into compound commands and piping them to <tt class="docutils literal">tee</tt> command. Below is a cleaner way to achieve the same results using named pipes.</p> <div class="highlight"><pre><span></span><span class="ch">#!/usr/bin/env bash</span> <span class="c1"># stdout and stderr are redirected to this file.</span> <span class="nv">log_file</span><span class="o">=</span><span class="s2">&quot;script.log&quot;</span> <span class="c1"># Terminate script if any command results in unhandled error.</span> <span class="nb">set</span> -e <span class="c1"># There is no option to create a temporary fifo so we&#39;ll create a temporary</span> <span class="c1"># directory instead and put fifo inside of it.</span> <span class="nv">fifo_dir</span><span class="o">=</span><span class="s2">&quot;</span><span class="k">$(</span>mktemp -d<span class="k">)</span><span class="s2">&quot;</span> <span class="nv">fifo</span><span class="o">=</span><span class="s2">&quot;</span><span class="si">${</span><span class="nv">fifo_dir</span><span class="si">}</span><span class="s2">/fifo&quot;</span> mkfifo <span class="s2">&quot;</span><span class="si">${</span><span class="nv">fifo</span><span class="si">}</span><span class="s2">&quot;</span> <span class="c1"># `tee` command copies everything from fifo to both stdout and ${log_file}.</span> tee <span class="s2">&quot;</span><span class="si">${</span><span class="nv">log_file</span><span class="si">}</span><span class="s2">&quot;</span> &lt; <span class="s2">&quot;</span><span class="si">${</span><span class="nv">fifo</span><span class="si">}</span><span class="s2">&quot;</span> <span class="p">&amp;</span> <span class="nv">tee_pid</span><span class="o">=</span><span class="nv">$!</span> <span class="c1"># Redirect stdout and stderr to fifo.</span> <span class="nb">exec</span> <span class="p">&amp;</span>&gt; <span class="s2">&quot;</span><span class="si">${</span><span class="nv">fifo</span><span class="si">}</span><span class="s2">&quot;</span> cleanup<span class="o">()</span> <span class="o">{</span> <span class="c1"># Remember exit code.</span> <span class="nv">code</span><span class="o">=</span><span class="nv">$?</span> <span class="c1"># Allow cleanup code to finish even if error occurs.</span> <span class="nb">set</span> +e <span class="nb">echo</span> <span class="s2">&quot;Exiting with code </span><span class="si">${</span><span class="nv">code</span><span class="si">}</span><span class="s2">&quot;</span> <span class="c1"># Close redirected stdout and stderr to finish `tee` process.</span> <span class="nb">exec</span> 1&gt;<span class="p">&amp;</span>- 2&gt;<span class="p">&amp;</span>- <span class="nb">wait</span> <span class="si">${</span><span class="nv">tee_pid</span><span class="si">}</span> rm -rf <span class="s2">&quot;</span><span class="si">${</span><span class="nv">fifo_dir</span><span class="si">}</span><span class="s2">&quot;</span> <span class="c1"># Do something with generated log file, e.g.:</span> <span class="c1"># cat &quot;${log_file}&quot; | mail -s &quot;${log_file}&quot; user@example.com</span> <span class="nb">exit</span> <span class="si">${</span><span class="nv">code</span><span class="si">}</span> <span class="o">}</span> <span class="c1"># cleanup() will be called with appropriate exit code even if script finishes</span> <span class="c1"># due to an error (see `set -e` above).</span> <span class="nb">trap</span> cleanup EXIT <span class="c1"># Script body goes here.</span> <span class="c1"># Note that if the script process is replaced using `exec` at some point the</span> <span class="c1"># cleanup code will not be executed, i.e. temporary files will not be deleted.</span> <span class="nv">$@</span> </pre></div> <p>Closing output descriptors and waiting in <tt class="docutils literal">cleanup()</tt> function is only needed to flush the logfile if we want to do something more with it inside of the script. Otherwise deleting the temporary directory containing the pipe is sufficient.</p> <p>There's an alternative way that uses builtin <tt class="docutils literal">coproc</tt> command <a class="reference external" href="http://wiki.bash-hackers.org/syntax/keywords/coproc#redirecting_the_output_of_a_script_to_a_file_and_to_the_screen">described here</a> and some relevant <a class="reference external" href="http://unix.stackexchange.com/questions/86270/how-do-you-use-the-command-coproc-in-bash">discussion here</a>. It has some benefits (e.g. not having to have access to a writable directory) but personally I'm sticking with named pipes for this purpose since the code looks more readable that way.</p> Nikita KarnauhovSat, 04 Jun 2016 00:00:00 +0600tag:,2016-06-04:posts/2016/Jun/copying-script-output-to-a-logfile.htmllinuxbashFixing TP-LINK login/posts/2016/May/fixing-tp-link-login.html<p>TP-LINK broke settings import after firmware update. Actually it was broken for quite some time (at least since 2014 according to some forums), but I've only just encountered this problem on my WDR3600 router. I don't update router firmware frequently. The breaking change was they stopped storing admin login passwords in plain text and switched to some hash sum instead (which is probably a good thing). As a result people are no longer able to login into their routers anymore after backing up and restoring their configs.</p> <p>One possible solution is resetting router to factory defaults and repeating setup from memory or from some web UI screenshots conveniently taken beforehand. I had no such screenshots and the option to reconfigure various port-forwarding and IP-binding rules wasn't very attractive.</p> <p>After some googling around I've learned that backed up config is actually more or less a text file encrypted with symmetric cypher (DES-ECB). Fortunately <a class="reference external" href="http://teknoraver.net/software/hacks/tplink/">other people</a> already done the research needed to decode it. Decoded config (backed up using older firmware) consists of ~1300 key-value pairs and looks like this:</p> <div class="highlight"><pre><span></span>lan_ip 192.168.8.200 lan_msk 255.255.255.0 ... lgn_ousr admin lgn_opswd admin lgn_usr ********** lgn_pwd ********** ... </pre></div> <p>To encode it back to a form consumable by the router you need to prepend the file by its MD5 sum and to pad with null bytes to the next 8 byte boundary (before encoding it using the same cypher). I've made <a class="reference external" href="https://gist.github.com/NikitaKarnauhov/5d9129f13e7b0e257cfbe93215751c7a#file-tlrecode-sh">a helpful script</a> to automate encoding/decoding process:</p> <p class="cut-begin" id="cut-2">tlrecode.sh</p> <div class="highlight"><pre><span></span><span class="ch">#!/usr/bin/env bash</span> <span class="c1"># tlrecode.sh</span> <span class="c1"># Decode and encode TP-LINK router config files.</span> <span class="c1">#</span> <span class="c1"># Creative Commons CC0 License:</span> <span class="c1"># http://creativecommons.org/publicdomain/zero/1.0/</span> <span class="c1">#</span> <span class="c1"># To the extent possible under law, the person who associated CC0 with this</span> <span class="c1"># work has waived all copyright and related or neighboring rights to this work.</span> <span class="nv">in</span><span class="o">=</span><span class="s2">&quot;&quot;</span> <span class="nv">out</span><span class="o">=</span><span class="s2">&quot;&quot;</span> <span class="nv">mode</span><span class="o">=</span><span class="s2">&quot;&quot;</span> <span class="c1"># See http://teknoraver.net/software/hacks/tplink/</span> <span class="nv">key</span><span class="o">=</span><span class="s2">&quot;478DA50BF9E3D2CF&quot;</span> <span class="nv">tmp_template</span><span class="o">=</span><span class="s2">&quot;tlrecode.XXXXXXXXXX&quot;</span> <span class="nv">tmp</span><span class="o">=</span><span class="s2">&quot;&quot;</span> <span class="nv">tmp2</span><span class="o">=</span><span class="s2">&quot;&quot;</span> usage<span class="o">()</span> <span class="o">{</span> cat <span class="s">&lt;&lt;EOF</span> <span class="s">tlrecode.sh</span> <span class="s">Decode and encode TP-LINK router config files.</span> <span class="s">Usage: tlrecode.sh (-e|-d) [-i] INPUT [-o] OUTPUT</span> <span class="s"> -i, --input Input file name.</span> <span class="s"> -o, --output Output file name.</span> <span class="s"> -d, --decode Decoding mode (default).</span> <span class="s"> -e, --encode Encoding mode.</span> <span class="s"> -h, --help Print this message.</span> <span class="s">EOF</span> <span class="o">}</span> error<span class="o">()</span> <span class="o">{</span> <span class="nb">echo</span> <span class="s2">&quot;Error: </span><span class="nv">$1</span><span class="s2">&quot;</span> &gt;<span class="p">&amp;</span>2 <span class="nb">exit</span> 1 <span class="o">}</span> decode<span class="o">()</span> <span class="o">{</span> openssl enc -d -des-ecb -K <span class="s2">&quot;</span><span class="si">${</span><span class="nv">key</span><span class="si">}</span><span class="s2">&quot;</span> -nopad -in <span class="s2">&quot;</span><span class="si">${</span><span class="nv">in</span><span class="si">}</span><span class="s2">&quot;</span> -out <span class="s2">&quot;</span><span class="si">${</span><span class="nv">tmp</span><span class="si">}</span><span class="s2">&quot;</span> <span class="o">&amp;&amp;</span> tail -c +17 <span class="s2">&quot;</span><span class="si">${</span><span class="nv">tmp</span><span class="si">}</span><span class="s2">&quot;</span> &gt; <span class="s2">&quot;</span><span class="si">${</span><span class="nv">tmp2</span><span class="si">}</span><span class="s2">&quot;</span> <span class="o">&amp;&amp;</span> tr -d <span class="s2">&quot;\000&quot;</span> &lt; <span class="s2">&quot;</span><span class="si">${</span><span class="nv">tmp2</span><span class="si">}</span><span class="s2">&quot;</span> &gt; <span class="s2">&quot;</span><span class="si">${</span><span class="nv">out</span><span class="si">}</span><span class="s2">&quot;</span> <span class="o">}</span> encode<span class="o">()</span> <span class="o">{</span> openssl md5 -binary <span class="s2">&quot;</span><span class="si">${</span><span class="nv">in</span><span class="si">}</span><span class="s2">&quot;</span> &gt; <span class="s2">&quot;</span><span class="si">${</span><span class="nv">tmp</span><span class="si">}</span><span class="s2">&quot;</span> <span class="o">&amp;&amp;</span> cat <span class="s2">&quot;</span><span class="si">${</span><span class="nv">tmp</span><span class="si">}</span><span class="s2">&quot;</span> <span class="s2">&quot;</span><span class="si">${</span><span class="nv">in</span><span class="si">}</span><span class="s2">&quot;</span> &gt; <span class="s2">&quot;</span><span class="si">${</span><span class="nv">tmp2</span><span class="si">}</span><span class="s2">&quot;</span> <span class="o">&amp;&amp;</span> truncate -s %8 <span class="s2">&quot;</span><span class="si">${</span><span class="nv">tmp2</span><span class="si">}</span><span class="s2">&quot;</span> <span class="o">&amp;&amp;</span> openssl enc -e -des-ecb -K <span class="s2">&quot;</span><span class="si">${</span><span class="nv">key</span><span class="si">}</span><span class="s2">&quot;</span> -nopad -in <span class="s2">&quot;</span><span class="si">${</span><span class="nv">tmp2</span><span class="si">}</span><span class="s2">&quot;</span> -out <span class="s2">&quot;</span><span class="si">${</span><span class="nv">out</span><span class="si">}</span><span class="s2">&quot;</span> <span class="o">}</span> <span class="k">while</span> <span class="o">[</span> <span class="nv">$#</span> -gt <span class="m">0</span> <span class="o">]</span><span class="p">;</span> <span class="k">do</span> <span class="k">case</span> <span class="s2">&quot;</span><span class="nv">$1</span><span class="s2">&quot;</span> in -i<span class="p">|</span>--input<span class="o">)</span> <span class="o">[</span> -z <span class="s2">&quot;</span><span class="si">${</span><span class="nv">in</span><span class="si">}</span><span class="s2">&quot;</span> <span class="o">]</span> <span class="o">||</span> error <span class="s2">&quot;input file &#39;</span><span class="si">${</span><span class="nv">in</span><span class="si">}</span><span class="s2">&#39; is already set.&quot;</span> <span class="o">[</span> <span class="nv">$#</span> -gt <span class="m">1</span> <span class="o">]</span> <span class="o">||</span> error <span class="s2">&quot;option &#39;</span><span class="nv">$1</span><span class="s2">&#39; needs an argument.&quot;</span> <span class="nv">in</span><span class="o">=</span><span class="s2">&quot;</span><span class="nv">$2</span><span class="s2">&quot;</span> <span class="nb">shift</span> 2 <span class="p">;;</span> -o<span class="p">|</span>--output<span class="o">)</span> <span class="o">[</span> -z <span class="s2">&quot;</span><span class="si">${</span><span class="nv">out</span><span class="si">}</span><span class="s2">&quot;</span> <span class="o">]</span> <span class="o">||</span> error <span class="s2">&quot;output file &#39;</span><span class="si">${</span><span class="nv">out</span><span class="si">}</span><span class="s2">&#39; is already set.&quot;</span> <span class="o">[</span> <span class="nv">$#</span> -gt <span class="m">1</span> <span class="o">]</span> <span class="o">||</span> error <span class="s2">&quot;option &#39;</span><span class="nv">$1</span><span class="s2">&#39; needs an argument.&quot;</span> <span class="nv">out</span><span class="o">=</span><span class="s2">&quot;</span><span class="nv">$2</span><span class="s2">&quot;</span> <span class="nb">shift</span> 2 <span class="p">;;</span> -d<span class="p">|</span>--decode<span class="o">)</span> <span class="o">[</span> -z <span class="s2">&quot;</span><span class="si">${</span><span class="nv">mode</span><span class="si">}</span><span class="s2">&quot;</span> <span class="o">]</span> <span class="o">||</span> error <span class="s2">&quot;mode &#39;</span><span class="si">${</span><span class="nv">mode</span><span class="si">}</span><span class="s2">&#39; is already set.&quot;</span> <span class="nv">mode</span><span class="o">=</span><span class="s2">&quot;decode&quot;</span> <span class="nb">shift</span> 1 <span class="p">;;</span> -e<span class="p">|</span>--encode<span class="o">)</span> <span class="o">[</span> -z <span class="s2">&quot;</span><span class="si">${</span><span class="nv">mode</span><span class="si">}</span><span class="s2">&quot;</span> <span class="o">]</span> <span class="o">||</span> error <span class="s2">&quot;mode &#39;</span><span class="si">${</span><span class="nv">mode</span><span class="si">}</span><span class="s2">&#39; is already set.&quot;</span> <span class="nv">mode</span><span class="o">=</span><span class="s2">&quot;encode&quot;</span> <span class="nb">shift</span> 1 <span class="p">;;</span> -h<span class="p">|</span>--help<span class="o">)</span> usage <span class="nb">exit</span> 0 <span class="p">;;</span> *<span class="o">)</span> <span class="k">if</span> <span class="o">[</span> -z <span class="s2">&quot;</span><span class="si">${</span><span class="nv">in</span><span class="si">}</span><span class="s2">&quot;</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span> <span class="nv">in</span><span class="o">=</span><span class="s2">&quot;</span><span class="nv">$1</span><span class="s2">&quot;</span> <span class="k">elif</span> <span class="o">[</span> -z <span class="s2">&quot;</span><span class="si">${</span><span class="nv">out</span><span class="si">}</span><span class="s2">&quot;</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span> <span class="nv">out</span><span class="o">=</span><span class="s2">&quot;</span><span class="nv">$1</span><span class="s2">&quot;</span> <span class="k">else</span> error <span class="s2">&quot;unexpected argument &#39;</span><span class="nv">$1</span><span class="s2">&#39;&quot;</span> <span class="k">fi</span> <span class="nb">shift</span> 1 <span class="p">;;</span> <span class="k">esac</span> <span class="k">done</span> <span class="o">[</span> -z <span class="s2">&quot;</span><span class="si">${</span><span class="nv">in</span><span class="si">}</span><span class="s2">&quot;</span> <span class="o">]</span> <span class="o">&amp;&amp;</span> error <span class="s2">&quot;no input file given.&quot;</span> <span class="o">[</span> -f <span class="s2">&quot;</span><span class="si">${</span><span class="nv">in</span><span class="si">}</span><span class="s2">&quot;</span> <span class="o">]</span> <span class="o">||</span> error <span class="s2">&quot;input file &#39;</span><span class="si">${</span><span class="nv">in</span><span class="si">}</span><span class="s2">&#39; does not exist.&quot;</span> <span class="o">[</span> -z <span class="s2">&quot;</span><span class="si">${</span><span class="nv">out</span><span class="si">}</span><span class="s2">&quot;</span> <span class="o">]</span> <span class="o">&amp;&amp;</span> error <span class="s2">&quot;no output file given.&quot;</span> <span class="o">[</span> -z <span class="s2">&quot;</span><span class="si">${</span><span class="nv">mode</span><span class="si">}</span><span class="s2">&quot;</span> <span class="o">]</span> <span class="o">&amp;&amp;</span> <span class="nv">mode</span><span class="o">=</span><span class="s2">&quot;decode&quot;</span> <span class="nv">tmp</span><span class="o">=</span><span class="s2">&quot;</span><span class="k">$(</span>mktemp <span class="si">${</span><span class="nv">tmp_template</span><span class="si">}</span><span class="k">)</span><span class="s2">&quot;</span> <span class="nv">tmp2</span><span class="o">=</span><span class="s2">&quot;</span><span class="k">$(</span>mktemp <span class="si">${</span><span class="nv">tmp_template</span><span class="si">}</span><span class="k">)</span><span class="s2">&quot;</span> <span class="k">if</span> <span class="o">[</span> <span class="s2">&quot;</span><span class="si">${</span><span class="nv">mode</span><span class="si">}</span><span class="s2">&quot;</span> <span class="o">==</span> <span class="s2">&quot;decode&quot;</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span> decode <span class="k">else</span> encode <span class="k">fi</span> <span class="nv">result</span><span class="o">=</span><span class="nv">$?</span> rm <span class="s2">&quot;</span><span class="si">${</span><span class="nv">tmp</span><span class="si">}</span><span class="s2">&quot;</span> <span class="s2">&quot;</span><span class="si">${</span><span class="nv">tmp2</span><span class="si">}</span><span class="s2">&quot;</span> <span class="nb">exit</span> <span class="si">${</span><span class="nv">result</span><span class="si">}</span> </pre></div> <p class="cut-end"></p> <p>To restore router login using this script you need to:</p> <ul class="simple"> <li>back up config before firmware update;</li> <li>reset to hardware defaults after the update (if you tried importing the backed up settings and are unable to log in);</li> <li>change login/password to the desired ones and back up the new config;</li> <li>decode both configs with <tt class="docutils literal">tlrecode.sh config.bin config.txt &amp;&amp; tlrecode.sh <span class="pre">config-new.bin</span> <span class="pre">config-new.txt</span></tt>;</li> <li>update the old config, replacing <tt class="docutils literal">lgn_</tt> lines with the ones from the new config;</li> <li>encode the updated config with <tt class="docutils literal">tlrecode.sh <span class="pre">-e</span> config.txt <span class="pre">config-updated.bin</span></tt>;</li> <li>restore router settings using <tt class="docutils literal"><span class="pre">config-updated.bin</span></tt>.</li> </ul> <p>After update process finishes you should be able to login with your desired credentials.</p> Nikita KarnauhovTue, 17 May 2016 00:00:00 +0600tag:,2016-05-17:posts/2016/May/fixing-tp-link-login.htmllinuxtp-linkPanorama of Chuya river joining Katun/posts/2015/Oct/panorama-of-chuya-river-joining-katun.html<div><p>I've finally got around to processing some of the pictures accumulated through the years. Apparently at the time I've had in mind to stitch a panorama out of some of them. Although it was mostly a test whether it can be shot without using a tripod the result is looking pretty good.</p> <div class="pic-wrapper compound"> <a href="/albums/altai-2013/IMG_9324_9329.jpg"><img src="/albums/altai-2013/600x600/IMG_9324_9329.jpg" alt=""></a><p></p></div> <p>Stitched from 6 (2 rows, 3 columns) horizontal pictures using <a class="reference external" href="http://http://hugin.sourceforge.net/">Hugin</a>.</p> <p>More pictures from the same trip can be found under the album link below the picture.</p> </div>Nikita KarnauhovTue, 13 Oct 2015 00:00:00 +0600tag:,2015-10-13:posts/2015/Oct/panorama-of-chuya-river-joining-katun.htmlaltaiphotoSwitching to XFCE/posts/2015/Sep/switching-to-xfce.html<div><p>I really like Gnome 3 for its look and feel. In fact I've been using Gnome since at least version 1.2, when it came with Enlightenment for a window manager. However after recent update to Fedora 22 I've found several things in it to be just too annoying. Namely, sometimes it starts to use 100% of one of CPU cores, sometimes extensions get spontaneously unloaded, some extensions are never being updated for current Gnome versions, GDM is always running, etc. All these things compelled me to switch to something lighter and less complex.</p> <p>I've already been using <tt class="docutils literal"><span class="pre">xfce4-panel</span></tt> in a sidebar mode along with Gnome Shell, so XFCE was the natural place for me to move. Here I tried to recreate familiar environment which resulted in the following layout:</p> <div class="pic-wrapper compound"> <a href="/albums/switching-to-xfce/terminals.png"><img src="/albums/switching-to-xfce/600x600/terminals.png" alt="top running in gnome-terminal and Midnight Commander with xoria256 theme running in xterm"></a><p>top running in gnome-terminal and Midnight Commander with xoria256 theme running in xterm</p></div> <p class="cut-begin" id="cut-3">another couple of screenshots and a bunch of patches</p> <div class="pic-wrapper compound"> <a href="/albums/switching-to-xfce/panel-plugins.png"><img src="/albums/switching-to-xfce/600x600/panel-plugins.png" alt="Ceti-2 GTK theme and the list of applets on the top panel"></a><p>Ceti-2 GTK theme and the list of applets on the top panel</p></div> <p>The theme is <a class="reference external" href="http://horst3180.deviantart.com/art/Ceti-2-Theme-489193140">Ceti-2</a> slightly tweaked to reduce padding on tabs and to change panel fonts:</p> <div class="highlight"><pre><span></span><span class="gh">diff -u -r Ceti-2.orig/gtk-2.0/gtkrc Ceti-2/gtk-2.0/gtkrc</span> <span class="gd">--- Ceti-2.orig/gtk-2.0/gtkrc 2015-09-05 23:07:25.158255238 +0600</span> <span class="gi">+++ Ceti-2/gtk-2.0/gtkrc 2015-09-04 00:10:27.000000000 +0600</span> <span class="gu">@@ -16,7 +16,7 @@</span> GtkWidget::focus-line-width = 1 GtkMenuBar::window-dragging = 1 GtkToolbar::window-dragging = 1 <span class="gd">- GtkToolbar::internal-padding = 4</span> <span class="gi">+ GtkToolbar::internal-padding = 0</span> GtkToolButton::icon-spacing = 4 GtkWidget::tooltip-radius = 2 <span class="gh">diff -u -r Ceti-2.orig/gtk-2.0/panel.rc Ceti-2/gtk-2.0/panel.rc</span> <span class="gd">--- Ceti-2.orig/gtk-2.0/panel.rc 2015-09-05 23:05:12.411546816 +0600</span> <span class="gi">+++ Ceti-2/gtk-2.0/panel.rc 2015-08-31 22:41:08.000000000 +0600</span> <span class="gu">@@ -1,6 +1,9 @@</span> <span class="gi">+gtk-icon-sizes = "panel-tasklist-menu=64,64"</span> <span class="gi">+</span> style "theme-panel" { ythickness = 0 <span class="gi">+ font_name = "RobotoAC Bold 9"</span> bg[NORMAL] = "#2D3136" bg[ACTIVE] = shade(0.9, "#2D3136") <span class="gu">@@ -44,6 +47,8 @@</span> style "panelbuttons" { <span class="gi">+ font_name = "RobotoAC Bold Condensed 10"</span> <span class="gi">+</span> xthickness = 4 ythickness = 3 <span class="gu">@@ -55,6 +60,8 @@</span> gradient_shades = {1.0,0.9,0.9,0.8} border_shades = { 0.6, 0.6 } } <span class="gi">+</span> <span class="gi">+ XfceTasklist::max-button-size = 32</span> } style "theme-panel-text" { </pre></div> <p>With the above <tt class="docutils literal"><span class="pre">internal-padding</span></tt> fix the toolbar and editor tabs of Eclipse look almost normal.</p> <div class="pic-wrapper compound"> <a href="/albums/switching-to-xfce/eclipse.png"><img src="/albums/switching-to-xfce/600x600/eclipse.png" alt="maximized and undecorated window of Eclipse with almost normally sized tabs"></a><p>maximized and undecorated window of Eclipse with almost normally sized tabs</p></div> <p>The font on the panels and the widow titles is Google's <a class="reference external" href="https://www.google.com/fonts/specimen/Roboto">Roboto</a> manually (using <tt class="docutils literal">fontforge</tt>) converted to all-caps variant. The modified versions can be found <a class="reference external" href="http://0x20.ru:8000/d/1863500a74/">here</a>.</p> <p>I had to change some of the applets' code for nicer looks: added padding to hardware monitors, changed color/font of keyboard indicators, made volume icon white instead of dark grey. Maybe some of these things are themeable but at least some of the fonts and colors are hardcoded so patching the code was inevitable. I've basically changed one hardcoded values for others so the code is still ugly but at least the applets now fit with my theme visually:</p> <div class="highlight"><pre><span></span><span class="gh">diff -u -r xfce4-kbdleds-plugin-0.0.6.orig/panel-plugin/kbdleds.c xfce4-kbdleds-plugin-0.0.6/panel-plugin/kbdleds.c</span> <span class="gd">--- xfce4-kbdleds-plugin-0.0.6.orig/panel-plugin/kbdleds.c 2011-10-13 22:51:23.000000000 +0700</span> <span class="gi">+++ xfce4-kbdleds-plugin-0.0.6/panel-plugin/kbdleds.c 2015-09-01 00:07:03.000966168 +0600</span> <span class="gu">@@ -220,7 +220,7 @@</span> gboolean kbdleds_update_state(gpointer data) { int i; gchar *str; <span class="gd">- gchar *template_on="&lt;span background=\"#00ff00\" foreground=\"#000000\"&gt;%c&lt;/span&gt;";</span> <span class="gi">+ gchar *template_on="&lt;span background=\"#ffffff\" foreground=\"#000000\"&gt;%c&lt;/span&gt;";</span> gchar *template_off="%c"; gchar *tempstr[NUM_LEDS]; gchar *templates[NUM_LEDS]; </pre></div> <div class="highlight"><pre><span></span><span class="gh">diff -u -r xfce4-pulseaudio-plugin-0.2.3.orig/panel-plugin/pulseaudio-button.c xfce4-pulseaudio-plugin-0.2.3/panel-plugin/pulseaudio-button.c</span> <span class="gd">--- xfce4-pulseaudio-plugin-0.2.3.orig/panel-plugin/pulseaudio-button.c 2015-05-04 02:52:14.000000000 +0600</span> <span class="gi">+++ xfce4-pulseaudio-plugin-0.2.3/panel-plugin/pulseaudio-button.c 2015-09-01 20:18:10.908803274 +0600</span> <span class="gu">@@ -137,7 +137,7 @@</span> /* Setup Gtk style */ css_provider = gtk_css_provider_new (); <span class="gd">- gtk_css_provider_load_from_data (css_provider, "#pulseaudio-button { -GtkWidget-focus-padding: 0; -GtkWidget-focus-line-width: 0; -GtkButton-default-border: 0; -GtkButton-inner-border: 0; padding: 1px; border-width: 1px;}", -1, NULL);</span> <span class="gi">+ gtk_css_provider_load_from_data (css_provider, "#pulseaudio-button { -GtkWidget-focus-padding: 0; -GtkWidget-focus-line-width: 0; -GtkButton-default-border: 0; -GtkButton-inner-border: 0; padding: 1px; border-width: 1px; color: #ffffff; }", -1, NULL);</span> gtk_style_context_add_provider (GTK_STYLE_CONTEXT (gtk_widget_get_style_context (GTK_WIDGET (button))), GTK_STYLE_PROVIDER (css_provider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); /* Intercept scroll events */ </pre></div> <div class="highlight"><pre><span></span><span class="gh">diff -u -r xfce4-xkb-plugin-0.7.1.orig/panel-plugin/xkb-cairo.c xfce4-xkb-plugin-0.7.1/panel-plugin/xkb-cairo.c</span> <span class="gd">--- xfce4-xkb-plugin-0.7.1.orig/panel-plugin/xkb-cairo.c 2015-02-28 03:53:11.000000000 +0600</span> <span class="gi">+++ xfce4-xkb-plugin-0.7.1/panel-plugin/xkb-cairo.c 2015-09-01 21:20:52.883016118 +0600</span> <span class="gu">@@ -31,7 +31,7 @@</span> #include &lt;librsvg/rsvg-cairo.h&gt; #endif <span class="gd">-#define XKB_PREFERRED_FONT "Courier New, Courier 10 Pitch, Monospace Bold"</span> <span class="gi">+#define XKB_PREFERRED_FONT "RobotoAC Bold 9"</span> #define xkb_cairo_arc_for_flag(cr, x, y, r, a1, a2) \ xx = layoutx + width - 12 + x; \ </pre></div> <p>I've also patched <tt class="docutils literal"><span class="pre">xfce4-panel</span></tt> itself to allow wider sidebar and bigger tasklist icons:</p> <div class="highlight"><pre><span></span><span class="gh">diff -u -r xfce4-panel-4.12.0.orig/panel/panel-itembar.c xfce4-panel-4.12.0/panel/panel-itembar.c</span> <span class="gd">--- xfce4-panel-4.12.0.orig/panel/panel-itembar.c 2014-04-25 03:16:37.000000000 +0700</span> <span class="gi">+++ xfce4-panel-4.12.0/panel/panel-itembar.c 2015-08-23 17:19:45.000000000 +0600</span> <span class="gu">@@ -193,7 +193,7 @@</span> PROP_SIZE, g_param_spec_uint ("size", NULL, NULL, <span class="gd">- 16, 128, 30,</span> <span class="gi">+ 16, 256, 30,</span> EXO_PARAM_WRITABLE)); g_object_class_install_property (gobject_class, <span class="gh">diff -u -r xfce4-panel-4.12.0.orig/panel/panel-preferences-dialog.glade xfce4-panel-4.12.0/panel/panel-preferences-dialog.glade</span> <span class="gd">--- xfce4-panel-4.12.0.orig/panel/panel-preferences-dialog.glade 2015-02-27 02:32:17.000000000 +0600</span> <span class="gi">+++ xfce4-panel-4.12.0/panel/panel-preferences-dialog.glade 2015-08-23 16:21:07.000000000 +0600</span> <span class="gu">@@ -73,7 +73,7 @@</span> &lt;object class="GtkAdjustment" id="size"&gt; &lt;property name="value"&gt;16&lt;/property&gt; &lt;property name="lower"&gt;16&lt;/property&gt; <span class="gd">- &lt;property name="upper"&gt;128&lt;/property&gt;</span> <span class="gi">+ &lt;property name="upper"&gt;256&lt;/property&gt;</span> &lt;property name="step_increment"&gt;1&lt;/property&gt; &lt;property name="page_increment"&gt;10&lt;/property&gt; &lt;/object&gt; <span class="gh">diff -u -r xfce4-panel-4.12.0.orig/panel/panel-preferences-dialog-ui.h xfce4-panel-4.12.0/panel/panel-preferences-dialog-ui.h</span> <span class="gd">--- xfce4-panel-4.12.0.orig/panel/panel-preferences-dialog-ui.h 2015-02-28 22:22:40.000000000 +0600</span> <span class="gi">+++ xfce4-panel-4.12.0/panel/panel-preferences-dialog-ui.h 2015-08-23 16:21:22.000000000 +0600</span> <span class="gu">@@ -28,7 +28,7 @@</span> "id=\"0\" translatable=\"yes\"&gt;Background image&lt;/col&gt;&lt;/row&gt;&lt;/data&gt;&lt;/obje" "ct&gt;&lt;object class=\"GtkAdjustment\" id=\"size\"&gt;&lt;property name=\"value\"" "&gt;16&lt;/property&gt;&lt;property name=\"lower\"&gt;16&lt;/property&gt;&lt;property name=\"up" <span class="gd">- "per\"&gt;128&lt;/property&gt;&lt;property name=\"step_increment\"&gt;1&lt;/property&gt;&lt;prop"</span> <span class="gi">+ "per\"&gt;256&lt;/property&gt;&lt;property name=\"step_increment\"&gt;1&lt;/property&gt;&lt;prop"</span> "erty name=\"page_increment\"&gt;10&lt;/property&gt;&lt;/object&gt;&lt;object class=\"GtkA" "djustment\" id=\"length\"&gt;&lt;property name=\"value\"&gt;25&lt;/property&gt;&lt;proper" "ty name=\"lower\"&gt;1&lt;/property&gt;&lt;property name=\"upper\"&gt;100&lt;/property&gt;&lt;p" <span class="gh">diff -u -r xfce4-panel-4.12.0.orig/panel/panel-window.c xfce4-panel-4.12.0/panel/panel-window.c</span> <span class="gd">--- xfce4-panel-4.12.0.orig/panel/panel-window.c 2015-02-28 20:52:27.000000000 +0600</span> <span class="gi">+++ xfce4-panel-4.12.0/panel/panel-window.c 2015-08-23 17:19:38.000000000 +0600</span> <span class="gu">@@ -392,7 +392,7 @@</span> g_object_class_install_property (gobject_class, PROP_SIZE, g_param_spec_uint ("size", NULL, NULL, <span class="gd">- 16, 128, 48,</span> <span class="gi">+ 16, 256, 48,</span> EXO_PARAM_READWRITE)); g_object_class_install_property (gobject_class, <span class="gh">diff -u -r xfce4-panel-4.12.0.orig/plugins/tasklist/tasklist-widget.c xfce4-panel-4.12.0/plugins/tasklist/tasklist-widget.c</span> <span class="gd">--- xfce4-panel-4.12.0.orig/plugins/tasklist/tasklist-widget.c 2015-02-27 02:32:17.000000000 +0600</span> <span class="gi">+++ xfce4-panel-4.12.0/plugins/tasklist/tasklist-widget.c 2015-09-05 22:35:33.794372013 +0600</span> <span class="gu">@@ -46,7 +46,7 @@</span> #define DEFAULT_BUTTON_SIZE (25) #define DEFAULT_MAX_BUTTON_LENGTH (200) <span class="gd">-#define DEFAULT_MENU_ICON_SIZE (16)</span> <span class="gi">+#define DEFAULT_MENU_ICON_SIZE (32)</span> #define DEFAULT_MIN_BUTTON_LENGTH (DEFAULT_MAX_BUTTON_LENGTH / 4) #define DEFAULT_ICON_LUCENCY (50) #define DEFAULT_ELLIPSIZE_MODE (PANGO_ELLIPSIZE_END) <span class="gu">@@ -2449,7 +2449,7 @@</span> return; /* get the window icon */ <span class="gd">- if (tasklist-&gt;show_labels)</span> <span class="gi">+ if (0 &amp;&amp; tasklist-&gt;show_labels)</span> pixbuf = wnck_window_get_mini_icon (window); else pixbuf = wnck_window_get_icon (window); <span class="gu">@@ -3495,7 +3495,7 @@</span> return; /* get the class group icon */ <span class="gd">- if (group_child-&gt;tasklist-&gt;show_labels)</span> <span class="gi">+ if (0 &amp;&amp; group_child-&gt;tasklist-&gt;show_labels)</span> pixbuf = wnck_class_group_get_mini_icon (class_group); else pixbuf = wnck_class_group_get_icon (class_group); </pre></div> <p class="cut-end"></p> <p>All in all, I'm quite pleased with the results. Here's the <em>before</em> picture (running Gnome 3) for comparison:</p> <div class="pic-wrapper compound"> <a href="/albums/switching-to-xfce/gnome-shell.png"><img src="/albums/switching-to-xfce/600x600/gnome-shell.png" alt="gnome-shell with similar customizations"></a><p>gnome-shell with similar customizations</p></div> <p>It's not a whole lot different from the <em>after</em> version but that was the whole point.</p> </div>Nikita KarnauhovSat, 05 Sep 2015 00:00:00 +0600tag:,2015-09-05:posts/2015/Sep/switching-to-xfce.htmllinuxgnomexfcescreenshots