1
# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
2
# Copyright 2012 Canonical
3
# Author: Marco Trevisan (Treviño)
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.
10
from __future__ import absolute_import
13
from time import sleep
15
from autopilot.emulators.X11 import Mouse
16
from autopilot.keybindings import KeybindingsHelper
18
from unity.emulators import UnityIntrospectionObject
19
logger = logging.getLogger(__name__)
22
class PanelController(UnityIntrospectionObject):
23
"""The PanelController class."""
25
def get_panel_for_monitor(self, monitor_num):
26
"""Return an instance of panel for the specified monitor, or None."""
27
panels = self.get_children_by_type(UnityPanel, monitor=monitor_num)
28
assert(len(panels) == 1)
31
def get_active_panel(self):
32
"""Return the active panel, or None."""
33
panels = self.get_children_by_type(UnityPanel, active=True)
34
assert(len(panels) == 1)
37
def get_active_indicator(self):
38
for panel in self.get_panels:
39
active = panel.get_active_indicator()
47
"""Return the available panels, or None."""
48
return self.get_children_by_type(UnityPanel)
51
class UnityPanel(UnityIntrospectionObject, KeybindingsHelper):
52
"""An individual panel for a monitor."""
54
def __init__(self, *args, **kwargs):
55
super(UnityPanel, self).__init__(*args, **kwargs)
58
def __get_menu_view(self):
59
"""Return the menu view."""
60
menus = self.get_children_by_type(MenuView)
61
assert(len(menus) == 1)
64
def __get_window_buttons(self):
65
"""Return the window buttons view."""
66
buttons = self.menus.get_children_by_type(WindowButtons)
67
assert(len(buttons) == 1)
70
def __get_grab_area(self):
71
"""Return the panel grab area."""
72
grab_areas = self.menus.get_children_by_type(GrabArea)
73
assert(len(grab_areas) == 1)
76
def __get_indicators_view(self):
77
"""Return the menu view."""
78
indicators = self.get_children_by_type(Indicators)
79
assert(len(indicators) == 1)
82
def move_mouse_below_the_panel(self):
83
"""Places the mouse to bottom of this panel."""
84
(x, y, w, h) = self.geometry
88
logger.debug("Moving mouse away from panel.")
89
self._mouse.move(target_x, target_y)
91
def move_mouse_over_menus(self):
92
"""Move the mouse over the menu area for this panel."""
93
(x, y, w, h) = self.menus.geometry
97
# The menu view has bigger geometry than the real layout
98
menu_entries = self.menus.get_entries()
99
if len(menu_entries) > 0:
100
first_x = menu_entries[0].x
101
last_x = menu_entries[-1].x + menu_entries[-1].width / 2
103
target_x = first_x + (last_x - first_x) / 2
105
logger.debug("Moving mouse to center of menu area.")
106
self._mouse.move(target_x, target_y)
108
def move_mouse_over_grab_area(self):
109
"""Move the mouse over the grab area for this panel."""
110
(x, y, w, h) = self.grab_area.geometry
114
logger.debug("Moving mouse to center of grab area.")
115
self._mouse.move(target_x, target_y)
117
def move_mouse_over_window_buttons(self):
118
"""Move the mouse over the center of the window buttons area for this panel."""
119
(x, y, w, h) = self.window_buttons.geometry
123
logger.debug("Moving mouse to center of the window buttons.")
124
self._mouse.move(target_x, target_y)
126
def move_mouse_over_indicators(self):
127
"""Move the mouse over the center of the indicators area for this panel."""
128
(x, y, w, h) = self.indicators.geometry
132
logger.debug("Moving mouse to center of the indicators area.")
133
self._mouse.move(target_x, target_y)
135
def get_indicator_entries(self, visible_only=True, include_hidden_menus=False):
136
"""Returns a list of entries for this panel including both menus and indicators"""
138
if include_hidden_menus or self.menus_shown:
139
entries = self.menus.get_entries()
140
entries += self.indicators.get_ordered_entries(visible_only)
143
def get_active_indicator(self):
144
"""Returns the indicator entry that is currently active"""
145
entries = self.get_indicator_entries(False, True)
146
entries = filter(lambda e: e.active == True, entries)
147
assert(len(entries) <= 1)
148
return entries[0] if entries else None
150
def get_indicator_entry(self, entry_id):
151
"""Returns the indicator entry for the given ID or None"""
152
entries = self.get_indicator_entries(False, True)
153
entries = filter(lambda e: e.entry_id == entry_id, entries)
154
assert(len(entries) <= 1)
155
return entries[0] if entries else None
159
return self.menus.panel_title
162
def desktop_is_active(self):
163
return self.menus.desktop_active
166
def menus_shown(self):
167
return self.active and self.menus.draw_menus
170
def window_buttons_shown(self):
171
return self.menus.draw_window_buttons
174
def window_buttons(self):
175
return self.__get_window_buttons()
179
return self.__get_menu_view()
183
return self.__get_grab_area()
186
def indicators(self):
187
return self.__get_indicators_view()
191
"""Returns a tuple of (x,y,w,h) for the current panel."""
192
return (self.x, self.y, self.width, self.height)
195
class MenuView(UnityIntrospectionObject):
196
"""The Menu View class."""
198
def get_entries(self):
199
"""Return a list of menu entries"""
200
entries = self.get_children_by_type(IndicatorEntry)
201
# We need to filter out empty entries, which are seperators - those
202
# are not valid, visible and working entries
203
# For instance, gedit adds some of those, breaking our tests
204
entries = [e for e in entries if (e.label != "")]
207
def get_menu_by_label(self, entry_label):
208
"""Return the first indicator entry found with the given label"""
209
indicators = self.get_children_by_type(IndicatorEntry, label=entry_label)
210
return indicators[0] if indicators else None
214
"""Returns a tuple of (x,y,w,h) for the current menu view."""
215
return (self.x, self.y, self.width, self.height)
218
class WindowButtons(UnityIntrospectionObject):
219
"""The window buttons class"""
221
def get_buttons(self, visible_only=True):
222
"""Return a list of window buttons"""
224
return self.get_children_by_type(WindowButton, visible=True)
226
return self.get_children_by_type(WindowButton)
228
def get_button(self, type):
229
buttons = self.get_children_by_type(WindowButton, type=type)
230
assert(len(buttons) == 1)
235
return len(self.get_buttons()) != 0
239
return self.get_button("Close")
243
return self.get_button("Minimize")
246
def unmaximize(self):
247
return self.get_button("Unmaximize")
251
return self.get_button("Maximize")
255
"""Returns a tuple of (x,y,w,h) for the current panel."""
256
return (self.x, self.y, self.width, self.height)
259
class WindowButton(UnityIntrospectionObject):
260
"""The Window WindowButton class."""
262
def __init__(self, *args, **kwargs):
263
super(WindowButton, self).__init__(*args, **kwargs)
264
self._mouse = Mouse()
266
def mouse_move_to(self):
267
target_x = self.x + self.width / 2
268
target_y = self.y + self.height / 2
269
self._mouse.move(target_x, target_y, rate=20, time_between_events=0.005)
271
def mouse_click(self):
274
self._mouse.click(press_duration=.1)
279
"""Returns a tuple of (x,y,w,h) for the window button."""
280
return (self.x, self.y, self.width, self.height)
283
class GrabArea(UnityIntrospectionObject):
284
"""The grab area class"""
288
"""Returns a tuple of (x,y,w,h) for the grab area."""
289
return (self.x, self.y, self.width, self.height)
292
class Indicators(UnityIntrospectionObject):
293
"""The Indicators View class."""
295
def get_ordered_entries(self, visible_only=True):
296
"""Return a list of indicators, ordered by their priority"""
299
entries = self.get_children_by_type(IndicatorEntry, visible=True)
301
entries = self.get_children_by_type(IndicatorEntry)
303
return sorted(entries, key=lambda entry: entry.priority)
305
def get_indicator_by_name_hint(self, name_hint):
306
"""Return the IndicatorEntry with the name_hint"""
307
indicators = self.get_children_by_type(IndicatorEntry, name_hint=name_hint)
308
assert(len(indicators) == 1)
313
"""Returns a tuple of (x,y,w,h) for the indicators area."""
314
return (self.x, self.y, self.width, self.height)
317
class IndicatorEntry(UnityIntrospectionObject):
318
"""The IndicatorEntry View class."""
320
def __init__(self, *args, **kwargs):
321
super(IndicatorEntry, self).__init__(*args, **kwargs)
322
self._mouse = Mouse()
324
def mouse_move_to(self):
325
target_x = self.x + self.width / 2
326
target_y = self.y + self.height / 2
327
self._mouse.move(target_x, target_y, rate=20, time_between_events=0.005)
329
def mouse_click(self, button=1):
333
self._mouse.click(press_duration=.1)
338
"""Returns a tuple of (x,y,w,h) for the indicator entry."""
339
return (self.x, self.y, self.width, self.height)
342
def menu_geometry(self):
343
"""Returns a tuple of (x,y,w,h) for the opened menu geometry."""
344
return (self.menu_x, self.menu_y, self.menu_width, self.menu_height)
347
with self.no_automatic_refreshing():
348
return "<IndicatorEntry 0x%x (%s)>" % (id(self), self.label)
351
class Tray(UnityIntrospectionObject):
352
"""A panel tray object."""