Best way to use Onboard as a full emoji keyboard
I'd like to have a thing to enter emoji on Ubuntu, with a large selection of emoji in (and fortunately the http://
So, what I think I'd like to do is offer an "Emoji keyboard" app, which is *really* just, basically, a thing to start a new separate instance of Onboard, with window decorations turned on, and a custom layout. I have a few questions which perhaps you can help with:
1. is it possible to start Onboard with a custom set of *settings*? The emoji keyboard is at least partially aimed at ordinary keyboard users who just want to find an emoji character, and so should be a window with window decorations and easily quittable, but I wouldn't want to change the standard onboard settings! So I'd like to launch it as, say, onboard --custom-
2. Is there documentation for the layout .onboard files and svgs and how to create them? I can of course probably work it out from the existing layouts and the code, but if there are docs I'd be happy to read them.
3. obviously there is a second step here, which is "make Ubuntu display the pretty emoji images in all applications rather than the Unicode character which you might not even have", but that's not what I'm trying to do.
I'd love to hear any suggestions that you might have on the subject. (I'd also be happy to take this conversation to a mailing list or somewhere else more appropriate if there is anywhere.)
Question information
- Language:
- English Edit question
- Status:
- Answered
- For:
- Onboard Edit question
- Assignee:
- No assignee Edit question
- Last query:
- Last reply:
This question was originally filed as bug #1394371.
Related FAQ:
None Link to a FAQ
This question was reopened
Revision history for this message
|
#1 |
Since you're not directly asking for changes in Onboard, I'll convert the bug report to a question. We can still open specific bug reports as needed later.
Revision history for this message
|
#2 |
Hi, Stuart. Whiteboard has few Emojis, but there are a little more in the "Small" and "Phone" layouts. Francesco worked on those back then. Nothing remotely close to thousands, though.
A second instance of Onboard isn't well supported currently. There's even a single instance check by default, and while it can be disabled
onboard -m
there is still only a single set of preferences for everything from window position to active layout.
1. Something like onboard --custom-
That said, with a bit of work it might actually be possible to add a file-based backend. Reading arbitrary settings from a file is already there in from of system defaults. Those are ini style files, you probably have one installed at /etc/onboard/
If you want to look at the code, the vast majority of Onboard's gets its settings from a central Config object (hierarchy) in Config.py. Those add_key calls install a bunch of properties for convenient, pythonic read/write access. The gsettings machinery behind that is hidden in ConfigUtils.py. That's where I would start.
2. There's no documentation for the layout files, sorry. We can walk you through, though. Also feel free to ask anytime.
The svg files are standard (Inkscape+scour, manually edited here and there), but Onboard only recognizes rect, path and g (group) tags. The link between *.onboard, *.svg and *.colors files is the id attribute, aka key id.
The easiest way to start a new layout is to copy an existing one with the "New" button in Preferences->Layout
3. I see, maybe Francesco looked into this before, but all the emojis we have so far are Unicode code points.
> I'd also be happy to take this conversation to a mailing list or
> somewhere else more appropriate if there is anywhere.
We're just a tiny team, there's no dedicated mailing list. We can subscribe people as needed to this question, though.
Revision history for this message
|
#3 |
I found file://
Revision history for this message
|
#4 |
> I found file://
That one is very outdated, unfortunately, don't look at it too closely. Francesco, if you happen to have anything more recent, please chime in.
> GSETTINGS environment variable which will let me create a separate gsettings schema
Right, GSETTINGS_
There's the keyfile backend for gsettings too. That might actually make something like onboard --custom-
> Am I right here, or is there some way to set where onboard looks for its images?
I believe there's no good way. Perhaps with the layout directory being the current directory. Otherwise it's either system or user folder. It should look relative to the layout folder too, I agree, absolute paths for --layout don't fully make sense otherwise. I'll look into that.
Revision history for this message
|
#5 |
Thank you for the help so far!
New update: since the emoji keyboard isn't user-customisable and so should not inherit onboard user settings, I can pass both GSETTINGS_
So I'm now in a position to do everything I want to, and I'm trying to work out the best way to write a layout. I think I've understood most of it, but I have a couple of questions about the layout XML, based on reading file://
1. there's a comment saying " the rows of keys on the Onboard keyboard are counted bottom to top starting with 1 ", but I don't understand why their order in the XML file matters, because each key specifically identifies an SVG id to define where it's placed. So, can the keys in the XML be in any order?
2. what does the group attribute mean, on <key>?
3. Is the id "layer0.like_rtrn" magic in some way, meaning "switch the display to layer0?"
4. How does, for example, <key_template button="true" id="layer1" label="⅙⁺₉" tooltip="Sub-, Superscripts; Fractions"/> know that it's a button to switch to a panel defined as <panel filename=
Revision history for this message
|
#6 |
You're welcome. Right, XDG_DATA_HOME, I should have remembered, good find.
1. This order of key rows/columns is just a convention inherited from the very first of Onboard's layouts. For children of panels, the actual order isn't supposed to be important, with the exception perhaps of items with the layer attribute, I'll explain below.
It's different for children of boxes. Those are inserted in order of appearance in the layout file and end up top to bottom or left to right, depending on the orientation of the box.
2. "group" is the size group. All keys within the same group get the same font size for their labels. Behind the scenes, labels are stretched to just fit into their respective keys, then the one key with minimum font size determines the font size of the whole group. In other words, If you set the label of any key to some long string, all keys' labels of the same group would shrink.
3. I'll split this, see below for the layer mechanics.
"layer0.like_rtrn" has two id's rolled into one. The main id, aka key_id is "layer0". This is how keys are referred to throughout Onboard. For certain keys, mainly buttons (button="true"), that id determines their function too. There's a class for each "button" in Keyboard.py.
The whole thing "layer0.like_rtrn" is considered to be the theme_id. Everything after and including the dot is optional. It is used to special case certain keys in certain color scheme files. Elsewhere the key is still recognized as simply "layer0".
Keys with the same function can and do move around between layouts. Sometimes color schemes that work well with one layout cause problems with others. The theme_id allows to override colors in those circumstances.
From my notes:
Use theme ids only where you really have to, they add a lot of complexity to layouts and color themes.
The theme_id should not reference layouts or themes directly. Names can change easily when layouts or themes are copied. Best describe the relative location or relation with surrounding keys (".like_rtrn" = same color as the return key).
3. + 4. layer0..n are kinda magic, yes. Those keys do switch layers and the id determines which layer they switch to. Which layer that happens to be is given by order of appearance of items with set "layer" attribute. Order of appearance means with depth-first traversal of the layout tree, though often all items with layer attribute end up to be siblings under a single panel.
The "layer0" button controls the first item with "layer=", "layer1" the second, and so on. If the same layer is specified for multiple layout items, no matter where in the tree, all became part of the same layer.
Revision history for this message
|
#7 |
Perhaps I should explain what I want to do, and you might be able to give some pointers; the above is really helpful, but I think I'm mostly getting confused by what a button is and so on :)
There are 5 classes of emoji (nature, places, smileys, objects, and other). Each of the classes has a whole bunch of characters in it; in particular, there are normally about 200 in each, which is way more than will sensibly fit on one keyboard. So, what I think I'd like is a layout with a standard 40 keys on it, with:
5 of the keys, which are the same on every panel, are used to switch between emoji types -- so there's one key for "nature", one for "places", etc.
1 of the keys is a 1/5, 2/5, 3/5 etc key, which switches between different subsets of an emoji type
The remaining 34 keys are that subset of the 200 emoji.
A lot of the button=true stuff seems to make a button act like a modifier key -- that is, you press it, it switches the keyboard to have different characters, and then pressing one of the different characters enters it and then switches the keyboard back to its default state. I don't want that for this example.
To explain in a bit more detail, imagine a simplified 9-button keyboard where there are three types of characters, letters, numbers, and special. So we start on "page 1" of "letters", which looks like
[A] [0] [!]
[a] [b] [c]
[d] [e] [1/6]
from here, pressing [1/6] would change to
[A] [0] [!]
[f] [g] [h]
[i] [j] [2/6]
etc. Pressing [0] (at any point!) would switch to the "numbers" keyboard:
[A] [0] [!]
[1] [2] [3]
[4] [5] [1/2]
and again, pressing [1/2] here would switch to "numbers keyboard 2/2" which has the next set of numbers on it. Importantly, though, we stay in numbers mode; that is, the top row [A] [0] [!] set the "mode" of the keyboard permanently; they don't set it only for the next character choice and then switch back.
Is what I describe doable? (Again, thank you for the help so far!)
Revision history for this message
|
#8 |
A "button" is basically any key you wouldn't find on a physical keyboard.
Check out the Phone layout, I believe that one does something closely to what you describe. There are two nested levels of layers. The outer level has the alpha and numbers layers. That would correspond to your [A] [0] [!] row. The numbers layer then has the 1/3 button that switches to 2/3 syms and 3/3 emoji.
You can add more top level layers that lead to other 1/3 or 1/6 buttons, there's no hard limit for their number, though with 5*6=30 layers we might run into trouble with details here and there, layer background colors in color schemes come to mind.
Another problem is that layouts have no actual concept for nesting layers. Onboard still sees them as one flat list of layers. Phone has some glitches with highlighting the right layer button because of that. I'll have to work on that again.
Switching back to the first layer can be turned off for arbitrary sub-trees
with unlatch_
Revision history for this message
|
#9 |
Aaaaaaaaah, *that's* what unlatch_layer does :) Thank you! OK, I'll give all this a try...
Revision history for this message
|
#10 |
OK, the thing I think I'm not quite following is this:
How do I make a particular <key> mean "switch to layer 3"? The only way I've found so far is by doing <key id="layer3">. But if I do that, then that also dictates where that key should appear in the layout, because it appears in the SVG rect with id="layer3". That can't be right, surely?
To explain my confusion, let's look at the miniature "example" keyboard, above.
[A] [0] [!]
[a] [b] [c]
[d] [e] [1/6]
Layer 0 is this layer, showing letters a-e. Layer 1 is the second letters layer, showing letters f-j. So the xml would look roughly like the below, which defines layer 0 (letters a-e) and layer 1 (letters f-j). Let's imagine that there are only those two letter layers.
<box>
<!-- layer 0, letters a-e -->
<panel>
<key id="layer0" label="A"/>
<key id="layer2" label="0"/>
<key id="layer4" label="!"/>
<key id="row2col1" label="a" char="a"/>
<key id="row2col2" label="b" char="b"/>
<key id="row2col3" label="c" char="c"/>
<key id="row3col1" label="d" char="d"/>
<key id="row3col2" label="e" char="e"/>
<key id="layer1" label="1/2"/> <!-- this has id=layer1 so that it switches the keyboard to show layer 1 -->
</panel>
<!-- layer 1, letters f-j -->
<panel>
<key id="layer0" label="A"/>
<key id="layer2" label="0"/>
<key id="layer4" label="!"/>
<key id="row2col1" label="f" char="f"/>
<key id="row2col2" label="g" char="g"/>
<key id="row2col3" label="h" char="h"/>
<key id="row3col1" label="i" char="i"/>
<key id="row3col2" label="j" char="j"/>
<key id="layer0" label="2/2"/> <!-- We want to switch back to layer 0 here, but... how? we already have an id=layer0 ! -->
</panel>
</box>
It feels like the id attribute on a key is being overloaded; it means both "where it appears in the svg" AND "which layer to switch to when this is pressed". I suspect I have misunderstood something here, but I don't know what! I've been looking at the Phone layout as suggested, but that's confusing me; in particular, it feels like I ought to be able to use the same SVG layout for each of the panels, but I can't do that because the 1/2 and 2/2 keys appear in the same place in the layout, but to make them switch to different places they need different IDs. Is there no way to separate "where this key appears" and "what this key does"; that is, to say <key id="row2col2" action=
Revision history for this message
|
#11 |
> How do I make a particular <key> mean "switch to layer 3"? The only
> way I've found so far is by doing <key id="layer3">.
That's it, a key with id="layer3" switches to the fourth layer.
> But if I do that, then that also dictates where that key should appear in the layout,
> because it appears in the SVG rect with id="layer3". That can't be right, surely?
It works well, because the vast majority of keys appear only once per layer and since there is usually a dedicated svg file per layer there are no ambiguities.
Exceptions exist, though. Phone has two hide buttons in Phone-Alpha.svg for example. One is defined in Phone.onboard:
<key id="hide" svg_id="hide.popup" ...>
the other in word_suggestion
<key group='wsbutton' id='hide.wordlist' svg_id=
The svg_id links to the right rectangle in the svg. That id can be any string, I just find that <key_id>.<context> format helpful when working on the svg file.
> <key id="layer0" label="2/2"/> <!-- We want to switch back to layer 0 here,
> but... how? we already have an id=layer0 ! -->
Both switch to layer 0. There's no requirement to have only a single button of any type.
> It feels like the id attribute on a key is being overloaded; it means both
> "where it appears in the svg" AND "which layer to switch to when this is pressed".
Maybe it is, but it seemed to worked alright for what we needed so far. Backwards compatibility to old layout files and trying not to throw out the baby with the bath water played a role here too.
> it feels like I ought to be able to use the same SVG layout for each of the panels
OK, I see. We didn't have this problem before, because layers usually look quite different. It felt natural to describe one layer per svg file.
> Is there no way to separate "where this key appears" and "what this key does"
There is, though it used to be the exception:
id= is what the key does, svg_id= is where it appears and theme_id= is how it looks.
Again, any string is fine for the svg_id, as long it uniquely addresses a drawing object in the svg.
Revision history for this message
|
#12 |
Aha, svg_id and id should solve my problem perfectly! Thank you :)
(Note: id is supposed to be unique, isn't it? Although onboard files don't have a DTD.)
Revision history for this message
|
#13 |
OK, I'm really close to working this all out now. One more question. With the .onboard file below, I see a strange effect; when I press the 1/2 button on panel 0, we correctly switch to panel 1, but the 1/2 button doesn't change to the 2/2 button which is present in panel 1; instead, the 1/2 button stays a 1/2 button but gets disabled! I don't understand why this is happening...!
(The associated svg layout file has rects laid out in a grid; top left rect is id x0y0, the one to its right is x1y0, etc.)
<?xml version="1.0" ?>
<!---
Copyright © 2014, Stuart Langridge
This Emoji keyboard is based on Whiteboard.onboard by Johannes Almer, part of Onboard.
Onboard is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
Onboard is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://
-->
<keyboard author="Stuart Langridge" description="A complete set of emoji." format="3.1" id="emoji" section=
<key_template id='layer0' button='true'/>
<key_template id='layer1' button='true'/>
<!-- box containing all the keys and buttons -->
<!-- the rows of keys on the Onboard keyboard are counted bottom to top starting with 1 -->
<box border="1" orientation=
<panel>
<panel filename=
<!-- row 4 -->
<key char="a" group="emojichar" id="x0y1" label="a"/>
<key char="b" group="emojichar" id="x1y1" label="b"/>
<key char="c" group="emojichar" id="x2y1" label="c"/>
<key char="d" group="emojichar" id="x3y1" label="d"/>
<key char="e" group="emojichar" id="x4y1" label="e"/>
<key char="f" group="emojichar" id="x5y1" label="f"/>
<key char="g" group="emojichar" id="x6y1" label="g"/>
<key group="toprow" id="layer0.
<key group="toprow" id="layer1.
</panel>
<panel filename=
<!-- row 4 -->
<key char="A" group="emojichar" id="x0y1" label="A"/>
<key char="B" group="emojichar" id="x1y1" label="B"/>
<key char="C" group="emojichar" id="x2y1" label="C"/>
<key char="D" group="emojichar" id="x3y1" label="D"/>
<key char="E" group="emojichar" id="x4y1" label="E"/>
<key char="F" group="emojichar" id="x5y1" label="F"/>
<key char="G" group="emojichar" id="x6y1" label="G"/>
<!-- row 3 -->
<key group="toprow" id="layer0.
<key group="toprow" id="layer0.
</panel>
</panel>
</box>
</keyboard>
Revision history for this message
|
#14 |
Yeah, this looks like a bug. The second key with the same id is swallowed by the keyboard layout check. You can do something like
<key group="
<key group="
That selects the first key definition if the systems current keyboard layout is azerty (french), and the second definition if the current layout is anything else, e.g. qwerty.
Me thinks It should at least do this matching only when the layout attribute was defined at least once. Your layout works with that fix, but I may have to restrict it further.
In the meantime change the second id slightly. With something like layer0.like_rtrn2 it should load.
Revision history for this message
|
#15 |
Aha. A different .trailingpart on the ID. Thank you.
Revision history for this message
|
#16 |
Aha. A different .trailingpart on the ID. Thank you.
Revision history for this message
|
#17 |
You're welcome. It's fixed in trunk too. The image loading issue too.
If you want to get the latest changes, here's how:
sudo apt-get build-dep onboard
bzr branch lp:onboard
cd onboard
debuild binary
sudo dpkg -i ../onboard*.deb
There'll be a new release soon (finally), but I'm still testing. If you find anything weird let me know.
Revision history for this message
|
#18 |
I'm still having issues, I think. In particular, below is a .onboard file for a tiny keyboard which has three categories, Letters, Numbers, and Special; three buttons one for each category to switch between the categories, and one button which switches between pages *in* a category and is labelled 1/3 or 2/3 etc. What happens is, the "Let" button does what it's supposed to, which is to switch to the first Letters page and that's it. But the Num and Spe buttons seem to act like a "Shift" key -- when you press them, they stay pressed, and double-pressing them locks them on in red. But I'm not declaring the Let button any differently than the Num and Spe buttons! I am confused, still :(
<?xml version="1.0" ?>
<!---
Copyright © 2014, Stuart Langridge
This Emoji keyboard is based on Whiteboard.onboard by Johannes Almer, part of Onboard.
Onboard is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
Onboard is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://
-->
<keyboard author="Stuart Langridge" description="A complete set of emoji." format="3.1" id="emoji" section=
<key_template id='layer0' button='true'/>
<key_template id='layer1' button='true'/>
<key_template id='layer2' button='true'/>
<key_template id='layer3' button='true'/>
<key_template id='layer4' button='true'/>
<key_template id='layer5' button='true'/>
<key_template id='layer6' button='true'/>
<key_template id='layer7' button='true'/>
<key_template id='layer8' button='true'/>
<!-- box containing all the keys and buttons -->
<!-- the rows of keys on the Onboard keyboard are counted bottom to top starting with 1 -->
<box border="1" orientation=
<panel>
<panel filename=
<key char="a" group="emojichar" id="x0y1" label="a"/>
<key char="b" group="emojichar" id="x1y1" label="b"/>
<key char="c" group="emojichar" id="x2y1" label="c"/>
<key group="toprow" id="layer0.
<key group="toprow" id="layer3.
<key group="toprow" id="layer6.
<key group="toprow" id="layer1.
</panel>
<panel filename=
<key char="a" group="emojichar" id="x0y1" label="d"/>
<key char="b" group="emojichar" id="x1y1" label="e"/>
<key char="c" group="emojichar" id="x2y1" label="f"/>
<key group="toprow" id="layer0.
<key group="toprow" id="layer3.
<key group="toprow" id="layer6.
<key group="toprow" id="layer2.
</panel>
<panel filename=
<key char="a" group="emojichar" id="x0y1" label="g"/>
<key char="b" group="emojichar" id="x1y1" label="h"/>
<key char="c" group="emojichar" id="x2y1" label="i"/>
<key group="toprow" id="layer0.
<key group="toprow" id="layer3.
<key group="toprow" id="layer6.
<key group="toprow" id="layer0.
</panel>
<panel filename=
<key char="a" group="emojichar" id="x0y1" label="1"/>
<key char="b" group="emojichar" id="x1y1" label="2"/>
<key char="c" group="emojichar" id="x2y1" label="3"/>
<key group="toprow" id="layer0.
<key group="toprow" id="layer3.
<key group="toprow" id="layer6.
<key group="toprow" id="layer4.
</panel>
<panel filename=
<key char="a" group="emojichar" id="x0y1" label="4"/>
<key char="b" group="emojichar" id="x1y1" label="5"/>
<key char="c" group="emojichar" id="x2y1" label="6"/>
<key group="toprow" id="layer0.
<key group="toprow" id="layer3.
<key group="toprow" id="layer6.
<key group="toprow" id="layer5.
</panel>
<panel filename=
<key char="a" group="emojichar" id="x0y1" label="7"/>
<key char="b" group="emojichar" id="x1y1" label="8"/>
<key char="c" group="emojichar" id="x2y1" label="9"/>
<key group="toprow" id="layer0.
<key group="toprow" id="layer3.
<key group="toprow" id="layer6.
<key group="toprow" id="layer3.
</panel>
<panel filename=
<key char="a" group="emojichar" id="x0y1" label="!"/>
<key char="b" group="emojichar" id="x1y1" label="$"/>
<key char="c" group="emojichar" id="x2y1" label="%"/>
<key group="toprow" id="layer0.
<key group="toprow" id="layer3.
<key group="toprow" id="layer6.
<key group="toprow" id="layer7.
</panel>
<panel filename=
<key char="a" group="emojichar" id="x0y1" label="^"/>
<key char="b" group="emojichar" id="x1y1" label="*"/>
<key char="c" group="emojichar" id="x2y1" label="@"/>
<key group="toprow" id="layer0.
<key group="toprow" id="layer3.
<key group="toprow" id="layer6.
<key group="toprow" id="layer8.
</panel>
<panel filename=
<key char="a" group="emojichar" id="x0y1" label=":"/>
<key char="b" group="emojichar" id="x1y1" label=";"/>
<key char="c" group="emojichar" id="x2y1" label="~"/>
<key group="toprow" id="layer0.
<key group="toprow" id="layer3.
<key group="toprow" id="layer6.
<key group="toprow" id="layer6.
</panel>
</panel>
</box>
</keyboard>
Revision history for this message
|
#19 |
All layer buttons cycle through inactive -> latched -> locked states by default. The idea is to a) indicate which layer is active and b) let the user decide if he just needs that layer to click a single key (latched) or to click multiple keys.
That default behavior can be changed in Preferences-
The layer0 button is an exception in that it is hard wired to never show latched or locked states. It's usually clear anyway when the first layer is active.
Here's what I think I can do:
1) I guess the hard wiring of layer0 button should move to the key definition. That way you could disable showing latched and locked state per key from the layouts (they would still act latched though, you just don't see it)
2) Modifier behavior from preferences could move to a key attribute as well and I should be able to add an option to stop the cycling back to layer 0.
How does that sound? Meanwhile you can keep working, the keyboard is usable anyway.
Revision history for this message
|
#20 |
I went ahead and added those changes to trunk. No more hard-coded behavior for layer0 and keys can be made to not become latched or locked. All you have to do is to set the layout format to 3.2 and add sticky_
You can add this to key_templates too if you only want to see it once per layer key. I've done this for testing with your layout and tried a couple other changes to keep it manageable when the number of layers increases. I'll attach it to the initial bug report. We can't attach stuff to questions, unfortunately.
https:/
You'll need the latest changes from trunk for this to work.
Revision history for this message
|
#21 |
I've made emojy layout for OnBoard https:/
Can you help with this problem?
Provide an answer of your own, or ask Stuart Langridge for more information if necessary.