diff options
| author | William Hua <william.hua@canonical.com> | 2014-04-11 03:51:58 +1200 |
|---|---|---|
| committer | William Hua <william.hua@canonical.com> | 2014-04-11 03:51:58 +1200 |
| commit | b37a14f4fe2fd1ac43d9c6978d80b1a9e99cbc0f (patch) | |
| tree | ffb2a655178063d1a1d4c27d5711a53fc6ef11a5 /lockscreen | |
| parent | 5269ab3470d7451467bd92d2fbe95cd6801f1c3a (diff) | |
| parent | e32bd7f76dfa9651caff80c58b4f88d5b3c58879 (diff) | |
Merge trunk.
(bzr r3764.7.2)
Diffstat (limited to 'lockscreen')
| -rw-r--r-- | lockscreen/BackgroundSettings.cpp | 2 | ||||
| -rw-r--r-- | lockscreen/CMakeLists.txt | 3 | ||||
| -rw-r--r-- | lockscreen/LockScreenAbstractShield.h | 1 | ||||
| -rw-r--r-- | lockscreen/LockScreenController.cpp | 306 | ||||
| -rw-r--r-- | lockscreen/LockScreenController.h | 36 | ||||
| -rw-r--r-- | lockscreen/LockScreenSettings.cpp | 46 | ||||
| -rw-r--r-- | lockscreen/LockScreenSettings.h | 15 | ||||
| -rw-r--r-- | lockscreen/LockScreenShield.cpp | 2 | ||||
| -rw-r--r-- | lockscreen/ScreenSaverDBusManager.cpp | 125 | ||||
| -rw-r--r-- | lockscreen/ScreenSaverDBusManager.h | 57 |
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 |
