Merge lp:~unity-team/unity/fix-lp1309778-trusty into lp:unity/7.2

Proposed by Christopher Townsend on 2015-07-15
Status: Needs review
Proposed branch: lp:~unity-team/unity/fix-lp1309778-trusty
Merge into: lp:unity/7.2
Prerequisite: lp:~unity-team/unity/fix-lp1351591-trusty
Diff against target: 5329 lines (+1369/-784)
71 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 (+6/-0)
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)
launcher/XdndStartStopNotifierImp.h (+1/-1)
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 (+63/-8)
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:~unity-team/unity/fix-lp1309778-trusty
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve on 2015-07-15
Unity Team 2015-07-15 Pending
Review via email: mp+264837@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.

To post a comment you must log in.

Unmerged revisions

3833. By Christopher Townsend on 2015-07-15

Merge lp:unity/7.2.

3832. By Marco Trevisan (Treviño) on 2015-05-28

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.

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 2015-03-12 00:57:05 +0000
+++ UnityCore/AppmenuIndicator.cpp 2015-07-15 14:19:40 +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 2015-03-12 00:57:05 +0000
+++ UnityCore/AppmenuIndicator.h 2015-07-15 14:19:40 +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-07-15 14:19:40 +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-12-09 15:41:53 +0000
+++ UnityCore/DBusIndicators.cpp 2015-07-15 14:19:40 +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-07-15 14:19:40 +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-07-15 14:19:40 +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-07-15 14:19:40 +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-07-15 14:19:40 +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-07-15 14:19:40 +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-07-15 14:19:40 +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-07-15 14:19:40 +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-07-15 14:19:40 +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 2015-03-12 00:57:05 +0000
+++ com.canonical.Unity.gschema.xml 2015-07-15 14:19:40 +0000
@@ -158,5 +158,11 @@
158 a window by double-clicking on its menus if the second click happens before the158 a window by double-clicking on its menus if the second click happens before the
159 specified value of ms is elapsed</description>159 specified value of ms is elapsed</description>
160 </key>160 </key>
161 <key type="b" name="unfocused-windows-popup">
162 <default>true</default>
163 <summary>Whether to pop-up a menu when clicking over unfocused windows entries</summary>
164 <description>By disabling this setting you can make unity to only focus a window
165 when clicking over unfocused menu entries</description>
166 </key>
161 </schema>167 </schema>
162</schemalist>168</schemalist>
163169
=== modified file 'dash/DashView.h'
--- dash/DashView.h 2014-07-24 13:49:53 +0000
+++ dash/DashView.h 2015-07-15 14:19:40 +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-08-06 14:09:30 +0000
+++ dash/ScopeView.h 2015-07-15 14:19:40 +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 2015-03-11 18:11:24 +0000
+++ debian/control 2015-07-15 14:19:40 +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 2015-03-12 00:57:05 +0000
+++ decorations/DecoratedWindow.cpp 2015-07-15 14:19:40 +0000
@@ -52,17 +52,13 @@
52 , deco_elements_(cu::DecorationElement::NONE)52 , deco_elements_(cu::DecorationElement::NONE)
53 , last_mwm_decor_(win_->mwmDecor())53 , last_mwm_decor_(win_->mwmDecor())
54 , last_actions_(win_->actions())54 , last_actions_(win_->actions())
55 , panel_id_(MENUS_PANEL_NAME + std::to_string(win_->id()))
55 , cv_(Settings::Instance().em())56 , cv_(Settings::Instance().em())
56{57{
57 active.changed.connect([this] (bool active) {58 active.changed.connect([this] (bool active) {
58 bg_textures_.clear();59 bg_textures_.clear();
59 if (top_layout_)60 if (top_layout_)
60 {
61 top_layout_->focused = active;61 top_layout_->focused = active;
62
63 if (!active)
64 UnsetAppMenu();
65 }
66 RedrawDecorations();62 RedrawDecorations();
67 });63 });
6864
@@ -703,7 +699,7 @@
703699
704void Window::Impl::SetupAppMenu()700void Window::Impl::SetupAppMenu()
705{701{
706 if (!active() || !top_layout_)702 if (!top_layout_)
707 return;703 return;
708704
709 auto const& menu_manager = manager_->impl_->menu_manager_;705 auto const& menu_manager = manager_->impl_->menu_manager_;
@@ -718,8 +714,11 @@
718714
719 auto menus = std::make_shared<MenuLayout>(menu_manager, win_);715 auto menus = std::make_shared<MenuLayout>(menu_manager, win_);
720 menus->Setup();716 menus->Setup();
717
718 if (menus->Items().empty())
719 return;
720
721 menus_ = menus;721 menus_ = menus;
722
723 auto const& grab_edge = grab_edge_.lock();722 auto const& grab_edge = grab_edge_.lock();
724 sliding_layout->SetInputItem(menus);723 sliding_layout->SetInputItem(menus);
725 sliding_layout->fadein = menu_manager->fadein();724 sliding_layout->fadein = menu_manager->fadein();
@@ -761,13 +760,18 @@
761 sliding_layout->mouse_owner = grab_edge_->mouse_owner();760 sliding_layout->mouse_owner = grab_edge_->mouse_owner();
762}761}
763762
763inline std::string const& Window::Impl::GetMenusPanelID() const
764{
765 return panel_id_;
766}
767
764void Window::Impl::UnsetAppMenu()768void Window::Impl::UnsetAppMenu()
765{769{
766 if (!menus_)770 if (!menus_)
767 return;771 return;
768772
769 auto const& indicators = manager_->impl_->menu_manager_->Indicators();773 auto const& indicators = manager_->impl_->menu_manager_->Indicators();
770 indicators->SyncGeometries(MENUS_PANEL_NAME, indicator::EntryLocationMap());774 indicators->SyncGeometries(GetMenusPanelID(), indicator::EntryLocationMap());
771 sliding_layout_->SetInputItem(nullptr);775 sliding_layout_->SetInputItem(nullptr);
772 grab_mouse_changed_->disconnect();776 grab_mouse_changed_->disconnect();
773}777}
@@ -780,7 +784,7 @@
780 auto const& indicators = manager_->impl_->menu_manager_->Indicators();784 auto const& indicators = manager_->impl_->menu_manager_->Indicators();
781 indicator::EntryLocationMap map;785 indicator::EntryLocationMap map;
782 menus_->ChildrenGeometries(map);786 menus_->ChildrenGeometries(map);
783 indicators->SyncGeometries(MENUS_PANEL_NAME, map);787 indicators->SyncGeometries(GetMenusPanelID(), map);
784}788}
785789
786bool Window::Impl::ActivateMenu(std::string const& entry_id)790bool Window::Impl::ActivateMenu(std::string const& entry_id)
787791
=== modified file 'decorations/DecorationsManager.cpp'
--- decorations/DecorationsManager.cpp 2015-03-12 00:57:05 +0000
+++ decorations/DecorationsManager.cpp 2015-07-15 14:19:40 +0000
@@ -144,27 +144,24 @@
144 return;144 return;
145 }145 }
146146
147 appmenu->active_window = screen->activeWindow();147 for (auto const& win : windows_)
148148 win.second->impl_->SetupAppMenu();
149 auto setup_active_window = [this] {
150 if (Window::Ptr const& active_win = active_deco_win_.lock())
151 active_win->impl_->SetupAppMenu();
152 };
153149
154 menu_connections_.Remove(appmenu_connection_);150 menu_connections_.Remove(appmenu_connection_);
155 appmenu_connection_ = menu_connections_.Add(appmenu->updated.connect(setup_active_window));151 appmenu_connection_ = menu_connections_.Add(appmenu->updated_win.connect([this] (uint32_t xid) {
156 setup_active_window();152 if (Window::Ptr const& win = GetWindowByXid(xid))
153 win->impl_->SetupAppMenu();
154 }));
157}155}
158156
159void Manager::Impl::UnsetAppMenu()157void Manager::Impl::UnsetAppMenu()
160{158{
161 menu_connections_.Remove(appmenu_connection_);159 menu_connections_.Remove(appmenu_connection_);
162 auto const& active_win = active_deco_win_.lock();
163160
164 if (active_win)161 for (auto const& win : windows_)
165 {162 {
166 active_win->impl_->UnsetAppMenu();163 win.second->impl_->UnsetAppMenu();
167 active_win->impl_->Damage();164 win.second->impl_->Damage();
168 }165 }
169}166}
170167
@@ -268,9 +265,6 @@
268265
269 if (new_active)266 if (new_active)
270 new_active->impl_->active = true;267 new_active->impl_->active = true;
271
272 if (indicator::AppmenuIndicator::Ptr const& appmenu = menu_manager_->AppMenu())
273 appmenu->active_window = active_xid;
274 }268 }
275 else if (event->xproperty.atom == Atoms::mwmHints ||269 else if (event->xproperty.atom == Atoms::mwmHints ||
276 event->xproperty.atom == Atoms::wmAllowedActions)270 event->xproperty.atom == Atoms::wmAllowedActions)
@@ -311,6 +305,9 @@
311305
312bool Manager::Impl::HandleFrameEvent(XEvent* event)306bool Manager::Impl::HandleFrameEvent(XEvent* event)
313{307{
308 if (WindowManager::Default().IsScaleActive())
309 return false;
310
314 auto const& win = GetWindowByFrame(event->xany.window);311 auto const& win = GetWindowByFrame(event->xany.window);
315312
316 // ButtonRelease events might happen also outside the frame window, in this313 // ButtonRelease events might happen also outside the frame window, in this
317314
=== modified file 'decorations/DecorationsMenuDropdown.cpp'
--- decorations/DecorationsMenuDropdown.cpp 2014-02-24 23:53:50 +0000
+++ decorations/DecorationsMenuDropdown.cpp 2015-07-15 14:19:40 +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-07-15 14:19:40 +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-07-15 14:19:40 +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-07-15 14:19:40 +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-12-16 19:35:06 +0000
+++ decorations/DecorationsPriv.h 2015-07-15 14:19:40 +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 2015-03-12 00:57:05 +0000
+++ decorations/DecorationsSlidingLayout.cpp 2015-07-15 14:19:40 +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-12-08 22:38:02 +0000
+++ decorations/DecorationsWidgets.cpp 2015-07-15 14:19:40 +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-07-15 14:19:40 +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 'launcher/XdndStartStopNotifierImp.h'
--- launcher/XdndStartStopNotifierImp.h 2012-11-15 16:05:35 +0000
+++ launcher/XdndStartStopNotifierImp.h 2015-07-15 14:19:40 +0000
@@ -27,7 +27,7 @@
2727
28namespace unity {28namespace unity {
2929
30class XdndStartStopNotifierImp : public XdndStartStopNotifier {30class XdndStartStopNotifierImp : public XdndStartStopNotifier, public sigc::trackable {
31public:31public:
32 XdndStartStopNotifierImp();32 XdndStartStopNotifierImp();
3333
3434
=== modified file 'lockscreen/LockScreenPanel.cpp'
--- lockscreen/LockScreenPanel.cpp 2014-12-15 19:12:07 +0000
+++ lockscreen/LockScreenPanel.cpp 2015-07-15 14:19:40 +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-07-15 14:19:40 +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-07-15 14:19:40 +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-12-08 19:50:13 +0000
+++ panel/PanelIndicatorEntryView.cpp 2015-07-15 14:19:40 +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-07-15 14:19:40 +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-07-15 14:19:40 +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-07-15 14:19:40 +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 2015-03-12 00:57:05 +0000
+++ panel/PanelMenuView.cpp 2015-07-15 14:19:40 +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 2015-03-12 00:57:05 +0000
+++ panel/PanelMenuView.h 2015-07-15 14:19:40 +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-03-06 16:26:34 +0000
+++ panel/PanelView.cpp 2015-07-15 14:19:40 +0000
@@ -519,7 +519,7 @@
519519
520 if (opacity_maximized_toggle_)520 if (opacity_maximized_toggle_)
521 {521 {
522 Window maximized_win = menu_view_->GetMaximizedWindow();522 Window maximized_win = menu_view_->maximized_window();
523523
524 if (wm.IsExpoActive() || (maximized_win != 0 && !wm.IsWindowObscured(maximized_win)))524 if (wm.IsExpoActive() || (maximized_win != 0 && !wm.IsWindowObscured(maximized_win)))
525 opacity = 1.0f;525 opacity = 1.0f;
@@ -676,7 +676,7 @@
676 if (!IsActive())676 if (!IsActive())
677 return false;677 return false;
678678
679 if ((menu_view_->HasMenus() && menu_view_->ActivateIfSensitive()) ||679 if ((menu_view_->HasKeyActivableMenus() && menu_view_->ActivateIfSensitive()) ||
680 indicators_->ActivateIfSensitive())680 indicators_->ActivateIfSensitive())
681 {681 {
682 // Since this only happens on keyboard events, we need to prevent that the682 // Since this only happens on keyboard events, we need to prevent that the
@@ -693,7 +693,7 @@
693 if (!IsActive())693 if (!IsActive())
694 return false;694 return false;
695695
696 if ((menu_view_->HasMenus() && menu_view_->ActivateEntry(entry_id, 0)) ||696 if ((menu_view_->HasKeyActivableMenus() && menu_view_->ActivateEntry(entry_id, 0)) ||
697 indicators_->ActivateEntry(entry_id, 0))697 indicators_->ActivateEntry(entry_id, 0))
698 {698 {
699 // Since this only happens on keyboard events, we need to prevent that the699 // Since this only happens on keyboard events, we need to prevent that the
700700
=== modified file 'plugins/unityshell/src/unityshell.cpp'
--- plugins/unityshell/src/unityshell.cpp 2015-06-03 12:46:12 +0000
+++ plugins/unityshell/src/unityshell.cpp 2015-07-15 14:19:40 +0000
@@ -156,6 +156,7 @@
156 , cScreen(CompositeScreen::get(screen))156 , cScreen(CompositeScreen::get(screen))
157 , gScreen(GLScreen::get(screen))157 , gScreen(GLScreen::get(screen))
158 , sScreen(ScaleScreen::get(screen))158 , sScreen(ScaleScreen::get(screen))
159 , WM(PluginAdapter::Initialize(screen))
159 , menus_(std::make_shared<menu::Manager>(std::make_shared<indicator::DBusIndicators>(), std::make_shared<key::GnomeGrabber>()))160 , menus_(std::make_shared<menu::Manager>(std::make_shared<indicator::DBusIndicators>(), std::make_shared<key::GnomeGrabber>()))
160 , deco_manager_(std::make_shared<decoration::Manager>(menus_))161 , deco_manager_(std::make_shared<decoration::Manager>(menus_))
161 , debugger_(this)162 , debugger_(this)
@@ -278,9 +279,6 @@
278 ScaleScreenInterface::setHandler(sScreen);279 ScaleScreenInterface::setHandler(sScreen);
279 screen->updateSupportedWmHints();280 screen->updateSupportedWmHints();
280281
281 PluginAdapter::Initialize(screen);
282 AddChild(&WindowManager::Default());
283
284 StartupNotifyService::Default()->SetSnDisplay(screen->snDisplay(), screen->screenNum());282 StartupNotifyService::Default()->SetSnDisplay(screen->snDisplay(), screen->screenNum());
285283
286 nux::NuxInitialize(0);284 nux::NuxInitialize(0);
@@ -441,13 +439,13 @@
441 sigc::mem_fun(this, &UnityScreen::OnMinimizeDurationChanged)439 sigc::mem_fun(this, &UnityScreen::OnMinimizeDurationChanged)
442 );440 );
443441
444 WindowManager& wm = WindowManager::Default();442 WM.initiate_spread.connect(sigc::mem_fun(this, &UnityScreen::OnInitiateSpread));
445 wm.initiate_spread.connect(sigc::mem_fun(this, &UnityScreen::OnInitiateSpread));443 WM.terminate_spread.connect(sigc::mem_fun(this, &UnityScreen::OnTerminateSpread));
446 wm.terminate_spread.connect(sigc::mem_fun(this, &UnityScreen::OnTerminateSpread));444 WM.initiate_expo.connect(sigc::mem_fun(this, &UnityScreen::DamagePanelShadow));
447 wm.initiate_expo.connect(sigc::mem_fun(this, &UnityScreen::DamagePanelShadow));445 WM.terminate_expo.connect(sigc::mem_fun(this, &UnityScreen::DamagePanelShadow));
448 wm.terminate_expo.connect(sigc::mem_fun(this, &UnityScreen::DamagePanelShadow));
449446
450 AddChild(&screen_introspection_);447 Introspectable::AddChild(&WM);
448 Introspectable::AddChild(&screen_introspection_);
451449
452 /* Create blur backup texture */450 /* Create blur backup texture */
453 auto gpu_device = nux::GetGraphicsDisplay()->GetGpuDevice();451 auto gpu_device = nux::GetGraphicsDisplay()->GetGpuDevice();
@@ -686,7 +684,7 @@
686 if (sources_.GetSource(local::RELAYOUT_TIMEOUT))684 if (sources_.GetSource(local::RELAYOUT_TIMEOUT))
687 return;685 return;
688686
689 if (WindowManager::Default().IsExpoActive())687 if (WM.IsExpoActive())
690 return;688 return;
691689
692 CompOutput* output = _last_output;690 CompOutput* output = _last_output;
@@ -947,7 +945,7 @@
947 nux::TexCoordXForm texxform;945 nux::TexCoordXForm texxform;
948 texxform.SetWrap(nux::TEXWRAP_REPEAT, nux::TEXWRAP_CLAMP);946 texxform.SetWrap(nux::TEXWRAP_REPEAT, nux::TEXWRAP_CLAMP);
949947
950 int monitor = WindowManager::Default().MonitorGeometryIn(NuxGeometryFromCompRect(output_dev));948 int monitor = WM.MonitorGeometryIn(NuxGeometryFromCompRect(output_dev));
951 auto const& texture = panel_style_.GetBackground(monitor)->GetDeviceTexture();949 auto const& texture = panel_style_.GetBackground(monitor)->GetDeviceTexture();
952 graphics_engine->QRP_GLSL_1Tex(0, 0, output_dev.width(), texture->GetHeight(), texture, texxform, nux::color::White);950 graphics_engine->QRP_GLSL_1Tex(0, 0, output_dev.width(), texture->GetHeight(), texture, texxform, nux::color::White);
953}951}
@@ -960,7 +958,7 @@
960 hud_controller_->IsVisible() ||958 hud_controller_->IsVisible() ||
961 session_controller_->Visible() ||959 session_controller_->Visible() ||
962 ((switcher_controller_->Visible() ||960 ((switcher_controller_->Visible() ||
963 WindowManager::Default().IsExpoActive())961 WM.IsExpoActive())
964 && !fullscreen_windows_.empty () && (!(screen->grabbed () && !screen->otherGrabExist (NULL))));962 && !fullscreen_windows_.empty () && (!(screen->grabbed () && !screen->otherGrabExist (NULL))));
965}963}
966964
@@ -2218,7 +2216,7 @@
2218 CompAction::State state,2216 CompAction::State state,
2219 CompOption::Vector& options)2217 CompOption::Vector& options)
2220{2218{
2221 WindowManager::Default().ShowDesktop();2219 WM.ShowDesktop();
2222 return true;2220 return true;
2223}2221}
22242222
@@ -2322,7 +2320,7 @@
2322 CompAction::State state,2320 CompAction::State state,
2323 CompOption::Vector& options)2321 CompOption::Vector& options)
2324{2322{
2325 if (WindowManager::Default().IsWallActive())2323 if (WM.IsWallActive())
2326 return false;2324 return false;
2327 else if (switcher_controller_->Visible())2325 else if (switcher_controller_->Visible())
2328 switcher_controller_->Next();2326 switcher_controller_->Next();
@@ -2520,11 +2518,9 @@
2520 }2518 }
2521 else2519 else
2522 {2520 {
2523 auto& wm = WindowManager::Default();2521 if (WM.IsScreenGrabbed())
2524
2525 if (wm.IsScreenGrabbed())
2526 {2522 {
2527 hud_ungrab_slot_ = wm.screen_ungrabbed.connect([this] { ShowHud(); });2523 hud_ungrab_slot_ = WM.screen_ungrabbed.connect([this] { ShowHud(); });
25282524
2529 // Let's wait ungrab event for maximum a couple of seconds...2525 // Let's wait ungrab event for maximum a couple of seconds...
2530 sources_.AddTimeoutSeconds(2, [this] {2526 sources_.AddTimeoutSeconds(2, [this] {
@@ -2663,7 +2659,7 @@
2663 KeySym keysym = XkbKeycodeToKeysym(screen->dpy(), keybind.keycode(), 0, 0);2659 KeySym keysym = XkbKeycodeToKeysym(screen->dpy(), keybind.keycode(), 0, 0);
2664 unsigned modifiers = CompizModifiersToNux(keybind.modifiers());2660 unsigned modifiers = CompizModifiersToNux(keybind.modifiers());
26652661
2666 WindowManager::Default().close_window_key = std::make_pair(modifiers, keysym);2662 WM.close_window_key = std::make_pair(modifiers, keysym);
2667}2663}
26682664
2669void UnityScreen::UpdateActivateIndicatorsKey()2665void UnityScreen::UpdateActivateIndicatorsKey()
@@ -2672,7 +2668,7 @@
2672 KeySym keysym = XkbKeycodeToKeysym(screen->dpy(), keybind.keycode(), 0, 0);2668 KeySym keysym = XkbKeycodeToKeysym(screen->dpy(), keybind.keycode(), 0, 0);
2673 unsigned modifiers = CompizModifiersToNux(keybind.modifiers());2669 unsigned modifiers = CompizModifiersToNux(keybind.modifiers());
26742670
2675 WindowManager::Default().activate_indicators_key = std::make_pair(modifiers, keysym);2671 WM.activate_indicators_key = std::make_pair(modifiers, keysym);
2676}2672}
26772673
2678bool UnityScreen::initPluginActions()2674bool UnityScreen::initPluginActions()
@@ -2925,7 +2921,7 @@
2925 }2921 }
2926 }2922 }
29272923
2928 if (WindowManager::Default().IsScaleActive() &&2924 if (uScreen->WM.IsScaleActive() &&
2929 uScreen->sScreen->getSelectedWindow() == window->id())2925 uScreen->sScreen->getSelectedWindow() == window->id())
2930 {2926 {
2931 nux::Geometry const& scaled_geo = GetScaledGeometry();2927 nux::Geometry const& scaled_geo = GetScaledGeometry();
@@ -3030,9 +3026,8 @@
3030 !(window_state & CompWindowStateFullscreenMask) &&3026 !(window_state & CompWindowStateFullscreenMask) &&
3031 !(window_type & CompWindowTypeFullscreenMask))3027 !(window_type & CompWindowTypeFullscreenMask))
3032 {3028 {
3033 WindowManager& wm = WindowManager::Default();
3034 auto const& output = uScreen->screen->currentOutputDev();3029 auto const& output = uScreen->screen->currentOutputDev();
3035 int monitor = wm.MonitorGeometryIn(NuxGeometryFromCompRect(output));3030 int monitor = uScreen->WM.MonitorGeometryIn(NuxGeometryFromCompRect(output));
30363031
3037 if (window->y() - window->border().top < output.y() + uScreen->panel_style_.PanelHeight(monitor))3032 if (window->y() - window->border().top < output.y() + uScreen->panel_style_.PanelHeight(monitor))
3038 {3033 {
@@ -3670,8 +3665,7 @@
3670 {3665 {
3671 if (strcmp(name, "hsize") == 0 || strcmp(name, "vsize") == 0)3666 if (strcmp(name, "hsize") == 0 || strcmp(name, "vsize") == 0)
3672 {3667 {
3673 WindowManager& wm = WindowManager::Default();3668 WM.viewport_layout_changed.emit(screen->vpSize().width(), screen->vpSize().height());
3674 wm.viewport_layout_changed.emit(screen->vpSize().width(), screen->vpSize().height());
3675 }3669 }
3676 else if (strcmp(name, "close_window_key") == 0)3670 else if (strcmp(name, "close_window_key") == 0)
3677 {3671 {
@@ -3787,13 +3781,11 @@
3787 if (QuicklistManager::Default()->Current())3781 if (QuicklistManager::Default()->Current())
3788 QuicklistManager::Default()->Current()->Hide();3782 QuicklistManager::Default()->Current()->Hide();
37893783
3790 auto& wm = WindowManager::Default();3784 if (WM.IsScaleActive())
37913785 WM.TerminateScale();
3792 if (wm.IsScaleActive())3786
3793 wm.TerminateScale();3787 if (WM.IsExpoActive())
37943788 WM.TerminateExpo();
3795 if (wm.IsExpoActive())
3796 wm.TerminateExpo();
37973789
3798 RaiseOSK();3790 RaiseOSK();
3799}3791}
@@ -3892,24 +3884,24 @@
3892 auto edge_barriers = std::make_shared<ui::EdgeBarrierController>();3884 auto edge_barriers = std::make_shared<ui::EdgeBarrierController>();
38933885
3894 launcher_controller_ = std::make_shared<launcher::Controller>(xdnd_manager, edge_barriers);3886 launcher_controller_ = std::make_shared<launcher::Controller>(xdnd_manager, edge_barriers);
3895 AddChild(launcher_controller_.get());3887 Introspectable::AddChild(launcher_controller_.get());
38963888
3897 switcher_controller_ = std::make_shared<switcher::Controller>();3889 switcher_controller_ = std::make_shared<switcher::Controller>();
3898 switcher_controller_->detail.changed.connect(sigc::mem_fun(this, &UnityScreen::OnSwitcherDetailChanged));3890 switcher_controller_->detail.changed.connect(sigc::mem_fun(this, &UnityScreen::OnSwitcherDetailChanged));
3899 AddChild(switcher_controller_.get());3891 Introspectable::AddChild(switcher_controller_.get());
39003892
3901 LOG_INFO(logger) << "initLauncher-Launcher " << timer.ElapsedSeconds() << "s";3893 LOG_INFO(logger) << "initLauncher-Launcher " << timer.ElapsedSeconds() << "s";
39023894
3903 /* Setup panel */3895 /* Setup panel */
3904 timer.Reset();3896 timer.Reset();
3905 panel_controller_ = std::make_shared<panel::Controller>(menus_, edge_barriers);3897 panel_controller_ = std::make_shared<panel::Controller>(menus_, edge_barriers);
3906 AddChild(panel_controller_.get());3898 Introspectable::AddChild(panel_controller_.get());
3907 LOG_INFO(logger) << "initLauncher-Panel " << timer.ElapsedSeconds() << "s";3899 LOG_INFO(logger) << "initLauncher-Panel " << timer.ElapsedSeconds() << "s";
39083900
3909 /* Setup Places */3901 /* Setup Places */
3910 dash_controller_ = std::make_shared<dash::Controller>();3902 dash_controller_ = std::make_shared<dash::Controller>();
3911 dash_controller_->on_realize.connect(sigc::mem_fun(this, &UnityScreen::OnDashRealized));3903 dash_controller_->on_realize.connect(sigc::mem_fun(this, &UnityScreen::OnDashRealized));
3912 AddChild(dash_controller_.get());3904 Introspectable::AddChild(dash_controller_.get());
39133905
3914 /* Setup Hud */3906 /* Setup Hud */
3915 hud_controller_ = std::make_shared<hud::Controller>();3907 hud_controller_ = std::make_shared<hud::Controller>();
@@ -3918,14 +3910,14 @@
3918 hud_controller_->multiple_launchers = (optionGetNumLaunchers() == 0);3910 hud_controller_->multiple_launchers = (optionGetNumLaunchers() == 0);
3919 hud_controller_->icon_size = launcher_controller_->options()->icon_size();3911 hud_controller_->icon_size = launcher_controller_->options()->icon_size();
3920 hud_controller_->tile_size = launcher_controller_->options()->tile_size();3912 hud_controller_->tile_size = launcher_controller_->options()->tile_size();
3921 AddChild(hud_controller_.get());3913 Introspectable::AddChild(hud_controller_.get());
3922 LOG_INFO(logger) << "initLauncher-hud " << timer.ElapsedSeconds() << "s";3914 LOG_INFO(logger) << "initLauncher-hud " << timer.ElapsedSeconds() << "s";
39233915
3924 // Setup Shortcut Hint3916 // Setup Shortcut Hint
3925 auto base_window_raiser = std::make_shared<shortcut::BaseWindowRaiserImp>();3917 auto base_window_raiser = std::make_shared<shortcut::BaseWindowRaiserImp>();
3926 auto shortcuts_modeller = std::make_shared<shortcut::CompizModeller>();3918 auto shortcuts_modeller = std::make_shared<shortcut::CompizModeller>();
3927 shortcut_controller_ = std::make_shared<shortcut::Controller>(base_window_raiser, shortcuts_modeller);3919 shortcut_controller_ = std::make_shared<shortcut::Controller>(base_window_raiser, shortcuts_modeller);
3928 AddChild(shortcut_controller_.get());3920 Introspectable::AddChild(shortcut_controller_.get());
3929 ShowFirstRunHints();3921 ShowFirstRunHints();
39303922
3931 // Setup Session Controller3923 // Setup Session Controller
@@ -3936,7 +3928,7 @@
3936 manager->unlocked.connect(sigc::mem_fun(this, &UnityScreen::OnScreenUnlocked));3928 manager->unlocked.connect(sigc::mem_fun(this, &UnityScreen::OnScreenUnlocked));
3937 session_dbus_manager_ = std::make_shared<session::DBusManager>(manager);3929 session_dbus_manager_ = std::make_shared<session::DBusManager>(manager);
3938 session_controller_ = std::make_shared<session::Controller>(manager);3930 session_controller_ = std::make_shared<session::Controller>(manager);
3939 AddChild(session_controller_.get());3931 Introspectable::AddChild(session_controller_.get());
39403932
3941 // Setup Lockscreen Controller3933 // Setup Lockscreen Controller
3942 screensaver_dbus_manager_ = std::make_shared<lockscreen::DBusManager>(manager);3934 screensaver_dbus_manager_ = std::make_shared<lockscreen::DBusManager>(manager);
@@ -4122,7 +4114,7 @@
4122 window->minimizedSetEnabled (this, false);4114 window->minimizedSetEnabled (this, false);
4123 }4115 }
41244116
4125 /* Keep this after the optionGetShowMinimizedWindows branch */4117 /* Keep this after the optionGetShowMIntrospectable.hinimizedWindows branch */
41264118
4127 if (window->state() & CompWindowStateFullscreenMask)4119 if (window->state() & CompWindowStateFullscreenMask)
4128 uScreen->fullscreen_windows_.push_back(window);4120 uScreen->fullscreen_windows_.push_back(window);
@@ -4139,8 +4131,8 @@
4139{4131{
4140 Window xid = window->id();4132 Window xid = window->id();
4141 auto const& swins = uScreen->sScreen->getWindows();4133 auto const& swins = uScreen->sScreen->getWindows();
4134 WindowManager& wm = uScreen->WM;
4142 bool scaled = std::find(swins.begin(), swins.end(), ScaleWindow::get(window)) != swins.end();4135 bool scaled = std::find(swins.begin(), swins.end(), ScaleWindow::get(window)) != swins.end();
4143 WindowManager& wm = WindowManager::Default();
41444136
4145 introspection4137 introspection
4146 .add(scaled ? GetScaledGeometry() : wm.GetWindowGeometry(xid))4138 .add(scaled ? GetScaledGeometry() : wm.GetWindowGeometry(xid))
@@ -4376,9 +4368,7 @@
43764368
4377nux::Geometry UnityWindow::GetScaledGeometry()4369nux::Geometry UnityWindow::GetScaledGeometry()
4378{4370{
4379 WindowManager& wm = WindowManager::Default();4371 if (!uScreen->WM.IsScaleActive())
4380
4381 if (!wm.IsScaleActive())
4382 return nux::Geometry();4372 return nux::Geometry();
43834373
4384 ScaleWindow* scale_win = ScaleWindow::get(window);4374 ScaleWindow* scale_win = ScaleWindow::get(window);
43854375
=== modified file 'plugins/unityshell/src/unityshell.h'
--- plugins/unityshell/src/unityshell.h 2015-06-03 12:46:12 +0000
+++ plugins/unityshell/src/unityshell.h 2015-07-15 14:19:40 +0000
@@ -333,6 +333,7 @@
333333
334 /* The window thread should be the last thing removed, as c++ does it in reverse order */334 /* The window thread should be the last thing removed, as c++ does it in reverse order */
335 std::unique_ptr<nux::WindowThread> wt;335 std::unique_ptr<nux::WindowThread> wt;
336 WindowManager& WM;
336337
337 menu::Manager::Ptr menus_;338 menu::Manager::Ptr menus_;
338 std::shared_ptr<decoration::Manager> deco_manager_;339 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-12-09 15:41:53 +0000
+++ services/panel-main.c 2015-07-15 14:19:40 +0000
@@ -26,20 +26,21 @@
26#include "config.h"26#include "config.h"
27#include "panel-a11y.h"27#include "panel-a11y.h"
28#include "panel-service.h"28#include "panel-service.h"
29#include "panel-service-private.h"
2930
30static GDBusNodeInfo *introspection_data = NULL;31static GDBusNodeInfo *introspection_data = NULL;
3132
32static const gchar introspection_xml[] =33static const gchar introspection_xml[] =
33 "<node>"34 "<node>"
34 " <interface name='com.canonical.Unity.Panel.Service'>"35 " <interface name='"UPS_IFACE"'>"
35 ""36 ""
36 " <method name='Sync'>"37 " <method name='Sync'>"
37 " <arg type='a(ssssbbusbbi)' name='state' direction='out'/>"38 " <arg type='"ENTRY_ARRAY_SIGNATURE"' name='state' direction='out'/>"
38 " </method>"39 " </method>"
39 ""40 ""
40 " <method name='SyncOne'>"41 " <method name='SyncOne'>"
41 " <arg type='s' name='indicator_id' direction='in'/>"42 " <arg type='s' name='indicator_id' direction='in'/>"
42 " <arg type='a(ssssbbusbbi)' name='state' direction='out'/>"43 " <arg type='"ENTRY_ARRAY_SIGNATURE"' name='state' direction='out'/>"
43 " </method>"44 " </method>"
44 ""45 ""
45 " <method name='SyncGeometries'>"46 " <method name='SyncGeometries'>"
@@ -109,10 +110,6 @@
109 " </interface>"110 " </interface>"
110 "</node>";111 "</node>";
111112
112#define S_NAME_DESKTOP "com.canonical.Unity.Panel.Service.Desktop"
113#define S_NAME_LOCKSCREEN "com.canonical.Unity.Panel.Service.LockScreen"
114#define S_PATH "/com/canonical/Unity/Panel/Service"
115#define S_IFACE "com.canonical.Unity.Panel.Service"
116113
117/* Forwards */114/* Forwards */
118static void115static void
@@ -270,8 +267,8 @@
270 GError *error = NULL;267 GError *error = NULL;
271 g_dbus_connection_emit_signal (connection,268 g_dbus_connection_emit_signal (connection,
272 NULL,269 NULL,
273 S_PATH,270 UPS_PATH,
274 S_IFACE,271 UPS_IFACE,
275 "ReSync",272 "ReSync",
276 g_variant_new ("(s)", indicator_id),273 g_variant_new ("(s)", indicator_id),
277 &error);274 &error);
@@ -292,10 +289,13 @@
292 GError *error = NULL;289 GError *error = NULL;
293 g_dbus_connection_emit_signal (connection,290 g_dbus_connection_emit_signal (connection,
294 NULL,291 NULL,
295 S_PATH,292 UPS_PATH,
296 S_IFACE,293 UPS_IFACE,
297 "EntryActivated",294 "EntryActivated",
298 g_variant_new ("(ss(iiuu))", panel_id, entry_id, x, y, w, h),295 g_variant_new ("(ss(iiuu))",
296 panel_id ? panel_id : "",
297 entry_id ? entry_id : "",
298 x, y, w, h),
299 &error);299 &error);
300300
301 if (error)301 if (error)
@@ -315,8 +315,8 @@
315315
316 g_dbus_connection_emit_signal (connection,316 g_dbus_connection_emit_signal (connection,
317 NULL,317 NULL,
318 S_PATH,318 UPS_PATH,
319 S_IFACE,319 UPS_IFACE,
320 "EntryActivateRequest",320 "EntryActivateRequest",
321 g_variant_new ("(s)", entry_id),321 g_variant_new ("(s)", entry_id),
322 &error);322 &error);
@@ -337,8 +337,8 @@
337 GError *error = NULL;337 GError *error = NULL;
338 g_dbus_connection_emit_signal (connection,338 g_dbus_connection_emit_signal (connection,
339 NULL,339 NULL,
340 S_PATH,340 UPS_PATH,
341 S_IFACE,341 UPS_IFACE,
342 "EntryShowNowChanged",342 "EntryShowNowChanged",
343 g_variant_new ("(sb)", entry_id, show_now_state),343 g_variant_new ("(sb)", entry_id, show_now_state),
344 &error);344 &error);
@@ -356,8 +356,8 @@
356 GError *error = NULL;356 GError *error = NULL;
357 g_dbus_connection_emit_signal (connection,357 g_dbus_connection_emit_signal (connection,
358 NULL,358 NULL,
359 S_PATH,359 UPS_PATH,
360 S_IFACE,360 UPS_IFACE,
361 "IconPathsChanged",361 "IconPathsChanged",
362 NULL,362 NULL,
363 &error);363 &error);
@@ -378,7 +378,7 @@
378 guint reg_id;378 guint reg_id;
379379
380 reg_id = g_dbus_connection_register_object (connection,380 reg_id = g_dbus_connection_register_object (connection,
381 S_PATH,381 UPS_PATH,
382 introspection_data->interfaces[0],382 introspection_data->interfaces[0],
383 &interface_vtable,383 &interface_vtable,
384 service,384 service,
@@ -489,7 +489,7 @@
489 service = panel_service_get_default ();489 service = panel_service_get_default ();
490490
491 owner_id = g_bus_own_name (G_BUS_TYPE_SESSION,491 owner_id = g_bus_own_name (G_BUS_TYPE_SESSION,
492 !lockscreen_mode ? S_NAME_DESKTOP : S_NAME_LOCKSCREEN,492 !lockscreen_mode ? UPS_NAME_DESKTOP : UPS_NAME_LOCKSCREEN,
493 G_BUS_NAME_OWNER_FLAGS_NONE,493 G_BUS_NAME_OWNER_FLAGS_NONE,
494 on_bus_acquired,494 on_bus_acquired,
495 on_name_acquired,495 on_name_acquired,
496496
=== 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-07-15 14:19:40 +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 2015-07-15 14:19:40 +0000
+++ services/panel-service.c 2015-07-15 14:19:40 +0000
@@ -42,7 +42,7 @@
4242
43#define NOTIFY_TIMEOUT 8043#define NOTIFY_TIMEOUT 80
44#define N_TIMEOUT_SLOTS 5044#define N_TIMEOUT_SLOTS 50
45#define MAX_INDICATOR_ENTRIES 10045#define MAX_INDICATOR_ENTRIES 500
4646
47#define NUX_VERTICAL_SCROLL_DELTA 12047#define NUX_VERTICAL_SCROLL_DELTA 120
48#define NUX_HORIZONTAL_SCROLL_DELTA (NUX_VERTICAL_SCROLL_DELTA ^ 2)48#define NUX_HORIZONTAL_SCROLL_DELTA (NUX_VERTICAL_SCROLL_DELTA ^ 2)
@@ -60,10 +60,13 @@
60{60{
61 GSList *indicators;61 GSList *indicators;
62 GSList *dropdown_entries;62 GSList *dropdown_entries;
63 GSList *removed_entries;
63 GHashTable *id2entry_hash;64 GHashTable *id2entry_hash;
64 GHashTable *panel2entries_hash;65 GHashTable *panel2entries_hash;
66 IndicatorObject *appmenu_indicator;
6567
66 gint32 timeouts[N_TIMEOUT_SLOTS];68 guint timeouts[N_TIMEOUT_SLOTS];
69 guint remove_idle;
6770
68 IndicatorObjectEntry *last_entry;71 IndicatorObjectEntry *last_entry;
69 IndicatorObjectEntry *last_dropdown_entry;72 IndicatorObjectEntry *last_dropdown_entry;
@@ -103,14 +106,14 @@
103106
104enum107enum
105{108{
106 SYNC_WAITING = -1,109 SYNC_WAITING = G_MAXUINT,
107 SYNC_NEUTRAL = 0,110 SYNC_NEUTRAL = 0,
108};111};
109112
110static guint32 _service_signals[LAST_SIGNAL] = { 0 };113static guint32 _service_signals[LAST_SIGNAL] = { 0 };
111114
112static const gchar * indicator_order[][2] = {115static const gchar * indicator_order[][2] = {
113 {"libappmenu.so", NULL}, /* indicator-appmenu" */116 {APPMENU_INDICATOR_NAME, NULL}, /* indicator-appmenu" */
114 {"libapplication.so", NULL}, /* indicator-application" */117 {"libapplication.so", NULL}, /* indicator-application" */
115 {"floating-indicators", NULL}, /* position-less NG indicators */118 {"floating-indicators", NULL}, /* position-less NG indicators */
116 {"libprintersmenu.so", NULL}, /* indicator-printers */119 {"libprintersmenu.so", NULL}, /* indicator-printers */
@@ -135,6 +138,8 @@
135static void notify_object (IndicatorObject *object);138static void notify_object (IndicatorObject *object);
136static void update_keybinding (GSettings *, const gchar *, gpointer);139static void update_keybinding (GSettings *, const gchar *, gpointer);
137static void emit_upstart_event (const gchar *);140static void emit_upstart_event (const gchar *);
141static gchar * get_indicator_entry_id_by_entry (IndicatorObjectEntry *entry);
142static IndicatorObjectEntry * get_indicator_entry_by_id (PanelService *self, const gchar *entry_id);
138static GdkFilterReturn event_filter (GdkXEvent *, GdkEvent *, PanelService *);143static GdkFilterReturn event_filter (GdkXEvent *, GdkEvent *, PanelService *);
139144
140/*145/*
@@ -163,7 +168,7 @@
163168
164 for (i = 0; i < N_TIMEOUT_SLOTS; i++)169 for (i = 0; i < N_TIMEOUT_SLOTS; i++)
165 {170 {
166 if (priv->timeouts[i] > 0)171 if (priv->timeouts[i] > 0 && priv->timeouts[i] != SYNC_WAITING)
167 {172 {
168 g_source_remove (priv->timeouts[i]);173 g_source_remove (priv->timeouts[i]);
169 priv->timeouts[i] = 0;174 priv->timeouts[i] = 0;
@@ -264,9 +269,10 @@
264}269}
265270
266static gboolean271static gboolean
267is_point_in_rect (gint x, gint y, GdkRectangle* rect)272rect_contains_point (GdkRectangle* rect, gint x, gint y)
268{273{
269 g_return_val_if_fail (rect, FALSE);274 if (!rect)
275 return FALSE;
270276
271 return (x >= rect->x && x <= (rect->x + rect->width) &&277 return (x >= rect->x && x <= (rect->x + rect->width) &&
272 y >= rect->y && y <= (rect->y + rect->height));278 y >= rect->y && y <= (rect->y + rect->height));
@@ -289,7 +295,7 @@
289 IndicatorObjectEntry *entry = k;295 IndicatorObjectEntry *entry = k;
290 GdkRectangle *geo = v;296 GdkRectangle *geo = v;
291297
292 if (is_point_in_rect (x, y, geo))298 if (rect_contains_point (geo, x, y))
293 {299 {
294 return entry;300 return entry;
295 }301 }
@@ -320,8 +326,7 @@
320 IndicatorObjectEntry *entry = key;326 IndicatorObjectEntry *entry = key;
321 GdkRectangle *geo = value;327 GdkRectangle *geo = value;
322328
323 if (x >= geo->x && x <= (geo->x + geo->width) &&329 if (rect_contains_point (geo, x, y))
324 y >= geo->y && y <= (geo->y + geo->height))
325 {330 {
326 return entry;331 return entry;
327 }332 }
@@ -331,7 +336,7 @@
331}336}
332337
333static const gchar*338static const gchar*
334get_panel_at (PanelService *self, gint x, gint y)339get_panel_for_parent_at (PanelService *self, guint parent, gint x, gint y)
335{340{
336 GHashTableIter panel_iter, entries_iter;341 GHashTableIter panel_iter, entries_iter;
337 gpointer key, value, k, v;342 gpointer key, value, k, v;
@@ -345,12 +350,20 @@
345350
346 while (g_hash_table_iter_next (&entries_iter, &k, &v))351 while (g_hash_table_iter_next (&entries_iter, &k, &v))
347 {352 {
353 IndicatorObjectEntry *entry = k;
348 GdkRectangle *geo = v;354 GdkRectangle *geo = v;
349355
350 if (x >= geo->x && x <= (geo->x + geo->width) &&356 /* The entry might be invalid at this point (as it could have been
351 y >= geo->y && y <= (geo->y + geo->height))357 * removed, but still not synced), so it's better to double check */
358 if (g_slist_find (self->priv->removed_entries, entry))
359 continue;
360
361 if (!parent || entry->parent_window == parent)
352 {362 {
353 return panel_id;363 if (rect_contains_point (geo, x, y))
364 {
365 return panel_id;
366 }
354 }367 }
355 }368 }
356 }369 }
@@ -413,7 +426,7 @@
413 /* Unity might register some "fake" dropdown entries that it might use to426 /* Unity might register some "fake" dropdown entries that it might use to
414 * to present long menu bars (right now only for appmenu indicator) */427 * to present long menu bars (right now only for appmenu indicator) */
415 entry = g_new0 (IndicatorObjectEntry, 1);428 entry = g_new0 (IndicatorObjectEntry, 1);
416 entry->parent_object = panel_service_get_indicator (self, "libappmenu.so");429 entry->parent_object = self->priv->appmenu_indicator;
417 entry->name_hint = g_strdup (entry_id);430 entry->name_hint = g_strdup (entry_id);
418 self->priv->dropdown_entries = g_slist_append (self->priv->dropdown_entries, entry);431 self->priv->dropdown_entries = g_slist_append (self->priv->dropdown_entries, entry);
419 g_hash_table_insert (self->priv->id2entry_hash, (gpointer)entry->name_hint, entry);432 g_hash_table_insert (self->priv->id2entry_hash, (gpointer)entry->name_hint, entry);
@@ -423,6 +436,21 @@
423}436}
424437
425static void438static void
439ensure_entry_menu_is_closed (PanelService *self,
440 const gchar *panel_id,
441 IndicatorObjectEntry *entry)
442{
443 PanelServicePrivate *priv = self->priv;
444
445 /* If the entry has been removed let's make sure that its menu is closed */
446 if (GTK_IS_MENU (priv->last_menu) && priv->last_menu == entry->menu)
447 {
448 if (!priv->last_panel || !panel_id || g_strcmp0 (priv->last_panel, panel_id) == 0)
449 gtk_menu_popdown (entry->menu);
450 }
451}
452
453static void
426reinject_key_event_to_root_window (XIDeviceEvent *ev)454reinject_key_event_to_root_window (XIDeviceEvent *ev)
427{455{
428 XKeyEvent kev;456 XKeyEvent kev;
@@ -542,9 +570,7 @@
542 {570 {
543 /* Middle clicks over an appmenu entry are considered just like571 /* Middle clicks over an appmenu entry are considered just like
544 * all other clicks */572 * all other clicks */
545 IndicatorObject *obj = get_entry_parent_indicator (entry);573 if (get_entry_parent_indicator (entry) == priv->appmenu_indicator)
546
547 if (g_strcmp0 (g_object_get_data (G_OBJECT (obj), "id"), "libappmenu.so") == 0)
548 {574 {
549 event_is_a_click = TRUE;575 event_is_a_click = TRUE;
550 }576 }
@@ -609,7 +635,7 @@
609initial_resync (PanelService *self)635initial_resync (PanelService *self)
610{636{
611 g_signal_emit (self, _service_signals[RE_SYNC], 0, "");637 g_signal_emit (self, _service_signals[RE_SYNC], 0, "");
612 return FALSE;638 return G_SOURCE_REMOVE;
613}639}
614640
615static gboolean641static gboolean
@@ -618,7 +644,7 @@
618 if (!lockscreen_mode)644 if (!lockscreen_mode)
619 emit_upstart_event ("indicator-services-start");645 emit_upstart_event ("indicator-services-start");
620646
621 return FALSE;647 return G_SOURCE_REMOVE;
622}648}
623649
624static void650static void
@@ -782,10 +808,10 @@
782 if (self->priv->indicators == NULL)808 if (self->priv->indicators == NULL)
783 {809 {
784 g_signal_emit (self, _service_signals[INDICATORS_CLEARED], 0);810 g_signal_emit (self, _service_signals[INDICATORS_CLEARED], 0);
785 return FALSE;811 return G_SOURCE_REMOVE;
786 }812 }
787813
788 return TRUE;814 return G_SOURCE_CONTINUE;
789}815}
790816
791static void817static void
@@ -863,6 +889,9 @@
863 g_object_ref_sink (G_OBJECT (indicator));889 g_object_ref_sink (G_OBJECT (indicator));
864 }890 }
865891
892 if (self->priv->appmenu_indicator == indicator)
893 self->priv->appmenu_indicator = NULL;
894
866 g_object_unref (G_OBJECT (indicator));895 g_object_unref (G_OBJECT (indicator));
867}896}
868897
@@ -1077,7 +1106,7 @@
1077 g_signal_emit (self, _service_signals[RE_SYNC],1106 g_signal_emit (self, _service_signals[RE_SYNC],
1078 0, g_object_get_data (G_OBJECT (object), "id"));1107 0, g_object_get_data (G_OBJECT (object), "id"));
10791108
1080 return FALSE;1109 return G_SOURCE_REMOVE;
1081}1110}
10821111
1083static void1112static void
@@ -1136,6 +1165,7 @@
1136 g_return_if_fail (PANEL_IS_SERVICE (self));1165 g_return_if_fail (PANEL_IS_SERVICE (self));
1137 g_return_if_fail (entry != NULL);1166 g_return_if_fail (entry != NULL);
11381167
1168 self->priv->removed_entries = g_slist_remove (self->priv->removed_entries, entry);
1139 gchar *entry_id = get_indicator_entry_id_by_entry (entry);1169 gchar *entry_id = get_indicator_entry_id_by_entry (entry);
1140 g_hash_table_insert (self->priv->id2entry_hash, entry_id, entry);1170 g_hash_table_insert (self->priv->id2entry_hash, entry_id, entry);
11411171
@@ -1175,6 +1205,42 @@
1175 notify_object (object);1205 notify_object (object);
1176}1206}
11771207
1208static gboolean
1209on_removed_idle (PanelService *self)
1210{
1211 GHashTableIter iter;
1212 GHashTable *entry2geometry_hash;
1213 IndicatorObjectEntry *entry;
1214 gpointer value;
1215 GSList *l;
1216
1217 for (l = self->priv->removed_entries; l; l = l->next)
1218 {
1219 entry = l->data;
1220 ensure_entry_menu_is_closed (self, NULL, entry);
1221
1222 g_hash_table_iter_init (&iter, self->priv->panel2entries_hash);
1223 while (g_hash_table_iter_next (&iter, NULL, &value))
1224 {
1225 if ((entry2geometry_hash = value))
1226 {
1227 g_hash_table_remove (entry2geometry_hash, entry);
1228
1229 if (g_hash_table_size (entry2geometry_hash) == 0)
1230 {
1231 g_hash_table_iter_remove (&iter);
1232 }
1233 }
1234 }
1235
1236 }
1237
1238 g_slist_free (self->priv->removed_entries);
1239 self->priv->removed_entries = NULL;
1240
1241 return G_SOURCE_REMOVE;
1242}
1243
1178static void1244static void
1179on_entry_removed (IndicatorObject *object,1245on_entry_removed (IndicatorObject *object,
1180 IndicatorObjectEntry *entry,1246 IndicatorObjectEntry *entry,
@@ -1183,11 +1249,6 @@
1183 g_return_if_fail (PANEL_IS_SERVICE (self));1249 g_return_if_fail (PANEL_IS_SERVICE (self));
1184 g_return_if_fail (entry != NULL);1250 g_return_if_fail (entry != NULL);
11851251
1186 /* Don't remove here the value from panel2entries_hash, this should be
1187 * done during the geometries sync, to avoid false positive.
1188 * FIXME this in libappmenu.so to avoid to send an "entry-removed" signal
1189 * when switching the focus from a window to one of its dialog children */
1190
1191 gchar *entry_id = get_indicator_entry_id_by_entry (entry);1252 gchar *entry_id = get_indicator_entry_id_by_entry (entry);
1192 g_hash_table_remove (self->priv->id2entry_hash, entry_id);1253 g_hash_table_remove (self->priv->id2entry_hash, entry_id);
1193 g_free (entry_id);1254 g_free (entry_id);
@@ -1202,6 +1263,13 @@
1202 g_signal_handlers_disconnect_by_data (entry->image, object);1263 g_signal_handlers_disconnect_by_data (entry->image, object);
1203 }1264 }
12041265
1266 self->priv->removed_entries = g_slist_append (self->priv->removed_entries, entry);
1267
1268 if (self->priv->remove_idle)
1269 g_source_remove (self->priv->remove_idle);
1270
1271 self->priv->remove_idle = g_idle_add ((GSourceFunc) on_removed_idle, self);
1272
1205 notify_object (object);1273 notify_object (object);
1206}1274}
12071275
@@ -1259,6 +1327,7 @@
1259 "unity",1327 "unity",
1260 "unity-3d",1328 "unity-3d",
1261 "unity-panel-service",1329 "unity-panel-service",
1330 "unity-all-menus",
1262 NULL1331 NULL
1263};1332};
12641333
@@ -1278,6 +1347,9 @@
12781347
1279 priv->indicators = g_slist_append (priv->indicators, object);1348 priv->indicators = g_slist_append (priv->indicators, object);
12801349
1350 if (!priv->appmenu_indicator && g_strcmp0 (name, APPMENU_INDICATOR_NAME) == 0)
1351 priv->appmenu_indicator = object;
1352
1281 g_object_set_data_full (G_OBJECT (object), "id", g_strdup (name), g_free);1353 g_object_set_data_full (G_OBJECT (object), "id", g_strdup (name), g_free);
12821354
1283 g_signal_connect (object, INDICATOR_OBJECT_SIGNAL_ENTRY_ADDED,1355 g_signal_connect (object, INDICATOR_OBJECT_SIGNAL_ENTRY_ADDED,
@@ -1539,10 +1611,11 @@
1539 guint32 image_type = 0;1611 guint32 image_type = 0;
1540 gchar *image_data = gtk_image_to_data (entry->image, &image_type);1612 gchar *image_data = gtk_image_to_data (entry->image, &image_type);
15411613
1542 g_variant_builder_add (b, "(ssssbbusbbi)",1614 g_variant_builder_add (b, ENTRY_SIGNATURE,
1543 indicator_id,1615 indicator_id,
1544 id,1616 id,
1545 entry->name_hint ? entry->name_hint : "",1617 entry->name_hint ? entry->name_hint : "",
1618 entry->parent_window,
1546 is_label ? gtk_label_get_label (entry->label) : "",1619 is_label ? gtk_label_get_label (entry->label) : "",
1547 is_label ? gtk_widget_get_sensitive (GTK_WIDGET (entry->label)) : FALSE,1620 is_label ? gtk_widget_get_sensitive (GTK_WIDGET (entry->label)) : FALSE,
1548 is_label ? gtk_widget_get_visible (GTK_WIDGET (entry->label)) : FALSE,1621 is_label ? gtk_widget_get_visible (GTK_WIDGET (entry->label)) : FALSE,
@@ -1559,14 +1632,15 @@
1559indicator_entry_null_to_variant (const gchar *indicator_id,1632indicator_entry_null_to_variant (const gchar *indicator_id,
1560 GVariantBuilder *b)1633 GVariantBuilder *b)
1561{1634{
1562 g_variant_builder_add (b, "(ssssbbusbbi)",1635 g_variant_builder_add (b, ENTRY_SIGNATURE,
1563 indicator_id,1636 indicator_id,
1564 "",1637 "",
1565 "",1638 "",
1639 0,
1566 "",1640 "",
1567 FALSE,1641 FALSE,
1568 FALSE,1642 FALSE,
1569 (guint32) 0,1643 0,
1570 "",1644 "",
1571 FALSE,1645 FALSE,
1572 FALSE,1646 FALSE,
@@ -1574,15 +1648,20 @@
1574}1648}
15751649
1576static void1650static void
1577indicator_object_full_to_variant (IndicatorObject *object, const gchar *indicator_id, GVariantBuilder *b)1651indicator_object_full_to_variant (PanelService *self, IndicatorObject *object,
1652 const gchar *indicator_id, GVariantBuilder *b)
1578{1653{
1579 GList *entries, *e;1654 GList *entries, *e;
1655 GHashTable *index_hash = NULL;
1580 gint parent_prio = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (object), "priority"));1656 gint parent_prio = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (object), "priority"));
1581 entries = indicator_object_get_entries (object);1657 entries = indicator_object_get_entries (object);
1582 gint index = 0;1658 guint index = 0;
15831659
1584 if (entries)1660 if (entries)
1585 {1661 {
1662 if (object == self->priv->appmenu_indicator)
1663 index_hash = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, NULL);
1664
1586 for (e = entries; e; e = e->next)1665 for (e = entries; e; e = e->next)
1587 {1666 {
1588 gint prio = -1;1667 gint prio = -1;
@@ -1596,14 +1675,29 @@
15961675
1597 if (prio < 0)1676 if (prio < 0)
1598 {1677 {
1678 if (index_hash)
1679 {
1680 index = GPOINTER_TO_UINT (g_hash_table_lookup (index_hash,
1681 GUINT_TO_POINTER (entry->parent_window)));
1682 }
1683
1599 prio = parent_prio + index;1684 prio = parent_prio + index;
1600 index++;1685 index++;
1686
1687 if (index_hash)
1688 {
1689 g_hash_table_insert (index_hash, GUINT_TO_POINTER (entry->parent_window),
1690 GUINT_TO_POINTER (index));
1691 }
1601 }1692 }
16021693
1603 indicator_entry_to_variant (entry, id, indicator_id, b, prio);1694 indicator_entry_to_variant (entry, id, indicator_id, b, prio);
1604 g_free (id);1695 g_free (id);
1605 }1696 }
16061697
1698 if (index_hash)
1699 g_hash_table_destroy (index_hash);
1700
1607 g_list_free (entries);1701 g_list_free (entries);
1608 }1702 }
1609 else1703 else
@@ -1614,15 +1708,15 @@
1614}1708}
16151709
1616static void1710static void
1617indicator_object_to_variant (IndicatorObject *object, const gchar *indicator_id, GVariantBuilder *b)1711indicator_object_to_variant (PanelService *self, IndicatorObject *object,
1712 const gchar *indicator_id, GVariantBuilder *b)
1618{1713{
1619 if (!GPOINTER_TO_INT (g_object_get_data (G_OBJECT (object), "remove")))1714 if (!GPOINTER_TO_INT (g_object_get_data (G_OBJECT (object), "remove")))
1620 {1715 {
1621 indicator_object_full_to_variant (object, indicator_id, b);1716 indicator_object_full_to_variant (self, object, indicator_id, b);
1622 }1717 }
1623 else1718 else
1624 {1719 {
1625 PanelService *self = panel_service_get_default ();
1626 indicator_entry_null_to_variant (indicator_id, b);1720 indicator_entry_null_to_variant (indicator_id, b);
1627 panel_service_actually_remove_indicator (self, object);1721 panel_service_actually_remove_indicator (self, object);
1628 }1722 }
@@ -1650,7 +1744,7 @@
1650 rect.height *= scale;1744 rect.height *= scale;
1651 }1745 }
16521746
1653 if (is_point_in_rect (x, y, &rect))1747 if (rect_contains_point (&rect, x, y))
1654 {1748 {
1655 return i;1749 return i;
1656 }1750 }
@@ -1722,8 +1816,8 @@
1722 GSList *i;1816 GSList *i;
1723 gint position;1817 gint position;
17241818
1725 g_variant_builder_init (&b, G_VARIANT_TYPE ("(a(ssssbbusbbi))"));1819 g_variant_builder_init (&b, G_VARIANT_TYPE ("("ENTRY_ARRAY_SIGNATURE")"));
1726 g_variant_builder_open (&b, G_VARIANT_TYPE ("a(ssssbbusbbi)"));1820 g_variant_builder_open (&b, G_VARIANT_TYPE (ENTRY_ARRAY_SIGNATURE));
17271821
1728 for (i = self->priv->indicators; i;)1822 for (i = self->priv->indicators; i;)
1729 {1823 {
@@ -1733,7 +1827,7 @@
17331827
1734 const gchar *indicator_id = g_object_get_data (G_OBJECT (indicator), "id");1828 const gchar *indicator_id = g_object_get_data (G_OBJECT (indicator), "id");
1735 position = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (indicator), "position"));1829 position = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (indicator), "position"));
1736 indicator_object_to_variant (indicator, indicator_id, &b);1830 indicator_object_to_variant (self, indicator, indicator_id, &b);
17371831
1738 /* Set the sync back to neutral */1832 /* Set the sync back to neutral */
1739 self->priv->timeouts[position] = SYNC_NEUTRAL;1833 self->priv->timeouts[position] = SYNC_NEUTRAL;
@@ -1749,8 +1843,8 @@
1749 GVariantBuilder b;1843 GVariantBuilder b;
1750 GSList *i;1844 GSList *i;
17511845
1752 g_variant_builder_init (&b, G_VARIANT_TYPE ("(a(ssssbbusbbi))"));1846 g_variant_builder_init (&b, G_VARIANT_TYPE ("("ENTRY_ARRAY_SIGNATURE")"));
1753 g_variant_builder_open (&b, G_VARIANT_TYPE ("a(ssssbbusbbi)"));1847 g_variant_builder_open (&b, G_VARIANT_TYPE (ENTRY_ARRAY_SIGNATURE));
17541848
1755 for (i = self->priv->indicators; i; i = i->next)1849 for (i = self->priv->indicators; i; i = i->next)
1756 {1850 {
@@ -1758,7 +1852,7 @@
1758 g_object_get_data (G_OBJECT (i->data), "id")) == 0)1852 g_object_get_data (G_OBJECT (i->data), "id")) == 0)
1759 {1853 {
1760 gint position = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (i->data), "position"));1854 gint position = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (i->data), "position"));
1761 indicator_object_to_variant (i->data, indicator_id, &b);1855 indicator_object_to_variant (self, i->data, indicator_id, &b);
17621856
1763 /* Set the sync back to neutral */1857 /* Set the sync back to neutral */
1764 self->priv->timeouts[position] = SYNC_NEUTRAL;1858 self->priv->timeouts[position] = SYNC_NEUTRAL;
@@ -1782,6 +1876,7 @@
1782{1876{
1783 IndicatorObject *object;1877 IndicatorObject *object;
1784 IndicatorObjectEntry *entry;1878 IndicatorObjectEntry *entry;
1879 GHashTable *entry2geometry_hash;
1785 gboolean valid_entry = TRUE;1880 gboolean valid_entry = TRUE;
1786 PanelServicePrivate *priv = self->priv;1881 PanelServicePrivate *priv = self->priv;
17871882
@@ -1802,24 +1897,18 @@
18021897
1803 if (entry)1898 if (entry)
1804 {1899 {
1805 GHashTable *entry2geometry_hash = g_hash_table_lookup (priv->panel2entries_hash, panel_id);1900 entry2geometry_hash = g_hash_table_lookup (priv->panel2entries_hash, panel_id);
18061901
1807 if (width < 0 || height < 0 || !valid_entry)1902 if (width < 0 || height < 0 || !valid_entry)
1808 {1903 {
1809 /* If the entry has been removed let's make sure that its menu is closed */1904 if (valid_entry)
1810 if (valid_entry && GTK_IS_MENU (priv->last_menu) && priv->last_menu == entry->menu)1905 ensure_entry_menu_is_closed (self, panel_id, entry);
1811 {
1812 if (!priv->last_panel || g_strcmp0 (priv->last_panel, panel_id) == 0)
1813 gtk_menu_popdown (entry->menu);
1814 }
18151906
1816 if (entry2geometry_hash)1907 if (entry2geometry_hash)
1817 {1908 {
1818 if (g_hash_table_size (entry2geometry_hash) > 1)1909 g_hash_table_remove (entry2geometry_hash, entry);
1819 {1910
1820 g_hash_table_remove (entry2geometry_hash, entry);1911 if (g_hash_table_size (entry2geometry_hash) == 0)
1821 }
1822 else
1823 {1912 {
1824 g_hash_table_remove (priv->panel2entries_hash, panel_id);1913 g_hash_table_remove (priv->panel2entries_hash, panel_id);
1825 }1914 }
@@ -2188,7 +2277,7 @@
2188 priv->last_x = x;2277 priv->last_x = x;
2189 priv->last_y = y;2278 priv->last_y = y;
2190 priv->last_menu_button = button;2279 priv->last_menu_button = button;
2191 priv->last_panel = get_panel_at (self, x, y);2280 priv->last_panel = get_panel_for_parent_at (self, xid, x, y);
21922281
2193 g_signal_connect (priv->last_menu, "hide", G_CALLBACK (on_active_menu_hidden), self);2282 g_signal_connect (priv->last_menu, "hide", G_CALLBACK (on_active_menu_hidden), self);
2194 g_signal_connect_after (priv->last_menu, "move-current",2283 g_signal_connect_after (priv->last_menu, "move-current",
@@ -2394,10 +2483,9 @@
2394 GList *entries;2483 GList *entries;
23952484
2396 g_return_if_fail (PANEL_IS_SERVICE (self));2485 g_return_if_fail (PANEL_IS_SERVICE (self));
23972486 g_return_if_fail (INDICATOR_IS_OBJECT (self->priv->appmenu_indicator));
2398 object = panel_service_get_indicator (self, "libappmenu.so");2487
2399 g_return_if_fail (INDICATOR_IS_OBJECT (object));2488 object = self->priv->appmenu_indicator;
2400
2401 entries = indicator_object_get_entries (object);2489 entries = indicator_object_get_entries (object);
24022490
2403 if (entries)2491 if (entries)
24042492
=== modified file 'services/panel-service.h'
--- services/panel-service.h 2014-12-09 15:41:53 +0000
+++ services/panel-service.h 2015-07-15 14:19:40 +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-07-15 14:19:40 +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-07-15 14:19:40 +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-07-15 14:19:40 +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-07-15 14:19:40 +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-07-15 14:19:40 +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-07-15 14:19:40 +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)