new stuff

This commit is contained in:
Akko
2025-06-24 00:59:23 +02:00
parent de49cd6b49
commit fac0a2266d
63 changed files with 1481 additions and 4896 deletions

View File

@@ -1,7 +1,7 @@
<!DOCTYPE html>
<html lang="en">
<head>
<!-- 2025-04-24 -->
<!-- 2025-06-23 -->
<meta charset="utf-8" />
<meta name="viewport" content="width=100%, initial-scale=0.7" />
<title>Framework Laptop Review</title>
@@ -206,14 +206,13 @@
</div>
</div>
<div id="content" class="content">
<div id="outline-container-org9fdc0c1" class="outline-2">
<h2 id="org9fdc0c1">My Experience with the Framework Laptop</h2>
<div class="outline-text-2" id="text-org9fdc0c1">
<div id="outline-container-org30dea7d" class="outline-2">
<h2 id="org30dea7d">My Experience with the Framework Laptop</h2>
<div class="outline-text-2" id="text-org30dea7d">
</div>
<div id="outline-container-org3608292" class="outline-3">
<h3 id="org3608292">Ordering</h3>
<div class="outline-text-3" id="text-org3608292">
<div id="outline-container-orgace771d" class="outline-3">
<h3 id="orgace771d">Ordering</h3>
<div class="outline-text-3" id="text-orgace771d">
<p>
I&rsquo;d been eyeing the <a href="https:frame.work">Framework laptop</a> since somewhere in October 2021, but the EU release got delayed and they were very hesitant to give time estimates. I only managed to get my hands on it in late February, and I ended up having to have it delivered to France. I understand the difficulty of setting up logistics especially these days, but I broke my previous laptop and being stuck in limbo like this was not fun.
</p>
@@ -224,14 +223,13 @@ I asked their customer service to make a small change to the delivery address, b
</p>
</div>
</div>
<div id="outline-container-org2a837a9" class="outline-3">
<h3 id="org2a837a9">Set-up</h3>
<div class="outline-text-3" id="text-org2a837a9">
<div id="outline-container-orgd542c22" class="outline-3">
<h3 id="orgd542c22">Set-up</h3>
<div class="outline-text-3" id="text-orgd542c22">
</div>
<div id="outline-container-org3f19395" class="outline-4">
<h4 id="org3f19395">Hardware</h4>
<div class="outline-text-4" id="text-org3f19395">
<div id="outline-container-org8c01345" class="outline-4">
<h4 id="org8c01345">Hardware</h4>
<div class="outline-text-4" id="text-org8c01345">
<p>
I got the DIY edition with the (lowest-end) i5-1135G7 CPU, 2x16GB RAM. I brought my own 1TB SSD. The higher spec CPUs didn&rsquo;t seem worth the money to me. The RAM is probably overkill.
</p>
@@ -258,10 +256,9 @@ The more you look at it, the nicer it gets!
</p>
</div>
</div>
<div id="outline-container-orge4c4da6" class="outline-4">
<h4 id="orge4c4da6">Software</h4>
<div class="outline-text-4" id="text-orge4c4da6">
<div id="outline-container-org5014083" class="outline-4">
<h4 id="org5014083">Software</h4>
<div class="outline-text-4" id="text-org5014083">
<p>
I installed Gentoo GNU+Linux on the laptop, just like I have on my desktop. I used an Ubuntu live CD as the install medium together with the Gentoo stage3 tarball, and it worked well. I didn&rsquo;t really have to jump through any laptop-specific hoops, it was a very nice experience. I did use the dist-kernel rather than configuring my own.
</p>
@@ -270,10 +267,9 @@ I installed Gentoo GNU+Linux on the laptop, just like I have on my desktop. I us
The laptop held up well during compiling. It&rsquo;s not as fast as a desktop of course, but compile times are not limiting. I&rsquo;ve put this thing through bootstrapping GCC for a cross-compilation toolchain, which is just about the biggest compile job I&rsquo;ve ran, and it wasn&rsquo;t <i>that</i> painful.
</p>
</div>
<div id="outline-container-orga6cd787" class="outline-5">
<h5 id="orga6cd787">Display scaling</h5>
<div class="outline-text-5" id="text-orga6cd787">
<div id="outline-container-org920cf66" class="outline-5">
<h5 id="org920cf66">Display scaling</h5>
<div class="outline-text-5" id="text-org920cf66">
<p>
Simply setting <code>Xft.dpi: 192</code> in .Xresources was enough for the vast majority of applications to use 2x scaling, which looks very good on this display. This is on X11 obviously; I don&rsquo;t use Wayland.
</p>
@@ -283,36 +279,33 @@ The odd application requires its own scaling setting. Rofi requires setting <cod
</p>
</div>
</div>
<div id="outline-container-orgc55d80a" class="outline-5">
<h5 id="orgc55d80a">Display manager</h5>
<div class="outline-text-5" id="text-orgc55d80a">
<div id="outline-container-org0b35370" class="outline-5">
<h5 id="org0b35370">Display manager</h5>
<div class="outline-text-5" id="text-org0b35370">
<p>
I used SDDM which works very well. I wanted to go for something a bit fancier looking, and this delivers. I don&rsquo;t usually use things in the whole QT ecosystem, so it&rsquo;s refreshing.
</p>
</div>
</div>
<div id="outline-container-orge4fd960" class="outline-5">
<h5 id="orge4fd960">Hibernate/suspend-to-disk</h5>
<div class="outline-text-5" id="text-orge4fd960">
<div id="outline-container-org39a8c54" class="outline-5">
<h5 id="org39a8c54">Hibernate/suspend-to-disk</h5>
<div class="outline-text-5" id="text-org39a8c54">
<p>
This required setting up a swap file and setting a kernel command line parameter to refer to it, but it was easy to do. It works well. I&rsquo;ve observed the laptop auto-hibernating when the battery runs out, but it doesn&rsquo;t do this reliably, so I should probably configure it myself.
</p>
</div>
</div>
<div id="outline-container-orgd62046c" class="outline-5">
<h5 id="orgd62046c"><a href="http://guake-project.org/">Guake</a>-like transient terminal</h5>
<div class="outline-text-5" id="text-orgd62046c">
<div id="outline-container-org749aff6" class="outline-5">
<h5 id="org749aff6"><a href="http://guake-project.org/">Guake</a>-like transient terminal</h5>
<div class="outline-text-5" id="text-org749aff6">
<p>
Using some <code>fish</code> scripts, <code>bspwm</code>, <code>picom</code> and <code>xst</code> I rigged up a transient, transparent terminal to use for quick shell jobs. I used the scripts and config file in <a href="#org1977cca">Appendix A</a> to do this. The implementation is a bit hacky, and it&rsquo;s not impossible to break, but it serves my purposes well (and more important, it was fun to make)!
Using some <code>fish</code> scripts, <code>bspwm</code>, <code>picom</code> and <code>xst</code> I rigged up a transient, transparent terminal to use for quick shell jobs. I used the scripts and config file in <a href="#org374f7ed">Appendix A</a> to do this. The implementation is a bit hacky, and it&rsquo;s not impossible to break, but it serves my purposes well (and more important, it was fun to make)!
</p>
</div>
</div>
<div id="outline-container-orge3bccc1" class="outline-5">
<h5 id="orge3bccc1">Wallpaper-setting script</h5>
<div class="outline-text-5" id="text-orge3bccc1">
<div id="outline-container-orgd249a13" class="outline-5">
<h5 id="orgd249a13">Wallpaper-setting script</h5>
<div class="outline-text-5" id="text-orgd249a13">
<p>
I wrote a script to set a random wallpaper.
</p>
@@ -322,28 +315,27 @@ I wrote a script to set a random wallpaper.
<span class="org-keyword">import</span> os
<span class="org-keyword">from</span> random <span class="org-keyword">import</span> choice
<span class="org-variable-name">pape_path</span> = os.path.expandvars(<span class="org-string">"$HOME/Pictures/Wallpapers"</span>)
<span class="org-variable-name">pape_path</span> <span class="org-operator">=</span> os.path.expandvars(<span class="org-string">"$HOME/Pictures/Wallpapers"</span>)
<span class="org-keyword">def</span> <span class="org-function-name">set_wallpaper</span>():
<span class="org-variable-name">files</span> = os.popen(f<span class="org-string">"ls </span>{pape_path}<span class="org-string">"</span>).read().split(<span class="org-string">'\n'</span>)
<span class="org-variable-name">pape</span> = choice(files)
<span class="org-variable-name">pp</span> = os.path.join(pape_path, pape)
<span class="org-variable-name">files</span> <span class="org-operator">=</span> os.popen(f<span class="org-string">"ls </span>{pape_path}<span class="org-string">"</span>).read().split(<span class="org-string">'</span><span class="org-constant">\n</span><span class="org-string">'</span>)
<span class="org-variable-name">pape</span> <span class="org-operator">=</span> choice(files)
<span class="org-variable-name">pp</span> <span class="org-operator">=</span> os.path.join(pape_path, pape)
os.popen(f<span class="org-string">"hsetroot -full </span>{pp}<span class="org-string">"</span>)
os.popen(f<span class="org-string">"echo </span>{pp}<span class="org-string"> &gt; /tmp/wallpaper"</span>)
<span class="org-keyword">if</span> <span class="org-builtin">__name__</span> == <span class="org-string">"__main__"</span>:
<span class="org-keyword">if</span> <span class="org-builtin">__name__</span> <span class="org-operator">==</span> <span class="org-string">"__main__"</span>:
set_wallpaper()
</pre>
</div>
</div>
</div>
<div id="outline-container-org16c82e4" class="outline-5">
<h5 id="org16c82e4">Lockscreen</h5>
<div class="outline-text-5" id="text-org16c82e4">
<div id="outline-container-org1269632" class="outline-5">
<h5 id="org1269632">Lockscreen</h5>
<div class="outline-text-5" id="text-org1269632">
<p>
I hacked together some <a href="#org8c10df1">pretty crappy code</a> to lock the screen using <code>i3lock</code>, with my wallpaper composed with a little lock icon as the background. Very overengineered.
I hacked together some <a href="#org0fc6761">pretty crappy code</a> to lock the screen using <code>i3lock</code>, with my wallpaper composed with a little lock icon as the background. Very overengineered.
</p>
<p width="60%" class="center">
@@ -356,35 +348,33 @@ Is there a better lockscreen out there that will let me set my own image as the
</p>
</div>
</div>
<div id="outline-container-org833202b" class="outline-5">
<h5 id="org833202b">TODO</h5>
<div class="outline-text-5" id="text-org833202b">
<div id="outline-container-org637f987" class="outline-5">
<h5 id="org637f987"><span class="todo TODO">TODO</span> </h5>
<div class="outline-text-5" id="text-org637f987">
</div>
<ul class="org-ul">
<li><a id="orga65eb89"></a>Battery level notifications<br></li>
<li><a id="org70971ed"></a>sleep-then-hibernate<br></li>
<li><a id="orgf84adca"></a>Battery tuning<br></li>
<li><a id="org5e221c3"></a>Battery level notifications<br></li>
<li><a id="orgb55190f"></a>sleep-then-hibernate<br></li>
<li><a id="org3a44924"></a>Battery tuning<br></li>
</ul>
</div>
</div>
</div>
<div id="outline-container-org272cd0d" class="outline-3">
<h3 id="org272cd0d">Impressions</h3>
<div class="outline-text-3" id="text-org272cd0d">
<div id="outline-container-orgde04702" class="outline-3">
<h3 id="orgde04702">Impressions</h3>
<div class="outline-text-3" id="text-orgde04702">
</div>
<div id="outline-container-org3df8987" class="outline-5">
<h5 id="org3df8987">Build Quality</h5>
<div class="outline-text-5" id="text-org3df8987">
<div id="outline-container-org8a66df3" class="outline-5">
<h5 id="org8a66df3">Build Quality</h5>
<div class="outline-text-5" id="text-org8a66df3">
<p>
The laptop is made of aluminium and feels solid but light. The screen does seem pretty flimsy, though. I probably wouldn&rsquo;t want to drop this thing. It looks sleek and elegant, but pretty muted.
</p>
</div>
</div>
<div id="outline-container-org3ee804a" class="outline-5">
<h5 id="org3ee804a">Screen</h5>
<div class="outline-text-5" id="text-org3ee804a">
<div id="outline-container-org2668431" class="outline-5">
<h5 id="org2668431">Screen</h5>
<div class="outline-text-5" id="text-org2668431">
<p>
This is my first time ever using a high-DPI screen, and I&rsquo;m very impressed by it. Text looks unbelievably crisp and pleasant to read. I was somewhat worried about the linux high DPI situation, but I am having no issues whatsoever.
</p>
@@ -398,57 +388,51 @@ The brightness goes up quite high, but colours feel somewhat washed out at high
</p>
</div>
</div>
<div id="outline-container-orgae6b1ca" class="outline-5">
<h5 id="orgae6b1ca">Keyboard</h5>
<div class="outline-text-5" id="text-orgae6b1ca">
<div id="outline-container-orge9b9091" class="outline-5">
<h5 id="orge9b9091">Keyboard</h5>
<div class="outline-text-5" id="text-orge9b9091">
<p>
Framework seems to advertise their keyboard as having particularly deep travel, but it mostly just feels like any chiclet keyboard to me. Not a bad chiclet keyboard, but not that great, either. The layout is fine, but it makes me miss the thinkpad.
</p>
</div>
</div>
<div id="outline-container-org532c3ec" class="outline-5">
<h5 id="org532c3ec">Touchpad</h5>
<div class="outline-text-5" id="text-org532c3ec">
<div id="outline-container-orgadfdf3f" class="outline-5">
<h5 id="orgadfdf3f">Touchpad</h5>
<div class="outline-text-5" id="text-orgadfdf3f">
<p>
I&rsquo;ve never had a decent touchpad before, so I was pleasantly surprised. I expected to miss the trackpoint on the thinkpad a lot, but this is fine, though it&rsquo;s still a step down. Pinch to zoom doesn&rsquo;t work very well, but I don&rsquo;t use that functionality a lot. I miss having dedicated mouse buttons; the clicking functionality on this touchpad works fine for me, but it&rsquo;s hard not to mess up left/middle/right click. That&rsquo;s a good incentive for me to practice relying on the mouse less, though. There&rsquo;s plenty of <a href="https://linuxtouchpad.org/">work being done</a> on the Linux touchpad experience software-side, too. It&rsquo;s a nice time to be a linux laptop user!
</p>
</div>
</div>
<div id="outline-container-orgeb70cd6" class="outline-5">
<h5 id="orgeb70cd6">Battery</h5>
<div class="outline-text-5" id="text-orgeb70cd6">
<div id="outline-container-orgd9a77f3" class="outline-5">
<h5 id="orgd9a77f3">Battery</h5>
<div class="outline-text-5" id="text-orgd9a77f3">
<p>
With the disclaimer that I haven&rsquo;t tested very intensely and I haven&rsquo;t tuned power settings very much. <br>
I seem to get about 6.5 hours of real-world use time when using Emacs and doing light web browsing. I don&rsquo;t have a good benchmark for more intensive tasks, but compiling does hit the battery pretty hard. All in all I&rsquo;m very happy with it, getting decent battery life on Linux is hard. It might be worth eventually buying a power bank for it though, for travel~
</p>
</div>
</div>
<div id="outline-container-org6cc2b8e" class="outline-5">
<h5 id="org6cc2b8e">Expansion cards/ports</h5>
<div class="outline-text-5" id="text-org6cc2b8e">
<div id="outline-container-org8eaaee2" class="outline-5">
<h5 id="org8eaaee2">Expansion cards/ports</h5>
<div class="outline-text-5" id="text-org8eaaee2">
<p>
The little expansion cards are one of Framework&rsquo;s big marketing things. I think they&rsquo;re pretty neat, though I don&rsquo;t always quite understand the way people talk about them, as &ldquo;dongle killers&rdquo;. I would find hotswapping these about equally obnoxious as carrying dongles. The idea of aftermarket expansion cards is interesting, though - these are low level, high bandwidth ports, with I think similar capabilities to the ExpressCard ports on old business laptops, but more modern with a USB-C port. I&rsquo;m looking forward to the USB4 era!
</p>
</div>
</div>
<div id="outline-container-orgf40041c" class="outline-5">
<h5 id="orgf40041c">Performance</h5>
<div class="outline-text-5" id="text-orgf40041c">
<div id="outline-container-org4716b34" class="outline-5">
<h5 id="org4716b34">Performance</h5>
<div class="outline-text-5" id="text-org4716b34">
<p>
So far I haven&rsquo;t felt limited by performance at all, the experience has been really snappy. I haven&rsquo;t thrown particularly difficult things at it, though, but that&rsquo;s fine - most of what I do on a laptop is reading, web browsing, and text editing. I played some Factorio on it and that seemed fine, but using the touchpad felt limiting so I didn&rsquo;t play very much.
</p>
</div>
</div>
</div>
<div id="outline-container-orga429851" class="outline-3">
<h3 id="orga429851">Closing words</h3>
<div class="outline-text-3" id="text-orga429851">
<div id="outline-container-org4e8b0c4" class="outline-3">
<h3 id="org4e8b0c4">Closing words</h3>
<div class="outline-text-3" id="text-org4e8b0c4">
<p>
Getting this laptop set up has been really fun! It&rsquo;s a good opportunity to take stock of where we&rsquo;re at. On the hardware side, I am very impressed that it&rsquo;s now possible to make a laptop that&rsquo;s this user-servicable, this well-specced and still not <i>that</i> expensive. It&rsquo;s a reminder of how much better things could be.
</p>
@@ -463,10 +447,9 @@ Personally, I&rsquo;m getting a rare chance to critically examine all the little
</div>
</div>
</div>
<div id="outline-container-org1977cca" class="outline-2">
<h2 id="org1977cca">Appendix A: Transient Terminal Sources</h2>
<div class="outline-text-2" id="text-org1977cca">
<div id="outline-container-org374f7ed" class="outline-2">
<h2 id="org374f7ed">Appendix A: Transient Terminal Sources</h2>
<div class="outline-text-2" id="text-org374f7ed">
<p>
<code>togglescratch</code>
</p>
@@ -519,9 +502,9 @@ Personally, I&rsquo;m getting a rare chance to critically examine all the little
<p>
<code>picom.conf</code>
</p>
<pre class="example">
fading = true;
#no-fading-openclose = true;
<div class="org-src-container">
<pre class="src src-nil">fading = true;
no-fading-openclose = true;
fade-delta = 5;
vsync = true;
backend="glx";
@@ -530,25 +513,25 @@ opacity-rule=["90:name = 'scratchterminal'"];
</pre>
</div>
</div>
<div id="outline-container-org8c10df1" class="outline-2">
<h2 id="org8c10df1">Appendix B: lock.py</h2>
<div class="outline-text-2" id="text-org8c10df1">
</div>
<div id="outline-container-org0fc6761" class="outline-2">
<h2 id="org0fc6761">Appendix B: lock.py</h2>
<div class="outline-text-2" id="text-org0fc6761">
<div class="org-src-container">
<pre class="src src-python"><span class="org-comment-delimiter">#</span><span class="org-comment">!/usr/bin/python3</span>
<span class="org-keyword">import</span> os
<span class="org-keyword">import</span> sys
<span class="org-keyword">import</span> time
<span class="org-keyword">if</span> <span class="org-builtin">__name__</span> == <span class="org-string">"__main__"</span>:
<span class="org-variable-name">width</span>, <span class="org-variable-name">height</span>, <span class="org-variable-name">lwidth</span>, <span class="org-variable-name">lheight</span> = <span class="org-highlight-numbers-number">2256</span>, <span class="org-highlight-numbers-number">1504</span>, <span class="org-highlight-numbers-number">320</span>, <span class="org-highlight-numbers-number">320</span>
icon = <span class="org-string">"$HOME/Pictures/lock_small.png"</span>
pape = os.popen(<span class="org-string">"cat /tmp/wallpaper"</span>).read()[:-<span class="org-highlight-numbers-number">1</span>]
cache = os.popen(<span class="org-string">"cat /tmp/lockscreen_cache"</span>).read()[:-<span class="org-highlight-numbers-number">1</span>]
<span class="org-keyword">if</span> <span class="org-builtin">__name__</span> <span class="org-operator">==</span> <span class="org-string">"__main__"</span>:
<span class="org-variable-name">width</span>, <span class="org-variable-name">height</span>, <span class="org-variable-name">lwidth</span>, <span class="org-variable-name">lheight</span> <span class="org-operator">=</span> <span class="org-highlight-numbers-number">2256</span>, <span class="org-highlight-numbers-number">1504</span>, <span class="org-highlight-numbers-number">320</span>, <span class="org-highlight-numbers-number">320</span>
<span class="org-variable-name">icon</span> <span class="org-operator">=</span> <span class="org-string">"$HOME/Pictures/lock_small.png"</span>
<span class="org-variable-name">pape</span> <span class="org-operator">=</span> os.popen(<span class="org-string">"cat /tmp/wallpaper"</span>).read()[:<span class="org-operator">-</span><span class="org-highlight-numbers-number">1</span>]
<span class="org-variable-name">cache</span> <span class="org-operator">=</span> os.popen(<span class="org-string">"cat /tmp/lockscreen_cache"</span>).read()[:<span class="org-operator">-</span><span class="org-highlight-numbers-number">1</span>]
<span class="org-keyword">if</span> pape != cache <span class="org-keyword">or</span> <span class="org-string">'--ignore-cache'</span> <span class="org-keyword">in</span> sys.argv:
<span class="org-keyword">if</span> pape <span class="org-operator">!=</span> cache <span class="org-keyword">or</span> <span class="org-string">'--ignore-cache'</span> <span class="org-keyword">in</span> sys.argv:
os.popen(f<span class="org-string">"convert </span>{pape}<span class="org-string"> -resize </span>{width}<span class="org-string">x</span>{height}<span class="org-string"> -background black -gravity center -extent </span>{width}<span class="org-string">x</span>{height}<span class="org-string"> /tmp/wallpaper.png"</span>).read()
os.popen(f<span class="org-string">"convert -composite /tmp/wallpaper.png </span>{icon}<span class="org-string"> -geometry +</span>{width//2 - lwidth//2}<span class="org-string">+</span>{height//2 - lheight//2}<span class="org-string"> /tmp/wallpaper.png"</span>).read()
os.popen(f<span class="org-string">"convert -composite /tmp/wallpaper.png </span>{icon}<span class="org-string"> -geometry +</span>{width<span class="org-operator">//</span>2 <span class="org-operator">-</span> lwidth<span class="org-operator">//</span>2}<span class="org-string">+</span>{height<span class="org-operator">//</span>2 <span class="org-operator">-</span> lheight<span class="org-operator">//</span>2}<span class="org-string"> /tmp/wallpaper.png"</span>).read()
os.popen(f<span class="org-string">"echo </span>{pape}<span class="org-string"> &gt; /tmp/lockscreen_cache"</span>)
os.popen(<span class="org-string">"i3lock -u -i /tmp/wallpaper.png"</span>)
@@ -560,7 +543,7 @@ opacity-rule=["90:name = 'scratchterminal'"];
</div>
</div>
<div id="postamble" class="status">
<div id='footer'><div id='publish-date'>Published: 2022-03-17</div><div id='modified-date'>Last modified: 2023-03-16</div><hr>
<div id='footer'><div id='publish-date'>Published: 2022-03-17</div><div id='modified-date'>Last modified: 2023-01-10</div><hr>
If you have any comments about this page, you can email me at: <br>
<b>akko [shift-2] nakadashi -dot- lol</b><br>
And I may include them on the website!<br>