#!/usr/local/bin/perl # ======================== # ===== =============== # ====== ================ # ====== ================ # ====== ==== ==== == # ====== === == = = # ====== === = == = # = === === = == ==== # = === === = == = = # == ===== ==== == # ======================== # # SPDX-License-Identifier: BSD-3-Clause # # Copyright © 2020 Joe # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # 3. Neither the name of the organization nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY JOE ''AS IS'' AND ANY # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE # DISCLAIMED. IN NO EVENT SHALL JOE BE LIABLE FOR ANY # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # bspwmrc # 2020-11-05 22:34 # Joe use strict; use warnings; use Capture::Tiny qw(capture); use Time::HiRes; use WWW::Curl::Easy; use constant { TERMINAL => 'st', TERM_PATH => '/usr/local/bin/st' }; use constant { SXHKD_PATH => '/usr/local/bin/sxhkd', PGREP_PATH => '/bin/pgrep', PKILL_PATH => '/bin/pkill', XRANDR_PATH => '/usr/local/bin/xrandr', MAINSCREEN_PATH => '/usr/home/jozan/.local/bin/mainscreen', DUALSCREEN_PATH => '/usr/home/jozan/.local/bin/dualscreen', TRIPLESCREEN_PATH => '/usr/home/jozan/.local/bin/triplescreen', BSPC_PATH => '/usr/local/bin/bspc', COMPTON_PATH => '/usr/local/bin/compton', XSET_PATH => '/usr/local/bin/xset', SETXKBMAP_PATH => '/usr/local/bin/setxkbmap', DUNST_PATH => '/usr/local/bin/dunst', LOWBAT_PATH => '/usr/local/bin/lowbat', EMACS_PATH => '/usr/local/bin/emacs', NEOVIM_PATH => '/usr/local/bin/nvim', PGREP_PATH => '/bin/pgrep', ESPEAK_PATH => '/usr/local/bin/espeak', SH_PATH => '/bin/sh', ZSH_PATH => '/usr/local/bin/zsh', DASH_PATH => '/usr/local/bin/dash', FISH_PATH => '/usr/local/bin/fish', COWSAY_PATH => '/usr/local/bin/cowsay', HTOP_PATH => '/usr/local/bin/htop', GOTOP_PATH => '/usr/local/bin/gotop', VIFM_PATH => '/usr/local/bin/vifm', GIT_PATH => '/usr/local/bin/git', XSETROOT_PATH => '/usr/local/bin/xsetroot', XINPUT_PATH => '/usr/local/bin/xinput', SETWP_PATH => '/usr/home/jozan/.local/bin/setwp', BSPSWALLOW_PATH => '/usr/home/jozan/.local/bin/bspswallow', NEOMUTT_PATH => '/usr/local/bin/neomutt', SCLI_PATH => '/usr/local/bin/scli', VIMPC_PATH => '/usr/local/bin/vimpc', MPD_NOTIFICATION_PATH => '/usr/local/bin/mpd-notification' }; use constant { BSP_BORDER_WIDTH => 1, BSP_WINDOW_GAP => 0, BSP_BORDER_COLOR => '#b92121', BSP_SPLIT_RATIO => '0.50', BSP_BORDERLESS_MONOCLE => 'true', BSP_GAPLESS_MONOCLE => 'true', BSP_SINGLE_MONOCLE => 'true', XSET_R_RATE_DELAY => 200, XSET_R_RATE_RATE => 150 }; use constant COWSAY_WELCOME => 'Welcome back, partner! And remember to try glest!'; use constant NETWORK_TEST_URL => 'https://www.freebsd.org/'; use constant SLEEP_TIME => 3.5; sub run_if_dead { my @argv = @_; my $bin; my $pid; if ($argv[0] =~ /SXHKD_SHELL/) { $bin = $argv[1]; } else { $bin = $argv[0]; } $bin =~ s/.+\///g; my (undef, undef, $retval) = capture { system( PGREP_PATH, $bin ); }; $retval = ($retval >> 8) & 0xff; if ($retval != 0) { $pid = fork(); if (not $pid) { if ($argv[0] =~ /SXHKD_SHELL/) { exec($argv[0] . ' ' . $argv[1]); exit; } else { exec(@argv); exit; } } } return; } sub kill_some { system(PKILL_PATH, TERMINAL); return; } sub enable_screens { my $stdout; my $screens; $screens = 1; ($stdout, undef, undef) = capture { system(XRANDR_PATH); }; if ($stdout =~ m/HDMI-1 connected/ && $stdout =~ m/VGA-1 connected/ == 1) { $screens = 3; system(TRIPLESCREEN_PATH); } elsif ($stdout =~ m/HDMI-1 connected/) { $screens = 2; system(DUALSCREEN_PATH); } else { system(MAINSCREEN_PATH); } return $screens; } sub bspc_configs { system(BSPC_PATH, 'config', 'border_width', BSP_BORDER_WIDTH); system(BSPC_PATH, 'config', 'window_gap', BSP_WINDOW_GAP); system(BSPC_PATH, 'config', 'focused_border_color', BSP_BORDER_COLOR); system(BSPC_PATH, 'config', 'split_ratio', BSP_SPLIT_RATIO); system(BSPC_PATH, 'config', 'borderless_monocle', BSP_BORDERLESS_MONOCLE); system(BSPC_PATH, 'config', 'gapless_monocle', BSP_GAPLESS_MONOCLE); system(BSPC_PATH, 'config', 'single_monocle', BSP_SINGLE_MONOCLE); return; } sub bspc_rules { system(BSPC_PATH, 'rule', '-a', 'Emacs', 'state=tiled'); system(BSPC_PATH, 'rule', '-a', 'Firefox', 'desktop=03', 'follow=true'); system(BSPC_PATH, 'rule', '-a', 'Wine', 'desktop=04', 'state=floating'); system(BSPC_PATH, 'rule', '-a', 'Dunst', 'layer=above'); system(BSPC_PATH, 'rule', '-a', 'Zathura', 'state=tiled'); system(BSPC_PATH, 'rule', '-a', 'qTox', 'desktop=10'); system(BSPC_PATH, 'rule', '-a', 'DergodsRealmII', 'state=floating'); system(BSPC_PATH, 'rule', '-a', 'obs', 'desktop=10', 'follow=true'); return; } sub run_bg_programs { run_if_dead('SXHKD_SHELL=' . DASH_PATH, SXHKD_PATH); run_if_dead(COMPTON_PATH); run_if_dead(DUNST_PATH); run_if_dead(LOWBAT_PATH); run_if_dead(BSPSWALLOW_PATH); run_if_dead(MPD_NOTIFICATION_PATH); system(SETWP_PATH); system(XSETROOT_PATH, '-cursor_name', 'left_ptr'); system(XSET_PATH, 'r', 'rate', XSET_R_RATE_DELAY, XSET_R_RATE_RATE); system(SETXKBMAP_PATH, '-layout', 'us,fr', '-option', 'grp:alt_shift_toggle'); system(XINPUT_PATH, '--set-prop', '12', '273', '-1'); return; } sub run_espeak { my $espeak_pid; $espeak_pid = fork(); if (not $espeak_pid) { exec(ESPEAK_PATH, COWSAY_WELCOME); } return; } sub fg_on_three_screens { my @term_pid; $term_pid[0] = fork(); if (not $term_pid[0]) { exec( TERM_PATH, '-e', SH_PATH, '-c', COWSAY_PATH . ' "' . COWSAY_WELCOME . '"; ' . ZSH_PATH ); exit; } Time::HiRes::sleep(SLEEP_TIME); $term_pid[1] = fork(); if (not $term_pid[1]) { exec(TERM_PATH, '-e', HTOP_PATH); exit; } Time::HiRes::sleep(SLEEP_TIME); $term_pid[2] = fork(); if (not $term_pid[2]) { exec(TERM_PATH, '-e', GOTOP_PATH); exit; } Time::HiRes::sleep(SLEEP_TIME); system(BSPC_PATH, 'node', '-f', 'west'); $term_pid[3] = fork(); if (not $term_pid[3]) { exec(TERM_PATH, '-e', VIFM_PATH); exit; } Time::HiRes::sleep(SLEEP_TIME); system(BSPC_PATH, 'node', '-z', 'right', '180', '0'); system(BSPC_PATH, 'node', '-z', 'top', '0', '70'); system(BSPC_PATH, 'node', '-f', 'east'); system(BSPC_PATH, 'node', '-f', 'north'); system(BSPC_PATH, 'node', '-z', 'bottom', '0', '-280'); system(BSPC_PATH, 'node', '-f', 'west'); return; } sub fg_on_two_screens { my @term_pid; $term_pid[0] = fork(); if (not $term_pid[0]) { exec( TERM_PATH, '-e', SH_PATH, '-c', COWSAY_PATH . ' "' . COWSAY_WELCOME . '"; ' . ZSH_PATH ); exit; } Time::HiRes::sleep(SLEEP_TIME); $term_pid[1] = fork(); if (not $term_pid[1]) { exec(TERM_PATH, '-e', HTOP_PATH); exit; } Time::HiRes::sleep(SLEEP_TIME); $term_pid[2] = fork(); if (not $term_pid[2]) { exec(TERM_PATH, '-e', GOTOP_PATH); exit; } Time::HiRes::sleep(SLEEP_TIME); system(BSPC_PATH, 'node', '-f', 'west'); $term_pid[3] = fork(); if (not $term_pid[3]) { exec(TERM_PATH, '-e', VIFM_PATH); exit; } Time::HiRes::sleep(SLEEP_TIME); system(BSPC_PATH, 'node', '-z', 'right', '180', '0'); system(BSPC_PATH, 'node', '-z', 'top', '0', '70'); system(BSPC_PATH, 'node', '-f', 'east'); system(BSPC_PATH, 'node', '-f', 'north'); system(BSPC_PATH, 'node', '-z', 'bottom', '0', '-280'); system(BSPC_PATH, 'node', '-f', 'west'); return; } sub fg_on_one_screen { my @term_pid; $term_pid[0] = fork(); if (not $term_pid[0]) { exec( TERM_PATH, '-e', SH_PATH, '-c', COWSAY_PATH . ' "' . COWSAY_WELCOME . '"; ' . ZSH_PATH ); exit; } Time::HiRes::sleep(SLEEP_TIME); system(BSPC_PATH, 'node', '-p', 'west'); $term_pid[1] = fork(); if (not $term_pid[1]) { exec(TERM_PATH, '-e', HTOP_PATH); exit; } Time::HiRes::sleep(SLEEP_TIME); $term_pid[2] = fork(); if (not $term_pid[2]) { exec(TERM_PATH, '-e', GOTOP_PATH); } Time::HiRes::sleep(SLEEP_TIME); system(BSPC_PATH, 'node', '-f', 'east'); $term_pid[3] = fork(); if (not $term_pid[3]) { exec(TERM_PATH, '-e', VIFM_PATH); } Time::HiRes::sleep(SLEEP_TIME); system(BSPC_PATH, 'node', '-f', 'west'); system(BSPC_PATH, 'node', '-f', 'north'); system(BSPC_PATH, 'node', '-z', 'bottom', '0', '-200'); system(BSPC_PATH, 'node', '-z', 'right', '-220', '0'); system(BSPC_PATH, 'node', '-f', 'east'); system(BSPC_PATH, 'node', '-z', 'bottom', '0', '70'); return; } sub run_terms { my ($screens) = @_; Time::HiRes::sleep(1); system(BSPC_PATH, 'desktop', '-f', '12'); if ($screens == 3) { fg_on_three_screens(); } elsif ($screens == 2) { fg_on_two_screens(); } else { fg_on_one_screen(); } return; } sub run_fg_programs { my ($screens) = @_; my @pid; run_espeak(); run_terms($screens); system(BSPC_PATH, 'desktop', '-f', '11'); $pid[0] = fork(); if (not $pid[0]) { exec(TERM_PATH, '-e', NEOMUTT_PATH); } Time::HiRes::sleep(SLEEP_TIME); system(BSPC_PATH, 'desktop', '-f', '10'); $pid[1] = fork(); if (not $pid[1]) { exec(TERM_PATH, '-e', SCLI_PATH); } Time::HiRes::sleep(SLEEP_TIME); system(BSPC_PATH, 'desktop', '-f', '09'); $pid[2] = fork(); if (not $pid[2]) { exec(TERM_PATH, '-e', VIMPC_PATH); } Time::HiRes::sleep(SLEEP_TIME); system(BSPC_PATH, 'desktop', '-f', '01'); $pid[3] = fork(); if (not $pid[3]) { exec(TERM_PATH, '-e', NEOVIM_PATH); } Time::HiRes::sleep(SLEEP_TIME); system(BSPC_PATH, 'desktop', '-f', '12'); return; } sub run_network_programs { my $curl; my $response_body; $curl = WWW::Curl::Easy->new; $curl->setopt(CURLOPT_URL, NETWORK_TEST_URL); $curl->setopt(CURLOPT_WRITEDATA, \$response_body); if ($curl->perform == 0) { system(GIT_PATH, '-C', '/usr/home/jozan/.elfeed', 'pull', 'origin', 'master'); } return; } sub main { my $screens; kill_some(); $screens = enable_screens(); bspc_configs(); bspc_rules(); run_bg_programs(); run_fg_programs($screens); run_network_programs(); return; } main(); __END__