on MacOS I used to use Yabai but moved away from it to using a hammerspoon setup to manipulate window positions. This was mostly because bsp just doesn't scale well with larger displays, in my opinion.
For me, the spatial mapping of windows comes naturally, though. For MacOS, I have 9 spaces. This can be as many or as little as you want, but for me, I have keybindings to switch between them, starting with ctrl + shift and then I map it to:
u i o
j k l
m , .
So in this array, top left is 'u', bottom right is '.' Then you are arbitrarily assigning that area for a certain kind of task or work. so maybe for communications (Teams, Discord, iMessage, etc.) may be designated as being in the 'j' space, or west. My primary work space where I web browsing or coding might be the 'k' area. My email could be 'u' and calendar 'i'. If you've ever worked with two windows side by side, then you already reasoning about it spatially. On the left is my terminal. On the right is my web browser. This just extends that concept slightly. I use 9 spaces in a square shape because it just translates to an extra large desktop.
With that being said, things I'm frequently using (browser, terminal, mail, music, discord, etc) have their own global keys set to launch or switch to them and that is actually what I use most. I think if you can think about how you'd like to organize your system, just practicing that will help you reason about it that way.
I've been trying Niri on my thinkpad and I really like it, though I think I agree that it can be trickier to spatially map where things are in it. Its spaces are vertical and then you are scrolling the horizontal plane. They aren't always the same dimensions because it depends on how many windows are open. Getting back to say, the top right space, requires more work, at least out of the box. But on a smallish laptop screen I think it is well thought out way to make it easier to swap between different views.
The book does contain fascist themes and Heinlein was not advocating for traditional libertarianism in it. I read it more as exploring the boundaries of liberty and what would constitute a “free” society. The society was, for most, effectively free, just that a normal person didn’t have the right to full citizenship without serving. It was a utopia for the average person - only those that served really saw the absolute horrors of war and were the only ones able to vote and hold office. Would you rather live in a society where your quality of life was genuinely excellent but you weren’t entitled to vote or one where your quality of life is markedly worse but you are allowed to steer the direction of your own governance? It’s a theme explored in many utopian stories, usually with the conclusion that freedom trumps ignorant bliss.
In a vacuum I think the interpretation Verhoeven had is mostly fine. It only becomes apparently ignorant if you’ve read more of Heinlein’s work, where libertarian themes are pervasive.
The spec kind of goes into it, but aside from the whole SPAs needing to behave like individual static documents, the big thing is that it's a place to store state. Some of this can be preserved through form actions and anchor tags but some cannot.
Let's say you are on an ecommerce website. It has a page for a shirt you're interested in. That shirt has different variations - color, size, sleeve length, etc.
If you use input elements and a form action, you can save the state that way, and the server redirects the user to the same page but with additional form attributes in the url. You now have a link to that specific variation for you to copy and send to your friend.
Would anyone really ever do that? probably not. More than likely there'd just be an add to cart button. This is serviceable but it's not necessarily great UX.
With the History API you can replace the url with one that will embed the state of the shirt so that when you link it to your friend it is exactly the one you want. Or if you bookmark it to come back to later you can. Or you can bookmark multiple variations without having to interact with the server at all.
Similarly on that web page, you have an image gallery for the shirt. Without History API, maybe You click on a thumbnail and it opens a preview which is a round trip to the server and a hard reload. Then you click next. same thing. new image. then again. and again. and each time you are adding a new item to the history stack. that might be fine or even preferred, but not always! If I want to get back to my shirt, I now have to navigate back several pages because each image has been added to the stack.
If you use the History API, you can add a new url to the stack when you open the image viewer. then as you navigate it, it updates it to point to the specific image, which gives the user the ability to link to that specific image in the gallery. when you're done. If you want to go back you only have to press back once because we weren't polluting the stack with history state with each image change.
Thanks for the detailed and thoughtful reply! I agree that in both of the scenarios you mentioned, this API does provide better usability.
I guess what feels wrong to me is the implicitness of this feature, I'm not sure whether clicking on something is going to add to history or not (until the back button breaks, then I really know).
The History API is pretty useful. It creates a lot of UX improvement opportunities when you're not polluting the stack with unnecessary state changes. It's also a great way to store state so that a user may bookmark or link something directly. It's straight up necessary for SPAs to behave how they should behave, where navigating back takes you back to the previous page.
Yeah but all of this is a symptom of a broader problem rather than reasons why the history API is useful.
SPAs, for example, require so many hacks to work correctly that I often wonder to myself if they’re not really just a colossal mistake that the industry is too blinded to accept.
As a user, I really don't care about the supposed purity or correctness of a website's tech stack. When I click "back" I want to go back to what I think the previous page was.
A building collapsing isn’t the only way people are affected by choices in construction. But if you want to talk about worst case scenarios then I can pick out some examples in IT too:
We constantly see people’s PII leaked on the internet, accounts hacked and money stolen, due to piss poor safeguards in the industry. And that’s without touching on the intentional malpractice of user tracking.
And yes, this is a different issue, but it’s another symptom of the same problem. Tech businesses don’t give a shit, and developers make excuses about how it’s not life or death. Except our bad choices do still negatively affect people’s lives even if we try to convince ourselves it doesn’t.
State management, URL fragment management, reimplementing basic controls...
One that I hate the most is that they first reimplement tabular display with a soup of divs, then because this is slow as a dog, they implement virtualized display, which means they now need to reimplement scrolling, and because this obviously breaks CTRL+F, they end up piling endless hacks to fix that - assuming they bother at all.
The result is a page that struggles to display 100 rows of data. Contrast that with regular HTML, where you can shove 10 000 rows into a table, fully styled, without noticeable performance drop. A "classical" webpage can show couple megabytes worth of data and still be faster and more responsive than typical SPA.
Sounds like you're referring to some specific examples of poorly implemented apps rather than the concept of SPAs as a whole.
For your example, the point of that div soup is that enables behaviours like row/column drag&drop reordering, inline data editing, realtime data syncing and streaming updates, etc. - there is no way to implement that kind of user experience with just html tables.
There's also huge benefit to being able to depend on clientside state. Especially if you want your apps to scale while keeping infra costs minimal.
I get the frustrations you're talking about, but almost all of them are side effects of solutions to very real UX problems that couldn't be solved in any other way.
And to be clear, I'm not saying that people building SPAs when all they needed was a page showing 10,000 rows of static data isn't a problem. It's just a people problem, not an SPA problem.
> all of them are side effects of solutions to very real UX problems that couldn't be solved in any other way.
Except they had been solved in other ways and the problem was people insisted on using web technologies to emulate those other technologies even when web technologies didn’t support the same primitives. And they chose that path because it was cheaper than using the correct technologies from the outset. And thus a thousand hacks were invented because it’s cheaper than doing things properly.
Then along comes Electron, React Native and so on and so forth. And our hacks continue to proliferate, memory usage be damned.
> And they chose that path because it was cheaper than using the correct technologies from the outset
No, otherwise they would not need all those hacks. Web stack makes it cheap (fast and easy) to build an MVP, but since the very primitives required to fully implement requirements are not even there, they end up implementing tons of ugly hacks held by duck tape. All because they thought they could iterate fast and cheap.
It's the same story with teams picking any highly dynamic language for an MVP and then implementing half-baked typing on top of it when the project gets out of MVP stage. Otherwise the bug reproduction rate outpaces fixing rate.
I’ve done both too. And I honestly don’t like the box model.
But I will admit I’ve focused more on desktop than mobile app development. And the thing about sizing stuff is it’s a much easier problem for desktop than mobile apps, which are full screen and you have a multitude of screen sizes and orientations.
>> I get the frustrations you're talking about, but almost all of them are side effects of solutions to very real UX problems that couldn't be solved in any other way.
Any other way? Just build a web app with emscripten. You can do anything.
For a while GTK had an HTML5 backend so you could build whole GUI apps for web, but I think it got dropped because nobody used it.
This is the whole concept of the SPA - make a page behave like multiple pages. The premise itself requires breaking absolutely everything assuming that content is static.
> There's also huge benefit to being able to depend on clientside state. Especially if you want your apps to scale while keeping infra costs minimal.
Um... I'm old enough to remember the initial release of node, where the value proposition was that since you cannot trust client data anyway and have to implement thorough checking both client and server side, why not implement that once.
> I get the frustrations you're talking about, but almost all of them are side effects of solutions to very real UX problems that couldn't be solved in any other way.
Let me introduce you to our lord and savior native app
If you don't manage the history properly in your SPA, pressing the back button could take the user out of the app entirely.
If you don't let web developers manage history/state like this, we'd be going back to the inefficient world of, "every forward/back movement loads a whole page." (With lots of unnecessary round trip messages between the client and server while the user waits for everything to load).
Basically, the ability to manage history is a user-centric feature. It makes the experience better for them.
> If you don't manage the history properly in your SPA, pressing the back button could take the user out of the app entirely.
Yes. And that should be the default behavior: browser buttons should take you through the browser's history. If you keep a in-app state and want the user to navigate through it, you should provide in-app buttons.
Nobody complains that the browser's close button quits the browser instead of the app it's showing, or that the computer's power button shuts down the whole OS and not only the program in the foreground.
Users must be educated. If they have learned that left means "back" and right means "forward", that a star (sometimes a heart) means "remember this for me", and that an underlined checkmark means "download", then understanding the concept of encapsulation shouldn't be too much for them.
> Yes. And that should be the default behavior: browser buttons should take you through the browser's history. If you keep a in-app state and want the user to navigate through it, you should provide in-app buttons.
The Back and Forward buttons on a web browser is the navigation for the web. If you click a link on a static html page it will create a new entry. If you click back, it'll take you back. If you press forward, You will navigate forward.
We should not be creating a secondary set of controls that does the same thing. This is bad UX, bad design, and bad for an accessible web.
> Nobody complains that the browser's close button quits the browser instead of the app it's showing, or that the computer's power button shuts down the whole OS and not only the program in the foreground.
It does close the app it's showing because we have tabs. If you close a tab, it'll close the app that it's showing. If you close the browser, which is made up of many tabs, it closes all of the tabs. Before tabs, if you closed a window, the web page you were on would close as well. It does what is reasonably expected.
If on your web application you have a 'link' to another 'page' where it shows a change in the view, then you'd expect you would be able to press back to go back to what you were just looking at. SPAs that DON'T do that are the ones that are doing a disservice to the user and reasonable navigation expectations.
> Users must be educated. If they have learned that left means "back" and right means "forward", that a star (sometimes a heart) means "remember this for me", and that an underlined checkmark means "download", then understanding the concept of encapsulation shouldn't be too much for them.
They should not have to be 'educated' here. The mental model of using the back and forward buttons to navigate within a webpage is totally fine.
Probably referring to using pushState (part of the History API) to update the URL to a bookmarkable fragment URL, or even to a regular path leading to a created document.
> The new history entry's URL. Note that the browser won't attempt to load this URL after a call to pushState(), but it may attempt to load the URL later, for instance, after the user restarts the browser.
Sure. I'm not speaking about preserving the full history stack in the URL, just storing state. Apologies in advance if my explanation for what I mean is something you already understand.
This can be as simple as having a single checkbox with a checked/unchecked state.
when you load the webpage, the javascript can pull in the url parameters with URLSearchParams (https://developer.mozilla.org/en-US/docs/Web/API/URLSearchPa...). If the url parameter you set is set to 'on' then the checkbox, which is by default unchecked, can be set to on.
You have your checkbox:
<input type="checkbox" id="check">
And then you have your javascript:
const check = document.getElementById('check');
// get state of checkbox from URL parameter
check.checked = new URLSearchParams(location.search).get('state') === 'on';
// add event listener to call history api to alter the URL state.
check.onchange = () => { history.replaceState(null, '', check.checked ? '?state=on' : '?state=off'); };
The history.replaceState() replaces the URL in your history with the one including the URL parameter, so if a user were to bookmark it, it would store that and reload it when they revisit the webpage.
If I used history.pushState(), each time I clicked on the checkbox, a new item would be added to the stack. for a checkbox this is almost certainly a bad idea because your browser history is going to be polluted pretty quickly if you happen to click it multiple times.
pushState can be useful when it matches the user expectations, though, like if it is an SPA and the user clicks on an internal link to another section of the site, they'd expect to be able to go back to the previous page, even though we're still on the same actual html page.
So you would not be preserving the entire history stack. You can sort of do this by encoding state changes into another url parameter, but the behavior isn't entirely consistent between browsers. It also does require, as far as I know, an explicit action from the user for it to actually affect their navigation. So a website couldn't just add 1000 entries to the user's history on load without some explicit interaction on the web page.
Once the user interacts, though, it does seem like it opens up a lot of opportunity to abuse it, intentionally or not. You can asynchronously push thousands of entries into the browser history without blocking interactivity of the site. you can even continue to push state to the URL from other inputs while doing so.
It’s kind of modal editing. Your 99% is enter to send because it’s a chat program. You’re sending mostly quick messages where adding a chorded input to send is just adding extra work to that mode.
When you enter a code block, that assumption changes. You are now in a “long text” mode where the assumptions are shifted where you are more likely want to insert a new line than to send the message.
I think people that have used tables or a spreadsheet and a text editor kind of understand modal editing and why we shift behaviors depending on the context. Pressing tab in a table or spreadsheet will navigate cells instead of inserting a tab character. Pressing arrow keys may navigate cells instead of characters in the cell. Pressing enter will navigate to the cell below, not the first column of the next row. It’s optimized for its primary use case.
I think if the mode change was more explicit it’d maybe be a better experience. Right now it is largely guessing what behavior someone wants based off the context of their message but if that mismatches the users expectations it’s always going to feel clumsy. A toggle or indicator with a keyboard shortcut. Can stick the advanced options inside the settings somewhere if a power user wants to tinker.
> I think people that have used tables or a spreadsheet and a text editor kind of understand modal editing and why we shift behaviors depending on the context.
I don't have a spreadsheet software nearby, but I remember the cell is highlighted different if you're in insert mode or navigation mode. Just like the status line in Vim let's you know which mode you're in.
Babel features are kind of a moot point if you’re just talking about the syntax, which seems to be the purpose of the post. Most of the reason to use org mode is tied to emacs.
There’s no reason you couldn’t do something similar with markdown code blocks if someone were so inclined. But that’s tool dependent, not syntax.
I sort of agree with Karl’s point about there being too many standards of markdown, but I doubt org mode would have survived the same level of popularity without suffering the same fate.
It doesn’t help that there is no standard for org mode. You can only really use and take advantage of its power in emacs. It isn’t susceptible to lossy transformations because there’s only one real org mode editor.
Well, but I am not aware of anyone having come up with a good syntax to do babel things in Markdown. Markdown and Org Mode also set out to serve different purposes. For a quick and dirty text Markdown might suffice, but the babel stuff and spreadsheet stuff enable a lot of use cases that Markdown simply doesn't cater to. We already have the implementation of all these nice things in Emacs. If we were to replicate them for some markdown dialect, they would probably be done half-right, before someone actually manages to get literate programming right for various languages, including what code to translate to, how to wrap or not wrap the code that is inside blocks, sessions, output formats, etc. We might as well use what we have with Emacs. There is probably a way to call Emacs' functionality from outside of Emacs, to treat it as a library.
But not all is well with Org Mode syntax either. Many git hosters have only a very rudimentary implementation of a parser and writing a parser for it is not actually that easy. Its dynamic nature requires at least a 2 step approach of parsing and then later checking all kinds of definitions at the top of a file and further processing the document according to that. It's power comes at that cost. That's probably why we have so many Markdowns, but only one Org Mode (OK maybe a few, counting Vim and VSCodium plugins, that achieve a feature subset).
I will say though, that org mode syntax is much better suited for writing technical documentation than markdown. The only issue is, that not so many people know it or want to learn it, and I don't know a way to change that. Perhaps that effort to have the org mode syntax separately defined (https://gitlab.com/publicvoit/orgdown/-/blob/master/doc/Over...) by the same author will help creating more support for the format in various tools.
I agree you would need to specify the markdown to allow more implementations. https://github.com/jgm/djot Would make a good DSL inside languages, combine that with compile-time execution so that blocks can auto-recalculate and you have a more available mechanism than emacs/org in other languages.
It's more likely it has to do with all the work they're doing to getting the WebExtension API to work with WebKit which is a main selling feature for the MacOS version - using firefox and chrome extensions in a webkit-powered browser.
And esp for the iOS version, where there are not many options for using extensions in other browsers. The only browser there that can use UBO, afaik. In MacOS it is a bit too buggy for me for daily use, ymmv.
The difference between those is the person is actually using this text editor that they built with the help of LLMs. There's plenty of people creating novel scripts and programs that can accommodate their own unique specifications.
If a programmer creating their own software (or contracting it out to a developer) would be a bespoke suit and using software someone or some company created without your input is an off the rack suit, I'd liken these sorts of programs as semi-bespoke, or made to measure.
"LLMs are literally technology that can only reproduce the past" feels like an odd statement. I think the point they're going for is that it's not thinking and so it's not going to produce new ideas like a human would? But literally no technology does that. That is all derived from some human beings being particularly clever.
LLMs are tools. They can enable a human to create new things because they are interfacing with a human to facilitate it. It's merging the functional knowledge and vision of a person and translating it into something else.
The expansion cards seem pretty gimmicky to me. You're replacing a hub with... a bunch of hubs with one port on it. I know it opens up to some third party modules (this one seems particularly cool: https://github.com/LeoDJ/FW-EC-DongleHiderPlus) but for the most part you are getting less connectivity than other laptops. You don't even get an audio jack without taking up one of your expansion slots (edit: on the Framework 16. 13 includes it).
If the expansion slots were larger then they could have maybe facilitated something like getting 2 usb-a ports in exchange for the one USB-C which feels like an actual thing to consider. As it is, it just doesn't feel like you're gaining anything. If you're carrying any additional expansion cards with you you lose the only advantage it has over buying a hub, which can turn that one usb-c slot into multiple usb-a ports, ethernet, hdmi, audio, sd card reader, etc.
> There's no reason why Framework cannot be that successful in 10 years time.
They don't have the resources nor is their scope large enough. Could that change in 10 years? Maybe, but probably not. I'm not even sure it's something they would want to replicate. Retail costs a lot of money and the benefits to it are quite limited. Similarly a service network that would be comparable to one of the larger PC manufacturers would also be very expensive.
> Furthermore, when Framework might become that successful, no need to buy a full new laptop, you can just buy the stuff that failed and move on. And if that does happen, then experience with Framework promises to be much better than experience with Macbook.
The experience you're describing is still involving a person opening up their laptop to replace whatever the failed part is, assuming they even know what the failed part is. I'm qualified to do those sort of diagnostics on a computer and depending on what it is, it'd still be more downtime than going to buy/getting a loaner laptop in most cases.
I'm not saying people can't learn that but I know that people won't.
For me, the spatial mapping of windows comes naturally, though. For MacOS, I have 9 spaces. This can be as many or as little as you want, but for me, I have keybindings to switch between them, starting with ctrl + shift and then I map it to:
So in this array, top left is 'u', bottom right is '.' Then you are arbitrarily assigning that area for a certain kind of task or work. so maybe for communications (Teams, Discord, iMessage, etc.) may be designated as being in the 'j' space, or west. My primary work space where I web browsing or coding might be the 'k' area. My email could be 'u' and calendar 'i'. If you've ever worked with two windows side by side, then you already reasoning about it spatially. On the left is my terminal. On the right is my web browser. This just extends that concept slightly. I use 9 spaces in a square shape because it just translates to an extra large desktop.With that being said, things I'm frequently using (browser, terminal, mail, music, discord, etc) have their own global keys set to launch or switch to them and that is actually what I use most. I think if you can think about how you'd like to organize your system, just practicing that will help you reason about it that way.
I've been trying Niri on my thinkpad and I really like it, though I think I agree that it can be trickier to spatially map where things are in it. Its spaces are vertical and then you are scrolling the horizontal plane. They aren't always the same dimensions because it depends on how many windows are open. Getting back to say, the top right space, requires more work, at least out of the box. But on a smallish laptop screen I think it is well thought out way to make it easier to swap between different views.
reply