/usr/lib/2013.com.canonical.certification:checkbox/bin/touchpad_test is in plainbox-provider-checkbox 0.4-1.
This file is owned by root:root, with mode 0o755.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 | #!/usr/bin/env python3
import sys
import gettext
from gettext import gettext as _
from gi.repository import Gio, Gtk, Gdk
from optparse import OptionParser
EXIT_WITH_FAILURE = 1
EXIT_WITH_SUCCESS = 0
EXIT_TIMEOUT = 30
class Direction(object):
def __init__(self, name):
self.name = name
self.tested = False
self.value = getattr(Gdk.ScrollDirection, name.upper())
class GtkScroller(object):
touchpad_key = "org.gnome.settings-daemon.peripherals.touchpad"
exit_code = EXIT_WITH_FAILURE
def __init__(self, directions, edge_scroll=False):
self.directions = directions
self.edge_scroll = edge_scroll
# Initialize GTK constants
self.ICON_SIZE = Gtk.IconSize.BUTTON
self.ICON_TESTED = Gtk.STOCK_YES
self.ICON_UNTESTED = Gtk.STOCK_INDEX
self.ICON_NOT_REQUIRED = Gtk.STOCK_REMOVE
self.button_factory = Gtk.Button
self.hbox_factory = Gtk.HBox
self.image_factory = Gtk.Image
self.label_factory = Gtk.Label
self.vbox_factory = Gtk.VBox
# Create GTK window.
window = Gtk.Window()
window.set_type_hint(Gdk.WindowType.TOPLEVEL)
window.add_events(
Gdk.EventMask.SCROLL_MASK | Gdk.EventMask.SMOOTH_SCROLL_MASK)
window.set_size_request(200, 100)
window.set_resizable(False)
window.set_title(_("Type Text"))
window.connect("delete-event", lambda w, e: self.quit())
window.connect("scroll-event", self.on_scroll)
window.show()
# Add common widgets to the window.
vbox = self._add_vbox(window)
self.label = self._add_label(vbox)
button_hbox = self._add_hbox(vbox)
validation_hbox = self._add_hbox(vbox)
self.status = self._add_label(vbox)
self.exit_button = self._add_button(vbox, Gtk.STOCK_CLOSE)
self.exit_button.connect("clicked", lambda w: self.quit())
# Add widgets for each direction.
self.icons = {}
for direction in self.directions:
self._add_label(button_hbox, direction.name)
self.icons[direction] = self._add_image(
validation_hbox, Gtk.STOCK_INDEX)
self.show_text(
_("Please move the mouse cursor to this window.") +
"\n" +
_("Then scroll in each direction on your touchpad."))
def _add_button(self, context, stock):
button = self.button_factory(stock=stock)
context.add(button)
button.show()
return button
def _add_hbox(self, context, spacing=4):
hbox = self.hbox_factory()
context.add(hbox)
hbox.set_spacing(4)
hbox.show()
return hbox
def _add_image(self, context, stock):
image = self.image_factory(stock=stock, icon_size=self.ICON_SIZE)
context.add(image)
image.show()
return image
def _add_label(self, context, text=None):
label = self.label_factory()
context.add(label)
label.set_size_request(0, 0)
label.set_line_wrap(True)
if text:
label.set_text(text)
label.show()
return label
def _add_vbox(self, context):
vbox = self.vbox_factory()
vbox.set_homogeneous(False)
vbox.set_spacing(8)
context.add(vbox)
vbox.show()
return vbox
def run(self):
# Save touchpad settings.
touchpad_settings = Gio.Settings.new(self.touchpad_key)
self.saved_horiz_scroll_enabled = touchpad_settings.get_boolean(
"horiz-scroll-enabled")
self.saved_scroll_method = touchpad_settings.get_string(
"scroll-method")
# Set touchpad settings.
touchpad_settings.set_boolean("horiz-scroll-enabled", True)
if self.edge_scroll:
touchpad_settings.set_string("scroll-method", "edge-scrolling")
Gtk.main()
def quit(self):
# Reset touchpad settings.
touchpad_settings = Gio.Settings.new(self.touchpad_key)
touchpad_settings.set_boolean(
"horiz-scroll-enabled", self.saved_horiz_scroll_enabled)
touchpad_settings.set_string(
"scroll-method", self.saved_scroll_method)
Gtk.main_quit()
def show_text(self, text, widget=None):
if widget is None:
widget = self.label
widget.set_text(text)
def found_direction(self, direction):
direction.tested = True
self.icons[direction].set_from_stock(
self.ICON_TESTED, size=self.ICON_SIZE)
self.check_directions()
def check_directions(self):
if all([direction.tested for direction in self.directions]):
self.show_text(
_("All required directions have been tested!"), self.status)
self.exit_code = EXIT_WITH_SUCCESS
self.exit_button.grab_focus()
def on_scroll(self, window, event):
for direction in self.directions:
if direction.value == event.direction:
self.found_direction(direction)
break
return True
def main(args):
gettext.textdomain("checkbox")
usage = """Usage: %prog DIRECTION... [--edge-scroll]"""
parser = OptionParser(usage=usage)
parser.add_option("--edge-scroll", action="store_true", default=False,
help="Force touchpad to use edge scrolling only")
(options, args) = parser.parse_args(args)
if not args:
parser.error("Must specify directions to test.")
directions = []
for arg in args:
try:
direction = Direction(arg)
except AttributeError:
parser.error("Unsupported direction: %s" % arg)
directions.append(direction)
scroller = GtkScroller(directions, edge_scroll=options.edge_scroll)
try:
scroller.run()
except KeyboardInterrupt:
scroller.show_text(_("Test interrupted"), self.status)
scroller.quit()
return scroller.exit_code
if __name__ == "__main__":
sys.exit(main(sys.argv[1:]))
|