#!/usr/bin/perl use strict; use warnings; # Workspace to push the terminal to when dismissed my $hidden = 'grave'; # Terminal application used for pop-up (swaymsg 'name') my $term = 'uxterm'; use JSON::XS; my $json = JSON::XS->new(); my $raw = join("\n",`swaymsg -t get_tree`); my $root = $json->decode($raw); # Get focused my $display = $root->{focus}->[0]; my ($workspace, $term_id, $term_ws); foreach my $d (@{$root->{nodes}}) { # If both the current workspace and terminal have been found, nothing else to look for if (defined($workspace) && defined($term_id)) { last; # If the display from this iteration of the loop is in focus, look for the active workspace } elsif ($d->{id} eq $display) { foreach my $w (@{$d->{nodes}}) { # Again, if both found, skip if (defined($workspace) && defined($term_id)) { last; # Otherwise if the current workspace is active, mark it } elsif ($w->{id} eq $d->{focus}->[0]) { $workspace = $w->{name}; } # In any case, look for the terminal app foreach my $n (@{$w->{floating_nodes}}) { if ($n->{name} eq $term) { $term_id = $n->{id}; $term_ws = $w->{name}; last; } } } # All other displays only need to be quickly searched for the term_id } else { foreach my $w (@{$d->{nodes}}) { if (defined($term_id)) { last; } foreach my $n (@{$w->{floating_nodes}}) { if ($n->{name} eq $term) { $term_id = $n->{id}; $term_ws = $w->{name}; last; } } } } } print "Active workspace = $workspace\nTerminal ID = $term_id\nTerminal WS = $term_ws\n"; # If there is no terminal found, spawn one if (!defined($term_id)) { print "No term running, starting one\n"; exec $term # If the current workspace is known and terminal isn't on it, bring and give focus } elsif ($workspace != $term_ws) { print "Term not on current workspace, bringing it\n"; `swaymsg "[con_id=$term_id]" move workspace $workspace`; `swaymsg "[con_id=$term_id]" focus`; # Otherwise hide it from whereever it is } else { print "Term is on current workspace or lost, moving to $hidden\n"; `swaymsg "[con_id=$term_id]" move workspace $hidden`; }