Merge lp:~unity-team/unity/7.2.4 into lp:unity/7.2

Proposed by Stephen M. Webb on 2014-12-15
Status: Merged
Approved by: Marco Trevisan (Treviño) on 2014-12-17
Approved revision: 3827
Merged at revision: 3806
Proposed branch: lp:~unity-team/unity/7.2.4
Merge into: lp:unity/7.2
Diff against target: 6023 lines (+2168/-709)
105 files modified
CMakeLists.txt (+1/-0)
UnityCore/DBusIndicators.cpp (+11/-0)
UnityCore/DBusIndicators.h (+1/-0)
UnityCore/DesktopUtilities.cpp (+12/-0)
UnityCore/DesktopUtilities.h (+1/-0)
UnityCore/GLibDBusProxy.cpp (+100/-3)
UnityCore/GLibDBusProxy.h (+6/-0)
UnityCore/GLibWrapper-inl.h (+12/-0)
UnityCore/GLibWrapper.h (+1/-0)
UnityCore/GnomeSessionManager.cpp (+0/-1)
UnityCore/Indicators.h (+1/-0)
dash/FilterBasicButton.cpp (+6/-3)
dash/previews/ActionButton.cpp (+5/-2)
dash/previews/ErrorPreview.cpp (+1/-0)
dash/previews/PaymentPreview.cpp (+3/-1)
data/CMakeLists.txt (+1/-0)
data/pam/CMakeLists.txt (+1/-0)
data/pam/unity (+2/-0)
debian/changelog (+59/-0)
debian/rules (+1/-1)
debian/unity.install (+1/-0)
debian/unity.migrations (+1/-0)
decorations/DecoratedWindow.cpp (+155/-64)
decorations/DecorationsEdgeBorders.cpp (+32/-19)
decorations/DecorationsForceQuitDialog.cpp (+17/-3)
decorations/DecorationsManager.cpp (+17/-26)
decorations/DecorationsPriv.h (+12/-3)
decorations/DecorationsTitle.cpp (+1/-0)
decorations/DecorationsWidgets.cpp (+13/-1)
decorations/DecorationsWidgets.h (+5/-0)
doc/unity.1 (+35/-10)
hud/HudIconTextureSource.cpp (+0/-5)
hud/HudIconTextureSource.h (+0/-1)
launcher/ApplicationLauncherIcon.cpp (+2/-0)
launcher/DesktopLauncherIcon.cpp (+13/-1)
launcher/DesktopLauncherIcon.h (+2/-0)
launcher/Launcher.cpp (+1/-3)
launcher/LauncherIcon.cpp (+117/-104)
launcher/LauncherIcon.h (+12/-8)
launcher/MockLauncherIcon.h (+0/-5)
launcher/SwitcherView.cpp (+9/-1)
launcher/Tooltip.cpp (+5/-4)
lockscreen/BackgroundSettings.cpp (+13/-11)
lockscreen/BackgroundSettings.h (+0/-1)
lockscreen/CMakeLists.txt (+2/-0)
lockscreen/CofView.cpp (+15/-2)
lockscreen/CofView.h (+3/-1)
lockscreen/LockScreenAbstractShield.h (+14/-1)
lockscreen/LockScreenController.cpp (+54/-14)
lockscreen/LockScreenController.h (+12/-3)
lockscreen/LockScreenPanel.cpp (+31/-2)
lockscreen/LockScreenSettings.cpp (+2/-0)
lockscreen/LockScreenSettings.h (+2/-1)
lockscreen/LockScreenShield.cpp (+60/-29)
lockscreen/LockScreenShield.h (+10/-3)
lockscreen/LockScreenShieldFactory.cpp (+7/-2)
lockscreen/LockScreenShieldFactory.h (+12/-2)
lockscreen/ShutdownNotifier.cpp (+152/-0)
lockscreen/ShutdownNotifier.h (+51/-0)
lockscreen/SuspendNotifier.cpp (+153/-0)
lockscreen/SuspendNotifier.h (+51/-0)
lockscreen/UserAuthenticatorPam.cpp (+1/-2)
lockscreen/UserPromptView.cpp (+96/-17)
lockscreen/UserPromptView.h (+5/-4)
panel/PanelIndicatorEntryView.cpp (+1/-1)
panel/PanelMenuView.cpp (+83/-38)
panel/PanelMenuView.h (+1/-1)
plugins/unityshell/src/unityshell.cpp (+29/-35)
plugins/unityshell/src/unityshell.h (+2/-2)
services/panel-main.c (+8/-0)
services/panel-service.c (+15/-0)
services/panel-service.h (+2/-0)
tests/CMakeLists.txt (+1/-1)
tests/mock_indicators.h (+1/-0)
tests/test_lockscreen_controller.cpp (+10/-2)
tests/test_main_xless.cpp (+4/-5)
tests/test_previews_music_payment.cpp (+1/-0)
tests/test_text_input.cpp (+1/-0)
tools/migration-scripts/03_unity_first_run_stamp_move (+35/-0)
unity-shared/CompizUtils.cpp (+77/-58)
unity-shared/CompizUtils.h (+36/-5)
unity-shared/DashStyle.cpp (+8/-11)
unity-shared/DecorationStyle.cpp (+2/-2)
unity-shared/GnomeKeyGrabber.cpp (+9/-0)
unity-shared/IconRenderer.cpp (+73/-43)
unity-shared/IconRenderer.h (+0/-2)
unity-shared/IconTexture.cpp (+1/-1)
unity-shared/IconTextureSource.cpp (+37/-1)
unity-shared/IconTextureSource.h (+10/-4)
unity-shared/LayoutSystem.cpp (+28/-4)
unity-shared/LayoutSystem.h (+2/-1)
unity-shared/PluginAdapter.cpp (+39/-2)
unity-shared/PluginAdapter.h (+3/-0)
unity-shared/SearchBar.cpp (+18/-12)
unity-shared/SearchBar.h (+9/-9)
unity-shared/SearchBarSpinner.h (+0/-2)
unity-shared/SpreadFilter.cpp (+3/-1)
unity-shared/StandaloneWindowManager.h (+2/-0)
unity-shared/TextInput.cpp (+138/-76)
unity-shared/TextInput.h (+17/-19)
unity-shared/UScreen.cpp (+26/-4)
unity-shared/UScreen.h (+0/-1)
unity-shared/UnitySettings.cpp (+9/-1)
unity-shared/WindowManager.h (+5/-0)
unity-shared/XWindowManager.cpp (+1/-1)
To merge this branch: bzr merge lp:~unity-team/unity/7.2.4
Reviewer Review Type Date Requested Status
Marco Trevisan (Treviño) 2014-12-15 Approve on 2014-12-17
Review via email: mp+244802@code.launchpad.net

Commit Message

release 7.2.4

Description of the Change

Backported fixes for Trusty SRU-4.

 [ Andrea Azzarone ]
 * Share lockscreen password between screens (lp: #1308540)
 * Allow a distinct pam config file for greeter and for lock-screen.
 (lp: #1305440)
 * Add an arrow activator in the lockscreen. (lp: #1332509)
 * Make sure GetScreenGeometry returns the correct value (lp: #1374785).

 [ Brandon Schaefer ]
 * fix tooltip for the "Show Desktop / Restore Windows" icon in the Alt-Tab
   switcher (lp: #1237132)
 * Use CONFIG instead of CACHE to store the first_run.stamp (lp: #1328677)

 [ Eleni Maria Stea ]
 * LayoutSystem: make sure the exposed open windows are displayed in the
   preserved order (lp: #1349281).

 [ handsome_feng ]
 * added support for getting the distro name from /etc/os-release
 (lp: #1329584)

 [ Iain Lane ]
 * When grabbing keys, try prefixing "XF86" if the key isn't found. GNOME
   gives us unprefixed keys sometimes (lp: #1302885).

 [ Marco Trevisan (Treviño) ]
 * make the Launcher icon count badge width depend on the text value width
   and scaling (lp: #1353070) (lp: #1354498) (lp: #796527) (lp: #1066971)
   (lp: #1361713)
 * DecoratedWindow: make edges independent from borders and properly update
   them on actions change (lp: #1276177), (lp: #1299741), (lp: #1301776),
   (lp: #1324104), (lp: #1364225), (lp: #1373695)
 * Lockscreen: scale the UI elements based on current monitor scaling
   (lp: #1292218)
 * UnityScreen: when filtering out windows in spread, make sure we unscale
   them (lp: #1316265).
 * PanelMenuView: ensure that proper window tiles and buttons are shown at
   the right place (lp: #1384910) (lp: #1384958) (lp: #1385285)
 * SearchBar, ActionButtons, IconRenderer: include the font scaling when
   scaling textual items (lp: #1332947) (lp: #1361751) (lp: #1362162)
   (lp: #1362346).
 * ApplicationLauncherIcon: make sure we close the dash if DnD is accepted
   and the application window is about to be focused (lp: #1350331).
 * SwitcherView: set progress on icon render args (lp: #1361679).
 * LockScreenController: wait for the primary shield to get the grab
   before setting the session locked (lp: #1368427) (lp: #1371764).

 [ Stephen M. Webb ]
 * updated the unity(1) manpage to match the actual command (lp: #1059275)
 * packaging version bump

To post a comment you must log in.
lp:~unity-team/unity/7.2.4 updated on 2014-12-17
3823. By Stephen M. Webb on 2014-12-16

unmapped all windows prior to shutdown (lp: #1370017) (lp: #1375271)

3824. By Stephen M. Webb on 2014-12-16

added decorations to windows in non-focused workspaces (lp: #1383468)

3825. By Stephen M. Webb on 2014-12-16

fixup for bug introduced in r3809

3826. By Stephen M. Webb on 2014-12-16

bumped package version to match upstream

3827. By Marco Trevisan (Treviño) on 2014-12-17

DesktopUtilities: remove leftover debug statement

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

Looks good!

There are some old fixes for bugs #1363534 and #1351591 that are not included here, but we might include them later.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'CMakeLists.txt'
2--- CMakeLists.txt 2014-10-29 16:43:57 +0000
3+++ CMakeLists.txt 2014-12-17 12:14:47 +0000
4@@ -259,6 +259,7 @@
5 add_subdirectory(unity-shared)
6 add_subdirectory(dash)
7 add_subdirectory(launcher)
8+add_subdirectory(data)
9 if (ENABLE_X_SUPPORT)
10 add_subdirectory(hud)
11 add_subdirectory(lockscreen)
12
13=== modified file 'UnityCore/DBusIndicators.cpp'
14--- UnityCore/DBusIndicators.cpp 2014-03-05 17:19:50 +0000
15+++ UnityCore/DBusIndicators.cpp 2014-12-17 12:14:47 +0000
16@@ -55,6 +55,7 @@
17 void Sync(GVariant* args, glib::Error const&);
18 void SyncGeometries(std::string const& name, EntryLocationMap const& locations);
19 void ShowEntriesDropdown(Indicator::Entries const&, Entry::Ptr const&, unsigned xid, int x, int y);
20+ void CloseActiveEntry();
21
22 void OnConnected();
23 void OnDisconnected();
24@@ -313,6 +314,11 @@
25 gproxy_.Call("ScrollEntry", g_variant_new("(si)", entry_id.c_str(), delta));
26 }
27
28+void DBusIndicators::Impl::CloseActiveEntry()
29+{
30+ gproxy_.Call("CloseActiveEntry");
31+}
32+
33 void DBusIndicators::Impl::Sync(GVariant* args, glib::Error const& error)
34 {
35 if (!args || error)
36@@ -489,6 +495,11 @@
37 pimpl->ShowEntriesDropdown(entries, selected, xid, x, y);
38 }
39
40+void DBusIndicators::CloseActiveEntry()
41+{
42+ pimpl->CloseActiveEntry();
43+}
44+
45 void DBusIndicators::OnEntryScroll(std::string const& entry_id, int delta)
46 {
47 pimpl->OnEntryScroll(entry_id, delta);
48
49=== modified file 'UnityCore/DBusIndicators.h'
50--- UnityCore/DBusIndicators.h 2014-03-04 13:14:12 +0000
51+++ UnityCore/DBusIndicators.h 2014-12-17 12:14:47 +0000
52@@ -40,6 +40,7 @@
53 std::vector<std::string> const& IconPaths() const;
54 void ShowEntriesDropdown(Indicator::Entries const&, Entry::Ptr const&, unsigned xid, int x, int y);
55 void SyncGeometries(std::string const& name, EntryLocationMap const& locations);
56+ void CloseActiveEntry();
57
58 protected:
59 virtual void OnEntryScroll(std::string const& entry_id, int delta);
60
61=== modified file 'UnityCore/DesktopUtilities.cpp'
62--- UnityCore/DesktopUtilities.cpp 2014-04-16 22:17:11 +0000
63+++ UnityCore/DesktopUtilities.cpp 2014-12-17 12:14:47 +0000
64@@ -66,6 +66,18 @@
65 return "";
66 }
67
68+std::string DesktopUtilities::GetUserConfigDirectory()
69+{
70+ const char *config_dir = g_get_user_config_dir();
71+ auto unity_config = glib::gchar_to_string(config_dir).append(G_DIR_SEPARATOR_S "unity" G_DIR_SEPARATOR_S);
72+
73+ if (g_mkdir_with_parents(unity_config.c_str(), 0700) >= 0)
74+ return unity_config;
75+
76+ LOG_ERROR(logger) << "Impossible to create unity config folder '"<< unity_config <<"' !";
77+ return "";
78+}
79+
80 std::string DesktopUtilities::GetUserRuntimeDirectory()
81 {
82 const char *runtime_dir = g_get_user_runtime_dir();
83
84=== modified file 'UnityCore/DesktopUtilities.h'
85--- UnityCore/DesktopUtilities.h 2014-04-16 22:17:11 +0000
86+++ UnityCore/DesktopUtilities.h 2014-12-17 12:14:47 +0000
87@@ -32,6 +32,7 @@
88 static std::string GetUserDataDirectory();
89 static std::string GetUserCacheDirectory();
90 static std::string GetUserRuntimeDirectory();
91+ static std::string GetUserConfigDirectory();
92 static std::vector<std::string> GetSystemDataDirectories();
93 static std::vector<std::string> GetDataDirectories();
94
95
96=== modified file 'UnityCore/GLibDBusProxy.cpp'
97--- UnityCore/GLibDBusProxy.cpp 2013-11-19 18:48:35 +0000
98+++ UnityCore/GLibDBusProxy.cpp 2014-12-17 12:14:47 +0000
99@@ -21,7 +21,7 @@
100
101 #include "GLibDBusProxy.h"
102
103-#include <map>
104+#include <unordered_map>
105 #include <memory>
106 #include <NuxCore/Logger.h>
107 #include <vector>
108@@ -30,6 +30,8 @@
109 #include "GLibSignal.h"
110 #include "GLibSource.h"
111
112+#include <gio/gunixfdlist.h>
113+
114 namespace unity
115 {
116 namespace glib
117@@ -47,7 +49,7 @@
118 {
119 public:
120 typedef std::vector<ReplyCallback> Callbacks;
121- typedef std::map<string, Callbacks> SignalHandlers;
122+ typedef std::unordered_map<string, Callbacks> SignalHandlers;
123
124 Impl(DBusProxy* owner,
125 string const& name,
126@@ -74,6 +76,12 @@
127 GCancellable *cancellable,
128 GDBusCallFlags flags,
129 int timeout_msec);
130+ void CallWithUnixFdList(std::string const& method_name,
131+ GVariant* parameters,
132+ CallFinishedCallback const& callback,
133+ GCancellable *cancellable,
134+ GDBusCallFlags flags,
135+ int timeout_msec);
136
137 void Connect(string const& signal_name, ReplyCallback const& callback);
138 void DisconnectSignal(string const& signal_name);
139@@ -85,6 +93,7 @@
140
141 static void OnProxyConnectCallback(GObject* source, GAsyncResult* res, gpointer impl);
142 static void OnCallCallback(GObject* source, GAsyncResult* res, gpointer call_data);
143+ static void OnCallWithUnixFdListCallback(GObject* source, GAsyncResult* res, gpointer call_data);
144
145 struct CallData
146 {
147@@ -399,6 +408,50 @@
148 data);
149 }
150
151+void DBusProxy::Impl::CallWithUnixFdList(string const& method_name,
152+ GVariant* parameters,
153+ CallFinishedCallback const& callback,
154+ GCancellable* cancellable,
155+ GDBusCallFlags flags,
156+ int timeout_msec)
157+{
158+ GCancellable* target_canc = cancellable != NULL ? cancellable : cancellable_;
159+
160+ if (!proxy_)
161+ {
162+ glib::Variant sinked_parameters(parameters);
163+ glib::Object<GCancellable> canc(target_canc, glib::AddRef());
164+ WaitForProxy(canc, timeout_msec, [this, method_name, sinked_parameters, callback, canc, flags, timeout_msec] (glib::Error const& err)
165+ {
166+ if (err)
167+ {
168+ callback(glib::Variant(), err);
169+ LOG_WARNING(logger) << "Cannot call method " << method_name
170+ << ": " << err;
171+ }
172+ else
173+ {
174+ CallWithUnixFdList(method_name, sinked_parameters, callback, canc, flags, timeout_msec);
175+ }
176+ });
177+ return;
178+ }
179+
180+ CallData* data = new CallData();
181+ data->callback = callback;
182+ data->method_name = method_name;
183+
184+ g_dbus_proxy_call_with_unix_fd_list(proxy_,
185+ method_name.c_str(),
186+ parameters,
187+ flags,
188+ timeout_msec,
189+ nullptr,
190+ target_canc,
191+ DBusProxy::Impl::OnCallWithUnixFdListCallback,
192+ data);
193+}
194+
195 void DBusProxy::Impl::OnCallCallback(GObject* source, GAsyncResult* res, gpointer call_data)
196 {
197 glib::Error error;
198@@ -407,7 +460,7 @@
199
200 if (error)
201 {
202- if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
203+ if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
204 {
205 // silently ignore, don't even invoke callback, FIXME: really?
206 return;
207@@ -425,6 +478,39 @@
208 data->callback(result, error);
209 }
210
211+void DBusProxy::Impl::OnCallWithUnixFdListCallback(GObject* source, GAsyncResult* res, gpointer call_data)
212+{
213+ glib::Object<GUnixFDList> fd_list;
214+
215+ glib::Error error;
216+ std::unique_ptr<CallData> data(static_cast<CallData*>(call_data));
217+ glib::Variant result(g_dbus_proxy_call_with_unix_fd_list_finish(G_DBUS_PROXY(source), &fd_list, res, &error), glib::StealRef());
218+
219+ if (error)
220+ {
221+ if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
222+ {
223+ // silently ignore, don't even invoke callback, FIXME: really?
224+ return;
225+ }
226+ else
227+ {
228+ LOG_WARNING(logger) << "Calling method \"" << data->method_name
229+ << "\" on object path: \""
230+ << g_dbus_proxy_get_object_path(G_DBUS_PROXY(source))
231+ << "\" failed: " << error;
232+ }
233+ }
234+
235+ if (data->callback)
236+ {
237+ gint idx;
238+ g_variant_get(result, "(h)", &idx);
239+ gint fd = g_unix_fd_list_get(fd_list, idx, nullptr);
240+ data->callback(glib::Variant(fd), error);
241+ }
242+}
243+
244 void DBusProxy::Impl::Connect(std::string const& signal_name, ReplyCallback const& callback)
245 {
246 if (!callback)
247@@ -487,6 +573,17 @@
248 timeout_msec);
249 }
250
251+void DBusProxy::CallWithUnixFdList(std::string const& method_name,
252+ GVariant* parameters,
253+ CallFinishedCallback const& callback,
254+ GCancellable *cancellable,
255+ GDBusCallFlags flags,
256+ int timeout_msec)
257+{
258+ pimpl->CallWithUnixFdList(method_name, parameters, callback, cancellable,
259+ flags, timeout_msec);
260+}
261+
262 glib::Variant DBusProxy::GetProperty(std::string const& name) const
263 {
264 if (IsConnected())
265
266=== modified file 'UnityCore/GLibDBusProxy.h'
267--- UnityCore/GLibDBusProxy.h 2013-03-25 12:09:41 +0000
268+++ UnityCore/GLibDBusProxy.h 2014-12-17 12:14:47 +0000
269@@ -64,6 +64,12 @@
270 GCancellable *cancellable = nullptr,
271 GDBusCallFlags flags = G_DBUS_CALL_FLAGS_NONE,
272 int timeout_msec = -1);
273+ void CallWithUnixFdList(std::string const& method_name,
274+ GVariant* parameters = nullptr,
275+ CallFinishedCallback const& callback = nullptr,
276+ GCancellable *cancellable = nullptr,
277+ GDBusCallFlags flags = G_DBUS_CALL_FLAGS_NONE,
278+ int timeout_msec = -1);
279
280 bool IsConnected() const;
281
282
283=== modified file 'UnityCore/GLibWrapper-inl.h'
284--- UnityCore/GLibWrapper-inl.h 2012-07-04 20:16:06 +0000
285+++ UnityCore/GLibWrapper-inl.h 2014-12-17 12:14:47 +0000
286@@ -94,6 +94,18 @@
287 }
288
289 template <typename T>
290+T** Object<T>::operator&()
291+{
292+ if (object_)
293+ {
294+ g_object_unref(object_);
295+ object_ = nullptr;
296+ }
297+
298+ return &object_;
299+}
300+
301+template <typename T>
302 Object<T>::operator bool() const
303 {
304 return bool(object_);
305
306=== modified file 'UnityCore/GLibWrapper.h'
307--- UnityCore/GLibWrapper.h 2013-05-17 16:52:19 +0000
308+++ UnityCore/GLibWrapper.h 2014-12-17 12:14:47 +0000
309@@ -56,6 +56,7 @@
310 operator T* () const;
311 operator bool() const;
312 T* operator->() const;
313+ T** operator&();
314 T* RawPtr() const;
315 // Release ownership of the object. No unref will occur.
316 T* Release();
317
318=== modified file 'UnityCore/GnomeSessionManager.cpp'
319--- UnityCore/GnomeSessionManager.cpp 2014-07-23 18:56:11 +0000
320+++ UnityCore/GnomeSessionManager.cpp 2014-12-17 12:14:47 +0000
321@@ -432,7 +432,6 @@
322 return;
323 }
324
325- // FIXME (andy) we should ask gnome-session to emit the logind signal
326 prompt ? manager_->prompt_lock_requested.emit() : manager_->lock_requested.emit();
327 }
328
329
330=== modified file 'UnityCore/Indicators.h'
331--- UnityCore/Indicators.h 2014-02-28 05:16:10 +0000
332+++ UnityCore/Indicators.h 2014-12-17 12:14:47 +0000
333@@ -44,6 +44,7 @@
334
335 virtual void SyncGeometries(std::string const& panel, EntryLocationMap const&) = 0;
336 virtual void ShowEntriesDropdown(Indicator::Entries const&, Entry::Ptr const&, unsigned xid, int x, int y) = 0;
337+ virtual void CloseActiveEntry() = 0;
338
339 // Signals
340 sigc::signal<void, Indicator::Ptr const&> on_object_added;
341
342=== modified file 'dash/FilterBasicButton.cpp'
343--- dash/FilterBasicButton.cpp 2014-07-24 14:03:10 +0000
344+++ dash/FilterBasicButton.cpp 2014-12-17 12:14:47 +0000
345@@ -20,6 +20,7 @@
346 */
347
348 #include "unity-shared/DashStyle.h"
349+#include "unity-shared/UnitySettings.h"
350 #include "FilterBasicButton.h"
351
352 namespace unity
353@@ -70,6 +71,7 @@
354 });
355
356 scale.changed.connect(sigc::mem_fun(this, &FilterBasicButton::UpdateScale));
357+ Settings::Instance().font_scaling.changed.connect(sigc::hide(sigc::mem_fun(this, &FilterBasicButton::InitTheme)));
358 }
359
360 void FilterBasicButton::InitTheme()
361@@ -81,11 +83,12 @@
362 normal_.reset(new nux::CairoWrapper(geo, sigc::bind(sigc::mem_fun(this, &FilterBasicButton::RedrawTheme), nux::ButtonVisualState::VISUAL_STATE_NORMAL)));
363 focus_.reset(new nux::CairoWrapper(geo, sigc::mem_fun(this, &FilterBasicButton::RedrawFocusOverlay)));
364
365- SetMinimumWidth(MIN_BUTTON_WIDTH.CP(scale));
366+ double font_scaling = Settings::Instance().font_scaling() * scale;
367+ SetMinimumWidth(MIN_BUTTON_WIDTH.CP(font_scaling));
368 ApplyMinWidth();
369
370- SetMinimumHeight(BUTTON_HEIGHT.CP(scale));
371- SetMaximumHeight(BUTTON_HEIGHT.CP(scale));
372+ SetMinimumHeight(BUTTON_HEIGHT.CP(font_scaling));
373+ SetMaximumHeight(BUTTON_HEIGHT.CP(font_scaling));
374 }
375
376 void FilterBasicButton::RedrawTheme(nux::Geometry const& geom, cairo_t* cr, nux::ButtonVisualState faked_state)
377
378=== modified file 'dash/previews/ActionButton.cpp'
379--- dash/previews/ActionButton.cpp 2014-07-24 14:03:10 +0000
380+++ dash/previews/ActionButton.cpp 2014-12-17 12:14:47 +0000
381@@ -25,6 +25,7 @@
382 #include <Nux/HLayout.h>
383 #include "unity-shared/IconTexture.h"
384 #include "unity-shared/StaticCairoText.h"
385+#include "unity-shared/UnitySettings.h"
386
387 namespace unity
388 {
389@@ -51,6 +52,7 @@
390 Init();
391 BuildLayout(label, icon_hint, "");
392 scale.changed.connect(sigc::mem_fun(this, &ActionButton::UpdateScale));
393+ Settings::Instance().font_scaling.changed.connect(sigc::hide(sigc::mem_fun(this, &ActionButton::InitTheme)));
394 }
395
396 ActionButton::~ActionButton()
397@@ -93,8 +95,9 @@
398 cr_normal_.reset(new nux::CairoWrapper(geo, sigc::bind(sigc::mem_fun(this, &ActionButton::RedrawTheme), nux::ButtonVisualState::VISUAL_STATE_NORMAL)));
399 cr_focus_.reset(new nux::CairoWrapper(geo, sigc::mem_fun(this, &ActionButton::RedrawFocusOverlay)));
400
401- SetMinimumHeight(MIN_BUTTON_HEIGHT.CP(scale));
402- SetMinimumWidth(MIN_BUTTON_WIDTH.CP(scale));
403+ double font_scaling = Settings::Instance().font_scaling() * scale;
404+ SetMinimumHeight(MIN_BUTTON_HEIGHT.CP(font_scaling));
405+ SetMinimumWidth(MIN_BUTTON_WIDTH.CP(font_scaling));
406 }
407
408 void ActionButton::SetExtraHint(std::string const& extra_hint, std::string const& font_hint)
409
410=== modified file 'dash/previews/ErrorPreview.cpp'
411--- dash/previews/ErrorPreview.cpp 2014-08-06 14:09:30 +0000
412+++ dash/previews/ErrorPreview.cpp 2014-12-17 12:14:47 +0000
413@@ -37,6 +37,7 @@
414
415 #include "stdio.h"
416 #include "config.h"
417+#include <glib/gi18n-lib.h>
418
419 namespace unity
420 {
421
422=== modified file 'dash/previews/PaymentPreview.cpp'
423--- dash/previews/PaymentPreview.cpp 2014-07-24 14:14:47 +0000
424+++ dash/previews/PaymentPreview.cpp 2014-12-17 12:14:47 +0000
425@@ -20,8 +20,10 @@
426 * Manuel de la Pena <manuel.delapena@canonical.com>
427 *
428 */
429+#include "PaymentPreview.h"
430+
431+#include <Nux/VLayout.h>
432 #include <NuxCore/Logger.h>
433-#include "PaymentPreview.h"
434 #include "unity-shared/CoverArt.h"
435 #include "unity-shared/DashStyle.h"
436 #include "unity-shared/PreviewStyle.h"
437
438=== added directory 'data'
439=== added file 'data/CMakeLists.txt'
440--- data/CMakeLists.txt 1970-01-01 00:00:00 +0000
441+++ data/CMakeLists.txt 2014-12-17 12:14:47 +0000
442@@ -0,0 +1,1 @@
443+add_subdirectory(pam)
444\ No newline at end of file
445
446=== added directory 'data/pam'
447=== added file 'data/pam/CMakeLists.txt'
448--- data/pam/CMakeLists.txt 1970-01-01 00:00:00 +0000
449+++ data/pam/CMakeLists.txt 2014-12-17 12:14:47 +0000
450@@ -0,0 +1,1 @@
451+install(FILES unity DESTINATION ${CMAKE_SYSCONFDIR}/pam.d)
452\ No newline at end of file
453
454=== added file 'data/pam/unity'
455--- data/pam/unity 1970-01-01 00:00:00 +0000
456+++ data/pam/unity 2014-12-17 12:14:47 +0000
457@@ -0,0 +1,2 @@
458+@include common-auth
459+auth optional pam_gnome_keyring.so
460
461=== modified file 'debian/changelog'
462--- debian/changelog 2014-08-26 13:49:00 +0000
463+++ debian/changelog 2014-12-17 12:14:47 +0000
464@@ -1,3 +1,59 @@
465+unity (7.2.4-0ubuntu1) UNRELEASED; urgency=medium
466+
467+ [ Andrea Azzarone ]
468+ * Share lockscreen password between screens (lp: #1308540)
469+ * Allow a distinct pam config file for greeter and for lock-screen.
470+ (lp: #1305440)
471+ * Add an arrow activator in the lockscreen. (lp: #1332509)
472+ * Make sure GetScreenGeometry returns the correct value (lp: #1374785).
473+ * unmapped all windows prior to shutdown (lp: #1370017) (lp: #1375271)
474+
475+ [ Brandon Schaefer ]
476+ * fix tooltip for the "Show Desktop / Restore Windows" icon in the Alt-Tab
477+ switcher (lp: #1237132)
478+ * Use CONFIG instead of CACHE to store the first_run.stamp (lp: #1328677)
479+
480+ [ Eleni Maria Stea ]
481+ * LayoutSystem: make sure the exposed open windows are displayed in the
482+ preserved order (lp: #1349281).
483+
484+ [ handsome_feng ]
485+ * added support for getting the distro name from /etc/os-release
486+ (lp: #1329584)
487+
488+ [ Iain Lane ]
489+ * When grabbing keys, try prefixing "XF86" if the key isn't found. GNOME
490+ gives us unprefixed keys sometimes (lp: #1302885).
491+
492+ [ Marco Trevisan (Treviño) ]
493+ * make the Launcher icon count badge width depend on the text value width
494+ and scaling (lp: #1353070) (lp: #1354498) (lp: #796527) (lp: #1066971)
495+ (lp: #1361713)
496+ * DecoratedWindow: make edges independent from borders and properly update
497+ them on actions change (lp: #1276177), (lp: #1299741), (lp: #1301776),
498+ (lp: #1324104), (lp: #1364225), (lp: #1373695)
499+ * Lockscreen: scale the UI elements based on current monitor scaling
500+ (lp: #1292218)
501+ * UnityScreen: when filtering out windows in spread, make sure we unscale
502+ them (lp: #1316265).
503+ * PanelMenuView: ensure that proper window tiles and buttons are shown at
504+ the right place (lp: #1384910) (lp: #1384958) (lp: #1385285)
505+ * SearchBar, ActionButtons, IconRenderer: include the font scaling when
506+ scaling textual items (lp: #1332947) (lp: #1361751) (lp: #1362162)
507+ (lp: #1362346).
508+ * ApplicationLauncherIcon: make sure we close the dash if DnD is accepted
509+ and the application window is about to be focused (lp: #1350331).
510+ * SwitcherView: set progress on icon render args (lp: #1361679).
511+ * LockScreenController: wait for the primary shield to get the grab
512+ before setting the session locked (lp: #1368427) (lp: #1371764).
513+ * added decorations to windows in non-focused workspaces (lp: #1383468)
514+
515+ [ Stephen M. Webb ]
516+ * updated the unity(1) manpage to match the actual command (lp: #1059275)
517+ * bumped package version to match upstream
518+
519+ -- Stephen M. Webb <stephen.webb@canonical.coma> Mon, 08 Dec 2014 14:29:17 -0500
520+
521 unity (7.2.3+14.04.20140826-0ubuntu1) trusty; urgency=medium
522
523 [ Andrea Azzarone ]
524@@ -2189,6 +2245,9 @@
525 unity (7.0.0daily13.05.08ubuntu.unity.next-0ubuntu1) raring; urgency=low
526
527 * Automatic snapshot from revision 3317 (ubuntu-unity/next)
528+
529+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Fri, 31 May 2013 04:06:11 +0000
530+
531 unity (7.0.0daily13.05.01.1ubuntu.unity.next-0ubuntu1) raring; urgency=low
532
533 [ Sebastien Bacher ]
534
535=== modified file 'debian/rules'
536--- debian/rules 2014-05-12 18:04:20 +0000
537+++ debian/rules 2014-12-17 12:14:47 +0000
538@@ -23,7 +23,7 @@
539
540 SCOPES_RECOMMENDS := $(shell perl debian/scopes-recommends-generator /usr/share/unity/client-scopes.json)
541
542-cmake_base_options := -DUSE_GSETTINGS=TRUE -DCOMPIZ_BUILD_WITH_RPATH=FALSE -DCOMPIZ_PACKAGING_ENABLED=TRUE -DCOMPIZ_PLUGIN_INSTALL_TYPE=package
543+cmake_base_options := -DUSE_GSETTINGS=TRUE -DCOMPIZ_BUILD_WITH_RPATH=FALSE -DCOMPIZ_PACKAGING_ENABLED=TRUE -DCMAKE_SYSCONFDIR=/etc -DCOMPIZ_PLUGIN_INSTALL_TYPE=package
544 ifeq ($(DEB_HOST_ARCH),$(findstring $(DEB_HOST_ARCH), $(gles2_architectures)))
545 cmake_gl_options := -DBUILD_GLES=TRUE -DDISABLE_MAINTAINER_CFLAGS=ON
546 endif
547
548=== modified file 'debian/unity.install'
549--- debian/unity.install 2011-09-15 16:42:23 +0000
550+++ debian/unity.install 2014-12-17 12:14:47 +0000
551@@ -1,3 +1,4 @@
552+etc/pam.d
553 usr/bin
554 usr/lib/compiz
555 usr/share/man/*/unity.1
556
557=== modified file 'debian/unity.migrations'
558--- debian/unity.migrations 2014-03-21 02:58:13 +0000
559+++ debian/unity.migrations 2014-12-17 12:14:47 +0000
560@@ -1,2 +1,3 @@
561 tools/migration-scripts/01_unity_change_dconf_path
562 tools/migration-scripts/02_unity_setup_text_scale_factor
563+tools/migration-scripts/03_unity_first_run_stamp_move
564
565=== modified file 'decorations/DecoratedWindow.cpp'
566--- decorations/DecoratedWindow.cpp 2014-04-02 12:26:14 +0000
567+++ decorations/DecoratedWindow.cpp 2014-12-17 12:14:47 +0000
568@@ -1,6 +1,6 @@
569 // -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
570 /*
571- * Copyright (C) 2013 Canonical Ltd
572+ * Copyright (C) 2013-2014 Canonical Ltd
573 *
574 * This program is free software: you can redistribute it and/or modify
575 * it under the terms of the GNU General Public License version 3 as
576@@ -46,8 +46,12 @@
577 , cwin_(CompositeWindow::get(win_))
578 , glwin_(GLWindow::get(win_))
579 , frame_(0)
580+ , monitor_(0)
581 , dirty_geo_(true)
582- , monitor_(0)
583+ , dirty_frame_(false)
584+ , deco_elements_(cu::DecorationElement::NONE)
585+ , last_mwm_decor_(win_->mwmDecor())
586+ , last_actions_(win_->actions())
587 , cv_(Settings::Instance().em())
588 {
589 active.changed.connect([this] (bool active) {
590@@ -107,14 +111,32 @@
591
592 void Window::Impl::Update()
593 {
594- ShouldBeDecorated() ? Decorate() : Undecorate();
595+ UpdateElements();
596+
597+ if (deco_elements_ & (cu::DecorationElement::EDGE | cu::DecorationElement::BORDER))
598+ Decorate();
599+ else
600+ Undecorate();
601+
602+ last_mwm_decor_ = win_->mwmDecor();
603+ last_actions_ = win_->actions();
604 }
605
606 void Window::Impl::Decorate()
607 {
608 SetupExtents();
609 UpdateFrame();
610- SetupWindowControls();
611+ SetupWindowEdges();
612+
613+ if (deco_elements_ & cu::DecorationElement::BORDER)
614+ {
615+ SetupWindowControls();
616+ }
617+ else
618+ {
619+ CleanupWindowControls();
620+ bg_textures_.clear();
621+ }
622 }
623
624 void Window::Impl::Undecorate()
625@@ -122,6 +144,7 @@
626 UnsetExtents();
627 UnsetFrame();
628 CleanupWindowControls();
629+ CleanupWindowEdges();
630 bg_textures_.clear();
631 }
632
633@@ -141,22 +164,39 @@
634 if (win_->hasUnmapReference())
635 return;
636
637- auto const& sb = Style::Get()->Border();
638- CompWindowExtents border(cv_->CP(sb.left),
639- cv_->CP(sb.right),
640- cv_->CP(sb.top),
641- cv_->CP(sb.bottom));
642-
643- auto const& ib = Style::Get()->InputBorder();
644- CompWindowExtents input(cv_->CP(sb.left + ib.left),
645- cv_->CP(sb.right + ib.right),
646- cv_->CP(sb.top + ib.top),
647- cv_->CP(sb.bottom + ib.bottom));
648+ CompWindowExtents border;
649+
650+ if (deco_elements_ & cu::DecorationElement::BORDER)
651+ {
652+ auto const& sb = Style::Get()->Border();
653+ border.left = cv_->CP(sb.left);
654+ border.right = cv_->CP(sb.right);
655+ border.top = cv_->CP(sb.top);
656+ border.bottom = cv_->CP(sb.bottom);
657+ }
658+
659+ CompWindowExtents input(border);
660+
661+ if (deco_elements_ & cu::DecorationElement::EDGE)
662+ {
663+ auto const& ib = Style::Get()->InputBorder();
664+ input.left += cv_->CP(ib.left);
665+ input.right += cv_->CP(ib.right);
666+ input.top += cv_->CP(ib.top);
667+ input.bottom += cv_->CP(ib.bottom);
668+ }
669
670 if (win_->border() != border || win_->input() != input)
671 win_->setWindowFrameExtents(&border, &input);
672 }
673
674+void Window::Impl::SendFrameExtents()
675+{
676+ UpdateElements(cu::WindowFilter::UNMAPPED);
677+ SetupExtents();
678+ win_->setWindowFrameExtents(&win_->border(), &win_->input());
679+}
680+
681 void Window::Impl::UnsetFrame()
682 {
683 if (!frame_)
684@@ -185,6 +225,15 @@
685 UpdateFrameGeo(frame_geo);
686 }
687
688+void Window::Impl::UpdateFrameActions()
689+{
690+ if (!dirty_frame_ && (win_->mwmDecor() != last_mwm_decor_ || win_->actions() != last_actions_))
691+ {
692+ dirty_frame_ = true;
693+ Damage();
694+ }
695+}
696+
697 void Window::Impl::CreateFrame(nux::Geometry const& frame_geo)
698 {
699 /* Since we're reparenting windows here, we need to grab the server
700@@ -282,6 +331,42 @@
701 win_->updateFrameRegion();
702 }
703
704+void Window::Impl::SetupWindowEdges()
705+{
706+ if (input_mixer_)
707+ return;
708+
709+ dpi_changed_ = Settings::Instance().dpi_changed.connect([this] {
710+ Update();
711+ edge_borders_->scale = cv_->DPIScale();
712+ if (top_layout_) top_layout_->scale = cv_->DPIScale();
713+ });
714+
715+ input_mixer_ = std::make_shared<InputMixer>();
716+ edge_borders_ = std::make_shared<EdgeBorders>(win_);
717+ edge_borders_->scale = cv_->DPIScale();
718+ input_mixer_->PushToFront(edge_borders_);
719+
720+ UpdateWindowEdgesGeo();
721+}
722+
723+void Window::Impl::UpdateWindowEdgesGeo()
724+{
725+ if (!edge_borders_)
726+ return;
727+
728+ auto const& input = win_->inputRect();
729+ edge_borders_->SetCoords(input.x(), input.y());
730+ edge_borders_->SetSize(input.width(), input.height());
731+}
732+
733+void Window::Impl::CleanupWindowEdges()
734+{
735+ input_mixer_.reset();
736+ edge_borders_.reset();
737+ dpi_changed_->disconnect();
738+}
739+
740 void Window::Impl::SetupWindowControls()
741 {
742 if (top_layout_)
743@@ -293,26 +378,7 @@
744 Decorate();
745 });
746
747- dpi_changed_ = Settings::Instance().dpi_changed.connect([this] {
748- Update();
749- top_layout_->scale = cv_->DPIScale();
750- });
751-
752- input_mixer_ = std::make_shared<InputMixer>();
753-
754- if (win_->actions() & CompWindowActionResizeMask)
755- {
756- auto edges = std::make_shared<EdgeBorders>(win_);
757- grab_edge_ = edges->GetEdge(Edge::Type::GRAB);
758- edge_borders_ = edges;
759- }
760- else /*if (win_->actions() & CompWindowActionMoveMask)*/
761- {
762- edge_borders_ = std::make_shared<GrabEdge>(win_);
763- grab_edge_ = edge_borders_;
764- }
765-
766- input_mixer_->PushToFront(edge_borders_);
767+ grab_edge_ = std::static_pointer_cast<EdgeBorders>(edge_borders_)->GetEdge(Edge::Type::GRAB);
768
769 auto padding = style->Padding(Side::TOP);
770 top_layout_ = std::make_shared<Layout>();
771@@ -347,6 +413,7 @@
772 top_layout_->Append(title_layout);
773
774 input_mixer_->PushToFront(top_layout_);
775+ dirty_frame_ = false;
776
777 SetupAppMenu();
778 RedrawDecorations();
779@@ -357,12 +424,12 @@
780 if (title_)
781 last_title_ = title_->text();
782
783+ if (input_mixer_)
784+ input_mixer_->Remove(top_layout_);
785+
786 UnsetAppMenu();
787 theme_changed_->disconnect();
788- dpi_changed_->disconnect();
789 top_layout_.reset();
790- input_mixer_.reset();
791- edge_borders_.reset();
792 }
793
794 bool Window::Impl::IsMaximized() const
795@@ -370,26 +437,25 @@
796 return (win_->state() & MAXIMIZE_STATE) == MAXIMIZE_STATE;
797 }
798
799+void Window::Impl::UpdateElements(cu::WindowFilter::Value wf)
800+{
801+ if (!parent_->scaled() && IsMaximized())
802+ {
803+ deco_elements_ = cu::DecorationElement::NONE;
804+ return;
805+ }
806+
807+ deco_elements_ = cu::WindowDecorationElements(win_, wf);
808+}
809+
810 bool Window::Impl::ShadowDecorated() const
811 {
812- if (!parent_->scaled() && IsMaximized())
813- return false;
814-
815- if (!cu::IsWindowShadowDecorable(win_))
816- return false;
817-
818- return true;
819+ return deco_elements_ & cu::DecorationElement::SHADOW;
820 }
821
822 bool Window::Impl::FullyDecorated() const
823 {
824- if (!parent_->scaled() && IsMaximized())
825- return false;
826-
827- if (!cu::IsWindowFullyDecorable(win_))
828- return false;
829-
830- return true;
831+ return deco_elements_ & cu::DecorationElement::BORDER;
832 }
833
834 bool Window::Impl::ShouldBeDecorated() const
835@@ -431,6 +497,7 @@
836 }
837
838 deco_tex.SetCoords(geo.x, geo.y);
839+ deco_tex.quad.region = deco_tex.quad.box;
840 }
841
842 void Window::Impl::UpdateDecorationTextures()
843@@ -442,7 +509,6 @@
844 }
845
846 auto const& geo = win_->borderRect();
847- auto const& input = win_->inputRect();
848 auto const& border = win_->border();
849
850 bg_textures_.resize(4);
851@@ -454,19 +520,18 @@
852 top_layout_->SetCoords(geo.x(), geo.y());
853 top_layout_->SetSize(geo.width(), border.top);
854
855- if (edge_borders_)
856- {
857- edge_borders_->SetCoords(input.x(), input.y());
858- edge_borders_->SetSize(input.width(), input.height());
859- }
860-
861 SyncMenusGeometries();
862 }
863
864 void Window::Impl::ComputeShadowQuads()
865 {
866- if (last_shadow_rect_.isEmpty() && !ShadowDecorated())
867+ if (!(deco_elements_ & cu::DecorationElement::SHADOW))
868+ {
869+ if (!last_shadow_rect_.isEmpty())
870+ last_shadow_rect_.setGeometry(0, 0, 0, 0);
871+
872 return;
873+ }
874
875 const auto* texture = ShadowTexture();
876
877@@ -554,6 +619,12 @@
878
879 if (shadows_rect != last_shadow_rect_)
880 {
881+ auto const& win_region = win_->region();
882+ quads[Quads::Pos::TOP_LEFT].region = CompRegion(quads[Quads::Pos::TOP_LEFT].box) - win_region;
883+ quads[Quads::Pos::TOP_RIGHT].region = CompRegion(quads[Quads::Pos::TOP_RIGHT].box) - win_region;
884+ quads[Quads::Pos::BOTTOM_LEFT].region = CompRegion(quads[Quads::Pos::BOTTOM_LEFT].box) - win_region;
885+ quads[Quads::Pos::BOTTOM_RIGHT].region = CompRegion(quads[Quads::Pos::BOTTOM_RIGHT].box) - win_region;
886+
887 last_shadow_rect_ = shadows_rect;
888 win_->updateWindowOutputExtents();
889 }
890@@ -563,16 +634,31 @@
891 GLWindowPaintAttrib const& attrib,
892 CompRegion const& region, unsigned mask)
893 {
894+ if (!(mask & PAINT_SCREEN_TRANSFORMED_MASK) && win_->defaultViewport() != screen->vp())
895+ {
896+ return;
897+ }
898+
899 if (dirty_geo_)
900 parent_->UpdateDecorationPosition();
901+
902+ if (dirty_frame_)
903+ {
904+ dirty_frame_ = false;
905+ CleanupWindowControls();
906+ CleanupWindowEdges();
907+ Update();
908+ }
909 }
910
911 void Window::Impl::Draw(GLMatrix const& transformation,
912 GLWindowPaintAttrib const& attrib,
913 CompRegion const& region, unsigned mask)
914 {
915- if (last_shadow_rect_.isEmpty())
916+ if (last_shadow_rect_.isEmpty() || (!(mask & PAINT_SCREEN_TRANSFORMED_MASK) && win_->defaultViewport() != screen->vp()))
917+ {
918 return;
919+ }
920
921 auto const& clip_region = (mask & PAINT_WINDOW_TRANSFORMED_MASK) ? infiniteRegion : region;
922 mask |= PAINT_WINDOW_BLEND_MASK;
923@@ -582,7 +668,7 @@
924 for (unsigned i = 0; i < shadow_quads_.size(); ++i)
925 {
926 auto& quad = shadow_quads_[Quads::Pos(i)];
927- glwin_->glAddGeometry({quad.matrix}, CompRegion(quad.box) - win_->region(), clip_region);
928+ glwin_->glAddGeometry(quad.matrices, quad.region, clip_region);
929 }
930
931 if (glwin_->vertexBuffer()->end())
932@@ -594,7 +680,7 @@
933 continue;
934
935 glwin_->vertexBuffer()->begin();
936- glwin_->glAddGeometry({dtex.quad.matrix}, dtex.quad.box, clip_region);
937+ glwin_->glAddGeometry(dtex.quad.matrices, dtex.quad.region, clip_region);
938
939 if (glwin_->vertexBuffer()->end())
940 glwin_->glDrawTexture(dtex, transformation, attrib, mask);
941@@ -707,6 +793,9 @@
942
943 if (top_layout_)
944 top_layout_->scale = cv_->DPIScale();
945+
946+ if (edge_borders_)
947+ edge_borders_->scale = cv_->DPIScale();
948 }
949 }
950
951@@ -789,6 +878,7 @@
952 {
953 impl_->UpdateMonitor();
954 impl_->ComputeShadowQuads();
955+ impl_->UpdateWindowEdgesGeo();
956 impl_->UpdateDecorationTextures();
957 impl_->UpdateForceQuitDialogPosition();
958 impl_->dirty_geo_ = false;
959@@ -808,7 +898,8 @@
960 {
961 data.add(impl_->win_->borderRect())
962 .add("input_geo", impl_->win_->inputRect())
963- .add("content_geo", impl_->win_->region().boundingRect())
964+ .add("content_geo", impl_->win_->geometry())
965+ .add("region", impl_->win_->region().boundingRect())
966 .add("title", title())
967 .add("active", impl_->active())
968 .add("scaled", scaled())
969
970=== modified file 'decorations/DecorationsEdgeBorders.cpp'
971--- decorations/DecorationsEdgeBorders.cpp 2014-02-18 23:01:33 +0000
972+++ decorations/DecorationsEdgeBorders.cpp 2014-12-17 12:14:47 +0000
973@@ -26,21 +26,31 @@
974 {
975 namespace
976 {
977-const int MIN_CORNER_EDGE = 10;
978+const RawPixel MIN_CORNER_EDGE = 10_em;
979 }
980
981 EdgeBorders::EdgeBorders(CompWindow* win)
982 {
983- items_.resize(size_t(Edge::Type::Size));
984-
985- for (unsigned i = 0; i < unsigned(Edge::Type::Size); ++i)
986- {
987- auto type = Edge::Type(i);
988-
989- if (type == Edge::Type::GRAB)
990- items_[i] = std::make_shared<GrabEdge>(win);
991- else
992- items_[i] = std::make_shared<Edge>(win, type);
993+ scale.changed.connect(sigc::hide(sigc::mem_fun(this, &EdgeBorders::Relayout)));
994+
995+ if (win->actions() & CompWindowActionResizeMask)
996+ {
997+ items_.resize(size_t(Edge::Type::Size));
998+
999+ for (unsigned i = 0; i < unsigned(Edge::Type::Size); ++i)
1000+ {
1001+ auto type = Edge::Type(i);
1002+
1003+ if (type == Edge::Type::GRAB)
1004+ items_[i] = std::make_shared<GrabEdge>(win);
1005+ else
1006+ items_[i] = std::make_shared<Edge>(win, type);
1007+ }
1008+ }
1009+ else /*if (win->actions() & CompWindowActionMoveMask)*/
1010+ {
1011+ items_.resize(size_t(Edge::Type::GRAB) + 1);
1012+ items_[unsigned(Edge::Type::GRAB)] = std::make_shared<GrabEdge>(win);
1013 }
1014
1015 Relayout();
1016@@ -54,10 +64,17 @@
1017 auto const& ib = win->input();
1018
1019 using namespace compiz::window::extents;
1020- Extents edges(std::max(ib.left, MIN_CORNER_EDGE),
1021- std::max(ib.right, MIN_CORNER_EDGE),
1022- std::max(ib.top, MIN_CORNER_EDGE),
1023- std::max(ib.bottom, MIN_CORNER_EDGE));
1024+ int min_corner_edge = MIN_CORNER_EDGE.CP(scale);
1025+ Extents edges(std::max(ib.left, min_corner_edge),
1026+ std::max(ib.right, min_corner_edge),
1027+ std::max(ib.top, min_corner_edge),
1028+ std::max(ib.bottom, min_corner_edge));
1029+
1030+ grab_edge->SetCoords(rect_.x() + ib.left, rect_.y() + ib.top - b.top);
1031+ grab_edge->SetSize(rect_.width() - ib.left - ib.right, b.top);
1032+
1033+ if (items_.size() != size_t(Edge::Type::Size))
1034+ return;
1035
1036 auto item = items_[unsigned(Edge::Type::TOP)];
1037 item->SetCoords(rect_.x() + edges.left, rect_.y());
1038@@ -90,10 +107,6 @@
1039 item = items_[unsigned(Edge::Type::BOTTOM_RIGHT)];
1040 item->SetCoords(rect_.x2() - edges.right, rect_.y2() - edges.bottom);
1041 item->SetSize(edges.right, edges.bottom);
1042-
1043- item = items_[unsigned(Edge::Type::GRAB)];
1044- item->SetCoords(rect_.x() + ib.left, rect_.y() + ib.top - b.top);
1045- item->SetSize(rect_.width() - ib.left - ib.right, b.top);
1046 }
1047
1048 Item::Ptr const& EdgeBorders::GetEdge(Edge::Type type) const
1049
1050=== modified file 'decorations/DecorationsForceQuitDialog.cpp'
1051--- decorations/DecorationsForceQuitDialog.cpp 2014-04-02 13:14:43 +0000
1052+++ decorations/DecorationsForceQuitDialog.cpp 2014-12-17 12:14:47 +0000
1053@@ -141,7 +141,7 @@
1054
1055 auto const& deco_style = decoration::Style::Get();
1056 auto const& offset = deco_style->ShadowOffset();
1057- int max_offset = std::max(std::abs(offset.x), std::abs(offset.y));
1058+ int max_offset = std::max(std::abs(offset.x * 4), std::abs(offset.y * 4));
1059 gtk_container_set_border_width(GTK_CONTAINER(self), deco_style->ActiveShadowRadius()+max_offset);
1060
1061 auto* screen = gtk_window_get_screen(self);
1062@@ -259,18 +259,32 @@
1063 auto const& radius = deco_style->CornerRadius();
1064 auto const& offset = deco_style->ShadowOffset();
1065 auto const& color = deco_style->ActiveShadowColor();
1066+ auto const& backcolor = deco_style->InactiveShadowColor();
1067 int decoration_radius = std::max({radius.top, radius.left, radius.right, radius.bottom});
1068
1069- gtk_css_provider_load_from_data(style, (R"(SheetStyleDialog {
1070+ gtk_css_provider_load_from_data(style, (R"(
1071+ SheetStyleDialog {
1072 background-color: #f7f6f5;
1073 color: #4a4a4a;
1074 border-radius: )"+std::to_string(decoration_radius)+R"(px;
1075- box-shadow: )"+std::to_string(offset.x)+"px "+std::to_string(offset.y)+"px "+
1076+ box-shadow: )"+std::to_string(2 * offset.x)+"px "+std::to_string(2 * offset.y)+"px "+
1077 std::to_string(deco_style->ActiveShadowRadius())+"px "+
1078 "rgba("+std::to_string(int(color.red * 255.0))+", "+
1079 std::to_string(int(color.green * 255.0))+", "+
1080 std::to_string(int(color.blue * 255.0))+", "+
1081 std::to_string(int(color.alpha))+'.'+std::to_string(int(color.alpha*10000.0))+')'+R"(;
1082+ }
1083+
1084+ SheetStyleDialog:backdrop {
1085+ background-color: shade(#f7f6f5, 1.2);
1086+ color: shade(#4a4a4a, 1.5);
1087+ border-radius: )"+std::to_string(decoration_radius)+R"(px;
1088+ box-shadow: )"+std::to_string(2 * offset.x)+"px "+std::to_string(2 * offset.y)+"px "+
1089+ std::to_string(deco_style->InactiveShadowRadius())+"px "+
1090+ "rgba("+std::to_string(int(backcolor.red * 255.0))+", "+
1091+ std::to_string(int(backcolor.green * 255.0))+", "+
1092+ std::to_string(int(backcolor.blue * 255.0))+", "+
1093+ std::to_string(int(backcolor.alpha))+'.'+std::to_string(int(backcolor.alpha*10000.0))+')'+R"(;
1094 })").c_str(), -1, nullptr);
1095
1096 auto* style_ctx = gtk_widget_get_style_context(self);
1097
1098=== modified file 'decorations/DecorationsManager.cpp'
1099--- decorations/DecorationsManager.cpp 2014-04-02 09:04:37 +0000
1100+++ decorations/DecorationsManager.cpp 2014-12-17 12:14:47 +0000
1101@@ -44,8 +44,7 @@
1102 }
1103
1104 Manager::Impl::Impl(decoration::Manager* parent, menu::Manager::Ptr const& menu)
1105- : active_window_(0)
1106- , enable_add_supported_atoms_(true)
1107+ : enable_add_supported_atoms_(true)
1108 , data_pool_(DataPool::Get())
1109 , menu_manager_(menu)
1110 {
1111@@ -55,7 +54,6 @@
1112 Display* dpy = screen->dpy();
1113 atom::_NET_REQUEST_FRAME_EXTENTS = XInternAtom(dpy, "_NET_REQUEST_FRAME_EXTENTS", False);
1114 atom::_NET_WM_VISIBLE_NAME = XInternAtom(dpy, "_NET_WM_VISIBLE_NAME", False);
1115- screen->updateSupportedWmHints();
1116
1117 auto rebuild_cb = sigc::mem_fun(this, &Impl::OnShadowOptionsChanged);
1118 manager_->active_shadow_color.changed.connect(sigc::hide(sigc::bind(rebuild_cb, true)));
1119@@ -208,15 +206,13 @@
1120
1121 bool Manager::Impl::HandleEventBefore(XEvent* event)
1122 {
1123- active_window_ = screen->activeWindow();
1124-
1125 switch (event->type)
1126 {
1127 case ClientMessage:
1128 if (event->xclient.message_type == atom::_NET_REQUEST_FRAME_EXTENTS)
1129 {
1130 if (Window::Ptr const& win = GetWindowByXid(event->xclient.window))
1131- win->impl_->Decorate();
1132+ win->impl_->SendFrameExtents();
1133 }
1134 else if (event->xclient.message_type == Atoms::toolkitAction)
1135 {
1136@@ -254,31 +250,26 @@
1137
1138 bool Manager::Impl::HandleEventAfter(XEvent* event)
1139 {
1140- if (screen->activeWindow() != active_window_)
1141- {
1142- // Do this when _NET_ACTIVE_WINDOW changes on root!
1143- if (active_deco_win_)
1144- active_deco_win_->impl_->active = false;
1145-
1146- active_window_ = screen->activeWindow();
1147- auto const& new_active = GetWindowByXid(active_window_);
1148- active_deco_win_ = new_active;
1149-
1150- if (new_active)
1151- new_active->impl_->active = true;
1152- }
1153-
1154 switch (event->type)
1155 {
1156 case PropertyNotify:
1157 {
1158- if (event->xproperty.atom == Atoms::mwmHints)
1159+ if (event->xproperty.atom == Atoms::winActive)
1160+ {
1161+ if (active_deco_win_)
1162+ active_deco_win_->impl_->active = false;
1163+
1164+ auto const& new_active = GetWindowByXid(screen->activeWindow());
1165+ active_deco_win_ = new_active;
1166+
1167+ if (new_active)
1168+ new_active->impl_->active = true;
1169+ }
1170+ else if (event->xproperty.atom == Atoms::mwmHints ||
1171+ event->xproperty.atom == Atoms::wmAllowedActions)
1172 {
1173 if (Window::Ptr const& win = GetWindowByXid(event->xproperty.window))
1174- {
1175- win->impl_->CleanupWindowControls();
1176- win->Update();
1177- }
1178+ win->impl_->UpdateFrameActions();
1179 }
1180 else if (event->xproperty.atom == XA_WM_NAME ||
1181 event->xproperty.atom == Atoms::wmName ||
1182@@ -445,7 +436,7 @@
1183 .add("active_shadow_radius", active_shadow_radius())
1184 .add("inactive_shadow_color", inactive_shadow_color())
1185 .add("inactive_shadow_radius", inactive_shadow_radius())
1186- .add("active_window", impl_->active_window_);
1187+ .add("active_window", screen->activeWindow());
1188 }
1189
1190 debug::Introspectable::IntrospectableList Manager::GetIntrospectableChildren()
1191
1192=== modified file 'decorations/DecorationsPriv.h'
1193--- decorations/DecorationsPriv.h 2014-04-02 09:05:59 +0000
1194+++ decorations/DecorationsPriv.h 2014-12-17 12:14:47 +0000
1195@@ -1,6 +1,6 @@
1196 // -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
1197 /*
1198- * Copyright (C) 2013 Canonical Ltd
1199+ * Copyright (C) 2013-2014 Canonical Ltd
1200 *
1201 * This program is free software: you can redistribute it and/or modify
1202 * it under the terms of the GNU General Public License version 3 as
1203@@ -88,15 +88,20 @@
1204 void SetupAppMenu();
1205 bool ActivateMenu(std::string const&);
1206 void ShowForceQuitDialog(bool, Time);
1207+ void SendFrameExtents();
1208
1209 private:
1210 void UnsetExtents();
1211 void SetupExtents();
1212+ void UpdateElements(cu::WindowFilter::Value wf = cu::WindowFilter::NONE);
1213 void UpdateMonitor();
1214 void UpdateFrame();
1215 void CreateFrame(nux::Geometry const&);
1216 void UpdateFrameGeo(nux::Geometry const&);
1217+ void UpdateFrameActions();
1218 void UnsetFrame();
1219+ void SetupWindowEdges();
1220+ void CleanupWindowEdges();
1221 void SetupWindowControls();
1222 void CleanupWindowControls();
1223 void UnsetAppMenu();
1224@@ -109,6 +114,7 @@
1225
1226 void ComputeShadowQuads();
1227 void UpdateDecorationTextures();
1228+ void UpdateWindowEdgesGeo();
1229 void UpdateForceQuitDialogPosition();
1230 void RenderDecorationTexture(Side, nux::Geometry const&);
1231 void Paint(GLMatrix const&, GLWindowPaintAttrib const&, CompRegion const&, unsigned mask);
1232@@ -122,8 +128,12 @@
1233 ::CompositeWindow* cwin_;
1234 ::GLWindow* glwin_;
1235 ::Window frame_;
1236+ int monitor_;
1237 bool dirty_geo_;
1238- int monitor_;
1239+ bool dirty_frame_;
1240+ unsigned deco_elements_;
1241+ unsigned last_mwm_decor_;
1242+ unsigned last_actions_;
1243
1244 CompRect last_shadow_rect_;
1245 Quads shadow_quads_;
1246@@ -176,7 +186,6 @@
1247 friend class Manager;
1248 friend struct Window::Impl;
1249
1250- ::Window active_window_;
1251 bool enable_add_supported_atoms_;
1252
1253 DataPool::Ptr data_pool_;
1254
1255=== modified file 'decorations/DecorationsTitle.cpp'
1256--- decorations/DecorationsTitle.cpp 2014-03-31 18:36:07 +0000
1257+++ decorations/DecorationsTitle.cpp 2014-12-17 12:14:47 +0000
1258@@ -80,6 +80,7 @@
1259
1260 Style::Get()->DrawTitle(text(), state, text_ctx, texture_size_.width / scale(), texture_size_.height / scale(), bg_geo * (1.0/scale));
1261 SetTexture(text_ctx);
1262+ texture_.UpdateMatrix();
1263 }
1264
1265 void Title::SetX(int x)
1266
1267=== modified file 'decorations/DecorationsWidgets.cpp'
1268--- decorations/DecorationsWidgets.cpp 2014-02-27 07:10:31 +0000
1269+++ decorations/DecorationsWidgets.cpp 2014-12-17 12:14:47 +0000
1270@@ -226,6 +226,12 @@
1271
1272 //
1273
1274+TexturedItem::TexturedItem()
1275+ : dirty_region_(false)
1276+{
1277+ geo_parameters_changed.connect([this] { dirty_region_ = true; });
1278+}
1279+
1280 void TexturedItem::SetTexture(cu::SimpleTexture::Ptr const& tex)
1281 {
1282 auto prev_geo = Geometry();
1283@@ -254,8 +260,14 @@
1284 if (!visible || Geometry().isEmpty() || !texture_)
1285 return;
1286
1287+ if (dirty_region_)
1288+ {
1289+ texture_.quad.region = texture_.quad.box;
1290+ dirty_region_ = false;
1291+ }
1292+
1293 ctx->vertexBuffer()->begin();
1294- ctx->glAddGeometry({texture_.quad.matrix}, texture_.quad.box, clip);
1295+ ctx->glAddGeometry(texture_.quad.matrices, texture_.quad.region, clip);
1296
1297 if (ctx->vertexBuffer()->end())
1298 ctx->glDrawTexture(texture_, transformation, attrib, mask);
1299
1300=== modified file 'decorations/DecorationsWidgets.h'
1301--- decorations/DecorationsWidgets.h 2014-02-27 07:10:31 +0000
1302+++ decorations/DecorationsWidgets.h 2014-12-17 12:14:47 +0000
1303@@ -121,6 +121,8 @@
1304 public:
1305 typedef std::shared_ptr<TexturedItem> Ptr;
1306
1307+ TexturedItem();
1308+
1309 void SetTexture(cu::SimpleTexture::Ptr const&);
1310 void Draw(GLWindow*, GLMatrix const&, GLWindowPaintAttrib const&, CompRegion const&, unsigned mask);
1311 void SetCoords(int x, int y);
1312@@ -133,6 +135,9 @@
1313
1314 CompRect& InternalGeo();
1315 cu::SimpleTextureQuad texture_;
1316+
1317+private:
1318+ bool dirty_region_;
1319 };
1320
1321
1322
1323=== modified file 'doc/unity.1'
1324--- doc/unity.1 2010-12-24 20:05:57 +0000
1325+++ doc/unity.1 2014-12-17 12:14:47 +0000
1326@@ -1,4 +1,4 @@
1327-.TH unity "1" "9 December 2010" "" "Linux User's Manual"
1328+.TH unity "1" "09 August 2014" "" "Linux User's Manual"
1329
1330 .SH NAME
1331 unity \- wrapper for starting the unity shell and handling fallback
1332@@ -12,17 +12,42 @@
1333 The \fBunity\fP program can be used to start the Unity shell as a compiz module, and to specify how to handle logging, debugging, as well as how to deal with the user's profile.
1334
1335 .SH OPTIONS
1336-.IP \fB\-\-advanced\-debug\fP
1337-Runs unity under debugging (using GDB or another debugger tool) to help tracking issues. Should only be used on request from a developper following a bug report.
1338-
1339-.IP \fB\-\-log\fP\ \fIfilename\fP
1340+.TP
1341+.BR \-\-advanced\-debug
1342+Runs unity under debugging (using \fBgdb\fR or another debugger tool) to help tracking issues. Should only be used on request from a developer following a bug report.
1343+
1344+.TP
1345+.BR "-\-compiz-path \fICOMPIZ_PATH\fR"
1346+Runs the compositor from a non-standard location.
1347+
1348+.TP
1349+.BR \-\-debug
1350+Runs Unity under
1351+.B gdb
1352+and prints a stack trace on crash.
1353+
1354+.TP
1355+.BR \-h ", " \-\-help
1356+Prints a usage message and exits.
1357+
1358+.TP
1359+.BR "\-\-log \fIfilename\fR"
1360 This parameter, followed by a path or filename, tells the Unity shell to store logs in the specified file.
1361
1362-.IP \fB\-\-reset\fP
1363-This option allows the user to reset profile parameters in compiz and restart the Unity shell with default settings.
1364-
1365-.IP \fB\-\-verbose\fP
1366-This option turns on displaying additional debugging output for the Unity shell. It can be used by the user to debug configuration issues. This option is often used along with the \fB\-\-log\fP option to save output to a file.
1367+.TP
1368+.BR \-\-replace
1369+Deprecated option for backwards compatibility. Has no effect.
1370+
1371+.TP
1372+.BR \-\-reset\-icons
1373+Resets the default Launcher icons.
1374+
1375+.TP
1376+.BR \-v ", " \-\-version
1377+Shows the program version number and exits.
1378+
1379+.TP
1380+.BR \-\-verbose
1381
1382 .SH "SEE ALSO"
1383 .B unity-panel-service
1384
1385=== modified file 'hud/HudIconTextureSource.cpp'
1386--- hud/HudIconTextureSource.cpp 2012-10-29 09:34:54 +0000
1387+++ hud/HudIconTextureSource.cpp 2014-12-17 12:14:47 +0000
1388@@ -109,11 +109,6 @@
1389 return nux::Color(0.0f, 0.0f, 0.0f, 0.0f);
1390 }
1391
1392-nux::BaseTexture* HudIconTextureSource::Emblem()
1393-{
1394- return nullptr;
1395-}
1396-
1397 }
1398 }
1399
1400
1401=== modified file 'hud/HudIconTextureSource.h'
1402--- hud/HudIconTextureSource.h 2013-11-06 11:21:43 +0000
1403+++ hud/HudIconTextureSource.h 2014-12-17 12:14:47 +0000
1404@@ -37,7 +37,6 @@
1405 virtual nux::Color BackgroundColor() const;
1406 virtual nux::BaseTexture* TextureForSize(int size);
1407 virtual nux::Color GlowColor();
1408- virtual nux::BaseTexture* Emblem();
1409 void ColorForIcon(GdkPixbuf* pixbuf);
1410
1411 private:
1412
1413=== modified file 'launcher/ApplicationLauncherIcon.cpp'
1414--- launcher/ApplicationLauncherIcon.cpp 2014-06-23 19:42:24 +0000
1415+++ launcher/ApplicationLauncherIcon.cpp 2014-12-17 12:14:47 +0000
1416@@ -33,6 +33,7 @@
1417 #include "MultiMonitor.h"
1418 #include "unity-shared/DesktopApplicationManager.h"
1419 #include "unity-shared/GnomeFileManager.h"
1420+#include "unity-shared/UBusWrapper.h"
1421 #include "unity-shared/UBusMessages.h"
1422 #include "unity-shared/UScreen.h"
1423
1424@@ -1168,6 +1169,7 @@
1425 if (!IsRunning())
1426 return false;
1427
1428+ UBusManager::SendMessage(UBUS_OVERLAY_CLOSE_REQUEST);
1429 Focus(ActionArg(ActionArg::Source::LAUNCHER, 1, timestamp));
1430
1431 if (GetWindows(WindowFilter::ON_CURRENT_DESKTOP).size() > 1)
1432
1433=== modified file 'launcher/DesktopLauncherIcon.cpp'
1434--- launcher/DesktopLauncherIcon.cpp 2013-10-13 23:09:05 +0000
1435+++ launcher/DesktopLauncherIcon.cpp 2014-12-17 12:14:47 +0000
1436@@ -33,7 +33,9 @@
1437 : SimpleLauncherIcon(IconType::DESKTOP)
1438 , show_in_switcher_(true)
1439 {
1440- tooltip_text = _("Show Desktop");
1441+ WindowManager::Default().show_desktop_changed.connect(sigc::mem_fun(this, &DesktopLauncherIcon::UpdateTooltipText));
1442+
1443+ UpdateTooltipText();
1444 icon_name = "desktop";
1445 SetQuirk(Quirk::VISIBLE, true);
1446 SetShortcut('d');
1447@@ -43,6 +45,16 @@
1448 {
1449 SimpleLauncherIcon::ActivateLauncherIcon(arg);
1450 WindowManager::Default().ShowDesktop();
1451+ UpdateTooltipText();
1452+}
1453+
1454+void DesktopLauncherIcon::UpdateTooltipText()
1455+{
1456+ auto const& wm = WindowManager::Default();
1457+ if (wm.InShowDesktop())
1458+ tooltip_text = _("Restore Windows");
1459+ else
1460+ tooltip_text = _("Show Desktop");
1461 }
1462
1463 std::string DesktopLauncherIcon::GetName() const
1464
1465=== modified file 'launcher/DesktopLauncherIcon.h'
1466--- launcher/DesktopLauncherIcon.h 2013-08-05 13:59:08 +0000
1467+++ launcher/DesktopLauncherIcon.h 2014-12-17 12:14:47 +0000
1468@@ -41,6 +41,8 @@
1469 std::string GetRemoteUri() const;
1470
1471 private:
1472+ void UpdateTooltipText();
1473+
1474 bool show_in_switcher_;
1475 };
1476
1477
1478=== modified file 'launcher/Launcher.cpp'
1479--- launcher/Launcher.cpp 2014-08-06 14:19:10 +0000
1480+++ launcher/Launcher.cpp 2014-12-17 12:14:47 +0000
1481@@ -1219,6 +1219,7 @@
1482 Resize(nux::Point(monitor_geo.x, monitor_geo.y + panel_height), monitor_geo.height - panel_height);
1483
1484 icon_renderer_->monitor = new_monitor;
1485+ icon_renderer_->scale = cv_->DPIScale();
1486 SetIconSize(options()->tile_size, options()->icon_size);
1487 }
1488
1489@@ -1516,10 +1517,7 @@
1490
1491 void Launcher::SetIconSize(int tile_size, int icon_size)
1492 {
1493- ui::IconRenderer::DestroyShortcutTextures();
1494-
1495 icon_size_ = tile_size;
1496- icon_renderer_->scale = cv_->DPIScale();
1497 icon_renderer_->SetTargetSize(icon_size_.CP(cv_), RawPixel(icon_size).CP(cv_), SPACE_BETWEEN_ICONS.CP(cv_));
1498 AbstractLauncherIcon::icon_size = icon_size_;
1499
1500
1501=== modified file 'launcher/LauncherIcon.cpp'
1502--- launcher/LauncherIcon.cpp 2014-05-28 12:14:44 +0000
1503+++ launcher/LauncherIcon.cpp 2014-12-17 12:14:47 +0000
1504@@ -59,6 +59,9 @@
1505 const std::string CENTER_STABILIZE_TIMEOUT = "center-stabilize-timeout";
1506 const std::string PRESENT_TIMEOUT = "present-timeout";
1507 const std::string QUIRK_DELAY_TIMEOUT = "quirk-delay-timeout";
1508+
1509+const int COUNT_FONT_SIZE = 11;
1510+const int COUNT_PADDING = 2;
1511 }
1512
1513 NUX_IMPLEMENT_OBJECT_TYPE(LauncherIcon);
1514@@ -69,7 +72,6 @@
1515 LauncherIcon::LauncherIcon(IconType type)
1516 : _icon_type(type)
1517 , _sticky(false)
1518- , _remote_urgent(false)
1519 , _present_urgency(0)
1520 , _progress(0.0f)
1521 , _sort_priority(DefaultPriority(type))
1522@@ -100,6 +102,11 @@
1523 mouse_up.connect(sigc::mem_fun(this, &LauncherIcon::RecvMouseUp));
1524 mouse_click.connect(sigc::mem_fun(this, &LauncherIcon::RecvMouseClick));
1525
1526+ auto const& count_rebuild_cb = sigc::mem_fun(this, &LauncherIcon::CleanCountTextures);
1527+ Settings::Instance().dpi_changed.connect(count_rebuild_cb);
1528+ Settings::Instance().font_scaling.changed.connect(sigc::hide(count_rebuild_cb));
1529+ icon_size.changed.connect(sigc::hide(count_rebuild_cb));
1530+
1531 for (unsigned i = 0; i < monitors::MAX; ++i)
1532 {
1533 for (unsigned j = 0; j < static_cast<unsigned>(Quirk::LAST); ++j)
1534@@ -966,14 +973,42 @@
1535 return result;
1536 }
1537
1538-nux::BaseTexture*
1539-LauncherIcon::Emblem()
1540+nux::BaseTexture* LauncherIcon::Emblem() const
1541 {
1542 return _emblem.GetPointer();
1543 }
1544
1545-void
1546-LauncherIcon::SetEmblem(LauncherIcon::BaseTexturePtr const& emblem)
1547+nux::BaseTexture* LauncherIcon::CountTexture(double scale)
1548+{
1549+ int count = Count();
1550+
1551+ if (!count)
1552+ return nullptr;
1553+
1554+ auto it = _counts.find(scale);
1555+
1556+ if (it != _counts.end())
1557+ return it->second.GetPointer();
1558+
1559+ auto const& texture = DrawCountTexture(count, scale);
1560+ _counts[scale] = texture;
1561+ return texture.GetPointer();
1562+}
1563+
1564+unsigned LauncherIcon::Count() const
1565+{
1566+ if (!_remote_entries.empty())
1567+ {
1568+ auto const& remote = _remote_entries.front();
1569+
1570+ if (remote->CountVisible())
1571+ return remote->Count();
1572+ }
1573+
1574+ return 0;
1575+}
1576+
1577+void LauncherIcon::SetEmblem(LauncherIcon::BaseTexturePtr const& emblem)
1578 {
1579 _emblem = emblem;
1580 EmitNeedsRedraw();
1581@@ -994,56 +1029,43 @@
1582 emblem->UnReference();
1583 }
1584
1585-void
1586-LauncherIcon::SetEmblemText(std::string const& text)
1587-{
1588- PangoLayout* layout = NULL;
1589-
1590- PangoContext* pangoCtx = NULL;
1591- PangoFontDescription* desc = NULL;
1592- GdkScreen* screen = gdk_screen_get_default(); // not ref'ed
1593- GtkSettings* settings = gtk_settings_get_default(); // not ref'ed
1594- gchar* fontName = NULL;
1595-
1596- int width = 32;
1597- int height = 8 * 2;
1598- int font_height = height - 5;
1599-
1600-
1601- nux::CairoGraphics cg(CAIRO_FORMAT_ARGB32, width, height);
1602+void LauncherIcon::CleanCountTextures()
1603+{
1604+ _counts.clear();
1605+ EmitNeedsRedraw();
1606+}
1607+
1608+BaseTexturePtr LauncherIcon::DrawCountTexture(unsigned count, double scale)
1609+{
1610+ glib::Object<PangoContext> pango_ctx(gdk_pango_context_get());
1611+ glib::Object<PangoLayout> layout(pango_layout_new(pango_ctx));
1612+
1613+ glib::String font_name;
1614+ g_object_get(gtk_settings_get_default(), "gtk-font-name", &font_name, nullptr);
1615+ std::shared_ptr<PangoFontDescription> desc(pango_font_description_from_string(font_name), pango_font_description_free);
1616+ int font_size = pango_units_from_double(Settings::Instance().font_scaling() * COUNT_FONT_SIZE);
1617+ pango_font_description_set_absolute_size(desc.get(), font_size);
1618+ pango_layout_set_font_description(layout, desc.get());
1619+
1620+ pango_layout_set_width(layout, pango_units_from_double(icon_size() * 0.75));
1621+ pango_layout_set_height(layout, -1);
1622+ pango_layout_set_wrap(layout, PANGO_WRAP_CHAR);
1623+ pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_MIDDLE);
1624+ pango_layout_set_text(layout, std::to_string(count).c_str(), -1);
1625+
1626+ PangoRectangle ink_rect;
1627+ pango_layout_get_pixel_extents(layout, &ink_rect, nullptr);
1628+
1629+ /* DRAW OUTLINE */
1630+ const float height = ink_rect.height + COUNT_PADDING * 4;
1631+ const float inset = height / 2.0;
1632+ const float radius = inset - 1.0f;
1633+ const float width = ink_rect.width + inset + COUNT_PADDING * 2;
1634+
1635+ nux::CairoGraphics cg(CAIRO_FORMAT_ARGB32, std::round(width * scale), std::round(height * scale));
1636+ cairo_surface_set_device_scale(cg.GetSurface(), scale, scale);
1637 cairo_t* cr = cg.GetInternalContext();
1638
1639- cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR);
1640- cairo_paint(cr);
1641-
1642- cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
1643-
1644-
1645- layout = pango_cairo_create_layout(cr);
1646-
1647- g_object_get(settings, "gtk-font-name", &fontName, NULL);
1648- desc = pango_font_description_from_string(fontName);
1649- pango_font_description_set_absolute_size(desc, pango_units_from_double(font_height));
1650-
1651- pango_layout_set_font_description(layout, desc);
1652- pango_font_description_free(desc);
1653-
1654- pango_layout_set_width(layout, pango_units_from_double(width - 4.0f));
1655- pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR);
1656- pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_NONE);
1657- pango_layout_set_markup_with_accel(layout, text.c_str(), -1, '_', NULL);
1658-
1659- pangoCtx = pango_layout_get_context(layout); // is not ref'ed
1660- pango_cairo_context_set_font_options(pangoCtx,
1661- gdk_screen_get_font_options(screen));
1662-
1663- PangoRectangle logical_rect, ink_rect;
1664- pango_layout_get_extents(layout, &logical_rect, &ink_rect);
1665-
1666- /* DRAW OUTLINE */
1667- float radius = height / 2.0f - 1.0f;
1668- float inset = radius + 1.0f;
1669-
1670 cairo_move_to(cr, inset, height - 1.0f);
1671 cairo_arc(cr, inset, inset, radius, 0.5 * M_PI, 1.5 * M_PI);
1672 cairo_arc(cr, width - inset, inset, radius, 1.5 * M_PI, 0.5 * M_PI);
1673@@ -1059,16 +1081,11 @@
1674 cairo_set_line_width(cr, 1.0f);
1675
1676 /* DRAW TEXT */
1677- cairo_move_to(cr,
1678- (int)((width - pango_units_to_double(logical_rect.width)) / 2.0f),
1679- (int)((height - pango_units_to_double(logical_rect.height)) / 2.0f - pango_units_to_double(logical_rect.y)));
1680+ cairo_move_to(cr, (width - ink_rect.width) / 2.0 - ink_rect.x,
1681+ (height - ink_rect.height) / 2.0 - ink_rect.y);
1682 pango_cairo_show_layout(cr, layout);
1683
1684- SetEmblem(texture_ptr_from_cairo_graphics(cg));
1685-
1686- // clean up
1687- g_object_unref(layout);
1688- g_free(fontName);
1689+ return texture_ptr_from_cairo_graphics(cg);
1690 }
1691
1692 void
1693@@ -1077,26 +1094,34 @@
1694 SetEmblem(BaseTexturePtr());
1695 }
1696
1697-void
1698-LauncherIcon::InsertEntryRemote(LauncherEntryRemote::Ptr const& remote)
1699+void LauncherIcon::InsertEntryRemote(LauncherEntryRemote::Ptr const& remote)
1700 {
1701- if (std::find(_entry_list.begin(), _entry_list.end(), remote) != _entry_list.end())
1702+ if (!remote || std::find(_remote_entries.begin(), _remote_entries.end(), remote) != _remote_entries.end())
1703 return;
1704
1705- _entry_list.push_front(remote);
1706+ _remote_entries.push_back(remote);
1707 AddChild(remote.get());
1708-
1709- remote->emblem_changed.connect(sigc::mem_fun(this, &LauncherIcon::OnRemoteEmblemChanged));
1710- remote->count_changed.connect(sigc::mem_fun(this, &LauncherIcon::OnRemoteCountChanged));
1711- remote->progress_changed.connect(sigc::mem_fun(this, &LauncherIcon::OnRemoteProgressChanged));
1712- remote->quicklist_changed.connect(sigc::mem_fun(this, &LauncherIcon::OnRemoteQuicklistChanged));
1713-
1714- remote->emblem_visible_changed.connect(sigc::mem_fun(this, &LauncherIcon::OnRemoteEmblemVisibleChanged));
1715- remote->count_visible_changed.connect(sigc::mem_fun(this, &LauncherIcon::OnRemoteCountVisibleChanged));
1716- remote->progress_visible_changed.connect(sigc::mem_fun(this, &LauncherIcon::OnRemoteProgressVisibleChanged));
1717-
1718- remote->urgent_changed.connect(sigc::mem_fun(this, &LauncherIcon::OnRemoteUrgentChanged));
1719-
1720+ SelectEntryRemote(remote);
1721+}
1722+
1723+void LauncherIcon::SelectEntryRemote(LauncherEntryRemote::Ptr const& remote)
1724+{
1725+ if (!remote)
1726+ return;
1727+
1728+ auto& cm = _remote_connections;
1729+ cm.Clear();
1730+
1731+ cm.Add(remote->emblem_changed.connect(sigc::mem_fun(this, &LauncherIcon::OnRemoteEmblemChanged)));
1732+ cm.Add(remote->count_changed.connect(sigc::mem_fun(this, &LauncherIcon::OnRemoteCountChanged)));
1733+ cm.Add(remote->progress_changed.connect(sigc::mem_fun(this, &LauncherIcon::OnRemoteProgressChanged)));
1734+ cm.Add(remote->quicklist_changed.connect(sigc::mem_fun(this, &LauncherIcon::OnRemoteQuicklistChanged)));
1735+
1736+ cm.Add(remote->emblem_visible_changed.connect(sigc::mem_fun(this, &LauncherIcon::OnRemoteEmblemVisibleChanged)));
1737+ cm.Add(remote->count_visible_changed.connect(sigc::mem_fun(this, &LauncherIcon::OnRemoteCountVisibleChanged)));
1738+ cm.Add(remote->progress_visible_changed.connect(sigc::mem_fun(this, &LauncherIcon::OnRemoteProgressVisibleChanged)));
1739+
1740+ cm.Add(remote->urgent_changed.connect(sigc::mem_fun(this, &LauncherIcon::OnRemoteUrgentChanged)));
1741
1742 if (remote->EmblemVisible())
1743 OnRemoteEmblemVisibleChanged(remote.get());
1744@@ -1113,28 +1138,30 @@
1745 OnRemoteQuicklistChanged(remote.get());
1746 }
1747
1748-void
1749-LauncherIcon::RemoveEntryRemote(LauncherEntryRemote::Ptr const& remote)
1750+void LauncherIcon::RemoveEntryRemote(LauncherEntryRemote::Ptr const& remote)
1751 {
1752- if (std::find(_entry_list.begin(), _entry_list.end(), remote) == _entry_list.end())
1753+ auto remote_it = std::find(_remote_entries.begin(), _remote_entries.end(), remote);
1754+
1755+ if (remote_it == _remote_entries.end())
1756 return;
1757
1758- _entry_list.remove(remote);
1759+ SetQuirk(Quirk::PROGRESS, false);
1760+
1761+ if (remote->Urgent())
1762+ SetQuirk(Quirk::URGENT, false);
1763+
1764+ _remote_entries.erase(remote_it);
1765 RemoveChild(remote.get());
1766-
1767 DeleteEmblem();
1768- SetQuirk(Quirk::PROGRESS, false);
1769-
1770- if (_remote_urgent)
1771- SetQuirk(Quirk::URGENT, false);
1772-
1773 _remote_menus = nullptr;
1774+
1775+ if (!_remote_entries.empty())
1776+ SelectEntryRemote(_remote_entries.back());
1777 }
1778
1779 void
1780 LauncherIcon::OnRemoteUrgentChanged(LauncherEntryRemote* remote)
1781 {
1782- _remote_urgent = remote->Urgent();
1783 SetQuirk(Quirk::URGENT, remote->Urgent());
1784 }
1785
1786@@ -1153,14 +1180,7 @@
1787 if (!remote->CountVisible())
1788 return;
1789
1790- if (remote->Count() / 10000 != 0)
1791- {
1792- SetEmblemText("****");
1793- }
1794- else
1795- {
1796- SetEmblemText(std::to_string(remote->Count()));
1797- }
1798+ CleanCountTextures();
1799 }
1800
1801 void
1802@@ -1190,14 +1210,7 @@
1803 void
1804 LauncherIcon::OnRemoteCountVisibleChanged(LauncherEntryRemote* remote)
1805 {
1806- if (remote->CountVisible())
1807- {
1808- SetEmblemText(std::to_string(remote->Count()));
1809- }
1810- else
1811- {
1812- DeleteEmblem();
1813- }
1814+ CleanCountTextures();
1815 }
1816
1817 void
1818
1819=== modified file 'launcher/LauncherIcon.h'
1820--- launcher/LauncherIcon.h 2014-05-28 09:56:00 +0000
1821+++ launcher/LauncherIcon.h 2014-12-17 12:14:47 +0000
1822@@ -154,14 +154,15 @@
1823 }
1824
1825 nux::BaseTexture* TextureForSize(int size);
1826-
1827- nux::BaseTexture* Emblem();
1828+ nux::BaseTexture* Emblem() const override;
1829+ nux::BaseTexture* CountTexture(double scale) override;
1830
1831 MenuItemsVector Menus();
1832-
1833- void InsertEntryRemote(LauncherEntryRemote::Ptr const& remote);
1834-
1835- void RemoveEntryRemote(LauncherEntryRemote::Ptr const& remote);
1836+ unsigned Count() const;
1837+
1838+ void InsertEntryRemote(LauncherEntryRemote::Ptr const&);
1839+ void SelectEntryRemote(LauncherEntryRemote::Ptr const&);
1840+ void RemoveEntryRemote(LauncherEntryRemote::Ptr const&);
1841
1842 nux::DndAction QueryAcceptDrop(DndData const& dnd_data)
1843 {
1844@@ -323,9 +324,10 @@
1845 void LoadQuicklist();
1846
1847 void OnTooltipEnabledChanged(bool value);
1848+ void CleanCountTextures();
1849+ BaseTexturePtr DrawCountTexture(unsigned count, double scale);
1850
1851 bool _sticky;
1852- bool _remote_urgent;
1853 float _present_urgency;
1854 float _progress;
1855 int _sort_priority;
1856@@ -346,8 +348,10 @@
1857 time::Spec _last_action;
1858
1859 BaseTexturePtr _emblem;
1860+ std::unordered_map<double, BaseTexturePtr> _counts;
1861
1862- std::list<LauncherEntryRemote::Ptr> _entry_list;
1863+ std::vector<LauncherEntryRemote::Ptr> _remote_entries;
1864+ connection::Manager _remote_connections;
1865 glib::Object<DbusmenuClient> _remote_menus;
1866
1867 static glib::Object<GtkIconTheme> _unity_theme;
1868
1869=== modified file 'launcher/MockLauncherIcon.h'
1870--- launcher/MockLauncherIcon.h 2013-12-11 15:03:25 +0000
1871+++ launcher/MockLauncherIcon.h 2014-12-17 12:14:47 +0000
1872@@ -329,11 +329,6 @@
1873 return icon_;
1874 }
1875
1876- nux::BaseTexture* Emblem()
1877- {
1878- return 0;
1879- }
1880-
1881 MenuItemsVector Menus()
1882 {
1883 return MenuItemsVector ();
1884
1885=== modified file 'launcher/SwitcherView.cpp'
1886--- launcher/SwitcherView.cpp 2014-08-06 14:19:10 +0000
1887+++ launcher/SwitcherView.cpp 2014-12-17 12:14:47 +0000
1888@@ -76,9 +76,10 @@
1889 icon_renderer_->pip_style = OVER_TILE;
1890 icon_renderer_->monitor = monitors::MAX;
1891 icon_renderer_->SetTargetSize(tile_size, icon_size, minimum_spacing);
1892+ icon_renderer_->scale = scale();
1893
1894 text_view_->SetMaximumWidth(tile_size * TEXT_TILE_MULTIPLIER);
1895- text_view_->SetLines(1);
1896+ text_view_->SetLines(-1);
1897 text_view_->SetTextColor(nux::color::White);
1898 text_view_->SetFont("Ubuntu Bold 10");
1899 text_view_->SetScale(scale);
1900@@ -196,6 +197,7 @@
1901 tile_size = TILE_SIZE.CP(scale);
1902 text_size = TEXT_SIZE.CP(scale);
1903 vertical_size = tile_size + VERTICAL_PADDING.CP(scale) * 2;
1904+ icon_renderer_->scale = scale;
1905 }
1906
1907 void SwitcherView::StartAnimation()
1908@@ -540,6 +542,12 @@
1909 arg.backlight_intensity = 0.7f;
1910 }
1911
1912+ if (icon->GetQuirk(AbstractLauncherIcon::Quirk::PROGRESS, monitor))
1913+ {
1914+ arg.progress_bias = 0.0;
1915+ arg.progress = CLAMP(icon->GetProgress(), 0.0f, 1.0f);
1916+ }
1917+
1918 return arg;
1919 }
1920
1921
1922=== modified file 'launcher/Tooltip.cpp'
1923--- launcher/Tooltip.cpp 2014-03-24 23:44:58 +0000
1924+++ launcher/Tooltip.cpp 2014-12-17 12:14:47 +0000
1925@@ -144,11 +144,12 @@
1926 _tooltip_text->SetMinimumWidth(text_min_width);
1927 _tooltip_text->SetMinimumHeight(text_height);
1928
1929+ int space_height = _padding.CP(cv_) + CORNER_RADIUS.CP(cv_);
1930 if (text_height < ANCHOR_HEIGHT.CP(cv_))
1931- {
1932- _top_space->SetMinMaxSize(1, (ANCHOR_HEIGHT.CP(cv_) - text_height) / 2 + _padding.CP(cv_) + CORNER_RADIUS.CP(cv_));
1933- _bottom_space->SetMinMaxSize(1, (ANCHOR_HEIGHT.CP(cv_) - text_height) / 2 + 1 + _padding.CP(cv_) + CORNER_RADIUS.CP(cv_));
1934- }
1935+ space_height += (ANCHOR_HEIGHT.CP(cv_) - text_height) / 2;
1936+
1937+ _top_space->SetMinMaxSize(1, space_height);
1938+ _bottom_space->SetMinMaxSize(1, space_height + 1);
1939
1940 CairoBaseWindow::PreLayoutManagement();
1941 }
1942
1943=== modified file 'lockscreen/BackgroundSettings.cpp'
1944--- lockscreen/BackgroundSettings.cpp 2014-04-10 01:16:32 +0000
1945+++ lockscreen/BackgroundSettings.cpp 2014-12-17 12:14:47 +0000
1946@@ -25,6 +25,7 @@
1947 #include "LockScreenSettings.h"
1948 #include "unity-shared/CairoTexture.h"
1949 #include "unity-shared/PanelStyle.h"
1950+#include "unity-shared/UnitySettings.h"
1951 #include "unity-shared/UScreen.h"
1952
1953 namespace unity
1954@@ -35,7 +36,7 @@
1955 {
1956 const std::string SETTINGS_NAME = "org.gnome.desktop.background";
1957
1958-constexpr int GetGridOffset(int size) { return (size % Settings::GRID_SIZE) / 2; }
1959+inline int GetGridOffset(int size) { return (size % Settings::GRID_SIZE) / 2; }
1960 }
1961
1962 BackgroundSettings::BackgroundSettings()
1963@@ -45,26 +46,27 @@
1964 gnome_bg_load_from_preferences(gnome_bg_, settings);
1965 }
1966
1967-BackgroundSettings::~BackgroundSettings()
1968-{}
1969-
1970 BaseTexturePtr BackgroundSettings::GetBackgroundTexture(int monitor)
1971 {
1972 nux::Geometry const& geo = UScreen::GetDefault()->GetMonitorGeometry(monitor);
1973+ double scale = unity::Settings::Instance().em(monitor)->DPIScale();
1974 auto& settings = Settings::Instance();
1975
1976 nux::CairoGraphics cairo_graphics(CAIRO_FORMAT_ARGB32, geo.width, geo.height);
1977+ cairo_surface_set_device_scale(cairo_graphics.GetSurface(), scale, scale);
1978 cairo_t* c = cairo_graphics.GetInternalContext();
1979
1980+ double s_width = geo.width / scale;
1981+ double s_height = geo.height / scale;
1982 cairo_surface_t* bg_surface = nullptr;
1983
1984 if (settings.use_user_background())
1985 {
1986- bg_surface = gnome_bg_create_surface(gnome_bg_, gdk_get_default_root_window(), geo.width, geo.height, FALSE);
1987+ bg_surface = gnome_bg_create_surface(gnome_bg_, gdk_get_default_root_window(), s_width, s_height, FALSE);
1988 }
1989 else if (!settings.background().empty())
1990 {
1991- glib::Object<GdkPixbuf> pixbuf(gdk_pixbuf_new_from_file_at_scale(settings.background().c_str(), geo.width, geo.height, FALSE, NULL));
1992+ glib::Object<GdkPixbuf> pixbuf(gdk_pixbuf_new_from_file_at_scale(settings.background().c_str(), s_width, s_height, FALSE, NULL));
1993
1994 if (pixbuf)
1995 bg_surface = gdk_cairo_surface_create_from_pixbuf(pixbuf, 0, NULL);
1996@@ -85,15 +87,15 @@
1997
1998 if (!settings.logo().empty())
1999 {
2000- int grid_x_offset = GetGridOffset(geo.width);
2001- int grid_y_offset = GetGridOffset(geo.height);
2002+ int grid_x_offset = GetGridOffset(s_width);
2003+ int grid_y_offset = GetGridOffset(s_height);
2004 cairo_surface_t* logo_surface = cairo_image_surface_create_from_png(settings.logo().c_str());
2005
2006 if (logo_surface)
2007 {
2008 int height = cairo_image_surface_get_height(logo_surface);
2009 int x = grid_x_offset;
2010- int y = grid_y_offset + Settings::GRID_SIZE * (geo.height / Settings::GRID_SIZE - 1) - height;
2011+ int y = grid_y_offset + Settings::GRID_SIZE * (s_height / Settings::GRID_SIZE - 1) - height;
2012
2013 cairo_save(c);
2014 cairo_translate(c, x, y);
2015@@ -107,8 +109,8 @@
2016
2017 if (settings.draw_grid())
2018 {
2019- int width = geo.width;
2020- int height = geo.height;
2021+ double width = s_width;
2022+ double height = s_height;
2023 int grid_x_offset = GetGridOffset(width);
2024 int grid_y_offset = GetGridOffset(height) + panel::Style::Instance().PanelHeight(monitor);
2025
2026
2027=== modified file 'lockscreen/BackgroundSettings.h'
2028--- lockscreen/BackgroundSettings.h 2014-03-06 03:55:03 +0000
2029+++ lockscreen/BackgroundSettings.h 2014-12-17 12:14:47 +0000
2030@@ -41,7 +41,6 @@
2031 {
2032 public:
2033 BackgroundSettings();
2034- ~BackgroundSettings();
2035
2036 BaseTexturePtr GetBackgroundTexture(int monitor);
2037
2038
2039=== modified file 'lockscreen/CMakeLists.txt'
2040--- lockscreen/CMakeLists.txt 2014-04-18 11:45:59 +0000
2041+++ lockscreen/CMakeLists.txt 2014-12-17 12:14:47 +0000
2042@@ -27,6 +27,8 @@
2043 LockScreenAcceleratorController.cpp
2044 LockScreenAccelerators.cpp
2045 ScreenSaverDBusManager.cpp
2046+ ShutdownNotifier.cpp
2047+ SuspendNotifier.cpp
2048 UserAuthenticatorPam.cpp
2049 UserPromptView.cpp
2050 )
2051
2052=== modified file 'lockscreen/CofView.cpp'
2053--- lockscreen/CofView.cpp 2014-02-13 13:57:57 +0000
2054+++ lockscreen/CofView.cpp 2014-12-17 12:14:47 +0000
2055@@ -18,6 +18,7 @@
2056 */
2057
2058 #include "CofView.h"
2059+#include "unity-shared/RawPixel.h"
2060
2061 #include "config.h"
2062
2063@@ -25,11 +26,23 @@
2064 {
2065 namespace lockscreen
2066 {
2067+namespace
2068+{
2069+const std::string COF_FILE = "cof.png";
2070+}
2071
2072 CofView::CofView()
2073 // FIXME (andy) if we get an svg cof we can make it fullscreen independent.
2074- : IconTexture(PKGDATADIR"/cof.png", 66)
2075-{}
2076+ : IconTexture(PKGDATADIR"/"+COF_FILE, -1)
2077+ , scale(1.0)
2078+{
2079+ scale.changed.connect([this] (double scale) {
2080+ int w, h;
2081+ gdk_pixbuf_get_file_info((PKGDATADIR"/" + COF_FILE).c_str(), &w, &h);
2082+ SetSize(RawPixel(std::max(w, h)).CP(scale));
2083+ ReLoadIcon();
2084+ });
2085+}
2086
2087 nux::Area* CofView::FindAreaUnderMouse(nux::Point const& mouse_position,
2088 nux::NuxEventType event_type)
2089
2090=== modified file 'lockscreen/CofView.h'
2091--- lockscreen/CofView.h 2014-02-13 13:57:57 +0000
2092+++ lockscreen/CofView.h 2014-12-17 12:14:47 +0000
2093@@ -27,11 +27,13 @@
2094 namespace lockscreen
2095 {
2096
2097-class CofView : public unity::IconTexture
2098+class CofView : public IconTexture
2099 {
2100 public:
2101 CofView();
2102
2103+ nux::Property<double> scale;
2104+
2105 nux::Area* FindAreaUnderMouse(nux::Point const& mouse_position,
2106 nux::NuxEventType event_type) override;
2107 };
2108
2109=== modified file 'lockscreen/LockScreenAbstractShield.h'
2110--- lockscreen/LockScreenAbstractShield.h 2014-06-23 19:42:24 +0000
2111+++ lockscreen/LockScreenAbstractShield.h 2014-12-17 12:14:47 +0000
2112@@ -32,25 +32,37 @@
2113 namespace lockscreen
2114 {
2115
2116+class UserPromptView;
2117+
2118 class AbstractShield : public MockableBaseWindow
2119 {
2120 public:
2121- AbstractShield(session::Manager::Ptr const& session, indicator::Indicators::Ptr const& indicators, Accelerators::Ptr const& accelerators, int monitor_num, bool is_primary)
2122+ AbstractShield(session::Manager::Ptr const& session,
2123+ indicator::Indicators::Ptr const& indicators,
2124+ Accelerators::Ptr const& accelerators,
2125+ nux::ObjectPtr<UserPromptView> const& prompt_view,
2126+ int monitor_num, bool is_primary)
2127 : MockableBaseWindow("Unity Lockscreen")
2128 , primary(is_primary)
2129 , monitor(monitor_num)
2130+ , scale(1.0)
2131 , session_manager_(session)
2132 , indicators_(indicators)
2133 , accelerators_(accelerators)
2134+ , prompt_view_(prompt_view)
2135 {}
2136
2137 nux::Property<bool> primary;
2138 nux::Property<int> monitor;
2139+ nux::Property<double> scale;
2140
2141 using MockableBaseWindow::RemoveLayout;
2142+ virtual bool HasGrab() const = 0;
2143 virtual bool IsIndicatorOpen() const = 0;
2144 virtual void ActivatePanel() = 0;
2145
2146+ sigc::signal<void> grabbed;
2147+ sigc::signal<void> grab_failed;
2148 sigc::signal<void, int, int> grab_motion;
2149 sigc::signal<void, unsigned long, unsigned long> grab_key;
2150
2151@@ -58,6 +70,7 @@
2152 session::Manager::Ptr session_manager_;
2153 indicator::Indicators::Ptr indicators_;
2154 Accelerators::Ptr accelerators_;
2155+ nux::ObjectPtr<UserPromptView> prompt_view_;
2156 };
2157
2158 } // lockscreen
2159
2160=== modified file 'lockscreen/LockScreenController.cpp'
2161--- lockscreen/LockScreenController.cpp 2014-08-06 14:11:17 +0000
2162+++ lockscreen/LockScreenController.cpp 2014-12-17 12:14:47 +0000
2163@@ -20,6 +20,7 @@
2164 #include "LockScreenController.h"
2165
2166 #include <UnityCore/DBusIndicators.h>
2167+#include <UnityCore/GLibDBusProxy.h>
2168 #include <NuxCore/Logger.h>
2169
2170 #include "LockScreenShield.h"
2171@@ -59,6 +60,7 @@
2172 , session_manager_(session_manager)
2173 , upstart_wrapper_(upstart_wrapper)
2174 , shield_factory_(shield_factory)
2175+ , suspend_notifier_(std::make_shared<SuspendNotifier>())
2176 , fade_animator_(LOCK_FADE_DURATION)
2177 , blank_window_animator_(IDLE_FADE_DURATION)
2178 , test_mode_(test_mode)
2179@@ -77,7 +79,7 @@
2180 });
2181 hidden_window_connection_->block();
2182
2183- suspend_connection_ = uscreen->suspending.connect([this] {
2184+ suspend_notifier_->RegisterInterest([this](){
2185 if (Settings::Instance().lock_on_suspend())
2186 session_manager_->PromptLockScreen();
2187 });
2188@@ -100,8 +102,7 @@
2189 fade_animator_.finished.connect([this] {
2190 if (animation::GetDirection(fade_animator_) == animation::Direction::BACKWARD)
2191 {
2192- motion_connection_->disconnect();
2193- key_connection_->disconnect();
2194+ primary_shield_connections_.Clear();
2195 uscreen_connection_->block();
2196 hidden_window_connection_->block();
2197 session_manager_->is_locked = false;
2198@@ -173,10 +174,7 @@
2199 primary_shield_ = shield;
2200 shield->primary = true;
2201 nux::GetWindowCompositor().SetAlwaysOnFrontWindow(primary_shield_.GetPointer());
2202- auto move_cb = sigc::mem_fun(this, &Controller::OnPrimaryShieldMotion);
2203- motion_connection_ = shield->grab_motion.connect(move_cb);
2204- auto key_cb = sigc::hide(sigc::hide(sigc::mem_fun(this, &Controller::ResetPostLockScreenSaver)));
2205- key_connection_ = shield->grab_key.connect(key_cb);
2206+ SetupPrimaryShieldConnections();
2207 break;
2208 }
2209 }
2210@@ -184,14 +182,52 @@
2211 ResetPostLockScreenSaver();
2212 }
2213
2214+void Controller::SetupPrimaryShieldConnections()
2215+{
2216+ if (!primary_shield_.IsValid())
2217+ return;
2218+
2219+ primary_shield_connections_.Clear();
2220+
2221+ auto move_cb = sigc::mem_fun(this, &Controller::OnPrimaryShieldMotion);
2222+ primary_shield_connections_.Add(primary_shield_->grab_motion.connect(move_cb));
2223+
2224+ auto key_cb = sigc::hide(sigc::hide(sigc::mem_fun(this, &Controller::ResetPostLockScreenSaver)));
2225+ primary_shield_connections_.Add(primary_shield_->grab_key.connect(key_cb));
2226+
2227+ if (!session_manager_->is_locked())
2228+ {
2229+ primary_shield_connections_.Add(primary_shield_->grabbed.connect([this] {
2230+ session_manager_->is_locked = true;
2231+ }));
2232+
2233+ primary_shield_connections_.Add(primary_shield_->grab_failed.connect([this] {
2234+ if (!session_manager_->is_locked())
2235+ {
2236+ LOG_ERROR(logger) << "Impossible to get the grab to lock the screen";
2237+ session_manager_->unlock_requested.emit();
2238+ }
2239+ }));
2240+ }
2241+}
2242+
2243 void Controller::EnsureShields(std::vector<nux::Geometry> const& monitors)
2244 {
2245 int num_monitors = monitors.size();
2246 int shields_size = shields_.size();
2247 int primary = UScreen::GetDefault()->GetMonitorWithMouse();
2248
2249+ // Keep a reference of the old prompt_view
2250+ nux::ObjectPtr<UserPromptView> prompt_view(prompt_view_.GetPointer());
2251+
2252 shields_.resize(num_monitors);
2253
2254+ if (!prompt_view)
2255+ {
2256+ prompt_view = test_mode_ ? nullptr : new UserPromptView(session_manager_);
2257+ prompt_view_ = prompt_view.GetPointer();
2258+ }
2259+
2260 for (int i = 0; i < num_monitors; ++i)
2261 {
2262 auto& shield = shields_[i];
2263@@ -199,7 +235,7 @@
2264
2265 if (i >= shields_size)
2266 {
2267- shield = shield_factory_->CreateShield(session_manager_, indicators_, accelerator_controller_->GetAccelerators(), i, i == primary);
2268+ shield = shield_factory_->CreateShield(session_manager_, indicators_, accelerator_controller_->GetAccelerators(), prompt_view, i, i == primary);
2269 is_new = true;
2270 }
2271
2272@@ -208,7 +244,7 @@
2273
2274 shield->SetGeometry(new_geo);
2275 shield->SetMinMaxSize(new_geo.width, new_geo.height);
2276- shield->primary = (i == primary);
2277+ shield->primary = false;
2278 shield->monitor = i;
2279
2280 // XXX: manually emit nux::Area::geometry_changed beucase nux can fail to emit it.
2281@@ -224,10 +260,7 @@
2282
2283 primary_shield_ = shields_[primary];
2284 primary_shield_->primary = true;
2285- auto move_cb = sigc::mem_fun(this, &Controller::OnPrimaryShieldMotion);
2286- motion_connection_ = primary_shield_->grab_motion.connect(move_cb);
2287- auto key_cb = sigc::hide(sigc::hide(sigc::mem_fun(this, &Controller::ResetPostLockScreenSaver)));
2288- key_connection_ = primary_shield_->grab_key.connect(key_cb);
2289+ SetupPrimaryShieldConnections();
2290 }
2291
2292 void Controller::EnsureBlankWindow()
2293@@ -349,7 +382,6 @@
2294 HideBlankWindow();
2295
2296 LockScreen();
2297- session_manager_->is_locked = true;
2298
2299 if (prompt_activation_)
2300 {
2301@@ -410,6 +442,11 @@
2302 indicators_ = std::make_shared<indicator::LockScreenDBusIndicators>();
2303 upstart_wrapper_->Emit("desktop-lock");
2304
2305+ shutdown_notifier_ = std::make_shared<ShutdownNotifier>();
2306+ shutdown_notifier_->RegisterInterest([](){
2307+ WindowManager::Default().UnmapAllNoNuxWindowsSync();
2308+ });
2309+
2310 accelerator_controller_ = std::make_shared<AcceleratorController>(session_manager_);
2311 auto activate_key = WindowManager::Default().activate_indicators_key();
2312 auto accelerator = std::make_shared<Accelerator>(activate_key.second, 0, activate_key.first);
2313@@ -435,6 +472,7 @@
2314 shield->PushToFront();
2315 });
2316
2317+ session_manager_->is_locked = primary_shield_->HasGrab();
2318 nux::GetWindowCompositor().SetAlwaysOnFrontWindow(primary_shield_.GetPointer());
2319 animation::StartOrReverse(fade_animator_, animation::Direction::FORWARD);
2320 }
2321@@ -447,6 +485,8 @@
2322
2323 void Controller::OnUnlockRequested()
2324 {
2325+ shutdown_notifier_.reset();
2326+
2327 lockscreen_timeout_.reset();
2328 screensaver_post_lock_timeout_.reset();
2329
2330
2331=== modified file 'lockscreen/LockScreenController.h'
2332--- lockscreen/LockScreenController.h 2014-06-23 19:21:17 +0000
2333+++ lockscreen/LockScreenController.h 2014-12-17 12:14:47 +0000
2334@@ -27,6 +27,9 @@
2335 #include "LockScreenShieldFactory.h"
2336 #include "LockScreenAcceleratorController.h"
2337 #include "ScreenSaverDBusManager.h"
2338+#include "ShutdownNotifier.h"
2339+#include "SuspendNotifier.h"
2340+#include "UserPromptView.h"
2341 #include "unity-shared/BackgroundEffectHelper.h"
2342 #include "unity-shared/UpstartWrapper.h"
2343
2344@@ -35,9 +38,13 @@
2345 namespace lockscreen
2346 {
2347
2348+class UserPromptView;
2349+
2350 class Controller : public sigc::trackable
2351 {
2352 public:
2353+ typedef std::shared_ptr<Controller> Ptr;
2354+
2355 Controller(DBusManager::Ptr const&, session::Manager::Ptr const&,
2356 UpstartWrapper::Ptr const& upstart_wrapper = std::make_shared<UpstartWrapper>(),
2357 ShieldFactoryInterface::Ptr const& shield_factory = std::make_shared<ShieldFactory>(),
2358@@ -61,6 +68,7 @@
2359 void BlankWindowGrabEnable(bool grab);
2360 void SimulateActivity();
2361 void ResetPostLockScreenSaver();
2362+ void SetupPrimaryShieldConnections();
2363 void ActivatePanel();
2364
2365 void OnLockRequested(bool prompt);
2366@@ -71,6 +79,7 @@
2367
2368 std::vector<nux::ObjectPtr<AbstractShield>> shields_;
2369 nux::ObjectWeakPtr<AbstractShield> primary_shield_;
2370+ nux::ObjectWeakPtr<UserPromptView> prompt_view_;
2371 nux::ObjectPtr<nux::BaseWindow> blank_window_;
2372
2373 DBusManager::Ptr dbus_manager_;
2374@@ -79,6 +88,8 @@
2375 AcceleratorController::Ptr accelerator_controller_;
2376 UpstartWrapper::Ptr upstart_wrapper_;
2377 ShieldFactoryInterface::Ptr shield_factory_;
2378+ ShutdownNotifier::Ptr shutdown_notifier_;
2379+ SuspendNotifier::Ptr suspend_notifier_;
2380
2381 nux::animation::AnimateValue<double> fade_animator_;
2382 nux::animation::AnimateValue<double> blank_window_animator_;
2383@@ -88,10 +99,8 @@
2384 BlurType old_blur_type_;
2385
2386 connection::Wrapper uscreen_connection_;
2387- connection::Wrapper suspend_connection_;
2388 connection::Wrapper hidden_window_connection_;
2389- connection::Wrapper motion_connection_;
2390- connection::Wrapper key_connection_;
2391+ connection::Manager primary_shield_connections_;
2392
2393 glib::Source::UniquePtr lockscreen_timeout_;
2394 glib::Source::UniquePtr lockscreen_delay_timeout_;
2395
2396=== modified file 'lockscreen/LockScreenPanel.cpp'
2397--- lockscreen/LockScreenPanel.cpp 2014-06-23 15:29:36 +0000
2398+++ lockscreen/LockScreenPanel.cpp 2014-12-17 12:14:47 +0000
2399@@ -82,7 +82,9 @@
2400 indicators_->on_entry_activate_request.connect(sigc::mem_fun(this, &Panel::OnEntryActivateRequest));
2401
2402 monitor.changed.connect([this, hostname] (int monitor) {
2403- hostname->SetScale(unity::Settings::Instance().em(monitor)->DPIScale());
2404+ double scale = unity::Settings::Instance().em(monitor)->DPIScale();
2405+ hostname->SetScale(scale);
2406+ static_cast<nux::HLayout*>(GetLayout())->SetLeftAndRightPadding(PADDING.CP(scale), 0);
2407 indicators_view_->SetMonitor(monitor);
2408 BuildTexture();
2409 QueueRelayout();
2410@@ -108,12 +110,39 @@
2411 return;
2412
2413 indicators_view_->AddIndicator(indicator);
2414+
2415+ if (!active)
2416+ {
2417+ for (auto const& entry : indicator->GetEntries())
2418+ {
2419+ if (entry->active())
2420+ {
2421+ active = true;
2422+ indicators_view_->ActivateEntry(entry->id());
2423+ OnEntryActivated(GetPanelName(), entry->id(), entry->geometry());
2424+ break;
2425+ }
2426+ }
2427+ }
2428+
2429 QueueRelayout();
2430 QueueDraw();
2431 }
2432
2433 void Panel::RemoveIndicator(indicator::Indicator::Ptr const& indicator)
2434 {
2435+ if (active)
2436+ {
2437+ for (auto const& entry : indicator->GetEntries())
2438+ {
2439+ if (entry->active())
2440+ {
2441+ active = false;
2442+ break;
2443+ }
2444+ }
2445+ }
2446+
2447 indicators_view_->RemoveIndicator(indicator);
2448 QueueRelayout();
2449 QueueDraw();
2450@@ -121,7 +150,7 @@
2451
2452 std::string Panel::GetPanelName() const
2453 {
2454- return "LockScreenPanel" + std::to_string(monitor);
2455+ return "LockScreenPanel";
2456 }
2457
2458 void Panel::OnIndicatorViewUpdated()
2459
2460=== modified file 'lockscreen/LockScreenSettings.cpp'
2461--- lockscreen/LockScreenSettings.cpp 2014-04-09 01:36:22 +0000
2462+++ lockscreen/LockScreenSettings.cpp 2014-12-17 12:14:47 +0000
2463@@ -55,6 +55,8 @@
2464 const std::string USE_OSK = "screen-keyboard-enabled";
2465 }
2466
2467+const RawPixel Settings::GRID_SIZE = 40_em;
2468+
2469 struct Settings::Impl
2470 {
2471 Impl()
2472
2473=== modified file 'lockscreen/LockScreenSettings.h'
2474--- lockscreen/LockScreenSettings.h 2014-04-09 01:36:22 +0000
2475+++ lockscreen/LockScreenSettings.h 2014-12-17 12:14:47 +0000
2476@@ -21,6 +21,7 @@
2477 #define UNITY_LOCKSCREEN_SETTINGS_H
2478
2479 #include <NuxCore/Property.h>
2480+#include "unity-shared/RawPixel.h"
2481
2482 namespace unity
2483 {
2484@@ -48,7 +49,7 @@
2485 nux::Property<bool> lock_on_suspend;
2486 nux::Property<bool> use_legacy;
2487
2488- static const int GRID_SIZE = 40;
2489+ static const RawPixel GRID_SIZE;
2490
2491 private:
2492 struct Impl;
2493
2494=== modified file 'lockscreen/LockScreenShield.cpp'
2495--- lockscreen/LockScreenShield.cpp 2014-08-06 14:11:17 +0000
2496+++ lockscreen/LockScreenShield.cpp 2014-12-17 12:14:47 +0000
2497@@ -19,7 +19,6 @@
2498
2499 #include "LockScreenShield.h"
2500
2501-#include <NuxCore/Logger.h>
2502 #include <Nux/VLayout.h>
2503 #include <Nux/HLayout.h>
2504 #include <Nux/PaintLayer.h>
2505@@ -30,6 +29,7 @@
2506 #include "LockScreenSettings.h"
2507 #include "UserPromptView.h"
2508 #include "unity-shared/UScreen.h"
2509+#include "unity-shared/UnitySettings.h"
2510 #include "unity-shared/WindowManager.h"
2511
2512 namespace unity
2513@@ -38,23 +38,30 @@
2514 {
2515 namespace
2516 {
2517-DECLARE_LOGGER(logger, "unity.lockscreen.shield");
2518-const unsigned MAX_GRAB_WAIT = 50;
2519+const unsigned MAX_GRAB_WAIT = 100;
2520 }
2521
2522-Shield::Shield(session::Manager::Ptr const& session_manager, indicator::Indicators::Ptr const& indicators, Accelerators::Ptr const& accelerators, int monitor_num, bool is_primary)
2523- : AbstractShield(session_manager, indicators, accelerators, monitor_num, is_primary)
2524+Shield::Shield(session::Manager::Ptr const& session_manager,
2525+ indicator::Indicators::Ptr const& indicators,
2526+ Accelerators::Ptr const& accelerators,
2527+ nux::ObjectPtr<UserPromptView> const& prompt_view,
2528+ int monitor_num, bool is_primary)
2529+ : AbstractShield(session_manager, indicators, accelerators, prompt_view, monitor_num, is_primary)
2530 , bg_settings_(std::make_shared<BackgroundSettings>())
2531- , prompt_view_(nullptr)
2532 , panel_view_(nullptr)
2533+ , cof_view_(nullptr)
2534 {
2535+ UpdateScale();
2536 is_primary ? ShowPrimaryView() : ShowSecondaryView();
2537
2538 EnableInputWindow(true);
2539
2540+ unity::Settings::Instance().dpi_changed.connect(sigc::mem_fun(this, &Shield::UpdateScale));
2541 geometry_changed.connect([this] (nux::Area*, nux::Geometry&) { UpdateBackgroundTexture();});
2542
2543 monitor.changed.connect([this] (int monitor) {
2544+ UpdateScale();
2545+
2546 if (panel_view_)
2547 panel_view_->monitor = monitor;
2548
2549@@ -69,12 +76,31 @@
2550 QueueDraw();
2551 });
2552
2553+ scale.changed.connect([this] (double scale) {
2554+ if (prompt_view_ && primary())
2555+ prompt_view_->scale = scale;
2556+
2557+ if (cof_view_)
2558+ cof_view_->scale = scale;
2559+
2560+ if (prompt_layout_)
2561+ prompt_layout_->SetLeftAndRightPadding(2 * Settings::GRID_SIZE.CP(scale));
2562+
2563+ background_layer_.reset();
2564+ UpdateBackgroundTexture();
2565+ });
2566+
2567 mouse_move.connect([this] (int x, int y, int, int, unsigned long, unsigned long) {
2568 auto const& abs_geo = GetAbsoluteGeometry();
2569 grab_motion.emit(abs_geo.x + x, abs_geo.y + y);
2570 });
2571 }
2572
2573+void Shield::UpdateScale()
2574+{
2575+ scale = unity::Settings::Instance().em(monitor)->DPIScale();
2576+}
2577+
2578 void Shield::UpdateBackgroundTexture()
2579 {
2580 auto const& monitor_geo = UScreen::GetDefault()->GetMonitorGeometry(monitor);
2581@@ -95,6 +121,7 @@
2582 {
2583 regrab_conn_->disconnect();
2584 regrab_timeout_.reset();
2585+ grabbed.emit();
2586 }
2587 else
2588 {
2589@@ -104,18 +131,29 @@
2590 if (cancel_on_failure)
2591 {
2592 regrab_timeout_.reset(new glib::Timeout(MAX_GRAB_WAIT, [this] {
2593- LOG_ERROR(logger) << "Impossible to get the grab to lock the screen";
2594- session_manager_->unlock_requested.emit();
2595+ grab_failed.emit();
2596 return false;
2597 }));
2598 }
2599 }
2600 }
2601
2602+bool Shield::HasGrab() const
2603+{
2604+ auto& wc = nux::GetWindowCompositor();
2605+ return (wc.GetPointerGrabArea() == this && wc.GetKeyboardGrabArea() == this);
2606+}
2607+
2608 void Shield::ShowPrimaryView()
2609 {
2610 if (primary_layout_)
2611 {
2612+ if (prompt_view_)
2613+ {
2614+ prompt_view_->scale = scale();
2615+ prompt_layout_->AddView(prompt_view_.GetPointer());
2616+ }
2617+
2618 GrabScreen(false);
2619 SetLayout(primary_layout_.GetPointer());
2620 return;
2621@@ -128,20 +166,26 @@
2622
2623 main_layout->AddView(CreatePanel());
2624
2625- nux::HLayout* prompt_layout = new nux::HLayout();
2626- prompt_layout->SetLeftAndRightPadding(2 * Settings::GRID_SIZE);
2627+ prompt_layout_ = new nux::HLayout();
2628+ prompt_layout_->SetLeftAndRightPadding(2 * Settings::GRID_SIZE.CP(scale));
2629
2630- prompt_view_ = CreatePromptView();
2631- prompt_layout->AddView(prompt_view_);
2632+ if (prompt_view_)
2633+ {
2634+ prompt_view_->scale = scale();
2635+ prompt_layout_->AddView(prompt_view_.GetPointer());
2636+ }
2637
2638 // 10 is just a random number to center the prompt view.
2639 main_layout->AddSpace(0, 10);
2640- main_layout->AddLayout(prompt_layout);
2641+ main_layout->AddLayout(prompt_layout_.GetPointer());
2642 main_layout->AddSpace(0, 10);
2643 }
2644
2645 void Shield::ShowSecondaryView()
2646 {
2647+ if (prompt_layout_)
2648+ prompt_layout_->RemoveChildObject(prompt_view_.GetPointer());
2649+
2650 if (cof_layout_)
2651 {
2652 SetLayout(cof_layout_.GetPointer());
2653@@ -153,8 +197,9 @@
2654 SetLayout(cof_layout_.GetPointer());
2655
2656 // The circle of friends
2657- CofView* cof_view = new CofView();
2658- main_layout->AddView(cof_view);
2659+ cof_view_ = new CofView();
2660+ cof_view_->scale = scale();
2661+ main_layout->AddView(cof_view_);
2662 }
2663
2664 Panel* Shield::CreatePanel()
2665@@ -182,20 +227,6 @@
2666 return panel_view_;
2667 }
2668
2669-UserPromptView* Shield::CreatePromptView()
2670-{
2671- auto* prompt_view = new UserPromptView(session_manager_);
2672-
2673- auto width = 8 * Settings::GRID_SIZE;
2674- auto height = 3 * Settings::GRID_SIZE;
2675-
2676- prompt_view->SetMinimumWidth(width);
2677- prompt_view->SetMaximumWidth(width);
2678- prompt_view->SetMinimumHeight(height);
2679-
2680- return prompt_view;
2681-}
2682-
2683 nux::Area* Shield::FindKeyFocusArea(unsigned etype, unsigned long keysym, unsigned long modifiers)
2684 {
2685 if (primary)
2686
2687=== modified file 'lockscreen/LockScreenShield.h'
2688--- lockscreen/LockScreenShield.h 2014-08-06 14:11:17 +0000
2689+++ lockscreen/LockScreenShield.h 2014-12-17 12:14:47 +0000
2690@@ -33,12 +33,18 @@
2691 class UserAuthenticator;
2692 class UserPromptView;
2693 class Panel;
2694+class CofView;
2695
2696 class Shield : public AbstractShield
2697 {
2698 public:
2699- Shield(session::Manager::Ptr const&, indicator::Indicators::Ptr const&, Accelerators::Ptr const&, int monitor, bool is_primary);
2700+ Shield(session::Manager::Ptr const&,
2701+ indicator::Indicators::Ptr const&,
2702+ Accelerators::Ptr const&,
2703+ nux::ObjectPtr<UserPromptView> const&,
2704+ int monitor, bool is_primary);
2705
2706+ bool HasGrab() const override;
2707 bool IsIndicatorOpen() const override;
2708 void ActivatePanel() override;
2709
2710@@ -52,18 +58,19 @@
2711 void GrabScreen(bool cancel_on_failure);
2712 void ShowPrimaryView();
2713 void ShowSecondaryView();
2714+ void UpdateScale();
2715 Panel* CreatePanel();
2716- UserPromptView* CreatePromptView();
2717
2718 std::shared_ptr<BackgroundSettings> bg_settings_;
2719 std::unique_ptr<nux::AbstractPaintLayer> background_layer_;
2720 nux::ObjectPtr<nux::Layout> primary_layout_;
2721+ nux::ObjectPtr<nux::Layout> prompt_layout_;
2722 nux::ObjectPtr<nux::Layout> cof_layout_;
2723 connection::Wrapper panel_active_conn_;
2724 connection::Wrapper regrab_conn_;
2725 glib::Source::UniquePtr regrab_timeout_;
2726- UserPromptView* prompt_view_;
2727 Panel* panel_view_;
2728+ CofView* cof_view_;
2729 };
2730
2731 }
2732
2733=== modified file 'lockscreen/LockScreenShieldFactory.cpp'
2734--- lockscreen/LockScreenShieldFactory.cpp 2014-04-17 13:08:05 +0000
2735+++ lockscreen/LockScreenShieldFactory.cpp 2014-12-17 12:14:47 +0000
2736@@ -19,15 +19,20 @@
2737
2738 #include "LockScreenShieldFactory.h"
2739 #include "LockScreenShield.h"
2740+#include "UserPromptView.h"
2741
2742 namespace unity
2743 {
2744 namespace lockscreen
2745 {
2746
2747-nux::ObjectPtr<AbstractShield> ShieldFactory::CreateShield(session::Manager::Ptr const& session_manager, indicator::Indicators::Ptr const& indicators, Accelerators::Ptr const& accelerators, int monitor, bool is_primary)
2748+nux::ObjectPtr<AbstractShield> ShieldFactory::CreateShield(session::Manager::Ptr const& session_manager,
2749+ indicator::Indicators::Ptr const& indicators,
2750+ Accelerators::Ptr const& accelerators,
2751+ nux::ObjectPtr<UserPromptView> const& prompt_view,
2752+ int monitor, bool is_primary)
2753 {
2754- return nux::ObjectPtr<Shield>(new Shield(session_manager, indicators, accelerators, monitor, is_primary));
2755+ return nux::ObjectPtr<Shield>(new Shield(session_manager, indicators, accelerators, prompt_view, monitor, is_primary));
2756 }
2757
2758 }
2759
2760=== modified file 'lockscreen/LockScreenShieldFactory.h'
2761--- lockscreen/LockScreenShieldFactory.h 2014-04-17 13:08:05 +0000
2762+++ lockscreen/LockScreenShieldFactory.h 2014-12-17 12:14:47 +0000
2763@@ -31,18 +31,28 @@
2764 namespace lockscreen
2765 {
2766
2767+class UserPromptView;
2768+
2769 struct ShieldFactoryInterface
2770 {
2771 typedef std::shared_ptr<ShieldFactoryInterface> Ptr;
2772
2773 virtual ~ShieldFactoryInterface() = default;
2774
2775- virtual nux::ObjectPtr<AbstractShield> CreateShield(session::Manager::Ptr const&, indicator::Indicators::Ptr const&, Accelerators::Ptr const&, int monitor, bool is_primary) = 0;
2776+ virtual nux::ObjectPtr<AbstractShield> CreateShield(session::Manager::Ptr const&,
2777+ indicator::Indicators::Ptr const&,
2778+ Accelerators::Ptr const&,
2779+ nux::ObjectPtr<UserPromptView> const&,
2780+ int monitor, bool is_primary) = 0;
2781 };
2782
2783 struct ShieldFactory : ShieldFactoryInterface
2784 {
2785- nux::ObjectPtr<AbstractShield> CreateShield(session::Manager::Ptr const&, indicator::Indicators::Ptr const&, Accelerators::Ptr const&, int monitor, bool is_primary) override;
2786+ nux::ObjectPtr<AbstractShield> CreateShield(session::Manager::Ptr const&,
2787+ indicator::Indicators::Ptr const&,
2788+ Accelerators::Ptr const&,
2789+ nux::ObjectPtr<UserPromptView> const&,
2790+ int monitor, bool is_primary) override;
2791 };
2792
2793 }
2794
2795=== added file 'lockscreen/ShutdownNotifier.cpp'
2796--- lockscreen/ShutdownNotifier.cpp 1970-01-01 00:00:00 +0000
2797+++ lockscreen/ShutdownNotifier.cpp 2014-12-17 12:14:47 +0000
2798@@ -0,0 +1,152 @@
2799+/*
2800+ * Copyright (C) 2014 Canonical Ltd
2801+ *
2802+ * This program is free software: you can redistribute it and/or modify
2803+ * it under the terms of the GNU General Public License version 3 as
2804+ * published by the Free Software Foundation.
2805+ *
2806+ * This program is distributed in the hope that it will be useful,
2807+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2808+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2809+ * GNU General Public License for more details.
2810+ *
2811+ * You should have received a copy of the GNU General Public License
2812+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2813+ *
2814+ * Authored by: Andrea Azzarone <andrea.azzarone@canonical.com>
2815+ */
2816+
2817+#include "ShutdownNotifier.h"
2818+
2819+#include <NuxCore/Logger.h>
2820+#include "UnityCore/GLibDBusProxy.h"
2821+
2822+namespace unity
2823+{
2824+namespace lockscreen
2825+{
2826+
2827+DECLARE_LOGGER(logger, "unity.lockscreen.shutdownnotifier");
2828+
2829+//
2830+// Private Implementation
2831+//
2832+
2833+class ShutdownNotifier::Impl
2834+{
2835+public:
2836+ Impl();
2837+ ~Impl();
2838+
2839+ bool RegisterInterest(ShutdownCallback const& cb);
2840+ void UnregisterInterest();
2841+
2842+ void Inhibit();
2843+ void Uninhibit();
2844+ bool IsInhibited() const;
2845+
2846+private:
2847+ std::shared_ptr<glib::DBusProxy> logind_proxy_;
2848+ ShutdownCallback cb_;
2849+ gint delay_inhibit_fd_;
2850+};
2851+
2852+ShutdownNotifier::Impl::Impl()
2853+ : logind_proxy_(std::make_shared<glib::DBusProxy>("org.freedesktop.login1",
2854+ "/org/freedesktop/login1",
2855+ "org.freedesktop.login1.Manager",
2856+ G_BUS_TYPE_SYSTEM))
2857+ , delay_inhibit_fd_(-1)
2858+{}
2859+
2860+ShutdownNotifier::Impl::~Impl()
2861+{
2862+ UnregisterInterest();
2863+}
2864+
2865+bool ShutdownNotifier::Impl::RegisterInterest(ShutdownCallback const& cb)
2866+{
2867+ if (!cb or cb_)
2868+ return false;
2869+
2870+ cb_ = cb;
2871+
2872+ Inhibit();
2873+
2874+ logind_proxy_->Connect("PrepareForShutdown", [this](GVariant* variant) {
2875+ bool active = glib::Variant(variant).GetBool();
2876+
2877+ if (active)
2878+ {
2879+ cb_();
2880+ UnregisterInterest();
2881+ }
2882+ });
2883+
2884+ return true;
2885+}
2886+
2887+void ShutdownNotifier::Impl::UnregisterInterest()
2888+{
2889+ if (!cb_)
2890+ return;
2891+
2892+ Uninhibit();
2893+
2894+ logind_proxy_->DisconnectSignal("PrepareForShutdown");
2895+ cb_ = nullptr;
2896+}
2897+
2898+void ShutdownNotifier::Impl::Inhibit()
2899+{
2900+ if (IsInhibited())
2901+ return;
2902+
2903+ GVariant* args = g_variant_new("(ssss)", "shutdown", "Unity Lockscreen", "Screen is locked", "delay");
2904+
2905+ logind_proxy_->CallWithUnixFdList("Inhibit", args, [this] (GVariant* variant, glib::Error const& e) {
2906+ if (e)
2907+ {
2908+ LOG_ERROR(logger) << "Failed to inhbit suspend";
2909+ }
2910+ delay_inhibit_fd_ = glib::Variant(variant).GetInt32();
2911+ });
2912+}
2913+
2914+void ShutdownNotifier::Impl::Uninhibit()
2915+{
2916+ if (!IsInhibited())
2917+ return;
2918+
2919+ close(delay_inhibit_fd_);
2920+ delay_inhibit_fd_ = -1;
2921+}
2922+
2923+bool ShutdownNotifier::Impl::IsInhibited() const
2924+{
2925+ return delay_inhibit_fd_ != -1;
2926+}
2927+
2928+//
2929+// End Private Implementation
2930+//
2931+
2932+ShutdownNotifier::ShutdownNotifier()
2933+ : pimpl_(new(Impl))
2934+{}
2935+
2936+ShutdownNotifier::~ShutdownNotifier()
2937+{}
2938+
2939+bool ShutdownNotifier::RegisterInterest(ShutdownCallback const& cb)
2940+{
2941+ return pimpl_->RegisterInterest(cb);
2942+}
2943+
2944+void ShutdownNotifier::UnregisterInterest()
2945+{
2946+ pimpl_->UnregisterInterest();
2947+}
2948+
2949+}
2950+}
2951
2952=== added file 'lockscreen/ShutdownNotifier.h'
2953--- lockscreen/ShutdownNotifier.h 1970-01-01 00:00:00 +0000
2954+++ lockscreen/ShutdownNotifier.h 2014-12-17 12:14:47 +0000
2955@@ -0,0 +1,51 @@
2956+/*
2957+ * Copyright (C) 2014 Canonical Ltd
2958+ *
2959+ * This program is free software: you can redistribute it and/or modify
2960+ * it under the terms of the GNU General Public License version 3 as
2961+ * published by the Free Software Foundation.
2962+ *
2963+ * This program is distributed in the hope that it will be useful,
2964+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2965+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2966+ * GNU General Public License for more details.
2967+ *
2968+ * You should have received a copy of the GNU General Public License
2969+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2970+ *
2971+ * Authored by: Andrea Azzarone <andrea.azzarone@canonical.com>
2972+ */
2973+
2974+#ifndef UNITY_LOCKSCREEN_SHUTDOWN_NOTIFIER
2975+#define UNITY_LOCKSCREEN_SHUTDOWN_NOTIFIER
2976+
2977+#include <memory>
2978+#include <functional>
2979+
2980+namespace unity
2981+{
2982+namespace lockscreen
2983+{
2984+
2985+typedef std::function<void()> ShutdownCallback;
2986+
2987+class ShutdownNotifier
2988+{
2989+public:
2990+ typedef std::shared_ptr<ShutdownNotifier> Ptr;
2991+
2992+ ShutdownNotifier();
2993+ ~ShutdownNotifier();
2994+
2995+ bool RegisterInterest(ShutdownCallback const&);
2996+ void UnregisterInterest();
2997+
2998+private:
2999+ class Impl;
3000+ std::unique_ptr<Impl> pimpl_;
3001+};
3002+
3003+}
3004+}
3005+
3006+#endif
3007
3008=== added file 'lockscreen/SuspendNotifier.cpp'
3009--- lockscreen/SuspendNotifier.cpp 1970-01-01 00:00:00 +0000
3010+++ lockscreen/SuspendNotifier.cpp 2014-12-17 12:14:47 +0000
3011@@ -0,0 +1,153 @@
3012+/*
3013+ * Copyright (C) 2014 Canonical Ltd
3014+ *
3015+ * This program is free software: you can redistribute it and/or modify
3016+ * it under the terms of the GNU General Public License version 3 as
3017+ * published by the Free Software Foundation.
3018+ *
3019+ * This program is distributed in the hope that it will be useful,
3020+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3021+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3022+ * GNU General Public License for more details.
3023+ *
3024+ * You should have received a copy of the GNU General Public License
3025+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
3026+ *
3027+ * Authored by: Andrea Azzarone <andrea.azzarone@canonical.com>
3028+ */
3029+
3030+#include "SuspendNotifier.h"
3031+
3032+#include <NuxCore/Logger.h>
3033+#include "UnityCore/GLibDBusProxy.h"
3034+
3035+namespace unity
3036+{
3037+namespace lockscreen
3038+{
3039+
3040+DECLARE_LOGGER(logger, "unity.lockscreen.suspendnotifier");
3041+
3042+//
3043+// Private Implementation
3044+//
3045+
3046+class SuspendNotifier::Impl
3047+{
3048+public:
3049+ Impl();
3050+ ~Impl();
3051+
3052+ bool RegisterInterest(SuspendCallback const& cb);
3053+ void UnregisterInterest();
3054+
3055+ void Inhibit();
3056+ void Uninhibit();
3057+ bool IsInhibited() const;
3058+
3059+private:
3060+ std::shared_ptr<glib::DBusProxy> logind_proxy_;
3061+ SuspendCallback cb_;
3062+ gint delay_inhibit_fd_;
3063+};
3064+
3065+SuspendNotifier::Impl::Impl()
3066+ : logind_proxy_(std::make_shared<glib::DBusProxy>("org.freedesktop.login1",
3067+ "/org/freedesktop/login1",
3068+ "org.freedesktop.login1.Manager",
3069+ G_BUS_TYPE_SYSTEM))
3070+ , delay_inhibit_fd_(-1)
3071+{}
3072+
3073+SuspendNotifier::Impl::~Impl()
3074+{
3075+ UnregisterInterest();
3076+}
3077+
3078+bool SuspendNotifier::Impl::RegisterInterest(SuspendCallback const& cb)
3079+{
3080+ if (!cb or cb_)
3081+ return false;
3082+
3083+ cb_ = cb;
3084+
3085+ Inhibit();
3086+
3087+ logind_proxy_->Connect("PrepareForSleep", [this](GVariant* variant) {
3088+ bool active = glib::Variant(variant).GetBool();
3089+
3090+ if (active) // suspending
3091+ {
3092+ cb_();
3093+ Uninhibit();
3094+ }
3095+ else // resuming
3096+ {
3097+ Inhibit();
3098+ }
3099+ });
3100+
3101+ return true;
3102+}
3103+
3104+void SuspendNotifier::Impl::UnregisterInterest()
3105+{
3106+ Uninhibit();
3107+
3108+ logind_proxy_->DisconnectSignal("PrepareForSleep");
3109+ cb_ = nullptr;
3110+}
3111+
3112+void SuspendNotifier::Impl::Inhibit()
3113+{
3114+ if (IsInhibited())
3115+ return;
3116+
3117+ GVariant* args = g_variant_new("(ssss)", "sleep", "Unity Lockscreen", "Unity wants to lock screen before suspending.", "delay");
3118+
3119+ logind_proxy_->CallWithUnixFdList("Inhibit", args, [this] (GVariant* variant, glib::Error const& e) {
3120+ if (e)
3121+ {
3122+ LOG_ERROR(logger) << "Failed to inhbit suspend";
3123+ }
3124+ delay_inhibit_fd_ = glib::Variant(variant).GetInt32();
3125+ });
3126+}
3127+
3128+void SuspendNotifier::Impl::Uninhibit()
3129+{
3130+ if (!IsInhibited())
3131+ return;
3132+
3133+ close(delay_inhibit_fd_);
3134+ delay_inhibit_fd_ = -1;
3135+}
3136+
3137+bool SuspendNotifier::Impl::IsInhibited() const
3138+{
3139+ return delay_inhibit_fd_ != -1;
3140+}
3141+
3142+//
3143+// End Private Implementation
3144+//
3145+
3146+SuspendNotifier::SuspendNotifier()
3147+ : pimpl_(new(Impl))
3148+{}
3149+
3150+SuspendNotifier::~SuspendNotifier()
3151+{}
3152+
3153+bool SuspendNotifier::RegisterInterest(SuspendCallback const& cb)
3154+{
3155+ return pimpl_->RegisterInterest(cb);
3156+}
3157+
3158+void SuspendNotifier::UnregisterInterest()
3159+{
3160+ pimpl_->UnregisterInterest();
3161+}
3162+
3163+}
3164+}
3165
3166=== added file 'lockscreen/SuspendNotifier.h'
3167--- lockscreen/SuspendNotifier.h 1970-01-01 00:00:00 +0000
3168+++ lockscreen/SuspendNotifier.h 2014-12-17 12:14:47 +0000
3169@@ -0,0 +1,51 @@
3170+/*
3171+ * Copyright (C) 2014 Canonical Ltd
3172+ *
3173+ * This program is free software: you can redistribute it and/or modify
3174+ * it under the terms of the GNU General Public License version 3 as
3175+ * published by the Free Software Foundation.
3176+ *
3177+ * This program is distributed in the hope that it will be useful,
3178+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3179+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3180+ * GNU General Public License for more details.
3181+ *
3182+ * You should have received a copy of the GNU General Public License
3183+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
3184+ *
3185+ * Authored by: Andrea Azzarone <andrea.azzarone@canonical.com>
3186+ */
3187+
3188+#ifndef UNITY_LOCKSCREEN_SUSPEND_NOTIFIER
3189+#define UNITY_LOCKSCREEN_SHUTDOWN_NOTIFIER
3190+
3191+#include <memory>
3192+#include <functional>
3193+
3194+namespace unity
3195+{
3196+namespace lockscreen
3197+{
3198+
3199+typedef std::function<void()> SuspendCallback;
3200+
3201+class SuspendNotifier
3202+{
3203+public:
3204+ typedef std::shared_ptr<SuspendNotifier> Ptr;
3205+
3206+ SuspendNotifier();
3207+ ~SuspendNotifier();
3208+
3209+ bool RegisterInterest(SuspendCallback const&);
3210+ void UnregisterInterest();
3211+
3212+private:
3213+ class Impl;
3214+ std::unique_ptr<Impl> pimpl_;
3215+};
3216+
3217+}
3218+}
3219+
3220+#endif
3221\ No newline at end of file
3222
3223=== modified file 'lockscreen/UserAuthenticatorPam.cpp'
3224--- lockscreen/UserAuthenticatorPam.cpp 2014-03-24 00:16:06 +0000
3225+++ lockscreen/UserAuthenticatorPam.cpp 2014-12-17 12:14:47 +0000
3226@@ -70,8 +70,7 @@
3227 conversation.conv = ConversationFunction;
3228 conversation.appdata_ptr = static_cast<void*>(this);
3229
3230- // FIXME (andy) We should install our own unityshell pam file.
3231- return pam_start("lightdm", username_.c_str(),
3232+ return pam_start("unity", username_.c_str(),
3233 &conversation, &pam_handle_) == PAM_SUCCESS;
3234 }
3235
3236
3237=== modified file 'lockscreen/UserPromptView.cpp'
3238--- lockscreen/UserPromptView.cpp 2014-07-24 14:03:10 +0000
3239+++ lockscreen/UserPromptView.cpp 2014-12-17 12:14:47 +0000
3240@@ -19,6 +19,9 @@
3241
3242 #include "UserPromptView.h"
3243
3244+#include "config.h"
3245+#include <glib/gi18n-lib.h>
3246+
3247 #include <boost/algorithm/string/trim.hpp>
3248 #include <Nux/VLayout.h>
3249
3250@@ -38,12 +41,12 @@
3251 const RawPixel LAYOUT_MARGIN = 10_em;
3252 const RawPixel MSG_LAYOUT_MARGIN = 15_em;
3253 const RawPixel PROMPT_LAYOUT_MARGIN = 5_em;
3254-
3255 const int PROMPT_FONT_SIZE = 13;
3256
3257-nux::AbstractPaintLayer* CrateBackgroundLayer(int width, int height)
3258+nux::AbstractPaintLayer* CrateBackgroundLayer(double width, double height, double scale)
3259 {
3260 nux::CairoGraphics cg(CAIRO_FORMAT_ARGB32, width, height);
3261+ cairo_surface_set_device_scale(cg.GetSurface(), scale, scale);
3262 cairo_t* cr = cg.GetInternalContext();
3263
3264 cairo_set_source_rgba(cr, 0.1, 0.1, 0.1, 0.4);
3265@@ -52,12 +55,12 @@
3266 1.0,
3267 0, 0,
3268 Settings::GRID_SIZE * 0.3,
3269- width, height);
3270+ width/scale, height/scale);
3271
3272 cairo_fill_preserve(cr);
3273
3274- cairo_set_source_rgba (cr, 0.4, 0.4, 0.4, 0.4);
3275- cairo_set_line_width (cr, 1);
3276+ cairo_set_source_rgba(cr, 0.4, 0.4, 0.4, 0.4);
3277+ cairo_set_line_width(cr, 1);
3278 cairo_stroke (cr);
3279
3280 // Create the texture layer
3281@@ -98,7 +101,11 @@
3282
3283 UserPromptView::UserPromptView(session::Manager::Ptr const& session_manager)
3284 : nux::View(NUX_TRACKER_LOCATION)
3285+ , scale(1.0)
3286 , session_manager_(session_manager)
3287+ , username_(nullptr)
3288+ , msg_layout_(nullptr)
3289+ , prompt_layout_(nullptr)
3290 {
3291 user_authenticator_.echo_on_requested.connect([this](std::string const& message, PromiseAuthCodePtr const& promise){
3292 AddPrompt(message, /* visible */ true, promise);
3293@@ -120,12 +127,65 @@
3294 ResetLayout();
3295 });
3296
3297+ scale.changed.connect(sigc::hide(sigc::mem_fun(this, &UserPromptView::UpdateSize)));
3298+
3299+ UpdateSize();
3300 ResetLayout();
3301
3302 user_authenticator_.AuthenticateStart(session_manager_->UserName(),
3303 sigc::mem_fun(this, &UserPromptView::AuthenticationCb));
3304 }
3305
3306+void UserPromptView::UpdateSize()
3307+{
3308+ auto width = 8 * Settings::GRID_SIZE.CP(scale);
3309+ auto height = 3 * Settings::GRID_SIZE.CP(scale);
3310+
3311+ SetMinimumWidth(width);
3312+ SetMaximumWidth(width);
3313+ SetMinimumHeight(height);
3314+
3315+ if (nux::Layout* layout = GetLayout())
3316+ {
3317+ layout->SetLeftAndRightPadding(PADDING.CP(scale));
3318+ layout->SetTopAndBottomPadding(PADDING.CP(scale));
3319+ static_cast<nux::VLayout*>(layout)->SetVerticalInternalMargin(LAYOUT_MARGIN.CP(scale));
3320+ }
3321+
3322+ if (username_)
3323+ username_->SetScale(scale);
3324+
3325+ if (msg_layout_)
3326+ {
3327+ msg_layout_->SetVerticalInternalMargin(MSG_LAYOUT_MARGIN.CP(scale));
3328+
3329+ for (auto* area : msg_layout_->GetChildren())
3330+ {
3331+ area->SetMaximumWidth(width);
3332+ static_cast<StaticCairoText*>(area)->SetScale(scale);
3333+ }
3334+ }
3335+
3336+ if (prompt_layout_)
3337+ {
3338+ prompt_layout_->SetVerticalInternalMargin(PROMPT_LAYOUT_MARGIN.CP(scale));
3339+
3340+ for (auto* area : prompt_layout_->GetChildren())
3341+ {
3342+ auto* text_input = static_cast<TextInput*>(area);
3343+ text_input->SetMinimumHeight(Settings::GRID_SIZE.CP(scale));
3344+ text_input->SetMaximumHeight(Settings::GRID_SIZE.CP(scale));
3345+ text_input->scale = scale();
3346+ }
3347+ }
3348+
3349+ bg_layer_.reset();
3350+
3351+ ComputeContentSize();
3352+ QueueRelayout();
3353+ QueueDraw();
3354+}
3355+
3356 bool UserPromptView::InspectKeyEvent(unsigned int eventType, unsigned int key_sym, const char* character)
3357 {
3358 if ((eventType == nux::NUX_KEYDOWN) && (key_sym == NUX_VK_ESCAPE))
3359@@ -145,24 +205,25 @@
3360
3361 SetLayout(new nux::VLayout());
3362
3363- GetLayout()->SetLeftAndRightPadding(PADDING);
3364- GetLayout()->SetTopAndBottomPadding(PADDING);
3365- static_cast<nux::VLayout*>(GetLayout())->SetVerticalInternalMargin(LAYOUT_MARGIN);
3366+ GetLayout()->SetLeftAndRightPadding(PADDING.CP(scale));
3367+ GetLayout()->SetTopAndBottomPadding(PADDING.CP(scale));
3368+ static_cast<nux::VLayout*>(GetLayout())->SetVerticalInternalMargin(LAYOUT_MARGIN.CP(scale));
3369
3370 auto const& real_name = session_manager_->RealName();
3371 auto const& name = (real_name.empty() ? session_manager_->UserName() : real_name);
3372
3373- unity::StaticCairoText* username = new unity::StaticCairoText(name);
3374- username->SetFont("Ubuntu "+std::to_string(PROMPT_FONT_SIZE));
3375- GetLayout()->AddView(username);
3376+ username_ = new unity::StaticCairoText(name);
3377+ username_->SetScale(scale);
3378+ username_->SetFont("Ubuntu "+std::to_string(PROMPT_FONT_SIZE));
3379+ GetLayout()->AddView(username_);
3380
3381 msg_layout_ = new nux::VLayout();
3382- msg_layout_->SetVerticalInternalMargin(MSG_LAYOUT_MARGIN);
3383+ msg_layout_->SetVerticalInternalMargin(MSG_LAYOUT_MARGIN.CP(scale));
3384 msg_layout_->SetReconfigureParentLayoutOnGeometryChange(true);
3385 GetLayout()->AddLayout(msg_layout_);
3386
3387 prompt_layout_ = new nux::VLayout();
3388- prompt_layout_->SetVerticalInternalMargin(PROMPT_LAYOUT_MARGIN);
3389+ prompt_layout_->SetVerticalInternalMargin(PROMPT_LAYOUT_MARGIN.CP(scale));
3390 prompt_layout_->SetReconfigureParentLayoutOnGeometryChange(true);
3391 GetLayout()->AddLayout(prompt_layout_);
3392
3393@@ -187,6 +248,21 @@
3394 }
3395 }
3396
3397+void UserPromptView::EnsureBGLayer()
3398+{
3399+ auto const& geo = GetGeometry();
3400+
3401+ if (bg_layer_)
3402+ {
3403+ auto const& layer_geo = bg_layer_->GetGeometry();
3404+
3405+ if (layer_geo.width == geo.width && layer_geo.height == geo.height)
3406+ return;
3407+ }
3408+
3409+ bg_layer_.reset(CrateBackgroundLayer(geo.width, geo.height, scale));
3410+}
3411+
3412 void UserPromptView::Draw(nux::GraphicsEngine& graphics_engine, bool /* force_draw */)
3413 {
3414 nux::Geometry const& geo = GetGeometry();
3415@@ -194,7 +270,7 @@
3416 graphics_engine.PushClippingRectangle(geo);
3417 nux::GetPainter().PaintBackground(graphics_engine, geo);
3418
3419- bg_layer_.reset(CrateBackgroundLayer(geo.width, geo.height));
3420+ EnsureBGLayer();
3421 nux::GetPainter().PushDrawLayer(graphics_engine, geo, bg_layer_.get());
3422
3423 nux::GetPainter().PopBackground();
3424@@ -208,7 +284,7 @@
3425
3426 if (!IsFullRedraw())
3427 {
3428- bg_layer_.reset(CrateBackgroundLayer(geo.width, geo.height));
3429+ EnsureBGLayer();
3430 nux::GetPainter().PushLayer(graphics_engine, geo, bg_layer_.get());
3431 }
3432
3433@@ -238,16 +314,18 @@
3434 auto* text_input = new unity::TextInput();
3435 auto* text_entry = text_input->text_entry();
3436
3437+ text_input->scale = scale();
3438 text_input->input_hint = SanitizeMessage(message);
3439 text_input->hint_font_size = PROMPT_FONT_SIZE;
3440 text_input->show_caps_lock = true;
3441+ text_input->show_activator = true;
3442 text_entry->SetPasswordMode(!visible);
3443 text_entry->SetPasswordChar("•");
3444 text_entry->SetToggleCursorVisibilityOnKeyFocus(true);
3445 text_entry->clipboard_enabled = false;
3446
3447- text_input->SetMinimumHeight(Settings::GRID_SIZE);
3448- text_input->SetMaximumHeight(Settings::GRID_SIZE);
3449+ text_input->SetMinimumHeight(Settings::GRID_SIZE.CP(scale));
3450+ text_input->SetMaximumHeight(Settings::GRID_SIZE.CP(scale));
3451 prompt_layout_->AddView(text_input, 1);
3452 focus_queue_.push_back(text_input);
3453
3454@@ -288,6 +366,7 @@
3455 {
3456 nux::Geometry const& geo = GetGeometry();
3457 auto* view = new unity::StaticCairoText("");
3458+ view->SetScale(scale);
3459 view->SetFont(Settings::Instance().font_name());
3460 view->SetTextColor(color);
3461 view->SetText(message);
3462
3463=== modified file 'lockscreen/UserPromptView.h'
3464--- lockscreen/UserPromptView.h 2014-04-16 19:19:41 +0000
3465+++ lockscreen/UserPromptView.h 2014-12-17 12:14:47 +0000
3466@@ -48,7 +48,8 @@
3467 {
3468 public:
3469 UserPromptView(session::Manager::Ptr const& session_manager);
3470- ~UserPromptView() {};
3471+
3472+ nux::Property<double> scale;
3473
3474 nux::View* focus_view();
3475
3476@@ -62,17 +63,17 @@
3477
3478 private:
3479 void ResetLayout();
3480+ void UpdateSize();
3481+ void EnsureBGLayer();
3482
3483 bool InspectKeyEvent(unsigned int eventType, unsigned int key_sym, const char* character);
3484
3485 session::Manager::Ptr session_manager_;
3486 UserAuthenticatorPam user_authenticator_;
3487 std::shared_ptr<nux::AbstractPaintLayer> bg_layer_;
3488+ StaticCairoText* username_;
3489 nux::VLayout* msg_layout_;
3490 nux::VLayout* prompt_layout_;
3491- StaticCairoText* message_;
3492- StaticCairoText* error_;
3493- StaticCairoText* invalid_login_;
3494 std::deque<TextInput*> focus_queue_;
3495
3496 nux::Geometry cached_focused_geo_;
3497
3498=== modified file 'panel/PanelIndicatorEntryView.cpp'
3499--- panel/PanelIndicatorEntryView.cpp 2014-05-30 07:20:13 +0000
3500+++ panel/PanelIndicatorEntryView.cpp 2014-12-17 12:14:47 +0000
3501@@ -426,7 +426,7 @@
3502 }
3503 }
3504
3505- glib::Object<PangoContext> context(gdk_pango_context_get_for_screen(gdk_screen_get_default()));
3506+ glib::Object<PangoContext> context(gdk_pango_context_get());
3507 std::shared_ptr<PangoFontDescription> desc(pango_font_description_from_string(font.c_str()), pango_font_description_free);
3508 pango_context_set_font_description(context, desc.get());
3509 pango_context_set_language(context, gtk_get_default_language());
3510
3511=== modified file 'panel/PanelMenuView.cpp'
3512--- panel/PanelMenuView.cpp 2014-04-02 21:42:44 +0000
3513+++ panel/PanelMenuView.cpp 2014-12-17 12:14:47 +0000
3514@@ -20,6 +20,7 @@
3515
3516 #include <Nux/Nux.h>
3517 #include <NuxCore/Logger.h>
3518+#include <boost/algorithm/string/erase.hpp>
3519
3520 #include "PanelMenuView.h"
3521 #include "unity-shared/AnimationUtils.h"
3522@@ -53,6 +54,32 @@
3523 const std::string WINDOW_ACTIVATED_TIMEOUT = "window-activated-timeout";
3524 const std::string UPDATE_SHOW_NOW_TIMEOUT = "update-show-now-timeout";
3525 const std::string INTEGRATED_MENUS_DOUBLE_CLICK_TIMEOUT = "integrated-menus-double-click-timeout";
3526+
3527+std::string get_current_desktop()
3528+{
3529+ std::ifstream fin("/etc/os-release");
3530+ std::string temp;
3531+ std::string os_release_name("Ubuntu");
3532+
3533+ if (fin.is_open())
3534+ {
3535+ while (getline(fin, temp))
3536+ {
3537+ if (temp.substr(0,4) == "NAME")
3538+ {
3539+ os_release_name = boost::erase_all_copy(temp.substr(temp.find_last_of('=')+1), "\"");
3540+ break;
3541+ }
3542+ }
3543+ fin.close();
3544+ }
3545+
3546+ //this is done to avoid breaking translation before 14.10.
3547+ if (os_release_name.empty() || os_release_name == "Ubuntu")
3548+ return _("Ubuntu Desktop");
3549+ else
3550+ return glib::String(g_strdup_printf(_("%s Desktop"), os_release_name.c_str())).Str();
3551+}
3552 }
3553
3554 PanelMenuView::PanelMenuView(menu::Manager::Ptr const& menus)
3555@@ -73,9 +100,8 @@
3556 , ignore_menu_visibility_(false)
3557 , integrated_menus_(decoration::Style::Get()->integrated_menus())
3558 , active_xid_(0)
3559- , desktop_name_(_("Ubuntu Desktop"))
3560+ , desktop_name_(get_current_desktop())
3561 {
3562-
3563 BamfWindow* active_win = bamf_matcher_get_active_window(matcher_);
3564 if (BAMF_IS_WINDOW(active_win))
3565 active_xid_ = bamf_window_get_xid(active_win);
3566@@ -249,6 +275,9 @@
3567 if (!mouse_inside)
3568 return nullptr;
3569
3570+ if (WindowManager::Default().IsExpoActive())
3571+ return nullptr;
3572+
3573 Area* found_area = nullptr;
3574
3575 if (!integrated_menus_ && !we_control_active_ && !spread_showing_)
3576@@ -360,14 +389,12 @@
3577
3578 bool PanelMenuView::ShouldDrawButtons() const
3579 {
3580+ if (spread_showing_)
3581+ return true;
3582+
3583 if (integrated_menus_)
3584 {
3585- if (spread_showing_)
3586- return true;
3587-
3588- WindowManager& wm = WindowManager::Default();
3589-
3590- if (!wm.IsExpoActive() && !wm.IsScaleActive())
3591+ if (!WindowManager::Default().IsExpoActive())
3592 return (GetMaximizedWindow() != 0);
3593
3594 return false;
3595@@ -375,9 +402,7 @@
3596
3597 if (we_control_active_ && is_maximized_ && !launcher_keynav_ && !switcher_showing_)
3598 {
3599- WindowManager& wm = WindowManager::Default();
3600-
3601- if (!wm.IsExpoActive())
3602+ if (!WindowManager::Default().IsExpoActive())
3603 {
3604 if (is_inside_ || show_now_activated_ || new_application_)
3605 return true;
3606@@ -387,9 +412,6 @@
3607 }
3608 }
3609
3610- if (spread_showing_)
3611- return true;
3612-
3613 return false;
3614 }
3615
3616@@ -795,7 +817,7 @@
3617 auto state = WidgetState::NORMAL;
3618 float dpi_scale = Settings::Instance().em(monitor_)->DPIScale();
3619
3620- if (integrated_menus_ && !is_desktop_focused_ && !WindowManager::Default().IsScaleActive())
3621+ if (integrated_menus_ && !is_desktop_focused_ && !WindowManager::Default().IsExpoActive())
3622 {
3623 title_geo_.x = geo.x + window_buttons_->GetBaseWidth() + (style->TitleIndent() * dpi_scale);
3624
3625@@ -828,10 +850,9 @@
3626 {
3627 if (integrated_menus_ || (!switcher_showing_ && !launcher_keynav_))
3628 {
3629- WindowManager& wm = WindowManager::Default();
3630 std::string new_title;
3631
3632- if (wm.IsExpoActive())
3633+ if (WindowManager::Default().IsExpoActive())
3634 {
3635 new_title = desktop_name_;
3636 }
3637@@ -1103,7 +1124,10 @@
3638 }
3639
3640 if (is_maximized_)
3641- maximized_set_.insert(active_xid_);
3642+ {
3643+ maximized_wins_.erase(std::remove(maximized_wins_.begin(), maximized_wins_.end(), active_xid_), maximized_wins_.end());
3644+ maximized_wins_.push_front(active_xid_);
3645+ }
3646
3647 // register callback for new view
3648 view_name_changed_signal_.Connect(new_view, "name-changed",
3649@@ -1159,7 +1183,7 @@
3650
3651 void PanelMenuView::OnWindowMinimized(Window xid)
3652 {
3653- maximized_set_.erase(xid);
3654+ maximized_wins_.erase(std::remove(maximized_wins_.begin(), maximized_wins_.end(), xid), maximized_wins_.end());
3655
3656 if (xid == active_xid_)
3657 {
3658@@ -1175,18 +1199,24 @@
3659
3660 void PanelMenuView::OnWindowUnminimized(Window xid)
3661 {
3662- if (WindowManager::Default().IsWindowMaximized(xid))
3663- maximized_set_.insert(xid);
3664-
3665 if (xid == active_xid_)
3666 {
3667+ if (WindowManager::Default().IsWindowMaximized(xid))
3668+ maximized_wins_.push_front(xid);
3669+
3670 if (Refresh())
3671 QueueDraw();
3672 }
3673- else if (integrated_menus_ && IsWindowUnderOurControl(xid))
3674+ else
3675 {
3676- if (Refresh())
3677- QueueDraw();
3678+ if (WindowManager::Default().IsWindowMaximized(xid))
3679+ maximized_wins_.push_back(xid);
3680+
3681+ if (integrated_menus_ && IsWindowUnderOurControl(xid))
3682+ {
3683+ if (Refresh())
3684+ QueueDraw();
3685+ }
3686 }
3687 }
3688
3689@@ -1194,7 +1224,7 @@
3690 {
3691 // FIXME: compiz doesn't give us a valid xid (is always 0 on unmap)
3692 // we need to do this again on BamfView closed signal.
3693- maximized_set_.erase(xid);
3694+ maximized_wins_.erase(std::remove(maximized_wins_.begin(), maximized_wins_.end(), xid), maximized_wins_.end());
3695
3696 if (xid == active_xid_)
3697 {
3698@@ -1212,22 +1242,26 @@
3699 {
3700 if (WindowManager::Default().IsWindowMaximized(xid))
3701 {
3702- maximized_set_.insert(xid);
3703-
3704 if (xid == active_xid_)
3705 {
3706+ maximized_wins_.push_front(xid);
3707+
3708 if (Refresh())
3709 QueueDraw();
3710 }
3711+ else
3712+ {
3713+ maximized_wins_.push_back(xid);
3714+ }
3715 }
3716 }
3717
3718 void PanelMenuView::OnWindowMaximized(Window xid)
3719 {
3720- maximized_set_.insert(xid);
3721-
3722 if (xid == active_xid_)
3723 {
3724+ maximized_wins_.push_front(xid);
3725+
3726 // We need to update the is_inside_ state in the case of maximization by grab
3727 auto mouse = nux::GetGraphicsDisplay()->GetMouseScreenCoord();
3728 is_inside_ = GetAbsoluteGeometry().IsInside(mouse);
3729@@ -1236,16 +1270,21 @@
3730 if (Refresh())
3731 FullRedraw();
3732 }
3733- else if (integrated_menus_ && IsWindowUnderOurControl(xid))
3734+ else
3735 {
3736- if (Refresh())
3737- QueueDraw();
3738+ maximized_wins_.push_back(xid);
3739+
3740+ if (integrated_menus_ && IsWindowUnderOurControl(xid))
3741+ {
3742+ if (Refresh())
3743+ QueueDraw();
3744+ }
3745 }
3746 }
3747
3748 void PanelMenuView::OnWindowRestored(Window xid)
3749 {
3750- maximized_set_.erase(xid);
3751+ maximized_wins_.erase(std::remove(maximized_wins_.begin(), maximized_wins_.end(), xid), maximized_wins_.end());
3752
3753 if (active_xid_ == xid)
3754 {
3755@@ -1344,7 +1383,7 @@
3756 Window window_xid = 0;
3757
3758 // Find the front-most of the maximized windows we are controlling
3759- for (auto xid : maximized_set_)
3760+ for (auto xid : maximized_wins_)
3761 {
3762 // We can safely assume only the front-most is visible
3763 if (IsValidWindow(xid))
3764@@ -1769,8 +1808,8 @@
3765 {
3766 PanelIndicatorsView::SetMonitor(monitor);
3767
3768+ maximized_wins_.clear();
3769 monitor_geo_ = UScreen::GetDefault()->GetMonitorGeometry(monitor_);
3770- maximized_set_.clear();
3771 GList* windows = bamf_matcher_get_window_stack_for_monitor(matcher_, monitor_);
3772
3773 for (GList* l = windows; l; l = l->next)
3774@@ -1780,12 +1819,18 @@
3775
3776 auto window = static_cast<BamfWindow*>(l->data);
3777 auto view = static_cast<BamfView*>(l->data);
3778+ auto xid = bamf_window_get_xid(window);
3779
3780 if (bamf_view_is_active(view))
3781- active_xid_ = bamf_window_get_xid(window);
3782+ active_xid_ = xid;
3783
3784 if (bamf_window_maximized(window) == BAMF_WINDOW_MAXIMIZED)
3785- maximized_set_.insert(bamf_window_get_xid(window));
3786+ {
3787+ if (xid == active_xid_)
3788+ maximized_wins_.push_front(xid);
3789+ else
3790+ maximized_wins_.push_back(xid);
3791+ }
3792 }
3793
3794 Window maximized = GetMaximizedWindow();
3795
3796=== modified file 'panel/PanelMenuView.h'
3797--- panel/PanelMenuView.h 2014-04-02 21:42:44 +0000
3798+++ panel/PanelMenuView.h 2014-12-17 12:14:47 +0000
3799@@ -170,7 +170,7 @@
3800 bool is_desktop_focused_;
3801
3802 PanelIndicatorEntryView* last_active_view_;
3803- std::set<Window> maximized_set_;
3804+ std::deque<Window> maximized_wins_;
3805 glib::Object<BamfApplication> new_application_;
3806 std::list<glib::Object<BamfApplication>> new_apps_;
3807 std::string panel_title_;
3808
3809=== modified file 'plugins/unityshell/src/unityshell.cpp'
3810--- plugins/unityshell/src/unityshell.cpp 2014-08-06 14:19:10 +0000
3811+++ plugins/unityshell/src/unityshell.cpp 2014-12-17 12:14:47 +0000
3812@@ -278,6 +278,7 @@
3813 CompositeScreenInterface::setHandler(cScreen);
3814 GLScreenInterface::setHandler(gScreen);
3815 ScaleScreenInterface::setHandler(sScreen);
3816+ screen->updateSupportedWmHints();
3817
3818 PluginAdapter::Initialize(screen);
3819 AddChild(&WindowManager::Default());
3820@@ -534,7 +535,19 @@
3821 else
3822 {
3823 CompMatch windows_match;
3824- for (auto xid : spread_filter_->FilteredWindows())
3825+ auto const& filtered_windows = spread_filter_->FilteredWindows();
3826+
3827+ for (auto const& swin : sScreen->getWindows())
3828+ {
3829+ if (filtered_windows.find(swin->window->id()) != filtered_windows.end())
3830+ continue;
3831+
3832+ auto* uwin = UnityWindow::get(swin->window);
3833+ uwin->OnTerminateSpread();
3834+ fake_decorated_windows_.erase(uwin);
3835+ }
3836+
3837+ for (auto xid : filtered_windows)
3838 windows_match |= "xid="+std::to_string(xid);
3839
3840 auto match = sScreen->getCustomMatch();
3841@@ -2791,23 +2804,6 @@
3842 return "Unity";
3843 }
3844
3845-bool isNuxWindow(CompWindow* value)
3846-{
3847- std::vector<Window> const& xwns = nux::XInputWindow::NativeHandleList();
3848- auto id = value->id();
3849-
3850- // iterate loop by hand rather than use std::find as this is considerably faster
3851- // we care about performance here because of the high frequency in which this function is
3852- // called (nearly every frame)
3853- unsigned int size = xwns.size();
3854- for (unsigned int i = 0; i < size; ++i)
3855- {
3856- if (xwns[i] == id)
3857- return true;
3858- }
3859- return false;
3860-}
3861-
3862 void UnityScreen::RaiseInputWindows()
3863 {
3864 std::vector<Window> const& xwns = nux::XInputWindow::NativeHandleList();
3865@@ -3715,7 +3711,6 @@
3866 }
3867
3868 auto max_bounds = NuxGeometryFromCompRect(output.workArea());
3869-
3870 if (launcher_controller_->options()->hide_mode != LAUNCHER_HIDE_NEVER)
3871 {
3872 int monitor_width = unity_settings_.LauncherWidth(monitor);
3873@@ -3729,19 +3724,18 @@
3874 layout.spacing = local::SCALE_SPACING.CP(monitor_scale);
3875 int padding = local::SCALE_PADDING.CP(monitor_scale);
3876 max_bounds.Expand(-padding, -padding);
3877- layout.LayoutWindows(layout_windows, max_bounds, final_bounds);
3878+ layout.LayoutWindowsNearest(layout_windows, max_bounds, final_bounds);
3879
3880- auto lw_it = layout_windows.begin();
3881- for (auto const& sw : scaled_windows)
3882+ for (auto const& lw : layout_windows)
3883 {
3884- if (lw_it == layout_windows.end())
3885- break;
3886-
3887- LayoutWindow::Ptr const& lw = *lw_it;
3888-
3889- if (sw->window->id() != lw->xid)
3890+ auto sw_it = std::find_if(scaled_windows.begin(), scaled_windows.end(), [&lw] (ScaleWindow* sw) {
3891+ return sw->window->id() == lw->xid;
3892+ });
3893+
3894+ if (sw_it == scaled_windows.end())
3895 continue;
3896
3897+ ScaleWindow* sw = *sw_it;
3898 ScaleSlot slot(CompRectFromNuxGeo(lw->result));
3899 slot.scale = lw->scale;
3900
3901@@ -3758,7 +3752,6 @@
3902 slot.filled = true;
3903
3904 sw->setSlot(slot);
3905- ++lw_it;
3906 }
3907 }
3908
3909@@ -3781,6 +3774,7 @@
3910 if (hud_controller_->IsVisible())
3911 hud_controller_->HideHud();
3912
3913+ menus_->Indicators()->CloseActiveEntry();
3914 launcher_controller_->ClearTooltips();
3915
3916 if (launcher_controller_->KeyNavIsActive())
3917@@ -3999,7 +3993,7 @@
3918 return launcher_controller_;
3919 }
3920
3921-std::shared_ptr<lockscreen::Controller> UnityScreen::lockscreen_controller()
3922+lockscreen::Controller::Ptr UnityScreen::lockscreen_controller()
3923 {
3924 return lockscreen_controller_;
3925 }
3926@@ -4038,8 +4032,8 @@
3927 void UnityScreen::ShowFirstRunHints()
3928 {
3929 sources_.AddTimeoutSeconds(1, [this] {
3930- auto const& cache_dir = DesktopUtilities::GetUserCacheDirectory();
3931- if (!cache_dir.empty() && !g_file_test((cache_dir+local::FIRST_RUN_STAMP).c_str(), G_FILE_TEST_EXISTS))
3932+ auto const& config_dir = DesktopUtilities::GetUserConfigDirectory();
3933+ if (!config_dir.empty() && !g_file_test((config_dir+local::FIRST_RUN_STAMP).c_str(), G_FILE_TEST_EXISTS))
3934 {
3935 // We focus the panel, so the shortcut hint will be hidden at first user input
3936 auto const& panels = panel_controller_->panels();
3937@@ -4052,7 +4046,7 @@
3938 shortcut_controller_->Show();
3939
3940 glib::Error error;
3941- g_file_set_contents((cache_dir+local::FIRST_RUN_STAMP).c_str(), "", 0, &error);
3942+ g_file_set_contents((config_dir+local::FIRST_RUN_STAMP).c_str(), "", 0, &error);
3943
3944 if (error)
3945 {
3946@@ -4092,7 +4086,7 @@
3947 , close_icon_state_(decoration::WidgetState::NORMAL)
3948 , deco_win_(uScreen->deco_manager_->HandleWindow(window))
3949 , need_fake_deco_redraw_(false)
3950- , is_nux_window_(isNuxWindow(window))
3951+ , is_nux_window_(PluginAdapter::IsNuxWindow(window))
3952 {
3953 WindowInterface::setHandler(window);
3954 GLWindowInterface::setHandler(gWindow);
3955@@ -4428,7 +4422,7 @@
3956 }
3957 else
3958 {
3959- window->setShowDesktopMode (false);
3960+ window->setShowDesktopMode(false);
3961 }
3962 }
3963 }
3964
3965=== modified file 'plugins/unityshell/src/unityshell.h'
3966--- plugins/unityshell/src/unityshell.h 2014-07-24 14:14:47 +0000
3967+++ plugins/unityshell/src/unityshell.h 2014-12-17 12:14:47 +0000
3968@@ -239,7 +239,7 @@
3969
3970 switcher::Controller::Ptr switcher_controller();
3971 launcher::Controller::Ptr launcher_controller();
3972- std::shared_ptr<lockscreen::Controller> lockscreen_controller();
3973+ lockscreen::Controller::Ptr lockscreen_controller();
3974
3975 bool DoesPointIntersectUnityGeos(nux::Point const& pt);
3976
3977@@ -348,7 +348,7 @@
3978 session::DBusManager::Ptr session_dbus_manager_;
3979 session::Controller::Ptr session_controller_;
3980 lockscreen::DBusManager::Ptr screensaver_dbus_manager_;
3981- std::shared_ptr<lockscreen::Controller> lockscreen_controller_;
3982+ lockscreen::Controller::Ptr lockscreen_controller_;
3983 debug::DebugDBusInterface debugger_;
3984 std::unique_ptr<BGHash> bghash_;
3985 spread::Filter::Ptr spread_filter_;
3986
3987=== added file 'resources/arrow_right.png'
3988Binary files resources/arrow_right.png 1970-01-01 00:00:00 +0000 and resources/arrow_right.png 2014-12-17 12:14:47 +0000 differ
3989=== modified file 'services/panel-main.c'
3990--- services/panel-main.c 2014-03-05 17:19:50 +0000
3991+++ services/panel-main.c 2014-12-17 12:14:47 +0000
3992@@ -82,6 +82,9 @@
3993 " <arg type='i' name='delta' direction='in'/>"
3994 " </method>"
3995 ""
3996+ ""
3997+ " <method name='CloseActiveEntry' />"
3998+ ""
3999 " <signal name='EntryActivated'>"
4000 " <arg type='s' name='panel_id' />"
4001 " <arg type='s' name='entry_id' />"
4002@@ -254,6 +257,11 @@
4003 g_dbus_method_invocation_return_value (invocation, NULL);
4004 g_free(entry_id);
4005 }
4006+ else if (g_strcmp0 (method_name, "CloseActiveEntry") == 0)
4007+ {
4008+ panel_service_close_active_entry (service);
4009+ g_dbus_method_invocation_return_value (invocation, NULL);
4010+ }
4011 }
4012
4013 static void
4014
4015=== modified file 'services/panel-service.c'
4016--- services/panel-service.c 2014-08-06 14:19:10 +0000
4017+++ services/panel-service.c 2014-12-17 12:14:47 +0000
4018@@ -2383,6 +2383,8 @@
4019 IndicatorObject *object;
4020 IndicatorObjectEntry *entry;
4021
4022+ g_return_if_fail (PANEL_IS_SERVICE (self));
4023+
4024 entry = get_indicator_entry_by_id (self, entry_id);
4025 g_return_if_fail (entry);
4026
4027@@ -2399,6 +2401,8 @@
4028 IndicatorObject *object;
4029 IndicatorObjectEntry *entry;
4030
4031+ g_return_if_fail (PANEL_IS_SERVICE (self));
4032+
4033 entry = get_indicator_entry_by_id (self, entry_id);
4034 g_return_if_fail (entry);
4035
4036@@ -2427,3 +2431,14 @@
4037 entry, 1, direction);
4038 }
4039 }
4040+
4041+void
4042+panel_service_close_active_entry (PanelService *self)
4043+{
4044+ g_return_if_fail (PANEL_IS_SERVICE (self));
4045+
4046+ if (GTK_IS_MENU (self->priv->last_menu))
4047+ {
4048+ gtk_menu_popdown (GTK_MENU (self->priv->last_menu));
4049+ }
4050+}
4051
4052=== modified file 'services/panel-service.h'
4053--- services/panel-service.h 2014-02-06 12:02:48 +0000
4054+++ services/panel-service.h 2014-12-17 12:14:47 +0000
4055@@ -122,6 +122,8 @@
4056 const gchar *entry_id,
4057 gint32 delta);
4058
4059+void panel_service_close_active_entry (PanelService *self);
4060+
4061 G_END_DECLS
4062
4063 #endif /* _PANEL_SERVICE_H_ */
4064
4065=== modified file 'tests/CMakeLists.txt'
4066--- tests/CMakeLists.txt 2014-02-20 20:52:57 +0000
4067+++ tests/CMakeLists.txt 2014-12-17 12:14:47 +0000
4068@@ -131,7 +131,6 @@
4069 test_favorite_store_gsettings.cpp
4070 test_favorite_store_private.cpp
4071 test_launcher_entry_remote.cpp
4072- test_launcher_model.cpp
4073 test_launcher_options.cpp
4074 test_layout_system.cpp
4075 test_model_iterator.cpp
4076@@ -242,6 +241,7 @@
4077 test_launcher_hover_machine.cpp
4078 test_launcher_icon.cpp
4079 test_launcher_minimize_speed.cpp
4080+ test_launcher_model.cpp
4081 test_launcher_tooltip.cpp
4082 test_lockscreen_controller.cpp
4083 test_panel_controller.cpp
4084
4085=== modified file 'tests/mock_indicators.h'
4086--- tests/mock_indicators.h 2014-02-28 05:16:10 +0000
4087+++ tests/mock_indicators.h 2014-12-17 12:14:47 +0000
4088@@ -36,6 +36,7 @@
4089 // Implementing Indicators virtual functions
4090 MOCK_METHOD2(SyncGeometries, void(std::string const&, EntryLocationMap const&));
4091 MOCK_METHOD5(ShowEntriesDropdown, void(Indicator::Entries const&, Entry::Ptr const&, unsigned xid, int x, int y));
4092+ MOCK_METHOD0(CloseActiveEntry, void());
4093 MOCK_CONST_METHOD0(IconPaths, std::vector<std::string> const&());
4094 MOCK_METHOD2(OnEntryScroll, void(std::string const&, int delta));
4095 MOCK_METHOD5(OnEntryShowMenu, void(std::string const&, unsigned xid, int x, int y, unsigned button));
4096
4097=== modified file 'tests/test_lockscreen_controller.cpp'
4098--- tests/test_lockscreen_controller.cpp 2014-06-23 19:42:24 +0000
4099+++ tests/test_lockscreen_controller.cpp 2014-12-17 12:14:47 +0000
4100@@ -20,6 +20,7 @@
4101 #include <gmock/gmock.h>
4102 using namespace testing;
4103
4104+#include "lockscreen/UserPromptView.h"
4105 #include "lockscreen/LockScreenController.h"
4106
4107 #include <Nux/NuxTimerTickSource.h>
4108@@ -29,6 +30,7 @@
4109
4110 #include "lockscreen/LockScreenSettings.h"
4111 #include "lockscreen/ScreenSaverDBusManager.h"
4112+#include "unity-shared/DashStyle.h"
4113 #include "unity-shared/PanelStyle.h"
4114 #include "unity-shared/UScreen.h"
4115 #include "test_mock_session_manager.h"
4116@@ -52,16 +54,21 @@
4117 struct MockShield : AbstractShield
4118 {
4119 MockShield()
4120- : AbstractShield(nullptr, nullptr, nullptr, 0, false)
4121+ : AbstractShield(nullptr, nullptr, nullptr, nux::ObjectPtr<UserPromptView>(), 0, false)
4122 {}
4123
4124 MOCK_CONST_METHOD0(IsIndicatorOpen, bool());
4125 MOCK_METHOD0(ActivatePanel, void());
4126+ MOCK_CONST_METHOD0(HasGrab, bool());
4127 };
4128
4129 struct ShieldFactoryMock : ShieldFactoryInterface
4130 {
4131- nux::ObjectPtr<AbstractShield> CreateShield(session::Manager::Ptr const&, indicator::Indicators::Ptr const&, Accelerators::Ptr const&, int, bool) override
4132+ nux::ObjectPtr<AbstractShield> CreateShield(session::Manager::Ptr const&,
4133+ indicator::Indicators::Ptr const&,
4134+ Accelerators::Ptr const&,
4135+ nux::ObjectPtr<UserPromptView> const&,
4136+ int, bool) override
4137 {
4138 return nux::ObjectPtr<AbstractShield>(new MockShield());
4139 }
4140@@ -95,6 +102,7 @@
4141 nux::animation::AnimationController animation_controller;
4142
4143 MockUScreen uscreen;
4144+ unity::dash::Style dash_style;
4145 unity::panel::Style panel_style;
4146 unity::lockscreen::Settings lockscreen_settings;
4147 session::MockManager::Ptr session_manager;
4148
4149=== modified file 'tests/test_main_xless.cpp'
4150--- tests/test_main_xless.cpp 2013-02-21 10:47:14 +0000
4151+++ tests/test_main_xless.cpp 2014-12-17 12:14:47 +0000
4152@@ -3,18 +3,17 @@
4153 #include <NuxCore/Logger.h>
4154 #include <Nux/Nux.h>
4155 #include <config.h>
4156-
4157+#include "test_utils.h"
4158
4159 const gchar* LOCAL_DATA_DIR = BUILDDIR"/tests/data:/usr/share";
4160
4161 int main(int argc, char** argv)
4162 {
4163 ::testing::InitGoogleTest(&argc, argv);
4164-#if G_ENCODE_VERSION (GLIB_MAJOR_VERSION, GLIB_MINOR_VERSION) <= GLIB_VERSION_2_34
4165- g_type_init();
4166-#endif
4167+
4168 setlocale(LC_ALL, "C");
4169-
4170+ g_setenv("LC_ALL", "C", TRUE);
4171+ Utils::init_gsettings_test_environment();
4172 g_setenv("XDG_DATA_DIRS", LOCAL_DATA_DIR, TRUE);
4173
4174 // Slightly higher as we're more likely to test things we know will fail
4175
4176=== modified file 'tests/test_previews_music_payment.cpp'
4177--- tests/test_previews_music_payment.cpp 2014-03-21 04:40:12 +0000
4178+++ tests/test_previews_music_payment.cpp 2014-12-17 12:14:47 +0000
4179@@ -21,6 +21,7 @@
4180 #include <gmock/gmock.h>
4181
4182 #include <Nux/Nux.h>
4183+#include <Nux/VLayout.h>
4184 #include <Nux/BaseWindow.h>
4185 #include <unity-shared/StaticCairoText.h>
4186 #include <unity-shared/CoverArt.h>
4187
4188=== modified file 'tests/test_text_input.cpp'
4189--- tests/test_text_input.cpp 2014-03-21 04:40:12 +0000
4190+++ tests/test_text_input.cpp 2014-12-17 12:14:47 +0000
4191@@ -23,6 +23,7 @@
4192 #include <gtest/gtest.h>
4193
4194 #include "unity-shared/DashStyle.h"
4195+#include "unity-shared/StaticCairoText.h"
4196 #include "unity-shared/TextInput.h"
4197 #include "test_utils.h"
4198
4199
4200=== added file 'tools/migration-scripts/03_unity_first_run_stamp_move'
4201--- tools/migration-scripts/03_unity_first_run_stamp_move 1970-01-01 00:00:00 +0000
4202+++ tools/migration-scripts/03_unity_first_run_stamp_move 2014-12-17 12:14:47 +0000
4203@@ -0,0 +1,35 @@
4204+#!/usr/bin/python
4205+# -*- coding: utf-8 -*-
4206+# Copyright (C) 2014 Canonical
4207+#
4208+# Authors:
4209+# Brandon Schaefer <brandon.schaefer@canonical.com>
4210+#
4211+# This program is free software; you can redistribute it and/or modify it under
4212+# the terms of the GNU General Public License as published by the Free Software
4213+# Foundation; version 3.
4214+#
4215+# This program is distributed in the hope that it will be useful, but WITHOUTa
4216+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
4217+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
4218+# details.
4219+#
4220+# You should have received a copy of the GNU General Public License along with
4221+# this program; if not, write to the Free Software Foundation, Inc.,
4222+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
4223+
4224+from gi.repository import GLib
4225+from os import path, rename, mkdir
4226+
4227+old_first_run_path = GLib.get_user_cache_dir() + "/unity/first_run.stamp"
4228+new_first_run_path = GLib.get_user_config_dir() + "/unity"
4229+
4230+# If we have the old first_run.stamp file, we must move it to the new location
4231+if path.isfile(old_first_run_path):
4232+
4233+ # make sure the new dir exists before attempting to move
4234+ if not path.isdir(new_first_run_path):
4235+ mkdir(new_first_run_path)
4236+
4237+ new_first_run_path += "/first_run.stamp"
4238+ rename(old_first_run_path, new_first_run_path)
4239
4240=== modified file 'unity-shared/CompizUtils.cpp'
4241--- unity-shared/CompizUtils.cpp 2014-04-14 13:51:58 +0000
4242+++ unity-shared/CompizUtils.cpp 2014-12-17 12:14:47 +0000
4243@@ -1,6 +1,6 @@
4244 // -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
4245 /*
4246-* Copyright (C) 2013 Canonical Ltd
4247+* Copyright (C) 2013-2014 Canonical Ltd
4248 *
4249 * This program is free software: you can redistribute it and/or modify
4250 * it under the terms of the GNU General Public License version 3 as
4251@@ -30,6 +30,11 @@
4252 {
4253 const unsigned PIXMAP_DEPTH = 32;
4254 const float DEFAULT_SCALE = 1.0f;
4255+ const unsigned DECORABLE_WINDOW_TYPES = CompWindowTypeDialogMask |
4256+ CompWindowTypeModalDialogMask |
4257+ CompWindowTypeUtilMask |
4258+ CompWindowTypeMenuMask |
4259+ CompWindowTypeNormalMask;
4260 }
4261
4262 SimpleTexture::SimpleTexture(GLTexture::List const& tex)
4263@@ -39,7 +44,7 @@
4264 //
4265
4266 SimpleTextureQuad::SimpleTextureQuad()
4267- : scale(DEFAULT_SCALE)
4268+ : scale_(DEFAULT_SCALE)
4269 {}
4270
4271 bool SimpleTextureQuad::SetTexture(SimpleTexture::Ptr const& simple_texture)
4272@@ -52,24 +57,27 @@
4273 if (st && st->texture())
4274 {
4275 auto* tex = st->texture();
4276- CompPoint old_coords(quad.box.x(), quad.box.y());
4277- short invalid = std::numeric_limits<short>::min();
4278- quad.box.setGeometry(invalid, invalid, tex->width() * scale, tex->height() * scale);
4279- SetCoords(old_coords.x(), old_coords.y());
4280+ CompSize size(tex->width() * scale_, tex->height() * scale_);
4281+
4282+ if (quad.box.width() != size.width() || quad.box.height() != size.height())
4283+ {
4284+ quad.box.setSize(size);
4285+ UpdateMatrix();
4286+ }
4287 }
4288
4289 return true;
4290 }
4291
4292-bool SimpleTextureQuad::SetScale(float s)
4293+bool SimpleTextureQuad::SetScale(double s)
4294 {
4295- if (!st || scale == s)
4296+ if (!st || scale_ == s)
4297 return false;
4298
4299- scale = s;
4300+ scale_ = s;
4301 auto* tex = st->texture();
4302- quad.box.setWidth(tex->width() * scale);
4303- quad.box.setHeight(tex->height() * scale);
4304+ quad.box.setWidth(tex->width() * scale_);
4305+ quad.box.setHeight(tex->height() * scale_);
4306 UpdateMatrix();
4307 return true;
4308 }
4309@@ -91,8 +99,8 @@
4310 int y = quad.box.y();
4311
4312 quad.matrix = (st && st->texture()) ? st->texture()->matrix() : GLTexture::Matrix();
4313- quad.matrix.xx /= scale;
4314- quad.matrix.yy /= scale;
4315+ quad.matrix.xx /= scale_;
4316+ quad.matrix.yy /= scale_;
4317 quad.matrix.x0 = 0.0f - COMP_TEX_COORD_X(quad.matrix, x);
4318 quad.matrix.y0 = 0.0f - COMP_TEX_COORD_Y(quad.matrix, y);
4319 }
4320@@ -166,57 +174,68 @@
4321 return cairo_xlib_surface_get_height(surface_);
4322 }
4323
4324+//
4325+//
4326+
4327+unsigned WindowDecorationElements(CompWindow* win, WindowFilter::Value wf)
4328+{
4329+ unsigned elements = DecorationElement::NONE;
4330+
4331+ if (!win)
4332+ return elements;
4333+
4334+ if (!win->isViewable() && wf == WindowFilter::NONE)
4335+ return elements;
4336+
4337+ if (win->wmType() & (CompWindowTypeDockMask | CompWindowTypeDesktopMask))
4338+ return elements;
4339+
4340+ if (win->inShowDesktopMode())
4341+ return elements;
4342+
4343+ auto const& region = win->region();
4344+ bool rectangular = (region.numRects() == 1);
4345+ bool alpha = win->alpha();
4346+
4347+ if (!rectangular && alpha) // Non-rectangular windows with alpha channel
4348+ return elements;
4349+
4350+ if (region.boundingRect() != win->geometry()) // Shaped windows
4351+ return elements;
4352+
4353+ if (rectangular)
4354+ elements |= DecorationElement::SHADOW;
4355+
4356+ if (!win->overrideRedirect() &&
4357+ (win->type() & DECORABLE_WINDOW_TYPES) &&
4358+ (win->frame() || win->hasUnmapReference() || wf == WindowFilter::UNMAPPED))
4359+ {
4360+ if (win->actions() & CompWindowActionResizeMask)
4361+ elements |= DecorationElement::EDGE;
4362+
4363+ if (rectangular && (win->mwmDecor() & (MwmDecorAll | MwmDecorTitle)))
4364+ elements |= DecorationElement::BORDER;
4365+ }
4366+
4367+ if (alpha && !(elements & DecorationElement::BORDER) && !(win->mwmDecor() & MwmDecorBorder))
4368+ elements &= ~DecorationElement::SHADOW;
4369+
4370+ return elements;
4371+}
4372+
4373+bool IsWindowEdgeDecorable(CompWindow* win)
4374+{
4375+ return WindowDecorationElements(win) & DecorationElement::EDGE;
4376+}
4377+
4378 bool IsWindowShadowDecorable(CompWindow* win)
4379 {
4380- if (!win)
4381- return false;
4382-
4383- if (!win->isViewable())
4384- return false;
4385-
4386- if (win->wmType() & (CompWindowTypeDockMask | CompWindowTypeDesktopMask))
4387- return false;
4388-
4389- if (win->region().numRects() != 1) // Non rectangular windows
4390- return false;
4391-
4392- if (win->alpha())
4393- return WindowHasMotifDecorations(win);
4394-
4395- return true;
4396+ return WindowDecorationElements(win) & DecorationElement::SHADOW;
4397 }
4398
4399 bool IsWindowFullyDecorable(CompWindow* win)
4400 {
4401- if (!win)
4402- return false;
4403-
4404- if (!IsWindowShadowDecorable(win))
4405- return false;
4406-
4407- return WindowHasMotifDecorations(win);
4408-}
4409-
4410-bool WindowHasMotifDecorations(CompWindow* win)
4411-{
4412- if (!win)
4413- return false;
4414-
4415- if (win->overrideRedirect())
4416- return false;
4417-
4418- switch (win->type())
4419- {
4420- case CompWindowTypeDialogMask:
4421- case CompWindowTypeModalDialogMask:
4422- case CompWindowTypeUtilMask:
4423- case CompWindowTypeMenuMask:
4424- case CompWindowTypeNormalMask:
4425- if (win->mwmDecor() & (MwmDecorAll | MwmDecorTitle))
4426- return true;
4427- }
4428-
4429- return false;
4430+ return WindowDecorationElements(win) & DecorationElement::BORDER;
4431 }
4432
4433 } // compiz_utils namespace
4434
4435=== modified file 'unity-shared/CompizUtils.h'
4436--- unity-shared/CompizUtils.h 2014-04-14 13:51:58 +0000
4437+++ unity-shared/CompizUtils.h 2014-12-17 12:14:47 +0000
4438@@ -31,8 +31,15 @@
4439
4440 struct TextureQuad
4441 {
4442+ TextureQuad()
4443+ : matrices(1)
4444+ , matrix(matrices[0])
4445+ {}
4446+
4447 CompRect box;
4448- GLTexture::Matrix matrix;
4449+ CompRegion region;
4450+ GLTexture::MatrixList matrices;
4451+ GLTexture::Matrix& matrix;
4452 };
4453
4454 struct SimpleTexture
4455@@ -59,11 +66,13 @@
4456 {
4457 SimpleTextureQuad();
4458 bool SetTexture(SimpleTexture::Ptr const&);
4459- bool SetScale(float scale);
4460+ bool SetScale(double scale);
4461 bool SetCoords(int x, int y);
4462 bool SetX(int x);
4463 bool SetY(int y);
4464
4465+ void UpdateMatrix();
4466+
4467 operator SimpleTexture::Ptr() const { return st; }
4468 operator bool() const { return st && st->texture(); }
4469 operator GLTexture*() const { return st ? st->texture() : nullptr; }
4470@@ -73,8 +82,7 @@
4471 TextureQuad quad;
4472
4473 private:
4474- void UpdateMatrix();
4475- float scale;
4476+ double scale_;
4477 };
4478
4479 struct PixmapTexture : SimpleTexture
4480@@ -111,9 +119,32 @@
4481 cairo_t *cr_;
4482 };
4483
4484+namespace WindowFilter
4485+{
4486+enum Value
4487+{
4488+ NONE,
4489+ UNMAPPED
4490+};
4491+}
4492+
4493+namespace DecorationElement
4494+{
4495+enum
4496+{
4497+ NONE = 0,
4498+ EDGE = (1 << 0),
4499+ SHADOW = (1 << 1),
4500+ BORDER = (1 << 2),
4501+ FULL = EDGE|SHADOW|BORDER
4502+};
4503+}
4504+
4505+unsigned WindowDecorationElements(CompWindow*, WindowFilter::Value wf = WindowFilter::NONE);
4506+
4507+bool IsWindowEdgeDecorable(CompWindow*);
4508 bool IsWindowShadowDecorable(CompWindow*);
4509 bool IsWindowFullyDecorable(CompWindow*);
4510-bool WindowHasMotifDecorations(CompWindow*);
4511
4512 } // compiz_utils namespace
4513 } // unity namespace
4514
4515=== modified file 'unity-shared/DashStyle.cpp'
4516--- unity-shared/DashStyle.cpp 2014-07-24 14:14:47 +0000
4517+++ unity-shared/DashStyle.cpp 2014-12-17 12:14:47 +0000
4518@@ -383,9 +383,9 @@
4519 ::pango_layout_context_changed(layout);
4520
4521 PangoRectangle log_rect;
4522- ::pango_layout_get_extents(layout, NULL, &log_rect);
4523- text_width_ = log_rect.width / PANGO_SCALE;
4524- text_height_ = log_rect.height / PANGO_SCALE;
4525+ ::pango_layout_get_pixel_extents(layout, NULL, &log_rect);
4526+ text_width_ = log_rect.width;
4527+ text_height_ = log_rect.height;
4528
4529 owner_->changed.emit();
4530
4531@@ -1396,10 +1396,10 @@
4532
4533 pango_cairo_context_set_resolution(pangoCtx, 96.0 * Settings::Instance().font_scaling());
4534 pango_layout_context_changed(layout);
4535- pango_layout_get_extents(layout, &inkRect, NULL);
4536+ pango_layout_get_pixel_extents(layout, &inkRect, NULL);
4537
4538- width = inkRect.width / PANGO_SCALE;
4539- height = inkRect.height / PANGO_SCALE;
4540+ width = inkRect.width;
4541+ height = inkRect.height;
4542
4543 // clean up
4544 pango_font_description_free(desc);
4545@@ -1444,11 +1444,8 @@
4546
4547 if (text_size > 0)
4548 {
4549- pango_font_description_set_absolute_size(desc, text_size * PANGO_SCALE);
4550- }
4551- else if (desc)
4552- {
4553- text_size = pango_font_description_get_size(desc) / PANGO_SCALE;
4554+ text_size = pango_units_from_double(Settings::Instance().font_scaling() * text_size);
4555+ pango_font_description_set_absolute_size(desc, text_size);
4556 }
4557
4558 PangoWeight weight;
4559
4560=== modified file 'unity-shared/DecorationStyle.cpp'
4561--- unity-shared/DecorationStyle.cpp 2014-04-02 17:05:04 +0000
4562+++ unity-shared/DecorationStyle.cpp 2014-12-17 12:14:47 +0000
4563@@ -147,8 +147,8 @@
4564 , ctx_(gtk_style_context_new())
4565 , settings_(g_settings_new(SETTINGS_NAME.c_str()))
4566 , usettings_(g_settings_new(UNITY_SETTINGS_NAME.c_str()))
4567- , title_pango_ctx_(gdk_pango_context_get_for_screen(gdk_screen_get_default()))
4568- , menu_item_pango_ctx_(gdk_pango_context_get_for_screen(gdk_screen_get_default()))
4569+ , title_pango_ctx_(gdk_pango_context_get())
4570+ , menu_item_pango_ctx_(gdk_pango_context_get())
4571 , title_alignment_(0)
4572 , title_indent_(0)
4573 , title_fade_(0)
4574
4575=== modified file 'unity-shared/GnomeKeyGrabber.cpp'
4576--- unity-shared/GnomeKeyGrabber.cpp 2014-02-28 18:52:30 +0000
4577+++ unity-shared/GnomeKeyGrabber.cpp 2014-12-17 12:14:47 +0000
4578@@ -200,6 +200,15 @@
4579 CompAction action;
4580 action.keyFromString(accelerator);
4581
4582+ if (action.key().toString().empty())
4583+ {
4584+ CompString prefixed = "XF86" + CompString(accelerator);
4585+ LOG_DEBUG(logger) << "Can't grab \"" << accelerator << "\", trying \"" << prefixed << "\"";
4586+ action.keyFromString(prefixed);
4587+ }
4588+ else
4589+ LOG_DEBUG(logger) << "grabAccelerator \"" << accelerator << "\"";
4590+
4591 if (!isActionPostponed(action))
4592 {
4593 action.setState(CompAction::StateInitKey);
4594
4595=== modified file 'unity-shared/IconRenderer.cpp'
4596--- unity-shared/IconRenderer.cpp 2014-05-08 18:52:16 +0000
4597+++ unity-shared/IconRenderer.cpp 2014-12-17 12:14:47 +0000
4598@@ -31,6 +31,8 @@
4599 #include "unity-shared/CairoTexture.h"
4600 #include "unity-shared/DecorationStyle.h"
4601 #include "unity-shared/TextureCache.h"
4602+#include "unity-shared/UnitySettings.h"
4603+#include "unity-shared/WindowManager.h"
4604 #include "GraphicsUtils.h"
4605
4606 #include <gtk/gtk.h>
4607@@ -199,6 +201,8 @@
4608 const std::array<int, IconSize::SIZE> TILE_SIZES = { 54, 150 };
4609 const std::array<int, IconSize::SIZE> GLOW_SIZES = { 62, 200 };
4610 const std::array<int, IconSize::SIZE> MARKER_SIZES = { 19, 37 };
4611+
4612+constexpr double count_scaling(double icon_size, bool switcher) { return icon_size / (TILE_SIZES[local::IconSize::SMALL] * (switcher ? 2.0 : 1.0)); }
4613 } // anonymous namespace
4614 } // local namespace
4615
4616@@ -210,7 +214,6 @@
4617 return instance;
4618 }
4619
4620- nux::ObjectPtr<nux::BaseTexture> RenderLabelTexture(char label, int icon_size, nux::Color const& bg_color);
4621 nux::ObjectPtr<nux::IOpenGLBaseTexture> offscreen_progress_texture;
4622 nux::ObjectPtr<nux::IOpenGLShaderProgram> shader_program_uv_persp_correction;
4623 #ifndef USE_GLES
4624@@ -224,8 +227,6 @@
4625 int ColorifyColor;
4626 int DesatFactor;
4627
4628- std::map<char, BaseTexturePtr> labels;
4629-
4630 private:
4631 TexturesPool();
4632
4633@@ -249,14 +250,18 @@
4634 LocalTextures(IconRenderer* parent)
4635 : parent_(parent)
4636 {
4637- theme_conn_ = decoration::Style::Get()->theme.changed.connect([this] (std::string const&) {
4638+ connections_.Add(decoration::Style::Get()->theme.changed.connect([this] (std::string const&) {
4639 auto& cache = TextureCache::GetDefault();
4640
4641 for (auto const& tex_data : texture_files_)
4642 cache.Invalidate(tex_data.name, tex_data.size, tex_data.size);
4643
4644 ReloadIconSizedTextures(parent_->icon_size, parent_->image_size);
4645- });
4646+ }));
4647+
4648+ auto clear_labels = sigc::hide(sigc::mem_fun(this, &LocalTextures::ClearLabels));
4649+ connections_.Add(Settings::Instance().font_scaling.changed.connect(clear_labels));
4650+ connections_.Add(WindowManager::Default().average_color.changed.connect(clear_labels));
4651 }
4652
4653 void ReloadIconSizedTextures(int icon_size, int image_size)
4654@@ -298,6 +303,22 @@
4655 *tex_data.tex_ptr = cache.FindTexture(tex_data.name, tex_data.size, tex_data.size, texture_loader);
4656 }
4657
4658+ nux::BaseTexture* RenderLabelTexture(char label, int icon_size, nux::Color const&);
4659+
4660+ BaseTexturePtr const& GetLabelTexture(char label, int icon_size, nux::Color const& color)
4661+ {
4662+ labels_.push_back(TextureCache::GetDefault().FindTexture(std::string(1, label), icon_size, icon_size, [this, &color] (std::string const& label, int size, int) {
4663+ return RenderLabelTexture(label[0], size, color);
4664+ }));
4665+
4666+ return labels_.back();
4667+ }
4668+
4669+ void ClearLabels()
4670+ {
4671+ labels_.clear();
4672+ }
4673+
4674 BaseTexturePtr icon_background;
4675 BaseTexturePtr icon_selected_background;
4676 BaseTexturePtr icon_edge;
4677@@ -315,7 +336,8 @@
4678 IconRenderer* parent_;
4679 struct TextureData { BaseTexturePtr* tex_ptr; std::string name; int size; };
4680 std::vector<TextureData> texture_files_;
4681- connection::Wrapper theme_conn_;
4682+ std::vector<BaseTexturePtr> labels_;
4683+ connection::Manager connections_;
4684 };
4685
4686 IconRenderer::IconRenderer()
4687@@ -335,6 +357,7 @@
4688 icon_size = tile_size;
4689 image_size = image_size_;
4690 local_textures_->ReloadIconSizedTextures(icon_size, image_size);
4691+ local_textures_->ClearLabels();
4692 }
4693
4694 spacing = spacing_;
4695@@ -352,6 +375,7 @@
4696 GetInverseScreenPerspectiveMatrix(ViewMatrix, ProjectionMatrix, geo.width, geo.height, 0.1f, 1000.0f, DEGTORAD(90));
4697
4698 nux::Matrix4 const& PremultMatrix = ProjectionMatrix * ViewMatrix;
4699+ int monitor = this->monitor();
4700
4701 std::list<RenderArg>::iterator it;
4702 int i;
4703@@ -363,6 +387,7 @@
4704 it->logical_center == launcher_icon->LastLogicalCenter(monitor) &&
4705 it->rotation == launcher_icon->LastRotation(monitor) &&
4706 it->skip == launcher_icon->WasSkipping(monitor) &&
4707+ launcher_icon->Count() == launcher_icon->LastCount(monitor) &&
4708 (launcher_icon->Emblem() != nullptr) == launcher_icon->HadEmblem(monitor))
4709 {
4710 continue;
4711@@ -372,6 +397,7 @@
4712 launcher_icon->RememberRotation(monitor, it->rotation);
4713 launcher_icon->RememberSkip(monitor, it->skip);
4714 launcher_icon->RememberEmblem(monitor, launcher_icon->Emblem() != nullptr);
4715+ launcher_icon->RememberCount(monitor, launcher_icon->Count());
4716
4717 float w = icon_size;
4718 float h = icon_size;
4719@@ -423,16 +449,26 @@
4720
4721 UpdateIconTransform(launcher_icon, ViewProjectionMatrix, geo, x, y, w, h, z, ui::IconTextureSource::TRANSFORM_HIT_AREA);
4722
4723- if (launcher_icon->Emblem())
4724- {
4725- nux::BaseTexture* emblem = launcher_icon->Emblem();
4726-
4727+ float emb_w, emb_h;
4728+ nux::BaseTexture* emblem = launcher_icon->Emblem();
4729+
4730+ if (nux::BaseTexture* count_texture = launcher_icon->CountTexture(local::count_scaling(icon_size, pip_style != OUTSIDE_TILE)))
4731+ {
4732+ emblem = count_texture;
4733+ emb_w = emblem->GetWidth();
4734+ emb_h = emblem->GetHeight();
4735+ }
4736+ else if (emblem)
4737+ {
4738+ emb_w = std::round(emblem->GetWidth() * scale());
4739+ emb_h = std::round(emblem->GetHeight() * scale());
4740+ }
4741+
4742+ if (emblem)
4743+ {
4744 float w = icon_size;
4745 float h = icon_size;
4746
4747- float emb_w = emblem->GetWidth();
4748- float emb_h = emblem->GetHeight();
4749-
4750 x = it->render_center.x + (icon_size * 0.50f - emb_w - icon_size * 0.05f); // puts right edge of emblem just over the edge of the launcher icon
4751 y = it->render_center.y - icon_size * 0.50f; // y = top left corner position of emblem
4752 z = it->render_center.z;
4753@@ -718,7 +754,18 @@
4754 tile_transform);
4755 }
4756
4757- if (arg.icon->Emblem())
4758+ if (nux::BaseTexture* count_texture = arg.icon->CountTexture(local::count_scaling(icon_size, pip_style != OUTSIDE_TILE)))
4759+ {
4760+ RenderElement(GfxContext,
4761+ arg,
4762+ count_texture->GetDeviceTexture(),
4763+ nux::color::White,
4764+ nux::color::White,
4765+ arg.alpha,
4766+ force_filter,
4767+ arg.icon->GetTransform(ui::IconTextureSource::TRANSFORM_EMBLEM, monitor));
4768+ }
4769+ else if (arg.icon->Emblem())
4770 {
4771 RenderElement(GfxContext,
4772 arg,
4773@@ -726,7 +773,7 @@
4774 nux::color::White,
4775 nux::color::White,
4776 arg.alpha,
4777- force_filter,
4778+ force_filter || scale != 1.0,
4779 arg.icon->GetTransform(ui::IconTextureSource::TRANSFORM_EMBLEM, monitor));
4780 }
4781
4782@@ -741,20 +788,8 @@
4783 // draw superkey-shortcut label
4784 if (arg.draw_shortcut && arg.shortcut_label)
4785 {
4786- char shortcut = (char) arg.shortcut_label;
4787-
4788- BaseTexturePtr label;
4789- auto label_it = textures_->labels.find(shortcut);
4790-
4791- if (label_it != textures_->labels.end())
4792- {
4793- label = label_it->second;
4794- }
4795- else
4796- {
4797- label = textures_->RenderLabelTexture(shortcut, icon_size, shortcut_color);
4798- textures_->labels[shortcut] = label;
4799- }
4800+ char shortcut = static_cast<char>(arg.shortcut_label);
4801+ auto const& label = local_textures_->GetLabelTexture(shortcut, icon_size, shortcut_color);
4802
4803 RenderElement(GfxContext,
4804 arg,
4805@@ -767,7 +802,7 @@
4806 }
4807 }
4808
4809-nux::ObjectPtr<nux::BaseTexture> IconRenderer::TexturesPool::RenderLabelTexture(char label, int icon_size, nux::Color const& bg_color)
4810+nux::BaseTexture* IconRenderer::LocalTextures::RenderLabelTexture(char label, int icon_size, nux::Color const& bg_color)
4811 {
4812 nux::CairoGraphics cg(CAIRO_FORMAT_ARGB32, icon_size, icon_size);
4813 cairo_t* cr = cg.GetInternalContext();
4814@@ -791,27 +826,27 @@
4815 cairo_set_source_rgba(cr, bg_color.red, bg_color.green, bg_color.blue, 0.20f);
4816 cairo_fill(cr);
4817
4818- const double text_ratio = 0.75;
4819- double text_size = label_size * text_ratio;
4820 glib::Object<PangoLayout> layout(pango_cairo_create_layout(cr));
4821 g_object_get(gtk_settings_get_default(), "gtk-font-name", &font_name, NULL);
4822 std::shared_ptr<PangoFontDescription> desc(pango_font_description_from_string(font_name),
4823 pango_font_description_free);
4824- pango_font_description_set_absolute_size(desc.get(), text_size * PANGO_SCALE);
4825+ const double text_ratio = 0.75;
4826+ int text_size = pango_units_from_double(label_size * text_ratio * Settings::Instance().font_scaling());
4827+ pango_font_description_set_absolute_size(desc.get(), text_size);
4828 pango_layout_set_font_description(layout, desc.get());
4829 pango_layout_set_text(layout, &label, 1);
4830
4831- nux::Size extents;
4832- pango_layout_get_pixel_size(layout, &extents.width, &extents.height);
4833+ PangoRectangle ink_rect;
4834+ pango_layout_get_pixel_extents(layout, &ink_rect, nullptr);
4835
4836 // position and paint text
4837 cairo_set_source_rgba(cr, 1.0f, 1.0f, 1.0f, 1.0f);
4838- double x = label_x - std::round((extents.width - label_w) / 2.0f);
4839- double y = label_y - std::round((extents.height - label_h) / 2.0f);
4840+ double x = label_x - std::round((ink_rect.width - label_w) / 2.0f) - ink_rect.x;
4841+ double y = label_y - std::round((ink_rect.height - label_h) / 2.0f) - ink_rect.y;
4842 cairo_move_to(cr, x, y);
4843 pango_cairo_show_layout(cr, layout);
4844
4845- return texture_ptr_from_cairo_graphics(cg);
4846+ return texture_from_cairo_graphics(cg);
4847 }
4848
4849 void IconRenderer::RenderElement(nux::GraphicsEngine& GfxContext,
4850@@ -1153,11 +1188,6 @@
4851 unity::graphics::PopOffscreenRenderTarget();
4852 }
4853
4854-void IconRenderer::DestroyShortcutTextures()
4855-{
4856- TexturesPool::Get()->labels.clear();
4857-}
4858-
4859 void IconRenderer::GetInverseScreenPerspectiveMatrix(nux::Matrix4& ViewMatrix, nux::Matrix4& PerspectiveMatrix,
4860 int ViewportWidth,
4861 int ViewportHeight,
4862
4863=== modified file 'unity-shared/IconRenderer.h'
4864--- unity-shared/IconRenderer.h 2014-02-27 02:37:18 +0000
4865+++ unity-shared/IconRenderer.h 2014-12-17 12:14:47 +0000
4866@@ -44,8 +44,6 @@
4867
4868 void SetTargetSize(int tile_size, int image_size, int spacing);
4869
4870- static void DestroyShortcutTextures();
4871-
4872 protected:
4873 void RenderElement(nux::GraphicsEngine& GfxContext,
4874 RenderArg const& arg,
4875
4876=== modified file 'unity-shared/IconTexture.cpp'
4877--- unity-shared/IconTexture.cpp 2014-07-24 13:49:53 +0000
4878+++ unity-shared/IconTexture.cpp 2014-12-17 12:14:47 +0000
4879@@ -142,7 +142,7 @@
4880 -1, _size,
4881 sigc::mem_fun(this, &IconTexture::IconLoaded));
4882 }
4883- else if (_icon_name.find("http://") == 0)
4884+ else if (_icon_name.find("://") != std::string::npos)
4885 {
4886 _handle = IconLoader::GetDefault().LoadFromURI(_icon_name,
4887 -1, _size, sigc::mem_fun(this, &IconTexture::IconLoaded));
4888
4889=== modified file 'unity-shared/IconTextureSource.cpp'
4890--- unity-shared/IconTextureSource.cpp 2013-10-04 00:46:07 +0000
4891+++ unity-shared/IconTextureSource.cpp 2014-12-17 12:14:47 +0000
4892@@ -19,6 +19,7 @@
4893
4894 #include "IconTextureSource.h"
4895 #include "MultiMonitor.h"
4896+#include "unity-shared/UnitySettings.h"
4897
4898 namespace unity
4899 {
4900@@ -34,11 +35,16 @@
4901 IconTextureSource::IconTextureSource()
4902 : skip_(RENDERERS_SIZE, false)
4903 , had_emblem_(RENDERERS_SIZE, false)
4904+ , last_count_(RENDERERS_SIZE, 0)
4905 , last_render_center_(RENDERERS_SIZE)
4906 , last_logical_center_(RENDERERS_SIZE)
4907 , last_rotation_(RENDERERS_SIZE)
4908 , transformations_(RENDERERS_SIZE, decltype(transformations_)::value_type(TRANSFORM_SIZE, std::vector<nux::Vector4>(4)))
4909-{}
4910+{
4911+ auto reset_count_cb = sigc::mem_fun(this, &IconTextureSource::ResetLastCount);
4912+ Settings::Instance().dpi_changed.connect(reset_count_cb);
4913+ Settings::Instance().font_scaling.changed.connect(sigc::hide(reset_count_cb));
4914+}
4915
4916 std::vector<nux::Vector4> & IconTextureSource::GetTransform(TransformIndex index, int monitor)
4917 {
4918@@ -91,5 +97,35 @@
4919 return had_emblem_[monitor];
4920 }
4921
4922+void IconTextureSource::RememberCount(int monitor, unsigned count)
4923+{
4924+ last_count_[monitor] = count;
4925+}
4926+
4927+unsigned IconTextureSource::LastCount(int monitor) const
4928+{
4929+ return last_count_[monitor];
4930+}
4931+
4932+unsigned IconTextureSource::Count() const
4933+{
4934+ return 0;
4935+}
4936+
4937+void IconTextureSource::ResetLastCount()
4938+{
4939+ std::fill(last_count_.begin(), last_count_.end(), 0);
4940+}
4941+
4942+nux::BaseTexture* IconTextureSource::Emblem() const
4943+{
4944+ return nullptr;
4945+}
4946+
4947+nux::BaseTexture* IconTextureSource::CountTexture(double scale)
4948+{
4949+ return nullptr;
4950+}
4951+
4952 }
4953 }
4954\ No newline at end of file
4955
4956=== modified file 'unity-shared/IconTextureSource.h'
4957--- unity-shared/IconTextureSource.h 2013-11-06 11:21:43 +0000
4958+++ unity-shared/IconTextureSource.h 2014-12-17 12:14:47 +0000
4959@@ -46,7 +46,7 @@
4960 };
4961
4962 IconTextureSource();
4963- virtual ~IconTextureSource() {}
4964+ virtual ~IconTextureSource() = default;
4965
4966 std::vector<nux::Vector4> & GetTransform(TransformIndex index, int monitor);
4967
4968@@ -62,17 +62,23 @@
4969 void RememberEmblem(int monitor, bool has_emblem);
4970 bool HadEmblem(int monitor) const;
4971
4972+ void RememberCount(int monitor, unsigned count);
4973+ unsigned LastCount(int monitor) const;
4974+
4975 virtual nux::Color BackgroundColor() const = 0;
4976-
4977 virtual nux::Color GlowColor() = 0;
4978-
4979 virtual nux::BaseTexture* TextureForSize(int size) = 0;
4980
4981- virtual nux::BaseTexture* Emblem() = 0;
4982+ virtual unsigned Count() const;
4983+ virtual nux::BaseTexture* CountTexture(double scale);
4984+ virtual nux::BaseTexture* Emblem() const;
4985
4986 private:
4987+ void ResetLastCount();
4988+
4989 std::vector<bool> skip_;
4990 std::vector<bool> had_emblem_;
4991+ std::vector<unsigned> last_count_;
4992 std::vector<nux::Point3> last_render_center_;
4993 std::vector<nux::Point3> last_logical_center_;
4994 std::vector<nux::Vector3> last_rotation_;
4995
4996=== modified file 'unity-shared/LayoutSystem.cpp'
4997--- unity-shared/LayoutSystem.cpp 2014-03-10 13:17:01 +0000
4998+++ unity-shared/LayoutSystem.cpp 2014-12-17 12:14:47 +0000
4999@@ -32,7 +32,33 @@
5000 if (windows.empty())
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches

to all changes:
to status/vote changes: