~3v1n0/unity/overlay-border-scale

« back to all changes in this revision

Viewing changes to tests/autopilot/autopilot/emulators/unity/dash.py

  • Committer: Daniel van Vugt
  • Date: 2012-03-14 06:24:18 UTC
  • mfrom: (2108 unity)
  • mto: This revision was merged to the branch mainline in revision 2146.
  • Revision ID: daniel.van.vugt@canonical.com-20120314062418-nprucpbr0m7qky5e
MergedĀ latestĀ lp:unity

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
 
2
# Copyright 2012 Canonical
 
3
# Author: Thomi Richards
 
4
#
 
5
# This program is free software: you can redistribute it and/or modify it
 
6
# under the terms of the GNU General Public License version 3, as published
 
7
# by the Free Software Foundation.
 
8
#
 
9
 
 
10
from time import sleep
 
11
 
 
12
from autopilot.emulators.unity import (
 
13
    get_state_by_path,
 
14
    make_introspection_object,
 
15
    UnityIntrospectionObject,
 
16
    )
 
17
from autopilot.emulators.X11 import Keyboard, Mouse
 
18
from autopilot.keybindings import KeybindingsHelper
 
19
 
 
20
import logging
 
21
 
 
22
 
 
23
logger = logging.getLogger(__name__)
 
24
 
 
25
 
 
26
class Dash(KeybindingsHelper):
 
27
    """
 
28
    An emulator class that makes it easier to interact with the unity dash.
 
29
    """
 
30
 
 
31
    def __init__(self):
 
32
        self.controller = DashController.get_all_instances()[0]
 
33
        self.view = self.controller.get_dash_view()
 
34
 
 
35
        self._keyboard = Keyboard()
 
36
        super(Dash, self).__init__()
 
37
 
 
38
    def toggle_reveal(self):
 
39
        """
 
40
        Reveals the dash if it's currently hidden, hides it otherwise.
 
41
        """
 
42
        logger.debug("Toggling dash visibility with Super key.")
 
43
        self.keybinding("dash/reveal")
 
44
        sleep(1)
 
45
 
 
46
    def ensure_visible(self, clear_search=True):
 
47
        """
 
48
        Ensures the dash is visible.
 
49
        """
 
50
        if not self.get_is_visible():
 
51
            self.toggle_reveal()
 
52
            self._wait_for_visibility(expect_visible=True)
 
53
            if clear_search:
 
54
                self.clear_search()
 
55
 
 
56
    def ensure_hidden(self):
 
57
        """
 
58
        Ensures the dash is hidden.
 
59
        """
 
60
        if self.get_is_visible():
 
61
            self.toggle_reveal()
 
62
            self._wait_for_visibility(expect_visible=False)
 
63
 
 
64
    def _wait_for_visibility(self, expect_visible):
 
65
        for i in range(11):
 
66
            if self.get_is_visible() != expect_visible:
 
67
                sleep(1)
 
68
            else:
 
69
                return
 
70
        raise RuntimeError("Dash not %s after waiting for 10 seconds." %
 
71
            ("Visible" if expect_visible else "Hidden"))
 
72
 
 
73
    def get_is_visible(self):
 
74
        """
 
75
        Is the dash visible?
 
76
        """
 
77
        return self.controller.visible
 
78
 
 
79
    def get_searchbar(self):
 
80
        """Returns the searchbar attached to the dash."""
 
81
        return self.view.get_searchbar()
 
82
 
 
83
    def get_num_rows(self):
 
84
        """Returns the number of displayed rows in the dash."""
 
85
        return self.view.num_rows
 
86
 
 
87
    def clear_search(self):
 
88
        """Clear the contents of the search bar.
 
89
 
 
90
        Assumes dash is already visible, and search bar has keyboard focus.
 
91
 
 
92
        """
 
93
        self._keyboard.press_and_release("Ctrl+a")
 
94
        self._keyboard.press_and_release("Delete")
 
95
 
 
96
    def reveal_application_lens(self, clear_search=True):
 
97
        """Reveal the application lense."""
 
98
        logger.debug("Revealing application lens with Super+a.")
 
99
        self._reveal_lens("lens_reveal/apps")
 
100
        if clear_search:
 
101
            self.clear_search()
 
102
 
 
103
    def reveal_music_lens(self, clear_search=True):
 
104
        """Reveal the music lense."""
 
105
        logger.debug("Revealing music lens with Super+m.")
 
106
        self._reveal_lens("lens_reveal/music")
 
107
 
 
108
    def reveal_file_lens(self, clear_search=True):
 
109
        """Reveal the file lense."""
 
110
        logger.debug("Revealing file lens with Super+f.")
 
111
        self._reveal_lens("lens_reveal/files")
 
112
        if clear_search:
 
113
            self.clear_search()
 
114
 
 
115
    def reveal_command_lens(self, clear_search=True):
 
116
        """Reveal the 'run command' lens."""
 
117
        logger.debug("Revealing command lens with Alt+F2.")
 
118
        self._reveal_lens("lens_reveal/command")
 
119
        if clear_search:
 
120
            self.clear_search()
 
121
 
 
122
    def _reveal_lens(self, binding_name):
 
123
        self.keybinding_hold(binding_name)
 
124
        self.keybinding_tap(binding_name)
 
125
        self.keybinding_release(binding_name)
 
126
 
 
127
    def get_current_lens(self):
 
128
        """Get the currently-active LensView object."""
 
129
        active_lens_name = self.view.get_lensbar().active_lens
 
130
        return self.view.get_lensview_by_name(active_lens_name)
 
131
 
 
132
    def close_with_alt_f4(self):
 
133
        """Send ALT+F4 in order to close the dash."""
 
134
        self._keyboard.press_and_release("Alt+F4")
 
135
 
 
136
 
 
137
class DashController(UnityIntrospectionObject):
 
138
    """The main dash controller object."""
 
139
 
 
140
    def get_dash_view(self):
 
141
        """Get the dash view that's attached to this controller."""
 
142
        return self.get_children_by_type(DashView)[0]
 
143
 
 
144
 
 
145
class DashView(UnityIntrospectionObject):
 
146
    """The dash view."""
 
147
 
 
148
    def get_searchbar(self):
 
149
        """Get the search bar attached to this dash view."""
 
150
        return self.get_children_by_type(SearchBar)[0]
 
151
 
 
152
    def get_lensbar(self):
 
153
        """Get the lensbar attached to this dash view."""
 
154
        return self.get_children_by_type(LensBar)[0]
 
155
 
 
156
    def get_lensview_by_name(self, lens_name):
 
157
        """Get a LensView child object by it's name. For example, "home.lens"."""
 
158
        lenses = self.get_children_by_type(LensView)
 
159
        for lens in lenses:
 
160
            if lens.name == lens_name:
 
161
                return lens
 
162
 
 
163
 
 
164
class SearchBar(UnityIntrospectionObject):
 
165
    """The search bar for the dash view."""
 
166
 
 
167
 
 
168
class LensBar(UnityIntrospectionObject):
 
169
    """The bar of lens icons at the bottom of the dash."""
 
170
 
 
171
 
 
172
class LensView(UnityIntrospectionObject):
 
173
    """A Lens View."""
 
174
 
 
175
    def get_groups(self):
 
176
        """Get a list of all groups within this lensview. May return an empty list."""
 
177
        groups = self.get_children_by_type(PlacesGroup)
 
178
        return groups
 
179
 
 
180
    def get_focused_category(self):
 
181
        """Return a PlacesGroup instance for the category whose header has keyboard focus.
 
182
 
 
183
        Returns None if no category headers have keyboard focus.
 
184
 
 
185
        """
 
186
        categories = self.get_children_by_type(PlacesGroup)
 
187
        matches = [m for m in categories if m.header_has_keyfocus]
 
188
        if matches:
 
189
            return matches[0]
 
190
        return None
 
191
 
 
192
    def get_category_by_name(self, category_name):
 
193
        """Return a PlacesGroup instance with the given name, or None."""
 
194
        categories = self.get_children_by_type(PlacesGroup)
 
195
        matches = [m for m in categories if m.name == category_name]
 
196
        if matches:
 
197
            return matches[0]
 
198
        return None
 
199
 
 
200
    def get_num_visible_categories(self):
 
201
        """Get the number of visible categories in this lens."""
 
202
        return len([c for c in self.get_children_by_type(PlacesGroup) if c.is_visible])
 
203
 
 
204
    def get_filterbar(self):
 
205
        """Get the filter bar for the current lense, or None if it doesn't have one."""
 
206
        bars = self.get_children_by_type(FilterBar)
 
207
        if bars:
 
208
            return bars[0]
 
209
        return None
 
210
 
 
211
 
 
212
class PlacesGroup(UnityIntrospectionObject):
 
213
    """A category in the lense view."""
 
214
 
 
215
    def get_results(self):
 
216
        """Get a list of all results within this category. May return an empty list."""
 
217
        result_view = self.get_children_by_type(ResultView)[0]
 
218
        return result_view.get_children_by_type(Result)
 
219
 
 
220
 
 
221
class ResultView(UnityIntrospectionObject):
 
222
    """Contains a list of Result objects."""
 
223
 
 
224
 
 
225
class Result(UnityIntrospectionObject):
 
226
    """A single result in the dash."""
 
227
 
 
228
 
 
229
class FilterBar(UnityIntrospectionObject):
 
230
    """A filterbar, as shown inside a lens."""
 
231
 
 
232
    def get_num_filters(self):
 
233
        """Get the number of filters in this filter bar."""
 
234
        filters = self.get_children_by_type(FilterExpanderLabel)
 
235
        return len(filters)
 
236
 
 
237
    def get_focused_filter(self):
 
238
        """Returns the id of the focused filter widget."""
 
239
        filters = self.get_children_by_type(FilterExpanderLabel)
 
240
        for filter_label in filters:
 
241
            if filter_label.expander_has_focus:
 
242
                return filter_label
 
243
        return None
 
244
 
 
245
    def is_expanded(self):
 
246
        """Return True if the filterbar on this lens is expanded, False otherwise.
 
247
        """
 
248
        searchbar = self._get_searchbar()
 
249
        return searchbar.showing_filters
 
250
 
 
251
    def ensure_expanded(self):
 
252
        """Expand the filter bar, if it's not already."""
 
253
        if not self.is_expanded():
 
254
            searchbar = self._get_searchbar()
 
255
            tx = searchbar.filter_label_x + (searchbar.filter_label_width / 2)
 
256
            ty = searchbar.filter_label_y + (searchbar.filter_label_height / 2)
 
257
            m = Mouse()
 
258
            m.move(tx, ty)
 
259
            m.click()
 
260
 
 
261
    def ensure_collapsed(self):
 
262
        """Collapse the filter bar, if it's not already."""
 
263
        if self.is_expanded():
 
264
            searchbar = self._get_searchbar()
 
265
            tx = searchbar.filter_label_x + (searchbar.filter_label_width / 2)
 
266
            ty = searchbar.filter_label_y + (searchbar.filter_label_height / 2)
 
267
            m = Mouse()
 
268
            m.move(tx, ty)
 
269
            m.click()
 
270
 
 
271
    def _get_searchbar(self):
 
272
        """Get the searchbar.
 
273
 
 
274
        This hack exists because there's now more than one SearchBar in Unity,
 
275
        and for some reason the FilterBar stuff is bundled in the SearchBar.
 
276
 
 
277
        """
 
278
        state_info = get_state_by_path("//DashView/SearchBar")
 
279
        assert(len(state_info) == 1)
 
280
        return make_introspection_object(("SearchBar", state_info[0]))
 
281
 
 
282
 
 
283
class FilterExpanderLabel(UnityIntrospectionObject):
 
284
    """A label that expands into a filter within a filter bar."""