Merge lp:~3v1n0/unity/lim-everywhere into lp:unity

Proposed by Marco Trevisan (Treviño)
Status: Merged
Approved by: Andrea Azzarone
Approved revision: no longer in the source branch.
Merged at revision: 3920
Proposed branch: lp:~3v1n0/unity/lim-everywhere
Merge into: lp:unity
Diff against target: 5330 lines (+1370/-785)
70 files modified
UnityCore/AppmenuIndicator.cpp (+52/-12)
UnityCore/AppmenuIndicator.h (+4/-3)
UnityCore/CMakeLists.txt (+1/-0)
UnityCore/DBusIndicators.cpp (+52/-40)
UnityCore/GLibDBusServer.cpp (+3/-2)
UnityCore/GLibSource.h (+2/-2)
UnityCore/Indicator.cpp (+15/-30)
UnityCore/Indicator.h (+3/-4)
UnityCore/IndicatorEntry.cpp (+15/-5)
UnityCore/IndicatorEntry.h (+4/-1)
UnityCore/Indicators.cpp (+2/-1)
UnityCore/pch/unitycore_pch.hh (+1/-0)
com.canonical.Unity.gschema.xml (+7/-1)
dash/DashView.h (+1/-1)
dash/ScopeView.h (+2/-1)
debian/control (+1/-1)
decorations/DecoratedWindow.cpp (+13/-9)
decorations/DecorationsManager.cpp (+12/-15)
decorations/DecorationsMenuDropdown.cpp (+4/-3)
decorations/DecorationsMenuEntry.cpp (+12/-2)
decorations/DecorationsMenuEntry.h (+2/-1)
decorations/DecorationsMenuLayout.cpp (+25/-3)
decorations/DecorationsPriv.h (+3/-1)
decorations/DecorationsSlidingLayout.cpp (+1/-1)
decorations/DecorationsWidgets.cpp (+4/-9)
launcher/LauncherEntryRemoteModel.h (+2/-2)
lockscreen/LockScreenPanel.cpp (+1/-1)
panel/PanelIndicatorEntryDropdownView.cpp (+6/-1)
panel/PanelIndicatorEntryDropdownView.h (+1/-0)
panel/PanelIndicatorEntryView.cpp (+7/-5)
panel/PanelIndicatorEntryView.h (+2/-3)
panel/PanelIndicatorsView.cpp (+43/-13)
panel/PanelIndicatorsView.h (+6/-4)
panel/PanelMenuView.cpp (+140/-112)
panel/PanelMenuView.h (+8/-4)
panel/PanelView.cpp (+3/-3)
plugins/unityshell/src/unityshell.cpp (+34/-44)
plugins/unityshell/src/unityshell.h (+2/-1)
services/panel-main.c (+20/-20)
services/panel-service-private.h (+22/-3)
services/panel-service.c (+148/-60)
services/panel-service.h (+0/-8)
shortcuts/ShortcutModel.h (+3/-3)
tests/autopilot/unity/emulators/panel.py (+4/-0)
tests/autopilot/unity/tests/__init__.py (+12/-13)
tests/autopilot/unity/tests/test_dash.py (+2/-2)
tests/autopilot/unity/tests/test_hud.py (+2/-2)
tests/autopilot/unity/tests/test_panel.py (+258/-211)
tests/autopilot/unity/tests/test_wm_keybindings.py (+1/-6)
tests/mock-application.h (+2/-2)
tests/test_dbus_indicators.cpp (+3/-4)
tests/test_indicator.cpp (+18/-21)
tests/test_indicator_appmenu.cpp (+182/-21)
tests/test_indicator_entry.cpp (+17/-14)
tests/test_indicators.cpp (+11/-11)
tests/test_panel_menu_view.cpp (+19/-3)
tests/test_panel_service.cpp (+6/-2)
tests/test_service_panel.cpp (+18/-15)
unity-shared/IconLoader.cpp (+2/-2)
unity-shared/MenuManager.cpp (+64/-9)
unity-shared/NuxObjectPtrHash.h (+36/-0)
unity-shared/PlacesVScrollBar.cpp (+1/-1)
unity-shared/PluginAdapter.cpp (+11/-2)
unity-shared/PluginAdapter.h (+2/-2)
unity-shared/PreviewStyle.cpp (+1/-1)
unity-shared/StandaloneWindowManager.cpp (+1/-0)
unity-shared/UBusWrapper.cpp (+3/-4)
unity-shared/UBusWrapper.h (+2/-2)
unity-shared/UnitySettings.cpp (+2/-0)
unity-shared/UnitySettings.h (+1/-0)
To merge this branch: bzr merge lp:~3v1n0/unity/lim-everywhere
Reviewer Review Type Date Requested Status
Stephen M. Webb (community) Approve
Andrea Azzarone (community) Approve
PS Jenkins bot (community) continuous-integration Approve
Review via email: mp+248359@code.launchpad.net

Commit message

Decorations, Panel: add menus for unfocused windows as well

Now the indicator-appmenu exports the menus for all the windows,
then it's up to us to filter them based on their parent window and
show on relevant place.
Also, set LIM as default now.

Description of the change

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

+1 for me as discussed over irc.

review: Approve
Revision history for this message
Stephen M. Webb (bregma) wrote :

AP tests need fixing, see inline comments.

review: Needs Fixing
Revision history for this message
Marco Trevisan (Treviño) (3v1n0) wrote :

fixed

Revision history for this message
Stephen M. Webb (bregma) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'UnityCore/AppmenuIndicator.cpp'
--- UnityCore/AppmenuIndicator.cpp 2014-12-18 19:30:05 +0000
+++ UnityCore/AppmenuIndicator.cpp 2015-02-19 19:24:14 +0000
@@ -17,41 +17,81 @@
17 * Authored by: Marco Trevisan (Treviño) <3v1n0@ubuntu.com>17 * Authored by: Marco Trevisan (Treviño) <3v1n0@ubuntu.com>
18 */18 */
1919
20#include "GLibSource.h"20#include <unordered_set>
21
21#include "AppmenuIndicator.h"22#include "AppmenuIndicator.h"
23#include "ConnectionManager.h"
2224
23namespace unity25namespace unity
24{26{
25namespace indicator27namespace indicator
26{28{
29namespace
30{
31const Indicator::Entries empty_entries_;
32}
2733
28struct AppmenuIndicator::Impl34struct AppmenuIndicator::Impl
29{35{
30 Impl(AppmenuIndicator* parent)36 Impl(AppmenuIndicator* parent)
31 {37 {
32 // When the active window has changed we might need to emit an updated signal38 connections_.Add(parent->on_entry_added.connect([this] (Entry::Ptr const& entry) {
33 parent->active_window.changed.connect([this, parent] (unsigned long) {39 window_entries_[entry->parent_window()].push_back(entry);
34 update_wait_.reset(new glib::Timeout(250, [parent] {40 }));
35 parent->updated.emit();41
36 return false;42 connections_.Add(parent->on_entry_removed.connect([this] (Entry::Ptr const& entry) {
37 }));43 auto it = window_entries_.find(entry->parent_window());
38 });44
3945 if (it != window_entries_.end())
40 parent->updated.connect([this] { update_wait_.reset(); });46 {
47 auto& entries = it->second;
48 entries.erase(std::remove(entries.begin(), entries.end(), entry), entries.end());
49
50 if (entries.empty())
51 window_entries_.erase(it);
52 }
53 }));
41 }54 }
4255
43 glib::Source::UniquePtr update_wait_;56 connection::Manager connections_;
57 std::unordered_map<uint32_t, Indicator::Entries> window_entries_;
44};58};
4559
46AppmenuIndicator::AppmenuIndicator(std::string const& name)60AppmenuIndicator::AppmenuIndicator(std::string const& name)
47 : Indicator(name)61 : Indicator(name)
48 , active_window(0)
49 , impl_(new AppmenuIndicator::Impl(this))62 , impl_(new AppmenuIndicator::Impl(this))
50{}63{}
5164
52AppmenuIndicator::~AppmenuIndicator()65AppmenuIndicator::~AppmenuIndicator()
53{}66{}
5467
68void AppmenuIndicator::Sync(Indicator::Entries const& entries)
69{
70 std::unordered_set<uint32_t> changed_windows;
71 connection::Wrapper added_conn(on_entry_added.connect([this, &changed_windows] (Entry::Ptr const& entry) {
72 changed_windows.insert(entry->parent_window());
73 }));
74
75 connection::Wrapper rm_conn(on_entry_removed.connect([this, &changed_windows] (Entry::Ptr const& entry) {
76 changed_windows.insert(entry->parent_window());
77 }));
78
79 Indicator::Sync(entries);
80
81 for (uint32_t win : changed_windows)
82 updated_win.emit(win);
83}
84
85Indicator::Entries const& AppmenuIndicator::GetEntriesForWindow(uint32_t parent_window) const
86{
87 auto it = impl_->window_entries_.find(parent_window);
88
89 if (it != impl_->window_entries_.end())
90 return it->second;
91
92 return empty_entries_;
93}
94
55void AppmenuIndicator::ShowAppmenu(unsigned int xid, int x, int y) const95void AppmenuIndicator::ShowAppmenu(unsigned int xid, int x, int y) const
56{96{
57 on_show_appmenu.emit(xid, x, y);97 on_show_appmenu.emit(xid, x, y);
5898
=== modified file 'UnityCore/AppmenuIndicator.h'
--- UnityCore/AppmenuIndicator.h 2014-12-18 18:46:29 +0000
+++ UnityCore/AppmenuIndicator.h 2015-02-19 19:24:14 +0000
@@ -36,12 +36,13 @@
36 AppmenuIndicator(std::string const& name);36 AppmenuIndicator(std::string const& name);
37 ~AppmenuIndicator();37 ~AppmenuIndicator();
3838
39 nux::Property<unsigned> active_window;39 bool IsAppmenu() const override { return true; }
4040 void Sync(Entries const&) override;
41 virtual bool IsAppmenu() const { return true; }41 Entries const& GetEntriesForWindow(uint32_t parent_window) const;
4242
43 void ShowAppmenu(unsigned xid, int x, int y) const;43 void ShowAppmenu(unsigned xid, int x, int y) const;
4444
45 sigc::signal<void, uint32_t> updated_win;
45 sigc::signal<void, unsigned, int, int> on_show_appmenu;46 sigc::signal<void, unsigned, int, int> on_show_appmenu;
4647
47private:48private:
4849
=== modified file 'UnityCore/CMakeLists.txt'
--- UnityCore/CMakeLists.txt 2014-02-05 11:38:22 +0000
+++ UnityCore/CMakeLists.txt 2015-02-19 19:24:14 +0000
@@ -117,6 +117,7 @@
117#117#
118include_directories(${CORE_DEPS_INCLUDE_DIRS})118include_directories(${CORE_DEPS_INCLUDE_DIRS})
119include_directories(${CMAKE_BINARY_DIR})119include_directories(${CMAKE_BINARY_DIR})
120include_directories(..)
120121
121set (LIBS ${CORE_DEPS_LDFLAGS} ${PRIVATE_CORE_DEPS_LDFLAGS})122set (LIBS ${CORE_DEPS_LDFLAGS} ${PRIVATE_CORE_DEPS_LDFLAGS})
122123
123124
=== modified file 'UnityCore/DBusIndicators.cpp'
--- UnityCore/DBusIndicators.cpp 2014-09-19 18:48:04 +0000
+++ UnityCore/DBusIndicators.cpp 2015-02-19 19:24:14 +0000
@@ -27,19 +27,29 @@
27#include "GLibSource.h"27#include "GLibSource.h"
28#include "Variant.h"28#include "Variant.h"
29#include "DBusIndicators.h"29#include "DBusIndicators.h"
30#include "services/panel-service-private.h"
3031
31namespace unity32namespace unity
32{33{
33namespace indicator34namespace indicator
34{35{
36
37namespace
38{
35DECLARE_LOGGER(logger, "unity.indicator.dbus");39DECLARE_LOGGER(logger, "unity.indicator.dbus");
3640
37namespace41inline bool verify_variant_type(GVariant* value, const gchar* type)
38{42{
39const std::string SERVICE_NAME_DESKTOP("com.canonical.Unity.Panel.Service.Desktop");43 if (!g_variant_is_of_type (value, G_VARIANT_TYPE(type)))
40const std::string SERVICE_NAME_LOCKSCREEN("com.canonical.Unity.Panel.Service.LockScreen");44 {
41const std::string SERVICE_PATH("/com/canonical/Unity/Panel/Service");45 LOG_ERROR(logger) << "Got invalid variant type: '"
42const std::string SERVICE_IFACE("com.canonical.Unity.Panel.Service");46 << g_variant_get_type_string(value) << "' ('"
47 << type << "' was expected)";
48 return false;
49 }
50
51 return true;
52}
43} // anonymous namespace53} // anonymous namespace
4454
4555
@@ -78,15 +88,15 @@
78 glib::Source::UniquePtr show_entry_idle_;88 glib::Source::UniquePtr show_entry_idle_;
79 glib::Source::UniquePtr show_appmenu_idle_;89 glib::Source::UniquePtr show_appmenu_idle_;
80 std::vector<std::string> icon_paths_;90 std::vector<std::string> icon_paths_;
81 std::map<std::string, EntryLocationMap> cached_locations_;91 std::unordered_map<std::string, EntryLocationMap> cached_locations_;
82};92};
8393
8494
85// Public Methods95// Public Methods
86DBusIndicators::Impl::Impl(std::string const& dbus_name, DBusIndicators* owner)96DBusIndicators::Impl::Impl(std::string const& dbus_name, DBusIndicators* owner)
87 : owner_(owner)97 : owner_(owner)
88 , gproxy_(dbus_name, SERVICE_PATH, SERVICE_IFACE,98 , gproxy_(dbus_name, UPS_PATH, UPS_IFACE, G_BUS_TYPE_SESSION,
89 G_BUS_TYPE_SESSION, G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES)99 G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES)
90{100{
91 gproxy_.Connect("ReSync", sigc::mem_fun(this, &DBusIndicators::Impl::OnReSync));101 gproxy_.Connect("ReSync", sigc::mem_fun(this, &DBusIndicators::Impl::OnReSync));
92 gproxy_.Connect("IconPathsChanged", sigc::mem_fun(this, &DBusIndicators::Impl::OnIconsPathChanged));102 gproxy_.Connect("IconPathsChanged", sigc::mem_fun(this, &DBusIndicators::Impl::OnIconsPathChanged));
@@ -208,6 +218,9 @@
208218
209void DBusIndicators::Impl::OnEntryActivated(GVariant* parameters)219void DBusIndicators::Impl::OnEntryActivated(GVariant* parameters)
210{220{
221 if (!verify_variant_type(parameters, "(ss(iiuu))"))
222 return;
223
211 glib::String panel;224 glib::String panel;
212 glib::String entry_id;225 glib::String entry_id;
213 nux::Rect geo;226 nux::Rect geo;
@@ -219,6 +232,9 @@
219232
220void DBusIndicators::Impl::OnEntryActivatedRequest(GVariant* parameters)233void DBusIndicators::Impl::OnEntryActivatedRequest(GVariant* parameters)
221{234{
235 if (!verify_variant_type(parameters, "(s)"))
236 return;
237
222 glib::String entry_name;238 glib::String entry_name;
223 g_variant_get(parameters, "(s)", &entry_name);239 g_variant_get(parameters, "(s)", &entry_name);
224240
@@ -228,6 +244,9 @@
228244
229void DBusIndicators::Impl::OnEntryShowNowChanged(GVariant* parameters)245void DBusIndicators::Impl::OnEntryShowNowChanged(GVariant* parameters)
230{246{
247 if (!verify_variant_type(parameters, "(sb)"))
248 return;
249
231 glib::String entry_name;250 glib::String entry_name;
232 gboolean show_now;251 gboolean show_now;
233 g_variant_get(parameters, "(sb)", &entry_name, &show_now);252 g_variant_get(parameters, "(sb)", &entry_name, &show_now);
@@ -325,9 +344,10 @@
325 return;344 return;
326345
327 GVariantIter* iter = nullptr;346 GVariantIter* iter = nullptr;
328 gchar* name_hint = nullptr;
329 gchar* indicator_id = nullptr;347 gchar* indicator_id = nullptr;
330 gchar* entry_id = nullptr;348 gchar* entry_id = nullptr;
349 gchar* name_hint = nullptr;
350 guint32 parent_window = 0;
331 gchar* label = nullptr;351 gchar* label = nullptr;
332 gboolean label_sensitive = false;352 gboolean label_sensitive = false;
333 gboolean label_visible = false;353 gboolean label_visible = false;
@@ -337,15 +357,17 @@
337 gboolean image_visible = false;357 gboolean image_visible = false;
338 gint32 priority = -1;358 gint32 priority = -1;
339359
340 std::map<Indicator::Ptr, Indicator::Entries> indicators;360 if (!verify_variant_type(args, "(" ENTRY_ARRAY_SIGNATURE ")"))
341 int wanted_idx = 0;361 return;
342 bool any_different_idx = false;362
343363 std::unordered_map<Indicator::Ptr, Indicator::Entries> indicators;
344 g_variant_get(args, "(a(ssssbbusbbi))", &iter);364
345 while (g_variant_iter_loop(iter, "(ssssbbusbbi)",365 g_variant_get(args, "(" ENTRY_ARRAY_SIGNATURE ")", &iter);
366 while (g_variant_iter_loop(iter, ENTRY_SIGNATURE,
346 &indicator_id,367 &indicator_id,
347 &entry_id,368 &entry_id,
348 &name_hint,369 &name_hint,
370 &parent_window,
349 &label,371 &label,
350 &label_sensitive,372 &label_sensitive,
351 &label_visible,373 &label_visible,
@@ -369,27 +391,20 @@
369 // Empty entries are empty indicators.391 // Empty entries are empty indicators.
370 if (!entry.empty())392 if (!entry.empty())
371 {393 {
372 Entry::Ptr e;394 Entry::Ptr e = indicator->GetEntry(entry_id);
373 if (!any_different_idx)395 int old_priority = e ? e->priority() : -1;
374 {396
375 // Indicators can only add or remove entries, so if397 // Indicators can only add or remove entries, so if
376 // there is a index change we can't reuse the existing ones398 // there is a priority change we can't reuse the existing ones
377 // after that index399 if (old_priority != priority)
378 if (indicator->EntryIndex(entry_id) == wanted_idx)400 e.reset();
379 {
380 e = indicator->GetEntry(entry_id);
381 }
382 else
383 {
384 any_different_idx = true;
385 }
386 }
387401
388 if (!e)402 if (!e)
389 {403 {
390 e = std::make_shared<Entry>(entry, name_hint, label, label_sensitive,404 e = std::make_shared<Entry>(entry, name_hint, parent_window,
391 label_visible, image_type, image_data,405 label, label_sensitive, label_visible,
392 image_sensitive, image_visible, priority);406 image_type, image_data, image_sensitive, image_visible,
407 priority);
393 }408 }
394 else409 else
395 {410 {
@@ -399,15 +414,12 @@
399 }414 }
400415
401 entries.push_back(e);416 entries.push_back(e);
402 ++wanted_idx;
403 }417 }
404 }418 }
405 g_variant_iter_free(iter);419 g_variant_iter_free(iter);
406420
407 for (auto i = indicators.begin(), end = indicators.end(); i != end; ++i)421 for (auto const& i : indicators)
408 {422 i.first->Sync(i.second);
409 i->first->Sync(indicators[i->first]);
410 }
411}423}
412424
413void DBusIndicators::Impl::SyncGeometries(std::string const& name,425void DBusIndicators::Impl::SyncGeometries(std::string const& name,
@@ -463,7 +475,7 @@
463}475}
464476
465DBusIndicators::DBusIndicators()477DBusIndicators::DBusIndicators()
466 : pimpl(new Impl(SERVICE_NAME_DESKTOP, this))478 : pimpl(new Impl(UPS_NAME_DESKTOP, this))
467{}479{}
468480
469DBusIndicators::DBusIndicators(std::string const& dbus_name)481DBusIndicators::DBusIndicators(std::string const& dbus_name)
@@ -471,7 +483,7 @@
471{}483{}
472484
473LockScreenDBusIndicators::LockScreenDBusIndicators()485LockScreenDBusIndicators::LockScreenDBusIndicators()
474 : DBusIndicators(SERVICE_NAME_LOCKSCREEN)486 : DBusIndicators(UPS_NAME_LOCKSCREEN)
475{}487{}
476488
477DBusIndicators::~DBusIndicators()489DBusIndicators::~DBusIndicators()
478490
=== modified file 'UnityCore/GLibDBusServer.cpp'
--- UnityCore/GLibDBusServer.cpp 2014-04-09 13:19:33 +0000
+++ UnityCore/GLibDBusServer.cpp 2015-02-19 19:24:14 +0000
@@ -17,6 +17,7 @@
17* Authored by: Marco Trevisan (Treviño) <marco.trevisan@canonical.com>17* Authored by: Marco Trevisan (Treviño) <marco.trevisan@canonical.com>
18*/18*/
1919
20#include <unordered_map>
20#include <NuxCore/Logger.h>21#include <NuxCore/Logger.h>
2122
22#include "GLibDBusServer.h"23#include "GLibDBusServer.h"
@@ -406,8 +407,8 @@
406407
407 GDBusInterfaceVTable interface_vtable_;408 GDBusInterfaceVTable interface_vtable_;
408 std::shared_ptr<GDBusInterfaceInfo> interface_info_;409 std::shared_ptr<GDBusInterfaceInfo> interface_info_;
409 std::map<guint, std::string> registrations_;410 std::unordered_map<guint, std::string> registrations_;
410 std::map<std::string, glib::Object<GDBusConnection>> connection_by_path_;411 std::unordered_map<std::string, glib::Object<GDBusConnection>> connection_by_path_;
411};412};
412413
413DBusObject::DBusObject(std::string const& introspection_xml, std::string const& interface_name)414DBusObject::DBusObject(std::string const& introspection_xml, std::string const& interface_name)
414415
=== modified file 'UnityCore/GLibSource.h'
--- UnityCore/GLibSource.h 2013-10-10 09:47:24 +0000
+++ UnityCore/GLibSource.h 2015-02-19 19:24:14 +0000
@@ -24,7 +24,7 @@
24#include <sigc++/sigc++.h>24#include <sigc++/sigc++.h>
25#include <glib.h>25#include <glib.h>
26#include <memory>26#include <memory>
27#include <map>27#include <unordered_map>
2828
29namespace unity29namespace unity
30{30{
@@ -223,7 +223,7 @@
223 Source::Ptr GetSource(unsigned int id) const;223 Source::Ptr GetSource(unsigned int id) const;
224224
225protected: // For testing purposes225protected: // For testing purposes
226 typedef std::map<std::string, Source::Ptr> SourcesMap;226 typedef std::unordered_map<std::string, Source::Ptr> SourcesMap;
227 SourcesMap sources_;227 SourcesMap sources_;
228228
229private:229private:
230230
=== modified file 'UnityCore/Indicator.cpp'
--- UnityCore/Indicator.cpp 2014-01-27 17:31:30 +0000
+++ UnityCore/Indicator.cpp 2015-02-19 19:24:14 +0000
@@ -36,7 +36,7 @@
36Indicator::~Indicator()36Indicator::~Indicator()
37{37{
38 for (auto const& entry : entries_)38 for (auto const& entry : entries_)
39 on_entry_removed.emit(entry->id());39 on_entry_removed.emit(entry);
40}40}
4141
42std::string const& Indicator::name() const42std::string const& Indicator::name() const
@@ -51,23 +51,23 @@
5151
52void Indicator::Sync(Indicator::Entries const& new_entries)52void Indicator::Sync(Indicator::Entries const& new_entries)
53{53{
54 bool added = false;54 bool changed = false;
55 Entries to_rm;
5655
57 if (!entries_.empty())56 for (auto it = entries_.begin(); it != entries_.end();)
58 {57 {
59 for (auto const& entry : entries_)58 auto entry = *it;
59
60 if (std::find(new_entries.begin(), new_entries.end(), entry) == new_entries.end())
60 {61 {
61 if (std::find(new_entries.begin(), new_entries.end(), entry) == new_entries.end())62 auto entry_id = entry->id();
62 to_rm.push_back(entry);63 entries_connections_.erase(entry);
64 it = entries_.erase(it);
65 on_entry_removed.emit(entry);
66 changed = true;
67 continue;
63 }68 }
64 }
6569
66 for (auto const& entry : to_rm)70 ++it;
67 {
68 entries_connections_.erase(entry);
69 on_entry_removed.emit(entry->id());
70 entries_.remove(entry);
71 }71 }
7272
73 for (auto const& new_entry : new_entries)73 for (auto const& new_entry : new_entries)
@@ -93,10 +93,10 @@
93 entries_.push_back(new_entry);93 entries_.push_back(new_entry);
94 on_entry_added.emit(new_entry);94 on_entry_added.emit(new_entry);
9595
96 added = true;96 changed = true;
97 }97 }
9898
99 if (!to_rm.empty() || added)99 if (changed)
100 updated.emit();100 updated.emit();
101}101}
102102
@@ -109,21 +109,6 @@
109 return Entry::Ptr();109 return Entry::Ptr();
110}110}
111111
112int Indicator::EntryIndex(std::string const& entry_id) const
113{
114 int i = 0;
115 for (auto const& entry : entries_)
116 {
117 if (entry->id() == entry_id)
118 {
119 return i;
120 }
121 ++i;
122 }
123
124 return -1;
125}
126
127std::ostream& operator<<(std::ostream& out, Indicator const& i)112std::ostream& operator<<(std::ostream& out, Indicator const& i)
128{113{
129 out << "<Indicator " << i.name() << std::endl;114 out << "<Indicator " << i.name() << std::endl;
130115
=== modified file 'UnityCore/Indicator.h'
--- UnityCore/Indicator.h 2014-02-05 17:16:41 +0000
+++ UnityCore/Indicator.h 2015-02-19 19:24:14 +0000
@@ -38,7 +38,7 @@
38{38{
39public:39public:
40 typedef std::shared_ptr<Indicator> Ptr;40 typedef std::shared_ptr<Indicator> Ptr;
41 typedef std::list<Entry::Ptr> Entries;41 typedef std::vector<Entry::Ptr> Entries;
4242
43 Indicator(std::string const& name);43 Indicator(std::string const& name);
44 virtual ~Indicator();44 virtual ~Indicator();
@@ -47,15 +47,14 @@
4747
48 virtual bool IsAppmenu() const { return false; }48 virtual bool IsAppmenu() const { return false; }
4949
50 void Sync(Entries const& new_entries);50 virtual void Sync(Entries const&);
51 Entry::Ptr GetEntry(std::string const& entry_id) const;51 Entry::Ptr GetEntry(std::string const& entry_id) const;
52 int EntryIndex(std::string const& entry_id) const;
53 Entries const& GetEntries() const;52 Entries const& GetEntries() const;
5453
55 // Signals54 // Signals
56 sigc::signal<void> updated;55 sigc::signal<void> updated;
57 sigc::signal<void, Entry::Ptr const&> on_entry_added;56 sigc::signal<void, Entry::Ptr const&> on_entry_added;
58 sigc::signal<void, std::string const&> on_entry_removed;57 sigc::signal<void, Entry::Ptr const&> on_entry_removed;
59 sigc::signal<void, std::string const&, unsigned, int, int, unsigned> on_show_menu;58 sigc::signal<void, std::string const&, unsigned, int, int, unsigned> on_show_menu;
60 sigc::signal<void, std::string const&> on_secondary_activate;59 sigc::signal<void, std::string const&> on_secondary_activate;
61 sigc::signal<void, std::string const&, int> on_scroll;60 sigc::signal<void, std::string const&, int> on_scroll;
6261
=== modified file 'UnityCore/IndicatorEntry.cpp'
--- UnityCore/IndicatorEntry.cpp 2014-02-07 23:54:15 +0000
+++ UnityCore/IndicatorEntry.cpp 2015-02-19 19:24:14 +0000
@@ -30,6 +30,7 @@
3030
31Entry::Entry(std::string const& id,31Entry::Entry(std::string const& id,
32 std::string const& name_hint,32 std::string const& name_hint,
33 uint32_t parent_window,
33 std::string const& label,34 std::string const& label,
34 bool label_sensitive,35 bool label_sensitive,
35 bool label_visible,36 bool label_visible,
@@ -40,6 +41,7 @@
40 int priority)41 int priority)
41 : id_(id)42 : id_(id)
42 , name_hint_(name_hint)43 , name_hint_(name_hint)
44 , parent_window_(parent_window)
43 , label_(label)45 , label_(label)
44 , label_visible_(label_visible)46 , label_visible_(label_visible)
45 , label_sensitive_(label_sensitive)47 , label_sensitive_(label_sensitive)
@@ -52,9 +54,10 @@
52 , active_(false)54 , active_(false)
53{}55{}
5456
55Entry::Entry(std::string const& id, std::string const& name_hint)57Entry::Entry(std::string const& id, std::string const& name_hint, uint32_t parent_window)
56 : id_(id)58 : id_(id)
57 , name_hint_(name_hint)59 , name_hint_(name_hint)
60 , parent_window_(parent_window)
58 , label_visible_(false)61 , label_visible_(false)
59 , label_sensitive_(false)62 , label_sensitive_(false)
60 , image_type_(0)63 , image_type_(0)
@@ -65,14 +68,19 @@
65 , active_(false)68 , active_(false)
66{}69{}
6770
71std::string const& Entry::id() const
72{
73 return id_;
74}
75
68std::string const& Entry::name_hint() const76std::string const& Entry::name_hint() const
69{77{
70 return name_hint_;78 return name_hint_;
71}79}
7280
73std::string const& Entry::id() const81uint32_t Entry::parent_window() const
74{82{
75 return id_;83 return parent_window_;
76}84}
7785
78std::string const& Entry::label() const86std::string const& Entry::label() const
@@ -199,6 +207,7 @@
199207
200 id_ = rhs.id_;208 id_ = rhs.id_;
201 name_hint_ = rhs.name_hint_;209 name_hint_ = rhs.name_hint_;
210 parent_window_ = rhs.parent_window_;
202 label_ = rhs.label_;211 label_ = rhs.label_;
203 label_sensitive_ = rhs.label_sensitive_;212 label_sensitive_ = rhs.label_sensitive_;
204 label_visible_ = rhs.label_visible_;213 label_visible_ = rhs.label_visible_;
@@ -258,7 +267,7 @@
258267
259void Entry::ShowMenu(int x, int y, unsigned button)268void Entry::ShowMenu(int x, int y, unsigned button)
260{269{
261 ShowMenu(0, x, y, button);270 ShowMenu(parent_window_, x, y, button);
262}271}
263272
264void Entry::ShowMenu(unsigned int xid, int x, int y, unsigned button)273void Entry::ShowMenu(unsigned int xid, int x, int y, unsigned button)
@@ -278,7 +287,8 @@
278287
279std::ostream& operator<<(std::ostream& out, Entry const& e)288std::ostream& operator<<(std::ostream& out, Entry const& e)
280{289{
281 out << "<indicator::Entry " << e.id() << " hint: '" << e.name_hint() << "' "290 out << "<indicator::Entry " << e.id() << " hint: '" << e.name_hint() << "'"
291 << " parent window: " << e.parent_window()
282 << std::boolalpha292 << std::boolalpha
283 << " \"" << e.label() << "\" ("293 << " \"" << e.label() << "\" ("
284 << e.label_sensitive() << ", " << e.label_visible() << ") image ("294 << e.label_sensitive() << ", " << e.label_visible() << ") image ("
285295
=== modified file 'UnityCore/IndicatorEntry.h'
--- UnityCore/IndicatorEntry.h 2014-02-05 17:16:41 +0000
+++ UnityCore/IndicatorEntry.h 2015-02-19 19:24:14 +0000
@@ -44,9 +44,10 @@
44public:44public:
45 typedef std::shared_ptr<Entry> Ptr;45 typedef std::shared_ptr<Entry> Ptr;
4646
47 Entry(std::string const& id, std::string const& name_hint = "");47 Entry(std::string const& id, std::string const& name_hint = "", uint32_t parent_window = 0);
48 Entry(std::string const& id,48 Entry(std::string const& id,
49 std::string const& name_hint,49 std::string const& name_hint,
50 uint32_t parent_window,
50 std::string const& label,51 std::string const& label,
51 bool label_sensitive,52 bool label_sensitive,
52 bool label_visible,53 bool label_visible,
@@ -61,6 +62,7 @@
6162
62 std::string const& id() const;63 std::string const& id() const;
63 std::string const& name_hint() const;64 std::string const& name_hint() const;
65 uint32_t parent_window() const;
6466
65 void set_image(int type, std::string const& data, bool sensitive, bool visible);67 void set_image(int type, std::string const& data, bool sensitive, bool visible);
66 bool image_visible() const;68 bool image_visible() const;
@@ -114,6 +116,7 @@
114private:116private:
115 std::string id_;117 std::string id_;
116 std::string name_hint_;118 std::string name_hint_;
119 uint32_t parent_window_;
117120
118 std::string label_;121 std::string label_;
119 bool label_visible_;122 bool label_visible_;
120123
=== modified file 'UnityCore/Indicators.cpp'
--- UnityCore/Indicators.cpp 2014-02-11 03:11:47 +0000
+++ UnityCore/Indicators.cpp 2015-02-19 19:24:14 +0000
@@ -20,6 +20,7 @@
2020
21#include "Indicators.h"21#include "Indicators.h"
22#include "AppmenuIndicator.h"22#include "AppmenuIndicator.h"
23#include "services/panel-service-private.h"
2324
24namespace unity25namespace unity
25{26{
@@ -143,7 +144,7 @@
143 if (indicator)144 if (indicator)
144 return indicator;145 return indicator;
145146
146 if (name == "libappmenu.so")147 if (name == APPMENU_INDICATOR_NAME)
147 {148 {
148 auto appmenu = std::make_shared<AppmenuIndicator>(name);149 auto appmenu = std::make_shared<AppmenuIndicator>(name);
149 appmenu->on_show_appmenu.connect(sigc::mem_fun(owner_, &Indicators::OnShowAppMenu));150 appmenu->on_show_appmenu.connect(sigc::mem_fun(owner_, &Indicators::OnShowAppMenu));
150151
=== modified file 'UnityCore/pch/unitycore_pch.hh'
--- UnityCore/pch/unitycore_pch.hh 2014-01-28 15:39:57 +0000
+++ UnityCore/pch/unitycore_pch.hh 2015-02-19 19:24:14 +0000
@@ -29,6 +29,7 @@
29#include <map>29#include <map>
30#include <memory>30#include <memory>
31#include <unordered_map>31#include <unordered_map>
32#include <functional>
3233
33#include <boost/utility.hpp>34#include <boost/utility.hpp>
34#include <dee.h>35#include <dee.h>
3536
=== modified file 'com.canonical.Unity.gschema.xml'
--- com.canonical.Unity.gschema.xml 2014-12-19 12:43:56 +0000
+++ com.canonical.Unity.gschema.xml 2015-02-19 19:24:14 +0000
@@ -47,7 +47,7 @@
47 <description>This is used to enable/disable double-click result activation in the dash. Double-click to activate, single click preview</description>47 <description>This is used to enable/disable double-click result activation in the dash. Double-click to activate, single click preview</description>
48 </key>48 </key>
49 <key type="b" name="integrated-menus">49 <key type="b" name="integrated-menus">
50 <default>false</default>50 <default>true</default>
51 <summary>Enable/Disable the integrated menus in Unity.</summary>51 <summary>Enable/Disable the integrated menus in Unity.</summary>
52 <description>When this is enabled, the application menus will be shown52 <description>When this is enabled, the application menus will be shown
53 on the window decoration, otherwise they will be always shown on the53 on the window decoration, otherwise they will be always shown on the
@@ -176,5 +176,11 @@
176 a window by double-clicking on its menus if the second click happens before the176 a window by double-clicking on its menus if the second click happens before the
177 specified value of ms is elapsed</description>177 specified value of ms is elapsed</description>
178 </key>178 </key>
179 <key type="b" name="unfocused-windows-popup">
180 <default>true</default>
181 <summary>Whether to pop-up a menu when clicking over unfocused windows entries</summary>
182 <description>By disabling this setting you can make unity to only focus a window
183 when clicking over unfocused menu entries</description>
184 </key>
179 </schema>185 </schema>
180</schemalist>186</schemalist>
181187
=== modified file 'dash/DashView.h'
--- dash/DashView.h 2014-07-07 13:16:18 +0000
+++ dash/DashView.h 2015-02-19 19:24:14 +0000
@@ -56,7 +56,7 @@
56class DashView : public nux::View, public unity::debug::Introspectable56class DashView : public nux::View, public unity::debug::Introspectable
57{57{
58 NUX_DECLARE_OBJECT_TYPE(DashView, nux::View);58 NUX_DECLARE_OBJECT_TYPE(DashView, nux::View);
59 typedef std::map<std::string, nux::ObjectPtr<ScopeView>> ScopeViews;59 typedef std::unordered_map<std::string, nux::ObjectPtr<ScopeView>> ScopeViews;
6060
61public:61public:
62 DashView(Scopes::Ptr const& scopes, ApplicationStarter::Ptr const& application_starter);62 DashView(Scopes::Ptr const& scopes, ApplicationStarter::Ptr const& application_starter);
6363
=== modified file 'dash/ScopeView.h'
--- dash/ScopeView.h 2014-07-11 20:53:25 +0000
+++ dash/ScopeView.h 2015-02-19 19:24:14 +0000
@@ -35,6 +35,7 @@
35#include "unity-shared/Introspectable.h"35#include "unity-shared/Introspectable.h"
36#include "PlacesGroup.h"36#include "PlacesGroup.h"
37#include "ResultViewGrid.h"37#include "ResultViewGrid.h"
38#include "unity-shared/NuxObjectPtrHash.h"
38#include "unity-shared/UBusWrapper.h"39#include "unity-shared/UBusWrapper.h"
3940
40namespace unity41namespace unity
@@ -48,7 +49,7 @@
48{49{
49 NUX_DECLARE_OBJECT_TYPE(ScopeView, nux::View);50 NUX_DECLARE_OBJECT_TYPE(ScopeView, nux::View);
50 typedef std::vector<PlacesGroup::Ptr> CategoryGroups;51 typedef std::vector<PlacesGroup::Ptr> CategoryGroups;
51 typedef std::map<PlacesGroup::Ptr, unsigned int> ResultCounts;52 typedef std::unordered_map<PlacesGroup::Ptr, unsigned int> ResultCounts;
5253
53public:54public:
54 ScopeView(Scope::Ptr const& scope, nux::Area* show_filters);55 ScopeView(Scope::Ptr const& scope, nux::Area* show_filters);
5556
=== modified file 'debian/control'
--- debian/control 2014-11-04 18:57:33 +0000
+++ debian/control 2015-02-19 19:24:14 +0000
@@ -80,7 +80,7 @@
80Provides: indicator-renderer80Provides: indicator-renderer
81Recommends: unity-control-center,81Recommends: unity-control-center,
82 ${unity-default-masterscopes}82 ${unity-default-masterscopes}
83 indicator-appmenu,83 indicator-appmenu (>= 15.02.0),
84 indicator-application,84 indicator-application,
85 indicator-sound,85 indicator-sound,
86 indicator-bluetooth,86 indicator-bluetooth,
8787
=== modified file 'decorations/DecoratedWindow.cpp'
--- decorations/DecoratedWindow.cpp 2014-12-19 13:03:44 +0000
+++ decorations/DecoratedWindow.cpp 2015-02-19 19:24:14 +0000
@@ -50,17 +50,13 @@
50 , deco_elements_(cu::DecorationElement::NONE)50 , deco_elements_(cu::DecorationElement::NONE)
51 , last_mwm_decor_(win_->mwmDecor())51 , last_mwm_decor_(win_->mwmDecor())
52 , last_actions_(win_->actions())52 , last_actions_(win_->actions())
53 , panel_id_(MENUS_PANEL_NAME + std::to_string(win_->id()))
53 , cv_(Settings::Instance().em())54 , cv_(Settings::Instance().em())
54{55{
55 active.changed.connect([this] (bool active) {56 active.changed.connect([this] (bool active) {
56 bg_textures_.clear();57 bg_textures_.clear();
57 if (top_layout_)58 if (top_layout_)
58 {
59 top_layout_->focused = active;59 top_layout_->focused = active;
60
61 if (!active)
62 UnsetAppMenu();
63 }
64 RedrawDecorations();60 RedrawDecorations();
65 });61 });
6662
@@ -701,7 +697,7 @@
701697
702void Window::Impl::SetupAppMenu()698void Window::Impl::SetupAppMenu()
703{699{
704 if (!active() || !top_layout_)700 if (!top_layout_)
705 return;701 return;
706702
707 auto const& menu_manager = manager_->impl_->menu_manager_;703 auto const& menu_manager = manager_->impl_->menu_manager_;
@@ -716,8 +712,11 @@
716712
717 auto menus = std::make_shared<MenuLayout>(menu_manager, win_);713 auto menus = std::make_shared<MenuLayout>(menu_manager, win_);
718 menus->Setup();714 menus->Setup();
715
716 if (menus->Items().empty())
717 return;
718
719 menus_ = menus;719 menus_ = menus;
720
721 auto const& grab_edge = grab_edge_.lock();720 auto const& grab_edge = grab_edge_.lock();
722 sliding_layout->SetInputItem(menus);721 sliding_layout->SetInputItem(menus);
723 sliding_layout->fadein = menu_manager->fadein();722 sliding_layout->fadein = menu_manager->fadein();
@@ -759,13 +758,18 @@
759 sliding_layout->mouse_owner = grab_edge_->mouse_owner();758 sliding_layout->mouse_owner = grab_edge_->mouse_owner();
760}759}
761760
761inline std::string const& Window::Impl::GetMenusPanelID() const
762{
763 return panel_id_;
764}
765
762void Window::Impl::UnsetAppMenu()766void Window::Impl::UnsetAppMenu()
763{767{
764 if (!menus_)768 if (!menus_)
765 return;769 return;
766770
767 auto const& indicators = manager_->impl_->menu_manager_->Indicators();771 auto const& indicators = manager_->impl_->menu_manager_->Indicators();
768 indicators->SyncGeometries(MENUS_PANEL_NAME, indicator::EntryLocationMap());772 indicators->SyncGeometries(GetMenusPanelID(), indicator::EntryLocationMap());
769 sliding_layout_->SetInputItem(nullptr);773 sliding_layout_->SetInputItem(nullptr);
770 grab_mouse_changed_->disconnect();774 grab_mouse_changed_->disconnect();
771}775}
@@ -778,7 +782,7 @@
778 auto const& indicators = manager_->impl_->menu_manager_->Indicators();782 auto const& indicators = manager_->impl_->menu_manager_->Indicators();
779 indicator::EntryLocationMap map;783 indicator::EntryLocationMap map;
780 menus_->ChildrenGeometries(map);784 menus_->ChildrenGeometries(map);
781 indicators->SyncGeometries(MENUS_PANEL_NAME, map);785 indicators->SyncGeometries(GetMenusPanelID(), map);
782}786}
783787
784bool Window::Impl::ActivateMenu(std::string const& entry_id)788bool Window::Impl::ActivateMenu(std::string const& entry_id)
785789
=== modified file 'decorations/DecorationsManager.cpp'
--- decorations/DecorationsManager.cpp 2014-12-19 13:03:44 +0000
+++ decorations/DecorationsManager.cpp 2015-02-19 19:24:14 +0000
@@ -141,27 +141,24 @@
141 return;141 return;
142 }142 }
143143
144 appmenu->active_window = screen->activeWindow();144 for (auto const& win : windows_)
145145 win.second->impl_->SetupAppMenu();
146 auto setup_active_window = [this] {
147 if (Window::Ptr const& active_win = active_deco_win_.lock())
148 active_win->impl_->SetupAppMenu();
149 };
150146
151 menu_connections_.Remove(appmenu_connection_);147 menu_connections_.Remove(appmenu_connection_);
152 appmenu_connection_ = menu_connections_.Add(appmenu->updated.connect(setup_active_window));148 appmenu_connection_ = menu_connections_.Add(appmenu->updated_win.connect([this] (uint32_t xid) {
153 setup_active_window();149 if (Window::Ptr const& win = GetWindowByXid(xid))
150 win->impl_->SetupAppMenu();
151 }));
154}152}
155153
156void Manager::Impl::UnsetAppMenu()154void Manager::Impl::UnsetAppMenu()
157{155{
158 menu_connections_.Remove(appmenu_connection_);156 menu_connections_.Remove(appmenu_connection_);
159 auto const& active_win = active_deco_win_.lock();
160157
161 if (active_win)158 for (auto const& win : windows_)
162 {159 {
163 active_win->impl_->UnsetAppMenu();160 win.second->impl_->UnsetAppMenu();
164 active_win->impl_->Damage();161 win.second->impl_->Damage();
165 }162 }
166}163}
167164
@@ -265,9 +262,6 @@
265262
266 if (new_active)263 if (new_active)
267 new_active->impl_->active = true;264 new_active->impl_->active = true;
268
269 if (indicator::AppmenuIndicator::Ptr const& appmenu = menu_manager_->AppMenu())
270 appmenu->active_window = active_xid;
271 }265 }
272 else if (event->xproperty.atom == Atoms::mwmHints ||266 else if (event->xproperty.atom == Atoms::mwmHints ||
273 event->xproperty.atom == Atoms::wmAllowedActions)267 event->xproperty.atom == Atoms::wmAllowedActions)
@@ -308,6 +302,9 @@
308302
309bool Manager::Impl::HandleFrameEvent(XEvent* event)303bool Manager::Impl::HandleFrameEvent(XEvent* event)
310{304{
305 if (WindowManager::Default().IsScaleActive())
306 return false;
307
311 auto const& win = GetWindowByFrame(event->xany.window);308 auto const& win = GetWindowByFrame(event->xany.window);
312309
313 // ButtonRelease events might happen also outside the frame window, in this310 // ButtonRelease events might happen also outside the frame window, in this
314311
=== modified file 'decorations/DecorationsMenuDropdown.cpp'
--- decorations/DecorationsMenuDropdown.cpp 2014-02-24 23:53:50 +0000
+++ decorations/DecorationsMenuDropdown.cpp 2015-02-19 19:24:14 +0000
@@ -33,7 +33,7 @@
33using namespace indicator;33using namespace indicator;
3434
35MenuDropdown::MenuDropdown(Indicators::Ptr const& indicators, CompWindow* win)35MenuDropdown::MenuDropdown(Indicators::Ptr const& indicators, CompWindow* win)
36 : MenuEntry(std::make_shared<Entry>("LIM-dropdown"), win)36 : MenuEntry(std::make_shared<Entry>("LIM"+std::to_string(win->id())+"-dropdown"), win)
37 , indicators_(indicators)37 , indicators_(indicators)
38{38{
39 natural_.width = ICON_SIZE;39 natural_.width = ICON_SIZE;
@@ -53,7 +53,7 @@
53 for (auto const& child : children_)53 for (auto const& child : children_)
54 entries.push_back(child->GetEntry());54 entries.push_back(child->GetEntry());
5555
56 indicators_->ShowEntriesDropdown(entries, active_, 0, geo.x(), geo.y2());56 indicators_->ShowEntriesDropdown(entries, active_, grab_.Window()->id(), geo.x(), geo.y2());
57}57}
5858
59bool MenuDropdown::ActivateChild(MenuEntry::Ptr const& child)59bool MenuDropdown::ActivateChild(MenuEntry::Ptr const& child)
@@ -118,7 +118,8 @@
118118
119void MenuDropdown::RenderTexture()119void MenuDropdown::RenderTexture()
120{120{
121 WidgetState state = active() ? WidgetState::PRELIGHT : WidgetState::NORMAL;121 WidgetState normal_state = focused() ? WidgetState::NORMAL : WidgetState::BACKDROP;
122 WidgetState state = active() ? WidgetState::PRELIGHT : normal_state;
122 cu::CairoContext icon_ctx(GetNaturalWidth(), GetNaturalHeight(), scale());123 cu::CairoContext icon_ctx(GetNaturalWidth(), GetNaturalHeight(), scale());
123124
124 if (state == WidgetState::PRELIGHT)125 if (state == WidgetState::PRELIGHT)
125126
=== modified file 'decorations/DecorationsMenuEntry.cpp'
--- decorations/DecorationsMenuEntry.cpp 2014-03-31 18:36:33 +0000
+++ decorations/DecorationsMenuEntry.cpp 2015-02-19 19:24:14 +0000
@@ -37,11 +37,13 @@
37 , in_dropdown(false)37 , in_dropdown(false)
38 , entry_(entry)38 , entry_(entry)
39 , grab_(win, true)39 , grab_(win, true)
40 , show_menu_enabled_(true)
40{41{
41 entry_->updated.connect(sigc::mem_fun(this, &MenuEntry::EntryUpdated));42 entry_->updated.connect(sigc::mem_fun(this, &MenuEntry::EntryUpdated));
42 horizontal_padding.changed.connect(sigc::hide(sigc::mem_fun(this, &MenuEntry::RenderTexture)));43 horizontal_padding.changed.connect(sigc::hide(sigc::mem_fun(this, &MenuEntry::RenderTexture)));
43 vertical_padding.changed.connect(sigc::hide(sigc::mem_fun(this, &MenuEntry::RenderTexture)));44 vertical_padding.changed.connect(sigc::hide(sigc::mem_fun(this, &MenuEntry::RenderTexture)));
44 scale.changed.connect(sigc::hide(sigc::mem_fun(this, &MenuEntry::RenderTexture)));45 scale.changed.connect(sigc::hide(sigc::mem_fun(this, &MenuEntry::RenderTexture)));
46 focused.changed.connect(sigc::hide(sigc::mem_fun(this, &MenuEntry::RenderTexture)));
45 in_dropdown.changed.connect([this] (bool in) { visible = entry_->visible() && !in; });47 in_dropdown.changed.connect([this] (bool in) { visible = entry_->visible() && !in; });
46 EntryUpdated();48 EntryUpdated();
47}49}
@@ -63,7 +65,7 @@
6365
64void MenuEntry::RenderTexture()66void MenuEntry::RenderTexture()
65{67{
66 WidgetState state = WidgetState::NORMAL;68 WidgetState state = focused() ? WidgetState::NORMAL : WidgetState::BACKDROP;
6769
68 if (show_now())70 if (show_now())
69 state = WidgetState::PRESSED;71 state = WidgetState::PRESSED;
@@ -120,10 +122,17 @@
120{122{
121 button_up_timer_.reset();123 button_up_timer_.reset();
122 grab_.ButtonDownEvent(p, button, timestamp);124 grab_.ButtonDownEvent(p, button, timestamp);
125 show_menu_enabled_ = (focused() || Settings::Instance().lim_unfocused_popup());
123}126}
124127
125void MenuEntry::ButtonUpEvent(CompPoint const& p, unsigned button, Time timestamp)128void MenuEntry::ButtonUpEvent(CompPoint const& p, unsigned button, Time timestamp)
126{129{
130 if (!show_menu_enabled_)
131 {
132 grab_.ButtonUpEvent(p, button, timestamp);
133 return;
134 }
135
127 if (button == 1 && !grab_.IsGrabbed())136 if (button == 1 && !grab_.IsGrabbed())
128 {137 {
129 unsigned double_click_wait = Settings::Instance().lim_double_click_wait();138 unsigned double_click_wait = Settings::Instance().lim_double_click_wait();
@@ -143,7 +152,8 @@
143152
144 if (button == 2 || button == 3)153 if (button == 2 || button == 3)
145 {154 {
146 ShowMenu(button);155 if (Style::Get()->WindowManagerAction(WMEvent(button)) == WMAction::NONE)
156 ShowMenu(button);
147 }157 }
148158
149 grab_.ButtonUpEvent(p, button, timestamp);159 grab_.ButtonUpEvent(p, button, timestamp);
150160
=== modified file 'decorations/DecorationsMenuEntry.h'
--- decorations/DecorationsMenuEntry.h 2014-02-27 07:10:31 +0000
+++ decorations/DecorationsMenuEntry.h 2015-02-19 19:24:14 +0000
@@ -63,10 +63,11 @@
6363
64protected:64protected:
65 indicator::Entry::Ptr entry_;65 indicator::Entry::Ptr entry_;
66 GrabEdge grab_;
6667
67private:68private:
69 bool show_menu_enabled_;
68 glib::Source::UniquePtr button_up_timer_;70 glib::Source::UniquePtr button_up_timer_;
69 GrabEdge grab_;
70};71};
7172
72} // decoration namespace73} // decoration namespace
7374
=== modified file 'decorations/DecorationsMenuLayout.cpp'
--- decorations/DecorationsMenuLayout.cpp 2014-02-26 00:14:46 +0000
+++ decorations/DecorationsMenuLayout.cpp 2015-02-19 19:24:14 +0000
@@ -35,7 +35,9 @@
35 , win_(win)35 , win_(win)
36 , last_pointer_(-1, -1)36 , last_pointer_(-1, -1)
37 , dropdown_(std::make_shared<MenuDropdown>(menu_manager_->Indicators(), win))37 , dropdown_(std::make_shared<MenuDropdown>(menu_manager_->Indicators(), win))
38{}38{
39 visible = false;
40}
3941
40void MenuLayout::Setup()42void MenuLayout::Setup()
41{43{
@@ -56,7 +58,7 @@
56 dropdown_->active.changed.connect(active_cb);58 dropdown_->active.changed.connect(active_cb);
57 dropdown_->show_now.changed.connect(show_now_cb);59 dropdown_->show_now.changed.connect(show_now_cb);
5860
59 for (auto const& entry : menu_manager_->AppMenu()->GetEntries())61 for (auto const& entry : menu_manager_->AppMenu()->GetEntriesForWindow(win_->id()))
60 {62 {
61 auto menu = std::make_shared<MenuEntry>(entry, win_);63 auto menu = std::make_shared<MenuEntry>(entry, win_);
62 menu->mouse_owner.changed.connect(ownership_cb);64 menu->mouse_owner.changed.connect(ownership_cb);
@@ -65,7 +67,24 @@
65 menu->focused = focused();67 menu->focused = focused();
66 menu->scale = scale();68 menu->scale = scale();
67 menu->SetParent(shared_from_this());69 menu->SetParent(shared_from_this());
68 items_.push_back(menu);70
71 if (items_.empty() || entry->priority() < 0)
72 {
73 items_.push_back(menu);
74 }
75 else
76 {
77 auto pos = items_.rbegin();
78
79 for (; pos != items_.rend(); ++pos)
80 {
81 auto menu = std::static_pointer_cast<MenuEntry>(*pos);
82 if (entry->priority() >= menu->GetEntry()->priority())
83 break;
84 }
85
86 items_.insert(pos.base(), menu);
87 }
69 }88 }
7089
71 if (!items_.empty())90 if (!items_.empty())
@@ -195,12 +214,14 @@
195 int accumolated_width = dropdown_width + left_padding + right_padding - inner_padding;214 int accumolated_width = dropdown_width + left_padding + right_padding - inner_padding;
196 int max_width = max_.width;215 int max_width = max_.width;
197 std::list<MenuEntry::Ptr> to_hide;216 std::list<MenuEntry::Ptr> to_hide;
217 bool is_visible = visible();
198218
199 for (auto const& item : items_)219 for (auto const& item : items_)
200 {220 {
201 if (!item->visible() || item == dropdown_)221 if (!item->visible() || item == dropdown_)
202 continue;222 continue;
203223
224 is_visible = true;
204 accumolated_width += item->GetNaturalWidth() + inner_padding;225 accumolated_width += item->GetNaturalWidth() + inner_padding;
205226
206 if (accumolated_width > max_width)227 if (accumolated_width > max_width)
@@ -235,6 +256,7 @@
235 dropdown_->Push(hidden);256 dropdown_->Push(hidden);
236 }257 }
237258
259 visible = is_visible;
238 Layout::DoRelayout();260 Layout::DoRelayout();
239}261}
240262
241263
=== modified file 'decorations/DecorationsPriv.h'
--- decorations/DecorationsPriv.h 2014-10-22 14:38:06 +0000
+++ decorations/DecorationsPriv.h 2015-02-19 19:24:14 +0000
@@ -111,6 +111,7 @@
111 bool ShouldBeDecorated() const;111 bool ShouldBeDecorated() const;
112 GLTexture* ShadowTexture() const;112 GLTexture* ShadowTexture() const;
113 unsigned ShadowRadius() const;113 unsigned ShadowRadius() const;
114 std::string const& GetMenusPanelID() const;
114115
115 void ComputeShadowQuads();116 void ComputeShadowQuads();
116 void UpdateDecorationTextures();117 void UpdateDecorationTextures();
@@ -143,6 +144,7 @@
143 connection::Wrapper dpi_changed_;144 connection::Wrapper dpi_changed_;
144 connection::Wrapper grab_mouse_changed_;145 connection::Wrapper grab_mouse_changed_;
145 std::string last_title_;146 std::string last_title_;
147 std::string panel_id_;
146 std::vector<cu::SimpleTextureQuad> bg_textures_;148 std::vector<cu::SimpleTextureQuad> bg_textures_;
147 std::shared_ptr<ForceQuitDialog> force_quit_;149 std::shared_ptr<ForceQuitDialog> force_quit_;
148 InputMixer::Ptr input_mixer_;150 InputMixer::Ptr input_mixer_;
@@ -194,7 +196,7 @@
194196
195 uweak_ptr<decoration::Window> active_deco_win_;197 uweak_ptr<decoration::Window> active_deco_win_;
196 uweak_ptr<InputMixer> last_mouse_owner_;198 uweak_ptr<InputMixer> last_mouse_owner_;
197 std::map<CompWindow*, decoration::Window::Ptr> windows_;199 std::unordered_map<CompWindow*, decoration::Window::Ptr> windows_;
198 std::unordered_map<::Window, std::weak_ptr<decoration::Window>> framed_windows_;200 std::unordered_map<::Window, std::weak_ptr<decoration::Window>> framed_windows_;
199201
200 menu::Manager::Ptr menu_manager_;202 menu::Manager::Ptr menu_manager_;
201203
=== modified file 'decorations/DecorationsSlidingLayout.cpp'
--- decorations/DecorationsSlidingLayout.cpp 2014-12-19 12:02:34 +0000
+++ decorations/DecorationsSlidingLayout.cpp 2015-02-19 19:24:14 +0000
@@ -137,7 +137,7 @@
137 auto& main_item_ = items_[ItemRole::MAIN];137 auto& main_item_ = items_[ItemRole::MAIN];
138 auto& input_item_ = items_[ItemRole::INPUT];138 auto& input_item_ = items_[ItemRole::INPUT];
139139
140 if (!input_item_)140 if (!input_item_ || !input_item_->visible())
141 {141 {
142 if (main_item_)142 if (main_item_)
143 main_item_->Draw(ctx, transformation, attrib, clip, mask);143 main_item_->Draw(ctx, transformation, attrib, clip, mask);
144144
=== modified file 'decorations/DecorationsWidgets.cpp'
--- decorations/DecorationsWidgets.cpp 2014-09-24 01:40:50 +0000
+++ decorations/DecorationsWidgets.cpp 2015-02-19 19:24:14 +0000
@@ -192,15 +192,10 @@
192192
193BasicContainer::Ptr Item::GetTopParent() const193BasicContainer::Ptr Item::GetTopParent() const
194{194{
195 BasicContainer::Ptr parent = GetParent();195 BasicContainer::Ptr parent = parent_;
196196
197 while (parent)197 while (parent && parent->parent_)
198 {198 parent = parent->parent_;
199 if (!parent->parent_)
200 return parent;
201
202 parent = parent->GetParent();
203 }
204199
205 return parent;200 return parent;
206}201}
207202
=== modified file 'launcher/LauncherEntryRemoteModel.h'
--- launcher/LauncherEntryRemoteModel.h 2012-05-07 19:52:54 +0000
+++ launcher/LauncherEntryRemoteModel.h 2015-02-19 19:24:14 +0000
@@ -22,7 +22,7 @@
2222
23#include <gio/gio.h>23#include <gio/gio.h>
24#include <sigc++/sigc++.h>24#include <sigc++/sigc++.h>
25#include <map>25#include <unordered_map>
2626
27#include "LauncherEntryRemote.h"27#include "LauncherEntryRemote.h"
2828
@@ -68,7 +68,7 @@
68 glib::Object<GDBusConnection> _conn;68 glib::Object<GDBusConnection> _conn;
69 unsigned int _launcher_entry_dbus_signal_id;69 unsigned int _launcher_entry_dbus_signal_id;
70 unsigned int _dbus_name_owner_changed_signal_id;70 unsigned int _dbus_name_owner_changed_signal_id;
71 std::map<std::string, LauncherEntryRemote::Ptr> _entries_by_uri;71 std::unordered_map<std::string, LauncherEntryRemote::Ptr> _entries_by_uri;
72};72};
7373
74} // namespace74} // namespace
7575
=== modified file 'lockscreen/LockScreenPanel.cpp'
--- lockscreen/LockScreenPanel.cpp 2014-09-19 18:22:14 +0000
+++ lockscreen/LockScreenPanel.cpp 2015-02-19 19:24:14 +0000
@@ -118,7 +118,7 @@
118 if (entry->active())118 if (entry->active())
119 {119 {
120 active = true;120 active = true;
121 indicators_view_->ActivateEntry(entry->id());121 indicators_view_->ActivateEntry(entry);
122 OnEntryActivated(GetPanelName(), entry->id(), entry->geometry());122 OnEntryActivated(GetPanelName(), entry->id(), entry->geometry());
123 break;123 break;
124 }124 }
125125
=== modified file 'panel/PanelIndicatorEntryDropdownView.cpp'
--- panel/PanelIndicatorEntryDropdownView.cpp 2014-02-25 00:28:58 +0000
+++ panel/PanelIndicatorEntryDropdownView.cpp 2015-02-19 19:24:14 +0000
@@ -98,6 +98,11 @@
98 return child;98 return child;
99}99}
100100
101void PanelIndicatorEntryDropdownView::Clear()
102{
103 children_.clear();
104}
105
101std::deque<PanelIndicatorEntryView::Ptr> const& PanelIndicatorEntryDropdownView::Children() const106std::deque<PanelIndicatorEntryView::Ptr> const& PanelIndicatorEntryDropdownView::Children() const
102{107{
103 return children_;108 return children_;
@@ -144,7 +149,7 @@
144 entries.push_back(entry->GetEntry());149 entries.push_back(entry->GetEntry());
145150
146 auto const& geo = GetAbsoluteGeometry();151 auto const& geo = GetAbsoluteGeometry();
147 indicators_->ShowEntriesDropdown(entries, active_entry_, 0, geo.x, geo.y + geo.height);152 indicators_->ShowEntriesDropdown(entries, active_entry_, entries[0]->parent_window(), geo.x, geo.y + geo.height);
148}153}
149154
150bool PanelIndicatorEntryDropdownView::ActivateChild(PanelIndicatorEntryView::Ptr const& child)155bool PanelIndicatorEntryDropdownView::ActivateChild(PanelIndicatorEntryView::Ptr const& child)
151156
=== modified file 'panel/PanelIndicatorEntryDropdownView.h'
--- panel/PanelIndicatorEntryDropdownView.h 2014-02-07 23:29:46 +0000
+++ panel/PanelIndicatorEntryDropdownView.h 2015-02-19 19:24:14 +0000
@@ -39,6 +39,7 @@
39 void Insert(PanelIndicatorEntryView::Ptr const&);39 void Insert(PanelIndicatorEntryView::Ptr const&);
40 void Remove(PanelIndicatorEntryView::Ptr const&);40 void Remove(PanelIndicatorEntryView::Ptr const&);
41 PanelIndicatorEntryView::Ptr Pop();41 PanelIndicatorEntryView::Ptr Pop();
42 void Clear();
4243
43 PanelIndicatorEntryView::Ptr Top() const;44 PanelIndicatorEntryView::Ptr Top() const;
44 std::deque<PanelIndicatorEntryView::Ptr> const& Children() const;45 std::deque<PanelIndicatorEntryView::Ptr> const& Children() const;
4546
=== modified file 'panel/PanelIndicatorEntryView.cpp'
--- panel/PanelIndicatorEntryView.cpp 2014-08-07 13:15:17 +0000
+++ panel/PanelIndicatorEntryView.cpp 2015-02-19 19:24:14 +0000
@@ -59,6 +59,7 @@
59 , cv_(unity::Settings::Instance().em(monitor_))59 , cv_(unity::Settings::Instance().em(monitor_))
60{60{
61 proxy_->active_changed.connect(sigc::mem_fun(this, &PanelIndicatorEntryView::OnActiveChanged));61 proxy_->active_changed.connect(sigc::mem_fun(this, &PanelIndicatorEntryView::OnActiveChanged));
62 proxy_->show_now_changed.connect(sigc::mem_fun(&show_now_changed, &sigc::signal<void, bool>::emit));
62 proxy_->updated.connect(sigc::mem_fun(this, &PanelIndicatorEntryView::Refresh));63 proxy_->updated.connect(sigc::mem_fun(this, &PanelIndicatorEntryView::Refresh));
6364
64 InputArea::mouse_down.connect(sigc::mem_fun(this, &PanelIndicatorEntryView::OnMouseDown));65 InputArea::mouse_down.connect(sigc::mem_fun(this, &PanelIndicatorEntryView::OnMouseDown));
@@ -84,11 +85,6 @@
84 Refresh();85 Refresh();
85}86}
8687
87PanelIndicatorEntryView::~PanelIndicatorEntryView()
88{
89 // Nothing to do...
90}
91
92void PanelIndicatorEntryView::OnActiveChanged(bool is_active)88void PanelIndicatorEntryView::OnActiveChanged(bool is_active)
93{89{
94 active_changed.emit(this, is_active);90 active_changed.emit(this, is_active);
@@ -114,10 +110,16 @@
114 });110 });
115111
116 wm.TerminateExpo();112 wm.TerminateExpo();
113 return;
117 }114 }
118115
119 if (wm.IsScaleActive())116 if (wm.IsScaleActive())
117 {
118 if (type_ == MENU)
119 return;
120
120 wm.TerminateScale();121 wm.TerminateScale();
122 }
121123
122 auto const& abs_geo = GetAbsoluteGeometry();124 auto const& abs_geo = GetAbsoluteGeometry();
123 proxy_->ShowMenu(abs_geo.x, abs_geo.y + abs_geo.height, button);125 proxy_->ShowMenu(abs_geo.x, abs_geo.y + abs_geo.height, button);
124126
=== modified file 'panel/PanelIndicatorEntryView.h'
--- panel/PanelIndicatorEntryView.h 2014-03-31 21:08:10 +0000
+++ panel/PanelIndicatorEntryView.h 2015-02-19 19:24:14 +0000
@@ -53,10 +53,8 @@
53 PanelIndicatorEntryView(indicator::Entry::Ptr const& proxy, int padding = 5,53 PanelIndicatorEntryView(indicator::Entry::Ptr const& proxy, int padding = 5,
54 IndicatorEntryType type = INDICATOR);54 IndicatorEntryType type = INDICATOR);
5555
56 virtual ~PanelIndicatorEntryView();
57
58 IndicatorEntryType GetType() const;56 IndicatorEntryType GetType() const;
59 indicator::Entry::Ptr GetEntry() const { return proxy_; }57 indicator::Entry::Ptr const& GetEntry() const { return proxy_; }
60 std::string GetEntryID() const;58 std::string GetEntryID() const;
61 int GetEntryPriority() const;59 int GetEntryPriority() const;
6260
@@ -93,6 +91,7 @@
9391
94 sigc::signal<void, PanelIndicatorEntryView*, bool> active_changed;92 sigc::signal<void, PanelIndicatorEntryView*, bool> active_changed;
95 sigc::signal<void, PanelIndicatorEntryView*> refreshed;93 sigc::signal<void, PanelIndicatorEntryView*> refreshed;
94 sigc::signal<void, bool> show_now_changed;
9695
97protected:96protected:
98 std::string GetName() const;97 std::string GetName() const;
9998
=== modified file 'panel/PanelIndicatorsView.cpp'
--- panel/PanelIndicatorsView.cpp 2014-03-06 09:26:03 +0000
+++ panel/PanelIndicatorsView.cpp 2015-02-19 19:24:14 +0000
@@ -71,7 +71,7 @@
71 indicators_.push_back(indicator);71 indicators_.push_back(indicator);
7272
73 for (auto const& entry : indicator->GetEntries())73 for (auto const& entry : indicator->GetEntries())
74 AddEntry(entry);74 OnEntryAdded(entry);
7575
76 auto& conn_manager = indicators_connections_[indicator];76 auto& conn_manager = indicators_connections_[indicator];
77 conn_manager.Add(indicator->on_entry_added.connect(sigc::mem_fun(this, &PanelIndicatorsView::OnEntryAdded)));77 conn_manager.Add(indicator->on_entry_added.connect(sigc::mem_fun(this, &PanelIndicatorsView::OnEntryAdded)));
@@ -83,7 +83,7 @@
83 indicators_connections_.erase(indicator);83 indicators_connections_.erase(indicator);
8484
85 for (auto const& entry : indicator->GetEntries())85 for (auto const& entry : indicator->GetEntries())
86 RemoveEntry(entry->id());86 RemoveEntry(entry);
8787
88 for (auto i = indicators_.begin(); i != indicators_.end(); ++i)88 for (auto i = indicators_.begin(); i != indicators_.end(); ++i)
89 {89 {
@@ -158,13 +158,13 @@
158 }158 }
159}159}
160160
161PanelIndicatorEntryView* PanelIndicatorsView::ActivateEntry(std::string const& entry_id, int button)161PanelIndicatorEntryView* PanelIndicatorsView::ActivateEntry(indicator::Entry::Ptr const& entry, int button)
162{162{
163 auto entry = entries_.find(entry_id);163 auto it = entries_.find(entry);
164164
165 if (entry != entries_.end())165 if (it != entries_.end())
166 {166 {
167 PanelIndicatorEntryView* view = entry->second;167 PanelIndicatorEntryView* view = it->second;
168168
169 if (view->IsSensitive() && view->IsVisible())169 if (view->IsSensitive() && view->IsVisible())
170 {170 {
@@ -181,6 +181,17 @@
181 return nullptr;181 return nullptr;
182}182}
183183
184PanelIndicatorEntryView* PanelIndicatorsView::ActivateEntry(std::string const& entry_id, int button)
185{
186 for (auto const& it : entries_)
187 {
188 if (it.first->id() == entry_id)
189 return ActivateEntry(it.first, button);
190 }
191
192 return nullptr;
193}
194
184bool PanelIndicatorsView::ActivateIfSensitive()195bool PanelIndicatorsView::ActivateIfSensitive()
185{196{
186 for (auto* area : layout_->GetChildren())197 for (auto* area : layout_->GetChildren())
@@ -222,7 +233,7 @@
222 if (!view->IsVisible())233 if (!view->IsVisible())
223 continue;234 continue;
224235
225 if (!target && view->IsFocused() &&236 if (!target &&
226 view->IsSensitive() &&237 view->IsSensitive() &&
227 view->GetAbsoluteGeometry().IsPointInside(x, y))238 view->GetAbsoluteGeometry().IsPointInside(x, y))
228 {239 {
@@ -267,9 +278,8 @@
267 if (!view)278 if (!view)
268 return;279 return;
269280
270 auto const& entry_id = view->GetEntryID();
271 bool added_to_dropdown = false;281 bool added_to_dropdown = false;
272 bool known_entry = (entries_.find(entry_id) != entries_.end());282 bool known_entry = (entries_.find(view->GetEntry()) != entries_.end());
273 view->SetOpacity(opacity());283 view->SetOpacity(opacity());
274284
275 if (!known_entry && dropdown_ && !dropdown_->Empty())285 if (!known_entry && dropdown_ && !dropdown_->Empty())
@@ -317,7 +327,7 @@
317 {327 {
318 view->SetMonitor(monitor_);328 view->SetMonitor(monitor_);
319 view->refreshed.connect(sigc::mem_fun(this, &PanelIndicatorsView::OnEntryRefreshed));329 view->refreshed.connect(sigc::mem_fun(this, &PanelIndicatorsView::OnEntryRefreshed));
320 entries_.insert({entry_id, view});330 entries_.insert({view->GetEntry(), view});
321 on_indicator_updated.emit();331 on_indicator_updated.emit();
322 entry_added.emit(view);332 entry_added.emit(view);
323 }333 }
@@ -346,6 +356,23 @@
346 on_indicator_updated.emit();356 on_indicator_updated.emit();
347}357}
348358
359void PanelIndicatorsView::ClearEntries()
360{
361 for (auto it = entries_.begin(); it != entries_.end();)
362 {
363 auto* entry = it->second;
364 ++it;
365
366 if (entry != dropdown_.GetPointer())
367 RemoveEntryView(entry);
368 }
369
370 on_indicator_updated.emit();
371
372 QueueRelayout();
373 QueueDraw();
374}
375
349void PanelIndicatorsView::RemoveEntryView(PanelIndicatorEntryView* view)376void PanelIndicatorsView::RemoveEntryView(PanelIndicatorEntryView* view)
350{377{
351 if (!view)378 if (!view)
@@ -357,7 +384,7 @@
357 dropdown_->Remove(PanelIndicatorEntryView::Ptr(view));384 dropdown_->Remove(PanelIndicatorEntryView::Ptr(view));
358385
359 RemoveChild(view);386 RemoveChild(view);
360 entries_.erase(view->GetEntryID());387 entries_.erase(view->GetEntry());
361 layout_->RemoveChildObject(view);388 layout_->RemoveChildObject(view);
362 on_indicator_updated.emit();389 on_indicator_updated.emit();
363390
@@ -365,9 +392,12 @@
365 QueueDraw();392 QueueDraw();
366}393}
367394
368void PanelIndicatorsView::RemoveEntry(std::string const& entry_id)395void PanelIndicatorsView::RemoveEntry(indicator::Entry::Ptr const& entry)
369{396{
370 RemoveEntryView(entries_[entry_id]);397 auto it = entries_.find(entry);
398
399 if (it != entries_.end())
400 RemoveEntryView(it->second);
371}401}
372402
373void PanelIndicatorsView::OverlayShown()403void PanelIndicatorsView::OverlayShown()
374404
=== modified file 'panel/PanelIndicatorsView.h'
--- panel/PanelIndicatorsView.h 2014-03-06 09:26:03 +0000
+++ panel/PanelIndicatorsView.h 2015-02-19 19:24:14 +0000
@@ -55,9 +55,10 @@
55 int padding = 5,55 int padding = 5,
56 IndicatorEntryPosition pos = AUTO,56 IndicatorEntryPosition pos = AUTO,
57 IndicatorEntryType type = IndicatorEntryType::INDICATOR);57 IndicatorEntryType type = IndicatorEntryType::INDICATOR);
58 void RemoveEntry(std::string const& entry_id);58 void RemoveEntry(indicator::Entry::Ptr const&);
5959
60 PanelIndicatorEntryView* ActivateEntryAt(int x, int y, int button = 1);60 PanelIndicatorEntryView* ActivateEntryAt(int x, int y, int button = 1);
61 PanelIndicatorEntryView* ActivateEntry(indicator::Entry::Ptr const&, int button = 1);
61 PanelIndicatorEntryView* ActivateEntry(std::string const& entry_id, int button = 1);62 PanelIndicatorEntryView* ActivateEntry(std::string const& entry_id, int button = 1);
62 bool ActivateIfSensitive();63 bool ActivateIfSensitive();
6364
@@ -84,18 +85,19 @@
84 typedef std::vector<indicator::Indicator::Ptr> Indicators;85 typedef std::vector<indicator::Indicator::Ptr> Indicators;
85 Indicators const& GetIndicators() const;86 Indicators const& GetIndicators() const;
8687
88 void ClearEntries();
89
87 virtual void Draw(nux::GraphicsEngine& GfxContext, bool force_draw);90 virtual void Draw(nux::GraphicsEngine& GfxContext, bool force_draw);
88 virtual void DrawContent(nux::GraphicsEngine& GfxContext, bool force_draw);91 virtual void DrawContent(nux::GraphicsEngine& GfxContext, bool force_draw);
8992
90 virtual void OnEntryAdded(indicator::Entry::Ptr const& entry);93 virtual void OnEntryAdded(indicator::Entry::Ptr const&);
91 virtual void OnEntryRefreshed(PanelIndicatorEntryView* view);94 virtual void OnEntryRefreshed(PanelIndicatorEntryView* view);
9295
93 void AddEntryView(PanelIndicatorEntryView* view, IndicatorEntryPosition pos = AUTO);96 void AddEntryView(PanelIndicatorEntryView* view, IndicatorEntryPosition pos = AUTO);
94 void RemoveEntryView(PanelIndicatorEntryView* view);97 void RemoveEntryView(PanelIndicatorEntryView* view);
9598
96 nux::HLayout* layout_;99 nux::HLayout* layout_;
97 typedef std::map<std::string, PanelIndicatorEntryView*> Entries;100 std::unordered_map<indicator::Entry::Ptr, PanelIndicatorEntryView*> entries_;
98 Entries entries_;
99101
100 int monitor_;102 int monitor_;
101 bool overlay_showing_;103 bool overlay_showing_;
102104
=== modified file 'panel/PanelMenuView.cpp'
--- panel/PanelMenuView.cpp 2014-12-19 13:03:44 +0000
+++ panel/PanelMenuView.cpp 2015-02-19 19:24:14 +0000
@@ -27,6 +27,7 @@
27#include "unity-shared/CairoTexture.h"27#include "unity-shared/CairoTexture.h"
28#include "unity-shared/DecorationStyle.h"28#include "unity-shared/DecorationStyle.h"
29#include "unity-shared/PanelStyle.h"29#include "unity-shared/PanelStyle.h"
30#include "unity-shared/RawPixel.h"
30#include "unity-shared/UnitySettings.h"31#include "unity-shared/UnitySettings.h"
31#include "unity-shared/UBusMessages.h"32#include "unity-shared/UBusMessages.h"
32#include "unity-shared/UScreen.h"33#include "unity-shared/UScreen.h"
@@ -43,15 +44,14 @@
4344
44namespace45namespace
45{46{
46 const int MAIN_LEFT_PADDING = 4;47 const RawPixel MAIN_LEFT_PADDING = 4_em;
47 const int TITLE_PADDING = 2;48 const RawPixel TITLE_PADDING = 2_em;
48 const int MENUBAR_PADDING = 4;49 const RawPixel MENUBAR_PADDING = 4_em;
49 const int MENU_ENTRIES_PADDING = 6;50 const int MENU_ENTRIES_PADDING = 6;
5051
51 const std::string NEW_APP_HIDE_TIMEOUT = "new-app-hide-timeout";52 const std::string NEW_APP_HIDE_TIMEOUT = "new-app-hide-timeout";
52 const std::string NEW_APP_SHOW_TIMEOUT = "new-app-show-timeout";53 const std::string NEW_APP_SHOW_TIMEOUT = "new-app-show-timeout";
53 const std::string WINDOW_MOVED_TIMEOUT = "window-moved-timeout";54 const std::string WINDOW_MOVED_TIMEOUT = "window-moved-timeout";
54 const std::string WINDOW_ACTIVATED_TIMEOUT = "window-activated-timeout";
55 const std::string UPDATE_SHOW_NOW_TIMEOUT = "update-show-now-timeout";55 const std::string UPDATE_SHOW_NOW_TIMEOUT = "update-show-now-timeout";
56 const std::string INTEGRATED_MENUS_DOUBLE_CLICK_TIMEOUT = "integrated-menus-double-click-timeout";56 const std::string INTEGRATED_MENUS_DOUBLE_CLICK_TIMEOUT = "integrated-menus-double-click-timeout";
5757
@@ -83,7 +83,10 @@
83}83}
8484
85PanelMenuView::PanelMenuView(menu::Manager::Ptr const& menus)85PanelMenuView::PanelMenuView(menu::Manager::Ptr const& menus)
86 : menu_manager_(menus)86 : active_window(0)
87 , maximized_window(0)
88 , focused(true)
89 , menu_manager_(menus)
87 , matcher_(bamf_matcher_get_default())90 , matcher_(bamf_matcher_get_default())
88 , is_inside_(false)91 , is_inside_(false)
89 , is_grabbed_(false)92 , is_grabbed_(false)
@@ -100,16 +103,15 @@
100 , ignore_menu_visibility_(false)103 , ignore_menu_visibility_(false)
101 , integrated_menus_(menu_manager_->integrated_menus())104 , integrated_menus_(menu_manager_->integrated_menus())
102 , always_show_menus_(menu_manager_->always_show_menus())105 , always_show_menus_(menu_manager_->always_show_menus())
103 , active_xid_(0)
104 , desktop_name_(get_current_desktop())106 , desktop_name_(get_current_desktop())
105{107{
106 BamfWindow* active_win = bamf_matcher_get_active_window(matcher_);108 BamfWindow* active_win = bamf_matcher_get_active_window(matcher_);
107 if (BAMF_IS_WINDOW(active_win))109 if (BAMF_IS_WINDOW(active_win))
108 active_xid_ = bamf_window_get_xid(active_win);110 active_window = bamf_window_get_xid(active_win);
109111
110 SetupPanelMenuViewSignals();
111 SetupWindowButtons();112 SetupWindowButtons();
112 SetupTitlebarGrabArea();113 SetupTitlebarGrabArea();
114 SetupPanelMenuViewSignals();
113 SetupWindowManagerSignals();115 SetupWindowManagerSignals();
114 SetupUBusManagerInterests();116 SetupUBusManagerInterests();
115117
@@ -128,8 +130,10 @@
128void PanelMenuView::OnStyleChanged()130void PanelMenuView::OnStyleChanged()
129{131{
130 int height = panel::Style::Instance().PanelHeight(monitor_);132 int height = panel::Style::Instance().PanelHeight(monitor_);
133 double scale = Settings::Instance().em(monitor_)->DPIScale();
131 window_buttons_->SetMinimumHeight(height);134 window_buttons_->SetMinimumHeight(height);
132 window_buttons_->SetMaximumHeight(height);135 window_buttons_->SetMaximumHeight(height);
136 window_buttons_->SetLeftAndRightPadding(MAIN_LEFT_PADDING.CP(scale), MENUBAR_PADDING.CP(scale));
133 window_buttons_->UpdateDPIChanged();137 window_buttons_->UpdateDPIChanged();
134138
135 layout_->SetLeftAndRightPadding(window_buttons_->GetContentWidth(), 0);139 layout_->SetLeftAndRightPadding(window_buttons_->GetContentWidth(), 0);
@@ -157,6 +161,20 @@
157161
158 menu_manager_->integrated_menus.changed.connect(sigc::mem_fun(this, &PanelMenuView::OnLIMChanged));162 menu_manager_->integrated_menus.changed.connect(sigc::mem_fun(this, &PanelMenuView::OnLIMChanged));
159 menu_manager_->always_show_menus.changed.connect(sigc::mem_fun(this, &PanelMenuView::OnAlwaysShowMenusChanged));163 menu_manager_->always_show_menus.changed.connect(sigc::mem_fun(this, &PanelMenuView::OnAlwaysShowMenusChanged));
164
165 auto update_target_cb = sigc::hide(sigc::mem_fun(this, &PanelMenuView::UpdateTargetWindowItems));
166 maximized_window.changed.connect(update_target_cb);
167 active_window.changed.connect(update_target_cb);
168
169 focused.changed.connect([this] (bool focused) {
170 Refresh(true);
171 window_buttons_->focused = focused;
172
173 for (auto const& entry : entries_)
174 entry.second->SetFocusedState(focused);
175
176 FullRedraw();
177 });
160}178}
161179
162void PanelMenuView::SetupWindowButtons()180void PanelMenuView::SetupWindowButtons()
@@ -164,7 +182,7 @@
164 window_buttons_ = new WindowButtons();182 window_buttons_ = new WindowButtons();
165 window_buttons_->SetParentObject(this);183 window_buttons_->SetParentObject(this);
166 window_buttons_->monitor = monitor_;184 window_buttons_->monitor = monitor_;
167 window_buttons_->controlled_window = active_xid_;185 window_buttons_->controlled_window = active_window();
168 window_buttons_->opacity = 0.0f;186 window_buttons_->opacity = 0.0f;
169 window_buttons_->SetLeftAndRightPadding(MAIN_LEFT_PADDING, MENUBAR_PADDING);187 window_buttons_->SetLeftAndRightPadding(MAIN_LEFT_PADDING, MENUBAR_PADDING);
170 window_buttons_->SetMaximumHeight(panel::Style::Instance().PanelHeight(monitor_));188 window_buttons_->SetMaximumHeight(panel::Style::Instance().PanelHeight(monitor_));
@@ -252,6 +270,27 @@
252 PanelIndicatorsView::AddIndicator(indicator);270 PanelIndicatorsView::AddIndicator(indicator);
253}271}
254272
273void PanelMenuView::UpdateTargetWindowItems()
274{
275 Window old_target = window_buttons_->controlled_window;
276 Window target_window = integrated_menus_ ? maximized_window() : active_window();
277
278 if (old_target != target_window)
279 {
280 window_buttons_->controlled_window = target_window;
281 ClearEntries();
282
283 if (indicator::AppmenuIndicator::Ptr appmenu = menu_manager_->AppMenu())
284 {
285 for (auto const& entry : appmenu->GetEntriesForWindow(target_window))
286 OnEntryAdded(entry);
287 }
288 }
289
290 if (integrated_menus_)
291 focused = (target_window == active_window());
292}
293
255void PanelMenuView::FullRedraw()294void PanelMenuView::FullRedraw()
256{295{
257 QueueDraw();296 QueueDraw();
@@ -266,9 +305,11 @@
266 if (!integrated_menus_)305 if (!integrated_menus_)
267 {306 {
268 CheckMouseInside();307 CheckMouseInside();
269 window_buttons_->focused = true;308 focused = true;
270 }309 }
271310
311 UpdateTargetWindowItems();
312
272 Refresh(true);313 Refresh(true);
273 FullRedraw();314 FullRedraw();
274}315}
@@ -302,7 +343,7 @@
302 return titlebar_grab_area_.GetPointer();343 return titlebar_grab_area_.GetPointer();
303 }344 }
304345
305 if (is_maximized_ || spread_showing_ || (integrated_menus_ && GetMaximizedWindow() != 0))346 if (is_maximized_ || spread_showing_ || (integrated_menus_ && maximized_window() != 0))
306 {347 {
307 found_area = window_buttons_->FindAreaUnderMouse(mouse_position, event_type);348 found_area = window_buttons_->FindAreaUnderMouse(mouse_position, event_type);
308 NUX_RETURN_VALUE_IF_NOTNULL(found_area, found_area);349 NUX_RETURN_VALUE_IF_NOTNULL(found_area, found_area);
@@ -313,7 +354,7 @@
313 found_area = titlebar_grab_area_->FindAreaUnderMouse(mouse_position, event_type);354 found_area = titlebar_grab_area_->FindAreaUnderMouse(mouse_position, event_type);
314 NUX_RETURN_VALUE_IF_NOTNULL(found_area, found_area);355 NUX_RETURN_VALUE_IF_NOTNULL(found_area, found_area);
315356
316 if (integrated_menus_ && GetMaximizedWindow() != 0)357 if (integrated_menus_ && maximized_window() != 0)
317 {358 {
318 /* When the integrated menus are enabled, that area must act both like an359 /* When the integrated menus are enabled, that area must act both like an
319 * indicator-entry view and like a panel-grab-area, so not to re-implement360 * indicator-entry view and like a panel-grab-area, so not to re-implement
@@ -382,10 +423,7 @@
382423
383bool PanelMenuView::ShouldDrawMenus() const424bool PanelMenuView::ShouldDrawMenus() const
384{425{
385 if (integrated_menus_ && !is_maximized_)426 if ((we_control_active_ || integrated_menus_) && !switcher_showing_ && !launcher_keynav_ && !ignore_menu_visibility_ && HasVisibleMenus())
386 return false;
387
388 if (we_control_active_ && !switcher_showing_ && !launcher_keynav_ && !ignore_menu_visibility_ && !entries_.empty())
389 {427 {
390 WindowManager& wm = WindowManager::Default();428 WindowManager& wm = WindowManager::Default();
391429
@@ -410,7 +448,7 @@
410 if (integrated_menus_)448 if (integrated_menus_)
411 {449 {
412 if (!WindowManager::Default().IsExpoActive())450 if (!WindowManager::Default().IsExpoActive())
413 return (GetMaximizedWindow() != 0);451 return (maximized_window() != 0);
414452
415 return false;453 return false;
416 }454 }
@@ -796,7 +834,7 @@
796834
797std::string PanelMenuView::GetMaximizedViewName(bool use_appname) const835std::string PanelMenuView::GetMaximizedViewName(bool use_appname) const
798{836{
799 Window maximized = GetMaximizedWindow();837 Window maximized = maximized_window();
800 BamfWindow* window = nullptr;838 BamfWindow* window = nullptr;
801 std::string label;839 std::string label;
802840
@@ -830,18 +868,18 @@
830 auto const& style = decoration::Style::Get();868 auto const& style = decoration::Style::Get();
831 auto text_size = style->TitleNaturalSize(label);869 auto text_size = style->TitleNaturalSize(label);
832 auto state = WidgetState::NORMAL;870 auto state = WidgetState::NORMAL;
833 float dpi_scale = Settings::Instance().em(monitor_)->DPIScale();871 double dpi_scale = Settings::Instance().em(monitor_)->DPIScale();
834872
835 if (integrated_menus_ && !is_desktop_focused_ && !WindowManager::Default().IsExpoActive())873 if (integrated_menus_ && !is_desktop_focused_ && !WindowManager::Default().IsExpoActive())
836 {874 {
837 title_geo_.x = geo.x + window_buttons_->GetBaseWidth() + (style->TitleIndent() * dpi_scale);875 title_geo_.x = geo.x + window_buttons_->GetBaseWidth() + (style->TitleIndent() * dpi_scale);
838876
839 if (!window_buttons_->focused())877 if (!focused())
840 state = WidgetState::BACKDROP;878 state = WidgetState::BACKDROP;
841 }879 }
842 else880 else
843 {881 {
844 title_geo_.x = geo.x + (MAIN_LEFT_PADDING + TITLE_PADDING) * dpi_scale;882 title_geo_.x = geo.x + MAIN_LEFT_PADDING.CP(dpi_scale) + TITLE_PADDING.CP(dpi_scale);
845 }883 }
846884
847 title_geo_.y = geo.y + (geo.height - (text_size.height * dpi_scale)) / 2;885 title_geo_.y = geo.y + (geo.height - (text_size.height * dpi_scale)) / 2;
@@ -904,20 +942,9 @@
904 if (geo.width > monitor_geo_.width)942 if (geo.width > monitor_geo_.width)
905 return false;943 return false;
906944
907 if (integrated_menus_)
908 {
909 Window maximized = GetMaximizedWindow();
910 window_buttons_->controlled_window = maximized;
911 window_buttons_->focused = (active_xid_ == maximized);
912 }
913 else
914 {
915 window_buttons_->controlled_window = active_xid_;
916 }
917
918 std::string const& new_title = GetCurrentTitle();945 std::string const& new_title = GetCurrentTitle();
919946
920 if (new_title == panel_title_ && !force && last_geo_ == geo && title_texture_)947 if (!force && new_title == panel_title_ && last_geo_ == geo && title_texture_)
921 {948 {
922 // No need to redraw the title, let's save some CPU time!949 // No need to redraw the title, let's save some CPU time!
923 return false;950 return false;
@@ -956,18 +983,20 @@
956983
957void PanelMenuView::OnEntryAdded(indicator::Entry::Ptr const& entry)984void PanelMenuView::OnEntryAdded(indicator::Entry::Ptr const& entry)
958{985{
959 PanelIndicatorEntryView* view;986 auto parent_window = entry->parent_window();
987 Window target = integrated_menus_ ? maximized_window() : active_window();
960988
961 view = new PanelIndicatorEntryView(entry, MENU_ENTRIES_PADDING, IndicatorEntryType::MENU);989 if (!parent_window || parent_window == target)
962 entry->show_now_changed.connect(sigc::mem_fun(this, &PanelMenuView::UpdateShowNow));990 AddEntryView(new PanelIndicatorEntryView(entry, MENU_ENTRIES_PADDING, IndicatorEntryType::MENU));
963 AddEntryView(view);
964}991}
965992
966void PanelMenuView::OnEntryViewAdded(PanelIndicatorEntryView* view)993void PanelMenuView::OnEntryViewAdded(PanelIndicatorEntryView* view)
967{994{
995 view->SetFocusedState(focused());
968 view->mouse_enter.connect(sigc::mem_fun(this, &PanelMenuView::OnPanelViewMouseEnter));996 view->mouse_enter.connect(sigc::mem_fun(this, &PanelMenuView::OnPanelViewMouseEnter));
969 view->mouse_leave.connect(sigc::mem_fun(this, &PanelMenuView::OnPanelViewMouseLeave));997 view->mouse_leave.connect(sigc::mem_fun(this, &PanelMenuView::OnPanelViewMouseLeave));
970 view->active_changed.connect(sigc::mem_fun(this, &PanelMenuView::OnActiveChanged));998 view->active_changed.connect(sigc::mem_fun(this, &PanelMenuView::OnActiveChanged));
999 view->show_now_changed.connect(sigc::mem_fun(this, &PanelMenuView::UpdateShowNow));
971}1000}
9721001
973void PanelMenuView::NotifyAllMenusClosed()1002void PanelMenuView::NotifyAllMenusClosed()
@@ -1116,58 +1145,41 @@
1116 show_now_activated_ = false;1145 show_now_activated_ = false;
1117 is_maximized_ = false;1146 is_maximized_ = false;
1118 is_desktop_focused_ = false;1147 is_desktop_focused_ = false;
1119 active_xid_ = 0;1148 Window active_xid = 0;
1120 bool force_refresh = false;
11211149
1122 sources_.Remove(WINDOW_MOVED_TIMEOUT);1150 sources_.Remove(WINDOW_MOVED_TIMEOUT);
11231151
1124 if (BAMF_IS_WINDOW(new_view))1152 if (BAMF_IS_WINDOW(new_view))
1125 {1153 {
1126 BamfWindow* window = reinterpret_cast<BamfWindow*>(new_view);1154 BamfWindow* window = reinterpret_cast<BamfWindow*>(new_view);
1127 active_xid_ = bamf_window_get_xid(window);1155 active_xid = bamf_window_get_xid(window);
1128 is_maximized_ = (bamf_window_maximized(window) == BAMF_WINDOW_MAXIMIZED);1156 is_maximized_ = (bamf_window_maximized(window) == BAMF_WINDOW_MAXIMIZED);
11291157
1130 if (bamf_window_get_window_type(window) == BAMF_WINDOW_DESKTOP)1158 if (bamf_window_get_window_type(window) == BAMF_WINDOW_DESKTOP)
1131 {1159 {
1132 is_desktop_focused_ = !GetMaximizedWindow();1160 is_desktop_focused_ = !maximized_window();
1133 we_control_active_ = true;1161 we_control_active_ = true;
1134 }1162 }
1135 else1163 else
1136 {1164 {
1137 we_control_active_ = IsWindowUnderOurControl(active_xid_);1165 we_control_active_ = IsWindowUnderOurControl(active_xid);
1138 }1166 }
11391167
1140 if (is_maximized_)1168 if (is_maximized_)
1141 {1169 {
1142 maximized_wins_.erase(std::remove(maximized_wins_.begin(), maximized_wins_.end(), active_xid_), maximized_wins_.end());1170 maximized_wins_.erase(std::remove(maximized_wins_.begin(), maximized_wins_.end(), active_xid), maximized_wins_.end());
1143 maximized_wins_.push_front(active_xid_);1171 maximized_wins_.push_front(active_xid);
1172 UpdateMaximizedWindow();
1144 }1173 }
11451174
1146 // register callback for new view1175 // register callback for new view
1147 view_name_changed_signal_.Connect(new_view, "name-changed",1176 view_name_changed_signal_.Connect(new_view, "name-changed",
1148 sigc::mem_fun(this, &PanelMenuView::OnNameChanged));1177 sigc::mem_fun(this, &PanelMenuView::OnNameChanged));
11491178 }
1150 if (integrated_menus_)1179
1151 force_refresh = is_maximized_;1180 active_window = active_xid;
1152 }1181
11531182 if (Refresh())
1154 if (!force_refresh && BAMF_IS_WINDOW(old_view) && integrated_menus_)
1155 force_refresh = (bamf_window_maximized(reinterpret_cast<BamfWindow*>(old_view)) == BAMF_WINDOW_MAXIMIZED);
1156
1157 if (ShouldDrawMenus())
1158 {
1159 // Wait 100ms before showing the menus again if we've just switched view
1160 // this is done because the menus are updated by the indicator with some
1161 // delay, and we don't want to see the previous menus and then the new ones
1162 ignore_menu_visibility_ = true;
1163 sources_.AddTimeout(100, [this] {
1164 ignore_menu_visibility_ = false;
1165 QueueDraw();
1166 return false;
1167 }, WINDOW_ACTIVATED_TIMEOUT);
1168 }
1169
1170 if (Refresh(force_refresh))
1171 FullRedraw();1183 FullRedraw();
1172}1184}
11731185
@@ -1198,8 +1210,9 @@
1198void PanelMenuView::OnWindowMinimized(Window xid)1210void PanelMenuView::OnWindowMinimized(Window xid)
1199{1211{
1200 maximized_wins_.erase(std::remove(maximized_wins_.begin(), maximized_wins_.end(), xid), maximized_wins_.end());1212 maximized_wins_.erase(std::remove(maximized_wins_.begin(), maximized_wins_.end(), xid), maximized_wins_.end());
1213 UpdateMaximizedWindow();
12011214
1202 if (xid == active_xid_)1215 if (xid == active_window())
1203 {1216 {
1204 if (Refresh())1217 if (Refresh())
1205 QueueDraw();1218 QueueDraw();
@@ -1213,10 +1226,13 @@
12131226
1214void PanelMenuView::OnWindowUnminimized(Window xid)1227void PanelMenuView::OnWindowUnminimized(Window xid)
1215{1228{
1216 if (xid == active_xid_)1229 if (xid == active_window())
1217 {1230 {
1218 if (WindowManager::Default().IsWindowMaximized(xid))1231 if (WindowManager::Default().IsWindowMaximized(xid))
1232 {
1219 maximized_wins_.push_front(xid);1233 maximized_wins_.push_front(xid);
1234 UpdateMaximizedWindow();
1235 }
12201236
1221 if (Refresh())1237 if (Refresh())
1222 QueueDraw();1238 QueueDraw();
@@ -1224,7 +1240,10 @@
1224 else1240 else
1225 {1241 {
1226 if (WindowManager::Default().IsWindowMaximized(xid))1242 if (WindowManager::Default().IsWindowMaximized(xid))
1243 {
1227 maximized_wins_.push_back(xid);1244 maximized_wins_.push_back(xid);
1245 UpdateMaximizedWindow();
1246 }
12281247
1229 if (integrated_menus_ && IsWindowUnderOurControl(xid))1248 if (integrated_menus_ && IsWindowUnderOurControl(xid))
1230 {1249 {
@@ -1239,8 +1258,9 @@
1239 // FIXME: compiz doesn't give us a valid xid (is always 0 on unmap)1258 // FIXME: compiz doesn't give us a valid xid (is always 0 on unmap)
1240 // we need to do this again on BamfView closed signal.1259 // we need to do this again on BamfView closed signal.
1241 maximized_wins_.erase(std::remove(maximized_wins_.begin(), maximized_wins_.end(), xid), maximized_wins_.end());1260 maximized_wins_.erase(std::remove(maximized_wins_.begin(), maximized_wins_.end(), xid), maximized_wins_.end());
1261 UpdateMaximizedWindow();
12421262
1243 if (xid == active_xid_)1263 if (xid == active_window())
1244 {1264 {
1245 if (Refresh())1265 if (Refresh())
1246 QueueDraw();1266 QueueDraw();
@@ -1256,9 +1276,10 @@
1256{1276{
1257 if (WindowManager::Default().IsWindowMaximized(xid))1277 if (WindowManager::Default().IsWindowMaximized(xid))
1258 {1278 {
1259 if (xid == active_xid_)1279 if (xid == active_window())
1260 {1280 {
1261 maximized_wins_.push_front(xid);1281 maximized_wins_.push_front(xid);
1282 UpdateMaximizedWindow();
12621283
1263 if (Refresh())1284 if (Refresh())
1264 QueueDraw();1285 QueueDraw();
@@ -1266,15 +1287,17 @@
1266 else1287 else
1267 {1288 {
1268 maximized_wins_.push_back(xid);1289 maximized_wins_.push_back(xid);
1290 UpdateMaximizedWindow();
1269 }1291 }
1270 }1292 }
1271}1293}
12721294
1273void PanelMenuView::OnWindowMaximized(Window xid)1295void PanelMenuView::OnWindowMaximized(Window xid)
1274{1296{
1275 if (xid == active_xid_)1297 if (xid == active_window())
1276 {1298 {
1277 maximized_wins_.push_front(xid);1299 maximized_wins_.push_front(xid);
1300 UpdateMaximizedWindow();
12781301
1279 // We need to update the is_inside_ state in the case of maximization by grab1302 // We need to update the is_inside_ state in the case of maximization by grab
1280 CheckMouseInside();1303 CheckMouseInside();
@@ -1286,6 +1309,7 @@
1286 else1309 else
1287 {1310 {
1288 maximized_wins_.push_back(xid);1311 maximized_wins_.push_back(xid);
1312 UpdateMaximizedWindow();
12891313
1290 if (integrated_menus_ && IsWindowUnderOurControl(xid))1314 if (integrated_menus_ && IsWindowUnderOurControl(xid))
1291 {1315 {
@@ -1298,8 +1322,9 @@
1298void PanelMenuView::OnWindowRestored(Window xid)1322void PanelMenuView::OnWindowRestored(Window xid)
1299{1323{
1300 maximized_wins_.erase(std::remove(maximized_wins_.begin(), maximized_wins_.end(), xid), maximized_wins_.end());1324 maximized_wins_.erase(std::remove(maximized_wins_.begin(), maximized_wins_.end(), xid), maximized_wins_.end());
1325 UpdateMaximizedWindow();
13011326
1302 if (active_xid_ == xid)1327 if (active_window() == xid)
1303 {1328 {
1304 is_maximized_ = false;1329 is_maximized_ = false;
1305 is_grabbed_ = false;1330 is_grabbed_ = false;
@@ -1316,13 +1341,13 @@
13161341
1317bool PanelMenuView::UpdateActiveWindowPosition()1342bool PanelMenuView::UpdateActiveWindowPosition()
1318{1343{
1319 bool we_control_window = IsWindowUnderOurControl(active_xid_);1344 bool we_control_window = IsWindowUnderOurControl(active_window);
13201345
1321 if (we_control_window != we_control_active_)1346 if (we_control_window != we_control_active_)
1322 {1347 {
1323 we_control_active_ = we_control_window;1348 we_control_active_ = we_control_window;
13241349
1325 if (!entries_.empty())1350 if (HasVisibleMenus())
1326 on_indicator_updated.emit();1351 on_indicator_updated.emit();
13271352
1328 if (Refresh())1353 if (Refresh())
@@ -1334,21 +1359,17 @@
13341359
1335void PanelMenuView::OnWindowMoved(Window xid)1360void PanelMenuView::OnWindowMoved(Window xid)
1336{1361{
1337 if (active_xid_ == xid)1362 if (!integrated_menus_ && active_window() == xid && UScreen::GetDefault()->GetMonitors().size() > 1)
1338 {1363 {
1339 /* When moving the active window, if the current panel is controlling1364 /* When moving the active window, if the current panel is controlling
1340 * the active window, then we postpone the timeout function every movement1365 * the active window, then we postpone the timeout function every movement
1341 * that we have, setting a longer timeout.1366 * that we have, setting a longer timeout.
1342 * Otherwise, if the moved window is not controlled by the current panel1367 * Otherwise, if the movedPanelMenuView::OnWindowMovedPanelMenuView::OnWindowMoved window is not controlled by the current panel
1343 * every few millisecond we check the new window position */1368 * every few millisecond we check the new window position */
13441369
1345 unsigned int timeout_length = 250;1370 unsigned int timeout_length = 250;
13461371
1347 if (we_control_active_)1372 if (!we_control_active_)
1348 {
1349 sources_.Remove(WINDOW_MOVED_TIMEOUT);
1350 }
1351 else
1352 {1373 {
1353 if (sources_.GetSource(WINDOW_MOVED_TIMEOUT))1374 if (sources_.GetSource(WINDOW_MOVED_TIMEOUT))
1354 return;1375 return;
@@ -1359,6 +1380,9 @@
1359 auto cb_func = sigc::mem_fun(this, &PanelMenuView::UpdateActiveWindowPosition);1380 auto cb_func = sigc::mem_fun(this, &PanelMenuView::UpdateActiveWindowPosition);
1360 sources_.AddTimeout(timeout_length, cb_func, WINDOW_MOVED_TIMEOUT);1381 sources_.AddTimeout(timeout_length, cb_func, WINDOW_MOVED_TIMEOUT);
1361 }1382 }
1383
1384 if (std::find(maximized_wins_.begin(), maximized_wins_.end(), xid) != maximized_wins_.end())
1385 UpdateMaximizedWindow();
1362}1386}
13631387
1364bool PanelMenuView::IsWindowUnderOurControl(Window xid) const1388bool PanelMenuView::IsWindowUnderOurControl(Window xid) const
@@ -1391,7 +1415,7 @@
1391 return false;1415 return false;
1392}1416}
13931417
1394Window PanelMenuView::GetMaximizedWindow() const1418void PanelMenuView::UpdateMaximizedWindow()
1395{1419{
1396 Window window_xid = 0;1420 Window window_xid = 0;
13971421
@@ -1406,7 +1430,7 @@
1406 }1430 }
1407 }1431 }
14081432
1409 return window_xid;1433 maximized_window = window_xid;
1410}1434}
14111435
1412Window PanelMenuView::GetTopWindow() const1436Window PanelMenuView::GetTopWindow() const
@@ -1466,11 +1490,14 @@
1466 if (!layout_->GetAbsoluteGeometry().IsInside(click))1490 if (!layout_->GetAbsoluteGeometry().IsInside(click))
1467 return;1491 return;
14681492
1469 unsigned double_click_wait = Settings::Instance().lim_double_click_wait();1493 auto& settings = Settings::Instance();
14701494
1471 if (double_click_wait > 0)1495 if (!focused && !settings.lim_unfocused_popup())
1496 return;
1497
1498 if (settings.lim_double_click_wait() > 0)
1472 {1499 {
1473 sources_.AddTimeout(double_click_wait, [this, click] {1500 sources_.AddTimeout(settings.lim_double_click_wait(), [this, click] {
1474 ActivateEntryAt(click.x, click.y);1501 ActivateEntryAt(click.x, click.y);
1475 return false;1502 return false;
1476 }, INTEGRATED_MENUS_DOUBLE_CLICK_TIMEOUT);1503 }, INTEGRATED_MENUS_DOUBLE_CLICK_TIMEOUT);
@@ -1489,15 +1516,18 @@
14891516
1490void PanelMenuView::OnMaximizedActivate(int x, int y)1517void PanelMenuView::OnMaximizedActivate(int x, int y)
1491{1518{
1492 Window maximized = GetMaximizedWindow();1519 Window maximized = maximized_window();
14931520
1494 if (maximized != 0)1521 if (maximized != 0)
1495 {1522 {
1496 if (maximized != active_xid_)1523 if (maximized != active_window())
1497 {1524 {
1498 WindowManager::Default().Activate(maximized);1525 auto& wm = WindowManager::Default();
1526 wm.Raise(maximized);
1527 wm.Activate(maximized);
1499 }1528 }
1500 else if (integrated_menus_)1529
1530 if (integrated_menus_)
1501 {1531 {
1502 // Adjusting the click coordinates to be absolute.1532 // Adjusting the click coordinates to be absolute.
1503 auto const& grab_geo = titlebar_grab_area_->GetAbsoluteGeometry();1533 auto const& grab_geo = titlebar_grab_area_->GetAbsoluteGeometry();
@@ -1509,7 +1539,7 @@
15091539
1510void PanelMenuView::MaximizedWindowWMAction(int x, int y, unsigned button)1540void PanelMenuView::MaximizedWindowWMAction(int x, int y, unsigned button)
1511{1541{
1512 Window maximized = GetMaximizedWindow();1542 Window maximized = maximized_window();
15131543
1514 if (!maximized)1544 if (!maximized)
1515 return;1545 return;
@@ -1590,7 +1620,7 @@
1590 * This is a workaround to avoid that the grid plugin would be fired1620 * This is a workaround to avoid that the grid plugin would be fired
1591 * showing the window shape preview effect. See bug #838923 */1621 * showing the window shape preview effect. See bug #838923 */
15921622
1593 Window maximized = GetMaximizedWindow();1623 Window maximized = maximized_window();
15941624
1595 if (maximized != 0)1625 if (maximized != 0)
1596 {1626 {
@@ -1611,7 +1641,7 @@
1611 x += titlebar_grab_area_->GetAbsoluteX();1641 x += titlebar_grab_area_->GetAbsoluteX();
1612 y += titlebar_grab_area_->GetAbsoluteY();1642 y += titlebar_grab_area_->GetAbsoluteY();
16131643
1614 Window maximized = GetMaximizedWindow();1644 Window maximized = maximized_window();
16151645
1616 /* When the drag goes out from the Panel, start the real movement.1646 /* When the drag goes out from the Panel, start the real movement.
1617 *1647 *
@@ -1686,6 +1716,8 @@
1686 PanelIndicatorsView::AddProperties(introspection);1716 PanelIndicatorsView::AddProperties(introspection);
16871717
1688 introspection1718 introspection
1719 .add("focused", focused())
1720 .add("integrated_menus", integrated_menus_)
1689 .add("mouse_inside", is_inside_)1721 .add("mouse_inside", is_inside_)
1690 .add("always_show_menus", always_show_menus_)1722 .add("always_show_menus", always_show_menus_)
1691 .add("grabbed", is_grabbed_)1723 .add("grabbed", is_grabbed_)
@@ -1694,7 +1726,8 @@
1694 .add("panel_title", panel_title_)1726 .add("panel_title", panel_title_)
1695 .add("desktop_active", (panel_title_ == desktop_name_))1727 .add("desktop_active", (panel_title_ == desktop_name_))
1696 .add("monitor", monitor_)1728 .add("monitor", monitor_)
1697 .add("active_window", active_xid_)1729 .add("active_window", active_window())
1730 .add("maximized_window", maximized_window())
1698 .add("draw_menus", ShouldDrawMenus())1731 .add("draw_menus", ShouldDrawMenus())
1699 .add("draw_window_buttons", ShouldDrawButtons())1732 .add("draw_window_buttons", ShouldDrawButtons())
1700 .add("controls_active_window", we_control_active_)1733 .add("controls_active_window", we_control_active_)
@@ -1833,32 +1866,19 @@
1833 auto xid = bamf_window_get_xid(window);1866 auto xid = bamf_window_get_xid(window);
18341867
1835 if (bamf_view_is_active(view))1868 if (bamf_view_is_active(view))
1836 active_xid_ = xid;1869 active_window = xid;
18371870
1838 if (bamf_window_maximized(window) == BAMF_WINDOW_MAXIMIZED)1871 if (bamf_window_maximized(window) == BAMF_WINDOW_MAXIMIZED)
1839 {1872 {
1840 if (xid == active_xid_)1873 if (xid == active_window())
1841 maximized_wins_.push_front(xid);1874 maximized_wins_.push_front(xid);
1842 else1875 else
1843 maximized_wins_.push_back(xid);1876 maximized_wins_.push_back(xid);
1844 }1877 }
1845 }1878 }
18461879
1847 Window maximized = GetMaximizedWindow();
1848 Window buttons_win = 0;
1849
1850 if (integrated_menus_)
1851 {
1852 buttons_win = maximized;
1853 window_buttons_->focused = (maximized == active_xid_);
1854 }
1855 else
1856 {
1857 buttons_win = (maximized == active_xid_) ? maximized : 0;
1858 }
1859
1860 window_buttons_->monitor = monitor_;1880 window_buttons_->monitor = monitor_;
1861 window_buttons_->controlled_window = buttons_win;1881 UpdateMaximizedWindow();
18621882
1863 OnStyleChanged();1883 OnStyleChanged();
1864 g_list_free(windows);1884 g_list_free(windows);
@@ -1866,7 +1886,15 @@
18661886
1867bool PanelMenuView::HasMenus() const1887bool PanelMenuView::HasMenus() const
1868{1888{
1869 if (entries_.empty())1889 if (!HasVisibleMenus())
1890 return false;
1891
1892 return integrated_menus_ || we_control_active_;
1893}
1894
1895bool PanelMenuView::HasKeyActivableMenus() const
1896{
1897 if (!HasVisibleMenus())
1870 return false;1898 return false;
18711899
1872 return integrated_menus_ ? is_maximized_ : we_control_active_;1900 return integrated_menus_ ? is_maximized_ : we_control_active_;
18731901
=== modified file 'panel/PanelMenuView.h'
--- panel/PanelMenuView.h 2014-12-19 12:09:16 +0000
+++ panel/PanelMenuView.h 2015-02-19 19:24:14 +0000
@@ -44,13 +44,17 @@
44 PanelMenuView(menu::Manager::Ptr const&);44 PanelMenuView(menu::Manager::Ptr const&);
45 ~PanelMenuView();45 ~PanelMenuView();
4646
47 nux::Property<Window> active_window;
48 nux::Property<Window> maximized_window;
49 nux::Property<bool> focused;
50
47 void SetMousePosition(int x, int y);51 void SetMousePosition(int x, int y);
48 void SetMonitor(int monitor) override;52 void SetMonitor(int monitor) override;
4953
50 Window GetTopWindow() const;54 Window GetTopWindow() const;
51 Window GetMaximizedWindow() const;
52 bool GetControlsActive() const;55 bool GetControlsActive() const;
53 bool HasMenus() const;56 bool HasMenus() const;
57 bool HasKeyActivableMenus() const;
5458
55 void NotifyAllMenusClosed();59 void NotifyAllMenusClosed();
5660
@@ -120,9 +124,9 @@
120 bool Refresh(bool force = false);124 bool Refresh(bool force = false);
121125
122 void UpdateTitleTexture(nux::Geometry const&, std::string const& label);126 void UpdateTitleTexture(nux::Geometry const&, std::string const& label);
123
124 void UpdateLastGeometry(nux::Geometry const& geo);127 void UpdateLastGeometry(nux::Geometry const& geo);
125 void UpdateTitleGradientTexture();128 void UpdateTitleGradientTexture();
129 void UpdateMaximizedWindow();
126130
127 void OnPanelViewMouseEnter(int x, int y, unsigned long mouse_button_state, unsigned long special_keys_state);131 void OnPanelViewMouseEnter(int x, int y, unsigned long mouse_button_state, unsigned long special_keys_state);
128 void OnPanelViewMouseLeave(int x, int y, unsigned long mouse_button_state, unsigned long special_keys_state);132 void OnPanelViewMouseLeave(int x, int y, unsigned long mouse_button_state, unsigned long special_keys_state);
@@ -134,6 +138,7 @@
134 void OnLauncherKeyNavEnded(GVariant* data);138 void OnLauncherKeyNavEnded(GVariant* data);
135 void OnLauncherSelectionChanged(GVariant* data);139 void OnLauncherSelectionChanged(GVariant* data);
136140
141 void UpdateTargetWindowItems();
137 void UpdateShowNow(bool ignore);142 void UpdateShowNow(bool ignore);
138 bool CheckMouseInside();143 bool CheckMouseInside();
139144
@@ -158,7 +163,7 @@
158163
159 void ActivateIntegratedMenus(nux::Point const&);164 void ActivateIntegratedMenus(nux::Point const&);
160165
161 menu::Manager::Ptr const& menu_manager_;166 menu::Manager::Ptr menu_manager_;
162 glib::Object<BamfMatcher> matcher_;167 glib::Object<BamfMatcher> matcher_;
163168
164 nux::TextureLayer* title_layer_;169 nux::TextureLayer* title_layer_;
@@ -190,7 +195,6 @@
190 bool integrated_menus_;195 bool integrated_menus_;
191 bool always_show_menus_;196 bool always_show_menus_;
192197
193 Window active_xid_;
194 nux::Geometry monitor_geo_;198 nux::Geometry monitor_geo_;
195 const std::string desktop_name_;199 const std::string desktop_name_;
196200
197201
=== modified file 'panel/PanelView.cpp'
--- panel/PanelView.cpp 2014-12-12 22:33:24 +0000
+++ panel/PanelView.cpp 2015-02-19 19:24:14 +0000
@@ -516,7 +516,7 @@
516516
517 if (opacity_maximized_toggle_)517 if (opacity_maximized_toggle_)
518 {518 {
519 Window maximized_win = menu_view_->GetMaximizedWindow();519 Window maximized_win = menu_view_->maximized_window();
520520
521 if (wm.IsExpoActive() || (maximized_win != 0 && !wm.IsWindowObscured(maximized_win)))521 if (wm.IsExpoActive() || (maximized_win != 0 && !wm.IsWindowObscured(maximized_win)))
522 opacity = 1.0f;522 opacity = 1.0f;
@@ -673,7 +673,7 @@
673 if (!IsActive())673 if (!IsActive())
674 return false;674 return false;
675675
676 if ((menu_view_->HasMenus() && menu_view_->ActivateIfSensitive()) ||676 if ((menu_view_->HasKeyActivableMenus() && menu_view_->ActivateIfSensitive()) ||
677 indicators_->ActivateIfSensitive())677 indicators_->ActivateIfSensitive())
678 {678 {
679 // Since this only happens on keyboard events, we need to prevent that the679 // Since this only happens on keyboard events, we need to prevent that the
@@ -690,7 +690,7 @@
690 if (!IsActive())690 if (!IsActive())
691 return false;691 return false;
692692
693 if ((menu_view_->HasMenus() && menu_view_->ActivateEntry(entry_id, 0)) ||693 if ((menu_view_->HasKeyActivableMenus() && menu_view_->ActivateEntry(entry_id, 0)) ||
694 indicators_->ActivateEntry(entry_id, 0))694 indicators_->ActivateEntry(entry_id, 0))
695 {695 {
696 // Since this only happens on keyboard events, we need to prevent that the696 // Since this only happens on keyboard events, we need to prevent that the
697697
=== modified file 'plugins/unityshell/src/unityshell.cpp'
--- plugins/unityshell/src/unityshell.cpp 2015-01-22 22:37:32 +0000
+++ plugins/unityshell/src/unityshell.cpp 2015-02-19 19:24:14 +0000
@@ -157,6 +157,7 @@
157 , cScreen(CompositeScreen::get(screen))157 , cScreen(CompositeScreen::get(screen))
158 , gScreen(GLScreen::get(screen))158 , gScreen(GLScreen::get(screen))
159 , sScreen(ScaleScreen::get(screen))159 , sScreen(ScaleScreen::get(screen))
160 , WM(PluginAdapter::Initialize(screen))
160 , menus_(std::make_shared<menu::Manager>(std::make_shared<indicator::DBusIndicators>(), std::make_shared<key::GnomeGrabber>()))161 , menus_(std::make_shared<menu::Manager>(std::make_shared<indicator::DBusIndicators>(), std::make_shared<key::GnomeGrabber>()))
161 , deco_manager_(std::make_shared<decoration::Manager>(menus_))162 , deco_manager_(std::make_shared<decoration::Manager>(menus_))
162 , debugger_(this)163 , debugger_(this)
@@ -281,9 +282,6 @@
281 ScaleScreenInterface::setHandler(sScreen);282 ScaleScreenInterface::setHandler(sScreen);
282 screen->updateSupportedWmHints();283 screen->updateSupportedWmHints();
283284
284 PluginAdapter::Initialize(screen);
285 AddChild(&WindowManager::Default());
286
287 nux::NuxInitialize(0);285 nux::NuxInitialize(0);
288#ifndef USE_GLES286#ifndef USE_GLES
289 wt.reset(nux::CreateFromForeignWindow(cScreen->output(),287 wt.reset(nux::CreateFromForeignWindow(cScreen->output(),
@@ -442,13 +440,13 @@
442 sigc::mem_fun(this, &UnityScreen::OnMinimizeDurationChanged)440 sigc::mem_fun(this, &UnityScreen::OnMinimizeDurationChanged)
443 );441 );
444442
445 WindowManager& wm = WindowManager::Default();443 WM.initiate_spread.connect(sigc::mem_fun(this, &UnityScreen::OnInitiateSpread));
446 wm.initiate_spread.connect(sigc::mem_fun(this, &UnityScreen::OnInitiateSpread));444 WM.terminate_spread.connect(sigc::mem_fun(this, &UnityScreen::OnTerminateSpread));
447 wm.terminate_spread.connect(sigc::mem_fun(this, &UnityScreen::OnTerminateSpread));445 WM.initiate_expo.connect(sigc::mem_fun(this, &UnityScreen::DamagePanelShadow));
448 wm.initiate_expo.connect(sigc::mem_fun(this, &UnityScreen::DamagePanelShadow));446 WM.terminate_expo.connect(sigc::mem_fun(this, &UnityScreen::DamagePanelShadow));
449 wm.terminate_expo.connect(sigc::mem_fun(this, &UnityScreen::DamagePanelShadow));
450447
451 AddChild(&screen_introspection_);448 Introspectable::AddChild(&WM);
449 Introspectable::AddChild(&screen_introspection_);
452450
453 /* Create blur backup texture */451 /* Create blur backup texture */
454 auto gpu_device = nux::GetGraphicsDisplay()->GetGpuDevice();452 auto gpu_device = nux::GetGraphicsDisplay()->GetGpuDevice();
@@ -687,7 +685,7 @@
687 if (sources_.GetSource(local::RELAYOUT_TIMEOUT))685 if (sources_.GetSource(local::RELAYOUT_TIMEOUT))
688 return;686 return;
689687
690 if (WindowManager::Default().IsExpoActive())688 if (WM.IsExpoActive())
691 return;689 return;
692690
693 CompOutput* output = _last_output;691 CompOutput* output = _last_output;
@@ -948,7 +946,7 @@
948 nux::TexCoordXForm texxform;946 nux::TexCoordXForm texxform;
949 texxform.SetWrap(nux::TEXWRAP_REPEAT, nux::TEXWRAP_CLAMP);947 texxform.SetWrap(nux::TEXWRAP_REPEAT, nux::TEXWRAP_CLAMP);
950948
951 int monitor = WindowManager::Default().MonitorGeometryIn(NuxGeometryFromCompRect(output_dev));949 int monitor = WM.MonitorGeometryIn(NuxGeometryFromCompRect(output_dev));
952 auto const& texture = panel_style_.GetBackground(monitor)->GetDeviceTexture();950 auto const& texture = panel_style_.GetBackground(monitor)->GetDeviceTexture();
953 graphics_engine->QRP_GLSL_1Tex(0, 0, output_dev.width(), texture->GetHeight(), texture, texxform, nux::color::White);951 graphics_engine->QRP_GLSL_1Tex(0, 0, output_dev.width(), texture->GetHeight(), texture, texxform, nux::color::White);
954}952}
@@ -961,7 +959,7 @@
961 hud_controller_->IsVisible() ||959 hud_controller_->IsVisible() ||
962 session_controller_->Visible() ||960 session_controller_->Visible() ||
963 ((switcher_controller_->Visible() ||961 ((switcher_controller_->Visible() ||
964 WindowManager::Default().IsExpoActive())962 WM.IsExpoActive())
965 && !fullscreen_windows_.empty () && (!(screen->grabbed () && !screen->otherGrabExist (NULL))));963 && !fullscreen_windows_.empty () && (!(screen->grabbed () && !screen->otherGrabExist (NULL))));
966}964}
967965
@@ -2219,7 +2217,7 @@
2219 CompAction::State state,2217 CompAction::State state,
2220 CompOption::Vector& options)2218 CompOption::Vector& options)
2221{2219{
2222 WindowManager::Default().ShowDesktop();2220 WM.ShowDesktop();
2223 return true;2221 return true;
2224}2222}
22252223
@@ -2323,7 +2321,7 @@
2323 CompAction::State state,2321 CompAction::State state,
2324 CompOption::Vector& options)2322 CompOption::Vector& options)
2325{2323{
2326 if (WindowManager::Default().IsWallActive())2324 if (WM.IsWallActive())
2327 return false;2325 return false;
2328 else if (switcher_controller_->Visible())2326 else if (switcher_controller_->Visible())
2329 switcher_controller_->Next();2327 switcher_controller_->Next();
@@ -2531,11 +2529,9 @@
2531 if (QuicklistManager::Default()->Current())2529 if (QuicklistManager::Default()->Current())
2532 QuicklistManager::Default()->Current()->Hide();2530 QuicklistManager::Default()->Current()->Hide();
25332531
2534 auto& wm = WindowManager::Default();2532 if (WM.IsScreenGrabbed())
2535
2536 if (wm.IsScreenGrabbed())
2537 {2533 {
2538 hud_ungrab_slot_ = wm.screen_ungrabbed.connect([this] { ShowHud(); });2534 hud_ungrab_slot_ = WM.screen_ungrabbed.connect([this] { ShowHud(); });
25392535
2540 // Let's wait ungrab event for maximum a couple of seconds...2536 // Let's wait ungrab event for maximum a couple of seconds...
2541 sources_.AddTimeoutSeconds(2, [this] {2537 sources_.AddTimeoutSeconds(2, [this] {
@@ -2664,7 +2660,7 @@
2664 KeySym keysym = XkbKeycodeToKeysym(screen->dpy(), keybind.keycode(), 0, 0);2660 KeySym keysym = XkbKeycodeToKeysym(screen->dpy(), keybind.keycode(), 0, 0);
2665 unsigned modifiers = CompizModifiersToNux(keybind.modifiers());2661 unsigned modifiers = CompizModifiersToNux(keybind.modifiers());
26662662
2667 WindowManager::Default().close_window_key = std::make_pair(modifiers, keysym);2663 WM.close_window_key = std::make_pair(modifiers, keysym);
2668}2664}
26692665
2670void UnityScreen::UpdateActivateIndicatorsKey()2666void UnityScreen::UpdateActivateIndicatorsKey()
@@ -2673,7 +2669,7 @@
2673 KeySym keysym = XkbKeycodeToKeysym(screen->dpy(), keybind.keycode(), 0, 0);2669 KeySym keysym = XkbKeycodeToKeysym(screen->dpy(), keybind.keycode(), 0, 0);
2674 unsigned modifiers = CompizModifiersToNux(keybind.modifiers());2670 unsigned modifiers = CompizModifiersToNux(keybind.modifiers());
26752671
2676 WindowManager::Default().activate_indicators_key = std::make_pair(modifiers, keysym);2672 WM.activate_indicators_key = std::make_pair(modifiers, keysym);
2677}2673}
26782674
2679bool UnityScreen::initPluginActions()2675bool UnityScreen::initPluginActions()
@@ -2926,7 +2922,7 @@
2926 }2922 }
2927 }2923 }
29282924
2929 if (WindowManager::Default().IsScaleActive() &&2925 if (uScreen->WM.IsScaleActive() &&
2930 uScreen->sScreen->getSelectedWindow() == window->id())2926 uScreen->sScreen->getSelectedWindow() == window->id())
2931 {2927 {
2932 nux::Geometry const& scaled_geo = GetScaledGeometry();2928 nux::Geometry const& scaled_geo = GetScaledGeometry();
@@ -3027,9 +3023,8 @@
3027 !(window_state & CompWindowStateFullscreenMask) &&3023 !(window_state & CompWindowStateFullscreenMask) &&
3028 !(window_type & CompWindowTypeFullscreenMask))3024 !(window_type & CompWindowTypeFullscreenMask))
3029 {3025 {
3030 WindowManager& wm = WindowManager::Default();
3031 auto const& output = uScreen->screen->currentOutputDev();3026 auto const& output = uScreen->screen->currentOutputDev();
3032 int monitor = wm.MonitorGeometryIn(NuxGeometryFromCompRect(output));3027 int monitor = uScreen->WM.MonitorGeometryIn(NuxGeometryFromCompRect(output));
30333028
3034 if (window->y() - window->border().top < output.y() + uScreen->panel_style_.PanelHeight(monitor))3029 if (window->y() - window->border().top < output.y() + uScreen->panel_style_.PanelHeight(monitor))
3035 {3030 {
@@ -3662,8 +3657,7 @@
3662 {3657 {
3663 if (strcmp(name, "hsize") == 0 || strcmp(name, "vsize") == 0)3658 if (strcmp(name, "hsize") == 0 || strcmp(name, "vsize") == 0)
3664 {3659 {
3665 WindowManager& wm = WindowManager::Default();3660 WM.viewport_layout_changed.emit(screen->vpSize().width(), screen->vpSize().height());
3666 wm.viewport_layout_changed.emit(screen->vpSize().width(), screen->vpSize().height());
3667 }3661 }
3668 else if (strcmp(name, "close_window_key") == 0)3662 else if (strcmp(name, "close_window_key") == 0)
3669 {3663 {
@@ -3779,13 +3773,11 @@
3779 if (QuicklistManager::Default()->Current())3773 if (QuicklistManager::Default()->Current())
3780 QuicklistManager::Default()->Current()->Hide();3774 QuicklistManager::Default()->Current()->Hide();
37813775
3782 auto& wm = WindowManager::Default();3776 if (WM.IsScaleActive())
37833777 WM.TerminateScale();
3784 if (wm.IsScaleActive())3778
3785 wm.TerminateScale();3779 if (WM.IsExpoActive())
37863780 WM.TerminateExpo();
3787 if (wm.IsExpoActive())
3788 wm.TerminateExpo();
37893781
3790 RaiseOSK();3782 RaiseOSK();
3791}3783}
@@ -3889,24 +3881,24 @@
3889 edge_barriers_ = std::make_shared<ui::EdgeBarrierController>();3881 edge_barriers_ = std::make_shared<ui::EdgeBarrierController>();
38903882
3891 launcher_controller_ = std::make_shared<launcher::Controller>(xdnd_manager, edge_barriers_);3883 launcher_controller_ = std::make_shared<launcher::Controller>(xdnd_manager, edge_barriers_);
3892 AddChild(launcher_controller_.get());3884 Introspectable::AddChild(launcher_controller_.get());
38933885
3894 switcher_controller_ = std::make_shared<switcher::Controller>();3886 switcher_controller_ = std::make_shared<switcher::Controller>();
3895 switcher_controller_->detail.changed.connect(sigc::mem_fun(this, &UnityScreen::OnSwitcherDetailChanged));3887 switcher_controller_->detail.changed.connect(sigc::mem_fun(this, &UnityScreen::OnSwitcherDetailChanged));
3896 AddChild(switcher_controller_.get());3888 Introspectable::AddChild(switcher_controller_.get());
38973889
3898 LOG_INFO(logger) << "initLauncher-Launcher " << timer.ElapsedSeconds() << "s";3890 LOG_INFO(logger) << "initLauncher-Launcher " << timer.ElapsedSeconds() << "s";
38993891
3900 /* Setup panel */3892 /* Setup panel */
3901 timer.Reset();3893 timer.Reset();
3902 panel_controller_ = std::make_shared<panel::Controller>(menus_, edge_barriers_);3894 panel_controller_ = std::make_shared<panel::Controller>(menus_, edge_barriers_);
3903 AddChild(panel_controller_.get());3895 Introspectable::AddChild(panel_controller_.get());
3904 LOG_INFO(logger) << "initLauncher-Panel " << timer.ElapsedSeconds() << "s";3896 LOG_INFO(logger) << "initLauncher-Panel " << timer.ElapsedSeconds() << "s";
39053897
3906 /* Setup Places */3898 /* Setup Places */
3907 dash_controller_ = std::make_shared<dash::Controller>();3899 dash_controller_ = std::make_shared<dash::Controller>();
3908 dash_controller_->on_realize.connect(sigc::mem_fun(this, &UnityScreen::OnDashRealized));3900 dash_controller_->on_realize.connect(sigc::mem_fun(this, &UnityScreen::OnDashRealized));
3909 AddChild(dash_controller_.get());3901 Introspectable::AddChild(dash_controller_.get());
39103902
3911 /* Setup Hud */3903 /* Setup Hud */
3912 hud_controller_ = std::make_shared<hud::Controller>();3904 hud_controller_ = std::make_shared<hud::Controller>();
@@ -3915,14 +3907,14 @@
3915 hud_controller_->multiple_launchers = (optionGetNumLaunchers() == 0);3907 hud_controller_->multiple_launchers = (optionGetNumLaunchers() == 0);
3916 hud_controller_->icon_size = launcher_controller_->options()->icon_size();3908 hud_controller_->icon_size = launcher_controller_->options()->icon_size();
3917 hud_controller_->tile_size = launcher_controller_->options()->tile_size();3909 hud_controller_->tile_size = launcher_controller_->options()->tile_size();
3918 AddChild(hud_controller_.get());3910 Introspectable::AddChild(hud_controller_.get());
3919 LOG_INFO(logger) << "initLauncher-hud " << timer.ElapsedSeconds() << "s";3911 LOG_INFO(logger) << "initLauncher-hud " << timer.ElapsedSeconds() << "s";
39203912
3921 // Setup Shortcut Hint3913 // Setup Shortcut Hint
3922 auto base_window_raiser = std::make_shared<shortcut::BaseWindowRaiserImp>();3914 auto base_window_raiser = std::make_shared<shortcut::BaseWindowRaiserImp>();
3923 auto shortcuts_modeller = std::make_shared<shortcut::CompizModeller>();3915 auto shortcuts_modeller = std::make_shared<shortcut::CompizModeller>();
3924 shortcut_controller_ = std::make_shared<shortcut::Controller>(base_window_raiser, shortcuts_modeller);3916 shortcut_controller_ = std::make_shared<shortcut::Controller>(base_window_raiser, shortcuts_modeller);
3925 AddChild(shortcut_controller_.get());3917 Introspectable::AddChild(shortcut_controller_.get());
3926 ShowFirstRunHints();3918 ShowFirstRunHints();
39273919
3928 // Setup Session Controller3920 // Setup Session Controller
@@ -3933,7 +3925,7 @@
3933 manager->unlocked.connect(sigc::mem_fun(this, &UnityScreen::OnScreenUnlocked));3925 manager->unlocked.connect(sigc::mem_fun(this, &UnityScreen::OnScreenUnlocked));
3934 session_dbus_manager_ = std::make_shared<session::DBusManager>(manager);3926 session_dbus_manager_ = std::make_shared<session::DBusManager>(manager);
3935 session_controller_ = std::make_shared<session::Controller>(manager);3927 session_controller_ = std::make_shared<session::Controller>(manager);
3936 AddChild(session_controller_.get());3928 Introspectable::AddChild(session_controller_.get());
39373929
3938 // Setup Lockscreen Controller3930 // Setup Lockscreen Controller
3939 screensaver_dbus_manager_ = std::make_shared<lockscreen::DBusManager>(manager);3931 screensaver_dbus_manager_ = std::make_shared<lockscreen::DBusManager>(manager);
@@ -4119,7 +4111,7 @@
4119 window->minimizedSetEnabled (this, false);4111 window->minimizedSetEnabled (this, false);
4120 }4112 }
41214113
4122 /* Keep this after the optionGetShowMinimizedWindows branch */4114 /* Keep this after the optionGetShowMIntrospectable.hinimizedWindows branch */
41234115
4124 if (window->state() & CompWindowStateFullscreenMask)4116 if (window->state() & CompWindowStateFullscreenMask)
4125 uScreen->fullscreen_windows_.push_back(window);4117 uScreen->fullscreen_windows_.push_back(window);
@@ -4136,8 +4128,8 @@
4136{4128{
4137 Window xid = window->id();4129 Window xid = window->id();
4138 auto const& swins = uScreen->sScreen->getWindows();4130 auto const& swins = uScreen->sScreen->getWindows();
4131 WindowManager& wm = uScreen->WM;
4139 bool scaled = std::find(swins.begin(), swins.end(), ScaleWindow::get(window)) != swins.end();4132 bool scaled = std::find(swins.begin(), swins.end(), ScaleWindow::get(window)) != swins.end();
4140 WindowManager& wm = WindowManager::Default();
41414133
4142 introspection4134 introspection
4143 .add(scaled ? GetScaledGeometry() : wm.GetWindowGeometry(xid))4135 .add(scaled ? GetScaledGeometry() : wm.GetWindowGeometry(xid))
@@ -4373,9 +4365,7 @@
43734365
4374nux::Geometry UnityWindow::GetScaledGeometry()4366nux::Geometry UnityWindow::GetScaledGeometry()
4375{4367{
4376 WindowManager& wm = WindowManager::Default();4368 if (!uScreen->WM.IsScaleActive())
4377
4378 if (!wm.IsScaleActive())
4379 return nux::Geometry();4369 return nux::Geometry();
43804370
4381 ScaleWindow* scale_win = ScaleWindow::get(window);4371 ScaleWindow* scale_win = ScaleWindow::get(window);
43824372
=== modified file 'plugins/unityshell/src/unityshell.h'
--- plugins/unityshell/src/unityshell.h 2014-12-12 20:44:52 +0000
+++ plugins/unityshell/src/unityshell.h 2015-02-19 19:24:14 +0000
@@ -332,6 +332,7 @@
332332
333 /* The window thread should be the last thing removed, as c++ does it in reverse order */333 /* The window thread should be the last thing removed, as c++ does it in reverse order */
334 std::unique_ptr<nux::WindowThread> wt;334 std::unique_ptr<nux::WindowThread> wt;
335 WindowManager& WM;
335336
336 menu::Manager::Ptr menus_;337 menu::Manager::Ptr menus_;
337 std::shared_ptr<decoration::Manager> deco_manager_;338 std::shared_ptr<decoration::Manager> deco_manager_;
@@ -368,7 +369,7 @@
368 typedef std::vector<CompActionPtr> ShortcutActions;369 typedef std::vector<CompActionPtr> ShortcutActions;
369 ShortcutActions _shortcut_actions;370 ShortcutActions _shortcut_actions;
370 std::map<CancelActionTarget, CompActionPtr> _escape_actions;371 std::map<CancelActionTarget, CompActionPtr> _escape_actions;
371 std::map<int, unsigned int> windows_for_monitor_;372 std::unordered_map<int, unsigned int> windows_for_monitor_;
372373
373 /* keyboard-nav mode */374 /* keyboard-nav mode */
374 CompWindow* newFocusedWindow;375 CompWindow* newFocusedWindow;
375376
=== modified file 'services/panel-main.c'
--- services/panel-main.c 2014-11-04 14:25:04 +0000
+++ services/panel-main.c 2015-02-19 19:24:14 +0000
@@ -27,20 +27,21 @@
27#include "config.h"27#include "config.h"
28#include "panel-a11y.h"28#include "panel-a11y.h"
29#include "panel-service.h"29#include "panel-service.h"
30#include "panel-service-private.h"
3031
31static GDBusNodeInfo *introspection_data = NULL;32static GDBusNodeInfo *introspection_data = NULL;
3233
33static const gchar introspection_xml[] =34static const gchar introspection_xml[] =
34 "<node>"35 "<node>"
35 " <interface name='com.canonical.Unity.Panel.Service'>"36 " <interface name='"UPS_IFACE"'>"
36 ""37 ""
37 " <method name='Sync'>"38 " <method name='Sync'>"
38 " <arg type='a(ssssbbusbbi)' name='state' direction='out'/>"39 " <arg type='"ENTRY_ARRAY_SIGNATURE"' name='state' direction='out'/>"
39 " </method>"40 " </method>"
40 ""41 ""
41 " <method name='SyncOne'>"42 " <method name='SyncOne'>"
42 " <arg type='s' name='indicator_id' direction='in'/>"43 " <arg type='s' name='indicator_id' direction='in'/>"
43 " <arg type='a(ssssbbusbbi)' name='state' direction='out'/>"44 " <arg type='"ENTRY_ARRAY_SIGNATURE"' name='state' direction='out'/>"
44 " </method>"45 " </method>"
45 ""46 ""
46 " <method name='SyncGeometries'>"47 " <method name='SyncGeometries'>"
@@ -110,10 +111,6 @@
110 " </interface>"111 " </interface>"
111 "</node>";112 "</node>";
112113
113#define S_NAME_DESKTOP "com.canonical.Unity.Panel.Service.Desktop"
114#define S_NAME_LOCKSCREEN "com.canonical.Unity.Panel.Service.LockScreen"
115#define S_PATH "/com/canonical/Unity/Panel/Service"
116#define S_IFACE "com.canonical.Unity.Panel.Service"
117114
118/* Forwards */115/* Forwards */
119static void116static void
@@ -271,8 +268,8 @@
271 GError *error = NULL;268 GError *error = NULL;
272 g_dbus_connection_emit_signal (connection,269 g_dbus_connection_emit_signal (connection,
273 NULL,270 NULL,
274 S_PATH,271 UPS_PATH,
275 S_IFACE,272 UPS_IFACE,
276 "ReSync",273 "ReSync",
277 g_variant_new ("(s)", indicator_id),274 g_variant_new ("(s)", indicator_id),
278 &error);275 &error);
@@ -293,10 +290,13 @@
293 GError *error = NULL;290 GError *error = NULL;
294 g_dbus_connection_emit_signal (connection,291 g_dbus_connection_emit_signal (connection,
295 NULL,292 NULL,
296 S_PATH,293 UPS_PATH,
297 S_IFACE,294 UPS_IFACE,
298 "EntryActivated",295 "EntryActivated",
299 g_variant_new ("(ss(iiuu))", panel_id, entry_id, x, y, w, h),296 g_variant_new ("(ss(iiuu))",
297 panel_id ? panel_id : "",
298 entry_id ? entry_id : "",
299 x, y, w, h),
300 &error);300 &error);
301301
302 if (error)302 if (error)
@@ -316,8 +316,8 @@
316316
317 g_dbus_connection_emit_signal (connection,317 g_dbus_connection_emit_signal (connection,
318 NULL,318 NULL,
319 S_PATH,319 UPS_PATH,
320 S_IFACE,320 UPS_IFACE,
321 "EntryActivateRequest",321 "EntryActivateRequest",
322 g_variant_new ("(s)", entry_id),322 g_variant_new ("(s)", entry_id),
323 &error);323 &error);
@@ -338,8 +338,8 @@
338 GError *error = NULL;338 GError *error = NULL;
339 g_dbus_connection_emit_signal (connection,339 g_dbus_connection_emit_signal (connection,
340 NULL,340 NULL,
341 S_PATH,341 UPS_PATH,
342 S_IFACE,342 UPS_IFACE,
343 "EntryShowNowChanged",343 "EntryShowNowChanged",
344 g_variant_new ("(sb)", entry_id, show_now_state),344 g_variant_new ("(sb)", entry_id, show_now_state),
345 &error);345 &error);
@@ -357,8 +357,8 @@
357 GError *error = NULL;357 GError *error = NULL;
358 g_dbus_connection_emit_signal (connection,358 g_dbus_connection_emit_signal (connection,
359 NULL,359 NULL,
360 S_PATH,360 UPS_PATH,
361 S_IFACE,361 UPS_IFACE,
362 "IconPathsChanged",362 "IconPathsChanged",
363 NULL,363 NULL,
364 &error);364 &error);
@@ -379,7 +379,7 @@
379 guint reg_id;379 guint reg_id;
380380
381 reg_id = g_dbus_connection_register_object (connection,381 reg_id = g_dbus_connection_register_object (connection,
382 S_PATH,382 UPS_PATH,
383 introspection_data->interfaces[0],383 introspection_data->interfaces[0],
384 &interface_vtable,384 &interface_vtable,
385 service,385 service,
@@ -485,7 +485,7 @@
485 service = panel_service_get_default ();485 service = panel_service_get_default ();
486486
487 owner_id = g_bus_own_name (G_BUS_TYPE_SESSION,487 owner_id = g_bus_own_name (G_BUS_TYPE_SESSION,
488 !lockscreen_mode ? S_NAME_DESKTOP : S_NAME_LOCKSCREEN,488 !lockscreen_mode ? UPS_NAME_DESKTOP : UPS_NAME_LOCKSCREEN,
489 G_BUS_NAME_OWNER_FLAGS_NONE,489 G_BUS_NAME_OWNER_FLAGS_NONE,
490 on_bus_acquired,490 on_bus_acquired,
491 on_name_acquired,491 on_name_acquired,
492492
=== modified file 'services/panel-service-private.h'
--- services/panel-service-private.h 2013-10-03 15:15:35 +0000
+++ services/panel-service-private.h 2015-02-19 19:24:14 +0000
@@ -21,9 +21,27 @@
2121
22#include <X11/Xlib.h>22#include <X11/Xlib.h>
23#include <X11/keysym.h>23#include <X11/keysym.h>
24#include <glib.h>
2425
25G_BEGIN_DECLS26G_BEGIN_DECLS
2627
28#ifdef __cplusplus
29extern "C" {
30#endif
31
32#define UPS_NAME_DESKTOP "com.canonical.Unity.Panel.Service.Desktop"
33#define UPS_NAME_LOCKSCREEN "com.canonical.Unity.Panel.Service.LockScreen"
34#define UPS_PATH "/com/canonical/Unity/Panel/Service"
35#define UPS_IFACE "com.canonical.Unity.Panel.Service"
36
37#define APPMENU_INDICATOR_NAME "libappmenu.so"
38
39#define ENTRY_SIGNATURE "(sssusbbusbbi)"
40#define ENTRY_ARRAY_SIGNATURE "a" ENTRY_SIGNATURE ""
41
42#define AltMask Mod1Mask
43#define SuperMask Mod4Mask
44
27typedef struct _KeyBinding45typedef struct _KeyBinding
28{46{
29 KeySym key;47 KeySym key;
@@ -31,11 +49,12 @@
31 guint32 modifiers;49 guint32 modifiers;
32} KeyBinding;50} KeyBinding;
3351
34#define AltMask Mod1Mask
35#define SuperMask Mod4Mask
36
37void parse_string_keybinding (const char *, KeyBinding *);52void parse_string_keybinding (const char *, KeyBinding *);
3853
54#ifdef __cplusplus
55}
56#endif
57
39G_END_DECLS58G_END_DECLS
4059
41#endif /* _PANEL_SERVICE_PRIVATE_H_ */60#endif /* _PANEL_SERVICE_PRIVATE_H_ */
4261
=== modified file 'services/panel-service.c'
--- services/panel-service.c 2014-11-28 12:55:58 +0000
+++ services/panel-service.c 2015-02-19 19:24:14 +0000
@@ -43,7 +43,7 @@
4343
44#define NOTIFY_TIMEOUT 8044#define NOTIFY_TIMEOUT 80
45#define N_TIMEOUT_SLOTS 5045#define N_TIMEOUT_SLOTS 50
46#define MAX_INDICATOR_ENTRIES 10046#define MAX_INDICATOR_ENTRIES 500
4747
48#define NUX_VERTICAL_SCROLL_DELTA 12048#define NUX_VERTICAL_SCROLL_DELTA 120
49#define NUX_HORIZONTAL_SCROLL_DELTA (NUX_VERTICAL_SCROLL_DELTA ^ 2)49#define NUX_HORIZONTAL_SCROLL_DELTA (NUX_VERTICAL_SCROLL_DELTA ^ 2)
@@ -61,10 +61,13 @@
61{61{
62 GSList *indicators;62 GSList *indicators;
63 GSList *dropdown_entries;63 GSList *dropdown_entries;
64 GSList *removed_entries;
64 GHashTable *id2entry_hash;65 GHashTable *id2entry_hash;
65 GHashTable *panel2entries_hash;66 GHashTable *panel2entries_hash;
67 IndicatorObject *appmenu_indicator;
6668
67 gint32 timeouts[N_TIMEOUT_SLOTS];69 guint timeouts[N_TIMEOUT_SLOTS];
70 guint remove_idle;
6871
69 IndicatorObjectEntry *last_entry;72 IndicatorObjectEntry *last_entry;
70 IndicatorObjectEntry *last_dropdown_entry;73 IndicatorObjectEntry *last_dropdown_entry;
@@ -104,14 +107,14 @@
104107
105enum108enum
106{109{
107 SYNC_WAITING = -1,110 SYNC_WAITING = G_MAXUINT,
108 SYNC_NEUTRAL = 0,111 SYNC_NEUTRAL = 0,
109};112};
110113
111static guint32 _service_signals[LAST_SIGNAL] = { 0 };114static guint32 _service_signals[LAST_SIGNAL] = { 0 };
112115
113static const gchar * indicator_order[][2] = {116static const gchar * indicator_order[][2] = {
114 {"libappmenu.so", NULL}, /* indicator-appmenu" */117 {APPMENU_INDICATOR_NAME, NULL}, /* indicator-appmenu" */
115 {"libapplication.so", NULL}, /* indicator-application" */118 {"libapplication.so", NULL}, /* indicator-application" */
116 {"floating-indicators", NULL}, /* position-less NG indicators */119 {"floating-indicators", NULL}, /* position-less NG indicators */
117 {"libprintersmenu.so", NULL}, /* indicator-printers */120 {"libprintersmenu.so", NULL}, /* indicator-printers */
@@ -136,6 +139,8 @@
136static void notify_object (IndicatorObject *object);139static void notify_object (IndicatorObject *object);
137static void update_keybinding (GSettings *, const gchar *, gpointer);140static void update_keybinding (GSettings *, const gchar *, gpointer);
138static void emit_upstart_event (const gchar *);141static void emit_upstart_event (const gchar *);
142static gchar * get_indicator_entry_id_by_entry (IndicatorObjectEntry *entry);
143static IndicatorObjectEntry * get_indicator_entry_by_id (PanelService *self, const gchar *entry_id);
139static GdkFilterReturn event_filter (GdkXEvent *, GdkEvent *, PanelService *);144static GdkFilterReturn event_filter (GdkXEvent *, GdkEvent *, PanelService *);
140145
141/*146/*
@@ -164,7 +169,7 @@
164169
165 for (i = 0; i < N_TIMEOUT_SLOTS; i++)170 for (i = 0; i < N_TIMEOUT_SLOTS; i++)
166 {171 {
167 if (priv->timeouts[i] > 0)172 if (priv->timeouts[i] > 0 && priv->timeouts[i] != SYNC_WAITING)
168 {173 {
169 g_source_remove (priv->timeouts[i]);174 g_source_remove (priv->timeouts[i]);
170 priv->timeouts[i] = 0;175 priv->timeouts[i] = 0;
@@ -265,9 +270,10 @@
265}270}
266271
267static gboolean272static gboolean
268is_point_in_rect (gint x, gint y, GdkRectangle* rect)273rect_contains_point (GdkRectangle* rect, gint x, gint y)
269{274{
270 g_return_val_if_fail (rect, FALSE);275 if (!rect)
276 return FALSE;
271277
272 return (x >= rect->x && x <= (rect->x + rect->width) &&278 return (x >= rect->x && x <= (rect->x + rect->width) &&
273 y >= rect->y && y <= (rect->y + rect->height));279 y >= rect->y && y <= (rect->y + rect->height));
@@ -290,7 +296,7 @@
290 IndicatorObjectEntry *entry = k;296 IndicatorObjectEntry *entry = k;
291 GdkRectangle *geo = v;297 GdkRectangle *geo = v;
292298
293 if (is_point_in_rect (x, y, geo))299 if (rect_contains_point (geo, x, y))
294 {300 {
295 return entry;301 return entry;
296 }302 }
@@ -321,8 +327,7 @@
321 IndicatorObjectEntry *entry = key;327 IndicatorObjectEntry *entry = key;
322 GdkRectangle *geo = value;328 GdkRectangle *geo = value;
323329
324 if (x >= geo->x && x <= (geo->x + geo->width) &&330 if (rect_contains_point (geo, x, y))
325 y >= geo->y && y <= (geo->y + geo->height))
326 {331 {
327 return entry;332 return entry;
328 }333 }
@@ -332,7 +337,7 @@
332}337}
333338
334static const gchar*339static const gchar*
335get_panel_at (PanelService *self, gint x, gint y)340get_panel_for_parent_at (PanelService *self, guint parent, gint x, gint y)
336{341{
337 GHashTableIter panel_iter, entries_iter;342 GHashTableIter panel_iter, entries_iter;
338 gpointer key, value, k, v;343 gpointer key, value, k, v;
@@ -346,12 +351,20 @@
346351
347 while (g_hash_table_iter_next (&entries_iter, &k, &v))352 while (g_hash_table_iter_next (&entries_iter, &k, &v))
348 {353 {
354 IndicatorObjectEntry *entry = k;
349 GdkRectangle *geo = v;355 GdkRectangle *geo = v;
350356
351 if (x >= geo->x && x <= (geo->x + geo->width) &&357 /* The entry might be invalid at this point (as it could have been
352 y >= geo->y && y <= (geo->y + geo->height))358 * removed, but still not synced), so it's better to double check */
359 if (g_slist_find (self->priv->removed_entries, entry))
360 continue;
361
362 if (!parent || entry->parent_window == parent)
353 {363 {
354 return panel_id;364 if (rect_contains_point (geo, x, y))
365 {
366 return panel_id;
367 }
355 }368 }
356 }369 }
357 }370 }
@@ -414,7 +427,7 @@
414 /* Unity might register some "fake" dropdown entries that it might use to427 /* Unity might register some "fake" dropdown entries that it might use to
415 * to present long menu bars (right now only for appmenu indicator) */428 * to present long menu bars (right now only for appmenu indicator) */
416 entry = g_new0 (IndicatorObjectEntry, 1);429 entry = g_new0 (IndicatorObjectEntry, 1);
417 entry->parent_object = panel_service_get_indicator (self, "libappmenu.so");430 entry->parent_object = self->priv->appmenu_indicator;
418 entry->name_hint = g_strdup (entry_id);431 entry->name_hint = g_strdup (entry_id);
419 self->priv->dropdown_entries = g_slist_append (self->priv->dropdown_entries, entry);432 self->priv->dropdown_entries = g_slist_append (self->priv->dropdown_entries, entry);
420 g_hash_table_insert (self->priv->id2entry_hash, (gpointer)entry->name_hint, entry);433 g_hash_table_insert (self->priv->id2entry_hash, (gpointer)entry->name_hint, entry);
@@ -424,6 +437,21 @@
424}437}
425438
426static void439static void
440ensure_entry_menu_is_closed (PanelService *self,
441 const gchar *panel_id,
442 IndicatorObjectEntry *entry)
443{
444 PanelServicePrivate *priv = self->priv;
445
446 /* If the entry has been removed let's make sure that its menu is closed */
447 if (GTK_IS_MENU (priv->last_menu) && priv->last_menu == entry->menu)
448 {
449 if (!priv->last_panel || !panel_id || g_strcmp0 (priv->last_panel, panel_id) == 0)
450 gtk_menu_popdown (entry->menu);
451 }
452}
453
454static void
427reinject_key_event_to_root_window (XIDeviceEvent *ev)455reinject_key_event_to_root_window (XIDeviceEvent *ev)
428{456{
429 XKeyEvent kev;457 XKeyEvent kev;
@@ -609,9 +637,7 @@
609 {637 {
610 /* Middle clicks over an appmenu entry are considered just like638 /* Middle clicks over an appmenu entry are considered just like
611 * all other clicks */639 * all other clicks */
612 IndicatorObject *obj = get_entry_parent_indicator (entry);640 if (get_entry_parent_indicator (entry) == priv->appmenu_indicator)
613
614 if (g_strcmp0 (g_object_get_data (G_OBJECT (obj), "id"), "libappmenu.so") == 0)
615 {641 {
616 event_is_a_click = TRUE;642 event_is_a_click = TRUE;
617 }643 }
@@ -677,7 +703,7 @@
677initial_resync (PanelService *self)703initial_resync (PanelService *self)
678{704{
679 g_signal_emit (self, _service_signals[RE_SYNC], 0, "");705 g_signal_emit (self, _service_signals[RE_SYNC], 0, "");
680 return FALSE;706 return G_SOURCE_REMOVE;
681}707}
682708
683static gboolean709static gboolean
@@ -686,7 +712,7 @@
686 if (!lockscreen_mode)712 if (!lockscreen_mode)
687 emit_upstart_event ("indicator-services-start");713 emit_upstart_event ("indicator-services-start");
688714
689 return FALSE;715 return G_SOURCE_REMOVE;
690}716}
691717
692static void718static void
@@ -850,10 +876,10 @@
850 if (self->priv->indicators == NULL)876 if (self->priv->indicators == NULL)
851 {877 {
852 g_signal_emit (self, _service_signals[INDICATORS_CLEARED], 0);878 g_signal_emit (self, _service_signals[INDICATORS_CLEARED], 0);
853 return FALSE;879 return G_SOURCE_REMOVE;
854 }880 }
855881
856 return TRUE;882 return G_SOURCE_CONTINUE;
857}883}
858884
859static void885static void
@@ -931,6 +957,9 @@
931 g_object_ref_sink (G_OBJECT (indicator));957 g_object_ref_sink (G_OBJECT (indicator));
932 }958 }
933959
960 if (self->priv->appmenu_indicator == indicator)
961 self->priv->appmenu_indicator = NULL;
962
934 g_object_unref (G_OBJECT (indicator));963 g_object_unref (G_OBJECT (indicator));
935}964}
936965
@@ -1145,7 +1174,7 @@
1145 g_signal_emit (self, _service_signals[RE_SYNC],1174 g_signal_emit (self, _service_signals[RE_SYNC],
1146 0, g_object_get_data (G_OBJECT (object), "id"));1175 0, g_object_get_data (G_OBJECT (object), "id"));
11471176
1148 return FALSE;1177 return G_SOURCE_REMOVE;
1149}1178}
11501179
1151static void1180static void
@@ -1204,6 +1233,7 @@
1204 g_return_if_fail (PANEL_IS_SERVICE (self));1233 g_return_if_fail (PANEL_IS_SERVICE (self));
1205 g_return_if_fail (entry != NULL);1234 g_return_if_fail (entry != NULL);
12061235
1236 self->priv->removed_entries = g_slist_remove (self->priv->removed_entries, entry);
1207 gchar *entry_id = get_indicator_entry_id_by_entry (entry);1237 gchar *entry_id = get_indicator_entry_id_by_entry (entry);
1208 g_hash_table_insert (self->priv->id2entry_hash, entry_id, entry);1238 g_hash_table_insert (self->priv->id2entry_hash, entry_id, entry);
12091239
@@ -1243,6 +1273,42 @@
1243 notify_object (object);1273 notify_object (object);
1244}1274}
12451275
1276static gboolean
1277on_removed_idle (PanelService *self)
1278{
1279 GHashTableIter iter;
1280 GHashTable *entry2geometry_hash;
1281 IndicatorObjectEntry *entry;
1282 gpointer value;
1283 GSList *l;
1284
1285 for (l = self->priv->removed_entries; l; l = l->next)
1286 {
1287 entry = l->data;
1288 ensure_entry_menu_is_closed (self, NULL, entry);
1289
1290 g_hash_table_iter_init (&iter, self->priv->panel2entries_hash);
1291 while (g_hash_table_iter_next (&iter, NULL, &value))
1292 {
1293 if ((entry2geometry_hash = value))
1294 {
1295 g_hash_table_remove (entry2geometry_hash, entry);
1296
1297 if (g_hash_table_size (entry2geometry_hash) == 0)
1298 {
1299 g_hash_table_iter_remove (&iter);
1300 }
1301 }
1302 }
1303
1304 }
1305
1306 g_slist_free (self->priv->removed_entries);
1307 self->priv->removed_entries = NULL;
1308
1309 return G_SOURCE_REMOVE;
1310}
1311
1246static void1312static void
1247on_entry_removed (IndicatorObject *object,1313on_entry_removed (IndicatorObject *object,
1248 IndicatorObjectEntry *entry,1314 IndicatorObjectEntry *entry,
@@ -1251,11 +1317,6 @@
1251 g_return_if_fail (PANEL_IS_SERVICE (self));1317 g_return_if_fail (PANEL_IS_SERVICE (self));
1252 g_return_if_fail (entry != NULL);1318 g_return_if_fail (entry != NULL);
12531319
1254 /* Don't remove here the value from panel2entries_hash, this should be
1255 * done during the geometries sync, to avoid false positive.
1256 * FIXME this in libappmenu.so to avoid to send an "entry-removed" signal
1257 * when switching the focus from a window to one of its dialog children */
1258
1259 gchar *entry_id = get_indicator_entry_id_by_entry (entry);1320 gchar *entry_id = get_indicator_entry_id_by_entry (entry);
1260 g_hash_table_remove (self->priv->id2entry_hash, entry_id);1321 g_hash_table_remove (self->priv->id2entry_hash, entry_id);
1261 g_free (entry_id);1322 g_free (entry_id);
@@ -1270,6 +1331,13 @@
1270 g_signal_handlers_disconnect_by_data (entry->image, object);1331 g_signal_handlers_disconnect_by_data (entry->image, object);
1271 }1332 }
12721333
1334 self->priv->removed_entries = g_slist_append (self->priv->removed_entries, entry);
1335
1336 if (self->priv->remove_idle)
1337 g_source_remove (self->priv->remove_idle);
1338
1339 self->priv->remove_idle = g_idle_add ((GSourceFunc) on_removed_idle, self);
1340
1273 notify_object (object);1341 notify_object (object);
1274}1342}
12751343
@@ -1327,6 +1395,7 @@
1327 "unity",1395 "unity",
1328 "unity-3d",1396 "unity-3d",
1329 "unity-panel-service",1397 "unity-panel-service",
1398 "unity-all-menus",
1330 NULL1399 NULL
1331};1400};
13321401
@@ -1346,6 +1415,9 @@
13461415
1347 priv->indicators = g_slist_append (priv->indicators, object);1416 priv->indicators = g_slist_append (priv->indicators, object);
13481417
1418 if (!priv->appmenu_indicator && g_strcmp0 (name, APPMENU_INDICATOR_NAME) == 0)
1419 priv->appmenu_indicator = object;
1420
1349 g_object_set_data_full (G_OBJECT (object), "id", g_strdup (name), g_free);1421 g_object_set_data_full (G_OBJECT (object), "id", g_strdup (name), g_free);
13501422
1351 g_signal_connect (object, INDICATOR_OBJECT_SIGNAL_ENTRY_ADDED,1423 g_signal_connect (object, INDICATOR_OBJECT_SIGNAL_ENTRY_ADDED,
@@ -1607,10 +1679,11 @@
1607 guint32 image_type = 0;1679 guint32 image_type = 0;
1608 gchar *image_data = gtk_image_to_data (entry->image, &image_type);1680 gchar *image_data = gtk_image_to_data (entry->image, &image_type);
16091681
1610 g_variant_builder_add (b, "(ssssbbusbbi)",1682 g_variant_builder_add (b, ENTRY_SIGNATURE,
1611 indicator_id,1683 indicator_id,
1612 id,1684 id,
1613 entry->name_hint ? entry->name_hint : "",1685 entry->name_hint ? entry->name_hint : "",
1686 entry->parent_window,
1614 is_label ? gtk_label_get_label (entry->label) : "",1687 is_label ? gtk_label_get_label (entry->label) : "",
1615 is_label ? gtk_widget_get_sensitive (GTK_WIDGET (entry->label)) : FALSE,1688 is_label ? gtk_widget_get_sensitive (GTK_WIDGET (entry->label)) : FALSE,
1616 is_label ? gtk_widget_get_visible (GTK_WIDGET (entry->label)) : FALSE,1689 is_label ? gtk_widget_get_visible (GTK_WIDGET (entry->label)) : FALSE,
@@ -1627,14 +1700,15 @@
1627indicator_entry_null_to_variant (const gchar *indicator_id,1700indicator_entry_null_to_variant (const gchar *indicator_id,
1628 GVariantBuilder *b)1701 GVariantBuilder *b)
1629{1702{
1630 g_variant_builder_add (b, "(ssssbbusbbi)",1703 g_variant_builder_add (b, ENTRY_SIGNATURE,
1631 indicator_id,1704 indicator_id,
1632 "",1705 "",
1633 "",1706 "",
1707 0,
1634 "",1708 "",
1635 FALSE,1709 FALSE,
1636 FALSE,1710 FALSE,
1637 (guint32) 0,1711 0,
1638 "",1712 "",
1639 FALSE,1713 FALSE,
1640 FALSE,1714 FALSE,
@@ -1642,15 +1716,20 @@
1642}1716}
16431717
1644static void1718static void
1645indicator_object_full_to_variant (IndicatorObject *object, const gchar *indicator_id, GVariantBuilder *b)1719indicator_object_full_to_variant (PanelService *self, IndicatorObject *object,
1720 const gchar *indicator_id, GVariantBuilder *b)
1646{1721{
1647 GList *entries, *e;1722 GList *entries, *e;
1723 GHashTable *index_hash = NULL;
1648 gint parent_prio = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (object), "priority"));1724 gint parent_prio = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (object), "priority"));
1649 entries = indicator_object_get_entries (object);1725 entries = indicator_object_get_entries (object);
1650 gint index = 0;1726 guint index = 0;
16511727
1652 if (entries)1728 if (entries)
1653 {1729 {
1730 if (object == self->priv->appmenu_indicator)
1731 index_hash = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, NULL);
1732
1654 for (e = entries; e; e = e->next)1733 for (e = entries; e; e = e->next)
1655 {1734 {
1656 gint prio = -1;1735 gint prio = -1;
@@ -1664,14 +1743,29 @@
16641743
1665 if (prio < 0)1744 if (prio < 0)
1666 {1745 {
1746 if (index_hash)
1747 {
1748 index = GPOINTER_TO_UINT (g_hash_table_lookup (index_hash,
1749 GUINT_TO_POINTER (entry->parent_window)));
1750 }
1751
1667 prio = parent_prio + index;1752 prio = parent_prio + index;
1668 index++;1753 index++;
1754
1755 if (index_hash)
1756 {
1757 g_hash_table_insert (index_hash, GUINT_TO_POINTER (entry->parent_window),
1758 GUINT_TO_POINTER (index));
1759 }
1669 }1760 }
16701761
1671 indicator_entry_to_variant (entry, id, indicator_id, b, prio);1762 indicator_entry_to_variant (entry, id, indicator_id, b, prio);
1672 g_free (id);1763 g_free (id);
1673 }1764 }
16741765
1766 if (index_hash)
1767 g_hash_table_destroy (index_hash);
1768
1675 g_list_free (entries);1769 g_list_free (entries);
1676 }1770 }
1677 else1771 else
@@ -1682,15 +1776,15 @@
1682}1776}
16831777
1684static void1778static void
1685indicator_object_to_variant (IndicatorObject *object, const gchar *indicator_id, GVariantBuilder *b)1779indicator_object_to_variant (PanelService *self, IndicatorObject *object,
1780 const gchar *indicator_id, GVariantBuilder *b)
1686{1781{
1687 if (!GPOINTER_TO_INT (g_object_get_data (G_OBJECT (object), "remove")))1782 if (!GPOINTER_TO_INT (g_object_get_data (G_OBJECT (object), "remove")))
1688 {1783 {
1689 indicator_object_full_to_variant (object, indicator_id, b);1784 indicator_object_full_to_variant (self, object, indicator_id, b);
1690 }1785 }
1691 else1786 else
1692 {1787 {
1693 PanelService *self = panel_service_get_default ();
1694 indicator_entry_null_to_variant (indicator_id, b);1788 indicator_entry_null_to_variant (indicator_id, b);
1695 panel_service_actually_remove_indicator (self, object);1789 panel_service_actually_remove_indicator (self, object);
1696 }1790 }
@@ -1718,7 +1812,7 @@
1718 rect.height *= scale;1812 rect.height *= scale;
1719 }1813 }
17201814
1721 if (is_point_in_rect (x, y, &rect))1815 if (rect_contains_point (&rect, x, y))
1722 {1816 {
1723 return i;1817 return i;
1724 }1818 }
@@ -1790,8 +1884,8 @@
1790 GSList *i;1884 GSList *i;
1791 gint position;1885 gint position;
17921886
1793 g_variant_builder_init (&b, G_VARIANT_TYPE ("(a(ssssbbusbbi))"));1887 g_variant_builder_init (&b, G_VARIANT_TYPE ("("ENTRY_ARRAY_SIGNATURE")"));
1794 g_variant_builder_open (&b, G_VARIANT_TYPE ("a(ssssbbusbbi)"));1888 g_variant_builder_open (&b, G_VARIANT_TYPE (ENTRY_ARRAY_SIGNATURE));
17951889
1796 for (i = self->priv->indicators; i;)1890 for (i = self->priv->indicators; i;)
1797 {1891 {
@@ -1801,7 +1895,7 @@
18011895
1802 const gchar *indicator_id = g_object_get_data (G_OBJECT (indicator), "id");1896 const gchar *indicator_id = g_object_get_data (G_OBJECT (indicator), "id");
1803 position = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (indicator), "position"));1897 position = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (indicator), "position"));
1804 indicator_object_to_variant (indicator, indicator_id, &b);1898 indicator_object_to_variant (self, indicator, indicator_id, &b);
18051899
1806 /* Set the sync back to neutral */1900 /* Set the sync back to neutral */
1807 self->priv->timeouts[position] = SYNC_NEUTRAL;1901 self->priv->timeouts[position] = SYNC_NEUTRAL;
@@ -1817,8 +1911,8 @@
1817 GVariantBuilder b;1911 GVariantBuilder b;
1818 GSList *i;1912 GSList *i;
18191913
1820 g_variant_builder_init (&b, G_VARIANT_TYPE ("(a(ssssbbusbbi))"));1914 g_variant_builder_init (&b, G_VARIANT_TYPE ("("ENTRY_ARRAY_SIGNATURE")"));
1821 g_variant_builder_open (&b, G_VARIANT_TYPE ("a(ssssbbusbbi)"));1915 g_variant_builder_open (&b, G_VARIANT_TYPE (ENTRY_ARRAY_SIGNATURE));
18221916
1823 for (i = self->priv->indicators; i; i = i->next)1917 for (i = self->priv->indicators; i; i = i->next)
1824 {1918 {
@@ -1826,7 +1920,7 @@
1826 g_object_get_data (G_OBJECT (i->data), "id")) == 0)1920 g_object_get_data (G_OBJECT (i->data), "id")) == 0)
1827 {1921 {
1828 gint position = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (i->data), "position"));1922 gint position = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (i->data), "position"));
1829 indicator_object_to_variant (i->data, indicator_id, &b);1923 indicator_object_to_variant (self, i->data, indicator_id, &b);
18301924
1831 /* Set the sync back to neutral */1925 /* Set the sync back to neutral */
1832 self->priv->timeouts[position] = SYNC_NEUTRAL;1926 self->priv->timeouts[position] = SYNC_NEUTRAL;
@@ -1850,6 +1944,7 @@
1850{1944{
1851 IndicatorObject *object;1945 IndicatorObject *object;
1852 IndicatorObjectEntry *entry;1946 IndicatorObjectEntry *entry;
1947 GHashTable *entry2geometry_hash;
1853 gboolean valid_entry = TRUE;1948 gboolean valid_entry = TRUE;
1854 PanelServicePrivate *priv = self->priv;1949 PanelServicePrivate *priv = self->priv;
18551950
@@ -1870,24 +1965,18 @@
18701965
1871 if (entry)1966 if (entry)
1872 {1967 {
1873 GHashTable *entry2geometry_hash = g_hash_table_lookup (priv->panel2entries_hash, panel_id);1968 entry2geometry_hash = g_hash_table_lookup (priv->panel2entries_hash, panel_id);
18741969
1875 if (width < 0 || height < 0 || !valid_entry)1970 if (width < 0 || height < 0 || !valid_entry)
1876 {1971 {
1877 /* If the entry has been removed let's make sure that its menu is closed */1972 if (valid_entry)
1878 if (valid_entry && GTK_IS_MENU (priv->last_menu) && priv->last_menu == entry->menu)1973 ensure_entry_menu_is_closed (self, panel_id, entry);
1879 {
1880 if (!priv->last_panel || g_strcmp0 (priv->last_panel, panel_id) == 0)
1881 gtk_menu_popdown (entry->menu);
1882 }
18831974
1884 if (entry2geometry_hash)1975 if (entry2geometry_hash)
1885 {1976 {
1886 if (g_hash_table_size (entry2geometry_hash) > 1)1977 g_hash_table_remove (entry2geometry_hash, entry);
1887 {1978
1888 g_hash_table_remove (entry2geometry_hash, entry);1979 if (g_hash_table_size (entry2geometry_hash) == 0)
1889 }
1890 else
1891 {1980 {
1892 g_hash_table_remove (priv->panel2entries_hash, panel_id);1981 g_hash_table_remove (priv->panel2entries_hash, panel_id);
1893 }1982 }
@@ -2256,7 +2345,7 @@
2256 priv->last_x = x;2345 priv->last_x = x;
2257 priv->last_y = y;2346 priv->last_y = y;
2258 priv->last_menu_button = button;2347 priv->last_menu_button = button;
2259 priv->last_panel = get_panel_at (self, x, y);2348 priv->last_panel = get_panel_for_parent_at (self, xid, x, y);
22602349
2261 g_signal_connect (priv->last_menu, "hide", G_CALLBACK (on_active_menu_hidden), self);2350 g_signal_connect (priv->last_menu, "hide", G_CALLBACK (on_active_menu_hidden), self);
2262 g_signal_connect_after (priv->last_menu, "move-current",2351 g_signal_connect_after (priv->last_menu, "move-current",
@@ -2462,10 +2551,9 @@
2462 GList *entries;2551 GList *entries;
24632552
2464 g_return_if_fail (PANEL_IS_SERVICE (self));2553 g_return_if_fail (PANEL_IS_SERVICE (self));
24652554 g_return_if_fail (INDICATOR_IS_OBJECT (self->priv->appmenu_indicator));
2466 object = panel_service_get_indicator (self, "libappmenu.so");2555
2467 g_return_if_fail (INDICATOR_IS_OBJECT (object));2556 object = self->priv->appmenu_indicator;
2468
2469 entries = indicator_object_get_entries (object);2557 entries = indicator_object_get_entries (object);
24702558
2471 if (entries)2559 if (entries)
24722560
=== modified file 'services/panel-service.h'
--- services/panel-service.h 2014-09-19 18:38:21 +0000
+++ services/panel-service.h 2015-02-19 19:24:14 +0000
@@ -56,14 +56,6 @@
56struct _PanelServiceClass56struct _PanelServiceClass
57{57{
58 GObjectClass parent_class;58 GObjectClass parent_class;
59
60 /*< private >*/
61 void (*_view_padding1) (void);
62 void (*_view_padding2) (void);
63 void (*_view_padding3) (void);
64 void (*_view_padding4) (void);
65 void (*_view_padding5) (void);
66 void (*_view_padding6) (void);
67};59};
6860
69GType panel_service_get_type (void) G_GNUC_CONST;61GType panel_service_get_type (void) G_GNUC_CONST;
7062
=== modified file 'shortcuts/ShortcutModel.h'
--- shortcuts/ShortcutModel.h 2013-01-19 00:25:07 +0000
+++ shortcuts/ShortcutModel.h 2015-02-19 19:24:14 +0000
@@ -21,7 +21,7 @@
21#define UNITYSHELL_SHORTCUS_MODEL_H21#define UNITYSHELL_SHORTCUS_MODEL_H
2222
23#include <boost/noncopyable.hpp>23#include <boost/noncopyable.hpp>
24#include <map>24#include <unordered_map>
25#include <memory>25#include <memory>
26#include <list>26#include <list>
27#include <string>27#include <string>
@@ -43,7 +43,7 @@
4343
44 nux::Property<int> categories_per_column;44 nux::Property<int> categories_per_column;
45 std::vector<std::string> const& categories() const { return categories_; }45 std::vector<std::string> const& categories() const { return categories_; }
46 std::map<std::string, std::list<AbstractHint::Ptr>> const& hints() const { return hints_; }46 std::unordered_map<std::string, std::list<AbstractHint::Ptr>> const& hints() const { return hints_; }
4747
48 void Fill();48 void Fill();
4949
@@ -51,7 +51,7 @@
51 void AddHint(AbstractHint::Ptr const& hint);51 void AddHint(AbstractHint::Ptr const& hint);
5252
53 std::vector<std::string> categories_;53 std::vector<std::string> categories_;
54 std::map<std::string, std::list<AbstractHint::Ptr>> hints_;54 std::unordered_map<std::string, std::list<AbstractHint::Ptr>> hints_;
55};55};
5656
57}57}
5858
=== modified file 'tests/autopilot/unity/emulators/panel.py'
--- tests/autopilot/unity/emulators/panel.py 2013-05-10 05:16:07 +0000
+++ tests/autopilot/unity/emulators/panel.py 2015-02-19 19:24:14 +0000
@@ -159,6 +159,10 @@
159 return self.menus.panel_title159 return self.menus.panel_title
160160
161 @property161 @property
162 def focused(self):
163 return self.menus.focused
164
165 @property
162 def desktop_is_active(self):166 def desktop_is_active(self):
163 return self.menus.desktop_active167 return self.menus.desktop_active
164168
165169
=== modified file 'tests/autopilot/unity/tests/__init__.py'
--- tests/autopilot/unity/tests/__init__.py 2014-02-12 20:43:54 +0000
+++ tests/autopilot/unity/tests/__init__.py 2015-02-19 19:24:14 +0000
@@ -48,7 +48,7 @@
48from Xlib import display48from Xlib import display
49from Xlib import Xutil49from Xlib import Xutil
5050
51from gi.repository import Gio51from gi.repository import GLib, Gio
5252
53log = getLogger(__name__)53log = getLogger(__name__)
5454
@@ -256,20 +256,19 @@
256 atom_type = display.Display().intern_atom('CARDINAL')256 atom_type = display.Display().intern_atom('CARDINAL')
257 return bamf_window.x_win.get_property(atom, atom_type, 0, 1024).value[0]257 return bamf_window.x_win.get_property(atom, atom_type, 0, 1024).value[0]
258258
259 def call_gsettings_cmd(self, command, schema, *args):259 def call_gsettings_cmd(self, command, schema, key, value=None):
260 """Set a desktop wide gsettings option260 """Set a desktop wide gsettings option
261
262 Using the gsettings command because there is a bug with importing
263 from gobject introspection and pygtk2 simultaneously, and the Xlib
264 keyboard layout bits are very unwieldy. This seems like the best
265 solution, even a little bit brutish.
266 """261 """
267 cmd = ['gsettings', command, schema] + list(args)262 settings = Gio.Settings.new(schema)
268 # strip to remove the trailing \n.263
269 ret = check_output(cmd).strip()264 if command == "get":
270 time.sleep(5)265 return settings.get_value(key).print_(type_annotate=False)
271 reset_display()266 elif command == "set":
272 return ret267 settings.set_value(key, GLib.Variant.parse(type=None, text=value))
268 settings.apply()
269 reset_display()
270 elif command == "reset":
271 settings.reset(key)
273272
274 def set_unity_option(self, option_name, option_value):273 def set_unity_option(self, option_name, option_value):
275 """Set an option in the unity compiz plugin options.274 """Set an option in the unity compiz plugin options.
276275
=== modified file 'tests/autopilot/unity/tests/test_dash.py'
--- tests/autopilot/unity/tests/test_dash.py 2014-02-28 19:53:07 +0000
+++ tests/autopilot/unity/tests/test_dash.py 2015-02-19 19:24:14 +0000
@@ -164,7 +164,7 @@
164164
165 self.assertProperty(char_win, is_active=True)165 self.assertProperty(char_win, is_active=True)
166166
167 def test_dash_does_not_open_when_fullscreen_window(self):167 def test_dash_opens_when_fullscreen_window(self):
168 """ The Dash must not open if a window is fullscreen. """168 """ The Dash must not open if a window is fullscreen. """
169 gedit = self.process_manager.start_app("Text Editor")169 gedit = self.process_manager.start_app("Text Editor")
170 self.keyboard.press_and_release('F11')170 self.keyboard.press_and_release('F11')
@@ -175,7 +175,7 @@
175 self.keybinding("dash/reveal")175 self.keybinding("dash/reveal")
176 self.addCleanup(self.unity.dash.ensure_hidden)176 self.addCleanup(self.unity.dash.ensure_hidden)
177177
178 self.assertThat(self.unity.dash.visible, Eventually(Equals(False)))178 self.assertThat(self.unity.dash.visible, Eventually(Equals(True)))
179179
180180
181class DashRevealWithSpreadTests(DashTestCase):181class DashRevealWithSpreadTests(DashTestCase):
182182
=== modified file 'tests/autopilot/unity/tests/test_hud.py'
--- tests/autopilot/unity/tests/test_hud.py 2014-02-28 19:53:07 +0000
+++ tests/autopilot/unity/tests/test_hud.py 2015-02-19 19:24:14 +0000
@@ -512,7 +512,7 @@
512 self.keyboard.type("e")512 self.keyboard.type("e")
513 self.assertThat(self.unity.hud.view.selected_button, Eventually(Equals(1)))513 self.assertThat(self.unity.hud.view.selected_button, Eventually(Equals(1)))
514514
515 def test_hud_does_not_open_when_fullscreen_window(self):515 def test_hud_opens_when_fullscreen_window(self):
516 """ The Hud must not open if a window is fullscreen. """516 """ The Hud must not open if a window is fullscreen. """
517 gedit = self.process_manager.start_app("Text Editor")517 gedit = self.process_manager.start_app("Text Editor")
518 self.keyboard.press_and_release('F11')518 self.keyboard.press_and_release('F11')
@@ -523,7 +523,7 @@
523 self.keybinding("hud/reveal")523 self.keybinding("hud/reveal")
524 self.addCleanup(self.unity.hud.ensure_hidden)524 self.addCleanup(self.unity.hud.ensure_hidden)
525525
526 self.assertThat(self.unity.hud.visible, Eventually(Equals(False)))526 self.assertThat(self.unity.hud.visible, Eventually(Equals(True)))
527527
528528
529class HudLauncherInteractionsTests(HudTestsBase):529class HudLauncherInteractionsTests(HudTestsBase):
530530
=== modified file 'tests/autopilot/unity/tests/test_panel.py'
--- tests/autopilot/unity/tests/test_panel.py 2014-03-04 15:30:06 +0000
+++ tests/autopilot/unity/tests/test_panel.py 2015-02-19 19:24:14 +0000
@@ -12,6 +12,7 @@
12#from autopilot.emulators.bamf import BamfWindow12#from autopilot.emulators.bamf import BamfWindow
13from autopilot.process import Window13from autopilot.process import Window
14from autopilot.matchers import Eventually14from autopilot.matchers import Eventually
15from autopilot.testcase import multiply_scenarios
15import logging16import logging
16import os17import os
17from testtools.matchers import Equals, GreaterThan, NotEquals18from testtools.matchers import Equals, GreaterThan, NotEquals
@@ -25,6 +26,13 @@
2526
26logger = logging.getLogger(__name__)27logger = logging.getLogger(__name__)
2728
29def _make_scenarios():
30 return multiply_scenarios(_make_monitor_scenarios(),
31 _make_menu_modes_scenarios())
32
33def _make_menu_modes_scenarios():
34 return [ ('Locally Integrated Menus', {'lim': True}),
35 ('Global Menus', {'lim': False}) ]
2836
29def _make_monitor_scenarios():37def _make_monitor_scenarios():
30 num_monitors = Display.create().get_num_screens()38 num_monitors = Display.create().get_num_screens()
@@ -38,17 +46,41 @@
3846
39 return scenarios47 return scenarios
4048
41
42class PanelTestsBase(UnityTestCase):49class PanelTestsBase(UnityTestCase):
4350
44 panel_monitor = 051 panel_monitor = 0
52 lim = False
4553
46 def setUp(self):54 def setUp(self):
47 super(PanelTestsBase, self).setUp()55 super(PanelTestsBase, self).setUp()
48 self.panel = self.unity.panels.get_panel_for_monitor(self.panel_monitor)56 self.panel = self.unity.panels.get_panel_for_monitor(self.panel_monitor)
57
58 old_lim = self.call_gsettings_cmd('get', 'com.canonical.Unity', 'integrated-menus')
59 self.call_gsettings_cmd('set', 'com.canonical.Unity', 'integrated-menus', str(self.lim).lower())
60 self.addCleanup(self.call_gsettings_cmd, 'set', 'com.canonical.Unity', 'integrated-menus', old_lim)
61
62 old_showmenus = self.call_gsettings_cmd('get', 'com.canonical.Unity', 'always-show-menus')
63 self.call_gsettings_cmd('set', 'com.canonical.Unity', 'always-show-menus', 'false')
64 self.addCleanup(self.call_gsettings_cmd, 'set', 'com.canonical.Unity', 'always-show-menus', old_showmenus)
65
49 self.panel.move_mouse_below_the_panel()66 self.panel.move_mouse_below_the_panel()
50 self.addCleanup(self.panel.move_mouse_below_the_panel)67 self.addCleanup(self.panel.move_mouse_below_the_panel)
5168
69 self.assertThat(self.panel.menus.integrated_menus, Eventually(Equals(self.lim)))
70 if not self.lim:
71 self.assertThat(self.panel.focused, Eventually(Equals(True)))
72
73 def ensure_window_state(self, win, maximized=False):
74 if maximized and not win.is_maximized:
75 self.keybinding("window/maximize")
76 self.addCleanup(self.keybinding, "window/restore")
77 elif not maximized and win.is_maximized:
78 self.keybinding("window/restore")
79 self.addCleanup(self.keybinding, "window/maximize")
80
81 sleep(.25)
82 self.assertProperty(win, is_maximized=maximized)
83
52 def open_new_application_window(self, app_name, maximized=False, move_to_monitor=True):84 def open_new_application_window(self, app_name, maximized=False, move_to_monitor=True):
53 """Opens a new instance of the requested application, ensuring that only85 """Opens a new instance of the requested application, ensuring that only
54 one window is opened.86 one window is opened.
@@ -68,17 +100,8 @@
68 if move_to_monitor:100 if move_to_monitor:
69 self.move_window_to_panel_monitor(app_win)101 self.move_window_to_panel_monitor(app_win)
70102
71 if maximized and not app_win.is_maximized:
72 self.keybinding("window/maximize")
73 self.addCleanup(self.keybinding, "window/restore")
74 elif not maximized and app_win.is_maximized:
75 self.keybinding("window/restore")
76 self.addCleanup(self.keybinding, "window/maximize")
77
78 app_win.set_focus()103 app_win.set_focus()
79 sleep(.25)104 self.ensure_window_state(app_win, maximized)
80
81 self.assertThat(app_win.is_maximized, Equals(maximized))
82105
83 return app_win106 return app_win
84107
@@ -137,9 +160,10 @@
137160
138 def sleep_menu_settle_period(self):161 def sleep_menu_settle_period(self):
139 """Sleep long enough for the menus to fade in and fade out again."""162 """Sleep long enough for the menus to fade in and fade out again."""
140 sleep(self.panel.menus.fadein_duration / 1000.0)163 if not self.lim:
141 sleep(self.panel.menus.discovery_duration)164 sleep(self.panel.menus.fadein_duration / 1000.0)
142 sleep(self.panel.menus.fadeout_duration / 1000.0)165 sleep(self.panel.menus.discovery_duration)
166 sleep(self.panel.menus.fadeout_duration / 1000.0)
143167
144 # Unable to exit SDM without any active apps, need a placeholder.168 # Unable to exit SDM without any active apps, need a placeholder.
145 # See bug LP:1079460169 # See bug LP:1079460
@@ -152,7 +176,7 @@
152176
153class PanelTitleTests(PanelTestsBase):177class PanelTitleTests(PanelTestsBase):
154178
155 scenarios = _make_monitor_scenarios()179 scenarios = _make_scenarios()
156180
157 def setUp(self):181 def setUp(self):
158 super(PanelTitleTests, self).setUp()182 super(PanelTitleTests, self).setUp()
@@ -174,13 +198,15 @@
174 """Panel must display application name for a non-maximised application."""198 """Panel must display application name for a non-maximised application."""
175 calc_win = self.open_new_application_window("Calculator", maximized=False)199 calc_win = self.open_new_application_window("Calculator", maximized=False)
176200
177 self.assertThat(self.panel.title, Eventually(Equals(calc_win.application.name)))201 expected = calc_win.application.name if not self.lim else ''
202 self.assertThat(self.panel.title, Eventually(Equals(expected)))
178203
179 def test_panel_title_with_maximized_application(self):204 def test_panel_title_with_maximized_application(self):
180 """Panel must display application name for a maximised application."""205 """Panel must display application name for a maximised application."""
181 text_win = self.open_new_application_window("Text Editor", maximized=True)206 text_win = self.open_new_application_window("Text Editor", maximized=True)
182207
183 self.assertThat(self.panel.title, Eventually(Equals(text_win.title)))208 self.assertThat(self.panel.title, Eventually(Equals(text_win.title)))
209 self.assertThat(self.panel.focused, Eventually(Equals(True)))
184210
185 def test_panel_title_with_maximized_window_restored_child(self):211 def test_panel_title_with_maximized_window_restored_child(self):
186 """Tests the title shown in the panel when opening the restored child of212 """Tests the title shown in the panel when opening the restored child of
@@ -194,14 +220,18 @@
194220
195 self.assertThat(lambda: len(text_win.application.get_windows()),221 self.assertThat(lambda: len(text_win.application.get_windows()),
196 Eventually(Equals(2)))222 Eventually(Equals(2)))
197 self.assertThat(self.panel.title, Equals(text_win.application.name))223 expected = text_win.application.name if not self.lim else text_win.title
224 self.assertThat(self.panel.title, Equals(expected))
225 self.assertThat(self.panel.focused, Eventually(Equals(not self.lim)))
198226
199 def test_panel_shows_app_title_with_maximised_app(self):227 def test_panel_shows_app_title_with_maximised_app(self):
200 """Tests app titles are shown in the panel with a non-focused maximized application."""228 """Tests app titles are shown in the panel with a non-focused maximized application."""
201 self.open_new_application_window("Text Editor", maximized=True)229 text_win = self.open_new_application_window("Text Editor", maximized=True)
202 calc_win = self.open_new_application_window("Calculator", maximized=False)230 calc_win = self.open_new_application_window("Calculator", maximized=False)
203231
204 self.assertThat(self.panel.title, Eventually(Equals(calc_win.application.name)))232 expected = calc_win.application.name if not self.lim else text_win.title
233 self.assertThat(self.panel.title, Eventually(Equals(expected)))
234 self.assertThat(self.panel.focused, Eventually(Equals(not self.lim)))
205235
206 def test_panel_title_updates_when_switching_to_maximized_app(self):236 def test_panel_title_updates_when_switching_to_maximized_app(self):
207 """Switching to a maximised app from a restored one must update the panel title."""237 """Switching to a maximised app from a restored one must update the panel title."""
@@ -242,13 +272,14 @@
242272
243class PanelWindowButtonsTests(PanelTestsBase):273class PanelWindowButtonsTests(PanelTestsBase):
244274
245 scenarios = _make_monitor_scenarios()275 scenarios = _make_scenarios()
246276
247 def setUp(self):277 def setUp(self):
248 super(PanelWindowButtonsTests, self).setUp()278 super(PanelWindowButtonsTests, self).setUp()
249 # Locked Launchers on all monitors279 # Locked Launchers on all monitors
250 self.set_unity_option('num_launchers', 0)280 self.set_unity_option('num_launchers', 0)
251 self.set_unity_option('launcher_hide_mode', 0)281 self.set_unity_option('launcher_hide_mode', 0)
282 self.always_visible = self.lim
252283
253 def test_window_buttons_dont_show_on_empty_desktop(self):284 def test_window_buttons_dont_show_on_empty_desktop(self):
254 """Tests that the window buttons are not shown on clean desktop."""285 """Tests that the window buttons are not shown on clean desktop."""
@@ -279,13 +310,14 @@
279310
280 self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(False)))311 self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(False)))
281312
282 def test_window_buttons_dont_show_for_maximized_window_on_mouse_out(self):313 def test_window_buttons_show_for_maximized_window_on_mouse_out(self):
283 """Window buttons must not show for a maximized window when the mouse is314 """Window buttons might show for a maximized window when the mouse is
284 outside the panel.315 outside the panel, depending on LIM setting.
285 """316 """
286 self.open_new_application_window("Text Editor", maximized=True)317 self.open_new_application_window("Text Editor", maximized=True)
287318
288 self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(False)))319 self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(self.always_visible)))
320 self.assertThat(self.panel.window_buttons.focused, Eventually(Equals(True)))
289321
290 def test_window_buttons_show_for_maximized_window_on_mouse_in(self):322 def test_window_buttons_show_for_maximized_window_on_mouse_in(self):
291 """Window buttons must show when a maximized window is focused and the323 """Window buttons must show when a maximized window is focused and the
@@ -296,8 +328,30 @@
296 self.panel.move_mouse_over_window_buttons()328 self.panel.move_mouse_over_window_buttons()
297329
298 self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(True)))330 self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(True)))
331 self.assertThat(self.panel.window_buttons.focused, Eventually(Equals(True)))
299 self.assertWinButtonsInOverlayMode(False)332 self.assertWinButtonsInOverlayMode(False)
300333
334 def test_window_buttons_show_for_maximized_unfocused_window_with_mouse_in_panel(self):
335 """Window buttons might show for an unfocused maximized window when the
336 mouse is over the panel, depending on LIM setting.
337 """
338 self.open_new_application_window("Text Editor", maximized=True)
339 self.open_new_application_window("Calculator")
340 self.panel.move_mouse_over_window_buttons()
341
342 self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(self.always_visible)))
343 self.assertThat(self.panel.window_buttons.focused, Eventually(Equals(not self.lim)))
344
345 def test_window_buttons_show_for_maximized_unfocused_window_on_mouse_out(self):
346 """Window buttons might show for an unfocused maximized window when the
347 mouse is outside the panel, depending on LIM setting.
348 """
349 self.open_new_application_window("Text Editor", maximized=True)
350 self.open_new_application_window("Calculator")
351
352 self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(self.always_visible)))
353 self.assertThat(self.panel.window_buttons.focused, Eventually(Equals(not self.lim)))
354
301 def test_window_buttons_show_with_dash(self):355 def test_window_buttons_show_with_dash(self):
302 """Window buttons must be shown when the dash is open."""356 """Window buttons must be shown when the dash is open."""
303 self.unity.dash.ensure_visible()357 self.unity.dash.ensure_visible()
@@ -340,122 +394,6 @@
340 else:394 else:
341 self.assertThat(self.unity.hud.view.overlay_window_buttons_shown[monitor], Equals(False))395 self.assertThat(self.unity.hud.view.overlay_window_buttons_shown[monitor], Equals(False))
342396
343 def test_window_buttons_update_visual_state(self):
344 """Window button must update its state in response to mouse events."""
345 self.open_new_application_window("Text Editor", maximized=True, move_to_monitor=True)
346 self.panel.move_mouse_over_window_buttons()
347 button = self.panel.window_buttons.unmaximize
348
349 self.assertThat(button.visual_state, Eventually(Equals("normal")))
350
351 button.mouse_move_to()
352 self.assertThat(button.visual_state, Eventually(Equals("prelight")))
353
354 self.mouse.press()
355 self.addCleanup(self.mouse.release)
356 self.assertThat(button.visual_state, Eventually(Equals("pressed")))
357
358 def test_window_buttons_cancel(self):
359 """Window buttons must ignore clicks when the mouse released outside
360 their area.
361 """
362 win = self.open_new_application_window("Text Editor", maximized=True, move_to_monitor=True)
363 self.panel.move_mouse_over_window_buttons()
364
365 button = self.panel.window_buttons.unmaximize
366 button.mouse_move_to()
367 self.mouse.press()
368 self.assertThat(button.visual_state, Eventually(Equals("pressed")))
369 self.panel.move_mouse_below_the_panel()
370 self.mouse.release()
371
372 self.assertThat(win.is_maximized, Equals(True))
373
374 def test_window_buttons_close_button_works_for_window(self):
375 """Close window button must actually closes a window."""
376 text_win = self.open_new_application_window("Text Editor",
377 maximized=True,
378 move_to_monitor=True)
379 win_xid = text_win.x_id
380
381 self.panel.window_buttons.close.mouse_click()
382 self.assertNoWindowOpenWithXid(win_xid)
383
384 def test_window_buttons_close_follows_fitts_law(self):
385 """Tests that the 'Close' button is activated when clicking at 0,0.
386
387 See bug #839690
388 """
389 text_win = self.open_new_application_window("Text Editor",
390 maximized=True,
391 move_to_monitor=True)
392 win_xid = text_win.x_id
393
394 self.panel.move_mouse_over_window_buttons()
395 screen_x, screen_y = self.display.get_screen_geometry(self.panel_monitor)[:2]
396 self.mouse.move(screen_x, screen_y)
397 self.mouse.click()
398
399 self.assertNoWindowOpenWithXid(win_xid)
400
401 def test_window_buttons_minimize_button_works_for_window(self):
402 """Tests that the window button 'Minimize' actually minimizes a window."""
403 text_win = self.open_new_application_window("Text Editor",
404 maximized=True,
405 move_to_monitor=True)
406
407 self.panel.window_buttons.minimize.mouse_click()
408
409 self.assertProperty(text_win, is_hidden=True)
410
411 def test_window_buttons_minimize_follows_fitts_law(self):
412 """Tests that the 'Minimize' button is conform to Fitts's Law.
413
414 See bug #839690
415 """
416 text_win = self.open_new_application_window("Text Editor",
417 maximized=True,
418 move_to_monitor=True)
419
420 self.panel.move_mouse_over_window_buttons()
421 button = self.panel.window_buttons.minimize
422 target_x = button.x + button.width / 2
423 target_y = self.display.get_screen_geometry(self.panel_monitor)[1]
424 self.mouse.move(target_x, target_y)
425 self.mouse.click()
426
427 self.assertProperty(text_win, is_hidden=True)
428
429 def test_window_buttons_unmaximize_button_works_for_window(self):
430 """Tests that the window button 'Unmaximize' actually unmaximizes a window."""
431 text_win = self.open_new_application_window("Text Editor",
432 maximized=True,
433 move_to_monitor=True)
434
435 self.panel.window_buttons.unmaximize.mouse_click()
436
437 self.assertProperties(text_win, is_maximized=False, is_focused=True)
438 self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(False)))
439
440 def test_window_buttons_unmaximize_follows_fitts_law(self):
441 """Tests that the 'Unmaximize' button is conform to Fitts's Law.
442
443 See bug #839690
444 """
445 text_win = self.open_new_application_window("Text Editor",
446 maximized=True,
447 move_to_monitor=True)
448
449 button = self.panel.window_buttons.unmaximize
450 button.mouse_move_to()
451 target_x = button.x + button.width / 2
452 target_y = self.display.get_screen_geometry(self.panel_monitor)[1]
453 self.mouse.move(target_x, target_y)
454 sleep(1)
455 self.mouse.click()
456
457 self.assertProperty(text_win, is_maximized=False)
458
459 def test_window_buttons_close_button_works_for_hud(self):397 def test_window_buttons_close_button_works_for_hud(self):
460 """Tests that the window 'Close' actually closes the HUD."""398 """Tests that the window 'Close' actually closes the HUD."""
461 self.unity.hud.ensure_visible()399 self.unity.hud.ensure_visible()
@@ -604,9 +542,7 @@
604542
605 def test_minimize_button_disabled_for_non_minimizable_windows(self):543 def test_minimize_button_disabled_for_non_minimizable_windows(self):
606 """Minimize button must be disabled for windows that don't support minimization."""544 """Minimize button must be disabled for windows that don't support minimization."""
607 text_win = self.open_new_application_window("Text Editor",545 text_win = self.open_new_application_window("Text Editor", maximized=True)
608 maximized=False,
609 move_to_monitor=True)
610546
611 self.keyboard.press_and_release("Ctrl+S")547 self.keyboard.press_and_release("Ctrl+S")
612 self.addCleanup(self.keyboard.press_and_release, "Escape")548 self.addCleanup(self.keyboard.press_and_release, "Escape")
@@ -626,28 +562,24 @@
626 """Window buttons must be shown when mouse is over panel area with an562 """Window buttons must be shown when mouse is over panel area with an
627 indicator open.563 indicator open.
628 """564 """
629 self.open_new_application_window("Text Editor",565 self.open_new_application_window("Text Editor", maximized=True)
630 maximized=True,
631 move_to_monitor=True)
632566
633 indicator = self.panel.indicators.get_indicator_by_name_hint("indicator-session")567 indicator = self.panel.indicators.get_indicator_by_name_hint("indicator-session")
634 self.mouse_open_indicator(indicator)568 self.mouse_open_indicator(indicator)
635 self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(False)))569 self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(self.always_visible)))
636570
637 self.panel.move_mouse_below_the_panel()571 self.panel.move_mouse_below_the_panel()
638 self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(False)))572 self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(self.always_visible)))
639573
640 self.panel.move_mouse_over_grab_area()574 self.panel.move_mouse_over_grab_area()
641 self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(True)))575 self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(True)))
642576
643 def test_window_buttons_show_when_holding_show_menu_key(self):577 def test_window_buttons_show_when_holding_show_menu_key(self):
644 """Window buttons must show when we press the show-menu keybinding."""578 """Window buttons must show when we press the show-menu keybinding."""
645 self.open_new_application_window("Text Editor",579 self.open_new_application_window("Text Editor", maximized=True)
646 maximized=True,
647 move_to_monitor=True)
648580
649 self.sleep_menu_settle_period()581 self.sleep_menu_settle_period()
650 self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(False)))582 self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(self.always_visible)))
651583
652 self.keybinding_hold("panel/show_menus")584 self.keybinding_hold("panel/show_menus")
653 self.addCleanup(self.keybinding_release, "panel/show_menus")585 self.addCleanup(self.keybinding_release, "panel/show_menus")
@@ -657,7 +589,7 @@
657 # Sleep a bit to avoid a race with the Hud showing589 # Sleep a bit to avoid a race with the Hud showing
658 sleep(0.5)590 sleep(0.5)
659 self.keybinding_release("panel/show_menus")591 self.keybinding_release("panel/show_menus")
660 self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(False)))592 self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(self.always_visible)))
661593
662 def test_window_buttons_cant_accept_keynav_focus(self):594 def test_window_buttons_cant_accept_keynav_focus(self):
663 """On a mouse down event over the window buttons595 """On a mouse down event over the window buttons
@@ -673,57 +605,149 @@
673605
674 self.assertThat(self.unity.hud.search_string, Eventually(Equals("HelloWorld")))606 self.assertThat(self.unity.hud.search_string, Eventually(Equals("HelloWorld")))
675607
676 def test_double_click_unmaximize_window(self):608
677 """Double clicking the grab area must unmaximize a maximized window."""609class PanelWindowButtonsActionsTests(PanelTestsBase):
678 gedit_win = self.open_new_application_window("Text Editor", maximized=True)610 """Test WindowButtons actions on windows, focused or not depending on LIM"""
679611 restored_on_top = False
680 self.panel.move_mouse_over_grab_area()612 scenarios = multiply_scenarios(_make_monitor_scenarios(),
681 self.mouse.click()613 (_make_menu_modes_scenarios() +
682 self.mouse.click()614 [('Locally Integrated Menus with restored on Top',
683615 {'lim': True, 'restored_on_top': True})]))
684 self.assertThat(self.panel.title, Eventually(Equals(gedit_win.application.name)))616
617 def setUp(self):
618 super(PanelWindowButtonsActionsTests, self).setUp()
619 self.text_win = self.open_new_application_window("Text Editor", maximized=True)
620
621 if self.restored_on_top:
622 self.open_new_application_window("Calculator")
623
624 def test_window_buttons_update_visual_state(self):
625 """Window button must update its state in response to mouse events."""
626 self.panel.move_mouse_over_window_buttons()
627 button = self.panel.window_buttons.unmaximize
628
629 self.assertThat(self.panel.window_buttons.focused, Eventually(Equals(not self.restored_on_top)))
630 self.assertThat(button.visual_state, Eventually(Equals("normal")))
631
632 button.mouse_move_to()
633 self.assertThat(button.visual_state, Eventually(Equals("prelight")))
634
635 self.mouse.press()
636 self.addCleanup(self.mouse.release)
637 self.assertThat(button.visual_state, Eventually(Equals("pressed")))
638
639 def test_window_buttons_cancel(self):
640 """Window buttons must ignore clicks when the mouse released outside
641 their area.
642 """
643 self.panel.move_mouse_over_window_buttons()
644
645 button = self.panel.window_buttons.unmaximize
646 button.mouse_move_to()
647 self.mouse.press()
648 self.assertThat(button.visual_state, Eventually(Equals("pressed")))
649 self.panel.move_mouse_below_the_panel()
650 self.mouse.release()
651
652 self.assertThat(self.text_win.is_maximized, Equals(True))
653
654 def test_window_buttons_close_button_works_for_window(self):
655 """Close window button must actually closes a window."""
656 win_xid = self.text_win.x_id
657
658 self.panel.window_buttons.close.mouse_click()
659 self.assertNoWindowOpenWithXid(win_xid)
660
661 def test_window_buttons_close_follows_fitts_law(self):
662 """Tests that the 'Close' button is activated when clicking at 0,0.
663
664 See bug #839690
665 """
666 win_xid = self.text_win.x_id
667
668 self.panel.move_mouse_over_window_buttons()
669 screen_x, screen_y = self.display.get_screen_geometry(self.panel_monitor)[:2]
670 self.mouse.move(screen_x, screen_y)
671 self.mouse.click()
672
673 self.assertNoWindowOpenWithXid(win_xid)
674
675 def test_window_buttons_minimize_button_works_for_window(self):
676 """Tests that the window button 'Minimize' actually minimizes a window."""
677 self.panel.window_buttons.minimize.mouse_click()
678 self.assertProperty(self.text_win, is_hidden=True)
679
680 def test_window_buttons_minimize_follows_fitts_law(self):
681 """Tests that the 'Minimize' button is conform to Fitts's Law.
682
683 See bug #839690
684 """
685 self.panel.move_mouse_over_window_buttons()
686 button = self.panel.window_buttons.minimize
687 target_x = button.x + button.width / 2
688 target_y = self.display.get_screen_geometry(self.panel_monitor)[1]
689 self.mouse.move(target_x, target_y)
690 self.mouse.click()
691
692 self.assertProperty(self.text_win, is_hidden=True)
693
694 def test_window_buttons_unmaximize_button_works_for_window(self):
695 """Tests that the window button 'Unmaximize' actually unmaximizes a window."""
696 self.panel.window_buttons.unmaximize.mouse_click()
697
698 self.assertProperties(self.text_win, is_maximized=False, is_focused=True)
699 self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(False)))
700
701 def test_window_buttons_unmaximize_follows_fitts_law(self):
702 """Tests that the 'Unmaximize' button is conform to Fitts's Law.
703
704 See bug #839690
705 """
706 button = self.panel.window_buttons.unmaximize
707 button.mouse_move_to()
708 target_x = button.x + button.width / 2
709 target_y = self.display.get_screen_geometry(self.panel_monitor)[1]
710 self.mouse.move(target_x, target_y)
711 sleep(1)
712 self.mouse.click()
713
714 self.assertProperty(self.text_win, is_maximized=False)
685715
686716
687class PanelHoverTests(PanelTestsBase):717class PanelHoverTests(PanelTestsBase):
688 """Tests with the mouse pointer hovering the panel area."""718 """Tests with the mouse pointer hovering the panel area."""
689719
690 scenarios = _make_monitor_scenarios()720 scenarios = _make_scenarios()
691721
692 def test_only_menus_show_for_restored_window_on_mouse_in_window_btn_area(self):722 def test_only_menus_show_for_restored_window_on_mouse_in_window_btn_area(self):
693 """Restored windows should only show menus when the mouse is in the window723 """Restored windows should only show menus when the mouse is in the window
694 button area.724 button area.
695 """725 """
696 self.open_new_application_window("Calculator",726 self.open_new_application_window("Calculator")
697 maximized=False,
698 move_to_monitor=True)
699 self.sleep_menu_settle_period()727 self.sleep_menu_settle_period()
700728
701 self.panel.move_mouse_over_window_buttons()729 self.panel.move_mouse_over_window_buttons()
702730
703 self.assertThat(self.panel.menus_shown, Eventually(Equals(True)))731 self.assertThat(self.panel.menus_shown, Eventually(Equals(not self.lim)))
704 self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(False)))732 self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(False)))
705733
706 def test_only_menus_show_for_restored_window_on_mouse_in_menu_area(self):734 def test_only_menus_show_for_restored_window_on_mouse_in_menu_area(self):
707 """Restored windows should only show menus when the mouse is in the window735 """Restored windows should only show menus when the mouse is in the window
708 menu area.736 menu area.
709 """737 """
710 self.open_new_application_window("Calculator",738 self.open_new_application_window("Calculator")
711 maximized=False,
712 move_to_monitor=True)
713 self.sleep_menu_settle_period()739 self.sleep_menu_settle_period()
714740
715 self.panel.move_mouse_over_menus()741 self.panel.move_mouse_over_menus()
716742
717 self.assertThat(self.panel.menus_shown, Eventually(Equals(True)))743 self.assertThat(self.panel.menus_shown, Eventually(Equals(not self.lim)))
718 self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(False)))744 self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(False)))
719745
720 def test_only_menus_show_for_restored_window_on_mouse_in_grab_area(self):746 def test_only_menus_show_for_restored_window_on_mouse_in_grab_area(self):
721 """Restored windows should only show menus when the mouse is in the panel747 """Restored windows should only show menus when the mouse is in the panel
722 grab area.748 grab area.
723 """749 """
724 self.open_new_application_window("Calculator",750 self.open_new_application_window("Calculator")
725 maximized=False,
726 move_to_monitor=True)
727 self.sleep_menu_settle_period()751 self.sleep_menu_settle_period()
728752
729 if self.panel.grab_area.width <= 0:753 if self.panel.grab_area.width <= 0:
@@ -731,14 +755,12 @@
731755
732 self.panel.move_mouse_over_grab_area()756 self.panel.move_mouse_over_grab_area()
733757
734 self.assertThat(self.panel.menus_shown, Eventually(Equals(True)))758 self.assertThat(self.panel.menus_shown, Eventually(Equals(not self.lim)))
735 self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(False)))759 self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(False)))
736760
737 def test_hovering_over_indicators_does_not_show_app_menus(self):761 def test_hovering_over_indicators_does_not_show_app_menus(self):
738 """Hovering the mouse over the indicators must not show app menus."""762 """Hovering the mouse over the indicators must not show app menus."""
739 self.open_new_application_window("Calculator",763 self.open_new_application_window("Text Editor", maximized=True)
740 maximized=False,
741 move_to_monitor=True)
742 self.sleep_menu_settle_period()764 self.sleep_menu_settle_period()
743765
744 self.panel.move_mouse_over_menus()766 self.panel.move_mouse_over_menus()
@@ -754,9 +776,7 @@
754 """Menus and window buttons must be shown when the mouse is in the window776 """Menus and window buttons must be shown when the mouse is in the window
755 button area for a maximised application.777 button area for a maximised application.
756 """778 """
757 self.open_new_application_window("Text Editor",779 self.open_new_application_window("Text Editor", maximized=True)
758 maximized=True,
759 move_to_monitor=True)
760 self.sleep_menu_settle_period()780 self.sleep_menu_settle_period()
761781
762 self.panel.move_mouse_over_window_buttons()782 self.panel.move_mouse_over_window_buttons()
@@ -768,9 +788,7 @@
768 """Menus and window buttons must be shown when the mouse is in the menu788 """Menus and window buttons must be shown when the mouse is in the menu
769 area for a maximised application.789 area for a maximised application.
770 """790 """
771 self.open_new_application_window("Text Editor",791 self.open_new_application_window("Text Editor", maximized=True)
772 maximized=True,
773 move_to_monitor=True)
774 self.sleep_menu_settle_period()792 self.sleep_menu_settle_period()
775793
776 self.panel.move_mouse_over_menus()794 self.panel.move_mouse_over_menus()
@@ -785,9 +803,7 @@
785 if self.panel.grab_area.width <= 0:803 if self.panel.grab_area.width <= 0:
786 self.skipTest("Grab area is too small to run this test!")804 self.skipTest("Grab area is too small to run this test!")
787805
788 self.open_new_application_window("Text Editor",806 self.open_new_application_window("Text Editor", maximized=True)
789 maximized=True,
790 move_to_monitor=True)
791 self.sleep_menu_settle_period()807 self.sleep_menu_settle_period()
792808
793 self.panel.move_mouse_over_grab_area()809 self.panel.move_mouse_over_grab_area()
@@ -799,9 +815,7 @@
799 """Hovering the mouse over the indicators must hide the menus and window815 """Hovering the mouse over the indicators must hide the menus and window
800 buttons.816 buttons.
801 """817 """
802 self.open_new_application_window("Text Editor",818 self.open_new_application_window("Text Editor", maximized=True)
803 maximized=True,
804 move_to_monitor=True)
805 self.sleep_menu_settle_period()819 self.sleep_menu_settle_period()
806820
807 self.panel.move_mouse_over_menus()821 self.panel.move_mouse_over_menus()
@@ -811,14 +825,14 @@
811825
812 self.panel.move_mouse_over_indicators()826 self.panel.move_mouse_over_indicators()
813827
814 self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(False)))828 self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(self.lim)))
815 self.assertThat(self.panel.menus_shown, Eventually(Equals(False)))829 self.assertThat(self.panel.menus_shown, Eventually(Equals(False)))
816830
817 def test_hovering_indicators_open_menus(self):831 def test_hovering_indicators_open_menus(self):
818 """Opening an indicator entry, and then hovering on other entries must832 """Opening an indicator entry, and then hovering on other entries must
819 open them.833 open them.
820 """834 """
821 self.open_new_application_window("Text Editor")835 self.open_new_application_window("Text Editor", maximized=self.lim)
822 entries = self.panel.get_indicator_entries(include_hidden_menus=True)836 entries = self.panel.get_indicator_entries(include_hidden_menus=True)
823837
824 self.assertThat(len(entries), GreaterThan(0))838 self.assertThat(len(entries), GreaterThan(0))
@@ -832,7 +846,7 @@
832846
833class PanelMenuTests(PanelTestsBase):847class PanelMenuTests(PanelTestsBase):
834848
835 scenarios = _make_monitor_scenarios()849 scenarios = _make_scenarios()
836850
837 def start_test_app_with_menus(self):851 def start_test_app_with_menus(self):
838 window_spec = {852 window_spec = {
@@ -846,7 +860,12 @@
846 {"Title": "&Quit"}860 {"Title": "&Quit"}
847 ]861 ]
848 }862 }
849 self.launch_test_window(window_spec)863 test_win = self.launch_test_window(window_spec)
864 test_win.set_focus()
865 self.move_window_to_panel_monitor(test_win)
866 self.ensure_window_state(test_win, maximized=self.lim)
867
868 return test_win
850869
851 def test_menus_are_added_on_new_application(self):870 def test_menus_are_added_on_new_application(self):
852 """Tests that menus are added when a new application is opened."""871 """Tests that menus are added when a new application is opened."""
@@ -872,10 +891,13 @@
872 "Current panel entries are: %r" % self.panel.menus.get_entries())891 "Current panel entries are: %r" % self.panel.menus.get_entries())
873892
874 self.panel.move_mouse_over_grab_area()893 self.panel.move_mouse_over_grab_area()
875 self.assertThat(self.panel.title, Eventually(Equals(test_win.application.name)))894 expected = test_win.application.name if not self.lim else ""
895 self.assertThat(self.panel.title, Eventually(Equals(expected)))
876896
877 def test_menus_shows_when_new_application_is_opened(self):897 def test_menus_shows_when_new_application_is_opened(self):
878 """When starting a new application, menus must first show, then hide."""898 """When starting a new application, menus must first show, then hide."""
899 if self.lim:
900 self.skipTest("Menu discovery is disabled when LIM are enabled.")
879901
880 # This test requires the window to be opened on the monitor that is being tested and902 # This test requires the window to be opened on the monitor that is being tested and
881 # we cannot guarantee which monitor the window will open up on.903 # we cannot guarantee which monitor the window will open up on.
@@ -890,6 +912,9 @@
890912
891 def test_menus_dont_show_if_a_new_application_window_is_opened(self):913 def test_menus_dont_show_if_a_new_application_window_is_opened(self):
892 """This tests the menu discovery feature on new window for a know application."""914 """This tests the menu discovery feature on new window for a know application."""
915 if self.lim:
916 self.skipTest("Menu discovery is disabled when LIM are enabled.")
917
893 self.open_new_application_window("Character Map")918 self.open_new_application_window("Character Map")
894 self.sleep_menu_settle_period()919 self.sleep_menu_settle_period()
895920
@@ -917,7 +942,7 @@
917942
918 self.panel.move_mouse_over_menus()943 self.panel.move_mouse_over_menus()
919944
920 self.assertThat(self.panel.menus_shown, Eventually(Equals(True)))945 self.assertThat(self.panel.menus_shown, Eventually(Equals(not self.lim)))
921946
922 def test_menus_dont_show_for_maximized_window_on_mouse_out(self):947 def test_menus_dont_show_for_maximized_window_on_mouse_out(self):
923 """Maximized window menus must not show when the mouse is outside the948 """Maximized window menus must not show when the mouse is outside the
@@ -947,7 +972,7 @@
947972
948 def test_menus_dont_show_with_hud(self):973 def test_menus_dont_show_with_hud(self):
949 """Tests that menus are not showing when opening the HUD."""974 """Tests that menus are not showing when opening the HUD."""
950 self.open_new_application_window("Text Editor", maximized=True)975 self.open_new_application_window("Character Map", maximized=True)
951 self.unity.hud.ensure_visible()976 self.unity.hud.ensure_visible()
952 self.addCleanup(self.unity.hud.ensure_hidden)977 self.addCleanup(self.unity.hud.ensure_hidden)
953978
@@ -957,11 +982,13 @@
957class PanelIndicatorEntryTests(PanelTestsBase):982class PanelIndicatorEntryTests(PanelTestsBase):
958 """Tests for the indicator entries, including both menu and indicators."""983 """Tests for the indicator entries, including both menu and indicators."""
959984
960 scenarios = _make_monitor_scenarios()985 scenarios = _make_scenarios()
961986
962 def open_app_and_get_menu_entry(self):987 def open_app_and_get_menu_entry(self):
963 """Open the test app and wait for the menu entry to appear."""988 """Open the test app and wait for the menu entry to appear."""
964 self.open_new_application_window("Calculator")989 self.open_new_application_window("Remmina" if self.lim else "Calculator",
990 maximized=self.lim)
991
965 refresh_fn = lambda: len(self.panel.menus.get_entries())992 refresh_fn = lambda: len(self.panel.menus.get_entries())
966 self.assertThat(refresh_fn, Eventually(GreaterThan(0)))993 self.assertThat(refresh_fn, Eventually(GreaterThan(0)))
967 menu_entry = self.panel.menus.get_entries()[0]994 menu_entry = self.panel.menus.get_entries()[0]
@@ -1033,7 +1060,7 @@
10331060
1034class PanelKeyNavigationTests(PanelTestsBase):1061class PanelKeyNavigationTests(PanelTestsBase):
10351062
1036 scenarios = _make_monitor_scenarios()1063 scenarios = _make_scenarios()
10371064
1038 def get_active_indicator(self):1065 def get_active_indicator(self):
1039 """Get the active indicator in a safe manner.1066 """Get the active indicator in a safe manner.
@@ -1048,17 +1075,17 @@
1048 """Pressing the open-menus keybinding must open the first indicator."""1075 """Pressing the open-menus keybinding must open the first indicator."""
1049 self.open_new_application_window("Calculator")1076 self.open_new_application_window("Calculator")
1050 refresh_fn = lambda: len(self.panel.menus.get_entries())1077 refresh_fn = lambda: len(self.panel.menus.get_entries())
1051 self.assertThat(refresh_fn, Eventually(GreaterThan(0)))1078 self.assertThat(refresh_fn, Eventually(Equals(0) if self.lim else GreaterThan(0)))
1052 self.addCleanup(self.keyboard.press_and_release, "Escape")1079 self.addCleanup(self.keyboard.press_and_release, "Escape")
1053 self.keybinding("panel/open_first_menu")1080 self.keybinding("panel/open_first_menu")
10541081
1055 open_indicator = self.get_active_indicator()1082 open_indicator = self.get_active_indicator()
1056 expected_indicator = self.panel.get_indicator_entries(include_hidden_menus=True)[0]1083 expected_indicator = self.panel.get_indicator_entries(include_hidden_menus=not self.lim)[0]
1057 self.assertThat(open_indicator.entry_id, Eventually(Equals(expected_indicator.entry_id)))1084 self.assertThat(open_indicator.entry_id, Eventually(Equals(expected_indicator.entry_id)))
10581085
1059 def test_panel_hold_show_menu_works(self):1086 def test_panel_hold_show_menu_works(self):
1060 """Holding the show menu key must reveal the menu with mnemonics."""1087 """Holding the show menu key must reveal the menu with mnemonics."""
1061 self.open_new_application_window("Text Editor")1088 self.open_new_application_window("Text Editor", maximized=self.lim)
1062 refresh_fn = lambda: len(self.panel.menus.get_entries())1089 refresh_fn = lambda: len(self.panel.menus.get_entries())
1063 self.assertThat(refresh_fn, Eventually(GreaterThan(0)))1090 self.assertThat(refresh_fn, Eventually(GreaterThan(0)))
1064 self.addCleanup(self.keyboard.press_and_release, "Escape")1091 self.addCleanup(self.keyboard.press_and_release, "Escape")
@@ -1073,7 +1100,7 @@
10731100
1074 def test_panel_menu_accelerators_work(self):1101 def test_panel_menu_accelerators_work(self):
1075 """Pressing a valid menu accelerator must open the correct menu item."""1102 """Pressing a valid menu accelerator must open the correct menu item."""
1076 self.open_new_application_window("Text Editor")1103 self.open_new_application_window("Text Editor", maximized=self.lim)
1077 refresh_fn = lambda: len(self.panel.menus.get_entries())1104 refresh_fn = lambda: len(self.panel.menus.get_entries())
1078 self.assertThat(refresh_fn, Eventually(GreaterThan(0)))1105 self.assertThat(refresh_fn, Eventually(GreaterThan(0)))
1079 self.addCleanup(self.keyboard.press_and_release, "Escape")1106 self.addCleanup(self.keyboard.press_and_release, "Escape")
@@ -1087,7 +1114,7 @@
1087 calc_win = self.open_new_application_window("Calculator")1114 calc_win = self.open_new_application_window("Calculator")
1088 self.assertProperty(calc_win, is_focused=True)1115 self.assertProperty(calc_win, is_focused=True)
10891116
1090 available_indicators = self.panel.get_indicator_entries(include_hidden_menus=True)1117 available_indicators = self.panel.get_indicator_entries(include_hidden_menus=not self.lim)
10911118
1092 self.keybinding("panel/open_first_menu")1119 self.keybinding("panel/open_first_menu")
1093 self.addCleanup(self.keyboard.press_and_release, "Escape")1120 self.addCleanup(self.keyboard.press_and_release, "Escape")
@@ -1102,7 +1129,7 @@
1102 calc_win = self.open_new_application_window("Calculator")1129 calc_win = self.open_new_application_window("Calculator")
1103 self.assertProperty(calc_win, is_focused=True)1130 self.assertProperty(calc_win, is_focused=True)
11041131
1105 available_indicators = self.panel.get_indicator_entries(include_hidden_menus=True)1132 available_indicators = self.panel.get_indicator_entries(include_hidden_menus=not self.lim)
11061133
1107 self.keybinding("panel/open_first_menu")1134 self.keybinding("panel/open_first_menu")
1108 self.addCleanup(self.keyboard.press_and_release, "Escape")1135 self.addCleanup(self.keyboard.press_and_release, "Escape")
@@ -1118,14 +1145,12 @@
1118 opened with the keyboard.1145 opened with the keyboard.
1119 """1146 """
1120 self.open_new_application_window("Calculator")1147 self.open_new_application_window("Calculator")
1121 available_indicators = self.panel.get_indicator_entries(include_hidden_menus=True)1148 available_indicators = self.panel.get_indicator_entries(include_hidden_menus=not self.lim)
11221149
1123 self.keybinding("panel/open_first_menu")1150 self.keybinding("panel/open_first_menu")
1124 self.addCleanup(self.keyboard.press_and_release, "Escape")1151 self.addCleanup(self.keyboard.press_and_release, "Escape")
11251152
1126 available_indicators[2].mouse_move_to()1153 available_indicators[2].mouse_move_to()
1127 self.addCleanup(self.panel.move_mouse_below_the_panel)
1128
1129 self.assertThat(available_indicators[2].active, Eventually(Equals(True)))1154 self.assertThat(available_indicators[2].active, Eventually(Equals(True)))
11301155
1131 self.keybinding("panel/prev_indicator")1156 self.keybinding("panel/prev_indicator")
@@ -1135,11 +1160,10 @@
1135class PanelGrabAreaTests(PanelTestsBase):1160class PanelGrabAreaTests(PanelTestsBase):
1136 """Panel grab area tests."""1161 """Panel grab area tests."""
11371162
1138 scenarios = _make_monitor_scenarios()1163 scenarios = _make_scenarios()
11391164
1140 def move_mouse_over_grab_area(self):1165 def move_mouse_over_grab_area(self):
1141 self.panel.move_mouse_over_grab_area()1166 self.panel.move_mouse_over_grab_area()
1142 self.addCleanup(self.panel.move_mouse_below_the_panel)
1143 sleep(.1)1167 sleep(.1)
11441168
1145 def test_unmaximize_from_grab_area_works(self):1169 def test_unmaximize_from_grab_area_works(self):
@@ -1192,6 +1216,29 @@
1192 self.assertThat(self.unity.hud.search_string, Eventually(Equals("HelloWorld")))1216 self.assertThat(self.unity.hud.search_string, Eventually(Equals("HelloWorld")))
11931217
11941218
1219class PanelLimTests(PanelTestsBase):
1220
1221 scenarios = _make_monitor_scenarios()
1222
1223 def setUp(self):
1224 self.lim = True
1225 super(PanelLimTests, self).setUp()
1226
1227 def test_title_focus_on_maximized_state_changes(self):
1228 text_win = self.open_new_application_window("Text Editor", maximized=True)
1229 self.assertThat(self.panel.focused, Eventually(Equals(True)))
1230 self.assertThat(self.panel.title, Eventually(Equals(text_win.title)))
1231
1232 self.open_new_application_window("Calculator")
1233 self.assertThat(self.panel.focused, Eventually(Equals(False)))
1234 self.assertThat(self.panel.title, Eventually(Equals(text_win.title)))
1235
1236 text_win.set_focus()
1237 self.assertProperty(text_win, is_focused=True)
1238 self.assertThat(self.panel.focused, Eventually(Equals(True)))
1239 self.assertThat(self.panel.title, Eventually(Equals(text_win.title)))
1240
1241
1195class PanelCrossMonitorsTests(PanelTestsBase):1242class PanelCrossMonitorsTests(PanelTestsBase):
1196 """Multimonitor panel tests."""1243 """Multimonitor panel tests."""
11971244
11981245
=== modified file 'tests/autopilot/unity/tests/test_wm_keybindings.py'
--- tests/autopilot/unity/tests/test_wm_keybindings.py 2013-12-04 19:42:43 +0000
+++ tests/autopilot/unity/tests/test_wm_keybindings.py 2015-02-19 19:24:14 +0000
@@ -21,27 +21,24 @@
2121
22 def open_panel_menu(self):22 def open_panel_menu(self):
23 panel = self.unity.panels.get_panel_for_monitor(0)23 panel = self.unity.panels.get_panel_for_monitor(0)
24 self.assertThat(lambda: len(panel.menus.get_entries()), Eventually(GreaterThan(0)))24 self.assertThat(lambda: len(panel.get_indicator_entries()), Eventually(GreaterThan(0)))
25 self.addCleanup(self.keyboard.press_and_release, "Escape")25 self.addCleanup(self.keyboard.press_and_release, "Escape")
26 self.keybinding("panel/open_first_menu")26 self.keybinding("panel/open_first_menu")
27 self.assertThat(self.unity.panels.get_active_indicator, Eventually(NotEquals(None)))27 self.assertThat(self.unity.panels.get_active_indicator, Eventually(NotEquals(None)))
2828
29 def test_dash_shows_on_menus_opened(self):29 def test_dash_shows_on_menus_opened(self):
30 self.process_manager.start_app_window("Calculator")
31 self.open_panel_menu()30 self.open_panel_menu()
32 self.addCleanup(self.unity.dash.ensure_hidden)31 self.addCleanup(self.unity.dash.ensure_hidden)
33 self.unity.dash.ensure_visible()32 self.unity.dash.ensure_visible()
34 self.assertThat(self.unity.panels.get_active_indicator, Eventually(Equals(None)))33 self.assertThat(self.unity.panels.get_active_indicator, Eventually(Equals(None)))
3534
36 def test_hud_shows_on_menus_opened(self):35 def test_hud_shows_on_menus_opened(self):
37 self.process_manager.start_app_window("Calculator")
38 self.open_panel_menu()36 self.open_panel_menu()
39 self.addCleanup(self.unity.hud.ensure_hidden)37 self.addCleanup(self.unity.hud.ensure_hidden)
40 self.unity.hud.ensure_visible()38 self.unity.hud.ensure_visible()
41 self.assertThat(self.unity.panels.get_active_indicator, Eventually(Equals(None)))39 self.assertThat(self.unity.panels.get_active_indicator, Eventually(Equals(None)))
4240
43 def test_switcher_shows_on_menus_opened(self):41 def test_switcher_shows_on_menus_opened(self):
44 self.process_manager.start_app_window("Calculator")
45 self.open_panel_menu()42 self.open_panel_menu()
46 self.addCleanup(self.unity.switcher.terminate)43 self.addCleanup(self.unity.switcher.terminate)
47 self.unity.switcher.initiate()44 self.unity.switcher.initiate()
@@ -49,7 +46,6 @@
49 self.assertThat(self.unity.panels.get_active_indicator, Eventually(Equals(None)))46 self.assertThat(self.unity.panels.get_active_indicator, Eventually(Equals(None)))
5047
51 def test_shortcut_hints_shows_on_menus_opened(self):48 def test_shortcut_hints_shows_on_menus_opened(self):
52 self.process_manager.start_app_window("Calculator")
53 self.open_panel_menu()49 self.open_panel_menu()
54 self.addCleanup(self.unity.shortcut_hint.ensure_hidden)50 self.addCleanup(self.unity.shortcut_hint.ensure_hidden)
55 self.unity.shortcut_hint.show()51 self.unity.shortcut_hint.show()
@@ -57,7 +53,6 @@
57 self.assertThat(self.unity.panels.get_active_indicator, Eventually(Equals(None)))53 self.assertThat(self.unity.panels.get_active_indicator, Eventually(Equals(None)))
5854
59 def test_spread_shows_on_menus_opened(self):55 def test_spread_shows_on_menus_opened(self):
60 self.process_manager.start_app_window("Calculator")
61 self.open_panel_menu()56 self.open_panel_menu()
62 self.addCleanup(self.unity.window_manager.terminate_spread)57 self.addCleanup(self.unity.window_manager.terminate_spread)
63 self.unity.window_manager.initiate_spread()58 self.unity.window_manager.initiate_spread()
6459
=== modified file 'tests/mock-application.h'
--- tests/mock-application.h 2014-03-21 04:40:12 +0000
+++ tests/mock-application.h 2015-02-19 19:24:14 +0000
@@ -20,7 +20,7 @@
20#ifndef TESTS_MOCK_APPLICATION_H20#ifndef TESTS_MOCK_APPLICATION_H
21#define TESTS_MOCK_APPLICATION_H21#define TESTS_MOCK_APPLICATION_H
2222
23#include <map>23#include <unordered_map>
24#include <gmock/gmock.h>24#include <gmock/gmock.h>
25#include <gio/gdesktopappinfo.h>25#include <gio/gdesktopappinfo.h>
26#include <UnityCore/GLibWrapper.h>26#include <UnityCore/GLibWrapper.h>
@@ -360,7 +360,7 @@
360 }360 }
361361
362private:362private:
363 typedef std::map<std::string, unity::ApplicationPtr> AppMap;363 typedef std::unordered_map<std::string, unity::ApplicationPtr> AppMap;
364 AppMap app_map_;364 AppMap app_map_;
365};365};
366366
367367
=== modified file 'tests/test_dbus_indicators.cpp'
--- tests/test_dbus_indicators.cpp 2013-03-25 18:22:32 +0000
+++ tests/test_dbus_indicators.cpp 2015-02-19 19:24:14 +0000
@@ -5,6 +5,7 @@
5#include <UnityCore/GLibWrapper.h>5#include <UnityCore/GLibWrapper.h>
6#include <UnityCore/DBusIndicators.h>6#include <UnityCore/DBusIndicators.h>
77
8#include "panel-service-private.h"
8#include "test_utils.h"9#include "test_utils.h"
910
10using namespace unity;11using namespace unity;
@@ -50,10 +51,8 @@
5051
51 GVariant* CallPanelMethod(std::string const& name) const52 GVariant* CallPanelMethod(std::string const& name) const
52 {53 {
53 return g_dbus_connection_call_sync(session,54 return g_dbus_connection_call_sync(session, "com.canonical.Unity.Test",
54 "com.canonical.Unity.Test",55 UPS_PATH, UPS_IFACE,
55 "/com/canonical/Unity/Panel/Service",
56 "com.canonical.Unity.Panel.Service",
57 name.c_str(),56 name.c_str(),
58 NULL,57 NULL,
59 NULL,58 NULL,
6059
=== modified file 'tests/test_indicator.cpp'
--- tests/test_indicator.cpp 2014-01-27 17:31:30 +0000
+++ tests/test_indicator.cpp 2015-02-19 19:24:14 +0000
@@ -44,7 +44,7 @@
4444
45 MOCK_CONST_METHOD0(Updated, void());45 MOCK_CONST_METHOD0(Updated, void());
46 MOCK_CONST_METHOD1(EntryAdded, void(Entry::Ptr const&));46 MOCK_CONST_METHOD1(EntryAdded, void(Entry::Ptr const&));
47 MOCK_CONST_METHOD1(EntryRemoved, void(std::string const&));47 MOCK_CONST_METHOD1(EntryRemoved, void(Entry::Ptr const&));
48 MOCK_CONST_METHOD5(ShowMenu, void(std::string const&, unsigned, int, int, unsigned));48 MOCK_CONST_METHOD5(ShowMenu, void(std::string const&, unsigned, int, int, unsigned));
49 MOCK_CONST_METHOD1(SecondaryActivate, void(std::string const&));49 MOCK_CONST_METHOD1(SecondaryActivate, void(std::string const&));
50 MOCK_CONST_METHOD2(Scroll, void(std::string const&, int));50 MOCK_CONST_METHOD2(Scroll, void(std::string const&, int));
@@ -57,7 +57,6 @@
57 EXPECT_EQ(indicator.name(), "indicator-test");57 EXPECT_EQ(indicator.name(), "indicator-test");
58 EXPECT_FALSE(indicator.IsAppmenu());58 EXPECT_FALSE(indicator.IsAppmenu());
59 EXPECT_EQ(indicator.GetEntry("test-entry"), nullptr);59 EXPECT_EQ(indicator.GetEntry("test-entry"), nullptr);
60 EXPECT_EQ(indicator.EntryIndex("test-entry"), -1);
61 EXPECT_TRUE(indicator.GetEntries().empty());60 EXPECT_TRUE(indicator.GetEntries().empty());
62}61}
6362
@@ -69,17 +68,17 @@
69 Indicator indicator("indicator-test");68 Indicator indicator("indicator-test");
70 SigReceiver::Nice sig_receiver(indicator);69 SigReceiver::Nice sig_receiver(indicator);
7170
72 entry = new Entry("test-entry-1", "name-hint", "label", true, true, 0, "icon",71 entry = new Entry("test-entry-1", "name-hint", 0, "label", true, true, 0, "icon",
73 true, true, -1);72 true, true, -1);
74 Entry::Ptr entry1(entry);73 Entry::Ptr entry1(entry);
75 sync_data.push_back(entry1);74 sync_data.push_back(entry1);
7675
77 entry = new Entry("test-entry-2", "name-hint", "label", true, true, 0, "icon",76 entry = new Entry("test-entry-2", "name-hint", 0, "label", true, true, 0, "icon",
78 true, true, -1);77 true, true, -1);
79 Entry::Ptr entry2(entry);78 Entry::Ptr entry2(entry);
80 sync_data.push_back(entry2);79 sync_data.push_back(entry2);
8180
82 entry = new Entry("test-entry-3", "name-hint", "label", true, true, 0, "icon",81 entry = new Entry("test-entry-3", "name-hint", 0, "label", true, true, 0, "icon",
83 true, true, -1);82 true, true, -1);
84 Entry::Ptr entry3(entry);83 Entry::Ptr entry3(entry);
85 sync_data.push_back(entry3);84 sync_data.push_back(entry3);
@@ -97,31 +96,29 @@
97 indicator.Sync(sync_data);96 indicator.Sync(sync_data);
98 EXPECT_EQ(indicator.GetEntries().size(), 3);97 EXPECT_EQ(indicator.GetEntries().size(), 3);
99 EXPECT_EQ(indicator.GetEntry("test-entry-2"), entry2);98 EXPECT_EQ(indicator.GetEntry("test-entry-2"), entry2);
100 EXPECT_EQ(indicator.EntryIndex("test-entry-2"), 1);
101 // Mock::VerifyAndClearExpectations(&sig_receiver);99 // Mock::VerifyAndClearExpectations(&sig_receiver);
102100
103 // Sync the indicator removing an entry101 // Sync the indicator removing an entry
104 sync_data.remove(entry2);102 sync_data.erase(std::remove(sync_data.begin(), sync_data.end(), entry2), sync_data.end());
105 EXPECT_EQ(sync_data.size(), 2);103 EXPECT_EQ(sync_data.size(), 2);
106 EXPECT_CALL(sig_receiver, Updated());104 EXPECT_CALL(sig_receiver, Updated());
107 EXPECT_CALL(sig_receiver, EntryAdded(_)).Times(0);105 EXPECT_CALL(sig_receiver, EntryAdded(_)).Times(0);
108 EXPECT_CALL(sig_receiver, EntryRemoved(entry2->id()));106 EXPECT_CALL(sig_receiver, EntryRemoved(entry2));
109107
110 indicator.Sync(sync_data);108 indicator.Sync(sync_data);
111 EXPECT_EQ(indicator.GetEntries().size(), 2);109 EXPECT_EQ(indicator.GetEntries().size(), 2);
112 EXPECT_EQ(indicator.GetEntry("test-entry-2"), nullptr);110 EXPECT_EQ(indicator.GetEntry("test-entry-2"), nullptr);
113 EXPECT_EQ(indicator.EntryIndex("test-entry-2"), -1);
114111
115 // Sync the indicator removing an entry and adding a new one112 // Sync the indicator removing an entry and adding a new one
116 entry = new Entry("test-entry-4", "name-hint", "label", true, true, 0, "icon",113 entry = new Entry("test-entry-4", "name-hint", 0, "label", true, true, 0, "icon",
117 true, true, -1);114 true, true, -1);
118 Entry::Ptr entry4(entry);115 Entry::Ptr entry4(entry);
119 sync_data.push_back(entry4);116 sync_data.push_back(entry4);
120 sync_data.remove(entry3);117 sync_data.erase(std::remove(sync_data.begin(), sync_data.end(), entry3), sync_data.end());
121 EXPECT_EQ(sync_data.size(), 2);118 EXPECT_EQ(sync_data.size(), 2);
122119
123 EXPECT_CALL(sig_receiver, EntryAdded(entry4));120 EXPECT_CALL(sig_receiver, EntryAdded(entry4));
124 EXPECT_CALL(sig_receiver, EntryRemoved(entry3->id()));121 EXPECT_CALL(sig_receiver, EntryRemoved(entry3));
125 EXPECT_CALL(sig_receiver, Updated());122 EXPECT_CALL(sig_receiver, Updated());
126 indicator.Sync(sync_data);123 indicator.Sync(sync_data);
127 EXPECT_EQ(indicator.GetEntries().size(), 2);124 EXPECT_EQ(indicator.GetEntries().size(), 2);
@@ -129,8 +126,8 @@
129 // Remove all the indicators126 // Remove all the indicators
130127
131 EXPECT_CALL(sig_receiver, EntryAdded(_)).Times(0);128 EXPECT_CALL(sig_receiver, EntryAdded(_)).Times(0);
132 EXPECT_CALL(sig_receiver, EntryRemoved(entry1->id()));129 EXPECT_CALL(sig_receiver, EntryRemoved(entry1));
133 EXPECT_CALL(sig_receiver, EntryRemoved(entry4->id()));130 EXPECT_CALL(sig_receiver, EntryRemoved(entry4));
134 EXPECT_CALL(sig_receiver, Updated());131 EXPECT_CALL(sig_receiver, Updated());
135132
136 sync_data.clear();133 sync_data.clear();
@@ -144,13 +141,13 @@
144 SigReceiver::Nice sig_receiver(indicator);141 SigReceiver::Nice sig_receiver(indicator);
145 Indicator::Entries sync_data;142 Indicator::Entries sync_data;
146143
147 auto entry1 = std::make_shared<Entry>("test-entry-1", "name-hint", "label", true, true, 0, "icon", true, true, -1);144 auto entry1 = std::make_shared<Entry>("test-entry-1", "name-hint", 0, "label", true, true, 0, "icon", true, true, -1);
148 sync_data.push_back(entry1);145 sync_data.push_back(entry1);
149146
150 auto entry2 = std::make_shared<Entry>("test-entry-2", "name-hint", "label", true, true, 0, "icon", true, true, -1);147 auto entry2 = std::make_shared<Entry>("test-entry-2", "name-hint", 0, "label", true, true, 0, "icon", true, true, -1);
151 sync_data.push_back(entry2);148 sync_data.push_back(entry2);
152149
153 auto entry3 = std::make_shared<Entry>("test-entry-3", "name-hint", "label", true, true, 0, "icon", true, true, -1);150 auto entry3 = std::make_shared<Entry>("test-entry-3", "name-hint", 0, "label", true, true, 0, "icon", true, true, -1);
154 sync_data.push_back(entry3);151 sync_data.push_back(entry3);
155152
156 EXPECT_CALL(sig_receiver, Updated());153 EXPECT_CALL(sig_receiver, Updated());
@@ -162,7 +159,7 @@
162 EXPECT_CALL(sig_receiver, Updated()).Times(0);159 EXPECT_CALL(sig_receiver, Updated()).Times(0);
163 indicator.Sync(sync_data);160 indicator.Sync(sync_data);
164161
165 sync_data.remove(entry3);162 sync_data.erase(std::remove(sync_data.begin(), sync_data.end(), entry3), sync_data.end());
166 EXPECT_CALL(sig_receiver, Updated());163 EXPECT_CALL(sig_receiver, Updated());
167 indicator.Sync(sync_data);164 indicator.Sync(sync_data);
168165
@@ -176,7 +173,7 @@
176 Indicator indicator("indicator-test");173 Indicator indicator("indicator-test");
177 SigReceiver::Nice sig_receiver(indicator);174 SigReceiver::Nice sig_receiver(indicator);
178175
179 auto entry = std::make_shared<Entry>("test-entry-1", "name-hint", "label", true, true, 0, "icon", true, true, -1);176 auto entry = std::make_shared<Entry>("test-entry-1", "name-hint", 0, "label", true, true, 0, "icon", true, true, -1);
180 indicator.Sync({entry});177 indicator.Sync({entry});
181178
182 EXPECT_CALL(sig_receiver, ShowMenu(entry->id(), 123456789, 50, 100, 2));179 EXPECT_CALL(sig_receiver, ShowMenu(entry->id(), 123456789, 50, 100, 2));
@@ -194,7 +191,7 @@
194 Indicator indicator("indicator-test");191 Indicator indicator("indicator-test");
195 SigReceiver::Nice sig_receiver(indicator);192 SigReceiver::Nice sig_receiver(indicator);
196193
197 auto entry = std::make_shared<Entry>("test-entry-2", "name-hint", "label", true, true, 0, "icon", true, true, -1);194 auto entry = std::make_shared<Entry>("test-entry-2", "name-hint", 0, "label", true, true, 0, "icon", true, true, -1);
198 indicator.Sync({entry});195 indicator.Sync({entry});
199196
200 EXPECT_CALL(sig_receiver, SecondaryActivate(entry->id()));197 EXPECT_CALL(sig_receiver, SecondaryActivate(entry->id()));
@@ -206,7 +203,7 @@
206 Indicator indicator("indicator-test");203 Indicator indicator("indicator-test");
207 SigReceiver::Nice sig_receiver(indicator);204 SigReceiver::Nice sig_receiver(indicator);
208205
209 auto entry = std::make_shared<Entry>("test-entry-2", "name-hint", "label", true, true, 0, "icon", true, true, -1);206 auto entry = std::make_shared<Entry>("test-entry-2", "name-hint", 0, "label", true, true, 0, "icon", true, true, -1);
210 indicator.Sync({entry});207 indicator.Sync({entry});
211208
212 EXPECT_CALL(sig_receiver, Scroll(entry->id(), -5));209 EXPECT_CALL(sig_receiver, Scroll(entry->id(), -5));
213210
=== modified file 'tests/test_indicator_appmenu.cpp'
--- tests/test_indicator_appmenu.cpp 2012-12-04 00:33:18 +0000
+++ tests/test_indicator_appmenu.cpp 2015-02-19 19:24:14 +0000
@@ -1,6 +1,6 @@
1// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-1// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
2/*2/*
3 * Copyright (C) 2012 Canonical Ltd3 * Copyright (C) 2012-2015 Canonical Ltd
4 *4 *
5 * This program is free software: you can redistribute it and/or modify5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as6 * it under the terms of the GNU General Public License version 3 as
@@ -18,15 +18,41 @@
18 */18 */
1919
20#include <UnityCore/AppmenuIndicator.h>20#include <UnityCore/AppmenuIndicator.h>
2121#include <gmock/gmock.h>
22#include <gtest/gtest.h>
2322
24using namespace std;23using namespace std;
25using namespace unity;24using namespace unity;
26using namespace indicator;25using namespace indicator;
26using namespace testing;
2727
28namespace28namespace
29{29{
30struct SigReceiver : sigc::trackable
31{
32 typedef NiceMock<SigReceiver> Nice;
33
34 SigReceiver(AppmenuIndicator const& const_indicator)
35 {
36 auto& indicator = const_cast<AppmenuIndicator&>(const_indicator);
37 indicator.updated.connect(sigc::mem_fun(this, &SigReceiver::Updated));
38 indicator.updated_win.connect(sigc::mem_fun(this, &SigReceiver::UpdatedWin));
39 indicator.on_entry_added.connect(sigc::mem_fun(this, &SigReceiver::EntryAdded));
40 indicator.on_entry_removed.connect(sigc::mem_fun(this, &SigReceiver::EntryRemoved));
41 indicator.on_show_menu.connect(sigc::mem_fun(this, &SigReceiver::ShowMenu));
42 indicator.on_show_appmenu.connect(sigc::mem_fun(this, &SigReceiver::ShowAppmenu));
43 indicator.on_secondary_activate.connect(sigc::mem_fun(this, &SigReceiver::SecondaryActivate));
44 indicator.on_scroll.connect(sigc::mem_fun(this, &SigReceiver::Scroll));
45 }
46
47 MOCK_CONST_METHOD0(Updated, void());
48 MOCK_CONST_METHOD1(UpdatedWin, void(uint32_t));
49 MOCK_CONST_METHOD1(EntryAdded, void(Entry::Ptr const&));
50 MOCK_CONST_METHOD1(EntryRemoved, void(Entry::Ptr const&));
51 MOCK_CONST_METHOD5(ShowMenu, void(std::string const&, unsigned, int, int, unsigned));
52 MOCK_CONST_METHOD3(ShowAppmenu, void(unsigned, int, int));
53 MOCK_CONST_METHOD1(SecondaryActivate, void(std::string const&));
54 MOCK_CONST_METHOD2(Scroll, void(std::string const&, int));
55};
3056
31TEST(TestAppmenuIndicator, Construction)57TEST(TestAppmenuIndicator, Construction)
32{58{
@@ -39,25 +65,160 @@
39TEST(TestAppmenuIndicator, ShowAppmenu)65TEST(TestAppmenuIndicator, ShowAppmenu)
40{66{
41 AppmenuIndicator indicator("indicator-appmenu");67 AppmenuIndicator indicator("indicator-appmenu");
4268 SigReceiver::Nice sig_receiver(indicator);
43 bool signal_emitted = false;69
44 int show_x, show_y;70 EXPECT_CALL(sig_receiver, ShowAppmenu(123456789, 50, 100));
45 unsigned show_xid;
46
47 // Connecting to signals
48 indicator.on_show_appmenu.connect([&] (unsigned int xid, int x, int y) {
49 signal_emitted = true;
50 show_xid = xid;
51 show_x = x;
52 show_y = y;
53 });
54
55 indicator.ShowAppmenu(123456789, 50, 100);71 indicator.ShowAppmenu(123456789, 50, 100);
56 EXPECT_TRUE(signal_emitted);72}
5773
58 EXPECT_EQ(show_xid, 123456789);74TEST(TestAppmenuIndicator, Syncing)
59 EXPECT_EQ(show_x, 50);75{
60 EXPECT_EQ(show_y, 100);76 Indicator::Entries sync_data;
77
78 AppmenuIndicator indicator("indicator-appmenu");
79 SigReceiver::Nice sig_receiver(indicator);
80 const uint32_t parent_window1 = 12345;
81 const uint32_t parent_window2 = 54321;
82
83 auto entry1 = std::make_shared<Entry>("test-entry-1", "name-hint", parent_window1, "label", true, true, 0, "icon", true, true, -1);
84 sync_data.push_back(entry1);
85
86 auto entry2 = std::make_shared<Entry>("test-entry-2", "name-hint", parent_window1, "label", true, true, 0, "icon", true, true, -1);
87 sync_data.push_back(entry2);
88
89 auto entry3 = std::make_shared<Entry>("test-entry-3", "name-hint", parent_window2, "label", true, true, 0, "icon", true, true, -1);
90 sync_data.push_back(entry3);
91
92 // Sync the indicator, adding 3 entries
93 {
94 testing::InSequence s;
95 EXPECT_CALL(sig_receiver, EntryAdded(entry1));
96 EXPECT_CALL(sig_receiver, EntryAdded(entry2));
97 EXPECT_CALL(sig_receiver, EntryAdded(entry3));
98 EXPECT_CALL(sig_receiver, EntryRemoved(_)).Times(0);
99 EXPECT_CALL(sig_receiver, Updated());
100 }
101
102 EXPECT_CALL(sig_receiver, UpdatedWin(parent_window1));
103 EXPECT_CALL(sig_receiver, UpdatedWin(parent_window2));
104
105 indicator.Sync(sync_data);
106 EXPECT_EQ(indicator.GetEntriesForWindow(parent_window1), Indicator::Entries({entry1, entry2}));
107 EXPECT_EQ(indicator.GetEntriesForWindow(parent_window2), Indicator::Entries({entry3}));
108
109 // Sync the indicator removing an entry
110 sync_data.erase(std::remove(sync_data.begin(), sync_data.end(), entry2), sync_data.end());
111 ASSERT_EQ(sync_data.size(), 2);
112 EXPECT_CALL(sig_receiver, Updated());
113 EXPECT_CALL(sig_receiver, UpdatedWin(parent_window1));
114 EXPECT_CALL(sig_receiver, UpdatedWin(parent_window2)).Times(0);
115 EXPECT_CALL(sig_receiver, EntryAdded(_)).Times(0);
116 EXPECT_CALL(sig_receiver, EntryRemoved(entry2));
117
118 indicator.Sync(sync_data);
119 EXPECT_EQ(indicator.GetEntries().size(), 2);
120 EXPECT_EQ(indicator.GetEntry("test-entry-2"), nullptr);
121 EXPECT_EQ(indicator.GetEntriesForWindow(parent_window1), Indicator::Entries({entry1}));
122
123 // Sync the indicator removing an entry and adding a new one
124 auto entry4 = std::make_shared<Entry>("test-entry-4", "name-hint", parent_window2, "label", true, true, 0, "icon", true, true, -1);
125 sync_data.push_back(entry4);
126 sync_data.erase(std::remove(sync_data.begin(), sync_data.end(), entry3), sync_data.end());
127 EXPECT_EQ(sync_data.size(), 2);
128
129 EXPECT_CALL(sig_receiver, EntryAdded(entry4));
130 EXPECT_CALL(sig_receiver, EntryRemoved(entry3));
131 EXPECT_CALL(sig_receiver, Updated());
132 EXPECT_CALL(sig_receiver, UpdatedWin(parent_window1)).Times(0);
133 EXPECT_CALL(sig_receiver, UpdatedWin(parent_window2));
134 indicator.Sync(sync_data);
135 EXPECT_EQ(indicator.GetEntriesForWindow(parent_window1), Indicator::Entries({entry1}));
136 EXPECT_EQ(indicator.GetEntriesForWindow(parent_window2), Indicator::Entries({entry4}));
137
138 // Remove all the indicators
139 EXPECT_CALL(sig_receiver, EntryAdded(_)).Times(0);
140 EXPECT_CALL(sig_receiver, EntryRemoved(entry1));
141 EXPECT_CALL(sig_receiver, EntryRemoved(entry4));
142 EXPECT_CALL(sig_receiver, Updated());
143 EXPECT_CALL(sig_receiver, UpdatedWin(parent_window1));
144 EXPECT_CALL(sig_receiver, UpdatedWin(parent_window2));
145
146 sync_data.clear();
147 indicator.Sync(sync_data);
148
149 EXPECT_TRUE(indicator.GetEntriesForWindow(parent_window1).empty());
150 EXPECT_TRUE(indicator.GetEntriesForWindow(parent_window2).empty());
151}
152
153TEST(TestAppmenuIndicator, Updated)
154{
155 AppmenuIndicator indicator("indicator-test");
156 SigReceiver::Nice sig_receiver(indicator);
157 Indicator::Entries sync_data;
158 const uint32_t parent_window1 = 12345;
159 const uint32_t parent_window2 = 54321;
160
161 auto entry1 = std::make_shared<Entry>("test-entry-1", "name-hint", parent_window1, "label", true, true, 0, "icon", true, true, -1);
162 sync_data.push_back(entry1);
163
164 auto entry2 = std::make_shared<Entry>("test-entry-2", "name-hint", parent_window2, "label", true, true, 0, "icon", true, true, -1);
165 sync_data.push_back(entry2);
166
167 auto entry3 = std::make_shared<Entry>("test-entry-3", "name-hint", parent_window1, "label", true, true, 0, "icon", true, true, -1);
168 sync_data.push_back(entry3);
169
170 EXPECT_CALL(sig_receiver, Updated());
171
172 // Sync the indicator, adding 3 entries
173 indicator.Sync(sync_data);
174
175 // Readding the same entries, nothing is emitted
176 EXPECT_CALL(sig_receiver, Updated()).Times(0);
177 indicator.Sync(sync_data);
178
179 sync_data.erase(std::remove(sync_data.begin(), sync_data.end(), entry3), sync_data.end());
180 EXPECT_CALL(sig_receiver, Updated());
181 indicator.Sync(sync_data);
182
183 sync_data.push_back(entry3);
184 EXPECT_CALL(sig_receiver, Updated());
185 indicator.Sync(sync_data);
186}
187
188TEST(TestAppmenuIndicator, UpdatedWin)
189{
190 AppmenuIndicator indicator("indicator-test");
191 SigReceiver::Nice sig_receiver(indicator);
192 Indicator::Entries sync_data;
193 const uint32_t parent_window1 = 12345;
194 const uint32_t parent_window2 = 54321;
195
196 auto entry1 = std::make_shared<Entry>("test-entry-1", "name-hint", parent_window1, "label", true, true, 0, "icon", true, true, -1);
197 sync_data.push_back(entry1);
198
199 auto entry2 = std::make_shared<Entry>("test-entry-2", "name-hint", parent_window2, "label", true, true, 0, "icon", true, true, -1);
200 sync_data.push_back(entry2);
201
202 auto entry3 = std::make_shared<Entry>("test-entry-3", "name-hint", parent_window1, "label", true, true, 0, "icon", true, true, -1);
203 sync_data.push_back(entry3);
204
205 EXPECT_CALL(sig_receiver, UpdatedWin(parent_window1));
206 EXPECT_CALL(sig_receiver, UpdatedWin(parent_window2));
207
208 // Sync the indicator, adding 3 entries
209 indicator.Sync(sync_data);
210
211 // Readding the same entries, nothing is emitted
212 EXPECT_CALL(sig_receiver, UpdatedWin(_)).Times(0);
213 indicator.Sync(sync_data);
214
215 sync_data.erase(std::remove(sync_data.begin(), sync_data.end(), entry3), sync_data.end());
216 EXPECT_CALL(sig_receiver, UpdatedWin(entry3->parent_window()));
217 indicator.Sync(sync_data);
218
219 sync_data.push_back(entry3);
220 EXPECT_CALL(sig_receiver, UpdatedWin(entry3->parent_window()));
221 indicator.Sync(sync_data);
61}222}
62223
63}224}
64225
=== modified file 'tests/test_indicator_entry.cpp'
--- tests/test_indicator_entry.cpp 2014-02-07 23:54:15 +0000
+++ tests/test_indicator_entry.cpp 2015-02-19 19:24:14 +0000
@@ -36,11 +36,12 @@
36TEST(TestIndicatorEntry, TestConstruction)36TEST(TestIndicatorEntry, TestConstruction)
37{37{
3838
39 Entry entry("id", "name_hint", "label", true, true, 1, "some icon", false, true, -1);39 Entry entry("id", "name_hint", 12345, "label", true, true, 1, "some icon", false, true, -1);
4040
41 EXPECT_EQ(entry.id(), "id");41 EXPECT_EQ(entry.id(), "id");
42 EXPECT_EQ(entry.name_hint(), "name_hint");
43 EXPECT_EQ(entry.parent_window(), 12345);
42 EXPECT_EQ(entry.label(), "label");44 EXPECT_EQ(entry.label(), "label");
43 EXPECT_EQ(entry.name_hint(), "name_hint");
44 EXPECT_TRUE(entry.label_sensitive());45 EXPECT_TRUE(entry.label_sensitive());
45 EXPECT_TRUE(entry.label_visible());46 EXPECT_TRUE(entry.label_visible());
46 EXPECT_FALSE(entry.image_sensitive());47 EXPECT_FALSE(entry.image_sensitive());
@@ -55,10 +56,11 @@
5556
56TEST(TestIndicatorEntry, TestConstructionEmpty)57TEST(TestIndicatorEntry, TestConstructionEmpty)
57{58{
58 Entry entry("id", "name_hint");59 Entry entry("id", "name_hint", 12345);
5960
60 EXPECT_EQ(entry.id(), "id");61 EXPECT_EQ(entry.id(), "id");
61 EXPECT_EQ(entry.name_hint(), "name_hint");62 EXPECT_EQ(entry.name_hint(), "name_hint");
63 EXPECT_EQ(entry.parent_window(), 12345);
62 EXPECT_TRUE(entry.label().empty());64 EXPECT_TRUE(entry.label().empty());
63 EXPECT_FALSE(entry.label_sensitive());65 EXPECT_FALSE(entry.label_sensitive());
64 EXPECT_FALSE(entry.label_visible());66 EXPECT_FALSE(entry.label_visible());
@@ -74,8 +76,8 @@
7476
75TEST(TestIndicatorEntry, TestAssignment)77TEST(TestIndicatorEntry, TestAssignment)
76{78{
77 Entry entry("id", "name_hint", "label", true, true, 0, "some icon", false, true, 10);79 Entry entry("id", "name_hint", 12345, "label", true, true, 0, "some icon", false, true, 10);
78 Entry other_entry("other_id", "other_name_hint", "other_label", false, false, 2, "other icon", true, false, 5);80 Entry other_entry("other_id", "other_name_hint", 54321, "other_label", false, false, 2, "other icon", true, false, 5);
7981
80 SigReceiver sig_receiver(entry);82 SigReceiver sig_receiver(entry);
81 EXPECT_CALL(sig_receiver, Updated());83 EXPECT_CALL(sig_receiver, Updated());
@@ -83,6 +85,7 @@
8385
84 EXPECT_EQ(entry.id(), "other_id");86 EXPECT_EQ(entry.id(), "other_id");
85 EXPECT_EQ(entry.name_hint(), "other_name_hint");87 EXPECT_EQ(entry.name_hint(), "other_name_hint");
88 EXPECT_EQ(entry.parent_window(), 54321);
86 EXPECT_EQ(entry.label(), "other_label");89 EXPECT_EQ(entry.label(), "other_label");
87 EXPECT_FALSE(entry.label_sensitive());90 EXPECT_FALSE(entry.label_sensitive());
88 EXPECT_FALSE(entry.label_visible());91 EXPECT_FALSE(entry.label_visible());
@@ -95,8 +98,8 @@
9598
96TEST(TestIndicatorEntry, TestShowNowEvents)99TEST(TestIndicatorEntry, TestShowNowEvents)
97{100{
98 Entry entry("id", "name_hint", "label", true, true,101 Entry entry("id", "name_hint", 0, "label", true, true,
99 0, "some icon", false, true, -1);102 0, "some icon", false, true, -1);
100 SigReceiver sig_receiver(entry);103 SigReceiver sig_receiver(entry);
101104
102 // Setting show_now to the same value doesn't emit any events.105 // Setting show_now to the same value doesn't emit any events.
@@ -116,7 +119,7 @@
116119
117TEST(TestIndicatorEntry, TestActiveEvents)120TEST(TestIndicatorEntry, TestActiveEvents)
118{121{
119 Entry entry("id", "name_hint", "label", true, true, 0, "some icon", false, true, -1);122 Entry entry("id", "name_hint", 0, "label", true, true, 0, "some icon", false, true, -1);
120123
121 SigReceiver sig_receiver(entry);124 SigReceiver sig_receiver(entry);
122125
@@ -137,7 +140,7 @@
137140
138TEST(TestIndicatorEntry, TestOnScroll)141TEST(TestIndicatorEntry, TestOnScroll)
139{142{
140 Entry entry("id", "name_hint", "label", true, true, 0, "some icon", false, true, -1);143 Entry entry("id", "name_hint", 0, "label", true, true, 0, "some icon", false, true, -1);
141 SigReceiver sig_receiver(entry);144 SigReceiver sig_receiver(entry);
142145
143 EXPECT_CALL(sig_receiver, OnScroll("id", 10));146 EXPECT_CALL(sig_receiver, OnScroll("id", 10));
@@ -149,16 +152,16 @@
149152
150TEST(TestIndicatorEntry, TestOnShowMenu)153TEST(TestIndicatorEntry, TestOnShowMenu)
151{154{
152 Entry entry("id", "name_hint", "label", true, true, 0, "some icon", false, true, -1);155 Entry entry("id", "name_hint", 123, "label", true, true, 0, "some icon", false, true, -1);
153 SigReceiver sig_receiver(entry);156 SigReceiver sig_receiver(entry);
154157
155 EXPECT_CALL(sig_receiver, OnShowMenu("id", 0, 10, 20, 1));158 EXPECT_CALL(sig_receiver, OnShowMenu("id", 123, 10, 20, 1));
156 entry.ShowMenu(10, 20, 1);159 entry.ShowMenu(10, 20, 1);
157}160}
158161
159TEST(TestIndicatorEntry, TestOnShowMenuXid)162TEST(TestIndicatorEntry, TestOnShowMenuXid)
160{163{
161 Entry entry("xid", "name_hint", "label", true, true, 0, "some icon", false, true, -1);164 Entry entry("xid", "name_hint", 0, "label", true, true, 0, "some icon", false, true, -1);
162 SigReceiver sig_receiver(entry);165 SigReceiver sig_receiver(entry);
163166
164 EXPECT_CALL(sig_receiver, OnShowMenu("xid", 88492615, 15, 25, 2));167 EXPECT_CALL(sig_receiver, OnShowMenu("xid", 88492615, 15, 25, 2));
@@ -167,7 +170,7 @@
167170
168TEST(TestIndicatorEntry, TestVisibility)171TEST(TestIndicatorEntry, TestVisibility)
169{172{
170 Entry entry("id", "name_hint", "label", true, true, 0, "some icon", false, false, -1);173 Entry entry("id", "name_hint", 0, "label", true, true, 0, "some icon", false, false, -1);
171174
172 EXPECT_TRUE(entry.visible());175 EXPECT_TRUE(entry.visible());
173176
@@ -208,7 +211,7 @@
208211
209TEST(TestIndicatorEntry, TestGeometry)212TEST(TestIndicatorEntry, TestGeometry)
210{213{
211 Entry entry("id", "name_hint", "label", true, true, 0, "some icon", false, true, -1);214 Entry entry("id", "name_hint", 0, "label", true, true, 0, "some icon", false, true, -1);
212 SigReceiver sig_receiver(entry);215 SigReceiver sig_receiver(entry);
213216
214 // Setting to the same value doesn't emit any events.217 // Setting to the same value doesn't emit any events.
215218
=== modified file 'tests/test_indicators.cpp'
--- tests/test_indicators.cpp 2014-02-11 03:11:47 +0000
+++ tests/test_indicators.cpp 2015-02-19 19:24:14 +0000
@@ -62,15 +62,15 @@
6262
63 Indicator::Ptr test_indicator_1 = indicators.AddIndicator("indicator-test-1");63 Indicator::Ptr test_indicator_1 = indicators.AddIndicator("indicator-test-1");
6464
65 entry = new Entry("indicator-test-1|entry-1", "name-hint-1", "label", true, true,65 entry = new Entry("indicator-test-1|entry-1", "name-hint-1", 0, "label", true, true,
66 0, "icon", true, true, -1);66 0, "icon", true, true, -1);
67 sync_data.push_back(Entry::Ptr(entry));67 sync_data.push_back(Entry::Ptr(entry));
6868
69 entry = new Entry("indicator-test-1|entry-2", "name-hint-2", "label", true, true,69 entry = new Entry("indicator-test-1|entry-2", "name-hint-2", 0, "label", true, true,
70 0, "icon", true, true, -1);70 0, "icon", true, true, -1);
71 sync_data.push_back(Entry::Ptr(entry));71 sync_data.push_back(Entry::Ptr(entry));
7272
73 entry = new Entry("indicator-test-1|entry-3", "name-hint-3", "label", true, true,73 entry = new Entry("indicator-test-1|entry-3", "name-hint-3", 0, "label", true, true,
74 0, "icon", true, true, -1);74 0, "icon", true, true, -1);
75 sync_data.push_back(Entry::Ptr(entry));75 sync_data.push_back(Entry::Ptr(entry));
7676
@@ -83,11 +83,11 @@
83 Indicator::Ptr test_indicator_2 = indicators.AddIndicator("indicator-test-2");83 Indicator::Ptr test_indicator_2 = indicators.AddIndicator("indicator-test-2");
84 sync_data.clear();84 sync_data.clear();
8585
86 entry = new Entry("indicator-test-2|entry-1", "name-hint-1", "label", true, true,86 entry = new Entry("indicator-test-2|entry-1", "name-hint-1", 0, "label", true, true,
87 0, "icon", true, true, -1);87 0, "icon", true, true, -1);
88 sync_data.push_back(Entry::Ptr(entry));88 sync_data.push_back(Entry::Ptr(entry));
8989
90 entry = new Entry("indicator-test-2|entry-2", "name-hint-2", "label", true, true,90 entry = new Entry("indicator-test-2|entry-2", "name-hint-2", 0, "label", true, true,
91 0, "icon", true, true, -1);91 0, "icon", true, true, -1);
92 sync_data.push_back(Entry::Ptr(entry));92 sync_data.push_back(Entry::Ptr(entry));
9393
9494
=== modified file 'tests/test_panel_menu_view.cpp'
--- tests/test_panel_menu_view.cpp 2014-03-21 04:40:12 +0000
+++ tests/test_panel_menu_view.cpp 2015-02-19 19:24:14 +0000
@@ -36,11 +36,22 @@
3636
37struct TestPanelMenuView : public testing::Test37struct TestPanelMenuView : public testing::Test
38{38{
39 TestPanelMenuView()
40 : menu_manager(std::make_shared<menu::MockManager>())
41 , menu_view(menu_manager)
42 {}
43
39 struct MockPanelMenuView : public PanelMenuView44 struct MockPanelMenuView : public PanelMenuView
40 {45 {
41 MockPanelMenuView()46 MockPanelMenuView(menu::Manager::Ptr const& menu_manager)
42 : PanelMenuView(std::make_shared<menu::MockManager>())47 : PanelMenuView(menu_manager)
43 {}48 {
49 view_opened_signal_.Disconnect();
50 active_win_changed_signal_.Disconnect();
51 active_app_changed_signal_.Disconnect();
52 view_closed_signal_.Disconnect();
53 maximized_wins_.clear();
54 }
4455
45 MOCK_METHOD0(QueueDraw, void());56 MOCK_METHOD0(QueueDraw, void());
46 MOCK_CONST_METHOD1(GetActiveViewName, std::string(bool));57 MOCK_CONST_METHOD1(GetActiveViewName, std::string(bool));
@@ -53,6 +64,7 @@
53 using PanelMenuView::titlebar_grab_area_;64 using PanelMenuView::titlebar_grab_area_;
54 using PanelMenuView::we_control_active_;65 using PanelMenuView::we_control_active_;
55 using PanelMenuView::spread_showing_;66 using PanelMenuView::spread_showing_;
67 using PanelMenuView::maximized_wins_;
56 };68 };
5769
58 nux::ObjectPtr<nux::BaseWindow> AddPanelToWindow(int monitor)70 nux::ObjectPtr<nux::BaseWindow> AddPanelToWindow(int monitor)
@@ -69,6 +81,7 @@
69 panel_win->ComputeContentSize();81 panel_win->ComputeContentSize();
7082
71 menu_view.SetMonitor(monitor);83 menu_view.SetMonitor(monitor);
84 menu_view.maximized_wins_.clear();
7285
73 return panel_win;86 return panel_win;
74 }87 }
@@ -79,6 +92,7 @@
79 MockUScreen uscreen;92 MockUScreen uscreen;
80 panel::Style panelStyle;93 panel::Style panelStyle;
81 testwrapper::StandaloneWM WM;94 testwrapper::StandaloneWM WM;
95 menu::MockManager::Ptr menu_manager;
82 testing::NiceMock<MockPanelMenuView> menu_view;96 testing::NiceMock<MockPanelMenuView> menu_view;
83};97};
8498
@@ -91,6 +105,7 @@
91105
92TEST_F(TestPanelMenuView, Escaping)106TEST_F(TestPanelMenuView, Escaping)
93{107{
108 menu_manager->integrated_menus = false;
94 ON_CALL(menu_view, GetActiveViewName(testing::_)).WillByDefault(Return("<>'"));109 ON_CALL(menu_view, GetActiveViewName(testing::_)).WillByDefault(Return("<>'"));
95 auto escapedText = "Panel d'Inici";110 auto escapedText = "Panel d'Inici";
96 ASSERT_TRUE(menu_view.GetCurrentTitle().empty());111 ASSERT_TRUE(menu_view.GetCurrentTitle().empty());
@@ -136,6 +151,7 @@
136TEST_P(ProgressTester, RestoreOnGrabInBiggerWorkArea)151TEST_P(ProgressTester, RestoreOnGrabInBiggerWorkArea)
137{152{
138 uscreen.SetupFakeMultiMonitor();153 uscreen.SetupFakeMultiMonitor();
154 connection::Manager conn;
139 unsigned monitor = uscreen.GetMonitors().size() - 1;155 unsigned monitor = uscreen.GetMonitors().size() - 1;
140 auto const& monitor_geo = uscreen.GetMonitorGeometry(monitor);156 auto const& monitor_geo = uscreen.GetMonitorGeometry(monitor);
141 WM->SetWorkareaGeometry(monitor_geo);157 WM->SetWorkareaGeometry(monitor_geo);
142158
=== modified file 'tests/test_panel_service.cpp'
--- tests/test_panel_service.cpp 2013-10-03 15:16:06 +0000
+++ tests/test_panel_service.cpp 2015-02-19 19:24:14 +0000
@@ -32,8 +32,8 @@
32{32{
33typedef std::tuple<glib::Object<GtkLabel>, glib::Object<GtkImage>> EntryObjects;33typedef std::tuple<glib::Object<GtkLabel>, glib::Object<GtkImage>> EntryObjects;
3434
35const std::string SYNC_ENTRY_VARIANT_FORMAT = "(ssssbbusbbi)";35const std::string SYNC_ENTRY_VARIANT_FORMAT = ENTRY_SIGNATURE;
36const std::string SYNC_ENTRIES_VARIANT_FORMAT = "(a"+SYNC_ENTRY_VARIANT_FORMAT+")";36const std::string SYNC_ENTRIES_VARIANT_FORMAT = "(" ENTRY_ARRAY_SIGNATURE ")";
3737
38struct TestPanelService : Test38struct TestPanelService : Test
39{39{
@@ -46,6 +46,7 @@
46 std::string indicator_id;46 std::string indicator_id;
47 std::string entry_id;47 std::string entry_id;
48 std::string entry_name_hint;48 std::string entry_name_hint;
49 uint32_t parent_window;
49 std::string label;50 std::string label;
50 bool label_sensitive;51 bool label_sensitive;
51 bool label_visible;52 bool label_visible;
@@ -63,6 +64,7 @@
63 gchar* indicator_id;64 gchar* indicator_id;
64 gchar* entry_id;65 gchar* entry_id;
65 gchar* entry_name_hint;66 gchar* entry_name_hint;
67 guint32 parent_window;
66 gchar* label;68 gchar* label;
67 gboolean label_sensitive;69 gboolean label_sensitive;
68 gboolean label_visible;70 gboolean label_visible;
@@ -77,6 +79,7 @@
77 &indicator_id,79 &indicator_id,
78 &entry_id,80 &entry_id,
79 &entry_name_hint,81 &entry_name_hint,
82 &parent_window,
80 &label,83 &label,
81 &label_sensitive,84 &label_sensitive,
82 &label_visible,85 &label_visible,
@@ -89,6 +92,7 @@
89 results.push_back({ glib::gchar_to_string(indicator_id),92 results.push_back({ glib::gchar_to_string(indicator_id),
90 glib::gchar_to_string(entry_id),93 glib::gchar_to_string(entry_id),
91 glib::gchar_to_string(entry_name_hint),94 glib::gchar_to_string(entry_name_hint),
95 parent_window,
92 glib::gchar_to_string(label),96 glib::gchar_to_string(label),
93 label_sensitive != FALSE,97 label_sensitive != FALSE,
94 label_visible != FALSE,98 label_visible != FALSE,
9599
=== modified file 'tests/test_service_panel.cpp'
--- tests/test_service_panel.cpp 2013-03-02 22:44:29 +0000
+++ tests/test_service_panel.cpp 2015-02-19 19:24:14 +0000
@@ -1,4 +1,5 @@
1#include "test_service_panel.h"1#include "test_service_panel.h"
2#include "panel-service-private.h"
23
3namespace unity4namespace unity
4{5{
@@ -9,11 +10,11 @@
9static const char * panel_interface =10static const char * panel_interface =
10"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"11"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
11"<node name=\"/\">\n"12"<node name=\"/\">\n"
12" <interface name=\"com.canonical.Unity.Panel.Service\">\n"13" <interface name=\"" UPS_IFACE "\">\n"
13"\n"14"\n"
14"<!-- Begin of real methods/signals -->\n"15"<!-- Begin of real methods/signals -->\n"
15" <method name='Sync'>"16" <method name='Sync'>"
16" <arg type='a(ssssbbusbbi)' name='state' direction='out'/>"17" <arg type='" ENTRY_ARRAY_SIGNATURE "' name='state' direction='out'/>"
17" </method>"18" </method>"
18"\n"19"\n"
19" <signal name='ReSync'>"20" <signal name='ReSync'>"
@@ -32,12 +33,13 @@
32"</node>\n"33"</node>\n"
33;34;
3435
35void add_entry_id(GVariantBuilder *b)36void add_entry_id(GVariantBuilder *b, gint priority)
36{37{
37 g_variant_builder_add (b, "(ssssbbusbbi)",38 g_variant_builder_add (b, ENTRY_SIGNATURE,
38 "test_indicator_id",39 "test_indicator_id",
39 "test_entry_id",40 "test_entry_id",
40 "test_entry_name_hint",41 "test_entry_name_hint",
42 0, /* parent window */
41 "test_entry_label",43 "test_entry_label",
42 TRUE, /* label sensitive */44 TRUE, /* label sensitive */
43 TRUE, /* label visible */45 TRUE, /* label visible */
@@ -45,15 +47,16 @@
45 "", /* image_data */47 "", /* image_data */
46 TRUE, /* image sensitive */48 TRUE, /* image sensitive */
47 TRUE, /* image visible */49 TRUE, /* image visible */
48 1 /* priority */);50 priority);
49}51}
5052
51void add_entry_id_2(GVariantBuilder *b)53void add_entry_id_2(GVariantBuilder *b, gint priority)
52{54{
53 g_variant_builder_add (b, "(ssssbbusbbi)",55 g_variant_builder_add (b, ENTRY_SIGNATURE,
54 "test_indicator_id",56 "test_indicator_id",
55 "test_entry_id2",57 "test_entry_id2",
56 "test_entry_name_hint2",58 "test_entry_name_hint2",
59 12345, /* parent window */
57 "test_entry_label2",60 "test_entry_label2",
58 TRUE, /* label sensitive */61 TRUE, /* label sensitive */
59 TRUE, /* label visible */62 TRUE, /* label visible */
@@ -61,7 +64,7 @@
61 "", /* image_data */64 "", /* image_data */
62 TRUE, /* image sensitive */65 TRUE, /* image sensitive */
63 TRUE, /* image visible */66 TRUE, /* image visible */
64 1 /* priority */);67 priority);
65}68}
66}69}
6770
@@ -73,7 +76,7 @@
73 auto object = glib::DBusObjectBuilder::GetObjectsForIntrospection(panel_interface).front();76 auto object = glib::DBusObjectBuilder::GetObjectsForIntrospection(panel_interface).front();
74 object->SetMethodsCallsHandler(sigc::mem_fun(this, &Panel::OnMethodCall));77 object->SetMethodsCallsHandler(sigc::mem_fun(this, &Panel::OnMethodCall));
7578
76 server_.AddObject(object, "/com/canonical/Unity/Panel/Service");79 server_.AddObject(object, UPS_PATH);
77}80}
7881
79GVariant* Panel::OnMethodCall(std::string const& method, GVariant *parameters)82GVariant* Panel::OnMethodCall(std::string const& method, GVariant *parameters)
@@ -82,18 +85,18 @@
82 {85 {
83 GVariantBuilder b;86 GVariantBuilder b;
8487
85 g_variant_builder_init (&b, G_VARIANT_TYPE ("(a(ssssbbusbbi))"));88 g_variant_builder_init (&b, G_VARIANT_TYPE ("(" ENTRY_ARRAY_SIGNATURE ")"));
86 g_variant_builder_open (&b, G_VARIANT_TYPE ("a(ssssbbusbbi)"));89 g_variant_builder_open (&b, G_VARIANT_TYPE (ENTRY_ARRAY_SIGNATURE));
8790
88 if (sync_return_mode_ == 0)91 if (sync_return_mode_ == 0)
89 {92 {
90 add_entry_id(&b);93 add_entry_id(&b, 1);
91 add_entry_id_2(&b);94 add_entry_id_2(&b, 2);
92 }95 }
93 else if (sync_return_mode_ == 1)96 else if (sync_return_mode_ == 1)
94 {97 {
95 add_entry_id_2(&b);98 add_entry_id_2(&b, 1);
96 add_entry_id(&b);99 add_entry_id(&b, 2);
97 }100 }
98101
99 if (sync_return_mode_ == 1)102 if (sync_return_mode_ == 1)
100103
=== modified file 'unity-shared/IconLoader.cpp'
--- unity-shared/IconLoader.cpp 2015-01-15 14:33:03 +0000
+++ unity-shared/IconLoader.cpp 2015-02-19 19:24:14 +0000
@@ -799,7 +799,7 @@
799 bool CoalesceTasksCb();799 bool CoalesceTasksCb();
800800
801private:801private:
802 std::map<std::string, glib::Object<GdkPixbuf>> cache_;802 std::unordered_map<std::string, glib::Object<GdkPixbuf>> cache_;
803 /* FIXME: the reference counting of IconLoaderTasks with shared pointers803 /* FIXME: the reference counting of IconLoaderTasks with shared pointers
804 * is currently somewhat broken, and the queued_tasks_ member is what keeps804 * is currently somewhat broken, and the queued_tasks_ member is what keeps
805 * it from crashing randomly.805 * it from crashing randomly.
@@ -807,7 +807,7 @@
807 * tasks, but when they are being completed in a worker thread, the thread807 * tasks, but when they are being completed in a worker thread, the thread
808 * should own them as well (yet it doesn't), this could cause trouble808 * should own them as well (yet it doesn't), this could cause trouble
809 * in the future... You've been warned! */809 * in the future... You've been warned! */
810 std::map<std::string, IconLoaderTask::Ptr> queued_tasks_;810 std::unordered_map<std::string, IconLoaderTask::Ptr> queued_tasks_;
811 std::queue<IconLoaderTask::Ptr> tasks_;811 std::queue<IconLoaderTask::Ptr> tasks_;
812 std::unordered_map<Handle, IconLoaderTask::Ptr> task_map_;812 std::unordered_map<Handle, IconLoaderTask::Ptr> task_map_;
813 std::vector<IconLoaderTask*> finished_tasks_;813 std::vector<IconLoaderTask*> finished_tasks_;
814814
=== modified file 'unity-shared/MenuManager.cpp'
--- unity-shared/MenuManager.cpp 2015-02-04 11:13:04 +0000
+++ unity-shared/MenuManager.cpp 2015-02-19 19:24:14 +0000
@@ -26,6 +26,7 @@
26#include <unordered_map>26#include <unordered_map>
2727
28#include "MenuManager.h"28#include "MenuManager.h"
29#include "WindowManager.h"
2930
30namespace unity31namespace unity
31{32{
@@ -48,16 +49,20 @@
48 : parent_(parent)49 : parent_(parent)
49 , indicators_(indicators)50 , indicators_(indicators)
50 , key_grabber_(grabber)51 , key_grabber_(grabber)
52 , show_now_window_(0)
51 , settings_(g_settings_new(SETTINGS_NAME.c_str()))53 , settings_(g_settings_new(SETTINGS_NAME.c_str()))
52 {54 {
53 for (auto const& indicator : indicators_->GetIndicators())55 for (auto const& indicator : indicators_->GetIndicators())
54 AddIndicator(indicator);56 AddIndicator(indicator);
5557
58 GrabMnemonicsForActiveWindow();
59
56 parent_->show_menus.changed.connect(sigc::mem_fun(this, &Impl::ShowMenus));60 parent_->show_menus.changed.connect(sigc::mem_fun(this, &Impl::ShowMenus));
57 indicators_->on_object_added.connect(sigc::mem_fun(this, &Impl::AddIndicator));61 indicators_->on_object_added.connect(sigc::mem_fun(this, &Impl::AddIndicator));
58 indicators_->on_object_removed.connect(sigc::mem_fun(this, &Impl::RemoveIndicator));62 indicators_->on_object_removed.connect(sigc::mem_fun(this, &Impl::RemoveIndicator));
59 indicators_->on_entry_activate_request.connect(sigc::mem_fun(this, &Impl::ActivateRequest));63 indicators_->on_entry_activate_request.connect(sigc::mem_fun(this, &Impl::ActivateRequest));
60 indicators_->icon_paths_changed.connect(sigc::mem_fun(this, &Impl::IconPathsChanged));64 indicators_->icon_paths_changed.connect(sigc::mem_fun(this, &Impl::IconPathsChanged));
65 WindowManager::Default().window_focus_changed.connect(sigc::hide(sigc::mem_fun(this, &Impl::GrabMnemonicsForActiveWindow)));
6166
62 signals_.Add<void, GSettings*, const gchar*>(settings_, "changed::" + LIM_KEY, [this] (GSettings*, const gchar*) {67 signals_.Add<void, GSettings*, const gchar*>(settings_, "changed::" + LIM_KEY, [this] (GSettings*, const gchar*) {
63 parent_->integrated_menus = g_settings_get_boolean(settings_, LIM_KEY.c_str());68 parent_->integrated_menus = g_settings_get_boolean(settings_, LIM_KEY.c_str());
The diff has been truncated for viewing.