Initial Lime window manager

This commit is contained in:
2026-10-02 14:14:47 -05:00
commit ccd691edd0
121 changed files with 29719 additions and 0 deletions

170
work/bar-grouping.html Normal file
View File

@@ -0,0 +1,170 @@
<div id="lime-bar-grouping" aria-label="Lime bar grouping and separators">
<style>
#lime-bar-grouping {
--lime-bg: light-dark(#fff7ed, #060a0c);
--lime-ink: light-dark(#35271d, #ffdbb0);
--lime-muted: light-dark(#685a4d, #a8adb0);
--lime-focus-bg: light-dark(#f0dfc8, #121f25);
--lime-idle-bg: light-dark(#f7eee1, #0b1216);
--lime-accent: light-dark(#8a470c, #ffac54);
--lime-separator: light-dark(#946336, #b88755);
--lime-edge: light-dark(#d5c6b5, #25343b);
--lime-divider: "|";
--lime-space: var(--lime-requested-space, 9px);
font-family: ui-monospace, "DejaVu Sans Mono", monospace;
color: var(--lime-ink);
display: grid;
gap: 20px;
padding: 4px 0;
}
#lime-bar-grouping * { box-sizing: border-box; }
#lime-bar-grouping .variant { min-width: 0; }
#lime-bar-grouping .caption {
font-size: 12px; line-height: 1.5;
color: var(--lime-muted); margin-bottom: 7px;
}
#lime-bar-grouping .bar {
display: grid; grid-template-columns: auto minmax(0, 1fr) auto;
min-width: 0; width: 100%; height: 34px;
background: var(--lime-bg); border: 1px solid var(--lime-edge);
font-size: 12px; line-height: 1;
}
#lime-bar-grouping .identity {
display: flex; align-items: center;
min-width: 0; padding: 0 var(--lime-space);
}
#lime-bar-grouping .logo { font-weight: 500; flex: none; }
#lime-bar-grouping .context {
display: flex; align-items: baseline; min-width: 0;
max-width: 160px; white-space: nowrap;
}
#lime-bar-grouping .activity {
color: var(--lime-muted); overflow: hidden; text-overflow: ellipsis;
min-width: 0; flex: 0 1 auto;
}
#lime-bar-grouping .view { flex: none; }
#lime-bar-grouping .dirty { color: var(--lime-accent); flex: none; }
#lime-bar-grouping .layout { white-space: nowrap; flex: none; }
#lime-bar-grouping .divider {
flex: none; margin: 0 var(--lime-space); color: var(--lime-separator);
}
#lime-bar-grouping .divider::before { content: var(--lime-divider); }
#lime-bar-grouping .title-region {
display: flex; align-items: center; min-width: 0; padding: 0 10px;
border-left: 2px solid var(--lime-accent);
background: var(--lime-focus-bg); color: var(--lime-accent);
}
#lime-bar-grouping .title-text {
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
min-width: 0;
}
#lime-bar-grouping .inactive .title-region {
border-left-color: transparent; background: var(--lime-idle-bg);
color: var(--lime-muted);
}
#lime-bar-grouping .status {
display: flex; align-items: center; min-width: 0;
padding: 0 var(--lime-space);
}
#lime-bar-grouping .status[hidden] { display: none; }
#lime-bar-grouping .status-item {
display: flex; align-items: center; white-space: nowrap; min-width: 0;
}
#lime-bar-grouping .status-icon {
display: inline-flex; align-items: center; margin-right: 5px;
color: var(--lime-muted); flex: none;
}
#lime-bar-grouping .status-icon svg { width: 13px; height: 13px; stroke-width: 1.8; }
#lime-bar-grouping .music-value {
overflow: hidden; text-overflow: ellipsis; max-width: 100px;
}
#lime-bar-grouping .clock-value { font-variant-numeric: tabular-nums; }
#lime-bar-grouping[data-icons="false"] .status-icon { display: none; }
@media (max-width: 640px) {
#lime-bar-grouping .music, #lime-bar-grouping .music-divider { display: none; }
#lime-bar-grouping .context { max-width: 120px; }
}
@media (max-width: 440px) {
#lime-bar-grouping { --lime-space: min(var(--lime-requested-space, 9px), 5px); }
#lime-bar-grouping .volume, #lime-bar-grouping .volume-divider { display: none; }
#lime-bar-grouping .context { max-width: 90px; }
#lime-bar-grouping .title-region { padding: 0 6px; }
}
</style>
<section class="variant" aria-label="Refined bar on the focused head">
<div class="caption">A · Refined grouping · Focused head</div>
<div class="bar" role="img" aria-label="Lime menu, WM activity and Code view, master-stack layout, focused title, then music, volume and time separated by contrasting pipes">
<div class="identity">
<span class="logo">Lime</span><span class="divider" aria-hidden="true"></span>
<span class="context"><span class="activity">WM</span><span class="view">:Code</span><span class="dirty">*</span></span>
<span class="divider" aria-hidden="true"></span><span class="layout">[]=</span>
</div>
<div class="title-region"><span class="title-text">config.lisp — VS Code</span></div>
<div class="status">
<span class="status-item music" aria-label="Playing: スパイダー"><span class="status-icon" aria-hidden="true"><i data-lucide="music-2"></i></span><span class="music-value">スパイダー</span></span>
<span class="divider music-divider" aria-hidden="true"></span>
<span class="status-item volume" aria-label="Volume: 25 percent"><span class="status-icon" aria-hidden="true"><i data-lucide="volume-2"></i></span>25%</span>
<span class="divider volume-divider" aria-hidden="true"></span>
<span class="status-item clock" aria-label="Time: 03:01"><span class="status-icon" aria-hidden="true"><i data-lucide="clock-3"></i></span><span class="clock-value">03:01</span></span>
</div>
</div>
</section>
<section class="variant inactive" aria-label="Refined bar on an unfocused head">
<div class="caption">Same design · Unfocused head</div>
<div class="bar" role="img" aria-label="Same separators and content, with a quieter title section on an unfocused head">
<div class="identity">
<span class="logo">Lime</span><span class="divider" aria-hidden="true"></span>
<span class="context"><span class="activity">WM</span><span class="view">:Code</span><span class="dirty">*</span></span>
<span class="divider" aria-hidden="true"></span><span class="layout">[]=</span>
</div>
<div class="title-region"><span class="title-text">config.lisp — VS Code</span></div>
<div class="status">
<span class="status-item music" aria-label="Playing: スパイダー"><span class="status-icon" aria-hidden="true"><i data-lucide="music-2"></i></span><span class="music-value">スパイダー</span></span>
<span class="divider music-divider" aria-hidden="true"></span>
<span class="status-item volume" aria-label="Volume: 25 percent"><span class="status-icon" aria-hidden="true"><i data-lucide="volume-2"></i></span>25%</span>
<span class="divider volume-divider" aria-hidden="true"></span>
<span class="status-item clock" aria-label="Time: 03:01"><span class="status-icon" aria-hidden="true"><i data-lucide="clock-3"></i></span><span class="clock-value">03:01</span></span>
</div>
</div>
</section>
<script>
(() => {
const root = document.getElementById('lime-bar-grouping');
const state = {
separator: '|', spacing: 9, icons: true, status: true,
context: 'WM:Code*', title: 'config.lisp — VS Code'
};
function render() {
root.style.setProperty('--lime-divider', JSON.stringify(state.separator));
root.style.setProperty('--lime-requested-space', state.spacing + 'px');
root.dataset.icons = String(state.icons);
const colon = state.context.indexOf(':');
const dirty = state.context.endsWith('*');
root.querySelectorAll('.activity').forEach(el => el.textContent = state.context.slice(0, colon));
root.querySelectorAll('.view').forEach(el => el.textContent = state.context.slice(colon, dirty ? -1 : undefined));
root.querySelectorAll('.dirty').forEach(el => el.textContent = dirty ? '*' : '');
root.querySelectorAll('.title-text').forEach(el => el.textContent = state.title);
root.querySelectorAll('.status').forEach(el => el.hidden = !state.status);
root.querySelectorAll('.bar').forEach(el => {
const focus = el.closest('.inactive') ? 'Unfocused head' : 'Focused head';
el.setAttribute('aria-label', focus + ': Lime menu; ' + state.context + '; master-stack layout; ' + state.title + (state.status ? '; music, volume and time' : '') + '.');
});
}
render();
if (globalThis.Tweak) {
const tweak = new Tweak({ container: root, onChange: render });
tweak.addSelect(state, 'separator', { label: 'Separator', options: [
{ label: 'Pipe |', value: '|' }, { label: 'Dot ·', value: '·' }
] });
tweak.addSlider(state, 'spacing', { label: 'Separator spacing', min: 5, max: 12, unit: 'px' });
tweak.addToggle(state, 'icons', { label: 'Status icons' });
tweak.addToggle(state, 'status', { label: 'Status visible' });
tweak.addSelect(state, 'context', { label: 'Activity and view', options: ['WM:Code*', 'Lime development:Debug*', 'Chill:Music'] });
tweak.addSelect(state, 'title', { label: 'Window title', options: ['config.lisp — VS Code', 'Terminal', 'Window management notes — Waterfox', 'Untitled window'] });
}
})();
</script>
</div>