12 Commits

Author SHA1 Message Date
kenji 73aab2452e style(firefox): finalize autohide toolbox for web-app profile
Successfully autohides both Tabs and Nav-bar using MrOtherGuy's strategy with a fixed trigger zone.
2026-01-05 15:03:00 -06:00
kenji 109fdb4672 style(firefox): improve autohide CSS for web-app profile
Ensures both tabs and address bar hide and reveal together seamlessly.
2026-01-05 14:48:18 -06:00
kenji 6281f9ea6f feat(firefox): implement dynamic tridactyl newtab via env var
Allows per-profile newtab overrides using TRIDACTYL_NEWTAB environment variable.
2026-01-05 14:42:18 -06:00
kenji edfb269308 feat(firefox): add new-tab-override to web-app profile
Ensures that new tabs and closed-tab fallbacks always redirect to the specified app URL.
2026-01-05 14:37:27 -06:00
kenji eed84ec64c fix(firefox): resolve syntax error in web-app profile 2026-01-05 14:32:24 -06:00
kenji ae7d017d2b feat(firefox): generalize youtube profile into modular web-app profile
- Renamed profiles/youtube.nix to profiles/web-app.nix.

- Refactored to accept id, name, and url as arguments.

- Added settings to force homepage on startup and new tabs.

- Disabled session restore and undo-close-tab for web-app profiles.
2026-01-05 14:31:20 -06:00
kenji e17b21ab69 feat(jellyfin): wrap mpv-shim in uwsm for better session management 2026-01-05 14:14:00 -06:00
kenji 59d29c6cea refactor(jellyfin): decentralize mpv-shim autostart
Move Hyprland autostart logic into the app's own module for better modularity.
2026-01-05 14:12:11 -06:00
kenji 29792a1307 feat(jellyfin): add jellyfin-mpv-shim for high-quality casting 2026-01-05 14:08:57 -06:00
kenji b86df062df feat(mpv): add uosc and thumbfast scripts for a minimalist UI 2026-01-05 14:01:54 -06:00
kenji b02be43aa0 feat(mpv): add hyprland window rules to match imv behavior 2026-01-05 13:58:00 -06:00
kenji 6d19db6577 feat: replace loupe with imv and update plymouth theme
- Replaced Loupe with imv for a keyboard-driven image viewer experience.

- Updated Plymouth logo with Firewatch-inspired ASCII art gradient.

- Updated Plymouth background color to match Firewatch palette (#2D112A).
2026-01-05 13:55:04 -06:00
11 changed files with 274 additions and 74 deletions
+10 -2
View File
@@ -16,7 +16,7 @@
];
workspace = [
"special:youtube, on-created-empty:uwsm app -- firefox -P YouTube --name youtube"
"special:youtube, on-created-empty:uwsm app -- env TRIDACTYL_NEWTAB=https://youtube.com firefox -P YouTube --name youtube"
];
windowrulev2 = [
@@ -38,6 +38,9 @@
bind J tabnext
bind K tabprev
unbind <C-e>
" Set newtab from environment variable if available (provided by native messenger)
js tri.native.run("printenv TRIDACTYL_NEWTAB").then(r => { if (r.stdout.trim()) tri.config.set("newtab", r.stdout.trim()) })
'';
programs.firefox = {
@@ -49,7 +52,12 @@
];
profiles = {
youtube = import ./profiles/youtube.nix {inherit pkgs myConfig;};
youtube = import ./profiles/web-app.nix {
inherit pkgs myConfig;
id = 1;
name = "YouTube";
url = "https://youtube.com";
};
hakase = {
search.force = true;
isDefault = true;
+173
View File
@@ -0,0 +1,173 @@
{
pkgs,
myConfig,
id,
name,
url,
...
}: {
inherit id name;
search.force = true;
search.default = "ddg";
extensions.force = true;
extensions.packages = with pkgs.nur.repos.rycee.firefox-addons; [
ublock-origin
bitwarden
tridactyl
new-tab-override
];
settings = {
# --- New Tab Override ---
"extensions.newtaboverride@agenedia.com.url" = url;
"extensions.newtaboverride@agenedia.com.type" = 1; # URL mode
# --- Privacy & Hardening ---
"browser.contentblocking.category" = "strict";
"privacy.trackingprotection.enabled" = true;
"privacy.resistFingerprinting" = true; # Note: Spoofs timezone and caps FPS to 60
"geo.enabled" = false;
"media.peerconnection.enabled" = false; # Prevents WebRTC IP leaks
"network.dns.disablePrefetch" = true;
"network.prefetch-next" = false;
# --- NixOS / Hyprland Integration ---
"widget.use-xdg-desktop-portal.file-picker" = 1; # Use native file picker
# --- UI & Behavior ---
"browser.compactmode.show" = true;
"browser.tabs.closeWindowWithLastTab" = false;
"extensions.pocket.enabled" = false;
"extensions.screenshots.disabled" = true;
"browser.topsites.contile.enabled" = false;
"browser.formfill.enable" = false;
"browser.search.suggest.enabled" = false;
"browser.search.suggest.enabled.private" = false;
"browser.urlbar.suggest.searches" = false;
"browser.urlbar.showSearchSuggestionsFirst" = false;
"browser.newtabpage.activity-stream.feeds.section.topstories" = false;
"browser.newtabpage.activity-stream.feeds.snippets" = false;
"browser.newtabpage.activity-stream.section.highlights.includePocket" = false;
"browser.newtabpage.activity-stream.section.highlights.includeBookmarks" = false;
"browser.newtabpage.activity-stream.section.highlights.includeDownloads" = false;
"browser.newtabpage.activity-stream.section.highlights.includeVisited" = false;
"browser.newtabpage.activity-stream.showSponsored" = false;
"browser.newtabpage.activity-stream.system.showSponsored" = false;
"browser.newtabpage.activity-stream.showSponsoredTopSites" = false;
"toolkit.legacyUserProfileCustomizations.stylesheets" = true;
"extensions.autoDisableScopes" = 0; # Enable extensions by default
# --- Homepage & Navigation ---
"browser.startup.page" = 1; # Always open the homepage
"browser.startup.homepage" = url;
"browser.newtab.url" = url; # Try to set newtab to homepage
"browser.sessionstore.resume_from_crash" = false; # Always start fresh
"browser.sessionstore.max_tabs_undo" = 0; # Disable undo close tab
# --- DNS over HTTPS (Quad9) ---
"network.trr.mode" = 2; # Use DoH with system fallback
"network.trr.uri" = "https://dns.quad9.net/dns-query";
};
userChrome = ''
/* --- Autohide Entire Toolbox (Tabs + Address Bar) --- */
/* Adapted from MrOtherGuy's autohide_main_toolbar.css */
:root{
/* Height of Tabs + Nav Bar approx 80px */
--uc-navbar-transform: -85px;
--uc-autohide-toolbar-delay: 0.1s;
--uc-autohide-toolbar-duration: 200ms;
}
:root[uidensity="compact"]{ --uc-navbar-transform: -70px }
#navigator-toolbox > div{ display: contents; }
/* Apply transform to TabsToolbar AND Nav-bar */
:root[sessionrestored] :where(#nav-bar,#PersonalToolbar,#TabsToolbar,#tab-notification-deck,.global-notificationbox,#notifications-toolbar){
transform: translateY(var(--uc-navbar-transform))
}
:root:is([customizing],[chromehidden*="toolbar"]) :where(#nav-bar,#PersonalToolbar,#TabsToolbar,#tab-notification-deck,.global-notificationbox,#notifications-toolbar){
transform: none !important;
opacity: 1 !important;
}
/* Hide styles for Nav-Bar AND TabsToolbar */
:where(#nav-bar,#TabsToolbar):not([customizing]){
opacity: 0;
transition: transform var(--uc-autohide-toolbar-duration) ease var(--uc-autohide-toolbar-delay), opacity var(--uc-autohide-toolbar-duration) ease var(--uc-autohide-toolbar-delay) !important;
position: relative;
z-index: 2;
}
#navigator-toolbox,
#sidebar-box,
#sidebar-main,
#sidebar-splitter,
#tabbrowser-tabbox{
z-index: auto !important;
}
/* Show when toolbox is focused or hovered */
#navigator-toolbox:focus-within > .browser-toolbar,
.browser-titlebar:hover ~ :is(#nav-bar,#PersonalToolbar,#TabsToolbar),
#nav-bar:hover,
#TabsToolbar:hover,
#nav-bar:hover + #PersonalToolbar{
transform: translateY(0);
opacity: 1;
transition-duration: var(--uc-autohide-toolbar-duration), var(--uc-autohide-toolbar-duration) !important;
transition-delay: 0s !important;
}
/* Ensure popups still work (URL bar) */
:root[sessionrestored] #urlbar[popover]{
opacity: 0;
pointer-events: none;
transition: transform var(--uc-autohide-toolbar-duration) ease var(--uc-autohide-toolbar-delay), opacity var(--uc-autohide-toolbar-duration) ease var(--uc-autohide-toolbar-delay);
transform: translateY(var(--uc-navbar-transform));
}
#mainPopupSet:has(> [panelopen]:not(#ask-chat-shortcuts,#selection-shortcut-action-panel,#chat-shortcuts-options-panel,#tab-preview-panel)) ~ toolbox #urlbar[popover],
.browser-titlebar:is(:hover,:focus-within) ~ #nav-bar #urlbar[popover],
#nav-bar:is(:hover,:focus-within) #urlbar[popover],
#urlbar-container > #urlbar[popover]:is([focused],[open]){
opacity: 1;
pointer-events: auto;
transition-delay: 0ms;
transform: translateY(0);
}
:where(:root[sessionrestored]) #urlbar-container > #urlbar[popover]:is([focused],[open]){
transition-duration: 100ms;
}
/* --- CRITICAL FIX: Trigger Zone --- */
/* Since we hide EVERYTHING, we need a hitbox at the top of the screen */
#navigator-toolbox::after {
content: "";
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 20px; /* Generous hit target */
z-index: 10000;
pointer-events: auto;
}
/* When hitbox is hovered, reveal bars */
#navigator-toolbox:hover :where(#nav-bar,#PersonalToolbar,#TabsToolbar) {
transform: translateY(0) !important;
opacity: 1 !important;
transition-delay: 0s !important;
}
/* Move up the content view to fill the gap */
:root[sessionrestored]:not([chromehidden~="toolbar"]) > body > #browser{
margin-top: var(--uc-navbar-transform);
}
/* Fix Titlebar and Bookmarks */
#titlebar { appearance: none !important; }
#PersonalToolbar { visibility: collapse !important; }
'';
}
+27 -44
View File
@@ -60,61 +60,44 @@
};
userChrome = ''
/* --- Floating Autohide Toolbox (Tabs Only) --- */
/* Take toolbox out of the document flow so web content is 100% height */
#navigator-toolbox {
position: fixed !important;
top: 0;
left: 0;
width: 100%;
z-index: 9999 !important;
background-color: var(--toolbar-bgcolor, #1c1b22) !important;
/* Start hidden */
transform: translateY(-100%) !important;
/* Hide the Navigation Bar by default */
#nav-bar {
height: 0px !important;
min-height: 0px !important;
overflow: hidden !important;
opacity: 0 !important;
transition: transform 0.2s ease, opacity 0.2s ease !important;
transition: height 0.3s ease, opacity 0.3s ease !important;
z-index: 100 !important;
}
/* Trigger zone */
#navigator-toolbox::after {
content: "";
position: absolute;
top: 100%;
left: 0;
width: 100%;
height: 10px;
z-index: 10000 !important;
}
/* Reveal when hovering */
#navigator-toolbox:hover {
transform: translateY(0) !important;
/* Show the Navigation Bar on hover over the navigator toolbox */
#navigator-toolbox:hover #nav-bar,
#nav-bar:focus-within {
height: 40px !important; /* Adjust based on your density settings */
min-height: 40px !important;
opacity: 1 !important;
}
/* --- Hide specific bars --- */
/* Hide Navigation Bar (Address Bar) COMPLETELY */
#nav-bar {
visibility: collapse !important;
/* Auto-hide Tabs Toolbar */
#TabsToolbar {
height: 0px !important;
min-height: 0px !important;
padding: 0 !important;
margin: 0 !important;
overflow: hidden !important;
opacity: 0 !important;
transition: height 0.3s ease, opacity 0.3s ease !important;
z-index: 100 !important;
}
/* Show Tabs Toolbar on hover over the navigator toolbox */
#navigator-toolbox:hover #TabsToolbar {
height: 30px !important; /* Adjust based on your tab height preference */
min-height: 30px !important;
opacity: 1 !important;
}
/* Hide Bookmarks Toolbar */
#PersonalToolbar { visibility: collapse !important; }
/* Hide Titlebar */
#titlebar { appearance: none !important; }
/* Ensure TabsToolbar looks okay on its own */
#TabsToolbar {
border: none !important;
background: transparent !important;
#PersonalToolbar {
visibility: collapse !important;
}
'';
}
+23
View File
@@ -0,0 +1,23 @@
{pkgs, ...}: {
home.packages = with pkgs; [imv];
xdg.mimeApps = {
enable = true;
defaultApplications = {
"image/png" = "imv.desktop";
"image/jpeg" = "imv.desktop";
"image/gif" = "imv.desktop";
"image/webp" = "imv.desktop";
"image/bmp" = "imv.desktop";
"image/svg+xml" = "imv.desktop";
"image/tiff" = "imv.desktop";
};
};
wayland.windowManager.hyprland.settings.windowrulev2 = [
# --- IMAGE VIEWER (IMV) ---
"float, class:^(imv)$"
"center, class:^(imv)$"
"size 70% 70%, class:^(imv)$"
];
}
+16
View File
@@ -0,0 +1,16 @@
{pkgs, ...}: {
home.packages = with pkgs; [
jellyfin-mpv-shim
];
wayland.windowManager.hyprland.settings.windowrulev2 = [
# --- JELLYFIN MPV SHIM ---
"float, class:^(jellyfin-mpv-shim)$"
"center, class:^(jellyfin-mpv-shim)$"
"size 70% 70%, class:^(jellyfin-mpv-shim)$"
];
wayland.windowManager.hyprland.settings.exec-once = [
"uwsm app -- jellyfin-mpv-shim"
];
}
-23
View File
@@ -1,23 +0,0 @@
{pkgs, ...}: {
home.packages = with pkgs; [loupe];
xdg.mimeApps = {
enable = true;
defaultApplications = {
"image/png" = "org.gnome.Loupe.desktop";
"image/jpeg" = "org.gnome.Loupe.desktop";
"image/gif" = "org.gnome.Loupe.desktop";
"image/webp" = "org.gnome.Loupe.desktop";
"image/bmp" = "org.gnome.Loupe.desktop";
"image/svg+xml" = "org.gnome.Loupe.desktop";
"image/tiff" = "org.gnome.Loupe.desktop";
};
};
wayland.windowManager.hyprland.settings.windowrulev2 = [
# --- IMAGE VIEWER (Loupe) ---
"float, class:^(org\.gnome\.Loupe)$"
"center, class:^(org\.gnome\.Loupe)$"
"size 70% 70%, class:^(org\.gnome\.Loupe)$"
];
}
+21 -2
View File
@@ -1,5 +1,17 @@
{pkgs, ...}: {
home.packages = with pkgs; [mpv];
programs.mpv = {
enable = true;
scripts = with pkgs.mpvScripts; [
uosc
thumbfast
];
config = {
# uosc provides its own UI
osc = "no";
osd-bar = "no";
border = "no";
};
};
xdg.mimeApps = {
enable = true;
@@ -12,4 +24,11 @@
"video/quicktime" = "mpv.desktop";
};
};
}
wayland.windowManager.hyprland.settings.windowrulev2 = [
# --- VIDEO PLAYER (mpv) ---
"float, class:^(mpv)$"
"center, class:^(mpv)$"
"size 70% 70%, class:^(mpv)$"
];
}
+2 -2
View File
@@ -1,7 +1,7 @@
# Omarchy Plymouth Theme Script
Window.SetBackgroundTopColor(0.101, 0.105, 0.149);
Window.SetBackgroundBottomColor(0.101, 0.105, 0.149);
Window.SetBackgroundTopColor(0.176, 0.067, 0.165);
Window.SetBackgroundBottomColor(0.176, 0.067, 0.165);
logo.image = Image("logo.png");
logo.sprite = Sprite(logo.image);
Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 54 KiB

+1
View File
@@ -5,5 +5,6 @@
../../apps/tickrs
../../apps/claude
../../apps/delfin
../../apps/jellyfin-mpv-shim
];
}
+1 -1
View File
@@ -3,7 +3,7 @@
../../apps/yazi
../../apps/gemini
../../apps/firefox
../../apps/loupe
../../apps/imv
../../apps/mpv
../../apps/mako
# ../../apps/starship