From 7c1955f0299c052d469745aa0ed9d41b710bf4c7 Mon Sep 17 00:00:00 2001 From: evgeny Date: Fri, 16 Oct 2026 14:14:04 +0200 Subject: [PATCH] Add a persistent cursor toggle to X11 broadcast controls --- tools/chatgui/CMakeLists.txt | 6 ++++++ tools/chatgui/src/stream_publish_window.cpp | 9 +++++++++ tools/chatgui/src/stream_publish_window.h | 2 +- 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/tools/chatgui/CMakeLists.txt b/tools/chatgui/CMakeLists.txt index faf3ecae..098154c1 100644 --- a/tools/chatgui/CMakeLists.txt +++ b/tools/chatgui/CMakeLists.txt @@ -196,6 +196,12 @@ if(QT_PACKAGE STREQUAL "Qt6" AND FFMPEG_FOUND) endif() endif() file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/chatgui_capture_enabled.txt" "${GUI_CAPTURE_ENABLED}\n") +if(GUI_CAPTURE_ENABLED AND UNIX AND NOT APPLE AND QT_FEATURE_xcb) + find_package(X11 REQUIRED COMPONENTS Xfixes) + target_sources(chatgui_stream_publish PRIVATE src/stream_screen_cursor.cpp) + target_compile_definitions(chatgui_stream_publish PUBLIC UTUN_STREAM_X11_CURSOR) + target_link_libraries(chatgui_stream_publish PRIVATE X11::X11 X11::Xfixes) +endif() add_library(chatgui_notifications STATIC src/message_notification.cpp src/user_activity_monitor.cpp) target_link_libraries(chatgui_notifications PUBLIC ${QT_PACKAGE}::Widgets PRIVATE utun) diff --git a/tools/chatgui/src/stream_publish_window.cpp b/tools/chatgui/src/stream_publish_window.cpp index d68d4d9e..f85633cc 100644 --- a/tools/chatgui/src/stream_publish_window.cpp +++ b/tools/chatgui/src/stream_publish_window.cpp @@ -78,6 +78,8 @@ StreamPublishWindow::StreamPublishWindow(StreamPublishEngine* engine, uint64_t g } m_rotation->button(0)->setChecked(true); angles->addStretch(); form->addRow(text("Rotation"), rotationRow); m_audio = new QCheckBox(text("Microphone enabled"), settings); m_audio->setChecked(true); form->addRow(m_audio); + m_cursor = new QCheckBox(text("Show mouse cursor"), settings); m_cursor->setChecked(true); + m_cursor->setObjectName(QStringLiteral("streamShowCursor")); form->insertRow(2, m_cursor); m_microphone = new QComboBox(settings); m_microphone->addItem(text("Default microphone"), QString()); for (const auto& device : SoundManager::enumerateCaptureDevices()) m_microphone->addItem(device.name, device.id); form->addRow(text("Microphone"), m_microphone); @@ -100,6 +102,7 @@ StreamPublishWindow::StreamPublishWindow(StreamPublishEngine* engine, uint64_t g for (auto* box : {m_mode, m_codec, m_bitrate}) connect(box, QOverload::of(&QComboBox::currentIndexChanged), this, &StreamPublishWindow::apply); connect(m_microphone, QOverload::of(&QComboBox::currentIndexChanged), this, &StreamPublishWindow::apply); connect(m_audio, &QCheckBox::toggled, this, &StreamPublishWindow::apply); + connect(m_cursor, &QCheckBox::toggled, this, &StreamPublishWindow::apply); #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) connect(m_rotation, &QButtonGroup::idClicked, this, &StreamPublishWindow::apply); #else @@ -153,6 +156,7 @@ void StreamPublishWindow::restoreSettings() { if (auto* button = m_rotation->button(m_settings.value("rotation").toInt())) button->setChecked(true); else DEBUG_WARN(DEBUG_CATEGORY_STREAM, "desktop saved capture rotation invalid"); m_audio->setChecked(m_settings.value("audio").toBool(true)); + m_cursor->setChecked(m_settings.value("show_cursor").toBool(true)); select(m_microphone, m_settings.value("microphone").toString(), "microphone"); m_updating = false; DEBUG_INFO(DEBUG_CATEGORY_STREAM, "desktop capture settings restored: %s", QJsonDocument(m_settings).toJson(QJsonDocument::Compact).constData()); @@ -173,6 +177,7 @@ void StreamPublishWindow::saveSettings() { if (m_codec->currentIndex() >= 0) saved["codec"] = config.video.codec; saved["bitrate"] = m_bitrate->currentData().toInt(); saved["rotation"] = config.video.rotation; saved["audio"] = config.audio; saved["microphone"] = config.microphone; + saved["show_cursor"] = config.showCursor; if (saved == m_settings) return; m_settings = saved; auto json = QJsonDocument(saved).toJson(QJsonDocument::Compact); @@ -263,6 +268,7 @@ StreamPublishConfig StreamPublishWindow::selection() const { config.video.bitrate = m_bitrate->currentData().toInt(); config.automaticBitrate = !config.video.bitrate; if (config.automaticBitrate) config.video.bitrate = std::clamp(config.video.width * config.video.height * config.video.fps / 11, 250000, 16000000); + config.showCursor = m_cursor->isChecked(); config.microphone = m_microphone->currentData().toString(); config.audio = m_audio->isChecked(); return config; } void StreamPublishWindow::apply() { @@ -293,5 +299,8 @@ void StreamPublishWindow::synchronize() { m_bitrate->setCurrentIndex(bitrateIndex); if (auto* button = m_rotation->button(config.video.rotation)) button->setChecked(true); m_audio->setChecked(config.audio); m_microphone->setCurrentIndex(m_microphone->findData(config.microphone)); + m_cursor->setChecked(config.showCursor); } + m_cursor->setVisible(StreamPublishEngine::cursorSupported(selection().source)); + m_cursor->setEnabled(!active || m_engine->running()); } diff --git a/tools/chatgui/src/stream_publish_window.h b/tools/chatgui/src/stream_publish_window.h index 6f9e6aeb..3322d309 100644 --- a/tools/chatgui/src/stream_publish_window.h +++ b/tools/chatgui/src/stream_publish_window.h @@ -20,7 +20,7 @@ private: QList m_sources; QList m_modes; QComboBox *m_source, *m_microphone, *m_mode, *m_codec, *m_bitrate; - QCheckBox *m_audio, *m_mute; + QCheckBox *m_audio, *m_mute, *m_cursor; QLabel *m_status, *m_stats, *m_inputChannels; QPushButton* m_start; QButtonGroup* m_rotation;