Compare commits

..

No commits in common. "0a6281b54369889435fa97205aa55cccd2e3a121" and "5fee14ab7f9c54e0045267c87edddffd128ad9fd" have entirely different histories.

26 changed files with 461 additions and 550 deletions

View file

@ -16,85 +16,54 @@ real names you type; this README explains what each one does.
|---|---| |---|---|
| `suckless/` | The programs, each with its own `config.h` and patches | | `suckless/` | The programs, each with its own `config.h` and patches |
| `home/` | Files that go in `~`, at the same path (they are symlinked) | | `home/` | Files that go in `~`, at the same path (they are symlinked) |
| `sistema/` | Files that go in `/` (acpid, zzz, turnstile, udev, doas, xbps, runit) | | `sistema/` | Files that go in `/` (acpid, zzz, elogind, udev, sudoers, runit) |
| `install.sh` | Installs everything on a fresh Void system | | `install.sh` | Installs everything on a fresh Void system |
## Install ## Install
On a fresh Void install, as your normal user (it asks for the root On a fresh Void install, as your normal user (it asks for sudo when needed):
password when needed: through sudo until doas is ready, then through doas):
git clone ssh://forgejo@ssh.alejandrogs.es/alejandrogs73/suckless.git ~/suckless git clone ssh://forgejo@ssh.alejandrogs.es/alejandrogs73/suckless.git ~/suckless
cd ~/suckless && ./install.sh cd ~/suckless && ./install.sh
It runs seven steps, which can also be run on their own (`./install.sh enlaces`, It runs six steps, which can also be run on their own (`./install.sh enlaces`,
for example) and repeated safely: for example) and repeated safely:
1. `paquetes` (packages): installs with xbps everything the setup uses. 1. `paquetes` (packages): installs with xbps everything the setup uses.
2. `suckless`: builds the programs and installs them in `/usr/local`. 2. `suckless`: builds the programs and installs them in `/usr/local`.
3. `enlaces` (links): symlinks every file in `home/` into `~`. If a different 3. `enlaces` (links): symlinks every file in `home/` into `~`. If a different
file was already there, it is kept as `.bak`. Since they are symlinks, file was already there, it is kept as `.bak`. Since they are symlinks,
editing `~/.bashrc` edits the repo. Links to files deleted from the repo editing `~/.bashrc` edits the repo. It also creates the user folders and
are removed. It also creates the user folders and
sets `~/.ssh` to 700. sets `~/.ssh` to 700.
4. `gtk`: builds the [Everforest GTK](https://github.com/Fausto-Korpsvart/Everforest-GTK-Theme) 4. `gtk`: builds the [Everforest GTK](https://github.com/Fausto-Korpsvart/Everforest-GTK-Theme)
theme (green, dark, medium palette) in `~/.themes` from a pinned commit, theme (green, dark, medium palette) in `~/.themes` from a pinned commit,
links it for GTK 4 apps and makes the Papirus folders green. Icons are and links it for GTK 4 apps. It fixes the colours of the GTK 2 part (the
theme ships Gruvbox ones) and makes the Papirus folders green. Icons are
Papirus-Dark everywhere. Qt 5 and Qt 6 apps use qt5ct/qt6ct Papirus-Dark everywhere. Qt 5 and Qt 6 apps use qt5ct/qt6ct
(`QT_QPA_PLATFORMTHEME` in `.xinitrc`) with the Fusion style and an (`QT_QPA_PLATFORMTHEME` in `.xinitrc`) with the Fusion style and an
Everforest palette (`home/.config/qt*ct/`). If a `papirus-icon-theme` Everforest palette (`home/.config/qt*ct/`). If a `papirus-icon-theme`
update turns the folders blue again, just run this step again. update turns the folders blue again, just run this step again.
5. `gnupg`: for after copying `~/.gnupg` by hand (from a USB stick, for 5. `gnupg`: for after copying `~/.gnupg` by hand (from a USB stick, for
example). It fixes the permissions, sets `pinentry-dmenu` with the dmenu example). It fixes the permissions, sets `pinentry-gtk` (falls back to
colours (`pinentry-curses` on a tty: `home/.local/bin/pinentry-menu` curses on a tty), enables gpg's SSH agent, adds the authentication subkeys
picks one), enables gpg's SSH agent, adds the authentication subkeys
to `sshcontrol` and caches the passphrase for one hour. `.bashrc` already to `sshcontrol` and caches the passphrase for one hour. `.bashrc` already
points `SSH_AUTH_SOCK` at the agent. If `~/.gnupg` does not exist yet, it points `SSH_AUTH_SOCK` at the agent. If `~/.gnupg` does not exist yet, it
does nothing. does nothing.
6. `sistema` (system): copies `sistema/` into `/`, sets up 6. `sistema` (system): copies `sistema/` into `/`, enables the runit services
`wpa_supplicant.conf` so wheel users can use `wpa_cli` without root and (dbus, elogind, polkitd, NetworkManager, bluetoothd, acpid, chronyd, tlp,
save networks, enables the runit services (dbus, turnstiled, automontaje, cupsd), removes dhcpcd and wpa_supplicant (NetworkManager
wpa_supplicant, dhcpcd, bluetoothd, acpid, chronyd, tlp, automontaje, already manages the network) and adds the user to the audio, video, input,
cupsd), removes NetworkManager, elogind and polkitd (if something asks for network, bluetooth and lpadmin (printer management) groups. Files in
polkit, like udisks2 or libvirt, D-Bus starts it on its own) and adds the `sudoers.d` are checked with `visudo` and installed with mode 440.
user to the audio, video, input, network, bluetooth, lpadmin (printer
management) and `_pipewire` (realtime priority for audio without rtkit)
groups. `doas.conf` is checked with `doas -C` before it is installed with
mode 400.
7. `quitar` (remove): uninstalls what the repo no longer uses because
something else replaces it: sudo (doas), feh (xwallpaper and nsxiv),
gammastep (sct), autorandr (`pantallas`), blueman and pavucontrol (the
`bluetooth` and `volumen` scripts), pinentry-gtk (pinentry-dmenu), vlc
(mpv), btop, NetworkManager and tlp-rdw (wpa_supplicant, dhcpcd and the
`wifi` script), rtkit and elogind (turnstile). sudo can be removed thanks
to `sistema/etc/xbps.d/sin-sudo.conf` (base-system depends on it), and it
is only removed once `/etc/doas.conf` is installed.
Afterwards, log out and back in (for the groups) and run `startx`. Afterwards, log out and back in (for the groups) and run `startx`.
Nix is not installed: the little that comes from it (webcord) is installed by Nix is not installed: the little that comes from it (webcord) is installed by
hand. hand.
## Without elogind
elogind is systemd's logind on its own, and it is not needed here:
- `XDG_RUNTIME_DIR` (`/run/user/UID`) is created by turnstile at login
(`sistema/etc/turnstile/turnstiled.conf`: only that, no user services).
- Xorg runs as root through `Xorg.wrap` (`needs_root_rights = yes` in
`/etc/X11/Xwrapper.config`, shipped by Void).
- The lid and the power and suspend buttons are handled by acpid, which
calls `zzz`. Power off and reboot are runit's.
- Devices (sound, video, input, bluetooth) are reached through the user's
groups, not through the ACLs elogind gave the active session.
What stops working: mounting disks from a file manager (udisks2 asks polkit
for an active session, and there is none). USB sticks are mounted by
`automontaje`.
## Rebuilding after changing the config ## Rebuilding after changing the config
cd suckless/dwm && make && doas make install cd suckless/dwm && make && sudo make install
## Updating from upstream ## Updating from upstream
@ -141,18 +110,6 @@ The audio keys (and clicks on VOL in the bar) use the `volumen` script
(`home/.local/bin/volumen`): it changes the volume with `wpctl`, refreshes (`home/.local/bin/volumen`): it changes the volume with `wpctl`, refreshes
slstatus and shows a notification with the level. slstatus and shows a notification with the level.
The script menus (`apagado`, `bluetooth`, `volumen salida`...) use `menu`,
which is dmenu with the dwm font and colours.
### Bar clicks
| Area | Left | Middle | Right | Wheel |
|---|---|---|---|---|
| Network | Connect to a network (`wifi`) | | `wpa_cli` | |
| VOL | Pick the audio output (`volumen salida`) | Mute | Mute the mic | Volume ± |
| BT | Bluetooth menu (`bluetooth`): connect, disconnect, scan and pair, power off | | Power on or off | |
| Date | This month's calendar | | | |
Screenshots are saved in `~/Images/Screenshots`, copied to the clipboard and Screenshots are saved in `~/Images/Screenshots`, copied to the clipboard and
shown in a notification. shown in a notification.
@ -160,19 +117,13 @@ shown in a notification.
- Logging in on tty1 starts `startx` automatically (`.bash_profile`); other - Logging in on tty1 starts `startx` automatically (`.bash_profile`); other
ttys do not. ttys do not.
- `.xinitrc` also starts `luz` (warm light with `sct` from 20:00 to 8:00, - `.xinitrc` also starts `gammastep` (warm light from 20:00 to 8:00, with a
with a one-hour transition) and `bateria` (warns at 15 % and, in red, at one-hour transition) and `bateria` (warns at 15 % and, in red, at 5 %; at
5 %; at 3 % it suspends with `doas -n zzz`). Suspend, power off and reboot 3 % it suspends with `sudo -n zzz`). Suspend, power off and reboot need no
need no password (`sistema/etc/doas.conf`). password (`sistema/etc/sudoers.d/energia`).
- Screens: `pantallas` (`sistema/usr/local/bin`) lines them up with `xrandr` - Screens: `autorandr` lines them up (the laptop one on the left and as
(the laptop one on the left and as primary) at startup and whenever one is primary) at startup and whenever one is plugged or unplugged (udev rule in
plugged or unplugged (udev rule in `sistema/`), then repaints the `sistema/`), then repaints the wallpaper.
wallpaper with `xwallpaper`.
- WiFi: `wifi` scans with `wpa_cli` and lists the networks in dmenu by
signal (`*` is the current one). For a new network it asks for the
password (hidden while typing) and saves it in
`/etc/wpa_supplicant/wpa_supplicant.conf` only if the connection works.
dhcpcd handles the cable on its own.
- Left click on the date in the bar: this month's calendar in a notification - Left click on the date in the bar: this month's calendar in a notification
(`calendario`), with today in green. (`calendario`), with today in green.
- bash: 10 000-entry history, without duplicates and shared between - bash: 10 000-entry history, without duplicates and shared between
@ -194,7 +145,7 @@ shown in a notification.
them in `/mnt/LABEL`, or `/mnt/sdXY` if they have no label, and unmounts them in `/mnt/LABEL`, or `/mnt/sdXY` if they have no label, and unmounts
them when removed, with a notification. FAT, exFAT and NTFS are owned by them when removed, with a notification. FAT, exFAT and NTFS are owned by
the user; internal disks are never touched. Before pulling a stick you the user; internal disks are never touched. Before pulling a stick you
wrote to, run `sync` (or `doas umount /mnt/...`). wrote to, run `sync` (or `sudo umount /mnt/...`).
- User folders in English and without accents (`user-dirs.dirs`): - User folders in English and without accents (`user-dirs.dirs`):
Documents, Downloads and Images. Documents, Downloads and Images.
@ -212,7 +163,6 @@ shown in a notification.
the combination with ligatures come from the `graphics-with-patches` the combination with ligatures come from the `graphics-with-patches`
branch of [st-graphics](https://github.com/sergei-grechanik/st-graphics), branch of [st-graphics](https://github.com/sergei-grechanik/st-graphics),
without boxdraw. without boxdraw.
- In st, Ctrl+Shift+right click on an image opens it in `nsxiv`.
- st shows images with the kitty graphics protocol; yazi detects it on its - st shows images with the kitty graphics protocol; yazi detects it on its
own and shows previews without ueberzugpp. own and shows previews without ueberzugpp.
- slock is modified by hand (not a patch): clock, date, battery and a bottom - slock is modified by hand (not a patch): clock, date, battery and a bottom

View file

@ -12,86 +12,55 @@ Tema Everforest y fuente Fira Code en todos.
|---|---| |---|---|
| `suckless/` | Los programas, cada uno con su `config.h` y sus parches | | `suckless/` | Los programas, cada uno con su `config.h` y sus parches |
| `home/` | Archivos que van en `~`, con la misma ruta (se enlazan) | | `home/` | Archivos que van en `~`, con la misma ruta (se enlazan) |
| `sistema/` | Archivos que van en `/` (acpid, zzz, turnstile, udev, doas, xbps, runit) | | `sistema/` | Archivos que van en `/` (acpid, zzz, elogind, udev, sudoers, runit) |
| `install.sh` | Lo instala todo en un Void recién instalado | | `install.sh` | Lo instala todo en un Void recién instalado |
## Instalar ## Instalar
En un Void recién instalado, como tu usuario (pide la contraseña de root En un Void recién instalado, como tu usuario (pide sudo cuando hace falta):
cuando hace falta: con sudo hasta que doas está listo, luego con doas):
git clone ssh://forgejo@ssh.alejandrogs.es/alejandrogs73/suckless.git ~/suckless git clone ssh://forgejo@ssh.alejandrogs.es/alejandrogs73/suckless.git ~/suckless
cd ~/suckless && ./install.sh cd ~/suckless && ./install.sh
Hace siete pasos, que también se pueden lanzar por separado Hace seis pasos, que también se pueden lanzar por separado
(`./install.sh enlaces`, por ejemplo) y repetir sin problema: (`./install.sh enlaces`, por ejemplo) y repetir sin problema:
1. `paquetes`: instala con xbps todo lo que usa la configuración. 1. `paquetes`: instala con xbps todo lo que usa la configuración.
2. `suckless`: compila e instala los programas en `/usr/local`. 2. `suckless`: compila e instala los programas en `/usr/local`.
3. `enlaces`: enlaza cada archivo de `home/` en `~`. Si ya existía un archivo 3. `enlaces`: enlaza cada archivo de `home/` en `~`. Si ya existía un archivo
distinto, lo guarda como `.bak`. Como son enlaces, editar `~/.bashrc` es distinto, lo guarda como `.bak`. Como son enlaces, editar `~/.bashrc` es
editar el repo. Los enlaces a archivos que se han borrado del repo se editar el repo. También crea las carpetas del usuario y deja `~/.ssh` en
quitan. También crea las carpetas del usuario y deja `~/.ssh` en
700. 700.
4. `gtk`: compila el tema [Everforest GTK](https://github.com/Fausto-Korpsvart/Everforest-GTK-Theme) 4. `gtk`: compila el tema [Everforest GTK](https://github.com/Fausto-Korpsvart/Everforest-GTK-Theme)
(verde, oscuro, paleta medium) en `~/.themes`, en una versión fija, y lo (verde, oscuro, paleta medium) en `~/.themes`, en una versión fija, y lo
enlaza para las apps de GTK 4, y pone verdes las carpetas de Papirus. Los enlaza para las apps de GTK 4. Corrige los colores de la parte de GTK 2
(el tema trae los de Gruvbox) y pone verdes las carpetas de Papirus. Los
iconos son Papirus-Dark en todo. Las apps Qt 5 y Qt 6 usan qt5ct/qt6ct iconos son Papirus-Dark en todo. Las apps Qt 5 y Qt 6 usan qt5ct/qt6ct
(`QT_QPA_PLATFORMTHEME` en `.xinitrc`) con el estilo Fusion y una paleta (`QT_QPA_PLATFORMTHEME` en `.xinitrc`) con el estilo Fusion y una paleta
Everforest (`home/.config/qt*ct/`). Si una actualización de Everforest (`home/.config/qt*ct/`). Si una actualización de
`papirus-icon-theme` devuelve las carpetas a azul, basta con repetir este `papirus-icon-theme` devuelve las carpetas a azul, basta con repetir este
paso. paso.
5. `gnupg`: para después de copiar `~/.gnupg` a mano (de un USB, por 5. `gnupg`: para después de copiar `~/.gnupg` a mano (de un USB, por
ejemplo). Arregla los permisos, pone `pinentry-dmenu` con los colores de ejemplo). Arregla los permisos, pone `pinentry-gtk` (en una tty cae a
dmenu (en una tty, `pinentry-curses`: lo decide curses solo), activa el agente SSH de gpg, añade a `sshcontrol` las
`home/.local/bin/pinentry-menu`), activa el agente SSH de gpg, añade a `sshcontrol` las
subclaves de autenticación y hace que recuerde la contraseña una hora. subclaves de autenticación y hace que recuerde la contraseña una hora.
`.bashrc` ya apunta `SSH_AUTH_SOCK` al agente. Si `~/.gnupg` no existe `.bashrc` ya apunta `SSH_AUTH_SOCK` al agente. Si `~/.gnupg` no existe
todavía, no hace nada. todavía, no hace nada.
6. `sistema`: copia `sistema/` en `/`, prepara `wpa_supplicant.conf` para que 6. `sistema`: copia `sistema/` en `/`, activa los servicios de runit (dbus,
los de wheel usen `wpa_cli` sin root y guarden redes, activa los servicios elogind, polkitd, NetworkManager, bluetoothd, acpid, chronyd, tlp,
de runit (dbus, turnstiled, wpa_supplicant, dhcpcd, bluetoothd, acpid, automontaje, cupsd), quita dhcpcd y wpa_supplicant (NetworkManager ya
chronyd, tlp, automontaje, cupsd), quita NetworkManager, elogind y polkitd gestiona la red) y añade el usuario a los grupos audio, video, input,
(si algo pide polkit, como udisks2 o libvirt, D-Bus lo arranca solo) y network, bluetooth y lpadmin (para gestionar impresoras). Los archivos de
añade el usuario a los grupos audio, video, input, network, bluetooth, `sudoers.d` se validan con `visudo` y se instalan con modo 440.
lpadmin (para gestionar impresoras) y `_pipewire` (prioridad de tiempo real
para el audio sin rtkit). `doas.conf` se valida con `doas -C` antes de
instalarlo con modo 400.
7. `quitar`: desinstala lo que el repo ya no usa porque lo sustituye otra
cosa: sudo (doas), feh (xwallpaper y nsxiv), gammastep (sct), autorandr
(`pantallas`), blueman y pavucontrol (scripts `bluetooth` y `volumen`),
pinentry-gtk (pinentry-dmenu), vlc (mpv), btop, NetworkManager y tlp-rdw
(wpa_supplicant, dhcpcd y el script `wifi`), rtkit y elogind (turnstile).
sudo se puede quitar gracias a `sistema/etc/xbps.d/sin-sudo.conf`
(base-system depende de él), y solo se quita si `/etc/doas.conf` ya está
instalado.
Después hay que cerrar sesión y volver a entrar (por los grupos) y lanzar Después hay que cerrar sesión y volver a entrar (por los grupos) y lanzar
`startx`. `startx`.
Nix no se instala: lo poco que viene de ahí (webcord) se instala a mano. Nix no se instala: lo poco que viene de ahí (webcord) se instala a mano.
## Sin elogind
elogind es el logind de systemd por separado, y aquí sobra:
- `XDG_RUNTIME_DIR` (`/run/user/UID`) lo crea turnstile al entrar
(`sistema/etc/turnstile/turnstiled.conf`: solo eso, sin servicios de
usuario).
- Xorg arranca como root con `Xorg.wrap` (`needs_root_rights = yes` en
`/etc/X11/Xwrapper.config`, lo trae Void).
- La tapa y los botones de encendido y suspender los lleva acpid, que llama a
`zzz`. Apagar y reiniciar son los de runit.
- Los dispositivos (sonido, vídeo, entrada, bluetooth) van por los grupos del
usuario, no por las ACL que ponía elogind a la sesión activa.
Lo que deja de ir: montar discos desde un gestor de archivos (udisks2 pide a
polkit una sesión activa, que ya no hay). Las memorias USB las monta
`automontaje`.
## Recompilar tras cambiar la configuración ## Recompilar tras cambiar la configuración
cd suckless/dwm && make && doas make install cd suckless/dwm && make && sudo make install
## Actualizar desde el proyecto original ## Actualizar desde el proyecto original
@ -139,18 +108,6 @@ Las teclas de audio (y los clics en VOL de la barra) usan el script `volumen`
(`home/.local/bin/volumen`): cambia el volumen con `wpctl`, refresca slstatus (`home/.local/bin/volumen`): cambia el volumen con `wpctl`, refresca slstatus
y muestra una notificación con el nivel. y muestra una notificación con el nivel.
Los menús de los scripts (`apagado`, `bluetooth`, `volumen salida`...) usan
`menu`, que es dmenu con la fuente y los colores de dwm.
### Clics en la barra
| Zona | Izquierdo | Central | Derecho | Rueda |
|---|---|---|---|---|
| Red | Conectarse a una red (`wifi`) | | `wpa_cli` | |
| VOL | Elegir la salida de audio (`volumen salida`) | Silenciar | Silenciar el micro | Volumen ± |
| BT | Menú de bluetooth (`bluetooth`): conectar, desconectar, buscar y emparejar, apagar | | Encender o apagar | |
| Fecha | Calendario del mes | | | |
Las capturas se guardan en `~/Images/Screenshots`, se copian al portapapeles Las capturas se guardan en `~/Images/Screenshots`, se copian al portapapeles
y muestran una notificación. y muestran una notificación.
@ -158,18 +115,13 @@ y muestran una notificación.
- Al entrar en tty1 se lanza `startx` solo (`.bash_profile`); en las demás - Al entrar en tty1 se lanza `startx` solo (`.bash_profile`); en las demás
tty no. tty no.
- `.xinitrc` arranca también `luz` (luz cálida con `sct` de 20:00 a 8:00, - `.xinitrc` arranca también `gammastep` (luz cálida de 20:00 a 8:00, con
con transición de una hora) y `bateria` (avisa al 15 % y, en rojo, al 5 %; transición de una hora) y `bateria` (avisa al 15 % y, en rojo, al 5 %; al
al 3 % suspende con `doas -n zzz`). Suspender, apagar y reiniciar no piden 3 % suspende con `sudo -n zzz`). Suspender, apagar y reiniciar no piden
contraseña (`sistema/etc/doas.conf`). contraseña (`sistema/etc/sudoers.d/energia`).
- Pantallas: `pantallas` (`sistema/usr/local/bin`) las pone en fila con - Pantallas: `autorandr` las pone en fila (la del portátil a la izquierda y
`xrandr` (la del portátil a la izquierda y como principal) al arrancar y como principal) al arrancar y cada vez que se conecta o desconecta una
cada vez que se conecta o desconecta una (regla de udev en `sistema/`), y (regla de udev en `sistema/`), y vuelve a pintar el fondo.
vuelve a pintar el fondo con `xwallpaper`.
- WiFi: `wifi` busca redes con `wpa_cli` y las enseña en dmenu por señal
(`*` la actual). Si la red es nueva pide la contraseña (no se ve al
escribirla) y la guarda en `/etc/wpa_supplicant/wpa_supplicant.conf` solo
si la conexión va bien. El cable lo coge dhcpcd solo.
- Clic izquierdo en la fecha de la barra: calendario del mes en una - Clic izquierdo en la fecha de la barra: calendario del mes en una
notificación (`calendario`), con el día de hoy en verde. notificación (`calendario`), con el día de hoy en verde.
- bash: historial de 10 000 órdenes, sin duplicados y compartido entre - bash: historial de 10 000 órdenes, sin duplicados y compartido entre
@ -191,7 +143,7 @@ y muestran una notificación.
las monta en `/mnt/ETIQUETA`, o en `/mnt/sdXY` si no tienen etiqueta, y las monta en `/mnt/ETIQUETA`, o en `/mnt/sdXY` si no tienen etiqueta, y
las desmonta al sacarlas, con una notificación. FAT, exFAT y NTFS quedan a las desmonta al sacarlas, con una notificación. FAT, exFAT y NTFS quedan a
nombre del usuario; los discos internos no se tocan. Antes de sacar una nombre del usuario; los discos internos no se tocan. Antes de sacar una
memoria en la que se ha escrito, `sync` (o `doas umount /mnt/...`). memoria en la que se ha escrito, `sync` (o `sudo umount /mnt/...`).
- Carpetas del usuario en inglés y sin tildes (`user-dirs.dirs`): - Carpetas del usuario en inglés y sin tildes (`user-dirs.dirs`):
Documents, Downloads e Images. Documents, Downloads e Images.
@ -208,7 +160,6 @@ y muestran una notificación.
con ligatures vienen de la rama `graphics-with-patches` de con ligatures vienen de la rama `graphics-with-patches` de
[st-graphics](https://github.com/sergei-grechanik/st-graphics), sin [st-graphics](https://github.com/sergei-grechanik/st-graphics), sin
boxdraw. boxdraw.
- En st, Ctrl+Shift+clic derecho sobre una imagen la abre en `nsxiv`.
- st muestra imágenes con el protocolo de gráficos de kitty; yazi lo detecta - st muestra imágenes con el protocolo de gráficos de kitty; yazi lo detecta
solo y enseña las vistas previas sin ueberzugpp. solo y enseña las vistas previas sin ueberzugpp.
- slock está modificado a mano (no es un parche): reloj, fecha, batería y - slock está modificado a mano (no es un parche): reloj, fecha, batería y

View file

@ -61,13 +61,13 @@ alias mv='mv -i'
# --- 4. Aliases para Void Linux (xbps) --- # --- 4. Aliases para Void Linux (xbps) ---
# Te ahorrarán teclear 'xbps-lo-que-sea' 40 veces al día # Te ahorrarán teclear 'xbps-lo-que-sea' 40 veces al día
alias xi='doas xbps-install' # Instalar paquete alias xi='sudo xbps-install' # Instalar paquete
alias xu='doas xbps-install -Su' # Actualizar todo el sistema alias xu='sudo xbps-install -Su' # Actualizar todo el sistema
alias xq='xbps-query -Rs' # Buscar paquete en el repositorio alias xq='xbps-query -Rs' # Buscar paquete en el repositorio
alias xl='xbps-query -l' # Listar paquetes instalados alias xl='xbps-query -l' # Listar paquetes instalados
alias xr='doas xbps-remove -R' # Eliminar paquete y sus huérfanos alias xr='sudo xbps-remove -R' # Eliminar paquete y sus huérfanos
alias esp32='doas chmod a+rw /dev/ttyUSB0' alias esp32='sudo chmod a+rw /dev/ttyUSB0'
# --- 5. Funciones Útiles --- # --- 5. Funciones Útiles ---

View file

@ -0,0 +1,6 @@
#!/bin/sh
# Tras cambiar de pantallas: la interna del portátil (eDP*/LVDS*) como
# principal y el fondo pintado de nuevo con la geometría nueva.
interna=$(xrandr | awk '/^(eDP|LVDS)[^ ]* connected/ { print $1; exit }')
[ -n "$interna" ] && xrandr --output "$interna" --primary
feh --no-fehbg --bg-fill "$HOME/.local/share/wallpaper.jpg"

286
home/.config/btop/btop.conf Normal file
View file

@ -0,0 +1,286 @@
#? Config file for btop v.1.4.7
#* Name of a btop++/bpytop/bashtop formatted ".theme" file, "Default" and "TTY" for builtin themes.
#* Themes should be placed in "../share/btop/themes" relative to binary or "$HOME/.config/btop/themes"
color_theme = "everforest-dark-medium"
#* If the theme set background should be shown, set to False if you want terminal background transparency.
theme_background = false
#* Sets if 24-bit truecolor should be used, will convert 24-bit colors to 256 color (6x6x6 color cube) if false.
truecolor = true
#* Set to true to force tty mode regardless if a real tty has been detected or not.
#* Will force 16-color mode and TTY theme, set all graph symbols to "tty" and swap out other non tty friendly symbols.
force_tty = false
#* Option to disable presets. Either the default preset, custom presets, or all presets.
#* "Off" All presets are enabled.
#* "Default" preset is disabled.#* "Custom" presets are disabled.#* "All" presets are disabled.
disable_presets = "Off"
#* Define presets for the layout of the boxes. Preset 0 is always all boxes shown with default settings. Max 9 presets.
#* Format: "box_name:P:G,box_name:P:G" P=(0 or 1) for alternate positions, G=graph symbol to use for box.
#* Use whitespace " " as separator between different presets.
#* Example: "cpu:0:default,mem:0:tty,proc:1:default cpu:0:braille,proc:0:tty"
presets = "cpu:1:default,proc:0:default cpu:0:default,mem:0:default,net:0:default cpu:0:block,net:0:tty"
#* Set to True to enable "h,j,k,l,g,G" keys for directional control in lists.
#* Conflicting keys for h:"help" and k:"kill" is accessible while holding shift.
vim_keys = false
#* Disable all mouse events.
disable_mouse = false
#* Rounded corners on boxes, is ignored if TTY mode is ON.
rounded_corners = true
#* Use terminal synchronized output sequences to reduce flickering on supported terminals.
terminal_sync = true
#* Default symbols to use for graph creation, "braille", "block" or "tty".
#* "braille" offers the highest resolution but might not be included in all fonts.
#* "block" has half the resolution of braille but uses more common characters.
#* "tty" uses only 3 different symbols but will work with most fonts and should work in a real TTY.
#* Note that "tty" only has half the horizontal resolution of the other two, so will show a shorter historical view.
graph_symbol = "braille"
# Graph symbol to use for graphs in cpu box, "default", "braille", "block" or "tty".
graph_symbol_cpu = "default"
# Graph symbol to use for graphs in gpu box, "default", "braille", "block" or "tty".
graph_symbol_gpu = "default"
# Graph symbol to use for graphs in cpu box, "default", "braille", "block" or "tty".
graph_symbol_mem = "default"
# Graph symbol to use for graphs in cpu box, "default", "braille", "block" or "tty".
graph_symbol_net = "default"
# Graph symbol to use for graphs in cpu box, "default", "braille", "block" or "tty".
graph_symbol_proc = "default"
#* Manually set which boxes to show. Available values are "cpu mem net proc" and "gpu0" through "gpu5", separate values with whitespace.
shown_boxes = "cpu mem net proc"
#* Update time in milliseconds, recommended 2000 ms or above for better sample times for graphs.
update_ms = 2000
#* Processes sorting, "pid" "program" "arguments" "threads" "user" "memory" "cpu lazy" "cpu direct",
#* "cpu lazy" sorts top process over time (easier to follow), "cpu direct" updates top process directly.
proc_sorting = "cpu lazy"
#* Reverse sorting order, True or False.
proc_reversed = false
#* Show processes as a tree.
proc_tree = false
#* Use the cpu graph colors in the process list.
proc_colors = true
#* Use a darkening gradient in the process list.
proc_gradient = true
#* If process cpu usage should be of the core it's running on or usage of the total available cpu power.
proc_per_core = false
#* Show process memory as bytes instead of percent.
proc_mem_bytes = true
#* Show cpu graph for each process.
proc_cpu_graphs = true
#* Use /proc/[pid]/smaps for memory information in the process info box (very slow but more accurate)
proc_info_smaps = false
#* Show proc box on left side of screen instead of right.
proc_left = false
#* (Linux) Filter processes tied to the Linux kernel(similar behavior to htop).
proc_filter_kernel = false
#* Should the process list follow the selected process when detailed view is open.
proc_follow_detailed = true
#* In tree-view, always accumulate child process resources in the parent process.
proc_aggregate = false
#* Should cpu and memory usage display be preserved for dead processes when paused.
keep_dead_proc_usage = false
#* Sets the CPU stat shown in upper half of the CPU graph, "total" is always available.
#* Select from a list of detected attributes from the options menu.
cpu_graph_upper = "Auto"
#* Sets the CPU stat shown in lower half of the CPU graph, "total" is always available.
#* Select from a list of detected attributes from the options menu.
cpu_graph_lower = "Auto"
#* If gpu info should be shown in the cpu box. Available values = "Auto", "On" and "Off".
show_gpu_info = "Auto"
#* Toggles if the lower CPU graph should be inverted.
cpu_invert_lower = true
#* Set to True to completely disable the lower CPU graph.
cpu_single_graph = false
#* Show cpu box at bottom of screen instead of top.
cpu_bottom = false
#* Shows the system uptime in the CPU box.
show_uptime = true
#* Shows the CPU package current power consumption in watts. Requires running `make setcap` or `make setuid` or running with sudo.
show_cpu_watts = true
#* Show cpu temperature.
check_temp = true
#* Which sensor to use for cpu temperature, use options menu to select from list of available sensors.
cpu_sensor = "Auto"
#* Show temperatures for cpu cores also if check_temp is True and sensors has been found.
show_coretemp = true
#* Set a custom mapping between core and coretemp, can be needed on certain cpus to get correct temperature for correct core.
#* Use lm-sensors or similar to see which cores are reporting temperatures on your machine.
#* Format "x:y" x=core with wrong temp, y=core with correct temp, use space as separator between multiple entries.
#* Example: "4:0 5:1 6:3"
cpu_core_map = ""
#* Which temperature scale to use, available values: "celsius", "fahrenheit", "kelvin" and "rankine".
temp_scale = "celsius"
#* Use base 10 for bits/bytes sizes, KB = 1000 instead of KiB = 1024.
base_10_sizes = false
#* Show CPU frequency.
show_cpu_freq = true
#* How to calculate CPU frequency, available values: "first", "range", "lowest", "highest" and "average".
freq_mode = "first"
#* Draw a clock at top of screen, formatting according to strftime, empty string to disable.
#* Special formatting: /host = hostname | /user = username | /uptime = system uptime
clock_format = "%X"
#* Update main ui in background when menus are showing, set this to false if the menus is flickering too much for comfort.
background_update = true
#* Custom cpu model name, empty string to disable.
custom_cpu_name = ""
#* Optional filter for shown disks, should be full path of a mountpoint, separate multiple values with whitespace " ".
#* Only disks matching the filter will be shown. Prepend exclude= to only show disks not matching the filter. Examples: disk_filter="/boot /home/user", disks_filter="exclude=/boot /home/user"
disks_filter = ""
#* Show graphs instead of meters for memory values.
mem_graphs = true
#* Show mem box below net box instead of above.
mem_below_net = false
#* Count ZFS ARC in cached and available memory.
zfs_arc_cached = true
#* If swap memory should be shown in memory box.
show_swap = true
#* Show swap as a disk, ignores show_swap value above, inserts itself after first disk.
swap_disk = true
#* If mem box should be split to also show disks info.
show_disks = true
#* Filter out non physical disks. Set this to False to include network disks, RAM disks and similar.
only_physical = true
#* Read disks list from /etc/fstab. This also disables only_physical.
use_fstab = true
#* Setting this to True will hide all datasets, and only show ZFS pools. (IO stats will be calculated per-pool)
zfs_hide_datasets = false
#* Set to true to show available disk space for privileged users.
disk_free_priv = false
#* Toggles if io activity % (disk busy time) should be shown in regular disk usage view.
show_io_stat = true
#* Toggles io mode for disks, showing big graphs for disk read/write speeds.
io_mode = false
#* Set to True to show combined read/write io graphs in io mode.
io_graph_combined = false
#* Set the top speed for the io graphs in MiB/s (100 by default), use format "mountpoint:speed" separate disks with whitespace " ".
#* Example: "/mnt/media:100 /:20 /boot:1".
io_graph_speeds = ""
#* Swap the positions of the upload and download speed graphs. When true, upload will be on top.
swap_upload_download = false
#* Set fixed values for network graphs in Mebibits. Is only used if net_auto is also set to False.
net_download = 100
net_upload = 100
#* Use network graphs auto rescaling mode, ignores any values set above and rescales down to 10 Kibibytes at the lowest.
net_auto = true
#* Sync the auto scaling for download and upload to whichever currently has the highest scale.
net_sync = true
#* Starts with the Network Interface specified here.
net_iface = ""
#* "True" shows bitrates in base 10 (Kbps, Mbps). "False" shows bitrates in binary sizes (Kibps, Mibps, etc.). "Auto" uses base_10_sizes.
base_10_bitrate = "Auto"
#* Show battery stats in top right if battery is present.
show_battery = true
#* Which battery to use if multiple are present. "Auto" for auto detection.
selected_battery = "Auto"
#* Show power stats of battery next to charge indicator.
show_battery_watts = true
#* Set loglevel for "~/.local/state/btop.log" levels are: "ERROR" "WARNING" "INFO" "DEBUG".
#* The level set includes all lower levels, i.e. "DEBUG" will show all logging info.
log_level = "WARNING"
#* Automatically save current settings to config file on exit.
save_config_on_exit = true
#* Measure PCIe throughput on NVIDIA cards, may impact performance on certain cards.
nvml_measure_pcie_speeds = true
#* Measure PCIe throughput on AMD cards, may impact performance on certain cards.
rsmi_measure_pcie_speeds = true
#* Horizontally mirror the GPU graph.
gpu_mirror_graph = true
#* Set which GPU vendors to show. Available values are "nvidia amd intel apple"
shown_gpus = "nvidia amd intel apple"
#* Custom gpu0 model name, empty string to disable.
custom_gpu_name0 = ""
#* Custom gpu1 model name, empty string to disable.
custom_gpu_name1 = ""
#* Custom gpu2 model name, empty string to disable.
custom_gpu_name2 = ""
#* Custom gpu3 model name, empty string to disable.
custom_gpu_name3 = ""
#* Custom gpu4 model name, empty string to disable.
custom_gpu_name4 = ""
#* Custom gpu5 model name, empty string to disable.
custom_gpu_name5 = ""

View file

@ -0,0 +1,9 @@
; Luz nocturna. Con horas fijas en vez de ubicación: de 20:00 a 21:00 pasa
; poco a poco a luz cálida y de 7:00 a 8:00 vuelve a la normal.
[general]
temp-day=6500
temp-night=4000
fade=1
dusk-time=20:00-21:00
dawn-time=07:00-08:00
adjustment-method=randr

3
home/.gtkrc-2.0 Normal file
View file

@ -0,0 +1,3 @@
# GTK 2 (pinentry-gtk, entre otros). El tema lo instala install.sh (paso gtk).
gtk-theme-name="Everforest-Green-Dark-Medium"
gtk-icon-theme-name="Papirus-Dark"

View file

@ -1,10 +1,15 @@
#!/bin/sh #!/bin/sh
# Menú de apagado con dmenu (Mod+Shift+Escape en dwm). Apagar, reiniciar y # Menú de apagado con dmenu (Mod+Shift+Escape en dwm). Apagar, reiniciar y
# salir de dwm piden confirmación. Suspender, apagar y reiniciar usan doas # salir de dwm piden confirmación. Suspender, apagar y reiniciar usan sudo
# sin contraseña (sistema/etc/doas.conf). # sin contraseña (sistema/etc/sudoers.d/energia).
menu() {
dmenu -i -p "$1" -fn "Fira Code:size=11" \
-nb "#2d353b" -nf "#d3c6aa" -sb "#a7c080" -sf "#2d353b"
}
confirmar() { confirmar() {
[ "$(printf 'No\nSí\n' | menu -p "¿$1?")" = "Sí" ] [ "$(printf 'No\nSí\n' | menu "¿$1?")" = "Sí" ]
} }
opcion=$(printf '%s\n' \ opcion=$(printf '%s\n' \
@ -12,12 +17,12 @@ opcion=$(printf '%s\n' \
"󰤄 Suspender" \ "󰤄 Suspender" \
"󰍃 Salir de dwm" \ "󰍃 Salir de dwm" \
"󰜉 Reiniciar" \ "󰜉 Reiniciar" \
"󰐥 Apagar" | menu -p "Sesión:") "󰐥 Apagar" | menu "Sesión:")
case $opcion in case $opcion in
*Bloquear) slock ;; *Bloquear) slock ;;
*Suspender) doas -n zzz ;; *Suspender) sudo -n zzz ;;
*Salir*) confirmar "Salir de dwm" && pkill -TERM -x dwm ;; *Salir*) confirmar "Salir de dwm" && pkill -TERM -x dwm ;;
*Reiniciar) confirmar "Reiniciar" && doas -n reboot ;; *Reiniciar) confirmar "Reiniciar" && sudo -n reboot ;;
*Apagar) confirmar "Apagar" && doas -n poweroff ;; *Apagar) confirmar "Apagar" && sudo -n poweroff ;;
esac esac

View file

@ -3,7 +3,7 @@
# mientras se descarga, y al 3 % suspende (con slock, como al cerrar la # mientras se descarga, y al 3 % suspende (con slock, como al cerrar la
# tapa) en vez de dejar que se apague de golpe. Cada umbral actúa una vez; # tapa) en vez de dejar que se apague de golpe. Cada umbral actúa una vez;
# al enchufar el cargador se reinicia. Se lanza desde .xinitrc y comprueba # al enchufar el cargador se reinicia. Se lanza desde .xinitrc y comprueba
# cada minuto. Suspender usa "doas -n zzz" (regla en sistema/etc/doas.conf). # cada minuto. Suspender usa "sudo -n zzz" (regla en sistema/etc/sudoers.d).
BAJA=15 BAJA=15
CRITICA=5 CRITICA=5
@ -26,7 +26,7 @@ while :; do
-i battery-empty "Batería agotada" "Queda un $nivel %: suspendiendo en 10 s" -i battery-empty "Batería agotada" "Queda un $nivel %: suspendiendo en 10 s"
avisado=$SUSPENDER avisado=$SUSPENDER
sleep 10 sleep 10
[ "$(cat "$bat/status")" = Discharging ] && doas -n zzz [ "$(cat "$bat/status")" = Discharging ] && sudo -n zzz
elif [ "$nivel" -le "$CRITICA" ] && [ "$avisado" -gt "$CRITICA" ]; then elif [ "$nivel" -le "$CRITICA" ] && [ "$avisado" -gt "$CRITICA" ]; then
notify-send -u critical -h string:x-dunst-stack-tag:bateria \ notify-send -u critical -h string:x-dunst-stack-tag:bateria \
-i battery-empty "Batería crítica" "Queda un $nivel %: enchufa el cargador ya" -i battery-empty "Batería crítica" "Queda un $nivel %: enchufa el cargador ya"

View file

@ -1,70 +0,0 @@
#!/bin/sh
# Menú de bluetooth con dmenu (clic izquierdo en BT de la barra): conectar o
# desconectar los dispositivos emparejados (󰂱 = conectado), buscar y
# emparejar uno nuevo y apagar el adaptador. Si está apagado, ofrece
# encenderlo.
avisar() {
notify-send -h string:x-dunst-stack-tag:bluetooth -i bluetooth "Bluetooth" "$1"
}
# "Device AA:BB:CC:DD:EE:FF Nombre" -> "Nombre (AA:BB:CC:DD:EE:FF)"
lista() { sed -n 's/^Device \([^ ]*\) \(.*\)/\2 (\1)/p'; }
mac() { printf '%s\n' "$1" | sed 's/.*(\([^)]*\))$/\1/'; }
if ! bluetoothctl show | grep -q 'Powered: yes'; then
[ "$(echo Encender | menu -p Bluetooth:)" = Encender ] || exit 0
bluetoothctl power on >/dev/null
pkill -USR1 -x slstatus
fi
conectados=$(bluetoothctl devices Connected | lista)
emparejados=$(bluetoothctl devices Paired | lista)
opcion=$(
printf '%s\n' "$emparejados" | while IFS= read -r d; do
[ -n "$d" ] || continue
if printf '%s\n' "$conectados" | grep -qxF "$d"; then
echo "󰂱 $d"
else
echo " $d"
fi
done
echo "󰍉 Buscar dispositivos"
echo "󰂲 Apagar"
)
opcion=$(printf '%s\n' "$opcion" | menu -p Bluetooth:)
case $opcion in
'') exit 0 ;;
*" Apagar")
bluetoothctl power off >/dev/null
;;
*" Buscar dispositivos")
avisar "Buscando dispositivos durante 10 s..."
bluetoothctl --timeout 10 scan on >/dev/null
nuevo=$(bluetoothctl devices | lista | awk -v e="$emparejados" '
BEGIN { n = split(e, a, "\n"); for (i = 1; i <= n; i++) visto[a[i]] }
!($0 in visto)' | menu -p Emparejar:)
[ -n "$nuevo" ] || exit 0
m=$(mac "$nuevo")
if bluetoothctl pair "$m" >/dev/null && bluetoothctl trust "$m" >/dev/null &&
bluetoothctl connect "$m" >/dev/null; then
avisar "Conectado: $nuevo"
else
avisar "No se pudo emparejar: $nuevo"
fi
;;
"󰂱 "*)
bluetoothctl disconnect "$(mac "$opcion")" >/dev/null &&
avisar "Desconectado: ${opcion#"󰂱 "}"
;;
*)
if bluetoothctl connect "$(mac "$opcion")" >/dev/null; then
avisar "Conectado: ${opcion#" "}"
else
avisar "No se pudo conectar: ${opcion#" "}"
fi
;;
esac
pkill -USR1 -x slstatus

View file

@ -1,22 +0,0 @@
#!/bin/sh
# Luz nocturna con sct: de 20:00 a 21:00 pasa poco a poco a luz cálida y de
# 7:00 a 8:00 vuelve a la normal. Se lanza desde .xinitrc y la ajusta cada
# minuto, así que también vuelve sola si xrandr la reinicia.
DIA=6500
NOCHE=4000
while :; do
m=$(($(date +%-H) * 60 + $(date +%-M)))
if [ "$m" -lt 420 ] || [ "$m" -ge 1260 ]; then
t=$NOCHE
elif [ "$m" -lt 480 ]; then
t=$((NOCHE + (DIA - NOCHE) * (m - 420) / 60))
elif [ "$m" -lt 1200 ]; then
t=$DIA
else
t=$((DIA - (DIA - NOCHE) * (m - 1200) / 60))
fi
sct "$t"
sleep 60
done

View file

@ -1,5 +0,0 @@
#!/bin/sh
# dmenu con la fuente y los colores de dwm, para los scripts de ~/.local/bin.
# Uso: menu [opciones de dmenu] (las que se pasen mandan sobre estas)
exec dmenu -i -fn "Fira Code:size=11" \
-nb "#2d353b" -nf "#d3c6aa" -sb "#a7c080" -sf "#2d353b" "$@"

View file

@ -1,8 +0,0 @@
#!/bin/sh
# pinentry de gpg-agent: pinentry-dmenu en X y pinentry-curses en una tty.
# Los colores de pinentry-dmenu están en ~/.gnupg/pinentry-dmenu.conf
# (lo escribe install.sh, paso gnupg).
if [ -n "$DISPLAY" ]; then
exec pinentry-dmenu "$@"
fi
exec pinentry-curses "$@"

View file

@ -1,31 +1,14 @@
#!/bin/sh #!/bin/sh
# Cambia el volumen o silencia la salida o el micro (PipeWire), refresca # Cambia el volumen o silencia la salida o el micro (PipeWire), refresca
# slstatus y lo muestra en una notificación que se sustituye a sí misma. # slstatus y lo muestra en una notificación que se sustituye a sí misma.
# "salida" elige con dmenu por dónde suena (altavoces, cascos...). # Uso: volumen subir|bajar|silenciar|micro
# Uso: volumen subir|bajar|silenciar|micro|salida
case $1 in case $1 in
subir) wpctl set-volume -l 1.0 @DEFAULT_AUDIO_SINK@ 5%+ ;; subir) wpctl set-volume -l 1.0 @DEFAULT_AUDIO_SINK@ 5%+ ;;
bajar) wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%- ;; bajar) wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%- ;;
silenciar) wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle ;; silenciar) wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle ;;
micro) wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle ;; micro) wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle ;;
salida) *) echo "uso: volumen subir|bajar|silenciar|micro" >&2; exit 1 ;;
# Las salidas de "wpctl status" (sección Sinks de Audio), con * la actual:
# " │ * 86. Nombre [vol: 0.50]" -> "* 86. Nombre"
s=$(wpctl status | awk '
/Sinks:/ { dentro = 1; next }
dentro && !/[0-9]\./ { exit }
dentro {
sub(/^[^*0-9]*/, ""); actual = sub(/^\* */, "")
sub(/ *\[vol:.*/, ""); print (actual ? "* " : " ") $0
}' | menu -p Salida:)
[ -n "$s" ] || exit 0
s=${s#??}
wpctl set-default "${s%%.*}"
exec notify-send -t 2000 -h string:x-dunst-stack-tag:volumen \
-i audio-speakers "Salida de audio" "${s#*. }"
;;
*) echo "uso: volumen subir|bajar|silenciar|micro|salida" >&2; exit 1 ;;
esac esac
pkill -USR1 -x slstatus pkill -USR1 -x slstatus

View file

@ -1,73 +0,0 @@
#!/bin/sh
# Menú de WiFi con dmenu y wpa_cli (clic izquierdo en la red de la barra).
# Busca redes y las ordena por señal; * marca la actual. Si la elegida ya está
# guardada se conecta; si no, pide la contraseña (no se ve al escribirla) y la
# guarda en /etc/wpa_supplicant/wpa_supplicant.conf cuando la conexión va bien.
# wpa_cli funciona sin root para los de wheel (ctrl_interface_group, lo pone
# install.sh en el paso sistema).
avisar() {
notify-send -h string:x-dunst-stack-tag:wifi -i network-wireless "WiFi" "$1"
}
IF=
for w in /sys/class/net/*/wireless; do
[ -e "$w" ] && IF=${w%/wireless} && IF=${IF##*/} && break
done
[ -n "$IF" ] || { avisar "No hay tarjeta WiFi"; exit 1; }
wpa() { wpa_cli -i "$IF" "$@"; }
wpa scan >/dev/null || { avisar "wpa_supplicant no responde"; exit 1; }
sleep 3
actual=$(wpa status | sed -n 's/^ssid=//p')
# scan_results: bssid, frecuencia, señal, flags y ssid, separados por tabuladores
resultados=$(wpa scan_results | tail -n +2)
ssid=$(printf '%s\n' "$resultados" | sort -t "$(printf '\t')" -k3,3nr |
awk -F '\t' -v a="$actual" '$5 != "" && !visto[$5]++ {
print ($5 == a ? "* " : " ") $5
}' | menu -l 15 -p WiFi:)
[ -n "$ssid" ] || exit 0
ssid=${ssid#??}
id=$(wpa list_networks | awk -F '\t' -v s="$ssid" 'NR > 1 && $2 == s { print $1; exit }')
nueva=
if [ -z "$id" ]; then
nueva=1
id=$(wpa add_network | tail -1)
wpa set_network "$id" ssid "\"$ssid\"" >/dev/null
flags=$(printf '%s\n' "$resultados" | awk -F '\t' -v s="$ssid" '$5 == s { print $4; exit }')
case $flags in
*WPA* | *RSN* | *SAE*)
clave=$(menu -p "Contraseña de $ssid:" -nf "#2d353b" </dev/null)
if [ -z "$clave" ]; then
wpa remove_network "$id" >/dev/null
exit 0
fi
wpa set_network "$id" psk "\"$clave\"" >/dev/null
;;
*) wpa set_network "$id" key_mgmt NONE >/dev/null ;;
esac
fi
avisar "Conectando a $ssid..."
wpa select_network "$id" >/dev/null
i=0
while [ "$i" -lt 20 ] && ! wpa status | grep -qx wpa_state=COMPLETED; do
sleep 1
i=$((i + 1))
done
# select_network deshabilita las demás redes: se vuelven a habilitar para que
# siga cambiando sola a la que haya.
if wpa status | grep -qx wpa_state=COMPLETED; then
wpa enable_network all >/dev/null
wpa save_config >/dev/null
avisar "Conectado a $ssid"
else
[ -n "$nueva" ] && wpa remove_network "$id" >/dev/null
wpa enable_network all >/dev/null
avisar "No se pudo conectar a $ssid"
fi
pkill -USR1 -x slstatus

View file

@ -1,6 +1,6 @@
#!/bin/sh #!/bin/sh
# turnstile ya crea XDG_RUNTIME_DIR (/run/user/UID); esto es solo por si falta. # elogind ya crea XDG_RUNTIME_DIR (/run/user/UID); esto es solo por si falta.
if [ -z "$XDG_RUNTIME_DIR" ]; then if [ -z "$XDG_RUNTIME_DIR" ]; then
export XDG_RUNTIME_DIR=/tmp/$(id -u)-runtime-dir export XDG_RUNTIME_DIR=/tmp/$(id -u)-runtime-dir
mkdir -p "$XDG_RUNTIME_DIR" mkdir -p "$XDG_RUNTIME_DIR"
@ -8,7 +8,7 @@ if [ -z "$XDG_RUNTIME_DIR" ]; then
fi fi
# Abrir el bus de sesión D-Bus antes de lanzar nada, para que pipewire, # Abrir el bus de sesión D-Bus antes de lanzar nada, para que pipewire,
# wireplumber, dunst... y dwm compartan el mismo bus. # wireplumber, dunst, blueman... y dwm compartan el mismo bus.
if [ -z "$DBUS_SESSION_BUS_ADDRESS" ]; then if [ -z "$DBUS_SESSION_BUS_ADDRESS" ]; then
exec dbus-run-session -- sh "$HOME/.xinitrc" exec dbus-run-session -- sh "$HOME/.xinitrc"
fi fi
@ -17,11 +17,13 @@ fi
# qt6ct también responde a "qt5ct", así que vale para Qt 5 y Qt 6. # qt6ct también responde a "qt5ct", así que vale para Qt 5 y Qt 6.
export QT_QPA_PLATFORMTHEME=qt5ct export QT_QPA_PLATFORMTHEME=qt5ct
# Teclado y pantallas primero. pantallas (sistema/usr/local/bin) las pone en # Teclado y monitores primero; el fondo se pinta después con la geometría final.
# fila, con la del portátil a la izquierda, y pinta el fondo; al conectar o # autorandr pone las pantallas conectadas en fila (la del portátil a la
# desconectar una, lo repite solo (regla de udev en sistema/). # izquierda); al conectar o desconectar una, lo repite solo (regla de udev en
# sistema/) y vuelve a pintar el fondo (~/.config/autorandr/postswitch).
setxkbmap es setxkbmap es
pantallas autorandr --change --default horizontal
feh --no-fehbg --bg-fill "$HOME/.local/share/wallpaper.jpg" &
pipewire & pipewire &
wireplumber & wireplumber &
@ -29,9 +31,10 @@ pipewire-pulse &
dunst & dunst &
picom & picom &
blueman-applet &
slstatus & slstatus &
clipmenud & clipmenud &
luz & gammastep &
bateria & bateria &
marcadores & marcadores &

View file

@ -2,10 +2,9 @@
# Deja un Void Linux recién instalado con este escritorio: paquetes, programas # Deja un Void Linux recién instalado con este escritorio: paquetes, programas
# de suckless, enlaces de la configuración en ~ y archivos de sistema. # de suckless, enlaces de la configuración en ~ y archivos de sistema.
# #
# Uso: ./install.sh [paquetes] [suckless] [enlaces] [gtk] [gnupg] [sistema] [quitar] # Uso: ./install.sh [paquetes] [suckless] [enlaces] [gtk] [gnupg] [sistema]
# Sin argumentos hace los siete pasos, en ese orden. Se ejecuta como el # Sin argumentos hace los seis pasos, en ese orden. Se ejecuta como el
# usuario normal; pide la contraseña de root (doas, o sudo en un Void recién # usuario normal; pide sudo cuando hace falta. Se puede repetir sin problema.
# instalado) cuando hace falta. Se puede repetir sin problema.
set -eu set -eu
@ -17,16 +16,16 @@ PAQUETES="
libXfixes-devel libxcb-devel freetype-devel fontconfig-devel harfbuzz-devel libXfixes-devel libxcb-devel freetype-devel fontconfig-devel harfbuzz-devel
libXrender-devel xorgproto imlib2-devel zlib-devel libxcrypt-devel libXrender-devel xorgproto imlib2-devel zlib-devel libxcrypt-devel
xorg xinit setxkbmap xrandr dbus turnstile xorg xinit setxkbmap xrandr dbus elogind polkit
picom dunst libnotify xwallpaper nsxiv maim xclip sct xss-lock picom dunst libnotify feh maim xclip gammastep xss-lock autorandr
pipewire wireplumber libspa-bluetooth alsa-pipewire pipewire wireplumber libspa-bluetooth alsa-pipewire rtkit pavucontrol
wpa_supplicant dhcpcd bluez acpid chrony tlp NetworkManager bluez blueman acpid chrony tlp tlp-rdw
cups cups-filters hplip cups cups-filters hplip
font-firacode nerd-fonts-symbols-ttf papirus-icon-theme papirus-folders font-firacode nerd-fonts-symbols-ttf papirus-icon-theme papirus-folders
sassc gnome-themes-extra qt5ct qt6ct sassc gtk-engine-murrine gnome-themes-extra qt5ct qt6ct
opendoas gnupg pinentry-dmenu gnupg pinentry-gtk
firefox thunderbird mpv neovim git fuse-sshfs unzip firefox thunderbird neovim git fuse-sshfs unzip
yazi file ffmpeg 7zip jq poppler fd ripgrep fzf zoxide resvg ImageMagick yazi file ffmpeg 7zip jq poppler fd ripgrep fzf zoxide resvg ImageMagick
" "
@ -34,43 +33,19 @@ SUCKLESS="dwm st dmenu slstatus slock scroll clipmenu"
# Tema GTK Everforest, en una versión fija para que siempre salga igual # Tema GTK Everforest, en una versión fija para que siempre salga igual
GTK_TEMA_REPO=https://github.com/Fausto-Korpsvart/Everforest-GTK-Theme GTK_TEMA_REPO=https://github.com/Fausto-Korpsvart/Everforest-GTK-Theme
GTK_TEMA_COMMIT=9b8be4d6648ae9eaae3dd550105081f8c9054825 GTK_TEMA_COMMIT=9b8be4d6648ae9eaae3dd550105081f8c9054825
SERVICIOS="dbus turnstiled wpa_supplicant dhcpcd bluetoothd acpid chronyd tlp automontaje cupsd" SERVICIOS="dbus elogind polkitd NetworkManager bluetoothd acpid chronyd tlp automontaje cupsd"
# La red la llevan wpa_supplicant y dhcpcd. polkitd no hace falta como # NetworkManager gestiona la red él solo; estos servicios se pelean con él.
# servicio: si algo lo pide (udisks2, libvirt), D-Bus lo arranca. turnstiled SERVICIOS_FUERA="dhcpcd wpa_supplicant"
# sustituye a elogind. GRUPOS="audio video input network bluetooth lpadmin"
SERVICIOS_FUERA="NetworkManager polkitd elogind"
# _pipewire da prioridad de tiempo real al audio sin rtkit
# (/etc/security/limits.d/25-pw-rlimits.conf, de pipewire).
GRUPOS="audio video input network bluetooth lpadmin _pipewire"
# Lo que sustituyen otras cosas del repo: sudo (doas), feh (xwallpaper y
# nsxiv), gammastep (sct), autorandr (pantallas), blueman y pavucontrol
# (scripts bluetooth y volumen), pinentry-gtk (pinentry-dmenu), vlc (mpv),
# NetworkManager (wpa_supplicant, dhcpcd y el script wifi), rtkit (el grupo
# _pipewire) y elogind (turnstile; Xorg arranca como root con Xorg.wrap y la
# tapa y los botones ya los lleva acpid).
QUITAR="
sudo feh gammastep autorandr blueman pavucontrol pinentry-gtk
gtk-engine-murrine vlc btop NetworkManager tlp-rdw rtkit elogind
"
msg() { printf '\033[1;32m==>\033[0m %s\n' "$*"; } msg() { printf '\033[1;32m==>\033[0m %s\n' "$*"; }
die() { printf '\033[1;31merror:\033[0m %s\n' "$*" >&2; exit 1; } die() { printf '\033[1;31merror:\033[0m %s\n' "$*" >&2; exit 1; }
# Como root: con doas cuando ya está configurado; antes (Void recién
# instalado) con sudo.
root() {
if command -v doas >/dev/null && [ -f /etc/doas.conf ]; then
doas "$@"
else
sudo "$@"
fi
}
paquetes() { paquetes() {
msg "Instalando paquetes" msg "Instalando paquetes"
root xbps-install -Syu xbps sudo xbps-install -Syu xbps
# shellcheck disable=SC2086 # shellcheck disable=SC2086
root xbps-install -Syu $PAQUETES sudo xbps-install -Syu $PAQUETES
} }
suckless() { suckless() {
@ -78,7 +53,7 @@ suckless() {
msg "Compilando $p" msg "Compilando $p"
make -C "$DIR/suckless/$p" clean >/dev/null make -C "$DIR/suckless/$p" clean >/dev/null
make -C "$DIR/suckless/$p" make -C "$DIR/suckless/$p"
root make -C "$DIR/suckless/$p" install sudo make -C "$DIR/suckless/$p" install
done done
} }
@ -104,14 +79,6 @@ enlaces() {
done done
cd "$DIR" cd "$DIR"
# Los enlaces a archivos que ya no están en home/ (borrados del repo)
find "$HOME" -xdev -type l -lname "$DIR/home/*" ! -exec test -e {} \; -print |
while read -r l; do
rm "$l"
rmdir "$(dirname "$l")" 2>/dev/null || true
echo " ${l#"$HOME"/} (ya no está en el repo: quitado)"
done
# Las carpetas de home/.config/user-dirs.dirs (y la de las capturas) # Las carpetas de home/.config/user-dirs.dirs (y la de las capturas)
mkdir -p "$HOME/Documents" "$HOME/Downloads" "$HOME/Images/Screenshots" mkdir -p "$HOME/Documents" "$HOME/Downloads" "$HOME/Images/Screenshots"
# ssh no quiere ~/.ssh accesible para otros # ssh no quiere ~/.ssh accesible para otros
@ -119,10 +86,10 @@ enlaces() {
} }
# Compila el tema GTK Everforest (verde, oscuro, paleta medium) en ~/.themes # Compila el tema GTK Everforest (verde, oscuro, paleta medium) en ~/.themes
# y lo enlaza para las apps de GTK 4. Qué tema e iconos se usan lo dice # y lo enlaza para las apps de GTK 4. Qué tema e iconos se usan lo dicen
# home/.config/gtk-*/settings.ini. Las carpetas de Papirus se ponen verdes; # home/.gtkrc-2.0 y home/.config/gtk-*/settings.ini. Las carpetas de Papirus
# una actualización de papirus-icon-theme las devuelve a azul, y basta con # se ponen verdes; una actualización de papirus-icon-theme las devuelve a
# repetir este paso. # azul, y basta con repetir este paso.
gtk() { gtk() {
msg "Compilando el tema GTK Everforest" msg "Compilando el tema GTK Everforest"
tmp=$(mktemp -d) tmp=$(mktemp -d)
@ -131,14 +98,25 @@ gtk() {
"$tmp/themes/install.sh" -t green -c dark --tweaks medium -l >/dev/null "$tmp/themes/install.sh" -t green -c dark --tweaks medium -l >/dev/null
rm -rf "$tmp" rm -rf "$tmp"
# La plantilla de GTK 2 del tema trae los colores de Gruvbox (fallo del
# tema original): se cambian por Everforest medium. pinentry-gtk es GTK 2.
sed -i \
-e 's|^gtk-color-scheme = "text_color:.*|gtk-color-scheme = "text_color:#d3c6aa\\nbase_color:#2d353b"|' \
-e 's|^gtk-color-scheme = "fg_color:.*|gtk-color-scheme = "fg_color:#d3c6aa\\nbg_color:#2d353b"|' \
-e 's|^gtk-color-scheme = "selected_fg_color:.*|gtk-color-scheme = "selected_fg_color:#2d353b\\nselected_bg_color:#a7c080"|' \
-e 's|^gtk-color-scheme = "titlebar_fg_color:.*|gtk-color-scheme = "titlebar_fg_color:#d3c6aa\\ntitlebar_bg_color:#2d353b"|' \
-e 's|^gtk-color-scheme = "menu_color:.*|gtk-color-scheme = "menu_color:#343f44"|' \
-e 's|^gtk-color-scheme = "tooltip_fg_color:.*|gtk-color-scheme = "tooltip_fg_color:#d3c6aa\\ntooltip_bg_color:#3d484d"|' \
-e 's|^gtk-color-scheme = "link_color:.*|gtk-color-scheme = "link_color:#7fbbb3\\nvisited_link_color:#d699b6"|' \
"$HOME/.themes/Everforest-Green-Dark-Medium/gtk-2.0/gtkrc"
msg "Carpetas de Papirus en verde" msg "Carpetas de Papirus en verde"
root papirus-folders -C green --theme Papirus-Dark >/dev/null sudo papirus-folders -C green --theme Papirus-Dark >/dev/null
} }
# ~/.gnupg se copia a mano (de un USB, por ejemplo). Deja los permisos como # ~/.gnupg se copia a mano (de un USB, por ejemplo). Deja los permisos como
# los quiere gpg, usa pinentry-dmenu (en una tty, pinentry-curses; lo decide # los quiere gpg, usa un pinentry gráfico (en una tty cae a curses solo) y
# home/.local/bin/pinentry-menu) y activa el agente SSH con las claves de # activa el agente SSH con las claves de autenticación.
# autenticación.
gnupg() { gnupg() {
g="$HOME/.gnupg" g="$HOME/.gnupg"
if [ ! -d "$g" ]; then if [ ! -d "$g" ]; then
@ -147,37 +125,21 @@ gnupg() {
fi fi
msg "Arreglando permisos de $g" msg "Arreglando permisos de $g"
root chown -R "$(id -u):$(id -g)" "$g" sudo chown -R "$(id -u):$(id -g)" "$g"
find "$g" -type d -exec chmod 700 {} + find "$g" -type d -exec chmod 700 {} +
find "$g" -type f -exec chmod 600 {} + find "$g" -type f -exec chmod 600 {} +
msg "Configurando gpg-agent (pinentry-dmenu y SSH)" msg "Configurando gpg-agent (pinentry gráfico y SSH)"
conf="$g/gpg-agent.conf" conf="$g/gpg-agent.conf"
touch "$conf" touch "$conf"
chmod 600 "$conf" chmod 600 "$conf"
sed -i '/^pinentry-program/d; /^default-cache-ttl/d' "$conf" sed -i '/^pinentry-program/d; /^default-cache-ttl/d' "$conf"
echo "pinentry-program $HOME/.local/bin/pinentry-menu" >>"$conf" echo "pinentry-program /usr/bin/pinentry-gtk-2" >>"$conf"
grep -qx enable-ssh-support "$conf" || echo enable-ssh-support >>"$conf" grep -qx enable-ssh-support "$conf" || echo enable-ssh-support >>"$conf"
# Recordar la contraseña una hora desde el último uso (por defecto, 10 min) # Recordar la contraseña una hora desde el último uso (por defecto, 10 min)
echo "default-cache-ttl 3600" >>"$conf" echo "default-cache-ttl 3600" >>"$conf"
echo "default-cache-ttl-ssh 3600" >>"$conf" echo "default-cache-ttl-ssh 3600" >>"$conf"
# pinentry-dmenu con la fuente y los colores de dmenu
cat >"$g/pinentry-dmenu.conf" <<-EOF
asterisk = "*";
prompt = "Contraseña:";
font = "Fira Code:size=11";
prompt_bg = "#a7c080";
prompt_fg = "#2d353b";
normal_bg = "#2d353b";
normal_fg = "#d3c6aa";
select_bg = "#a7c080";
select_fg = "#2d353b";
desc_bg = "#2d353b";
desc_fg = "#d3c6aa";
EOF
chmod 600 "$g/pinentry-dmenu.conf"
# sshcontrol dice qué claves usa el agente para SSH: se añaden las # sshcontrol dice qué claves usa el agente para SSH: se añaden las
# subclaves de autenticación [A] que falten. # subclaves de autenticación [A] que falten.
touch "$g/sshcontrol" touch "$g/sshcontrol"
@ -201,79 +163,47 @@ sistema() {
find . -type f | while read -r f; do find . -type f | while read -r f; do
f=${f#.} f=${f#.}
case $f in case $f in
/etc/doas.conf) /etc/sudoers.d/*)
# Un doas.conf roto deja sin root: se valida antes de copiarlo. # git no guarda el modo 440 que exige sudo; y un sudoers
doas -C ".$f" || die "doas.conf inválido" # roto deja sin sudo, así que se valida antes de copiarlo.
root install -D -m 400 ".$f" "$f" visudo -cf ".$f" >/dev/null || die "sudoers inválido: $f"
sudo install -D -m 440 ".$f" "$f"
;; ;;
*) root install -D -m "$(stat -c %a ".$f")" ".$f" "$f" ;; *) sudo install -D -m "$(stat -c %a ".$f")" ".$f" "$f" ;;
esac esac
echo " $f" echo " $f"
done done
cd "$DIR" cd "$DIR"
# wpa_cli sin root para los de wheel (script wifi) y guardar las redes
# nuevas. El archivo tiene las contraseñas: se edita en su sitio.
msg "Configurando wpa_supplicant"
w=/etc/wpa_supplicant/wpa_supplicant.conf
cabecera="ctrl_interface=/run/wpa_supplicant
ctrl_interface_group=wheel
update_config=1"
# shellcheck disable=SC2016
root sh -c 'umask 077; touch "$1"
{ printf "%s\n" "$2"; grep -v -e "^ctrl_interface" -e "^update_config" "$1"; } >"$1.nuevo"
mv "$1.nuevo" "$1"' sh "$w" "$cabecera"
msg "Activando servicios" msg "Activando servicios"
for s in $SERVICIOS; do for s in $SERVICIOS; do
[ -d "/etc/sv/$s" ] || die "no existe el servicio $s (¿faltan paquetes?)" [ -d "/etc/sv/$s" ] || die "no existe el servicio $s (¿faltan paquetes?)"
if [ ! -e "/var/service/$s" ]; then if [ ! -e "/var/service/$s" ]; then
root ln -s "/etc/sv/$s" /var/service/ sudo ln -s "/etc/sv/$s" /var/service/
fi fi
done done
for s in $SERVICIOS_FUERA; do for s in $SERVICIOS_FUERA; do
if [ -e "/var/service/$s" ]; then if [ -e "/var/service/$s" ]; then
root rm "/var/service/$s" sudo rm "/var/service/$s"
fi fi
done done
msg "Añadiendo $USER a los grupos: $GRUPOS" msg "Añadiendo $USER a los grupos: $GRUPOS"
for g in $GRUPOS; do for g in $GRUPOS; do
if getent group "$g" >/dev/null; then if getent group "$g" >/dev/null; then
root usermod -aG "$g" "$USER" sudo usermod -aG "$g" "$USER"
fi fi
done done
} }
# Desinstala lo que el repo ya no usa (QUITAR), si está instalado. sudo solo
# se quita cuando doas ya funciona (paso sistema).
quitar() {
[ -f /etc/doas.conf ] || die "falta /etc/doas.conf: ejecuta antes el paso sistema"
fuera=
for p in $QUITAR; do
xbps-query "$p" >/dev/null 2>&1 && fuera="$fuera $p"
done
if [ -z "$fuera" ]; then
return 0
fi
msg "Quitando:$fuera"
# shellcheck disable=SC2086
root xbps-remove -Ry $fuera
# Lo que puso aquí una versión anterior de sistema/ para elogind
if [ -e /etc/elogind/logind.conf.d/10-acpid.conf ]; then
root rm /etc/elogind/logind.conf.d/10-acpid.conf
fi
}
[ -f /etc/void-release ] || command -v xbps-install >/dev/null || [ -f /etc/void-release ] || command -v xbps-install >/dev/null ||
die "esto es solo para Void Linux" die "esto es solo para Void Linux"
[ "$(id -u)" -ne 0 ] || die "ejecútalo como tu usuario, no como root" [ "$(id -u)" -ne 0 ] || die "ejecútalo como tu usuario, no como root"
[ $# -gt 0 ] || set -- paquetes suckless enlaces gtk gnupg sistema quitar [ $# -gt 0 ] || set -- paquetes suckless enlaces gtk gnupg sistema
for paso; do for paso; do
case $paso in case $paso in
paquetes|suckless|enlaces|gtk|gnupg|sistema|quitar) "$paso" ;; paquetes|suckless|enlaces|gtk|gnupg|sistema) "$paso" ;;
*) die "paso desconocido: $paso" ;; *) die "paso desconocido: $paso" ;;
esac esac
done done

View file

@ -1,8 +0,0 @@
# doas en vez de sudo. Los de wheel pueden hacer de root con su contraseña,
# que se recuerda unos minutos. Suspender, apagar y reiniciar (sin
# argumentos) no la piden: los usan bateria y apagado (home/.local/bin).
# Vale la última regla que coincide.
permit persist :wheel
permit nopass :wheel as root cmd zzz args
permit nopass :wheel as root cmd poweroff args
permit nopass :wheel as root cmd reboot args

View file

@ -0,0 +1,11 @@
# acpid ya se encarga de la tapa y del botón de suspender (llama a zzz) y del
# botón de encendido. Si elogind también reacciona, el portátil se suspende
# dos veces: al abrir la tapa se enciende, se vuelve a suspender y luego
# arranca. Así solo lo gestiona acpid.
[Login]
HandlePowerKey=ignore
HandleSuspendKey=ignore
HandleHibernateKey=ignore
HandleLidSwitch=ignore
HandleLidSwitchExternalPower=ignore
HandleLidSwitchDocked=ignore

View file

@ -0,0 +1,4 @@
# Suspender, apagar y reiniciar sin contraseña para los de wheel (solo esos
# comandos y sin argumentos). Los usan el script bateria (suspender al
# agotarse) y el menú de apagado (home/.local/bin/apagado).
%wheel ALL=(root) NOPASSWD: /usr/bin/zzz "", /usr/bin/poweroff "", /usr/bin/reboot ""

View file

@ -1,7 +0,0 @@
# turnstile en vez de elogind, solo para crear /run/user/UID
# (XDG_RUNTIME_DIR) al entrar. Sin gestor de servicios de usuario: lo de la
# sesión lo arranca .xinitrc. Tampoco exporta DBUS_SESSION_BUS_ADDRESS,
# porque el bus lo abre .xinitrc con dbus-run-session.
backend = none
manage_rundir = yes
export_dbus_address = no

View file

@ -1,3 +1,4 @@
# Al conectar o desconectar una pantalla, colocarlas todas en fila y repintar # Sustituye a la regla de autorandr (/usr/lib/udev/rules.d): al conectar o
# el fondo (sistema/usr/local/bin/pantallas). # desconectar una pantalla, colocarlas todas en fila ("horizontal") en vez
ACTION=="change", SUBSYSTEM=="drm", RUN+="/usr/local/bin/pantallas" # de buscar un perfil guardado llamado "default".
ACTION=="change", SUBSYSTEM=="drm", RUN+="/usr/bin/autorandr --batch --change --default horizontal"

View file

@ -1,2 +0,0 @@
# base-system depende de sudo; así se puede quitar (se usa doas).
ignorepkg=sudo

View file

@ -1,39 +0,0 @@
#!/bin/sh
# Pone en fila todas las pantallas conectadas, con la del portátil
# (eDP*/LVDS*) a la izquierda y como principal, apaga las desconectadas y
# vuelve a pintar el fondo. Lo lanzan .xinitrc al arrancar y la regla de udev
# (sistema/etc/udev/rules.d) al conectar o desconectar una pantalla.
#
# udev lo ejecuta como root: entonces se relanza como el usuario de la sesión
# de dwm, con su DISPLAY.
if [ "$(id -u)" -eq 0 ]; then
pid=$(pgrep -xo dwm) || exit 0
usuario=$(stat -c %U "/proc/$pid")
casa=$(getent passwd "$usuario" | cut -d: -f6)
entorno=$(tr '\0' '\n' <"/proc/$pid/environ" | grep -E '^(DISPLAY|XAUTHORITY)=')
# shellcheck disable=SC2086
exec env $entorno HOME="$casa" chpst -u "$usuario" "$0"
fi
estado=$(xrandr) || exit 1
interna=$(echo "$estado" | awk '/^(eDP|LVDS)[^ ]* connected/ { print $1 }')
otras=$(echo "$estado" | awk '/ connected/ && $1 !~ /^(eDP|LVDS)/ { print $1 }')
fuera=$(echo "$estado" | awk '/ disconnected/ { print $1 }')
set --
ant=
for o in $interna $otras; do
if [ -z "$ant" ]; then
set -- "$@" --output "$o" --auto --primary --pos 0x0
else
set -- "$@" --output "$o" --auto --right-of "$ant"
fi
ant=$o
done
for o in $fuera; do
set -- "$@" --output "$o" --off
done
[ $# -gt 0 ] && xrandr "$@"
xwallpaper --zoom "$HOME/.local/share/wallpaper.jpg"

View file

@ -38,8 +38,11 @@ static const Rule rules[] = {
* hasta que se cierra; noswallow = 1 lo evita para esa ventana. */ * hasta que se cierra; noswallow = 1 lo evita para esa ventana. */
/* class instance title tags mask isfloating isterminal noswallow monitor */ /* class instance title tags mask isfloating isterminal noswallow monitor */
{ "st-256color", NULL, NULL, 0, 0, 1, 0, -1 }, { "st-256color", NULL, NULL, 0, 0, 1, 0, -1 },
{ "st-float", NULL, NULL, 0, 1, 0, 1, -1 }, /* st -c st-float (p. ej. wpa_cli) */ { "st-float", NULL, NULL, 0, 1, 0, 1, -1 }, /* st -c st-float (p. ej. nmtui) */
{ "Gimp", NULL, NULL, 0, 1, 0, 0, -1 }, { "Gimp", NULL, NULL, 0, 1, 0, 0, -1 },
{ NULL, "pavucontrol", NULL, 0, 1, 0, 0, -1 },
{ NULL, "blueman-manager", NULL, 0, 1, 0, 0, -1 },
{ "Pinentry-gtk-2", NULL, NULL, 0, 1, 0, 1, -1 }, /* contraseña de gpg/ssh */
{ "Firefox", "Places", NULL, 0, 1, 0, 0, -1 }, /* biblioteca/descargas */ { "Firefox", "Places", NULL, 0, 1, 0, 0, -1 }, /* biblioteca/descargas */
{ "Firefox", "Toolkit", NULL, 0, 1, 0, 0, -1 }, /* picture-in-picture */ { "Firefox", "Toolkit", NULL, 0, 1, 0, 0, -1 }, /* picture-in-picture */
{ NULL, NULL, "Event Tester", 0, 0, 0, 1, -1 }, /* xev */ { NULL, NULL, "Event Tester", 0, 0, 0, 1, -1 }, /* xev */
@ -96,22 +99,22 @@ static const char *lockcmd[] = { "slock", NULL };
* (1 izquierdo, 2 central, 3 derecho, 4/5 rueda arriba/abajo). * (1 izquierdo, 2 central, 3 derecho, 4/5 rueda arriba/abajo).
*/ */
static const StatusCmd statuscmds[] = { static const StatusCmd statuscmds[] = {
/* red: izquierdo conectarse a una red (script wifi), derecho wpa_cli */ /* red: izquierdo conectarse a una red, derecho el menú completo de nmtui */
{ "case $BUTTON in " { "case $BUTTON in "
"1) wifi ;; " "1) st -c st-float -g 90x30 -e nmtui connect ;; "
"3) st -c st-float -g 90x30 -e wpa_cli ;; " "3) st -c st-float -g 90x30 -e nmtui ;; "
"esac", 1 }, "esac", 1 },
/* volumen: izquierdo elegir la salida, central silenciar, derecho micro, rueda subir/bajar */ /* volumen: izquierdo pavucontrol, central silenciar, derecho micro, rueda subir/bajar */
{ "case $BUTTON in " { "case $BUTTON in "
"1) volumen salida ;; " "1) pavucontrol ;; "
"2) " VOLMUTECMD " ;; " "2) " VOLMUTECMD " ;; "
"3) " MICMUTECMD " ;; " "3) " MICMUTECMD " ;; "
"4) " VOLUPCMD " ;; " "4) " VOLUPCMD " ;; "
"5) " VOLDOWNCMD " ;; " "5) " VOLDOWNCMD " ;; "
"esac", 2 }, "esac", 2 },
/* bluetooth: izquierdo el menú (script bluetooth), derecho encender/apagar el adaptador */ /* bluetooth: izquierdo blueman, derecho encender/apagar el adaptador */
{ "case $BUTTON in " { "case $BUTTON in "
"1) bluetooth ;; " "1) blueman-manager ;; "
"3) if bluetoothctl show | grep -q 'Powered: yes'; " "3) if bluetoothctl show | grep -q 'Powered: yes'; "
"then bluetoothctl power off; else bluetoothctl power on; fi >/dev/null" STATUSREFRESH " ;; " "then bluetoothctl power off; else bluetoothctl power on; fi >/dev/null" STATUSREFRESH " ;; "
"esac", 3 }, "esac", 3 },

View file

@ -214,7 +214,7 @@ static uint forcemousemod = ShiftMask;
*/ */
static MouseShortcut mshortcuts[] = { static MouseShortcut mshortcuts[] = {
/* mask button function argument release */ /* mask button function argument release */
{ TERMMOD, Button3, previewimage, {.s = "nsxiv"} }, { TERMMOD, Button3, previewimage, {.s = "feh"} },
{ TERMMOD, Button2, showimageinfo, {}, 1 }, { TERMMOD, Button2, showimageinfo, {}, 1 },
{ XK_ANY_MOD, Button2, selpaste, {.i = 0}, 1 }, { XK_ANY_MOD, Button2, selpaste, {.i = 0}, 1 },
{ ShiftMask, Button4, ttysend, {.s = "\033[5;2~"} }, { ShiftMask, Button4, ttysend, {.s = "\033[5;2~"} },