1c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Copyright (c) 2010 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/idle.h"
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include <gdk/gdk.h>
872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include <gdk/gdkx.h>
972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
1072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include <vector>
1172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
1272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "base/basictypes.h"
13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/engine/idle_query_linux.h"
1472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/gtk/gtk_util.h"
1572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/x/x11_util.h"
1672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
1772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsennamespace {
1872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
1972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenclass ScreensaverWindowFinder : public ui::EnumerateWindowsDelegate {
2072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen public:
2172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ScreensaverWindowFinder()
2272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      : exists_(false) {}
2372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
2472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  bool exists() const { return exists_; }
2572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
2672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen protected:
2772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  virtual bool ShouldStopIterating(XID window) {
2872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    if (!ui::IsWindowVisible(window) || !IsScreensaverWindow(window))
2972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      return false;
3072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    exists_ = true;
3172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return true;
3272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
3372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
3472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen private:
3572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  bool IsScreensaverWindow(XID window) const {
3672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    // It should occupy the full screen.
3772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    if (!ui::IsX11WindowFullScreen(window))
3872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      return false;
3972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
4072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    // For xscreensaver, the window should have _SCREENSAVER_VERSION property.
4172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    if (ui::PropertyExists(window, "_SCREENSAVER_VERSION"))
4272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      return true;
4372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
4472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    // For all others, like gnome-screensaver, the window's WM_CLASS property
4572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    // should contain "screensaver".
4672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    std::string value;
4772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    if (!ui::GetStringProperty(window, "WM_CLASS", &value))
4872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      return false;
4972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
5072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return value.find("screensaver") != std::string::npos;
5172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
5272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
5372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  bool exists_;
5472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
5572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  DISALLOW_COPY_AND_ASSIGN(ScreensaverWindowFinder);
5672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen};
5772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
5872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenbool ScreensaverWindowExists() {
5972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ScreensaverWindowFinder finder;
6072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  gtk_util::EnumerateTopLevelWindows(&finder);
6172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  return finder.exists();
6272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
6372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
6472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochIdleState CalculateIdleState(unsigned int idle_threshold) {
6772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Usually the screensaver is used to lock the screen, so we do not need to
6872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // check if the workstation is locked.
6972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  gdk_error_trap_push();
7072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  bool result = ScreensaverWindowExists();
7172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  bool got_error = gdk_error_trap_pop();
7272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (result && !got_error)
7372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return IDLE_STATE_LOCKED;
7472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  browser_sync::IdleQueryLinux idle_query;
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  unsigned int idle_time = idle_query.IdleTime();
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (idle_time >= idle_threshold)
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return IDLE_STATE_IDLE;
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return IDLE_STATE_ACTIVE;
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
81