aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAbdus <abdus@abdus.net>2021-02-20 10:31:09 +0530
committerAbdus <abdus@abdus.net>2021-02-20 10:31:09 +0530
commit78797bc5e6d0aa29adb983dec18b95993f468964 (patch)
treeeb8e7c6e2968862296312e039510ca5105d43739
parent47a1215dc61242f0ef04f8b48c84877e9b6da0f2 (diff)
downloaddotfiles-78797bc5e6d0aa29adb983dec18b95993f468964.tar.bz2
dotfiles-78797bc5e6d0aa29adb983dec18b95993f468964.zip
:zap: automated updates
-rwxr-xr-xaggregate.sh6
-rw-r--r--awesome/rc.lua573
-rw-r--r--awesome/theme.lua135
-rw-r--r--mpv/encoding.rst155
-rw-r--r--mpv/input.conf194
-rw-r--r--mpv/mplayer-input.conf93
-rw-r--r--mpv/mpv.conf147
-rw-r--r--mpv/restore-old-bindings.conf61
-rw-r--r--mpv/tech-overview.txt657
-rw-r--r--mpv/watch_later/063DAEC803841EB7113A47FA3CECAED82
-rw-r--r--mpv/watch_later/1683D817BBC6E82BE119984C7CD7CE621
-rw-r--r--mpv/watch_later/259ABA88A08CB894944550AA228486692
-rw-r--r--mpv/watch_later/344170F291482DA4FBD322DE38400EAE1
-rw-r--r--mpv/watch_later/34D62D9163E6D92542DE17F52B5701161
-rw-r--r--mpv/watch_later/36FA3790081EBC3AF44BCAE5A52795F61
-rw-r--r--mpv/watch_later/3CF79AAAC15C73A8DFAA9C10D9B5B0A01
-rw-r--r--mpv/watch_later/487847FC7BB604E14B83758574B87EA23
-rw-r--r--mpv/watch_later/493B758B964204D5E80BE9B1D72BA27E1
-rw-r--r--mpv/watch_later/5561E0E59EDF8AA973A6E44D0E3AE48B1
-rw-r--r--mpv/watch_later/5C1E00E1E47E9A373A1F87DA46035BA31
-rw-r--r--mpv/watch_later/677EDF3B061976BEB66A39169FE0D27A0
-rw-r--r--mpv/watch_later/7B044A79775C002A6EE31A57B9BD0A001
-rw-r--r--mpv/watch_later/917B1861D498E15C1677BC9D24372EA92
-rw-r--r--mpv/watch_later/A9618E91E7A663A6906F5C861673BBB51
-rw-r--r--mpv/watch_later/AC58ECADDE9A134294955B55B2DDBE201
-rw-r--r--mpv/watch_later/AF3CC3CF42020DE14E050A555E7DB42C1
-rw-r--r--mpv/watch_later/D6526CC3419AD09A1C1EAFA7D509BBE01
-rw-r--r--mpv/watch_later/ED200CF84DE626FC1B96CFD87242E5CA1
-rw-r--r--mpv/watch_later/F107AE031822EF7A9FAA3B8A3ACC540A1
-rw-r--r--mpv/watch_later/F37DF3B4287319FEAF4A5337CD033E520
-rw-r--r--mpv/watch_later/FAAABC80E940CFB30C49FEEABA15012B3
-rw-r--r--sway/config6
-rw-r--r--vim/init.vim9
-rw-r--r--zsh/.zshrc2
34 files changed, 2061 insertions, 4 deletions
diff --git a/aggregate.sh b/aggregate.sh
index a637160..0822a52 100755
--- a/aggregate.sh
+++ b/aggregate.sh
@@ -14,6 +14,9 @@ function update_everything() {
# sway
rsync --out-format="%n" -La ~/.config/sway/* ./sway/
+ # awesome
+ rsync --out-format="%n" -La ~/.config/awesome/* ./awesome/
+
# waybar
rsync --out-format="%n" -a ~/.config/waybar/* ./waybar/
@@ -47,6 +50,9 @@ function update_everything() {
# kitty
rsync --out-format="%n" -La ~/.config/kitty/* ./kitty/
+ # mpv
+ rsync --out-format="%n" -La ~/.config/mpv/* ./mpv/
+
}
if [[ $COMMAND == "clean" ]]; then
diff --git a/awesome/rc.lua b/awesome/rc.lua
new file mode 100644
index 0000000..83da24b
--- /dev/null
+++ b/awesome/rc.lua
@@ -0,0 +1,573 @@
+-- If LuaRocks is installed, make sure that packages installed through it are
+-- found (e.g. lgi). If LuaRocks is not installed, do nothing.
+pcall(require, "luarocks.loader")
+
+-- Standard awesome library
+local gears = require("gears")
+local awful = require("awful")
+require("awful.autofocus")
+-- Widget and layout library
+local wibox = require("wibox")
+-- Theme handling library
+local beautiful = require("beautiful")
+-- Notification library
+local naughty = require("naughty")
+local menubar = require("menubar")
+local hotkeys_popup = require("awful.hotkeys_popup")
+-- Enable hotkeys help widget for VIM and other apps
+-- when client with a matching name is opened:
+require("awful.hotkeys_popup.keys")
+
+-- {{{ Error handling
+-- Check if awesome encountered an error during startup and fell back to
+-- another config (This code will only ever execute for the fallback config)
+if awesome.startup_errors then
+ naughty.notify({ preset = naughty.config.presets.critical,
+ title = "Oops, there were errors during startup!",
+ text = awesome.startup_errors })
+end
+
+-- Handle runtime errors after startup
+do
+ local in_error = false
+ awesome.connect_signal("debug::error", function (err)
+ -- Make sure we don't go into an endless error loop
+ if in_error then return end
+ in_error = true
+
+ naughty.notify({ preset = naughty.config.presets.critical,
+ title = "Oops, an error happened!",
+ text = tostring(err) })
+ in_error = false
+ end)
+end
+-- }}}
+
+-- {{{ Variable definitions
+-- Themes define colours, icons, font and wallpapers.
+beautiful.init(gears.filesystem.get_configuration_dir() .. "theme.lua")
+
+-- This is used later as the default terminal and editor to run.
+terminal = "xterm"
+editor = "nvim"
+editor_cmd = terminal .. " -e " .. editor
+
+-- Default modkey.
+-- Usually, Mod4 is the key with a logo between Control and Alt.
+-- If you do not like this or do not have such a key,
+-- I suggest you to remap Mod4 to another key using xmodmap or other tools.
+-- However, you can use another modifier like Mod1, but it may interact with others.
+modkey = "Mod4"
+
+-- Table of layouts to cover with awful.layout.inc, order matters.
+awful.layout.layouts = {
+ --awful.layout.suit.floating,
+ --awful.layout.suit.tile,
+ --awful.layout.suit.tile.left,
+ --awful.layout.suit.tile.bottom,
+ --awful.layout.suit.tile.top,
+ --awful.layout.suit.fair,
+ --awful.layout.suit.fair.horizontal,
+ awful.layout.suit.spiral,
+ --awful.layout.suit.spiral.dwindle,
+ --awful.layout.suit.max,
+ --awful.layout.suit.max.fullscreen,
+ --awful.layout.suit.magnifier,
+ --awful.layout.suit.corner.nw,
+ -- awful.layout.suit.corner.ne,
+ -- awful.layout.suit.corner.sw,
+ -- awful.layout.suit.corner.se,
+}
+-- }}}
+
+-- {{{ Menu
+-- Create a launcher widget and a main menu
+myawesomemenu = {
+ { "hotkeys", function() hotkeys_popup.show_help(nil, awful.screen.focused()) end },
+ { "manual", terminal .. " -e man awesome" },
+ { "edit config", editor_cmd .. " " .. awesome.conffile },
+ { "restart", awesome.restart },
+ { "quit", function() awesome.quit() end },
+}
+
+mymainmenu = awful.menu({ items = { { "awesome", myawesomemenu, beautiful.awesome_icon },
+ { "open terminal", terminal }
+ }
+ })
+
+mylauncher = awful.widget.launcher({ image = beautiful.awesome_icon,
+ menu = mymainmenu })
+
+-- Menubar configuration
+menubar.utils.terminal = terminal -- Set the terminal for applications that require it
+-- }}}
+
+-- Keyboard map indicator and switcher
+mykeyboardlayout = awful.widget.keyboardlayout()
+
+-- {{{ Wibar
+-- Create a textclock widget
+mytextclock = wibox.widget.textclock()
+
+-- Create a wibox for each screen and add it
+local taglist_buttons = gears.table.join(
+ awful.button({ }, 1, function(t) t:view_only() end),
+ awful.button({ modkey }, 1, function(t)
+ if client.focus then
+ client.focus:move_to_tag(t)
+ end
+ end),
+ awful.button({ }, 3, awful.tag.viewtoggle),
+ awful.button({ modkey }, 3, function(t)
+ if client.focus then
+ client.focus:toggle_tag(t)
+ end
+ end),
+ awful.button({ }, 4, function(t) awful.tag.viewnext(t.screen) end),
+ awful.button({ }, 5, function(t) awful.tag.viewprev(t.screen) end)
+ )
+
+local tasklist_buttons = gears.table.join(
+ awful.button({ }, 1, function (c)
+ if c == client.focus then
+ c.minimized = true
+ else
+ c:emit_signal(
+ "request::activate",
+ "tasklist",
+ {raise = true}
+ )
+ end
+ end),
+ awful.button({ }, 3, function()
+ awful.menu.client_list({ theme = { width = 250 } })
+ end),
+ awful.button({ }, 4, function ()
+ awful.client.focus.byidx(1)
+ end),
+ awful.button({ }, 5, function ()
+ awful.client.focus.byidx(-1)
+ end))
+
+local function set_wallpaper(s)
+ -- Wallpaper
+ if beautiful.wallpaper then
+ local wallpaper = beautiful.wallpaper
+ -- If wallpaper is a function, call it with the screen
+ if type(wallpaper) == "function" then
+ wallpaper = wallpaper(s)
+ end
+ gears.wallpaper.maximized(wallpaper, s, true)
+ end
+end
+
+-- Re-set wallpaper when a screen's geometry changes (e.g. different resolution)
+screen.connect_signal("property::geometry", set_wallpaper)
+
+awful.screen.connect_for_each_screen(function(s)
+ -- Wallpaper
+ set_wallpaper(s)
+
+ -- Each screen has its own tag table.
+ awful.tag({ "1", "2", "3", "4", "5", "6", "7", "8", "9" }, s, awful.layout.layouts[1])
+
+ -- Create a promptbox for each screen
+ s.mypromptbox = awful.widget.prompt()
+ -- Create an imagebox widget which will contain an icon indicating which layout we're using.
+ -- We need one layoutbox per screen.
+ s.mylayoutbox = awful.widget.layoutbox(s)
+ s.mylayoutbox:buttons(gears.table.join(
+ awful.button({ }, 1, function () awful.layout.inc( 1) end),
+ awful.button({ }, 3, function () awful.layout.inc(-1) end),
+ awful.button({ }, 4, function () awful.layout.inc( 1) end),
+ awful.button({ }, 5, function () awful.layout.inc(-1) end)))
+ -- Create a taglist widget
+ s.mytaglist = awful.widget.taglist {
+ screen = s,
+ filter = awful.widget.taglist.filter.all,
+ buttons = taglist_buttons
+ }
+
+ -- Create a tasklist widget
+ s.mytasklist = awful.widget.tasklist {
+ screen = s,
+ filter = awful.widget.tasklist.filter.currenttags,
+ buttons = tasklist_buttons
+ }
+
+ -- Create the wibox
+ s.mywibox = awful.wibar({ position = "top", screen = s })
+
+ -- Add widgets to the wibox
+ s.mywibox:setup {
+ layout = wibox.layout.align.horizontal,
+ { -- Left widgets
+ layout = wibox.layout.fixed.horizontal,
+ mylauncher,
+ s.mytaglist,
+ s.mypromptbox,
+ },
+ s.mytasklist, -- Middle widget
+ { -- Right widgets
+ layout = wibox.layout.fixed.horizontal,
+ mykeyboardlayout,
+ wibox.widget.systray(),
+ mytextclock,
+ s.mylayoutbox,
+ },
+ }
+end)
+-- }}}
+
+-- {{{ Mouse bindings
+root.buttons(gears.table.join(
+ awful.button({ }, 3, function () mymainmenu:toggle() end),
+ awful.button({ }, 4, awful.tag.viewnext),
+ awful.button({ }, 5, awful.tag.viewprev)
+))
+-- }}}
+
+-- {{{ Key bindings
+globalkeys = gears.table.join(
+ awful.key({ modkey, }, "s", hotkeys_popup.show_help,
+ {description="show help", group="awesome"}),
+ awful.key({ modkey, }, "Left", awful.tag.viewprev,
+ {description = "view previous", group = "tag"}),
+ awful.key({ modkey, }, "Right", awful.tag.viewnext,
+ {description = "view next", group = "tag"}),
+ awful.key({ modkey, }, "Escape", awful.tag.history.restore,
+ {description = "go back", group = "tag"}),
+
+ awful.key({ modkey, }, "j",
+ function ()
+ awful.client.focus.byidx( 1)
+ end,
+ {description = "focus next by index", group = "client"}
+ ),
+ awful.key({ modkey, }, "k",
+ function ()
+ awful.client.focus.byidx(-1)
+ end,
+ {description = "focus previous by index", group = "client"}
+ ),
+ awful.key({ modkey, }, "w", function () mymainmenu:show() end,
+ {description = "show main menu", group = "awesome"}),
+
+ -- Layout manipulation
+ awful.key({ modkey, "Shift" }, "j", function () awful.client.swap.byidx( 1) end,
+ {description = "swap with next client by index", group = "client"}),
+ awful.key({ modkey, "Shift" }, "k", function () awful.client.swap.byidx( -1) end,
+ {description = "swap with previous client by index", group = "client"}),
+ awful.key({ modkey, "Control" }, "j", function () awful.screen.focus_relative( 1) end,
+ {description = "focus the next screen", group = "screen"}),
+ awful.key({ modkey, "Control" }, "k", function () awful.screen.focus_relative(-1) end,
+ {description = "focus the previous screen", group = "screen"}),
+ awful.key({ modkey, }, "u", awful.client.urgent.jumpto,
+ {description = "jump to urgent client", group = "client"}),
+ awful.key({ modkey, }, "Tab",
+ function ()
+ awful.client.focus.history.previous()
+ if client.focus then
+ client.focus:raise()
+ end
+ end,
+ {description = "go back", group = "client"}),
+
+ -- Standard program
+ awful.key({ modkey, }, "Return", function () awful.spawn(terminal) end,
+ {description = "open a terminal", group = "launcher"}),
+ awful.key({ modkey, "Control" }, "r", awesome.restart,
+ {description = "reload awesome", group = "awesome"}),
+ awful.key({ modkey, "Shift" }, "e", awesome.quit,
+ {description = "quit awesome", group = "awesome"}),
+
+ awful.key({ modkey, }, "l", function () awful.tag.incmwfact( 0.05) end,
+ {description = "increase master width factor", group = "layout"}),
+ awful.key({ modkey, }, "h", function () awful.tag.incmwfact(-0.05) end,
+ {description = "decrease master width factor", group = "layout"}),
+ awful.key({ modkey, "Shift" }, "h", function () awful.tag.incnmaster( 1, nil, true) end,
+ {description = "increase the number of master clients", group = "layout"}),
+ awful.key({ modkey, "Shift" }, "l", function () awful.tag.incnmaster(-1, nil, true) end,
+ {description = "decrease the number of master clients", group = "layout"}),
+ awful.key({ modkey, "Control" }, "h", function () awful.tag.incncol( 1, nil, true) end,
+ {description = "increase the number of columns", group = "layout"}),
+ awful.key({ modkey, "Control" }, "l", function () awful.tag.incncol(-1, nil, true) end,
+ {description = "decrease the number of columns", group = "layout"}),
+ awful.key({ modkey, }, "space", function () awful.layout.inc( 1) end,
+ {description = "select next", group = "layout"}),
+ awful.key({ modkey, "Shift" }, "space", function () awful.layout.inc(-1) end,
+ {description = "select previous", group = "layout"}),
+
+ awful.key({ modkey, "Control" }, "n",
+ function ()
+ local c = awful.client.restore()
+ -- Focus restored client
+ if c then
+ c:emit_signal(
+ "request::activate", "key.unminimize", {raise = true}
+ )
+ end
+ end,
+ {description = "restore minimized", group = "client"}),
+
+ -- Prompt
+ awful.key({ modkey }, "r", function () awful.screen.focused().mypromptbox:run() end,
+ {description = "run prompt", group = "launcher"}),
+
+ awful.key({ modkey }, "x",
+ function ()
+ awful.prompt.run {
+ prompt = "Run Lua code: ",
+ textbox = awful.screen.focused().mypromptbox.widget,
+ exe_callback = awful.util.eval,
+ history_path = awful.util.get_cache_dir() .. "/history_eval"
+ }
+ end,
+ {description = "lua execute prompt", group = "awesome"}),
+ -- Menubar
+ awful.key({ modkey }, "p", function() menubar.show() end,
+ {description = "show the menubar", group = "launcher"})
+)
+
+clientkeys = gears.table.join(
+ awful.key({ modkey, }, "f",
+ function (c)
+ c.fullscreen = not c.fullscreen
+ c:raise()
+ end,
+ {description = "toggle fullscreen", group = "client"}),
+ awful.key({ modkey, "Shift" }, "q", function (c) c:kill() end,
+ {description = "close", group = "client"}),
+ awful.key({ modkey, "Control" }, "space", awful.client.floating.toggle ,
+ {description = "toggle floating", group = "client"}),
+ awful.key({ modkey, "Control" }, "Return", function (c) c:swap(awful.client.getmaster()) end,
+ {description = "move to master", group = "client"}),
+ awful.key({ modkey, }, "o", function (c) c:move_to_screen() end,
+ {description = "move to screen", group = "client"}),
+ awful.key({ modkey, }, "t", function (c) c.ontop = not c.ontop end,
+ {description = "toggle keep on top", group = "client"}),
+ awful.key({ modkey, }, "n",
+ function (c)
+ -- The client currently has the input focus, so it cannot be
+ -- minimized, since minimized clients can't have the focus.
+ c.minimized = true
+ end ,
+ {description = "minimize", group = "client"}),
+ awful.key({ modkey, }, "m",
+ function (c)
+ c.maximized = not c.maximized
+ c:raise()
+ end ,
+ {description = "(un)maximize", group = "client"}),
+ awful.key({ modkey, "Control" }, "m",
+ function (c)
+ c.maximized_vertical = not c.maximized_vertical
+ c:raise()
+ end ,
+ {description = "(un)maximize vertically", group = "client"}),
+ awful.key({ modkey, "Shift" }, "m",
+ function (c)
+ c.maximized_horizontal = not c.maximized_horizontal
+ c:raise()
+ end ,
+ {description = "(un)maximize horizontally", group = "client"}),
+
+ -- custom keybindings
+ awful.key({ modkey, 'Control' }, "b", function() awful.util.spawn("brave") end),
+ awful.key({}, "n", function() naughty.notify(
+ { preset = naughty.config.presets.critical,
+ title = "Oops, there were errors during startup!",
+ text = awesome.startup_errors }
+ ) end)
+)
+
+
+-- Bind all key numbers to tags.
+-- Be careful: we use keycodes to make it work on any keyboard layout.
+-- This should map on the top row of your keyboard, usually 1 to 9.
+for i = 1, 9 do
+ globalkeys = gears.table.join(globalkeys,
+ -- View tag only.
+ awful.key({ modkey }, "#" .. i + 9,
+ function ()
+ local screen = awful.screen.focused()
+ local tag = screen.tags[i]
+ if tag then
+ tag:view_only()
+ end
+ end,
+ {description = "view tag #"..i, group = "tag"}),
+ -- Toggle tag display.
+ awful.key({ modkey, "Control" }, "#" .. i + 9,
+ function ()
+ local screen = awful.screen.focused()
+ local tag = screen.tags[i]
+ if tag then
+ awful.tag.viewtoggle(tag)
+ end
+ end,
+ {description = "toggle tag #" .. i, group = "tag"}),
+ -- Move client to tag.
+ awful.key({ modkey, "Shift" }, "#" .. i + 9,
+ function ()
+ if client.focus then
+ local tag = client.focus.screen.tags[i]
+ if tag then
+ client.focus:move_to_tag(tag)
+ end
+ end
+ end,
+ {description = "move focused client to tag #"..i, group = "tag"}),
+ -- Toggle tag on focused client.
+ awful.key({ modkey, "Control", "Shift" }, "#" .. i + 9,
+ function ()
+ if client.focus then
+ local tag = client.focus.screen.tags[i]
+ if tag then
+ client.focus:toggle_tag(tag)
+ end
+ end
+ end,
+ {description = "toggle focused client on tag #" .. i, group = "tag"})
+ )
+end
+
+clientbuttons = gears.table.join(
+ awful.button({ }, 1, function (c)
+ c:emit_signal("request::activate", "mouse_click", {raise = true})
+ end),
+ awful.button({ modkey }, 1, function (c)
+ c:emit_signal("request::activate", "mouse_click", {raise = true})
+ awful.mouse.client.move(c)
+ end),
+ awful.button({ modkey }, 3, function (c)
+ c:emit_signal("request::activate", "mouse_click", {raise = true})
+ awful.mouse.client.resize(c)
+ end)
+)
+
+-- Set keys
+root.keys(globalkeys)
+-- }}}
+
+-- {{{ Rules
+-- Rules to apply to new clients (through the "manage" signal).
+awful.rules.rules = {
+ -- All clients will match this rule.
+ { rule = { },
+ properties = { border_width = beautiful.border_width,
+ border_color = beautiful.border_normal,
+ focus = awful.client.focus.filter,
+ raise = true,
+ keys = clientkeys,
+ buttons = clientbuttons,
+ screen = awful.screen.preferred,
+ placement = awful.placement.no_overlap+awful.placement.no_offscreen
+ }
+ },
+
+ -- Floating clients.
+ { rule_any = {
+ instance = {
+ "DTA", -- Firefox addon DownThemAll.
+ "copyq", -- Includes session name in class.
+ "pinentry",
+ },
+ class = {
+ "Arandr",
+ "Blueman-manager",
+ "Gpick",
+ "Kruler",
+ "MessageWin", -- kalarm.
+ "Sxiv",
+ "Tor Browser", -- Needs a fixed window size to avoid fingerprinting by screen size.
+ "Wpa_gui",
+ "veromix",
+ "xtightvncviewer"},
+
+ -- Note that the name property shown in xprop might be set slightly after creation of the client
+ -- and the name shown there might not match defined rules here.
+ name = {
+ "Event Tester", -- xev.
+ },
+ role = {
+ "AlarmWindow", -- Thunderbird's calendar.
+ "ConfigManager", -- Thunderbird's about:config.
+ "pop-up", -- e.g. Google Chrome's (detached) Developer Tools.
+ }
+ }, properties = { floating = true }},
+
+ -- dont add titlebars to normal clients and dialogs
+ { rule_any = {type = { "normal", "dialog" }
+ }, properties = { titlebars_enabled = false }
+ },
+
+ -- Set Firefox to always map on the tag named "2" on screen 1.
+ -- { rule = { class = "Firefox" },
+ -- properties = { screen = 1, tag = "2" } },
+}
+-- }}}
+
+-- {{{ Signals
+-- Signal function to execute when a new client appears.
+client.connect_signal("manage", function (c)
+ -- Set the windows at the slave,
+ -- i.e. put it at the end of others instead of setting it master.
+ -- if not awesome.startup then awful.client.setslave(c) end
+
+ if awesome.startup
+ and not c.size_hints.user_position
+ and not c.size_hints.program_position then
+ -- Prevent clients from being unreachable after screen count changes.
+ awful.placement.no_offscreen(c)
+ end
+end)
+
+-- Add a titlebar if titlebars_enabled is set to true in the rules.
+client.connect_signal("request::titlebars", function(c)
+ -- buttons for the titlebar
+ local buttons = gears.table.join(
+ awful.button({ }, 1, function()
+ c:emit_signal("request::activate", "titlebar", {raise = true})
+ awful.mouse.client.move(c)
+ end),
+ awful.button({ }, 3, function()
+ c:emit_signal("request::activate", "titlebar", {raise = true})
+ awful.mouse.client.resize(c)
+ end)
+ )
+
+ awful.titlebar(c) : setup {
+ { -- Left
+ awful.titlebar.widget.iconwidget(c),
+ buttons = buttons,
+ layout = wibox.layout.fixed.horizontal
+ },
+ { -- Middle
+ { -- Title
+ align = "center",
+ widget = awful.titlebar.widget.titlewidget(c)
+ },
+ buttons = buttons,
+ layout = wibox.layout.flex.horizontal
+ },
+ { -- Right
+ awful.titlebar.widget.floatingbutton (c),
+ awful.titlebar.widget.maximizedbutton(c),
+ awful.titlebar.widget.stickybutton (c),
+ awful.titlebar.widget.ontopbutton (c),
+ awful.titlebar.widget.closebutton (c),
+ layout = wibox.layout.fixed.horizontal()
+ },
+ layout = wibox.layout.align.horizontal
+ }
+end)
+
+-- Enable sloppy focus, so that focus follows mouse.
+client.connect_signal("mouse::enter", function(c)
+ c:emit_signal("request::activate", "mouse_enter", {raise = false})
+end)
+
+client.connect_signal("focus", function(c) c.border_color = beautiful.border_focus end)
+client.connect_signal("unfocus", function(c) c.border_color = beautiful.border_normal end)
+-- }}}
diff --git a/awesome/theme.lua b/awesome/theme.lua
new file mode 100644
index 0000000..8e3daba
--- /dev/null
+++ b/awesome/theme.lua
@@ -0,0 +1,135 @@
+---------------------------
+-- Default awesome theme --
+---------------------------
+
+local theme_assets = require("beautiful.theme_assets")
+local xresources = require("beautiful.xresources")
+local dpi = xresources.apply_dpi
+
+local gfs = require("gears.filesystem")
+local themes_path = gfs.get_themes_dir()
+
+local theme = {}
+
+theme.font = "IBM Plex Sans 10"
+
+theme.bg_normal = "#000000"
+theme.bg_focus = "#ff0000"
+theme.bg_urgent = "#ff0000"
+theme.bg_minimize = "#444444"
+theme.bg_systray = theme.bg_normal
+
+theme.fg_normal = "#ff0000"
+theme.fg_focus = "#ffffff"
+theme.fg_urgent = "#ffffff"
+theme.fg_minimize = "#ffffff"
+
+theme.useless_gap = dpi(1)
+theme.border_width = dpi(1)
+theme.border_normal = "#000000"
+theme.border_focus = "#535d6c"
+theme.border_marked = "#91231c"
+
+
+-- There are other variable sets
+-- overriding the default one when
+-- defined, the sets are:
+-- taglist_[bg|fg]_[focus|urgent|occupied|empty|volatile]
+-- tasklist_[bg|fg]_[focus|urgent]
+-- titlebar_[bg|fg]_[normal|focus]
+-- tooltip_[font|opacity|fg_color|bg_color|border_width|border_color]
+-- mouse_finder_[color|timeout|animate_timeout|radius|factor]
+-- prompt_[fg|bg|fg_cursor|bg_cursor|font]
+-- hotkeys_[bg|fg|border_width|border_color|shape|opacity|modifiers_fg|label_bg|label_fg|group_margin|font|description_font]
+-- Example:
+--theme.taglist_bg_focus = "#ff0000"
+
+-- Generate taglist squares:
+local taglist_square_size = dpi(4)
+theme.taglist_squares_sel = theme_assets.taglist_squares_sel(
+ taglist_square_size, theme.fg_normal
+)
+theme.taglist_squares_unsel = theme_assets.taglist_squares_unsel(
+ taglist_square_size, theme.fg_normal
+)
+
+-- Variables set for theming notifications:
+theme.notification_font = "IBM Plex Sans"
+theme.notification_bg = "#141414"
+theme.notification_fg = "#ffffff"
+-- notification_[width|height|margin]
+theme.notification_border_color = "#ff0000"
+theme.notification_border_width = 2
+theme.notification_shape = "dotted"
+
+-- Variables set for theming the menu:
+-- menu_[bg|fg]_[normal|focus]
+-- menu_[border_color|border_width]
+theme.menu_submenu_icon = themes_path.."default/submenu.png"
+theme.menu_height = dpi(15)
+theme.menu_width = dpi(100)
+
+-- You can add as many variables as
+-- you wish and access them by using
+-- beautiful.variable in your rc.lua
+--theme.bg_widget = "#cc0000"
+
+-- Define the image to load
+theme.titlebar_close_button_normal = themes_path.."default/titlebar/close_normal.png"
+theme.titlebar_close_button_focus = themes_path.."default/titlebar/close_focus.png"
+
+theme.titlebar_minimize_button_normal = themes_path.."default/titlebar/minimize_normal.png"
+theme.titlebar_minimize_button_focus = themes_path.."default/titlebar/minimize_focus.png"
+
+theme.titlebar_ontop_button_normal_inactive = themes_path.."default/titlebar/ontop_normal_inactive.png"
+theme.titlebar_ontop_button_focus_inactive = themes_path.."default/titlebar/ontop_focus_inactive.png"
+theme.titlebar_ontop_button_normal_active = themes_path.."default/titlebar/ontop_normal_active.png"
+theme.titlebar_ontop_button_focus_active = themes_path.."default/titlebar/ontop_focus_active.png"
+
+theme.titlebar_sticky_button_normal_inactive = themes_path.."default/titlebar/sticky_normal_inactive.png"
+theme.titlebar_sticky_button_focus_inactive = themes_path.."default/titlebar/sticky_focus_inactive.png"
+theme.titlebar_sticky_button_normal_active = themes_path.."default/titlebar/sticky_normal_active.png"
+theme.titlebar_sticky_button_focus_active = themes_path.."default/titlebar/sticky_focus_active.png"
+
+theme.titlebar_floating_button_normal_inactive = themes_path.."default/titlebar/floating_normal_inactive.png"
+theme.titlebar_floating_button_focus_inactive = themes_path.."default/titlebar/floating_focus_inactive.png"
+theme.titlebar_floating_button_normal_active = themes_path.."default/titlebar/floating_normal_active.png"
+theme.titlebar_floating_button_focus_active = themes_path.."default/titlebar/floating_focus_active.png"
+
+theme.titlebar_maximized_button_normal_inactive = themes_path.."default/titlebar/maximized_normal_inactive.png"
+theme.titlebar_maximized_button_focus_inactive = themes_path.."default/titlebar/maximized_focus_inactive.png"
+theme.titlebar_maximized_button_normal_active = themes_path.."default/titlebar/maximized_normal_active.png"
+theme.titlebar_maximized_button_focus_active = themes_path.."default/titlebar/maximized_focus_active.png"
+
+theme.wallpaper = themes_path.."default/background.png"
+
+-- You can use your own layout icons like this:
+theme.layout_fairh = themes_path.."default/layouts/fairhw.png"
+theme.layout_fairv = themes_path.."default/layouts/fairvw.png"
+theme.layout_floating = themes_path.."default/layouts/floatingw.png"
+theme.layout_magnifier = themes_path.."default/layouts/magnifierw.png"
+theme.layout_max = themes_path.."default/layouts/maxw.png"
+theme.layout_fullscreen = themes_path.."default/layouts/fullscreenw.png"
+theme.layout_tilebottom = themes_path.."default/layouts/tilebottomw.png"
+theme.layout_tileleft = themes_path.."default/layouts/tileleftw.png"
+theme.layout_tile = themes_path.."default/layouts/tilew.png"
+theme.layout_tiletop = themes_path.."default/layouts/tiletopw.png"
+theme.layout_spiral = themes_path.."default/layouts/spiralw.png"
+theme.layout_dwindle = themes_path.."default/layouts/dwindlew.png"
+theme.layout_cornernw = themes_path.."default/layouts/cornernww.png"
+theme.layout_cornerne = themes_path.."default/layouts/cornernew.png"
+theme.layout_cornersw = themes_path.."default/layouts/cornersww.png"
+theme.layout_cornerse = themes_path.."default/layouts/cornersew.png"
+
+-- Generate Awesome icon:
+theme.awesome_icon = theme_assets.awesome_icon(
+ theme.menu_height, theme.bg_focus, theme.fg_focus
+)
+
+-- Define the icon theme for application icons. If not set then the icons
+-- from /usr/share/icons and /usr/share/icons/hicolor will be used.
+theme.icon_theme = nil
+
+return theme
+
+-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
diff --git a/mpv/encoding.rst b/mpv/encoding.rst
new file mode 100644
index 0000000..ee46cec
--- /dev/null
+++ b/mpv/encoding.rst
@@ -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 ab=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 libvorbis -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 ab=128k
+
+Typical VP8 encoding, WebM (restricted Matroska) container::
+
+ mpv infile -o outfile.mkv \
+ -of webm \
+ -ovc libvpx -ovcopts qmin=6,b=1000000k \
+ -oac libvorbis -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.mp3 infile.flac -no-video -oac
+ libmp3lame -oacopts ab=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
diff --git a/mpv/input.conf b/mpv/input.conf
new file mode 100644
index 0000000..d05cd50
--- /dev/null
+++ b/mpv/input.conf
@@ -0,0 +1,194 @@
+######################################################
+#
+# mpv default 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 on/off
+#MBTN_RIGHT cycle pause # toggle pause on/off
+#MBTN_BACK playlist-prev
+#MBTN_FORWARD playlist-next
+
+# 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 seek 10
+#WHEEL_DOWN seek -10
+#WHEEL_LEFT add volume -2
+#WHEEL_RIGHT add volume 2
+
+## Seek units are in seconds, but note that these are limited by keyframes
+#RIGHT seek 5
+#LEFT seek -5
+#UP seek 60
+#DOWN seek -60
+# 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
+#Shift+LEFT no-osd seek -1 exact
+#Shift+UP no-osd seek 5 exact
+#Shift+DOWN no-osd seek -5 exact
+# Skip to previous/next subtitle (subject to some restrictions; see manpage)
+#Ctrl+LEFT no-osd sub-seek -1
+#Ctrl+RIGHT no-osd sub-seek 1
+# Adjust timing to previous/next subtitle
+#Ctrl+Shift+LEFT sub-step -1
+#Ctrl+Shift+RIGHT sub-step 1
+# Move video rectangle
+#Alt+left add video-pan-x 0.1
+#Alt+right add video-pan-x -0.1
+#Alt+up add video-pan-y 0.1
+#Alt+down add video-pan-y -0.1
+# Zoom/unzoom video
+#Alt++ add video-zoom 0.1
+#Alt+- add video-zoom -0.1
+# Reset video zoom/pan settings
+#Alt+BS set video-zoom 0 ; set video-pan-x 0 ; set video-pan-y 0
+#PGUP add chapter 1 # skip to next chapter
+#PGDWN add chapter -1 # skip to previous chapter
+#Shift+PGUP seek 600
+#Shift+PGDWN seek -600
+#[ multiply speed 1/1.1 # scale playback speed
+#] multiply speed 1.1
+#{ multiply speed 0.5
+#} multiply speed 2.0
+#BS set speed 1.0 # reset speed to normal
+#Shift+BS revert-seek # undo previous (or marked) seek
+#Shift+Ctrl+BS revert-seek mark # mark position for revert-seek
+#q quit
+#Q quit-watch-later
+#q {encode} quit 4
+#ESC set fullscreen no
+#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
+#> playlist-next # skip to next file
+#ENTER playlist-next # skip to next file
+#< playlist-prev # skip to previous file
+#O no-osd cycle-values osd-level 3 1 # cycle through OSD mode
+#o show-progress
+#P show-progress
+#i script-binding stats/display-stats
+#I script-binding stats/display-stats-toggle
+#` script-binding console/enable
+#z add sub-delay -0.1 # subtract 100 ms delay from subs
+#Z add sub-delay +0.1 # add
+#x add sub-delay +0.1 # same as previous binding (discouraged)
+#ctrl++ add audio-delay 0.100 # this changes audio/video sync
+#ctrl+- add audio-delay -0.100
+#Shift+g add sub-scale +0.1 # increase subtitle font size
+#Shift+f add sub-scale -0.1 # decrease subtitle font size
+#9 add volume -2
+#/ add volume -2
+#0 add volume 2
+#* add volume 2
+#m cycle 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
+#Alt+1 set window-scale 1.0
+#Alt+2 set window-scale 2.0
+# toggle deinterlacer (automatically inserts or removes required filter)
+#d cycle deinterlace
+#r add sub-pos -1 # move subtitles up
+#R add sub-pos +1 # down
+#t add sub-pos +1 # same as previous binding (discouraged)
+#v cycle sub-visibility
+# stretch SSA/ASS subtitles with anamorphic videos to match historical
+#V cycle sub-ass-vsfilter-aspect-compat
+# switch between applying no style overrides to SSA/ASS subtitles, and
+# overriding them almost completely with the normal subtitle style
+#u cycle-values sub-ass-override "force" "no"
+#j cycle sub # cycle through subtitles
+#J cycle sub down # ...backwards
+#SHARP cycle audio # switch audio streams
+#_ cycle video
+#T cycle ontop # toggle video window ontop of other windows
+#f cycle fullscreen # toggle fullscreen
+#s screenshot # take a screenshot
+#S screenshot video # ...without subtitles
+#Ctrl+s screenshot window # ...with subtitles and OSD, and scaled
+#Alt+s screenshot each-frame # automatically screenshot every frame
+#w add panscan -0.1 # zoom out with -panscan 0 -fs
+#W add panscan +0.1 # in
+#e add panscan +0.1 # same as previous binding (discouraged)
+# cycle video aspect ratios; "-1" is the container aspect
+#A cycle-values video-aspect-override "16:9" "4:3" "2.35:1" "-1"
+#POWER quit
+#PLAY cycle pause
+#PAUSE cycle pause
+#PLAYPAUSE cycle pause
+#PLAYONLY set pause no
+#PAUSEONLY set pause yes
+#STOP quit
+#FORWARD seek 60
+#REWIND seek -60
+#NEXT playlist-next
+#PREV playlist-prev
+#VOLUME_UP add volume 2
+#VOLUME_DOWN add volume -2
+#MUTE cycle mute
+#CLOSE_WIN quit
+#CLOSE_WIN {encode} quit 4
+#ctrl+w quit
+#E cycle edition # next edition
+#l ab-loop # Set/clear A-B loop points
+#L cycle-values loop-file "inf" "no" # toggle infinite looping
+#ctrl+c quit 4
+#DEL script-binding osc/visibility # cycle OSC display
+#ctrl+h cycle-values hwdec "auto" "no" # cycle hardware decoding
+#F8 show_text ${playlist} # show playlist
+#F9 show_text ${track-list} # show list of audio/sub streams
+
+#
+# Legacy bindings (may or may not be removed in the future)
+#
+#! add chapter -1 # skip to previous chapter
+#@ add chapter 1 # next
+
+#
+# Not assigned by default
+# (not an exhaustive list of unbound commands)
+#
+
+# ? cycle angle # switch DVD/Bluray angle
+# ? cycle sub-forced-only # toggle DVD forced subs
+# ? cycle program # cycle transport stream programs
+# ? stop # stop playback (quit or enter idle mode)
diff --git a/mpv/mplayer-input.conf b/mpv/mplayer-input.conf
new file mode 100644
index 0000000..2d23e47
--- /dev/null
+++ b/mpv/mplayer-input.conf
@@ -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
diff --git a/mpv/mpv.conf b/mpv/mpv.conf
new file mode 100644
index 0000000..6d22c0f
--- /dev/null
+++ b/mpv/mpv.conf
@@ -0,0 +1,147 @@
+#####################################
+#
+# CUSTOM CONFIG
+#
+#####################################
+save-position-on-quit
+
+
+
+#
+# Example mpv configuration file
+#
+# Warning:
+#
+# The commented example options usually do _not_ set the default values. Call
+# mpv with --list-options to see the default values for most options. There is
+# no builtin or example mpv.conf with all the defaults.
+#
+#
+# Configuration files are read system-wide from /usr/local/etc/mpv.conf
+# and per-user from ~/.config/mpv/mpv.conf, where per-user settings override
+# system-wide settings, all of which are overridden by the command line.
+#
+# Configuration file settings and the command line options use the same
+# underlying mechanisms. Most options can be put into the configuration file
+# by dropping the preceding '--'. See the man page for a complete list of
+# options.
+#
+# Lines starting with '#' are comments and are ignored.
+#
+# See the CONFIGURATION FILES section in the man page
+# for a detailed description of the syntax.
+#
+# Profiles should be placed at the bottom of the configuration file to ensure
+# that settings wanted as defaults are not restricted to specific profiles.
+
+##################
+# video settings #
+##################
+
+# Start in fullscreen mode by default.
+#fs=yes
+
+# force starting with centered window
+#geometry=50%:50%
+
+# don't allow a new window to have a size larger than 90% of the screen size
+#autofit-larger=90%x90%
+
+# Do not close the window on exit.
+#keep-open=yes
+
+# Do not wait with showing the video window until it has loaded. (This will
+# resize the window once video is loaded. Also always shows a window with
+# audio.)
+#force-window=immediate
+
+# Disable the On Screen Controller (OSC).
+#osc=no
+
+# Keep the player window on top of all other windows.
+#ontop=yes
+
+# Specify high quality video rendering preset (for --vo=gpu only)
+# Can cause performance problems with some drivers and GPUs.
+#profile=gpu-hq
+
+# Force video to lock on the display's refresh rate, and change video and audio
+# speed to some degree to ensure synchronous playback - can cause problems
+# with some drivers and desktop environments.
+#video-sync=display-resample
+
+# Enable hardware decoding if available. Often, this does not work with all
+# video outputs, but should work well with default settings on most systems.
+# If performance or energy usage is an issue, forcing the vdpau or vaapi VOs
+# may or may not help.
+#hwdec=auto
+
+##################
+# audio settings #
+##################
+
+# Specify default audio device. You can list devices with: --audio-device=help
+# The option takes the device string (the stuff between the '...').
+#audio-device=alsa/default
+
+# Do not filter audio to keep pitch when changing playback speed.
+#audio-pitch-correction=no
+
+# Output 5.1 audio natively, and upmix/downmix audio with a different format.
+#audio-channels=5.1
+# Disable any automatic remix, _if_ the audio output accepts the audio format.
+# of the currently played file. See caveats mentioned in the manpage.
+# (The default is "auto-safe", see manpage.)
+#audio-channels=auto
+
+##################
+# other settings #
+##################
+
+# Pretend to be a web browser. Might fix playback with some streaming sites,
+# but also will break with shoutcast streams.
+#user-agent="Mozilla/5.0"
+
+# cache settings
+#
+# Use a large seekable RAM cache even for local input.
+#cache=yes
+#
+# Use extra large RAM cache (needs cache=yes to make it useful).
+#demuxer-max-bytes=500M
+#demuxer-max-back-bytes=100M
+#
+# Disable the behavior that the player will pause if the cache goes below a
+# certain fill size.
+#cache-pause=no
+#
+# Store cache payload on the hard disk instead of in RAM. (This may negatively
+# impact performance unless used for slow input such as network.)
+#cache-dir=~/.cache/
+#cache-on-disk=yes
+
+# Display English subtitles if available.
+#slang=en
+
+# Play Finnish audio if available, fall back to English otherwise.
+#alang=fi,en
+
+# Change subtitle encoding. For Arabic subtitles use 'cp1256'.
+# If the file seems to be valid UTF-8, prefer UTF-8.
+# (You can add '+' in front of the codepage to force it.)
+#sub-codepage=cp1256
+
+# You can also include other configuration files.
+#include=/path/to/the/file/you/want/to/include
+
+############
+# Profiles #
+############
+
+# The options declared as part of profiles override global default settings,
+# but only take effect when the profile is active.
+
+# The following profile can be enabled on the command line with: --profile=eye-cancer
+
+#[eye-cancer]
+#sharpen=5
diff --git a/mpv/restore-old-bindings.conf b/mpv/restore-old-bindings.conf
new file mode 100644
index 0000000..662a699
--- /dev/null
+++ b/mpv/restore-old-bindings.conf
@@ -0,0 +1,61 @@
+
+# This file contains all bindings that were removed 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.27.0 (macOS and Wayland only)
+
+# WHEEL_UP seek 10
+# WHEEL_DOWN seek -10
+# WHEEL_LEFT seek 5
+# WHEEL_RIGHT seek -5
+
+# changed in mpv 0.26.0
+
+h cycle tv-channel -1 # previous channel
+k cycle tv-channel +1 # next channel
+H cycle dvb-channel-name -1 # previous channel
+K cycle dvb-channel-name +1 # next channel
+
+I show-text "${filename}" # display filename in osd
+
+# changed in mpv 0.24.0
+
+L cycle-values loop "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
+( add balance -0.1
+) add balance 0.1
+F cycle sub-forced-only
+TAB cycle program
+A cycle angle
+U stop
+o osd
+I show-text "${filename}"
diff --git a/mpv/tech-overview.txt b/mpv/tech-overview.txt
new file mode 100644
index 0000000..4bb06ff
--- /dev/null
+++ b/mpv/tech-overview.txt
@@ -0,0 +1,657 @@
+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 (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_tracks, 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
+ Or permanently by building with --enable-ta-leak-report.
+ 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 (libmpv/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.h (below) how to access options.
+
+ The actual option parser is spread over m_option.c, m_config.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. This (unfortunately) contains both
+ declarations for the "legacy-ish" global m_config struct, and 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_dvd.c turns DVDs into mpeg
+ streams (DVDs are actually a bunch of vob files etc. on a filesystem),
+ stream_tv.c provides TV input including channel switching.
+
+ 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 demux_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.
+
+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.) dec_video.c
+ handles most of connecting the frontend with the actual decoder.
+
+video/filter/:
+ vf_*.c and vf.c form the video filter chain. They are fed by the video
+ decoder, and output the filtered images to the VOs though vf_vo.c. By
+ default, no video filters (except vf_vo) are used. vf_scale is automatically
+ inserted if the video output can't handle the video format used by the
+ decoder.
+
+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 can pick a windowing system at runtime, e.g. the same binary can
+ provide both X11 and Cocoa support on OSX.
+
+ 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 and dec_audio.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 filter chain. af_lavrresample is inserted if any form of conversion
+ between audio formats is needed.
+
+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.
+
+ There are wrappers to support for two types of audio APIs: push.c and
+ pull.c. ao.c calls into one of these. They contain 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/. The MPlayer subreader.c is mostly gone - parts
+ of it survive in demux_subreader.c. It's used as last fallback, or to handle
+ some text subtitle types on Libav. It should go away eventually. 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 file input.conf is actually integrated into the mpv binary by the
+ build system. It contains the default 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 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 pthread 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 (osdep/atomic.h for partial C99 support), 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 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 standard pthread API for this.
+There's a lot of literature on it. Read it.
+
+For initial understanding, it may be helpful to know that condition variables
+are not variables that signal a condition. pthread_cond_t does not have any
+state per-se. Maybe pthread_cond_t would better be named pthread_interrupt_t,
+because its sole purpose is to interrupt a thread waiting via pthread_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:
+
+ pthread_mutex_t lock;
+ pthread_cond_t cond_var;
+ struct something state_var; // protected by lock, changes signaled by cond_var
+
+Waiter thread:
+
+ pthread_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. pthread_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.
+ pthread_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).
+ // ...
+
+ pthread_mutex_unlock(&lock);
+
+Signaler thread:
+
+ pthread_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 pthread_cond_wait(). If not, nothing happens.
+ pthread_cond_broadcast(&cond_var);
+
+ // Fun fact: good implementations wake up the waiter only when the lock is
+ // released, to reduce kernel scheduling overhead.
+ pthread_mutex_unlock(&lock);
+
+Some basic rules:
+ 1. Always access your state under proper locking
+ 2. Always check your predicate before every call to pthread_cond_wait()
+ (And don't call pthread_cond_wait() if the predicate is fulfilled.)
+ 3. Always call pthread_cond_wait() in a loop
+ (And only if your predicate failed without releasing the lock..)
+ 4. Always call pthread_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 pthread_cond_t 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 pthread_cond_wait() and friends,
+ nothing else)
+ - Changing the predicate, but not updating all pthread_cond_broadcast()/
+ _signal() calls correctly
+ - Forgetting that pthread_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.
diff --git a/mpv/watch_later/063DAEC803841EB7113A47FA3CECAED8 b/mpv/watch_later/063DAEC803841EB7113A47FA3CECAED8
new file mode 100644
index 0000000..f6079e0
--- /dev/null
+++ b/mpv/watch_later/063DAEC803841EB7113A47FA3CECAED8
@@ -0,0 +1,2 @@
+start=467.066667
+volume=98.000000
diff --git a/mpv/watch_later/1683D817BBC6E82BE119984C7CD7CE62 b/mpv/watch_later/1683D817BBC6E82BE119984C7CD7CE62
new file mode 100644
index 0000000..c6c6344
--- /dev/null
+++ b/mpv/watch_later/1683D817BBC6E82BE119984C7CD7CE62
@@ -0,0 +1 @@
+pause=yes
diff --git a/mpv/watch_later/259ABA88A08CB894944550AA22848669 b/mpv/watch_later/259ABA88A08CB894944550AA22848669
new file mode 100644
index 0000000..9e504ea
--- /dev/null
+++ b/mpv/watch_later/259ABA88A08CB894944550AA22848669
@@ -0,0 +1,2 @@
+start=2.202200
+ab-loop-a=1.768433
diff --git a/mpv/watch_later/344170F291482DA4FBD322DE38400EAE b/mpv/watch_later/344170F291482DA4FBD322DE38400EAE
new file mode 100644
index 0000000..5bd51ca
--- /dev/null
+++ b/mpv/watch_later/344170F291482DA4FBD322DE38400EAE
@@ -0,0 +1 @@
+# redirect entry
diff --git a/mpv/watch_later/34D62D9163E6D92542DE17F52B570116 b/mpv/watch_later/34D62D9163E6D92542DE17F52B570116
new file mode 100644
index 0000000..079a1c7
--- /dev/null
+++ b/mpv/watch_later/34D62D9163E6D92542DE17F52B570116
@@ -0,0 +1 @@
+start=6.332988
diff --git a/mpv/watch_later/36FA3790081EBC3AF44BCAE5A52795F6 b/mpv/watch_later/36FA3790081EBC3AF44BCAE5A52795F6
new file mode 100644
index 0000000..7156053
--- /dev/null
+++ b/mpv/watch_later/36FA3790081EBC3AF44BCAE5A52795F6
@@ -0,0 +1 @@
+start=12.966667
diff --git a/mpv/watch_later/3CF79AAAC15C73A8DFAA9C10D9B5B0A0 b/mpv/watch_later/3CF79AAAC15C73A8DFAA9C10D9B5B0A0
new file mode 100644
index 0000000..5bd51ca
--- /dev/null
+++ b/mpv/watch_later/3CF79AAAC15C73A8DFAA9C10D9B5B0A0
@@ -0,0 +1 @@
+# redirect entry
diff --git a/mpv/watch_later/487847FC7BB604E14B83758574B87EA2 b/mpv/watch_later/487847FC7BB604E14B83758574B87EA2
new file mode 100644
index 0000000..cb91da2
--- /dev/null
+++ b/mpv/watch_later/487847FC7BB604E14B83758574B87EA2
@@ -0,0 +1,3 @@
+volume=40.000000
+fullscreen=yes
+aid=1
diff --git a/mpv/watch_later/493B758B964204D5E80BE9B1D72BA27E b/mpv/watch_later/493B758B964204D5E80BE9B1D72BA27E
new file mode 100644
index 0000000..c6c6344
--- /dev/null
+++ b/mpv/watch_later/493B758B964204D5E80BE9B1D72BA27E
@@ -0,0 +1 @@
+pause=yes
diff --git a/mpv/watch_later/5561E0E59EDF8AA973A6E44D0E3AE48B b/mpv/watch_later/5561E0E59EDF8AA973A6E44D0E3AE48B
new file mode 100644
index 0000000..df47dd5
--- /dev/null
+++ b/mpv/watch_later/5561E0E59EDF8AA973A6E44D0E3AE48B
@@ -0,0 +1 @@
+start=5535.785786
diff --git a/mpv/watch_later/5C1E00E1E47E9A373A1F87DA46035BA3 b/mpv/watch_later/5C1E00E1E47E9A373A1F87DA46035BA3
new file mode 100644
index 0000000..5bd51ca
--- /dev/null
+++ b/mpv/watch_later/5C1E00E1E47E9A373A1F87DA46035BA3
@@ -0,0 +1 @@
+# redirect entry
diff --git a/mpv/watch_later/677EDF3B061976BEB66A39169FE0D27A b/mpv/watch_later/677EDF3B061976BEB66A39169FE0D27A
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/mpv/watch_later/677EDF3B061976BEB66A39169FE0D27A
diff --git a/mpv/watch_later/7B044A79775C002A6EE31A57B9BD0A00 b/mpv/watch_later/7B044A79775C002A6EE31A57B9BD0A00
new file mode 100644
index 0000000..bf0ceec
--- /dev/null
+++ b/mpv/watch_later/7B044A79775C002A6EE31A57B9BD0A00
@@ -0,0 +1 @@
+start=0.000000
diff --git a/mpv/watch_later/917B1861D498E15C1677BC9D24372EA9 b/mpv/watch_later/917B1861D498E15C1677BC9D24372EA9
new file mode 100644
index 0000000..899d62a
--- /dev/null
+++ b/mpv/watch_later/917B1861D498E15C1677BC9D24372EA9
@@ -0,0 +1,2 @@
+start=134.159036
+volume=76.000000
diff --git a/mpv/watch_later/A9618E91E7A663A6906F5C861673BBB5 b/mpv/watch_later/A9618E91E7A663A6906F5C861673BBB5
new file mode 100644
index 0000000..cefa127
--- /dev/null
+++ b/mpv/watch_later/A9618E91E7A663A6906F5C861673BBB5
@@ -0,0 +1 @@
+volume=54.000000
diff --git a/mpv/watch_later/AC58ECADDE9A134294955B55B2DDBE20 b/mpv/watch_later/AC58ECADDE9A134294955B55B2DDBE20
new file mode 100644
index 0000000..635c1df
--- /dev/null
+++ b/mpv/watch_later/AC58ECADDE9A134294955B55B2DDBE20
@@ -0,0 +1 @@
+start=2027.375000
diff --git a/mpv/watch_later/AF3CC3CF42020DE14E050A555E7DB42C b/mpv/watch_later/AF3CC3CF42020DE14E050A555E7DB42C
new file mode 100644
index 0000000..ab2683a
--- /dev/null
+++ b/mpv/watch_later/AF3CC3CF42020DE14E050A555E7DB42C
@@ -0,0 +1 @@
+start=15.640000
diff --git a/mpv/watch_later/D6526CC3419AD09A1C1EAFA7D509BBE0 b/mpv/watch_later/D6526CC3419AD09A1C1EAFA7D509BBE0
new file mode 100644
index 0000000..c440864
--- /dev/null
+++ b/mpv/watch_later/D6526CC3419AD09A1C1EAFA7D509BBE0
@@ -0,0 +1 @@
+volume=36.000000
diff --git a/mpv/watch_later/ED200CF84DE626FC1B96CFD87242E5CA b/mpv/watch_later/ED200CF84DE626FC1B96CFD87242E5CA
new file mode 100644
index 0000000..5bd51ca
--- /dev/null
+++ b/mpv/watch_later/ED200CF84DE626FC1B96CFD87242E5CA
@@ -0,0 +1 @@
+# redirect entry
diff --git a/mpv/watch_later/F107AE031822EF7A9FAA3B8A3ACC540A b/mpv/watch_later/F107AE031822EF7A9FAA3B8A3ACC540A
new file mode 100644
index 0000000..c440864
--- /dev/null
+++ b/mpv/watch_later/F107AE031822EF7A9FAA3B8A3ACC540A
@@ -0,0 +1 @@
+volume=36.000000
diff --git a/mpv/watch_later/F37DF3B4287319FEAF4A5337CD033E52 b/mpv/watch_later/F37DF3B4287319FEAF4A5337CD033E52
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/mpv/watch_later/F37DF3B4287319FEAF4A5337CD033E52
diff --git a/mpv/watch_later/FAAABC80E940CFB30C49FEEABA15012B b/mpv/watch_later/FAAABC80E940CFB30C49FEEABA15012B
new file mode 100644
index 0000000..3da364f
--- /dev/null
+++ b/mpv/watch_later/FAAABC80E940CFB30C49FEEABA15012B
@@ -0,0 +1,3 @@
+start=44.419375
+pause=yes
+volume=42.000000
diff --git a/sway/config b/sway/config
index 4c4bad8..3d8dc3a 100644
--- a/sway/config
+++ b/sway/config
@@ -19,7 +19,7 @@ set $term alacritty
# Note: pass the final command to swaymsg so that the resulting window can be opened
# on the original workspace that the command was run on.
set $rofi rofi -combi-modi window,drun,ssh,run -theme material -icon-theme "Papirus" -show combi
-set $dmenu dmenu_run -l 15 -nb "#282a36" -nf "#fff" -sb "#50fa7b" -sf "#282a36" -fn "IBM Plex Mono" -p "exec:"
+set $dmenu dmenu_run -l 15 -nb "#282a36" -nf "#fff" -sb "#50fa7b" -sf "#282a36" -fn "Iosevka" -p "exec:"
set $menu $dmenu
@@ -289,7 +289,7 @@ exec_always {
# gsettings set $gnome-schema cursor-theme 'Enter Cursor Theme'
}
-font pango:IBM Plex Mono 10
+font pango:Iosevka 10
gaps outer 0
gaps inner 0
@@ -311,7 +311,7 @@ client.unfocused #2E3440 #2E3440 #D8DEE9 #5c6370 #2E3
######################################
# START SOME APPS #
######################################
-# exec_always mpv 'https://www.youtube.com/watch?v=wkfyu9Sxr8g' # play music
+exec_always mpv --loop-file='inf' 'https://www.youtube.com/watch?v=_pLO4jFDeIc' # play music
exec_always newsboat -x reload # get feed articles
include /etc/sway/config.d/*
diff --git a/vim/init.vim b/vim/init.vim
index 0b178a1..53ca5dc 100644
--- a/vim/init.vim
+++ b/vim/init.vim
@@ -94,9 +94,16 @@ let g:indentLine_showFirstIndentLevel = 1
let g:indentLine_setColors = 0
+let g:airline_section_b = '%{getcwd()}' " display cwd in sec-2 of the statusline
+let g:airline_powerline_fonts = 1 " use powerline fonts in airline
let g:airline#extensions#tabline#enabled = 1 " enable upper tabline
let g:airline#extensions#tabline#fnamemod = ':t' " no idea what this does
-let g:airline_powerline_fonts = 1 " use powerline fonts in airline
+let g:airline#extensions#tabline#show_tab_count = 0 " tab count next to filename
+let g:airline#extensions#tabline#tab_min_count = 2 " show tabline when >= 2 tabs are open
+let g:airline#extensions#tabline#show_splits = 1 " enable the buffer name that displays on the right of the tabline
+let g:airline#extensions#tabline#show_tab_nr = 0 " disable tab numbers
+let g:airline#extensions#tabline#show_close_button = 0 " remove 'X' at the end of the tabline
+let g:airline#extensions#tabline#tabs_label = '' " can put text here like BUFFERS to denote buffers (I clear it so nothing is shown)
let g:airline#extensions#tabline#formatter =
\'unique_tail_improved' " upper tabline filename formatter
diff --git a/zsh/.zshrc b/zsh/.zshrc
index 9d9f2b2..b16a972 100644
--- a/zsh/.zshrc
+++ b/zsh/.zshrc
@@ -86,3 +86,5 @@ alias swaylock="swaylock --screenshots --clock --indicator --indicator-radius 10
function haste() {
curl -XPOST 'https://hastebin.com/documents' --data-binary @-
}
+
+export PATH="$HOME/.yarn/bin:$HOME/.config/yarn/global/node_modules/.bin:$PATH"