• Home
  • Tags
  • RSS
  • About
  • automatically suspending cpu hungry applications

    Timestamp:
    Tags: config

    TLDR: Using the awesome window manager: how to automatically send SIGSTOP and SIGCONT to application windows when they get unfocused or focused, respectively, to let the application not waste CPU cycles when not in use.

    I don’t require any fancy looking GUI, so my desktop runs no full-blown desktop environment like Gnome or KDE but instead only awesome as a light-weight window manager. Usually, the only application windows I have open are rxvt-unicode as my terminal emulator and firefox/iceweasel with the pentadactyl extension as my browser. Thus, I would expect that CPU usage of my idle system would be pretty much zero but instead firefox decides to constantly eat 10-15%. Probably to update some GIF animations or JavaScript (or nowadays even HTML5 video animations). But I don’t need it to do that when I’m not currently looking at my browser window. Disabling all JavaScript is no option because some websites that I need for uni or work are just completely broken without JavaScript, so I have to enable it for those websites.

    Solution: send SIGSTOP when my firefox window looses focus and send SIGCONT once it gains focus again.

    The following addition to my /etc/xdg/awesome/rc.lua does the trick:

    local capi = { timer = timer }
    client.add_signal("focus", function(c)
      if c.class == "Iceweasel" then
        awful.util.spawn("kill -CONT " .. c.pid)
      end
    end)
    client.add_signal("unfocus", function(c)
      if c.class == "Iceweasel" then
        local timer_stop = capi.timer { timeout = 10 }
        local send_sigstop = function ()
          timer_stop:stop()
          if client.focus.pid ~= c.pid then
            awful.util.spawn("kill -STOP " .. c.pid)
          end
        end
        timer_stop:add_signal("timeout", send_sigstop)
        timer_stop:start()
      end
    end)
    

    Since I’m running Debian, the class is “Iceweasel” and not “Firefox”. When the window gains focus, a SIGCONT is sent immediately. I’m executing kill because I don’t know how to send UNIX signals from lua directly.

    When the window looses focus, then the SIGSTOP signal is only sent after a 10 second timeout. This is done for several reasons:

    With this change, when I now open htop, the process consuming most CPU resources is htop itself. Success!

    Another cool advantage is, that firefox can now be moved completely into swap space in case I run otherwise memory hungry applications without ever requiring any memory from swap until I really use it again.

    I haven’t encountered any disadvantages of this setup yet. If 10 seconds prove to be too short to copy and paste I can easily extend this delay. Even clicking on links in my terminal works flawlessly - the new tab will just only load once firefox gets focused again.

    EDIT: thanks to Helmut Grohne for suggesting to compare the pid instead of the raw client instance to prevent misbehaviour when firefox opens additional windows like the preferences dialog.