I write and work in several languages: German, Spanish, French, Greek, English. In mac when you press a key longer than 2 seconds you can choose between special characters derivative from a main character. In windows there is a software called Holdkey that does the same. Is there anything similar in Linux. I haven't found it yet.


I have two advices:

  1. Use a suitable keyboard layout, i.e. a layout with dead keys. If you have an English keyboard, pick for instance English (US, intl., with dead keys). But there are several other variants.
  2. Define a compose key. That way you'll be able to type many characters which are not included in the keyboard layout you are using. (Compose key is a XKB feature, so it's available on Kubuntu, but you need to figure out how to define it there.)
| improve this answer | |
  • Thank you! I didn't thought about the use of English (US, intl., with dead keys). This idea is very use to configure and very easy to use. I choosed EurKEY (US based layout with european letters) for my use is perfect. – George G. Jun 3 '19 at 2:29

If you are not afraid to set up (instructions should be clear), below could give you an alternative to quickly insert your often used special character (-alternatives).

Editable special character tool

The script below is a flexible tool (window to insert characters from, in a click) to have often used characters available in a second:

enter image description here

How it works

  • Call the window with a shortcut
  • To insert a character, simply click on it, and it will paste the character into the window you were working in.
  • To add a set of characters, press + A text editor window will open, add your "family" name on the first line, related special characters on the next lines, one character per line, for example:


    (from the image). Close the file, the special characters will be available from now on from the next time you call the window.

  • to delete a set of available characters, press x

How to set up

  1. You need to satisfy a few dependencies:

    • python3-xlib

      sudo apt install python3-xlib
    • pyautogui:

      pip3 install pyautogui
    • pyperclip:

      sudo apt install python3-pyperclip xsel xclip
    • You might have to install Wnck:

      python3-gi gir1.2-wnck-3.0

    Log out and back in.

  2. Copy the script below into an empty file, save it as specialchars.py and make it executable

    #!/usr/bin/env python3
    import os
    import gi
    gi.require_version("Gtk", "3.0")
    gi.require_version('Wnck', '3.0')
    from gi.repository import Gtk, Wnck, Gdk
    import subprocess
    import pyperclip
    import pyautogui
    css_data = """
    .label {
      font-weight: bold;
      color: blue;
    .delete {
      color: red;
    fpath = os.environ["HOME"] + "/.specialchars"
    def create_dirs():
        except FileExistsError:
    def listfiles():
        files = os.listdir(fpath)
        chardata = []
        for f in files:
            f = os.path.join(fpath, f)
            chars = [s.strip() for s in open(f).readlines()]
                category = chars[0]
                members = chars[1:]
            except IndexError:
                chardata.append([category, members, f])
        chardata.sort(key=lambda x: x[0])
        return chardata
    def create_newfamily(button):
        n = 1
        while True:
            name = "charfamily_" + str(n)
            file = os.path.join(fpath, name)
            if os.path.exists(file):
                n = n + 1
        open(file, "wt").write("")
        subprocess.Popen(["xdg-open", file])
    class Window(Gtk.Window):
        def __init__(self):
            # self.set_active(True)
            self.connect("key-press-event", self.get_key)
            self.set_default_size(0, 0)
            self.provider = Gtk.CssProvider.new()
            self.maingrid = Gtk.Grid()
            chardata = listfiles()
            # get the currently active window
            self.screendata = Wnck.Screen.get_default()
            self.curr_subject = self.screendata.get_active_window().get_xid()
            row = 0
            for d in chardata:
                bbox = Gtk.HBox()
                fambutton = Gtk.Button(d[0])
                fambutton_cont = fambutton.get_style_context()
                fambutton.connect("pressed", self.open_file, d[2])
                    "Edit special characters of '" + d[0] + "'"
                bbox.pack_start(fambutton, False, False, 0)
                for c in d[1]:
                    button = Gtk.Button(c)
                    button.connect("pressed", self.replace, c)
                    button.set_size_request(1, 1)
                    bbox.pack_start(button, False, False, 0)
                self.maingrid.attach(bbox, 0, row, 1, 1)
                deletebutton = Gtk.Button("X")
                deletebutton_cont = deletebutton.get_style_context()
                deletebutton.connect("pressed", self.delete_file, d[2], bbox)
                deletebutton.set_tooltip_text("Delete family")
                self.maingrid.attach(deletebutton, 100, row, 1, 1)
                row = row + 1
            addbutton = Gtk.Button("+")
            addbutton.connect("pressed", create_newfamily)
            addbutton.set_tooltip_text("Add family")
            self.maingrid.attach(addbutton, 100, 100, 1, 1)
            self.maingrid.attach(Gtk.Label("- Press Esc to exit -"), 0, 100, 1, 1)
        def get_key(self, button, val):
            # keybinding to close the previews
            if Gdk.keyval_name(val.keyval) == "Escape":
        def replace(self, button, char, *args):
            subprocess.call(["wmctrl", "-ia", str(self.curr_subject)])
            pyautogui.hotkey('ctrl', 'v')
        def open_file(self, button, path):
            subprocess.Popen(["xdg-open", path])
        def delete_file(self, button, path, widget):
            self.resize(10, 10)
  3. Set up a shortcut key to run:

    python3 /path/to/specialchars.py

On first run, you will only see a + button. Start Adding your character "families" and restart (-call) the window to have all available in a click.

That's it...

| improve this answer | |
  • Interesting solution, hence +1'ed but just one question: why python3-xlib is necessary ? I don't see Xlib being imported anywhere in the code – Sergiy Kolodyazhnyy Jun 1 '19 at 23:24
  • @SergiyKolodyazhnyy Aarrgh, copied too much over from my answer here: askubuntu.com/questions/1071218/… thanks for mentioning! – Jacob Vlijm Jun 2 '19 at 5:40
  • Haha, either script or copy and paste all the things - that's the way to go XD I'll look over the other answer as well. Thanks for the weekend read. – Sergiy Kolodyazhnyy Jun 2 '19 at 5:49
  • @SergiyKolodyazhnyy Hah, I only copied the install instructions! :) – Jacob Vlijm Jun 2 '19 at 5:52
  • @SergiyKolodyazhnyy waitwai!! Autogui uses Xlib... – Jacob Vlijm Jun 2 '19 at 5:54

You can use unicode to type special characters on Linux.

To type a special character, first press down CTRL+SHIFT+U and then let go of the keys.

Next, type the hexadecimal code for the character you wish to insert and then press ENTER

The hexadecimal code for "ü" is 00fc.

Click here to see the Wikipedia page for Unicode characters.

Click here to see the Wikipedia page for Unicode math characters.

| improve this answer | |
  • Clarification: Hold CTRL and SHIFT hit U, let go of CTRL and SHIFT keys, type the code, press enter. – Hannu Jun 2 '19 at 8:21
  • Thanks for this idea. However for me personally I think the best option is to use a Keyboard layout. I found EurKEY (US based layout with european letters) the best for people who need German language characters as well as Spanish. I will use you idea for greek characters that I don't use that often. – George G. Jun 3 '19 at 2:33
  • @Hannu You can let go of all the keys CTRL and SHIFT and U. There is no need to hold down U while you type the code. – mchid Jun 4 '19 at 20:46
  • 1
    "hit U" = no holding. – Hannu Jun 5 '19 at 14:43
  • @Hannu Although, you can hold down U when you type the code you just don't need to. Either way works. – mchid Jun 6 '19 at 21:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.