1. 59
  1. 9

    It’s interesting that although both Firefox and Emacs are officially “Free Software”, doing something like this is far more time consuming and difficult. There’s obviously a gradient here, within the category.

    For example, what I’d say is if Firefox could detect that the Emacs keybindings are used (I have no experience with how it’s internally built up) it should know to disable C-n like in your example, or C-w too, which is far more annoying from my experience with the same setup, since instead of cutting (or in Emacs’ish killing a region) you close a tab. I have no idea where to start with this, if I would want to do this. So I do have the formal freedom to change something (and wait a few hours for it to compile), and I guess I could hire someone to do it for me, but I don’t have the real ability, the actual interdependence to do this on a regular basis, which from my experience with Emacs is what Free Software is thinking about, when they talk about the freedom to change and improve something.

    1. 10

      Yes, I completely agree. It’s very rare to actually exercise software freedom. I almost never do it and almost no one else does either. There had to be a huge activation energy of being sufficiently annoyed to want to see this change through and being confident enough to see a way to do it.

      Firefox is quite a scary codebase too. It goes way back to the mid 90s. It even has a Y2K disclaimer:


      If I hadn’t gotten help in IRC, I probably wouldn’t have been able to do this without giving up. I was so sure that the XUL was a red herring.

      I think there’s an important conversation to be had here about the practicality of actually exercising software freedom, so that’s why I was rather deliberate about using that phrase.

      1. 8

        I “disabled” C-w by rebinding Ctrl to Alt. Well, something along those lines, at least. Go into about:config and change the property ui.key.accelKey to 18 (works on my keyboard, don’t know if right answer in general). This was once upon a time the default in Unix Mozilla before someone somewhere decided that Linux users must all be Windows refugees.

        As a side note, this works for “new window” too, which on my computer is now Alt-N not Ctrl-N.

        1. 1

          That’s interesting, but there’s still M-w to copy and I’m really used to C-t to open a tab, which was what I was talking about.

        2. 6

          It’s interesting that although both Firefox and Emacs are officially “Free Software”, doing something like this is far more time consuming and difficult.

          The irony of this is that the whole point of building on XUL is to make changes like this easier, (after all, jwz was an early Netscape employee who at the time was best-known for his work on xemacs) but somehow defeat was snatched from the jaws of victory somewhere along the line, and now edits to the XUL do not take effect without spending 2 hours recompiling the entire codebase.

        3. 7

          The development iteration cycle for Firefox is pretty shameful. Since you were only touching XUL, you really didn’t need to do those multiple, hour+ long builds. You could have popped open those files in Emacs—because they’re just text and remain text, even after being converted into build artifacts—then edited and saved them and tested your changes.

          As one longtime contributor once said, and I’m paraphrasing, touching the Mozilla codebase sucks and testing your changes is too slow, “that’s why [he] decided to do as much as [he] can in XUL and JS [instead of C++ which does require doing a proper rebuild]”.

          The reality is that it doesn’t have to be this way, that all the plaintext declaration, configuration, and logic could be as easily editable as your elisp customizations, but to even get to the point where your plaintext changes are picked up means you have to (a) already have some familiarity and insight to mozilla internals to figure out how to make that happen; and (b) still have to spend, the first time during your setup, maybe a quarter of the length that a single build would have taken, and where you instead are having to poke at configuration options, setting up symlinks, and writing swapout scripts.

          This is a more general problem—more projects than just Mozilla are afflicted and not necessarily in regard to the specifics I’m describing here—but there is a commonality among them. I wrote a little bit about this problem before in a brief post titled Nobody wants to work on infrastructure. I make the case that if you have a project, especially one with funding, then not directing your paid help towards building the necessary infrastructure to ease the lives of your unpaid help is “like finding a genie and not checking to see if your first wish could be for more wishes”. The Oil Shell maintainer last year pointed out that this is given a little bit of coverage in a chapter of CATB, and Andy Chu from oilshell.org refers to it as “parallelizing” the project’s development. (You’ll be interested, maybe, in how one of ESR’s examples is in the MATLAB community, to the extent that any openness exists there.)

          This is something I’ve spent a lot of time thinking about over the last year, and maybe a tenth of that time writing code and experiments. triplescripts.org is going to launch towards these purposes and will exist as one part tool “vendor” (as a FOSS project), and two parts advocacy group meant to organize and promote the ideals of the group, even if you aren’t using the tooling. With regard to the specifics of the suggestions coming out of the group, I expect there will be intense pushback, but it’s plain as day to me that this is how things will evolve—because they have to, because nobody has enough time to waste away on the setup involved in the “implicit step zero” for every project they want to dive into—and because those projects that do evolve in that direction will be able to outpace those that don’t, and will end up thriving at a great advantage, just like natural selection’s role in real world biological evolution.

          1. 8

            The development iteration cycle for Firefox is pretty shameful. Since you were only touching XUL, you really didn’t need to do those multiple, hour+ long builds.

            That’s not really fair as OP was using apt build-dep rather than set up Firefox’s development environment. From the article:

            I didn’t want to figure out how to clone its repo, how to setup a development environment, how to configure the build, what kinds of builds there are, and how to integrate all of this with my operating system. Luckily, someone else has already done all of this work for me: the Debian packagers.

            I’m not saying OP made the wrong decision for his use case or anything, but we do put a lot of energy into improving Firefox’s development experience (this is coincidentally what I work on, though not so much build related). It sounds like people on IRC were suggesting the appropriate build type (artifact builds) for this use case. Fwiw, my build times are typically ~1-2min.

            1. 4

              I still think it is shameful, although it’s mostly not Mozilla’s fault. It’s just that Firefox is written in C++ and C++ ecosystem lacks uniform build system and therefore C++ projects are uniquely hostile to casual contributors.

            2. 5

              Firefox incremental builds usually take about three minutes for me. Mach still does a little bit more crap than just rebuild changed files and relink, but it’s not like building from scratch. It’s still not instant, linking libxul (especially with debug info) even with lld takes a minute or two (or more on a slower CPU), but it’s not hours.

              OS package build systems are designed for correctness and reproducibility, not for development. They want you to always just nuke the whole build directory and start over. There are sometimes ways around that. In FreeBSD Ports, you can rm work/.build_done* and make restage reinstall :)

              BTW, the web inspector works on XUL, but I’m not sure if keybindings could be changed from there.

              1. 1

                I figured there was some processing to be done on the XUL files after the build. When I look at the list of files in the Debian package, I don’t see anything obvious in there that corresponds to the files I modified. It was easier to wait a total of six hours for the build and do something else in the meantime (I watched some TV) than to try to figure out how to reduce the build times, or avoid building altogether, as you say.

                Man, it would be so cool if Firefox’s config could be as versatile as elisp, but I thought they were explicitly moving away from that by locking out extension authors out of XUL?

                And yeah, making the code more easily hackable seems like a huge wish to ask of the genie. I think in general, nobody wants to know how anyone else’s code works. That’s why we build interfaces, abstractions, wrappers: so we can avoid having to figure each other out. It felt to me like Firefox was thriving the most when extension authors could do just that, and I hope the direction they’re taking it is worth it in the end.

                Oh, and I know what you mean about Matlab. The situation there is kind of weird because it’s kind of pseudo-open source in a limited way. Most of Matlab’s source is visible, and your license lets you change it and share it but only with other Matlab license holders. The Matlab language was always intended to be simple enough to allow modification by “non-programmers”, as Matlab users often call themselves.

                It’s a good example. Maybe Julia one day will achieve something similar.

                1. 4

                  I figured there was some processing to be done on the XUL files after the build.

                  I don’t contribute to Mozilla anymore, and I’m not going to dive deep into this case, but from a quick glance at the file paths alone, the .xul and .dtd files will be fully intact, while the .inc files will be preprocessed, but in some trivial way that could be done by hand (e.g., “let’s copy and paste this file’s contents as a block into the file that includes it”). Not frictionless or fun, but still less exasperating (provided that you’ve already got step 0 behind you) than a test-and-debug cycle with latency measured not just in minutes, but on the order of hours.

                  When I look at the list of files in the Debian package, I don’t see anything obvious in there that corresponds to the files I modified.

                  They’re usually ZIPped during the build and end up living in one or more JARs, so you won’t be able to spot them with find(1), but they’re there and accessible to anyone wielding unzip or file-roller.

                  Man, it would be so cool if Firefox’s config could be as versatile as elisp

                  I’m mostly referring to the straightforward, no-build workflow of editing plain text with fast turnaround, rather than any kind of inherent lispiness. In the case of fx, it’d be JSON and JS, not elisp.

                  but I thought they were explicitly moving away from that by locking out extension authors out of XUL? ¶ And yeah, making the code more easily hackable seems like a huge wish to ask of the genie.

                  Right. Like I said, it doesn’t have to be this way. But it really isn’t that big of an ask. Things have moved in the direction of getting worse, not better (hence why I don’t fritter my time away on Mozilla anymore). And Firefox Corp is something like 5–10 times as well-funded now as they were when Firefox was actually effective at being a force for good and demonstrating that it might take over the world, instead of, you know, doing ads and corporate partnerships and then lying about not getting any money.

                  (Caveat: maybe in fact things have changed so much that doing a rebuild really is the only feasible way even for JS and XUL changes. On the other hand, I made a passing comment recently-ish that building Firefox took around 2 hours and some naysayer showed up to say that wasn’t even close to true. I then went off and tested by doing a fresh build, which I hadn’t done in years at that point and even without any particular itch to scratch. Turns out: nope: not wrong. It still took 2 hours.)

                  Even if it were the case that things have really changed so much (and I don’t know whether it’s true, but I’m not going to waste my time again just to find out), that would really only underscore my central claim—we know it doesn’t have to be this way, because it’s a fact that it used to not be; it getting more broken is a recent development, relatively speaking (cf “code from the 90s”).

                  1. 2

                    (hacker of Mozilla codebases)

                    Yes, there is some postprocessing that occurs. Unfortunately mach (the build system) is mostly oriented to developers that are creating the entire enchilada, not focused front end changes without building an entire test browser, so this kind of usage is not well catered to. Good on you for sticking with it.

                    I should add that building Chromium is no picnic, either.

                    1. 13

                      Fixing this kind of problem in Chromium has always been a nightmare; fixing it in Firefox has only been bad since 57.

                      The main difference to me is that when I talk to Mozilla people about it, they reply something like “oh, that’s annoying. it’s too bad it doesn’t work better.” but when I asked Chromium devs about it they said “of course you can’t change the key bindings; can you imagine what kind of crazy bug reports we’d get from users if we let them rebind keys? never going to happen.”

                      1. 3

                        mach (the build system)

                        One thing I liked about my approach is that I didn’t have to learn anything about this. Of course it’s a tradeoff. If I ever really get involved in Firefox development, I’ll need to learn about it. For a one-off thing, though, I was able to remain ignorant.

                        1. 1

                          I wouldn’t say that Mozilla is much better than Chrome in general, maybe in a few limited circumstances.

                          This whole tale reminds me of the time I didn’t exercise software freedom on Firefox, but just switched to a proprietary browser (Vivaldi), because I just couldn’t take Mozilla’s **** anymore. :-/

                          Breaking the world with 57 was bad enough, but when they re-did the navigation bar and changed the navigation bar UI editor to not let you remove elements from the navigation bar? Sorry, that’s just a cruel joke.

                          That’s when I realized that I’m probably not Mozilla’s target audience anymore and moved on after more than 15 years of Phoenix/Firebird/Firefox.

                    2. 5

                      If I’m not mistaken, the XUL pages should be editable as content of omni.ja within a release build directory of Firefox, which could spare you all the building of binary files.

                      Again I might be wrong, but I think you could “just” extract the XUL files from omni.ja, patch them and then deflate again.

                      Hopefully someone in irc.mozilla.org #developers or #build can confirm this.

                      1. 4

                        omni.ja is not quite a ZIP file, although it’s close enough that some unmodified ZIP tools can extract files from it.

                        Apparently you can use unmodified ZIP tools to repack omni.ja, if you’re careful.

                        1. 2
                        2. 4

                          This is true, however it’s not so simple, you also need to purge some caches.


                          1. 3

                            There should be more threads about arcane and obscure Firefox trickery. Thanks! 👍

                        3. 4

                          I don’t think at any point was the addition of Rust touted as a replacement for XUL, they do very different things in Firefox.

                          What happened was that the big release – Firefox Quantum – contained both the introduction of a lot of key Rust code, as well as disabling external XUL as a first step to getting rid of it entirely. People definitely misinterpreted these two things as being “Rust is replacing XUL”, but that’s not the case. Rust replaced a bunch of C++ code.

                          If anything, the dependency chain is the other way around: Completely ripping out the C++ code was blocked on a bunch of XUL stuff going away (or the Rust code getting support for it); until then the old C++ code still had to be around for some special cases.

                          The XUL code is being replaced by more normal HTML/JS, slowly.

                          FWIW if you don’t want to actually build Firefox, most of the Firefox XUL stuff is on your disk in plaintext form, just in a weird zip file that also contains cached “compiled” versions. I’ve edited this and had it work in the past, I think the advice there should still be applicable but I’m not sure.

                          1. 2

                            When I started, I didn’t know that the changes would all be in XUL. I didn’t want to learn anything more than necessary to get my goal done. At the time, it was easier to spend a few hours recompiling than figuring out how not to.

                            Now I wonder, since apparently the only changes I made are in omni.ja, could I just save that file and keep it around for future Firefox updates until they finally rip out XUL?

                            1. 2

                              Could I just save that file and keep it around for future Firefox updates

                              No, that would almost certainly break, omni.ja contains most of the browser UI code and is tied tightly to browser internals

                              But you can keep around a patch and write a script that lets you repatch omni.ja each update

                              until they finally rip out XUL?

                              It doesn’t really matter if they rip out XUL, the code would then be replaced with HTML/JS still living in omni.ja and you’d be able to write your patch to work with that when it changes

                              1. 2

                                could I just save that file and keep it around for future Firefox updates

                                In fact, that was the spirit behind why these things were put in a JAR in the first place—so you could do almost exactly that. The choice to build on XPCOM was deeply tied into that philosophy. In practice, this failed for reasons similar to why semver can fail. People kind of do what they want to do instead of satisfying the constraints that are laid out. And of course, after acknowledging that it never really worked, Mozilla doesn’t pretend to follow that architecture anymore.

                                If you haven’t read Yegge’s old “Pinocchio Problem” yet, it’s a great read in its own right. But extremely relevant to this topic are the parallels he draws wrt systems like Emacs and systems like Firefox.

                            2. 3

                              I wish there were a browser version of Emacs – a fast, native core set of primitives, stitched together in a totally programmable runtime. That seems to me like an achievable vision, and one that could allow for endless asinine fiddling of the sort that I engage in in Elisp when I’m trying to keep from doing work.

                              1. 4
                                1. 2

                                  I’ve been trying to avoid learning new languages unless it’s a different paradigm (thinking shift). Seeing that project a while back got me seriously thinking about learning Lua. Luakit is a great concept.

                                  1. 3

                                    It’s a great concept but on apt-based distributions webkit doesn’t get security updates, so in practice it’s iffy.

                                    Maybe in a few years there’ll be something equivalent based on Servo once that gets packaged and supported.

                                2. 3

                                  never tried it, but you can take a look at Next browser https://github.com/atlas-engineer/next/blob/master/README.org Being written in common lisp, you should be able to connect emacs (slime-mode) to it and hack away.

                                3. 2

                                  Any Mozilla employees/Firefox developers around? What’s the chance of this being merged into Firefox if a proper patch is made, along with all the other bits and pieces necessary to be able to select key bindings from about:preferences?

                                  Nice work JordiGH :) I’d love to have emacs keybindings everywhere.

                                  1. 2

                                    about:preferences seems very unlikely. Maybe you could find someone on IRC supportive to the cause to allow this in about:config?

                                  2. 2

                                    This should be a config option.

                                    1. 1

                                      Wow that’s awesome. I have so many questions, but one surfaces to the top in my mind:

                                      Can you make a build for me that disables shift-ctrl-q?!?!

                                      1. 0

                                        You use arrow keys in emacs? Heathen! :-)