commit 7381e34f95b46976a2630c036bac10c14d3b87ab
parent 64c6a344d08963a596503df7011defc231abcffd
Author: MTRNord <mtrnord1@gmail.com>
Date: Sat, 5 Dec 2020 18:12:29 +0100
feat: Add ability to have multiple actions beyond workspace managment
Took 1 hour 4 minutes
Diffstat:
9 files changed, 214 insertions(+), 65 deletions(-)
diff --git a/.idea/LaunchpadSwayControler.iml b/.idea/LaunchpadSwayControler.iml
@@ -4,6 +4,7 @@
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/launchpad_sway_controler/src" isTestSource="false" />
+ <sourceFolder url="file://$MODULE_DIR$/lsc_example_plugin/src" isTestSource="false" />
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="inheritedJdk" />
diff --git a/.idea/workspace.xml b/.idea/workspace.xml
@@ -2,17 +2,19 @@
<project version="4">
<component name="CargoProjects">
<cargoProject FILE="$PROJECT_DIR$/Cargo.toml" />
+ <cargoProject FILE="$PROJECT_DIR$/lsc_example_plugin/Cargo.toml" />
</component>
<component name="ChangeListManager">
<list default="true" id="cfc5721f-cc06-4df2-8555-3745919e4c56" name="Default Changelist" comment="">
- <change beforePath="$PROJECT_DIR$/.idea/.gitignore" beforeDir="false" />
- <change beforePath="$PROJECT_DIR$/.idea/misc.xml" beforeDir="false" />
- <change beforePath="$PROJECT_DIR$/.idea/modules.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/modules.xml" afterDir="false" />
+ <change afterPath="$PROJECT_DIR$/launchpad_sway_controler/src/plugin_actions/mod.rs" afterDir="false" />
+ <change afterPath="$PROJECT_DIR$/lsc_example_plugin/Cargo.toml" afterDir="false" />
+ <change afterPath="$PROJECT_DIR$/lsc_example_plugin/src/main.rs" afterDir="false" />
+ <change beforePath="$PROJECT_DIR$/.idea/LaunchpadSwayControler.iml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/LaunchpadSwayControler.iml" afterDir="false" />
+ <change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Cargo.lock" beforeDir="false" afterPath="$PROJECT_DIR$/Cargo.lock" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Cargo.toml" beforeDir="false" afterPath="$PROJECT_DIR$/Cargo.toml" afterDir="false" />
- <change beforePath="$PROJECT_DIR$/LaunchpadSwayControler.iml" beforeDir="false" />
- <change beforePath="$PROJECT_DIR$/src/main.rs" beforeDir="false" />
- <change beforePath="$PROJECT_DIR$/src/sway/mod.rs" beforeDir="false" />
+ <change beforePath="$PROJECT_DIR$/launchpad_sway_controler/src/main.rs" beforeDir="false" afterPath="$PROJECT_DIR$/launchpad_sway_controler/src/main.rs" afterDir="false" />
+ <change beforePath="$PROJECT_DIR$/launchpad_sway_controler/src/sway/mod.rs" beforeDir="false" afterPath="$PROJECT_DIR$/launchpad_sway_controler/src/sway/mod.rs" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
@@ -20,11 +22,13 @@
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="DarkyenusTimeTracker">
- <option name="totalTimeSeconds" value="4" />
+ <option name="totalTimeSeconds" value="4158" />
<option name="idleThresholdMs" value="60000" />
<option name="autoCountIdleSeconds" value="0" />
<option name="stopWhenIdleRatherThanPausing" value="true" />
<option name="pauseOtherTrackerInstances" value="false" />
+ <option name="gitIntegration" value="true" />
+ <option name="naggedAbout" value="1" />
</component>
<component name="Git.Settings">
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
@@ -48,9 +52,21 @@
<property name="project.structure.last.edited" value="Project" />
<property name="project.structure.proportion" value="0.0" />
<property name="project.structure.side.proportion" value="0.2" />
- <property name="settings.editor.selected.configurable" value="language.rust" />
+ <property name="settings.editor.selected.configurable" value="language.rust.rustfmt" />
</component>
- <component name="RunManager">
+ <component name="RunManager" selected="Cargo.Run">
+ <configuration name="Run lsc_example_plugin" type="CargoCommandRunConfiguration" factoryName="Cargo Command" temporary="true">
+ <option name="channel" value="DEFAULT" />
+ <option name="command" value="run --package lsc_example_plugin --bin lsc_example_plugin" />
+ <option name="allFeatures" value="false" />
+ <option name="emulateTerminal" value="false" />
+ <option name="backtrace" value="SHORT" />
+ <option name="workingDirectory" value="file://$PROJECT_DIR$/lsc_example_plugin" />
+ <envs />
+ <method v="2">
+ <option name="CARGO.BUILD_TASK_PROVIDER" enabled="true" />
+ </method>
+ </configuration>
<configuration name="Run" type="CargoCommandRunConfiguration" factoryName="Cargo Command" nameIsGenerated="true">
<option name="channel" value="DEFAULT" />
<option name="command" value="run -p launchpad_sway_controler" />
@@ -63,9 +79,21 @@
<option name="CARGO.BUILD_TASK_PROVIDER" enabled="true" />
</method>
</configuration>
+ <list>
+ <item itemvalue="Cargo.Run" />
+ <item itemvalue="Cargo.Run lsc_example_plugin" />
+ </list>
+ <recent_temporary>
+ <list>
+ <item itemvalue="Cargo.Run lsc_example_plugin" />
+ </list>
+ </recent_temporary>
</component>
<component name="RustProjectSettings">
+ <option name="runRustfmtOnSave" value="true" />
<option name="toolchainHomeDirectory" value="/usr/bin" />
+ <option name="useRustfmt" value="true" />
+ <option name="version" value="2" />
</component>
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
<component name="TaskManager">
@@ -75,10 +103,23 @@
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1607182424184</updated>
- <workItem from="1607182426972" duration="210000" />
+ <workItem from="1607182426972" duration="523000" />
+ <workItem from="1607182962786" duration="5115000" />
+ </task>
+ <task id="LOCAL-00001" summary="refactor: Use Workspace setup">
+ <created>1607182699156</created>
+ <option name="number" value="00001" />
+ <option name="presentableId" value="LOCAL-00001" />
+ <option name="project" value="LOCAL" />
+ <updated>1607182699156</updated>
</task>
+ <option name="localTasksCounter" value="2" />
<servers />
</component>
+ <component name="VcsManagerConfiguration">
+ <MESSAGE value="refactor: Use Workspace setup" />
+ <option name="LAST_COMMIT_MESSAGE" value="refactor: Use Workspace setup" />
+ </component>
<component name="XSLT-Support.FileAssociations.UIState">
<expand />
<select />
diff --git a/Cargo.lock b/Cargo.lock
@@ -491,6 +491,17 @@ dependencies = [
]
[[package]]
+name = "lsc_example_plugin"
+version = "0.1.0"
+dependencies = [
+ "color-eyre",
+ "futures-util",
+ "tokio",
+ "tracing",
+ "tracing-subscriber",
+]
+
+[[package]]
name = "matchers"
version = "0.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/Cargo.toml b/Cargo.toml
@@ -1,6 +1,7 @@
[workspace]
members = [
"launchpad_sway_controler",
+ "lsc_example_plugin"
]
[profile.dev.package.backtrace]
diff --git a/launchpad_sway_controler/src/main.rs b/launchpad_sway_controler/src/main.rs
@@ -1,22 +1,68 @@
-use crate::sway::{
- get_workspaces, listen_for_workspace_changes, LaunchpadWorkspaceMapping,
- WorkspaceLaunchpadMapping,
-};
+use crate::plugin_actions::PluginActions;
+use crate::sway::{get_workspaces, listen_for_workspace_changes};
use color_eyre::Result;
use midir::{Ignore, MidiInput, MidiOutputConnection};
use std::convert::{TryFrom, TryInto};
use std::env;
use std::io::stdin;
use std::process::exit;
+use strum::EnumIter;
use strum::IntoEnumIterator;
use swayipc_async::Connection;
use tokio::runtime::Runtime;
use tracing::*;
+mod plugin_actions;
mod sway;
+#[non_exhaustive]
+#[derive(Debug, Copy, Clone, EnumIter)]
+pub enum LaunchpadMapping {
+ Firefox = 119,
+ Chats = 118,
+ Email = 117,
+ Coding = 116,
+ Steam = 115,
+ Games = 114,
+ Youtube = 113,
+ Test = 112,
+}
+
+impl Into<PluginActions<'_>> for LaunchpadMapping {
+ fn into(self) -> PluginActions<'static> {
+ match self {
+ LaunchpadMapping::Firefox => PluginActions::SwayWorkspace("1:\u{e007}"),
+ LaunchpadMapping::Chats => PluginActions::SwayWorkspace("2:\u{f086}"),
+ LaunchpadMapping::Email => PluginActions::SwayWorkspace("3:\u{f0e0}"),
+ LaunchpadMapping::Coding => PluginActions::SwayWorkspace("5:\u{f1c9}"),
+ LaunchpadMapping::Steam => PluginActions::SwayWorkspace("11:\u{f1b6}"),
+ LaunchpadMapping::Games => PluginActions::SwayWorkspace("12:\u{f11b}"),
+ LaunchpadMapping::Youtube => PluginActions::SwayWorkspace("13:\u{f167}"),
+ LaunchpadMapping::Test => PluginActions::ExamplePlugin,
+ }
+ }
+}
+
+impl TryFrom<i32> for LaunchpadMapping {
+ type Error = ();
+
+ fn try_from(input: i32) -> Result<LaunchpadMapping, Self::Error> {
+ match input {
+ 119 => Ok(LaunchpadMapping::Firefox),
+ 118 => Ok(LaunchpadMapping::Chats),
+ 117 => Ok(LaunchpadMapping::Email),
+ 116 => Ok(LaunchpadMapping::Coding),
+ 115 => Ok(LaunchpadMapping::Steam),
+ 114 => Ok(LaunchpadMapping::Games),
+ 113 => Ok(LaunchpadMapping::Youtube),
+ 112 => Ok(LaunchpadMapping::Test),
+ _ => Err(()),
+ }
+ }
+}
+
fn reset_colors(conn_out: &mut MidiOutputConnection) {
- for value in WorkspaceLaunchpadMapping::iter() {
+ for value in LaunchpadMapping::iter() {
conn_out
.send(&[144, (value as i32).try_into().unwrap(), 15])
.unwrap();
@@ -64,13 +110,11 @@ async fn main() -> Result<()> {
move |_, message, _| {
if message[2] == 127 {
debug!("{:?}", message);
- if let Ok(v) = LaunchpadWorkspaceMapping::try_from(message[1] as i32) {
+ if let Ok(v) = LaunchpadMapping::try_from(message[1] as i32) {
rt.block_on(async {
- let mut connection = Connection::new().await.unwrap();
- connection
- .run_command(format!("workspace --no-auto-back-and-forth {}", v))
- .await
- .unwrap();
+ if let Err(e) = Into::<PluginActions>::into(v).run().await {
+ error!("Error while executing action: {}", e);
+ }
});
}
}
diff --git a/launchpad_sway_controler/src/plugin_actions/mod.rs b/launchpad_sway_controler/src/plugin_actions/mod.rs
@@ -0,0 +1,29 @@
+use color_eyre::Result;
+use swayipc_async::Connection;
+use tokio::io::AsyncWriteExt;
+use tokio::net::UnixStream;
+
+pub enum PluginActions<'a> {
+ SwayWorkspace(&'a str),
+ ExamplePlugin,
+}
+
+impl PluginActions<'_> {
+ pub async fn run(&self) -> Result<()> {
+ match self {
+ PluginActions::SwayWorkspace(workspace) => {
+ let mut connection = Connection::new().await?;
+ connection
+ .run_command(format!("workspace --no-auto-back-and-forth {}", workspace))
+ .await
+ .unwrap();
+ }
+ PluginActions::ExamplePlugin => {
+ let mut socket = UnixStream::connect("/run/lsc_example_plugin.sock").await?;
+
+ socket.write(b"test\n").await?;
+ }
+ }
+ Ok(())
+ }
+}
diff --git a/launchpad_sway_controler/src/sway/mod.rs b/launchpad_sway_controler/src/sway/mod.rs
@@ -3,8 +3,6 @@ use color_eyre::Result;
use futures_util::stream::StreamExt;
use midir::MidiOutput;
use std::convert::{TryFrom, TryInto};
-use std::fmt::{Display, Formatter};
-use strum::EnumIter;
use swayipc_async::{Connection, Event, EventType, WorkspaceChange};
use tracing::*;
@@ -31,48 +29,6 @@ pub async fn get_workspaces(connection: &mut Connection) -> Result<()> {
#[non_exhaustive]
#[derive(Debug, Copy, Clone)]
-pub enum LaunchpadWorkspaceMapping {
- Firefox,
- Chats,
- Email,
- Coding,
- Steam,
- Games,
- Youtube,
-}
-
-impl Display for LaunchpadWorkspaceMapping {
- fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
- match self {
- Self::Firefox => write!(f, "1:\u{e007}"),
- Self::Chats => write!(f, "2:\u{f086}"),
- Self::Email => write!(f, "3:\u{f0e0}"),
- Self::Coding => write!(f, "5:\u{f1c9}"),
- Self::Steam => write!(f, "11:\u{f1b6}"),
- Self::Games => write!(f, "12:\u{f11b}"),
- Self::Youtube => write!(f, "13:\u{f167}"),
- }
- }
-}
-
-impl TryFrom<i32> for LaunchpadWorkspaceMapping {
- type Error = ();
-
- fn try_from(input: i32) -> Result<LaunchpadWorkspaceMapping, Self::Error> {
- match input {
- 119 => Ok(LaunchpadWorkspaceMapping::Firefox),
- 118 => Ok(LaunchpadWorkspaceMapping::Chats),
- 117 => Ok(LaunchpadWorkspaceMapping::Email),
- 116 => Ok(LaunchpadWorkspaceMapping::Coding),
- 115 => Ok(LaunchpadWorkspaceMapping::Steam),
- 114 => Ok(LaunchpadWorkspaceMapping::Games),
- 113 => Ok(LaunchpadWorkspaceMapping::Youtube),
- _ => Err(()),
- }
- }
-}
-#[non_exhaustive]
-#[derive(Debug, Copy, Clone, EnumIter)]
pub enum WorkspaceLaunchpadMapping {
Firefox = 119,
Chats = 118,
diff --git a/lsc_example_plugin/Cargo.toml b/lsc_example_plugin/Cargo.toml
@@ -0,0 +1,14 @@
+[package]
+name = "lsc_example_plugin"
+version = "0.1.0"
+authors = ["MTRNord <mtrnord1@gmail.com>"]
+edition = "2018"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+tracing = "0.1"
+tracing-subscriber = "0.2"
+tokio = { version = "0.3.2", features = ["full"] }
+futures-util = "0.3.7"
+color-eyre = "0.5"
+\ No newline at end of file
diff --git a/lsc_example_plugin/src/main.rs b/lsc_example_plugin/src/main.rs
@@ -0,0 +1,51 @@
+use color_eyre::Result;
+use futures_util::StreamExt;
+use std::os::unix::fs::PermissionsExt;
+use std::path::Path;
+use std::{env, fs};
+use tokio::io::{AsyncBufReadExt, BufStream};
+use tokio::net::UnixListener;
+use tracing::*;
+
+#[tokio::main]
+async fn main() -> Result<()> {
+ // Enable the logging crates
+ color_eyre::install()?;
+ if let Err(_) = env::var("RUST_LOG") {
+ env::set_var("RUST_LOG", "INFO");
+ }
+ tracing_subscriber::fmt::init();
+
+ let socket_path = Path::new("/run/lsc_example_plugin.sock");
+ if socket_path.exists() {
+ fs::remove_file(socket_path)?;
+ }
+
+ // First we create a unix socket. This is required to be a) The same as the crate name and b) to be in /run
+ let mut listener = UnixListener::bind(socket_path).unwrap();
+
+ let mut perms = fs::metadata(socket_path)?.permissions();
+ perms.set_mode(0o666);
+ fs::set_permissions(socket_path, perms)?;
+ // This listens for new connections
+ while let Some(stream) = listener.next().await {
+ match stream {
+ Ok(stream) => {
+ tokio::spawn(async move {
+ println!("new client!");
+ let buffer = BufStream::new(stream);
+ let mut lines = buffer.lines();
+ while let Ok(line) = lines.next_line().await {
+ if let Some(line) = line {
+ println!("{}", line);
+ }
+ }
+ });
+ }
+ Err(e) => {
+ error!("Unix socket connection failed: {}", e);
+ }
+ }
+ }
+ Ok(())
+}