summaryrefslogtreecommitdiff
diff options
-rw-r--r--CMakeLists.txt2
-rw-r--r--UnityCore/DBusIndicators.cpp9
-rw-r--r--UnityCore/DBusIndicators.h6
-rw-r--r--UnityCore/GnomeSessionManager.cpp42
-rw-r--r--UnityCore/GnomeSessionManager.h1
-rw-r--r--UnityCore/GnomeSessionManagerImpl.h1
-rw-r--r--UnityCore/SessionManager.h5
-rw-r--r--debian/changelog32
-rw-r--r--debian/control10
-rw-r--r--hud/HudView.cpp2
-rw-r--r--lockscreen/BackgroundSettings.cpp153
-rw-r--r--lockscreen/BackgroundSettings.h55
-rw-r--r--lockscreen/CMakeLists.txt33
-rw-r--r--lockscreen/CofView.cpp41
-rw-r--r--lockscreen/CofView.h42
-rw-r--r--lockscreen/LockScreenAbstractShield.h60
-rw-r--r--lockscreen/LockScreenController.cpp260
-rw-r--r--lockscreen/LockScreenController.h76
-rw-r--r--lockscreen/LockScreenPanel.cpp225
-rw-r--r--lockscreen/LockScreenPanel.h75
-rw-r--r--lockscreen/LockScreenSettings.cpp104
-rw-r--r--lockscreen/LockScreenSettings.h66
-rw-r--r--lockscreen/LockScreenShield.cpp220
-rw-r--r--lockscreen/LockScreenShield.h67
-rw-r--r--lockscreen/LockScreenShieldFactory.cpp34
-rw-r--r--lockscreen/LockScreenShieldFactory.h51
-rw-r--r--lockscreen/UserAuthenticator.h56
-rw-r--r--lockscreen/UserAuthenticatorPam.cpp171
-rw-r--r--lockscreen/UserAuthenticatorPam.h66
-rw-r--r--lockscreen/UserPromptView.cpp282
-rw-r--r--lockscreen/UserPromptView.h81
-rw-r--r--lockscreen/pch/lockscreen_pch.hh32
-rw-r--r--panel/PanelIndicatorEntryView.cpp2
-rw-r--r--panel/PanelIndicatorsView.cpp8
-rw-r--r--panel/PanelIndicatorsView.h1
-rw-r--r--panel/PanelMenuView.cpp1
-rw-r--r--panel/PanelMenuView.h1
-rw-r--r--panel/PanelView.cpp15
-rw-r--r--plugins/unityshell/CMakeLists.txt6
-rw-r--r--plugins/unityshell/src/nux-text-entry-accessible.cpp27
-rw-r--r--plugins/unityshell/src/unity-text-input-accessible.cpp90
-rw-r--r--plugins/unityshell/src/unity-text-input-accessible.h57
-rw-r--r--plugins/unityshell/src/unitya11y.cpp5
-rw-r--r--plugins/unityshell/src/unityshell.cpp57
-rw-r--r--plugins/unityshell/src/unityshell.h7
-rw-r--r--plugins/unityshell/unityshell.xml.in20
-rw-r--r--po/POTFILES.in1
-rw-r--r--resources/cof.pngbin0 -> 4822 bytes
-rw-r--r--services/CMakeLists.txt3
-rw-r--r--services/panel-main.c23
-rw-r--r--services/panel-service.c24
-rw-r--r--services/panel-service.h2
-rw-r--r--services/unity-panel-service-lockscreen.conf.in8
-rw-r--r--shutdown/CMakeLists.txt1
-rw-r--r--shutdown/SessionDBusManager.cpp180
-rw-r--r--shutdown/SessionDBusManager.h50
-rw-r--r--shutdown/StandaloneSession.cpp1
-rw-r--r--tests/CMakeLists.txt5
-rw-r--r--tests/autopilot/unity/tests/launcher/test_icon_behavior.py2
-rw-r--r--tests/autopilot/unity/tests/launcher/test_tooltips.py5
-rw-r--r--tests/autopilot/unity/tests/test_quicklist.py17
-rw-r--r--tests/autopilot/unity/tests/test_spread.py2
-rw-r--r--tests/data/external.gschema.xml24
-rw-r--r--tests/test_gnome_session_manager.cpp88
-rw-r--r--tests/test_lockscreen_controller.cpp344
-rw-r--r--tests/test_mock_session_manager.h1
-rw-r--r--tests/test_text_input.cpp6
-rw-r--r--tests/test_upstart_wrapper.cpp90
-rw-r--r--tests/test_user_authenticator_pam.cpp58
-rw-r--r--tests/test_utils.h2
-rw-r--r--unity-shared/CMakeLists.txt1
-rw-r--r--unity-shared/GtkTexture.h64
-rw-r--r--unity-shared/IMTextEntry.cpp5
-rw-r--r--unity-shared/IMTextEntry.h2
-rw-r--r--unity-shared/MockableBaseWindow.h1
-rw-r--r--unity-shared/TextInput.cpp77
-rw-r--r--unity-shared/TextInput.h18
-rw-r--r--unity-shared/UScreen.cpp6
-rw-r--r--unity-shared/UnityWindowView.cpp2
-rw-r--r--unity-shared/UpstartWrapper.cpp74
-rw-r--r--unity-shared/UpstartWrapper.h53
-rw-r--r--unity-shared/WindowManager.h1
82 files changed, 3732 insertions, 166 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 60e12c9d5..4cde7cb0d 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -230,6 +230,7 @@ set(UNITY_PLUGIN_SHARED_DEPS
indicator3-0.4>=0.4.90
json-glib-1.0
libbamf3>=0.5.0
+ gnome-desktop-3.0
libnotify
libstartup-notification-1.0
nux-4.0>=4.0.5
@@ -263,6 +264,7 @@ add_subdirectory(dash)
add_subdirectory(launcher)
if (ENABLE_X_SUPPORT)
add_subdirectory(hud)
+ add_subdirectory(lockscreen)
add_subdirectory(panel)
add_subdirectory(decorations)
add_subdirectory(plugins/unityshell)
diff --git a/UnityCore/DBusIndicators.cpp b/UnityCore/DBusIndicators.cpp
index 7267af913..e924d7ae5 100644
--- a/UnityCore/DBusIndicators.cpp
+++ b/UnityCore/DBusIndicators.cpp
@@ -36,7 +36,8 @@ DECLARE_LOGGER(logger, "unity.indicator.dbus");
namespace
{
-const std::string SERVICE_NAME("com.canonical.Unity.Panel.Service");
+const std::string SERVICE_NAME_DESKTOP("com.canonical.Unity.Panel.Service.Desktop");
+const std::string SERVICE_NAME_LOCKSCREEN("com.canonical.Unity.Panel.Service.LockScreen");
const std::string SERVICE_PATH("/com/canonical/Unity/Panel/Service");
const std::string SERVICE_IFACE("com.canonical.Unity.Panel.Service");
} // anonymous namespace
@@ -456,13 +457,17 @@ void DBusIndicators::Impl::SyncGeometries(std::string const& name,
}
DBusIndicators::DBusIndicators()
- : pimpl(new Impl(SERVICE_NAME, this))
+ : pimpl(new Impl(SERVICE_NAME_DESKTOP, this))
{}
DBusIndicators::DBusIndicators(std::string const& dbus_name)
: pimpl(new Impl(dbus_name, this))
{}
+LockScreenDBusIndicators::LockScreenDBusIndicators()
+ : DBusIndicators(SERVICE_NAME_LOCKSCREEN)
+{}
+
DBusIndicators::~DBusIndicators()
{}
diff --git a/UnityCore/DBusIndicators.h b/UnityCore/DBusIndicators.h
index f0c9edace..a888ec86d 100644
--- a/UnityCore/DBusIndicators.h
+++ b/UnityCore/DBusIndicators.h
@@ -22,7 +22,6 @@
#include "Indicators.h"
-
namespace unity
{
namespace indicator
@@ -56,6 +55,11 @@ private:
std::unique_ptr<Impl> pimpl;
};
+struct LockScreenDBusIndicators : DBusIndicators
+{
+ LockScreenDBusIndicators();
+};
+
}
}
diff --git a/UnityCore/GnomeSessionManager.cpp b/UnityCore/GnomeSessionManager.cpp
index 4edddf80a..f1dcdbcd6 100644
--- a/UnityCore/GnomeSessionManager.cpp
+++ b/UnityCore/GnomeSessionManager.cpp
@@ -87,6 +87,23 @@ GnomeManager::Impl::Impl(GnomeManager* manager, bool test_mode)
shell_object_ = shell_server_.GetObject(shell::DBUS_INTERFACE);
shell_object_->SetMethodsCallsHandler(sigc::mem_fun(this, &Impl::OnShellMethodCall));
+ {
+ const char* session_id = test_mode_ ? "id0" : g_getenv("XDG_SESSION_ID");
+
+ login_proxy_ = std::make_shared<glib::DBusProxy>(test_mode_ ? testing::DBUS_NAME : "org.freedesktop.login1",
+ "/org/freedesktop/login1/session/" + glib::gchar_to_string(session_id),
+ "org.freedesktop.login1.Session",
+ test_mode_ ? G_BUS_TYPE_SESSION : G_BUS_TYPE_SYSTEM);
+
+ login_proxy_->Connect("Lock", [this](GVariant*){
+ manager_->lock_requested.emit();
+ });
+
+ login_proxy_->Connect("Unlock", [this](GVariant*){
+ manager_->unlock_requested.emit();
+ });
+ }
+
CallLogindMethod("CanHibernate", nullptr, [this] (GVariant* variant, glib::Error const& err) {
if (err)
{
@@ -376,9 +393,7 @@ GnomeManager::~GnomeManager()
std::string GnomeManager::RealName() const
{
- const char* name = g_get_real_name();
-
- std::string real_name(name ? name : "");
+ std::string real_name = glib::gchar_to_string(g_get_real_name());
if (real_name == "Unknown")
real_name.clear();
@@ -388,22 +403,25 @@ std::string GnomeManager::RealName() const
std::string GnomeManager::UserName() const
{
- const char* name = g_get_user_name();
+ return glib::gchar_to_string(g_get_user_name());
+}
- return name ? name : "";
+std::string GnomeManager::HostName() const
+{
+ return glib::gchar_to_string(g_get_host_name());
}
void GnomeManager::LockScreen()
{
impl_->EnsureCancelPendingAction();
- auto proxy = std::make_shared<glib::DBusProxy>(impl_->test_mode_ ? testing::DBUS_NAME : "org.gnome.ScreenSaver",
- "/org/gnome/ScreenSaver", "org.gnome.ScreenSaver");
-
- // By passing the proxy to the lambda we ensure that it will stay alive
- // until we get the last callback.
- proxy->Call("Lock", nullptr, [proxy] (GVariant*) {});
- proxy->Call("SimulateUserActivity", nullptr, [proxy] (GVariant*) {});
+ // FIXME (andy) we should ask gnome-session to emit the logind signal
+ if (UserName().find("guest-") == 0)
+ {
+ LOG_INFO(logger) << "Impossible to lock a guest session";
+ return;
+ }
+ lock_requested.emit();
}
void GnomeManager::Logout()
diff --git a/UnityCore/GnomeSessionManager.h b/UnityCore/GnomeSessionManager.h
index 6adb0593a..d32296d66 100644
--- a/UnityCore/GnomeSessionManager.h
+++ b/UnityCore/GnomeSessionManager.h
@@ -35,6 +35,7 @@ public:
std::string RealName() const;
std::string UserName() const;
+ std::string HostName() const;
void LockScreen();
void Logout();
diff --git a/UnityCore/GnomeSessionManagerImpl.h b/UnityCore/GnomeSessionManagerImpl.h
index 991d88e1c..320c0f4dd 100644
--- a/UnityCore/GnomeSessionManagerImpl.h
+++ b/UnityCore/GnomeSessionManagerImpl.h
@@ -69,6 +69,7 @@ struct GnomeManager::Impl
shell::Action pending_action_;
glib::DBusServer shell_server_;
glib::DBusObject::Ptr shell_object_;
+ glib::DBusProxy::Ptr login_proxy_;
};
} // namespace session
diff --git a/UnityCore/SessionManager.h b/UnityCore/SessionManager.h
index 64f931899..ea8b13c60 100644
--- a/UnityCore/SessionManager.h
+++ b/UnityCore/SessionManager.h
@@ -38,6 +38,7 @@ public:
virtual std::string RealName() const = 0;
virtual std::string UserName() const = 0;
+ virtual std::string HostName() const = 0;
virtual void LockScreen() = 0;
virtual void Logout() = 0;
@@ -56,6 +57,10 @@ public:
Manager(const Manager&) = delete;
Manager& operator=(const Manager&) = delete;
+ sigc::signal<void> lock_requested;
+ sigc::signal<void> unlock_requested;
+ sigc::signal<void> locked;
+ sigc::signal<void> unlocked;
sigc::signal<void, bool /* inhibitors */> logout_requested;
sigc::signal<void, bool /* inhibitors */> reboot_requested;
sigc::signal<void, bool /* inhibitors */> shutdown_requested;
diff --git a/debian/changelog b/debian/changelog
index a8d4bb0f1..a8e58d4c3 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,35 @@
+unity (7.1.2+14.04.20140311-0ubuntu1) trusty; urgency=low
+
+ [ CI bot ]
+ * Lockscreen: Multimonitor support, use greeter settings and don't
+ paint popup windows In detail:  - Use proper fonts for text input  -
+ Make text cursor to blink as expected (needs
+ lp:~3v1n0/nux/textentry-toggle-cursor-visibility)  - Use bullet as
+ password char  - Support multi-monitor correctly, switching view on
+ mouse movement (as the greeter does)  - Fixed lockscreen not showing
+ on newly attached monitors  - Never paint windows that might popup
+ under the lockscreen (such as tooltips or notifications)  - Use
+ unity greeter gsettings values for painting the Background (support
+ color, or disable user bg)  - Don't lock guest sessions
+
+ [ Stephen M. Webb ]
+ * Bump Nux build-dep to 4.0.6 for ABI change.
+
+ [ Andrea Azzarone ]
+ * Implement the lockscreen in Unity that looks like unity-greeter.
+ Also allow to fallback to lightdm + greeter (tty switching) in case
+ you need more pam power. (LP: #878836)
+
+ [ Marco Trevisan (Treviño) ]
+ * LockScreenPanel: added a light version of PanelView for Lockscreen
+ only, using PanelIndicatorsView - Indicators scrubbing using mouse
+ works again - Indicators key navigation is supported (Alt+F10
+ included) - Indicators will be correctly visible in light themes as
+ well - Show hostname (optionally) on the top left side of the panel
+ - LockScreenSettings now bind settings from unity-greeter dconf path
+
+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Tue, 11 Mar 2014 18:37:36 +0000
+
unity (7.1.2+14.04.20140305-0ubuntu1) trusty; urgency=low
[ Chris Townsend ]
diff --git a/debian/control b/debian/control
index 396e11905..111609b22 100644
--- a/debian/control
+++ b/debian/control
@@ -9,24 +9,21 @@ Build-Depends: cmake,
dh-migrations,
dh-translations (>= 94),
google-mock (>= 1.6.0+svn437),
- google-mock,
gsettings-desktop-schemas-dev,
gsettings-ubuntu-schemas (>= 0.0.1+14.04.20140219),
intltool (>= 0.35.0),
libatk1.0-dev,
libbamf3-dev (>= 0.5.0+13.10.20130731),
libboost-dev,
- libboost-serialization-dev,
libcairo2-dev,
libdbus-1-dev,
- libcompizconfig0-dev (>= 1:0.9.11),
libdbusmenu-glib-dev (>= 0.3.91),
libdee-dev (>= 1.2.6),
libgee-dev (>= 0.5.0),
libgeis-dev (>= 2.0.10),
libgl1-mesa-dri,
libglib2.0-dev (>= 2.39.1),
- libgrail-dev (>= 1.0.20),
+ libgnome-desktop-3-dev,
libgtest-dev,
libgtk-3-dev (>= 3.1),
libido3-0.1-dev (>= 13.10.0),
@@ -37,14 +34,14 @@ Build-Depends: cmake,
libnih-dbus-dev,
libnih-dev,
libnotify-dev,
- libnux-4.0-dev (>= 4.0.5),
+ libnux-4.0-dev (>= 4.0.6),
+ libpam0g-dev,
libpango1.0-dev,
libsigc++-2.0-dev,
libstartup-notification0-dev,
libunique-dev,
libunity-dev (>= 7.1.0),
libunity-misc-dev (>= 4.0.4),
- libunity-scopes-json-def-desktop,
libupstart-dev,
libxcb-icccm4-dev,
libxfixes-dev (>= 1:5.0.1-1),
@@ -77,6 +74,7 @@ Depends: ${shlibs:Depends},
nux-tools,
dconf-cli,
unity-asset-pool (>= 0.8.18),
+ unity-greeter,
bamfdaemon,
libxfixes3 (>= 1:5.0.1-1),
libxi6 (>= 2:1.7.1.901),
diff --git a/hud/HudView.cpp b/hud/HudView.cpp
index b52aed55a..035a30c9f 100644
--- a/hud/HudView.cpp
+++ b/hud/HudView.cpp
@@ -507,8 +507,6 @@ void View::DrawContent(nux::GraphicsEngine& gfx_context, bool force_draw)
GetLayout()->ProcessDraw(gfx_context, force_draw);
}
- overlay_window_buttons_->QueueDraw();
-
gfx_context.PopClippingRectangle();
renderer_.DrawInnerCleanup(gfx_context, draw_content_geo, GetAbsoluteGeometry(), GetGeometry());
diff --git a/lockscreen/BackgroundSettings.cpp b/lockscreen/BackgroundSettings.cpp
new file mode 100644
index 000000000..44dd94436
--- /dev/null
+++ b/lockscreen/BackgroundSettings.cpp
@@ -0,0 +1,153 @@
+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
+/*
+* Copyright (C) 2013 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 <Nux/Nux.h>
+#include "BackgroundSettings.h"
+
+#include <libgnome-desktop/gnome-bg.h>
+
+#include "LockScreenSettings.h"
+#include "unity-shared/CairoTexture.h"
+#include "unity-shared/PanelStyle.h"
+#include "unity-shared/UScreen.h"
+
+namespace unity
+{
+namespace lockscreen
+{
+namespace
+{
+const std::string SETTINGS_NAME = "org.gnome.desktop.background";
+
+constexpr int GetGridOffset(int size) { return (size % Settings::GRID_SIZE) / 2; }
+}
+
+BackgroundSettings::BackgroundSettings()
+ : gnome_bg_(gnome_bg_new())
+{
+ glib::Object<GSettings> settings(g_settings_new(SETTINGS_NAME.c_str()));
+ gnome_bg_load_from_preferences(gnome_bg_, settings);
+}
+
+BackgroundSettings::~BackgroundSettings()
+{}
+
+BaseTexturePtr BackgroundSettings::GetBackgroundTexture(int monitor)
+{
+ nux::Geometry const& geo = UScreen::GetDefault()->GetMonitorGeometry(monitor);
+ auto& settings = Settings::Instance();
+
+ nux::CairoGraphics cairo_graphics(CAIRO_FORMAT_ARGB32, geo.width, geo.height);
+ cairo_t* c = cairo_graphics.GetInternalContext();
+
+ cairo_surface_t* bg_surface = nullptr;
+
+ if (settings.use_user_background())
+ {
+ bg_surface = gnome_bg_create_surface(gnome_bg_, gdk_get_default_root_window(), geo.width, geo.height, FALSE);
+ }
+ else if (!settings.background().empty())
+ {
+ glib::Object<GdkPixbuf> pixbuf(gdk_pixbuf_new_from_file_at_scale(settings.background().c_str(), geo.width, geo.height, FALSE, NULL));
+
+ if (pixbuf)
+ bg_surface = gdk_cairo_surface_create_from_pixbuf(pixbuf, 0, NULL);
+ }
+
+ if (bg_surface)
+ {
+ cairo_set_source_surface(c, bg_surface, 0, 0);
+ cairo_paint(c);
+ cairo_surface_destroy(bg_surface);
+ }
+ else
+ {
+ auto const& bg_color = settings.background_color();
+ cairo_set_source_rgb(c, bg_color.red, bg_color.green, bg_color.blue);
+ cairo_paint(c);
+ }
+
+ if (!settings.logo().empty())
+ {
+ int grid_x_offset = GetGridOffset(geo.width);
+ int grid_y_offset = GetGridOffset(geo.height);
+ cairo_surface_t* logo_surface = cairo_image_surface_create_from_png(settings.logo().c_str());
+
+ if (logo_surface)
+ {
+ int height = cairo_image_surface_get_height(logo_surface);
+ int x = grid_x_offset;
+ int y = grid_y_offset + Settings::GRID_SIZE * (geo.height / Settings::GRID_SIZE - 1) - height;
+
+ cairo_save(c);
+ cairo_translate(c, x, y);
+
+ cairo_set_source_surface(c, logo_surface, 0, 0);
+ cairo_paint_with_alpha(c, 0.5);
+ cairo_surface_destroy(logo_surface);
+ cairo_restore(c);
+ }
+ }
+
+ if (settings.draw_grid())
+ {
+ 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);
+
+ // overlay grid
+ cairo_surface_t* overlay_surface = cairo_surface_create_similar(cairo_graphics.GetSurface(),
+ CAIRO_CONTENT_COLOR_ALPHA,
+ Settings::GRID_SIZE,
+ Settings::GRID_SIZE);
+
+ cairo_t* oc = cairo_create(overlay_surface);
+ cairo_rectangle(oc, 0, 0, 1, 1);
+ cairo_rectangle(oc, Settings::GRID_SIZE - 1, 0, 1, 1);
+ cairo_rectangle(oc, 0, Settings::GRID_SIZE - 1, 1, 1);
+ cairo_rectangle(oc, Settings::GRID_SIZE - 1, Settings::GRID_SIZE - 1, 1, 1);
+ cairo_set_source_rgba(oc, 1.0, 1.0, 1.0, 0.25);
+ cairo_fill(oc);
+
+ cairo_pattern_t* overlay = cairo_pattern_create_for_surface(overlay_surface);
+
+ cairo_matrix_t matrix;
+ cairo_matrix_init_identity(&matrix);
+ cairo_matrix_translate(&matrix, -grid_x_offset, -grid_y_offset);
+
+ cairo_pattern_set_matrix(overlay, &matrix);
+ cairo_pattern_set_extend(overlay, CAIRO_EXTEND_REPEAT);
+
+ cairo_save(c);
+ cairo_set_source(c, overlay);
+ cairo_rectangle(c, 0, 0, width, height);
+ cairo_fill(c);
+ cairo_restore(c);
+
+ cairo_pattern_destroy(overlay);
+ cairo_surface_destroy(overlay_surface);
+ cairo_destroy(oc);
+ }
+
+ return texture_ptr_from_cairo_graphics(cairo_graphics);
+}
+
+} // lockscreen
+} // unity
diff --git a/lockscreen/BackgroundSettings.h b/lockscreen/BackgroundSettings.h
new file mode 100644
index 000000000..c6abcbfc2
--- /dev/null
+++ b/lockscreen/BackgroundSettings.h
@@ -0,0 +1,55 @@
+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
+/*
+* Copyright (C) 2013 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 UNITY_BACKGROUND_SETTINGS_H
+#define UNITY_BACKGROUND_SETTINGS_H
+
+#include <NuxCore/ObjectPtr.h>
+#include <UnityCore/GLibWrapper.h>
+
+namespace nux
+{
+class BaseTexture;
+}
+
+class _GnomeBG;
+
+namespace unity
+{
+typedef nux::ObjectPtr<nux::BaseTexture> BaseTexturePtr;
+
+namespace lockscreen
+{
+
+class BackgroundSettings
+{
+public:
+ BackgroundSettings();
+ ~BackgroundSettings();
+
+ BaseTexturePtr GetBackgroundTexture(int monitor);
+
+private:
+ glib::Object<_GnomeBG> gnome_bg_;
+};
+
+}
+}
+
+#endif
diff --git a/lockscreen/CMakeLists.txt b/lockscreen/CMakeLists.txt
new file mode 100644
index 000000000..e755e7fee
--- /dev/null
+++ b/lockscreen/CMakeLists.txt
@@ -0,0 +1,33 @@
+set(UNITY_SRC ../plugins/unityshell/src)
+
+set (CFLAGS
+ ${CACHED_UNITY_DEPS_CFLAGS}
+ ${CACHED_UNITY_DEPS_CFLAGS_OTHER}
+ ${PIC_FLAGS}
+ )
+
+string (REPLACE ";" " " CFLAGS "${CFLAGS}")
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CFLAGS}")
+
+set (LIBS ${CACHED_UNITY_DEPS_LDFLAGS} ${UNITY_STANDALONE_LADD})
+
+include_directories (.. ../services ../UnityCore ${UNITY_SRC} ${CMAKE_BINARY_DIR})
+
+#
+# Headers & Sources
+#
+set (LOCKSCREEN_SOURCES
+ BackgroundSettings.cpp
+ CofView.cpp
+ LockScreenController.cpp
+ LockScreenSettings.cpp
+ LockScreenShield.cpp
+ LockScreenShieldFactory.cpp
+ LockScreenPanel.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_pch(pch/lockscreen_pch.hh lockscreen-lib)
diff --git a/lockscreen/CofView.cpp b/lockscreen/CofView.cpp
new file mode 100644
index 000000000..40ad382ca
--- /dev/null
+++ b/lockscreen/CofView.cpp
@@ -0,0 +1,41 @@
+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
+/*
+* Copyright (C) 2013 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 "CofView.h"
+
+#include "config.h"
+
+namespace unity
+{
+namespace lockscreen
+{
+
+CofView::CofView()
+ // FIXME (andy) if we get an svg cof we can make it fullscreen independent.
+ : IconTexture(PKGDATADIR"/cof.png", 66)
+{}
+
+nux::Area* CofView::FindAreaUnderMouse(nux::Point const& mouse_position,
+ nux::NuxEventType event_type)
+{
+ return nullptr;
+}
+
+}
+}
diff --git a/lockscreen/CofView.h b/lockscreen/CofView.h
new file mode 100644
index 000000000..60c1ca7b9
--- /dev/null
+++ b/lockscreen/CofView.h
@@ -0,0 +1,42 @@
+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
+/*
+* Copyright (C) 2013 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_COF_VIEW_H
+#define UNITYSHELL_COF_VIEW_H
+
+#include "unity-shared/IconTexture.h"
+
+namespace unity
+{
+namespace lockscreen
+{
+
+class CofView : public unity::IconTexture
+{
+public:
+ CofView();
+
+ nux::Area* FindAreaUnderMouse(nux::Point const& mouse_position,
+ nux::NuxEventType event_type) override;
+};
+
+}
+}
+
+#endif \ No newline at end of file
diff --git a/lockscreen/LockScreenAbstractShield.h b/lockscreen/LockScreenAbstractShield.h
new file mode 100644
index 000000000..584a66fe3
--- /dev/null
+++ b/lockscreen/LockScreenAbstractShield.h
@@ -0,0 +1,60 @@
+// -*- 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: Marco Trevisan <marco.trevisan@canonical.com>
+ */
+
+#ifndef UNITY_LOCKSCREEN_ABSTRACT_SHIELD_H
+#define UNITY_LOCKSCREEN_ABSTRACT_SHIELD_H
+
+#include <NuxCore/Property.h>
+#include <UnityCore/SessionManager.h>
+#include <UnityCore/Indicators.h>
+
+#include "unity-shared/MockableBaseWindow.h"
+
+namespace unity
+{
+namespace lockscreen
+{
+
+class AbstractShield : public MockableBaseWindow
+{
+public:
+ AbstractShield(session::Manager::Ptr const& session, indicator::Indicators::Ptr const& indicators, int monitor_num, bool is_primary)
+ : MockableBaseWindow("Unity Lockscreen")
+ , primary(is_primary)
+ , monitor(monitor_num)
+ , session_manager_(session)
+ , indicators_(indicators)
+ {}
+
+ nux::Property<bool> primary;
+ nux::Property<int> monitor;
+
+ virtual bool IsIndicatorOpen() const = 0;
+
+ sigc::signal<void, int, int> grab_motion;
+
+protected:
+ session::Manager::Ptr session_manager_;
+ indicator::Indicators::Ptr indicators_;
+};
+
+} // lockscreen
+} // unity
+
+#endif // UNITY_LOCKSCREEN_ABSTRACT_SHIELD_H
diff --git a/lockscreen/LockScreenController.cpp b/lockscreen/LockScreenController.cpp
new file mode 100644
index 000000000..8b4487906
--- /dev/null
+++ b/lockscreen/LockScreenController.cpp
@@ -0,0 +1,260 @@
+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
+/*
+* Copyright (C) 2013-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 "LockScreenController.h"
+
+#include <UnityCore/DBusIndicators.h>
+#include "LockScreenShield.h"
+#include "LockScreenSettings.h"
+#include "unity-shared/AnimationUtils.h"
+#include "unity-shared/UScreen.h"
+#include "unity-shared/WindowManager.h"
+
+namespace unity
+{
+namespace lockscreen
+{
+namespace
+{
+const unsigned int FADE_DURATION = 400;
+}
+
+namespace testing
+{
+const std::string DBUS_NAME = "com.canonical.Unity.Test.DisplayManager";
+}
+
+Controller::Controller(session::Manager::Ptr const& session_manager,
+ UpstartWrapper::Ptr const& upstart_wrapper,
+ ShieldFactoryInterface::Ptr const& shield_factory,
+ bool test_mode)
+ : session_manager_(session_manager)
+ , upstart_wrapper_(upstart_wrapper)
+ , shield_factory_(shield_factory)
+ , fade_animator_(FADE_DURATION)
+ , test_mode_(test_mode)
+{
+ uscreen_connection_ = UScreen::GetDefault()->changed.connect([this] (int, std::vector<nux::Geometry> const& monitors) {
+ EnsureShields(monitors);
+ });
+ uscreen_connection_->block();
+
+ session_manager_->lock_requested.connect(sigc::mem_fun(this, &Controller::OnLockRequested));
+ session_manager_->unlock_requested.connect(sigc::mem_fun(this, &Controller::OnUnlockRequested));
+
+ fade_animator_.updated.connect([this](double value) {
+ std::for_each(shields_.begin(), shields_.end(), [value](nux::ObjectPtr<Shield> const& shield) {
+ shield->SetOpacity(value);
+ });
+ });
+
+ fade_animator_.finished.connect([this] {
+ if (animation::GetDirection(fade_animator_) == animation::Direction::BACKWARD)
+ {
+ motion_connection_->disconnect();
+ uscreen_connection_->block();
+ session_manager_->unlocked.emit();
+ shields_.clear();
+
+ if (Settings::Instance().lockscreen_type() == Type::UNITY)
+ {
+ upstart_wrapper_->Emit("desktop-unlock");
+ indicators_.reset();
+ }
+ }
+ });
+}
+
+void Controller::OnPrimaryShieldMotion(int x, int y)
+{
+ if (!primary_shield_->GetAbsoluteGeometry().IsPointInside(x, y))
+ {
+ for (auto const& shield : shields_)
+ {
+ if (!shield->GetAbsoluteGeometry().IsPointInside(x, y))
+ continue;
+
+ primary_shield_->primary = false;
+ primary_shield_ = shield;
+ shield->primary = true;
+ auto move_cb = sigc::mem_fun(this, &Controller::OnPrimaryShieldMotion);
+ motion_connection_ = shield->grab_motion.connect(move_cb);
+ break;
+ }
+ }
+}
+
+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;
+
+ shields_.resize(num_monitors);
+
+ for (int i = 0; i < num_monitors; ++i)
+ {
+ auto& shield = shields_[i];
+ bool is_new = false;
+
+ if (i >= shields_size)
+ {
+ shield = shield_factory_->CreateShield(session_manager_, indicators_, i, i == primary);
+ is_new = true;
+ }
+
+ shield->SetGeometry(monitors[i]);
+ shield->SetMinMaxSize(monitors[i].width, monitors[i].height);
+ shield->primary = (i == primary);
+ shield->monitor = i;
+
+ if (is_new && fade_animator_.GetCurrentValue() > 0)
+ {
+ 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);
+ }
+}
+
+void Controller::OnLockRequested()
+{
+ if (IsLocked())
+ return;
+
+ auto lockscreen_type = Settings::Instance().lockscreen_type();
+
+ if (lockscreen_type == Type::NONE)
+ {
+ session_manager_->unlocked.emit();
+ return;
+ }
+
+ if (lockscreen_type == Type::LIGHTDM)
+ {
+ LockScreenUsingDisplayManager();
+ }
+ else if (lockscreen_type == Type::UNITY)
+ {
+ LockScreenUsingUnity();
+ }
+
+ session_manager_->locked.emit();
+}
+
+void Controller::LockScreenUsingDisplayManager()
+{
+ // TODO (andy) Move to a different class (DisplayManagerWrapper)
+ const char* session_path = g_getenv("XDG_SESSION_PATH");
+
+ if (!session_path)
+ 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);
+
+ proxy->Call("Lock", nullptr, [proxy] (GVariant*) {});
+
+ ShowShields();
+ animation::Skip(fade_animator_);
+}
+
+void Controller::LockScreenUsingUnity()
+{
+ indicators_ = std::make_shared<indicator::LockScreenDBusIndicators>();
+ upstart_wrapper_->Emit("desktop-lock");
+
+ ShowShields();
+}
+
+void Controller::ShowShields()
+{
+ old_blur_type_ = BackgroundEffectHelper::blur_type;
+ BackgroundEffectHelper::blur_type = BLUR_NONE;
+
+ WindowManager::Default().SaveInputFocus();
+ EnsureShields(UScreen::GetDefault()->GetMonitors());
+ uscreen_connection_->unblock();
+
+ std::for_each(shields_.begin(), shields_.end(), [] (nux::ObjectPtr<Shield> const& shield) {
+ shield->SetOpacity(0.0f);
+ shield->ShowWindow(true);
+ shield->PushToFront();
+ });
+
+ animation::StartOrReverse(fade_animator_, animation::Direction::FORWARD);
+}
+
+void Controller::OnUnlockRequested()
+{
+ if (!IsLocked())
+ return;
+
+ auto lockscreen_type = Settings::Instance().lockscreen_type();
+
+ if (lockscreen_type == Type::NONE)
+ return;
+
+ HideShields();
+
+ if (lockscreen_type == Type::LIGHTDM)
+ animation::Skip(fade_animator_);
+}
+
+void Controller::HideShields()
+{
+ std::for_each(shields_.begin(), shields_.end(), [](nux::ObjectPtr<Shield> const& shield) {
+ shield->UnGrabPointer();
+ shield->UnGrabKeyboard();
+ });
+
+ WindowManager::Default().RestoreInputFocus();
+ animation::StartOrReverse(fade_animator_, animation::Direction::BACKWARD);
+
+ BackgroundEffectHelper::blur_type = old_blur_type_;
+}
+
+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;
+}
+
+} // lockscreen
+} // unity
diff --git a/lockscreen/LockScreenController.h b/lockscreen/LockScreenController.h
new file mode 100644
index 000000000..3e42bfd52
--- /dev/null
+++ b/lockscreen/LockScreenController.h
@@ -0,0 +1,76 @@
+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
+/*
+* Copyright (C) 2013-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 UNITY_LOCKSCREEN_CONTROLLER_H
+#define UNITY_LOCKSCREEN_CONTROLLER_H
+
+#include <NuxCore/Animation.h>
+#include <UnityCore/ConnectionManager.h>
+
+#include "LockScreenShieldFactory.h"
+#include "unity-shared/BackgroundEffectHelper.h"
+#include "unity-shared/UpstartWrapper.h"
+
+namespace unity
+{
+namespace lockscreen
+{
+
+class Controller : public sigc::trackable
+{
+public:
+ Controller(session::Manager::Ptr const& session_manager,
+ UpstartWrapper::Ptr const& upstart_wrapper = std::make_shared<UpstartWrapper>(),
+ ShieldFactoryInterface::Ptr const& shield_factory = std::make_shared<ShieldFactory>(),
+ bool test_mode = false);
+
+ 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 ShowShields();
+ void HideShields();
+
+ void OnLockRequested();
+ void OnUnlockRequested();
+ void OnPrimaryShieldMotion(int x, int y);
+
+ std::vector<nux::ObjectPtr<AbstractShield>> shields_;
+ nux::ObjectWeakPtr<AbstractShield> primary_shield_;
+ 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_;
+ bool test_mode_;
+ BlurType old_blur_type_;
+};
+
+}
+}
+
+#endif \ No newline at end of file
diff --git a/lockscreen/LockScreenPanel.cpp b/lockscreen/LockScreenPanel.cpp
new file mode 100644
index 000000000..b110ec70c
--- /dev/null
+++ b/lockscreen/LockScreenPanel.cpp
@@ -0,0 +1,225 @@
+// -*- 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: Marco Trevisan <marco.trevisan@canonical.com>
+ */
+
+#include "LockScreenPanel.h"
+
+#include <boost/algorithm/string/trim.hpp>
+#include <Nux/HLayout.h>
+
+#include "LockScreenSettings.h"
+#include "panel/PanelIndicatorsView.h"
+#include "unity-shared/CairoTexture.h"
+#include "unity-shared/StaticCairoText.h"
+#include "unity-shared/PanelStyle.h"
+#include "unity-shared/RawPixel.h"
+#include "unity-shared/UnitySettings.h"
+#include "unity-shared/WindowManager.h"
+
+namespace unity
+{
+namespace lockscreen
+{
+namespace
+{
+const RawPixel PADDING = 5_em;
+}
+
+using namespace indicator;
+using namespace panel;
+
+Panel::Panel(int monitor_, Indicators::Ptr const& indicators, session::Manager::Ptr const& session_manager)
+ : nux::View(NUX_TRACKER_LOCATION)
+ , active(false)
+ , monitor(monitor_)
+ , indicators_(indicators)
+ , needs_geo_sync_(true)
+{
+ double scale = unity::Settings::Instance().em(monitor)->DPIScale();
+ auto* layout = new nux::HLayout();
+ layout->SetLeftAndRightPadding(PADDING.CP(scale), 0);
+ SetLayout(layout);
+
+ BuildTexture();
+
+ // Add setting
+ auto *hostname = new StaticCairoText(session_manager->HostName());
+ hostname->SetFont(Settings::Instance().font_name());
+ hostname->SetTextColor(nux::color::White);
+ hostname->SetInputEventSensitivity(false);
+ hostname->SetScale(scale);
+ hostname->SetVisible(Settings::Instance().show_hostname());
+ layout->AddView(hostname, 1, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL);
+
+ indicators_view_ = new PanelIndicatorsView();
+ indicators_view_->SetMonitor(monitor);
+ indicators_view_->OverlayShown();
+ indicators_view_->on_indicator_updated.connect(sigc::mem_fun(this, &Panel::OnIndicatorViewUpdated));
+ layout->AddView(indicators_view_, 1, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL);
+
+ for (auto const& indicator : indicators_->GetIndicators())
+ AddIndicator(indicator);
+
+ indicators_->on_object_added.connect(sigc::mem_fun(this, &Panel::AddIndicator));
+ indicators_->on_object_removed.connect(sigc::mem_fun(this, &Panel::RemoveIndicator));
+ indicators_->on_entry_show_menu.connect(sigc::mem_fun(this, &Panel::OnEntryShowMenu));
+ indicators_->on_entry_activated.connect(sigc::mem_fun(this, &Panel::OnEntryActivated));
+ indicators_->on_entry_activate_request.connect(sigc::mem_fun(this, &Panel::OnEntryActivateRequest));
+
+ monitor.changed.connect([this, hostname] (int monitor) {
+ hostname->SetScale(unity::Settings::Instance().em(monitor)->DPIScale());
+ indicators_view_->SetMonitor(monitor);
+ BuildTexture();
+ QueueRelayout();
+ });
+}
+
+void Panel::BuildTexture()
+{
+ int height = panel::Style::Instance().PanelHeight(monitor);
+ nux::CairoGraphics context(CAIRO_FORMAT_ARGB32, 1, height);
+ auto* cr = context.GetInternalContext();
+ cairo_set_source_rgb(cr, 0.1, 0.1, 0.1);
+ cairo_paint_with_alpha(cr, 0.4);
+ bg_texture_ = texture_ptr_from_cairo_graphics(context);
+
+ view_layout_->SetMinimumHeight(height);
+ view_layout_->SetMaximumHeight(height);
+}
+
+void Panel::AddIndicator(Indicator::Ptr const& indicator)
+{
+ if (indicator->IsAppmenu())
+ return;
+
+ indicators_view_->AddIndicator(indicator);
+ QueueRelayout();
+ QueueDraw();
+}
+
+void Panel::RemoveIndicator(indicator::Indicator::Ptr const& indicator)
+{
+ indicators_view_->RemoveIndicator(indicator);
+ QueueRelayout();
+ QueueDraw();
+}
+
+std::string Panel::GetPanelName() const
+{
+ return "LockScreenPanel" + std::to_string(monitor);
+}
+
+void Panel::OnIndicatorViewUpdated()
+{
+ needs_geo_sync_ = true;
+ QueueRelayout();
+ QueueDraw();
+}
+
+void Panel::OnEntryShowMenu(std::string const& entry_id, unsigned xid, int x, int y, unsigned button)
+{
+ if (!GetInputEventSensitivity())
+ return;
+
+ // This is ugly... But Nux fault!
+ WindowManager::Default().UnGrabMousePointer(CurrentTime, button, x, y);
+
+ active = true;
+}
+
+void Panel::OnEntryActivateRequest(std::string const& entry_id)
+{
+ if (GetInputEventSensitivity())
+ indicators_view_->ActivateEntry(entry_id, 0);
+}
+
+void Panel::ActivateFirst()
+{
+ if (GetInputEventSensitivity())
+ indicators_view_->ActivateIfSensitive();
+}
+
+void Panel::OnEntryActivated(std::string const& panel, std::string const& entry_id, nux::Rect const&)
+{
+ if (!GetInputEventSensitivity() || (!panel.empty() && panel != GetPanelName()))
+ return;
+
+ bool active = !entry_id.empty();
+ if (active && !track_menu_pointer_timeout_)
+ {
+ track_menu_pointer_timeout_.reset(new glib::Timeout(16));
+ track_menu_pointer_timeout_->Run([this] {
+ nux::Point const& mouse = nux::GetGraphicsDisplay()->GetMouseScreenCoord();
+ if (tracked_pointer_pos_ != mouse)
+ {
+ if (GetAbsoluteGeometry().IsPointInside(mouse.x, mouse.y))
+ indicators_view_->ActivateEntryAt(mouse.x, mouse.y);
+
+ tracked_pointer_pos_ = mouse;
+ }
+
+ return true;
+ });
+ }
+ else if (!active)
+ {
+ track_menu_pointer_timeout_.reset();
+ tracked_pointer_pos_ = {-1, -1};
+ this->active = false;
+ }
+}
+
+void Panel::Draw(nux::GraphicsEngine& graphics_engine, bool force_draw)
+{
+ auto const& geo = GetGeometry();
+
+ unsigned int alpha, src, dest = 0;
+ graphics_engine.GetRenderStates().GetBlend(alpha, src, dest);
+ graphics_engine.GetRenderStates().SetBlend(true, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+
+ graphics_engine.PushClippingRectangle(geo);
+ nux::GetPainter().PaintBackground(graphics_engine, geo);
+
+ nux::TexCoordXForm texxform;
+ texxform.SetWrap(nux::TEXWRAP_REPEAT, nux::TEXWRAP_CLAMP);
+ graphics_engine.QRP_1Tex(geo.x, geo.y, geo.width, geo.height,
+ bg_texture_->GetDeviceTexture(), texxform,
+ nux::color::White);
+
+ view_layout_->ProcessDraw(graphics_engine, force_draw);
+
+ graphics_engine.PopClippingRectangle();
+ graphics_engine.GetRenderStates().SetBlend(alpha, src, dest);
+
+ if (needs_geo_sync_)
+ {
+ EntryLocationMap locations;
+ indicators_view_->GetGeometryForSync(locations);
+ indicators_->SyncGeometries(GetPanelName(), locations);
+ needs_geo_sync_ = false;
+ }
+}
+
+bool Panel::InspectKeyEvent(unsigned int event_type, unsigned int keysym, const char*)
+{
+ ActivateFirst();
+ return true;
+}
+
+}
+}
diff --git a/lockscreen/LockScreenPanel.h b/lockscreen/LockScreenPanel.h
new file mode 100644
index 000000000..4221cc430
--- /dev/null
+++ b/lockscreen/LockScreenPanel.h
@@ -0,0 +1,75 @@
+// -*- 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: Marco Trevisan <marco.trevisan@canonical.com>
+ */
+
+#ifndef UNITY_LOCKSCREEN_PANEL
+#define UNITY_LOCKSCREEN_PANEL
+
+#include <Nux/Nux.h>
+#include <Nux/View.h>
+#include <UnityCore/Indicators.h>
+#include <UnityCore/GLibSource.h>
+#include <UnityCore/SessionManager.h>
+
+namespace unity
+{
+namespace panel
+{
+class PanelIndicatorsView;
+}
+
+namespace lockscreen
+{
+
+class Panel : public nux::View
+{
+public:
+ Panel(int monitor, indicator::Indicators::Ptr const&, session::Manager::Ptr const&);
+
+ nux::Property<bool> active;
+ nux::Property<int> monitor;
+
+protected:
+ void Draw(nux::GraphicsEngine& GfxContext, bool force_draw) override;
+ bool InspectKeyEvent(unsigned int event_type, unsigned int keysym, const char*) override;
+
+private:
+ void ActivateFirst();
+ void AddIndicator(indicator::Indicator::Ptr const&);
+ void RemoveIndicator(indicator::Indicator::Ptr const&);
+ void OnIndicatorViewUpdated();
+ void OnEntryActivated(std::string const& panel, std::string const& entry_id, nux::Rect const& geo);
+ void OnEntryShowMenu(std::string const& entry_id, unsigned xid, int x, int y, unsigned button);
+ void OnEntryActivateRequest(std::string const& entry_id);
+
+ void BuildTexture();
+ std::string GetPanelName() const;
+
+ indicator::Indicators::Ptr indicators_;
+ panel::PanelIndicatorsView* indicators_view_;
+ nux::ObjectPtr<nux::BaseTexture> bg_texture_;
+
+ bool needs_geo_sync_;
+ nux::Point tracked_pointer_pos_;
+ glib::Source::UniquePtr track_menu_pointer_timeout_;
+};
+
+} // lockscreen namespace
+} // unity namespace
+
+#endif // UNITY_LOCKSCREEN_PANEL
diff --git a/lockscreen/LockScreenSettings.cpp b/lockscreen/LockScreenSettings.cpp
new file mode 100644
index 000000000..c791be237
--- /dev/null
+++ b/lockscreen/LockScreenSettings.cpp
@@ -0,0 +1,104 @@
+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
+/*
+* Copyright (C) 2013 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 "LockScreenSettings.h"
+
+#include <NuxCore/Logger.h>
+#include <sigc++/adaptors/hide.h>
+#include <UnityCore/GLibSignal.h>
+#include <UnityCore/GLibWrapper.h>
+
+namespace unity
+{
+namespace lockscreen
+{
+
+DECLARE_LOGGER(logger, "unity.lockscreen.settings");
+
+namespace
+{
+Settings* settings_instance = nullptr;
+
+const std::string GREETER_SETTINGS = "com.canonical.unity-greeter";
+const std::string LOGO_KEY = "logo";
+const std::string FONT_KEY = "font-name";
+const std::string BACKGROUND_KEY = "background";
+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";
+}
+
+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))))
+ {
+ UpdateSettings();
+ }
+
+ void UpdateSettings()
+ {
+ auto* s = settings_instance;
+ s->font_name = glib::String(g_settings_get_string(greeter_settings_, FONT_KEY.c_str())).Str();
+ s->logo = glib::String(g_settings_get_string(greeter_settings_, LOGO_KEY.c_str())).Str();
+ s->background = glib::String(g_settings_get_string(greeter_settings_, BACKGROUND_KEY.c_str())).Str();
+ s->background_color = nux::Color(glib::String(g_settings_get_string(greeter_settings_, BACKGROUND_COLOR_KEY.c_str())).Str());
+ s->show_hostname = g_settings_get_boolean(greeter_settings_, SHOW_HOSTNAME_KEY.c_str()) != FALSE;
+ s->use_user_background = g_settings_get_boolean(greeter_settings_, USER_BG_KEY.c_str()) != FALSE;
+ s->draw_grid = g_settings_get_boolean(greeter_settings_, DRAW_GRID_KEY.c_str()) != FALSE;
+ }
+
+ glib::Object<GSettings> greeter_settings_;
+ glib::Signal<void, GSettings*, const gchar*> signal_;
+};
+
+Settings::Settings()
+{
+ if (settings_instance)
+ {
+ LOG_ERROR(logger) << "More than one lockscreen::Settings created.";
+ }
+ else
+ {
+ lockscreen_type = Type::UNITY;
+ settings_instance = this;
+ impl_.reset(new Impl());
+ }
+}
+
+Settings::~Settings()
+{
+ if (settings_instance == this)
+ settings_instance = nullptr;
+}
+
+Settings& Settings::Instance()
+{
+ if (!settings_instance)
+ {
+ LOG_ERROR(logger) << "No lockscreen::Settings created yet.";
+ }
+
+ return *settings_instance;
+}
+
+}
+}
diff --git a/lockscreen/LockScreenSettings.h b/lockscreen/LockScreenSettings.h
new file mode 100644
index 000000000..4e1148673
--- /dev/null
+++ b/lockscreen/LockScreenSettings.h
@@ -0,0 +1,66 @@
+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
+/*
+* Copyright (C) 2013 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 UNITY_LOCKSCREEN_SETTINGS_H
+#define UNITY_LOCKSCREEN_SETTINGS_H
+
+#include <NuxCore/Property.h>
+
+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:
+ Settings();
+ ~Settings();
+
+ static Settings& Instance();
+
+ nux::Property<Type> lockscreen_type;
+ nux::Property<std::string> font_name;
+ nux::Property<std::string> logo;
+ nux::Property<std::string> background;
+ nux::Property<nux::Color> background_color;
+ nux::Property<bool> show_hostname;
+ nux::Property<bool> use_user_background;
+ nux::Property<bool> draw_grid;
+
+ static const int GRID_SIZE = 40;
+
+private:
+ struct Impl;
+ std::unique_ptr<Impl> impl_;
+};
+
+}
+}
+
+#endif
diff --git a/lockscreen/LockScreenShield.cpp b/lockscreen/LockScreenShield.cpp
new file mode 100644
index 000000000..da8372103
--- /dev/null
+++ b/lockscreen/LockScreenShield.cpp
@@ -0,0 +1,220 @@
+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
+/*
+* Copyright (C) 2013 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 "LockScreenShield.h"
+
+#include <Nux/VLayout.h>
+#include <Nux/HLayout.h>
+#include <Nux/PaintLayer.h>
+
+#include "BackgroundSettings.h"
+#include "CofView.h"
+#include "LockScreenPanel.h"
+#include "LockScreenSettings.h"
+#include "UserPromptView.h"
+#include "unity-shared/UScreen.h"
+#include "unity-shared/WindowManager.h"
+
+namespace unity
+{
+namespace lockscreen
+{
+
+Shield::Shield(session::Manager::Ptr const& session_manager, indicator::Indicators::Ptr const& indicators, int monitor_num, bool is_primary)
+ : AbstractShield(session_manager, indicators, monitor_num, is_primary)
+ , bg_settings_(std::make_shared<BackgroundSettings>())
+ , prompt_view_(nullptr)
+ , panel_view_(nullptr)
+{
+ is_primary ? ShowPrimaryView() : ShowSecondaryView();
+
+ EnableInputWindow(true);
+
+ geometry_changed.connect([this] (nux::Area*, nux::Geometry&) { UpdateBackgroundTexture();});
+
+ monitor.changed.connect([this] (int monitor) {
+ if (panel_view_)
+ panel_view_->monitor = monitor;
+
+ UpdateBackgroundTexture();
+ });
+
+ primary.changed.connect([this] (bool is_primary) {
+ if (!is_primary)
+ {
+ UnGrabPointer();
+ UnGrabKeyboard();
+ }
+
+ is_primary ? ShowPrimaryView() : ShowSecondaryView();
+ if (panel_view_) panel_view_->SetInputEventSensitivity(is_primary);
+ QueueRelayout();
+ QueueDraw();
+ });
+
+ mouse_move.connect([this] (int x, int y, int, int, unsigned long, unsigned long) {
+ auto const& abs_geo = GetAbsoluteGeometry();
+ grab_motion.emit(abs_geo.x + x, abs_geo.y + y);
+ });
+}
+
+void Shield::UpdateBackgroundTexture()
+{
+ auto const& monitor_geo = UScreen::GetDefault()->GetMonitorGeometry(monitor);
+
+ if (!background_layer_ || monitor_geo != background_layer_->GetGeometry())
+ {
+ auto background_texture = bg_settings_->GetBackgroundTexture(monitor);
+ background_layer_.reset(new nux::TextureLayer(background_texture->GetDeviceTexture(), nux::TexCoordXForm(), nux::color::White, true));
+ SetBackgroundLayer(background_layer_.get());
+ }
+}
+
+void Shield::ShowPrimaryView()
+{
+ GrabPointer();
+ GrabKeyboard();
+
+ if (primary_layout_)
+ {
+ SetLayout(primary_layout_.GetPointer());
+ return;
+ }
+
+ nux::Layout* main_layout = new nux::VLayout();
+ primary_layout_ = main_layout;
+ SetLayout(primary_layout_.GetPointer());
+
+ main_layout->AddView(CreatePanel());
+
+ nux::HLayout* prompt_layout = new nux::HLayout();
+ prompt_layout->SetLeftAndRightPadding(2 * Settings::GRID_SIZE);
+
+ prompt_view_ = CreatePromptView();
+ prompt_layout->AddView(prompt_view_);
+
+ // 10 is just a random number to center the prompt view.
+ main_layout->AddSpace(0, 10);
+ main_layout->AddLayout(prompt_layout);
+ main_layout->AddSpace(0, 10);
+}
+
+void Shield::ShowSecondaryView()
+{
+ if (cof_layout_)
+ {
+ SetLayout(cof_layout_.GetPointer());
+ return;
+ }
+
+ nux::Layout* main_layout = new nux::VLayout();
+ cof_layout_ = main_layout;
+ SetLayout(cof_layout_.GetPointer());
+
+ // The circle of friends
+ CofView* cof_view = new CofView();
+ main_layout->AddView(cof_view);
+}
+
+Panel* Shield::CreatePanel()
+{
+ if (!indicators_ || !session_manager_)
+ return nullptr;
+
+ panel_view_ = new Panel(monitor, indicators_, session_manager_);
+ panel_active_conn_ = panel_view_->active.changed.connect([this] (bool active) {
+ if (primary())
+ {
+ if (active)
+ {
+ UnGrabPointer();
+ UnGrabKeyboard();
+ }
+ else
+ {
+ GrabPointer();
+ GrabKeyboard();
+ }
+ }
+ });
+
+ return panel_view_;
+}
+
+UserPromptView* Shield::CreatePromptView()
+{
+ auto* prompt_view = new UserPromptView(session_manager_);
+
+ auto width = 8 * Settings::GRID_SIZE;
+ auto height = 3 * Settings::GRID_SIZE;
+
+ prompt_view->SetMinimumWidth(width);
+ prompt_view->SetMaximumWidth(width);
+ prompt_view->SetMinimumHeight(height);
+
+ return prompt_view;
+}
+
+nux::Area* Shield::FindKeyFocusArea(unsigned etype, unsigned long key_code, unsigned long modifiers)
+{
+ if (primary)
+ {
+ if (panel_view_)
+ {
+ modifiers &= (nux::NUX_STATE_ALT | nux::NUX_STATE_CTRL | nux::NUX_STATE_SUPER | nux::NUX_STATE_SHIFT);
+ auto const& indicators_key = WindowManager::Default().activate_indicators_key();
+
+ if (indicators_key.first == modifiers && indicators_key.second == key_code)
+ return panel_view_;
+ }
+
+ if (prompt_view_)
+ {
+ auto* focus_view = prompt_view_->focus_view();
+
+ if (focus_view && focus_view->GetInputEventSensitivity())
+ return focus_view;
+ }
+ }
+
+ return nullptr;
+}
+
+bool Shield::AcceptKeyNavFocus()
+{
+ return false;
+}
+
+nux::Area* Shield::FindAreaUnderMouse(nux::Point const& mouse, nux::NuxEventType event_type)
+{
+ nux::Area* area = BaseWindow::FindAreaUnderMouse(mouse, event_type);
+
+ if (!area && primary)
+ return this;
+
+ return area;
+}
+
+bool Shield::IsIndicatorOpen() const
+{
+ return panel_view_ ? panel_view_->active() : false;
+}
+
+}
+}
diff --git a/lockscreen/LockScreenShield.h b/lockscreen/LockScreenShield.h
new file mode 100644
index 000000000..b4c951bab
--- /dev/null
+++ b/lockscreen/LockScreenShield.h
@@ -0,0 +1,67 @@
+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
+/*
+* Copyright (C) 2013 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 UNITY_LOCKSCREEN_SHIELD_H
+#define UNITY_LOCKSCREEN_SHIELD_H
+
+#include <UnityCore/ConnectionManager.h>
+#include "LockScreenAbstractShield.h"
+
+namespace unity
+{
+namespace lockscreen
+{
+
+class BackgroundSettings;
+class UserAuthenticator;
+class UserPromptView;
+class Panel;
+
+class Shield : public AbstractShield
+{
+public:
+ Shield(session::Manager::Ptr const&, indicator::Indicators::Ptr const&, int monitor, bool is_primary);
+
+ bool IsIndicatorOpen() const;
+
+protected:
+ bool AcceptKeyNavFocus() override;
+ nux::Area* FindKeyFocusArea(unsigned int, unsigned long, unsigned long) override;
+ nux::Area* FindAreaUnderMouse(nux::Point const&, nux::NuxEventType) override;
+
+private:
+ void UpdateBackgroundTexture();
+ void ShowPrimaryView();
+ void ShowSecondaryView();
+ Panel* CreatePanel();
+ UserPromptView* CreatePromptView();
+
+ std::shared_ptr<BackgroundSettings> bg_settings_;
+ std::unique_ptr<nux::AbstractPaintLayer> background_layer_;
+ nux::ObjectPtr<nux::Layout> primary_layout_;
+ nux::ObjectPtr<nux::Layout> cof_layout_;
+ connection::Wrapper panel_active_conn_;
+ UserPromptView* prompt_view_;
+ Panel* panel_view_;
+};
+
+}
+}
+
+#endif \ No newline at end of file
diff --git a/lockscreen/LockScreenShieldFactory.cpp b/lockscreen/LockScreenShieldFactory.cpp
new file mode 100644
index 000000000..4932ca5c4
--- /dev/null
+++ b/lockscreen/LockScreenShieldFactory.cpp
@@ -0,0 +1,34 @@
+// -*- 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 "LockScreenShieldFactory.h"
+#include "LockScreenShield.h"
+
+namespace unity
+{
+namespace lockscreen
+{
+
+nux::ObjectPtr<AbstractShield> ShieldFactory::CreateShield(session::Manager::Ptr const& session_manager, indicator::Indicators::Ptr const& indicators, int monitor, bool is_primary)
+{
+ return nux::ObjectPtr<Shield>(new Shield(session_manager, indicators, monitor, is_primary));
+}
+
+}
+}
diff --git a/lockscreen/LockScreenShieldFactory.h b/lockscreen/LockScreenShieldFactory.h
new file mode 100644
index 000000000..19b3894fa
--- /dev/null
+++ b/lockscreen/LockScreenShieldFactory.h
@@ -0,0 +1,51 @@
+// -*- 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 UNITY_LOCKSCREEN_SHIELD_FACTORY
+#define UNITY_LOCKSCREEN_SHIELD_FACTORY
+
+#include <Nux/Nux.h>
+#include "LockScreenAbstractShield.h"
+
+namespace unity
+{
+
+class MockableBaseWindow;
+
+namespace lockscreen
+{
+
+struct ShieldFactoryInterface
+{
+ typedef std::shared_ptr<ShieldFactoryInterface> Ptr;
+
+ virtual ~ShieldFactoryInterface() = default;
+
+ virtual nux::ObjectPtr<AbstractShield> CreateShield(session::Manager::Ptr const&, indicator::Indicators::Ptr const&, int monitor, bool is_primary) = 0;
+};
+
+struct ShieldFactory : ShieldFactoryInterface
+{
+ nux::ObjectPtr<AbstractShield> CreateShield(session::Manager::Ptr const&, indicator::Indicators::Ptr const&, int monitor, bool is_primary) override;
+};
+
+}
+}
+
+#endif
diff --git a/lockscreen/UserAuthenticator.h b/lockscreen/UserAuthenticator.h
new file mode 100644
index 000000000..a8b46b816
--- /dev/null
+++ b/lockscreen/UserAuthenticator.h
@@ -0,0 +1,56 @@
+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
+/*
+ * Copyright (C) 2013 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 UNITY_USER_AUTHENTICATOR_H
+#define UNITY_USER_AUTHENTICATOR_H
+
+#include <future>
+#include <functional>
+#include <memory>
+#include <sigc++/signal.h>
+#include <string>
+
+namespace unity
+{
+namespace lockscreen
+{
+
+typedef std::shared_ptr<std::promise<std::string>> PromiseAuthCodePtr;
+
+class UserAuthenticator
+{
+public:
+ typedef std::function<void(bool)> AuthenticateEndCallback;
+
+ virtual ~UserAuthenticator() = default;
+
+ // Authenticate the user in a background thread.
+ virtual bool AuthenticateStart(std::string const& username, AuthenticateEndCallback const&) = 0;
+
+ sigc::signal<void, std::string, PromiseAuthCodePtr const&> echo_on_requested;
+ sigc::signal<void, std::string, PromiseAuthCodePtr const&> echo_off_requested;
+ sigc::signal<void, std::string> message_requested;
+ sigc::signal<void, std::string> error_requested;
+ sigc::signal<void> clear_prompts;
+};
+
+} // lockscreen
+} // unity
+
+ #endif // UNITY_USER_AUTHENTICATOR_H
diff --git a/lockscreen/UserAuthenticatorPam.cpp b/lockscreen/UserAuthenticatorPam.cpp
new file mode 100644
index 000000000..73e3c1d70
--- /dev/null
+++ b/lockscreen/UserAuthenticatorPam.cpp
@@ -0,0 +1,171 @@
+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
+/*
+ * Copyright (C) 2013 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>
+ */
+
+// Kindly inspired by user_authenticator_linux.cc of chromium project
+// In the future would be nice to have something less static. For the moment
+// let's just fallcback to lightdm.
+
+#include "UserAuthenticatorPam.h"
+
+#include <cstring>
+#include <security/pam_appl.h>
+#include <vector>
+
+namespace unity
+{
+namespace lockscreen
+{
+
+bool UserAuthenticatorPam::AuthenticateStart(std::string const& username,
+ AuthenticateEndCallback const& authenticate_cb)
+{
+ first_prompt_ = true;
+ username_ = username;
+ authenticate_cb_ = authenticate_cb;
+
+ if (!InitPam())
+ return false;
+
+ glib::Object<GTask> task(g_task_new(nullptr, cancellable_, [] (GObject*, GAsyncResult*, gpointer data) {
+ auto self = static_cast<UserAuthenticatorPam*>(data);
+ pam_end(self->pam_handle_, self->status_);
+ self->authenticate_cb_(self->status_ == PAM_SUCCESS);
+ }, this));
+
+ g_task_set_task_data(task, this, nullptr);
+
+ g_task_run_in_thread(task, [] (GTask* task, gpointer, gpointer data, GCancellable*) {
+ auto self = static_cast<UserAuthenticatorPam*>(data);
+ self->status_ = pam_authenticate(self->pam_handle_, 0);
+ });
+
+ return true;
+}
+
+bool UserAuthenticatorPam::InitPam()
+{
+ pam_conv conversation;
+ conversation.conv = ConversationFunction;
+ conversation.appdata_ptr = static_cast<void*>(this);
+
+ // FIXME (andy) We should install our own unityshell pam file.
+ return pam_start("lightdm", username_.c_str(),
+ &conversation, &pam_handle_) == PAM_SUCCESS;
+}
+
+int UserAuthenticatorPam::ConversationFunction(int num_msg,
+ const pam_message** msg,
+ pam_response** resp,
+ void* appdata_ptr)
+{
+ if (num_msg <= 0)
+ return PAM_CONV_ERR;
+
+ auto* tmp_response = static_cast<pam_response*>(calloc(num_msg, sizeof(pam_response)));
+
+ if (!tmp_response)
+ return PAM_CONV_ERR;
+
+ UserAuthenticatorPam* user_auth = static_cast<UserAuthenticatorPam*>(appdata_ptr);
+
+ if (!user_auth->first_prompt_)
+ {
+ // Adding a timeout ensures that the signal is emitted in the main thread
+ user_auth->source_manager_.AddTimeout(0, [user_auth] { user_auth->clear_prompts.emit(); return false; });
+ }
+
+ user_auth->first_prompt_ = false;
+
+ bool raise_error = false;
+ int count;
+ std::vector<PromiseAuthCodePtr> promises;
+
+ for (count = 0; count < num_msg && !raise_error; ++count)
+ {
+ switch (msg[count]->msg_style)
+ {
+ case PAM_PROMPT_ECHO_ON:
+ {
+ auto promise = std::make_shared<std::promise<std::string>>();
+ promises.push_back(promise);
+
+ // Adding a timeout ensures that the signal is emitted in the main thread
+ std::string message(msg[count]->msg);
+ user_auth->source_manager_.AddTimeout(0, [user_auth, message, promise] { user_auth->echo_on_requested.emit(message, promise); return false; });
+ break;
+ }
+ case PAM_PROMPT_ECHO_OFF:
+ {
+ auto promise = std::make_shared<std::promise<std::string>>();
+ promises.push_back(promise);
+
+ // Adding a timeout ensures that the signal is emitted in the main thread
+ std::string message(msg[count]->msg);
+ user_auth->source_manager_.AddTimeout(0, [user_auth, message, promise] { user_auth->echo_off_requested.emit(message, promise); return false; });
+ break;
+ }
+ case PAM_TEXT_INFO:
+ {
+ // Adding a timeout ensures that the signal is emitted in the main thread
+ std::string message(msg[count]->msg);
+ user_auth->source_manager_.AddTimeout(0, [user_auth, message] { user_auth->message_requested.emit(message); return false; });
+ break;
+ }
+ default:
+ {
+ // Adding a timeout ensures that the signal is emitted in the main thread
+ std::string message(msg[count]->msg);
+ user_auth->source_manager_.AddTimeout(0, [user_auth, message] { user_auth->error_requested.emit(message); return false; });
+ }
+ }
+ }
+
+ int i = 0;
+
+ for (auto const& promise : promises)
+ {
+ auto future = promise->get_future();
+ pam_response* resp_item = &tmp_response[i++];
+ resp_item->resp_retcode = 0;
+ resp_item->resp = strdup(future.get().c_str());
+
+ if (!resp_item->resp)
+ {
+ raise_error = true;
+ break;
+ }
+ }
+
+ if (raise_error)
+ {
+ for (int i = 0; i < count; ++i)
+ free(tmp_response[i].resp);
+
+ free(tmp_response);
+ return PAM_CONV_ERR;
+ }
+ else
+ {
+ *resp = tmp_response;
+ return PAM_SUCCESS;
+ }
+}
+
+} // lockscreen
+} // unity
diff --git a/lockscreen/UserAuthenticatorPam.h b/lockscreen/UserAuthenticatorPam.h
new file mode 100644
index 000000000..5174aec81
--- /dev/null
+++ b/lockscreen/UserAuthenticatorPam.h
@@ -0,0 +1,66 @@
+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
+/*
+ * Copyright (C) 2013 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 UNITY_USER_AUTHENTICATOR_PAM_H
+#define UNITY_USER_AUTHENTICATOR_PAM_H
+
+#include <boost/noncopyable.hpp>
+#include <UnityCore/GLibWrapper.h>
+#include <UnityCore/GLibSource.h>
+
+#include "UserAuthenticator.h"
+
+// Forward declarations
+struct pam_handle;
+struct pam_message;
+struct pam_response;
+
+namespace unity
+{
+namespace lockscreen
+{
+
+class UserAuthenticatorPam : public UserAuthenticator, private boost::noncopyable
+{
+public:
+ bool AuthenticateStart(std::string const& username, AuthenticateEndCallback const&) override;
+
+private:
+ // TODO (andy) move to pimpl
+ bool InitPam();
+
+ static int ConversationFunction(int num_msg,
+ const pam_message** msg,
+ pam_response** resp,
+ void* appdata_ptr);
+
+ std::string username_;
+ AuthenticateEndCallback authenticate_cb_;
+
+ int status_;
+ bool first_prompt_;
+ pam_handle* pam_handle_;
+ glib::Cancellable cancellable_;
+ glib::SourceManager source_manager_;
+};
+
+} // lockscreen
+} // unity
+
+#endif // UNITY_USER_AUTHENTICATOR_PAM_H
diff --git a/lockscreen/UserPromptView.cpp b/lockscreen/UserPromptView.cpp
new file mode 100644
index 000000000..28163b9d8
--- /dev/null
+++ b/lockscreen/UserPromptView.cpp
@@ -0,0 +1,282 @@
+// -*- 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 "UserPromptView.h"
+
+#include <boost/algorithm/string/trim.hpp>
+#include <Nux/VLayout.h>
+
+#include "LockScreenSettings.h"
+#include "unity-shared/CairoTexture.h"
+#include "unity-shared/TextInput.h"
+#include "unity-shared/StaticCairoText.h"
+#include "unity-shared/RawPixel.h"
+
+namespace unity
+{
+namespace lockscreen
+{
+namespace
+{
+const RawPixel PADDING = 10_em;
+const RawPixel LAYOUT_MARGIN = 10_em;
+const RawPixel MSG_LAYOUT_MARGIN = 15_em;
+const RawPixel PROMPT_LAYOUT_MARGIN = 5_em;
+const int PROMPT_FONT_SIZE = 13;
+
+nux::AbstractPaintLayer* CrateBackgroundLayer(int width, int height)
+{
+ nux::CairoGraphics cg(CAIRO_FORMAT_ARGB32, width, height);
+ cairo_t* cr = cg.GetInternalContext();
+
+ cairo_set_source_rgba(cr, 0.1, 0.1, 0.1, 0.4);
+
+ cg.DrawRoundedRectangle(cr,
+ 1.0,
+ 0, 0,
+ Settings::GRID_SIZE * 0.3,
+ width, height);
+
+ cairo_fill_preserve(cr);
+
+ cairo_set_source_rgba (cr, 0.4, 0.4, 0.4, 0.4);
+ cairo_set_line_width (cr, 1);
+ cairo_stroke (cr);
+
+ // Create the texture layer
+ nux::TexCoordXForm texxform;
+
+ nux::ROPConfig rop;
+ rop.Blend = true;
+ rop.SrcBlend = GL_ONE;
+ rop.DstBlend = GL_ONE_MINUS_SRC_ALPHA;
+
+ return (new nux::TextureLayer(texture_ptr_from_cairo_graphics(cg)->GetDeviceTexture(),
+ texxform,
+ nux::color::White,
+ true,
+ rop));
+}
+
+std::string SanitizeMessage(std::string const& message)
+{
+ std::string msg = boost::algorithm::trim_copy(message);
+
+ if (msg.empty())
+ return msg;
+
+ if (msg[msg.size()-1] == ':')
+ msg = msg.substr(0, msg.size()-1);
+
+ if (msg == "Password")
+ return _("Password");
+
+ if (msg == "login")
+ return _("Username");
+
+ return msg;
+}
+
+}
+
+UserPromptView::UserPromptView(session::Manager::Ptr const& session_manager)
+ : nux::View(NUX_TRACKER_LOCATION)
+ , session_manager_(session_manager)
+{
+ user_authenticator_.echo_on_requested.connect([this](std::string const& message, PromiseAuthCodePtr const& promise){
+ AddPrompt(message, /* visible */ true, promise);
+ });
+
+ user_authenticator_.echo_off_requested.connect([this](std::string const& message, PromiseAuthCodePtr const& promise){
+ AddPrompt(message, /* visible */ false, promise);
+ });
+
+ user_authenticator_.message_requested.connect([this](std::string const& message){
+ AddMessage(message, nux::color::White);
+ });
+
+ user_authenticator_.error_requested.connect([this](std::string const& message){
+ AddMessage(message, nux::color::Red);
+ });
+
+ user_authenticator_.clear_prompts.connect([this](){
+ ResetLayout();
+ });
+
+ ResetLayout();
+
+ user_authenticator_.AuthenticateStart(session_manager_->UserName(),
+ sigc::mem_fun(this, &UserPromptView::AuthenticationCb));
+}
+
+void UserPromptView::ResetLayout()
+{
+ focus_queue_.clear();
+
+ SetLayout(new nux::VLayout());
+
+ GetLayout()->SetLeftAndRightPadding(PADDING);
+ GetLayout()->SetTopAndBottomPadding(PADDING);
+ static_cast<nux::VLayout*>(GetLayout())->SetVerticalInternalMargin(LAYOUT_MARGIN);
+
+ auto const& real_name = session_manager_->RealName();
+ auto const& name = (real_name.empty() ? session_manager_->UserName() : real_name);
+
+ unity::StaticCairoText* username = new unity::StaticCairoText(name);
+ username->SetFont("Ubuntu "+std::to_string(PROMPT_FONT_SIZE));
+ GetLayout()->AddView(username);
+
+ msg_layout_ = new nux::VLayout();
+ msg_layout_->SetVerticalInternalMargin(MSG_LAYOUT_MARGIN);
+ msg_layout_->SetReconfigureParentLayoutOnGeometryChange(true);
+ GetLayout()->AddLayout(msg_layout_);
+
+ prompt_layout_ = new nux::VLayout();
+ prompt_layout_->SetVerticalInternalMargin(PROMPT_LAYOUT_MARGIN);
+ prompt_layout_->SetReconfigureParentLayoutOnGeometryChange(true);
+ GetLayout()->AddLayout(prompt_layout_);
+
+ QueueRelayout();
+ QueueDraw();
+}
+
+void UserPromptView::AuthenticationCb(bool authenticated)
+{
+ ResetLayout();
+
+ if (authenticated)
+ {
+ session_manager_->unlock_requested.emit();
+ }
+ else
+ {
+ AddMessage(_("Invalid password, please try again"), nux::color::Red);
+
+ user_authenticator_.AuthenticateStart(session_manager_->UserName(),
+ sigc::mem_fun(this, &UserPromptView::AuthenticationCb));
+ }
+}
+
+void UserPromptView::Draw(nux::GraphicsEngine& graphics_engine, bool /* force_draw */)
+{
+ nux::Geometry const& geo = GetGeometry();
+
+ graphics_engine.PushClippingRectangle(geo);
+ nux::GetPainter().PaintBackground(graphics_engine, geo);
+
+ bg_layer_.reset(CrateBackgroundLayer(geo.width, geo.height));
+ nux::GetPainter().PushDrawLayer(graphics_engine, geo, bg_layer_.get());
+
+ nux::GetPainter().PopBackground();
+ graphics_engine.PopClippingRectangle();
+}
+
+void UserPromptView::DrawContent(nux::GraphicsEngine& graphics_engine, bool force_draw)
+{
+ nux::Geometry const& geo = GetGeometry();
+ graphics_engine.PushClippingRectangle(geo);
+
+ if (!IsFullRedraw())
+ {
+ bg_layer_.reset(CrateBackgroundLayer(geo.width, geo.height));
+ nux::GetPainter().PushLayer(graphics_engine, geo, bg_layer_.get());
+ }
+
+ if (GetLayout())
+ GetLayout()->ProcessDraw(graphics_engine, force_draw);
+
+ if (!IsFullRedraw())
+ nux::GetPainter().PopBackground();
+
+ graphics_engine.PopClippingRectangle();
+}
+
+nux::View* UserPromptView::focus_view()
+{
+ if (focus_queue_.empty())
+ return nullptr;
+
+ for (auto* view : focus_queue_)
+ if (view->HasKeyboardFocus())
+ return view;
+
+ return focus_queue_.front();
+}
+
+void UserPromptView::AddPrompt(std::string const& message, bool visible, PromiseAuthCodePtr const& promise)
+{
+ auto* text_input = new unity::TextInput();
+ auto* text_entry = text_input->text_entry();
+
+ text_input->input_hint = SanitizeMessage(message);
+ text_input->hint_font_size = PROMPT_FONT_SIZE;
+ text_entry->SetPasswordMode(!visible);
+ text_entry->SetPasswordChar("•");
+ text_entry->SetToggleCursorVisibilityOnKeyFocus(true);
+
+ text_input->SetMinimumHeight(Settings::GRID_SIZE);
+ text_input->SetMaximumHeight(Settings::GRID_SIZE);
+ prompt_layout_->AddView(text_input, 1);
+ focus_queue_.push_back(text_entry);
+
+ // Don't remove it, it helps with a11y.
+ if (focus_queue_.size() == 1)
+ nux::GetWindowCompositor().SetKeyFocusArea(text_entry);
+
+ text_entry->activated.connect([this, text_input, promise](){
+ if (focus_queue_.size() == 1)
+ {
+ text_input->SetSpinnerVisible(true);
+ text_input->SetSpinnerState(STATE_SEARCHING);
+ }
+
+ focus_queue_.pop_front();
+ auto* text_entry = text_input->text_entry();
+ text_entry->SetInputEventSensitivity(false);
+ QueueRelayout();
+ QueueDraw();
+
+ std::string const& password = text_entry->GetText();
+ if (promise)
+ promise->set_value(password);
+ });
+
+ GetLayout()->ComputeContentPosition(0, 0);
+ ComputeContentSize();
+ QueueRelayout();
+ QueueDraw();
+}
+
+void UserPromptView::AddMessage(std::string const& message, nux::Color const& color)
+{
+ auto* view = new unity::StaticCairoText("");
+ view->SetFont(Settings::Instance().font_name());
+ view->SetTextColor(color);
+ view->SetText(message);
+
+ msg_layout_->AddView(view);
+
+ GetLayout()->ComputeContentPosition(0, 0);
+ ComputeContentSize();
+ QueueRelayout();
+ QueueDraw();
+}
+
+}
+}
diff --git a/lockscreen/UserPromptView.h b/lockscreen/UserPromptView.h
new file mode 100644
index 000000000..7d5ea4336
--- /dev/null
+++ b/lockscreen/UserPromptView.h
@@ -0,0 +1,81 @@
+// -*- 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 UNITY_USER_PROMPT_BOX
+#define UNITY_USER_PROMPT_BOX
+
+#include <memory>
+#include <deque>
+
+#include <Nux/Nux.h>
+#include <Nux/View.h>
+#include <UnityCore/SessionManager.h>
+
+#include "UserAuthenticatorPam.h"
+#include "unity-shared/IMTextEntry.h"
+#include "unity-shared/SearchBarSpinner.h"
+
+namespace nux
+{
+class VLayout;
+}
+
+namespace unity
+{
+
+class StaticCairoText;
+class TextInput;
+
+namespace lockscreen
+{
+
+class UserPromptView : public nux::View
+{
+public:
+ UserPromptView(session::Manager::Ptr const& session_manager);
+ ~UserPromptView() {};
+
+ nux::View* focus_view();
+
+ void AddPrompt(std::string const& message, bool visible, PromiseAuthCodePtr const&);
+ void AddMessage(std::string const& message, nux::Color const& color);
+ void AuthenticationCb(bool authenticated);
+
+protected:
+ void Draw(nux::GraphicsEngine& graphics_engine, bool force_draw) override;
+ void DrawContent(nux::GraphicsEngine& graphics_engine, bool force_draw) override;
+
+private:
+ void ResetLayout();
+
+ session::Manager::Ptr session_manager_;
+ UserAuthenticatorPam user_authenticator_;
+ std::shared_ptr<nux::AbstractPaintLayer> bg_layer_;
+ nux::VLayout* msg_layout_;
+ nux::VLayout* prompt_layout_;
+ StaticCairoText* message_;
+ StaticCairoText* error_;
+ StaticCairoText* invalid_login_;
+ std::deque<IMTextEntry*> focus_queue_;
+};
+
+}
+}
+
+#endif
diff --git a/lockscreen/pch/lockscreen_pch.hh b/lockscreen/pch/lockscreen_pch.hh
new file mode 100644
index 000000000..09f3d0a20
--- /dev/null
+++ b/lockscreen/pch/lockscreen_pch.hh
@@ -0,0 +1,32 @@
+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
+/*
+ * Copyright (C) 2013 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>
+ */
+
+/*
+ * These are the precompiled header includes for this module.
+ * Only system header files can be listed here.
+ */
+
+#include <memory>
+#include <vector>
+#include <deque>
+#include <security/pam_appl.h>
+
+#include <Nux/Nux.h>
+#include <UnityCore/SessionManager.h>
+#include <UnityCore/Indicators.h> \ No newline at end of file
diff --git a/panel/PanelIndicatorEntryView.cpp b/panel/PanelIndicatorEntryView.cpp
index 5dba6ec2a..42aff3fbf 100644
--- a/panel/PanelIndicatorEntryView.cpp
+++ b/panel/PanelIndicatorEntryView.cpp
@@ -387,7 +387,7 @@ void PanelIndicatorEntryView::DrawEntryContent(cairo_t *cr, unsigned int width,
pango_layout_get_pixel_size(layout, &extents.width, &extents.height);
int y = (height - extents.height) / 2;
- if (overlay_showing_)
+ if (overlay_showing_ && !IsActive())
{
cairo_move_to(cr, x, y);
cairo_set_source_rgb(cr, 1.0f, 1.0f, 1.0f);
diff --git a/panel/PanelIndicatorsView.cpp b/panel/PanelIndicatorsView.cpp
index b65530b84..90fb67176 100644
--- a/panel/PanelIndicatorsView.cpp
+++ b/panel/PanelIndicatorsView.cpp
@@ -42,6 +42,7 @@ PanelIndicatorsView::PanelIndicatorsView()
, opacity(1.0f, sigc::mem_fun(this, &PanelIndicatorsView::SetOpacity))
, layout_(new nux::HLayout("", NUX_TRACKER_LOCATION))
, monitor_(0)
+, overlay_showing_(false)
{
opacity.DisableNotifications();
layout_->SetContentDistribution(nux::MAJOR_POSITION_END);
@@ -327,6 +328,9 @@ PanelIndicatorEntryView *PanelIndicatorsView::AddEntry(Entry::Ptr const& entry,
auto view = new PanelIndicatorEntryView(entry, padding, type);
AddEntryView(view, pos);
+ if (overlay_showing_)
+ view->OverlayShown();
+
return view;
}
@@ -368,12 +372,16 @@ void PanelIndicatorsView::RemoveEntry(std::string const& entry_id)
void PanelIndicatorsView::OverlayShown()
{
+ overlay_showing_ = true;
+
for (auto const& entry: entries_)
entry.second->OverlayShown();
}
void PanelIndicatorsView::OverlayHidden()
{
+ overlay_showing_ = false;
+
for (auto const& entry: entries_)
entry.second->OverlayHidden();
}
diff --git a/panel/PanelIndicatorsView.h b/panel/PanelIndicatorsView.h
index 0f6f7c44e..0219a407c 100644
--- a/panel/PanelIndicatorsView.h
+++ b/panel/PanelIndicatorsView.h
@@ -98,6 +98,7 @@ protected:
Entries entries_;
int monitor_;
+ bool overlay_showing_;
private:
bool SetOpacity(double& target, double const& new_value);
diff --git a/panel/PanelMenuView.cpp b/panel/PanelMenuView.cpp
index 185192558..a30b2af68 100644
--- a/panel/PanelMenuView.cpp
+++ b/panel/PanelMenuView.cpp
@@ -64,7 +64,6 @@ PanelMenuView::PanelMenuView(menu::Manager::Ptr const& menus)
, is_desktop_focused_(false)
, last_active_view_(nullptr)
, new_application_(nullptr)
- , overlay_showing_(false)
, switcher_showing_(false)
, spread_showing_(false)
, launcher_keynav_(false)
diff --git a/panel/PanelMenuView.h b/panel/PanelMenuView.h
index cf62915b9..9ee842450 100644
--- a/panel/PanelMenuView.h
+++ b/panel/PanelMenuView.h
@@ -176,7 +176,6 @@ private:
nux::Geometry last_geo_;
nux::Geometry title_geo_;
- bool overlay_showing_;
bool switcher_showing_;
bool spread_showing_;
bool launcher_keynav_;
diff --git a/panel/PanelView.cpp b/panel/PanelView.cpp
index a6ce660a1..4debdd8d3 100644
--- a/panel/PanelView.cpp
+++ b/panel/PanelView.cpp
@@ -19,20 +19,11 @@
*/
#include <Nux/Nux.h>
-#include <Nux/BaseWindow.h>
#include <Nux/HLayout.h>
-#include <Nux/Layout.h>
-#include <Nux/WindowCompositor.h>
-#include <NuxGraphics/CairoGraphics.h>
#include <NuxCore/Logger.h>
#include <UnityCore/GLibWrapper.h>
-#include <NuxGraphics/GLThread.h>
-#include <NuxGraphics/RenderingPipe.h>
-
-#include <glib.h>
-
#include "unity-shared/PanelStyle.h"
#include "unity-shared/TextureCache.h"
#include "unity-shared/WindowManager.h"
@@ -556,7 +547,11 @@ void PanelView::PreLayoutManagement()
{
View::PreLayoutManagement();
- int menu_width = GetMaximumWidth() - indicators_->GetBaseWidth() - tray_->GetBaseWidth();
+ int tray_width = 0;
+ if (tray_)
+ tray_width = tray_->GetBaseWidth();
+
+ int menu_width = GetMaximumWidth() - indicators_->GetBaseWidth() - tray_width;
menu_view_->SetMinimumWidth(menu_width);
menu_view_->SetMaximumWidth(menu_width);
diff --git a/plugins/unityshell/CMakeLists.txt b/plugins/unityshell/CMakeLists.txt
index 5fa3917b1..43e46e4bc 100644
--- a/plugins/unityshell/CMakeLists.txt
+++ b/plugins/unityshell/CMakeLists.txt
@@ -13,7 +13,7 @@ endif()
compiz_plugin (unityshell
PKGDEPS ${UNITY_PLUGIN_DEPS}
PLUGINDEPS composite opengl compiztoolbox scale
- CFLAGSADD "-DINSTALLPREFIX='\"${CMAKE_INSTALL_PREFIX}\"' -DPKGDATADIR='\"${PKGDATADIR}\"' -I${CMAKE_BINARY_DIR} -I${CMAKE_SOURCE_DIR} ${BOOT_LOGGER_FLAG} -DGETTEXT_PACKAGE='\"unity\"' ${MAINTAINER_CXXFLAGS} -I${CMAKE_SOURCE_DIR}/dash/ -I${CMAKE_SOURCE_DIR}/launcher/ -I${CMAKE_SOURCE_DIR}/hud/ -I${CMAKE_SOURCE_DIR}/panel/ -I${CMAKE_SOURCE_DIR}/shortcuts/ -I${CMAKE_SOURCE_DIR}/shutdown/ -I${CMAKE_SOURCE_DIR}/unity-shared/"
+ CFLAGSADD "-DINSTALLPREFIX='\"${CMAKE_INSTALL_PREFIX}\"' -DPKGDATADIR='\"${PKGDATADIR}\"' -I${CMAKE_BINARY_DIR} -I${CMAKE_SOURCE_DIR} ${BOOT_LOGGER_FLAG} -DGETTEXT_PACKAGE='\"unity\"' ${MAINTAINER_CXXFLAGS} -I${CMAKE_SOURCE_DIR}/dash/ -I${CMAKE_SOURCE_DIR}/launcher/ -I${CMAKE_SOURCE_DIR}/lockscreen/ -I${CMAKE_SOURCE_DIR}/hud/ -I${CMAKE_SOURCE_DIR}/panel/ -I${CMAKE_SOURCE_DIR}/shortcuts/ -I${CMAKE_SOURCE_DIR}/shutdown/ -I${CMAKE_SOURCE_DIR}/unity-shared/"
LIBDIRS "${CMAKE_BINARY_DIR}/UnityCore"
)
@@ -26,6 +26,8 @@ add_dependencies(unityshell
decorations-lib
hud-lib
launcher-lib
+ pam
+ lockscreen-lib
panel-lib
shortcuts-lib
shutdown-lib
@@ -39,6 +41,8 @@ target_link_libraries(unityshell
decorations-lib
hud-lib
launcher-lib
+ pam
+ lockscreen-lib
panel-lib
shortcuts-lib
shutdown-lib
diff --git a/plugins/unityshell/src/nux-text-entry-accessible.cpp b/plugins/unityshell/src/nux-text-entry-accessible.cpp
index e948f2827..bda50a611 100644
--- a/plugins/unityshell/src/nux-text-entry-accessible.cpp
+++ b/plugins/unityshell/src/nux-text-entry-accessible.cpp
@@ -48,36 +48,19 @@ static AtkStateSet* nux_text_entry_accessible_ref_state_set(AtkObject* obj);
G_DEFINE_TYPE(NuxTextEntryAccessible, nux_text_entry_accessible, NUX_TYPE_VIEW_ACCESSIBLE);
-#define NUX_TEXT_ENTRY_ACCESSIBLE_GET_PRIVATE(obj) \
- (G_TYPE_INSTANCE_GET_PRIVATE ((obj), NUX_TYPE_TEXT_ENTRY_ACCESSIBLE, \
- NuxTextEntryAccessiblePrivate))
-
-struct _NuxTextEntryAccessiblePrivate
-{
-};
-
-
static void
nux_text_entry_accessible_class_init(NuxTextEntryAccessibleClass* klass)
{
- GObjectClass* gobject_class = G_OBJECT_CLASS(klass);
AtkObjectClass* atk_class = ATK_OBJECT_CLASS(klass);
/* AtkObject */
atk_class->ref_state_set = nux_text_entry_accessible_ref_state_set;
atk_class->initialize = nux_text_entry_accessible_initialize;
-
- g_type_class_add_private(gobject_class, sizeof(NuxTextEntryAccessiblePrivate));
}
static void
nux_text_entry_accessible_init(NuxTextEntryAccessible* self)
-{
- NuxTextEntryAccessiblePrivate* priv =
- NUX_TEXT_ENTRY_ACCESSIBLE_GET_PRIVATE(self);
-
- self->priv = priv;
-}
+{}
AtkObject*
nux_text_entry_accessible_new(nux::Object* object)
@@ -98,9 +81,15 @@ static void
nux_text_entry_accessible_initialize(AtkObject* accessible,
gpointer data)
{
+ nux::Object* nux_object = NULL;
+ nux::TextEntry* text_entry = NULL;
+
ATK_OBJECT_CLASS(nux_text_entry_accessible_parent_class)->initialize(accessible, data);
- atk_object_set_role(accessible, ATK_ROLE_ENTRY);
+ nux_object = nux_object_accessible_get_object(NUX_OBJECT_ACCESSIBLE(accessible));
+ text_entry = dynamic_cast<nux::TextEntry*>(nux_object);
+
+ atk_object_set_role(accessible, text_entry->PasswordMode() ? ATK_ROLE_PASSWORD_TEXT : ATK_ROLE_ENTRY);
}
static AtkStateSet*
diff --git a/plugins/unityshell/src/unity-text-input-accessible.cpp b/plugins/unityshell/src/unity-text-input-accessible.cpp
new file mode 100644
index 000000000..57d1a490a
--- /dev/null
+++ b/plugins/unityshell/src/unity-text-input-accessible.cpp
@@ -0,0 +1,90 @@
+/*
+ * 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 "unity-text-input-accessible.h"
+
+#include "unitya11y.h"
+#include "TextInput.h"
+
+using namespace unity;
+
+/* GObject */
+static void unity_text_input_accessible_class_init(UnityTextInputAccessibleClass* klass);
+static void unity_text_input_accessible_init(UnityTextInputAccessible* self);
+//static void unity_text_input_accessible_finalize(GObject* object);
+
+/* AtkObject.h */
+static void unity_text_input_accessible_initialize(AtkObject* accessible,
+ gpointer data);
+
+G_DEFINE_TYPE(UnityTextInputAccessible, unity_text_input_accessible, NUX_TYPE_VIEW_ACCESSIBLE)
+
+static void
+unity_text_input_accessible_class_init(UnityTextInputAccessibleClass* klass)
+{
+ AtkObjectClass* atk_class = ATK_OBJECT_CLASS(klass);
+
+ /* AtkObject */
+ atk_class->initialize = unity_text_input_accessible_initialize;
+}
+
+static void
+unity_text_input_accessible_init(UnityTextInputAccessible* self)
+{}
+
+AtkObject*
+unity_text_input_accessible_new(nux::Object* object)
+{
+ AtkObject* accessible = NULL;
+
+ g_return_val_if_fail(dynamic_cast<TextInput*>(object), NULL);
+
+ accessible = ATK_OBJECT(g_object_new(UNITY_TYPE_TEXT_INPUT_ACCESSIBLE, NULL));
+
+ atk_object_initialize(accessible, object);
+
+ return accessible;
+}
+
+static void
+unity_text_input_accessible_initialize(AtkObject* accessible,
+ gpointer data)
+{
+ nux::Object* nux_object = NULL;
+ TextInput* text_input = NULL;
+ nux::TextEntry* text_entry = NULL;
+
+ ATK_OBJECT_CLASS(unity_text_input_accessible_parent_class)->initialize(accessible, data);
+
+ accessible->role = ATK_ROLE_PANEL;
+
+ nux_object = nux_object_accessible_get_object(NUX_OBJECT_ACCESSIBLE(accessible));
+ text_input = dynamic_cast<TextInput*>(nux_object);
+
+ if (text_input == NULL)
+ return;
+
+ text_entry = text_input->text_entry();
+
+ if (text_entry != NULL)
+ {
+ AtkObject* text_entry_accessible = NULL;
+ text_entry_accessible = unity_a11y_get_accessible(text_entry);
+ atk_object_set_name(text_entry_accessible, text_input->input_hint().c_str());
+ }
+}
diff --git a/plugins/unityshell/src/unity-text-input-accessible.h b/plugins/unityshell/src/unity-text-input-accessible.h
new file mode 100644
index 000000000..c1ab85636
--- /dev/null
+++ b/plugins/unityshell/src/unity-text-input-accessible.h
@@ -0,0 +1,57 @@
+/*
+ * 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 UNITY_TEXT_INPUT_ACCESSIBLE_H
+#define UNITY_TEXT_INPUT_ACCESSIBLE_H
+
+#include <atk/atk.h>
+
+#include "nux-view-accessible.h"
+
+G_BEGIN_DECLS
+
+#define UNITY_TYPE_TEXT_INPUT_ACCESSIBLE (unity_text_input_accessible_get_type ())
+#define UNITY_TEXT_INPUT_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), UNITY_TYPE_TEXT_INPUT_ACCESSIBLE, UnityTextInputAccessible))
+#define UNITY_TEXT_INPUT_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), UNITY_TYPE_TEXT_INPUT_ACCESSIBLE, UnityTextInputAccessibleClass))
+#define UNITY_IS_TEXT_INPUT_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), UNITY_TYPE_TEXT_INPUT_ACCESSIBLE))
+#define UNITY_IS_TEXT_INPUT_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), UNITY_TYPE_TEXT_INPUT_ACCESSIBLE))
+#define UNITY_TEXT_INPUT_ACCESSIBLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), UNITY_TYPE_TEXT_INPUT_ACCESSIBLE, UnityTextInputAccessibleClass))
+
+typedef struct _UnityTextInputAccessible UnityTextInputAccessible;
+typedef struct _UnityTextInputAccessibleClass UnityTextInputAccessibleClass;
+typedef struct _UnityTextInputAccessiblePrivate UnityTextInputAccessiblePrivate;
+
+struct _UnityTextInputAccessible
+{
+ NuxViewAccessible parent;
+
+ /*< private >*/
+ UnityTextInputAccessiblePrivate* priv;
+};
+
+struct _UnityTextInputAccessibleClass
+{
+ NuxViewAccessibleClass parent_class;
+};
+
+GType unity_text_input_accessible_get_type(void);
+AtkObject* unity_text_input_accessible_new(nux::Object* object);
+
+G_END_DECLS
+
+#endif
diff --git a/plugins/unityshell/src/unitya11y.cpp b/plugins/unityshell/src/unitya11y.cpp
index 50a72a380..346c915ae 100644
--- a/plugins/unityshell/src/unitya11y.cpp
+++ b/plugins/unityshell/src/unitya11y.cpp
@@ -42,6 +42,7 @@
#include "QuicklistView.h"
#include "QuicklistMenuItem.h"
#include "SwitcherView.h"
+#include "TextInput.h"
#include "SessionButton.h"
#include "unity-launcher-accessible.h"
#include "unity-launcher-icon-accessible.h"
@@ -54,6 +55,7 @@
#include "unity-quicklist-accessible.h"
#include "unity-quicklist-menu-item-accessible.h"
#include "unity-switcher-accessible.h"
+#include "unity-text-input-accessible.h"
#include "unity-session-button-accessible.h"
using namespace unity;
@@ -187,6 +189,9 @@ unity_a11y_create_accessible(nux::Object* object)
if (object->Type().IsDerivedFromType(unity::SearchBar::StaticObjectType))
return unity_search_bar_accessible_new(object);
+ if (object->Type().IsDerivedFromType(unity::TextInput::StaticObjectType))
+ return unity_text_input_accessible_new(object);
+
if (object->Type().IsDerivedFromType(unity::switcher::SwitcherView::StaticObjectType))
return unity_switcher_accessible_new(object);
diff --git a/plugins/unityshell/src/unityshell.cpp b/plugins/unityshell/src/unityshell.cpp
index 7f794253e..af09ebc3b 100644
--- a/plugins/unityshell/src/unityshell.cpp
+++ b/plugins/unityshell/src/unityshell.cpp
@@ -338,12 +338,14 @@ UnityScreen::UnityScreen(CompScreen* screen)
optionSetShowDesktopKeyInitiate(boost::bind(&UnityScreen::showDesktopKeyInitiate, this, _1, _2, _3));
optionSetPanelFirstMenuInitiate(boost::bind(&UnityScreen::showPanelFirstMenuKeyInitiate, this, _1, _2, _3));
optionSetPanelFirstMenuTerminate(boost::bind(&UnityScreen::showPanelFirstMenuKeyTerminate, this, _1, _2, _3));
+ optionSetPanelFirstMenuNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2));
optionSetAutomaximizeValueNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2));
optionSetDashTapDurationNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2));
optionSetAltTabTimeoutNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2));
optionSetAltTabBiasViewportNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2));
optionSetDisableShowDesktopNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2));
optionSetDisableMouseNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2));
+ optionSetLockScreenTypeNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2));
optionSetAltTabForwardAllInitiate(boost::bind(&UnityScreen::altTabForwardAllInitiate, this, _1, _2, _3));
optionSetAltTabForwardInitiate(boost::bind(&UnityScreen::altTabForwardInitiate, this, _1, _2, _3));
@@ -2005,6 +2007,9 @@ bool UnityScreen::showLauncherKeyInitiate(CompAction* action,
CompAction::State state,
CompOption::Vector& options)
{
+ if (lockscreen_controller_->IsLocked())
+ return true;
+
// to receive the Terminate event
if (state & CompAction::StateInitKey)
action->setState(action->state() | CompAction::StateTermKey);
@@ -2014,7 +2019,8 @@ bool UnityScreen::showLauncherKeyInitiate(CompAction* action,
launcher_controller_->HandleLauncherKeyPress(when);
EnsureSuperKeybindings ();
- if (!shortcut_controller_->Visible() && shortcut_controller_->IsEnabled())
+ if (!shortcut_controller_->Visible() &&
+ shortcut_controller_->IsEnabled())
{
if (shortcut_controller_->Show())
{
@@ -2436,7 +2442,8 @@ bool UnityScreen::ShowHud()
return false; // early exit if the switcher is open
}
- if (PluginAdapter::Default().IsTopWindowFullscreenOnMonitorWithMouse())
+ if (PluginAdapter::Default().IsTopWindowFullscreenOnMonitorWithMouse() ||
+ lockscreen_controller_->IsLocked())
{
return false;
}
@@ -2523,7 +2530,11 @@ bool UnityScreen::LockScreenInitiate(CompAction* action,
CompAction::State state,
CompOption::Vector& options)
{
- session_controller_->LockScreen();
+ sources_.AddIdle([this] {
+ session_controller_->LockScreen();
+ return false;
+ });
+
return true;
}
@@ -2574,6 +2585,15 @@ void UnityScreen::UpdateCloseWindowKey(CompAction::KeyBinding const& keybind)
WindowManager::Default().close_window_key = std::make_pair(modifiers, keysym);
}
+void UnityScreen::UpdateActivateIndicatorsKey()
+{
+ CompAction::KeyBinding const& keybind = optionGetPanelFirstMenu().key();
+ KeySym keysym = XkbKeycodeToKeysym(screen->dpy(), keybind.keycode(), 0, 0);
+ unsigned modifiers = CompizModifiersToNux(keybind.modifiers());
+
+ WindowManager::Default().activate_indicators_key = std::make_pair(modifiers, keysym);
+}
+
bool UnityScreen::initPluginActions()
{
PluginAdapter& adapter = PluginAdapter::Default();
@@ -2802,6 +2822,24 @@ bool UnityWindow::glPaint(const GLWindowPaintAttrib& attrib,
GLWindowPaintAttrib wAttrib = attrib;
+ if (uScreen->lockscreen_controller_->IsLocked())
+ {
+ if (window->type() != CompWindowTypePopupMenuMask ||
+ !uScreen->lockscreen_controller_->HasOpenMenu())
+ {
+ // For some reasons PAINT_WINDOW_NO_CORE_INSTANCE_MASK doesn't work here
+ // (well, it works too much, as it applies to menus too), so we need
+ // to paint the windows at the proper opacity, overriding any other
+ // paint plugin (animation, fade?) that might interfere with us.
+ wAttrib.opacity = COMPIZ_COMPOSITE_OPAQUE * (1.0f - uScreen->lockscreen_controller_->Opacity());
+ int old_index = gWindow->glPaintGetCurrentIndex();
+ gWindow->glPaintSetCurrentIndex(MAXSHORT);
+ bool ret = gWindow->glPaint(wAttrib, matrix, region, mask);
+ gWindow->glPaintSetCurrentIndex(old_index);
+ return ret;
+ }
+ }
+
if (mMinimizeHandler)
{
mask |= mMinimizeHandler->getPaintMask ();
@@ -2830,7 +2868,7 @@ bool UnityWindow::glPaint(const GLWindowPaintAttrib& attrib,
paintInnerGlow(scaled_geo, matrix, attrib, mask);
}
- if (uScreen->session_controller_ && uScreen->session_controller_->Visible())
+ if (uScreen->session_controller_->Visible())
{
// Let's darken the other windows if the session dialog is visible
wAttrib.brightness *= 0.75f;
@@ -3485,6 +3523,12 @@ void UnityScreen::optionChanged(CompOption* opt, UnityshellOptions::Options num)
case UnityshellOptions::EdgePassedDisabledMs:
launcher_options->edge_passed_disabled_ms = optionGetEdgePassedDisabledMs();
break;
+ case UnityshellOptions::LockScreenType:
+ lockscreen_settings_.lockscreen_type = static_cast<lockscreen::Type>(optionGetLockScreenType());
+ break;
+ case UnityshellOptions::PanelFirstMenu:
+ UpdateActivateIndicatorsKey();
+ break;
default:
break;
}
@@ -3627,9 +3671,14 @@ void UnityScreen::initLauncher()
// Setup Session Controller
auto manager = std::make_shared<session::GnomeManager>();
+ session_dbus_manager_ = std::make_shared<session::DBusManager>(manager);
session_controller_ = std::make_shared<session::Controller>(manager);
AddChild(session_controller_.get());
+ // Setup Lockscreen Controller
+ lockscreen_controller_ = std::make_shared<lockscreen::Controller>(manager);
+ UpdateActivateIndicatorsKey();
+
auto on_launcher_size_changed = [this] (nux::Area* area, int w, int h) {
/* The launcher geometry includes 1px used to draw the right margin
* that must not be considered when drawing an overlay */
diff --git a/plugins/unityshell/src/unityshell.h b/plugins/unityshell/src/unityshell.h
index 5a8e22b91..a57ce4568 100644
--- a/plugins/unityshell/src/unityshell.h
+++ b/plugins/unityshell/src/unityshell.h
@@ -58,6 +58,8 @@
#include "FontSettings.h"
#include "ShortcutController.h"
#include "LauncherController.h"
+#include "LockScreenController.h"
+#include "LockScreenSettings.h"
#include "PanelController.h"
#include "PanelStyle.h"
#include "UScreen.h"
@@ -65,6 +67,7 @@
#include "ScreenIntrospection.h"
#include "SwitcherController.h"
#include "SessionController.h"
+#include "SessionDBusManager.h"
#include "SpreadFilter.h"
#include "UBusWrapper.h"
#include "UnityshellPrivate.h"
@@ -297,6 +300,7 @@ private:
unsigned XModifiersToNux(unsigned input) const;
void UpdateCloseWindowKey(CompAction::KeyBinding const&);
+ void UpdateActivateIndicatorsKey();
bool getMipmap () override { return false; }
@@ -311,6 +315,7 @@ private:
FontSettings font_settings_;
internal::FavoriteStoreGSettings favorite_store_;
ThumbnailGenerator thumbnail_generator_;
+ lockscreen::Settings lockscreen_settings_;
/* The window thread should be the last thing removed, as c++ does it in reverse order */
std::unique_ptr<nux::WindowThread> wt;
@@ -326,7 +331,9 @@ private:
switcher::Controller::Ptr switcher_controller_;
hud::Controller::Ptr hud_controller_;
shortcut::Controller::Ptr shortcut_controller_;
+ session::DBusManager::Ptr session_dbus_manager_;
session::Controller::Ptr session_controller_;
+ std::shared_ptr<lockscreen::Controller> lockscreen_controller_;
debug::DebugDBusInterface debugger_;
std::unique_ptr<BGHash> bghash_;
spread::Filter::Ptr spread_filter_;
diff --git a/plugins/unityshell/unityshell.xml.in b/plugins/unityshell/unityshell.xml.in
index ca9ab9c21..cefb87537 100644
--- a/plugins/unityshell/unityshell.xml.in
+++ b/plugins/unityshell/unityshell.xml.in
@@ -146,6 +146,26 @@
<_long>Enables possibility to display an overlay showing available mouse and keyboard shortcuts.</_long>
<default>true</default>
</option>
+
+ <option name="lock_screen_type" type="int">
+ <_short>Lockscreen</_short>
+ <_long>Set how Unity should handle lockscreen.</_long>
+ <min>0</min>
+ <max>2</max>
+ <default>2</default>
+ <desc>
+ <value>0</value>
+ <_name>None</_name>
+ </desc>
+ <desc>
+ <value>1</value>
+ <_name>Lightdm</_name>
+ </desc>
+ <desc>
+ <value>2</value>
+ <_name>Unity</_name>
+ </desc>
+ </option>
</group>
<group>
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 1e8eff75c..df28a9aa7 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -24,6 +24,7 @@ launcher/SoftwareCenterLauncherIcon.cpp
launcher/SpacerLauncherIcon.cpp
launcher/TrashLauncherIcon.cpp
launcher/VolumeLauncherIcon.cpp
+lockscreen/UserPromptView.cpp
panel/PanelMenuView.cpp
plugins/networkarearegion/networkarearegion.xml.in
plugins/unity-mt-grab-handles/unitymtgrabhandles.xml.in
diff --git a/resources/cof.png b/resources/cof.png
new file mode 100644
index 000000000..09392003e
--- /dev/null
+++ b/resources/cof.png
Binary files differ
diff --git a/services/CMakeLists.txt b/services/CMakeLists.txt
index 8ce92ca10..103c8854c 100644
--- a/services/CMakeLists.txt
+++ b/services/CMakeLists.txt
@@ -58,3 +58,6 @@ install(TARGETS unity-panel-service DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/unit
configure_file(unity-panel-service.conf.in ${CMAKE_CURRENT_BINARY_DIR}/unity-panel-service.conf)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/unity-panel-service.conf DESTINATION ${CMAKE_INSTALL_PREFIX}/share/upstart/sessions)
+
+configure_file(unity-panel-service-lockscreen.conf.in ${CMAKE_CURRENT_BINARY_DIR}/unity-panel-service-lockscreen.conf)
+install(FILES ${CMAKE_CURRENT_BINARY_DIR}/unity-panel-service-lockscreen.conf DESTINATION ${CMAKE_INSTALL_PREFIX}/share/upstart/sessions)
diff --git a/services/panel-main.c b/services/panel-main.c
index 484c85750..837b036e6 100644
--- a/services/panel-main.c
+++ b/services/panel-main.c
@@ -106,7 +106,8 @@ static const gchar introspection_xml[] =
" </interface>"
"</node>";
-#define S_NAME "com.canonical.Unity.Panel.Service"
+#define S_NAME_DESKTOP "com.canonical.Unity.Panel.Service.Desktop"
+#define S_NAME_LOCKSCREEN "com.canonical.Unity.Panel.Service.LockScreen"
#define S_PATH "/com/canonical/Unity/Panel/Service"
#define S_IFACE "com.canonical.Unity.Panel.Service"
@@ -440,6 +441,13 @@ main (gint argc, gchar **argv)
{
PanelService *service;
guint owner_id;
+ gboolean lockscreen_mode = FALSE;
+ GError *error = NULL;
+ GOptionContext *context;
+ GOptionEntry entries[] = {
+ { "lockscreen-mode", 0, 0, G_OPTION_ARG_NONE, &lockscreen_mode, "Load indicators for the lockscreen", NULL },
+ { NULL }};
+
g_unsetenv ("UBUNTU_MENUPROXY");
g_setenv ("NO_AT_BRIDGE", "1", TRUE);
@@ -449,6 +457,17 @@ main (gint argc, gchar **argv)
gtk_icon_theme_append_search_path (gtk_icon_theme_get_default(), INDICATORICONDIR);
ido_init ();
+ context = g_option_context_new ("- Unity Panel Service");
+ g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE);
+ if (!g_option_context_parse (context, &argc, &argv, &error))
+ {
+ g_print ("unity-panel-service: %s\n", error->message);
+ g_print ("Try --help for more information.\n");
+ return 1;
+ }
+
+ panel_service_set_lockscreen_mode (lockscreen_mode);
+
if (g_getenv ("SILENT_PANEL_SERVICE") != NULL)
{
g_log_set_default_handler (discard_log_message, NULL);
@@ -462,7 +481,7 @@ main (gint argc, gchar **argv)
service = panel_service_get_default ();
owner_id = g_bus_own_name (G_BUS_TYPE_SESSION,
- S_NAME,
+ !lockscreen_mode ? S_NAME_DESKTOP : S_NAME_LOCKSCREEN,
G_BUS_NAME_OWNER_FLAGS_NONE,
on_bus_acquired,
on_name_acquired,
diff --git a/services/panel-service.c b/services/panel-service.c
index 01995646e..17789027b 100644
--- a/services/panel-service.c
+++ b/services/panel-service.c
@@ -53,6 +53,7 @@ G_DEFINE_TYPE (PanelService, panel_service, G_TYPE_OBJECT);
#define SHOW_HUD_KEY "show-hud"
static PanelService *static_service = NULL;
+static gboolean lockscreen_mode = FALSE;
struct _PanelServicePrivate
{
@@ -150,7 +151,7 @@ panel_service_class_dispose (GObject *self)
g_idle_remove_by_data (self);
gdk_window_remove_filter (NULL, (GdkFilterFunc)event_filter, self);
- if (priv->upstart != NULL)
+ if (priv->upstart != NULL && !lockscreen_mode)
{
int event_sent = 0;
event_sent = upstart_emit_event_sync (NULL, priv->upstart,
@@ -461,6 +462,9 @@ event_filter (GdkXEvent *ev, GdkEvent *gev, PanelService *self)
{
case XI_KeyPress:
{
+ if (lockscreen_mode)
+ break;
+
KeySym keysym = XkbKeycodeToKeysym (event->display, event->detail, 0, 0);
if (event_matches_keybinding (event->mods.base, keysym, &priv->menu_toggle) ||
@@ -586,7 +590,7 @@ initial_resync (PanelService *self)
static gboolean
ready_signal (PanelService *self)
{
- if (PANEL_IS_SERVICE (self) && self->priv->upstart != NULL)
+ if (PANEL_IS_SERVICE (self) && self->priv->upstart != NULL && !lockscreen_mode)
{
int event_sent = 0;
event_sent = upstart_emit_event_sync (NULL, self->priv->upstart, "indicator-services-start", NULL, 0);
@@ -714,7 +718,7 @@ panel_service_init (PanelService *self)
update_keybinding (priv->gsettings, SHOW_HUD_KEY, &priv->show_hud);
const gchar *upstartsession = g_getenv ("UPSTART_SESSION");
- if (upstartsession != NULL)
+ if (upstartsession != NULL && !lockscreen_mode)
{
DBusConnection *conn = dbus_connection_open (upstartsession, NULL);
if (conn != NULL)
@@ -859,7 +863,11 @@ initial_load_default_or_custom_indicators (PanelService *self, GList *indicators
if (!indicators)
{
- load_indicators (self);
+ if (!lockscreen_mode)
+ {
+ load_indicators (self);
+ }
+
load_indicators_from_indicator_files (self);
sort_indicators (self);
}
@@ -908,6 +916,12 @@ panel_service_get_default_with_indicators (GList *indicators)
return self;
}
+void
+panel_service_set_lockscreen_mode (gboolean enable)
+{
+ lockscreen_mode = enable;
+}
+
guint
panel_service_get_n_indicators (PanelService *self)
{
@@ -1313,7 +1327,7 @@ load_indicators_from_indicator_files (PanelService *self)
IndicatorNg *indicator;
filename = g_build_filename (INDICATOR_SERVICE_DIR, name, NULL);
- indicator = indicator_ng_new_for_profile (filename, "desktop", &error);
+ indicator = indicator_ng_new_for_profile (filename, !lockscreen_mode ? "desktop" : "desktop_lockscreen", &error);
if (indicator)
{
load_indicator (self, INDICATOR_OBJECT (indicator), name);
diff --git a/services/panel-service.h b/services/panel-service.h
index f386ffdf1..a4c76ac25 100644
--- a/services/panel-service.h
+++ b/services/panel-service.h
@@ -71,6 +71,8 @@ GType panel_service_get_type (void) G_GNUC_CONST;
PanelService * panel_service_get_default ();
PanelService * panel_service_get_default_with_indicators (GList *indicators);
+void panel_service_set_lockscreen_mode (gboolean enable);
+
guint panel_service_get_n_indicators (PanelService *self);
IndicatorObject * panel_service_get_indicator_nth (PanelService *self, guint position);
diff --git a/services/unity-panel-service-lockscreen.conf.in b/services/unity-panel-service-lockscreen.conf.in
new file mode 100644
index 000000000..b6a3cb600
--- /dev/null
+++ b/services/unity-panel-service-lockscreen.conf.in
@@ -0,0 +1,8 @@
+description "Backing Service for the Unity Panel"
+author "Andrea Azzarone <andrea.azzarone@canonical.com>"
+
+start on desktop-lock
+stop on desktop-unlock
+
+respawn
+exec ${CMAKE_INSTALL_PREFIX}/lib/unity/unity-panel-service --lockscreen-mode \ No newline at end of file
diff --git a/shutdown/CMakeLists.txt b/shutdown/CMakeLists.txt
index df1de7d4e..29e332788 100644
--- a/shutdown/CMakeLists.txt
+++ b/shutdown/CMakeLists.txt
@@ -19,6 +19,7 @@ include_directories (.. ../services ../UnityCore ${UNITY_SRC} ${CMAKE_BINARY_DIR
set (SHUTDOWN_SOURCES
SessionButton.cpp
SessionController.cpp
+ SessionDBusManager.cpp
SessionView.cpp
)
diff --git a/shutdown/SessionDBusManager.cpp b/shutdown/SessionDBusManager.cpp
new file mode 100644
index 000000000..f47c7c1cc
--- /dev/null
+++ b/shutdown/SessionDBusManager.cpp
@@ -0,0 +1,180 @@
+// -*- 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: Marco Trevisan <marco.trevisan@canonical.com>
+ */
+
+#include "SessionDBusManager.h"
+
+namespace unity
+{
+namespace session
+{
+namespace dbus
+{
+const std::string NAME = "com.canonical.Unity";
+const std::string INTERFACE = "com.canonical.Unity.Session";
+const std::string OBJECT_PATH = "/com/canonical/Unity/Session";
+const std::string INTROSPECTION_XML =
+R"(<node>
+ <interface name="com.canonical.Unity.Session">
+ <method name="RealName">
+ <arg type="s" direction="out" name="realname" />
+ </method>
+ <method name="UserName">
+ <arg type="s" direction="out" name="username" />
+ </method>
+ <method name="HostName">
+ <arg type="s" direction="out" name="hostname" />
+ </method>
+ <method name="Lock" />
+ <method name="Logout" />
+ <method name="RequestLogout" />
+ <method name="Reboot" />
+ <method name="RequestReboot" />
+ <method name="Shutdown" />
+ <method name="RequestShutdown" />
+ <method name="Suspend" />
+ <method name="Hibernate" />
+ <method name="CancelAction" />
+ <method name="CanShutdown">
+ <arg type="b" direction="out" name="canshutdown" />
+ </method>
+ <method name="CanSuspend">
+ <arg type="b" direction="out" name="cansuspend" />
+ </method>
+ <method name="CanHibernate">
+ <arg type="b" direction="out" name="canhibernate" />
+ </method>
+
+ <signal name="LockRequested" />
+ <signal name="Locked" />
+ <signal name="UnlockRequested" />
+ <signal name="Unlocked" />
+ <signal name="LogoutRequested">
+ <arg type="b" name="have_inhibitors" />
+ </signal>
+ <signal name="RebootRequested">
+ <arg type="b" name="have_inhibitors" />
+ </signal>
+ <signal name="ShutdownRequested">
+ <arg type="b" name="have_inhibitors" />
+ </signal>
+ </interface>
+</node>)";
+}
+
+DBusManager::DBusManager(session::Manager::Ptr const& session)
+ : session_(session)
+ , server_(dbus::NAME)
+{
+ server_.AddObjects(dbus::INTROSPECTION_XML, dbus::OBJECT_PATH);
+ object_ = server_.GetObject(dbus::INTERFACE);
+ object_->SetMethodsCallsHandler([this] (std::string const& method, GVariant*) -> GVariant* {
+ if (method == "RealName")
+ {
+ return g_variant_new("(s)", session_->RealName().c_str());
+ }
+ else if (method == "UserName")
+ {
+ return g_variant_new("(s)", session_->UserName().c_str());
+ }
+ else if (method == "HostName")
+ {
+ return g_variant_new("(s)", session_->HostName().c_str());
+ }
+ else if (method == "Lock")
+ {
+ session_->LockScreen();
+ }
+ else if (method == "Logout")
+ {
+ session_->Logout();
+ }
+ else if (method == "RequestLogout")
+ {
+ session_->logout_requested.emit(false);
+ }
+ else if (method == "Reboot")
+ {
+ session_->Reboot();
+ }
+ else if (method == "RequestReboot")
+ {
+ session_->reboot_requested.emit(false);
+ }
+ else if (method == "Shutdown")
+ {
+ session_->Shutdown();
+ }
+ else if (method == "RequestShutdown")
+ {
+ session_->shutdown_requested.emit(false);
+ }
+ else if (method == "Suspend")
+ {
+ session_->Suspend();
+ }
+ else if (method == "Hibernate")
+ {
+ session_->Hibernate();
+ }
+ else if (method == "CancelAction")
+ {
+ session_->CancelAction();
+ session_->cancel_requested.emit();
+ }
+ else if (method == "CanShutdown")
+ {
+ return g_variant_new("(b)", session_->CanShutdown() != FALSE);
+ }
+ else if (method == "CanSuspend")
+ {
+ return g_variant_new("(b)", session_->CanSuspend() != FALSE);
+ }
+ else if (method == "CanHibernate")
+ {
+ return g_variant_new("(b)", session_->CanHibernate() != FALSE);
+ }
+
+ return nullptr;
+ });
+
+ connections_.Add(session_->lock_requested.connect([this] {
+ object_->EmitSignal("LockRequested");
+ }));
+ connections_.Add(session_->locked.connect([this] {
+ object_->EmitSignal("Locked");
+ }));
+ connections_.Add(session_->unlock_requested.connect([this] {
+ object_->EmitSignal("UnlockRequested");
+ }));
+ connections_.Add(session_->unlocked.connect([this] {
+ object_->EmitSignal("Unlocked");
+ }));
+ connections_.Add(session_->logout_requested.connect([this] (bool inhibitors) {
+ object_->EmitSignal("LogoutRequested", g_variant_new("(b)", inhibitors));
+ }));
+ connections_.Add(session_->reboot_requested.connect([this] (bool inhibitors) {
+ object_->EmitSignal("RebootRequested", g_variant_new("(b)", inhibitors));
+ }));
+ connections_.Add(session_->shutdown_requested.connect([this] (bool inhibitors) {
+ object_->EmitSignal("ShutdownRequested", g_variant_new("(b)", inhibitors));
+ }));
+}
+
+} // session
+} // unity
diff --git a/shutdown/SessionDBusManager.h b/shutdown/SessionDBusManager.h
new file mode 100644
index 000000000..dbbb2bda9
--- /dev/null
+++ b/shutdown/SessionDBusManager.h
@@ -0,0 +1,50 @@
+// -*- 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: Marco Trevisan <marco.trevisan@canonical.com>
+ */
+
+#ifndef UNITYSHELL_SESSION_DBUS_MANAGER_H
+#define UNITYSHELL_SESSION_DBUS_MANAGER_H
+
+#include <UnityCore/ConnectionManager.h>
+#include <UnityCore/GLibDBusServer.h>
+#include <UnityCore/SessionManager.h>
+
+namespace unity
+{
+namespace session
+{
+
+class DBusManager
+{
+public:
+ typedef std::shared_ptr<DBusManager> Ptr;
+
+ DBusManager(session::Manager::Ptr const& manager);
+ virtual ~DBusManager() = default;
+
+private:
+ session::Manager::Ptr session_;
+ glib::DBusServer server_;
+ glib::DBusObject::Ptr object_;
+ connection::Manager connections_;
+};
+
+} // session
+} // unity
+
+#endif
diff --git a/shutdown/StandaloneSession.cpp b/shutdown/StandaloneSession.cpp
index 206b233f7..0c64b9afe 100644
--- a/shutdown/StandaloneSession.cpp
+++ b/shutdown/StandaloneSession.cpp
@@ -38,6 +38,7 @@ public:
std::string RealName() const { return "Marco Trevisan"; }
std::string UserName() const { return "marco"; }
+ std::string HostName() const { return "tricky"; }
void LockScreen() { std::cout << "LockScreen" << std::endl; }
void Logout() { std::cout << "Logout" << std::endl; }
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 86f88a772..99dfd975f 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -243,6 +243,7 @@ if (ENABLE_X_SUPPORT)
test_launcher_icon.cpp
test_launcher_minimize_speed.cpp
test_launcher_tooltip.cpp
+ test_lockscreen_controller.cpp
test_panel_controller.cpp
test_panel_indicators_view.cpp
test_panel_indicator_entry_dropdown_view.cpp
@@ -292,6 +293,8 @@ if (ENABLE_X_SUPPORT)
test_unity_settings.cpp
test_unity_window_style.cpp
test_unity_window_view.cpp
+ test_upstart_wrapper.cpp
+ test_user_authenticator_pam.cpp
test_volume_launcher_icon.cpp
test_window_buttons.cpp
test_xdnd_manager_imp.cpp
@@ -319,7 +322,9 @@ if (ENABLE_X_SUPPORT)
decorations-lib
hud-lib
launcher-lib
+ lockscreen-lib
panel-lib
+ pam
previews-lib
shortcuts-lib
shutdown-lib
diff --git a/tests/autopilot/unity/tests/launcher/test_icon_behavior.py b/tests/autopilot/unity/tests/launcher/test_icon_behavior.py
index 669747ee4..e469be7fa 100644
--- a/tests/autopilot/unity/tests/launcher/test_icon_behavior.py
+++ b/tests/autopilot/unity/tests/launcher/test_icon_behavior.py
@@ -70,7 +70,7 @@ class LauncherIconsTests(LauncherTestCase):
self.unity.dash.ensure_visible()
self.addCleanup(self.unity.dash.ensure_hidden)
- self.assertThat(bfb.get_tooltip().active, Eventually(Equals(False)))
+ self.assertThat(bfb.get_tooltip(), Equals(None))
def test_bfb_tooltip_is_disabled_when_dash_is_open(self):
"""Tests the that bfb tooltip is disabled when the dash is open."""
diff --git a/tests/autopilot/unity/tests/launcher/test_tooltips.py b/tests/autopilot/unity/tests/launcher/test_tooltips.py
index 4ea8e53a3..f403a8a80 100644
--- a/tests/autopilot/unity/tests/launcher/test_tooltips.py
+++ b/tests/autopilot/unity/tests/launcher/test_tooltips.py
@@ -38,14 +38,13 @@ class LauncherTooltipTests(LauncherTestCase):
if size > 5:
size = 5
- # subsequent tooltips reveal instantly, but hide on exit
+ # subsequent tooltips reveal instantly, but are destroyed on exit, meaning None
a, b = 0, 1
while b < size:
self.mouse.move(self.icons[b].center.x, self.icons[b].center.y)
self.assertThat(lambda: self.icons[b].get_tooltip(), Eventually(NotEquals(None)))
self.assertThat(self.icons[b].get_tooltip().active, Eventually(Equals(True)))
- self.assertThat(lambda: self.icons[a].get_tooltip(), Eventually(NotEquals(None)))
- self.assertThat(self.icons[a].get_tooltip().active, Eventually(Equals(False)))
+ self.assertThat(self.icons[a].get_tooltip(), Equals(None))
a, b = a + 1, b + 1
b -= 1
diff --git a/tests/autopilot/unity/tests/test_quicklist.py b/tests/autopilot/unity/tests/test_quicklist.py
index 743a9fabb..9e3dd00c9 100644
--- a/tests/autopilot/unity/tests/test_quicklist.py
+++ b/tests/autopilot/unity/tests/test_quicklist.py
@@ -11,8 +11,9 @@ from __future__ import absolute_import
from autopilot.display import move_mouse_to_screen
from autopilot.matchers import Eventually
+from autopilot.introspection.dbus import StateNotFoundError
import os.path
-from testtools.matchers import Contains, Equals, NotEquals
+from testtools.matchers import Contains, Equals, NotEquals, Not, Raises
from time import sleep
from xdg.DesktopEntry import DesktopEntry
@@ -90,8 +91,7 @@ class QuicklistActionTests(UnityTestCase):
self.assertThat(lambda: len(nautilus_windows_fn()), Eventually(Equals(1)))
[nautilus_window] = nautilus_windows_fn()
- self.assertThat(lambda: self.get_startup_notification_timestamp(nautilus_window),
- Eventually(Equals(new_win_ql_item.activate_timestamp)))
+ self.assertThat(new_win_ql_item.wait_until_destroyed, Not(Raises()))
def test_quicklist_application_item_focus_last_active_window(self):
"""This tests shows that when you activate a quicklist application item
@@ -198,7 +198,7 @@ class QuicklistActionTests(UnityTestCase):
icon1_ql = self.open_quicklist_for_icon(icons[1])
self.assertThat(icon1_ql.active, Eventually(Equals(True)))
- self.assertThat(icon0_ql.active, Eventually(Equals(False)))
+ self.assertThat(icon0_ql.wait_until_destroyed, Not(Raises()))
def test_right_clicking_same_icon_doesnt_reopen_ql(self):
"""A right click to the same icon in the launcher must
@@ -213,8 +213,13 @@ class QuicklistActionTests(UnityTestCase):
calc_ql = self.open_quicklist_for_icon(calc_icon)
self.assertThat(calc_ql.active, Eventually(Equals(True)))
- calc_ql = self.open_quicklist_for_icon(calc_icon)
- self.assertThat(calc_ql.active, Eventually(Equals(False)))
+ # We've to manually open the icon this time, as when the quicklist goes away
+ # its Destroyed, so its None!
+ launcher = self.unity.launcher.get_launcher_for_monitor(0)
+ launcher.click_launcher_icon(calc_icon, button=3)
+ self.addCleanup(self.keyboard.press_and_release, "Escape")
+ calc_ql = calc_icon.get_quicklist()
+ self.assertThat(calc_ql, Equals(None))
class QuicklistKeyNavigationTests(UnityTestCase):
diff --git a/tests/autopilot/unity/tests/test_spread.py b/tests/autopilot/unity/tests/test_spread.py
index 7093b9303..beaf41f82 100644
--- a/tests/autopilot/unity/tests/test_spread.py
+++ b/tests/autopilot/unity/tests/test_spread.py
@@ -200,7 +200,7 @@ class SpreadTests(UnityTestCase):
self.assertThat(icon.get_tooltip().active, Eventually(Equals(True)))
self.initiate_spread_for_screen()
- self.assertThat(icon.get_tooltip().active, Eventually(Equals(False)))
+ self.assertThat(icon.get_tooltip(), Equals(None))
def test_spread_puts_panel_in_overlay_mode(self):
"""Test that the panel is in overlay mode when in spread"""
diff --git a/tests/data/external.gschema.xml b/tests/data/external.gschema.xml
index a7e292e0e..160b79723 100644
--- a/tests/data/external.gschema.xml
+++ b/tests/data/external.gschema.xml
@@ -52,4 +52,28 @@
<default>false</default>
</key>
</schema>
+
+ <schema id="com.canonical.unity-greeter" path="/com/canonical/unity-greeter/">
+ <key type="s" name="logo">
+ <default>'/usr/share/unity-greeter/logo.png'</default>
+ </key>
+ <key type="s" name="font-name">
+ <default>'Ubuntu 11'</default>
+ </key>
+ <key type="s" name="background">
+ <default>'/usr/share/backgrounds/warty-final-ubuntu.png'</default>
+ </key>
+ <key type="s" name="background-color">
+ <default>'#2C001E'</default>
+ </key>
+ <key type="b" name="draw-user-backgrounds">
+ <default>true</default>
+ </key>
+ <key type="b" name="draw-grid">
+ <default>true</default>
+ </key>
+ <key type="b" name="show-hostname">
+ <default>true</default>
+ </key>
+ </schema>
</schemalist>
diff --git a/tests/test_gnome_session_manager.cpp b/tests/test_gnome_session_manager.cpp
index 79017bdb0..0335012d5 100644
--- a/tests/test_gnome_session_manager.cpp
+++ b/tests/test_gnome_session_manager.cpp
@@ -37,9 +37,9 @@ const std::string SHELL_INTERFACE = "org.gnome.SessionManager.EndSessionDialog";
const std::string SHELL_OBJECT_PATH = "/org/gnome/SessionManager/EndSessionDialog";
const std::string UPOWER_PATH = "/org/freedesktop/UPower";
-const std::string LOGIND_PATH = "/org/freedesktop/login1";
+const std::string LOGIND_MANAGER_PATH = "/org/freedesktop/login1";
+const std::string LOGIND_SESSION_PATH = "/org/freedesktop/login1/session/id0";
const std::string CONSOLE_KIT_PATH = "/org/freedesktop/ConsoleKit/Manager";
-const std::string SCREEN_SAVER_PATH = "/org/gnome/ScreenSaver";
const std::string SESSION_MANAGER_PATH = "/org/gnome/SessionManager";
const std::string SESSION_OPTIONS = "com.canonical.indicator.session";
@@ -62,7 +62,7 @@ R"(<node>
</interface>
</node>)";
-const std::string LOGIND =
+const std::string LOGIND_MANAGER =
R"(<node>
<interface name="org.freedesktop.login1.Manager">
<method name="CanSuspend">
@@ -89,6 +89,14 @@ R"(<node>
</interface>
</node>)";
+const std::string LOGIND_SESSION =
+R"(<node>
+ <interface name="org.freedesktop.login1.Session">
+ <signal name="Lock" />
+ <signal name="Unlock" />
+ </interface>
+</node>)";
+
const std::string CONSOLE_KIT =
R"(<node>
<interface name="org.freedesktop.ConsoleKit.Manager">
@@ -100,14 +108,6 @@ R"(<node>
</interface>
</node>)";
-const std::string SCREEN_SAVER =
-R"(<node>
- <interface name="org.gnome.ScreenSaver">
- <method name="Lock"/>
- <method name="SimulateUserActivity"/>
- </interface>
-</node>)";
-
const std::string SESSION_MANAGER =
R"(<node>
<interface name="org.gnome.SessionManager">
@@ -162,7 +162,8 @@ struct TestGnomeSessionManager : testing::Test
});
logind_ = std::make_shared<DBusServer>();
- logind_->AddObjects(introspection::LOGIND, LOGIND_PATH);
+ logind_->AddObjects(introspection::LOGIND_MANAGER, LOGIND_MANAGER_PATH);
+ logind_->AddObjects(introspection::LOGIND_SESSION, LOGIND_SESSION_PATH);
logind_->GetObjects().front()->SetMethodsCallsHandler([&] (std::string const& method, GVariant*) -> GVariant* {
if (method == "CanSuspend")
{
@@ -181,9 +182,6 @@ struct TestGnomeSessionManager : testing::Test
console_kit_ = std::make_shared<DBusServer>();
console_kit_->AddObjects(introspection::CONSOLE_KIT, CONSOLE_KIT_PATH);
- screen_saver_ = std::make_shared<DBusServer>();
- screen_saver_->AddObjects(introspection::SCREEN_SAVER, SCREEN_SAVER_PATH);
-
session_manager_ = std::make_shared<DBusServer>();
session_manager_->AddObjects(introspection::SESSION_MANAGER, SESSION_MANAGER_PATH);
session_manager_->GetObjects().front()->SetMethodsCallsHandler([&] (std::string const& method, GVariant*) -> GVariant* {
@@ -215,7 +213,6 @@ struct TestGnomeSessionManager : testing::Test
Utils::WaitUntilMSec([] { return upower_->IsConnected(); });
Utils::WaitUntilMSec([] { return logind_->IsConnected(); });
Utils::WaitUntilMSec([] { return console_kit_->IsConnected(); });
- Utils::WaitUntilMSec([] { return screen_saver_->IsConnected(); });
Utils::WaitUntilMSec([] { return session_manager_->IsConnected(); });
Utils::WaitUntilMSec([] { return shell_proxy_->IsConnected();});
ASSERT_TRUE(shell_proxy_->IsConnected());
@@ -267,7 +264,6 @@ struct TestGnomeSessionManager : testing::Test
upower_.reset();
logind_.reset();
console_kit_.reset();
- screen_saver_.reset();
session_manager_.reset();
}
@@ -327,7 +323,6 @@ struct TestGnomeSessionManager : testing::Test
static DBusServer::Ptr upower_;
static DBusServer::Ptr console_kit_;
static DBusServer::Ptr logind_;
- static DBusServer::Ptr screen_saver_;
static DBusServer::Ptr session_manager_;
static DBusProxy::Ptr shell_proxy_;
};
@@ -336,7 +331,6 @@ session::Manager::Ptr TestGnomeSessionManager::manager;
DBusServer::Ptr TestGnomeSessionManager::upower_;
DBusServer::Ptr TestGnomeSessionManager::console_kit_;
DBusServer::Ptr TestGnomeSessionManager::logind_;
-DBusServer::Ptr TestGnomeSessionManager::screen_saver_;
DBusServer::Ptr TestGnomeSessionManager::session_manager_;
DBusProxy::Ptr TestGnomeSessionManager::shell_proxy_;
bool TestGnomeSessionManager::can_shutdown_;
@@ -375,31 +369,17 @@ TEST_F(TestGnomeSessionManager, UserName)
TEST_F(TestGnomeSessionManager, LockScreen)
{
- bool lock_called = false;
- bool simulate_activity_called = false;
+ bool lock_emitted = false;
- screen_saver_->GetObjects().front()->SetMethodsCallsHandler([&] (std::string const& method, GVariant*) -> GVariant* {
- if (method == "Lock")
- {
- lock_called = true;
- EXPECT_FALSE(simulate_activity_called);
- }
- else if (method == "SimulateUserActivity")
- {
- simulate_activity_called = true;
- EXPECT_TRUE(lock_called);
- }
-
- return nullptr;
+ manager->lock_requested.connect([&lock_emitted]()
+ {
+ lock_emitted = true;
});
manager->LockScreen();
- Utils::WaitUntilMSec(lock_called);
- EXPECT_TRUE(lock_called);
-
- Utils::WaitUntilMSec(simulate_activity_called);
- EXPECT_TRUE(simulate_activity_called);
+ Utils::WaitUntilMSec(lock_emitted);
+ EXPECT_TRUE(lock_emitted);
}
TEST_F(TestGnomeSessionManager, Logout)
@@ -1004,4 +984,34 @@ TEST_F(TestGnomeSessionManager, CancelRequested)
EXPECT_TRUE(closed);
}
+TEST_F(TestGnomeSessionManager, DISABLED_LogindLock)
+{
+ bool lock_emitted = false;
+
+ manager->lock_requested.connect([&lock_emitted]()
+ {
+ lock_emitted = true;
+ });
+
+ logind_->GetObject("org.freedesktop.login1.Session")->EmitSignal("Lock");
+
+ Utils::WaitUntilMSec(lock_emitted);
+ EXPECT_TRUE(lock_emitted);
+}
+
+TEST_F(TestGnomeSessionManager, LogindUnLock)
+{
+ bool unlock_emitted = false;
+
+ manager->unlock_requested.connect([&unlock_emitted]()
+ {
+ unlock_emitted = true;
+ });
+
+ logind_->GetObject("org.freedesktop.login1.Session")->EmitSignal("Unlock");
+
+ Utils::WaitUntilMSec(unlock_emitted);
+ EXPECT_TRUE(unlock_emitted);
+}
+
} // Namespace
diff --git a/tests/test_lockscreen_controller.cpp b/tests/test_lockscreen_controller.cpp
new file mode 100644
index 000000000..7e817cff6
--- /dev/null
+++ b/tests/test_lockscreen_controller.cpp
@@ -0,0 +1,344 @@
+// -*- 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 <gmock/gmock.h>
+using namespace testing;
+
+#include "lockscreen/LockScreenController.h"
+
+#include <Nux/NuxTimerTickSource.h>
+#include <NuxCore/AnimationController.h>
+#include <UnityCore/GLibDBusServer.h>
+
+
+#include "lockscreen/LockScreenSettings.h"
+#include "unity-shared/PanelStyle.h"
+#include "unity-shared/UScreen.h"
+#include "unity-shared/UnitySettings.h"
+#include "test_mock_session_manager.h"
+#include "test_uscreen_mock.h"
+#include "test_utils.h"
+
+namespace unity
+{
+namespace lockscreen
+{
+namespace
+{
+
+const unsigned ANIMATION_DURATION = 400 * 1000; // in microseconds
+const unsigned TICK_DURATION = 10 * 1000;
+
+const std::string TEST_SERVER_NAME = "com.canonical.Unity.Test.DisplayManager";
+const std::string LIGHTDM_PATH = "/org/freedesktop/DisplayManager/Session0";
+
+}
+
+namespace introspection
+{
+
+const std::string LIGHTDM =
+R"(<node>
+ <interface name="org.freedesktop.DisplayManager.Session">
+ <method name="Lock"/>
+ </interface>
+</node>)";
+
+}
+
+struct MockShield : AbstractShield
+{
+ MockShield()
+ : AbstractShield(nullptr, nullptr, 0, false)
+ {}
+
+ MOCK_CONST_METHOD0(IsIndicatorOpen, bool());
+};
+
+struct ShieldFactoryMock : ShieldFactoryInterface
+{
+ nux::ObjectPtr<AbstractShield> CreateShield(session::Manager::Ptr const&, indicator::Indicators::Ptr const&, int, bool) override
+ {
+ return nux::ObjectPtr<AbstractShield>(new MockShield());
+ }
+};
+
+struct TestLockScreenController : Test
+{
+ TestLockScreenController()
+ : animation_controller(tick_source)
+ , session_manager(std::make_shared<NiceMock<session::MockManager>>())
+ , upstart_wrapper(std::make_shared<UpstartWrapper>())
+ , shield_factory(std::make_shared<ShieldFactoryMock>())
+ , controller(session_manager, upstart_wrapper, shield_factory)
+ {
+ lightdm_ = std::make_shared<glib::DBusServer>(TEST_SERVER_NAME);
+ lightdm_->AddObjects(introspection::LIGHTDM, LIGHTDM_PATH);
+
+ Utils::WaitUntilMSec([] { return lightdm_->IsConnected(); });
+ }
+
+ struct ControllerWrap : Controller
+ {
+ ControllerWrap(session::Manager::Ptr const& session_manager,
+ UpstartWrapper::Ptr const& upstart_wrapper,
+ ShieldFactoryInterface::Ptr const& shield_factory)
+ : Controller(session_manager, upstart_wrapper, shield_factory, /* test_mode */ true)
+ {}
+
+ using Controller::shields_;
+ };
+
+ nux::NuxTimerTickSource tick_source;
+ nux::animation::AnimationController animation_controller;
+
+ MockUScreen uscreen;
+ unity::Settings unity_settings;
+ unity::panel::Style panel_style;
+ unity::lockscreen::Settings lockscreen_settings;
+ static glib::DBusServer::Ptr lightdm_;
+ session::MockManager::Ptr session_manager;
+ unity::UpstartWrapper::Ptr upstart_wrapper;
+
+ ShieldFactoryMock::Ptr shield_factory;
+ ControllerWrap controller;
+};
+
+glib::DBusServer::Ptr TestLockScreenController::lightdm_;
+
+TEST_F(TestLockScreenController, Construct)
+{
+ EXPECT_TRUE(controller.shields_.empty());
+}
+
+TEST_F(TestLockScreenController, DisconnectUScreenSignalsOnDestruction)
+{
+ size_t before = uscreen.changed.size();
+ {
+ Controller dummy(session_manager);
+ }
+ ASSERT_EQ(before, uscreen.changed.size());
+
+ std::vector<nux::Geometry> monitors;
+ uscreen.changed.emit(0, monitors);
+}
+
+TEST_F(TestLockScreenController, DisconnectSessionManagerSignalsOnDestruction)
+{
+ size_t before = session_manager->unlock_requested.size();
+ {
+ Controller dummy(session_manager);
+ }
+ ASSERT_EQ(before, session_manager->unlock_requested.size());
+
+ session_manager->unlock_requested.emit();
+}
+
+TEST_F(TestLockScreenController, UScreenChangedIgnoredOnScreenUnlocked)
+{
+ uscreen.SetupFakeMultiMonitor(/*primary*/ 0, /*emit_change*/ true);
+ EXPECT_TRUE(controller.shields_.empty());
+}
+
+TEST_F(TestLockScreenController, LockScreenTypeNone)
+{
+ lockscreen_settings.lockscreen_type = Type::NONE;
+ session_manager->lock_requested.emit();
+
+ ASSERT_EQ(0, controller.shields_.size());
+}
+
+TEST_F(TestLockScreenController, LockScreenTypeLightdmOnSingleMonitor)
+{
+ g_setenv("XDG_SESSION_PATH", LIGHTDM_PATH.c_str(), true);
+
+ bool lock_called = false;
+
+ lightdm_->GetObjects().front()->SetMethodsCallsHandler([&] (std::string const& method, GVariant*) -> GVariant* {
+ if (method == "Lock")
+ lock_called = true;
+
+ return nullptr;
+ });
+
+ lockscreen_settings.lockscreen_type = Type::LIGHTDM;
+ session_manager->lock_requested.emit();
+
+ ASSERT_EQ(1, controller.shields_.size());
+ EXPECT_FALSE(controller.shields_.at(0)->primary());
+ Utils::WaitUntilMSec(lock_called);
+}
+
+TEST_F(TestLockScreenController, LockScreenTypeLightdmOnMultiMonitor)
+{
+ g_setenv("XDG_SESSION_PATH", LIGHTDM_PATH.c_str(), true);
+
+ bool lock_called = false;
+
+ lightdm_->GetObjects().front()->SetMethodsCallsHandler([&] (std::string const& method, GVariant*) -> GVariant* {
+ if (method == "Lock")
+ lock_called = true;
+
+ return nullptr;
+ });
+
+ lockscreen_settings.lockscreen_type = Type::LIGHTDM;
+ uscreen.SetupFakeMultiMonitor(/*primary*/ 0, /*emit_change*/ true);
+ session_manager->lock_requested.emit();
+
+ ASSERT_EQ(monitors::MAX, controller.shields_.size());
+
+ for (unsigned int i=0; i < monitors::MAX; ++i)
+ EXPECT_FALSE(controller.shields_.at(i)->primary());
+
+ Utils::WaitUntilMSec(lock_called);
+}
+
+TEST_F(TestLockScreenController, UnlockScreenTypeLightdmOnSingleMonitor)
+{
+ g_setenv("XDG_SESSION_PATH", LIGHTDM_PATH.c_str(), true);
+
+ bool lock_called = false;
+
+ lightdm_->GetObjects().front()->SetMethodsCallsHandler([&] (std::string const& method, GVariant*) -> GVariant* {
+ if (method == "Lock")
+ lock_called = true;
+
+ return nullptr;
+ });
+
+ lockscreen_settings.lockscreen_type = Type::LIGHTDM;
+ session_manager->lock_requested.emit();
+
+ ASSERT_EQ(1, controller.shields_.size());
+ Utils::WaitUntilMSec(lock_called);
+
+ session_manager->unlock_requested.emit();
+ tick_source.tick(ANIMATION_DURATION);
+
+ ASSERT_EQ(0, controller.shields_.size());
+}
+
+TEST_F(TestLockScreenController, UnlockScreenTypeLightdmOnMultiMonitor)
+{
+ g_setenv("XDG_SESSION_PATH", LIGHTDM_PATH.c_str(), true);
+
+ bool lock_called = false;
+
+ lightdm_->GetObjects().front()->SetMethodsCallsHandler([&] (std::string const& method, GVariant*) -> GVariant* {
+ if (method == "Lock")
+ lock_called = true;
+
+ return nullptr;
+ });
+
+ lockscreen_settings.lockscreen_type = Type::LIGHTDM;
+ uscreen.SetupFakeMultiMonitor(/*primary*/ 0, /*emit_change*/ true);
+ session_manager->lock_requested.emit();
+
+ ASSERT_EQ(monitors::MAX, controller.shields_.size());
+ Utils::WaitUntilMSec(lock_called);
+
+ session_manager->unlock_requested.emit();
+ tick_source.tick(ANIMATION_DURATION);
+
+ ASSERT_EQ(0, controller.shields_.size());
+}
+
+TEST_F(TestLockScreenController, LockScreenOnSingleMonitor)
+{
+ session_manager->lock_requested.emit();
+
+ ASSERT_EQ(1, controller.shields_.size());
+ EXPECT_EQ(uscreen.GetMonitors().at(0), controller.shields_.at(0)->GetGeometry());
+}
+
+TEST_F(TestLockScreenController, LockScreenOnMultiMonitor)
+{
+ uscreen.SetupFakeMultiMonitor();
+
+ session_manager->lock_requested.emit();
+ ASSERT_EQ(monitors::MAX, controller.shields_.size());
+
+ for (unsigned int i=0; i < monitors::MAX; ++i)
+ EXPECT_EQ(uscreen.GetMonitors().at(i), controller.shields_.at(i)->GetAbsoluteGeometry());
+}
+
+TEST_F(TestLockScreenController, SwitchToMultiMonitor)
+{
+ session_manager->lock_requested.emit();
+ tick_source.tick(ANIMATION_DURATION);
+
+ ASSERT_EQ(1, controller.shields_.size());
+ EXPECT_EQ(uscreen.GetMonitors().at(0), controller.shields_.at(0)->GetGeometry());
+
+ uscreen.SetupFakeMultiMonitor(/* primary */ 0, /* emit_change */ true);
+
+ ASSERT_EQ(monitors::MAX, controller.shields_.size());
+
+ for (unsigned int i=0; i < monitors::MAX; ++i)
+ {
+ ASSERT_EQ(uscreen.GetMonitors().at(i), controller.shields_.at(i)->GetAbsoluteGeometry());
+ ASSERT_TRUE(controller.shields_.at(i)->IsVisible());
+ }
+}
+
+TEST_F(TestLockScreenController, SwitchToSingleMonitor)
+{
+ uscreen.SetupFakeMultiMonitor(/* primary */ 0, /* emit_change */ true);
+ session_manager->lock_requested.emit();
+
+ ASSERT_EQ(monitors::MAX, controller.shields_.size());
+
+ for (unsigned int i=0; i < monitors::MAX; ++i)
+ ASSERT_EQ(uscreen.GetMonitors().at(i), controller.shields_.at(i)->GetAbsoluteGeometry());
+
+ uscreen.Reset(/* emit_change */ true);
+
+ ASSERT_EQ(1, controller.shields_.size());
+ EXPECT_EQ(uscreen.GetMonitors().at(0), controller.shields_.at(0)->GetGeometry());
+}
+
+TEST_F(TestLockScreenController, UnlockScreenOnSingleMonitor)
+{
+ session_manager->lock_requested.emit();
+
+ ASSERT_EQ(1, controller.shields_.size());
+
+ session_manager->unlock_requested.emit();
+ tick_source.tick(ANIMATION_DURATION);
+
+ EXPECT_TRUE(controller.shields_.empty());
+}
+
+TEST_F(TestLockScreenController, UnlockScreenOnMultiMonitor)
+{
+ uscreen.SetupFakeMultiMonitor(/* primary */ 0, /* emit_change */ true);
+ session_manager->lock_requested.emit();
+
+ ASSERT_EQ(monitors::MAX, controller.shields_.size());
+
+ session_manager->unlock_requested.emit();
+ tick_source.tick(ANIMATION_DURATION);
+
+ EXPECT_TRUE(controller.shields_.empty());
+}
+
+} // lockscreen
+} // unity
diff --git a/tests/test_mock_session_manager.h b/tests/test_mock_session_manager.h
index 352e914f8..42da560c5 100644
--- a/tests/test_mock_session_manager.h
+++ b/tests/test_mock_session_manager.h
@@ -31,6 +31,7 @@ struct MockManager : Manager
MOCK_CONST_METHOD0(RealName, std::string());
MOCK_CONST_METHOD0(UserName, std::string());
+ MOCK_CONST_METHOD0(HostName, std::string());
MOCK_METHOD0(LockScreen, void());
MOCK_METHOD0(Logout, void());
diff --git a/tests/test_text_input.cpp b/tests/test_text_input.cpp
index aad469861..440a1c015 100644
--- a/tests/test_text_input.cpp
+++ b/tests/test_text_input.cpp
@@ -22,7 +22,9 @@
#include <gtest/gtest.h>
+#include "unity-shared/DashStyle.h"
#include "unity-shared/TextInput.h"
+#include "unity-shared/UnitySettings.h"
#include "test_utils.h"
using namespace nux;
@@ -33,7 +35,6 @@ namespace unity
class TextInputMock : public TextInput
{
public:
- using TextInput::Init;
using TextInput::OnInputHintChanged;
using TextInput::OnMouseButtonDown;
using TextInput::OnEndKeyFocus;
@@ -50,11 +51,12 @@ class TestTextInput : public ::testing::Test
TestTextInput()
{
entry = new TextInputMock();
- entry->Init();
hint = entry->GetHint();
pango_entry = entry->GetPangoEntry();
}
+ unity::Settings unity_settings_;
+ dash::Style dash_style_;
nux::ObjectPtr<TextInputMock> entry;
StaticCairoText* hint;
IMTextEntry* pango_entry;
diff --git a/tests/test_upstart_wrapper.cpp b/tests/test_upstart_wrapper.cpp
new file mode 100644
index 000000000..95b17d357
--- /dev/null
+++ b/tests/test_upstart_wrapper.cpp
@@ -0,0 +1,90 @@
+// -*- 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 <gtest/gtest.h>
+using namespace testing;
+
+#include "unity-shared/UpstartWrapper.h"
+
+#include <UnityCore/GLibDBusServer.h>
+#include <UnityCore/Variant.h>
+
+#include "test_utils.h"
+
+namespace
+{
+
+const std::string UPSTART =
+R"(<node>
+ <interface name="com.ubuntu.Upstart0_6">
+ <method name="EmitEvent">
+ <arg name="name" type="s" direction="in" />
+ <arg name="env" type="as" direction="in" />
+ <arg name="wait" type="b" direction="in" />
+ </method>
+
+ <signal name="EventEmitted">
+ <arg name="name" type="s" />
+ <arg name="env" type="as" />
+ </signal>
+ </interface>
+</node>)";
+
+struct MockUpstartWrapper : unity::UpstartWrapper {
+ MockUpstartWrapper()
+ : UpstartWrapper(UpstartWrapper::TestMode())
+ {}
+};
+
+struct TestUpstartWrapper : public Test
+{
+ TestUpstartWrapper()
+ {
+ upstart_server_ = std::make_shared<unity::glib::DBusServer>("com.canonical.Unity.Test.Upstart");
+ upstart_server_->AddObjects(UPSTART, "/com/ubuntu/Upstart");
+
+ Utils::WaitUntilMSec([this] { return upstart_server_->IsConnected(); });
+ }
+
+ unity::glib::DBusServer::Ptr upstart_server_;
+ MockUpstartWrapper upstart_wrapper_;
+};
+
+
+TEST_F(TestUpstartWrapper, Emit)
+{
+ bool event_emitted = false;
+
+ upstart_server_->GetObjects().front()->SetMethodsCallsHandler([&] (std::string const& method, GVariant* par) -> GVariant* {
+ if (method == "EmitEvent")
+ {
+ event_emitted = true;
+
+ std::string event_name = glib::Variant(g_variant_get_child_value(par, 0)).GetString();
+ EXPECT_EQ("desktop-lock", event_name);
+ }
+
+ return nullptr;
+ });
+
+ upstart_wrapper_.Emit("desktop-lock");
+ Utils::WaitUntil(event_emitted);
+}
+
+}
diff --git a/tests/test_user_authenticator_pam.cpp b/tests/test_user_authenticator_pam.cpp
new file mode 100644
index 000000000..64b9a8431
--- /dev/null
+++ b/tests/test_user_authenticator_pam.cpp
@@ -0,0 +1,58 @@
+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
+/*
+ * Copyright (C) 2013 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 <gtest/gtest.h>
+
+#include "lockscreen/UserAuthenticatorPam.h"
+#include "test_utils.h"
+
+using unity::lockscreen::UserAuthenticatorPam;
+
+#include <security/pam_appl.h>
+
+// Would be nice to build a testing pam module, but writing a
+// pam_authenticate function here works just fine for the moment.
+int pam_authenticate(pam_handle_t *pamh, int flags)
+{
+ pam_conv* conversation;
+ struct pam_message msg;
+ const struct pam_message *msgp;
+
+ pam_get_item(pamh, PAM_CONV, (const void**) &conversation);
+
+ msg.msg_style = PAM_PROMPT_ECHO_OFF;
+ msgp = &msg;
+
+ pam_response* resp = nullptr;
+ conversation->conv(1, &msgp, &resp, conversation->appdata_ptr);
+
+ return strcmp(resp[0].resp, "password");
+}
+
+namespace
+{
+
+struct TestUserAuthenticatorPam : public ::testing::Test
+{
+ UserAuthenticatorPam user_authenticator_pam_;
+};
+
+// FIXME (add tests)
+
+}
diff --git a/tests/test_utils.h b/tests/test_utils.h
index 6e989afd6..4b04d8be4 100644
--- a/tests/test_utils.h
+++ b/tests/test_utils.h
@@ -46,7 +46,7 @@ public:
if (result == expected_result)
g_source_remove(timeout_id);
- EXPECT_EQ(result, expected_result) << (error_msg.empty() ? "" : ("Error: " + error_msg));
+ EXPECT_EQ(expected_result, result) << (error_msg.empty() ? "" : ("Error: " + error_msg));
}
static void WaitUntil(std::function<bool()> const& check_function, bool result = true, unsigned max_wait = 1, std::string const& error_msg = "")
diff --git a/unity-shared/CMakeLists.txt b/unity-shared/CMakeLists.txt
index 1e6233aff..b56c77990 100644
--- a/unity-shared/CMakeLists.txt
+++ b/unity-shared/CMakeLists.txt
@@ -67,6 +67,7 @@ set (UNITY_SHARED_SOURCES
UnitySettings.cpp
UnityWindowStyle.cpp
UnityWindowView.cpp
+ UpstartWrapper.cpp
UserThumbnailProvider.cpp
VScrollBarOverlayWindow.cpp
WindowButtons.cpp
diff --git a/unity-shared/GtkTexture.h b/unity-shared/GtkTexture.h
new file mode 100644
index 000000000..9d6e70c49
--- /dev/null
+++ b/unity-shared/GtkTexture.h
@@ -0,0 +1,64 @@
+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
+/*
+ * Copyright 2013 Canonical Ltd.
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser 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 warranties of
+ * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the applicable version of the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of both the GNU Lesser General Public
+ * License version 3 along with this program. If not, see
+ * <http://www.gnu.org/licenses/>
+ *
+ * Authored by: Andrea Azzarone <andrea.azzarone@canonical.com>
+ *
+ */
+
+#ifndef UNITY_GDK_TEXTURE_H
+#define UNITY_GDK_TEXTURE_H
+
+#include <Nux/Nux.h>
+#include <NuxGraphics/GdkGraphics.h>
+#include <NuxGraphics/NuxGraphics.h>
+#include <NuxGraphics/GLTextureResourceManager.h>
+
+namespace unity
+{
+
+typedef nux::ObjectPtr<nux::BaseTexture> BaseTexturePtr;
+
+// Create a texture from the GdkGraphics object.
+//
+// Returns a new BaseTexture that has a ref count of 1.
+inline nux::BaseTexture* texture_from_gdk_graphics(nux::GdkGraphics const& cg)
+{
+ nux::NBitmapData* bitmap = cg.GetBitmap();
+ nux::BaseTexture* tex = nux::GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableTexture();
+ tex->Update(bitmap);
+ delete bitmap;
+ return tex;
+}
+
+// Create a texture from the GdkGraphics object.
+//
+// Returns a new smart pointer to a texture where that smart pointer is the
+// sole owner of the texture object.
+inline BaseTexturePtr texture_ptr_from_gdk_graphics(nux::GdkGraphics const& cg)
+{
+ BaseTexturePtr result(texture_from_gdk_graphics(cg));
+ // Since the ObjectPtr takes a reference, and the texture is initially
+ // owned, the reference count now is two.
+ nuxAssert(result->GetReferenceCount() == 2);
+ result->UnReference();
+ return result;
+}
+
+}
+
+#endif
diff --git a/unity-shared/IMTextEntry.cpp b/unity-shared/IMTextEntry.cpp
index db7c86c29..0e4e383f3 100644
--- a/unity-shared/IMTextEntry.cpp
+++ b/unity-shared/IMTextEntry.cpp
@@ -1,4 +1,4 @@
-// -*- Mode: C++; indent-tabs-mode: ni; tab-width: 2 -*-
+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
/*
* Copyright (C) 2011-2012 Canonical Ltd
*
@@ -26,7 +26,7 @@ namespace unity
NUX_IMPLEMENT_OBJECT_TYPE(IMTextEntry);
IMTextEntry::IMTextEntry()
-: TextEntry("", NUX_TRACKER_LOCATION)
+ : TextEntry("", NUX_TRACKER_LOCATION)
{}
void IMTextEntry::CopyClipboard()
@@ -85,4 +85,5 @@ bool IMTextEntry::im_preedit()
{
return !preedit_.empty();
}
+
}
diff --git a/unity-shared/IMTextEntry.h b/unity-shared/IMTextEntry.h
index 086b23e51..194077e90 100644
--- a/unity-shared/IMTextEntry.h
+++ b/unity-shared/IMTextEntry.h
@@ -32,7 +32,7 @@ class IMTextEntry : public nux::TextEntry
NUX_DECLARE_OBJECT_TYPE(IMTextEntry, nux::TextEntry);
public:
IMTextEntry();
- virtual ~IMTextEntry() {}
+
bool im_preedit();
protected:
diff --git a/unity-shared/MockableBaseWindow.h b/unity-shared/MockableBaseWindow.h
index 3fa051b12..fb52eef06 100644
--- a/unity-shared/MockableBaseWindow.h
+++ b/unity-shared/MockableBaseWindow.h
@@ -37,7 +37,6 @@ public:
: nux::BaseWindow(window_name, NUX_TRACKER_LOCATION)
, struts_enabled_(false)
{}
- virtual ~MockableBaseWindow() {}
/**
* Sets the window opacity.
diff --git a/unity-shared/TextInput.cpp b/unity-shared/TextInput.cpp
index f4f38bbbb..2dfb72769 100644
--- a/unity-shared/TextInput.cpp
+++ b/unity-shared/TextInput.cpp
@@ -30,9 +30,8 @@ const int TEXT_INPUT_RIGHT_BORDER = 10;
const int HIGHLIGHT_HEIGHT = 24;
// Fonts
-const std::string HINT_LABEL_FONT_SIZE = "12px";
-const std::string HINT_LABEL_FONT_STYLE = "Italic";
-const std::string HINT_LABEL_DEFAULT_FONT = "Ubuntu " + HINT_LABEL_FONT_STYLE + " " + HINT_LABEL_FONT_SIZE;
+const std::string HINT_LABEL_DEFAULT_FONT_NAME = "Ubuntu";
+const int HINT_LABEL_FONT_SIZE = 11;
const std::string PANGO_ENTRY_DEFAULT_FONT_FAMILY = "Ubuntu";
const int PANGO_ENTRY_FONT_SIZE = 14;
@@ -42,34 +41,33 @@ const int PANGO_ENTRY_FONT_SIZE = 14;
namespace unity
{
-nux::logging::Logger logger("unity.dash.textinput");
+nux::logging::Logger logger("unity.textinput");
NUX_IMPLEMENT_OBJECT_TYPE(TextInput);
TextInput::TextInput(NUX_FILE_LINE_DECL)
: View(NUX_FILE_LINE_PARAM)
, input_hint("")
+ , hint_font_name(HINT_LABEL_DEFAULT_FONT_NAME)
+ , hint_font_size(HINT_LABEL_FONT_SIZE)
+ , bg_layer_(new nux::ColorLayer(nux::Color(0xff595853), true))
, last_width_(-1)
, last_height_(-1)
{
- Init();
-}
-
-void TextInput::Init()
-{
- bg_layer_.reset(new nux::ColorLayer(nux::Color(0xff595853), true));
-
layout_ = new nux::HLayout(NUX_TRACKER_LOCATION);
layout_->SetLeftAndRightPadding(LEFT_INTERNAL_PADDING, TEXT_INPUT_RIGHT_BORDER);
layout_->SetSpaceBetweenChildren(SPACE_BETWEEN_ENTRY_AND_HIGHLIGHT);
SetLayout(layout_);
nux::HLayout* hint_layout = new nux::HLayout(NUX_TRACKER_LOCATION);
+ hint_layout->SetLeftAndRightPadding(3, 3);
- hint_ = new StaticCairoText(" ");
+ hint_ = new StaticCairoText("");
hint_->SetTextColor(nux::Color(1.0f, 1.0f, 1.0f, 0.5f));
- hint_->SetFont(HINT_LABEL_DEFAULT_FONT.c_str());
- hint_layout->AddView(hint_, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL);
+ hint_layout->AddView(hint_, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL);
+ hint_font_name.changed.connect(sigc::hide(sigc::mem_fun(this, &TextInput::UpdateHintFont)));
+ hint_font_size.changed.connect(sigc::hide(sigc::mem_fun(this, &TextInput::UpdateHintFont)));
+ UpdateHintFont();
pango_entry_ = new IMTextEntry();
pango_entry_->SetFontFamily(PANGO_ENTRY_DEFAULT_FONT_FAMILY.c_str());
@@ -77,14 +75,22 @@ void TextInput::Init()
pango_entry_->cursor_moved.connect([this](int i) { QueueDraw(); });
pango_entry_->mouse_down.connect(sigc::mem_fun(this, &TextInput::OnMouseButtonDown));
pango_entry_->end_key_focus.connect(sigc::mem_fun(this, &TextInput::OnEndKeyFocus));
+ pango_entry_->text_changed.connect([this](nux::TextEntry*) {
+ hint_->SetVisible(input_string().empty());
+ });
layered_layout_ = new nux::LayeredLayout();
- layered_layout_->AddLayout(hint_layout);
+ layered_layout_->AddLayer(hint_layout);
layered_layout_->AddLayer(pango_entry_);
layered_layout_->SetPaintAll(true);
layered_layout_->SetActiveLayerN(1);
layout_->AddView(layered_layout_, 1, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FIX);
+ spinner_ = new SearchBarSpinner();
+ spinner_->SetVisible(false);
+ spinner_->SetMinMaxSize(22, 22);
+ layout_->AddView(spinner_, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL);
+
sig_manager_.Add<void, GtkSettings*, GParamSpec*>(gtk_settings_get_default(),
"notify::gtk-font-name", sigc::mem_fun(this, &TextInput::OnFontChanged));
OnFontChanged(gtk_settings_get_default());
@@ -97,11 +103,25 @@ void TextInput::Init()
}
+void TextInput::SetSpinnerVisible(bool visible)
+{
+ spinner_->SetVisible(visible);
+}
+
+void TextInput::SetSpinnerState(SpinnerState spinner_state)
+{
+ spinner_->SetState(spinner_state);
+}
+
+void TextInput::UpdateHintFont()
+{
+ hint_->SetFont((hint_font_name() + " " + std::to_string(hint_font_size())).c_str());
+}
+
void TextInput::OnFontChanged(GtkSettings* settings, GParamSpec* pspec)
{
glib::String font_name;
PangoFontDescription* desc;
- std::ostringstream font_desc;
g_object_get(settings, "gtk-font-name", &font_name, NULL);
@@ -112,20 +132,19 @@ void TextInput::OnFontChanged(GtkSettings* settings, GParamSpec* pspec)
pango_entry_->SetFontSize(PANGO_ENTRY_FONT_SIZE);
pango_entry_->SetFontOptions(gdk_screen_get_font_options(gdk_screen_get_default()));
- font_desc << pango_font_description_get_family(desc) << " " << HINT_LABEL_FONT_STYLE << " " << HINT_LABEL_FONT_SIZE;
- hint_->SetFont(font_desc.str().c_str());
-
- font_desc.str("");
- font_desc.clear();
-
- pango_font_description_free(desc);
+ if (hint_font_name() == HINT_LABEL_DEFAULT_FONT_NAME)
+ {
+ std::ostringstream font_desc;
+ font_desc << pango_font_description_get_family(desc) << " " << hint_font_size();
+ hint_->SetFont(font_desc.str().c_str());
+ pango_font_description_free(desc);
+ }
}
}
void TextInput::OnInputHintChanged()
{
- glib::String tmp(g_markup_escape_text(input_hint().c_str(), -1));
- hint_->SetText(tmp);
+ hint_->SetText(input_hint().c_str(), true);
}
void TextInput::Draw(nux::GraphicsEngine& GfxContext, bool force_draw)
@@ -184,14 +203,10 @@ void TextInput::UpdateBackground(bool force)
{
int RADIUS = 5;
nux::Geometry geo(GetGeometry());
- geo.width = layered_layout_->GetAbsoluteX() +
- layered_layout_->GetAbsoluteWidth() -
- GetAbsoluteX() +
- TEXT_INPUT_RIGHT_BORDER;
LOG_DEBUG(logger) << "height: "
<< geo.height << " - "
- << layered_layout_->GetGeometry().height << " - "
+ << layout_->GetGeometry().height << " - "
<< pango_entry_->GetGeometry().height;
if (geo.width == last_width_
@@ -250,7 +265,7 @@ void TextInput::OnEndKeyFocus()
}
-nux::TextEntry* TextInput::text_entry() const
+IMTextEntry* TextInput::text_entry() const
{
return pango_entry_;
}
diff --git a/unity-shared/TextInput.h b/unity-shared/TextInput.h
index 48c0b9018..462474d6e 100644
--- a/unity-shared/TextInput.h
+++ b/unity-shared/TextInput.h
@@ -39,6 +39,7 @@
#include "unity-shared/IconTexture.h"
#include "unity-shared/IMTextEntry.h"
#include "unity-shared/Introspectable.h"
+#include "unity-shared/SearchBarSpinner.h"
#include "unity-shared/StaticCairoText.h"
namespace nux
@@ -49,6 +50,7 @@ class LinearLayout;
namespace unity
{
+
class TextInput : public unity::debug::Introspectable, public nux::View
{
NUX_DECLARE_OBJECT_TYPE(TextInput, nux::View);
@@ -56,18 +58,22 @@ class TextInput : public unity::debug::Introspectable, public nux::View
public:
typedef nux::ObjectPtr<TextInput> Ptr;
TextInput(NUX_FILE_LINE_PROTO);
- TextInput(bool show_filter_hint, NUX_FILE_LINE_PROTO);
- nux::TextEntry* text_entry() const;
+ void SetSpinnerVisible(bool visible);
+ void SetSpinnerState(SpinnerState spinner_state);
+
+ IMTextEntry* text_entry() const;
nux::RWProperty<std::string> input_string;
nux::Property<std::string> input_hint;
+ nux::Property<std::string> hint_font_name;
+ nux::Property<int> hint_font_size;
nux::ROProperty<bool> im_active;
nux::ROProperty<bool> im_preedit;
private:
-
void OnFontChanged(GtkSettings* settings, GParamSpec* pspec=NULL);
+ void UpdateHintFont();
void Draw(nux::GraphicsEngine& GfxContext, bool force_draw);
void DrawContent(nux::GraphicsEngine& GfxContext, bool force_draw);
void UpdateBackground(bool force);
@@ -78,11 +84,8 @@ private:
bool AcceptKeyNavFocus();
protected:
-
- void Init();
void OnInputHintChanged();
- void OnMouseButtonDown(int x, int y, unsigned long button_flags,
- unsigned long key_flags);
+ void OnMouseButtonDown(int x, int y, unsigned long button_flags, unsigned long key_flags);
void OnEndKeyFocus();
// getters & setters
@@ -104,6 +107,7 @@ private:
std::unique_ptr<nux::AbstractPaintLayer> highlight_layer_;
nux::HLayout* layout_;
nux::LayeredLayout* layered_layout_;
+ SearchBarSpinner* spinner_;
int last_width_;
int last_height_;
diff --git a/unity-shared/UScreen.cpp b/unity-shared/UScreen.cpp
index 0de6dff4f..4a2ad6701 100644
--- a/unity-shared/UScreen.cpp
+++ b/unity-shared/UScreen.cpp
@@ -98,16 +98,16 @@ nux::Geometry UScreen::GetScreenGeometry() const
const std::string UScreen::GetMonitorName(int output_number = 0) const
{
- if (output_number < 0 || output_number > gdk_screen_get_n_monitors(screen_))
+ if (output_number < 0 || output_number >= gdk_screen_get_n_monitors(screen_))
{
- LOG_ERROR(logger) << "UScreen::GetMonitorName: Invalid monitor number" << output_number;
+ LOG_WARN(logger) << "UScreen::GetMonitorName: Invalid monitor number" << output_number;
return "";
}
glib::String output_name(gdk_screen_get_monitor_plug_name(screen_, output_number));
if (!output_name)
{
- LOG_ERROR(logger) << "UScreen::GetMonitorName: Failed to get monitor name for monitor" << output_number;
+ LOG_WARN(logger) << "UScreen::GetMonitorName: Failed to get monitor name for monitor" << output_number;
return "";
}
diff --git a/unity-shared/UnityWindowView.cpp b/unity-shared/UnityWindowView.cpp
index 0ddf5cd07..61124578f 100644
--- a/unity-shared/UnityWindowView.cpp
+++ b/unity-shared/UnityWindowView.cpp
@@ -245,7 +245,7 @@ void UnityWindowView::Draw(nux::GraphicsEngine& GfxContext, bool force_draw)
auto temp_background_color = background_color();
auto blend_mode = nux::LAYER_BLEND_MODE_OVERLAY;
- if (Settings::Instance().GetLowGfxMode())
+ if (Settings::Instance().GetLowGfxMode() || BackgroundEffectHelper::blur_type == BLUR_NONE)
{
temp_background_color.alpha = 1.0f;
blend_mode = nux::LAYER_BLEND_MODE_NORMAL;
diff --git a/unity-shared/UpstartWrapper.cpp b/unity-shared/UpstartWrapper.cpp
new file mode 100644
index 000000000..eda82399c
--- /dev/null
+++ b/unity-shared/UpstartWrapper.cpp
@@ -0,0 +1,74 @@
+// -*- 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 "UpstartWrapper.h"
+
+#include <UnityCore/GLibDBusProxy.h>
+
+namespace unity
+{
+
+//
+// Start private implementation
+//
+
+class UpstartWrapper::Impl
+{
+public:
+ Impl(bool test_mode = false);
+
+ void Emit(std::string const& name);
+
+private:
+ glib::DBusProxy::Ptr upstart_proxy_;
+};
+
+UpstartWrapper::Impl::Impl(bool test_mode)
+{
+ upstart_proxy_ = std::make_shared<unity::glib::DBusProxy>(test_mode ? "com.canonical.Unity.Test.Upstart" : "com.ubuntu.Upstart",
+ "/com/ubuntu/Upstart",
+ "com.ubuntu.Upstart0_6");
+}
+
+void UpstartWrapper::Impl::Emit(std::string const& name)
+{
+ upstart_proxy_->Call("EmitEvent", g_variant_new("(sasb)", name.c_str(), nullptr, 0));
+}
+
+//
+// End private implementation
+//
+
+UpstartWrapper::UpstartWrapper()
+ : pimpl_(new Impl)
+{}
+
+UpstartWrapper::UpstartWrapper(UpstartWrapper::TestMode const& tm)
+ : pimpl_(new Impl(true))
+{}
+
+UpstartWrapper::~UpstartWrapper()
+{}
+
+void UpstartWrapper::Emit(std::string const& name)
+{
+ pimpl_->Emit(name);
+}
+
+}
diff --git a/unity-shared/UpstartWrapper.h b/unity-shared/UpstartWrapper.h
new file mode 100644
index 000000000..3be88d9cb
--- /dev/null
+++ b/unity-shared/UpstartWrapper.h
@@ -0,0 +1,53 @@
+// -*- 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 UNITY_UPSTART_WRAPPER
+#define UNITY_UPSTART_WRAPPER
+
+#include <memory>
+
+namespace unity
+{
+
+class UpstartWrapper
+{
+public:
+ typedef std::shared_ptr<UpstartWrapper> Ptr;
+
+ UpstartWrapper();
+ ~UpstartWrapper();
+
+ void Emit(std::string const& name);
+
+protected:
+ struct TestMode {};
+ UpstartWrapper(TestMode const&);
+
+private:
+ // Noncopyable
+ UpstartWrapper(UpstartWrapper const&) = delete;
+ UpstartWrapper& operator=(UpstartWrapper const&) = delete;
+
+ class Impl;
+ std::unique_ptr<Impl> pimpl_;
+};
+
+}
+
+#endif
diff --git a/unity-shared/WindowManager.h b/unity-shared/WindowManager.h
index 330b9be86..0da719399 100644
--- a/unity-shared/WindowManager.h
+++ b/unity-shared/WindowManager.h
@@ -166,6 +166,7 @@ public:
// Nux Modifiers, Nux Keycode (= X11 KeySym)
nux::Property<std::pair<unsigned, unsigned>> close_window_key;
+ nux::Property<std::pair<unsigned, unsigned>> activate_indicators_key;
nux::Property<nux::Color> average_color;
// Signals