X-Git-Url: https://git.sur5r.net/?p=i3%2Fi3;a=blobdiff_plain;f=i3-save-tree;h=da5e6deddedb4bd1078f2b9c091fd8d9c3a0d626;hp=6ac3e1b1a2564b83e3dffa522fc01f9b657b2681;hb=HEAD;hpb=12885cb0ab4c4f24532d57ac7ca812686f070d79 diff --git a/i3-save-tree b/i3-save-tree index 6ac3e1b1..da5e6ded 100755 --- a/i3-save-tree +++ b/i3-save-tree @@ -13,11 +13,13 @@ use POSIX qw(locale_h); use File::Find; use File::Basename qw(basename); use File::Temp qw(tempfile); +use List::Util qw(first); use Getopt::Long; use Pod::Usage; use AnyEvent::I3; use JSON::XS; use List::Util qw(first); +use Encode qw(decode); use v5.10; use utf8; use open ':encoding(UTF-8)'; @@ -40,19 +42,27 @@ my $result = GetOptions( die "Could not parse command line options" unless $result; -if (!defined($workspace) && !defined($output)) { - die "One of --workspace or --output need to be specified"; -} - -unless (defined($workspace) ^ defined($output)) { +if (defined($workspace) && defined($output)) { die "Only one of --workspace or --output can be specified"; } +$workspace = decode('utf-8', $workspace); +$output = decode('utf-8', $output); + my $i3 = i3(); if (!$i3->connect->recv) { die "Could not connect to i3"; } +sub get_current_workspace { + my $current = first { $_->{focused} } @{$i3->get_workspaces->recv}; + return $current->{name}; +} + +if (!defined($workspace) && !defined($output)) { + $workspace = get_current_workspace(); +} + sub filter_containers { my ($tree, $pred) = @_; @@ -88,6 +98,8 @@ my %allowed_keys = map { ($_, 1) } qw( name geometry window_properties + marks + rect ); sub strip_containers { @@ -105,12 +117,13 @@ sub strip_containers { delete $tree->{geometry} if zero_rect($tree->{geometry}); + # Retain the rect for floating containers to keep their positions. + delete $tree->{rect} unless $tree->{type} eq 'floating_con'; + delete $tree->{current_border_width} if $tree->{current_border_width} == -1; for my $key (keys %$tree) { - next if exists($allowed_keys{$key}); - - delete $tree->{$key}; + delete $tree->{$key} unless exists($allowed_keys{$key}); } for my $key (qw(nodes floating_nodes)) { @@ -149,12 +162,16 @@ sub dump_containers { say "$ws// $desc with " . @{$tree->{nodes}} . " children"; } - # Turn “window_properties” into “swallows” expressions. - my $swallows = {}; - for my $property (keys %{$tree->{window_properties}}) { - $swallows->{$property} = '^' . quotemeta($tree->{window_properties}->{$property}) . '$'; + # Turn “window_properties” into “swallows” expressions, but only for leaf + # nodes. It only makes sense for leaf nodes to swallow anything. + if (leaf_node($tree)) { + my $swallows = {}; + for my $property (keys %{$tree->{window_properties}}) { + $swallows->{$property} = '^' . quotemeta($tree->{window_properties}->{$property}) . '$' + if $property ne 'transient_for'; + } + $tree->{swallows} = [ $swallows ]; } - $tree->{swallows} = [ $swallows ]; delete $tree->{window_properties}; my @keys = sort keys %$tree; @@ -208,7 +225,7 @@ my $tree = $i3->get_tree->recv; my $dump; if (defined($workspace)) { $dump = filter_containers($tree, sub { - $_->{type} eq 'workspace' && $_->{name} eq $workspace + $_->{type} eq 'workspace' && ($_->{name} eq $workspace || ($workspace =~ /^\d+$/ && $_->{num} eq $workspace)) }); } else { $dump = filter_containers($tree, sub { @@ -238,7 +255,7 @@ for my $key (qw(nodes floating_nodes)) { =head1 SYNOPSIS - i3-save-tree [--workspace=name] [--output=name] + i3-save-tree [--workspace=name|number] [--output=name] =head1 DESCRIPTION @@ -251,19 +268,20 @@ specification. When a window is mapped (made visible on the screen) that matches the specification, i3 will put it into that place and kill the placeholder. +If neither argument is specified, the currently focused workspace will be used. + =head1 OPTIONS =over -=item B<--workspace=name> +=item B<--workspace=name|number> -Specifies the workspace that should be dumped, e.g. 1. Either this or --output -need to be specified. +Specifies the workspace that should be dumped, e.g. 1. This can either be a +name or the number of a workspace. =item B<--output=name> -Specifies the output that should be dumped, e.g. LVDS-1. Either this or ---workspace need to be specified. +Specifies the output that should be dumped, e.g. LVDS-1. =back