configuration merge with laptop and pc

This commit is contained in:
2026-08-15 21:51:35 +02:00
parent b0b2e04b7f
commit 974858253b
32 changed files with 1861 additions and 144 deletions
+2 -1
View File
@@ -3,6 +3,7 @@
{{- $git_signingkey := promptStringOnce . "git.signingkey" "Git Signing Key" -}}
{{- $gpg_recipient := promptStringOnce . "gpg.recipient" "GPG Recipient Address" -}}
{{- $is_intel_cpu := promptBoolOnce . "cpu.intel" "Is this a Intel CPU?" -}}
{{- $is_amd_cpu := promptBoolOnce . "cpu.amd" "Is this a AMD CPU?" -}}
{{- $is_intel_i915_gpu := promptBoolOnce . "gpu.intel_i915" "Is this a Intel i915 GPU?" -}}
{{- $is_work_env := promptBoolOnce . "work_env" "Install work environment?" -}}
@@ -15,6 +16,7 @@ data:
recipient: {{ $gpg_recipient | quote }}
cpu:
intel: {{ $is_intel_cpu }}
amd: {{ $is_amd_cpu }}
gpu:
intel_i915: {{ $is_intel_i915_gpu }}
work_env: {{ $is_work_env }}
@@ -25,7 +27,6 @@ edit:
merge:
command: meld
args:
- {{ printf "%q" "{{ .Target }}" }}
- {{ printf "%q" "{{ .Source }}" }}
- {{ printf "%q" "{{ .Destination }}" }}
+9 -2
View File
@@ -25,6 +25,8 @@ packages:
- texinfo
- unzip
- usbutils
- cups
- cups-pk-helper
# Display
- brightnessctl
- ddcutil
@@ -100,12 +102,13 @@ packages:
- papirus-icon-theme
# Themes
- colloid-catppuccin-gtk-theme-git
- darkly-bin
# Software
- bat
- btop
- bitwarden
- chezmoi
- chromium
- ungoogled-chromium-bin
- evince
- fastfetch
- figlet
@@ -114,7 +117,7 @@ packages:
- github-cli
- go
- grim
- jre-openjdk
- jdk-openjdk
- jq
- kdeconnect
- kitty
@@ -147,6 +150,7 @@ packages:
- hunspell-en_gb
- hunspell-en_us
- qalculate-gtk
- wofi
# VIM
- lua-language-server
intel_graphics_i915:
@@ -161,6 +165,9 @@ packages:
intel_cpu:
yay:
- intel-ucode
amd_cpu:
yay:
- amd-ucode
work_env:
yay:
- teams-for-linux-bin
+10
View File
@@ -32,3 +32,13 @@
type: git-repo
url: https://github.com/catppuccin/spicetify.git
refreshPeriod: 168h
# Theme for QT
.config/qt5ct/colors/catppuccin-mocha-blue.conf:
type: file
url: https://raw.githubusercontent.com/catppuccin/qt5ct/refs/heads/main/themes/catppuccin-mocha-blue.conf
refreshPeriod: 168h
.config/qt6ct/colors/catppuccin-mocha-blue.conf:
type: file
url: https://raw.githubusercontent.com/catppuccin/qt5ct/refs/heads/main/themes/catppuccin-mocha-blue.conf
refreshPeriod: 168h
+79 -45
View File
@@ -1,74 +1,108 @@
Desktop
Documents
Downloads
Music
Pictures
Projects
Public
Templates
Videos
thunderbird
.cache
.lesshst
.thunderbird
.azure
.bash_history
.cache
.camera_driver
.cargo
.claude
.claude.json
.claude.json.backup
.gradle
.ideavimrc
.java
.jbr
.jdks
.junie
.lesshst
.librewolf
.local
.local/share/*
.local/share/**
.local/state/**
.local/state/**
.mozilla
.MakeMKV
.node_repl_history
.npm
.nvm
.pki
.python_history
.rustup
.ssh
.thunderbird
.config/Signal
.config/autostart
.config/Bitwarden
.config/bruno
.config/chezmoi
.config/chromium
.config/Claude
.config/cura
.config/dconf
.config/draw.io
.config/filezilla
.config/fontforge
.config/FreeCAD
.config/gh
.config/GIMP
.config/go
.config/google-chrome
.config/icedtea-web
.config/inkscape
.config/isyncrc
.config/JetBrains
.config/kdeconnect
.config/lftp
.config/libaccounts-glib
.config/libreoffice
.config/librewolf
.config/mozilla
.config/nemo
.config/Nextcloud
.config/nvim/lazy-lock.json
.config/nvm
.config/nvtop
.config/okularpartrc
.config/okularrc
.config/OpenSCAD
.config/openttd
.config/pavucontrol.ini
.config/pulse
.config/spotify
.config/systemd
.config/yay
.config/Bitwarden
.config/autostart
.config/teams-for-linux
.config/Claude
.config/chromium
.config/filezilla
.config/kdeconnect
.config/kitty/kitty.conf.bak
.config/lftp
.config/qalculate
.config/qt5ct/qss
.config/qt6ct/qss
.config/QtProject.conf
.config/rustdesk
.config/Signal
.config/spicetify
.config/spotify
.config/spotify-launcher.conf
.config/systemd
.config/teams-for-linux
.config/yay
.gnupg
.gnupg/crls.d
!.gnupg/dirmngr.conf
!.gnupg/gpg-agent.conf
!.gnupg/gpg.conf
.gnupg/openpgp-revocs.d
.gnupg/private-keys-v1.d
.gnupg/public-keys.d
.gnupg/sshcontrol
.gnupg/trustdb.gpg
.local
.local/state/**
.local/share/**
.npm
.nvm
.ssh
.pki
.python_history
.azure
.config/JetBrains
.config/bruno
.config/draw.io
.config/gh
.config/qalculate
.gradle
.ideavimrc
.jdks
Desktop
Documents
dotfiles
Downloads
isyncrc
maildir
maintenance
Music
nextcloud
Pictures
Projects
Public
Templates
thunderbird
Videos
@@ -0,0 +1,10 @@
{{- if eq .chezmoi.os "linux" -}}
#!/usr/bin/env bash
set -e
[ "${CHEZMOI}" -eq 1 ] || exit 1
systemctl --user enable --now dms
# vim: syntax=bash ft=template
{{- end -}}
@@ -12,9 +12,25 @@ if [ ! -d "/opt/spotify" ]; then
exit 0
fi
# Apply theme to spotify if either the spotify binary has changed, or the theme was updated in github
# spotify hash: {{ include "/opt/spotify/spotify" | sha256sum }}
# catppuccin hash: {{ joinPath .chezmoi.homeDir ".config/spicetify-catppuccin-theme/catppuccin/app.scss" | include | sha256sum }}
{{ $spotifyPath := "/opt/spotify/spotify" }}
{{ $s := stat $spotifyPath }}
{{ if and $s (hasKey $s "Exists") $s.Exists }}
# spotify hash: {{ include $spotifyPath | sha256sum }}
{{ else }}
# spotify hash: <not installed>
{{ end }}
{{ $catppuccinPath := joinPath .chezmoi.homeDir ".config/spicetify-catppuccin-theme/catppuccin/app.scss" }}
{{ $c := stat $catppuccinPath }}
{{ if and $c (hasKey $c "Exists") $c.Exists }}
# catppuccin hash: {{ include $catppuccinPath | sha256sum }}
{{ else }}
# catppuccin hash: <theme not installed>
{{ end }}
mkdir -p ~/.config/spicetify/Themes
cp -r ~/.config/spicetify-catppuccin-theme/catppuccin ~/.config/spicetify/Themes/
@@ -35,3 +51,4 @@ spicetify config current_theme catppuccin
spicetify config color_scheme mocha
spicetify config inject_css 1 inject_theme_js 1 replace_colors 1 overwrite_assets 1
spicetify apply
@@ -25,6 +25,11 @@ declare -a yay_packages
yay_packages+=({{ . | quote}})
{{ end -}}
{{ end -}}
{{ if eq .cpu.amd true -}}
{{ range .packages.arch.amd_cpu.yay -}}
yay_packages+=({{ . | quote}})
{{ end -}}
{{ end -}}
{{ if eq .gpu.intel_i915 true -}}
{{ range .packages.arch.intel_graphics_i915.yay -}}
yay_packages+=({{ . | quote}})
+2 -2
View File
@@ -12,10 +12,10 @@ HISTTIMEFORMAT="[%F %T] "
HISTCONTROL="ignoredups"
HISTSIZE="200"
HISTFILESIZE="2000"
shopt -s histappend
shopt -s histappend # append new entries to the histry instead of overwriting
# --- Bash Options ---
set -o vi
set -o vi # mandated by POSIX
shopt -s checkwinsize
# --- Pager ---
+1
View File
@@ -0,0 +1 @@
(gtk_accel_path "<Actions>/DirViewActions/OpenInTerminal" "F4")
+3 -3
View File
@@ -5,7 +5,7 @@
color_theme = "/home/frank/.config/btop/themes/catppuccin_mocha.theme"
#* If the theme set background should be shown, set to False if you want terminal background transparency.
theme_background = true
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
@@ -27,13 +27,13 @@ presets = "cpu:1:default,proc:0:default cpu:0:default,mem:0:default,net:0:defaul
#* 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
vim_keys = true
#* Disable all mouse events.
disable_mouse = false
#* Rounded corners on boxes, is ignored if TTY mode is ON.
rounded_corners = true
rounded_corners = false
#* Use terminal synchronized output sequences to reduce flickering on supported terminals.
terminal_sync = true
+2
View File
@@ -3,4 +3,6 @@ file:///home/frank/Downloads Downloads
file:///home/frank/Pictures Pictures
file:///home/frank/Projects Projects
file:///home/frank/Projects/inso-automation inso-automation
file:///home/frank/Documents/3d-printing 3d-printing
file:///home/frank/nextcloud nextcloud
smb://10.10.10.5/ HOMESERVER
@@ -9,3 +9,10 @@ hl.on("hyprland.start", function()
hl.exec_cmd("~/.config/hypr/scripts/autostart.sh")
end)
-- old stuff, probably not needed anymore
-- exec-once = gnome-keyring-daemon --start --components=secrets
-- exec-once = systemctl --user start gcr-ssh-agent.socket
--
-- Polkit Daemon
-- exec-once = /usr/lib/polkit-gnome/polkit-gnome-authentication-agent-1
--
+21 -2
View File
@@ -9,7 +9,7 @@ hl.monitor({
-- if no profile match at all, the fallback_profile will be applied anyways.
local fallback_profile="laptop"
local profiles = {
home = {
home_docked = {
priority = 10,
monitors = {
"desc:GIGA-BYTE TECHNOLOGY CO. LTD. M34WQ 0x00000B52",
@@ -25,6 +25,25 @@ local profiles = {
workspace_rules = {
},
},
home_pc = {
priority = 20,
monitors = {
"desc:GIGA-BYTE TECHNOLOGY CO. LTD. M34WQ 0x00000B52",
"desc:Dell Inc. DELL U2724D DL7R834",
"desc:Dell Inc. DELL U2414H 292K475V26JL",
},
disable_other_monitors = true,
monitor_config = {
["desc:GIGA-BYTE TECHNOLOGY CO. LTD. M34WQ 0x00000B52"] = {disabled=false, scale=1, position="0x0", mode="3440x1440@120"},
["desc:Dell Inc. DELL U2414H 292K475V26JL"] = {disabled=false, scale=1, position="760x-1080", mode="1920x1080@60"},
["desc:Dell Inc. DELL U2724D DL7R834"] = {disabled=false, scale=1, position="3440x0", mode="2560x1440@120"},
},
workspace_rules = {
{ workspace = "1", monitor = "desc:GIGA-BYTE TECHNOLOGY CO. LTD. M34WQ 0x00000B52", default = true, persistent = true},
{ workspace = "9", monitor = "desc:Dell Inc. DELL U2724D DL7R834", default = true, persistent = true},
{ workspace = "10", monitor = "desc:Dell Inc. DELL U2414H 292K475V26JL", default = true, persistent = true},
}
},
work = {
priority = 10,
monitors = {
@@ -162,7 +181,7 @@ local function apply_monitor_profile()
end
local monitor_profile_timer = nil
local function request_apply_monitor_profile(data)
function request_apply_monitor_profile(data)
debug_notify("requested monitor profile update")
table.insert(apply_monitor_request_queue, data or {})
if monitor_profile_timer == nil or not monitor_profile_timer:is_enabled() then
@@ -1,10 +1,16 @@
#!/usr/bin/env bash
(sleep 5 ; hyprctl eval 'request_apply_monitor_profile()') &
hyprctl dispatch 'hl.dsp.exec_cmd("uwsm app -- thunderbird", {workspace = 10})'
{{ if eq .work_env true -}}
hyprctl dispatch 'hl.dsp.exec_cmd("uwsm app -- /home/frank/.local/share/applications/librewolf.webapp-e7db0a1c-02e9-42cc-a5da-8fdc222e89dc.desktop", {workspace = 9})'
hyprctl dispatch 'hl.dsp.exec_cmd("uwsm app -- jetbrains-toolbox.desktop")'
{{ end -}}
hyprctl dispatch 'hl.dsp.exec_cmd("uwsm app -- nextcloud")'
sleep 3
hyprctl dispatch 'hl.dsp.exec_cmd("uwsm app -- Telegram --ozone-platform=wayland", {workspace = 10})'
hyprctl dispatch 'hl.dsp.exec_cmd("uwsm app -- signal-desktop --ozone-platform=wayland", {workspace = 10})'
{{ if eq .work_env true -}}
hyprctl dispatch 'hl.dsp.exec_cmd("uwsm app -- /home/frank/.local/share/applications/librewolf.webapp-daf88433-cdaa-4a10-9bfb-af0a20fb7b71.desktop", {workspace = 9})'
{{ end -}}
-75
View File
@@ -1,75 +0,0 @@
[Default Applications]
application/pdf=librewolf.desktop
application/rss+xml=userapp-Thunderbird-WTV1S3.desktop
application/vnd.comicbook+zip=librewolf.desktop
application/vnd.comicbook-rar=librewolf.desktop
application/x-bzpdf=librewolf.desktop
application/x-ext-pdf=librewolf.desktop
application/x-extension-ics=userapp-Thunderbird-X7G9S3.desktop
application/x-extension-rss=userapp-Thunderbird-WTV1S3.desktop
application/x-gzpdf=librewolf.desktop
image/avif=dms-open.desktop
image/bmp=dms-open.desktop
image/gif=dms-open.desktop
image/jpeg=dms-open.desktop
image/png=dms-open.desktop
image/svg+xml=dms-open.desktop
image/webp=dms-open.desktop
inode/directory=nemo.desktop
message/rfc822=userapp-Thunderbird-3QI0S3.desktop
text/calendar=userapp-Thunderbird-X7G9S3.desktop
text/html=librewolf.desktop
text/plain=nvim.desktop
x-directory/normal=nemo.desktop
x-scheme-handler/about=librewolf.desktop
x-scheme-handler/calendar=dms-open.desktop
x-scheme-handler/feed=userapp-Thunderbird-WTV1S3.desktop
x-scheme-handler/http=librewolf.desktop
x-scheme-handler/https=librewolf.desktop
x-scheme-handler/mailto=userapp-Thunderbird-3QI0S3.desktop
x-scheme-handler/mid=userapp-Thunderbird-3QI0S3.desktop
x-scheme-handler/net.thunderbird=userapp-Thunderbird-U229S3.desktop
x-scheme-handler/news=userapp-Thunderbird-AH40S3.desktop
x-scheme-handler/nntp=userapp-Thunderbird-AH40S3.desktop
x-scheme-handler/snews=userapp-Thunderbird-AH40S3.desktop
x-scheme-handler/unknown=librewolf.desktop
x-scheme-handler/webcal=userapp-Thunderbird-X7G9S3.desktop
x-scheme-handler/webcals=userapp-Thunderbird-X7G9S3.desktop
x-scheme-handler/claude=claude-desktop.desktop
x-scheme-handler/jetbrains=jetbrainsd.desktop
x-scheme-handler/claude-cli=claude-code-url-handler.desktop
application/xhtml+xml=librewolf.desktop
x-scheme-handler/bruno=bruno.desktop
[Added Associations]
application/pdf=librewolf.desktop;
application/rss+xml=userapp-Thunderbird-WTV1S3.desktop;
application/vnd.comicbook+zip=librewolf.desktop;
application/vnd.comicbook-rar=librewolf.desktop;
application/x-bzpdf=librewolf.desktop;
application/x-ext-pdf=librewolf.desktop;
application/x-extension-ics=userapp-Thunderbird-X7G9S3.desktop;
application/x-extension-rss=userapp-Thunderbird-WTV1S3.desktop;
application/x-gzpdf=librewolf.desktop;
image/avif=dms-open.desktop;
image/bmp=dms-open.desktop;
image/gif=dms-open.desktop;
image/jpeg=dms-open.desktop;
image/png=dms-open.desktop;
image/svg+xml=dms-open.desktop;
image/webp=dms-open.desktop;
message/rfc822=userapp-Thunderbird-3QI0S3.desktop;
text/calendar=userapp-Thunderbird-X7G9S3.desktop;
x-scheme-handler/calendar=dms-open.desktop;
x-scheme-handler/feed=userapp-Thunderbird-WTV1S3.desktop;
x-scheme-handler/mailto=userapp-Thunderbird-3QI0S3.desktop;
x-scheme-handler/mid=userapp-Thunderbird-3QI0S3.desktop;
x-scheme-handler/net.thunderbird=userapp-Thunderbird-U229S3.desktop;
x-scheme-handler/news=userapp-Thunderbird-AH40S3.desktop;
x-scheme-handler/nntp=userapp-Thunderbird-AH40S3.desktop;
x-scheme-handler/snews=userapp-Thunderbird-AH40S3.desktop;
x-scheme-handler/webcal=userapp-Thunderbird-X7G9S3.desktop;
x-scheme-handler/webcals=userapp-Thunderbird-X7G9S3.desktop;
application/xhtml+xml=librewolf.desktop;
[Removed Associations]
+99
View File
@@ -0,0 +1,99 @@
{{ $rss := "x" }}
{{ $cal := "x" }}
{{ $mail := "x" }}
{{ $tb := "x" }}
{{ $news := "x" }}
{{- if eq .chezmoi.hostname "arch-next" -}}
{{- $rss = "userapp-Thunderbird-Y886T3.desktop" -}}
{{- $cal = "userapp-Thunderbird-NA25T3.desktop" -}}
{{- $mail = "userapp-Thunderbird-Q3N5T3.desktop" -}}
{{- $tb = "userapp-Thunderbird-SIG6T3.desktop" }}
{{- $news = "userapp-Thunderbird-A0Q6T3.desktop" }}
{{- else if eq .chezmoi.hostname "xps13-ia" -}}
{{- $rss = "userapp-Thunderbird-WTV1S3.desktop" -}}
{{- $cal = "userapp-Thunderbird-X7G9S3.desktop" -}}
{{- $mail = "userapp-Thunderbird-3QI0S3.desktop" -}}
{{- $tb = "userapp-Thunderbird-U229S3.desktop" -}}
{{- $news = "userapp-Thunderbird-AH40S3.desktop" -}}
{{- end -}}
[Default Applications]
application/pdf=librewolf.desktop
application/rss+xml={{ $rss }}
application/vnd.comicbook+zip=librewolf.desktop
application/vnd.comicbook-rar=librewolf.desktop
application/x-bzpdf=librewolf.desktop
application/x-ext-pdf=librewolf.desktop
application/x-extension-ics={{ $cal}}
application/x-extension-rss={{ $rss }}
application/x-gzpdf=librewolf.desktop
image/avif=dms-open.desktop
image/bmp=dms-open.desktop
image/gif=dms-open.desktop
image/jpeg=dms-open.desktop
image/png=dms-open.desktop
image/svg+xml=dms-open.desktop
image/webp=dms-open.desktop
inode/directory=nemo.desktop
message/rfc822={{ $mail }}
text/calendar={{ $cal }}
text/html=librewolf.desktop
text/plain=nvim.desktop
x-directory/normal=nemo.desktop
x-scheme-handler/about=librewolf.desktop
x-scheme-handler/calendar=dms-open.desktop
x-scheme-handler/feed={{ $rss }}
x-scheme-handler/http=librewolf.desktop
x-scheme-handler/https=librewolf.desktop
x-scheme-handler/mailto={{ $mail }}
x-scheme-handler/mid={{ $mail }}
x-scheme-handler/net.thunderbird={{ $tb }}
x-scheme-handler/news={{ $news }}
x-scheme-handler/nntp={{ $news }}
x-scheme-handler/snews={{ $news }}
x-scheme-handler/unknown=librewolf.desktop
x-scheme-handler/webcal={{ $cal }}
x-scheme-handler/webcals={{ $cal }}
x-scheme-handler/claude=claude-desktop.desktop
x-scheme-handler/jetbrains=jetbrainsd.desktop
x-scheme-handler/claude-cli=claude-code-url-handler.desktop
application/xhtml+xml=librewolf.desktop
x-scheme-handler/bruno=bruno.desktop
[Added Associations]
application/pdf=librewolf.desktop;
application/rss+xml={{ $rss }};
application/vnd.comicbook+zip=librewolf.desktop;
application/vnd.comicbook-rar=librewolf.desktop;
application/x-bzpdf=librewolf.desktop;
application/x-ext-pdf=librewolf.desktop;
application/x-extension-ics={{ $cal }};
application/x-extension-rss={{ $rss }};
application/x-gzpdf=librewolf.desktop;
image/avif=dms-open.desktop;
image/bmp=dms-open.desktop;
image/gif=dms-open.desktop;
image/jpeg=dms-open.desktop;
image/png=dms-open.desktop;
image/svg+xml=dms-open.desktop;
image/webp=dms-open.desktop;
message/rfc822={{ $mail }};
text/calendar={{ $cal }};
x-scheme-handler/calendar=dms-open.desktop;
x-scheme-handler/feed={{ $rss }};
x-scheme-handler/mailto={{ $mail }};
x-scheme-handler/mid={{ $mail }};
x-scheme-handler/net.thunderbird={{ $tb }};
x-scheme-handler/news={{ $rss }};
x-scheme-handler/nntp={{ $rss }};
x-scheme-handler/snews={{ $rss }};
x-scheme-handler/webcal={{ $cal }};
x-scheme-handler/webcals={{ $cal }};
application/xhtml+xml=librewolf.desktop;
[Removed Associations]
+155
View File
@@ -0,0 +1,155 @@
General usage
=============
::
mpv infile --o=outfile [--of=outfileformat] [--ofopts=formatoptions] [--orawts] \
[(any other mpv options)] \
--ovc=outvideocodec [--ovcopts=outvideocodecoptions] \
--oac=outaudiocodec [--oacopts=outaudiocodecoptions]
Help for these options is provided if giving help as parameter, as in::
mpv --ovc=help
The suboptions of these generally are identical to ffmpeg's (as option parsing
is simply delegated to ffmpeg). The option --ocopyts enables copying timestamps
from the source as-is, instead of fixing them to match audio playback time
(note: this doesn't work with all output container formats); --orawts even turns
off discontinuity fixing.
Note that if neither --ofps nor --oautofps is specified, VFR encoding is assumed
and the time base is 24000fps. --oautofps sets --ofps to a guessed fps number
from the input video. Note that not all codecs and not all formats support VFR
encoding, and some which do have bugs when a target bitrate is specified - use
--ofps or --oautofps to force CFR encoding in these cases.
Of course, the options can be stored in a profile, like this .config/mpv/mpv.conf
section::
[myencprofile]
vf-add = scale=480:-2
ovc = libx264
ovcopts-add = preset=medium
ovcopts-add = tune=fastdecode
ovcopts-add = crf=23
ovcopts-add = maxrate=1500k
ovcopts-add = bufsize=1000k
ovcopts-add = rc_init_occupancy=900k
ovcopts-add = refs=2
ovcopts-add = profile=baseline
oac = aac
oacopts-add = b=96k
It's also possible to define default encoding options by putting them into
the section named ``[encoding]``. (This behavior changed after mpv 0.3.x. In
mpv 0.3.x, config options in the default section / no section were applied
to encoding. This is not the case anymore.)
One can then encode using this profile using the command::
mpv infile --o=outfile.mp4 --profile=myencprofile
Some example profiles are provided in a file
etc/encoding-profiles.conf; as for this, see below.
Encoding examples
=================
These are some examples of encoding targets this code has been used and tested
for.
Typical MPEG-4 Part 2 ("ASP", "DivX") encoding, AVI container::
mpv infile --o=outfile.avi \
--vf=fps=25 \
--ovc=mpeg4 --ovcopts=qscale=4 \
--oac=libmp3lame --oacopts=b=128k
Note: AVI does not support variable frame rate, so the fps filter must be used.
The frame rate should ideally match the input (25 for PAL, 24000/1001 or
30000/1001 for NTSC)
Typical MPEG-4 Part 10 ("AVC", "H.264") encoding, Matroska (MKV) container::
mpv infile --o=outfile.mkv \
--ovc=libx264 --ovcopts=preset=medium,crf=23,profile=baseline \
--oac=libopus --oacopts=qscale=3
Typical MPEG-4 Part 10 ("AVC", "H.264") encoding, MPEG-4 (MP4) container::
mpv infile --o=outfile.mp4 \
--ovc=libx264 --ovcopts=preset=medium,crf=23,profile=baseline \
--oac=aac --oacopts=b=128k
Typical VP8 encoding, WebM (restricted Matroska) container::
mpv infile -o outfile.mkv \
--of=webm \
--ovc=libvpx --ovcopts=qmin=6,b=1000000k \
--oac=libopus --oacopts=qscale=3
Device targets
==============
As the options for various devices can get complex, profiles can be used.
An example profile file for encoding is provided in
etc/encoding-profiles.conf in the source tree. This file is installed and loaded
by default. If you want to modify it, you can replace and it with your own copy
by doing::
mkdir -p ~/.mpv
cp /etc/mpv/encoding-profiles.conf ~/.mpv/encoding-profiles.conf
Keep in mind that the default profile is the playback one. If you want to add
options that apply only in encoding mode, put them into a ``[encoding]``
section.
Refer to the top of that file for more comments - in a nutshell, the following
options are added by it::
--profile=enc-to-dvdpal # DVD-Video PAL, use dvdauthor -v pal+4:3 -a ac3+en
--profile=enc-to-dvdntsc # DVD-Video NTSC, use dvdauthor -v ntsc+4:3 -a ac3+en
--profile=enc-to-bb-9000 # MP4 for Blackberry Bold 9000
--profile=enc-to-nok-6300 # 3GP for Nokia 6300
--profile=enc-to-psp # MP4 for PlayStation Portable
--profile=enc-to-iphone # MP4 for iPhone
--profile=enc-to-iphone-4 # MP4 for iPhone 4 (double res)
--profile=enc-to-iphone-5 # MP4 for iPhone 5 (even larger res)
You can encode using these with a command line like::
mpv infile --o=outfile.mp4 --profile=enc-to-bb-9000
Of course, you are free to override options set by these profiles by specifying
them after the -profile option.
What works
==========
* Encoding at variable frame rate (default)
* Encoding at constant frame rate using --vf=fps=RATE
* 2-pass encoding (specify flags=+pass1 in the first pass's --ovcopts, specify
flags=+pass2 in the second pass)
* Hardcoding subtitles using vobsub, ass or srt subtitle rendering (just
configure mpv for the subtitles as usual)
* Hardcoding any other mpv OSD (e.g. time codes, using --osdlevel=3 and
--vf=expand=::::1)
* Encoding directly from a DVD, network stream, webcam, or any other source
mpv supports
* Using x264 presets/tunings/profiles (by using profile=, tune=, preset= in the
--ovcopts)
* Deinterlacing/Inverse Telecine with any of mpv's filters for that
* Audio file converting: mpv --o=outfile.m4a infile.flac --no-video
--oac=aac --oacopts=b=320k
What does not work yet
======================
* 3-pass encoding (ensuring constant total size and bitrate constraints while
having VBR audio; mencoder calls this "frameno")
* Direct stream copy
+246
View File
@@ -0,0 +1,246 @@
# mpv keybindings
#
# Location of user-defined bindings: ~/.config/mpv/input.conf
#
# Lines starting with # are comments. Use SHARP to assign the # key.
# Copy this file and uncomment and edit the bindings you want to change.
#
# List of commands and further details: DOCS/man/input.rst
# List of special keys: --input-keylist
# Keybindings testing mode: mpv --input-test --force-window --idle
#
# Use 'ignore' to unbind a key fully (e.g. 'ctrl+a ignore').
#
# Strings need to be quoted and escaped:
# KEY show-text "This is a single backslash: \\ and a quote: \" !"
#
# You can use modifier-key combinations like Shift+Left or Ctrl+Alt+x with
# the modifiers Shift, Ctrl, Alt and Meta (may not work on the terminal).
#
# The default keybindings are hardcoded into the mpv binary.
# You can disable them completely with: --no-input-default-bindings
# Developer note:
# On compilation, this file is baked into the mpv binary, and all lines are
# uncommented (unless '#' is followed by a space) - thus this file defines the
# default key bindings.
# If this is enabled, treat all the following bindings as default.
#default-bindings start
#MBTN_LEFT ignore # don't do anything
#MBTN_LEFT_DBL cycle fullscreen # toggle fullscreen
#MBTN_RIGHT cycle pause # toggle pause/playback mode
#MBTN_BACK playlist-prev # skip to the previous file
#MBTN_FORWARD playlist-next # skip to the next file
#Ctrl+MBTN_LEFT script-binding positioning/drag-to-pan # pan around the clicked point
# Mouse wheels, touchpad or other input devices that have axes
# if the input devices supports precise scrolling it will also scale the
# numeric value accordingly
#WHEEL_UP add volume 2
#WHEEL_DOWN add volume -2
#WHEEL_LEFT seek -10 # seek 10 seconds backward
#WHEEL_RIGHT seek 10 # seek 10 seconds forward
## Seek units are in seconds, but note that these are limited by keyframes
#RIGHT seek 5 # seek 5 seconds forward
#LEFT seek -5 # seek 5 seconds backward
#UP seek 60 # seek 1 minute forward
#DOWN seek -60 # seek 1 minute backward
# Do smaller, always exact (non-keyframe-limited), seeks with shift.
# Don't show them on the OSD (no-osd).
#Shift+RIGHT no-osd seek 1 exact # seek exactly 1 second forward
#Shift+LEFT no-osd seek -1 exact # seek exactly 1 second backward
#Shift+UP no-osd seek 5 exact # seek exactly 5 seconds forward
#Shift+DOWN no-osd seek -5 exact # seek exactly 5 seconds backward
#Ctrl+LEFT no-osd sub-seek -1 # seek to the previous subtitle
#Ctrl+RIGHT no-osd sub-seek 1 # seek to the next subtitle
#Ctrl+Shift+LEFT sub-step -1 # change subtitle timing such that the previous subtitle is displayed
#Ctrl+Shift+RIGHT sub-step 1 # change subtitle timing such that the next subtitle is displayed
#Alt+left add video-pan-x 0.1 # move the video right
#Alt+right add video-pan-x -0.1 # move the video left
#Alt+up add video-pan-y 0.1 # move the video down
#Alt+down add video-pan-y -0.1 # move the video up
#Alt++ add video-zoom 0.1 # zoom in
#ZOOMIN add video-zoom 0.1 # zoom in
#Alt+- add video-zoom -0.1 # zoom out
#ZOOMOUT add video-zoom -0.1 # zoom out
#Alt+KP_ADD add video-zoom 0.1 # zoom in
#Alt+KP_SUBTRACT add video-zoom -0.1 # zoom out
#Ctrl+WHEEL_UP script-binding positioning/cursor-centric-zoom 0.1 # zoom in towards the cursor
#Ctrl+WHEEL_DOWN script-binding positioning/cursor-centric-zoom -0.1 # zoom out towards the cursor
#Alt+BS set video-zoom 0; no-osd set panscan 0; no-osd set video-pan-x 0; no-osd set video-pan-y 0; no-osd set video-align-x 0; no-osd set video-align-y 0 # reset zoom and pan settings
#HOME seek 0 absolute # seek to the start
#PGUP add chapter 1 # seek to the next chapter
#PGDWN add chapter -1 # seek to the previous chapter
#Shift+PGUP seek 600 # seek 10 minutes forward
#Shift+PGDWN seek -600 # seek 10 minutes backward
#[ multiply speed 1/1.1 # decrease the playback speed
#] multiply speed 1.1 # increase the playback speed
#{ multiply speed 0.5 # halve the playback speed
#} multiply speed 2.0 # double the playback speed
#BS set speed 1.0 # reset the speed to normal
#Shift+BS revert-seek # undo the previous (or marked) seek
#Shift+Ctrl+BS revert-seek mark # mark the position for revert-seek
#q quit
#Q quit-watch-later # exit and remember the playback position
#q {encode} quit 4
#ESC set fullscreen no # leave fullscreen
#ESC {encode} quit 4
#p cycle pause # toggle pause/playback mode
#. frame-step # advance one frame and pause
#, frame-back-step # go back by one frame and pause
#SPACE cycle pause # toggle pause/playback mode
#> playlist-next # skip to the next file
#ENTER playlist-next # skip to the next file
#< playlist-prev # skip to the previous file
#Shift+HOME no-osd set playlist-pos 0 # skip to the first file
#Shift+END no-osd set playlist-pos-1 ${playlist-count} # skip to the last file
#O no-osd cycle-values osd-level 3 1 # toggle displaying the OSD on user interaction or always
#o show-progress # show playback progress
#P show-progress # show playback progress
#i script-binding stats/display-stats # display information and statistics
#I script-binding stats/display-stats-toggle # toggle displaying information and statistics
#? script-binding stats/display-page-4-toggle # toggle displaying key bindings
#` script-binding commands/open # open the console
#z add sub-delay -0.1 # shift subtitles 100 ms earlier
#Z add sub-delay +0.1 # delay subtitles by 100 ms
#x add sub-delay +0.1 # delay subtitles by 100 ms
#ctrl++ add audio-delay 0.100 # change audio/video sync by delaying the audio
#ctrl+- add audio-delay -0.100 # change audio/video sync by shifting the audio earlier
#ctrl+KP_ADD add audio-delay 0.100 # change audio/video sync by delaying the audio
#ctrl+KP_SUBTRACT add audio-delay -0.100 # change audio/video sync by shifting the audio earlier
#G add sub-scale +0.1 # increase the subtitle font size
#F add sub-scale -0.1 # decrease the subtitle font size
#9 add volume -2
#/ add volume -2
#KP_DIVIDE add volume -2
#0 add volume 2
#* add volume 2
#KP_MULTIPLY add volume 2
#m cycle mute # toggle mute
#1 add contrast -1
#2 add contrast 1
#3 add brightness -1
#4 add brightness 1
#5 add gamma -1
#6 add gamma 1
#7 add saturation -1
#8 add saturation 1
#Alt+0 set window-scale 0.5 # halve the window size
#Alt+1 set window-scale 1.0 # reset the window size
#Alt+2 set window-scale 2.0 # double the window size
#b cycle deband # toggle the debanding filter
#d cycle deinterlace # cycle the deinterlacing filter
#r add sub-pos -1 # move subtitles up
#R add sub-pos +1 # move subtitles down
#t add sub-pos +1 # move subtitles down
#v cycle sub-visibility # hide or show the subtitles
#Alt+v cycle secondary-sub-visibility # hide or show the secondary subtitles
#V cycle sub-ass-use-video-data # cycle which video data gets used in ASS rendering to fix broken files
#u cycle-values sub-ass-override "force" "scale" # toggle overriding SSA/ASS subtitle styles with the normal styles
#j cycle sub # switch subtitle track
#J cycle sub down # switch subtitle track backwards
#SHARP cycle audio # switch audio track
#_ cycle video # switch video track
#T cycle ontop # toggle placing the video on top of other windows
#f cycle fullscreen # toggle fullscreen
#s screenshot # take a screenshot of the video in its original resolution with subtitles
#S screenshot video # take a screenshot of the video in its original resolution without subtitles
#Ctrl+s screenshot window # take a screenshot of the window with OSD and subtitles
#Alt+s screenshot each-frame # automatically screenshot every frame; issue this command again to stop taking screenshots
#w add panscan -0.1 # decrease panscan
#W add panscan +0.1 # shrink black bars by cropping the video
#e add panscan +0.1 # shrink black bars by cropping the video
#A cycle-values video-aspect-override "16:9" "4:3" "2.35:1" "no" # cycle the video aspect ratio
#POWER quit
#PLAY cycle pause # toggle pause/playback mode
#PAUSE cycle pause # toggle pause/playback mode
#PLAYPAUSE cycle pause # toggle pause/playback mode
#PLAYONLY set pause no # unpause
#PAUSEONLY set pause yes # pause
#STOP quit
#FORWARD seek 60 # seek 1 minute forward
#REWIND seek -60 # seek 1 minute backward
#NEXT playlist-next # skip to the next file
#PREV playlist-prev # skip to the previous file
#VOLUME_UP add volume 2
#VOLUME_DOWN add volume -2
#MUTE cycle mute # toggle mute
#CLOSE_WIN quit
#CLOSE_WIN {encode} quit 4
#ctrl+w quit
#E cycle edition # switch edition
#l ab-loop # set/clear A-B loop points
#L cycle-values loop-file "inf" "no" # toggle infinite looping
#ctrl+c quit 4
#Ctrl+v loadfile ${clipboard/text} append-play; show-text '+ ${clipboard/text}' # append the copied path
#DEL script-binding osc/visibility # cycle OSC visibility between never, auto (mouse-move) and always
#ctrl+h cycle-values hwdec "no" "auto" # toggle hardware decoding
#F8 show-text ${playlist} # show the playlist
#F9 show-text ${track-list} # show the list of video, audio and sub tracks
#g ignore
#g-p script-binding select/select-playlist
#g-s script-binding select/select-sid
#g-S script-binding select/select-secondary-sid
#g-a script-binding select/select-aid
#g-v script-binding select/select-vid
#g-t script-binding select/select-track
#g-c script-binding select/select-chapter
#g-e script-binding select/select-edition
#g-l script-binding select/select-subtitle-line
#g-d script-binding select/select-audio-device
#g-h script-binding select/select-watch-history
#g-w script-binding select/select-watch-later
#g-b script-binding select/select-binding
#g-r script-binding select/show-properties
#g-m script-binding select/menu
#MENU script-binding select/menu
#ctrl+p script-binding select/menu
#Alt+KP1 add video-rotate -1 # rotate video counterclockwise by 1 degree
#Alt+KP5 set video-rotate 0 # reset rotation
#Alt+KP3 add video-rotate 1 # rotate video clockwise by 1 degree
#KP1 add video-zoom -0.01 # zoom out video
#KP2 add video-scale-y -0.01 # scale down video vertically
#KP4 add video-scale-x -0.01 # scale down video horizontally
#KP5 set video-scale-x 1.00; set video-scale-y 1; set video-zoom 0 # reset video scale
#KP6 add video-scale-x 0.01 # scale up video horizontally
#KP8 add video-scale-y 0.01 # scale up video vertically
#KP9 add video-zoom 0.01 # zoom in video
#Ctrl+KP1 add video-pan-x -0.01; add video-pan-y 0.01 # move video left and down
#Ctrl+KP2 add video-pan-y 0.01 # move video down
#Ctrl+KP3 add video-pan-x 0.01; add video-pan-y 0.01 # move video right and down
#Ctrl+KP4 add video-pan-x -0.01 # move video left
#Ctrl+KP5 set video-pan-x 0.00; set video-pan-y 0.00 # reset video position
#Ctrl+KP6 add video-pan-x 0.01 # move video right
#Ctrl+KP7 add video-pan-x -0.01; add video-pan-y -0.01 # move video left and up
#Ctrl+KP8 add video-pan-y -0.01 # move video up
#Ctrl+KP9 add video-pan-x 0.01; add video-pan-y -0.01 # move video right and up
#Ctrl+KP_END add video-align-x -0.01; add video-align-y 0.01 # align video left and down
#Ctrl+KP_DOWN add video-align-y 0.01 # align video down
#Ctrl+KP_PGDWN add video-align-x 0.01; add video-align-y 0.01 # align video right and down
#Ctrl+KP_LEFT add video-align-x -0.01 # align video left
#Ctrl+KP_BEGIN set video-align-x 0.00; set video-align-y 0.00 # reset video alignment
#Ctrl+KP_RIGHT add video-align-x 0.01 # align video right
#Ctrl+KP_HOME add video-align-x -0.01; add video-align-y -0.01 # align video left and up
#Ctrl+KP_UP add video-align-y -0.01 # align video up
#Ctrl+KP_PGUP add video-align-x 0.01; add video-align-y -0.01 # align video right and up
#
# Legacy bindings (may or may not be removed in the future)
#
#! add chapter -1 # seek to the previous chapter
#@ add chapter 1 # seek to the next chapter
#
# Not assigned by default
# (not an exhaustive list of unbound commands)
#
# ? cycle sub-forced-events-only # display only DVD/PGS forced subtitle events
# ? stop # stop playback (quit or enter idle mode)
+93
View File
@@ -0,0 +1,93 @@
##
## MPlayer-style key bindings
##
## Save it as ~/.config/mpv/input.conf to use it.
##
## Generally, it's recommended to use this as reference-only.
##
RIGHT seek +10
LEFT seek -10
DOWN seek -60
UP seek +60
PGUP seek 600
PGDWN seek -600
m cycle mute
SHARP cycle audio # switch audio streams
+ add audio-delay 0.100
= add audio-delay 0.100
- add audio-delay -0.100
[ multiply speed 0.9091 # scale playback speed
] multiply speed 1.1
{ multiply speed 0.5
} multiply speed 2.0
BS set speed 1.0 # reset speed to normal
q quit
ESC quit
ENTER playlist-next force # skip to next file
p cycle pause
. frame-step # advance one frame and pause
SPACE cycle pause
HOME set playlist-pos 0 # not the same as MPlayer
#END pt_up_step -1
> playlist-next # skip to next file
< playlist-prev # previous
#INS alt_src_step 1
#DEL alt_src_step -1
o osd
I show-text "${filename}" # display filename in osd
P show-progress
z add sub-delay -0.1 # subtract 100 ms delay from subs
x add sub-delay +0.1 # add
9 add volume -1
/ add volume -1
0 add volume 1
* add volume 1
1 add contrast -1
2 add contrast 1
3 add brightness -1
4 add brightness 1
5 add hue -1
6 add hue 1
7 add saturation -1
8 add saturation 1
( add balance -0.1 # adjust audio balance in favor of left
) add balance +0.1 # right
d cycle framedrop
D cycle deinterlace # toggle deinterlacer (auto-inserted filter)
r add sub-pos -1 # move subtitles up
t add sub-pos +1 # down
#? sub-step +1 # immediately display next subtitle
#? sub-step -1 # previous
#? add sub-scale +0.1 # increase subtitle font size
#? add sub-scale -0.1 # decrease subtitle font size
f cycle fullscreen
T cycle ontop # toggle video window ontop of other windows
w add panscan -0.1 # zoom out with -panscan 0 -fs
e add panscan +0.1 # in
c cycle stream-capture # save (and append) file/stream to stream.dump with -capture
s screenshot # take a screenshot (if you want PNG, use "--screenshot-format=png")
S screenshot - each-frame # S will take a png screenshot of every frame
h cycle tv-channel 1
l cycle tv-channel -1
n cycle tv-norm
#b tv_step_chanlist
#? add chapter -1 # skip to previous dvd chapter
#? add chapter +1 # next
##
## Advanced seek
## Uncomment the following lines to be able to seek to n% of the media with
## the Fx keys.
##
#F1 seek 10 absolute-percent
#F2 seek 20 absolute-percent
#F3 seek 30 absolute-percent
#F4 seek 40 absolute-percent
#F5 seek 50 absolute-percent
#F6 seek 60 absolute-percent
#F7 seek 70 absolute-percent
#F8 seek 80 absolute-percent
#F9 seek 90 absolute-percent
+42
View File
@@ -0,0 +1,42 @@
##################
# video settings #
##################
# Start in fullscreen mode by default.
fs=yes
profile=high-quality
video-sync=display-resample
interpolation
hwdec=auto
##################
# audio settings #
##################
audio-channels=auto
##################
# other settings #
##################
cache=yes
demuxer-max-bytes=500M
demuxer-max-back-bytes=100M
cache-pause=no
cache-on-disk=no
# Display English subtitles if available.
slang=de,en
# Play Finnish audio if available, fall back to English otherwise.
alang=de,en
sub-auto=fuzzy
sub-font="Inter"
sub-bold=yes
############
# Profiles #
############
@@ -0,0 +1,59 @@
# This file contains all bindings that were removed or changed
# after a certain release.
# If you want MPlayer bindings, use mplayer-input.conf
# Pick the bindings you want back and add them to your own input.conf. Append
# this file to your input.conf if you want them all back:
#
# cat restore-old-bindings.conf >> ~/.config/mpv/input.conf
#
# Older installations use ~/.mpv/input.conf instead.
# changed in mpv 0.37.0
WHEEL_UP seek 10 # seek 10 seconds forward
WHEEL_DOWN seek -10 # seek 10 seconds backward
WHEEL_LEFT add volume -2
WHEEL_RIGHT add volume 2
# changed in mpv 0.27.0 (macOS and Wayland only)
# WHEEL_LEFT seek 5
# WHEEL_RIGHT seek -5
# changed in mpv 0.26.0
H cycle dvbin-channel-switch-offset up
K cycle dvbin-channel-switch-offset down
I show-text "${filename}" # display filename in osd
# changed in mpv 0.24.0
L cycle-values loop-playlist "inf" "no"
# changed in mpv 0.10.0
O osd
D cycle deinterlace
d cycle framedrop
# changed in mpv 0.7.0
ENTER playlist-next force
# changed in mpv 0.6.0
ESC quit
# changed in mpv 0.5.0
PGUP seek 600
PGDWN seek -600
RIGHT seek 10
LEFT seek -10
+ add audio-delay 0.100
- add audio-delay -0.100
F cycle sub-forced-events-only
U stop
o cycle-values osd-level
@@ -0,0 +1,41 @@
# This file contains all bindings that were removed or changed
# after a certain release.
# Pick the bindings you want back and add them to your own osc.conf. Append
# this file to your osc.conf if you want them all back:
#
# cat restore-osc-bindings.conf >> ~/.config/mpv/script-opts/osc.conf
# changed in mpv 0.40.0
# previously unbound
title_mbtn_mid_command=
play_pause_mbtn_mid_command=
play_pause_mbtn_right_command=
fullscreen_mbtn_right_command=
volume_mbtn_right_command=
# restore playlist_osd=yes behavior
playlist_prev_mbtn_left_command=playlist-prev; show-text ${playlist} 3000
playlist_next_mbtn_left_command=playlist-next; show-text ${playlist} 3000
# restore chapter_osd=yes behavior
chapter_prev_mbtn_left_command=no-osd add chapter -1; show-text ${chapter-list} 3000
chapter_next_mbtn_left_command=no-osd add chapter 1; show-text ${chapter-list} 3000
# restore behavior before select.lua usage
playlist_prev_mbtn_right_command=show-text ${playlist} 3000
playlist_next_mbtn_right_command=show-text ${playlist} 3000
title=${media-title}
title_mbtn_left_command=show-text "${!playlist-count==1:[${playlist-pos-1}/${playlist-count}] }${media-title}"
title_mbtn_right_command=show-text ${filename}
chapter_prev_mbtn_right_command=show-text ${chapter-list} 3000
chapter_next_mbtn_right_command=show-text ${chapter-list} 3000
audio_track_mbtn_right_command=cycle audio down
audio_track_mbtn_mid_command=show-text ${track-list/audio} 3000
sub_track_mbtn_right_command=cycle sub down
sub_track_mbtn_mid_command=show-text ${track-list/sub} 3000
+656
View File
@@ -0,0 +1,656 @@
This file intends to give a big picture overview of how mpv is structured.
player/*.c:
Essentially makes up the player applications, including the main() function
and the playback loop.
Generally, it accesses all other subsystems, initializes them, and pushes
data between them during playback.
The structure is as follows (as of commit e13c05366557cb):
* main():
* basic initializations (e.g. init_libav() and more)
* pre-parse command line (verbosity level, config file locations)
* load config files (mp_parse_cfgfiles())
* parse command line, add files from the command line to playlist
(m_config_parse_mp_command_line())
* check help options etc. (call handle_help_options()), possibly exit
* call mp_play_files() function that works down the playlist:
* run idle loop (idle_loop()), until there are files in the
playlist or an exit command was given (only if --idle it set)
* actually load and play a file in play_current_file():
* run all the dozens of functions to load the file and
initialize playback
* run a small loop that does normal playback, until the file is
done or a command terminates playback
(on each iteration, run_playloop() is called, which is rather
big and complicated - it decodes some audio and video on
each frame, waits for input, etc.)
* uninitialize playback
* determine next entry on the playlist to play
* loop, or exit if no next file or quit is requested
(see enum stop_play_reason)
* call mp_destroy()
* run_playloop():
* calls fill_audio_out_buffers()
This checks whether new audio needs to be decoded, and pushes it
to the AO.
* calls write_video()
Decode new video, and push it to the VO.
* determines whether playback of the current file has ended
* determines when to start playback after seeks
* and calls a whole lot of other stuff
(Really, this function does everything.)
Things worth saying about the playback core:
- most state is in MPContext (core.h), which is not available to the
subsystems (and should not be made available)
- the currently played tracks are in mpctx->current_track, and decoder
state in track.dec/d_sub
- the other subsystems rarely call back into the frontend, and the frontend
polls them instead (probably a good thing)
- one exceptions are wakeup callbacks, which notify a "higher" component
of a changed situation in a subsystem
I like to call the player/*.c files the "frontend".
ta.h & ta.c:
Hierarchical memory manager inspired by talloc from Samba. It's like a
malloc() with more features. Most importantly, each talloc allocation can
have a parent, and if the parent is free'd, all children will be free'd as
well. The parent is an arbitrary talloc allocation. It's either set by the
allocation call by passing a talloc parent, usually as first argument to the
allocation function. It can also be set or reset later by other calls (at
least talloc_steal()). A talloc allocation that is used as parent is often
called a talloc context.
One very useful feature of talloc is fast tracking of memory leaks. ("Fast"
as in it doesn't require valgrind.) You can enable it by setting the
MPV_LEAK_REPORT environment variable to "1":
export MPV_LEAK_REPORT=1
This will list all unfree'd allocations on exit.
Documentation can be found here:
http://git.samba.org/?p=samba.git;a=blob;f=lib/talloc/talloc.h;hb=HEAD
For some reason, we're still using API-compatible wrappers instead of TA
directly. The talloc wrapper has only a subset of the functionality, and
in particular the wrappers abort() on memory allocation failure.
Note: unlike tcmalloc, jemalloc, etc., talloc() is not actually a malloc
replacement. It works on top of system malloc and provides additional
features that are supposed to make memory management easier.
player/command.c:
This contains the implementation for client API commands and properties.
Properties are essentially dynamic variables changed by certain commands.
This is basically responsible for all user commands, like initiating
seeking, switching tracks, etc. It calls into other player/*.c files,
where most of the work is done, but also calls other parts of mpv.
player/core.h:
Data structures and function prototypes for most of player/*.c. They are
usually not accessed by other parts of mpv for the sake of modularization.
player/client.c:
This implements the client API (mpv/client.h). For the most part, this
just calls into other parts of the player. This also manages a ringbuffer
of events from player to clients.
options/options.h, options/options.c
options.h contains the global option struct MPOpts. The option declarations
(option names, types, and MPOpts offsets for the option parser) are in
options.c. Most default values for options and MPOpts are in
mp_default_opts at the end of options.c.
MPOpts is unfortunately quite monolithic, but is being incrementally broken
up into sub-structs. Many components have their own sub-option structs
separate from MPOpts. New options should be bound to the component that uses
them. Add a new option table/struct if needed.
The global MPOpts still contains the sub-structs as fields, which serves to
link them to the option parser. For example, an entry like this may be
typical:
{"", OPT_SUBSTRUCT(demux_opts, demux_conf)},
This directs the option access code to include all options in demux_conf
into the global option list, with no prefix (""), and as part of the
MPOpts.demux_opts field. The MPOpts.demux_opts field is actually not
accessed anywhere, and instead demux.c does this:
struct m_config_cache *opts_cache =
m_config_cache_alloc(demuxer, global, &demux_conf);
struct demux_opts *opts = opts_cache->opts;
... to get a copy of its options.
See m_config_core.h (below) how to access options.
The actual option parser is spread over m_option.c, m_config_frontend.c,
and parse_commandline.c, and uses the option table in options.c.
options/m_config_*.h & m_config_*.c:
Code for querying and managing options. m_config_frontend.h contains
declarations for the "legacy-ish" global m_config struct, while
m_config_core.h provides ways to access options in a threads-safe way
anywhere, like m_config_cache_alloc().
m_config_cache_alloc() lets anyone read, observe, and write options in any
thread. The only state it needs is struct mpv_global, which is an opaque
type that can be passed "down" the component hierarchy. For safety reasons,
you should not pass down any pointers to option structs (like MPOpts), but
instead pass down mpv_global, and use m_config_cache_alloc() (or similar)
to get a synchronized copy of the options.
input/input.c:
This translates keyboard input coming from VOs and other sources (such
as remote control devices like Apple IR or client API commands) to the
key bindings listed in the user's (or the builtin) input.conf and turns
them into items of type struct mp_cmd. These commands are queued, and read
by playloop.c. They get pushed with run_command() to command.c.
Note that keyboard input and commands used by the client API are the same.
The client API only uses the command parser though, and has its own queue
of input commands somewhere else.
common/msg.h:
All terminal output must go through mp_msg().
stream/*:
File input is implemented here. stream.h/.c provides a simple stream based
interface (like reading a number of bytes at a given offset). mpv can
also play from http streams and such, which is implemented here.
E.g. if mpv sees "http://something" on the command line, it will pick
stream_lavf.c based on the prefix, and pass the rest of the filename to it.
Some stream inputs are quite special: stream_dvdnav.c turns DVDs into mpeg
streams (DVDs are actually a bunch of vob files etc. on a filesystem),
Some stream inputs are just there to invoke special demuxers, like
stream_mf.c. (Basically to make the prefix "mf://" do something special.)
demux/:
Demuxers split data streams into audio/video/sub streams, which in turn
are split in packets. Packets (see packet.h) are mostly byte chunks
tagged with a playback time (PTS). These packets are passed to the decoders.
Most demuxers have been removed from this fork, and the only important and
"actual" demuxers left are demux_mkv.c and demux_lavf.c (uses libavformat).
There are some pseudo demuxers like demux_cue.c.
The main interface is in demux.h. The stream headers are in stheader.h.
There is a stream header for each audio/video/sub stream, and each of them
holds codec information about the stream and other information.
demux.c is a bit big, the main reason being that it contains the demuxer
cache, which is implemented as a list of packets. The cache is complex
because it support seeking, multiple ranges, prefetching, and so on.
filters/:
Filter related code. filter.c contains the generic filtering framework
which converts input frames to output frames (audio, video, or demux
packet data). f_decoder_wrapper.c is a source filter which connects the
frontend with the actual audio and video decoders. f_output_chain.c handles
VO/AO output conversions. f_autoconvert.c automatically inserts the
appropriate conversion filters if format conversion is needed.
video/:
This contains several things related to audio/video decoding, as well as
video filters.
mp_image.h and img_format.h define how mpv stores decoded video frames
internally.
video/decode/:
vd_*.c are video decoders. (There's only vd_lavc.c left.)
video/filter/:
vf_*.c are video filters. They are fed by the video decoder, and output the
filtered images to the VOs. By default, no video filters are used.
video/out/:
Video output. They also create GUI windows and handle user input. In most
cases, the windowing code is shared among VOs, like x11_common.c for X11 and
w32_common.c for Windows. The VOs stand between frontend and windowing code.
vo_gpu and vo_gpu_next can pick a windowing system at runtime, e.g. the same
binary can provide both X11 and Cocoa support on macOS.
VOs can be reconfigured at runtime. A vo_reconfig() call can change the video
resolution and format, without destroying the window.
vo_gpu should be taken as reference.
audio/:
format.h/format.c define the uncompressed audio formats. (As well as some
compressed formats used for spdif.)
audio/decode/:
ad_*.c handle audio decoding. ad_lavc.c is the decoder using ffmpeg.
ad_spdif.c is not really a decoder, but is used for compressed audio
passthrough.
audio/filter/:
Audio filters. af_scaletempo2 is inserted by default if playback is different
from normal speed.
audio/out/:
Audio outputs.
Unlike VOs, AOs can't be reconfigured on a format change. On audio format
changes, the AO will simply be closed and re-opened.
buffer.c is the wrapper to support for two types of audio APIs: push and
pull. ao.c calls into that. It contains generic code to deal with the data
flow these APIs impose.
Note that mpv synchronizes the video to the audio. That's the reason
why buggy audio drivers can have a bad influence on playback quality.
sub/:
Contains subtitle and OSD rendering.
osd.c/.h is actually the OSD code. It queries dec_sub.c to retrieve
decoded/rendered subtitles. osd_libass.c is the actual implementation of
the OSD text renderer (which uses libass, and takes care of all the tricky
fontconfig/freetype API usage and text layouting).
The VOs call osd.c to render OSD and subtitle (via e.g. osd_draw()). osd.c
in turn asks dec_sub.c for subtitle overlay bitmaps, which relays the
request to one of the sd_*.c subtitle decoders/renderers.
Subtitle loading is in demux/. Normally, subtitles are loaded via demux_lavf.c.
The subtitles are passed to dec_sub.c and the subtitle decoders in sd_*.c
as they are demuxed. All text subtitles are rendered by sd_ass.c. If text
subtitles are not in the ASS format, the libavcodec subtitle converters are
used (lavc_conv.c).
Text subtitles can be preloaded, in which case they are read fully as soon
as the subtitle is selected. In this case, they are effectively stored in
sd_ass.c's internal state.
etc/:
The files input.conf and builtin.conf are actually integrated into the mpv
binary by the build system. They contain the default configs and keybindings.
Best practices and Concepts within mpv
======================================
General contribution etc.
-------------------------
See: DOCS/contribute.md
Error checking
--------------
If an error is relevant, it should be handled. If it's interesting, log the
error. However, mpv often keeps errors silent and reports failures somewhat
coarsely by propagating them upwards the caller chain. This is OK, as long as
the errors are not very interesting, or would require a developer to debug it
anyway (in which case using a debugger would be more convenient, and the
developer would need to add temporary debug printfs to get extremely detailed
information which would not be appropriate during normal operation).
Basically, keep a balance on error reporting. But always check them, unless you
have a good argument not to.
Memory allocation errors (OOM) are a special class of errors. Normally such
allocation failures are not handled "properly". Instead, abort() is called.
(New code should use MP_HANDLE_OOM() for this.) This is done out of laziness and
for convenience, and due to the fact that MPlayer/mplayer2 never handled it
correctly. (MPlayer varied between handling it correctly, trying to do so but
failing, and just not caring, while mplayer2 started using abort() for it.)
This is justifiable in a number of ways. Error handling paths are notoriously
untested and buggy, so merely having them won't make your program more reliable.
Having these error handling paths also complicates non-error code, due to the
need to roll back state at any point after a memory allocation.
Take any larger body of code, that is supposed to handle OOM, and test whether
the error paths actually work, for example by overriding malloc with a version
that randomly fails. You will find bugs quickly, and often they will be very
annoying to fix (if you can even reproduce them).
In addition, a clear indication that something went wrong may be missing. On
error your program may exhibit "degraded" behavior by design. Consider a video
encoder dropping frames somewhere in the middle of a video due to temporary
allocation failures, instead of just exiting with an errors. In other cases, it
may open conceptual security holes. Failing fast may be better.
mpv uses GPU APIs, which may be break on allocation errors (because driver
authors will have the same issues as described here), or don't even have a real
concept for dealing with OOM (OpenGL).
libmpv is often used by GUIs, which I predict always break if OOM happens.
Last but not least, OSes like Linux use "overcommit", which basically means that
your program may crash any time OOM happens, even if it doesn't use malloc() at
all!
But still, don't just assume malloc() always succeeds. Use MP_HANDLE_OOM(). The
ta* APIs do this for you. The reason for this is that dereferencing a NULL
pointer can have security relevant consequences if large offsets are involved.
Also, a clear error message is better than a random segfault.
Some big memory allocations are checked anyway. For example, all code must
assume that allocating video frames or packets can fail. (The above example
of dropping video frames during encoding is entirely possible in mpv.)
Undefined behavior
------------------
Undefined behavior (UB) is a concept in the C language. C is famous for being a
language that makes it almost impossible to write working code, because
undefined behavior is so easily triggered, compilers will happily abuse it to
generate "faster" code, debugging tools will shout at you, and sometimes it
even means your code doesn't work.
There is a lot of literature on this topic. Read it.
(In C's defense, UB exists in other languages too, but since they're not used
for low level infrastructure, and/or these languages are at times not rigorously
defined, simply nobody cares. However, the C standard committee is still guilty
for not addressing this. I'll admit that I can't even tell from the standard's
gibberish whether some specific behavior is UB or not. It's written like tax
law.)
In mpv, we generally try to avoid undefined behavior. For one, we want portable
and reliable operation. But more importantly, we want clean output from
debugging tools, in order to find real bugs more quickly and effectively.
Avoid the "works in practice" argument. Once debugging tools come into play, or
simply when "in practice" stops being true, this will all get back to you in a
bad way.
Global state, library safety
----------------------------
Mutable global state is when code uses global variables that are not read-only.
This must be avoided in mpv. Always use context structs that the caller of
your code needs to allocate, and whose pointers are passed to your functions.
Library safety means that your code (or library) can be used by a library
without causing conflicts with other library users in the same process. To any
piece of code, a "safe" library's API can simply be used, without having to
worry about other API users that may be around somewhere.
Libraries are often not library safe, because they use global mutable state
or other "global" resources. Typical examples include use of signals, simple
global variables (like hsearch() in libc), or internal caches not protected by
locks.
A surprisingly high number of libraries are not library safe because they need
global initialization. Typically they provide an API function, which
"initializes" the library, and which must be called before calling any other
API functions. Often, you are to provide global configuration parameters, which
can change the behavior of the library. If two libraries A and B use library C,
but A and B initialize C with different parameters, something "bad" may happen.
In addition, these global initialization functions are often not thread-safe. So
if A and B try to initialize C at the same time (from different threads and
without knowing about each other), it may cause undefined behavior. (libcurl is
a good example of both of these issues. FFmpeg and some TLS libraries used to be
affected, but improved.)
This is so bad because library A and B from the previous example most likely
have no way to cooperate, because they're from different authors and have no
business knowing each others. They'd need a library D, which wraps library C
in a safe way. Unfortunately, typically something worse happens: libraries get
"infected" by the unsafeness of its sub-libraries, and export a global init API
just to initialize the sub-libraries. In the previous example, libraries A and B
would export global init APIs just to init library C, even though the rest of
A/B are clean and library safe. (Again, libcurl is an example of this, if you
subtract other historic anti-features.)
The main problem with library safety is that its lack propagates to all
libraries using the library.
We require libmpv to be library safe. This is not really possible, because some
libraries are not library safe (FFmpeg, Xlib, partially ALSA). However, for
ideological reasons, there is no global init API, and best effort is made to try
to avoid problems.
libmpv has some features that are not library safe, but which are disabled by
default (such as terminal usage aka stdout, or JSON IPC blocking SIGPIPE for
internal convenience).
A notable, very disgustingly library unsafe behavior of libmpv is calling
abort() on some memory allocation failure. See error checking section.
Logging
-------
All logging and terminal output in mpv goes through the functions and macros
provided in common/msg.h. This is in part for library safety, and in part to
make sure users can silence all output, or to redirect the output elsewhere,
like a log file or the internal console.lua script.
Locking
-------
See generally available literature. In mpv, we use mp_thread for this.
Always keep locking clean. Don't skip locking just because it will work "in
practice". (See undefined behavior section.) If your use case is simple, you may
use C11 atomics, but most likely you will only hurt yourself and others.
Always make clear which fields in a struct are protected by which lock. If a
field is immutable, or simply not thread-safe (e.g. state for a single worker
thread), document it as well.
Internal mpv APIs are assumed to be not thread-safe by default. If they have
special guarantees (such as being usable by more than one thread at a time),
these should be explicitly documented.
All internal mpv APIs must be free of global state. Even if a component is not
thread-safe, multiple threads can use _different_ instances of it without any
locking.
On a side note, recursive locks may seem convenient at first, but introduce
additional problems with condition variables and locking hierarchies. They
should be avoided.
Locking hierarchy
-----------------
A simple way to avoid deadlocks with classic locking is to define a locking
hierarchy or lock order. If all threads acquire locks in the same order, no
deadlocks will happen.
For example, a "leaf" lock is a lock that is below all other locks in the
hierarchy. You can acquire it any time, as long as you don't acquire other
locks while holding it.
Unfortunately, C has no way to declare or check the lock order, so you should at
least document it.
In addition, try to avoid exposing locks to the outside. Making the declaration
of a lock private to a specific .c file (and _not_ exporting accessors or
lock/unlock functions that manipulate the lock) is a good idea. Your component's
API may acquire internal locks, but should release them when returning. Keeping
the entire locking in a single file makes it easy to check it.
Avoiding callback hell
----------------------
mpv code is separated in components, like the "frontend" (i.e. MPContext mpctx),
VOs, AOs, demuxers, and more. The frontend usually calls "down" the usage
hierarchy: mpctx almost on top, then things like vo/ao, and utility code on the
very bottom.
"Callback hell" is when components call both up and down the hierarchy,
which for example leads to accidentally recursion, reentrancy problems, or
locking nightmares. This is avoided by (mostly) calling only down the hierarchy.
Basically the call graph forms a DAG. The other direction is handled by event
queues, wakeup callbacks, and similar mechanisms.
Typically, a component provides an API, and does not know anything about its
user. The API user (component higher in the hierarchy) polls the state of the
lower component when needed.
This also enforces some level of modularization, and with some luck the locking
hierarchy. (Basically, locks of lower components automatically become leaf
locks.) Another positive effect is simpler memory management.
(Also see e.g.: http://250bpm.com/blog:24)
Wakeup callbacks
----------------
This is a common concept in mpv. Even the public API uses it. It's used when an
API has internal threads (or otherwise triggers asynchronous events), but the
component call hierarchy needs to be kept. The wakeup callback is the only
exception to the call hierarchy, and always calls up.
For example, vo spawns a thread that the API user (the mpv frontend) does not
need to know about. vo simply provides a single-threaded API (or that looks like
one). This API needs a way to notify the API user of new events. But the vo
event producer is on the vo thread - it can't simply invoke a callback back into
the API user, because then the API user has to deal with locking, despite not
using threads. In addition, this will probably cause problems like mentioned in
the "callback hell" section, especially lock order issues.
The solution is the wakeup callback. It merely unblocks the API user from
waiting, and the API user then uses the normal vo API to examine whether or
which state changed. As a concept, it documents what a wakeup callback is
allowed to do and what not, to avoid the aforementioned problems.
Generally, you are not allowed to call any API from the wakeup callback. You
just do whatever is needed to unblock your thread. For example, if it's waiting
on a mutex/condition variable, acquire the mutex, set a change flag, signal
the condition variable, unlock, return. (This mutex must not be held when
calling the API. It must be a leaf lock.)
Restricting the wakeup callback like this sidesteps any reentrancy issues and
other complexities. The API implementation can simply hold internal (and
non-recursive) locks while invoking the wakeup callback.
The API user still needs to deal with locking (probably), but there's only the
need to implement a single "receiver", that can handle the entire API of the
used component. (Or multiple APIs - MPContext for example has only 1 wakeup
callback that handles all AOs, VOs, input, demuxers, and more. It simple re-runs
the playloop.)
You could get something more advanced by turning this into a message queue. The
API would append a message to the queue, and the API user can read it. But then
you still need a way to "wakeup" the API user (unless you force the API user
to block on your API, which will make things inconvenient for the API user). You
also need to worry about what happens if the message queue overruns (you either
lose messages or have unbounded memory usage). In the mpv public API, the
distinction between message queue and wakeup callback is sort of blurry, because
it does provide a message queue, but an additional wakeup callback, so API
users are not required to call mpv_wait_event() with a high timeout.
mpv itself prefers using wakeup callbacks over a generic event queue, because
most times an event queue is not needed (or complicates things), and it is
better to do it manually.
(You could still abstract the API user side of wakeup callback handling, and
avoid reimplementing it all the time. Although mp_dispatch_queue already
provides mechanisms for this.)
Condition variables
-------------------
They're used whenever a thread needs to wait for something, without nonsense
like sleep calls or busy waiting. mpv uses the mp_thread API for this.
There's a lot of literature on condition variables, threading in general. Read it.
For initial understanding, it may be helpful to know that condition variables
are not variables that signal a condition. mp_cond does not have any
state per-se. Maybe mp_cond would better be named mp_interrupt,
because its sole purpose is to interrupt a thread waiting via mp_cond_wait()
(or similar). The "something" in "waiting for something" can be called
predicate (to avoid confusing it with "condition"). Consult literature for the
proper terms.
The very short version is...
Shared declarations:
mp_mutex lock;
mp_cond cond_var;
struct something state_var; // protected by lock, changes signaled by cond_var
Waiter thread:
mp_mutex_lock(&lock);
// Wait for a change in state_var. We want to wait until predicate_fulfilled()
// returns true.
// Must be a loop for 2 reasons:
// 1. cond_var may be associated with other conditions too
// 2. mp_cond_wait() can have sporadic wakeups
while (!predicate_fulfilled(&state_var)) {
// This unlocks, waits for cond_var to be signaled, and then locks again.
// The _whole_ point of cond_var is that unlocking and waiting for the
// signal happens atomically.
mp_cond_wait(&cond_var, &lock);
}
// Here you may react to the state change. The state cannot change
// asynchronously as long as you still hold the lock (and didn't release
// and reacquire it).
// ...
mp_mutex_unlock(&lock);
Signaler thread:
mp_mutex_lock(&lock);
// Something changed. Update the shared variable with the new state.
update_state(&state_var);
// Notify that something changed. This will wake up the waiter thread if
// it's blocked in mp_cond_wait(). If not, nothing happens.
mp_cond_broadcast(&cond_var);
// Fun fact: good implementations wake up the waiter only when the lock is
// released, to reduce kernel scheduling overhead.
mp_mutex_unlock(&lock);
Some basic rules:
1. Always access your state under proper locking
2. Always check your predicate before every call to mp_cond_wait()
(And don't call mp_cond_wait() if the predicate is fulfilled.)
3. Always call mp_cond_wait() in a loop
(And only if your predicate failed without releasing the lock..)
4. Always call mp_cond_broadcast()/_signal() inside of its associated
lock
mpv sometimes violates rule 3, and leaves "retrying" (i.e. looping) to the
caller.
Common pitfalls:
- Thinking that mp_cond is some kind of semaphore, or holds any
application state or the user predicate (it _only_ wakes up threads
that are at the same time blocking on mp_cond_wait() and friends,
nothing else)
- Changing the predicate, but not updating all mp_cond_broadcast()/
_signal() calls correctly
- Forgetting that mp_cond_wait() unlocks the lock (other threads can
and must acquire the lock)
- Holding multiple nested locks while trying to wait (=> deadlock, violates
the lock order anyway)
- Waiting for a predicate correctly, but unlocking/relocking before acting
on it (unlocking allows arbitrary state changes)
- Confusing which lock/condition var. is used to manage a bit of state
Generally available literature probably has better examples and explanations.
Using condition variables the proper way is generally preferred over using more
messy variants of them. (Just saying because on win32, "SetEvent" exists, and
it's inferior to condition variables. Try to avoid the win32 primitives, even if
you're dealing with Windows-only code.)
Threads
-------
Threading should be conservatively used. Normally, mpv code pretends to be
single-threaded, and provides thread-unsafe APIs. Threads are used coarsely,
and if you can avoid messing with threads, you should. For example, VOs and AOs
do not need to deal with threads normally, even though they run on separate
threads. The glue code "isolates" them from any threading issues.
+30
View File
@@ -1,2 +1,32 @@
[Appearance]
color_scheme_path=/home/frank/.config/qt5ct/colors/catppuccin-mocha-blue.conf
custom_palette=true
icon_theme=Papirus-Dark
standard_dialogs=xdgdesktopportal
style=Darkly
[Fonts]
fixed="FiraMono Nerd Font,13,-1,5,50,0,0,0,0,0,Regular"
general="Inter,13,-1,5,50,0,0,0,0,0,Regular"
[Interface]
activate_item_on_single_click=1
buttonbox_layout=0
cursor_flash_time=1000
dialog_buttons_have_icons=2
double_click_interval=400
gui_effects=@Invalid()
keyboard_scheme=2
menus_have_icons=true
show_shortcuts_in_context_menus=true
stylesheets=@Invalid()
toolbutton_style=4
underline_shortcut=2
wheel_scroll_lines=3
[SettingsWindow]
geometry=@ByteArray(\x1\xd9\xd0\xcb\0\x3\0\0\0\0\0\0\0\0\0\0\0\0\x5?\0\0\x5\x43\0\0\0\0\0\0\0\0\0\0\x6\xb7\0\0\x5\x9f\0\0\0\0\x2\0\0\0\rp\0\0\0\0\0\0\0\0\0\0\x5?\0\0\x5\x43)
[Troubleshooting]
force_raster_widgets=1
ignored_applications=@Invalid()
+30 -3
View File
@@ -1,5 +1,32 @@
[SettingsWindow]
geometry=@ByteArray(\x1\xd9\xd0\xcb\0\x3\0\0\0\0\0\0\0\0\0\0\0\0\x4\x13\0\0\x2l\0\0\0\0\0\0\0\0\0\0\x4\x13\0\0\x2l\0\0\0\x1\x2\0\0\0\rp\0\0\0\0\0\0\0\0\0\0\x4\x13\0\0\x2l)
[Appearance]
color_scheme_path=/home/frank/.config/qt6ct/colors/catppuccin-mocha-blue.conf
custom_palette=true
icon_theme=Papirus-Dark
standard_dialogs=xdgdesktopportal
style=Darkly
[Fonts]
fixed="FiraMono Nerd Font,13,-1,5,400,0,0,0,0,0,0,0,0,0,0,1,,0,0"
general="Inter,13,-1,5,400,0,0,0,0,0,0,0,0,0,0,1,,0,0"
[Interface]
activate_item_on_single_click=1
buttonbox_layout=2
cursor_flash_time=1200
dialog_buttons_have_icons=2
double_click_interval=400
gui_effects=@Invalid()
keyboard_scheme=2
menus_have_icons=true
show_shortcuts_in_context_menus=true
stylesheets=@Invalid()
toolbutton_style=4
underline_shortcut=2
wheel_scroll_lines=3
[SettingsWindow]
geometry=@ByteArray(\x1\xd9\xd0\xcb\0\x3\0\0\0\0\0\0\0\0\0\0\0\0\x5?\0\0\x5\x43\0\0\0\0\0\0\0\0\0\0\x5?\0\0\x5\x43\0\0\0\0\x2\0\0\0\rp\0\0\0\0\0\0\0\0\0\0\x5?\0\0\x5\x43)
[Troubleshooting]
force_raster_widgets=1
ignored_applications=@Invalid()
@@ -0,0 +1,12 @@
#!/bin/bash
action=$(wofi --cache-file=/dev/null --dmenu << EOF
󰅛 Restart Network
EOF
)
case "$action" in
"󰅛 Restart Network")
~/.config/scripts/restart_network.sh
;;
esac
@@ -0,0 +1,6 @@
#!/bin/bash
PCIE_ADAPTER_SUFFIX=$(lspci | grep I225 | cut -d' ' -f1)
PCIE_ADAPTER_ADDRESS=$(ls -1 /sys/bus/pci/devices | grep "${PCIE_ADAPTER_SUFFIX}")
pkexec bash -c "echo 1 > /sys/bus/pci/devices/${PCIE_ADAPTER_ADDRESS}/remove; echo 1 > /sys/bus/pci/rescan"
+1
View File
@@ -1,2 +1,3 @@
export XCURSOR_THEME="Breeze_Light"
export XCURSOR_SIZE="24"
export QT_QPA_PLATFORMTHEME="qt6ct"
+1
View File
@@ -1,2 +1,3 @@
export HYPRCURSOR_THEME="Breeze_Light"
export HYPRCURSOR_SIZE="24"
export QT_QPA_PLATFORMTHEME="qt6ct"
@@ -0,0 +1,41 @@
# SPDIF devices
monitor.alsa.rules = [
{
matches = [
{
# Matches all sources
node.name = "~alsa_input.*"
},
{
# Matches all sinks
node.name = "~alsa_output.*"
}
]
actions = {
update-props = {
session.suspend-timeout-seconds = 0
}
}
}
]
# bluetooth devices
monitor.bluez.rules = [
{
matches = [
{
# Matches all sources
node.name = "~bluez_input.*"
},
{
# Matches all sinks
node.name = "~bluez_output.*"
}
]
actions = {
update-props = {
session.suspend-timeout-seconds = 0
}
}
}
]
+32
View File
@@ -0,0 +1,32 @@
show=drun
width=600
height=300
location=center
columns=1
prompt=Application
allow_images=true
image_size=24
allow_markup=true
hide_scroll=true
parse_search=true
term=kitty
matching=contains
insensitive=true
dmenu-parse_action=true
run-always_parse_args=true
run-show_all=false
drun-disable_prime=true
drun-display_generic=false
key_up=Ctrl-k
key_down=Ctrl-j
key_left=Ctrl-h
key_right=Ctrl-l
key_pgup=Ctrl-u
key_pgdown=Ctrl-d
key_expand=Ctrl-e
+132
View File
@@ -0,0 +1,132 @@
/* MACHHIATO */
@define-color rosewater #f4dbd6;
@define-color flamingo #f0c6c6;
@define-color pink #f5bde6;
@define-color mauve #c6a0f6;
@define-color red #ed8796;
@define-color maroon #ee99a0;
@define-color peach #f5a97f;
@define-color yellow #eed49f;
@define-color green #a6da95;
@define-color teal #8bd5ca;
@define-color sky #91d7e3;
@define-color sapphire #7dc4e4;
@define-color blue #8aadf4;
@define-color lavender #b7bdf8;
@define-color text #cad3f5;
@define-color subtext1 #b8c0e0;
@define-color subtext0 #a5adcb;
@define-color overlay2 #939ab7;
@define-color overlay1 #8087a2;
@define-color overlay0 #6e738d;
@define-color surface2 #5b6078;
@define-color surface1 #494d64;
@define-color surface0 #363a4f;
@define-color base #24273a;
@define-color mantle #1e2030;
@define-color crust #181926;
* {
font-family: 'Noto Sans Nerd Font', 'FiraMono Nerd Font', 'FiraCode Nerd Font Mono', 'RobotoMono Nerd Font Propo', monospace;
font-size: 14px;
outline: none;
}
window {
margin: 0px;
padding: 7px;
border: 2px solid @yellow;
border-radius: 0px;
background-color: @crust;
}
#outer-box {
margin : 17px;
}
#input {
background-color : @surface0;
color : @text;
border-radius : 0;
padding: 2px 0px;
margin-bottom : 17px;
}
#input:focus {
box-shadow: none;
}
#input image {
color: @yellow;
padding: 0 7px;
}
#scroll {
border: none;
}
/* First Level Entries */
#inner-box > #entry {
border-radius : 0;
border: 1px solid @mantle;
background-color : @mantle;
color: @text;
padding : 7px;
padding-left : 22px;
}
#inner-box > #entry:nth-child(odd) {
background-color : @base;
}
#inner-box > #entry:selected {
background-color: @surface1;
color: @blue;
border: 1px solid @yellow;
}
#inner-box > #entry:selected #text {
color: @blue;
}
#inner-box > #entry expander #entry {
border-radius : 0;
border: none;
color: @text;
padding : 2px;
background-color : @mantle;
padding-left: 17px;
}
#inner-box > #entry:nth-child(odd) expander #entry {
background-color : @base;
}
#inner-box > #entry:selected expander #entry {
background-color : @surface1;
}
#inner-box > #entry:selected expander #entry #text {
color: @text;
}
#inner-box > #entry:selected expander #entry:selected {
background-color: @surface2;
}
#inner-box > #entry:selected expander #entry:selected #text {
color: @yellow;
}
#text {
border: none;
color: @text;
margin-left : 12px;
}
#entry arrow {
margin-left : -17px;
color: @text;
margin-right : 2px;
}