Compare commits
2
Commits
5e6dc9e533
...
1a91d00f2c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1a91d00f2c | ||
|
|
19063a3e02 |
@@ -13,3 +13,6 @@
|
|||||||
# Python helper bytecode is local runtime state.
|
# Python helper bytecode is local runtime state.
|
||||||
__pycache__/
|
__pycache__/
|
||||||
*.py[cod]
|
*.py[cod]
|
||||||
|
|
||||||
|
# Generated from the colour scheme; machine state, not configuration.
|
||||||
|
/config/dot/kitty/current-theme.conf
|
||||||
|
|||||||
@@ -183,7 +183,6 @@ font_size 14.0
|
|||||||
|
|
||||||
#: Cursor customization {{{
|
#: Cursor customization {{{
|
||||||
|
|
||||||
cursor #c8d3f5
|
|
||||||
|
|
||||||
#: Default cursor color. If set to the special value none the cursor
|
#: Default cursor color. If set to the special value none the cursor
|
||||||
#: will be rendered with a "reverse video" effect. It's color will be
|
#: will be rendered with a "reverse video" effect. It's color will be
|
||||||
@@ -193,7 +192,6 @@ cursor #c8d3f5
|
|||||||
#: precedence. Also, the cursor colors are modified if the cell
|
#: precedence. Also, the cursor colors are modified if the cell
|
||||||
#: background and foreground colors have very low contrast.
|
#: background and foreground colors have very low contrast.
|
||||||
|
|
||||||
cursor_text_color #111325
|
|
||||||
|
|
||||||
#: The color of text under the cursor. If you want it rendered with
|
#: The color of text under the cursor. If you want it rendered with
|
||||||
#: the background color of the cell underneath instead, use the
|
#: the background color of the cell underneath instead, use the
|
||||||
@@ -312,7 +310,6 @@ cursor_shape block
|
|||||||
#: robustly with the ever-changing sea of bugs that is Cocoa is too
|
#: robustly with the ever-changing sea of bugs that is Cocoa is too
|
||||||
#: much effort.
|
#: much effort.
|
||||||
|
|
||||||
url_color #4fd6be
|
|
||||||
# url_style curly
|
# url_style curly
|
||||||
|
|
||||||
#: The color and style for highlighting URLs on mouse-over. url_style
|
#: The color and style for highlighting URLs on mouse-over. url_style
|
||||||
@@ -734,12 +731,10 @@ window_border_width 1pt
|
|||||||
#: placed centrally. A value of top-left means the padding will be
|
#: placed centrally. A value of top-left means the padding will be
|
||||||
#: only at the bottom and right edges.
|
#: only at the bottom and right edges.
|
||||||
|
|
||||||
active_border_color #82aaff
|
|
||||||
|
|
||||||
#: The color for the border of the active window. Set this to none to
|
#: The color for the border of the active window. Set this to none to
|
||||||
#: not draw borders around the active window.
|
#: not draw borders around the active window.
|
||||||
|
|
||||||
inactive_border_color #2f334d
|
|
||||||
|
|
||||||
#: The color for the border of inactive windows.
|
#: The color for the border of inactive windows.
|
||||||
|
|
||||||
@@ -960,16 +955,11 @@ tab_powerline_style round
|
|||||||
#: Template to use for active tabs. If not specified falls back to
|
#: Template to use for active tabs. If not specified falls back to
|
||||||
#: tab_title_template.
|
#: tab_title_template.
|
||||||
|
|
||||||
active_tab_foreground #1e2030
|
|
||||||
active_tab_background #82aaff
|
|
||||||
# active_tab_font_style bold-italic
|
# active_tab_font_style bold-italic
|
||||||
inactive_tab_foreground #c8d3f5
|
|
||||||
inactive_tab_background #42465a
|
|
||||||
# inactive_tab_font_style normal
|
# inactive_tab_font_style normal
|
||||||
|
|
||||||
#: Tab bar colors and styles.
|
#: Tab bar colors and styles.
|
||||||
|
|
||||||
tab_bar_background #222436
|
|
||||||
|
|
||||||
#: Background color for the tab bar. Defaults to using the terminal
|
#: Background color for the tab bar. Defaults to using the terminal
|
||||||
#: background color.
|
#: background color.
|
||||||
@@ -983,8 +973,8 @@ tab_bar_margin_color none
|
|||||||
|
|
||||||
#: Color scheme {{{
|
#: Color scheme {{{
|
||||||
|
|
||||||
foreground #c8d3f5
|
|
||||||
background #222436
|
include current-theme.conf
|
||||||
|
|
||||||
#: The foreground and background colors.
|
#: The foreground and background colors.
|
||||||
|
|
||||||
@@ -1043,8 +1033,6 @@ dim_opacity 1
|
|||||||
#: How much to dim text that has the DIM/FAINT attribute set. One
|
#: How much to dim text that has the DIM/FAINT attribute set. One
|
||||||
#: means no dimming and zero means fully dimmed (i.e. invisible).
|
#: means no dimming and zero means fully dimmed (i.e. invisible).
|
||||||
|
|
||||||
selection_foreground #2d3f76
|
|
||||||
selection_background #c8d3f5
|
|
||||||
|
|
||||||
#: The foreground and background colors for text selected with the
|
#: The foreground and background colors for text selected with the
|
||||||
#: mouse. Setting both of these to none will cause a "reverse video"
|
#: mouse. Setting both of these to none will cause a "reverse video"
|
||||||
@@ -1060,47 +1048,29 @@ selection_background #c8d3f5
|
|||||||
#: dull and bright version, for the first 16 colors. You can set the
|
#: dull and bright version, for the first 16 colors. You can set the
|
||||||
#: remaining 240 colors as color16 to color255.
|
#: remaining 240 colors as color16 to color255.
|
||||||
|
|
||||||
color0 #1b1d2b
|
|
||||||
color8 #444a73
|
|
||||||
|
|
||||||
#: black
|
#: black
|
||||||
|
|
||||||
color1 #ff757f
|
|
||||||
color9 #ff757f
|
|
||||||
|
|
||||||
#: red
|
#: red
|
||||||
|
|
||||||
color2 #a5e8b5
|
|
||||||
color10 #a5e8b5
|
|
||||||
|
|
||||||
#: green
|
#: green
|
||||||
color3 #ffc777
|
|
||||||
color11 #ffc777
|
|
||||||
|
|
||||||
#: yellow
|
#: yellow
|
||||||
|
|
||||||
color4 #82aaff
|
|
||||||
color12 #82aaff
|
|
||||||
|
|
||||||
#: blue
|
#: blue
|
||||||
|
|
||||||
color5 #c099ff
|
|
||||||
color13 #c099ff
|
|
||||||
|
|
||||||
#: magenta
|
#: magenta
|
||||||
|
|
||||||
color6 #86e1fc
|
|
||||||
color14 #86e1fc
|
|
||||||
|
|
||||||
#: cyan
|
#: cyan
|
||||||
|
|
||||||
color7 #828bb8
|
|
||||||
color15 #c8d3f5
|
|
||||||
|
|
||||||
#: white
|
#: white
|
||||||
|
|
||||||
color16 #ff966c
|
|
||||||
color17 #c53b53
|
|
||||||
|
|
||||||
# mark1_foreground black
|
# mark1_foreground black
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
# Tokyo Night Day — the palette's own light variant.
|
||||||
|
#
|
||||||
|
# The same hues as Moon at a different lightness, so a terminal in light mode
|
||||||
|
# still belongs to this desktop rather than looking like a different machine.
|
||||||
|
# Kept in the same order as tokyonight-moon.conf so the two can be diffed.
|
||||||
|
|
||||||
|
cursor #3760bf
|
||||||
|
cursor_text_color #e1e2e7
|
||||||
|
url_color #118c74
|
||||||
|
active_border_color #2e7de9
|
||||||
|
inactive_border_color #c4c8da
|
||||||
|
active_tab_foreground #e1e2e7
|
||||||
|
active_tab_background #2e7de9
|
||||||
|
inactive_tab_foreground #3760bf
|
||||||
|
inactive_tab_background #c4c8da
|
||||||
|
tab_bar_background #e1e2e7
|
||||||
|
foreground #3760bf
|
||||||
|
background #e1e2e7
|
||||||
|
selection_foreground #e1e2e7
|
||||||
|
selection_background #99a7df
|
||||||
|
color0 #e9e9ed
|
||||||
|
color8 #a1a6c5
|
||||||
|
color1 #f52a65
|
||||||
|
color9 #f52a65
|
||||||
|
color2 #587539
|
||||||
|
color10 #587539
|
||||||
|
color3 #8c6c3e
|
||||||
|
color11 #8c6c3e
|
||||||
|
color4 #2e7de9
|
||||||
|
color12 #2e7de9
|
||||||
|
color5 #9854f1
|
||||||
|
color13 #9854f1
|
||||||
|
color6 #007197
|
||||||
|
color14 #007197
|
||||||
|
color7 #6172b0
|
||||||
|
color15 #3760bf
|
||||||
|
color16 #b15c00
|
||||||
|
color17 #c64343
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
# Tokyo Night Moon — the dark theme Panama ships.
|
||||||
|
#
|
||||||
|
# Extracted from kitty.conf so the two schemes can be swapped. kitty.conf
|
||||||
|
# includes current-theme.conf, which Panama generates from the colour scheme
|
||||||
|
# setting; that generated file is gitignored because it is machine state.
|
||||||
|
#
|
||||||
|
# Live changes go through `kitty @ set-colors`, which is why kitty.conf enables
|
||||||
|
# remote control. Without it a scheme change would only reach terminals opened
|
||||||
|
# afterwards.
|
||||||
|
|
||||||
|
cursor #c8d3f5
|
||||||
|
cursor_text_color #111325
|
||||||
|
url_color #4fd6be
|
||||||
|
active_border_color #82aaff
|
||||||
|
inactive_border_color #2f334d
|
||||||
|
active_tab_foreground #1e2030
|
||||||
|
active_tab_background #82aaff
|
||||||
|
inactive_tab_foreground #c8d3f5
|
||||||
|
inactive_tab_background #42465a
|
||||||
|
tab_bar_background #222436
|
||||||
|
foreground #c8d3f5
|
||||||
|
background #222436
|
||||||
|
selection_foreground #2d3f76
|
||||||
|
selection_background #c8d3f5
|
||||||
|
color0 #1b1d2b
|
||||||
|
color8 #444a73
|
||||||
|
color1 #ff757f
|
||||||
|
color9 #ff757f
|
||||||
|
color2 #a5e8b5
|
||||||
|
color10 #a5e8b5
|
||||||
|
color3 #ffc777
|
||||||
|
color11 #ffc777
|
||||||
|
color4 #82aaff
|
||||||
|
color12 #82aaff
|
||||||
|
color5 #c099ff
|
||||||
|
color13 #c099ff
|
||||||
|
color6 #86e1fc
|
||||||
|
color14 #86e1fc
|
||||||
|
color7 #828bb8
|
||||||
|
color15 #c8d3f5
|
||||||
|
color16 #ff966c
|
||||||
|
color17 #c53b53
|
||||||
@@ -10,3 +10,6 @@ vim.api.nvim_create_autocmd("BufWritePre", {
|
|||||||
vim.fn.winrestview(view)
|
vim.fn.winrestview(view)
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
-- Follow the desktop's light/dark setting while running, not only at startup.
|
||||||
|
require("config.panama").watch()
|
||||||
|
|||||||
@@ -0,0 +1,88 @@
|
|||||||
|
-- Panama desktop integration.
|
||||||
|
--
|
||||||
|
-- Neovim is the one application here that neither reads the desktop portal nor
|
||||||
|
-- has a control socket open by default, so it reads the shared settings file
|
||||||
|
-- directly -- the same ~/.config/panama/settings.json that the shell and the
|
||||||
|
-- Hyprland config read.
|
||||||
|
--
|
||||||
|
-- Nothing here may raise. A missing or malformed settings file must cost the
|
||||||
|
-- user their colour scheme preference and nothing else; editing text is more
|
||||||
|
-- important than matching the desktop.
|
||||||
|
|
||||||
|
local M = {}
|
||||||
|
|
||||||
|
local function settings_path()
|
||||||
|
local config_home = os.getenv("XDG_CONFIG_HOME")
|
||||||
|
if config_home == nil or config_home == "" then
|
||||||
|
local home = os.getenv("HOME")
|
||||||
|
if home == nil or home == "" then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
config_home = home .. "/.config"
|
||||||
|
end
|
||||||
|
return config_home .. "/panama/settings.json"
|
||||||
|
end
|
||||||
|
|
||||||
|
-- "dark" or "light". Defaults to dark, which is what Panama ships.
|
||||||
|
function M.color_scheme()
|
||||||
|
local path = settings_path()
|
||||||
|
if not path then
|
||||||
|
return "dark"
|
||||||
|
end
|
||||||
|
|
||||||
|
local ok, contents = pcall(function()
|
||||||
|
local file = io.open(path, "r")
|
||||||
|
if not file then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
local text = file:read("*a")
|
||||||
|
file:close()
|
||||||
|
return text
|
||||||
|
end)
|
||||||
|
if not ok or not contents or contents == "" then
|
||||||
|
return "dark"
|
||||||
|
end
|
||||||
|
|
||||||
|
local decoded_ok, decoded = pcall(vim.json.decode, contents)
|
||||||
|
if not decoded_ok or type(decoded) ~= "table" then
|
||||||
|
return "dark"
|
||||||
|
end
|
||||||
|
|
||||||
|
return decoded.colorScheme == "light" and "light" or "dark"
|
||||||
|
end
|
||||||
|
|
||||||
|
function M.is_light()
|
||||||
|
return M.color_scheme() == "light"
|
||||||
|
end
|
||||||
|
|
||||||
|
-- tokyonight ships a light variant in the same family, so light mode stays the
|
||||||
|
-- same identity rather than becoming a different editor theme.
|
||||||
|
function M.tokyonight_style()
|
||||||
|
return M.is_light() and "day" or "moon"
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Re-apply the scheme when the window regains focus.
|
||||||
|
--
|
||||||
|
-- Neovim reads the setting once at startup and has no control socket open by
|
||||||
|
-- default, so an editor already running when the desktop scheme flips would
|
||||||
|
-- otherwise stay on the old palette until it was restarted. FocusGained is
|
||||||
|
-- cheap, happens exactly when you would notice the mismatch, and does nothing
|
||||||
|
-- at all unless the scheme actually changed.
|
||||||
|
function M.watch()
|
||||||
|
local applied = M.color_scheme()
|
||||||
|
|
||||||
|
vim.api.nvim_create_autocmd("FocusGained", {
|
||||||
|
group = vim.api.nvim_create_augroup("PanamaColorScheme", { clear = true }),
|
||||||
|
callback = function()
|
||||||
|
local current = M.color_scheme()
|
||||||
|
if current == applied then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
applied = current
|
||||||
|
vim.o.background = current
|
||||||
|
pcall(vim.cmd.colorscheme, current == "light" and "tokyonight-day" or "tokyonight-moon")
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
return M
|
||||||
@@ -1,31 +1,68 @@
|
|||||||
|
-- Tokyo Night, following the desktop's colour scheme.
|
||||||
|
--
|
||||||
|
-- Moon when Panama is dark, Day when it is light. Same theme family either way,
|
||||||
|
-- so the editor keeps the identity the rest of the desktop has rather than
|
||||||
|
-- becoming a different-looking application when the scheme flips.
|
||||||
|
--
|
||||||
|
-- The readability fixes below are deliberately dark-only. They were written
|
||||||
|
-- against Moon's palette -- a pale comment colour, a mid-grey gutter -- and
|
||||||
|
-- applying them to Day would put light grey text on a light background, which
|
||||||
|
-- is exactly the legibility problem they exist to solve, inverted.
|
||||||
|
|
||||||
|
local panama = require("config.panama")
|
||||||
|
|
||||||
return {
|
return {
|
||||||
{
|
{
|
||||||
"folke/tokyonight.nvim",
|
"folke/tokyonight.nvim",
|
||||||
opts = {
|
opts = function()
|
||||||
style = "moon",
|
local light = panama.is_light()
|
||||||
|
|
||||||
|
return {
|
||||||
|
style = panama.tokyonight_style(),
|
||||||
|
light_style = "day",
|
||||||
transparent = true,
|
transparent = true,
|
||||||
|
|
||||||
on_colors = function(colors)
|
on_colors = function(colors)
|
||||||
|
if light then
|
||||||
|
-- Day's defaults are tuned for a light ground and mostly need no
|
||||||
|
-- help. Comments are the exception: the shipped #848cb5 measures
|
||||||
|
-- 2.54:1 against the #e1e2e7 background, well under the 3:1 floor
|
||||||
|
-- for secondary text. This is 3.25:1 -- readable, and still clearly
|
||||||
|
-- dimmer than Normal's 4.52:1 so it does not compete with code.
|
||||||
|
colors.comment = "#7079a8"
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
colors.comment = "#a0a7c5"
|
colors.comment = "#a0a7c5"
|
||||||
colors.fg_gutter = "#787f93"
|
colors.fg_gutter = "#787f93"
|
||||||
colors.terminal_black = "#828bb8"
|
colors.terminal_black = "#828bb8"
|
||||||
end,
|
end,
|
||||||
|
|
||||||
on_highlights = function(highlights, colors)
|
on_highlights = function(highlights, colors)
|
||||||
-- Fix inline code visibility in markdown
|
-- Inline code in markdown is invisible at both lightnesses without
|
||||||
|
-- an explicit background, because the theme leaves it unset.
|
||||||
highlights["@markup.raw.markdown_inline"] = {
|
highlights["@markup.raw.markdown_inline"] = {
|
||||||
bg = colors.terminal_black,
|
bg = light and colors.bg_highlight or colors.terminal_black,
|
||||||
fg = colors.fg,
|
fg = colors.fg,
|
||||||
}
|
}
|
||||||
highlights["RenderMarkdownCodeInline"] = {
|
highlights["RenderMarkdownCodeInline"] = {
|
||||||
bg = colors.terminal_black,
|
bg = light and colors.bg_highlight or colors.terminal_black,
|
||||||
fg = colors.fg,
|
fg = colors.fg,
|
||||||
}
|
}
|
||||||
-- Fix LspReference* readability: DiagnosticUnnecessary dims fg for unused
|
|
||||||
-- imports, making text nearly invisible against LspReferenceText's background
|
-- LspReference* readability: DiagnosticUnnecessary dims fg for unused
|
||||||
highlights["LspReferenceText"] = { bg = colors.fg_gutter, fg = colors.fg }
|
-- imports, making text nearly invisible against LspReferenceText's
|
||||||
highlights["LspReferenceRead"] = { bg = colors.fg_gutter, fg = colors.fg }
|
-- background.
|
||||||
highlights["LspReferenceWrite"] = { bg = colors.fg_gutter, fg = colors.fg }
|
local reference = {
|
||||||
|
bg = light and colors.bg_visual or colors.fg_gutter,
|
||||||
|
fg = colors.fg,
|
||||||
|
}
|
||||||
|
highlights["LspReferenceText"] = reference
|
||||||
|
highlights["LspReferenceRead"] = reference
|
||||||
|
highlights["LspReferenceWrite"] = reference
|
||||||
|
end,
|
||||||
|
}
|
||||||
end,
|
end,
|
||||||
},
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"LazyVim/LazyVim",
|
"LazyVim/LazyVim",
|
||||||
|
|||||||
+57
@@ -0,0 +1,57 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Propagates the colour scheme to applications that do not read the desktop
|
||||||
|
# portal.
|
||||||
|
#
|
||||||
|
# Most modern applications DO follow org.freedesktop.portal.Settings and need
|
||||||
|
# nothing from us: GTK4/libadwaita, Qt6, Chromium and Electron all read
|
||||||
|
# org.freedesktop.appearance color-scheme, which xdg-desktop-portal-gtk serves
|
||||||
|
# from gsettings. Panama sets that, so those follow automatically.
|
||||||
|
#
|
||||||
|
# Terminals are the notable exception -- they predate the standard and carry
|
||||||
|
# their own palettes. kitty is handled here.
|
||||||
|
#
|
||||||
|
# panama-theme-apps dark|light
|
||||||
|
#
|
||||||
|
# kitty gets it twice: the generated include file so terminals opened later
|
||||||
|
# start correct, and a live `set-colors` over its control socket so terminals
|
||||||
|
# already open change now. Without the second, a scheme change appears to do
|
||||||
|
# nothing until you open a new window.
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
scheme="${1:-dark}"
|
||||||
|
case "$scheme" in
|
||||||
|
dark|light) ;;
|
||||||
|
*) printf 'usage: panama-theme-apps [dark|light]\n' >&2; exit 2 ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
kitty_dir="${XDG_CONFIG_HOME:-$HOME/.config}/kitty"
|
||||||
|
theme_file="$kitty_dir/themes/tokyonight-moon.conf"
|
||||||
|
[[ "$scheme" == "light" ]] && theme_file="$kitty_dir/themes/tokyonight-day.conf"
|
||||||
|
|
||||||
|
status_kitty="skipped"
|
||||||
|
if [[ -r "$theme_file" ]]; then
|
||||||
|
# Written atomically: kitty may read this while a new window is starting.
|
||||||
|
if cp "$theme_file" "$kitty_dir/current-theme.conf.tmp" 2>/dev/null \
|
||||||
|
&& mv "$kitty_dir/current-theme.conf.tmp" "$kitty_dir/current-theme.conf" 2>/dev/null; then
|
||||||
|
status_kitty="written"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Live-apply to running terminals. kitty appends its PID to the socket name
|
||||||
|
# from listen_on, so there is one socket per instance -- "unix:@mykitty"
|
||||||
|
# alone reaches nothing, which is exactly how this looked like remote
|
||||||
|
# control being disabled when it was not.
|
||||||
|
if command -v kitty >/dev/null 2>&1 && command -v ss >/dev/null 2>&1; then
|
||||||
|
applied=0
|
||||||
|
while read -r socket; do
|
||||||
|
[[ -n "$socket" ]] || continue
|
||||||
|
if kitty @ --to "unix:@${socket#@}" set-colors --all --configured "$theme_file" >/dev/null 2>&1; then
|
||||||
|
applied=$((applied + 1))
|
||||||
|
fi
|
||||||
|
done < <(ss -xl 2>/dev/null | grep -oE '@mykitty[^[:space:]]*' | sort -u)
|
||||||
|
(( applied > 0 )) && status_kitty="applied to $applied"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
printf '{"scheme":"%s","kitty":"%s"}\n' "$scheme" "$status_kitty"
|
||||||
@@ -21,6 +21,8 @@ import qs.config
|
|||||||
Singleton {
|
Singleton {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
|
readonly property string appThemePath: Quickshell.shellDir + "/scripts/panama-theme-apps"
|
||||||
|
|
||||||
readonly property bool dark: DesktopPreferences.get("colorScheme") !== "light"
|
readonly property bool dark: DesktopPreferences.get("colorScheme") !== "light"
|
||||||
property string lastError: ""
|
property string lastError: ""
|
||||||
|
|
||||||
@@ -92,6 +94,12 @@ Singleton {
|
|||||||
commands.push(["hyprctl", "eval",
|
commands.push(["hyprctl", "eval",
|
||||||
`hl.config({ general = { col = { inactive_border = "${inactive}" } } })`]);
|
`hl.config({ general = { col = { inactive_border = "${inactive}" } } })`]);
|
||||||
|
|
||||||
|
// Applications that predate org.freedesktop.appearance and carry their
|
||||||
|
// own palettes -- terminals, chiefly. Everything that reads the portal
|
||||||
|
// (GTK4, Qt6, Chromium, Electron) is already handled by the gsettings
|
||||||
|
// write above and needs nothing here.
|
||||||
|
commands.push([root.appThemePath, root.dark ? "dark" : "light"]);
|
||||||
|
|
||||||
root.enqueue(commands);
|
root.enqueue(commands);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -70,6 +70,27 @@ for dir in "${dirs[@]}"; do
|
|||||||
log "Linked $PANAMA_DOT/$dir → $CONFIG/$dir"
|
log "Linked $PANAMA_DOT/$dir → $CONFIG/$dir"
|
||||||
done
|
done
|
||||||
|
|
||||||
|
# kitty.conf ends with `include current-theme.conf`, and that file is generated
|
||||||
|
# from the desktop colour scheme rather than committed -- it is machine state.
|
||||||
|
# A fresh checkout therefore has no such file, and kitty starts by complaining
|
||||||
|
# about a missing include and falling back to its stock colours. Seed it from
|
||||||
|
# the scheme in settings.json (dark unless the user has chosen otherwise) so a
|
||||||
|
# first launch is themed; ColorScheme.qml overwrites it on every change after.
|
||||||
|
KITTY_THEME="$PANAMA_DOT/kitty/current-theme.conf"
|
||||||
|
if [ -e "$KITTY_THEME" ]; then
|
||||||
|
log "Keeping existing kitty theme at $KITTY_THEME"
|
||||||
|
else
|
||||||
|
scheme="dark"
|
||||||
|
settings="${XDG_CONFIG_HOME:-$HOME/.config}/panama/settings.json"
|
||||||
|
if [ -r "$settings" ]; then
|
||||||
|
stored="$(jq -r '.colorScheme // "dark"' "$settings" 2>/dev/null || echo dark)"
|
||||||
|
[ "$stored" = "light" ] && scheme="light"
|
||||||
|
fi
|
||||||
|
[ "$scheme" = "light" ] && theme="tokyonight-day" || theme="tokyonight-moon"
|
||||||
|
cp "$PANAMA_DOT/kitty/themes/$theme.conf" "$KITTY_THEME"
|
||||||
|
log "Seeded kitty $scheme theme ($theme) → $KITTY_THEME"
|
||||||
|
fi
|
||||||
|
|
||||||
# Vicinae 0.26 discovers user themes from its XDG data directory rather than
|
# Vicinae 0.26 discovers user themes from its XDG data directory rather than
|
||||||
# from ~/.config/vicinae. Keep the authored theme in Panama with the rest of
|
# from ~/.config/vicinae. Keep the authored theme in Panama with the rest of
|
||||||
# the launcher config and expose only that file at Vicinae's runtime path.
|
# the launcher config and expose only that file at Vicinae's runtime path.
|
||||||
|
|||||||
@@ -113,6 +113,25 @@ config_home="$(mktemp -d /tmp/panama-displays-config.XXXXXX)"
|
|||||||
run() { XDG_CONFIG_HOME="$config_home" qs -p "$harness" "$@"; }
|
run() { XDG_CONFIG_HOME="$config_home" qs -p "$harness" "$@"; }
|
||||||
status() { run ipc call displays-test status; }
|
status() { run ipc call displays-test status; }
|
||||||
|
|
||||||
|
# The shipped geometry, read from the Hyprland config rather than from the
|
||||||
|
# running compositor.
|
||||||
|
#
|
||||||
|
# Everything below captures "original" from what it observes at start, which is
|
||||||
|
# correct only if the display is already in a good state. A previous run that
|
||||||
|
# failed mid-revert leaves the display changed, and the next run then captures
|
||||||
|
# THAT as the original and faithfully restores the desktop to a broken value.
|
||||||
|
# One flake becomes permanent. So refuse to run from a state that does not match
|
||||||
|
# what the config says, rather than laundering it.
|
||||||
|
shipped_scale="$(sed -n 's/^local shipped_scale *= *\([0-9.]*\).*/\1/p' \
|
||||||
|
"$repo_dir/config/dot/hypr/monitors.lua" | head -1)"
|
||||||
|
[[ -n "$shipped_scale" ]] || fail 'could not read the shipped scale from monitors.lua -- the guard below depends on it, and skipping it silently is how a dirty baseline gets laundered'
|
||||||
|
if [[ -n "$shipped_scale" ]]; then
|
||||||
|
live_scale="$(hyprctl -j monitors | jq -r '.[0].scale')"
|
||||||
|
if ! awk -v a="$live_scale" -v b="$shipped_scale" 'BEGIN { exit !(a == b) }'; then
|
||||||
|
fail "the display is at scale $live_scale but the config ships $shipped_scale -- refusing to capture a dirty state as the baseline. Restore it first: hyprctl eval 'hl.monitor({ output = \"DP-2\", mode = \"4500x3000@60\", scale = $shipped_scale, transform = 0 })'"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
original_mode=""
|
original_mode=""
|
||||||
original_scale=""
|
original_scale=""
|
||||||
original_transform=""
|
original_transform=""
|
||||||
|
|||||||
@@ -13,6 +13,20 @@ cleanup() {
|
|||||||
trap cleanup EXIT
|
trap cleanup EXIT
|
||||||
|
|
||||||
qs ipc call focus end >/dev/null 2>&1 || true
|
qs ipc call focus end >/dev/null 2>&1 || true
|
||||||
|
|
||||||
|
# focus start records the caffeine state it found so end() can hand it back, and
|
||||||
|
# the assertion below requires caffeine to finish off. Both are only true if
|
||||||
|
# caffeine starts off.
|
||||||
|
#
|
||||||
|
# This test kills and restarts the live shell, so an interrupted run leaves
|
||||||
|
# caffeine on with nothing to turn it back off. The next run then records
|
||||||
|
# "previously on", faithfully restores it, and fails -- and every run after
|
||||||
|
# that fails identically, with the desktop quietly unable to idle or lock the
|
||||||
|
# whole time. Refuse to start from that state rather than latching it in.
|
||||||
|
if [[ "$(qs ipc call caffeine status 2>/dev/null)" != "false" ]]; then
|
||||||
|
fail 'caffeine is on before the session starts -- this test cannot distinguish "restored correctly" from "never released". Turn it off first: qs ipc call caffeine toggle'
|
||||||
|
fi
|
||||||
|
|
||||||
qs ipc call focus start >/dev/null
|
qs ipc call focus start >/dev/null
|
||||||
|
|
||||||
state_file=$(find "${XDG_STATE_HOME:-$HOME/.local/state}/quickshell/by-shell" -name focus-session.json -print -quit)
|
state_file=$(find "${XDG_STATE_HOME:-$HOME/.local/state}/quickshell/by-shell" -name focus-session.json -print -quit)
|
||||||
|
|||||||
Reference in New Issue
Block a user