Archive

Posts Tagged ‘x11’

Suspend out-of-focus Firefox to save battery from useless CPU usage

November 29th, 2014 2 comments

My Firefox (or rather Iceweasel) is prone to constantly spinning and eating about 50-70% CPU on average when should be supposed to just sit idle. I tried to find the root cause, but Javascript profiler sees nothing and other forays didn’t end up with much (I discovered that spinning progress wheel when some tab is forever loading amounts to about 20% CPU, though). Not sure if always, but sometimes it spins within WebGLImageConverter::run() (no callgraph, sorry).

So in the end I decided to treat the symptoms instead. Cleaning my CPU fan helped with the noise, but the main problem is that running firefox brings my battery life to about 1/2 to 1/3. So one obvious solution would be to just stop the damn process when I don’t use it. I typically don’t do background downloads while on battery (or otherwise), so that means I want it stopped when the window is inactive – not in focus. This is surprisingly exotic idea, apparently, and not easy to do in most window managers.

I even tried switching to awesome or i3 window managers which should make this easy, but I’m psychologically not up to that; I think I’m too conservative, but I decided not to stick with that. I use the MATE desktop environment with marco window manager. Perhaps switching to sawfish would be a good option, but in the end I just decided to write a shell script that will periodically assess the situation and suspend or resume firefox as needed. Of course this introduces extra wakeups and ambient CPU load, but when powertop reports that my GoogleTalkPlugin (running at all times for whatever reason) wakes up 150 times per second, the powersaving situation on Linux is still too messy – so who cares?

Here goes the script, in the hope that it will be useful for someone else too. Run it in a terminal or backgrounded in your ~/.xprofile, it will stop the firefox process when out of focus for more than 10s and on battery, and resume it within a second when switching back. In practice, I found these timings completely acceptable so far, and didn’t notice any ill effects of constant STOP/CONT either.

firefox-suspender.sh:

#!/bin/bash
#
# firefox-suspender: Periodically check whether firefox is out of focus
# and STOP it in that case after a time delay; if in focus but stopped,
# send SIGCONT.
#
# (c) Petr Baudis <pasky@ucw.cz>  2014
# MIT licence if this is even copyrightable
 
loop_delay=1    # [s]
stop_delay=10   # [s]
 
last_in_focus=$(date +%s)
firefoxpid=
state=running
 
while true; do
  sleep $loop_delay
 
  # Get active window id
  window=$(xprop -root _NET_ACTIVE_WINDOW)
  window=${window#*# }
  # What kind of window is it?
  class=$(xprop -id "$window" WM_CLASS)
  # echo Active window $window, class $class
 
  if [[ "$class" =~ Navigator ]]; then
    # Firefox!  We know it is running.  Make sure we
    # have its pid and update the last seen date.
    # If we stopped it, resume again.
    if [ "$state" = stopped ]; then
      echo "$(date)  Resuming firefox @ $firefoxpid"
      if kill -CONT $firefoxpid; then
        state=running
      else
        firefoxpid=
      fi
    fi
    last_in_focus=$(date +%s)
    if [ -z "$firefoxpid" ]; then
      firefoxpid=$(pidof iceweasel)
    fi
    if [ -z "$firefoxpid" ]; then
      firefoxpid=$(pidof firefox)
    fi
 
    continue
  fi
 
  # Not Firefox!  If it's running, we are on battery and
  # it's been long enough, stop it now.
  if [ "$state" != running ]; then
    continue
  fi
 
  read battery </sys/class/power_supply/BAT0/status
  if [ "$battery" != Discharging ]; then
    continue
  fi
 
  if [ $(($(date +%s) - last_in_focus)) -ge $stop_delay ]; then
    echo "$(date)  Stopping firefox @ $firefoxpid"
    if ! kill -STOP $firefoxpid; then
      firefoxpid=
    fi
    state=stopped
  fi
done

An improved version of this script: https://github.com/mkoura/browser-suspender

Categories: linux Tags: , , , ,

CLIPBOARD cut’n’paste in xterm

May 16th, 2014 No comments

Call me old-fashioned but I’m still using xterm on my desktop computer (where I use just fluxbox as my window manager) – it suits me just fine, but for one thing that I finally managed to solve. xterm by default ignores the clipboard, and none of the previously published solutions cut it for me, until now.

In X11, we have two commonly used selection buffers – PRIMARY and CLIPBOARD:

  • PRIMARY is used when you simply highlight text in most applications, without pressing anything, and you can paste from it using the middle mouse button; it is of fleeting nature and used for quick cut’n’paste; and it doesn’t work well with all applications, e.g. libreoffice doesn’t put highlighted stuff there at least in some contexts and non-textarea HTML5 text edit widgets usually can’t handle the middle button for pasting.
  • CLIPBOARD is used when you use ctrl-c or ctrl-v and can be used even with the evil applications above, but the problem is it’s not supported by xterm well!

In most terminal emulators, you can use the clipboard either using menus or shift-ctrl-c / shift-ctrl-v. However, in xterm, the best you can do is either…

  • Make it use CLIPBOARD just instead of PRIMARY and in the same manner – the moment you select any text in xterm, it will plaster it over whatever else was in the CLIPBOARD before, without any explicit action. This sucks.
  • Have a different set of bindings for selection to PRIMARY and CLIPBOARD. This is a lot better, but I’m out of modifiers since I use shift to cut’n’paste in terminal applications that use mouse themselves (e.g. elinks).

So, my solution is to bring in the shift-ctrl-c / shift-ctrl-v bindings! In your ~/.Xresources or ~/.Xdefaults, add

XTerm*VT100.*translations:      #override \
        Shift Ctrl C: select-end(CLIPBOARD, CUT_BUFFER0) \n\
        Shift Ctrl V: insert-selection(CLIPBOARD, CUT_BUFFER0)

(and don’t forget to xrdb ~/.Xresources afterwards).

Now, you can use shift-ctrl-v for pasting from CLIPBOARD, and almost use shift-ctrl-c for copying to clipboard. There is a catch – you must press shift-ctrl-c while you are still holding the mouse button, i.e you press left mouse button, drag your selection, then before releasing it, press shift-ctrl-c; thankfully, that can be done by one hand without too much cramping.

It’s a bit inconvenient because of this bug, and doesn’t quite work with left and right selection; maybe I will sometime get around to adding true clipboard support to xterm code, but I think this is good enough for me at this point. :)

Categories: linux Tags: , ,