fracture91 / ignpp

Firefox and Chrome extension for boards.ign.com
http://vestitools.pbworks.com/
3 stars 2 forks source link

Don't autorefresh if browser is idle #257

Closed fracture91 closed 13 years ago

fracture91 commented 13 years ago

We must make sure that IGN++ doesn't end up refreshing forever when the user is away. Luckily, Chrome and Firefox have APIs to determine if the machine/browser is idle or not. I should introduce a function like GM_idle that accepts a number of milliseconds and returns true if the browser has been idle for that long. Whenever a refresh timer is triggered, check this idle state and don't refresh if it's idle. This should also apply to background refreshes as in #256. The idle state should be ignored if the focus is ignored as in #230. The idle time passed to GM_idle should be some hardcoded number (or maybe controlled by a hidden pref). Something like 10 minutes should be good.

Chrome's queryState method is asynchronous, so it looks like I'll have to add a listener which would send a message to content scripts when the browser becomes active. Content script then records the date of activity. GM_idle can compare current date to date of last activity to determine if the browser is idle. Then GM_idle can remain synchronous. This is assuming that Chrome will fire an event every time the user does something that indicates he is active. Need to test it out. If it doesn't, periodically poll querystate and send result to content script.

https://developer.mozilla.org/en/XPCOM_Interface_Reference/nsIIdleService http://code.google.com/chrome/extensions/idle.html

fracture91 commented 13 years ago

queryState's threshold must be at least 15 seconds or an error is thrown. From looking at the source code, it looks like the threshold is also clamped at a maximum of one hour. That would be nice to include in the documentation. Also, it's measured in seconds, not milliseconds, so GM_idle will need to be less precise on Chrome. I can't get the onStateChanged event to fire at all.

Looks like I will need to poll queryState every second on the background page with a 15 second threshold. If the state is active, send a message to all managed tabs, which then record the current date as the date of last activity. If idle, managed tabs should record the current date - 15 seconds as the date of last activity. When GM_idle is called, return true if the current date minus the date of last activity is greater than the given threshold.

fracture91 commented 13 years ago

I think this introduced a bug. If you leave the browser idle with a boards tab open for a while, then return and refresh the page, scripts won't be applied for a while. During this time, it looks like the background page is hard at work doing something.

I suspect that Chrome stops handling the idle requests when the browser has been idle for a while, so they stack up. When user returns, it has to handle a bunch all at once which freezes it for a bit.

I think this could be solved by not sending any more idle messages once the browser turns idle - the content script shouldn't care about these anyway. Regardless of whether this is the actual problem, it should be fixed for performance reasons.

In fact, the background page really only needs to report the transition between the two states...I really messed that up if I'm correct.

fracture91 commented 13 years ago

I tested this by letting Chrome sit with a board tab open for 20 minutes. I came back and refreshed the tab without incident. Seems to be fixed.