summaryrefslogtreecommitdiff
path: root/perl5
diff options
context:
space:
mode:
authorSean Whitton <spwhitton@spwhitton.name>2024-01-14 13:26:00 +0000
committerSean Whitton <spwhitton@spwhitton.name>2024-01-14 13:28:13 +0000
commit37dc2639a9453c0f24ed48cedb11223a6fb937a7 (patch)
treefd6d0bcfac8785bbd6f36021f8367c7ac8270487 /perl5
parentfdf056d799b974d878ba77cb96056125a0510e92 (diff)
downloaddotfiles-37dc2639a9453c0f24ed48cedb11223a6fb937a7.tar.gz
add & use Local::Desktop::WMIPC class for i3/Sway IPC connections
Diffstat (limited to 'perl5')
-rw-r--r--perl5/Local/Desktop.pm14
-rw-r--r--perl5/Local/Desktop/WMIPC.pm61
2 files changed, 67 insertions, 8 deletions
diff --git a/perl5/Local/Desktop.pm b/perl5/Local/Desktop.pm
index 5f30e507..a9051b02 100644
--- a/perl5/Local/Desktop.pm
+++ b/perl5/Local/Desktop.pm
@@ -20,6 +20,7 @@ package Local::Desktop;
use 5.028;
use strict;
use warnings;
+use lib "$ENV{HOME}/src/dotfiles/perl5";
use Carp;
use JSON;
@@ -29,9 +30,9 @@ use File::Spec::Functions "rel2abs";
use Exporter "import";
use File::Copy;
use List::Util "first";
+use Local::Desktop::WMIPC;
our @EXPORT = qw(
- $wmipc wmipc
@all_workspaces
fresh_workspace
compact_workspaces
@@ -40,10 +41,6 @@ our @EXPORT = qw(
resize_for_current_outputs
pick_random_wallpapers );
-`sh -c "command -v i3-msg"`;
-our $wmipc = $? == 0 ? "i3-msg" : "swaymsg";
-sub wmipc { system $wmipc, "-q", join "; ", @_ }
-
my $output_re = qr/ ([0-9]+)x([0-9]+)\+([0-9]+)\+([0-9]+) /;
our @all_workspaces = (
@@ -79,7 +76,7 @@ sub fresh_workspace {
push @cmds, "workspace $next_free_workspace";
push @cmds, "workspace back_and_forth" unless $opts{go};
- wmipc @cmds;
+ Local::Desktop::WMIPC->new->cmd(@cmds);
}
$next_free_workspace
}
@@ -96,7 +93,8 @@ return undef if there is no space for a gap.
sub compact_workspaces {
my %opts = @_;
- my @workspaces = @{ decode_json `$wmipc -t get_workspaces` };
+ my $wmipc = Local::Desktop::WMIPC->new;
+ my @workspaces = $wmipc->get_workspaces->@*;
@workspaces < @all_workspaces or return;
my ($current_workspace, $gap_workspace);
if ($opts{leave_gap}) {
@@ -117,7 +115,7 @@ sub compact_workspaces {
: unshift @cmds, $pair
}
- wmipc map "rename workspace $_->[0] to $_->[1]", @cmds;
+ $wmipc->cmd(map "rename workspace $_->[0] to $_->[1]", @cmds);
$opts{leave_gap} and $gap_workspace
}
diff --git a/perl5/Local/Desktop/WMIPC.pm b/perl5/Local/Desktop/WMIPC.pm
new file mode 100644
index 00000000..effa7797
--- /dev/null
+++ b/perl5/Local/Desktop/WMIPC.pm
@@ -0,0 +1,61 @@
+package Local::Desktop::WMIPC;
+use 5.036;
+
+# Copyright (C) 2024 Sean Whitton
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or (at
+# your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+use IO::Socket::UNIX;
+use parent "IO::Socket::UNIX";
+use Exporter "import";
+use overload "<>" => sub { shift->recv };
+use JSON;
+use Encode "encode";
+
+our @EXPORT_OK = ();
+
+sub new ($class, $socket = $ENV{SWAYSOCK} || $ENV{I3SOCK}) {
+ bless IO::Socket::UNIX->new(Type => SOCK_STREAM, Peer => $socket)
+ => $class;
+}
+
+sub send ($self, $type, $payload = "") {
+ $payload = encode "UTF-8", $payload;
+ my $head = pack "A6ll", "i3-ipc", length $payload, $type;
+ $self->SUPER::send($head.$payload);
+ return $self->recv;
+}
+
+sub recv ($self) {
+ my $buf;
+ $self->SUPER::recv($buf, 14);
+ length $buf or die "WMIPC socket EOF";
+ my $len = (unpack "A6ll", $buf)[1];
+ $self->SUPER::recv($buf, $len);
+ return decode_json $buf;
+}
+
+sub subscribe ($self, @event_types) {
+ my $reply = $self->send(2, encode_json \@event_types);
+ $reply->{success} or die "WMIPC subscription failed";
+}
+
+sub cmd ($self, @cmds) { $self->send(0, join "; ", @cmds) }
+
+sub get_tree { shift->send(4) }
+sub get_workspaces { shift->send(1) }
+
+sub send_tick ($self, $payload = "") { $self->send(10, $payload) }
+
+1;