<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>my tech blog &#187; cinnamon</title>
	<atom:link href="http://billauer.se/blog/category/cinnamon/feed/" rel="self" type="application/rss+xml" />
	<link>https://billauer.se/blog</link>
	<description>Anything I found worthy to write down.</description>
	<lastBuildDate>Thu, 12 Mar 2026 11:36:00 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.2</generator>
		<item>
		<title>Remapping keyboard keys to allow å, ä and ö</title>
		<link>https://billauer.se/blog/2023/11/xmodmap-mapping-swedish/</link>
		<comments>https://billauer.se/blog/2023/11/xmodmap-mapping-swedish/#comments</comments>
		<pubDate>Sat, 11 Nov 2023 10:56:54 +0000</pubDate>
		<dc:creator>eli</dc:creator>
				<category><![CDATA[cinnamon]]></category>
		<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">https://billauer.se/blog/?p=6964</guid>
		<description><![CDATA[Motivation I have an English / Hebrew keyboard, but occasionally I also want to use the Swedish letters å, ä and ö. The idea is to sacrifice three keys on the keyboard for this purpose. But which ones? I went for the keypad&#8217;s /, * and &#8211; keys. But hey, I use these normally every [...]]]></description>
			<content:encoded><![CDATA[<h3>Motivation</h3>
<p>I have an English / Hebrew keyboard, but occasionally I also want to use the Swedish letters å, ä and ö. The idea is to sacrifice three keys on the keyboard for this purpose.</p>
<p>But which ones? I went for the keypad&#8217;s /, * and &#8211; keys. But hey, I use these normally every now and then.</p>
<p>So why not use these keys with Alt to produce the desired letters? Here&#8217;s a simple reason: I don&#8217;t know how to do that. What I managed to achieve with xmodmap isn&#8217;t sensitive to Alt. Only Shift.</p>
<p>And why not use the keys that are commonly used in Swedish keyboards? Because the relevant keys are used for colon and double quotes. These are useful in Swedish as well. This is normally solved by using the right-Alt button to select the Swedish letters. But as just mentioned, I didn&#8217;t find the way to use Alt buttons as a modifier.</p>
<p>And why don&#8217;t I just install the Swedish keyboard layout? I might do that later on, but right now I don&#8217;t use Swedish often enough to justify another language candidate. It makes language switching more cumbersome.</p>
<p>So my solution was to write simple bash scripts that turn the said keys into å, ä and ö, and another bash script that bring them back to their default use. I&#8217;m sure there&#8217;s a way to fix it nicely with the Alt key, but I won&#8217;t bother.</p>
<p>All here relates to Linux Mint 19 running Cinnamon.</p>
<h3>Making changes</h3>
<p>First thing first: Save the current setting, in case you mess up:</p>
<pre>$ xmodmap -pke &gt; default-mapping.txt</pre>
<p>Now let&#8217;s look at the default situation. Start with the mapping of modifiers:</p>
<pre>$ <strong>xmodmap</strong>
xmodmap:  up to 4 keys per modifier, (keycodes in parentheses):

shift       Shift_L (0x32),  Shift_R (0x3e)
lock        Caps_Lock (0x42)
control     Control_L (0x25),  Control_R (0x69)
mod1        Alt_L (0x40),  Alt_R (0x6c),  Meta_L (0xcd)
mod2        Num_Lock (0x4d)
mod3
mod4        Super_L (0x85),  Super_R (0x86),  Super_L (0xce),  Hyper_L (0xcf)
mod5        ISO_Level3_Shift (0x5c),  Mode_switch (0xcb)</pre>
<p>To get the current keyboard mapping, try</p>
<pre>$ xmodmap -pk | less
$ xmodmap -pke | less</pre>
<p>The output is a list of keycode commands. Let&#8217;s look at one row:</p>
<pre>keycode  42 = g G hebrew_ayin G U05F1</pre>
<p>The number is the code of the physical key 42 on the keyboard.</p>
<p>That is followed by a number of keysyms. The first is with no modifier pressed, the second with Shift, the third when Mode_switch is used, and the forth is Switch + Mode_switch.</p>
<p>In my case, Mode_switch is when the language is changed to Hebrew, which is why &#8220;hebrew_ayin&#8221; is listed.</p>
<p>The fifth code, U05F1, is a Unicode character U+05F1, a Hebrew ligature character (ױ). Not clear what that&#8217;s for.</p>
<p>According to the man page, there may be up to 8 keysyms, but most X servers rarely use more than four. However, looking at the output of &#8220;xmodmap -pke&#8221;, there are 10 keysyms allocated to the function keys (F1, F2, etc.). Once again, not clear what for.</p>
<p>If the number codes aren&#8217;t clear, use this command to obtain X events. The keycodes are printed out (among all the mumbo-jumbo, it says e.g. &#8220;keycode 82&#8243;)</p>
<pre>$ xev</pre>
<p>This utility opens a small windows and dumps all X events that it gets. So this small window must have focus so that the keyboard events are directed to it.</p>
<h3>What do these keysyms mean?</h3>
<p>I tried this on keycode 90, which is the keypad&#8217;s zero or Ins key. Its assignment is originally</p>
<pre>keycode  90 = KP_Insert KP_0 KP_Insert KP_0</pre>
<p>So I changed it with</p>
<pre>$ xmodmap -e "keycode 90 = a b c d e f g h i j"</pre>
<p>This command takes a couple of seconds to execute. I&#8217;m discussing why it&#8217;s slow below.</p>
<p>After this, pressing this character plainly now just printed out &#8220;a&#8221;. No I could test a whole lot of combinations to find out what each of these positions mean:</p>
<ol>
<li>No modifier.</li>
<li>Shift</li>
<li>Hebrew mode on</li>
<li>Hebrew mode on + Shift</li>
</ol>
<p>No surprise here. As for the rest of the keysyms, I didn&#8217;t manage to get any of the e-j letter to appear, no matter what combination I tried. So I guess they&#8217;re not relevant in my setting. The man page was correct: Only four of them are actually used.</p>
<p>By the way, when applying Caps Lock, I got the uppercase version of the same letters. It&#8217;s really twisted.</p>
<p>Reverting my change from above:</p>
<pre>$ xmodmap -e "keycode 90 = KP_Insert KP_0 KP_Insert KP_0"</pre>
<h3>The scripts</h3>
<p>To reiterate, the purpose is to turn the keypad&#8217;s /, *, &#8211; into å, ä and ö.</p>
<p>Their respective 106, 63 and 82 (that was pretty random, wasn&#8217;t it?), with the following defaults:</p>
<pre>keycode 106 = KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide XF86Ungrab KP_Divide KP_Divide XF86Ungrab
keycode  63 = KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply XF86ClearGrab KP_Multiply KP_Multiply XF86ClearGrab
keycode  82 = KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract XF86Prev_VMode KP_Subtract KP_Subtract XF86Prev_VMode</pre>
<p>So this is the script to bring back the buttons to normal (which I named &#8220;kbnormal&#8221;):</p>
<pre>#!/bin/bash

echo "Changing the keymap to normal."
echo "The display will now freeze for 7-8 seconds. Don't worry..."
sleep 0.5

/usr/bin/xmodmap - &lt;&lt;EOF
keycode 106 = KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide XF86Ungrab KP_Divide KP_Divide XF86Ungrab
keycode  63 = KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply XF86ClearGrab KP_Multiply KP_Multiply XF86ClearGrab
keycode  82 = KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract XF86Prev_VMode KP_Subtract KP_Subtract XF86Prev_VMode
EOF</pre>
<p>And finally, this is the script that turns these buttons into å, ä and ö:</p>
<pre>#!/bin/bash

echo "Changing the keymap to swedish letters on numpad's /, *, -"
echo "The display will now freeze for 7-8 seconds. Don't worry..."
sleep 0.5

/usr/bin/xmodmap - &lt;&lt;EOF
keycode 106 = aring Aring aring Aring
keycode  63 = adiaeresis Adiaeresis adiaeresis Adiaeresis
keycode  82 = odiaeresis Odiaeresis odiaeresis Odiaeresis
EOF</pre>
<p>The change is temporary, and that&#8217;s fine for my purposes. I know a lot  of people have been struggling with making the changes permanent, and I  have no idea how to do that, nor do I have any motivation to find out.</p>
<p>See the notification that the screen will freeze for a few seconds? It&#8217;s for real. The mouse pointer keeps running normally, but the desktop freezes completely for a few seconds sometimes up to twenty seconds, including the clock.</p>
<p>That rings an old bell. Like, a <a rel="noopener" href="https://billauer.se/blog/2017/05/vmplayer-disk-calm/" target="_blank">six years old bell</a>. I&#8217;ve been wondering why moving the mouse pointer in and out from a VMWare window causes the entire screen to freeze for a minute. The reason is that xmodmap calls XChangeKeyboardMapping() for every &#8220;keycode&#8221; row. And each such call causes the X server to <a href="https://lesstif.sourceforge.net/doc/Xlib/spec/xlib.html" target="_blank">report a MappingNotify events to all clients</a>. These clients may process such an event by requesting an update of their view of the keymap.</p>
<p>This was probably reasonable in the good old times when people had a few windows on a desktop. But with multiple desktops and a gazillion windows and small apps on each, I suppose this isn&#8217;t peanuts anymore. The more virtual desktop I have, and the more windows I have on each, the longer the freeze. I&#8217;m not sure if this issue is related to Linux Mint, Cinnamon, or to the fact that it&#8217;s so convenient to have a lot of open windows with Cinnamon. While writing this, I have 40 windows spread on five virtual desktops.</p>
<h3>Reducing the freeze time</h3>
<p>As just mentioned, the problem is that xmodmap calls XChangeKeyboardMapping() for each key mapping that needs to be modified. But XChangeKeyboardMapping() can also be used to change a range of key mappings. In fact, it&#8217;s possible to set the entire map in one call. This was the not-so-elegant workaround that was <a rel="noopener" href="https://unix.stackexchange.com/questions/94336/xmodmap-hanging-the-system-for-20-secs-and-not-sticking/" target="_blank">suggested on a Stackexchange page</a>.</p>
<p>So the strategy is now like this: Read the entire keymap into an array, make the changes in this array, and then write it back in one call. If I had the motivation and patience to modify xmodmap, this is what I would have done. But since I&#8217;m in here for solving my own little problem, this is the C program that does the same as the script above. Only with a freeze that is three times shorter: One call to XChangeKeyboardMapping() instead of three.</p>
<pre><span class="hljs-meta">#<span class="hljs-keyword">include</span> <span class="hljs-string">&lt;stdlib.h&gt;</span></span>
<span class="hljs-meta">#<span class="hljs-keyword">include</span> <span class="hljs-string">&lt;stdio.h&gt;</span></span>
<span class="hljs-meta">#<span class="hljs-keyword">include</span> <span class="hljs-string">&lt;unistd.h&gt;</span></span>
<span class="hljs-meta">#<span class="hljs-keyword">include</span> <span class="hljs-string">&lt;X11/XKBlib.h&gt;</span></span>

<span class="hljs-meta">#<span class="hljs-keyword">define</span> update_per_code 4</span>

<span class="hljs-type">static</span> <span class="hljs-type">const</span> <span class="hljs-class"><span class="hljs-keyword">struct</span> {</span>
  <span class="hljs-type">int</span> keycode;
  <span class="hljs-type">char</span> *names[update_per_code];
} updatelist [] = {
  { <span class="hljs-number">106</span>, { <span class="hljs-string">"aring"</span>, <span class="hljs-string">"Aring"</span>, <span class="hljs-string">"aring"</span>, <span class="hljs-string">"Aring"</span> }},
  { <span class="hljs-number">63</span>, { <span class="hljs-string">"adiaeresis"</span>, <span class="hljs-string">"Adiaeresis"</span>, <span class="hljs-string">"adiaeresis"</span>, <span class="hljs-string">"Adiaeresis"</span> }},
  { <span class="hljs-number">82</span>, { <span class="hljs-string">"odiaeresis"</span>, <span class="hljs-string">"Odiaeresis"</span>, <span class="hljs-string">"odiaeresis"</span>, <span class="hljs-string">"Odiaeresis"</span> }},
  { }
};

<span class="hljs-type">int</span> <span class="hljs-title function_">main</span><span class="hljs-params">(<span class="hljs-type">int</span> argc, <span class="hljs-type">char</span> *argv[])</span> {
  <span class="hljs-type">int</span> rc = <span class="hljs-number">0</span>;
  <span class="hljs-type">int</span> minkey, maxkey;
  <span class="hljs-type">int</span> keysyms_per_keycode;
  <span class="hljs-type">int</span> i, j;

  Display *dpy = <span class="hljs-literal">NULL</span>;
  KeySym *keysyms = <span class="hljs-literal">NULL</span>;

  dpy = XOpenDisplay(<span class="hljs-literal">NULL</span>);

  <span class="hljs-keyword">if</span> (!dpy) {
    <span class="hljs-built_in">fprintf</span>(<span class="hljs-built_in">stderr</span>, <span class="hljs-string">"Failed to open default display.\n"</span>);
    rc = <span class="hljs-number">1</span>;
    <span class="hljs-keyword">goto</span> end;
  }

  XDisplayKeycodes(dpy, &amp;minkey, &amp;maxkey);

  keysyms = XGetKeyboardMapping(dpy, minkey, <span class="hljs-number">1</span>+maxkey-minkey,
				&amp;keysyms_per_keycode);

  <span class="hljs-keyword">if</span> (!keysyms) {
    <span class="hljs-built_in">fprintf</span>(<span class="hljs-built_in">stderr</span>, <span class="hljs-string">"Failed to get current keyboard mapping table\n"</span>);
    rc = <span class="hljs-number">1</span>;
    <span class="hljs-keyword">goto</span> end;
  }

  <span class="hljs-keyword">if</span> (keysyms_per_keycode &lt; update_per_code) {
    <span class="hljs-built_in">fprintf</span>(<span class="hljs-built_in">stderr</span>, <span class="hljs-string">"Number of keysyms per key is %d, no room for %d as in internal table.\n"</span>, keysyms_per_keycode,  update_per_code);
    rc = <span class="hljs-number">1</span>;
    <span class="hljs-keyword">goto</span> end;
  }

  <span class="hljs-comment">/*
   * Time for action: Update the requested key mappings and write back
   * the updated mapping table.
   */</span>

  <span class="hljs-keyword">for</span> (i=<span class="hljs-number">0</span>; updatelist[i].keycode; i++) { <span class="hljs-comment">// keycode == 0 is never valid</span>
    <span class="hljs-type">int</span> key = updatelist[i].keycode;
    <span class="hljs-type">int</span> offset = (key - minkey) * keysyms_per_keycode;

    <span class="hljs-keyword">if</span> ((key &lt; minkey) || (key &gt; maxkey)) {
      <span class="hljs-built_in">fprintf</span>(<span class="hljs-built_in">stderr</span>, <span class="hljs-string">"Requested keycode %d is out of range.\n"</span>, key);
      rc = <span class="hljs-number">1</span>;
      <span class="hljs-keyword">goto</span> end;
    }

    <span class="hljs-keyword">for</span> (j=<span class="hljs-number">0</span>; j &lt; update_per_code; j++, offset++) {
      <span class="hljs-type">char</span> *name = updatelist[i].names[j];
      KeySym k = XStringToKeysym(name);

      <span class="hljs-keyword">if</span> (k == NoSymbol) {
	<span class="hljs-built_in">fprintf</span>(<span class="hljs-built_in">stderr</span>, <span class="hljs-string">"Invalid key symbol name \"%s\" for key %d\n"</span>,
		name, key);
	rc = <span class="hljs-number">1</span>;
	<span class="hljs-keyword">goto</span> end;
      }
      keysyms[offset] = k;
    }
  }

  <span class="hljs-built_in">fprintf</span>(<span class="hljs-built_in">stderr</span>, <span class="hljs-string">"The X display may freeze for a few seconds now. "</span>
	  <span class="hljs-string">"Don't worry...\n"</span>);

  usleep(<span class="hljs-number">100000</span>);

  rc = XChangeKeyboardMapping(dpy, minkey, keysyms_per_keycode,
			      keysyms, <span class="hljs-number">1</span>+maxkey-minkey);

  <span class="hljs-keyword">if</span> (rc)
    <span class="hljs-built_in">fprintf</span>(<span class="hljs-built_in">stderr</span>, <span class="hljs-string">"Failed to update keyboard mapping table.\n"</span>);

 end:
  <span class="hljs-keyword">if</span> (keysyms)
    XFree(keysyms);

  <span class="hljs-keyword">if</span> (dpy)
    XCloseDisplay(dpy);

  <span class="hljs-keyword">return</span> rc;
}</pre>
<p>It might be necessary to install Xlib&#8217;s development package, for example</p>
<pre># apt install xutils-dev</pre>
<p>Compilation with:</p>
<pre>$ gcc keymapper.c -o keymapper -Wall -O3 -lX11</pre>
<p>The only obvious change that you may want to do is the entries in updatelist[], so that they match your needs.</p>
<p>Note that this program only changes the first four keysyms of each key code (or what you change @update_per_code to). Rationale: I&#8217;ve never manage to activate the the other entries, so why touch them?</p>
]]></content:encoded>
			<wfw:commentRss>https://billauer.se/blog/2023/11/xmodmap-mapping-swedish/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Linux Mint + Cinnamon: Volume buttons stop to work suddenly</title>
		<link>https://billauer.se/blog/2023/05/cinnamon-volume-buttons-dbus/</link>
		<comments>https://billauer.se/blog/2023/05/cinnamon-volume-buttons-dbus/#comments</comments>
		<pubDate>Wed, 31 May 2023 09:58:16 +0000</pubDate>
		<dc:creator>eli</dc:creator>
				<category><![CDATA[cinnamon]]></category>
		<category><![CDATA[Linux sound]]></category>
		<category><![CDATA[systemd]]></category>

		<guid isPermaLink="false">https://billauer.se/blog/?p=6875</guid>
		<description><![CDATA[The nuisance After trying to fix another problem with Pulseaudio, and messing up a bit with its configuration files, the option to control the volume by virtue of keyboard buttons suddenly stopped to work. The cursor would blink briefly when pressing the button, but nothing else happened. I tried all the fairly normal things, including [...]]]></description>
			<content:encoded><![CDATA[<h3>The nuisance</h3>
<p>After trying to fix another problem with Pulseaudio, and messing up a bit with its configuration files, the option to control the volume by virtue of keyboard buttons suddenly stopped to work. The cursor would blink briefly when pressing the button, but nothing else happened.</p>
<p>I tried all the fairly normal things, including to restart the Pulseaudio daemon, to restart Cinnamon (with <a title="When mplayer plays a black window (or: Cinnamon leaking GPU memory)" href="https://billauer.se/blog/2019/04/cinnamon-gpu-memory-leak-restart/" target="_blank">Alt-F2 + &#8220;r&#8221;</a>), restart the session by changing the user (to the same user), disconnect and reconnect the (USB) keyboard, and a whole lot of other things.</p>
<p>It took me quite some time to fix this, so here&#8217;s what worked for me this time, along with some debug info.</p>
<p>The machine was a Linux Mint 19 with Cinnamon.</p>
<p>At an earlier stage, even the sound applet was gone from its desktop panel. To fix that, I right-clicked the panel, picked Troubleshoot &gt; Looking Glass, and picked the Extension tab. There&#8217;s an applet listed called &#8220;Sound&#8221;. So I right-clicked it, and chose &#8220;Reload Code&#8221;. That got the applet back to the panel, and it worked flawlessly. But then I was stuck with the volume button problem.</p>
<h3>The fix</h3>
<p>What I actually did:</p>
<ul>
<li>Kill the process named csd-keyboard (probably irrelevant)</li>
<li>Kill the process named csd-media-keys</li>
<li>Restart pulseaudio with &#8220;pulseaudio -k&#8221;</li>
</ul>
<p>This was the output of journalctl as a result of these:</p>
<pre>May 31 12:17:03 cinnamon-session[2115]: WARNING: t+1132491.55749s: Application 'cinnamon-settings-daemon-keyboard.desktop' killed by signal 15
May 31 12:17:17 cinnamon-session[2115]: WARNING: t+1132505.78238s: Application 'cinnamon-settings-daemon-media-keys.desktop' killed by signal 15
May 31 12:17:17 rtkit-daemon[2284]: Successfully made thread 4304 of process 4304 (n/a) owned by '1010' high priority at nice level -11.
May 31 12:17:17 rtkit-daemon[2284]: Supervising 8 threads of 4 processes of 1 users.
<span class="punch">May 31 12:17:17 pulseaudio[4304]: [pulseaudio] pid.c: Daemon already running.
</span>May 31 12:18:04 bluetoothd[12009]: Endpoint unregistered: sender=:1.120210 path=/MediaEndpoint/A2DPSource
May 31 12:18:04 bluetoothd[12009]: Endpoint unregistered: sender=:1.120210 path=/MediaEndpoint/A2DPSink
May 31 12:18:04 rtkit-daemon[2284]: Successfully made thread 4345 of process 4345 (n/a) owned by '1010' high priority at nice level -11.
May 31 12:18:04 rtkit-daemon[2284]: Supervising 4 threads of 4 processes of 1 users.
May 31 12:18:04 pulseaudio[4345]: [pulseaudio] sink.c: Default and alternate sample rates are the same.
May 31 12:18:04 rtkit-daemon[2284]: Supervising 3 threads of 3 processes of 1 users.
May 31 12:18:04 rtkit-daemon[2284]: Successfully made thread 4347 of process 4345 (n/a) owned by '1010' RT at priority 5.
May 31 12:18:04 rtkit-daemon[2284]: Supervising 4 threads of 3 processes of 1 users.
May 31 12:18:04 rtkit-daemon[2284]: Supervising 4 threads of 3 processes of 1 users.
May 31 12:18:04 rtkit-daemon[2284]: Successfully made thread 4348 of process 4345 (n/a) owned by '1010' RT at priority 5.
May 31 12:18:04 rtkit-daemon[2284]: Supervising 5 threads of 3 processes of 1 users.
May 31 12:18:04 rtkit-daemon[2284]: Supervising 5 threads of 3 processes of 1 users.
May 31 12:18:04 rtkit-daemon[2284]: Successfully made thread 4349 of process 4345 (n/a) owned by '1010' RT at priority 5.
May 31 12:18:04 rtkit-daemon[2284]: Supervising 6 threads of 3 processes of 1 users.
May 31 12:18:05 rtkit-daemon[2284]: Supervising 6 threads of 3 processes of 1 users.
May 31 12:18:05 rtkit-daemon[2284]: Successfully made thread 4350 of process 4345 (n/a) owned by '1010' RT at priority 5.
May 31 12:18:05 rtkit-daemon[2284]: Supervising 7 threads of 3 processes of 1 users.
May 31 12:18:05 bluetoothd[12009]: Endpoint registered: sender=:1.120482 path=/MediaEndpoint/A2DPSource
May 31 12:18:05 bluetoothd[12009]: Endpoint registered: sender=:1.120482 path=/MediaEndpoint/A2DPSink
May 31 12:18:05 pulseaudio[4345]: [pulseaudio] backend-ofono.c: Failed to register as a handsfree audio agent with ofono: org.freedesktop.DBus.Error.ServiceUnknown: The name org.ofono was not provided by any .service files
May 31 12:18:05 rtkit-daemon[2284]: Successfully made thread 4352 of process 4352 (n/a) owned by '1010' high priority at nice level -11.
May 31 12:18:05 rtkit-daemon[2284]: Supervising 8 threads of 4 processes of 1 users.
May 31 12:18:05 pulseaudio[4352]: [pulseaudio] pid.c: Daemon already running.
May 31 12:18:58 gnome-keyring-daemon[2204]: asked to register item /org/freedesktop/secrets/collection/login/9, but it's already registered</pre>
<p>I suppose that killing csd-media-keys was the part that really did the trick, because that caused a request to start Pulseaudio.</p>
<h3>Why it worked (presumably)</h3>
<p>The cinnamon-settings-daemon is the component responsible for passing the keyboard request to Pulseaudio. Apparently, messing up with Pulseaudio caused one of its components, csd-media-keys, to mess up as well. Killing it caused cinnamon-settings-daemon to restart it automatically. From fresh.</p>
<p>It&#8217;s fine to kill the csd-* processes. Nothing dramatic happens. The killed process is just restarted. But I haven&#8217;t tried to kill cinnamon-settings-daemon itself. I believe it will restart Cinnamon completely, something I wanted to avoid.</p>
<h3>Dbus activity</h3>
<p>I&#8217;ve already <a title="systemd / DBus debugging starter pack" href="https://billauer.se/blog/2019/05/dbus-dump-systemd-debugging/" target="_blank">written a post</a> mentioning how to monitor the Dbus. So here&#8217;s a different take on the same topic.</p>
<p>The difference is quite evident when running dbus-monitor (not as root) as follows in order to monitor the activity for the current session:</p>
<pre>$ dbus-monitor</pre>
<p>This is the output as a result of pressing a volume up button, when it works correctly (i.e. after fixing the problem):</p>
<pre>method call time=1685525392.173838 sender=:<span class="punch">1.6531</span> -&gt; destination=:<span class="punch">1.6616</span> serial=1431 path=/org/cinnamon/SettingsDaemon/KeybindingHandler; interface=org.cinnamon.SettingsDaemon.KeybindingHandler; member=HandleKeybinding
   uint32 2
method call time=1685525392.174967 sender=:1.6616 -&gt; destination=org.freedesktop.DBus serial=566 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=AddMatch
   string "type='signal',interface='ca.desrt.dconf.Writer',path='/ca/desrt/dconf/Writer/user',arg0path='/org/cinnamon/desktop/sound/'"
method return time=1685525392.175012 sender=org.freedesktop.DBus -&gt; destination=:1.6616 serial=382 reply_serial=566
method call time=1685525392.175026 sender=:1.6616 -&gt; destination=:1.6531 serial=567 path=/org/Cinnamon; interface=org.Cinnamon; member=ShowOSD
   array [
      dict entry(
         string "icon"
         variant             string "audio-volume-medium-symbolic"
      )
      dict entry(
         string "level"
         variant             int32 34
      )
   ]
method call time=1685525392.175170 sender=:1.6616 -&gt; destination=org.freedesktop.DBus serial=568 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=RemoveMatch
   string "type='signal',interface='ca.desrt.dconf.Writer',path='/ca/desrt/dconf/Writer/user',arg0path='/org/cinnamon/desktop/sound/'"
method return time=1685525392.175189 sender=org.freedesktop.DBus -&gt; destination=:1.6616 serial=383 reply_serial=568
method call time=1685525392.175198 sender=:1.6616 -&gt; destination=org.freedesktop.DBus serial=569 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=AddMatch
   string "type='signal',interface='ca.desrt.dconf.Writer',path='/ca/desrt/dconf/Writer/user',arg0path='/org/cinnamon/desktop/sound/'"
method return time=1685525392.175216 sender=org.freedesktop.DBus -&gt; destination=:1.6616 serial=384 reply_serial=569
method call time=1685525392.176330 sender=:<span class="punch">1.6618</span> -&gt; destination=org.freedesktop.DBus serial=26 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=RequestName
   string "org.freedesktop.ReserveDevice1.Audio2"
   uint32 5
signal time=1685525392.176383 sender=org.freedesktop.DBus -&gt; destination=(null destination) serial=50 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=NameOwnerChanged
   string "org.freedesktop.ReserveDevice1.Audio2"
   string ""
   string ":1.6618"
signal time=1685525392.176411 sender=org.freedesktop.DBus -&gt; destination=:1.6618 serial=51 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=NameAcquired
   string "org.freedesktop.ReserveDevice1.Audio2"
method return time=1685525392.176427 sender=org.freedesktop.DBus -&gt; destination=:1.6618 serial=52 reply_serial=26
   uint32 1
method return time=1685525392.184853 sender=:1.6616 -&gt; destination=:1.6531 serial=570 reply_serial=1431
method call time=1685525392.184915 sender=:1.6616 -&gt; destination=org.freedesktop.DBus serial=571 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=RemoveMatch
   string "type='signal',interface='ca.desrt.dconf.Writer',path='/ca/desrt/dconf/Writer/user',arg0path='/org/cinnamon/desktop/sound/'"
method return time=1685525392.184937 sender=org.freedesktop.DBus -&gt; destination=:1.6616 serial=385 reply_serial=571
method return time=1685525392.190757 sender=:1.6531 -&gt; destination=:1.6616 serial=1432 reply_serial=567</pre>
<p>Unfortunately, I didn&#8217;t save the output before the fix. But it was exactly two rows of output. As far as I recall, the first and last row from this dump were present when it didn&#8217;t work (i.e. the row involving KeybindingHandler&#8217;s request, and the return method that closed it).</p>
<p>The bus addresses can be listed with the following command:</p>
<pre>$ busctl <span style="color: #ff0000;"><strong>--user</strong></span></pre>
<p>In this specific session the output was:</p>
<pre>NAME                                                       PID PROCESS         USER             CONNECTION    UNIT                      SESSION    DESCRIPTION
:1.0                                                      2103 systemd         eli              :1.0          user@1010.service         -          -
:1.1014                                                  45251 pxgsettings     eli              :1.1014       session-c1.scope          c1         -
:1.1015                                                  45277 scp-dbus-servic eli              :1.1015       user@1010.service         -          -
:1.1016                                                  45277 scp-dbus-servic eli              :1.1016       user@1010.service         -          -
:1.12                                                     2213 csd-a11y-keyboa eli              :1.12         session-c1.scope          c1         -
:1.1234                                                  53331 nemo            eli              :1.1234       session-c1.scope          c1         -
:1.13                                                     2221 csd-a11y-settin eli              :1.13         session-c1.scope          c1         -
:1.131                                                   16564 klauncher       eli              :1.131        session-c1.scope          c1         -
:1.16                                                     2232 csd-cursor      eli              :1.16         session-c1.scope          c1         -
:1.17                                                     2225 csd-color       eli              :1.17         session-c1.scope          c1         -
:1.18                                                     2238 csd-clipboard   eli              :1.18         session-c1.scope          c1         -
:1.19                                                     2242 csd-orientation eli              :1.19         session-c1.scope          c1         -
:1.20                                                     2233 csd-wacom       eli              :1.20         session-c1.scope          c1         -
:1.21                                                     2245 csd-xsettings   eli              :1.21         session-c1.scope          c1         -
:1.22                                                     2248 csd-mouse       eli              :1.22         session-c1.scope          c1         -
:1.24                                                     2256 csd-print-notif eli              :1.24         session-c1.scope          c1         -
:1.26                                                     2258 csd-background  eli              :1.26         session-c1.scope          c1         -
:1.27                                                     2260 gvfsd           eli              :1.27         user@1010.service         -          -
:1.28                                                     2267 csd-housekeepin eli              :1.28         session-c1.scope          c1         -
:1.29                                                     2274 csd-screensaver eli              :1.29         session-c1.scope          c1         -
:1.30                                                     2270 csd-power       eli              :1.30         session-c1.scope          c1         -
:1.31                                                     2299 dconf-service   eli              :1.31         user@1010.service         -          -
:1.32                                                     2285 csd-automount   eli              :1.32         session-c1.scope          c1         -
:1.329                                                   22590 xreader         eli              :1.329        session-c1.scope          c1         -
:1.33                                                     2306 gvfsd-fuse      eli              :1.33         user@1010.service         -          -
:1.330                                                   22596 xreaderd        eli              :1.330        user@1010.service         -          -
:1.332                                                   22606 WebKitNetworkPr eli              :1.332        session-c1.scope          c1         -
:1.35                                                     2313 csd-printer     eli              :1.35         session-c1.scope          c1         -
:1.37                                                     2349 gvfs-udisks2-vo eli              :1.37         user@1010.service         -          -
:1.38                                                     2384 gvfs-gphoto2-vo eli              :1.38         user@1010.service         -          -
:1.39                                                     2277 csd-xrandr      eli              :1.39         session-c1.scope          c1         -
:1.40                                                     2410 gvfs-goa-volume eli              :1.40         user@1010.service         -          -
:1.41                                                     2414 goa-daemon      eli              :1.41         user@1010.service         -          -
:1.42                                                     2427 goa-identity-se eli              :1.42         user@1010.service         -          -
:1.43                                                     2432 gvfs-mtp-volume eli              :1.43         user@1010.service         -          -
:1.44                                                     2436 gvfs-afc-volume eli              :1.44         user@1010.service         -          -
:1.448                                                   31116 gvfsd-http      eli              :1.448        user@1010.service         -          -
:1.457                                                   31367 gvfsd-network   eli              :1.457        user@1010.service         -          -
:1.46                                                     2472 polkit-gnome-au eli              :1.46         session-c1.scope          c1         -
:1.463                                                   31401 gvfsd-dnssd     eli              :1.463        user@1010.service         -          -
:1.47                                                     2481 cinnamon-killer eli              :1.47         session-c1.scope          c1         -
:1.48                                                     2478 nemo-desktop    eli              :1.48         session-c1.scope          c1         -
:1.49                                                     2480 nm-applet       eli              :1.49         session-c1.scope          c1         -
:1.5                                                      2115 cinnamon-sessio eli              :1.5          session-c1.scope          c1         -
:1.50                                                     2474 blueberry-obex- eli              :1.50         session-c1.scope          c1         -
:1.51                                                     2474 blueberry-obex- eli              :1.51         session-c1.scope          c1         -
:1.52                                                     2499 obexd           eli              :1.52         user@1010.service         -          -
:1.54                                                     2506 gvfsd-trash     eli              :1.54         user@1010.service         -          -
:1.55                                                     2512 gvfsd-metadata  eli              :1.55         user@1010.service         -          -
:1.56                                                     2535 python2         eli              :1.56         session-c1.scope          c1         -
:1.5653                                                  62813 chrome          eli              :1.5653       session-c1.scope          c1         -
:1.5654                                                  62813 chrome          eli              :1.5654       session-c1.scope          c1         -
:1.5655                                                  62813 chrome          eli              :1.5655       session-c1.scope          c1         -
:1.5656                                                  62813 chrome          eli              :1.5656       session-c1.scope          c1         -
:1.5661                                                  62813 chrome          eli              :1.5661       session-c1.scope          c1         -
:1.57                                                     2534 cinnamon-screen eli              :1.57         session-c1.scope          c1         -
:1.58                                                     2574 gnome-terminal  eli              :1.58         session-c1.scope          c1         -
:1.5834                                                  52878 xreader         eli              :1.5834       session-c1.scope          c1         -
:1.5836                                                  52891 WebKitNetworkPr eli              :1.5836       session-c1.scope          c1         -
:1.5842                                                  54509 xreader         eli              :1.5842       session-c1.scope          c1         -
:1.5843                                                  54522 WebKitNetworkPr eli              :1.5843       session-c1.scope          c1         -
:1.59                                                     2574 gnome-terminal  eli              :1.59         session-c1.scope          c1         -
:1.6                                                      2115 cinnamon-sessio eli              :1.6          session-c1.scope          c1         -
:1.60                                                     2579 gconfd-2        eli              :1.60         user@1010.service         -          -
:1.61                                                     2574 gnome-terminal  eli              :1.61         session-c1.scope          c1         -
:1.6105                                                  47745 xreader         eli              :1.6105       session-c1.scope          c1         -
:1.6107                                                  47757 WebKitNetworkPr eli              :1.6107       session-c1.scope          c1         -
:1.6477                                                  31538 thunderbird-bin eli              :1.6477       session-c1.scope          c1         -
:1.6478                                                  31538 thunderbird-bin eli              :1.6478       session-c1.scope          c1         -
<span class="punch">:1.6531                                                   2451 cinnamon        eli              :1.6531       session-c1.scope          c1         -
</span>:1.6562                                                  69100 csd-sound       eli              :1.6562       session-c1.scope          c1         -
:1.6592                                                   1641 firefox-bin     eli              :1.6592       session-c1.scope          c1         -
:1.6593                                                   1641 firefox-bin     eli              :1.6593       session-c1.scope          c1         -
:1.6594                                                   1700 Web Content     eli              :1.6594       session-c1.scope          c1         -
:1.6595                                                   1760 WebExtensions   eli              :1.6595       session-c1.scope          c1         -
:1.6596                                                   1824 Web Content     eli              :1.6596       session-c1.scope          c1         -
:1.6597                                                   1876 Web Content     eli              :1.6597       session-c1.scope          c1         -
:1.6598                                                   1975 cinnamon-settin eli              :1.6598       session-c1.scope          c1         -
:1.6599                                                   1975 cinnamon-settin eli              :1.6599       session-c1.scope          c1         -
:1.6608                                                   2640 Web Content     eli              :1.6608       session-c1.scope          c1         -
:1.6609                                                   3399 Web Content     eli              :1.6609       session-c1.scope          c1         -
:1.6615                                                   4286 csd-keyboard    eli              :1.6615       session-c1.scope          c1         -
<span class="punch">:1.6616                                                   4296 csd-media-keys  eli              :1.6616       session-c1.scope          c1         -
</span>:1.6617                                                   4296 csd-media-keys  eli              :1.6617       session-c1.scope          c1         -
<span class="punch">:1.6618                                                   4345 pulseaudio      eli              :1.6618       session-c1.scope          c1         -
</span>:1.6621                                                   4692 xed             eli              :1.6621       session-c1.scope          c1         -
:1.6625                                                   5225 busctl          eli              :1.6625       session-c1.scope          c1         -
:1.67                                                     2860 applet.py       eli              :1.67         session-c1.scope          c1         -
:1.7                                                      2189 at-spi-bus-laun eli              :1.7          user@1010.service         -          -
:1.73                                                     3537 gnome-system-mo eli              :1.73         session-c1.scope          c1         -
:1.8                                                      2196 at-spi2-registr eli              :1.8          user@1010.service         -          -
:1.9                                                      2204 gnome-keyring-d eli              :1.9          session-c1.scope          c1         -
:1.92                                                     8884 xdg-desktop-por eli              :1.92         user@1010.service         -          -
:1.93                                                     8888 xdg-document-po eli              :1.93         user@1010.service         -          -
:1.94                                                     8891 xdg-permission- eli              :1.94         user@1010.service         -          -
:1.95                                                     8902 pxgsettings     eli              :1.95         user@1010.service         -          -
:1.96                                                     8906 xdg-desktop-por eli              :1.96         user@1010.service         -          -
ca.desrt.dconf                                            2299 dconf-service   eli              :1.31         user@1010.service         -          -
ca.desrt.dconf-editor                                        - -               -                (activatable) -                         -
org.Cinnamon                                              2451 cinnamon        eli              :1.6531       session-c1.scope          c1         -
org.Cinnamon.HotplugSniffer                                  - -               -                (activatable) -                         -
org.Cinnamon.LookingGlass                                 2451 cinnamon        eli              :1.6531       session-c1.scope          c1         -
org.Cinnamon.Melange                                         - -               -                (activatable) -                         -
org.Cinnamon.Slideshow                                       - -               -                (activatable) -                         -
org.Nemo                                                 53331 nemo            eli              :1.1234       session-c1.scope          c1         -
org.NemoDesktop                                           2478 nemo-desktop    eli              :1.48         session-c1.scope          c1         -
org.PulseAudio1                                           4345 pulseaudio      eli              :1.6618       session-c1.scope          c1         -
org.a11y.Bus                                              2189 at-spi-bus-laun eli              :1.7          user@1010.service         -          -
org.bluez.obex                                            2499 obexd           eli              :1.52         user@1010.service         -          -
org.cinnamon.ScreenSaver                                  2534 cinnamon-screen eli              :1.57         session-c1.scope          c1         -
org.cinnamon.SettingsDaemon.KeybindingHandler             4296 csd-media-keys  eli              :1.6616       session-c1.scope          c1         -</pre>
<p>So it&#8217;s quite clear that the players here were cinnamon&#8217;s main socket, csd-media-keys and pulseaudio.</p>
]]></content:encoded>
			<wfw:commentRss>https://billauer.se/blog/2023/05/cinnamon-volume-buttons-dbus/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>The sledge hammer: Forcing a permanent screen resolution mode on Linux</title>
		<link>https://billauer.se/blog/2020/08/linux-override-fake-edid/</link>
		<comments>https://billauer.se/blog/2020/08/linux-override-fake-edid/#comments</comments>
		<pubDate>Sun, 02 Aug 2020 07:31:42 +0000</pubDate>
		<dc:creator>eli</dc:creator>
				<category><![CDATA[cinnamon]]></category>
		<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">https://billauer.se/blog/?p=6086</guid>
		<description><![CDATA[When to do this Because Gnome desktop is sure it knows what&#8217;s best for me, and it&#8217;s virtually impossible to just tell it that I want this screen resolution mode and no other, there is only one option left: Lie about the monitor&#8217;s graphics mode capabilities. Make the kernel feed it with fake screen information [...]]]></description>
			<content:encoded><![CDATA[<h3>When to do this</h3>
<p>Because Gnome desktop is sure <a title="Linux: Permanent graphics mode (resolution) on Cinnamon" href="https://billauer.se/blog/2019/08/cinnamon-permanent-resolution-xrandr/" target="_blank">it knows what&#8217;s best for me</a>, and it&#8217;s virtually impossible to just tell it that I want this screen resolution mode and no other, there is only one option left: Lie about the monitor&#8217;s graphics mode capabilities. Make the kernel feed it with fake screen information (EDID), that basically says &#8220;there is only this resolution&#8221;. Leave it with one choice only.</p>
<p>What is EDID? It&#8217;s a tiny chunk of information that is stored on a small EEPROM memory on the monitor. The graphics card fetches this blob through two I2C wires on the cable, and deduces from it what graphics mode (with painfully detailed timing parameters) the monitor supports. It&#8217;s that little hex blob that appears when you go xrandr &#8211;verbose.</p>
<p>I should mention a post in <a href="https://forums.gentoo.org/viewtopic-t-984216-start-0.html" target="_blank">Gentoo forum</a>, which suggests making X ignore EDID info by using</p>
<pre>Option       "UseEDID" "false"
Option       "UseEDIDFreqs" "false"</pre>
<p>in /etc/X11/xorg.conf, or is it a file in /usr/share/X11/xorg.conf.d/? And then just set the screen mode old-school. Didn&#8217;t bother to check this. There are too many players in this game. Faking EDID seemed to be a much better idea than to ask politely not to consider it.</p>
<h3>How to feed a fake EDID</h3>
<p>The name of the game is <a href="https://wiki.archlinux.org/index.php/Kernel_mode_setting" target="_blank">Kernel Mode Setting</a> (KMS). Among others, it allows loading a file from /lib/firmware which is used as the screen information (EDID) instead of getting it from the screen.</p>
<p>For this to work, the CONFIG_DRM_LOAD_EDID_FIRMWARE kernel compilation must be enabled (set to &#8220;y&#8221;).</p>
<p>Note that unless Early KMS is required, the firmware file is loaded after the initramfs stage. In other words, it&#8217;s not necessary to push the fake EDID file into the initramfs, but it&#8217;s OK to have it present only in the filesystem that is mounted after the initramfs.</p>
<p>The EDID file should be stored in /lib/firmware/edid (create the directory if necessary) and the following command should be added to the kernel command line:</p>
<pre>drm_kms_helper.edid_firmware=edid/fake_edid.bin</pre>
<p>(for kernels 4.15 and later, there&#8217;s a drm.edid_firmware parameter that is supposed to be better in some way).</p>
<h3>Generating a custom EDID file</h3>
<p>I needed a special graphics mode to <a title="LG OLED with a Linux computer: Getting that pitch black" href="https://billauer.se/blog/2020/06/lg-oled-linux-hdmi-black-level/" target="_blank">solve a problem with my OLED screen</a>. Meaning I had to cook my own EDID file. It turned out quite easy, actually.</p>
<p>The kernel&#8217;s doc for this is Documentation/admin-guide/edid.rst</p>
<p>In the kernel&#8217;s tools/edid, edit one of the asm files (e.g. 1920x1080.S) and set the parameters to the correct mode. This file has just defines. The actual data format is produced in edid.S, which is included at the bottom. The output in this case is 1920x1080.bin. Note that the C file (1920x1080.c) is an output as well in this case &#8212; for reference of some other use, I guess.</p>
<p>And then just type &#8220;make&#8221; in tools/edid/ (don&#8217;t compile the kernel, that&#8217;s really not necessary for this).</p>
<p>The numbers in the asm file are in a slightly different notation, as explained in the kernel doc. Not a big deal to figure out.</p>
<p>In my case, I translated this xrandr mode line</p>
<pre>  oledblack (0x10b) 173.000MHz -HSync +VSync
        h: width  1920 start 2048 end 2248 total 2576 skew    0 clock  67.16KHz
        v: height 1080 start 1083 end 1088 total 1120           clock  59.96Hz</pre>
<p>to this:</p>
<pre>/* EDID */
#define VERSION 1
#define REVISION 3

/* Display */
#define CLOCK 173000 /* kHz */
#define XPIX 1920
#define YPIX 1080
#define XY_RATIO XY_RATIO_16_9
#define XBLANK 656
#define YBLANK 40
#define XOFFSET 128
#define XPULSE 200
#define YOFFSET 3
#define YPULSE 5
#define DPI 96
#define VFREQ 60 /* Hz */
#define TIMING_NAME "Linux FHD"
/* No ESTABLISHED_TIMINGx_BITS */
#define HSYNC_POL 0
#define VSYNC_POL 0

#include "edid.S"</pre>
<p>There seems to be a distinction between standard resolution modes and those that aren&#8217;t. I got away with this, because 1920x1080 is a standard mode. It may be slightly trickier with a non-standard mode.</p>
<h3>When it works</h3>
<p>This is what it looks like when all is well. First, the kernel logs. In my case, because I didn&#8217;t put the file in the initramfs, loading it fails twice:</p>
<pre>[    3.517734] platform HDMI-A-3: Direct firmware load for edid/1920x1080.bin failed with error -2
[    3.517800] [drm:drm_load_edid_firmware [drm_kms_helper]] *ERROR* Requesting EDID firmware "edid/1920x1080.bin" failed (err=-2)</pre>
<p>and again:</p>
<pre>[    4.104528] platform HDMI-A-3: Direct firmware load for edid/1920x1080.bin failed with error -2
[    4.104580] [drm:drm_load_edid_firmware [drm_kms_helper]] *ERROR* Requesting EDID firmware "edid/1920x1080.bin" failed (err=-2)</pre>
<p>But then, much later, it loads properly:</p>
<pre>[   19.864966] [drm] Got external EDID base block and 0 extensions from "edid/1920x1080.bin" for connector "HDMI-A-3"
[   93.298915] [drm] Got external EDID base block and 0 extensions from "edid/1920x1080.bin" for connector "HDMI-A-3"
[  109.573124] [drm] Got external EDID base block and 0 extensions from "edid/1920x1080.bin" for connector "HDMI-A-3"
[ 1247.290084] [drm] Got external EDID base block and 0 extensions from "edid/1920x1080.bin" for connector "HDMI-A-3"</pre>
<p>Why several times? Well, the screen resolution is probably set up several times as the system goes up. There&#8217;s clearly a quick screen flash a few seconds after the desktop goes up. I don&#8217;t know exactly why, and at this stage I don&#8217;t care. The screen is at the only mode allowed, and that&#8217;s it.</p>
<p>And now to how xrandr sees the situation:</p>
<pre>$ <strong>xrandr -d :0 --verbose</strong>
<span style="color: #888888;"><em>[ ... ]</em></span>
HDMI3 connected primary 1920x1080+0+0 (0x10c) normal (normal left inverted right x axis y axis) 500mm x 281mm
 Identifier: 0x48
 Timestamp:  21339
 Subpixel:   unknown
 Gamma:      1.0:1.0:1.0
 Brightness: 1.0
 Clones:   
 CRTC:       0
 CRTCs:      0
 Transform:  1.000000 0.000000 0.000000
 0.000000 1.000000 0.000000
 0.000000 0.000000 1.000000
 filter:
 EDID:
 00ffffffffffff0031d8000000000000
 051601036d321c78ea5ec0a4594a9825
 205054000000d1c00101010101010101
 010101010101944380907238284080c8
 3500f41911000018000000ff004c696e
 75782023300a20202020000000fd003b
 3d424412000a202020202020000000fc
 004c696e7578204648440a2020200045
 aspect ratio: Automatic
 supported: Automatic, 4:3, 16:9
 Broadcast RGB: Automatic
 supported: Automatic, Full, Limited 16:235
 audio: auto
 supported: force-dvi, off, auto, on
 1920x1080 (0x10c) 173.000MHz -HSync -VSync *current +preferred
 h: width  1920 start 2048 end 2248 total 2576 skew    0 clock  67.16KHz
 v: height 1080 start 1083 end 1088 total 1120           clock  59.96Hz</pre>
<p>Compare the EDID part with 1920x1080.c, which was created along with the binary:</p>
<pre>{
 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
 0x31, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x05, 0x16, 0x01, 0x03, 0x6d, 0x32, 0x1c, 0x78,
 0xea, 0x5e, 0xc0, 0xa4, 0x59, 0x4a, 0x98, 0x25,
 0x20, 0x50, 0x54, 0x00, 0x00, 0x00, 0xd1, 0xc0,
 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x94, 0x43,
 0x80, 0x90, 0x72, 0x38, 0x28, 0x40, 0x80, 0xc8,
 0x35, 0x00, 0xf4, 0x19, 0x11, 0x00, 0x00, 0x18,
 0x00, 0x00, 0x00, 0xff, 0x00, 0x4c, 0x69, 0x6e,
 0x75, 0x78, 0x20, 0x23, 0x30, 0x0a, 0x20, 0x20,
 0x20, 0x20, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x3b,
 0x3d, 0x42, 0x44, 0x12, 0x00, 0x0a, 0x20, 0x20,
 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0xfc,
 0x00, 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x20, 0x46,
 0x48, 0x44, 0x0a, 0x20, 0x20, 0x20, 0x00, 0x45,
};</pre>
<p>So it definitely took the bait.</p>
]]></content:encoded>
			<wfw:commentRss>https://billauer.se/blog/2020/08/linux-override-fake-edid/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>LG OLED with a Linux computer: Getting that pitch black</title>
		<link>https://billauer.se/blog/2020/06/lg-oled-linux-hdmi-black-level/</link>
		<comments>https://billauer.se/blog/2020/06/lg-oled-linux-hdmi-black-level/#comments</comments>
		<pubDate>Sat, 27 Jun 2020 05:58:51 +0000</pubDate>
		<dc:creator>eli</dc:creator>
				<category><![CDATA[cinnamon]]></category>
		<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">https://billauer.se/blog/?p=6061</guid>
		<description><![CDATA[Introduction So I got myself an LG OLED65B9. It&#8217;s huge and a really nice piece of electronics. I opted out the bells and whistles, and connected it via HDMI to my already existing media computer, running Linux Mint 18.1. All I wanted was a plain (yet very high quality) display. However at some point I [...]]]></description>
			<content:encoded><![CDATA[<h3>Introduction</h3>
<p>So I got myself an LG OLED65B9. It&#8217;s huge and a really nice piece of electronics. I opted out the bells and whistles, and connected it via HDMI to my already existing media computer, running Linux Mint 18.1. All I wanted was a plain (yet very high quality) display.</p>
<p>However at some point I noticed that black wasn&#8217;t displayed as black. I opened GIMP, drew a huge black rectangle, and it displayed as dark grey. At first I thought that the screen was defective (or that I was overly optimistic expecting that black would be complete darkness), but then I tried an image from a USB stick, and reassured myself that black is displayed as complete darkness. As it should. Or why did I pay extra for an OLED?</p>
<p>Because I skipped the &#8220;play with the new toy&#8221; phase with this display, I&#8217;m 100% it&#8217;s with its factory settings. It&#8217;s not something I messed up.</p>
<p>I should mention that I use plain HD resolution of 1920x1080. The screen can do much better than that (see list of resolutions below), and defaults at 3840x2160 with my computer, but it&#8217;s quite pointless: Don&#8217;t know about you, I have nothing to show that goes higher than 1080p. And the computer&#8217;s graphics stutters at 4k UHD. So why push it?</p>
<p>I have a <a href="https://billauer.se/blog/2019/08/cinnamon-permanent-resolution-xrandr/" target="_blank">previous post</a> on graphics modes, and <a href="https://billauer.se/blog/2017/03/brix-linux-media-center-notes/" target="_blank">one on the setup</a> of the Brix media center computer involved.</p>
<h3>So why is black displayed LCD style?</h3>
<p>The truth is that I don&#8217;t know for sure. But it seems to be a problem only with standard 16:9 graphics modes. When switching to modes that are typical for computers (5:4 and 4:3 aspect ratios), the image was stretched to the entire screen, and black areas showed as pitch black. I&#8217;m not sure about this conclusion, and even less do I have an idea why this would happen or why a properly designed display would &#8220;correct&#8221; a pixel that arrives as RGB all zeros to something brighter.</p>
<p>Also, the black level on text consoles (Ctrl-Shift-F1 style) is horrible. But I&#8217;m not sure about which resolution they use.</p>
<p>An idea that crossed my mind is that maybe the pixels are sent as YCbCr in some modes or maybe the computer goes &#8220;Hey, I&#8217;m a TV now, let&#8217;s do some color correction nobody asked for&#8221; when standard HDTV aspect ratios are used. If any, I would go for the second possibility. But xrandr&#8217;s verbose output implies that both brightness and gamma are set to 1.0 for the relevant HDMI output, even when black isn&#8217;t black.</p>
<p>The graphics adapter is Intel Celeron J3160&#8242;s on-chip &#8220;HD Graphics&#8221; processor (8086:22b1) so nothing fancy here.</p>
<p><strong>Update, 24.2.21:</strong> It actually seems like there&#8217;s an explanation. The  computer uses the i915 module on a Linux kernel 4.4.0-53-generic. Why is  that important? Well, look at the output of xrandr below. It says  &#8220;Broadcast RGB: Automatic&#8221;. That means that the color range is set  automatically by the driver. And indeed one of the options is &#8220;Limited  16:235&#8243; which means that the darkest black is actually level 16 out of  255, as mentioned <a href="https://wiki.archlinux.org/index.php/Intel_graphics#Weathered_colors_(color_range_problems)" target="_blank">here</a>, and passionately discussed <a href="https://bugs.freedesktop.org/show_bug.cgi?id=107476" target="_blank">here</a> and <a href="https://bugzilla.kernel.org/show_bug.cgi?id=94921" target="_blank">here</a>.</p>
<p>The automatic mode was added to the driver in kernel commit <a href="https://github.com/torvalds/linux/commit/55bc60db5988c8366751d3d04dd690698a53412c" target="_blank">55bc60db5988c8366751d3d04dd690698a53412c</a>.</p>
<p>The interesting part seems to be this change in  drivers/gpu/drm/i915/intel_hdmi.c (became  drivers/gpu/drm/i915/display/intel_hdmi.c later):</p>
<pre>+	if (intel_hdmi-&gt;color_range_auto) {
+		/* See CEA-861-E - 5.1 Default Encoding Parameters */
+		if (intel_hdmi-&gt;has_hdmi_sink &amp;&amp;
+		    drm_mode_cea_vic(adjusted_mode) &gt; 1)
+			intel_hdmi-&gt;color_range = SDVO_COLOR_RANGE_16_235;
+		else
+			intel_hdmi-&gt;color_range = 0;
+	}</pre>
<p>The call to drm_mode_cea_vic() apparently says, that if there&#8217;s a  known Video Identification Code (VIC) for the timing parameters in use  (i.e., there&#8217;s a standard mode corresponding what is used), then the  limited color range is applied. Why? Because. I don&#8217;t know if this was  fixed since.</p>
<p>Thanks to Nate Long for pointing out the discussions on the kernel module.</p>
<h3>The fix</h3>
<p>This just worked for me, and I didn&#8217;t feel like playing with it further. So I can&#8217;t assure that this is a consistent solution, but it actually seems that way.</p>
<p>The idea is that since the problem arises with standard 16:9 modes, maybe make up a non-standard one?</p>
<p>Unlike <a href="https://billauer.se/blog/2019/08/cinnamon-permanent-resolution-xrandr/" target="_blank">the case</a> with my previous TV, using cvt to calculate the timing parameters turned out to be a good idea.</p>
<pre>$ <strong>cvt 1920 1080 60</strong>
# 1920x1080 59.96 Hz (CVT 2.07M9) hsync: 67.16 kHz; pclk: 173.00 MHz
Modeline "1920x1080_60.00"  173.00  1920 2048 2248 2576  1080 1083 1088 1120 -hsync +vsync
$ <strong>xrandr -d :0 --newmode "try" 173.00  1920 2048 2248 2576  1080 1083 1088 1120 -hsync +vsync</strong>
$ <strong>xrandr -d :0 --addmode HDMI3 try</strong>
$ <strong>xrandr -d :0 --output HDMI3 --mode try</strong></pre>
<p>At this point I got a proper 1920x1080 on the screen, with black pixels as dark as when the display is powered off. The output of xrandr after this was somewhat unexpected, yet functionally what I wanted:</p>
<pre>$ <strong>xrandr -d :0 --verbose</strong></pre>
<pre>  1280x720 (0x4b) 74.250MHz +HSync +VSync +preferred
        h: width  1280 start 1390 end 1430 total 1650 skew    0 clock  45.00KHz
        v: height  720 start  725 end  730 total  750           clock  60.00Hz
<strong><span style="color: #ff0000;">  1920x1080 (0x141) 173.000MHz -HSync +VSync *current
        h: width  1920 start 2048 end 2248 total 2576 skew    0 clock  67.16KHz
        v: height 1080 start 1083 end 1088 total 1120           clock  59.96Hz
</span></strong>  1920x1080 (0x10c) 148.500MHz +HSync +VSync
        h: width  1920 start 2008 end 2052 total 2200 skew    0 clock  67.50KHz
        v: height 1080 start 1084 end 1089 total 1125           clock  60.00Hz
<span style="color: #888888;"><em> [ ... ]</em></span>
  try (0x13e) 173.000MHz -HSync +VSync
        h: width  1920 start 2048 end 2248 total 2576 skew    0 clock  67.16KHz
        v: height 1080 start 1083 end 1088 total 1120           clock  59.96Hz</pre>
<p>So the mode in effect didn&#8217;t turn out the one I generated (&#8220;try&#8221;), but a replica of its parameters, marked as 0x141 (and 0x13a on another occasion). This mode wasn&#8217;t there before.</p>
<p>I&#8217;m don&#8217;t quite understand how this happened. Maybe Cinnamon&#8217;s machinery did this. It kind of gets in the way all the time, and at times it didn&#8217;t let me set just any mode I liked with xrandr, so maybe that. This whole thing with graphics modes is completely out of control.</p>
<p>I should mention that there is no problem with sound in this mode (or any other situation I tried). Not that there should be, but at some point I thought maybe there would be, because the mode implies a computer and not a TV-something. But no issues at all. Actually, the screen&#8217;s loudspeakers are remarkably good, with a surprisingly present bass, but that&#8217;s a different story.</p>
<p>As for making this special mode permanent, that turned out to be a problem in itself. <a title="The sledge hammer: Setting a permanent screen resolution mode on Linux" href="https://billauer.se/blog/2020/08/linux-override-fake-edid/" target="_blank">This post</a> shows how I eventually solved it.</p>
<h3>List of graphics modes</h3>
<p>Just in case this interests anyone, this is the output of a full resolution list:</p>
<pre>$ <strong>xrandr -d :0 --verbose
</strong><em><span style="color: #888888;">[ ... ]</span></em>
HDMI3 connected primary 3840x2160+0+0 (0x1ba) normal (normal left inverted right x axis y axis) 1600mm x 900mm
	Identifier: 0x48
	Timestamp:  -1469585217
	Subpixel:   unknown
	Gamma:      1.0:1.0:1.0
	Brightness: 1.0
	Clones:
	CRTC:       0
	CRTCs:      0
	Transform:  1.000000 0.000000 0.000000
	            0.000000 1.000000 0.000000
	            0.000000 0.000000 1.000000
	           filter:
	EDID:
		00ffffffffffff001e6da0c001010101
		011d010380a05a780aee91a3544c9926
		0f5054a1080031404540614071408180
		d1c00101010104740030f2705a80b058
		8a0040846300001e023a801871382d40
		582c450040846300001e000000fd0018
		781e871e000a202020202020000000fc
		004c472054560a20202020202020012d
		02035af1565f101f0413051403021220
		212215015d5e6263643f403209570715
		07505707016704033d1ec05f7e016e03
		0c001000b83c20008001020304e200cf
		e305c000e50e60616566eb0146d0002a
		1803257d76ace3060d01662150b05100
		1b304070360040846300001e00000000
		0000000000000000000000000000008b
	aspect ratio: Automatic
		supported: Automatic, 4:3, 16:9
	Broadcast RGB: Automatic
		supported: Automatic, Full, Limited 16:235
	audio: auto
		supported: force-dvi, off, auto, on
  3840x2160 (0x1ba) 297.000MHz +HSync +VSync *current +preferred
        h: width  3840 start 4016 end 4104 total 4400 skew    0 clock  67.50KHz
        v: height 2160 start 2168 end 2178 total 2250           clock  30.00Hz
  4096x2160 (0x1bb) 297.000MHz +HSync +VSync
        h: width  4096 start 5116 end 5204 total 5500 skew    0 clock  54.00KHz
        v: height 2160 start 2168 end 2178 total 2250           clock  24.00Hz
  4096x2160 (0x1bc) 296.703MHz +HSync +VSync
        h: width  4096 start 5116 end 5204 total 5500 skew    0 clock  53.95KHz
        v: height 2160 start 2168 end 2178 total 2250           clock  23.98Hz
  3840x2160 (0x1bd) 297.000MHz +HSync +VSync
        h: width  3840 start 4896 end 4984 total 5280 skew    0 clock  56.25KHz
        v: height 2160 start 2168 end 2178 total 2250           clock  25.00Hz
  3840x2160 (0x1be) 297.000MHz +HSync +VSync
        h: width  3840 start 5116 end 5204 total 5500 skew    0 clock  54.00KHz
        v: height 2160 start 2168 end 2178 total 2250           clock  24.00Hz
  3840x2160 (0x1bf) 296.703MHz +HSync +VSync
        h: width  3840 start 4016 end 4104 total 4400 skew    0 clock  67.43KHz
        v: height 2160 start 2168 end 2178 total 2250           clock  29.97Hz
  3840x2160 (0x1c0) 296.703MHz +HSync +VSync
        h: width  3840 start 5116 end 5204 total 5500 skew    0 clock  53.95KHz
        v: height 2160 start 2168 end 2178 total 2250           clock  23.98Hz
  1920x1080 (0x1c1) 297.000MHz +HSync +VSync
        h: width  1920 start 2008 end 2052 total 2200 skew    0 clock 135.00KHz
        v: height 1080 start 1084 end 1089 total 1125           clock 120.00Hz
  1920x1080 (0x1c2) 297.000MHz +HSync +VSync
        h: width  1920 start 2448 end 2492 total 2640 skew    0 clock 112.50KHz
        v: height 1080 start 1084 end 1094 total 1125           clock 100.00Hz
  1920x1080 (0x1c3) 296.703MHz +HSync +VSync
        h: width  1920 start 2008 end 2052 total 2200 skew    0 clock 134.87KHz
        v: height 1080 start 1084 end 1089 total 1125           clock 119.88Hz
  1920x1080 (0x16c) 148.500MHz +HSync +VSync
        h: width  1920 start 2008 end 2052 total 2200 skew    0 clock  67.50KHz
        v: height 1080 start 1084 end 1089 total 1125           clock  60.00Hz
  1920x1080 (0x1c4) 148.500MHz +HSync +VSync
        h: width  1920 start 2448 end 2492 total 2640 skew    0 clock  56.25KHz
        v: height 1080 start 1084 end 1089 total 1125           clock  50.00Hz
  1920x1080 (0x16d) 148.352MHz +HSync +VSync
        h: width  1920 start 2008 end 2052 total 2200 skew    0 clock  67.43KHz
        v: height 1080 start 1084 end 1089 total 1125           clock  59.94Hz
  1920x1080i (0x10c) 74.250MHz +HSync +VSync Interlace
        h: width  1920 start 2008 end 2052 total 2200 skew    0 clock  33.75KHz
        v: height 1080 start 1084 end 1094 total 1125           clock  60.00Hz
  1920x1080i (0x10d) 74.250MHz +HSync +VSync Interlace
        h: width  1920 start 2448 end 2492 total 2640 skew    0 clock  28.12KHz
        v: height 1080 start 1084 end 1094 total 1125           clock  50.00Hz
  1920x1080 (0x1c5) 74.250MHz +HSync +VSync
        h: width  1920 start 2008 end 2052 total 2200 skew    0 clock  33.75KHz
        v: height 1080 start 1084 end 1089 total 1125           clock  30.00Hz
  1920x1080 (0x1c6) 74.250MHz +HSync +VSync
        h: width  1920 start 2448 end 2492 total 2640 skew    0 clock  28.12KHz
        v: height 1080 start 1084 end 1089 total 1125           clock  25.00Hz
  1920x1080 (0x1c7) 74.250MHz +HSync +VSync
        h: width  1920 start 2558 end 2602 total 2750 skew    0 clock  27.00KHz
        v: height 1080 start 1084 end 1089 total 1125           clock  24.00Hz
  1920x1080i (0x10e) 74.176MHz +HSync +VSync Interlace
        h: width  1920 start 2008 end 2052 total 2200 skew    0 clock  33.72KHz
        v: height 1080 start 1084 end 1094 total 1125           clock  59.94Hz
  1920x1080 (0x1c8) 74.176MHz +HSync +VSync
        h: width  1920 start 2008 end 2052 total 2200 skew    0 clock  33.72KHz
        v: height 1080 start 1084 end 1089 total 1125           clock  29.97Hz
  1920x1080 (0x1c9) 74.176MHz +HSync +VSync
        h: width  1920 start 2558 end 2602 total 2750 skew    0 clock  26.97KHz
        v: height 1080 start 1084 end 1089 total 1125           clock  23.98Hz
  1280x1024 (0x1b5) 108.000MHz +HSync +VSync
        h: width  1280 start 1328 end 1440 total 1688 skew    0 clock  63.98KHz
        v: height 1024 start 1025 end 1028 total 1066           clock  60.02Hz
  1360x768 (0x4b) 85.500MHz +HSync +VSync
        h: width  1360 start 1424 end 1536 total 1792 skew    0 clock  47.71KHz
        v: height  768 start  771 end  777 total  795           clock  60.02Hz
  1152x864 (0x1ca) 81.579MHz -HSync +VSync
        h: width  1152 start 1216 end 1336 total 1520 skew    0 clock  53.67KHz
        v: height  864 start  865 end  868 total  895           clock  59.97Hz
  1280x720 (0x110) 74.250MHz +HSync +VSync
        h: width  1280 start 1390 end 1430 total 1650 skew    0 clock  45.00KHz
        v: height  720 start  725 end  730 total  750           clock  60.00Hz
  1280x720 (0x111) 74.250MHz +HSync +VSync
        h: width  1280 start 1720 end 1760 total 1980 skew    0 clock  37.50KHz
        v: height  720 start  725 end  730 total  750           clock  50.00Hz
  1280x720 (0x112) 74.176MHz +HSync +VSync
        h: width  1280 start 1390 end 1430 total 1650 skew    0 clock  44.96KHz
        v: height  720 start  725 end  730 total  750           clock  59.94Hz
  1024x768 (0x113) 65.000MHz -HSync -VSync
        h: width  1024 start 1048 end 1184 total 1344 skew    0 clock  48.36KHz
        v: height  768 start  771 end  777 total  806           clock  60.00Hz
  800x600 (0x115) 40.000MHz +HSync +VSync
        h: width   800 start  840 end  968 total 1056 skew    0 clock  37.88KHz
        v: height  600 start  601 end  605 total  628           clock  60.32Hz
  720x576 (0x116) 27.000MHz -HSync -VSync
        h: width   720 start  732 end  796 total  864 skew    0 clock  31.25KHz
        v: height  576 start  581 end  586 total  625           clock  50.00Hz
  720x576i (0x117) 13.500MHz -HSync -VSync Interlace
        h: width   720 start  732 end  795 total  864 skew    0 clock  15.62KHz
        v: height  576 start  580 end  586 total  625           clock  50.00Hz
  720x480 (0x118) 27.027MHz -HSync -VSync
        h: width   720 start  736 end  798 total  858 skew    0 clock  31.50KHz
        v: height  480 start  489 end  495 total  525           clock  60.00Hz
  720x480 (0x119) 27.000MHz -HSync -VSync
        h: width   720 start  736 end  798 total  858 skew    0 clock  31.47KHz
        v: height  480 start  489 end  495 total  525           clock  59.94Hz
  640x480 (0x11c) 25.200MHz -HSync -VSync
        h: width   640 start  656 end  752 total  800 skew    0 clock  31.50KHz
        v: height  480 start  490 end  492 total  525           clock  60.00Hz
  640x480 (0x11d) 25.175MHz -HSync -VSync
        h: width   640 start  656 end  752 total  800 skew    0 clock  31.47KHz
        v: height  480 start  490 end  492 total  525           clock  59.94Hz
  720x400 (0x1cb) 28.320MHz -HSync +VSync
        h: width   720 start  738 end  846 total  900 skew    0 clock  31.47KHz
        v: height  400 start  412 end  414 total  449           clock  70.08Hz

<strong></strong></pre>
<p>So it even supports fallback mode with a 25.175 MHz clock if one really insists.</p>
]]></content:encoded>
			<wfw:commentRss>https://billauer.se/blog/2020/06/lg-oled-linux-hdmi-black-level/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Linux: Permanent graphics mode (resolution) on Cinnamon</title>
		<link>https://billauer.se/blog/2019/08/cinnamon-permanent-resolution-xrandr/</link>
		<comments>https://billauer.se/blog/2019/08/cinnamon-permanent-resolution-xrandr/#comments</comments>
		<pubDate>Sun, 04 Aug 2019 04:04:14 +0000</pubDate>
		<dc:creator>eli</dc:creator>
				<category><![CDATA[cinnamon]]></category>
		<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">https://billauer.se/blog/?p=5816</guid>
		<description><![CDATA[The goal Quite simple: Set a fixed graphics mode on the computer screen. More precisely, make Cinnamon (version 3.2.6) on Linux Mint 18.1 (Serena) show the desktop with a predefined resolution, no matter what happens. Spoiler: I failed. But I got close enough for practical purposes, and collected a lot of knowledge while trying. So [...]]]></description>
			<content:encoded><![CDATA[<h3>The goal</h3>
<p>Quite simple: Set a fixed graphics mode on the computer screen.</p>
<p>More precisely, make Cinnamon (version 3.2.6) on Linux Mint 18.1 (Serena) show the desktop with a predefined resolution, no matter what happens. Spoiler: I failed. But I got close enough for practical purposes, and collected a lot of knowledge while trying. So here it is.</p>
<p>The reason I need this: On the machine mentioned <a href="https://billauer.se/blog/2017/03/brix-linux-media-center-notes/" target="_blank">here</a>,  I have an two screens connected through an HDMI splitter, so the monitor identification is somewhat shaky, and it&#8217;s not clear which piece of info the computer gets each time. To make it even trickier, the graphics mode I need is only listed in the EDID information submitted by one of the monitors. In other words: More often than not, the computer doesn&#8217;t know it&#8217;s allowed to use the mode I want it to use.</p>
<p>This situation meets the somewhat arrogant &#8220;I know what&#8217;s best, I never fail&#8221; attitude often seen by graphics software. There is more than one automatic mechanism for changing the resolution to &#8220;what is correct&#8221;, so just changing the resolution with xrandr doesn&#8217;t cut. The underlying mechanisms seem to change frequently from one version to another, and having them documented is probably too much to ask for. It seems like there are some race conditions taking place between different utilities that have a say on this matter. Possibly the reason for the problem I tried to solve on <a href="https://billauer.se/blog/2017/12/linux-mint-blank-screen/" target="_blank">this post</a>.</p>
<p>For clarity: EDID is a chunk of data that is typically stored on a small flash memory on the monitor. This data is fetched through I2C wires that are part of an DVI / HDMI / VGA connector when the monitor is plugged in. This is how the computer knows not only the commercial name of the monitor, but also what graphics modes it supports and prefers.</p>
<p><strong>I have <a title="The sledge hammer: Setting a permanent screen resolution mode on Linux" href="https://billauer.se/blog/2020/08/linux-override-fake-edid/" target="_blank">another post</a> which solves this in a more aggressive way</strong>, and also one with a <a title="LG OLED with a Linux computer: Getting that pitch black" href="https://billauer.se/blog/2020/06/lg-oled-linux-hdmi-black-level/" target="_blank">related discussion</a> regarding an newer OLED display.</p>
<h3>How cinnamon selects the resolution to use</h3>
<p>So &#8212; the first question is: How does (my very specific) Cinnamon determine which screen resolution is the &#8220;correct&#8221; one?</p>
<p>This is a journey into the realm of mystery and uncertainty, but it seems like the rationale is to remember previously connected monitors, along with a separate user-selected graphics mode for each.</p>
<p>So the steps are probably something like:</p>
<ul>
<li>Grab the list of allowed resolution modes, as presented by xrandr, for the relevant monitor (through libxrandr?). This is typically the set of modes listed in the monitor&#8217;s EDID information, but it&#8217;s possible to add modes as well (see below).</li>
<li>If there&#8217;s a user logged in, look up .config/monitors.xml in that user&#8217;s home directory. If there&#8217;s a match between the monitor&#8217;s product identification, apply the selected resolution. This file is changed by Cinnamon&#8217;s Display setting utility (among others, I guess), and presents the user&#8217;s preferences.</li>
<li>There&#8217;s possibly also a globally default monitor.xml at /etc/gnome-settings-daemon/xrandr/. I don&#8217;t have such file, and it&#8217;s not clear if it&#8217;s in effect had it existed. I haven&#8217;t tried this one.</li>
<li>If there&#8217;s no matching (or adequate?) mode setting in monitor.xml (or no user logged in), choose the preferred mode, as pointed at by xrandr.</li>
</ul>
<p>This way or another, monitors.xml only lists width, height and rate for each graphics mode, without the timing details that are required to run it properly. So if the resolution requested in monitors.xml isn&#8217;t listed by xrandr, there is no way to request it, as there is crucial information missing. This isn&#8217;t supposed to happen ever, since the utility that sets the user&#8217;s preferences isn&#8217;t supposed to select a mode that the monitor doesn&#8217;t support. But if it does, the logical thing would be to ignore the resolution in monitors.xml, and go on with the monitor&#8217;s preferred mode. In reality, it appears like this causes the blank screen that I&#8217;ve mentioned on <a href="https://billauer.se/blog/2017/12/linux-mint-blank-screen/" target="_blank">this post</a>.</p>
<p>The automatic setting of resolution seems to take place when some kind of X session starts (the login screen and after the user logs in) as well as when a new monitor is hotplugged. Setting a monitor&#8217;s mode with xrandr seems to trigger an automatic setting as well sometimes. Having tried to set the resolution with xrandr a few times, it reverts sometimes to the automatic setting, and sometimes it stays with the one I set. Go figure.</p>
<p>It seems to be related to Cinnamon&#8217;s setting daemon (executed as /usr/lib/x86_64-linux-gnu/cinnamon-settings-daemon/csd-xrandr), which, according to <a href="https://superuser.com/questions/968190/unable-to-change-screen-settings-on-linux-mint-settingsdaemon-was-not-provided/1002218" target="_blank">this thread</a>, can be turned off by going to Menu &gt; Startup Applications and switch off &#8220;Cinnamon Setting Daemon &#8211; xrandr&#8221; (that simple?!). It has also been suggested to remove ~/.config/autostart/cinnamon-settings-daemon-xrandr.desktop, but I don&#8217;t have such file on my computer. Anyhow, I discovered this possibility after solving my own problem in another way, so I didn&#8217;t get further into this.</p>
<h3>How I got it done (hopefully)</h3>
<p><strong>IMPORTANT</strong>: I&#8217;ve added <a title="The sledge hammer: Setting a permanent screen resolution mode on Linux" href="https://billauer.se/blog/2020/08/linux-override-fake-edid/" target="_blank">another post</a> on how to really nail down the graphics mode, even if the trick below fails.</p>
<p>Since there are all kinds of ghosts in the system that insist on &#8220;fixing&#8221; the display resolution, I might as well play along. So the trick is as follows:</p>
<ul>
<li>Edit ~/.config/monitors.xml (manually), setting the resolution for <strong>all monitors listed</strong> to the one I want.</li>
<li>Make sure that the desired graphics mode, along with its timing parameters, is listed by xrandr, even if the monitor didn&#8217;t mention it in its EDID info.The first step is relatively easy. The entries in the XML file look like this:</li>
</ul>
<div>
<pre>      &lt;output name="HDMI3"&gt;
          &lt;vendor&gt;SNY&lt;/vendor&gt;
          &lt;product&gt;0x0801&lt;/product&gt;
          &lt;serial&gt;0x01010101&lt;/serial&gt;
          &lt;width&gt;<span style="color: #ff0000;"><strong>1360</strong></span>&lt;/width&gt;
          &lt;height&gt;<strong><span style="color: #ff0000;">768</span></strong>&lt;/height&gt;
          &lt;rate&gt;<span style="color: #ff0000;"><strong>60</strong></span>&lt;/rate&gt;
          &lt;x&gt;0&lt;/x&gt;
          &lt;y&gt;0&lt;/y&gt;
          &lt;rotation&gt;normal&lt;/rotation&gt;
          &lt;reflect_x&gt;no&lt;/reflect_x&gt;
          &lt;reflect_y&gt;no&lt;/reflect_y&gt;
          &lt;primary&gt;yes&lt;/primary&gt;
      &lt;/output&gt;</pre>
</div>
<div>
<p>This is after editing the file. I needed 1360 x 768 @60 Hz, as shown above. So just set the width, height and rate tags in the XML file for <strong>all entries</strong>. No matter what monitor the system thinks it sees, the &#8220;user preference&#8221;  is the same.</p>
<p>Now making sure that the mode exists: Add something like the following as /etc/X11/Xsession.d/10add-xrandr-mode (owned by root, not executable, no shebang):</p>
<pre>xrandr -d :0 --newmode "hdmi_splitter" 85.5 1360 1424 1536 1792 768 771 777 795 +hsync +vsync
xrandr -d :0 --addmode HDMI3 hdmi_splitter
xrandr -d :0 --output HDMI3 --mode hdmi_splitter</pre>
<p>Needless to say (?), this relates to the specific graphics mode.</p>
<p>So this file is executed every time X is started (and hence the xrandr modes list is cleared). All it does is making sure that the relevant output port (HDMI3) knows how to display 1360 x 768. Note that the name of the mode has no particular significance, and that the frame rate isn&#8217;t given explicitly, but is calculated by the tools. I got these figures from an xrandr readout with the desired monitor connected directly. See the full listing at the end of this post. It&#8217;s the first entry there.</p>
<p>The third command actually switches the display to the desired mode. It can be removed actually, because it&#8217;s overridden very soon anyhow. Nevertheless, it shows the command that can be used manually on console, given the two earlier commands (should not be needed, given that the mode is invoked automatically, fingers crossed).</p>
<p>That&#8217;s it. Except for occasional glitches (getting full control of this was too much to expect), the two actions mentioned above are enough to get the mode I wanted. Not the &#8220;no matter what&#8221; I wanted, but close enough.</p>
<p>As for the -d :0 flags, it&#8217;s required in remote sessions and scripts. Alternatively, start with an</p>
<pre>$ export DISPLAY=:0</pre>
</div>
<h3>Using cvt to obtain the timing parameters (not!)</h3>
<p>It&#8217;s suggested on some websites to obtain the timing parameters with something like</p>
<pre>$ cvt 1360 768 60
# 1360x768 59.80 Hz (CVT) hsync: 47.72 kHz; pclk: 84.75 MHz
Modeline "1360x768_60.00"   84.75  1360 1432 1568 1776  768 771 781 798 -hsync +vsync</pre>
<p>I tried this, and the monitor didn&#8217;t sync on the signal. It&#8217;s indeed a pretty lousy monitor to miss on a DVI signals, and still.</p>
<p>Note the small differences between the timing parameters &#8212; that&#8217;s probably the reason for this failure. So when the real parameters can be obtained, use them. There is no secret catch-all formula for all graphics modes. The formula works on a good day.</p>
<h3>Hands off, Cinnamon&#8217;s daemon!</h3>
<p>My original idea was to turn off all automatic graphics mode setting mechanisms, and stay with a single xrandr command, running from /etc/X11/Xsession.d/ or something. It was a great idea, but it didn&#8217;t work: I saw a momentary switch to the mode I wanted, and then it changed to something else. I could have added some kind of daemon of my own, that waits a bit and then changes the mode with xrandr, but that&#8217;s just adding another daemon to wrestle with the others.</p>
<p>So this didn&#8217;t really help, but I&#8217;ll leave it here anyway, in case someone wants to change the display mode without having some daemon change it back. Note that according to <a href="https://unix.stackexchange.com/questions/429628/stop-display-settings-changing-when-turning-off-dp-monitors-on-linux-mint/512817" target="_blank">this page</a>,  using gsettings as shown below works only up to Cinnamon before version 3.4, after  which the procedure is different (haven&#8217;t tried it however): Copy  /etc/xdg/autostart/cinnamon-settings-daemon-xrandr.desktop to  $HOME/.config/autostart. Then append the line Hidden=true to the copied  file.</p>
<p>In short, YMMV. Here&#8217;s how I did it on my system (and then found it&#8217;s not good enough, as mentioned above).</p>
<p>Resolution mode settings made with xrandr will be sporadically overridden by cinnamon-settings-daemon, which has a lot of plugins running for different housekeeping tasks. One of them is to keep X-Window&#8217;s display resolution in sync with .config/monitors.xml. So disable it.</p>
<p>Following <a href="https://billauer.se/blog/2017/02/gnome-cinnamon-desktop-settings/" target="_blank">my own post</a>, this is typically the setting for the said plugin:</p>
<pre>$ gsettings list-recursively org.gnome.settings-daemon.plugins.xrandr
org.gnome.settings-daemon.plugins.xrandr active true
org.gnome.settings-daemon.plugins.xrandr priority 0
org.gnome.settings-daemon.plugins.xrandr default-monitors-setup 'follow-lid'
org.gnome.settings-daemon.plugins.xrandr default-configuration-file '/etc/gnome-settings-daemon/xrandr/monitors.xml'</pre>
<p>So turn it off:</p>
<pre>$ gsettings set org.gnome.settings-daemon.plugins.xrandr active false</pre>
<p>and then check again with the list-recursively command above.</p>
<h3>xrandr output: The full list of modes</h3>
<p>Just for reference, these are the modes given by xrandr for the monitor I did all this for:</p>
<pre>$ xrandr -d :0 --verbose

<span style="color: #888888;"><em>[ ... ]</em></span>

  1360x768 (0x4b) 85.500MHz +HSync +VSync *current +preferred
        h: width  1360 start 1424 end 1536 total 1792 skew    0 clock  47.71KHz
        v: height  768 start  771 end  777 total  795           clock  60.02Hz
  1920x1080i (0x10b) 74.250MHz -HSync -VSync Interlace
        h: width  1920 start 2008 end 2052 total 2200 skew    0 clock  33.75KHz
        v: height 1080 start 1084 end 1094 total 1125           clock  60.00Hz
  1920x1080i (0x10c) 74.250MHz +HSync +VSync Interlace
        h: width  1920 start 2008 end 2052 total 2200 skew    0 clock  33.75KHz
        v: height 1080 start 1084 end 1094 total 1125           clock  60.00Hz
  1920x1080i (0x10d) 74.250MHz +HSync +VSync Interlace
        h: width  1920 start 2448 end 2492 total 2640 skew    0 clock  28.12KHz
        v: height 1080 start 1084 end 1094 total 1125           clock  50.00Hz
  1920x1080i (0x10e) 74.176MHz +HSync +VSync Interlace
        h: width  1920 start 2008 end 2052 total 2200 skew    0 clock  33.72KHz
        v: height 1080 start 1084 end 1094 total 1125           clock  59.94Hz
  1280x720 (0x10f) 74.250MHz -HSync -VSync
        h: width  1280 start 1390 end 1430 total 1650 skew    0 clock  45.00KHz
        v: height  720 start  725 end  730 total  750           clock  60.00Hz
  1280x720 (0x110) 74.250MHz +HSync +VSync
        h: width  1280 start 1390 end 1430 total 1650 skew    0 clock  45.00KHz
        v: height  720 start  725 end  730 total  750           clock  60.00Hz
  1280x720 (0x111) 74.250MHz +HSync +VSync
        h: width  1280 start 1720 end 1760 total 1980 skew    0 clock  37.50KHz
        v: height  720 start  725 end  730 total  750           clock  50.00Hz
  1280x720 (0x112) 74.176MHz +HSync +VSync
        h: width  1280 start 1390 end 1430 total 1650 skew    0 clock  44.96KHz
        v: height  720 start  725 end  730 total  750           clock  59.94Hz
  1024x768 (0x113) 65.000MHz -HSync -VSync
        h: width  1024 start 1048 end 1184 total 1344 skew    0 clock  48.36KHz
        v: height  768 start  771 end  777 total  806           clock  60.00Hz
  800x600 (0x114) 40.000MHz +HSync +VSync
        h: width   800 start  840 end  968 total 1056 skew    0 clock  37.88KHz
        v: height  600 start  601 end  605 total  628           clock  60.32Hz
  720x576 (0x115) 27.000MHz -HSync -VSync
        h: width   720 start  732 end  796 total  864 skew    0 clock  31.25KHz
        v: height  576 start  581 end  586 total  625           clock  50.00Hz
  720x576i (0x116) 13.500MHz -HSync -VSync Interlace
        h: width   720 start  732 end  795 total  864 skew    0 clock  15.62KHz
        v: height  576 start  580 end  586 total  625           clock  50.00Hz
  720x480 (0x117) 27.027MHz -HSync -VSync
        h: width   720 start  736 end  798 total  858 skew    0 clock  31.50KHz
        v: height  480 start  489 end  495 total  525           clock  60.00Hz
  720x480 (0x118) 27.000MHz -HSync -VSync
        h: width   720 start  736 end  798 total  858 skew    0 clock  31.47KHz
        v: height  480 start  489 end  495 total  525           clock  59.94Hz
  720x480i (0x119) 13.514MHz -HSync -VSync Interlace
        h: width   720 start  739 end  801 total  858 skew    0 clock  15.75KHz
        v: height  480 start  488 end  494 total  525           clock  60.00Hz
  720x480i (0x11a) 13.500MHz -HSync -VSync Interlace
        h: width   720 start  739 end  801 total  858 skew    0 clock  15.73KHz
        v: height  480 start  488 end  494 total  525           clock  59.94Hz
  640x480 (0x11b) 25.200MHz -HSync -VSync
        h: width   640 start  656 end  752 total  800 skew    0 clock  31.50KHz
        v: height  480 start  490 end  492 total  525           clock  60.00Hz
  640x480 (0x11c) 25.175MHz -HSync -VSync
        h: width   640 start  656 end  752 total  800 skew    0 clock  31.47KHz
        v: height  480 start  490 end  492 total  525           clock  59.94Hz</pre>
<p>The vast majority are standard VESA modes.</p>
]]></content:encoded>
			<wfw:commentRss>https://billauer.se/blog/2019/08/cinnamon-permanent-resolution-xrandr/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>When mplayer plays a black window (or: Cinnamon leaking GPU memory)</title>
		<link>https://billauer.se/blog/2019/04/cinnamon-gpu-memory-leak-restart/</link>
		<comments>https://billauer.se/blog/2019/04/cinnamon-gpu-memory-leak-restart/#comments</comments>
		<pubDate>Sun, 14 Apr 2019 12:22:53 +0000</pubDate>
		<dc:creator>eli</dc:creator>
				<category><![CDATA[cinnamon]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">https://billauer.se/blog/?p=5732</guid>
		<description><![CDATA[The incident All of the sudden, playing videos with Mplayer opened a black window. Sometimes going fullscreen helped, sometimes it didn&#8217;t, sometimes with video playing but without OSD. ffplay worked, but somewhat limping. Setting: Linux Mint 19 on an x86_64, with a couple of fanless GeForce GT 1030 graphics cards and Cinnamon 3.8.9. Mplayer&#8217;s output [...]]]></description>
			<content:encoded><![CDATA[<h3>The incident</h3>
<p>All of the sudden, playing videos with Mplayer opened a black window. Sometimes going fullscreen helped, sometimes it didn&#8217;t, sometimes with video playing but without OSD. ffplay worked, but somewhat limping.</p>
<p>Setting: Linux Mint 19 on an x86_64, with a couple of fanless GeForce GT 1030 graphics cards and Cinnamon 3.8.9.</p>
<p>Mplayer&#8217;s output in this situation:</p>
<pre>Playing IHS_1235.MOV.
libavformat version 57.83.100 (external)
libavformat file format detected.
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f858e2362a0]Protocol name not provided, cannot determine if input is local or a network protocol, buffers and access patterns cannot be configured optimally without knowing the protocol
[lavf] stream 0: video (h264), -vid 0
[lavf] stream 1: audio (pcm_s16le), -aid 0, -alang eng
VIDEO:  [H264]  1920x1080  24bpp  59.940 fps  36067.5 kbps (4402.8 kbyte/s)
==========================================================================
Opening video decoder: [ffmpeg] FFmpeg's libavcodec codec family
libavcodec version 57.107.100 (external)
Selected video codec: [ffh264] vfm: ffmpeg (FFmpeg H.264)
==========================================================================
Opening audio decoder: [pcm] Uncompressed PCM audio decoder
AUDIO: 48000 Hz, 2 ch, s16le, 1536.0 kbit/100.00% (ratio: 192000-&gt;192000)
Selected audio codec: [pcm] afm: pcm (Uncompressed PCM)
==========================================================================
AO: [pulse] 48000Hz 2ch s16le (2 bytes per sample)
Starting playback...
Movie-Aspect is undefined - no prescaling applied.
VO: [vdpau] 1920x1080 =&gt; 1920x1080 Planar YV12
[vdpau] Error when calling vdp_output_surface_create: The system does not have enough resources to complete the requested operation at this time.
[vdpau] Error when calling vdp_output_surface_create: The system does not have enough resources to complete the requested operation at this time.
[vdpau] Error when calling vdp_output_surface_create: The system does not have enough resources to complete the requested operation at this time.
[vdpau] Error when calling vdp_output_surface_create: The system does not have enough resources to complete the requested operation at this time.
[vdpau] Error when calling vdp_presentation_queue_block_until_surface_idle: An invalid handle value was provided.
[vdpau] Error when calling vdp_video_mixer_render: An invalid handle value was provided.
[vdpau] Error when calling vdp_presentation_queue_display: An invalid handle value was provided.
A:   0.2 V:   0.0 A-V:  0.216 ct:  0.000   0/  0 ??% ??% ??,?% 0 0
[vdpau] Error when calling vdp_presentation_queue_block_until_surface_idle: An invalid handle value was provided.
[vdpau] Error when calling vdp_video_mixer_render: An invalid handle value was provided.
[vdpau] Error when calling vdp_presentation_queue_block_until_surface_idle: An invalid handle value was provided.
[vdpau] Error when calling vdp_video_mixer_render: An invalid handle value was provided.
[vdpau] Error when calling vdp_presentation_queue_display: An invalid handle value was provided.
[vdpau] Error when calling vdp_presentation_queue_display: An invalid handle value was provided.</pre>
<p>And a lot of error messages, with &#8220;invalid handle value was provided&#8221; all over the place.</p>
<h3>What does the graphics card have to say?</h3>
<p>Opening Nvidia&#8217;s graphical control panel (Nvidia X Server Settings), it turns out that &#8220;User Dedicated Memory&#8221; stands at 1864 MB out of 1998 MB (93%). No wonder things don&#8217;t work.</p>
<p>OK, so who&#8217;s eating up all RAM? I have a wild guess, but nothing like getting it black on white:</p>
<pre>$ nvidia-smi
Sun Apr 14 14:39:40 2019
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 396.37                 Driver Version: 396.37                    |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  GeForce GT 1030     Off  | 00000000:17:00.0 Off |                  N/A |
|  0%   41C    P8    N/A /  30W |      1MiB /  2001MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+
|   1  GeForce GT 1030     Off  | 00000000:65:00.0  On |                  N/A |
|  0%   51C    P8    N/A /  30W |   <span style="color: #ff0000;"><strong>1914MiB</strong></span> /  1998MiB |      8%      Default |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID   Type   Process name                             Usage      |
|=============================================================================|
|    1      1803      G   /usr/lib/xorg/Xorg                           433MiB |
|    1      2373      G   <span style="color: #ff0000;"><strong>cinnamon</strong></span>                                    <span style="color: #ff0000;"><strong>1310MiB</strong></span> |
|    1     54180      G   ...uest-channel-token=14764917277860092693   165MiB |
|    1     68188      G   /usr/bin/nvidia-settings                       0MiB |
+-----------------------------------------------------------------------------+</pre>
<p><em>(The memory consumptions are at the far right on each line. Scroll to see them)</em></p>
<p>At that very moment it had slurped quite some CPU RAM as well: 5.7 GB virtual memory allocated and 1.3 GB resident (real RAM). So leaking memory everywhere. That&#8217;s after running two months.</p>
<p>The other hog is Google Chrome, by the way, (165 MiB), also after running continuously for two months.</p>
<h3>Solution</h3>
<p>The solution is surprisingly simple and harmless: Restart Cinammon. Yes, you can do this even if there are a lot of windows open, spread out in different workspaces. They will remain in place, don&#8217;t worry.</p>
<p>The somewhat scary option is to request to switch user on the desktop&#8217;s GUI, and login as the same user again. Scary, because I get a blank screen with only a cursor pointer. To get out of that situation, Ctrl-Alt-F7 got me a proper login screen. And after logging in, all is fine. I&#8217;m not all that sure I&#8217;ll get that login screen every time, though.</p>
<p>The safer way is to reset Cinnamon without logging out, but  the tabs will be reordered within each workspace. To do this (as I mentioned on <a href="https://billauer.se/blog/2018/12/writing-cinnamon-applet/" target="_blank">another post</a>):</p>
<p>Press <strong>ALT-F2, type “r” and Enter.</strong> Look away for a few seconds, because what happens next looks like a sudden reboot, but it isn&#8217;t. All comes back.</p>
<p>Except that the order of the Windows tabs is reordered. It seems to help to do this before the restart: Go through each of the workspaces, minimize all windows and then open them from the tabs, going from left to right. Helps partially.</p>
<p>And a lot of memory has been freed. Resident CPU RAM went down from 1.3 GB to 256 MB, but even more important:</p>
<pre>$ nvidia-smi
Sun Apr 14 14:49:19 2019
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 396.37                 Driver Version: 396.37                    |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  GeForce GT 1030     Off  | 00000000:17:00.0 Off |                  N/A |
|  0%   41C    P8    N/A /  30W |      1MiB /  2001MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+
|   1  GeForce GT 1030     Off  | 00000000:65:00.0  On |                  N/A |
|  0%   52C    P0    N/A /  30W |    <span style="color: #ff0000;"><strong>701MiB</strong></span> /  1998MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID   Type   Process name                             Usage      |
|=============================================================================|
|    1      1803      G   /usr/lib/xorg/Xorg                           498MiB |
|    1      2373      G   <span style="color: #ff0000;"><strong>cinnamon</strong></span>                                      <span style="color: #ff0000;"><strong>17MiB</strong></span> |
|    1     54180      G   ...uest-channel-token=14764917277860092693   177MiB |
+-----------------------------------------------------------------------------+</pre>
<p>That&#8217;s a crash diet until the next time. Once a month, I guess.</p>
]]></content:encoded>
			<wfw:commentRss>https://billauer.se/blog/2019/04/cinnamon-gpu-memory-leak-restart/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Solved: Missing ktorrent icon on Linux Mint / Cinnamon</title>
		<link>https://billauer.se/blog/2018/12/ktorrent-icon-linux-mint-cinnamon/</link>
		<comments>https://billauer.se/blog/2018/12/ktorrent-icon-linux-mint-cinnamon/#comments</comments>
		<pubDate>Mon, 24 Dec 2018 08:08:07 +0000</pubDate>
		<dc:creator>eli</dc:creator>
				<category><![CDATA[cinnamon]]></category>
		<category><![CDATA[Internet]]></category>
		<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">https://billauer.se/blog/?p=5632</guid>
		<description><![CDATA[Running ktorrent on Linux Mint 19 (Tara), the famous downwards-arrow icon was invisible on the system tray. Which made it appear like the program had quit when it was actually minimized. Clicking the empty box made ktorrent re-appear. Solution: Invoke the Qt5 configuration tool $ qt5ct and under the Appearance tab set &#8220;Style&#8221; to gtk2 [...]]]></description>
			<content:encoded><![CDATA[<p>Running ktorrent on Linux Mint 19 (Tara), the famous downwards-arrow icon was invisible on the system tray. Which made it appear like the program had quit when it was actually minimized. Clicking the empty box made ktorrent re-appear.</p>
<p>Solution: Invoke the Qt5 configuration tool</p>
<pre>$ qt5ct</pre>
<p>and under the Appearance tab set &#8220;Style&#8221; to gtk2 (I believe it was &#8220;Fusion&#8221; before). It&#8217;s not just prettier generally, but after restarting ktorrent, the icon is there.</p>
<p>Actually, it&#8217;s probably not about the style, but the fact that qt5ct was run. Because before making the change, the ktorrent printed out the following when launched from the command line:</p>
<pre>Mon Dec 24 09:52:55 2018: Qt Warning: QSystemTrayIcon::setVisible: No Icon set
Warning: QSystemTrayIcon::setVisible: No Icon set
Mon Dec 24 09:52:55 2018: Starting minimized
Mon Dec 24 09:52:55 2018: Started update timer
<strong>Mon Dec 24 09:52:55 2018: Qt Warning: inotify_add_watch("/home/eli/.config/qt5ct") failed: "No such file or directory"</strong>
Warning: inotify_add_watch("/home/eli/.config/qt5ct") failed: "No such file or directory"</pre>
<p>The &#8220;No Icon set&#8221; warning is misleading, because it continued to appear. This is <strong>after</strong> the fix, with the icon properly in place in the tray:</p>
<pre>Mon Dec 24 10:16:17 2018: Qt Warning: QSystemTrayIcon::setVisible: No Icon set
Warning: QSystemTrayIcon::setVisible: No Icon set</pre>
<p>Anyhow, problem fixed. For me, that is.</p>
<p>And why ktorrent? Because its last reported <a href="https://usn.ubuntu.com/436-1/" target="_blank">vulnerability</a> was in 2009, compared with &#8220;Transmission&#8221; which had a <a href="https://security-tracker.debian.org/tracker/CVE-2018-5702" target="_blank">nasty issue</a> in January 2018. Actually, the exploit in Transmission is <a href="https://bugs.chromium.org/p/project-zero/issues/detail?id=1447" target="_blank">interesting by itself</a>, with a clear lesson: If you set up a webserver on the local host for any purpose, assume anyone can access it. Setting it to respond to 127.0.0.1 only doesn&#8217;t help.</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>https://billauer.se/blog/2018/12/ktorrent-icon-linux-mint-cinnamon/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Writing a panel applet for Cinnamon: The basics</title>
		<link>https://billauer.se/blog/2018/12/writing-cinnamon-applet/</link>
		<comments>https://billauer.se/blog/2018/12/writing-cinnamon-applet/#comments</comments>
		<pubDate>Sat, 08 Dec 2018 19:15:40 +0000</pubDate>
		<dc:creator>eli</dc:creator>
				<category><![CDATA[cinnamon]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">https://billauer.se/blog/?p=5629</guid>
		<description><![CDATA[Introduction What I wanted: A simple applet on Cinnamon, which allows me to turn a service on and off (hostapd, a Wifi hotspot). I first went for Argos catch-all extension, and learned that Cinnamon isn&#8217;t gnome-shell, and in particular that extensions for gnome-shell don&#8217;t (necessarily?) work with Cinnamon. Speaking of which, my system is Linux [...]]]></description>
			<content:encoded><![CDATA[<h3>Introduction</h3>
<p>What I wanted: A simple applet on Cinnamon, which allows me to turn a service on and off (hostapd, a Wifi hotspot). I first went for <a href="https://billauer.se/blog/2018/12/argos-gnome-cinnamon/" target="_blank">Argos catch-all extension</a>, and learned that Cinnamon isn&#8217;t gnome-shell, and in particular that extensions for gnome-shell don&#8217;t (necessarily?) work with Cinnamon.</p>
<p>Speaking of which, my system is Linux Mint 19 on an x86_64, with</p>
<pre>$ cinnamon --version
Cinnamon 3.8.9</pre>
<p>So I went for writing the applet myself. Given the so-so level of difficulty, I should have done that to begin with.</p>
<p>Spoiler: I&#8217;m <strong>not going to</strong> dive into the details of that, because my hostapd-firewall-DHCP daemon setting is quite specific. Rather, I&#8217;ll discuss about some general aspects of writing an applet.</p>
<p>So what is it like? Well, quite similar to writing something useful in JavaScript for a web page. Cinnamon&#8217;s applets are in fact written in JavaScript, and it feels pretty much the same. In particular, this thing about nothing happening when there&#8217;s an error, now go figure what it was. And yes, there&#8217;s an error log console which helps with syntax errors (reminds browsers&#8217; error log, discussed below) but often run-time errors just lead to nothing. A situation that is familiar to anyone with JavaScript experience.</p>
<p>And I also finally understand why the cinnamon process hogs CPU all the time. OK, it&#8217;s usually just a few percents, and still, what is it doing all that time with no user activity? Answer: Running some JavaScript, I suppose.</p>
<p>But all in all, if you&#8217;re good with JavaScript and understand the concepts of GUI programming and events + fairly OK with object oriented programming, it&#8217;s quite fun. And there&#8217;s another thing you better be good at:</p>
<h3>Read The Source</h3>
<p>As of December 2018, the API for Cinnamon applets is hardly documented, and it&#8217;s somewhat messy. So after reading a couple of tutorials (See &#8220;References&#8221; at the bottom of this post), the best way to grasp how to get X done is by reading the sources of existing applets:</p>
<ul>
<li>System-installed: /usr/share/cinnamon/applets</li>
<li>User-installed: ~/.local/share/cinnamon/applets</li>
<li>Cinnamon&#8217;s core JavaScript sources: /usr/share/cinnamon/js</li>
</ul>
<p>Each of these contains several subdirectories, typically with the form name@creator, one for each applet  that is available for adding to the panels. Each of these has at least two files, which are also those to supply for your own applet:</p>
<ul>
<li>metadata.json, which contains some basic info on the applet  (probably used while selecting applets to add).</li>
<li>applet.js, which contains the JavaScript code for the applet.</li>
</ul>
<p>It doesn&#8217;t matter if they&#8217;re executable, even though they often are.</p>
<p>There may also be additional *.js files.</p>
<p>Also, there might also be a po/ directory, which often contains .po  and .pot files that are intended for localizing the text displayed to  the user. These go along with the _() function in the JavaScript code.   For the purposes of a simple applet, these are not necessary. Ignore  these _(&#8220;Something&#8221;) things in the JavaScript code, and read them as  just &#8220;Something&#8221;.</p>
<p>Some applets allow parameter setting. The runtime values for these are at ~/.cinnamon, which contains configuration data etc.</p>
<h3>Two ways to object orient</h3>
<p>Unfortunately, there are two styles for defining the applet class, both of which are used. This is a matter of minor confusion if you read the code of a few applets, and therefore worthy to note: Some of the applets use JavaScript class declarations (extending a built-in class), e.g.</p>
<pre>class CinnamonSoundApplet extends Applet.TextIconApplet {
    constructor(metadata, orientation, panel_height, instanceId) {
        super(orientation, panel_height, instanceId);</pre>
<p>and others use the &#8220;prototype&#8221; syntax:</p>
<pre>MyApplet.prototype = {
  __proto__: Applet.IconApplet.prototype,</pre>
<p>and so on. I guess they&#8217;re equivalent, despite the difference in syntax. Note that in the latter format, the constructor is a function called _init().</p>
<p>This way or another, all classes that employ timeout callbacks should have a destroy() method (no underscore prefix) to cancel them before quitting.</p>
<p>I wasn&#8217;t aware of these two syntax possibilities, and therefore started from the first applet I got my hands on. It happened to be written in the &#8220;prototype&#8221; syntax, which is probably the less preferable choice. I&#8217;m therefore not so sure my example below is a good starter.</p>
<h3>Getting Started</h3>
<p>It&#8217;s really about three steps to get an applet up and running.</p>
<ul>
<li>Create a directory in ~/.local/share/cinnamon/applets/ and put the two files there: metadata.json and applet.js.</li>
<li>Restart Cinnamon. No, it&#8217;s not as bad as it sounds. See below.</li>
<li>Install the applet to some panel, just like any other applet.</li>
</ul>
<div>I warmly suggest copying an existing applet and hacking it. You can start with the skeleton applet I&#8217;ve listed below, but there are plenty other available on the web, in particular along with tutorials.</div>
<h3>The development cycle (or: how to &#8220;run&#8221;)</h3>
<p>None of the changes made in the applet&#8217;s directory (well, almost none) take any effect until Cinnamon is restarted, and when it is, everything is in sync. It&#8217;s not like a reboot, and it&#8217;s fine to do on the computer you&#8217;re working on, really. All windows remain in their workspaces  (even though the windows&#8217; tabs at the panel may change order). No reason  to avoid this, even if you have a lot of windows opened. Done it a gazillion  times.</p>
<p>So how to restart Cinnamon: <strong>ALT-F2, type &#8220;r&#8221; and Enter.</strong> Then cringe as your desktop fades away and be overwhelmed when it returns, and nothing bad happened.</p>
<p>If something is wrong with your applet (or otherwise), there a notification saying &#8220;Problems during Cinnamon startup&#8221; elaborating that &#8220;Cinnamon started  successfully, but one or more applets, desklets or extensions failed to  load&#8221;. From my own experience, that&#8217;s as bad as it gets: The applet wasn&#8217;t loaded, or doesn&#8217;t run properly.</p>
<p>Press <strong>Win+L</strong> (or ALT-F2, then type &#8220;lg&#8221; and Enter, or type &#8220;cinnamon-looking-glass&#8221; at shell prompt as non-root user) to launch the Looking Glass tool (called &#8220;Melange&#8221;). The Log tab is helpful with detailed error messages (colored red, that helps). Alternatively, look for the detailed error message in .xsession-errors in your home directory.</p>
<p>Note that the error message often appears <strong>before</strong> the line saying that the relevant applet was loaded.</p>
<p>OK, so now to some more specific topics.</p>
<h3>Custom icons</h3>
<p>Icons are referenced by their file name, without extension, in the JavaScript code as well as the metadata.json file (as &#8220;icon&#8221; assignment). The search path is the applet&#8217;s own icons/ subdirectory and the system icons, present at /usr/share/icons/.</p>
<p>My own experience is that creating an icons/ directory side-by-side with applet.js, and putting a PNG file named wifi-icon-off.png there makes a command like</p>
<pre>this.set_applet_icon_name("wifi-icon-off");</pre>
<p>work for setting the applet&#8217;s main icon on the panel. The PNG&#8217;s transparency is honored. The official file format is SVG, but who&#8217;s got patience for that.</p>
<p>Same goes with something menu items with icons:</p>
<pre>item = new PopupMenu.PopupIconMenuItem("Access point off", "wifi-icon-off", St.IconType.FULLCOLOR);

item.connect('activate', Lang.bind(this, function() {
   Main.Util.spawnCommandLine("/usr/local/bin/access-point-ctl off");
}));
this.menu.addMenuItem(item);</pre>
<p>My own experience with the menu items is that if the icon file isn&#8217;t found, Cinnamon silently puts an empty slot instead. JavaScript-style no fussing.</p>
<p>I didn&#8217;t manage to achieve something similar with the &#8220;icon&#8221; assignment in metadata.json, so the choices are either to save the icon in /usr/share/icons/,  or use one of the system icons, or eliminate the &#8220;icon&#8221; assignment altogether from the JSON file. I went to the last option. This resulted in a dull default icon when installing the applet, but this is of zero importance for an applet I&#8217;ve written myself.</p>
<h3>Running shell commands from JavaScript</h3>
<p>The common way to execute a shell command is e.g.</p>
<pre>const Main = imports.ui.main;

Main.Util.spawnCommandLine("gnome-terminal");</pre>
<p>The assignment of Main is typically done once, and at the top of the script, of course.</p>
<p>When the output of the command is of interest, it becomes slightly more difficult. The following function implements the parallel of the <strong>Perl</strong> backtick operator: Run the command, and return the result as a string. Note that unlike its <strong>bash</strong> counterpart, newlines remain newlines, and are <strong>not</strong> translated into spaces:</p>
<pre>const GLib = imports.gi.GLib;

function backtick(command) {
  try {
    let [result, stdout, stderr] = GLib.spawn_command_line_sync(command);
    if (stdout != null) {
      return stdout.toString();
    }
  }
  catch (e) {
    global.logError(e);
  }

  return "";
}</pre>
<p>and then one can go e.g.</p>
<pre>let output = backtick("/bin/systemctl is-active hostapd");</pre>
<p>after which <em>output</em> is a string containing the result of the execution (with a trailing newline, by the way).</p>
<p>As of December 2018, there&#8217;s no proper documentation of Cinnamon&#8217;s Glib wrapper, however the <a href="https://developer.gnome.org/glib/2.32/glib-Spawning-Processes.html#g-spawn-command-line-sync" target="_blank">documentation of the C library</a> can give an idea.</p>
<h3>My example applet</h3>
<p>OK, so here&#8217;s a skeleton applet for getting started with.</p>
<p>Its pros:</p>
<ul>
<li>It&#8217;s short, quite minimal, and keeps the mumbo-jumbo to a minimum</li>
<li>It shows a simple drop-down menu display applet, which allows running a different shell command from each entry.</li>
</ul>
<div>Its cons:</div>
<div>
<ul>
<li>It&#8217;s written in the less-preferable &#8220;prototype&#8221; syntax for defining objects.</li>
<li>It does nothing useful. In particular, the shell commands it executes exist only on my computer.</li>
<li>It depends on a custom icon (see &#8220;Custom Icons&#8221; above). Maybe this is an advantage&#8230;?</li>
</ul>
</div>
<p>So if you want to give it a go, create a directory named &#8216;wifier@eli&#8217; (or anything else?) in ~/.local/share/cinnamon/applets/, and put this as metadata.json:</p>
<pre>{
    "description": "Turn Wifi Access Point on and off",
    "uuid": "wifier@eli",
    "name": "Wifier"
}</pre>
<p>And this as applet.js:</p>
<pre>const Applet = imports.ui.applet;
const Lang = imports.lang;
const St = imports.gi.St;
const Main = imports.ui.main;
const PopupMenu = imports.ui.popupMenu;
const UUID = 'wifier@eli';

function ConfirmDialog(){
  this._init();
}

function MyApplet(orientation, panelHeight, instanceId) {
  this._init(orientation, panelHeight, instanceId);
}

MyApplet.prototype = {
  __proto__: Applet.IconApplet.prototype,

  _init: function(orientation, panelHeight, instanceId) {
    Applet.IconApplet.prototype._init.call(this, orientation, panelHeight, instanceId);

    try {
      this.set_applet_icon_name("wifi-icon-off");
      this.set_applet_tooltip("Control Wifi access point");

      this.menuManager = new PopupMenu.PopupMenuManager(this);
      this.menu = new Applet.AppletPopupMenu(this, orientation);
      this.menuManager.addMenu(this.menu);

      this._contentSection = new PopupMenu.PopupMenuSection();
      this.menu.addMenuItem(this._contentSection);

      // First item: Turn on
      let item = new PopupMenu.PopupIconMenuItem("Access point on", "wifi-icon-on", St.IconType.FULLCOLOR);

      item.connect('activate', Lang.bind(this, function() {
					   Main.Util.spawnCommandLine("/usr/local/bin/access-point-ctl on");
					 }));
      this.menu.addMenuItem(item);

      // Second item: Turn off
      item = new PopupMenu.PopupIconMenuItem("Access point off", "wifi-icon-off", St.IconType.FULLCOLOR);

      item.connect('activate', Lang.bind(this, function() {
					   Main.Util.spawnCommandLine("/usr/local/bin/access-point-ctl off");
					 }));
      this.menu.addMenuItem(item);
    }
    catch (e) {
      global.logError(e);
    }
  },

  on_applet_clicked: function(event) {
    this.menu.toggle();
  },
};

function main(metadata, orientation, panelHeight, instanceId) {
  let myApplet = new MyApplet(orientation, panelHeight, instanceId);
  return myApplet;
}</pre>
<p>Next, create an &#8220;icons&#8221; subdirectory (e.g. ~/.local/share/cinnamon/applets/wifier@eli/icons/) and put a small (32 x 32 ?) PNG image there as wifi-icon-off.png, which functions as the applet&#8217;s top icon. Possibly download mine <a href="/non-html/wifi-icon-off.png" target="_blank">from here</a>.</p>
<p>Anyhow, be sure to have an icon file. Otherwise there will be nothing on the panel.</p>
<p>Finally, restart Cinnamon, as explained above. You will get errors when trying the menu items (failed execution), but don&#8217;t worry &#8212; nothing bad will happen.</p>
<h3>References</h3>
<ul>
<li>A JavaScript <a href="http://lira.epac.to:8080/doc/cinnamon/cinnamon-js/" target="_blank">object reference</a> (there&#8217;s probably some &#8220;original&#8221; out there, but where?)</li>
<li>The main <a href="http://developer.linuxmint.com/reference/git/cinnamon-tutorials/" target="_blank">Cinnamon reference page</a> (don&#8217;t expect too much)</li>
<li><a href="https://wiki.gnome.org/Projects/GnomeShell/Extensions/EcoDoc/Applet" target="_blank">Creating an Applet</a></li>
<li><a href="http://developer.linuxmint.com/reference/git/cinnamon-tutorials/write-applet.html" target="_blank">Writing an Applet</a></li>
<li>Lang.bind() explained <a href="https://github.com/linuxmint/Cinnamon/wiki/General-coding-tips" target="_blank">here</a>.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>https://billauer.se/blog/2018/12/writing-cinnamon-applet/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Failed: Install Argos Shell Extension on Cinnamon</title>
		<link>https://billauer.se/blog/2018/12/argos-gnome-cinnamon/</link>
		<comments>https://billauer.se/blog/2018/12/argos-gnome-cinnamon/#comments</comments>
		<pubDate>Thu, 06 Dec 2018 11:21:50 +0000</pubDate>
		<dc:creator>eli</dc:creator>
				<category><![CDATA[cinnamon]]></category>
		<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">https://billauer.se/blog/?p=5626</guid>
		<description><![CDATA[You have been warned These are my pile of jots as I tried to install Argos &#8220;Gnome Shell Extension in seconds&#8221; on my Mint 19 Cinnamon machine. As the title implies, it didn&#8217;t work out, so I went for writing an applet from scratch, more or less. Not being strong on Gnome internals, I&#8217;m under [...]]]></description>
			<content:encoded><![CDATA[<h3>You have been warned</h3>
<p>These are my pile of jots as I tried to install <a href="https://github.com/p-e-w/argos">Argos &#8220;Gnome Shell Extension in seconds&#8221;</a> on my Mint 19 Cinnamon machine. As the title implies, it didn&#8217;t work out, so I went for <a title="Writing a panel applet for Cinnamon: The basics" href="https://billauer.se/blog/2018/12/writing-cinnamon-applet/" target="_blank">writing an applet from scratch</a>, more or less.</p>
<p>Not being strong on Gnome internals, I&#8217;m under the impression that it&#8217;s simply because Cinnamon isn&#8217;t Gnome shell. This post is just the accumulation of notes I took while trying. Nothing to follow step-by-step, as it leads nowhere.</p>
<p>It&#8217;s here for the crumbs of info I gathered nevertheless.</p>
<h3>Here we go</h3>
<p>It says on the project&#8217;s <a href="https://github.com/p-e-w/argos#examples" target="_blank">Github page</a> that a recent version of Gnome should include Argos. So I went for it:</p>
<pre># apt install gnome-shell-extensions</pre>
<p>And since I&#8217;m at it:</p>
<pre># apt install gnome-tweaks</pre>
<p>Restart Gnome shell: ALT-F2, type &#8220;r&#8221; and enter. For a second, it looks like a logout, but everything returns to where it was. Don&#8217;t hesitate doing this, even if there are a lot of windows opened.</p>
<p>Nada. So I went the manual way. First, found out my Gnome Shell version:</p>
<pre>$ apt-cache show gnome-shell | grep Version</pre>
<p>or better,</p>
<pre>$ gnome-shell --version
GNOME Shell 3.28.3</pre>
<p>and downloaded the extension for Gnome shell 3.28 from <a href="https://extensions.gnome.org/extension/1176/argos/" target="_blank">Gnome&#8217;s extension page</a>. Then realized it&#8217;s slightly out of date with the git repo, so</p>
<pre>$ git clone https://github.com/p-e-w/argos.git
$ cd argos
$ cp -r 'argos@pew.worldwidemann.com' ~/.local/share/cinnamon/extensions/</pre>
<p>Note that I copied it into cinnamon&#8217;s subdirectory. It&#8217;s usually ~/.local/share/gnome-shell/extensions, but not when running Cinnamon!</p>
<p>Restart Gnome shell again: ALT-F2, type &#8220;r&#8221; and enter.</p>
<p>Then open the &#8220;Extensions&#8221; GUI thingy from the main menu. Argos extension appears. Select it and press the &#8220;+&#8221; button to add it.</p>
<p>Restart Gnome shell again. This time a notification appears, saying &#8220;Problems during Cinnamon startup&#8221; elaborating that &#8220;Cinnamon started successfully, but one or more applets, desklets or extensions failed to load&#8221;.</p>
<p>Looking at ~/.xsession-errors, I found</p>
<pre>Cjs-Message: 12:14:42.822: JS LOG: [LookingGlass/error] [argos@pew.worldwidemann.com]: Missing property "cinnamon-version" in metadata.json</pre>
<p>Can&#8217;t argue with that, can you? Let&#8217;s see:</p>
<pre>$ cinnamon --version
Cinnamon 3.8.9</pre>
<p>So edit ~/.local/share/cinnamon/extensions/argos@pew.worldwidemann.com/metadata.json and add the line marked in red (not at the end, because the last line doesn&#8217;t end with a comma):</p>
<pre>  "version": 2,
<span style="color: #ff0000;"><strong>  "cinnamon-version": [ "3.6", "3.8", "4.0" ]</strong></span>,
  "shell-version": ["3.14", "3.16", "3.18", "3.20", "3.22", "3.24", "3.26", "3.28"]</pre>
<p>I took this line from some applet I found under ~/.local/share/cinnamon. Not much thought given here.</p>
<p>And guess what? Reset again with ALT-F2 r. Failed again. Now in ~/.xsession-errors:</p>
<pre>Cjs-Message: 12:50:32.643: JS LOG: [LookingGlass/error]
[argos@pew.worldwidemann.com]: No JS module 'extensionUtils' found in search path
[argos@pew.worldwidemann.com]: Error importing extension.js from argos@pew.worldwidemann.com</pre>
<p>It seems like Cinnamon has changed the extension mechanism altogether, which explains why there&#8217;s no extension tab in Gnome Tweaker, and why extensionUtils is missing.</p>
<p>Maybe <a href="https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/1" target="_blank">this</a> explains it. Frankly, I didn&#8217;t bother to read that long discussion, but the underlying issue is probably buried there.</p>
]]></content:encoded>
			<wfw:commentRss>https://billauer.se/blog/2018/12/argos-gnome-cinnamon/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A watchdog script for restarting Cinnamon hogging memory at startup</title>
		<link>https://billauer.se/blog/2017/12/linux-mint-blank-screen/</link>
		<comments>https://billauer.se/blog/2017/12/linux-mint-blank-screen/#comments</comments>
		<pubDate>Fri, 01 Dec 2017 19:16:22 +0000</pubDate>
		<dc:creator>eli</dc:creator>
				<category><![CDATA[cinnamon]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[systemd]]></category>

		<guid isPermaLink="false">https://billauer.se/blog/?p=5310</guid>
		<description><![CDATA[Introduction August 2019 update: I&#8217;ve disactivated the service described below on my own machine, because in the end, the system didn&#8217;t recover properly from the condition it was supposed to solve. No solution, in the end. Having installed Linux Mint 18.1 (kernel 4.4.0-53) with overlayroot on a Gigabyte Brix BACE-3160 (see other notes on this [...]]]></description>
			<content:encoded><![CDATA[<h3>Introduction</h3>
<p><em>August 2019 update: I&#8217;ve disactivated the service described below on my own machine, because in the end, the system didn&#8217;t recover properly from the condition it was supposed to solve. No solution, in the end.</em></p>
<p>Having installed Linux Mint 18.1 (kernel 4.4.0-53) with overlayroot on a Gigabyte Brix BACE-3160 (see other notes on this <a href="https://billauer.se/blog/2017/02/i915-brix-drm-graphics/" target="_blank">here</a> and <a href="https://billauer.se/blog/2017/02/read-only-root-overlay-ram-tmpfs/" target="_blank">here</a>) for my living room media center, I had an issue with bringing up the computer every now and then. Namely, I had a blank screen with mouse pointer only, 100% CPU on the cinnamon process, and some 50% on cinnamon-settings-daemon, eating all RAM (8 GB) gradually until the computer crashes (as it&#8217;s swapless).</p>
<p>The whole point with an overlayroot based media center is that it behaves like any electrical appliance. In particular, you know it will recover well from a power outage. And not crash because of some silly desktop manager messing up.</p>
<p>I&#8217;m not alone: There&#8217;s a <a href="https://bugs.launchpad.net/linuxmint/+bug/1653160" target="_blank">bug report</a> on this. There&#8217;s also this Git Hub <a href="https://github.com/linuxmint/Cinnamon/issues/5569" target="_blank">issues page</a> seems to point at the problem, in particular as it was closed pointing at <a href="https://github.com/linuxmint/cinnamon-settings-daemon/issues/167" target="_blank">a commit</a>, which was merged into the main repository saying &#8220;Add detection for accountsservice background as it&#8217;s ubuntu only&#8221;.</p>
<p>It seems to be more common with SSD disks (because they&#8217;re faster).</p>
<p>And still there&#8217;s no solution available, almost a year later. Don&#8217;t tell me to upgrade. Upgrading means trading known bugs for new, unknown ones.</p>
<p>Which leaves me with making a workaround. In this case, a watchdog service, which monitors the resident memory usage of the process having the command line &#8220;cinnamon&#8221;. If it goes above 300 MiB during its first five minutes (more or less), restard the mdm service, which in turn restarts Cinnamon. Plain and disgusting.</p>
<p>The ironic truth is that I haven&#8217;t been able to test the watchdog for real, as I&#8217;ve failed to repeat the problem, despite a lot of power cycles. But I have verified that it works by lowering the memory threshold, and confirmed that the mdm service is indeed restarted. I also know from previous experience that restarting mdm helps.</p>
<h3>The stuff</h3>
<p>This should be copied to /usr/local/bin/cinnamon-watchdog.pl (executable at least by root):</p>
<pre>#!/usr/bin/perl
use warnings;
use strict;

my $cmd = 'cinnamon';
my $limit = 200; # Maximal resident memory size in MiB
my $timeout = 300; # Approximately how long this script should run, in seconds

my $pid;
my $timer = 0;
my $rss = 0;

eval {
  while (1) {
    $timer++;

    if ($timer &gt;= $timeout) {
      if (defined $pid) {
	logger("Quitting. cinnamon process seems to behave well with $rss MiB resident memory");
      } else {
	logger("Quitting without finding the cinnamon process")
      }
      last;
    }

    sleep(1);

    undef $pid if ((defined $pid) &amp;&amp; !is_target($cmd, $pid));

    $pid = find_target($cmd) unless (defined $pid);

    next unless (defined $pid); # No target process running yet?

    $rss = resident_memory($pid);

    if ($rss &gt; $limit) {
      $timer = 0;
      logger("Restarting cinnamon: Has reached $rss MiB resident memory");
      system('/bin/systemctl', 'restart', 'mdm') == 0
	or die("Failed to restart mdm service\n");
    }
  }
};

if ($@) {
  logger("Process died: $@");
  exit(1);
}

exit(0);

######## SUBROUTINES ########

sub find_target {
  my $target = shift;
  foreach my $entry (&lt;/proc/*&gt;) {
    my ($pid) = ($entry =~ /^\/proc\/(\d+)$/);
    next unless (defined $pid);

    return $pid
      if (is_target($target, $pid));
  }

  return undef;
}
sub is_target {
  my ($target, $pid) = @_;
  my ($cmdline, $c);

  local $/;

  open (F, "/proc/$pid/cmdline") or return 0;
  $cmdline = &lt;F&gt;;
  close F;

  return 0 unless (defined $cmdline);

  ($c) = ($cmdline =~ /^([^\x00]*)/);

  return $target eq $c;
}

sub resident_memory {
  my ($pid) = @_;

  local $/;

  open (F, "/proc/$pid/statm") or return 0;
  my $mem = &lt;F&gt;;
  close F;

  return 0 unless (defined $mem);

  my @entries = ($mem =~ /(\d+)/g);

  return 0 unless (defined $entries[1]); # Should never happen

  return int($entries[1] / 256); # Convert pages to MiBs
}

sub logger {
  my $msg = shift;
  system('/usr/bin/logger', "cinnamon-watchdog: $msg") == 0
    or warn("Failed to call logger\n");
}</pre>
<p>And this service unit file to /etc/systemd/system/cinnamon-watchdog.service:</p>
<pre>[Unit]
Description=Cinnamon watchdog service

[Service]
ExecStart=/usr/local/bin/cinnamon-watchdog.pl
Type=simple

[Install]
WantedBy=multi-user.target</pre>
<p>Enable service:</p>
<pre># <strong>systemctl enable cinnamon-watchdog</strong>
Created symlink from /etc/systemd/system/multi-user.target.wants/cinnamon-watchdog.service to /etc/systemd/system/cinnamon-watchdog.service.</pre>
<p>That&#8217;s it. The service will be active on the next reboot</p>
<h3>A few comments on the Perl script</h3>
<ul>
<li>The script monitors the memory consumption because it&#8217;s a simple and safe indication of the problem, not the problem itself.</li>
<li>It accesses the files under /proc/ directly rather than obtaining the information from e.g. ps. I suppose the proc format is more stable than ps&#8217; output. The ps utility obtains its information from exactly the same source.</li>
<li>The script exits voluntarily after slightly more than $timeout seconds after its invocation or its last intervention. In other words, if the cinnamon process hogs memory after its first five minutes, the script won&#8217;t be there to do anything. Neither should it. Its purpose is very specific.</li>
<li>The 200 MiB limit is based upon experience with my own system: It usually ends up with 123 MiB or so.</li>
</ul>
<h3>Random vaguely related notes</h3>
<p>Before going for this ugly solution, I actually tried to find the root of the problem (and obviously failed). Below are some random pieces of info I picked up while doing so.</p>
<p>The mdm setup files, in this order:</p>
<ul>
<li>/usr/share/mdm/defaults.conf</li>
<li>/usr/share/mdm/distro.conf</li>
<li>/etc/mdm/mdm.conf</li>
</ul>
<p>Things I tried that didn&#8217;t help:</p>
<ul>
<li>removing Background line from /var/lib/AccountsService/users/ as suggested below (didn&#8217;t make any difference)</li>
<li>Replacing autologin with a timed login of 10 seconds (I suspected that the problem was that Accountservice wasn&#8217;t up when it was required to say which background to put).</li>
</ul>
<h3>Additional ramblings</h3>
<p>It seemed to be a result of the <a href="https://tim.purewhite.id.au/2012/05/when-did-linux-start-moving-away-from-its-simplicity/" target="_blank">Accountservice</a> daemon attempting to fiddle with the background image.</p>
<p>So in /var/lib/AccountsService/users/ there&#8217;s a file called &#8220;eli&#8221; (my user name, obviously), which says</p>
<pre>[User]
Background=/usr/share/backgrounds/linuxmint/default_background.jpg
SystemAccount=false</pre>
<p>So what happens if I remove the Background line? Nothing. That is, the problem remains as before.</p>
<h3>A sample .xsession-errors when things went wrong</h3>
<pre>initctl: Unable to connect to Upstart: Failed to connect to socket /com/ubuntu/u
pstart: Connection refused
syndaemon: no process found
/etc/mdm/Xsession: Beginning session setup...
localuser:eli being added to access control list
** Message: couldn't access control socket: /run/user/1010/keyring/control: No s
uch file or directory
** Message: couldn't access control socket: /run/user/1010/keyring/control: No s
uch file or directory
SSH_AUTH_SOCK=/run/user/1010/keyring/ssh
SSH_AUTH_SOCK=/run/user/1010/keyring/ssh

(cinnamon-settings-daemon:2002): power-plugin-WARNING **: session inhibition not
 available, cinnamon-session is not available

(cinnamon-settings-daemon:2002): power-plugin-WARNING **: session inhibition not
 available, cinnamon-session is not available</pre>
]]></content:encoded>
			<wfw:commentRss>https://billauer.se/blog/2017/12/linux-mint-blank-screen/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
