Skip to content

Commit 7d7da24

Browse files
authored
Merge pull request #339 from Ph4ntomas/324-output_handle-active_tags
api: add [in]active tags filtering to OutputHandle
2 parents 54ab3ca + 2b9adf2 commit 7d7da24

3 files changed

Lines changed: 181 additions & 0 deletions

File tree

api/lua/pinnacle/output.lua

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -756,6 +756,62 @@ function OutputHandle:tags()
756756
return handles
757757
end
758758

759+
---Gets the active tags this output has.
760+
---
761+
---@return pinnacle.tag.TagHandle[]
762+
function OutputHandle:active_tags()
763+
local tags = self:tags()
764+
765+
---@type (fun(): boolean)[]
766+
local batch = {}
767+
for i, tag in ipairs(tags) do
768+
batch[i] = function()
769+
return tag:active()
770+
end
771+
end
772+
773+
local responses = require("pinnacle.util").batch(batch)
774+
775+
---@type pinnacle.tag.TagHandle[]
776+
local active_tags = {}
777+
778+
for i, is_active in ipairs(responses) do
779+
if is_active then
780+
table.insert(active_tags, tags[i])
781+
end
782+
end
783+
784+
return active_tags
785+
end
786+
787+
---Gets the inactive tags this output has.
788+
---
789+
---@return pinnacle.tag.TagHandle[]
790+
function OutputHandle:inactive_tags()
791+
local tags = self:tags()
792+
793+
---@type (fun(): boolean)[]
794+
local batch = {}
795+
for i, tag in ipairs(tags) do
796+
batch[i] = function()
797+
return not tag:active()
798+
end
799+
end
800+
801+
local responses = require("pinnacle.util").batch(batch)
802+
803+
---@type pinnacle.tag.TagHandle[]
804+
local inactive_tags = {}
805+
806+
for i, is_active in ipairs(responses) do
807+
if is_active then
808+
table.insert(inactive_tags, tags[i])
809+
end
810+
end
811+
812+
return inactive_tags
813+
end
814+
759815
---Get this output's scale.
760816
---
761817
---@return number

api/rust/src/output.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -856,6 +856,30 @@ impl OutputHandle {
856856
.map(|id| TagHandle { id })
857857
}
858858

859+
/// Gets handles to all active tags on this output.
860+
pub fn active_tags(&self) -> impl Iterator<Item = TagHandle> + use<> {
861+
self.active_tags_async().block_on_tokio()
862+
}
863+
864+
/// Async impl for [`Self::active_tags`].
865+
pub async fn active_tags_async(&self) -> impl Iterator<Item = TagHandle> + use<> {
866+
self.tags_async()
867+
.await
868+
.batch_filter(|tag| tag.active_async().boxed(), |is_active| is_active)
869+
}
870+
871+
/// Gets handles to all inactive tags on this output.
872+
pub fn inactive_tags(&self) -> impl Iterator<Item = TagHandle> + use<> {
873+
self.inactive_tags_async().block_on_tokio()
874+
}
875+
876+
/// Async impl for [`Self::active_tags`].
877+
pub async fn inactive_tags_async(&self) -> impl Iterator<Item = TagHandle> + use<> {
878+
self.tags_async()
879+
.await
880+
.batch_filter(|tag| tag.active_async().boxed(), |is_active| !is_active)
881+
}
882+
859883
/// Gets this output's current scale.
860884
pub fn scale(&self) -> f32 {
861885
self.scale_async().block_on_tokio()

tests/integration/api/output.rs

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -811,6 +811,107 @@ fn output_handle_tags() {
811811
}
812812
}
813813

814+
#[test_log::test]
815+
fn output_handle_active_tags() {
816+
for_each_api(|lang| {
817+
let (mut fixture, output, _) = set_up();
818+
819+
fixture.pinnacle().focus_output(&output);
820+
821+
output.with_state_mut(|state| {
822+
let tag2 = Tag::new("2".to_string());
823+
tag2.set_active(false);
824+
825+
let tag3 = Tag::new("3".to_string());
826+
tag3.set_active(true);
827+
828+
state.add_tags([tag2, tag3]);
829+
});
830+
831+
match lang {
832+
Lang::Rust => fixture.spawn_blocking(move || {
833+
let mut tags = pinnacle_api::output::get_focused()
834+
.unwrap()
835+
.active_tags()
836+
.map(|t| t.name())
837+
.collect::<Vec<_>>();
838+
839+
tags.sort();
840+
841+
assert_eq!(tags.len(), 2);
842+
assert_eq!(tags.as_slice(), ["1", "3"]);
843+
}),
844+
Lang::Lua => spawn_lua_blocking! {
845+
fixture,
846+
local tags = Output.get_focused():active_tags()
847+
assert(#tags == 2)
848+
849+
local tagnames = {}
850+
for k, v in ipairs(tags) do
851+
tagnames[k] = v:name()
852+
end
853+
854+
table.sort(tagnames)
855+
856+
assert(tagnames[1] == "1")
857+
assert(tagnames[2] == "3")
858+
},
859+
};
860+
})
861+
}
862+
863+
#[test_log::test]
864+
fn output_handle_inactive_tags() {
865+
for_each_api(|lang| {
866+
let (mut fixture, output, _) = set_up();
867+
868+
fixture.pinnacle().focus_output(&output);
869+
870+
output.with_state_mut(|state| {
871+
let tag2 = Tag::new("2".to_string());
872+
tag2.set_active(false);
873+
874+
let tag3 = Tag::new("3".to_string());
875+
tag3.set_active(false);
876+
877+
let tag4 = Tag::new("4".to_string());
878+
tag4.set_active(true);
879+
880+
state.add_tags([tag2, tag3, tag4]);
881+
});
882+
883+
match lang {
884+
Lang::Rust => fixture.spawn_blocking(move || {
885+
let mut tags = pinnacle_api::output::get_focused()
886+
.unwrap()
887+
.inactive_tags()
888+
.map(|t| t.name())
889+
.collect::<Vec<_>>();
890+
891+
tags.sort();
892+
893+
assert_eq!(tags.len(), 2);
894+
assert_eq!(tags.as_slice(), ["2", "3"]);
895+
}),
896+
Lang::Lua => spawn_lua_blocking! {
897+
fixture,
898+
local tags = Output.get_focused():inactive_tags()
899+
assert(#tags == 2)
900+
901+
local tagnames = {}
902+
for k, v in ipairs(tags) do
903+
tagnames[k] = v:name()
904+
end
905+
906+
table.sort(tagnames)
907+
908+
assert(tagnames[1] == "2")
909+
assert(tagnames[2] == "3")
910+
},
911+
};
912+
})
913+
}
914+
814915
#[test_log::test]
815916
fn output_handle_scale() {
816917
let (mut fixture, output, _) = set_up();

0 commit comments

Comments
 (0)