summaryrefslogtreecommitdiffstats
path: root/i3
diff options
context:
space:
mode:
Diffstat (limited to 'i3')
-rwxr-xr-xi3/.bin/i3-switch-workspace137
-rwxr-xr-xi3/.bin/kill-focused49
-rw-r--r--i3/.config/i3/config77
-rw-r--r--i3/.config/i3/terminal-workspace.json125
4 files changed, 388 insertions, 0 deletions
diff --git a/i3/.bin/i3-switch-workspace b/i3/.bin/i3-switch-workspace
new file mode 100755
index 0000000..b54afa1
--- /dev/null
+++ b/i3/.bin/i3-switch-workspace
@@ -0,0 +1,137 @@
+#!/usr/bin/env perl
+use strict;
+use warnings;
+use 5.014;
+
+use IO::Socket::UNIX;
+use JSON::PP;
+
+my $json = JSON::PP->new;
+
+my $virtual_workspace = 'virtual';
+
+my %message_types = (
+ command => 0,
+ get_workspaces => 1,
+ subscribe => 2,
+ get_outputs => 3,
+ get_tree => 4,
+ get_marks => 5,
+ get_bar_config => 6,
+ get_version => 7,
+);
+
+my %message_codes = (reverse %message_types);
+
+my $dir = $ARGV[0];
+
+chomp(my $path = qx(i3 --get-socketpath));
+my $sock = IO::Socket::UNIX->new(Peer => $path);
+
+my $workspace_data = $json->decode(i3_msg('get_workspaces'));
+my $tree_data = $json->decode(i3_msg('get_tree'));
+
+my $first = 99999;
+my $last = -99999;
+my $cur;
+my $cur_name;
+my $virtual_output;
+
+for my $i (0..$#$workspace_data) {
+ my $num = $workspace_data->[$i]{num};
+ if ($workspace_data->[$i]{focused}) {
+ $cur = $num;
+ $cur_name = $workspace_data->[$i]{name};
+ if ($cur_name eq $virtual_workspace) {
+ $virtual_output = $workspace_data->[$i]{output};
+ }
+ }
+
+ my $workspace_tree = find_workspace($tree_data, $num);
+ next unless
+ @{ $workspace_tree->{nodes} } ||
+ @{ $workspace_tree->{floating_nodes} };
+
+ $first = $num if $num < $first;
+ $last = $num if $num > $last;
+}
+
+if ($dir eq 'prev') {
+ if ($cur >= $first) {
+ i3_msg('command', "workspace ${\($cur - 1)}");
+ }
+}
+elsif ($dir eq 'next') {
+ if ($cur <= $last) {
+ i3_msg('command', "workspace ${\($cur + 1)}");
+ }
+}
+elsif ($dir eq $virtual_workspace) {
+ if (!defined $virtual_output || $virtual_output eq 'VIRTUAL1') {
+ i3_msg(
+ 'command',
+ "workspace $virtual_workspace; move workspace to output eDP1",
+ );
+ }
+ else {
+ i3_msg(
+ 'command',
+ "workspace $virtual_workspace; move workspace to output VIRTUAL1",
+ );
+ }
+}
+else {
+ die "unknown subcommand $dir";
+}
+
+sub find_workspace {
+ my ($tree, $num) = @_;
+ if (exists $tree->{num} && $tree->{num} == $num) {
+ return $tree;
+ }
+ for my $node (@{ $tree->{nodes} }) {
+ my $found = find_workspace($node, $num);
+ return $found if $found;
+ }
+ return;
+}
+
+sub build_i3_msg {
+ my ($type, $payload) = @_;
+
+ $payload = ''
+ unless $type eq 'command' || $type eq 'subscribe';
+
+ utf8::encode($payload);
+
+ return 'i3-ipc'
+ . pack('LL', length($payload), $message_types{$type})
+ . $payload;
+}
+
+sub get_i3_msg {
+ my $bytes = $sock->read(my $header, 14);
+ die "invalid read" if $bytes != 14;
+ die "invalid format: $header" if substr($header, 0, 6) ne 'i3-ipc';
+ my ($length, $type) = unpack('LL', substr($header, 6, 8));
+
+ if ($length) {
+ my $bytes = $sock->read(my $payload, $length);
+ die "invalid read" if $bytes != $length;
+ utf8::decode($payload);
+ return ($message_codes{$type}, $payload);
+ }
+ else {
+ return ($message_codes{$type});
+ }
+}
+
+sub i3_msg {
+ my ($type, $payload) = @_;
+ my $msg = build_i3_msg($type, $payload);
+ $sock->write($msg);
+ my ($got_type, $got_payload) = get_i3_msg();
+ die "got $got_type message, expected $type message"
+ unless $type eq $got_type;
+ return $got_payload;
+}
diff --git a/i3/.bin/kill-focused b/i3/.bin/kill-focused
new file mode 100755
index 0000000..37271ac
--- /dev/null
+++ b/i3/.bin/kill-focused
@@ -0,0 +1,49 @@
+#!/usr/bin/env perl
+use strict;
+use warnings;
+use 5.014;
+
+use JSON::PP;
+
+my ($sig) = @ARGV;
+my $pid = get_pid();
+my $pgrp = get_pgrp($pid);
+kill $sig, -$pgrp;
+
+sub get_pid {
+ my $window_id = get_window_id();
+ die "couldn't find window" unless defined $window_id;
+ my $prop = `xprop -id $window_id _NET_WM_PID`;
+ die "couldn't get pid from focused window"
+ if $prop =~ /not found/;
+ chomp($prop);
+ $prop =~ s/^_NET_WM_PID\(CARDINAL\) = //;
+ return $prop;
+}
+
+sub get_pgrp {
+ my ($pid) = @_;
+ open my $stat_fh, '<', "/proc/$pid/stat"
+ or die "couldn't open /proc/$pid/stat";
+ my $stat = do { local $/; <$stat_fh> };
+ my @f = ($stat =~ /\([^)]*\)|[^ ]+/g);
+ return $f[4];
+}
+
+sub get_window_id {
+ return find(decode_json(`i3-msg -t get_tree`))->{window};
+}
+
+sub find {
+ my ($t) = @_;
+ if ($t->{focused}) {
+ return $t;
+ }
+
+ for my $subtree (@{ $t->{nodes} }, @{ $t->{floating_nodes} }) {
+ my $found = find($subtree);
+ return $found if $found;
+ }
+
+ return;
+}
diff --git a/i3/.config/i3/config b/i3/.config/i3/config
new file mode 100644
index 0000000..afa6af1
--- /dev/null
+++ b/i3/.config/i3/config
@@ -0,0 +1,77 @@
+set $mod Mod4
+
+default_border pixel 1
+hide_edge_borders smart
+client.focused #aaaaaa #aaaaaa #ffffff #ffffff
+client.focused_inactive #000000 #000000 #ffffff #888888
+client.unfocused #000000 #000000 #ffffff #888888
+client.urgent #ff0000 #ff0000 #ffffff #ff0000
+
+floating_modifier $mod
+floating_minimum_size 1 x 1
+floating_maximum_size -1 x -1
+
+focus_wrapping no
+
+for_window [instance="Alacritty-tdrop"] floating enable
+for_window [instance="Alacritty-tdrop"] sticky enable
+
+for_window [class="Steam"] floating enable
+for_window [class="ArenaTracker"] floating enable
+
+for_window [title="zoom"] floating enable
+
+bindsym $mod+q kill
+
+bindsym $mod+h focus left
+bindsym $mod+j focus down
+bindsym $mod+k focus up
+bindsym $mod+l focus right
+
+bindsym $mod+Shift+h move left
+bindsym $mod+Shift+j move down
+bindsym $mod+Shift+k move up
+bindsym $mod+Shift+l move right
+
+bindsym $mod+f fullscreen
+
+bindsym $mod+Shift+space floating toggle
+bindsym $mod+space focus mode_toggle
+
+bindsym $mod+bracketleft exec i3-switch-workspace prev
+bindsym $mod+bracketright exec i3-switch-workspace next
+bindsym $mod+v exec vscreen goto
+
+bindsym $mod+Shift+o exec "i3-msg 'append_layout .config/i3/terminal-workspace.json; exec env WINIT_X11_SCALE_FACTOR=1 alacritty; exec env WINIT_X11_SCALE_FACTOR=1 alacritty; exec env WINIT_X11_SCALE_FACTOR=1 alacritty; exec env WINIT_X11_SCALE_FACTOR=1 alacritty; exec env WINIT_X11_SCALE_FACTOR=1 alacritty'"
+
+bindsym $mod+1 workspace 1
+bindsym $mod+2 workspace 2
+bindsym $mod+3 workspace 3
+bindsym $mod+4 workspace 4
+bindsym $mod+5 workspace 5
+bindsym $mod+6 workspace 6
+bindsym $mod+7 workspace 7
+bindsym $mod+8 workspace 8
+bindsym $mod+9 workspace 9
+
+bindsym $mod+Shift+1 move container to workspace 1
+bindsym $mod+Shift+2 move container to workspace 2
+bindsym $mod+Shift+3 move container to workspace 3
+bindsym $mod+Shift+4 move container to workspace 4
+bindsym $mod+Shift+5 move container to workspace 5
+bindsym $mod+Shift+6 move container to workspace 6
+bindsym $mod+Shift+7 move container to workspace 7
+bindsym $mod+Shift+8 move container to workspace 8
+bindsym $mod+Shift+9 move container to workspace 9
+
+bindsym $mod+c reload
+bindsym $mod+Shift+c restart
+bindsym $mod+Shift+q exec "i3-nagbar -t warning -m 'You pressed the exit shortcut. Do you really want to exit i3? This will end your X session.' -b 'Yes, exit i3' 'i3-msg exit'"
+
+bar {
+ tray_output primary
+ status_command status
+ font xft:DejaVuSansMono 12
+}
+
+exec "i3-msg 'workspace 5'"
diff --git a/i3/.config/i3/terminal-workspace.json b/i3/.config/i3/terminal-workspace.json
new file mode 100644
index 0000000..d957bc1
--- /dev/null
+++ b/i3/.config/i3/terminal-workspace.json
@@ -0,0 +1,125 @@
+// vim:ts=4:sw=4:et
+{
+ // splitv split container with 3 children
+ "border": "pixel",
+ "floating": "auto_off",
+ "layout": "splitv",
+ "marks": [],
+ "percent": 0.337251851851852,
+ "type": "con",
+ "nodes": [
+ {
+ "border": "pixel",
+ "current_border_width": 1,
+ "floating": "auto_off",
+ "geometry": {
+ "height": 340,
+ "width": 564,
+ "x": 0,
+ "y": 0
+ },
+ "marks": [],
+ "name": "main:0:zsh - \"doy@hornet:~/conf\"",
+ "percent": 0.333333333333333,
+ "swallows": [
+ {
+ "instance": "^Alacritty$"
+ }
+ ],
+ "type": "con"
+ },
+ {
+ "border": "pixel",
+ "current_border_width": 1,
+ "floating": "auto_off",
+ "geometry": {
+ "height": 340,
+ "width": 564,
+ "x": 0,
+ "y": 0
+ },
+ "marks": [],
+ "name": "work:0:zsh - \"doy@hornet:~\"",
+ "percent": 0.333333333333333,
+ "swallows": [
+ {
+ "instance": "^Alacritty$"
+ }
+ ],
+ "type": "con"
+ },
+ {
+ "border": "pixel",
+ "current_border_width": 1,
+ "floating": "auto_off",
+ "geometry": {
+ "height": 340,
+ "width": 564,
+ "x": 0,
+ "y": 0
+ },
+ "marks": [],
+ "name": "misc:0:mtr - \"doy@hornet:~\"",
+ "percent": 0.333333333333333,
+ "swallows": [
+ {
+ "instance": "^Alacritty$"
+ }
+ ],
+ "type": "con"
+ }
+ ]
+}
+
+{
+ // splitv split container with 2 children
+ "border": "pixel",
+ "floating": "auto_off",
+ "layout": "splitv",
+ "marks": [],
+ "percent": 0.662748148148148,
+ "type": "con",
+ "nodes": [
+ {
+ "border": "pixel",
+ "current_border_width": 1,
+ "floating": "auto_off",
+ "geometry": {
+ "height": 340,
+ "width": 564,
+ "x": 0,
+ "y": 0
+ },
+ "marks": [],
+ "name": "chat:0:vim - \"doy@hornet:~\"",
+ "percent": 0.5,
+ "swallows": [
+ {
+ "instance": "^Alacritty$"
+ }
+ ],
+ "type": "con"
+ },
+ {
+ "border": "pixel",
+ "current_border_width": 1,
+ "floating": "auto_off",
+ "geometry": {
+ "height": 340,
+ "width": 564,
+ "x": 0,
+ "y": 0
+ },
+ "marks": [],
+ "name": "docs:0:zsh - \"doy@hornet:~\"",
+ "percent": 0.5,
+ "swallows": [
+ {
+ "instance": "^Alacritty$"
+ }
+ ],
+ "type": "con"
+ }
+ ]
+}
+