summaryrefslogtreecommitdiff
path: root/lockscreen
diff options
authorWilliam Hua <william.hua@canonical.com>2014-04-11 03:51:58 +1200
committerWilliam Hua <william.hua@canonical.com>2014-04-11 03:51:58 +1200
commitb37a14f4fe2fd1ac43d9c6978d80b1a9e99cbc0f (patch)
treeffb2a655178063d1a1d4c27d5711a53fc6ef11a5 /lockscreen
parent5269ab3470d7451467bd92d2fbe95cd6801f1c3a (diff)
parente32bd7f76dfa9651caff80c58b4f88d5b3c58879 (diff)
Merge trunk.
(bzr r3764.7.2)
Diffstat (limited to 'lockscreen')
-rw-r--r--lockscreen/BackgroundSettings.cpp2
-rw-r--r--lockscreen/CMakeLists.txt3
-rw-r--r--lockscreen/LockScreenAbstractShield.h1
-rw-r--r--lockscreen/LockScreenController.cpp306
-rw-r--r--lockscreen/LockScreenController.h36
-rw-r--r--lockscreen/LockScreenSettings.cpp46
-rw-r--r--lockscreen/LockScreenSettings.h15
-rw-r--r--lockscreen/LockScreenShield.cpp2
-rw-r--r--lockscreen/ScreenSaverDBusManager.cpp125
-rw-r--r--lockscreen/ScreenSaverDBusManager.h57
10 files changed, 501 insertions, 92 deletions
diff --git a/lockscreen/BackgroundSettings.cpp b/lockscreen/BackgroundSettings.cpp
index 44dd94436..8c933be5f 100644
--- a/lockscreen/BackgroundSettings.cpp
+++ b/lockscreen/BackgroundSettings.cpp
@@ -110,7 +110,7 @@ BaseTexturePtr BackgroundSettings::GetBackgroundTexture(int monitor)
int width = geo.width;
int height = geo.height;
int grid_x_offset = GetGridOffset(width);
- int grid_y_offset = GetGridOffset(height) + panel::Style().Instance().PanelHeight(monitor);
+ int grid_y_offset = GetGridOffset(height) + panel::Style::Instance().PanelHeight(monitor);
// overlay grid
cairo_surface_t* overlay_surface = cairo_surface_create_similar(cairo_graphics.GetSurface(),
diff --git a/lockscreen/CMakeLists.txt b/lockscreen/CMakeLists.txt
index e755e7fee..b32421f8f 100644
--- a/lockscreen/CMakeLists.txt
+++ b/lockscreen/CMakeLists.txt
@@ -24,10 +24,11 @@ set (LOCKSCREEN_SOURCES
LockScreenShield.cpp
LockScreenShieldFactory.cpp
LockScreenPanel.cpp
+ ScreenSaverDBusManager.cpp
UserAuthenticatorPam.cpp
UserPromptView.cpp
)
add_library (lockscreen-lib STATIC ${LOCKSCREEN_SOURCES})
-add_dependencies (lockscreen-lib unity-core-${UNITY_API_VERSION} unity-shared panel-lib pam)
+add_dependencies (lockscreen-lib unity-core-${UNITY_API_VERSION} unity-shared pam)
add_pch(pch/lockscreen_pch.hh lockscreen-lib)
diff --git a/lockscreen/LockScreenAbstractShield.h b/lockscreen/LockScreenAbstractShield.h
index a9e993196..a3907a56f 100644
--- a/lockscreen/LockScreenAbstractShield.h
+++ b/lockscreen/LockScreenAbstractShield.h
@@ -49,6 +49,7 @@ public:
virtual bool IsIndicatorOpen() const = 0;
sigc::signal<void, int, int> grab_motion;
+ sigc::signal<void, unsigned long, unsigned long> grab_key;
protected:
session::Manager::Ptr session_manager_;
diff --git a/lockscreen/LockScreenController.cpp b/lockscreen/LockScreenController.cpp
index 3385d0ef3..e0482a5f5 100644
--- a/lockscreen/LockScreenController.cpp
+++ b/lockscreen/LockScreenController.cpp
@@ -34,44 +34,69 @@ namespace lockscreen
{
namespace
{
-const unsigned int FADE_DURATION = 400;
-}
+const unsigned int IDLE_FADE_DURATION = 10000;
+const unsigned int LOCK_FADE_DURATION = 400;
+const unsigned int POST_LOCK_SCREENSAVER_WAIT = 2;
-namespace testing
+class BlankWindow : public nux::BaseWindow
{
-const std::string DBUS_NAME = "com.canonical.Unity.Test.DisplayManager";
+public:
+ BlankWindow() : nux::BaseWindow("UnityScreensaver") {}
+ bool AcceptKeyNavFocus() override { return true; }
+ bool InspectKeyEvent(unsigned int, unsigned int, const char*) override { return true; };
+};
}
-DECLARE_LOGGER(logger, "unity.locksreen");
+DECLARE_LOGGER(logger, "unity.lockscreen");
-Controller::Controller(session::Manager::Ptr const& session_manager,
+Controller::Controller(DBusManager::Ptr const& dbus_manager,
+ session::Manager::Ptr const& session_manager,
UpstartWrapper::Ptr const& upstart_wrapper,
ShieldFactoryInterface::Ptr const& shield_factory,
bool test_mode)
- : session_manager_(session_manager)
+ : opacity([this] { return fade_animator_.GetCurrentValue(); })
+ , dbus_manager_(dbus_manager)
+ , session_manager_(session_manager)
, upstart_wrapper_(upstart_wrapper)
, shield_factory_(shield_factory)
- , fade_animator_(FADE_DURATION)
+ , fade_animator_(LOCK_FADE_DURATION)
+ , blank_window_animator_(IDLE_FADE_DURATION)
, test_mode_(test_mode)
+ , prompt_activation_(false)
{
- uscreen_connection_ = UScreen::GetDefault()->changed.connect([this] (int, std::vector<nux::Geometry> const& monitors) {
+ auto* uscreen = UScreen::GetDefault();
+ uscreen_connection_ = uscreen->changed.connect([this] (int, std::vector<nux::Geometry> const& monitors) {
EnsureShields(monitors);
+ EnsureBlankWindow();
});
+
uscreen_connection_->block();
- session_manager_->lock_requested.connect(sigc::mem_fun(this, &Controller::OnLockRequested));
+ suspend_connection_ = uscreen->suspending.connect([this] {
+ if (Settings::Instance().lock_on_suspend())
+ session_manager_->PromptLockScreen();
+ });
+
+ dbus_manager_->simulate_activity.connect(sigc::mem_fun(this, &Controller::SimulateActivity));
+ session_manager_->screensaver_requested.connect(sigc::mem_fun(this, &Controller::OnScreenSaverActivationRequest));
+ session_manager_->lock_requested.connect(sigc::bind(sigc::mem_fun(this, &Controller::OnLockRequested), false));
+ session_manager_->prompt_lock_requested.connect(sigc::bind(sigc::mem_fun(this, &Controller::OnLockRequested), true));
session_manager_->unlock_requested.connect(sigc::mem_fun(this, &Controller::OnUnlockRequested));
+ session_manager_->presence_status_changed.connect(sigc::mem_fun(this, &Controller::OnPresenceStatusChanged));
fade_animator_.updated.connect([this](double value) {
std::for_each(shields_.begin(), shields_.end(), [value](nux::ObjectPtr<Shield> const& shield) {
shield->SetOpacity(value);
});
+
+ opacity.changed.emit(value);
});
fade_animator_.finished.connect([this] {
if (animation::GetDirection(fade_animator_) == animation::Direction::BACKWARD)
{
motion_connection_->disconnect();
+ key_connection_->disconnect();
uscreen_connection_->block();
session_manager_->unlocked.emit();
@@ -81,15 +106,47 @@ Controller::Controller(session::Manager::Ptr const& session_manager,
shields_.clear();
- if (Settings::Instance().lockscreen_type() == Type::UNITY)
- {
- upstart_wrapper_->Emit("desktop-unlock");
- indicators_.reset();
- }
+ upstart_wrapper_->Emit("desktop-unlock");
+ indicators_.reset();
+ }
+ else if (!prompt_activation_)
+ {
+ screensaver_post_lock_timeout_.reset(new glib::TimeoutSeconds(POST_LOCK_SCREENSAVER_WAIT, [this] {
+ OnPresenceStatusChanged(true);
+ return false;
+ }));
+ }
+ });
+
+ blank_window_animator_.updated.connect([this](double value) {
+ if (blank_window_)
+ blank_window_->SetOpacity(value);
+ });
+
+ blank_window_animator_.finished.connect([this] {
+ bool shown = blank_window_animator_.GetCurrentValue() == 1.0;
+ BlankWindowGrabEnable(shown);
+ dbus_manager_->active = shown;
+ lockscreen_delay_timeout_.reset();
+
+ if (shown && Settings::Instance().lock_on_blank())
+ {
+ int lock_delay = Settings::Instance().lock_delay();
+
+ lockscreen_delay_timeout_.reset(new glib::TimeoutSeconds(lock_delay, [this] {
+ session_manager_->PromptLockScreen();
+ return false;
+ }));
}
});
}
+void Controller::ResetPostLockScreenSaver()
+{
+ screensaver_post_lock_timeout_.reset();
+ HideBlankWindow();
+}
+
void Controller::OnPrimaryShieldMotion(int x, int y)
{
if (!primary_shield_->GetAbsoluteGeometry().IsPointInside(x, y))
@@ -104,17 +161,20 @@ void Controller::OnPrimaryShieldMotion(int x, int y)
shield->primary = true;
auto move_cb = sigc::mem_fun(this, &Controller::OnPrimaryShieldMotion);
motion_connection_ = shield->grab_motion.connect(move_cb);
+ auto key_cb = sigc::hide(sigc::hide(sigc::mem_fun(this, &Controller::ResetPostLockScreenSaver)));
+ key_connection_ = shield->grab_key.connect(key_cb);
break;
}
}
+
+ ResetPostLockScreenSaver();
}
void Controller::EnsureShields(std::vector<nux::Geometry> const& monitors)
{
int num_monitors = monitors.size();
int shields_size = shields_.size();
- bool unity_mode = (Settings::Instance().lockscreen_type() == Type::UNITY);
- int primary = unity_mode ? UScreen::GetDefault()->GetMonitorWithMouse() : -1;
+ int primary = UScreen::GetDefault()->GetMonitorWithMouse();
shields_.resize(num_monitors);
@@ -138,77 +198,192 @@ void Controller::EnsureShields(std::vector<nux::Geometry> const& monitors)
{
shield->SetOpacity(fade_animator_.GetCurrentValue());
shield->ShowWindow(true);
- shield->PushToFront();
}
}
- if (unity_mode)
+ primary_shield_ = shields_[primary];
+ primary_shield_->primary = true;
+ auto move_cb = sigc::mem_fun(this, &Controller::OnPrimaryShieldMotion);
+ motion_connection_ = primary_shield_->grab_motion.connect(move_cb);
+ auto key_cb = sigc::hide(sigc::hide(sigc::mem_fun(this, &Controller::ResetPostLockScreenSaver)));
+ key_connection_ = primary_shield_->grab_key.connect(key_cb);
+}
+
+void Controller::EnsureBlankWindow()
+{
+ auto const& screen_geo = UScreen::GetDefault()->GetScreenGeometry();
+
+ if (!blank_window_)
{
- primary_shield_ = shields_[primary];
- primary_shield_->primary = true;
- auto move_cb = sigc::mem_fun(this, &Controller::OnPrimaryShieldMotion);
- motion_connection_ = primary_shield_->grab_motion.connect(move_cb);
+ blank_window_ = new BlankWindow();
+ blank_window_->SetBackgroundLayer(new nux::ColorLayer(nux::color::Black, true));
+ blank_window_->SetOpacity(blank_window_animator_.GetCurrentValue());
+ blank_window_->ShowWindow(true);
+ blank_window_->PushToFront();
}
+
+ blank_window_->SetGeometry(screen_geo);
+ blank_window_->SetMinMaxSize(screen_geo.width, screen_geo.height);
}
-void Controller::OnLockRequested()
+void Controller::ShowBlankWindow()
{
+ if (blank_window_ && blank_window_->GetOpacity() == 1.0)
+ return;
+
+ EnsureBlankWindow();
+ animation::StartOrReverse(blank_window_animator_, animation::Direction::FORWARD);
+}
+
+void Controller::HideBlankWindow()
+{
+ if (!blank_window_)
+ return;
+
+ blank_window_->ShowWindow(false);
+ blank_window_.Release();
+ animation::SetValue(blank_window_animator_, animation::Direction::BACKWARD);
+ lockscreen_delay_timeout_.reset();
+}
+
+void Controller::BlankWindowGrabEnable(bool grab)
+{
+ if (!blank_window_)
+ return;
+
+ if (grab)
+ {
+ for (auto const& shield : shields_)
+ {
+ shield->UnGrabPointer();
+ shield->UnGrabKeyboard();
+ }
+
+ blank_window_->EnableInputWindow(true);
+ blank_window_->GrabPointer();
+ blank_window_->GrabKeyboard();
+ blank_window_->PushToFront();
+
+ blank_window_->mouse_move.connect([this](int, int, int dx, int dy, unsigned long, unsigned long) {
+ if ((dx || dy) && !lockscreen_timeout_) HideBlankWindow();
+ });
+ blank_window_->key_down.connect([this] (unsigned long, unsigned long e, unsigned long, const char*, unsigned short) {
+ if (!lockscreen_timeout_) HideBlankWindow();
+ });
+ blank_window_->mouse_down.connect([this] (int, int, unsigned long, unsigned long) {
+ if (!lockscreen_timeout_) HideBlankWindow();
+ });
+ }
+ else
+ {
+ blank_window_->UnGrabPointer();
+ blank_window_->UnGrabKeyboard();
+
+ for (auto const& shield : shields_)
+ {
+ if (!shield->primary())
+ continue;
+
+ shield->GrabPointer();
+ shield->GrabKeyboard();
+ }
+ }
+}
+
+void Controller::OnLockRequested(bool prompt)
+{
+ if (Settings::Instance().use_legacy())
+ {
+ auto proxy = std::make_shared<glib::DBusProxy>("org.gnome.ScreenSaver", "/org/gnome/ScreenSaver", "org.gnome.ScreenSaver");
+ proxy->CallBegin("Lock", nullptr, [proxy] (GVariant*, glib::Error const&) {});
+ return;
+ }
+
if (IsLocked())
{
LOG_DEBUG(logger) << "Failed to lock screen: the screen is already locked.";
return;
}
- lockscreen_timeout_.reset(new glib::Timeout(10, [this](){
- if (WindowManager::Default().IsScreenGrabbed())
+ if (prompt)
+ {
+ EnsureBlankWindow();
+ blank_window_->SetOpacity(1.0);
+ }
+
+ prompt_activation_ = prompt;
+
+ lockscreen_timeout_.reset(new glib::Timeout(30, [this] {
+ bool grabbed_by_blank = (blank_window_ && blank_window_->OwnsPointerGrab());
+
+ if (WindowManager::Default().IsScreenGrabbed() && !grabbed_by_blank)
{
+ HideBlankWindow();
LOG_DEBUG(logger) << "Failed to lock the screen: the screen is already grabbed.";
return true; // keep trying
}
- auto lockscreen_type = Settings::Instance().lockscreen_type();
+ if (!prompt_activation_)
+ HideBlankWindow();
- if (lockscreen_type == Type::NONE)
- {
- session_manager_->unlocked.emit();
- return false;
- }
+ LockScreen();
+ session_manager_->locked.emit();
- if (lockscreen_type == Type::LIGHTDM)
- {
- LockScreenUsingDisplayManager();
- }
- else if (lockscreen_type == Type::UNITY)
+ if (prompt_activation_)
{
- LockScreenUsingUnity();
+ animation::Skip(fade_animator_);
+ HideBlankWindow();
}
- session_manager_->locked.emit();
-
+ lockscreen_timeout_.reset();
return false;
}));
}
-void Controller::LockScreenUsingDisplayManager()
+void Controller::OnPresenceStatusChanged(bool is_idle)
{
- // TODO (andy) Move to a different class (DisplayManagerWrapper)
- const char* session_path = g_getenv("XDG_SESSION_PATH");
+ if (Settings::Instance().use_legacy())
+ return;
+
+ if (is_idle)
+ {
+ ShowBlankWindow();
+ }
+ else if (!lockscreen_timeout_)
+ {
+ HideBlankWindow();
+ }
+}
- if (!session_path)
+void Controller::OnScreenSaverActivationRequest(bool activate)
+{
+ if (Settings::Instance().use_legacy())
+ {
+ auto proxy = std::make_shared<glib::DBusProxy>("org.gnome.ScreenSaver", "/org/gnome/ScreenSaver", "org.gnome.ScreenSaver");
+ proxy->CallBegin("SetActive", g_variant_new("(b)", activate != FALSE), [proxy] (GVariant*, glib::Error const&) {});
return;
+ }
- auto proxy = std::make_shared<glib::DBusProxy>(test_mode_ ? testing::DBUS_NAME : "org.freedesktop.DisplayManager",
- session_path,
- "org.freedesktop.DisplayManager.Session",
- test_mode_ ? G_BUS_TYPE_SESSION : G_BUS_TYPE_SYSTEM);
+ // It looks we need to do this after a small delay, not to get the screen back on
+ screensaver_activation_timeout_.reset(new glib::Timeout(100, [this, activate] {
+ if (dbus_manager_->active() == activate)
+ return false;
- proxy->Call("Lock", nullptr, [proxy] (GVariant*) {});
+ if (activate)
+ {
+ ShowBlankWindow();
+ animation::Skip(blank_window_animator_);
+ }
+ else
+ {
+ SimulateActivity();
+ }
- ShowShields();
- animation::Skip(fade_animator_);
+ return false;
+ }));
}
-void Controller::LockScreenUsingUnity()
+void Controller::LockScreen()
{
indicators_ = std::make_shared<indicator::LockScreenDBusIndicators>();
upstart_wrapper_->Emit("desktop-lock");
@@ -234,26 +409,26 @@ void Controller::ShowShields()
animation::StartOrReverse(fade_animator_, animation::Direction::FORWARD);
}
+void Controller::SimulateActivity()
+{
+ HideBlankWindow();
+ XResetScreenSaver(nux::GetGraphicsDisplay()->GetX11Display());
+}
+
void Controller::OnUnlockRequested()
{
lockscreen_timeout_.reset();
+ screensaver_post_lock_timeout_.reset();
- if (!IsLocked())
- return;
-
- auto lockscreen_type = Settings::Instance().lockscreen_type();
-
- if (lockscreen_type == Type::NONE)
- return;
-
+ HideBlankWindow();
HideShields();
-
- if (lockscreen_type == Type::LIGHTDM)
- animation::Skip(fade_animator_);
}
void Controller::HideShields()
{
+ if (!IsLocked())
+ return;
+
std::for_each(shields_.begin(), shields_.end(), [](nux::ObjectPtr<Shield> const& shield) {
shield->UnGrabPointer();
shield->UnGrabKeyboard();
@@ -270,11 +445,6 @@ bool Controller::IsLocked() const
return !shields_.empty();
}
-double Controller::Opacity() const
-{
- return fade_animator_.GetCurrentValue();
-}
-
bool Controller::HasOpenMenu() const
{
return primary_shield_.IsValid() ? primary_shield_->IsIndicatorOpen() : false;
diff --git a/lockscreen/LockScreenController.h b/lockscreen/LockScreenController.h
index 4ae971270..434b95c13 100644
--- a/lockscreen/LockScreenController.h
+++ b/lockscreen/LockScreenController.h
@@ -25,6 +25,7 @@
#include <UnityCore/GLibSource.h>
#include "LockScreenShieldFactory.h"
+#include "ScreenSaverDBusManager.h"
#include "unity-shared/BackgroundEffectHelper.h"
#include "unity-shared/UpstartWrapper.h"
@@ -36,41 +37,62 @@ namespace lockscreen
class Controller : public sigc::trackable
{
public:
- Controller(session::Manager::Ptr const& session_manager,
+ Controller(DBusManager::Ptr const&, session::Manager::Ptr const&,
UpstartWrapper::Ptr const& upstart_wrapper = std::make_shared<UpstartWrapper>(),
ShieldFactoryInterface::Ptr const& shield_factory = std::make_shared<ShieldFactory>(),
bool test_mode = false);
+ nux::ROProperty<double> opacity;
+
bool IsLocked() const;
bool HasOpenMenu() const;
- double Opacity() const;
private:
friend class TestLockScreenController;
void EnsureShields(std::vector<nux::Geometry> const& monitors);
- void LockScreenUsingDisplayManager();
- void LockScreenUsingUnity();
+ void EnsureBlankWindow();
+ void LockScreen();
void ShowShields();
void HideShields();
+ void ShowBlankWindow();
+ void HideBlankWindow();
+ void BlankWindowGrabEnable(bool grab);
+ void SimulateActivity();
+ void ResetPostLockScreenSaver();
- void OnLockRequested();
+ void OnLockRequested(bool prompt);
void OnUnlockRequested();
+ void OnPresenceStatusChanged(bool idle);
+ void OnScreenSaverActivationRequest(bool activate);
void OnPrimaryShieldMotion(int x, int y);
std::vector<nux::ObjectPtr<AbstractShield>> shields_;
nux::ObjectWeakPtr<AbstractShield> primary_shield_;
+ nux::ObjectPtr<nux::BaseWindow> blank_window_;
+
+ DBusManager::Ptr dbus_manager_;
session::Manager::Ptr session_manager_;
indicator::Indicators::Ptr indicators_;
UpstartWrapper::Ptr upstart_wrapper_;
ShieldFactoryInterface::Ptr shield_factory_;
+
nux::animation::AnimateValue<double> fade_animator_;
- connection::Wrapper uscreen_connection_;
- connection::Wrapper motion_connection_;
+ nux::animation::AnimateValue<double> blank_window_animator_;
+
bool test_mode_;
+ bool prompt_activation_;
BlurType old_blur_type_;
+ connection::Wrapper uscreen_connection_;
+ connection::Wrapper suspend_connection_;
+ connection::Wrapper motion_connection_;
+ connection::Wrapper key_connection_;
+
glib::Source::UniquePtr lockscreen_timeout_;
+ glib::Source::UniquePtr lockscreen_delay_timeout_;
+ glib::Source::UniquePtr screensaver_activation_timeout_;
+ glib::Source::UniquePtr screensaver_post_lock_timeout_;
};
}
diff --git a/lockscreen/LockScreenSettings.cpp b/lockscreen/LockScreenSettings.cpp
index c791be237..d1cd2a99b 100644
--- a/lockscreen/LockScreenSettings.cpp
+++ b/lockscreen/LockScreenSettings.cpp
@@ -43,18 +43,34 @@ const std::string BACKGROUND_COLOR_KEY = "background-color";
const std::string USER_BG_KEY = "draw-user-backgrounds";
const std::string DRAW_GRID_KEY = "draw-grid";
const std::string SHOW_HOSTNAME_KEY = "show-hostname";
+
+const std::string GS_SETTINGS = "org.gnome.desktop.screensaver";
+const std::string IDLE_ACTIVATION_ENABLED_KEY = "idle-activation-enabled";
+const std::string LOCK_DELAY = "lock-delay";
+const std::string LOCK_ENABLED = "lock-enabled";
+const std::string LOCK_ON_SUSPEND = "ubuntu-lock-on-suspend";
+
+const std::string A11Y_SETTINGS = "org.gnome.desktop.a11y.applications";
+const std::string USE_SCREEN_READER = "screen-reader-enabled";
+const std::string USE_OSK = "screen-keyboard-enabled";
}
struct Settings::Impl
{
Impl()
: greeter_settings_(g_settings_new(GREETER_SETTINGS.c_str()))
- , signal_(greeter_settings_, "changed", sigc::hide(sigc::hide(sigc::mem_fun(this, &Impl::UpdateSettings))))
+ , gs_settings_(g_settings_new(GS_SETTINGS.c_str()))
+ , a11y_settings_(g_settings_new(A11Y_SETTINGS.c_str()))
+ , greeter_signal_(greeter_settings_, "changed", sigc::hide(sigc::hide(sigc::mem_fun(this, &Impl::UpdateGreeterSettings))))
+ , gs_signal_(gs_settings_, "changed", sigc::hide(sigc::hide(sigc::mem_fun(this, &Impl::UpdateGSSettings))))
+ , osk_signal_(a11y_settings_, "changed", sigc::hide(sigc::hide(sigc::mem_fun(this, &Impl::UpdateA11YSettings))))
{
- UpdateSettings();
+ UpdateGreeterSettings();
+ UpdateGSSettings();
+ UpdateA11YSettings();
}
- void UpdateSettings()
+ void UpdateGreeterSettings()
{
auto* s = settings_instance;
s->font_name = glib::String(g_settings_get_string(greeter_settings_, FONT_KEY.c_str())).Str();
@@ -66,8 +82,29 @@ struct Settings::Impl
s->draw_grid = g_settings_get_boolean(greeter_settings_, DRAW_GRID_KEY.c_str()) != FALSE;
}
+ void UpdateGSSettings()
+ {
+ auto* s = settings_instance;
+ s->lock_on_blank = g_settings_get_boolean(gs_settings_, LOCK_ENABLED.c_str()) != FALSE;
+ s->lock_on_suspend = g_settings_get_boolean(gs_settings_, LOCK_ON_SUSPEND.c_str()) != FALSE;
+ s->lock_delay = g_settings_get_uint(gs_settings_, LOCK_DELAY.c_str());
+ }
+
+ void UpdateA11YSettings()
+ {
+ bool legacy = false;
+ legacy = g_settings_get_boolean(a11y_settings_, USE_SCREEN_READER.c_str()) != FALSE;
+ legacy = legacy || g_settings_get_boolean(a11y_settings_, USE_OSK.c_str()) != FALSE;
+ settings_instance->use_legacy = legacy;
+ }
+
glib::Object<GSettings> greeter_settings_;
- glib::Signal<void, GSettings*, const gchar*> signal_;
+ glib::Object<GSettings> gs_settings_;
+ glib::Object<GSettings> a11y_settings_;
+
+ glib::Signal<void, GSettings*, const gchar*> greeter_signal_;
+ glib::Signal<void, GSettings*, const gchar*> gs_signal_;
+ glib::Signal<void, GSettings*, const gchar*> osk_signal_;
};
Settings::Settings()
@@ -78,7 +115,6 @@ Settings::Settings()
}
else
{
- lockscreen_type = Type::UNITY;
settings_instance = this;
impl_.reset(new Impl());
}
diff --git a/lockscreen/LockScreenSettings.h b/lockscreen/LockScreenSettings.h
index 4e1148673..dbbe5d38c 100644
--- a/lockscreen/LockScreenSettings.h
+++ b/lockscreen/LockScreenSettings.h
@@ -27,15 +27,6 @@ namespace unity
namespace lockscreen
{
-enum class Type : int
-{
- NONE = 0, // Do nothing
- LIGHTDM, // Fallback to lightdm
- UNITY // Use custom Unity lockscreen
-};
-
-// TODO (andy) use the same options of unity-greeter
-
class Settings
{
public:
@@ -44,7 +35,6 @@ public:
static Settings& Instance();
- nux::Property<Type> lockscreen_type;
nux::Property<std::string> font_name;
nux::Property<std::string> logo;
nux::Property<std::string> background;
@@ -53,6 +43,11 @@ public:
nux::Property<bool> use_user_background;
nux::Property<bool> draw_grid;
+ nux::Property<int> lock_delay;
+ nux::Property<bool> lock_on_blank;
+ nux::Property<bool> lock_on_suspend;
+ nux::Property<bool> use_legacy;
+
static const int GRID_SIZE = 40;
private:
diff --git a/lockscreen/LockScreenShield.cpp b/lockscreen/LockScreenShield.cpp
index a204457e6..d8bafdc8f 100644
--- a/lockscreen/LockScreenShield.cpp
+++ b/lockscreen/LockScreenShield.cpp
@@ -175,6 +175,8 @@ nux::Area* Shield::FindKeyFocusArea(unsigned etype, unsigned long key_sym, unsig
{
if (primary)
{
+ grab_key.emit(modifiers, key_code);
+
if (panel_view_ && panel_view_->WillHandleKeyEvent(etype, key_sym, modifiers))
return panel_view_;
diff --git a/lockscreen/ScreenSaverDBusManager.cpp b/lockscreen/ScreenSaverDBusManager.cpp
new file mode 100644
index 000000000..52aba0e59
--- /dev/null
+++ b/lockscreen/ScreenSaverDBusManager.cpp
@@ -0,0 +1,125 @@
+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
+/*
+ * Copyright (C) 2014 Canonical Ltd
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authored by: Andrea Azzarone <andrea.azzarone@canonical.com>
+ */
+
+#include "ScreenSaverDBusManager.h"
+
+#include "LockScreenSettings.h"
+#include "GLibDBusProxy.h"
+#include "Variant.h"
+
+namespace unity
+{
+namespace lockscreen
+{
+namespace dbus
+{
+const std::string NAME = "org.gnome.ScreenSaver";
+const std::string INTERFACE = "org.gnome.ScreenSaver";
+const std::string OBJECT_PATH = "/org/gnome/ScreenSaver";
+const std::string INTROSPECTION_XML =
+R"(<node>
+ <interface name="org.gnome.ScreenSaver">
+ <method name="Lock" />
+ <method name="GetActive">
+ <arg type="b" direction="out" name="value" />
+ </method>
+ <method name="GetActiveTime">
+ <arg type="u" direction="out" name="seconds" />
+ </method>
+ <method name="SetActive">
+ <arg type="b" direction="in" name="value" />
+ </method>
+ <method name="SimulateUserActivity" />
+ <signal name="ActiveChanged">
+ <arg name="new_value" type="b" />
+ </signal>
+ </interface>
+</node>)";
+}
+
+DBusManager::DBusManager(session::Manager::Ptr const& session)
+ : active(false)
+ , session_(session)
+ , object_(std::make_shared<glib::DBusObject>(dbus::INTROSPECTION_XML, dbus::INTERFACE))
+ , time_(0)
+{
+ active.changed.connect(sigc::mem_fun(this, &DBusManager::SetActive));
+
+ // This is a workaround we use to fallback to use gnome-screensaver if the screen reader is enabled
+ Settings::Instance().use_legacy.changed.connect(sigc::hide(sigc::mem_fun(this, &DBusManager::EnsureService)));
+
+ object_->SetMethodsCallsHandler([this] (std::string const& method, GVariant* parameters) -> GVariant* {
+ if (method == "Lock")
+ {
+ session_->LockScreen();
+ }
+ else if (method == "GetActive")
+ {
+ return g_variant_new("(b)", active() ? TRUE : FALSE);
+ }
+ else if (method == "GetActiveTime")
+ {
+ return g_variant_new("(u)", time_ ? (time(nullptr) - time_) : 0);
+ }
+ else if (method == "SetActive")
+ {
+ if (glib::Variant(parameters).GetBool())
+ session_->ScreenSaverActivate();
+ else
+ session_->ScreenSaverDeactivate();
+ }
+ else if (method == "SimulateUserActivity")
+ {
+ simulate_activity.emit();
+ }
+
+ return nullptr;
+ });
+
+ EnsureService();
+}
+
+void DBusManager::EnsureService()
+{
+ if (!Settings::Instance().use_legacy())
+ {
+ if (!server_)
+ {
+ server_ = std::make_shared<glib::DBusServer>(dbus::NAME, G_BUS_TYPE_SESSION, G_BUS_NAME_OWNER_FLAGS_REPLACE);
+ server_->AddObject(object_, dbus::OBJECT_PATH);
+ }
+ }
+ else
+ {
+ server_.reset();
+
+ // Let's make GS to restart...
+ auto proxy = std::make_shared<glib::DBusProxy>("org.gnome.ScreenSaver", "/org/gnome/ScreenSaver", "org.gnome.ScreenSaver");
+ proxy->CallBegin("SimulateUserActivity", nullptr, [proxy] (GVariant*, glib::Error const&) {});
+ }
+}
+
+void DBusManager::SetActive(bool active)
+{
+ time_ = active ? time(nullptr) : 0;
+ object_->EmitSignal("ActiveChanged", g_variant_new("(b)", active ? TRUE : FALSE));
+}
+
+} // lockscreen
+} // unity
diff --git a/lockscreen/ScreenSaverDBusManager.h b/lockscreen/ScreenSaverDBusManager.h
new file mode 100644
index 000000000..a9c86a0a1
--- /dev/null
+++ b/lockscreen/ScreenSaverDBusManager.h
@@ -0,0 +1,57 @@
+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
+/*
+ * Copyright (C) 2014 Canonical Ltd
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authored by: Andrea Azzarone <andrea.azzarone@canonical.com>
+ */
+
+#ifndef UNITYSHELL_SCREENSAVER_DBUS_MANAGER_H
+#define UNITYSHELL_SCREENSAVER_DBUS_MANAGER_H
+
+#include <NuxCore/Property.h>
+#include <UnityCore/GLibDBusServer.h>
+#include <UnityCore/SessionManager.h>
+
+namespace unity
+{
+namespace lockscreen
+{
+
+class DBusManager : public sigc::trackable
+{
+public:
+ typedef std::shared_ptr<DBusManager> Ptr;
+
+ DBusManager(session::Manager::Ptr const&);
+
+ nux::Property<bool> active;
+
+ sigc::signal<void> simulate_activity;
+
+private:
+ void SetActive(bool active);
+ void EnsureService();
+
+ session::Manager::Ptr session_;
+ glib::DBusServer::Ptr server_;
+ glib::DBusObject::Ptr object_;
+
+ time_t time_;
+};
+
+} // session
+} // unity
+
+#endif