I am interested in making our keyboard shortcuts discoverable, ubiquitous, and consistent. This is especially important because of the approximately half a million demon-possessed trackpads that OLPC has shipped (not blaming; I thought that the resistive pad was a cool idea too, in fact, it&#39;s still a cool idea and the XO had a pretty good batting average with its attempted miracles).<br>
<br>The overall plan is outlined at <a href="http://wiki.sugarlabs.org/go/Design_Team/Vision/Proposals/Keyboard_Action">http://wiki.sugarlabs.org/go/Design_Team/Vision/Proposals/Keyboard_Action</a> . I&#39;ve posted it here before, but since I combined it with another idea about the home view, it didn&#39;t get discussed much. I&#39;m starting to code it, so I want to get some more consensus before I go too far. I&#39;ll start with vision, then talk about implementation.<br>
<br>The vision is to provide software support for three desirable qualities.<br><br><b>Discoverable</b>. Without discoverability, shortcuts are useless. And we have pre-literate kids as a part of our user base, so including &quot;ctrl-x&quot; in our popdowns isn&#39;t going to cut it. My basic idea is that when the user presses/holds ctrl, the shortcuts show up as translucent letters in front of the toolbar buttons. Some open questions:<br>
<br>Delay? My instinct is yes, so that fast typers aren&#39;t slowed down by UI candy, but a pretty small one - around 300-700 ms. I&#39;d rather not make this configurable.<br><br>Non-&quot;ctrl&quot; shortcuts: My idea is to have two lines: the top third of the toolbar button can say &quot;Alt&quot; or &quot;Shift&quot;, then the bottom two thirds has the letter. F5 or Pause or whatever should just say the key name. The problem is, how do you distinguish ctrl-alt-a from alt-a, and ctrl-F5 from F5. IMO it&#39;s not actually a tragedy if you just don&#39;t make that distinction.<br>
<br><b>Ubiquitous. </b>To me, this goal means increasing our software support for the developer/translator team assigning shortcuts. It&#39;s true, it&#39;s really just one line and one string per button (<span style="font-family: courier new,monospace;">customButton.props.accelerator = _(&#39;&lt;ctrl&gt;b&#39;)</span>) but that&#39;s a big nuisance for translators, and programmers are meant to be lazy. So I think you should be able to assign the accelerator from within the translatable string. GTK already has a similar mechanism, but it&#39;s inappropriate. Setting the label to &quot;go _next&quot; will, if the use_underline property is true, set the mnemonic, a kind of shortcut that works only if the control&#39;s visible, to alt-n, and draw the label with the n underlined. Four problems: we care about tooltip, not label; we want the shortcut to be available when you&#39;re on a different toolbar; we want ctrl, not alt; and this doesn&#39;t seem to work in sugar, for reasons I&#39;ve not investigated. So I propose doing the same thing, but using the tooltip, a real shortcut, ctrl, and the character u&quot;\u00ad&quot; which is &quot;soft hyphen&quot;, ie, by nature an invisible typesetting mark. Issues: I haven&#39;t tested if you can use the backslash escape to get this in Pootle, if not it&#39;s a problem.<br>
<br><b>Consistent</b>. This means dealing with all the shortcuts in a unified fashion. First principle is, ctrl for activity shortcuts, alt for global/frame ones, ctrl-alt for modified ctrl shortcuts (ie, ctrl-alt-v is paste-and-pop-clipboard), ctrl-shift or alt-shift is backwards (redo or alt-shift-tab). Here&#39;s my list of global shortcuts/key assignments, copied from keyhandler.py with my proposed changes in bold, please add anything I&#39;ve forgotten:<br>
<span style="font-family: courier new,monospace;">_actions_table = {</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">    &#39;F1&#39;                   : &#39;zoom_mesh&#39;,</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">    &#39;F2&#39;                   : &#39;zoom_group&#39;,</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">    &#39;F3&#39;                   : &#39;zoom_home&#39;,</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">    &#39;F4&#39;                   : &#39;zoom_activity&#39;,</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">    &#39;F9&#39;                   : &#39;brightness_down&#39;,</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">    &#39;F10&#39;                  : &#39;brightness_up&#39;,</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">    &#39;&lt;alt&gt;F9&#39;              : &#39;brightness_min&#39;,</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">    &#39;&lt;alt&gt;F10&#39;             : &#39;brightness_max&#39;,</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">    &#39;XF86AudioMute&#39;        : &#39;volume_mute&#39;,</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">    &#39;F11&#39;                  : &#39;volume_down&#39;,</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">    &#39;XF86AudioLowerVolume&#39; : &#39;volume_down&#39;,</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">    &#39;F12&#39;                  : &#39;volume_up&#39;,</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">    &#39;XF86AudioRaiseVolume&#39; : &#39;volume_up&#39;,</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">    &#39;&lt;alt&gt;F11&#39;             : &#39;volume_min&#39;,</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">    &#39;&lt;alt&gt;F12&#39;             : &#39;volume_max&#39;,</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">    &#39;0x93&#39;                 : &#39;frame&#39;,</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">    &#39;Insert&#39;             </span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">    &#39;0xEB&#39;                 : &#39;rotate&#39;,</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">    &#39;&lt;alt&gt;Tab&#39;             : &#39;next_window&#39;,</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">    &#39;&lt;alt&gt;&lt;shift&gt;Tab&#39;      : &#39;previous_window&#39;,</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">    &#39;&lt;alt&gt;Escape&#39;          : &#39;close_window&#39;,</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">    &#39;0xDC&#39;                 : &#39;open_search&#39;,</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"># the following are intended for emulator users</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">    &#39;&lt;alt&gt;&lt;shift&gt;f&#39;        : &#39;frame&#39;,</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">    &#39;&lt;alt&gt;&lt;shift&gt;q&#39;        : &#39;quit_emulator&#39;,</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">    &#39;XF86Search&#39;           : &#39;open_search&#39;,</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">    &#39;&lt;alt&gt;&lt;shift&gt;o&#39;        : &#39;open_search&#39;,</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">    &#39;&lt;alt&gt;&lt;shift&gt;r&#39;        : &#39;rotate&#39;,</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">    &#39;&lt;alt&gt;&lt;shift&gt;s&#39;        : &#39;say_text&#39;,</span><br>
<br>-SOAS <br><br><br><br><br>