diff --git a/src/Instance.cxx b/src/Instance.cxx index d05b1de14..aab8a83a2 100644 --- a/src/Instance.cxx +++ b/src/Instance.cxx @@ -90,6 +90,22 @@ Instance::DeletePartition(Partition &partition) noexcept } } +AudioOutputControl * +Instance::FindOutput(std::string_view name, + Partition &excluding_partition) noexcept +{ + for (auto &partition : partitions) { + if (&partition == &excluding_partition) + continue; + + auto *output = partition.outputs.FindByName(name); + if (output != nullptr && !output->IsDummy()) + return output; + } + + return nullptr; +} + #ifdef ENABLE_DATABASE const Database & diff --git a/src/Instance.hxx b/src/Instance.hxx index 3a77650bd..253dad670 100644 --- a/src/Instance.hxx +++ b/src/Instance.hxx @@ -38,6 +38,7 @@ class InotifyUpdate; class ClientList; struct Partition; +class AudioOutputControl; class StateFile; class RemoteTagCache; class StickerDatabase; @@ -171,6 +172,17 @@ struct Instance final void BeginShutdownPartitions() noexcept; + /** + * Returns the (non-dummy) audio output device with the + * specified name. Returns nullptr if the name does not + * exist. + * + * @param excluding_partition ignore this partition + */ + [[gnu::pure]] + AudioOutputControl *FindOutput(std::string_view name, + Partition &excluding_partition) noexcept; + #ifdef ENABLE_DATABASE /** * Returns the global #Database instance. May return nullptr diff --git a/src/command/PartitionCommands.cxx b/src/command/PartitionCommands.cxx index 8a2dd112a..722f53aa3 100644 --- a/src/command/PartitionCommands.cxx +++ b/src/command/PartitionCommands.cxx @@ -145,29 +145,24 @@ handle_moveoutput(Client &client, Request request, Response &response) /* find the partition which owns this output currently */ auto &instance = client.GetInstance(); - for (auto &partition : instance.partitions) { - if (&partition == &dest_partition) - continue; - auto *output = partition.outputs.FindByName(output_name); - if (output == nullptr || output->IsDummy()) - continue; - - const bool was_enabled = output->IsEnabled(); - - if (existing_output != nullptr) - /* move the output back where it once was */ - existing_output->ReplaceDummy(output->Steal(), - was_enabled); - else - /* copy the AudioOutputControl and add it to the output list */ - dest_partition.outputs.AddMoveFrom(std::move(*output), - was_enabled); - - instance.EmitIdle(IDLE_OUTPUT); - return CommandResult::OK; + auto *output = instance.FindOutput(output_name, dest_partition); + if (output == nullptr) { + response.Error(ACK_ERROR_NO_EXIST, "No such output"); + return CommandResult::ERROR; } - response.Error(ACK_ERROR_NO_EXIST, "No such output"); - return CommandResult::ERROR; + const bool was_enabled = output->IsEnabled(); + + if (existing_output != nullptr) + /* move the output back where it once was */ + existing_output->ReplaceDummy(output->Steal(), + was_enabled); + else + /* copy the AudioOutputControl and add it to the output list */ + dest_partition.outputs.AddMoveFrom(std::move(*output), + was_enabled); + + instance.EmitIdle(IDLE_OUTPUT); + return CommandResult::OK; }