Merge lp:~andyrock/unity/lockscreen into lp:unity

Proposed by Andrea Azzarone on 2014-02-13
Status: Merged
Approved by: Marco Trevisan (Treviño) on 2014-03-10
Approved revision: 4099
Merged at revision: 3703
Proposed branch: lp:~andyrock/unity/lockscreen
Merge into: lp:unity
Diff against target: 5118 lines (+3653/-167) 80 files modified
To merge this branch: bzr merge lp:~andyrock/unity/lockscreen
Reviewer Review Type Date Requested Status
Marco Trevisan (Treviño) Approve on 2014-03-10
PS Jenkins bot continuous-integration Approve on 2014-03-07
Robert Ancell 2014-02-13 Approve on 2014-02-25
Sebastien Bacher Needs Information on 2014-02-25
Review via email: mp+206291@code.launchpad.net

Commit Message

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.

Description of the Change

== General ==
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.

https://bugs.launchpad.net/ayatana-design/+bug/878836/+attachment/3980171/+files/Screenshot%20from%202014-02-13%2023%3A40%3A36.png

== Known issues ==
1. The panel is not 50% transparent (FIXED)
2. No way to switch user from the lockscreen (FIXED lp:~andyrock/indicator-session/lockscreen/+merge/207591)
3. alt+f10 shortcut does not work in the lockscreen (FIXED in lp:~3v1n0/unity/lockscreen-panel)
4. Accessibilty not fully implemented (keyboard and screen-reader work, high-contrast need to be implemented)
   See: lp:~andyrock/nux/view-added/+merge/207763
5. Not full pam support (FIXED)

Remaining issues can be fixed just falling back to lightdm (there is an option in ccsm).

== Notes ==
When testing make sure to run the correct panel service.
At the moment you can lock the screen just using the shortcut (Super+L) or the command:
sudo loginctl lock-sessions

That's because session-menu->Lock does call gnome-screensaver methods to lock the screen.
I'll propose a branch as soon as possible.

To post a comment you must log in.
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Robert Ancell (robert-ancell) wrote :

587 +void Controller::LockScreenUsingDisplayManager()
588 +{
589 + // TODO (andy) Move to a different class (DisplayManagerWrapper)
590 + const char* session_path_raw = g_getenv("XDG_SESSION_PATH");
591 + std::string session_path = session_path_raw ? session_path_raw : "";

You should just give up if $XDG_SESSION_PATH is undefined - you can't call Lock() without it.

review: Needs Fixing
Robert Ancell (robert-ancell) wrote :

I wouldn't worry too much about handling PAM not starting. If this occurs then Real Bad Things (TM) have happened to your system. It's probably best to leave the session locked and get a sysadmin to log into a text terminal to fix it (if PAM is truly broken then they might have a hard time doing that).

1357 + // FIXME (andy) would be nice to support a fallback in case PAM
1358 + // is not available.
1359 + if (!InitPam())
1360 + return false;

Robert Ancell (robert-ancell) wrote :

I think you've covered this in point 5, but the PAM support is not complete enough for production. :) I'll re-review when it is.

Robert Ancell (robert-ancell) wrote :

+ // TODO (andy) fallback to CK. But we need to figure out how to do that.

Do you need to support ConsoleKit? I don't think you do on Ubuntu, are there other Unity consumers who need it?

If you need to, the following seems to work for LightDM:
http://bazaar.launchpad.net/~lightdm-team/lightdm/trunk/view/head:/liblightdm-gobject/power.c#L91

Marco Trevisan (Treviño) (3v1n0) wrote :

Please update the build dependencies in debian as well

Marco Trevisan (Treviño) (3v1n0) wrote :

PanelView: I guess you don't want to add a tray also in lockscreen mode, right? :)
I'd like also if you'd use a struct to initialize more than a bool.

LockScreenSettings: why don't you use the same approach I used for decoration::Settings? It might also help testing...
Also you miss an #include <NuxCore/Property.h>

You miss a lot of includes (I'm not using pch here), and so I get a lot of errors:

#include <NuxGraphics/GLTextureResourceManager.h> // for nux::BaseTexture
Why not a forward declaration?

Anyway, in general it doesn't compile here... I'm getting tons of errors without pch enabled. :(

PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Andrea Azzarone (andyrock) wrote :

> PanelView: I guess you don't want to add a tray also in lockscreen mode,
> right? :)
> I'd like also if you'd use a struct to initialize more than a bool.
>

I can't because I need the value of lockscreen_mode_ in the constructor of panel::PanelView.

>
> LockScreenSettings: why don't you use the same approach I used for
> decoration::Settings? It might also help testing...

decoration::Settings?

> Also you miss an #include <NuxCore/Property.h>
>
> You miss a lot of includes (I'm not using pch here), and so I get a lot of
> errors:
>
> #include <NuxGraphics/GLTextureResourceManager.h> // for nux::BaseTexture
> Why not a forward declaration?
>
> Anyway, in general it doesn't compile here... I'm getting tons of errors
> without pch enabled. :(

Ok fixed. Forward declaration with nux is almost impossible :D

PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Sebastien Bacher (seb128) wrote :

Thanks for the work, some questions:

- > Also allow to fallback to lightdm + greeter (tty switching) in case you need more pam power.

How do you fallback? Do you plan to put a widget on the lock screen that sends you to the greeter?

- the pam integration doesn't seem a small detail to handle. Robert, do you think it's possible to copy the one from lightdm? (I don't know how much that's a separate part of code that can be copied/reused)

- the lock_screen_type options has none/lightdm/custom, what does "custom" mean there? would that allow use to keep using gnome-screensaver instead of unity if needed?

review: Needs Information
Andrea Azzarone (andyrock) wrote :

> Thanks for the work, some questions:
>
> - > Also allow to fallback to lightdm + greeter (tty switching) in case you
> need more pam power.
>
> How do you fallback? Do you plan to put a widget on the lock screen that sends
> you to the greeter?
>

Yeah the branch already does that.

>
> - the pam integration doesn't seem a small detail to handle. Robert, do you
> think it's possible to copy the one from lightdm? (I don't know how much
> that's a separate part of code that can be copied/reused)

I don't think it's possible.

>
> - the lock_screen_type options has none/lightdm/custom, what does "custom"
> mean there? would that allow use to keep using gnome-screensaver instead of
> unity if needed?

None allow to uses gnome-screensaver or whatever you want, custom it's just unity.
I should change name.

lp:~andyrock/unity/lockscreen updated on 2014-02-14
4058. By Marco Trevisan (Treviño) on 2014-02-14

Merging with lp:~3v1n0/unity/text-escaping-fix (so with lp:~3v1n0/unity/decorations-menu)

4059. By Marco Trevisan (Treviño) on 2014-02-14

GSchema: set integrated-menus tweaks to match design specs

4060. By Marco Trevisan (Treviño) on 2014-02-14

DecorationsMenuEntry, PanelTitlebarGrabArea: ignore motion threshold only if still inside the item

Othewise grabbing away a window would be delayed too much when not needed

Robert Ancell (robert-ancell) wrote :

> - the pam integration doesn't seem a small detail to handle. Robert, do you
> think it's possible to copy the one from lightdm? (I don't know how much
> that's a separate part of code that can be copied/reused)

No, but it's not enormously complicated to implement - you just need to be able to handle all the prompts that PAM throws at you. The current code just handles a single username and password prompt (in a very hacky way).

Andrea Azzarone (andyrock) wrote :

I'm already working on it.

2014-02-16 22:28 GMT+01:00 Robert Ancell <email address hidden>:

> > - the pam integration doesn't seem a small detail to handle. Robert, do
> you
> > think it's possible to copy the one from lightdm? (I don't know how much
> > that's a separate part of code that can be copied/reused)
>
> No, but it's not enormously complicated to implement - you just need to be
> able to handle all the prompts that PAM throws at you. The current code
> just handles a single username and password prompt (in a very hacky way).
> --
> https://code.launchpad.net/~andyrock/unity/lockscreen/+merge/206291
> You are the owner of lp:~andyrock/unity/lockscreen.
>

--
Andrea Azzarone
http://launchpad.net/~andyrock
http://wiki.ubuntu.com/AndreaAzzarone

lp:~andyrock/unity/lockscreen updated on 2014-02-19
4061. By Marco Trevisan (Treviño) on 2014-02-15

PanelMenuView: fix logic of HasMenus, again...

4062. By Marco Trevisan (Treviño) on 2014-02-18

Merging with trunk

4063. By Marco Trevisan (Treviño) on 2014-02-18

Merging with Brandon's HiDPI stuff

4064. By Marco Trevisan (Treviño) on 2014-02-18

DecorationStyle, UnitySettings: set integrated_menus off by default :(

4065. By Marco Trevisan (Treviño) on 2014-02-18

UnityGSchema: make favorites list easier editable

4066. By Marco Trevisan (Treviño) on 2014-02-18

DecoratedWindow: don't use a property for monitor, just a member

4067. By Marco Trevisan (Treviño) on 2014-02-18

Merging with Brandon's panel branch

4068. By Marco Trevisan (Treviño) on 2014-02-18

Merging with Brandon's quicklist branch

4069. By Marco Trevisan (Treviño) on 2014-02-18

Merging with HiDPI stuff, so with spread improvements

4070. By Marco Trevisan (Treviño) on 2014-02-18

Merging with lp:~3v1n0/unity/spread-filter

4071. By Marco Trevisan (Treviño) on 2014-02-18

DecorationsEdgeBorders: don't depend on theme, but rather on actual window extents

4072. By Marco Trevisan (Treviño) on 2014-02-18

CompizUtils: update the geometry size when setting the scale

4073. By Marco Trevisan (Treviño) on 2014-02-19

DecorationsWidgets: add Scale property, use on TexturedItem to update geometry

4074. By Marco Trevisan (Treviño) on 2014-02-19

TestDecorationLayout: verify scale property

4075. By Marco Trevisan (Treviño) on 2014-02-19

DecorationsWindowButton: remove the custom code for scaling them up

4076. By Marco Trevisan (Treviño) on 2014-02-19

DecoratedWindow: set the top layout scale to the value we use for this monitor

4077. By Marco Trevisan (Treviño) on 2014-02-19

DecoratedWindow: add some more introspection data

4078. By Marco Trevisan (Treviño) on 2014-02-19

PanelMenuView: put back virtual methods, to make tests happier

4079. By Marco Trevisan (Treviño) on 2014-02-19

PanelIndicatorsView: never try to add to dropdown an already known entry

As it might have been just popped out from the dropdown, and we might have
an infinite loop of push/pop's.

4080. By Marco Trevisan (Treviño) on 2014-02-19

Merging with Brandon's HiDPI chain, again

4081. By Marco Trevisan (Treviño) on 2014-02-19

CairoBaseWindow: add EMConverter in the base class

Instead of adding this to tooltip or Quicklist

4082. By Marco Trevisan (Treviño) on 2014-02-19

Merging against lp:~3v1n0/unity/hdpi-gnome-scaling-factor

PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
lp:~andyrock/unity/lockscreen updated on 2014-02-20
4083. By Andrea Azzarone on 2014-02-20

Merge trunk.

4084. By Andrea Azzarone on 2014-02-20

Revert po changes.

Andrea Azzarone (andyrock) wrote :

Robert can you give a look now?

PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Sebastien Bacher (seb128) wrote :

looking to the screenshot on https://launchpadlibrarian.net/166229067/Screenshot%20from%202014-02-13%2023%3A40%3A36.png I see no widget/obvious way to go back to the greeter, is that an available feature? what's the user interaction?

review: Needs Information
Robert Ancell (robert-ancell) wrote :

The PAM support looks good to me now.

Andrea Azzarone (andyrock) wrote :

> looking to the screenshot on https://launchpadlibrarian.net/166229067/Screensh
> ot%20from%202014-02-13%2023%3A40%3A36.png I see no widget/obvious way to go
> back to the greeter, is that an available feature? what's the user
> interaction?

I'm going to propose a branch against session indicator to add a "Switch user..." item.

Sebastien Bacher (seb128) wrote :

> I'm going to propose a branch against session indicator to add a "Switch user..." item.

That seems suboptimal/not obvious, we should have something on the screen for that imho (widget, button)...

Andrea Azzarone (andyrock) wrote :

> > I'm going to propose a branch against session indicator to add a "Switch
> user..." item.
>
> That seems suboptimal/not obvious, we should have something on the screen for
> that imho (widget, button)...

Not sure, it's the same location of the "lock/switch account..." in the desktop. John Lea what do you think?

lp:~andyrock/unity/lockscreen updated on 2014-02-22
4085. By Andrea Azzarone on 2014-02-21

Merge trunk.

4086. By Andrea Azzarone on 2014-02-22

Improve screen reader in the lockscreen.

4087. By Andrea Azzarone on 2014-02-22

Add missing files.

4088. By Andrea Azzarone on 2014-02-22

Remove panel tray in the lockscreen.

PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
lp:~andyrock/unity/lockscreen updated on 2014-02-22
4089. By Andrea Azzarone on 2014-02-22

Correct handle the grab when using the keyboard shortcut to lock the screen.

PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
lp:~andyrock/unity/lockscreen updated on 2014-02-22
4090. By Andrea Azzarone on 2014-02-22

Share the logo with unity-greeter.

PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Andrea Azzarone (andyrock) wrote :

-- package 'gnome-desktop-3.0' not found

What?

Sebastien Bacher (seb128) wrote :

> -- package 'gnome-desktop-3.0' not found

you need a build-depends on the library...

lp:~andyrock/unity/lockscreen updated on 2014-02-25
4091. By Andrea Azzarone on 2014-02-25

Add libgnome-desktop-dev.

PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Sebastien Bacher (seb128) wrote :

I've built that locally to give it some testing, it works mostly fine, good work!

Some small comments:

- the default config was to still use gnome-screensaver, is that wanted?

- even after changing the config, using indicator-session or ctrl-alt-l calls gnome-screensaver, do we need to land changes for those at the same time?

- the sound indicator lists e.g rhythmbox for me and let you start it in session, is that wanted?

- the password prompt displays "*" chars, lightdm and our other desktop prompts use dots instead

review: Needs Information
Andrea Azzarone (andyrock) wrote :

> I've built that locally to give it some testing, it works mostly fine, good
> work!
>
> Some small comments:
>
> - the default config was to still use gnome-screensaver, is that wanted?

Actually gnome-screensaver sould be disabled by default, at least the lockscreen.

>
> - even after changing the config, using indicator-session or ctrl-alt-l calls
> gnome-screensaver, do we need to land changes for those at the same time?
>

super-l sould work. We need to patch also the session indicator.

> - the sound indicator lists e.g rhythmbox for me and let you start it in
> session, is that wanted?

Nope, but it's an indicator bug.

>
> - the password prompt displays "*" chars, lightdm and our other desktop
> prompts use dots instead

Well nux does not allow us to use dots :/

Sebastien Bacher (seb128) wrote :

> Actually gnome-screensaver sould be disabled by default, at least the lockscreen.

hum, in fact I think I tried 'ctrl-alt-l" and got screensaver and though the config was wrong, super-L works as you pointing it

> Nope, but it's an indicator bug.

Ok

> Well nux does not allow us to use dots :/

you mean it doesn't allow unicode chars? :-(

Andrea Azzarone (andyrock) wrote :

2014-02-25 13:07 GMT+01:00 Sebastien Bacher <email address hidden>:

> > Actually gnome-screensaver sould be disabled by default, at least the
> lockscreen.
>
> hum, in fact I think I tried 'ctrl-alt-l" and got screensaver and though
> the config was wrong, super-L works as you pointing it
>
> > Nope, but it's an indicator bug.
>
> Ok
>
> > Well nux does not allow us to use dots :/
>
> you mean it doesn't allow unicode chars? :-(
>

Indeed.

> --
> https://code.launchpad.net/~andyrock/unity/lockscreen/+merge/206291
> You are the owner of lp:~andyrock/unity/lockscreen.
>

--
Andrea Azzarone
http://launchpad.net/~andyrock
http://wiki.ubuntu.com/AndreaAzzarone

Andrea Azzarone (andyrock) wrote :

Seb I added lignome-desktop-dev but it's not working. http://bazaar.launchpad.net/~andyrock/unity/lockscreen/revision/4091

Sebastien Bacher (seb128) wrote :

> lignome-desktop-dev but it's not working

that's the old gtk2 version, you want "libgnome-desktop-3-dev" (run "dpkg -S gnome-desktop-3.0.pc" on your install to know what binaries ships the file you need ;-)

lp:~andyrock/unity/lockscreen updated on 2014-02-25
4092. By Andrea Azzarone on 2014-02-25

Fix Build-Depends.

PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
lp:~andyrock/unity/lockscreen updated on 2014-02-25
4093. By Andrea Azzarone on 2014-02-25

Add libpam.

PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Robert Ancell (robert-ancell) wrote :

I'm happy with this as long as the remaining issues are fixed.

review: Approve
lp:~andyrock/unity/lockscreen updated on 2014-03-04
4094. By Andrea Azzarone on 2014-03-04

Fix the failing tests in test_gnome_session_manager.cpp

4095. By Andrea Azzarone on 2014-03-04

Merge trunk.

4096. By Andrea Azzarone on 2014-03-04

Fix failing tests in upstart wrapper.

4097. By Andrea Azzarone on 2014-03-04

Fix the lockscreen::Controller tests too.

PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
lp:~andyrock/unity/lockscreen updated on 2014-03-05
4098. By Andrea Azzarone on 2014-03-05

Minor change.

PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
lp:~andyrock/unity/lockscreen updated on 2014-03-06
4099. By Andrea Azzarone on 2014-03-06

Merge trunk.

PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Marco Trevisan (Treviño) (3v1n0) wrote :

You should revert your changes to po/*.po files, but the lockscreen code is great and works well.

I've introduced some random fixes in lp:~3v1n0/unity/lockscreen-review and lp:~3v1n0/unity/lockscreen-panel to improve multi-monitor and settings support and to cleanup a few things.

review: Approve
lp:~andyrock/unity/lockscreen updated on 2014-03-10
4100. By Andrea Azzarone on 2014-03-07

Merge.

4101. By Andrea Azzarone on 2014-03-10

Revert po/* changes.

4102. By Andrea Azzarone on 2014-03-10

Disable LogindLock for the moment.

Preview Diff

1=== modified file 'CMakeLists.txt'
2--- CMakeLists.txt 2014-02-23 21:53:24 +0000
3+++ CMakeLists.txt 2014-03-10 19:41:23 +0000
4@@ -230,6 +230,7 @@
5 indicator3-0.4>=0.4.90
6 json-glib-1.0
7 libbamf3>=0.5.0
8+ gnome-desktop-3.0
9 libnotify
10 libstartup-notification-1.0
11 nux-4.0>=4.0.5
12@@ -263,6 +264,7 @@
13 add_subdirectory(launcher)
14 if (ENABLE_X_SUPPORT)
15 add_subdirectory(hud)
16+ add_subdirectory(lockscreen)
17 add_subdirectory(panel)
18 add_subdirectory(decorations)
19 add_subdirectory(plugins/unityshell)
20
21=== modified file 'UnityCore/DBusIndicators.cpp'
22--- UnityCore/DBusIndicators.cpp 2014-02-28 05:16:10 +0000
23+++ UnityCore/DBusIndicators.cpp 2014-03-10 19:41:23 +0000
24@@ -36,7 +36,8 @@
25
26 namespace
27 {
28-const std::string SERVICE_NAME("com.canonical.Unity.Panel.Service");
29+const std::string SERVICE_NAME_DESKTOP("com.canonical.Unity.Panel.Service.Desktop");
30+const std::string SERVICE_NAME_LOCKSCREEN("com.canonical.Unity.Panel.Service.LockScreen");
31 const std::string SERVICE_PATH("/com/canonical/Unity/Panel/Service");
32 const std::string SERVICE_IFACE("com.canonical.Unity.Panel.Service");
33 } // anonymous namespace
34@@ -456,13 +457,17 @@
35 }
36
37 DBusIndicators::DBusIndicators()
38- : pimpl(new Impl(SERVICE_NAME, this))
39+ : pimpl(new Impl(SERVICE_NAME_DESKTOP, this))
40 {}
41
42 DBusIndicators::DBusIndicators(std::string const& dbus_name)
43 : pimpl(new Impl(dbus_name, this))
44 {}
45
46+LockScreenDBusIndicators::LockScreenDBusIndicators()
47+ : DBusIndicators(SERVICE_NAME_LOCKSCREEN)
48+{}
49+
50 DBusIndicators::~DBusIndicators()
51 {}
52
53
54=== modified file 'UnityCore/DBusIndicators.h'
55--- UnityCore/DBusIndicators.h 2014-02-28 05:16:10 +0000
56+++ UnityCore/DBusIndicators.h 2014-03-10 19:41:23 +0000
57@@ -22,7 +22,6 @@
58
59 #include "Indicators.h"
60
61-
62 namespace unity
63 {
64 namespace indicator
65@@ -56,6 +55,11 @@
66 std::unique_ptr<Impl> pimpl;
67 };
68
69+struct LockScreenDBusIndicators : DBusIndicators
70+{
71+ LockScreenDBusIndicators();
72+};
73+
74 }
75 }
76
77
78=== modified file 'UnityCore/GnomeSessionManager.cpp'
79--- UnityCore/GnomeSessionManager.cpp 2014-02-12 04:04:39 +0000
80+++ UnityCore/GnomeSessionManager.cpp 2014-03-10 19:41:23 +0000
81@@ -87,6 +87,23 @@
82 shell_object_ = shell_server_.GetObject(shell::DBUS_INTERFACE);
83 shell_object_->SetMethodsCallsHandler(sigc::mem_fun(this, &Impl::OnShellMethodCall));
84
85+ {
86+ const char* session_id = test_mode_ ? "id0" : g_getenv("XDG_SESSION_ID");
87+
88+ login_proxy_ = std::make_shared<glib::DBusProxy>(test_mode_ ? testing::DBUS_NAME : "org.freedesktop.login1",
89+ "/org/freedesktop/login1/session/" + glib::gchar_to_string(session_id),
90+ "org.freedesktop.login1.Session",
91+ test_mode_ ? G_BUS_TYPE_SESSION : G_BUS_TYPE_SYSTEM);
92+
93+ login_proxy_->Connect("Lock", [this](GVariant*){
94+ manager_->lock_requested.emit();
95+ });
96+
97+ login_proxy_->Connect("Unlock", [this](GVariant*){
98+ manager_->unlock_requested.emit();
99+ });
100+ }
101+
102 CallLogindMethod("CanHibernate", nullptr, [this] (GVariant* variant, glib::Error const& err) {
103 if (err)
104 {
105@@ -376,9 +393,7 @@
106
107 std::string GnomeManager::RealName() const
108 {
109- const char* name = g_get_real_name();
110-
111- std::string real_name(name ? name : "");
112+ std::string real_name = glib::gchar_to_string(g_get_real_name());
113
114 if (real_name == "Unknown")
115 real_name.clear();
116@@ -388,22 +403,25 @@
117
118 std::string GnomeManager::UserName() const
119 {
120- const char* name = g_get_user_name();
121+ return glib::gchar_to_string(g_get_user_name());
122+}
123
124- return name ? name : "";
125+std::string GnomeManager::HostName() const
126+{
127+ return glib::gchar_to_string(g_get_host_name());
128 }
129
130 void GnomeManager::LockScreen()
131 {
132 impl_->EnsureCancelPendingAction();
133
134- auto proxy = std::make_shared<glib::DBusProxy>(impl_->test_mode_ ? testing::DBUS_NAME : "org.gnome.ScreenSaver",
135- "/org/gnome/ScreenSaver", "org.gnome.ScreenSaver");
136-
137- // By passing the proxy to the lambda we ensure that it will stay alive
138- // until we get the last callback.
139- proxy->Call("Lock", nullptr, [proxy] (GVariant*) {});
140- proxy->Call("SimulateUserActivity", nullptr, [proxy] (GVariant*) {});
141+ // FIXME (andy) we should ask gnome-session to emit the logind signal
142+ if (UserName().find("guest-") == 0)
143+ {
144+ LOG_INFO(logger) << "Impossible to lock a guest session";
145+ return;
146+ }
147+ lock_requested.emit();
148 }
149
150 void GnomeManager::Logout()
151
152=== modified file 'UnityCore/GnomeSessionManager.h'
153--- UnityCore/GnomeSessionManager.h 2013-03-05 20:21:29 +0000
154+++ UnityCore/GnomeSessionManager.h 2014-03-10 19:41:23 +0000
155@@ -35,6 +35,7 @@
156
157 std::string RealName() const;
158 std::string UserName() const;
159+ std::string HostName() const;
160
161 void LockScreen();
162 void Logout();
163
164=== modified file 'UnityCore/GnomeSessionManagerImpl.h'
165--- UnityCore/GnomeSessionManagerImpl.h 2013-03-19 16:05:30 +0000
166+++ UnityCore/GnomeSessionManagerImpl.h 2014-03-10 19:41:23 +0000
167@@ -69,6 +69,7 @@
168 shell::Action pending_action_;
169 glib::DBusServer shell_server_;
170 glib::DBusObject::Ptr shell_object_;
171+ glib::DBusProxy::Ptr login_proxy_;
172 };
173
174 } // namespace session
175
176=== modified file 'UnityCore/SessionManager.h'
177--- UnityCore/SessionManager.h 2013-02-21 18:14:47 +0000
178+++ UnityCore/SessionManager.h 2014-03-10 19:41:23 +0000
179@@ -38,6 +38,7 @@
180
181 virtual std::string RealName() const = 0;
182 virtual std::string UserName() const = 0;
183+ virtual std::string HostName() const = 0;
184
185 virtual void LockScreen() = 0;
186 virtual void Logout() = 0;
187@@ -56,6 +57,10 @@
188 Manager(const Manager&) = delete;
189 Manager& operator=(const Manager&) = delete;
190
191+ sigc::signal<void> lock_requested;
192+ sigc::signal<void> unlock_requested;
193+ sigc::signal<void> locked;
194+ sigc::signal<void> unlocked;
195 sigc::signal<void, bool /* inhibitors */> logout_requested;
196 sigc::signal<void, bool /* inhibitors */> reboot_requested;
197 sigc::signal<void, bool /* inhibitors */> shutdown_requested;
198
199=== modified file 'debian/control'
200--- debian/control 2014-02-21 13:49:05 +0000
201+++ debian/control 2014-03-10 19:41:23 +0000
202@@ -9,24 +9,21 @@
203 dh-migrations,
204 dh-translations (>= 94),
205 google-mock (>= 1.6.0+svn437),
206- google-mock,
207 gsettings-desktop-schemas-dev,
208 gsettings-ubuntu-schemas (>= 0.0.1+14.04.20140219),
209 intltool (>= 0.35.0),
210 libatk1.0-dev,
211 libbamf3-dev (>= 0.5.0+13.10.20130731),
212 libboost-dev,
213- libboost-serialization-dev,
214 libcairo2-dev,
215 libdbus-1-dev,
216- libcompizconfig0-dev (>= 1:0.9.11),
217 libdbusmenu-glib-dev (>= 0.3.91),
218 libdee-dev (>= 1.2.6),
219 libgee-dev (>= 0.5.0),
220 libgeis-dev (>= 2.0.10),
221 libgl1-mesa-dri,
222 libglib2.0-dev (>= 2.39.1),
223- libgrail-dev (>= 1.0.20),
224+ libgnome-desktop-3-dev,
225 libgtest-dev,
226 libgtk-3-dev (>= 3.1),
227 libido3-0.1-dev (>= 13.10.0),
228@@ -38,13 +35,13 @@
229 libnih-dev,
230 libnotify-dev,
231 libnux-4.0-dev (>= 4.0.5),
232+ libpam0g-dev,
233 libpango1.0-dev,
234 libsigc++-2.0-dev,
235 libstartup-notification0-dev,
236 libunique-dev,
237 libunity-dev (>= 7.1.0),
238 libunity-misc-dev (>= 4.0.4),
239- libunity-scopes-json-def-desktop,
240 libupstart-dev,
241 libxcb-icccm4-dev,
242 libxfixes-dev (>= 1:5.0.1-1),
243@@ -77,6 +74,7 @@
244 nux-tools,
245 dconf-cli,
246 unity-asset-pool (>= 0.8.18),
247+ unity-greeter,
248 bamfdaemon,
249 libxfixes3 (>= 1:5.0.1-1),
250 libxi6 (>= 2:1.7.1.901),
251
252=== modified file 'hud/HudView.cpp'
253--- hud/HudView.cpp 2014-02-10 15:31:44 +0000
254+++ hud/HudView.cpp 2014-03-10 19:41:23 +0000
255@@ -507,8 +507,6 @@
256 GetLayout()->ProcessDraw(gfx_context, force_draw);
257 }
258
259- overlay_window_buttons_->QueueDraw();
260-
261 gfx_context.PopClippingRectangle();
262
263 renderer_.DrawInnerCleanup(gfx_context, draw_content_geo, GetAbsoluteGeometry(), GetGeometry());
264
265=== added directory 'lockscreen'
266=== added file 'lockscreen/BackgroundSettings.cpp'
267--- lockscreen/BackgroundSettings.cpp 1970-01-01 00:00:00 +0000
268+++ lockscreen/BackgroundSettings.cpp 2014-03-10 19:41:23 +0000
269@@ -0,0 +1,153 @@
270+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
271+/*
272+* Copyright (C) 2013 Canonical Ltd
273+*
274+* This program is free software: you can redistribute it and/or modify
275+* it under the terms of the GNU General Public License version 3 as
276+* published by the Free Software Foundation.
277+*
278+* This program is distributed in the hope that it will be useful,
279+* but WITHOUT ANY WARRANTY; without even the implied warranty of
280+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
281+* GNU General Public License for more details.
282+*
283+* You should have received a copy of the GNU General Public License
284+* along with this program. If not, see <http://www.gnu.org/licenses/>.
285+*
286+* Authored by: Andrea Azzarone <andrea.azzarone@canonical.com>
287+*/
288+
289+#include <Nux/Nux.h>
290+#include "BackgroundSettings.h"
291+
292+#include <libgnome-desktop/gnome-bg.h>
293+
294+#include "LockScreenSettings.h"
295+#include "unity-shared/CairoTexture.h"
296+#include "unity-shared/PanelStyle.h"
297+#include "unity-shared/UScreen.h"
298+
299+namespace unity
300+{
301+namespace lockscreen
302+{
303+namespace
304+{
305+const std::string SETTINGS_NAME = "org.gnome.desktop.background";
306+
307+constexpr int GetGridOffset(int size) { return (size % Settings::GRID_SIZE) / 2; }
308+}
309+
310+BackgroundSettings::BackgroundSettings()
311+ : gnome_bg_(gnome_bg_new())
312+{
313+ glib::Object<GSettings> settings(g_settings_new(SETTINGS_NAME.c_str()));
314+ gnome_bg_load_from_preferences(gnome_bg_, settings);
315+}
316+
317+BackgroundSettings::~BackgroundSettings()
318+{}
319+
320+BaseTexturePtr BackgroundSettings::GetBackgroundTexture(int monitor)
321+{
322+ nux::Geometry const& geo = UScreen::GetDefault()->GetMonitorGeometry(monitor);
323+ auto& settings = Settings::Instance();
324+
325+ nux::CairoGraphics cairo_graphics(CAIRO_FORMAT_ARGB32, geo.width, geo.height);
326+ cairo_t* c = cairo_graphics.GetInternalContext();
327+
328+ cairo_surface_t* bg_surface = nullptr;
329+
330+ if (settings.use_user_background())
331+ {
332+ bg_surface = gnome_bg_create_surface(gnome_bg_, gdk_get_default_root_window(), geo.width, geo.height, FALSE);
333+ }
334+ else if (!settings.background().empty())
335+ {
336+ glib::Object<GdkPixbuf> pixbuf(gdk_pixbuf_new_from_file_at_scale(settings.background().c_str(), geo.width, geo.height, FALSE, NULL));
337+
338+ if (pixbuf)
339+ bg_surface = gdk_cairo_surface_create_from_pixbuf(pixbuf, 0, NULL);
340+ }
341+
342+ if (bg_surface)
343+ {
344+ cairo_set_source_surface(c, bg_surface, 0, 0);
345+ cairo_paint(c);
346+ cairo_surface_destroy(bg_surface);
347+ }
348+ else
349+ {
350+ auto const& bg_color = settings.background_color();
351+ cairo_set_source_rgb(c, bg_color.red, bg_color.green, bg_color.blue);
352+ cairo_paint(c);
353+ }
354+
355+ if (!settings.logo().empty())
356+ {
357+ int grid_x_offset = GetGridOffset(geo.width);
358+ int grid_y_offset = GetGridOffset(geo.height);
359+ cairo_surface_t* logo_surface = cairo_image_surface_create_from_png(settings.logo().c_str());
360+
361+ if (logo_surface)
362+ {
363+ int height = cairo_image_surface_get_height(logo_surface);
364+ int x = grid_x_offset;
365+ int y = grid_y_offset + Settings::GRID_SIZE * (geo.height / Settings::GRID_SIZE - 1) - height;
366+
367+ cairo_save(c);
368+ cairo_translate(c, x, y);
369+
370+ cairo_set_source_surface(c, logo_surface, 0, 0);
371+ cairo_paint_with_alpha(c, 0.5);
372+ cairo_surface_destroy(logo_surface);
373+ cairo_restore(c);
374+ }
375+ }
376+
377+ if (settings.draw_grid())
378+ {
379+ int width = geo.width;
380+ int height = geo.height;
381+ int grid_x_offset = GetGridOffset(width);
382+ int grid_y_offset = GetGridOffset(height);
383+
384+ // overlay grid
385+ cairo_surface_t* overlay_surface = cairo_surface_create_similar(cairo_graphics.GetSurface(),
386+ CAIRO_CONTENT_COLOR_ALPHA,
387+ Settings::GRID_SIZE,
388+ Settings::GRID_SIZE);
389+
390+ cairo_t* oc = cairo_create(overlay_surface);
391+ cairo_rectangle(oc, 0, 0, 1, 1);
392+ cairo_rectangle(oc, Settings::GRID_SIZE - 1, 0, 1, 1);
393+ cairo_rectangle(oc, 0, Settings::GRID_SIZE - 1, 1, 1);
394+ cairo_rectangle(oc, Settings::GRID_SIZE - 1, Settings::GRID_SIZE - 1, 1, 1);
395+ cairo_set_source_rgba(oc, 1.0, 1.0, 1.0, 0.25);
396+ cairo_fill(oc);
397+
398+ cairo_pattern_t* overlay = cairo_pattern_create_for_surface(overlay_surface);
399+
400+ cairo_matrix_t matrix;
401+ cairo_matrix_init_identity(&matrix);
402+ cairo_matrix_translate(&matrix, -grid_x_offset, -grid_y_offset);
403+
404+ cairo_pattern_set_matrix(overlay, &matrix);
405+ cairo_pattern_set_extend(overlay, CAIRO_EXTEND_REPEAT);
406+
407+ cairo_save(c);
408+ cairo_set_source(c, overlay);
409+ cairo_rectangle(c, 0, 0, width, height);
410+ cairo_fill(c);
411+ cairo_restore(c);
412+
413+ cairo_pattern_destroy(overlay);
414+ cairo_surface_destroy(overlay_surface);
415+ cairo_destroy(oc);
416+ }
417+
418+ return texture_ptr_from_cairo_graphics(cairo_graphics);
419+}
420+
421+} // lockscreen
422+} // unity
423
424=== added file 'lockscreen/BackgroundSettings.h'
425--- lockscreen/BackgroundSettings.h 1970-01-01 00:00:00 +0000
426+++ lockscreen/BackgroundSettings.h 2014-03-10 19:41:23 +0000
427@@ -0,0 +1,55 @@
428+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
429+/*
430+* Copyright (C) 2013 Canonical Ltd
431+*
432+* This program is free software: you can redistribute it and/or modify
433+* it under the terms of the GNU General Public License version 3 as
434+* published by the Free Software Foundation.
435+*
436+* This program is distributed in the hope that it will be useful,
437+* but WITHOUT ANY WARRANTY; without even the implied warranty of
438+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
439+* GNU General Public License for more details.
440+*
441+* You should have received a copy of the GNU General Public License
442+* along with this program. If not, see <http://www.gnu.org/licenses/>.
443+*
444+* Authored by: Andrea Azzarone <andrea.azzarone@canonical.com>
445+*/
446+
447+#ifndef UNITY_BACKGROUND_SETTINGS_H
448+#define UNITY_BACKGROUND_SETTINGS_H
449+
450+#include <NuxCore/ObjectPtr.h>
451+#include <UnityCore/GLibWrapper.h>
452+
453+namespace nux
454+{
455+class BaseTexture;
456+}
457+
458+class _GnomeBG;
459+
460+namespace unity
461+{
462+typedef nux::ObjectPtr<nux::BaseTexture> BaseTexturePtr;
463+
464+namespace lockscreen
465+{
466+
467+class BackgroundSettings
468+{
469+public:
470+ BackgroundSettings();
471+ ~BackgroundSettings();
472+
473+ BaseTexturePtr GetBackgroundTexture(int monitor);
474+
475+private:
476+ glib::Object<_GnomeBG> gnome_bg_;
477+};
478+
479+}
480+}
481+
482+#endif
483
484=== added file 'lockscreen/CMakeLists.txt'
485--- lockscreen/CMakeLists.txt 1970-01-01 00:00:00 +0000
486+++ lockscreen/CMakeLists.txt 2014-03-10 19:41:23 +0000
487@@ -0,0 +1,33 @@
488+set(UNITY_SRC ../plugins/unityshell/src)
489+
490+set (CFLAGS
491+ ${CACHED_UNITY_DEPS_CFLAGS}
492+ ${CACHED_UNITY_DEPS_CFLAGS_OTHER}
493+ ${PIC_FLAGS}
494+ )
495+
496+string (REPLACE ";" " " CFLAGS "${CFLAGS}")
497+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CFLAGS}")
498+
499+set (LIBS ${CACHED_UNITY_DEPS_LDFLAGS} ${UNITY_STANDALONE_LADD})
500+
501+include_directories (.. ../services ../UnityCore ${UNITY_SRC} ${CMAKE_BINARY_DIR})
502+
503+#
504+# Headers & Sources
505+#
506+set (LOCKSCREEN_SOURCES
507+ BackgroundSettings.cpp
508+ CofView.cpp
509+ LockScreenController.cpp
510+ LockScreenSettings.cpp
511+ LockScreenShield.cpp
512+ LockScreenShieldFactory.cpp
513+ LockScreenPanel.cpp
514+ UserAuthenticatorPam.cpp
515+ UserPromptView.cpp
516+ )
517+
518+add_library (lockscreen-lib STATIC ${LOCKSCREEN_SOURCES})
519+add_dependencies (lockscreen-lib unity-core-${UNITY_API_VERSION} unity-shared panel-lib pam)
520+add_pch(pch/lockscreen_pch.hh lockscreen-lib)
521
522=== added file 'lockscreen/CofView.cpp'
523--- lockscreen/CofView.cpp 1970-01-01 00:00:00 +0000
524+++ lockscreen/CofView.cpp 2014-03-10 19:41:23 +0000
525@@ -0,0 +1,41 @@
526+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
527+/*
528+* Copyright (C) 2013 Canonical Ltd
529+*
530+* This program is free software: you can redistribute it and/or modify
531+* it under the terms of the GNU General Public License version 3 as
532+* published by the Free Software Foundation.
533+*
534+* This program is distributed in the hope that it will be useful,
535+* but WITHOUT ANY WARRANTY; without even the implied warranty of
536+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
537+* GNU General Public License for more details.
538+*
539+* You should have received a copy of the GNU General Public License
540+* along with this program. If not, see <http://www.gnu.org/licenses/>.
541+*
542+* Authored by: Andrea Azzarone <andrea.azzarone@canonical.com>
543+*/
544+
545+#include "CofView.h"
546+
547+#include "config.h"
548+
549+namespace unity
550+{
551+namespace lockscreen
552+{
553+
554+CofView::CofView()
555+ // FIXME (andy) if we get an svg cof we can make it fullscreen independent.
556+ : IconTexture(PKGDATADIR"/cof.png", 66)
557+{}
558+
559+nux::Area* CofView::FindAreaUnderMouse(nux::Point const& mouse_position,
560+ nux::NuxEventType event_type)
561+{
562+ return nullptr;
563+}
564+
565+}
566+}
567
568=== added file 'lockscreen/CofView.h'
569--- lockscreen/CofView.h 1970-01-01 00:00:00 +0000
570+++ lockscreen/CofView.h 2014-03-10 19:41:23 +0000
571@@ -0,0 +1,42 @@
572+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
573+/*
574+* Copyright (C) 2013 Canonical Ltd
575+*
576+* This program is free software: you can redistribute it and/or modify
577+* it under the terms of the GNU General Public License version 3 as
578+* published by the Free Software Foundation.
579+*
580+* This program is distributed in the hope that it will be useful,
581+* but WITHOUT ANY WARRANTY; without even the implied warranty of
582+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
583+* GNU General Public License for more details.
584+*
585+* You should have received a copy of the GNU General Public License
586+* along with this program. If not, see <http://www.gnu.org/licenses/>.
587+*
588+* Authored by: Andrea Azzarone <andrea.azzarone@canonical.com>
589+*/
590+
591+#ifndef UNITYSHELL_COF_VIEW_H
592+#define UNITYSHELL_COF_VIEW_H
593+
594+#include "unity-shared/IconTexture.h"
595+
596+namespace unity
597+{
598+namespace lockscreen
599+{
600+
601+class CofView : public unity::IconTexture
602+{
603+public:
604+ CofView();
605+
606+ nux::Area* FindAreaUnderMouse(nux::Point const& mouse_position,
607+ nux::NuxEventType event_type) override;
608+};
609+
610+}
611+}
612+
613+#endif
614\ No newline at end of file
615
616=== added file 'lockscreen/LockScreenAbstractShield.h'
617--- lockscreen/LockScreenAbstractShield.h 1970-01-01 00:00:00 +0000
618+++ lockscreen/LockScreenAbstractShield.h 2014-03-10 19:41:23 +0000
619@@ -0,0 +1,55 @@
620+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
621+/*
622+ * Copyright (C) 2014 Canonical Ltd
623+ *
624+ * This program is free software: you can redistribute it and/or modify
625+ * it under the terms of the GNU General Public License version 3 as
626+ * published by the Free Software Foundation.
627+ *
628+ * This program is distributed in the hope that it will be useful,
629+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
630+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
631+ * GNU General Public License for more details.
632+ *
633+ * You should have received a copy of the GNU General Public License
634+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
635+ *
636+ * Authored by: Marco Trevisan <marco.trevisan@canonical.com>
637+ */
638+
639+#ifndef UNITY_LOCKSCREEN_ABSTRACT_SHIELD_H
640+#define UNITY_LOCKSCREEN_ABSTRACT_SHIELD_H
641+
642+#include <NuxCore/Property.h>
643+#include <UnityCore/SessionManager.h>
644+
645+#include "unity-shared/MockableBaseWindow.h"
646+
647+namespace unity
648+{
649+namespace lockscreen
650+{
651+
652+class AbstractShield : public MockableBaseWindow
653+{
654+public:
655+ AbstractShield(session::Manager::Ptr const& session, int monitor_num, bool is_primary)
656+ : MockableBaseWindow("Unity Lockscreen")
657+ , primary(is_primary)
658+ , monitor(monitor_num)
659+ , session_manager_(session)
660+ {}
661+
662+ nux::Property<bool> primary;
663+ nux::Property<int> monitor;
664+
665+ sigc::signal<void, int, int> grab_motion;
666+
667+protected:
668+ session::Manager::Ptr session_manager_;
669+};
670+
671+} // lockscreen
672+} // unity
673+
674+#endif // UNITY_LOCKSCREEN_ABSTRACT_SHIELD_H
675
676=== added file 'lockscreen/LockScreenController.cpp'
677--- lockscreen/LockScreenController.cpp 1970-01-01 00:00:00 +0000
678+++ lockscreen/LockScreenController.cpp 2014-03-10 19:41:23 +0000
679@@ -0,0 +1,249 @@
680+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
681+/*
682+* Copyright (C) 2013-2014 Canonical Ltd
683+*
684+* This program is free software: you can redistribute it and/or modify
685+* it under the terms of the GNU General Public License version 3 as
686+* published by the Free Software Foundation.
687+*
688+* This program is distributed in the hope that it will be useful,
689+* but WITHOUT ANY WARRANTY; without even the implied warranty of
690+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
691+* GNU General Public License for more details.
692+*
693+* You should have received a copy of the GNU General Public License
694+* along with this program. If not, see <http://www.gnu.org/licenses/>.
695+*
696+* Authored by: Andrea Azzarone <andrea.azzarone@canonical.com>
697+*/
698+
699+#include "LockScreenController.h"
700+
701+#include "LockScreenShield.h"
702+#include "LockScreenSettings.h"
703+#include "unity-shared/AnimationUtils.h"
704+#include "unity-shared/UScreen.h"
705+#include "unity-shared/WindowManager.h"
706+
707+namespace unity
708+{
709+namespace lockscreen
710+{
711+namespace
712+{
713+const unsigned int FADE_DURATION = 400;
714+}
715+
716+namespace testing
717+{
718+const std::string DBUS_NAME = "com.canonical.Unity.Test.DisplayManager";
719+}
720+
721+Controller::Controller(session::Manager::Ptr const& session_manager,
722+ UpstartWrapper::Ptr const& upstart_wrapper,
723+ ShieldFactoryInterface::Ptr const& shield_factory,
724+ bool test_mode)
725+ : session_manager_(session_manager)
726+ , upstart_wrapper_(upstart_wrapper)
727+ , shield_factory_(shield_factory)
728+ , fade_animator_(FADE_DURATION)
729+ , test_mode_(test_mode)
730+{
731+ uscreen_connection_ = UScreen::GetDefault()->changed.connect([this] (int, std::vector<nux::Geometry> const& monitors) {
732+ EnsureShields(monitors);
733+ });
734+ uscreen_connection_->block();
735+
736+ session_manager_->lock_requested.connect(sigc::mem_fun(this, &Controller::OnLockRequested));
737+ session_manager_->unlock_requested.connect(sigc::mem_fun(this, &Controller::OnUnlockRequested));
738+
739+ fade_animator_.updated.connect([this](double value) {
740+ std::for_each(shields_.begin(), shields_.end(), [value](nux::ObjectPtr<Shield> const& shield) {
741+ shield->SetOpacity(value);
742+ });
743+ });
744+
745+ fade_animator_.finished.connect([this] {
746+ if (animation::GetDirection(fade_animator_) == animation::Direction::BACKWARD)
747+ {
748+ motion_connection_->disconnect();
749+ uscreen_connection_->block();
750+ session_manager_->unlocked.emit();
751+ shields_.clear();
752+
753+ if (Settings::Instance().lockscreen_type() == Type::UNITY)
754+ upstart_wrapper_->Emit("desktop-unlock");
755+ }
756+ });
757+}
758+
759+void Controller::OnPrimaryShieldMotion(int x, int y)
760+{
761+ if (!primary_shield_->GetAbsoluteGeometry().IsPointInside(x, y))
762+ {
763+ for (auto const& shield : shields_)
764+ {
765+ if (!shield->GetAbsoluteGeometry().IsPointInside(x, y))
766+ continue;
767+
768+ primary_shield_->primary = false;
769+ primary_shield_ = shield;
770+ shield->primary = true;
771+ auto move_cb = sigc::mem_fun(this, &Controller::OnPrimaryShieldMotion);
772+ motion_connection_ = shield->grab_motion.connect(move_cb);
773+ break;
774+ }
775+ }
776+}
777+
778+void Controller::EnsureShields(std::vector<nux::Geometry> const& monitors)
779+{
780+ int num_monitors = monitors.size();
781+ int shields_size = shields_.size();
782+ bool unity_mode = (Settings::Instance().lockscreen_type() == Type::UNITY);
783+ int primary = unity_mode ? UScreen::GetDefault()->GetMonitorWithMouse() : -1;
784+
785+ shields_.resize(num_monitors);
786+
787+ for (int i = 0; i < num_monitors; ++i)
788+ {
789+ auto& shield = shields_[i];
790+ bool is_new = false;
791+
792+ if (i >= shields_size)
793+ {
794+ shield = shield_factory_->CreateShield(session_manager_, i, i == primary);
795+ is_new = true;
796+ }
797+
798+ shield->SetGeometry(monitors[i]);
799+ shield->SetMinMaxSize(monitors[i].width, monitors[i].height);
800+ shield->primary = (i == primary);
801+ shield->monitor = i;
802+
803+ if (is_new && fade_animator_.GetCurrentValue() > 0)
804+ {
805+ shield->SetOpacity(fade_animator_.GetCurrentValue());
806+ shield->ShowWindow(true);
807+ shield->PushToFront();
808+ }
809+ }
810+
811+ if (unity_mode)
812+ {
813+ primary_shield_ = shields_[primary];
814+ primary_shield_->primary = true;
815+ auto move_cb = sigc::mem_fun(this, &Controller::OnPrimaryShieldMotion);
816+ motion_connection_ = primary_shield_->grab_motion.connect(move_cb);
817+ }
818+}
819+
820+void Controller::OnLockRequested()
821+{
822+ if (IsLocked())
823+ return;
824+
825+ auto lockscreen_type = Settings::Instance().lockscreen_type();
826+
827+ if (lockscreen_type == Type::NONE)
828+ {
829+ session_manager_->unlocked.emit();
830+ return;
831+ }
832+
833+ if (lockscreen_type == Type::LIGHTDM)
834+ {
835+ LockScreenUsingDisplayManager();
836+ }
837+ else if (lockscreen_type == Type::UNITY)
838+ {
839+ upstart_wrapper_->Emit("desktop-lock");
840+ LockScreenUsingUnity();
841+ }
842+
843+ session_manager_->locked.emit();
844+}
845+
846+void Controller::LockScreenUsingDisplayManager()
847+{
848+ // TODO (andy) Move to a different class (DisplayManagerWrapper)
849+ const char* session_path = g_getenv("XDG_SESSION_PATH");
850+
851+ if (!session_path)
852+ return;
853+
854+ auto proxy = std::make_shared<glib::DBusProxy>(test_mode_ ? testing::DBUS_NAME : "org.freedesktop.DisplayManager",
855+ session_path,
856+ "org.freedesktop.DisplayManager.Session",
857+ test_mode_ ? G_BUS_TYPE_SESSION : G_BUS_TYPE_SYSTEM);
858+
859+ proxy->Call("Lock", nullptr, [proxy] (GVariant*) {});
860+
861+ ShowShields();
862+ animation::Skip(fade_animator_);
863+}
864+
865+void Controller::LockScreenUsingUnity()
866+{
867+ ShowShields();
868+}
869+
870+void Controller::ShowShields()
871+{
872+ old_blur_type_ = BackgroundEffectHelper::blur_type;
873+ BackgroundEffectHelper::blur_type = BLUR_NONE;
874+
875+ WindowManager::Default().SaveInputFocus();
876+ EnsureShields(UScreen::GetDefault()->GetMonitors());
877+ uscreen_connection_->unblock();
878+
879+ std::for_each(shields_.begin(), shields_.end(), [] (nux::ObjectPtr<Shield> const& shield) {
880+ shield->SetOpacity(0.0f);
881+ shield->ShowWindow(true);
882+ shield->PushToFront();
883+ });
884+
885+ animation::StartOrReverse(fade_animator_, animation::Direction::FORWARD);
886+}
887+
888+void Controller::OnUnlockRequested()
889+{
890+ if (!IsLocked())
891+ return;
892+
893+ auto lockscreen_type = Settings::Instance().lockscreen_type();
894+
895+ if (lockscreen_type == Type::NONE)
896+ return;
897+
898+ HideShields();
899+
900+ if (lockscreen_type == Type::LIGHTDM)
901+ animation::Skip(fade_animator_);
902+}
903+
904+void Controller::HideShields()
905+{
906+ std::for_each(shields_.begin(), shields_.end(), [](nux::ObjectPtr<Shield> const& shield) {
907+ shield->UnGrabPointer();
908+ shield->UnGrabKeyboard();
909+ });
910+
911+ WindowManager::Default().RestoreInputFocus();
912+ animation::StartOrReverse(fade_animator_, animation::Direction::BACKWARD);
913+
914+ BackgroundEffectHelper::blur_type = old_blur_type_;
915+}
916+
917+bool Controller::IsLocked() const
918+{
919+ return !shields_.empty();
920+}
921+
922+double Controller::Opacity() const
923+{
924+ return fade_animator_.GetCurrentValue();
925+}
926+
927+} // lockscreen
928+} // unity
929
930=== added file 'lockscreen/LockScreenController.h'
931--- lockscreen/LockScreenController.h 1970-01-01 00:00:00 +0000
932+++ lockscreen/LockScreenController.h 2014-03-10 19:41:23 +0000
933@@ -0,0 +1,74 @@
934+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
935+/*
936+* Copyright (C) 2013-2014 Canonical Ltd
937+*
938+* This program is free software: you can redistribute it and/or modify
939+* it under the terms of the GNU General Public License version 3 as
940+* published by the Free Software Foundation.
941+*
942+* This program is distributed in the hope that it will be useful,
943+* but WITHOUT ANY WARRANTY; without even the implied warranty of
944+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
945+* GNU General Public License for more details.
946+*
947+* You should have received a copy of the GNU General Public License
948+* along with this program. If not, see <http://www.gnu.org/licenses/>.
949+*
950+* Authored by: Andrea Azzarone <andrea.azzarone@canonical.com>
951+*/
952+
953+#ifndef UNITY_LOCKSCREEN_CONTROLLER_H
954+#define UNITY_LOCKSCREEN_CONTROLLER_H
955+
956+#include <NuxCore/Animation.h>
957+#include <UnityCore/ConnectionManager.h>
958+
959+#include "LockScreenShieldFactory.h"
960+#include "unity-shared/BackgroundEffectHelper.h"
961+#include "unity-shared/UpstartWrapper.h"
962+
963+namespace unity
964+{
965+namespace lockscreen
966+{
967+
968+class Controller : public sigc::trackable
969+{
970+public:
971+ Controller(session::Manager::Ptr const& session_manager,
972+ UpstartWrapper::Ptr const& upstart_wrapper = std::make_shared<UpstartWrapper>(),
973+ ShieldFactoryInterface::Ptr const& shield_factory = std::make_shared<ShieldFactory>(),
974+ bool test_mode = false);
975+
976+ bool IsLocked() const;
977+ double Opacity() const;
978+
979+private:
980+ friend class TestLockScreenController;
981+
982+ void EnsureShields(std::vector<nux::Geometry> const& monitors);
983+ void LockScreenUsingDisplayManager();
984+ void LockScreenUsingUnity();
985+ void ShowShields();
986+ void HideShields();
987+
988+ void OnLockRequested();
989+ void OnUnlockRequested();
990+ void OnPrimaryShieldMotion(int x, int y);
991+
992+ std::vector<nux::ObjectPtr<AbstractShield>> shields_;
993+ nux::ObjectWeakPtr<AbstractShield> primary_shield_;
994+ session::Manager::Ptr session_manager_;
995+ UpstartWrapper::Ptr upstart_wrapper_;
996+ ShieldFactoryInterface::Ptr shield_factory_;
997+ nux::animation::AnimateValue<double> fade_animator_;
998+ connection::Wrapper uscreen_connection_;
999+ connection::Wrapper motion_connection_;
1000+ bool test_mode_;
1001+ BlurType old_blur_type_;
1002+};
1003+
1004+}
1005+}
1006+
1007+#endif
1008\ No newline at end of file
1009
1010=== added file 'lockscreen/LockScreenPanel.cpp'
1011--- lockscreen/LockScreenPanel.cpp 1970-01-01 00:00:00 +0000
1012+++ lockscreen/LockScreenPanel.cpp 2014-03-10 19:41:23 +0000
1013@@ -0,0 +1,230 @@
1014+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
1015+/*
1016+ * Copyright (C) 2014 Canonical Ltd
1017+ *
1018+ * This program is free software: you can redistribute it and/or modify
1019+ * it under the terms of the GNU General Public License version 3 as
1020+ * published by the Free Software Foundation.
1021+ *
1022+ * This program is distributed in the hope that it will be useful,
1023+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1024+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1025+ * GNU General Public License for more details.
1026+ *
1027+ * You should have received a copy of the GNU General Public License
1028+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1029+ *
1030+ * Authored by: Marco Trevisan <marco.trevisan@canonical.com>
1031+ */
1032+
1033+#include "LockScreenPanel.h"
1034+
1035+#include <boost/algorithm/string/trim.hpp>
1036+#include <Nux/HLayout.h>
1037+
1038+#include "LockScreenSettings.h"
1039+#include "panel/PanelIndicatorsView.h"
1040+#include "unity-shared/CairoTexture.h"
1041+#include "unity-shared/StaticCairoText.h"
1042+#include "unity-shared/PanelStyle.h"
1043+#include "unity-shared/RawPixel.h"
1044+#include "unity-shared/UnitySettings.h"
1045+#include "unity-shared/WindowManager.h"
1046+
1047+namespace unity
1048+{
1049+namespace lockscreen
1050+{
1051+namespace
1052+{
1053+const RawPixel PADDING = 5_em;
1054+}
1055+
1056+using namespace indicator;
1057+using namespace panel;
1058+
1059+Panel::Panel(int monitor_, Indicators::Ptr const& indicators, session::Manager::Ptr const& session_manager)
1060+ : nux::View(NUX_TRACKER_LOCATION)
1061+ , active(true)
1062+ , monitor(monitor_)
1063+ , indicators_(indicators)
1064+ , needs_geo_sync_(true)
1065+{
1066+ double scale = unity::Settings::Instance().em(monitor)->DPIScale();
1067+ auto* layout = new nux::HLayout();
1068+ layout->SetLeftAndRightPadding(PADDING.CP(scale), 0);
1069+ SetLayout(layout);
1070+
1071+ BuildTexture();
1072+
1073+ // Add setting
1074+ auto *hostname = new StaticCairoText(session_manager->HostName());
1075+ hostname->SetFont(Settings::Instance().font_name());
1076+ hostname->SetTextColor(nux::color::White);
1077+ hostname->SetInputEventSensitivity(false);
1078+ hostname->SetScale(scale);
1079+ hostname->SetVisible(Settings::Instance().show_hostname());
1080+ layout->AddView(hostname, 1, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL);
1081+
1082+ indicators_view_ = new PanelIndicatorsView();
1083+ indicators_view_->SetMonitor(monitor);
1084+ indicators_view_->OverlayShown();
1085+ indicators_view_->on_indicator_updated.connect(sigc::mem_fun(this, &Panel::OnIndicatorViewUpdated));
1086+ layout->AddView(indicators_view_, 1, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL);
1087+
1088+ for (auto const& indicator : indicators_->GetIndicators())
1089+ AddIndicator(indicator);
1090+
1091+ indicators_->on_object_added.connect(sigc::mem_fun(this, &Panel::AddIndicator));
1092+ indicators_->on_object_removed.connect(sigc::mem_fun(this, &Panel::RemoveIndicator));
1093+ indicators_->on_entry_show_menu.connect(sigc::mem_fun(this, &Panel::OnEntryShowMenu));
1094+ indicators_->on_entry_activated.connect(sigc::mem_fun(this, &Panel::OnEntryActivated));
1095+ indicators_->on_entry_activate_request.connect(sigc::mem_fun(this, &Panel::OnEntryActivateRequest));
1096+
1097+ monitor.changed.connect([this, hostname] (int monitor) {
1098+ hostname->SetScale(unity::Settings::Instance().em(monitor)->DPIScale());
1099+ indicators_view_->SetMonitor(monitor);
1100+ BuildTexture();
1101+ QueueRelayout();
1102+ });
1103+}
1104+
1105+void Panel::BuildTexture()
1106+{
1107+ int height = panel::Style::Instance().PanelHeight(monitor);
1108+ nux::CairoGraphics context(CAIRO_FORMAT_ARGB32, 1, height);
1109+ auto* cr = context.GetInternalContext();
1110+ cairo_set_source_rgb(cr, 0.1, 0.1, 0.1);
1111+ cairo_paint_with_alpha(cr, 0.4);
1112+ bg_texture_ = texture_ptr_from_cairo_graphics(context);
1113+
1114+ view_layout_->SetMinimumHeight(height);
1115+ view_layout_->SetMaximumHeight(height);
1116+}
1117+
1118+void Panel::AddIndicator(Indicator::Ptr const& indicator)
1119+{
1120+ if (indicator->IsAppmenu())
1121+ return;
1122+
1123+ indicators_view_->AddIndicator(indicator);
1124+ QueueRelayout();
1125+ QueueDraw();
1126+}
1127+
1128+void Panel::RemoveIndicator(indicator::Indicator::Ptr const& indicator)
1129+{
1130+ indicators_view_->RemoveIndicator(indicator);
1131+ QueueRelayout();
1132+ QueueDraw();
1133+}
1134+
1135+std::string Panel::GetPanelName() const
1136+{
1137+ return "LockScreenPanel" + std::to_string(monitor);
1138+}
1139+
1140+void Panel::OnIndicatorViewUpdated()
1141+{
1142+ needs_geo_sync_ = true;
1143+ QueueRelayout();
1144+ QueueDraw();
1145+}
1146+
1147+void Panel::OnEntryShowMenu(std::string const& entry_id, unsigned xid, int x, int y, unsigned button)
1148+{
1149+ if (!active())
1150+ return;
1151+
1152+ // This is ugly... But Nux fault!
1153+ WindowManager::Default().UnGrabMousePointer(CurrentTime, button, x, y);
1154+
1155+ auto shield = static_cast<nux::BaseWindow*>(GetTopLevelViewWindow());
1156+ shield->UnGrabPointer();
1157+ shield->UnGrabKeyboard();
1158+}
1159+
1160+void Panel::OnEntryActivateRequest(std::string const& entry_id)
1161+{
1162+ if (active())
1163+ indicators_view_->ActivateEntry(entry_id, 0);
1164+}
1165+
1166+void Panel::ActivateFirst()
1167+{
1168+ if (active())
1169+ indicators_view_->ActivateIfSensitive();
1170+}
1171+
1172+void Panel::OnEntryActivated(std::string const& panel, std::string const& entry_id, nux::Rect const&)
1173+{
1174+ if (!active() || (!panel.empty() && panel != GetPanelName()))
1175+ return;
1176+
1177+ bool active = !entry_id.empty();
1178+ if (active && !track_menu_pointer_timeout_)
1179+ {
1180+ track_menu_pointer_timeout_.reset(new glib::Timeout(16));
1181+ track_menu_pointer_timeout_->Run([this] {
1182+ nux::Point const& mouse = nux::GetGraphicsDisplay()->GetMouseScreenCoord();
1183+ if (tracked_pointer_pos_ != mouse)
1184+ {
1185+ if (GetAbsoluteGeometry().IsPointInside(mouse.x, mouse.y))
1186+ indicators_view_->ActivateEntryAt(mouse.x, mouse.y);
1187+
1188+ tracked_pointer_pos_ = mouse;
1189+ }
1190+
1191+ return true;
1192+ });
1193+ }
1194+ else if (!active)
1195+ {
1196+ track_menu_pointer_timeout_.reset();
1197+ tracked_pointer_pos_ = {-1, -1};
1198+
1199+ auto shield = static_cast<nux::BaseWindow*>(GetTopLevelViewWindow());
1200+ shield->GrabPointer();
1201+ shield->GrabKeyboard();
1202+ }
1203+}
1204+
1205+void Panel::Draw(nux::GraphicsEngine& graphics_engine, bool force_draw)
1206+{
1207+ auto const& geo = GetGeometry();
1208+
1209+ unsigned int alpha, src, dest = 0;
1210+ graphics_engine.GetRenderStates().GetBlend(alpha, src, dest);
1211+ graphics_engine.GetRenderStates().SetBlend(true, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1212+
1213+ graphics_engine.PushClippingRectangle(geo);
1214+ nux::GetPainter().PaintBackground(graphics_engine, geo);
1215+
1216+ nux::TexCoordXForm texxform;
1217+ texxform.SetWrap(nux::TEXWRAP_REPEAT, nux::TEXWRAP_CLAMP);
1218+ graphics_engine.QRP_1Tex(geo.x, geo.y, geo.width, geo.height,
1219+ bg_texture_->GetDeviceTexture(), texxform,
1220+ nux::color::White);
1221+
1222+ view_layout_->ProcessDraw(graphics_engine, force_draw);
1223+
1224+ graphics_engine.PopClippingRectangle();
1225+ graphics_engine.GetRenderStates().SetBlend(alpha, src, dest);
1226+
1227+ if (needs_geo_sync_)
1228+ {
1229+ EntryLocationMap locations;
1230+ indicators_view_->GetGeometryForSync(locations);
1231+ indicators_->SyncGeometries(GetPanelName(), locations);
1232+ needs_geo_sync_ = false;
1233+ }
1234+}
1235+
1236+bool Panel::InspectKeyEvent(unsigned int event_type, unsigned int keysym, const char*)
1237+{
1238+ ActivateFirst();
1239+ return true;
1240+}
1241+
1242+}
1243+}
1244
1245=== added file 'lockscreen/LockScreenPanel.h'
1246--- lockscreen/LockScreenPanel.h 1970-01-01 00:00:00 +0000
1247+++ lockscreen/LockScreenPanel.h 2014-03-10 19:41:23 +0000
1248@@ -0,0 +1,75 @@
1249+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
1250+/*
1251+ * Copyright (C) 2014 Canonical Ltd
1252+ *
1253+ * This program is free software: you can redistribute it and/or modify
1254+ * it under the terms of the GNU General Public License version 3 as
1255+ * published by the Free Software Foundation.
1256+ *
1257+ * This program is distributed in the hope that it will be useful,
1258+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1259+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1260+ * GNU General Public License for more details.
1261+ *
1262+ * You should have received a copy of the GNU General Public License
1263+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1264+ *
1265+ * Authored by: Marco Trevisan <marco.trevisan@canonical.com>
1266+ */
1267+
1268+#ifndef UNITY_LOCKSCREEN_PANEL
1269+#define UNITY_LOCKSCREEN_PANEL
1270+
1271+#include <Nux/Nux.h>
1272+#include <Nux/View.h>
1273+#include <UnityCore/Indicators.h>
1274+#include <UnityCore/GLibSource.h>
1275+#include <UnityCore/SessionManager.h>
1276+
1277+namespace unity
1278+{
1279+namespace panel
1280+{
1281+class PanelIndicatorsView;
1282+}
1283+
1284+namespace lockscreen
1285+{
1286+
1287+class Panel : public nux::View
1288+{
1289+public:
1290+ Panel(int monitor, indicator::Indicators::Ptr const&, session::Manager::Ptr const&);
1291+
1292+ nux::Property<bool> active;
1293+ nux::Property<int> monitor;
1294+
1295+protected:
1296+ void Draw(nux::GraphicsEngine& GfxContext, bool force_draw) override;
1297+ bool InspectKeyEvent(unsigned int event_type, unsigned int keysym, const char*) override;
1298+
1299+private:
1300+ void ActivateFirst();
1301+ void AddIndicator(indicator::Indicator::Ptr const&);
1302+ void RemoveIndicator(indicator::Indicator::Ptr const&);
1303+ void OnIndicatorViewUpdated();
1304+ void OnEntryActivated(std::string const& panel, std::string const& entry_id, nux::Rect const& geo);
1305+ void OnEntryShowMenu(std::string const& entry_id, unsigned xid, int x, int y, unsigned button);
1306+ void OnEntryActivateRequest(std::string const& entry_id);
1307+
1308+ void BuildTexture();
1309+ std::string GetPanelName() const;
1310+
1311+ indicator::Indicators::Ptr indicators_;
1312+ panel::PanelIndicatorsView* indicators_view_;
1313+ nux::ObjectPtr<nux::BaseTexture> bg_texture_;
1314+
1315+ bool needs_geo_sync_;
1316+ nux::Point tracked_pointer_pos_;
1317+ glib::Source::UniquePtr track_menu_pointer_timeout_;
1318+};
1319+
1320+} // lockscreen namespace
1321+} // unity namespace
1322+
1323+#endif // UNITY_LOCKSCREEN_PANEL
1324
1325=== added file 'lockscreen/LockScreenSettings.cpp'
1326--- lockscreen/LockScreenSettings.cpp 1970-01-01 00:00:00 +0000
1327+++ lockscreen/LockScreenSettings.cpp 2014-03-10 19:41:23 +0000
1328@@ -0,0 +1,104 @@
1329+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
1330+/*
1331+* Copyright (C) 2013 Canonical Ltd
1332+*
1333+* This program is free software: you can redistribute it and/or modify
1334+* it under the terms of the GNU General Public License version 3 as
1335+* published by the Free Software Foundation.
1336+*
1337+* This program is distributed in the hope that it will be useful,
1338+* but WITHOUT ANY WARRANTY; without even the implied warranty of
1339+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1340+* GNU General Public License for more details.
1341+*
1342+* You should have received a copy of the GNU General Public License
1343+* along with this program. If not, see <http://www.gnu.org/licenses/>.
1344+*
1345+* Authored by: Andrea Azzarone <andrea.azzarone@canonical.com>
1346+*/
1347+
1348+#include "LockScreenSettings.h"
1349+
1350+#include <NuxCore/Logger.h>
1351+#include <sigc++/adaptors/hide.h>
1352+#include <UnityCore/GLibSignal.h>
1353+#include <UnityCore/GLibWrapper.h>
1354+
1355+namespace unity
1356+{
1357+namespace lockscreen
1358+{
1359+
1360+DECLARE_LOGGER(logger, "unity.lockscreen.settings");
1361+
1362+namespace
1363+{
1364+Settings* settings_instance = nullptr;
1365+
1366+const std::string GREETER_SETTINGS = "com.canonical.unity-greeter";
1367+const std::string LOGO_KEY = "logo";
1368+const std::string FONT_KEY = "font-name";
1369+const std::string BACKGROUND_KEY = "background";
1370+const std::string BACKGROUND_COLOR_KEY = "background-color";
1371+const std::string USER_BG_KEY = "draw-user-backgrounds";
1372+const std::string DRAW_GRID_KEY = "draw-grid";
1373+const std::string SHOW_HOSTNAME_KEY = "show-hostname";
1374+}
1375+
1376+struct Settings::Impl
1377+{
1378+ Impl()
1379+ : greeter_settings_(g_settings_new(GREETER_SETTINGS.c_str()))
1380+ , signal_(greeter_settings_, "changed", sigc::hide(sigc::hide(sigc::mem_fun(this, &Impl::UpdateSettings))))
1381+ {
1382+ UpdateSettings();
1383+ }
1384+
1385+ void UpdateSettings()
1386+ {
1387+ auto* s = settings_instance;
1388+ s->font_name = glib::String(g_settings_get_string(greeter_settings_, FONT_KEY.c_str())).Str();
1389+ s->logo = glib::String(g_settings_get_string(greeter_settings_, LOGO_KEY.c_str())).Str();
1390+ s->background = glib::String(g_settings_get_string(greeter_settings_, BACKGROUND_KEY.c_str())).Str();
1391+ s->background_color = nux::Color(glib::String(g_settings_get_string(greeter_settings_, BACKGROUND_COLOR_KEY.c_str())).Str());
1392+ s->show_hostname = g_settings_get_boolean(greeter_settings_, SHOW_HOSTNAME_KEY.c_str()) != FALSE;
1393+ s->use_user_background = g_settings_get_boolean(greeter_settings_, USER_BG_KEY.c_str()) != FALSE;
1394+ s->draw_grid = g_settings_get_boolean(greeter_settings_, DRAW_GRID_KEY.c_str()) != FALSE;
1395+ }
1396+
1397+ glib::Object<GSettings> greeter_settings_;
1398+ glib::Signal<void, GSettings*, const gchar*> signal_;
1399+};
1400+
1401+Settings::Settings()
1402+{
1403+ if (settings_instance)
1404+ {
1405+ LOG_ERROR(logger) << "More than one lockscreen::Settings created.";
1406+ }
1407+ else
1408+ {
1409+ lockscreen_type = Type::UNITY;
1410+ settings_instance = this;
1411+ impl_.reset(new Impl());
1412+ }
1413+}
1414+
1415+Settings::~Settings()
1416+{
1417+ if (settings_instance == this)
1418+ settings_instance = nullptr;
1419+}
1420+
1421+Settings& Settings::Instance()
1422+{
1423+ if (!settings_instance)
1424+ {
1425+ LOG_ERROR(logger) << "No lockscreen::Settings created yet.";
1426+ }
1427+
1428+ return *settings_instance;
1429+}
1430+
1431+}
1432+}
1433
1434=== added file 'lockscreen/LockScreenSettings.h'
1435--- lockscreen/LockScreenSettings.h 1970-01-01 00:00:00 +0000
1436+++ lockscreen/LockScreenSettings.h 2014-03-10 19:41:23 +0000
1437@@ -0,0 +1,66 @@
1438+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
1439+/*
1440+* Copyright (C) 2013 Canonical Ltd
1441+*
1442+* This program is free software: you can redistribute it and/or modify
1443+* it under the terms of the GNU General Public License version 3 as
1444+* published by the Free Software Foundation.
1445+*
1446+* This program is distributed in the hope that it will be useful,
1447+* but WITHOUT ANY WARRANTY; without even the implied warranty of
1448+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1449+* GNU General Public License for more details.
1450+*
1451+* You should have received a copy of the GNU General Public License
1452+* along with this program. If not, see <http://www.gnu.org/licenses/>.
1453+*
1454+* Authored by: Andrea Azzarone <andrea.azzarone@canonical.com>
1455+*/
1456+
1457+#ifndef UNITY_LOCKSCREEN_SETTINGS_H
1458+#define UNITY_LOCKSCREEN_SETTINGS_H
1459+
1460+#include <NuxCore/Property.h>
1461+
1462+namespace unity
1463+{
1464+namespace lockscreen
1465+{
1466+
1467+enum class Type : int
1468+{
1469+ NONE = 0, // Do nothing
1470+ LIGHTDM, // Fallback to lightdm
1471+ UNITY // Use custom Unity lockscreen
1472+};
1473+
1474+// TODO (andy) use the same options of unity-greeter
1475+
1476+class Settings
1477+{
1478+public:
1479+ Settings();
1480+ ~Settings();
1481+
1482+ static Settings& Instance();
1483+
1484+ nux::Property<Type> lockscreen_type;
1485+ nux::Property<std::string> font_name;
1486+ nux::Property<std::string> logo;
1487+ nux::Property<std::string> background;
1488+ nux::Property<nux::Color> background_color;
1489+ nux::Property<bool> show_hostname;
1490+ nux::Property<bool> use_user_background;
1491+ nux::Property<bool> draw_grid;
1492+
1493+ static const int GRID_SIZE = 40;
1494+
1495+private:
1496+ struct Impl;
1497+ std::unique_ptr<Impl> impl_;
1498+};
1499+
1500+}
1501+}
1502+
1503+#endif
1504
1505=== added file 'lockscreen/LockScreenShield.cpp'
1506--- lockscreen/LockScreenShield.cpp 1970-01-01 00:00:00 +0000
1507+++ lockscreen/LockScreenShield.cpp 2014-03-10 19:41:23 +0000
1508@@ -0,0 +1,200 @@
1509+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
1510+/*
1511+* Copyright (C) 2013 Canonical Ltd
1512+*
1513+* This program is free software: you can redistribute it and/or modify
1514+* it under the terms of the GNU General Public License version 3 as
1515+* published by the Free Software Foundation.
1516+*
1517+* This program is distributed in the hope that it will be useful,
1518+* but WITHOUT ANY WARRANTY; without even the implied warranty of
1519+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1520+* GNU General Public License for more details.
1521+*
1522+* You should have received a copy of the GNU General Public License
1523+* along with this program. If not, see <http://www.gnu.org/licenses/>.
1524+*
1525+* Authored by: Andrea Azzarone <andrea.azzarone@canonical.com>
1526+*/
1527+
1528+#include "LockScreenShield.h"
1529+
1530+#include <Nux/VLayout.h>
1531+#include <Nux/HLayout.h>
1532+#include <Nux/PaintLayer.h>
1533+#include <UnityCore/DBusIndicators.h>
1534+
1535+#include "BackgroundSettings.h"
1536+#include "CofView.h"
1537+#include "LockScreenPanel.h"
1538+#include "LockScreenSettings.h"
1539+#include "UserPromptView.h"
1540+#include "unity-shared/GnomeKeyGrabber.h"
1541+#include "unity-shared/PanelStyle.h"
1542+#include "unity-shared/UScreen.h"
1543+#include "unity-shared/WindowManager.h"
1544+
1545+namespace unity
1546+{
1547+namespace lockscreen
1548+{
1549+
1550+Shield::Shield(session::Manager::Ptr const& session_manager, int monitor_num, bool is_primary)
1551+ : AbstractShield(session_manager, monitor_num, is_primary)
1552+ , bg_settings_(new BackgroundSettings)
1553+ , prompt_view_(nullptr)
1554+{
1555+ is_primary ? ShowPrimaryView() : ShowSecondaryView();
1556+
1557+ EnableInputWindow(true);
1558+
1559+ geometry_changed.connect([this] (nux::Area*, nux::Geometry&) { UpdateBackgroundTexture();});
1560+
1561+ monitor.changed.connect([this] (int monitor) {
1562+ if (panel_view_)
1563+ panel_view_->monitor = monitor;
1564+
1565+ UpdateBackgroundTexture();
1566+ });
1567+
1568+ primary.changed.connect([this] (bool is_primary) {
1569+ if (!is_primary)
1570+ {
1571+ UnGrabPointer();
1572+ UnGrabKeyboard();
1573+ }
1574+
1575+ is_primary ? ShowPrimaryView() : ShowSecondaryView();
1576+ if (panel_view_) panel_view_->active = is_primary;
1577+ QueueRelayout();
1578+ QueueDraw();
1579+ });
1580+
1581+ mouse_move.connect([this] (int x, int y, int, int, unsigned long, unsigned long) {
1582+ auto const& abs_geo = GetAbsoluteGeometry();
1583+ grab_motion.emit(abs_geo.x + x, abs_geo.y + y);
1584+ });
1585+}
1586+
1587+void Shield::UpdateBackgroundTexture()
1588+{
1589+ auto const& monitor_geo = UScreen::GetDefault()->GetMonitorGeometry(monitor);
1590+
1591+ if (!background_layer_ || monitor_geo != background_layer_->GetGeometry())
1592+ {
1593+ auto background_texture = bg_settings_->GetBackgroundTexture(monitor);
1594+ background_layer_.reset(new nux::TextureLayer(background_texture->GetDeviceTexture(), nux::TexCoordXForm(), nux::color::White, true));
1595+ SetBackgroundLayer(background_layer_.get());
1596+ }
1597+}
1598+
1599+void Shield::ShowPrimaryView()
1600+{
1601+ GrabPointer();
1602+ GrabKeyboard();
1603+
1604+ if (primary_layout_)
1605+ {
1606+ SetLayout(primary_layout_.GetPointer());
1607+ return;
1608+ }
1609+
1610+ nux::Layout* main_layout = new nux::VLayout();
1611+ primary_layout_ = main_layout;
1612+ SetLayout(primary_layout_.GetPointer());
1613+
1614+ main_layout->AddView(CreatePanel());
1615+
1616+ nux::HLayout* prompt_layout = new nux::HLayout();
1617+ prompt_layout->SetLeftAndRightPadding(2 * Settings::GRID_SIZE);
1618+
1619+ prompt_view_ = CreatePromptView();
1620+ prompt_layout->AddView(prompt_view_);
1621+
1622+ // 10 is just a random number to center the prompt view.
1623+ main_layout->AddSpace(0, 10);
1624+ main_layout->AddLayout(prompt_layout);
1625+ main_layout->AddSpace(0, 10);
1626+}
1627+
1628+void Shield::ShowSecondaryView()
1629+{
1630+ if (cof_layout_)
1631+ {
1632+ SetLayout(cof_layout_.GetPointer());
1633+ return;
1634+ }
1635+
1636+ nux::Layout* main_layout = new nux::VLayout();
1637+ cof_layout_ = main_layout;
1638+ SetLayout(cof_layout_.GetPointer());
1639+
1640+ // The circle of friends
1641+ CofView* cof_view = new CofView();
1642+ main_layout->AddView(cof_view);
1643+}
1644+
1645+Panel* Shield::CreatePanel()
1646+{
1647+ auto indicators = std::make_shared<indicator::LockScreenDBusIndicators>();
1648+ panel_view_ = new Panel(monitor, indicators, session_manager_);
1649+
1650+ return panel_view_;
1651+}
1652+
1653+UserPromptView* Shield::CreatePromptView()
1654+{
1655+ auto* prompt_view = new UserPromptView(session_manager_);
1656+
1657+ auto width = 8 * Settings::GRID_SIZE;
1658+ auto height = 3 * Settings::GRID_SIZE;
1659+
1660+ prompt_view->SetMinimumWidth(width);
1661+ prompt_view->SetMaximumWidth(width);
1662+ prompt_view->SetMinimumHeight(height);
1663+
1664+ return prompt_view;
1665+}
1666+
1667+nux::Area* Shield::FindKeyFocusArea(unsigned etype, unsigned long key_code, unsigned long modifiers)
1668+{
1669+ if (primary)
1670+ {
1671+ if (panel_view_)
1672+ {
1673+ modifiers &= (nux::NUX_STATE_ALT | nux::NUX_STATE_CTRL | nux::NUX_STATE_SUPER | nux::NUX_STATE_SHIFT);
1674+ auto const& indicators_key = WindowManager::Default().activate_indicators_key();
1675+
1676+ if (indicators_key.first == modifiers && indicators_key.second == key_code)
1677+ return panel_view_;
1678+ }
1679+
1680+ if (prompt_view_)
1681+ {
1682+ auto* focus_view = prompt_view_->focus_view();
1683+
1684+ if (focus_view && focus_view->GetInputEventSensitivity())
1685+ return focus_view;
1686+ }
1687+ }
1688+
1689+ return nullptr;
1690+}
1691+
1692+bool Shield::AcceptKeyNavFocus()
1693+{
1694+ return false;
1695+}
1696+
1697+nux::Area* Shield::FindAreaUnderMouse(nux::Point const& mouse, nux::NuxEventType event_type)
1698+{
1699+ nux::Area* area = BaseWindow::FindAreaUnderMouse(mouse, event_type);
1700+
1701+ if (!area && primary)
1702+ return this;
1703+
1704+ return area;
1705+}
1706+
1707+}
1708+}
1709
1710=== added file 'lockscreen/LockScreenShield.h'
1711--- lockscreen/LockScreenShield.h 1970-01-01 00:00:00 +0000
1712+++ lockscreen/LockScreenShield.h 2014-03-10 19:41:23 +0000
1713@@ -0,0 +1,63 @@
1714+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
1715+/*
1716+* Copyright (C) 2013 Canonical Ltd
1717+*
1718+* This program is free software: you can redistribute it and/or modify
1719+* it under the terms of the GNU General Public License version 3 as
1720+* published by the Free Software Foundation.
1721+*
1722+* This program is distributed in the hope that it will be useful,
1723+* but WITHOUT ANY WARRANTY; without even the implied warranty of
1724+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1725+* GNU General Public License for more details.
1726+*
1727+* You should have received a copy of the GNU General Public License
1728+* along with this program. If not, see <http://www.gnu.org/licenses/>.
1729+*
1730+* Authored by: Andrea Azzarone <andrea.azzarone@canonical.com>
1731+*/
1732+
1733+#ifndef UNITY_LOCKSCREEN_SHIELD_H
1734+#define UNITY_LOCKSCREEN_SHIELD_H
1735+
1736+#include "LockScreenAbstractShield.h"
1737+
1738+namespace unity
1739+{
1740+namespace lockscreen
1741+{
1742+
1743+class BackgroundSettings;
1744+class UserAuthenticator;
1745+class UserPromptView;
1746+class Panel;
1747+
1748+class Shield : public AbstractShield
1749+{
1750+public:
1751+ Shield(session::Manager::Ptr const& session_manager, int monitor, bool is_primary);
1752+
1753+protected:
1754+ bool AcceptKeyNavFocus() override;
1755+ nux::Area* FindKeyFocusArea(unsigned int, unsigned long, unsigned long) override;
1756+ nux::Area* FindAreaUnderMouse(nux::Point const&, nux::NuxEventType) override;
1757+
1758+private:
1759+ void UpdateBackgroundTexture();
1760+ void ShowPrimaryView();
1761+ void ShowSecondaryView();
1762+ Panel* CreatePanel();
1763+ UserPromptView* CreatePromptView();
1764+
1765+ std::shared_ptr<BackgroundSettings> bg_settings_;
1766+ std::unique_ptr<nux::AbstractPaintLayer> background_layer_;
1767+ nux::ObjectPtr<nux::Layout> primary_layout_;
1768+ nux::ObjectPtr<nux::Layout> cof_layout_;
1769+ UserPromptView* prompt_view_;
1770+ Panel* panel_view_;
1771+};
1772+
1773+}
1774+}
1775+
1776+#endif
1777\ No newline at end of file
1778
1779=== added file 'lockscreen/LockScreenShieldFactory.cpp'
1780--- lockscreen/LockScreenShieldFactory.cpp 1970-01-01 00:00:00 +0000
1781+++ lockscreen/LockScreenShieldFactory.cpp 2014-03-10 19:41:23 +0000
1782@@ -0,0 +1,34 @@
1783+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
1784+/*
1785+* Copyright (C) 2014 Canonical Ltd
1786+*
1787+* This program is free software: you can redistribute it and/or modify
1788+* it under the terms of the GNU General Public License version 3 as
1789+* published by the Free Software Foundation.
1790+*
1791+* This program is distributed in the hope that it will be useful,
1792+* but WITHOUT ANY WARRANTY; without even the implied warranty of
1793+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1794+* GNU General Public License for more details.
1795+*
1796+* You should have received a copy of the GNU General Public License
1797+* along with this program. If not, see <http://www.gnu.org/licenses/>.
1798+*
1799+* Authored by: Andrea Azzarone <andrea.azzarone@canonical.com>
1800+*/
1801+
1802+#include "LockScreenShieldFactory.h"
1803+#include "LockScreenShield.h"
1804+
1805+namespace unity
1806+{
1807+namespace lockscreen
1808+{
1809+
1810+nux::ObjectPtr<AbstractShield> ShieldFactory::CreateShield(session::Manager::Ptr const& session_manager, int monitor, bool is_primary)
1811+{
1812+ return nux::ObjectPtr<Shield>(new Shield(session_manager, monitor, is_primary));
1813+}
1814+
1815+}
1816+}
1817
1818=== added file 'lockscreen/LockScreenShieldFactory.h'
1819--- lockscreen/LockScreenShieldFactory.h 1970-01-01 00:00:00 +0000
1820+++ lockscreen/LockScreenShieldFactory.h 2014-03-10 19:41:23 +0000
1821@@ -0,0 +1,51 @@
1822+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
1823+/*
1824+* Copyright (C) 2014 Canonical Ltd
1825+*
1826+* This program is free software: you can redistribute it and/or modify
1827+* it under the terms of the GNU General Public License version 3 as
1828+* published by the Free Software Foundation.
1829+*
1830+* This program is distributed in the hope that it will be useful,
1831+* but WITHOUT ANY WARRANTY; without even the implied warranty of
1832+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1833+* GNU General Public License for more details.
1834+*
1835+* You should have received a copy of the GNU General Public License
1836+* along with this program. If not, see <http://www.gnu.org/licenses/>.
1837+*
1838+* Authored by: Andrea Azzarone <andrea.azzarone@canonical.com>
1839+*/
1840+
1841+#ifndef UNITY_LOCKSCREEN_SHIELD_FACTORY
1842+#define UNITY_LOCKSCREEN_SHIELD_FACTORY
1843+
1844+#include <Nux/Nux.h>
1845+#include "LockScreenAbstractShield.h"
1846+
1847+namespace unity
1848+{
1849+
1850+class MockableBaseWindow;
1851+
1852+namespace lockscreen
1853+{
1854+
1855+struct ShieldFactoryInterface
1856+{
1857+ typedef std::shared_ptr<ShieldFactoryInterface> Ptr;
1858+
1859+ virtual ~ShieldFactoryInterface() = default;
1860+
1861+ virtual nux::ObjectPtr<AbstractShield> CreateShield(session::Manager::Ptr const&, int monitor, bool is_primary) = 0;
1862+};
1863+
1864+struct ShieldFactory : ShieldFactoryInterface
1865+{
1866+ nux::ObjectPtr<AbstractShield> CreateShield(session::Manager::Ptr const&, int monitor, bool is_primary) override;
1867+};
1868+
1869+}
1870+}
1871+
1872+#endif
1873
1874=== added file 'lockscreen/UserAuthenticator.h'
1875--- lockscreen/UserAuthenticator.h 1970-01-01 00:00:00 +0000
1876+++ lockscreen/UserAuthenticator.h 2014-03-10 19:41:23 +0000
1877@@ -0,0 +1,56 @@
1878+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
1879+/*
1880+ * Copyright (C) 2013 Canonical Ltd
1881+ *
1882+ * This program is free software: you can redistribute it and/or modify
1883+ * it under the terms of the GNU General Public License version 3 as
1884+ * published by the Free Software Foundation.
1885+ *
1886+ * This program is distributed in the hope that it will be useful,
1887+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1888+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1889+ * GNU General Public License for more details.
1890+ *
1891+ * You should have received a copy of the GNU General Public License
1892+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1893+ *
1894+ * Authored by: Andrea Azzarone <andrea.azzarone@canonical.com>
1895+ */
1896+
1897+#ifndef UNITY_USER_AUTHENTICATOR_H
1898+#define UNITY_USER_AUTHENTICATOR_H
1899+
1900+#include <future>
1901+#include <functional>
1902+#include <memory>
1903+#include <sigc++/signal.h>
1904+#include <string>
1905+
1906+namespace unity
1907+{
1908+namespace lockscreen
1909+{
1910+
1911+typedef std::shared_ptr<std::promise<std::string>> PromiseAuthCodePtr;
1912+
1913+class UserAuthenticator
1914+{
1915+public:
1916+ typedef std::function<void(bool)> AuthenticateEndCallback;
1917+
1918+ virtual ~UserAuthenticator() = default;
1919+
1920+ // Authenticate the user in a background thread.
1921+ virtual bool AuthenticateStart(std::string const& username, AuthenticateEndCallback const&) = 0;
1922+
1923+ sigc::signal<void, std::string, PromiseAuthCodePtr const&> echo_on_requested;
1924+ sigc::signal<void, std::string, PromiseAuthCodePtr const&> echo_off_requested;
1925+ sigc::signal<void, std::string> message_requested;
1926+ sigc::signal<void, std::string> error_requested;
1927+ sigc::signal<void> clear_prompts;
1928+};
1929+
1930+} // lockscreen
1931+} // unity
1932+
1933+ #endif // UNITY_USER_AUTHENTICATOR_H
1934
1935=== added file 'lockscreen/UserAuthenticatorPam.cpp'
1936--- lockscreen/UserAuthenticatorPam.cpp 1970-01-01 00:00:00 +0000
1937+++ lockscreen/UserAuthenticatorPam.cpp 2014-03-10 19:41:23 +0000
1938@@ -0,0 +1,171 @@
1939+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
1940+/*
1941+ * Copyright (C) 2013 Canonical Ltd
1942+ *
1943+ * This program is free software: you can redistribute it and/or modify
1944+ * it under the terms of the GNU General Public License version 3 as
1945+ * published by the Free Software Foundation.
1946+ *
1947+ * This program is distributed in the hope that it will be useful,
1948+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1949+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1950+ * GNU General Public License for more details.
1951+ *
1952+ * You should have received a copy of the GNU General Public License
1953+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1954+ *
1955+ * Authored by: Andrea Azzarone <andrea.azzarone@canonical.com>
1956+ */
1957+
1958+// Kindly inspired by user_authenticator_linux.cc of chromium project
1959+// In the future would be nice to have something less static. For the moment
1960+// let's just fallcback to lightdm.
1961+
1962+#include "UserAuthenticatorPam.h"
1963+
1964+#include <cstring>
1965+#include <security/pam_appl.h>
1966+#include <vector>
1967+
1968+namespace unity
1969+{
1970+namespace lockscreen
1971+{
1972+
1973+bool UserAuthenticatorPam::AuthenticateStart(std::string const& username,
1974+ AuthenticateEndCallback const& authenticate_cb)
1975+{
1976+ first_prompt_ = true;
1977+ username_ = username;
1978+ authenticate_cb_ = authenticate_cb;
1979+
1980+ if (!InitPam())
1981+ return false;
1982+
1983+ glib::Object<GTask> task(g_task_new(nullptr, cancellable_, [] (GObject*, GAsyncResult*, gpointer data) {
1984+ auto self = static_cast<UserAuthenticatorPam*>(data);
1985+ pam_end(self->pam_handle_, self->status_);
1986+ self->authenticate_cb_(self->status_ == PAM_SUCCESS);
1987+ }, this));
1988+
1989+ g_task_set_task_data(task, this, nullptr);
1990+
1991+ g_task_run_in_thread(task, [] (GTask* task, gpointer, gpointer data, GCancellable*) {
1992+ auto self = static_cast<UserAuthenticatorPam*>(data);
1993+ self->status_ = pam_authenticate(self->pam_handle_, 0);
1994+ });
1995+
1996+ return true;
1997+}
1998+
1999+bool UserAuthenticatorPam::InitPam()
2000+{
2001+ pam_conv conversation;
2002+ conversation.conv = ConversationFunction;
2003+ conversation.appdata_ptr = static_cast<void*>(this);
2004+
2005+ // FIXME (andy) We should install our own unityshell pam file.
2006+ return pam_start("lightdm", username_.c_str(),
2007+ &conversation, &pam_handle_) == PAM_SUCCESS;
2008+}
2009+
2010+int UserAuthenticatorPam::ConversationFunction(int num_msg,
2011+ const pam_message** msg,
2012+ pam_response** resp,
2013+ void* appdata_ptr)
2014+{
2015+ if (num_msg <= 0)
2016+ return PAM_CONV_ERR;
2017+
2018+ auto* tmp_response = static_cast<pam_response*>(calloc(num_msg, sizeof(pam_response)));
2019+
2020+ if (!tmp_response)
2021+ return PAM_CONV_ERR;
2022+
2023+ UserAuthenticatorPam* user_auth = static_cast<UserAuthenticatorPam*>(appdata_ptr);
2024+
2025+ if (!user_auth->first_prompt_)
2026+ {
2027+ // Adding a timeout ensures that the signal is emitted in the main thread
2028+ user_auth->source_manager_.AddTimeout(0, [user_auth] { user_auth->clear_prompts.emit(); return false; });
2029+ }
2030+
2031+ user_auth->first_prompt_ = false;
2032+
2033+ bool raise_error = false;
2034+ int count;
2035+ std::vector<PromiseAuthCodePtr> promises;
2036+
2037+ for (count = 0; count < num_msg && !raise_error; ++count)
2038+ {
2039+ switch (msg[count]->msg_style)
2040+ {
2041+ case PAM_PROMPT_ECHO_ON:
2042+ {
2043+ auto promise = std::make_shared<std::promise<std::string>>();
2044+ promises.push_back(promise);
2045+
2046+ // Adding a timeout ensures that the signal is emitted in the main thread
2047+ std::string message(msg[count]->msg);
2048+ user_auth->source_manager_.AddTimeout(0, [user_auth, message, promise] { user_auth->echo_on_requested.emit(message, promise); return false; });
2049+ break;
2050+ }
2051+ case PAM_PROMPT_ECHO_OFF:
2052+ {
2053+ auto promise = std::make_shared<std::promise<std::string>>();
2054+ promises.push_back(promise);
2055+
2056+ // Adding a timeout ensures that the signal is emitted in the main thread
2057+ std::string message(msg[count]->msg);
2058+ user_auth->source_manager_.AddTimeout(0, [user_auth, message, promise] { user_auth->echo_off_requested.emit(message, promise); return false; });
2059+ break;
2060+ }
2061+ case PAM_TEXT_INFO:
2062+ {
2063+ // Adding a timeout ensures that the signal is emitted in the main thread
2064+ std::string message(msg[count]->msg);
2065+ user_auth->source_manager_.AddTimeout(0, [user_auth, message] { user_auth->message_requested.emit(message); return false; });
2066+ break;
2067+ }
2068+ default:
2069+ {
2070+ // Adding a timeout ensures that the signal is emitted in the main thread
2071+ std::string message(msg[count]->msg);
2072+ user_auth->source_manager_.AddTimeout(0, [user_auth, message] { user_auth->error_requested.emit(message); return false; });
2073+ }
2074+ }
2075+ }
2076+
2077+ int i = 0;
2078+
2079+ for (auto const& promise : promises)
2080+ {
2081+ auto future = promise->get_future();
2082+ pam_response* resp_item = &tmp_response[i++];
2083+ resp_item->resp_retcode = 0;
2084+ resp_item->resp = strdup(future.get().c_str());
2085+
2086+ if (!resp_item->resp)
2087+ {
2088+ raise_error = true;
2089+ break;
2090+ }
2091+ }
2092+
2093+ if (raise_error)
2094+ {
2095+ for (int i = 0; i < count; ++i)
2096+ free(tmp_response[i].resp);
2097+
2098+ free(tmp_response);
2099+ return PAM_CONV_ERR;
2100+ }
2101+ else
2102+ {
2103+ *resp = tmp_response;
2104+ return PAM_SUCCESS;
2105+ }
2106+}
2107+
2108+} // lockscreen
2109+} // unity
2110
2111=== added file 'lockscreen/UserAuthenticatorPam.h'
2112--- lockscreen/UserAuthenticatorPam.h 1970-01-01 00:00:00 +0000
2113+++ lockscreen/UserAuthenticatorPam.h 2014-03-10 19:41:23 +0000
2114@@ -0,0 +1,66 @@
2115+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
2116+/*
2117+ * Copyright (C) 2013 Canonical Ltd
2118+ *
2119+ * This program is free software: you can redistribute it and/or modify
2120+ * it under the terms of the GNU General Public License version 3 as
2121+ * published by the Free Software Foundation.
2122+ *
2123+ * This program is distributed in the hope that it will be useful,
2124+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2125+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2126+ * GNU General Public License for more details.
2127+ *
2128+ * You should have received a copy of the GNU General Public License
2129+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2130+ *
2131+ * Authored by: Andrea Azzarone <andrea.azzarone@canonical.com>
2132+ */
2133+
2134+#ifndef UNITY_USER_AUTHENTICATOR_PAM_H
2135+#define UNITY_USER_AUTHENTICATOR_PAM_H
2136+
2137+#include <boost/noncopyable.hpp>
2138+#include <UnityCore/GLibWrapper.h>
2139+#include <UnityCore/GLibSource.h>
2140+
2141+#include "UserAuthenticator.h"
2142+
2143+// Forward declarations
2144+struct pam_handle;
2145+struct pam_message;
2146+struct pam_response;
2147+
2148+namespace unity
2149+{
2150+namespace lockscreen
2151+{
2152+
2153+class UserAuthenticatorPam : public UserAuthenticator, private boost::noncopyable
2154+{
2155+public:
2156+ bool AuthenticateStart(std::string const& username, AuthenticateEndCallback const&) override;
2157+
2158+private:
2159+ // TODO (andy) move to pimpl
2160+ bool InitPam();
2161+
2162+ static int ConversationFunction(int num_msg,
2163+ const pam_message** msg,
2164+ pam_response** resp,
2165+ void* appdata_ptr);
2166+
2167+ std::string username_;
2168+ AuthenticateEndCallback authenticate_cb_;
2169+
2170+ int status_;
2171+ bool first_prompt_;
2172+ pam_handle* pam_handle_;
2173+ glib::Cancellable cancellable_;
2174+ glib::SourceManager source_manager_;
2175+};
2176+
2177+} // lockscreen
2178+} // unity
2179+
2180+#endif // UNITY_USER_AUTHENTICATOR_PAM_H
2181
2182=== added file 'lockscreen/UserPromptView.cpp'
2183--- lockscreen/UserPromptView.cpp 1970-01-01 00:00:00 +0000
2184+++ lockscreen/UserPromptView.cpp 2014-03-10 19:41:23 +0000
2185@@ -0,0 +1,282 @@
2186+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
2187+/*
2188+* Copyright (C) 2014 Canonical Ltd
2189+*
2190+* This program is free software: you can redistribute it and/or modify
2191+* it under the terms of the GNU General Public License version 3 as
2192+* published by the Free Software Foundation.
2193+*
2194+* This program is distributed in the hope that it will be useful,
2195+* but WITHOUT ANY WARRANTY; without even the implied warranty of
2196+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2197+* GNU General Public License for more details.
2198+*
2199+* You should have received a copy of the GNU General Public License
2200+* along with this program. If not, see <http://www.gnu.org/licenses/>.
2201+*
2202+* Authored by: Andrea Azzarone <andrea.azzarone@canonical.com>
2203+*/
2204+
2205+#include "UserPromptView.h"
2206+
2207+#include <boost/algorithm/string/trim.hpp>
2208+#include <Nux/VLayout.h>
2209+
2210+#include "LockScreenSettings.h"
2211+#include "unity-shared/CairoTexture.h"
2212+#include "unity-shared/TextInput.h"
2213+#include "unity-shared/StaticCairoText.h"
2214+#include "unity-shared/RawPixel.h"
2215+
2216+namespace unity
2217+{
2218+namespace lockscreen
2219+{
2220+namespace
2221+{
2222+const RawPixel PADDING = 10_em;
2223+const RawPixel LAYOUT_MARGIN = 10_em;
2224+const RawPixel MSG_LAYOUT_MARGIN = 15_em;
2225+const RawPixel PROMPT_LAYOUT_MARGIN = 5_em;
2226+const int PROMPT_FONT_SIZE = 13;
2227+
2228+nux::AbstractPaintLayer* CrateBackgroundLayer(int width, int height)
2229+{
2230+ nux::CairoGraphics cg(CAIRO_FORMAT_ARGB32, width, height);
2231+ cairo_t* cr = cg.GetInternalContext();
2232+
2233+ cairo_set_source_rgba(cr, 0.1, 0.1, 0.1, 0.4);
2234+
2235+ cg.DrawRoundedRectangle(cr,
2236+ 1.0,
2237+ 0, 0,
2238+ Settings::GRID_SIZE * 0.3,
2239+ width, height);
2240+
2241+ cairo_fill_preserve(cr);
2242+
2243+ cairo_set_source_rgba (cr, 0.4, 0.4, 0.4, 0.4);
2244+ cairo_set_line_width (cr, 1);
2245+ cairo_stroke (cr);
2246+
2247+ // Create the texture layer
2248+ nux::TexCoordXForm texxform;
2249+
2250+ nux::ROPConfig rop;
2251+ rop.Blend = true;
2252+ rop.SrcBlend = GL_ONE;
2253+ rop.DstBlend = GL_ONE_MINUS_SRC_ALPHA;
2254+
2255+ return (new nux::TextureLayer(texture_ptr_from_cairo_graphics(cg)->GetDeviceTexture(),
2256+ texxform,
2257+ nux::color::White,
2258+ true,
2259+ rop));
2260+}
2261+
2262+std::string SanitizeMessage(std::string const& message)
2263+{
2264+ std::string msg = boost::algorithm::trim_copy(message);
2265+
2266+ if (msg.empty())
2267+ return msg;
2268+
2269+ if (msg[msg.size()-1] == ':')
2270+ msg = msg.substr(0, msg.size()-1);
2271+
2272+ if (msg == "Password")
2273+ return _("Password");
2274+
2275+ if (msg == "login")
2276+ return _("Username");
2277+
2278+ return msg;
2279+}
2280+
2281+}
2282+
2283+UserPromptView::UserPromptView(session::Manager::Ptr const& session_manager)
2284+ : nux::View(NUX_TRACKER_LOCATION)
2285+ , session_manager_(session_manager)
2286+{
2287+ user_authenticator_.echo_on_requested.connect([this](std::string const& message, PromiseAuthCodePtr const& promise){
2288+ AddPrompt(message, /* visible */ true, promise);
2289+ });
2290+
2291+ user_authenticator_.echo_off_requested.connect([this](std::string const& message, PromiseAuthCodePtr const& promise){
2292+ AddPrompt(message, /* visible */ false, promise);
2293+ });
2294+
2295+ user_authenticator_.message_requested.connect([this](std::string const& message){
2296+ AddMessage(message, nux::color::White);
2297+ });
2298+
2299+ user_authenticator_.error_requested.connect([this](std::string const& message){
2300+ AddMessage(message, nux::color::Red);
2301+ });
2302+
2303+ user_authenticator_.clear_prompts.connect([this](){
2304+ ResetLayout();
2305+ });
2306+
2307+ ResetLayout();
2308+
2309+ user_authenticator_.AuthenticateStart(session_manager_->UserName(),
2310+ sigc::mem_fun(this, &UserPromptView::AuthenticationCb));
2311+}
2312+
2313+void UserPromptView::ResetLayout()
2314+{
2315+ focus_queue_.clear();
2316+
2317+ SetLayout(new nux::VLayout());
2318+
2319+ GetLayout()->SetLeftAndRightPadding(PADDING);
2320+ GetLayout()->SetTopAndBottomPadding(PADDING);
2321+ static_cast<nux::VLayout*>(GetLayout())->SetVerticalInternalMargin(LAYOUT_MARGIN);
2322+
2323+ auto const& real_name = session_manager_->RealName();
2324+ auto const& name = (real_name.empty() ? session_manager_->UserName() : real_name);
2325+
2326+ unity::StaticCairoText* username = new unity::StaticCairoText(name);
2327+ username->SetFont("Ubuntu "+std::to_string(PROMPT_FONT_SIZE));
2328+ GetLayout()->AddView(username);
2329+
2330+ msg_layout_ = new nux::VLayout();
2331+ msg_layout_->SetVerticalInternalMargin(MSG_LAYOUT_MARGIN);
2332+ msg_layout_->SetReconfigureParentLayoutOnGeometryChange(true);
2333+ GetLayout()->AddLayout(msg_layout_);
2334+
2335+ prompt_layout_ = new nux::VLayout();
2336+ prompt_layout_->SetVerticalInternalMargin(PROMPT_LAYOUT_MARGIN);
2337+ prompt_layout_->SetReconfigureParentLayoutOnGeometryChange(true);
2338+ GetLayout()->AddLayout(prompt_layout_);
2339+
2340+ QueueRelayout();
2341+ QueueDraw();
2342+}
2343+
2344+void UserPromptView::AuthenticationCb(bool authenticated)
2345+{
2346+ ResetLayout();
2347+
2348+ if (authenticated)
2349+ {
2350+ session_manager_->unlock_requested.emit();
2351+ }
2352+ else
2353+ {
2354+ AddMessage(_("Invalid password, please try again"), nux::color::Red);
2355+
2356+ user_authenticator_.AuthenticateStart(session_manager_->UserName(),
2357+ sigc::mem_fun(this, &UserPromptView::AuthenticationCb));
2358+ }
2359+}
2360+
2361+void UserPromptView::Draw(nux::GraphicsEngine& graphics_engine, bool /* force_draw */)
2362+{
2363+ nux::Geometry const& geo = GetGeometry();
2364+
2365+ graphics_engine.PushClippingRectangle(geo);
2366+ nux::GetPainter().PaintBackground(graphics_engine, geo);
2367+
2368+ bg_layer_.reset(CrateBackgroundLayer(geo.width, geo.height));
2369+ nux::GetPainter().PushDrawLayer(graphics_engine, geo, bg_layer_.get());
2370+
2371+ nux::GetPainter().PopBackground();
2372+ graphics_engine.PopClippingRectangle();
2373+}
2374+
2375+void UserPromptView::DrawContent(nux::GraphicsEngine& graphics_engine, bool force_draw)
2376+{
2377+ nux::Geometry const& geo = GetGeometry();
2378+ graphics_engine.PushClippingRectangle(geo);
2379+
2380+ if (!IsFullRedraw())
2381+ {
2382+ bg_layer_.reset(CrateBackgroundLayer(geo.width, geo.height));
2383+ nux::GetPainter().PushLayer(graphics_engine, geo, bg_layer_.get());
2384+ }
2385+
2386+ if (GetLayout())
2387+ GetLayout()->ProcessDraw(graphics_engine, force_draw);
2388+
2389+ if (!IsFullRedraw())
2390+ nux::GetPainter().PopBackground();
2391+
2392+ graphics_engine.PopClippingRectangle();
2393+}
2394+
2395+nux::View* UserPromptView::focus_view()
2396+{
2397+ if (focus_queue_.empty())
2398+ return nullptr;
2399+
2400+ for (auto* view : focus_queue_)
2401+ if (view->HasKeyboardFocus())
2402+ return view;
2403+
2404+ return focus_queue_.front();
2405+}
2406+
2407+void UserPromptView::AddPrompt(std::string const& message, bool visible, PromiseAuthCodePtr const& promise)
2408+{
2409+ auto* text_input = new unity::TextInput();
2410+ auto* text_entry = text_input->text_entry();
2411+
2412+ text_input->input_hint = SanitizeMessage(message);
2413+ text_input->hint_font_size = PROMPT_FONT_SIZE;
2414+ text_entry->SetPasswordMode(!visible);
2415+ text_entry->SetPasswordChar("•");
2416+ text_entry->SetToggleCursorVisibilityOnKeyFocus(true);
2417+
2418+ text_input->SetMinimumHeight(Settings::GRID_SIZE);
2419+ text_input->SetMaximumHeight(Settings::GRID_SIZE);
2420+ prompt_layout_->AddView(text_input, 1);
2421+ focus_queue_.push_back(text_entry);
2422+
2423+ // Don't remove it, it helps with a11y.
2424+ if (focus_queue_.size() == 1)
2425+ nux::GetWindowCompositor().SetKeyFocusArea(text_entry);
2426+
2427+ text_entry->activated.connect([this, text_input, promise](){
2428+ if (focus_queue_.size() == 1)
2429+ {
2430+ text_input->SetSpinnerVisible(true);
2431+ text_input->SetSpinnerState(STATE_SEARCHING);
2432+ }
2433+
2434+ focus_queue_.pop_front();
2435+ auto* text_entry = text_input->text_entry();
2436+ text_entry->SetInputEventSensitivity(false);
2437+ QueueRelayout();
2438+ QueueDraw();
2439+
2440+ std::string const& password = text_entry->GetText();
2441+ if (promise)
2442+ promise->set_value(password);
2443+ });
2444+
2445+ GetLayout()->ComputeContentPosition(0, 0);
2446+ ComputeContentSize();
2447+ QueueRelayout();
2448+ QueueDraw();
2449+}
2450+
2451+void UserPromptView::AddMessage(std::string const& message, nux::Color const& color)
2452+{
2453+ auto* view = new unity::StaticCairoText("");
2454+ view->SetFont(Settings::Instance().font_name());
2455+ view->SetTextColor(color);
2456+ view->SetText(message);
2457+
2458+ msg_layout_->AddView(view);
2459+
2460+ GetLayout()->ComputeContentPosition(0, 0);
2461+ ComputeContentSize();
2462+ QueueRelayout();
2463+ QueueDraw();
2464+}
2465+
2466+}
2467+}
2468
2469=== added file 'lockscreen/UserPromptView.h'
2470--- lockscreen/UserPromptView.h 1970-01-01 00:00:00 +0000
2471+++ lockscreen/UserPromptView.h 2014-03-10 19:41:23 +0000
2472@@ -0,0 +1,81 @@
2473+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
2474+/*
2475+* Copyright (C) 2014 Canonical Ltd
2476+*
2477+* This program is free software: you can redistribute it and/or modify
2478+* it under the terms of the GNU General Public License version 3 as
2479+* published by the Free Software Foundation.
2480+*
2481+* This program is distributed in the hope that it will be useful,
2482+* but WITHOUT ANY WARRANTY; without even the implied warranty of
2483+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2484+* GNU General Public License for more details.
2485+*
2486+* You should have received a copy of the GNU General Public License
2487+* along with this program. If not, see <http://www.gnu.org/licenses/>.
2488+*
2489+* Authored by: Andrea Azzarone <andrea.azzarone@canonical.com>
2490+*/
2491+
2492+#ifndef UNITY_USER_PROMPT_BOX
2493+#define UNITY_USER_PROMPT_BOX
2494+
2495+#include <memory>
2496+#include <deque>
2497+
2498+#include <Nux/Nux.h>
2499+#include <Nux/View.h>
2500+#include <UnityCore/SessionManager.h>
2501+
2502+#include "UserAuthenticatorPam.h"
2503+#include "unity-shared/IMTextEntry.h"
2504+#include "unity-shared/SearchBarSpinner.h"
2505+
2506+namespace nux
2507+{
2508+class VLayout;
2509+}
2510+
2511+namespace unity
2512+{
2513+
2514+class StaticCairoText;
2515+class TextInput;
2516+
2517+namespace lockscreen
2518+{
2519+
2520+class UserPromptView : public nux::View
2521+{
2522+public:
2523+ UserPromptView(session::Manager::Ptr const& session_manager);
2524+ ~UserPromptView() {};
2525+
2526+ nux::View* focus_view();
2527+
2528+ void AddPrompt(std::string const& message, bool visible, PromiseAuthCodePtr const&);
2529+ void AddMessage(std::string const& message, nux::Color const& color);
2530+ void AuthenticationCb(bool authenticated);
2531+
2532+protected:
2533+ void Draw(nux::GraphicsEngine& graphics_engine, bool force_draw) override;
2534+ void DrawContent(nux::GraphicsEngine& graphics_engine, bool force_draw) override;
2535+
2536+private:
2537+ void ResetLayout();
2538+
2539+ session::Manager::Ptr session_manager_;
2540+ UserAuthenticatorPam user_authenticator_;
2541+ std::shared_ptr<nux::AbstractPaintLayer> bg_layer_;
2542+ nux::VLayout* msg_layout_;
2543+ nux::VLayout* prompt_layout_;
2544+ StaticCairoText* message_;
2545+ StaticCairoText* error_;
2546+ StaticCairoText* invalid_login_;
2547+ std::deque<IMTextEntry*> focus_queue_;
2548+};
2549+
2550+}
2551+}
2552+
2553+#endif
2554
2555=== added directory 'lockscreen/pch'
2556=== added file 'lockscreen/pch/lockscreen_pch.hh'
2557--- lockscreen/pch/lockscreen_pch.hh 1970-01-01 00:00:00 +0000
2558+++ lockscreen/pch/lockscreen_pch.hh 2014-03-10 19:41:23 +0000
2559@@ -0,0 +1,31 @@
2560+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
2561+/*
2562+ * Copyright (C) 2013 Canonical Ltd
2563+ *
2564+ * This program is free software: you can redistribute it and/or modify
2565+ * it under the terms of the GNU General Public License version 3 as
2566+ * published by the Free Software Foundation.
2567+ *
2568+ * This program is distributed in the hope that it will be useful,
2569+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2570+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2571+ * GNU General Public License for more details.
2572+ *
2573+ * You should have received a copy of the GNU General Public License
2574+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2575+ *
2576+ * Authored by: Andrea Azzarone <andrea.azzarone@canonical.com>
2577+ */
2578+
2579+/*
2580+ * These are the precompiled header includes for this module.
2581+ * Only system header files can be listed here.
2582+ */
2583+
2584+#include <memory>
2585+#include <vector>
2586+#include <deque>
2587+#include <security/pam_appl.h>
2588+
2589+#include <Nux/Nux.h>
2590+#include <UnityCore/SessionManager.h>
2591\ No newline at end of file
2592
2593=== modified file 'panel/PanelIndicatorEntryView.cpp'
2594--- panel/PanelIndicatorEntryView.cpp 2014-02-28 15:01:24 +0000
2595+++ panel/PanelIndicatorEntryView.cpp 2014-03-10 19:41:23 +0000
2596@@ -387,7 +387,7 @@
2597 pango_layout_get_pixel_size(layout, &extents.width, &extents.height);
2598 int y = (height - extents.height) / 2;
2599
2600- if (overlay_showing_)
2601+ if (overlay_showing_ && !IsActive())
2602 {
2603 cairo_move_to(cr, x, y);
2604 cairo_set_source_rgb(cr, 1.0f, 1.0f, 1.0f);
2605
2606=== modified file 'panel/PanelIndicatorsView.cpp'
2607--- panel/PanelIndicatorsView.cpp 2014-02-25 02:38:26 +0000
2608+++ panel/PanelIndicatorsView.cpp 2014-03-10 19:41:23 +0000
2609@@ -42,6 +42,7 @@
2610 , opacity(1.0f, sigc::mem_fun(this, &PanelIndicatorsView::SetOpacity))
2611 , layout_(new nux::HLayout("", NUX_TRACKER_LOCATION))
2612 , monitor_(0)
2613+, overlay_showing_(false)
2614 {
2615 opacity.DisableNotifications();
2616 layout_->SetContentDistribution(nux::MAJOR_POSITION_END);
2617@@ -327,6 +328,9 @@
2618 auto view = new PanelIndicatorEntryView(entry, padding, type);
2619 AddEntryView(view, pos);
2620
2621+ if (overlay_showing_)
2622+ view->OverlayShown();
2623+
2624 return view;
2625 }
2626
2627@@ -368,12 +372,16 @@
2628
2629 void PanelIndicatorsView::OverlayShown()
2630 {
2631+ overlay_showing_ = true;
2632+
2633 for (auto const& entry: entries_)
2634 entry.second->OverlayShown();
2635 }
2636
2637 void PanelIndicatorsView::OverlayHidden()
2638 {
2639+ overlay_showing_ = false;
2640+
2641 for (auto const& entry: entries_)
2642 entry.second->OverlayHidden();
2643 }
2644
2645=== modified file 'panel/PanelIndicatorsView.h'
2646--- panel/PanelIndicatorsView.h 2014-02-18 04:47:43 +0000
2647+++ panel/PanelIndicatorsView.h 2014-03-10 19:41:23 +0000
2648@@ -98,6 +98,7 @@
2649 Entries entries_;
2650
2651 int monitor_;
2652+ bool overlay_showing_;
2653
2654 private:
2655 bool SetOpacity(double& target, double const& new_value);
2656
2657=== modified file 'panel/PanelMenuView.cpp'
2658--- panel/PanelMenuView.cpp 2014-02-27 05:45:23 +0000
2659+++ panel/PanelMenuView.cpp 2014-03-10 19:41:23 +0000
2660@@ -64,7 +64,6 @@
2661 , is_desktop_focused_(false)
2662 , last_active_view_(nullptr)
2663 , new_application_(nullptr)
2664- , overlay_showing_(false)
2665 , switcher_showing_(false)
2666 , spread_showing_(false)
2667 , launcher_keynav_(false)
2668
2669=== modified file 'panel/PanelMenuView.h'
2670--- panel/PanelMenuView.h 2014-02-27 05:45:23 +0000
2671+++ panel/PanelMenuView.h 2014-03-10 19:41:23 +0000
2672@@ -176,7 +176,6 @@
2673 nux::Geometry last_geo_;
2674 nux::Geometry title_geo_;
2675
2676- bool overlay_showing_;
2677 bool switcher_showing_;
2678 bool spread_showing_;
2679 bool launcher_keynav_;
2680
2681=== modified file 'panel/PanelView.cpp'
2682--- panel/PanelView.cpp 2014-02-25 22:10:53 +0000
2683+++ panel/PanelView.cpp 2014-03-10 19:41:23 +0000
2684@@ -19,20 +19,11 @@
2685 */
2686
2687 #include <Nux/Nux.h>
2688-#include <Nux/BaseWindow.h>
2689 #include <Nux/HLayout.h>
2690-#include <Nux/Layout.h>
2691-#include <Nux/WindowCompositor.h>
2692
2693-#include <NuxGraphics/CairoGraphics.h>
2694 #include <NuxCore/Logger.h>
2695 #include <UnityCore/GLibWrapper.h>
2696
2697-#include <NuxGraphics/GLThread.h>
2698-#include <NuxGraphics/RenderingPipe.h>
2699-
2700-#include <glib.h>
2701-
2702 #include "unity-shared/PanelStyle.h"
2703 #include "unity-shared/TextureCache.h"
2704 #include "unity-shared/WindowManager.h"
2705@@ -556,7 +547,11 @@
2706 {
2707 View::PreLayoutManagement();
2708
2709- int menu_width = GetMaximumWidth() - indicators_->GetBaseWidth() - tray_->GetBaseWidth();
2710+ int tray_width = 0;
2711+ if (tray_)
2712+ tray_width = tray_->GetBaseWidth();
2713+
2714+ int menu_width = GetMaximumWidth() - indicators_->GetBaseWidth() - tray_width;
2715
2716 menu_view_->SetMinimumWidth(menu_width);
2717 menu_view_->SetMaximumWidth(menu_width);
2718
2719=== modified file 'plugins/unityshell/CMakeLists.txt'
2720--- plugins/unityshell/CMakeLists.txt 2013-12-16 14:19:38 +0000
2721+++ plugins/unityshell/CMakeLists.txt 2014-03-10 19:41:23 +0000
2722@@ -13,7 +13,7 @@
2723 compiz_plugin (unityshell
2724 PKGDEPS ${UNITY_PLUGIN_DEPS}
2725 PLUGINDEPS composite opengl compiztoolbox scale
2726- 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/"
2727+ 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/"
2728 LIBDIRS "${CMAKE_BINARY_DIR}/UnityCore"
2729 )
2730
2731@@ -26,6 +26,8 @@
2732 decorations-lib
2733 hud-lib
2734 launcher-lib
2735+ pam
2736+ lockscreen-lib
2737 panel-lib
2738 shortcuts-lib
2739 shutdown-lib
2740@@ -39,6 +41,8 @@
2741 decorations-lib
2742 hud-lib
2743 launcher-lib
2744+ pam
2745+ lockscreen-lib
2746 panel-lib
2747 shortcuts-lib
2748 shutdown-lib
2749
2750=== modified file 'plugins/unityshell/src/nux-text-entry-accessible.cpp'
2751--- plugins/unityshell/src/nux-text-entry-accessible.cpp 2011-09-15 13:58:42 +0000
2752+++ plugins/unityshell/src/nux-text-entry-accessible.cpp 2014-03-10 19:41:23 +0000
2753@@ -48,36 +48,19 @@
2754 G_DEFINE_TYPE(NuxTextEntryAccessible, nux_text_entry_accessible, NUX_TYPE_VIEW_ACCESSIBLE);
2755
2756
2757-#define NUX_TEXT_ENTRY_ACCESSIBLE_GET_PRIVATE(obj) \
2758- (G_TYPE_INSTANCE_GET_PRIVATE ((obj), NUX_TYPE_TEXT_ENTRY_ACCESSIBLE, \
2759- NuxTextEntryAccessiblePrivate))
2760-
2761-struct _NuxTextEntryAccessiblePrivate
2762-{
2763-};
2764-
2765-
2766 static void
2767 nux_text_entry_accessible_class_init(NuxTextEntryAccessibleClass* klass)
2768 {
2769- GObjectClass* gobject_class = G_OBJECT_CLASS(klass);
2770 AtkObjectClass* atk_class = ATK_OBJECT_CLASS(klass);
2771
2772 /* AtkObject */
2773 atk_class->ref_state_set = nux_text_entry_accessible_ref_state_set;
2774 atk_class->initialize = nux_text_entry_accessible_initialize;
2775-
2776- g_type_class_add_private(gobject_class, sizeof(NuxTextEntryAccessiblePrivate));
2777 }
2778
2779 static void
2780 nux_text_entry_accessible_init(NuxTextEntryAccessible* self)
2781-{
2782- NuxTextEntryAccessiblePrivate* priv =
2783- NUX_TEXT_ENTRY_ACCESSIBLE_GET_PRIVATE(self);
2784-
2785- self->priv = priv;
2786-}
2787+{}
2788
2789 AtkObject*
2790 nux_text_entry_accessible_new(nux::Object* object)
2791@@ -98,9 +81,15 @@
2792 nux_text_entry_accessible_initialize(AtkObject* accessible,
2793 gpointer data)
2794 {
2795+ nux::Object* nux_object = NULL;
2796+ nux::TextEntry* text_entry = NULL;
2797+
2798 ATK_OBJECT_CLASS(nux_text_entry_accessible_parent_class)->initialize(accessible, data);
2799
2800- atk_object_set_role(accessible, ATK_ROLE_ENTRY);
2801+ nux_object = nux_object_accessible_get_object(NUX_OBJECT_ACCESSIBLE(accessible));
2802+ text_entry = dynamic_cast<nux::TextEntry*>(nux_object);
2803+
2804+ atk_object_set_role(accessible, text_entry->PasswordMode() ? ATK_ROLE_PASSWORD_TEXT : ATK_ROLE_ENTRY);
2805 }
2806
2807 static AtkStateSet*
2808
2809=== added file 'plugins/unityshell/src/unity-text-input-accessible.cpp'
2810--- plugins/unityshell/src/unity-text-input-accessible.cpp 1970-01-01 00:00:00 +0000
2811+++ plugins/unityshell/src/unity-text-input-accessible.cpp 2014-03-10 19:41:23 +0000
2812@@ -0,0 +1,90 @@
2813+/*
2814+ * Copyright (C) 2014 Canonical Ltd
2815+ *
2816+ * This program is free software: you can redistribute it and/or modify
2817+ * it under the terms of the GNU General Public License version 3 as
2818+ * published by the Free Software Foundation.
2819+ *
2820+ * This program is distributed in the hope that it will be useful,
2821+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2822+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2823+ * GNU General Public License for more details.
2824+ *
2825+ * You should have received a copy of the GNU General Public License
2826+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2827+ *
2828+ * Authored by: Andrea Azzarone <andrea.azzarone@canonical.com>
2829+ */
2830+
2831+#include "unity-text-input-accessible.h"
2832+
2833+#include "unitya11y.h"
2834+#include "TextInput.h"
2835+
2836+using namespace unity;
2837+
2838+/* GObject */
2839+static void unity_text_input_accessible_class_init(UnityTextInputAccessibleClass* klass);
2840+static void unity_text_input_accessible_init(UnityTextInputAccessible* self);
2841+//static void unity_text_input_accessible_finalize(GObject* object);
2842+
2843+/* AtkObject.h */
2844+static void unity_text_input_accessible_initialize(AtkObject* accessible,
2845+ gpointer data);
2846+
2847+G_DEFINE_TYPE(UnityTextInputAccessible, unity_text_input_accessible, NUX_TYPE_VIEW_ACCESSIBLE)
2848+
2849+static void
2850+unity_text_input_accessible_class_init(UnityTextInputAccessibleClass* klass)
2851+{
2852+ AtkObjectClass* atk_class = ATK_OBJECT_CLASS(klass);
2853+
2854+ /* AtkObject */
2855+ atk_class->initialize = unity_text_input_accessible_initialize;
2856+}
2857+
2858+static void
2859+unity_text_input_accessible_init(UnityTextInputAccessible* self)
2860+{}
2861+
2862+AtkObject*
2863+unity_text_input_accessible_new(nux::Object* object)
2864+{
2865+ AtkObject* accessible = NULL;
2866+
2867+ g_return_val_if_fail(dynamic_cast<TextInput*>(object), NULL);
2868+
2869+ accessible = ATK_OBJECT(g_object_new(UNITY_TYPE_TEXT_INPUT_ACCESSIBLE, NULL));
2870+
2871+ atk_object_initialize(accessible, object);
2872+
2873+ return accessible;
2874+}
2875+
2876+static void
2877+unity_text_input_accessible_initialize(AtkObject* accessible,
2878+ gpointer data)
2879+{
2880+ nux::Object* nux_object = NULL;
2881+ TextInput* text_input = NULL;
2882+ nux::TextEntry* text_entry = NULL;
2883+
2884+ ATK_OBJECT_CLASS(unity_text_input_accessible_parent_class)->initialize(accessible, data);
2885+
2886+ accessible->role = ATK_ROLE_PANEL;
2887+
2888+ nux_object = nux_object_accessible_get_object(NUX_OBJECT_ACCESSIBLE(accessible));
2889+ text_input = dynamic_cast<TextInput*>(nux_object);
2890+
2891+ if (text_input == NULL)
2892+ return;
2893+
2894+ text_entry = text_input->text_entry();
2895+
2896+ if (text_entry != NULL)
2897+ {
2898+ AtkObject* text_entry_accessible = NULL;
2899+ text_entry_accessible = unity_a11y_get_accessible(text_entry);
2900+ atk_object_set_name(text_entry_accessible, text_input->input_hint().c_str());
2901+ }
2902+}
2903
2904=== added file 'plugins/unityshell/src/unity-text-input-accessible.h'
2905--- plugins/unityshell/src/unity-text-input-accessible.h 1970-01-01 00:00:00 +0000
2906+++ plugins/unityshell/src/unity-text-input-accessible.h 2014-03-10 19:41:23 +0000
2907@@ -0,0 +1,57 @@
2908+/*
2909+ * Copyright (C) 2014 Canonical Ltd
2910+ *
2911+ * This program is free software: you can redistribute it and/or modify
2912+ * it under the terms of the GNU General Public License version 3 as
2913+ * published by the Free Software Foundation.
2914+ *
2915+ * This program is distributed in the hope that it will be useful,
2916+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2917+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2918+ * GNU General Public License for more details.
2919+ *
2920+ * You should have received a copy of the GNU General Public License
2921+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2922+ *
2923+ * Authored by: Andrea Azzarone <andrea.azzarone@canonical.com>
2924+ */
2925+
2926+#ifndef UNITY_TEXT_INPUT_ACCESSIBLE_H
2927+#define UNITY_TEXT_INPUT_ACCESSIBLE_H
2928+
2929+#include <atk/atk.h>
2930+
2931+#include "nux-view-accessible.h"
2932+
2933+G_BEGIN_DECLS
2934+
2935+#define UNITY_TYPE_TEXT_INPUT_ACCESSIBLE (unity_text_input_accessible_get_type ())
2936+#define UNITY_TEXT_INPUT_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), UNITY_TYPE_TEXT_INPUT_ACCESSIBLE, UnityTextInputAccessible))
2937+#define UNITY_TEXT_INPUT_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), UNITY_TYPE_TEXT_INPUT_ACCESSIBLE, UnityTextInputAccessibleClass))
2938+#define UNITY_IS_TEXT_INPUT_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), UNITY_TYPE_TEXT_INPUT_ACCESSIBLE))
2939+#define UNITY_IS_TEXT_INPUT_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), UNITY_TYPE_TEXT_INPUT_ACCESSIBLE))
2940+#define UNITY_TEXT_INPUT_ACCESSIBLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), UNITY_TYPE_TEXT_INPUT_ACCESSIBLE, UnityTextInputAccessibleClass))
2941+
2942+typedef struct _UnityTextInputAccessible UnityTextInputAccessible;
2943+typedef struct _UnityTextInputAccessibleClass UnityTextInputAccessibleClass;
2944+typedef struct _UnityTextInputAccessiblePrivate UnityTextInputAccessiblePrivate;
2945+
2946+struct _UnityTextInputAccessible
2947+{
2948+ NuxViewAccessible parent;
2949+
2950+ /*< private >*/
2951+ UnityTextInputAccessiblePrivate* priv;
2952+};
2953+
2954+struct _UnityTextInputAccessibleClass
2955+{
2956+ NuxViewAccessibleClass parent_class;
2957+};
2958+
2959+GType unity_text_input_accessible_get_type(void);
2960+AtkObject* unity_text_input_accessible_new(nux::Object* object);
2961+
2962+G_END_DECLS
2963+
2964+#endif
2965
2966=== modified file 'plugins/unityshell/src/unitya11y.cpp'
2967--- plugins/unityshell/src/unitya11y.cpp 2014-02-19 04:15:22 +0000
2968+++ plugins/unityshell/src/unitya11y.cpp 2014-03-10 19:41:23 +0000
2969@@ -42,6 +42,7 @@
2970 #include "QuicklistView.h"
2971 #include "QuicklistMenuItem.h"
2972 #include "SwitcherView.h"
2973+#include "TextInput.h"
2974 #include "SessionButton.h"
2975 #include "unity-launcher-accessible.h"
2976 #include "unity-launcher-icon-accessible.h"
2977@@ -54,6 +55,7 @@
2978 #include "unity-quicklist-accessible.h"
2979 #include "unity-quicklist-menu-item-accessible.h"
2980 #include "unity-switcher-accessible.h"
2981+#include "unity-text-input-accessible.h"
2982 #include "unity-session-button-accessible.h"
2983
2984 using namespace unity;
2985@@ -187,6 +189,9 @@
2986 if (object->Type().IsDerivedFromType(unity::SearchBar::StaticObjectType))
2987 return unity_search_bar_accessible_new(object);
2988
2989+ if (object->Type().IsDerivedFromType(unity::TextInput::StaticObjectType))
2990+ return unity_text_input_accessible_new(object);
2991+
2992 if (object->Type().IsDerivedFromType(unity::switcher::SwitcherView::StaticObjectType))
2993 return unity_switcher_accessible_new(object);
2994
2995
2996=== modified file 'plugins/unityshell/src/unityshell.cpp'
2997--- plugins/unityshell/src/unityshell.cpp 2014-02-28 19:36:29 +0000
2998+++ plugins/unityshell/src/unityshell.cpp 2014-03-10 19:41:23 +0000
2999@@ -338,12 +338,14 @@
3000 optionSetShowDesktopKeyInitiate(boost::bind(&UnityScreen::showDesktopKeyInitiate, this, _1, _2, _3));
3001 optionSetPanelFirstMenuInitiate(boost::bind(&UnityScreen::showPanelFirstMenuKeyInitiate, this, _1, _2, _3));
3002 optionSetPanelFirstMenuTerminate(boost::bind(&UnityScreen::showPanelFirstMenuKeyTerminate, this, _1, _2, _3));
3003+ optionSetPanelFirstMenuNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2));
3004 optionSetAutomaximizeValueNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2));
3005 optionSetDashTapDurationNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2));
3006 optionSetAltTabTimeoutNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2));
3007 optionSetAltTabBiasViewportNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2));
3008 optionSetDisableShowDesktopNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2));
3009 optionSetDisableMouseNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2));
3010+ optionSetLockScreenTypeNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2));
3011
3012 optionSetAltTabForwardAllInitiate(boost::bind(&UnityScreen::altTabForwardAllInitiate, this, _1, _2, _3));
3013 optionSetAltTabForwardInitiate(boost::bind(&UnityScreen::altTabForwardInitiate, this, _1, _2, _3));
3014@@ -2003,6 +2005,9 @@
3015 CompAction::State state,
3016 CompOption::Vector& options)
3017 {
3018+ if (lockscreen_controller_->IsLocked())
3019+ return true;
3020+
3021 // to receive the Terminate event
3022 if (state & CompAction::StateInitKey)
3023 action->setState(action->state() | CompAction::StateTermKey);
3024@@ -2012,7 +2017,8 @@
3025 launcher_controller_->HandleLauncherKeyPress(when);
3026 EnsureSuperKeybindings ();
3027
3028- if (!shortcut_controller_->Visible() && shortcut_controller_->IsEnabled())
3029+ if (!shortcut_controller_->Visible() &&
3030+ shortcut_controller_->IsEnabled())
3031 {
3032 if (shortcut_controller_->Show())
3033 {
3034@@ -2434,7 +2440,8 @@
3035 return false; // early exit if the switcher is open
3036 }
3037
3038- if (PluginAdapter::Default().IsTopWindowFullscreenOnMonitorWithMouse())
3039+ if (PluginAdapter::Default().IsTopWindowFullscreenOnMonitorWithMouse() ||
3040+ lockscreen_controller_->IsLocked())
3041 {
3042 return false;
3043 }
3044@@ -2521,7 +2528,11 @@
3045 CompAction::State state,
3046 CompOption::Vector& options)
3047 {
3048- session_controller_->LockScreen();
3049+ sources_.AddIdle([this] {
3050+ session_controller_->LockScreen();
3051+ return false;
3052+ });
3053+
3054 return true;
3055 }
3056
3057@@ -2572,6 +2583,15 @@
3058 WindowManager::Default().close_window_key = std::make_pair(modifiers, keysym);
3059 }
3060
3061+void UnityScreen::UpdateActivateIndicatorsKey()
3062+{
3063+ CompAction::KeyBinding const& keybind = optionGetPanelFirstMenu().key();
3064+ KeySym keysym = XkbKeycodeToKeysym(screen->dpy(), keybind.keycode(), 0, 0);
3065+ unsigned modifiers = CompizModifiersToNux(keybind.modifiers());
3066+
3067+ WindowManager::Default().activate_indicators_key = std::make_pair(modifiers, keysym);
3068+}
3069+
3070 bool UnityScreen::initPluginActions()
3071 {
3072 PluginAdapter& adapter = PluginAdapter::Default();
3073@@ -2800,6 +2820,23 @@
3074
3075 GLWindowPaintAttrib wAttrib = attrib;
3076
3077+ if (window->type() != CompWindowTypePopupMenuMask)
3078+ {
3079+ if (uScreen->lockscreen_controller_->IsLocked())
3080+ {
3081+ // For some reasons PAINT_WINDOW_NO_CORE_INSTANCE_MASK doesn't work here
3082+ // (well, it works too much, as it applies to menus too), so we need
3083+ // to paint the windows at the proper opacity, overriding any other
3084+ // paint plugin (animation, fade?) that might interfere with us.
3085+ wAttrib.opacity = COMPIZ_COMPOSITE_OPAQUE * (1.0f - uScreen->lockscreen_controller_->Opacity());
3086+ int old_index = gWindow->glPaintGetCurrentIndex();
3087+ gWindow->glPaintSetCurrentIndex(MAXSHORT);
3088+ bool ret = gWindow->glPaint(wAttrib, matrix, region, mask);
3089+ gWindow->glPaintSetCurrentIndex(old_index);
3090+ return ret;
3091+ }
3092+ }
3093+
3094 if (mMinimizeHandler)
3095 {
3096 mask |= mMinimizeHandler->getPaintMask ();
3097@@ -2828,7 +2865,7 @@
3098 paintInnerGlow(scaled_geo, matrix, attrib, mask);
3099 }
3100
3101- if (uScreen->session_controller_ && uScreen->session_controller_->Visible())
3102+ if (uScreen->session_controller_->Visible())
3103 {
3104 // Let's darken the other windows if the session dialog is visible
3105 wAttrib.brightness *= 0.75f;
3106@@ -3480,6 +3517,12 @@
3107 case UnityshellOptions::EdgePassedDisabledMs:
3108 launcher_options->edge_passed_disabled_ms = optionGetEdgePassedDisabledMs();
3109 break;
3110+ case UnityshellOptions::LockScreenType:
3111+ lockscreen_settings_.lockscreen_type = static_cast<lockscreen::Type>(optionGetLockScreenType());
3112+ break;
3113+ case UnityshellOptions::PanelFirstMenu:
3114+ UpdateActivateIndicatorsKey();
3115+ break;
3116 default:
3117 break;
3118 }
3119@@ -3622,9 +3665,14 @@
3120
3121 // Setup Session Controller
3122 auto manager = std::make_shared<session::GnomeManager>();
3123+ session_dbus_manager_ = std::make_shared<session::DBusManager>(manager);
3124 session_controller_ = std::make_shared<session::Controller>(manager);
3125 AddChild(session_controller_.get());
3126
3127+ // Setup Lockscreen Controller
3128+ lockscreen_controller_ = std::make_shared<lockscreen::Controller>(manager);
3129+ UpdateActivateIndicatorsKey();
3130+
3131 auto on_launcher_size_changed = [this] (nux::Area* area, int w, int h) {
3132 /* The launcher geometry includes 1px used to draw the right margin
3133 * that must not be considered when drawing an overlay */
3134
3135=== modified file 'plugins/unityshell/src/unityshell.h'
3136--- plugins/unityshell/src/unityshell.h 2014-02-24 18:21:09 +0000
3137+++ plugins/unityshell/src/unityshell.h 2014-03-10 19:41:23 +0000
3138@@ -58,6 +58,8 @@
3139 #include "FontSettings.h"
3140 #include "ShortcutController.h"
3141 #include "LauncherController.h"
3142+#include "LockScreenController.h"
3143+#include "LockScreenSettings.h"
3144 #include "PanelController.h"
3145 #include "PanelStyle.h"
3146 #include "UScreen.h"
3147@@ -65,6 +67,7 @@
3148 #include "ScreenIntrospection.h"
3149 #include "SwitcherController.h"
3150 #include "SessionController.h"
3151+#include "SessionDBusManager.h"
3152 #include "SpreadFilter.h"
3153 #include "UBusWrapper.h"
3154 #include "UnityshellPrivate.h"
3155@@ -297,6 +300,7 @@
3156 unsigned XModifiersToNux(unsigned input) const;
3157
3158 void UpdateCloseWindowKey(CompAction::KeyBinding const&);
3159+ void UpdateActivateIndicatorsKey();
3160
3161 bool getMipmap () override { return false; }
3162
3163@@ -311,6 +315,7 @@
3164 FontSettings font_settings_;
3165 internal::FavoriteStoreGSettings favorite_store_;
3166 ThumbnailGenerator thumbnail_generator_;
3167+ lockscreen::Settings lockscreen_settings_;
3168
3169 /* The window thread should be the last thing removed, as c++ does it in reverse order */
3170 std::unique_ptr<nux::WindowThread> wt;
3171@@ -326,7 +331,9 @@
3172 switcher::Controller::Ptr switcher_controller_;
3173 hud::Controller::Ptr hud_controller_;
3174 shortcut::Controller::Ptr shortcut_controller_;
3175+ session::DBusManager::Ptr session_dbus_manager_;
3176 session::Controller::Ptr session_controller_;
3177+ std::shared_ptr<lockscreen::Controller> lockscreen_controller_;
3178 debug::DebugDBusInterface debugger_;
3179 std::unique_ptr<BGHash> bghash_;
3180 spread::Filter::Ptr spread_filter_;
3181
3182=== modified file 'plugins/unityshell/unityshell.xml.in'
3183--- plugins/unityshell/unityshell.xml.in 2014-02-25 09:33:43 +0000
3184+++ plugins/unityshell/unityshell.xml.in 2014-03-10 19:41:23 +0000
3185@@ -146,6 +146,26 @@
3186 <_long>Enables possibility to display an overlay showing available mouse and keyboard shortcuts.</_long>
3187 <default>true</default>
3188 </option>
3189+
3190+ <option name="lock_screen_type" type="int">
3191+ <_short>Lockscreen</_short>
3192+ <_long>Set how Unity should handle lockscreen.</_long>
3193+ <min>0</min>
3194+ <max>2</max>
3195+ <default>2</default>
3196+ <desc>
3197+ <value>0</value>
3198+ <_name>None</_name>
3199+ </desc>
3200+ <desc>
3201+ <value>1</value>
3202+ <_name>Lightdm</_name>
3203+ </desc>
3204+ <desc>
3205+ <value>2</value>
3206+ <_name>Unity</_name>
3207+ </desc>
3208+ </option>
3209 </group>
3210
3211 <group>
3212
3213=== modified file 'po/POTFILES.in'
3214--- po/POTFILES.in 2013-05-10 10:07:04 +0000
3215+++ po/POTFILES.in 2014-03-10 19:41:23 +0000
3216@@ -24,6 +24,7 @@
3217 launcher/SpacerLauncherIcon.cpp
3218 launcher/TrashLauncherIcon.cpp
3219 launcher/VolumeLauncherIcon.cpp
3220+lockscreen/UserPromptView.cpp
3221 panel/PanelMenuView.cpp
3222 plugins/networkarearegion/networkarearegion.xml.in
3223 plugins/unity-mt-grab-handles/unitymtgrabhandles.xml.in
3224
3225=== added file 'resources/cof.png'
3226Binary files resources/cof.png 1970-01-01 00:00:00 +0000 and resources/cof.png 2014-03-10 19:41:23 +0000 differ
3227=== modified file 'services/CMakeLists.txt'
3228--- services/CMakeLists.txt 2013-08-07 16:37:05 +0000
3229+++ services/CMakeLists.txt 2014-03-10 19:41:23 +0000
3230@@ -58,3 +58,6 @@
3231
3232 configure_file(unity-panel-service.conf.in ${CMAKE_CURRENT_BINARY_DIR}/unity-panel-service.conf)
3233 install(FILES ${CMAKE_CURRENT_BINARY_DIR}/unity-panel-service.conf DESTINATION ${CMAKE_INSTALL_PREFIX}/share/upstart/sessions)
3234+
3235+configure_file(unity-panel-service-lockscreen.conf.in ${CMAKE_CURRENT_BINARY_DIR}/unity-panel-service-lockscreen.conf)
3236+install(FILES ${CMAKE_CURRENT_BINARY_DIR}/unity-panel-service-lockscreen.conf DESTINATION ${CMAKE_INSTALL_PREFIX}/share/upstart/sessions)
3237
3238=== modified file 'services/panel-main.c'
3239--- services/panel-main.c 2014-02-28 05:13:02 +0000
3240+++ services/panel-main.c 2014-03-10 19:41:23 +0000
3241@@ -106,7 +106,8 @@
3242 " </interface>"
3243 "</node>";
3244
3245-#define S_NAME "com.canonical.Unity.Panel.Service"
3246+#define S_NAME_DESKTOP "com.canonical.Unity.Panel.Service.Desktop"
3247+#define S_NAME_LOCKSCREEN "com.canonical.Unity.Panel.Service.LockScreen"
3248 #define S_PATH "/com/canonical/Unity/Panel/Service"
3249 #define S_IFACE "com.canonical.Unity.Panel.Service"
3250
3251@@ -440,6 +441,13 @@
3252 {
3253 PanelService *service;
3254 guint owner_id;
3255+ gboolean lockscreen_mode = FALSE;
3256+ GError *error = NULL;
3257+ GOptionContext *context;
3258+ GOptionEntry entries[] = {
3259+ { "lockscreen-mode", 0, 0, G_OPTION_ARG_NONE, &lockscreen_mode, "Load indicators for the lockscreen", NULL },
3260+ { NULL }};
3261+
3262
3263 g_unsetenv ("UBUNTU_MENUPROXY");
3264 g_setenv ("NO_AT_BRIDGE", "1", TRUE);
3265@@ -449,6 +457,17 @@
3266 gtk_icon_theme_append_search_path (gtk_icon_theme_get_default(), INDICATORICONDIR);
3267 ido_init ();
3268
3269+ context = g_option_context_new ("- Unity Panel Service");
3270+ g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE);
3271+ if (!g_option_context_parse (context, &argc, &argv, &error))
3272+ {
3273+ g_print ("unity-panel-service: %s\n", error->message);
3274+ g_print ("Try --help for more information.\n");
3275+ return 1;
3276+ }
3277+
3278+ panel_service_set_lockscreen_mode (lockscreen_mode);
3279+
3280 if (g_getenv ("SILENT_PANEL_SERVICE") != NULL)
3281 {
3282 g_log_set_default_handler (discard_log_message, NULL);
3283@@ -462,7 +481,7 @@
3284 service = panel_service_get_default ();
3285
3286 owner_id = g_bus_own_name (G_BUS_TYPE_SESSION,
3287- S_NAME,
3288+ !lockscreen_mode ? S_NAME_DESKTOP : S_NAME_LOCKSCREEN,
3289 G_BUS_NAME_OWNER_FLAGS_NONE,
3290 on_bus_acquired,
3291 on_name_acquired,
3292
3293=== modified file 'services/panel-service.c'
3294--- services/panel-service.c 2014-03-03 11:00:27 +0000
3295+++ services/panel-service.c 2014-03-10 19:41:23 +0000
3296@@ -53,6 +53,7 @@
3297 #define SHOW_HUD_KEY "show-hud"
3298
3299 static PanelService *static_service = NULL;
3300+static gboolean lockscreen_mode = FALSE;
3301
3302 struct _PanelServicePrivate
3303 {
3304@@ -150,7 +151,7 @@
3305 g_idle_remove_by_data (self);
3306 gdk_window_remove_filter (NULL, (GdkFilterFunc)event_filter, self);
3307
3308- if (priv->upstart != NULL)
3309+ if (priv->upstart != NULL && !lockscreen_mode)
3310 {
3311 int event_sent = 0;
3312 event_sent = upstart_emit_event_sync (NULL, priv->upstart,
3313@@ -461,6 +462,9 @@
3314 {
3315 case XI_KeyPress:
3316 {
3317+ if (lockscreen_mode)
3318+ break;
3319+
3320 KeySym keysym = XkbKeycodeToKeysym (event->display, event->detail, 0, 0);
3321
3322 if (event_matches_keybinding (event->mods.base, keysym, &priv->menu_toggle) ||
3323@@ -586,7 +590,7 @@
3324 static gboolean
3325 ready_signal (PanelService *self)
3326 {
3327- if (PANEL_IS_SERVICE (self) && self->priv->upstart != NULL)
3328+ if (PANEL_IS_SERVICE (self) && self->priv->upstart != NULL && !lockscreen_mode)
3329 {
3330 int event_sent = 0;
3331 event_sent = upstart_emit_event_sync (NULL, self->priv->upstart, "indicator-services-start", NULL, 0);
3332@@ -714,7 +718,7 @@
3333 update_keybinding (priv->gsettings, SHOW_HUD_KEY, &priv->show_hud);
3334
3335 const gchar *upstartsession = g_getenv ("UPSTART_SESSION");
3336- if (upstartsession != NULL)
3337+ if (upstartsession != NULL && !lockscreen_mode)
3338 {
3339 DBusConnection *conn = dbus_connection_open (upstartsession, NULL);
3340 if (conn != NULL)
3341@@ -859,7 +863,11 @@
3342
3343 if (!indicators)
3344 {
3345- load_indicators (self);
3346+ if (!lockscreen_mode)
3347+ {
3348+ load_indicators (self);
3349+ }
3350+
3351 load_indicators_from_indicator_files (self);
3352 sort_indicators (self);
3353 }
3354@@ -908,6 +916,12 @@
3355 return self;
3356 }
3357
3358+void
3359+panel_service_set_lockscreen_mode (gboolean enable)
3360+{
3361+ lockscreen_mode = enable;
3362+}
3363+
3364 guint
3365 panel_service_get_n_indicators (PanelService *self)
3366 {
3367@@ -1313,7 +1327,7 @@
3368 IndicatorNg *indicator;
3369
3370 filename = g_build_filename (INDICATOR_SERVICE_DIR, name, NULL);
3371- indicator = indicator_ng_new_for_profile (filename, "desktop", &error);
3372+ indicator = indicator_ng_new_for_profile (filename, !lockscreen_mode ? "desktop" : "desktop_greeter", &error);
3373 if (indicator)
3374 {
3375 load_indicator (self, INDICATOR_OBJECT (indicator), name);
3376
3377=== modified file 'services/panel-service.h'
3378--- services/panel-service.h 2014-01-28 11:47:04 +0000
3379+++ services/panel-service.h 2014-03-10 19:41:23 +0000
3380@@ -71,6 +71,8 @@
3381 PanelService * panel_service_get_default ();
3382 PanelService * panel_service_get_default_with_indicators (GList *indicators);
3383
3384+void panel_service_set_lockscreen_mode (gboolean enable);
3385+
3386 guint panel_service_get_n_indicators (PanelService *self);
3387
3388 IndicatorObject * panel_service_get_indicator_nth (PanelService *self, guint position);
3389
3390=== added file 'services/unity-panel-service-lockscreen.conf.in'
3391--- services/unity-panel-service-lockscreen.conf.in 1970-01-01 00:00:00 +0000
3392+++ services/unity-panel-service-lockscreen.conf.in 2014-03-10 19:41:23 +0000
3393@@ -0,0 +1,8 @@
3394+description "Backing Service for the Unity Panel"
3395+author "Andrea Azzarone <andrea.azzarone@canonical.com>"
3396+
3397+start on desktop-lock
3398+stop on desktop-unlock
3399+
3400+respawn
3401+exec ${CMAKE_INSTALL_PREFIX}/lib/unity/unity-panel-service --lockscreen-mode
3402\ No newline at end of file
3403
3404=== modified file 'shutdown/CMakeLists.txt'
3405--- shutdown/CMakeLists.txt 2013-02-17 23:55:54 +0000
3406+++ shutdown/CMakeLists.txt 2014-03-10 19:41:23 +0000
3407@@ -19,6 +19,7 @@
3408 set (SHUTDOWN_SOURCES
3409 SessionButton.cpp
3410 SessionController.cpp
3411+ SessionDBusManager.cpp
3412 SessionView.cpp
3413 )
3414
3415
3416=== added file 'shutdown/SessionDBusManager.cpp'
3417--- shutdown/SessionDBusManager.cpp 1970-01-01 00:00:00 +0000
3418+++ shutdown/SessionDBusManager.cpp 2014-03-10 19:41:23 +0000
3419@@ -0,0 +1,180 @@
3420+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
3421+/*
3422+ * Copyright (C) 2014 Canonical Ltd
3423+ *
3424+ * This program is free software: you can redistribute it and/or modify
3425+ * it under the terms of the GNU General Public License version 3 as
3426+ * published by the Free Software Foundation.
3427+ *
3428+ * This program is distributed in the hope that it will be useful,
3429+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3430+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3431+ * GNU General Public License for more details.
3432+ *
3433+ * You should have received a copy of the GNU General Public License
3434+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
3435+ *
3436+ * Authored by: Marco Trevisan <marco.trevisan@canonical.com>
3437+ */
3438+
3439+#include "SessionDBusManager.h"
3440+
3441+namespace unity
3442+{
3443+namespace session
3444+{
3445+namespace dbus
3446+{
3447+const std::string NAME = "com.canonical.Unity";
3448+const std::string INTERFACE = "com.canonical.Unity.Session";
3449+const std::string OBJECT_PATH = "/com/canonical/Unity/Session";
3450+const std::string INTROSPECTION_XML =
3451+R"(<node>
3452+ <interface name="com.canonical.Unity.Session">
3453+ <method name="RealName">
3454+ <arg type="s" direction="out" name="realname" />
3455+ </method>
3456+ <method name="UserName">
3457+ <arg type="s" direction="out" name="username" />
3458+ </method>
3459+ <method name="HostName">
3460+ <arg type="s" direction="out" name="hostname" />
3461+ </method>
3462+ <method name="Lock" />
3463+ <method name="Logout" />
3464+ <method name="RequestLogout" />
3465+ <method name="Reboot" />
3466+ <method name="RequestReboot" />
3467+ <method name="Shutdown" />
3468+ <method name="RequestShutdown" />
3469+ <method name="Suspend" />
3470+ <method name="Hibernate" />
3471+ <method name="CancelAction" />
3472+ <method name="CanShutdown">
3473+ <arg type="b" direction="out" name="canshutdown" />
3474+ </method>
3475+ <method name="CanSuspend">
3476+ <arg type="b" direction="out" name="cansuspend" />
3477+ </method>
3478+ <method name="CanHibernate">
3479+ <arg type="b" direction="out" name="canhibernate" />
3480+ </method>
3481+
3482+ <signal name="LockRequested" />
3483+ <signal name="Locked" />
3484+ <signal name="UnlockRequested" />
3485+ <signal name="Unlocked" />
3486+ <signal name="LogoutRequested">
3487+ <arg type="b" name="have_inhibitors" />
3488+ </signal>
3489+ <signal name="RebootRequested">
3490+ <arg type="b" name="have_inhibitors" />
3491+ </signal>
3492+ <signal name="ShutdownRequested">
3493+ <arg type="b" name="have_inhibitors" />
3494+ </signal>
3495+ </interface>
3496+</node>)";
3497+}
3498+
3499+DBusManager::DBusManager(session::Manager::Ptr const& session)
3500+ : session_(session)
3501+ , server_(dbus::NAME)
3502+{
3503+ server_.AddObjects(dbus::INTROSPECTION_XML, dbus::OBJECT_PATH);
3504+ object_ = server_.GetObject(dbus::INTERFACE);
3505+ object_->SetMethodsCallsHandler([this] (std::string const& method, GVariant*) -> GVariant* {
3506+ if (method == "RealName")
3507+ {
3508+ return g_variant_new("(s)", session_->RealName().c_str());
3509+ }
3510+ else if (method == "UserName")
3511+ {
3512+ return g_variant_new("(s)", session_->UserName().c_str());
3513+ }
3514+ else if (method == "HostName")
3515+ {
3516+ return g_variant_new("(s)", session_->HostName().c_str());
3517+ }
3518+ else if (method == "Lock")
3519+ {
3520+ session_->LockScreen();
3521+ }
3522+ else if (method == "Logout")
3523+ {
3524+ session_->Logout();
3525+ }
3526+ else if (method == "RequestLogout")
3527+ {
3528+ session_->logout_requested.emit(false);
3529+ }
3530+ else if (method == "Reboot")
3531+ {
3532+ session_->Reboot();
3533+ }
3534+ else if (method == "RequestReboot")
3535+ {
3536+ session_->reboot_requested.emit(false);
3537+ }
3538+ else if (method == "Shutdown")
3539+ {
3540+ session_->Shutdown();
3541+ }
3542+ else if (method == "RequestShutdown")
3543+ {
3544+ session_->shutdown_requested.emit(false);
3545+ }
3546+ else if (method == "Suspend")
3547+ {
3548+ session_->Suspend();
3549+ }
3550+ else if (method == "Hibernate")
3551+ {
3552+ session_->Hibernate();
3553+ }
3554+ else if (method == "CancelAction")
3555+ {
3556+ session_->CancelAction();
3557+ session_->cancel_requested.emit();
3558+ }
3559+ else if (method == "CanShutdown")
3560+ {
3561+ return g_variant_new("(b)", session_->CanShutdown() != FALSE);
3562+ }
3563+ else if (method == "CanSuspend")
3564+ {
3565+ return g_variant_new("(b)", session_->CanSuspend() != FALSE);
3566+ }
3567+ else if (method == "CanHibernate")
3568+ {
3569+ return g_variant_new("(b)", session_->CanHibernate() != FALSE);
3570+ }
3571+
3572+ return nullptr;
3573+ });
3574+
3575+ connections_.Add(session_->lock_requested.connect([this] {
3576+ object_->EmitSignal("LockRequested");
3577+ }));
3578+ connections_.Add(session_->locked.connect([this] {
3579+ object_->EmitSignal("Locked");
3580+ }));
3581+ connections_.Add(session_->unlock_requested.connect([this] {
3582+ object_->EmitSignal("UnlockRequested");
3583+ }));
3584+ connections_.Add(session_->unlocked.connect([this] {
3585+ object_->EmitSignal("Unlocked");
3586+ }));
3587+ connections_.Add(session_->logout_requested.connect([this] (bool inhibitors) {
3588+ object_->EmitSignal("LogoutRequested", g_variant_new("(b)", inhibitors));
3589+ }));
3590+ connections_.Add(session_->reboot_requested.connect([this] (bool inhibitors) {
3591+ object_->EmitSignal("RebootRequested", g_variant_new("(b)", inhibitors));
3592+ }));
3593+ connections_.Add(session_->shutdown_requested.connect([this] (bool inhibitors) {
3594+ object_->EmitSignal("ShutdownRequested", g_variant_new("(b)", inhibitors));
3595+ }));
3596+}
3597+
3598+} // session
3599+} // unity
3600
3601=== added file 'shutdown/SessionDBusManager.h'
3602--- shutdown/SessionDBusManager.h 1970-01-01 00:00:00 +0000
3603+++ shutdown/SessionDBusManager.h 2014-03-10 19:41:23 +0000
3604@@ -0,0 +1,50 @@
3605+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
3606+/*
3607+ * Copyright (C) 2014 Canonical Ltd
3608+ *
3609+ * This program is free software: you can redistribute it and/or modify
3610+ * it under the terms of the GNU General Public License version 3 as
3611+ * published by the Free Software Foundation.
3612+ *
3613+ * This program is distributed in the hope that it will be useful,
3614+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3615+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3616+ * GNU General Public License for more details.
3617+ *
3618+ * You should have received a copy of the GNU General Public License
3619+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
3620+ *
3621+ * Authored by: Marco Trevisan <marco.trevisan@canonical.com>
3622+ */
3623+
3624+#ifndef UNITYSHELL_SESSION_DBUS_MANAGER_H
3625+#define UNITYSHELL_SESSION_DBUS_MANAGER_H
3626+
3627+#include <UnityCore/ConnectionManager.h>
3628+#include <UnityCore/GLibDBusServer.h>
3629+#include <UnityCore/SessionManager.h>
3630+
3631+namespace unity
3632+{
3633+namespace session
3634+{
3635+
3636+class DBusManager
3637+{
3638+public:
3639+ typedef std::shared_ptr<DBusManager> Ptr;
3640+
3641+ DBusManager(session::Manager::Ptr const& manager);
3642+ virtual ~DBusManager() = default;
3643+
3644+private:
3645+ session::Manager::Ptr session_;
3646+ glib::DBusServer server_;
3647+ glib::DBusObject::Ptr object_;
3648+ connection::Manager connections_;
3649+};
3650+
3651+} // session
3652+} // unity
3653+
3654+#endif
3655
3656=== modified file 'shutdown/StandaloneSession.cpp'
3657--- shutdown/StandaloneSession.cpp 2013-03-07 22:30:02 +0000
3658+++ shutdown/StandaloneSession.cpp 2014-03-10 19:41:23 +0000
3659@@ -38,6 +38,7 @@
3660
3661 std::string RealName() const { return "Marco Trevisan"; }
3662 std::string UserName() const { return "marco"; }
3663+ std::string HostName() const { return "tricky"; }
3664
3665 void LockScreen() { std::cout << "LockScreen" << std::endl; }
3666 void Logout() { std::cout << "Logout" << std::endl; }
3667
3668=== modified file 'tests/CMakeLists.txt'
3669--- tests/CMakeLists.txt 2014-02-17 18:51:34 +0000
3670+++ tests/CMakeLists.txt 2014-03-10 19:41:23 +0000
3671@@ -243,6 +243,7 @@
3672 test_launcher_icon.cpp
3673 test_launcher_minimize_speed.cpp
3674 test_launcher_tooltip.cpp
3675+ test_lockscreen_controller.cpp
3676 test_panel_controller.cpp
3677 test_panel_indicators_view.cpp
3678 test_panel_indicator_entry_dropdown_view.cpp
3679@@ -292,6 +293,8 @@
3680 test_unity_settings.cpp
3681 test_unity_window_style.cpp
3682 test_unity_window_view.cpp
3683+ test_upstart_wrapper.cpp
3684+ test_user_authenticator_pam.cpp
3685 test_volume_launcher_icon.cpp
3686 test_window_buttons.cpp
3687 test_xdnd_manager_imp.cpp
3688@@ -319,7 +322,9 @@
3689 decorations-lib
3690 hud-lib
3691 launcher-lib
3692+ lockscreen-lib
3693 panel-lib
3694+ pam
3695 previews-lib
3696 shortcuts-lib
3697 shutdown-lib
3698
3699=== modified file 'tests/autopilot/unity/tests/launcher/test_icon_behavior.py'
3700--- tests/autopilot/unity/tests/launcher/test_icon_behavior.py 2014-01-23 15:51:46 +0000
3701+++ tests/autopilot/unity/tests/launcher/test_icon_behavior.py 2014-03-10 19:41:23 +0000
3702@@ -70,7 +70,7 @@
3703 self.unity.dash.ensure_visible()
3704 self.addCleanup(self.unity.dash.ensure_hidden)
3705
3706- self.assertThat(bfb.get_tooltip().active, Eventually(Equals(False)))
3707+ self.assertThat(bfb.get_tooltip(), Equals(None))
3708
3709 def test_bfb_tooltip_is_disabled_when_dash_is_open(self):
3710 """Tests the that bfb tooltip is disabled when the dash is open."""
3711
3712=== modified file 'tests/autopilot/unity/tests/launcher/test_tooltips.py'
3713--- tests/autopilot/unity/tests/launcher/test_tooltips.py 2014-01-23 15:51:46 +0000
3714+++ tests/autopilot/unity/tests/launcher/test_tooltips.py 2014-03-10 19:41:23 +0000
3715@@ -38,14 +38,13 @@
3716 if size > 5:
3717 size = 5
3718
3719- # subsequent tooltips reveal instantly, but hide on exit
3720+ # subsequent tooltips reveal instantly, but are destroyed on exit, meaning None
3721 a, b = 0, 1
3722 while b < size:
3723 self.mouse.move(self.icons[b].center.x, self.icons[b].center.y)
3724 self.assertThat(lambda: self.icons[b].get_tooltip(), Eventually(NotEquals(None)))
3725 self.assertThat(self.icons[b].get_tooltip().active, Eventually(Equals(True)))
3726- self.assertThat(lambda: self.icons[a].get_tooltip(), Eventually(NotEquals(None)))
3727- self.assertThat(self.icons[a].get_tooltip().active, Eventually(Equals(False)))
3728+ self.assertThat(self.icons[a].get_tooltip(), Equals(None))
3729 a, b = a + 1, b + 1
3730 b -= 1
3731
3732
3733=== modified file 'tests/autopilot/unity/tests/test_quicklist.py'
3734--- tests/autopilot/unity/tests/test_quicklist.py 2013-09-12 15:36:55 +0000
3735+++ tests/autopilot/unity/tests/test_quicklist.py 2014-03-10 19:41:23 +0000
3736@@ -11,8 +11,9 @@
3737
3738 from autopilot.display import move_mouse_to_screen
3739 from autopilot.matchers import Eventually
3740+from autopilot.introspection.dbus import StateNotFoundError
3741 import os.path
3742-from testtools.matchers import Contains, Equals, NotEquals
3743+from testtools.matchers import Contains, Equals, NotEquals, Not, Raises
3744 from time import sleep
3745 from xdg.DesktopEntry import DesktopEntry
3746
3747@@ -90,8 +91,7 @@
3748 self.assertThat(lambda: len(nautilus_windows_fn()), Eventually(Equals(1)))
3749 [nautilus_window] = nautilus_windows_fn()
3750
3751- self.assertThat(lambda: self.get_startup_notification_timestamp(nautilus_window),
3752- Eventually(Equals(new_win_ql_item.activate_timestamp)))
3753+ self.assertThat(new_win_ql_item.wait_until_destroyed, Not(Raises()))
3754
3755 def test_quicklist_application_item_focus_last_active_window(self):
3756 """This tests shows that when you activate a quicklist application item
3757@@ -198,7 +198,7 @@
3758
3759 icon1_ql = self.open_quicklist_for_icon(icons[1])
3760 self.assertThat(icon1_ql.active, Eventually(Equals(True)))
3761- self.assertThat(icon0_ql.active, Eventually(Equals(False)))
3762+ self.assertThat(icon0_ql.wait_until_destroyed, Not(Raises()))
3763
3764 def test_right_clicking_same_icon_doesnt_reopen_ql(self):
3765 """A right click to the same icon in the launcher must
3766@@ -213,8 +213,13 @@
3767 calc_ql = self.open_quicklist_for_icon(calc_icon)
3768 self.assertThat(calc_ql.active, Eventually(Equals(True)))
3769
3770- calc_ql = self.open_quicklist_for_icon(calc_icon)
3771- self.assertThat(calc_ql.active, Eventually(Equals(False)))
3772+ # We've to manually open the icon this time, as when the quicklist goes away
3773+ # its Destroyed, so its None!
3774+ launcher = self.unity.launcher.get_launcher_for_monitor(0)
3775+ launcher.click_launcher_icon(calc_icon, button=3)
3776+ self.addCleanup(self.keyboard.press_and_release, "Escape")
3777+ calc_ql = calc_icon.get_quicklist()
3778+ self.assertThat(calc_ql, Equals(None))
3779
3780
3781 class QuicklistKeyNavigationTests(UnityTestCase):
3782
3783=== modified file 'tests/autopilot/unity/tests/test_spread.py'
3784--- tests/autopilot/unity/tests/test_spread.py 2014-02-27 16:35:53 +0000
3785+++ tests/autopilot/unity/tests/test_spread.py 2014-03-10 19:41:23 +0000
3786@@ -200,7 +200,7 @@
3787 self.assertThat(icon.get_tooltip().active, Eventually(Equals(True)))
3788
3789 self.initiate_spread_for_screen()
3790- self.assertThat(icon.get_tooltip().active, Eventually(Equals(False)))
3791+ self.assertThat(icon.get_tooltip(), Equals(None))
3792
3793 def test_spread_puts_panel_in_overlay_mode(self):
3794 """Test that the panel is in overlay mode when in spread"""
3795
3796=== modified file 'tests/data/external.gschema.xml'
3797--- tests/data/external.gschema.xml 2014-01-30 17:57:29 +0000
3798+++ tests/data/external.gschema.xml 2014-03-10 19:41:23 +0000
3799@@ -52,4 +52,28 @@
3800 <default>false</default>
3801 </key>
3802 </schema>
3803+
3804+ <schema id="com.canonical.unity-greeter" path="/com/canonical/unity-greeter/">
3805+ <key type="s" name="logo">
3806+ <default>'/usr/share/unity-greeter/logo.png'</default>
3807+ </key>
3808+ <key type="s" name="font-name">
3809+ <default>'Ubuntu 11'</default>
3810+ </key>
3811+ <key type="s" name="background">
3812+ <default>'/usr/share/backgrounds/warty-final-ubuntu.png'</default>
3813+ </key>
3814+ <key type="s" name="background-color">
3815+ <default>'#2C001E'</default>
3816+ </key>
3817+ <key type="b" name="draw-user-backgrounds">
3818+ <default>true</default>
3819+ </key>
3820+ <key type="b" name="draw-grid">
3821+ <default>true</default>
3822+ </key>
3823+ <key type="b" name="show-hostname">
3824+ <default>true</default>
3825+ </key>
3826+ </schema>
3827 </schemalist>
3828
3829=== modified file 'tests/test_gnome_session_manager.cpp'
3830--- tests/test_gnome_session_manager.cpp 2013-11-29 19:04:38 +0000
3831+++ tests/test_gnome_session_manager.cpp 2014-03-10 19:41:23 +0000
3832@@ -37,9 +37,9 @@
3833 const std::string SHELL_OBJECT_PATH = "/org/gnome/SessionManager/EndSessionDialog";
3834
3835 const std::string UPOWER_PATH = "/org/freedesktop/UPower";
3836-const std::string LOGIND_PATH = "/org/freedesktop/login1";
3837+const std::string LOGIND_MANAGER_PATH = "/org/freedesktop/login1";
3838+const std::string LOGIND_SESSION_PATH = "/org/freedesktop/login1/session/id0";
3839 const std::string CONSOLE_KIT_PATH = "/org/freedesktop/ConsoleKit/Manager";
3840-const std::string SCREEN_SAVER_PATH = "/org/gnome/ScreenSaver";
3841 const std::string SESSION_MANAGER_PATH = "/org/gnome/SessionManager";
3842
3843 const std::string SESSION_OPTIONS = "com.canonical.indicator.session";
3844@@ -62,7 +62,7 @@
3845 </interface>
3846 </node>)";
3847
3848-const std::string LOGIND =
3849+const std::string LOGIND_MANAGER =
3850 R"(<node>
3851 <interface name="org.freedesktop.login1.Manager">
3852 <method name="CanSuspend">
3853@@ -89,6 +89,14 @@
3854 </interface>
3855 </node>)";
3856
3857+const std::string LOGIND_SESSION =
3858+R"(<node>
3859+ <interface name="org.freedesktop.login1.Session">
3860+ <signal name="Lock" />
3861+ <signal name="Unlock" />
3862+ </interface>
3863+</node>)";
3864+
3865 const std::string CONSOLE_KIT =
3866 R"(<node>
3867 <interface name="org.freedesktop.ConsoleKit.Manager">
3868@@ -100,14 +108,6 @@
3869 </interface>
3870 </node>)";
3871
3872-const std::string SCREEN_SAVER =
3873-R"(<node>
3874- <interface name="org.gnome.ScreenSaver">
3875- <method name="Lock"/>
3876- <method name="SimulateUserActivity"/>
3877- </interface>
3878-</node>)";
3879-
3880 const std::string SESSION_MANAGER =
3881 R"(<node>
3882 <interface name="org.gnome.SessionManager">
3883@@ -162,7 +162,8 @@
3884 });
3885
3886 logind_ = std::make_shared<DBusServer>();
3887- logind_->AddObjects(introspection::LOGIND, LOGIND_PATH);
3888+ logind_->AddObjects(introspection::LOGIND_MANAGER, LOGIND_MANAGER_PATH);
3889+ logind_->AddObjects(introspection::LOGIND_SESSION, LOGIND_SESSION_PATH);
3890 logind_->GetObjects().front()->SetMethodsCallsHandler([&] (std::string const& method, GVariant*) -> GVariant* {
3891 if (method == "CanSuspend")
3892 {
3893@@ -181,9 +182,6 @@
3894 console_kit_ = std::make_shared<DBusServer>();
3895 console_kit_->AddObjects(introspection::CONSOLE_KIT, CONSOLE_KIT_PATH);
3896
3897- screen_saver_ = std::make_shared<DBusServer>();
3898- screen_saver_->AddObjects(introspection::SCREEN_SAVER, SCREEN_SAVER_PATH);
3899-
3900 session_manager_ = std::make_shared<DBusServer>();
3901 session_manager_->AddObjects(introspection::SESSION_MANAGER, SESSION_MANAGER_PATH);
3902 session_manager_->GetObjects().front()->SetMethodsCallsHandler([&] (std::string const& method, GVariant*) -> GVariant* {
3903@@ -215,7 +213,6 @@
3904 Utils::WaitUntilMSec([] { return upower_->IsConnected(); });
3905 Utils::WaitUntilMSec([] { return logind_->IsConnected(); });
3906 Utils::WaitUntilMSec([] { return console_kit_->IsConnected(); });
3907- Utils::WaitUntilMSec([] { return screen_saver_->IsConnected(); });
3908 Utils::WaitUntilMSec([] { return session_manager_->IsConnected(); });
3909 Utils::WaitUntilMSec([] { return shell_proxy_->IsConnected();});
3910 ASSERT_TRUE(shell_proxy_->IsConnected());
3911@@ -267,7 +264,6 @@
3912 upower_.reset();
3913 logind_.reset();
3914 console_kit_.reset();
3915- screen_saver_.reset();
3916 session_manager_.reset();
3917 }
3918
3919@@ -327,7 +323,6 @@
3920 static DBusServer::Ptr upower_;
3921 static DBusServer::Ptr console_kit_;
3922 static DBusServer::Ptr logind_;
3923- static DBusServer::Ptr screen_saver_;
3924 static DBusServer::Ptr session_manager_;
3925 static DBusProxy::Ptr shell_proxy_;
3926 };
3927@@ -336,7 +331,6 @@
3928 DBusServer::Ptr TestGnomeSessionManager::upower_;
3929 DBusServer::Ptr TestGnomeSessionManager::console_kit_;
3930 DBusServer::Ptr TestGnomeSessionManager::logind_;
3931-DBusServer::Ptr TestGnomeSessionManager::screen_saver_;
3932 DBusServer::Ptr TestGnomeSessionManager::session_manager_;
3933 DBusProxy::Ptr TestGnomeSessionManager::shell_proxy_;
3934 bool TestGnomeSessionManager::can_shutdown_;
3935@@ -375,31 +369,17 @@
3936
3937 TEST_F(TestGnomeSessionManager, LockScreen)
3938 {
3939- bool lock_called = false;
3940- bool simulate_activity_called = false;
3941-
3942- screen_saver_->GetObjects().front()->SetMethodsCallsHandler([&] (std::string const& method, GVariant*) -> GVariant* {
3943- if (method == "Lock")
3944- {
3945- lock_called = true;
3946- EXPECT_FALSE(simulate_activity_called);
3947- }
3948- else if (method == "SimulateUserActivity")
3949- {
3950- simulate_activity_called = true;
3951- EXPECT_TRUE(lock_called);
3952- }
3953-
3954- return nullptr;
3955+ bool lock_emitted = false;
3956+
3957+ manager->lock_requested.connect([&lock_emitted]()
3958+ {
3959+ lock_emitted = true;
3960 });
3961
3962 manager->LockScreen();
3963
3964- Utils::WaitUntilMSec(lock_called);
3965- EXPECT_TRUE(lock_called);
3966-
3967- Utils::WaitUntilMSec(simulate_activity_called);
3968- EXPECT_TRUE(simulate_activity_called);
3969+ Utils::WaitUntilMSec(lock_emitted);
3970+ EXPECT_TRUE(lock_emitted);
3971 }
3972
3973 TEST_F(TestGnomeSessionManager, Logout)
3974@@ -1004,4 +984,34 @@
3975 EXPECT_TRUE(closed);
3976 }
3977
3978+TEST_F(TestGnomeSessionManager, DISABLED_LogindLock)
3979+{
3980+ bool lock_emitted = false;
3981+
3982+ manager->lock_requested.connect([&lock_emitted]()
3983+ {
3984+ lock_emitted = true;
3985+ });
3986+
3987+ logind_->GetObject("org.freedesktop.login1.Session")->EmitSignal("Lock");
3988+
3989+ Utils::WaitUntilMSec(lock_emitted);
3990+ EXPECT_TRUE(lock_emitted);
3991+}
3992+
3993+TEST_F(TestGnomeSessionManager, LogindUnLock)
3994+{
3995+ bool unlock_emitted = false;
3996+
3997+ manager->unlock_requested.connect([&unlock_emitted]()
3998+ {
3999+ unlock_emitted = true;
4000+ });
4001+
4002+ logind_->GetObject("org.freedesktop.login1.Session")->EmitSignal("Unlock");
4003+
4004+ Utils::WaitUntilMSec(unlock_emitted);
4005+ EXPECT_TRUE(unlock_emitted);
4006+}
4007+
4008 } // Namespace
4009
4010=== added file 'tests/test_lockscreen_controller.cpp'
4011--- tests/test_lockscreen_controller.cpp 1970-01-01 00:00:00 +0000
4012+++ tests/test_lockscreen_controller.cpp 2014-03-10 19:41:23 +0000
4013@@ -0,0 +1,335 @@
4014+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
4015+/*
4016+* Copyright (C) 2014 Canonical Ltd
4017+*
4018+* This program is free software: you can redistribute it and/or modify
4019+* it under the terms of the GNU General Public License version 3 as
4020+* published by the Free Software Foundation.
4021+*
4022+* This program is distributed in the hope that it will be useful,
4023+* but WITHOUT ANY WARRANTY; without even the implied warranty of
4024+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4025+* GNU General Public License for more details.
4026+*
4027+* You should have received a copy of the GNU General Public License
4028+* along with this program. If not, see <http://www.gnu.org/licenses/>.
4029+*
4030+* Authored by: Andrea Azzarone <andrea.azzarone@canonical.com>
4031+*/
4032+
4033+#include <gmock/gmock.h>
4034+using namespace testing;
4035+
4036+#include "lockscreen/LockScreenController.h"
4037+
4038+#include <Nux/NuxTimerTickSource.h>
4039+#include <NuxCore/AnimationController.h>
4040+#include <UnityCore/GLibDBusServer.h>
4041+
4042+
4043+#include "lockscreen/LockScreenSettings.h"
4044+#include "unity-shared/PanelStyle.h"
4045+#include "unity-shared/UScreen.h"
4046+#include "unity-shared/UnitySettings.h"
4047+#include "test_mock_session_manager.h"
4048+#include "test_uscreen_mock.h"
4049+#include "test_utils.h"
4050+
4051+namespace unity
4052+{
4053+namespace lockscreen
4054+{
4055+namespace
4056+{
4057+
4058+const unsigned ANIMATION_DURATION = 400 * 1000; // in microseconds
4059+const unsigned TICK_DURATION = 10 * 1000;
4060+
4061+const std::string TEST_SERVER_NAME = "com.canonical.Unity.Test.DisplayManager";
4062+const std::string LIGHTDM_PATH = "/org/freedesktop/DisplayManager/Session0";
4063+
4064+}
4065+
4066+namespace introspection
4067+{
4068+
4069+const std::string LIGHTDM =
4070+R"(<node>
4071+ <interface name="org.freedesktop.DisplayManager.Session">
4072+ <method name="Lock"/>
4073+ </interface>
4074+</node>)";
4075+
4076+}
4077+
4078+struct ShieldFactoryMock : ShieldFactoryInterface
4079+{
4080+ nux::ObjectPtr<AbstractShield> CreateShield(session::Manager::Ptr const&, int, bool) override
4081+ {
4082+ return nux::ObjectPtr<AbstractShield>(new AbstractShield(nullptr, 0, false));
4083+ }
4084+};
4085+
4086+struct TestLockScreenController : Test
4087+{
4088+ TestLockScreenController()
4089+ : animation_controller(tick_source)
4090+ , session_manager(std::make_shared<NiceMock<session::MockManager>>())
4091+ , upstart_wrapper(std::make_shared<UpstartWrapper>())
4092+ , shield_factory(std::make_shared<ShieldFactoryMock>())
4093+ , controller(session_manager, upstart_wrapper, shield_factory)
4094+ {
4095+ lightdm_ = std::make_shared<glib::DBusServer>(TEST_SERVER_NAME);
4096+ lightdm_->AddObjects(introspection::LIGHTDM, LIGHTDM_PATH);
4097+
4098+ Utils::WaitUntilMSec([] { return lightdm_->IsConnected(); });
4099+ }
4100+
4101+ struct ControllerWrap : Controller
4102+ {
4103+ ControllerWrap(session::Manager::Ptr const& session_manager,
4104+ UpstartWrapper::Ptr const& upstart_wrapper,
4105+ ShieldFactoryInterface::Ptr const& shield_factory)
4106+ : Controller(session_manager, upstart_wrapper, shield_factory, /* test_mode */ true)
4107+ {}
4108+
4109+ using Controller::shields_;
4110+ };
4111+
4112+ nux::NuxTimerTickSource tick_source;
4113+ nux::animation::AnimationController animation_controller;
4114+
4115+ MockUScreen uscreen;
4116+ unity::Settings unity_settings;
4117+ unity::panel::Style panel_style;
4118+ unity::lockscreen::Settings lockscreen_settings;
4119+ static glib::DBusServer::Ptr lightdm_;
4120+ session::MockManager::Ptr session_manager;
4121+ unity::UpstartWrapper::Ptr upstart_wrapper;
4122+
4123+ ShieldFactoryMock::Ptr shield_factory;
4124+ ControllerWrap controller;
4125+};
4126+
4127+glib::DBusServer::Ptr TestLockScreenController::lightdm_;
4128+
4129+TEST_F(TestLockScreenController, Construct)
4130+{
4131+ EXPECT_TRUE(controller.shields_.empty());
4132+}
4133+
4134+TEST_F(TestLockScreenController, DisconnectUScreenSignalsOnDestruction)
4135+{
4136+ size_t before = uscreen.changed.size();
4137+ {
4138+ Controller dummy(session_manager);
4139+ }
4140+ ASSERT_EQ(before, uscreen.changed.size());
4141+
4142+ std::vector<nux::Geometry> monitors;
4143+ uscreen.changed.emit(0, monitors);
4144+}
4145+
4146+TEST_F(TestLockScreenController, DisconnectSessionManagerSignalsOnDestruction)
4147+{
4148+ size_t before = session_manager->unlock_requested.size();
4149+ {
4150+ Controller dummy(session_manager);
4151+ }
4152+ ASSERT_EQ(before, session_manager->unlock_requested.size());
4153+
4154+ session_manager->unlock_requested.emit();
4155+}
4156+
4157+TEST_F(TestLockScreenController, UScreenChangedIgnoredOnScreenUnlocked)
4158+{
4159+ uscreen.SetupFakeMultiMonitor(/*primary*/ 0, /*emit_change*/ true);
4160+ EXPECT_TRUE(controller.shields_.empty());
4161+}
4162+
4163+TEST_F(TestLockScreenController, LockScreenTypeNone)
4164+{
4165+ lockscreen_settings.lockscreen_type = Type::NONE;
4166+ session_manager->lock_requested.emit();
4167+
4168+ ASSERT_EQ(0, controller.shields_.size());
4169+}
4170+
4171+TEST_F(TestLockScreenController, LockScreenTypeLightdmOnSingleMonitor)
4172+{
4173+ g_setenv("XDG_SESSION_PATH", LIGHTDM_PATH.c_str(), true);
4174+
4175+ bool lock_called = false;
4176+
4177+ lightdm_->GetObjects().front()->SetMethodsCallsHandler([&] (std::string const& method, GVariant*) -> GVariant* {
4178+ if (method == "Lock")
4179+ lock_called = true;
4180+
4181+ return nullptr;
4182+ });
4183+
4184+ lockscreen_settings.lockscreen_type = Type::LIGHTDM;
4185+ session_manager->lock_requested.emit();
4186+
4187+ ASSERT_EQ(1, controller.shields_.size());
4188+ EXPECT_FALSE(controller.shields_.at(0)->primary());
4189+ Utils::WaitUntilMSec(lock_called);
4190+}
4191+
4192+TEST_F(TestLockScreenController, LockScreenTypeLightdmOnMultiMonitor)
4193+{
4194+ g_setenv("XDG_SESSION_PATH", LIGHTDM_PATH.c_str(), true);
4195+
4196+ bool lock_called = false;
4197+
4198+ lightdm_->GetObjects().front()->SetMethodsCallsHandler([&] (std::string const& method, GVariant*) -> GVariant* {
4199+ if (method == "Lock")
4200+ lock_called = true;
4201+
4202+ return nullptr;
4203+ });
4204+
4205+ lockscreen_settings.lockscreen_type = Type::LIGHTDM;
4206+ uscreen.SetupFakeMultiMonitor(/*primary*/ 0, /*emit_change*/ true);
4207+ session_manager->lock_requested.emit();
4208+
4209+ ASSERT_EQ(monitors::MAX, controller.shields_.size());
4210+
4211+ for (unsigned int i=0; i < monitors::MAX; ++i)
4212+ EXPECT_FALSE(controller.shields_.at(i)->primary());
4213+
4214+ Utils::WaitUntilMSec(lock_called);
4215+}
4216+
4217+TEST_F(TestLockScreenController, UnlockScreenTypeLightdmOnSingleMonitor)
4218+{
4219+ g_setenv("XDG_SESSION_PATH", LIGHTDM_PATH.c_str(), true);
4220+
4221+ bool lock_called = false;
4222+
4223+ lightdm_->GetObjects().front()->SetMethodsCallsHandler([&] (std::string const& method, GVariant*) -> GVariant* {
4224+ if (method == "Lock")
4225+ lock_called = true;
4226+
4227+ return nullptr;
4228+ });
4229+
4230+ lockscreen_settings.lockscreen_type = Type::LIGHTDM;
4231+ session_manager->lock_requested.emit();
4232+
4233+ ASSERT_EQ(1, controller.shields_.size());
4234+ Utils::WaitUntilMSec(lock_called);
4235+
4236+ session_manager->unlock_requested.emit();
4237+ tick_source.tick(ANIMATION_DURATION);
4238+
4239+ ASSERT_EQ(0, controller.shields_.size());
4240+}
4241+
4242+TEST_F(TestLockScreenController, UnlockScreenTypeLightdmOnMultiMonitor)
4243+{
4244+ g_setenv("XDG_SESSION_PATH", LIGHTDM_PATH.c_str(), true);
4245+
4246+ bool lock_called = false;
4247+
4248+ lightdm_->GetObjects().front()->SetMethodsCallsHandler([&] (std::string const& method, GVariant*) -> GVariant* {
4249+ if (method == "Lock")
4250+ lock_called = true;
4251+
4252+ return nullptr;
4253+ });
4254+
4255+ lockscreen_settings.lockscreen_type = Type::LIGHTDM;
4256+ uscreen.SetupFakeMultiMonitor(/*primary*/ 0, /*emit_change*/ true);
4257+ session_manager->lock_requested.emit();
4258+
4259+ ASSERT_EQ(monitors::MAX, controller.shields_.size());
4260+ Utils::WaitUntilMSec(lock_called);
4261+
4262+ session_manager->unlock_requested.emit();
4263+ tick_source.tick(ANIMATION_DURATION);
4264+
4265+ ASSERT_EQ(0, controller.shields_.size());
4266+}
4267+
4268+TEST_F(TestLockScreenController, LockScreenOnSingleMonitor)
4269+{
4270+ session_manager->lock_requested.emit();
4271+
4272+ ASSERT_EQ(1, controller.shields_.size());
4273+ EXPECT_EQ(uscreen.GetMonitors().at(0), controller.shields_.at(0)->GetGeometry());
4274+}
4275+
4276+TEST_F(TestLockScreenController, LockScreenOnMultiMonitor)
4277+{
4278+ uscreen.SetupFakeMultiMonitor();
4279+
4280+ session_manager->lock_requested.emit();
4281+ ASSERT_EQ(monitors::MAX, controller.shields_.size());
4282+
4283+ for (unsigned int i=0; i < monitors::MAX; ++i)
4284+ EXPECT_EQ(uscreen.GetMonitors().at(i), controller.shields_.at(i)->GetAbsoluteGeometry());
4285+}
4286+
4287+TEST_F(TestLockScreenController, SwitchToMultiMonitor)
4288+{
4289+ session_manager->lock_requested.emit();
4290+ tick_source.tick(ANIMATION_DURATION);
4291+
4292+ ASSERT_EQ(1, controller.shields_.size());
4293+ EXPECT_EQ(uscreen.GetMonitors().at(0), controller.shields_.at(0)->GetGeometry());
4294+
4295+ uscreen.SetupFakeMultiMonitor(/* primary */ 0, /* emit_change */ true);
4296+
4297+ ASSERT_EQ(monitors::MAX, controller.shields_.size());
4298+
4299+ for (unsigned int i=0; i < monitors::MAX; ++i)
4300+ {
4301+ ASSERT_EQ(uscreen.GetMonitors().at(i), controller.shields_.at(i)->GetAbsoluteGeometry());
4302+ ASSERT_TRUE(controller.shields_.at(i)->IsVisible());
4303+ }
4304+}
4305+
4306+TEST_F(TestLockScreenController, SwitchToSingleMonitor)
4307+{
4308+ uscreen.SetupFakeMultiMonitor(/* primary */ 0, /* emit_change */ true);
4309+ session_manager->lock_requested.emit();
4310+
4311+ ASSERT_EQ(monitors::MAX, controller.shields_.size());
4312+
4313+ for (unsigned int i=0; i < monitors::MAX; ++i)
4314+ ASSERT_EQ(uscreen.GetMonitors().at(i), controller.shields_.at(i)->GetAbsoluteGeometry());
4315+
4316+ uscreen.Reset(/* emit_change */ true);
4317+
4318+ ASSERT_EQ(1, controller.shields_.size());
4319+ EXPECT_EQ(uscreen.GetMonitors().at(0), controller.shields_.at(0)->GetGeometry());
4320+}
4321+
4322+TEST_F(TestLockScreenController, UnlockScreenOnSingleMonitor)
4323+{
4324+ session_manager->lock_requested.emit();
4325+
4326+ ASSERT_EQ(1, controller.shields_.size());
4327+
4328+ session_manager->unlock_requested.emit();
4329+ tick_source.tick(ANIMATION_DURATION);
4330+
4331+ EXPECT_TRUE(controller.shields_.empty());
4332+}
4333+
4334+TEST_F(TestLockScreenController, UnlockScreenOnMultiMonitor)
4335+{
4336+ uscreen.SetupFakeMultiMonitor(/* primary */ 0, /* emit_change */ true);
4337+ session_manager->lock_requested.emit();
4338+
4339+ ASSERT_EQ(monitors::MAX, controller.shields_.size());
4340+
4341+ session_manager->unlock_requested.emit();
4342+ tick_source.tick(ANIMATION_DURATION);
4343+
4344+ EXPECT_TRUE(controller.shields_.empty());
4345+}
4346+
4347+} // lockscreen
4348+} // unity
4349
4350=== modified file 'tests/test_mock_session_manager.h'
4351--- tests/test_mock_session_manager.h 2013-03-07 21:26:57 +0000
4352+++ tests/test_mock_session_manager.h 2014-03-10 19:41:23 +0000
4353@@ -31,6 +31,7 @@
4354
4355 MOCK_CONST_METHOD0(RealName, std::string());
4356 MOCK_CONST_METHOD0(UserName, std::string());
4357+ MOCK_CONST_METHOD0(HostName, std::string());
4358
4359 MOCK_METHOD0(LockScreen, void());
4360 MOCK_METHOD0(Logout, void());
4361
4362=== modified file 'tests/test_text_input.cpp'
4363--- tests/test_text_input.cpp 2012-12-14 12:14:34 +0000
4364+++ tests/test_text_input.cpp 2014-03-10 19:41:23 +0000
4365@@ -22,7 +22,9 @@
4366
4367 #include <gtest/gtest.h>
4368
4369+#include "unity-shared/DashStyle.h"
4370 #include "unity-shared/TextInput.h"
4371+#include "unity-shared/UnitySettings.h"
4372 #include "test_utils.h"
4373
4374 using namespace nux;
4375@@ -33,7 +35,6 @@
4376 class TextInputMock : public TextInput
4377 {
4378 public:
4379- using TextInput::Init;
4380 using TextInput::OnInputHintChanged;
4381 using TextInput::OnMouseButtonDown;
4382 using TextInput::OnEndKeyFocus;
4383@@ -50,11 +51,12 @@
4384 TestTextInput()
4385 {
4386 entry = new TextInputMock();
4387- entry->Init();
4388 hint = entry->GetHint();
4389 pango_entry = entry->GetPangoEntry();
4390 }
4391
4392+ unity::Settings unity_settings_;
4393+ dash::Style dash_style_;
4394 nux::ObjectPtr<TextInputMock> entry;
4395 StaticCairoText* hint;
4396 IMTextEntry* pango_entry;
4397
4398=== added file 'tests/test_upstart_wrapper.cpp'
4399--- tests/test_upstart_wrapper.cpp 1970-01-01 00:00:00 +0000
4400+++ tests/test_upstart_wrapper.cpp 2014-03-10 19:41:23 +0000
4401@@ -0,0 +1,90 @@
4402+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
4403+/*
4404+* Copyright (C) 2014 Canonical Ltd
4405+*
4406+* This program is free software: you can redistribute it and/or modify
4407+* it under the terms of the GNU General Public License version 3 as
4408+* published by the Free Software Foundation.
4409+*
4410+* This program is distributed in the hope that it will be useful,
4411+* but WITHOUT ANY WARRANTY; without even the implied warranty of
4412+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4413+* GNU General Public License for more details.
4414+*
4415+* You should have received a copy of the GNU General Public License
4416+* along with this program. If not, see <http://www.gnu.org/licenses/>.
4417+*
4418+* Authored by: Andrea Azzarone <andrea.azzarone@canonical.com>
4419+*/
4420+
4421+#include <gtest/gtest.h>
4422+using namespace testing;
4423+
4424+#include "unity-shared/UpstartWrapper.h"
4425+
4426+#include <UnityCore/GLibDBusServer.h>
4427+#include <UnityCore/Variant.h>
4428+
4429+#include "test_utils.h"
4430+
4431+namespace
4432+{
4433+
4434+const std::string UPSTART =
4435+R"(<node>
4436+ <interface name="com.ubuntu.Upstart0_6">
4437+ <method name="EmitEvent">
4438+ <arg name="name" type="s" direction="in" />
4439+ <arg name="env" type="as" direction="in" />
4440+ <arg name="wait" type="b" direction="in" />
4441+ </method>
4442+
4443+ <signal name="EventEmitted">
4444+ <arg name="name" type="s" />
4445+ <arg name="env" type="as" />
4446+ </signal>
4447+ </interface>
4448+</node>)";
4449+
4450+struct MockUpstartWrapper : unity::UpstartWrapper {
4451+ MockUpstartWrapper()
4452+ : UpstartWrapper(UpstartWrapper::TestMode())
4453+ {}
4454+};
4455+
4456+struct TestUpstartWrapper : public Test
4457+{
4458+ TestUpstartWrapper()
4459+ {
4460+ upstart_server_ = std::make_shared<unity::glib::DBusServer>("com.canonical.Unity.Test.Upstart");
4461+ upstart_server_->AddObjects(UPSTART, "/com/ubuntu/Upstart");
4462+
4463+ Utils::WaitUntilMSec([this] { return upstart_server_->IsConnected(); });
4464+ }
4465+
4466+ unity::glib::DBusServer::Ptr upstart_server_;
4467+ MockUpstartWrapper upstart_wrapper_;
4468+};
4469+
4470+
4471+TEST_F(TestUpstartWrapper, Emit)
4472+{
4473+ bool event_emitted = false;
4474+
4475+ upstart_server_->GetObjects().front()->SetMethodsCallsHandler([&] (std::string const& method, GVariant* par) -> GVariant* {
4476+ if (method == "EmitEvent")
4477+ {
4478+ event_emitted = true;
4479+
4480+ std::string event_name = glib::Variant(g_variant_get_child_value(par, 0)).GetString();
4481+ EXPECT_EQ("desktop-lock", event_name);
4482+ }
4483+
4484+ return nullptr;
4485+ });
4486+
4487+ upstart_wrapper_.Emit("desktop-lock");
4488+ Utils::WaitUntil(event_emitted);
4489+}
4490+
4491+}
4492
4493=== added file 'tests/test_user_authenticator_pam.cpp'
4494--- tests/test_user_authenticator_pam.cpp 1970-01-01 00:00:00 +0000
4495+++ tests/test_user_authenticator_pam.cpp 2014-03-10 19:41:23 +0000
4496@@ -0,0 +1,58 @@
4497+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
4498+/*
4499+ * Copyright (C) 2013 Canonical Ltd
4500+ *
4501+ * This program is free software: you can redistribute it and/or modify
4502+ * it under the terms of the GNU General Public License version 3 as
4503+ * published by the Free Software Foundation.
4504+ *
4505+ * This program is distributed in the hope that it will be useful,
4506+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4507+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4508+ * GNU General Public License for more details.
4509+ *
4510+ * You should have received a copy of the GNU General Public License
4511+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4512+ *
4513+ * Authored by: Andrea Azzarone <andrea.azzarone@canonical.com>
4514+ */
4515+
4516+#include <gtest/gtest.h>
4517+
4518+#include "lockscreen/UserAuthenticatorPam.h"
4519+#include "test_utils.h"
4520+
4521+using unity::lockscreen::UserAuthenticatorPam;
4522+
4523+#include <security/pam_appl.h>
4524+
4525+// Would be nice to build a testing pam module, but writing a
4526+// pam_authenticate function here works just fine for the moment.
4527+int pam_authenticate(pam_handle_t *pamh, int flags)
4528+{
4529+ pam_conv* conversation;
4530+ struct pam_message msg;
4531+ const struct pam_message *msgp;
4532+
4533+ pam_get_item(pamh, PAM_CONV, (const void**) &conversation);
4534+
4535+ msg.msg_style = PAM_PROMPT_ECHO_OFF;
4536+ msgp = &msg;
4537+
4538+ pam_response* resp = nullptr;
4539+ conversation->conv(1, &msgp, &resp, conversation->appdata_ptr);
4540+
4541+ return strcmp(resp[0].resp, "password");
4542+}
4543+
4544+namespace
4545+{
4546+
4547+struct TestUserAuthenticatorPam : public ::testing::Test
4548+{
4549+ UserAuthenticatorPam user_authenticator_pam_;
4550+};
4551+
4552+// FIXME (add tests)
4553+
4554+}
4555
4556=== modified file 'tests/test_utils.h'
4557--- tests/test_utils.h 2013-07-11 00:52:33 +0000
4558+++ tests/test_utils.h 2014-03-10 19:41:23 +0000
4559@@ -46,7 +46,7 @@
4560 if (result == expected_result)
4561 g_source_remove(timeout_id);
4562
4563- EXPECT_EQ(result, expected_result) << (error_msg.empty() ? "" : ("Error: " + error_msg));
4564+ EXPECT_EQ(expected_result, result) << (error_msg.empty() ? "" : ("Error: " + error_msg));
4565 }
4566
4567 static void WaitUntil(std::function<bool()> const& check_function, bool result = true, unsigned max_wait = 1, std::string const& error_msg = "")
4568
4569=== modified file 'unity-shared/CMakeLists.txt'
4570--- unity-shared/CMakeLists.txt 2014-02-20 18:34:46 +0000
4571+++ unity-shared/CMakeLists.txt 2014-03-10 19:41:23 +0000
4572@@ -67,6 +67,7 @@
4573 UnitySettings.cpp
4574 UnityWindowStyle.cpp
4575 UnityWindowView.cpp
4576+ UpstartWrapper.cpp
4577 UserThumbnailProvider.cpp
4578 VScrollBarOverlayWindow.cpp
4579 WindowButtons.cpp
4580
4581=== added file 'unity-shared/GtkTexture.h'
4582--- unity-shared/GtkTexture.h 1970-01-01 00:00:00 +0000
4583+++ unity-shared/GtkTexture.h 2014-03-10 19:41:23 +0000
4584@@ -0,0 +1,64 @@
4585+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
4586+/*
4587+ * Copyright 2013 Canonical Ltd.
4588+ *
4589+ * This program is free software: you can redistribute it and/or modify it
4590+ * under the terms of the GNU Lesser General Public License version 3, as
4591+ * published by the Free Software Foundation.
4592+ *
4593+ * This program is distributed in the hope that it will be useful, but
4594+ * WITHOUT ANY WARRANTY; without even the implied warranties of
4595+ * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
4596+ * PURPOSE. See the applicable version of the GNU Lesser General Public
4597+ * License for more details.
4598+ *
4599+ * You should have received a copy of both the GNU Lesser General Public
4600+ * License version 3 along with this program. If not, see
4601+ * <http://www.gnu.org/licenses/>
4602+ *
4603+ * Authored by: Andrea Azzarone <andrea.azzarone@canonical.com>
4604+ *
4605+ */
4606+
4607+#ifndef UNITY_GDK_TEXTURE_H
4608+#define UNITY_GDK_TEXTURE_H
4609+
4610+#include <Nux/Nux.h>
4611+#include <NuxGraphics/GdkGraphics.h>
4612+#include <NuxGraphics/NuxGraphics.h>
4613+#include <NuxGraphics/GLTextureResourceManager.h>
4614+
4615+namespace unity
4616+{
4617+
4618+typedef nux::ObjectPtr<nux::BaseTexture> BaseTexturePtr;
4619+
4620+// Create a texture from the GdkGraphics object.
4621+//
4622+// Returns a new BaseTexture that has a ref count of 1.
4623+inline nux::BaseTexture* texture_from_gdk_graphics(nux::GdkGraphics const& cg)
4624+{
4625+ nux::NBitmapData* bitmap = cg.GetBitmap();
4626+ nux::BaseTexture* tex = nux::GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableTexture();
4627+ tex->Update(bitmap);
4628+ delete bitmap;
4629+ return tex;
4630+}
4631+
4632+// Create a texture from the GdkGraphics object.
4633+//
4634+// Returns a new smart pointer to a texture where that smart pointer is the
4635+// sole owner of the texture object.
4636+inline BaseTexturePtr texture_ptr_from_gdk_graphics(nux::GdkGraphics const& cg)
4637+{
4638+ BaseTexturePtr result(texture_from_gdk_graphics(cg));
4639+ // Since the ObjectPtr takes a reference, and the texture is initially
4640+ // owned, the reference count now is two.
4641+ nuxAssert(result->GetReferenceCount() == 2);
4642+ result->UnReference();
4643+ return result;
4644+}
4645+
4646+}
4647+
4648+#endif
4649
4650=== modified file 'unity-shared/IMTextEntry.cpp'
4651--- unity-shared/IMTextEntry.cpp 2012-07-04 02:37:23 +0000
4652+++ unity-shared/IMTextEntry.cpp 2014-03-10 19:41:23 +0000
4653@@ -1,4 +1,4 @@
4654-// -*- Mode: C++; indent-tabs-mode: ni; tab-width: 2 -*-
4655+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
4656 /*
4657 * Copyright (C) 2011-2012 Canonical Ltd
4658 *
4659@@ -26,7 +26,7 @@
4660 NUX_IMPLEMENT_OBJECT_TYPE(IMTextEntry);
4661
4662 IMTextEntry::IMTextEntry()
4663-: TextEntry("", NUX_TRACKER_LOCATION)
4664+ : TextEntry("", NUX_TRACKER_LOCATION)
4665 {}
4666
4667 void IMTextEntry::CopyClipboard()
4668@@ -85,4 +85,5 @@
4669 {
4670 return !preedit_.empty();
4671 }
4672+
4673 }
4674
4675=== modified file 'unity-shared/IMTextEntry.h'
4676--- unity-shared/IMTextEntry.h 2013-11-06 11:21:43 +0000
4677+++ unity-shared/IMTextEntry.h 2014-03-10 19:41:23 +0000
4678@@ -32,7 +32,7 @@
4679 NUX_DECLARE_OBJECT_TYPE(IMTextEntry, nux::TextEntry);
4680 public:
4681 IMTextEntry();
4682- virtual ~IMTextEntry() {}
4683+
4684 bool im_preedit();
4685
4686 protected:
4687
4688=== modified file 'unity-shared/MockableBaseWindow.h'
4689--- unity-shared/MockableBaseWindow.h 2013-11-06 11:21:43 +0000
4690+++ unity-shared/MockableBaseWindow.h 2014-03-10 19:41:23 +0000
4691@@ -37,7 +37,6 @@
4692 : nux::BaseWindow(window_name, NUX_TRACKER_LOCATION)
4693 , struts_enabled_(false)
4694 {}
4695- virtual ~MockableBaseWindow() {}
4696
4697 /**
4698 * Sets the window opacity.
4699
4700=== modified file 'unity-shared/TextInput.cpp'
4701--- unity-shared/TextInput.cpp 2014-02-25 03:35:17 +0000
4702+++ unity-shared/TextInput.cpp 2014-03-10 19:41:23 +0000
4703@@ -30,9 +30,8 @@
4704 const int HIGHLIGHT_HEIGHT = 24;
4705
4706 // Fonts
4707-const std::string HINT_LABEL_FONT_SIZE = "12px";
4708-const std::string HINT_LABEL_FONT_STYLE = "Italic";
4709-const std::string HINT_LABEL_DEFAULT_FONT = "Ubuntu " + HINT_LABEL_FONT_STYLE + " " + HINT_LABEL_FONT_SIZE;
4710+const std::string HINT_LABEL_DEFAULT_FONT_NAME = "Ubuntu";
4711+const int HINT_LABEL_FONT_SIZE = 11;
4712
4713 const std::string PANGO_ENTRY_DEFAULT_FONT_FAMILY = "Ubuntu";
4714 const int PANGO_ENTRY_FONT_SIZE = 14;
4715@@ -42,34 +41,33 @@
4716 namespace unity
4717 {
4718
4719-nux::logging::Logger logger("unity.dash.textinput");
4720+nux::logging::Logger logger("unity.textinput");
4721
4722 NUX_IMPLEMENT_OBJECT_TYPE(TextInput);
4723
4724 TextInput::TextInput(NUX_FILE_LINE_DECL)
4725 : View(NUX_FILE_LINE_PARAM)
4726 , input_hint("")
4727+ , hint_font_name(HINT_LABEL_DEFAULT_FONT_NAME)
4728+ , hint_font_size(HINT_LABEL_FONT_SIZE)
4729+ , bg_layer_(new nux::ColorLayer(nux::Color(0xff595853), true))
4730 , last_width_(-1)
4731 , last_height_(-1)
4732 {
4733- Init();
4734-}
4735-
4736-void TextInput::Init()
4737-{
4738- bg_layer_.reset(new nux::ColorLayer(nux::Color(0xff595853), true));
4739-
4740 layout_ = new nux::HLayout(NUX_TRACKER_LOCATION);
4741 layout_->SetLeftAndRightPadding(LEFT_INTERNAL_PADDING, TEXT_INPUT_RIGHT_BORDER);
4742 layout_->SetSpaceBetweenChildren(SPACE_BETWEEN_ENTRY_AND_HIGHLIGHT);
4743 SetLayout(layout_);
4744
4745 nux::HLayout* hint_layout = new nux::HLayout(NUX_TRACKER_LOCATION);
4746+ hint_layout->SetLeftAndRightPadding(3, 3);
4747
4748- hint_ = new StaticCairoText(" ");
4749+ hint_ = new StaticCairoText("");
4750 hint_->SetTextColor(nux::Color(1.0f, 1.0f, 1.0f, 0.5f));
4751- hint_->SetFont(HINT_LABEL_DEFAULT_FONT.c_str());
4752- hint_layout->AddView(hint_, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL);
4753+ hint_layout->AddView(hint_, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL);
4754+ hint_font_name.changed.connect(sigc::hide(sigc::mem_fun(this, &TextInput::UpdateHintFont)));
4755+ hint_font_size.changed.connect(sigc::hide(sigc::mem_fun(this, &TextInput::UpdateHintFont)));
4756+ UpdateHintFont();
4757
4758 pango_entry_ = new IMTextEntry();
4759 pango_entry_->SetFontFamily(PANGO_ENTRY_DEFAULT_FONT_FAMILY.c_str());
4760@@ -77,14 +75,22 @@
4761 pango_entry_->cursor_moved.connect([this](int i) { QueueDraw(); });
4762 pango_entry_->mouse_down.connect(sigc::mem_fun(this, &TextInput::OnMouseButtonDown));
4763 pango_entry_->end_key_focus.connect(sigc::mem_fun(this, &TextInput::OnEndKeyFocus));
4764+ pango_entry_->text_changed.connect([this](nux::TextEntry*) {
4765+ hint_->SetVisible(input_string().empty());
4766+ });
4767
4768 layered_layout_ = new nux::LayeredLayout();
4769- layered_layout_->AddLayout(hint_layout);
4770+ layered_layout_->AddLayer(hint_layout);
4771 layered_layout_->AddLayer(pango_entry_);
4772 layered_layout_->SetPaintAll(true);
4773 layered_layout_->SetActiveLayerN(1);
4774 layout_->AddView(layered_layout_, 1, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FIX);
4775
4776+ spinner_ = new SearchBarSpinner();
4777+ spinner_->SetVisible(false);
4778+ spinner_->SetMinMaxSize(22, 22);
4779+ layout_->AddView(spinner_, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL);
4780+
4781 sig_manager_.Add<void, GtkSettings*, GParamSpec*>(gtk_settings_get_default(),
4782 "notify::gtk-font-name", sigc::mem_fun(this, &TextInput::OnFontChanged));
4783 OnFontChanged(gtk_settings_get_default());
4784@@ -97,11 +103,25 @@
4785
4786 }
4787
4788+void TextInput::SetSpinnerVisible(bool visible)
4789+{
4790+ spinner_->SetVisible(visible);
4791+}
4792+
4793+void TextInput::SetSpinnerState(SpinnerState spinner_state)
4794+{
4795+ spinner_->SetState(spinner_state);
4796+}
4797+
4798+void TextInput::UpdateHintFont()
4799+{
4800+ hint_->SetFont((hint_font_name() + " " + std::to_string(hint_font_size())).c_str());
4801+}
4802+
4803 void TextInput::OnFontChanged(GtkSettings* settings, GParamSpec* pspec)
4804 {
4805 glib::String font_name;
4806 PangoFontDescription* desc;
4807- std::ostringstream font_desc;
4808
4809 g_object_get(settings, "gtk-font-name", &font_name, NULL);
4810
4811@@ -112,20 +132,19 @@
4812 pango_entry_->SetFontSize(PANGO_ENTRY_FONT_SIZE);
4813 pango_entry_->SetFontOptions(gdk_screen_get_font_options(gdk_screen_get_default()));
4814
4815- font_desc << pango_font_description_get_family(desc) << " " << HINT_LABEL_FONT_STYLE << " " << HINT_LABEL_FONT_SIZE;
4816- hint_->SetFont(font_desc.str().c_str());
4817-
4818- font_desc.str("");
4819- font_desc.clear();
4820-
4821- pango_font_description_free(desc);
4822+ if (hint_font_name() == HINT_LABEL_DEFAULT_FONT_NAME)
4823+ {
4824+ std::ostringstream font_desc;
4825+ font_desc << pango_font_description_get_family(desc) << " " << hint_font_size();
4826+ hint_->SetFont(font_desc.str().c_str());
4827+ pango_font_description_free(desc);
4828+ }
4829 }
4830 }
4831
4832 void TextInput::OnInputHintChanged()
4833 {
4834- glib::String tmp(g_markup_escape_text(input_hint().c_str(), -1));
4835- hint_->SetText(tmp);
4836+ hint_->SetText(input_hint().c_str(), true);
4837 }
4838
4839 void TextInput::Draw(nux::GraphicsEngine& GfxContext, bool force_draw)
4840@@ -184,14 +203,10 @@
4841 {
4842 int RADIUS = 5;
4843 nux::Geometry geo(GetGeometry());
4844- geo.width = layered_layout_->GetAbsoluteX() +
4845- layered_layout_->GetAbsoluteWidth() -
4846- GetAbsoluteX() +
4847- TEXT_INPUT_RIGHT_BORDER;
4848
4849 LOG_DEBUG(logger) << "height: "
4850 << geo.height << " - "
4851- << layered_layout_->GetGeometry().height << " - "
4852+ << layout_->GetGeometry().height << " - "
4853 << pango_entry_->GetGeometry().height;
4854
4855 if (geo.width == last_width_
4856@@ -250,7 +265,7 @@
4857 }
4858
4859
4860-nux::TextEntry* TextInput::text_entry() const
4861+IMTextEntry* TextInput::text_entry() const
4862 {
4863 return pango_entry_;
4864 }
4865
4866=== modified file 'unity-shared/TextInput.h'
4867--- unity-shared/TextInput.h 2013-09-19 16:44:03 +0000
4868+++ unity-shared/TextInput.h 2014-03-10 19:41:23 +0000
4869@@ -39,6 +39,7 @@
4870 #include "unity-shared/IconTexture.h"
4871 #include "unity-shared/IMTextEntry.h"
4872 #include "unity-shared/Introspectable.h"
4873+#include "unity-shared/SearchBarSpinner.h"
4874 #include "unity-shared/StaticCairoText.h"
4875
4876 namespace nux
4877@@ -49,6 +50,7 @@
4878
4879 namespace unity
4880 {
4881+
4882 class TextInput : public unity::debug::Introspectable, public nux::View
4883 {
4884 NUX_DECLARE_OBJECT_TYPE(TextInput, nux::View);
4885@@ -56,18 +58,22 @@
4886 public:
4887 typedef nux::ObjectPtr<TextInput> Ptr;
4888 TextInput(NUX_FILE_LINE_PROTO);
4889- TextInput(bool show_filter_hint, NUX_FILE_LINE_PROTO);
4890-
4891- nux::TextEntry* text_entry() const;
4892+
4893+ void SetSpinnerVisible(bool visible);
4894+ void SetSpinnerState(SpinnerState spinner_state);
4895+
4896+ IMTextEntry* text_entry() const;
4897
4898 nux::RWProperty<std::string> input_string;
4899 nux::Property<std::string> input_hint;
4900+ nux::Property<std::string> hint_font_name;
4901+ nux::Property<int> hint_font_size;
4902 nux::ROProperty<bool> im_active;
4903 nux::ROProperty<bool> im_preedit;
4904
4905 private:
4906-
4907 void OnFontChanged(GtkSettings* settings, GParamSpec* pspec=NULL);
4908+ void UpdateHintFont();
4909 void Draw(nux::GraphicsEngine& GfxContext, bool force_draw);
4910 void DrawContent(nux::GraphicsEngine& GfxContext, bool force_draw);
4911 void UpdateBackground(bool force);
4912@@ -78,11 +84,8 @@
4913 bool AcceptKeyNavFocus();
4914
4915 protected:
4916-
4917- void Init();
4918 void OnInputHintChanged();
4919- void OnMouseButtonDown(int x, int y, unsigned long button_flags,
4920- unsigned long key_flags);
4921+ void OnMouseButtonDown(int x, int y, unsigned long button_flags, unsigned long key_flags);
4922 void OnEndKeyFocus();
4923
4924 // getters & setters
4925@@ -104,6 +107,7 @@
4926 std::unique_ptr<nux::AbstractPaintLayer> highlight_layer_;
4927 nux::HLayout* layout_;
4928 nux::LayeredLayout* layered_layout_;
4929+ SearchBarSpinner* spinner_;
4930
4931 int last_width_;
4932 int last_height_;
4933
4934=== modified file 'unity-shared/UScreen.cpp'
4935--- unity-shared/UScreen.cpp 2014-02-27 05:30:25 +0000
4936+++ unity-shared/UScreen.cpp 2014-03-10 19:41:23 +0000
4937@@ -98,16 +98,16 @@
4938
4939 const std::string UScreen::GetMonitorName(int output_number = 0) const
4940 {
4941- if (output_number < 0 || output_number > gdk_screen_get_n_monitors(screen_))
4942+ if (output_number < 0 || output_number >= gdk_screen_get_n_monitors(screen_))
4943 {
4944- LOG_ERROR(logger) << "UScreen::GetMonitorName: Invalid monitor number" << output_number;
4945+ LOG_WARN(logger) << "UScreen::GetMonitorName: Invalid monitor number" << output_number;
4946 return "";
4947 }
4948
4949 glib::String output_name(gdk_screen_get_monitor_plug_name(screen_, output_number));
4950 if (!output_name)
4951 {
4952- LOG_ERROR(logger) << "UScreen::GetMonitorName: Failed to get monitor name for monitor" << output_number;
4953+ LOG_WARN(logger) << "UScreen::GetMonitorName: Failed to get monitor name for monitor" << output_number;
4954 return "";
4955 }
4956
4957
4958=== modified file 'unity-shared/UnityWindowView.cpp'
4959--- unity-shared/UnityWindowView.cpp 2013-11-21 19:38:45 +0000
4960+++ unity-shared/UnityWindowView.cpp 2014-03-10 19:41:23 +0000
4961@@ -245,7 +245,7 @@
4962 auto temp_background_color = background_color();
4963 auto blend_mode = nux::LAYER_BLEND_MODE_OVERLAY;
4964
4965- if (Settings::Instance().GetLowGfxMode())
4966+ if (Settings::Instance().GetLowGfxMode() || BackgroundEffectHelper::blur_type == BLUR_NONE)
4967 {
4968 temp_background_color.alpha = 1.0f;
4969 blend_mode = nux::LAYER_BLEND_MODE_NORMAL;
4970
4971=== added file 'unity-shared/UpstartWrapper.cpp'
4972--- unity-shared/UpstartWrapper.cpp 1970-01-01 00:00:00 +0000
4973+++ unity-shared/UpstartWrapper.cpp 2014-03-10 19:41:23 +0000
4974@@ -0,0 +1,74 @@
4975+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
4976+/*
4977+* Copyright (C) 2014 Canonical Ltd
4978+*
4979+* This program is free software: you can redistribute it and/or modify
4980+* it under the terms of the GNU General Public License version 3 as
4981+* published by the Free Software Foundation.
4982+*
4983+* This program is distributed in the hope that it will be useful,
4984+* but WITHOUT ANY WARRANTY; without even the implied warranty of
4985+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4986+* GNU General Public License for more details.
4987+*
4988+* You should have received a copy of the GNU General Public License
4989+* along with this program. If not, see <http://www.gnu.org/licenses/>.
4990+*
4991+* Authored by: Andrea Azzarone <andrea.azzarone@canonical.com>
4992+*/
4993+
4994+#include "UpstartWrapper.h"
4995+
4996+#include <UnityCore/GLibDBusProxy.h>
4997+
4998+namespace unity
4999+{
5000+
The diff has been truncated for viewing.