[HN Gopher] Things I've learned building a modern TUI framework ___________________________________________________________________ Things I've learned building a modern TUI framework Author : willm Score : 326 points Date : 2022-08-03 13:24 UTC (9 hours ago) (HTM) web link (www.textualize.io) (TXT) w3m dump (www.textualize.io) | rochak wrote: | I love TUI and CLI based tools that keep me in my terminal as I | have started to dread web applications more and more with every | passing day. For obvious reasons, these tools have a better and | more consistent UX since they need to rely on keyboard a lot more | and are catered to more tech minded people. Not to mention the | fact that they help avoid getting distracted by the endless ocean | that is the internet. | MaxBarraclough wrote: | A neat FOSS project. Have to admit I was surprised to see you're | hiring and already have 2 developers on staff besides the | founder. Where does the money come from? Paid support? | | It would be good if the _What we do_ page answered this. | asicsp wrote: | From https://www.willmcgugan.com/blog/tech/post/textualize-is- | hir... | | > _At the end of last year I took a year off to work on my | Open-source projects and develop an idea that I believe will | allow the terminal to eat some of the browser's lunch. Turns | out this idea was compelling enough to attract some sweet sweet | VC cash and I am now hiring a third Python developer to join | the company._ | teddyh wrote: | The question then becomes: What do _the VCs_ think that the | money will come from? | __tyler__ wrote: | Textualize mention they want to make it so that you can | deploy the same code base as a TUI and a web app. My guess | this will be additional paid functionality that makes a | seamless hosting experience. | stjohnswarts wrote: | VCs are naturally risk takers, there is a lot of VC money | out there seeking novel projects. Maybe if textual can land | some companies like Dell/IBM/AMD/Oracle/AWS who want | snappier textual frontends for sysadmins rather than | slow/clunky web interfaces for sysadmins/app admins to do | stuff like board management controllers and textual | dashboards for app/status monitoring stuff. Lower | bandwidth/more dependable than web interfaces over | slow/spotty interconnections with something like mosh. | Seems like an option. Projects like this that add color, | etc add a 3rd dimension to a 2 dimensional text landscape | and I think that counts for a lot. | teddyh wrote: | > _Maybe if textual can land some companies like Dell | /IBM/AMD/Oracle/AWS_ | | And? What does "land" mean here, exactly? The project is | FOSS, so they won't sell the software the traditional | way. So how will they _make money_? | vulcan01 wrote: | Large companies tend to prefer support for any major | dependencies, so, companies built around an open-source | project typically sell support. Customers might also hire | them for consulting, custom implementations using the | project, etc. | | However, it's not a high-value business so it is somewhat | surprising VCs are funding this. | teddyh wrote: | Maybe the VCs are quietly planning to force the company | to make the source proprietary once they get enough | adoption by such large companies? | zasdffaa wrote: | Make me happy and point me at some of these because I | have something and can find no-one to even look at it, | and I believe it has actual cash value. | Lendal wrote: | Apparently some VCs are not expecting anything back except | karma for making needed enhancements to civilization. | kmike84 wrote: | The advice to use lru_cache is good. | | But there is an issue if lru_cache is used on methods, like in | the example given in the article: | | 1. When lru_cache is used on a method, `self` is used as a part | of cache key. That's good, because there is a single cache for | all instances, and using self as a part of the key allows not to | share data between instances (it'd be incorrect in most cases). | | 2. But: because `self` is a part of a key, a reference to `self` | is stored in the cache. | | 3. If there is a reference to Python object, it can't be | deallocated. So, an instance can't be deallocated until the cache | is deallocated (or the entry is expired) - if a lru_cache'd | method is called at least once. | | 4. Cache itself is never deallocated (well, at least until the | class is destroyed, probably at Python shutdown). So, instances | are kept in memory, unless the cache is over the size limit, and | all entries for this instance are purged. | | I think there is a similar problem in the source code as well, | e.g. | https://github.com/Textualize/textual/blob/4d94df81e44b27fff... - | a DirectoryTree instance won't be deallocated if its | render_tree_label method is called, at least until new cache | records push out all the references to this particular instance. | | It may be important or not, depending on a situation, but it's | good to be aware of this caveat. lru_cache is not a good fit for | methods unfortunately. | ttymck wrote: | Does @staticmethod run into this same issue? | kmike84 wrote: | No. | Philip-J-Fry wrote: | This is great, it feels like it's one of the better frameworks | that is actually trying to improve the way we write terminal UIs. | | Seems like Textualize is coming at it from the right angle, | abstract as much as you can away such that a widget is something | self contained and your UIs are _actually_ composable a la web | frameworks like React or Vue. | | Declarative UIs are the future. Now... When will someone make a | Go port... | lotw_dot_site wrote: | One of my proudest moments during the development of "Linux on | the Web" had to be the creation of a Terminal application (try it | at https://lotw.site/shell) that can render its output with near- | native efficiency. My initial attempt was based on placing | character images, one-by-one, onto a canvas element, but it was | horribly sluggish. Then I started playing around with a "Virtual | Dom" (React-like) approach, wherein I convert the underlying data | structure into an html string, and then set the innerHTML | property of a div element, for every time the screen has to be | redrawn. (Source code: | https://github.com/linuxontheweb/LOTW/blob/main/root/code/ap..., | the relevant code is the "render" function starting on line 569, | and the innerHTML is set on line 940). | | I don't know how many years its been that I started working on | the Terminal application, but it was only within the past week or | so that I "bit the bullet" and figured out how to do finger | pad/mouse wheel scrolling of the output buffer (See the | 'main.onwheel' function in the source code for that little | tidbit!). Since I required fine-grained control over the | rendering process, I could not rely on the "naive" way of doing | scrolling on the web (which is to simply let the browser take | care of the entire process). | munificent wrote: | _> My initial attempt was based on placing character images, | one-by-one, onto a canvas element, but it was horribly | sluggish._ | | I've done web-based terminal-style renders in a number of | different ways for my roguelike [1]. I've done both DOM and | canvas renderers. I found that the fastest approach to be: | | 1. Render each glyph to a canvas. | | 2. Only re-render glyphs that actually changed. | | Doing that was _much_ faster than using the DOM. I imagine I | could go even faster using WebGL but at this point, I | considered the performance good enough. | | For anyone interested, my terminal library is written in Dart | and is open source: | | https://github.com/munificent/malison | | [1]: http://munificent.github.io/hauberk/ | jonathan_s wrote: | Same experience here. Canvas rendering is much faster for | terminal apps if done well. I think also VS code uses a | canvas for its terminal because its superior performance. | markdog12 wrote: | It's been 357 years, and Dart still can't go full screen | without a hack like this: https://github.com/munificent/haube | rk/blob/master/web/main.d... | | https://github.com/dart-lang/sdk/issues/11506 (Jun 25, 2013) | munificent wrote: | That code is seven years old: https://github.com/munificent | /hauberk/commit/2ba2f260baa7004... | | I should fix it to use: | https://api.dart.dev/stable/2.17.6/dart- | html/Element/request... | | I just never noticed because it wasn't causing any | problems. | lotw_dot_site wrote: | If I would have continued my original approach, I probably | would have been able to get something like that working | pretty well, but since it is pretty hard to beat Virtual DOM | types of approaches, I had no need to try anything else when | rendering full screens of text could keep up with key repeat | rate. | | But of course, the idea of developing a terminal using a | standard DOM-centric approach is usually not going to turn | out very well... though Google is an exception here with the | hterm js library that underlies the terminal output for | Chromebooks: https://chromium.googlesource.com/apps/libapps/+ | /master/hter.... Most Chromebook users will never have the | opportunity to put this to use, though people like me who put | their Chromebooks in developer mode the first chance they get | use it _all the time_. | navanchauhan wrote: | Didn't look through GitHub to see if someone else has already | mentioned the issue but it just shows a blank black screen when | opened in Safari | | > Unhandled Promise Rejection: ReferenceError: Can't find | variable: webkitResolveLocalFileSystemURL | lotw_dot_site wrote: | Yeah, I don't personally mess with anything but Chrome, and I | consider supporting browsers that are not Chromium-based to | be a fork of the entire project. | | Per the Disclaimer in the Github README | (https://github.com/linuxontheweb/LOTW/): | | --------------- | | LOTW is developed in the crouton environment, which involves | ChromeOS in developer mode. All development and testing is | currently done on a Chromebook, using an up-to-date Chrome | browser. | | The system should basically work in any modern browser and | host OS, but there are likely many tiny glitches that degrade | the user experience in other browsers and/or operating | systems. | | --------------- | | The crucial fact of LOTW is that it is based around the | concept of a full-featured, sandboxed file system in your | browser. Only Chromium-based browsers natively support that | kind of thing via 'webkitRequestFileSystem'. | | That being said, there is a shim/polyfill that is supposed to | load and take care of that | (https://github.com/linuxontheweb/LOTW/blob/main/www/js/fs- | sh..., created by Eric Bidelman when he was at Google). Last | I knew, Firefox seemed to work with it. | ketralnis wrote: | > I don't personally mess with anything but Chrome, and I | consider supporting browsers that are not Chromium-based to | be a fork of the entire project | | I see the ie6 world is coming back | lotw_dot_site wrote: | Funny, that, seeing how M$ themselves are perhaps the | biggest contributors to the current browser codebase | monoculture issue. | | Anytime a software project develops enough complexity, | there is no shame in targeting a specific platform. Given | enough eyes on a thing, though, those kinds of | "supported" issues always take care of themselves. | | But I'm just a lone developer trying to do something | never before done. I'm still trying to prove a concept... | dahfizz wrote: | Gotta love how cross platform the web is... | Illniyar wrote: | Everyone seems to be very excited about this framework, and while | it looks very impressive, I don't inderstand the impetus for it. | | Why do I need the terminal to become an interactive visual app? | Why not use the tools that are designed for visual interactive | applications- like GUIs ? | brabel wrote: | I am on the same boat: just can't see why someone would want to | turn the terminal into what is basically a GUI with just poorer | graphis?! | | Am I completely missing something? Should I start thinking of | replacing my desktop environment with a terminal emulator that | does everything, including displaying images, videos, windows | etc to gain some advantage I am unaware of? | cwalv wrote: | It's a least common denominator thing: there a places where | you can easily run a terminal app but not a browser/electron, | which are probably the next level up in the | portability/fidelity tradeoff. | BiteCode_dev wrote: | - you don't need compiled dependencies | | - you may work mostly in the terminal and want to fire a | quick tool: dev is a lot of that so it's great for this use | case | | - it's cross platform | | - it works with no X so it works with ssh | | - it doesn't eat a lot of resources | | - it's fast to launch | | - you usually already have a cli entry point, so this is a | natural next step. The quick script becomes really nice | | - it's very constrained, so devs have to focus on the most | important things which makes the UI usually better than usual | | - it's a common denominator so you can generate web ui and | native ui form that | | - TUI have naturally good keyboard workflow for free | | - it's just really cool | mikkelam wrote: | I honestly think this is just developers being developers. Why? | Because it's cool. It's not more than that | gjulianm wrote: | Maybe you don't have access to a graphics server, or just want | to add a small interface to a certain part of a bigger | application/script that works in the terminal. For example, apt | will show you TUIs sometimes when it asks more complex | configuration questions. | trebbble wrote: | It's really handy if your "window manager" is actually _in_ | your terminal (say, you use tmux). Otherwise you 've got two | layers of "window manager" to deal with--your terminal | multiplexer, and your actual window manager. | | Why might one use something like tmux instead of relying on | Rectangle or a tilling window manager or what have you? | | 1) The terminal is far easier to gain access to cross-platform | than any GUI window manager, so if you can keep most of your | workflow in the terminal, you can work just about anywhere. You | get it out-of-the-box basically everywhere but Windows | (assuming we mean a Unixy terminal, here, not cmd or | powershell) but it's very easy to gain access to a unixy | terminal there, too, these days. | | 2) Maybe you are constrained to the terminal for some reason, | as in the case of a remote server that doesn't have X | installed. | mixmastamyk wrote: | Works from a headless server. | | Cool, but I'm surprised at VC money to be honest. | rakoo wrote: | Because making GUIs is either native but with "complicated" | frameworks that aren't simply cross-platform, or web-ish and | fat with Electron. | | Every OS has a terminal, so every OS can render those apps. | Maybe we'll finally get a Electron-less slack one day. | oblio wrote: | Now instead of supporting 3 browsers (Chrome, Firefox, Safari) | you now have to support 5 different terminals. | | Though it's probably easier to fully support a different | terminal. | | Interesting trade offs. | MaxBarraclough wrote: | Every multi-platform UI toolkit must put in the work to support | multiple platforms, by definition. | jacobtomlinson wrote: | I'm so excited about textual! | | I started working on a TUI application over Christmas that used | it but put it on the back burner until the css branch gets | merged. | fadjfadjiiitlz wrote: | * Fortunately the Unicode database contains a mapping of which | characters are single width and which are double. Rich (and | Textual) will look up this database for every character it | prints. Its not a cheap operation, but with a bit of engineering | effort and caching (see lru_cache) it is fast enough. * | | A bitmap sounds suitably compact and fast. There are likely to be | large intervals of double-only or single-only items so it may be | even smaller. | | Regarding your hiring it would be nice to actually get a reply, | and say why if you don't want a person. | public_defender wrote: | Has anything been built with textual yet? People here seem to be | discussing it mostly at the conceptual level. | andrewshadura wrote: | I'm considering porting git-crecord to it, but the lack of | documentation isn't particularly motivating :) | willm wrote: | We have a gallery of apps in | https://www.textualize.io/textual/gallery | | I'm surprised how much has been done with it. The version in | master has been stuck in limbo while we've been working on the | CSS branch. | nickdothutton wrote: | It's this kind of project that makes me want to run a | shellhost/service/"club". So much interesting stuff happening in | the terminal these days for high-productivity individuals who are | sick of the way the web has gone. | mark_l_watson wrote: | Really good that he got funding for his open source project. I | tried Textualize earlier this year and it was really nice: easy | to use and the UIs look great. | | Apologies in advance for drifting off topic: as (primarily) a | Common Lisp developer, it makes me sad to see great Python | projects that will never be replicated in my world. Perhaps there | are 10,000 times as many Python developers as CL, so it is | understandable. | openfuture wrote: | There's a nice TUI lib for cl that I am using for tala (my take | on this "TUIs will eat the web" thing... datalisp.is). | mark_l_watson wrote: | thank you!! | | EDIT: do you mean cl-tui? | tambourine_man wrote: | Every time I see that scrolling demo my jaw drops. It never gets | old. | | I've been using terminals for too long and the expectation of | what should be possible is engrained deep. | | I want tmux to scroll and have hover states like that. | [deleted] | sebastianconcpt wrote: | OMG you using CSS for stying the TUI??! I love this! | | Please tell me you can have window widgets | | Like a modern Turbo Vision [1] where you can drag/drop them even | one on top of the other? | | [1] http://tvision.sourceforge.net/#wtv | willm wrote: | Yup, it's a subset of CSS of course. But you will be right at | home if you know CSS. | | We support multiple layers, but we are explicitly not | advocating windows that can be dragged around. It wouldn't be | hard to build, but I feel TUIs should avoid the requirement to | shuffle windows around like a desktop app. | mixmastamyk wrote: | Working notebook tabs should be fine in the short term. Don't | think those were mainstream in the TV days, which was more | the MDI era. | | Also, please make them look like actual tabs, which TUI and | Web designers avoid like the plague for some reason. :-P | chrismorgan wrote: | I'm a little disappointed to see no mention of the problems of | colour. Perhaps Textual is just too firmly in the camp of | overriding _everything_ , so that these problems don't appear | (and it just feels extremely heavily out of place instead). As a | user of a light, high-contrast terminal, I will state that _most_ | TUIs that I use are badly executed, featuring awful ugliness, | complete inaccessibility, or both, due to incorrect assumptions | about colour. | | Terminals just have the wrong primitives for colour. It's | irredeemably broken, needing complete replacement with an | altogether different approach to colours, and I don't even know | quite what that approach would be, quite apart from the | improbability of convincing people to implement it. | | There are default foreground and background colours, and they | could be black and white, white and black, or just about | anything, really. (People speak of 16- and 256-colour terminals, | but they're actually 18- and 258-colour.) | | You want to make your text stronger? Have fun. You'll look at | your terminal that does #ccc-on-#000 or similar, and try bold. | One some terminals, this will also change the colour to #fff, but | on others it won't. You kind of want to, because bold-but-the- | same-colour isn't drawing the attention you want, so you figure | you'll set the colour to bright white. Well, now your text is | _completely invisible_ for may light terminal users. So you | begrudgingly roll that back and decide to try yellow. Eh, it's a | bit dull, but not _too_ bad. You'll still get complaints from | light terminal users, though, because although it does have the | advantage of distinctiveness, it's _much_ lower contrast. Don't | even think of bright yellow, because that's back to being almost | invisible in most light terminals. | | Light terminal themes have to decide whether colours 8-15 mean | "bright" (increase lightness and perhaps saturation) or "higher | contrast" (where you _decrease_ lightness). Having played the | game, I can report that both choices will break some things, but | that "bright" is _probably_ the more reasonable of the two. But | know that you can't rely on any particular direction in the | relationship between colours 0-7 and 8-15. | | You think you'll get around all of this by setting background | colours? Please don't, this just guarantees that your app will | feel _completely_ out of place, and probably be unpleasant to | use. | | You're fed up with light terminal considerations? Well then, | perhaps you'd like some blue in your dark terminal. Pity that | there are still widely-used terminals out there where blue so | dark that it's almost invisible and _extremely_ hard to read. And | even bright blue is commonly mildly painful to read. So blue's | out for any length of text. | | My advice ends up: by default, you should not set _any_ | background colours, and for foregrounds you can use the default | colour and colours 1 (red), 2 (green), 5 (purple) and 6 (teal), | and I will graciously permit you to use colours 3 (yellow) and 4 | (blue) for no more than one word at a time (e.g. "warning:" in | yellow). Seriously. Until the user opts into anything else, treat | the entire thing as a five-and-a-bit-colour terminal, because | you'll cause misery if you go any further. _Never_ use colours 0, | 7, 8 or 15 by default without determining what they and the | default colours are, because they may be high contrast or _zero_ | contrast. You can also use bold, which _may_ give brighter | colours, whatever that means, but shouldn't use colours 7-15 | directly. | | In many terminals it is possible to determine what the default | background and foreground colours and other colours are, and if | you have a _really_ good reason why you want to use a bunch more | colours you can try reading them and at least doing something | simple like switching between a light and dark theme, but I | recommend against that, because setting backgrounds is still just | generally... _non-native_ is probably a decent way of putting it. | Stay colour-neutral by default, fit in rather than standing out. | | This is hardly the only place terminals are using a fundamentally | bad model. The article does talk about the problems of column | widths, seen especially in emoji. We seriously need to burn the | current scheme of terminals down and build something _sound_ in | its place. Of course, this is extraordinarily unlikely to happen, | and only stands any chance whatsoever if compatibility can be | maintained in some way. | eesmith wrote: | Textual builds on Rich. Rich says this, at | https://rich.readthedocs.io/en/latest/console.html#color-sys... | : | | > There are several "standards" for writing color to the | terminal which are not all universally supported. Rich will | auto-detect the appropriate color system, or you can set it | manually by supplying a value for color_system to the Console | constructor. | | with options None, "auto", "standard", "256", "truecolor", and | "windows". | willm wrote: | These issues are precisely why Textual uses Truecolor by | default. It is supported on the vast majority of terminals. | Colors are reduced to 256 (actually 240 because we avoid the | ANSI colors) on terminals without truecolor support. | | 16.7 million colors gives you a lot more control over emphasis, | and de-emphasis. You can fade foreground / background, you can | draw subtle borders, and you can boost saturation. Many of the | techniques that web-developers have enjoyed for years. | | It's true we don't make use of the user's theme, but you've | laid bare the problems with ANSI themes. Respecting the user's | color theme isn't going to guarantee readability (probably the | opposite). | simonw wrote: | This is all great, but I particularly liked the tip here on using | Python Fraction objects for screen positioning calculations where | floating point errors could result in a whole extra character | causing display bugs. | drewzero1 wrote: | I think I missed the point of that exercise, so I appreciate | your brief summary. Thanks! | ketralnis wrote: | I miss vbdos. This used to be so easy. | skavi wrote: | Why don't more languages offer a zero allocation way to view a | HashMap K V as a HashSet K. | lilyball wrote: | A key weakness of TUIs is the complete lack of accessibility. | Everything is characters arranged for the eye to see, there's | nothing at all for screen readers to use to extract semantic | meaning. | trebbble wrote: | I'm having trouble imagining how to solve this in the terminal | itself--there a way to pass information to a screen-reader via | some kind of side channel? | cbm-vic-20 wrote: | Most of these modern TUIs don't work on real "glass" terminals. | Sure, nobody uses them anymore. I asked one of the Charm | developer relations people if their stuff worked on old-school | terminals like the VT-420, but they'd never even heard of that, | didn't know what it was. Of course, the VT-420 came out before | they were born, but still... | azinman2 wrote: | Do you use a VT-420? | dragontamer wrote: | > The first trick is "overwrite, don't clear". If you clear the | "screen" and then add new content, you risk seeing a blank or | partially blank frame for a brief moment. It's far better to | overwrite the content in the terminal entirely so that there is | no intermediate blank frame. | | > The second trick [...] | | > The third trick [...] | | This is pretty hilarious to consider when coming from Win32API. | | Its traditional to clears the window before showing anything on | Win32. Clearing the window happens so fast that you shouldn't see | a flicker, even as the mouse moves over your window (each pixel | your mouse cursor moves, Win32API will clear the window to its | background, redraw the window (erasing the old mouse pointer), | and draw the mouse pointer in the new location. | | This "TUI needs to be overwritten, not cleared" idea seems quaint | and slow. Win32API was drawRect(background color) for decades on | ancient 386 machines and fast enough to deliver a good | experience. Why is a 80 x 24 terminal window so much slower? | | > In Textual the layout process creates a "render map". Basically | a mapping of the Widget on to it's location on the screen. In an | earlier version, Textual would do a wasteful refresh of the | entire screen if even a single widget changed position. I wanted | to avoid that by comparing the before and after render map. | | Win32API creates and maintains the "invalidRect", the rectangle | that needs to be re-rendered from scratch (ie: draw-calls called | upon the hierarchy of "windows" from the background to | foreground, in order , to make the overall window look | unchanged). | | Not only from mouse-cursor movements, but also as other windows | "move" ontop of your window, or Clippy's speech bubble disappears | (if you remember that little UI from the 90s version of Microsoft | Word). | | And again, this needed to be done every time the mouse moved one | pixel, to erase the old mouse cursor (aka: redraw the entire | window from scratch "over" the old mouse cursor, making it look | like you've erased it) and redraw the mouse cursor on top of the | fresh coat of paint. It was an incredibly common operation even | in 20MHz 80386 land from the early `90s. | | There's just no way a modern terminal is that slow, unless | there's a billion layers of vsync / refreshes going on. There's | definitely something wrong going on IMO here. | | > Unicode art is good | | This is true. Heck, ASCII art / symbols are often good enough to | do many, many things. | | There's something wrong with the terminal model at the | fundamental level if you're a couple of magnitudes slower than | the 1980s. I can't say I'm an expert on TUI (or guis for that | matter), but... this whole blog post is kind of a horror story | IMO. | willm wrote: | Win32API was designed to render a GUI from day 1. The terminal | protocol pre-dates Windows and wasn't designed with modern | hardware in mind. It's not that it is slow per se. | dragontamer wrote: | A 1920 byte (80x24x1-byte each) character window shouldn't be | having performance problems on modern systems (ie: seeing | blank-characters or whatever) when a 1080 x 1920 x 4-byte == | 8MB desktop completes any execution faster than the eye can | see on 30 year old hardware (blank, redraw, scale, etc. etc.) | | Something, somewhere, is flushing the screen and waiting for | V-Sync, or something like that. You can write a 2D Canvas or | even 3D world (involving the reupload of entire geometries | each frame) that executes faster in Javascript compared to | this 80x24x1 byte TUI window. | willm wrote: | It's not a "performance" issue, it's a protocol issue. One | which is largely solved with the synchronisation protocol. | Workarounds are needed for older emulators. | badsectoracula wrote: | > Its traditional to clears the window before showing anything | on Win32. Clearing the window happens so fast that you | shouldn't see a flicker | | That is not due to speed but due to Windows API being smart | with clipping regions/rectangles to only allow pixel updates in | damaged regions (e.g. uncovered parts of a window as you move | it). Note that nowadays this only happens inside windows as | toplevel windows are composed via DWM in an offscreen buffer. | Windows also tries to doublebuffer window drawing updates to | avoid flickering. However in Win7 (with DWM -aka Aero mode- | disabled) and earlier you'd be able to see flickering by, e.g. | resizing windows with complex UIs. | | Also the "tradition" here isn't to clear the window but to | invalidate the regions that were damaged so that the next | update (which does clear the window) only affects the damaged | regions instead of the entire window. This was most common | during the 90s and early 2000s though, at some point computers | and memory were fast and big enough to do double buffering | during paint events (which in some cases you still need to do | when working with GDI) to avoid visible flickering - and | nowadays most common flickering issues are solved by Windows | themselves doing it via composition. | | > even as the mouse moves over your window (each pixel your | mouse cursor moves, Win32API will clear the window to its | background, redraw the window (erasing the old mouse pointer), | and draw the mouse pointer in the new location. | | This is what Windows did until Windows 3.1 (and you could see | the cursor flickering when, e.g. a control drew itself while | the cursor was over it) but with Windows 95 the system composed | the mouse cursor to avoid that flickering. However nowadays | (and for a long time now actually) the mouse cursor is drawn by | the GPU as a separate hardware plane on top of the screen | contents. All Windows do in that case is to send the cursor | image to the GPU and set the registers that specify the plane | (cursor) position whenever the mouse moves - no drawing takes | place. | dragontamer wrote: | > All Windows do in that case is to send the cursor image to | the GPU and set the registers that specify the plane (cursor) | position whenever the mouse moves - no drawing takes place. | | On the contrary. The modern GPU has so many buffers that its | constantly recalculating every pixel with custom code pixel | shaders (transparency and everything) every frame, maybe 60 | FPS or faster. | | Yeah, the CPU doesn't do any of that bit-blit stuff anymore. | But the GPU does that constantly every frame, over-and-over | again to compose modern windows. VRAM is 500GBps for a reason | on modern GPUs. | | In either case, "blanking" the screen and redrawing it is a | fundamentally fast operation 30 years ago, let alone today. | Today's computers are so much faster that there are layers of | custom-programmable parts running on 2 different processors | (CPU passing data to GPU over PCIe) every frame. | | 4GB+ VRAM buffers on the GPU allows the GPU to save off some | work of course, but there's an incredible amount of | calculations that occur on every pixel of every frame 60 | times a second today. | | -------- | | In any case, a pure-text, maybe ASCII (or Unicode) window | shouldn't be having these issues. | wolpoli wrote: | I feel like these TUI projects are popping up as a rejection to | the modern mobile first GUI. They are keyboard driven, have no | pictures, have clear borders between sections of the app, and are | truly focus on the content. | badsectoracula wrote: | The linked video looks like it follows mobile/web styling | though, it feels like if you could run a modern mobile-first | web site through elinks. Sure there aren't pictures (which is | really the least of modern GUI issues) but everything looks | "flat" with big sizes (e.g. scrollbars) and aside from | background color there isn't any other distinction between | elements. Compare this with, e.g., the Debian textmode | installer (which i guess is based on the Newt TUI library) or | the console version of Yast in openSUSE (which is based on | libyui, itself using ncurses for the console backend). In those | the elements are very clear (though Newt's buttons are a bit | too big IMO), scrollbars are thin (perhaps too think for | libyui) and everything has a clear border. | | Also no scrolling areas inside scrolling areas, which is always | annoying. | | [0] | https://news.softpedia.com/images/reviews/large/debianinstal... | | [1] https://documentation.suse.com/sles/15-GA/html/SLES- | all/imag... | nisegami wrote: | Textual seems to be the right fit for a project I just started, | but I have some concerns about its maturity and longevity. I feel | better about both after reading the post (and seeing the call for | applicants at the end despite the economy). Maybe I should just | jump in. | idomi wrote: | There are so much stuff you could do with it right? | forrestthewoods wrote: | I'm sad that Python is so slow it needs an LRU cache for trivial | math operations like computing the overlap between a pair of 2D | rects. | jorgenbuilder wrote: | I have to say that my immediate reaction is "why the *#%# would | one want to render a gui in a terminal" | mixmastamyk wrote: | Uses 1/100 the resources of a modern GUI, maybe 1/1000 of an | electron app. Works over ssh. | mixmastamyk wrote: | I like this, seems to be the answer to the promise of Urwid. | Unfortunately the main developer of which left for a long time | once it hit 1.0. It was enough to build a widget toolkit, but | didn't get proper widgets implemented for long enough that I lost | track. | | I wanted to build an CUA terminal editor with one of these for | decades but micro is recently good enough. So am cheering on in | spirit. | baobob wrote: | Does Textualize have a good example application? I was impressed | by the demos (moreso that the company is somehow funded!), but I | couldn't find any actual real world application using it yet. | | Also reliance on the mouse in the demos made me feel a bit | queasy. Anything involving overriding the default mouse semantics | in a terminal window can go straight to hell | willm wrote: | We have a [gallery](https://www.textualize.io/textual/gallery) | of Textual apps, although largely using the older version on | Textual/ | shrubble wrote: | For full-on terminal nuttiness, see the demo video (and it is | like a demoscene video) at https://notcurses.com . Someday I will | figure out how to use that library... | robocat wrote: | Semi-pornographic soundtrack to the demo makes it feel rather | non-professional to me ("penitrate my face" is not what I want | to hear at work). | shrubble wrote: | Apologies, I watched the video but didn't catch that. | kevin_thibedeau wrote: | > Fortunately the Unicode database contains a mapping of which | characters are single width and which are double. | | This doesn't work for all emoji. Some are categorized as | ambiguous width and their rendered width is system dependent. | dahfizz wrote: | This is really cool! I was impressed by the demo. I would be sad | to see this replace a more "traditional" cli/tui, but for highly | complex command line applications like qemu this is really | awesome! | BiteCode_dev wrote: | I really like this trend of "making the terminal great again". | Between rich/textual in python and lipgloss/bubble tea for | golang, this turns cmd from "the default ugly stuff that is easy | to produce" into "something fun and pretty". | | Also note that those projects have the (not anymore) secret goal | to also produce a web app from the same code base automatically. | | I imagine native will follow, or wasm, or something. | Nevertheless, having the terminal as the smallest denominator for | UI makes a lot of sense for small utilities. You won't build the | next Figma with it but a lot of scripts could benefit from that. | mastry wrote: | Agreed. I cut my programming teeth on the Dr. Dobbs/Al Stevens | "D-flat" series which was a text-based windowing system in C. | Some of the most fun I've ever had programming. The hardest | part was waiting for the next issue to be published! | password4321 wrote: | I've tried to find the most recent version of that library, | even emailing the author, but he's long since moved on and I | could only find bits and pieces. | | Maybe https://archive.org/details/dflat is best now? | mr_tristan wrote: | The general workflow I'm finding useful is to generate a ton of | simple logs, ingest all those logs into a SQLite database (that | acts like a "data lake"), and then use the customized REPL to | generate some charts (typically .png files), CSV, or ascii | reports. | | I could see using a REPL to generate a TUI, e.g., "run a query | and generate your own `top`". This seems like it could be a lot | easier than trying to generate a PDF, interactive Excel, or | complex HTML report (which usually means a bunch of | javaScript). | | There's something about text interfaces that just fundamentally | "flows" from most programming environments. | zokier wrote: | I feel the opposite, these kinds of projects imho are just | moving terminals away from their key benefits, being simple, | predictable, brutally functional with no gratuitous animations | or flourishes, allowing no-hassle adaptation to any colortheme | and font. | | Indeed, if all the features of modern graphical/web | applications are dragged into terminals, then what is the point | of using terminal anymore instead of native graphics/web? | | Furthermore the CLI proponent in me is saddened seeing this | being largely another step away from CLI tools, although | strictly speaking its true that the technology doesn't really | define the interaction model. | gjulianm wrote: | > Indeed, if all the features of modern graphical/web | applications are dragged into terminals, then what is the | point of using terminal anymore instead of native | graphics/web? | | It's not "all the features", but just being able to build a | basic interface without too much trouble is a blessing. | Several use cases: | | - The most important: you don't have access to native | graphics/web. A lot of people still need to work with remote | servers where installing X is not viable and you can't access | web ports. | | - Simplicity. For simple interfaces, it's far easier to just | use the terminal with an extra Python dependency, than it is | to create a regular UI that will require a graphical server, | graphics libraries and such. A web interface would be even | harder to do. | | - Easy adding interfaces to existing scripts. In fact I used | textualize precisely for this, a script that launched some | long running tasks, and I wanted to check the progress and be | able to stop/throttle them. Launching a simple interface was | easy enough, the rest of the script is still a regular Python | script, but for that situation it just pops up a TUI. | | Also, it's not like TUI apps are new. A lot of terminal | applications will launch a TUI sometimes because it's just | easier. See for example some configuration dialogs for APT. | tcoff91 wrote: | Another great thing is that they are keyboard driven. | Keyboard driven computing is far more powerful than using a | mouse for many things. | zokier wrote: | TUI apps are not inherently more keyboard driven than GUI | apps. Indeed, if you look at the demo video linked in the | article, majority of the interactions are done with | mouse. | willm wrote: | Textual supports both keyboard and mouse control. But we | are aiming for a keyboard-first interface, which I feel | is a better fit for terminals. | zasdffaa wrote: | Powerful? you mean it can do more than is actually | possible to do with a mouse? | agentwiggles wrote: | Power is the amount of work done over a period of time, | so even if you can do the same exact set of things with a | mouse and keyboard, if the keyboard is faster at doing | them, it's more powerful. | | You can do all your text entry by clicking keys on an on- | screen keyboard if you like, but saying that a physical | keyboard is a more "powerful" way to enter text seems | reasonable to me. | | (sorry in advance, I know this is needlessly "well | ackchually" lol) | zasdffaa wrote: | > but saying that a physical keyboard is a more | "powerful" way to enter text seems reasonable to me | | No. It's _faster_ and that 's all. So call it by that | word which is very precise. | | If you say 'power' = 'speed' then you've destroyed the | meaning of one of those words, just for the modern habit | of co-opting a fancier word for a simpler one. I'd prefer | people didn't do that, and differentiated 'speed' from a | thing you call power which indicates "I can't do that at | all, at any speed". | | If you don't like bullshit marketing and PR, don't follow | it. | Sparkle-san wrote: | If we go by the physics definition power is work over | time, so the same work over a shorter time is by | definition more powerful. I don't think applying that | term to software is inherently wrong. | [deleted] | clucas wrote: | Interesting, so do you avoid describing one programming | language as being "more powerful" than another? They're | all Turing complete, after all... it's just a question of | how fast you can develop in one, right? | zasdffaa wrote: | Good question, 'power' I reserve for turing completeness | (some aren't, such as SQL before recursive CTEs were | added, and... well, here's a list | https://iq.opengenus.org/non-turing-complete-programming- | lan...) | | For "how much crap do I have to write to get it to do | something", I call that expressivity. Scala is more | expressive than fractran (I guess...). | robertlagrant wrote: | What's the case for power equals Turing completeness over | power equals speed of development? | clucas wrote: | Sounds like you are consistent with your usage of terms, | and I understand the logic and the motivation. | | I would just caution that it's fairly idiosyncratic - | plenty of people out there don't use the word "power" the | way you do. For example, here is how Paul Graham talks | about the "power" of programming languages: | http://www.paulgraham.com/avg.html | | Just saying, as consistent as your definitions are | internally, being too rigid about it may hinder your | ability to communicate with others in the field. Good | luck buddy <3 | zasdffaa wrote: | Thoughtful reply and it is much appreciated dude, take | care! | [deleted] | layer8 wrote: | One benefit is that you can operate "blindly", without | needing the hand-eye-coordination feedback loop. This | tends to make frequent operations more automatic and | decrease cognitive overhead. | | Another benefit is that keyboard input is higher-bandwith | than mouse operations. Imagine a mouse-only interface for | everything you can do on the Linux command line, or all | the operations you can do in Vim or Emacs (beyond actual | text input). | | It's more powerful in the sense of "power user". | mark_l_watson wrote: | Well said! I do a lot of my work over SSH or Mosh with tmux | to remote servers. Projects like Textualize fulfill a real | need here. Another cool hack: using a terminal backend for | matplotlib to get inline plots while working via SSH/Mosh. | jonpalmisc wrote: | I agree. Seeing the next generation of terminal apps that | often seem to use "pretty" and "fancy" output formatting | (read: "non-parseable" and "overly-decorated") makes me sad. | Plain, simple, human-readable, and machine-parseable output | can't be beat in my mind. | capitol_ wrote: | More and more terminal apps come with a --json parameter, | so that their output can be easily machine parseable. | | Cramming output intended for humans, and output intended | for data transfer between processes into the same format | makes the lives of both groups of recipients worse. | dymk wrote: | Human-readable and machine-readable: not the same thing in | the general case. | | Hence -porcelain and friends. | mrighele wrote: | Not all console programs are meant to be batch tools whose | output needs to be piped and parsed. | | Sometimes you need an interactive tool and you may want to | run then in a console. | | Emacs is an example | bigyikes wrote: | I think there's room for two categories of terminal apps. | "Library" apps, and "User" apps. | | Library apps are intended to be consumed by other terminal | apps, or by advanced users. User apps are strictly intended | for humans. | | Take ffmpeg as an example. This is an excellent "library" | app, so much that there are many actual libraries that are | thin wrappers around it. It's incredibly versatile. | | Do I want to interact with ffmpeg, though? For one-off | tasks, no, I'll just fire up VLC or some other tool instead | of reading the ffmpeg man pages. | | Friendly, stylized, non-parseable, "user" terminal apps are | a comfortable middle ground between hard-core "library" | apps and full-on GUI apps. | diarrhea wrote: | Git follows this model as well, calling it porcelain and | plumbing (the internals). Arguably, there's a third layer | in actual GUIs wrapping the porcelain (and sometimes | plumbing). | Beltalowda wrote: | ffmpeg specifically is a bit of an outlier; together with | some other tools like qemu. | | For the rest of things, you can go a long way by just | aligning things nicely, indentation, wrapping/indenting | properly according to the terminal width, and maybe | adding a bit of bold text which is both easily parsed by | machines _and_ human readable. | | I generally think these are often considerably more user- | friendly than outputting 6 different colours - half of | which don't work well on many background colours so it's | unreadable - assuming the terminal is 290 characters wide | - many tools these days seem to think you've got | infinitely wide screens - and all the other things these | "modern" things do. | | Something like "df" is a simple but classic example; GNU | df at least aligns nicely no matter the column sizes | (some other dfs, like NetBSD df, don't) and that's still | easily used by machines _and_ humans. Maybe -h should be | the default though (which would break scripts, so it can | 't be changed for /usr/bin/df, but in an ideal world...) | | Basically, you can have your cake and eat it too. | zozbot234 wrote: | > I feel the opposite, these kinds of projects imho are just | moving terminals away from their key benefits, being simple, | predictable, brutally functional with no gratuitous | animations or flourishes | | This stuff is not "new" at all. It's just the latest twist on | the ANSI art of old, and the use case is similar. | smolder wrote: | I still use IRSSI as an IRC client, running in a screen | session, through SSH, from multiple machines or even from my | phone. The TUI in gnu screen over SSH setup is really handy | for securely accessing a continuously-running application | from anywhere you happen to be. I could use irccloud or some | other web based thing, sure, but I like hosting my own | services and having auth and device whitelisting uniformly | handled the SSH way. Yet a chat client doesn't work well as a | set of CLI commands as opposed to a TUI. Email from TUI might | not be too bad either. There are lots of cases where I think | it'd fit. | wiseowise wrote: | Nobody forces you to use them. | BiteCode_dev wrote: | Ah but that's the best part about TUI, you can fall back on | the cli when you don't want the whole burrito. | spicybright wrote: | Well, sticking with the analogy you're falling back to a | taco made from different ingredients rather than just a | part of the burrito. That can be intrusive if they decide | to put chicken instead of ground beef in it. | | More concretely, it's using a totally different tool to get | a subset of functionality you want vs other solutions. | | Personally I don't see a reason why one would do that, but | more power to you if you do. If anything, ordering the taco | sometimes is going to give you a more refined palette than | if you got the same burrito each time (i.e. more experience | in the problem space you're working in). | | (I'm getting hungry now...) | stjohnswarts wrote: | .... if the tui app includes the functionality. | leejoramo wrote: | As someone who started out using pre-PC micro-computers | (TRS-80, Apple ][, CP/M), I often would like to have access | to a good suite of what we now call TUI programs. | | Having a common TUI would be a bonus, which briefly existed | back in Borland's heyday. | woodrowbarlow wrote: | in practice, i rarely see a tool that _only_ offers a tui. | most tui tools i encounter will respond helpfully to a | `--help` flag and let me do anything i need from a script. | any tool that doesn 't is nearly useless - i don't think this | is lost on most cli app developers, and i don't think it's at | odds with the quest for 'pretty' UIs in interactive mode. | icedchai wrote: | I feel the same. Simple ANSI color is enough. Call me old | school, I don't want emojis in my terminal. | cauefcr wrote: | With emojis you usually also get unicode, which is great | for all the non-ascii-languages out there. | shreyshnaccount wrote: | imagine cross platform apps that work just as well on phones, | and built using this type of almost scripting like code. (check | out pywebio too) | ludston wrote: | Like a Web browser? | shreyshnaccount wrote: | yes, minus the Javascript. | K0nserv wrote: | I wrote[0] something similar to the first part of this post a | while back for one of the AoC 2019 puzzles. However, it didn't | strike me that you can represent each frame as a set and use the | difference to figure out the resulting render commands, that's | super neat. | | Something strange that I found was: If you redraw only two | characters in the terminal, neither iTerm nor macOS's terminal | would render the update. In my solution I always rendered some | characters redundantly to get around this. | | EDIT: I went back and looked at this code again based on the | insights from this blog post and figured out a few more issues I | had and fixed them. | | 0: https://hugotunius.se/2019/12/29/efficient-terminal- | drawing-... | silon42 wrote: | The biggest problems with terminals are: - some terminals support | escape sequences that can do bad stuff (like when you accidentaly | 'cat' a binary file - keyboard support is severly limited, | especially regarding the Esc key and the modifiers. | ilc wrote: | People underestimate this. But you are very right. | | I'll give a small story from my distant past: | | I went to a college with Sun IPCs and IPXs. It turns out, if | you make the terminal beep on one, it is the HIGHEST priority | thing the machine can do as far as we could tell. So when | someone sent someone else, 2 megs of ^Gs via some mechanism | usable in the 1990's, and recipient is sitting in the middle of | a cathedral computing center. The machine literally will beep, | and beep, and you can't stop it. | | That is a lot of bleeping, beeping. They had to power the poor | machine off. Since I've used visual bell on every terminal | program I use. Since I've turned on Virtual Bell in every | terminal emulator, and I don't trust much on a terminal. | | May a terminal emulator author read my cautionary tale. (Before | you ask: No I was not the user involved.) | wrycoder wrote: | Back in the day, this was called feeping creatures. ___________________________________________________________________ (page generated 2022-08-03 23:00 UTC)