OptiKey / OptiKey

OptiKey - Full computer control and speech with your eyes
http://www.optikey.org
GNU General Public License v3.0
4.28k stars 507 forks source link

Adding support for custom keyboard layouts #471

Closed maxieds closed 6 years ago

maxieds commented 6 years ago

Hello.

I have a friend who has a motor disability and uses OptiKey to write computer programming language source code (slowly). She needs a single custom keyboard which contains all of the lowercase qwerty keys along with common symbols like '(', '{', and ';' on it at once. Currently it is painfully slow and difficult for her to write software since it requires changing keyboard pages for simple statements , e.g. "if(cond) {...". I have created a fork of the original source code so I can modify it for her and this specialized task.

My plan is to have a configuration file format which defines the custom keyboard layout and keymaps and then load it from file dynamically at runtime. The trouble I'm having is finding exactly where the original keyboard layouts are getting loaded in the unmodified source code. It looks like the keyboards are statically hardcoded in this file (and the keys are defined here). I also found references to a filepath for loading dynamic keyboards in this file. It's referenced as JuliusSweetland\OptiKey\Keyboards\.

Can someone point me in the direction of where in the source code I should look to go forward with making these modifications? Most of the documentation for the OptiKey software is geared at the end user. Any other tips you can give me for modifying the source code or it's organization would be very helpful here as well.

maxieds commented 6 years ago

I did subsequently find this localization guide which should be enough to get my friend up and running for software programming. I'm wondering if there's an easy way currently load custom key layouts from a file like this dynamically at runtime? It's kind of a pain to have to write a new locale (BTW I'm calling her new one the "Hacker" language) everytime a specific user has a new layout that suits a particular task they are using OptiKey for and recompiling is worse on Windows. If not would this be a useful feature that I could add to the main code base? Please let me know. I'd be happy to help if it is.

JuliusSweetland commented 6 years ago

@maxieds Hi Maxie. OptiKey does currently support the concept of dynamic keyboards loaded from xml, but there is not any official documentation. For this task I think the best way would be to hard code a new keyboard. This shouldn't be a new language, but instead could be an alternative to the Alpha1 keyboard. If you look here: https://github.com/OptiKey/OptiKey/tree/master/src/JuliusSweetland.OptiKey/UI/Views/Keyboards/English

You'll see 4 layouts for English: the default (Alpha), AlphabeticalAlpha, SimplifiedAlpha, and CommuniKate (which will actually be moving to the Common directory when I get a chance to make a change this evening). There are equivalent ViewModel files here: https://github.com/OptiKey/OptiKey/tree/master/src/JuliusSweetland.OptiKey/UI/ViewModels/Keyboards but these are not language specific.

The approach I would take it to copy the existing Alpha keyboard and add to it/modify it until it contains all the keys required. If there are too many then we can talk about having AlphaProgramming1.xaml and AlphaProgramming2.xaml files. I can then show you how to surface this to the end users in the Management Console so that anyone has the ability to go in and change their default Alpha keyboard to a programming keyboard.

FYI when you reply if you put @juliussweetland in your message I will get an email and be able to reply faster.

maxieds commented 6 years ago

@JuliusSweetland: Thank you. Your post actually arrived right at the conclusion of my late night / early morning adventures into the OptiKey source code. We had already found the CustomKeyboard at runtime and Keyboards settings in the OptiKey GUI, but yes there was no documentation for the syntax of these files except for what I could get out of the source code for OptiKey on my non-native Linux box. I managed to create a test XML file for the first screen of the programming layout (see also the attached PDF for Anna's nice schematic and layouts). The TextKey entries work wonderfully for the ASCII characters on the keyboard. The only problem is that I can't seem to get the ActionKey entries for the remaining keys to work correctly. Can you take a look at my attached layout file and help me figure out how to get the FunctionKeys working? OptiKey_coders_keyboard_layout_v2.pdf

<?xml version="1.0" encoding="utf-8"?>
<Keyboard>
     <Name>Anna's Custom Hacking Keyboard Profile (Page 1)</Name>
     <Symbol>ALPHA_LETTERS</Symbol>
     <HideFromKeyboardMenu>False</HideFromKeyboardMenu>
     <ShowOutputPanel>True</ShowOutputPanel>
     <Grid>
          <Rows>5</Rows>
          <Cols>24</Cols>
     </Grid>
     <Keys>
          <!-- Top Row Specs -->
          <TextKey> 
               <Row>0</Row>
               <Col>0</Col>
               <Height>1</Height>
               <Width>2</Width>
               <Text>&amp;</Text>
               <Label>&amp;</Label>
          </TextKey>
          <TextKey> 
               <Row>0</Row>
               <Col>2</Col>
               <Height>1</Height>
               <Width>2</Width>
               <Text>@</Text>
               <Label>@</Label>
          </TextKey>
          <TextKey> 
               <Row>0</Row>
               <Col>4</Col>
               <Height>1</Height>
               <Width>2</Width>
               <Text>if</Text>
               <Label>IF</Label>
          </TextKey>
          <TextKey> 
               <Row>0</Row>
               <Col>6</Col>
               <Height>1</Height>
               <Width>2</Width>
               <Text>else</Text>
               <Label>ELSE</Label>
          </TextKey>
          <TextKey> 
               <Row>0</Row>
               <Col>8</Col>
               <Height>1</Height>
               <Width>2</Width>
               <Text>continue</Text>
               <Label>CONTINUE</Label>
          </TextKey>
          <TextKey> 
               <Row>0</Row>
               <Col>10</Col>
               <Height>1</Height>
               <Width>2</Width>
               <Text>break</Text>
               <Label>BREAK</Label>
          </TextKey>
          <TextKey> 
               <Row>0</Row>
               <Col>12</Col>
               <Height>1</Height>
               <Width>2</Width>
               <Text>for</Text>
               <Label>FOR</Label>
          </TextKey>
          <TextKey> 
               <Row>0</Row>
               <Col>14</Col>
               <Height>1</Height>
               <Width>2</Width>
               <Text>while</Text>
               <Label>WHILE</Label>
          </TextKey>
          <TextKey> 
               <Row>0</Row>
               <Col>16</Col>
               <Height>1</Height>
               <Width>2</Width>
               <Text>int</Text>
               <Label>INT</Label>
          </TextKey>
          <TextKey> 
               <Row>0</Row>
               <Col>18</Col>
               <Height>1</Height>
               <Width>2</Width>
               <Text>char</Text>
               <Label>CHAR</Label>
          </TextKey>
          <ActionKey> 
               <Row>0</Row>
               <Col>20</Col>
               <Height>1</Height>
               <Width>2</Width>
               <Label>MENU</Label>
               <FunctionKey>Menu</FunctionKey>
          </ActionKey>
          <ChangeKeyboardKey> 
               <Row>0</Row>
               <Col>22</Col>
               <Height>1</Height>
               <Width>2</Width>
               <Label>NEXTKBD2</Label>
               <ReturnToThisKeyboard>True</ReturnToThisKeyboard>
               <DestinationKeyboard>HackerKeyboard2</DestinationKeyboard>
          </ChangeKeyboardKey>

          <!-- Second Row Specs -->       
          <TextKey> 
               <Row>1</Row>
               <Col>0</Col>
               <Height>1</Height>
               <Width>2</Width>
               <Text>q</Text>
               <Label>q</Label>
          </TextKey>
          <TextKey> 
               <Row>1</Row>
               <Col>2</Col>
               <Height>1</Height>
               <Width>2</Width>
               <Text>w</Text>
               <Label>w</Label>
          </TextKey>
          <TextKey> 
               <Row>1</Row>
               <Col>4</Col>
               <Height>1</Height>
               <Width>2</Width>
               <Text>e</Text>
               <Label>e</Label>
          </TextKey>
          <TextKey> 
               <Row>1</Row>
               <Col>6</Col>
               <Height>1</Height>
               <Width>2</Width>
               <Text>r</Text>
               <Label>r</Label>
          </TextKey>
          <TextKey> 
               <Row>1</Row>
               <Col>8</Col>
               <Height>1</Height>
               <Width>2</Width>
               <Text>t</Text>
               <Label>t</Label>
          </TextKey>
          <TextKey> 
               <Row>1</Row>
               <Col>10</Col>
               <Height>1</Height>
               <Width>2</Width>
               <Text>y</Text>
               <Label>y</Label>
          </TextKey>
          <TextKey> 
               <Row>1</Row>
               <Col>12</Col>
               <Height>1</Height>
               <Width>2</Width>
               <Text>u</Text>
               <Label>u</Label>
          </TextKey>
          <TextKey> 
               <Row>1</Row>
               <Col>14</Col>
               <Height>1</Height>
               <Width>2</Width>
               <Text>i</Text>
               <Label>i</Label>
          </TextKey>
          <TextKey> 
               <Row>1</Row>
               <Col>16</Col>
               <Height>1</Height>
               <Width>2</Width>
               <Text>o</Text>
               <Label>o</Label>
          </TextKey>
          <TextKey> 
               <Row>1</Row>
               <Col>18</Col>
               <Height>1</Height>
               <Width>2</Width>
               <Text>p</Text>
               <Label>p</Label>
          </TextKey>
          <TextKey> 
               <Row>1</Row>
               <Col>20</Col>
               <Height>1</Height>
               <Width>2</Width>
               <Text>&#47;</Text>
               <Label>&#47;</Label>
          </TextKey>
          <TextKey> 
               <Row>1</Row>
               <Col>22</Col>
               <Height>1</Height>
               <Width>2</Width>
               <Label>BACKONE</Label>
               <Text>&#127;</Text>
          </TextKey>

          <!-- Third Row Specs -->
          <TextKey> 
               <Row>2</Row>i
               <Col>0</Col>
               <Height>1</Height>
               <Width>2</Width>
               <Text>&#9;</Text>
               <Label>TAB</Label>
          </TextKey>
          <TextKey> 
               <Row>2</Row>
               <Col>2</Col>
               <Height>1</Height>
               <Width>2</Width>
               <Text>a</Text>
               <Label>a</Label>
          </TextKey>
          <TextKey> 
               <Row>2</Row>
               <Col>4</Col>
               <Height>1</Height>
               <Width>2</Width>
               <Text>s</Text>
               <Label>s</Label>
          </TextKey>
          <TextKey> 
               <Row>2</Row>
               <Col>6</Col>
               <Height>1</Height>
               <Width>2</Width>
               <Text>d</Text>
               <Label>d</Label>
          </TextKey>
          <TextKey> 
               <Row>2</Row>
               <Col>8</Col>
               <Height>1</Height>
               <Width>2</Width>
               <Text>f</Text>
               <Label>f</Label>
          </TextKey>
          <TextKey> 
               <Row>2</Row>
               <Col>10</Col>
               <Height>1</Height>
               <Width>2</Width>
               <Text>g</Text>
               <Label>g</Label>
          </TextKey>
          <TextKey> 
               <Row>2</Row>
               <Col>12</Col>
               <Height>1</Height>
               <Width>2</Width>
               <Text>h</Text>
               <Label>h</Label>
          </TextKey>
          <TextKey> 
               <Row>2</Row>
               <Col>14</Col>
               <Height>1</Height>
               <Width>2</Width>
               <Text>j</Text>
               <Label>j</Label>
          </TextKey>
          <TextKey> 
               <Row>2</Row>
               <Col>16</Col>
               <Height>1</Height>
               <Width>2</Width>
               <Text>k</Text>
               <Label>k</Label>
          </TextKey>
          <TextKey> 
               <Row>2</Row>
               <Col>18</Col>
               <Height>1</Height>
               <Width>2</Width>
               <Text>l</Text>
               <Label>l</Label>
          </TextKey>
          <TextKey> 
               <Row>2</Row>
               <Col>20</Col>
               <Height>1</Height>
               <Width>2</Width>
               <Text>!</Text>
               <Label>!</Label>
          </TextKey>
          <TextKey> 
               <Row>2</Row>
               <Col>22</Col>
               <Height>1</Height>
               <Width>2</Width>
               <Text>$</Text>
               <Label>$</Label>
          </TextKey>

          <!-- Fourth Row Specs -->
          <ActionKey> 
               <Row>3</Row>
               <Col>0</Col>
               <Height>1</Height>
               <Width>2</Width>
               <Label>SHIFT</Label>
               <FunctionKey>Keys.LeftShift</FunctionKey>
          </ActionKey>
          <TextKey> 
               <Row>3</Row>
               <Col>2</Col>
               <Height>1</Height>
               <Width>2</Width>
               <Text>z</Text>
               <Label>z</Label>
          </TextKey>
          <TextKey> 
               <Row>3</Row>
               <Col>4</Col>
               <Height>1</Height>
               <Width>2</Width>
               <Text>x</Text>
               <Label>x</Label>
          </TextKey>
          <TextKey> 
               <Row>3</Row>
               <Col>6</Col>
               <Height>1</Height>
               <Width>2</Width>
               <Text>c</Text>
               <Label>c</Label>
          </TextKey>
          <TextKey> 
               <Row>3</Row>
               <Col>8</Col>
               <Height>1</Height>
               <Width>2</Width>
               <Text>v</Text>
               <Label>v</Label>
          </TextKey>
          <TextKey> 
               <Row>3</Row>
               <Col>10</Col>
               <Height>1</Height>
               <Width>2</Width>
               <Text>b</Text>
               <Label>b</Label>
          </TextKey>
          <TextKey> 
               <Row>3</Row>
               <Col>12</Col>
               <Height>1</Height>
               <Width>2</Width>
               <Text>n</Text>
               <Label>n</Label>
          </TextKey>
          <TextKey> 
               <Row>3</Row>
               <Col>14</Col>
               <Height>1</Height>
               <Width>2</Width>
               <Text>m</Text>
               <Label>m</Label>
          </TextKey>
          <TextKey> 
               <Row>3</Row>
               <Col>16</Col>
               <Height>1</Height>
               <Width>2</Width>
               <Text>`</Text>
               <Label>`</Label>
          </TextKey>
          <TextKey> 
               <Row>3</Row>
               <Col>18</Col>
               <Height>1</Height>
               <Width>2</Width>
               <Text>&#59;</Text>
               <Label>&#59;</Label>
          </TextKey>
          <TextKey> 
               <Row>3</Row>
               <Col>20</Col>
               <Height>1</Height>
               <Width>2</Width>
               <Text>.</Text>
               <Label>.</Label>
          </TextKey>
          <TextKey> 
               <Row>3</Row>
               <Col>22</Col>
               <Height>1</Height>
               <Width>2</Width>
               <Text>^</Text>
               <Label>^</Label>
          </TextKey>

          <!-- Row Five Specs -->
          <ActionKey> 
               <Row>4</Row>
               <Col>0</Col>
               <Height>1</Height>
               <Width>2</Width>
               <Label>CTRL</Label>
               <FunctionKey>Keys.ControlKey</FunctionKey>
          </ActionKey>
          <ActionKey> 
               <Row>4</Row>
               <Col>2</Col>
               <Height>1</Height>
               <Width>2</Width>
               <Label>ALT</Label>
               <FunctionKey>Keys.Alt</FunctionKey>
          </ActionKey>
          <TextKey> 
               <Row>4</Row>
               <Col>4</Col>
               <Height>1</Height>
               <Width>2</Width>
               <Text>(</Text>
               <Label>(</Label>
          </TextKey>
          <TextKey> 
               <Row>4</Row>
               <Col>6</Col>
               <Height>1</Height>
               <Width>2</Width>
               <Text>)</Text>
               <Label>)</Label>
          </TextKey>
          <TextKey> 
               <Row>4</Row>
               <Col>8</Col>
               <Height>1</Height>
               <Width>4</Width>
               <Text>&#32;</Text>
               <Label>SPACE</Label>
          </TextKey>
          <TextKey> 
               <Row>4</Row>
               <Col>12</Col>
               <Height>1</Height>
               <Width>2</Width>
               <Text>{</Text>
               <Label>{</Label>
          </TextKey>
          <TextKey> 
               <Row>4</Row>
               <Col>14</Col>
               <Height>1</Height>
               <Width>2</Width>
               <Text>}</Text>
               <Label>}</Label>
          </TextKey>
          <TextKey> 
               <Row>4</Row>
               <Col>16</Col>
               <Height>1</Height>
               <Width>4</Width>
               <Text>&#13;</Text>
               <Label>ENTER</Label>
               <Symbol>Enter</Symbol>
          </TextKey>
          <TextKey> 
               <Row>4</Row>
               <Col>20</Col>
               <Height>1</Height>
               <Width>2</Width>
               <Text>=</Text>
               <Label>=</Label>
          </TextKey>
          <TextKey> 
               <Row>4</Row>
               <Col>22</Col>
               <Height>1</Height>
               <Width>2</Width>
               <Text>_</Text>
               <Label>_</Label>
          </TextKey>          

     </Keys>
</Keyboard>
JuliusSweetland commented 6 years ago

@maxieds Hi Maxie. Dynamic keyboard support was actually written by @kmcnaught as part of her excellent work on EyeMine. I'm at work, but a quick look at this class: https://github.com/OptiKey/OptiKey/blob/5b64d3551ad4ea3f5a2856f3894e1a8e0ba3de3e/src/JuliusSweetland.OptiKey/Models/XmlKeyboardModels/XmlActionKey.cs suggests that an ActionKey should have an "Action" rather than a "FunctionKey" and the value should be a member of the enum FunctionKeys, (https://github.com/OptiKey/OptiKey/blob/master/src/JuliusSweetland.OptiKey/Enums/FunctionKeys.cs) e.g. "LeftCtrl"

Can you give that a go and let me know if that helps?

Also you can check the log file as the xml parsing logic outputs log entries when it encounters issues. Instructions on finding the logs can be found here: https://github.com/OptiKey/OptiKey/wiki/Other-issues

maxieds commented 6 years ago

@JuliusSweetland @kmcnaught: Another thing that doesn't seem to be working with the loading of custom keyboards from XML file is the ability to specify a CAPSLOCK and normal keysetting, i.e., effectively getting both a/A from the same key on the same keyboard by pressing the shift command. If it were possible to specify these settings from the XML file as in the .xaml keyboard layout files you suggested I modify, then from Anna's schematics there shouldn't be any need for a new keyboard setting since you can get all of the required characters by pressing shift. I guess this is more of a feature request for the application unless I've missed something and this behavior is already possible with the existing code.

JuliusSweetland commented 6 years ago

@maxieds It may be possible to support upper and lowercase letters, but I don't think you will be able to change the value of a key, e.g. from "\" to "|" by pressing shift. Unless... you create 2 dynamic keyboards and put a fake SHIFT key on each one that actually switches between the keyboards.

kmcnaught commented 6 years ago

Hi @maxieds,

As Julius mentioned, I added the dynamic keyboard support while forking the repo for a minecraft-specific version of OptiKey. As such it's not documented for other users, and may be slightly lacking in functionality in areas that weren't necessary for me. But I was always intending it to be useful to others.

It might be worth you checking out the EyeMine code to see example keyboards: https://github.com/SpecialEffect/EyeMine/tree/dynamicKeyboardsMinecraft/src/JuliusSweetland.OptiKey/Resources/Keyboards/EyeTracker

Julius is correct that ActionKeys have Actions, which should be a member of enum FunctionKeys.

maxieds commented 6 years ago

Thanks again for all of the helpful suggestions. The following are the completed mock ups of the hacker's / custom coding keyboard layouts:

  1. HackerKeyboard1.xml
  2. HackerKeyboard2.xml
  3. HackerKeyboardSymbols1.xml

If other users want to modify them, the examples are fairly complete and self-documenting. Other Actions for the ActionKey entries are found in this enum.

I also added instructions for use in the README.md file in my forked repo. Please by all means use and copy these instructions and our new keyboard files to your project so other users can modify them and see how to use this undocumented capability easily. There's no use in me having stared at this all night in C# for someone else to have to do the same :)

@JuliusSweetland @kmcnaught

JuliusSweetland commented 6 years ago

@maxieds Thanks Maxie. I'll try to find time this week to take what you've produced and add it to a new OptiKey wiki page outlining how dynamic keyboards work.

Is Anna happy with the new hacker keyboards?

maxieds commented 6 years ago

Is Anna happy with the new hacker keyboards?

Don't know yet, she's still asleep at this time of the morning. I prefer to work in the middle of the night :)

@JuliusSweetland

JuliusSweetland commented 6 years ago

@maxieds I prefer working like that also. I'd be very interested to hear how she likes them when she's had a chance to try them out.

maxieds commented 6 years ago

@JuliusSweetland

I think we came to the conclusion that it is overall much more useful for coding than the default keyboard layouts for obvious reasons, but at the same time there are some improvements that need to be made and/or added to the default branch.

First, off there needs to be an icon or menu item in the main keyboard menu (with the language selection settings, etc.) that will take users off to the list of dynamically loaded keyboards at runtime. As it is now, you can only get to this screen with an ActionKey with action of DynamicKeyboardNext (or similar). So you need to have a custom keyboard specified as your start up keyboard to even see these settings. It would be nice to have the option to switch to a dynamic keyboard layout without having to start in this mode. This is not ideal for users.

Secondly, there are text sizing issues with the smaller keys. I think that it's choosing the largest textsize possible for all width-2 keys, i.e., CONTINUE has the same font size as A which leads to some on screen readability issues. For comparison, see this image where the width-4 ENTER and SPACE keys are appropriately sized and much easier to read with eye tracking software. This could also easily be amended by including a new XML element for the key ICON associated with that key as is standard in the .xaml files used to configure all of the built-in keyboard layouts. This actually should be fairly easy to add to the existing source. Then you just put the burden of figuring out the appropriate display sizing on the user who can custom pick their icons from the large list in pageset.obz.

There are also some functionality improvements that could be made to the dictionary / auto completion suggestions when parsing source code. In particular, the English dictionary is not the most relevant set of lookups that can be given when we are speaking Python or C++. You mentioned the possibility before of adding a new class of built-in keyboards specifically for this purpose. Perhaps you could add some way of tagging the type of application or document that is being typed and modify the loaded dictionary accordingly? I think it would also be useful to have the auto completion operate with some kind of regex or pattern matching for writing in programming languages. For example, after I type if(flag) an obvious next suggestion is { or :, and similarly after the if and a closing ``}'' it should suggest else if( and else {. This might require keeping too much state to be useful, but it again would be a really nice feature to improve the user's experience with OptiKey for this task.

These are just a few suggestions for improving the user experience with this new feature. Overall I have to say that I'm impressed with the quality of the software and had a fun time hacking on it today. Nice work! It would be even better if I could figure out how to get it to build with dotnet or xbuild on Linux.

JuliusSweetland commented 6 years ago

@maxieds These are all good suggestions. The most important one, I believe, is the key sizing issues. In the normal keyboards this is tackled by setting the SharedSizeGroup (e.g. SharedSizeGroup="KeyWithSingleLetter") property on the key. Are you interested in trying to add this to the xml parsing logic? That way you would set one group for keys with single letters, another for keys with longer text, and another for keys with symbols. This (should) work in conjunction with the width/height properties to make the appearance of keys consistent across these group names.

maxieds commented 6 years ago

This modification would need to be done to the C# source code, correct? I can't just add this into the xml file parameters as is in the existing branch?

On Wed, Jul 4, 2018, 3:32 PM Julius notifications@github.com wrote:

@maxieds https://github.com/maxieds These are all good suggestions. The most important one, I believe, is the key sizing issues. In the normal keyboards this is tackled by setting the SharedSizeGroup (e.g. SharedSizeGroup="KeyWithSingleLetter") property on the key. Are you interested in trying to add this to the xml parsing logic? That way you would set one group for keys with single letters, another for keys with longer text, and another for keys with symbols. This (should) work in conjunction with the width/height properties to make the appearance of keys consistent across these group names.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/OptiKey/OptiKey/issues/471#issuecomment-402547725, or mute the thread https://github.com/notifications/unsubscribe-auth/AVI4uM4bFp0PQ7yC2oxoG10LDSRoEIgfks5uDRhDgaJpZM4VByZg .

JuliusSweetland commented 6 years ago

That's correct - it would have to be a code change.

On Wed, Jul 4, 2018 at 8:41 PM Maxie D. Schmidt notifications@github.com wrote:

This modification would need to be done to the C# source code, correct? I can't just add this into the xml file parameters as is in the existing branch?

On Wed, Jul 4, 2018, 3:32 PM Julius notifications@github.com wrote:

@maxieds https://github.com/maxieds These are all good suggestions. The most important one, I believe, is the key sizing issues. In the normal keyboards this is tackled by setting the SharedSizeGroup (e.g. SharedSizeGroup="KeyWithSingleLetter") property on the key. Are you interested in trying to add this to the xml parsing logic? That way you would set one group for keys with single letters, another for keys with longer text, and another for keys with symbols. This (should) work in conjunction with the width/height properties to make the appearance of keys consistent across these group names.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/OptiKey/OptiKey/issues/471#issuecomment-402547725, or mute the thread < https://github.com/notifications/unsubscribe-auth/AVI4uM4bFp0PQ7yC2oxoG10LDSRoEIgfks5uDRhDgaJpZM4VByZg

.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/OptiKey/OptiKey/issues/471#issuecomment-402548789, or mute the thread https://github.com/notifications/unsubscribe-auth/AEgPgZKpSHFTbH9bVZeXFOlHo-VkH9KYks5uDRppgaJpZM4VByZg .

annakirkpatrick commented 6 years ago

Hi, all,

This is Anna. I'm not a member of the stay-up-all-night-hacking club, but I I do have a github account.

Maxie showed me the keyboards this morning and we got them working on my machine. And I know how to modify them, which is probably the most important part. (I know I will inevitably run into the need to make small changes once I start actually using the new keyboards.)

At the moment Maxie actually has my eye tracker, for hacking/testing purposes, and so I have not really tried to use the new layout yet. (I'm currently writing with speech to text software, which is great for English, not so much for C or Python.) But I will definitely give some feedback once I have been using the new keyboards for a few weeks, and I will of course share whatever iteration of the keyboards turned out to be the most useful.

I will make a couple of other comments about some of the questions discussed in this thread. Take them for whatever they're worth.

  1. Maxie mentioned some code prediction/completion features that might be useful. It is absolutely true that the normal English dictionary does not lead to good predictions when you're writing code (and some of the spacing behavior is problematic as well), but I don't think the answer is to try to integrate the code prediction into OptiKey. There are lots of great editors for all sorts of languages that already have some really good prediction and completion tools, and most of them can be accessed with just tab and enter, so they are quite usable with OptiKey. (Sometimes you need arrow keys, which is why I included them on the "symbols" keyboard.) If anything, my suggestion would be to include an option to simply turn off predictions and remove the prediction panel from the top of the keyboard. This would either free up some screen real estate for your editor or give room to put more of the necessary symbols on the main keyboard.

  2. The ability to switch between dynamic keyboards during use could be quite helpful. Two reasons. First, as it stands, you can have a dynamic keyboards selected as your starting keyboard and then accidentally navigate back to the main alpha keyboard (through the menu), and the only way then to get back to your custom keyboard is to restart the program, which can't be done from inside OptiKey. (Now that I think about it, that is probably a feature worth considering. I have seen some instances where OptiKey gets very slow and difficult to use. Can't work out why. In these cases, the best solution I have found is to just restart the program. I have some ability to use a trackball or joystick mouse, so I can restart OptiKey from the taskbar, but some of your users probably don't have that option.) Second, I can envision designing several different hacker keyboards for myself aimed at different languages. The core of the keyboard would stay the same, but some of the language specific keys which shift. In this situation, I can see switching between them pretty frequently (e.g., switching from my Python keyboard to my Bash keyboard and back again as I am writing code and debugging). Certainly not an urgent thing for me, as I do have the ability to use a mouse, but I can see it being very useful to some.

Like I said, just some thoughts. Thanks to both of you for your help and your work on this project!

maxieds commented 6 years ago

I'm working on the shared size group property code now. I will also see how difficult it is to add in the icon element into an XmlKey and see if we can get these custom layouts setup and looking more or less like the defaults if the user configures them this way.

On Wed, Jul 4, 2018, 4:15 PM Anna Kirkpatrick notifications@github.com wrote:

Hi, all,

This is Anna. I'm not a member of the stay-up-all-night-hacking club, but I I do have a github account.

Maxie showed me the keyboards this morning and we got them working on my machine. And I know how to modify them, which is probably the most important part. (I know I will inevitably run into the need to make small changes once I start actually using the new keyboards.)

At the moment Maxie actually has my eye tracker, for hacking/testing purposes, and so I have not really tried to use the new layout yet. (I'm currently writing with speech to text software, which is great for English, not so much for C or Python.) But I will definitely give some feedback once I have been using the new keyboards for a few weeks, and I will of course share whatever iteration of the keyboards turned out to be the most useful.

I will make a couple of other comments about some of the questions discussed in this thread. Take them for whatever they're worth.

1.

Maxie mentioned some code prediction/completion features that might be useful. It is absolutely true that the normal English dictionary does not lead to good predictions when you're writing code (and some of the spacing behavior is problematic as well), but I don't think the answer is to try to integrate the code prediction into OptiKey. There are lots of great editors for all sorts of languages that already have some really good prediction and completion tools, and most of them can be accessed with just tab and enter, so they are quite usable with OptiKey. (Sometimes you need arrow keys, which is why I included them on the "symbols" keyboard.) If anything, my suggestion would be to include an option to simply turn off predictions and remove the prediction panel from the top of the keyboard. This would either free up some screen real estate for your editor or give room to put more of the necessary symbols on the main keyboard. 2.

The ability to switch between dynamic keyboards during use could be quite helpful. Two reasons. First, as it stands, you can have a dynamic keyboards selected as your starting keyboard and then accidentally navigate back to the main alpha keyboard (through the menu), and the only way then to get back to your custom keyboard is to restart the program, which can't be done from inside OptiKey. (Now that I think about it, that is probably a feature worth considering. I have seen some instances where OptiKey gets very slow and difficult to use. Can't work out why. In these cases, the best solution I have found is to just restart the program. I have some ability to use a trackball or joystick mouse, so I can restart OptiKey from the taskbar, but some of your users probably don't have that option.) Second, I can envision designing several different hacker keyboards for myself aimed at different languages. The core of the keyboard would stay the same, but some of the language specific keys which shift. In this situation, I can see switching between them pretty frequently (e.g., switching from my Python keyboard to my Bash keyboard and back again as I am writing code and debugging). Certainly not an urgent thing for me, as I do have the ability to use a mouse, but I can see it being very useful to some.

Like I said, just some thoughts. Thanks to both of you for your help and your work on this project!

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/OptiKey/OptiKey/issues/471#issuecomment-402552988, or mute the thread https://github.com/notifications/unsubscribe-auth/AVI4uEG9Ak5FgnWcW0ESMg2mRlF2vyrwks5uDSJGgaJpZM4VByZg .

JuliusSweetland commented 6 years ago

@annakirkpatrick I'm glad it looks promising so far. Regarding point 2 one suggestion would be to set the startup keyboard to Dynamic and create a few keyboards to meet your purposes. Each keyboard would need a link back to the main Dynamic selection keyboard (a back key?) and possible a Menu key to allow you access to all the usual keyboards.

maxieds commented 6 years ago

The only problem with this method is that without the keyboard menu link, if you ever make your way on to one of the built-in keyboards (say Alpha1 or currency) then you're stuck without a link and can't get back to the coding boards without restarting.

On Wed, Jul 4, 2018, 4:32 PM Julius notifications@github.com wrote:

@annakirkpatrick https://github.com/annakirkpatrick I'm glad it looks promising so far. Regarding point 2 one suggestion would be to set the startup keyboard to Dynamic and create a few keyboards to meet your purposes. Each keyboard would need a link back to the main Dynamic selection keyboard (a back key?) and possible a Menu key to allow you access to all the usual keyboards.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/OptiKey/OptiKey/issues/471#issuecomment-402555136, or mute the thread https://github.com/notifications/unsubscribe-auth/AVI4uJbh1hSEMufaebkiPpFd4ReWo34Tks5uDSZSgaJpZM4VByZg .

JuliusSweetland commented 6 years ago

Good point. I've got to work on something else high priority before I could possibly look at this for you.

On Wed, 4 Jul 2018, 22:47 Maxie D. Schmidt, notifications@github.com wrote:

The only problem with this method is that without the keyboard menu link, if you ever make your way on to one of the built-in keyboards (say Alpha1 or currency) then you're stuck without a link and can't get back to the coding boards without restarting.

On Wed, Jul 4, 2018, 4:32 PM Julius notifications@github.com wrote:

@annakirkpatrick https://github.com/annakirkpatrick I'm glad it looks promising so far. Regarding point 2 one suggestion would be to set the startup keyboard to Dynamic and create a few keyboards to meet your purposes. Each keyboard would need a link back to the main Dynamic selection keyboard (a back key?) and possible a Menu key to allow you access to all the usual keyboards.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/OptiKey/OptiKey/issues/471#issuecomment-402555136, or mute the thread < https://github.com/notifications/unsubscribe-auth/AVI4uJbh1hSEMufaebkiPpFd4ReWo34Tks5uDSZSgaJpZM4VByZg

.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/OptiKey/OptiKey/issues/471#issuecomment-402563542, or mute the thread https://github.com/notifications/unsubscribe-auth/AEgPgQtNMWDd5C9OLSsVgCdkMB5iT-o0ks5uDTf0gaJpZM4VByZg .

maxieds commented 6 years ago

@JuliusSweetland @annakirkpatrick

I'll see if I can work on this with my other modifications to the source (maybe in a few days). I'm going to issue a pull request soon for the modifications I made to the OptiKey source. The icons were already enabled in the XML files via the SYMBOL element, so I just needed to find where these were named. Updated screenshots and instructions of the much improved, nicer looking UI for these custom layouts are available in my forked repo. The updated keyboard files with icons for common named keys are available here in the meantime.

annakirkpatrick commented 6 years ago

@maxieds : This is really cool! Text sizes look much better now.

The shift behaviour is a bit confusing. i think largely this is a consequence of not changing the key labels to lower case when on that keyboard. I can Change that in the xml files and see how much of a difference that makes. it may turn out that the usual shift behaviour is useful enough that it isn't worth it to use the shift key hack to fit in a few extra symbols on the main keyboard. I'll just have to try and see what works best. I think I have good tools to experiment with now. Thanks!

kmcnaught commented 6 years ago

Hi @maxieds, I'm afraid I'm a daytime programmer too :)

A couple of things - though maybe I'm too late to the party and have lost the thread:

SharedSizeGroup: I already use this for keys in EyeMine, but it was a late addition so I haven't pushed it back to OptiKey. Check out commit eaf6ad8714e1e402b9157de4ec62111a6e5f6312. According to .NET rules a sharedsizegroup name must only consist of letters, digits, and underscore characters, and not start with a numeric value.

Small note: there's a small bug which occasionally makes the sizes inconsistent when you have two keys in progress at the same time (i.e. your gaze drifts between them). This is purely aesthetic and only occasionally comes up - now we have a user for the dynamic keyboards I'll report it.

Shift behaviour - have you found InitialKeyStates in the XML Keyboard definition? I can't remember exactly how the shift behaviour works for typing, but it's possible you could hold shift down for a whole keyboard, e.g. have one version with capitals (and InitialKeyStates->KeyLockedDown-> LeftShiftKey) and another with lower case (and InitialKeyStates->KeyUp-> LeftShiftKey).

Menu/navigation with dynamic keyboards - the way I imagined this working is that you'd have two use cases: 1 - User only wants their custom keyboards. Set the starting keyboard to be 'dynamic folder' (as you have) and make sure the back button doesn't take you out of here - I think this is possibly a bug in the core OptiKey branch. Then any navigation between your own keyboards you manage yourself with ChangeKeyboard keys. This gets a little tricky if you also want to add, e.g. one builtin keyboard (which you can link to using ChangeKeyboard keys too), just because many builtin keyboards have links to the menu and other keyboards too, so you might get a little lost navigation-wise.

2 - User wants all of OptiKey too. I would propose you create a basic (dynamic) menu keyboard, which has everything you want access to (for example, a copy of Julius' menu keyboard, but replace one of the less relevant keys (e.g. I always sacrifice diacritics) with a link to the DynamicKeyboardSelector keyboard, or your own dynamic sub-menu, e.g. 'Coding keyboards'. Now set up Optikey to start on the individual XML file defining your top level menu. Does this make sense?

kmcnaught commented 6 years ago

@annakirkpatrick, see my previous comment for suggestions on keyboard navigation.

In terms of word prediction, you might for now prefer to just remove the <ShowOutputPanel>True</ShowOutputPanel> from a keyboard if you don't want OptiKey's text suggestion. This removes the first two rows, including the suggested words and the scratchpad. If if was useful, these code be split apart in C# to expose the two things separately. But from your description it sounds like you wouldn't need either.

JuliusSweetland commented 6 years ago

@kmcnaught thanks Kirsty. Any chance you could put the sharedsizegroup update on a pr so I can pull it into master?

On Thu, 5 Jul 2018, 09:10 kmcnaught, notifications@github.com wrote:

@annakirkpatrick https://github.com/annakirkpatrick, see my previous comment for suggestions on keyboard navigation.

In terms of word prediction, you might for now prefer to just remove the

True

from a keyboard if you don't want OptiKey's text suggestion. This removes the first two rows, including the suggested words and the scratchpad. If if was useful, these code be split apart in C# to expose the two things separately. But from your description it sounds like you wouldn't need either.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/OptiKey/OptiKey/issues/471#issuecomment-402640969, or mute the thread https://github.com/notifications/unsubscribe-auth/AEgPgVm9KF2Y7EsZxzfFs7ThG6tgd2D7ks5uDcn_gaJpZM4VByZg .

annakirkpatrick commented 6 years ago

@kmcnaught thanks for your insight! I'm trying to make sure I understand your suggestions about organization. Option 1 makes sense, and the potential issue you highlight is indeed what I have run into. I'm struggling to see, though, why option 2 doesn't suffer from essentially the same problem. If you start on your custom dynamic menu keyboard, then from there you can clearly access all of the keyboards. But, suppose you navigate to, say, the main alphabetic keyboard. From there, the only places you can go are the normal OptiKey keyboards. So you can't get from the normal alphabetic keyboard back to your custom dynamic keyboards, right?

Also, thank you for mentioning the <ShowOutputPanel>True</ShowOutputPanel> option. Changing that to false gives me so much more space to use for keys or other applications! You are correct that I don't need either the predictions or the output panel.

annakirkpatrick commented 6 years ago

@maxieds , @JuliusSweetland , I have been experimenting with the new keyboards and learning how to make edits to the XML. As I mentioned before, the shift behavior is weird, with the letters appearing in uppercase regardless of whether the uppercase or lowercase keyboard is currently selected. I went to the XML files expecting to find that they both had uppercase letters. Keyboard 1 has lowercase letters while keyboard 2 has uppercase letters, but both keyboards are displayed as uppercase. (The typed characters are correct, at least in the sense that they are defined that way in the XML, though of course this is confusing as a user since they all appear uppercase on the keyboard.) Looking a little more broadly, it would appear that all of the text on the keyboard is displayed in uppercase, regardless of the case of the text in the XML. Is there a way to force keys to be displayed with lowercase text? (If not, I will just go back to a keyboard layout with normal shift behavior, which I honestly might end up doing anyway.)

JuliusSweetland commented 6 years ago

Off the top of my head it might be the initial shift behaviour (on most keyboards the shift key is initially pressed down). The shift key then goes through three states: down, locked down (like caps lock) and then up. See if you can release shift?

Otherwise can you experiment and see what is output, is it always uppercase? Keys can have their text set (which is always displayed, regardless of the state of the shift key), or you can set their ShiftUpText and ShiftDownText (I think those are the properties) and the appropriate one is displayed depending on the global state of the shift key.

On Thu, 5 Jul 2018, 21:52 Anna Kirkpatrick, notifications@github.com wrote:

@maxieds https://github.com/maxieds , @JuliusSweetland https://github.com/JuliusSweetland , I have been experimenting with the new keyboards and learning how to make edits to the XML. As I mentioned before, the shift behavior is weird, with the letters appearing in uppercase regardless of whether the uppercase or lowercase keyboard is currently selected. I went to the XML files expecting to find that they both had uppercase letters. Keyboard 1 has lowercase letters while keyboard 2 has uppercase letters, but both keyboards are displayed as uppercase. (The typed characters are correct, at least in the sense that they are defined that way in the XML, though of course this is confusing as a user since they all appear uppercase on the keyboard.) Looking a little more broadly, it would appear that all of the text on the keyboard is displayed in uppercase, regardless of the case of the text in the XML. Is there a way to force keys to be displayed with lowercase text? (If not, I will just go back to a keyboard layout with normal shift behavior, which I honestly might end up doing anyway.)

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/OptiKey/OptiKey/issues/471#issuecomment-402848864, or mute the thread https://github.com/notifications/unsubscribe-auth/AEgPge4GTv8hwoJx5uQmle91wstt5hD7ks5uDnx0gaJpZM4VByZg .

annakirkpatrick commented 6 years ago

@JuliusSweetland This keyboard does not have an actual shift key. Instead, Maxie used the hack you suggested above to create a fake shift key that just switches between two keyboards. (This allowed symbols to change as a result of pressing shift.)

I did try adding

     <InitialKeyStates>
          <KeyUp>LeftShift</KeyUp>
     </InitialKeyStates>

to the keyboard that should correspond to lowercase letters. No change.

Keyboard 1 always types lowercase letters, and keyboard 2 always types uppercase letters. This is the correct behavior; just accompanied by confusing graphics.

For both of the keyboards, the Text and Label properties are both set. It looks like the Label is displayed while the Text is what is actually typed. I do not see ShiftUpText or ShiftDownText anywhere.

JuliusSweetland commented 6 years ago

Can you explain the confusing behaviour? I'm not sure I understand what is going wrong if the keyboards display the correct key labels and output the correct output?

On Thu, 5 Jul 2018, 22:27 Anna Kirkpatrick, notifications@github.com wrote:

@JuliusSweetland https://github.com/JuliusSweetland This keyboard does not have an actual shift key. Instead, Maxie used the hack you suggested above to create a fake shift key that just switches between two keyboards. (This allowed symbols to change as a result of pressing shift.)

I did try adding

 <InitialKeyStates>
      <KeyUp>LeftShift</KeyUp>
 </InitialKeyStates>

to the keyboard that should correspond to lowercase letters. No change.

Keyboard 1 always types lowercase letters, and keyboard 2 always types uppercase letters. This is the correct behavior; just accompanied by confusing graphics.

For both of the keyboards, the Text and Label properties are both set. It looks like the Label is displayed while the Text is what is actually typed. I do not see ShiftUpText or ShiftDownText anywhere.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/OptiKey/OptiKey/issues/471#issuecomment-402857662, or mute the thread https://github.com/notifications/unsubscribe-auth/AEgPgeoxUt48ZEj4-vEVAfXNrtfxYI7rks5uDoTOgaJpZM4VByZg .

annakirkpatrick commented 6 years ago

@JuliusSweetland The output is correct; the labels are not. If the XML file sets the label equal to "a", the key displays "A". (It also displays "A" when the file does specify "A", resulting in the situation where a key labeled "A" sometimes types "a" and sometimes types "A". These are different keys, of course, on different keyboards, but they should have different displayed labels and don't.)

JuliusSweetland commented 6 years ago

@annakirkpatrick @maxieds OK this is a little bit complicated so let me explain a few things:

1.The label displayed on a key can be set in one of two ways; either by setting the Text property on the Key class (which results in this code being called to determine the case of the label https://github.com/OptiKey/OptiKey/blob/5b64d3551ad4ea3f5a2856f3894e1a8e0ba3de3e/src/JuliusSweetland.OptiKey/UI/Controls/Key.cs#L259) - this approach forces the case of the label on the key to Upper, Lower, or Title case, depending on what is explicitly set on the key, or in the OptiKey settings (Management Settings). This will not react to the state of the shift key. This is the method used by the Dynamic Keyboard when you specify the Label in the xml.

2.By individually setting the ShiftUpText and ShiftDownText properties. This then lets OptiKey decide which to display depending on the shift key state: Up = ShiftUpText, Down = ShiftDownText, or LockedDown = ShiftDownText. This is the approach you would want (assuming the shift state is correctly controlled by your keyboards). You would need to d 2 things:

a) Add support for ShiftUpText and ShiftDownText in the xml. The key's Text (which is actually the label of the key) is set here: https://github.com/OptiKey/OptiKey/blob/8cb69d0ec5b0c1d57047613c41675f30b025bda1/src/JuliusSweetland.OptiKey/UI/Views/Keyboards/Common/DynamicKeyboard.xaml.cs#L86

You would also need to add new properties for ShiftUpLabel and ShiftDownLabel to this class: https://github.com/OptiKey/OptiKey/blob/master/src/JuliusSweetland.OptiKey/Models/XmlKeyboardModels/XmlKey.cs#L23

All Text values in your XML should really be lowercase if you are going to rely on OptiKey to determine the casing for you based on the shift key state.

IF, HOWEVER, YOU WANT TO EXPLICITLY SET THE OUTPUT TEXT VALUE (INCLUDING CASING) IN YOUR XML FILE, then you need to effectively prevent OptiKey from setting the shift state (by setting the initial shift state to Up and then not altering this. If you do this then you don't need to do the above, but instead you need to set the Key Case property (https://github.com/OptiKey/OptiKey/blob/master/src/JuliusSweetland.OptiKey/UI/Controls/Key.cs#L296). To do this you'd need to add a new LabelCase property to your xml, to the XmlKey class, and to the logic in DynamicKeyboard.xaml.cs

I'll leave you to decide which approach is appropriate. The latter should work, but only if you are setting the InitialKeyStates property.

I hope that makes sense.

kmcnaught commented 6 years ago

@annakirkpatrick, my suggestions on navigation assumed that every keyboard has a 'Back' key, which I now realise might not be true, in which case you are correct that some pages might not let you get back to the dynamic keyboards again. I think Julius and I once chatted about explicitly replacing the current 'Menu' keyboard with a dynamic XML version (for everyone), which would mean that following a "Menu" key on any of the built in keyboards would take you to your own menu (which might include a link to "DynamicKeyboardSelector", or "Coding Keyboards", or just a few individual dynamic keyboards). I think this would be a reasonably sensible solution, since it also supports users who might want to contribute new C# keyboards (e.g. because they need some functionality that isn't yet in dynamic XML keyboards), allowing anyone else to define their own subset of keyboards they want to use, with a single XML file. @JuliusSweetland , what do you think about this? I'd be happy to implement it if you think it's a reasonable solution, should have some time in the next few weeks.

@JuliusSweetland I'll also try to get a PR together for 'SharedSizeGroup' in the next few days.

@annakirkpatrick I'll try to take a look at the shift behaviour soon too and make a suggestion. It wouldn't be too hard to add ShiftUpText/ShiftDownText in the XML definitions, but I'm not 100% sure whether the shift key would currently work correctly from a dynamic key, since we skip some of the more advanced typing logic that OptiKey uses. I'd have to take another look to remember how things are set up.

JuliusSweetland commented 6 years ago

I think it would be a good idea to replace the current menu keyboard, but would it be possible to replicate the different layouts for horizontal and vertical orientation? I guess not so another option would be to add a setting to replace the menu with a dynamic menu?

On Fri, 6 Jul 2018, 11:03 kmcnaught, notifications@github.com wrote:

@annakirkpatrick https://github.com/annakirkpatrick, my suggestions on navigation assumed that every keyboard has a 'Back' key, which I now realise might not be true, in which case you are correct that some pages might not let you get back to the dynamic keyboards again. I think Julius and I once chatted about explicitly replacing the current 'Menu' keyboard with a dynamic XML version (for everyone), which would mean that following a "Menu" key on any of the built in keyboards would take you to your own menu (which might include a link to "DynamicKeyboardSelector", or "Coding Keyboards", or just a few individual dynamic keyboards). I think this would be a reasonably sensible solution, since it also supports users who might want to contribute new C# keyboards (e.g. because they need some functionality that isn't yet in dynamic XML keyboards), allowing anyone else to define their own subset of keyboards they want to use, with a single XML file. @JuliusSweetland https://github.com/JuliusSweetland , what do you think about this? I'd be happy to implement it if you think it's a reasonable solution, should have some time in the next few weeks.

@JuliusSweetland https://github.com/JuliusSweetland I'll also try to get a PR together for 'SharedSizeGroup' in the next few days.

@annakirkpatrick https://github.com/annakirkpatrick I'll try to take a look at the shift behaviour soon too and make a suggestion. It wouldn't be too hard to add ShiftUpText/ShiftDownText in the XML definitions, but I'm not 100% sure whether the shift key would currently work correctly from a dynamic key, since we skip some of the more advanced typing logic that OptiKey uses. I'd have to take another look to remember how things are set up.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/OptiKey/OptiKey/issues/471#issuecomment-402989694, or mute the thread https://github.com/notifications/unsubscribe-auth/AEgPgal7Lxrago-mi0jPkTYNrNu4GsTfks5uDzYFgaJpZM4VByZg .

annakirkpatrick commented 6 years ago

@JuliusSweetland thank you for that explanation regarding the case of labels displayed on the keys. I do think I understand what is going on now. My inclination is to use the first strategy you presented and to include a true shift key on the keyboard. The potential issue here, of course, is your comment

(assuming the shift state is correctly controlled by your keyboards)

@kmcnaught, I would really appreciate your input on this. I have been looking through some of the code, and I think I could handle adding the ShiftUpText/ShiftDownText as Julius described, but I know I'm not seeing the whole picture.

Regarding navigation and menus, yes, there are several keyboards that don't have a back button, which certainly can lead to getting stuck.

Replacing the menu keyboard with a dynamic keyboard sounds fine to me (modulo the comments Julius has already made).

A potential alternative: Would it make sense to just add a button to the current menu keyboard that links to the dynamic keyboard selector? Of course, that creates a layout problem because the current menu is a nice 4 x 4 grid, but I can see several potential solutions. I've never used the sleep button on the menu screen; minimize always seemed much more useful and also essentially locks the keyboard. So I would be tempted to replace the sleep button. I can also see combining the increase opacity and decrease opacity keys, either letting each occupy half of the same key (which still gives a key larger than the normal letter keys) or creating a separate keyboard to adjust opacity.

JuliusSweetland commented 6 years ago

I like either the idea of replacing the menu sleep key, or splitting the opacity key. We could support both via a new setting alongside the existing dynamic settings.

On Fri, 6 Jul 2018, 22:16 Anna Kirkpatrick, notifications@github.com wrote:

@JuliusSweetland https://github.com/JuliusSweetland thank you for that explanation regarding the case of labels displayed on the keys. I do think I understand what is going on now. My inclination is to use the first strategy you presented and to include a true shift key on the keyboard. The potential issue here, of course, is your comment

(assuming the shift state is correctly controlled by your keyboards)

@kmcnaught https://github.com/kmcnaught, I would really appreciate your input on this. I have been looking through some of the code, and I think I could handle adding the ShiftUpText/ShiftDownText as Julius described, but I know I'm not seeing the whole picture.

Regarding navigation and menus, yes, there are several keyboards that don't have a back button, which certainly can lead to getting stuck.

Replacing the menu keyboard with a dynamic keyboard sounds fine to me (modulo the comments Julius has already made).

A potential alternative: Would it make sense to just add a button to the current menu keyboard that links to the dynamic keyboard selector? Of course, that creates a layout problem because the current menu is a nice 4 x 4 grid, but I can see several potential solutions. I've never used the sleep button on the menu screen; minimize always seemed much more useful and also essentially locks the keyboard. So I would be tempted to replace the sleep button. I can also see combining the increase opacity and decrease opacity keys, either letting each occupy half of the same key (which still gives a key larger than the normal letter keys) or creating a separate keyboard to adjust opacity.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/OptiKey/OptiKey/issues/471#issuecomment-403149042, or mute the thread https://github.com/notifications/unsubscribe-auth/AEgPgVRl66xhFZOOr9-adkAvRmcy1c8Zks5uD9PAgaJpZM4VByZg .

annakirkpatrick commented 6 years ago

@kmcnaught @JuliusSweetland @maxieds I've got shift working on dynamic keyboards! I made the changes Julius described to add support for the additional properties in the XML file and then set the corresponding properties of the Key object correctly, and it works.

At the moment, all I have is a minimal example. Just a keyboard with 2 keys: shift and A.

I see no reason that this won't work with a full keyboard. I just haven't had the time to do all of the necessary text entry to build one yet.

It is late and I need to turn off my computer, so I'm going to delay posting/pushing code until tomorrow.

I just wanted to go ahead and post this so that nobody spends any more time on a problem that is now solved.

JuliusSweetland commented 6 years ago

Great news. Thanks for the update.

On Mon, 9 Jul 2018, 03:04 Anna Kirkpatrick, notifications@github.com wrote:

@kmcnaught https://github.com/kmcnaught @JuliusSweetland https://github.com/JuliusSweetland @maxieds https://github.com/maxieds I've got shift working on dynamic keyboards! I made the changes Julius described to add support for the additional properties in the XML file and then set the corresponding properties of the Key object correctly, and it works.

At the moment, all I have is a minimal example. Just a keyboard with 2 keys: shift and A.

I see no reason that this won't work with a full keyboard. I just haven't had the time to do all of the necessary text entry to build one yet.

It is late and I need to turn off my computer, so I'm going to delay posting/pushing code until tomorrow.

I just wanted to go ahead and post this so that nobody spends any more time on a problem that is now solved.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/OptiKey/OptiKey/issues/471#issuecomment-403339124, or mute the thread https://github.com/notifications/unsubscribe-auth/AEgPgexpWUPecazL4a3_xcoOo7-js-Y6ks5uEroogaJpZM4VByZg .

kmcnaught commented 6 years ago

@annakirkpatrick great news - sorry I haven't had time to contribute. I took a quick look at shift behaviour myself before I saw this and agree with you that there's no reason this won't work.

@JuliusSweetland, @maxieds, @annakirkpatrick I don't see any reason why a dynamic 'Menu' keyboard couldn't support both vertical and horizontal formats, and from my perspective would be a lot cleaner than hard-changing the C# menu according to individual preferences - otherwise we'll end up having to support everyone's favourite pages and gradually increase clutter (or have an exponential explosion of feature toggles in the settings).

Obviously there's no reason for Anna not to use her own fork with a different C# menu keyboard, I'm just thinking about what gets incorporated into the main repo. Maybe in the interests of speed (bearing in mind I'm obviously failing to act quickly on this right now :)) @annakirkpatrick should move forward with her own hard coded preferred menu for now - just keeping the 'hard coding' commits separate so we can remove them from PRs, then I'll look at doing it properly with an XML file for each of the vertical, horizontal layouts.

JuliusSweetland commented 6 years ago

The replacement menu as a dynamic keyboard which supports horizontal and vertical layout sounds good to me. It could be used only when dynamic keyboards are enabled in the settings so most users are unaffected.

On Mon, 9 Jul 2018, 11:40 kmcnaught, notifications@github.com wrote:

@annakirkpatrick https://github.com/annakirkpatrick great news - sorry I haven't had time to contribute. I took a quick look at shift behaviour myself before I saw this and agree with you that there's no reason this won't work.

@JuliusSweetland https://github.com/JuliusSweetland, @maxieds https://github.com/maxieds, @annakirkpatrick https://github.com/annakirkpatrick I don't see any reason why a dynamic 'Menu' keyboard couldn't support both vertical and horizontal formats, and from my perspective would be a lot cleaner than hard-changing the C# menu according to individual preferences - otherwise we'll end up having to support everyone's favourite pages and gradually increase clutter (or have an exponential explosion of feature toggles in the settings).

Obviously there's no reason for Anna not to use her own fork with a different C# menu keyboard, I'm just thinking about what gets incorporated into the main repo. Maybe in the interests of speed (bearing in mind I'm obviously failing to act quickly on this right now :)) @annakirkpatrick https://github.com/annakirkpatrick should move forward with her own hard coded preferred menu for now - just keeping the 'hard coding' commits separate so we can remove them from PRs, then I'll look at doing it properly with an XML file for each of the vertical, horizontal layouts.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/OptiKey/OptiKey/issues/471#issuecomment-403436717, or mute the thread https://github.com/notifications/unsubscribe-auth/AEgPgXJajy9z-Q-HzlF6BOYP1yL_0yWpks5uEzMxgaJpZM4VByZg .

annakirkpatrick commented 6 years ago

Just a quick note to let everyone know that I have my" hacker" keyboard layout up and running. I have posted the XML and a screenshot over in my fork if anyone is curious.

XML: https://github.com/annakirkpatrick/OptiKey/blob/master/keyboards/BigHackerKeyboard.xml screenshot: https://github.com/annakirkpatrick/OptiKey/blob/master/keyboards/screenshots/BigHackerKeyboard.png

(The layout is based on some analysis of character frequency in source code that I did for another project some time ago. I've noticed that the easiest keys to consistently hit are near the center of the screen, so I organized the keyboard accordingly by frequency. Obviously some compromises were made in order to keep some semblance of organization, but in general I have quite a high tolerance for steep learning curves. Also, this is definitely intended for use on a large monitor. I would not even try to use it on my laptop screen.)

I have not touched anything regarding menus yet. That is next on my list, as I am sure the current configuration will get on my nerves. I don't think I have enough understanding of how the dynamic keyboards actually work to try to code up a menu that way, so I probably will hardcode something in the C# in my own fork for now. And of course I'll be careful about keeping the commits separate. (I will admit that I know very little about user-facing application development, but one thing I definitely can do is keep my commits organized.)

Also, there is now pull request with my changes to support ShiftUpText and ShiftDownText in dynamic keyboards. It's just a few dozen lines of code, so hopefully everything looks okay. But, like I said, I know very little about this type of development, so feedback is welcome and I'm happy to make changes if needed.

JuliusSweetland commented 6 years ago

@annakirkpatrick Thank you for the PR - that is now merged

maxieds commented 6 years ago

@JuliusSweetland

Do you need me to take some work off your plate and write the user documentation for these features?

JuliusSweetland commented 6 years ago

That would be REALLY helpful. Thank you.

On Wed, 11 Jul 2018, 01:03 Maxie D. Schmidt, notifications@github.com wrote:

@JuliusSweetland https://github.com/JuliusSweetland

Do you need me to take some work off your plate and write the user documentation for these features?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/OptiKey/OptiKey/issues/471#issuecomment-404003083, or mute the thread https://github.com/notifications/unsubscribe-auth/AEgPgfO9DlFE4fbpNE8T4QNptapyEIFxks5uFUDRgaJpZM4VByZg .

annakirkpatrick commented 6 years ago

@maxieds @JuliusSweetland I can also help with user documentation on how to create XML keyboards.

maxieds commented 6 years ago

@juliussweetland @annakirkpatrick

Yes, implicitly I was going to rope you into showing me the new options in your big hacker keyboard tomorrow when I have more energy. We can work on this tomorrow and post the user documentation to Anna's repo for Julius to add to the Optikey website 😁

On Jul 10, 2018 10:22 PM, "Anna Kirkpatrick" notifications@github.com wrote:

@maxieds https://github.com/maxieds @JuliusSweetland https://github.com/JuliusSweetland I can also help with user documentation on how to create XML keyboards.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/OptiKey/OptiKey/issues/471#issuecomment-404023765, or mute the thread https://github.com/notifications/unsubscribe-auth/AVI4uH0TqxjvcLlLklWDVZFLuGPLfXbjks5uFWFygaJpZM4VByZg .

annakirkpatrick commented 6 years ago

@JuliusSweetland Can you give me any guidance on how to best contribute documentation? Apparently the OptiKey wiki is not actually part of the OptiKey repository, so the fork, modify, pull request model doesn't seem to apply.

maxieds commented 6 years ago

@JuliusSweetland @annakirkpatrick

I have written my first draft of the custom XML keyboard layouts documentation here (Wiki page on Anna's forked repo). Please let me know what you think and if this will do it for the documentation we were after here. It's a little long but should be plenty of detail to get users up and running.

annakirkpatrick commented 6 years ago

@maxieds @JuliusSweetland I've taken a look at the wiki page that Maxie drafted, and I do think it covers all of the important points. I made one edit to clarify some of the more detailed behavior, but there are a couple more places where I think adding another sentence or two could be helpful. It is getting late, so I will make those edits tomorrow.

@JuliusSweetland I saw that you moved my keyboard file into the Resources directory with a commit message indicating that this would make it available to end-users. Where does that directory actually end up after install? It would be good to include that path in the documentation.

JuliusSweetland commented 6 years ago

Hi Anna,

You could either email me the markup directly or post the new markup I'm an issue?

Regards Julius

On Thu, 12 Jul 2018, 00:25 Anna Kirkpatrick, notifications@github.com wrote:

@JuliusSweetland https://github.com/JuliusSweetland Can you give me any guidance on how to best contribute documentation? Apparently the OptiKey wiki is not actually part of the OptiKey repository, so the fork, modify, pull request model doesn't seem to apply.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/OptiKey/OptiKey/issues/471#issuecomment-404341166, or mute the thread https://github.com/notifications/unsubscribe-auth/AEgPgSLG1TJbQ4wVGx0lUCpT98-Pnrc4ks5uFol3gaJpZM4VByZg .