You are not logged in.
I often use ibus to type in other languages. Especially when writing emails, I tend to edit a lot as I go along. The trouble is that in many applications when I click on the screen to move the cursor somewhere, if I'm using ibus then the last character I typed simply disappears.
For example, in mate-terminal, thunderbird, and pluma, if I type this (for example):
ho ho ho
Then click somewhere on the screen, the text turns into this:
ho ho h
Have any of you found a way to type in other languages--with or without ibus--without being affected by this?
I have considered using a keyboard layout with dead keys as a workaround, but I don't like having to type the diacritic before the letter.
--------------
My setup:
- Devuan Jessie with MATE
- ibus 1.5.9-1
- ibus packages installed: ibus, ibus-gtk, ibus-gtk3, ibus-m17n, ibus-qt4
Last edited by GNUser (2017-10-08 01:16:02)
Offline
I couldn't find anything suitable, so I rolled my own alternative to ibus. It's a simple bash script that allows typing diacritic either before or after the letter, user's choice. The script does not use "preedit text", so no characters ever disappear.
Getting the dependencies:
sudo apt-get install xvkbd python3 && sudo pip3 install pynput
You also need to install yad, which is not in the Devuan Jessie repositories but is easy to find (e.g., by clicking on your architecture at the bottom of this page).
pynput didn't work for me at first because one of its dependencies, the "six" module, was outdated. So, to be safe:
sudo pip3 install --upgrade six
Well, here's the script. It should "just work" once you have all the dependencies. You only need to alter it if you want to add or change the special characters section.
#!/bin/bash
# International keyboard (alternative to ibus for x11)
# Author: Bruno "GNUser" Dantas
# License: GPLv3
# Dependencies:
# sudo apt-get install xvkbd python3 yad
# sudo pip3 install pynput
# Usage:
# - Change the triggers and unicode sequences in "watch_for_triggers" function to suit your needs
# - Run this script as regular user to turn on the international keyboard
# - Stop the script--via taskbar icon or, if running in terminal, Control+c--to clean up without a trace
main()
{
create_pipe
create_keylogger # writes to pipe
create_taskbar_icon
watch_for_triggers # reads from pipe, replaces user-defined character combinations with unicode characters
}
create_pipe()
{
pipe=/tmp/international
rm -f $pipe
mkfifo $pipe
exec 3<>$pipe
}
create_keylogger()
{
# to troubleshoot the keylogger:
# 1. copy the python code below into a file foo
# 2. comment out the three fifo lines, uncomment the print line in log_it function
# 3. in a terminal: python3 /path/to/foo
# 4. type stuff outside the terminal and watch terminal
echo "
from pynput import keyboard
from pynput import mouse
import os
fifo_write = open('$pipe', 'w')
def log_it(output):
fifo_write.write(output + '\n')
fifo_write.flush()
#print(output)
# get initial capslock state
exit_code = os.system('''xset q 2>/dev/null | grep -q -E 'Caps Lock: +on' ''')
if exit_code == 0:
capslock_in_effect = True
else:
capslock_in_effect = False
# this function runs each time a key is pressed:
def on_press(key):
global capslock_in_effect
output = str(key)
if output == 'Key.caps_lock': # if capslock pressed, toggle capslock state
capslock_in_effect = not capslock_in_effect
if not output.startswith('Key'): # special keys start with 'Key' and can be logged as-is
output = output[1:-1] # remove quotes around character
if capslock_in_effect:
output = output.swapcase()
if not output.startswith('Key.shift'): # don't log shift keys (e.g., while loop expects a~ not aKey.shift~)
log_it(output)
# this function runs each time a mouse button is pressed:
def on_click(x, y, button, pressed):
button = str(button)
if pressed and button == 'Button.left':
log_it('Key.mousebutton_left')
# start listening
with mouse.Listener(on_click=on_click) as listener:
with keyboard.Listener(on_press=on_press) as listener:
listener.join()
" >/tmp/tiny-keylogger
python3 /tmp/tiny-keylogger &
}
echo "$(basename $0)" >/tmp/scriptname # so cleanup function can find this script's name when called from yad
cleanup()
{
echo "Cleaning up..."
pkill -f International # kill taskbar icon
pkill -f tiny-keylogger # kill keylogger
pkill -KILL "$(cat /tmp/scriptname)" # kill this script
}
trap cleanup EXIT HUP TERM INT
create_taskbar_icon()
{
export -f cleanup
yad --notification --image='accessories-character-map' --text='International Keyboard' \
--no-middle --menu="Stop!bash -c cleanup" --command='' &
}
replace()
{
xvkbd -xsendevent -text "\b\b\[U$1]" # send two backspaces then desired unicode character
}
watch_for_triggers()
{
# endless loop (it reads from a fifo pipe, so never encounters EOF)
while read current_char; do
echo "${previous_char}${current_char}" # for debugging while running in terminal
case "${previous_char}${current_char}" in
# Portuguese
'A`') replace 00C0;;
'a`') replace 00E0;;
"A'") replace 00C1;;
"a'") replace 00E1;;
'A^') replace 00C2;;
'a^') replace 00E2;;
'A~') replace 00C3;;
'a~') replace 00E3;;
"E'") replace 00C9;;
"e'") replace 00E9;;
'E^') replace 00CA;;
'e^') replace 00EA;;
"I'") replace 00CD;;
"i'") replace 00ED;;
'O`') replace 00D2;;
'o`') replace 00F2;;
"O'") replace 00D3;;
"o'") replace 00F3;;
'O^') replace 00D4;;
'o^') replace 00F4;;
'O~') replace 00D5;;
'o~') replace 00F5;;
"U'") replace 00DA;;
"u'") replace 00FA;;
'U;') replace 00DC;;
'u;') replace 00FC;;
'C;') replace 00C7;;
'c;') replace 00E7;;
# Esperanto
'Cx') replace 0108;;
'CX') replace 0108;;
'cx') replace 0109;;
'Gx') replace 011C;;
'GX') replace 011C;;
'gx') replace 011D;;
'Hx') replace 0124;;
'HX') replace 0124;;
'hx') replace 0125;;
'Jx') replace 0134;;
'JX') replace 0134;;
'jx') replace 0135;;
'Sx') replace 015C;;
'SX') replace 015C;;
'sx') replace 015D;;
'Ux') replace 016C;;
'UX') replace 016C;;
'ux') replace 016D;;
esac
previous_char=$current_char
done <&3
}
main
Last edited by GNUser (2017-10-22 01:36:19)
Offline