diff --git a/.clangd b/.clangd old mode 100644 new mode 100755 diff --git a/.config/LICENSE b/.config/LICENSE old mode 100644 new mode 100755 diff --git a/.config/alacritty/themes/Homebrew.toml b/.config/alacritty/themes/Homebrew.toml old mode 100644 new mode 100755 diff --git a/.config/fish/.gitignore b/.config/fish/.gitignore old mode 100644 new mode 100755 diff --git a/.config/fish/completions/fish-lsp.fish b/.config/fish/completions/fish-lsp.fish old mode 100644 new mode 100755 diff --git a/.config/fish/conf.d/rustup.fish b/.config/fish/conf.d/rustup.fish old mode 100644 new mode 100755 diff --git a/.config/fish/config.fish b/.config/fish/config.fish index 8c5cc26..75c020a 100755 --- a/.config/fish/config.fish +++ b/.config/fish/config.fish @@ -21,6 +21,9 @@ switch (uname) # Android fish_add_path -a /usr/share/android-tools + # rocm + fish_add_path -a /opt/rocm/bin + # Java #fish_add_path -a /usr/local/jdk-21/bin @@ -28,10 +31,14 @@ switch (uname) #fish_add_path -a /usr/local/share/ltex-ls-16.0.0/bin # pyenv - fish_add_path -a /usr/share/pyenv/bin - pyenv init - | source + set -x PYENV_ROOT /usr/share/pyenv + fish_add_path -a $PYENV_ROOT/bin + pyenv init - fish | source status --is-interactive; and pyenv virtualenv-init - | source + # Zig + fish_add_path -a /usr/share/zig + # VARIABLES diff --git a/.config/ghostty/config b/.config/ghostty/config old mode 100644 new mode 100755 index 6c2413c..60eebe2 --- a/.config/ghostty/config +++ b/.config/ghostty/config @@ -87,6 +87,19 @@ macos-icon = official macos-icon-frame = aluminum macos-icon-ghost-color = macos-icon-screen-color = +linux-cgroup = single-instance +linux-cgroup-memory-limit = +linux-cgroup-processes-limit = +linux-cgroup-hard-fail = false +gtk-single-instance = desktop +#gtk-titlebar = true +gtk-titlebar = false +gtk-tabs-location = top +adw-toolbar-style = raised +#adw-toast = clipboard-copy +gtk-wide-tabs = true +gtk-adwaita = true +#gtk-custom-css = desktop-notifications = true bold-is-bright = false term = xterm-ghostty diff --git a/.config/nvim/.gitignore b/.config/nvim/.gitignore old mode 100644 new mode 100755 diff --git a/.config/nvim/.stylua.toml b/.config/nvim/.stylua.toml old mode 100644 new mode 100755 diff --git a/.config/nvim/after/queries/ecma/textobjects.scm b/.config/nvim/after/queries/ecma/textobjects.scm old mode 100644 new mode 100755 diff --git a/.config/nvim/init.lua b/.config/nvim/init.lua old mode 100644 new mode 100755 diff --git a/.config/nvim/lua/user/core/init.lua b/.config/nvim/lua/user/core/init.lua old mode 100644 new mode 100755 diff --git a/.config/nvim/lua/user/core/keymaps.lua b/.config/nvim/lua/user/core/keymaps.lua old mode 100644 new mode 100755 diff --git a/.config/nvim/lua/user/core/options.lua b/.config/nvim/lua/user/core/options.lua old mode 100644 new mode 100755 diff --git a/.config/nvim/lua/user/lazy.lua b/.config/nvim/lua/user/lazy.lua old mode 100644 new mode 100755 diff --git a/.config/nvim/lua/user/plugins/00_colorscheme.lua b/.config/nvim/lua/user/plugins/00_colorscheme.lua old mode 100644 new mode 100755 diff --git a/.config/nvim/lua/user/plugins/01_treesitter.lua b/.config/nvim/lua/user/plugins/01_treesitter.lua old mode 100644 new mode 100755 diff --git a/.config/nvim/lua/user/plugins/02_nvim-treesitter-text-objects.lua b/.config/nvim/lua/user/plugins/02_nvim-treesitter-text-objects.lua old mode 100644 new mode 100755 diff --git a/.config/nvim/lua/user/plugins/03_nvim-cmp.lua b/.config/nvim/lua/user/plugins/03_nvim-cmp.lua old mode 100644 new mode 100755 diff --git a/.config/nvim/lua/user/plugins/04_linting.lua b/.config/nvim/lua/user/plugins/04_linting.lua old mode 100644 new mode 100755 diff --git a/.config/nvim/lua/user/plugins/05_compiler.lua b/.config/nvim/lua/user/plugins/05_compiler.lua old mode 100644 new mode 100755 diff --git a/.config/nvim/lua/user/plugins/06_rustacean.lua b/.config/nvim/lua/user/plugins/06_rustacean.lua old mode 100644 new mode 100755 diff --git a/.config/nvim/lua/user/plugins/07_vimtex.lua b/.config/nvim/lua/user/plugins/07_vimtex.lua old mode 100644 new mode 100755 diff --git a/.config/nvim/lua/user/plugins/08_fugitive.lua b/.config/nvim/lua/user/plugins/08_fugitive.lua old mode 100644 new mode 100755 diff --git a/.config/nvim/lua/user/plugins/09_gitsigns.lua b/.config/nvim/lua/user/plugins/09_gitsigns.lua old mode 100644 new mode 100755 diff --git a/.config/nvim/lua/user/plugins/10_todo-comments.lua b/.config/nvim/lua/user/plugins/10_todo-comments.lua old mode 100644 new mode 100755 diff --git a/.config/nvim/lua/user/plugins/11_telescope.lua b/.config/nvim/lua/user/plugins/11_telescope.lua old mode 100644 new mode 100755 diff --git a/.config/nvim/lua/user/plugins/12_neorg.lua b/.config/nvim/lua/user/plugins/12_neorg.lua old mode 100644 new mode 100755 diff --git a/.config/nvim/lua/user/plugins/13_terminal.lua b/.config/nvim/lua/user/plugins/13_terminal.lua old mode 100644 new mode 100755 diff --git a/.config/nvim/lua/user/plugins/14_vim-maximizer.lua b/.config/nvim/lua/user/plugins/14_vim-maximizer.lua old mode 100644 new mode 100755 diff --git a/.config/nvim/lua/user/plugins/15_autopairs.lua b/.config/nvim/lua/user/plugins/15_autopairs.lua old mode 100644 new mode 100755 diff --git a/.config/nvim/lua/user/plugins/16_surround.lua b/.config/nvim/lua/user/plugins/16_surround.lua old mode 100644 new mode 100755 diff --git a/.config/nvim/lua/user/plugins/17_which-key.lua b/.config/nvim/lua/user/plugins/17_which-key.lua old mode 100644 new mode 100755 diff --git a/.config/nvim/lua/user/plugins/18_nvim-tree.lua b/.config/nvim/lua/user/plugins/18_nvim-tree.lua old mode 100644 new mode 100755 diff --git a/.config/nvim/lua/user/plugins/19_trouble.lua b/.config/nvim/lua/user/plugins/19_trouble.lua old mode 100644 new mode 100755 diff --git a/.config/nvim/lua/user/plugins/20_substitute.lua b/.config/nvim/lua/user/plugins/20_substitute.lua old mode 100644 new mode 100755 diff --git a/.config/nvim/lua/user/plugins/21_lualine.lua b/.config/nvim/lua/user/plugins/21_lualine.lua old mode 100644 new mode 100755 diff --git a/.config/nvim/lua/user/plugins/22_formatting.lua b/.config/nvim/lua/user/plugins/22_formatting.lua old mode 100644 new mode 100755 diff --git a/.config/nvim/lua/user/plugins/23_indent-blankline.lua b/.config/nvim/lua/user/plugins/23_indent-blankline.lua old mode 100644 new mode 100755 index 572e0bd..90ae3e3 --- a/.config/nvim/lua/user/plugins/23_indent-blankline.lua +++ b/.config/nvim/lua/user/plugins/23_indent-blankline.lua @@ -1,8 +1,8 @@ return { - "lukas-reineke/indent-blankline.nvim", - event = { "BufReadPre", "BufNewFile" }, - main = "ibl", - opts = { - indent = { char = "┊" }, - }, + "lukas-reineke/indent-blankline.nvim", + event = { "BufReadPre", "BufNewFile" }, + main = "ibl", + opts = { + indent = { char = "┊" }, + }, } diff --git a/.config/nvim/lua/user/plugins/24_alpha.lua b/.config/nvim/lua/user/plugins/24_alpha.lua old mode 100644 new mode 100755 diff --git a/.config/nvim/lua/user/plugins/25_auto-session.lua b/.config/nvim/lua/user/plugins/25_auto-session.lua old mode 100644 new mode 100755 diff --git a/.config/nvim/lua/user/plugins/26_dressing.lua b/.config/nvim/lua/user/plugins/26_dressing.lua old mode 100644 new mode 100755 diff --git a/.config/nvim/lua/user/plugins/27_comment.lua b/.config/nvim/lua/user/plugins/27_comment.lua old mode 100644 new mode 100755 diff --git a/.config/nvim/lua/user/plugins/28_bufferline.lua b/.config/nvim/lua/user/plugins/28_bufferline.lua old mode 100644 new mode 100755 diff --git a/.config/nvim/lua/user/plugins/init.lua b/.config/nvim/lua/user/plugins/init.lua old mode 100644 new mode 100755 diff --git a/.config/nvim/lua/user/plugins/lsp/00_mason.lua b/.config/nvim/lua/user/plugins/lsp/00_mason.lua old mode 100644 new mode 100755 diff --git a/.config/nvim/lua/user/plugins/lsp/01_lspconfig.lua b/.config/nvim/lua/user/plugins/lsp/01_lspconfig.lua old mode 100644 new mode 100755 diff --git a/.config/sway/config b/.config/sway/config new file mode 100755 index 0000000..df8553b --- /dev/null +++ b/.config/sway/config @@ -0,0 +1,68 @@ +# Default config for sway +# +# Copy this to ~/.config/sway/config and edit it to your liking. +# +# Read `man 5 sway` for a complete reference. + +# openSUSE theme +default_border pixel 2 +gaps inner 10 +client.focused #6da741 #173f4f #73ba25 +client.unfocused #00a489 #173f4f #35b9ab +client.focused_inactive #6da741 #00a489 #173f4f + +#don't show gaps if there's only one window on the desktop +smart_gaps on + +### Variables +# +# Logo key. Use Mod1 for Alt. +set $mod Mod4 + +# Home row direction keys, like vim +set $left h +set $down j +set $up k +set $right l + +# Waybar position +set $waybar_position top + +# Your preferred terminal emulator +#set $term alacritty #--config-file ~/.config/alacritty/alacritty.yml +set $term ghostty + +# Your preferred application launcher +# Note: pass the final command to swaymsg so that the resulting window can be opened +# on the original workspace that the command was run on. +#set $menu dmenu_path | dmenu | xargs swaymsg exec -- +# it is set in config.d/50-openSUSE.conf + +# wofi as application launcher +set $menu wofi -I -S drun --conf=/etc/wofi/config --style=/etc/wofi/style.css +#set $menu rofi -no-lazy-grab -disable-history -modi "drun" -show drun -theme ~/.config/rofi/config.rasi + +# Sway Notification Centre +set $toggle_notification "swaync-client -t -sw" + +# Wob +set $wob wob --config ~/.config/sway/wob/wob.ini + +# background +set $background ~/.config/backgrounds/tokyonight.jpg + +# monitors +set $ext_monitor HDMI-A-1 +set $int_monitor eDP-1 + +# screen capture +set $screen grimshot copy +# screen capture +set $screen_area grimshot copy area + + +include ~/.config/sway/config.d/*.conf +include ~/.config/sway/inputs/*.conf +include ~/.config/sway/outputs/*.conf +include ~/.config/sway/modes/*.conf +include ~/.config/sway/config.d/* diff --git a/.config/sway/config.d/50-general-binds.conf b/.config/sway/config.d/50-general-binds.conf new file mode 100755 index 0000000..bb187e5 --- /dev/null +++ b/.config/sway/config.d/50-general-binds.conf @@ -0,0 +1,143 @@ +### Key bindings +# +# Basics: +# + # Start a terminal + bindsym $mod+Shift+Return exec $term + + # Kill focused window + bindsym $mod+Shift+c kill + + # Start your launcher + bindsym $mod+p exec $menu + + # Screen capture + bindsym $mod+Print exec $screen + + # Screen capture area + bindsym $mod+Shift+Print exec $screen_area + + # Drag floating windows by holding down $mod and left mouse button. + # Resize them with right mouse button + $mod. + # Despite the name, also works for non-floating windows. + # Change normal to inverse to use left mouse button for resizing and right + # mouse button for dragging. + floating_modifier $mod normal + + # Reload the configuration file + bindsym $mod+q reload + + # Exit sway (logs you out of your Wayland session) + bindsym $mod+Shift+q exec swaynag -t warning -m 'You pressed the exit shortcut. Do you really want to exit sway? This will end your Wayland session.' -b 'Yes, exit sway' 'swaymsg exit' + +# +# Moving around: +# + # Move your focus around + bindsym $mod+$left focus left + bindsym $mod+$down focus down + bindsym $mod+$up focus up + bindsym $mod+$right focus right + # Or use $mod+[up|down|left|right] + bindsym $mod+Left focus left + bindsym $mod+Down focus down + bindsym $mod+Up focus up + bindsym $mod+Right focus right + + # Move the focused window with the same, but add Shift + bindsym $mod+Shift+$left move left + bindsym $mod+Shift+$down move down + bindsym $mod+Shift+$up move up + bindsym $mod+Shift+$right move right + # Ditto, with arrow keys + bindsym $mod+Shift+Left move left + bindsym $mod+Shift+Down move down + bindsym $mod+Shift+Up move up + bindsym $mod+Shift+Right move right +# +# Workspaces: +# + # Switch to workspace + bindsym $mod+1 workspace number 1 + bindsym $mod+2 workspace number 2 + bindsym $mod+3 workspace number 3 + bindsym $mod+4 workspace number 4 + bindsym $mod+5 workspace number 5 + bindsym $mod+6 workspace number 6 + bindsym $mod+7 workspace number 7 + bindsym $mod+8 workspace number 8 + bindsym $mod+9 workspace number 9 + bindsym $mod+0 workspace number 10 + # Move focused container to workspace + bindsym $mod+Shift+1 move container to workspace number 1 + bindsym $mod+Shift+2 move container to workspace number 2 + bindsym $mod+Shift+3 move container to workspace number 3 + bindsym $mod+Shift+4 move container to workspace number 4 + bindsym $mod+Shift+5 move container to workspace number 5 + bindsym $mod+Shift+6 move container to workspace number 6 + bindsym $mod+Shift+7 move container to workspace number 7 + bindsym $mod+Shift+8 move container to workspace number 8 + bindsym $mod+Shift+9 move container to workspace number 9 + bindsym $mod+Shift+0 move container to workspace number 10 + # Note: workspaces can have any name you want, not just numbers. + # We just use 1-10 as the default. + +# +# Layout stuff: +# + # You can "split" the current object of your focus with + # $mod+b or $mod+v, for horizontal and vertical splits + # respectively. + bindsym $mod+b splith + bindsym $mod+v splitv + + # Switch the current container between different layout styles + bindsym $mod+s layout stacking + bindsym $mod+w layout tabbed + bindsym $mod+e layout toggle split + + # Make the current focus fullscreen + bindsym $mod+f fullscreen + + # Toggle the current focus between tiling and floating mode + bindsym $mod+Shift+space floating toggle + + # Swap focus between the tiling area and the floating area + bindsym $mod+space focus mode_toggle + + # Move focus to the parent container + bindsym $mod+a focus parent + +bindsym $mod+r mode "resize" + +# Cycle through workspaces +bindsym $mod+tab workspace next_on_output +bindsym $mod+Shift+tab workspace prev_on_output + +bindsym --to-code { + $mod+b splith + $mod+v splitv +} + +# Media keys +bindsym XF86AudioMicMute exec pactl set-source-mute @DEFAULT_SOURCE@ toggle + +bindsym XF86MonBrightnessDown exec brightnessctl -q set 5%- && ( echo $((`brightnessctl get` * 100 / `brightnessctl m`)) > $SWAYSOCK.wob ) +bindsym XF86MonBrightnessUp exec brightnessctl -q set +5% && ( echo $((`brightnessctl get` * 100 / `brightnessctl m`)) > $SWAYSOCK.wob ) + +bindsym XF86AudioRaiseVolume exec pamixer --allow-boost -ui 2 && dc -e "[`pamixer --get-volume`]sM 100d `pamixer --get-volume` $SWAYSOCK.wob +bindsym XF86AudioLowerVolume exec pamixer --allow-boost -ud 2 && dc -e "[`pamixer --get-volume`]sM 100d `pamixer --get-volume` $SWAYSOCK.wob +bindsym XF86AudioMute exec pamixer --toggle-mute && ( pamixer --get-mute && echo 0 > $SWAYSOCK.wob ) + +# Media player controls +bindsym --no-warn XF86AudioPlay exec playerctl play-pause +bindsym --no-warn XF86AudioNext exec playerctl next +bindsym --no-warn XF86AudioPrev exec playerctl previous + +# Shutdown +# unbindsym $mod+Shift+q +# bindsym $mod+Shift+q mode $mode_system + +# Toggle notification bar +bindsym $mod+Shift+n exec $toggle_notification + diff --git a/.config/sway/config.d/50-systemd-user.conf b/.config/sway/config.d/50-systemd-user.conf new file mode 100755 index 0000000..8781db9 --- /dev/null +++ b/.config/sway/config.d/50-systemd-user.conf @@ -0,0 +1,16 @@ +# sway does not set DISPLAY/WAYLAND_DISPLAY in the systemd user environment +# See FS#63021 +# Adapted from xorg's 50-systemd-user.sh, which achieves a similar goal. + +# Upstream refuses to set XDG_CURRENT_DESKTOP so we have to. +exec systemctl --user set-environment XDG_CURRENT_DESKTOP=sway +exec systemctl --user import-environment DISPLAY \ + SWAYSOCK \ + WAYLAND_DISPLAY \ + XDG_CURRENT_DESKTOP + +exec hash dbus-update-activation-environment 2>/dev/null && \ + dbus-update-activation-environment --systemd DISPLAY \ + SWAYSOCK \ + XDG_CURRENT_DESKTOP=sway \ + WAYLAND_DISPLAY diff --git a/.config/sway/config.d/96-waybar-config.conf b/.config/sway/config.d/96-waybar-config.conf new file mode 100755 index 0000000..db883d0 --- /dev/null +++ b/.config/sway/config.d/96-waybar-config.conf @@ -0,0 +1,8 @@ +# +# Status Bar: +# +bar { + id default + swaybar_command waybar + position $waybar_position +} diff --git a/.config/sway/config.d/99-autostart.conf b/.config/sway/config.d/99-autostart.conf new file mode 100755 index 0000000..f0cbdb5 --- /dev/null +++ b/.config/sway/config.d/99-autostart.conf @@ -0,0 +1,23 @@ +# enable numlock +input * xkb_numlock enable + +exec { + '[ -x "$(command -v blueman-applet)" ] && blueman-applet' + #'[ -x "$(command -v ~/.config/waybar/scripts/battery-notification.sh)" ] && ~/.config/waybar/scripts/battery-notification.sh' + # Default wallpaper + swaybg -o $int_monitor -i $background + swaybg -o $ext_monitor -i $background +} + +exec_always { + #emacs --daemon + gsettings set org.gnome.desktop.interface gtk-theme 'Adwaita-dark' + gsettings set org.gnome.desktop.interface icon-theme 'Adwaita' + gsettings set org.gnome.desktop.interface cursor-theme 'Adwaita' + systemctl --user import-environment + test -e $SWAYSOCK.wob || mkfifo $SWAYSOCK.wob + tail -f $SWAYSOCK.wob | $wob + swaync --style ~/.config/sway/swaync/style.css --config ~/.config/sway/swaync/config.json +} + +exec /usr/libexec/polkit-gnome-authentication-agent-1 diff --git a/.config/sway/env b/.config/sway/env new file mode 100755 index 0000000..cd4e453 --- /dev/null +++ b/.config/sway/env @@ -0,0 +1,17 @@ +# recomended enviroment variables for sway based desktop +# openSUSEway installs/imports this to/from: +# /usr/lib/environment.d/50-openSUSE.conf +# /etc/profile.d/openSUSEway.sh +MOZ_ENABLE_WAYLAND=1 +QT_QPA_PLATFORM=wayland-egl +CLUTTER_BACKEND=wayland +ECORE_EVAS_ENGINE=wayland-egl +ELM_ENGINE=wayland_egl +SDL_VIDEODRIVER=wayland +_JAVA_AWT_WM_NONREPARENTING=1 +NO_AT_BRIDGE=1 + +# QT theme for openSUSEway +# needs qt5ct and adwaita-qt5 packages +# default config is /etc/xdg/qt5ct/qt5ct.conf +QT_QPA_PLATFORMTHEME=qt5ct diff --git a/.config/sway/inputs/default-keyboard.conf b/.config/sway/inputs/default-keyboard.conf new file mode 100755 index 0000000..4af8ce6 --- /dev/null +++ b/.config/sway/inputs/default-keyboard.conf @@ -0,0 +1,14 @@ +### Input configuration +# +# You can get the names of your inputs by running: swaymsg -t get_inputs +# Read `man 5 sway-input` for more information about this section. + +#input type:keyboard { +# xkb_layout "us" +#} + +input type:keyboard { + xkb_layout "us" + xkb_variant "altgr-intl" +} + diff --git a/.config/sway/inputs/default-touchpad.conf b/.config/sway/inputs/default-touchpad.conf new file mode 100755 index 0000000..b7afc37 --- /dev/null +++ b/.config/sway/inputs/default-touchpad.conf @@ -0,0 +1,26 @@ +### Input configuration +# +# You can get the names of your inputs by running: swaymsg -t get_inputs +# Read `man 5 sway-input` for more information about this section. +input type:touchpad { + dwt enabled + tap enabled + natural_scroll enabled +} + +#input type:mouse { +# map_to_output eDP-1 +#} +# +#input type:touchpad { +# map_to_output eDP-1 +#} +# +#input type:tablet_tool { +# map_to_output eDP-1 +#} +# +#input type:touch { +# map_to_output eDP-1 +#} + diff --git a/.config/sway/modes/10-idle.conf b/.config/sway/modes/10-idle.conf new file mode 100755 index 0000000..f311e28 --- /dev/null +++ b/.config/sway/modes/10-idle.conf @@ -0,0 +1,24 @@ +# +# You can get the names of your outputs by running: swaymsg -t get_outputs + +### Idle configuration +# +# Example configuration: +# +# exec swayidle -w \ +# timeout 300 'swaylock -f -c 000000' \ +# timeout 600 'swaymsg "output * dpms off"' resume 'swaymsg "output * dpms on"' \ +# before-sleep 'swaylock -f -c 000000' +# +# This will lock your screen after 300 seconds of inactivity, then turn off +# your displays after another 300 seconds, and turn your screens back on when +# resumed. It will also lock your screen before your computer goes to sleep. + +# Lockscreen configuration +set $screenlock 'swaylock -f -c 000000' +# Idle configuration +exec swayidle -w \ + timeout 7200 $screenlock \ + timeout 3600 'swaymsg "output * dpms off"' \ + resume 'swaymsg "output * dpms on"' \ + before-sleep $screenlock diff --git a/.config/sway/modes/20-resize.conf b/.config/sway/modes/20-resize.conf new file mode 100755 index 0000000..c12ad7c --- /dev/null +++ b/.config/sway/modes/20-resize.conf @@ -0,0 +1,23 @@ +# +# Resizing containers: +# +mode "resize" { + # left will shrink the containers width + # right will grow the containers width + # up will shrink the containers height + # down will grow the containers height + bindsym $left resize shrink width 10px + bindsym $down resize grow height 10px + bindsym $up resize shrink height 10px + bindsym $right resize grow width 10px + + # Ditto, with arrow keys + bindsym Left resize shrink width 10px + bindsym Down resize grow height 10px + bindsym Up resize shrink height 10px + bindsym Right resize grow width 10px + + # Return to default mode + bindsym Return mode "default" + bindsym Escape mode "default" +} diff --git a/.config/sway/modes/30-scratchpad.conf b/.config/sway/modes/30-scratchpad.conf new file mode 100755 index 0000000..856b214 --- /dev/null +++ b/.config/sway/modes/30-scratchpad.conf @@ -0,0 +1,12 @@ +# +# Scratchpad: +# + # Sway has a "scratchpad", which is a bag of holding for windows. + # You can send windows there and get them back later. + + # Move the currently focused window to the scratchpad + bindsym $mod+Shift+minus move scratchpad + + # Show the next scratchpad window or hide the focused scratchpad window. + # If there are multiple scratchpad windows, this command cycles through them. + bindsym $mod+minus scratchpad show diff --git a/.config/sway/modes/70-shutdown.conf b/.config/sway/modes/70-shutdown.conf new file mode 100755 index 0000000..7ac5bf9 --- /dev/null +++ b/.config/sway/modes/70-shutdown.conf @@ -0,0 +1,15 @@ +# System mode menu +set $mode_system "What to do? (l) lock, (e) logout, (r) reboot, (s) suspend, (Shift+s) shutdown" + +mode $mode_system { + bindsym l exec $screenlock; mode "default" + bindsym e exec swaymsg exit; mode "default" + bindsym r exec systemctl reboot; mode "default" + bindsym s exec systemctl suspend; mode "default" + bindsym Shift+s exec systemctl poweroff; mode "default" + + # back to normal: Enter or Escape + bindsym Return mode "default" + bindsym Escape mode "default" +} + diff --git a/.config/sway/modes/recording b/.config/sway/modes/recording new file mode 100755 index 0000000..14bbcfa --- /dev/null +++ b/.config/sway/modes/recording @@ -0,0 +1,19 @@ +set $mode_recording " \ +Record (r) \ ++ [Shift for ]" + +set $recorder /usr/share/sway/scripts/recorder.sh + +mode --pango_markup $mode_recording { + $bindsym r exec $recorder, mode "default" + $bindsym Shift+r exec $recorder -a, mode "default" + + # Return to default mode. + $bindsym Escape mode "default" +} + +## Launch // Recording Mode ## +$bindsym $mod+Shift+r mode $mode_recording + +## Launch // Stop Recording Mode ## +$bindsym $mod+Escape exec killall -s SIGINT wf-recorder \ No newline at end of file diff --git a/.config/sway/modes/screenshot b/.config/sway/modes/screenshot new file mode 100755 index 0000000..9b3bc9e --- /dev/null +++ b/.config/sway/modes/screenshot @@ -0,0 +1,23 @@ +set $mode_screenshot " \ +Pick (p) \ +Output (o) \ ++ Shift for  \ ++ Ctrl for " + +mode --pango_markup $mode_screenshot { + # output = currently active output + $bindsym o mode "default", exec $screenshot_screen_clipboard + $bindsym Shift+o mode "default", exec $screenshot_screen_file + $bindsym Shift+Ctrl+o mode "default", exec $screenshot_screen_upload + + # pick the region to screenshot + $bindsym p mode "default", exec $screenshot_selection_clipboard + $bindsym Shift+p mode "default", exec $screenshot_selection_file + $bindsym Shift+Ctrl+p mode "default", exec $screenshot_selection_upload + + # Return to default mode. + $bindsym Escape mode "default" +} + +## Launch // Screenshot Mode ## +$bindsym Print mode $mode_screenshot diff --git a/.config/sway/outputs/default-screen.conf b/.config/sway/outputs/default-screen.conf new file mode 100755 index 0000000..b843579 --- /dev/null +++ b/.config/sway/outputs/default-screen.conf @@ -0,0 +1,35 @@ +### Output configuration +# +# Example configuration: +# +# output HDMI-A-1 resolution 1920x1080 position 1920,0 +# +# You can get the names of your outputs by running: swaymsg -t get_outputs +# Default wallpaper output * bg $background fill +# +# output $ext_monitor pos 0 0 res 1920x1080 output $int_monitor pos 1920 0 res 1920x1080 +# +# Default wallpaper (more resolutions are available in /usr/share/backgrounds/sway/) + + + +output $ext_monitor pos 0 0 res 1920x1080 +output $int_monitor pos 1920 0 res 1920x1080 + +# focus output $ext_monitor +# focus output $int_monitor + +bindswitch --reload --locked lid:on output $int_monitor disable +bindswitch --reload --locked lid:off output $int_monitor enable + +workspace 1 output $ext_monitor +workspace 2 output $ext_monitor +workspace 3 output $ext_monitor +workspace 4 output $ext_monitor +workspace 5 output $ext_monitor +workspace 6 output $int_monitor +workspace 7 output $int_monitor +workspace 8 output $int_monitor +workspace 9 output $int_monitor +workspace 0 output $int_monitor + diff --git a/.config/sway/swaync/config.json b/.config/sway/swaync/config.json new file mode 100755 index 0000000..ea55c07 --- /dev/null +++ b/.config/sway/swaync/config.json @@ -0,0 +1,38 @@ +{ + "$schema": "/etc/xdg/swaync/configSchema.json", + "positionX": "right", + "positionY": "top", + "control-center-margin-top": 0, + "control-center-margin-bottom": 0, + "control-center-margin-right": 0, + "control-center-margin-left": 0, + "notification-icon-size": 64, + "notification-body-image-height": 100, + "notification-body-image-width": 200, + "timeout": 10, + "timeout-low": 5, + "timeout-critical": 0, + "fit-to-screen": true, + "control-center-width": 500, + "control-center-height": 600, + "notification-window-width": 500, + "keyboard-shortcuts": true, + "image-visibility": "when-available", + "transition-time": 200, + "hide-on-clear": false, + "hide-on-action": true, + "script-fail-notify": true, + "scripts": { + "example-script": { + "exec": "echo 'Do something...'", + "urgency": "Normal" + } + }, + "notification-visibility": { + "example-name": { + "state": "muted", + "urgency": "Low", + "app-name": "Spotify" + } + } +} diff --git a/.config/sway/swaync/style.css b/.config/sway/swaync/style.css new file mode 100755 index 0000000..6376a88 --- /dev/null +++ b/.config/sway/swaync/style.css @@ -0,0 +1,217 @@ +@define-color cc-bg rgba(190, 29, 122, 0.4); + +@define-color noti-text-color rgba(122, 162, 247, 1); +@define-color noti-border-color rgba(149.2, 21, 95.1, 0.4); +@define-color noti-bg rgba(239, 78, 145, 0.4); +@define-color noti-bg-hover rgba(243.7, 60.5, 136.7, 1); +@define-color noti-bg-focus rgba(243.7, 60.5, 136.7, 0.6); +@define-color noti-close-bg rgba(115.0, 218.0, 202.0, 0.1); +@define-color noti-close-bg-hover rgba(115.0, 218.0, 202.0, 0.15); + +@define-color bg-selected rgba(231, 129, 179, 1); + +* { + font-family: "Comic Code"; + font-size: 15px; +} + +.notification-row { + outline: none; +} + +.notification-row:focus, +.notification-row:hover { + background: @noti-bg-focus; +} + +.notification { + border-radius: 12px; + margin: 6px 12px; + box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.3), 0 1px 3px 1px rgba(0, 0, 0, 0.7), + 0 2px 6px 2px rgba(0, 0, 0, 0.3); + padding: 0; +} + +.critical { + background: @bg-selected; + padding: 6px; + border-radius: 12px; +} + +/* Uncomment to enable specific urgency colors +.low { + background: yellow; + padding: 6px; + border-radius: 12px; +} + +.normal { + background: green; + padding: 6px; + border-radius: 12px; +} + +.critical { + background: red; + padding: 6px; + border-radius: 12px; +} +*/ + +.notification-content { + background: transparent; + padding: 6px; + border-radius: 12px; +} + +.close-button { + background: @noti-close-bg; + color: @noti-text-color; + text-shadow: none; + padding: 0; + border-radius: 100%; + margin-top: 10px; + margin-right: 16px; + box-shadow: none; + border: none; + min-width: 24px; + min-height: 24px; +} + +.close-button:hover { + box-shadow: none; + background: @noti-close-bg-hover; + transition: all 0.15s ease-in-out; + border: none; +} + +.notification-default-action, +.notification-action { + padding: 4px; + margin: 0; + box-shadow: none; + background: @noti-bg; + border: 1px solid @noti-border-color; + color: white; +} + +.notification-default-action:hover, +.notification-action:hover { + -gtk-icon-effect: none; + background: @noti-bg-hover; +} + +.notification-default-action { + border-radius: 12px; +} + +/* When alternative actions are visible */ +.notification-default-action:not(:only-child) { + border-bottom-left-radius: 0px; + border-bottom-right-radius: 0px; +} + +.notification-action { + border-radius: 0px; + border-top: none; + border-right: none; +} + +/* add bottom border radius to eliminate clipping */ +.notification-action:first-child { + border-bottom-left-radius: 10px; +} + +.notification-action:last-child { + border-bottom-right-radius: 10px; + border-right: 1px solid @noti-border-color; +} + +.image { +} + +.body-image { + margin-top: 6px; + background-color: white; + border-radius: 12px; +} + +.summary { + color: @noti-text-color; + text-shadow: none; +} + +.time { + color: @noti-text-color; + text-shadow: none; + margin-right: 18px; +} + +.body { + background: transparent; + color: @noti-text-color; + text-shadow: none; +} + +/* The "Notifications" and "Do Not Disturb" text widget */ +.top-action-title { + color: @noti-text-color; + text-shadow: none; +} + +.control-center-clear-all { + color: @noti-text-color; + text-shadow: none; + background: @cc-bg; + border: 1px solid @noti-border-color; + box-shadow: none; + border-radius: 12px; +} + +.control-center-clear-all:hover { + background: @noti-bg-hover; +} + +.control-center-dnd { + border-radius: 12px; + background: @noti-bg; + border: 1px solid @noti-border-color; + box-shadow: none; +} + +.control-center-dnd:checked { + background: @bg-selected; +} + +.control-center-dnd slider:hover { + background: @noti-close-bg-hover; +} + +.control-center-dnd slider { + background: @noti-bg-hover; + border-radius: 12px; +} + +/* The .control-center Window. + * Can't apply padding and margin so may be easier to use "> box" instead + */ +.control-center { + background: @cc-bg; +} + +/* The first control-center child. May be easier to style this than .control-center */ +.control-center > box { +} + +.control-center-list { + background: transparent; +} + +.floating-notifications { + background: transparent; +} + +/* Window behind control center and on all other monitors */ +.blank-window { + background: alpha(black, 0.25); +} diff --git a/.config/sway/wob/wob.ini b/.config/sway/wob/wob.ini new file mode 100755 index 0000000..e9e8348 --- /dev/null +++ b/.config/sway/wob/wob.ini @@ -0,0 +1,11 @@ +timeout = 1000 +height = 32 +border_offset = 0 +border_size = 2 +bar_padding = 2 +border_color = 35B9AB66 +background_color = 173F4F66 +bar_color = 35B9ABFF +overflow_border_color = EE2E2466 +overflow_background_color = 173F4F66 +overflow_bar_color = EE2E24FF diff --git a/.config/waybar/config.jsonc b/.config/waybar/config.jsonc new file mode 100755 index 0000000..1ebdbbe --- /dev/null +++ b/.config/waybar/config.jsonc @@ -0,0 +1,314 @@ +// ============================================================================= +// +// Waybar configuration +// +// Configuration reference: https://github.com/Alexays/Waybar/wiki/Configuration +// +// ============================================================================= + +{ + // ------------------------------------------------------------------------- + // Global configuration + // ------------------------------------------------------------------------- + + "layer": "top", + + // If height property would be not present, it'd be calculated dynamically + "height": 30, + "position": "top", + + "modules-left": ["custom/menu", "sway/workspaces", "custom/scratchpad"], + "modules-center": ["custom/wf-recorder", "sway/mode", "custom/weather"], + "modules-right": [ + + // informational + "sway/language", + //"custom/github", + //"custom/clipboard", + "cpu", + "memory", + "disk", + "battery", + "temperature", + + // connecting + "network", + //"bluetooth", + + // media + //"custom/playerctl", + "idle_inhibitor", + "pulseaudio", + "backlight", + + // system + //"custom/sunset", + //"custom/pacman", + + //"clock", + "custom/clock", + "tray" + ], + + // ------------------------------------------------------------------------- + // Modules + // ------------------------------------------------------------------------- + + "battery": { + "interval": 30, + "states": { + "warning": 30, + "critical": 15 + }, + "format-charging": " {capacity}%", + "format": "{icon} {capacity}%", + "format-icons": ["", "", "", "", "", ""], + "tooltip": true + //"bat": "BAT0" + }, + + "custom/clock": { + "exec": "echo ' '$(date +'%e %b %Y %H:%M')' '", + "interval": 60, + "tooltip": true, + "tooltip-format": "{:%B %Y}\n{calendar}", + "on-click": "swaymsg exec \\$calendar" + }, + + "clock": { + "interval": 60, + "format": "{:%e %b %Y %H:%M}", + "tooltip": true, + "tooltip-format": "{:%B %Y}\n{calendar}", + "on-click": "swaymsg exec \\$calendar" + }, + + "cpu": { + "interval": 5, + "format": "﬙ {usage}%", + "states": { + "warning": 70, + "critical": 90 + }, + "on-click": "swaymsg exec \\$term_float htop" + }, + + "memory": { + "interval": 5, + "format": " {}%", + "states": { + "warning": 70, + "critical": 90 + }, + "on-click": "swaymsg exec \\$term_float htop" + }, + + "network": { + "interval": 5, + "format-wifi": " ", + "format-ethernet": "", + "format-disconnected": "睊", + "tooltip-format": "{ifname} ({essid}): {ipaddr}", + "on-click": "swaymsg exec \\$term_float nmtui" + }, + + "sway/mode": { + "format": "{}", + "tooltip": false + }, + + "idle_inhibitor": { + "format": "{icon}", + "format-icons": { + "activated": "", + "deactivated": "" + } + }, + + "backlight": { + "format": "{icon} {percent}%", + "format-icons": ["", "", ""], + "on-scroll-up": "light -A 1", + "on-scroll-down": "light -U 1" + }, + + "pulseaudio": { + "scroll-step": 5, + "format": "{icon} {volume}%{format_source}", + "format-muted": "婢 {format_source}", + "format-source": "", + "format-source-muted": " ", + "format-icons": { + "headphone": "", + "headset": "", + "default": ["奄", "奔", "墳"] + }, + "tooltip-format": "{icon} {volume}% {format_source}", + "on-click": "swaymsg exec \\$pulseaudio" + }, + + "temperature": { + "critical-threshold": 90, + "interval": 5, + "format": "{icon} {temperatureC}°C", + "format-icons": ["", "", ""], + "tooltip": false, + "on-click": "swaymsg exec \"\\$term_float watch sensors\"" + }, + + "tray": { + "icon-size": 21, + "spacing": 5 + }, + + //"custom/pacman": { + // "format": " {}", + // "interval": 3600, + // "exec-if": "[ $(pamac checkupdates -q | wc -l) -gt 0 ]", + // "exec": "pamac checkupdates -q | wc -l", + // "on-click": "pamac-manager --updates; pkill -RTMIN+4 waybar", + // "signal": 4 + //}, + + "custom/menu": { + "format": "", + "on-click": "swaymsg exec \\$menu", + "tooltip": false + }, + + "bluetooth": { + "format": " {status}", + "format-connected": " {status}", + "format-connected-battery": " {status} {device_battery_percentage}%", + //"format-connected": " {device_alias}", + //"format-connected-battery": " {device_alias} {device_battery_percentage}%", + //"format-device-preference": [ "device1", "device2" ], // preference list deciding the displayed device + "tooltip-format": "{controller_alias}\t{controller_address}\n\n{num_connections} connected", + "tooltip-format-connected": "{controller_alias}\t{controller_address}\n\n{num_connections} connected\n\n{device_enumerate}", + "tooltip-format-enumerate-connected": "{device_alias}\t{device_address}", + "tooltip-format-enumerate-connected-battery": "{device_alias}\t{device_address}\t{device_battery_percentage}%" + }, + + "sway/language": { + "format": " {}", + "min-length": 5, + "tooltip": false, + "on-click": "swaymsg input $(swaymsg -t get_inputs --raw | jq '[.[] | select(.type == \"keyboard\")][0] | .identifier') xkb_switch_layout next" + }, + + "custom/scratchpad": { + "interval": "once", + "return-type": "json", + "format": "{icon}", + "format-icons": { + "one": "类", + "many": "缾" + }, + "exec": "/bin/sh ~/.config/waybar/scripts/scratchpad.sh", + "on-click": "swaymsg 'scratchpad show'", + "signal": 7 + }, + + "custom/sunset": { + "interval": "once", + "tooltip": false, + "return-type": "json", + "format": "{icon}", + "format-icons": { + "on": "", + "off": "" + }, + "exec": "~/.config/waybar/scripts/sunset.sh", + "on-click": "~/.config/waybar/scripts/sunset.sh toggle; pkill -RTMIN+6 waybar", + "exec-if": "~/.config/waybar/scripts/sunset.sh check", + "signal": 6 + }, + + "custom/wf-recorder": { + "interval": "once", + "return-type": "json", + "format": "{}", + "tooltip-format": "{tooltip}", + "exec": "echo '{\"class\": \"recording\",\"text\":\"雷\",\"tooltip\":\"press $mod+Esc to stop recording\"}'", + "exec-if": "pgrep wf-recorder", + "on-click": "killall -s SIGINT wf-recorder", + "signal": 8 + }, + + "custom/github": { + "interval": 300, + "tooltip": false, + "return-type": "json", + "format": " {}", + "exec": "gh api '/notifications' -q '{ text: length }' | cat -", + "exec-if": "[ -x \"$(command -v gh)\" ] && gh auth status 2>&1 | grep -q -m 1 'Logged in' && gh api '/notifications' -q 'length' | grep -q -m 1 '0' ; test $? -eq 1", + "on-click": "xdg-open https://github.com/notifications && sleep 30 && pkill -RTMIN+4 waybar", + "signal": 4 + }, + + "disk": { + "interval": 30, + "format": " {free}", + "path": "/" + }, + + "custom/playerctl": { + "interval": "once", + "tooltip": true, + "return-type": "json", + "format": "{icon}", + "format-icons": { + "Playing": "奈", + "Paused": "" + }, + "exec": "playerctl metadata --format '{\"alt\": \"{{status}}\", \"tooltip\": \"{{playerName}}: {{markup_escape(title)}} - {{markup_escape(artist)}}\" }'", + "on-click": "playerctl play-pause; pkill -RTMIN+5 waybar", + "on-click-right": "playerctl next; pkill -RTMIN+5 waybar", + "on-scroll-up": "playerctl position 10+; pkill -RTMIN+5 waybar", + "on-scroll-down": "playerctl position 10-; pkill -RTMIN+5 waybar", + "signal": 5 + }, + + "custom/clipboard": { + "format": "", + "interval": "once", + "return-type": "json", + "on-click": "swaymsg -q exec '$clipboard'; pkill -RTMIN+9 waybar", + "on-click-right": "swaymsg -q exec '$clipboard-del'; pkill -RTMIN+9 waybar", + "on-click-middle": "rm -f ~/.cache/cliphist/db; pkill -RTMIN+9 waybar", + "exec": "printf '{\"tooltip\":\"%s\"}' $(cliphist list | wc -l)", + "exec-if": "[ -x \"$(command -v cliphist)\" ] && [ $(cliphist list | wc -l) -gt 0 ]", + "signal": 9 + }, + + "custom/weather": { + "icon-size": 42, + "format": "{icon} {}", + "tooltip": true, + "interval": 3600, + // accepts a location as an argument (in quotes) + "exec": "~/.config/sway/waybar/scripts/weather.py", + "return-type": "json", + "format-icons": { + "Unknown": "", + "Cloudy": "摒", + "Fog": "", + "HeavyRain": "", + "HeavyShowers": "", + "HeavySnow": "", + "HeavySnowShowers": "ﰕ", + "LightRain": "", + "LightShowers": "", + "LightSleet": "", + "LightSleetShowers": "", + "LightSnow": "", + "LightSnowShowers": "ﭽ", + "PartlyCloudy": "", + "Sunny": "", + "ThunderyHeavyRain": "ﭼ", + "ThunderyShowers": "", + "ThunderySnowShowers": "", + "VeryCloudy": "" + } + } +} diff --git a/.config/waybar/contrib/autoname-workspaces.py b/.config/waybar/contrib/autoname-workspaces.py new file mode 100755 index 0000000..3ec3992 --- /dev/null +++ b/.config/waybar/contrib/autoname-workspaces.py @@ -0,0 +1,124 @@ +#!/usr/bin/python + +# This script requires i3ipc-python package (install it from a system package manager +# or pip). +# It adds icons to the workspace name for each open window. +# Set your keybindings like this: set $workspace1 workspace number 1 +# Add your icons to WINDOW_ICONS. +# Based on https://github.com/maximbaz/dotfiles/blob/master/bin/i3-autoname-workspaces + +import argparse +import i3ipc +import logging +import re +import signal +import sys + +WINDOW_ICONS = { + "firefox": "", +} + +DEFAULT_ICON = "󰀏" + + +def icon_for_window(window): + name = None + if window.app_id is not None and len(window.app_id) > 0: + name = window.app_id.lower() + elif window.window_class is not None and len(window.window_class) > 0: + name = window.window_class.lower() + + if name in WINDOW_ICONS: + return WINDOW_ICONS[name] + + logging.info("No icon available for window with name: %s" % str(name)) + return DEFAULT_ICON + +def rename_workspaces(ipc): + for workspace in ipc.get_tree().workspaces(): + name_parts = parse_workspace_name(workspace.name) + icon_tuple = () + for w in workspace: + if w.app_id is not None or w.window_class is not None: + icon = icon_for_window(w) + if not ARGUMENTS.duplicates and icon in icon_tuple: + continue + icon_tuple += (icon,) + name_parts["icons"] = " ".join(icon_tuple) + " " + new_name = construct_workspace_name(name_parts) + ipc.command('rename workspace "%s" to "%s"' % (workspace.name, new_name)) + + +def undo_window_renaming(ipc): + for workspace in ipc.get_tree().workspaces(): + name_parts = parse_workspace_name(workspace.name) + name_parts["icons"] = None + new_name = construct_workspace_name(name_parts) + ipc.command('rename workspace "%s" to "%s"' % (workspace.name, new_name)) + ipc.main_quit() + sys.exit(0) + + +def parse_workspace_name(name): + return re.match( + "(?P[0-9]+):?(?P\w+)? ?(?P.+)?", name + ).groupdict() + + +def construct_workspace_name(parts): + new_name = str(parts["num"]) + if parts["shortname"] or parts["icons"]: + new_name += ":" + + if parts["shortname"]: + new_name += parts["shortname"] + + if parts["icons"]: + new_name += " " + parts["icons"] + + return new_name + + +if __name__ == "__main__": + parser = argparse.ArgumentParser( + description="This script automatically changes the workspace name in sway depending on your open applications." + ) + parser.add_argument( + "--duplicates", + "-d", + action="store_true", + help="Set it when you want an icon for each instance of the same application per workspace.", + ) + parser.add_argument( + "--logfile", + "-l", + type=str, + default="/tmp/sway-autoname-workspaces.log", + help="Path for the logfile.", + ) + args = parser.parse_args() + global ARGUMENTS + ARGUMENTS = args + + logging.basicConfig( + level=logging.INFO, + filename=ARGUMENTS.logfile, + filemode="w", + format="%(message)s", + ) + + ipc = i3ipc.Connection() + + for sig in [signal.SIGINT, signal.SIGTERM]: + signal.signal(sig, lambda signal, frame: undo_window_renaming(ipc)) + + def window_event_handler(ipc, e): + if e.change in ["new", "close", "move"]: + rename_workspaces(ipc) + + ipc.on("window", window_event_handler) + + rename_workspaces(ipc) + + ipc.main() + diff --git a/.config/waybar/contrib/inactive-windows-transparency.py b/.config/waybar/contrib/inactive-windows-transparency.py new file mode 100755 index 0000000..b81134d --- /dev/null +++ b/.config/waybar/contrib/inactive-windows-transparency.py @@ -0,0 +1,69 @@ +#!/usr/bin/python + +# This script requires i3ipc-python package (install it from a system package manager +# or pip). +# It makes inactive windows transparent. Use `transparency_val` variable to control +# transparency strength in range of 0…1 or use the command line argument -o. + +import argparse +import i3ipc +import signal +import sys +from functools import partial + +def on_window_focus(inactive_opacity, ipc, event): + global prev_focused + global prev_workspace + + focused_workspace = ipc.get_tree().find_focused() + + if focused_workspace == None: + return + + focused = event.container + workspace = focused_workspace.workspace().num + + if focused.id != prev_focused.id: # https://github.com/swaywm/sway/issues/2859 + focused.command("opacity 1") + if workspace == prev_workspace: + prev_focused.command("opacity " + inactive_opacity) + prev_focused = focused + prev_workspace = workspace + + +def remove_opacity(ipc): + for workspace in ipc.get_tree().workspaces(): + for w in workspace: + w.command("opacity 1") + ipc.main_quit() + sys.exit(0) + + +if __name__ == "__main__": + transparency_val = "0.80" + + parser = argparse.ArgumentParser( + description="This script allows you to set the transparency of unfocused windows in sway." + ) + parser.add_argument( + "--opacity", + "-o", + type=str, + default=transparency_val, + help="set opacity value in range 0...1", + ) + args = parser.parse_args() + + ipc = i3ipc.Connection() + prev_focused = None + prev_workspace = ipc.get_tree().find_focused().workspace().num + + for window in ipc.get_tree(): + if window.focused: + prev_focused = window + else: + window.command("opacity " + args.opacity) + for sig in [signal.SIGINT, signal.SIGTERM]: + signal.signal(sig, lambda signal, frame: remove_opacity(ipc)) + ipc.on("window::focus", partial(on_window_focus, args.opacity)) + ipc.main() \ No newline at end of file diff --git a/.config/waybar/scripts/autoname-workspaces.py b/.config/waybar/scripts/autoname-workspaces.py new file mode 100755 index 0000000..3ec3992 --- /dev/null +++ b/.config/waybar/scripts/autoname-workspaces.py @@ -0,0 +1,124 @@ +#!/usr/bin/python + +# This script requires i3ipc-python package (install it from a system package manager +# or pip). +# It adds icons to the workspace name for each open window. +# Set your keybindings like this: set $workspace1 workspace number 1 +# Add your icons to WINDOW_ICONS. +# Based on https://github.com/maximbaz/dotfiles/blob/master/bin/i3-autoname-workspaces + +import argparse +import i3ipc +import logging +import re +import signal +import sys + +WINDOW_ICONS = { + "firefox": "", +} + +DEFAULT_ICON = "󰀏" + + +def icon_for_window(window): + name = None + if window.app_id is not None and len(window.app_id) > 0: + name = window.app_id.lower() + elif window.window_class is not None and len(window.window_class) > 0: + name = window.window_class.lower() + + if name in WINDOW_ICONS: + return WINDOW_ICONS[name] + + logging.info("No icon available for window with name: %s" % str(name)) + return DEFAULT_ICON + +def rename_workspaces(ipc): + for workspace in ipc.get_tree().workspaces(): + name_parts = parse_workspace_name(workspace.name) + icon_tuple = () + for w in workspace: + if w.app_id is not None or w.window_class is not None: + icon = icon_for_window(w) + if not ARGUMENTS.duplicates and icon in icon_tuple: + continue + icon_tuple += (icon,) + name_parts["icons"] = " ".join(icon_tuple) + " " + new_name = construct_workspace_name(name_parts) + ipc.command('rename workspace "%s" to "%s"' % (workspace.name, new_name)) + + +def undo_window_renaming(ipc): + for workspace in ipc.get_tree().workspaces(): + name_parts = parse_workspace_name(workspace.name) + name_parts["icons"] = None + new_name = construct_workspace_name(name_parts) + ipc.command('rename workspace "%s" to "%s"' % (workspace.name, new_name)) + ipc.main_quit() + sys.exit(0) + + +def parse_workspace_name(name): + return re.match( + "(?P[0-9]+):?(?P\w+)? ?(?P.+)?", name + ).groupdict() + + +def construct_workspace_name(parts): + new_name = str(parts["num"]) + if parts["shortname"] or parts["icons"]: + new_name += ":" + + if parts["shortname"]: + new_name += parts["shortname"] + + if parts["icons"]: + new_name += " " + parts["icons"] + + return new_name + + +if __name__ == "__main__": + parser = argparse.ArgumentParser( + description="This script automatically changes the workspace name in sway depending on your open applications." + ) + parser.add_argument( + "--duplicates", + "-d", + action="store_true", + help="Set it when you want an icon for each instance of the same application per workspace.", + ) + parser.add_argument( + "--logfile", + "-l", + type=str, + default="/tmp/sway-autoname-workspaces.log", + help="Path for the logfile.", + ) + args = parser.parse_args() + global ARGUMENTS + ARGUMENTS = args + + logging.basicConfig( + level=logging.INFO, + filename=ARGUMENTS.logfile, + filemode="w", + format="%(message)s", + ) + + ipc = i3ipc.Connection() + + for sig in [signal.SIGINT, signal.SIGTERM]: + signal.signal(sig, lambda signal, frame: undo_window_renaming(ipc)) + + def window_event_handler(ipc, e): + if e.change in ["new", "close", "move"]: + rename_workspaces(ipc) + + ipc.on("window", window_event_handler) + + rename_workspaces(ipc) + + ipc.main() + diff --git a/.config/waybar/scripts/battery-notification.sh b/.config/waybar/scripts/battery-notification.sh new file mode 100755 index 0000000..50e209b --- /dev/null +++ b/.config/waybar/scripts/battery-notification.sh @@ -0,0 +1,40 @@ +#!/bin/bash +# This program uses upower to check the battery percentage every 5 seconds +# Dependencies: upower, libnotify, alsa-utils * mako?? * +# Havent tested without mako, but it should work without it... + +# Defaults +THRESHOLD=20 # threshold percentage to send a notification +NOTIFICATION_SENT=0 + +while true; do +# Calculate the current percentage and round to whole number + CURRENT_PERCENTAGE=$(upower -i $(upower -e | grep 'BAT') | awk '/percentage/ {print $2}' | tr -d '%') + STATUS=$(upower -i $(upower -e | grep 'BAT') | grep -oP 'state:\s+\K\w+') +# Convert the status to an integer for easier comparison later + case "$STATUS" in + "charging") STATUS=1 ;; + "discharging") STATUS=0 ;; + *) STATUS=-1 ;; + esac + +# Send a notification if +# 1. The battery is discharging +# 2. The current percentage is less than the threshold +# 3. A notification hasn't been sent yet + if [ "$CURRENT_PERCENTAGE" -lt "$THRESHOLD" ] && [ "$STATUS" -eq 0 ] && [ "$NOTIFICATION_SENT" -eq 0 ]; then + # Send the notification and play a sound + notify-send -u low -a "BatteryNotification" -t 5000 "Low battery. Please plug in." + #This is for playing a sound, you can comment it out if you don't want it or change it to something else + ffplay -v 0 -nodisp -autoexit notification.mp3 > /dev/null 2>&1 + # IMPORTANT: Set the notification sent flag to 1 so we don't send another notification until the battery is charged + NOTIFICATION_SENT=1 + fi + +# Reset the notification sent flag if the battery is charging + if [ $STATUS -eq 1 ]; then + NOTIFICATION_SENT=0 + fi + + sleep 5 +done diff --git a/.config/waybar/scripts/grimshot b/.config/waybar/scripts/grimshot new file mode 100755 index 0000000..4ce31f2 --- /dev/null +++ b/.config/waybar/scripts/grimshot @@ -0,0 +1,154 @@ +#!/bin/sh + +## Grimshot: a helper for screenshots within sway +## Requirements: +## - `grim`: screenshot utility for wayland +## - `slurp`: to select an area +## - `swaymsg`: to read properties of current window +## - `wl-copy`: clipboard utility +## - `jq`: json utility to parse swaymsg output +## - `notify-send`: to show notifications +## Those are needed to be installed, if unsure, run `grimshot check` +## +## See `man 1 grimshot` or `grimshot usage` for further details. + +getTargetDirectory() { + test -f ${XDG_CONFIG_HOME:-~/.config}/user-dirs.dirs && \ + . ${XDG_CONFIG_HOME:-~/.config}/user-dirs.dirs + + echo ${XDG_SCREENSHOTS_DIR:-${XDG_PICTURES_DIR:-$HOME}} +} + +if [ "$1" = "--notify" ]; then + NOTIFY=yes + shift 1 +else + NOTIFY=no +fi + +ACTION=${1:-usage} +SUBJECT=${2:-screen} +FILE=${3:-$(getTargetDirectory)/$(date -Ins).png} + +if [ "$ACTION" != "save" ] && [ "$ACTION" != "copy" ] && [ "$ACTION" != "check" ]; then + echo "Usage:" + echo " grimshot [--notify] (copy|save) [active|screen|output|area|window] [FILE|-]" + echo " grimshot check" + echo " grimshot usage" + echo "" + echo "Commands:" + echo " copy: Copy the screenshot data into the clipboard." + echo " save: Save the screenshot to a regular file or '-' to pipe to STDOUT." + echo " check: Verify if required tools are installed and exit." + echo " usage: Show this message and exit." + echo "" + echo "Targets:" + echo " active: Currently active window." + echo " screen: All visible outputs." + echo " output: Currently active output." + echo " area: Manually select a region." + echo " window: Manually select a window." + exit +fi + +notify() { + notify-send -t 3000 -a grimshot "$@" +} +notifyOk() { + [ "$NOTIFY" = "no" ] && return + + TITLE=${2:-"Screenshot"} + MESSAGE=${1:-"OK"} + notify "$TITLE" "$MESSAGE" +} +notifyError() { + if [ $NOTIFY = "yes" ]; then + TITLE=${2:-"Screenshot"} + MESSAGE=${1:-"Error taking screenshot with grim"} + notify -u critical "$TITLE" "$MESSAGE" + else + echo $1 + fi +} + +die() { + MSG=${1:-Bye} + notifyError "Error: $MSG" + exit 2 +} + +check() { + COMMAND=$1 + if command -v "$COMMAND" > /dev/null 2>&1; then + RESULT="OK" + else + RESULT="NOT FOUND" + fi + echo " $COMMAND: $RESULT" +} + +takeScreenshot() { + FILE=$1 + GEOM=$2 + OUTPUT=$3 + if [ ! -z "$OUTPUT" ]; then + grim -o "$OUTPUT" "$FILE" || die "Unable to invoke grim" + elif [ -z "$GEOM" ]; then + grim "$FILE" || die "Unable to invoke grim" + else + grim -g "$GEOM" "$FILE" || die "Unable to invoke grim" + fi +} + +if [ "$ACTION" = "check" ] ; then + echo "Checking if required tools are installed. If something is missing, install it to your system and make it available in PATH..." + check grim + check slurp + check swaymsg + check wl-copy + check jq + check notify-send + exit +elif [ "$SUBJECT" = "area" ] ; then + GEOM=$(slurp -d) + # Check if user exited slurp without selecting the area + if [ -z "$GEOM" ]; then + exit 1 + fi + WHAT="Area" +elif [ "$SUBJECT" = "active" ] ; then + FOCUSED=$(swaymsg -t get_tree | jq -r 'recurse(.nodes[]?, .floating_nodes[]?) | select(.focused)') + GEOM=$(echo "$FOCUSED" | jq -r '.rect | "\(.x),\(.y) \(.width)x\(.height)"') + APP_ID=$(echo "$FOCUSED" | jq -r '.app_id') + WHAT="$APP_ID window" +elif [ "$SUBJECT" = "screen" ] ; then + GEOM="" + WHAT="Screen" +elif [ "$SUBJECT" = "output" ] ; then + GEOM="" + OUTPUT=$(swaymsg -t get_outputs | jq -r '.[] | select(.focused)' | jq -r '.name') + WHAT="$OUTPUT" +elif [ "$SUBJECT" = "window" ] ; then + GEOM=$(swaymsg -t get_tree | jq -r '.. | select(.pid? and .visible?) | .rect | "\(.x),\(.y) \(.width)x\(.height)"' | slurp) + # Check if user exited slurp without selecting the area + if [ -z "$GEOM" ]; then + exit 1 + fi + WHAT="Window" +else + die "Unknown subject to take a screen shot from" "$SUBJECT" +fi + +if [ "$ACTION" = "copy" ] ; then + takeScreenshot - "$GEOM" "$OUTPUT" | wl-copy --type image/png || die "Clipboard error" + notifyOk "$WHAT copied to buffer" +else + if takeScreenshot "$FILE" "$GEOM" "$OUTPUT"; then + TITLE="Screenshot of $SUBJECT" + MESSAGE=$(basename "$FILE") + notifyOk "$MESSAGE" "$TITLE" + echo $FILE + else + notifyError "Error taking screenshot with grim" + fi +fi diff --git a/.config/waybar/scripts/help.sh b/.config/waybar/scripts/help.sh new file mode 100755 index 0000000..a5e1a4d --- /dev/null +++ b/.config/waybar/scripts/help.sh @@ -0,0 +1,24 @@ +#!/bin/sh +set -x +# toggles the help wrapper state + +STATE_FILE=$HOME/.config/nwg-wrapper/help.state +PID_FILE=$HOME/.config/nwg-wrapper/help.pid + +PID=$(cat $PID_FILE 2>/dev/null) +STATE=$(cat $STATE_FILE 2>/dev/null) + +if [[ $STATE == 'true' && "$1" != "--restore" ]] || [[ "$1" == "--restore" && $STATE == 'false' ]] +then + if kill -0 $PID; then + kill -9 $PID + rm -rf $PID_FILE + fi + echo "false" > $STATE_FILE +else + if ! kill -0 $PID; then + nwg-wrapper -s help.sh -p left -a end & + echo $! > $PID_FILE + fi + echo "true" > $STATE_FILE +fi diff --git a/.config/waybar/scripts/inactive-windows-transparency.py b/.config/waybar/scripts/inactive-windows-transparency.py new file mode 100755 index 0000000..b81134d --- /dev/null +++ b/.config/waybar/scripts/inactive-windows-transparency.py @@ -0,0 +1,69 @@ +#!/usr/bin/python + +# This script requires i3ipc-python package (install it from a system package manager +# or pip). +# It makes inactive windows transparent. Use `transparency_val` variable to control +# transparency strength in range of 0…1 or use the command line argument -o. + +import argparse +import i3ipc +import signal +import sys +from functools import partial + +def on_window_focus(inactive_opacity, ipc, event): + global prev_focused + global prev_workspace + + focused_workspace = ipc.get_tree().find_focused() + + if focused_workspace == None: + return + + focused = event.container + workspace = focused_workspace.workspace().num + + if focused.id != prev_focused.id: # https://github.com/swaywm/sway/issues/2859 + focused.command("opacity 1") + if workspace == prev_workspace: + prev_focused.command("opacity " + inactive_opacity) + prev_focused = focused + prev_workspace = workspace + + +def remove_opacity(ipc): + for workspace in ipc.get_tree().workspaces(): + for w in workspace: + w.command("opacity 1") + ipc.main_quit() + sys.exit(0) + + +if __name__ == "__main__": + transparency_val = "0.80" + + parser = argparse.ArgumentParser( + description="This script allows you to set the transparency of unfocused windows in sway." + ) + parser.add_argument( + "--opacity", + "-o", + type=str, + default=transparency_val, + help="set opacity value in range 0...1", + ) + args = parser.parse_args() + + ipc = i3ipc.Connection() + prev_focused = None + prev_workspace = ipc.get_tree().find_focused().workspace().num + + for window in ipc.get_tree(): + if window.focused: + prev_focused = window + else: + window.command("opacity " + args.opacity) + for sig in [signal.SIGINT, signal.SIGTERM]: + signal.signal(sig, lambda signal, frame: remove_opacity(ipc)) + ipc.on("window::focus", partial(on_window_focus, args.opacity)) + ipc.main() \ No newline at end of file diff --git a/.config/waybar/scripts/notification.mp3 b/.config/waybar/scripts/notification.mp3 new file mode 100755 index 0000000..4cb3394 Binary files /dev/null and b/.config/waybar/scripts/notification.mp3 differ diff --git a/.config/waybar/scripts/recorder.sh b/.config/waybar/scripts/recorder.sh new file mode 100755 index 0000000..7d96ffe --- /dev/null +++ b/.config/waybar/scripts/recorder.sh @@ -0,0 +1,47 @@ +#!/bin/bash +set -x + +pid=`pgrep wf-recorder` +status=$? + +gif=false + +countdown() { + notify "Recording in 3 seconds" -t 1000 + sleep 1 + notify "Recording in 2 seconds" -t 1000 + sleep 1 + notify "Recording in 1 seconds" -t 1000 + sleep 1 +} + +notify() { + line=$1 + shift + notify-send "Recording" "${line}" -i /usr/share/icons/Papirus-Dark/32x32/devices/camera-video.svg $*; +} + +if [ $status != 0 ] +then + target_path=$(xdg-user-dir VIDEOS) + timestamp=$(date +'recording_%Y%m%d-%H%M%S') + + notify "Select a region to record" -t 1000 + area=$(swaymsg -t get_tree | jq -r '.. | select(.pid? and .visible?) | .rect | "\(.x),\(.y) \(.width)x\(.height)"' | slurp) + + countdown + (sleep 0.5 && pkill -RTMIN+8 waybar) & + + if [ "$1" == "-a" ]; then + file="$target_path/$timestamp.mp4" + wf-recorder --audio -g "$area" --file="$file" + else + file="$target_path/$timestamp.webm" + wf-recorder -g "$area" -c libvpx --codec-param="qmin=0" --codec-param="qmax=25" --codec-param="crf=4" --codec-param="b:v=1M" --file="$file" + fi + + pkill -RTMIN+8 waybar && notify "Finished recording ${file}" +else + pkill --signal SIGINT wf-recorder + pkill -RTMIN+8 waybar +fi \ No newline at end of file diff --git a/.config/waybar/scripts/sbdp.py b/.config/waybar/scripts/sbdp.py new file mode 100755 index 0000000..3f1d794 --- /dev/null +++ b/.config/waybar/scripts/sbdp.py @@ -0,0 +1,142 @@ +#!/usr/bin/python +import glob +import json +import re +import sys +from typing import Text + +if len(sys.argv) >= 2: + rootPath = sys.argv[1] +else: + rootPath = "~/.config/sway/config" + + +def readFile(filePath): + try: + paths = glob.glob(filePath) + except: + print("couldn't resolve glob:", filePath) + paths = [] + + allLines: list[str] = [] + for path in paths: + allLines = allLines + open(path, "r").readlines() + + finalLines: list[str] = [] + for line in allLines: + if re.search(r"^include\s+(.+?)$", line): + nextPath = re.findall(r"^include\s+(.+?)$", line)[0] + finalLines = finalLines + readFile(nextPath) + else: + finalLines = finalLines + [line] + + return finalLines + + +lines = readFile(rootPath) + + +def findKeybindingForLine(lineNumber: int, lines: list[str]): + return lines[lineNumber + 1].split(" ")[1] + + +class DocsConfig: + category: Text + action: Text + keybinding: Text + + +def getDocsConfig(lines: list[str]): + docsLineRegex = ( + r"^## (?P.+?) // (?P.+?)\s+(// (?P.+?))*##" + ) + docsConfig: list[DocsConfig] = [] + for index, line in enumerate(lines): + match = re.match(docsLineRegex, line) + if match: + config = DocsConfig() + config.category = match.group("category") + config.action = match.group("action") + config.keybinding = match.group("keybinding") + if config.keybinding == None: + config.keybinding = findKeybindingForLine(index, lines) + docsConfig = docsConfig + [config] + return docsConfig + + +def getSymbolDict(lines: list[str]): + setRegex = r"^set\s+(?P\$.+?)\s(?P.+)?" + dictionary = {} + for line in lines: + match = re.match(setRegex, line) + if match: + if match.group("variable"): + dictionary[match.group("variable")] = match.group("value") + return dict(dictionary) + + +translations = { + "Mod1": "Alt", + "Mod2": "", + "Mod3": "בּ", + "Mod4": "", + "Mod5": "Scroll", + "question": "?", + "space": "␣", + "minus": "-", + "plus": "+", + "Return": "", + "XF86AudioRaiseVolume": "ﱛ", + "XF86AudioLowerVolume": "ﱜ", + "XF86AudioMute": "ﱝ", + "XF86AudioMicMute": "", + "XF86MonBrightnessUp": "", + "XF86MonBrightnessDown": "", + "XF86PowerOff": "襤", + "XF86TouchpadToggle": "Toggle Touchpad", +} + + +def translate(word: Text, dictionary: dict): + try: + return dictionary[word.strip()] + except: + return word.strip() + + +def replaceBindingFromMap(binding: Text, dictionary: dict): + elements = binding.split("+") + resultElements = [] + for el in elements: + translation = translate(translate(el, dictionary), translations) + resultElements = resultElements + [translation] + + return " + ".join(resultElements) + + +def sanitize(configs: list[DocsConfig], symbolDict: dict): + for index, config in enumerate(configs): + config.keybinding = replaceBindingFromMap(config.keybinding, symbolDict) + configs[index] = config + return configs + + +def getDocsList(lines: list[str]): + docsConfig = getDocsConfig(lines) + symbolDict = getSymbolDict(lines) + sanitizedConfig = sanitize(docsConfig, symbolDict) + return sanitizedConfig + + +docsList = getDocsList(lines) + +result = [] +for config in docsList: + result = result + [ + { + "category": config.category, + "action": config.action, + "keybinding": config.keybinding, + } + ] +print(json.dumps(result)) diff --git a/.config/waybar/scripts/scratchpad.sh b/.config/waybar/scripts/scratchpad.sh new file mode 100755 index 0000000..8b2ca24 --- /dev/null +++ b/.config/waybar/scripts/scratchpad.sh @@ -0,0 +1,15 @@ +#!/bin/sh +tooltip=$(swaymsg -r -t get_tree | jq -r 'recurse(.nodes[]) | first(select(.name=="__i3_scratch")) | .floating_nodes | .[] | "\(.app_id) | \(.name)"') +count=$(echo -n "$tooltip" | grep -c '^') + +if [[ "$count" -eq 0 ]]; then + exit 1 +elif [[ "$count" -eq 1 ]]; then + class="one" +elif [[ "$count" -gt 1 ]]; then + class="many" +else + class="unknown" +fi + +printf '{"text":"%s", "class":"%s", "alt":"%s", "tooltip":"%s"}\n' "$count" "$class" "$class" "${tooltip//$'\n'/'\n'}" diff --git a/.config/waybar/scripts/setkeyboard.sh b/.config/waybar/scripts/setkeyboard.sh new file mode 100755 index 0000000..dc94bf9 --- /dev/null +++ b/.config/waybar/scripts/setkeyboard.sh @@ -0,0 +1,5 @@ +#!/bin/sh +## updates the sway keyboard setting to the currently active X11 layout + +swaymsg input type:keyboard xkb_layout "$(localectl status | grep "X11 Layout" | sed -e "s/^.*X11 Layout://")" +swaymsg input type:keyboard xkb_variant "$(localectl status | grep "X11 Variant" | sed -e "s/^.*X11 Variant://")" \ No newline at end of file diff --git a/.config/waybar/scripts/sunset.sh b/.config/waybar/scripts/sunset.sh new file mode 100755 index 0000000..de246f4 --- /dev/null +++ b/.config/waybar/scripts/sunset.sh @@ -0,0 +1,60 @@ +#!/bin/bash + +#Startup function +function start(){ + [[ -f "$HOME/.config/wlsunset/config" ]] && source "$HOME/.config/wlsunset/config" + temp_low=${temp_low:-"4000"} + temp_high=${temp_high:-"6500"} + duration=${duration:-"900"} + sunrise=${sunrise:-"07:00"} + sunset=${sunset:-"19:00"} + longitude=${longitude:-65} + latitude=${latitude:-65} + location=${location:-"off"} + + if [ "${location}" = "on" ]; + then + CONTENT=$(curl -s https://freegeoip.app/json/) + content_longitude=$(echo $CONTENT | jq '.longitude // empty') + longitude=${content_longitude:-"${longitude}"} + content_latitude=$(echo $CONTENT | jq '.latitude // empty') + latitude=${content_latitude:-"${latitude}"} + wlsunset -l $latitude -L $longitude -t $temp_low -T $temp_high -d $duration & + else + wlsunset -t $temp_low -T $temp_high -d $duration -S $sunrise -s $sunset & + fi +} + +#Accepts managing parameter +case $1'' in + 'off') + pkill wlsunset + ;; + + 'on') + start + ;; + + 'toggle') + if pkill -0 wlsunset + then + pkill wlsunset + else + start + fi + ;; + 'check') + command -v wlsunset + exit $? + ;; +esac + +#Returns a string for Waybar +if pkill -0 wlsunset +then + class="on" +else + class="off" +fi + +printf '{"alt":"%s"}\n' "$class" diff --git a/.config/waybar/scripts/upload-image.sh b/.config/waybar/scripts/upload-image.sh new file mode 100755 index 0000000..3d93647 --- /dev/null +++ b/.config/waybar/scripts/upload-image.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +URL=$(curl -s -F "file=@\"$1\";filename=.png" 'https://x0.at') +echo $URL | wl-copy +notify-send " $URL" diff --git a/.config/waybar/scripts/weather.py b/.config/waybar/scripts/weather.py new file mode 100755 index 0000000..d49de97 --- /dev/null +++ b/.config/waybar/scripts/weather.py @@ -0,0 +1,145 @@ +#!/usr/bin/env python + +# credits: @bjesus https://gist.github.com/bjesus/f8db49e1434433f78e5200dc403d58a3 + +import json +import requests +import sys +import urllib.parse +from datetime import datetime + +WEATHER_SYMBOL = { + "Unknown": "✨", + "Cloudy": "☁️", + "Fog": "🌫", + "HeavyRain": "🌧", + "HeavyShowers": "🌧", + "HeavySnow": "❄️", + "HeavySnowShowers": "❄️", + "LightRain": "🌦", + "LightShowers": "🌦", + "LightSleet": "🌧", + "LightSleetShowers": "🌧", + "LightSnow": "🌨", + "LightSnowShowers": "🌨", + "PartlyCloudy": "⛅️", + "Sunny": "☀️", + "ThunderyHeavyRain": "🌩", + "ThunderyShowers": "⛈", + "ThunderySnowShowers": "⛈", + "VeryCloudy": "☁️", +} + +WWO_CODE = { + "113": "Sunny", + "116": "PartlyCloudy", + "119": "Cloudy", + "122": "VeryCloudy", + "143": "Fog", + "176": "LightShowers", + "179": "LightSleetShowers", + "182": "LightSleet", + "185": "LightSleet", + "200": "ThunderyShowers", + "227": "LightSnow", + "230": "HeavySnow", + "248": "Fog", + "260": "Fog", + "263": "LightShowers", + "266": "LightRain", + "281": "LightSleet", + "284": "LightSleet", + "293": "LightRain", + "296": "LightRain", + "299": "HeavyShowers", + "302": "HeavyRain", + "305": "HeavyShowers", + "308": "HeavyRain", + "311": "LightSleet", + "314": "LightSleet", + "317": "LightSleet", + "320": "LightSnow", + "323": "LightSnowShowers", + "326": "LightSnowShowers", + "329": "HeavySnow", + "332": "HeavySnow", + "335": "HeavySnowShowers", + "338": "HeavySnow", + "350": "LightSleet", + "353": "LightShowers", + "356": "HeavyShowers", + "359": "HeavyRain", + "362": "LightSleetShowers", + "365": "LightSleetShowers", + "368": "LightSnowShowers", + "371": "HeavySnowShowers", + "374": "LightSleetShowers", + "377": "LightSleet", + "386": "ThunderyShowers", + "389": "ThunderyHeavyRain", + "392": "ThunderySnowShowers", + "395": "HeavySnowShowers", +} + +data = {} + +try: + city = urllib.parse.quote(sys.argv[1].strip()) +except: + #city = "ireland_dublin" + city = "ciudad_juarez" + +weather = requests.get("https://wttr.in/" + city + "?format=j1").json() + + +def format_time(time): + return time.replace("00", "").zfill(2) + + +def format_temp(temp): + return (hour['FeelsLikeC']+"°").ljust(3) + + +def format_chances(hour): + chances = { + "chanceoffog": "Fog", + "chanceoffrost": "Frost", + "chanceofovercast": "Overcast", + "chanceofrain": "Rain", + "chanceofsnow": "Snow", + "chanceofsunshine": "Sunshine", + "chanceofthunder": "Thunder", + "chanceofwindy": "Wind" + } + + conditions = [] + for event in chances.keys(): + if int(hour[event]) > 0: + conditions.append(chances[event]+" "+hour[event]+"%") + return ", ".join(conditions) + + +data['text'] = weather['current_condition'][0]['FeelsLikeC']+"°" +data['alt'] = WWO_CODE[weather['current_condition'][0]['weatherCode']] + +data['tooltip'] = f"{weather['current_condition'][0]['weatherDesc'][0]['value']} {weather['current_condition'][0]['temp_C']}°\n" +data['tooltip'] += f"Feels like: {weather['current_condition'][0]['FeelsLikeC']}°\n" +data['tooltip'] += f"Wind: {weather['current_condition'][0]['windspeedKmph']}Km/h\n" +data['tooltip'] += f"Humidity: {weather['current_condition'][0]['humidity']}%\n" +for i, day in enumerate(weather['weather']): + data['tooltip'] += f"\n" + if i == 0: + data['tooltip'] += "Today, " + if i == 1: + data['tooltip'] += "Tomorrow, " + data['tooltip'] += f"{day['date']}\n" + data['tooltip'] += f"⬆️ {day['maxtempC']}° ⬇️ {day['mintempC']}° " + data['tooltip'] += f"🌅 {day['astronomy'][0]['sunrise']} 🌇 {day['astronomy'][0]['sunset']}\n" + for hour in day['hourly']: + if i == 0: + if int(format_time(hour['time'])) < datetime.now().hour-2: + continue + data['tooltip'] += f"{format_time(hour['time'])} {WEATHER_SYMBOL[WWO_CODE[hour['weatherCode']]]} {format_temp(hour['FeelsLikeC'])} {hour['weatherDesc'][0]['value']}, {format_chances(hour)}\n" + + +print(json.dumps(data)) diff --git a/.config/waybar/scripts/wob.sh b/.config/waybar/scripts/wob.sh new file mode 100755 index 0000000..dc24061 --- /dev/null +++ b/.config/waybar/scripts/wob.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash +# https://github.com/francma/wob/wiki/wob-wrapper-script +#$1 - accent color. $2 - background color. $3 - new value +# returns 0 (success) if $1 is running and is attached to this sway session; else 1 +is_running_on_this_screen() { + pkill -0 $1 || return 1 + for pid in $( pgrep $1 ); do + WOB_SWAYSOCK="$( tr '\0' '\n' < /proc/$pid/environ | awk -F'=' '/^SWAYSOCK/ {print $2}' )" + if [[ "$WOB_SWAYSOCK" == "$SWAYSOCK" ]]; then + return 0 + fi + done + return 1 +} + +new_value=$3 # null or a percent; no checking!! + +wob_pipe=~/.cache/$( basename $SWAYSOCK ).wob + +[[ -p $wob_pipe ]] || mkfifo $wob_pipe + +# wob does not appear in $(swaymsg -t get_msg), so: +is_running_on_this_screen wob || { + tail -f $wob_pipe | wob --border-color $1 --bar-color $1 --background-color $2 --anchor top --anchor center --margin 20 & +} + +[[ "$new_value" ]] && echo $new_value > $wob_pipe diff --git a/.config/waybar/style.css b/.config/waybar/style.css new file mode 100755 index 0000000..7f1e748 --- /dev/null +++ b/.config/waybar/style.css @@ -0,0 +1,214 @@ +/* ============================================================================= + * + * Waybar configuration + * + * Configuration reference: https://github.com/Alexays/Waybar/wiki/Configuration + * + * =========================================================================== */ + +/* import css definitions for current theme */ +@import "theme.css"; + +/* ----------------------------------------------------------------------------- + * Keyframes + * -------------------------------------------------------------------------- */ + +@keyframes blink-warning { + 70% { + color: @wm_icon_bg; + } + + to { + color: @wm_icon_bg; + background-color: @warning_color; + } +} + +@keyframes blink-critical { + 70% { + color: @wm_icon_bg; + } + + to { + color: @wm_icon_bg; + background-color: @error_color; + } +} + +/* ----------------------------------------------------------------------------- + * Base styles + * -------------------------------------------------------------------------- */ + +/* Reset all styles */ +* { + border: none; + border-radius: 0; + min-height: 0; + margin: 0; + padding: 0; + font-family: "Terminess Nerd Font Mono", "Terminess Nerd Font", sans-serif; + /*font-family: "Comic Code", "Comic Code", sans-serif;*/ +} + +/* The whole bar */ +#waybar { + background: @background_color; + color: @text_color; + font-size: 14px; +} + +/* Each module */ +#custom-pacman, +#custom-menu, +#custom-help, +#custom-scratchpad, +#custom-github, +#custom-clipboard, +#bluetooth, +#battery, +#clock, +#cpu, +#memory, +#mode, +#network, +#pulseaudio, +#temperature, +#idle_inhibitor, +#backlight, +#language, +#custom-sunset, +#custom-playerctl, +#tray { + padding-left: 10px; + padding-right: 10px; +} + +/* ----------------------------------------------------------------------------- + * Module styles + * -------------------------------------------------------------------------- */ + +#custom-scratchpad { + background-color: @background_color; +} + +#battery { + animation-timing-function: linear; + animation-iteration-count: infinite; + animation-direction: alternate; +} + +#battery.warning { + color: @warning_color; +} + +#battery.critical { + color: @error_color; +} + +#battery.warning.discharging { + animation-name: blink-warning; + animation-duration: 3s; +} + +#battery.critical.discharging { + animation-name: blink-critical; + animation-duration: 2s; +} + +#clock { + font-weight: bold; + background-color: @accent_color; +} + +#custom-clock { + /*color: @bright_text_color;*/ + color: @black_color; + font-weight: bold; + background-color: @accent_color; +} + +#cpu.warning { + color: @warning_color; +} + +#cpu.critical { + color: @error_color; +} + +#custom-menu { + color: @bright_text_color; + background-color: @accent_color; + padding-left: 10px; + padding-right: 14px; +} + +#memory { + animation-timing-function: linear; + animation-iteration-count: infinite; + animation-direction: alternate; +} + +#memory.warning { + color: @warning_color; +} + +#memory.critical { + color: @error_color; + animation-name: blink-critical; + animation-duration: 2s; +} + +#mode { + background: @background_color; +} + +#network.disconnected { + color: @warning_color; +} + +#pulseaudio.muted { + color: @warning_color; +} + +#temperature.critical { + color: @error_color; +} + +#window { + font-weight: bold; + margin-right: 25px; + color: @theme_selected_bg_color; +} + +#workspaces button { + border-top: 2px solid transparent; + /* To compensate for the top border and still have vertical centering */ + padding-bottom: 2px; + padding-left: 10px; + padding-right: 10px; + color: @text_color; +} + +#workspaces button.focused { + border-color: @bright_text_color; + color: @bright_text_color; + background-color: @accent_color; +} + +#workspaces button.urgent { + border-color: @error_color; + color: @error_color; +} + +#custom-pacman { + color: @warning_color; +} + +#bluetooth.disabled { + color: @warning_color; +} + +#custom-wf-recorder { + color: @error_color; + padding-right: 10px; +} diff --git a/.config/waybar/theme.css b/.config/waybar/theme.css new file mode 100755 index 0000000..b47b947 --- /dev/null +++ b/.config/waybar/theme.css @@ -0,0 +1,13 @@ +/* theme specific color values */ +/* file will be overwritten on each logon with values from configured theme in /usr/share/sway/themes */ +@define-color transparent_background_color rgba(20, 22, 27, 0.9); +@define-color background_color #111111; +@define-color bright_text_color #ffffff; +/*@define-color dim_text_color #cab9d0; */ +@define-color dim_text_color #ffffff; +@define-color text_color #e5097f; +/*@define-color accent_color #d960a8; */ +@define-color accent_color #e5097f; +@define-color alternative_color #b7026d; +@define-color warning_color #524778; +@define-color error_color #dc3545; diff --git a/.config/waybar/themes/matcha-pink/theme.css b/.config/waybar/themes/matcha-pink/theme.css new file mode 100755 index 0000000..0086452 --- /dev/null +++ b/.config/waybar/themes/matcha-pink/theme.css @@ -0,0 +1,13 @@ +/* theme specific color values */ +/* file will be overwritten on each logon with values from configured theme in /usr/share/sway/themes */ +@define-color transparent_background_color rgba(20, 22, 27, 0.9); +@define-color background_color #b7026d; +@define-color bright_text_color #e88fda; +@define-color dim_text_color #cab9d0; +/*@define-color text_color #e88fda;*/ +@define-color text_color #f8b8d0; +@define-color accent_color #d960a8; +@define-color alternative_color #b7026d; +@define-color warning_color #524778; +@define-color error_color #dc3545; +@define-color black_color #000000; diff --git a/.gitconfig b/.gitconfig old mode 100644 new mode 100755 index 8d3a8f5..241d1d7 --- a/.gitconfig +++ b/.gitconfig @@ -4,3 +4,7 @@ name = Eduardo Cueto-Mendoza [commit] gpgsign = true +[safe] + directory = /usr/share/pyenv +[init] + defaultBranch = main diff --git a/.gitignore b/.gitignore old mode 100644 new mode 100755 diff --git a/.gnupg/common.conf b/.gnupg/common.conf old mode 100644 new mode 100755 diff --git a/.gnupg/gpg-agent.conf b/.gnupg/gpg-agent.conf index 5ba1cb9..549e052 100644 --- a/.gnupg/gpg-agent.conf +++ b/.gnupg/gpg-agent.conf @@ -6,10 +6,8 @@ #pinentry-program /usr/local/bin/pinentry-curses #pinentry-program /usr/local/bin/pinentry-mac #pinentry-program /opt/homebrew/bin/pinentry-mac -pinentry-program /opt/homebrew/bin/pinentry -#pinentry-program /usr/bin/pinentry-curses +pinentry-program /usr/bin/pinentry-curses enable-ssh-support ttyname $GPG_TTY default-cache-ttl 60 max-cache-ttl 120 -allow-loopback-pinentry diff --git a/.gnupg/gpg.conf b/.gnupg/gpg.conf old mode 100644 new mode 100755 diff --git a/.stow-local-ignore b/.stow-local-ignore old mode 100644 new mode 100755 diff --git a/.wgetrc b/.wgetrc old mode 100644 new mode 100755