Searching txt.sour.is

Twts matching #like
Sort by: Newest, Oldest, Most Relevant

Okay, so, my website also includes my code / git repos, and those are made browsable by stagit. What I don’t like about this (these days) is that this includes all the diffs of my commits. In other words: All my code.

This makes it super easy for malicious crawlers to slurp up valuable data. I don’t like that.

I’m thinking about switching to this instead:

https://movq.de/git2/

It still shows project infos and there are Atom feeds, but to get the code, you have to actually clone the repos.

🤔

(If you spot any bugs, let me know.)

⤋ Read More
↳ In-reply-to » I should really fix this damn bug where new replies to read replies to unknown conversation roots are not showing up in tt. I run into this bug almost daily for weeks now.

@prologic@twtxt.net A screenshot won’t help in this case, as you don’t see anything. :-D It starts off just fine with a conversation tree like that:

Unknown conversation root
└╴Read reply
  └╴Read subreply

Everything works. After reloading the feeds, a new message becomes part of the conversation, so the conversation e.g. looks:

Unknown conversation root
└╴Read reply
  ├╴Read subreply
  └╴Unread subreply

However, the bug is that the whole conversation is not shown at all. None of the three (or four with the root) messages appear in the message tree view. My recursive SQL determining the messages to display is clearly broken.

⤋ Read More
↳ In-reply-to » 📣 ACTION REQUIRED: Hey folks 👋 For those of you whom are using the Twtxt App either via the Hosted option or on your own twtd instnace or via Github/Gitea or any other publishing backend (doesn't amtter). Please read.

IMPORTANT: Treat the re oery code like a password.

⤋ Read More

Posting the review and plan here for posterity as it is related to this thread: https://canvas.mills.io/a/6QVGjzRW

The PR(s) as-is will likely not go ahead I’m afraid. More work to be done, but this is basically all about the “Recovery” story and how to anchor and notion of an “account” without well umm an account 🤣

⤋ Read More

Unread messages are yellow, while read messages are white in tt. Focusing them just alternates the fore- and background colors. With the old color scheme, I disliked that inline code and code blocks were basically just the opposite of normal text. Hence, unread code was white and read code yellow. I found this often confusing, especially with larger code blocks. Sure, there are the timestamp and author columns that still show the usual white (read) and yellow (unread) background for selected messages, but still.

This is how it was before with unread messages:

Image

Before with read messages:

Image

So, I just reworked the code styles. Not sure if I like that or if it is actually an improvement. Unread code is teal on gray when not in focus and becomes blue on orange when focused. I thought the dark gray code background on a black regular background is still nice and subtle. The same similarity in colors for focused messages meant to go with an orange code background on a yellow regular background. The teal was too light, so went with a blue foreground color:

Image

When read and unfocused, the new color scheme calls for the same code style teal on dark gray. However, with white as the main background for selected messages, I went with a light gray code background and a blue code foreground. Again, the contrast with white and teal wasn’t good enough. Vice versa, blue on dark gray is also not all that readable:

Image

It looks like a parrot. Let’s see if I begin to like it.

⤋ Read More
↳ In-reply-to » I trip over this in our code at work all the time.

@movq@www.uninformativ.de The nice thing about properties is that you can compute and cache things on the fly at first attempt and also ensure validation for writing. But like you said, since it’s not obvious that reading or writing might do some more things, it’s strongly advised to avoid doing expensive stuff disguised as properties.

I reckon the vast majority of property use cases is to provide read-only access. At least that was my impression when I was doing a lot more in Python.

Personally, I think that this just reads a lot nicer:

oink.my_property
oink.my_property = 42

Than:

oink.get_my_property()
oink.set_my_property(42)

Btw, any field access is implemented using method calls. I might be wrong, but I believe there’s always __getattr__ and __setattr__ involved. 8-)

⤋ Read More

I trip over this in our code at work all the time.

Python has this concept of “properties”:

class Oink:
    def __init__(self):
        self._foo = 3

    @property
    def my_property(self):
        return self._foo


a = Oink()
print(a.my_property)

my_property() is a method but it can be used as if it were a field.

This can also be used to define a setter:

class Oink:
    def __init__(self):
        self._foo = 3

    @property
    def my_property(self):
        return self._foo

    @my_property.setter
    def my_property(self, value):
        self._foo = 123 * value

Because, for some reason, Python people don’t like getters and setters. Instead, they hide it behind a property.

The result is, when you read this:

a.my_property = 5
print(a.my_property)

You have no idea that this actually calls a method.

⤋ Read More

@david@daiwei.me Oh, really? I thought I’ve posted compose view screenshots before. Anyway. Glad you like it as much as I do. :-)

The update interval has always been one second. I just didn’t remember and thus tried to time it by watching the preview update while typing. It felt like roughly under two seconds, but apparently my inner clock was off. After taking the screenshot and then examining it more closely, I noticed that the interval is stated right in the UI. :-D So, I just amended my message and didn’t bother taking a new screenshot. I figured I just leave it alone and see who spots the change, if at all. And, of course, you found the easter egg. Congrats, mate! 8-)

⤋ Read More
↳ In-reply-to » @lyse Ahh yes, but tt has a "draft" mode right? You didn't publish, then edit over and over did you? 😅

@prologic@twtxt.net Not sure if this really counts as a draft mode or this is what you had in mind. I just was in the editor for ages and didn’t close it. tt provides an integrated preview for the rendered message in there. It automatically updates every second.

Here’s a screenshot of the compose view with the conversation context on the top to which to reply to, the editor in the middle and the almost-live preview at the bottom, I hope it’s big enough:

Image

But it’s not like I hit the “Add message” button in the compose view (the one currently selected on the screenshot), see the message in the conversation tree and then come back into the compose view to continue editing. There’s no edit functionality in tt. Once the message is appended to my twtxt.txt file on disk, all I can do is edit it with vim. The U+2028 line breaks are really annoying to deal with (I’m sure I could do something about that if I spent the time), so I try to avoid that at all costs.

Once new messages have been added to my local file, I then manually upload the file to my server in a separate terminal. There’s no upload command integrated into tt. Right from my very first message in the beginning, I’ve always done it exactly like that. I’m used to this and it really doesn’t bother me. But I can see that others might not be fans of that at all. I might add an upload mechanism to tt at some point in the future.

⤋ Read More

I really think I should go back to Java.

Writing programs in Python is so exhausting. I want a compiler and I want static typing. No, linters and type checkers and IDEs are not good enough. Compilers catch way more errors in advance.

Rust is also exhausting. They’re constantly adding language features and, at the same time, the runtime library remains tiny and you need 3rd party libraries for everything. Many of those are still at version 0.x (SemVer!) and you can’t rely on anything. Often times, you need the latest Rust nightly compiler.

Go is … I don’t like it. And huge binaries.

I like C as a language, but it’s too fragile. I want to have a proper HashMap every now and then.

None of the above have good GUI libraries, at least not on Linux.

And then there’s Java. This is my fractal renderer that I wrote over 17 years ago:

https://movq.de/v/fcd3c4e557/vid-1784121825.mp4

It’s fast. It has a GUI with custom widgets and those weren’t even hard to make. It still works without changing a single line of code. The source code files have timestamps from 2009 and I just noticed that the JAR file I’m using in the video was compiled in 2010.

Java as a language is relatively easy to learn and to master. There are few surprises. The source code organization with packages is good. Java API docs are clear and well written.

The JVM ramp-up times have improved considerably:

https://movq.de/v/e7314e521e/vid-1784121998.mp4

This isn’t like the Dark Ages anymore. Might even be usable for some CLI tools.

The only thing where Java really sucks is anything close-ish to the kernel. Try issuing an ioctl() … I couldn’t have made my TUI framework in Java, but then again, I wouldn’t have needed to because Swing already exists and it just works.

⤋ Read More
↳ In-reply-to » Easy way to do digital detox: Use a Mastodon instance that someone else maintains. And when it’s down, there’s nothing you can do but wait. 😅

@david@daiwei.me That’s a good thing. I still use it heavily, but I also realize that it is addictive. This whole idea of getting likes and boosts is horrible. Seeing “number goes up” is inherently addictive design, if you ask me. This should never have been added to a Free Platform like Mastodon, and I’m glad that twtxt doesn’t have anything like it.

⤋ Read More
↳ In-reply-to » Yeah, lol, fuck off. Tried to reproduce that hashing issue, thus playing around with Go a little bit. And what did I find?

I also set this to local years ago:

$ go env | grep TELEM
GOTELEMETRY='local'

When this came out I was also outraged. But it doesn’t go anywhere, there are no network connections. It is effectively “off” like this.

⤋ Read More
↳ In-reply-to » I don't think I'm going to add edit and delete support in this app because I think it was a horrible mistake to add those features to a client 🤣

I will very likely add a way to delete your feed(s) from the search engine, because I do thing that’s important. But as Art 17 points out, we can’t really guaranteed deletion in everyone’s caches around the planet haha 😆

⤋ Read More
↳ In-reply-to » I don't think I'm going to add edit and delete support in this app because I think it was a horrible mistake to add those features to a client 🤣

as upset repeatedly in the past and many debates and discussions, I don’t think there’s any other viable way to do, threatening in a purely decentralized way because I think you’re just create another set of problems that are probably likely far worse

⤋ Read More

Hurray, I can now press gg instead of g to go to the top in tt. Much better! :-) Other multi-key combinations are also easily possible now.

I should probably write a real article about this at some point, but here we go. The only downside with my new key binding system is that it breaks tview’s established pattern. You’ve got an InputHandler(), that is implemented using WrapInputHandler(…). It typically then directly implements the switching logic depending on the key press. Something like this:

func (w *Widget) InputHandler() func(event *tcell.EventKey, setFocus func(p tview.Primitive)) {
    // WrapInputHandler allows for intercepting key events with SetInputCapture(…)
    // from the outside for customization. This handles the default key bindings.
    return t.WrapInputHandler(func(event *tcell.EventKey, setFocus func(p tview.Primitive)) {
        switch event.Key() {
        case tcell.KeyRune:
            if event.Modifiers() == tcell.ModNone {
                switch event.Rune() {
                case 'k':
                    w.scrollUp()
                    return // we already handled the event, stop processing

                case 'j':
                    w.scrollDown()
                    return
                }
            }
        }

        // We didn't handle the key event. Maybe the parent
        // widget knows what to do with it.
        if handler := w.parent.InputHandler(); handler != nil {
            handler(event, setFocus)
        }
    })
}

From the outside, you can intercept and either stop or continue the widget’s original key handling with a potentially rewritten key event using SetInputCapture(…):

w := NewWidget()
// customized or additional key bindings
w.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey {
    switch event.Key() {
    case tcell.KeyUp:
        // Rewrite the event, so the "cursor up" key is an alias
        // for the vim key binding "k", that is handled by the
        // wrapped input handler above. (I know, I know, this is a
        // completely unrealistic example, why would anyone use
        // cursor keys when there are vim key bindings available?!)
        return tcell.NewEventKey(tcell.KeyRune, 'k', tcell.ModNone)

    case tcell.KeyRune:
        if event.Modifiers() == tcell.ModNone {
            switch event.Rune() {
                case 'q':
                    app.Stop()
                    // we already handled the event, do not pass it
                    // to the wrapped input handler above
                    return nil

                case 'r':
                    toggleMessageReadStatus()
                    return nil
            }
        }
    }

    // we didn't handle the event, pass it to the wrapped
    // input handler above
    return event
}

Since they all expect a single key, I’ve noticed that using multiple dedicated KeyBindings of mine on these different levels kinda breaks multi-key handling with common prefixes. The outer-most KeyBinding captures the prefix, but it can’t transfer it to the inner one if not handled by the outer one. At least not without some more (potentially ugly) changes. So, I now have to work with just a single KeyBindings object for the entire widget chain (if it consists of multiple other widgets or the regular input handler and input capture are in the game). The outside needs to register all its key bind customizations or extensions at the same level that the original widget handles its default ones. Doable by exposing the widget’s KeyBindings instance, but not pretty. You always have to keep this in mind.

With the KeyBindings, it will look like that:

type Widget struct {
    parent tview.Primitive

    // make it available to children or the outside either by
    // direct field access or by providing a getter method
    KeyBindings *bind.KeyBindings
}

func NewWidget() *Widget {
    w := &Widget{KeyBindings: &bind.KeyBindings{}}
    w.KeyBindings. // default key bindings
        Bind0(bind.KeySequence('k', w.scrollUp).
        Bind0(bind.KeySequence('j', w.scrollDown)
    return w
}

func (w *Widget) InputHandler() InputHandler() func(event *tcell.EventKey, setFocus func(p tview.Primitive)) {
    return t.WrapInputHandler(func(event *tcell.EventKey, setFocus func(p tview.Primitive)) {
        // also note the missing support for focus transfer at the moment
        event = w.KeyBindings.Capture(event)
        if event == nil {
            return
        }

        if handler := w.parent.InputHandler(); handler != nil {
            handler(event, setFocus)
        }
    }
}

And then from the outside, or in a child widget:

w := NewWidget()
w.KeyBindings. // additional or customized key bindings
    Bind1(bind.KeySequence(tcell.KeyUp), func(*tcell.EventKey) *tcell.EventKey {
        return tcell.NewEventKey(tcell.KeyRune, 'k', tcell.ModNone)
    }).
    Bind0(bind.KeySequence('q'), app.Stop).
    Bind0(bind.KeySequence('r'), toggleMessageReadStatus)

When directly working with tview primitives that are not part of custom widget implementations, the following works well so far:

textView := tview.NewTextView().
    SetWordWrap(true).
    SetText("…")
    SetScrollable(true)
textView.SetInputCapture((&bind.KeyBindings{}).
    Bind0(bind.KeySequence('q'), app.Stop).
    Bind1(bind.KeySequence('g', 'g'), func(*tcell.EventKey) *tcell.EventKey {
        return tcell.NewEventKey(tcell.KeyHome, 0, tcell.ModNone)
    }).
    Capture)

I need to sleep on this some more.

Also, writing very long messages like this one is really not all that fun in tt’s editor. I should absolutely provide a way to shell out to vim.

(Took me about one and a half hours to compose, holy crap. But not only because of not using vim. Although, that might have saved me a quarter hour or so for sure. Proof-reading this message also uncovered quite a few bugs in my real documentation. So, that’s a big win!) Good night!

⤋ Read More

@balloonfu-sen@yarn.girlonthemoon.xyz Unfortunately I tried to support SFTP but ripped this out as Browsers (which the Swag framework uses under the hood as a framework to build PWA(s)) doesn’t support raw TCP connections. So FTP / SFTP is not possible without hacks like a proxy. Which I don’t really want to support. So only things that have some kind of HTTP API are possible viable publihsing backends right now. That is Github/Gitea, twtd, Yarn, etc.

⤋ Read More

@david@daiwei.me Ta, I continued my fun with studying the tcell and cbind code bases for key bindings. My plan is to eventually not only support custom key bindings in the tt configuration file, but also to enable multi-key sequences, such as gg to jump to the top of a list/tree. Or use other vim-like navigation movements like 7j or 25gg etc.

And it turns out there are only a hand full oft tcell/cbind version combinations that work together. Only if all stars align, there’s chance of success. I will probably end up pulling cbind in to simplify my life. There are situations where tcell.EventKey’s triple of key, modifiers and rune are not all that intuitive to me. Let’s see.

⤋ Read More
↳ In-reply-to » We slept in the forest. It was really great except of my mate's fucking terror dog who was barking and snarling the entire night to each and every sound. I had maybe half an hour of sleep in total. Despite that, it was pleasantly warm. Well, the night, that is. The heat was brutal during the days. Literally streams of sweat were running down on us on the way there in the evening and back in the morning.

@prologic@twtxt.net Well, 15 shows the site. On the left, I had a roll mat on a tarp. I borrowed some “NVA tarps” from the scouts for this trip. The scouts got them from the National People’s Army, the German Democratic Republic’s armed forces after Germany was reunited. They’re 1.75m x 1.75m in size and weigh 1.3kg, quite heavy, but super awesome. One tarp on the bottom, another one to cover up the clothes, shoes and sleeping bag in order to protect against the thaw. Finally, a mosquito net over all that, hung from a rope between two trees.

My mate just used a hammock with a mozzie net on the right hand side. The third tarp served as the luxurious bedside carpet. :-)

We sat on my second tarp to chill and enjoy the sunset and surroundings. It was nice to notice birds etc. die down. It took a really long time for the last light to fade away. Since we have a very high risk of forest fires, we of course couldn’t have a camp fire. But after all the exhaustion, I didn’t even miss it for one second.

Since we had dinner at home before leaving, all we brought were two lye rolls, two grain rolls, two brezels, some sausage and chocolate biscuits for breakfast. From the 2.5l of water, I ended up using 2l. It’s always good to have a little extra, despite the unnecessary weight. We had brekkie a few kilometers further on a bench in the shade. The first bench was already in direct sun.

Our camp site was maybe 30m to the side and a few meters down of a summit path hidden behind some trees and bushes. We were quite lucky, the other side of the hill got quite a bit of a breeze at night. We could hear the leaved treetops making much more noise behind us.

@movq@www.uninformativ.de Yes, these kind of dogs should really be strictly forbidden!

It’s not illegal if you own the forest or ask the owner. :-)

@david@daiwei.me Yeah, no clue. But my mate said the dog is disqualified from such adventures in the future. :-)

The temps were supposed to hit 14°C just before sunrise. Since we didn’t bring a thermometer, I can’t tell for sure. I was rather hot in my sleeping bag, so I had to pull out my arms every now and then. My mate’s sleeping bag was a little lighter and, unfortunately, the zipper jammed up. Since it didn’t close all the way, it felt quite a bit cold I was told in the morning. When we got up at 6ish (we said, we don’t care about time at all), it was probably already 16°C if not more. I brought a jumper, but a t-shirt was already nice enough to wear. The jumper just served as my pillow. The mercury raised by the minute then.

Yeah, I circled the spot with a biro to keep an eye on it. Until now, there’s absolutely nothing to see. Looks like I got lucky.

⤋ Read More

Friday, my love, we meet again. I am going to take you to lunch, and pamper you. I will led you to believe you are the only one in my life, but then, as the working day sunsets, I shall leave you at the door, like a stood up girl by her prom date.

Weekend babies, here we come! 😂

⤋ Read More

@GabesArcade@gabesarcade.com hey, thanks Gabe! One of the things I like the most about twtxt is the community size. We are relatively small. Twtxt users tend to “know” each other better than on the other, much bigger communities. I believe that’s good. Glad to have you around!

Of course, it’s simplicity is part of its strength too!

⤋ Read More
↳ In-reply-to » (#6icxocaexwil) @GabesArcade The no-JS part is one thing, but you also have to disable the (nowadays common) forced-HTTP-to-HTTPS-redirect, because those old browsers can’t do modern crypto. And make sure that your webserver serves the correct page even if no Host header is sent by the client. And don’t even think about serving UTF-8 or even just putting utf-8 in the content type. 😅 And for the JPEG thumbnails I pass a special flag to ImageMagick so that IBM Web Explorer from OS/2 won’t trip. 🤣 And always use link rel="stylesheet" for CSS, because some browsers render inlined CSS as literal text. And … probably more that I forgot by now. 😂

@movq@www.uninformativ.de see anything you like here? 🤭

⤋ Read More
↳ In-reply-to » Anyone using XMPP? I've been hearing a lot about how it is the OG messaging protocol. That G00gle Talk used to use it as a back-end, that FB messanger and w_hatsapp use some modified version of it or something; And that setting up a server (or even using a public one) would be a better alternative to the aforementioned apps, so I did. Now the question is: "Where the Fu__ are my video calls at!!? 🤣" ... The protocol supports videoconferencing and I'm yet to find a decent Desktop/Mobile client that implements it. I wish I knew enough Code-Fu to contribute/help implement some, somewhere.

@movq@www.uninformativ.de Welcome to the University Computer Centre Greifswald, where we like FLOSS and have never known fear or money!

⤋ Read More
↳ In-reply-to » Very hot above 30°C, but luckily also incredibly cloudy and a lot of wind. That's what we got today. My mate and I went on a quick stroll this evening and got a surprise killer sunset: https://lyse.isobeef.org/abendhimmel-2026-07-07/

@lyse@lyse.isobeef.org 07, right there, is my favourite. That’s not to say I don’t like the rest. I love them all! I don’t think I would ever get tired of enjoying that view, each and every day. 😍

⤋ Read More

Windows NT 4 didn’t have a Device Manager. You know, this thing right here that got introduced with Windows 95:

Image

And that’s super awkward in NT4.

You know what doesn’t have a Device Manager, either? Linux. Why? 🤔 Isn’t this one of the most useful system tools? It gives you an overview of the devices in your system and tells you which driver is used for them. Linux could really use such a tool, I think? 🤔

(There are programs like “hardinfo” and I remember ancient KDE providing such a tool, but they’re all an afterthought. Hardly integrated into the overall system.)

⤋ Read More
↳ In-reply-to » @lyse This apparently depends on the program now … Some Qt6 programs still allow that, others don’t. I can’t remember if GTK ever had that feature. 🤔 But yeah, this whole “move stuff around as you please”-mentality is mostly gone.

@movq@www.uninformativ.de It sure feels like the focus is heavily shifted to the average Joe and the power users are left standing.

⤋ Read More

Java 1.3 on Windows 95 with Proton as the editor could be another option for next Advent of Code.

Win95 runs pretty smoothly on my old box (no surprise, that box came with Win95) and I like Java, so … why not …

Not sure about the speed, though. 🥴

Image

⤋ Read More

I just read @kat@yarn.girlonthemoon.xyz’s blog post over here:

https://bubblegum.girlonthemoon.xyz/articles/learning-to-code-like-it-s-the-90s

Jesus, it must be so overwhelming for young people to get started with programming.

When I started programming, there was the built-in ROM BASIC of that PC and probably a bit of BASIC on a floppy, and that was it. Nowadays? Millions of libraries and frameworks and languages and what not – and, much worse, there’s the expectation that you need to make something fancy. When I started, printing something and understanding IF was good enough.

⤋ Read More
↳ In-reply-to » @movq https://movq.de/blog/postings/2026-07-03/0/POSTING-en.html Oh yeah, the toolbar handles. You could actually move the toolbars around and sometimes even customize them. I have no evidence, but to me it feels like a lot of programs don't allow that anymore nowadays.

@lyse@lyse.isobeef.org This apparently depends on the program now … Some Qt6 programs still allow that, others don’t. I can’t remember if GTK ever had that feature. 🤔 But yeah, this whole “move stuff around as you please”-mentality is mostly gone.

I know I keep referring to StarOffice 3.1 a lot, but it’s just such a good example for all these things. All the toolbars and panels could be rearranged:

Image

(This is running in Wine, btw.)

LibreOffice is the descendant of StarOffice and it doesn’t support anything like that anymore.

Maybe it was deemed too confusing for users? “Oh no, I mis-clicked something and now that bar is gone! How do I get it back? I don’t even know what it’s called!” 🤔

⤋ Read More
↳ In-reply-to » We’re at 39.5 °C now. Are we going to hit 40? https://movq.de/v/43544d5385/2026-06-27--14-12.webp

@movq@www.uninformativ.de Oh my! :-O We reached 38°C. It’s now down one degree.

I just got up from my two, three hours siesta. And I tell you, that was bloody amazing. Layed in bed in undies, no blanket, just some power metal in my headphones and I was sleeping like a baby. Normally, I NEED a blanket, no matter what. But this summer, it’s already the second time that I actually manage to drop off without one.

⤋ Read More
↳ In-reply-to » I complain about this a lot:

@lyse@lyse.isobeef.org I noticed that loading="lazy" might not be so great after all.

This is without lazy loading:

Image

The total page load time is around 400-500 ms. Okay.

Now this is with lazy loading:

Image

It finished much quicker, after about 250 ms. Sounds good.

But notice this gap right here?

Image

This wasn’t there before. With lazy loading, it now takes something like 80-100 ms until the browser even starts loading images. This is Chromium, but Firefox shows a similar gap.

The net result is that there is a very noticeable delay/flicker when you open a page, because it takes so long until the images have loaded. Yes, the layout doesn’t shift around, but that has nothing to do with lazy loading.

How odd. 🤔

⤋ Read More
↳ In-reply-to » @lyse Mhm, yeah, I also think I like date := time.Date(2026, time.June, 19, /**/ 17, 0, 0, 0, time.UTC) the most. 🤔 (My only gripe with this is that it isn’t obvious whether the third 0 is milli-, micro- or nanoseconds. These days it’s probably nanoseconds, but you never know.)

@movq@www.uninformativ.de Right. A Go programmer eventually knows that its nanoseconds precision. Keyword arguments like in Python are just sooo superior to unnamed positional arguments. I wish that Go had them, too.

⤋ Read More
↳ In-reply-to » @movq Yeah, that would also be fine with me. I certainly do like the "arbitrary" in your comment.

@lyse@lyse.isobeef.org Mhm, yeah, I also think I like date := time.Date(2026, time.June, 19, /**/ 17, 0, 0, 0, time.UTC) the most. 🤔 (My only gripe with this is that it isn’t obvious whether the third 0 is milli-, micro- or nanoseconds. These days it’s probably nanoseconds, but you never know.)

⤋ Read More
↳ In-reply-to » Hmmm are there really no decent Wayland (desktop) compatible image viewers that don't drag in Mesa and all it's hundreds of dependences or GCC and libgcc and it's multi-hour long build time or Rust? geez

@prologic@twtxt.net The only image viewer I like in general is this one:

https://codeberg.org/nsxiv/nsxiv

It’s for X11, though.

Allegedly, this Wayland image viewer is somewhat similar to nsxiv, maybe you’ll like that? 🤔

https://github.com/artemsen/swayimg

⤋ Read More

So I’ve been working on GoNIX the last few days… Which is derived from µLinux – At least it’s entire build process. GoNIX however has a 100% Go userland, including the init process, package and service management.

Now… As an experiment, because I was able to make much process on enhancing the build tools and package management, I decided to see if I could build a “Desktop” Gui of sorts…

I still wanted it to be fairly minimal and lightweight. So I went with wayland (of course) and labwc and yambar. So far I’m liking the result 👌 42 packages in the wayland-desktop meta port. Not too bad. Not sure if I can slim that down anymore… But trying to avoid Mesa/GL as that drags in far too much “cruft”.

⤋ Read More
↳ In-reply-to » @lyse Oh wow, we’re talking about such a detailed level. 🤔

@movq@www.uninformativ.de Yeah, that would also be fine with me. I certainly do like the “arbitrary” in your comment.

While writing the article, I also thought about something like that:

date := time.Date(2026, 6, 19,
    17, 0, 0, 0, time.UTC)

Or possibly:

date := time.Date(
    2026, 6, 19,
    17, 0, 0, 0, time.UTC,
)

But it’s four lines for a damn timestamp. I also contemplated whether a comment acting as a separator is all that’s needed:

date := time.Date(2026, 6, 19, /**/ 17, 0, 0, 0, time.UTC)

I might like that the most. Not entirely sure yet. It kinda feels like a hack, but still a little elegant. Add your comment on top and we’re golden. Maybe?

I deliberately excluded them as this only distracted from the points I wanted to make. And I also realized that this example was just not ideal at all. Perhaps I should add them nevertheless?

If I ever invented a programming language, a much more human readable timestamp representation of some sort, RFC 3339 or very close to that would be part of that language. Something along the lines of /pattern/ for regexes in certain languages.

⤋ Read More
↳ In-reply-to » In the light of current events, I will first consult my pillow and only then write an article about readable code.

@lyse@lyse.isobeef.org Oh wow, we’re talking about such a detailed level. 🤔

I agree with most of what you said.

I probably would have written it like this:

// Arbitrary reference date.
//                   Y  m   d   H  M  S  nano
date := time.Date(2026, 6, 19, 17, 0, 0, 0, time.UTC)

Would this be better or worse? 😅

⤋ Read More

@itsericwoodward@itsericwoodward.com

But it also wouldn’t surprise me to find out that people like Bezzos, Musk, and Zuckerberg are actually ghoulish aliens

Yeah, that’s easier to accept, isn’t? “Phew, they’re not human after all. They’re not absolute psychopaths with zero empathy – they’re just aliens. Humans are good!” 😅

⤋ Read More
↳ In-reply-to » I went to check on the fireflies this season. But I didn't see any. Instead lots of moths. At first, I thought it might have been still too light, but it was already dark enough for me to miss and destroy a snail shell. Bummer. Maybe it was too wet tonight. Although, it's probably just another or two weeks until my glowing friends will finally show up.

@bender@twtxt.net @movq@www.uninformativ.de Ta! I don’t know about regional differences. But at the moment, they first start slowly appearing at around 21:45 to 22:00. And then it gets more and more. You’ve got about an hour until it’s over.

People often say that they are in and over the meadows close to the edges of the forest. But at least over here, there are literally magnitudes more in the forest. So far, I’ve maybe seen thirty, fourty (30-40) fireflies outside at the meadows, but one or two thousand (1000-2000) inside. Exactly like last year.

They like a little bit openish spots in the forest. Not like a clearing, but if you can see ~10 meters from the path into the woodland, chances are that fireflies will pop up. But if it’s really thick brush, the odds are very slim. The hotspots also slowly wander around over time. So, I just keep on walking after a few minutes of stopping to enjoy the show.

⤋ Read More
↳ In-reply-to » Behold, I bring you (reincarnated) mbox.blue -- A tiny shared linux server based on / around containers (my own implemtnation).

@prologic@twtxt.net I think I said this before: This looks like a really cool thing! I just wish I had a use case for it, then I’d be all over you. 😅 But since I run so many servers of my own already …

What’s your motivation for running this, btw? 🤔

⤋ Read More

I noticed that there are quite a few UI glitches in vim-classic – and quickly found the cause: It comes with outdated Unicode tables.

I have to admit that I wasn’t aware that there’s a new Unicode release every year:

https://en.wikipedia.org/wiki/Unicode#Versions

Look at this huge number of changes. Every program has to keep track of that, often through libraries but sometimes not (like in Vim’s case).

I use Unicode extensively, but this shit is extremely expensive …

My TUI framework is having the same problem. At the moment, this is all offloaded to wcwidth, but if that library was to become unmaintained, I’d have to track Unicode myself.

Gah!

The DOS days were simpler. CP437, end of story. (Yes, I know that’s a lie.)

⤋ Read More
↳ In-reply-to » @lyse Awww, that sounds like a typical experience at school. 😅 They meant well but somehow it was still shitty …

@lyse@lyse.isobeef.org Yeah, I have a couple of teachers in my family and they all tell similar stories. 🙄

I have almost no recollection of my time at the “Gymnasium” anymore. I’m either traumatized by it or I wasn’t very interested in what happened there. 😅 But I have some vague memories of doing “computer stuff” at school. There certainly were computers and they certainly ran DOS games like Duke Nukem, that I do know. 😂 Just checked my records, and no, this wasn’t an official class. At best, it was one of those AGs. 🤔

⤋ Read More
↳ In-reply-to » @lyse Ah, you mean the categorization. Yeah, that would never work in Windows, at least not without having a centralized package manager (so there’s one authoritative source of which program belongs into which category).

@lyse@lyse.isobeef.org Awww, that sounds like a typical experience at school. 😅 They meant well but somehow it was still shitty …

I’ve never heard about that Wahlteil/Pflichtteil stuff (or forgot about it). Must be a BaWü thing. 🤔

⤋ Read More
↳ In-reply-to » Speaking of UIs, this is how Thunderbird looks now:

@movq@www.uninformativ.de Yes, yes, yes and yes.

The start screen looks exactly like a website not a desktop application.

I mean, I find Motif also fairly ugly. Granted, it’s a hell lot more discoverable than anything today. The old Windows UIs probably had the best balances. But it’s Windows, it doesn’t have a place in my heart. So, I stick with good old KDE. ;-) That’s my nostalgia kicking in.

⤋ Read More
↳ In-reply-to » @lyse In what way was KDE 3’s menu organized? KDE 1 is the only KDE version I ever used. 😅 We’re talking about this one, right?

@movq@www.uninformativ.de Yes, this screenshot. However, not the Dutch but rather the German version, no wonder it looks so crazy!!1!11

It’s been a hot minute or two since I last used KDE, so I don’t remember exactly. I just vaguely recall that I found myself thinking multiple times that the KDE application categories were better matching or there were more or something like that. Most of my classmates were on Windows and had one giant long list of all sort of stuff in there. You even had to scroll in the menu. Sure, they installed all kind of garbage, which didn’t exactly help. Where in KDE, they were actually grouped by Office, Internet, Graphics, Multimedia, Games, etc. In Windows, applications usually hid themselves in a sub folder named after the software vendor. At least in the later (?) days.

I only used Win 95, 98 and XP at home. For maths class with computer algebra system (Maple), we had a Cassiopeia with Win CE: https://en.wikipedia.org/wiki/Casio_Cassiopeia At school, there was probably also Win 2000, but I don’t know anymore for sure.

⤋ Read More

Speaking of UIs, this is how Thunderbird looks now:

https://movq.de/v/a41105eebb/

So we continue to let every program make up its own UI style (and then we complain that “the Linux desktop” looks “messy” and “inconsistent”). I guess this uses GTK, but it doesn’t look like any other GTK program. Buttons, tabs, drop-downs, whatever, it’s all different. It even has its own subwindow system (i.e., popups that you can’t move).

I didn’t say this in the blog post, but I’m convinced that programmers these days absolutely positively hate everything that looks even remotely like Windows 95 or Motif – with a passion. I see that in my coworkers as well, they really can’t stand it. It’s an emotional thing.

⤋ Read More

Eat like an Italian: Two budget-friendly recipes to hit your five veg a day
Forget dietary “magic bullets” and embrace these rustic, vegetable-forward dishes. They’re thrifty, comforting and delicious – and just happen to be healthy. ⌘ Read more

⤋ Read More

My suburb smells like Weet-Bix – and money. But there’s a downside to riverside splendour
In this often overlooked suburban pocket, the dumps are now parks, the factories are arts centres, and large riverfront homes have made way for even larger ones. ⌘ Read more

⤋ Read More

My suburb smells like Weet-Bix – and money. But there’s a downside to riverside splendour
In this often overlooked suburban pocket, the dumps are now parks, the factories are arts centres, and large riverfront homes have made way for even larger ones. ⌘ Read more

⤋ Read More
↳ In-reply-to » @lyse Is it this one? https://github.com/rivo/tview It’s almost 10 years old but hasn’t seen a 1.0.0 release yet? 🤔

@lyse@lyse.isobeef.org Interesting approach. 🤔

The master branch should never be in a broken state (apart from bugs I don’t know about). Any intermediate state during the development of a larger feature will happen in a different branch.

I mean, yeah, but … I don’t know, I like having “traditional releases” as a second safety net when I write programs. I like to let things mature for a while and then I cut a new release. So it’s, like, “we have a bunch of new features and fixes here, and to the best of my knowledge this works fine now”. But maybe I’m just paranoid. 🤔

⤋ Read More

Škoda’s New EV Will Likely Be Its Most Expensive Yet
The Škoda Peaq, which will debut this summer as the European automaker’s flagship model, seats seven and has an intriguing design. It will almost certainly come with a hefty price tag. ⌘ Read more

⤋ Read More
↳ In-reply-to » Every now and then, I think that I have carefully proof-read my message enough times and hit the "Add message" button in tt. But then, in the message tree, I spot another missed typo. My process is then to go to my twtxt.txt and fix it by hand. However, I still have to clean up tt's cache. This is rather tidious:

@lyse@lyse.isobeef.org

Now I’m curious how movwin deals with that. ;-)

Focus handling? I hardly remember, lol. 😅 Did that 6 months ago and haven’t touched it since. Let’s see.

The core main loop gets keyboard/mouse events from curses. At this level, the main loop only knows about exactly one widget, so it passes the event to that widget (whatever that is, doesn’t matter – they all inherit from the Widget base class, it could be a Window, a WindowManager, or an Edit box directly).

The outermost widget is usually a WindowManager. It implements a few hotkeys of its own, like switching to another window. If none of those hotkeys match, it passes the event to the currently focused window.

Same story here: Window implements some hotkeys (like opening the menu bar). If none of those match, then … the magic happens.

Each Window acts as a focus manager. It can descend into its child widget hierarchy and collect all child widgets in a depth-first search. They are collected into a flat list. Each Window then has an attribute _focus_position, which is an index into that list. Pressing Tab or Shift+Tab increases or decreases that index and that allows you to select the next/previous focusable widget in the current window.

Eventually, Window passes the input event to the currently focused widget.

Usually on initialization, the application can ask a Window object to focus a certain widget. The file selection dialog does that, for example, because the “natural” focus order would be to focus the Edit box at the top of the window first – but that’s not what the user wants, the Table showing the list of files should be focused.

If no widget ever feels responsible for handling a certain input event, then there’s a global unhandled_input callback that the application can provide (same as in urwid).

I think that’s it.

Hm, that’s more complicated than I remembered, but apparently it works fine, because I completely forgot about this. 😅 All I did in the last few months was make new classes that inherit from Widget, like the new Table class or Edit or HexEdit or whatever, and if they want to get input events, then they must implement the methods input_key() or input_mouse().

Does this answer your question? 😅 (I admit that I didn’t exactly understand your scenario, so I just went ahead and rambled about my implementation. 😅)

⤋ Read More

Iran War Live Updates: Mediator Says Peace Deal Could be Finalized Within 24 Hours
The prime minister of Pakistan, a key intermediary in U.S.-Iran talks, said a deal was “likely expected.” An Iranian official sought to temper expectations but said an agreement could be signed in the coming days. ⌘ Read more

⤋ Read More

Iran War Live Updates: Mediator Says Peace Deal Could be Finalized Within 24 Hours
The prime minister of Pakistan, a key intermediary in U.S.-Iran talks, said a deal was “likely expected.” An Iranian official sought to temper expectations but said an agreement could be signed in the coming days. ⌘ Read more

⤋ Read More

Iran War Live Updates: Mediator Says Peace Deal Could be Finalized Within 24 Hours
The prime minister of Pakistan, a key intermediary in U.S.-Iran talks, said a deal was “likely expected.” An Iranian official sought to temper expectations but said an agreement could be signed in the coming days. ⌘ Read more

⤋ Read More

Iran War Live Updates: Mediator Says Peace Deal Could be Finalized Within 24 Hours
The prime minister of Pakistan, a key intermediary in U.S.-Iran talks, said a deal was “likely expected.” An Iranian official sought to temper expectations but said an agreement could be signed in the coming days. ⌘ Read more

⤋ Read More

Iran War Live Updates: Mediator Says Peace Deal Could be Finalized Within 24 Hours
The prime minister of Pakistan, a key intermediary in U.S.-Iran talks, said a deal was “likely expected.” An Iranian official sought to temper expectations but said an agreement could be signed in the coming days. ⌘ Read more

⤋ Read More

Iran War Live Updates: Mediator Says Peace Deal Could be Finalized Within 24 Hours
The prime minister of Pakistan, a key intermediary in U.S.-Iran talks, said a deal was “likely expected.” An Iranian official sought to temper expectations but said an agreement could be signed in the coming days. ⌘ Read more

⤋ Read More

Iran War Live Updates: Mediator Says Peace Deal Could be Finalized Within 24 Hours
The prime minister of Pakistan, a key intermediary in U.S.-Iran talks, said a deal was “likely expected.” An Iranian official sought to temper expectations but said an agreement could be signed in the coming days. ⌘ Read more

⤋ Read More

Iran War Live Updates: Mediator Says Peace Deal Could be Finalized Within 24 Hours
The prime minister of Pakistan, a key intermediary between the U.S. and Iran, said a deal was “likely expected.” Officials on each side have also expressed optimism, but it still could be derailed. ⌘ Read more

⤋ Read More

Iran War Live Updates: Mediator Says Peace Deal Could be Finalized Within 24 Hours
The prime minister of Pakistan, a key intermediary between the U.S. and Iran, said a deal was “likely expected.” Officials on each side have also expressed optimism, but it still could be derailed. ⌘ Read more

⤋ Read More

Iran War Live Updates: Mediator Says Peace Deal Could be Finalized Within 24 Hours
The prime minister of Pakistan, a key intermediary between the U.S. and Iran, said a deal was “likely expected.” Officials on each side have also expressed optimism, but it still could be derailed. ⌘ Read more

⤋ Read More

Iran War Live Updates: Mediator Says Peace Deal Could be Finalized Within 24 Hours
The prime minister of Pakistan, a key intermediary between the U.S. and Iran, said a deal was “likely expected.” Officials on each side have also expressed optimism, but it still could be derailed. ⌘ Read more

⤋ Read More

Iran War Live Updates: Mediator Says Peace Deal Could be Finalized Within 24 Hours
The prime minister of Pakistan, a key intermediary between the U.S. and Iran, said a deal was “likely expected.” Officials on each side have also expressed optimism, but it still could be derailed. ⌘ Read more

⤋ Read More

Iran War Live Updates: Mediator Says Peace Deal Could be Finalized Within 24 Hours
The prime minister of Pakistan, a key intermediary between the U.S. and Iran, said a deal was “likely expected.” Officials on each side have also expressed optimism, but it still could be derailed. ⌘ Read more

⤋ Read More

Iran War Live Updates: Mediator Says Peace Deal Could be Finalized Within 24 Hours
The prime minister of Pakistan, a key intermediary between the U.S. and Iran, said a deal was “likely expected.” Officials on each side have also expressed optimism, but it still could be derailed. ⌘ Read more

⤋ Read More

Iran War Live Updates: Mediator Says Peace Deal Could be Finalized Within 24 Hours
The prime minister of Pakistan, a key intermediary between the U.S. and Iran, said a deal was “likely expected.” Officials on each side have also expressed optimism, but it still could be derailed. ⌘ Read more

⤋ Read More

Iran War Live Updates: Mediator Says Peace Deal Could be Finalized Within 24 Hours
The prime minister of Pakistan, a key intermediary between the U.S. and Iran, said a deal was “likely expected.” Officials on each side have also expressed optimism, but it still could be derailed. ⌘ Read more

⤋ Read More