mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Add support for G-S-D's media-keys extension
This fixes media keys handling on (but not limited to, probably): * GNOME * Cinnamon * MATE * Budgie * Pantheon (elementaryOS) * Unity
This commit is contained in:
parent
486424af4f
commit
28f857f763
5 changed files with 250 additions and 0 deletions
|
@ -812,6 +812,8 @@ PRIVATE
|
||||||
platform/linux/linux_desktop_environment.h
|
platform/linux/linux_desktop_environment.h
|
||||||
platform/linux/linux_gdk_helper.cpp
|
platform/linux/linux_gdk_helper.cpp
|
||||||
platform/linux/linux_gdk_helper.h
|
platform/linux/linux_gdk_helper.h
|
||||||
|
platform/linux/linux_gsd_media_keys.cpp
|
||||||
|
platform/linux/linux_gsd_media_keys.h
|
||||||
platform/linux/linux_libs.cpp
|
platform/linux/linux_libs.cpp
|
||||||
platform/linux/linux_libs.h
|
platform/linux/linux_libs.h
|
||||||
platform/linux/linux_wayland_integration.cpp
|
platform/linux/linux_wayland_integration.cpp
|
||||||
|
@ -1101,6 +1103,13 @@ if (NOT LINUX)
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if (LINUX AND DESKTOP_APP_DISABLE_DBUS_INTEGRATION)
|
||||||
|
remove_target_sources(Telegram ${src_loc}
|
||||||
|
platform/linux/linux_gsd_media_keys.cpp
|
||||||
|
platform/linux/linux_gsd_media_keys.h
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
if (LINUX AND DESKTOP_APP_DISABLE_WAYLAND_INTEGRATION)
|
if (LINUX AND DESKTOP_APP_DISABLE_WAYLAND_INTEGRATION)
|
||||||
remove_target_sources(Telegram ${src_loc} platform/linux/linux_wayland_integration.cpp)
|
remove_target_sources(Telegram ${src_loc} platform/linux/linux_wayland_integration.cpp)
|
||||||
nice_target_sources(Telegram ${src_loc} PRIVATE platform/linux/linux_wayland_integration_dummy.cpp)
|
nice_target_sources(Telegram ${src_loc} PRIVATE platform/linux/linux_wayland_integration_dummy.cpp)
|
||||||
|
|
182
Telegram/SourceFiles/platform/linux/linux_gsd_media_keys.cpp
Normal file
182
Telegram/SourceFiles/platform/linux/linux_gsd_media_keys.cpp
Normal file
|
@ -0,0 +1,182 @@
|
||||||
|
/*
|
||||||
|
This file is part of Telegram Desktop,
|
||||||
|
the official desktop application for the Telegram messaging service.
|
||||||
|
|
||||||
|
For license and copyright information please follow this link:
|
||||||
|
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
*/
|
||||||
|
#include "platform/linux/linux_gsd_media_keys.h"
|
||||||
|
|
||||||
|
#include "core/sandbox.h"
|
||||||
|
#include "media/player/media_player_instance.h"
|
||||||
|
|
||||||
|
#include <QtDBus/QDBusConnection>
|
||||||
|
#include <QtDBus/QDBusConnectionInterface>
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#undef signals
|
||||||
|
#include <gio/gio.h>
|
||||||
|
#define signals public
|
||||||
|
} // extern "C"
|
||||||
|
|
||||||
|
namespace Platform {
|
||||||
|
namespace internal {
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
constexpr auto kDBusTimeout = 30000;
|
||||||
|
constexpr auto kService = "org.gnome.SettingsDaemon.MediaKeys"_cs;
|
||||||
|
constexpr auto kOldService = "org.gnome.SettingsDaemon"_cs;
|
||||||
|
constexpr auto kMATEService = "org.mate.SettingsDaemon"_cs;
|
||||||
|
constexpr auto kObjectPath = "/org/gnome/SettingsDaemon/MediaKeys"_cs;
|
||||||
|
constexpr auto kMATEObjectPath = "/org/mate/SettingsDaemon/MediaKeys"_cs;
|
||||||
|
constexpr auto kInterface = kService;
|
||||||
|
constexpr auto kMATEInterface = "org.mate.SettingsDaemon.MediaKeys"_cs;
|
||||||
|
|
||||||
|
void KeyPressed(
|
||||||
|
GDBusConnection *connection,
|
||||||
|
const gchar *sender_name,
|
||||||
|
const gchar *object_path,
|
||||||
|
const gchar *interface_name,
|
||||||
|
const gchar *signal_name,
|
||||||
|
GVariant *parameters,
|
||||||
|
gpointer user_data) {
|
||||||
|
gchar *appUtf8;
|
||||||
|
gchar *keyUtf8;
|
||||||
|
g_variant_get(parameters, "(ss)", &appUtf8, &keyUtf8);
|
||||||
|
const auto app = QString::fromUtf8(appUtf8);
|
||||||
|
const auto key = QString::fromUtf8(keyUtf8);
|
||||||
|
g_free(keyUtf8);
|
||||||
|
g_free(appUtf8);
|
||||||
|
|
||||||
|
if (app != QCoreApplication::applicationName()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Core::Sandbox::Instance().customEnterFromEventLoop([&] {
|
||||||
|
if (key == qstr("Play")) {
|
||||||
|
Media::Player::instance()->playPause();
|
||||||
|
} else if (key == qstr("Stop")) {
|
||||||
|
Media::Player::instance()->stop();
|
||||||
|
} else if (key == qstr("Next")) {
|
||||||
|
Media::Player::instance()->next();
|
||||||
|
} else if (key == qstr("Previous")) {
|
||||||
|
Media::Player::instance()->previous();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
GSDMediaKeys::GSDMediaKeys() {
|
||||||
|
GError *error = nullptr;
|
||||||
|
const auto interface = QDBusConnection::sessionBus().interface();
|
||||||
|
|
||||||
|
if (!interface) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (interface->isServiceRegistered(kService.utf16())) {
|
||||||
|
_service = kService.utf16();
|
||||||
|
_objectPath = kObjectPath.utf16();
|
||||||
|
_interface = kInterface.utf16();
|
||||||
|
} else if (interface->isServiceRegistered(kOldService.utf16())) {
|
||||||
|
_service = kOldService.utf16();
|
||||||
|
_objectPath = kObjectPath.utf16();
|
||||||
|
_interface = kInterface.utf16();
|
||||||
|
} else if (interface->isServiceRegistered(kMATEService.utf16())) {
|
||||||
|
_service = kMATEService.utf16();
|
||||||
|
_objectPath = kMATEObjectPath.utf16();
|
||||||
|
_interface = kMATEInterface.utf16();
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_dbusConnection = g_bus_get_sync(
|
||||||
|
G_BUS_TYPE_SESSION,
|
||||||
|
nullptr,
|
||||||
|
&error);
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
LOG(("GSD Media Keys Error: %1").arg(error->message));
|
||||||
|
g_error_free(error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto reply = g_dbus_connection_call_sync(
|
||||||
|
_dbusConnection,
|
||||||
|
_service.toUtf8(),
|
||||||
|
_objectPath.toUtf8(),
|
||||||
|
_interface.toUtf8(),
|
||||||
|
"GrabMediaPlayerKeys",
|
||||||
|
g_variant_new(
|
||||||
|
"(su)",
|
||||||
|
QCoreApplication::applicationName().toUtf8().constData(),
|
||||||
|
0),
|
||||||
|
nullptr,
|
||||||
|
G_DBUS_CALL_FLAGS_NONE,
|
||||||
|
kDBusTimeout,
|
||||||
|
nullptr,
|
||||||
|
&error);
|
||||||
|
|
||||||
|
if (!error) {
|
||||||
|
_grabbed = true;
|
||||||
|
g_variant_unref(reply);
|
||||||
|
} else {
|
||||||
|
LOG(("GSD Media Keys Error: %1").arg(error->message));
|
||||||
|
g_error_free(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
_signalId = g_dbus_connection_signal_subscribe(
|
||||||
|
_dbusConnection,
|
||||||
|
_service.toUtf8(),
|
||||||
|
_interface.toUtf8(),
|
||||||
|
"MediaPlayerKeyPressed",
|
||||||
|
_objectPath.toUtf8(),
|
||||||
|
nullptr,
|
||||||
|
G_DBUS_SIGNAL_FLAGS_NONE,
|
||||||
|
KeyPressed,
|
||||||
|
nullptr,
|
||||||
|
nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
GSDMediaKeys::~GSDMediaKeys() {
|
||||||
|
GError *error = nullptr;
|
||||||
|
|
||||||
|
if (_signalId != 0) {
|
||||||
|
g_dbus_connection_signal_unsubscribe(
|
||||||
|
_dbusConnection,
|
||||||
|
_signalId);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_grabbed) {
|
||||||
|
auto reply = g_dbus_connection_call_sync(
|
||||||
|
_dbusConnection,
|
||||||
|
_service.toUtf8(),
|
||||||
|
_objectPath.toUtf8(),
|
||||||
|
_interface.toUtf8(),
|
||||||
|
"ReleaseMediaPlayerKeys",
|
||||||
|
g_variant_new(
|
||||||
|
"(s)",
|
||||||
|
QCoreApplication::applicationName().toUtf8().constData()),
|
||||||
|
nullptr,
|
||||||
|
G_DBUS_CALL_FLAGS_NONE,
|
||||||
|
kDBusTimeout,
|
||||||
|
nullptr,
|
||||||
|
&error);
|
||||||
|
|
||||||
|
if (!error) {
|
||||||
|
_grabbed = false;
|
||||||
|
g_variant_unref(reply);
|
||||||
|
} else {
|
||||||
|
LOG(("GSD Media Keys Error: %1").arg(error->message));
|
||||||
|
g_error_free(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_dbusConnection) {
|
||||||
|
g_object_unref(_dbusConnection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
} // namespace Platform
|
36
Telegram/SourceFiles/platform/linux/linux_gsd_media_keys.h
Normal file
36
Telegram/SourceFiles/platform/linux/linux_gsd_media_keys.h
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
/*
|
||||||
|
This file is part of Telegram Desktop,
|
||||||
|
the official desktop application for the Telegram messaging service.
|
||||||
|
|
||||||
|
For license and copyright information please follow this link:
|
||||||
|
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
typedef struct _GDBusConnection GDBusConnection;
|
||||||
|
|
||||||
|
namespace Platform {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
class GSDMediaKeys {
|
||||||
|
public:
|
||||||
|
GSDMediaKeys();
|
||||||
|
|
||||||
|
GSDMediaKeys(const GSDMediaKeys &other) = delete;
|
||||||
|
GSDMediaKeys &operator=(const GSDMediaKeys &other) = delete;
|
||||||
|
GSDMediaKeys(GSDMediaKeys &&other) = delete;
|
||||||
|
GSDMediaKeys &operator=(GSDMediaKeys &&other) = delete;
|
||||||
|
|
||||||
|
~GSDMediaKeys();
|
||||||
|
|
||||||
|
private:
|
||||||
|
GDBusConnection *_dbusConnection = nullptr;
|
||||||
|
QString _service;
|
||||||
|
QString _objectPath;
|
||||||
|
QString _interface;
|
||||||
|
uint _signalId = 0;
|
||||||
|
bool _grabbed = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
} // namespace Platform
|
|
@ -23,8 +23,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "storage/localstorage.h"
|
#include "storage/localstorage.h"
|
||||||
#include "window/window_controller.h"
|
#include "window/window_controller.h"
|
||||||
#include "window/window_session_controller.h"
|
#include "window/window_session_controller.h"
|
||||||
|
#include "media/player/media_player_instance.h"
|
||||||
|
#include "media/audio/media_audio.h"
|
||||||
#include "base/platform/base_platform_info.h"
|
#include "base/platform/base_platform_info.h"
|
||||||
#include "base/platform/linux/base_xcb_utilities_linux.h"
|
#include "base/platform/linux/base_xcb_utilities_linux.h"
|
||||||
|
#ifndef DESKTOP_APP_DISABLE_DBUS_INTEGRATION
|
||||||
|
#include "platform/linux/linux_gsd_media_keys.h"
|
||||||
|
#endif // !DESKTOP_APP_DISABLE_DBUS_INTEGRATION
|
||||||
#include "base/call_delayed.h"
|
#include "base/call_delayed.h"
|
||||||
#include "ui/widgets/input_fields.h"
|
#include "ui/widgets/input_fields.h"
|
||||||
#include "facades.h"
|
#include "facades.h"
|
||||||
|
@ -572,6 +577,17 @@ void MainWindow::initHook() {
|
||||||
} else {
|
} else {
|
||||||
LOG(("Not using Unity launcher counter."));
|
LOG(("Not using Unity launcher counter."));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Media::Player::instance()->updatedNotifier(
|
||||||
|
) | rpl::start_with_next([=](const Media::Player::TrackState &state) {
|
||||||
|
if (!Media::Player::IsStoppedOrStopping(state.state)) {
|
||||||
|
if (!_gsdMediaKeys) {
|
||||||
|
_gsdMediaKeys = std::make_unique<internal::GSDMediaKeys>();
|
||||||
|
}
|
||||||
|
} else if (_gsdMediaKeys) {
|
||||||
|
_gsdMediaKeys = nullptr;
|
||||||
|
}
|
||||||
|
}, lifetime());
|
||||||
#endif // !DESKTOP_APP_DISABLE_DBUS_INTEGRATION
|
#endif // !DESKTOP_APP_DISABLE_DBUS_INTEGRATION
|
||||||
|
|
||||||
updateWaylandDecorationColors();
|
updateWaylandDecorationColors();
|
||||||
|
|
|
@ -24,6 +24,11 @@ typedef struct _GDBusProxy GDBusProxy;
|
||||||
#endif // !DESKTOP_APP_DISABLE_DBUS_INTEGRATION
|
#endif // !DESKTOP_APP_DISABLE_DBUS_INTEGRATION
|
||||||
|
|
||||||
namespace Platform {
|
namespace Platform {
|
||||||
|
#ifndef DESKTOP_APP_DISABLE_DBUS_INTEGRATION
|
||||||
|
namespace internal {
|
||||||
|
class GSDMediaKeys;
|
||||||
|
} // namespace internal
|
||||||
|
#endif // !DESKTOP_APP_DISABLE_DBUS_INTEGRATION
|
||||||
|
|
||||||
class MainWindow : public Window::MainWindow {
|
class MainWindow : public Window::MainWindow {
|
||||||
public:
|
public:
|
||||||
|
@ -88,6 +93,8 @@ private:
|
||||||
DBusMenuExporter *_mainMenuExporter = nullptr;
|
DBusMenuExporter *_mainMenuExporter = nullptr;
|
||||||
QDBusObjectPath _mainMenuPath;
|
QDBusObjectPath _mainMenuPath;
|
||||||
|
|
||||||
|
std::unique_ptr<internal::GSDMediaKeys> _gsdMediaKeys;
|
||||||
|
|
||||||
QMenu *psMainMenu = nullptr;
|
QMenu *psMainMenu = nullptr;
|
||||||
QAction *psLogout = nullptr;
|
QAction *psLogout = nullptr;
|
||||||
QAction *psUndo = nullptr;
|
QAction *psUndo = nullptr;
|
||||||
|
|
Loading…
Add table
Reference in a new issue