Compare commits
10 Commits
6ed3b6b0e0
...
5b86d1cd9b
| Author | SHA1 | Date |
|---|---|---|
|
|
5b86d1cd9b | |
|
|
fbc5116995 | |
|
|
22284efb55 | |
|
|
68c74a3863 | |
|
|
97e17dc9cf | |
|
|
e866187d2c | |
|
|
8a56e69f33 | |
|
|
9941dba87a | |
|
|
a7c057eff4 | |
|
|
bbe7834d4d |
|
|
@ -70,7 +70,7 @@
|
|||
};
|
||||
users.users.${user} = {
|
||||
isNormalUser = true;
|
||||
extraGroups = ["wheel"]; # Enable ‘sudo’ for the user.
|
||||
extraGroups = ["wheel" "video"]; # Enable ‘sudo’ for the user.
|
||||
openssh.authorizedKeys.keys = [
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKAa3tMzSCRuprEACrBsKI0F/o73o6J9L1qR3TaZn/N8 user@Kell"
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIByLwLAdJbmoDV5sx4hg5NbzKbOh1GmWEhDOUJ1GQBhK user@Riva"
|
||||
|
|
|
|||
|
|
@ -26,7 +26,9 @@ in {
|
|||
rclone
|
||||
opencode
|
||||
# zed-editor
|
||||
uv
|
||||
google-cloud-sdk
|
||||
awscli2
|
||||
distrobox
|
||||
gnome-disk-utility
|
||||
moonlight-qt
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ in {
|
|||
Status = "locked";
|
||||
};
|
||||
"privacy.trackingprotection.enabled" = true;
|
||||
"media.webrtc.camera.allow-pipewire" = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@
|
|||
pname = "Helium";
|
||||
version = "0.4.7.1";
|
||||
src = pkgs.fetchurl {
|
||||
url = "https://github.com/imputnet/helium-linux/releases/download/0.8.5.1/helium-0.8.5.1-x86_64.AppImage";
|
||||
sha256 = "sha256-jFSLLDsHB/NiJqFmn8S+JpdM8iCy3Zgyq+8l4RkBecM=";
|
||||
url = "https://github.com/imputnet/helium-linux/releases/download/0.9.4.1/helium-0.9.4.1-x86_64.AppImage";
|
||||
sha256 = "sha256-N5gdWuxOrIudJx/4nYo4/SKSxakpTFvL4zzByv6Cnug=";
|
||||
};
|
||||
})
|
||||
];
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ in {
|
|||
"uwsm app -- hyprpaper"
|
||||
"uwsm app -- foot --server"
|
||||
"uwsm app -- hyprctl dispatch exec ags run"
|
||||
"uwsm app -- ${pkgs.mate.mate-polkit}/bin/polkit-mate"
|
||||
"uwsm app -- ${pkgs.mate-polkit}/bin/polkit-mate"
|
||||
];
|
||||
env = [
|
||||
"WLR_NO_HARDWARE_CURSORS,1"
|
||||
|
|
@ -286,11 +286,12 @@ in {
|
|||
++ (
|
||||
# workspaces
|
||||
builtins.concatLists (builtins.genList (x: let
|
||||
ws = let c = (x + 1) / 10; in builtins.toString (x + 1 - (c * 10));
|
||||
in [
|
||||
"$mainMod, ${ws}, ${workspace_command_prefix}workspace, ${toString (x + 1)}"
|
||||
"$mainMod SHIFT, ${ws}, ${workspace_command_prefix}movetoworkspace, ${toString (x + 1)}"
|
||||
]) 10)
|
||||
ws = let c = (x + 1) / 10; in builtins.toString (x + 1 - (c * 10));
|
||||
in [
|
||||
"$mainMod, ${ws}, ${workspace_command_prefix}workspace, ${toString (x + 1)}"
|
||||
"$mainMod SHIFT, ${ws}, ${workspace_command_prefix}movetoworkspace, ${toString (x + 1)}"
|
||||
])
|
||||
10)
|
||||
);
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -0,0 +1,180 @@
|
|||
-- frame-seek.lua
|
||||
-- Allows seeking to a specific frame number or timestamp
|
||||
|
||||
local input = require("mp.input")
|
||||
|
||||
local jump_mode = nil -- "frame" or "time"
|
||||
local relative = false
|
||||
local minus = false
|
||||
local fps = 0
|
||||
|
||||
function parse_timestamp(input_str)
|
||||
-- Formats:
|
||||
-- HH:MM:SS.ms
|
||||
-- MM:SS.ms
|
||||
-- SS.ms
|
||||
-- .ms
|
||||
|
||||
-- More than 60 minutes or seconds can be entered - it will seek any amount accurately
|
||||
|
||||
-- First try to match HH:MM:SS.ms
|
||||
local hours, minutes, seconds = input_str:match("^(%d+):(%d+):(%d+%.?%d*)$")
|
||||
if hours and minutes and seconds then
|
||||
return tonumber(hours) * 3600 + tonumber(minutes) * 60 + tonumber(seconds)
|
||||
end
|
||||
|
||||
-- Try to match MM:SS.ms
|
||||
local minutes, seconds = input_str:match("^(%d+):(%d+%.?%d*)$")
|
||||
if minutes and seconds then
|
||||
return tonumber(minutes) * 60 + tonumber(seconds)
|
||||
end
|
||||
|
||||
-- Try to match just seconds (with or without decimal)
|
||||
local seconds = input_str:match("^(%d+%.?%d*)$")
|
||||
if seconds then
|
||||
return tonumber(seconds)
|
||||
end
|
||||
|
||||
local milliseconds = input_str:match("^%.(%d+)$")
|
||||
if milliseconds ~= nil then
|
||||
return tonumber("0." .. milliseconds)
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
function seek_to_frame(frame_num)
|
||||
fps = mp.get_property_number("estimated-vf-fps")
|
||||
if not fps or fps <= 0 then
|
||||
mp.osd_message("Error: Cannot determine framerate")
|
||||
return
|
||||
end
|
||||
|
||||
local timestamp = frame_num / fps
|
||||
|
||||
seek_to_timestamp(timestamp)
|
||||
end
|
||||
|
||||
function seek_to_timestamp(timestamp)
|
||||
if minus then timestamp = -timestamp end
|
||||
|
||||
local cur_time = mp.get_property_number("time-pos")
|
||||
if not cur_time then return end
|
||||
|
||||
if relative then
|
||||
if timestamp == 0 then return end
|
||||
|
||||
if math.abs(timestamp) < 10 then
|
||||
mp.commandv("seek", timestamp, "exact")
|
||||
else
|
||||
-- Only show OSD if seek >10s
|
||||
mp.command("seek " .. timestamp .. " exact")
|
||||
end
|
||||
else
|
||||
-- Handle imprecise float
|
||||
if math.abs(timestamp - cur_time) < 1e-7 then return end
|
||||
mp.command("seek " .. timestamp .. " absolute+exact")
|
||||
end
|
||||
|
||||
mp.observe_property("time-pos", "number", display_osd_message)
|
||||
end
|
||||
|
||||
function display_osd_message(_, timestamp)
|
||||
if timestamp == nil then return end
|
||||
mp.unobserve_property(display_osd_message)
|
||||
|
||||
-- Format the display nicely
|
||||
local hours = math.floor(timestamp / 3600)
|
||||
local minutes = math.floor((timestamp % 3600) / 60)
|
||||
local seconds = math.floor(timestamp % 60)
|
||||
local milliseconds = math.floor((timestamp % 1) * 1000 + 0.5)
|
||||
|
||||
local display_time = string.format("%02d:%02d", minutes, seconds)
|
||||
|
||||
if hours ~= 0 then
|
||||
display_time = string.format("%d:", hours) .. display_time
|
||||
end
|
||||
|
||||
if milliseconds ~= 0 or jump_mode == "frame" then
|
||||
display_time = display_time .. string.format(".%03d", milliseconds)
|
||||
end
|
||||
|
||||
if jump_mode == "frame" and fps and fps > 0 then
|
||||
local frame_num = math.floor(timestamp * fps + 0.5)
|
||||
mp.osd_message(string.format("Seeking to frame %d (%s)", frame_num, display_time))
|
||||
else
|
||||
mp.osd_message(string.format("Seeking to %s", display_time))
|
||||
end
|
||||
end
|
||||
|
||||
function jump_submit(input)
|
||||
if not input or input == "" then
|
||||
reset()
|
||||
return
|
||||
end
|
||||
|
||||
-- Handle relative marker
|
||||
if input:sub(1, 1) == "r" then
|
||||
relative = true
|
||||
input = input:sub(2)
|
||||
end
|
||||
|
||||
-- Handle negative input
|
||||
minus = false
|
||||
if input:sub(1, 1) == "-" then
|
||||
minus = true
|
||||
input = input:sub(2)
|
||||
end
|
||||
|
||||
if jump_mode == "frame" then
|
||||
local frame_num = tonumber(input)
|
||||
if frame_num then
|
||||
seek_to_frame(math.floor(frame_num))
|
||||
else
|
||||
mp.osd_message("Invalid frame number")
|
||||
end
|
||||
elseif jump_mode == "time" then
|
||||
local timestamp = parse_timestamp(input)
|
||||
if timestamp then
|
||||
seek_to_timestamp(timestamp)
|
||||
else
|
||||
mp.osd_message("Invalid timestamp format")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function reset()
|
||||
jump_mode = nil
|
||||
relative = false
|
||||
minus = false
|
||||
end
|
||||
|
||||
function run_script(mode, prompt, relative_flag)
|
||||
if mp.get_property("path") == nil then return end
|
||||
|
||||
reset()
|
||||
jump_mode = mode
|
||||
relative = relative_flag
|
||||
|
||||
input.get({
|
||||
prompt = prompt,
|
||||
submit = jump_submit,
|
||||
})
|
||||
end
|
||||
|
||||
-- Register key bindings
|
||||
mp.add_key_binding("ctrl+t", "seek-timestamp", function()
|
||||
run_script("time", "Seek to time:", false)
|
||||
end)
|
||||
|
||||
mp.add_key_binding("ctrl+T", "seek-frame", function()
|
||||
run_script("frame", "Seek to frame:", false)
|
||||
end)
|
||||
|
||||
mp.add_key_binding(nil, "seek-timestamp-relative", function()
|
||||
run_script("time", "Seek forward by time:", true)
|
||||
end)
|
||||
|
||||
mp.add_key_binding(nil, "seek-frame-relative", function()
|
||||
run_script("frame", "Seek forward by frame:", true)
|
||||
end)
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
vim.keymap.set("i", "jj", "<Esc>", {})
|
||||
vim.keymap.set({ "n", "v" }, "k", "v:count == 0 ? 'gk' : 'k'", { expr = true })
|
||||
vim.keymap.set({ "n", "v" }, "j", "v:count == 0 ? 'gj' : 'j'", { expr = true })
|
||||
vim.keymap.set({ "n", "v" }, "k", "v:count == 0 ? 'gk' : 'k'", { expr = true, silent = true })
|
||||
vim.keymap.set({ "n", "v" }, "j", "v:count == 0 ? 'gj' : 'j'", { expr = true, silent = true })
|
||||
vim.keymap.set("n", "<S-k>", "<Nop>", {})
|
||||
vim.keymap.set("t", "jj", "<C-\\><C-n>", { noremap = true, silent = true })
|
||||
vim.keymap.set("n", "<Backspace>", ":q<cr>", { noremap = true, silent = true })
|
||||
|
|
@ -15,15 +15,16 @@ vim.keymap.set("n", "<C-I>", "<C-I>", { noremap = true, silent = true })
|
|||
vim.keymap.set("n", "n", "nzz", { noremap = true })
|
||||
vim.keymap.set("n", "N", "Nzz", { noremap = true })
|
||||
vim.keymap.set("x", "<leader>p", [["_dP]], { noremap = true })
|
||||
vim.keymap.set({"n", "v"}, "<leader>y", [["+y]])
|
||||
vim.keymap.set({"n", "v"}, "<leader>Y", [["+Y]])
|
||||
vim.keymap.set({ "n", "v" }, "<leader>y", [["+y]])
|
||||
vim.keymap.set({ "n", "v" }, "<leader>Y", [["+Y]])
|
||||
vim.keymap.set("n", "<Tab>", "<Nop>", { noremap = true })
|
||||
vim.keymap.set("n", "<leader><space>", ":noh<cr>", { noremap = true, silent = true })
|
||||
vim.keymap.set("n", "gn", ":n<cr>", { noremap = true, silent = true })
|
||||
-- vim.keymap.set("n", "gi", ":ClangdSwitchSourceHeader<cr>", { noremap = true, silent = true })
|
||||
vim.keymap.set("n", "-", function () require("oil").open() end, { desc = "Open parent directory" })
|
||||
vim.keymap.set("n", "<leader>-", function () require("oil").open() end, { desc = "Open parent directory" })
|
||||
vim.keymap.set("n", "<leader>g", function () require("neogit").open({kind="replace"}) end, { noremap = true, silent = true })
|
||||
vim.keymap.set("n", "-", function() require("oil").open() end, { desc = "Open parent directory" })
|
||||
vim.keymap.set("n", "<leader>-", function() require("oil").open() end, { desc = "Open parent directory" })
|
||||
vim.keymap.set("n", "<leader>g", function() require("neogit").open({ kind = "replace" }) end,
|
||||
{ noremap = true, silent = true })
|
||||
vim.keymap.set("x", "<leader>a", "<C-A>", { noremap = true, silent = true })
|
||||
vim.keymap.set("x", "<leader>x", "<C-X>", { noremap = true, silent = true })
|
||||
vim.keymap.set("x", "<leader>ga", "g<C-A>", { noremap = true, silent = true })
|
||||
|
|
|
|||
|
|
@ -22,7 +22,15 @@
|
|||
|
||||
home.packages = with pkgs; [
|
||||
spotify
|
||||
slack
|
||||
(pkgs.symlinkJoin {
|
||||
name = "slack-pipewire";
|
||||
paths = [pkgs.slack];
|
||||
buildInputs = [pkgs.makeWrapper];
|
||||
postBuild = ''
|
||||
wrapProgram $out/bin/slack \
|
||||
--add-flags "--enable-features=WebRTCPipeWireCamera"
|
||||
'';
|
||||
})
|
||||
eid-mw
|
||||
onlyoffice-desktopeditors
|
||||
libreoffice
|
||||
|
|
|
|||
|
|
@ -175,9 +175,15 @@ in {
|
|||
};
|
||||
services.usbmuxd.enable = true;
|
||||
environment.systemPackages = with pkgs; [
|
||||
libcamera
|
||||
ifuse
|
||||
libimobiledevice
|
||||
scrcpy
|
||||
v4l-utils
|
||||
];
|
||||
boot.kernel.sysctl = {
|
||||
"net.ipv6.conf.all.disable_ipv6" = 1;
|
||||
"net.ipv6.conf.default.disable_ipv6" = 1;
|
||||
"net.ipv6.conf.lo.disable_ipv6" = 1;
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,13 +14,14 @@
|
|||
|
||||
boot.initrd.availableKernelModules = ["xhci_pci" "thunderbolt" "nvme" "usb_storage" "sd_mod"];
|
||||
boot.initrd.kernelModules = [];
|
||||
boot.kernelModules = ["kvm-intel" "v4l2loopback"];
|
||||
boot.extraModulePackages = with config.boot.kernelPackages; [v4l2loopback tp_smapi];
|
||||
boot.kernelModules = ["kvm-intel" "v4l2loopback" "intel_vsc" "intel_vsc_csi" "intel_vsc_vbus"];
|
||||
boot.extraModulePackages = with config.boot.kernelPackages; [v4l2loopback tp_smapi ipu6-drivers];
|
||||
boot.extraModprobeConfig = ''
|
||||
options thinkpad_acpi fan_control=1
|
||||
options v4l2loopback exclusive_caps=1 card_label="Android Virtual Camera"
|
||||
options v4l2loopback exclusive_caps=1 video_nr=42 card_label="IPU6 Virtual Camera"
|
||||
'';
|
||||
boot.kernelParams = ["ipv6.disable=1"];
|
||||
# boot.kernelParams = ["ipv6.disable=1"];
|
||||
|
||||
fileSystems."/" = {
|
||||
device = "rpool/root";
|
||||
|
|
@ -52,24 +53,48 @@
|
|||
hardware.trackpoint.enable = lib.mkDefault true;
|
||||
hardware.trackpoint.emulateWheel = lib.mkDefault config.hardware.trackpoint.enable;
|
||||
hardware.trackpoint.device = "TPPS/2 Synaptics TrackPoint";
|
||||
hardware.ipu6.enable = true;
|
||||
hardware.ipu6.platform = "ipu6ep";
|
||||
nixpkgs.config.packageOverrides = pkgs: {
|
||||
zfs = pkgs.zfs_unstable;
|
||||
};
|
||||
# boot.kernelPackages = pkgs.linuxPackages_latest;
|
||||
# boot.kernelPackages = pkgs.linuxPackages_latest.extend ( self: super: {
|
||||
# ipu6-drivers = super.ipu6-drivers.overrideAttrs (
|
||||
# final: previous: rec {
|
||||
# src = builtins.fetchGit {
|
||||
# url = "https://github.com/intel/ipu6-drivers.git";
|
||||
# ref = "master";
|
||||
# rev = "4bb5b4d8128fbf7f4730cd364a8f7fc13a0ef65b";
|
||||
# };
|
||||
# patches = [
|
||||
# "${src}/patches/0001-v6.10-IPU6-headers-used-by-PSYS.patch"
|
||||
# ] ;
|
||||
# }
|
||||
# );
|
||||
# } );
|
||||
boot.kernelPackages = pkgs.linuxPackages_latest;
|
||||
hardware.firmware = with pkgs; [
|
||||
ipu6-camera-bins
|
||||
ivsc-firmware
|
||||
];
|
||||
services.udev.extraRules = ''
|
||||
SUBSYSTEM=="intel-ipu6-psys", MODE="0660", GROUP="video"
|
||||
'';
|
||||
systemd.services.ipu6-v4l2-proxy = {
|
||||
description = "IPU6 Libcamera to V4L2Loopback Proxy";
|
||||
# wantedBy = ["multi-user.target"];
|
||||
after = ["systemd-udev-settle.service"];
|
||||
|
||||
serviceConfig = {
|
||||
ExecStart = let
|
||||
gstPluginPath = pkgs.lib.makeSearchPathOutput "lib" "lib/gstreamer-1.0" (with pkgs.gst_all_1;
|
||||
[
|
||||
gstreamer
|
||||
gst-plugins-base
|
||||
gst-plugins-good
|
||||
gst-plugins-bad
|
||||
]
|
||||
++ [pkgs.libcamera]);
|
||||
in ''
|
||||
${pkgs.gst_all_1.gstreamer}/bin/gst-launch-1.0 \
|
||||
--gst-plugin-path=${gstPluginPath} \
|
||||
libcamerasrc \
|
||||
! video/x-raw \
|
||||
! vapostproc contrast=1.3 saturation=1.4 brightness=-0.15 \
|
||||
! video/x-raw,width=1280,height=720 \
|
||||
! videoconvert \
|
||||
! gamma gamma=0.7 \
|
||||
! videoconvert \
|
||||
! video/x-raw,format=YUY2 \
|
||||
! v4l2sink device=/dev/video42
|
||||
'';
|
||||
|
||||
Restart = "always";
|
||||
RestartSec = "3";
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,12 +48,20 @@
|
|||
services.gnome.sushi.enable = true;
|
||||
|
||||
services.pipewire = {
|
||||
wireplumber.enable = true;
|
||||
enable = true;
|
||||
alsa.enable = true;
|
||||
alsa.support32Bit = true;
|
||||
pulse.enable = true;
|
||||
jack.enable = true;
|
||||
};
|
||||
services.pipewire.wireplumber.extraConfig = {
|
||||
"99-libcamera" = {
|
||||
"wireplumber.settings" = {
|
||||
"camera.use-libcamera" = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
hardware.bluetooth = {
|
||||
enable = true;
|
||||
|
|
|
|||
Loading…
Reference in New Issue