<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-713602603894920874</id><updated>2026-02-14T04:13:09.105-08:00</updated><category term="Computer-Tech"/><category term="Programming"/><category term="Education"/><category term="Ubuntu-Linux"/><category term="Mental-Note"/><category term="Computing-Science"/><category term="Mac"/><category term="Updated"/><category term="Science"/><category term="Clojure"/><category term="Windows-OS"/><category term="Book-Review"/><category term="Artificial-Intelligence"/><category term="Book-Recommended"/><category term="Lubuntu"/><category term="Philosophy"/><category term="Computer-Security"/><category term="Math"/><category term="Web-Development"/><category term="Business"/><category term="Canada"/><category term="Java"/><category term="JavaScript"/><category term="Economics"/><category term="Communication"/><category term="Debian-Linux"/><category term="Emacs"/><category term="Career"/><category term="IT-Networking"/><category term="Web-Design"/><category term="Firefox"/><category term="Incanter"/><category term="React"/><category term="React-Native"/><category term="TypeScript"/><category term="marketing"/><category term="DNS"/><category term="Finance"/><category term="Git"/><category term="Keyboard"/><category term="SMART-Tech"/><category term="Alberta"/><category term="Bibliography"/><category term="Frauds-Scams"/><category term="Health"/><category term="LaTeX"/><category term="Python"/><category term="Thesis-Writing"/><category term="Writing"/><category term="iOS"/><category term="Blogger"/><category term="Django"/><category term="Elixir"/><category term="Haskell"/><category term="OpenShift"/><category term="Phoenix"/><category term="Politics"/><category term="Skype"/><title type='text'>Tech Stuff and Notes</title><subtitle type='html'>on software development, computing science, software technologies, learning, etc.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://blog.carsoncheng.ca/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/713602603894920874/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://blog.carsoncheng.ca/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/713602603894920874/posts/default?start-index=26&amp;max-results=25&amp;redirect=false'/><author><name>blogger</name><uri>http://www.blogger.com/profile/09586588053165570068</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>243</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-713602603894920874.post-4597699661403210753</id><published>2024-10-03T13:54:00.000-07:00</published><updated>2024-10-19T11:17:33.026-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Artificial-Intelligence"/><category scheme="http://www.blogger.com/atom/ns#" term="Business"/><category scheme="http://www.blogger.com/atom/ns#" term="Computer-Tech"/><category scheme="http://www.blogger.com/atom/ns#" term="Economics"/><title type='text'>Resistance to AI Automation will crumble</title><content type='html'>&lt;p&gt;And I don&#39;t mean The Resistance to Terminators.&lt;br /&gt;&lt;br /&gt;Al automation promises to revolutionize white-collar or office work. Some think there’s plenty of resistance against quick AI adoption and so there won’t be major negative societal disruptions. I’ve come to believe that resistance will crumble.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;Legal and copyright issues could slow AI down, but not for long.&lt;/h2&gt;&lt;p&gt;&lt;br /&gt;AI generated code may be hard to accept into proprietary code bases due to legal uncertainty, e.g., copyright issues.&amp;nbsp; For example, the Google v Oracle Java lawsuit started in 2010 and reached conclusion in the Supreme Court in 2021.&amp;nbsp; That’s 11 years of legal uncertainty over whether there was copied code.&lt;br /&gt;&lt;br /&gt;Having said that, Google kept using the disputed technology through those years of litigation.&amp;nbsp; There are ways around legal issues like that I presume.&amp;nbsp; And the legal cases against AI are already underway as in the Github Copilot lawsuit [1], so the clock is already ticking — and currently, the AI side is winning [2].&lt;br /&gt;&lt;br /&gt;It feels there&#39;s some amount of inevitability at play too in terms of resolving the copyright issues.&amp;nbsp; The actors&#39; guild has agreed to a contract allowing limited AI usage with major media companies. OpenAI is securing deals with media companies to train and utilize their copyrighted materials. The writing is on the wall, and AI is writing it. &lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;People and companies are resistant to change, but new folks will jump ahead&lt;/h2&gt;&lt;p&gt;&lt;br /&gt;Some say &quot;The future is already here; it&#39;s just unevenly distributed&quot; (William Gibson).&lt;br /&gt;&lt;br /&gt;One reason that happens is that status quo lowers risk.&amp;nbsp; If you&#39;re Apple and if you have AI that can do the work of half your software development workforce, do you layoff 50% of SDEs?&amp;nbsp; No.&amp;nbsp; No one has the risk tolerance for that big a move all at once.&amp;nbsp; What if you were wrong?&amp;nbsp; What if the wrong automation tech is used, or the people you hire to manage that get it wrong?&amp;nbsp; Betting &quot;all in&quot; on a single roll of the dice is too risky.&lt;br /&gt;&lt;br /&gt;Not without an external crisis, at least.&lt;br /&gt;&lt;br /&gt;The oil and gas industry used to employ a lot of people.&amp;nbsp; Until oil price crashed and belt tightening resulted in lots of layoffs and automation.&amp;nbsp; Those jobs are never coming back because they were automated away [11].&amp;nbsp; But without the price crash, the amount or severity of layoffs might not have been as bad.&lt;br /&gt;&lt;br /&gt;After all, one way for a manager to get promoted is by managing more people and a bigger budget.&amp;nbsp; So the status quo of using more people than automation is a self-interested move.&amp;nbsp; A crisis like a big oil price crash is required to shake that status quo loose.&lt;br /&gt;&lt;br /&gt;But new companies don&#39;t have the same status quo problem.&amp;nbsp; Old companies will either succeed or fail.&amp;nbsp; New startups with come in with automation and AI baked in to reduce cost, extend their funding runway, and to get product market fit faster.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;Old Tech will eventually come around to automation anyway&lt;/h2&gt;&lt;p style=&quot;text-align: left;&quot;&gt;&lt;br /&gt;People say that it&#39;s normal for FAANG type companies to lose 5% or more tech workers every year for various reasons [3].&amp;nbsp; Attrition, eliminating teams of projects that get cancelled, &quot;unregretted attrition&quot;, etc.&amp;nbsp; Depending on the speed of AI automation progress, old tech companies can just keep up with 5% unregretted attrition each year to slowly turnover the company to AI.&lt;br /&gt;&lt;br /&gt;Some might say it&#39;s already started since 2022 [4].&lt;br /&gt;&lt;br /&gt;And for those old stuffy companies who don&#39;t come around fast enough to automation?&amp;nbsp; They can always turn from being an engineering company into a financial engineering firm, like Siemens, IBM or GE.&lt;br /&gt;&lt;br /&gt;I’m kidding! Slightly.&amp;nbsp; But just because Air Canada will probably think twice about using AI for customer service after that lawsuit [8], that doesn’t mean they won’t outsource to an AI customer service startup that’s also willing to defend them against lawsuits.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;Lump of Labour fallacy is about the whole economy, not a single sector&lt;/h2&gt;&lt;p style=&quot;text-align: left;&quot;&gt;&lt;br /&gt;Some say don&#39;t worry about AI automation producing negative societal disruptions in the form of making everyone unemployed because Lump of Labour is a fallacy [6].&lt;br /&gt;&lt;br /&gt;The Lump of Labour fallacy misconception is that there&#39;s only a fixed amount of work to be done, so don&#39;t worry about automation taking work away from people!&amp;nbsp; There&#39;ll always be more work invented by people to do!&lt;br /&gt;&lt;br /&gt;Some would say this time is different because AI could do that newly invented work too.&amp;nbsp; But even without this AI-everywhere angle, you have to see that the type of work may be different.&lt;br /&gt;&lt;br /&gt;When manufacturing and software development work gets automated, what new work is there to do?&amp;nbsp; Those workers can re-skill into making TikTok influencing channels?&lt;br /&gt;&lt;br /&gt;Some say “yes, of course”, but there&#39;s just no guarantee that the new work would be &quot;better&quot; (e.g. higher abstraction of code, safer workplace, higher paying, improved quality of life at work).&amp;nbsp; It could be worse or more dangerous.&amp;nbsp; As climate change gets worse, maybe those displaced tech workers can re-skill into forest fire fighting?&amp;nbsp; I doubt non-robotic LLMs can do that.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;Jevons Paradox applies to things people want, not things people are ambivalent about or worse&lt;/h2&gt;&lt;p style=&quot;text-align: left;&quot;&gt;&lt;br /&gt;Some say don&#39;t worry about AI automation making office/tech/programming workers unemployed because Jevons says greater efficiency will induce more demand for software, etc. [6]&lt;br /&gt;&lt;br /&gt;Jevons Paradox states that increased efficiency leads to increased consumption.&amp;nbsp; i.e. as X becomes more efficient, more X will be used. Substitute X with:&lt;br /&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Oil&lt;/li&gt;&lt;li&gt;Gas&lt;/li&gt;&lt;li&gt;Electricity&lt;/li&gt;&lt;li&gt;Microsoft Office&lt;/li&gt;&lt;/ul&gt;&lt;p style=&quot;text-align: left;&quot;&gt;&lt;br /&gt;Look, people want dogs and cats.&amp;nbsp; But generally speaking, people aren&#39;t into wanting software developers and assembly line workers.&lt;br /&gt;&lt;br /&gt;USA is manufacturing more than ever, but is employing fewer manufacturing workers than ever. Maybe AI will let us substitute &quot;manufacturing&quot; with &quot;software developing&quot; in that sentence.&lt;br /&gt;&lt;br /&gt;Consumers want the goods, not the people producing them (see: offshoring).&amp;nbsp; If AI can produce it cheaper with fewer humans involved and without animal testing, then consumers would want that instead (mainly because it&#39;s cheaper).&lt;br /&gt;&lt;br /&gt;So at best, Jevons says people will want more software and apps than ever before because they&#39;ll get more efficient with AI.&amp;nbsp; But nothing says that the code has to be written by humans.&lt;br /&gt;&lt;br /&gt;In fact, we&#39;ve seen this last point before.&amp;nbsp; Practically no one writes the assembly code that those software requires written to work — compilers write that automatically for us since decades ago.&lt;br /&gt;&lt;br /&gt;Fortunately, assembly code programmers could easily up-skill to higher level languages like Java.&amp;nbsp; With AI, coders may have to up-skill to higher level languages like English, and compete with all the non-coders who can already English better than them.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;Software developers will work at higher levels of abstractions.&amp;nbsp; Yes, and so can everyone else&lt;/h2&gt;&lt;p style=&quot;text-align: left;&quot;&gt;&lt;br /&gt;Some say software developers shouldn&#39;t worry about automation taking their jobs, because at best AI can spit out code given some architecture and specifications for problems that the human software developer has to write up into prompts.&amp;nbsp; So the human SDE can now work at a higher level of abstraction, work at system design levels and above, double check the code that AI produced to make sure there&#39;s no hallucinations.&lt;br /&gt;&lt;br /&gt;Sure, yes.&amp;nbsp; But what evidence is there that BSc graduates with education in algorithms and data structures can write those prompts better than, e.g., BA philosophy graduates who trained in close-reading, analyzing, and writing highly technical English in all their Analytic Philosophy classes?&lt;br /&gt;&lt;br /&gt;There&#39;s also a lot of LLB lawyers who are underemployed in the legal or adjacent fields doing paralegal or repetitive property conveyancing work.&amp;nbsp; Maybe some of them can do this AI software development prompting better than CS/SDE graduates?&lt;br /&gt;&lt;br /&gt;In fact, we&#39;ve seen this broadening (or democratizing) of a labour field before.&amp;nbsp; It used to be highly technical and challenging work to do special event photography.&amp;nbsp; You have to get the lighting, shutter speed, and aperture just right or else you&#39;ll miss the moment, or waste and run out of expensive film.&amp;nbsp; Digital SLR photography and big inexpensive memory cards means many with an eye for beautiful photos can now do wedding photography, take 1000s of photos, then choose the best 50 afterwards.&amp;nbsp; Or just fix it in &quot;post&quot; with Photoshop.&lt;br /&gt;&lt;br /&gt;This means sky-high compensations or job security will come down, if not in one field (tech), then maybe in any field that&#39;s at risk of AI automation (all white collar or office jobs).&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;AI is a bubble, until it’s not&lt;/h2&gt;&lt;p style=&quot;text-align: left;&quot;&gt;&lt;br /&gt;The last few points focused more on software development, but that’s a canary in the coal mine.&amp;nbsp; Some say software development is more resistant to AI automation because it’s already in the business of automation [7].&amp;nbsp; But that just means that if (since?) software engineering labour is at risk, then many other fields are also at risk too.&lt;br /&gt;&lt;br /&gt;Some say AI is like crypto.&amp;nbsp; It’s all hype and a bubble run like or by some of the same personalities.&amp;nbsp; But that’s a useless comparison.&amp;nbsp; Can you, in 1999, tell if the internet is a bubble or not based on how tulips were a bubble [9]?&amp;nbsp; They’re just not the same.&amp;nbsp; And at least with AI there are clear and present use-cases, no AGI required.&lt;br /&gt;&lt;br /&gt;So forget AGI.&amp;nbsp; Resistance to automation will crumble.&amp;nbsp; There&#39;s too much money to be made in automating even just 10% [10] of the white-collar or office work labour market, in whole or in part, outright or by “just” improving human efficiency.&amp;nbsp; That&#39;s the &quot;killer app&quot; of AI.&lt;br /&gt;&lt;br /&gt;Don’t focus so much on the automating a worker outright-in-whole part.&amp;nbsp; Instead, focus on the replacement in-part, by “just” improving human efficiency, part.&amp;nbsp; E.g. Self-checkout didn’t eliminate “cashiers”, but allows one supervisor to do the work of (say) three cashiers.&lt;br /&gt;&lt;br /&gt;How much profit can this “killer app&quot; make that would justify the (non) bubble?&amp;nbsp; I lazily checked with Meta AI and it says:&lt;br /&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;telemarketing and public opinion researchers (including call center representatives) in the USA in 2020 probably had compensation of about $100B&lt;/li&gt;&lt;li&gt;software developers (including applications and systems software developers) employed in the USA in 2020 made about $200B&lt;/li&gt;&lt;li&gt;office managers, supervisors, support and assistants employed in the USA in 2020 made about $200B&lt;/li&gt;&lt;/ul&gt;&lt;p style=&quot;text-align: left;&quot;&gt;&lt;br /&gt;That’s $500B right there. So by automating even just 10%, it’d take just 10 years to fill the $500 billion dollar revenue gap [5].&amp;nbsp; That percentage will go up, the addressable market is not just the USA, and there are many other labour fields to automate than those.&lt;br /&gt;&lt;br /&gt;That’s why I think AI adoption will be quicker and there’ll be more negative societal disruptions coming up.&amp;nbsp; We can’t all re-skill to fight forest fires.&lt;/p&gt;&lt;p style=&quot;text-align: left;&quot;&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left;&quot;&gt;&lt;b&gt;EDIT&lt;/b&gt;: To clarify, I don&#39;t mean for sure tech or any other jobs will definitely get decimated by AI efficiency gains.&amp;nbsp; It&#39;s just that quoting &quot;Jevons&quot; or &quot;Lump of Labour&quot; isn&#39;t a knock-out against that possibility.&amp;nbsp; The analysis has to be deeper than just invoking those, by now, thought-stopping thoughts.&lt;/p&gt;&lt;p style=&quot;text-align: left;&quot;&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left;&quot;&gt;Let me volunteer one possibility, for example, AI makes coding jobs 10% more efficient, meaning cost of labour is reduced.&amp;nbsp; Because cost of software production goes down, consumers want more apps, so much more than the 10% efficiency gains allow that more humans developers are needed.&amp;nbsp; This is the classic &lt;a href=&quot;https://en.wikipedia.org/wiki/Rebound_effect_(conservation)&quot; target=&quot;_blank&quot;&gt;rebound effect&lt;/a&gt; in Jevons.&amp;nbsp; Notice it requires consumers to want so much more apps that it more than offsets the 10% efficiency gains — there is &lt;a href=&quot;https://blog.carsoncheng.ca/2024/09/jevons-is-paradox-not-rule.html&quot;&gt;no guarantee&lt;/a&gt; it rebounds that much!&lt;/p&gt;&lt;p style=&quot;text-align: left;&quot;&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left;&quot;&gt;&lt;b&gt;EDIT 2&lt;/b&gt;: Also, jobs getting decimated by AI efficiency gains is not necessarily bad!&amp;nbsp; Machines decimated coal mining jobs, which is bad for jobs, but given there are better alternate jobs, it was great for the health and safety of would-be coal miners!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;[1]: &lt;a href=&quot;https://www.artificialintelligence-news.com/news/openai-and-microsoft-lawsuit-github-copilot/&quot;&gt;https://www.artificialintelligence-news.com/news/openai-and-microsoft-lawsuit-github-copilot/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;[2]: &lt;a href=&quot;https://www.developer-tech.com/news/judge-dismisses-majority-github-copilot-copyright-claims/&quot;&gt;https://www.developer-tech.com/news/judge-dismisses-majority-github-copilot-copyright-claims/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;[3]: &lt;a href=&quot;https://www.seattletimes.com/business/amazon/internal-amazon-documents-shed-light-on-how-company-pressures-out-6-of-office-workers/&quot;&gt;https://www.seattletimes.com/business/amazon/internal-amazon-documents-shed-light-on-how-company-pressures-out-6-of-office-workers/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;[4]: &lt;a href=&quot;https://layoffs.fyi&quot;&gt;https://layoffs.fyi&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;[5]: &lt;a href=&quot;https://blog.carsoncheng.ca/2024/07/re-500b-ai-revenue-expectations-gap.html&quot;&gt;https://blog.carsoncheng.ca/2024/07/re-500b-ai-revenue-expectations-gap.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;[6]: AI and the automation of work. &lt;a href=&quot;https://www.ben-evans.com/benedictevans/2023/7/2/working-with-ai&quot;&gt;https://www.ben-evans.com/benedictevans/2023/7/2/working-with-ai&lt;/a&gt; &lt;br /&gt;&lt;br /&gt;[7]: I believe Yann LeCun said something like that but I can’t find the source.&lt;br /&gt;&lt;br /&gt;[8]: &lt;a href=&quot;https://www.cbc.ca/news/canada/british-columbia/air-canada-chatbot-lawsuit-1.7116416&quot;&gt;https://www.cbc.ca/news/canada/british-columbia/air-canada-chatbot-lawsuit-1.7116416&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;[9]: &lt;a href=&quot;https://en.m.wikipedia.org/wiki/Tulip_mania&quot;&gt;https://en.m.wikipedia.org/wiki/Tulip_mania&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;[10]: &lt;a href=&quot;https://news.ycombinator.com/item?id=41465081&quot;&gt;https://news.ycombinator.com/item?id=41465081&lt;/a&gt; - study says there&#39;s a 26.08% increase in productivity with AI, and more specifically a 27% to 39% for junior level and 8% to 13% at senior level.&amp;nbsp; So my &quot;10%&quot; guess wasn&#39;t too bad?&lt;br /&gt;&lt;br /&gt;[11]: &lt;a href=&quot;https://www.parklandinstitute.ca/job_creation_or_job_loss&quot;&gt;https://www.parklandinstitute.ca/job_creation_or_job_loss&lt;/a&gt; - “the Big Four are leading the push to automate away even more jobs in the coming years … The Alberta oil and gas industry employed 25,788 fewer workers in 2021 than in 2014 (a 15.5% reduction)”&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.carsoncheng.ca/feeds/4597699661403210753/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/713602603894920874/4597699661403210753' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/713602603894920874/posts/default/4597699661403210753'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/713602603894920874/posts/default/4597699661403210753'/><link rel='alternate' type='text/html' href='http://blog.carsoncheng.ca/2024/10/resistance-to-ai-automation-will-crumble.html' title='Resistance to AI Automation will crumble'/><author><name>blogger</name><uri>http://www.blogger.com/profile/09586588053165570068</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-713602603894920874.post-8520986575869001622</id><published>2024-10-02T01:50:00.000-07:00</published><updated>2024-10-02T01:50:00.115-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Artificial-Intelligence"/><category scheme="http://www.blogger.com/atom/ns#" term="Business"/><category scheme="http://www.blogger.com/atom/ns#" term="Computer-Tech"/><category scheme="http://www.blogger.com/atom/ns#" term="Economics"/><title type='text'>Labour Automation vs Growth</title><content type='html'>&lt;p&gt;Automation in oil and gas reduced labour needed to extract and produce oil. Oil as a product is not a platform-platform. Oil usage cannot induce demand for ever more oil by being a medium for platforms that can recursively host more platforms of products. Because oil does not induce exponential demand, then automation has a good chance of reducing labour down.&lt;br /&gt;&lt;br /&gt;The flip side is that platform-platforms can recursively host more platforms of products. So platform-platforms has a chance to induce exponential demand, and so while automation reduces labour per unit produced, on the whole the exponential demand for units can balance out if not even increase labour required industry-wide.&lt;br /&gt;&lt;br /&gt;C compilers are not platform-platforms. Compilers in general basically eliminated all assembly programming labour. The reason there are more programmers now than when assembly language reigned supreme is not because compiler automation freed up labour for more creative things. The reason is more because that other platform-platforms like the internet and operating systems induced exponential demand for software.&lt;br /&gt;&lt;br /&gt;Other examples of automation that are not platform-platforms and in fact eliminated a lot of labour include:&lt;br /&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Manufacturing automation&lt;/li&gt;&lt;li&gt;Bookbinding automation (replaced by printing presses)&lt;/li&gt;&lt;li&gt;Telephone switchboard automation (replaced by digital systems)&lt;/li&gt;&lt;/ul&gt;&lt;p style=&quot;text-align: left;&quot;&gt;&lt;br /&gt;Jevons Paradox states that increased efficiency leads to increased consumption.&amp;nbsp; i.e. as X becomes more efficient, more X will be used. Substitute X with:&lt;br /&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Oil&lt;/li&gt;&lt;li&gt;Gas&lt;/li&gt;&lt;li&gt;Electricity&lt;/li&gt;&lt;li&gt;Microsoft Office&lt;/li&gt;&lt;/ul&gt;&lt;p style=&quot;text-align: left;&quot;&gt;&lt;br /&gt;But software developers? Or assembly line workers? USA is manufacturing more than ever, but is employing fewer manufacturing workers than ever. Maybe AI will allow us to&amp;nbsp; substitute &quot;manufacturing&quot; with &quot;software developing&quot; in that sentence.&lt;br /&gt;&lt;br /&gt;Jevon&#39;s Paradox &quot;works&quot; only for items that consumers actually want. If extreme environmentalism &quot;won&quot;, gas usage would go down no matter how efficient gas engines get. If coal-powered SUVs became unreasonably ultra trendy, coal use would go up regardless of how inefficient coal was.&lt;br /&gt;&lt;br /&gt;Software development and manufacturing workers are not goods that consumers want. They want what&#39;s produced. And if AI can produce it cheaper with fewer humans involved and without animal testing, then consumers would want that instead.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.carsoncheng.ca/feeds/8520986575869001622/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/713602603894920874/8520986575869001622' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/713602603894920874/posts/default/8520986575869001622'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/713602603894920874/posts/default/8520986575869001622'/><link rel='alternate' type='text/html' href='http://blog.carsoncheng.ca/2024/10/labour-automation-vs-growth.html' title='Labour Automation vs Growth'/><author><name>blogger</name><uri>http://www.blogger.com/profile/09586588053165570068</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-713602603894920874.post-5394365486800605310</id><published>2024-10-01T01:48:00.000-07:00</published><updated>2024-10-01T01:48:00.234-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Artificial-Intelligence"/><category scheme="http://www.blogger.com/atom/ns#" term="Business"/><category scheme="http://www.blogger.com/atom/ns#" term="Computer-Tech"/><category scheme="http://www.blogger.com/atom/ns#" term="Economics"/><title type='text'>The Internet is a Platform-Platform.  AI is not.</title><content type='html'>&lt;p&gt;AI is not like the internet or computer operating system software in terms of its economic impact.&lt;br /&gt;&lt;br /&gt;The latter two are platform-platforms while AI is not.&lt;br /&gt;&lt;br /&gt;A platform is a kind of medium.&amp;nbsp; e.g. YouTube is a platform for videos.&lt;br /&gt;&lt;br /&gt;Some platforms are special in that they are recursively platforms for platforms.&lt;br /&gt;&lt;br /&gt;Computer hardware are platform-platforms.&amp;nbsp; They&#39;re a medium for various single purpose built software, of course, but more importantly they are also a medium for different operating systems (OSs).&lt;br /&gt;&lt;br /&gt;OSs like macOS or Windows are platform-platforms.&amp;nbsp; The most easiest and reductive way to see this is that you can virtualize and run macOS on Windows, and vice versa.&amp;nbsp; More substantively, these OSs can run internet or web browsers.&lt;br /&gt;&lt;br /&gt;Internet and web browsers and the physical internetwork they connect to form platform-platforms.&amp;nbsp; Different businesses run on the web, but more importantly, the web or internet are a medium for running app stores on desktop and mobile devices.&lt;br /&gt;&lt;br /&gt;Is AI a platform-platform?&amp;nbsp; What is it a medium for?&amp;nbsp; Does this medium support a platform recursively?&lt;br /&gt;&lt;br /&gt;Or is AI more like a sufficiently smart general compiler?&amp;nbsp; AI can automate existing products and workflows, but it isn&#39;t a medium that will enable more products exponentially by carrying platforms on platforms … on platforms.&lt;br /&gt;&lt;br /&gt;Others have noted similar ideas.&amp;nbsp; e.g. AI is a feature, not a product.&amp;nbsp; Actually, it&#39;s worse: &quot;AI is a tech to enable a feature, not a feature in itself&quot; [1].&lt;br /&gt;&lt;br /&gt;Or that current AI are automated &quot;infinite interns that can write anything for you&quot; [2].&amp;nbsp; But follow that train of thought to the conclusion that a human-level current-generation AI would be an actually-human intern and now wonder: since when do human interns (even an infinity of them) form a medium that can be a platform for platforms?&amp;nbsp; (… unless you use them like transistors, to do computation as a human powered Turing machine, just to argue they can do what actual computers can already do.)&lt;br /&gt;&lt;br /&gt;This distinction between products and platforms vs platform-platforms can inform us on the economic impact of AI on society.&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;[1]:&amp;nbsp;( &lt;a href=&quot;https://www.threads.net/@benedictevans/post/C8C00e5OZBT&quot;&gt;https://www.threads.net/@benedictevans/post/C8C00e5OZBT&lt;/a&gt; )&lt;/p&gt;&lt;p&gt;&amp;nbsp;[2]: ( &lt;a href=&quot;https://www.ben-evans.com/benedictevans/2023/7/2/working-with-ai&quot;&gt;https://www.ben-evans.com/benedictevans/2023/7/2/working-with-ai&lt;/a&gt; )&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.carsoncheng.ca/feeds/5394365486800605310/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/713602603894920874/5394365486800605310' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/713602603894920874/posts/default/5394365486800605310'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/713602603894920874/posts/default/5394365486800605310'/><link rel='alternate' type='text/html' href='http://blog.carsoncheng.ca/2024/10/the-internet-is-platform-platform-ai-is.html' title='The Internet is a Platform-Platform.  AI is not.'/><author><name>blogger</name><uri>http://www.blogger.com/profile/09586588053165570068</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-713602603894920874.post-3953640319731019033</id><published>2024-09-16T02:00:00.000-07:00</published><updated>2024-09-16T02:00:00.117-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Artificial-Intelligence"/><category scheme="http://www.blogger.com/atom/ns#" term="Career"/><category scheme="http://www.blogger.com/atom/ns#" term="Computer-Tech"/><category scheme="http://www.blogger.com/atom/ns#" term="Programming"/><category scheme="http://www.blogger.com/atom/ns#" term="Writing"/><title type='text'>Jevons Is a Paradox, Not a Rule</title><content type='html'>&lt;p&gt;Jevons Paradox says that as technology becomes more efficient, overall resource consumption can increase. This was seen during the Industrial Revolution when more efficient coal engines led to higher coal usage. However, this paradox is not universal, and efficiency can also lead to reduced resource consumption.&lt;br /&gt;&lt;br /&gt;In the context of AI coding tools (e.g. GitHub Copilot), there&#39;s a belief that increased efficiency will lead to more coding jobs by lowering development costs. While this may happen, history shows that technological advancements can also displace workers.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Counter Examples&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;The invention of programming compilers made coding more efficient but reduced demand for assembly language programmers, who were once critical to assembly-based software development. While many of those programmers probably found other coding jobs in higher-level languages, Jevons simply doesn&#39;t guarantee it.&lt;br /&gt;&lt;br /&gt;Similar patterns have occurred in other industries more starkly. The mechanization of agriculture reduced the need for farm labor.&amp;nbsp; See this graph: &lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;https://ourworldindata.org/grapher/number-of-people-employed-in-agriculture&quot;&gt;https://ourworldindata.org/grapher/number-of-people-employed-in-agriculture&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Then there&#39;s the replacement of draft horses, where ICE vehicles meant horses were no longer needed and millions of draft horses were slaughtered or displaced, and their population dwindled.&amp;nbsp; See this graph:&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;https://www.researchgate.net/publication/338480301/figure/fig1/AS:845430833283085@1578577826802/Evolution-of-the-horse-population-in-France-from-1800-to-2010-translated-from-French.ppm&quot;&gt;https://www.researchgate.net/publication/338480301/figure/fig1/AS:845430833283085@1578577826802/Evolution-of-the-horse-population-in-France-from-1800-to-2010-translated-from-French.ppm&lt;/a&gt; &lt;br /&gt;&lt;br /&gt;In recent years, coal consumption has fallen despite energy efficiency gains due to the shift to other energy sources (e.g. renewables, gas).&lt;br /&gt;&lt;br /&gt;The rebound effect, which drives Jevons Paradox, doesn’t always occur at full strength. For example, energy-efficient LED lighting and fuel-efficient cars have reduced overall energy and fuel consumption, despite potentially increasing usage. Similarly, AI tools may lead to fewer coding jobs, even if more code is produced.&lt;br /&gt;&lt;br /&gt;Ultimately, while AI could increase software development demand, it may also reduce the need for certain types of programmers. History shows that efficiency gains don’t always lead to more jobs. Jevons didn&#39;t guarantee draft horses more jobs, after all.&lt;br /&gt;&lt;br /&gt;This was written in collaboration with an AI — another example where more words will be written as efficiency per word increases but the number of writing jobs may well decrease (as it apparently already has: &lt;a href=&quot;https://www.bbc.com/news/business-65906521&quot;&gt;https://www.bbc.com/news/business-65906521&lt;/a&gt; ). &lt;br /&gt;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.carsoncheng.ca/feeds/3953640319731019033/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/713602603894920874/3953640319731019033' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/713602603894920874/posts/default/3953640319731019033'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/713602603894920874/posts/default/3953640319731019033'/><link rel='alternate' type='text/html' href='http://blog.carsoncheng.ca/2024/09/jevons-is-paradox-not-rule.html' title='Jevons Is a Paradox, Not a Rule'/><author><name>blogger</name><uri>http://www.blogger.com/profile/09586588053165570068</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-713602603894920874.post-3928805697153688280</id><published>2024-08-13T15:02:00.000-07:00</published><updated>2024-08-13T15:02:00.119-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Computer-Tech"/><category scheme="http://www.blogger.com/atom/ns#" term="Mac"/><title type='text'>How to use Homebrew on a Multi-user macOS</title><content type='html'>&lt;p&gt;You&#39;ll find descriptions of how to do this, like on StackOverflow: &lt;a href=&quot;https://stackoverflow.com/questions/41840479/how-to-use-homebrew-on-a-multi-user-macos-sierra-setup&quot; target=&quot;_blank&quot;&gt;How to use Homebrew on a Multi-user MacOS Sierra Setup&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;It&#39;s said that using `sudo` is wrong.&lt;/p&gt;&lt;p&gt;It&#39;s said that using a per-user local version of brew is right, but...&lt;/p&gt;&lt;p&gt;1. it doesn&#39;t play well with `nvm` (&lt;a href=&quot;https://stackoverflow.com/questions/41840479/how-to-use-homebrew-on-a-multi-user-macos-sierra-setup#comment118321744_55021458&quot; target=&quot;_blank&quot;&gt;see&lt;/a&gt;)&lt;/p&gt;&lt;p&gt;2. it is completely and entirely unsupported (&lt;a href=&quot;https://stackoverflow.com/questions/41840479/how-to-use-homebrew-on-a-multi-user-macos-sierra-setup#comment133690270_55021458&quot; target=&quot;_blank&quot;&gt;see&lt;/a&gt;)&lt;/p&gt;&lt;p&gt;3. many packages don&#39;t support it (&lt;a href=&quot;https://stackoverflow.com/questions/41840479/how-to-use-homebrew-on-a-multi-user-macos-sierra-setup#comment136593573_55021458&quot; target=&quot;_blank&quot;&gt;see&lt;/a&gt;)&lt;/p&gt;&lt;p&gt;4. many packages will install from source instead of a binary (&lt;a href=&quot;https://stackoverflow.com/questions/41840479/how-to-use-homebrew-on-a-multi-user-macos-sierra-setup#comment138783588_55021458&quot; target=&quot;_blank&quot;&gt;see&lt;/a&gt;)&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;So the &lt;b&gt;&lt;i&gt;practical&lt;/i&gt;&lt;/b&gt;, quick and dirty solution is to just use `sudo` (&lt;a href=&quot;https://stackoverflow.com/questions/41840479/how-to-use-homebrew-on-a-multi-user-macos-sierra-setup/44481141#44481141&quot; target=&quot;_blank&quot;&gt;see&lt;/a&gt;).&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;In my experience&lt;/b&gt;, if I recall correctly, homebrew on macOS 14 by default uses the group &quot;admin&quot; for where it installs things, and it sets the permissions to &quot;read&quot; and &quot;execute&quot; as needed already.&amp;nbsp; The only thing missing are &quot;write&quot; permissions.&amp;nbsp; And for the user to include brew binaries on their PATH.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Also, &quot;Administrator&quot; users on Macs are in group &quot;admin&quot; by default already too.&amp;nbsp; I&#39;m guessing if your user is using brew, they&#39;re probably a macOS &quot;Administrator&quot; too (or else why would you let them use a global brew install?).&lt;br /&gt;&lt;/p&gt;&lt;p&gt;So I just ran in Terminal:&lt;br /&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;$ sudo chmod -R g+w $(brew --prefix)&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;Then for the user that wants to use brew, put in their home directory&#39;s &quot;.zprofile&quot; file:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;blockquote&gt;eval &quot;$(/opt/homebrew/bin/brew shellenv)&quot;&lt;/blockquote&gt;&lt;br /&gt;To ensure brew is working for them, run in their Terminal: $ brew doctor&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Warning&lt;/b&gt;: this is unsupported, and it&#39;s said to be wrong, and you&#39;re letting all Admin users on that machine to share one single installation of homebrew!&lt;/p&gt;&lt;p&gt;If roommates fight over fridge space, you&#39;ve got no one but yourself to blame for not buying each roommate their own fridge!&lt;/p&gt;&lt;p&gt;So what use-case does this safely enable?&amp;nbsp; A single human with multiple macOS user profiles to isolate their work space while sharing (with themselves!) the same global brew install.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.carsoncheng.ca/feeds/3928805697153688280/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/713602603894920874/3928805697153688280' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/713602603894920874/posts/default/3928805697153688280'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/713602603894920874/posts/default/3928805697153688280'/><link rel='alternate' type='text/html' href='http://blog.carsoncheng.ca/2024/08/how-to-use-homebrew-on-multi-user-macos.html' title='How to use Homebrew on a Multi-user macOS'/><author><name>blogger</name><uri>http://www.blogger.com/profile/09586588053165570068</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-713602603894920874.post-8759217314014849617</id><published>2024-08-12T15:00:00.000-07:00</published><updated>2024-08-12T15:00:00.109-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Computer-Security"/><category scheme="http://www.blogger.com/atom/ns#" term="Computer-Tech"/><category scheme="http://www.blogger.com/atom/ns#" term="Mac"/><category scheme="http://www.blogger.com/atom/ns#" term="Ubuntu-Linux"/><title type='text'>You can mount Linux Ext or LUKS disks on Mac, Windows!</title><content type='html'>&lt;p&gt;This is exciting! I’ve been looking for a disk format that works seamlessly across Mac, Windows, and Linux.&amp;nbsp; Something like a USB or disk image that mounts on all three desktop platforms.&lt;br /&gt;&lt;br /&gt;The obvious choice is exFAT, but what if I want a modern disk format with journaling for data safety?&lt;br /&gt;&lt;br /&gt;Ext4 is one option, although it used to be read-only on Macs (see &lt;a href=&quot;https://blog.carsoncheng.ca/2013/08/mounting-ext2ext3ext4-usb-flash-drives.html&quot; target=&quot;_blank&quot;&gt;Mounting Ext2/Ext3/Ext4 USB Flash Drives on Mac: Read Only Success&lt;/a&gt;). Maybe things have gotten better in the last 10 years?&lt;br /&gt;&lt;br /&gt;And what if I want disk encryption?&lt;br /&gt;&lt;br /&gt;VeraCrypt with an exFAT disk works: see &lt;a href=&quot;https://blog.carsoncheng.ca/2016/11/sharing-truecrypt-usb-volume-on-3.html&quot; target=&quot;_blank&quot;&gt;Sharing TrueCrypt USB volume on 3 platforms: Mac, Windows, Linux&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;But what if you want both encryption and a modern file system? I couldn&#39;t find a solution to this, until I found…&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;linsk&lt;/h2&gt;&lt;p&gt;In summary, &lt;a href=&quot;https://github.com/AlexSSD7/linsk/tree/master&quot; target=&quot;_blank&quot;&gt;linsk&lt;/a&gt; is an easy way to run an Alpine Linux VM using qemu to mount a disk within it, and then share that disk back out to your local host machine via a networking protocol.&lt;br /&gt;&lt;br /&gt;So now you can mount an Ext4 disk, or a LUKS encrypted Ext4 disk, on your Mac or Windows machine!&lt;br /&gt;&lt;br /&gt;The usage notes are so good, you can just look there for how to install and use.&lt;br /&gt;&lt;br /&gt;Here&#39;s a quick use reference, more for my own reference than anything&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;How to use linsk to mount a Ext4 disk within a LUKS encrypted disk on macOS&lt;/h2&gt;&lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; If you&#39;re not me, please read the &lt;a href=&quot;https://github.com/AlexSSD7/linsk/tree/master&quot; target=&quot;_blank&quot;&gt;linsk&lt;/a&gt; documentation first and understand it completely before proceeding below!&amp;nbsp; This assumes you installed linsk correctly, including qemu!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;1. With the disk plugged into your Mac, make sure to unmount all volumes that macOS auto-mounts!!!&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Warning Danger Caution Danger&lt;/b&gt;: If you don&#39;t unmount all volumes first, the following may delete, nuke, and destroy all your disk data.&amp;nbsp; macOS likes to repeatedly auto-mount any volume it sees, so after every step below, make sure to unmount those volumes again!!!&amp;nbsp; You&#39;ll see warnings to this effect from linsk in the terminal as well.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;2. In Terminal, run: $ diskutil list&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Find your disk and note its path: e.g. `/dev/diskX`&lt;br /&gt;&lt;br /&gt;The value of `X` in `diskX` may change every time your Mac encounter the disk!&lt;br /&gt;&lt;br /&gt;However, the LVM group/volume/luks-container names within that disk should be stable (unless intentionally changed), so in the future, you can skip down to the `linsk run` step 5 below if you&#39;re just re-mounting the same volume.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;3. Find the LUKS volume to mount within diskX.&amp;nbsp; Run: $ sudo linsk ls dev:/dev/diskX&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Note the `vda` drive you&#39;d see are the system drives within Alpine Linux, so ignore those.&lt;br /&gt;&lt;br /&gt;For this example, suppose: `vdb1` is the `crypto_LUKS` volume you&#39;re interested in.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;4. Find the Ext4 volume inside the LUKS volume by running: $ sudo linsk ls dev:/dev/diskX --luks-container vdb1&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Now suppose that `cryptcontainer` is the ext4 volume you want to mount.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;5. Mount the ext4 volume. Run: $ sudo linsk run dev:/dev/diskX --luks-container vdb1 mapper/cryptcontainer&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;6. Alternatively, mount the ext4 volume and open a debug shell.&amp;nbsp; Run: $ sudo linsk run --debug-shell dev:/dev/diskX --luks-container vdb1 mapper/cryptcontainer&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;This will mount that volume and open a shell within the Alpine Linux VM so you can do whatever you want to that disk volume from within Linux.&amp;nbsp; Good for changing disk ownership or permissions as needed so your Mac can access it.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;7. Mount the volume from macOS.&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;You can use Cmd+k to connect to the network volume that linsk / Alpine Linux sets up for you locally.&lt;br /&gt;&lt;br /&gt;You can also use the Mac Terminal.&amp;nbsp; Run: $ mount_afp -i -o noowners afp://linsk@127.0.0.1:9000/linsk /Path/to/mountpoint&lt;br /&gt;&lt;br /&gt;`sudo` is not needed and unhelpful here!&lt;br /&gt;&lt;br /&gt;You might find the folders in the mounted volume do not have the right permissions for you to open them up.&amp;nbsp; You might try using `sudo chown` or `chmod`, etc., and find they don&#39;t work to fix this.&amp;nbsp; You might try `umask` on your Mac, and find they don&#39;t work.&lt;br /&gt;&lt;br /&gt;If it&#39;s your own disk you want access to, you might as well just tell linsk to open up a debug shell into the Alpine Linux VM and change the permissions on the disk from there.&lt;br /&gt;&lt;br /&gt;i.e. Run: $ sudo linsk run --debug-shell dev:/dev/diskX --luks-container vdb1 mapper/cryptcontainer&lt;br /&gt;&lt;br /&gt;Then use the Linux chown/chmod tools as needed.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.carsoncheng.ca/feeds/8759217314014849617/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/713602603894920874/8759217314014849617' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/713602603894920874/posts/default/8759217314014849617'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/713602603894920874/posts/default/8759217314014849617'/><link rel='alternate' type='text/html' href='http://blog.carsoncheng.ca/2024/08/you-can-mount-linux-ext-or-luks-disks.html' title='You can mount Linux Ext or LUKS disks on Mac, Windows!'/><author><name>blogger</name><uri>http://www.blogger.com/profile/09586588053165570068</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-713602603894920874.post-2334827399873097346</id><published>2024-07-15T05:00:00.000-07:00</published><updated>2024-07-15T05:00:00.118-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Artificial-Intelligence"/><category scheme="http://www.blogger.com/atom/ns#" term="Business"/><category scheme="http://www.blogger.com/atom/ns#" term="Computer-Tech"/><category scheme="http://www.blogger.com/atom/ns#" term="Economics"/><title type='text'>Re: AI heatwave</title><content type='html'>&lt;p&gt;I’m trying to make sense of “The AI summer” [1].&lt;br /&gt;&lt;br /&gt;OpenAI’s ChatGPT had a meteoric rise in popularity not because the technology works (it does, for some reasonable definition of “works”) but rather the foundation is there for viral spread because:&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;blockquote&gt;&amp;gt; a lot of this is ‘standing on the shoulders of giants’ - OpenAI didn’t have to wait for people to buy devices or for telcos to build DSL or 3G&lt;br /&gt;&lt;br /&gt;&amp;gt; ChatGPT is just a website or an app, and … it could ride on all of the infrastructure we’ve built over the last 25 years. So a huge number of people went off to try it last year. &lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;But current AI’s problem is that no one knows what to do with it:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&amp;gt; The problem is that most of them haven’t been back. … most people played with it once or twice, or go back only every couple of weeks&lt;br /&gt;&lt;br /&gt;&amp;gt; On one hand, getting a quarter to a third of the developed world’s population to try a new product in 18 months is very hard. But on the other, most people who tried it didn’t see how it was useful.&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Current AI is more R&amp;amp;D than basic foundational research but it is still more R than D, and it’s still far from being COTS [3] products:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&amp;gt; Accenture … Last summer it proudly announced that it had already done $300m of ‘generative AI’ work for clients… and that it had done 300 projects. Even an LLM can divide 300 by 300 - that’s a lot of pilots, not deployment.&lt;br /&gt;&lt;br /&gt;&amp;gt; As a lot of people have now pointed out, all of that adds up to a stupefyingly large amount of capex (and a lot of other investment too) being pulled forward for a technology that’s mostly still only in the experimental budgets.&lt;br /&gt;&lt;br /&gt;&amp;gt; an LLM by itself is not a product - it’s a technology that can enable a tool or a feature, and it needs to be unbundled or rebundled into new framings, UX and tools to be become useful. That takes even more time.&lt;/blockquote&gt;&lt;p&gt;&lt;br /&gt;&lt;br /&gt;It took 8 years (to approx. June 2022) for cloud adoption to touch 25%. It took that long for cloud adoption expected-in-3-years to just pass 40% [2].&lt;/p&gt;&lt;p&gt;It took 2 more years and a pandemic (to approx. January 2024) for cloud adoption to get to about 30%. 
It took that long for cloud adoption expected-in-3-years to get near 50%:&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;blockquote&gt;&amp;gt; If you work in tech, cloud is old and boring and done, but it’s still only a third or so of enterprise workflows&lt;br /&gt;&lt;br /&gt;&amp;gt; it took more than 20 years for 20% of US retail to move online&lt;/blockquote&gt;&lt;p&gt;&lt;br /&gt;&lt;br /&gt;Gen AI and LLMs are here to stay but it’ll still take many years to decades for it to spread everywhere and displace existing technologies and labor.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;br /&gt;[1]: &lt;a href=&quot;https://www.ben-evans.com/benedictevans/2024/7/9/the-ai-summer&quot;&gt;https://www.ben-evans.com/benedictevans/2024/7/9/the-ai-summer&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;[2]: &lt;a href=&quot;https://www.ben-evans.com/benedictevans/2023/7/2/working-with-ai&quot;&gt;https://www.ben-evans.com/benedictevans/2023/7/2/working-with-ai&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;[3]: &lt;a href=&quot;https://en.wikipedia.org/wiki/Commercial_off-the-shelf&quot;&gt;https://en.wikipedia.org/wiki/Commercial_off-the-shelf&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.carsoncheng.ca/feeds/2334827399873097346/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/713602603894920874/2334827399873097346' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/713602603894920874/posts/default/2334827399873097346'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/713602603894920874/posts/default/2334827399873097346'/><link rel='alternate' type='text/html' href='http://blog.carsoncheng.ca/2024/07/re-ai-heatwave.html' title='Re: AI heatwave'/><author><name>blogger</name><uri>http://www.blogger.com/profile/09586588053165570068</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-713602603894920874.post-426789573889811732</id><published>2024-07-12T14:30:00.000-07:00</published><updated>2024-07-15T13:42:27.735-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Artificial-Intelligence"/><category scheme="http://www.blogger.com/atom/ns#" term="Business"/><category scheme="http://www.blogger.com/atom/ns#" term="Computer-Tech"/><category scheme="http://www.blogger.com/atom/ns#" term="Economics"/><category scheme="http://www.blogger.com/atom/ns#" term="Finance"/><title type='text'>RE: $500B AI revenue expectations gap</title><content type='html'>&lt;div style=&quot;text-align: left;&quot;&gt;They say there is a $500B &quot;gap between the revenue expectations implied by the AI infrastructure build-out, and actual revenue growth in the AI ecosystem&quot; [1].&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;h1 style=&quot;text-align: left;&quot;&gt;Part 1&lt;/h1&gt;&lt;div style=&quot;text-align: left;&quot;&gt;&lt;br /&gt;Given the business that Sequoia Cap is in, it should not be surprising that they’d say things like:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&amp;gt; Investment incineration… a lot of people lose a lot of money during speculative technology waves. It’s hard to pick winners, but much easier to pick losers&lt;br /&gt;&lt;br /&gt;&amp;gt; Winners vs. losers… there are always winners during periods of excess infrastructure building. AI is likely to be the next transformative technology wave… lt will cause harm primarily to investors. &lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;i.e. invest right and you’d capture a huge amount of value. Invest wrong and you’d be burning your money. So do investments with us.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;h1 style=&quot;text-align: left;&quot;&gt;Part 2&lt;/h1&gt;&lt;div style=&quot;text-align: left;&quot;&gt;&lt;br /&gt;What I found interesting is the point about there being a:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&amp;gt; $500B … gap between the revenue expectations [$600B] implied by the AI infrastructure build-out, and actual revenue growth in the AI ecosystem [$100B] … that needs to be filled for each year of CapEx at today’s levels [GPU $150B, “Data Center Facility Build and Cost to Operate” $150B (they seem to have included OpEx in their “CapEx” figure)]&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;This means there’s either some amazing AI killer apps that will make $500B in sales or some AI investments will get incinerated.&lt;br /&gt;&lt;br /&gt;Investment incineration &quot;will cause harm primarily to investors&quot; [1] — Nvidia, the data center builders, facility operators, and power companies will all have gotten paid for the work they will do — but I wonder what are the broader implications of the $500B revenue expectations gap.&lt;br /&gt;&lt;br /&gt;Is it — the investments, not necessarily the GPT/LLM tech — irrational exuberance?&amp;nbsp; How much of today’s Big Tech valuation is driven by it?&amp;nbsp; How sensitive is it to interest rates?&amp;nbsp; Notice this &quot;bubble&quot;, if it is one, is not occurring during a ZIRP [3] period.&lt;br /&gt;&lt;br /&gt;It seems AI startups aren’t the ones building AI data centers — &quot;much of the incremental data center build-out is coming from big tech companies&quot; [2].&amp;nbsp; So startups seem less affected by that cost.&lt;br /&gt;&lt;br /&gt;But actually 50% of the $500B revenue expectations gap is “software margin” — that’s the margin earned by “The end user of the GPU—for example, Starbucks, X, Tesla, Github Copilot or a new startup” [2].&lt;br /&gt;&lt;br /&gt;Which means when some of the $500B expected revenue doesn’t show up, it’ll be hitting the AI startups&#39; margins.&lt;br /&gt;&lt;br /&gt;Now remember the other 50% is “CapEx”: Nvidia GPU, and “Data Center Facility Build and Cost to Operate”.&amp;nbsp; And remember that Nvidia, the data center builders, facility operators, and power companies will all have gotten paid for the work they will do — because they don’t work for free or for startups&#39; equity.&amp;nbsp; So it seems they won’t have their margins squeezed.&lt;br /&gt;&lt;br /&gt;But doesn’t that also mean when some of the $500B expected revenue doesn’t show up, it’ll be hitting the Big Tech AI data center’s top line?&lt;br /&gt;&lt;br /&gt;I don&#39;t know enough to know what will happen, but it seems some amount of AI Investment cooling will hit AI startups and Big Tech&#39;s AI data center buildout.&amp;nbsp; Big Tech has been and remains profitable, and their GPUs are paid for, so it&#39;ll mainly change their product priorities and revenue forecasts (and thus stock price?).&amp;nbsp; AI startups, however...&lt;br /&gt;&lt;br /&gt;But perhaps, just in time, the Fed&#39;s interest rates will go down for unrelated reasons.&lt;br /&gt;&lt;br /&gt;[1]: https://www.sequoiacap.com/article/ais-600b-question/&lt;br /&gt;[2]: https://www.sequoiacap.com/article/follow-the-gpus-perspective/&lt;br /&gt;[3]: https://en.wikipedia.org/wiki/Zero_interest-rate_policy&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.carsoncheng.ca/feeds/426789573889811732/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/713602603894920874/426789573889811732' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/713602603894920874/posts/default/426789573889811732'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/713602603894920874/posts/default/426789573889811732'/><link rel='alternate' type='text/html' href='http://blog.carsoncheng.ca/2024/07/re-500b-ai-revenue-expectations-gap.html' title='RE: $500B AI revenue expectations gap'/><author><name>blogger</name><uri>http://www.blogger.com/profile/09586588053165570068</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-713602603894920874.post-6381225878088673980</id><published>2024-03-30T15:30:00.000-07:00</published><updated>2024-03-30T15:33:19.795-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Artificial-Intelligence"/><category scheme="http://www.blogger.com/atom/ns#" term="Computer-Tech"/><category scheme="http://www.blogger.com/atom/ns#" term="Philosophy"/><title type='text'>Standard Disclaimer to AI, etc.</title><content type='html'>&lt;p&gt;Attention All: This content is the product of human creativity and is 
intended for human consumption and reflection. Using this content for 
learning, training, inference,  or any other purpose without explicit 
permission undermines ethical standards in AI use.  Furthermore, unless 
otherwise required, this content has All Rights Reserved.  Your 
compliance is required to respect the integrity of human-created content
 and uphold ethical principles in AI research, development, and 
deployment.&lt;/p&gt;&lt;p&gt;&quot;This content&quot; here means everything past, present, and future on this web site.&lt;/p&gt;&lt;p&gt;You may ask: why don&#39;t you use &lt;a href=&quot;https://www.eff.org/deeplinks/2023/12/no-robotstxt-how-ask-chatgpt-and-google-bard-not-use-your-website-training&quot;&gt;robots.txt&lt;/a&gt; (EFF)?&lt;/p&gt;&lt;p&gt;Because only Google and OpenAI has promised to respect that moving forwards.&amp;nbsp; It&#39;s not universal to all AI, LLM, bots, etc.&amp;nbsp; Also, given they only made that promise after having crawled and created their vast datasets for their own AI training, isn&#39;t it incredibly convenient for them to then say everyone should respect robots.txt in regards AI dataset creation?&lt;/p&gt;&lt;p&gt;If AI ever becomes intelligent enough, it seems only reasonable to appeal to ethics to request the data here not be used.&lt;/p&gt;&lt;p&gt;But for completeness, I intend the robots.txt for this web site to be:&lt;/p&gt;&lt;p&gt;User-agent: GPTBot&lt;br /&gt;Disallow: /&lt;br /&gt;User-agent: Google-Extended&lt;br /&gt;Disallow: /&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.carsoncheng.ca/feeds/6381225878088673980/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/713602603894920874/6381225878088673980' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/713602603894920874/posts/default/6381225878088673980'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/713602603894920874/posts/default/6381225878088673980'/><link rel='alternate' type='text/html' href='http://blog.carsoncheng.ca/2024/03/standard-disclaimer-to-ai-etc.html' title='Standard Disclaimer to AI, etc.'/><author><name>blogger</name><uri>http://www.blogger.com/profile/09586588053165570068</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-713602603894920874.post-8598881675163302936</id><published>2022-05-09T08:00:00.001-07:00</published><updated>2022-05-09T08:00:00.159-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Clojure"/><category scheme="http://www.blogger.com/atom/ns#" term="Computing-Science"/><category scheme="http://www.blogger.com/atom/ns#" term="JavaScript"/><category scheme="http://www.blogger.com/atom/ns#" term="Programming"/><title type='text'>Trampolines - fun way to make recursion not stack overflow</title><content type='html'>&lt;p&gt;(We&#39;ll use JavaScript for today, running in the Firefox developer console.) &lt;br /&gt;&lt;/p&gt;&lt;p&gt;No doubt when you learned recursion, you learned that each recursive function call uses stack space to do its work.&amp;nbsp; There&#39;s only so much stack space.&amp;nbsp; So unless your programming language has a special feature (called tail call elimination), a recursive function can eventually exhaust all stack space, leading to the famous stack overflow error (not the web site). &lt;/p&gt;&lt;p&gt;For example, let&#39;s write a loop to sum up numbers from 0 up to some &lt;i&gt;N&lt;/i&gt; like this:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;let sum = 0;
for (let i = 0; i &amp;lt; 10000; ++i) sum += i;
console.log(sum); // prints: 49995000&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now a recursive version might look like this:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;const loop = function(i, sum){
  if (i &amp;lt; 10000){
    sum += i;
    return loop(i + 1, sum);
  } else {
    return sum;
  }
};
console.log(loop(0, 0)); // prints: 49995000&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;As you can see, a loop is just a recursive function call.&lt;/p&gt;&lt;p&gt;The above is a nice, simple demo of converting a loop to recursion.&amp;nbsp; But if instead of summing up to 10,000, we sum up to 100,000, then the loop prints 4999950000.&amp;nbsp; But the recursive function prints:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;code&gt;Uncaught InternalError: too much recursion&lt;/code&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;With a link to: &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Too_much_recursion&quot;&gt;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Too_much_recursion&lt;/a&gt; &lt;/p&gt;&lt;p&gt;&lt;b&gt;Trampolines&lt;/b&gt;&lt;/p&gt;&lt;p&gt;No surprise, like the title says, trampolines can fix this!&lt;/p&gt;&lt;p&gt;The key is to not allow the &lt;i&gt;loop&lt;/i&gt; function to run &lt;i&gt;loop(i + 1, sum)&lt;/i&gt;, because that&#39;d consume stack space!&amp;nbsp; Instead, the &lt;i&gt;loop&lt;/i&gt; function will &lt;i&gt;return&lt;/i&gt; a function called a &lt;i&gt;thunk&lt;/i&gt;.&amp;nbsp; That thunk function, when run, will run and return &lt;i&gt;loop(i + 1, sum)&lt;/i&gt;.&amp;nbsp; This also means a thunk can return a thunk!&lt;br /&gt;&lt;/p&gt;&lt;p&gt;The function that runs &lt;i&gt;loop&lt;/i&gt;, and any thunk functions, is called a &lt;i&gt;trampoline&lt;/i&gt;.&amp;nbsp; That&#39;s because the thunk function the trampoline runs may return a thunk, and if so, that thunk will get run too.&amp;nbsp; The thunks keep bouncing off of the trampoline function.&amp;nbsp; Until one day a thunk returns a value instead of a thunk!&amp;nbsp; Then the trampoline&#39;s job is done, and that value is returned.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Because the thunk itself only ever uses a single &quot;frame&quot; of space on the stack, rather than recursively using more and more stack space with recursive function calls, and so the stack overflow error is avoided.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;Here&#39;s how the code will look:&lt;br /&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;const loop = function(i, sum){
  if (i &amp;lt; 100000){
    sum += i;
    let thunk = ()=&amp;gt;{return loop(i + 1, sum)};
    return thunk; // rather than returning loop(i + 1, sum)
  } else {
    return sum;
  }
};
 

const trampoline = function(){
  let tv = loop(0, 0);
  while (typeof tv === &#39;function&#39;){
    tv = tv(); // returns either a thunk function or a value
  }
  return tv;
};
 

console.log(trampoline()); // prints: 4999950000
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Trampolines running thunk-returning thunk functions is a generic technique that&#39;s applicable in other languages and situations too!&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Tail Call Elimination: no need for trampolines&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;If your programming language has full support for an optimization called Tail Call Elimination, the above trampoline technique is completely unnecessary.&lt;/p&gt;&lt;p&gt;It turns out JavaScript at one point had this optimization planned.&amp;nbsp; It was to be an &quot;invisible&quot; opportunistic tail call optimization (TCO).&amp;nbsp; Meaning that if you correctly wrote a proper recursive function call in tail position, then TCO would kick in, and it wouldn&#39;t consume stack space (thus no stack overflow).&lt;/p&gt;&lt;p&gt;TCO is currently only available on Apple&#39;s Safari browser and on iOS [1].&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Google&#39;s V8 team apparently came to the conclusion that TCO makes the wrong tradeoff.&amp;nbsp; Because it&#39;s an opportunistic optimization, it&#39;s very easy for a programmer to write code they think would get TCO, but actually won&#39;t, and it can be very difficult to discover the error during testing.&amp;nbsp; They advocated for an explicit syntactic way to designate a recursive function call as requiring tail call elimination.&amp;nbsp; But... well, it all fell by the wayside and was never picked back up [2].&lt;/p&gt;&lt;p&gt;Interestingly, the Clojure programming language&#39;s creator, Rich Hickey, basically made the same argument.&amp;nbsp; In Clojure, recursive function calls requiring TCO must be written explicitly with a &lt;i&gt;recur&lt;/i&gt; syntax.&amp;nbsp; In that case, no trampoline is needed, and the recursive function call won&#39;t overflow the stack.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;[1] &lt;a href=&quot;https://kangax.github.io/compat-table/es6/&quot;&gt;https://kangax.github.io/compat-table/es6/&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;[2] &lt;a href=&quot;https://stackoverflow.com/a/42788286&quot;&gt;https://stackoverflow.com/a/42788286&lt;/a&gt; &lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.carsoncheng.ca/feeds/8598881675163302936/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/713602603894920874/8598881675163302936' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/713602603894920874/posts/default/8598881675163302936'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/713602603894920874/posts/default/8598881675163302936'/><link rel='alternate' type='text/html' href='http://blog.carsoncheng.ca/2022/05/trampolines-fun-way-to-make-recursion.html' title='Trampolines - fun way to make recursion not stack overflow'/><author><name>blogger</name><uri>http://www.blogger.com/profile/09586588053165570068</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-713602603894920874.post-4627164262253906869</id><published>2022-05-02T08:00:00.007-07:00</published><updated>2022-05-02T08:00:00.177-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Computer-Tech"/><category scheme="http://www.blogger.com/atom/ns#" term="Firefox"/><category scheme="http://www.blogger.com/atom/ns#" term="iOS"/><title type='text'>Firefox Focus - weird but good, standalone mobile browser and ad blocker</title><content type='html'>&lt;p&gt;The best ad blocker around (uBlock Origin [0]) is not available on iPhone iOS.&amp;nbsp; That&#39;s essentially because Firefox and other browsers on iOS do not have the ability to load plugins as sophisticated as uBlock Origin.&lt;/p&gt;&lt;p&gt;A good substitute is Firefox Focus [1].&amp;nbsp; It&#39;s a content blocker on iOS, and can be set up that way so that Focus will block ads from showing when you use Safari!&lt;/p&gt;&lt;p&gt;A weird thing though is that Focus will not block ads on the main Firefox browser.&amp;nbsp; Again, something to do with iOS restrictions on iPhones.&lt;/p&gt;&lt;p&gt;That&#39;s ok, because &lt;a href=&quot;https://blog.carsoncheng.ca/2022/04/ad-blocking-in-firefox-on-iphone-ios.html&quot;&gt;Firefox has ad blocking built in&lt;/a&gt; (though as an obscure feature).&lt;/p&gt;&lt;p&gt;Another weird thing is that Firefox Focus also functions as a weird mobile web browser.&amp;nbsp; Weird because although Focus is &quot;Firefox&quot; branded, it doesn&#39;t have any of the account and password syncing features of the actual Firefox browser.&lt;/p&gt;&lt;p&gt;Oh, and Focus doesn&#39;t have tabs.&amp;nbsp; You literally have to focus on one web page at a time.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;[0] &lt;a href=&quot;https://github.com/gorhill/uBlock&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;https://github.com/gorhill/uBlock&lt;/a&gt; &lt;br /&gt;&lt;/p&gt;&lt;p&gt;[1] &lt;a href=&quot;https://en.wikipedia.org/wiki/Firefox_Focus&quot;&gt;https://en.wikipedia.org/wiki/Firefox_Focus&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.carsoncheng.ca/feeds/4627164262253906869/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/713602603894920874/4627164262253906869' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/713602603894920874/posts/default/4627164262253906869'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/713602603894920874/posts/default/4627164262253906869'/><link rel='alternate' type='text/html' href='http://blog.carsoncheng.ca/2022/05/firefox-focus-weird-but-good-standalone.html' title='Firefox Focus - weird but good, standalone mobile browser and ad blocker'/><author><name>blogger</name><uri>http://www.blogger.com/profile/09586588053165570068</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-713602603894920874.post-6045698890002962081</id><published>2022-04-25T08:30:00.001-07:00</published><updated>2022-04-25T08:30:00.152-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Computer-Tech"/><category scheme="http://www.blogger.com/atom/ns#" term="Firefox"/><category scheme="http://www.blogger.com/atom/ns#" term="iOS"/><title type='text'>Ad blocking in Firefox on iPhone iOS</title><content type='html'>&lt;p&gt;uBlock Origin [0] is a plugin for the best ad blocking available, and 
it&#39;s available for Firefox on Android, Windows, Mac, and Linux.&lt;br /&gt;&lt;br /&gt;However, Firefox on iPhone iOS (FF-iOS) does not have any plug-in support, so uBlock Origin is not available for it.&lt;br /&gt;&lt;br /&gt;FF-iOS
 doesn&#39;t support plug-ins apparently because it&#39;s actually using 
Safari&#39;s rendering engine underneath (a choice forced by Apple, 
apparently).&lt;br /&gt;&lt;br /&gt;&lt;b&gt;What to do about ad blocking in FF-iOS then?&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Turns
 out &lt;b&gt;FF-iOS has ad blocking built-in&lt;/b&gt;! You just need to go into 
&quot;Settings&quot; &amp;gt; &quot;Tracking Protection&quot;. Then enable &quot;Enhanced Tracking 
Protection&quot;, and set &quot;Protection Level&quot; to &quot;Strict&quot;.&lt;br /&gt;&lt;br /&gt;This feature is frustratingly [1][2] not well publicized [3]!&lt;br /&gt;&lt;br /&gt;Another
 very popular plug-in is &quot;dark mode&quot;, and that too is built into FF-iOS!
  It&#39;s very prominently publicized in the app&#39;s &quot;more&quot; menu though.&lt;br /&gt;&lt;br /&gt;[0] &lt;a href=&quot;https://github.com/gorhill/uBlock&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;https://github.com/gorhill/uBlock&lt;/a&gt;&lt;br /&gt;[1] &lt;a href=&quot;https://www.reddit.com/r/firefox/comments/jwi1r9/firefox_ios_should_integrate_with_ublock_to_make/&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;https://www.reddit.com/r/firefox/comments/jwi1r9/firefox_ios_should_integrate_with_ublock_to_make/&lt;/a&gt;&lt;br /&gt;[2] &lt;a href=&quot;https://www.reddit.com/r/firefox/comments/n9jfui/firefox_ios_and_lack_of_content_blockers/&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;https://www.reddit.com/r/firefox/comments/n9jfui/firefox_ios_and_lack_of_content_blockers/&lt;/a&gt;&lt;br /&gt;[3] &lt;a href=&quot;https://github.com/mozilla-mobile/firefox-ios/issues/5198#issuecomment-575617840&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;https://github.com/mozilla-mobile/firefox-ios/issues/5198#issuecomment-575617840&lt;/a&gt;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.carsoncheng.ca/feeds/6045698890002962081/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/713602603894920874/6045698890002962081' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/713602603894920874/posts/default/6045698890002962081'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/713602603894920874/posts/default/6045698890002962081'/><link rel='alternate' type='text/html' href='http://blog.carsoncheng.ca/2022/04/ad-blocking-in-firefox-on-iphone-ios.html' title='Ad blocking in Firefox on iPhone iOS'/><author><name>blogger</name><uri>http://www.blogger.com/profile/09586588053165570068</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-713602603894920874.post-8461886894225426933</id><published>2021-04-28T17:44:00.001-07:00</published><updated>2021-04-28T17:44:00.245-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Mental-Note"/><category scheme="http://www.blogger.com/atom/ns#" term="Programming"/><category scheme="http://www.blogger.com/atom/ns#" term="Web-Development"/><title type='text'>Programming Language Notes 2021 - multiplatform, GUIs</title><content type='html'>&lt;p&gt;&lt;i&gt;These are &lt;b&gt;incomplete&lt;/b&gt; notes and thoughts on programming languages through lens of multiplatform support and coding GUI apps for platforms like Android, iOS, Mac, Windows, Linux, and web (front and back ends).&lt;br /&gt;&lt;/i&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;JavaScript&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Lack type safety.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Java, Go, &lt;/b&gt;&lt;b&gt;&lt;b&gt;Python, Ruby, C++, C, &lt;/b&gt;&lt;/b&gt;&lt;b&gt;&lt;b&gt;Elixir&lt;/b&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Not great for frontend web dev.&lt;/p&gt;&lt;p&gt;&lt;b&gt;D&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Not great for Android or iOS. &amp;nbsp; Can build web apps via compiling to WASM (pretty sure it&#39;s experimental), but lack mature frameworks for frontend web dev.&amp;nbsp; Not very popularly used, unfortunately.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;TypeScript&lt;/b&gt;&lt;/p&gt;&lt;p&gt;It&#39;s JavaScript but with a brilliant aftermarket type system retrofit. If you must code JS, then TS is a fantastic upgrade.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;For backend, there&#39;s faster languages (Java, Go).&amp;nbsp; For device native apps, other languages are maybe better suited (Swift, Kotlin, etc).&amp;nbsp; Great choice for web frontend.&lt;/p&gt;&lt;p&gt;For frontend web dev, used with React is popular.&amp;nbsp; There&#39;s React Native to build device native apps for Macs, Windows, Linux, Android, and iOS that uses platform native UI widgets (some haven&#39;t reached 1.0 yet though, if you&#39;re looking for maturity).&amp;nbsp; You&#39;d still have to build 5 specialized UIs though (6 including web), and there are faster device native languages.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Kotlin&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Compiles to JVM, JS, and native.&amp;nbsp; &lt;a href=&quot;https://kotlinlang.org/docs/multiplatform.html&quot; target=&quot;_blank&quot;&gt;Kotlin Multiplatform&lt;/a&gt; Mobile (alpha) is great for write-once application logic for iOS / Android native apps, but the UI code must be specialized for each platform (could still be written in Kotlin though).&lt;/p&gt;&lt;p&gt;e.g. Use with Google Android&#39;s Jetpack Compose (beta) and Apple&#39;s Swift UI for native Android and iOS UI.&lt;/p&gt;&lt;p&gt;e.g. Use with Jetbrains&#39; &lt;a href=&quot;https://www.jetbrains.com/lp/compose/&quot; target=&quot;_blank&quot;&gt;Compose for Desktop&lt;/a&gt; to build apps for Windows, Macs, and Linux --- but this&amp;nbsp; runs on JVM and renders using Skia, so it doesn&#39;t use platform native UI widgets (it draws it&#39;s own like a game does).&amp;nbsp; And it&#39;s in alpha.&lt;/p&gt;&lt;p&gt;Some say Jetpack Compose is Google Android team&#39;s answer to Google Ads team&#39;s Dart/Flutter. &lt;br /&gt;&lt;/p&gt;&lt;p&gt;Kotlin/JS means you can use with React for frontend web dev too.&amp;nbsp; Not sure of its maturity.&amp;nbsp; Kotlin is great for backend using Spring or Ktor.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;PHP&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Not great for device native apps&lt;/p&gt;&lt;p&gt;&lt;b&gt;C#&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Windows centric.&amp;nbsp; Blazor lets you do frontend web dev by compiling to WASM but it adds C#&#39;s runtime to your web app to run in WASM as well (read: bigger, slower app).&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Rust&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Lower level, like C or C++.&amp;nbsp; Can build web apps via compiling to WASM, but without bringing a runtime along for the ride (check out Yew or Seed).&amp;nbsp; Can build backend stuff (check out Actix-web or Rocket), but frameworks aren&#39;t mature the way Django or RoR are.&lt;/p&gt;&lt;p&gt;Coding device native GUI apps is... &lt;a href=&quot;https://www.areweguiyet.com/&quot; target=&quot;_blank&quot;&gt;not there yet&lt;/a&gt;.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Rust is getting a lot of traction for systems programming though (unlike D, unfortunately).&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Dart&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Basically exists for Flutter.&amp;nbsp; Flutter lets you build apps for Windows, Macs, Linux, iOS, Android, and the web.&amp;nbsp; On the web, it draws into a canvas.&amp;nbsp; On devices, it renders using Skia.&amp;nbsp; So it doesn&#39;t use platform native UI widgets anywhere, and draws it&#39;s own like a game does.&amp;nbsp; On the web, it&#39;s UI performance is a little janky.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Dart compiles to JS or runs on Dart VM.&amp;nbsp; Unlike the Kotlin stuff above, Flutter is production ready and being used by Google, notably by their Ads team (apparently some of the Kotlin stuff above are the Android team&#39;s answer to Flutter).&lt;br /&gt;&lt;/p&gt;&lt;p&gt;It&#39;s from Google, so who knows if they&#39;ll cancel it in 5 years time.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;u&gt;Other thoughts&lt;/u&gt;&lt;/b&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Rendering to Skia like Compose for Desktop and Flutter is not great for accessibility, and their accessibility features are currently WIP.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;React Native has edge cases for each platform so you&#39;d still need to know each platform carefully.&amp;nbsp; Plus TypeScript / JavaScript bridging into native can have performance issues.&lt;/p&gt;&lt;p&gt;&amp;nbsp;Nothing&#39;s perfect.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;i&gt;That&#39;s all I&#39;ve got time for today!&lt;/i&gt;&lt;/p&gt;&lt;p&gt;&lt;i&gt;Missing: Scala, Clojure, Haskell, F#, Crystal, PureScript, Elm.&lt;/i&gt;&lt;br /&gt;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.carsoncheng.ca/feeds/8461886894225426933/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/713602603894920874/8461886894225426933' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/713602603894920874/posts/default/8461886894225426933'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/713602603894920874/posts/default/8461886894225426933'/><link rel='alternate' type='text/html' href='http://blog.carsoncheng.ca/2021/04/programming-language-notes-2021.html' title='Programming Language Notes 2021 - multiplatform, GUIs'/><author><name>blogger</name><uri>http://www.blogger.com/profile/09586588053165570068</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-713602603894920874.post-4565809205678789437</id><published>2021-03-25T20:54:00.286-07:00</published><updated>2021-03-25T20:54:00.722-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Computer-Tech"/><category scheme="http://www.blogger.com/atom/ns#" term="Debian-Linux"/><category scheme="http://www.blogger.com/atom/ns#" term="Firefox"/><category scheme="http://www.blogger.com/atom/ns#" term="Mac"/><title type='text'>Use ISO 8601 dates in PCManFM on Debian LXQt</title><content type='html'>&lt;p&gt;I like &lt;a href=&quot;https://en.wikipedia.org/wiki/ISO_8601&quot; target=&quot;_blank&quot;&gt;ISO 8601&lt;/a&gt; or RFC 3339 style dates.&amp;nbsp; That is, rather than &quot;January 15, 2021&quot;, I like &quot;2021-01-15&quot;.&lt;/p&gt;&lt;p&gt;This is especially useful in a file manager, having all the year-month-day lined up vertically in a column.&lt;/p&gt;&lt;p&gt;I also prefer 24-hr time format for the same reason.&amp;nbsp; But how to set this up?&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;u&gt;&lt;b&gt;macOS Finder&lt;/b&gt;&lt;/u&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;For Mac&#39;s file manager, it&#39;s really easy to set the date/time format:&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Just open &lt;i&gt;&lt;b&gt;System Preferences&lt;/b&gt;&lt;/i&gt; &amp;gt; &lt;i&gt;&lt;b&gt;Language 
&amp;amp; Region&lt;/b&gt;&lt;/i&gt; &amp;gt; &lt;i&gt;&lt;b&gt;Advanced&lt;/b&gt;&lt;/i&gt; &amp;gt; &lt;i&gt;&lt;b&gt;Dates&lt;/b&gt;&lt;/i&gt;, then modify the date formats to 
whatever you want.&amp;nbsp; At the same time, you could go to the &lt;i&gt;&lt;b&gt;Times&lt;/b&gt;&lt;/i&gt; tab and 
set it to use 24-hr format.&amp;nbsp;&lt;/p&gt;&lt;p&gt;Done!&amp;nbsp; I offer this as just a point of comparison for what&#39;s below... &lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;u&gt;&lt;b&gt;Debian LXQt PCManFM&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;&lt;p&gt;On LXQt&#39;s PCManFM file manager, running on Debian, the setup was... annoyingly difficult.&lt;/p&gt;&lt;p&gt;PCManFM does not allow custom date/time formatting.&amp;nbsp; It only respects the system set &lt;i&gt;locale&lt;/i&gt;.&amp;nbsp; So you have to choose the right locale.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Step 1.1: Select Locale&lt;/b&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;On LXQt, you can easily set the locale (they call it &quot;Region&quot;) by running &lt;b&gt;&lt;i&gt;lxqt-config-locale&lt;/i&gt;&lt;/b&gt; in the terminal, or else click the system &lt;i&gt;&lt;b&gt;Preferences&lt;/b&gt;&lt;/i&gt; &amp;gt; &lt;i&gt;&lt;b&gt;LXQt settings&lt;/b&gt;&lt;/i&gt; &amp;gt; &lt;i&gt;&lt;b&gt;Locale&lt;/b&gt;&lt;/i&gt;.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Step 1.2: Which locale to choose???&lt;/b&gt;&lt;/p&gt;&lt;p&gt;You have a number of options.&lt;/p&gt;&lt;p&gt;Do you want:&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;English language&lt;/li&gt;&lt;li&gt;dollar denominated&lt;/li&gt;&lt;li&gt;metric&lt;/li&gt;&lt;li&gt;ISO-8601&lt;/li&gt;&lt;li&gt;but 12-hr time?&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Use &lt;b&gt;Canadian English&lt;/b&gt; (en_CA) locale.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;If that&#39;s not close enough, and you &lt;i&gt;really&lt;/i&gt; want 24-hr time as well, you can enable &lt;b&gt;&lt;i&gt;Detailed Settings&lt;/i&gt;&lt;/b&gt; and change the &lt;b&gt;&lt;i&gt;Time&lt;/i&gt;&lt;/b&gt; locale to &lt;b&gt;Sweden - English&lt;/b&gt; (en_SE).&lt;/p&gt;&lt;p&gt;Be sure to see &lt;b&gt;Step 2: Installing Locales in Debian&lt;/b&gt;, because chances are doing the above will cause system errors  later!&lt;/p&gt;&lt;p&gt;Note that en_CA uses Canadian dollars, not USD!&amp;nbsp; You can change the &lt;b&gt;&lt;i&gt;Currency&lt;/i&gt;&lt;/b&gt; locale to &lt;b&gt;American English&lt;/b&gt; (en_US) if you want &lt;i&gt;real&lt;/i&gt; USD dollars.&amp;nbsp; Although it probably doesn&#39;t matter for formatting purposes.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Why Sweden?&amp;nbsp; It turns out lots of Europeans want something similar, as in a locale that is English language, metric, using ISO-8601 or similar style dates!&lt;/p&gt;&lt;p&gt;Sweden - English is an unofficial locale made up to give us that [1], but it does use Swedish 
kronor SEK for currency [2].&amp;nbsp; That&#39;s why you &lt;i&gt;only&lt;/i&gt; want to set the &lt;b&gt;&lt;i&gt;Time&lt;/i&gt;&lt;/b&gt; locale to use en_SE, keeping the rest as en_CA (or en_US).&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Step 2: Installing Locales in Debian&lt;/b&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Selecting the &quot;Region&quot; in LXQt&#39;s &lt;i&gt;locale &lt;/i&gt;preference app is just half the story.&lt;/p&gt;&lt;p&gt;PCManFM will probably work fine as is.&amp;nbsp; Qt apps are fine because it uses it&#39;s own Qt locale definition lookup system, and includes en_CA and en_SE by default.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Debian does &lt;b&gt;&lt;i&gt;not&lt;/i&gt;&lt;/b&gt; include en_CA by default, so you&#39;ll have to install it.&amp;nbsp; And it does &lt;b&gt;&lt;i&gt;not&lt;/i&gt;&lt;/b&gt; have en_SE... not at all... you&#39;ll have to add the en_SE definition file manually then install it.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;You can download a copy of the &lt;a href=&quot;http://www.stacken.kth.se/~auno/en_SE&quot; target=&quot;_blank&quot;&gt;en_SE locale definition&lt;/a&gt; written by Mikael Auno [7].&amp;nbsp; Then create this directory if it doesn&#39;t exist:&lt;/p&gt;&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;/usr/local/share/i18n/locales&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;Place the &lt;code&gt;en_SE&lt;/code&gt; file into the above &lt;code&gt;locales&lt;/code&gt; directory.&amp;nbsp; Create a text file in the above &lt;code&gt;i18n&lt;/code&gt; directory containing this text:&lt;br /&gt;&lt;br /&gt; &lt;code&gt;en_SE.UTF-8 UTF-8&lt;/code&gt;&lt;/p&gt;&lt;p&gt;Then run in terminal:&lt;br /&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;$ sudo dpkg-reconfigure locales&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You should see a list of locales you can install.&amp;nbsp; Look for and install the ones you selected in LXQt&#39;s &lt;i&gt;locale &lt;/i&gt;preference app.&amp;nbsp; For my example above, that means en_CA, en_US, and en_SE.&lt;/p&gt;&lt;p&gt;Lastly, logout and re-login for the changes to take effect.&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;u&gt;&lt;b&gt;Fully Custom Locales in Debian: don&#39;t bother&lt;br /&gt;&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;&lt;p&gt;From above, you see Debian allows you to create totally custom locales, so you can customize all the formats the way Macs can!&amp;nbsp; After all, that &lt;code&gt;en_SE&lt;/code&gt; locale file you downloaded was just &lt;i&gt;made up&lt;/i&gt; so to speak, and you can customize it however you want.&lt;/p&gt;&lt;p&gt;...but Qt won&#39;t use it.&amp;nbsp; Qt&#39;s locale system runs parallel to Debian Linux&#39;s.&lt;/p&gt;&lt;p&gt;So why go through the trouble of installing the en_SE locale if Qt won&#39;t use it?&amp;nbsp; Because if you don&#39;t, you&#39;ll run into problems with non-Qt apps, problems like:&lt;/p&gt;&lt;p&gt;Run &lt;code&gt;locale&lt;/code&gt; in the terminal, and it&#39;ll complain:&lt;/p&gt;&lt;p style=&quot;margin-left: 40px; text-align: left;&quot;&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;locale: Cannot set LC_MESSAGES to default locale: No such file or directory&lt;br /&gt;locale: Cannot set LC_ALL to default locale: No such file or directory&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;Unzip certain archives using &lt;code&gt;file-roller&lt;/code&gt; results in a dialog box complaining:&lt;/p&gt;&lt;p style=&quot;margin-left: 40px; text-align: left;&quot;&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;An error occurred while extracting files.&lt;br /&gt;Pathname can&#39;t be converted from UTF-8 to current locale.&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;That occurs because a locale you chose in LXQt was not installed in Debian [8].&amp;nbsp; Qt is perfectly happy though, as it runs a separate locale system...&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;u&gt;&lt;b&gt;Firefox locale incompatibility&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;&lt;p&gt;If you set your locale to Canadian or US English (en_CA or en_US), and enabled &lt;b&gt;&lt;i&gt;Detailed Settings&lt;/i&gt;&lt;/b&gt; to change the &lt;b&gt;&lt;i&gt;Time&lt;/i&gt;&lt;/b&gt; locale to &lt;b&gt;Sweden - English&lt;/b&gt; (en_SE), Firefox will show numbers in Swedish / European style, like &quot;3,14&quot; instead of &quot;3.14&quot;.&lt;/p&gt;&lt;p&gt;This problem happens at least in the downloads window.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Method 1: Fix by setting LC_ALL environment variable &lt;/b&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;The most reliable way to fix it in Debian is to set the &lt;code&gt;LC_ALL&lt;/code&gt;  environment variable, but &lt;i&gt;only&lt;/i&gt; for Firefox [13].&amp;nbsp; Don&#39;t set &lt;code&gt;LC_ALL&lt;/code&gt;  globally or it&#39;ll undo the locale changes above, plus you just shouldn&#39;t as it overrides everything [12].&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;i&gt;&lt;b&gt;For the terminal :&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;With that said, all it involves is opening Firefox in the terminal like this:&lt;/p&gt;&lt;p&gt;&lt;code&gt;LC_ALL=en_CA.utf8 firefox&lt;/code&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;You can save that in a script that&#39;s in your &lt;code&gt;PATH&lt;/code&gt; so running Firefox always uses the &lt;code&gt;LC_ALL&lt;/code&gt; locale.&lt;/p&gt;&lt;p&gt;&lt;i&gt;&lt;b&gt;For the Firefox icon:&lt;/b&gt;&lt;/i&gt; &lt;br /&gt;&lt;/p&gt;&lt;p&gt;The Firefox icon in Debian requires a different fix though.&amp;nbsp; That icon in the applications menu is controlled by a&amp;nbsp; &lt;code&gt;firefox.desktop&lt;/code&gt; file located at:&lt;/p&gt;&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;/usr/share/applications/firefox.desktop&lt;/code&gt;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&lt;/p&gt;&lt;p&gt;You can modify it directly or, safer, copy it to your user&#39;s applications folder:&lt;/p&gt;&lt;p&gt;&lt;code&gt;~/.local/share/applications&lt;/code&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Once copied, open it in a plaintext editor and change the &lt;code&gt;Exec&lt;/code&gt; line to this:&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;code&gt;Exec=sh -c &quot;LC_ALL=en_CA.utf8 /usr/bin/firefox&quot;&lt;/code&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Method 2: &lt;/b&gt;&lt;b&gt;&lt;b&gt;Fix by setting&lt;/b&gt; Firefox locale internally&lt;/b&gt;&lt;/p&gt;&lt;p&gt;The &quot;official&quot; way to set the Firefox user interface locale is via Firefox&#39;s preferences [14]:&amp;nbsp; open preferences, then go to the &lt;i&gt;Language&lt;/i&gt; section of the &lt;i&gt;General&lt;/i&gt; panel.&lt;/p&gt;&lt;p&gt;I&#39;ve tried it on Debian and it doesn&#39;t work.&lt;/p&gt;&lt;p&gt;You could also try finding in &lt;code&gt;about:config&lt;/code&gt; the &lt;code&gt;&lt;/code&gt;&lt;code&gt;intl.locale.requested&lt;/code&gt; key and set it to the desired locale [15].&amp;nbsp; I didn&#39;t test this method though because setting the &lt;code&gt;LC_ALL&lt;/code&gt; environment variable worked perfectly for me.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;u&gt;&lt;b&gt;Other locale options&lt;/b&gt;&lt;/u&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Sweden - English&lt;/b&gt; (en_SE) is an unofficial locale made up to give us English language, metric, ISO-8601 date format [1].&amp;nbsp; But it uses Swedish kronor SEK for currency [2]. &lt;/p&gt;&lt;p&gt;&lt;b&gt;Denmark - English&lt;/b&gt; (en_DK) is another unofficial locale made up with similar English and metric formats [3].&amp;nbsp; But the date is backwards (in dd/MM/y format), and uses Danish kroner DKK currency [4].&lt;/p&gt;&lt;p&gt;&lt;b&gt;Ireland - English&lt;/b&gt; (en_IE) is an &lt;i&gt;official&lt;/i&gt; locale that, like Denmark - English, gives us English and metric units [5], and like en_DK, the date is backwards (in dd/MM/y format).&amp;nbsp; It uses Euro for currency [6] though.&lt;/p&gt;&lt;p&gt;So by mixing and matching Ireland, Denmark, and Sweden, you should be able to get a reasonable ISO 8601/English/Euro(pean) locale.&lt;/p&gt;&lt;p&gt;And mixing Canada, US, and Sweden will get you a reasonable ISO 8601/English/Dollar locale.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;u&gt;&lt;b&gt;References&lt;/b&gt;&lt;/u&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;[1]: https://unix.stackexchange.com/a/62318&lt;/p&gt;&lt;p&gt;[2]: https://icu4c-demos.unicode.org/icu-bin/locexp?d_=en&amp;amp;_=en_SE&lt;/p&gt;&lt;p&gt;[3]: https://unix.stackexchange.com/a/272665 and https://superuser.com/a/1269909&lt;br /&gt;&lt;/p&gt;&lt;p&gt;[4]: https://icu4c-demos.unicode.org/icu-bin/locexp?d_=en&amp;amp;_=en_DK&lt;/p&gt;&lt;p&gt;[5]: https://unix.stackexchange.com/a/62317&lt;/p&gt;&lt;p&gt;[6]: https://icu4c-demos.unicode.org/icu-bin/locexp?d_=en&amp;amp;_=en_IE&lt;/p&gt;&lt;p&gt;[7]: https://bugs.launchpad.net/ubuntu/+source/langpack-locales/+bug/208548/comments/11&lt;/p&gt;&lt;p&gt;[8]: https://unix.stackexchange.com/a/269293&lt;/p&gt;&lt;p&gt;[12]: https://wiki.debian.org/Locale#Configuration&amp;nbsp;&lt;/p&gt;&lt;p&gt;[13]: https://unix.stackexchange.com/questions/34965/how-to-change-firefox-language#comment47453_34967&lt;/p&gt;&lt;p&gt;[14]: https://support.mozilla.org/en-US/kb/use-firefox-another-language?redirectslug=use-firefox-interface-other-languages-language-pack&amp;amp;redirectlocale=en-US#w_how-to-change-the-language-of-the-user-interface&lt;/p&gt;&lt;p&gt;[15]: https://support.mozilla.org/en-US/questions/1223719#answer-1127761&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;u&gt;&lt;b&gt;Bibliography&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;&lt;p&gt;[9]: https://github.com/lxqt/pcmanfm-qt/issues/656&lt;/p&gt;&lt;p&gt;[10]: https://github.com/lxqt/lxqt-config/issues/507&lt;/p&gt;&lt;p&gt;[11]: https://wiki.debian.org/Locale&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.carsoncheng.ca/feeds/4565809205678789437/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/713602603894920874/4565809205678789437' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/713602603894920874/posts/default/4565809205678789437'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/713602603894920874/posts/default/4565809205678789437'/><link rel='alternate' type='text/html' href='http://blog.carsoncheng.ca/2021/03/use-iso-8601-dates-in-pcmanfm-on-debian.html' title='Use ISO 8601 dates in PCManFM on Debian LXQt'/><author><name>blogger</name><uri>http://www.blogger.com/profile/09586588053165570068</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-713602603894920874.post-1507882054472325334</id><published>2021-03-18T11:52:00.001-07:00</published><updated>2021-11-06T11:10:44.763-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Computer-Tech"/><category scheme="http://www.blogger.com/atom/ns#" term="Debian-Linux"/><category scheme="http://www.blogger.com/atom/ns#" term="Ubuntu-Linux"/><title type='text'>Enable 3 Finger Drag on Linux</title><content type='html'>&lt;p&gt;&lt;/p&gt;&lt;h1 style=&quot;text-align: left;&quot;&gt;&lt;b&gt;&lt;b&gt;3 Finger Drag (3FD)&lt;/b&gt; is not available on Windows, and not built-in on Linux&lt;br /&gt;&lt;/b&gt;&lt;/h1&gt;&lt;p&gt;On Windows, we can achieve something similar.&amp;nbsp; Let&#39;s call it:&amp;nbsp; &lt;b&gt;3 Finger Tap to Drag Lock&lt;/b&gt;.&amp;nbsp; See &lt;a href=&quot;https://blog.carsoncheng.ca/2021/02/enable-3-finger-drag-on-windows.html&quot; target=&quot;_blank&quot;&gt;Enable 3 Finger Drag on Windows&lt;/a&gt; for how.&lt;/p&gt;&lt;p&gt;On Linux, it &lt;i&gt;is&lt;/i&gt; apparently possible to have pretty good 3 Finger Drag!&amp;nbsp; See below. &lt;/p&gt;Pretty
 good but not as good as Mac&#39;s 3FD, but without Apple&#39;s tightly 
integrated hardware, software, OS, driver, etc., it&#39;s impossible to get 
Apple Mac&#39;s high quality 3FD.&lt;h1 style=&quot;text-align: left;&quot;&gt;&lt;b&gt;What&#39;s 3FD anyway?&lt;/b&gt; &lt;br /&gt;&lt;/h1&gt;&lt;p&gt;3 Finger Drag refers to a Mac 
accessibility feature.&amp;nbsp; When enabled, if you place three fingers on the 
Mac&#39;s trackpad or touchpad, then move those fingers in unison on the 
trackpad, the mouse pointer behave as if you 
left-clicked-and-are-dragging.&lt;/p&gt;&lt;p&gt;It&#39;s a better more ergonomic alternative to the tap-twice-and-drag method that&#39;s common on Macs, Windows, and Linux.&lt;/p&gt;&lt;p&gt;It&#39;s
 better because there&#39;s less finger tapping movement which can develop 
into &quot;trigger finger&quot; type repetitive strain injury.&amp;nbsp; If you drag things
 around a lot, tap-twice-and-drag plus another tap to deactivate 
dragging starts to add up to being a nuisance!&lt;br /&gt;&lt;/p&gt;&lt;p&gt;And at least 
for me, when dragging using the&amp;nbsp; tap-twice-and-drag gesture, I often 
have trouble continuing to drag mid-drag if I lift my hand away from the
 trackpad to reposition.&amp;nbsp; And ironically, I also have trouble 
disengaging the drag once I&#39;ve reached the target of the drag motion 
too!&lt;/p&gt;&lt;h1 style=&quot;text-align: left;&quot;&gt;&lt;b&gt;How to add 3FD to Linux&lt;/b&gt;&lt;/h1&gt;&lt;p&gt;As of 2021 January, the happy path to getting 3FD on Linux is: &lt;/p&gt;&lt;ol style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Use a desktop Linux system that uses libinput for handling the trackpad&lt;/li&gt;&lt;li&gt;build your own custom 3FD enabled libinput&lt;/li&gt;&lt;li&gt;install your custom libinput.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;b&gt;(1) Use a desktop Linux system that uses libinput for handling the trackpad&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Fortunately, Ubuntu and Debian uses libinput.&amp;nbsp; And libinput works with both Wayland and X11.&amp;nbsp; And Gnome/Xfce/KDE/LXDE all work with libinput.&amp;nbsp; So practically everyone&#39;s standardized onto libinput for trackpad and gesture support in 2021!&lt;/p&gt;&lt;p&gt;&lt;b&gt;(2) Build custom 3FD enabled libinput &lt;/b&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Unfortunately, 3FD isn&#39;t standard in libinput.&amp;nbsp; And likely won&#39;t be for a very long time if ever.&lt;/p&gt;&lt;p&gt;But there&#39;s a patched version of libinput with 3FD added!&amp;nbsp; Here&#39;s the most recent patch:&amp;nbsp; &lt;a href=&quot;https://github.com/aakside/libinput/tree/1.16-branch-complyue&quot; target=&quot;_blank&quot;&gt;aakside&#39;s libinput&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;b&gt;(3) install your custom libinput&lt;/b&gt; &lt;/p&gt;&lt;p&gt;See &lt;a href=&quot;https://medium.com/@dakshin.k1/enable-3-finger-gesture-for-click-and-drag-on-windows-and-linux-cd7165b66851&quot; target=&quot;_blank&quot;&gt;Dakshin Karthikeyan&#39;s article&lt;/a&gt; for the Linux specific instructions on how to install.&lt;/p&gt;&lt;p&gt;Caution: Dakshin&#39;s article references a different 3FD patched libinput that&#39;s by jafd, which is slightly older and apparently with less 3FD enabling features.&lt;/p&gt;&lt;p&gt;To be clear, aakside&#39;s 3FD enabled libinput is a rebasing of complyue&#39;s 3FD libinput patch onto a more updated libinput.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;I wrote a &lt;a href=&quot;https://blog.carsoncheng.ca/2021/03/state-of-built-in-3-finger-drag-on-linux.html&quot; target=&quot;_blank&quot;&gt;State of Built-in 3 Finger Drag on Linux&lt;/a&gt; post earlier if you want to understand more the relationship between the various libinput patches / forks.&lt;/p&gt;&lt;p&gt;&lt;i&gt;&lt;u&gt;&lt;b&gt;Alternatively...&lt;/b&gt;&lt;/u&gt;&lt;/i&gt;&lt;/p&gt;&lt;p&gt;It&#39;s work checking out another route to 3FD based on top of libinput like libinput-gestures called &lt;a href=&quot;https://github.com/marsqing/libinput-three-finger-drag&quot; target=&quot;_blank&quot;&gt;libinput-three-finger-drag (marsqing)&lt;/a&gt;.&amp;nbsp; It can work alongside libinput-gestures.&amp;nbsp; However, it&#39;s &lt;a href=&quot;https://github.com/marsqing/libinput-three-finger-drag/issues/4&quot; target=&quot;_blank&quot;&gt;stopped working as of 2021 Oct 28&lt;/a&gt;. But if it works, it seems less invasive than using a patched libinput?&lt;br /&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.carsoncheng.ca/feeds/1507882054472325334/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/713602603894920874/1507882054472325334' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/713602603894920874/posts/default/1507882054472325334'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/713602603894920874/posts/default/1507882054472325334'/><link rel='alternate' type='text/html' href='http://blog.carsoncheng.ca/2021/02/enable-3-finger-drag-on-linux.html' title='Enable 3 Finger Drag on Linux'/><author><name>blogger</name><uri>http://www.blogger.com/profile/09586588053165570068</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-713602603894920874.post-4028740664987310467</id><published>2021-03-10T15:57:00.001-08:00</published><updated>2021-11-06T11:08:18.839-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Computer-Tech"/><category scheme="http://www.blogger.com/atom/ns#" term="Debian-Linux"/><category scheme="http://www.blogger.com/atom/ns#" term="Ubuntu-Linux"/><title type='text'>State of Built-in 3 Finger Drag on Linux</title><content type='html'>&lt;p&gt;&amp;nbsp;Will we ever get built-in 3 Finger Drag (3FD) on Linux?&amp;nbsp; At this point, likely not.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Non-libinput desktop Linux&lt;/b&gt; &lt;br /&gt;&lt;/p&gt;&lt;p&gt;For older desktop Linux not using libinput for trackpad support, you can look into &lt;a href=&quot;https://github.com/BlueDragonX/xf86-input-mtrack&quot; target=&quot;_blank&quot;&gt;mtrack&lt;/a&gt; (no 3FD but...) and the &lt;a href=&quot;https://github.com/p2rkw/xf86-input-mtrack&quot; target=&quot;_blank&quot;&gt;p2rkw&#39;s mtrack fork&lt;/a&gt; which provides 3FD.&amp;nbsp; &lt;a href=&quot;https://martys.typepad.com/blog/2015/08/3-finger-drag-on-linux.html&quot; target=&quot;_blank&quot;&gt;Marty&#39;s article&lt;/a&gt; [1] is older but explains it well for non-libinput desktop Linux.&lt;/p&gt;&lt;p&gt;But non-libinput is on the way out. &lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Libinput is basically standard in 2021&lt;/b&gt; &lt;br /&gt;&lt;/p&gt;&lt;p&gt;Everyone&#39;s using libinput now, pretty much.&amp;nbsp; If you&#39;re on a desktop Linux machine using Wayland, you&#39;re using libinput.&lt;/p&gt;&lt;p&gt;If you&#39;re using X11 still, you still could be using libinput.&amp;nbsp; Or 
synaptics or xf86-input-* or...&amp;nbsp; but at least on Debian buster LXDE as I
 am, turns out it&#39;s using libinput.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://gitlab.freedesktop.org/libinput/libinput&quot; target=&quot;_blank&quot;&gt;Libinput&lt;/a&gt; sits between your 
input drivers in the linux kernel and the display server.&amp;nbsp; Libinput is 
the present and future of gesture, event, and pointer support for trackpads on Linux.&lt;/p&gt;&lt;p&gt;So if you want 3FD into the future, we have to look at libinput. &lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Configuring libinput&lt;/b&gt;&lt;/p&gt;&lt;p&gt;If you&#39;re using Wayland on Linux, there&#39;s no way to configure libinput.&amp;nbsp; This is &lt;a href=&quot;https://wayland.freedesktop.org/libinput/doc/latest/faqs.html#how-do-i-configure-my-device-on-wayland&quot; target=&quot;_blank&quot;&gt;by design&lt;/a&gt;.&amp;nbsp;
 You should use your desktop environment&#39;s configuration to configure 
the trackpad.&amp;nbsp; Your desktop environment will configure libinput as 
needed.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Using X11 on Linux, you can still configure libinput.&amp;nbsp;
 Like most things X11 related, you have to change configuration files 
here and there.&amp;nbsp; See &lt;a href=&quot;https://wayland.freedesktop.org/libinput/doc/latest/faqs.html#how-do-i-configure-my-device-on-x&quot; target=&quot;_blank&quot;&gt;libinput&#39;s FAQ on this point&lt;/a&gt; to start.&amp;nbsp; But &lt;a href=&quot;https://wiki.archlinux.org/index.php/Libinput&quot; target=&quot;_blank&quot;&gt;ArchWiki&#39;s libinput page&lt;/a&gt; is great with plenty of details.&lt;/p&gt;&lt;p&gt;There is, however, no configuration for 3FD for libinput anyway.&lt;/p&gt;&lt;p&gt;&lt;b&gt;State of 3FD support in libinput via patches&lt;/b&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;There&#39;s two patched versions of libinput with 3FD added you could try!&lt;/p&gt;&lt;ol style=&quot;text-align: left;&quot;&gt;&lt;li&gt;&lt;a href=&quot;https://github.com/jafd/libinput&quot; target=&quot;_blank&quot;&gt;&amp;nbsp;jafd&#39;s libinput&amp;nbsp;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://github.com/aakside/libinput/tree/1.16-branch-complyue&quot; target=&quot;_blank&quot;&gt;aakside&#39;s libinput&lt;/a&gt; --- this is an updated version of &lt;a href=&quot;https://github.com/complyue/libinput&quot; target=&quot;_blank&quot;&gt;complyue&#39;s libinput&lt;/a&gt; which had 3FD enabled but was based on an older libinput version&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;See &lt;a href=&quot;https://medium.com/@dakshin.k1/enable-3-finger-gesture-for-click-and-drag-on-windows-and-linux-cd7165b66851&quot; target=&quot;_blank&quot;&gt;Dakshin Karthikeyan&#39;s article&lt;/a&gt; for the Linux specific instructions on how to install.&amp;nbsp; But Dakshin references jafd&#39;s libinput instead of complyue / aakside&#39;s patch.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;If you go through the whole&amp;nbsp;&lt;a href=&quot;https://gitlab.freedesktop.org/libinput/libinput/-/issues/298&quot; target=&quot;_blank&quot;&gt;Request for three fingers click+movement &lt;/a&gt;in libinput&#39;s repository, you&#39;ll see that jafd&#39;s 3FD is possibly less featureful than complyue&#39;s.&amp;nbsp; But complyue&#39;s version was based on an older libinput.&lt;/p&gt;&lt;p&gt;That Request discussion thread also seems to point at the difficulty and possibly impossibility of libinput ever having 3FD enabled by default.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Fortunately, aakside updated complyue&#39;s patch to the latest libinput! &lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;3FD via libinput-gestures&lt;/b&gt;&lt;/p&gt;&lt;p&gt;There is another route to 3FD via &lt;a href=&quot;https://github.com/bulletmark/libinput-gestures&quot; target=&quot;_blank&quot;&gt;libinput-gestures&lt;/a&gt; via this patched &lt;a href=&quot;https://github.com/daveriedstra/libinput-gestures/tree/three-finger-drag&quot; target=&quot;_blank&quot;&gt;fork of libinput-gestures with basic 3FD support&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;b&gt;3FD via libinput-3FD&lt;/b&gt;&lt;/p&gt;&lt;p&gt;There is another route to 3FD based on top of libinput like libinput-gestures called &lt;a href=&quot;https://github.com/marsqing/libinput-three-finger-drag&quot; target=&quot;_blank&quot;&gt;libinput-three-finger-drag (marsqing)&lt;/a&gt;.&amp;nbsp; It can work alongside libinput-gestures.&amp;nbsp; However, it&#39;s &lt;a href=&quot;https://github.com/marsqing/libinput-three-finger-drag/issues/4&quot; target=&quot;_blank&quot;&gt;stopped working as of 2021 Oct 28&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;References&lt;/b&gt;&lt;/p&gt;[1]&amp;nbsp;&lt;a href=&quot;https://martys.typepad.com/blog/2015/08/3-finger-drag-on-linux.html&quot; target=&quot;_blank&quot;&gt;3-finger-drag on Linux&lt;/a&gt; </content><link rel='replies' type='application/atom+xml' href='http://blog.carsoncheng.ca/feeds/4028740664987310467/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/713602603894920874/4028740664987310467' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/713602603894920874/posts/default/4028740664987310467'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/713602603894920874/posts/default/4028740664987310467'/><link rel='alternate' type='text/html' href='http://blog.carsoncheng.ca/2021/03/state-of-built-in-3-finger-drag-on-linux.html' title='State of Built-in 3 Finger Drag on Linux'/><author><name>blogger</name><uri>http://www.blogger.com/profile/09586588053165570068</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-713602603894920874.post-6437511004928304457</id><published>2021-03-04T22:33:00.006-08:00</published><updated>2021-03-04T22:33:00.771-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Debian-Linux"/><category scheme="http://www.blogger.com/atom/ns#" term="Lubuntu"/><category scheme="http://www.blogger.com/atom/ns#" term="Ubuntu-Linux"/><title type='text'>.bashrc, .profile, .bash_profile in Lubuntu vs Debian LXDE</title><content type='html'>&lt;p&gt;Here we go again... profile vs bash_profile vs bashrc dot files.&lt;/p&gt;&lt;h1 style=&quot;text-align: left;&quot;&gt;&lt;b&gt;In Lubuntu&lt;br /&gt;&lt;/b&gt;&lt;/h1&gt;&lt;p&gt;I had figured &lt;a href=&quot;https://blog.carsoncheng.ca/2020/04/profile-bashprofile-bashrc-on-ubuntu.html&quot; target=&quot;_blank&quot;&gt;previously [1]&lt;/a&gt; that:&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Desktop environment&#39;s graphical login sources .profile&lt;/li&gt;&lt;li&gt;bash started in login mode sources .bash_profile, but if that doesn&#39;t exist, then falls back to sourcing .profile&lt;/li&gt;&lt;li&gt;bash started interactively (hence in non-login, or interactive, mode) sources in .bashrc only&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Both .bash_profile and .profile should contain code to source in .bashrc&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;So when does code in each file run? &lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;.profile&lt;/b&gt; has code you want to run only once, and only upon your DE graphical login.&lt;/p&gt;&lt;p&gt;&lt;b&gt;.bash_profile&lt;/b&gt; has code you want to run once only upon your bash shell executing in login mode&lt;/p&gt;&lt;p&gt;&lt;b&gt;.bashrc&lt;/b&gt; has code you want to run every single time bash starts, or when you login (if .profile sources in .bashrc as it should), or when bash starts in login mode (if .bash_profile sources in .bashrc as it should).&lt;/p&gt;&lt;h1 style=&quot;text-align: left;&quot;&gt;In Debian LXDE&lt;br /&gt;&lt;/h1&gt;&lt;p&gt;It seems that:&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Desktop environment&#39;s graphical login &lt;b&gt;AND&lt;/b&gt; bash started in login mode both source .bash_profile, but if that doesn&#39;t exist, then falls back to sourcing .profile&lt;/li&gt;&lt;li&gt;bash started interactively (hence in non-login, or interactive, mode) sources in .bashrc only&lt;br /&gt;&lt;/li&gt;&lt;li&gt;.bash_profile or .profile should contain code to source in .bashrc&lt;/li&gt;&lt;li&gt;You should &lt;i&gt;not&lt;/i&gt; have both .bash_profile and .profile since then the latter will be ignored anyway&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;This meant there&#39;s no place to put code that you want to run only once, and only upon your DE graphical login.&lt;/p&gt;&lt;p&gt;The workaround is to put the code in .profile (and you shouldn&#39;t have .bash_profile around as it&#39;ll override .profile).&lt;/p&gt;&lt;p&gt;Then make that code run only if the GUI is running, which you can detect.&amp;nbsp; And also make the code only once only, by checking if it&#39;s run before.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;e.g. in .profile&lt;br /&gt;&lt;/p&gt;&lt;p&gt;
&lt;code&gt;&lt;/code&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;
if [ -n &quot;$DISPLAY&quot; ]; then
    if [ ! -n &quot;$RUNONCE&quot; ]; then
        export RUNONCE=&quot;done&quot; # like a C include guard
        cat &quot;GUI running&quot; &amp;gt; GUI_is_running.txt
    fi
fi &lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In a console without a GUI, $DISPLAY is not defined.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;h1 style=&quot;text-align: left;&quot;&gt;To learn more &lt;br /&gt;&lt;/h1&gt;&lt;p&gt;&amp;nbsp;Some resources from other sites:&lt;br /&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;&lt;a href=&quot;https://superuser.com/a/183980&quot; target=&quot;_blank&quot;&gt;Difference between .bashrc and .bash_profile&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://superuser.com/a/789465&quot; target=&quot;_blank&quot;&gt;Choosing between .bashrc, .profile, .bash_profile, etc&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://serverfault.com/a/261807&quot; target=&quot;_blank&quot;&gt;What are the functional differences between .profile .bash_profile and .bashrc&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://leimao.github.io/blog/bashrc-VS-profile-VS-bash_profile/&quot; target=&quot;_blank&quot;&gt;~/.bashrc VS ~/.profile VS ~/.bash_profile&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://news.ycombinator.com/item?id=24881711&quot; target=&quot;_blank&quot;&gt;HN: barrkel | on: /.bashrc VS –/.profile VS –/.bash_profile &lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;[1] &lt;a href=&quot;https://blog.carsoncheng.ca/2020/04/profile-bashprofile-bashrc-on-ubuntu.html&quot; target=&quot;_blank&quot;&gt;profile bash_profile bashrc on Ubuntu Linux, Macs, and Windows&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.carsoncheng.ca/feeds/6437511004928304457/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/713602603894920874/6437511004928304457' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/713602603894920874/posts/default/6437511004928304457'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/713602603894920874/posts/default/6437511004928304457'/><link rel='alternate' type='text/html' href='http://blog.carsoncheng.ca/2021/03/bashrc-profile-bashprofile-in-lubuntu.html' title='.bashrc, .profile, .bash_profile in Lubuntu vs Debian LXDE'/><author><name>blogger</name><uri>http://www.blogger.com/profile/09586588053165570068</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-713602603894920874.post-463850374867504289</id><published>2021-02-25T11:25:00.000-08:00</published><updated>2021-02-25T11:25:00.899-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Computer-Tech"/><category scheme="http://www.blogger.com/atom/ns#" term="Mac"/><title type='text'>Mac Finder still shows incorrect folder sizes</title><content type='html'>It&#39;s been two years, and the Mac Finder &lt;i&gt;still&lt;/i&gt; shows incorrect folder sizes --- on macOS 10.15 Catalina.&lt;br /&gt;&lt;p&gt;A single screenshot shows how hilarious / sad this is:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg5XYB4jdNY_K3fBQjn_lp_AlFc9gaMqoLdpo5kov6B42l1xemqEaNrgS1cqHs56xKLxUY32AeSSJfT_J8FlQoBRuUGEN-mrf2MJXsgKr1-OAlonkZ4U_OpgugP1GC5PEjaKy4RHmg-V4I/&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;413&quot; data-original-width=&quot;1025&quot; height=&quot;258&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg5XYB4jdNY_K3fBQjn_lp_AlFc9gaMqoLdpo5kov6B42l1xemqEaNrgS1cqHs56xKLxUY32AeSSJfT_J8FlQoBRuUGEN-mrf2MJXsgKr1-OAlonkZ4U_OpgugP1GC5PEjaKy4RHmg-V4I/w640-h258/Screen+Shot+2021-02-20+at+23.14.17.jpg&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&amp;nbsp;&lt;p&gt;&lt;/p&gt;&lt;p&gt;The screenshot here shows the Finder thinking my &quot;lol&quot; folder is 17.92 GB.&lt;/p&gt;&lt;p&gt;But inside &quot;lol&quot; are two sub-directories: &quot;magic&quot;, and &quot;movs&quot;.&amp;nbsp; Finder thinks those two folders are zero KB.&lt;/p&gt;&lt;p&gt;Inside &quot;movs&quot; are a bunch of MP4 files that together are several &lt;i&gt;hundred&lt;/i&gt; MBs.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Bring up the terminal to check, and &lt;i&gt;du&lt;/i&gt; shows &quot;lol&quot; is actually 211 GB !!!&lt;/p&gt;&lt;p&gt;For the record, &lt;i&gt;du&lt;/i&gt; is correct.&amp;nbsp; &quot;magic&quot; contains a lot more files.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Oh Apple... I can&#39;t recall classic Mac OS Finder, since the System 7 days, ever having this level of... mistake? incompetency? error?&amp;nbsp; If every time the Finder&#39;s Get Info window is open, it would just spin out a &lt;i&gt;du&lt;/i&gt; sub-process to get the folder size, then it wouldn&#39;t get it this wrong.&amp;nbsp; But nope.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;And for the record, I had to restart the Mac to get the folder size to show correctly.&amp;nbsp; Something with the Finder got really screwed up I guess.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;This problem has been known for two years, since macOS 10.14.&amp;nbsp; See:&lt;br /&gt;&lt;/p&gt;&lt;p&gt;- 2019 February:&amp;nbsp;&lt;a href=&quot;https://mjtsai.com/blog/2019/02/22/finder-shows-incorrect-folder-sizes/&quot; target=&quot;_blank&quot;&gt;Finder Shows Incorrect Folder Sizes&lt;/a&gt; --- on macOS 10.14&lt;br /&gt;&lt;/p&gt;&lt;p&gt;- 2020 February:&amp;nbsp;&lt;a href=&quot;https://daringfireball.net/2020/02/what_you_see_in_the_finder_should_be_correct&quot; target=&quot;_blank&quot;&gt;What You See in the Finder Should Always Be Correct&lt;/a&gt;&lt;/p&gt;- 2021 February: here we are... </content><link rel='replies' type='application/atom+xml' href='http://blog.carsoncheng.ca/feeds/463850374867504289/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/713602603894920874/463850374867504289' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/713602603894920874/posts/default/463850374867504289'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/713602603894920874/posts/default/463850374867504289'/><link rel='alternate' type='text/html' href='http://blog.carsoncheng.ca/2021/02/mac-finder-still-shows-incorrect-folder.html' title='Mac Finder still shows incorrect folder sizes'/><author><name>blogger</name><uri>http://www.blogger.com/profile/09586588053165570068</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg5XYB4jdNY_K3fBQjn_lp_AlFc9gaMqoLdpo5kov6B42l1xemqEaNrgS1cqHs56xKLxUY32AeSSJfT_J8FlQoBRuUGEN-mrf2MJXsgKr1-OAlonkZ4U_OpgugP1GC5PEjaKy4RHmg-V4I/s72-w640-h258-c/Screen+Shot+2021-02-20+at+23.14.17.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-713602603894920874.post-9103146986256702541</id><published>2021-02-19T14:03:00.130-08:00</published><updated>2021-02-19T14:03:00.341-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Computer-Tech"/><category scheme="http://www.blogger.com/atom/ns#" term="Debian-Linux"/><category scheme="http://www.blogger.com/atom/ns#" term="Ubuntu-Linux"/><category scheme="http://www.blogger.com/atom/ns#" term="Windows-OS"/><title type='text'>Remap Capslock to Control in VirtualBox Linux guest on Windows host</title><content type='html'>&lt;p&gt;Let&#39;s say you have Debian Linux guest OS in VirtualBox, running on a Windows 10 host.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Here&#39;s how to map capslock to control&lt;/b&gt;&lt;/p&gt;&lt;p&gt;If it was a Mac host, it&#39;d be super easy: install and use &lt;a href=&quot;https://karabiner-elements.pqrs.org/&quot; target=&quot;_blank&quot;&gt;Karabiner-Elements&lt;/a&gt; to remap capslock to control in the Mac host [3]. Now both host and guest Linux will have the remapping.&amp;nbsp; Done.&lt;/p&gt;&lt;p&gt;On Windows, it&#39;s not so easy.&lt;/p&gt;&lt;p&gt;You basically have to do the remapping in both Windows and Linux.&amp;nbsp; Follow the ideas here:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ol style=&quot;text-align: left;&quot;&gt;&lt;li&gt;&lt;a href=&quot;https://blog.carsoncheng.ca/2021/01/remap-one-key-to-another-in-windows.html&quot; target=&quot;_blank&quot;&gt;Remap one key to another in Windows, like Capslock to Control&lt;/a&gt;&amp;nbsp;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.carsoncheng.ca/2021/02/remap-one-key-to-another-in-linux-like.html&quot; target=&quot;_blank&quot;&gt;Remap one key to another in Linux, like Capslock to Control&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;b&gt;Set shift key to break capslock for greater reliability&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;For greater reliability, you should also set shift key to break capslock.&amp;nbsp; So adding that to the Linux command for making capslock a control key, you&#39;d get this command to run instead:   &lt;/p&gt;&lt;p style=&quot;margin-left: 40px; text-align: left;&quot;&gt;&lt;code&gt;setxkbmap -option -option caps:ctrl_modifier -option shift:breaks_caps &lt;br /&gt;&lt;/code&gt;&lt;/p&gt;&lt;p&gt;The first blank &quot;-option&quot; clears any previously set.&amp;nbsp; Then the second option sets the capslock to control.&amp;nbsp; The third option makes shift key break capslock.&lt;/p&gt;&lt;p&gt;This is needed because sometimes switching between Windows host and Linux guest, the capslock gets locked down.&amp;nbsp; Now a quick tap on the shift key should break that lock.&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left;&quot;&gt;&lt;b&gt;What&#39;s wrong with remapping in Windows host only?&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left;&quot;&gt;If you remap capslock to control in Windows host only, it&#39;ll actually sort of work in the Linux guest --- except in Linux, the capslock will now function as &lt;i&gt;both&lt;/i&gt; capslock &lt;i&gt;and&lt;/i&gt; control!&lt;/p&gt;&lt;p style=&quot;text-align: left;&quot;&gt;I did that for a while and didn&#39;t notice as I tested it inside Linux guest.&amp;nbsp; Capslock-T in Firefox still created new tabs!&amp;nbsp; Works!&amp;nbsp; But if you start typing, you&#39;ll notice things are in all caps until you tap capslock again, and vice versa.&lt;/p&gt;&lt;p style=&quot;text-align: left;&quot;&gt;&lt;b&gt;What&#39;s wrong with remapping in Linux guest only?&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left;&quot;&gt;If you remap capslock to control in Linux guest only, it&#39;ll actually work!&amp;nbsp; Except the capslock LED light will turn on/off with each click.&amp;nbsp; And if you switch back to Windows, capslock might have been engaged as you used capslock-as-control in Linux guest.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;That&#39;s why you must do the remapping in both Windows host and Linux guest.&amp;nbsp; That way they stay in sync with each other, and the LED light won&#39;t turn on.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Capslock LED light in Linux&lt;/b&gt;&lt;/p&gt;&lt;p&gt;As I was troubleshooting the Linux guest only remapping, and noticed the capslock LED light would turn on/off, at first I thought the problem was in Linux.&lt;/p&gt;&lt;p&gt;And in case it is for your situation, here&#39;s how to fix or check.&lt;/p&gt;&lt;p&gt;&lt;code&gt;xmodmap -e &#39;clear Lock&#39;&lt;/code&gt; is suppose to clear the capslock LED from being turned on [1].&amp;nbsp; Try that, despite &lt;i&gt;xmodmap&lt;/i&gt; being a deprecated system.&lt;/p&gt;&lt;p&gt;You can check if the LED is being turned on by Linux by running this command:&lt;/p&gt;
&lt;code&gt;&lt;pre&gt;cat &#39;/sys/class/leds/input5::capslock/brightness&#39;
&lt;/pre&gt;&lt;/code&gt;
&lt;p&gt;Turns out the LED property is represented as &quot;just a file&quot; on Linux you can open and read [2].&lt;br /&gt;&lt;/p&gt;&lt;p&gt;In my case, that command showed the LED was always off from Linux guest&#39;s point of view.&amp;nbsp; Turned out Windows host was controlling it.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Reference&lt;/b&gt;&lt;/p&gt;&lt;p&gt;[1]&amp;nbsp;&lt;a href=&quot;https://unix.stackexchange.com/a/75578&quot; target=&quot;_blank&quot;&gt;How to prevent the caps-lock toggle effect, without remapping or disabling it?&lt;/a&gt; &lt;br /&gt;&lt;/p&gt;&lt;p&gt;[2] &lt;a href=&quot;https://askubuntu.com/a/734861&quot; target=&quot;_blank&quot;&gt;Turn the Caps Lock LED on, while keep Caps Lock status is off&lt;/a&gt;&lt;/p&gt;&lt;p&gt;[3] Actually, I think Mac&#39;s System Preferences even have a built in setting 
for doing this remapping, so Karabiner might not even be needed for this 
single simple remapping.&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.carsoncheng.ca/feeds/9103146986256702541/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/713602603894920874/9103146986256702541' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/713602603894920874/posts/default/9103146986256702541'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/713602603894920874/posts/default/9103146986256702541'/><link rel='alternate' type='text/html' href='http://blog.carsoncheng.ca/2021/02/remap-capslock-to-control-in-virtualbox.html' title='Remap Capslock to Control in VirtualBox Linux guest on Windows host'/><author><name>blogger</name><uri>http://www.blogger.com/profile/09586588053165570068</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-713602603894920874.post-3172375838550475776</id><published>2021-02-10T00:36:00.118-08:00</published><updated>2021-03-26T20:50:34.334-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Computer-Tech"/><category scheme="http://www.blogger.com/atom/ns#" term="Debian-Linux"/><category scheme="http://www.blogger.com/atom/ns#" term="Ubuntu-Linux"/><title type='text'>Remap one key to another in Linux, like Capslock to Control</title><content type='html'>&lt;p&gt;Linux is known for choice and customizability.&lt;/p&gt;&lt;p&gt;So it&#39;s ironic but when it comes to keyboard and mouse key remapping and scripting, Linux is the more challenging than Windows (using AutoHotKey) or Macs (using Karabiner-Elements).&lt;/p&gt;&lt;p&gt;I&#39;ll link to some guides and answers below, but some big picture ideas to be aware of in 2020 for Linux key remapping:&lt;/p&gt;&lt;h1 style=&quot;text-align: left;&quot;&gt;&lt;b&gt;xmodmap is deprecated&lt;/b&gt;&lt;/h1&gt;&lt;p&gt;Prefer using &lt;b&gt;setxkbmap&lt;/b&gt; if it&#39;ll do what you want.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Some xmodmap functionality remains, but it&#39;s clearly a deprecated system and it sometimes doesn&#39;t work.&lt;/p&gt;&lt;p&gt;I tried to do some simple key remapping with it on Debian LXDE and it didn&#39;t work for me.&lt;/p&gt;&lt;h1 style=&quot;text-align: left;&quot;&gt;&lt;b&gt;setxkbmap is preferred but complicated&lt;/b&gt;&lt;/h1&gt;&lt;p&gt;It has many common remappings like turning capslock to control [1]:&lt;/p&gt;&lt;p style=&quot;margin-left: 40px; text-align: left;&quot;&gt;&lt;code&gt;setxkbmap -option -option caps:ctrl_modifier&lt;/code&gt;&lt;/p&gt;&lt;p&gt;The first blank &quot;-option&quot; clears any previously set.&amp;nbsp; Then the second option sets the capslock to control.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Swapping the left control and alt keys can be easy to do as there&#39;s a direct option for it too.&lt;/p&gt;&lt;p&gt;Running setxkbmap only affects the current session, so logging out will wipe the settings. To make it auto set on login, put it in a script run from .bashrc or similar.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Limitations&lt;/b&gt; &lt;br /&gt;&lt;/p&gt;&lt;p&gt;But what if you want to swap the &lt;i&gt;right&lt;/i&gt; control and alt keys instead?&amp;nbsp; Or some weird 4 way switch of keys? &lt;br /&gt;&lt;/p&gt;&lt;p&gt;There many be some set of xkeyboard-config options that&#39;ll work, but it&#39;s not straightforward the way it is on a Mac with Karabiner-Elements. &lt;br /&gt;&lt;/p&gt;&lt;p&gt;You also may have to find and use keycodes or events generated by your keyboard or mouse interactively.&amp;nbsp; Do this using the &lt;b&gt;xev&lt;/b&gt; command line app [3].&lt;/p&gt;&lt;p&gt;&amp;nbsp;If you want to go down this route, be sure to check out:&amp;nbsp; &lt;a href=&quot;https://medium.com/@damko/a-simple-humble-but-comprehensive-guide-to-xkb-for-linux-6f1ad5e13450&quot; target=&quot;_blank&quot;&gt;A simple, humble but comprehensive guide to XKB for linux&lt;/a&gt;.&amp;nbsp; But if you want an easier way, check out the last section below because, of course, there&#39;s an app for that!&lt;br /&gt;&lt;/p&gt;&lt;h1 style=&quot;text-align: left;&quot;&gt;Show setxkbmap options&lt;/h1&gt;&lt;p&gt;To find what options are supported by setxkbmap, you can run [2]:&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;margin-left: 40px; text-align: left;&quot;&gt;&lt;code&gt;man xkeyboard-config&lt;/code&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;man xkeyboard-config is not complete: e.g. right alt to right control&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;More annoyingly, turns out running &lt;i&gt;man xkeyboard-config&lt;/i&gt; does not list a complete list of what setxkbmap can do!&lt;/p&gt;&lt;p&gt;For example, let&#39;s say you want to make the right alt another right control key.&lt;/p&gt;&lt;p&gt;It&#39;s not listed in &lt;i&gt;man xkeyboard-config&lt;/i&gt; but it &lt;i&gt;is&lt;/i&gt; easily possible!&amp;nbsp; Just run:&lt;/p&gt;&lt;p&gt;&lt;code&gt;setxkbmap -option ctrl:ralt_rctrl&lt;/code&gt;&lt;/p&gt;&lt;p&gt;It is listed in a lower level description file at however [4] :&lt;/p&gt;&lt;p&gt;&lt;code&gt;/usr/share/X11/xkb/rules/evdev&lt;/code&gt; &lt;br /&gt;&lt;/p&gt;&lt;p&gt;And if you&#39;re up to it, you can change the low level description files that setxkbmap uses to give you great control over the keyboard remappings.&amp;nbsp; But it&#39;s not easy the way it is on Macs and Windows!&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;h1 style=&quot;text-align: left;&quot;&gt;&lt;b&gt;Remapping single keys using hwdb files&lt;/b&gt;&lt;br /&gt;&lt;/h1&gt;&lt;p&gt;This is lower level than setxkbmap, but it&#39;s not deprecated like xmodmap, and for single key to single key remapping, it seems to work well.&lt;/p&gt;&lt;p&gt;Detailed instructions found at: &lt;a href=&quot;https://www.reddit.com/r/linux_gaming/comments/k3h9qv/remapping_keys_using_hwdb_files/&quot; target=&quot;_blank&quot;&gt;Remapping keys using hwdb files&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;&lt;h1 style=&quot;text-align: left;&quot;&gt;&lt;b&gt;Use an app to intercept and inject keys&lt;/b&gt;&lt;br /&gt;&lt;/h1&gt;&lt;p&gt;This method allows more complex hotkeys and combos to be remapped to almost arbitrary input.&lt;/p&gt;&lt;p&gt;This is really new.&amp;nbsp; Try out&amp;nbsp; &lt;a href=&quot;https://github.com/sezanzeb/key-mapper&quot; target=&quot;_blank&quot;&gt;sezanzeb&#39;s key-mapper&lt;/a&gt;.&amp;nbsp; It works with X11 and Wayland, and has an easy GUI interface to it.&lt;/p&gt;&lt;p&gt;Here&#39;s a nice guide for it: &lt;a href=&quot;https://www.linuxuprising.com/2020/12/remap-keyboard-and-mouse-buttons-on.html&quot; target=&quot;_blank&quot;&gt;Remap Keyboard And Mouse Buttons On Linux With The New Key Mapper GUI (Supports X11 And Wayland)&lt;/a&gt;.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Since key-mapper is a Python program, you&#39;ll need Python to run it 
anyway.&amp;nbsp; So on Debian, you might as well just install Python and pip, 
then use pip to install it.&lt;/p&gt;&lt;p&gt;Key-mapper is &lt;b&gt;not&lt;/b&gt; available in Debian&#39;s package system, so you&#39;ll have to download and install it from the &lt;a href=&quot;https://github.com/sezanzeb/key-mapper&quot; target=&quot;_blank&quot;&gt;key-mapper Github repository&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;In fact, Debian has a package called &quot;keymapper&quot; that is &lt;b&gt;not&lt;/b&gt; the key-mapper you&#39;re looking for.&amp;nbsp; Using apt to install key-mapper, even key-mapper&#39;s own pre-packaged .deb file, kept suggesting the wrong &quot;keymapper&quot; package instead.&lt;/p&gt;Probably easiest to just install it with pip!&lt;br /&gt;&lt;p&gt;(&lt;b&gt;NEW!&lt;/b&gt;)&amp;nbsp; Check out &lt;a href=&quot;https://github.com/rbreaves/kinto&quot; target=&quot;_blank&quot;&gt;kinto&lt;/a&gt; if you&#39;re interested in mac-style hotkeys on Linux and Windows!&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;References&lt;/b&gt;&lt;/p&gt;&lt;p&gt;[1] &lt;a href=&quot;https://opensource.com/article/18/11/how-swap-ctrl-and-caps-lock-your-keyboard&quot; target=&quot;_blank&quot;&gt; How to swap Ctrl and Caps Lock keys in Linux&lt;/a&gt;&lt;/p&gt;&lt;p&gt;[2] &lt;a href=&quot;https://unix.stackexchange.com/q/43976&quot; target=&quot;_blank&quot;&gt;List all valid kbd layou ts, variants and toggle options (to use with setxkbmap)&lt;/a&gt;&lt;/p&gt;&lt;p&gt;[3] &lt;a href=&quot;https://unix.stackexchange.com/a/75492&quot; target=&quot;_blank&quot;&gt;How to prevent the caps-lock toggle effect, without remapping or disabling it?&lt;/a&gt;&lt;/p&gt;&lt;p&gt;[4]&amp;nbsp;&lt;a href=&quot;https://unix.stackexchange.com/a/353699&quot; target=&quot;_blank&quot;&gt;Map right alt to left control&lt;/a&gt; &lt;br /&gt;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.carsoncheng.ca/feeds/3172375838550475776/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/713602603894920874/3172375838550475776' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/713602603894920874/posts/default/3172375838550475776'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/713602603894920874/posts/default/3172375838550475776'/><link rel='alternate' type='text/html' href='http://blog.carsoncheng.ca/2021/02/remap-one-key-to-another-in-linux-like.html' title='Remap one key to another in Linux, like Capslock to Control'/><author><name>blogger</name><uri>http://www.blogger.com/profile/09586588053165570068</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-713602603894920874.post-7399475558950399192</id><published>2021-02-02T21:33:00.190-08:00</published><updated>2021-02-02T21:33:00.794-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Computer-Tech"/><category scheme="http://www.blogger.com/atom/ns#" term="Windows-OS"/><title type='text'>Enable 3 Finger Drag on Windows</title><content type='html'>&lt;p&gt;&lt;b&gt;3 Finger Drag (3FD) is not available on Windows&lt;/b&gt;&lt;b&gt;, and not built-in on Linux&lt;/b&gt; &lt;br /&gt;&lt;/p&gt;&lt;p&gt;For Linux support, I&#39;ll write another post in the future. &lt;br /&gt;&lt;/p&gt;&lt;p&gt;On Windows, we can achieve something similar.&amp;nbsp; Let&#39;s call this:&amp;nbsp; &lt;b&gt;3 Finger Tap to Drag Lock&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;It&#39;s Dakshin&#39;s idea [1], refined further [2] and tweaked below.&lt;b&gt; &lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;What&#39;s 3FD anyway?&lt;/b&gt; &lt;br /&gt;&lt;/p&gt;&lt;p&gt;3 Finger Drag refers to a Mac accessibility feature.&amp;nbsp; When enabled, if you place three fingers on the Mac&#39;s trackpad or touchpad, then move those fingers in unison on the trackpad, the mouse pointer behave as if you left-clicked-and-are-dragging.&lt;/p&gt;&lt;p&gt;It&#39;s a better more ergonomic alternative to the tap-twice-and-drag method that&#39;s common on Macs, Windows, and Linux.&lt;/p&gt;&lt;p&gt;It&#39;s better because there&#39;s less finger tapping movement which can develop into &quot;trigger finger&quot; type repetitive strain injury.&amp;nbsp; If you drag things around a lot, tap-twice-and-drag plus another tap to deactivate dragging starts to add up to being a nuisance!&lt;br /&gt;&lt;/p&gt;&lt;p&gt;And at least for me, when dragging using the&amp;nbsp; tap-twice-and-drag gesture, I often have trouble continuing to drag mid-drag if I lift my hand away from the trackpad to reposition.&amp;nbsp; And ironically, I also have trouble disengaging the drag once I&#39;ve reached the target of the drag motion too!&lt;/p&gt;&lt;p&gt;&lt;b&gt;3 Finger Tap to Drag Lock (3FTD) on Windows&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;The gesture allows you to tap on the trackpad with 3 fingers, which will &quot;lock&quot; the left click down.&amp;nbsp; Then you can use 1 finger to move the cursor around, thus dragging what&#39;s clicked on!&amp;nbsp; A single tap again will disengage it.&lt;/p&gt;&lt;p&gt;You&#39;ll need to install &lt;a href=&quot;https://www.autohotkey.com/&quot; target=&quot;_blank&quot;&gt;AutoHotKey&lt;/a&gt; (AHK) as this is a script continuously running in the background to make it happen.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Installing the AHK Script&lt;/b&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Make a text file and copy the script below into it, then save the text file with a &lt;b&gt;.ahk&lt;/b&gt; file extension.&amp;nbsp; Double click the .ahk script file and AutoHotKey will run it to give you this 3FTD behaviour.&lt;/p&gt;&lt;p&gt;If you want the script to run every time you log in to Windows, you&#39;ll need to move the script or add a shortcut to it into the Windows startup folder.&amp;nbsp; See &lt;a href=&quot;https://www.maketecheasier.com/schedule-autohotkey-startup-windows/&quot; target=&quot;_blank&quot;&gt;detailed instructions&lt;/a&gt; [3] for that.&lt;/p&gt;&lt;p&gt;&lt;b&gt;ThreeFingerTapDragLock.ahk&lt;/b&gt;&lt;/p&gt;
&lt;code&gt;&lt;pre&gt;#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn  ; Enable warnings to assist with detecting common errors.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.

#SingleInstance force

drag_enabled := false

; Key combo for 4 finger tap:  #^+F24
#^+F22:: ; 3 finger tap
    if (drag_enabled) 
        Click, Up
    else
        Click, Down
    drag_enabled := !drag_enabled
return

#If drag_enabled
LButton::
    Click, Up
    drag_enabled := false
return
#If
&lt;/pre&gt;&lt;/code&gt;
&lt;p&gt;&lt;b&gt;Limitations of this script: games and VirtualBox&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Chances are, this script won&#39;t work inside games.&amp;nbsp; Many games access the mouse and keyboard at a lower level than what AHK can effectively manipulate, or has anti-scripting functionality built-in.&lt;/p&gt;&lt;p&gt;AHK also doesn&#39;t play nice with VirtualBox since it&#39;s virtualizing the keyboard and mouse for the guest OS!&lt;/p&gt;&lt;p&gt;To avoid problems with VirtualBox, I tweaked the above script so it only works outside of it:&lt;/p&gt;&lt;p&gt;&lt;b&gt;ThreeFingerTapDragLock_OutsideVBox.ahk&lt;/b&gt;&lt;/p&gt;
&lt;code&gt;&lt;pre&gt;#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn  ; Enable warnings to assist with detecting common errors.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.

#SingleInstance force

drag_enabled := false

#If !WinActive(&quot;ahk_exe VirtualBoxVM.exe&quot;)
; Key combo for 4 finger tap:  #^+F24
#^+F22:: ; 3 finger tap
    if (drag_enabled) 
        Click, Up
    else
        Click, Down
    drag_enabled := !drag_enabled
return


#If drag_enabled &amp;amp;&amp;amp; !WinActive(&quot;ahk_exe VirtualBoxVM.exe&quot;)
LButton::
    Click, Up
    drag_enabled := false
return
#If
&lt;/pre&gt;&lt;/code&gt;
&lt;p&gt;&lt;b&gt;Note about the Key combo&lt;/b&gt;&lt;/p&gt;&lt;p&gt;My trackpad&#39;s 3 finger tap sends the key combo Win+Ctrl+Shift+F22.&lt;/p&gt;&lt;p&gt;And it&#39;s F24 instead of F22 if I 4 finger tap.&lt;/p&gt;&lt;p&gt;So the Key combo in the scripts above can be easily changed if you prefer a 4 finger instead of 3 finger gestures.&lt;/p&gt;&lt;p&gt;But also, if your laptop or vendor trackpad is different, you&#39;ll have to use AHK to find out the appropriate key combo to put in the script instead.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;References&lt;/b&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;[1] &lt;a href=&quot;https://medium.com/@dakshin.k1/enable-3-finger-gesture-for-click-and-drag-on-windows-and-linux-cd7165b66851&quot; target=&quot;_blank&quot;&gt;Enable 3 Finger Gesture for click and drag on Windows and Linux&lt;/a&gt;&lt;/p&gt;&lt;p&gt;[2] &lt;a href=&quot;https://stackoverflow.com/a/65307232&quot; target=&quot;_blank&quot;&gt;AutoHotKey - Three finger dragging script causing minor issue, how to fix?&lt;/a&gt;&lt;/p&gt;&lt;p&gt;[3] &lt;a href=&quot;https://www.maketecheasier.com/schedule-autohotkey-startup-windows/&quot; target=&quot;_blank&quot;&gt; How to Schedule AutoHotKey to Start Up with Windows&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.carsoncheng.ca/feeds/7399475558950399192/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/713602603894920874/7399475558950399192' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/713602603894920874/posts/default/7399475558950399192'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/713602603894920874/posts/default/7399475558950399192'/><link rel='alternate' type='text/html' href='http://blog.carsoncheng.ca/2021/02/enable-3-finger-drag-on-windows.html' title='Enable 3 Finger Drag on Windows'/><author><name>blogger</name><uri>http://www.blogger.com/profile/09586588053165570068</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-713602603894920874.post-5024873238642100186</id><published>2021-01-27T19:09:00.124-08:00</published><updated>2021-01-27T19:09:08.019-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Computer-Tech"/><category scheme="http://www.blogger.com/atom/ns#" term="Windows-OS"/><title type='text'>How to disable Lenovo Fn-Tab Magnifier Hotkey</title><content type='html'>&lt;p&gt;Lenovo makes some great laptops, like their ThinkPad T series.&lt;/p&gt;&lt;p&gt;But who&#39;s brilliant idea was it to &quot;hard&quot; wire the Fn-Tab key combo at a low level to activate the Windows Magnifier?&lt;/p&gt;&lt;p&gt;This annoying behaviour can&#39;t be remapped away with AutoHotKeys.&lt;/p&gt;&lt;p&gt;Lenovo&#39;s Vantage program calls them Hidden Keyboard Functions.&amp;nbsp; They&#39;re aware some people have a tendency to mistype Fn for Ctrl, so they offer a &quot;Fn and Ctrl key swap&quot; option instead.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Two ways to disable Fn-Tab Magnifier behaviour&lt;/b&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;(1) Disable permanently by changing the Magnify app&#39;s name&lt;/b&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;You can take file ownership of the Magnifier app, then change it&#39;s name from Magnify.exe to something else (e.g. Magnify.exe.bu as a backup).&lt;/p&gt;&lt;p&gt;That way, Fn-Tab can&#39;t find the Magnify app!&lt;/p&gt;&lt;p&gt;But Windows&#39;s own key combo won&#39;t find it either!&amp;nbsp; Congrats, you&#39;ve disabled the Magnify hotkey permanently.&lt;/p&gt;&lt;p&gt;Detailed instructions can be found elsewhere [2] labelled as &quot;method 2&quot; (different than my # 2 below).&lt;/p&gt;&lt;p&gt;I don&#39;t like this method because I still want the Windows hotkey to bring up the Magnifier.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;(2) Disable only the Fn-Tab hotkey&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Inspired by a similar question from way way back [3], I found out the Fn-Tab hotkey will open any app who&#39;s path is entered into a specific Windows Registry entry!&lt;/p&gt;&lt;p&gt;Specifically, this Registry entry:&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;margin-left: 40px; text-align: left;&quot;&gt;HKEY_LOCAL_MACHINE\SOFTWARE\Lenovo\ShortcutKey\AppLaunch\Ex_13\UIAccess&lt;br /&gt;&lt;/p&gt;&lt;p&gt;The key name &quot;File&quot; by default has the data value:&lt;/p&gt;&lt;p style=&quot;margin-left: 40px; text-align: left;&quot;&gt;%SystemRoot%\system32\magnify.exe&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Well if you change that to:&lt;/p&gt;&lt;p style=&quot;margin-left: 40px; text-align: left;&quot;&gt;%SystemRoot%\system32\magnify.exe.bak&lt;/p&gt;&lt;p&gt;Then Fn-Tab won&#39;t find the magnify app and won&#39;t do anything!&amp;nbsp; In fact, you should be able to make Fn-Tab launch any app you want using this technique!&lt;/p&gt;&lt;p&gt;If you&#39;re trusting and lazy, and want an easy way to enable or disable the Lenovo Fn-Tab behaviour, save the following into text files and change the file extension to &lt;b&gt;.reg&lt;/b&gt; so that you can double click the file to make the above registry edit for you:&lt;/p&gt;&lt;p&gt;&lt;b&gt;EnableLenovoFnTabMagnify.reg&lt;/b&gt;&lt;/p&gt;
&lt;code&gt;&lt;pre&gt;Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Lenovo\ShortcutKey\AppLaunch\Ex_13\UIAccess]
&quot;File&quot;=hex(2):25,00,53,00,79,00,73,00,74,00,65,00,6d,00,52,00,6f,00,6f,00,74,\
  00,25,00,5c,00,73,00,79,00,73,00,74,00,65,00,6d,00,33,00,32,00,5c,00,6d,00,\
  61,00,67,00,6e,00,69,00,66,00,79,00,2e,00,65,00,78,00,65,00,00,00
&quot;Parameters&quot;=&quot;&quot;
&lt;/pre&gt;&lt;/code&gt;

&lt;p&gt;&lt;b&gt;DisableLenovoFnTabMagnify.reg&lt;/b&gt;&lt;br /&gt;&lt;/p&gt;
&lt;code&gt;&lt;pre&gt;Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Lenovo\ShortcutKey\AppLaunch\Ex_13\UIAccess]
&quot;File&quot;=hex(2):25,00,53,00,79,00,73,00,74,00,65,00,6d,00,52,00,6f,00,6f,00,74,\
  00,25,00,5c,00,73,00,79,00,73,00,74,00,65,00,6d,00,33,00,32,00,5c,00,6d,00,\
  61,00,67,00,6e,00,69,00,66,00,79,00,2e,00,65,00,78,00,65,00,2e,00,62,00,61,\
  00,6b,00,00,00
&quot;Parameters&quot;=&quot;&quot;
&lt;/pre&gt;&lt;/code&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;References&lt;/b&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;[1] &lt;a href=&quot;https://forums.lenovo.com/t5/ThinkPad-X-Series-Laptops/Fn-TAB-brings-up-Magnifier/m-p/4405553?page=1#4564296&quot; target=&quot;_blank&quot;&gt;Fn-TAB brings up Magnifier&lt;/a&gt;&lt;/p&gt;&lt;p&gt;[2] &lt;a href=&quot;https://www.top-password.com/blog/turn-off-disable-magnifier-in-windows-10/&quot; target=&quot;_blank&quot;&gt;3 Ways to Turn Off / Disable Magnifier in Windows 10&lt;/a&gt;&lt;/p&gt;&lt;p&gt;[3] &lt;a href=&quot;https://www.eehelp.com/question/full-of-thinkpad-fn-spacebar-screen-magnifier/&quot; target=&quot;_blank&quot;&gt;Full of ThinkPad (Fn + SPACEBAR) screen magnifier&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.carsoncheng.ca/feeds/5024873238642100186/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/713602603894920874/5024873238642100186' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/713602603894920874/posts/default/5024873238642100186'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/713602603894920874/posts/default/5024873238642100186'/><link rel='alternate' type='text/html' href='http://blog.carsoncheng.ca/2021/01/how-to-disable-lenovo-fn-tab-magnifier.html' title='How to disable Lenovo Fn-Tab Magnifier Hotkey'/><author><name>blogger</name><uri>http://www.blogger.com/profile/09586588053165570068</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-713602603894920874.post-9013396142519226527</id><published>2021-01-20T15:40:00.043-08:00</published><updated>2021-03-26T20:51:59.940-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Computer-Tech"/><category scheme="http://www.blogger.com/atom/ns#" term="Keyboard"/><category scheme="http://www.blogger.com/atom/ns#" term="Mac"/><category scheme="http://www.blogger.com/atom/ns#" term="Windows-OS"/><title type='text'>Remap one key to another in Windows, like Capslock to Control</title><content type='html'>&lt;p&gt;There&#39;s three options to consider for remapping keys on Windows.&lt;/p&gt;&lt;p&gt;&lt;b&gt;(1) Manually edit the Windows Registry&lt;/b&gt; &lt;br /&gt;&lt;/p&gt;&lt;p&gt;You can directly edit the Windows registry to remap keys, for example to &lt;a href=&quot;https://superuser.com/a/949533&quot; target=&quot;_blank&quot;&gt;Map capslock to control&lt;/a&gt;.&amp;nbsp; You&#39;ll need to know the keyboard hex scan codes involved though.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;(2) Edit the Windows Registry with SharpKeys&lt;/b&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;If you have many keys to remap, or don&#39;t want to manually mess with the registry, there&#39;s an App for that!&amp;nbsp; &lt;a href=&quot;https://github.com/randyrants/sharpkeys&quot; target=&quot;_blank&quot;&gt;SharpKeys&lt;/a&gt; looks pretty good.&amp;nbsp; You can use it to remap the Right Alt to the Left Windows key for example.&lt;/p&gt;&lt;p&gt;&lt;b&gt;(3) Don&#39;t edit the Registry but run a background app like PT or AHK&lt;/b&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Some common remappings like Capslock to control can be easily done without editing the registry at all!&amp;nbsp; You can run an app that stays in the background, listening for the keys you want changed, then they&#39;ll inject the key you want for it to change to.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Microsoft&#39;s &lt;a href=&quot;https://github.com/microsoft/PowerToys&quot; target=&quot;_blank&quot;&gt;PowerToys&lt;/a&gt; has a module for that sort of usage, and it comes with other toys like advanced file name changer, etc.&amp;nbsp; The kind of key remapping allowed is extremely limited though.&lt;br /&gt;&lt;/p&gt;&lt;p&gt; Another option is &lt;a href=&quot;https://www.autohotkey.com/&quot; target=&quot;_blank&quot;&gt;AutoHotKey&lt;/a&gt; (AHK).&amp;nbsp; It&#39;ll  give you extreme customization beyond remapping a single key to a single key.&amp;nbsp; It&#39;ll let you script keys and combos to do pretty much arbitrary things to the keyboard and mouse.&lt;/p&gt;&lt;p&gt;Don&#39;t run both PowerToys keyboard remapping module &lt;i&gt;and&lt;/i&gt; AHK key remappings together as they may interfere with each other!&lt;/p&gt;&lt;p&gt;(&lt;i&gt;&lt;b&gt;NEW!&lt;/b&gt;&lt;/i&gt;)&amp;nbsp; Check out &lt;a href=&quot;https://github.com/rbreaves/kinto&quot; target=&quot;_blank&quot;&gt;kinto&lt;/a&gt; if you&#39;re interested in mac-style hotkeys on Linux and Windows!&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Remap Capslock to Control with AutoHotKey&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Make a text file and copy the script below into it, then save the text file with a &lt;b&gt;.ahk&lt;/b&gt; file extension.&amp;nbsp; Double click the .ahk script file and AutoHotKey will run it to give you this 3FTD behaviour.&lt;br /&gt;&lt;br /&gt;If you want the script to run every time you log in to Windows, you&#39;ll need to move the script or add a shortcut to it into the Windows startup folder.&amp;nbsp; See &lt;a href=&quot;https://www.maketecheasier.com/schedule-autohotkey-startup-windows/&quot; target=&quot;_blank&quot;&gt;detailed instructions&lt;/a&gt; for that. &lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;CapslockAsControl.ahk&lt;/b&gt;&lt;/p&gt;
&lt;code&gt;&lt;pre&gt;#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn  ; Enable warnings to assist with detecting common errors.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.

#SingleInstance force

Capslock::Ctrl
&lt;/pre&gt;&lt;/code&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;h1 style=&quot;text-align: left;&quot;&gt;&lt;b&gt;Limitations to all methods&lt;br /&gt;&lt;/b&gt;&lt;/h1&gt;&lt;p&gt;&lt;b&gt;Some Windows hotkeys cannot be remapped!&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Key combos like Windows key + L are dealt with by the Windows OS at a much lower level and treated specially.&amp;nbsp; Those cannot be remapped by PowerToys or AHK, at least not normally or usefully.&lt;/p&gt;&lt;p&gt;You could disable Win+L completely by disabling the Windows lock screen function [1].&amp;nbsp; But then your computer will never lock... ever.&amp;nbsp; Not when waking from sleep, not from the Control + Alt + Delete menu.&amp;nbsp; It&#39;s all or nothing.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Some apps don&#39;t allow / respect the remapping&lt;/b&gt;s&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Also apps that access the keyboard at a lower level, like some games and VirtualBox, don&#39;t play nice with AHK remappings.&lt;/p&gt;&lt;p&gt;Games access keyboards in a way that reduces latency to increase gaming responsiveness. And some games have anti-scripting functionality to discourage cheating.&lt;/p&gt;&lt;p&gt;VirtualBox is virtualizing your PC for another OS so a Windows background app messing with the keyboard of course won&#39;t play nice with VirtualBox.&amp;nbsp; And yes, Win+L will lock Windows even if you&#39;re inside a Linux guest in VirtualBox!&lt;/p&gt;&lt;p&gt;&lt;b&gt;Vendor hotkeys can&#39;t be remapped&lt;/b&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;There are vendor specific keys and combos that your PC maker may have added via their keyboard drivers.&amp;nbsp; Like Lenovo&#39;s Fn+Tab starts the Windows magnifier key combo.&amp;nbsp; Press that while in a VirtualBox guest OS and it&#39;ll still run the magnifier!&lt;/p&gt;&lt;p&gt;Neither AHK nor PowerToys can remap the Fn+Tab combo either.&amp;nbsp; In fact, remapping the Fn key is usually tough if not impossible.&amp;nbsp; It&#39;s something handled specially by vendor&#39;s drivers on laptops to provide special functionality.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;&lt;h1 style=&quot;text-align: left;&quot;&gt;&lt;b&gt;Compared to Macs&lt;/b&gt; &lt;br /&gt;&lt;/h1&gt;&lt;p&gt;&lt;b&gt;Scripting with AppleScript&lt;/b&gt; &lt;br /&gt;&lt;/p&gt;&lt;p&gt;Coming from the Mac world where &lt;a href=&quot;https://en.wikipedia.org/wiki/AppleScript&quot; target=&quot;_blank&quot;&gt;AppleScript&lt;/a&gt; lets you implement customized and scripted automation of tasks, AutoHotKey (AHK) is similar in many ways.&amp;nbsp; Since AppleScript can be substituted with JavaScript, then the scripting language itself is better than AHK.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;However, AppleScript doesn&#39;t provide hooks to customize or remap keys and key combos, so AHK does have this feature AppleScript doesn&#39;t.&lt;/p&gt;&lt;p&gt;On the flip side, Mac apps that make extensive use of Apple&#39;s &lt;a href=&quot;https://en.wikipedia.org/wiki/AppleScript#Open_Scripting_Architecture&quot; target=&quot;_blank&quot;&gt;Open Scripting Architecture&lt;/a&gt; allow AppleScripts to directly access certain data inside those apps for better integration.&amp;nbsp; Not every or many apps support advanced OSA usage, but it gives AppleScript an edge.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Remapping with Karabiner&lt;/b&gt; &lt;br /&gt;&lt;/p&gt;&lt;p&gt;As for providing key and combo remapping, I&#39;m finding &lt;a href=&quot;https://karabiner-elements.pqrs.org/&quot; target=&quot;_blank&quot;&gt;Karabiner-Elements&lt;/a&gt; on Macs to be better for that job than AHK.&lt;/p&gt;&lt;p&gt;Karabiner is more intuitive, purpose built for remapping keys, with many of the same AHK features for multi-key remapping.&amp;nbsp; It can also run scripts on key triggers like AHK, so Karabiner + AppleScript is roughly equivalent to AHK&#39;s functionality.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Less limitations&lt;/b&gt; &lt;br /&gt;&lt;/p&gt;&lt;p&gt;Macs have less limitations than Windows on the key remapping front too.&amp;nbsp; You&#39;ll have no problems using Karabiner-Elements to remap the &quot;Apple key&quot; (command key) vs the difficulties of remapping the Windows key (especially special combos like Win+L).&lt;/p&gt;&lt;p&gt;Key remappings with Karabiner on Macs are also respected by VirtualBox unlike remappings done via AHK on Windows.&amp;nbsp; To be fair, some AHK key remappings do work with VirtualBox, but I had trouble with modifier keys and special Windows hotkeys.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;References&lt;/b&gt;&lt;/p&gt;&lt;p&gt;[1] &lt;a href=&quot;https://www.faqforge.com/windows/windows-10/how-to-disable-windows-10-workstation-lock-window-l-functionality/&quot; target=&quot;_blank&quot;&gt;How to disable Windows 10 Workstation Lock (Window + L) Functionality&lt;/a&gt;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.carsoncheng.ca/feeds/9013396142519226527/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/713602603894920874/9013396142519226527' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/713602603894920874/posts/default/9013396142519226527'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/713602603894920874/posts/default/9013396142519226527'/><link rel='alternate' type='text/html' href='http://blog.carsoncheng.ca/2021/01/remap-one-key-to-another-in-windows.html' title='Remap one key to another in Windows, like Capslock to Control'/><author><name>blogger</name><uri>http://www.blogger.com/profile/09586588053165570068</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-713602603894920874.post-1722281405022395977</id><published>2021-01-12T19:24:00.004-08:00</published><updated>2021-01-12T19:24:01.273-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Java"/><category scheme="http://www.blogger.com/atom/ns#" term="Programming"/><title type='text'>My app uses only java.base, but actually jdeps missed the jdk.crypto.cryptoki module!</title><content type='html'>&lt;p&gt;I was building a small app and I purposely used only the &lt;b&gt;java.base&lt;/b&gt; module.&amp;nbsp; That way when I build a custom Java Runtime for it, I can build the smallest possible runtime with &lt;i&gt;jlink&lt;/i&gt;.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Java&#39;s &lt;i&gt;jdeps&lt;/i&gt; lets you know which module your app depends on, and it said my app only uses the &lt;i&gt;java.base&lt;/i&gt; module.&amp;nbsp;&lt;/p&gt;&lt;p&gt;Build the runtime with &lt;i&gt;jlink&lt;/i&gt; and run my app with it and &lt;i&gt;oops&lt;/i&gt;, an error having to do with &lt;i&gt;cryptoki&lt;/i&gt;.&lt;/p&gt;&lt;p&gt;Turns out &lt;i&gt;jdeps&lt;/i&gt; made a mistake and did not identify the &lt;b&gt;jdk.crypto.cryptoki&lt;/b&gt; module!&lt;/p&gt;&lt;p&gt;I suspect my use of the &lt;b&gt;java.net.URI&lt;/b&gt; class was to blame, as it was used to access an &lt;i&gt;https&lt;/i&gt; URL.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Anyway, if you purposely depend only on the &lt;b&gt;java.base&lt;/b&gt; module, but also use the &lt;b&gt;URI&lt;/b&gt; class, note that it may actually also depend on the &lt;a href=&quot;https://docs.oracle.com/javase/9/docs/api/jdk.crypto.cryptoki-summary.html&quot;&gt;&lt;b&gt;jdk.crypto.cryptoki&lt;/b&gt;&lt;/a&gt; module!&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.carsoncheng.ca/feeds/1722281405022395977/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/713602603894920874/1722281405022395977' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/713602603894920874/posts/default/1722281405022395977'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/713602603894920874/posts/default/1722281405022395977'/><link rel='alternate' type='text/html' href='http://blog.carsoncheng.ca/2021/01/my-app-uses-only-javabase-but-actually.html' title='My app uses only java.base, but actually jdeps missed the jdk.crypto.cryptoki module!'/><author><name>blogger</name><uri>http://www.blogger.com/profile/09586588053165570068</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-713602603894920874.post-1823270633679692336</id><published>2021-01-06T19:02:00.002-08:00</published><updated>2021-01-06T19:02:04.385-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Java"/><category scheme="http://www.blogger.com/atom/ns#" term="Programming"/><title type='text'>Build your own custom Java Runtime with jlink and jdeps</title><content type='html'>&lt;p&gt;Since Java 9, the way Java programs are supposed to be distributed changed.&lt;/p&gt;&lt;p&gt;It used to be that users would install a Java Runtime Environment (JRE) on their system.&amp;nbsp; The user then gets the Java app from the app developer.&amp;nbsp; The Java app then runs on the JRE that&#39;s installed.&lt;/p&gt;&lt;p&gt;Some OS like Macs used to even have a &quot;system&quot; JRE installed as part of the OS.&lt;/p&gt;&lt;p&gt;The world&#39;s moved on from that style of app distribution.&amp;nbsp; Nowadays, many users want statically compiled programs, or a single executable file with no dependencies.&amp;nbsp; For better or worse.&lt;/p&gt;&lt;p&gt;That means when you develop a Java app and want to distribute it, it&#39;s on you as the developer to create your own custom Java Runtime and package that runtime together with the rest of your app for distribution.&lt;/p&gt;&lt;p&gt;The upshot is that if you don&#39;t use too much of the Java standard library and customize your Java Runtime, then you pay for only what you use in terms of the size of the Java runtime you need to package with your app.&lt;/p&gt;&lt;p&gt;You can find what Java modules your app depends on using &lt;b&gt;jdeps&lt;/b&gt; easily: &lt;code&gt;jdeps my.jar&lt;/code&gt;&lt;/p&gt;&lt;p&gt;Then you can use &lt;b&gt;jlink&lt;/b&gt; to create the Java Runtime your app needs: &lt;code&gt;jlink --output my-custom-runtime --add-modules java.base,and.other.modules&lt;/code&gt;&lt;/p&gt;&lt;p&gt;Then you can run your app with the custom Java Runtime: &lt;code&gt;/path/to/my-custom-runtime/bin/java -jar my.jar&lt;/code&gt;&lt;/p&gt;&lt;p&gt;The Java Runtime that &lt;i&gt;jlink&lt;/i&gt; creates is specific to the OS platform you ran &lt;i&gt;jlink&lt;/i&gt; on.&amp;nbsp; So on Windows, you&#39;ll have to substitute &lt;i&gt;java.exe&lt;/i&gt; for &lt;i&gt;java&lt;/i&gt; in the path above.&lt;/p&gt;&lt;p&gt;There&#39;s a way to cross-compile a Java Runtime for a different OS platform with &lt;i&gt;jlink&lt;/i&gt;, but you&#39;ll need to download the target platform&#39;s JDK.&amp;nbsp; It was easier to run the target platform&#39;s OS in a virtual machine and run &lt;i&gt;jlink&lt;/i&gt; on it instead.&lt;/p&gt;&lt;p&gt;A thorough and detailed tutorial is &lt;a href=&quot;https://www.devdungeon.com/content/how-create-java-runtime-images-jlink&quot; target=&quot;_blank&quot;&gt;How to Create Java Runtime Images with jlink&lt;/a&gt;.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.carsoncheng.ca/feeds/1823270633679692336/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/713602603894920874/1823270633679692336' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/713602603894920874/posts/default/1823270633679692336'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/713602603894920874/posts/default/1823270633679692336'/><link rel='alternate' type='text/html' href='http://blog.carsoncheng.ca/2021/01/build-your-own-custom-java-runtime-with.html' title='Build your own custom Java Runtime with jlink and jdeps'/><author><name>blogger</name><uri>http://www.blogger.com/profile/09586588053165570068</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>