summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.config/i3/config5
-rw-r--r--.config/sway/config5
-rw-r--r--perl5/Local/Desktop.pm60
-rwxr-xr-xscripts/desktop/i3status-wrapper4
4 files changed, 66 insertions, 8 deletions
diff --git a/.config/i3/config b/.config/i3/config
index fdc6a2c5..2104b9f7 100644
--- a/.config/i3/config
+++ b/.config/i3/config
@@ -311,6 +311,11 @@ bar {
binding_mode #000000 #900000 #FFFFF6
}
+ # We don't set workspace_buttons to "no" even though we start off with
+ # a single workspace (see i3status-wrapper) because under Sway that
+ # can trigger a bug which means the button display doesn't get
+ # properly updated.
+
position bottom
strip_workspace_numbers yes
diff --git a/.config/sway/config b/.config/sway/config
index 0c383426..2b6649df 100644
--- a/.config/sway/config
+++ b/.config/sway/config
@@ -323,6 +323,11 @@ bar {
binding_mode #000000BB #900000BB #FFFFF6BB
}
+ # We don't set workspace_buttons to "no" even though we start off with
+ # a single workspace (see i3status-wrapper) because under Sway that
+ # can trigger a bug which means the button display doesn't get
+ # properly updated.
+
position bottom
strip_workspace_numbers yes
status_edge_padding 11
diff --git a/perl5/Local/Desktop.pm b/perl5/Local/Desktop.pm
index c5af6fc2..616ee89e 100644
--- a/perl5/Local/Desktop.pm
+++ b/perl5/Local/Desktop.pm
@@ -33,6 +33,7 @@ use List::Util "first";
our @EXPORT = qw(
$wmipc wmipc
fresh_workspace
+ compact_workspaces
select_wallpaper_files
ensure_resize_for_current_outputs
resize_for_current_outputs
@@ -44,6 +45,13 @@ sub wmipc { system "$wmipc -q " . join ", ", @_ }
my $output_re = qr/ ([0-9]+)x([0-9]+)\+([0-9]+)\+([0-9]+) /;
+my @all_workspaces = (
+ "1", "2", "3", "4", "5", "6",
+ "7", "8", "9", "10", "11:F1", "12:F2",
+ "13:F3", "14:F4", "15:F5", "16:F6", "17:F7", "18:F8",
+ "19:F9", "20:F10", "21:F11", "22:F12"
+);
+
=head fresh_workspace($send)
Switch to the next free workspace, if any. Return the name of that workspace,
@@ -53,12 +61,7 @@ the fresh workspace instead of switching focus there.
=cut
sub fresh_workspace {
- my %current_names = map +($_->{name}, undef),
- @{ decode_json `$wmipc -t get_workspaces` };
- my $next_free_workspace = first { not exists $current_names{$_} }
- "1", "2", "3", "4", "5", "6", "7", "8",
- "9", "10", "11:F1", "12:F2", "13:F3", "14:F4", "15:F5",
- "16:F6", "17:F7", "18:F8", "19:F9", "20:F10", "21:F11", "22:F12";
+ my $next_free_workspace = compact_workspaces(leave_gap => 1);
if ($next_free_workspace) {
my @cmds;
@@ -78,7 +81,48 @@ sub fresh_workspace {
wmipc @cmds;
}
$next_free_workspace
- }
+}
+
+=head compact_workspaces(%opts)
+
+Rename workspaces so as to remove gaps in the sequence of workspaces, and show
+or hide workspace buttons depending on whether there is >1 workspace.
+
+If C<$opts{leave_gap}>, ensure there is a gap of one workspace after the
+currently focused workspace and return the name of the gap workspace, or just
+return undef if there is no space for a gap.
+
+=cut
+
+sub compact_workspaces {
+ my %opts = @_;
+ my @workspaces = @{ decode_json `$wmipc -t get_workspaces` };
+ @workspaces < @all_workspaces or return;
+ my $buttons_cmd
+ = "bar bar-0 workspace_buttons " . (@workspaces > 1 ? "yes" : "no");
+ my ($current_workspace, $gap_workspace);
+ if ($opts{leave_gap}) {
+ $_->{focused} and $current_workspace = $_->{name}, last
+ for @workspaces
+ }
+
+ my ($i, @cmds);
+ while (my $next = shift @workspaces) {
+ my $workspace = $all_workspaces[$i++];
+ $opts{leave_gap}
+ and $next->{name} eq $current_workspace
+ and $gap_workspace = $all_workspaces[$i++];
+ next if $next->{name} eq $workspace;
+ my $pair = [$next->{name}, $workspace];
+ _wsnum($next->{name}) > _wsnum($workspace)
+ ? push @cmds, $pair
+ : unshift @cmds, $pair
+ }
+
+ wmipc $buttons_cmd, map "rename workspace $_->[0] to $_->[1]", @cmds;
+
+ $opts{leave_gap} and $gap_workspace
+}
=head select_wallpaper_files(@files)
@@ -188,4 +232,6 @@ sub _get_screen_size {
$canvas =~ /current ([0-9]+) x ([0-9]+)/;
}
+sub _wsnum { (split /:/, $_[0])[0] }
+
1;
diff --git a/scripts/desktop/i3status-wrapper b/scripts/desktop/i3status-wrapper
index 5c4a25c8..af487b0c 100755
--- a/scripts/desktop/i3status-wrapper
+++ b/scripts/desktop/i3status-wrapper
@@ -78,7 +78,7 @@ unless (fork // die "couldn't fork()!") {
my $caffeinated_id;
open my $events, "-|",
- $wmipc, "-t", "subscribe", "-m", '[ "window" ]';
+ $wmipc, "-t", "subscribe", "-m", '[ "window", "workspace" ]';
while (my $event = decode_json <$events>) {
if ($event->{change} eq "mark") {
@@ -91,5 +91,7 @@ while (my $event = decode_json <$events>) {
undef $caffeinated_id, undef $info{caffeinated_name};
kill USR1 => $i3status;
}
+ } elsif ($event->{change} eq "init" or $event->{change} eq "empty") {
+ compact_workspaces;
}
}