diff --git a/src/klkt/icons.qrc b/src/klkt/icons.qrc
deleted file mode 100644
index f7f3841d4f6245013081d5b10252d94a914b3c69..0000000000000000000000000000000000000000
--- a/src/klkt/icons.qrc
+++ /dev/null
@@ -1,12 +0,0 @@
-<RCC>
-    <qresource prefix="/icons">
-        <file alias="LICENSE">icons/LICENSE</file>
-        <file alias="pause.png">icons/pause-fill.png</file>
-        <file alias="play.png">icons/play-fill.png</file>
-        <file alias="README">icons/README</file>
-        <file alias="previous.png">icons/skip-back-mini-fill.png</file>
-        <file alias="next.png">icons/skip-forward-mini-fill.png</file>
-        <file alias="stop.png">icons/stop-fill.png</file>
-        <file alias="shuffle.png">icons/shuffle-line.png</file>
-    </qresource>
-</RCC>
diff --git a/src/klkt/icons/LICENSE b/src/klkt/icons/LICENSE
deleted file mode 100644
index 261eeb9e9f8b2b4b0d119366dda99c6fd7d35c64..0000000000000000000000000000000000000000
--- a/src/klkt/icons/LICENSE
+++ /dev/null
@@ -1,201 +0,0 @@
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "[]"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright [yyyy] [name of copyright owner]
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
diff --git a/src/klkt/icons/README b/src/klkt/icons/README
deleted file mode 100644
index bf4405c87c2c842603273cd493071c089a6a66e5..0000000000000000000000000000000000000000
--- a/src/klkt/icons/README
+++ /dev/null
@@ -1,2 +0,0 @@
-Icons from https://github.com/Remix-Design/RemixIcon
-APACHE 2.0 License, see LICENSE file in this directory.
diff --git a/src/klkt/icons/pause-fill.png b/src/klkt/icons/pause-fill.png
deleted file mode 100644
index dcf4f380c729f67c6f87c028ff73b8c7f07b7a9d..0000000000000000000000000000000000000000
Binary files a/src/klkt/icons/pause-fill.png and /dev/null differ
diff --git a/src/klkt/icons/play-fill.png b/src/klkt/icons/play-fill.png
deleted file mode 100644
index 9393efb14bb3db872c5d3536ba8940f95bb13afc..0000000000000000000000000000000000000000
Binary files a/src/klkt/icons/play-fill.png and /dev/null differ
diff --git a/src/klkt/icons/shuffle-line.png b/src/klkt/icons/shuffle-line.png
deleted file mode 100644
index 9bba2d7dd92327c23d510acdeaa30d81ccc635b8..0000000000000000000000000000000000000000
Binary files a/src/klkt/icons/shuffle-line.png and /dev/null differ
diff --git a/src/klkt/icons/skip-back-mini-fill.png b/src/klkt/icons/skip-back-mini-fill.png
deleted file mode 100644
index cc7315afa08d3faf1fa333d8503028d8a06f851e..0000000000000000000000000000000000000000
Binary files a/src/klkt/icons/skip-back-mini-fill.png and /dev/null differ
diff --git a/src/klkt/icons/skip-forward-mini-fill.png b/src/klkt/icons/skip-forward-mini-fill.png
deleted file mode 100644
index fa9a89ecb3221d6c5818866992821d09c8986228..0000000000000000000000000000000000000000
Binary files a/src/klkt/icons/skip-forward-mini-fill.png and /dev/null differ
diff --git a/src/klkt/icons/stop-fill.png b/src/klkt/icons/stop-fill.png
deleted file mode 100644
index 0fd15cd332493589a7e67e913368517c49fe0e54..0000000000000000000000000000000000000000
Binary files a/src/klkt/icons/stop-fill.png and /dev/null differ
diff --git a/src/klkt/klkt.cpp b/src/klkt/klkt.cpp
deleted file mode 100644
index 2ffefafbaf2f8e9acc5950f68b0344056b2e07c8..0000000000000000000000000000000000000000
--- a/src/klkt/klkt.cpp
+++ /dev/null
@@ -1,20 +0,0 @@
-#include "klkt.hpp"
-
-#ifdef __linux__
-#include <sys/prctl.h>
-#include <signal.h>
-#endif
-
-int
-main(int argc, char **argv)
-{
-#ifdef __linux__
-    /* Dies when the parent dies */
-    prctl(PR_SET_PDEATHSIG, SIGHUP);
-#endif
-
-    Application app(argc, argv);
-    int code = app.exec();
-    notify_uninit();
-    return code;
-}
diff --git a/src/klkt/klkt.hpp b/src/klkt/klkt.hpp
deleted file mode 100644
index b3387d4b93e875b714d0235e463270a93ec270f9..0000000000000000000000000000000000000000
--- a/src/klkt/klkt.hpp
+++ /dev/null
@@ -1,627 +0,0 @@
-#ifndef APPLICATION_HPP
-#define APPLICATION_HPP
-
-#include <libnotify/notify.h>
-
-#include <QObject>
-#include <QApplication>
-#include <QHostAddress>
-#include <QSystemTrayIcon>
-#include <QIcon>
-#include <QPixmap>
-#include <QMenu>
-#include <QAction>
-#include <QList>
-#include <QMap>
-#include <QTcpSocket>
-#include <QTextCodec>
-#include <QStandardPaths>
-#include <QDir>
-#include <QSettings>
-#include <QProcess>
-#include <QLocalSocket>
-
-#include <algorithm>
-#include <iostream>
-#include <stdio.h>
-
-#include <lektor/common.h>
-LKT_PUSH
-LKT_IGNORE_WARN_WRITE_STRING
-#include <lektor/internal/icon.xpm>
-LKT_POP
-
-static inline const int UTF8_MIB = 106;
-
-/* Hop();; We wrap the glib types */
-#define URGENCY(x) x = NOTIFY_URGENCY_##x,
-enum Urgency { URGENCY(LOW) URGENCY(NORMAL) URGENCY(CRITICAL) };
-#undef URGENCY
-
-static inline const char *
-__urgencyToString(Urgency urg)
-{
-    switch (urg) {
-    case Urgency::LOW: return "LOW";
-    case Urgency::NORMAL: return "NORMAL";
-    case Urgency::CRITICAL: return "CRITICAL";
-    default: return "UNKNOWN";
-    }
-}
-
-#if defined(Q_OS_LINUX)
-/* Restrict libnotify (thus glib...) only to that function */
-static void
-sendNotification(const char *name, const char *msg, enum Urgency urgency)
-{
-    GdkPixbuf *gtk_icon       = gdk_pixbuf_new_from_xpm_data(const_cast<const char **>(icon));
-    NotifyNotification *notif = notify_notification_new(name, msg, NULL);
-    notify_notification_set_icon_from_pixbuf(notif, gtk_icon);
-    notify_notification_set_urgency(notif, static_cast<NotifyUrgency>(urgency));
-    notify_notification_show(notif, NULL);
-    g_object_unref(G_OBJECT(notif));
-    g_object_unref(gtk_icon);
-    fprintf(stdout, "# %s (%s) -> %s\n", name, __urgencyToString(urgency),
-            QString(msg).replace('\n', "\\n").toStdString().c_str());
-    fflush(stdout);
-}
-#else
-#error \
-    "System is not supported yet, you need to write a 'sendNotification(const char *, const char *, enum Urgency)' function for that system"
-#endif
-
-/* Config class, the ~/.config/lektor/klkt.ini file */
-class Config final {
-private:
-    static inline const QString opt_host = "lektord/host";
-    static inline const QString opt_port = "lektord/port";
-
-    QString m_host;
-    qint16 m_port;
-
-public:
-    Config(QApplication *app, const QString &file)
-    {
-        QSettings settings(file, QSettings::IniFormat, app);
-        m_host = settings.value(opt_host, "127.0.0.1").toString();
-        m_port = settings.value(opt_port, "6600").toInt();
-
-        settings.setValue(opt_host, m_host);
-        settings.setValue(opt_port, m_port);
-    }
-
-    qint16 getPort(void) const { return m_port; }
-    bool isUnix(void) const { return m_port <= 0; }
-    const QString &getHost(void) const { return m_host; }
-};
-
-/* Socket, can be unix socket or tcp socket. Because QIODevice don't have all that what we need */
-class Socket final : public QObject {
-    Q_OBJECT
-private:
-    enum Type {
-        Unix,
-        Tcp,
-    };
-
-    /* Can be tcp or unix socket */
-    QTcpSocket m_tcp;
-    QLocalSocket m_unix;
-    Type m_type;
-
-    /* Where to connect */
-    QString m_host;
-    qint16 m_port;
-
-public slots:
-    /* Re-emit signals */
-    inline void triggetConnected(void) { emit connected(); }
-    inline void triggetDisconnected(void) { emit disconnected(); }
-    inline void triggetReadyRead(void) { emit readyRead(); }
-
-signals:
-    /* Used signals from TCP and Unix sockets */
-    void connected(void);
-    void disconnected(void);
-    void readyRead(void);
-
-public:
-    Socket(const QString &host, qint16 port) { reset(host, port); }
-
-    void reset(const QString host, qint16 port)
-    {
-        m_host = host;
-        m_port = port;
-
-        /* Unix specific stuff */
-        if (port <= 0) {
-            m_type = Type::Unix;
-            connect(&m_unix, &QLocalSocket::connected, this, &Socket::triggetConnected);
-            connect(&m_unix, &QLocalSocket::disconnected, this, &Socket::triggetDisconnected);
-            connect(&m_unix, &QLocalSocket::readyRead, this, &Socket::triggetReadyRead);
-        }
-
-        /* TCP specific stuff */
-        else {
-            m_type = Type::Tcp;
-            connect(&m_tcp, &QTcpSocket::connected, this, &Socket::triggetConnected);
-            connect(&m_tcp, &QTcpSocket::disconnected, this, &Socket::triggetDisconnected);
-            connect(&m_tcp, &QTcpSocket::readyRead, this, &Socket::triggetReadyRead);
-        }
-    }
-
-#define __DIFFERENTIATE(unix, tcp)                                                      \
-    {                                                                                   \
-        switch (m_type) {                                                               \
-        case Type::Unix: unix; break;                                                   \
-        case Type::Tcp: tcp; break;                                                     \
-        }                                                                               \
-        sendNotification("Klkt fatal error", "Unknown socket type", Urgency::CRITICAL); \
-        ::exit(EXIT_FAILURE);                                                           \
-    }
-
-    // clang-format off
-    inline bool isValid(void)           __DIFFERENTIATE({ return m_unix.isValid(); }, { return m_tcp.isValid(); });
-    inline QByteArray readAll(void)     __DIFFERENTIATE({ return m_unix.readAll(); }, { return m_tcp.readAll(); });
-    inline qint64 write(const char *d)  __DIFFERENTIATE({ return m_unix.write(d);  }, { return m_tcp.write(d);  });
-    inline void close(void)             __DIFFERENTIATE({ return m_unix.close();   }, { return m_tcp.close();   });
-    inline void doConnect(void)         __DIFFERENTIATE({ return m_unix.connectToServer(m_host); },
-                                                        { return m_tcp.connectToHost(m_host, m_port); });
-    inline bool waitForConnected(int ms = 30000)    __DIFFERENTIATE({ return m_unix.waitForConnected(ms); },
-                                                                    { return m_tcp.waitForConnected(ms); });
-    inline bool waitForDisconnected(int ms = 30000) __DIFFERENTIATE({ return m_unix.waitForDisconnected(ms); },
-                                                                    { return m_tcp.waitForDisconnected(ms); });
-    // clang-format on
-#undef __DIFFERENTIATE
-};
-
-/* Used to generate a notification for the state of lektord and get the currently playing kara */
-class Status final : public QWidget {
-    Q_OBJECT
-private:
-    Socket m_sock;
-    QString m_pending_data;
-    QString m_state;
-    QMap<QString, QString> m_current_kara;
-    QMetaObject::Connection m_connect_read;
-    bool m_deletable  = false;
-    bool m_send_notif = true;
-
-    static inline const char *StatusString  = "status\n";
-    static inline const char *CurrentString = "currentsong\n";
-
-    void sendNotification(const char *title, const char *msg, Urgency urg)
-    {
-        if (!m_send_notif)
-            return;
-        ::sendNotification(title, msg, urg);
-    }
-
-private slots:
-    void connected(void) { m_sock.write(StatusString); }
-
-    void disconnected(void)
-    {
-        if (m_deletable)
-            return;
-
-        if (m_state == "play") {
-            // m_current_kara["category"] + " - " + m_current_kara["language"] + "\n" +
-            QString kara = m_current_kara["source"] + "\n" + m_current_kara["type"] + " - " +
-                           m_current_kara["title"] + " [" + m_current_kara["author"] + "]";
-            sendNotification("lektord is playing", kara.toStdString().c_str(), Urgency::LOW);
-            emit changeCurrentKara(kara);
-            emit changeStatus(Play);
-        }
-
-        else if (m_state == "stop") {
-            sendNotification("lektord is stopped", "lektord is not playing", Urgency::LOW);
-            emit changeCurrentKara("lektord is stopped");
-            emit changeStatus(Stop);
-        }
-
-        else if (m_state == "pause") {
-            sendNotification("lektord is paused", "lektord is not playing", Urgency::LOW);
-            emit changeCurrentKara("lektord is paused");
-            emit changeStatus(Pause);
-        }
-
-        else {
-            sendNotification("lektord error",
-                             tr("lektord has the following unkown state: '%1'")
-                                 .arg(m_state)
-                                 .toStdString()
-                                 .c_str(),
-                             Urgency::CRITICAL);
-            emit changeCurrentKara(tr("Unknown state: '%1'").arg(m_state));
-            emit changeStatus(Unknown);
-        }
-
-        m_deletable = true;
-    }
-
-    void readCurrent(void)
-    {
-        QByteArray got = m_sock.readAll();
-        m_pending_data += QTextCodec::codecForMib(UTF8_MIB)->toUnicode(got);
-        QStringList lines = m_pending_data.split("\n");
-        int return_position;
-
-        for (auto &line : lines) {
-            return_position = line.length() + 1;
-            m_pending_data  = m_pending_data.right(m_pending_data.length() - return_position);
-            if (line == "OK" || line.left(3) == "ACK") {
-                m_sock.close();
-                return;
-            }
-
-            /* Decode line */
-#define DECODE(what)                                         \
-    if (line.startsWith(what ": ", Qt::CaseInsensitive)) {   \
-        line.remove(0, static_cast<int>(strlen(what ": "))); \
-        m_current_kara.insert(what, line);                   \
-    }
-            DECODE("title")
-            DECODE("author")
-            DECODE("source")
-            DECODE("type")
-            DECODE("category")
-            DECODE("language")
-#undef DECODE
-        }
-    }
-
-    void readStatus(void)
-    {
-        QByteArray got = m_sock.readAll();
-        m_pending_data += QTextCodec::codecForMib(UTF8_MIB)->toUnicode(got);
-        QStringList lines = m_pending_data.split("\n");
-        int return_position;
-
-        for (const auto &line : lines) {
-            return_position = line.length() + 1;
-            m_pending_data  = m_pending_data.right(m_pending_data.length() - return_position);
-            if (line == "OK" || line.left(3) == "ACK") {
-                /* Read the current song if needed */
-                if (m_state == "play") {
-                    QWidget::disconnect(m_connect_read);
-                    m_pending_data = "";
-                    m_connect_read =
-                        QWidget::connect(&m_sock, &Socket::readyRead, this, &Status::readCurrent);
-                    m_sock.write(CurrentString);
-                } else
-                    m_sock.close();
-                return;
-            }
-
-            QStringList play_state = line.split(": ");
-            if (play_state.length() == 2 && play_state.at(0) == "state")
-                m_state = play_state.at(1);
-        }
-    }
-
-public:
-    Status(const QString &host, qint16 port, bool send_notif = true)
-        : m_sock(host, port)
-        , m_send_notif(send_notif)
-    {
-        fprintf(stdout, "Query status%s\n", send_notif ? "" : " (no notification)");
-        m_sock.doConnect();
-        QWidget::connect(&m_sock, &Socket::connected, this, &Status::connected);
-        QWidget::connect(&m_sock, &Socket::disconnected, this, &Status::disconnected);
-        m_connect_read = QWidget::connect(&m_sock, &Socket::readyRead, this, &Status::readStatus);
-        fflush(stdout);
-    }
-
-    Status &operator=(Status &) = delete;
-
-    inline bool isDeletable(void) const { return m_deletable; }
-    inline void waitForDisconnected(void) { m_sock.waitForDisconnected(-1); }
-
-    enum {
-        Pause,
-        Play,
-        Stop,
-        Unknown,
-    };
-
-signals:
-    void changeCurrentKara(QString);
-    void changeStatus(int);
-};
-
-/* Send commends to lektord */
-class Commander final : public QObject {
-    Q_OBJECT
-private:
-    Socket m_sock;
-    const char *m_cmd;
-
-    static inline const char *CMD_NEXT       = "next\n";
-    static inline const char *CMD_PREVIOUS   = "previous\n";
-    static inline const char *CMD_SHUFFLE    = "shuffle\n";
-    static inline const char *CMD_FORCE_PLAY = "play\n";
-    static inline const char *CMD_TOGGLE     = "pause\n";
-
-    void doCommand(void)
-    {
-        fprintf(stdout, "Send command %s", m_cmd);
-        m_sock.doConnect();
-        connect(&m_sock, &Socket::connected, this, [&]() { m_sock.write(m_cmd); });
-        connect(&m_sock, &Socket::disconnected, this, [&]() { emit finished(); });
-        connect(&m_sock, &Socket::readyRead, this, [&]() {
-            QStringList lines =
-                QTextCodec::codecForMib(UTF8_MIB)->toUnicode(m_sock.readAll()).split("\n");
-            for (auto &line : lines) {
-                if (line == "OK" || line.left(3) == "ACK") {
-                    m_sock.close();
-                    emit finished();
-                    return;
-                }
-            }
-        });
-        fflush(stdout);
-        m_sock.waitForDisconnected();
-    }
-
-    Commander(const QString &host, qint16 port, const char *command)
-        : m_sock(host, port)
-        , m_cmd(command)
-    {
-        doCommand();
-    };
-
-    Commander(const QString &host, qint16 port)
-        : m_sock(host, port)
-        , m_cmd(nullptr)
-    {
-    }
-
-public slots:
-#define DECLARE_CMD(name) \
-    static void name(const QString &host, qint16 port) { Commander cmd(host, port, CMD_##name); }
-    DECLARE_CMD(NEXT)
-    DECLARE_CMD(PREVIOUS)
-    DECLARE_CMD(SHUFFLE)
-    DECLARE_CMD(TOGGLE)
-    DECLARE_CMD(FORCE_PLAY)
-
-    void handleCorrectPlay(int sta)
-    {
-        switch (sta) {
-        case Status::Play:
-        case Status::Pause:
-            m_cmd = CMD_TOGGLE;
-            doCommand();
-            break;
-
-        default:
-            m_cmd = CMD_FORCE_PLAY;
-            doCommand();
-            break;
-        }
-    }
-
-    static void PLAY(const QString &host, qint16 port)
-    {
-        std::cout << "Asked a PLAY command" << std::endl;
-        Status sta(host, port, false);
-        Commander cmd(host, port);
-        connect(&sta, &Status::changeStatus, &cmd, &Commander::handleCorrectPlay);
-        sta.waitForDisconnected();
-    }
-#undef DECLARE_CMD
-
-signals:
-    void finished(void);
-};
-
-/* The application */
-class Application final : public QApplication {
-    Q_OBJECT
-private:
-    bool m_exit;
-    QPixmap m_xpm;
-    QIcon m_icon;
-    QSystemTrayIcon m_tray_icon;
-    QMenu m_menu;
-
-    bool m_already_red  = false;
-    bool m_is_connected = false;
-    QString m_pending_data;
-
-    QString m_host = "127.0.0.1";
-    qint16 m_port  = 6600;
-    QString m_config_file;
-
-    Socket m_sock;
-
-    QList<Status *> m_garbage;
-
-    static inline const char *ListenString = "idle player\n";
-
-protected slots:
-    void notifyExit(void)
-    {
-        garbageCollect(true);
-
-        if (m_exit)
-            return;
-
-        sendNotification("Klkt quitting", "Klkt will stop", Urgency::LOW);
-        m_exit = true;
-        if (m_sock.isValid())
-            m_sock.close();
-
-        quit();
-    }
-
-    void disconnected(void)
-    {
-        if (m_exit || !m_is_connected)
-            return;
-
-        sendNotification("Connexion lost", "Connexion to lektord has been lost!",
-                         Urgency::CRITICAL);
-        m_pending_data = "";
-        m_is_connected = false;
-    }
-
-    void reconnect(void)
-    {
-        Config conf(this, m_config_file);
-        if (conf.isUnix()) {
-#if defined(Q_OS_MSDOS) || defined(Q_OS_WIN32) || defined(Q_OS_WINCE) || defined(Q_OS_WIN) || \
-    defined(Q_OS_WINRT)
-            sendNotification("Klkt fatal error",
-                             "The 'unix' socket type is not available on your platform",
-                             Urgency::CRITICAL);
-#endif
-        }
-
-        m_host = conf.getHost();
-        m_port = conf.getPort();
-        m_sock.reset(m_host, m_port);
-        m_sock.doConnect();
-        if (!m_sock.waitForConnected(50000))
-            sendNotification("Klkt not connected", "Connexion to lektord failed",
-                             Urgency::CRITICAL);
-        else
-            m_is_connected = true;
-    }
-
-    void read(void)
-    {
-        QByteArray got = m_sock.readAll();
-        m_pending_data = QTextCodec::codecForMib(UTF8_MIB)->toUnicode(got);
-
-        if (!m_already_red) {
-            m_already_red = true;
-            m_sock.write(ListenString);
-        }
-
-        for (const auto &line : m_pending_data.split("\n")) {
-            if (line.left(2) == "OK")
-                queryStatus();
-        }
-    }
-
-    void connected(void) {}
-
-private:
-    void queryStatus(void)
-    {
-        garbageCollect();
-        Status *ptr_status = new Status(m_host, m_port);
-        connect(ptr_status, &Status::changeCurrentKara, this,
-                [&](QString kara) { m_tray_icon.setToolTip(kara); });
-        m_garbage.push_back(ptr_status);
-    }
-
-    void garbageCollect(bool force = false)
-    {
-        std::transform(m_garbage.begin(), m_garbage.end(), m_garbage.begin(),
-                       [&force](Status *p_sta) -> Status * {
-                           if (force || (p_sta && p_sta->isDeletable())) {
-                               delete p_sta;
-                               return nullptr;
-                           } else
-                               return p_sta;
-                       });
-
-        /* Should be enaugh to delete all used status sockets */
-        while (m_garbage.length() > 0 && m_garbage.front() == nullptr)
-            m_garbage.pop_front();
-    }
-
-    // Qt::GenericConfigLocation
-public:
-    Application(int argc, char **argv)
-        : QApplication(argc, argv)
-        , m_exit(false)
-        , m_xpm(icon)
-        , m_icon(m_xpm)
-        , m_tray_icon(m_icon)
-        , m_config_file(QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation))
-        , m_sock(m_host, m_port)
-    {
-        notify_init("Klkt");
-
-        {
-            QDir config_dir(m_config_file);
-            if (!config_dir.mkpath(m_config_file)) {
-                sendNotification("Klkt fatal error",
-                                 tr("Failed to create the Klkt config dir %1")
-                                     .arg(m_config_file)
-                                     .toStdString()
-                                     .c_str(),
-                                 Urgency::CRITICAL);
-                ::exit(EXIT_FAILURE);
-            }
-            m_config_file += "/lektor/klkt.ini";
-            QFile conf_file(m_config_file);
-            if (!conf_file.open(QIODevice::ReadWrite | QIODevice::Text)) {
-                sendNotification("Klkt fatal error",
-                                 tr("Failed to create Klkt config file %1")
-                                     .arg(m_config_file)
-                                     .toStdString()
-                                     .c_str(),
-                                 Urgency::CRITICAL);
-                ::exit(EXIT_FAILURE);
-            }
-            conf_file.close();
-        }
-
-        {
-            m_menu.addSection("Playback");
-            QAction *playback_play = m_menu.addAction(QIcon(":/icons/play.png"), "Play/Pause");
-            QAction *playback_next = m_menu.addAction(QIcon(":/icons/next.png"), "Next");
-            QAction *playback_prev = m_menu.addAction(QIcon(":/icons/previous.png"), "Previous");
-            QAction *playback_shuf = m_menu.addAction(QIcon(":/icons/shuffle.png"), "Shuffle");
-            m_menu.addSection("System");
-            QAction *action_reco    = m_menu.addAction("Reconnect");
-            QAction *action_restart = m_menu.addAction("Restart");
-            QAction *action_quit    = m_menu.addAction("Quit");
-            m_tray_icon.setContextMenu(&m_menu);
-            m_tray_icon.setToolTip("The lektord mk7 system tray client");
-
-            playback_play->setIconVisibleInMenu(true);
-            playback_prev->setIconVisibleInMenu(true);
-            playback_next->setIconVisibleInMenu(true);
-            playback_shuf->setIconVisibleInMenu(true);
-
-            connect(playback_play, &QAction::triggered, this,
-                    [&]() { Commander::PLAY(m_host, m_port); });
-            connect(playback_next, &QAction::triggered, this,
-                    [&]() { Commander::NEXT(m_host, m_port); });
-            connect(playback_prev, &QAction::triggered, this,
-                    [&]() { Commander::PREVIOUS(m_host, m_port); });
-            connect(playback_shuf, &QAction::triggered, this,
-                    [&]() { Commander::SHUFFLE(m_host, m_port); });
-
-            connect(action_quit, &QAction::triggered, this, &Application::notifyExit);
-            connect(action_reco, &QAction::triggered, this, &Application::reconnect);
-            connect(action_restart, &QAction::triggered, this, &Application::restart);
-            connect(&m_tray_icon, &QSystemTrayIcon::activated, &m_menu,
-                    [&]() { m_menu.popup(QCursor::pos()); });
-        }
-
-        m_tray_icon.show();
-
-        connect(&m_sock, &Socket::connected, this, &Application::connected);
-        connect(&m_sock, &Socket::disconnected, this, &Application::disconnected);
-        connect(&m_sock, &Socket::readyRead, this, &Application::read);
-
-        reconnect();
-    }
-
-    void restart(void) const
-    {
-        sendNotification("Klkt restart", "Klkt will restart", Urgency::LOW);
-        QStringList args{ QApplication::applicationFilePath() };
-        QProcess::startDetached(args[0], args);
-        ::exit(EXIT_SUCCESS);
-    }
-};
-
-#endif // APPLICATION_HPP
diff --git a/src/klkt/klkt.pro b/src/klkt/klkt.pro
deleted file mode 100644
index 25125e87a8a19681ca45867b3ed272aa3373eca6..0000000000000000000000000000000000000000
--- a/src/klkt/klkt.pro
+++ /dev/null
@@ -1,29 +0,0 @@
-QT += core gui network
-greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
-
-QT_CONFIG -= no-pkg-config
-CONFIG    += c++17 console
-CONFIG    -= app_bundle
-CONFIG	  += link_pkgconfig
-PKGCONFIG += libnotify
-
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000
-
-SOURCES +=                          \
-        klkt.cpp                    \
-
-HEADERS +=                          \
-        klkt.hpp                    \
-        ../../inc/lektor/icon.xpm   \
-        ../../inc/lektor/common.h   \
-
-INCLUDEPATH +=                      \
-        ../../inc/
-
-# Default rules for deployment.
-qnx: target.path = /tmp/$${TARGET}/bin
-else: unix:!android: target.path = /opt/$${TARGET}/bin
-!isEmpty(target.path): INSTALLS += target
-
-RESOURCES += \
-    icons.qrc