    <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:content="http://purl.org/rss/1.0/modules/content/">
     <channel>
        <title>ACCU  :: Making a Linux Desktop</title>
        <link>https://members.accu.org/index.php/articles/2834</link>
        <description>Professionalism in Programming</description>
        <dc:language>en-us</dc:language> 
        <dc:creator>Administrator</dc:creator> 
        <admin:generatorAgent rdf:resource="http://www.xaraya.org" /> 
        <admin:errorReportsTo rdf:resource="mailto:webeditor@accu.org" />
       <sy:updatePeriod>hourly</sy:updatePeriod>
       <sy:updateFrequency>1</sy:updateFrequency>
       <docs>http://backend.userland.com/rss</docs>




<div class="xar-mod-head"><span class="xar-mod-title">Design of applications and programs + CVu Journal Vol 32, #4 - September 2020</span></div>

<table border="0" cellpadding="1" cellspacing="0">
    <tbody>
    <tr>
        <td valign="top">
            Browse in :
       </td>
       <td valign="top">

                                            <a href="https://members.accu.org/index.php/articles/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c13/">Topics</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c67/">Design</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c76/">Journals</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c77/">CVu</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c414/">324</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/c67-414/">Any of these categories</a>

                    -                        <a href="https://members.accu.org/index.php/articles/c67+414/">All of these categories</a>
<br />
</td>
   </tr>
   </tbody>
</table>




<div class="xar-error">
   <p>
 <strong>Note:</strong> when you create a new publication type,
the articles module will automatically use the templates
<em>user-display-[publicationtype].xt</em>
and <em>user-summary-[publicationtype].xt</em>.
If those templates do not exist when you try to preview or display a new article,
you'll get this warning :-)  Please place your own templates in themes/<em>yourtheme</em>/modules/articles . The templates will get the extension .xt there. </p>
</div>
<div class="xar-norm xar-standard-box-padding">
   <h1><strong>Title:</strong>&nbsp;Making a Linux Desktop</h1>
<p><strong>Author:</strong>&nbsp;Bob Schmidt</p>
<p>
<strong>Date:</strong> 08 September 2020 18:46:41 +01:00 or Tue, 08 September 2020 18:46:41 +01:00</p>
<p><strong>Summary:</strong>&nbsp;Alan Griffiths adds support for shell components to the desktop environment.</p>
<p><strong>Body:</strong>&nbsp;<p>Iâ€™m working on a project (Mir) that, among other things, aims to make it easy to develop graphical â€˜desktop environmentsâ€™ for Linux. There are a lot of features that are common between all designs for desktop environments and, in addition, a lot that is common between the majority of designs. For example, it is common for applications to draw â€˜windowsâ€™ and for these to be combined onto the screen.</p>

<p>By providing the common features, and for the rest offering both sensible defaults and an easy way to customise them, Mir is designed to support a range of possible designs. This series of articles demonstrates how to make use of the facilities Mir provides.</p>

<p>So far, all the articles in the series show features of the egmde â€˜desktop environmentâ€™ being implemented in the egmde program itself. But there are often reasons to add features in separate programs: these can be developed and updated separately, or even replaced to tailor the user experience.</p>

<p>Because such programs are part of the â€˜desktop environmentâ€™ they often use features of the compositor that are not (or should not be) available to ordinary applications. In particular, they might need to request that they are docked to an edge of the display or appear behind (or in front) of applications. These are things a normal Wayland application isnâ€™t expected to do but are part of shell-specific Wayland extensions.</p>

<p>Mir provides implementations of several of these â€˜shell componentâ€™ specific protocols, but leaves them disabled by default. In this article weâ€™re going to see how egmde enables these protocols just for shell components.</p>

<h2>Configuring shell components</h2>

<p>The first thing we need to do is identify the programs we want to run as shell components. In egmde, I recently added a configuration option â€˜shell-componentsâ€™ as follows:</p>

<pre class="programlisting">
  CommandLineOption{
    run_shell_components,
    &quot;shell-components&quot;,
    &quot;Colon separated shell components to launch on    
    startup&quot;, &quot;&quot;},</pre>
	
<p>This, like the options weâ€™ve seen in previous articles, is passed to the <code>run_with()</code> method of MirRunner. In common with other Mir configuration options, users of egmde can specify shell components on the command line, with an environment variable or in a config file. In this case, weâ€™ll just use a config file:</p>

<pre class="programlisting">
  echo shell-components=waybar &gt;&gt;
  ~/.config/egmde.config</pre>
  
<p>Oh, while weâ€™re at it, we ought to install â€˜waybarâ€™ â€“ a simple, Wayland based, docking bar that can be used for this article (it doesnâ€™t have to be Waybar, for example, â€˜mate-panelâ€™ works too).</p>

<pre class="programlisting">
  sudo apt install waybar</pre>
  
<h2>Identifying and running shell components</h2>

<p>Now we need to launch the shell components on startup, and also ensure that we can identify them later so that we can allow them access to the special Wayland protocol extensions. We do that by keeping a note of their process identifiers (see Listing 1).</p>

<table class="sidebartable">
	<tr>
		<td>
			<pre class="programlisting">
std::set&lt;pid_t&gt; shell_component_pids;
auto run_shell_components = 
  [&amp;](std::string const&amp; apps)
{
  for (auto i = begin(apps); i != end(apps); )
  {
    auto const j = find(i, end(apps), ':');
    shell_component_pids.insert(
      launcher.run_app(
        std::string{i, j},
        egmde::Launcher::Mode::wayland));
    if ((i = j) != end(apps)) ++i;
  }
};
			</pre>
		</td>
	</tr>
	<tr>
		<td class="title">Listing 1</td>
	</tr>
</table>

<p>The <code>run_shell_components</code> lambda is passed to the <code>CommandLineOption</code> we saw above and handles the <code>shell-components</code> option configured. Weâ€™ll use the list of <code>shell_component_pids</code> shortly.</p>

<h2>Configuring the Wayland protocol extensions</h2>

<p>The protocol extensions weâ€™re interested in for shell components are <code>wlr_layer_shell</code> and <code>xdg_output_manager</code>. We can, with the list of process identifiers we built earlier, enable these just for shell components as shown in Listing 2.</p>

<table class="sidebartable">
	<tr>
		<td>
			<pre class="programlisting">
// Protocols we're reserving for shell components
std::set&lt;std::string&gt; const shell_protocols{
  WaylandExtensions::zwlr_layer_shell_v1,
  WaylandExtensions::zxdg_output_manager_v1};
WaylandExtensions extensions;
for (auto const&amp; protocol : shell_protocols)
{
  extensions.enable(protocol);
}
extensions.set_filter([&amp;](Application const&amp; app,
  char const* protocol)
{
  if (shell_protocols.find(protocol) 
    == end(shell_protocols))
    return true;
  return shell_component_pids.find(pid_of(app)) 
    != end(shell_component_pids);
});
			</pre>
		</td>
	</tr>
	<tr>
		<td class="title">Listing 2</td>
	</tr>
</table>

<p>This configures <code>extensions</code> to enable these protocol extensions but also run all enabled protocol extensions through a filter that disables them for any processes not found in <code>shell_component_pids</code>.</p>

<p>The only thing left after this, is to pass <code>extensions</code> to the <code>run_with()</code> method of <code>MirRunner</code>.</p>

<h2>Running the changes</h2>

<p>You can install and run egmde as a snap:</p>

<pre class="programlisting">
  snap install egmde --classic --edge</pre>
  
<p>If you want to build it yourself, the source is on github, so you can download and build it (these instructions in Listing 3 are for Ubuntu, the details might vary for other distros).</p>

<table class="sidebartable">
	<tr>
		<td>
			<pre class="programlisting">
sudo apt-add-repository ppa:mir-team/release
sudo apt install libmiral-dev mir-graphics-drivers-desktop libwayland-dev
sudo apt install libfreetype6-dev libxkbcommon-dev libboost-filesystem-dev
sudo apt install qtwayland5
sudo apt install g++ cmake
git clone https://github.com/AlanGriffiths/egmde.git
mkdir -p egmde/build
cd egmde/build
cmake ..
make
sudo make install
			</pre>
		</td>
	</tr>
	<tr>
		<td class="title">Listing 3</td>
	</tr>
</table>

<p>Either way, you can then select <strong>egmde</strong> at the greeter.</p>

<h2>Conclusion</h2>

<p>The format of this article has changed from earlier ones in the series. There have been a lot of incremental improvements to egmde in since the last one and the changes discussed here were not simple to separate into a branch based on the previous article.</p>

<p>The current versions has, in addition to the â€˜shell componentâ€™ support discussed here, workspaces, and some additional keyboard shortcuts. (And quite a few bugs fixed.) The program has grown, but is still a manageable size for a â€˜hobby projectâ€™:</p>

<pre class="programlisting">
$ wc -l *.cpp *.h
  658 egfullscreenclient.cpp
  766 eglauncher.cpp
  115 egmde.cpp
  187 egshellcommands.cpp
  176 egwallpaper.cpp
  382 egwindowmanager.cpp
   53 egworker.cpp
  229 printer.cpp
  241 egfullscreenclient.h
   67 eglauncher.h
   80 egshellcommands.h
   58 egwallpaper.h
   83 egwindowmanager.h
   52 egworker.h
   54 printer.h
 3201 total</pre>
 
<p>Thereâ€™s still some way to go before it is a full featured â€˜desktop environmentâ€™, but Iâ€™ve found it usable for the majority of my computing needs.</p>

<h2>References</h2>

<p>The Mir homepage: <a href="https://mir-server.io/">https://mir-server.io/</a></p>

<p>The egmde git repo: <a href="https://github.com/AlanGriffiths/egmde">https://github.com/AlanGriffiths/egmde</a></p>

<p class="bio"><span class="author"><b>Alan Griffiths</b></span> Alan Griffiths has delivered working software and development processes to a range of organizations, written for a number of magazines, spoken at several conferences, and made many friends.</p>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
