how does X suck today? Today it's DPMS.

A little while ago I added mouse hysteresis to xscreensaver (meaning, if you only move the mouse by some small number of pixels per second, it won't consider that to be enough activity to turn off the screen saver.) People have been asking this for a while, so that dirty mice or earthquakes or whatever don't unblank their screens. It works good.

But it occurred to me that this was going to interfere with power management. Say you have things set so that the screen blanks after 10 minutes, and the monitor powers down after 60 minutes, and a truck goes by and rumbles your desk by one pixel at 59 minutes.

  • 0:10:00 -- screen blanks
  • 0:59:00 -- truck!
  • 1:00:00 -- monitor should power down
  • 1:58:00 -- monitor does power down

So if a truck goes by every 58 minutes, the monitor will always stay on, since xscreensaver now knows to ignore small motions like that, but the X server itself does not.

The obvious solution here is to tell the X server to keep its hands off of the monitor, and for xscreensaver to take care of powering it up and down by itself. Sounds easy enough, right? Except it doesn't work: if the monitor is in "suspend" mode and you try to put it in "standby" or "off" mode, it powers back on. DPMSForceLevel() succeeds, and DPMSInfo() says that the monitor is in "suspend" or "off", and yet, there it is, fully powered up and staring you in the face.

So, fuck it, I guess. If you expect DPMS to work right, don't.

Tags: , , ,

38 Responses:

  1. xed_geek says:

    Obvious stupid question: Any way to wrestle control of the mouse input from X? Just not pass the input along unless > Z pixels. Probably not.

  2. strspn says:

    Some programmer in the past is trying to force you throw up a "This machine is powering down now, you have %d seconds to prevent it" display.

  3. vxo says:

    I've noticed this... the truly curious thing is, sometimes using xset force dpms off from a console reawakens the monitor the moment it finishes turning off, even if there's no concievable way that the mouse or keyboard could have passed input.

    Low-tech solution? I hit the power button on the monitor before leaving the system for a while.

    • prumpf says:

      I always figured that one was because by the time you release the enter key, the monitor's already in the off state, so it powers back up because there was a key event. My solution is to do sleep 1 && xset dpms force off, because I usually manage to get my finger off the enter key if I have a second to do it in.

  4. ajaxxx says:

    i don't see a bug report from you about this. it does sound like a legitimate issue, and probably wouldn't be hard to fix if it were on my radar...

    • jwz says:

      But see, it now no longer matters whether it ever gets fixed. The fact that this bug has ever existed means I can never rely on correct behavior.

      Now I know that there exist X servers out in the world that have this bug (where N probably approaches "all of them.") If I commit this change, I'll start getting an endless stream of bug reports about how "the new xscreensaver breaks power-saving." So it's not worth even trying.

      • ajaxxx says:

        you tell me about a bug in DPMS. i fix it and bump the version number. you call DPMSGetVersion() and if the version number is high enough use the sane behaviour. sounds fixable to me.

        • jwz says:

          Is there any reason I should believe that X servers from different vendors use the same numbering scheme? That works for XFree or XOrg or whichever branch of the fork you work on, but it doesn't tell me anything about Sun or SGI or OSX or who-knows-what-else.

          • ajaxxx says:

            yes. every major vendor ships code based on Xorg now. IBM's and Sun's X servers track Xorg. SGI's new machines are based on either XFree86 or Xorg, Xsgi development is (sadly) effectively dead to my knowledge. likewise OSX's, and the Cygwin and now mingw servers for win32, are all based on Xorg for all new versions.

   is the canonical upstream. if says "version 1.3 of the DPMS extension protocol defines these semantics, and earlier versions are broken", then that is effectively holy writ.

        • strspn says:

          call DPMSGetVersion() and if the version number is high enough use the sane behaviour

          Yes! Bloat the code to prepare for any permutation of doing identical things!

          • ajaxxx says:

            your definition of bloat is bizarre. he's talking about adding code to begin with. i'm saying wrap it in a conditional. five more instructions, max.

            • Iterate the process and you'll get it.

              • jesus_x says:

                All features are bloat to someone, and all bugfixes are bloat to someone else. But in general, we can agree that SOME things truly ARE bloat, like building a broken web browser into an OS core. This is not a case where you'd find much consensus on bloat.

                • strspn says:

                  Work around the problems of the past at the expense of future understanding, or beat the problems of the past into submission, and make it look like we had it easier than we actually did.... Or, BOTH!

                  I don't use "bloat" in a perjorative connotation. I just don't like to cook with oil when I can avoid it.

      • fo0bar says:

        I fail to see how introducing this new feature would break things. If a truck comes by every 58 minutes, the monitor will never turn off (as stated). If mouse hysteresis is introduced, you will see a screen hack; if not, you will see a desktop...

        Oh, now I get it. "My screen isn't turning off but xscreensaver is running. It's xscreensaver's fault!"

        • jwz says:

          I wasn't talking about the "mouse hysteresis" feature, I was talking about the "try to do dpms properly" feature. As it stands, if I moved the dpms logic from the server to the client, the result would be that the monitor would never power off, truck or no. So people would rightly complain "my monitor stopped ever powering down when I went from xscreensaver version N to N+1."

    • jwz says:

      Maybe the right way to fix this is to resurrect the XIdle extension and then extend it to allow xscreensaver to re-set the server's idea of idle times. So, when xscreensaver decides that a mouse motion didn't count, it could tell the server, "nevermind that, the user has been idle for an hour and a half." Then the server-side DPMS state would take that into account and set the monitor power level appropriately.

      This would result in more wear on the monitor's power supply, though: when a truck goes by, the monitor might power up and then power down again immediately (as the server reacts, and then xscreensaver tells it "nevermind that.")

      So maybe a better fix would be to add a way to tell the server "don't ever change the monitor power level unless you are explicitly ordered to." Then the monitor would power back on when and only when xscreensaver told it to, and not as a (direct, server-internal) result of user activity. That way, the two processes wouldn't second-guess each other.

      An xscreensaver crash could leave things in a bad state, though.

      • ajaxxx says:

        So maybe a better fix would be to add a way to tell the server "don't ever change the monitor power level unless you are explicitly ordered to." Then the monitor would power back on when and only when xscreensaver told it to, and not as a (direct, server-internal) result of user activity. That way, the two processes wouldn't second-guess each other. An xscreensaver crash could leave things in a bad state, though.

        i don't think crashing would necessarily be a problem. consider it like a "DPMS grab". if the client goes away, so does the grab, and then the server's built-in timer logic takes over. an xscreensaver hang would still be problematic, but that's not news.

        i agree about resurrecting XIdle though, and if i have my way it'll be included in 7.0 which should be out this summer.

        • jwz says:

          Yeah, "DPMS grab" sounds sensible.

          • ajaxxx says:

            only problem with the grab idea is there's no way to add it to Xext without upgrading the client library, which kinda blows. in theory you could add it to DPMSForceLevel() but that sanity-checks its arguments. lame. so that means either:

            - do a configure check for the new entrypoint at build time
            - reimplement the DPMS client code in xscreensaver (where "reimplement" really means "copy over")

            neither one is ideal.

            thanks for #2726, i'll try to get to it this week.

            • peruano says:

              Shit... I wish all my bug reports that I submitted to people at work would get fix as fast as this! They should all have livejournal accounts...

  5. d14n says:

    Why is it that almost all power management implementations for PCs completely fail to operate as they are expected to? I have always found oddities with DPMS. ACPI has always caused problems for me. My current laptop freezes halfway through loading from the hibernation file. These are all features that manufacturers put in products because they know the features are important to customers, but they also seem to be the least-reliable and worst-tested features.

    • karlshea says:

      Because it's more important that Windows Media Player be skinnable than for power management to work, obviously.

    • On my current system, X's DPMS actually crashes my monitor. Yes, I said monitor (Samsung 191T+ LCD). After a few DPMS cycles it starts blinking randomly, and I have to cycle power. After a few more cycles it stops responding to the power switch and I have to unplug it. After I got tired of this, I disabled DPMS and the problems went away.

    • smackfu says:

      I figure that no one likes testing it, because if you have a bug, you tend to be in a state where you can't run a debugger and you have to do a hard reboot.

    • mjg59 says:

      Hibernate is generally implemented by the OS, and has very little to do with ACPI. That said, most ACPI implementations are shit beyond belief.

  6. boggyb says:

    I think I had problems with that at one time under Windows (Win2k SP4, GeForce4 card). One of the many random programs I've written basically displays an icon in the try and lets you get at all sorts of power management controls (everything from lock workstation to shutdown even if something tries to block it or hangs). The "Power off monitor" command did power the monitor off... for about 2 seconds.

    Under MS you call DefWindowProc(hwnd, WM_SYSCOMMAND, SC_MONITORPOWER, 2); to achieve this (translates into shut off the display). I can only assume some driver or hardware was lying through its teeth at windows, as it worked fine just now. Then again, the card is an nVidia, and I'm using a very old version of the drivers as the newer versions wedge some part of the system whenever a game changes resolution to run full screen! How they managed that one I don't know, but it's very irritating.

  7. netsharc says:

    What if, after it detects the truck, XScreensaver tells X to power the monitor down in 1 minute? (or 60-x minutes). Would that work?

    • badc0ffee says:

      I'm sure he tried that, but it's a good suggestion

    • jwz says:

      I guess that might work. That's a complicated little dance, though -- keeping track of the difference between "xscreensaver idle time" and "server idle time." If the client's notion of the server's notion of idle time is off, it could act really weird.

      Also, it just occurred to me that the second truck is going to power the screen back on again, and someone (client or server) needs to turn it back off eventually. Bleh.

  8. I actually stopped using xscreensaver after a brief trial because I found it caused DPMS to never kick in at all. Very annoying.

    • jwz says:

      I haven't heard of that before. Did you verify the dpms settings in xscreensaver-demo? Running xscreensaver with -verbose might provide a clue.

      • Hrmm...seems to work now. I have since switched distros and blah blah blah. I find it odd that something actually works MORE reliably on gentoo for once.

  9. ninjaseg says:

    You know, I once hacked up a shell script for my "Media PC" to allow me to use the power button on my LIRC remote to turn the monitor on and off. (I wasn't using a TV at the time). What it did was set all the DPMS timeouts to 0, which resulted in the monitor turning off, and it *stays off* no matter what. Perfect. Exactly what I wanted. To turn it back on, it just restored the timeouts and did an 'xset dpms force on'.

    Simple, worked great. I've since accidentally lost the script. Oooops.