Oops. Sorry, I didn&#39;t know that &quot;tab&quot; was &quot;send&quot; in this gmail&#39;s keyboard shortcuts. Resend, more complete at bottom.<br><br><div class="gmail_quote">---------- Forwarded message ----------<br>From: <b class="gmail_sendername">Jameson Quinn</b> <span dir="ltr">&lt;<a href="mailto:jameson.quinn@gmail.com">jameson.quinn@gmail.com</a>&gt;</span><br>
Date: 2009/4/30<br>Subject: Keyboard shortcuts<br>To: sugar-devel &lt;<a href="mailto:sugar-devel@lists.sugarlabs.org">sugar-devel@lists.sugarlabs.org</a>&gt;<br><br><br>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" target="_blank">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;"><b><span style="font-family: courier new,monospace;">    &#39;Insert&#39;               : &#39;frame&#39;, #for SoaS<br>
    &#39;0x00&#39;                 : &#39;frame&#39;, #for SoaS on Xephyr, see below.</span></b><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;">
<b><span style="font-family: courier new,monospace;">    &#39;&lt;alt&gt;&lt;ctrl&gt;Escape&#39;    : &#39;close_window_discard_from_journal&#39;,</span></b><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">    &#39;0xDC&#39;                 : &#39;open_search&#39;,<br><b>    &#39;&lt;alt&gt;1&#39;               : </b></span><b><span style="font-family: courier new,monospace;">&#39;zoom_mesh&#39;</span><span style="font-family: courier new,monospace;">,<br>
 #... alt-numeral should be like the top row of the frame, so alt-5 would be journal <br> #and alt-6 first running activity <br>    &#39;&lt;alt&gt;Enter&#39;           : &#39;hide-toolbar&#39;, #if implemented by activity<br>
    &#39;&lt;alt&gt;v&#39;               : &#39;view-source&#39;,<br>    &#39;&lt;alt&gt;c&#39;               : &#39;screen-capture&#39;,<br>    &#39;PrtSc&#39;                : &#39;screen-capture&#39;,</span></b><br>       <br style="font-family: courier new,monospace;">
<b><span style="font-family: courier new,monospace;">    &#39;&lt;alt&gt;s&#39;               : &#39;say_text&#39;,</span></b> #was alt-shift-s<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;">

<b><span style="font-family: courier new,monospace;">#    &#39;&lt;alt&gt;&lt;shift&gt;f&#39;        : &#39;frame&#39;,</span> #removed</b><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;"><b><span style="font-family: courier new,monospace;">#    &#39;&lt;alt&gt;&lt;shift&gt;o&#39;        : &#39;open_search&#39;, #removed</span></b><br style="font-family: courier new,monospace;">

<b><span style="font-family: courier new,monospace;">#    &#39;&lt;alt&gt;&lt;shift&gt;r&#39;        : &#39;rotate&#39;, #removed</span></b><br>
<br>...<br>Also, ctrl-numeral would choose toolbars, and toolbar tabs would get little translucent numbers when you held control.<br><br>Implementation<br><br>Basically, I propose to do all this magic only on the subclasses already existing in sugar-graphics. Some of this is more-or-less a monkeypatch to GTK itself, but I am not signing up for dealing with upstream, and in fact much of this is not even appropriate for upstream. Some of you might feel that the &quot;ubiquitous&quot; stuff (saving LOC and strings) is not worth the maintenance headache to do it in such a hack-y fashion. If enough people say so, I have no problem abandoning that part of the plan.<br>
<br>OK, sorry for the double-post, and none of this is set in stone. I&#39;m happy to discuss and bikeshed a bit, but I have already started coding, so please comment relatively quickly if you object to the whole idea.<br>
<br>Jameson<br>
</div><br>