diff --git a/CMakeLists.txt b/CMakeLists.txt index 0252d65..b9fd93a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,6 +24,7 @@ pkg_check_modules(Xext REQUIRED xext) set(SOURCES src/main.cpp src/MpvPlayerBackend.cpp + src/utils.cpp ) find_program(CCACHE_FOUND ccache) @@ -50,7 +51,6 @@ if(DEVELOP) set(SOURCES ${SOURCES} runtimeqml/runtimeqml.cpp) add_definitions(-DQRC_SOURCE_PATH="${PROJECT_SOURCE_DIR}/src/qml") add_definitions(-DQT_QML_DEBUG) - endif(DEVELOP) add_executable(KittehPlayer ${SOURCES} ${qml_QRC}) diff --git a/KittehPlayer.pro b/KittehPlayer.pro index e818e9f..d36f221 100644 --- a/KittehPlayer.pro +++ b/KittehPlayer.pro @@ -3,19 +3,20 @@ TARGET = KittehPlayer TEMPLATE = app QT += qml quickcontrols2 widgets x11extras -SOURCES += src/main.cpp src/MpvPlayerBackend.cpp +SOURCES += src/main.cpp src/MpvPlayerBackend.cpp src/utils.cpp CONFIG += release #CONFIG+=qtquickcompiler QT_CONFIG -= no-pkg-config CONFIG += link_pkgconfig -PKGCONFIG += mpv x11 xext +PKGCONFIG += mpv RESOURCES += src/qml/qml.qrc unix { isEmpty { PREFIX = /usr } + PKGCONFIG += x11 xext target.path = $$PREFIX/bin @@ -30,7 +31,7 @@ unix { INSTALLS += target -HEADERS += src/MpvPlayerBackend.h +HEADERS += src/MpvPlayerBackend.h src/utils.hpp DISTFILES += KittehPlayer.desktop KittehPlayer.png README.md LICENSE.txt diff --git a/src/MpvPlayerBackend.cpp b/src/MpvPlayerBackend.cpp index cece4ea..bc22dde 100644 --- a/src/MpvPlayerBackend.cpp +++ b/src/MpvPlayerBackend.cpp @@ -1,20 +1,16 @@ #include +#include #include #include "MpvPlayerBackend.h" +#include "utils.hpp" #include #include #include #include #include -#include -#include -#include -#include -#include -#include namespace { @@ -156,9 +152,7 @@ MpvPlayerBackend::MpvPlayerBackend(QQuickItem* parent) MpvPlayerBackend::~MpvPlayerBackend() { - Display *dpy = QX11Info::display(); - DPMSEnable(dpy); - qDebug() << "Enabled DPMS."; + SetDPMS(true); mpv_render_context_free(mpv_gl); mpv_terminate_destroy(mpv); } @@ -307,6 +301,13 @@ MpvPlayerBackend::createTimestamp(const QVariant& seconds) const return hour + minute + second; } +void +MpvPlayerBackend::toggleOnTop() +{ + onTop = !onTop; + AlwaysOnTop(window()->winId(), onTop); +} + void MpvPlayerBackend::on_mpv_events() { diff --git a/src/MpvPlayerBackend.h b/src/MpvPlayerBackend.h index d430d10..8032383 100644 --- a/src/MpvPlayerBackend.h +++ b/src/MpvPlayerBackend.h @@ -16,6 +16,7 @@ class MpvPlayerBackend : public QQuickFramebufferObject Q_OBJECT mpv_handle* mpv; mpv_render_context* mpv_gl; + bool onTop = false; friend class MpvRenderer; @@ -35,6 +36,7 @@ public slots: void nextSubtitleTrack(); void prevPlaylistItem(); void nextPlaylistItem(); + void toggleOnTop(); QVariant getTracks() const; void setVolume(const QVariant& volume); diff --git a/src/main.cpp b/src/main.cpp index 4c0ac6c..9d336d8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2,19 +2,15 @@ #include "runtimeqml/runtimeqml.h" #endif -#include #include "MpvPlayerBackend.h" -#include +#include "utils.hpp" +#include + #include #include #include +#include #include -#include -#include -#include -#include -#include -#include #ifdef WIN32 #include "setenv_mingw.hpp" @@ -44,9 +40,7 @@ main(int argc, char* argv[]) } } - Display *dpy = QX11Info::display(); - DPMSDisable(dpy); - qDebug() << "Disabled DPMS."; + SetDPMS(false); QString newpath = QProcessEnvironment::systemEnvironment().value("APPDIR", "") + @@ -54,8 +48,8 @@ main(int argc, char* argv[]) setenv("PATH", newpath.toUtf8().constData(), 1); QApplication::setAttribute(Qt::AA_EnableHighDpiScaling); - QApplication::setAttribute(Qt::AA_NativeWindows); - + QApplication::setAttribute(Qt::AA_NativeWindows); + qmlRegisterType("player", 1, 0, "PlayerBackend"); std::setlocale(LC_NUMERIC, "C"); diff --git a/src/qml/Translator.qml b/src/qml/Translator.qml index 4a32552..9ee80d3 100644 --- a/src/qml/Translator.qml +++ b/src/qml/Translator.qml @@ -13,7 +13,7 @@ Item { function getTranslation(code, language) { var lang = Translations.translations[language] - if (lang == undefined) { + if (lang == undefined || lang == "undefined") { return "TranslationNotFound" } var text = String(Translations.translations[i18n.language][code]) diff --git a/src/qml/main.qml b/src/qml/main.qml index 874217b..6c5cf5c 100644 --- a/src/qml/main.qml +++ b/src/qml/main.qml @@ -734,6 +734,13 @@ ApplicationWindow { } shortcut: keybinds.nyanCat } + Action { + text: translate.getTranslation("TOGGLE_ALWAYS_ON_TOP", + i18n.language) + onTriggered: { + player.toggleOnTop() + } + } } Menu { id: aboutMenuBarItem diff --git a/src/qml/translations.js b/src/qml/translations.js index 9159703..c52369e 100644 --- a/src/qml/translations.js +++ b/src/qml/translations.js @@ -39,7 +39,8 @@ var translations = { TOGGLE_NYAN_CAT: "Toggle Nyan Cat", ABOUT: "About", ABOUT_QT: "About Qt", - TITLE: "Title" + TITLE: "Title", + TOGGLE_ALWAYS_ON_TOP: "Toggle Always On Top" }, spanish: { SAVE_SCREENSHOT: "Guardar captura en", diff --git a/src/utils.cpp b/src/utils.cpp new file mode 100644 index 0000000..aaa41bf --- /dev/null +++ b/src/utils.cpp @@ -0,0 +1,77 @@ +#include "utils.hpp" +#include + +#include +#include + +QString +getPlatformName() +{ + QGuiApplication* qapp = + qobject_cast(QCoreApplication::instance()); + return qapp->platformName(); +} + +#ifdef __linux__ +#include +#include +#include +#include +#include +#include + +void +SetDPMS(bool on) +{ + Display* dpy = QX11Info::display(); + if (on) { + DPMSEnable(dpy); + qDebug() << "Enabled DPMS."; + } else { + DPMSDisable(dpy); + qDebug() << "Disabled DPMS."; + } +} + +void +AlwaysOnTop(WId wid, bool on) +{ + qDebug() << "On Top:" << on; + Display* display = QX11Info::display(); + XEvent event; + event.xclient.type = ClientMessage; + event.xclient.serial = 0; + event.xclient.send_event = True; + event.xclient.display = display; + event.xclient.window = wid; + event.xclient.message_type = XInternAtom(display, "_NET_WM_STATE", False); + event.xclient.format = 32; + + event.xclient.data.l[0] = on; + event.xclient.data.l[1] = XInternAtom(display, "_NET_WM_STATE_ABOVE", False); + event.xclient.data.l[2] = 0; + event.xclient.data.l[3] = 0; + event.xclient.data.l[4] = 0; + + XSendEvent(display, + DefaultRootWindow(display), + False, + SubstructureRedirectMask | SubstructureNotifyMask, + &event); +} + +#else + +void +AlwaysOnTop(WId wid, bool on) +{ + qDebug() << "Can't set on top for platform: " << getPlatformName(); +} + +void +SetDPMS(bool on) +{ + qDebug() << "Can't set DPMS for platform: " << getPlatformName(); +} + +#endif \ No newline at end of file diff --git a/src/utils.hpp b/src/utils.hpp new file mode 100644 index 0000000..8af9fff --- /dev/null +++ b/src/utils.hpp @@ -0,0 +1,11 @@ +#ifndef UTILS_H +#define UTILS_H +#include +#include + +void +SetDPMS(bool on); +void +AlwaysOnTop(WId wid, bool on); + +#endif