Merge lp:~3v1n0/unity/hud-lock-out-monitors-tests into lp:unity
- hud-lock-out-monitors-tests
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Gord Allott |
Approved revision: | no longer in the source branch. |
Merged at revision: | 2188 |
Proposed branch: | lp:~3v1n0/unity/hud-lock-out-monitors-tests |
Merge into: | lp:unity |
Diff against target: |
1544 lines (+530/-245) 27 files modified
manual-tests/Hud.txt (+0/-16) plugins/unityshell/src/BamfLauncherIcon.cpp (+36/-43) plugins/unityshell/src/BamfLauncherIcon.h (+2/-1) plugins/unityshell/src/HudController.cpp (+50/-38) plugins/unityshell/src/HudController.h (+6/-9) plugins/unityshell/src/HudIcon.cpp (+4/-4) plugins/unityshell/src/HudIcon.h (+2/-1) plugins/unityshell/src/HudView.cpp (+20/-11) plugins/unityshell/src/HudView.h (+2/-8) plugins/unityshell/src/IconTexture.cpp (+21/-18) plugins/unityshell/src/IconTexture.h (+1/-0) plugins/unityshell/src/LauncherIcon.cpp (+14/-12) plugins/unityshell/src/SimpleLauncherIcon.cpp (+7/-0) plugins/unityshell/src/SimpleLauncherIcon.h (+2/-0) plugins/unityshell/src/unityshell.cpp (+4/-2) tests/autopilot/autopilot/emulators/X11.py (+11/-1) tests/autopilot/autopilot/emulators/bamf.py (+5/-0) tests/autopilot/autopilot/emulators/unity/hud.py (+35/-0) tests/autopilot/autopilot/emulators/unity/icons.py (+9/-0) tests/autopilot/autopilot/emulators/unity/launcher.py (+24/-5) tests/autopilot/autopilot/emulators/unity/switcher.py (+2/-2) tests/autopilot/autopilot/tests/__init__.py (+12/-4) tests/autopilot/autopilot/tests/test_hud.py (+240/-50) tests/autopilot/autopilot/tests/test_launcher.py (+1/-2) tests/autopilot/autopilot/tests/test_shortcut_hint.py (+3/-5) tests/autopilot/autopilot/tests/test_showdesktop.py (+5/-4) tests/autopilot/autopilot/tests/test_switcher.py (+12/-9) |
To merge this branch: | bzr merge lp:~3v1n0/unity/hud-lock-out-monitors-tests |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Thomi Richards (community) | Approve | ||
Gord Allott | Pending | ||
Review via email: mp+99215@code.launchpad.net |
This proposal supersedes a proposal from 2012-03-21.
Commit message
HudController: Fixed geometries for single-launcher mode.
And added tests for multimonitor in HUD, with lock-out support.
Description of the change
Added tests for multimonitor in HUD, with lock-out support.
Also fixed the bug #963577 with some HudController and HudView code cleanup and improvements.
The tests now also support the HudLauncherIcon, and I've included some more utility functions to avoid them to fail.
Gord Allott (gordallott) wrote : Posted in a previous version of this proposal | # |
Thomi Richards (thomir-deactivatedaccount) wrote : Posted in a previous version of this proposal | # |
Hi,
44 + def is_rect_
45 + (m_x, m_y, m_w, m_h) = self.get_
46 + return (x >= m_x and x + w <= m_x + m_w and y >= m_y and y + h <= m_y + m_h)
47 +
Instead of passing x,y,w & h as separate parameters, just pass 'rect', and make sure it's a tuple in the function:
def is_rect_
"""Returns True if `rect` is _entirely_ on the specified monitor, with no overlap"""
if type(rect) is not tuple:
raise TypeError("rect must be a tuple.")
...if you want you can also check that monitor_number is a valid integer, and that the tuple values are all ints.
This:
59 + def get_geometry(self):
60 + return (self.x, self.y, self.width, self.height)
61 +
should be a property, like this:
58 + @property
59 + def geometry(self):
60 + return (self.x, self.y, self.width, self.height)
61 +
this:
84 + screen_geometry = ScreenGeometry()
85 + num_monitors = screen_
86 +
87 + if num_monitors == 1:
88 + scenarios = [
89 + ('Single Monitor, Launcher never hide', {'hud_monitor': 0, 'launcher_
90 + ('Single Monitor, Launcher autohide', {'hud_monitor': 0, 'launcher_
91 + ]
92 + else:
93 + scenarios = []
94 + for i in range(num_
95 + scenarios.
96 + scenarios.
is kind of ugly. A better way to do it is how we do it in the launcher tests - use a function to generate the scenarios.
The first two changes I mentioned mean that you can rewrite this:
112 + (x, y, w, h) = self.hud.
113 + self.assertTrue
like this:
self.assertTrue
The new test:
131 + def test_hud_
...needs a docstring.
Finally, please use matchers for everything except simple true/false tests, so this:
139 + self.assertEqua
becomes:
self.assertThat
Cheers,
Thomi Richards (thomir-deactivatedaccount) wrote : | # |
Hi,
There are a few things that need to be fixed:
712 - .add("x", _center[0].x)
713 - .add("y", _center[0].y)
714 - .add("z", _center[0].z)
715 - .add("related-
716 - .add("icon-type", _icon_type)
717 - .add("tooltip-
718 - .add("sort-
719 - .add("quirk-
720 - .add("quirk-
721 - .add("quirk-
722 - .add("quirk-
723 - .add("quirk-
724 + .add("center_x", _center[0].x)
725 + .add("center_y", _center[0].y)
726 + .add("center_z", _center[0].z)
727 + .add("related_
728 + .add("icon_type", _icon_type)
729 + .add("tooltip_
730 + .add("sort_
731 + .add("active", GetQuirk(
732 + .add("visible", GetQuirk(
733 + .add("urgent", GetQuirk(
734 + .add("running", GetQuirk(
735 + .add("starting", GetQuirk(
736 + .add("desaturated", GetQuirk(
737 + .add("presented", GetQuirk(
Hyphens ('-') get translated to underscores ('_') in python automatically. You don't need to do this in the C++ code. It doesn't hurt, but you don't need to do it. More importantly, I don't think renaming 'x', 'y', 'z' to center_x, center_y, and center_z is a good idea. It seems natural to me that the x,y & z properties represent the center of the icon. If you are going to change this, please make sure that all the autopilot tests are updated accordingly.
There's something very wrong with this code:
823 + def is_rect_
824 + """Returns True if `rect` is _entirely_ on the specified monitor, with no overlap"""
825 +
826 + if type(rect) is not tuple or len(rect) != 4:
827 + raise TypeError("rect must be a tuple of 4 int elements.")
828 +
829 + (x, y, w, h) = self.get_
830 +
831 + (m_x, m_y, m_w, m_h) = self.get_
832 + return (x >= m_x and x + w <= m_x + m_w and y >= m_y and y + h <= m_y + m_h)
833 +
...Can you spot it? What exactly is 'rect' used for?
THis property:
910 + @property
911 + def show_embedded_
Should be renamed. Either 'showing_
I notice that you've changed this code:
970 icons = self.get_
971 - return icons or None
972 + if len(icons):
973 + return icons[0]
974 +
975 + return None
976 +
It used to return a list or none, now it returns an instance or none. Have you updated everywhere that called this method to cope with the change? Further, are you *absolutely* sure that it's impossible for there to be more than one launcher icon with the same desktop file? I'm pretty sure Jason said that this could happen, whcih is why I was returning a list.
This:
1016 +def _make_scenarios():
1017 + screen_geometry = Screen...
Marco Trevisan (Treviño) (3v1n0) wrote : | # |
Ooops... Myabe I was too tired yesterday night, I figured there was still some debugging code around, sorry.
> Hi,
>
> There are a few things that need to be fixed:
>
> 728 + .add("icon_type", _icon_type)
> Hyphens ('-') get translated to underscores ('_') in python automatically. You
> don't need to do this in the C++ code. It doesn't hurt, but you don't need to
> do it.
Yes, I know, but it also was to keep the same way of naming the introspection parameters.
Plus, there was no need to include the "quirk-" prefix.
> More importantly, I don't think renaming 'x', 'y', 'z' to center_x,
> center_y, and center_z is a good idea. It seems natural to me that the x,y & z
> properties represent the center of the icon.
Yes, maybe you are, but I'm not sure we're all since there was this code:
target_y = icon.y + (self.icon_size / 2)
self.
self.
Also, considering that everywhere we consider the X / Y points as the coordinates of the top left edge, we should just apply this to icons too.
> If you are going to change this, please make sure that all the autopilot tests
> are updated accordingly.
Yes, I've done that.
> There's something very wrong with this code:
>
> 823 + def is_rect_
> ...Can you spot it? What exactly is 'rect' used for?
Yes, sorry it should have been used here:
> 829 + (x, y, w, h) = self.get_
Maybe a copy&paste typo.
> THis property:
>
> 910 + @property
> 911 + def show_embedded_
>
> Should be renamed. Either 'showing_
> maybe even 'displaying_
> in property names.
Yes, actually I should have removed that, since I don't use it anymore (I used on previous revisions).
I've updated it against new API and new name, btw.
> I notice that you've changed this code:
>
> 970 icons = self.get_
> desktop_
> 971 - return icons or None
> 972 + if len(icons):
> 973 + return icons[0]
> 974 +
> 975 + return None
> 976 +
>
> It used to return a list or none, now it returns an instance or none. Have you
> updated everywhere that called this method to cope with the change?
Yes, it was called only once in an HUD test, that I've updated moving to desktop_id
> Further, are you *absolutely* sure that it's impossible for there to be more than one
> launcher icon with the same desktop file? I'm pretty sure Jason said that this
> could happen, whcih is why I was returning a list.
No, it's currently impossible (at least, it shouldn't happen unless we have bamf crashes, but this something to be fixed elsewhere) that two icons have the same desktop file, considering by "desktop file" the .desktop full path.
If it happens, btw it's safe to just take the first icon.
Otherwise we should just rename it into get_icons_
Anyway I'm for the only-one-icon way: it simplifies the usage and just works.
> This:
>
> 1016 +...
Marco Trevisan (Treviño) (3v1n0) wrote : | # |
Thomi, the tests now should be done.
Thomi Richards (thomir-deactivatedaccount) wrote : | # |
Hi,
Almost there :)
Please change this:
81 + .add("desktop_id", glib::String(
to use the methods on the std::string. Something like this (untested, but should work):
std::string desktop_file = DesktopFile();
std::string desktop_id = desktop_
The current code involves way too much casting, uses c functions when we have c++ alternatives, and looks awful.
This docstringsd needs a period at the end:
762 + """Returns True if `rect` is _entirely_ on the specified monitor, with no overlap"""
Please add a blank line between the class docstring at the property:
797 """Proxy object for the hud view child of the controller."""
798 + @property
799 + def geometry(self):
Please add a docstring here:
814 + def get_embedded_
...detailing what the possible return values are.
Please rename this:
858 + @property
859 + def center_
since you're not returning the geometry, just a point. Maybe call it "position", "center_position", or "center_point" or something. Also, please add a docstring, since you're returning x, y AND z properties, which might confuse people (who only expect X & Y).
Please revert this change:
966 - scenario_name = ','.join(names)
967 + scenario_name = ', '.join(names)
multiply_scenarios is from testscenarios. I won't want two functions that behave differently.
This should go in AutopilotTestCase:
1034 + screen_geo = ScreenGeometry()
Please add a blank line betweeb the class definition and the setUp method:
1081 +class HudBehaviorTest
1082 + def setUp(self):
This test:
1245 + def test_hud_
1246 + """Tests that the launcher icons are desaturates when HUD is open"""
1247 +
1248 + self.reveal_hud()
1249 + sleep(.5)
1250 +
1251 + for icon in self.launcher.
1252 + if not isinstance(icon, HudLauncherIcon):
1253 + self.assertTrue
Is good, but we probably want another one that asserts that the hud icon is NOT desaturated.
As discussed on IRC, please change this:
975 + def start_app_
976 + """Start one of the known apps using the C locale, and kill it on tear down.
977 +
978 + if files is specified, start the application with the specified files.
979 + """
980 + os.putenv("LC_ALL", "C")
981 + self.start_
982 + self.addCleanup
to something like this (changing the current start_app):
def start_app(self, app_name, files=[], locale=None):
"""Start one of the known apps, and kill it on tear down.
If files is specified, start the application with the specified files.
If locale is specified, the locale will be set when the application is launched.
"""
if locale:
else:
app = self.KNOWN_
Thomi Richards (thomir-deactivatedaccount) wrote : | # |
+1
Preview Diff
1 | === modified file 'manual-tests/Hud.txt' |
2 | --- manual-tests/Hud.txt 2012-03-26 21:04:10 +0000 |
3 | +++ manual-tests/Hud.txt 2012-03-27 22:51:18 +0000 |
4 | @@ -49,22 +49,6 @@ |
5 | After pressing escape in step three, the text "test" should be removed from the hud search |
6 | After step four, the hud should dismiss itself and not be present. |
7 | |
8 | -Hud Reveal Behaviour |
9 | ---------- |
10 | -This test ensures that the hud behaves correctly with a locked out launcher |
11 | - |
12 | -Setup: |
13 | -#. Ensure the launchers hide mode is set to "Never" |
14 | - |
15 | -Action: |
16 | -#. Tap Alt |
17 | - |
18 | -Outcome: |
19 | - The Launcher should stick be locked out. |
20 | - The Launcher icons should be desaturated. |
21 | - The top most Launcher icon should be an icon related the the focused window |
22 | - The BFB should not be present |
23 | - |
24 | Alt+Arrow keys not passed to application |
25 | ---------------------------------------- |
26 | Tests that Alt+ArrowKey events are correctly passed to the active window |
27 | |
28 | === modified file 'plugins/unityshell/src/BamfLauncherIcon.cpp' |
29 | --- plugins/unityshell/src/BamfLauncherIcon.cpp 2012-03-22 15:14:49 +0000 |
30 | +++ plugins/unityshell/src/BamfLauncherIcon.cpp 2012-03-27 22:51:18 +0000 |
31 | @@ -335,7 +335,7 @@ |
32 | |
33 | std::vector<Window> BamfLauncherIcon::WindowsOnViewport() |
34 | { |
35 | - WindowFilterMask filter; |
36 | + WindowFilterMask filter = 0; |
37 | filter |= WindowFilter::MAPPED; |
38 | filter |= WindowFilter::USER_VISIBLE; |
39 | filter |= WindowFilter::ON_CURRENT_DESKTOP; |
40 | @@ -346,7 +346,7 @@ |
41 | |
42 | std::vector<Window> BamfLauncherIcon::WindowsForMonitor(int monitor) |
43 | { |
44 | - WindowFilterMask filter; |
45 | + WindowFilterMask filter = 0; |
46 | filter |= WindowFilter::MAPPED; |
47 | filter |= WindowFilter::USER_VISIBLE; |
48 | filter |= WindowFilter::ON_CURRENT_DESKTOP; |
49 | @@ -455,26 +455,18 @@ |
50 | |
51 | void BamfLauncherIcon::AddProperties(GVariantBuilder* builder) |
52 | { |
53 | - LauncherIcon::AddProperties(builder); |
54 | - |
55 | - GList* children, *l; |
56 | - children = bamf_view_get_children(BAMF_VIEW(_bamf_app.RawPtr())); |
57 | - GVariant* xids[(int) g_list_length(children)]; |
58 | - |
59 | - int i = 0; |
60 | - for (l = children; l; l = l->next) |
61 | - { |
62 | - if (!BAMF_IS_WINDOW(l->data)) |
63 | - continue; |
64 | - |
65 | - Window xid = bamf_window_get_xid(static_cast<BamfWindow*>(l->data)); |
66 | - xids[i++] = g_variant_new_uint32(xid); |
67 | - } |
68 | - g_list_free(children); |
69 | + SimpleLauncherIcon::AddProperties(builder); |
70 | + |
71 | + GVariantBuilder xids_builder; |
72 | + g_variant_builder_init(&xids_builder, G_VARIANT_TYPE ("au")); |
73 | + |
74 | + for (auto xid : GetWindows()) |
75 | + g_variant_builder_add(&xids_builder, "u", xid); |
76 | |
77 | variant::BuilderWrapper(builder) |
78 | - .add("desktop-file", DesktopFile()) |
79 | - .add("xids", g_variant_new_array(G_VARIANT_TYPE_UINT32, xids, i)) |
80 | + .add("desktop_file", DesktopFile()) |
81 | + .add("desktop_id", GetDesktopID()) |
82 | + .add("xids", g_variant_builder_end(&xids_builder)) |
83 | .add("sticky", IsSticky()); |
84 | } |
85 | |
86 | @@ -627,26 +619,8 @@ |
87 | |
88 | bool BamfLauncherIcon::Spread(bool current_desktop, int state, bool force) |
89 | { |
90 | - GList* children, *l; |
91 | - children = bamf_view_get_children(BAMF_VIEW(_bamf_app.RawPtr())); |
92 | - WindowManager* wm = WindowManager::Default(); |
93 | - |
94 | - std::vector<Window> windowList; |
95 | - for (l = children; l; l = l->next) |
96 | - { |
97 | - if (!BAMF_IS_WINDOW(l->data)) |
98 | - continue; |
99 | - |
100 | - Window xid = bamf_window_get_xid(static_cast<BamfWindow*>(l->data)); |
101 | - |
102 | - if (!current_desktop || (current_desktop && wm->IsWindowOnCurrentDesktop(xid))) |
103 | - { |
104 | - windowList.push_back(xid); |
105 | - } |
106 | - } |
107 | - |
108 | - g_list_free(children); |
109 | - return WindowManager::Default()->ScaleWindowGroup(windowList, state, force); |
110 | + auto windows = GetWindows(current_desktop ? WindowFilter::ON_CURRENT_DESKTOP : 0); |
111 | + return WindowManager::Default()->ScaleWindowGroup(windows, state, force); |
112 | } |
113 | |
114 | void BamfLauncherIcon::EnsureWindowState() |
115 | @@ -1049,16 +1023,35 @@ |
116 | UpdateIconGeometries(center); |
117 | } |
118 | |
119 | +std::string BamfLauncherIcon::GetDesktopID() |
120 | +{ |
121 | + std::string const& desktop_file = DesktopFile(); |
122 | + |
123 | + if (!desktop_file.empty()) |
124 | + { |
125 | + size_t id_pos = desktop_file.rfind('/'); |
126 | + |
127 | + if (id_pos != std::string::npos) |
128 | + { |
129 | + size_t id_start = id_pos + 1; |
130 | + |
131 | + return (id_start < desktop_file.length()) ? desktop_file.substr(id_start) : ""; |
132 | + } |
133 | + } |
134 | + |
135 | + return desktop_file; |
136 | +} |
137 | + |
138 | const gchar* BamfLauncherIcon::GetRemoteUri() |
139 | { |
140 | if (_remote_uri.empty()) |
141 | { |
142 | const std::string prefix = "application://"; |
143 | - glib::String basename(g_path_get_basename(DesktopFile().c_str())); |
144 | + std::string const& desktop_id = GetDesktopID(); |
145 | |
146 | - if (!basename.Str().empty()) |
147 | + if (!desktop_id.empty()) |
148 | { |
149 | - _remote_uri = prefix + basename.Str(); |
150 | + _remote_uri = prefix + desktop_id; |
151 | } |
152 | } |
153 | |
154 | |
155 | === modified file 'plugins/unityshell/src/BamfLauncherIcon.h' |
156 | --- plugins/unityshell/src/BamfLauncherIcon.h 2012-03-22 15:14:49 +0000 |
157 | +++ plugins/unityshell/src/BamfLauncherIcon.h 2012-03-27 22:51:18 +0000 |
158 | @@ -113,8 +113,9 @@ |
159 | |
160 | bool OwnsWindow(Window w) const; |
161 | |
162 | - std::vector<Window> GetWindows(WindowFilterMask filter, int monitor = -1); |
163 | + std::vector<Window> GetWindows(WindowFilterMask filter = 0, int monitor = -1); |
164 | const std::set<std::string>& GetSupportedTypes(); |
165 | + std::string GetDesktopID(); |
166 | |
167 | |
168 | glib::Object<BamfApplication> _bamf_app; |
169 | |
170 | === modified file 'plugins/unityshell/src/HudController.cpp' |
171 | --- plugins/unityshell/src/HudController.cpp 2012-03-21 15:30:49 +0000 |
172 | +++ plugins/unityshell/src/HudController.cpp 2012-03-27 22:51:18 +0000 |
173 | @@ -40,6 +40,8 @@ |
174 | |
175 | Controller::Controller() |
176 | : launcher_width(65) |
177 | + , launcher_locked_out(false) |
178 | + , multiple_launchers(true) |
179 | , hud_service_("com.canonical.hud", "/com/canonical/hud") |
180 | , window_(nullptr) |
181 | , visible_(false) |
182 | @@ -47,12 +49,11 @@ |
183 | , timeline_id_(0) |
184 | , last_opacity_(0.0f) |
185 | , start_time_(0) |
186 | - , launcher_is_locked_out_(false) |
187 | , view_(nullptr) |
188 | , monitor_index_(0) |
189 | { |
190 | LOG_DEBUG(logger) << "hud startup"; |
191 | - SetupRelayoutCallbacks(); |
192 | + UScreen::GetDefault()->changed.connect([&] (int, std::vector<nux::Geometry>&) { Relayout(); }); |
193 | |
194 | ubus.RegisterInterest(UBUS_HUD_CLOSE_REQUEST, sigc::mem_fun(this, &Controller::OnExternalHideHud)); |
195 | |
196 | @@ -65,13 +66,13 @@ |
197 | gint32 overlay_monitor = 0; |
198 | g_variant_get(data, UBUS_OVERLAY_FORMAT_STRING, &overlay_identity, &can_maximise, &overlay_monitor); |
199 | |
200 | - if (g_strcmp0(overlay_identity, "hud")) |
201 | + if (overlay_identity.Str() != "hud") |
202 | { |
203 | HideHud(true); |
204 | } |
205 | }); |
206 | |
207 | - launcher_width.changed.connect([this] (int new_width) { Relayout(); }); |
208 | + launcher_width.changed.connect([&] (int new_width) { Relayout(); }); |
209 | |
210 | PluginAdapter::Default()->compiz_screen_ungrabbed.connect(sigc::mem_fun(this, &Controller::OnScreenUngrabbed)); |
211 | |
212 | @@ -120,14 +121,24 @@ |
213 | AddChild(view_); |
214 | } |
215 | |
216 | -void Controller::SetupRelayoutCallbacks() |
217 | -{ |
218 | - GdkScreen* screen = gdk_screen_get_default(); |
219 | - |
220 | - sig_manager_.Add(new glib::Signal<void, GdkScreen*>(screen, |
221 | - "monitors-changed", sigc::mem_fun(this, &Controller::Relayout))); |
222 | - sig_manager_.Add(new glib::Signal<void, GdkScreen*>(screen, |
223 | - "size-changed", sigc::mem_fun(this, &Controller::Relayout))); |
224 | +int Controller::GetTargetMonitor() |
225 | +{ |
226 | + return UScreen::GetDefault()->GetMonitorWithMouse(); |
227 | +} |
228 | + |
229 | +bool Controller::IsLockedToLauncher(int monitor) |
230 | +{ |
231 | + if (launcher_locked_out) |
232 | + { |
233 | + int primary_monitor = UScreen::GetDefault()->GetPrimaryMonitor(); |
234 | + |
235 | + if (multiple_launchers || (!multiple_launchers && primary_monitor == monitor)) |
236 | + { |
237 | + return true; |
238 | + } |
239 | + } |
240 | + |
241 | + return false; |
242 | } |
243 | |
244 | void Controller::EnsureHud() |
245 | @@ -158,30 +169,31 @@ |
246 | |
247 | nux::Geometry Controller::GetIdealWindowGeometry() |
248 | { |
249 | - UScreen *uscreen = UScreen::GetDefault(); |
250 | - int primary_monitor = uscreen->GetMonitorWithMouse(); |
251 | - auto monitor_geo = uscreen->GetMonitorGeometry(primary_monitor); |
252 | + int target_monitor = GetTargetMonitor(); |
253 | + auto monitor_geo = UScreen::GetDefault()->GetMonitorGeometry(target_monitor); |
254 | |
255 | - // We want to cover as much of the screen as possible to grab any mouse events outside |
256 | - // of our window |
257 | + // We want to cover as much of the screen as possible to grab any mouse events |
258 | + // outside of our window |
259 | panel::Style &panel_style = panel::Style::Instance(); |
260 | nux::Geometry geo(monitor_geo.x, |
261 | - monitor_geo.y + panel_style.panel_height, |
262 | - monitor_geo.width, |
263 | - monitor_geo.height - panel_style.panel_height); |
264 | - if (launcher_is_locked_out_) |
265 | + monitor_geo.y + panel_style.panel_height, |
266 | + monitor_geo.width, |
267 | + monitor_geo.height - panel_style.panel_height); |
268 | + |
269 | + if (IsLockedToLauncher(target_monitor)) |
270 | { |
271 | geo.x += launcher_width; |
272 | geo.width -= launcher_width; |
273 | } |
274 | + |
275 | return geo; |
276 | } |
277 | |
278 | -void Controller::Relayout(GdkScreen*screen) |
279 | +void Controller::Relayout() |
280 | { |
281 | EnsureHud(); |
282 | - nux::Geometry content_geo = view_->GetGeometry(); |
283 | - nux::Geometry geo = GetIdealWindowGeometry(); |
284 | + nux::Geometry const& content_geo = view_->GetGeometry(); |
285 | + nux::Geometry const& geo = GetIdealWindowGeometry(); |
286 | |
287 | window_->SetGeometry(geo); |
288 | layout_->SetMinMaxSize(content_geo.width, content_geo.height); |
289 | @@ -190,7 +202,7 @@ |
290 | } |
291 | |
292 | void Controller::OnMouseDownOutsideWindow(int x, int y, |
293 | - unsigned long bflags, unsigned long kflags) |
294 | + unsigned long bflags, unsigned long kflags) |
295 | { |
296 | LOG_DEBUG(logger) << "OnMouseDownOutsideWindow called"; |
297 | HideHud(); |
298 | @@ -234,16 +246,6 @@ |
299 | return visible_; |
300 | } |
301 | |
302 | -void Controller::SetLauncherIsLockedOut(bool launcher_is_locked_out) |
303 | -{ |
304 | - launcher_is_locked_out_ = launcher_is_locked_out; |
305 | - if (launcher_is_locked_out_) |
306 | - view_->SetHideIcon(IconHideState::HIDE); |
307 | - else |
308 | - view_->SetHideIcon(IconHideState::SHOW); |
309 | - Relayout(); |
310 | -} |
311 | - |
312 | void Controller::ShowHud() |
313 | { |
314 | PluginAdapter* adaptor = PluginAdapter::Default(); |
315 | @@ -259,6 +261,15 @@ |
316 | return; |
317 | } |
318 | |
319 | + unsigned int target_monitor = GetTargetMonitor(); |
320 | + |
321 | + if (target_monitor != monitor_index_) |
322 | + { |
323 | + Relayout(); |
324 | + monitor_index_ = target_monitor; |
325 | + } |
326 | + |
327 | + view_->ShowEmbeddedIcon(!IsLockedToLauncher(monitor_index_)); |
328 | view_->AboutToShow(); |
329 | |
330 | // we first want to grab the currently active window, luckly we can just ask the jason interface(bamf) |
331 | @@ -289,7 +300,6 @@ |
332 | // hide the launcher |
333 | GVariant* message_data = g_variant_new("(b)", TRUE); |
334 | ubus.SendMessage(UBUS_LAUNCHER_LOCK_HIDE, message_data); |
335 | - monitor_index_ = UScreen::GetDefault()->GetMonitorWithMouse(); |
336 | GVariant* info = g_variant_new(UBUS_OVERLAY_FORMAT_STRING, "hud", FALSE, monitor_index_); |
337 | ubus.SendMessage(UBUS_OVERLAY_SHOWN, info); |
338 | |
339 | @@ -410,7 +420,6 @@ |
340 | ubus.SendMessage(UBUS_HUD_ICON_CHANGED, g_variant_new_string(query->icon_name.c_str())); |
341 | } |
342 | |
343 | - |
344 | void Controller::OnQueriesFinished(Hud::Queries queries) |
345 | { |
346 | view_->SetQueries(queries); |
347 | @@ -438,7 +447,10 @@ |
348 | void Controller::AddProperties(GVariantBuilder* builder) |
349 | { |
350 | variant::BuilderWrapper(builder) |
351 | - .add("visible", visible_); |
352 | + .add(window_ ? window_->GetGeometry() : nux::Geometry()) |
353 | + .add("visible", visible_) |
354 | + .add("hud_monitor", monitor_index_) |
355 | + .add("locked_to_launcher", IsLockedToLauncher(monitor_index_)); |
356 | } |
357 | |
358 | |
359 | |
360 | === modified file 'plugins/unityshell/src/HudController.h' |
361 | --- plugins/unityshell/src/HudController.h 2012-03-21 15:30:49 +0000 |
362 | +++ plugins/unityshell/src/HudController.h 2012-03-27 22:51:18 +0000 |
363 | @@ -22,7 +22,6 @@ |
364 | #include <memory> |
365 | |
366 | #include <gdk/gdk.h> |
367 | -#include <UnityCore/GLibSignal.h> |
368 | #include <UnityCore/Hud.h> |
369 | |
370 | #include <NuxCore/Property.h> |
371 | @@ -49,12 +48,13 @@ |
372 | nux::BaseWindow* window() const; |
373 | |
374 | nux::Property<int> launcher_width; |
375 | + nux::Property<bool> launcher_locked_out; |
376 | + nux::Property<bool> multiple_launchers; |
377 | |
378 | void ShowHideHud(); |
379 | void ShowHud(); |
380 | void HideHud(bool restore_focus = true); |
381 | bool IsVisible(); |
382 | - void SetLauncherIsLockedOut(bool launcher_is_locked_out); |
383 | |
384 | protected: |
385 | std::string GetName() const; |
386 | @@ -64,11 +64,13 @@ |
387 | void EnsureHud(); |
388 | void SetupWindow(); |
389 | void SetupHudView(); |
390 | - void SetupRelayoutCallbacks(); |
391 | void RegisterUBusInterests(); |
392 | |
393 | + int GetTargetMonitor(); |
394 | + bool IsLockedToLauncher(int monitor); |
395 | + |
396 | nux::Geometry GetIdealWindowGeometry(); |
397 | - void Relayout(GdkScreen*screen=NULL); |
398 | + void Relayout(); |
399 | |
400 | void OnMouseDownOutsideWindow(int x, int y, unsigned long bflags, unsigned long kflags); |
401 | void OnScreenUngrabbed(); |
402 | @@ -81,8 +83,6 @@ |
403 | void OnQueryActivated(Query::Ptr query); |
404 | void OnQuerySelected(Query::Ptr query); |
405 | |
406 | - |
407 | -private: |
408 | void StartShowHideTimeline(); |
409 | static gboolean OnViewShowHideFrame(Controller* self); |
410 | |
411 | @@ -93,7 +93,6 @@ |
412 | private: |
413 | UBusManager ubus; |
414 | Hud hud_service_; |
415 | - glib::SignalManager sig_manager_; |
416 | nux::BaseWindow* window_; |
417 | bool visible_; |
418 | bool need_show_; |
419 | @@ -101,8 +100,6 @@ |
420 | guint timeline_id_; |
421 | float last_opacity_; |
422 | gint64 start_time_; |
423 | - |
424 | - bool launcher_is_locked_out_; |
425 | |
426 | View* view_; |
427 | guint ensure_id_; |
428 | |
429 | === modified file 'plugins/unityshell/src/HudIcon.cpp' |
430 | --- plugins/unityshell/src/HudIcon.cpp 2012-03-26 22:43:48 +0000 |
431 | +++ plugins/unityshell/src/HudIcon.cpp 2012-03-27 22:51:18 +0000 |
432 | @@ -42,10 +42,6 @@ |
433 | Init(); |
434 | } |
435 | |
436 | -Icon::~Icon() |
437 | -{ |
438 | -} |
439 | - |
440 | void Icon::Init() |
441 | { |
442 | SetMinimumWidth(66); |
443 | @@ -89,6 +85,10 @@ |
444 | icon_renderer_.RenderIcon(GfxContext, arg, toplevel->GetGeometry(), toplevel->GetGeometry()); |
445 | } |
446 | |
447 | +std::string Icon::GetName() const |
448 | +{ |
449 | + return "EmbeddedIcon"; |
450 | +} |
451 | |
452 | } |
453 | } |
454 | |
455 | === modified file 'plugins/unityshell/src/HudIcon.h' |
456 | --- plugins/unityshell/src/HudIcon.h 2012-03-26 22:43:48 +0000 |
457 | +++ plugins/unityshell/src/HudIcon.h 2012-03-27 22:51:18 +0000 |
458 | @@ -53,12 +53,13 @@ |
459 | typedef nux::ObjectPtr<IconTexture> Ptr; |
460 | Icon(nux::BaseTexture* texture, guint width, guint height); |
461 | Icon(std::string const& icon_name, unsigned int size, bool defer_icon_loading = false); |
462 | - ~Icon(); |
463 | |
464 | protected: |
465 | void Draw(nux::GraphicsEngine& GfxContext, bool force_draw); |
466 | void Init(); |
467 | |
468 | + std::string GetName() const; |
469 | + |
470 | nux::ObjectPtr<nux::BaseTexture> background_; |
471 | nux::ObjectPtr<nux::BaseTexture> gloss_; |
472 | nux::ObjectPtr<nux::BaseTexture> edge_; |
473 | |
474 | === modified file 'plugins/unityshell/src/HudView.cpp' |
475 | --- plugins/unityshell/src/HudView.cpp 2012-03-21 15:07:29 +0000 |
476 | +++ plugins/unityshell/src/HudView.cpp 2012-03-27 22:51:18 +0000 |
477 | @@ -64,7 +64,7 @@ |
478 | , current_height_(0) |
479 | , timeline_need_more_draw_(false) |
480 | , selected_button_(0) |
481 | - , icon_state_(IconHideState::SHOW) |
482 | + , show_embedded_icon_(true) |
483 | , activated_signal_sent_(false) |
484 | { |
485 | renderer_.SetOwner(this); |
486 | @@ -127,7 +127,6 @@ |
487 | |
488 | View::~View() |
489 | { |
490 | - RemoveChild(search_bar_.GetPointer()); |
491 | for (auto button = buttons_.begin(); button != buttons_.end(); button++) |
492 | { |
493 | RemoveChild((*button).GetPointer()); |
494 | @@ -272,22 +271,30 @@ |
495 | void View::SetIcon(std::string icon_name) |
496 | { |
497 | LOG_DEBUG(logger) << "Setting icon to " << icon_name; |
498 | - icon_->SetByIconName(icon_name.c_str(), icon_size); |
499 | + icon_->SetByIconName(icon_name, icon_size); |
500 | QueueDraw(); |
501 | } |
502 | |
503 | -void View::SetHideIcon(IconHideState hide_icon) |
504 | +void View::ShowEmbeddedIcon(bool show) |
505 | { |
506 | LOG_DEBUG(logger) << "Hide icon called"; |
507 | - if (hide_icon == icon_state_) |
508 | + if (show == show_embedded_icon_) |
509 | return; |
510 | |
511 | - icon_state_ = hide_icon; |
512 | - |
513 | - if (icon_state_ == IconHideState::HIDE) |
514 | - layout_->RemoveChildObject(dynamic_cast<nux::Area*>(icon_layout_.GetPointer())); |
515 | + show_embedded_icon_ = show; |
516 | + |
517 | + if (show_embedded_icon_) |
518 | + { |
519 | + layout_->AddLayout(icon_layout_.GetPointer(), 0, nux::MINOR_POSITION_TOP, |
520 | + nux::MINOR_SIZE_MATCHCONTENT, 100.0f, nux::LayoutPosition::NUX_LAYOUT_BEGIN); |
521 | + |
522 | + AddChild(icon_.GetPointer()); |
523 | + } |
524 | else |
525 | - layout_->AddLayout(icon_layout_.GetPointer(), 0, nux::MINOR_POSITION_TOP, nux::MINOR_SIZE_MATCHCONTENT, 100.0f, nux::LayoutPosition::NUX_LAYOUT_BEGIN); |
526 | + { |
527 | + layout_->RemoveChildObject(static_cast<nux::Area*>(icon_layout_.GetPointer())); |
528 | + RemoveChild(icon_.GetPointer()); |
529 | + } |
530 | |
531 | Relayout(); |
532 | } |
533 | @@ -303,7 +310,7 @@ |
534 | width = 1024; |
535 | height = 276; |
536 | |
537 | - if (icon_state_ == IconHideState::HIDE) |
538 | + if (!show_embedded_icon_) |
539 | { |
540 | width -= icon_layout_->GetGeometry().width; |
541 | } |
542 | @@ -351,6 +358,7 @@ |
543 | icon_ = new Icon("", icon_size, true); |
544 | icon_layout_ = new nux::VLayout(); |
545 | { |
546 | + AddChild(icon_.GetPointer()); |
547 | icon_layout_->SetVerticalExternalMargin(icon_vertical_margin); |
548 | icon_layout_->AddView(icon_.GetPointer(), 0, nux::MINOR_POSITION_LEFT, nux::MINOR_SIZE_FULL); |
549 | layout_->AddLayout(icon_layout_.GetPointer(), 0, nux::MINOR_POSITION_TOP, nux::MINOR_SIZE_MATCHCONTENT); |
550 | @@ -491,6 +499,7 @@ |
551 | { |
552 | unsigned num_buttons = buttons_.size(); |
553 | variant::BuilderWrapper(builder) |
554 | + .add(GetGeometry()) |
555 | .add("selected_button", selected_button_) |
556 | .add("num_buttons", num_buttons); |
557 | } |
558 | |
559 | === modified file 'plugins/unityshell/src/HudView.h' |
560 | --- plugins/unityshell/src/HudView.h 2012-03-21 14:44:41 +0000 |
561 | +++ plugins/unityshell/src/HudView.h 2012-03-27 22:51:18 +0000 |
562 | @@ -44,12 +44,6 @@ |
563 | namespace hud |
564 | { |
565 | |
566 | -enum IconHideState |
567 | -{ |
568 | - HIDE, |
569 | - SHOW |
570 | -}; |
571 | - |
572 | class View : public nux::View, public unity::debug::Introspectable |
573 | { |
574 | NUX_DECLARE_OBJECT_TYPE(HudView, nux::View); |
575 | @@ -65,7 +59,7 @@ |
576 | |
577 | void SetQueries(Hud::Queries queries); |
578 | void SetIcon(std::string icon_name); |
579 | - void SetHideIcon(IconHideState hide_icon); |
580 | + void ShowEmbeddedIcon(bool show); |
581 | |
582 | void AboutToShow(); |
583 | void AboutToHide(); |
584 | @@ -126,7 +120,7 @@ |
585 | int current_height_; |
586 | bool timeline_need_more_draw_; |
587 | int selected_button_; |
588 | - IconHideState icon_state_; |
589 | + bool show_embedded_icon_; |
590 | bool activated_signal_sent_; |
591 | }; |
592 | |
593 | |
594 | === modified file 'plugins/unityshell/src/IconTexture.cpp' |
595 | --- plugins/unityshell/src/IconTexture.cpp 2012-03-27 01:38:08 +0000 |
596 | +++ plugins/unityshell/src/IconTexture.cpp 2012-03-27 22:51:18 +0000 |
597 | @@ -57,44 +57,47 @@ |
598 | } |
599 | |
600 | IconTexture::IconTexture(std::string const& icon_name, unsigned int size, bool defer_icon_loading) |
601 | - : TextureArea(NUX_TRACKER_LOCATION) |
602 | - , _accept_key_nav_focus(false) |
603 | - , _icon_name(icon_name.empty() ? DEFAULT_ICON : icon_name) |
604 | - , _size(size) |
605 | - , _texture_width(0) |
606 | - , _texture_height(0) |
607 | - , _loading(false) |
608 | - , _opacity(1.0f) |
609 | + : TextureArea(NUX_TRACKER_LOCATION), |
610 | + _accept_key_nav_focus(false), |
611 | + _icon_name(!icon_name.empty() ? icon_name : DEFAULT_ICON), |
612 | + _size(size), |
613 | + _texture_width(0), |
614 | + _texture_height(0), |
615 | + _loading(false), |
616 | + _opacity(1.0f) |
617 | { |
618 | - |
619 | - if (_icon_name != "" && !defer_icon_loading) |
620 | + if (!defer_icon_loading) |
621 | LoadIcon(); |
622 | } |
623 | |
624 | +IconTexture::~IconTexture() |
625 | +{} |
626 | + |
627 | void IconTexture::SetByIconName(std::string const& icon_name, unsigned int size) |
628 | { |
629 | + if (_icon_name == icon_name && _size == size) |
630 | + return; |
631 | + |
632 | _icon_name = icon_name; |
633 | _size = size; |
634 | + |
635 | LoadIcon(); |
636 | } |
637 | |
638 | + |
639 | void IconTexture::SetByFilePath(std::string const& file_path, unsigned int size) |
640 | { |
641 | - _icon_name = file_path; |
642 | - _size = size; |
643 | - |
644 | - LoadIcon(); |
645 | + SetByIconName(file_path, size); |
646 | } |
647 | |
648 | void IconTexture::LoadIcon() |
649 | { |
650 | LOG_DEBUG(logger) << "LoadIcon called (" << _icon_name << ") - loading: " << _loading; |
651 | -static const char* const DEFAULT_GICON = ". GThemedIcon text-x-preview"; |
652 | - if (_icon_name.empty()) |
653 | - return; |
654 | + static const char* const DEFAULT_GICON = ". GThemedIcon text-x-preview"; |
655 | |
656 | if (_loading) |
657 | return; |
658 | + |
659 | _loading = true; |
660 | |
661 | glib::Object<GIcon> icon(::g_icon_new_for_string(_icon_name.empty() ? DEFAULT_GICON : _icon_name.c_str(), NULL)); |
662 | @@ -231,7 +234,7 @@ |
663 | { |
664 | unity::variant::BuilderWrapper(builder) |
665 | .add(GetGeometry()) |
666 | - .add("iconname", _icon_name); |
667 | + .add("icon_name", _icon_name); |
668 | } |
669 | |
670 | // |
671 | |
672 | === modified file 'plugins/unityshell/src/IconTexture.h' |
673 | --- plugins/unityshell/src/IconTexture.h 2012-03-26 22:43:48 +0000 |
674 | +++ plugins/unityshell/src/IconTexture.h 2012-03-27 22:51:18 +0000 |
675 | @@ -38,6 +38,7 @@ |
676 | public: |
677 | IconTexture(nux::BaseTexture* texture, guint width, guint height); |
678 | IconTexture(std::string const& icon_name, unsigned int size, bool defer_icon_loading = false); |
679 | + virtual ~IconTexture(); |
680 | |
681 | void SetByIconName(std::string const& icon_name, unsigned int size); |
682 | void SetByFilePath(std::string const& file_path, unsigned int size); |
683 | |
684 | === modified file 'plugins/unityshell/src/LauncherIcon.cpp' |
685 | --- plugins/unityshell/src/LauncherIcon.cpp 2012-03-26 23:23:42 +0000 |
686 | +++ plugins/unityshell/src/LauncherIcon.cpp 2012-03-27 22:51:18 +0000 |
687 | @@ -185,18 +185,20 @@ |
688 | LauncherIcon::AddProperties(GVariantBuilder* builder) |
689 | { |
690 | unity::variant::BuilderWrapper(builder) |
691 | - .add("x", _center[0].x) |
692 | - .add("y", _center[0].y) |
693 | - .add("z", _center[0].z) |
694 | - .add("related-windows", (int)Windows().size()) |
695 | - .add("icon-type", _icon_type) |
696 | - .add("tooltip-text", tooltip_text()) |
697 | - .add("sort-priority", _sort_priority) |
698 | - .add("quirk-active", GetQuirk(QUIRK_ACTIVE)) |
699 | - .add("quirk-visible", GetQuirk(QUIRK_VISIBLE)) |
700 | - .add("quirk-urgent", GetQuirk(QUIRK_URGENT)) |
701 | - .add("quirk-running", GetQuirk(QUIRK_RUNNING)) |
702 | - .add("quirk-presented", GetQuirk(QUIRK_PRESENTED)); |
703 | + .add("center_x", _center[0].x) |
704 | + .add("center_y", _center[0].y) |
705 | + .add("center_z", _center[0].z) |
706 | + .add("related_windows", static_cast<unsigned int>(Windows().size())) |
707 | + .add("icon_type", _icon_type) |
708 | + .add("tooltip_text", tooltip_text()) |
709 | + .add("sort_priority", _sort_priority) |
710 | + .add("active", GetQuirk(QUIRK_ACTIVE)) |
711 | + .add("visible", GetQuirk(QUIRK_VISIBLE)) |
712 | + .add("urgent", GetQuirk(QUIRK_URGENT)) |
713 | + .add("running", GetQuirk(QUIRK_RUNNING)) |
714 | + .add("starting", GetQuirk(QUIRK_STARTING)) |
715 | + .add("desaturated", GetQuirk(QUIRK_DESAT)) |
716 | + .add("presented", GetQuirk(QUIRK_PRESENTED)); |
717 | } |
718 | |
719 | void |
720 | |
721 | === modified file 'plugins/unityshell/src/SimpleLauncherIcon.cpp' |
722 | --- plugins/unityshell/src/SimpleLauncherIcon.cpp 2012-03-14 06:24:18 +0000 |
723 | +++ plugins/unityshell/src/SimpleLauncherIcon.cpp 2012-03-27 22:51:18 +0000 |
724 | @@ -23,6 +23,7 @@ |
725 | #include <NuxCore/Logger.h> |
726 | #include <Nux/Nux.h> |
727 | #include <Nux/BaseWindow.h> |
728 | +#include <UnityCore/Variant.h> |
729 | |
730 | #include "SimpleLauncherIcon.h" |
731 | #include "PluginAdapter.h" |
732 | @@ -148,6 +149,12 @@ |
733 | return "SimpleLauncherIcon"; |
734 | } |
735 | |
736 | +void SimpleLauncherIcon::AddProperties(GVariantBuilder* builder) |
737 | +{ |
738 | + LauncherIcon::AddProperties(builder); |
739 | + variant::BuilderWrapper(builder).add("icon_name", icon_name); |
740 | +} |
741 | + |
742 | } // namespace launcher |
743 | } // namespace unity |
744 | |
745 | |
746 | === modified file 'plugins/unityshell/src/SimpleLauncherIcon.h' |
747 | --- plugins/unityshell/src/SimpleLauncherIcon.h 2012-03-14 06:24:18 +0000 |
748 | +++ plugins/unityshell/src/SimpleLauncherIcon.h 2012-03-27 22:51:18 +0000 |
749 | @@ -47,6 +47,8 @@ |
750 | |
751 | protected: |
752 | std::string GetName() const; |
753 | + void AddProperties(GVariantBuilder* builder); |
754 | + |
755 | virtual void OnMouseDown(int button, int monitor); |
756 | virtual void OnMouseUp(int button, int monitor); |
757 | virtual void OnMouseClick(int button, int monitor); |
758 | |
759 | === modified file 'plugins/unityshell/src/unityshell.cpp' |
760 | --- plugins/unityshell/src/unityshell.cpp 2012-03-26 21:52:33 +0000 |
761 | +++ plugins/unityshell/src/unityshell.cpp 2012-03-27 22:51:18 +0000 |
762 | @@ -2520,6 +2520,7 @@ |
763 | case UnityshellOptions::NumLaunchers: |
764 | launcher_controller_->multiple_launchers = optionGetNumLaunchers() == 0; |
765 | dash_controller_->use_primary = !launcher_controller_->multiple_launchers(); |
766 | + hud_controller_->multiple_launchers = launcher_controller_->multiple_launchers(); |
767 | break; |
768 | case UnityshellOptions::LauncherCaptureMouse: |
769 | launcher_options->edge_resist = optionGetLauncherCaptureMouse(); |
770 | @@ -2540,7 +2541,7 @@ |
771 | case UnityshellOptions::LauncherHideMode: |
772 | { |
773 | launcher_options->hide_mode = (unity::launcher::LauncherHideMode) optionGetLauncherHideMode(); |
774 | - hud_controller_->SetLauncherIsLockedOut(launcher_options->hide_mode == unity::launcher::LauncherHideMode::LAUNCHER_HIDE_NEVER); |
775 | + hud_controller_->launcher_locked_out = (launcher_options->hide_mode == unity::launcher::LauncherHideMode::LAUNCHER_HIDE_NEVER); |
776 | break; |
777 | } |
778 | case UnityshellOptions::BacklightMode: |
779 | @@ -2775,7 +2776,8 @@ |
780 | /* Setup Hud */ |
781 | hud_controller_.reset(new hud::Controller()); |
782 | auto hide_mode = (unity::launcher::LauncherHideMode) optionGetLauncherHideMode(); |
783 | - hud_controller_->SetLauncherIsLockedOut(hide_mode == unity::launcher::LauncherHideMode::LAUNCHER_HIDE_NEVER); |
784 | + hud_controller_->launcher_locked_out = (hide_mode == unity::launcher::LauncherHideMode::LAUNCHER_HIDE_NEVER); |
785 | + hud_controller_->multiple_launchers = (optionGetNumLaunchers() == 0); |
786 | AddChild(hud_controller_.get()); |
787 | LOG_INFO(logger) << "initLauncher-hud " << timer.ElapsedSeconds() << "s"; |
788 | |
789 | |
790 | === modified file 'tests/autopilot/autopilot/emulators/X11.py' |
791 | --- tests/autopilot/autopilot/emulators/X11.py 2012-03-25 20:50:33 +0000 |
792 | +++ tests/autopilot/autopilot/emulators/X11.py 2012-03-27 22:51:18 +0000 |
793 | @@ -360,10 +360,20 @@ |
794 | Returns a tuple containing (x,y,width,height). |
795 | |
796 | """ |
797 | - if monitor_number >= self.get_num_monitors(): |
798 | + if monitor_number < 0 or monitor_number >= self.get_num_monitors(): |
799 | raise ValueError('Specified monitor number is out of range.') |
800 | return tuple(self._default_screen.get_monitor_geometry(monitor_number)) |
801 | |
802 | + def is_rect_on_monitor(self, monitor_number, rect): |
803 | + """Returns True if `rect` is _entirely_ on the specified monitor, with no overlap.""" |
804 | + |
805 | + if type(rect) is not tuple or len(rect) != 4: |
806 | + raise TypeError("rect must be a tuple of 4 int elements.") |
807 | + |
808 | + (x, y, w, h) = rect |
809 | + (m_x, m_y, m_w, m_h) = self.get_monitor_geometry(monitor_number) |
810 | + return (x >= m_x and x + w <= m_x + m_w and y >= m_y and y + h <= m_y + m_h) |
811 | + |
812 | def move_mouse_to_monitor(self, monitor_number): |
813 | """Move the mouse to the center of the specified monitor.""" |
814 | geo = self.get_monitor_geometry(monitor_number) |
815 | |
816 | === modified file 'tests/autopilot/autopilot/emulators/bamf.py' |
817 | --- tests/autopilot/autopilot/emulators/bamf.py 2012-03-20 00:21:52 +0000 |
818 | +++ tests/autopilot/autopilot/emulators/bamf.py 2012-03-27 22:51:18 +0000 |
819 | @@ -184,6 +184,11 @@ |
820 | return self._view_iface.Name() |
821 | |
822 | @property |
823 | + def icon(self): |
824 | + """Get the application icon.""" |
825 | + return self._view_iface.Icon() |
826 | + |
827 | + @property |
828 | def is_active(self): |
829 | """Is the application active (i.e.- has keyboard focus)?""" |
830 | return self._view_iface.IsActive() |
831 | |
832 | === modified file 'tests/autopilot/autopilot/emulators/unity/hud.py' |
833 | --- tests/autopilot/autopilot/emulators/unity/hud.py 2012-03-04 23:12:19 +0000 |
834 | +++ tests/autopilot/autopilot/emulators/unity/hud.py 2012-03-27 22:51:18 +0000 |
835 | @@ -14,6 +14,16 @@ |
836 | class HudView(UnityIntrospectionObject): |
837 | """Proxy object for the hud view child of the controller.""" |
838 | |
839 | + @property |
840 | + def geometry(self): |
841 | + return (self.x, self.y, self.width, self.height) |
842 | + |
843 | +class EmbeddedIcon(UnityIntrospectionObject): |
844 | + """Proxy object for the hud embedded icon child of the view.""" |
845 | + |
846 | + @property |
847 | + def geometry(self): |
848 | + return (self.x, self.y, self.width, self.height) |
849 | |
850 | class HudController(UnityIntrospectionObject, KeybindingsHelper): |
851 | """Proxy object for the Unity Hud Controller.""" |
852 | @@ -35,11 +45,24 @@ |
853 | """Tap the 'Alt' key to toggle the hud visibility.""" |
854 | self.keybinding("hud/reveal", tap_delay) |
855 | |
856 | + def get_embedded_icon(self): |
857 | + """Returns the HUD view embedded icon or None if is not shown.""" |
858 | + view = self._get_view() |
859 | + if (not view): |
860 | + return None |
861 | + |
862 | + icons = view.get_children_by_type(EmbeddedIcon) |
863 | + return icons[0] if icons else None |
864 | + |
865 | def _get_view(self): |
866 | views = self.get_children_by_type(HudView) |
867 | return views[0] if views else None |
868 | |
869 | @property |
870 | + def geometry(self): |
871 | + return (self.x, self.y, self.width, self.height) |
872 | + |
873 | + @property |
874 | def selected_button(self): |
875 | view = self._get_view() |
876 | if view: |
877 | @@ -54,3 +77,15 @@ |
878 | return view.num_buttons |
879 | else: |
880 | return 0 |
881 | + |
882 | + @property |
883 | + def is_locked_to_launcher(self): |
884 | + return bool(self.locked_to_launcher) |
885 | + |
886 | + @property |
887 | + def monitor(self): |
888 | + return int(self.hud_monitor) |
889 | + |
890 | + @property |
891 | + def has_embedded_icon(self): |
892 | + return (self.get_embedded_icon() != None) |
893 | |
894 | === modified file 'tests/autopilot/autopilot/emulators/unity/icons.py' |
895 | --- tests/autopilot/autopilot/emulators/unity/icons.py 2012-03-04 23:12:19 +0000 |
896 | +++ tests/autopilot/autopilot/emulators/unity/icons.py 2012-03-27 22:51:18 +0000 |
897 | @@ -19,6 +19,11 @@ |
898 | |
899 | """ |
900 | |
901 | + @property |
902 | + def center_position(self): |
903 | + """Get the center point of an icon, returns a tuple with (x, y, z)""" |
904 | + return (self.center_x, self.center_y, self.center_z) |
905 | + |
906 | def get_quicklist(self): |
907 | """Get the quicklist for this launcher icon. |
908 | |
909 | @@ -34,6 +39,10 @@ |
910 | """Represents the BFB button in the launcher.""" |
911 | |
912 | |
913 | +class HudLauncherIcon(SimpleLauncherIcon): |
914 | + """Represents the HUD button in the launcher.""" |
915 | + |
916 | + |
917 | class BamfLauncherIcon(SimpleLauncherIcon): |
918 | """Represents a launcher icon with BAMF integration.""" |
919 | |
920 | |
921 | === modified file 'tests/autopilot/autopilot/emulators/unity/launcher.py' |
922 | --- tests/autopilot/autopilot/emulators/unity/launcher.py 2012-03-25 21:25:54 +0000 |
923 | +++ tests/autopilot/autopilot/emulators/unity/launcher.py 2012-03-27 22:51:18 +0000 |
924 | @@ -12,7 +12,7 @@ |
925 | |
926 | from autopilot.keybindings import KeybindingsHelper |
927 | from autopilot.emulators.unity import UnityIntrospectionObject |
928 | -from autopilot.emulators.unity.icons import BamfLauncherIcon, SimpleLauncherIcon |
929 | +from autopilot.emulators.unity.icons import BFBLauncherIcon, BamfLauncherIcon, SimpleLauncherIcon |
930 | from autopilot.emulators.X11 import Mouse, ScreenGeometry |
931 | |
932 | |
933 | @@ -200,8 +200,8 @@ |
934 | logger.debug("Clicking launcher icon %r on monitor %d with mouse button %d", |
935 | icon, self.monitor, button) |
936 | self.mouse_reveal_launcher() |
937 | - target_x = icon.x + self.x |
938 | - target_y = icon.y + (self.icon_size / 2) |
939 | + target_x = icon.center_x + self.x |
940 | + target_y = icon.center_y |
941 | self._mouse.move(target_x, target_y ) |
942 | self._mouse.click(button) |
943 | self.move_mouse_to_right_of_launcher() |
944 | @@ -258,10 +258,15 @@ |
945 | class LauncherModel(UnityIntrospectionObject): |
946 | """THe launcher model. Contains all launcher icons as children.""" |
947 | |
948 | + def get_bfb_icon(self): |
949 | + icons = BFBLauncherIcon.get_all_instances() |
950 | + assert(len(icons) == 1) |
951 | + return icons[0] |
952 | + |
953 | def get_launcher_icons(self, visible_only=True): |
954 | """Get a list of launcher icons in this launcher.""" |
955 | if visible_only: |
956 | - return self.get_children_by_type(SimpleLauncherIcon, quirk_visible=True) |
957 | + return self.get_children_by_type(SimpleLauncherIcon, visible=True) |
958 | else: |
959 | return self.get_children_by_type(SimpleLauncherIcon) |
960 | |
961 | @@ -281,7 +286,21 @@ |
962 | Returns None if there is no such launcher icon. |
963 | """ |
964 | icons = self.get_children_by_type(SimpleLauncherIcon, desktop_file=desktop_file) |
965 | - return icons or None |
966 | + if len(icons): |
967 | + return icons[0] |
968 | + |
969 | + return None |
970 | + |
971 | + def get_icon_by_desktop_id(self, desktop_id): |
972 | + """Gets a launcher icon with the specified desktop id. |
973 | + |
974 | + Returns None if there is no such launcher icon. |
975 | + """ |
976 | + icons = self.get_children_by_type(SimpleLauncherIcon, desktop_id=desktop_id) |
977 | + if len(icons): |
978 | + return icons[0] |
979 | + |
980 | + return None |
981 | |
982 | def num_launcher_icons(self): |
983 | """Get the number of icons in the launcher model.""" |
984 | |
985 | === modified file 'tests/autopilot/autopilot/emulators/unity/switcher.py' |
986 | --- tests/autopilot/autopilot/emulators/unity/switcher.py 2012-03-07 17:24:15 +0000 |
987 | +++ tests/autopilot/autopilot/emulators/unity/switcher.py 2012-03-27 22:51:18 +0000 |
988 | @@ -136,11 +136,11 @@ |
989 | return None |
990 | |
991 | def get_icon_name(self, index): |
992 | - return self.__get_icon(index)['tooltip-text'] |
993 | + return self.__get_icon(index)['tooltip_text'] |
994 | |
995 | def get_icon_desktop_file(self, index): |
996 | try: |
997 | - return self.__get_icon(index)['desktop-file'] |
998 | + return self.__get_icon(index)['desktop_file'] |
999 | except: |
1000 | return None |
1001 | |
1002 | |
1003 | === modified file 'tests/autopilot/autopilot/tests/__init__.py' |
1004 | --- tests/autopilot/autopilot/tests/__init__.py 2012-03-27 20:48:14 +0000 |
1005 | +++ tests/autopilot/autopilot/tests/__init__.py 2012-03-27 22:51:18 +0000 |
1006 | @@ -25,7 +25,7 @@ |
1007 | from autopilot.emulators.unity.launcher import LauncherController |
1008 | from autopilot.emulators.unity.switcher import Switcher |
1009 | from autopilot.emulators.unity.workspace import WorkspaceManager |
1010 | -from autopilot.emulators.X11 import Keyboard, Mouse |
1011 | +from autopilot.emulators.X11 import ScreenGeometry, Keyboard, Mouse |
1012 | from autopilot.glibrunner import GlibRunner |
1013 | from autopilot.globals import (global_context, |
1014 | video_recording_enabled, |
1015 | @@ -229,17 +229,25 @@ |
1016 | self.dash = Dash() |
1017 | self.switcher = Switcher() |
1018 | self.workspace = WorkspaceManager() |
1019 | + self.screen_geo = ScreenGeometry() |
1020 | self.launcher = self._get_launcher_controller() |
1021 | self.addCleanup(self.workspace.switch_to, self.workspace.current_workspace) |
1022 | self.addCleanup(Keyboard.cleanup) |
1023 | self.addCleanup(Mouse.cleanup) |
1024 | |
1025 | - def start_app(self, app_name, files=[]): |
1026 | + def start_app(self, app_name, files=[], locale=None): |
1027 | """Start one of the known apps, and kill it on tear down. |
1028 | |
1029 | - if files is specified, start the application with the specified files. |
1030 | + If files is specified, start the application with the specified files. |
1031 | + If locale is specified, the locale will be set when the application is launched. |
1032 | """ |
1033 | - logger.info("Starting application '%s'", app_name) |
1034 | + if locale: |
1035 | + os.putenv("LC_ALL", locale) |
1036 | + self.addCleanup(os.unsetenv, "LC_ALL") |
1037 | + logger.info("Starting application '%s' with files %r in locale %s", app_name, files, locale) |
1038 | + else: |
1039 | + logger.info("Starting application '%s' with files %r", app_name, files) |
1040 | + |
1041 | app = self.KNOWN_APPS[app_name] |
1042 | self.bamf.launch_application(app['desktop-file'], files) |
1043 | self.addCleanup(call, ["killall", app['process-name']]) |
1044 | |
1045 | === modified file 'tests/autopilot/autopilot/tests/test_hud.py' |
1046 | --- tests/autopilot/autopilot/tests/test_hud.py 2012-03-21 14:44:41 +0000 |
1047 | +++ tests/autopilot/autopilot/tests/test_hud.py 2012-03-27 22:51:18 +0000 |
1048 | @@ -1,58 +1,81 @@ |
1049 | # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- |
1050 | -# Copyright 2010 Canonical |
1051 | -# Author: Alex Launi |
1052 | +# Copyright 2012 Canonical |
1053 | +# Author: Alex Launi, |
1054 | +# Marco Trevisan |
1055 | # |
1056 | # This program is free software: you can redistribute it and/or modify it |
1057 | # under the terms of the GNU General Public License version 3, as published |
1058 | # by the Free Software Foundation. |
1059 | |
1060 | -from testtools.matchers import Equals, LessThan |
1061 | +from testtools.matchers import Equals, NotEquals, LessThan, GreaterThan |
1062 | from time import sleep |
1063 | |
1064 | +from autopilot.emulators.X11 import ScreenGeometry |
1065 | from autopilot.emulators.unity.hud import HudController |
1066 | -from autopilot.tests import AutopilotTestCase |
1067 | +from autopilot.emulators.unity.icons import HudLauncherIcon |
1068 | +from autopilot.tests import AutopilotTestCase, multiply_scenarios |
1069 | from os import remove |
1070 | |
1071 | -class HudTests(AutopilotTestCase): |
1072 | - |
1073 | - scenarios = [ |
1074 | - ('Launcher never hide', {'launcher_hide_mode': 0}), |
1075 | - ('Launcher autohide', {'launcher_hide_mode': 1}), |
1076 | - ] |
1077 | +def _make_monitor_scenarios(): |
1078 | + num_monitors = ScreenGeometry().get_num_monitors() |
1079 | + scenarios = [] |
1080 | + |
1081 | + if num_monitors == 1: |
1082 | + scenarios = [('Single Monitor', {'hud_monitor': 0})] |
1083 | + |
1084 | + else: |
1085 | + for i in range(num_monitors): |
1086 | + scenarios += [('Monitor %d' % (i), {'hud_monitor': i})] |
1087 | + |
1088 | + return scenarios |
1089 | + |
1090 | +class HudTestsBase(AutopilotTestCase): |
1091 | |
1092 | def setUp(self): |
1093 | - super(HudTests, self).setUp() |
1094 | - self.set_unity_option('launcher_hide_mode', self.launcher_hide_mode) |
1095 | - sleep(0.5) |
1096 | + super(HudTestsBase, self).setUp() |
1097 | + |
1098 | + sleep(0.25) |
1099 | self.hud = self.get_hud_controller() |
1100 | |
1101 | def tearDown(self): |
1102 | self.hud.ensure_hidden() |
1103 | - super(HudTests, self).tearDown() |
1104 | + super(HudTestsBase, self).tearDown() |
1105 | |
1106 | def get_hud_controller(self): |
1107 | controllers = HudController.get_all_instances() |
1108 | self.assertEqual(1, len(controllers)) |
1109 | return controllers[0] |
1110 | |
1111 | + def get_hud_launcher_icon(self): |
1112 | + icons = HudLauncherIcon.get_all_instances() |
1113 | + self.assertEqual(1, len(icons)) |
1114 | + return icons[0] |
1115 | + |
1116 | def get_num_active_launcher_icons(self): |
1117 | num_active = 0 |
1118 | for icon in self.launcher.model.get_launcher_icons(): |
1119 | - if icon.quirk_active and icon.quirk_visible: |
1120 | + if icon.active and icon.visible: |
1121 | num_active += 1 |
1122 | return num_active |
1123 | |
1124 | - def test_initially_hidden(self): |
1125 | - self.assertFalse(self.hud.visible) |
1126 | - |
1127 | def reveal_hud(self): |
1128 | self.hud.toggle_reveal() |
1129 | for counter in range(10): |
1130 | sleep(1) |
1131 | if self.hud.visible: |
1132 | break |
1133 | + |
1134 | self.assertTrue(self.hud.visible, "HUD did not appear.") |
1135 | |
1136 | + |
1137 | +class HudBehaviorTests(HudTestsBase): |
1138 | + |
1139 | + def setUp(self): |
1140 | + super(HudBehaviorTests, self).setUp() |
1141 | + |
1142 | + self.hud_monitor = self.screen_geo.get_primary_monitor() |
1143 | + self.screen_geo.move_mouse_to_monitor(self.hud_monitor) |
1144 | + |
1145 | def test_no_initial_values(self): |
1146 | self.reveal_hud() |
1147 | self.assertThat(self.hud.num_buttons, Equals(0)) |
1148 | @@ -121,36 +144,6 @@ |
1149 | sleep(1) |
1150 | self.assertFalse(self.hud.visible) |
1151 | |
1152 | - def test_multiple_hud_reveal_does_not_break_launcher(self): |
1153 | - """Multiple Hud reveals must not cause the launcher to set multiple |
1154 | - apps as active. |
1155 | - |
1156 | - """ |
1157 | - # We need an app to switch to: |
1158 | - self.start_app('Character Map') |
1159 | - # We need an application to play with - I'll use the calculator. |
1160 | - self.start_app('Calculator') |
1161 | - sleep(1) |
1162 | - |
1163 | - # before we start, make sure there's zero or one active icon: |
1164 | - num_active = self.get_num_active_launcher_icons() |
1165 | - self.assertThat(num_active, LessThan(2), "Invalid number of launcher icons active before test has run!") |
1166 | - |
1167 | - # reveal and hide hud several times over: |
1168 | - for i in range(3): |
1169 | - self.hud.ensure_visible() |
1170 | - sleep(0.5) |
1171 | - self.hud.ensure_hidden() |
1172 | - sleep(0.5) |
1173 | - |
1174 | - # click application icons for running apps in the launcher: |
1175 | - icon = self.launcher.model.get_icon_by_tooltip_text("Character Map") |
1176 | - self.launcher.get_launcher_for_monitor(0).click_launcher_icon(icon) |
1177 | - |
1178 | - # see how many apps are marked as being active: |
1179 | - num_active = self.get_num_active_launcher_icons() |
1180 | - self.assertLessEqual(num_active, 1, "More than one launcher icon active after test has run!") |
1181 | - |
1182 | def test_restore_focus(self): |
1183 | """Ensures that once the hud is dismissed, the same application |
1184 | that was focused before hud invocation is refocused |
1185 | @@ -191,7 +184,7 @@ |
1186 | """Read the saved file. The content should be "0 ".""" |
1187 | |
1188 | self.addCleanup(remove, '/tmp/autopilot_gedit_undo_test_temp_file.txt') |
1189 | - self.start_app('Text Editor', files=['/tmp/autopilot_gedit_undo_test_temp_file.txt']) |
1190 | + self.start_app('Text Editor', files=['/tmp/autopilot_gedit_undo_test_temp_file.txt'], locale='C') |
1191 | |
1192 | sleep(1) |
1193 | self.keyboard.type("0") |
1194 | @@ -202,8 +195,9 @@ |
1195 | sleep(1) |
1196 | |
1197 | self.keyboard.type("undo") |
1198 | + sleep(1) |
1199 | self.keyboard.press_and_release('Return') |
1200 | - sleep(1) |
1201 | + sleep(.5) |
1202 | |
1203 | self.keyboard.press_and_release("Ctrl+s") |
1204 | sleep(1) |
1205 | @@ -211,3 +205,199 @@ |
1206 | contents = open("/tmp/autopilot_gedit_undo_test_temp_file.txt").read().strip('\n') |
1207 | self.assertEqual("0 ", contents) |
1208 | |
1209 | + |
1210 | +class HudLauncherInteractionsTests(HudTestsBase): |
1211 | + |
1212 | + launcher_modes = [('Launcher autohide', {'launcher_autohide': False}), |
1213 | + ('Launcher never hide', {'launcher_autohide': True})] |
1214 | + |
1215 | + scenarios = multiply_scenarios(_make_monitor_scenarios(), launcher_modes) |
1216 | + |
1217 | + def setUp(self): |
1218 | + super(HudLauncherInteractionsTests, self).setUp() |
1219 | + # Launchers on all monitors |
1220 | + self.set_unity_option('num_launchers', 0) |
1221 | + self.set_unity_option('launcher_hide_mode', int(self.launcher_autohide)) |
1222 | + |
1223 | + self.screen_geo.move_mouse_to_monitor(self.hud_monitor) |
1224 | + sleep(0.5) |
1225 | + |
1226 | + def test_multiple_hud_reveal_does_not_break_launcher(self): |
1227 | + """Multiple Hud reveals must not cause the launcher to set multiple |
1228 | + apps as active. |
1229 | + |
1230 | + """ |
1231 | + launcher = self.launcher.get_launcher_for_monitor(self.hud_monitor) |
1232 | + |
1233 | + # We need an app to switch to: |
1234 | + self.start_app('Character Map') |
1235 | + # We need an application to play with - I'll use the calculator. |
1236 | + self.start_app('Calculator') |
1237 | + sleep(1) |
1238 | + |
1239 | + # before we start, make sure there's zero or one active icon: |
1240 | + num_active = self.get_num_active_launcher_icons() |
1241 | + self.assertThat(num_active, LessThan(2), "Invalid number of launcher icons active before test has run!") |
1242 | + |
1243 | + # reveal and hide hud several times over: |
1244 | + for i in range(3): |
1245 | + self.hud.ensure_visible() |
1246 | + sleep(0.5) |
1247 | + self.hud.ensure_hidden() |
1248 | + sleep(0.5) |
1249 | + |
1250 | + # click application icons for running apps in the launcher: |
1251 | + icon = self.launcher.model.get_icon_by_desktop_id("gucharmap.desktop") |
1252 | + launcher.click_launcher_icon(icon) |
1253 | + |
1254 | + # see how many apps are marked as being active: |
1255 | + num_active = self.get_num_active_launcher_icons() |
1256 | + self.assertLessEqual(num_active, 1, "More than one launcher icon active after test has run!") |
1257 | + |
1258 | + def test_hud_does_not_change_launcher_status(self): |
1259 | + """Tests if the HUD reveal keeps the launcher in the status it was""" |
1260 | + |
1261 | + launcher = self.launcher.get_launcher_for_monitor(self.hud_monitor) |
1262 | + |
1263 | + launcher_shows_pre = launcher.is_showing() |
1264 | + sleep(.25) |
1265 | + |
1266 | + self.reveal_hud() |
1267 | + sleep(1) |
1268 | + |
1269 | + launcher_shows_post = launcher.is_showing() |
1270 | + self.assertThat(launcher_shows_pre, Equals(launcher_shows_post)) |
1271 | + |
1272 | + |
1273 | +class HudLockedLauncherInteractionsTests(HudTestsBase): |
1274 | + |
1275 | + scenarios = _make_monitor_scenarios() |
1276 | + |
1277 | + def setUp(self): |
1278 | + super(HudLockedLauncherInteractionsTests, self).setUp() |
1279 | + # Locked Launchers on all monitors |
1280 | + self.set_unity_option('num_launchers', 0) |
1281 | + self.set_unity_option('launcher_hide_mode', 0) |
1282 | + |
1283 | + self.screen_geo.move_mouse_to_monitor(self.hud_monitor) |
1284 | + sleep(0.5) |
1285 | + |
1286 | + def test_hud_launcher_icon_hides_bfb(self): |
1287 | + """Tests that the BFB icon is hidden when the HUD launcher icon is shown""" |
1288 | + |
1289 | + hud_icon = self.get_hud_launcher_icon() |
1290 | + bfb_icon = self.launcher.model.get_bfb_icon() |
1291 | + |
1292 | + self.assertTrue(bfb_icon.visible) |
1293 | + self.assertFalse(hud_icon.visible) |
1294 | + sleep(.25) |
1295 | + |
1296 | + self.reveal_hud() |
1297 | + sleep(.5) |
1298 | + |
1299 | + self.assertTrue(hud_icon.visible) |
1300 | + self.assertFalse(bfb_icon.visible) |
1301 | + |
1302 | + def test_hud_desaturates_launcher_icons(self): |
1303 | + """Tests that the launcher icons are desaturates when HUD is open""" |
1304 | + |
1305 | + self.reveal_hud() |
1306 | + sleep(.5) |
1307 | + |
1308 | + for icon in self.launcher.model.get_launcher_icons(): |
1309 | + if isinstance(icon, HudLauncherIcon): |
1310 | + self.assertFalse(icon.desaturated) |
1311 | + else: |
1312 | + self.assertTrue(icon.desaturated) |
1313 | + |
1314 | + |
1315 | +class HudVisualTests(HudTestsBase): |
1316 | + |
1317 | + launcher_modes = [('Launcher autohide', {'launcher_autohide': False}), |
1318 | + ('Launcher never hide', {'launcher_autohide': True})] |
1319 | + |
1320 | + launcher_screen = [('Launcher on primary monitor', {'launcher_primary_only': False}), |
1321 | + ('Launcher on all monitors', {'launcher_primary_only': True})] |
1322 | + |
1323 | + scenarios = multiply_scenarios(_make_monitor_scenarios(), launcher_modes, launcher_screen) |
1324 | + |
1325 | + def setUp(self): |
1326 | + super(HudVisualTests, self).setUp() |
1327 | + self.screen_geo.move_mouse_to_monitor(self.hud_monitor) |
1328 | + self.set_unity_option('launcher_hide_mode', int(self.launcher_autohide)) |
1329 | + self.set_unity_option('num_launchers', int(self.launcher_primary_only)) |
1330 | + self.hud_monitor_is_primary = (self.screen_geo.get_primary_monitor() == self.hud_monitor) |
1331 | + self.hud_locked = (not self.launcher_autohide and (not self.launcher_primary_only or self.hud_monitor_is_primary)) |
1332 | + sleep(0.5) |
1333 | + |
1334 | + def test_initially_hidden(self): |
1335 | + self.assertFalse(self.hud.visible) |
1336 | + |
1337 | + def test_hud_is_on_right_monitor(self): |
1338 | + """Tests if the hud is shown and fits the monitor where it should be""" |
1339 | + self.reveal_hud() |
1340 | + self.assertThat(self.hud_monitor, Equals(self.hud.monitor)) |
1341 | + self.assertTrue(self.screen_geo.is_rect_on_monitor(self.hud.monitor, self.hud.geometry)) |
1342 | + |
1343 | + def test_hud_geometries(self): |
1344 | + """Tests the HUD geometries for the given monitor and status""" |
1345 | + self.reveal_hud() |
1346 | + monitor_geo = self.screen_geo.get_monitor_geometry(self.hud_monitor) |
1347 | + monitor_x = monitor_geo[0] |
1348 | + monitor_w = monitor_geo[2] |
1349 | + hud_x = self.hud.geometry[0] |
1350 | + hud_w = self.hud.geometry[2] |
1351 | + |
1352 | + if self.hud_locked: |
1353 | + self.assertThat(hud_x, GreaterThan(monitor_x)) |
1354 | + self.assertThat(hud_x, LessThan(monitor_x + monitor_w)) |
1355 | + self.assertThat(hud_w, Equals(monitor_x + monitor_w - hud_x)) |
1356 | + else: |
1357 | + self.assertThat(hud_x, Equals(monitor_x)) |
1358 | + self.assertThat(hud_w, Equals(monitor_w)) |
1359 | + |
1360 | + def test_hud_is_locked_to_launcher(self): |
1361 | + """Tests if the HUD is locked to launcher as we expect or not""" |
1362 | + self.reveal_hud() |
1363 | + sleep(.25) |
1364 | + |
1365 | + self.assertThat(self.hud.is_locked_to_launcher, Equals(self.hud_locked)) |
1366 | + |
1367 | + def test_hud_icon_is_shown(self): |
1368 | + """Tests that the correct HUD icon is shown""" |
1369 | + self.reveal_hud() |
1370 | + sleep(.5) |
1371 | + |
1372 | + hud_launcher_icon = self.get_hud_launcher_icon() |
1373 | + hud_embedded_icon = self.hud.get_embedded_icon() |
1374 | + |
1375 | + # FIXME this should check self.hud.is_locked_to_launcher |
1376 | + # but the HUD icon is currently shared between launchers. |
1377 | + if not self.launcher_autohide: |
1378 | + self.assertTrue(hud_launcher_icon.visible) |
1379 | + self.assertFalse(hud_launcher_icon.desaturated) |
1380 | + |
1381 | + # FIXME remove this once the issue above has been resolved |
1382 | + if self.hud.is_locked_to_launcher: |
1383 | + self.assertThat(hud_embedded_icon, Equals(None)) |
1384 | + else: |
1385 | + self.assertThat(hud_embedded_icon, NotEquals(None)) |
1386 | + self.assertFalse(hud_launcher_icon.visible) |
1387 | + |
1388 | + def test_hud_icon_show_the_focused_application_emblem(self): |
1389 | + """Tests that the correct HUD icon is shown""" |
1390 | + self.start_app("Calculator") |
1391 | + calctools = self.get_app_instances("Calculator") |
1392 | + self.assertThat(len(calctools), GreaterThan(0)) |
1393 | + calc = calctools[0] |
1394 | + self.assertTrue(calc.is_active) |
1395 | + |
1396 | + self.reveal_hud() |
1397 | + sleep(.5) |
1398 | + |
1399 | + if self.hud.is_locked_to_launcher: |
1400 | + hud_launcher_icon = self.get_hud_launcher_icon() |
1401 | + self.assertThat(hud_launcher_icon.icon_name, Equals(calc.icon)) |
1402 | + else: |
1403 | + hud_embedded_icon = self.hud.get_embedded_icon() |
1404 | + self.assertThat(hud_embedded_icon.icon_name, Equals(calc.icon)) |
1405 | |
1406 | === modified file 'tests/autopilot/autopilot/tests/test_launcher.py' |
1407 | --- tests/autopilot/autopilot/tests/test_launcher.py 2012-03-27 20:48:14 +0000 |
1408 | +++ tests/autopilot/autopilot/tests/test_launcher.py 2012-03-27 22:51:18 +0000 |
1409 | @@ -534,9 +534,8 @@ |
1410 | def test_launcher_does_not_reveal_with_mouse_down(self): |
1411 | """Launcher must not reveal if have mouse button 1 down.""" |
1412 | launcher_instance = self.get_launcher() |
1413 | - screens = ScreenGeometry() |
1414 | |
1415 | - screens.move_mouse_to_monitor(launcher_instance.monitor) |
1416 | + self.screen_geo.move_mouse_to_monitor(launcher_instance.monitor) |
1417 | self.mouse.press(1) |
1418 | launcher_instance.mouse_reveal_launcher() |
1419 | self.assertThat(launcher_instance.is_showing(), Equals(False)) |
1420 | |
1421 | === modified file 'tests/autopilot/autopilot/tests/test_shortcut_hint.py' |
1422 | --- tests/autopilot/autopilot/tests/test_shortcut_hint.py 2012-03-21 22:32:36 +0000 |
1423 | +++ tests/autopilot/autopilot/tests/test_shortcut_hint.py 2012-03-27 22:51:18 +0000 |
1424 | @@ -29,9 +29,8 @@ |
1425 | sleep(1) |
1426 | |
1427 | def skip_if_monitor_too_small(self): |
1428 | - screen = ScreenGeometry(); |
1429 | - monitor = screen.get_primary_monitor() |
1430 | - monitor_geo = screen.get_monitor_geometry(monitor); |
1431 | + monitor = self.screen_geo.get_primary_monitor() |
1432 | + monitor_geo = self.screen_geo.get_monitor_geometry(monitor); |
1433 | monitor_w = monitor_geo[2]; |
1434 | monitor_h = monitor_geo[3]; |
1435 | launcher_width = self.launcher.get_launcher_for_monitor(monitor).geometry[2]; |
1436 | @@ -49,8 +48,7 @@ |
1437 | def get_launcher(self): |
1438 | # We could parameterise this so all tests run on both monitors (if MM is |
1439 | # set up), but I think it's fine to just always use monitor primary monitor: |
1440 | - screen = ScreenGeometry(); |
1441 | - monitor = screen.get_primary_monitor() |
1442 | + monitor = self.screen_geo.get_primary_monitor() |
1443 | return self.launcher.get_launcher_for_monitor(monitor) |
1444 | |
1445 | |
1446 | |
1447 | === modified file 'tests/autopilot/autopilot/tests/test_showdesktop.py' |
1448 | --- tests/autopilot/autopilot/tests/test_showdesktop.py 2012-03-12 04:06:44 +0000 |
1449 | +++ tests/autopilot/autopilot/tests/test_showdesktop.py 2012-03-27 22:51:18 +0000 |
1450 | @@ -9,6 +9,7 @@ |
1451 | from time import sleep |
1452 | |
1453 | from autopilot.emulators.unity.switcher import Switcher |
1454 | +from autopilot.emulators.unity.icons import DesktopLauncherIcon |
1455 | from autopilot.tests import AutopilotTestCase |
1456 | |
1457 | |
1458 | @@ -23,8 +24,8 @@ |
1459 | |
1460 | def launch_test_apps(self): |
1461 | """Launch character map and calculator apps.""" |
1462 | - self.start_app('Character Map') |
1463 | - self.start_app('Calculator') |
1464 | + self.start_app('Character Map', locale='C') |
1465 | + self.start_app('Calculator', locale='C') |
1466 | sleep(1) |
1467 | |
1468 | def test_showdesktop_hides_apps(self): |
1469 | @@ -75,7 +76,7 @@ |
1470 | self.assertTrue(win.is_hidden, "Window '%s' is not hidden after show desktop activated." % (win.title)) |
1471 | |
1472 | # We'll un-minimise the character map - find it's launcherIcon in the launcher: |
1473 | - charmap_icon = self.launcher.model.get_icon_by_tooltip_text('Character Map') |
1474 | + charmap_icon = self.launcher.model.get_icon_by_desktop_id("gucharmap.desktop") |
1475 | if charmap_icon: |
1476 | self.launcher.get_launcher_for_monitor(0).click_launcher_icon(charmap_icon) |
1477 | else: |
1478 | @@ -108,7 +109,7 @@ |
1479 | for i in range(switcher.get_model_size()): |
1480 | current_icon = switcher.current_icon |
1481 | self.assertIsNotNone(current_icon) |
1482 | - if current_icon.tooltip_text == 'Show Desktop': |
1483 | + if isinstance(current_icon, DesktopLauncherIcon): |
1484 | found = True |
1485 | break |
1486 | switcher.previous_icon() |
1487 | |
1488 | === modified file 'tests/autopilot/autopilot/tests/test_switcher.py' |
1489 | --- tests/autopilot/autopilot/tests/test_switcher.py 2012-03-14 06:24:18 +0000 |
1490 | +++ tests/autopilot/autopilot/tests/test_switcher.py 2012-03-27 22:51:18 +0000 |
1491 | @@ -292,6 +292,11 @@ |
1492 | class SwitcherWorkspaceTests(AutopilotTestCase): |
1493 | """Test Switcher behavior with respect to multiple workspaces.""" |
1494 | |
1495 | + def get_bamf_application(self, name): |
1496 | + apps = self.get_app_instances(name) |
1497 | + self.assertThat(len(apps), Equals(1)) |
1498 | + return apps[0] |
1499 | + |
1500 | def test_switcher_shows_current_workspace_only(self): |
1501 | """Switcher must show apps from the current workspace only.""" |
1502 | self.close_all_app('Calculator') |
1503 | @@ -308,8 +313,8 @@ |
1504 | sleep(1) |
1505 | icon_names = [i.tooltip_text for i in self.switcher.get_switcher_icons()] |
1506 | self.switcher.terminate() |
1507 | - self.assertThat(icon_names, Contains("Character Map")) |
1508 | - self.assertThat(icon_names, Not(Contains("Calculator"))) |
1509 | + self.assertThat(icon_names, Contains(self.get_bamf_application("Character Map").name)) |
1510 | + self.assertThat(icon_names, Not(Contains(self.get_bamf_application("Calculator").name))) |
1511 | |
1512 | def test_switcher_all_mode_shows_all_apps(self): |
1513 | """Test switcher 'show_all' mode shows apps from all workspaces.""" |
1514 | @@ -327,8 +332,8 @@ |
1515 | sleep(1) |
1516 | icon_names = [i.tooltip_text for i in self.switcher.get_switcher_icons()] |
1517 | self.switcher.terminate() |
1518 | - self.assertThat(icon_names, Contains("Character Map")) |
1519 | - self.assertThat(icon_names, Contains("Calculator")) |
1520 | + self.assertThat(icon_names, Contains(self.get_bamf_application("Calculator").name)) |
1521 | + self.assertThat(icon_names, Contains(self.get_bamf_application("Character Map").name)) |
1522 | |
1523 | def test_switcher_can_switch_to_minimised_window(self): |
1524 | """Switcher must be able to switch to a minimised window when there's |
1525 | @@ -353,16 +358,14 @@ |
1526 | |
1527 | self.switcher.initiate() |
1528 | sleep(1) |
1529 | - while self.switcher.current_icon.tooltip_text != 'Mahjongg': |
1530 | + while self.switcher.current_icon.tooltip_text != self.get_bamf_application("Mahjongg").name: |
1531 | self.switcher.next_icon() |
1532 | sleep(1) |
1533 | self.switcher.stop() |
1534 | sleep(1) |
1535 | |
1536 | - #get calculator windows - there should be only one: |
1537 | - mahjongg_apps = self.get_app_instances("Mahjongg") |
1538 | - self.assertThat(len(mahjongg_apps), Equals(1)) |
1539 | - wins = mahjongg_apps[0].get_windows() |
1540 | + #get mahjongg windows - there should be two: |
1541 | + wins = self.get_bamf_application("Mahjongg").get_windows() |
1542 | self.assertThat(len(wins), Equals(2)) |
1543 | # Ideally we should be able to find the instance that is on the |
1544 | # current workspace and ask that one if it is hidden. |
+1, seems good here