Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 13 additions & 5 deletions src/platform/linux/kwingrab.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ namespace kwin {
* @brief KWin screencast output name and geometry.
*/
struct output_parameter_t {
std::string name = ""; ///< KWin output name.
std::string name; ///< KWin output name.
int width = 0; ///< Output width in pixels.
int height = 0; ///< Output height in pixels.
int pos_x = 0; ///< Output X position in the compositor layout.
Expand All @@ -279,6 +279,7 @@ namespace kwin {
screencast_t &operator=(screencast_t &&) = delete; // Do not allow to copying

~screencast_t() {
// Release KDE screencast wayland extensions and reset pointers
if (kde_screencast_stream_v1_) {
zkde_screencast_stream_unstable_v1_close(kde_screencast_stream_v1_);
kde_screencast_stream_v1_ = nullptr;
Expand All @@ -287,23 +288,30 @@ namespace kwin {
zkde_screencast_unstable_v1_destroy(kde_screencast_v1_);
kde_screencast_v1_ = nullptr;
}

if (kde_output_order) {
kde_output_order_v1_destroy(kde_output_order);
kde_output_order = nullptr;
}

// Clear output order list
output_order.clear();
// Clear current output parameters
out_params.reset();
out_params = nullptr;

// wl_output is owned by the registry, released on disconnect
for (const auto &out : outputs | std::views::keys) {
wl_output_destroy(out);
// also cleanup associated output parameters and clear output list when done
for (auto &[output, params] : outputs) {
wl_output_destroy(output);
params.reset();
}
outputs.clear();

// Release wayland registry, display and reset pointers
if (wl_registry) {
wl_registry_destroy(wl_registry);
wl_registry = nullptr;
}

if (wl_display) {
wl_display_disconnect(wl_display);
wl_display = nullptr;
Expand Down
60 changes: 21 additions & 39 deletions src/platform/linux/pipewire.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,34 +136,44 @@ namespace pipewire {

~pipewire_t() {
BOOST_LOG(debug) << "[pipewire] Destroying pipewire_t"sv;
try {
cleanup_stream();
} catch (const std::exception &e) {
BOOST_LOG(error) << "[pipewire] Standard exception caught in ~pipewire_t cleanup_stream: "sv << e.what();
} catch (...) {
BOOST_LOG(error) << "[pipewire] Unknown exception caught in ~pipewire_t cleanup_stream"sv;
}

pw_thread_loop_lock(loop);

// Lock the frame mutex to stop fill_img
BOOST_LOG(debug) << "[pipewire] Stop fill_img"sv;
{
std::scoped_lock lock(stream_data.frame_mutex);
stream_data.frame_ready = false;
stream_data.current_buffer = nullptr;
}

// Release pipewire stream
if (stream_data.stream) {
BOOST_LOG(debug) << "[pipewire] Disconnect stream"sv;
pw_stream_disconnect(stream_data.stream);
BOOST_LOG(debug) << "[pipewire] Destroy stream"sv;
pw_stream_destroy(stream_data.stream);
stream_data.stream = nullptr;
}
// Release pipewire core
if (core) {
BOOST_LOG(debug) << "[pipewire] Disconnect PW core"sv;
pw_core_disconnect(core);
core = nullptr;
}
// Release pipewire context
if (context) {
BOOST_LOG(debug) << "[pipewire] Destroy PW context"sv;
pw_context_destroy(context);
context = nullptr;
}

pw_thread_loop_unlock(loop);

// Release pipewire file descriptor
if (fd >= 0) {
BOOST_LOG(debug) << "[pipewire] Close pipewire_fd"sv;
close(fd);
}
// Release pipewire thread loop
BOOST_LOG(debug) << "[pipewire] Stop PW thread loop"sv;
pw_thread_loop_unlock(loop);
pw_thread_loop_stop(loop);
BOOST_LOG(debug) << "[pipewire] Destroy PW thread loop"sv;
pw_thread_loop_destroy(loop);
Expand Down Expand Up @@ -245,34 +255,6 @@ namespace pipewire {
return 0;
}

/**
* @brief Release the active PipeWire stream and listener.
*/
void cleanup_stream() {
BOOST_LOG(debug) << "[pipewire] Cleaning up stream"sv;
if (loop && stream_data.stream) {
pw_thread_loop_lock(loop);

// 1. Lock the frame mutex to stop fill_img
BOOST_LOG(debug) << "[pipewire] Stop fill_img"sv;
{
std::scoped_lock lock(stream_data.frame_mutex);
stream_data.frame_ready = false;
stream_data.current_buffer = nullptr;
}

if (stream_data.stream) {
BOOST_LOG(debug) << "[pipewire] Disconnect stream"sv;
pw_stream_disconnect(stream_data.stream);
BOOST_LOG(debug) << "[pipewire] Destroy stream"sv;
pw_stream_destroy(stream_data.stream);
stream_data.stream = nullptr;
}

pw_thread_loop_unlock(loop);
}
}

/**
* @brief Create the PipeWire stream if it is not already active.
*
Expand Down