Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: handle createworkspacev2 #242

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
13 changes: 6 additions & 7 deletions examples/keyword.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
/// Demostrates how to fetch and set keywords
///
///
/// Usage: cargo run --example keyword <keyword> <value>?
/// Example: cargo run --example keyword decoration:rounding (prints value)
/// Example: cargo run --example keyword decoration:rounding (prints value)
/// Example: cargo run --example keyword decoration:rounding 15 (sets value)

use hyprland::keyword::Keyword;

fn main() -> hyprland::Result<()> {
let args: Vec<_> = std::env::args().skip(1).collect();
let keyword = args[0].clone();

match args.len() {
0 => panic!("You need to pass a keyword"),
1 => println!("{} value is {}", keyword, Keyword::get(&keyword)?.value),
2 => Keyword::set(keyword, args[1].clone())?
_ => panic!("Takes up to 2 arguments only!")
2 => Keyword::set(keyword, args[1].clone())?,
_ => panic!("Takes up to 2 arguments only!"),
}

Ok(())
}
}
4 changes: 2 additions & 2 deletions examples/keyword_async.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ async fn main() -> hyprland::Result<()> {
match args.len() {
0 => panic!("You need to pass a keyword"),
1 => println!("{} value is {}", keyword, Keyword::get_async(&keyword).await?.value),
2 => Keyword::set_async(keyword, args[1].clone()).await?
2 => Keyword::set_async(keyword, args[1].clone()).await?,
_ => panic!("Takes up to 2 arguments only!")
}

Ok(())
}
}
2 changes: 1 addition & 1 deletion src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -248,5 +248,5 @@ fn test_binds() {
Ok(v) => v,
Err(e) => panic!("Error occured: {e}"), // Note to greppers: this is in a test!
};
assert_eq!(built_bind, "SUPER,v,/togglefloating");
assert_eq!(built_bind, "SUPER,v,togglefloating");
}
1 change: 1 addition & 0 deletions src/event_listener/async_im.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ impl HasAsyncExecutor for AsyncEventListener {
match event {
Event::WorkspaceChanged(id) => arm_async!(id, workspace_changed_events, self),
Event::WorkspaceAdded(id) => arm_async!(id, workspace_added_events, self),
Event::WorkspaceAddedV2(data) => arm_async!(data, workspace_added_v2_events, self),
Event::WorkspaceDeleted(data) => {
arm_async!(data, workspace_destroyed_events, self)
}
Expand Down
1 change: 1 addition & 0 deletions src/event_listener/immutable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ impl HasExecutor for EventListener {
match event {
WorkspaceChanged(id) => arm!(id, workspace_changed_events, self),
WorkspaceAdded(id) => arm!(id, workspace_added_events, self),
WorkspaceAddedV2(data) => arm!(data, workspace_added_v2_events, self),
WorkspaceDeleted(data) => arm!(data, workspace_destroyed_events, self),
WorkspaceMoved(evend) => arm!(evend, workspace_moved_events, self),
WorkspaceRename(even) => arm!(even, workspace_rename_events, self),
Expand Down
1 change: 1 addition & 0 deletions src/event_listener/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ macro_rules! init_events {
$name {
workspace_changed_events: vec![],
workspace_added_events: vec![],
workspace_added_v2_events: vec![],
workspace_destroyed_events: vec![],
workspace_moved_events: vec![],
workspace_rename_events: vec![],
Expand Down
2 changes: 1 addition & 1 deletion src/event_listener/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ pub use crate::event_listener::async_im::AsyncEventListener;

add_listener!(workspace_change d, WorkspaceType, "on workspace change", "changed workspace to" => id);
add_listener!(workspace_added, WorkspaceType, "a workspace is created", "workspace was added" => id);
add_listener!(workspace_destroy ed, WorkspaceDestroyedEventData, "a workspace is destroyed", "a workspace was destroyed" => data);
add_listener!(workspace_destroy ed, WorkspaceV2Data, "a workspace is destroyed", "a workspace was destroyed" => data);
add_listener!(workspace_moved, MonitorEventData, "a workspace is moved", "workspace was moved" => id);
add_listener!(workspace_rename, WorkspaceRenameEventData, "a workspace is renamed", "workspace was renamed" => id);
add_listener!(active_monitor_change d, MonitorEventData, "the active monitor is changed", "Active monitor changed to" => data);
Expand Down
114 changes: 114 additions & 0 deletions src/event_listener/shared/event_parsing_test.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
use crate::event_listener::{
event_parser, Event, MonitorEventData, WorkspaceRenameEventData, WorkspaceType, WorkspaceV2Data,
};

#[test]
fn test_parsing_unknown_event() {
let events = r#"unknowevent>>2"#;
let parsed = event_parser(events.into()).unwrap();
assert_eq!(parsed, vec![])
}

#[test]
fn test_parsing_bad_id() {
let events = r#"createworkspacev2>>NOT_A_NUMBER,name"#;
let error = event_parser(events.into()).err();
assert!(error.is_some());
assert_eq!(
format!("{}", error.unwrap()),
"Cannot parse workspace id: invalid integer error: invalid digit found in string"
)
}

#[test]
fn test_parsing_createworkspace() {
let events = r#"createworkspace>>2"#;
let parsed = event_parser(events.into()).unwrap();
assert_eq!(
parsed,
vec![Event::WorkspaceAdded(WorkspaceType::Regular("2".into()))]
)
}

#[test]
fn test_parsing_moveworkspace() {
let events = r#"moveworkspace>>2,monitor-1"#;
let parsed = event_parser(events.into()).unwrap();
assert_eq!(
parsed,
vec![Event::WorkspaceMoved(MonitorEventData {
monitor_name: "monitor-1".into(),
workspace: WorkspaceType::Regular("2".into()),
})]
)
}

#[test]
fn test_parsing_createworkspacev2() {
let events = r#"createworkspacev2>>2,name-2"#;
let parsed = event_parser(events.into()).unwrap();
assert_eq!(
parsed,
vec![Event::WorkspaceAddedV2(WorkspaceV2Data {
workspace_id: 2,
workspace_name: WorkspaceType::Regular("name-2".into()),
})]
)
}

#[test]
fn test_parsing_destroyworkspacev2() {
let events = r#"destroyworkspacev2>>2,name-2"#;
let parsed = event_parser(events.into()).unwrap();
assert_eq!(
parsed,
vec![Event::WorkspaceDeleted(WorkspaceV2Data {
workspace_id: 2,
workspace_name: WorkspaceType::Regular("name-2".into()),
})]
)
}

#[test]
fn test_parsing_createworkspacev2_special() {
let events = r#"createworkspacev2>>-98,special:name-2"#;
let parsed = event_parser(events.into()).unwrap();
assert_eq!(
parsed,
vec![Event::WorkspaceAddedV2(WorkspaceV2Data {
workspace_id: -98,
workspace_name: WorkspaceType::Special(Some("name-2".into())),
})]
)
}

#[test]
fn test_parsing_workspacerename() {
let events = r#"renameworkspace>>3,new name"#;
let parsed = event_parser(events.into()).unwrap();
assert_eq!(
parsed,
vec![Event::WorkspaceRename(WorkspaceRenameEventData {
workspace_id: 3,
workspace_name: "new name".into(),
})]
)
}

#[test]
fn test_parsing_multiple_events() {
let events = r#"createworkspace>>2
createworkspacev2>>2,named 2
"#;
let parsed = event_parser(events.into()).unwrap();
assert_eq!(
parsed,
vec![
Event::WorkspaceAdded(WorkspaceType::Regular("2".into())),
Event::WorkspaceAddedV2(WorkspaceV2Data {
workspace_id: 2,
workspace_name: WorkspaceType::Regular("named 2".into()),
}),
]
)
}
66 changes: 46 additions & 20 deletions src/event_listener/shared.rs → src/event_listener/shared/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ use once_cell::sync::Lazy;
use regex::{Error as RegexError, Regex};
use std::{fmt::Debug, pin::Pin};

#[cfg(test)]
mod event_parsing_test;

/// This trait provides shared behaviour for listener types
pub(crate) trait Listener: HasExecutor {
/// This method starts the event listener
Expand Down Expand Up @@ -227,7 +230,8 @@ pub(crate) type AsyncClosures<T> = Vec<AsyncClosure<T>>;
pub(crate) struct Events {
pub(crate) workspace_changed_events: Closures<WorkspaceType>,
pub(crate) workspace_added_events: Closures<WorkspaceType>,
pub(crate) workspace_destroyed_events: Closures<WorkspaceDestroyedEventData>,
pub(crate) workspace_added_v2_events: Closures<WorkspaceV2Data>,
pub(crate) workspace_destroyed_events: Closures<WorkspaceV2Data>,
pub(crate) workspace_moved_events: Closures<MonitorEventData>,
pub(crate) workspace_rename_events: Closures<WorkspaceRenameEventData>,
pub(crate) active_monitor_changed_events: Closures<MonitorEventData>,
Expand All @@ -253,7 +257,8 @@ pub(crate) struct Events {
pub(crate) struct AsyncEvents {
pub(crate) workspace_changed_events: AsyncClosures<WorkspaceType>,
pub(crate) workspace_added_events: AsyncClosures<WorkspaceType>,
pub(crate) workspace_destroyed_events: AsyncClosures<WorkspaceDestroyedEventData>,
pub(crate) workspace_added_v2_events: AsyncClosures<WorkspaceV2Data>,
pub(crate) workspace_destroyed_events: AsyncClosures<WorkspaceV2Data>,
pub(crate) workspace_moved_events: AsyncClosures<MonitorEventData>,
pub(crate) workspace_rename_events: AsyncClosures<WorkspaceRenameEventData>,
pub(crate) active_monitor_changed_events: AsyncClosures<MonitorEventData>,
Expand All @@ -275,15 +280,6 @@ pub(crate) struct AsyncEvents {
pub(crate) screencast_events: AsyncClosures<ScreencastEventData>,
}

/// Event data for destroyworkspacev2 event
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct WorkspaceDestroyedEventData {
/// Workspace Id
pub workspace_id: WorkspaceId,
/// Workspace name
pub workspace_name: String,
}

/// Event data for renameworkspace event
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct WorkspaceRenameEventData {
Expand Down Expand Up @@ -321,7 +317,7 @@ pub struct WindowMoveEvent {
}

/// The data for the event executed when opening a new window
#[derive(Clone, Debug)]
#[derive(Clone, Debug, PartialEq)]
pub struct WindowOpenEvent {
/// Window address
pub window_address: Address,
Expand Down Expand Up @@ -456,12 +452,22 @@ pub struct WindowFloatEventData {
pub is_floating: bool,
}

/// This struct workspacev2 creation and deletion data
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct WorkspaceV2Data {
/// Workspace Id
pub workspace_id: WorkspaceId,
/// Workspace name
pub workspace_name: WorkspaceType,
}

/// This enum holds every event type
#[derive(Debug, Clone)]
#[derive(Debug, Clone, PartialEq)]
pub(crate) enum Event {
WorkspaceChanged(WorkspaceType),
WorkspaceDeleted(WorkspaceDestroyedEventData),
WorkspaceDeleted(WorkspaceV2Data),
WorkspaceAdded(WorkspaceType),
WorkspaceAddedV2(WorkspaceV2Data),
WorkspaceMoved(MonitorEventData),
WorkspaceRename(WorkspaceRenameEventData),
ActiveWindowChangedV1(Option<(String, String)>),
Expand Down Expand Up @@ -502,6 +508,14 @@ fn parse_string_as_work(str: String) -> WorkspaceType {
}
}

fn parse_string_as_workspace_id(id: &str) -> crate::Result<WorkspaceId> {
id.parse::<WorkspaceId>().map_err(|e| {
HyprError::Internal(format!(
"Cannot parse workspace id: invalid integer error: {e}"
))
})
}

macro_rules! report_unknown {
($event:expr) => {
#[cfg(not(feature = "silent"))]
Expand Down Expand Up @@ -531,6 +545,7 @@ enum ParsedEventType {
WorkspaceChanged,
WorkspaceDeletedV2,
WorkspaceAdded,
WorkspaceAddedV2,
WorkspaceMoved,
WorkspaceRename,
ActiveWindowChangedV1,
Expand Down Expand Up @@ -560,7 +575,7 @@ static EVENT_SET: Lazy<Box<[(ParsedEventType, Regex)]>> = Lazy::new(|| {
(
ParsedEventType::WorkspaceChanged,
r"\bworkspace>>(?P<workspace>.*)",
),
),
(
ParsedEventType::WorkspaceDeletedV2,
r"destroyworkspacev2>>(?P<id>.*),(?P<name>.*)",
Expand All @@ -569,6 +584,10 @@ static EVENT_SET: Lazy<Box<[(ParsedEventType, Regex)]>> = Lazy::new(|| {
ParsedEventType::WorkspaceAdded,
r"createworkspace>>(?P<workspace>.*)",
),
(
ParsedEventType::WorkspaceAddedV2,
r"createworkspacev2>>(?P<id>.*),(?P<name>.*)",
),
(
ParsedEventType::WorkspaceMoved,
r"moveworkspace>>(?P<workspace>.*),(?P<monitor>.*)",
Expand Down Expand Up @@ -723,19 +742,26 @@ pub(crate) fn event_parser(event: String) -> crate::Result<Vec<Event>> {
};
Ok(Event::WorkspaceChanged(workspace))
}
ParsedEventType::WorkspaceDeletedV2 => Ok(Event::WorkspaceDeleted(WorkspaceDestroyedEventData { workspace_id: captures["id"].parse::<WorkspaceId>().map_err(|e| HyprError::Internal(format!("Workspace delete v2: invalid integer error: {e}")))?, workspace_name: captures["name"].to_string() })),
ParsedEventType::WorkspaceDeletedV2 => Ok(Event::WorkspaceDeleted(WorkspaceV2Data {
workspace_id: parse_string_as_workspace_id(&captures["id"])?,
workspace_name: parse_string_as_work(captures["name"].to_string())
})),
ParsedEventType::WorkspaceAdded => Ok(Event::WorkspaceAdded(parse_string_as_work(
captures["workspace"].to_string(),
))),
ParsedEventType::WorkspaceMoved => Ok(Event::WorkspaceMoved(MonitorEventData {
ParsedEventType::WorkspaceAddedV2 => Ok(Event::WorkspaceAddedV2(
WorkspaceV2Data {
workspace_id: parse_string_as_workspace_id(&captures["id"])?,
workspace_name: parse_string_as_work(captures["name"].to_string()),
}
)),
ParsedEventType::WorkspaceMoved => Ok(Event::WorkspaceMoved(MonitorEventData {
monitor_name: captures["monitor"].to_string(),
workspace: parse_string_as_work(captures["workspace"].to_string()),
})),
ParsedEventType::WorkspaceRename => {
Ok(Event::WorkspaceRename(WorkspaceRenameEventData {
workspace_id: captures["id"]
.parse::<WorkspaceId>()
.map_err(|e| HyprError::Internal(format!("Workspace rename: invalid integer error: {e}")))?,
workspace_id: parse_string_as_workspace_id(&captures["id"])?,
workspace_name: captures["name"].to_string(),
}))
}
Expand Down