Merge lp:~3v1n0/unity/lockscreen-review into lp:unity

Proposed by Marco Trevisan (Treviño)
Status: Merged
Merged at revision: 3703
Proposed branch: lp:~3v1n0/unity/lockscreen-review
Merge into: lp:unity
Prerequisite: lp:~azzar1/unity/lockscreen
Diff against target: 1793 lines (+533/-291)
32 files modified
UnityCore/DBusIndicators.cpp (+2/-2)
UnityCore/GnomeSessionManager.cpp (+12/-7)
UnityCore/GnomeSessionManager.h (+1/-0)
UnityCore/SessionManager.h (+2/-1)
debian/control (+1/-5)
lockscreen/BackgroundSettings.cpp (+78/-41)
lockscreen/BackgroundSettings.h (+8/-8)
lockscreen/LockScreenAbstractShield.h (+55/-0)
lockscreen/LockScreenController.cpp (+91/-57)
lockscreen/LockScreenController.h (+10/-6)
lockscreen/LockScreenShield.cpp (+81/-25)
lockscreen/LockScreenShield.h (+11/-16)
lockscreen/LockScreenShieldFactory.cpp (+2/-5)
lockscreen/LockScreenShieldFactory.h (+4/-8)
lockscreen/UserAuthenticator.h (+6/-6)
lockscreen/UserAuthenticatorPam.cpp (+14/-12)
lockscreen/UserAuthenticatorPam.h (+1/-2)
lockscreen/UserPromptView.cpp (+67/-33)
lockscreen/UserPromptView.h (+3/-3)
lockscreen/pch/lockscreen_pch.hh (+6/-2)
plugins/unityshell/src/unityshell.cpp (+10/-1)
plugins/unityshell/unityshell.xml.in (+1/-1)
po/POTFILES.in (+1/-0)
services/panel-main.c (+2/-2)
tests/data/external.gschema.xml (+18/-0)
tests/test_lockscreen_controller.cpp (+10/-7)
tests/test_text_input.cpp (+0/-2)
unity-shared/IMTextEntry.cpp (+3/-2)
unity-shared/IMTextEntry.h (+1/-4)
unity-shared/TextInput.cpp (+25/-24)
unity-shared/TextInput.h (+4/-6)
unity-shared/UScreen.cpp (+3/-3)
To merge this branch: bzr merge lp:~3v1n0/unity/lockscreen-review
Reviewer Review Type Date Requested Status
Andrea Azzarone (community) Needs Fixing
Brandon Schaefer (community) Approve
PS Jenkins bot (community) continuous-integration Needs Fixing
Review via email: mp+209796@code.launchpad.net

Commit message

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

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Brandon Schaefer (brandontschaefer) wrote :

Code looks good to me, and unit tests are passing :)

review: Approve
Revision history for this message
Andrea Azzarone (azzar1) wrote :

1070 - auto* tmp_response = static_cast<pam_response*>(malloc(num_msg * sizeof(pam_response)));
1071 + auto* tmp_response = g_new0(pam_response, num_msg);

Please revert. Pam specs says that you need to can use just malloc. I know that internall g_new0 uses it but we don't know in future.

review: Needs Fixing

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'UnityCore/DBusIndicators.cpp'
2--- UnityCore/DBusIndicators.cpp 2014-03-06 21:47:27 +0000
3+++ UnityCore/DBusIndicators.cpp 2014-03-06 21:47:28 +0000
4@@ -36,8 +36,8 @@
5
6 namespace
7 {
8-const std::string SERVICE_NAME_DESKTOP("com.canonical.Unity.Panel.ServiceDesktop");
9-const std::string SERVICE_NAME_LOCKSCREEN("com.canonical.Unity.Panel.ServiceLockscreen");
10+const std::string SERVICE_NAME_DESKTOP("com.canonical.Unity.Panel.Service.Desktop");
11+const std::string SERVICE_NAME_LOCKSCREEN("com.canonical.Unity.Panel.Service.LockScreen");
12 const std::string SERVICE_PATH("/com/canonical/Unity/Panel/Service");
13 const std::string SERVICE_IFACE("com.canonical.Unity.Panel.Service");
14 } // anonymous namespace
15
16=== modified file 'UnityCore/GnomeSessionManager.cpp'
17--- UnityCore/GnomeSessionManager.cpp 2014-03-06 21:47:27 +0000
18+++ UnityCore/GnomeSessionManager.cpp 2014-03-06 21:47:28 +0000
19@@ -89,10 +89,9 @@
20
21 {
22 const char* session_id = test_mode_ ? "id0" : g_getenv("XDG_SESSION_ID");
23- session_id = session_id ? session_id : "";
24
25 login_proxy_ = std::make_shared<glib::DBusProxy>(test_mode_ ? testing::DBUS_NAME : "org.freedesktop.login1",
26- std::string("/org/freedesktop/login1/session/") + session_id,
27+ "/org/freedesktop/login1/session/" + glib::gchar_to_string(session_id),
28 "org.freedesktop.login1.Session",
29 test_mode_ ? G_BUS_TYPE_SESSION : G_BUS_TYPE_SYSTEM);
30
31@@ -394,9 +393,7 @@
32
33 std::string GnomeManager::RealName() const
34 {
35- const char* name = g_get_real_name();
36-
37- std::string real_name(name ? name : "");
38+ std::string real_name = glib::gchar_to_string(g_get_real_name());
39
40 if (real_name == "Unknown")
41 real_name.clear();
42@@ -406,9 +403,12 @@
43
44 std::string GnomeManager::UserName() const
45 {
46- const char* name = g_get_user_name();
47+ return glib::gchar_to_string(g_get_user_name());
48+}
49
50- return name ? name : "";
51+std::string GnomeManager::HostName() const
52+{
53+ return glib::gchar_to_string(g_get_host_name());
54 }
55
56 void GnomeManager::LockScreen()
57@@ -416,6 +416,11 @@
58 impl_->EnsureCancelPendingAction();
59
60 // FIXME (andy) we should ask gnome-session to emit the logind signal
61+ if (UserName().find("guest-") == 0)
62+ {
63+ LOG_INFO(logger) << "Impossible to lock a guest session";
64+ return;
65+ }
66 lock_requested.emit();
67 }
68
69
70=== modified file 'UnityCore/GnomeSessionManager.h'
71--- UnityCore/GnomeSessionManager.h 2013-03-05 20:21:29 +0000
72+++ UnityCore/GnomeSessionManager.h 2014-03-06 21:47:28 +0000
73@@ -35,6 +35,7 @@
74
75 std::string RealName() const;
76 std::string UserName() const;
77+ std::string HostName() const;
78
79 void LockScreen();
80 void Logout();
81
82=== modified file 'UnityCore/SessionManager.h'
83--- UnityCore/SessionManager.h 2014-03-06 21:47:27 +0000
84+++ UnityCore/SessionManager.h 2014-03-06 21:47:28 +0000
85@@ -38,6 +38,7 @@
86
87 virtual std::string RealName() const = 0;
88 virtual std::string UserName() const = 0;
89+ virtual std::string HostName() const = 0;
90
91 virtual void LockScreen() = 0;
92 virtual void Logout() = 0;
93@@ -56,9 +57,9 @@
94 Manager(const Manager&) = delete;
95 Manager& operator=(const Manager&) = delete;
96
97- sigc::signal<void, bool /* inhibitors */> logout_requested;
98 sigc::signal<void> lock_requested;
99 sigc::signal<void> unlock_requested;
100+ sigc::signal<void, bool /* inhibitors */> logout_requested;
101 sigc::signal<void, bool /* inhibitors */> reboot_requested;
102 sigc::signal<void, bool /* inhibitors */> shutdown_requested;
103
104
105=== modified file 'debian/control'
106--- debian/control 2014-03-06 21:47:27 +0000
107+++ debian/control 2014-03-06 21:47:28 +0000
108@@ -9,17 +9,14 @@
109 dh-migrations,
110 dh-translations (>= 94),
111 google-mock (>= 1.6.0+svn437),
112- google-mock,
113 gsettings-desktop-schemas-dev,
114 gsettings-ubuntu-schemas (>= 0.0.1+14.04.20140219),
115 intltool (>= 0.35.0),
116 libatk1.0-dev,
117 libbamf3-dev (>= 0.5.0+13.10.20130731),
118 libboost-dev,
119- libboost-serialization-dev,
120 libcairo2-dev,
121 libdbus-1-dev,
122- libcompizconfig0-dev (>= 1:0.9.11),
123 libdbusmenu-glib-dev (>= 0.3.91),
124 libdee-dev (>= 1.2.6),
125 libgee-dev (>= 0.5.0),
126@@ -27,7 +24,6 @@
127 libgl1-mesa-dri,
128 libglib2.0-dev (>= 2.39.1),
129 libgnome-desktop-3-dev,
130- libgrail-dev (>= 1.0.20),
131 libgtest-dev,
132 libgtk-3-dev (>= 3.1),
133 libido3-0.1-dev (>= 13.10.0),
134@@ -46,7 +42,6 @@
135 libunique-dev,
136 libunity-dev (>= 7.1.0),
137 libunity-misc-dev (>= 4.0.4),
138- libunity-scopes-json-def-desktop,
139 libupstart-dev,
140 libxcb-icccm4-dev,
141 libxfixes-dev (>= 1:5.0.1-1),
142@@ -79,6 +74,7 @@
143 nux-tools,
144 dconf-cli,
145 unity-asset-pool (>= 0.8.18),
146+ unity-greeter,
147 bamfdaemon,
148 libxfixes3 (>= 1:5.0.1-1),
149 libxi6 (>= 2:1.7.1.901),
150
151=== modified file 'lockscreen/BackgroundSettings.cpp'
152--- lockscreen/BackgroundSettings.cpp 2014-03-06 21:47:27 +0000
153+++ lockscreen/BackgroundSettings.cpp 2014-03-06 21:47:28 +0000
154@@ -17,22 +17,31 @@
155 * Authored by: Andrea Azzarone <andrea.azzarone@canonical.com>
156 */
157
158+#include <Nux/Nux.h>
159 #include "BackgroundSettings.h"
160
161 #include <libgnome-desktop/gnome-bg.h>
162
163 #include "LockScreenSettings.h"
164-#include "unity-shared/GtkTexture.h"
165+#include "unity-shared/CairoTexture.h"
166 #include "unity-shared/PanelStyle.h"
167 #include "unity-shared/UScreen.h"
168
169-namespace unity
170+namespace unity
171 {
172 namespace lockscreen
173 {
174 namespace
175 {
176 const std::string SETTINGS_NAME = "org.gnome.desktop.background";
177+const std::string GREETER_SETTINGS = "com.canonical.unity-greeter";
178+const std::string LOGO_KEY = "logo";
179+const std::string BACKGROUND_KEY = "background";
180+const std::string BACKGROUND_COLOR_KEY = "background-color";
181+const std::string USER_BG_KEY = "draw-user-backgrounds";
182+const std::string DRAW_GRID_KEY = "draw-grid";
183+
184+constexpr int GetGridOffset(int size) { return (size % Settings::GRID_SIZE) / 2; }
185 }
186
187 BackgroundSettings::BackgroundSettings()
188@@ -45,32 +54,72 @@
189 BackgroundSettings::~BackgroundSettings()
190 {}
191
192-BaseTexturePtr BackgroundSettings::GetBackgroundTexture(int monitor,
193- bool draw_grid,
194- bool draw_logo)
195+BaseTexturePtr BackgroundSettings::GetBackgroundTexture(int monitor)
196 {
197- nux::Geometry geo = UScreen::GetDefault()->GetMonitorGeometry(monitor);
198-
199- cairo_surface_t* cairo_surface = gnome_bg_create_surface(gnome_bg_, gdk_get_default_root_window(),
200- geo.width, geo.height, FALSE);
201- cairo_t* c = cairo_create(cairo_surface);
202-
203- if (draw_logo)
204- {
205+ nux::Geometry const& geo = UScreen::GetDefault()->GetMonitorGeometry(monitor);
206+ glib::Object<GSettings> greeter_settings(g_settings_new(GREETER_SETTINGS.c_str()));
207+ bool user_bg = g_settings_get_boolean(greeter_settings, USER_BG_KEY.c_str()) != FALSE;
208+ bool draw_grid = g_settings_get_boolean(greeter_settings, DRAW_GRID_KEY.c_str()) != FALSE;
209+
210+ nux::CairoGraphics cairo_graphics(CAIRO_FORMAT_ARGB32, geo.width, geo.height);
211+ cairo_t* c = cairo_graphics.GetInternalContext();
212+
213+ cairo_surface_t* bg_surface = nullptr;
214+
215+ if (user_bg)
216+ {
217+ bg_surface = gnome_bg_create_surface(gnome_bg_, gdk_get_default_root_window(), geo.width, geo.height, FALSE);
218+ }
219+ else
220+ {
221+ glib::String bg_file(g_settings_get_string(greeter_settings, BACKGROUND_KEY.c_str()));
222+
223+ if (bg_file)
224+ {
225+ glib::Object<GdkPixbuf> pixbuf(gdk_pixbuf_new_from_file_at_scale(bg_file, geo.width, geo.height, FALSE, NULL));
226+
227+ if (pixbuf)
228+ bg_surface = gdk_cairo_surface_create_from_pixbuf(pixbuf, 0, NULL);
229+ }
230+ }
231+
232+ if (bg_surface)
233+ {
234+ cairo_set_source_surface(c, bg_surface, 0, 0);
235+ cairo_paint(c);
236+ cairo_surface_destroy(bg_surface);
237+ }
238+ else
239+ {
240+ nux::Color bg_color(glib::String(g_settings_get_string(greeter_settings, BACKGROUND_COLOR_KEY.c_str())).Str());
241+ cairo_set_source_rgb(c, bg_color.red, bg_color.green, bg_color.blue);
242+ cairo_paint(c);
243+ }
244+
245+ {
246+ glib::String logo(g_settings_get_string(greeter_settings, LOGO_KEY.c_str()));
247 int grid_x_offset = GetGridOffset(geo.width);
248- int grid_y_offset = GetGridOffset(geo.height) + panel::Style::Instance().PanelHeight(monitor);
249-
250- cairo_save(c);
251-
252- int height = 43;
253- int x = grid_x_offset;
254- int y = grid_y_offset + Settings::GRID_SIZE * (geo.height / Settings::GRID_SIZE - 1) - height;
255- cairo_translate (c, x, y);
256-
257- cairo_surface_t* logo_surface = cairo_image_surface_create_from_png ("/usr/share/unity-greeter/logo.png");
258- cairo_set_source_surface(c, logo_surface, 0, 0);
259- cairo_paint_with_alpha(c, 0.5);
260- cairo_restore(c);
261+ int grid_y_offset = GetGridOffset(geo.height);
262+
263+ if (logo && !logo.Str().empty())
264+ {
265+ cairo_surface_t* logo_surface = cairo_image_surface_create_from_png(logo);
266+
267+ if (logo_surface)
268+ {
269+ int height = cairo_image_surface_get_height(logo_surface);
270+ int x = grid_x_offset;
271+ int y = grid_y_offset + Settings::GRID_SIZE * (geo.height / Settings::GRID_SIZE - 1) - height;
272+
273+ cairo_save(c);
274+ cairo_translate(c, x, y);
275+
276+ cairo_set_source_surface(c, logo_surface, 0, 0);
277+ cairo_paint_with_alpha(c, 0.5);
278+ cairo_surface_destroy(logo_surface);
279+ cairo_restore(c);
280+ }
281+ }
282 }
283
284 if (draw_grid)
285@@ -78,10 +127,10 @@
286 int width = geo.width;
287 int height = geo.height;
288 int grid_x_offset = GetGridOffset(width);
289- int grid_y_offset = GetGridOffset(height) + panel::Style::Instance().PanelHeight(monitor);
290+ int grid_y_offset = GetGridOffset(height);
291
292 // overlay grid
293- cairo_surface_t* overlay_surface = cairo_surface_create_similar(cairo_surface,
294+ cairo_surface_t* overlay_surface = cairo_surface_create_similar(cairo_graphics.GetSurface(),
295 CAIRO_CONTENT_COLOR_ALPHA,
296 Settings::GRID_SIZE,
297 Settings::GRID_SIZE);
298@@ -114,19 +163,7 @@
299 cairo_destroy(oc);
300 }
301
302- GdkPixbuf* gdk_pixbuf = gdk_pixbuf_get_from_surface(cairo_surface,
303- 0, 0,
304- geo.width, geo.height);
305-
306- cairo_destroy(c);
307- cairo_surface_destroy(cairo_surface);
308-
309- return texture_ptr_from_gdk_graphics(nux::GdkGraphics(gdk_pixbuf));
310-}
311-
312-int BackgroundSettings::GetGridOffset(int size)
313-{
314- return (size % Settings::GRID_SIZE) / 2;
315+ return texture_ptr_from_cairo_graphics(cairo_graphics);
316 }
317
318 } // lockscreen
319
320=== modified file 'lockscreen/BackgroundSettings.h'
321--- lockscreen/BackgroundSettings.h 2014-03-06 21:47:27 +0000
322+++ lockscreen/BackgroundSettings.h 2014-03-06 21:47:28 +0000
323@@ -20,14 +20,18 @@
324 #ifndef UNITY_BACKGROUND_SETTINGS_H
325 #define UNITY_BACKGROUND_SETTINGS_H
326
327-#include <Nux/Nux.h>
328+#include <NuxCore/ObjectPtr.h>
329 #include <UnityCore/GLibWrapper.h>
330
331+namespace nux
332+{
333+class BaseTexture;
334+}
335+
336 class _GnomeBG;
337
338-namespace unity
339+namespace unity
340 {
341-
342 typedef nux::ObjectPtr<nux::BaseTexture> BaseTexturePtr;
343
344 namespace lockscreen
345@@ -39,13 +43,9 @@
346 BackgroundSettings();
347 ~BackgroundSettings();
348
349- BaseTexturePtr GetBackgroundTexture(int monitor,
350- bool draw_grid,
351- bool draw_logo);
352+ BaseTexturePtr GetBackgroundTexture(int monitor);
353
354 private:
355- static int GetGridOffset(int size);
356-
357 glib::Object<_GnomeBG> gnome_bg_;
358 };
359
360
361=== added file 'lockscreen/LockScreenAbstractShield.h'
362--- lockscreen/LockScreenAbstractShield.h 1970-01-01 00:00:00 +0000
363+++ lockscreen/LockScreenAbstractShield.h 2014-03-06 21:47:28 +0000
364@@ -0,0 +1,55 @@
365+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
366+/*
367+ * Copyright (C) 2014 Canonical Ltd
368+ *
369+ * This program is free software: you can redistribute it and/or modify
370+ * it under the terms of the GNU General Public License version 3 as
371+ * published by the Free Software Foundation.
372+ *
373+ * This program is distributed in the hope that it will be useful,
374+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
375+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
376+ * GNU General Public License for more details.
377+ *
378+ * You should have received a copy of the GNU General Public License
379+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
380+ *
381+ * Authored by: Marco Trevisan <marco.trevisan@canonical.com>
382+ */
383+
384+#ifndef UNITY_LOCKSCREEN_ABSTRACT_SHIELD_H
385+#define UNITY_LOCKSCREEN_ABSTRACT_SHIELD_H
386+
387+#include <NuxCore/Property.h>
388+#include <UnityCore/SessionManager.h>
389+
390+#include "unity-shared/MockableBaseWindow.h"
391+
392+namespace unity
393+{
394+namespace lockscreen
395+{
396+
397+class AbstractShield : public MockableBaseWindow
398+{
399+public:
400+ AbstractShield(session::Manager::Ptr const& session, int monitor_num, bool is_primary)
401+ : MockableBaseWindow("Unity Lockscreen")
402+ , primary(is_primary)
403+ , monitor(monitor_num)
404+ , session_manager_(session)
405+ {}
406+
407+ nux::Property<bool> primary;
408+ nux::Property<int> monitor;
409+
410+ sigc::signal<void, int, int> grab_motion;
411+
412+protected:
413+ session::Manager::Ptr session_manager_;
414+};
415+
416+} // lockscreen
417+} // unity
418+
419+#endif // UNITY_LOCKSCREEN_ABSTRACT_SHIELD_H
420
421=== modified file 'lockscreen/LockScreenController.cpp'
422--- lockscreen/LockScreenController.cpp 2014-03-06 21:47:27 +0000
423+++ lockscreen/LockScreenController.cpp 2014-03-06 21:47:28 +0000
424@@ -19,6 +19,7 @@
425
426 #include "LockScreenController.h"
427
428+#include "LockScreenShield.h"
429 #include "LockScreenSettings.h"
430 #include "unity-shared/AnimationUtils.h"
431 #include "unity-shared/UScreen.h"
432@@ -48,10 +49,12 @@
433 , fade_animator_(FADE_DURATION)
434 , test_mode_(test_mode)
435 {
436- auto* uscreen = UScreen::GetDefault();
437- uscreen->changed.connect(sigc::mem_fun(this, &Controller::OnUScreenChanged));
438+ uscreen_connection_ = UScreen::GetDefault()->changed.connect([this] (int, std::vector<nux::Geometry> const& monitors) {
439+ EnsureShields(monitors);
440+ });
441+ uscreen_connection_->block();
442
443- session_manager_->lock_requested.connect(sigc::mem_fun(this,&Controller::OnLockRequested));
444+ session_manager_->lock_requested.connect(sigc::mem_fun(this, &Controller::OnLockRequested));
445 session_manager_->unlock_requested.connect(sigc::mem_fun(this, &Controller::OnUnlockRequested));
446
447 fade_animator_.updated.connect([this](double value) {
448@@ -60,32 +63,78 @@
449 });
450 });
451
452- fade_animator_.finished.connect([this]() {
453- if (fade_animator_.GetCurrentValue() == 0.0f)
454+ fade_animator_.finished.connect([this] {
455+ if (animation::GetDirection(fade_animator_) == animation::Direction::BACKWARD)
456+ {
457+ motion_connection_->disconnect();
458+ uscreen_connection_->block();
459 shields_.clear();
460+
461+ if (Settings::Instance().lockscreen_type() == Type::UNITY)
462+ upstart_wrapper_->Emit("desktop-unlock");
463+ }
464 });
465 }
466
467-void Controller::OnUScreenChanged(int primary, std::vector<nux::Geometry> const& monitors)
468+void Controller::OnPrimaryShieldMotion(int x, int y)
469 {
470- if (IsLocked())
471- EnsureShields(primary, monitors);
472+ if (!primary_shield_->GetAbsoluteGeometry().IsPointInside(x, y))
473+ {
474+ for (auto const& shield : shields_)
475+ {
476+ if (!shield->GetAbsoluteGeometry().IsPointInside(x, y))
477+ continue;
478+
479+ primary_shield_->primary = false;
480+ primary_shield_ = shield;
481+ shield->primary = true;
482+ auto move_cb = sigc::mem_fun(this, &Controller::OnPrimaryShieldMotion);
483+ motion_connection_ = shield->grab_motion.connect(move_cb);
484+ break;
485+ }
486+ }
487 }
488
489-void Controller::EnsureShields(int primary, std::vector<nux::Geometry> const& monitors)
490+void Controller::EnsureShields(std::vector<nux::Geometry> const& monitors)
491 {
492 int num_monitors = monitors.size();
493 int shields_size = shields_.size();
494+ bool unity_mode = (Settings::Instance().lockscreen_type() == Type::UNITY);
495+ int primary = unity_mode ? UScreen::GetDefault()->GetMonitorWithMouse() : -1;
496+
497+ shields_.resize(num_monitors);
498
499 for (int i = 0; i < num_monitors; ++i)
500 {
501+ auto& shield = shields_[i];
502+ bool is_new = false;
503+
504 if (i >= shields_size)
505- shields_.push_back(shield_factory_->CreateShield(session_manager_, i, i == primary));
506-
507- shields_[i]->SetGeometry(monitors.at(i));
508- }
509-
510- shields_.resize(num_monitors);
511+ {
512+ shield = shield_factory_->CreateShield(session_manager_, i, i == primary);
513+ is_new = true;
514+ }
515+
516+ shield->SetGeometry(monitors[i]);
517+ shield->SetMinMaxSize(monitors[i].width, monitors[i].height);
518+ shield->primary = (i == primary);
519+ shield->monitor = i;
520+
521+ if (is_new && fade_animator_.GetCurrentValue() > 0)
522+ {
523+ shield->SetOpacity(fade_animator_.GetCurrentValue());
524+ shield->ShowWindow(true);
525+ shield->PushToFront();
526+ }
527+ }
528+
529+ if (unity_mode)
530+ {
531+ primary_shield_ = shields_[primary];
532+ primary_shield_->primary = true;
533+ auto move_cb = sigc::mem_fun(this, &Controller::OnPrimaryShieldMotion);
534+ motion_connection_ = primary_shield_->grab_motion.connect(move_cb);
535+ }
536 }
537
538 void Controller::OnLockRequested()
539@@ -93,8 +142,6 @@
540 if (IsLocked())
541 return;
542
543- upstart_wrapper_->Emit("desktop-lock");
544-
545 auto lockscreen_type = Settings::Instance().lockscreen_type();
546
547 if (lockscreen_type == Type::NONE)
548@@ -107,6 +154,7 @@
549 }
550 else if (lockscreen_type == Type::UNITY)
551 {
552+ upstart_wrapper_->Emit("desktop-lock");
553 LockScreenUsingUnity();
554 }
555 }
556@@ -115,7 +163,7 @@
557 {
558 // TODO (andy) Move to a different class (DisplayManagerWrapper)
559 const char* session_path = g_getenv("XDG_SESSION_PATH");
560-
561+
562 if (!session_path)
563 return;
564
565@@ -126,38 +174,31 @@
566
567 proxy->Call("Lock", nullptr, [proxy] (GVariant*) {});
568
569- ShowShields(/* interactive */ false, /* skip animation */ true);
570+ ShowShields();
571+ animation::Skip(fade_animator_);
572 }
573
574 void Controller::LockScreenUsingUnity()
575 {
576- ShowShields(/* interactive */ true, /* skip animation */ false);
577+ ShowShields();
578 }
579
580-void Controller::ShowShields(bool interactive, bool skip_animation)
581+void Controller::ShowShields()
582 {
583 old_blur_type_ = BackgroundEffectHelper::blur_type;
584 BackgroundEffectHelper::blur_type = BLUR_NONE;
585
586- WindowManager& wm = WindowManager::Default();
587- wm.SaveInputFocus();
588-
589- auto* uscreen = UScreen::GetDefault();
590- EnsureShields(interactive ? uscreen->GetPrimaryMonitor() : -1, uscreen->GetMonitors());
591-
592- std::for_each(shields_.begin(), shields_.end(), [skip_animation](nux::ObjectPtr<Shield> const& shield) {
593+ WindowManager::Default().SaveInputFocus();
594+ EnsureShields(UScreen::GetDefault()->GetMonitors());
595+ uscreen_connection_->unblock();
596+
597+ std::for_each(shields_.begin(), shields_.end(), [] (nux::ObjectPtr<Shield> const& shield) {
598+ shield->SetOpacity(0.0f);
599 shield->ShowWindow(true);
600- shield->SetOpacity(skip_animation ? 1.0 : 0.0);
601+ shield->PushToFront();
602 });
603
604- if (!interactive)
605- {
606- shields_.at(uscreen->GetPrimaryMonitor())->GrabPointer();
607- shields_.at(uscreen->GetPrimaryMonitor())->GrabKeyboard();
608- }
609-
610- if (!skip_animation)
611- animation::StartOrReverse(fade_animator_, animation::Direction::FORWARD);
612+ animation::StartOrReverse(fade_animator_, animation::Direction::FORWARD);
613 }
614
615 void Controller::OnUnlockRequested()
616@@ -165,38 +206,26 @@
617 if (!IsLocked())
618 return;
619
620- upstart_wrapper_->Emit("desktop-unlock");
621-
622 auto lockscreen_type = Settings::Instance().lockscreen_type();
623
624 if (lockscreen_type == Type::NONE)
625- {
626 return;
627- }
628- else if (lockscreen_type == Type::LIGHTDM)
629- {
630- HideShields(/* skip animation */ true);
631- }
632- else if (lockscreen_type == Type::UNITY)
633- {
634- HideShields(/* skip animation */ false);
635- }
636+
637+ HideShields();
638+
639+ if (lockscreen_type == Type::LIGHTDM)
640+ animation::Skip(fade_animator_);
641 }
642
643-void Controller::HideShields(bool skip_animation)
644+void Controller::HideShields()
645 {
646 std::for_each(shields_.begin(), shields_.end(), [](nux::ObjectPtr<Shield> const& shield) {
647 shield->UnGrabPointer();
648 shield->UnGrabKeyboard();
649 });
650
651- WindowManager& wm = WindowManager::Default();
652- wm.RestoreInputFocus();
653-
654- if (skip_animation)
655- shields_.clear();
656- else
657- animation::StartOrReverse(fade_animator_, animation::Direction::BACKWARD);
658+ WindowManager::Default().RestoreInputFocus();
659+ animation::StartOrReverse(fade_animator_, animation::Direction::BACKWARD);
660
661 BackgroundEffectHelper::blur_type = old_blur_type_;
662 }
663@@ -206,5 +235,10 @@
664 return !shields_.empty();
665 }
666
667+bool Controller::IsShielded() const
668+{
669+ return (fade_animator_.GetCurrentValue() == 1.0f && !shields_.empty());
670+}
671+
672 } // lockscreen
673 } // unity
674
675=== modified file 'lockscreen/LockScreenController.h'
676--- lockscreen/LockScreenController.h 2014-03-06 21:47:27 +0000
677+++ lockscreen/LockScreenController.h 2014-03-06 21:47:28 +0000
678@@ -21,8 +21,8 @@
679 #define UNITY_LOCKSCREEN_CONTROLLER_H
680
681 #include <NuxCore/Animation.h>
682+#include <UnityCore/ConnectionManager.h>
683
684-#include "LockScreenShield.h"
685 #include "LockScreenShieldFactory.h"
686 #include "unity-shared/BackgroundEffectHelper.h"
687 #include "unity-shared/UpstartWrapper.h"
688@@ -41,25 +41,29 @@
689 bool test_mode = false);
690
691 bool IsLocked() const;
692+ bool IsShielded() const;
693
694 private:
695 friend class TestLockScreenController;
696
697- void EnsureShields(int primary, std::vector<nux::Geometry> const& monitors);
698+ void EnsureShields(std::vector<nux::Geometry> const& monitors);
699 void LockScreenUsingDisplayManager();
700 void LockScreenUsingUnity();
701- void ShowShields(bool interactive, bool skip_animation);
702- void HideShields(bool skip_animation);
703+ void ShowShields();
704+ void HideShields();
705
706- void OnUScreenChanged(int primary, std::vector<nux::Geometry> const& monitors);
707 void OnLockRequested();
708 void OnUnlockRequested();
709+ void OnPrimaryShieldMotion(int x, int y);
710
711- std::vector<nux::ObjectPtr<Shield>> shields_;
712+ std::vector<nux::ObjectPtr<AbstractShield>> shields_;
713+ nux::ObjectWeakPtr<AbstractShield> primary_shield_;
714 session::Manager::Ptr session_manager_;
715 UpstartWrapper::Ptr upstart_wrapper_;
716 ShieldFactoryInterface::Ptr shield_factory_;
717 nux::animation::AnimateValue<double> fade_animator_;
718+ connection::Wrapper uscreen_connection_;
719+ connection::Wrapper motion_connection_;
720 bool test_mode_;
721 BlurType old_blur_type_;
722 };
723
724=== modified file 'lockscreen/LockScreenShield.cpp'
725--- lockscreen/LockScreenShield.cpp 2014-03-06 21:47:27 +0000
726+++ lockscreen/LockScreenShield.cpp 2014-03-06 21:47:28 +0000
727@@ -31,36 +31,59 @@
728 #include "panel/PanelView.h"
729 #include "unity-shared/GnomeKeyGrabber.h"
730 #include "unity-shared/PanelStyle.h"
731+#include "unity-shared/UScreen.h"
732
733 namespace unity
734 {
735 namespace lockscreen
736 {
737
738-Shield::Shield(session::Manager::Ptr const& session_manager, int monitor, bool is_primary)
739- : MockableBaseWindow("Lockscreen")
740- , primary(is_primary)
741- , session_manager_(session_manager)
742- , monitor_(monitor)
743+Shield::Shield(session::Manager::Ptr const& session_manager, int monitor_num, bool is_primary)
744+ : AbstractShield(session_manager, monitor_num, is_primary)
745 , bg_settings_(new BackgroundSettings)
746 , prompt_view_(nullptr)
747 {
748- SetLayout(new nux::VLayout());
749-
750 is_primary ? ShowPrimaryView() : ShowSecondaryView();
751
752 EnableInputWindow(true);
753
754- geometry_changed.connect([this](nux::Area*, nux::Geometry&) {
755+ geometry_changed.connect([this] (nux::Area*, nux::Geometry&) { UpdateBackgroundTexture();});
756+
757+ monitor.changed.connect([this] (int monitor) {
758+ if (primary() && panel_view_)
759+ panel_view_->SetMonitor(monitor);
760+
761 UpdateBackgroundTexture();
762 });
763+
764+ primary.changed.connect([this] (bool is_primary) {
765+ if (!is_primary)
766+ {
767+ UnGrabPointer();
768+ UnGrabKeyboard();
769+ }
770+
771+ is_primary ? ShowPrimaryView() : ShowSecondaryView();
772+ QueueRelayout();
773+ QueueDraw();
774+ });
775+
776+ mouse_move.connect([this] (int x, int y, int, int, unsigned long, unsigned long) {
777+ auto const& abs_geo = GetAbsoluteGeometry();
778+ grab_motion.emit(abs_geo.x + x, abs_geo.y + y);
779+ });
780 }
781
782 void Shield::UpdateBackgroundTexture()
783 {
784- auto background_texture = bg_settings_->GetBackgroundTexture(monitor_, true, true);
785- background_layer_.reset(new nux::TextureLayer(background_texture->GetDeviceTexture(), nux::TexCoordXForm(), nux::color::White, true));
786- SetBackgroundLayer(background_layer_.get());
787+ auto const& monitor_geo = UScreen::GetDefault()->GetMonitorGeometry(monitor);
788+
789+ if (!background_layer_ || monitor_geo != background_layer_->GetGeometry())
790+ {
791+ auto background_texture = bg_settings_->GetBackgroundTexture(monitor);
792+ background_layer_.reset(new nux::TextureLayer(background_texture->GetDeviceTexture(), nux::TexCoordXForm(), nux::color::White, true));
793+ SetBackgroundLayer(background_layer_.get());
794+ }
795 }
796
797 void Shield::ShowPrimaryView()
798@@ -68,7 +91,15 @@
799 GrabPointer();
800 GrabKeyboard();
801
802- nux::Layout* main_layout = GetLayout();
803+ if (primary_layout_)
804+ {
805+ SetLayout(primary_layout_.GetPointer());
806+ return;
807+ }
808+
809+ nux::Layout* main_layout = new nux::VLayout();
810+ primary_layout_ = main_layout;
811+ SetLayout(primary_layout_.GetPointer());
812
813 main_layout->AddView(CreatePanel());
814
815@@ -86,7 +117,15 @@
816
817 void Shield::ShowSecondaryView()
818 {
819- nux::Layout* main_layout = GetLayout();
820+ if (cof_layout_)
821+ {
822+ SetLayout(cof_layout_.GetPointer());
823+ return;
824+ }
825+
826+ nux::Layout* main_layout = new nux::VLayout();
827+ cof_layout_ = main_layout;
828+ SetLayout(cof_layout_.GetPointer());
829
830 // The circle of friends
831 CofView* cof_view = new CofView();
832@@ -104,9 +143,10 @@
833 indicators->on_entry_activated.connect(sigc::mem_fun(this, &Shield::OnIndicatorEntryActivated));
834
835 panel::PanelView* panel_view = new panel::PanelView(this, menu_manager, /*lockscreen_mode*/ true);
836- panel_view->SetMaximumHeight(panel::Style::Instance().PanelHeight(monitor_));
837+ panel_view->SetMaximumHeight(panel::Style::Instance().PanelHeight(monitor));
838 panel_view->SetOpacity(0.5);
839- panel_view->SetMonitor(monitor_);
840+ panel_view->SetMonitor(monitor);
841+ panel_view_ = panel_view;
842
843 return panel_view;
844 }
845@@ -127,27 +167,33 @@
846
847 void Shield::OnIndicatorEntryShowMenu(std::string const&, unsigned, int, int, unsigned)
848 {
849- UnGrabPointer();
850- UnGrabKeyboard();
851+ if (primary())
852+ {
853+ UnGrabPointer();
854+ UnGrabKeyboard();
855+ }
856 }
857
858 void Shield::OnIndicatorEntryActivated(std::string const& panel, std::string const& entry, nux::Geometry const& geo)
859 {
860- if (entry.empty() and geo.IsNull()) /* on menu closed */
861+ if (primary() && entry.empty() and geo.IsNull()) /* on menu closed */
862 {
863 GrabPointer();
864 GrabKeyboard();
865 }
866 }
867
868-nux::Area* Shield::FindKeyFocusArea(unsigned int,
869- unsigned long,
870- unsigned long)
871+nux::Area* Shield::FindKeyFocusArea(unsigned int, unsigned long, unsigned long)
872 {
873- if (prompt_view_ && prompt_view_->focus_view() && prompt_view_->focus_view()->GetInputEventSensitivity())
874- return prompt_view_->focus_view();
875- else
876- return nullptr;
877+ if (primary && prompt_view_)
878+ {
879+ auto* focus_view = prompt_view_->focus_view();
880+
881+ if (focus_view && focus_view->GetInputEventSensitivity())
882+ return focus_view;
883+ }
884+
885+ return nullptr;
886 }
887
888
889@@ -156,5 +202,15 @@
890 return false;
891 }
892
893+nux::Area* Shield::FindAreaUnderMouse(nux::Point const& mouse, nux::NuxEventType event_type)
894+{
895+ nux::Area* area = BaseWindow::FindAreaUnderMouse(mouse, event_type);
896+
897+ if (!area && primary)
898+ return this;
899+
900+ return area;
901+}
902+
903 }
904 }
905
906=== modified file 'lockscreen/LockScreenShield.h'
907--- lockscreen/LockScreenShield.h 2014-03-06 21:47:27 +0000
908+++ lockscreen/LockScreenShield.h 2014-03-06 21:47:28 +0000
909@@ -20,13 +20,14 @@
910 #ifndef UNITY_LOCKSCREEN_SHIELD_H
911 #define UNITY_LOCKSCREEN_SHIELD_H
912
913-#include <NuxCore/Property.h>
914-#include <UnityCore/SessionManager.h>
915-
916-#include "unity-shared/MockableBaseWindow.h"
917+#include "LockScreenAbstractShield.h"
918
919 namespace unity
920 {
921+namespace panel
922+{
923+class PanelView;
924+}
925 namespace lockscreen
926 {
927
928@@ -34,19 +35,14 @@
929 class UserAuthenticator;
930 class UserPromptView;
931
932-class Shield : public MockableBaseWindow
933+class Shield : public AbstractShield
934 {
935 public:
936 Shield(session::Manager::Ptr const& session_manager, int monitor, bool is_primary);
937
938- nux::Property<bool> primary;
939-
940- nux::Area* FindKeyFocusArea(unsigned int,
941- unsigned long,
942- unsigned long) override;
943-
944 bool AcceptKeyNavFocus() override;
945-
946+ nux::Area* FindKeyFocusArea(unsigned int, unsigned long, unsigned long) override;
947+ nux::Area* FindAreaUnderMouse(nux::Point const&, nux::NuxEventType) override;
948
949 private:
950 void UpdateBackgroundTexture();
951@@ -58,13 +54,12 @@
952 void OnIndicatorEntryShowMenu(std::string const&, unsigned, int, int, unsigned);
953 void OnIndicatorEntryActivated(std::string const& panel, std::string const& entry, nux::Geometry const& geo);
954
955-
956- session::Manager::Ptr session_manager_;
957- int monitor_;
958 std::shared_ptr<BackgroundSettings> bg_settings_;
959 std::unique_ptr<nux::AbstractPaintLayer> background_layer_;
960-
961+ nux::ObjectPtr<nux::Layout> primary_layout_;
962+ nux::ObjectPtr<nux::Layout> cof_layout_;
963 UserPromptView* prompt_view_;
964+ panel::PanelView* panel_view_;
965 };
966
967 }
968
969=== modified file 'lockscreen/LockScreenShieldFactory.cpp'
970--- lockscreen/LockScreenShieldFactory.cpp 2014-03-06 21:47:27 +0000
971+++ lockscreen/LockScreenShieldFactory.cpp 2014-03-06 21:47:28 +0000
972@@ -25,12 +25,9 @@
973 namespace lockscreen
974 {
975
976-nux::ObjectPtr<MockableBaseWindow> ShieldFactory::CreateShield(session::Manager::Ptr const& session_manager,
977- int monitor,
978- bool is_primary)
979+nux::ObjectPtr<AbstractShield> ShieldFactory::CreateShield(session::Manager::Ptr const& session_manager, int monitor, bool is_primary)
980 {
981- nux::ObjectPtr<Shield> shield(new Shield(session_manager, monitor, is_primary));
982- return shield;
983+ return nux::ObjectPtr<Shield>(new Shield(session_manager, monitor, is_primary));
984 }
985
986 }
987
988=== modified file 'lockscreen/LockScreenShieldFactory.h'
989--- lockscreen/LockScreenShieldFactory.h 2014-03-06 21:47:27 +0000
990+++ lockscreen/LockScreenShieldFactory.h 2014-03-06 21:47:28 +0000
991@@ -21,7 +21,7 @@
992 #define UNITY_LOCKSCREEN_SHIELD_FACTORY
993
994 #include <Nux/Nux.h>
995-#include <UnityCore/SessionManager.h>
996+#include "LockScreenAbstractShield.h"
997
998 namespace unity
999 {
1000@@ -35,18 +35,14 @@
1001 {
1002 typedef std::shared_ptr<ShieldFactoryInterface> Ptr;
1003
1004- virtual ~ShieldFactoryInterface() {};
1005+ virtual ~ShieldFactoryInterface() = default;
1006
1007- virtual nux::ObjectPtr<MockableBaseWindow> CreateShield(session::Manager::Ptr const& session_manager,
1008- int monitor,
1009- bool is_primary) = 0;
1010+ virtual nux::ObjectPtr<AbstractShield> CreateShield(session::Manager::Ptr const&, int monitor, bool is_primary) = 0;
1011 };
1012
1013 struct ShieldFactory : ShieldFactoryInterface
1014 {
1015- nux::ObjectPtr<MockableBaseWindow> CreateShield(session::Manager::Ptr const& session_manager,
1016- int monitor,
1017- bool is_primary) override;
1018+ nux::ObjectPtr<AbstractShield> CreateShield(session::Manager::Ptr const&, int monitor, bool is_primary) override;
1019 };
1020
1021 }
1022
1023=== modified file 'lockscreen/UserAuthenticator.h'
1024--- lockscreen/UserAuthenticator.h 2014-03-06 21:47:27 +0000
1025+++ lockscreen/UserAuthenticator.h 2014-03-06 21:47:28 +0000
1026@@ -31,20 +31,20 @@
1027 namespace lockscreen
1028 {
1029
1030+typedef std::shared_ptr<std::promise<std::string>> PromiseAuthCodePtr;
1031+
1032 class UserAuthenticator
1033 {
1034 public:
1035 typedef std::function<void(bool)> AuthenticateEndCallback;
1036
1037- virtual ~UserAuthenticator() {};
1038+ virtual ~UserAuthenticator() = default;
1039
1040 // Authenticate the user in a background thread.
1041- virtual bool AuthenticateStart(std::string const& username,
1042- AuthenticateEndCallback authenticate_cb) = 0;
1043+ virtual bool AuthenticateStart(std::string const& username, AuthenticateEndCallback const&) = 0;
1044
1045- // FIXME (andy) found a better name for the promise ptr.
1046- sigc::signal<void, std::string, std::shared_ptr<std::promise<std::string>> const&> echo_on_requested;
1047- sigc::signal<void, std::string, std::shared_ptr<std::promise<std::string>> const&> echo_off_requested;
1048+ sigc::signal<void, std::string, PromiseAuthCodePtr const&> echo_on_requested;
1049+ sigc::signal<void, std::string, PromiseAuthCodePtr const&> echo_off_requested;
1050 sigc::signal<void, std::string> message_requested;
1051 sigc::signal<void, std::string> error_requested;
1052 sigc::signal<void> clear_prompts;
1053
1054=== modified file 'lockscreen/UserAuthenticatorPam.cpp'
1055--- lockscreen/UserAuthenticatorPam.cpp 2014-03-06 21:47:27 +0000
1056+++ lockscreen/UserAuthenticatorPam.cpp 2014-03-06 21:47:28 +0000
1057@@ -33,7 +33,7 @@
1058 {
1059
1060 bool UserAuthenticatorPam::AuthenticateStart(std::string const& username,
1061- AuthenticateEndCallback authenticate_cb)
1062+ AuthenticateEndCallback const& authenticate_cb)
1063 {
1064 first_prompt_ = true;
1065 username_ = username;
1066@@ -77,21 +77,24 @@
1067 if (num_msg <= 0)
1068 return PAM_CONV_ERR;
1069
1070- auto* tmp_response = static_cast<pam_response*>(malloc(num_msg * sizeof(pam_response)));
1071+ auto* tmp_response = g_new0(pam_response, num_msg);
1072+
1073 if (!tmp_response)
1074 return PAM_CONV_ERR;
1075
1076 UserAuthenticatorPam* user_auth = static_cast<UserAuthenticatorPam*>(appdata_ptr);
1077
1078 if (!user_auth->first_prompt_)
1079+ {
1080 // Adding a timeout ensures that the signal is emitted in the main thread
1081- user_auth->source_manager_.AddTimeout(0, [&]() { user_auth->clear_prompts.emit(); return false; });
1082+ user_auth->source_manager_.AddTimeout(0, [user_auth] { user_auth->clear_prompts.emit(); return false; });
1083+ }
1084
1085 user_auth->first_prompt_ = false;
1086
1087 bool raise_error = false;
1088 int count;
1089- std::vector<std::shared_ptr<std::promise<std::string>>> promises;
1090+ std::vector<PromiseAuthCodePtr> promises;
1091
1092 for (count = 0; count < num_msg && !raise_error; ++count)
1093 {
1094@@ -104,7 +107,7 @@
1095
1096 // Adding a timeout ensures that the signal is emitted in the main thread
1097 std::string message(msg[count]->msg);
1098- user_auth->source_manager_.AddTimeout(0, [&, message, promise]() { user_auth->echo_on_requested.emit(message, promise); return false; });
1099+ user_auth->source_manager_.AddTimeout(0, [user_auth, message, promise] { user_auth->echo_on_requested.emit(message, promise); return false; });
1100 break;
1101 }
1102 case PAM_PROMPT_ECHO_OFF:
1103@@ -114,28 +117,28 @@
1104
1105 // Adding a timeout ensures that the signal is emitted in the main thread
1106 std::string message(msg[count]->msg);
1107- user_auth->source_manager_.AddTimeout(0, [&, message, promise]() { user_auth->echo_off_requested.emit(message, promise); return false; });
1108+ user_auth->source_manager_.AddTimeout(0, [user_auth, message, promise] { user_auth->echo_off_requested.emit(message, promise); return false; });
1109+ break;
1110 }
1111- break;
1112 case PAM_TEXT_INFO:
1113 {
1114 // Adding a timeout ensures that the signal is emitted in the main thread
1115 std::string message(msg[count]->msg);
1116- user_auth->source_manager_.AddTimeout(0, [&, message]() { user_auth->message_requested.emit(message); return false; });
1117+ user_auth->source_manager_.AddTimeout(0, [user_auth, message] { user_auth->message_requested.emit(message); return false; });
1118 break;
1119 }
1120 default:
1121 {
1122 // Adding a timeout ensures that the signal is emitted in the main thread
1123 std::string message(msg[count]->msg);
1124- user_auth->source_manager_.AddTimeout(0, [&, message]() { user_auth->error_requested.emit(message); return false; });
1125+ user_auth->source_manager_.AddTimeout(0, [user_auth, message] { user_auth->error_requested.emit(message); return false; });
1126 }
1127 }
1128 }
1129
1130 int i = 0;
1131
1132- for (auto promise : promises)
1133+ for (auto const& promise : promises)
1134 {
1135 auto future = promise->get_future();
1136 pam_response* resp_item = &tmp_response[i++];
1137@@ -152,8 +155,7 @@
1138 if (raise_error)
1139 {
1140 for (int i = 0; i < count; ++i)
1141- if (tmp_response[i].resp)
1142- free(tmp_response[i].resp);
1143+ free(tmp_response[i].resp);
1144
1145 free(tmp_response);
1146 return PAM_CONV_ERR;
1147
1148=== modified file 'lockscreen/UserAuthenticatorPam.h'
1149--- lockscreen/UserAuthenticatorPam.h 2014-03-06 21:47:27 +0000
1150+++ lockscreen/UserAuthenticatorPam.h 2014-03-06 21:47:28 +0000
1151@@ -39,8 +39,7 @@
1152 class UserAuthenticatorPam : public UserAuthenticator, private boost::noncopyable
1153 {
1154 public:
1155- bool AuthenticateStart(std::string const& username,
1156- AuthenticateEndCallback authenticate_cb) override;
1157+ bool AuthenticateStart(std::string const& username, AuthenticateEndCallback const&) override;
1158
1159 private:
1160 // TODO (andy) move to pimpl
1161
1162=== modified file 'lockscreen/UserPromptView.cpp'
1163--- lockscreen/UserPromptView.cpp 2014-03-06 21:47:27 +0000
1164+++ lockscreen/UserPromptView.cpp 2014-03-06 21:47:28 +0000
1165@@ -19,17 +19,27 @@
1166
1167 #include "UserPromptView.h"
1168
1169+#include <boost/algorithm/string/trim.hpp>
1170 #include <Nux/VLayout.h>
1171
1172 #include "LockScreenSettings.h"
1173 #include "unity-shared/CairoTexture.h"
1174 #include "unity-shared/TextInput.h"
1175 #include "unity-shared/StaticCairoText.h"
1176+#include "unity-shared/RawPixel.h"
1177
1178 namespace unity
1179 {
1180 namespace lockscreen
1181 {
1182+namespace
1183+{
1184+const RawPixel PADDING = 10_em;
1185+const RawPixel LAYOUT_MARGIN = 10_em;
1186+const RawPixel MSG_LAYOUT_MARGIN = 15_em;
1187+const RawPixel PROMPT_LAYOUT_MARGIN = 5_em;
1188+const int PROMPT_FONT_SIZE = 13;
1189+const int MESSAGE_FONT_SIZE = 11;
1190
1191 nux::AbstractPaintLayer* CrateBackgroundLayer(int width, int height)
1192 {
1193@@ -65,15 +75,36 @@
1194 rop));
1195 }
1196
1197+std::string SanitizeMessage(std::string const& message)
1198+{
1199+ std::string msg = boost::algorithm::trim_copy(message);
1200+
1201+ if (msg.empty())
1202+ return msg;
1203+
1204+ if (msg[msg.size()-1] == ':')
1205+ msg = msg.substr(0, msg.size()-1);
1206+
1207+ if (msg == "Password")
1208+ return _("Password");
1209+
1210+ if (msg == "login")
1211+ return _("Username");
1212+
1213+ return msg;
1214+}
1215+
1216+}
1217+
1218 UserPromptView::UserPromptView(session::Manager::Ptr const& session_manager)
1219 : nux::View(NUX_TRACKER_LOCATION)
1220 , session_manager_(session_manager)
1221 {
1222- user_authenticator_.echo_on_requested.connect([this](std::string const& message, std::shared_ptr<std::promise<std::string>> const& promise){
1223+ user_authenticator_.echo_on_requested.connect([this](std::string const& message, PromiseAuthCodePtr const& promise){
1224 AddPrompt(message, /* visible */ true, promise);
1225 });
1226
1227- user_authenticator_.echo_off_requested.connect([this](std::string const& message, std::shared_ptr<std::promise<std::string>> const& promise){
1228+ user_authenticator_.echo_off_requested.connect([this](std::string const& message, PromiseAuthCodePtr const& promise){
1229 AddPrompt(message, /* visible */ false, promise);
1230 });
1231
1232@@ -97,28 +128,28 @@
1233
1234 void UserPromptView::ResetLayout()
1235 {
1236- focus_queue_ = std::queue<IMTextEntry*>();
1237+ focus_queue_.clear();
1238
1239 SetLayout(new nux::VLayout());
1240
1241- GetLayout()->SetLeftAndRightPadding(10);
1242- GetLayout()->SetTopAndBottomPadding(10);
1243- static_cast<nux::VLayout*>(GetLayout())->SetVerticalInternalMargin(10);
1244+ GetLayout()->SetLeftAndRightPadding(PADDING);
1245+ GetLayout()->SetTopAndBottomPadding(PADDING);
1246+ static_cast<nux::VLayout*>(GetLayout())->SetVerticalInternalMargin(LAYOUT_MARGIN);
1247
1248 auto const& real_name = session_manager_->RealName();
1249 auto const& name = (real_name.empty() ? session_manager_->UserName() : real_name);
1250
1251 unity::StaticCairoText* username = new unity::StaticCairoText(name);
1252- username->SetFont("Ubuntu 13");
1253+ username->SetFont("Ubuntu "+std::to_string(PROMPT_FONT_SIZE));
1254 GetLayout()->AddView(username);
1255
1256 msg_layout_ = new nux::VLayout();
1257- msg_layout_->SetVerticalInternalMargin(15);
1258+ msg_layout_->SetVerticalInternalMargin(MSG_LAYOUT_MARGIN);
1259 msg_layout_->SetReconfigureParentLayoutOnGeometryChange(true);
1260 GetLayout()->AddLayout(msg_layout_);
1261
1262 prompt_layout_ = new nux::VLayout();
1263- prompt_layout_->SetVerticalInternalMargin(5);
1264+ prompt_layout_->SetVerticalInternalMargin(PROMPT_LAYOUT_MARGIN);
1265 prompt_layout_->SetReconfigureParentLayoutOnGeometryChange(true);
1266 GetLayout()->AddLayout(prompt_layout_);
1267
1268@@ -146,7 +177,7 @@
1269 void UserPromptView::Draw(nux::GraphicsEngine& graphics_engine, bool /* force_draw */)
1270 {
1271 nux::Geometry const& geo = GetGeometry();
1272-
1273+
1274 graphics_engine.PushClippingRectangle(geo);
1275 nux::GetPainter().PaintBackground(graphics_engine, geo);
1276
1277@@ -182,46 +213,49 @@
1278 if (focus_queue_.empty())
1279 return nullptr;
1280
1281- focus_queue_.front()->cursor_visible_ = true;
1282+ for (auto* view : focus_queue_)
1283+ if (view->HasKeyboardFocus())
1284+ return view;
1285+
1286 return focus_queue_.front();
1287 }
1288
1289-void UserPromptView::AddPrompt(std::string const& message, bool visible, std::shared_ptr<std::promise<std::string>> const& promise)
1290+void UserPromptView::AddPrompt(std::string const& message, bool visible, PromiseAuthCodePtr const& promise)
1291 {
1292- auto text_input = new unity::TextInput();
1293-
1294- text_input->input_hint = message;
1295- text_input->text_entry()->SetPasswordMode(!visible);
1296-
1297- text_input->text_entry()->cursor_visible_ = false;
1298- if (text_input->text_entry()->cursor_blink_timer_)
1299- g_source_remove(text_input->text_entry()->cursor_blink_timer_);
1300+ auto* text_input = new unity::TextInput();
1301+ auto* text_entry = text_input->text_entry();
1302+
1303+ text_input->input_hint = SanitizeMessage(message);
1304+ text_input->hint_font_size = PROMPT_FONT_SIZE;
1305+ text_entry->SetPasswordMode(!visible);
1306+ text_entry->SetPasswordChar("•");
1307+ text_entry->SetToggleCursorVisibilityOnKeyFocus(true);
1308
1309 text_input->SetMinimumHeight(Settings::GRID_SIZE);
1310 text_input->SetMaximumHeight(Settings::GRID_SIZE);
1311 prompt_layout_->AddView(text_input, 1);
1312- focus_queue_.push(text_input->text_entry());
1313+ focus_queue_.push_back(text_entry);
1314
1315 // Don't remove it, it helps with a11y.
1316 if (focus_queue_.size() == 1)
1317- nux::GetWindowCompositor().SetKeyFocusArea(text_input->text_entry());
1318+ nux::GetWindowCompositor().SetKeyFocusArea(text_entry);
1319
1320- text_input->text_entry()->activated.connect([this, text_input, promise](){
1321+ text_entry->activated.connect([this, text_input, promise](){
1322 if (focus_queue_.size() == 1)
1323 {
1324 text_input->SetSpinnerVisible(true);
1325 text_input->SetSpinnerState(STATE_SEARCHING);
1326 }
1327
1328- this->focus_queue_.pop();
1329-
1330- text_input->text_entry()->SetInputEventSensitivity(false);
1331- text_input->text_entry()->cursor_visible_ = false;
1332- this->QueueRelayout();
1333- this->QueueDraw();
1334-
1335- std::string password = text_input->text_entry()->GetText();
1336- promise->set_value(password);
1337+ focus_queue_.pop_front();
1338+ auto* text_entry = text_input->text_entry();
1339+ text_entry->SetInputEventSensitivity(false);
1340+ QueueRelayout();
1341+ QueueDraw();
1342+
1343+ std::string const& password = text_entry->GetText();
1344+ if (promise)
1345+ promise->set_value(password);
1346 });
1347
1348 GetLayout()->ComputeContentPosition(0, 0);
1349@@ -233,7 +267,7 @@
1350 void UserPromptView::AddMessage(std::string const& message, nux::Color const& color)
1351 {
1352 auto* view = new unity::StaticCairoText("");
1353- view->SetFont("Ubuntu 10");
1354+ view->SetFont("Ubuntu "+std::to_string(MESSAGE_FONT_SIZE));
1355 view->SetTextColor(color);
1356 view->SetText(message);
1357
1358
1359=== modified file 'lockscreen/UserPromptView.h'
1360--- lockscreen/UserPromptView.h 2014-03-06 21:47:27 +0000
1361+++ lockscreen/UserPromptView.h 2014-03-06 21:47:28 +0000
1362@@ -21,7 +21,7 @@
1363 #define UNITY_USER_PROMPT_BOX
1364
1365 #include <memory>
1366-#include <queue>
1367+#include <deque>
1368
1369 #include <Nux/Nux.h>
1370 #include <Nux/View.h>
1371@@ -53,7 +53,7 @@
1372
1373 nux::View* focus_view();
1374
1375- void AddPrompt(std::string const& message, bool visible, std::shared_ptr<std::promise<std::string>> const& promise);
1376+ void AddPrompt(std::string const& message, bool visible, PromiseAuthCodePtr const&);
1377 void AddMessage(std::string const& message, nux::Color const& color);
1378 void AuthenticationCb(bool authenticated);
1379
1380@@ -72,7 +72,7 @@
1381 StaticCairoText* message_;
1382 StaticCairoText* error_;
1383 StaticCairoText* invalid_login_;
1384- std::queue<IMTextEntry*> focus_queue_;
1385+ std::deque<IMTextEntry*> focus_queue_;
1386 };
1387
1388 }
1389
1390=== modified file 'lockscreen/pch/lockscreen_pch.hh'
1391--- lockscreen/pch/lockscreen_pch.hh 2014-03-06 21:47:27 +0000
1392+++ lockscreen/pch/lockscreen_pch.hh 2014-03-06 21:47:28 +0000
1393@@ -23,5 +23,9 @@
1394 */
1395
1396 #include <memory>
1397-
1398-#include <Nux/BaseWindow.h>
1399\ No newline at end of file
1400+#include <vector>
1401+#include <deque>
1402+#include <security/pam_appl.h>
1403+
1404+#include <Nux/Nux.h>
1405+#include <UnityCore/SessionManager.h>
1406\ No newline at end of file
1407
1408=== modified file 'plugins/unityshell/src/unityshell.cpp'
1409--- plugins/unityshell/src/unityshell.cpp 2014-03-06 21:47:27 +0000
1410+++ plugins/unityshell/src/unityshell.cpp 2014-03-06 21:47:28 +0000
1411@@ -2810,6 +2810,15 @@
1412
1413 GLWindowPaintAttrib wAttrib = attrib;
1414
1415+ if (window->type() != CompWindowTypePopupMenuMask)
1416+ {
1417+ if (uScreen->lockscreen_controller_->IsShielded())
1418+ {
1419+ wAttrib.opacity = 0;
1420+ return gWindow->glPaint(wAttrib, matrix, region, mask);
1421+ }
1422+ }
1423+
1424 if (mMinimizeHandler)
1425 {
1426 mask |= mMinimizeHandler->getPaintMask ();
1427@@ -2838,7 +2847,7 @@
1428 paintInnerGlow(scaled_geo, matrix, attrib, mask);
1429 }
1430
1431- if (uScreen->session_controller_ && uScreen->session_controller_->Visible())
1432+ if (uScreen->session_controller_->Visible())
1433 {
1434 // Let's darken the other windows if the session dialog is visible
1435 wAttrib.brightness *= 0.75f;
1436
1437=== modified file 'plugins/unityshell/unityshell.xml.in'
1438--- plugins/unityshell/unityshell.xml.in 2014-03-06 21:47:27 +0000
1439+++ plugins/unityshell/unityshell.xml.in 2014-03-06 21:47:28 +0000
1440@@ -163,7 +163,7 @@
1441 </desc>
1442 <desc>
1443 <value>2</value>
1444- <_name>Custom lockscreen</_name>
1445+ <_name>Unity</_name>
1446 </desc>
1447 </option>
1448 </group>
1449
1450=== modified file 'po/POTFILES.in'
1451--- po/POTFILES.in 2013-05-10 10:07:04 +0000
1452+++ po/POTFILES.in 2014-03-06 21:47:28 +0000
1453@@ -24,6 +24,7 @@
1454 launcher/SpacerLauncherIcon.cpp
1455 launcher/TrashLauncherIcon.cpp
1456 launcher/VolumeLauncherIcon.cpp
1457+lockscreen/UserPromptView.cpp
1458 panel/PanelMenuView.cpp
1459 plugins/networkarearegion/networkarearegion.xml.in
1460 plugins/unity-mt-grab-handles/unitymtgrabhandles.xml.in
1461
1462=== modified file 'services/panel-main.c'
1463--- services/panel-main.c 2014-03-06 21:47:27 +0000
1464+++ services/panel-main.c 2014-03-06 21:47:28 +0000
1465@@ -106,8 +106,8 @@
1466 " </interface>"
1467 "</node>";
1468
1469-#define S_NAME_DESKTOP "com.canonical.Unity.Panel.ServiceDesktop"
1470-#define S_NAME_LOCKSCREEN "com.canonical.Unity.Panel.ServiceLockscreen"
1471+#define S_NAME_DESKTOP "com.canonical.Unity.Panel.Service.Desktop"
1472+#define S_NAME_LOCKSCREEN "com.canonical.Unity.Panel.Service.LockScreen"
1473 #define S_PATH "/com/canonical/Unity/Panel/Service"
1474 #define S_IFACE "com.canonical.Unity.Panel.Service"
1475
1476
1477=== modified file 'tests/data/external.gschema.xml'
1478--- tests/data/external.gschema.xml 2014-01-30 17:57:29 +0000
1479+++ tests/data/external.gschema.xml 2014-03-06 21:47:28 +0000
1480@@ -52,4 +52,22 @@
1481 <default>false</default>
1482 </key>
1483 </schema>
1484+
1485+ <schema id="com.canonical.unity-greeter" path="/com/canonical/unity-greeter/">
1486+ <key type="s" name="logo">
1487+ <default>'/usr/share/unity-greeter/logo.png'</default>
1488+ </key>
1489+ <key type="s" name="background">
1490+ <default>'/usr/share/backgrounds/warty-final-ubuntu.png'</default>
1491+ </key>
1492+ <key type="s" name="background-color">
1493+ <default>'#2C001E'</default>
1494+ </key>
1495+ <key type="b" name="draw-user-backgrounds">
1496+ <default>true</default>
1497+ </key>
1498+ <key type="b" name="draw-grid">
1499+ <default>true</default>
1500+ </key>
1501+ </schema>
1502 </schemalist>
1503
1504=== modified file 'tests/test_lockscreen_controller.cpp'
1505--- tests/test_lockscreen_controller.cpp 2014-03-06 21:47:27 +0000
1506+++ tests/test_lockscreen_controller.cpp 2014-03-06 21:47:28 +0000
1507@@ -64,11 +64,10 @@
1508
1509 struct ShieldFactoryMock : ShieldFactoryInterface
1510 {
1511- nux::ObjectPtr<MockableBaseWindow> CreateShield (session::Manager::Ptr const&, int, bool) override
1512+ nux::ObjectPtr<AbstractShield> CreateShield(session::Manager::Ptr const&, int, bool) override
1513 {
1514- nux::ObjectPtr<MockableBaseWindow> shield(new MockableBaseWindow);
1515- return shield;
1516- }
1517+ return nux::ObjectPtr<AbstractShield>(new AbstractShield(nullptr, 0, false));
1518+ }
1519 };
1520
1521 struct TestLockScreenController : Test
1522@@ -254,7 +253,7 @@
1523 }
1524
1525 TEST_F(TestLockScreenController, LockScreenOnSingleMonitor)
1526-{
1527+{
1528 session_manager->lock_requested.emit();
1529
1530 ASSERT_EQ(1, controller.shields_.size());
1531@@ -275,6 +274,7 @@
1532 TEST_F(TestLockScreenController, SwitchToMultiMonitor)
1533 {
1534 session_manager->lock_requested.emit();
1535+ tick_source.tick(ANIMATION_DURATION);
1536
1537 ASSERT_EQ(1, controller.shields_.size());
1538 EXPECT_EQ(uscreen.GetMonitors().at(0), controller.shields_.at(0)->GetGeometry());
1539@@ -284,7 +284,10 @@
1540 ASSERT_EQ(monitors::MAX, controller.shields_.size());
1541
1542 for (unsigned int i=0; i < monitors::MAX; ++i)
1543- EXPECT_EQ(uscreen.GetMonitors().at(i), controller.shields_.at(i)->GetAbsoluteGeometry());
1544+ {
1545+ ASSERT_EQ(uscreen.GetMonitors().at(i), controller.shields_.at(i)->GetAbsoluteGeometry());
1546+ ASSERT_TRUE(controller.shields_.at(i)->IsVisible());
1547+ }
1548 }
1549
1550 TEST_F(TestLockScreenController, SwitchToSingleMonitor)
1551@@ -295,7 +298,7 @@
1552 ASSERT_EQ(monitors::MAX, controller.shields_.size());
1553
1554 for (unsigned int i=0; i < monitors::MAX; ++i)
1555- EXPECT_EQ(uscreen.GetMonitors().at(i), controller.shields_.at(i)->GetAbsoluteGeometry());
1556+ ASSERT_EQ(uscreen.GetMonitors().at(i), controller.shields_.at(i)->GetAbsoluteGeometry());
1557
1558 uscreen.Reset(/* emit_change */ true);
1559
1560
1561=== modified file 'tests/test_text_input.cpp'
1562--- tests/test_text_input.cpp 2014-03-06 21:47:27 +0000
1563+++ tests/test_text_input.cpp 2014-03-06 21:47:28 +0000
1564@@ -35,7 +35,6 @@
1565 class TextInputMock : public TextInput
1566 {
1567 public:
1568- using TextInput::Init;
1569 using TextInput::OnInputHintChanged;
1570 using TextInput::OnMouseButtonDown;
1571 using TextInput::OnEndKeyFocus;
1572@@ -52,7 +51,6 @@
1573 TestTextInput()
1574 {
1575 entry = new TextInputMock();
1576- entry->Init();
1577 hint = entry->GetHint();
1578 pango_entry = entry->GetPangoEntry();
1579 }
1580
1581=== modified file 'unity-shared/IMTextEntry.cpp'
1582--- unity-shared/IMTextEntry.cpp 2012-07-04 02:37:23 +0000
1583+++ unity-shared/IMTextEntry.cpp 2014-03-06 21:47:28 +0000
1584@@ -1,4 +1,4 @@
1585-// -*- Mode: C++; indent-tabs-mode: ni; tab-width: 2 -*-
1586+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
1587 /*
1588 * Copyright (C) 2011-2012 Canonical Ltd
1589 *
1590@@ -26,7 +26,7 @@
1591 NUX_IMPLEMENT_OBJECT_TYPE(IMTextEntry);
1592
1593 IMTextEntry::IMTextEntry()
1594-: TextEntry("", NUX_TRACKER_LOCATION)
1595+ : TextEntry("", NUX_TRACKER_LOCATION)
1596 {}
1597
1598 void IMTextEntry::CopyClipboard()
1599@@ -85,4 +85,5 @@
1600 {
1601 return !preedit_.empty();
1602 }
1603+
1604 }
1605
1606=== modified file 'unity-shared/IMTextEntry.h'
1607--- unity-shared/IMTextEntry.h 2014-03-06 21:47:27 +0000
1608+++ unity-shared/IMTextEntry.h 2014-03-06 21:47:28 +0000
1609@@ -32,12 +32,9 @@
1610 NUX_DECLARE_OBJECT_TYPE(IMTextEntry, nux::TextEntry);
1611 public:
1612 IMTextEntry();
1613- virtual ~IMTextEntry() {}
1614+
1615 bool im_preedit();
1616
1617- using TextEntry::cursor_visible_;
1618- using TextEntry::cursor_blink_timer_;
1619-
1620 protected:
1621 virtual void InsertText(std::string const& text);
1622 virtual void CopyClipboard();
1623
1624=== modified file 'unity-shared/TextInput.cpp'
1625--- unity-shared/TextInput.cpp 2014-03-06 21:47:27 +0000
1626+++ unity-shared/TextInput.cpp 2014-03-06 21:47:28 +0000
1627@@ -30,9 +30,8 @@
1628 const int HIGHLIGHT_HEIGHT = 24;
1629
1630 // Fonts
1631-const std::string HINT_LABEL_FONT_SIZE = "14px";
1632-const std::string HINT_LABEL_FONT_STYLE = "";
1633-const std::string HINT_LABEL_DEFAULT_FONT = "Ubuntu " + HINT_LABEL_FONT_STYLE + " " + HINT_LABEL_FONT_SIZE;
1634+const std::string HINT_LABEL_DEFAULT_FONT_NAME = "Ubuntu";
1635+const int HINT_LABEL_FONT_SIZE = 11;
1636
1637 const std::string PANGO_ENTRY_DEFAULT_FONT_FAMILY = "Ubuntu";
1638 const int PANGO_ENTRY_FONT_SIZE = 14;
1639@@ -42,34 +41,33 @@
1640 namespace unity
1641 {
1642
1643-nux::logging::Logger logger("unity.dash.textinput");
1644+nux::logging::Logger logger("unity.textinput");
1645
1646 NUX_IMPLEMENT_OBJECT_TYPE(TextInput);
1647
1648 TextInput::TextInput(NUX_FILE_LINE_DECL)
1649 : View(NUX_FILE_LINE_PARAM)
1650 , input_hint("")
1651+ , hint_font_name(HINT_LABEL_DEFAULT_FONT_NAME)
1652+ , hint_font_size(HINT_LABEL_FONT_SIZE)
1653+ , bg_layer_(new nux::ColorLayer(nux::Color(0xff595853), true))
1654 , last_width_(-1)
1655 , last_height_(-1)
1656 {
1657- Init();
1658-}
1659-
1660-void TextInput::Init()
1661-{
1662- bg_layer_.reset(new nux::ColorLayer(nux::Color(0xff595853), true));
1663-
1664 layout_ = new nux::HLayout(NUX_TRACKER_LOCATION);
1665 layout_->SetLeftAndRightPadding(LEFT_INTERNAL_PADDING, TEXT_INPUT_RIGHT_BORDER);
1666 layout_->SetSpaceBetweenChildren(SPACE_BETWEEN_ENTRY_AND_HIGHLIGHT);
1667 SetLayout(layout_);
1668
1669 nux::HLayout* hint_layout = new nux::HLayout(NUX_TRACKER_LOCATION);
1670+ hint_layout->SetLeftAndRightPadding(3, 3);
1671
1672- hint_ = new StaticCairoText(" ");
1673+ hint_ = new StaticCairoText("");
1674 hint_->SetTextColor(nux::Color(1.0f, 1.0f, 1.0f, 0.5f));
1675- hint_->SetFont(HINT_LABEL_DEFAULT_FONT.c_str());
1676- hint_layout->AddView(hint_, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL);
1677+ hint_layout->AddView(hint_, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL);
1678+ hint_font_name.changed.connect(sigc::hide(sigc::mem_fun(this, &TextInput::UpdateHintFont)));
1679+ hint_font_size.changed.connect(sigc::hide(sigc::mem_fun(this, &TextInput::UpdateHintFont)));
1680+ UpdateHintFont();
1681
1682 pango_entry_ = new IMTextEntry();
1683 pango_entry_->SetFontFamily(PANGO_ENTRY_DEFAULT_FONT_FAMILY.c_str());
1684@@ -115,11 +113,15 @@
1685 spinner_->SetState(spinner_state);
1686 }
1687
1688+void TextInput::UpdateHintFont()
1689+{
1690+ hint_->SetFont((hint_font_name() + " " + std::to_string(hint_font_size())).c_str());
1691+}
1692+
1693 void TextInput::OnFontChanged(GtkSettings* settings, GParamSpec* pspec)
1694 {
1695 glib::String font_name;
1696 PangoFontDescription* desc;
1697- std::ostringstream font_desc;
1698
1699 g_object_get(settings, "gtk-font-name", &font_name, NULL);
1700
1701@@ -130,20 +132,19 @@
1702 pango_entry_->SetFontSize(PANGO_ENTRY_FONT_SIZE);
1703 pango_entry_->SetFontOptions(gdk_screen_get_font_options(gdk_screen_get_default()));
1704
1705- font_desc << pango_font_description_get_family(desc) << " " << HINT_LABEL_FONT_STYLE << " " << HINT_LABEL_FONT_SIZE;
1706- hint_->SetFont(font_desc.str().c_str());
1707-
1708- font_desc.str("");
1709- font_desc.clear();
1710-
1711- pango_font_description_free(desc);
1712+ if (hint_font_name() == HINT_LABEL_DEFAULT_FONT_NAME)
1713+ {
1714+ std::ostringstream font_desc;
1715+ font_desc << pango_font_description_get_family(desc) << " " << hint_font_size();
1716+ hint_->SetFont(font_desc.str().c_str());
1717+ pango_font_description_free(desc);
1718+ }
1719 }
1720 }
1721
1722 void TextInput::OnInputHintChanged()
1723 {
1724- glib::String tmp(g_markup_escape_text(input_hint().c_str(), -1));
1725- hint_->SetText(tmp);
1726+ hint_->SetText(input_hint().c_str(), true);
1727 }
1728
1729 void TextInput::Draw(nux::GraphicsEngine& GfxContext, bool force_draw)
1730
1731=== modified file 'unity-shared/TextInput.h'
1732--- unity-shared/TextInput.h 2014-03-06 21:47:27 +0000
1733+++ unity-shared/TextInput.h 2014-03-06 21:47:28 +0000
1734@@ -58,7 +58,6 @@
1735 public:
1736 typedef nux::ObjectPtr<TextInput> Ptr;
1737 TextInput(NUX_FILE_LINE_PROTO);
1738- TextInput(bool show_filter_hint, NUX_FILE_LINE_PROTO);
1739
1740 void SetSpinnerVisible(bool visible);
1741 void SetSpinnerState(SpinnerState spinner_state);
1742@@ -67,12 +66,14 @@
1743
1744 nux::RWProperty<std::string> input_string;
1745 nux::Property<std::string> input_hint;
1746+ nux::Property<std::string> hint_font_name;
1747+ nux::Property<int> hint_font_size;
1748 nux::ROProperty<bool> im_active;
1749 nux::ROProperty<bool> im_preedit;
1750
1751 private:
1752-
1753 void OnFontChanged(GtkSettings* settings, GParamSpec* pspec=NULL);
1754+ void UpdateHintFont();
1755 void Draw(nux::GraphicsEngine& GfxContext, bool force_draw);
1756 void DrawContent(nux::GraphicsEngine& GfxContext, bool force_draw);
1757 void UpdateBackground(bool force);
1758@@ -83,11 +84,8 @@
1759 bool AcceptKeyNavFocus();
1760
1761 protected:
1762-
1763- void Init();
1764 void OnInputHintChanged();
1765- void OnMouseButtonDown(int x, int y, unsigned long button_flags,
1766- unsigned long key_flags);
1767+ void OnMouseButtonDown(int x, int y, unsigned long button_flags, unsigned long key_flags);
1768 void OnEndKeyFocus();
1769
1770 // getters & setters
1771
1772=== modified file 'unity-shared/UScreen.cpp'
1773--- unity-shared/UScreen.cpp 2014-02-27 05:30:25 +0000
1774+++ unity-shared/UScreen.cpp 2014-03-06 21:47:28 +0000
1775@@ -98,16 +98,16 @@
1776
1777 const std::string UScreen::GetMonitorName(int output_number = 0) const
1778 {
1779- if (output_number < 0 || output_number > gdk_screen_get_n_monitors(screen_))
1780+ if (output_number < 0 || output_number >= gdk_screen_get_n_monitors(screen_))
1781 {
1782- LOG_ERROR(logger) << "UScreen::GetMonitorName: Invalid monitor number" << output_number;
1783+ LOG_WARN(logger) << "UScreen::GetMonitorName: Invalid monitor number" << output_number;
1784 return "";
1785 }
1786
1787 glib::String output_name(gdk_screen_get_monitor_plug_name(screen_, output_number));
1788 if (!output_name)
1789 {
1790- LOG_ERROR(logger) << "UScreen::GetMonitorName: Failed to get monitor name for monitor" << output_number;
1791+ LOG_WARN(logger) << "UScreen::GetMonitorName: Failed to get monitor name for monitor" << output_number;
1792 return "";
1793 }
1794