<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Open-SourceonDocs</title><link>https://hiraethecho.github.io/docs/tags/open-source/</link><description>Recent contentinOpen-SourceonDocs</description><generator>Hugo --0.152.2</generator><language>en</language><managingEditor>wyz2016zxc@outlook.com(Hiraeth)</managingEditor><webMaster>wyz2016zxc@outlook.com(Hiraeth)</webMaster><lastBuildDate>Mon, 16 Mar 2026 15:39:39 +0800</lastBuildDate><atom:link href="https://hiraethecho.github.io/docs/tags/open-source/index.xml" rel="self" type="application/rss+xml"/><item><title>折腾的linux+X11+dwm</title><link>https://hiraethecho.github.io/docs/project/dwm/</link><pubDate>Mon, 29 Jul 2024 00:00:00 +0000</pubDate><author>wyz2016zxc@outlook.com(Hiraeth)</author><guid>https://hiraethecho.github.io/docs/project/dwm/</guid><description>关于linux C dwm等</description><content:encoded><![CDATA[<h1 id="近期折腾的archlinux">
  <a class="anchor inpage" href="#%e8%bf%91%e6%9c%9f%e6%8a%98%e8%85%be%e7%9a%84archlinux">#</a>近期折腾的archlinux</h1>
<p>也算是一些业余学习吧。先叠个甲，业余学习所以可能有错误，只是个人理解。</p>
<h2 id="linux">
  <a class="anchor inpage" href="#linux">##</a>linux</h2>
<p>linux内核的功能是调用硬件，为程序分配使用<br>
GNU is not unix. 在斯托曼的组织下，为了取代unix开发了一系列自由软件，但是没有内核，用了linus的内核。<br>
shell是包裹在内核外面的外壳，用来和内核沟通。并且有POSIX的shell标准，来规范shell的语言。常见的shell有<code>bash</code> <code>zsh</code>等。而另一个常见的<code>fish</code>不符合POSIX.<br>
Terminal是使用shell的界面。最基础的terminal就是tty，是过去计算机的一个物理部件（console控制台是另一个过去的物理部件，直接控制机器。tty是<em>远程</em>的控制方式。）常见的terminal有alacritty、kitty和各大桌面环境配套的。</p>
<p>linux的哲学之一在于，每一个程序只做一件事，并努力做到最好。像word这样的windows应用，常被认为是臃肿的，“每个人只用到了全部功能的1%
”。但这是因为“每个人用的都是不同的1%”。然而在linux的世界里，为了自己需要的那1%，通常只需要安装对应的那1%。当然，困难之处在于在广大社区中找到对应的程序，并且使自己所需要的各种程序和谐共存互相协调。</p>
<p>GNU/linux有各种发行版，虽然个人感到主要区别在包管理器和预装软件。包管理器的其中一个功能就是尽量保证各个程序可以互相协调，自动解决程序的依赖等问题。至于预装软件可能是发行版制作者的个人倾向。<br>
BTW，I use arch.</p>
<p>Arch发行版是一个Geek风格的linux发行版，目的在于用户尽可能自由配置自己的linux（当然似乎比不上Gentoo甚至lfs）。它有两个特点，其一是滚动更新，即没有稳定版本，总可以获得最新的软件版本。好处是获得最新功能，第一时间获得已知bug的修复；坏处是，也可以第一时间获得bug，以及面临软件之间版本不兼容的问题（这也是linux哲学的负面影响）。第二个特点是AUR，既用户仓库。每个发行版的包管理器通常有对应的软件源，而arch除了官方软件源外还有用户仓库，即每个用户都可以把应用按照规范打包供他人使用。优点在于AUR里什么都有，缺点在于很多应用无人负责或没有充分维护。</p>
<h2 id="图形化界面x11">
  <a class="anchor inpage" href="#%e5%9b%be%e5%bd%a2%e5%8c%96%e7%95%8c%e9%9d%a2x11">##</a>图形化界面X11</h2>
<p>为了在tty外情景使用linux，需要图形化界面。</p>
<p>X11是linux的一个图形化界面的协议，每个图形化程序并不是靠它自己显示画面，而是通过协议用Xorg来创建图形的。除此之外还有混成器（例如picom）来提供一些画面特效等。wayland是另一套图形化方案，本身替代了Xorg和混成器的功能。</p>
<p>linux下的桌面环境（Desktop Environment），如KDE GNOME Xfce等，提供了一整套日常使用的基本功能，例如窗口管理，应用启动器，托盘，设置，蓝牙，网络等。但事实上如果追求极简，那么仅仅使用窗口管理器（Windows Manager）也是可行的。</p>
<p>Windows Manager，通俗的解释，就是显示应用程序的窗口，并且拖动、调整大小、最大化等功能的部分，不包括壁纸、声音网络蓝牙键盘触摸板等设置、应用启动器和托盘。<br>
常见的独立窗口管理器包括i3，openbox，awesome等。而我选择的是dwm，属于suckless系列，用C语言编写，代码仅2000余行，更改配置需要修改源码重新编译，添加功能是通过.diff文件打补丁实现。</p>
<h2 id="dwm和c">
  <a class="anchor inpage" href="#dwm%e5%92%8cc">##</a>dwm和C</h2>
<p>这几周时间一直在加强的我dwm，被迫学习了C语言的使用，以及基于lazygit的自娱自乐式历史管理。</p>
<p>C语言是面向过程的，以函数为中心的。但实际写dwm代码的时候，则主要用“面向对象”的思路在写。对象里的函数和变量是用指针或者全局变量，实现地很曲折。</p>
<p>C语言算是很底层的编程语言了，指针可能是其最重要的特性。指针直接指向变量的存储地址，非常有趣。在函数调用时，传参传指针进去，可以直接在物理存贮的意义上理解程序是如何使用和修改变量的值的。另外还有位运算，也很有趣。</p>
<p>C语言同时还是非常省内存（这里应该指的是内存吗？）的语言，每次写一个新变量都小心翼翼地。遥想大一学C语言的时候，还要注意变量要在代码块之前先声明，开个动态数组都麻烦的一匹，用完还要free掉。后来看见其他语言随便新建变量，太难接受了。不过这种节省也导致一些逆天的feature.例如一个结构体</p>
<details open>
    <summary>C</summary><pre
        class="chroma codeblock"
      ><code class="language-C" data-lang="C"
          ><span style="display:flex;"><span><span style="color:#66d9ef">typedef</span> <span style="color:#66d9ef">struct</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">int</span> i;
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">float</span> f;
</span></span><span style="display:flex;"><span>} Arg1;</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>那么一个Arg就会有两个成员。但是还有一种操作</p>
<details open>
    <summary>C</summary><pre
        class="chroma codeblock"
      ><code class="language-C" data-lang="C"
          ><span style="display:flex;"><span><span style="color:#66d9ef">typedef</span> <span style="color:#66d9ef">union</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">int</span> i;
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">float</span> f;
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">void</span> <span style="color:#f92672">*</span>v;
</span></span><span style="display:flex;"><span>} Arg2;</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>乍一看和上一个差不多，但这个<code>union</code>的意思是，<code>Arg2</code>只能有一个类型。当创建一个<code>Arg1 a1</code>时，会给 <code>a1.i</code>和<code>a1.f</code>都分配地址。但是<code>Arg2 a2</code>就只有一个地址，当用了<code>a2.i=1</code>之后就不能再赋值<code>a2.f</code>了。这样如果不同函数的输入一个是<code>int</code>另一个是<code>float</code>，那就可以都写成<code>Arg2</code>，十分优雅。但是需要复杂功能是就很难用。<br>
除此之外，这个<code>void *v</code>也是个奇妙的用法，只要用上强制类型转换<code>Client *c=(Client *)v</code>就可以很灵活的使用各种类型的变量了。</p>
<h2 id="">
  <a class="anchor inpage" href="#">##</a></h2>
<p>最后，可以在我的
找到我的dotfiles和dwm。还没有整理，也没文档，以后有时间心情再说吧。</p>
<h2 id="tabbed-scratchpad">
  <a class="anchor inpage" href="#tabbed-scratchpad">##</a>tabbed scratchpad</h2>
<p><code>st -c class -n name</code> with <code>precmd () {print -Pn &quot;\e]0;%~\a&quot;}</code> in <code>.zshrc</code></p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">_NET_WM_ICON_NAME(UTF8_STRING) = &#34;~&#34;
WM_ICON_NAME(UTF8_STRING) = &#34;~&#34;
WM_CLASS(STRING) = &#34;name&#34;, &#34;class&#34;
_NET_WM_NAME(UTF8_STRING) = &#34;~&#34;
WM_NAME(UTF8_STRING) = &#34;~&#34;</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p><code>tabbed -n &quot;scratchpad&quot; -c -r 2 st -w '' -g 150x40 -c class -n name</code> with <code>precmd () {print -Pn &quot;\e]0;%~\a&quot;}</code> in <code>.zshrc</code></p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">WM_NAME(UTF8_STRING) = &#34;~&#34;
_NET_WM_NAME(UTF8_STRING) = &#34;~&#34;
WM_CLASS(STRING) = &#34;scratchpad&#34;, &#34;tabbed&#34;</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p><strong>summary</strong>: In <code>WM_CLASS(STRING)=&quot;name&quot;,&quot;class&quot;</code>, <code>&quot;name&quot;</code> is for <code>st -n name</code> and <code>tabbed -n name</code>, and is also <code>instance</code> in <code>rules</code>; <code>class</code> is for <code>st -c class</code>, and class of <code>tabbed</code> is always <code>tabbed</code>.</p>
<p>origin <code>manage()</code>:</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">  selmon-&gt;tagset[selmon-&gt;seltags] &amp;= ~scratchtag;
  if (!strcmp(c-&gt;name, scratchpadname)) {
    c-&gt;mon-&gt;tagset[c-&gt;mon-&gt;seltags] |= c-&gt;tags = scratchtag;
    c-&gt;isfloating = True;
  }</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>we can modify to</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">void manage(Window w, XWindowAttributes *wa) {
  Client *c, *t = NULL;
&#43; XClassHint ch = {NULL, NULL};
&#43; const char *class, *instance;
    ...
&#43; XGetClassHint(dpy, c-&gt;win, &amp;ch);
&#43;  instance = ch.res_name ? ch.res_name : broken;
  selmon-&gt;tagset[selmon-&gt;seltags] &amp;= ~scratchtag;
~ if (!strcmp(instance, scratchpadname)) {
    c-&gt;mon-&gt;tagset[c-&gt;mon-&gt;seltags] |= c-&gt;tags = scratchtag;
    c-&gt;isfloating = True;
  }
}</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>btw, <code>apply_rules</code>:</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">  XGetClassHint(dpy, c-&gt;win, &amp;ch);
  class = ch.res_class ? ch.res_class : broken;
  instance = ch.res_name ? ch.res_name : broken;

  for (i = 0; i &lt; LENGTH(rules); i&#43;&#43;) {
    r = &amp;rules[i];
    if ((!r-&gt;title || strstr(c-&gt;name, r-&gt;title)) &amp;&amp;
        (!r-&gt;class || strstr(class, r-&gt;class)) &amp;&amp;
        (!r-&gt;instance || strstr(instance, r-&gt;instance))) {
      c-&gt;isfloating = r-&gt;isfloating;
      c-&gt;tags |= r-&gt;tags;
      c-&gt;opacity = r-&gt;opacity;
      c-&gt;unfocusopacity = r-&gt;unfocusopacity;
      for (m = mons; m &amp;&amp; m-&gt;num != r-&gt;monitor; m = m-&gt;next) ;
      if (m)
        c-&gt;mon = m;
    }
  }</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script>]]></content:encoded></item></channel></rss>