From dc3f42535741a6c8749953e73e77b3f983733faa Mon Sep 17 00:00:00 2001 From: tanyulong Date: Fri, 9 Jul 2021 10:30:19 +0800 Subject: [PATCH] Add a detection mechanism when PulseAudio exits abnormally --- ukui-volume-control-applet-qt/main.cpp | 9 ++ .../translations/bo.ts | 51 ++++++++--- .../translations/zh_CN.ts | 49 +++++++---- .../ukmedia_device_switch_widget.cpp | 87 ++++++++++++++++++- .../ukmedia_device_switch_widget.h | 23 +++++ .../ukui-volume-control-applet-qt.pro | 4 +- 6 files changed, 191 insertions(+), 32 deletions(-) diff --git a/ukui-volume-control-applet-qt/main.cpp b/ukui-volume-control-applet-qt/main.cpp index c02a842..9d33691 100755 --- a/ukui-volume-control-applet-qt/main.cpp +++ b/ukui-volume-control-applet-qt/main.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include /*! The ukui-media is the media of UKUI. @@ -91,6 +92,14 @@ int main(int argc, char *argv[]) return EXIT_SUCCESS; } + #ifndef QT_NO_TRANSLATION + QString translatorFileName = QLatin1String("qt_"); + translatorFileName += QLocale::system().name(); + QTranslator *pTranslator = new QTranslator(); + if (pTranslator->load(translatorFileName, QLibraryInfo::location(QLibraryInfo::TranslationsPath))) + app.installTranslator(pTranslator); + #endif + //加载qm文件 QTranslator translator; translator.load("/usr/share/ukui-media/translations/" + QLocale::system().name()); diff --git a/ukui-volume-control-applet-qt/translations/bo.ts b/ukui-volume-control-applet-qt/translations/bo.ts index 9950f86..a3ab02e 100755 --- a/ukui-volume-control-applet-qt/translations/bo.ts +++ b/ukui-volume-control-applet-qt/translations/bo.ts @@ -17,52 +17,70 @@ DeviceSwitchWidget - + Go Into Mini Mode - + Output volume control - - + + Mute - - + + Sound preference(S) - + Device Volume - + Application Volume - - - - + + Error + + + + + Unable to connect to the sound system, please check whether the pulseaudio service is running! + + + + + + + Speaker (Realtek Audio) - - + + Headphone + + QObject + + + PulseAudio Volume Control + + + UkmediaDeviceWidget @@ -93,6 +111,11 @@ UkmediaMiniMasterVolumeWidget + + + Speaker (Realtek Audio) + + Go Into Full Mode diff --git a/ukui-volume-control-applet-qt/translations/zh_CN.ts b/ukui-volume-control-applet-qt/translations/zh_CN.ts index f72e0dc..5d82d82 100755 --- a/ukui-volume-control-applet-qt/translations/zh_CN.ts +++ b/ukui-volume-control-applet-qt/translations/zh_CN.ts @@ -17,52 +17,70 @@ DeviceSwitchWidget - + Go Into Mini Mode 进入Mini模式 - + Output volume control 输出音量控制 - - + + Mute 静音 - - + + Sound preference(S) 声音首选项 - + Device Volume 设备音量 - - Application Volume + + Application Volume 应用音量 - - - - + + Error + 错误 + + + + Unable to connect to the sound system, please check whether the pulseaudio service is running! + 无法连接到系统声音,请检查pulseaudio服务是否正在运行! + + + + + + Speaker (Realtek Audio) 扬声器(Realtek Audio) - - + + Headphone 模拟耳机 + + QObject + + + PulseAudio Volume Control + + + UkmediaDeviceWidget @@ -94,6 +112,7 @@ UkmediaMiniMasterVolumeWidget + Speaker (Realtek Audio) 扬声器(Realtek Audio) diff --git a/ukui-volume-control-applet-qt/ukmedia_device_switch_widget.cpp b/ukui-volume-control-applet-qt/ukmedia_device_switch_widget.cpp index e2714a2..cb10ae2 100755 --- a/ukui-volume-control-applet-qt/ukmedia_device_switch_widget.cpp +++ b/ukui-volume-control-applet-qt/ukmedia_device_switch_widget.cpp @@ -151,8 +151,71 @@ void DeviceSwitchWidget::hideWindow() // isShow = true; } +gboolean DeviceSwitchWidget::connect_to_pulse(gpointer userdata) +{ + //连接到pulseaudio + pa_glib_mainloop *m = pa_glib_mainloop_new(g_main_context_default()); + DeviceSwitchWidget *w = static_cast(userdata); + w->api = pa_glib_mainloop_get_api(m); + + pa_proplist *proplist = pa_proplist_new(); + pa_proplist_sets(proplist, PA_PROP_APPLICATION_NAME, QObject::tr("PulseAudio Volume Control").toUtf8().constData()); + pa_proplist_sets(proplist, PA_PROP_APPLICATION_ID, "org.PulseAudio.pavucontrol"); + pa_proplist_sets(proplist, PA_PROP_APPLICATION_ICON_NAME, "audio-card"); + pa_proplist_sets(proplist, PA_PROP_APPLICATION_VERSION, "PACKAGE_VERSION"); + w->m_paContext = pa_context_new_with_proplist(w->api, nullptr, proplist); + g_assert(w->m_paContext); + + pa_proplist_free(proplist); +// qDebug() <<"123123" << pa_context_connect(m_paContext, nullptr, PA_CONTEXT_NOFAIL, nullptr) ; + + pa_context_set_state_callback(w->m_paContext, context_state_callback, w); + if (pa_context_connect(w->m_paContext, nullptr, PA_CONTEXT_NOFAIL, nullptr) < 0) { + if (pa_context_errno(w->m_paContext) == PA_ERR_INVALID) { +// w->setConnectingMessage(QObject::tr("Connection to PulseAudio failed. Automatic retry in 5s\n\n" +// "In this case this is likely because PULSE_SERVER in the Environment/X11 Root Window Properties\n" +// "or default-server in client.conf is misconfigured.\n" +// "This situation can also arrise when PulseAudio crashed and left stale details in the X11 Root Window.\n" +// "If this is the case, then PulseAudio should autospawn again, or if this is not configured you should\n" +// "run start-pulseaudio-x11 manually.").toUtf8().constData()); + qDebug() << "连接pulseaudio error"; + } + else { + g_timeout_add_seconds(5,connect_to_pulse,w); + } + } + + return false; +} + +void DeviceSwitchWidget::context_state_callback(pa_context *c, void *userdata) { + DeviceSwitchWidget *w = static_cast(userdata); + g_assert(c); + + switch (pa_context_get_state(c)) { + case PA_CONTEXT_UNCONNECTED: + case PA_CONTEXT_CONNECTING: + case PA_CONTEXT_AUTHORIZING: + case PA_CONTEXT_SETTING_NAME: + break; + + case PA_CONTEXT_READY: { + pa_operation *o; + break; + } + case PA_CONTEXT_FAILED: + w->pulseDisconnectMseeageBox(); + break; + case PA_CONTEXT_TERMINATED: + default: + break; + } +} + + DeviceSwitchWidget::DeviceSwitchWidget(QWidget *parent) : QWidget (parent) { + connect_to_pulse(this); setAttribute(Qt::WA_TranslucentBackground); setWindowFlags(Qt::WindowStaysOnTopHint|Qt::Popup); mThemeName = UKUI_THEME_WHITE; @@ -255,6 +318,7 @@ DeviceSwitchWidget::DeviceSwitchWidget(QWidget *parent) : QWidget (parent) if G_UNLIKELY (mate_mixer_context_open(context) == FALSE) { g_warning ("Failed to connect to a sound system**********************"); } + appWidget->setFixedSize(358,320); devWidget->setFixedSize(358,320); @@ -453,7 +517,7 @@ DeviceSwitchWidget::DeviceSwitchWidget(QWidget *parent) : QWidget (parent) */ void DeviceSwitchWidget::systemTrayMenuInit() { - menu = new QMenu(this); + menu = new QMenu(); qDebug() << "new menu"; // menu->setAttribute(Qt::WA_DeleteOnClose); // menu->setAttribute(); @@ -1278,6 +1342,7 @@ void DeviceSwitchWidget::on_context_state_notify (MateMixerContext *context,GPar } else if (state == MATE_MIXER_STATE_FAILED) { g_warning("Failed to connect a sound system"); + qDebug() << "Failed to connect a sound system"; } } @@ -2088,6 +2153,12 @@ void DeviceSwitchWidget::app_volume_mute (MateMixerStreamControl *control, QStri Q_EMIT w->appvolume_mute_change_mastervolume_status();*/ } +void DeviceSwitchWidget::pulseDisconnectMseeageBox() +{ + QMessageBox::critical(NULL, tr("Error"), tr("Unable to connect to the sound system, please check whether the pulseaudio service is running!"), QMessageBox::Abort); + exit(-1); +} + /*! * \brief * \details @@ -2095,6 +2166,17 @@ void DeviceSwitchWidget::app_volume_mute (MateMixerStreamControl *control, QStri */ void DeviceSwitchWidget::set_context(DeviceSwitchWidget *w,MateMixerContext *context) { + MateMixerStream *pOutputStream = mate_mixer_context_get_default_output_stream(context); + MateMixerState state = mate_mixer_context_get_state(context); + if (pOutputStream != nullptr) { + w->pulseDisconnectMseeageBox(); + } + qDebug() << "output stream" << mate_mixer_stream_get_name(pOutputStream) << state; + g_signal_connect (G_OBJECT (context), + "stream-added", + G_CALLBACK (on_context_stream_added), + w); + g_signal_connect (G_OBJECT (context), "stream-removed", G_CALLBACK (on_context_stream_removed), @@ -2439,8 +2521,9 @@ void DeviceSwitchWidget::update_icon_output (DeviceSwitchWidget *w,MateMixerCont if (QGSettings::isSchemaInstalled(UKUI_VOLUME_BRIGHTNESS_GSETTING_ID)) { if (w->m_pVolumeSetting->keys().contains("volumesize")) { w->m_pVolumeSetting->set(UKUI_VOLUME_KEY,value); - } + } } + qDebug() << "update icon output" << value << state << mate_mixer_stream_control_get_name(control); if (state) { systemTrayIcon = "audio-volume-muted-symbolic"; audioIconStr = "audio-volume-muted-symbolic"; diff --git a/ukui-volume-control-applet-qt/ukmedia_device_switch_widget.h b/ukui-volume-control-applet-qt/ukmedia_device_switch_widget.h index 71be9b9..5881b47 100755 --- a/ukui-volume-control-applet-qt/ukmedia_device_switch_widget.h +++ b/ukui-volume-control-applet-qt/ukmedia_device_switch_widget.h @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -46,6 +47,11 @@ extern "C" { #include #include #include +#include +#include +#include +#include +#include } #define SOUND_MODE_SCRIPTS "/usr/share/ukui-media/scripts/detection_output_mode.sh" @@ -101,7 +107,11 @@ class DeviceSwitchWidget:public QWidget public: DeviceSwitchWidget(QWidget *parent = nullptr); ~DeviceSwitchWidget(); + + static gboolean connect_to_pulse(gpointer userdata); + static void context_state_callback(pa_context *c, void *userdata); void get_window_nameAndid(); + void pulseDisconnectMseeageBox(); QList listExistsPath(); QString findFreePath(); void addValue(QString name,QString filename); @@ -259,6 +269,19 @@ private: bool firstEnterSystem = true; ca_context *caContext; + bool setOutputVolume = false; + bool setInputVolume = false; + + QByteArray role; + QByteArray device; + pa_channel_map channelMap; + pa_cvolume volume; + pa_context* m_paContext ; + pa_mainloop_api* api; + pa_ext_stream_restore_info info; + + + protected: void paintEvent(QPaintEvent *event); bool event(QEvent *event);//重写窗口事件 diff --git a/ukui-volume-control-applet-qt/ukui-volume-control-applet-qt.pro b/ukui-volume-control-applet-qt/ukui-volume-control-applet-qt.pro index 728edd9..b7ae512 100755 --- a/ukui-volume-control-applet-qt/ukui-volume-control-applet-qt.pro +++ b/ukui-volume-control-applet-qt/ukui-volume-control-applet-qt.pro @@ -36,7 +36,9 @@ PKGCONFIG += \ Qt5Multimedia \ dconf \ x11 \ - libcanberra + libcanberra \ + libpulse \ + libpulse-mainloop-glib # libwnck-1.0 HEADERS += \ -- 2.23.0