mirror of
https://github.com/outbackdingo/hyprcosmic.git
synced 2026-08-25 07:10:09 +00:00
Give rofi a theme, in four layers
`rofi -show drun` came up unstyled. Three separate reasons, all of them invisible: `import-theme` wrote ~/.config/rofi/theme.rasi, but rofi only ever auto-loads config.rasi and nothing imported theme.rasi; theme.rasi holds a HyDE palette and nothing else, no widget geometry at all; and no layout was shipped anywhere for it to colour. The layering mirrors what config/waybar already does, for the same reason -- a theme supplies colours, and the layout has to survive being handed a theme that defines only some of them: 1. palette.rasi defaults, under the exact names HyDE themes use 2. theme.rasi the installed theme's rofi.theme, written by cosmic-conf 3. rules.rasi geometry and layout, with no colour literals at all 4. local.rasi per-machine paths: sidebar wallpaper, icon theme Later imports win, so a theme recolours the launcher without rules.rasi knowing a theme exists, and a machine points at its own wallpaper without either of them knowing the path. Unlike waybar there is no bridge step: a HyDE rofi.theme defines the names rules.rasi already references. 1 and 3 are shared and go under /usr/share/hyprcosmic/rofi. 2 and 4 must be per-user, and config.rasi with them: it imports those two relatively, and rofi resolves a relative @import against the importing file's directory. rules.rasi is HyDE's style_1 with three deliberate departures, documented in its header. HyDE computes the border width, radius and font in rofilaunch.sh before invoking rofi; there is no launcher script here -- the keybinding runs `rofi -show drun` bare -- so those are baked in. The sidebar image moves to local.rasi because HyDE's ~/.cache/hyde/wall.thmb does not exist outside HyDE. And dummywall gets `background-color: @main-bg` rather than transparent, so a machine with no wallpaper set shows a panel instead of a hole. The display-* labels are Nerd Font glyphs copied byte-for-byte out of style_1.rasi. They are Private Use Area codepoints and do not survive being retyped; verified as U+F303, U+F120, U+F07B, U+F2D0, each followed by a thin space, and confirmed present in JetBrainsMono Nerd Font via `fc-list :charset=`. Verified with `rofi -dump-theme` and `-dump-config`: both exit 0 with empty stderr, and the merged dump shows the Tokyo Night theme's main-bg beating the palette default.
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
/* rofi configuration and theme entry point for a HyprCosmic session.
|
||||
*
|
||||
* Below the configuration block this file is only an import list, because the
|
||||
* order is the whole design:
|
||||
*
|
||||
* 1. palette.rasi default colours, under the names HyDE themes use
|
||||
* 2. theme.rasi the installed HyDE theme's rofi.theme, if any
|
||||
* 3. rules.rasi geometry and layout; no colour literals at all
|
||||
* 4. local.rasi per-machine bits: the sidebar wallpaper, the icon theme
|
||||
*
|
||||
* Imports are read strictly in sequence and a later definition of a property
|
||||
* wins over an earlier one. That is what lets step 2 recolour the launcher
|
||||
* without step 3 knowing a theme exists, and step 4 point at a wallpaper
|
||||
* without either of them knowing the path.
|
||||
*
|
||||
* There is no bridge step, unlike waybar: a HyDE rofi.theme defines exactly the
|
||||
* names rules.rasi already references, so nothing needs mapping.
|
||||
*
|
||||
* Steps 2 and 4 are relative imports, which rofi resolves against the directory
|
||||
* of the importing file. That is why this file belongs at
|
||||
* ~/.config/rofi/config.rasi rather than under /usr/share: both are per-user.
|
||||
* It is also the only name rofi loads on its own, so `rofi -show drun` from a
|
||||
* keybinding picks all of this up with no arguments and no launcher script.
|
||||
*
|
||||
* Both relative imports must exist. A missing @import is an error rofi reports
|
||||
* in place of the launcher, not a warning it skips, so `cosmic-conf` writes
|
||||
* theme.rasi and local.rasi even when there is nothing to put in them -- empty,
|
||||
* in which case the defaults from step 1 stand.
|
||||
*/
|
||||
|
||||
configuration {
|
||||
modi: "drun,run,window,filebrowser";
|
||||
show-icons: true;
|
||||
|
||||
/* Nerd Font glyphs, as HyDE's style_1 has them: apps, terminal, files,
|
||||
* windows. They render as tofu without a Nerd Font installed; see the font
|
||||
* list in rules.rasi. */
|
||||
display-drun: " ";
|
||||
display-run: " ";
|
||||
display-filebrowser: " ";
|
||||
display-window: " ";
|
||||
|
||||
drun-display-format: "{name}";
|
||||
window-format: "{w}{t}";
|
||||
}
|
||||
|
||||
@import "/usr/share/hyprcosmic/rofi/palette.rasi"
|
||||
@import "theme.rasi"
|
||||
@import "/usr/share/hyprcosmic/rofi/rules.rasi"
|
||||
@import "local.rasi"
|
||||
@@ -0,0 +1,31 @@
|
||||
/* Default colours for the HyprCosmic launcher.
|
||||
*
|
||||
* Only one name set is needed here, unlike waybar's palette.css. A HyDE theme's
|
||||
* rofi.theme is a list of exactly these names -- main-bg, select-fg and so on --
|
||||
* and rules.rasi references the same names directly, so there is nothing to
|
||||
* bridge between. Importing a theme after this file simply re-points them.
|
||||
*
|
||||
* Defining them here is what makes a missing theme harmless: rules.rasi always
|
||||
* resolves against something, so an unthemed launcher renders with these values
|
||||
* instead of every widget falling back to rofi's stock grey.
|
||||
*
|
||||
* Values are Tokyo Night, matching cosmic-conf's own defaults.
|
||||
*/
|
||||
|
||||
* {
|
||||
/* Window and text. main-br is the window border, main-ex an accent HyDE
|
||||
* uses for secondary text; rofi themes vary in how much of it they set. */
|
||||
main-bg: #1a1b26e6;
|
||||
main-fg: #c0caf5ff;
|
||||
main-br: #bb9af7ff;
|
||||
main-ex: #7dcfffff;
|
||||
|
||||
/* The highlighted row. */
|
||||
select-bg: #7aa2f7ff;
|
||||
select-fg: #1a1b26ff;
|
||||
|
||||
/* Named by HyDE's themes but unused by this layout. Defined so a theme that
|
||||
* sets them parses, and so one that does not still resolves. */
|
||||
separatorcolor: transparent;
|
||||
border-color: transparent;
|
||||
}
|
||||
@@ -0,0 +1,173 @@
|
||||
/* Geometry and layout for the HyprCosmic launcher.
|
||||
*
|
||||
* Adapted from HyDE's style_1 ("Background image with a sidebar list"), which
|
||||
* is the layout its rofilaunch.sh uses by default. Two deliberate differences:
|
||||
*
|
||||
* - HyDE injects the border radii, border width and font at the command line,
|
||||
* as three -theme-str arguments computed from Hyprland's own gaps and
|
||||
* border settings. We have no launcher script -- the keybinding in
|
||||
* cosmic.conf runs plain `rofi -show drun` -- so those values are written
|
||||
* out here, at the defaults rofilaunch.sh would have produced.
|
||||
* - The sidebar image lives in local.rasi rather than here, because the
|
||||
* wallpaper path is per-user. HyDE points at ~/.cache/hyde/wall.thmb, a
|
||||
* thumbnail its wallpaper scripts generate; we do not run those, so
|
||||
* pointing there would render an empty panel on every machine.
|
||||
*
|
||||
* No colour literals: every colour is a name from palette.rasi, which a theme
|
||||
* may have re-pointed. That separation is what lets `cosmic-conf import-theme`
|
||||
* recolour the launcher without touching a line of layout.
|
||||
*/
|
||||
|
||||
/* Pango takes a comma-separated family list, so the Nerd Font is a preference
|
||||
* rather than a requirement -- the glyphs in config.rasi's mode labels need it,
|
||||
* but everything else still renders without it. */
|
||||
* {
|
||||
font: "JetBrainsMono Nerd Font, Noto Sans Mono 10";
|
||||
}
|
||||
|
||||
|
||||
// Main //
|
||||
window {
|
||||
height: 33em;
|
||||
width: 63em;
|
||||
transparency: "real";
|
||||
fullscreen: false;
|
||||
enabled: true;
|
||||
cursor: "default";
|
||||
spacing: 0em;
|
||||
padding: 0em;
|
||||
border: 2px;
|
||||
border-radius: 30px;
|
||||
border-color: @main-br;
|
||||
background-color: @main-bg;
|
||||
}
|
||||
mainbox {
|
||||
enabled: true;
|
||||
spacing: 0em;
|
||||
padding: 0em;
|
||||
orientation: horizontal;
|
||||
children: [ "dummywall" , "listbox" ];
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
/* The sidebar. Solid colour here so that a machine with no wallpaper override
|
||||
* gets a panel in the theme's own background, not a hole. local.rasi paints an
|
||||
* image over the top when there is one. */
|
||||
dummywall {
|
||||
spacing: 0em;
|
||||
padding: 0em;
|
||||
width: 37em;
|
||||
expand: false;
|
||||
orientation: horizontal;
|
||||
children: [ "mode-switcher" , "inputbar" ];
|
||||
background-color: @main-bg;
|
||||
}
|
||||
|
||||
|
||||
// Modes //
|
||||
mode-switcher {
|
||||
orientation: vertical;
|
||||
enabled: true;
|
||||
width: 3.8em;
|
||||
padding: 9.2em 0.5em 9.2em 0.5em;
|
||||
spacing: 1.2em;
|
||||
background-color: transparent;
|
||||
}
|
||||
button {
|
||||
cursor: pointer;
|
||||
border-radius: 2em;
|
||||
background-color: @main-bg;
|
||||
text-color: @main-fg;
|
||||
}
|
||||
button selected {
|
||||
background-color: @main-fg;
|
||||
text-color: @main-bg;
|
||||
}
|
||||
|
||||
|
||||
// Inputs //
|
||||
/* The entry is hidden: typing filters the list without a visible prompt, which
|
||||
* is what gives style_1 its uncluttered look. inputbar still has to exist for
|
||||
* keystrokes to reach the filter. */
|
||||
inputbar {
|
||||
enabled: true;
|
||||
children: [ "entry" ];
|
||||
background-color: transparent;
|
||||
}
|
||||
entry {
|
||||
enabled: false;
|
||||
}
|
||||
|
||||
|
||||
// Lists //
|
||||
listbox {
|
||||
spacing: 0em;
|
||||
padding: 2em;
|
||||
children: [ "dummy" , "listview" , "dummy" ];
|
||||
background-color: transparent;
|
||||
}
|
||||
listview {
|
||||
enabled: true;
|
||||
spacing: 0em;
|
||||
padding: 0em;
|
||||
columns: 1;
|
||||
lines: 8;
|
||||
cycle: true;
|
||||
dynamic: true;
|
||||
scrollbar: false;
|
||||
layout: vertical;
|
||||
reverse: false;
|
||||
expand: false;
|
||||
fixed-height: true;
|
||||
fixed-columns: true;
|
||||
cursor: "default";
|
||||
background-color: transparent;
|
||||
text-color: @main-fg;
|
||||
}
|
||||
dummy {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
|
||||
// Elements //
|
||||
element {
|
||||
enabled: true;
|
||||
spacing: 0.8em;
|
||||
padding: 0.4em 0.4em 0.4em 1.5em;
|
||||
border-radius: 20px;
|
||||
cursor: pointer;
|
||||
background-color: transparent;
|
||||
text-color: @main-fg;
|
||||
}
|
||||
element selected.normal {
|
||||
background-color: @select-bg;
|
||||
text-color: @select-fg;
|
||||
}
|
||||
element-icon {
|
||||
size: 2.8em;
|
||||
cursor: inherit;
|
||||
background-color: transparent;
|
||||
text-color: inherit;
|
||||
}
|
||||
element-text {
|
||||
vertical-align: 0.5;
|
||||
horizontal-align: 0.0;
|
||||
cursor: inherit;
|
||||
background-color: transparent;
|
||||
text-color: inherit;
|
||||
}
|
||||
|
||||
|
||||
// Error message //
|
||||
error-message {
|
||||
text-color: @main-fg;
|
||||
background-color: @main-bg;
|
||||
text-transform: capitalize;
|
||||
children: [ "textbox" ];
|
||||
}
|
||||
textbox {
|
||||
text-color: inherit;
|
||||
background-color: inherit;
|
||||
vertical-align: 0.5;
|
||||
horizontal-align: 0.5;
|
||||
}
|
||||
Reference in New Issue
Block a user