Skip to content

Support for discard while on battery, Firefox #421

@meltyness

Description

@meltyness

There have been some previous discussions about this, but I've made some headway myself towards this end.

The idea would be, to somehow ensure that Auto Tab Discard is only active while not connected to an AC power source. Auto Tab Discard supports this in the Chrome ecosystem where a readily-available API mechanism has not been specifically barred as (I think) a privacy measure. This seeks a middleground, or alternative support.

Foreword

The most pertinent development (I guess the most obvious mechanism) is that Mozilla has deliberately removed the BatteryStatus API from the browser, so that information is simply not available to the Extension. https://developer.mozilla.org/en-US/docs/Web/API/Battery_Status_API

Some stuff that I bumped into / thought about / didn't seem to be viable:

  • Headless mode / marionette / debugging
    • These can't work because the Profile is locked, and the Profile dictates the Extension storage. If you have a graphical session, that's the only thing that can manipulate the Profile.
  • Modifying Profile database files, in flight
    • This won't statefully update the Extension, also I couldn't find it.
  • Using Tampermonkey to create a callback
    • Tampermonkey won't be able to tamper another extension's page.

I could be wrong, maybe there's a better way to do this with Firefox, but I'll provide a solution that I've put in place that required a small backend tweak to auto-tab-discard

Solution

I've come up with a multi-pronged solution that seems to work OK in my case.

Generally, on Linux, acpid2 can be used to effectively apply (and remove) arbitrary battery-saving measures. However a cooperation is needed between the daemon and the Firefox extension to implement in this way.

There's a restore callback in options/index.js which appears to have last responsibility prior to page load for populating the options form. I appended to following:

  switch (document.URL.split("#")[1]) {
  case "sb-v1-be-quiet":
    document.getElementById("period").value = 1;
    document.querySelector("input#save").click();
    window.close();
    break;
  case "sb-v1-be-loud":
    document.getElementById("period").value = 0;
    document.querySelector("input#save").click();
    window.close();
    break;
  }

So effectively providing an API to signal that "sleeping tabs should be disabled." And then a power event for acpid can be configured, something like /etc/acpi/ff_custom.sh executable, and tied to an acpid2 event in the typical manner.

#!/bin/bash
# Make firefox aggressively sleep tabs on battery

export DISPLAY=:0.0
export HOME=/home/meltyness
export XDG_SEAT=seat0
export DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus
/usr/bin/on_ac_power
START=$?
sleep 30
/usr/bin/on_ac_power
FINISH=$? # I don't get it. Need to debounce this somehow
AVOID_GAMING=`cat /sys/bus/pci/devices/0000:01:00.0/power/runtime_status`
echo $AVOID_GAMING
if [[ $START == $FINISH && $AVOID_GAMING == "suspended" ]]; then
	/usr/bin/on_ac_power
	if [ $? -eq 1 ]; then
		su -m -c 'firefox-esr --new-window "moz-extension://59bacad8-826c-40f1-acd2-5708a13b87ac/data/options/index.html#sb-v1-be-quiet"' meltyness
	else
		su -m -c 'firefox-esr --new-window "moz-extension://59bacad8-826c-40f1-acd2-5708a13b87ac/data/options/index.html#sb-v1-be-loud"' meltyness
	fi
fi

So this has a gaming mode escape hatch in case my dGPU is runtime operational, and some nascent efforts to debounce, since the actual act of pulling the plug causes this whole thing to run like, 4 times, which I have been as yet, unable to explain or prevent.

Now this has the downsides of:

  • being weird and awkward
  • needing to be updated when the extension version changes
  • stealing focus and briefly flashing firefox windows, sometimes for no apparent reason
  • acpi generates false events occasionally depending on whether a charge limit is in-place
  • doesn't work on a truly multi-user system
  • possibly being broken if you ever restart DBUS or your DM and the session bus moves

However, it might be an alright centerpiece towards sorting this behavior out.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions