Welcome to Suricrasia Online!

"Connecting your world, whenever!"

Making Firefox Act More Like Chrome

I've been wanting to switch to firefox for a long time, but two pain points have always prevented me from doing so. First, there is a feature on chrome that will search the contents of your primary xclipboard if you center-click on the "new tab" button. I use this feature a lot since it basically means searching from a selection is a two-click process. This process has inexorably seeped into my muscle memory over the last decade, and I'm loathe to part with it. It's just so convenient!

The second "feature" (which firefox users rightly hate) is that chrome has no minimum tab width. You can make 1000 tabs if you want, they'll just end up looking like little grey slivers. On firefox if you make too many tabs the entire tabbar will turn into a scrollable element. Obviously, this is a less hostile design. However, I would actually prefer the UI get hostile when I open too many tabs. I have a habit of opening scores of tabs and forgetting about them, so being punished for this behaviour is a good motivator to close them every once in a while. On firefox's tab scroller, I remain blissfully oblivious of how bad my tab hoarding situation is getting.

I finally worked up the nerve to solve both these problems. I have attempted this before, my first attempt was submitting a feature request for the center-click thing, but that didn't go anywhere (UPDATE: apparently a patch was merged! So this should be available in firefox soon.) My second attempt was cloning firefox entirely and modifying the code itself. This did work, but I got tired of manually updating and rebuilding, so I gave up and deleted my local clone (and lost the patch >.<). Thankfully, I figured out a way to solve this problem on stock firefox developer edition. Now I can use firefox full time!

1) Search when center-clicking on new tab button

The way I solved this was by making an extension. The extension provides a "browser action" (toolbar button) that you can use to replace the "new tab" button entirely. Clicking on it makes a new tab, but center-clicking will search the contents of the primary xclipboard. If the clipboard contents is a valid URL, it goes straight there.

In order to get the contents of the xclipboard we need to use native messaging. This is a way for extensions to call external processes and get information back from them. Unfortunately that means quite a bit more configuration is required compared to regular run-of-the-mill extensions.

What follows from here are instructions for how to get all that set up.

Native messaging config

I'm pretty sure this won't work if you're using the "snap" version of firefox, due to its restrictive sandboxing. So make sure you install it in a different way.

Make sure that you have python3 installed, as well as the "xclip" utility. On ubuntu/debian, you can just do sudo apt install xclip. Python3 is installed by default on ubuntu.

Next, save the following snippet to xclip.py and place it inside the directory ~/.mozilla/native-messaging-apps. Ensure that the file is executable with chmod +x xclip.py.

#!/usr/bin/env python3

import subprocess, json, sys, struct

try:
  p = subprocess.Popen(["xclip", "-o"], stdout=subprocess.PIPE)
  out, err = p.communicate()
  out = out.decode("utf8")
except Exception as e:
  out = None
  err = str(e)

x = {"out": out, "err": err}

encodedContent = json.dumps(x)
encodedLength = struct.pack('@I', len(encodedContent))
encodedContent = encodedContent.encode()

sys.stdout.buffer.write(encodedLength)
sys.stdout.buffer.write(encodedContent)
sys.stdout.buffer.flush()

Next, save the following snippet to xclip.json and place it inside the directory ~/.mozilla/native-messaging-hosts. Be sure to change "/home/blackle" to the actual path to your home directory!

{
  "name": "xclip",
  "description": "xclip -o for NM",
  "path": "/home/blackle/.mozilla/native-messaging-apps/xclip.py",
  "type": "stdio",
  "allowed_extensions": [
    "xclip_search_1@suricrasia.online",
    "xclip_search_2@suricrasia.online",
    "xclip_search_3@suricrasia.online",
    "xclip_search_4@suricrasia.online",
    "xclip_search_5@suricrasia.online"
  ]
}

Now that this is done, firefox will know how to get the clipboard contents using xclip.py.

Creating the extension

The next step is to create an extension that uses a search engine of your choice to search the clipboard content. You can use the following form to do this. If you want multiple buttons that search different sites, make sure that the "extension index" is different for each one (max 5.)

If you don't want to enable javascript, here is a pre-made extension that uses google for searching.

Extension generator

Installing the extension

Unfortunately you cannot side-load an unsigned extension on certain builds of firefox. There is allegedly a way to have mozilla automatically sign an extension. You're free to experiment with that if you want.

Ultimately I decided to just install Firefox Developer Edition which will let you side-load an unsigned extension if you disable the about:config flag xpinstall.signatures.required.

Once you've got the extension installed, pin it to your taskbar. You can put this button almost anywhere in the UI. I removed the real "new tab" button and replaced it with the extension.

2) No scrolling in tab list

There are already some purported solutions to disabling tab-scrolling in firefox. These use an about:config setting plus some custom userChrome.css rules to manually specify a smaller minimum width for tabs. Unfortunately this isn't enough, since when the tabs become smaller than 50px the javascript running the tab list will trigger an "overflow" state and add the scrolling arrows. There's some CSS floating around to get rid of those, but I found it just causes everything to stutter, flipping between overflowed and non-overflowed.

My solution still uses some of these userChrome.css rules, but also I've written a userscript to disable the overflow handling entirely in javascript. That way the tablist will never think it's been overflowed, so it won't show the scroll arrows.

To begin, change browser.tabs.tabMinWidth in about:config to "1". You can also change the toolkit.tabbox.switchByScrolling config to enable switching tabs with the scroll wheel.

Next, you will need to enable userChrome.css support. This reddit post serves as a good tutorial.

Once you've done this, add the following to your userChrome.css.

.tabbrowser-tab:not([pinned]) {
  min-width: 1px !important;
}

Next you will need to install a userChrome.js loader. I used this one. Pick the "I'm only interested in scripts" download option.

The last step is to add this userscript I wrote:

// ==UserScript==
// @name            noTabScroll
// @author          blackle
// @include         main
// @startup         UC.noTabScroll.exec(win);
// @shutdown
// @onlyonce
// ==/UserScript==

UC.noTabScroll = {
  exec: function (win) {
    let {customElements} = win;

    const old_on_underflow = customElements.get('arrowscrollbox').prototype.on_underflow;
    customElements.get('arrowscrollbox').prototype.on_underflow = function (e) {
      if (this.id === "tabbrowser-arrowscrollbox") {
        e.preventDefault();
        return;
      }
      old_on_underflow.call(this, e);
    };
    const old_on_overflow = customElements.get('arrowscrollbox').prototype.on_overflow;
    customElements.get('arrowscrollbox').prototype.on_overflow = function (e) {
      if (this.id === "tabbrowser-arrowscrollbox") {
        e.preventDefault();
        return;
      }
      old_on_overflow.call(this, e);
    };
    customElements.get('tabbrowser-tabs').prototype._initializeArrowScrollbox = function () {
      return;
    };
  },
}

And that should be everything!


← Back