From 2162cd594ccd0309ed12293021b09394532c6880 Mon Sep 17 00:00:00 2001 From: Protesilaos Stavrou Date: Fri, 27 Aug 2021 14:56:26 +0300 Subject: [PATCH] bspwm: bring back old configs; add changes (WIP) I plan to switch back to my bspwm setup. There probably is a lot of work to be done here, though my quick experiments today show that we are on the right path. --- bin/bin/bspwm_conf_colors | 43 ++ bin/bin/bspwm_conf_desktops | 32 ++ bin/bin/bspwm_conf_reset_monitors | 57 +++ bin/bin/bspwm_conf_xrandr | 66 +++ bin/bin/bspwm_dynamic_desktops | 223 +++++++++ bin/bin/bspwm_external_rules | 98 ++++ bin/bin/bspwm_focus_mode | 84 ++++ bin/bin/bspwm_multifaceted_operation | 60 +++ bin/bin/bspwm_reorder_desktops | 33 ++ bin/bin/bspwm_resize | 26 + bin/bin/bspwm_smart_move | 60 +++ bin/bin/bspwm_smart_presel | 42 ++ bin/bin/melonpanel | 415 ++++++++++++++++ bin/bin/panel_bspwm | 99 ++++ bin/bin/panel_main | 52 ++ bin/bin/panel_theme | 25 + bin/bin/panel_volume | 58 +++ bin/bin/poweroptionsmenu | 100 ++++ bin/bin/toggle_kbd_layout | 35 ++ {shell => bspwm}/.Xmodmap | 16 +- bspwm/.config/bspwm/active-theme | 1 + bspwm/.config/bspwm/bspwmrc | 143 ++++++ bspwm/.config/sxhkd/cheatsheet_sxhkdrc.txt | 113 +++++ bspwm/.config/sxhkd/sxhkdrc | 128 +++++ bspwm/.config/sxhkd/sxhkdrc_bspc | 232 +++++++++ dunst/.config/dunst/dunstrc | 466 ++++++++++++++++++ gtk/.config/gtk-3.0/settings.ini | 17 + gtk/.config/gtk-4.0/settings.ini | 2 + gtk/.config/xsettingsd/xsettingsd.conf | 29 ++ gtk/.gtkrc-2.0 | 15 + .../autostart/gnome-keyring-pkcs11.desktop | 9 + .../autostart/gnome-keyring-secrets.desktop | 13 + .../autostart/gnome-keyring-ssh.desktop | 12 + rofi/.config/rofi/config.rasi | 119 +++++ rofi/.config/rofi/themes/modus-operandi.rasi | 34 ++ .../rofi/themes/modus-themes-active.rasi | 1 + .../rofi/themes/modus-themes-common.rasi | 136 +++++ rofi/.config/rofi/themes/modus-vivendi.rasi | 34 ++ xorg/.profile | 57 +++ xorg/.xinitrc | 74 +++ 40 files changed, 3251 insertions(+), 8 deletions(-) create mode 100755 bin/bin/bspwm_conf_colors create mode 100755 bin/bin/bspwm_conf_desktops create mode 100755 bin/bin/bspwm_conf_reset_monitors create mode 100755 bin/bin/bspwm_conf_xrandr create mode 100755 bin/bin/bspwm_dynamic_desktops create mode 100755 bin/bin/bspwm_external_rules create mode 100755 bin/bin/bspwm_focus_mode create mode 100755 bin/bin/bspwm_multifaceted_operation create mode 100755 bin/bin/bspwm_reorder_desktops create mode 100755 bin/bin/bspwm_resize create mode 100755 bin/bin/bspwm_smart_move create mode 100755 bin/bin/bspwm_smart_presel create mode 100755 bin/bin/melonpanel create mode 100755 bin/bin/panel_bspwm create mode 100755 bin/bin/panel_main create mode 100755 bin/bin/panel_theme create mode 100755 bin/bin/panel_volume create mode 100755 bin/bin/poweroptionsmenu create mode 100755 bin/bin/toggle_kbd_layout rename {shell => bspwm}/.Xmodmap (86%) create mode 100644 bspwm/.config/bspwm/active-theme create mode 100644 bspwm/.config/bspwm/bspwmrc create mode 100644 bspwm/.config/sxhkd/cheatsheet_sxhkdrc.txt create mode 100644 bspwm/.config/sxhkd/sxhkdrc create mode 100644 bspwm/.config/sxhkd/sxhkdrc_bspc create mode 100644 dunst/.config/dunst/dunstrc create mode 100644 gtk/.config/gtk-3.0/settings.ini create mode 100644 gtk/.config/gtk-4.0/settings.ini create mode 100644 gtk/.config/xsettingsd/xsettingsd.conf create mode 100644 gtk/.gtkrc-2.0 create mode 100644 keyring/.config/autostart/gnome-keyring-pkcs11.desktop create mode 100644 keyring/.config/autostart/gnome-keyring-secrets.desktop create mode 100644 keyring/.config/autostart/gnome-keyring-ssh.desktop create mode 100644 rofi/.config/rofi/config.rasi create mode 100644 rofi/.config/rofi/themes/modus-operandi.rasi create mode 100644 rofi/.config/rofi/themes/modus-themes-active.rasi create mode 100644 rofi/.config/rofi/themes/modus-themes-common.rasi create mode 100644 rofi/.config/rofi/themes/modus-vivendi.rasi create mode 100644 xorg/.profile create mode 100644 xorg/.xinitrc diff --git a/bin/bin/bspwm_conf_colors b/bin/bin/bspwm_conf_colors new file mode 100755 index 00000000..5a3b02c4 --- /dev/null +++ b/bin/bin/bspwm_conf_colors @@ -0,0 +1,43 @@ +#!/bin/bash + +# bspwm_conf_colors --- Configure color settings for BSPWM. +# +# Copyright (c) 2019-2021 Protesilaos Stavrou +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Values come from my Modus themes for GNU Emacs: +# . +if [ -f "$HOME"/.config/bspwm/active-theme ] +then + case "$(cat "$HOME"/.config/bspwm/active-theme)" in + dark*) + border_active="#c0c530" + border_focus="#44bc44" + border_normal="#000000" + bg_preselect="#041529" + ;; + *) + border_active="#5317ac" + border_focus="#8f0075" + border_normal="#ffffff" + bg_preselect="#ebf6fa" + ;; + esac + + bspc config active_border_color "$border_active" # for multihead setups only + bspc config focused_border_color "$border_focus" + bspc config normal_border_color "$border_normal" + bspc config presel_feedback_color "$bg_preselect" +fi diff --git a/bin/bin/bspwm_conf_desktops b/bin/bin/bspwm_conf_desktops new file mode 100755 index 00000000..ba1f3b6f --- /dev/null +++ b/bin/bin/bspwm_conf_desktops @@ -0,0 +1,32 @@ +#!/bin/bash + +# bspwm_conf_desktops --- Configure monitor settings for BSPWM. +# +# Copyright (c) 2019-2021 Protesilaos Stavrou +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +if [ "$(bspc query -M | wc -l)" -eq 2 ]; then + # Set the workspaces per monitor. We only define one per monitor, + # because of another script I have that implements dynamic desktops. + # For the XrandR settings see my `bspwm_conf_xrandr'. + bspc monitor LVDS-1 -d 1 + bspc monitor VGA-1 -d 8 + + # Make sure borders are always on, otherwise it is impossible to + # find the focused window on two monitors with monocles… + bspc config borderless_monocle false +else + bspc monitor -d 1 +fi diff --git a/bin/bin/bspwm_conf_reset_monitors b/bin/bin/bspwm_conf_reset_monitors new file mode 100755 index 00000000..f92128ec --- /dev/null +++ b/bin/bin/bspwm_conf_reset_monitors @@ -0,0 +1,57 @@ +#!/bin/bash + +# EXPERIMENTAL 2019-11-30: It works after connecting a monitor to the +# laptop, but not when disconnecting. The problem seems to be with +# BSPWM, since `bspc query -M' continues to list the second monitor… +# Will investigate further. +# +# Copyright (c) 2019-2021 Protesilaos Stavrou +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +## Commentary: +# +# Run this after {dis,}connecting an external monitor. It will +# recognifure the layout, based on the functions provided in the scripts +# it calls. + +_check() { + command -v "$1" > /dev/null +} + +# In case something stops working, we can call this script +# (Ctrl+Alt+Delete on my sxhkdrc) and apply the modifications again. +_kbd_reset_and_xmodmap() { + xmod="$HOME"/.Xmodmap + + setxkbmap -layout 'us,el' -option 'ctrl:nocaps,compose:menu' + [ -f "$xmod" ] && xmodmap "$xmod" +} + +_check bspwm_conf_xrandr && bspwm_conf_xrandr +_check bspwm_conf_desktops && bspwm_conf_desktops +_kbd_reset_and_xmodmap + +# Apply the last defined wallpaper +fehbg="$HOME"/.fehbg + +if [ -f "$fehbg" ] && _check feh; then + sh -c "$fehbg" +fi + +# Reload the panel +pkill -x melonpanel && melonpanel + +# Switch my font sizes in Emacs +pgrep -x emacs && emacsclient -e '(prot/fonts-per-monitor)' diff --git a/bin/bin/bspwm_conf_xrandr b/bin/bin/bspwm_conf_xrandr new file mode 100755 index 00000000..34e95d6f --- /dev/null +++ b/bin/bin/bspwm_conf_xrandr @@ -0,0 +1,66 @@ +#!/bin/bash + +# bspwm_conf_xrandr --- BSPWM Xrandr settings for my laptop. +# +# Copyright (c) 2019-2021 Protesilaos Stavrou +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +xrandr --output VGA-1 --brightness 0.935 --gamma 1:1:1 + + + + +## NOTE 2021-08-27: Below are old configurations. Keeping them here for +## future reference. + +# # XrandR functions +# # ---------------- +# +# # The brightness and gamma settings are specific to my Lenovo ThinkPad +# # X220. It improves the reproduction of colours, especially when +# # working with light themes. Adjustments to these values have no effect +# # if a program such as `redshift' is running. +# _laptop() { +# xrandr --output LVDS-1 --mode 1366x768 --pos 0x0 \ +# --brightness 1.0 --gamma 0.76:0.75:0.68 \ +# "$@" +# } +# +# _multihead() { +# _laptop +# +# # Configure the external display on the VGA port. Making it the +# # `primary' can cause problems in certain contexts that assume this +# # to be the left- and top- most monitor. +# xrandr --output VGA-1 --primary --mode 1920x1080 --pos 1366x0 +# } +# +# # Conditions for running this script +# # ---------------------------------- +# +# # If the VGA-1 port connects to a monitor, the output of the variable +# # will not be empty. In which case it is assumed that I am using my +# # external display, whose resolution I know in advance. If the variable +# # is empty, then no external monitor is connected. +# # +# # This is a simplistic approach which will not work if the external +# # monitor has another resolution. It will also fail if executed from +# # another machine, say, another laptop that uses an HDMI connection +# # instead. +# if [ -n "$(xrandr --query | grep 'VGA-1 connected')" ]; then +# _multihead +# else +# _laptop --primary +# fi diff --git a/bin/bin/bspwm_dynamic_desktops b/bin/bin/bspwm_dynamic_desktops new file mode 100755 index 00000000..692c853d --- /dev/null +++ b/bin/bin/bspwm_dynamic_desktops @@ -0,0 +1,223 @@ +#!/bin/bash + +# bspwm_dynamic_desktops --- Dynamic desktops (work spaces) for BSPWM. +# +# Copyright (c) 2019-2021 Protesilaos Stavrou +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +## Commentary: +# +# The idea with dynamic desktops is to maintain a list of varying +# lengths with only the active items. Whereas the default is to keep a +# fixed list of, say, ten desktops at all times. +# +# What this script does, in outline: +# +# - Switching to a non-existent desktop will create it dynamically. +# - Sending a node to a given desktop will create that desktop as well. +# - There also exists a variant that follows the node to that desktop. +# - Empty desktops are removed. +# +# Furthermore, there exists a toggle for multi-head setups (typically +# dual-monitor) which allows us to bind desktops to monitors, while +# retaining the aforementioned patterns of behaviour. In practice this +# means that the relevant commands become agnostic to the focused +# monitor so that, e.g., switching to desktop 1 will always take you to +# desktop 1 which belongs to monitor A. +# +# This script's commands are meant to be implemented in SXHKD (or +# equivalent). Furthermore, the desktops need to be set to one per +# monitor in bspwmrc (empty desktops are removed upon invoking one of +# this script's commands). +# +# `bspwm_dynamic_desktops' is part of my dotfiles (which also offer a +# complete implementation): https://gitlab.com/protesilaos/dotfiles + + + +# See the --options below for the available arguments for $1. $2 must +# be a number from 0 to 9. +[ "$#" -eq 2 ] || { echo 'Must be run with two arguments.'; exit 1; } + +# Capture the arguments. We need to run tests against them. Renaming +# them makes things easier to read. +option="${*:1:1}" +target_desktop="${*:2:1}" + +case "$target_desktop" in + [!0-9]) + echo "The second argument must be a valid number" + exit 1 + ;; +esac + +# The `dynamic_but_dedicated' switch concerns multi-head setups +# (typically dual-monitor). It allows us to specify a range of numbered +# desktops that we would want to always place on dedicated monitors. +# This means that while we retain the functionality of dynamically +# creating/removing desktops, we also bind certain desktops to monitors. +# +# NOTE: it only applies to the `--ns*' options (see the last part of the +# script). As such, you can still send a node to any +# dynamically-created numbered desktop on the next monitor, by using the +# `--nm*' options. +if [ "$(bspc query -M | wc -l)" -gt 1 ]; then + # Switch to `false' to restore the monitor-independent behaviour. + dynamic_but_dedicated='true' +fi + +# Here we specify the range of desktops that should always appear on the +# monitor named `LVDS-1'. Everything else appears on `VGA-1'. You can +# find the names of your monitors with `bspc query -M --names`. +# +# NOTE: if you use more that two monitors, you need to create another +# range similar to the one for LVDS-1 and adapt things accordingly. +if [ "$dynamic_but_dedicated" = 'true' ]; then + dedicated_desktops='false' + case "$target_desktop" in + [1-5]) dedicated_monitor="LVDS-1" ;; + *) dedicated_monitor="VGA-1" ;; + esac +fi + +# Command for querying BSPWM desktops. Used further below. +_query_desktops() { + bspc query -D -d "$@" +} + +# The core functionality of this script. Behaviour changes based on +# whether this is a desktop or a node (each action is mapped to +# different key chords in sxhkd). +# +# If the target desktop does not exist, it is created on the spot. +_desk_or_node() { + _dynamic_desktops() { + # Here we make sure to clean up the arguments passed to this + # function. We can operate on them with greater flexibility. + local monitor action + monitor="${*:1:1}" + action="${*:2}" + + # Leave the unquoted in tact! Else the commands will not run. + if ! _query_desktops "$target_desktop" > /dev/null; then + bspc monitor "$monitor" -a "$target_desktop" && $action + else + # BACK-AND-FORTH behaviour: inputting the number of the + # focused desktop switches to the last one. + # + # If you do not like this, just replace the whole if/fi part + # below with $action (and do not quote it). + if [ "$(_query_desktops --names)" -eq "$target_desktop" ]; then + bspc desktop -f last + else + $action + fi + fi + } + + # Reorder desktops on the target monitor (the target is the first + # argument passed to this function). The default is the focused + # one. + _desk_order() { + while read -r line; do + printf "%s\\n" "$line" + done < <(bspc query -D -m "${1:-focused}" --names) | sort -g | paste -d ' ' -s + } + + # Determines whether the behaviour of this function concerns nodes + # or desktops. The "monitor" is just a filter for nodes/desktops + # (hence the `shift'). It concerns multihead setups. + case "$1" in + node|desktop) + _dynamic_desktops 'focused.focused' bspc "$@" + # Do not quote the following `$(…)` we want term splitting + # here. The next comment silences the `shellcheck' utility. + # + # shellcheck disable=SC2046 + bspc monitor -o $(eval _desk_order) + ;; + monitor) + shift + if [ -n "$dedicated_desktops" ]; then + _dynamic_desktops "$dedicated_monitor" bspc "$@" + # Do not quote the following `$(…)` we want term splitting + # here. The next comment silences the `shellcheck' utility. + # + # shellcheck disable=SC2046 + bspc monitor "$dedicated_monitor" -o $(eval _desk_order "$dedicated_monitor") + else + _dynamic_desktops next bspc "$@" + # Do not quote the following `$(…)` we want term splitting + # here. The next comment silences the `shellcheck' utility. + # + # shellcheck disable=SC2046 + bspc monitor next -o $(eval _desk_order next) + fi + ;; + esac +} + +# Invoke the above command, passing to it arguments that change its +# behaviour (desktop or node). +# +# Mnemonics for shorter options: +# n* == node +# d* == desktop +case "$option" in + --na|--send-all-to-desktop) + _desk_or_node node 'any.local' -d "${target_desktop}" + ;; + --ns|--send-focused-to-desktop) + if [ -n "$dedicated_desktops" ]; then + _desk_or_node monitor node focused -d "${target_desktop}" + else + _desk_or_node node focused -d "${target_desktop}" + fi + ;; + --nsf|--send-focused-to-desktop-and-follow) + if [ -n "$dedicated_desktops" ]; then + _desk_or_node monitor node focused -d "${target_desktop}" --follow + else + _desk_or_node node focused -d "${target_desktop}" --follow + fi + ;; + --nm|--send-focused-to-next-monitor) + _desk_or_node monitor node focused -d "${target_desktop}" + ;; + --nmf|--send-focused-to-next-monitor-and-follow) + _desk_or_node monitor node focused -d "${target_desktop}" --follow + ;; + --da|--activate-desktop-and-place-receptacle) + _desk_or_node monitor node @"$target_desktop":/ -i && bspc desktop -a "${target_desktop}" + ;; + --df|--focus-desktop) + if [ -n "$dedicated_desktops" ]; then + _desk_or_node monitor desktop -f "${target_desktop}" + else + _desk_or_node desktop -f "${target_desktop}" + fi + ;; + *) + echo "< $option > is not a valid option." + exit 1 + ;; +esac + +# Remove empty desktops. This works for multiple monitors, as well. +# This will NOT REMOVE empty desktops that contain only receptacles +# (applies to the --activate-desktop option above). +for i in $(_query_desktops '.!focused.!occupied' --names); do + bspc desktop "$i" -r +done diff --git a/bin/bin/bspwm_external_rules b/bin/bin/bspwm_external_rules new file mode 100755 index 00000000..a2dfd769 --- /dev/null +++ b/bin/bin/bspwm_external_rules @@ -0,0 +1,98 @@ +#!/bin/bash + +# External rules for BSPWM. This script is part of my dotfiles: +# https://gitlab.com/protesilaos/dotfiles. +# +# Copyright (c) 2019-2021 Protesilaos Stavrou +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + + +# NOTE 2021-08-27: Needs review, but I am bringing it back anyway +# because it should still work fine based on what I remember. + + +# Manual tiling +# ============= + +# Spawn window on the newest receptacle or preselection and switch focus +# to it. For multiple presels, priority is given to the current +# desktop. +_bspc_query() { + bspc query -N -n "$@" +} + +recept="$(_bspc_query 'any.leaf.!window')" +presel="$(_bspc_query 'newest.!automatic')" + +# Receptacles will not switch focus to the present desktop, whereas +# preselection will. This way we can develop different workflows (e.g. +# create 3 recept in one desktop, launch 3 GUIs that take time to load, +# switch to another desktop and continue working, until you decide to go +# back to the GUIs). This has no effect when all actions occur within +# the focused desktop. +# +# Also see my SXHKD bindings for advanced manual tiling actions (refer +# to my dotfiles). +if [ -n "$recept" ]; then + target="$recept" + attention="off" +elif [ -n "$presel" ]; then + target="$presel" +fi + +echo "node=${target:-focused}" +echo "follow=${attention:-on}" + +# Window rules +# ============ + +# Operate on windows based on their properties. The positional +# arguments are defined in the `external_rules_command` of `man bspc`. +window_id="$1" +window_class="$2" +window_instance="$3" +window_title="$(xwininfo -id "$window_id" | sed ' /^xwininfo/!d ; s,.*"\(.*\)".*,\1,')" + +case "$window_class" in + [Mm]pv|[Vv]lc|[Pp]avucontrol|[Ee]o[mg]|[Ff]eh|[Rr]istretto|[Ss]xiv|my_float_window) + echo "state=floating" + echo "center=on" + ;; + [Mm]ate-calc) + echo "state=pseudo_tiled" + ;; + * ) + case "$(xprop -id "$window_id" _NET_WM_WINDOW_TYPE)" in + *_NET_WM_WINDOW_TYPE_DIALOG*) + echo "state=floating" + ;; + *) + echo "state=tiled" + ;; + esac + ;; +esac + +# FIXME the "file operations" applies to the `caja` file manager. +# TODO There should be a better way of handling this. +case "$window_title" in + 'File Operations'*) + echo "state=floating" + echo "center=on" + ;; + my_float_window) + echo "state=floating" + ;; +esac diff --git a/bin/bin/bspwm_focus_mode b/bin/bin/bspwm_focus_mode new file mode 100755 index 00000000..fab13905 --- /dev/null +++ b/bin/bin/bspwm_focus_mode @@ -0,0 +1,84 @@ +#!/bin/bash + +# bspwm focus mode --- removes gaps, padding, panel from the viewport. +# +# This script is meant to be used in my custom desktop session: +# https://gitlab.com/protesilaos/dotfiles. +# +# Copyright (c) 2019-2021 Protesilaos Stavrou +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or (at +# your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# This assumes that we are already running the lemonbar script. +[ -z "$(pgrep -x melonpanel > /dev/null)" ] || { echo "No running melonpanel"; exit 1; } + +panel_height="$(awk -F '=' '/melonpanel_height/ { print $2; exit; }' "$(command -v melonpanel 2> /dev/null)")" + +# The bottom padding is extracted from the running program. +bottom_padding="$(bspc config bottom_padding)" + +# Read the default setting from the bspwm config file. +_get_value() { + local bspwmrc + bspwmrc="$HOME/.config/bspwm/bspwmrc" + + sed "/$1/!d ; s,.* $1 \([a-z0-9]*\).*,\1," "$bspwmrc" +} + +## Use the function that gets the desired value from bspwmrc. +window_gap="$(_get_value window_gap)" +gapless_monocle="$(_get_value gapless_monocle)" +border_width="$(_get_value border_width)" + +# Calculate the actual gap from the bottom of the viewport to the lower +# part of the nodes. +effective_padding=$(("$bottom_padding" + "$window_gap")) + +# If we are not in "focus mode"... +if [ "$effective_padding" -ge "$panel_height" ] ; then + bottom_padding=0 + window_gap=0 + gapless_monocle=true + border_width=1 + + # No need to keep the panel + pkill -xo melonpanel && pkill -x lemonbar +else + # Unset everything + unset bottom_padding + unset window_gap + unset gapless_monocle + unset border_width + panel_status=on +fi + +# Create overlapping borders in focus mode. +if [ -n "$border_width" ]; then + bspc config window_gap -"$border_width" + bspc config border_width "$border_width" + for side in top right bottom left; do + bspc config "${side}"_padding "$border_width" + done +else + bspc config window_gap "${window_gap:=2}" + bspc config border_width "${border_width:=2}" + bspc config bottom_padding "${bottom_padding:=$panel_height}" + for side in right left top; do + bspc config "${side}"_padding "0" + done +fi + +bspc config gapless_monocle "${gapless_monocle:=false}" + +[ -n "$panel_status" ] && melonpanel diff --git a/bin/bin/bspwm_multifaceted_operation b/bin/bin/bspwm_multifaceted_operation new file mode 100755 index 00000000..beb7cb45 --- /dev/null +++ b/bin/bin/bspwm_multifaceted_operation @@ -0,0 +1,60 @@ +#!/bin/bash + +# Facilitates BSPWM operations over multiple selection paths. The +# actions defined herein are assigned to key chords (sxhkd). Everything +# is part of my dotfiles: https://gitlab.com/protesilaos/dotfiles. +# +# Copyright (c) 2019-2021 Protesilaos Stavrou +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +_query_nodes() { + for i in $(bspc query -N -n "$1"); do + bspc node "$i" "${@:2}" + done +} + +# Mnemonics for shorter options: +# r* == receptacles +# n* == nodes +# d* == desktops +case "$1" in + --rk|--kill-all-receptacles) + _query_nodes '.leaf.!window' -k + ;; + --nca|--close-all-local-non-focused) + _query_nodes '.!focused.!marked.local.window' -c + ;; + --nka|--kill-all-local-non-focused) + _query_nodes '.!focused.!marked.local.window' -k + ;; + --nla|--lock-all-local) + _query_nodes '.local.window' -g locked=on + ;; + --nula|--unlock-all-local) + _query_nodes '.local.window' -g locked=off + ;; + --nms|--summon-all-marked) + _query_nodes '.marked' -d focused --follow + ;; + --db|--bring-desktop-here) + for i in $(bspc query -N -d "$2" -n '.window'); do + bspc node "$i" -d 'focused.focused' + done + ;; + --ds|--send-desktop-there) + # NOTE another script of mine (see dotfiles). + bspwm_dynamic_desktops --send-all-to-desktop "$2" + ;; +esac diff --git a/bin/bin/bspwm_reorder_desktops b/bin/bin/bspwm_reorder_desktops new file mode 100755 index 00000000..8fd02a95 --- /dev/null +++ b/bin/bin/bspwm_reorder_desktops @@ -0,0 +1,33 @@ +#!/bin/bash + +# Reorder BSPWM desktops. This is an excerpt of another script I have +# that implements dynamic desktop creation/deletion. It is kept here in +# case the reordering functionality is needed on its own. Everything is +# part of my dotfiles: https://gitlab.com/protesilaos/dotfiles. +# +# Copyright (c) 2019-2021 Protesilaos Stavrou +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +_desk_order() { + while read -r line; do + printf "%s\\n" "$line" + done < <(bspc query -D -m "${1:-focused}" --names) | sort -g | paste -d ' ' -s +} + +# shellcheck disable=SC2046 +bspc monitor -o $(eval _desk_order) # do not quote! we want term splitting here + +# Accepts an argument for targeting a monitor: +#bspc monitor -o $(eval _desk_order next) diff --git a/bin/bin/bspwm_resize b/bin/bin/bspwm_resize new file mode 100755 index 00000000..bd9a9dea --- /dev/null +++ b/bin/bin/bspwm_resize @@ -0,0 +1,26 @@ +#!/bin/bash +# Extracted and adapted from source: +# https://github.com/Chrysostomus/bspwm-scripts/blob/master/bin/bspwm_resize.sh + +# Resizes (expands or contracts) the selected node in the given +# direction. This is assigned to a key binding in $HOME/.config/sxhkd/sxhkdrc + +# NOTE by Protesilaos 2020-05-01: The support for floating windows was +# contributed by Pierre-François Bonnefoi who also recommends the +# following sxhkdrc config: +# +# super + ctrl + {Left,Down,Up,Right} +# bspwm_resize {west,south,north,east} 50 + +size=${2:-'10'} +direction=$1 + +bspc query -N -n focused.floating +floating=$? + +case "$direction" in + west) [ $floating = 0 ] && bspc node -z right -"$size" 0 || bspc node @west -r -"$size" || bspc node @east -r -"$size" ;; + east) [ $floating = 0 ] && bspc node -z right +"$size" 0 || bspc node @west -r +"$size" || bspc node @east -r +"$size" ;; + north) [ $floating = 0 ] && bspc node -z bottom 0 -"$size" || bspc node @south -r -"$size" || bspc node @north -r -"$size" ;; + south) [ $floating = 0 ] && bspc node -z bottom 0 +"$size" || bspc node @south -r +"$size" || bspc node @north -r +"$size" ;; +esac diff --git a/bin/bin/bspwm_smart_move b/bin/bin/bspwm_smart_move new file mode 100755 index 00000000..6bf2c3fd --- /dev/null +++ b/bin/bin/bspwm_smart_move @@ -0,0 +1,60 @@ +#!/bin/bash + +# A more fluid way of moving windows with BSPWM, which is meant to be +# implemented in SXHKD. If there is a window in the given direction, +# swap places with it. Else if there is a receptacle move to it +# ("consume" its place). Otherwise create a receptacle in the given +# direction by splitting the entire viewport (circumvents the tiling +# scheme while respecting the current split ratio configuration). In +# the latter scenario, inputting the direction twice will thus move the +# focused window out of its current layout and into the receptacle. +# +# Part of my dotfiles: https://gitlab.com/protesilaos/dotfiles +# +# Copyright (c) 2019-2021 Protesilaos Stavrou +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + + +[ "$#" -eq 1 ] || { echo "Pass only one argument: north,east,south,west"; exit 1; } + +# Check if argument is a valid direction. +case "$1" in + north|east|south|west) + dir="$1" + ;; + *) + echo "Not a valid argument." + echo "Use one of: north,east,south,west" + exit 1 + ;; +esac + +_query_nodes() { + bspc query -N -n "$@" +} + +# Do not operate on floating windows! +[ -z "$(_query_nodes focused.floating)" ] || { echo "Only move tiled windows."; exit 1; } + +receptacle="$(_query_nodes 'any.leaf.!window')" + +# This regulates the behaviour documented in the description. +if [ -n "$(_query_nodes "${dir}.!floating")" ]; then + bspc node -s "$dir" +elif [ -n "$receptacle" ]; then + bspc node focused -n "$receptacle" --follow +else + bspc node @/ -p "$dir" -i && bspc node -n "$receptacle" --follow +fi diff --git a/bin/bin/bspwm_smart_presel b/bin/bin/bspwm_smart_presel new file mode 100755 index 00000000..6275c944 --- /dev/null +++ b/bin/bin/bspwm_smart_presel @@ -0,0 +1,42 @@ +#!/bin/bash + +# Lets BSPWM send the marked {or just the focused} node to a receptacle +# {or a preselection}. This script is part of my dotfiles: +# https://gitlab.com/protesilaos/dotfiles. +# +# Copyright (c) 2019-2021 Protesilaos Stavrou +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or (at +# your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +_bspc_query() { + bspc query -N -n "$@" +} + +_marked_else_focused() { + if [ -n "$(_bspc_query 'any.marked')" ]; then + echo 'any.marked' + else + echo 'focused' + fi +} + +receptacle="$(_bspc_query 'any.leaf.!window')" + +# Use a receptacle if available, else use a preselection. None is +# limited to the focused desktop. +if [ -n "$receptacle" ]; then + bspc node "$(_marked_else_focused)" -n "$receptacle" --follow +else + bspc node "$(_marked_else_focused)" -n 'newest.!automatic' --follow +fi diff --git a/bin/bin/melonpanel b/bin/bin/melonpanel new file mode 100755 index 00000000..13963be6 --- /dev/null +++ b/bin/bin/melonpanel @@ -0,0 +1,415 @@ +#!/bin/bash + +# Melonpanel --- Script to draw a panel with `lemonbar'. +# +# Copyright (c) 2019-2021 Protesilaos Stavrou +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +## Commentary: +# +# This script, called "Melonpanel" is my `lemonbar' implementation, for +# use in my custom BSPWM desktop session. I just selected the name +# "melon" as an anagram for "lemon" and then switched "bar" with +# "panel". This is to avoid naming conflicts where we could +# accidentally kill the wrong process or whatnot. +# +# I am using `lemonbar' instead of more popular options, such as +# `polybar' in part because I like experimenting with shell scripting. +# +# Dependencies for melonpanel: +# bspwm lemonbar-xft xdo +# +# Dependencies for individual modules: +# acpi alsa-utils + + + +# FIXME 2021-08-27: I am bringing this back from git history with some +# minor edits, but it needs a major redesign. We must pipe each module +# to its own named pipe and then figure out how to read each of them +# independent of the rest. + + +#### General settings + +# Check for dependencies. Fail if unmet. +_checkdep() { + command -v "$1" > /dev/null || { echo "Missing dependency: $1"; exit 1; } +} + +_checkdep bspwm +_checkdep lemonbar +_checkdep xdo + +# Kill any running lemonbar +pgrep -x lemonbar > /dev/null && pkill -x lemonbar + +# DO NOT EDIT the name of this parameter (checked by other scripts). +melonpanel_height=22 + +#### Colours + +# Here we are re-using the bspwm active theme, because I only ever use +# lemonbar with it. Otherwise there would have to be a +# lemonbar-specific file. Refer to my `delight' script as well. +# +# Values are taken from my Modus themes for Emacs: +# . +case "$(cat "$HOME"/.config/bspwm/active-theme)" +in + dark*) + bg_main="#000000" + bg_alt="#191a1b" + fg_main="#ffffff" + fg_alt="#a8a8a8" + red="#ff8059" + green="#44bc44" + yellow="#d0bc00" + ;; + *) + bg_main="#ffffff" + bg_alt="#f0f0f0" + fg_main="#000000" + fg_alt="#505050" + red="#a60000" + green="#005e00" + yellow="#813e00" + ;; +esac + +#### Fonts (upstream lemonbar only supports bitmap fonts) + +# My fork: . Also on the +# AUR. +fontmain='Monospace:style=regular:size=9' +fontbold='Monospace:style=bold:size=9' + +# fontmain='-misc-fixed-medium-r-normal--13-120-75-75-c-80-iso10646-1' +# fontbold='-misc-fixed-bold-r-normal--13-120-75-75-c-80-iso10646-1' + + +#### Panel modules + +# NOTE all functions that are meant to pipe their output to the panel +# will echo a majuscule (letter A-Z). This is done to easily retrieve +# their output from the named pipe. The letter has to be unique and, +# ideally, use common words that denote the function of the content of +# the command such as e.g. D for Date, N for Network... Where this +# would lead to conflicts, find a synonym or something close enough. +# +# The various sequences %{..} are part of lemonbar's syntax for styling +# the output. See `man lemonbar`. + +# Battery status. +_battery() { + command -v acpi > /dev/null || return 1 + + local label command status output + + label='B:' + # Using Bash parameter expansion here. Just experimenting... + command="$(acpi -b)" + status="${command#*: }" # Delete up to the colon and the following space + status="${status:0:1}" # Use first character + output="${command#*, }" # Delete up to first comma + output="${output%,*}" # Same but read from the end + + # The $battery_status will tell us if it is (C)harging or + # (D)ischaging. If dischange level reaches 0-9, the whole indicator + # will turn into to a bright colour. Otherwise, discharging will be + # denoted by a coloured output of the current level followed by the + # minus sign. + case "$status" in + 'C') + echo "%{F$fg_alt}${label}%{F-} %{F$green}${output}+%{F-}" + ;; + 'D') + case "${output%?}" in + [0-9]) + echo "%{B$yellow}%{F$bg_main} $label ${output}- %{F-}%{B-}" + ;; + *) + echo "%{F$fg_alt}${label}%{F-} %{F$yellow}${output}-%{F-}" + ;; + esac + ;; + *) + echo "%{F$fg_alt}${label}%{F-} ${output}" + ;; + esac +} + +_temperature() { + command -v acpi > /dev/null || return 1 + + local label command output + + label='T:' + # Use Bash parameter expansion again... + command="$(acpi -t)" + output="${command#*: }" + output="${output#*, }" + output="${output:0:2}" + + # Up to 59 degrees celsius keep text colour same as default. 60-79 + # turn the colour red on normal background. Else turn the whole + # indicator red. + case "$output" in + [12345][0-9]) + echo "%{F$fg_alt}${label}%{F-} ${output}°C" + ;; + [67][0-9]) + echo "%{F$fg_alt}${label}%{F-} %{F$red}${output}°C%{F-}" + ;; + *) + echo "%{F$bg_main}%{B$red} $label ${output}°C %{B-}%{F-}" + ;; + esac +} + +_volume() { + command -v amixer > /dev/null || return 1 + + local label status output + + label='V:' + # Could not do this with just parameter expansions... + status="$(amixer get Master | awk -F'[][]' '/%/{print $2","$4;exit}')" + output="${status%,*}" + + case "${status#*%}" in + 'off') echo "%{F$fg_alt}${label}%{F-} $output (Muted)" ;; + *) echo "%{F$fg_alt}${label}%{F-} $output" ;; + esac +} + +_notmuch() { + command -v notmuch > /dev/null || return 1 + + local label count + + label='E:' + # Could not do this with just parameter expansions… + count="$(notmuch count tag:unread and tag:inbox)" + + echo "%{F$fg_alt}${label}%{F-} $count" +} + +# Keyboard indicators. +_keyboard() { + local kd_layout kb_caps + + # Checks if the current layout is set to Greek (adjust accordingly). + # If yes, the indicator will be displayed, else it is assumed that + # English is being used. + if [ "$(setxkbmap -query | sed '/^l/!d ; s,.*:[\ ]*,,g')" = 'gr' ] + then + kb_layout="%{B$bg_alt}%{U$fg_main}%{+u} EL %{-u}%{U-}%{B-}" + fi + + # Show an indicator if Caps Lock is on. + if [ "$(xset -q | awk '/Caps/ { print $4 }')" = 'on' ] + then + kb_caps="%{B$bg_alt}%{U$fg_main}%{+u} CAPS %{-u}%{U-}%{B-}" + fi + + # Print the indicators next each other in the given order. + printf "%s %s" "$kb_layout" "$kb_caps" +} + +_datetime() { + local label output + + label='D:' + output="$(date +'%a %-d %b, %R')" + + echo "%{F$fg_alt}${label}%{F-} $output" +} + +# Include all modules in a single infinite loop that iterates every +# second (adjust interval accordingly, as it can be taxing on system +# resources). +_modules() { + while true + do + # echo "B" "$(_battery)" + # echo "T" "$(_temperature)" + echo "D" "$(_datetime)" + echo "E" "$(_notmuch)" + echo "K" "$(_keyboard)" + echo "V" "$(_volume)" + sleep 1s + done +} + +#### Piping and reading the output of the modules + +# The design of this section has been heavily inspired/adapted from the +# examples provided by upstream bspwm. + +# set path to named pipe used to store process data for these operations +melonpanel_fifo='/tmp/melonpanel.fifo' + +# make sure you delete any existing named pipe +[ -p "$melonpanel_fifo" ] && rm "$melonpanel_fifo" + +# create a new named pipe +mkfifo "$melonpanel_fifo" + +# pipe the output of the modules to the fifo +_modules > "$melonpanel_fifo" & +bspc subscribe report > "$melonpanel_fifo" & + +# Read the content of the fifo file. We differentiate between modules +# based on the majuscule (letter A-Z) they piped into melonpanel_fifo +# (see modules above). Here we just add a shorter variable to each +# module, which helps position it on the panel (the last printf). +_melonpanel() { + while read -r line + do + case $line + in + # B*) + # # battery status + # bat="${line#?}" + # ;; + # T*) + # # temperature + # therm="${line#?}" + # ;; + D*) + # current date and time + date="${line#?}" + ;; + E*) + # notmuch unread count + mail="${line#?}" + ;; + K*) + # keyboard layout (en or gr) + key="${line#?}" + ;; + V*) + # volume level + vol="${line#?}" + ;; + W*) + # bspwm's state + wm= + IFS=':' + set -- ${line#?} + while [ "$#" -gt 0 ] + do + item="$1" + name="${item#?}" + case "$item" in + [mMfFoOuULG]*) + case "$item" in + m*) + # monitor + FG="$fg_alt" # needed to avoid invalid colour error + on_focused_monitor= + name= + ;; + M*) + # focused monitor + FG="$fg_alt" # needed to avoid invalid colour error + on_focused_monitor=1 + name= + ;; + # {Free,Occupied,Urgent} focused + [FOU]*) + if [ -n "$on_focused_monitor" ] + then + name="%{T2}${name/*/[$name]}%{T-}" + FG="$fg_main" + else + name="${name/*/ $name-}" + FG="$fg_alt" + fi + ;; + # {free,occupied,urgent} unfocused + f*) + FG="$fg_alt" + name="${name/*/ $name }" + ;; + o*) + FG="$fg_alt" + name="${name/*/ $name^}" + ;; + u*) + FG="$red" + name="${name/*/ $name\#}" + ;; + # desktop layout for monocle and node flags + LM|G*?) + if [ "$(bspc query -N -d any.focused | wc -l)" -gt 1 ] + then + FG="$fg_main" + name="${name/*/ $name }" + else + FG="$fg_alt" + name="${name/*/ * }" + fi + ;; + *) + FG="$fg_alt" + name="${name/*/ * }" + ;; + esac + wm="${wm}%{F$FG}${name}%{F-}" + ;; + esac + shift + done + esac + + _panel_layout() { + # echo "%{l}$wm%{r}$key $bat $therm $vol $date " + echo "%{l}$wm%{r}$key $mail $vol $date " + } + + if [ "$(bspc query -M | wc -l)" -gt 1 ] + then + printf "%s%s\n" "%{Sf}$(_panel_layout)" "%{Sl}$(_panel_layout)" + else + printf "%s\n" "%{Sf}$(_panel_layout)" + fi + done +} + +#### Launch the panel with the given parameters + +# NOTE the syntax for the background value. If you want transparency, +# just replace "ff" with a lower value: "00" means no opacity. This is +# hexadecimal notation: 0-9, a-f, A-F. +_melonpanel < "$melonpanel_fifo" \ + | lemonbar -b -u 1 -p -g "x${melonpanel_height}" \ + -F "$fg_main" -B "#ff${bg_main:1}" \ + -f "$fontmain" -f "$fontbold" -n "Melonpanel" & + +# Hide panel when windows are in full screen mode. This does not work +# all the time, especially with lower `sleep` values, requiring a +# re-launch of melonpanel (pkill -x melonpanel && melonpanel). I have +# yet to find a robust solution. +# +# Source of this snippet (with minor adapatations by me): +# https://github.com/baskerville/bspwm/issues/484 +until bar_id=$(xdo id -a 'Melonpanel') +do + sleep 0.1s +done + +xdo below -t $(xdo id -n root) $bar_id & diff --git a/bin/bin/panel_bspwm b/bin/bin/panel_bspwm new file mode 100755 index 00000000..ddd683ec --- /dev/null +++ b/bin/bin/panel_bspwm @@ -0,0 +1,99 @@ +#!/bin/bash + +# XXX 2021-08-27: work-in-progress + +command -v bspwm > /dev/null || { echo "Missing dependency: bspwm"; exit 1; } +command -v panel_theme > /dev/null || { echo "Missing dependency: panel_theme"; exit 1; } + +. panel_theme + +fifo='/tmp/panel_bspwm.fifo' + +_make_pipe() +{ + if [ -p "$fifo" ] + then + return 0 + else + mkfifo "$fifo" 2> /dev/null + fi +} + +_make_pipe + +bspc subscribe report > "$fifo" & + +while read -r line +do + # bspwm's state + wm= + IFS=':' + set -- ${line#?} + while [ "$#" -gt 0 ] + do + item="$1" + name="${item#?}" + case "$item" in + [mMfFoOuULG]*) + case "$item" in + m*) + # monitor + FG="$fg_alt" # needed to avoid invalid colour error + on_focused_monitor= + name= + ;; + M*) + # focused monitor + FG="$fg_alt" # needed to avoid invalid colour error + on_focused_monitor=1 + name= + ;; + # {Free,Occupied,Urgent} focused + [FOU]*) + if [ -n "$on_focused_monitor" ] + then + name="%{T2}${name/*/[$name]}%{T-}" + FG="$fg_main" + else + name="${name/*/ $name-}" + FG="$fg_alt" + fi + ;; + # {free,occupied,urgent} unfocused + f*) + FG="$fg_alt" + name="${name/*/ $name }" + ;; + o*) + FG="$fg_alt" + name="${name/*/ $name^}" + ;; + u*) + FG="$red" + name="${name/*/ $name\#}" + ;; + # desktop layout for monocle and node flags + LM|G*?) + if [ "$(bspc query -N -d any.focused | wc -l)" -gt 1 ] + then + FG="$fg_main" + name="${name/*/ $name }" + else + FG="$fg_alt" + name="${name/*/ * }" + fi + ;; + *) + FG="$fg_alt" + name="${name/*/ * }" + ;; + esac + wm="${wm}%{F$FG}${name}%{F-}" + ;; + esac + shift + done + + echo "$wm" + +done < "$fifo" diff --git a/bin/bin/panel_main b/bin/bin/panel_main new file mode 100755 index 00000000..a94be674 --- /dev/null +++ b/bin/bin/panel_main @@ -0,0 +1,52 @@ +#!/bin/bash + +# XXX 2021-08-27: work-in-progress + +command -v lemonbar > /dev/null || { echo "Missing dependency: lemonbar"; exit 1; } +command -v panel_theme > /dev/null || { echo "Missing dependency: panel_theme"; exit 1; } + +fifo='/tmp/panel_main.fifo' +panel_height=22 +fontmain='Monospace:style=regular:size=9' +fontbold='Monospace:style=bold:size=9' + +. panel_theme + +# TODO 2021-08-27: How to combine multiple modules, each of which prints +# to its own named pipe? Wrapping `panel_bspwm' and `panel_volume -S' +# into a single function and then feeding that to `lemonbar' only shows +# one module at a time. So we need them to be on the same line somehow. + +# TODO 2021-08-27: Check whether the above assumption is correct. Maybe +# there is something we are missing in such a design. + + +# _make_pipe() +# { +# if [ -p "$fifo" ] +# then +# return 0 +# else +# mkfifo "$fifo" 2> /dev/null +# fi +# } + +_bspwm() +{ + panel_bspwm +} + +_volume() +{ + panel_volume -S +} + + +# The bar style to-be-used: + + # | lemonbar -b -u 1 -p -g "x${panel_height}" \ + # -F "$fg_main" -B "#ff${bg_main:1}" \ + # -f "$fontmain" -f "$fontbold" -n "Panel" & + + + diff --git a/bin/bin/panel_theme b/bin/bin/panel_theme new file mode 100755 index 00000000..d327a9f0 --- /dev/null +++ b/bin/bin/panel_theme @@ -0,0 +1,25 @@ +#!/bin/bash + +# XXX 2021-08-27: work-in-progress + +case "$(cat "$HOME"/.config/bspwm/active-theme)" +in + dark*) + bg_main="#000000" + bg_alt="#191a1b" + fg_main="#ffffff" + fg_alt="#a8a8a8" + red="#ff8059" + green="#44bc44" + yellow="#d0bc00" + ;; + *) + bg_main="#ffffff" + bg_alt="#f0f0f0" + fg_main="#000000" + fg_alt="#505050" + red="#a60000" + green="#005e00" + yellow="#813e00" + ;; +esac diff --git a/bin/bin/panel_volume b/bin/bin/panel_volume new file mode 100755 index 00000000..35b5f53c --- /dev/null +++ b/bin/bin/panel_volume @@ -0,0 +1,58 @@ +#!/bin/bash + +# XXX 2021-08-27: work-in-progress + +command -v amixer > /dev/null || { echo "Missing dependency: amixer"; exit 1; } +command -v panel_theme > /dev/null || { echo "Missing dependency: panel_theme"; exit 1; } + +. panel_theme + +fifo='/tmp/panel_vol.fifo' + +_make_pipe() +{ + if [ -p "$fifo" ] + then + return 0 + else + mkfifo "$fifo" 2> /dev/null + fi +} + +_status() +{ + label='V:' + # Could not do this with just parameter expansions... + status="$(amixer get Master | awk -F'[][]' '/%/{print $2","$4;exit}')" + output="${status%,*}" + + case "${status#*%}" in + 'off') echo "%{F$fg_alt}${label}%{F-} $output (Muted)" ;; + *) echo "%{F$fg_alt}${label}%{F-} $output" ;; + esac +} + +_set() +{ + amixer set Master "$1" +} + +_update() +{ + _make_pipe + _status > "$fifo" +} + +# Returns the state of volume. +_subscribe() +{ + _make_pipe + tail -f "$fifo" +} + +case "$1" in + -s) _set "$2" ;; + -S) _subscribe ;; + -v) _status ;; + *) _update ;; +esac diff --git a/bin/bin/poweroptionsmenu b/bin/bin/poweroptionsmenu new file mode 100755 index 00000000..8128c613 --- /dev/null +++ b/bin/bin/poweroptionsmenu @@ -0,0 +1,100 @@ +#!/bin/bash + +# poweroptionsmenu --- rofi or dmenu interface for session actions. +# +# Copyright (c) 2019-2020 Protesilaos Stavrou +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Dependency: +# rofi OR dmenu + +_pkill() { + if pgrep -x "$1"; then + pkill -x "$1" + fi +} + +_kill_processes() { + _pkill bspwm_external_rules + _pkill sxhkd + _pkill melonpanel + _pkill feh + _pkill xcompmgr +} + +# In case something stops working, we can call this script +# (Ctrl+Alt+Delete on my sxhkdrc) and apply the modifications again. +_kbd_reset_and_xmodmap() { + xmod="$HOME"/.Xmodmap + + setxkbmap -layout 'us,el' -option 'ctrl:nocaps,compose:menu' + [ -f "$xmod" ] && xmodmap "$xmod" +} + +# TODO is this the most robust way to check for systemd? Is it standard? +_check_systemd() { + if [ -n "/run/systemd/system" ]; then + systemctl "$1" + else + sudo "$1" + fi +} + +# The idea with _reboot() and _poweroff() is to use the appropriate +# command depending on whether the machine is running systemd or not. +# +# The `reboot' and `poweroff' require escalated privileges. Read: +# https://wiki.voidlinux.org/Post_Installation#Allow_users_to_shutdown_without_a_password +_reboot() { + _check_systemd 'reboot' +} + +_poweroff() { + _check_systemd 'poweroff' +} + +_checkdep() { + command -v "$1" > /dev/null || return 1 +} + +_dynamic_menu() { + if _checkdep rofi; then + # use printf to output array items on a new line + rofi -dmenu -i -no-custom -p 'Power options' + elif _checkdep dmenu; then + dmenu -i -p 'Power options' + else + echo "Missing rofi or dmenu dependency." && exit 1 + fi +} + +# Possible actions +actions=('Log out' 'Reboot' 'Power off' 'Xmodmap and keyboard reload' 'Configure anew BSPWM monitors/desktops') + +# List actions to choose from. Output array items on a new line. +_list_actions() { + printf '%s\n' "${actions[@]}" | _dynamic_menu +} + +choice="$(_list_actions)" + +# Run the selected command. +case "$choice" in + L*) _kill_processes && bspc quit ;; + R*) _kill_processes && _reboot ;; + P*) _kill_processes && _poweroff ;; + X*) _kbd_reset_and_xmodmap ;; + C*) bspwm_conf_reset_monitors ;; +esac diff --git a/bin/bin/toggle_kbd_layout b/bin/bin/toggle_kbd_layout new file mode 100755 index 00000000..ad5a5d12 --- /dev/null +++ b/bin/bin/toggle_kbd_layout @@ -0,0 +1,35 @@ +#!/bin/bash + +# Very simple way to switch keyboard layouts between US QWERTY and +# standard Greek. This script is assigned to a key chord in my +# `sxkdrc`. A variant of this is also included in my system panel, the +# `melonpanel` to get the current layout. Everything is part of my +# dotfiles: https://gitlab.com/protesilaos/dotfiles. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +key_mods="$HOME"/.Xmodmap + +[ "$(command -v setxkbmap 2> /dev/null)" ] && [ -f "$key_mods" ] || { echo "Missing dependency"; exit 1; } + +_set_lang() { + setxkbmap -layout "$1" -option 'ctrl:nocaps,compose:menu' + xmodmap "$key_mods" +} + +if [ "$(setxkbmap -query | sed '/^l/!d ; s,.*:[\ ]*,,g')" == 'gr' ]; then + _set_lang us +else + _set_lang gr +fi diff --git a/shell/.Xmodmap b/bspwm/.Xmodmap similarity index 86% rename from shell/.Xmodmap rename to bspwm/.Xmodmap index 9c0d7d5a..30904c9e 100644 --- a/shell/.Xmodmap +++ b/bspwm/.Xmodmap @@ -43,11 +43,11 @@ clear control add control = Caps_Lock Control_L Control_R keycode 66 = Control_L Caps_Lock NoSymbol NoSymbol -! Keep Super in left Win -keycode 133 = Super_L - -! Right Super as right Hyper -keycode 134 = Super_R - -! Set super -add mod4 = Super_L Super_R +! ! Keep Super in left Win +! keycode 133 = Super_L +! +! ! Right Super as right Win +! keycode 134 = Super_R +! +! ! Set super +! add mod4 = Super_L Super_R diff --git a/bspwm/.config/bspwm/active-theme b/bspwm/.config/bspwm/active-theme new file mode 100644 index 00000000..162faa69 --- /dev/null +++ b/bspwm/.config/bspwm/active-theme @@ -0,0 +1 @@ +light diff --git a/bspwm/.config/bspwm/bspwmrc b/bspwm/.config/bspwm/bspwmrc new file mode 100644 index 00000000..bd9b2585 --- /dev/null +++ b/bspwm/.config/bspwm/bspwmrc @@ -0,0 +1,143 @@ +#!/bin/bash + +# bspwmrc --- Initialisation script for BSPWM. +# +# Copyright (c) 2019 Protesilaos Stavrou +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +## Commentary: +# +# This file is part of my custom desktop session on Void Linux. Other +# important settings are defined in `.xinitrc' and application-specific +# initialisation files. See: https://gitlab.com/protesilaos/dotfiles + + +############## +# Essentials # +############## + +# Truncate a couple of common commands that are used herein. +_bc() { + bspc config "$@" +} + +_check() { + command -v "$1" > /dev/null +} + +# Determine XrandR settings. Whether an external display is connected +# to the laptop or not. +_check bspwm_conf_xrandr && bspwm_conf_xrandr + +# Define desktop[s] [per monitor]. Contingent on the above. Also note +# that this leverages my `bspwm_dynamic_desktops'. +_check bspwm_conf_desktops && bspwm_conf_desktops + +################## +# Visual options # +################## + +# window management +# ----------------- +_bc initial_polarity second_child +_bc border_width 2 +_bc window_gap 2 +_bc split_ratio 0.50 +_bc single_monocle true +_bc borderless_monocle true +_bc gapless_monocle false +_bc focus_follows_pointer true +_bc pointer_follows_monitor true +_bc pointer_modifier mod1 +_bc pointer_action1 move +_bc pointer_action2 resize_side +_bc ignore_ewmh_focus false + +# window rules +_check bspwm_external_rules && \ + _bc external_rules_command \ + "$(command -v bspwm_external_rules)" + +# colours +# ------- + +_check bspwm_conf_colors && bspwm_conf_colors + +############# +# autostart # +############# + +# Specify keyboard layout. For the key chord that performs the layout +# switching between US QWERTY and Greek refer to my `sxhkdrc`. +# +# Originally found the options in this location (Debian Buster): +# /usr/share/X11/xkb/rules/base.lst +# +# caps:hyper Make Caps Lock an additional Hyper +# compose:menu Menu key behaves as Compose +# +# The options are required in order for Xmodmap to work properly (see +# below). +if _check setxkbmap; then + setxkbmap -layout 'us,el' -option 'ctrl:nocaps,compose:menu' +fi + +# Parse my custom key mappings. These make Caps behave as another Ctrl +# key. We need to evaluate this first otherwise it might mess up with +# SXHKD. +[ -f "$HOME"/.Xmodmap ] && xmodmap "$HOME"/.Xmodmap + +# The hotkey daemon that handles all custom key bindings. I split the +# key chords into separate files, based on their scope. The ones that +# pertain to the window manager are defined in sxhkdrc_bspc. +_check sxhkd && sxhkd -c "$HOME"/.config/sxhkd/sxhkdrc{,_bspc} & + +# Launch my custom Lemonbar implementation (the system panel). +if _check melonpanel; then + # Make sure we have no running instances + pgrep -x melonpanel && pkill -x melonpanel + melonpanel + + # Add padding equal to the panel height to fix an issue where there + # is an overlap between panel and windows in monitor LVDS1. The + # panel gets covered by the windows. This only happens when an + # external monitor is connected to my laptop, for reasons that I + # cannot determine… + if [ "$(bspc query -M | wc -l)" -gt 1 ]; then + _panel_height() { + awk -F '=' '/melonpanel_height/ { print $2; exit; }' \ + $(command -v melonpanel) + } + + bspc config bottom_padding "$(_panel_height)" + fi +fi + +# Run the tool that sets the wallpaper. A program could be used that +# handles the desktop in general, including the option to set icons. +# But this is enough for my case. Here is a command I tested and which +# works (using the Xfce desktop manager): +# xfdesktop --sm-client-disable --disable-wm-check & +if _check feh; then + if [ -n "$HOME"/.fehbg ]; then + "$HOME"/.fehbg & + fi +fi + +# Start the simple display compositor. See `xcompmgr --help'. +_check xcompmgr && xcompmgr -cCfF -t -2 -l -2 -r 2.8 -o 0.55 -D 5 -I 0.075 -O 0.075 & + +# Simple daemon for GTK settings +xsettingsd -c "$HOME"/.config/xsettingsd/xsettingsd.conf & diff --git a/bspwm/.config/sxhkd/cheatsheet_sxhkdrc.txt b/bspwm/.config/sxhkd/cheatsheet_sxhkdrc.txt new file mode 100644 index 00000000..15c88f00 --- /dev/null +++ b/bspwm/.config/sxhkd/cheatsheet_sxhkdrc.txt @@ -0,0 +1,113 @@ +List of common key bindings. All definitions are stored at: + + ~/.config/sxhkd/sxhkdrc + ~/.config/sxhkd/sxhkdrc_bspc + +The latter is for definitions that control the window manager. While +the former has WM-independent keys. + +Last review 2019-07-01. + +Explanation of the basics +========================= + +The Super key, aka "mod4", is the one that most keyboards mark with the +Windows logo. While the key "Return" is also known as "Enter". + +Motions are the same as Vim: h,j,k,l (left,down,up,right). + +This is the general format of a key chord (aka key binding): + + Super + + +And this is a key chord chain: + + Super + ; + +The keys "Super", "Alt", "Shift", "Ctrl" are known as "modifiers". + +To run a key chord, hold down the modifier and press the key. Key chord +chains build on that principle: you type the key binding to the left of +the semicolon (;), release the modifier and then type the key (or key +chord) to the right of the semicolon. + +In this document, the notation {h,j,k,l} means "any one among" the +comma-separated items. Whereas {1-4} denotes a range: 1,2,3,4. + +Getting started +=============== + +Super + Return |-Open a terminal running the "Default" tmux session +Super + Shift + Return |-Open a generic, yet fully-capable terminal (xterm) +Super + q |-Close focused window safely (apps might require confirmation) +Super + Shift + q |-Kill focused window (no confirmation whatsoever) +Ctrl + Alt + Delete |-Launch poweroptionsmenu, where you can choose to log out, reboot, etc. + +Window motions +============== + +Super + {h,j,k,l} |-Move focus in the given direction == choose which window has attention +Super + Shift + {h,j,k,l} |-Swap focused node with the one in the given direction +Super + Ctrl + {h,j,k,l} |-Expand/contract tiled node in that direction, provided there is a split +Super + Alt + {h,j,k,l} |-Set preselection (manual tiling) for next window + |---Cancel presel by inputting same command again +Super + Alt + {1-9} |-Set the presel ratio, relative to the focused node +Super + Shift + |-Move floating window +Alt + right click |-Drag floating window +Alt + left click |-Resize floating window from the nearest edge + +Window and desktop actions +========================== + +Super + Space |-Toggle between tiled and floating states +Super + m |-Toggle between tiled and monocle layout (monocle == maximised nodes) +Super + f |-Toggle focused window's full screen view +Alt + Tab |-Cycle through windows on the current desktop +Alt + Shift + Tab |-Cycle backwardly through windows on the current desktop + +Desktop operations +================== + +Super + {0-9} |-Switch to the designated desktop (workspace) +Super + Shift + {0-9} |-Send focused node to the given desktop + |---Desktops are created/removed dynamically (my custom setup) +Super + Tab |-Cycle through desktops on the current monitor +Super + Shift + Tab |-Cycle backwardly through desktops on the current monitor +Super + r |-Rotate the node tree 90 degrees clockwise +Super + Shift + r |-Rotate the node tree 90 degrees counter-clockwise +Super + Alt + r |-Mirror/flip the node tree (top left becomes bottom right) +Super + s ; {b,e} |-Balance or equalise node splits (better try it to get an idea) + |---Balance works on the parent node. Equalise is for all nodes. +Super + Shift + {[,]} |-Incrementally decrease or increase the gaps between the tiled nodes +Super + Shift + {y,u,i,o} |-Change to gap presents {0,5,10,20} +Super + comma |-Switch focus to the next monitor (cycles through monitors) +Super + Shift + comma |-Switch focus to the previous monitor (cycles through monitors) + +Launching programs +================== + +Super + d |-Run dmenu with access to all binaries in PATH +Super + Shift + d |-Run flatpakmenu with access to all flatpak apps +Super + g ; {1-3} |-Open graphical apps {firefox,caja,thunderbird} +Super + x ; 0 |-Launch a floating terminal running calc + +Useful extras +============= + +Super + {F1,Home} |-Launch a floating window with this cheat sheet +Print |-Get a screenshot of the focused window saved to the ~/Desktop +Super + Print |-Get a screenshot of the entire viewport saved to the ~/Desktop +Super + p |-Run passmenu to copy a password stored with the UNIX tool "pass" +Super + x ; w |-Run a floating image browser, from where you can also set the wallpaper +Super + e ; c |-Toggle the display compotisor (do this if you have performance issues) +Super + e ; f |-Toggle BSPWM "focus mode", to remove gaps, the padding, the panel +Super + e ; t |-Run tempusmenu to select a Tempus theme for a live theme switch + |---The Tempus themes: https://gitlab.com/protesilaos/tempus-themes + |---Some ports of the Tempus themes are distributed with my dotfiles + +Further reading +=============== + +Study the ~/.config/sxhkd/sxhkdrc and ~/.config/sxhkd/sxhkdrc_bspc. +They are extensively documented. You will find key chords for tasks not +included herein, such as multimedia keys, setting node flags, and more. diff --git a/bspwm/.config/sxhkd/sxhkdrc b/bspwm/.config/sxhkd/sxhkdrc new file mode 100644 index 00000000..fcb26b41 --- /dev/null +++ b/bspwm/.config/sxhkd/sxhkdrc @@ -0,0 +1,128 @@ +# +# SXHKD module with WM-agnostic keys +# +# Part of my dotfiles: . +# + +### Description +# +# Partial configuration file for the Simple X Hotkey Daemon. Meant to +# work with `bspwm`. This is part of my dotfiles, which are managed +# with GNU Stow. See https://gitlab.com/protesilaos/dotfiles + +### Code: + +#### Environment + + +# I am using the prefix `mod4 + e' as a mnemonic for "environment". +# +# The following commands are: +# +# f == bspwm focus mode (my script) +# s == reload sxhkd +# p == reload melonpanel (my lemonbar script) +# x == reload the Xresources file +mod4 + x ; e ; {f,s,p,t,x} + { \ + bspwm_focus_mode, \ + pkill -USR1 -x sxhkd && notify-send -i key_bindings "Reloaded key bindings", \ + pkill -x melonpanel && melonpanel, \ + xrdb -I "$HOME" -merge "$HOME"/.Xresources \ + } + +mod4 + F5 + delight + + +# Invoke the session management menu (log out, lock, reboot, shutdown). +ctrl + alt + Delete + poweroptionsmenu + +#### Keyboard layout + +# NOTE 2021-08-27: review commentary about layout toggle. + +# We can set the keyboard layouts, as well as the toggle directly via +# `setxkbmap`. Example of what I used to run: +# +# setxkbmap -layout 'us,gr' -option 'ctrl:nocaps,compose:menu' +# +# However, doing so means losing out on the possibility to easily find +# out the current/active layout from a script: X knows about "us,gr" in +# that order, not which one is currently typing. As such, in `bspwmrc` +# I simply autostart `setxkbmap -layout 'us'` without defining the +# second layout and a toggle. The toggle is set below. With the +# difference being that it invokes a custom script that switches between +# the us,gr layout. All this is done to be able to get the active +# keyboard layout and print its name to my system panel (custom lemonbar +# called "melonpanel"). +# +# The key chord is based on the Emacs function `toggle-input-method', +# which is bound to C-\ +mod4 + backslash + toggle_kbd_layout + +#### Main programs + +# # Use Xterm as a standalone tool or with Tmux (with Shift). +# mod4 + {_, shift + } Return +# {xterm,xterm -e tmux new-session -A -s 'Default'} + +mod4 + Return + alacritty + +# Show the desired rofi views. +mod4 + x ; {x,b} + rofi -show {drun,window} + + +#### Miscellaneous tools and media keys + + +# Screenshots (requires `scrot`). First one is for the focused window. +# The other is of the entire X session (including all active monitors). +# Note that `scrot` also has an interactive mode that I do not use. +Print + scrot -u -z '%Y-%m-%d_%H:%M:%S_$wx$h$n.png' -e 'mv $f ~/Desktop' \ + && notify-send -i gnome-screenshot "Window view screenshot" "Saved image to Desktop" +mod4 + Print + scrot -m -z '%Y-%m-%d_%H:%M:%S_$wx$h.png' -e 'mv $f ~/Desktop' \ + && notify-send -i gnome-screenshot "Screen view screenshot" "Saved image to Desktop" + +# Control the laptop's screen brightness (requires `xbacklight`). +XF86MonBrightness{Down,Up} + xbacklight {-dec 15,-inc 15} + + +# Specifically for `bongo', my Emacs music manager. +XF86Audio{Play,Prev,Next} + emacsclient -e { \ + "(bongo-pause/resume)", \ + "(bongo-previous)", \ + "(bongo-next)" \ + } + +# Control the [last] currently active player. +mod4 + XF86Audio{Play,Prev,Next} + playerctl {play-pause,previous,next} + +# Speaker/output volume. Requires `amixer` and dedicated keys. +XF86Audio{Mute,LowerVolume,RaiseVolume} + amixer set Master {toggle,5%-,5%+} + +# Microphone/input volume. Same requirements as previous definition. +XF86AudioMicMute + amixer set Capture toggle +mod4 + XF86Audio{Mute,LowerVolume,RaiseVolume} + amixer set Capture {toggle,5%-,5%+} + + + +# TODO 2019-11-01: These will need to be reviewed once all key bindings +# are rewritten. Perhaps it would be nice to produce something that is +# interactive and searchable… +# # Bring up the help text for common keybindings +# mod4 + {F1,Home} +# xterm -class "my_float_window" \ +# -geometry '100x30' -e less "$HOME/.config/sxhkd/cheatsheet_sxhkdrc.txt" diff --git a/bspwm/.config/sxhkd/sxhkdrc_bspc b/bspwm/.config/sxhkd/sxhkdrc_bspc new file mode 100644 index 00000000..178efe1c --- /dev/null +++ b/bspwm/.config/sxhkd/sxhkdrc_bspc @@ -0,0 +1,232 @@ +# +# SXHKD module with BPSWM-specific commands +# +# Part of my dotfiles: https://gitlab.com/protesilaos/dotfiles +# +### Description +# +# Partial configuration file for the Simple X Hotkey Daemon. Meant to +# work with `bspwm`. This is part of my dotfiles, which are managed +# with GNU Stow. See https://gitlab.com/protesilaos/dotfiles +# +# LARGE PORTIONS OF THIS FILE INVOKE MY SHELL SCRIPTS. Do not blindly +# copy-paste from here! + +### Code + +# Close {or kill} currently focused node +mod4 + {_,shift + }q + bspc node -{c,k} + +#### Focus/swap nodes/desktops + +# Focus the node in the given direction. +mod4 + {h,j,k,l} + bspc node -f {west,south,north,east} + +# Swap focused window with the one in the given direction. If there is +# no window in that direction, a receptacle will be created. Inputting +# any direction again will move the focused window to the position of +# the receptacle. This will effectively remove it from the current +# layout, creating a more fluid workflow that does not constrain you to +# the tree of the tiling scheme. +# +# IF you only ever want to move a window into an existing one and avoid +# the added features of the scripted behaviour, use the following +# command instead: +# +# bspc node -s {west,south,north,east} +# +# TIP after breaking free from the layout, you can use --balance to +# spread out the nodes (see the key chord further down). You may also +# --rotate the tree. +# +# bspwm_smart_move is part of my dotfiles (link in the description). +mod4 + shift + {h,j,k,l} + bspwm_smart_move {west,south,north,east} + +# Dynamic desktop behaviour: this invokes a script of mine that +# implements dynamic desktops (see dotfiles). If the given desktop +# number is missing, it is created on the spot. Empty desktops are then +# removed automatically. +# +# +# mod4 + = focus the given desktop +# mod4 + shift + = send focused window to given desktop +# mod4 + ctrl + shift + = as above, but send to next monitor +# mod4 + ctrl + = switches the active (visible) desktop of the +# unfocused monitor, without focusing it (focus stays on the current +# desktop/monitor). It also inserts a receptacle, meaning that the next +# created window will go there without calling focus to itself (see my +# bspwm_external_rules). +# +# +# Commands for receptacles are defined in the "advanced operations" +# section. +# +# NOTE the leading `;` runs this command asynchronously. +# +# NOTE2 the script also offers commands for sending to a desktop on the +# current or the next monitor and following it right away. The +# shorthand for those is `--nsf' and `--nmf' respectively. A +# commented-out version is provided below the enabled key bindings, +# which replaces the "send" commands noted above with their +# "send+follow" equivalents. +mod4 + {_,shift + ,ctrl + shift +,ctrl +}{0-9} + ;bspwm_dynamic_desktops {--df,--ns,--nm,--da} {0-9} + +## Use this for "send+follow" instead of just "send" +# mod4 + {_,shift + ,ctrl + shift +,ctrl +}{0-9} +# ;bspwm_dynamic_desktops {--df,--nsf,--nmf,--da} {0-9} + +# With `alt` focus {next,previous} window in the current desktop. With +# `mod4` focus {next,previous} desktop in the current monitor. +# Cyclical behaviour. Move in the opposite direction while also holding +# down `shift`. +{mod4,alt} + {_,shift +} Tab + bspc {desktop,node} -f {next,prev}.local + +# Switch to the other monitor. +mod4 + o + bspc monitor -f next + +# Switch to last active {desktop,node}. With mod4 move to the last +# active desktop. With alt move to the last active node. "grave" is +# positioned above Tab in QWERTY layouts. +{mod4,alt} + grave + bspc {desktop,node} -f last + +# Expand or contract node in the given direction. +# +# For floating windows one can use Alt + Right Mouse click to +# drag/resize in the given direction (this works in other DEs as well, +# such as MATE and Xfce). I have not set the script to resize floating +# windows because: (i) I do not use them and if I do I do not want to +# change their dimensions, and (ii) to keep the script concise. +mod4 + ctrl + {h,j,k,l} + bspwm_resize {west,south,north,east} 50 + +# Move a floating window with the arrow keys (else use Alt + Left Mouse +# Click to drag). I seldom use floating windows. +mod4 + shift + {Left,Down,Up,Right} + bspc node -v {-20 0,0 20,0 -20,20 0} + +# Preselect the direction or insert again to cancel the preselection. +# This enters the manual tiling mode that splits the currently focused +# window. +mod4 + alt + {h,j,k,l} + bspc node --presel-dir '~{west,south,north,east}' + +# Preselect the ratio. The default value is 0.5, defined in `bspwmrc`. +mod4 + alt + {1-9} + bspc node -o 0.{1-9} + +# Transpose desktops, while keeping focus on the present monitor. With +# shift the focus stays on the present window/desktop, thus moving to +# the other monitor. +mod4 + {_, shift + }t + bspc desktop --swap next.active {_,--follow} + +#### Node layout state and flags + +# Toggle monocle layout (maximise focused node). If you use `-l +# monocle` you lose the toggle functionality. +mod4 + m + bspc desktop -l next + +# Toggle floating, tiled, fullscreen view. Tiled is what is used by +# default. Floating windows have their own dimensions and can be stacked +# on top of each other. +# +# NOTE the presence of the tilde ~. If current state matches the given +# state, then the argument is interpreted as the last state. +mod4 + {shift + space,space,f} + bspc node -t ~{tiled,floating,fullscreen} + +# Set the node flags. Locked is a node that cannot be closed with `bspc +# node --close`. Marked is a specific selector that allows operating on +# the given item (such as sending the marked item to the newest +# preselection). Sticky stays in the focused desktop. Private tries to +# keep its dimensions and tiling position. +mod4 + x ; f ; {l,m,s,p} + bspc node -g {locked,marked,sticky,private} + +#### Manipulate the workspace + +# Rotate all windows {counter-}clockwise by 90 degrees. +mod4 + {_,shift + }r + bspc node @/ --rotate {90,-90} + +# Dynamic gaps. +mod4 + shift + bracket{left,right} + bspc config -d focused window_gap "$(($(bspc config -d focused window_gap) {-,+} 5 ))" + +#### Advanced operations (receptacles and scripted actions) + +# NOTE The behaviour of preselections and receptacles is regulated by my +# bspwm_external_rules command (which is called from within bspwmrc). + +# Insert receptacle following the tiling scheme or preselection. +# Receptacles are empty frames that function as placeholders for +# windows. +# +# Whereas bspwm_smart_move (defined above) will automatically insert +# a receptacle in the given direction by splitting the entire viewport. +mod4 + x ; n ; r + bspc node -i + +# Insert the marked window (or focused if no marks) in the first +# matching receptacle (or preselection if no receptacles). +mod4 + x ; n ; i + bspwm_smart_presel + +# Kill/remove the first matching receptacle from the current desktop. +# With shift, kill them all at once. +mod4 + n ; mod4 + {_, shift + }r + { \ + bspc node 'any.leaf.!window.local' -k, \ + bspwm_multifaceted_operation --kill-all-receptacles \ + } + +# Summon all marked windows across all desktops to the current desktop. +mod4 + x ; n ; m + bspwm_multifaceted_operation --summon-all-marked + +# Bring the windows of the given desktop to the current one. With +# shift, send the current window to the given one. +mod4 + x ; n ; mod4 + {_, shift + }{0-9} + bspwm_multifaceted_operation {--bring-desktop-here,--send-desktop-there} {0-9} + +# Close {or kill} all windows in the present desktop except the focused +# or any marked ones. +mod4 + x ; n ; mod4 + {_,shift + }q + bspwm_multifaceted_operation --{close,kill}-all-local-non-focused + +# Assign the locked flag to all windows in the current desktop. With +# shift, remove the locked flag from all. +mod4 + x ; n ; {_, shift + }l + bspwm_multifaceted_operation {--lock-all-local,--unlock-all-local} + + +#### Continuous input mode + +# EXPLAIN: The following key chords have a colon sign `:' before their +# last part. By pressing the keys to the left of the colon, you can +# then pass the commands by only using the keys to the right of the +# colon. This eliminates the need for repeated chord presses that +# involve the modifier keys. Exit the mode with "Escape". +# +# NOTE: All of the following are mirrors of their afore-mentioned +# couterparts. + +# Resize node in the given direction. +mod4 + c : {h,j,k,l} + bspwm_resize {west,south,north,east} 50 + +# Mode for dynamic gaps. +mod4 + c : bracket{left,right} + bspc config -d focused window_gap "$(($(bspc config -d focused window_gap) {-,+} 5 ))" + +# Move floating windows with the arrow keys +mod4 + c : {Left,Down,Up,Right} + bspc node -v {-20 0,0 20,0 -20,20 0} diff --git a/dunst/.config/dunst/dunstrc b/dunst/.config/dunst/dunstrc new file mode 100644 index 00000000..79d4b224 --- /dev/null +++ b/dunst/.config/dunst/dunstrc @@ -0,0 +1,466 @@ +[global] + ### Display ### + + # Which monitor should the notifications be displayed on. + monitor = 0 + + # Display notification on focused monitor. Possible modes are: + # mouse: follow mouse pointer + # keyboard: follow window with keyboard focus + # none: don't follow anything + # + # "keyboard" needs a window manager that exports the + # _NET_ACTIVE_WINDOW property. + # This should be the case for almost all modern window managers. + # + # If this option is set to mouse or keyboard, the monitor option + # will be ignored. + follow = keyboard + + # The geometry of the window: + # [{width}]x{height}[+/-{x}+/-{y}] + # The geometry of the message window. + # The height is measured in number of notifications everything else + # in pixels. If the width is omitted but the height is given + # ("-geometry x2"), the message window expands over the whole screen + # (dmenu-like). If width is 0, the window expands to the longest + # message displayed. A positive x is measured from the left, a + # negative from the right side of the screen. Y is measured from + # the top and down respectively. + # The width can be negative. In this case the actual width is the + # screen width minus the width defined in within the geometry option. + geometry = "300x5-5-30" + + # Turn on the progess bar + progress_bar = true + + # Set the progress bar height. This includes the frame, so make sure + # it's at least twice as big as the frame width. + progress_bar_height = 10 + + # Set the frame width of the progress bar + progress_bar_frame_width = 1 + + # Set the minimum width for the progress bar + progress_bar_min_width = 150 + + # Set the maximum width for the progress bar + progress_bar_max_width = 300 + + + # Show how many messages are currently hidden (because of geometry). + indicate_hidden = yes + + # Shrink window if it's smaller than the width. Will be ignored if + # width is 0. + shrink = no + + # The transparency of the window. Range: [0; 100]. + # This option will only work if a compositing window manager is + # present (e.g. xcompmgr, compiz, etc.). + transparency = 0 + + # The height of the entire notification. If the height is smaller + # than the font height and padding combined, it will be raised + # to the font height and padding. + notification_height = 0 + + # Draw a line of "separator_height" pixel height between two + # notifications. + # Set to 0 to disable. + separator_height = 1 + + # Padding between text and separator. + padding = 8 + + # Horizontal padding. + horizontal_padding = 8 + + # Padding between text and icon. + text_icon_padding = 0 + + # Defines width in pixels of frame around the notification window. + # Set to 0 to disable. + frame_width = 3 + + # Defines color of the frame around the notification window. + frame_color = "#aaaaaa" + + # Define a color for the separator. + # possible values are: + # * auto: dunst tries to find a color fitting to the background; + # * foreground: use the same color as the foreground; + # * frame: use the same color as the frame; + # * anything else will be interpreted as a X color. + separator_color = frame + + # Sort messages by urgency. + sort = yes + + # Don't remove messages, if the user is idle (no mouse or keyboard input) + # for longer than idle_threshold seconds. + # Set to 0 to disable. + # A client can set the 'transient' hint to bypass this. See the rules + # section for how to disable this if necessary + idle_threshold = 120 + + ### Text ### + + font = Monospace 10 + + # The spacing between lines. If the height is smaller than the + # font height, it will get raised to the font height. + line_height = 0 + + # Possible values are: + # full: Allow a small subset of html markup in notifications: + # bold + # italic + # strikethrough + # underline + # + # For a complete reference see + # . + # + # strip: This setting is provided for compatibility with some broken + # clients that send markup even though it's not enabled on the + # server. Dunst will try to strip the markup but the parsing is + # simplistic so using this option outside of matching rules for + # specific applications *IS GREATLY DISCOURAGED*. + # + # no: Disable markup parsing, incoming notifications will be treated as + # plain text. Dunst will not advertise that it has the body-markup + # capability if this is set as a global setting. + # + # It's important to note that markup inside the format option will be parsed + # regardless of what this is set to. + markup = full + + # The format of the message. Possible variables are: + # %a appname + # %s summary + # %b body + # %i iconname (including its path) + # %I iconname (without its path) + # %p progress value if set ([ 0%] to [100%]) or nothing + # %n progress value if set without any extra characters + # %% Literal % + # Markup is allowed + format = "%s\n%b" + + # Alignment of message text. + # Possible values are "left", "center" and "right". + alignment = left + + # Vertical alignment of message text and icon. + # Possible values are "top", "center" and "bottom". + vertical_alignment = center + + # Show age of message if message is older than show_age_threshold + # seconds. + # Set to -1 to disable. + show_age_threshold = 60 + + # Split notifications into multiple lines if they don't fit into + # geometry. + word_wrap = yes + + # When word_wrap is set to no, specify where to make an ellipsis in long lines. + # Possible values are "start", "middle" and "end". + ellipsize = middle + + # Ignore newlines '\n' in notifications. + ignore_newline = no + + # Stack together notifications with the same content + stack_duplicates = true + + # Hide the count of stacked notifications with the same content + hide_duplicate_count = false + + # Display indicators for URLs (U) and actions (A). + show_indicators = yes + + ### Icons ### + + # Align icons left/right/off + icon_position = left + + # Scale small icons up to this size, set to 0 to disable. Helpful + # for e.g. small files or high-dpi screens. In case of conflict, + # max_icon_size takes precedence over this. + min_icon_size = 0 + + # Scale larger icons down to this size, set to 0 to disable + max_icon_size = 32 + + # Paths to default icons. + icon_path = /usr/share/icons/Adwaita/16x16/status/:/usr/share/icons/Adwaita/16x16/devices/ + + ### History ### + + # Should a notification popped up from history be sticky or timeout + # as if it would normally do. + sticky_history = yes + + # Maximum amount of notifications kept in history + history_length = 20 + + ### Misc/Advanced ### + + # dmenu path. + dmenu = /usr/bin/dmenu -p dunst: + + # Browser for opening urls in context menu. + browser = /usr/bin/firefox -new-tab + + # Always run rule-defined scripts, even if the notification is suppressed + always_run_script = true + + # Define the title of the windows spawned by dunst + title = Dunst + + # Define the class of the windows spawned by dunst + class = Dunst + + # Print a notification on startup. + # This is mainly for error detection, since dbus (re-)starts dunst + # automatically after a crash. + startup_notification = false + + # Manage dunst's desire for talking + # Can be one of the following values: + # crit: Critical features. Dunst aborts + # warn: Only non-fatal warnings + # mesg: Important Messages + # info: all unimportant stuff + # debug: all less than unimportant stuff + verbosity = mesg + + # Define the corner radius of the notification window + # in pixel size. If the radius is 0, you have no rounded + # corners. + # The radius will be automatically lowered if it exceeds half of the + # notification height to avoid clipping text and/or icons. + corner_radius = 0 + + # Ignore the dbus closeNotification message. + # Useful to enforce the timeout set by dunst configuration. Without this + # parameter, an application may close the notification sent before the + # user defined timeout. + ignore_dbusclose = false + + ### Wayland ### + # These settings are Wayland-specific. They have no effect when using X11 + + # Uncomment this if you want to let notications appear under fullscreen + # applications (default: overlay) + # layer = top + + # Set this to true to use X11 output on Wayland. + force_xwayland = false + + ### Legacy + + # Use the Xinerama extension instead of RandR for multi-monitor support. + # This setting is provided for compatibility with older nVidia drivers that + # do not support RandR and using it on systems that support RandR is highly + # discouraged. + # + # By enabling this setting dunst will not be able to detect when a monitor + # is connected or disconnected which might break follow mode if the screen + # layout changes. + force_xinerama = false + + ### mouse + + # Defines list of actions for each mouse event + # Possible values are: + # * none: Don't do anything. + # * do_action: If the notification has exactly one action, or one is marked as default, + # invoke it. If there are multiple and no default, open the context menu. + # * close_current: Close current notification. + # * close_all: Close all notifications. + # These values can be strung together for each mouse event, and + # will be executed in sequence. + mouse_left_click = close_current + mouse_middle_click = do_action, close_current + mouse_right_click = close_all + +# Experimental features that may or may not work correctly. Do not expect them +# to have a consistent behaviour across releases. +[experimental] + # Calculate the dpi to use on a per-monitor basis. + # If this setting is enabled the Xft.dpi value will be ignored and instead + # dunst will attempt to calculate an appropriate dpi value for each monitor + # using the resolution and physical size. This might be useful in setups + # where there are multiple screens with very different dpi values. + per_monitor_dpi = false + +# The internal keyboard shortcut support in dunst is now considered deprecated +# and should be replaced by dunstctl calls. You can use the configuration of your +# WM or DE to bind these to shortcuts of your choice. +# Check the dunstctl manual page for more info. +[shortcuts] + + # Shortcuts are specified as [modifier+][modifier+]...key + # Available modifiers are "ctrl", "mod1" (the alt-key), "mod2", + # "mod3" and "mod4" (windows-key). + # Xev might be helpful to find names for keys. + + # Close notification. Equivalent dunstctl command: + # dunstctl close + # close = ctrl+space + + # Close all notifications. Equivalent dunstctl command: + # dunstctl close-all + # close_all = ctrl+shift+space + + # Redisplay last message(s). Equivalent dunstctl command: + # dunstctl history-pop + # history = ctrl+grave + + # Context menu. Equivalent dunstctl command: + # dunstctl context + # context = ctrl+shift+period + +[urgency_low] + # IMPORTANT: colors have to be defined in quotation marks. + # Otherwise the "#" and following would be interpreted as a comment. + background = "#222222" + foreground = "#888888" + timeout = 4 + # Icon for notifications with low urgency, uncomment to enable + #icon = /path/to/icon + +[urgency_normal] + background = "#333333" + foreground = "#ffffff" + timeout = 6 + # Icon for notifications with normal urgency, uncomment to enable + #icon = /path/to/icon + +[urgency_critical] + background = "#900000" + foreground = "#ffffff" + frame_color = "#ff0000" + timeout = 0 + # Icon for notifications with critical urgency, uncomment to enable + #icon = /path/to/icon + +# Every section that isn't one of the above is interpreted as a rules to +# override settings for certain messages. +# +# Messages can be matched by +# appname (discouraged, see desktop_entry) +# body +# category +# desktop_entry +# icon +# match_transient +# msg_urgency +# stack_tag +# summary +# +# and you can override the +# background +# foreground +# format +# frame_color +# fullscreen +# new_icon +# set_stack_tag +# set_transient +# timeout +# urgency +# +# Shell-like globbing will get expanded. +# +# Instead of the appname filter, it's recommended to use the desktop_entry filter. +# GLib based applications export their desktop-entry name. In comparison to the appname, +# the desktop-entry won't get localized. +# +# SCRIPTING +# You can specify a script that gets run when the rule matches by +# setting the "script" option. +# The script will be called as follows: +# script appname summary body icon urgency +# where urgency can be "LOW", "NORMAL" or "CRITICAL". +# +# NOTE: if you don't want a notification to be displayed, set the format +# to "". +# NOTE: It might be helpful to run dunst -print in a terminal in order +# to find fitting options for rules. + +# Disable the transient hint so that idle_threshold cannot be bypassed from the +# client +#[transient_disable] +# match_transient = yes +# set_transient = no +# +# Make the handling of transient notifications more strict by making them not +# be placed in history. +#[transient_history_ignore] +# match_transient = yes +# history_ignore = yes + +# fullscreen values +# show: show the notifications, regardless if there is a fullscreen window opened +# delay: displays the new notification, if there is no fullscreen window active +# If the notification is already drawn, it won't get undrawn. +# pushback: same as delay, but when switching into fullscreen, the notification will get +# withdrawn from screen again and will get delayed like a new notification +#[fullscreen_delay_everything] +# fullscreen = delay +#[fullscreen_show_critical] +# msg_urgency = critical +# fullscreen = show + +#[espeak] +# summary = "*" +# script = dunst_espeak.sh + +#[script-test] +# summary = "*script*" +# script = dunst_test.sh + +#[ignore] +# # This notification will not be displayed +# summary = "foobar" +# format = "" + +#[history-ignore] +# # This notification will not be saved in history +# summary = "foobar" +# history_ignore = yes + +#[skip-display] +# # This notification will not be displayed, but will be included in the history +# summary = "foobar" +# skip_display = yes + +#[signed_on] +# appname = Pidgin +# summary = "*signed on*" +# urgency = low +# +#[signed_off] +# appname = Pidgin +# summary = *signed off* +# urgency = low +# +#[says] +# appname = Pidgin +# summary = *says* +# urgency = critical +# +#[twitter] +# appname = Pidgin +# summary = *twitter.com* +# urgency = normal +# +#[stack-volumes] +# appname = "some_volume_notifiers" +# set_stack_tag = "volume" +# +# vim: ft=cfg diff --git a/gtk/.config/gtk-3.0/settings.ini b/gtk/.config/gtk-3.0/settings.ini new file mode 100644 index 00000000..ae90a236 --- /dev/null +++ b/gtk/.config/gtk-3.0/settings.ini @@ -0,0 +1,17 @@ +[Settings] +gtk-application-prefer-dark-theme=0 +gtk-theme-name=Adwaita +gtk-icon-theme-name=Adwaita +gtk-font-name=Sans 10 +gtk-cursor-theme-name=Adwaita +gtk-cursor-theme-size=0 +gtk-toolbar-style=GTK_TOOLBAR_BOTH_HORIZ +gtk-toolbar-icon-size=GTK_ICON_SIZE_SMALL_TOOLBAR +gtk-button-images=1 +gtk-menu-images=1 +gtk-enable-event-sounds=1 +gtk-enable-input-feedback-sounds=1 +gtk-xft-antialias=1 +gtk-xft-hinting=1 +gtk-xft-hintstyle=hintslight +gtk-xft-rgba=rgb diff --git a/gtk/.config/gtk-4.0/settings.ini b/gtk/.config/gtk-4.0/settings.ini new file mode 100644 index 00000000..7c6461a7 --- /dev/null +++ b/gtk/.config/gtk-4.0/settings.ini @@ -0,0 +1,2 @@ +[Settings] +gtk-application-prefer-dark-theme=0 diff --git a/gtk/.config/xsettingsd/xsettingsd.conf b/gtk/.config/xsettingsd/xsettingsd.conf new file mode 100644 index 00000000..d0034ced --- /dev/null +++ b/gtk/.config/xsettingsd/xsettingsd.conf @@ -0,0 +1,29 @@ +Gdk/WindowScalingFactor 1 +Gtk/ButtonImages 0 +Gtk/CanChangeAccels 0 +Gtk/ColorPalette "black:white:gray50:red:purple:blue:light blue:green:yellow:orange:lavender:brown:goldenrod4:dodger blue:pink:light green:gray10:gray30:gray75:gray90" +Gtk/CursorThemeName "Adwaita" +Gtk/CursorThemeSize 0 +Gtk/DecorationLayout ":minimize,maximize,close" +Gtk/FontName "Sans 10.5" +Gtk/IconSizes "" +Gtk/KeyThemeName "" +Gtk/MenuBarAccel "" +Gtk/MenuImages 1 +Gtk/MonospaceFontName "Monospace 10" +Gtk/ToolbarIconSize 3 +Gtk/ToolbarStyle "icons" +Net/CursorBlink 1 +Net/CursorBlinkTime 1200 +Net/DndDragThreshold 8 +Net/DoubleClickDistance 5 +Net/DoubleClickTime 400 +Net/EnableEventSounds 1 +Net/EnableInputFeedbackSounds 1 +Net/IconThemeName "Adwaita" +Net/SoundThemeName "default" +Net/ThemeName "Adwaita" +Xft/Antialias 1 +Xft/HintStyle "hintslight" +Xft/Hinting 1 +Xft/RGBA "rgb" diff --git a/gtk/.gtkrc-2.0 b/gtk/.gtkrc-2.0 new file mode 100644 index 00000000..101d14cd --- /dev/null +++ b/gtk/.gtkrc-2.0 @@ -0,0 +1,15 @@ +gtk-theme-name='Arc-Dark' +gtk-icon-theme-name='Papirus-Dark' +gtk-font-name='Sans 10' +gtk-cursor-theme-name='Adwaita' +gtk-cursor-theme-size=0 +gtk-toolbar-style=GTK_TOOLBAR_BOTH_HORIZ +gtk-toolbar-icon-size=GTK_ICON_SIZE_SMALL_TOOLBAR +gtk-button-images=1 +gtk-menu-images=1 +gtk-enable-event-sounds=1 +gtk-enable-input-feedback-sounds=1 +gtk-xft-antialias=1 +gtk-xft-hinting=1 +gtk-xft-hintstyle='hintslight' +gtk-xft-rgba='rgb' diff --git a/keyring/.config/autostart/gnome-keyring-pkcs11.desktop b/keyring/.config/autostart/gnome-keyring-pkcs11.desktop new file mode 100644 index 00000000..a604e12a --- /dev/null +++ b/keyring/.config/autostart/gnome-keyring-pkcs11.desktop @@ -0,0 +1,9 @@ +[Desktop Entry] +Type=Application +Name=Certificate and Key Storage +Comment=GNOME Keyring: PKCS#11 Component +Exec=/usr/bin/gnome-keyring-daemon --start --components=pkcs11 +X-GNOME-Autostart-Phase=PreDisplayServer +X-GNOME-AutoRestart=true +X-GNOME-Autostart-enabled=true +X-GNOME-Autostart-Notify=true diff --git a/keyring/.config/autostart/gnome-keyring-secrets.desktop b/keyring/.config/autostart/gnome-keyring-secrets.desktop new file mode 100644 index 00000000..647ea71a --- /dev/null +++ b/keyring/.config/autostart/gnome-keyring-secrets.desktop @@ -0,0 +1,13 @@ +[Desktop Entry] +Type=Application +Name=Secret Storage Service +Comment=GNOME Keyring: Secret Service +Exec=/usr/bin/gnome-keyring-daemon --start --components=secrets +NoDisplay=true +X-GNOME-Autostart-Phase=PreDisplayServer +X-GNOME-AutoRestart=false +X-GNOME-Autostart-Notify=true +X-GNOME-Bugzilla-Bugzilla=GNOME +X-GNOME-Bugzilla-Product=gnome-keyring +X-GNOME-Bugzilla-Component=general +X-GNOME-Bugzilla-Version=3.28.2 diff --git a/keyring/.config/autostart/gnome-keyring-ssh.desktop b/keyring/.config/autostart/gnome-keyring-ssh.desktop new file mode 100644 index 00000000..00c1aee9 --- /dev/null +++ b/keyring/.config/autostart/gnome-keyring-ssh.desktop @@ -0,0 +1,12 @@ +[Desktop Entry] +Type=Application +Name=SSH Key Agent +Comment=GNOME Keyring: SSH Agent +Exec=/usr/bin/gnome-keyring-daemon --start --components=ssh +X-GNOME-Autostart-Phase=PreDisplayServer +X-GNOME-AutoRestart=false +X-GNOME-Autostart-Notify=true +X-GNOME-Bugzilla-Bugzilla=GNOME +X-GNOME-Bugzilla-Product=gnome-keyring +X-GNOME-Bugzilla-Component=general +X-GNOME-Bugzilla-Version=3.28.2 diff --git a/rofi/.config/rofi/config.rasi b/rofi/.config/rofi/config.rasi new file mode 100644 index 00000000..113bb3c9 --- /dev/null +++ b/rofi/.config/rofi/config.rasi @@ -0,0 +1,119 @@ +configuration { + modi: "run,drun,window"; + width: 100; + lines: 8; + columns: 1; + font: "Monospace 11"; + location: 6; + yoffset: 0; + xoffset: 0; + fixed-num-lines: false; + show-icons: true; + terminal: "xterm"; +/* run-command: "{cmd}";*/ +/* run-list-command: "";*/ +/* run-shell-command: "{terminal} -e {cmd}";*/ +/* window-command: "xkill -id {window}";*/ + window-match-fields: "all"; + drun-match-fields: "name,exec"; + case-sensitive: true; + cycle: true; + sidebar-mode: true; +/* eh: 1;*/ + auto-select: false; + combi-modi: "window,drun"; + matching: "regex"; +/* tokenize: true;*/ +/* m: "-5";*/ +/* filter: ;*/ + hide-scrollbar: true; + fullscreen: false; +/* dpi: -1;*/ + threads: 0; +/* scroll-method: 0;*/ + window-format: "{w:0} {n:0} {t:0}"; + click-to-exit: true; + show-match: true; + theme: "~/.config/rofi/themes/modus-themes-active.rasi"; + max-history-size: 25; + combi-hide-mode-prefix: true; +/* pid: "/run/user/1000/rofi.pid";*/ + display-window: "Windows"; +/* display-windowcd: ;*/ + display-run: "Executables"; +/* display-ssh: ;*/ + display-drun: "Applications"; + display-combi: "Combined"; +/* display-keys: ;*/ + kb-primary-paste: "Control+Y"; + kb-secondary-paste: "Control+y"; + kb-clear-line: "Control+Shift+BackSpace"; + kb-move-front: "Control+a"; + kb-move-end: "Control+e"; + kb-move-word-back: "Alt+b"; + kb-move-word-forward: "Alt+f"; + kb-move-char-back: "Left,Control+b"; + kb-move-char-forward: "Right,Control+f"; + kb-remove-word-back: "Control+BackSpace"; + kb-remove-word-forward: "Alt+d"; + kb-remove-char-forward: "Delete,Control+d"; + kb-remove-char-back: "BackSpace"; + kb-remove-to-eol: "Control+k"; + kb-remove-to-sol: "Control+K"; + kb-accept-entry: "Control+j,Control+m,Return,KP_Enter"; +/* kb-accept-custom: "Control+Return";*/ +/* kb-accept-alt: "Shift+Return";*/ +/* kb-delete-entry: "Shift+Delete";*/ +/* kb-mode-next: "Shift+Right,Control+Tab";*/ +/* kb-mode-previous: "Shift+Left,Control+ISO_Left_Tab";*/ +/* kb-row-left: "Control+Page_Up";*/ +/* kb-row-right: "Control+Page_Down";*/ +/* kb-row-up: "Up,Control+p,ISO_Left_Tab";*/ +/* kb-row-down: "Down,Control+n";*/ +/* kb-row-tab: "Tab";*/ + kb-page-prev: "Alt+v,Page_Up"; + kb-page-next: "Control+v,Page_Down"; + kb-row-first: "Alt+less,Home,KP_Home"; + kb-row-last: "Alt+greater,End,KP_End"; +/* kb-row-select: "Control+space";*/ +/* kb-screenshot: "Alt+S";*/ +/* kb-toggle-case-sensitivity: "grave,dead_grave";*/ +/* kb-toggle-sort: "Alt+grave";*/ +/* kb-cancel: "Escape,Control+g,Control+bracketleft";*/ +/* kb-custom-1: "Alt+1";*/ +/* kb-custom-2: "Alt+2";*/ +/* kb-custom-3: "Alt+3";*/ +/* kb-custom-4: "Alt+4";*/ +/* kb-custom-5: "Alt+5";*/ +/* kb-custom-6: "Alt+6";*/ +/* kb-custom-7: "Alt+7";*/ +/* kb-custom-8: "Alt+8";*/ +/* kb-custom-9: "Alt+9";*/ +/* kb-custom-10: "Alt+0";*/ +/* kb-custom-11: "Alt+exclam";*/ +/* kb-custom-12: "Alt+at";*/ +/* kb-custom-13: "Alt+numbersign";*/ +/* kb-custom-14: "Alt+dollar";*/ +/* kb-custom-15: "Alt+percent";*/ +/* kb-custom-16: "Alt+dead_circumflex";*/ +/* kb-custom-17: "Alt+ampersand";*/ +/* kb-custom-18: "Alt+asterisk";*/ +/* kb-custom-19: "Alt+parenleft";*/ +/* kb-select-1: "Super+1";*/ +/* kb-select-2: "Super+2";*/ +/* kb-select-3: "Super+3";*/ +/* kb-select-4: "Super+4";*/ +/* kb-select-5: "Super+5";*/ +/* kb-select-6: "Super+6";*/ +/* kb-select-7: "Super+7";*/ +/* kb-select-8: "Super+8";*/ +/* kb-select-9: "Super+9";*/ +/* kb-select-10: "Super+0";*/ +/* ml-row-left: "ScrollLeft";*/ +/* ml-row-right: "ScrollRight";*/ +/* ml-row-up: "ScrollUp";*/ +/* ml-row-down: "ScrollDown";*/ +/* me-select-entry: "MousePrimary";*/ +/* me-accept-entry: "MouseDPrimary";*/ +/* me-accept-custom: "Control+MouseDPrimary";*/ +} diff --git a/rofi/.config/rofi/themes/modus-operandi.rasi b/rofi/.config/rofi/themes/modus-operandi.rasi new file mode 100644 index 00000000..00ee39c5 --- /dev/null +++ b/rofi/.config/rofi/themes/modus-operandi.rasi @@ -0,0 +1,34 @@ +/** + * rofi -dump-theme output. + * Rofi version: 1.6.1 + * User: Protesilaos Stavrou + * Copyright: Protesilaos Stavrou --- Released under the GNU GPLv3 + * Comment: Simple port of the Modus Operandi theme for Emacs (https://protesilaos.com/modus-themes) + **/ + +* { + /* Custom colours */ + bg-alt: #f0f0f0ff; + bg-main: #ffffffff; + fg-alt: #505050ff; + fg-main: #000000ff; + red: #a60000ff; + green: #005e00ff; + yellow: #813e00ff; + blue: #0031a9ff; + magenta: #721045ff; + cyan: #00538bff; + red-bright: #b60000ff; + green-bright: #006800ff; + yellow-bright: #605b00ff; + blue-bright: #1f1fceff; + magenta-bright: #a8007fff; + cyan-bright: #005f88ff; + selection-bg: #b0d8ffff; + + /* Global properties */ + background-color: rgba (0,0,0, 0%); + highlight: bold underline #1f1fce; +} + +@import "modus-themes-common.rasi" \ No newline at end of file diff --git a/rofi/.config/rofi/themes/modus-themes-active.rasi b/rofi/.config/rofi/themes/modus-themes-active.rasi new file mode 100644 index 00000000..ce353585 --- /dev/null +++ b/rofi/.config/rofi/themes/modus-themes-active.rasi @@ -0,0 +1 @@ +@import "modus-operandi.rasi" diff --git a/rofi/.config/rofi/themes/modus-themes-common.rasi b/rofi/.config/rofi/themes/modus-themes-common.rasi new file mode 100644 index 00000000..60396d72 --- /dev/null +++ b/rofi/.config/rofi/themes/modus-themes-common.rasi @@ -0,0 +1,136 @@ +/** + * rofi -dump-theme output. + * Rofi version: 1.6.1 + * User: Protesilaos Stavrou + * Copyright: Protesilaos Stavrou --- Released under the GNU GPLv3 + * Comment: Simple port of the Modus themes for Emacs (https://protesilaos.com/modus-themes) + **/ + +window { + background-color: @bg-main; + border: 2px 0 0; + border-color: @fg-alt; + padding: 0px; +} + +mainbox { + border: 0; + padding: 0; +} + +message { + border: 2px solid 0px 0px; + border-color: @fg-alt; + padding: 1px ; +} + +textbox { + text-color: @fg-main; +} + +listview { + fixed-height: 0; + border: 2px solid 0px 0px; + border-color: @bg-alt; + spacing: 4px; + scrollbar: true; + padding: 2px 0px 0px; +} + +element { + border: 0; + padding: 1px; +} + +element.normal.normal { + background-color: @bg-main; + text-color: @fg-main; +} + +element.normal.urgent { + background-color: @red; + text-color: @bg-alt; +} + +element.normal.active { + background-color: @bg-alt; + text-color: @fg-alt; +} + +element.selected.normal { + background-color: @selection-bg; + text-color: @fg-main; +} + +element.selected.urgent { + background-color: @red-bright; + text-color: @bg-main; +} + +element.selected.active { + background-color: @blue; + text-color: @bg-main; +} + +element.alternate.normal { + background-color: @bg-main; + text-color: @fg-main; +} + +element.alternate.urgent { + background-color: @red-bright; + text-color: @bg-alt; +} + +element alternate.active { + background-color: @cyan-bright; + text-color: @bg-alt; +} + +mode-switcher { + border: 2px dash 0px 0px ; + border-color: @bg-alt; +} + +scrollbar { + /* width: 4px; */ + width: 0; + border: 0; + handle-color: @fg-alt; + /* handle-width: 8px; */ + handle-width: 0; + padding: 0; +} + +sidebar { + border: 2px solid 0px 0px; + border-color: @fg-alt; +} + +button { + spacing: 0; + background-color: @bg-main; + text-color: @fg-alt; +} + +button.selected { + background-color: @bg-alt; + text-color: @fg-main; +} + +inputbar { + spacing: 10; + padding: 1px; + text-color: @fg-main; + children: [ prompt,entry ]; +} + +prompt { + spacing: 0; + text-color: @cyan; +} + +entry { + spacing: 0; + text-color: @fg-main; +} diff --git a/rofi/.config/rofi/themes/modus-vivendi.rasi b/rofi/.config/rofi/themes/modus-vivendi.rasi new file mode 100644 index 00000000..2bc1c00e --- /dev/null +++ b/rofi/.config/rofi/themes/modus-vivendi.rasi @@ -0,0 +1,34 @@ +/** + * rofi -dump-theme output. + * Rofi version: 1.6.1 + * User: Protesilaos Stavrou + * Copyright: Protesilaos Stavrou --- Released under the GNU GPLv3 + * Comment: Simple port of the Modus Operandi theme for Emacs (https://protesilaos.com/modus-themes) + **/ + +* { + /* Custom colours */ + bg-alt: #191a1bff; + bg-main: #000000ff; + fg-alt: #a8a8a8ff; + fg-main: #ffffffff; + red: #ff8059ff; + green: #44bc44ff; + yellow: #d0bc00ff; + blue: #2fafffff; + magenta: #feacd0ff; + cyan: #00d3d0ff; + red-bright: #fe6060ff; + green-bright: #4fe42fff; + yellow-bright: #f0dd60ff; + blue-bright: #4fafffff; + magenta-bright: #ff62d4ff; + cyan-bright: #3fdfd0ff; + selection-bg: #103265ff; + + /* Global properties */ + background-color: rgba (0,0,0, 0%); + highlight: bold underline #4fafff; +} + +@import "modus-themes-common.rasi" \ No newline at end of file diff --git a/xorg/.profile b/xorg/.profile new file mode 100644 index 00000000..7544bae2 --- /dev/null +++ b/xorg/.profile @@ -0,0 +1,57 @@ +# .profile --- Initialisation script for display managers. +# +# Copyright (c) 2020 Protesilaos Stavrou +# +# This program is free software; you can redistribute it and/or +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +## Commentary: +# +# This script is read by a graphical display manager when logging into +# the session. It is conceptually similar to `.xinitrc' and I am +# considering it as practically equivalent to it for the ordinary +# functioning of my custom desktop session. Refer to my dotfiles for +# the specifics: https://gitlab.com/protesilaos/dotfiles + + +############### +# Shell setup # +############### + +# Source my bashrc. +if [ -n "$BASH_VERSION" ]; then + if [ -f "$HOME"/.bashrc ]; then + source "$HOME"/.bashrc + fi +fi + +# Set PATH so it includes user's private executables. +if [ -d "$HOME"/bin ]; then + PATH=$PATH:"$HOME"/bin +fi + +# This is another possible location for user-specific binaries. +if [ -d "$HOME"/.local/bin ]; then + PATH=$PATH:"$HOME"/.local/bin +fi + +########################## +# Environment essentials # +########################## + +# Auto unlocks the GPG and SSH agents. +eval $(/usr/bin/gnome-keyring-daemon --start --components=pkcs11,secrets,ssh) +export SSH_AUTH_SOCK + +# Load my XTerm and relevant configurations. +[ -f "$HOME"/.Xresources ] && xrdb -I "$HOME" -merge "$HOME"/.Xresources diff --git a/xorg/.xinitrc b/xorg/.xinitrc new file mode 100644 index 00000000..810097eb --- /dev/null +++ b/xorg/.xinitrc @@ -0,0 +1,74 @@ +# xinitrc --- Initialisation script for the X server session. +# +# Copyright (c) 2019-2020 Protesilaos Stavrou +# +# This program is free software; you can redistribute it and/or +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +### Commentary: +# +# This script is a core part of my custom desktop session, centred +# around GNU Emacs: . +# +### Code: + + +#### Shell setup + +# Source my bashrc. +if [ -n "$BASH_VERSION" ]; then + if [ -f "$HOME"/.bashrc ]; then + source "$HOME"/.bashrc + fi +fi + +# Set PATH so it includes user's private executables. +if [ -d "$HOME"/bin ]; then + PATH=$PATH:"$HOME"/bin +fi + +# This is another possible location for user-specific binaries. +if [ -d "$HOME"/.local/bin ]; then + PATH=$PATH:"$HOME"/.local/bin +fi + +#### Environment essentials + +# Auto unlocks the GPG and SSH agents. +eval $(/usr/bin/gnome-keyring-daemon --start --components=pkcs11,secrets,ssh) +export SSH_AUTH_SOCK + +#### Session selection + +# Launch X by running: +# +# xinit +# xinit xfce +# +# Or pass this file and the DE/WM arg to startx: +# startx ~/.xinitrc emacs +# +# Also check my `.bash_profile' for the automatic login setup. + +# Emacs is the default. +session=${1:-bspwm} + +#### Sessions + +# Map arguments to commands. +case $session in + bspwm ) exec bspwm ;; + mate ) exec mate-session ;; + xfce ) exec startxfce4 ;; + *) echo "Unknown session" ;; +esac