Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAjay Garg <ajay@activitycentral.com>2012-08-30 14:19:55 (GMT)
committer Ajay Garg <ajay@activitycentral.com>2012-08-30 14:19:55 (GMT)
commit1791298a22b81af46f0280a727c72643f099b43e (patch)
tree91f38b78e148df7a8c52993eba48a566f79a54f7
parent2563b25ec36cea7f4e7691f081a41020b78f9639 (diff)
ac#2268: Extensions removal: touchpad modes, system monitoring and feedback (UY).
-rw-r--r--rpms/sugar/0133-ac-2268-Extensions-removal-touchpad-modes-system-mon.patch642
1 files changed, 642 insertions, 0 deletions
diff --git a/rpms/sugar/0133-ac-2268-Extensions-removal-touchpad-modes-system-mon.patch b/rpms/sugar/0133-ac-2268-Extensions-removal-touchpad-modes-system-mon.patch
new file mode 100644
index 0000000..97c600b
--- /dev/null
+++ b/rpms/sugar/0133-ac-2268-Extensions-removal-touchpad-modes-system-mon.patch
@@ -0,0 +1,642 @@
+From db1c00a2b46dd4a1908e7860eba1e66fa6da361a Mon Sep 17 00:00:00 2001
+From: Ajay Garg <ajay@activitycentral.com>
+Date: Thu, 30 Aug 2012 19:45:54 +0530
+Subject: [PATCH] ac#2268: Extensions removal: touchpad modes, system monitoring and feedback (UY).
+Organization: Sugar Labs Foundation
+Signed-off-by: Ajay Garg <ajay@activitycentral.com>
+---
+ extensions/deviceicon/Makefile.am | 6 +-
+ extensions/deviceicon/feedback.py | 179 ------------------------------
+ extensions/deviceicon/resources.py | 215 ------------------------------------
+ extensions/deviceicon/touchpad.py | 142 ------------------------
+ extensions/globalkey/Makefile.am | 1 -
+ extensions/globalkey/touchpad.py | 33 ------
+ 6 files changed, 1 insertions(+), 575 deletions(-)
+ delete mode 100644 extensions/deviceicon/feedback.py
+ delete mode 100644 extensions/deviceicon/resources.py
+ delete mode 100644 extensions/deviceicon/touchpad.py
+ delete mode 100644 extensions/globalkey/touchpad.py
+
+diff --git a/extensions/deviceicon/Makefile.am b/extensions/deviceicon/Makefile.am
+index b38cbb3..67d08f9 100644
+--- a/extensions/deviceicon/Makefile.am
++++ b/extensions/deviceicon/Makefile.am
+@@ -4,10 +4,6 @@ sugar_PYTHON = \
+ __init__.py \
+ battery.py \
+ network.py \
+- resources.py \
+ speaker.py \
+- touchpad.py \
+ virtualkeyboard.py \
+- volume.py \
+- feedback.py
+-
++ volume.py
+diff --git a/extensions/deviceicon/feedback.py b/extensions/deviceicon/feedback.py
+deleted file mode 100644
+index 49db09b..0000000
+--- a/extensions/deviceicon/feedback.py
++++ /dev/null
+@@ -1,179 +0,0 @@
+-# Copyright (C) Mukesh Gupta <mukeshgupta.2006@gmail.com>
+-#
+-# This program is free software; you can redistribute it and/or modify
+-# it under the terms of the GNU General Public License as published by
+-# the Free Software Foundation; either version 2 of the License, or
+-# (at your option) any later version.
+-#
+-# This program is distributed in the hope that it will be useful,
+-# but WITHOUT ANY WARRANTY; without even the implied warranty of
+-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+-# GNU General Public License for more details.
+-#
+-# You should have received a copy of the GNU General Public License
+-# along with this program; if not, write to the Free Software
+-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+-
+-import logging
+-from gettext import gettext as _
+-
+-import gconf
+-import gtk
+-
+-from sugar import profile
+-from sugar.graphics import style
+-from sugar.graphics.icon import Icon
+-from sugar.graphics.tray import TrayIcon
+-from sugar.graphics.palette import Palette
+-from sugar.graphics.menuitem import MenuItem
+-from sugar.graphics.toolbutton import ToolButton
+-
+-from jarabe.model import feedback_collector
+-
+-
+-_ICON_NAME = 'feedback-icon'
+-
+-
+-class DeviceView(TrayIcon):
+-
+- FRAME_POSITION_RELATIVE = 500
+-
+- def __init__(self):
+- TrayIcon.__init__(self, icon_name=_ICON_NAME,
+- xo_color=profile.get_color())
+- self.create_palette()
+-
+- def create_palette(self):
+- logging.debug('palette created')
+- self.palette = _Palette(_('Feedback'))
+- self.palette.set_group_id('frame')
+- return self.palette
+-
+-
+-class _Palette(Palette):
+-
+- def __init__(self, primary_text):
+- Palette.__init__(self, primary_text)
+-
+- icon = Icon()
+- icon.set_from_icon_name('emblem-favorite', gtk.ICON_SIZE_MENU)
+- icon.props.xo_color = profile.get_color()
+-
+- personalized = MenuItem(_('Personalized submit...'))
+- personalized.set_image(icon)
+- personalized.connect('activate', self.__personalized_activate_cb)
+- personalized.show()
+- self.menu.append(personalized)
+-
+- self._anonymous = MenuItem(_('Anonymous submit'), 'emblem-favorite')
+- self._anonymous.connect('activate', self.__anonymous_activate_cb)
+- self._anonymous.show()
+- self.menu.append(self._anonymous)
+-
+- def popup(self, immediate=False, state=None):
+- self._anonymous.set_sensitive(not feedback_collector.is_empty())
+- Palette.popup(self, immediate=immediate, state=state)
+-
+- def __anonymous_activate_cb(self, button):
+- feedback_collector.anonymous_submit()
+-
+- def __personalized_activate_cb(self, button):
+- window = _Window()
+- window.show()
+-
+-
+-class _Window(gtk.Window):
+-
+- __gtype_name__ = 'FeedbackWindow'
+-
+- def __init__(self):
+- gtk.Window.__init__(self)
+-
+- self.set_border_width(style.LINE_WIDTH)
+- offset = style.GRID_CELL_SIZE
+- width = gtk.gdk.screen_width() - offset * 2
+- height = gtk.gdk.screen_height() - offset * 2
+- self.set_size_request(width, height)
+- self.set_position(gtk.WIN_POS_CENTER_ALWAYS)
+- self.set_decorated(False)
+- self.set_resizable(False)
+- self.set_modal(True)
+-
+- canvas = gtk.VBox()
+- self.add(canvas)
+-
+- self._toolbar = gtk.Toolbar()
+- canvas.pack_start(self._toolbar, False)
+-
+- icon = Icon()
+- icon.set_from_icon_name('emblem-favorite', gtk.ICON_SIZE_LARGE_TOOLBAR)
+- icon.props.xo_color = profile.get_color()
+- self._add_widget(icon)
+-
+- self._add_separator(False)
+-
+- title = gtk.Label(_('Submit feedback'))
+- self._add_widget(title)
+-
+- self._add_separator(True)
+-
+- submit = ToolButton('dialog-ok', tooltip=_('Submit'))
+- submit.connect('clicked', lambda button: self._submit())
+- self._toolbar.insert(submit, -1)
+-
+- cancel = ToolButton('dialog-cancel', tooltip=_('Cancel'))
+- cancel.connect('clicked', lambda button: self.destroy())
+- self._toolbar.insert(cancel, -1)
+-
+- bg = gtk.EventBox()
+- bg.modify_bg(gtk.STATE_NORMAL, style.COLOR_WHITE.get_gdk_color())
+- canvas.pack_start(bg)
+-
+- self._message = gtk.TextView()
+- scrolled = gtk.ScrolledWindow()
+- scrolled.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
+- scrolled.set_border_width(style.DEFAULT_PADDING)
+- scrolled.add(self._message)
+- bg.add(scrolled)
+-
+- self.show_all()
+- self.set_focus(self._message)
+-
+- self.connect("realize", self.__realize_cb)
+-
+- def do_key_press_event(self, event):
+- if event.keyval == gtk.keysyms.Escape:
+- self.destroy()
+- elif event.keyval == gtk.keysyms.Return and \
+- event.state & gtk.gdk.CONTROL_MASK:
+- self._submit()
+- else:
+- gtk.Window.do_key_press_event(self, event)
+-
+- def _add_widget(self, widget):
+- tool_item = gtk.ToolItem()
+- tool_item.add(widget)
+- self._toolbar.insert(tool_item, -1)
+-
+- def _add_separator(self, expand):
+- separator = gtk.SeparatorToolItem()
+- separator.props.draw = False
+- if expand:
+- separator.set_expand(True)
+- else:
+- separator.set_size_request(style.DEFAULT_SPACING, -1)
+- self._toolbar.insert(separator, -1)
+-
+- def _submit(self):
+- feedback_collector.submit(self._message.props.buffer.props.text)
+- self.destroy()
+-
+- def __realize_cb(self, widget):
+- self.window.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_DIALOG)
+- self.window.set_accept_focus(True)
+-
+-
+-def setup(tray):
+- client = gconf.client_get_default()
+- if client.get_bool('/desktop/sugar/feedback/personalized_submit'):
+- tray.add_device(DeviceView())
+diff --git a/extensions/deviceicon/resources.py b/extensions/deviceicon/resources.py
+deleted file mode 100644
+index 5e39d4e..0000000
+--- a/extensions/deviceicon/resources.py
++++ /dev/null
+@@ -1,215 +0,0 @@
+-# Copyright (C) Anish Mangal <anishmangal2002@gmail.com>
+-#
+-# This program is free software; you can redistribute it and/or modify
+-# it under the terms of the GNU General Public License as published by
+-# the Free Software Foundation; either version 2 of the License, or
+-# (at your option) any later version.
+-#
+-# This program is distributed in the hope that it will be useful,
+-# but WITHOUT ANY WARRANTY; without even the implied warranty of
+-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+-# GNU General Public License for more details.
+-#
+-# You should have received a copy of the GNU General Public License
+-# along with this program; if not, write to the Free Software
+-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+-
+-from gettext import gettext as _
+-import logging
+-import os
+-
+-import gobject
+-import gtk
+-import gconf
+-
+-from sugar.graphics.tray import TrayIcon
+-from sugar.graphics.xocolor import XoColor
+-from sugar.graphics.palette import Palette
+-from sugar.graphics import style
+-
+-
+-_SYSTEM_MOODS = ['-sad', '-normal', '-happy']
+-_ICON_NAME = 'computer'
+-_UPDATE_INTERVAL = 5 * 1000
+-
+-
+-class DeviceView(TrayIcon):
+-
+- FRAME_POSITION_RELATIVE = 500
+-
+- def __init__(self):
+- client = gconf.client_get_default()
+- self._color = XoColor(client.get_string('/desktop/sugar/user/color'))
+- TrayIcon.__init__(self, icon_name=_ICON_NAME, xo_color=self._color)
+- self.create_palette()
+- self._icon_widget.connect('button-release-event', self._click_cb)
+-
+- def create_palette(self):
+- self.palette = ResourcePalette(_('System resources'))
+- self.palette.set_group_id('frame')
+- self.palette.add_timer()
+- self.palette.connect('system-mood-changed',
+- self._system_mood_changed_cb)
+- return self.palette
+-
+- def _system_mood_changed_cb(self, palette_, mood):
+- self.icon.props.icon_name = _ICON_NAME + mood
+-
+- def _click_cb(self, widget, event):
+- self.palette_invoker.notify_right_click()
+-
+-
+-class ResourcePalette(Palette):
+- __gsignals__ = {
+- 'system-mood-changed': (gobject.SIGNAL_RUN_FIRST,
+- gobject.TYPE_NONE,
+- ([str])),
+- }
+-
+- def __init__(self, primary_text):
+- Palette.__init__(self, label=primary_text)
+-
+- self.vbox = gtk.VBox()
+- self.set_content(self.vbox)
+-
+- self._cpu_text = gtk.Label()
+- self.vbox.pack_start(self._cpu_text, padding=style.DEFAULT_PADDING)
+- self._cpu_bar = gtk.ProgressBar()
+- self._cpu_bar.set_size_request(
+- style.zoom(style.GRID_CELL_SIZE * 4), -1)
+- self.vbox.pack_start(self._cpu_bar, padding=style.DEFAULT_PADDING)
+-
+- self._memory_text = gtk.Label()
+- self.vbox.pack_start(self._memory_text, padding=style.DEFAULT_PADDING)
+- self._memory_bar = gtk.ProgressBar()
+- self._memory_bar.set_size_request(
+- style.zoom(style.GRID_CELL_SIZE * 4), -1)
+- self.vbox.pack_start(self._memory_bar, padding=style.DEFAULT_PADDING)
+-
+- self._system_mood = None
+- try:
+- self._cpu_times = self._get_cpu_times_list()
+- except IOError:
+- logging.exception('An error ocurred while attempting to '
+- 'read /proc/stat')
+- self._stop_computing_statistics()
+-
+- self.vbox.show()
+- self._cpu_text.show()
+- self._cpu_bar.show()
+- self._memory_text.show()
+- self._memory_bar.show()
+-
+- def add_timer(self):
+- gobject.timeout_add(_UPDATE_INTERVAL, self.__timer_cb)
+-
+- def _get_cpu_times_list(self):
+- """Return various cpu times as read from /proc/stat
+-
+- This method returns the following cpu times measured
+- in jiffies (1/100 of a second for x86 systems)
+- as an ordered list of numbers - [user, nice,
+- system, idle, iowait] where,
+-
+- user: normal processes executing in user mode
+- nice: niced processes executing in user mode
+- system: processes executing in kernel mode
+- idle: twiddling thumbs
+- iowait: waiting for I/O to complete
+-
+- Note: For systems having 2 or more CPU's, the above
+- numbers would be the cumulative sum of these times
+- for all CPU's present in the system.
+-
+- """
+- return [int(count)
+- for count in file('/proc/stat').readline().split()[1:6]]
+-
+- def _percentage_cpu_available(self):
+- """
+- Return free CPU resources as a percentage
+-
+- """
+- _cpu_times_new = self._get_cpu_times_list()
+- _cpu_times_current = [(new - old)
+- for new, old in zip(_cpu_times_new, self._cpu_times)]
+- user_, nice_, system_, idle, iowait = _cpu_times_current
+- cpu_free = (idle + iowait) * 100.0 / sum(_cpu_times_current)
+- self._cpu_times = self._get_cpu_times_list()
+- return cpu_free
+-
+- def _percentage_memory_available(self):
+- """
+- Return free memory as a percentage
+-
+- """
+- for line in file('/proc/meminfo'):
+- name, value, unit_ = line.split()[:3]
+- if 'MemTotal:' == name:
+- total = int(value)
+- elif 'MemFree:' == name:
+- free = int(value)
+- elif 'Buffers:' == name:
+- buffers = int(value)
+- elif 'Cached:' == name:
+- cached = int(value)
+- elif 'Active:' == name:
+- break
+- return (free + buffers + cached) * 100.0 / total
+-
+- def __timer_cb(self):
+- try:
+- cpu_in_use = 100 - self._percentage_cpu_available()
+- memory_in_use = 100 - self._percentage_memory_available()
+- except IOError:
+- logging.exception('An error ocurred while trying to '
+- 'retrieve resource usage statistics')
+- self._stop_and_show_error()
+- return False
+- else:
+- self._cpu_text.set_label(_('CPU in use: %d%%' % cpu_in_use))
+- self._cpu_bar.set_fraction(float(cpu_in_use) / 100)
+- self._memory_text.set_label(_('Memory in use: %d%%' %
+- memory_in_use))
+- self._memory_bar.set_fraction(float(memory_in_use) / 100)
+-
+- # both cpu_free and memory_free lie between 0-100
+- system_mood = _SYSTEM_MOODS[
+- int(300 - (cpu_in_use + 2 * memory_in_use)) // 100]
+-
+- # check if self._system_mood exists
+- try:
+- if self._system_mood != system_mood:
+- self.emit('system-mood-changed', system_mood)
+- self._system_mood = system_mood
+- except AttributeError:
+- self.emit('system-mood-changed', system_mood)
+- self._system_mood = system_mood
+-
+- return True
+-
+- def _stop_and_show_error(self):
+- """
+- Stop computing usage statistics and display an error message
+- since we've hit an exception.
+-
+- """
+- # Use the existing _cpu_text label to display the error. Remove
+- # everything else.
+- self._cpu_text.set_size_request(
+- style.zoom(style.GRID_CELL_SIZE * 4), -1)
+- self._cpu_text.set_line_wrap(True)
+- self._cpu_text.set_text(_('Cannot compute CPU and memory usage '
+- 'statistics!'))
+- self.vbox.remove(self._cpu_bar)
+- self.vbox.remove(self._memory_text)
+- self.vbox.remove(self._memory_bar)
+- self.emit('system-mood-changed', '-error')
+-
+-
+-def setup(tray):
+- if not (os.path.exists('/proc/stat') and os.path.exists('/proc/meminfo')):
+- logging.warning('Either /proc/stat or /proc/meminfo not present. Not '
+- 'adding the CPU and memory usage icon to the frame')
+- return
+- tray.add_device(DeviceView())
+diff --git a/extensions/deviceicon/touchpad.py b/extensions/deviceicon/touchpad.py
+deleted file mode 100644
+index ba02037..0000000
+--- a/extensions/deviceicon/touchpad.py
++++ /dev/null
+@@ -1,142 +0,0 @@
+-# Copyright (C) 2010, Walter Bender, Sugar Labs
+-#
+-# This program is free software; you can redistribute it and/or modify
+-# it under the terms of the GNU General Public License as published by
+-# the Free Software Foundation; either version 2 of the License, or
+-# (at your option) any later version.
+-#
+-# This program is distributed in the hope that it will be useful,
+-# but WITHOUT ANY WARRANTY; without even the implied warranty of
+-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+-# GNU General Public License for more details.
+-#
+-# You should have received a copy of the GNU General Public License
+-# along with this program; if not, write to the Free Software
+-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+-
+-
+-from gettext import gettext as _
+-import os
+-
+-import gtk
+-import gconf
+-import glib
+-
+-import logging
+-
+-from sugar.graphics.tray import TrayIcon
+-from sugar.graphics.xocolor import XoColor
+-from sugar.graphics.palette import Palette
+-from sugar.graphics import style
+-
+-from jarabe.frame.frameinvoker import FrameWidgetInvoker
+-
+-TOUCHPAD_MODE_CAPACITIVE = 'capacitive'
+-TOUCHPAD_MODE_RESISTIVE = 'resistive'
+-TOUCHPAD_MODES = [TOUCHPAD_MODE_CAPACITIVE, TOUCHPAD_MODE_RESISTIVE]
+-STATUS_TEXT = {
+- TOUCHPAD_MODE_CAPACITIVE: _('finger'),
+- TOUCHPAD_MODE_RESISTIVE: _('stylus'),
+-}
+-STATUS_ICON = {
+- TOUCHPAD_MODE_CAPACITIVE: 'touchpad-' + TOUCHPAD_MODE_CAPACITIVE,
+- TOUCHPAD_MODE_RESISTIVE: 'touchpad-' + TOUCHPAD_MODE_RESISTIVE,
+-}
+-# NODE_PATH is used to communicate with the touchpad device.
+-NODE_PATH = '/sys/devices/platform/i8042/serio1/ptmode'
+-
+-_view = None
+-
+-
+-class DeviceView(TrayIcon):
+- """ Manage the touchpad mode from the device palette on the Frame. """
+-
+- FRAME_POSITION_RELATIVE = 500
+-
+- def __init__(self):
+- """ Create the icon that represents the touchpad. """
+- icon_name = STATUS_ICON[_read_touchpad_mode()]
+-
+- client = gconf.client_get_default()
+- color = XoColor(client.get_string('/desktop/sugar/user/color'))
+- TrayIcon.__init__(self, icon_name=icon_name, xo_color=color)
+-
+- self.set_palette_invoker(FrameWidgetInvoker(self))
+- self.connect('button-release-event', self.__button_release_event_cb)
+-
+- def create_palette(self):
+- """ Create a palette for this icon; called by the Sugar framework
+- when a palette needs to be displayed. """
+- label = glib.markup_escape_text(_('My touchpad'))
+- self._palette = ResourcePalette(label, self.icon)
+- self._palette.set_group_id('frame')
+- return self._palette
+-
+- def __button_release_event_cb(self, widget, event):
+- """ Callback for button release event; used to invoke touchpad-mode
+- change. """
+- self._palette.toggle_mode()
+- return True
+-
+-
+-class ResourcePalette(Palette):
+- """ Palette attached to the decive icon that represents the touchpas. """
+-
+- def __init__(self, primary_text, icon):
+- """ Create the palette and initilize with current touchpad status. """
+- Palette.__init__(self, label=primary_text)
+-
+- self._icon = icon
+-
+- vbox = gtk.VBox()
+- self.set_content(vbox)
+-
+- self._status_text = gtk.Label()
+- vbox.pack_start(self._status_text, padding=style.DEFAULT_PADDING)
+- self._status_text.show()
+-
+- vbox.show()
+-
+- self._mode = _read_touchpad_mode()
+- self._update()
+-
+- def _update(self):
+- """ Update the label and icon based on the current mode. """
+- self._status_text.set_label(STATUS_TEXT[self._mode])
+- self._icon.props.icon_name = STATUS_ICON[self._mode]
+-
+- def toggle_mode(self):
+- """ Toggle the touchpad mode. """
+- self._mode = TOUCHPAD_MODES[1 - TOUCHPAD_MODES.index(self._mode)]
+- _write_touchpad_mode(self._mode)
+- self._update()
+-
+-
+-def setup(tray):
+- """ Initialize the device icon; called by the shell when initializing the
+- Frame. """
+- global _view
+- if os.path.exists(NODE_PATH):
+- _view = DeviceView()
+- tray.add_device(_view)
+- _write_touchpad_mode(TOUCHPAD_MODE_CAPACITIVE)
+-
+-
+-def _read_touchpad_mode():
+- """ Read the touchpad mode from the node path. """
+- node_file_handle = open(NODE_PATH, 'r')
+- text = node_file_handle.read()
+- node_file_handle.close()
+-
+- return TOUCHPAD_MODES[int(text[0])]
+-
+-
+-def _write_touchpad_mode(touchpad):
+- """ Write the touchpad mode to the node path. """
+- try:
+- node_file_handle = open(NODE_PATH, 'w')
+- except IOError, e:
+- logging.error('Error opening %s for writing: %s', NODE_PATH, e)
+- return
+- node_file_handle.write(str(TOUCHPAD_MODES.index(touchpad)))
+- node_file_handle.close()
+diff --git a/extensions/globalkey/Makefile.am b/extensions/globalkey/Makefile.am
+index e3aaa8a..b44626e 100644
+--- a/extensions/globalkey/Makefile.am
++++ b/extensions/globalkey/Makefile.am
+@@ -4,6 +4,5 @@ sugar_PYTHON = \
+ __init__.py \
+ magnifier.py \
+ screenshot.py \
+- touchpad.py \
+ viewsource.py \
+ virtualkeyboard.py
+diff --git a/extensions/globalkey/touchpad.py b/extensions/globalkey/touchpad.py
+deleted file mode 100644
+index eeaba40..0000000
+--- a/extensions/globalkey/touchpad.py
++++ /dev/null
+@@ -1,33 +0,0 @@
+-# Copyright (C) 2010, Martin Abente
+-#
+-# This program is free software; you can redistribute it and/or modify
+-# it under the terms of the GNU General Public License as published by
+-# the Free Software Foundation; either version 2 of the License, or
+-# (at your option) any later version.
+-#
+-# This program is distributed in the hope that it will be useful,
+-# but WITHOUT ANY WARRANTY; without even the implied warranty of
+-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+-# GNU General Public License for more details.
+-#
+-# You should have received a copy of the GNU General Public License
+-# along with this program; if not, write to the Free Software
+-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+-
+-import logging
+-
+-BOUND_KEYS = ['<alt>m']
+-touchpad = None
+-
+-def handle_key_press(key):
+- global touchpad
+- if touchpad is None:
+- try:
+- touchpad = __import__('deviceicon.touchpad', globals(),
+- locals(), ['touchpad'])
+- except Exception:
+- logging.error('Could not import touchpad module.')
+- return
+-
+- if touchpad._view is not None:
+- touchpad._view._palette.toggle_mode()
+--
+1.7.4.4
+