Merge lp:~unity-team/unity/fix-lp1309778-trusty into lp:unity/7.2
- fix-lp1309778-trusty
- Merge into trusty
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 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
PS Jenkins bot (community) | continuous-integration | Approve | |
Unity Team | 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.
Description of the change
PS Jenkins bot (ps-jenkins) wrote : | # |
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:3833
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Unmerged revisions
- 3833. By Christopher Townsend
-
Merge lp:unity/7.2.
- 3832. By Marco Trevisan (Treviño)
-
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
1 | === modified file 'UnityCore/AppmenuIndicator.cpp' |
2 | --- UnityCore/AppmenuIndicator.cpp 2015-03-12 00:57:05 +0000 |
3 | +++ UnityCore/AppmenuIndicator.cpp 2015-07-15 14:19:40 +0000 |
4 | @@ -17,41 +17,81 @@ |
5 | * Authored by: Marco Trevisan (Treviño) <3v1n0@ubuntu.com> |
6 | */ |
7 | |
8 | -#include "GLibSource.h" |
9 | +#include <unordered_set> |
10 | + |
11 | #include "AppmenuIndicator.h" |
12 | +#include "ConnectionManager.h" |
13 | |
14 | namespace unity |
15 | { |
16 | namespace indicator |
17 | { |
18 | +namespace |
19 | +{ |
20 | +const Indicator::Entries empty_entries_; |
21 | +} |
22 | |
23 | struct AppmenuIndicator::Impl |
24 | { |
25 | Impl(AppmenuIndicator* parent) |
26 | { |
27 | - // When the active window has changed we might need to emit an updated signal |
28 | - parent->active_window.changed.connect([this, parent] (unsigned long) { |
29 | - update_wait_.reset(new glib::Timeout(250, [parent] { |
30 | - parent->updated.emit(); |
31 | - return false; |
32 | - })); |
33 | - }); |
34 | - |
35 | - parent->updated.connect([this] { update_wait_.reset(); }); |
36 | + connections_.Add(parent->on_entry_added.connect([this] (Entry::Ptr const& entry) { |
37 | + window_entries_[entry->parent_window()].push_back(entry); |
38 | + })); |
39 | + |
40 | + connections_.Add(parent->on_entry_removed.connect([this] (Entry::Ptr const& entry) { |
41 | + auto it = window_entries_.find(entry->parent_window()); |
42 | + |
43 | + if (it != window_entries_.end()) |
44 | + { |
45 | + auto& entries = it->second; |
46 | + entries.erase(std::remove(entries.begin(), entries.end(), entry), entries.end()); |
47 | + |
48 | + if (entries.empty()) |
49 | + window_entries_.erase(it); |
50 | + } |
51 | + })); |
52 | } |
53 | |
54 | - glib::Source::UniquePtr update_wait_; |
55 | + connection::Manager connections_; |
56 | + std::unordered_map<uint32_t, Indicator::Entries> window_entries_; |
57 | }; |
58 | |
59 | AppmenuIndicator::AppmenuIndicator(std::string const& name) |
60 | : Indicator(name) |
61 | - , active_window(0) |
62 | , impl_(new AppmenuIndicator::Impl(this)) |
63 | {} |
64 | |
65 | AppmenuIndicator::~AppmenuIndicator() |
66 | {} |
67 | |
68 | +void 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 | + |
85 | +Indicator::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 | + |
95 | void AppmenuIndicator::ShowAppmenu(unsigned int xid, int x, int y) const |
96 | { |
97 | on_show_appmenu.emit(xid, x, y); |
98 | |
99 | === modified file 'UnityCore/AppmenuIndicator.h' |
100 | --- UnityCore/AppmenuIndicator.h 2015-03-12 00:57:05 +0000 |
101 | +++ UnityCore/AppmenuIndicator.h 2015-07-15 14:19:40 +0000 |
102 | @@ -36,12 +36,13 @@ |
103 | AppmenuIndicator(std::string const& name); |
104 | ~AppmenuIndicator(); |
105 | |
106 | - nux::Property<unsigned> active_window; |
107 | - |
108 | - virtual bool IsAppmenu() const { return true; } |
109 | + bool IsAppmenu() const override { return true; } |
110 | + void Sync(Entries const&) override; |
111 | + Entries const& GetEntriesForWindow(uint32_t parent_window) const; |
112 | |
113 | void ShowAppmenu(unsigned xid, int x, int y) const; |
114 | |
115 | + sigc::signal<void, uint32_t> updated_win; |
116 | sigc::signal<void, unsigned, int, int> on_show_appmenu; |
117 | |
118 | private: |
119 | |
120 | === modified file 'UnityCore/CMakeLists.txt' |
121 | --- UnityCore/CMakeLists.txt 2014-02-05 11:38:22 +0000 |
122 | +++ UnityCore/CMakeLists.txt 2015-07-15 14:19:40 +0000 |
123 | @@ -117,6 +117,7 @@ |
124 | # |
125 | include_directories(${CORE_DEPS_INCLUDE_DIRS}) |
126 | include_directories(${CMAKE_BINARY_DIR}) |
127 | +include_directories(..) |
128 | |
129 | set (LIBS ${CORE_DEPS_LDFLAGS} ${PRIVATE_CORE_DEPS_LDFLAGS}) |
130 | |
131 | |
132 | === modified file 'UnityCore/DBusIndicators.cpp' |
133 | --- UnityCore/DBusIndicators.cpp 2014-12-09 15:41:53 +0000 |
134 | +++ UnityCore/DBusIndicators.cpp 2015-07-15 14:19:40 +0000 |
135 | @@ -27,19 +27,29 @@ |
136 | #include "GLibSource.h" |
137 | #include "Variant.h" |
138 | #include "DBusIndicators.h" |
139 | +#include "services/panel-service-private.h" |
140 | |
141 | namespace unity |
142 | { |
143 | namespace indicator |
144 | { |
145 | + |
146 | +namespace |
147 | +{ |
148 | DECLARE_LOGGER(logger, "unity.indicator.dbus"); |
149 | |
150 | -namespace |
151 | +inline bool verify_variant_type(GVariant* value, const gchar* type) |
152 | { |
153 | -const std::string SERVICE_NAME_DESKTOP("com.canonical.Unity.Panel.Service.Desktop"); |
154 | -const std::string SERVICE_NAME_LOCKSCREEN("com.canonical.Unity.Panel.Service.LockScreen"); |
155 | -const std::string SERVICE_PATH("/com/canonical/Unity/Panel/Service"); |
156 | -const std::string SERVICE_IFACE("com.canonical.Unity.Panel.Service"); |
157 | + if (!g_variant_is_of_type (value, G_VARIANT_TYPE(type))) |
158 | + { |
159 | + LOG_ERROR(logger) << "Got invalid variant type: '" |
160 | + << g_variant_get_type_string(value) << "' ('" |
161 | + << type << "' was expected)"; |
162 | + return false; |
163 | + } |
164 | + |
165 | + return true; |
166 | +} |
167 | } // anonymous namespace |
168 | |
169 | |
170 | @@ -78,15 +88,15 @@ |
171 | glib::Source::UniquePtr show_entry_idle_; |
172 | glib::Source::UniquePtr show_appmenu_idle_; |
173 | std::vector<std::string> icon_paths_; |
174 | - std::map<std::string, EntryLocationMap> cached_locations_; |
175 | + std::unordered_map<std::string, EntryLocationMap> cached_locations_; |
176 | }; |
177 | |
178 | |
179 | // Public Methods |
180 | DBusIndicators::Impl::Impl(std::string const& dbus_name, DBusIndicators* owner) |
181 | : owner_(owner) |
182 | - , gproxy_(dbus_name, SERVICE_PATH, SERVICE_IFACE, |
183 | - G_BUS_TYPE_SESSION, G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES) |
184 | + , gproxy_(dbus_name, UPS_PATH, UPS_IFACE, G_BUS_TYPE_SESSION, |
185 | + G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES) |
186 | { |
187 | gproxy_.Connect("ReSync", sigc::mem_fun(this, &DBusIndicators::Impl::OnReSync)); |
188 | gproxy_.Connect("IconPathsChanged", sigc::mem_fun(this, &DBusIndicators::Impl::OnIconsPathChanged)); |
189 | @@ -208,6 +218,9 @@ |
190 | |
191 | void DBusIndicators::Impl::OnEntryActivated(GVariant* parameters) |
192 | { |
193 | + if (!verify_variant_type(parameters, "(ss(iiuu))")) |
194 | + return; |
195 | + |
196 | glib::String panel; |
197 | glib::String entry_id; |
198 | nux::Rect geo; |
199 | @@ -219,6 +232,9 @@ |
200 | |
201 | void DBusIndicators::Impl::OnEntryActivatedRequest(GVariant* parameters) |
202 | { |
203 | + if (!verify_variant_type(parameters, "(s)")) |
204 | + return; |
205 | + |
206 | glib::String entry_name; |
207 | g_variant_get(parameters, "(s)", &entry_name); |
208 | |
209 | @@ -228,6 +244,9 @@ |
210 | |
211 | void DBusIndicators::Impl::OnEntryShowNowChanged(GVariant* parameters) |
212 | { |
213 | + if (!verify_variant_type(parameters, "(sb)")) |
214 | + return; |
215 | + |
216 | glib::String entry_name; |
217 | gboolean show_now; |
218 | g_variant_get(parameters, "(sb)", &entry_name, &show_now); |
219 | @@ -325,9 +344,10 @@ |
220 | return; |
221 | |
222 | GVariantIter* iter = nullptr; |
223 | - gchar* name_hint = nullptr; |
224 | gchar* indicator_id = nullptr; |
225 | gchar* entry_id = nullptr; |
226 | + gchar* name_hint = nullptr; |
227 | + guint32 parent_window = 0; |
228 | gchar* label = nullptr; |
229 | gboolean label_sensitive = false; |
230 | gboolean label_visible = false; |
231 | @@ -337,15 +357,17 @@ |
232 | gboolean image_visible = false; |
233 | gint32 priority = -1; |
234 | |
235 | - std::map<Indicator::Ptr, Indicator::Entries> indicators; |
236 | - int wanted_idx = 0; |
237 | - bool any_different_idx = false; |
238 | - |
239 | - g_variant_get(args, "(a(ssssbbusbbi))", &iter); |
240 | - while (g_variant_iter_loop(iter, "(ssssbbusbbi)", |
241 | + if (!verify_variant_type(args, "(" ENTRY_ARRAY_SIGNATURE ")")) |
242 | + return; |
243 | + |
244 | + std::unordered_map<Indicator::Ptr, Indicator::Entries> indicators; |
245 | + |
246 | + g_variant_get(args, "(" ENTRY_ARRAY_SIGNATURE ")", &iter); |
247 | + while (g_variant_iter_loop(iter, ENTRY_SIGNATURE, |
248 | &indicator_id, |
249 | &entry_id, |
250 | &name_hint, |
251 | + &parent_window, |
252 | &label, |
253 | &label_sensitive, |
254 | &label_visible, |
255 | @@ -369,27 +391,20 @@ |
256 | // Empty entries are empty indicators. |
257 | if (!entry.empty()) |
258 | { |
259 | - Entry::Ptr e; |
260 | - if (!any_different_idx) |
261 | - { |
262 | - // Indicators can only add or remove entries, so if |
263 | - // there is a index change we can't reuse the existing ones |
264 | - // after that index |
265 | - if (indicator->EntryIndex(entry_id) == wanted_idx) |
266 | - { |
267 | - e = indicator->GetEntry(entry_id); |
268 | - } |
269 | - else |
270 | - { |
271 | - any_different_idx = true; |
272 | - } |
273 | - } |
274 | + Entry::Ptr e = indicator->GetEntry(entry_id); |
275 | + int old_priority = e ? e->priority() : -1; |
276 | + |
277 | + // Indicators can only add or remove entries, so if |
278 | + // there is a priority change we can't reuse the existing ones |
279 | + if (old_priority != priority) |
280 | + e.reset(); |
281 | |
282 | if (!e) |
283 | { |
284 | - e = std::make_shared<Entry>(entry, name_hint, label, label_sensitive, |
285 | - label_visible, image_type, image_data, |
286 | - image_sensitive, image_visible, priority); |
287 | + e = std::make_shared<Entry>(entry, name_hint, parent_window, |
288 | + label, label_sensitive, label_visible, |
289 | + image_type, image_data, image_sensitive, image_visible, |
290 | + priority); |
291 | } |
292 | else |
293 | { |
294 | @@ -399,15 +414,12 @@ |
295 | } |
296 | |
297 | entries.push_back(e); |
298 | - ++wanted_idx; |
299 | } |
300 | } |
301 | g_variant_iter_free(iter); |
302 | |
303 | - for (auto i = indicators.begin(), end = indicators.end(); i != end; ++i) |
304 | - { |
305 | - i->first->Sync(indicators[i->first]); |
306 | - } |
307 | + for (auto const& i : indicators) |
308 | + i.first->Sync(i.second); |
309 | } |
310 | |
311 | void DBusIndicators::Impl::SyncGeometries(std::string const& name, |
312 | @@ -463,7 +475,7 @@ |
313 | } |
314 | |
315 | DBusIndicators::DBusIndicators() |
316 | - : pimpl(new Impl(SERVICE_NAME_DESKTOP, this)) |
317 | + : pimpl(new Impl(UPS_NAME_DESKTOP, this)) |
318 | {} |
319 | |
320 | DBusIndicators::DBusIndicators(std::string const& dbus_name) |
321 | @@ -471,7 +483,7 @@ |
322 | {} |
323 | |
324 | LockScreenDBusIndicators::LockScreenDBusIndicators() |
325 | - : DBusIndicators(SERVICE_NAME_LOCKSCREEN) |
326 | + : DBusIndicators(UPS_NAME_LOCKSCREEN) |
327 | {} |
328 | |
329 | DBusIndicators::~DBusIndicators() |
330 | |
331 | === modified file 'UnityCore/GLibDBusServer.cpp' |
332 | --- UnityCore/GLibDBusServer.cpp 2014-04-09 13:19:33 +0000 |
333 | +++ UnityCore/GLibDBusServer.cpp 2015-07-15 14:19:40 +0000 |
334 | @@ -17,6 +17,7 @@ |
335 | * Authored by: Marco Trevisan (Treviño) <marco.trevisan@canonical.com> |
336 | */ |
337 | |
338 | +#include <unordered_map> |
339 | #include <NuxCore/Logger.h> |
340 | |
341 | #include "GLibDBusServer.h" |
342 | @@ -406,8 +407,8 @@ |
343 | |
344 | GDBusInterfaceVTable interface_vtable_; |
345 | std::shared_ptr<GDBusInterfaceInfo> interface_info_; |
346 | - std::map<guint, std::string> registrations_; |
347 | - std::map<std::string, glib::Object<GDBusConnection>> connection_by_path_; |
348 | + std::unordered_map<guint, std::string> registrations_; |
349 | + std::unordered_map<std::string, glib::Object<GDBusConnection>> connection_by_path_; |
350 | }; |
351 | |
352 | DBusObject::DBusObject(std::string const& introspection_xml, std::string const& interface_name) |
353 | |
354 | === modified file 'UnityCore/GLibSource.h' |
355 | --- UnityCore/GLibSource.h 2013-10-10 09:47:24 +0000 |
356 | +++ UnityCore/GLibSource.h 2015-07-15 14:19:40 +0000 |
357 | @@ -24,7 +24,7 @@ |
358 | #include <sigc++/sigc++.h> |
359 | #include <glib.h> |
360 | #include <memory> |
361 | -#include <map> |
362 | +#include <unordered_map> |
363 | |
364 | namespace unity |
365 | { |
366 | @@ -223,7 +223,7 @@ |
367 | Source::Ptr GetSource(unsigned int id) const; |
368 | |
369 | protected: // For testing purposes |
370 | - typedef std::map<std::string, Source::Ptr> SourcesMap; |
371 | + typedef std::unordered_map<std::string, Source::Ptr> SourcesMap; |
372 | SourcesMap sources_; |
373 | |
374 | private: |
375 | |
376 | === modified file 'UnityCore/Indicator.cpp' |
377 | --- UnityCore/Indicator.cpp 2014-01-27 17:31:30 +0000 |
378 | +++ UnityCore/Indicator.cpp 2015-07-15 14:19:40 +0000 |
379 | @@ -36,7 +36,7 @@ |
380 | Indicator::~Indicator() |
381 | { |
382 | for (auto const& entry : entries_) |
383 | - on_entry_removed.emit(entry->id()); |
384 | + on_entry_removed.emit(entry); |
385 | } |
386 | |
387 | std::string const& Indicator::name() const |
388 | @@ -51,23 +51,23 @@ |
389 | |
390 | void Indicator::Sync(Indicator::Entries const& new_entries) |
391 | { |
392 | - bool added = false; |
393 | - Entries to_rm; |
394 | + bool changed = false; |
395 | |
396 | - if (!entries_.empty()) |
397 | + for (auto it = entries_.begin(); it != entries_.end();) |
398 | { |
399 | - for (auto const& entry : entries_) |
400 | + auto entry = *it; |
401 | + |
402 | + if (std::find(new_entries.begin(), new_entries.end(), entry) == new_entries.end()) |
403 | { |
404 | - if (std::find(new_entries.begin(), new_entries.end(), entry) == new_entries.end()) |
405 | - to_rm.push_back(entry); |
406 | + auto entry_id = entry->id(); |
407 | + entries_connections_.erase(entry); |
408 | + it = entries_.erase(it); |
409 | + on_entry_removed.emit(entry); |
410 | + changed = true; |
411 | + continue; |
412 | } |
413 | - } |
414 | |
415 | - for (auto const& entry : to_rm) |
416 | - { |
417 | - entries_connections_.erase(entry); |
418 | - on_entry_removed.emit(entry->id()); |
419 | - entries_.remove(entry); |
420 | + ++it; |
421 | } |
422 | |
423 | for (auto const& new_entry : new_entries) |
424 | @@ -93,10 +93,10 @@ |
425 | entries_.push_back(new_entry); |
426 | on_entry_added.emit(new_entry); |
427 | |
428 | - added = true; |
429 | + changed = true; |
430 | } |
431 | |
432 | - if (!to_rm.empty() || added) |
433 | + if (changed) |
434 | updated.emit(); |
435 | } |
436 | |
437 | @@ -109,21 +109,6 @@ |
438 | return Entry::Ptr(); |
439 | } |
440 | |
441 | -int Indicator::EntryIndex(std::string const& entry_id) const |
442 | -{ |
443 | - int i = 0; |
444 | - for (auto const& entry : entries_) |
445 | - { |
446 | - if (entry->id() == entry_id) |
447 | - { |
448 | - return i; |
449 | - } |
450 | - ++i; |
451 | - } |
452 | - |
453 | - return -1; |
454 | -} |
455 | - |
456 | std::ostream& operator<<(std::ostream& out, Indicator const& i) |
457 | { |
458 | out << "<Indicator " << i.name() << std::endl; |
459 | |
460 | === modified file 'UnityCore/Indicator.h' |
461 | --- UnityCore/Indicator.h 2014-02-05 17:16:41 +0000 |
462 | +++ UnityCore/Indicator.h 2015-07-15 14:19:40 +0000 |
463 | @@ -38,7 +38,7 @@ |
464 | { |
465 | public: |
466 | typedef std::shared_ptr<Indicator> Ptr; |
467 | - typedef std::list<Entry::Ptr> Entries; |
468 | + typedef std::vector<Entry::Ptr> Entries; |
469 | |
470 | Indicator(std::string const& name); |
471 | virtual ~Indicator(); |
472 | @@ -47,15 +47,14 @@ |
473 | |
474 | virtual bool IsAppmenu() const { return false; } |
475 | |
476 | - void Sync(Entries const& new_entries); |
477 | + virtual void Sync(Entries const&); |
478 | Entry::Ptr GetEntry(std::string const& entry_id) const; |
479 | - int EntryIndex(std::string const& entry_id) const; |
480 | Entries const& GetEntries() const; |
481 | |
482 | // Signals |
483 | sigc::signal<void> updated; |
484 | sigc::signal<void, Entry::Ptr const&> on_entry_added; |
485 | - sigc::signal<void, std::string const&> on_entry_removed; |
486 | + sigc::signal<void, Entry::Ptr const&> on_entry_removed; |
487 | sigc::signal<void, std::string const&, unsigned, int, int, unsigned> on_show_menu; |
488 | sigc::signal<void, std::string const&> on_secondary_activate; |
489 | sigc::signal<void, std::string const&, int> on_scroll; |
490 | |
491 | === modified file 'UnityCore/IndicatorEntry.cpp' |
492 | --- UnityCore/IndicatorEntry.cpp 2014-02-07 23:54:15 +0000 |
493 | +++ UnityCore/IndicatorEntry.cpp 2015-07-15 14:19:40 +0000 |
494 | @@ -30,6 +30,7 @@ |
495 | |
496 | Entry::Entry(std::string const& id, |
497 | std::string const& name_hint, |
498 | + uint32_t parent_window, |
499 | std::string const& label, |
500 | bool label_sensitive, |
501 | bool label_visible, |
502 | @@ -40,6 +41,7 @@ |
503 | int priority) |
504 | : id_(id) |
505 | , name_hint_(name_hint) |
506 | + , parent_window_(parent_window) |
507 | , label_(label) |
508 | , label_visible_(label_visible) |
509 | , label_sensitive_(label_sensitive) |
510 | @@ -52,9 +54,10 @@ |
511 | , active_(false) |
512 | {} |
513 | |
514 | -Entry::Entry(std::string const& id, std::string const& name_hint) |
515 | +Entry::Entry(std::string const& id, std::string const& name_hint, uint32_t parent_window) |
516 | : id_(id) |
517 | , name_hint_(name_hint) |
518 | + , parent_window_(parent_window) |
519 | , label_visible_(false) |
520 | , label_sensitive_(false) |
521 | , image_type_(0) |
522 | @@ -65,14 +68,19 @@ |
523 | , active_(false) |
524 | {} |
525 | |
526 | +std::string const& Entry::id() const |
527 | +{ |
528 | + return id_; |
529 | +} |
530 | + |
531 | std::string const& Entry::name_hint() const |
532 | { |
533 | return name_hint_; |
534 | } |
535 | |
536 | -std::string const& Entry::id() const |
537 | +uint32_t Entry::parent_window() const |
538 | { |
539 | - return id_; |
540 | + return parent_window_; |
541 | } |
542 | |
543 | std::string const& Entry::label() const |
544 | @@ -199,6 +207,7 @@ |
545 | |
546 | id_ = rhs.id_; |
547 | name_hint_ = rhs.name_hint_; |
548 | + parent_window_ = rhs.parent_window_; |
549 | label_ = rhs.label_; |
550 | label_sensitive_ = rhs.label_sensitive_; |
551 | label_visible_ = rhs.label_visible_; |
552 | @@ -258,7 +267,7 @@ |
553 | |
554 | void Entry::ShowMenu(int x, int y, unsigned button) |
555 | { |
556 | - ShowMenu(0, x, y, button); |
557 | + ShowMenu(parent_window_, x, y, button); |
558 | } |
559 | |
560 | void Entry::ShowMenu(unsigned int xid, int x, int y, unsigned button) |
561 | @@ -278,7 +287,8 @@ |
562 | |
563 | std::ostream& operator<<(std::ostream& out, Entry const& e) |
564 | { |
565 | - out << "<indicator::Entry " << e.id() << " hint: '" << e.name_hint() << "' " |
566 | + out << "<indicator::Entry " << e.id() << " hint: '" << e.name_hint() << "'" |
567 | + << " parent window: " << e.parent_window() |
568 | << std::boolalpha |
569 | << " \"" << e.label() << "\" (" |
570 | << e.label_sensitive() << ", " << e.label_visible() << ") image (" |
571 | |
572 | === modified file 'UnityCore/IndicatorEntry.h' |
573 | --- UnityCore/IndicatorEntry.h 2014-02-05 17:16:41 +0000 |
574 | +++ UnityCore/IndicatorEntry.h 2015-07-15 14:19:40 +0000 |
575 | @@ -44,9 +44,10 @@ |
576 | public: |
577 | typedef std::shared_ptr<Entry> Ptr; |
578 | |
579 | - Entry(std::string const& id, std::string const& name_hint = ""); |
580 | + Entry(std::string const& id, std::string const& name_hint = "", uint32_t parent_window = 0); |
581 | Entry(std::string const& id, |
582 | std::string const& name_hint, |
583 | + uint32_t parent_window, |
584 | std::string const& label, |
585 | bool label_sensitive, |
586 | bool label_visible, |
587 | @@ -61,6 +62,7 @@ |
588 | |
589 | std::string const& id() const; |
590 | std::string const& name_hint() const; |
591 | + uint32_t parent_window() const; |
592 | |
593 | void set_image(int type, std::string const& data, bool sensitive, bool visible); |
594 | bool image_visible() const; |
595 | @@ -114,6 +116,7 @@ |
596 | private: |
597 | std::string id_; |
598 | std::string name_hint_; |
599 | + uint32_t parent_window_; |
600 | |
601 | std::string label_; |
602 | bool label_visible_; |
603 | |
604 | === modified file 'UnityCore/Indicators.cpp' |
605 | --- UnityCore/Indicators.cpp 2014-02-11 03:11:47 +0000 |
606 | +++ UnityCore/Indicators.cpp 2015-07-15 14:19:40 +0000 |
607 | @@ -20,6 +20,7 @@ |
608 | |
609 | #include "Indicators.h" |
610 | #include "AppmenuIndicator.h" |
611 | +#include "services/panel-service-private.h" |
612 | |
613 | namespace unity |
614 | { |
615 | @@ -143,7 +144,7 @@ |
616 | if (indicator) |
617 | return indicator; |
618 | |
619 | - if (name == "libappmenu.so") |
620 | + if (name == APPMENU_INDICATOR_NAME) |
621 | { |
622 | auto appmenu = std::make_shared<AppmenuIndicator>(name); |
623 | appmenu->on_show_appmenu.connect(sigc::mem_fun(owner_, &Indicators::OnShowAppMenu)); |
624 | |
625 | === modified file 'UnityCore/pch/unitycore_pch.hh' |
626 | --- UnityCore/pch/unitycore_pch.hh 2014-01-28 15:39:57 +0000 |
627 | +++ UnityCore/pch/unitycore_pch.hh 2015-07-15 14:19:40 +0000 |
628 | @@ -29,6 +29,7 @@ |
629 | #include <map> |
630 | #include <memory> |
631 | #include <unordered_map> |
632 | +#include <functional> |
633 | |
634 | #include <boost/utility.hpp> |
635 | #include <dee.h> |
636 | |
637 | === modified file 'com.canonical.Unity.gschema.xml' |
638 | --- com.canonical.Unity.gschema.xml 2015-03-12 00:57:05 +0000 |
639 | +++ com.canonical.Unity.gschema.xml 2015-07-15 14:19:40 +0000 |
640 | @@ -158,5 +158,11 @@ |
641 | a window by double-clicking on its menus if the second click happens before the |
642 | specified value of ms is elapsed</description> |
643 | </key> |
644 | + <key type="b" name="unfocused-windows-popup"> |
645 | + <default>true</default> |
646 | + <summary>Whether to pop-up a menu when clicking over unfocused windows entries</summary> |
647 | + <description>By disabling this setting you can make unity to only focus a window |
648 | + when clicking over unfocused menu entries</description> |
649 | + </key> |
650 | </schema> |
651 | </schemalist> |
652 | |
653 | === modified file 'dash/DashView.h' |
654 | --- dash/DashView.h 2014-07-24 13:49:53 +0000 |
655 | +++ dash/DashView.h 2015-07-15 14:19:40 +0000 |
656 | @@ -56,7 +56,7 @@ |
657 | class DashView : public nux::View, public unity::debug::Introspectable |
658 | { |
659 | NUX_DECLARE_OBJECT_TYPE(DashView, nux::View); |
660 | - typedef std::map<std::string, nux::ObjectPtr<ScopeView>> ScopeViews; |
661 | + typedef std::unordered_map<std::string, nux::ObjectPtr<ScopeView>> ScopeViews; |
662 | |
663 | public: |
664 | DashView(Scopes::Ptr const& scopes, ApplicationStarter::Ptr const& application_starter); |
665 | |
666 | === modified file 'dash/ScopeView.h' |
667 | --- dash/ScopeView.h 2014-08-06 14:09:30 +0000 |
668 | +++ dash/ScopeView.h 2015-07-15 14:19:40 +0000 |
669 | @@ -35,6 +35,7 @@ |
670 | #include "unity-shared/Introspectable.h" |
671 | #include "PlacesGroup.h" |
672 | #include "ResultViewGrid.h" |
673 | +#include "unity-shared/NuxObjectPtrHash.h" |
674 | #include "unity-shared/UBusWrapper.h" |
675 | |
676 | namespace unity |
677 | @@ -48,7 +49,7 @@ |
678 | { |
679 | NUX_DECLARE_OBJECT_TYPE(ScopeView, nux::View); |
680 | typedef std::vector<PlacesGroup::Ptr> CategoryGroups; |
681 | - typedef std::map<PlacesGroup::Ptr, unsigned int> ResultCounts; |
682 | + typedef std::unordered_map<PlacesGroup::Ptr, unsigned int> ResultCounts; |
683 | |
684 | public: |
685 | ScopeView(Scope::Ptr const& scope, nux::Area* show_filters); |
686 | |
687 | === modified file 'debian/control' |
688 | --- debian/control 2015-03-11 18:11:24 +0000 |
689 | +++ debian/control 2015-07-15 14:19:40 +0000 |
690 | @@ -80,7 +80,7 @@ |
691 | Provides: indicator-renderer |
692 | Recommends: unity-control-center, |
693 | ${unity-default-masterscopes} |
694 | - indicator-appmenu, |
695 | + indicator-appmenu (>= 15.02.0), |
696 | indicator-application, |
697 | indicator-sound, |
698 | indicator-bluetooth, |
699 | |
700 | === modified file 'decorations/DecoratedWindow.cpp' |
701 | --- decorations/DecoratedWindow.cpp 2015-03-12 00:57:05 +0000 |
702 | +++ decorations/DecoratedWindow.cpp 2015-07-15 14:19:40 +0000 |
703 | @@ -52,17 +52,13 @@ |
704 | , deco_elements_(cu::DecorationElement::NONE) |
705 | , last_mwm_decor_(win_->mwmDecor()) |
706 | , last_actions_(win_->actions()) |
707 | + , panel_id_(MENUS_PANEL_NAME + std::to_string(win_->id())) |
708 | , cv_(Settings::Instance().em()) |
709 | { |
710 | active.changed.connect([this] (bool active) { |
711 | bg_textures_.clear(); |
712 | if (top_layout_) |
713 | - { |
714 | top_layout_->focused = active; |
715 | - |
716 | - if (!active) |
717 | - UnsetAppMenu(); |
718 | - } |
719 | RedrawDecorations(); |
720 | }); |
721 | |
722 | @@ -703,7 +699,7 @@ |
723 | |
724 | void Window::Impl::SetupAppMenu() |
725 | { |
726 | - if (!active() || !top_layout_) |
727 | + if (!top_layout_) |
728 | return; |
729 | |
730 | auto const& menu_manager = manager_->impl_->menu_manager_; |
731 | @@ -718,8 +714,11 @@ |
732 | |
733 | auto menus = std::make_shared<MenuLayout>(menu_manager, win_); |
734 | menus->Setup(); |
735 | + |
736 | + if (menus->Items().empty()) |
737 | + return; |
738 | + |
739 | menus_ = menus; |
740 | - |
741 | auto const& grab_edge = grab_edge_.lock(); |
742 | sliding_layout->SetInputItem(menus); |
743 | sliding_layout->fadein = menu_manager->fadein(); |
744 | @@ -761,13 +760,18 @@ |
745 | sliding_layout->mouse_owner = grab_edge_->mouse_owner(); |
746 | } |
747 | |
748 | +inline std::string const& Window::Impl::GetMenusPanelID() const |
749 | +{ |
750 | + return panel_id_; |
751 | +} |
752 | + |
753 | void Window::Impl::UnsetAppMenu() |
754 | { |
755 | if (!menus_) |
756 | return; |
757 | |
758 | auto const& indicators = manager_->impl_->menu_manager_->Indicators(); |
759 | - indicators->SyncGeometries(MENUS_PANEL_NAME, indicator::EntryLocationMap()); |
760 | + indicators->SyncGeometries(GetMenusPanelID(), indicator::EntryLocationMap()); |
761 | sliding_layout_->SetInputItem(nullptr); |
762 | grab_mouse_changed_->disconnect(); |
763 | } |
764 | @@ -780,7 +784,7 @@ |
765 | auto const& indicators = manager_->impl_->menu_manager_->Indicators(); |
766 | indicator::EntryLocationMap map; |
767 | menus_->ChildrenGeometries(map); |
768 | - indicators->SyncGeometries(MENUS_PANEL_NAME, map); |
769 | + indicators->SyncGeometries(GetMenusPanelID(), map); |
770 | } |
771 | |
772 | bool Window::Impl::ActivateMenu(std::string const& entry_id) |
773 | |
774 | === modified file 'decorations/DecorationsManager.cpp' |
775 | --- decorations/DecorationsManager.cpp 2015-03-12 00:57:05 +0000 |
776 | +++ decorations/DecorationsManager.cpp 2015-07-15 14:19:40 +0000 |
777 | @@ -144,27 +144,24 @@ |
778 | return; |
779 | } |
780 | |
781 | - appmenu->active_window = screen->activeWindow(); |
782 | - |
783 | - auto setup_active_window = [this] { |
784 | - if (Window::Ptr const& active_win = active_deco_win_.lock()) |
785 | - active_win->impl_->SetupAppMenu(); |
786 | - }; |
787 | + for (auto const& win : windows_) |
788 | + win.second->impl_->SetupAppMenu(); |
789 | |
790 | menu_connections_.Remove(appmenu_connection_); |
791 | - appmenu_connection_ = menu_connections_.Add(appmenu->updated.connect(setup_active_window)); |
792 | - setup_active_window(); |
793 | + appmenu_connection_ = menu_connections_.Add(appmenu->updated_win.connect([this] (uint32_t xid) { |
794 | + if (Window::Ptr const& win = GetWindowByXid(xid)) |
795 | + win->impl_->SetupAppMenu(); |
796 | + })); |
797 | } |
798 | |
799 | void Manager::Impl::UnsetAppMenu() |
800 | { |
801 | menu_connections_.Remove(appmenu_connection_); |
802 | - auto const& active_win = active_deco_win_.lock(); |
803 | |
804 | - if (active_win) |
805 | + for (auto const& win : windows_) |
806 | { |
807 | - active_win->impl_->UnsetAppMenu(); |
808 | - active_win->impl_->Damage(); |
809 | + win.second->impl_->UnsetAppMenu(); |
810 | + win.second->impl_->Damage(); |
811 | } |
812 | } |
813 | |
814 | @@ -268,9 +265,6 @@ |
815 | |
816 | if (new_active) |
817 | new_active->impl_->active = true; |
818 | - |
819 | - if (indicator::AppmenuIndicator::Ptr const& appmenu = menu_manager_->AppMenu()) |
820 | - appmenu->active_window = active_xid; |
821 | } |
822 | else if (event->xproperty.atom == Atoms::mwmHints || |
823 | event->xproperty.atom == Atoms::wmAllowedActions) |
824 | @@ -311,6 +305,9 @@ |
825 | |
826 | bool Manager::Impl::HandleFrameEvent(XEvent* event) |
827 | { |
828 | + if (WindowManager::Default().IsScaleActive()) |
829 | + return false; |
830 | + |
831 | auto const& win = GetWindowByFrame(event->xany.window); |
832 | |
833 | // ButtonRelease events might happen also outside the frame window, in this |
834 | |
835 | === modified file 'decorations/DecorationsMenuDropdown.cpp' |
836 | --- decorations/DecorationsMenuDropdown.cpp 2014-02-24 23:53:50 +0000 |
837 | +++ decorations/DecorationsMenuDropdown.cpp 2015-07-15 14:19:40 +0000 |
838 | @@ -33,7 +33,7 @@ |
839 | using namespace indicator; |
840 | |
841 | MenuDropdown::MenuDropdown(Indicators::Ptr const& indicators, CompWindow* win) |
842 | - : MenuEntry(std::make_shared<Entry>("LIM-dropdown"), win) |
843 | + : MenuEntry(std::make_shared<Entry>("LIM"+std::to_string(win->id())+"-dropdown"), win) |
844 | , indicators_(indicators) |
845 | { |
846 | natural_.width = ICON_SIZE; |
847 | @@ -53,7 +53,7 @@ |
848 | for (auto const& child : children_) |
849 | entries.push_back(child->GetEntry()); |
850 | |
851 | - indicators_->ShowEntriesDropdown(entries, active_, 0, geo.x(), geo.y2()); |
852 | + indicators_->ShowEntriesDropdown(entries, active_, grab_.Window()->id(), geo.x(), geo.y2()); |
853 | } |
854 | |
855 | bool MenuDropdown::ActivateChild(MenuEntry::Ptr const& child) |
856 | @@ -118,7 +118,8 @@ |
857 | |
858 | void MenuDropdown::RenderTexture() |
859 | { |
860 | - WidgetState state = active() ? WidgetState::PRELIGHT : WidgetState::NORMAL; |
861 | + WidgetState normal_state = focused() ? WidgetState::NORMAL : WidgetState::BACKDROP; |
862 | + WidgetState state = active() ? WidgetState::PRELIGHT : normal_state; |
863 | cu::CairoContext icon_ctx(GetNaturalWidth(), GetNaturalHeight(), scale()); |
864 | |
865 | if (state == WidgetState::PRELIGHT) |
866 | |
867 | === modified file 'decorations/DecorationsMenuEntry.cpp' |
868 | --- decorations/DecorationsMenuEntry.cpp 2014-03-31 18:36:33 +0000 |
869 | +++ decorations/DecorationsMenuEntry.cpp 2015-07-15 14:19:40 +0000 |
870 | @@ -37,11 +37,13 @@ |
871 | , in_dropdown(false) |
872 | , entry_(entry) |
873 | , grab_(win, true) |
874 | + , show_menu_enabled_(true) |
875 | { |
876 | entry_->updated.connect(sigc::mem_fun(this, &MenuEntry::EntryUpdated)); |
877 | horizontal_padding.changed.connect(sigc::hide(sigc::mem_fun(this, &MenuEntry::RenderTexture))); |
878 | vertical_padding.changed.connect(sigc::hide(sigc::mem_fun(this, &MenuEntry::RenderTexture))); |
879 | scale.changed.connect(sigc::hide(sigc::mem_fun(this, &MenuEntry::RenderTexture))); |
880 | + focused.changed.connect(sigc::hide(sigc::mem_fun(this, &MenuEntry::RenderTexture))); |
881 | in_dropdown.changed.connect([this] (bool in) { visible = entry_->visible() && !in; }); |
882 | EntryUpdated(); |
883 | } |
884 | @@ -63,7 +65,7 @@ |
885 | |
886 | void MenuEntry::RenderTexture() |
887 | { |
888 | - WidgetState state = WidgetState::NORMAL; |
889 | + WidgetState state = focused() ? WidgetState::NORMAL : WidgetState::BACKDROP; |
890 | |
891 | if (show_now()) |
892 | state = WidgetState::PRESSED; |
893 | @@ -120,10 +122,17 @@ |
894 | { |
895 | button_up_timer_.reset(); |
896 | grab_.ButtonDownEvent(p, button, timestamp); |
897 | + show_menu_enabled_ = (focused() || Settings::Instance().lim_unfocused_popup()); |
898 | } |
899 | |
900 | void MenuEntry::ButtonUpEvent(CompPoint const& p, unsigned button, Time timestamp) |
901 | { |
902 | + if (!show_menu_enabled_) |
903 | + { |
904 | + grab_.ButtonUpEvent(p, button, timestamp); |
905 | + return; |
906 | + } |
907 | + |
908 | if (button == 1 && !grab_.IsGrabbed()) |
909 | { |
910 | unsigned double_click_wait = Settings::Instance().lim_double_click_wait(); |
911 | @@ -143,7 +152,8 @@ |
912 | |
913 | if (button == 2 || button == 3) |
914 | { |
915 | - ShowMenu(button); |
916 | + if (Style::Get()->WindowManagerAction(WMEvent(button)) == WMAction::NONE) |
917 | + ShowMenu(button); |
918 | } |
919 | |
920 | grab_.ButtonUpEvent(p, button, timestamp); |
921 | |
922 | === modified file 'decorations/DecorationsMenuEntry.h' |
923 | --- decorations/DecorationsMenuEntry.h 2014-02-27 07:10:31 +0000 |
924 | +++ decorations/DecorationsMenuEntry.h 2015-07-15 14:19:40 +0000 |
925 | @@ -63,10 +63,11 @@ |
926 | |
927 | protected: |
928 | indicator::Entry::Ptr entry_; |
929 | + GrabEdge grab_; |
930 | |
931 | private: |
932 | + bool show_menu_enabled_; |
933 | glib::Source::UniquePtr button_up_timer_; |
934 | - GrabEdge grab_; |
935 | }; |
936 | |
937 | } // decoration namespace |
938 | |
939 | === modified file 'decorations/DecorationsMenuLayout.cpp' |
940 | --- decorations/DecorationsMenuLayout.cpp 2014-02-26 00:14:46 +0000 |
941 | +++ decorations/DecorationsMenuLayout.cpp 2015-07-15 14:19:40 +0000 |
942 | @@ -35,7 +35,9 @@ |
943 | , win_(win) |
944 | , last_pointer_(-1, -1) |
945 | , dropdown_(std::make_shared<MenuDropdown>(menu_manager_->Indicators(), win)) |
946 | -{} |
947 | +{ |
948 | + visible = false; |
949 | +} |
950 | |
951 | void MenuLayout::Setup() |
952 | { |
953 | @@ -56,7 +58,7 @@ |
954 | dropdown_->active.changed.connect(active_cb); |
955 | dropdown_->show_now.changed.connect(show_now_cb); |
956 | |
957 | - for (auto const& entry : menu_manager_->AppMenu()->GetEntries()) |
958 | + for (auto const& entry : menu_manager_->AppMenu()->GetEntriesForWindow(win_->id())) |
959 | { |
960 | auto menu = std::make_shared<MenuEntry>(entry, win_); |
961 | menu->mouse_owner.changed.connect(ownership_cb); |
962 | @@ -65,7 +67,24 @@ |
963 | menu->focused = focused(); |
964 | menu->scale = scale(); |
965 | menu->SetParent(shared_from_this()); |
966 | - items_.push_back(menu); |
967 | + |
968 | + if (items_.empty() || entry->priority() < 0) |
969 | + { |
970 | + items_.push_back(menu); |
971 | + } |
972 | + else |
973 | + { |
974 | + auto pos = items_.rbegin(); |
975 | + |
976 | + for (; pos != items_.rend(); ++pos) |
977 | + { |
978 | + auto menu = std::static_pointer_cast<MenuEntry>(*pos); |
979 | + if (entry->priority() >= menu->GetEntry()->priority()) |
980 | + break; |
981 | + } |
982 | + |
983 | + items_.insert(pos.base(), menu); |
984 | + } |
985 | } |
986 | |
987 | if (!items_.empty()) |
988 | @@ -195,12 +214,14 @@ |
989 | int accumolated_width = dropdown_width + left_padding + right_padding - inner_padding; |
990 | int max_width = max_.width; |
991 | std::list<MenuEntry::Ptr> to_hide; |
992 | + bool is_visible = visible(); |
993 | |
994 | for (auto const& item : items_) |
995 | { |
996 | if (!item->visible() || item == dropdown_) |
997 | continue; |
998 | |
999 | + is_visible = true; |
1000 | accumolated_width += item->GetNaturalWidth() + inner_padding; |
1001 | |
1002 | if (accumolated_width > max_width) |
1003 | @@ -235,6 +256,7 @@ |
1004 | dropdown_->Push(hidden); |
1005 | } |
1006 | |
1007 | + visible = is_visible; |
1008 | Layout::DoRelayout(); |
1009 | } |
1010 | |
1011 | |
1012 | === modified file 'decorations/DecorationsPriv.h' |
1013 | --- decorations/DecorationsPriv.h 2014-12-16 19:35:06 +0000 |
1014 | +++ decorations/DecorationsPriv.h 2015-07-15 14:19:40 +0000 |
1015 | @@ -111,6 +111,7 @@ |
1016 | bool ShouldBeDecorated() const; |
1017 | GLTexture* ShadowTexture() const; |
1018 | unsigned ShadowRadius() const; |
1019 | + std::string const& GetMenusPanelID() const; |
1020 | |
1021 | void ComputeShadowQuads(); |
1022 | void UpdateDecorationTextures(); |
1023 | @@ -143,6 +144,7 @@ |
1024 | connection::Wrapper dpi_changed_; |
1025 | connection::Wrapper grab_mouse_changed_; |
1026 | std::string last_title_; |
1027 | + std::string panel_id_; |
1028 | std::vector<cu::SimpleTextureQuad> bg_textures_; |
1029 | std::shared_ptr<ForceQuitDialog> force_quit_; |
1030 | InputMixer::Ptr input_mixer_; |
1031 | @@ -194,7 +196,7 @@ |
1032 | |
1033 | uweak_ptr<decoration::Window> active_deco_win_; |
1034 | uweak_ptr<InputMixer> last_mouse_owner_; |
1035 | - std::map<CompWindow*, decoration::Window::Ptr> windows_; |
1036 | + std::unordered_map<CompWindow*, decoration::Window::Ptr> windows_; |
1037 | std::unordered_map<::Window, std::weak_ptr<decoration::Window>> framed_windows_; |
1038 | |
1039 | menu::Manager::Ptr menu_manager_; |
1040 | |
1041 | === modified file 'decorations/DecorationsSlidingLayout.cpp' |
1042 | --- decorations/DecorationsSlidingLayout.cpp 2015-03-12 00:57:05 +0000 |
1043 | +++ decorations/DecorationsSlidingLayout.cpp 2015-07-15 14:19:40 +0000 |
1044 | @@ -137,7 +137,7 @@ |
1045 | auto& main_item_ = items_[ItemRole::MAIN]; |
1046 | auto& input_item_ = items_[ItemRole::INPUT]; |
1047 | |
1048 | - if (!input_item_) |
1049 | + if (!input_item_ || !input_item_->visible()) |
1050 | { |
1051 | if (main_item_) |
1052 | main_item_->Draw(ctx, transformation, attrib, clip, mask); |
1053 | |
1054 | === modified file 'decorations/DecorationsWidgets.cpp' |
1055 | --- decorations/DecorationsWidgets.cpp 2014-12-08 22:38:02 +0000 |
1056 | +++ decorations/DecorationsWidgets.cpp 2015-07-15 14:19:40 +0000 |
1057 | @@ -192,15 +192,10 @@ |
1058 | |
1059 | BasicContainer::Ptr Item::GetTopParent() const |
1060 | { |
1061 | - BasicContainer::Ptr parent = GetParent(); |
1062 | - |
1063 | - while (parent) |
1064 | - { |
1065 | - if (!parent->parent_) |
1066 | - return parent; |
1067 | - |
1068 | - parent = parent->GetParent(); |
1069 | - } |
1070 | + BasicContainer::Ptr parent = parent_; |
1071 | + |
1072 | + while (parent && parent->parent_) |
1073 | + parent = parent->parent_; |
1074 | |
1075 | return parent; |
1076 | } |
1077 | |
1078 | === modified file 'launcher/LauncherEntryRemoteModel.h' |
1079 | --- launcher/LauncherEntryRemoteModel.h 2012-05-07 19:52:54 +0000 |
1080 | +++ launcher/LauncherEntryRemoteModel.h 2015-07-15 14:19:40 +0000 |
1081 | @@ -22,7 +22,7 @@ |
1082 | |
1083 | #include <gio/gio.h> |
1084 | #include <sigc++/sigc++.h> |
1085 | -#include <map> |
1086 | +#include <unordered_map> |
1087 | |
1088 | #include "LauncherEntryRemote.h" |
1089 | |
1090 | @@ -68,7 +68,7 @@ |
1091 | glib::Object<GDBusConnection> _conn; |
1092 | unsigned int _launcher_entry_dbus_signal_id; |
1093 | unsigned int _dbus_name_owner_changed_signal_id; |
1094 | - std::map<std::string, LauncherEntryRemote::Ptr> _entries_by_uri; |
1095 | + std::unordered_map<std::string, LauncherEntryRemote::Ptr> _entries_by_uri; |
1096 | }; |
1097 | |
1098 | } // namespace |
1099 | |
1100 | === modified file 'launcher/XdndStartStopNotifierImp.h' |
1101 | --- launcher/XdndStartStopNotifierImp.h 2012-11-15 16:05:35 +0000 |
1102 | +++ launcher/XdndStartStopNotifierImp.h 2015-07-15 14:19:40 +0000 |
1103 | @@ -27,7 +27,7 @@ |
1104 | |
1105 | namespace unity { |
1106 | |
1107 | -class XdndStartStopNotifierImp : public XdndStartStopNotifier { |
1108 | +class XdndStartStopNotifierImp : public XdndStartStopNotifier, public sigc::trackable { |
1109 | public: |
1110 | XdndStartStopNotifierImp(); |
1111 | |
1112 | |
1113 | === modified file 'lockscreen/LockScreenPanel.cpp' |
1114 | --- lockscreen/LockScreenPanel.cpp 2014-12-15 19:12:07 +0000 |
1115 | +++ lockscreen/LockScreenPanel.cpp 2015-07-15 14:19:40 +0000 |
1116 | @@ -118,7 +118,7 @@ |
1117 | if (entry->active()) |
1118 | { |
1119 | active = true; |
1120 | - indicators_view_->ActivateEntry(entry->id()); |
1121 | + indicators_view_->ActivateEntry(entry); |
1122 | OnEntryActivated(GetPanelName(), entry->id(), entry->geometry()); |
1123 | break; |
1124 | } |
1125 | |
1126 | === modified file 'panel/PanelIndicatorEntryDropdownView.cpp' |
1127 | --- panel/PanelIndicatorEntryDropdownView.cpp 2014-02-25 00:28:58 +0000 |
1128 | +++ panel/PanelIndicatorEntryDropdownView.cpp 2015-07-15 14:19:40 +0000 |
1129 | @@ -98,6 +98,11 @@ |
1130 | return child; |
1131 | } |
1132 | |
1133 | +void PanelIndicatorEntryDropdownView::Clear() |
1134 | +{ |
1135 | + children_.clear(); |
1136 | +} |
1137 | + |
1138 | std::deque<PanelIndicatorEntryView::Ptr> const& PanelIndicatorEntryDropdownView::Children() const |
1139 | { |
1140 | return children_; |
1141 | @@ -144,7 +149,7 @@ |
1142 | entries.push_back(entry->GetEntry()); |
1143 | |
1144 | auto const& geo = GetAbsoluteGeometry(); |
1145 | - indicators_->ShowEntriesDropdown(entries, active_entry_, 0, geo.x, geo.y + geo.height); |
1146 | + indicators_->ShowEntriesDropdown(entries, active_entry_, entries[0]->parent_window(), geo.x, geo.y + geo.height); |
1147 | } |
1148 | |
1149 | bool PanelIndicatorEntryDropdownView::ActivateChild(PanelIndicatorEntryView::Ptr const& child) |
1150 | |
1151 | === modified file 'panel/PanelIndicatorEntryDropdownView.h' |
1152 | --- panel/PanelIndicatorEntryDropdownView.h 2014-02-07 23:29:46 +0000 |
1153 | +++ panel/PanelIndicatorEntryDropdownView.h 2015-07-15 14:19:40 +0000 |
1154 | @@ -39,6 +39,7 @@ |
1155 | void Insert(PanelIndicatorEntryView::Ptr const&); |
1156 | void Remove(PanelIndicatorEntryView::Ptr const&); |
1157 | PanelIndicatorEntryView::Ptr Pop(); |
1158 | + void Clear(); |
1159 | |
1160 | PanelIndicatorEntryView::Ptr Top() const; |
1161 | std::deque<PanelIndicatorEntryView::Ptr> const& Children() const; |
1162 | |
1163 | === modified file 'panel/PanelIndicatorEntryView.cpp' |
1164 | --- panel/PanelIndicatorEntryView.cpp 2014-12-08 19:50:13 +0000 |
1165 | +++ panel/PanelIndicatorEntryView.cpp 2015-07-15 14:19:40 +0000 |
1166 | @@ -59,6 +59,7 @@ |
1167 | , cv_(unity::Settings::Instance().em(monitor_)) |
1168 | { |
1169 | proxy_->active_changed.connect(sigc::mem_fun(this, &PanelIndicatorEntryView::OnActiveChanged)); |
1170 | + proxy_->show_now_changed.connect(sigc::mem_fun(&show_now_changed, &sigc::signal<void, bool>::emit)); |
1171 | proxy_->updated.connect(sigc::mem_fun(this, &PanelIndicatorEntryView::Refresh)); |
1172 | |
1173 | InputArea::mouse_down.connect(sigc::mem_fun(this, &PanelIndicatorEntryView::OnMouseDown)); |
1174 | @@ -84,11 +85,6 @@ |
1175 | Refresh(); |
1176 | } |
1177 | |
1178 | -PanelIndicatorEntryView::~PanelIndicatorEntryView() |
1179 | -{ |
1180 | - // Nothing to do... |
1181 | -} |
1182 | - |
1183 | void PanelIndicatorEntryView::OnActiveChanged(bool is_active) |
1184 | { |
1185 | active_changed.emit(this, is_active); |
1186 | @@ -114,10 +110,16 @@ |
1187 | }); |
1188 | |
1189 | wm.TerminateExpo(); |
1190 | + return; |
1191 | } |
1192 | |
1193 | if (wm.IsScaleActive()) |
1194 | + { |
1195 | + if (type_ == MENU) |
1196 | + return; |
1197 | + |
1198 | wm.TerminateScale(); |
1199 | + } |
1200 | |
1201 | auto const& abs_geo = GetAbsoluteGeometry(); |
1202 | proxy_->ShowMenu(abs_geo.x, abs_geo.y + abs_geo.height, button); |
1203 | |
1204 | === modified file 'panel/PanelIndicatorEntryView.h' |
1205 | --- panel/PanelIndicatorEntryView.h 2014-03-31 21:08:10 +0000 |
1206 | +++ panel/PanelIndicatorEntryView.h 2015-07-15 14:19:40 +0000 |
1207 | @@ -53,10 +53,8 @@ |
1208 | PanelIndicatorEntryView(indicator::Entry::Ptr const& proxy, int padding = 5, |
1209 | IndicatorEntryType type = INDICATOR); |
1210 | |
1211 | - virtual ~PanelIndicatorEntryView(); |
1212 | - |
1213 | IndicatorEntryType GetType() const; |
1214 | - indicator::Entry::Ptr GetEntry() const { return proxy_; } |
1215 | + indicator::Entry::Ptr const& GetEntry() const { return proxy_; } |
1216 | std::string GetEntryID() const; |
1217 | int GetEntryPriority() const; |
1218 | |
1219 | @@ -93,6 +91,7 @@ |
1220 | |
1221 | sigc::signal<void, PanelIndicatorEntryView*, bool> active_changed; |
1222 | sigc::signal<void, PanelIndicatorEntryView*> refreshed; |
1223 | + sigc::signal<void, bool> show_now_changed; |
1224 | |
1225 | protected: |
1226 | std::string GetName() const; |
1227 | |
1228 | === modified file 'panel/PanelIndicatorsView.cpp' |
1229 | --- panel/PanelIndicatorsView.cpp 2014-03-06 09:26:03 +0000 |
1230 | +++ panel/PanelIndicatorsView.cpp 2015-07-15 14:19:40 +0000 |
1231 | @@ -71,7 +71,7 @@ |
1232 | indicators_.push_back(indicator); |
1233 | |
1234 | for (auto const& entry : indicator->GetEntries()) |
1235 | - AddEntry(entry); |
1236 | + OnEntryAdded(entry); |
1237 | |
1238 | auto& conn_manager = indicators_connections_[indicator]; |
1239 | conn_manager.Add(indicator->on_entry_added.connect(sigc::mem_fun(this, &PanelIndicatorsView::OnEntryAdded))); |
1240 | @@ -83,7 +83,7 @@ |
1241 | indicators_connections_.erase(indicator); |
1242 | |
1243 | for (auto const& entry : indicator->GetEntries()) |
1244 | - RemoveEntry(entry->id()); |
1245 | + RemoveEntry(entry); |
1246 | |
1247 | for (auto i = indicators_.begin(); i != indicators_.end(); ++i) |
1248 | { |
1249 | @@ -158,13 +158,13 @@ |
1250 | } |
1251 | } |
1252 | |
1253 | -PanelIndicatorEntryView* PanelIndicatorsView::ActivateEntry(std::string const& entry_id, int button) |
1254 | +PanelIndicatorEntryView* PanelIndicatorsView::ActivateEntry(indicator::Entry::Ptr const& entry, int button) |
1255 | { |
1256 | - auto entry = entries_.find(entry_id); |
1257 | + auto it = entries_.find(entry); |
1258 | |
1259 | - if (entry != entries_.end()) |
1260 | + if (it != entries_.end()) |
1261 | { |
1262 | - PanelIndicatorEntryView* view = entry->second; |
1263 | + PanelIndicatorEntryView* view = it->second; |
1264 | |
1265 | if (view->IsSensitive() && view->IsVisible()) |
1266 | { |
1267 | @@ -181,6 +181,17 @@ |
1268 | return nullptr; |
1269 | } |
1270 | |
1271 | +PanelIndicatorEntryView* PanelIndicatorsView::ActivateEntry(std::string const& entry_id, int button) |
1272 | +{ |
1273 | + for (auto const& it : entries_) |
1274 | + { |
1275 | + if (it.first->id() == entry_id) |
1276 | + return ActivateEntry(it.first, button); |
1277 | + } |
1278 | + |
1279 | + return nullptr; |
1280 | +} |
1281 | + |
1282 | bool PanelIndicatorsView::ActivateIfSensitive() |
1283 | { |
1284 | for (auto* area : layout_->GetChildren()) |
1285 | @@ -222,7 +233,7 @@ |
1286 | if (!view->IsVisible()) |
1287 | continue; |
1288 | |
1289 | - if (!target && view->IsFocused() && |
1290 | + if (!target && |
1291 | view->IsSensitive() && |
1292 | view->GetAbsoluteGeometry().IsPointInside(x, y)) |
1293 | { |
1294 | @@ -267,9 +278,8 @@ |
1295 | if (!view) |
1296 | return; |
1297 | |
1298 | - auto const& entry_id = view->GetEntryID(); |
1299 | bool added_to_dropdown = false; |
1300 | - bool known_entry = (entries_.find(entry_id) != entries_.end()); |
1301 | + bool known_entry = (entries_.find(view->GetEntry()) != entries_.end()); |
1302 | view->SetOpacity(opacity()); |
1303 | |
1304 | if (!known_entry && dropdown_ && !dropdown_->Empty()) |
1305 | @@ -317,7 +327,7 @@ |
1306 | { |
1307 | view->SetMonitor(monitor_); |
1308 | view->refreshed.connect(sigc::mem_fun(this, &PanelIndicatorsView::OnEntryRefreshed)); |
1309 | - entries_.insert({entry_id, view}); |
1310 | + entries_.insert({view->GetEntry(), view}); |
1311 | on_indicator_updated.emit(); |
1312 | entry_added.emit(view); |
1313 | } |
1314 | @@ -346,6 +356,23 @@ |
1315 | on_indicator_updated.emit(); |
1316 | } |
1317 | |
1318 | +void PanelIndicatorsView::ClearEntries() |
1319 | +{ |
1320 | + for (auto it = entries_.begin(); it != entries_.end();) |
1321 | + { |
1322 | + auto* entry = it->second; |
1323 | + ++it; |
1324 | + |
1325 | + if (entry != dropdown_.GetPointer()) |
1326 | + RemoveEntryView(entry); |
1327 | + } |
1328 | + |
1329 | + on_indicator_updated.emit(); |
1330 | + |
1331 | + QueueRelayout(); |
1332 | + QueueDraw(); |
1333 | +} |
1334 | + |
1335 | void PanelIndicatorsView::RemoveEntryView(PanelIndicatorEntryView* view) |
1336 | { |
1337 | if (!view) |
1338 | @@ -357,7 +384,7 @@ |
1339 | dropdown_->Remove(PanelIndicatorEntryView::Ptr(view)); |
1340 | |
1341 | RemoveChild(view); |
1342 | - entries_.erase(view->GetEntryID()); |
1343 | + entries_.erase(view->GetEntry()); |
1344 | layout_->RemoveChildObject(view); |
1345 | on_indicator_updated.emit(); |
1346 | |
1347 | @@ -365,9 +392,12 @@ |
1348 | QueueDraw(); |
1349 | } |
1350 | |
1351 | -void PanelIndicatorsView::RemoveEntry(std::string const& entry_id) |
1352 | +void PanelIndicatorsView::RemoveEntry(indicator::Entry::Ptr const& entry) |
1353 | { |
1354 | - RemoveEntryView(entries_[entry_id]); |
1355 | + auto it = entries_.find(entry); |
1356 | + |
1357 | + if (it != entries_.end()) |
1358 | + RemoveEntryView(it->second); |
1359 | } |
1360 | |
1361 | void PanelIndicatorsView::OverlayShown() |
1362 | |
1363 | === modified file 'panel/PanelIndicatorsView.h' |
1364 | --- panel/PanelIndicatorsView.h 2014-03-06 09:26:03 +0000 |
1365 | +++ panel/PanelIndicatorsView.h 2015-07-15 14:19:40 +0000 |
1366 | @@ -55,9 +55,10 @@ |
1367 | int padding = 5, |
1368 | IndicatorEntryPosition pos = AUTO, |
1369 | IndicatorEntryType type = IndicatorEntryType::INDICATOR); |
1370 | - void RemoveEntry(std::string const& entry_id); |
1371 | + void RemoveEntry(indicator::Entry::Ptr const&); |
1372 | |
1373 | PanelIndicatorEntryView* ActivateEntryAt(int x, int y, int button = 1); |
1374 | + PanelIndicatorEntryView* ActivateEntry(indicator::Entry::Ptr const&, int button = 1); |
1375 | PanelIndicatorEntryView* ActivateEntry(std::string const& entry_id, int button = 1); |
1376 | bool ActivateIfSensitive(); |
1377 | |
1378 | @@ -84,18 +85,19 @@ |
1379 | typedef std::vector<indicator::Indicator::Ptr> Indicators; |
1380 | Indicators const& GetIndicators() const; |
1381 | |
1382 | + void ClearEntries(); |
1383 | + |
1384 | virtual void Draw(nux::GraphicsEngine& GfxContext, bool force_draw); |
1385 | virtual void DrawContent(nux::GraphicsEngine& GfxContext, bool force_draw); |
1386 | |
1387 | - virtual void OnEntryAdded(indicator::Entry::Ptr const& entry); |
1388 | + virtual void OnEntryAdded(indicator::Entry::Ptr const&); |
1389 | virtual void OnEntryRefreshed(PanelIndicatorEntryView* view); |
1390 | |
1391 | void AddEntryView(PanelIndicatorEntryView* view, IndicatorEntryPosition pos = AUTO); |
1392 | void RemoveEntryView(PanelIndicatorEntryView* view); |
1393 | |
1394 | nux::HLayout* layout_; |
1395 | - typedef std::map<std::string, PanelIndicatorEntryView*> Entries; |
1396 | - Entries entries_; |
1397 | + std::unordered_map<indicator::Entry::Ptr, PanelIndicatorEntryView*> entries_; |
1398 | |
1399 | int monitor_; |
1400 | bool overlay_showing_; |
1401 | |
1402 | === modified file 'panel/PanelMenuView.cpp' |
1403 | --- panel/PanelMenuView.cpp 2015-03-12 00:57:05 +0000 |
1404 | +++ panel/PanelMenuView.cpp 2015-07-15 14:19:40 +0000 |
1405 | @@ -27,6 +27,7 @@ |
1406 | #include "unity-shared/CairoTexture.h" |
1407 | #include "unity-shared/DecorationStyle.h" |
1408 | #include "unity-shared/PanelStyle.h" |
1409 | +#include "unity-shared/RawPixel.h" |
1410 | #include "unity-shared/UnitySettings.h" |
1411 | #include "unity-shared/UBusMessages.h" |
1412 | #include "unity-shared/UScreen.h" |
1413 | @@ -43,15 +44,14 @@ |
1414 | |
1415 | namespace |
1416 | { |
1417 | - const int MAIN_LEFT_PADDING = 4; |
1418 | - const int TITLE_PADDING = 2; |
1419 | - const int MENUBAR_PADDING = 4; |
1420 | + const RawPixel MAIN_LEFT_PADDING = 4_em; |
1421 | + const RawPixel TITLE_PADDING = 2_em; |
1422 | + const RawPixel MENUBAR_PADDING = 4_em; |
1423 | const int MENU_ENTRIES_PADDING = 6; |
1424 | |
1425 | const std::string NEW_APP_HIDE_TIMEOUT = "new-app-hide-timeout"; |
1426 | const std::string NEW_APP_SHOW_TIMEOUT = "new-app-show-timeout"; |
1427 | const std::string WINDOW_MOVED_TIMEOUT = "window-moved-timeout"; |
1428 | - const std::string WINDOW_ACTIVATED_TIMEOUT = "window-activated-timeout"; |
1429 | const std::string UPDATE_SHOW_NOW_TIMEOUT = "update-show-now-timeout"; |
1430 | const std::string INTEGRATED_MENUS_DOUBLE_CLICK_TIMEOUT = "integrated-menus-double-click-timeout"; |
1431 | |
1432 | @@ -83,7 +83,10 @@ |
1433 | } |
1434 | |
1435 | PanelMenuView::PanelMenuView(menu::Manager::Ptr const& menus) |
1436 | - : menu_manager_(menus) |
1437 | + : active_window(0) |
1438 | + , maximized_window(0) |
1439 | + , focused(true) |
1440 | + , menu_manager_(menus) |
1441 | , matcher_(bamf_matcher_get_default()) |
1442 | , is_inside_(false) |
1443 | , is_grabbed_(false) |
1444 | @@ -100,16 +103,15 @@ |
1445 | , ignore_menu_visibility_(false) |
1446 | , integrated_menus_(menu_manager_->integrated_menus()) |
1447 | , always_show_menus_(menu_manager_->always_show_menus()) |
1448 | - , active_xid_(0) |
1449 | , desktop_name_(get_current_desktop()) |
1450 | { |
1451 | BamfWindow* active_win = bamf_matcher_get_active_window(matcher_); |
1452 | if (BAMF_IS_WINDOW(active_win)) |
1453 | - active_xid_ = bamf_window_get_xid(active_win); |
1454 | + active_window = bamf_window_get_xid(active_win); |
1455 | |
1456 | - SetupPanelMenuViewSignals(); |
1457 | SetupWindowButtons(); |
1458 | SetupTitlebarGrabArea(); |
1459 | + SetupPanelMenuViewSignals(); |
1460 | SetupWindowManagerSignals(); |
1461 | SetupUBusManagerInterests(); |
1462 | |
1463 | @@ -128,8 +130,10 @@ |
1464 | void PanelMenuView::OnStyleChanged() |
1465 | { |
1466 | int height = panel::Style::Instance().PanelHeight(monitor_); |
1467 | + double scale = Settings::Instance().em(monitor_)->DPIScale(); |
1468 | window_buttons_->SetMinimumHeight(height); |
1469 | window_buttons_->SetMaximumHeight(height); |
1470 | + window_buttons_->SetLeftAndRightPadding(MAIN_LEFT_PADDING.CP(scale), MENUBAR_PADDING.CP(scale)); |
1471 | window_buttons_->UpdateDPIChanged(); |
1472 | |
1473 | layout_->SetLeftAndRightPadding(window_buttons_->GetContentWidth(), 0); |
1474 | @@ -157,6 +161,20 @@ |
1475 | |
1476 | menu_manager_->integrated_menus.changed.connect(sigc::mem_fun(this, &PanelMenuView::OnLIMChanged)); |
1477 | menu_manager_->always_show_menus.changed.connect(sigc::mem_fun(this, &PanelMenuView::OnAlwaysShowMenusChanged)); |
1478 | + |
1479 | + auto update_target_cb = sigc::hide(sigc::mem_fun(this, &PanelMenuView::UpdateTargetWindowItems)); |
1480 | + maximized_window.changed.connect(update_target_cb); |
1481 | + active_window.changed.connect(update_target_cb); |
1482 | + |
1483 | + focused.changed.connect([this] (bool focused) { |
1484 | + Refresh(true); |
1485 | + window_buttons_->focused = focused; |
1486 | + |
1487 | + for (auto const& entry : entries_) |
1488 | + entry.second->SetFocusedState(focused); |
1489 | + |
1490 | + FullRedraw(); |
1491 | + }); |
1492 | } |
1493 | |
1494 | void PanelMenuView::SetupWindowButtons() |
1495 | @@ -164,7 +182,7 @@ |
1496 | window_buttons_ = new WindowButtons(); |
1497 | window_buttons_->SetParentObject(this); |
1498 | window_buttons_->monitor = monitor_; |
1499 | - window_buttons_->controlled_window = active_xid_; |
1500 | + window_buttons_->controlled_window = active_window(); |
1501 | window_buttons_->opacity = 0.0f; |
1502 | window_buttons_->SetLeftAndRightPadding(MAIN_LEFT_PADDING, MENUBAR_PADDING); |
1503 | window_buttons_->SetMaximumHeight(panel::Style::Instance().PanelHeight(monitor_)); |
1504 | @@ -252,6 +270,27 @@ |
1505 | PanelIndicatorsView::AddIndicator(indicator); |
1506 | } |
1507 | |
1508 | +void PanelMenuView::UpdateTargetWindowItems() |
1509 | +{ |
1510 | + Window old_target = window_buttons_->controlled_window; |
1511 | + Window target_window = integrated_menus_ ? maximized_window() : active_window(); |
1512 | + |
1513 | + if (old_target != target_window) |
1514 | + { |
1515 | + window_buttons_->controlled_window = target_window; |
1516 | + ClearEntries(); |
1517 | + |
1518 | + if (indicator::AppmenuIndicator::Ptr appmenu = menu_manager_->AppMenu()) |
1519 | + { |
1520 | + for (auto const& entry : appmenu->GetEntriesForWindow(target_window)) |
1521 | + OnEntryAdded(entry); |
1522 | + } |
1523 | + } |
1524 | + |
1525 | + if (integrated_menus_) |
1526 | + focused = (target_window == active_window()); |
1527 | +} |
1528 | + |
1529 | void PanelMenuView::FullRedraw() |
1530 | { |
1531 | QueueDraw(); |
1532 | @@ -266,9 +305,11 @@ |
1533 | if (!integrated_menus_) |
1534 | { |
1535 | CheckMouseInside(); |
1536 | - window_buttons_->focused = true; |
1537 | + focused = true; |
1538 | } |
1539 | |
1540 | + UpdateTargetWindowItems(); |
1541 | + |
1542 | Refresh(true); |
1543 | FullRedraw(); |
1544 | } |
1545 | @@ -302,7 +343,7 @@ |
1546 | return titlebar_grab_area_.GetPointer(); |
1547 | } |
1548 | |
1549 | - if (is_maximized_ || spread_showing_ || (integrated_menus_ && GetMaximizedWindow() != 0)) |
1550 | + if (is_maximized_ || spread_showing_ || (integrated_menus_ && maximized_window() != 0)) |
1551 | { |
1552 | found_area = window_buttons_->FindAreaUnderMouse(mouse_position, event_type); |
1553 | NUX_RETURN_VALUE_IF_NOTNULL(found_area, found_area); |
1554 | @@ -313,7 +354,7 @@ |
1555 | found_area = titlebar_grab_area_->FindAreaUnderMouse(mouse_position, event_type); |
1556 | NUX_RETURN_VALUE_IF_NOTNULL(found_area, found_area); |
1557 | |
1558 | - if (integrated_menus_ && GetMaximizedWindow() != 0) |
1559 | + if (integrated_menus_ && maximized_window() != 0) |
1560 | { |
1561 | /* When the integrated menus are enabled, that area must act both like an |
1562 | * indicator-entry view and like a panel-grab-area, so not to re-implement |
1563 | @@ -382,10 +423,7 @@ |
1564 | |
1565 | bool PanelMenuView::ShouldDrawMenus() const |
1566 | { |
1567 | - if (integrated_menus_ && !is_maximized_) |
1568 | - return false; |
1569 | - |
1570 | - if (we_control_active_ && !switcher_showing_ && !launcher_keynav_ && !ignore_menu_visibility_ && !entries_.empty()) |
1571 | + if ((we_control_active_ || integrated_menus_) && !switcher_showing_ && !launcher_keynav_ && !ignore_menu_visibility_ && HasVisibleMenus()) |
1572 | { |
1573 | WindowManager& wm = WindowManager::Default(); |
1574 | |
1575 | @@ -410,7 +448,7 @@ |
1576 | if (integrated_menus_) |
1577 | { |
1578 | if (!WindowManager::Default().IsExpoActive()) |
1579 | - return (GetMaximizedWindow() != 0); |
1580 | + return (maximized_window() != 0); |
1581 | |
1582 | return false; |
1583 | } |
1584 | @@ -796,7 +834,7 @@ |
1585 | |
1586 | std::string PanelMenuView::GetMaximizedViewName(bool use_appname) const |
1587 | { |
1588 | - Window maximized = GetMaximizedWindow(); |
1589 | + Window maximized = maximized_window(); |
1590 | BamfWindow* window = nullptr; |
1591 | std::string label; |
1592 | |
1593 | @@ -830,18 +868,18 @@ |
1594 | auto const& style = decoration::Style::Get(); |
1595 | auto text_size = style->TitleNaturalSize(label); |
1596 | auto state = WidgetState::NORMAL; |
1597 | - float dpi_scale = Settings::Instance().em(monitor_)->DPIScale(); |
1598 | + double dpi_scale = Settings::Instance().em(monitor_)->DPIScale(); |
1599 | |
1600 | if (integrated_menus_ && !is_desktop_focused_ && !WindowManager::Default().IsExpoActive()) |
1601 | { |
1602 | title_geo_.x = geo.x + window_buttons_->GetBaseWidth() + (style->TitleIndent() * dpi_scale); |
1603 | |
1604 | - if (!window_buttons_->focused()) |
1605 | + if (!focused()) |
1606 | state = WidgetState::BACKDROP; |
1607 | } |
1608 | else |
1609 | { |
1610 | - title_geo_.x = geo.x + (MAIN_LEFT_PADDING + TITLE_PADDING) * dpi_scale; |
1611 | + title_geo_.x = geo.x + MAIN_LEFT_PADDING.CP(dpi_scale) + TITLE_PADDING.CP(dpi_scale); |
1612 | } |
1613 | |
1614 | title_geo_.y = geo.y + (geo.height - (text_size.height * dpi_scale)) / 2; |
1615 | @@ -904,20 +942,9 @@ |
1616 | if (geo.width > monitor_geo_.width) |
1617 | return false; |
1618 | |
1619 | - if (integrated_menus_) |
1620 | - { |
1621 | - Window maximized = GetMaximizedWindow(); |
1622 | - window_buttons_->controlled_window = maximized; |
1623 | - window_buttons_->focused = (active_xid_ == maximized); |
1624 | - } |
1625 | - else |
1626 | - { |
1627 | - window_buttons_->controlled_window = active_xid_; |
1628 | - } |
1629 | - |
1630 | std::string const& new_title = GetCurrentTitle(); |
1631 | |
1632 | - if (new_title == panel_title_ && !force && last_geo_ == geo && title_texture_) |
1633 | + if (!force && new_title == panel_title_ && last_geo_ == geo && title_texture_) |
1634 | { |
1635 | // No need to redraw the title, let's save some CPU time! |
1636 | return false; |
1637 | @@ -956,18 +983,20 @@ |
1638 | |
1639 | void PanelMenuView::OnEntryAdded(indicator::Entry::Ptr const& entry) |
1640 | { |
1641 | - PanelIndicatorEntryView* view; |
1642 | + auto parent_window = entry->parent_window(); |
1643 | + Window target = integrated_menus_ ? maximized_window() : active_window(); |
1644 | |
1645 | - view = new PanelIndicatorEntryView(entry, MENU_ENTRIES_PADDING, IndicatorEntryType::MENU); |
1646 | - entry->show_now_changed.connect(sigc::mem_fun(this, &PanelMenuView::UpdateShowNow)); |
1647 | - AddEntryView(view); |
1648 | + if (!parent_window || parent_window == target) |
1649 | + AddEntryView(new PanelIndicatorEntryView(entry, MENU_ENTRIES_PADDING, IndicatorEntryType::MENU)); |
1650 | } |
1651 | |
1652 | void PanelMenuView::OnEntryViewAdded(PanelIndicatorEntryView* view) |
1653 | { |
1654 | + view->SetFocusedState(focused()); |
1655 | view->mouse_enter.connect(sigc::mem_fun(this, &PanelMenuView::OnPanelViewMouseEnter)); |
1656 | view->mouse_leave.connect(sigc::mem_fun(this, &PanelMenuView::OnPanelViewMouseLeave)); |
1657 | view->active_changed.connect(sigc::mem_fun(this, &PanelMenuView::OnActiveChanged)); |
1658 | + view->show_now_changed.connect(sigc::mem_fun(this, &PanelMenuView::UpdateShowNow)); |
1659 | } |
1660 | |
1661 | void PanelMenuView::NotifyAllMenusClosed() |
1662 | @@ -1116,58 +1145,41 @@ |
1663 | show_now_activated_ = false; |
1664 | is_maximized_ = false; |
1665 | is_desktop_focused_ = false; |
1666 | - active_xid_ = 0; |
1667 | - bool force_refresh = false; |
1668 | + Window active_xid = 0; |
1669 | |
1670 | sources_.Remove(WINDOW_MOVED_TIMEOUT); |
1671 | |
1672 | if (BAMF_IS_WINDOW(new_view)) |
1673 | { |
1674 | BamfWindow* window = reinterpret_cast<BamfWindow*>(new_view); |
1675 | - active_xid_ = bamf_window_get_xid(window); |
1676 | + active_xid = bamf_window_get_xid(window); |
1677 | is_maximized_ = (bamf_window_maximized(window) == BAMF_WINDOW_MAXIMIZED); |
1678 | |
1679 | if (bamf_window_get_window_type(window) == BAMF_WINDOW_DESKTOP) |
1680 | { |
1681 | - is_desktop_focused_ = !GetMaximizedWindow(); |
1682 | + is_desktop_focused_ = !maximized_window(); |
1683 | we_control_active_ = true; |
1684 | } |
1685 | else |
1686 | { |
1687 | - we_control_active_ = IsWindowUnderOurControl(active_xid_); |
1688 | + we_control_active_ = IsWindowUnderOurControl(active_xid); |
1689 | } |
1690 | |
1691 | if (is_maximized_) |
1692 | { |
1693 | - maximized_wins_.erase(std::remove(maximized_wins_.begin(), maximized_wins_.end(), active_xid_), maximized_wins_.end()); |
1694 | - maximized_wins_.push_front(active_xid_); |
1695 | + maximized_wins_.erase(std::remove(maximized_wins_.begin(), maximized_wins_.end(), active_xid), maximized_wins_.end()); |
1696 | + maximized_wins_.push_front(active_xid); |
1697 | + UpdateMaximizedWindow(); |
1698 | } |
1699 | |
1700 | // register callback for new view |
1701 | view_name_changed_signal_.Connect(new_view, "name-changed", |
1702 | sigc::mem_fun(this, &PanelMenuView::OnNameChanged)); |
1703 | - |
1704 | - if (integrated_menus_) |
1705 | - force_refresh = is_maximized_; |
1706 | - } |
1707 | - |
1708 | - if (!force_refresh && BAMF_IS_WINDOW(old_view) && integrated_menus_) |
1709 | - force_refresh = (bamf_window_maximized(reinterpret_cast<BamfWindow*>(old_view)) == BAMF_WINDOW_MAXIMIZED); |
1710 | - |
1711 | - if (ShouldDrawMenus()) |
1712 | - { |
1713 | - // Wait 100ms before showing the menus again if we've just switched view |
1714 | - // this is done because the menus are updated by the indicator with some |
1715 | - // delay, and we don't want to see the previous menus and then the new ones |
1716 | - ignore_menu_visibility_ = true; |
1717 | - sources_.AddTimeout(100, [this] { |
1718 | - ignore_menu_visibility_ = false; |
1719 | - QueueDraw(); |
1720 | - return false; |
1721 | - }, WINDOW_ACTIVATED_TIMEOUT); |
1722 | - } |
1723 | - |
1724 | - if (Refresh(force_refresh)) |
1725 | + } |
1726 | + |
1727 | + active_window = active_xid; |
1728 | + |
1729 | + if (Refresh()) |
1730 | FullRedraw(); |
1731 | } |
1732 | |
1733 | @@ -1198,8 +1210,9 @@ |
1734 | void PanelMenuView::OnWindowMinimized(Window xid) |
1735 | { |
1736 | maximized_wins_.erase(std::remove(maximized_wins_.begin(), maximized_wins_.end(), xid), maximized_wins_.end()); |
1737 | + UpdateMaximizedWindow(); |
1738 | |
1739 | - if (xid == active_xid_) |
1740 | + if (xid == active_window()) |
1741 | { |
1742 | if (Refresh()) |
1743 | QueueDraw(); |
1744 | @@ -1213,10 +1226,13 @@ |
1745 | |
1746 | void PanelMenuView::OnWindowUnminimized(Window xid) |
1747 | { |
1748 | - if (xid == active_xid_) |
1749 | + if (xid == active_window()) |
1750 | { |
1751 | if (WindowManager::Default().IsWindowMaximized(xid)) |
1752 | + { |
1753 | maximized_wins_.push_front(xid); |
1754 | + UpdateMaximizedWindow(); |
1755 | + } |
1756 | |
1757 | if (Refresh()) |
1758 | QueueDraw(); |
1759 | @@ -1224,7 +1240,10 @@ |
1760 | else |
1761 | { |
1762 | if (WindowManager::Default().IsWindowMaximized(xid)) |
1763 | + { |
1764 | maximized_wins_.push_back(xid); |
1765 | + UpdateMaximizedWindow(); |
1766 | + } |
1767 | |
1768 | if (integrated_menus_ && IsWindowUnderOurControl(xid)) |
1769 | { |
1770 | @@ -1239,8 +1258,9 @@ |
1771 | // FIXME: compiz doesn't give us a valid xid (is always 0 on unmap) |
1772 | // we need to do this again on BamfView closed signal. |
1773 | maximized_wins_.erase(std::remove(maximized_wins_.begin(), maximized_wins_.end(), xid), maximized_wins_.end()); |
1774 | + UpdateMaximizedWindow(); |
1775 | |
1776 | - if (xid == active_xid_) |
1777 | + if (xid == active_window()) |
1778 | { |
1779 | if (Refresh()) |
1780 | QueueDraw(); |
1781 | @@ -1256,9 +1276,10 @@ |
1782 | { |
1783 | if (WindowManager::Default().IsWindowMaximized(xid)) |
1784 | { |
1785 | - if (xid == active_xid_) |
1786 | + if (xid == active_window()) |
1787 | { |
1788 | maximized_wins_.push_front(xid); |
1789 | + UpdateMaximizedWindow(); |
1790 | |
1791 | if (Refresh()) |
1792 | QueueDraw(); |
1793 | @@ -1266,15 +1287,17 @@ |
1794 | else |
1795 | { |
1796 | maximized_wins_.push_back(xid); |
1797 | + UpdateMaximizedWindow(); |
1798 | } |
1799 | } |
1800 | } |
1801 | |
1802 | void PanelMenuView::OnWindowMaximized(Window xid) |
1803 | { |
1804 | - if (xid == active_xid_) |
1805 | + if (xid == active_window()) |
1806 | { |
1807 | maximized_wins_.push_front(xid); |
1808 | + UpdateMaximizedWindow(); |
1809 | |
1810 | // We need to update the is_inside_ state in the case of maximization by grab |
1811 | CheckMouseInside(); |
1812 | @@ -1286,6 +1309,7 @@ |
1813 | else |
1814 | { |
1815 | maximized_wins_.push_back(xid); |
1816 | + UpdateMaximizedWindow(); |
1817 | |
1818 | if (integrated_menus_ && IsWindowUnderOurControl(xid)) |
1819 | { |
1820 | @@ -1298,8 +1322,9 @@ |
1821 | void PanelMenuView::OnWindowRestored(Window xid) |
1822 | { |
1823 | maximized_wins_.erase(std::remove(maximized_wins_.begin(), maximized_wins_.end(), xid), maximized_wins_.end()); |
1824 | + UpdateMaximizedWindow(); |
1825 | |
1826 | - if (active_xid_ == xid) |
1827 | + if (active_window() == xid) |
1828 | { |
1829 | is_maximized_ = false; |
1830 | is_grabbed_ = false; |
1831 | @@ -1316,13 +1341,13 @@ |
1832 | |
1833 | bool PanelMenuView::UpdateActiveWindowPosition() |
1834 | { |
1835 | - bool we_control_window = IsWindowUnderOurControl(active_xid_); |
1836 | + bool we_control_window = IsWindowUnderOurControl(active_window); |
1837 | |
1838 | if (we_control_window != we_control_active_) |
1839 | { |
1840 | we_control_active_ = we_control_window; |
1841 | |
1842 | - if (!entries_.empty()) |
1843 | + if (HasVisibleMenus()) |
1844 | on_indicator_updated.emit(); |
1845 | |
1846 | if (Refresh()) |
1847 | @@ -1334,21 +1359,17 @@ |
1848 | |
1849 | void PanelMenuView::OnWindowMoved(Window xid) |
1850 | { |
1851 | - if (active_xid_ == xid) |
1852 | + if (!integrated_menus_ && active_window() == xid && UScreen::GetDefault()->GetMonitors().size() > 1) |
1853 | { |
1854 | /* When moving the active window, if the current panel is controlling |
1855 | * the active window, then we postpone the timeout function every movement |
1856 | * that we have, setting a longer timeout. |
1857 | - * Otherwise, if the moved window is not controlled by the current panel |
1858 | + * Otherwise, if the movedPanelMenuView::OnWindowMovedPanelMenuView::OnWindowMoved window is not controlled by the current panel |
1859 | * every few millisecond we check the new window position */ |
1860 | |
1861 | unsigned int timeout_length = 250; |
1862 | |
1863 | - if (we_control_active_) |
1864 | - { |
1865 | - sources_.Remove(WINDOW_MOVED_TIMEOUT); |
1866 | - } |
1867 | - else |
1868 | + if (!we_control_active_) |
1869 | { |
1870 | if (sources_.GetSource(WINDOW_MOVED_TIMEOUT)) |
1871 | return; |
1872 | @@ -1359,6 +1380,9 @@ |
1873 | auto cb_func = sigc::mem_fun(this, &PanelMenuView::UpdateActiveWindowPosition); |
1874 | sources_.AddTimeout(timeout_length, cb_func, WINDOW_MOVED_TIMEOUT); |
1875 | } |
1876 | + |
1877 | + if (std::find(maximized_wins_.begin(), maximized_wins_.end(), xid) != maximized_wins_.end()) |
1878 | + UpdateMaximizedWindow(); |
1879 | } |
1880 | |
1881 | bool PanelMenuView::IsWindowUnderOurControl(Window xid) const |
1882 | @@ -1391,7 +1415,7 @@ |
1883 | return false; |
1884 | } |
1885 | |
1886 | -Window PanelMenuView::GetMaximizedWindow() const |
1887 | +void PanelMenuView::UpdateMaximizedWindow() |
1888 | { |
1889 | Window window_xid = 0; |
1890 | |
1891 | @@ -1406,7 +1430,7 @@ |
1892 | } |
1893 | } |
1894 | |
1895 | - return window_xid; |
1896 | + maximized_window = window_xid; |
1897 | } |
1898 | |
1899 | Window PanelMenuView::GetTopWindow() const |
1900 | @@ -1466,11 +1490,14 @@ |
1901 | if (!layout_->GetAbsoluteGeometry().IsInside(click)) |
1902 | return; |
1903 | |
1904 | - unsigned double_click_wait = Settings::Instance().lim_double_click_wait(); |
1905 | - |
1906 | - if (double_click_wait > 0) |
1907 | + auto& settings = Settings::Instance(); |
1908 | + |
1909 | + if (!focused && !settings.lim_unfocused_popup()) |
1910 | + return; |
1911 | + |
1912 | + if (settings.lim_double_click_wait() > 0) |
1913 | { |
1914 | - sources_.AddTimeout(double_click_wait, [this, click] { |
1915 | + sources_.AddTimeout(settings.lim_double_click_wait(), [this, click] { |
1916 | ActivateEntryAt(click.x, click.y); |
1917 | return false; |
1918 | }, INTEGRATED_MENUS_DOUBLE_CLICK_TIMEOUT); |
1919 | @@ -1489,15 +1516,18 @@ |
1920 | |
1921 | void PanelMenuView::OnMaximizedActivate(int x, int y) |
1922 | { |
1923 | - Window maximized = GetMaximizedWindow(); |
1924 | + Window maximized = maximized_window(); |
1925 | |
1926 | if (maximized != 0) |
1927 | { |
1928 | - if (maximized != active_xid_) |
1929 | + if (maximized != active_window()) |
1930 | { |
1931 | - WindowManager::Default().Activate(maximized); |
1932 | + auto& wm = WindowManager::Default(); |
1933 | + wm.Raise(maximized); |
1934 | + wm.Activate(maximized); |
1935 | } |
1936 | - else if (integrated_menus_) |
1937 | + |
1938 | + if (integrated_menus_) |
1939 | { |
1940 | // Adjusting the click coordinates to be absolute. |
1941 | auto const& grab_geo = titlebar_grab_area_->GetAbsoluteGeometry(); |
1942 | @@ -1509,7 +1539,7 @@ |
1943 | |
1944 | void PanelMenuView::MaximizedWindowWMAction(int x, int y, unsigned button) |
1945 | { |
1946 | - Window maximized = GetMaximizedWindow(); |
1947 | + Window maximized = maximized_window(); |
1948 | |
1949 | if (!maximized) |
1950 | return; |
1951 | @@ -1590,7 +1620,7 @@ |
1952 | * This is a workaround to avoid that the grid plugin would be fired |
1953 | * showing the window shape preview effect. See bug #838923 */ |
1954 | |
1955 | - Window maximized = GetMaximizedWindow(); |
1956 | + Window maximized = maximized_window(); |
1957 | |
1958 | if (maximized != 0) |
1959 | { |
1960 | @@ -1611,7 +1641,7 @@ |
1961 | x += titlebar_grab_area_->GetAbsoluteX(); |
1962 | y += titlebar_grab_area_->GetAbsoluteY(); |
1963 | |
1964 | - Window maximized = GetMaximizedWindow(); |
1965 | + Window maximized = maximized_window(); |
1966 | |
1967 | /* When the drag goes out from the Panel, start the real movement. |
1968 | * |
1969 | @@ -1686,6 +1716,8 @@ |
1970 | PanelIndicatorsView::AddProperties(introspection); |
1971 | |
1972 | introspection |
1973 | + .add("focused", focused()) |
1974 | + .add("integrated_menus", integrated_menus_) |
1975 | .add("mouse_inside", is_inside_) |
1976 | .add("always_show_menus", always_show_menus_) |
1977 | .add("grabbed", is_grabbed_) |
1978 | @@ -1694,7 +1726,8 @@ |
1979 | .add("panel_title", panel_title_) |
1980 | .add("desktop_active", (panel_title_ == desktop_name_)) |
1981 | .add("monitor", monitor_) |
1982 | - .add("active_window", active_xid_) |
1983 | + .add("active_window", active_window()) |
1984 | + .add("maximized_window", maximized_window()) |
1985 | .add("draw_menus", ShouldDrawMenus()) |
1986 | .add("draw_window_buttons", ShouldDrawButtons()) |
1987 | .add("controls_active_window", we_control_active_) |
1988 | @@ -1833,32 +1866,19 @@ |
1989 | auto xid = bamf_window_get_xid(window); |
1990 | |
1991 | if (bamf_view_is_active(view)) |
1992 | - active_xid_ = xid; |
1993 | + active_window = xid; |
1994 | |
1995 | if (bamf_window_maximized(window) == BAMF_WINDOW_MAXIMIZED) |
1996 | { |
1997 | - if (xid == active_xid_) |
1998 | + if (xid == active_window()) |
1999 | maximized_wins_.push_front(xid); |
2000 | else |
2001 | maximized_wins_.push_back(xid); |
2002 | } |
2003 | } |
2004 | |
2005 | - Window maximized = GetMaximizedWindow(); |
2006 | - Window buttons_win = 0; |
2007 | - |
2008 | - if (integrated_menus_) |
2009 | - { |
2010 | - buttons_win = maximized; |
2011 | - window_buttons_->focused = (maximized == active_xid_); |
2012 | - } |
2013 | - else |
2014 | - { |
2015 | - buttons_win = (maximized == active_xid_) ? maximized : 0; |
2016 | - } |
2017 | - |
2018 | window_buttons_->monitor = monitor_; |
2019 | - window_buttons_->controlled_window = buttons_win; |
2020 | + UpdateMaximizedWindow(); |
2021 | |
2022 | OnStyleChanged(); |
2023 | g_list_free(windows); |
2024 | @@ -1866,7 +1886,15 @@ |
2025 | |
2026 | bool PanelMenuView::HasMenus() const |
2027 | { |
2028 | - if (entries_.empty()) |
2029 | + if (!HasVisibleMenus()) |
2030 | + return false; |
2031 | + |
2032 | + return integrated_menus_ || we_control_active_; |
2033 | +} |
2034 | + |
2035 | +bool PanelMenuView::HasKeyActivableMenus() const |
2036 | +{ |
2037 | + if (!HasVisibleMenus()) |
2038 | return false; |
2039 | |
2040 | return integrated_menus_ ? is_maximized_ : we_control_active_; |
2041 | |
2042 | === modified file 'panel/PanelMenuView.h' |
2043 | --- panel/PanelMenuView.h 2015-03-12 00:57:05 +0000 |
2044 | +++ panel/PanelMenuView.h 2015-07-15 14:19:40 +0000 |
2045 | @@ -44,13 +44,17 @@ |
2046 | PanelMenuView(menu::Manager::Ptr const&); |
2047 | ~PanelMenuView(); |
2048 | |
2049 | + nux::Property<Window> active_window; |
2050 | + nux::Property<Window> maximized_window; |
2051 | + nux::Property<bool> focused; |
2052 | + |
2053 | void SetMousePosition(int x, int y); |
2054 | void SetMonitor(int monitor) override; |
2055 | |
2056 | Window GetTopWindow() const; |
2057 | - Window GetMaximizedWindow() const; |
2058 | bool GetControlsActive() const; |
2059 | bool HasMenus() const; |
2060 | + bool HasKeyActivableMenus() const; |
2061 | |
2062 | void NotifyAllMenusClosed(); |
2063 | |
2064 | @@ -120,9 +124,9 @@ |
2065 | bool Refresh(bool force = false); |
2066 | |
2067 | void UpdateTitleTexture(nux::Geometry const&, std::string const& label); |
2068 | - |
2069 | void UpdateLastGeometry(nux::Geometry const& geo); |
2070 | void UpdateTitleGradientTexture(); |
2071 | + void UpdateMaximizedWindow(); |
2072 | |
2073 | void OnPanelViewMouseEnter(int x, int y, unsigned long mouse_button_state, unsigned long special_keys_state); |
2074 | void OnPanelViewMouseLeave(int x, int y, unsigned long mouse_button_state, unsigned long special_keys_state); |
2075 | @@ -134,6 +138,7 @@ |
2076 | void OnLauncherKeyNavEnded(GVariant* data); |
2077 | void OnLauncherSelectionChanged(GVariant* data); |
2078 | |
2079 | + void UpdateTargetWindowItems(); |
2080 | void UpdateShowNow(bool ignore); |
2081 | bool CheckMouseInside(); |
2082 | |
2083 | @@ -158,7 +163,7 @@ |
2084 | |
2085 | void ActivateIntegratedMenus(nux::Point const&); |
2086 | |
2087 | - menu::Manager::Ptr const& menu_manager_; |
2088 | + menu::Manager::Ptr menu_manager_; |
2089 | glib::Object<BamfMatcher> matcher_; |
2090 | |
2091 | nux::TextureLayer* title_layer_; |
2092 | @@ -190,7 +195,6 @@ |
2093 | bool integrated_menus_; |
2094 | bool always_show_menus_; |
2095 | |
2096 | - Window active_xid_; |
2097 | nux::Geometry monitor_geo_; |
2098 | const std::string desktop_name_; |
2099 | |
2100 | |
2101 | === modified file 'panel/PanelView.cpp' |
2102 | --- panel/PanelView.cpp 2014-03-06 16:26:34 +0000 |
2103 | +++ panel/PanelView.cpp 2015-07-15 14:19:40 +0000 |
2104 | @@ -519,7 +519,7 @@ |
2105 | |
2106 | if (opacity_maximized_toggle_) |
2107 | { |
2108 | - Window maximized_win = menu_view_->GetMaximizedWindow(); |
2109 | + Window maximized_win = menu_view_->maximized_window(); |
2110 | |
2111 | if (wm.IsExpoActive() || (maximized_win != 0 && !wm.IsWindowObscured(maximized_win))) |
2112 | opacity = 1.0f; |
2113 | @@ -676,7 +676,7 @@ |
2114 | if (!IsActive()) |
2115 | return false; |
2116 | |
2117 | - if ((menu_view_->HasMenus() && menu_view_->ActivateIfSensitive()) || |
2118 | + if ((menu_view_->HasKeyActivableMenus() && menu_view_->ActivateIfSensitive()) || |
2119 | indicators_->ActivateIfSensitive()) |
2120 | { |
2121 | // Since this only happens on keyboard events, we need to prevent that the |
2122 | @@ -693,7 +693,7 @@ |
2123 | if (!IsActive()) |
2124 | return false; |
2125 | |
2126 | - if ((menu_view_->HasMenus() && menu_view_->ActivateEntry(entry_id, 0)) || |
2127 | + if ((menu_view_->HasKeyActivableMenus() && menu_view_->ActivateEntry(entry_id, 0)) || |
2128 | indicators_->ActivateEntry(entry_id, 0)) |
2129 | { |
2130 | // Since this only happens on keyboard events, we need to prevent that the |
2131 | |
2132 | === modified file 'plugins/unityshell/src/unityshell.cpp' |
2133 | --- plugins/unityshell/src/unityshell.cpp 2015-06-03 12:46:12 +0000 |
2134 | +++ plugins/unityshell/src/unityshell.cpp 2015-07-15 14:19:40 +0000 |
2135 | @@ -156,6 +156,7 @@ |
2136 | , cScreen(CompositeScreen::get(screen)) |
2137 | , gScreen(GLScreen::get(screen)) |
2138 | , sScreen(ScaleScreen::get(screen)) |
2139 | + , WM(PluginAdapter::Initialize(screen)) |
2140 | , menus_(std::make_shared<menu::Manager>(std::make_shared<indicator::DBusIndicators>(), std::make_shared<key::GnomeGrabber>())) |
2141 | , deco_manager_(std::make_shared<decoration::Manager>(menus_)) |
2142 | , debugger_(this) |
2143 | @@ -278,9 +279,6 @@ |
2144 | ScaleScreenInterface::setHandler(sScreen); |
2145 | screen->updateSupportedWmHints(); |
2146 | |
2147 | - PluginAdapter::Initialize(screen); |
2148 | - AddChild(&WindowManager::Default()); |
2149 | - |
2150 | StartupNotifyService::Default()->SetSnDisplay(screen->snDisplay(), screen->screenNum()); |
2151 | |
2152 | nux::NuxInitialize(0); |
2153 | @@ -441,13 +439,13 @@ |
2154 | sigc::mem_fun(this, &UnityScreen::OnMinimizeDurationChanged) |
2155 | ); |
2156 | |
2157 | - WindowManager& wm = WindowManager::Default(); |
2158 | - wm.initiate_spread.connect(sigc::mem_fun(this, &UnityScreen::OnInitiateSpread)); |
2159 | - wm.terminate_spread.connect(sigc::mem_fun(this, &UnityScreen::OnTerminateSpread)); |
2160 | - wm.initiate_expo.connect(sigc::mem_fun(this, &UnityScreen::DamagePanelShadow)); |
2161 | - wm.terminate_expo.connect(sigc::mem_fun(this, &UnityScreen::DamagePanelShadow)); |
2162 | + WM.initiate_spread.connect(sigc::mem_fun(this, &UnityScreen::OnInitiateSpread)); |
2163 | + WM.terminate_spread.connect(sigc::mem_fun(this, &UnityScreen::OnTerminateSpread)); |
2164 | + WM.initiate_expo.connect(sigc::mem_fun(this, &UnityScreen::DamagePanelShadow)); |
2165 | + WM.terminate_expo.connect(sigc::mem_fun(this, &UnityScreen::DamagePanelShadow)); |
2166 | |
2167 | - AddChild(&screen_introspection_); |
2168 | + Introspectable::AddChild(&WM); |
2169 | + Introspectable::AddChild(&screen_introspection_); |
2170 | |
2171 | /* Create blur backup texture */ |
2172 | auto gpu_device = nux::GetGraphicsDisplay()->GetGpuDevice(); |
2173 | @@ -686,7 +684,7 @@ |
2174 | if (sources_.GetSource(local::RELAYOUT_TIMEOUT)) |
2175 | return; |
2176 | |
2177 | - if (WindowManager::Default().IsExpoActive()) |
2178 | + if (WM.IsExpoActive()) |
2179 | return; |
2180 | |
2181 | CompOutput* output = _last_output; |
2182 | @@ -947,7 +945,7 @@ |
2183 | nux::TexCoordXForm texxform; |
2184 | texxform.SetWrap(nux::TEXWRAP_REPEAT, nux::TEXWRAP_CLAMP); |
2185 | |
2186 | - int monitor = WindowManager::Default().MonitorGeometryIn(NuxGeometryFromCompRect(output_dev)); |
2187 | + int monitor = WM.MonitorGeometryIn(NuxGeometryFromCompRect(output_dev)); |
2188 | auto const& texture = panel_style_.GetBackground(monitor)->GetDeviceTexture(); |
2189 | graphics_engine->QRP_GLSL_1Tex(0, 0, output_dev.width(), texture->GetHeight(), texture, texxform, nux::color::White); |
2190 | } |
2191 | @@ -960,7 +958,7 @@ |
2192 | hud_controller_->IsVisible() || |
2193 | session_controller_->Visible() || |
2194 | ((switcher_controller_->Visible() || |
2195 | - WindowManager::Default().IsExpoActive()) |
2196 | + WM.IsExpoActive()) |
2197 | && !fullscreen_windows_.empty () && (!(screen->grabbed () && !screen->otherGrabExist (NULL)))); |
2198 | } |
2199 | |
2200 | @@ -2218,7 +2216,7 @@ |
2201 | CompAction::State state, |
2202 | CompOption::Vector& options) |
2203 | { |
2204 | - WindowManager::Default().ShowDesktop(); |
2205 | + WM.ShowDesktop(); |
2206 | return true; |
2207 | } |
2208 | |
2209 | @@ -2322,7 +2320,7 @@ |
2210 | CompAction::State state, |
2211 | CompOption::Vector& options) |
2212 | { |
2213 | - if (WindowManager::Default().IsWallActive()) |
2214 | + if (WM.IsWallActive()) |
2215 | return false; |
2216 | else if (switcher_controller_->Visible()) |
2217 | switcher_controller_->Next(); |
2218 | @@ -2520,11 +2518,9 @@ |
2219 | } |
2220 | else |
2221 | { |
2222 | - auto& wm = WindowManager::Default(); |
2223 | - |
2224 | - if (wm.IsScreenGrabbed()) |
2225 | + if (WM.IsScreenGrabbed()) |
2226 | { |
2227 | - hud_ungrab_slot_ = wm.screen_ungrabbed.connect([this] { ShowHud(); }); |
2228 | + hud_ungrab_slot_ = WM.screen_ungrabbed.connect([this] { ShowHud(); }); |
2229 | |
2230 | // Let's wait ungrab event for maximum a couple of seconds... |
2231 | sources_.AddTimeoutSeconds(2, [this] { |
2232 | @@ -2663,7 +2659,7 @@ |
2233 | KeySym keysym = XkbKeycodeToKeysym(screen->dpy(), keybind.keycode(), 0, 0); |
2234 | unsigned modifiers = CompizModifiersToNux(keybind.modifiers()); |
2235 | |
2236 | - WindowManager::Default().close_window_key = std::make_pair(modifiers, keysym); |
2237 | + WM.close_window_key = std::make_pair(modifiers, keysym); |
2238 | } |
2239 | |
2240 | void UnityScreen::UpdateActivateIndicatorsKey() |
2241 | @@ -2672,7 +2668,7 @@ |
2242 | KeySym keysym = XkbKeycodeToKeysym(screen->dpy(), keybind.keycode(), 0, 0); |
2243 | unsigned modifiers = CompizModifiersToNux(keybind.modifiers()); |
2244 | |
2245 | - WindowManager::Default().activate_indicators_key = std::make_pair(modifiers, keysym); |
2246 | + WM.activate_indicators_key = std::make_pair(modifiers, keysym); |
2247 | } |
2248 | |
2249 | bool UnityScreen::initPluginActions() |
2250 | @@ -2925,7 +2921,7 @@ |
2251 | } |
2252 | } |
2253 | |
2254 | - if (WindowManager::Default().IsScaleActive() && |
2255 | + if (uScreen->WM.IsScaleActive() && |
2256 | uScreen->sScreen->getSelectedWindow() == window->id()) |
2257 | { |
2258 | nux::Geometry const& scaled_geo = GetScaledGeometry(); |
2259 | @@ -3030,9 +3026,8 @@ |
2260 | !(window_state & CompWindowStateFullscreenMask) && |
2261 | !(window_type & CompWindowTypeFullscreenMask)) |
2262 | { |
2263 | - WindowManager& wm = WindowManager::Default(); |
2264 | auto const& output = uScreen->screen->currentOutputDev(); |
2265 | - int monitor = wm.MonitorGeometryIn(NuxGeometryFromCompRect(output)); |
2266 | + int monitor = uScreen->WM.MonitorGeometryIn(NuxGeometryFromCompRect(output)); |
2267 | |
2268 | if (window->y() - window->border().top < output.y() + uScreen->panel_style_.PanelHeight(monitor)) |
2269 | { |
2270 | @@ -3670,8 +3665,7 @@ |
2271 | { |
2272 | if (strcmp(name, "hsize") == 0 || strcmp(name, "vsize") == 0) |
2273 | { |
2274 | - WindowManager& wm = WindowManager::Default(); |
2275 | - wm.viewport_layout_changed.emit(screen->vpSize().width(), screen->vpSize().height()); |
2276 | + WM.viewport_layout_changed.emit(screen->vpSize().width(), screen->vpSize().height()); |
2277 | } |
2278 | else if (strcmp(name, "close_window_key") == 0) |
2279 | { |
2280 | @@ -3787,13 +3781,11 @@ |
2281 | if (QuicklistManager::Default()->Current()) |
2282 | QuicklistManager::Default()->Current()->Hide(); |
2283 | |
2284 | - auto& wm = WindowManager::Default(); |
2285 | - |
2286 | - if (wm.IsScaleActive()) |
2287 | - wm.TerminateScale(); |
2288 | - |
2289 | - if (wm.IsExpoActive()) |
2290 | - wm.TerminateExpo(); |
2291 | + if (WM.IsScaleActive()) |
2292 | + WM.TerminateScale(); |
2293 | + |
2294 | + if (WM.IsExpoActive()) |
2295 | + WM.TerminateExpo(); |
2296 | |
2297 | RaiseOSK(); |
2298 | } |
2299 | @@ -3892,24 +3884,24 @@ |
2300 | auto edge_barriers = std::make_shared<ui::EdgeBarrierController>(); |
2301 | |
2302 | launcher_controller_ = std::make_shared<launcher::Controller>(xdnd_manager, edge_barriers); |
2303 | - AddChild(launcher_controller_.get()); |
2304 | + Introspectable::AddChild(launcher_controller_.get()); |
2305 | |
2306 | switcher_controller_ = std::make_shared<switcher::Controller>(); |
2307 | switcher_controller_->detail.changed.connect(sigc::mem_fun(this, &UnityScreen::OnSwitcherDetailChanged)); |
2308 | - AddChild(switcher_controller_.get()); |
2309 | + Introspectable::AddChild(switcher_controller_.get()); |
2310 | |
2311 | LOG_INFO(logger) << "initLauncher-Launcher " << timer.ElapsedSeconds() << "s"; |
2312 | |
2313 | /* Setup panel */ |
2314 | timer.Reset(); |
2315 | panel_controller_ = std::make_shared<panel::Controller>(menus_, edge_barriers); |
2316 | - AddChild(panel_controller_.get()); |
2317 | + Introspectable::AddChild(panel_controller_.get()); |
2318 | LOG_INFO(logger) << "initLauncher-Panel " << timer.ElapsedSeconds() << "s"; |
2319 | |
2320 | /* Setup Places */ |
2321 | dash_controller_ = std::make_shared<dash::Controller>(); |
2322 | dash_controller_->on_realize.connect(sigc::mem_fun(this, &UnityScreen::OnDashRealized)); |
2323 | - AddChild(dash_controller_.get()); |
2324 | + Introspectable::AddChild(dash_controller_.get()); |
2325 | |
2326 | /* Setup Hud */ |
2327 | hud_controller_ = std::make_shared<hud::Controller>(); |
2328 | @@ -3918,14 +3910,14 @@ |
2329 | hud_controller_->multiple_launchers = (optionGetNumLaunchers() == 0); |
2330 | hud_controller_->icon_size = launcher_controller_->options()->icon_size(); |
2331 | hud_controller_->tile_size = launcher_controller_->options()->tile_size(); |
2332 | - AddChild(hud_controller_.get()); |
2333 | + Introspectable::AddChild(hud_controller_.get()); |
2334 | LOG_INFO(logger) << "initLauncher-hud " << timer.ElapsedSeconds() << "s"; |
2335 | |
2336 | // Setup Shortcut Hint |
2337 | auto base_window_raiser = std::make_shared<shortcut::BaseWindowRaiserImp>(); |
2338 | auto shortcuts_modeller = std::make_shared<shortcut::CompizModeller>(); |
2339 | shortcut_controller_ = std::make_shared<shortcut::Controller>(base_window_raiser, shortcuts_modeller); |
2340 | - AddChild(shortcut_controller_.get()); |
2341 | + Introspectable::AddChild(shortcut_controller_.get()); |
2342 | ShowFirstRunHints(); |
2343 | |
2344 | // Setup Session Controller |
2345 | @@ -3936,7 +3928,7 @@ |
2346 | manager->unlocked.connect(sigc::mem_fun(this, &UnityScreen::OnScreenUnlocked)); |
2347 | session_dbus_manager_ = std::make_shared<session::DBusManager>(manager); |
2348 | session_controller_ = std::make_shared<session::Controller>(manager); |
2349 | - AddChild(session_controller_.get()); |
2350 | + Introspectable::AddChild(session_controller_.get()); |
2351 | |
2352 | // Setup Lockscreen Controller |
2353 | screensaver_dbus_manager_ = std::make_shared<lockscreen::DBusManager>(manager); |
2354 | @@ -4122,7 +4114,7 @@ |
2355 | window->minimizedSetEnabled (this, false); |
2356 | } |
2357 | |
2358 | - /* Keep this after the optionGetShowMinimizedWindows branch */ |
2359 | + /* Keep this after the optionGetShowMIntrospectable.hinimizedWindows branch */ |
2360 | |
2361 | if (window->state() & CompWindowStateFullscreenMask) |
2362 | uScreen->fullscreen_windows_.push_back(window); |
2363 | @@ -4139,8 +4131,8 @@ |
2364 | { |
2365 | Window xid = window->id(); |
2366 | auto const& swins = uScreen->sScreen->getWindows(); |
2367 | + WindowManager& wm = uScreen->WM; |
2368 | bool scaled = std::find(swins.begin(), swins.end(), ScaleWindow::get(window)) != swins.end(); |
2369 | - WindowManager& wm = WindowManager::Default(); |
2370 | |
2371 | introspection |
2372 | .add(scaled ? GetScaledGeometry() : wm.GetWindowGeometry(xid)) |
2373 | @@ -4376,9 +4368,7 @@ |
2374 | |
2375 | nux::Geometry UnityWindow::GetScaledGeometry() |
2376 | { |
2377 | - WindowManager& wm = WindowManager::Default(); |
2378 | - |
2379 | - if (!wm.IsScaleActive()) |
2380 | + if (!uScreen->WM.IsScaleActive()) |
2381 | return nux::Geometry(); |
2382 | |
2383 | ScaleWindow* scale_win = ScaleWindow::get(window); |
2384 | |
2385 | === modified file 'plugins/unityshell/src/unityshell.h' |
2386 | --- plugins/unityshell/src/unityshell.h 2015-06-03 12:46:12 +0000 |
2387 | +++ plugins/unityshell/src/unityshell.h 2015-07-15 14:19:40 +0000 |
2388 | @@ -333,6 +333,7 @@ |
2389 | |
2390 | /* The window thread should be the last thing removed, as c++ does it in reverse order */ |
2391 | std::unique_ptr<nux::WindowThread> wt; |
2392 | + WindowManager& WM; |
2393 | |
2394 | menu::Manager::Ptr menus_; |
2395 | std::shared_ptr<decoration::Manager> deco_manager_; |
2396 | @@ -368,7 +369,7 @@ |
2397 | typedef std::vector<CompActionPtr> ShortcutActions; |
2398 | ShortcutActions _shortcut_actions; |
2399 | std::map<CancelActionTarget, CompActionPtr> _escape_actions; |
2400 | - std::map<int, unsigned int> windows_for_monitor_; |
2401 | + std::unordered_map<int, unsigned int> windows_for_monitor_; |
2402 | |
2403 | /* keyboard-nav mode */ |
2404 | CompWindow* newFocusedWindow; |
2405 | |
2406 | === modified file 'services/panel-main.c' |
2407 | --- services/panel-main.c 2014-12-09 15:41:53 +0000 |
2408 | +++ services/panel-main.c 2015-07-15 14:19:40 +0000 |
2409 | @@ -26,20 +26,21 @@ |
2410 | #include "config.h" |
2411 | #include "panel-a11y.h" |
2412 | #include "panel-service.h" |
2413 | +#include "panel-service-private.h" |
2414 | |
2415 | static GDBusNodeInfo *introspection_data = NULL; |
2416 | |
2417 | static const gchar introspection_xml[] = |
2418 | "<node>" |
2419 | - " <interface name='com.canonical.Unity.Panel.Service'>" |
2420 | + " <interface name='"UPS_IFACE"'>" |
2421 | "" |
2422 | " <method name='Sync'>" |
2423 | - " <arg type='a(ssssbbusbbi)' name='state' direction='out'/>" |
2424 | + " <arg type='"ENTRY_ARRAY_SIGNATURE"' name='state' direction='out'/>" |
2425 | " </method>" |
2426 | "" |
2427 | " <method name='SyncOne'>" |
2428 | " <arg type='s' name='indicator_id' direction='in'/>" |
2429 | - " <arg type='a(ssssbbusbbi)' name='state' direction='out'/>" |
2430 | + " <arg type='"ENTRY_ARRAY_SIGNATURE"' name='state' direction='out'/>" |
2431 | " </method>" |
2432 | "" |
2433 | " <method name='SyncGeometries'>" |
2434 | @@ -109,10 +110,6 @@ |
2435 | " </interface>" |
2436 | "</node>"; |
2437 | |
2438 | -#define S_NAME_DESKTOP "com.canonical.Unity.Panel.Service.Desktop" |
2439 | -#define S_NAME_LOCKSCREEN "com.canonical.Unity.Panel.Service.LockScreen" |
2440 | -#define S_PATH "/com/canonical/Unity/Panel/Service" |
2441 | -#define S_IFACE "com.canonical.Unity.Panel.Service" |
2442 | |
2443 | /* Forwards */ |
2444 | static void |
2445 | @@ -270,8 +267,8 @@ |
2446 | GError *error = NULL; |
2447 | g_dbus_connection_emit_signal (connection, |
2448 | NULL, |
2449 | - S_PATH, |
2450 | - S_IFACE, |
2451 | + UPS_PATH, |
2452 | + UPS_IFACE, |
2453 | "ReSync", |
2454 | g_variant_new ("(s)", indicator_id), |
2455 | &error); |
2456 | @@ -292,10 +289,13 @@ |
2457 | GError *error = NULL; |
2458 | g_dbus_connection_emit_signal (connection, |
2459 | NULL, |
2460 | - S_PATH, |
2461 | - S_IFACE, |
2462 | + UPS_PATH, |
2463 | + UPS_IFACE, |
2464 | "EntryActivated", |
2465 | - g_variant_new ("(ss(iiuu))", panel_id, entry_id, x, y, w, h), |
2466 | + g_variant_new ("(ss(iiuu))", |
2467 | + panel_id ? panel_id : "", |
2468 | + entry_id ? entry_id : "", |
2469 | + x, y, w, h), |
2470 | &error); |
2471 | |
2472 | if (error) |
2473 | @@ -315,8 +315,8 @@ |
2474 | |
2475 | g_dbus_connection_emit_signal (connection, |
2476 | NULL, |
2477 | - S_PATH, |
2478 | - S_IFACE, |
2479 | + UPS_PATH, |
2480 | + UPS_IFACE, |
2481 | "EntryActivateRequest", |
2482 | g_variant_new ("(s)", entry_id), |
2483 | &error); |
2484 | @@ -337,8 +337,8 @@ |
2485 | GError *error = NULL; |
2486 | g_dbus_connection_emit_signal (connection, |
2487 | NULL, |
2488 | - S_PATH, |
2489 | - S_IFACE, |
2490 | + UPS_PATH, |
2491 | + UPS_IFACE, |
2492 | "EntryShowNowChanged", |
2493 | g_variant_new ("(sb)", entry_id, show_now_state), |
2494 | &error); |
2495 | @@ -356,8 +356,8 @@ |
2496 | GError *error = NULL; |
2497 | g_dbus_connection_emit_signal (connection, |
2498 | NULL, |
2499 | - S_PATH, |
2500 | - S_IFACE, |
2501 | + UPS_PATH, |
2502 | + UPS_IFACE, |
2503 | "IconPathsChanged", |
2504 | NULL, |
2505 | &error); |
2506 | @@ -378,7 +378,7 @@ |
2507 | guint reg_id; |
2508 | |
2509 | reg_id = g_dbus_connection_register_object (connection, |
2510 | - S_PATH, |
2511 | + UPS_PATH, |
2512 | introspection_data->interfaces[0], |
2513 | &interface_vtable, |
2514 | service, |
2515 | @@ -489,7 +489,7 @@ |
2516 | service = panel_service_get_default (); |
2517 | |
2518 | owner_id = g_bus_own_name (G_BUS_TYPE_SESSION, |
2519 | - !lockscreen_mode ? S_NAME_DESKTOP : S_NAME_LOCKSCREEN, |
2520 | + !lockscreen_mode ? UPS_NAME_DESKTOP : UPS_NAME_LOCKSCREEN, |
2521 | G_BUS_NAME_OWNER_FLAGS_NONE, |
2522 | on_bus_acquired, |
2523 | on_name_acquired, |
2524 | |
2525 | === modified file 'services/panel-service-private.h' |
2526 | --- services/panel-service-private.h 2013-10-03 15:15:35 +0000 |
2527 | +++ services/panel-service-private.h 2015-07-15 14:19:40 +0000 |
2528 | @@ -21,9 +21,27 @@ |
2529 | |
2530 | #include <X11/Xlib.h> |
2531 | #include <X11/keysym.h> |
2532 | +#include <glib.h> |
2533 | |
2534 | G_BEGIN_DECLS |
2535 | |
2536 | +#ifdef __cplusplus |
2537 | +extern "C" { |
2538 | +#endif |
2539 | + |
2540 | +#define UPS_NAME_DESKTOP "com.canonical.Unity.Panel.Service.Desktop" |
2541 | +#define UPS_NAME_LOCKSCREEN "com.canonical.Unity.Panel.Service.LockScreen" |
2542 | +#define UPS_PATH "/com/canonical/Unity/Panel/Service" |
2543 | +#define UPS_IFACE "com.canonical.Unity.Panel.Service" |
2544 | + |
2545 | +#define APPMENU_INDICATOR_NAME "libappmenu.so" |
2546 | + |
2547 | +#define ENTRY_SIGNATURE "(sssusbbusbbi)" |
2548 | +#define ENTRY_ARRAY_SIGNATURE "a" ENTRY_SIGNATURE "" |
2549 | + |
2550 | +#define AltMask Mod1Mask |
2551 | +#define SuperMask Mod4Mask |
2552 | + |
2553 | typedef struct _KeyBinding |
2554 | { |
2555 | KeySym key; |
2556 | @@ -31,11 +49,12 @@ |
2557 | guint32 modifiers; |
2558 | } KeyBinding; |
2559 | |
2560 | -#define AltMask Mod1Mask |
2561 | -#define SuperMask Mod4Mask |
2562 | - |
2563 | void parse_string_keybinding (const char *, KeyBinding *); |
2564 | |
2565 | +#ifdef __cplusplus |
2566 | +} |
2567 | +#endif |
2568 | + |
2569 | G_END_DECLS |
2570 | |
2571 | #endif /* _PANEL_SERVICE_PRIVATE_H_ */ |
2572 | |
2573 | === modified file 'services/panel-service.c' |
2574 | --- services/panel-service.c 2015-07-15 14:19:40 +0000 |
2575 | +++ services/panel-service.c 2015-07-15 14:19:40 +0000 |
2576 | @@ -42,7 +42,7 @@ |
2577 | |
2578 | #define NOTIFY_TIMEOUT 80 |
2579 | #define N_TIMEOUT_SLOTS 50 |
2580 | -#define MAX_INDICATOR_ENTRIES 100 |
2581 | +#define MAX_INDICATOR_ENTRIES 500 |
2582 | |
2583 | #define NUX_VERTICAL_SCROLL_DELTA 120 |
2584 | #define NUX_HORIZONTAL_SCROLL_DELTA (NUX_VERTICAL_SCROLL_DELTA ^ 2) |
2585 | @@ -60,10 +60,13 @@ |
2586 | { |
2587 | GSList *indicators; |
2588 | GSList *dropdown_entries; |
2589 | + GSList *removed_entries; |
2590 | GHashTable *id2entry_hash; |
2591 | GHashTable *panel2entries_hash; |
2592 | + IndicatorObject *appmenu_indicator; |
2593 | |
2594 | - gint32 timeouts[N_TIMEOUT_SLOTS]; |
2595 | + guint timeouts[N_TIMEOUT_SLOTS]; |
2596 | + guint remove_idle; |
2597 | |
2598 | IndicatorObjectEntry *last_entry; |
2599 | IndicatorObjectEntry *last_dropdown_entry; |
2600 | @@ -103,14 +106,14 @@ |
2601 | |
2602 | enum |
2603 | { |
2604 | - SYNC_WAITING = -1, |
2605 | + SYNC_WAITING = G_MAXUINT, |
2606 | SYNC_NEUTRAL = 0, |
2607 | }; |
2608 | |
2609 | static guint32 _service_signals[LAST_SIGNAL] = { 0 }; |
2610 | |
2611 | static const gchar * indicator_order[][2] = { |
2612 | - {"libappmenu.so", NULL}, /* indicator-appmenu" */ |
2613 | + {APPMENU_INDICATOR_NAME, NULL}, /* indicator-appmenu" */ |
2614 | {"libapplication.so", NULL}, /* indicator-application" */ |
2615 | {"floating-indicators", NULL}, /* position-less NG indicators */ |
2616 | {"libprintersmenu.so", NULL}, /* indicator-printers */ |
2617 | @@ -135,6 +138,8 @@ |
2618 | static void notify_object (IndicatorObject *object); |
2619 | static void update_keybinding (GSettings *, const gchar *, gpointer); |
2620 | static void emit_upstart_event (const gchar *); |
2621 | +static gchar * get_indicator_entry_id_by_entry (IndicatorObjectEntry *entry); |
2622 | +static IndicatorObjectEntry * get_indicator_entry_by_id (PanelService *self, const gchar *entry_id); |
2623 | static GdkFilterReturn event_filter (GdkXEvent *, GdkEvent *, PanelService *); |
2624 | |
2625 | /* |
2626 | @@ -163,7 +168,7 @@ |
2627 | |
2628 | for (i = 0; i < N_TIMEOUT_SLOTS; i++) |
2629 | { |
2630 | - if (priv->timeouts[i] > 0) |
2631 | + if (priv->timeouts[i] > 0 && priv->timeouts[i] != SYNC_WAITING) |
2632 | { |
2633 | g_source_remove (priv->timeouts[i]); |
2634 | priv->timeouts[i] = 0; |
2635 | @@ -264,9 +269,10 @@ |
2636 | } |
2637 | |
2638 | static gboolean |
2639 | -is_point_in_rect (gint x, gint y, GdkRectangle* rect) |
2640 | +rect_contains_point (GdkRectangle* rect, gint x, gint y) |
2641 | { |
2642 | - g_return_val_if_fail (rect, FALSE); |
2643 | + if (!rect) |
2644 | + return FALSE; |
2645 | |
2646 | return (x >= rect->x && x <= (rect->x + rect->width) && |
2647 | y >= rect->y && y <= (rect->y + rect->height)); |
2648 | @@ -289,7 +295,7 @@ |
2649 | IndicatorObjectEntry *entry = k; |
2650 | GdkRectangle *geo = v; |
2651 | |
2652 | - if (is_point_in_rect (x, y, geo)) |
2653 | + if (rect_contains_point (geo, x, y)) |
2654 | { |
2655 | return entry; |
2656 | } |
2657 | @@ -320,8 +326,7 @@ |
2658 | IndicatorObjectEntry *entry = key; |
2659 | GdkRectangle *geo = value; |
2660 | |
2661 | - if (x >= geo->x && x <= (geo->x + geo->width) && |
2662 | - y >= geo->y && y <= (geo->y + geo->height)) |
2663 | + if (rect_contains_point (geo, x, y)) |
2664 | { |
2665 | return entry; |
2666 | } |
2667 | @@ -331,7 +336,7 @@ |
2668 | } |
2669 | |
2670 | static const gchar* |
2671 | -get_panel_at (PanelService *self, gint x, gint y) |
2672 | +get_panel_for_parent_at (PanelService *self, guint parent, gint x, gint y) |
2673 | { |
2674 | GHashTableIter panel_iter, entries_iter; |
2675 | gpointer key, value, k, v; |
2676 | @@ -345,12 +350,20 @@ |
2677 | |
2678 | while (g_hash_table_iter_next (&entries_iter, &k, &v)) |
2679 | { |
2680 | + IndicatorObjectEntry *entry = k; |
2681 | GdkRectangle *geo = v; |
2682 | |
2683 | - if (x >= geo->x && x <= (geo->x + geo->width) && |
2684 | - y >= geo->y && y <= (geo->y + geo->height)) |
2685 | + /* The entry might be invalid at this point (as it could have been |
2686 | + * removed, but still not synced), so it's better to double check */ |
2687 | + if (g_slist_find (self->priv->removed_entries, entry)) |
2688 | + continue; |
2689 | + |
2690 | + if (!parent || entry->parent_window == parent) |
2691 | { |
2692 | - return panel_id; |
2693 | + if (rect_contains_point (geo, x, y)) |
2694 | + { |
2695 | + return panel_id; |
2696 | + } |
2697 | } |
2698 | } |
2699 | } |
2700 | @@ -413,7 +426,7 @@ |
2701 | /* Unity might register some "fake" dropdown entries that it might use to |
2702 | * to present long menu bars (right now only for appmenu indicator) */ |
2703 | entry = g_new0 (IndicatorObjectEntry, 1); |
2704 | - entry->parent_object = panel_service_get_indicator (self, "libappmenu.so"); |
2705 | + entry->parent_object = self->priv->appmenu_indicator; |
2706 | entry->name_hint = g_strdup (entry_id); |
2707 | self->priv->dropdown_entries = g_slist_append (self->priv->dropdown_entries, entry); |
2708 | g_hash_table_insert (self->priv->id2entry_hash, (gpointer)entry->name_hint, entry); |
2709 | @@ -423,6 +436,21 @@ |
2710 | } |
2711 | |
2712 | static void |
2713 | +ensure_entry_menu_is_closed (PanelService *self, |
2714 | + const gchar *panel_id, |
2715 | + IndicatorObjectEntry *entry) |
2716 | +{ |
2717 | + PanelServicePrivate *priv = self->priv; |
2718 | + |
2719 | + /* If the entry has been removed let's make sure that its menu is closed */ |
2720 | + if (GTK_IS_MENU (priv->last_menu) && priv->last_menu == entry->menu) |
2721 | + { |
2722 | + if (!priv->last_panel || !panel_id || g_strcmp0 (priv->last_panel, panel_id) == 0) |
2723 | + gtk_menu_popdown (entry->menu); |
2724 | + } |
2725 | +} |
2726 | + |
2727 | +static void |
2728 | reinject_key_event_to_root_window (XIDeviceEvent *ev) |
2729 | { |
2730 | XKeyEvent kev; |
2731 | @@ -542,9 +570,7 @@ |
2732 | { |
2733 | /* Middle clicks over an appmenu entry are considered just like |
2734 | * all other clicks */ |
2735 | - IndicatorObject *obj = get_entry_parent_indicator (entry); |
2736 | - |
2737 | - if (g_strcmp0 (g_object_get_data (G_OBJECT (obj), "id"), "libappmenu.so") == 0) |
2738 | + if (get_entry_parent_indicator (entry) == priv->appmenu_indicator) |
2739 | { |
2740 | event_is_a_click = TRUE; |
2741 | } |
2742 | @@ -609,7 +635,7 @@ |
2743 | initial_resync (PanelService *self) |
2744 | { |
2745 | g_signal_emit (self, _service_signals[RE_SYNC], 0, ""); |
2746 | - return FALSE; |
2747 | + return G_SOURCE_REMOVE; |
2748 | } |
2749 | |
2750 | static gboolean |
2751 | @@ -618,7 +644,7 @@ |
2752 | if (!lockscreen_mode) |
2753 | emit_upstart_event ("indicator-services-start"); |
2754 | |
2755 | - return FALSE; |
2756 | + return G_SOURCE_REMOVE; |
2757 | } |
2758 | |
2759 | static void |
2760 | @@ -782,10 +808,10 @@ |
2761 | if (self->priv->indicators == NULL) |
2762 | { |
2763 | g_signal_emit (self, _service_signals[INDICATORS_CLEARED], 0); |
2764 | - return FALSE; |
2765 | + return G_SOURCE_REMOVE; |
2766 | } |
2767 | |
2768 | - return TRUE; |
2769 | + return G_SOURCE_CONTINUE; |
2770 | } |
2771 | |
2772 | static void |
2773 | @@ -863,6 +889,9 @@ |
2774 | g_object_ref_sink (G_OBJECT (indicator)); |
2775 | } |
2776 | |
2777 | + if (self->priv->appmenu_indicator == indicator) |
2778 | + self->priv->appmenu_indicator = NULL; |
2779 | + |
2780 | g_object_unref (G_OBJECT (indicator)); |
2781 | } |
2782 | |
2783 | @@ -1077,7 +1106,7 @@ |
2784 | g_signal_emit (self, _service_signals[RE_SYNC], |
2785 | 0, g_object_get_data (G_OBJECT (object), "id")); |
2786 | |
2787 | - return FALSE; |
2788 | + return G_SOURCE_REMOVE; |
2789 | } |
2790 | |
2791 | static void |
2792 | @@ -1136,6 +1165,7 @@ |
2793 | g_return_if_fail (PANEL_IS_SERVICE (self)); |
2794 | g_return_if_fail (entry != NULL); |
2795 | |
2796 | + self->priv->removed_entries = g_slist_remove (self->priv->removed_entries, entry); |
2797 | gchar *entry_id = get_indicator_entry_id_by_entry (entry); |
2798 | g_hash_table_insert (self->priv->id2entry_hash, entry_id, entry); |
2799 | |
2800 | @@ -1175,6 +1205,42 @@ |
2801 | notify_object (object); |
2802 | } |
2803 | |
2804 | +static gboolean |
2805 | +on_removed_idle (PanelService *self) |
2806 | +{ |
2807 | + GHashTableIter iter; |
2808 | + GHashTable *entry2geometry_hash; |
2809 | + IndicatorObjectEntry *entry; |
2810 | + gpointer value; |
2811 | + GSList *l; |
2812 | + |
2813 | + for (l = self->priv->removed_entries; l; l = l->next) |
2814 | + { |
2815 | + entry = l->data; |
2816 | + ensure_entry_menu_is_closed (self, NULL, entry); |
2817 | + |
2818 | + g_hash_table_iter_init (&iter, self->priv->panel2entries_hash); |
2819 | + while (g_hash_table_iter_next (&iter, NULL, &value)) |
2820 | + { |
2821 | + if ((entry2geometry_hash = value)) |
2822 | + { |
2823 | + g_hash_table_remove (entry2geometry_hash, entry); |
2824 | + |
2825 | + if (g_hash_table_size (entry2geometry_hash) == 0) |
2826 | + { |
2827 | + g_hash_table_iter_remove (&iter); |
2828 | + } |
2829 | + } |
2830 | + } |
2831 | + |
2832 | + } |
2833 | + |
2834 | + g_slist_free (self->priv->removed_entries); |
2835 | + self->priv->removed_entries = NULL; |
2836 | + |
2837 | + return G_SOURCE_REMOVE; |
2838 | +} |
2839 | + |
2840 | static void |
2841 | on_entry_removed (IndicatorObject *object, |
2842 | IndicatorObjectEntry *entry, |
2843 | @@ -1183,11 +1249,6 @@ |
2844 | g_return_if_fail (PANEL_IS_SERVICE (self)); |
2845 | g_return_if_fail (entry != NULL); |
2846 | |
2847 | - /* Don't remove here the value from panel2entries_hash, this should be |
2848 | - * done during the geometries sync, to avoid false positive. |
2849 | - * FIXME this in libappmenu.so to avoid to send an "entry-removed" signal |
2850 | - * when switching the focus from a window to one of its dialog children */ |
2851 | - |
2852 | gchar *entry_id = get_indicator_entry_id_by_entry (entry); |
2853 | g_hash_table_remove (self->priv->id2entry_hash, entry_id); |
2854 | g_free (entry_id); |
2855 | @@ -1202,6 +1263,13 @@ |
2856 | g_signal_handlers_disconnect_by_data (entry->image, object); |
2857 | } |
2858 | |
2859 | + self->priv->removed_entries = g_slist_append (self->priv->removed_entries, entry); |
2860 | + |
2861 | + if (self->priv->remove_idle) |
2862 | + g_source_remove (self->priv->remove_idle); |
2863 | + |
2864 | + self->priv->remove_idle = g_idle_add ((GSourceFunc) on_removed_idle, self); |
2865 | + |
2866 | notify_object (object); |
2867 | } |
2868 | |
2869 | @@ -1259,6 +1327,7 @@ |
2870 | "unity", |
2871 | "unity-3d", |
2872 | "unity-panel-service", |
2873 | + "unity-all-menus", |
2874 | NULL |
2875 | }; |
2876 | |
2877 | @@ -1278,6 +1347,9 @@ |
2878 | |
2879 | priv->indicators = g_slist_append (priv->indicators, object); |
2880 | |
2881 | + if (!priv->appmenu_indicator && g_strcmp0 (name, APPMENU_INDICATOR_NAME) == 0) |
2882 | + priv->appmenu_indicator = object; |
2883 | + |
2884 | g_object_set_data_full (G_OBJECT (object), "id", g_strdup (name), g_free); |
2885 | |
2886 | g_signal_connect (object, INDICATOR_OBJECT_SIGNAL_ENTRY_ADDED, |
2887 | @@ -1539,10 +1611,11 @@ |
2888 | guint32 image_type = 0; |
2889 | gchar *image_data = gtk_image_to_data (entry->image, &image_type); |
2890 | |
2891 | - g_variant_builder_add (b, "(ssssbbusbbi)", |
2892 | + g_variant_builder_add (b, ENTRY_SIGNATURE, |
2893 | indicator_id, |
2894 | id, |
2895 | entry->name_hint ? entry->name_hint : "", |
2896 | + entry->parent_window, |
2897 | is_label ? gtk_label_get_label (entry->label) : "", |
2898 | is_label ? gtk_widget_get_sensitive (GTK_WIDGET (entry->label)) : FALSE, |
2899 | is_label ? gtk_widget_get_visible (GTK_WIDGET (entry->label)) : FALSE, |
2900 | @@ -1559,14 +1632,15 @@ |
2901 | indicator_entry_null_to_variant (const gchar *indicator_id, |
2902 | GVariantBuilder *b) |
2903 | { |
2904 | - g_variant_builder_add (b, "(ssssbbusbbi)", |
2905 | + g_variant_builder_add (b, ENTRY_SIGNATURE, |
2906 | indicator_id, |
2907 | "", |
2908 | "", |
2909 | + 0, |
2910 | "", |
2911 | FALSE, |
2912 | FALSE, |
2913 | - (guint32) 0, |
2914 | + 0, |
2915 | "", |
2916 | FALSE, |
2917 | FALSE, |
2918 | @@ -1574,15 +1648,20 @@ |
2919 | } |
2920 | |
2921 | static void |
2922 | -indicator_object_full_to_variant (IndicatorObject *object, const gchar *indicator_id, GVariantBuilder *b) |
2923 | +indicator_object_full_to_variant (PanelService *self, IndicatorObject *object, |
2924 | + const gchar *indicator_id, GVariantBuilder *b) |
2925 | { |
2926 | GList *entries, *e; |
2927 | + GHashTable *index_hash = NULL; |
2928 | gint parent_prio = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (object), "priority")); |
2929 | entries = indicator_object_get_entries (object); |
2930 | - gint index = 0; |
2931 | + guint index = 0; |
2932 | |
2933 | if (entries) |
2934 | { |
2935 | + if (object == self->priv->appmenu_indicator) |
2936 | + index_hash = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, NULL); |
2937 | + |
2938 | for (e = entries; e; e = e->next) |
2939 | { |
2940 | gint prio = -1; |
2941 | @@ -1596,14 +1675,29 @@ |
2942 | |
2943 | if (prio < 0) |
2944 | { |
2945 | + if (index_hash) |
2946 | + { |
2947 | + index = GPOINTER_TO_UINT (g_hash_table_lookup (index_hash, |
2948 | + GUINT_TO_POINTER (entry->parent_window))); |
2949 | + } |
2950 | + |
2951 | prio = parent_prio + index; |
2952 | index++; |
2953 | + |
2954 | + if (index_hash) |
2955 | + { |
2956 | + g_hash_table_insert (index_hash, GUINT_TO_POINTER (entry->parent_window), |
2957 | + GUINT_TO_POINTER (index)); |
2958 | + } |
2959 | } |
2960 | |
2961 | indicator_entry_to_variant (entry, id, indicator_id, b, prio); |
2962 | g_free (id); |
2963 | } |
2964 | |
2965 | + if (index_hash) |
2966 | + g_hash_table_destroy (index_hash); |
2967 | + |
2968 | g_list_free (entries); |
2969 | } |
2970 | else |
2971 | @@ -1614,15 +1708,15 @@ |
2972 | } |
2973 | |
2974 | static void |
2975 | -indicator_object_to_variant (IndicatorObject *object, const gchar *indicator_id, GVariantBuilder *b) |
2976 | +indicator_object_to_variant (PanelService *self, IndicatorObject *object, |
2977 | + const gchar *indicator_id, GVariantBuilder *b) |
2978 | { |
2979 | if (!GPOINTER_TO_INT (g_object_get_data (G_OBJECT (object), "remove"))) |
2980 | { |
2981 | - indicator_object_full_to_variant (object, indicator_id, b); |
2982 | + indicator_object_full_to_variant (self, object, indicator_id, b); |
2983 | } |
2984 | else |
2985 | { |
2986 | - PanelService *self = panel_service_get_default (); |
2987 | indicator_entry_null_to_variant (indicator_id, b); |
2988 | panel_service_actually_remove_indicator (self, object); |
2989 | } |
2990 | @@ -1650,7 +1744,7 @@ |
2991 | rect.height *= scale; |
2992 | } |
2993 | |
2994 | - if (is_point_in_rect (x, y, &rect)) |
2995 | + if (rect_contains_point (&rect, x, y)) |
2996 | { |
2997 | return i; |
2998 | } |
2999 | @@ -1722,8 +1816,8 @@ |
3000 | GSList *i; |
3001 | gint position; |
3002 | |
3003 | - g_variant_builder_init (&b, G_VARIANT_TYPE ("(a(ssssbbusbbi))")); |
3004 | - g_variant_builder_open (&b, G_VARIANT_TYPE ("a(ssssbbusbbi)")); |
3005 | + g_variant_builder_init (&b, G_VARIANT_TYPE ("("ENTRY_ARRAY_SIGNATURE")")); |
3006 | + g_variant_builder_open (&b, G_VARIANT_TYPE (ENTRY_ARRAY_SIGNATURE)); |
3007 | |
3008 | for (i = self->priv->indicators; i;) |
3009 | { |
3010 | @@ -1733,7 +1827,7 @@ |
3011 | |
3012 | const gchar *indicator_id = g_object_get_data (G_OBJECT (indicator), "id"); |
3013 | position = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (indicator), "position")); |
3014 | - indicator_object_to_variant (indicator, indicator_id, &b); |
3015 | + indicator_object_to_variant (self, indicator, indicator_id, &b); |
3016 | |
3017 | /* Set the sync back to neutral */ |
3018 | self->priv->timeouts[position] = SYNC_NEUTRAL; |
3019 | @@ -1749,8 +1843,8 @@ |
3020 | GVariantBuilder b; |
3021 | GSList *i; |
3022 | |
3023 | - g_variant_builder_init (&b, G_VARIANT_TYPE ("(a(ssssbbusbbi))")); |
3024 | - g_variant_builder_open (&b, G_VARIANT_TYPE ("a(ssssbbusbbi)")); |
3025 | + g_variant_builder_init (&b, G_VARIANT_TYPE ("("ENTRY_ARRAY_SIGNATURE")")); |
3026 | + g_variant_builder_open (&b, G_VARIANT_TYPE (ENTRY_ARRAY_SIGNATURE)); |
3027 | |
3028 | for (i = self->priv->indicators; i; i = i->next) |
3029 | { |
3030 | @@ -1758,7 +1852,7 @@ |
3031 | g_object_get_data (G_OBJECT (i->data), "id")) == 0) |
3032 | { |
3033 | gint position = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (i->data), "position")); |
3034 | - indicator_object_to_variant (i->data, indicator_id, &b); |
3035 | + indicator_object_to_variant (self, i->data, indicator_id, &b); |
3036 | |
3037 | /* Set the sync back to neutral */ |
3038 | self->priv->timeouts[position] = SYNC_NEUTRAL; |
3039 | @@ -1782,6 +1876,7 @@ |
3040 | { |
3041 | IndicatorObject *object; |
3042 | IndicatorObjectEntry *entry; |
3043 | + GHashTable *entry2geometry_hash; |
3044 | gboolean valid_entry = TRUE; |
3045 | PanelServicePrivate *priv = self->priv; |
3046 | |
3047 | @@ -1802,24 +1897,18 @@ |
3048 | |
3049 | if (entry) |
3050 | { |
3051 | - GHashTable *entry2geometry_hash = g_hash_table_lookup (priv->panel2entries_hash, panel_id); |
3052 | + entry2geometry_hash = g_hash_table_lookup (priv->panel2entries_hash, panel_id); |
3053 | |
3054 | if (width < 0 || height < 0 || !valid_entry) |
3055 | { |
3056 | - /* If the entry has been removed let's make sure that its menu is closed */ |
3057 | - if (valid_entry && GTK_IS_MENU (priv->last_menu) && priv->last_menu == entry->menu) |
3058 | - { |
3059 | - if (!priv->last_panel || g_strcmp0 (priv->last_panel, panel_id) == 0) |
3060 | - gtk_menu_popdown (entry->menu); |
3061 | - } |
3062 | + if (valid_entry) |
3063 | + ensure_entry_menu_is_closed (self, panel_id, entry); |
3064 | |
3065 | if (entry2geometry_hash) |
3066 | { |
3067 | - if (g_hash_table_size (entry2geometry_hash) > 1) |
3068 | - { |
3069 | - g_hash_table_remove (entry2geometry_hash, entry); |
3070 | - } |
3071 | - else |
3072 | + g_hash_table_remove (entry2geometry_hash, entry); |
3073 | + |
3074 | + if (g_hash_table_size (entry2geometry_hash) == 0) |
3075 | { |
3076 | g_hash_table_remove (priv->panel2entries_hash, panel_id); |
3077 | } |
3078 | @@ -2188,7 +2277,7 @@ |
3079 | priv->last_x = x; |
3080 | priv->last_y = y; |
3081 | priv->last_menu_button = button; |
3082 | - priv->last_panel = get_panel_at (self, x, y); |
3083 | + priv->last_panel = get_panel_for_parent_at (self, xid, x, y); |
3084 | |
3085 | g_signal_connect (priv->last_menu, "hide", G_CALLBACK (on_active_menu_hidden), self); |
3086 | g_signal_connect_after (priv->last_menu, "move-current", |
3087 | @@ -2394,10 +2483,9 @@ |
3088 | GList *entries; |
3089 | |
3090 | g_return_if_fail (PANEL_IS_SERVICE (self)); |
3091 | - |
3092 | - object = panel_service_get_indicator (self, "libappmenu.so"); |
3093 | - g_return_if_fail (INDICATOR_IS_OBJECT (object)); |
3094 | - |
3095 | + g_return_if_fail (INDICATOR_IS_OBJECT (self->priv->appmenu_indicator)); |
3096 | + |
3097 | + object = self->priv->appmenu_indicator; |
3098 | entries = indicator_object_get_entries (object); |
3099 | |
3100 | if (entries) |
3101 | |
3102 | === modified file 'services/panel-service.h' |
3103 | --- services/panel-service.h 2014-12-09 15:41:53 +0000 |
3104 | +++ services/panel-service.h 2015-07-15 14:19:40 +0000 |
3105 | @@ -56,14 +56,6 @@ |
3106 | struct _PanelServiceClass |
3107 | { |
3108 | GObjectClass parent_class; |
3109 | - |
3110 | - /*< private >*/ |
3111 | - void (*_view_padding1) (void); |
3112 | - void (*_view_padding2) (void); |
3113 | - void (*_view_padding3) (void); |
3114 | - void (*_view_padding4) (void); |
3115 | - void (*_view_padding5) (void); |
3116 | - void (*_view_padding6) (void); |
3117 | }; |
3118 | |
3119 | GType panel_service_get_type (void) G_GNUC_CONST; |
3120 | |
3121 | === modified file 'shortcuts/ShortcutModel.h' |
3122 | --- shortcuts/ShortcutModel.h 2013-01-19 00:25:07 +0000 |
3123 | +++ shortcuts/ShortcutModel.h 2015-07-15 14:19:40 +0000 |
3124 | @@ -21,7 +21,7 @@ |
3125 | #define UNITYSHELL_SHORTCUS_MODEL_H |
3126 | |
3127 | #include <boost/noncopyable.hpp> |
3128 | -#include <map> |
3129 | +#include <unordered_map> |
3130 | #include <memory> |
3131 | #include <list> |
3132 | #include <string> |
3133 | @@ -43,7 +43,7 @@ |
3134 | |
3135 | nux::Property<int> categories_per_column; |
3136 | std::vector<std::string> const& categories() const { return categories_; } |
3137 | - std::map<std::string, std::list<AbstractHint::Ptr>> const& hints() const { return hints_; } |
3138 | + std::unordered_map<std::string, std::list<AbstractHint::Ptr>> const& hints() const { return hints_; } |
3139 | |
3140 | void Fill(); |
3141 | |
3142 | @@ -51,7 +51,7 @@ |
3143 | void AddHint(AbstractHint::Ptr const& hint); |
3144 | |
3145 | std::vector<std::string> categories_; |
3146 | - std::map<std::string, std::list<AbstractHint::Ptr>> hints_; |
3147 | + std::unordered_map<std::string, std::list<AbstractHint::Ptr>> hints_; |
3148 | }; |
3149 | |
3150 | } |
3151 | |
3152 | === modified file 'tests/autopilot/unity/emulators/panel.py' |
3153 | --- tests/autopilot/unity/emulators/panel.py 2013-05-10 05:16:07 +0000 |
3154 | +++ tests/autopilot/unity/emulators/panel.py 2015-07-15 14:19:40 +0000 |
3155 | @@ -159,6 +159,10 @@ |
3156 | return self.menus.panel_title |
3157 | |
3158 | @property |
3159 | + def focused(self): |
3160 | + return self.menus.focused |
3161 | + |
3162 | + @property |
3163 | def desktop_is_active(self): |
3164 | return self.menus.desktop_active |
3165 | |
3166 | |
3167 | === modified file 'tests/autopilot/unity/tests/__init__.py' |
3168 | --- tests/autopilot/unity/tests/__init__.py 2014-02-12 20:43:54 +0000 |
3169 | +++ tests/autopilot/unity/tests/__init__.py 2015-07-15 14:19:40 +0000 |
3170 | @@ -48,7 +48,7 @@ |
3171 | from Xlib import display |
3172 | from Xlib import Xutil |
3173 | |
3174 | -from gi.repository import Gio |
3175 | +from gi.repository import GLib, Gio |
3176 | |
3177 | log = getLogger(__name__) |
3178 | |
3179 | @@ -256,20 +256,19 @@ |
3180 | atom_type = display.Display().intern_atom('CARDINAL') |
3181 | return bamf_window.x_win.get_property(atom, atom_type, 0, 1024).value[0] |
3182 | |
3183 | - def call_gsettings_cmd(self, command, schema, *args): |
3184 | + def call_gsettings_cmd(self, command, schema, key, value=None): |
3185 | """Set a desktop wide gsettings option |
3186 | - |
3187 | - Using the gsettings command because there is a bug with importing |
3188 | - from gobject introspection and pygtk2 simultaneously, and the Xlib |
3189 | - keyboard layout bits are very unwieldy. This seems like the best |
3190 | - solution, even a little bit brutish. |
3191 | """ |
3192 | - cmd = ['gsettings', command, schema] + list(args) |
3193 | - # strip to remove the trailing \n. |
3194 | - ret = check_output(cmd).strip() |
3195 | - time.sleep(5) |
3196 | - reset_display() |
3197 | - return ret |
3198 | + settings = Gio.Settings.new(schema) |
3199 | + |
3200 | + if command == "get": |
3201 | + return settings.get_value(key).print_(type_annotate=False) |
3202 | + elif command == "set": |
3203 | + settings.set_value(key, GLib.Variant.parse(type=None, text=value)) |
3204 | + settings.apply() |
3205 | + reset_display() |
3206 | + elif command == "reset": |
3207 | + settings.reset(key) |
3208 | |
3209 | def set_unity_option(self, option_name, option_value): |
3210 | """Set an option in the unity compiz plugin options. |
3211 | |
3212 | === modified file 'tests/autopilot/unity/tests/test_dash.py' |
3213 | --- tests/autopilot/unity/tests/test_dash.py 2014-02-28 19:53:07 +0000 |
3214 | +++ tests/autopilot/unity/tests/test_dash.py 2015-07-15 14:19:40 +0000 |
3215 | @@ -164,7 +164,7 @@ |
3216 | |
3217 | self.assertProperty(char_win, is_active=True) |
3218 | |
3219 | - def test_dash_does_not_open_when_fullscreen_window(self): |
3220 | + def test_dash_opens_when_fullscreen_window(self): |
3221 | """ The Dash must not open if a window is fullscreen. """ |
3222 | gedit = self.process_manager.start_app("Text Editor") |
3223 | self.keyboard.press_and_release('F11') |
3224 | @@ -175,7 +175,7 @@ |
3225 | self.keybinding("dash/reveal") |
3226 | self.addCleanup(self.unity.dash.ensure_hidden) |
3227 | |
3228 | - self.assertThat(self.unity.dash.visible, Eventually(Equals(False))) |
3229 | + self.assertThat(self.unity.dash.visible, Eventually(Equals(True))) |
3230 | |
3231 | |
3232 | class DashRevealWithSpreadTests(DashTestCase): |
3233 | |
3234 | === modified file 'tests/autopilot/unity/tests/test_hud.py' |
3235 | --- tests/autopilot/unity/tests/test_hud.py 2014-02-28 19:53:07 +0000 |
3236 | +++ tests/autopilot/unity/tests/test_hud.py 2015-07-15 14:19:40 +0000 |
3237 | @@ -512,7 +512,7 @@ |
3238 | self.keyboard.type("e") |
3239 | self.assertThat(self.unity.hud.view.selected_button, Eventually(Equals(1))) |
3240 | |
3241 | - def test_hud_does_not_open_when_fullscreen_window(self): |
3242 | + def test_hud_opens_when_fullscreen_window(self): |
3243 | """ The Hud must not open if a window is fullscreen. """ |
3244 | gedit = self.process_manager.start_app("Text Editor") |
3245 | self.keyboard.press_and_release('F11') |
3246 | @@ -523,7 +523,7 @@ |
3247 | self.keybinding("hud/reveal") |
3248 | self.addCleanup(self.unity.hud.ensure_hidden) |
3249 | |
3250 | - self.assertThat(self.unity.hud.visible, Eventually(Equals(False))) |
3251 | + self.assertThat(self.unity.hud.visible, Eventually(Equals(True))) |
3252 | |
3253 | |
3254 | class HudLauncherInteractionsTests(HudTestsBase): |
3255 | |
3256 | === modified file 'tests/autopilot/unity/tests/test_panel.py' |
3257 | --- tests/autopilot/unity/tests/test_panel.py 2014-03-04 15:30:06 +0000 |
3258 | +++ tests/autopilot/unity/tests/test_panel.py 2015-07-15 14:19:40 +0000 |
3259 | @@ -12,6 +12,7 @@ |
3260 | #from autopilot.emulators.bamf import BamfWindow |
3261 | from autopilot.process import Window |
3262 | from autopilot.matchers import Eventually |
3263 | +from autopilot.testcase import multiply_scenarios |
3264 | import logging |
3265 | import os |
3266 | from testtools.matchers import Equals, GreaterThan, NotEquals |
3267 | @@ -25,6 +26,13 @@ |
3268 | |
3269 | logger = logging.getLogger(__name__) |
3270 | |
3271 | +def _make_scenarios(): |
3272 | + return multiply_scenarios(_make_monitor_scenarios(), |
3273 | + _make_menu_modes_scenarios()) |
3274 | + |
3275 | +def _make_menu_modes_scenarios(): |
3276 | + return [ ('Locally Integrated Menus', {'lim': True}), |
3277 | + ('Global Menus', {'lim': False}) ] |
3278 | |
3279 | def _make_monitor_scenarios(): |
3280 | num_monitors = Display.create().get_num_screens() |
3281 | @@ -38,17 +46,41 @@ |
3282 | |
3283 | return scenarios |
3284 | |
3285 | - |
3286 | class PanelTestsBase(UnityTestCase): |
3287 | |
3288 | panel_monitor = 0 |
3289 | + lim = False |
3290 | |
3291 | def setUp(self): |
3292 | super(PanelTestsBase, self).setUp() |
3293 | self.panel = self.unity.panels.get_panel_for_monitor(self.panel_monitor) |
3294 | + |
3295 | + old_lim = self.call_gsettings_cmd('get', 'com.canonical.Unity', 'integrated-menus') |
3296 | + self.call_gsettings_cmd('set', 'com.canonical.Unity', 'integrated-menus', str(self.lim).lower()) |
3297 | + self.addCleanup(self.call_gsettings_cmd, 'set', 'com.canonical.Unity', 'integrated-menus', old_lim) |
3298 | + |
3299 | + old_showmenus = self.call_gsettings_cmd('get', 'com.canonical.Unity', 'always-show-menus') |
3300 | + self.call_gsettings_cmd('set', 'com.canonical.Unity', 'always-show-menus', 'false') |
3301 | + self.addCleanup(self.call_gsettings_cmd, 'set', 'com.canonical.Unity', 'always-show-menus', old_showmenus) |
3302 | + |
3303 | self.panel.move_mouse_below_the_panel() |
3304 | self.addCleanup(self.panel.move_mouse_below_the_panel) |
3305 | |
3306 | + self.assertThat(self.panel.menus.integrated_menus, Eventually(Equals(self.lim))) |
3307 | + if not self.lim: |
3308 | + self.assertThat(self.panel.focused, Eventually(Equals(True))) |
3309 | + |
3310 | + def ensure_window_state(self, win, maximized=False): |
3311 | + if maximized and not win.is_maximized: |
3312 | + self.keybinding("window/maximize") |
3313 | + self.addCleanup(self.keybinding, "window/restore") |
3314 | + elif not maximized and win.is_maximized: |
3315 | + self.keybinding("window/restore") |
3316 | + self.addCleanup(self.keybinding, "window/maximize") |
3317 | + |
3318 | + sleep(.25) |
3319 | + self.assertProperty(win, is_maximized=maximized) |
3320 | + |
3321 | def open_new_application_window(self, app_name, maximized=False, move_to_monitor=True): |
3322 | """Opens a new instance of the requested application, ensuring that only |
3323 | one window is opened. |
3324 | @@ -68,17 +100,8 @@ |
3325 | if move_to_monitor: |
3326 | self.move_window_to_panel_monitor(app_win) |
3327 | |
3328 | - if maximized and not app_win.is_maximized: |
3329 | - self.keybinding("window/maximize") |
3330 | - self.addCleanup(self.keybinding, "window/restore") |
3331 | - elif not maximized and app_win.is_maximized: |
3332 | - self.keybinding("window/restore") |
3333 | - self.addCleanup(self.keybinding, "window/maximize") |
3334 | - |
3335 | app_win.set_focus() |
3336 | - sleep(.25) |
3337 | - |
3338 | - self.assertThat(app_win.is_maximized, Equals(maximized)) |
3339 | + self.ensure_window_state(app_win, maximized) |
3340 | |
3341 | return app_win |
3342 | |
3343 | @@ -137,9 +160,10 @@ |
3344 | |
3345 | def sleep_menu_settle_period(self): |
3346 | """Sleep long enough for the menus to fade in and fade out again.""" |
3347 | - sleep(self.panel.menus.fadein_duration / 1000.0) |
3348 | - sleep(self.panel.menus.discovery_duration) |
3349 | - sleep(self.panel.menus.fadeout_duration / 1000.0) |
3350 | + if not self.lim: |
3351 | + sleep(self.panel.menus.fadein_duration / 1000.0) |
3352 | + sleep(self.panel.menus.discovery_duration) |
3353 | + sleep(self.panel.menus.fadeout_duration / 1000.0) |
3354 | |
3355 | # Unable to exit SDM without any active apps, need a placeholder. |
3356 | # See bug LP:1079460 |
3357 | @@ -152,7 +176,7 @@ |
3358 | |
3359 | class PanelTitleTests(PanelTestsBase): |
3360 | |
3361 | - scenarios = _make_monitor_scenarios() |
3362 | + scenarios = _make_scenarios() |
3363 | |
3364 | def setUp(self): |
3365 | super(PanelTitleTests, self).setUp() |
3366 | @@ -174,13 +198,15 @@ |
3367 | """Panel must display application name for a non-maximised application.""" |
3368 | calc_win = self.open_new_application_window("Calculator", maximized=False) |
3369 | |
3370 | - self.assertThat(self.panel.title, Eventually(Equals(calc_win.application.name))) |
3371 | + expected = calc_win.application.name if not self.lim else '' |
3372 | + self.assertThat(self.panel.title, Eventually(Equals(expected))) |
3373 | |
3374 | def test_panel_title_with_maximized_application(self): |
3375 | """Panel must display application name for a maximised application.""" |
3376 | text_win = self.open_new_application_window("Text Editor", maximized=True) |
3377 | |
3378 | self.assertThat(self.panel.title, Eventually(Equals(text_win.title))) |
3379 | + self.assertThat(self.panel.focused, Eventually(Equals(True))) |
3380 | |
3381 | def test_panel_title_with_maximized_window_restored_child(self): |
3382 | """Tests the title shown in the panel when opening the restored child of |
3383 | @@ -194,14 +220,18 @@ |
3384 | |
3385 | self.assertThat(lambda: len(text_win.application.get_windows()), |
3386 | Eventually(Equals(2))) |
3387 | - self.assertThat(self.panel.title, Equals(text_win.application.name)) |
3388 | + expected = text_win.application.name if not self.lim else text_win.title |
3389 | + self.assertThat(self.panel.title, Equals(expected)) |
3390 | + self.assertThat(self.panel.focused, Eventually(Equals(not self.lim))) |
3391 | |
3392 | def test_panel_shows_app_title_with_maximised_app(self): |
3393 | """Tests app titles are shown in the panel with a non-focused maximized application.""" |
3394 | - self.open_new_application_window("Text Editor", maximized=True) |
3395 | + text_win = self.open_new_application_window("Text Editor", maximized=True) |
3396 | calc_win = self.open_new_application_window("Calculator", maximized=False) |
3397 | |
3398 | - self.assertThat(self.panel.title, Eventually(Equals(calc_win.application.name))) |
3399 | + expected = calc_win.application.name if not self.lim else text_win.title |
3400 | + self.assertThat(self.panel.title, Eventually(Equals(expected))) |
3401 | + self.assertThat(self.panel.focused, Eventually(Equals(not self.lim))) |
3402 | |
3403 | def test_panel_title_updates_when_switching_to_maximized_app(self): |
3404 | """Switching to a maximised app from a restored one must update the panel title.""" |
3405 | @@ -242,13 +272,14 @@ |
3406 | |
3407 | class PanelWindowButtonsTests(PanelTestsBase): |
3408 | |
3409 | - scenarios = _make_monitor_scenarios() |
3410 | + scenarios = _make_scenarios() |
3411 | |
3412 | def setUp(self): |
3413 | super(PanelWindowButtonsTests, self).setUp() |
3414 | # Locked Launchers on all monitors |
3415 | self.set_unity_option('num_launchers', 0) |
3416 | self.set_unity_option('launcher_hide_mode', 0) |
3417 | + self.always_visible = self.lim |
3418 | |
3419 | def test_window_buttons_dont_show_on_empty_desktop(self): |
3420 | """Tests that the window buttons are not shown on clean desktop.""" |
3421 | @@ -279,13 +310,14 @@ |
3422 | |
3423 | self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(False))) |
3424 | |
3425 | - def test_window_buttons_dont_show_for_maximized_window_on_mouse_out(self): |
3426 | - """Window buttons must not show for a maximized window when the mouse is |
3427 | - outside the panel. |
3428 | + def test_window_buttons_show_for_maximized_window_on_mouse_out(self): |
3429 | + """Window buttons might show for a maximized window when the mouse is |
3430 | + outside the panel, depending on LIM setting. |
3431 | """ |
3432 | self.open_new_application_window("Text Editor", maximized=True) |
3433 | |
3434 | - self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(False))) |
3435 | + self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(self.always_visible))) |
3436 | + self.assertThat(self.panel.window_buttons.focused, Eventually(Equals(True))) |
3437 | |
3438 | def test_window_buttons_show_for_maximized_window_on_mouse_in(self): |
3439 | """Window buttons must show when a maximized window is focused and the |
3440 | @@ -296,8 +328,30 @@ |
3441 | self.panel.move_mouse_over_window_buttons() |
3442 | |
3443 | self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(True))) |
3444 | + self.assertThat(self.panel.window_buttons.focused, Eventually(Equals(True))) |
3445 | self.assertWinButtonsInOverlayMode(False) |
3446 | |
3447 | + def test_window_buttons_show_for_maximized_unfocused_window_with_mouse_in_panel(self): |
3448 | + """Window buttons might show for an unfocused maximized window when the |
3449 | + mouse is over the panel, depending on LIM setting. |
3450 | + """ |
3451 | + self.open_new_application_window("Text Editor", maximized=True) |
3452 | + self.open_new_application_window("Calculator") |
3453 | + self.panel.move_mouse_over_window_buttons() |
3454 | + |
3455 | + self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(self.always_visible))) |
3456 | + self.assertThat(self.panel.window_buttons.focused, Eventually(Equals(not self.lim))) |
3457 | + |
3458 | + def test_window_buttons_show_for_maximized_unfocused_window_on_mouse_out(self): |
3459 | + """Window buttons might show for an unfocused maximized window when the |
3460 | + mouse is outside the panel, depending on LIM setting. |
3461 | + """ |
3462 | + self.open_new_application_window("Text Editor", maximized=True) |
3463 | + self.open_new_application_window("Calculator") |
3464 | + |
3465 | + self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(self.always_visible))) |
3466 | + self.assertThat(self.panel.window_buttons.focused, Eventually(Equals(not self.lim))) |
3467 | + |
3468 | def test_window_buttons_show_with_dash(self): |
3469 | """Window buttons must be shown when the dash is open.""" |
3470 | self.unity.dash.ensure_visible() |
3471 | @@ -340,122 +394,6 @@ |
3472 | else: |
3473 | self.assertThat(self.unity.hud.view.overlay_window_buttons_shown[monitor], Equals(False)) |
3474 | |
3475 | - def test_window_buttons_update_visual_state(self): |
3476 | - """Window button must update its state in response to mouse events.""" |
3477 | - self.open_new_application_window("Text Editor", maximized=True, move_to_monitor=True) |
3478 | - self.panel.move_mouse_over_window_buttons() |
3479 | - button = self.panel.window_buttons.unmaximize |
3480 | - |
3481 | - self.assertThat(button.visual_state, Eventually(Equals("normal"))) |
3482 | - |
3483 | - button.mouse_move_to() |
3484 | - self.assertThat(button.visual_state, Eventually(Equals("prelight"))) |
3485 | - |
3486 | - self.mouse.press() |
3487 | - self.addCleanup(self.mouse.release) |
3488 | - self.assertThat(button.visual_state, Eventually(Equals("pressed"))) |
3489 | - |
3490 | - def test_window_buttons_cancel(self): |
3491 | - """Window buttons must ignore clicks when the mouse released outside |
3492 | - their area. |
3493 | - """ |
3494 | - win = self.open_new_application_window("Text Editor", maximized=True, move_to_monitor=True) |
3495 | - self.panel.move_mouse_over_window_buttons() |
3496 | - |
3497 | - button = self.panel.window_buttons.unmaximize |
3498 | - button.mouse_move_to() |
3499 | - self.mouse.press() |
3500 | - self.assertThat(button.visual_state, Eventually(Equals("pressed"))) |
3501 | - self.panel.move_mouse_below_the_panel() |
3502 | - self.mouse.release() |
3503 | - |
3504 | - self.assertThat(win.is_maximized, Equals(True)) |
3505 | - |
3506 | - def test_window_buttons_close_button_works_for_window(self): |
3507 | - """Close window button must actually closes a window.""" |
3508 | - text_win = self.open_new_application_window("Text Editor", |
3509 | - maximized=True, |
3510 | - move_to_monitor=True) |
3511 | - win_xid = text_win.x_id |
3512 | - |
3513 | - self.panel.window_buttons.close.mouse_click() |
3514 | - self.assertNoWindowOpenWithXid(win_xid) |
3515 | - |
3516 | - def test_window_buttons_close_follows_fitts_law(self): |
3517 | - """Tests that the 'Close' button is activated when clicking at 0,0. |
3518 | - |
3519 | - See bug #839690 |
3520 | - """ |
3521 | - text_win = self.open_new_application_window("Text Editor", |
3522 | - maximized=True, |
3523 | - move_to_monitor=True) |
3524 | - win_xid = text_win.x_id |
3525 | - |
3526 | - self.panel.move_mouse_over_window_buttons() |
3527 | - screen_x, screen_y = self.display.get_screen_geometry(self.panel_monitor)[:2] |
3528 | - self.mouse.move(screen_x, screen_y) |
3529 | - self.mouse.click() |
3530 | - |
3531 | - self.assertNoWindowOpenWithXid(win_xid) |
3532 | - |
3533 | - def test_window_buttons_minimize_button_works_for_window(self): |
3534 | - """Tests that the window button 'Minimize' actually minimizes a window.""" |
3535 | - text_win = self.open_new_application_window("Text Editor", |
3536 | - maximized=True, |
3537 | - move_to_monitor=True) |
3538 | - |
3539 | - self.panel.window_buttons.minimize.mouse_click() |
3540 | - |
3541 | - self.assertProperty(text_win, is_hidden=True) |
3542 | - |
3543 | - def test_window_buttons_minimize_follows_fitts_law(self): |
3544 | - """Tests that the 'Minimize' button is conform to Fitts's Law. |
3545 | - |
3546 | - See bug #839690 |
3547 | - """ |
3548 | - text_win = self.open_new_application_window("Text Editor", |
3549 | - maximized=True, |
3550 | - move_to_monitor=True) |
3551 | - |
3552 | - self.panel.move_mouse_over_window_buttons() |
3553 | - button = self.panel.window_buttons.minimize |
3554 | - target_x = button.x + button.width / 2 |
3555 | - target_y = self.display.get_screen_geometry(self.panel_monitor)[1] |
3556 | - self.mouse.move(target_x, target_y) |
3557 | - self.mouse.click() |
3558 | - |
3559 | - self.assertProperty(text_win, is_hidden=True) |
3560 | - |
3561 | - def test_window_buttons_unmaximize_button_works_for_window(self): |
3562 | - """Tests that the window button 'Unmaximize' actually unmaximizes a window.""" |
3563 | - text_win = self.open_new_application_window("Text Editor", |
3564 | - maximized=True, |
3565 | - move_to_monitor=True) |
3566 | - |
3567 | - self.panel.window_buttons.unmaximize.mouse_click() |
3568 | - |
3569 | - self.assertProperties(text_win, is_maximized=False, is_focused=True) |
3570 | - self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(False))) |
3571 | - |
3572 | - def test_window_buttons_unmaximize_follows_fitts_law(self): |
3573 | - """Tests that the 'Unmaximize' button is conform to Fitts's Law. |
3574 | - |
3575 | - See bug #839690 |
3576 | - """ |
3577 | - text_win = self.open_new_application_window("Text Editor", |
3578 | - maximized=True, |
3579 | - move_to_monitor=True) |
3580 | - |
3581 | - button = self.panel.window_buttons.unmaximize |
3582 | - button.mouse_move_to() |
3583 | - target_x = button.x + button.width / 2 |
3584 | - target_y = self.display.get_screen_geometry(self.panel_monitor)[1] |
3585 | - self.mouse.move(target_x, target_y) |
3586 | - sleep(1) |
3587 | - self.mouse.click() |
3588 | - |
3589 | - self.assertProperty(text_win, is_maximized=False) |
3590 | - |
3591 | def test_window_buttons_close_button_works_for_hud(self): |
3592 | """Tests that the window 'Close' actually closes the HUD.""" |
3593 | self.unity.hud.ensure_visible() |
3594 | @@ -604,9 +542,7 @@ |
3595 | |
3596 | def test_minimize_button_disabled_for_non_minimizable_windows(self): |
3597 | """Minimize button must be disabled for windows that don't support minimization.""" |
3598 | - text_win = self.open_new_application_window("Text Editor", |
3599 | - maximized=False, |
3600 | - move_to_monitor=True) |
3601 | + text_win = self.open_new_application_window("Text Editor", maximized=True) |
3602 | |
3603 | self.keyboard.press_and_release("Ctrl+S") |
3604 | self.addCleanup(self.keyboard.press_and_release, "Escape") |
3605 | @@ -626,28 +562,24 @@ |
3606 | """Window buttons must be shown when mouse is over panel area with an |
3607 | indicator open. |
3608 | """ |
3609 | - self.open_new_application_window("Text Editor", |
3610 | - maximized=True, |
3611 | - move_to_monitor=True) |
3612 | + self.open_new_application_window("Text Editor", maximized=True) |
3613 | |
3614 | indicator = self.panel.indicators.get_indicator_by_name_hint("indicator-session") |
3615 | self.mouse_open_indicator(indicator) |
3616 | - self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(False))) |
3617 | + self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(self.always_visible))) |
3618 | |
3619 | self.panel.move_mouse_below_the_panel() |
3620 | - self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(False))) |
3621 | + self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(self.always_visible))) |
3622 | |
3623 | self.panel.move_mouse_over_grab_area() |
3624 | self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(True))) |
3625 | |
3626 | def test_window_buttons_show_when_holding_show_menu_key(self): |
3627 | """Window buttons must show when we press the show-menu keybinding.""" |
3628 | - self.open_new_application_window("Text Editor", |
3629 | - maximized=True, |
3630 | - move_to_monitor=True) |
3631 | + self.open_new_application_window("Text Editor", maximized=True) |
3632 | |
3633 | self.sleep_menu_settle_period() |
3634 | - self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(False))) |
3635 | + self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(self.always_visible))) |
3636 | |
3637 | self.keybinding_hold("panel/show_menus") |
3638 | self.addCleanup(self.keybinding_release, "panel/show_menus") |
3639 | @@ -657,7 +589,7 @@ |
3640 | # Sleep a bit to avoid a race with the Hud showing |
3641 | sleep(0.5) |
3642 | self.keybinding_release("panel/show_menus") |
3643 | - self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(False))) |
3644 | + self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(self.always_visible))) |
3645 | |
3646 | def test_window_buttons_cant_accept_keynav_focus(self): |
3647 | """On a mouse down event over the window buttons |
3648 | @@ -673,57 +605,149 @@ |
3649 | |
3650 | self.assertThat(self.unity.hud.search_string, Eventually(Equals("HelloWorld"))) |
3651 | |
3652 | - def test_double_click_unmaximize_window(self): |
3653 | - """Double clicking the grab area must unmaximize a maximized window.""" |
3654 | - gedit_win = self.open_new_application_window("Text Editor", maximized=True) |
3655 | - |
3656 | - self.panel.move_mouse_over_grab_area() |
3657 | - self.mouse.click() |
3658 | - self.mouse.click() |
3659 | - |
3660 | - self.assertThat(self.panel.title, Eventually(Equals(gedit_win.application.name))) |
3661 | + |
3662 | +class PanelWindowButtonsActionsTests(PanelTestsBase): |
3663 | + """Test WindowButtons actions on windows, focused or not depending on LIM""" |
3664 | + restored_on_top = False |
3665 | + scenarios = multiply_scenarios(_make_monitor_scenarios(), |
3666 | + (_make_menu_modes_scenarios() + |
3667 | + [('Locally Integrated Menus with restored on Top', |
3668 | + {'lim': True, 'restored_on_top': True})])) |
3669 | + |
3670 | + def setUp(self): |
3671 | + super(PanelWindowButtonsActionsTests, self).setUp() |
3672 | + self.text_win = self.open_new_application_window("Text Editor", maximized=True) |
3673 | + |
3674 | + if self.restored_on_top: |
3675 | + self.open_new_application_window("Calculator") |
3676 | + |
3677 | + def test_window_buttons_update_visual_state(self): |
3678 | + """Window button must update its state in response to mouse events.""" |
3679 | + self.panel.move_mouse_over_window_buttons() |
3680 | + button = self.panel.window_buttons.unmaximize |
3681 | + |
3682 | + self.assertThat(self.panel.window_buttons.focused, Eventually(Equals(not self.restored_on_top))) |
3683 | + self.assertThat(button.visual_state, Eventually(Equals("normal"))) |
3684 | + |
3685 | + button.mouse_move_to() |
3686 | + self.assertThat(button.visual_state, Eventually(Equals("prelight"))) |
3687 | + |
3688 | + self.mouse.press() |
3689 | + self.addCleanup(self.mouse.release) |
3690 | + self.assertThat(button.visual_state, Eventually(Equals("pressed"))) |
3691 | + |
3692 | + def test_window_buttons_cancel(self): |
3693 | + """Window buttons must ignore clicks when the mouse released outside |
3694 | + their area. |
3695 | + """ |
3696 | + self.panel.move_mouse_over_window_buttons() |
3697 | + |
3698 | + button = self.panel.window_buttons.unmaximize |
3699 | + button.mouse_move_to() |
3700 | + self.mouse.press() |
3701 | + self.assertThat(button.visual_state, Eventually(Equals("pressed"))) |
3702 | + self.panel.move_mouse_below_the_panel() |
3703 | + self.mouse.release() |
3704 | + |
3705 | + self.assertThat(self.text_win.is_maximized, Equals(True)) |
3706 | + |
3707 | + def test_window_buttons_close_button_works_for_window(self): |
3708 | + """Close window button must actually closes a window.""" |
3709 | + win_xid = self.text_win.x_id |
3710 | + |
3711 | + self.panel.window_buttons.close.mouse_click() |
3712 | + self.assertNoWindowOpenWithXid(win_xid) |
3713 | + |
3714 | + def test_window_buttons_close_follows_fitts_law(self): |
3715 | + """Tests that the 'Close' button is activated when clicking at 0,0. |
3716 | + |
3717 | + See bug #839690 |
3718 | + """ |
3719 | + win_xid = self.text_win.x_id |
3720 | + |
3721 | + self.panel.move_mouse_over_window_buttons() |
3722 | + screen_x, screen_y = self.display.get_screen_geometry(self.panel_monitor)[:2] |
3723 | + self.mouse.move(screen_x, screen_y) |
3724 | + self.mouse.click() |
3725 | + |
3726 | + self.assertNoWindowOpenWithXid(win_xid) |
3727 | + |
3728 | + def test_window_buttons_minimize_button_works_for_window(self): |
3729 | + """Tests that the window button 'Minimize' actually minimizes a window.""" |
3730 | + self.panel.window_buttons.minimize.mouse_click() |
3731 | + self.assertProperty(self.text_win, is_hidden=True) |
3732 | + |
3733 | + def test_window_buttons_minimize_follows_fitts_law(self): |
3734 | + """Tests that the 'Minimize' button is conform to Fitts's Law. |
3735 | + |
3736 | + See bug #839690 |
3737 | + """ |
3738 | + self.panel.move_mouse_over_window_buttons() |
3739 | + button = self.panel.window_buttons.minimize |
3740 | + target_x = button.x + button.width / 2 |
3741 | + target_y = self.display.get_screen_geometry(self.panel_monitor)[1] |
3742 | + self.mouse.move(target_x, target_y) |
3743 | + self.mouse.click() |
3744 | + |
3745 | + self.assertProperty(self.text_win, is_hidden=True) |
3746 | + |
3747 | + def test_window_buttons_unmaximize_button_works_for_window(self): |
3748 | + """Tests that the window button 'Unmaximize' actually unmaximizes a window.""" |
3749 | + self.panel.window_buttons.unmaximize.mouse_click() |
3750 | + |
3751 | + self.assertProperties(self.text_win, is_maximized=False, is_focused=True) |
3752 | + self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(False))) |
3753 | + |
3754 | + def test_window_buttons_unmaximize_follows_fitts_law(self): |
3755 | + """Tests that the 'Unmaximize' button is conform to Fitts's Law. |
3756 | + |
3757 | + See bug #839690 |
3758 | + """ |
3759 | + button = self.panel.window_buttons.unmaximize |
3760 | + button.mouse_move_to() |
3761 | + target_x = button.x + button.width / 2 |
3762 | + target_y = self.display.get_screen_geometry(self.panel_monitor)[1] |
3763 | + self.mouse.move(target_x, target_y) |
3764 | + sleep(1) |
3765 | + self.mouse.click() |
3766 | + |
3767 | + self.assertProperty(self.text_win, is_maximized=False) |
3768 | |
3769 | |
3770 | class PanelHoverTests(PanelTestsBase): |
3771 | """Tests with the mouse pointer hovering the panel area.""" |
3772 | |
3773 | - scenarios = _make_monitor_scenarios() |
3774 | + scenarios = _make_scenarios() |
3775 | |
3776 | def test_only_menus_show_for_restored_window_on_mouse_in_window_btn_area(self): |
3777 | """Restored windows should only show menus when the mouse is in the window |
3778 | button area. |
3779 | """ |
3780 | - self.open_new_application_window("Calculator", |
3781 | - maximized=False, |
3782 | - move_to_monitor=True) |
3783 | + self.open_new_application_window("Calculator") |
3784 | self.sleep_menu_settle_period() |
3785 | |
3786 | self.panel.move_mouse_over_window_buttons() |
3787 | |
3788 | - self.assertThat(self.panel.menus_shown, Eventually(Equals(True))) |
3789 | + self.assertThat(self.panel.menus_shown, Eventually(Equals(not self.lim))) |
3790 | self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(False))) |
3791 | |
3792 | def test_only_menus_show_for_restored_window_on_mouse_in_menu_area(self): |
3793 | """Restored windows should only show menus when the mouse is in the window |
3794 | menu area. |
3795 | """ |
3796 | - self.open_new_application_window("Calculator", |
3797 | - maximized=False, |
3798 | - move_to_monitor=True) |
3799 | + self.open_new_application_window("Calculator") |
3800 | self.sleep_menu_settle_period() |
3801 | |
3802 | self.panel.move_mouse_over_menus() |
3803 | |
3804 | - self.assertThat(self.panel.menus_shown, Eventually(Equals(True))) |
3805 | + self.assertThat(self.panel.menus_shown, Eventually(Equals(not self.lim))) |
3806 | self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(False))) |
3807 | |
3808 | def test_only_menus_show_for_restored_window_on_mouse_in_grab_area(self): |
3809 | """Restored windows should only show menus when the mouse is in the panel |
3810 | grab area. |
3811 | """ |
3812 | - self.open_new_application_window("Calculator", |
3813 | - maximized=False, |
3814 | - move_to_monitor=True) |
3815 | + self.open_new_application_window("Calculator") |
3816 | self.sleep_menu_settle_period() |
3817 | |
3818 | if self.panel.grab_area.width <= 0: |
3819 | @@ -731,14 +755,12 @@ |
3820 | |
3821 | self.panel.move_mouse_over_grab_area() |
3822 | |
3823 | - self.assertThat(self.panel.menus_shown, Eventually(Equals(True))) |
3824 | + self.assertThat(self.panel.menus_shown, Eventually(Equals(not self.lim))) |
3825 | self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(False))) |
3826 | |
3827 | def test_hovering_over_indicators_does_not_show_app_menus(self): |
3828 | """Hovering the mouse over the indicators must not show app menus.""" |
3829 | - self.open_new_application_window("Calculator", |
3830 | - maximized=False, |
3831 | - move_to_monitor=True) |
3832 | + self.open_new_application_window("Text Editor", maximized=True) |
3833 | self.sleep_menu_settle_period() |
3834 | |
3835 | self.panel.move_mouse_over_menus() |
3836 | @@ -754,9 +776,7 @@ |
3837 | """Menus and window buttons must be shown when the mouse is in the window |
3838 | button area for a maximised application. |
3839 | """ |
3840 | - self.open_new_application_window("Text Editor", |
3841 | - maximized=True, |
3842 | - move_to_monitor=True) |
3843 | + self.open_new_application_window("Text Editor", maximized=True) |
3844 | self.sleep_menu_settle_period() |
3845 | |
3846 | self.panel.move_mouse_over_window_buttons() |
3847 | @@ -768,9 +788,7 @@ |
3848 | """Menus and window buttons must be shown when the mouse is in the menu |
3849 | area for a maximised application. |
3850 | """ |
3851 | - self.open_new_application_window("Text Editor", |
3852 | - maximized=True, |
3853 | - move_to_monitor=True) |
3854 | + self.open_new_application_window("Text Editor", maximized=True) |
3855 | self.sleep_menu_settle_period() |
3856 | |
3857 | self.panel.move_mouse_over_menus() |
3858 | @@ -785,9 +803,7 @@ |
3859 | if self.panel.grab_area.width <= 0: |
3860 | self.skipTest("Grab area is too small to run this test!") |
3861 | |
3862 | - self.open_new_application_window("Text Editor", |
3863 | - maximized=True, |
3864 | - move_to_monitor=True) |
3865 | + self.open_new_application_window("Text Editor", maximized=True) |
3866 | self.sleep_menu_settle_period() |
3867 | |
3868 | self.panel.move_mouse_over_grab_area() |
3869 | @@ -799,9 +815,7 @@ |
3870 | """Hovering the mouse over the indicators must hide the menus and window |
3871 | buttons. |
3872 | """ |
3873 | - self.open_new_application_window("Text Editor", |
3874 | - maximized=True, |
3875 | - move_to_monitor=True) |
3876 | + self.open_new_application_window("Text Editor", maximized=True) |
3877 | self.sleep_menu_settle_period() |
3878 | |
3879 | self.panel.move_mouse_over_menus() |
3880 | @@ -811,14 +825,14 @@ |
3881 | |
3882 | self.panel.move_mouse_over_indicators() |
3883 | |
3884 | - self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(False))) |
3885 | + self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(self.lim))) |
3886 | self.assertThat(self.panel.menus_shown, Eventually(Equals(False))) |
3887 | |
3888 | def test_hovering_indicators_open_menus(self): |
3889 | """Opening an indicator entry, and then hovering on other entries must |
3890 | open them. |
3891 | """ |
3892 | - self.open_new_application_window("Text Editor") |
3893 | + self.open_new_application_window("Text Editor", maximized=self.lim) |
3894 | entries = self.panel.get_indicator_entries(include_hidden_menus=True) |
3895 | |
3896 | self.assertThat(len(entries), GreaterThan(0)) |
3897 | @@ -832,7 +846,7 @@ |
3898 | |
3899 | class PanelMenuTests(PanelTestsBase): |
3900 | |
3901 | - scenarios = _make_monitor_scenarios() |
3902 | + scenarios = _make_scenarios() |
3903 | |
3904 | def start_test_app_with_menus(self): |
3905 | window_spec = { |
3906 | @@ -846,7 +860,12 @@ |
3907 | {"Title": "&Quit"} |
3908 | ] |
3909 | } |
3910 | - self.launch_test_window(window_spec) |
3911 | + test_win = self.launch_test_window(window_spec) |
3912 | + test_win.set_focus() |
3913 | + self.move_window_to_panel_monitor(test_win) |
3914 | + self.ensure_window_state(test_win, maximized=self.lim) |
3915 | + |
3916 | + return test_win |
3917 | |
3918 | def test_menus_are_added_on_new_application(self): |
3919 | """Tests that menus are added when a new application is opened.""" |
3920 | @@ -872,10 +891,13 @@ |
3921 | "Current panel entries are: %r" % self.panel.menus.get_entries()) |
3922 | |
3923 | self.panel.move_mouse_over_grab_area() |
3924 | - self.assertThat(self.panel.title, Eventually(Equals(test_win.application.name))) |
3925 | + expected = test_win.application.name if not self.lim else "" |
3926 | + self.assertThat(self.panel.title, Eventually(Equals(expected))) |
3927 | |
3928 | def test_menus_shows_when_new_application_is_opened(self): |
3929 | """When starting a new application, menus must first show, then hide.""" |
3930 | + if self.lim: |
3931 | + self.skipTest("Menu discovery is disabled when LIM are enabled.") |
3932 | |
3933 | # This test requires the window to be opened on the monitor that is being tested and |
3934 | # we cannot guarantee which monitor the window will open up on. |
3935 | @@ -890,6 +912,9 @@ |
3936 | |
3937 | def test_menus_dont_show_if_a_new_application_window_is_opened(self): |
3938 | """This tests the menu discovery feature on new window for a know application.""" |
3939 | + if self.lim: |
3940 | + self.skipTest("Menu discovery is disabled when LIM are enabled.") |
3941 | + |
3942 | self.open_new_application_window("Character Map") |
3943 | self.sleep_menu_settle_period() |
3944 | |
3945 | @@ -917,7 +942,7 @@ |
3946 | |
3947 | self.panel.move_mouse_over_menus() |
3948 | |
3949 | - self.assertThat(self.panel.menus_shown, Eventually(Equals(True))) |
3950 | + self.assertThat(self.panel.menus_shown, Eventually(Equals(not self.lim))) |
3951 | |
3952 | def test_menus_dont_show_for_maximized_window_on_mouse_out(self): |
3953 | """Maximized window menus must not show when the mouse is outside the |
3954 | @@ -947,7 +972,7 @@ |
3955 | |
3956 | def test_menus_dont_show_with_hud(self): |
3957 | """Tests that menus are not showing when opening the HUD.""" |
3958 | - self.open_new_application_window("Text Editor", maximized=True) |
3959 | + self.open_new_application_window("Character Map", maximized=True) |
3960 | self.unity.hud.ensure_visible() |
3961 | self.addCleanup(self.unity.hud.ensure_hidden) |
3962 | |
3963 | @@ -957,11 +982,13 @@ |
3964 | class PanelIndicatorEntryTests(PanelTestsBase): |
3965 | """Tests for the indicator entries, including both menu and indicators.""" |
3966 | |
3967 | - scenarios = _make_monitor_scenarios() |
3968 | + scenarios = _make_scenarios() |
3969 | |
3970 | def open_app_and_get_menu_entry(self): |
3971 | """Open the test app and wait for the menu entry to appear.""" |
3972 | - self.open_new_application_window("Calculator") |
3973 | + self.open_new_application_window("Remmina" if self.lim else "Calculator", |
3974 | + maximized=self.lim) |
3975 | + |
3976 | refresh_fn = lambda: len(self.panel.menus.get_entries()) |
3977 | self.assertThat(refresh_fn, Eventually(GreaterThan(0))) |
3978 | menu_entry = self.panel.menus.get_entries()[0] |
3979 | @@ -1033,7 +1060,7 @@ |
3980 | |
3981 | class PanelKeyNavigationTests(PanelTestsBase): |
3982 | |
3983 | - scenarios = _make_monitor_scenarios() |
3984 | + scenarios = _make_scenarios() |
3985 | |
3986 | def get_active_indicator(self): |
3987 | """Get the active indicator in a safe manner. |
3988 | @@ -1048,17 +1075,17 @@ |
3989 | """Pressing the open-menus keybinding must open the first indicator.""" |
3990 | self.open_new_application_window("Calculator") |
3991 | refresh_fn = lambda: len(self.panel.menus.get_entries()) |
3992 | - self.assertThat(refresh_fn, Eventually(GreaterThan(0))) |
3993 | + self.assertThat(refresh_fn, Eventually(Equals(0) if self.lim else GreaterThan(0))) |
3994 | self.addCleanup(self.keyboard.press_and_release, "Escape") |
3995 | self.keybinding("panel/open_first_menu") |
3996 | |
3997 | open_indicator = self.get_active_indicator() |
3998 | - expected_indicator = self.panel.get_indicator_entries(include_hidden_menus=True)[0] |
3999 | + expected_indicator = self.panel.get_indicator_entries(include_hidden_menus=not self.lim)[0] |
4000 | self.assertThat(open_indicator.entry_id, Eventually(Equals(expected_indicator.entry_id))) |
4001 | |
4002 | def test_panel_hold_show_menu_works(self): |
4003 | """Holding the show menu key must reveal the menu with mnemonics.""" |
4004 | - self.open_new_application_window("Text Editor") |
4005 | + self.open_new_application_window("Text Editor", maximized=self.lim) |
4006 | refresh_fn = lambda: len(self.panel.menus.get_entries()) |
4007 | self.assertThat(refresh_fn, Eventually(GreaterThan(0))) |
4008 | self.addCleanup(self.keyboard.press_and_release, "Escape") |
4009 | @@ -1073,7 +1100,7 @@ |
4010 | |
4011 | def test_panel_menu_accelerators_work(self): |
4012 | """Pressing a valid menu accelerator must open the correct menu item.""" |
4013 | - self.open_new_application_window("Text Editor") |
4014 | + self.open_new_application_window("Text Editor", maximized=self.lim) |
4015 | refresh_fn = lambda: len(self.panel.menus.get_entries()) |
4016 | self.assertThat(refresh_fn, Eventually(GreaterThan(0))) |
4017 | self.addCleanup(self.keyboard.press_and_release, "Escape") |
4018 | @@ -1087,7 +1114,7 @@ |
4019 | calc_win = self.open_new_application_window("Calculator") |
4020 | self.assertProperty(calc_win, is_focused=True) |
4021 | |
4022 | - available_indicators = self.panel.get_indicator_entries(include_hidden_menus=True) |
4023 | + available_indicators = self.panel.get_indicator_entries(include_hidden_menus=not self.lim) |
4024 | |
4025 | self.keybinding("panel/open_first_menu") |
4026 | self.addCleanup(self.keyboard.press_and_release, "Escape") |
4027 | @@ -1102,7 +1129,7 @@ |
4028 | calc_win = self.open_new_application_window("Calculator") |
4029 | self.assertProperty(calc_win, is_focused=True) |
4030 | |
4031 | - available_indicators = self.panel.get_indicator_entries(include_hidden_menus=True) |
4032 | + available_indicators = self.panel.get_indicator_entries(include_hidden_menus=not self.lim) |
4033 | |
4034 | self.keybinding("panel/open_first_menu") |
4035 | self.addCleanup(self.keyboard.press_and_release, "Escape") |
4036 | @@ -1118,14 +1145,12 @@ |
4037 | opened with the keyboard. |
4038 | """ |
4039 | self.open_new_application_window("Calculator") |
4040 | - available_indicators = self.panel.get_indicator_entries(include_hidden_menus=True) |
4041 | + available_indicators = self.panel.get_indicator_entries(include_hidden_menus=not self.lim) |
4042 | |
4043 | self.keybinding("panel/open_first_menu") |
4044 | self.addCleanup(self.keyboard.press_and_release, "Escape") |
4045 | |
4046 | available_indicators[2].mouse_move_to() |
4047 | - self.addCleanup(self.panel.move_mouse_below_the_panel) |
4048 | - |
4049 | self.assertThat(available_indicators[2].active, Eventually(Equals(True))) |
4050 | |
4051 | self.keybinding("panel/prev_indicator") |
4052 | @@ -1135,11 +1160,10 @@ |
4053 | class PanelGrabAreaTests(PanelTestsBase): |
4054 | """Panel grab area tests.""" |
4055 | |
4056 | - scenarios = _make_monitor_scenarios() |
4057 | + scenarios = _make_scenarios() |
4058 | |
4059 | def move_mouse_over_grab_area(self): |
4060 | self.panel.move_mouse_over_grab_area() |
4061 | - self.addCleanup(self.panel.move_mouse_below_the_panel) |
4062 | sleep(.1) |
4063 | |
4064 | def test_unmaximize_from_grab_area_works(self): |
4065 | @@ -1192,6 +1216,29 @@ |
4066 | self.assertThat(self.unity.hud.search_string, Eventually(Equals("HelloWorld"))) |
4067 | |
4068 | |
4069 | +class PanelLimTests(PanelTestsBase): |
4070 | + |
4071 | + scenarios = _make_monitor_scenarios() |
4072 | + |
4073 | + def setUp(self): |
4074 | + self.lim = True |
4075 | + super(PanelLimTests, self).setUp() |
4076 | + |
4077 | + def test_title_focus_on_maximized_state_changes(self): |
4078 | + text_win = self.open_new_application_window("Text Editor", maximized=True) |
4079 | + self.assertThat(self.panel.focused, Eventually(Equals(True))) |
4080 | + self.assertThat(self.panel.title, Eventually(Equals(text_win.title))) |
4081 | + |
4082 | + self.open_new_application_window("Calculator") |
4083 | + self.assertThat(self.panel.focused, Eventually(Equals(False))) |
4084 | + self.assertThat(self.panel.title, Eventually(Equals(text_win.title))) |
4085 | + |
4086 | + text_win.set_focus() |
4087 | + self.assertProperty(text_win, is_focused=True) |
4088 | + self.assertThat(self.panel.focused, Eventually(Equals(True))) |
4089 | + self.assertThat(self.panel.title, Eventually(Equals(text_win.title))) |
4090 | + |
4091 | + |
4092 | class PanelCrossMonitorsTests(PanelTestsBase): |
4093 | """Multimonitor panel tests.""" |
4094 | |
4095 | |
4096 | === modified file 'tests/autopilot/unity/tests/test_wm_keybindings.py' |
4097 | --- tests/autopilot/unity/tests/test_wm_keybindings.py 2013-12-04 19:42:43 +0000 |
4098 | +++ tests/autopilot/unity/tests/test_wm_keybindings.py 2015-07-15 14:19:40 +0000 |
4099 | @@ -21,27 +21,24 @@ |
4100 | |
4101 | def open_panel_menu(self): |
4102 | panel = self.unity.panels.get_panel_for_monitor(0) |
4103 | - self.assertThat(lambda: len(panel.menus.get_entries()), Eventually(GreaterThan(0))) |
4104 | + self.assertThat(lambda: len(panel.get_indicator_entries()), Eventually(GreaterThan(0))) |
4105 | self.addCleanup(self.keyboard.press_and_release, "Escape") |
4106 | self.keybinding("panel/open_first_menu") |
4107 | self.assertThat(self.unity.panels.get_active_indicator, Eventually(NotEquals(None))) |
4108 | |
4109 | def test_dash_shows_on_menus_opened(self): |
4110 | - self.process_manager.start_app_window("Calculator") |
4111 | self.open_panel_menu() |
4112 | self.addCleanup(self.unity.dash.ensure_hidden) |
4113 | self.unity.dash.ensure_visible() |
4114 | self.assertThat(self.unity.panels.get_active_indicator, Eventually(Equals(None))) |
4115 | |
4116 | def test_hud_shows_on_menus_opened(self): |
4117 | - self.process_manager.start_app_window("Calculator") |
4118 | self.open_panel_menu() |
4119 | self.addCleanup(self.unity.hud.ensure_hidden) |
4120 | self.unity.hud.ensure_visible() |
4121 | self.assertThat(self.unity.panels.get_active_indicator, Eventually(Equals(None))) |
4122 | |
4123 | def test_switcher_shows_on_menus_opened(self): |
4124 | - self.process_manager.start_app_window("Calculator") |
4125 | self.open_panel_menu() |
4126 | self.addCleanup(self.unity.switcher.terminate) |
4127 | self.unity.switcher.initiate() |
4128 | @@ -49,7 +46,6 @@ |
4129 | self.assertThat(self.unity.panels.get_active_indicator, Eventually(Equals(None))) |
4130 | |
4131 | def test_shortcut_hints_shows_on_menus_opened(self): |
4132 | - self.process_manager.start_app_window("Calculator") |
4133 | self.open_panel_menu() |
4134 | self.addCleanup(self.unity.shortcut_hint.ensure_hidden) |
4135 | self.unity.shortcut_hint.show() |
4136 | @@ -57,7 +53,6 @@ |
4137 | self.assertThat(self.unity.panels.get_active_indicator, Eventually(Equals(None))) |
4138 | |
4139 | def test_spread_shows_on_menus_opened(self): |
4140 | - self.process_manager.start_app_window("Calculator") |
4141 | self.open_panel_menu() |
4142 | self.addCleanup(self.unity.window_manager.terminate_spread) |
4143 | self.unity.window_manager.initiate_spread() |
4144 | |
4145 | === modified file 'tests/mock-application.h' |
4146 | --- tests/mock-application.h 2014-03-21 04:40:12 +0000 |
4147 | +++ tests/mock-application.h 2015-07-15 14:19:40 +0000 |
4148 | @@ -20,7 +20,7 @@ |
4149 | #ifndef TESTS_MOCK_APPLICATION_H |
4150 | #define TESTS_MOCK_APPLICATION_H |
4151 | |
4152 | -#include <map> |
4153 | +#include <unordered_map> |
4154 | #include <gmock/gmock.h> |
4155 | #include <gio/gdesktopappinfo.h> |
4156 | #include <UnityCore/GLibWrapper.h> |
4157 | @@ -360,7 +360,7 @@ |
4158 | } |
4159 | |
4160 | private: |
4161 | - typedef std::map<std::string, unity::ApplicationPtr> AppMap; |
4162 | + typedef std::unordered_map<std::string, unity::ApplicationPtr> AppMap; |
4163 | AppMap app_map_; |
4164 | }; |
4165 | |
4166 | |
4167 | === modified file 'tests/test_dbus_indicators.cpp' |
4168 | --- tests/test_dbus_indicators.cpp 2013-03-25 18:22:32 +0000 |
4169 | +++ tests/test_dbus_indicators.cpp 2015-07-15 14:19:40 +0000 |
4170 | @@ -5,6 +5,7 @@ |
4171 | #include <UnityCore/GLibWrapper.h> |
4172 | #include <UnityCore/DBusIndicators.h> |
4173 | |
4174 | +#include "panel-service-private.h" |
4175 | #include "test_utils.h" |
4176 | |
4177 | using namespace unity; |
4178 | @@ -50,10 +51,8 @@ |
4179 | |
4180 | GVariant* CallPanelMethod(std::string const& name) const |
4181 | { |
4182 | - return g_dbus_connection_call_sync(session, |
4183 | - "com.canonical.Unity.Test", |
4184 | - "/com/canonical/Unity/Panel/Service", |
4185 | - "com.canonical.Unity.Panel.Service", |
4186 | + return g_dbus_connection_call_sync(session, "com.canonical.Unity.Test", |
4187 | + UPS_PATH, UPS_IFACE, |
4188 | name.c_str(), |
4189 | NULL, |
4190 | NULL, |
4191 | |
4192 | === modified file 'tests/test_indicator.cpp' |
4193 | --- tests/test_indicator.cpp 2014-01-27 17:31:30 +0000 |
4194 | +++ tests/test_indicator.cpp 2015-07-15 14:19:40 +0000 |
4195 | @@ -44,7 +44,7 @@ |
4196 | |
4197 | MOCK_CONST_METHOD0(Updated, void()); |
4198 | MOCK_CONST_METHOD1(EntryAdded, void(Entry::Ptr const&)); |
4199 | - MOCK_CONST_METHOD1(EntryRemoved, void(std::string const&)); |
4200 | + MOCK_CONST_METHOD1(EntryRemoved, void(Entry::Ptr const&)); |
4201 | MOCK_CONST_METHOD5(ShowMenu, void(std::string const&, unsigned, int, int, unsigned)); |
4202 | MOCK_CONST_METHOD1(SecondaryActivate, void(std::string const&)); |
4203 | MOCK_CONST_METHOD2(Scroll, void(std::string const&, int)); |
4204 | @@ -57,7 +57,6 @@ |
4205 | EXPECT_EQ(indicator.name(), "indicator-test"); |
4206 | EXPECT_FALSE(indicator.IsAppmenu()); |
4207 | EXPECT_EQ(indicator.GetEntry("test-entry"), nullptr); |
4208 | - EXPECT_EQ(indicator.EntryIndex("test-entry"), -1); |
4209 | EXPECT_TRUE(indicator.GetEntries().empty()); |
4210 | } |
4211 | |
4212 | @@ -69,17 +68,17 @@ |
4213 | Indicator indicator("indicator-test"); |
4214 | SigReceiver::Nice sig_receiver(indicator); |
4215 | |
4216 | - entry = new Entry("test-entry-1", "name-hint", "label", true, true, 0, "icon", |
4217 | + entry = new Entry("test-entry-1", "name-hint", 0, "label", true, true, 0, "icon", |
4218 | true, true, -1); |
4219 | Entry::Ptr entry1(entry); |
4220 | sync_data.push_back(entry1); |
4221 | |
4222 | - entry = new Entry("test-entry-2", "name-hint", "label", true, true, 0, "icon", |
4223 | + entry = new Entry("test-entry-2", "name-hint", 0, "label", true, true, 0, "icon", |
4224 | true, true, -1); |
4225 | Entry::Ptr entry2(entry); |
4226 | sync_data.push_back(entry2); |
4227 | |
4228 | - entry = new Entry("test-entry-3", "name-hint", "label", true, true, 0, "icon", |
4229 | + entry = new Entry("test-entry-3", "name-hint", 0, "label", true, true, 0, "icon", |
4230 | true, true, -1); |
4231 | Entry::Ptr entry3(entry); |
4232 | sync_data.push_back(entry3); |
4233 | @@ -97,31 +96,29 @@ |
4234 | indicator.Sync(sync_data); |
4235 | EXPECT_EQ(indicator.GetEntries().size(), 3); |
4236 | EXPECT_EQ(indicator.GetEntry("test-entry-2"), entry2); |
4237 | - EXPECT_EQ(indicator.EntryIndex("test-entry-2"), 1); |
4238 | // Mock::VerifyAndClearExpectations(&sig_receiver); |
4239 | |
4240 | // Sync the indicator removing an entry |
4241 | - sync_data.remove(entry2); |
4242 | + sync_data.erase(std::remove(sync_data.begin(), sync_data.end(), entry2), sync_data.end()); |
4243 | EXPECT_EQ(sync_data.size(), 2); |
4244 | EXPECT_CALL(sig_receiver, Updated()); |
4245 | EXPECT_CALL(sig_receiver, EntryAdded(_)).Times(0); |
4246 | - EXPECT_CALL(sig_receiver, EntryRemoved(entry2->id())); |
4247 | + EXPECT_CALL(sig_receiver, EntryRemoved(entry2)); |
4248 | |
4249 | indicator.Sync(sync_data); |
4250 | EXPECT_EQ(indicator.GetEntries().size(), 2); |
4251 | EXPECT_EQ(indicator.GetEntry("test-entry-2"), nullptr); |
4252 | - EXPECT_EQ(indicator.EntryIndex("test-entry-2"), -1); |
4253 | |
4254 | // Sync the indicator removing an entry and adding a new one |
4255 | - entry = new Entry("test-entry-4", "name-hint", "label", true, true, 0, "icon", |
4256 | + entry = new Entry("test-entry-4", "name-hint", 0, "label", true, true, 0, "icon", |
4257 | true, true, -1); |
4258 | Entry::Ptr entry4(entry); |
4259 | sync_data.push_back(entry4); |
4260 | - sync_data.remove(entry3); |
4261 | + sync_data.erase(std::remove(sync_data.begin(), sync_data.end(), entry3), sync_data.end()); |
4262 | EXPECT_EQ(sync_data.size(), 2); |
4263 | |
4264 | EXPECT_CALL(sig_receiver, EntryAdded(entry4)); |
4265 | - EXPECT_CALL(sig_receiver, EntryRemoved(entry3->id())); |
4266 | + EXPECT_CALL(sig_receiver, EntryRemoved(entry3)); |
4267 | EXPECT_CALL(sig_receiver, Updated()); |
4268 | indicator.Sync(sync_data); |
4269 | EXPECT_EQ(indicator.GetEntries().size(), 2); |
4270 | @@ -129,8 +126,8 @@ |
4271 | // Remove all the indicators |
4272 | |
4273 | EXPECT_CALL(sig_receiver, EntryAdded(_)).Times(0); |
4274 | - EXPECT_CALL(sig_receiver, EntryRemoved(entry1->id())); |
4275 | - EXPECT_CALL(sig_receiver, EntryRemoved(entry4->id())); |
4276 | + EXPECT_CALL(sig_receiver, EntryRemoved(entry1)); |
4277 | + EXPECT_CALL(sig_receiver, EntryRemoved(entry4)); |
4278 | EXPECT_CALL(sig_receiver, Updated()); |
4279 | |
4280 | sync_data.clear(); |
4281 | @@ -144,13 +141,13 @@ |
4282 | SigReceiver::Nice sig_receiver(indicator); |
4283 | Indicator::Entries sync_data; |
4284 | |
4285 | - auto entry1 = std::make_shared<Entry>("test-entry-1", "name-hint", "label", true, true, 0, "icon", true, true, -1); |
4286 | + auto entry1 = std::make_shared<Entry>("test-entry-1", "name-hint", 0, "label", true, true, 0, "icon", true, true, -1); |
4287 | sync_data.push_back(entry1); |
4288 | |
4289 | - auto entry2 = std::make_shared<Entry>("test-entry-2", "name-hint", "label", true, true, 0, "icon", true, true, -1); |
4290 | + auto entry2 = std::make_shared<Entry>("test-entry-2", "name-hint", 0, "label", true, true, 0, "icon", true, true, -1); |
4291 | sync_data.push_back(entry2); |
4292 | |
4293 | - auto entry3 = std::make_shared<Entry>("test-entry-3", "name-hint", "label", true, true, 0, "icon", true, true, -1); |
4294 | + auto entry3 = std::make_shared<Entry>("test-entry-3", "name-hint", 0, "label", true, true, 0, "icon", true, true, -1); |
4295 | sync_data.push_back(entry3); |
4296 | |
4297 | EXPECT_CALL(sig_receiver, Updated()); |
4298 | @@ -162,7 +159,7 @@ |
4299 | EXPECT_CALL(sig_receiver, Updated()).Times(0); |
4300 | indicator.Sync(sync_data); |
4301 | |
4302 | - sync_data.remove(entry3); |
4303 | + sync_data.erase(std::remove(sync_data.begin(), sync_data.end(), entry3), sync_data.end()); |
4304 | EXPECT_CALL(sig_receiver, Updated()); |
4305 | indicator.Sync(sync_data); |
4306 | |
4307 | @@ -176,7 +173,7 @@ |
4308 | Indicator indicator("indicator-test"); |
4309 | SigReceiver::Nice sig_receiver(indicator); |
4310 | |
4311 | - auto entry = std::make_shared<Entry>("test-entry-1", "name-hint", "label", true, true, 0, "icon", true, true, -1); |
4312 | + auto entry = std::make_shared<Entry>("test-entry-1", "name-hint", 0, "label", true, true, 0, "icon", true, true, -1); |
4313 | indicator.Sync({entry}); |
4314 | |
4315 | EXPECT_CALL(sig_receiver, ShowMenu(entry->id(), 123456789, 50, 100, 2)); |
4316 | @@ -194,7 +191,7 @@ |
4317 | Indicator indicator("indicator-test"); |
4318 | SigReceiver::Nice sig_receiver(indicator); |
4319 | |
4320 | - auto entry = std::make_shared<Entry>("test-entry-2", "name-hint", "label", true, true, 0, "icon", true, true, -1); |
4321 | + auto entry = std::make_shared<Entry>("test-entry-2", "name-hint", 0, "label", true, true, 0, "icon", true, true, -1); |
4322 | indicator.Sync({entry}); |
4323 | |
4324 | EXPECT_CALL(sig_receiver, SecondaryActivate(entry->id())); |
4325 | @@ -206,7 +203,7 @@ |
4326 | Indicator indicator("indicator-test"); |
4327 | SigReceiver::Nice sig_receiver(indicator); |
4328 | |
4329 | - auto entry = std::make_shared<Entry>("test-entry-2", "name-hint", "label", true, true, 0, "icon", true, true, -1); |
4330 | + auto entry = std::make_shared<Entry>("test-entry-2", "name-hint", 0, "label", true, true, 0, "icon", true, true, -1); |
4331 | indicator.Sync({entry}); |
4332 | |
4333 | EXPECT_CALL(sig_receiver, Scroll(entry->id(), -5)); |
4334 | |
4335 | === modified file 'tests/test_indicator_appmenu.cpp' |
4336 | --- tests/test_indicator_appmenu.cpp 2012-12-04 00:33:18 +0000 |
4337 | +++ tests/test_indicator_appmenu.cpp 2015-07-15 14:19:40 +0000 |
4338 | @@ -1,6 +1,6 @@ |
4339 | // -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- |
4340 | /* |
4341 | - * Copyright (C) 2012 Canonical Ltd |
4342 | + * Copyright (C) 2012-2015 Canonical Ltd |
4343 | * |
4344 | * This program is free software: you can redistribute it and/or modify |
4345 | * it under the terms of the GNU General Public License version 3 as |
4346 | @@ -18,15 +18,41 @@ |
4347 | */ |
4348 | |
4349 | #include <UnityCore/AppmenuIndicator.h> |
4350 | - |
4351 | -#include <gtest/gtest.h> |
4352 | +#include <gmock/gmock.h> |
4353 | |
4354 | using namespace std; |
4355 | using namespace unity; |
4356 | using namespace indicator; |
4357 | +using namespace testing; |
4358 | |
4359 | namespace |
4360 | { |
4361 | +struct SigReceiver : sigc::trackable |
4362 | +{ |
4363 | + typedef NiceMock<SigReceiver> Nice; |
4364 | + |
4365 | + SigReceiver(AppmenuIndicator const& const_indicator) |
4366 | + { |
4367 | + auto& indicator = const_cast<AppmenuIndicator&>(const_indicator); |
4368 | + indicator.updated.connect(sigc::mem_fun(this, &SigReceiver::Updated)); |
4369 | + indicator.updated_win.connect(sigc::mem_fun(this, &SigReceiver::UpdatedWin)); |
4370 | + indicator.on_entry_added.connect(sigc::mem_fun(this, &SigReceiver::EntryAdded)); |
4371 | + indicator.on_entry_removed.connect(sigc::mem_fun(this, &SigReceiver::EntryRemoved)); |
4372 | + indicator.on_show_menu.connect(sigc::mem_fun(this, &SigReceiver::ShowMenu)); |
4373 | + indicator.on_show_appmenu.connect(sigc::mem_fun(this, &SigReceiver::ShowAppmenu)); |
4374 | + indicator.on_secondary_activate.connect(sigc::mem_fun(this, &SigReceiver::SecondaryActivate)); |
4375 | + indicator.on_scroll.connect(sigc::mem_fun(this, &SigReceiver::Scroll)); |
4376 | + } |
4377 | + |
4378 | + MOCK_CONST_METHOD0(Updated, void()); |
4379 | + MOCK_CONST_METHOD1(UpdatedWin, void(uint32_t)); |
4380 | + MOCK_CONST_METHOD1(EntryAdded, void(Entry::Ptr const&)); |
4381 | + MOCK_CONST_METHOD1(EntryRemoved, void(Entry::Ptr const&)); |
4382 | + MOCK_CONST_METHOD5(ShowMenu, void(std::string const&, unsigned, int, int, unsigned)); |
4383 | + MOCK_CONST_METHOD3(ShowAppmenu, void(unsigned, int, int)); |
4384 | + MOCK_CONST_METHOD1(SecondaryActivate, void(std::string const&)); |
4385 | + MOCK_CONST_METHOD2(Scroll, void(std::string const&, int)); |
4386 | +}; |
4387 | |
4388 | TEST(TestAppmenuIndicator, Construction) |
4389 | { |
4390 | @@ -39,25 +65,160 @@ |
4391 | TEST(TestAppmenuIndicator, ShowAppmenu) |
4392 | { |
4393 | AppmenuIndicator indicator("indicator-appmenu"); |
4394 | - |
4395 | - bool signal_emitted = false; |
4396 | - int show_x, show_y; |
4397 | - unsigned show_xid; |
4398 | - |
4399 | - // Connecting to signals |
4400 | - indicator.on_show_appmenu.connect([&] (unsigned int xid, int x, int y) { |
4401 | - signal_emitted = true; |
4402 | - show_xid = xid; |
4403 | - show_x = x; |
4404 | - show_y = y; |
4405 | - }); |
4406 | - |
4407 | + SigReceiver::Nice sig_receiver(indicator); |
4408 | + |
4409 | + EXPECT_CALL(sig_receiver, ShowAppmenu(123456789, 50, 100)); |
4410 | indicator.ShowAppmenu(123456789, 50, 100); |
4411 | - EXPECT_TRUE(signal_emitted); |
4412 | - |
4413 | - EXPECT_EQ(show_xid, 123456789); |
4414 | - EXPECT_EQ(show_x, 50); |
4415 | - EXPECT_EQ(show_y, 100); |
4416 | +} |
4417 | + |
4418 | +TEST(TestAppmenuIndicator, Syncing) |
4419 | +{ |
4420 | + Indicator::Entries sync_data; |
4421 | + |
4422 | + AppmenuIndicator indicator("indicator-appmenu"); |
4423 | + SigReceiver::Nice sig_receiver(indicator); |
4424 | + const uint32_t parent_window1 = 12345; |
4425 | + const uint32_t parent_window2 = 54321; |
4426 | + |
4427 | + auto entry1 = std::make_shared<Entry>("test-entry-1", "name-hint", parent_window1, "label", true, true, 0, "icon", true, true, -1); |
4428 | + sync_data.push_back(entry1); |
4429 | + |
4430 | + auto entry2 = std::make_shared<Entry>("test-entry-2", "name-hint", parent_window1, "label", true, true, 0, "icon", true, true, -1); |
4431 | + sync_data.push_back(entry2); |
4432 | + |
4433 | + auto entry3 = std::make_shared<Entry>("test-entry-3", "name-hint", parent_window2, "label", true, true, 0, "icon", true, true, -1); |
4434 | + sync_data.push_back(entry3); |
4435 | + |
4436 | + // Sync the indicator, adding 3 entries |
4437 | + { |
4438 | + testing::InSequence s; |
4439 | + EXPECT_CALL(sig_receiver, EntryAdded(entry1)); |
4440 | + EXPECT_CALL(sig_receiver, EntryAdded(entry2)); |
4441 | + EXPECT_CALL(sig_receiver, EntryAdded(entry3)); |
4442 | + EXPECT_CALL(sig_receiver, EntryRemoved(_)).Times(0); |
4443 | + EXPECT_CALL(sig_receiver, Updated()); |
4444 | + } |
4445 | + |
4446 | + EXPECT_CALL(sig_receiver, UpdatedWin(parent_window1)); |
4447 | + EXPECT_CALL(sig_receiver, UpdatedWin(parent_window2)); |
4448 | + |
4449 | + indicator.Sync(sync_data); |
4450 | + EXPECT_EQ(indicator.GetEntriesForWindow(parent_window1), Indicator::Entries({entry1, entry2})); |
4451 | + EXPECT_EQ(indicator.GetEntriesForWindow(parent_window2), Indicator::Entries({entry3})); |
4452 | + |
4453 | + // Sync the indicator removing an entry |
4454 | + sync_data.erase(std::remove(sync_data.begin(), sync_data.end(), entry2), sync_data.end()); |
4455 | + ASSERT_EQ(sync_data.size(), 2); |
4456 | + EXPECT_CALL(sig_receiver, Updated()); |
4457 | + EXPECT_CALL(sig_receiver, UpdatedWin(parent_window1)); |
4458 | + EXPECT_CALL(sig_receiver, UpdatedWin(parent_window2)).Times(0); |
4459 | + EXPECT_CALL(sig_receiver, EntryAdded(_)).Times(0); |
4460 | + EXPECT_CALL(sig_receiver, EntryRemoved(entry2)); |
4461 | + |
4462 | + indicator.Sync(sync_data); |
4463 | + EXPECT_EQ(indicator.GetEntries().size(), 2); |
4464 | + EXPECT_EQ(indicator.GetEntry("test-entry-2"), nullptr); |
4465 | + EXPECT_EQ(indicator.GetEntriesForWindow(parent_window1), Indicator::Entries({entry1})); |
4466 | + |
4467 | + // Sync the indicator removing an entry and adding a new one |
4468 | + auto entry4 = std::make_shared<Entry>("test-entry-4", "name-hint", parent_window2, "label", true, true, 0, "icon", true, true, -1); |
4469 | + sync_data.push_back(entry4); |
4470 | + sync_data.erase(std::remove(sync_data.begin(), sync_data.end(), entry3), sync_data.end()); |
4471 | + EXPECT_EQ(sync_data.size(), 2); |
4472 | + |
4473 | + EXPECT_CALL(sig_receiver, EntryAdded(entry4)); |
4474 | + EXPECT_CALL(sig_receiver, EntryRemoved(entry3)); |
4475 | + EXPECT_CALL(sig_receiver, Updated()); |
4476 | + EXPECT_CALL(sig_receiver, UpdatedWin(parent_window1)).Times(0); |
4477 | + EXPECT_CALL(sig_receiver, UpdatedWin(parent_window2)); |
4478 | + indicator.Sync(sync_data); |
4479 | + EXPECT_EQ(indicator.GetEntriesForWindow(parent_window1), Indicator::Entries({entry1})); |
4480 | + EXPECT_EQ(indicator.GetEntriesForWindow(parent_window2), Indicator::Entries({entry4})); |
4481 | + |
4482 | + // Remove all the indicators |
4483 | + EXPECT_CALL(sig_receiver, EntryAdded(_)).Times(0); |
4484 | + EXPECT_CALL(sig_receiver, EntryRemoved(entry1)); |
4485 | + EXPECT_CALL(sig_receiver, EntryRemoved(entry4)); |
4486 | + EXPECT_CALL(sig_receiver, Updated()); |
4487 | + EXPECT_CALL(sig_receiver, UpdatedWin(parent_window1)); |
4488 | + EXPECT_CALL(sig_receiver, UpdatedWin(parent_window2)); |
4489 | + |
4490 | + sync_data.clear(); |
4491 | + indicator.Sync(sync_data); |
4492 | + |
4493 | + EXPECT_TRUE(indicator.GetEntriesForWindow(parent_window1).empty()); |
4494 | + EXPECT_TRUE(indicator.GetEntriesForWindow(parent_window2).empty()); |
4495 | +} |
4496 | + |
4497 | +TEST(TestAppmenuIndicator, Updated) |
4498 | +{ |
4499 | + AppmenuIndicator indicator("indicator-test"); |
4500 | + SigReceiver::Nice sig_receiver(indicator); |
4501 | + Indicator::Entries sync_data; |
4502 | + const uint32_t parent_window1 = 12345; |
4503 | + const uint32_t parent_window2 = 54321; |
4504 | + |
4505 | + auto entry1 = std::make_shared<Entry>("test-entry-1", "name-hint", parent_window1, "label", true, true, 0, "icon", true, true, -1); |
4506 | + sync_data.push_back(entry1); |
4507 | + |
4508 | + auto entry2 = std::make_shared<Entry>("test-entry-2", "name-hint", parent_window2, "label", true, true, 0, "icon", true, true, -1); |
4509 | + sync_data.push_back(entry2); |
4510 | + |
4511 | + auto entry3 = std::make_shared<Entry>("test-entry-3", "name-hint", parent_window1, "label", true, true, 0, "icon", true, true, -1); |
4512 | + sync_data.push_back(entry3); |
4513 | + |
4514 | + EXPECT_CALL(sig_receiver, Updated()); |
4515 | + |
4516 | + // Sync the indicator, adding 3 entries |
4517 | + indicator.Sync(sync_data); |
4518 | + |
4519 | + // Readding the same entries, nothing is emitted |
4520 | + EXPECT_CALL(sig_receiver, Updated()).Times(0); |
4521 | + indicator.Sync(sync_data); |
4522 | + |
4523 | + sync_data.erase(std::remove(sync_data.begin(), sync_data.end(), entry3), sync_data.end()); |
4524 | + EXPECT_CALL(sig_receiver, Updated()); |
4525 | + indicator.Sync(sync_data); |
4526 | + |
4527 | + sync_data.push_back(entry3); |
4528 | + EXPECT_CALL(sig_receiver, Updated()); |
4529 | + indicator.Sync(sync_data); |
4530 | +} |
4531 | + |
4532 | +TEST(TestAppmenuIndicator, UpdatedWin) |
4533 | +{ |
4534 | + AppmenuIndicator indicator("indicator-test"); |
4535 | + SigReceiver::Nice sig_receiver(indicator); |
4536 | + Indicator::Entries sync_data; |
4537 | + const uint32_t parent_window1 = 12345; |
4538 | + const uint32_t parent_window2 = 54321; |
4539 | + |
4540 | + auto entry1 = std::make_shared<Entry>("test-entry-1", "name-hint", parent_window1, "label", true, true, 0, "icon", true, true, -1); |
4541 | + sync_data.push_back(entry1); |
4542 | + |
4543 | + auto entry2 = std::make_shared<Entry>("test-entry-2", "name-hint", parent_window2, "label", true, true, 0, "icon", true, true, -1); |
4544 | + sync_data.push_back(entry2); |
4545 | + |
4546 | + auto entry3 = std::make_shared<Entry>("test-entry-3", "name-hint", parent_window1, "label", true, true, 0, "icon", true, true, -1); |
4547 | + sync_data.push_back(entry3); |
4548 | + |
4549 | + EXPECT_CALL(sig_receiver, UpdatedWin(parent_window1)); |
4550 | + EXPECT_CALL(sig_receiver, UpdatedWin(parent_window2)); |
4551 | + |
4552 | + // Sync the indicator, adding 3 entries |
4553 | + indicator.Sync(sync_data); |
4554 | + |
4555 | + // Readding the same entries, nothing is emitted |
4556 | + EXPECT_CALL(sig_receiver, UpdatedWin(_)).Times(0); |
4557 | + indicator.Sync(sync_data); |
4558 | + |
4559 | + sync_data.erase(std::remove(sync_data.begin(), sync_data.end(), entry3), sync_data.end()); |
4560 | + EXPECT_CALL(sig_receiver, UpdatedWin(entry3->parent_window())); |
4561 | + indicator.Sync(sync_data); |
4562 | + |
4563 | + sync_data.push_back(entry3); |
4564 | + EXPECT_CALL(sig_receiver, UpdatedWin(entry3->parent_window())); |
4565 | + indicator.Sync(sync_data); |
4566 | } |
4567 | |
4568 | } |
4569 | |
4570 | === modified file 'tests/test_indicator_entry.cpp' |
4571 | --- tests/test_indicator_entry.cpp 2014-02-07 23:54:15 +0000 |
4572 | +++ tests/test_indicator_entry.cpp 2015-07-15 14:19:40 +0000 |
4573 | @@ -36,11 +36,12 @@ |
4574 | TEST(TestIndicatorEntry, TestConstruction) |
4575 | { |
4576 | |
4577 | - Entry entry("id", "name_hint", "label", true, true, 1, "some icon", false, true, -1); |
4578 | + Entry entry("id", "name_hint", 12345, "label", true, true, 1, "some icon", false, true, -1); |
4579 | |
4580 | EXPECT_EQ(entry.id(), "id"); |
4581 | + EXPECT_EQ(entry.name_hint(), "name_hint"); |
4582 | + EXPECT_EQ(entry.parent_window(), 12345); |
4583 | EXPECT_EQ(entry.label(), "label"); |
4584 | - EXPECT_EQ(entry.name_hint(), "name_hint"); |
4585 | EXPECT_TRUE(entry.label_sensitive()); |
4586 | EXPECT_TRUE(entry.label_visible()); |
4587 | EXPECT_FALSE(entry.image_sensitive()); |
4588 | @@ -55,10 +56,11 @@ |
4589 | |
4590 | TEST(TestIndicatorEntry, TestConstructionEmpty) |
4591 | { |
4592 | - Entry entry("id", "name_hint"); |
4593 | + Entry entry("id", "name_hint", 12345); |
4594 | |
4595 | EXPECT_EQ(entry.id(), "id"); |
4596 | EXPECT_EQ(entry.name_hint(), "name_hint"); |
4597 | + EXPECT_EQ(entry.parent_window(), 12345); |
4598 | EXPECT_TRUE(entry.label().empty()); |
4599 | EXPECT_FALSE(entry.label_sensitive()); |
4600 | EXPECT_FALSE(entry.label_visible()); |
4601 | @@ -74,8 +76,8 @@ |
4602 | |
4603 | TEST(TestIndicatorEntry, TestAssignment) |
4604 | { |
4605 | - Entry entry("id", "name_hint", "label", true, true, 0, "some icon", false, true, 10); |
4606 | - Entry other_entry("other_id", "other_name_hint", "other_label", false, false, 2, "other icon", true, false, 5); |
4607 | + Entry entry("id", "name_hint", 12345, "label", true, true, 0, "some icon", false, true, 10); |
4608 | + Entry other_entry("other_id", "other_name_hint", 54321, "other_label", false, false, 2, "other icon", true, false, 5); |
4609 | |
4610 | SigReceiver sig_receiver(entry); |
4611 | EXPECT_CALL(sig_receiver, Updated()); |
4612 | @@ -83,6 +85,7 @@ |
4613 | |
4614 | EXPECT_EQ(entry.id(), "other_id"); |
4615 | EXPECT_EQ(entry.name_hint(), "other_name_hint"); |
4616 | + EXPECT_EQ(entry.parent_window(), 54321); |
4617 | EXPECT_EQ(entry.label(), "other_label"); |
4618 | EXPECT_FALSE(entry.label_sensitive()); |
4619 | EXPECT_FALSE(entry.label_visible()); |
4620 | @@ -95,8 +98,8 @@ |
4621 | |
4622 | TEST(TestIndicatorEntry, TestShowNowEvents) |
4623 | { |
4624 | - Entry entry("id", "name_hint", "label", true, true, |
4625 | - 0, "some icon", false, true, -1); |
4626 | + Entry entry("id", "name_hint", 0, "label", true, true, |
4627 | + 0, "some icon", false, true, -1); |
4628 | SigReceiver sig_receiver(entry); |
4629 | |
4630 | // Setting show_now to the same value doesn't emit any events. |
4631 | @@ -116,7 +119,7 @@ |
4632 | |
4633 | TEST(TestIndicatorEntry, TestActiveEvents) |
4634 | { |
4635 | - Entry entry("id", "name_hint", "label", true, true, 0, "some icon", false, true, -1); |
4636 | + Entry entry("id", "name_hint", 0, "label", true, true, 0, "some icon", false, true, -1); |
4637 | |
4638 | SigReceiver sig_receiver(entry); |
4639 | |
4640 | @@ -137,7 +140,7 @@ |
4641 | |
4642 | TEST(TestIndicatorEntry, TestOnScroll) |
4643 | { |
4644 | - Entry entry("id", "name_hint", "label", true, true, 0, "some icon", false, true, -1); |
4645 | + Entry entry("id", "name_hint", 0, "label", true, true, 0, "some icon", false, true, -1); |
4646 | SigReceiver sig_receiver(entry); |
4647 | |
4648 | EXPECT_CALL(sig_receiver, OnScroll("id", 10)); |
4649 | @@ -149,16 +152,16 @@ |
4650 | |
4651 | TEST(TestIndicatorEntry, TestOnShowMenu) |
4652 | { |
4653 | - Entry entry("id", "name_hint", "label", true, true, 0, "some icon", false, true, -1); |
4654 | + Entry entry("id", "name_hint", 123, "label", true, true, 0, "some icon", false, true, -1); |
4655 | SigReceiver sig_receiver(entry); |
4656 | |
4657 | - EXPECT_CALL(sig_receiver, OnShowMenu("id", 0, 10, 20, 1)); |
4658 | + EXPECT_CALL(sig_receiver, OnShowMenu("id", 123, 10, 20, 1)); |
4659 | entry.ShowMenu(10, 20, 1); |
4660 | } |
4661 | |
4662 | TEST(TestIndicatorEntry, TestOnShowMenuXid) |
4663 | { |
4664 | - Entry entry("xid", "name_hint", "label", true, true, 0, "some icon", false, true, -1); |
4665 | + Entry entry("xid", "name_hint", 0, "label", true, true, 0, "some icon", false, true, -1); |
4666 | SigReceiver sig_receiver(entry); |
4667 | |
4668 | EXPECT_CALL(sig_receiver, OnShowMenu("xid", 88492615, 15, 25, 2)); |
4669 | @@ -167,7 +170,7 @@ |
4670 | |
4671 | TEST(TestIndicatorEntry, TestVisibility) |
4672 | { |
4673 | - Entry entry("id", "name_hint", "label", true, true, 0, "some icon", false, false, -1); |
4674 | + Entry entry("id", "name_hint", 0, "label", true, true, 0, "some icon", false, false, -1); |
4675 | |
4676 | EXPECT_TRUE(entry.visible()); |
4677 | |
4678 | @@ -208,7 +211,7 @@ |
4679 | |
4680 | TEST(TestIndicatorEntry, TestGeometry) |
4681 | { |
4682 | - Entry entry("id", "name_hint", "label", true, true, 0, "some icon", false, true, -1); |
4683 | + Entry entry("id", "name_hint", 0, "label", true, true, 0, "some icon", false, true, -1); |
4684 | SigReceiver sig_receiver(entry); |
4685 | |
4686 | // Setting to the same value doesn't emit any events. |
4687 | |
4688 | === modified file 'tests/test_indicators.cpp' |
4689 | --- tests/test_indicators.cpp 2014-02-11 03:11:47 +0000 |
4690 | +++ tests/test_indicators.cpp 2015-07-15 14:19:40 +0000 |
4691 | @@ -62,15 +62,15 @@ |
4692 | |
4693 | Indicator::Ptr test_indicator_1 = indicators.AddIndicator("indicator-test-1"); |
4694 | |
4695 | - entry = new Entry("indicator-test-1|entry-1", "name-hint-1", "label", true, true, |
4696 | - 0, "icon", true, true, -1); |
4697 | - sync_data.push_back(Entry::Ptr(entry)); |
4698 | - |
4699 | - entry = new Entry("indicator-test-1|entry-2", "name-hint-2", "label", true, true, |
4700 | - 0, "icon", true, true, -1); |
4701 | - sync_data.push_back(Entry::Ptr(entry)); |
4702 | - |
4703 | - entry = new Entry("indicator-test-1|entry-3", "name-hint-3", "label", true, true, |
4704 | + entry = new Entry("indicator-test-1|entry-1", "name-hint-1", 0, "label", true, true, |
4705 | + 0, "icon", true, true, -1); |
4706 | + sync_data.push_back(Entry::Ptr(entry)); |
4707 | + |
4708 | + entry = new Entry("indicator-test-1|entry-2", "name-hint-2", 0, "label", true, true, |
4709 | + 0, "icon", true, true, -1); |
4710 | + sync_data.push_back(Entry::Ptr(entry)); |
4711 | + |
4712 | + entry = new Entry("indicator-test-1|entry-3", "name-hint-3", 0, "label", true, true, |
4713 | 0, "icon", true, true, -1); |
4714 | sync_data.push_back(Entry::Ptr(entry)); |
4715 | |
4716 | @@ -83,11 +83,11 @@ |
4717 | Indicator::Ptr test_indicator_2 = indicators.AddIndicator("indicator-test-2"); |
4718 | sync_data.clear(); |
4719 | |
4720 | - entry = new Entry("indicator-test-2|entry-1", "name-hint-1", "label", true, true, |
4721 | + entry = new Entry("indicator-test-2|entry-1", "name-hint-1", 0, "label", true, true, |
4722 | 0, "icon", true, true, -1); |
4723 | sync_data.push_back(Entry::Ptr(entry)); |
4724 | |
4725 | - entry = new Entry("indicator-test-2|entry-2", "name-hint-2", "label", true, true, |
4726 | + entry = new Entry("indicator-test-2|entry-2", "name-hint-2", 0, "label", true, true, |
4727 | 0, "icon", true, true, -1); |
4728 | sync_data.push_back(Entry::Ptr(entry)); |
4729 | |
4730 | |
4731 | === modified file 'tests/test_panel_menu_view.cpp' |
4732 | --- tests/test_panel_menu_view.cpp 2014-03-21 04:40:12 +0000 |
4733 | +++ tests/test_panel_menu_view.cpp 2015-07-15 14:19:40 +0000 |
4734 | @@ -36,11 +36,22 @@ |
4735 | |
4736 | struct TestPanelMenuView : public testing::Test |
4737 | { |
4738 | + TestPanelMenuView() |
4739 | + : menu_manager(std::make_shared<menu::MockManager>()) |
4740 | + , menu_view(menu_manager) |
4741 | + {} |
4742 | + |
4743 | struct MockPanelMenuView : public PanelMenuView |
4744 | { |
4745 | - MockPanelMenuView() |
4746 | - : PanelMenuView(std::make_shared<menu::MockManager>()) |
4747 | - {} |
4748 | + MockPanelMenuView(menu::Manager::Ptr const& menu_manager) |
4749 | + : PanelMenuView(menu_manager) |
4750 | + { |
4751 | + view_opened_signal_.Disconnect(); |
4752 | + active_win_changed_signal_.Disconnect(); |
4753 | + active_app_changed_signal_.Disconnect(); |
4754 | + view_closed_signal_.Disconnect(); |
4755 | + maximized_wins_.clear(); |
4756 | + } |
4757 | |
4758 | MOCK_METHOD0(QueueDraw, void()); |
4759 | MOCK_CONST_METHOD1(GetActiveViewName, std::string(bool)); |
4760 | @@ -53,6 +64,7 @@ |
4761 | using PanelMenuView::titlebar_grab_area_; |
4762 | using PanelMenuView::we_control_active_; |
4763 | using PanelMenuView::spread_showing_; |
4764 | + using PanelMenuView::maximized_wins_; |
4765 | }; |
4766 | |
4767 | nux::ObjectPtr<nux::BaseWindow> AddPanelToWindow(int monitor) |
4768 | @@ -69,6 +81,7 @@ |
4769 | panel_win->ComputeContentSize(); |
4770 | |
4771 | menu_view.SetMonitor(monitor); |
4772 | + menu_view.maximized_wins_.clear(); |
4773 | |
4774 | return panel_win; |
4775 | } |
4776 | @@ -79,6 +92,7 @@ |
4777 | MockUScreen uscreen; |
4778 | panel::Style panelStyle; |
4779 | testwrapper::StandaloneWM WM; |
4780 | + menu::MockManager::Ptr menu_manager; |
4781 | testing::NiceMock<MockPanelMenuView> menu_view; |
4782 | }; |
4783 | |
4784 | @@ -91,6 +105,7 @@ |
4785 | |
4786 | TEST_F(TestPanelMenuView, Escaping) |
4787 | { |
4788 | + menu_manager->integrated_menus = false; |
4789 | ON_CALL(menu_view, GetActiveViewName(testing::_)).WillByDefault(Return("<>'")); |
4790 | auto escapedText = "Panel d'Inici"; |
4791 | ASSERT_TRUE(menu_view.GetCurrentTitle().empty()); |
4792 | @@ -136,6 +151,7 @@ |
4793 | TEST_P(ProgressTester, RestoreOnGrabInBiggerWorkArea) |
4794 | { |
4795 | uscreen.SetupFakeMultiMonitor(); |
4796 | + connection::Manager conn; |
4797 | unsigned monitor = uscreen.GetMonitors().size() - 1; |
4798 | auto const& monitor_geo = uscreen.GetMonitorGeometry(monitor); |
4799 | WM->SetWorkareaGeometry(monitor_geo); |
4800 | |
4801 | === modified file 'tests/test_panel_service.cpp' |
4802 | --- tests/test_panel_service.cpp 2013-10-03 15:16:06 +0000 |
4803 | +++ tests/test_panel_service.cpp 2015-07-15 14:19:40 +0000 |
4804 | @@ -32,8 +32,8 @@ |
4805 | { |
4806 | typedef std::tuple<glib::Object<GtkLabel>, glib::Object<GtkImage>> EntryObjects; |
4807 | |
4808 | -const std::string SYNC_ENTRY_VARIANT_FORMAT = "(ssssbbusbbi)"; |
4809 | -const std::string SYNC_ENTRIES_VARIANT_FORMAT = "(a"+SYNC_ENTRY_VARIANT_FORMAT+")"; |
4810 | +const std::string SYNC_ENTRY_VARIANT_FORMAT = ENTRY_SIGNATURE; |
4811 | +const std::string SYNC_ENTRIES_VARIANT_FORMAT = "(" ENTRY_ARRAY_SIGNATURE ")"; |
4812 | |
4813 | struct TestPanelService : Test |
4814 | { |
4815 | @@ -46,6 +46,7 @@ |
4816 | std::string indicator_id; |
4817 | std::string entry_id; |
4818 | std::string entry_name_hint; |
4819 | + uint32_t parent_window; |
4820 | std::string label; |
4821 | bool label_sensitive; |
4822 | bool label_visible; |
4823 | @@ -63,6 +64,7 @@ |
4824 | gchar* indicator_id; |
4825 | gchar* entry_id; |
4826 | gchar* entry_name_hint; |
4827 | + guint32 parent_window; |
4828 | gchar* label; |
4829 | gboolean label_sensitive; |
4830 | gboolean label_visible; |
4831 | @@ -77,6 +79,7 @@ |
4832 | &indicator_id, |
4833 | &entry_id, |
4834 | &entry_name_hint, |
4835 | + &parent_window, |
4836 | &label, |
4837 | &label_sensitive, |
4838 | &label_visible, |
4839 | @@ -89,6 +92,7 @@ |
4840 | results.push_back({ glib::gchar_to_string(indicator_id), |
4841 | glib::gchar_to_string(entry_id), |
4842 | glib::gchar_to_string(entry_name_hint), |
4843 | + parent_window, |
4844 | glib::gchar_to_string(label), |
4845 | label_sensitive != FALSE, |
4846 | label_visible != FALSE, |
4847 | |
4848 | === modified file 'tests/test_service_panel.cpp' |
4849 | --- tests/test_service_panel.cpp 2013-03-02 22:44:29 +0000 |
4850 | +++ tests/test_service_panel.cpp 2015-07-15 14:19:40 +0000 |
4851 | @@ -1,4 +1,5 @@ |
4852 | #include "test_service_panel.h" |
4853 | +#include "panel-service-private.h" |
4854 | |
4855 | namespace unity |
4856 | { |
4857 | @@ -9,11 +10,11 @@ |
4858 | static const char * panel_interface = |
4859 | "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" |
4860 | "<node name=\"/\">\n" |
4861 | -" <interface name=\"com.canonical.Unity.Panel.Service\">\n" |
4862 | +" <interface name=\"" UPS_IFACE "\">\n" |
4863 | "\n" |
4864 | "<!-- Begin of real methods/signals -->\n" |
4865 | " <method name='Sync'>" |
4866 | -" <arg type='a(ssssbbusbbi)' name='state' direction='out'/>" |
4867 | +" <arg type='" ENTRY_ARRAY_SIGNATURE "' name='state' direction='out'/>" |
4868 | " </method>" |
4869 | "\n" |
4870 | " <signal name='ReSync'>" |
4871 | @@ -32,12 +33,13 @@ |
4872 | "</node>\n" |
4873 | ; |
4874 | |
4875 | -void add_entry_id(GVariantBuilder *b) |
4876 | +void add_entry_id(GVariantBuilder *b, gint priority) |
4877 | { |
4878 | - g_variant_builder_add (b, "(ssssbbusbbi)", |
4879 | + g_variant_builder_add (b, ENTRY_SIGNATURE, |
4880 | "test_indicator_id", |
4881 | "test_entry_id", |
4882 | "test_entry_name_hint", |
4883 | + 0, /* parent window */ |
4884 | "test_entry_label", |
4885 | TRUE, /* label sensitive */ |
4886 | TRUE, /* label visible */ |
4887 | @@ -45,15 +47,16 @@ |
4888 | "", /* image_data */ |
4889 | TRUE, /* image sensitive */ |
4890 | TRUE, /* image visible */ |
4891 | - 1 /* priority */); |
4892 | + priority); |
4893 | } |
4894 | |
4895 | -void add_entry_id_2(GVariantBuilder *b) |
4896 | +void add_entry_id_2(GVariantBuilder *b, gint priority) |
4897 | { |
4898 | - g_variant_builder_add (b, "(ssssbbusbbi)", |
4899 | + g_variant_builder_add (b, ENTRY_SIGNATURE, |
4900 | "test_indicator_id", |
4901 | "test_entry_id2", |
4902 | "test_entry_name_hint2", |
4903 | + 12345, /* parent window */ |
4904 | "test_entry_label2", |
4905 | TRUE, /* label sensitive */ |
4906 | TRUE, /* label visible */ |
4907 | @@ -61,7 +64,7 @@ |
4908 | "", /* image_data */ |
4909 | TRUE, /* image sensitive */ |
4910 | TRUE, /* image visible */ |
4911 | - 1 /* priority */); |
4912 | + priority); |
4913 | } |
4914 | } |
4915 | |
4916 | @@ -73,7 +76,7 @@ |
4917 | auto object = glib::DBusObjectBuilder::GetObjectsForIntrospection(panel_interface).front(); |
4918 | object->SetMethodsCallsHandler(sigc::mem_fun(this, &Panel::OnMethodCall)); |
4919 | |
4920 | - server_.AddObject(object, "/com/canonical/Unity/Panel/Service"); |
4921 | + server_.AddObject(object, UPS_PATH); |
4922 | } |
4923 | |
4924 | GVariant* Panel::OnMethodCall(std::string const& method, GVariant *parameters) |
4925 | @@ -82,18 +85,18 @@ |
4926 | { |
4927 | GVariantBuilder b; |
4928 | |
4929 | - g_variant_builder_init (&b, G_VARIANT_TYPE ("(a(ssssbbusbbi))")); |
4930 | - g_variant_builder_open (&b, G_VARIANT_TYPE ("a(ssssbbusbbi)")); |
4931 | + g_variant_builder_init (&b, G_VARIANT_TYPE ("(" ENTRY_ARRAY_SIGNATURE ")")); |
4932 | + g_variant_builder_open (&b, G_VARIANT_TYPE (ENTRY_ARRAY_SIGNATURE)); |
4933 | |
4934 | if (sync_return_mode_ == 0) |
4935 | { |
4936 | - add_entry_id(&b); |
4937 | - add_entry_id_2(&b); |
4938 | + add_entry_id(&b, 1); |
4939 | + add_entry_id_2(&b, 2); |
4940 | } |
4941 | else if (sync_return_mode_ == 1) |
4942 | { |
4943 | - add_entry_id_2(&b); |
4944 | - add_entry_id(&b); |
4945 | + add_entry_id_2(&b, 1); |
4946 | + add_entry_id(&b, 2); |
4947 | } |
4948 | |
4949 | if (sync_return_mode_ == 1) |
4950 | |
4951 | === modified file 'unity-shared/IconLoader.cpp' |
4952 | --- unity-shared/IconLoader.cpp 2014-03-21 01:49:22 +0000 |
4953 | +++ unity-shared/IconLoader.cpp 2015-07-15 14:19:40 +0000 |
4954 | @@ -799,7 +799,7 @@ |
4955 | bool CoalesceTasksCb(); |
4956 | |
4957 | private: |
4958 | - std::map<std::string, glib::Object<GdkPixbuf>> cache_; |
4959 | + std::unordered_map<std::string, glib::Object<GdkPixbuf>> cache_; |
4960 | /* FIXME: the reference counting of IconLoaderTasks with shared pointers |
4961 | * is currently somewhat broken, and the queued_tasks_ member is what keeps |
4962 | * it from crashing randomly. |
4963 | @@ -807,7 +807,7 @@ |
4964 | * tasks, but when they are being completed in a worker thread, the thread |
4965 | * should own them as well (yet it doesn't), this could cause trouble |
4966 | * in the future... You've been warned! */ |
4967 | - std::map<std::string, IconLoaderTask::Ptr> queued_tasks_; |
4968 | + std::unordered_map<std::string, IconLoaderTask::Ptr> queued_tasks_; |
4969 | std::queue<IconLoaderTask::Ptr> tasks_; |
4970 | std::unordered_map<Handle, IconLoaderTask::Ptr> task_map_; |
4971 | std::vector<IconLoaderTask*> finished_tasks_; |
4972 | |
4973 | === modified file 'unity-shared/MenuManager.cpp' |
4974 | --- unity-shared/MenuManager.cpp 2015-03-12 00:57:05 +0000 |
4975 | +++ unity-shared/MenuManager.cpp 2015-07-15 14:19:40 +0000 |
4976 | @@ -26,6 +26,7 @@ |
4977 | #include <unordered_map> |
4978 | |
4979 | #include "MenuManager.h" |
4980 | +#include "WindowManager.h" |
4981 | |
4982 | namespace unity |
4983 | { |
4984 | @@ -48,16 +49,20 @@ |
4985 | : parent_(parent) |
4986 | , indicators_(indicators) |
4987 | , key_grabber_(grabber) |
4988 | + , show_now_window_(0) |
4989 | , settings_(g_settings_new(SETTINGS_NAME.c_str())) |
4990 | { |
4991 | for (auto const& indicator : indicators_->GetIndicators()) |
4992 | AddIndicator(indicator); |
4993 | |
4994 | + GrabMnemonicsForActiveWindow(); |
4995 | + |
4996 | parent_->show_menus.changed.connect(sigc::mem_fun(this, &Impl::ShowMenus)); |
4997 | indicators_->on_object_added.connect(sigc::mem_fun(this, &Impl::AddIndicator)); |
4998 | indicators_->on_object_removed.connect(sigc::mem_fun(this, &Impl::RemoveIndicator)); |
4999 | indicators_->on_entry_activate_request.connect(sigc::mem_fun(this, &Impl::ActivateRequest)); |
5000 | indicators_->icon_paths_changed.connect(sigc::mem_fun(this, &Impl::IconPathsChanged)); |
FAILED: Continuous integration, rev:3832 jenkins. qa.ubuntu. com/job/ unity-7. 2-ci/20/ jenkins. qa.ubuntu. com/job/ unity-7. 2-trusty- amd64-ci/ 20/console jenkins. qa.ubuntu. com/job/ unity-7. 2-trusty- armhf-ci/ 20/console jenkins. qa.ubuntu. com/job/ unity-7. 2-trusty- i386-ci/ 20/console
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/unity- 7.2-ci/ 20/rebuild
http://