This commit allows to assign the `Shift+Tab` key binding to an action in
`Preferences>Keybindings`.
In GTK the Tab key can be modified by the Shift key. Such a key combination
has a special key value - `Gdk.KEY_ISO_Left_Tab`.
To allow it, `key = key_with_shift.keyval` was added to the code.
However, `Gdk.KEY_ISO_Left_Tab` key value is displayed as `Left Tab` in
`Preferences>Keybindings`, which is confusing as it is not obvious that it
corresponds to the `Shift+Tab` key combination. To make sure that `Shift+Tab`
is displayed as `Shift+Tab`, the `Shift+Tab` case is treated as if no Shift
was pressed at all.
This commit adds tests that check that:
1) Default key binding accelerators are distinct.
2) Message dialog appears when a duplicate key binding accelerator is
attempted to be assigned to a different action.
3) Duplicate key binding accelerator cannot refer to more than one action.
Also, `active_message_dialog` attribute was added to `PrefsEditor`, so
that tests could get a reference to a message dialog window.
This commit forbids setting duplicate key bindings in
`Preferences > Keybindings` tab.
If a duplicate key binding is detected upon editing, such a key binding
is not assigned and instead a message dialog is displayed saying that the
key binding is a duplicate.
This commit allows to set key bindings that contain
a key modified by a Shift key (e.g. `Ctrl + {`).
For example, after pressing `Ctrl + Shift + [`,
a key binding will be set to `Ctrl + {` as opposed
to `Ctrl + Shift + {` as before.
This is achieved by checking whether a key changes its
value when a Shift key is down. If it does, then the
Shift modifier is removed from `mods`. One exception:
if a key binding contains a letter then the Shift
modifier is not removed. This is because, for some
reason, a key value of a letter is never modified by the
Shift modifier and always corresponds to a key value of
a lowercase character. This is already handled in
`terminatorlib/keybindings.py`.
Resolves: #149