mirror of https://github.com/Flinner/dots.git
Compare commits
12 Commits
ec0c51c07a
...
22d2a9d827
Author | SHA1 | Date |
---|---|---|
Flinner Yuu | 22d2a9d827 | |
Flinner Yuu | 16b557435e | |
Flinner Yuu | 3bcffbbfc1 | |
Flinner Yuu | a13773dc70 | |
Flinner Yuu | e94a61b04f | |
Flinner Yuu | 534dff1aa8 | |
Flinner Yuu | 6ea2071b36 | |
Flinner Yuu | 51eb11db16 | |
Flinner Yuu | cbe9cc8788 | |
Flinner Yuu | 48720c1722 | |
Flinner Yuu | ce8ee58b97 | |
Flinner Yuu | 39abcc64e4 |
|
@ -18,6 +18,7 @@ env:
|
||||||
TERM: xterm-256color
|
TERM: xterm-256color
|
||||||
|
|
||||||
window:
|
window:
|
||||||
|
opacity: 0.9
|
||||||
# Window dimensions (changes require restart)
|
# Window dimensions (changes require restart)
|
||||||
#
|
#
|
||||||
# Specified in number of columns/lines, not pixels.
|
# Specified in number of columns/lines, not pixels.
|
||||||
|
@ -245,7 +246,6 @@ font:
|
||||||
# Window opacity as a floating point number from `0.0` to `1.0`.
|
# Window opacity as a floating point number from `0.0` to `1.0`.
|
||||||
# The value `0.0` is completely transparent and `1.0` is opaque.
|
# The value `0.0` is completely transparent and `1.0` is opaque.
|
||||||
#background_opacity: 1.0
|
#background_opacity: 1.0
|
||||||
background_opacity: 0.9
|
|
||||||
|
|
||||||
#selection:
|
#selection:
|
||||||
# This string contains all characters that are used as separators for "semantic words" in Alacritty.
|
# This string contains all characters that are used as separators for "semantic words" in Alacritty.
|
||||||
|
@ -285,7 +285,7 @@ background_opacity: 0.9
|
||||||
# - (Linux/BSD) user login shell
|
# - (Linux/BSD) user login shell
|
||||||
# - (Windows) powershell
|
# - (Windows) powershell
|
||||||
shell:
|
shell:
|
||||||
program: /usr/bin/zsh
|
program: zsh
|
||||||
# args:
|
# args:
|
||||||
# - --login
|
# - --login
|
||||||
# Startup directory
|
# Startup directory
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#!/bin/bash
|
#!/usr/bin/env bash
|
||||||
#xset r rate 400 100
|
#xset r rate 400 100
|
||||||
##emacs -fs &
|
##emacs -fs &
|
||||||
rm -rf ~/.cache/fontconfig
|
rm -rf ~/.cache/fontconfig
|
||||||
|
@ -23,7 +23,6 @@ source ~/.fehbg
|
||||||
#(sleep 1 && keynav)&
|
#(sleep 1 && keynav)&
|
||||||
# warped > keynav
|
# warped > keynav
|
||||||
(sleep 1 && warpd)&
|
(sleep 1 && warpd)&
|
||||||
(sleep 0 && ~/bin/keyboard ) &
|
|
||||||
killall wired
|
killall wired
|
||||||
(sleep 1 && wired ) &
|
(sleep 1 && wired ) &
|
||||||
#(sleep 3 && optimus-manager-qt) &
|
#(sleep 3 && optimus-manager-qt) &
|
||||||
|
@ -33,8 +32,10 @@ killall wired
|
||||||
(sleep 6 && bspc rule -r KeePassXC ) &
|
(sleep 6 && bspc rule -r KeePassXC ) &
|
||||||
|
|
||||||
(sleep 5 && syncthing -no-browser) &
|
(sleep 5 && syncthing -no-browser) &
|
||||||
|
(sleep 100 && nextcloud --background) &
|
||||||
|
|
||||||
#(sleep 5 && thunderbird ) &
|
#(sleep 5 && thunderbird ) &
|
||||||
(sleep 7 && bspc rule -r Thunderbird ) &
|
#(sleep 7 && bspc rule -r Thunderbird ) &
|
||||||
|
|
||||||
# Kill all davail instances before launching a single one
|
# Kill all davail instances before launching a single one
|
||||||
kill $(pgrep --full "davmail")
|
kill $(pgrep --full "davmail")
|
||||||
|
@ -54,9 +55,20 @@ killall goimapnotify
|
||||||
#done
|
#done
|
||||||
~/bin/run_goimapnotify.sh &
|
~/bin/run_goimapnotify.sh &
|
||||||
|
|
||||||
|
## Keyboard
|
||||||
|
# ibus-daemon &
|
||||||
|
# uim-toolbar-gtk3-systray & #uim Japanses Input
|
||||||
|
# Japanses Input
|
||||||
|
#(sleep 1 && fcitx -d ) &
|
||||||
|
(sleep 0 && ~/bin/keyboard ) &
|
||||||
|
|
||||||
|
## Audio
|
||||||
|
(sleep 0 && dbus-run-session pipewire ) &
|
||||||
|
(sleep 2 && dbus-run-session pipewire-pulse ) &
|
||||||
|
(sleep 2 && dbus-run-session wireplumber ) &
|
||||||
|
|
||||||
|
#(sleep 2 && polkit-dumb-agent) &
|
||||||
|
|
||||||
#ibus-daemon &
|
|
||||||
#uim-toolbar-gtk3-systray & #uim Japanses Input
|
|
||||||
|
|
||||||
#if bspwm
|
#if bspwm
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,35 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
|
PYTORCH_NO_CUDA_MEMORY_CACHING=1
|
||||||
|
|
||||||
[ -z "$2" ] && echo "usage: input.mp4 output.mp4"
|
[ -z "$2" ] && echo "usage: input.mp4 output.mp4"
|
||||||
[ -z "$2" ] && exit
|
[ -z "$2" ] && exit
|
||||||
|
|
||||||
VIDEO="$1"
|
VIDEO="$1"
|
||||||
VIDEO_OUTPUT="$2"
|
VIDEO_OUTPUT="$2"
|
||||||
|
|
||||||
TMP_RAW_AUDIO=$(mktemp --suffix ".mp3")
|
mkdir -p ~/tmp/demusicify
|
||||||
TMP_VOCALS_DIR=$(mktemp --directory)
|
echo "Created ~/tmp/demusicify"
|
||||||
TMP_VOCALS=$(mktemp --suffix ".mp3")
|
|
||||||
|
echo "Using ~/tmp/demusicify as a temp directory"
|
||||||
|
TMP_RAW_AUDIO=$(mktemp -p ~/tmp/demusicify --suffix ".mp3")
|
||||||
|
TMP_VOCALS_DIR=$(mktemp -p ~/tmp/demusicify --directory)
|
||||||
|
TMP_VOCALS=$(mktemp -p ~/tmp/demusicify --suffix ".mp3")
|
||||||
|
|
||||||
|
function cleanup () {
|
||||||
|
|
||||||
|
read -p "Do you want to cleanup? y/n" -n 1 -r
|
||||||
|
echo # (optional) move to a new line
|
||||||
|
if [[ ! $REPLY =~ ^[Yy]$ ]]
|
||||||
|
then
|
||||||
|
[[ "$0" = "$BASH_SOURCE" ]] && exit 1 || return 1 # handle exits from shell or function but don't exit interactive shell
|
||||||
|
echo "Cleaning up!"
|
||||||
|
rm "$TMP_RAW_AUDIO"
|
||||||
|
rm "$TMP_VOCALS"
|
||||||
|
rm -rf "$TMP_VOCALS_DIR"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
trap cleanup EXIT
|
||||||
|
|
||||||
# Extract Audio from Video
|
# Extract Audio from Video
|
||||||
ffmpeg -i "$VIDEO" -vn "$TMP_RAW_AUDIO" -y
|
ffmpeg -i "$VIDEO" -vn "$TMP_RAW_AUDIO" -y
|
||||||
|
@ -16,7 +37,7 @@ ffmpeg -i "$VIDEO" -vn "$TMP_RAW_AUDIO" -y
|
||||||
# move to a tmp file, becuase demucs creates a lot of garbage
|
# move to a tmp file, becuase demucs creates a lot of garbage
|
||||||
pushd "$TMP_VOCALS_DIR" || exit
|
pushd "$TMP_VOCALS_DIR" || exit
|
||||||
|
|
||||||
demucs --two-stems=vocals --segment 10 "$TMP_RAW_AUDIO"
|
demucs --two-stems=vocals --segment 15 "$TMP_RAW_AUDIO"
|
||||||
|
|
||||||
cp ./separated/*/*/vocals.wav "$TMP_VOCALS"
|
cp ./separated/*/*/vocals.wav "$TMP_VOCALS"
|
||||||
|
|
||||||
|
@ -29,8 +50,3 @@ ffmpeg \
|
||||||
-c:v copy \
|
-c:v copy \
|
||||||
-map 0 -map 1:a \
|
-map 0 -map 1:a \
|
||||||
-y "$VIDEO_OUTPUT"
|
-y "$VIDEO_OUTPUT"
|
||||||
|
|
||||||
|
|
||||||
rm "$TMP_RAW_AUDIO"
|
|
||||||
rm "$TMP_VOCALS"
|
|
||||||
rm -rf "$TMP_VOCALS_DIR"
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#!/bin/bash
|
#!/usr/bin/env bash
|
||||||
setxkbmap -option ctrl:swapcaps
|
setxkbmap -option ctrl:swapcaps
|
||||||
setxkbmap -option altwin:swap_lalt_lwin
|
setxkbmap -option altwin:swap_lalt_lwin
|
||||||
setxkbmap -model pc105 -layout us,ar -variant ,qwerty -option grp:shifts_toggle
|
setxkbmap -model pc105 -layout us,ar -variant ,qwerty -option grp:shifts_toggle
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#!/bin/bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
DEVICE_BUS_ID=$(lspci | grep "VGA compatible controller: NVIDIA" | awk '{print $1}')
|
DEVICE_BUS_ID=$(lspci | grep "VGA compatible controller: NVIDIA" | awk '{print $1}')
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
export __NV_PRIME_RENDER_OFFLOAD=1
|
||||||
|
export __NV_PRIME_RENDER_OFFLOAD_PROVIDER=NVIDIA-G0
|
||||||
|
export __GLX_VENDOR_LIBRARY_NAME=nvidia
|
||||||
|
export __VK_LAYER_NV_optimus=NVIDIA_only
|
||||||
|
exec "$@"
|
|
@ -0,0 +1,836 @@
|
||||||
|
"""
|
||||||
|
This script is intended to be called from OBS Studio. Provides
|
||||||
|
mouse-based zoom and tracking for desktop/monitor/window/game sources.
|
||||||
|
For more information please visit:
|
||||||
|
https://github.com/tryptech/obs-zoom-and-follow
|
||||||
|
"""
|
||||||
|
|
||||||
|
description = (
|
||||||
|
"Crops and resizes a source to simulate a zoomed in tracked to"\
|
||||||
|
" the mouse.\n\n"
|
||||||
|
+ "Set activation hotkey in Settings.\n\n"
|
||||||
|
+ "Active Border enables lazy/smooth tracking; border size"\
|
||||||
|
"calculated as percent of smallest dimension. "
|
||||||
|
+ "Border of 50% keeps mouse locked in the center of the zoom"\
|
||||||
|
" frame\n\n"
|
||||||
|
+ "By tryptech (@yo_tryptech / tryptech#1112)\n\n"
|
||||||
|
+ "v2022.09.26"
|
||||||
|
)
|
||||||
|
|
||||||
|
import obspython as obs
|
||||||
|
import pywinctl as pwc # version >=0.0.38
|
||||||
|
from platform import system
|
||||||
|
from math import sqrt
|
||||||
|
from json import load, loads
|
||||||
|
|
||||||
|
c = pwc.getMousePos
|
||||||
|
get_position = lambda: [c().x, c().y]
|
||||||
|
zoom_id_tog = None
|
||||||
|
follow_id_tog = None
|
||||||
|
new_source = True
|
||||||
|
ZOOM_NAME_TOG = "zoom.toggle"
|
||||||
|
FOLLOW_NAME_TOG = "follow.toggle"
|
||||||
|
ZOOM_DESC_TOG = "Enable/Disable Mouse Zoom"
|
||||||
|
FOLLOW_DESC_TOG = "Enable/Disable Mouse Follow"
|
||||||
|
USE_MANUAL_MONITOR_SIZE = "Manual Monitor Size"
|
||||||
|
|
||||||
|
|
||||||
|
# -------------------------------------------------------------------
|
||||||
|
|
||||||
|
class CursorWindow:
|
||||||
|
flag = lock = track = update = True
|
||||||
|
zi_timer = zo_timer = 0
|
||||||
|
windows = window_titles = monitor = window = window_handle \
|
||||||
|
= window_name = ''
|
||||||
|
monitors = pwc.getAllScreens()
|
||||||
|
monitors_key = list(dict.keys(monitors))
|
||||||
|
monitor_override = manual_offset = monitor_size_override = False
|
||||||
|
monitor_override_id = ''
|
||||||
|
source_w = source_h = source_x = source_y = zoom_x = zoom_y \
|
||||||
|
= source_x_override = source_y_override = 0
|
||||||
|
refresh_rate = int(obs.obs_get_frame_interval_ns()/1000000)
|
||||||
|
source_name = source_type = ''
|
||||||
|
zoom_w = 1280
|
||||||
|
zoom_h = 720
|
||||||
|
active_border = 0.15
|
||||||
|
max_speed = 160
|
||||||
|
smooth = 1.0
|
||||||
|
zoom_time = 300
|
||||||
|
|
||||||
|
def update_sources(self):
|
||||||
|
"""
|
||||||
|
Update the list of Windows and Monitors from PyWinCtl
|
||||||
|
"""
|
||||||
|
self.windows = pwc.getAllWindows()
|
||||||
|
self.monitors = pwc.getAllScreens()
|
||||||
|
self.monitors_key = list(dict.keys(self.monitors))
|
||||||
|
|
||||||
|
def update_window_dim(self, window):
|
||||||
|
"""
|
||||||
|
Update the stored window dimensions to those of the selected
|
||||||
|
window
|
||||||
|
|
||||||
|
:param window: Window with new dimensions
|
||||||
|
"""
|
||||||
|
print("Updating stored dimensions to match current dimensions")
|
||||||
|
if window != None:
|
||||||
|
# FIXME: on macos get window bounds results in an error and
|
||||||
|
# does not work
|
||||||
|
# NSInternalInconsistencyException - NSWindow drag regions
|
||||||
|
# should only be invalidated on the Main Thread!
|
||||||
|
window_dim = window.getClientFrame()
|
||||||
|
if (self.source_w != window_dim.right - window_dim.left
|
||||||
|
or self.source_h != window_dim.bottom - window_dim.top
|
||||||
|
or self.source_x != window_dim.left
|
||||||
|
or self.source_y != window_dim.top):
|
||||||
|
print("OLD")
|
||||||
|
print("Width, Height, X, Y")
|
||||||
|
print(f"{self.source_w}, {self.source_h}, {self.source_x},"\
|
||||||
|
f" {self.source_y}")
|
||||||
|
self.source_w = window_dim.right - window_dim.left
|
||||||
|
self.source_h = window_dim.bottom - window_dim.top
|
||||||
|
self.source_x = window_dim.left
|
||||||
|
self.source_y = window_dim.top
|
||||||
|
print("NEW")
|
||||||
|
print("Width, Height, X, Y")
|
||||||
|
print(f"{self.source_w}, {self.source_h}, {self.source_x},"\
|
||||||
|
f" {self.source_y}")
|
||||||
|
else:
|
||||||
|
print("Dimensions did not change")
|
||||||
|
|
||||||
|
def update_monitor_dim(self, monitor):
|
||||||
|
"""
|
||||||
|
Update the stored dimensions based on the selected monitor
|
||||||
|
|
||||||
|
:param monitor: Single monitor as returned from the PyWinCtl
|
||||||
|
Monitor function getAllScreens()
|
||||||
|
"""
|
||||||
|
if self.monitor_size_override:
|
||||||
|
print("Manual monitor size enabled")
|
||||||
|
print("Dimensions set to:")
|
||||||
|
print("Width, Height, X, Y")
|
||||||
|
self.source_x = monitor['pos'].x
|
||||||
|
self.source_y = monitor['pos'].y
|
||||||
|
print(f"{self.source_w}, {self.source_h}, {self.source_x}, \
|
||||||
|
{self.source_y}")
|
||||||
|
else:
|
||||||
|
print(f"Updating stored dimensions to match monitor's dimensions | {monitor}")
|
||||||
|
if (self.source_w != monitor['size'].width
|
||||||
|
or self.source_h != monitor['size'].height
|
||||||
|
or self.source_x != monitor['pos'].x
|
||||||
|
or self.source_y != monitor['pos'].y):
|
||||||
|
print("OLD")
|
||||||
|
print("Width, Height, X, Y")
|
||||||
|
print(f"{self.source_w}, {self.source_h}, {self.source_x}, \
|
||||||
|
{self.source_y}")
|
||||||
|
self.source_w = monitor['size'].width
|
||||||
|
self.source_h = monitor['size'].height
|
||||||
|
self.source_x = monitor['pos'].x
|
||||||
|
self.source_y = monitor['pos'].y
|
||||||
|
print("NEW")
|
||||||
|
print("Width, Height, X, Y")
|
||||||
|
print(f"{self.source_w}, {self.source_h}, {self.source_x}, \
|
||||||
|
{self.source_y}")
|
||||||
|
else:
|
||||||
|
print("Dimensions did not change")
|
||||||
|
|
||||||
|
def window_capture_mac(self, data):
|
||||||
|
"""
|
||||||
|
Window capture for macOS
|
||||||
|
macos uses an exclusive property 'window_name' pywinctl does not
|
||||||
|
report application windows correctly for macos yet, so we must
|
||||||
|
capture based on the actual window name and not based on the
|
||||||
|
application like we do for windows.
|
||||||
|
"""
|
||||||
|
|
||||||
|
self.window_name = data.get('window_name')
|
||||||
|
|
||||||
|
def monitor_capture_mac(self, data):
|
||||||
|
"""
|
||||||
|
The 'display' property is an index value and not the true
|
||||||
|
monitor id. It is only returned when there is more than one
|
||||||
|
monitor on your system. We will assume that the order of the
|
||||||
|
monitors returned from pywinctl are in the same order that OBS
|
||||||
|
is assigning the display index value.
|
||||||
|
"""
|
||||||
|
monitor_index = data.get('display', 0)
|
||||||
|
print(f"Retrieving monitor {monitor_index}")
|
||||||
|
for monitor in self.monitors.items():
|
||||||
|
if (monitor['id'] == monitor_index):
|
||||||
|
print(f"Found monitor {monitor['id']} | {monitor}")
|
||||||
|
self.update_monitor_dim(monitor)
|
||||||
|
|
||||||
|
def window_capture_gen(self, data):
|
||||||
|
"""
|
||||||
|
TODO: More Linux testing, specifically with handles Windows
|
||||||
|
capture for Windows and Linux. In Windows, application data is
|
||||||
|
stored as "Title:WindowClass:Executable"
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
# Assuming the OBS data is formatted correctly, we should
|
||||||
|
# be able to identify the window
|
||||||
|
# If New Source/Init
|
||||||
|
# If Handle Exists
|
||||||
|
# Else
|
||||||
|
if new_source:
|
||||||
|
# If new source selected / OBS initialize
|
||||||
|
# Build window, window_handle, and
|
||||||
|
# window_name
|
||||||
|
print("New Source")
|
||||||
|
print("Retrieving target window info from OBS")
|
||||||
|
self.window_name = data['window'].split(":")[0]
|
||||||
|
print(f"Searching for: {self.window_name}")
|
||||||
|
for w in self.windows:
|
||||||
|
if w.title == self.window_name:
|
||||||
|
window_match = w
|
||||||
|
self.window_handle = w.getHandle()
|
||||||
|
new_source = False
|
||||||
|
print(f"Window Match: {window_match.title}")
|
||||||
|
print("Window Match Handle:"\
|
||||||
|
f" {str(self.window_handle)}")
|
||||||
|
if self.window_handle != '':
|
||||||
|
# If window handle is already stored
|
||||||
|
# Get window based on handle
|
||||||
|
# Check if name needs changing
|
||||||
|
print(f"Handle exists: {str(self.window_handle)}")
|
||||||
|
handle_match = False
|
||||||
|
for w in self.windows:
|
||||||
|
if w.getHandle() == self.window_handle:
|
||||||
|
handle_match = True
|
||||||
|
print(f"Found Handle: {str(w.getHandle())} | {self.window}")
|
||||||
|
window_match = w
|
||||||
|
if window_match.title != self.window:
|
||||||
|
print("Changing target title")
|
||||||
|
print(f"Old Title: {self.window_name}")
|
||||||
|
self.window_name = w.title
|
||||||
|
print(f"New Title: {self.window_name}")
|
||||||
|
if handle_match == False:
|
||||||
|
# TODO: If the handle no longer exists,
|
||||||
|
# eg. Window or App closed
|
||||||
|
raise
|
||||||
|
else:
|
||||||
|
print("I don't know how it gets here.")
|
||||||
|
window_match = None
|
||||||
|
# TODO:
|
||||||
|
except:
|
||||||
|
print(f"Source {self.source_name} has changed." \
|
||||||
|
" Select new source window")
|
||||||
|
window_match = None
|
||||||
|
return window_match
|
||||||
|
|
||||||
|
def monitor_capture_gen(self, data):
|
||||||
|
"""
|
||||||
|
If monitor override, update with monitor override
|
||||||
|
Else if no monitor ID, monitor does not exist
|
||||||
|
Else search for the monitor and update
|
||||||
|
"""
|
||||||
|
monitor_id = data.get('monitor', None)
|
||||||
|
if len(self.monitors.items()) == 1:
|
||||||
|
print("Only one monitor detected. Forcing override.")
|
||||||
|
for monitor in self.monitors.items():
|
||||||
|
self.update_monitor_dim(monitor[1])
|
||||||
|
elif self.monitor_override is True:
|
||||||
|
print(f"Monitor Override: {self.monitor_override}")
|
||||||
|
for monitor in self.monitors.items():
|
||||||
|
if monitor[0] == self.monitors_key[
|
||||||
|
self.monitor_override_id]:
|
||||||
|
self.update_monitor_dim(monitor[1])
|
||||||
|
elif monitor_id == None:
|
||||||
|
print(f"Key 'monitor' does not exist in {data}")
|
||||||
|
else:
|
||||||
|
print(f"Searching for monitor {monitor_id}")
|
||||||
|
for monitor in self.monitors.items():
|
||||||
|
if (monitor[1]['id'] == monitor_id):
|
||||||
|
print(f"Found monitor {monitor[1]['id']} | {monitor}")
|
||||||
|
self.update_monitor_dim(monitor[1])
|
||||||
|
|
||||||
|
def update_source_size(self):
|
||||||
|
"""
|
||||||
|
Adjusts the source size variables based on the source given
|
||||||
|
"""
|
||||||
|
global new_source
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Try to pull the data for the source object
|
||||||
|
# OBS stores the monitor index/window target in the
|
||||||
|
# window/game/display sources settings
|
||||||
|
# Info is stored in a JSON format
|
||||||
|
source = obs.obs_get_source_by_name(self.source_name)
|
||||||
|
source_settings = obs.obs_source_get_settings(source)
|
||||||
|
data = loads(obs.obs_data_get_json(source_settings))
|
||||||
|
except:
|
||||||
|
# If it cannot be pulled, it is likely one of the following:
|
||||||
|
# The source no longer exists
|
||||||
|
# The source's name has changed
|
||||||
|
# OBS does not have the sources loaded yet when launching
|
||||||
|
# the script on start
|
||||||
|
|
||||||
|
print("Source '" + self.source_name + "' not found.")
|
||||||
|
if len(self.window_name) == 0:
|
||||||
|
# OBS does not have the sources loaded yet when
|
||||||
|
# launching the script on start
|
||||||
|
self.source_name = ''
|
||||||
|
print(obs.obs_get_source_by_name(self.source_name))
|
||||||
|
else:
|
||||||
|
# If the source data is pulled, it exists. Therefore other
|
||||||
|
# information must also exists. Source Type is pulled to
|
||||||
|
# determine if the source is a display, game, or window
|
||||||
|
|
||||||
|
print(f"Source loaded successfully: {self.source_type}")
|
||||||
|
self.source_type = obs.obs_source_get_id(source)
|
||||||
|
print(f"Source Type: f{self.source_type}")
|
||||||
|
if (self.source_type in { 'window_capture','game_capture' }):
|
||||||
|
window_match = ''
|
||||||
|
if 'window_name' in data:
|
||||||
|
self.window_capture_mac(data)
|
||||||
|
elif 'window' in data:
|
||||||
|
window_match = self.window_capture_gen(data)
|
||||||
|
if window_match is not None:
|
||||||
|
print("Proceeding to resize")
|
||||||
|
self.window = pwc.getWindowsWithTitle(self.window_name)[0]
|
||||||
|
self.update_window_dim(self.window)
|
||||||
|
elif (self.source_type == 'monitor_capture'):
|
||||||
|
self.monitor_capture_gen(data)
|
||||||
|
elif (self.source_type == 'display_capture'):
|
||||||
|
self.monitor_capture_mac(data)
|
||||||
|
if (self.manual_offset
|
||||||
|
or self.monitor_size_override):
|
||||||
|
self.source_x += self.source_x_override
|
||||||
|
self.source_y += self.source_y_override
|
||||||
|
|
||||||
|
def resetZI(self):
|
||||||
|
"""
|
||||||
|
Reset the zoom-in timer
|
||||||
|
"""
|
||||||
|
self.zi_timer = 0
|
||||||
|
|
||||||
|
def resetZO(self):
|
||||||
|
"""
|
||||||
|
Reset the zoom-out timer
|
||||||
|
"""
|
||||||
|
self.zo_timer = 0
|
||||||
|
|
||||||
|
def cubic_in_out(self, p):
|
||||||
|
"""
|
||||||
|
Cubic in/out easing function. Accelerates until halfway, then
|
||||||
|
decelerates.
|
||||||
|
|
||||||
|
:param p: Linear temporal percent progress through easing from
|
||||||
|
0 to 1
|
||||||
|
:return: Adjusted percent progress
|
||||||
|
"""
|
||||||
|
if p < 0.5:
|
||||||
|
return 4 * p * p * p
|
||||||
|
else:
|
||||||
|
f = (2 * p) - 2
|
||||||
|
return 0.5 * f * f * f + 1
|
||||||
|
|
||||||
|
def check_offset(self, arg1, arg2, smooth):
|
||||||
|
"""
|
||||||
|
Checks if a given value is offset from pivot value and provides
|
||||||
|
an adjustment towards the pivot based on a smoothing factor
|
||||||
|
|
||||||
|
:param arg1: Pivot value
|
||||||
|
:param arg2: Checked value
|
||||||
|
:param smooth: Smoothing factor; larger values adjusts more
|
||||||
|
smoothly
|
||||||
|
:return: Adjustment value
|
||||||
|
"""
|
||||||
|
result = round((arg1 - arg2) / smooth + 1)
|
||||||
|
return int(result)
|
||||||
|
|
||||||
|
def follow(self, mousePos):
|
||||||
|
"""
|
||||||
|
Updates the position of the zoom window.
|
||||||
|
|
||||||
|
:param mousePos: [x,y] position of the mouse on the canvas of
|
||||||
|
all connected displays
|
||||||
|
:return: If the zoom window was moved
|
||||||
|
"""
|
||||||
|
track = False
|
||||||
|
|
||||||
|
if ((mousePos[0] - (self.source_x + self.source_w) < 1)
|
||||||
|
and (mousePos[0] - self.source_x > -1)):
|
||||||
|
if ((mousePos[1] - (self.source_y + self.source_h) < 1)
|
||||||
|
and (mousePos[1] - self.source_y > -1)):
|
||||||
|
track = True
|
||||||
|
|
||||||
|
if not track:
|
||||||
|
return track
|
||||||
|
|
||||||
|
move = False
|
||||||
|
|
||||||
|
# Find shortest dimension (usually height)
|
||||||
|
borderScale = min(self.zoom_w, self.zoom_h)
|
||||||
|
# Get active zone edges
|
||||||
|
zoom_edge_left = ( self.zoom_x
|
||||||
|
+ int(self.active_border * borderScale))
|
||||||
|
zoom_edge_right = ( self.zoom_x
|
||||||
|
+ self.zoom_w
|
||||||
|
- int(self.active_border * borderScale))
|
||||||
|
zoom_edge_top = ( self.zoom_y
|
||||||
|
+ int(self.active_border * borderScale))
|
||||||
|
zoom_edge_bottom = (self.zoom_y
|
||||||
|
+ self.zoom_h
|
||||||
|
- int(self.active_border * borderScale))
|
||||||
|
|
||||||
|
# Clamp zone edges at center
|
||||||
|
if zoom_edge_right < zoom_edge_left:
|
||||||
|
zoom_edge_left = self.zoom_x + int(self.zoom_w/2.0)
|
||||||
|
zoom_edge_right = zoom_edge_left
|
||||||
|
|
||||||
|
if zoom_edge_bottom < zoom_edge_top:
|
||||||
|
zoom_edge_top = self.zoom_y + int(self.zoom_h/2.0)
|
||||||
|
zoom_edge_bottom = zoom_edge_top
|
||||||
|
|
||||||
|
# Set smoothing values
|
||||||
|
smoothFactor = 1 if self.update else int((self.smooth * 9) / 10 + 1)
|
||||||
|
|
||||||
|
# Set x and y zoom offset
|
||||||
|
x_o = mousePos[0] - self.source_x
|
||||||
|
y_o = mousePos[1] - self.source_y
|
||||||
|
|
||||||
|
# Set x and y zoom offset
|
||||||
|
offset_x = offset_y = 0
|
||||||
|
|
||||||
|
if x_o < zoom_edge_left:
|
||||||
|
offset_x = self.check_offset(x_o, zoom_edge_left, smoothFactor)
|
||||||
|
move = True
|
||||||
|
elif x_o > zoom_edge_right:
|
||||||
|
offset_x = self.check_offset(x_o, zoom_edge_right, smoothFactor)
|
||||||
|
move = True
|
||||||
|
|
||||||
|
if y_o < zoom_edge_top:
|
||||||
|
offset_y = self.check_offset(y_o, zoom_edge_top, smoothFactor)
|
||||||
|
move = True
|
||||||
|
elif y_o > zoom_edge_bottom:
|
||||||
|
offset_y = self.check_offset(y_o, zoom_edge_bottom, smoothFactor)
|
||||||
|
move = True
|
||||||
|
|
||||||
|
# Max speed clamp
|
||||||
|
#if not self.update:
|
||||||
|
speed_h = sqrt((offset_x**2)+(offset_y**2))
|
||||||
|
speed_factor = max(self.max_speed, speed_h)/float(self.max_speed)
|
||||||
|
if not self.update:
|
||||||
|
offset_x /= speed_factor
|
||||||
|
offset_y /= speed_factor
|
||||||
|
|
||||||
|
self.zoom_x += offset_x
|
||||||
|
self.zoom_y += offset_y
|
||||||
|
if (self.active_border < 0.5):
|
||||||
|
self.check_pos()
|
||||||
|
|
||||||
|
return move
|
||||||
|
|
||||||
|
def check_pos(self):
|
||||||
|
"""
|
||||||
|
Checks if zoom window exceeds window dimensions and clamps it if
|
||||||
|
true
|
||||||
|
"""
|
||||||
|
if not self.monitor_size_override:
|
||||||
|
x_min = 0
|
||||||
|
x_max = self.source_w - self.zoom_w
|
||||||
|
y_min = 0
|
||||||
|
y_max = self.source_h - self.zoom_h
|
||||||
|
else:
|
||||||
|
x_min = self.source_x_override
|
||||||
|
x_max = self.source_w - self.zoom_w + self.source_x_override
|
||||||
|
y_min = self.source_y_override
|
||||||
|
y_max = self.source_h - self.zoom_h + self.source_y_override
|
||||||
|
|
||||||
|
if self.zoom_x < x_min:
|
||||||
|
self.zoom_x = x_min
|
||||||
|
elif self.zoom_x > x_max:
|
||||||
|
self.zoom_x = x_max
|
||||||
|
if self.zoom_y < y_min:
|
||||||
|
self.zoom_y = y_min
|
||||||
|
elif self.zoom_y > y_max:
|
||||||
|
self.zoom_y = y_max
|
||||||
|
|
||||||
|
def set_crop(self, inOut):
|
||||||
|
"""
|
||||||
|
Set dimensions of the crop filter used for zooming
|
||||||
|
|
||||||
|
:param inOut: direction of the filter zoom, in or out
|
||||||
|
"""
|
||||||
|
totalFrames = int(self.zoom_time / self.refresh_rate)
|
||||||
|
|
||||||
|
source = obs.obs_get_source_by_name(self.source_name)
|
||||||
|
crop = obs.obs_source_get_filter_by_name(source, "ZoomCrop")
|
||||||
|
|
||||||
|
if crop is None: # create filter
|
||||||
|
_s = obs.obs_data_create()
|
||||||
|
obs.obs_data_set_bool(_s, "relative", False)
|
||||||
|
f = obs.obs_source_create_private("crop_filter",
|
||||||
|
"ZoomCrop", _s)
|
||||||
|
obs.obs_source_filter_add(source, f)
|
||||||
|
obs.obs_source_release(f)
|
||||||
|
obs.obs_data_release(_s)
|
||||||
|
|
||||||
|
s = obs.obs_source_get_settings(crop)
|
||||||
|
i = obs.obs_data_set_int
|
||||||
|
|
||||||
|
if inOut == 0:
|
||||||
|
self.resetZI()
|
||||||
|
if self.zo_timer < totalFrames:
|
||||||
|
self.zo_timer += 1
|
||||||
|
time = self.cubic_in_out(self.zo_timer / totalFrames)
|
||||||
|
i(s, "left", int(((1 - time) * self.zoom_x)))
|
||||||
|
i(s, "top", int(((1 - time) * self.zoom_y)))
|
||||||
|
i(
|
||||||
|
s,
|
||||||
|
"cx",
|
||||||
|
self.zoom_w + int(time * (self.source_w - self.zoom_w)),
|
||||||
|
)
|
||||||
|
i(
|
||||||
|
s,
|
||||||
|
"cy",
|
||||||
|
self.zoom_h + int(time * (self.source_h - self.zoom_h)),
|
||||||
|
)
|
||||||
|
self.update = True
|
||||||
|
else:
|
||||||
|
i(s, "left", 0)
|
||||||
|
i(s, "top", 0)
|
||||||
|
i(s, "cx", self.source_w)
|
||||||
|
i(s, "cy", self.source_h)
|
||||||
|
self.update = False
|
||||||
|
else:
|
||||||
|
self.resetZO()
|
||||||
|
if self.zi_timer < totalFrames:
|
||||||
|
self.zi_timer += 1
|
||||||
|
time = self.cubic_in_out(self.zi_timer / totalFrames)
|
||||||
|
i(s, "left", int(time * self.zoom_x))
|
||||||
|
i(s, "top", int(time * self.zoom_y))
|
||||||
|
i(
|
||||||
|
s,
|
||||||
|
"cx",
|
||||||
|
self.source_w - int(time * (self.source_w - self.zoom_w)),
|
||||||
|
)
|
||||||
|
i(
|
||||||
|
s,
|
||||||
|
"cy",
|
||||||
|
self.source_h - int(time * (self.source_h - self.zoom_h)),
|
||||||
|
)
|
||||||
|
self.update = True if time < 0.8 else False
|
||||||
|
else:
|
||||||
|
i(s, "left", int(self.zoom_x))
|
||||||
|
i(s, "top", int(self.zoom_y))
|
||||||
|
i(s, "cx", int(self.zoom_w))
|
||||||
|
i(s, "cy", int(self.zoom_h))
|
||||||
|
self.update = False
|
||||||
|
|
||||||
|
obs.obs_source_update(crop, s)
|
||||||
|
|
||||||
|
obs.obs_data_release(s)
|
||||||
|
obs.obs_source_release(source)
|
||||||
|
obs.obs_source_release(crop)
|
||||||
|
if (inOut == 0) and (self.zo_timer >= totalFrames):
|
||||||
|
obs.remove_current_callback()
|
||||||
|
|
||||||
|
def tracking(self):
|
||||||
|
"""
|
||||||
|
Tracking state function
|
||||||
|
"""
|
||||||
|
if self.lock:
|
||||||
|
if self.track or self.update:
|
||||||
|
self.follow(get_position())
|
||||||
|
self.set_crop(int(self.lock))
|
||||||
|
|
||||||
|
def tick(self):
|
||||||
|
"""
|
||||||
|
Containing function that is run every frame
|
||||||
|
"""
|
||||||
|
self.tracking()
|
||||||
|
|
||||||
|
|
||||||
|
zoom = CursorWindow()
|
||||||
|
|
||||||
|
|
||||||
|
# -------------------------------------------------------------------
|
||||||
|
def script_description():
|
||||||
|
return description
|
||||||
|
|
||||||
|
|
||||||
|
def script_defaults(settings):
|
||||||
|
obs.obs_data_set_default_string(settings, "source", "")
|
||||||
|
obs.obs_data_set_default_bool(settings,
|
||||||
|
"Manual Monitor Override", False)
|
||||||
|
obs.obs_data_set_default_bool(settings, "Manual Offset", False)
|
||||||
|
obs.obs_data_set_default_int(settings, "Width", 1280)
|
||||||
|
obs.obs_data_set_default_int(settings, "Height", 720)
|
||||||
|
obs.obs_data_set_default_double(settings, "Border", 0.15)
|
||||||
|
obs.obs_data_set_default_int(settings, "Speed", 160)
|
||||||
|
obs.obs_data_set_default_double(settings, "Smooth", 1.0)
|
||||||
|
obs.obs_data_set_default_int(settings, "Zoom", 300)
|
||||||
|
obs.obs_data_set_default_int(settings, "Manual X Offset", 0)
|
||||||
|
obs.obs_data_set_default_int(settings, "Manual Y Offset", 0)
|
||||||
|
|
||||||
|
|
||||||
|
def script_update(settings):
|
||||||
|
global new_source
|
||||||
|
|
||||||
|
source_string = obs.obs_data_get_string(settings, "source")
|
||||||
|
if source_string == "":
|
||||||
|
zoom.source_name = zoom.source_type = ""
|
||||||
|
return
|
||||||
|
|
||||||
|
[source, source_type] = source_string.split("||")
|
||||||
|
if zoom.source_name != source:
|
||||||
|
zoom.source_name = source
|
||||||
|
zoom.source_type = source_type
|
||||||
|
new_source = True
|
||||||
|
if new_source:
|
||||||
|
print("Source update")
|
||||||
|
zoom.update_sources()
|
||||||
|
sources = obs.obs_enum_sources()
|
||||||
|
if len(sources) == 0:
|
||||||
|
print("No sources, likely OBS startup.")
|
||||||
|
else:
|
||||||
|
print("Non-initial update")
|
||||||
|
zoom.update_source_size()
|
||||||
|
print("Source Name: " + zoom.source_name)
|
||||||
|
zoom.monitor_override = obs.obs_data_get_bool(settings,
|
||||||
|
"Manual Monitor Override")
|
||||||
|
zoom.monitor_override_id = obs.obs_data_get_int(settings, "monitor")
|
||||||
|
zoom.monitor_size_override = obs.obs_data_get_bool(settings,
|
||||||
|
"Manual Monitor Dim")
|
||||||
|
if zoom.monitor_size_override:
|
||||||
|
zoom.source_w = obs.obs_data_get_int(settings, "Monitor Width")
|
||||||
|
zoom.source_h = obs.obs_data_get_int(settings, "Monitor Height")
|
||||||
|
zoom.manual_offset = obs.obs_data_get_bool(settings, "Manual Offset")
|
||||||
|
zoom.zoom_w = obs.obs_data_get_int(settings, "Width")
|
||||||
|
zoom.zoom_h = obs.obs_data_get_int(settings, "Height")
|
||||||
|
zoom.active_border = obs.obs_data_get_double(settings, "Border")
|
||||||
|
zoom.max_speed = obs.obs_data_get_int(settings, "Speed")
|
||||||
|
zoom.smooth = obs.obs_data_get_double(settings, "Smooth")
|
||||||
|
zoom.zoom_time = obs.obs_data_get_double(settings, "Zoom")
|
||||||
|
if zoom.monitor_size_override or zoom.manual_offset:
|
||||||
|
zoom.source_x_override = obs.obs_data_get_int(settings,
|
||||||
|
"Manual X Offset")
|
||||||
|
zoom.source_y_override = obs.obs_data_get_int(settings,
|
||||||
|
"Manual Y Offset")
|
||||||
|
else:
|
||||||
|
zoom.source_x_override = 0
|
||||||
|
zoom.source_y_override = 0
|
||||||
|
|
||||||
|
|
||||||
|
def populate_list_property_with_source_names(list_property):
|
||||||
|
global new_source
|
||||||
|
|
||||||
|
print("Updating Source List")
|
||||||
|
zoom.update_sources()
|
||||||
|
sources = obs.obs_enum_sources()
|
||||||
|
print(f"System: {system()}")
|
||||||
|
if sources is not None:
|
||||||
|
obs.obs_property_list_clear(list_property)
|
||||||
|
obs.obs_property_list_add_string(list_property, "", "")
|
||||||
|
for source in sources:
|
||||||
|
if system() == "Darwin":
|
||||||
|
print(f"{obs.obs_source_get_name(source)} | {source}")
|
||||||
|
source_type = obs.obs_source_get_id(source)
|
||||||
|
print("DEBUG:", source_type)
|
||||||
|
if source_type in { "monitor_capture", "window_capture",
|
||||||
|
"game_capture","xshm_input", "display_capture" }:
|
||||||
|
name_val = name = obs.obs_source_get_name(source)
|
||||||
|
name = name + "||" + source_type
|
||||||
|
obs.obs_property_list_add_string(list_property, name_val, name)
|
||||||
|
obs.source_list_release(sources)
|
||||||
|
new_source = True
|
||||||
|
print(f"New source: {str(new_source)}")
|
||||||
|
|
||||||
|
|
||||||
|
def populate_list_property_with_monitors(list_property):
|
||||||
|
print("Updating Monitor List")
|
||||||
|
if zoom.monitors is not None:
|
||||||
|
obs.obs_property_list_clear(list_property)
|
||||||
|
obs.obs_property_list_add_int(list_property, "", -1)
|
||||||
|
monitor_index = 0
|
||||||
|
for monitor in zoom.monitors:
|
||||||
|
screen_size = pwc.getScreenSize(monitor)
|
||||||
|
obs.obs_property_list_add_int(list_property,
|
||||||
|
f"{monitor}: {screen_size.width} x {screen_size.height}",
|
||||||
|
monitor_index)
|
||||||
|
monitor_index += 1
|
||||||
|
print("Monitor override list updated")
|
||||||
|
|
||||||
|
|
||||||
|
def callback(props, prop, *args):
|
||||||
|
prop_name = obs.obs_property_name(prop)
|
||||||
|
monitor_override = obs.obs_properties_get(props, "Manual Monitor Override")
|
||||||
|
monitor_size_override = obs.obs_properties_get(props, "Manual Monitor Dim")
|
||||||
|
refresh_monitor = obs.obs_properties_get(props, "Refresh monitors")
|
||||||
|
source_type = zoom.source_type
|
||||||
|
if prop_name == "source":
|
||||||
|
if source_type in {'monitor_capture', 'display_capture'}:
|
||||||
|
obs.obs_property_set_visible(monitor_override,True)
|
||||||
|
obs.obs_property_set_visible(refresh_monitor,True)
|
||||||
|
obs.obs_property_set_visible(monitor_size_override,True)
|
||||||
|
else:
|
||||||
|
obs.obs_property_set_visible(monitor_override,False)
|
||||||
|
obs.obs_property_set_visible(refresh_monitor,False)
|
||||||
|
obs.obs_property_set_visible(monitor_size_override,False)
|
||||||
|
obs.obs_property_set_visible(
|
||||||
|
obs.obs_properties_get(props, "Monitor Width"),
|
||||||
|
zoom.monitor_size_override)
|
||||||
|
obs.obs_property_set_visible(
|
||||||
|
obs.obs_properties_get(props, "Monitor Height"),
|
||||||
|
zoom.monitor_size_override)
|
||||||
|
obs.obs_property_set_visible(
|
||||||
|
obs.obs_properties_get(props, "Manual X Offset"),
|
||||||
|
zoom.manual_offset)
|
||||||
|
obs.obs_property_set_visible(
|
||||||
|
obs.obs_properties_get(props, "Manual Y Offset"),
|
||||||
|
zoom.manual_offset)
|
||||||
|
monitor = obs.obs_properties_get(props, "monitor")
|
||||||
|
obs.obs_property_set_visible(monitor,zoom.monitor_override
|
||||||
|
and obs.obs_property_visible(monitor_override))
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def script_properties():
|
||||||
|
props = obs.obs_properties_create()
|
||||||
|
|
||||||
|
zs = obs.obs_properties_add_list(
|
||||||
|
props,
|
||||||
|
"source",
|
||||||
|
"Zoom Source",
|
||||||
|
obs.OBS_COMBO_TYPE_LIST,
|
||||||
|
obs.OBS_COMBO_FORMAT_STRING,
|
||||||
|
)
|
||||||
|
populate_list_property_with_source_names(zs)
|
||||||
|
|
||||||
|
obs.obs_properties_add_button(props, "Refresh sources",
|
||||||
|
"Refresh list of sources",
|
||||||
|
lambda props,prop: True if callback(props, zs) else True)
|
||||||
|
|
||||||
|
monitor_override = obs.obs_properties_add_bool(props,
|
||||||
|
"Manual Monitor Override", "Enable Monitor Override")
|
||||||
|
|
||||||
|
m = obs.obs_properties_add_list(
|
||||||
|
props,
|
||||||
|
"monitor",
|
||||||
|
"Monitor Override",
|
||||||
|
obs.OBS_COMBO_TYPE_LIST,
|
||||||
|
obs.OBS_COMBO_FORMAT_INT,
|
||||||
|
)
|
||||||
|
populate_list_property_with_monitors(m)
|
||||||
|
|
||||||
|
rm = obs.obs_properties_add_button(props,
|
||||||
|
"Refresh monitors", "Refresh list of monitors", lambda props,
|
||||||
|
prop: True if callback(props, zs) else True)
|
||||||
|
|
||||||
|
mon_size = obs.obs_properties_add_bool(props,
|
||||||
|
"Manual Monitor Dim", "Enable Manual Monitor Dimensions")
|
||||||
|
|
||||||
|
mon_w = obs.obs_properties_add_int(props,
|
||||||
|
"Monitor Width", "Manual Monitor Width", -8000, 8000, 1)
|
||||||
|
mon_h = obs.obs_properties_add_int(props,
|
||||||
|
"Monitor Height", "Manual Monitor Height", -8000, 8000, 1)
|
||||||
|
|
||||||
|
offset = obs.obs_properties_add_bool(props,
|
||||||
|
"Manual Offset", "Enable Manual Offset")
|
||||||
|
|
||||||
|
mx = obs.obs_properties_add_int(props,
|
||||||
|
"Manual X Offset", "Manual X Offset", -8000, 8000, 1)
|
||||||
|
my = obs.obs_properties_add_int(props,
|
||||||
|
"Manual Y Offset", "Manual Y Offset", -8000, 8000, 1)
|
||||||
|
|
||||||
|
obs.obs_properties_add_int(props,
|
||||||
|
"Width", "Zoom Window Width", 320, 3840, 1)
|
||||||
|
obs.obs_properties_add_int(props,
|
||||||
|
"Height", "Zoom Window Height", 240, 3840, 1)
|
||||||
|
obs.obs_properties_add_float_slider(props,
|
||||||
|
"Border", "Active Border", 0, 0.5, 0.01)
|
||||||
|
obs.obs_properties_add_int(props,
|
||||||
|
"Speed", "Max Scroll Speed", 0, 540, 10)
|
||||||
|
obs.obs_properties_add_float_slider(props,
|
||||||
|
"Smooth", "Smooth", 0, 10, 1.00)
|
||||||
|
obs.obs_properties_add_int_slider(props,
|
||||||
|
"Zoom", "Zoom Duration (ms)", 0, 1000, 1)
|
||||||
|
|
||||||
|
mon_show = (True if
|
||||||
|
zoom.source_type in { 'monitor_capture', 'display_capture' }
|
||||||
|
else False)
|
||||||
|
|
||||||
|
obs.obs_property_set_visible(monitor_override, mon_show)
|
||||||
|
obs.obs_property_set_visible(m, zoom.monitor_override)
|
||||||
|
obs.obs_property_set_visible(rm, zoom.monitor_override)
|
||||||
|
obs.obs_property_set_visible(mon_h, zoom.monitor_override)
|
||||||
|
obs.obs_property_set_visible(mon_w, zoom.monitor_override)
|
||||||
|
obs.obs_property_set_visible(mx, zoom.manual_offset)
|
||||||
|
obs.obs_property_set_visible(my, zoom.manual_offset)
|
||||||
|
|
||||||
|
obs.obs_property_set_modified_callback(zs, callback)
|
||||||
|
obs.obs_property_set_modified_callback(monitor_override, callback)
|
||||||
|
obs.obs_property_set_modified_callback(mon_size, callback)
|
||||||
|
obs.obs_property_set_modified_callback(offset, callback)
|
||||||
|
return props
|
||||||
|
|
||||||
|
|
||||||
|
def script_load(settings):
|
||||||
|
global zoom_id_tog
|
||||||
|
|
||||||
|
load_settings = loads(obs.obs_data_get_json(settings))
|
||||||
|
try:
|
||||||
|
[source, source_type] = load_settings['source'].split("||")
|
||||||
|
[zoom.source_name, zoom.source_type] = [source, source_type]
|
||||||
|
except:
|
||||||
|
print(f"Key 'source' does not exist | {load_settings}")
|
||||||
|
|
||||||
|
zoom_id_tog = obs.obs_hotkey_register_frontend(
|
||||||
|
ZOOM_NAME_TOG, ZOOM_DESC_TOG, toggle_zoom
|
||||||
|
)
|
||||||
|
hotkey_save_array = obs.obs_data_get_array(settings, ZOOM_NAME_TOG)
|
||||||
|
obs.obs_hotkey_load(zoom_id_tog, hotkey_save_array)
|
||||||
|
obs.obs_data_array_release(hotkey_save_array)
|
||||||
|
|
||||||
|
global follow_id_tog
|
||||||
|
follow_id_tog = obs.obs_hotkey_register_frontend(
|
||||||
|
FOLLOW_NAME_TOG, FOLLOW_DESC_TOG, toggle_follow
|
||||||
|
)
|
||||||
|
hotkey_save_array = obs.obs_data_get_array(settings, FOLLOW_NAME_TOG)
|
||||||
|
obs.obs_hotkey_load(follow_id_tog, hotkey_save_array)
|
||||||
|
obs.obs_data_array_release(hotkey_save_array)
|
||||||
|
zoom.update_sources()
|
||||||
|
zoom.new_source = True
|
||||||
|
|
||||||
|
|
||||||
|
def script_unload():
|
||||||
|
obs.obs_hotkey_unregister(toggle_zoom)
|
||||||
|
obs.obs_hotkey_unregister(toggle_follow)
|
||||||
|
|
||||||
|
|
||||||
|
def script_save(settings):
|
||||||
|
hotkey_save_array = obs.obs_hotkey_save(zoom_id_tog)
|
||||||
|
obs.obs_data_set_array(settings, ZOOM_NAME_TOG, hotkey_save_array)
|
||||||
|
obs.obs_data_array_release(hotkey_save_array)
|
||||||
|
|
||||||
|
hotkey_save_array = obs.obs_hotkey_save(follow_id_tog)
|
||||||
|
obs.obs_data_set_array(settings, FOLLOW_NAME_TOG, hotkey_save_array)
|
||||||
|
obs.obs_data_array_release(hotkey_save_array)
|
||||||
|
|
||||||
|
|
||||||
|
def toggle_zoom(pressed):
|
||||||
|
if pressed:
|
||||||
|
if new_source:
|
||||||
|
zoom.update_sources()
|
||||||
|
if zoom.source_name != "" and zoom.flag:
|
||||||
|
zoom.update_source_size()
|
||||||
|
obs.timer_add(zoom.tick, zoom.refresh_rate)
|
||||||
|
zoom.lock = True
|
||||||
|
zoom.flag = False
|
||||||
|
elif not zoom.flag:
|
||||||
|
zoom.flag = True
|
||||||
|
zoom.lock = False
|
||||||
|
print(f"Zoom: {zoom.lock}")
|
||||||
|
if zoom.lock:
|
||||||
|
print(f"Mouse position: {get_position()}")
|
||||||
|
|
||||||
|
|
||||||
|
def toggle_follow(pressed):
|
||||||
|
if pressed:
|
||||||
|
if zoom.track:
|
||||||
|
zoom.track = False
|
||||||
|
elif not zoom.track:
|
||||||
|
zoom.track = True
|
||||||
|
print(f"Tracking: {zoom.track}")
|
|
@ -1,6 +1,6 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
for imapnotify_config in ~/Documents/passwords/*_imapnotify.json; do
|
for imapnotify_config in ~/Documents/Passwords/*_imapnotify.json; do
|
||||||
LOG_FILE=$(sed 's#/#_#g' <<< "$imapnotify_config" )
|
LOG_FILE=$(sed 's#/#_#g' <<< "$imapnotify_config" )
|
||||||
# sleep for internet to get ready lol
|
# sleep for internet to get ready lol
|
||||||
(sleep 60 && goimapnotify -conf "$imapnotify_config" &> ~/.cache/"$LOG_FILE") &
|
(sleep 60 && goimapnotify -conf "$imapnotify_config" &> ~/.cache/"$LOG_FILE") &
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#!/bin/bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
|
||||||
unset LOCK_KEEPASSXC
|
unset LOCK_KEEPASSXC
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
# I didn't write this!
|
||||||
|
|
||||||
|
import json,yaml,sys,os
|
||||||
|
|
||||||
|
if len(sys.argv) != 2:
|
||||||
|
print('Usage:\n '+os.path.basename(__file__)+' /path/file{.json|.yml}')
|
||||||
|
print('\nConverts JSON to YAML, and vice-versa')
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
path = sys.argv[1]
|
||||||
|
|
||||||
|
if not os.path.isfile(path):
|
||||||
|
print('Bad or non-existant file: '+path)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
with open(path) as file:
|
||||||
|
|
||||||
|
if path.lower().endswith('json'):
|
||||||
|
print(yaml.dump(json.load(file), Dumper=yaml.CDumper, allow_unicode=True))
|
||||||
|
elif path.lower().endswith('yaml') or path.lower().endswith('yml'):
|
||||||
|
print(json.dumps(yaml.load(file, Loader=yaml.SafeLoader), ensure_ascii=False ,indent=2))
|
||||||
|
else:
|
||||||
|
print('Bad file extension. Must be yml or json')
|
||||||
|
|
|
@ -35,7 +35,7 @@ bspc rule -a Thunderbird desktop='^8'
|
||||||
bspc rule -a KeePassXC desktop='^8'
|
bspc rule -a KeePassXC desktop='^8'
|
||||||
# the confirm dialog
|
# the confirm dialog
|
||||||
bspc rule -a "KeePassXC:*:Confirm Auto-Type" sticky=on
|
bspc rule -a "KeePassXC:*:Confirm Auto-Type" sticky=on
|
||||||
bspc rule -a "Dragon-drag-and-drop" sticky=on
|
bspc rule -a "Dragon-drop" sticky=on
|
||||||
|
|
||||||
bspc rule -a Dino desktop='^8'
|
bspc rule -a Dino desktop='^8'
|
||||||
bspc rule -a Peek state=floating
|
bspc rule -a Peek state=floating
|
||||||
|
|
|
@ -86,6 +86,9 @@ remove warning by use-package
|
||||||
#+end_src
|
#+end_src
|
||||||
Emacs Backups trashing local dir!
|
Emacs Backups trashing local dir!
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
|
(use-package no-littering
|
||||||
|
(setq auto-save-file-name-transforms
|
||||||
|
`((".*" ,(no-littering-expand-var-file-name "auto-save/") t))))
|
||||||
(setq backup-directory-alist `(("." . "~/.local/share/emacs-backups")))
|
(setq backup-directory-alist `(("." . "~/.local/share/emacs-backups")))
|
||||||
(setq make-backup-files t ; backup of a file the first time it is saved.
|
(setq make-backup-files t ; backup of a file the first time it is saved.
|
||||||
backup-by-copying t ; don't clobber symlinks
|
backup-by-copying t ; don't clobber symlinks
|
||||||
|
@ -198,13 +201,13 @@ Actuall Theme:
|
||||||
(doom-themes-org-config))
|
(doom-themes-org-config))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
Transperancy!
|
Transparency!
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
;; for the first frame
|
;; for the first frame
|
||||||
(set-frame-parameter nil 'alpha-background 0.9)
|
(set-frame-parameter nil 'alpha-background 0.8)
|
||||||
;; for other frames
|
;; for other frames
|
||||||
(add-hook 'server-after-make-frame-hook
|
(add-hook 'server-after-make-frame-hook
|
||||||
(lambda nil (set-frame-parameter nil 'alpha-background 0.9)))
|
(lambda nil (set-frame-parameter nil 'alpha-background 0.8)))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
Center text in the frame, looks nice ;)
|
Center text in the frame, looks nice ;)
|
||||||
|
@ -520,8 +523,10 @@ Capture
|
||||||
"cl" '(lsp-avy-lens :which-key "Code Action")
|
"cl" '(lsp-avy-lens :which-key "Code Action")
|
||||||
"ci" '(lsp-ui-imenu :which-key "lsp imenu")
|
"ci" '(lsp-ui-imenu :which-key "lsp imenu")
|
||||||
"cr" '(lsp-rename :which-key "rename")
|
"cr" '(lsp-rename :which-key "rename")
|
||||||
"cs" '(lsp-find-refernces :which-key "find refernces")
|
;"cs" '(lsp-find-refernces :which-key "find refernces")
|
||||||
"cd" '(lsp-find-definition :which-key "goto defintion")
|
;"cd" '(lsp-find-definition :which-key "goto defintion")
|
||||||
|
"cd" '(lsp-ui-peek-find-definitions :which-key "goto defintion")
|
||||||
|
"cs" '(lsp-ui-peek-find-refernces :which-key "find refernces")
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
**** Git (g)
|
**** Git (g)
|
||||||
|
@ -600,7 +605,7 @@ Capture
|
||||||
(define-key evil-insert-state-map "\C-y" 'yank)
|
(define-key evil-insert-state-map "\C-y" 'yank)
|
||||||
(define-key evil-visual-state-map "\C-y" 'yank)
|
(define-key evil-visual-state-map "\C-y" 'yank)
|
||||||
|
|
||||||
(define-key evil-normal-state-map "K" 'lsp-ui-doc-glance); TODO: all modes
|
;(define-key evil-normal-state-map "K" 'lsp-ui-doc-glance); moved to lsp-ui
|
||||||
(define-key evil-visual-state-map "\C-y" 'yank)
|
(define-key evil-visual-state-map "\C-y" 'yank)
|
||||||
;(define-key evil-insert-state-map "\C-k" 'kill-line)
|
;(define-key evil-insert-state-map "\C-k" 'kill-line)
|
||||||
(define-key evil-normal-state-map "Q" 'call-last-kbd-macro)
|
(define-key evil-normal-state-map "Q" 'call-last-kbd-macro)
|
||||||
|
@ -922,16 +927,16 @@ use-package
|
||||||
(setq org-log-done 'time)
|
(setq org-log-done 'time)
|
||||||
(setq org-log-into-drawer t)
|
(setq org-log-into-drawer t)
|
||||||
(dolist (face '((org-document-title . 2.0)
|
(dolist (face '((org-document-title . 2.0)
|
||||||
(org-level-1 . 1.2)
|
(org-level-1 . 1.5)
|
||||||
(org-level-2 . 1.1)
|
(org-level-2 . 1.0)
|
||||||
(org-level-3 . 1.05)
|
(org-level-3 . 1.0)
|
||||||
(org-level-4 . 1.0)
|
(org-level-4 . 1.0)
|
||||||
(org-level-5 . 1.1)
|
(org-level-5 . 1.0)
|
||||||
(org-level-6 . 1.1)
|
(org-level-6 . 1.0)
|
||||||
(org-level-7 . 1.1)
|
(org-level-7 . 1.0)
|
||||||
(org-level-8 . 1.1)))
|
(org-level-8 . 1.0)))
|
||||||
;; (set-face-attribute (car face) nil :font my/ui/varfont :weight 'regular :height (cdr face)))
|
;; (set-face-attribute (car face) nil :font my/ui/varfont :weight 'regular :height (cdr face)))
|
||||||
(set-face-attribute (car face) nil :font my/ui/varfont :weight 'regular :height (cdr face)))
|
(set-face-attribute (car face) nil :font my/ui/monofont :weight 'regular :height (cdr face)))
|
||||||
;)
|
;)
|
||||||
|
|
||||||
(setq org-todo-keyword-faces `(("NOW" (:foreground "white" :background "#444527"))
|
(setq org-todo-keyword-faces `(("NOW" (:foreground "white" :background "#444527"))
|
||||||
|
@ -1496,7 +1501,7 @@ Stopped using this, I just use Anki like a normal person
|
||||||
(use-package rainbow-delimiters
|
(use-package rainbow-delimiters
|
||||||
:hook (prog-mode . rainbow-delimiters-mode)
|
:hook (prog-mode . rainbow-delimiters-mode)
|
||||||
(prog-mode . show-paren-mode)
|
(prog-mode . show-paren-mode)
|
||||||
(prog-mode . electric-pair-local-mode)
|
;(prog-mode . electric-pair-local-mode)
|
||||||
)
|
)
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
|
@ -1542,7 +1547,11 @@ Counsel Projectile
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
(use-package recentf
|
(use-package recentf
|
||||||
:defer 10
|
:defer 10
|
||||||
:config (recentf-mode 1))
|
:config (recentf-mode 1)
|
||||||
|
; https://github.com/emacscollective/no-littering#suggested-settings
|
||||||
|
(with-eval-after-load 'no-littering
|
||||||
|
(add-to-list 'recentf-exclude no-littering-var-directory)
|
||||||
|
(add-to-list 'recentf-exclude no-littering-etc-directory)))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
*** lsp performance
|
*** lsp performance
|
||||||
|
@ -1595,6 +1604,8 @@ Lsp UI
|
||||||
;; (lsp-ui-doc-enable nil)
|
;; (lsp-ui-doc-enable nil)
|
||||||
:bind
|
:bind
|
||||||
(:map lsp-ui-mode-map
|
(:map lsp-ui-mode-map
|
||||||
|
([remap evil-lookup] . lsp-ui-doc-glance)
|
||||||
|
([remap xref-find-references] . lsp-ui-peek-find-references)
|
||||||
("C-c z" . lsp-ui-doc-focus-frame)
|
("C-c z" . lsp-ui-doc-focus-frame)
|
||||||
:map lsp-ui-doc-frame-mode-map
|
:map lsp-ui-doc-frame-mode-map
|
||||||
("C-g" . lsp-ui-doc-unfocus-frame)
|
("C-g" . lsp-ui-doc-unfocus-frame)
|
||||||
|
@ -1602,6 +1613,8 @@ Lsp UI
|
||||||
))
|
))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
|
#+RESULTS:
|
||||||
|
|
||||||
*** lsp treemacs
|
*** lsp treemacs
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
;; (use-package lsp-treemacs
|
;; (use-package lsp-treemacs
|
||||||
|
@ -1753,9 +1766,6 @@ Auto format
|
||||||
;; comment to disable rustfmt on save
|
;; comment to disable rustfmt on save
|
||||||
(setq rustic-format-on-save t)
|
(setq rustic-format-on-save t)
|
||||||
(add-hook 'rustic-mode-hook 'my/dev/rustic-mode-hook)
|
(add-hook 'rustic-mode-hook 'my/dev/rustic-mode-hook)
|
||||||
;; (add-hook 'rustic-mode-hook 'electric-pair-mode)
|
|
||||||
;; (define-key lsp-ui-mode-map [remap xref-find-definitions] #'lsp-ui-peek-find-definitions)
|
|
||||||
;; (define-key lsp-ui-mode-map [remap xref-find-references] #'lsp-ui-peek-find-references)
|
|
||||||
(add-hook 'rustic-mode-hook 'lsp)
|
(add-hook 'rustic-mode-hook 'lsp)
|
||||||
:custom
|
:custom
|
||||||
(rustic-rustfmt-config-alist '((edition . "2021"))))
|
(rustic-rustfmt-config-alist '((edition . "2021"))))
|
||||||
|
@ -1866,7 +1876,9 @@ Auto format
|
||||||
;; formats the buffer before saving
|
;; formats the buffer before saving
|
||||||
;; (add-hook 'before-save-hook 'tide-format-before-save)
|
;; (add-hook 'before-save-hook 'tide-format-before-save)
|
||||||
(add-hook 'before-save-hook 'prettier-js)
|
(add-hook 'before-save-hook 'prettier-js)
|
||||||
|
(add-to-list 'auto-mode-alist '("\\.tsx\\'" . js-jsx-mode))
|
||||||
:hook(typescript-mode . setup-tide-mode)
|
:hook(typescript-mode . setup-tide-mode)
|
||||||
|
:hook(typescript-mode . prettier-mode)
|
||||||
:hook(typescript-mode . lsp))
|
:hook(typescript-mode . lsp))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
|
@ -1889,6 +1901,7 @@ lsp hooks setups
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
(add-hook 'html-mode-hook 'lsp)
|
(add-hook 'html-mode-hook 'lsp)
|
||||||
(add-hook 'js-mode-hook 'lsp)
|
(add-hook 'js-mode-hook 'lsp)
|
||||||
|
(add-hook 'js-jsx-mode-hook 'lsp)
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
*** Lua
|
*** Lua
|
||||||
|
@ -2151,7 +2164,8 @@ ivy bibtex
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
(use-package nix-mode
|
(use-package nix-mode
|
||||||
:hook (nix-mode . (lambda ()
|
:hook (nix-mode . (lambda ()
|
||||||
(add-hook 'before-save-hook 'nix-mode-format nil t))))
|
;(add-hook 'before-save-hook 'nix-mode-format nil t)))); doesn't require nixfmt
|
||||||
|
(add-hook 'before-save-hook 'nix-format-buffer nil t))))
|
||||||
|
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
|
@ -2193,8 +2207,8 @@ ivy bibtex
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
(use-package vterm
|
(use-package vterm
|
||||||
:commands vterm
|
:commands vterm
|
||||||
;; :bind (:map vterm-mode-map
|
:bind (:map vterm-mode-map
|
||||||
;; ("C-t" . vterm-toggle))
|
("C-t" . vterm-toggle))
|
||||||
:config
|
:config
|
||||||
;;Toggle vterm
|
;;Toggle vterm
|
||||||
(evil-define-key '(normal visual insert) 'vterm-mode-map (kbd "C-t") 'vterm-toggle)
|
(evil-define-key '(normal visual insert) 'vterm-mode-map (kbd "C-t") 'vterm-toggle)
|
||||||
|
@ -2424,7 +2438,7 @@ I wrote that, neat isn't it? :P
|
||||||
#+begin_src emacs-lisp :tangle no
|
#+begin_src emacs-lisp :tangle no
|
||||||
;; Doesn't tangle!
|
;; Doesn't tangle!
|
||||||
;; loaded in use-package (block below)
|
;; loaded in use-package (block below)
|
||||||
(load "~/Documents/passwords/circe-networks.el")
|
(load "~/Nextcloud/Passwords/circe-networks.el")
|
||||||
|
|
||||||
; example content
|
; example content
|
||||||
(add-to-list 'circe-networks `("chat.name/username" :host "irc.example.com" :port 69
|
(add-to-list 'circe-networks `("chat.name/username" :host "irc.example.com" :port 69
|
||||||
|
@ -2475,7 +2489,7 @@ I wrote that, neat isn't it? :P
|
||||||
(enable-lui-track)
|
(enable-lui-track)
|
||||||
;(add-to-list 'circe-networks `())
|
;(add-to-list 'circe-networks `())
|
||||||
;; adding to list happens here!
|
;; adding to list happens here!
|
||||||
(load "~/Documents/passwords/circe-networks.el")
|
(load "~/Nextcloud/Passwords/circe-networks.el")
|
||||||
(setq circe-color-nicks-min-constrast-ratio 4.5
|
(setq circe-color-nicks-min-constrast-ratio 4.5
|
||||||
circe-color-nicks-everywhere t)
|
circe-color-nicks-everywhere t)
|
||||||
:hook (circe-channel-mode . enable-circe-color-nicks)
|
:hook (circe-channel-mode . enable-circe-color-nicks)
|
||||||
|
@ -2519,9 +2533,12 @@ I wrote that, neat isn't it? :P
|
||||||
* Email (mu4e)
|
* Email (mu4e)
|
||||||
** Package
|
** Package
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
(use-package mu4e
|
|
||||||
:demand
|
(use-package mu4e ;
|
||||||
;; :ensure-system-package mu
|
;; this line is for nixos
|
||||||
|
;; until here
|
||||||
|
;;:ensure-system-package mu
|
||||||
|
:commands (mu4e)
|
||||||
:bind (:map mu4e-main-mode-map
|
:bind (:map mu4e-main-mode-map
|
||||||
([remap revert-buffer] . mu4e-update-index))
|
([remap revert-buffer] . mu4e-update-index))
|
||||||
:custom
|
:custom
|
||||||
|
@ -2540,8 +2557,8 @@ I wrote that, neat isn't it? :P
|
||||||
(mu4e-view-mode . olivetti-mode)
|
(mu4e-view-mode . olivetti-mode)
|
||||||
(mu4e-main-mode . olivetti-mode)
|
(mu4e-main-mode . olivetti-mode)
|
||||||
(mu4e-compose-mode . flyspell-mode)
|
(mu4e-compose-mode . flyspell-mode)
|
||||||
(mu4e-context-changed . mu4e-update-index)
|
(mu4e-context-changed . mu4e-update-index))
|
||||||
)
|
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
** Contexts
|
** Contexts
|
||||||
|
@ -2550,6 +2567,7 @@ I wrote that, neat isn't it? :P
|
||||||
;; ~/Maildir/Account0/{Inbox,Sent,Trash}
|
;; ~/Maildir/Account0/{Inbox,Sent,Trash}
|
||||||
;; ~/Maildir/Account1/{Inbox,Sent,Trash}
|
;; ~/Maildir/Account1/{Inbox,Sent,Trash}
|
||||||
;; where Account0 is context name
|
;; where Account0 is context name
|
||||||
|
(with-eval-after-load 'mu4e
|
||||||
(defun my-make-mu4e-context (context-name full-name mail-address signature)
|
(defun my-make-mu4e-context (context-name full-name mail-address signature)
|
||||||
"Return a mu4e context named CONTEXT-NAME with :match-func matching
|
"Return a mu4e context named CONTEXT-NAME with :match-func matching
|
||||||
folder name CONTEXT-NAME in Maildir. The context's `user-mail-address',
|
folder name CONTEXT-NAME in Maildir. The context's `user-mail-address',
|
||||||
|
@ -2597,7 +2615,7 @@ I wrote that, neat isn't it? :P
|
||||||
(mu4e-drafts-folder . ,(concat dir-name "/Drafts"))
|
(mu4e-drafts-folder . ,(concat dir-name "/Drafts"))
|
||||||
(mu4e-trash-folder . ,(concat dir-name "/Trash"))
|
(mu4e-trash-folder . ,(concat dir-name "/Trash"))
|
||||||
(mu4e-refile-folder . ,(concat dir-name "/Archive"))
|
(mu4e-refile-folder . ,(concat dir-name "/Archive"))
|
||||||
(mu4e-compose-signature . ,signature)))))
|
(mu4e-compose-signature . ,signature))))))
|
||||||
;;Fixing duplicate UID errors when using mbsync and mu4e
|
;;Fixing duplicate UID errors when using mbsync and mu4e
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
|
@ -2606,6 +2624,7 @@ I wrote that, neat isn't it? :P
|
||||||
;; This is a sample, it doesn't get included in init.el
|
;; This is a sample, it doesn't get included in init.el
|
||||||
;; I put mine at location specified in the next code block
|
;; I put mine at location specified in the next code block
|
||||||
;; any number of email can be used ofc
|
;; any number of email can be used ofc
|
||||||
|
(with-eval-after-load 'mu4e
|
||||||
(setq mu4e-contexts `(
|
(setq mu4e-contexts `(
|
||||||
,(my-make-mu4e-context
|
,(my-make-mu4e-context
|
||||||
"maildir-context" "Full Name"
|
"maildir-context" "Full Name"
|
||||||
|
@ -2613,13 +2632,13 @@ I wrote that, neat isn't it? :P
|
||||||
,(my-make-mu4e-context
|
,(my-make-mu4e-context
|
||||||
"maildir-context2" "Full Name2"
|
"maildir-context2" "Full Name2"
|
||||||
"Email Address2" "Signature2")
|
"Email Address2" "Signature2")
|
||||||
))
|
)))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
or don't include in git source :)
|
or don't include in git source :)
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
(eval-after-load 'mu4e
|
(with-eval-after-load 'mu4e
|
||||||
(load "~/Documents/passwords/mu4e-context.el"))
|
(load "~/Nextcloud/Passwords/mu4e-context.el"))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
** Other fixes
|
** Other fixes
|
||||||
|
@ -2628,7 +2647,9 @@ see: [[https://github.com/djcb/mu/issues/1136][djcb/mu#1136 Shouldn't set flag T
|
||||||
should only move to trash, not delete entirely from the server
|
should only move to trash, not delete entirely from the server
|
||||||
|
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
(setf (alist-get 'trash mu4e-marks)
|
|
||||||
|
(with-eval-after-load 'mu4e
|
||||||
|
(setf (alist-get 'trash mu4e-marks)
|
||||||
(list :char '("d" . "▼")
|
(list :char '("d" . "▼")
|
||||||
:prompt "dtrash"
|
:prompt "dtrash"
|
||||||
:dyn-target (lambda (target msg)
|
:dyn-target (lambda (target msg)
|
||||||
|
@ -2637,7 +2658,7 @@ should only move to trash, not delete entirely from the server
|
||||||
;; Here's the main difference to the regular trash mark,
|
;; Here's the main difference to the regular trash mark,
|
||||||
;; no +T before -N so the message is not marked as
|
;; no +T before -N so the message is not marked as
|
||||||
;; IMAP-deleted:
|
;; IMAP-deleted:
|
||||||
(mu4e--server-move docid (mu4e--mark-check-target target) "-N"))))
|
(mu4e--server-move docid (mu4e--mark-check-target target) "-N")))))
|
||||||
|
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
|
@ -2659,9 +2680,10 @@ I prefer text/plain, over everything >:)
|
||||||
(add-to-list 'mm-discouraged-alternatives "text/richtext")
|
(add-to-list 'mm-discouraged-alternatives "text/richtext")
|
||||||
(add-to-list 'mm-discouraged-alternatives "text/html"))
|
(add-to-list 'mm-discouraged-alternatives "text/html"))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
** Send email (msmtp)
|
** Send email (msmtp)
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
(setq sendmail-program "/usr/bin/msmtp"
|
(setq sendmail-program (executable-find "msmtp") ;"/usr/bin/msmtp"
|
||||||
message-sendmail-f-is-evil t
|
message-sendmail-f-is-evil t
|
||||||
message-sendmail-extra-arguments '("--read-envelope-from")
|
message-sendmail-extra-arguments '("--read-envelope-from")
|
||||||
send-mail-function 'smtpmail-send-it
|
send-mail-function 'smtpmail-send-it
|
||||||
|
|
|
@ -1,15 +1,17 @@
|
||||||
# Beware! This file is rewritten by htop when settings are changed in the interface.
|
# Beware! This file is rewritten by htop when settings are changed in the interface.
|
||||||
# The parser is also very primitive, and not human-friendly.
|
# The parser is also very primitive, and not human-friendly.
|
||||||
htop_version=3.2.1
|
htop_version=3.2.2
|
||||||
config_reader_min_version=3
|
config_reader_min_version=3
|
||||||
fields=0 48 17 18 38 39 40 2 46 47 49 1
|
fields=0 48 17 18 38 39 40 2 46 47 49 1
|
||||||
hide_kernel_threads=1
|
hide_kernel_threads=1
|
||||||
hide_userland_threads=1
|
hide_userland_threads=1
|
||||||
|
hide_running_in_container=0
|
||||||
shadow_other_users=0
|
shadow_other_users=0
|
||||||
show_thread_names=0
|
show_thread_names=0
|
||||||
show_program_path=0
|
show_program_path=1
|
||||||
highlight_base_name=1
|
highlight_base_name=0
|
||||||
highlight_deleted_exe=1
|
highlight_deleted_exe=1
|
||||||
|
shadow_distribution_path_prefix=0
|
||||||
highlight_megabytes=1
|
highlight_megabytes=1
|
||||||
highlight_threads=1
|
highlight_threads=1
|
||||||
highlight_changes=0
|
highlight_changes=0
|
||||||
|
@ -18,39 +20,41 @@ find_comm_in_cmdline=1
|
||||||
strip_exe_from_cmdline=1
|
strip_exe_from_cmdline=1
|
||||||
show_merged_command=1
|
show_merged_command=1
|
||||||
header_margin=1
|
header_margin=1
|
||||||
screen_tabs=1
|
screen_tabs=0
|
||||||
detailed_cpu_time=0
|
detailed_cpu_time=0
|
||||||
cpu_count_from_one=1
|
cpu_count_from_one=0
|
||||||
show_cpu_usage=1
|
show_cpu_usage=1
|
||||||
show_cpu_frequency=0
|
show_cpu_frequency=0
|
||||||
|
show_cpu_temperature=0
|
||||||
|
degree_fahrenheit=0
|
||||||
update_process_names=0
|
update_process_names=0
|
||||||
account_guest_in_cpu_meter=0
|
account_guest_in_cpu_meter=0
|
||||||
color_scheme=0
|
color_scheme=0
|
||||||
enable_mouse=1
|
enable_mouse=1
|
||||||
delay=20
|
delay=15
|
||||||
hide_function_bar=0
|
hide_function_bar=0
|
||||||
header_layout=two_50_50
|
header_layout=two_50_50
|
||||||
column_meters_0=LeftCPUs2 CPU Battery Blank Blank Blank Memory NetworkIO DiskIO
|
column_meters_0=LeftCPUs2 Memory Swap Clock NetworkIO
|
||||||
column_meter_modes_0=1 1 1 2 2 2 3 4 4
|
column_meter_modes_0=1 1 1 4 3
|
||||||
column_meters_1=RightCPUs2 Memory Zram Swap Blank Blank Blank LoadAverage Uptime Tasks
|
column_meters_1=RightCPUs2 Tasks LoadAverage Uptime DiskIO
|
||||||
column_meter_modes_1=1 1 1 1 2 2 2 3 4 4
|
column_meter_modes_1=1 2 2 4 3
|
||||||
tree_view=0
|
tree_view=0
|
||||||
sort_key=46
|
sort_key=47
|
||||||
tree_sort_key=46
|
tree_sort_key=0
|
||||||
sort_direction=-1
|
sort_direction=-1
|
||||||
tree_sort_direction=1
|
tree_sort_direction=1
|
||||||
tree_view_always_by_pid=0
|
tree_view_always_by_pid=0
|
||||||
all_branches_collapsed=0
|
all_branches_collapsed=0
|
||||||
screen:Main=PID USER PRIORITY NICE M_VIRT M_RESIDENT M_SHARE STATE PERCENT_CPU PERCENT_MEM TIME Command
|
screen:Main=PID USER PRIORITY NICE M_VIRT M_RESIDENT M_SHARE STATE PERCENT_CPU PERCENT_MEM TIME Command
|
||||||
.sort_key=PERCENT_CPU
|
.sort_key=PERCENT_MEM
|
||||||
.tree_sort_key=PERCENT_CPU
|
.tree_sort_key=PID
|
||||||
.tree_view=0
|
.tree_view=0
|
||||||
.tree_view_always_by_pid=0
|
.tree_view_always_by_pid=0
|
||||||
.sort_direction=-1
|
.sort_direction=-1
|
||||||
.tree_sort_direction=1
|
.tree_sort_direction=1
|
||||||
.all_branches_collapsed=0
|
.all_branches_collapsed=0
|
||||||
screen:I/O=PID USER IO_PRIORITY IO_RATE IO_READ_RATE IO_WRITE_RATE PERCENT_SWAP_DELAY PERCENT_IO_DELAY Command
|
screen:I/O=PID USER IO_PRIORITY IO_RATE IO_READ_RATE IO_WRITE_RATE PERCENT_SWAP_DELAY PERCENT_IO_DELAY Command
|
||||||
.sort_key=IO_WRITE_RATE
|
.sort_key=IO_RATE
|
||||||
.tree_sort_key=PID
|
.tree_sort_key=PID
|
||||||
.tree_view=0
|
.tree_view=0
|
||||||
.tree_view_always_by_pid=0
|
.tree_view_always_by_pid=0
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
sub-file-paths=ass:srt:sub:Sub:subs:Subs:subtitles:Subtitles
|
sub-file-paths=ass:srt:sub:Sub:subs:Subs:subtitles:Subtitles
|
||||||
sub-auto=fuzzy
|
sub-auto=fuzzy
|
||||||
|
alang=jpn
|
||||||
|
|
||||||
screenshot-format=png
|
screenshot-format=png
|
||||||
screenshot-high-bit-depth=yes
|
screenshot-high-bit-depth=yes
|
||||||
|
@ -10,3 +11,6 @@ screenshot-directory="~/Pictures/screenshots"
|
||||||
screenshot-template="%f-%wH.%wM.%wS.%wT-#%#00n"
|
screenshot-template="%f-%wH.%wM.%wS.%wT-#%#00n"
|
||||||
force-window=immediate
|
force-window=immediate
|
||||||
hwdec=auto
|
hwdec=auto
|
||||||
|
|
||||||
|
script-opts-append=ytdl_hook-ytdl_path=yt-dlp
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
####################
|
####################
|
||||||
|
|
||||||
# Anki deck for new cards. Subdecks are supported.
|
# Anki deck for new cards. Subdecks are supported.
|
||||||
deck_name=Japanese::Mining
|
deck_name=all::Japanese::Mining
|
||||||
|
|
||||||
# Model names are listed in `Tools -> Manage note types` menu in Anki.
|
# Model names are listed in `Tools -> Manage note types` menu in Anki.
|
||||||
model_name=animecards
|
model_name=animecards
|
||||||
|
|
|
@ -0,0 +1,275 @@
|
||||||
|
-- youtube-quality.lua
|
||||||
|
-- Source: https://github.com/jgreco/mpv-youtube-quality/blob/master/youtube-quality.lua
|
||||||
|
-- Change youtube video quality on the fly.
|
||||||
|
--
|
||||||
|
-- Diplays a menu that lets you switch to different ytdl-format settings while
|
||||||
|
-- you're in the middle of a video (just like you were using the web player).
|
||||||
|
--
|
||||||
|
-- Bound to ctrl-f by default.
|
||||||
|
|
||||||
|
local mp = require 'mp'
|
||||||
|
local utils = require 'mp.utils'
|
||||||
|
local msg = require 'mp.msg'
|
||||||
|
local assdraw = require 'mp.assdraw'
|
||||||
|
|
||||||
|
local opts = {
|
||||||
|
--key bindings
|
||||||
|
toggle_menu_binding = "ctrl+f",
|
||||||
|
up_binding = "UP",
|
||||||
|
down_binding = "DOWN",
|
||||||
|
select_binding = "ENTER",
|
||||||
|
|
||||||
|
--formatting / cursors
|
||||||
|
selected_and_active = "▶ - ",
|
||||||
|
selected_and_inactive = "● - ",
|
||||||
|
unselected_and_active = "▷ - ",
|
||||||
|
unselected_and_inactive = "○ - ",
|
||||||
|
|
||||||
|
--font size scales by window, if false requires larger font and padding sizes
|
||||||
|
scale_playlist_by_window=false,
|
||||||
|
|
||||||
|
--playlist ass style overrides inside curly brackets, \keyvalue is one field, extra \ for escape in lua
|
||||||
|
--example {\\fnUbuntu\\fs10\\b0\\bord1} equals: font=Ubuntu, size=10, bold=no, border=1
|
||||||
|
--read http://docs.aegisub.org/3.2/ASS_Tags/ for reference of tags
|
||||||
|
--undeclared tags will use default osd settings
|
||||||
|
--these styles will be used for the whole playlist. More specific styling will need to be hacked in
|
||||||
|
--
|
||||||
|
--(a monospaced font is recommended but not required)
|
||||||
|
style_ass_tags = "{\\fnmonospace}",
|
||||||
|
|
||||||
|
--paddings for top left corner
|
||||||
|
text_padding_x = 5,
|
||||||
|
text_padding_y = 5,
|
||||||
|
|
||||||
|
--other
|
||||||
|
menu_timeout = 10,
|
||||||
|
|
||||||
|
--use youtube-dl to fetch a list of available formats (overrides quality_strings)
|
||||||
|
fetch_formats = true,
|
||||||
|
|
||||||
|
--default menu entries
|
||||||
|
quality_strings=[[
|
||||||
|
[
|
||||||
|
{"4320p" : "bestvideo[height<=?4320p]+bestaudio/best"},
|
||||||
|
{"2160p" : "bestvideo[height<=?2160]+bestaudio/best"},
|
||||||
|
{"1440p" : "bestvideo[height<=?1440]+bestaudio/best"},
|
||||||
|
{"1080p" : "bestvideo[height<=?1080]+bestaudio/best"},
|
||||||
|
{"720p" : "bestvideo[height<=?720]+bestaudio/best"},
|
||||||
|
{"480p" : "bestvideo[height<=?480]+bestaudio/best"},
|
||||||
|
{"360p" : "bestvideo[height<=?360]+bestaudio/best"},
|
||||||
|
{"240p" : "bestvideo[height<=?240]+bestaudio/best"},
|
||||||
|
{"144p" : "bestvideo[height<=?144]+bestaudio/best"}
|
||||||
|
]
|
||||||
|
]],
|
||||||
|
}
|
||||||
|
(require 'mp.options').read_options(opts, "youtube-quality")
|
||||||
|
opts.quality_strings = utils.parse_json(opts.quality_strings)
|
||||||
|
|
||||||
|
local destroyer = nil
|
||||||
|
|
||||||
|
|
||||||
|
function show_menu()
|
||||||
|
local selected = 1
|
||||||
|
local active = 0
|
||||||
|
local current_ytdl_format = mp.get_property("ytdl-format")
|
||||||
|
msg.verbose("current ytdl-format: "..current_ytdl_format)
|
||||||
|
local num_options = 0
|
||||||
|
local options = {}
|
||||||
|
|
||||||
|
|
||||||
|
if opts.fetch_formats then
|
||||||
|
options, num_options = download_formats()
|
||||||
|
end
|
||||||
|
|
||||||
|
if next(options) == nil then
|
||||||
|
for i,v in ipairs(opts.quality_strings) do
|
||||||
|
num_options = num_options + 1
|
||||||
|
for k,v2 in pairs(v) do
|
||||||
|
options[i] = {label = k, format=v2}
|
||||||
|
if v2 == current_ytdl_format then
|
||||||
|
active = i
|
||||||
|
selected = active
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--set the cursor to the currently format
|
||||||
|
for i,v in ipairs(options) do
|
||||||
|
if v.format == current_ytdl_format then
|
||||||
|
active = i
|
||||||
|
selected = active
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function selected_move(amt)
|
||||||
|
selected = selected + amt
|
||||||
|
if selected < 1 then selected = num_options
|
||||||
|
elseif selected > num_options then selected = 1 end
|
||||||
|
timeout:kill()
|
||||||
|
timeout:resume()
|
||||||
|
draw_menu()
|
||||||
|
end
|
||||||
|
function choose_prefix(i)
|
||||||
|
if i == selected and i == active then return opts.selected_and_active
|
||||||
|
elseif i == selected then return opts.selected_and_inactive end
|
||||||
|
|
||||||
|
if i ~= selected and i == active then return opts.unselected_and_active
|
||||||
|
elseif i ~= selected then return opts.unselected_and_inactive end
|
||||||
|
return "> " --shouldn't get here.
|
||||||
|
end
|
||||||
|
|
||||||
|
function draw_menu()
|
||||||
|
local ass = assdraw.ass_new()
|
||||||
|
|
||||||
|
ass:pos(opts.text_padding_x, opts.text_padding_y)
|
||||||
|
ass:append(opts.style_ass_tags)
|
||||||
|
|
||||||
|
for i,v in ipairs(options) do
|
||||||
|
ass:append(choose_prefix(i)..v.label.."\\N")
|
||||||
|
end
|
||||||
|
|
||||||
|
local w, h = mp.get_osd_size()
|
||||||
|
if opts.scale_playlist_by_window then w,h = 0, 0 end
|
||||||
|
mp.set_osd_ass(w, h, ass.text)
|
||||||
|
end
|
||||||
|
|
||||||
|
function destroy()
|
||||||
|
timeout:kill()
|
||||||
|
mp.set_osd_ass(0,0,"")
|
||||||
|
mp.remove_key_binding("move_up")
|
||||||
|
mp.remove_key_binding("move_down")
|
||||||
|
mp.remove_key_binding("select")
|
||||||
|
mp.remove_key_binding("escape")
|
||||||
|
destroyer = nil
|
||||||
|
end
|
||||||
|
timeout = mp.add_periodic_timer(opts.menu_timeout, destroy)
|
||||||
|
destroyer = destroy
|
||||||
|
|
||||||
|
mp.add_forced_key_binding(opts.up_binding, "move_up", function() selected_move(-1) end, {repeatable=true})
|
||||||
|
mp.add_forced_key_binding(opts.down_binding, "move_down", function() selected_move(1) end, {repeatable=true})
|
||||||
|
mp.add_forced_key_binding(opts.select_binding, "select", function()
|
||||||
|
destroy()
|
||||||
|
mp.set_property("ytdl-format", options[selected].format)
|
||||||
|
reload_resume()
|
||||||
|
end)
|
||||||
|
mp.add_forced_key_binding(opts.toggle_menu_binding, "escape", destroy)
|
||||||
|
|
||||||
|
draw_menu()
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local ytdl = {
|
||||||
|
path = "yt-dlp",
|
||||||
|
searched = false,
|
||||||
|
blacklisted = {}
|
||||||
|
}
|
||||||
|
|
||||||
|
format_cache={}
|
||||||
|
function download_formats()
|
||||||
|
local function exec(args)
|
||||||
|
local ret = utils.subprocess({args = args})
|
||||||
|
return ret.status, ret.stdout, ret
|
||||||
|
end
|
||||||
|
|
||||||
|
local function table_size(t)
|
||||||
|
s = 0
|
||||||
|
for i,v in ipairs(t) do
|
||||||
|
s = s+1
|
||||||
|
end
|
||||||
|
return s
|
||||||
|
end
|
||||||
|
|
||||||
|
local url = mp.get_property("path")
|
||||||
|
|
||||||
|
url = string.gsub(url, "ytdl://", "") -- Strip possible ytdl:// prefix.
|
||||||
|
|
||||||
|
-- don't fetch the format list if we already have it
|
||||||
|
if format_cache[url] ~= nil then
|
||||||
|
local res = format_cache[url]
|
||||||
|
return res, table_size(res)
|
||||||
|
end
|
||||||
|
mp.osd_message("fetching available formats with youtube-dl...", 60)
|
||||||
|
|
||||||
|
if not (ytdl.searched) then
|
||||||
|
local ytdl_mcd = mp.find_config_file("youtube-dl")
|
||||||
|
if not (ytdl_mcd == nil) then
|
||||||
|
msg.verbose("found youtube-dl at: " .. ytdl_mcd)
|
||||||
|
ytdl.path = ytdl_mcd
|
||||||
|
end
|
||||||
|
ytdl.searched = true
|
||||||
|
end
|
||||||
|
|
||||||
|
local command = {ytdl.path, "--no-warnings", "--no-playlist", "-J"}
|
||||||
|
table.insert(command, url)
|
||||||
|
local es, json, result = exec(command)
|
||||||
|
|
||||||
|
if (es < 0) or (json == nil) or (json == "") then
|
||||||
|
mp.osd_message("fetching formats failed...", 1)
|
||||||
|
msg.error("failed to get format list: " .. err)
|
||||||
|
return {}, 0
|
||||||
|
end
|
||||||
|
|
||||||
|
local json, err = utils.parse_json(json)
|
||||||
|
|
||||||
|
if (json == nil) then
|
||||||
|
mp.osd_message("fetching formats failed...", 1)
|
||||||
|
msg.error("failed to parse JSON data: " .. err)
|
||||||
|
return {}, 0
|
||||||
|
end
|
||||||
|
|
||||||
|
res = {}
|
||||||
|
msg.verbose("youtube-dl succeeded!")
|
||||||
|
for i,v in ipairs(json.formats) do
|
||||||
|
if v.vcodec ~= "none" then
|
||||||
|
local fps = v.fps and v.fps.."fps" or ""
|
||||||
|
local resolution = string.format("%sx%s", v.width, v.height)
|
||||||
|
local l = string.format("%-9s %-5s (%-4s / %s)", resolution, fps, v.ext, v.vcodec)
|
||||||
|
local f = string.format("%s+bestaudio/best", v.format_id)
|
||||||
|
table.insert(res, {label=l, format=f, width=v.width })
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
table.sort(res, function(a, b) return a.width > b.width end)
|
||||||
|
|
||||||
|
mp.osd_message("", 0)
|
||||||
|
format_cache[url] = res
|
||||||
|
return res, table_size(res)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- register script message to show menu
|
||||||
|
mp.register_script_message("toggle-quality-menu",
|
||||||
|
function()
|
||||||
|
if destroyer ~= nil then
|
||||||
|
destroyer()
|
||||||
|
else
|
||||||
|
show_menu()
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
-- keybind to launch menu
|
||||||
|
mp.add_key_binding(opts.toggle_menu_binding, "quality-menu", show_menu)
|
||||||
|
|
||||||
|
-- special thanks to reload.lua (https://github.com/4e6/mpv-reload/)
|
||||||
|
function reload_resume()
|
||||||
|
local playlist_pos = mp.get_property_number("playlist-pos")
|
||||||
|
local reload_duration = mp.get_property_native("duration")
|
||||||
|
local time_pos = mp.get_property("time-pos")
|
||||||
|
|
||||||
|
mp.set_property_number("playlist-pos", playlist_pos)
|
||||||
|
|
||||||
|
-- Tries to determine live stream vs. pre-recordered VOD. VOD has non-zero
|
||||||
|
-- duration property. When reloading VOD, to keep the current time position
|
||||||
|
-- we should provide offset from the start. Stream doesn't have fixed start.
|
||||||
|
-- Decent choice would be to reload stream from it's current 'live' positon.
|
||||||
|
-- That's the reason we don't pass the offset when reloading streams.
|
||||||
|
if reload_duration and reload_duration > 0 then
|
||||||
|
local function seeker()
|
||||||
|
mp.commandv("seek", time_pos, "absolute")
|
||||||
|
mp.unregister_event(seeker)
|
||||||
|
end
|
||||||
|
mp.register_event("file-loaded", seeker)
|
||||||
|
end
|
||||||
|
end
|
|
@ -756,12 +756,14 @@ interface = eth0
|
||||||
|
|
||||||
[module/wireless-network]
|
[module/wireless-network]
|
||||||
type = internal/network
|
type = internal/network
|
||||||
interface = wlan0
|
;interface = wlan0
|
||||||
|
interface = wlp8s0
|
||||||
|
|
||||||
; Normal Module
|
; Normal Module
|
||||||
[module/network]
|
[module/network]
|
||||||
type = internal/network
|
type = internal/network
|
||||||
interface = wlan0
|
;interface = wlan0
|
||||||
|
interface = wlp8s0
|
||||||
|
|
||||||
; Seconds to sleep between updates
|
; Seconds to sleep between updates
|
||||||
; Default: 1
|
; Default: 1
|
||||||
|
|
|
@ -468,7 +468,7 @@ map g/ cd /
|
||||||
map g? cd /usr/share/doc/ranger
|
map g? cd /usr/share/doc/ranger
|
||||||
|
|
||||||
# Custom Commands
|
# Custom Commands
|
||||||
map gd open_with dragon-drag-and-drop -a -x
|
map gd open_with dragon-drop -a -x
|
||||||
# clean latex files
|
# clean latex files
|
||||||
map dlc shell latexmk -c
|
map dlc shell latexmk -c
|
||||||
map dlC shell latexmk -C
|
map dlC shell latexmk -C
|
||||||
|
|
|
@ -294,4 +294,4 @@ mime application/x-executable = "$1"
|
||||||
# Move the file to trash using trash-cli.
|
# Move the file to trash using trash-cli.
|
||||||
label trash, has trash-put = trash-put -- "$@"
|
label trash, has trash-put = trash-put -- "$@"
|
||||||
label trash = mkdir -p -- ${XDG_DATA_DIR:-$HOME/.ranger}/ranger-trash; mv -- "$@" ${XDG_DATA_DIR:-$HOME/.ranger}/ranger-trash
|
label trash = mkdir -p -- ${XDG_DATA_DIR:-$HOME/.ranger}/ranger-trash; mv -- "$@" ${XDG_DATA_DIR:-$HOME/.ranger}/ranger-trash
|
||||||
has dragon-drag-and-drop, X, flag f = dragon-drag-and-drop -a -x "$@"
|
has dragon-drag-drop, X, flag f = dragon-drag-drop -a -x "$@"
|
||||||
|
|
|
@ -3,5 +3,5 @@
|
||||||
#--write-subs
|
#--write-subs
|
||||||
--embed-subs
|
--embed-subs
|
||||||
--write-auto-subs
|
--write-auto-subs
|
||||||
--sub-langs "en.*"
|
#--sub-langs "en.*,ja.*"
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ set selection-clipboard clipboard
|
||||||
map u scroll half-up
|
map u scroll half-up
|
||||||
map d scroll half-down
|
map d scroll half-down
|
||||||
map D toggle_page_mode
|
map D toggle_page_mode
|
||||||
|
# or set first-page-column 1:1 OR 1:2
|
||||||
map r reload
|
map r reload
|
||||||
map R rotate
|
map R rotate
|
||||||
map K zoom in
|
map K zoom in
|
||||||
|
|
12
zsh/.zshrc
12
zsh/.zshrc
|
@ -62,6 +62,10 @@ zplugin ice wait'0' lucid
|
||||||
zinit load agkozak/zsh-z
|
zinit load agkozak/zsh-z
|
||||||
|
|
||||||
|
|
||||||
|
zplugin ice wait'5' lucid
|
||||||
|
zplugin load chisui/zsh-nix-shell
|
||||||
|
|
||||||
|
|
||||||
#zplugin ice wait'1' lucid
|
#zplugin ice wait'1' lucid
|
||||||
#zplugin load marlonrichert/zsh-autocomplete
|
#zplugin load marlonrichert/zsh-autocomplete
|
||||||
|
|
||||||
|
@ -187,6 +191,7 @@ alias sudo='sudo '
|
||||||
|
|
||||||
alias fm='ranger'
|
alias fm='ranger'
|
||||||
alias fm.='. ranger'
|
alias fm.='. ranger'
|
||||||
|
alias books="fm ~/Nextcloud/Books"
|
||||||
|
|
||||||
alias ll='ls -alF'
|
alias ll='ls -alF'
|
||||||
alias la='ls -A'
|
alias la='ls -A'
|
||||||
|
@ -209,6 +214,7 @@ alias ip='ip --color=auto'
|
||||||
alias ytfzfd='YTFZF_PLAYER="youtube-dl --embed-subs --write-sub --sub-lang en" ytfzf'
|
alias ytfzfd='YTFZF_PLAYER="youtube-dl --embed-subs --write-sub --sub-lang en" ytfzf'
|
||||||
|
|
||||||
alias cargo-doc-server="python -m http.server -d target/doc/ -b 127.0.0.1"
|
alias cargo-doc-server="python -m http.server -d target/doc/ -b 127.0.0.1"
|
||||||
|
alias startx="exec startx"
|
||||||
|
|
||||||
#===============================================================================================
|
#===============================================================================================
|
||||||
|
|
||||||
|
@ -275,6 +281,12 @@ export LESS_TERMCAP_so=$(printf '\e[01;33m') # enter standout mode - yellow
|
||||||
export LESS_TERMCAP_ue=$(printf '\e[0m') # leave underline mode
|
export LESS_TERMCAP_ue=$(printf '\e[0m') # leave underline mode
|
||||||
export LESS_TERMCAP_us=$(printf '\e[04;36m') # enter underline mode - cyan
|
export LESS_TERMCAP_us=$(printf '\e[04;36m') # enter underline mode - cyan
|
||||||
|
|
||||||
|
# fcitx (japanese)
|
||||||
|
GTK_IM_MODULE='fcitx'
|
||||||
|
QT_IM_MODULE='fcitx'
|
||||||
|
SDL_IM_MODULE='fcitx'
|
||||||
|
XMODIFIERS='@im=fcitx'
|
||||||
|
|
||||||
#===============================================================================================
|
#===============================================================================================
|
||||||
|
|
||||||
# Load the pure theme, with zsh-async library that's bundled with it
|
# Load the pure theme, with zsh-async library that's bundled with it
|
||||||
|
|
Loading…
Reference in New Issue