30
30
from signal import SIGTSTP, SIGCONT, SIGTERM
31
from subprocess import Popen, PIPE
31
from subprocess import check_call, check_output, Popen, PIPE
32
32
from argparse import ArgumentParser
35
35
class AppThread(threading.Thread):
36
37
def __init__(self, app_name):
37
38
self._appname = app_name
143
def move_window(app, timeout):
146
# Start the process in a separate thread
147
app_thread = AppThread(app)
150
while app_thread.pid is None:
157
window_list = check_output(['wmctrl', '-l'], universal_newlines=True)
160
for line in window_list.split('\n'):
162
window_id = line.split()[0]
165
# Get the screen information from GDK
166
from gi.repository import Gdk
168
screen = Gdk.Screen.get_default()
169
geom = screen.get_monitor_geometry(screen.get_primary_monitor())
171
# Find out the window information from xwininfo
177
for line in check_output(['xwininfo', '-name', app],
178
universal_newlines=True).split('\n'):
179
if 'Absolute upper-left X' in line:
180
win_x = line.split(': ')[-1].strip()
181
elif 'Absolute upper-left Y' in line:
182
win_y = line.split(': ')[-1].strip()
183
elif 'Width' in line:
184
win_width = line.split(': ')[-1].strip()
185
elif 'Height' in line:
186
win_height = line.split(': ')[-1].strip()
188
move_line = ["0", win_x, win_y, win_width, win_height]
190
directions = {'RIGHT': geom.width,
197
while current != 'STOP':
198
if current == 'RIGHT':
199
# Check if top right corner of window reached top right point
200
if int(move_line[1]) + int(win_width) != directions[current]:
201
new_x = int(move_line[1]) + 1
202
move_line[1] = str(new_x)
205
elif current == 'DOWN':
206
if int(move_line[2]) + int(win_height) != directions[current]:
207
new_y = int(move_line[2]) + 1
208
move_line[2] = str(new_y)
211
elif current == 'LEFT':
212
if int(move_line[1]) != int(directions[current]):
213
new_x = int(move_line[1]) - 1
214
move_line[1] = str(new_x)
217
elif current == 'UP':
218
if int(move_line[2]) != int(directions[current]):
219
new_y = int(move_line[2]) - 1
220
move_line[2] = str(new_y)
224
check_call(['wmctrl', '-i', '-r', window_id,
225
'-e', ','.join(move_line)])
227
os.kill(pid, SIGTERM)
229
print("Could not get window handle for %s" % app, file=sys.stderr)
142
235
def print_open_close(iterations, timeout, *args):
144
237
print('Opening and closing a 3D window')
274
def print_move_window(iterations, timeout, *args):
276
print('Moving a 3D window across the screen')
278
for it in range(iterations):
279
print('Iteration %d of %d:' % (it + 1, iterations))
280
exit_status = move_window('glxgears',
182
288
tests = {'open-close': print_open_close,
183
289
'suspend-resume': print_suspend_resume,
184
'open-close-multi': print_open_close_multi}
290
'open-close-multi': print_open_close_multi,
291
'move': print_move_window}
186
usage = 'Usage: %{prog}s [OPTIONS]'
187
parser = ArgumentParser(usage)
293
parser = ArgumentParser(description='Script that performs window operation')
188
294
parser.add_argument('-t', '--test',
190
296
help='The name of the test to run. \
206
312
help='The time in seconds between each test. \
208
parser.add_argument('-w', '--windows_number',
314
parser.add_argument('-w', '--windows-number',
210
317
help='The number of windows to open.')
212
319
args = parser.parse_args()
214
if args.windows_number:
215
if args.test not in ('open-close-multi', 'all'):
216
parser.error('-w or --windows_number can only be used with '
217
'the "open-close-multi" test or with the '
219
windows_number = args.windows_number
224
iterations = args.iterations
225
timeout = args.timeout
226
windows_number = args.windows_number
228
323
test = tests.get(args.test)
231
status = test(iterations, timeout, windows_number)
326
status = test(args.iterations, args.timeout, args.windows_number)
233
328
if args.test == 'all':
234
329
for test in tests:
235
exit_status = tests[test](iterations, timeout,
330
exit_status = tests[test](args.iterations, args.timeout,
237
332
if exit_status != 0:
238
333
status = exit_status