[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Using .XCompose



I have conducted an experiment with the following ~/.XCompose file,
and tried to document it relatively thoroughly below.

It is my hope that OP and/or others may find some of this
(unfortunately rather voluminous) information helpful or at least
somewhat interesting, though it is difficult for me to know precisely
whether or how they will be able to use it.

Of course, to interpret any meaning from the results presented here,
the context/environment in which the test was conducted matters
greatly. Details about my system are attached, in the file
"system_synposis_bbhuit.txt". (In case that attachment gets lost
somehow, I will simply post the same information in a follow-up
message.)


%% THREE XCOMPOSE RULES to test

$ cat ~/.XCompose
include "%L"
<U0D19>   : "ങ്ങ" # Ajith's auto-geminate rule, (U0D19) => (U0D19) (U0D4D) (U0D19)
<Multi_key> <s> <x> : "✄"  # (U2704) white scissors, h/t David Wright
<Z>                 : "ARGA WARGA IN THE DARGA instead of Z"

I started an X Window session, and then in a few applications I tested
whether the three custom rules above were effective.

For the tests, I used a couple of terminal emulators for X (xterm and
mlterm) and a couple of graphical web browsers (firefox-esr and
qutebrowser):

davidson@bbhuit:0 ~$ dpkg-query -l --no-pager xterm mlterm firefox-esr qutebrowser Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name           Version              Architecture Description
+++-==============-====================-============-============================================================
ii  firefox-esr    68.10.0esr-1~deb10u1 amd64        Mozilla Firefox web browser - Extended Support Release (ESR)
ii  mlterm         3.8.6-2              amd64        MultiLingual TERMinal
ii  qutebrowser    1.6.1-2              all          Keyboard-driven, vim-like browser based on PyQt5
ii  xterm          344-1                amd64        X terminal emulator


%% ARGA WARGA

The third rule ('Z' => "ARGA WARGA...Z") was easiest to test:

 1. Open the application. (If necessary, navigate to a text entry field.)
 2. (While under "us" keyboard layout) strike the key labeled "Z" on my
    standard US laptop keyboard
 3. Observe whether

      ARGA WARGA IN THE DARGA instead of Z

    is printed.

The two terminal emulators passed this test. The graphical web browsers failed
in an interesting way. Instead of displaying

     ARGA WARGA IN THE DARGA instead of Z

in the text entry field, they displayed just

     A

Also, upon starting up (but only on the first start-up since
installation of the three rules in ~/.XCompose) , firefox-esr issued
the following errors, which appear to be explanatory:

 (firefox-esr:11619): Gtk-WARNING **: 16:27:05.630: GTK+ supports to output one char only:
 "ങ്ങ" # Ajith's auto-geminate rule, (U0D19) => (U0D19) (U0D4D) (U0D19):
 <U0D19>   : "ങ്ങ" # Ajith's auto-geminate rule, (U0D19) => (U0D19) (U0D4D) (U0D19)

 (firefox-esr:11619): Gtk-WARNING **: 16:27:05.630: GTK+ supports to output one char only:
 "ARGA WARGA IN THE DARGA instead of Z":
 <Z>                 : "ARGA WARGA IN THE DARGA instead of Z"

(I have split each error into three separate lines above to improve legibility.)

Although both web browsers performed identically, failing in the same
way, only firefox-esr issued this explanatory error message.

Unlike firefox-esr, qutebrowser does not use libgtk (do "apt-cache
depends qutebrowser" to see its dependencies), but both graphical web
browsers failed this test identically.


%% WHITE SCISSORS

The second rule (David Wright's white scissors rule) was tested as
follows:

 1. Open the application. (If necessary, navigate to a text entry field.)

 2. Under "us" keyboard layout, hold down the compose key. Strike the
    key labeled "S" on my standard US laptop keyboard. Release the
    compose key. Strike the key labeled "X".

 3. Observe whether

        ✄

   is printed.

All four applications passed this test. (I should mention that I have
noticed that sometimes when I use the compose key, it seems to get
ignored on the first try. It happens frequently enough that it has
become second nature to me to simply backspace and try again, when
this happens. Whether this is human error, or something else, is not
something I have spent time investigating. Whatever the cause, it does
not trouble me more than other commonly self-inflicted typos do.)

NB: If, like me, you occasionally confuse the Ctrl key with the
compose key, then keep in mind that when testing this rule in a
terminal emulator, that typing Ctrl-s (presumably by accident) may
well stop the terminal from echoing entered characters to the display
until you enter Ctrl-q to resume normal terminal operation. (That is
to say, Ctrl-s doesn't "break your keyboard", it only pauses your
terminal's printout to the display until you resume it with Ctrl-q.)


%% AUTO-GEMINATION

Finally. The first rule in the ~/.XCompose file above

  <U0D19>   : "ങ്ങ" # Ajith's auto-geminate rule, (U0D19) => (U0D19) (U0D4D) (U0D19)

I tested as follows (after installing the "Lohit TrueType font for
Malayalam Language" package, fonts-lohit-mlym):

 1. I opened an xterm (uxterm, actually) and issued the following
    command to alter the X Window display keymap:

    $ setxkbmap -display $DISPLAY -layout us,in -variant ,mal

    This configures --as my alternate keyboard layout in the current X
    display-- the variant "mal" (malayalam) of the "in" (indian)
    keyboard layout, so that switching to the alternate layout will
    permit me to enter malayalam characters.

    On my system, the longer command below is equivalent to the
    command above, because the setting for XKBOPTIONS that the longer
    command specifies (with the -option flag), is already set as a
    default in my /etc/default/keyboard (see attached system synopsis
    for details of this):

    $ setxkbmap -display $DISPLAY -layout us,in -variant ,mal -option grp:caps_toggle

    I mention this equivalence because the longer command makes
    explicit whick key permits me to switch from my main "us" keyboard
    layout to the alternate layout "in.mal" (and back again).

    NB: In these commands, make note of the commas. In particular the
    comma in ",mal" is not a typo.

    NBB: I believe at least one other poster here correctly urged
    caution when experimenting with setxkbmap. You can render your
    keyboard non-functional in the X session. Have a plan for shutting
    down the X session without the use of your keyboard.

 2. To test applications besides xterm itself, I launched the
    application from the xterm just opened. (When testing xterm, I
    skipped this step.)

      $ mlterm # or firefox-esr or qutebrowser

 3. If necessary, navigate to a text entry field.

 4. Strike the capslock key to switch to the alternate keyboard
    layout configured in step 1.

 5. Hold down the shift key. Strike the key labeled "U" on my standard
    US laptop keyboard.

 6. Observe whether

       ങ്ങ

    is printed, according to the custom auto-geminate rule in ~/.XCompose.

The terminal emulators passed this test. The graphical web browsers
failed, instead printing only

       ങ

The error message from firefox-esr above seems to suggest why that is.

Another thing I think is interesting is that while the terminal
emulators did pass this test and the browsers failed, it is only the
graphical web browsers which seem to transform/meld a typed sequence
of

  "ങ" followed by "്" followed by "ങ"

into what appears (to my utterly ignorant eye) to be a "freshly
synthetic" glyph. (That three-character sequence is typed, on my
standard US laptop keyboard under the "in.mal" keyboard layout, by
striking the "U" key while holding down shift, then striking the "D"
key (unshifted), and then again striking the "U" key while holding
down shift.)

Finally, in case it is of interest to anyone, in the attached file
"xev_output_annotated.txt" is some xev(1) output with commentary that
gives a detailed close-up of performing steps 4 through 6 in an
xterm. (As with the system synopsis, if it happens to "get lost" I'll
just post it the message body of a follow-up.)
This is a synopsis of my (buster) system, which I have set up to make
it relatively simple to switch between english, french, and russian in
linux virtual terminals.

$ uname -a
Linux bbhuit 4.19.0-9-amd64 #1 SMP Debian 4.19.118-2+deb10u1 (2020-06-07) x86_64 GNU/Linux

%% DISPLAY (on the console)

My default virtual consoles (ttys) display english and french text
pretty well:

$ cat /etc/default/console-setup
# CONFIGURATION FILE FOR SETUPCON
# Consult the console-setup(5) manual page
# See also setupcon(1)
ACTIVE_CONSOLES="/dev/tty[1-6]"
CHARMAP="UTF-8"
CODESET="Lat15"
FONTFACE="Terminus"
FONTSIZE="12x24"
VIDEOMODE=


Supplementing this, I have a user configuration which I can deploy on
a case-by-case basis in a given tty with "setupcon --current-tty -f
russian" so that russian text is displayed well enough, at the cost of
losing a few latin glyphs:

$ cat ~/.console-setup.russian
ACTIVE_CONSOLES="/dev/tty[1-6]"
CHARMAP="UTF-8"
CODESET="CyrSlav"
FONTFACE="Terminus"
FONTSIZE="12x24"
VIDEOMODE=


%% KEYBOARD (on the console, and in X)

My default keyboard setup (below) allows at the console entry of most
latin characters I will ever care to type (at least in french or
english) on a bog-standard US laptop keyboard using "us" layout, using
the "menu" key as the compose key. ("The compose key", set by the
second element in XKBOPTIONS below, is the referent of the keysym
<Multi_key> in /usr/share/X11/locale/$LANG/Compose.)

The capslock key toggles to-and-from russian "ru" keyboard layout, so
that I can type cyrillic characters FOR ME TO ENJOY. By the way, shift
+ capslock in both layouts performs THE ORIGINAL FUNCTION OF CAPSLOCK,
WHICH IS SHOUTING.

In an X Window display, many more characters become available, both
for entry and display.

$ cat /etc/default/keyboard
# KEYBOARD CONFIGURATION FILE
# Consult the keyboard(5) manual page
# See also setxkbmap(1)
XKBMODEL="pc101"
XKBLAYOUT="us,ru"
XKBVARIANT=","
XKBOPTIONS="grp:caps_toggle,compose:menu"
BACKSPACE="guess"


%% BEYOND THE CONSOLE

When an X Window display is needed, I run from a tty:

$ startx

I have no ~/.xinitrc file. (If I had one, startx would use it.) My
~/.xsession file is below. It is meant to start a window manager,
namely ratpoison:

$ cat ~/.xsession
#!/bin/sh
exec ratpoison -f ${HOME}/.ratpoisonrc

I believe it gets executed by one of the scripts in the
/etc/X11/Xsession.d/ directory, as a consequence of running startx.
It is executable by owner:

$ ls -l ~/.xsession
-rwxr--r-- 1 davidson davidson 49 juil.  9 02:44 /home/davidson/.xsession

The following line in my window manager configuration file sets up a
shortcut key for launching lxterm, which is a locale-sensitive wrapper
around xterm, the venerable terminal emulator for the X Window
System. Since I use UTF-8 locales, it launches uxterm (xterm wrapped
for that sort of locale).

$ head -n 1 ~/.ratpoisonrc
bind c exec lxterm +sb -bg black -fg steelblue1 -selbg gray20
$ man xev
[...]
DESCRIPTION

  Xev creates a window and then asks the X server to send it events
  whenever anything happens to the window (such as it being moved,
  resized, typed in, clicked in, etc.).  You can also attach it to an
  existing window.  It is useful for seeing what causes events to
  occur and to display the information that they contain; it is
  essentially a debugging and development tool, and should not be
  needed in normal usage.

This is the command I issued from within an xterm (uxterm, really) to
launch xev and attach it to that terminal's window.

$ xev -id $WINDOWID -event keyboard # I press enter, of course

# And here is the release of the enter key:

KeyRelease event, serial 18, synthetic NO, window 0x60000f,
    root 0x102, subw 0x0, time 76502401, (1362,764), root:(1364,766),
    state 0x0, keycode 36 (keysym 0xff0d, Return), same_screen YES,
    XLookupString gives 1 bytes: (0d) ""
    XFilterEvent returns: False

# Next, I strike the capslock key to enter the Malayalam keymap, "ml".
# The capslock key's keycode happens to be 66. This is a relatively
# low-level identifier, mechanical, relatively meaningless in itself,
# fixed by factual accident.
#
# Its keysym, under my configuration, is apparently <ISO_Next_Group>.
#
# A keysym is an identifier of somewhat higher abstraction than a
# keycode, and is meant to *mean* something. (I mean, just compare the
# two names to see this!)
#
# The following *three* records correspond to striking this key.
#
# NB: For some reason, each key struck seems to correspond to *three*
#     records in the xev output:
#
#     1. a KeyRelease event (kind of weird, but that's how it is).
#     2. a KeyPress event.
#     3. a KeyRelease event.

KeyRelease event, serial 21, synthetic NO, window 0x60000f,
    root 0x102, subw 0x0, time 76506392, (1362,764), root:(1364,766),
    state 0x0, keycode 66 (keysym 0xfe08, ISO_Next_Group), same_screen YES,
    XLookupString gives 0 bytes: 
    XFilterEvent returns: False

KeyPress event, serial 21, synthetic NO, window 0x60000f,
    root 0x102, subw 0x0, time 76506392, (1362,764), root:(1364,766),
    state 0x0, keycode 66 (keysym 0xfe08, ISO_Next_Group), same_screen YES,
    XLookupString gives 0 bytes: 
    XmbLookupString gives 0 bytes: 
    XFilterEvent returns: False

KeyRelease event, serial 21, synthetic NO, window 0x60000f,
    root 0x102, subw 0x0, time 76506480, (1362,764), root:(1364,766),
    state 0x2000, keycode 66 (keysym 0xfe08, ISO_Next_Group), same_screen YES,
    XLookupString gives 0 bytes: 
    XFilterEvent returns: False

# Next, I hold down a shift key (left shift, as it happens).
#
# NB: The following *two* records correspond to this. First a
# KeyRelease, then a KeyPress.

KeyRelease event, serial 21, synthetic NO, window 0x60000f,
    root 0x102, subw 0x0, time 76509510, (1362,764), root:(1364,766),
    state 0x2000, keycode 50 (keysym 0xffe1, Shift_L), same_screen YES,
    XLookupString gives 0 bytes: 
    XFilterEvent returns: False

KeyPress event, serial 21, synthetic NO, window 0x60000f,
    root 0x102, subw 0x0, time 76509510, (1362,764), root:(1364,766),
    state 0x2000, keycode 50 (keysym 0xffe1, Shift_L), same_screen YES,
    XLookupString gives 0 bytes: 
    XmbLookupString gives 0 bytes: 
    XFilterEvent returns: False

# Then, still holding down the shift key, I strike the key labeled "U"
# on my standard US laptop keyboard.
#
# NB: The next *four* records correspond to this action.
#
#       * The first two events are due to holding down the key labeled
#         "U" (KeyRelease event followed by KeyPress),
#
#       * followed by a third, MAGICALLY INTERPOLATED, KeyPress event
#         (presumably due to the relevant entry in ~/.XCompose),
#
#       * and wrapped up with the KeyRelease event corresponding to
#         releasing that "U" labeled key.

KeyRelease event, serial 21, synthetic NO, window 0x60000f,
    root 0x102, subw 0x0, time 76509907, (1362,764), root:(1364,766),
    state 0x2001, keycode 30 (keysym 0x1000d19, U0D19), same_screen YES,
    XLookupString gives 3 bytes: (e0 b4 99) "à´?"
    XFilterEvent returns: False

KeyPress event, serial 21, synthetic NO, window 0x60000f,
    root 0x102, subw 0x0, time 76509907, (1362,764), root:(1364,766),
    state 0x2001, keycode 30 (keysym 0x1000d19, U0D19), same_screen YES,
    XLookupString gives 3 bytes: (e0 b4 99) "à´?"
    XmbLookupString gives 3 bytes: (e0 b4 99) "à´?"
    XFilterEvent returns: True

# This one is THE MAGIC!

KeyPress event, serial 21, synthetic NO, window 0x60000f,
    root 0x102, subw 0x0, time 76509907, (1362,764), root:(1364,766),
    state 0x2001, keycode 0 (keysym 0x0, NoSymbol), same_screen YES,
    XLookupString gives 0 bytes: 
    XmbLookupString gives 9 bytes: (e0 b4 99 e0 b5 8d e0 b4 99) "���"
    XFilterEvent returns: False

KeyRelease event, serial 21, synthetic NO, window 0x60000f,
    root 0x102, subw 0x0, time 76509998, (1362,764), root:(1364,766),
    state 0x2001, keycode 30 (keysym 0x1000d19, U0D19), same_screen YES,
    XLookupString gives 3 bytes: (e0 b4 99) "à´?"
    XFilterEvent returns: False

# And now I release the shift key.

KeyRelease event, serial 21, synthetic NO, window 0x60000f,
    root 0x102, subw 0x0, time 76510083, (1362,764), root:(1364,766),
    state 0x2001, keycode 50 (keysym 0xffe1, Shift_L), same_screen YES,
    XLookupString gives 0 bytes: 
    XFilterEvent returns: False

# Having wrapped up my experiment (and happily observing the desired
# character echoed to the terminal), I strike the capslock key to
# return to a more familiar-to-me keymap. Three records, as per usual,
# correspond to this action: Release, Press, Release.

KeyRelease event, serial 21, synthetic NO, window 0x60000f,
    root 0x102, subw 0x0, time 76514882, (1362,764), root:(1364,766),
    state 0x2000, keycode 66 (keysym 0xfe08, ISO_Next_Group), same_screen YES,
    XLookupString gives 0 bytes: 
    XFilterEvent returns: False

KeyPress event, serial 21, synthetic NO, window 0x60000f,
    root 0x102, subw 0x0, time 76514882, (1362,764), root:(1364,766),
    state 0x2000, keycode 66 (keysym 0xfe08, ISO_Next_Group), same_screen YES,
    XLookupString gives 0 bytes: 
    XmbLookupString gives 0 bytes: 
    XFilterEvent returns: False

KeyRelease event, serial 21, synthetic NO, window 0x60000f,
    root 0x102, subw 0x0, time 76514968, (1362,764), root:(1364,766),
    state 0x0, keycode 66 (keysym 0xfe08, ISO_Next_Group), same_screen YES,
    XLookupString gives 0 bytes: 
    XFilterEvent returns: False

# Here I hold down the control key, as a preliminary step to entering
# Ctrl-c, to kill xev. Two events (Release followed by Press),
# correspond to this preliminary action. The victim of the killing
# strike --'c'-- has obviously failed to record its own assassination.

KeyRelease event, serial 21, synthetic NO, window 0x60000f,
    root 0x102, subw 0x0, time 76517083, (1362,764), root:(1364,766),
    state 0x0, keycode 37 (keysym 0xffe3, Control_L), same_screen YES,
    XLookupString gives 0 bytes: 
    XFilterEvent returns: False

KeyPress event, serial 21, synthetic NO, window 0x60000f,
    root 0x102, subw 0x0, time 76517083, (1362,764), root:(1364,766),
    state 0x0, keycode 37 (keysym 0xffe3, Control_L), same_screen YES,
    XLookupString gives 0 bytes: 
    XmbLookupString gives 0 bytes: 
    XFilterEvent returns: False

Reply to: