sway-launchpad

A small rust script to switch sway workspaces using a Launchpad S
git clone git://archive.git.mtrnord.blog/MTRNord/sway-launchpad.git
Log | Files | Refs | LICENSE

commit 64c6a344d08963a596503df7011defc231abcffd
parent cd23caab1b568e4706af5d1bb0dced4b973f6584
Author: MTRNord <mtrnord1@gmail.com>
Date:   Sat,  5 Dec 2020 16:38:19 +0100

refactor: Use Workspace setup

Diffstat:
D.idea/.gitignore | 6------
A.idea/LaunchpadSwayControler.iml | 13+++++++++++++
D.idea/misc.xml | 7-------
M.idea/modules.xml | 2+-
A.idea/workspace.xml | 87+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
MCargo.lock | 20+++++---------------
MCargo.toml | 22++++------------------
DLaunchpadSwayControler.iml | 13-------------
Alaunchpad_sway_controler/Cargo.toml | 18++++++++++++++++++
Rsrc/main.rs -> launchpad_sway_controler/src/main.rs | 0
Alaunchpad_sway_controler/src/sway/mod.rs | 133+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dsrc/sway/mod.rs | 128-------------------------------------------------------------------------------
12 files changed, 261 insertions(+), 188 deletions(-)

diff --git a/.idea/.gitignore b/.idea/.gitignore @@ -1,6 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml -# Datasource local storage ignored files -/dataSources/ -/dataSources.local.xml diff --git a/.idea/LaunchpadSwayControler.iml b/.idea/LaunchpadSwayControler.iml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="UTF-8"?> +<module type="JAVA_MODULE" version="4"> + <component name="NewModuleRootManager" inherit-compiler-output="true"> + <exclude-output /> + <content url="file://$MODULE_DIR$"> + <sourceFolder url="file://$MODULE_DIR$/launchpad_sway_controler/src" isTestSource="false" /> + <excludeFolder url="file://$MODULE_DIR$/target" /> + </content> + <orderEntry type="inheritedJdk" /> + <orderEntry type="sourceFolder" forTests="false" /> + </component> +</module> +\ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml @@ -1,6 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<project version="4"> - <component name="ProjectRootManager"> - <output url="file://$PROJECT_DIR$/out" /> - </component> -</project> -\ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml @@ -2,7 +2,7 @@ <project version="4"> <component name="ProjectModuleManager"> <modules> - <module fileurl="file://$PROJECT_DIR$/LaunchpadSwayControler.iml" filepath="$PROJECT_DIR$/LaunchpadSwayControler.iml" /> + <module fileurl="file://$PROJECT_DIR$/.idea/LaunchpadSwayControler.iml" filepath="$PROJECT_DIR$/.idea/LaunchpadSwayControler.iml" /> </modules> </component> </project> \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml @@ -0,0 +1,86 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project version="4"> + <component name="CargoProjects"> + <cargoProject FILE="$PROJECT_DIR$/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 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" /> + </list> + <option name="SHOW_DIALOG" value="false" /> + <option name="HIGHLIGHT_CONFLICTS" value="true" /> + <option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" /> + <option name="LAST_RESOLUTION" value="IGNORE" /> + </component> + <component name="DarkyenusTimeTracker"> + <option name="totalTimeSeconds" value="4" /> + <option name="idleThresholdMs" value="60000" /> + <option name="autoCountIdleSeconds" value="0" /> + <option name="stopWhenIdleRatherThanPausing" value="true" /> + <option name="pauseOtherTrackerInstances" value="false" /> + </component> + <component name="Git.Settings"> + <option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" /> + </component> + <component name="KotlinMultiplatform"> + <allAvailableExecutables /> + </component> + <component name="MacroExpansionManager"> + <option name="directoryName" value="ho9ja37x" /> + </component> + <component name="ProjectId" id="1lFAMettmogwp3he1jrYeQkqtz8" /> + <component name="ProjectViewState"> + <option name="hideEmptyMiddlePackages" value="true" /> + <option name="showLibraryContents" value="true" /> + </component> + <component name="PropertiesComponent"> + <property name="RunOnceActivity.OpenProjectViewOnStart" value="true" /> + <property name="RunOnceActivity.ShowReadmeOnStart" value="true" /> + <property name="WebServerToolWindowFactoryState" value="false" /> + <property name="org.rust.cargo.project.model.PROJECT_DISCOVERY" value="true" /> + <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" /> + </component> + <component name="RunManager"> + <configuration name="Run" type="CargoCommandRunConfiguration" factoryName="Cargo Command" nameIsGenerated="true"> + <option name="channel" value="DEFAULT" /> + <option name="command" value="run -p launchpad_sway_controler" /> + <option name="allFeatures" value="false" /> + <option name="emulateTerminal" value="false" /> + <option name="backtrace" value="SHORT" /> + <option name="workingDirectory" value="file://$PROJECT_DIR$" /> + <envs /> + <method v="2"> + <option name="CARGO.BUILD_TASK_PROVIDER" enabled="true" /> + </method> + </configuration> + </component> + <component name="RustProjectSettings"> + <option name="toolchainHomeDirectory" value="/usr/bin" /> + </component> + <component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" /> + <component name="TaskManager"> + <task active="true" id="Default" summary="Default task"> + <changelist id="cfc5721f-cc06-4df2-8555-3745919e4c56" name="Default Changelist" comment="" /> + <created>1607182424184</created> + <option name="number" value="Default" /> + <option name="presentableId" value="Default" /> + <updated>1607182424184</updated> + <workItem from="1607182426972" duration="210000" /> + </task> + <servers /> + </component> + <component name="XSLT-Support.FileAssociations.UIState"> + <expand /> + <select /> + </component> +</project> +\ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock @@ -201,15 +201,6 @@ dependencies = [ ] [[package]] -name = "cloudabi" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4344512281c643ae7638bbabc3af17a11307803ec8f0fcad9fae512a8bf36467" -dependencies = [ - "bitflags", -] - -[[package]] name = "color-eyre" version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -669,12 +660,11 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c361aa727dd08437f2f1447be8b59a33b0edd15e0fcee698f935613d9efbca9b" +checksum = "d7c6d9b8427445284a09c55be860a15855ab580a417ccad9da88f5a06787ced0" dependencies = [ - "cfg-if 0.1.10", - "cloudabi", + "cfg-if 1.0.0", "instant", "libc", "redox_syscall", @@ -916,9 +906,9 @@ checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" [[package]] name = "smallvec" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7acad6f34eb9e8a259d3283d1e8c1d34d7415943d4895f65cc73813c7396fc85" +checksum = "ae524f056d7d770e174287294f562e95044c68e88dec909a00d2094805db9d75" [[package]] name = "socket2" diff --git a/Cargo.toml b/Cargo.toml @@ -1,21 +1,7 @@ -[package] -name = "launchpad_sway_controler" -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] -midir = "0.7" -swayipc-async = "2.0.0-alpha.1" -tokio = { version = "0.3.2", features = ["full"] } -futures-util = "0.3.7" -color-eyre = "0.5" -alsa = "0.4.3" -strum = { version = "0.20", features = ["derive"] } -tracing = "0.1" -tracing-subscriber = "0.2" +[workspace] +members = [ + "launchpad_sway_controler", +] [profile.dev.package.backtrace] opt-level = 3 \ No newline at end of file diff --git a/LaunchpadSwayControler.iml b/LaunchpadSwayControler.iml @@ -1,12 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<module type="RUST_MODULE" version="4"> - <component name="NewModuleRootManager" inherit-compiler-output="true"> - <exclude-output /> - <content url="file://$MODULE_DIR$"> - <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" /> - <excludeFolder url="file://$MODULE_DIR$/target" /> - </content> - <orderEntry type="inheritedJdk" /> - <orderEntry type="sourceFolder" forTests="false" /> - </component> -</module> -\ No newline at end of file diff --git a/launchpad_sway_controler/Cargo.toml b/launchpad_sway_controler/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "launchpad_sway_controler" +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] +midir = "0.7" +swayipc-async = "2.0.0-alpha.1" +tokio = { version = "0.3.2", features = ["full"] } +futures-util = "0.3.7" +color-eyre = "0.5" +alsa = "0.4.3" +strum = { version = "0.20", features = ["derive"] } +tracing = "0.1" +tracing-subscriber = "0.2" diff --git a/src/main.rs b/launchpad_sway_controler/src/main.rs diff --git a/launchpad_sway_controler/src/sway/mod.rs b/launchpad_sway_controler/src/sway/mod.rs @@ -0,0 +1,133 @@ +use crate::reset_colors; +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::*; + +pub async fn get_workspaces(connection: &mut Connection) -> Result<()> { + let workspaces = connection.get_workspaces().await?; + debug!("{:#?}", workspaces); + + for space in workspaces { + if space.focused { + let midi_out = MidiOutput::new("My Test Output")?; + let midi_out_ports = midi_out.ports(); + let out_port = midi_out_ports.get(1).unwrap(); + let mut conn_out = midi_out.connect(out_port, "midir-test").unwrap(); + if let Ok(workspace) = WorkspaceLaunchpadMapping::try_from(space.num) { + reset_colors(&mut conn_out); + conn_out + .send(&[144, (workspace as i32).try_into().unwrap(), 28]) + .unwrap(); + } + } + } + Ok(()) +} + +#[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, + Email = 117, + Coding = 116, + Steam = 115, + Games = 114, + Youtube = 113, +} + +impl TryFrom<i32> for WorkspaceLaunchpadMapping { + type Error = (); + + fn try_from(input: i32) -> Result<WorkspaceLaunchpadMapping, Self::Error> { + match input { + 1 => Ok(WorkspaceLaunchpadMapping::Firefox), + 2 => Ok(WorkspaceLaunchpadMapping::Chats), + 3 => Ok(WorkspaceLaunchpadMapping::Email), + 5 => Ok(WorkspaceLaunchpadMapping::Coding), + 11 => Ok(WorkspaceLaunchpadMapping::Steam), + 12 => Ok(WorkspaceLaunchpadMapping::Games), + 13 => Ok(WorkspaceLaunchpadMapping::Youtube), + _ => Err(()), + } + } +} + +pub async fn listen_for_workspace_changes() -> Result<()> { + // subscribe to a workspace events. + let subs = [EventType::Workspace]; + let mut events = Connection::new().await?.subscribe(&subs).await?; + let midi_out = MidiOutput::new("My Test Output")?; + let midi_out_ports = midi_out.ports(); + let out_port = midi_out_ports.get(1).unwrap(); + let mut conn_out = midi_out.connect(out_port, "midir-test").unwrap(); + while let Some(event) = events.next().await { + if let Ok(ref event) = event { + if let Event::Workspace(ref w) = event { + if w.change == WorkspaceChange::Focus { + if let Some(v) = &w.current { + if let Some(num) = v.num { + // TODO make ? work + if let Ok(workspace) = WorkspaceLaunchpadMapping::try_from(num) { + reset_colors(&mut conn_out); + conn_out + .send(&[144, (workspace as i32).try_into().unwrap(), 28]) + .unwrap(); + } + } + } + } + } + } + //println!("{:?}", event) + } + + Ok(()) +} diff --git a/src/sway/mod.rs b/src/sway/mod.rs @@ -1,128 +0,0 @@ -use crate::reset_colors; -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::*; - -pub async fn get_workspaces(connection: &mut Connection) -> Result<()> { - let workspaces = connection.get_workspaces().await?; - debug!("{:#?}", workspaces); - - for space in workspaces { - if space.focused { - let midi_out = MidiOutput::new("My Test Output")?; - let midi_out_ports = midi_out.ports(); - let out_port = midi_out_ports.get(1).unwrap(); - let mut conn_out = midi_out.connect(out_port, "midir-test").unwrap(); - if let Ok(workspace) = WorkspaceLaunchpadMapping::try_from(space.num) { - reset_colors(&mut conn_out); - conn_out - .send(&[144, (workspace as i32).try_into().unwrap(), 28]) - .unwrap(); - } - } - } - Ok(()) -} - -#[non_exhaustive] -#[derive(Debug, Copy, Clone)] -pub enum LaunchpadWorkspaceMapping { - Firefox, - Chats, - Email, - 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::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::Steam), - 115 => Ok(LaunchpadWorkspaceMapping::Games), - 114 => Ok(LaunchpadWorkspaceMapping::Youtube), - _ => Err(()), - } - } -} -#[non_exhaustive] -#[derive(Debug, Copy, Clone, EnumIter)] -pub enum WorkspaceLaunchpadMapping { - Firefox = 119, - Chats = 118, - Email = 117, - Steam = 116, - Games = 115, - Youtube = 114, -} - -impl TryFrom<i32> for WorkspaceLaunchpadMapping { - type Error = (); - - fn try_from(input: i32) -> Result<WorkspaceLaunchpadMapping, Self::Error> { - match input { - 1 => Ok(WorkspaceLaunchpadMapping::Firefox), - 2 => Ok(WorkspaceLaunchpadMapping::Chats), - 3 => Ok(WorkspaceLaunchpadMapping::Email), - 11 => Ok(WorkspaceLaunchpadMapping::Steam), - 12 => Ok(WorkspaceLaunchpadMapping::Games), - 13 => Ok(WorkspaceLaunchpadMapping::Youtube), - _ => Err(()), - } - } -} - -pub async fn listen_for_workspace_changes() -> Result<()> { - // subscribe to a workspace events. - let subs = [EventType::Workspace]; - let mut events = Connection::new().await?.subscribe(&subs).await?; - let midi_out = MidiOutput::new("My Test Output")?; - let midi_out_ports = midi_out.ports(); - let out_port = midi_out_ports.get(1).unwrap(); - let mut conn_out = midi_out.connect(out_port, "midir-test").unwrap(); - while let Some(event) = events.next().await { - if let Ok(ref event) = event { - if let Event::Workspace(ref w) = event { - if w.change == WorkspaceChange::Focus { - if let Some(v) = &w.current { - if let Some(num) = v.num { - // TODO make ? work - if let Ok(workspace) = WorkspaceLaunchpadMapping::try_from(num) { - reset_colors(&mut conn_out); - conn_out - .send(&[144, (workspace as i32).try_into().unwrap(), 28]) - .unwrap(); - } - } - } - } - } - } - //println!("{:?}", event) - } - - Ok(()) -}