mirror of
https://github.com/zoriya/noctalia-shell.git
synced 2025-12-06 06:36:15 +00:00
Compare commits
36 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
899595ec5c | ||
|
|
dbf1020636 | ||
|
|
7def695c0e | ||
|
|
b51a87a981 | ||
|
|
3da2682111 | ||
|
|
758f2f2e55 | ||
|
|
26a27c3393 | ||
|
|
9d9bfb54e1 | ||
|
|
ab5b1e4d82 | ||
|
|
8cb9f04a22 | ||
|
|
22bc5a3bff | ||
|
|
f5982f41a2 | ||
|
|
9a80d51b10 | ||
|
|
fa838ecdb1 | ||
|
|
c0d6780c3d | ||
|
|
8935f9a0f9 | ||
|
|
b8b97c46a0 | ||
|
|
f2bbf70f93 | ||
|
|
ecf468f78f | ||
|
|
0b35fc1d2d | ||
|
|
94c5d73a61 | ||
|
|
f399a6d9f5 | ||
|
|
44fd859aec | ||
|
|
53d0c3943d | ||
|
|
d80f923802 | ||
|
|
1b861d7b7b | ||
|
|
65933208ec | ||
|
|
5df218a789 | ||
|
|
2f7a834b55 | ||
|
|
eca301553e | ||
|
|
91efa38101 | ||
|
|
acfe94f736 | ||
|
|
97bfcbb9e8 | ||
|
|
9e47d91be2 | ||
|
|
b9ae772987 | ||
|
|
4265290a0f |
@@ -4,7 +4,7 @@
|
||||
"mOnPrimary": "#11111b",
|
||||
"mSecondary": "#fab387",
|
||||
"mOnSecondary": "#11111b",
|
||||
"mTertiary": "#a6e3a1",
|
||||
"mTertiary": "#94e2d5",
|
||||
"mOnTertiary": "#11111b",
|
||||
"mError": "#f38ba8",
|
||||
"mOnError": "#11111b",
|
||||
@@ -16,19 +16,19 @@
|
||||
"mShadow": "#11111b"
|
||||
},
|
||||
"light": {
|
||||
"mPrimary": "#9349ef",
|
||||
"mPrimary": "#8839ef",
|
||||
"mOnPrimary": "#eff1f5",
|
||||
"mSecondary": "#f67525",
|
||||
"mSecondary": "#fe640b",
|
||||
"mOnSecondary": "#eff1f5",
|
||||
"mTertiary": "#40b635",
|
||||
"mTertiary": "#40a02b",
|
||||
"mOnTertiary": "#eff1f5",
|
||||
"mError": "#f38ba8",
|
||||
"mOnError": "#11111b",
|
||||
"mError": "#d20f39",
|
||||
"mOnError": "#dce0e8",
|
||||
"mSurface": "#eff1f5",
|
||||
"mOnSurface": "#4c4f69",
|
||||
"mSurfaceVariant": "#ccd0da",
|
||||
"mOnSurfaceVariant": "#6c6f85",
|
||||
"mOutline": "#aeb5c4",
|
||||
"mOutline": "#a5adcb",
|
||||
"mShadow": "#dce0e8"
|
||||
}
|
||||
}
|
||||
|
||||
34
Assets/ColorScheme/Everforest.json
Normal file
34
Assets/ColorScheme/Everforest.json
Normal file
@@ -0,0 +1,34 @@
|
||||
{
|
||||
"dark": {
|
||||
"mPrimary": "#D3C6AA",
|
||||
"mOnPrimary": "#232A2E",
|
||||
"mSecondary": "#D3C6AA",
|
||||
"mOnSecondary": "#232A2E",
|
||||
"mTertiary": "#9DA9A0",
|
||||
"mOnTertiary": "#232A2E",
|
||||
"mError": "#E67E80",
|
||||
"mOnError": "#232A2E",
|
||||
"mSurface": "#232A2E",
|
||||
"mOnSurface": "#859289",
|
||||
"mSurfaceVariant": "#2D353B",
|
||||
"mOnSurfaceVariant": "#D3C6AA",
|
||||
"mOutline": "#D3C6AA",
|
||||
"mShadow": "#475258"
|
||||
},
|
||||
"light": {
|
||||
"mPrimary": "#434F55",
|
||||
"mOnPrimary": "#D3C6AA",
|
||||
"mSecondary": "#232a2e",
|
||||
"mOnSecondary": "#D3C6AA",
|
||||
"mTertiary": "#333c43",
|
||||
"mOnTertiary": "#9DA9A0",
|
||||
"mError": "#E66868",
|
||||
"mOnError": "#9DA9A0",
|
||||
"mSurface": "#BEC5B2",
|
||||
"mOnSurface": "#333C43",
|
||||
"mSurfaceVariant": "#9DA9A0",
|
||||
"mOnSurfaceVariant": "#232A2E",
|
||||
"mOutline": "#232A2E",
|
||||
"mShadow": "#ECF5ED"
|
||||
}
|
||||
}
|
||||
@@ -1,34 +1,34 @@
|
||||
{
|
||||
"dark": {
|
||||
"mPrimary": "#ff9e64",
|
||||
"mOnPrimary": "#1a1b26",
|
||||
"mSecondary": "#e0af68",
|
||||
"mOnSecondary": "#1a1b26",
|
||||
"mTertiary": "#7aa2f7",
|
||||
"mOnTertiary": "#1a1b26",
|
||||
"mPrimary": "#7aa2f7",
|
||||
"mOnPrimary": "#16161e",
|
||||
"mSecondary": "#bb9af7",
|
||||
"mOnSecondary": "#16161e",
|
||||
"mTertiary": "#9ece6a",
|
||||
"mOnTertiary": "#16161e",
|
||||
"mError": "#f7768e",
|
||||
"mOnError": "#1a1b26",
|
||||
"mOnError": "#16161e",
|
||||
"mSurface": "#1a1b26",
|
||||
"mOnSurface": "#a9b1d6",
|
||||
"mSurfaceVariant": "#292e42",
|
||||
"mOnSurfaceVariant": "#787c99",
|
||||
"mOutline": "#3d4462",
|
||||
"mShadow": "#1a1b26"
|
||||
"mOnSurface": "#c0caf5",
|
||||
"mSurfaceVariant": "#24283b",
|
||||
"mOnSurfaceVariant": "#9aa5ce",
|
||||
"mOutline": "#565f89",
|
||||
"mShadow": "#15161e"
|
||||
},
|
||||
"light": {
|
||||
"mPrimary": "#fd5d00",
|
||||
"mOnPrimary": "#e6e7ed",
|
||||
"mSecondary": "#bb8027",
|
||||
"mOnSecondary": "#e6e7ed",
|
||||
"mTertiary": "#4a80f4",
|
||||
"mOnTertiary": "#e6e7ed",
|
||||
"mError": "#965027",
|
||||
"mOnError": "#e6e7ed",
|
||||
"mSurface": "#e6e7ed",
|
||||
"mOnSurface": "#343b58",
|
||||
"mSurfaceVariant": "#d5d6db",
|
||||
"mOnSurfaceVariant": "#40434f",
|
||||
"mOutline": "#babbc3",
|
||||
"mShadow": "#c0caf5"
|
||||
"mPrimary": "#2e7de9",
|
||||
"mOnPrimary": "#e1e2e7",
|
||||
"mSecondary": "#9854f1",
|
||||
"mOnSecondary": "#e1e2e7",
|
||||
"mTertiary": "#587539",
|
||||
"mOnTertiary": "#e1e2e7",
|
||||
"mError": "#f52a65",
|
||||
"mOnError": "#e1e2e7",
|
||||
"mSurface": "#e1e2e7",
|
||||
"mOnSurface": "#3760bf",
|
||||
"mSurfaceVariant": "#d0d5e3",
|
||||
"mOnSurfaceVariant": "#6172b0",
|
||||
"mOutline": "#b4b5b9",
|
||||
"mShadow": "#a8aecb"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,6 +70,12 @@ Singleton {
|
||||
lines.push('input_path = "' + Quickshell.shellDir + '/Assets/Matugen/templates/vesktop.css"')
|
||||
lines.push('output_path = "~/.config/vesktop/themes/noctalia.theme.css"')
|
||||
}
|
||||
if (Settings.data.matugen.pywalfox) {
|
||||
lines.push("\n[templates.pywalfox]")
|
||||
lines.push('input_path = "' + Quickshell.shellDir + '/Assets/Matugen/templates/pywalfox.json"')
|
||||
lines.push('output_path = "~/.cache/wal/colors.json"')
|
||||
lines.push('post_hook = "pywalfox update"')
|
||||
}
|
||||
|
||||
return lines.join("\n") + "\n"
|
||||
}
|
||||
|
||||
22
Assets/Matugen/templates/pywalfox.json
Normal file
22
Assets/Matugen/templates/pywalfox.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"wallpaper": "{{image}}",
|
||||
"alpha": "100",
|
||||
"colors": {
|
||||
"color0": "{{colors.background.default.hex}}",
|
||||
"color1": "",
|
||||
"color2": "",
|
||||
"color3": "",
|
||||
"color4": "",
|
||||
"color5": "",
|
||||
"color6": "",
|
||||
"color7": "",
|
||||
"color8": "",
|
||||
"color9": "",
|
||||
"color10": "{{colors.primary.default.hex}}",
|
||||
"color11": "",
|
||||
"color12": "",
|
||||
"color13": "{{colors.surface_bright.default.hex}}",
|
||||
"color14": "",
|
||||
"color15": "{{colors.on_surface.default.hex}}"
|
||||
}
|
||||
}
|
||||
@@ -1,572 +1,113 @@
|
||||
/*
|
||||
* Vesktop Theme
|
||||
* Generated with Matugen
|
||||
* Base was taken from https://github.com/catppuccin/discord <3
|
||||
/**
|
||||
* @name noctalia
|
||||
* @description Original theme: midnight | A dark, rounded discord theme.
|
||||
* @author refact0r
|
||||
* @version 1.6.2
|
||||
* @invite nz87hXyvcy
|
||||
* @website https://github.com/refact0r/midnight-discord
|
||||
* @source https://github.com/refact0r/midnight-discord/blob/master/midnight.theme.css
|
||||
* @authorId 508863359777505290
|
||||
* @authorLink https://www.refact0r.dev
|
||||
*/
|
||||
|
||||
/* IMPORTANT: make sure to enable dark mode in discord settings for the theme to apply properly!!! */
|
||||
|
||||
/* Dark Theme */
|
||||
.visual-refresh.theme-dark,
|
||||
.visual-refresh .theme-dark {
|
||||
/* Brand Colors */
|
||||
--brand-experiment: {{colors.primary.default.hex}};
|
||||
--bg-brand: {{colors.primary.default.hex}};
|
||||
--brand-500: {{colors.primary.default.hex}} !important;
|
||||
--text-link: {{colors.primary.default.hex}} !important;
|
||||
--text-brand: {{colors.primary.default.hex}};
|
||||
--control-brand-foreground: {{colors.primary.default.hex}};
|
||||
--control-brand-foreground-new: {{colors.primary.default.hex}};
|
||||
--mention-foreground: {{colors.primary.default.hex}};
|
||||
--mention-background: {{colors.primary.default.hex}}20;
|
||||
--focus-primary: {{colors.primary.default.hex}};
|
||||
--logo-primary: {{colors.on_surface.default.hex}};
|
||||
--badge-brand-bg: {{colors.primary.default.hex}};
|
||||
--badge-brand-text: {{colors.on_primary.default.hex}};
|
||||
@import url('https://refact0r.github.io/midnight-discord/build/midnight.css');
|
||||
|
||||
/* Text Colors */
|
||||
--header-primary: {{colors.on_surface.default.hex}} !important;
|
||||
--header-secondary: {{colors.on_surface_variant.default.hex}} !important;
|
||||
--text-normal: {{colors.on_surface.default.hex}} !important;
|
||||
--text-default: {{colors.on_surface.default.hex}};
|
||||
--text-muted: {{colors.on_surface_variant.default.hex}} !important;
|
||||
--text-primary: {{colors.on_surface.default.hex}};
|
||||
--text-secondary: {{colors.on_surface_variant.default.hex}};
|
||||
--text-tertiary: {{colors.on_surface_variant.default.hex}} !important;
|
||||
--interactive-normal: {{colors.on_surface.default.hex}} !important;
|
||||
--interactive-muted: {{colors.on_surface_variant.default.hex}};
|
||||
--interactive-hover: {{colors.on_surface.default.hex}};
|
||||
--interactive-active: {{colors.on_surface.default.hex}};
|
||||
/* customize things here */
|
||||
:root {
|
||||
/* font, change to 'gg sans' for default discord font*/
|
||||
--font: 'figtree';
|
||||
|
||||
/* Main Background Colors - Bar color (mSurface) colors.surface.default.hex*/
|
||||
--background-primary: {{colors.surface_variant.default.hex}} !important;
|
||||
--background-floating: {{colors.surface_variant.default.hex}} !important;
|
||||
--background-surface-high: {{colors.surface_variant.default.hex}} !important;
|
||||
--modal-background: {{colors.surface_variant.default.hex}} !important;
|
||||
--app-background-frame: {{colors.surface_variant.default.hex}} !important;
|
||||
--home-background: {{colors.surface_variant.default.hex}} !important;
|
||||
--chat-background: {{colors.surface_variant.default.hex}} !important;
|
||||
--chat-background-default: {{colors.surface_variant.default.hex}} !important;
|
||||
--chat-input-container-background: {{colors.surface_container.default.hex}} !important;
|
||||
|
||||
/* Secondary Background Colors - Workspace color (mSurfaceVariant) */
|
||||
--background-secondary: {{colors.surface.default.hex}} !important;
|
||||
--background-secondary-alt: {{colors.surface.default.hex}} !important;
|
||||
--background-surface-higher: {{colors.surface.default.hex}} !important;
|
||||
--background-base-low: {{colors.surface.default.hex}} !important;
|
||||
--background-base-lower: {{colors.surface.default.hex}} !important;
|
||||
--channeltextarea-background: {{colors.surface_container.default.hex}} !important;
|
||||
--modal-footer-background: {{colors.surface.default.hex}} !important;
|
||||
|
||||
/* New Messages Banner */
|
||||
--background-mentioned: {{colors.primary.default.hex}}15 !important;
|
||||
--background-mentioned-hover: {{colors.primary.default.hex}}20 !important;
|
||||
--text-mentioned: {{colors.on_surface.default.hex}} !important;
|
||||
--text-mentioned-hover: {{colors.on_surface.default.hex}} !important;
|
||||
--text-mentioned-link: {{colors.primary.default.hex}} !important;
|
||||
|
||||
/* Additional Discord-specific variables for new messages banner */
|
||||
--background-message-automod: {{colors.primary.default.hex}}15 !important;
|
||||
--background-message-automod-hover: {{colors.primary.default.hex}}20 !important;
|
||||
--background-message-highlight: {{colors.primary.default.hex}}15 !important;
|
||||
--background-message-highlight-hover: {{colors.primary.default.hex}}20 !important;
|
||||
|
||||
/* Discord unread messages banner specific variables */
|
||||
--background-mentioned: {{colors.primary.default.hex}}15 !important;
|
||||
--background-mentioned-hover: {{colors.primary.default.hex}}20 !important;
|
||||
--text-mentioned: {{colors.on_surface.default.hex}} !important;
|
||||
--text-mentioned-hover: {{colors.on_surface.default.hex}} !important;
|
||||
--text-mentioned-link: {{colors.primary.default.hex}} !important;
|
||||
|
||||
/* Additional Discord banner text variables */
|
||||
--text-normal: {{colors.on_surface.default.hex}} !important;
|
||||
--text-default: {{colors.on_surface.default.hex}} !important;
|
||||
--text-primary: {{colors.on_surface.default.hex}} !important;
|
||||
--text-secondary: {{colors.on_surface_variant.default.hex}} !important;
|
||||
--text-tertiary: {{colors.on_surface_variant.default.hex}} !important;
|
||||
--text-muted: {{colors.on_surface_variant.default.hex}} !important;
|
||||
--interactive-normal: {{colors.on_surface.default.hex}} !important;
|
||||
--interactive-muted: {{colors.on_surface_variant.default.hex}} !important;
|
||||
|
||||
/* Additional Discord banner variables */
|
||||
--background-message-automod: {{colors.primary.default.hex}}15 !important;
|
||||
--background-message-automod-hover: {{colors.primary.default.hex}}20 !important;
|
||||
--background-message-highlight: {{colors.primary.default.hex}}15 !important;
|
||||
--background-message-highlight-hover: {{colors.primary.default.hex}}20 !important;
|
||||
--background-message-hover: {{colors.surface_variant.default.hex}}50 !important;
|
||||
--background-modifier-hover: {{colors.surface_variant.default.hex}}80 !important;
|
||||
--background-modifier-selected: {{colors.primary.default.hex}}20 !important;
|
||||
--background-modifier-accent: {{colors.primary.default.hex}}30 !important;
|
||||
--background-modifier-active: {{colors.primary.default.hex}}25 !important;
|
||||
|
||||
/* Chat Input Improvements */
|
||||
--text-input-background: {{colors.surface_container.default.hex}} !important;
|
||||
--text-input-border: {{colors.outline.default.hex}} !important;
|
||||
--text-input-border-hover: {{colors.primary.default.hex}} !important;
|
||||
|
||||
/* Additional Discord-specific input variables */
|
||||
--deprecated-text-input-bg: {{colors.surface_container.default.hex}} !important;
|
||||
--deprecated-text-input-border: {{colors.outline.default.hex}} !important;
|
||||
--deprecated-text-input-border-hover: {{colors.primary.default.hex}} !important;
|
||||
--input-background: {{colors.surface_container.default.hex}} !important;
|
||||
--input-border: {{colors.outline.default.hex}} !important;
|
||||
--input-placeholder-text: {{colors.on_surface_variant.default.hex}} !important;
|
||||
|
||||
/* Elevated/Container Backgrounds */
|
||||
--background-tertiary: {{colors.surface_container.default.hex}} !important;
|
||||
--background-accent: {{colors.surface_container.default.hex}} !important;
|
||||
--background-surface-highest: {{colors.surface_container_high.default.hex}} !important;
|
||||
--background-base-lowest: {{colors.surface_container.default.hex}} !important;
|
||||
/* top left corner text */
|
||||
--corner-text: 'Midnight';
|
||||
|
||||
/* Border Colors */
|
||||
--border-faint: {{colors.outline_variant.default.hex}};
|
||||
--border-strong: {{colors.surface_container.default.hex}};
|
||||
--border-normal: {{colors.surface_container_high.default.hex}};
|
||||
--border-subtle: {{colors.surface.default.hex}} !important;
|
||||
--chat-border: {{colors.surface_container_high.default.hex}};
|
||||
/* color of status indicators and window controls */
|
||||
--online-indicator: {{colors.inverse_primary.default.hex}}; /* change to #23a55a for default green */
|
||||
--dnd-indicator: {{colors.error.default.hex}}; /* change to #f13f43 for default red */
|
||||
--idle-indicator: {{colors.tertiary_container.default.hex}}; /* change to #f0b232 for default yellow */
|
||||
--streaming-indicator: {{colors.on_primary.default.hex}}; /* change to #593695 for default purple */
|
||||
|
||||
/* Status Colors */
|
||||
--status-positive: {{colors.tertiary.default.hex}};
|
||||
--status-positive-background: {{colors.tertiary.default.hex}};
|
||||
--status-positive-text: {{colors.on_tertiary.default.hex}};
|
||||
--text-positive: {{colors.tertiary.default.hex}};
|
||||
--text-feedback-positive: {{colors.tertiary.default.hex}};
|
||||
--background-feedback-positive: {{colors.tertiary.default.hex}}20;
|
||||
--info-positive-background: {{colors.tertiary.default.hex}}20;
|
||||
--info-positive-foreground: {{colors.tertiary.default.hex}};
|
||||
--info-positive-text: {{colors.on_surface.default.hex}};
|
||||
/* accent colors */
|
||||
--accent-1: {{colors.tertiary.default.hex}}; /* links */
|
||||
--accent-2: {{colors.primary.default.hex}}; /* general unread/mention elements, some icons when active */
|
||||
--accent-3: {{colors.primary.default.hex}}; /* accent buttons */
|
||||
--accent-4: {{colors.surface_bright.default.hex}}; /* accent buttons when hovered */
|
||||
--accent-5: {{colors.primary_fixed_dim.default.hex}}; /* accent buttons when clicked */
|
||||
--mention: {{colors.surface.default.hex}}; /* mentions & mention messages */
|
||||
--mention-hover: {{colors.surface_bright.default.hex}}; /* mentions & mention messages when hovered */
|
||||
|
||||
--status-warning: {{colors.secondary.default.hex}};
|
||||
--status-warning-background: {{colors.secondary.default.hex}};
|
||||
--status-warning-text: {{colors.on_secondary.default.hex}};
|
||||
--text-warning: {{colors.secondary.default.hex}};
|
||||
--text-feedback-warning: {{colors.secondary.default.hex}};
|
||||
--background-feedback-warning: {{colors.secondary.default.hex}}20;
|
||||
--info-warning-background: {{colors.secondary.default.hex}}20;
|
||||
--info-warning-foreground: {{colors.secondary.default.hex}};
|
||||
--info-warning-text: {{colors.on_surface.default.hex}};
|
||||
/* text colors */
|
||||
--text-0: {{colors.surface.default.hex}}; /* text on colored elements */
|
||||
--text-1: {{colors.on_surface.default.hex}}; /* other normally white text */
|
||||
--text-2: {{colors.on_surface.default.hex}}; /* headings and important text */
|
||||
--text-3: {{colors.on_surface_variant.default.hex}}; /* normal text */
|
||||
--text-4: {{colors.on_surface_variant.default.hex}}; /* icon buttons and channels */
|
||||
--text-5: {{colors.outline.default.hex}}; /* muted channels/chats and timestamps */
|
||||
|
||||
--status-danger: {{colors.error.default.hex}};
|
||||
--status-danger-background: {{colors.error.default.hex}};
|
||||
--status-danger-text: {{colors.on_error.default.hex}};
|
||||
--text-danger: {{colors.error.default.hex}};
|
||||
--text-feedback-critical: {{colors.error.default.hex}};
|
||||
--background-feedback-critical: {{colors.error.default.hex}}20;
|
||||
--info-danger-background: {{colors.error.default.hex}}20;
|
||||
--info-danger-foreground: {{colors.error.default.hex}};
|
||||
--info-danger-text: {{colors.on_surface.default.hex}};
|
||||
/* background and dark colors */
|
||||
--bg-1: {{colors.primary.default.hex}}; /* dark buttons when clicked */
|
||||
--bg-2: {{colors.surface_container_high.default.hex}}; /* dark buttons */
|
||||
--bg-3: {{colors.surface_container_low.default.hex}}; /* spacing, secondary elements */
|
||||
--bg-4: {{colors.surface.default.hex}}; /* main background color */
|
||||
--hover: {{colors.surface_bright.default.hex}}; /* channels and buttons when hovered */
|
||||
--active: {{colors.surface_bright.default.hex}}; /* channels and buttons when clicked or selected */
|
||||
--message-hover: {{colors.surface_bright.default.hex}}; /* messages when hovered */
|
||||
|
||||
/* Button Colors */
|
||||
--button-secondary-background: {{colors.surface_variant.default.hex}} !important;
|
||||
--button-secondary-background-hover: {{colors.surface_container.default.hex}};
|
||||
--button-secondary-background-active: {{colors.surface_container.default.hex}};
|
||||
--button-secondary-background-disabled: {{colors.surface_variant.default.hex}};
|
||||
--button-secondary-text: {{colors.on_surface.default.hex}} !important;
|
||||
/* amount of spacing and padding */
|
||||
--spacing: 12px;
|
||||
|
||||
--button-filled-brand-text: {{colors.on_primary.default.hex}};
|
||||
--button-filled-brand-background: {{colors.primary.default.hex}};
|
||||
--button-filled-brand-background-hover: {{colors.primary.default.hex}};
|
||||
--button-filled-brand-background-active: {{colors.primary.default.hex}};
|
||||
/* animations */
|
||||
/* ALL ANIMATIONS CAN BE DISABLED WITH REDUCED MOTION IN DISCORD SETTINGS */
|
||||
--list-item-transition: 0.2s ease; /* channels/members/settings hover transition */
|
||||
--unread-bar-transition: 0.2s ease; /* unread bar moving into view transition */
|
||||
--moon-spin-transition: 0.4s ease; /* moon icon spin */
|
||||
--icon-spin-transition: 1s ease; /* round icon button spin (settings, emoji, etc.) */
|
||||
|
||||
/* Input Colors */
|
||||
--input-background: {{colors.surface_container.default.hex}};
|
||||
--input-border: {{colors.outline.default.hex}};
|
||||
--input-placeholder-text: {{colors.on_surface_variant.default.hex}};
|
||||
/* corner roundness (border-radius) */
|
||||
--roundness-xl: 22px; /* roundness of big panel outer corners */
|
||||
--roundness-l: 20px; /* popout panels */
|
||||
--roundness-m: 16px; /* smaller panels, images, embeds */
|
||||
--roundness-s: 12px; /* members, settings inputs */
|
||||
--roundness-xs: 10px; /* channels, buttons */
|
||||
--roundness-xxs: 8px; /* searchbar, small elements */
|
||||
|
||||
/* Scrollbar Colors */
|
||||
--scrollbar-thin-thumb: {{colors.primary.default.hex}};
|
||||
--scrollbar-thin-track: transparent;
|
||||
--scrollbar-auto-thumb: {{colors.primary.default.hex}};
|
||||
--scrollbar-auto-track: {{colors.surface_container_high.default.hex}};
|
||||
--scrollbar-auto-scrollbar-color-thumb: {{colors.primary.default.hex}};
|
||||
--scrollbar-auto-scrollbar-color-track: {{colors.surface_container_high.default.hex}};
|
||||
/* direct messages moon icon */
|
||||
/* change to block to show, none to hide */
|
||||
--discord-icon: none; /* discord icon */
|
||||
--moon-icon: block; /* moon icon */
|
||||
--moon-icon-url: url('https://upload.wikimedia.org/wikipedia/commons/c/c4/Font_Awesome_5_solid_moon.svg'); /* custom icon url */
|
||||
--moon-icon-size: auto;
|
||||
|
||||
/* Icon Colors */
|
||||
--icon-muted: {{colors.on_surface_variant.default.hex}};
|
||||
--icon-default: {{colors.on_surface.default.hex}};
|
||||
--icon-primary: {{colors.on_surface.default.hex}};
|
||||
--icon-secondary: {{colors.on_surface_variant.default.hex}};
|
||||
--icon-tertiary: {{colors.on_surface_variant.default.hex}} !important;
|
||||
|
||||
/* Channel Colors */
|
||||
--channels-default: {{colors.on_surface_variant.default.hex}} !important;
|
||||
--channel-icon: {{colors.on_surface_variant.default.hex}} !important;
|
||||
--channel-text-area-placeholder: {{colors.on_surface.default.hex}}80;
|
||||
|
||||
/* Selection and Hover States */
|
||||
--background-modifier-hover: {{colors.surface_variant.default.hex}}80;
|
||||
--background-modifier-selected: {{colors.primary.default.hex}}20 !important;
|
||||
--background-modifier-accent: {{colors.primary.default.hex}}30;
|
||||
--background-modifier-active: {{colors.primary.default.hex}}25 !important;
|
||||
--background-message-hover: {{colors.surface_variant.default.hex}}50 !important;
|
||||
--background-message-highlight: {{colors.primary.default.hex}}15;
|
||||
--background-message-highlight-hover: {{colors.primary.default.hex}}20;
|
||||
|
||||
/* Code Block - Use workspace background */
|
||||
--background-code: {{colors.surface_container.default.hex}};
|
||||
--textbox-markdown-syntax: {{colors.on_surface_variant.default.hex}};
|
||||
|
||||
/* Spoiler */
|
||||
--spoiler-revealed-background: {{colors.surface_container.default.hex}};
|
||||
--spoiler-hidden-background: {{colors.surface_variant.default.hex}};
|
||||
|
||||
/* White/Black Overrides */
|
||||
--white: {{colors.on_surface.default.hex}};
|
||||
--white-400: {{colors.on_surface.default.hex}};
|
||||
--white-500: {{colors.on_surface.default.hex}};
|
||||
--white-600: {{colors.on_surface_variant.default.hex}};
|
||||
--white-700: {{colors.on_surface_variant.default.hex}};
|
||||
--black-500: {{colors.surface_container_high.default.hex}};
|
||||
|
||||
/* Force styling for Discord unread messages banner */
|
||||
--unread-bar-background: {{colors.primary.default.hex}}15 !important;
|
||||
--unread-bar-text: {{colors.on_surface.default.hex}} !important;
|
||||
--unread-bar-hover: {{colors.primary.default.hex}}20 !important;
|
||||
|
||||
/* Additional Discord unread bar variables */
|
||||
--background-mentioned: {{colors.primary.default.hex}}15 !important;
|
||||
--background-mentioned-hover: {{colors.primary.default.hex}}20 !important;
|
||||
--text-mentioned: {{colors.on_surface.default.hex}} !important;
|
||||
--text-mentioned-hover: {{colors.on_surface.default.hex}} !important;
|
||||
--text-mentioned-link: {{colors.primary.default.hex}} !important;
|
||||
|
||||
/* Discord banner specific variables */
|
||||
--background-message-automod: {{colors.primary.default.hex}}15 !important;
|
||||
--background-message-automod-hover: {{colors.primary.default.hex}}20 !important;
|
||||
--background-message-highlight: {{colors.primary.default.hex}}15 !important;
|
||||
--background-message-highlight-hover: {{colors.primary.default.hex}}20 !important;
|
||||
|
||||
/* Discord unread bar specific variables */
|
||||
--background-mentioned: {{colors.primary.default.hex}}15 !important;
|
||||
--background-mentioned-hover: {{colors.primary.default.hex}}20 !important;
|
||||
--text-mentioned: {{colors.on_surface.default.hex}} !important;
|
||||
--text-mentioned-hover: {{colors.on_surface.default.hex}} !important;
|
||||
--text-mentioned-link: {{colors.primary.default.hex}} !important;
|
||||
|
||||
/* Additional Discord text variables that might affect the banner */
|
||||
--text-normal: {{colors.on_surface.default.hex}} !important;
|
||||
--text-default: {{colors.on_surface.default.hex}} !important;
|
||||
--text-primary: {{colors.on_surface.default.hex}} !important;
|
||||
--text-secondary: {{colors.on_surface_variant.default.hex}} !important;
|
||||
--text-tertiary: {{colors.on_surface_variant.default.hex}} !important;
|
||||
--text-muted: {{colors.on_surface_variant.default.hex}} !important;
|
||||
--interactive-normal: {{colors.on_surface.default.hex}} !important;
|
||||
--interactive-muted: {{colors.on_surface_variant.default.hex}} !important;
|
||||
|
||||
/* Force styling for Discord chat input */
|
||||
--chat-input-background: {{colors.surface_container.default.hex}} !important;
|
||||
--chat-input-placeholder: {{colors.on_surface_variant.default.hex}} !important;
|
||||
|
||||
/* Discord unread messages banner specific variables */
|
||||
--new-messages-bar-background: {{colors.surface_container.default.hex}} !important;
|
||||
--new-messages-bar-text: {{colors.on_surface.default.hex}} !important;
|
||||
--new-messages-bar-hover: {{colors.surface_container_high.default.hex}} !important;
|
||||
--bar-button-background: {{colors.surface_container.default.hex}} !important;
|
||||
--bar-button-text: {{colors.on_surface.default.hex}} !important;
|
||||
--bar-button-hover: {{colors.surface_container_high.default.hex}} !important;
|
||||
/* filter uncolorable elements to fit theme */
|
||||
/* (just set to none, they're too much work to configure) */
|
||||
--login-bg-filter: saturate(0.3) hue-rotate(-15deg) brightness(0.4); /* login background artwork */
|
||||
--green-to-accent-3-filter: hue-rotate(56deg) saturate(1.43); /* add friend page explore icon */
|
||||
--blurple-to-accent-3-filter: hue-rotate(304deg) saturate(0.84) brightness(1.2); /* add friend page school icon */
|
||||
}
|
||||
|
||||
.visual-refresh.theme-dark ::selection,
|
||||
.visual-refresh .theme-dark ::selection {
|
||||
background-color: {{colors.primary.default.hex}};
|
||||
/* Selected chat/friend text */
|
||||
.selected_f5eb4b,
|
||||
.selected_f6f816 .link_d8bfb3 {
|
||||
color: var(--text-0) !important;
|
||||
background: var(--accent-3) !important;
|
||||
}
|
||||
|
||||
/* Force Discord unread messages banner styling */
|
||||
.visual-refresh.theme-dark .newMessagesBar__0f481,
|
||||
.visual-refresh.theme-dark .barButtonMain__0f481,
|
||||
.visual-refresh.theme-dark .barButtonBase__0f481,
|
||||
.visual-refresh.theme-dark .span__0f481 {
|
||||
background-color: {{colors.surface_container.default.hex}} !important;
|
||||
color: {{colors.on_surface.default.hex}} !important;
|
||||
.selected_f6f816 .link_d8bfb3 * {
|
||||
color: var(--text-0) !important;
|
||||
fill: var(--text-0) !important;
|
||||
}
|
||||
|
||||
.visual-refresh.theme-dark .newMessagesBar__0f481:hover,
|
||||
.visual-refresh.theme-dark .barButtonMain__0f481:hover,
|
||||
.visual-refresh.theme-dark .barButtonBase__0f481:hover {
|
||||
background-color: {{colors.surface_container_high.default.hex}} !important;
|
||||
/* Make channel name text less visible (darker) */
|
||||
.name__2ea32 {
|
||||
color: var(--text-5) !important;
|
||||
opacity: 0.7 !important;
|
||||
}
|
||||
|
||||
/* Force Discord chat input styling */
|
||||
.visual-refresh.theme-dark .channelTextArea-rNsIhG,
|
||||
.visual-refresh.theme-dark .channelTextArea-rNsIhG *,
|
||||
.visual-refresh.theme-dark .scrollableContainer-2NUZem,
|
||||
.visual-refresh.theme-dark [data-slate-editor="true"] {
|
||||
background-color: {{colors.surface_container.default.hex}} !important;
|
||||
/* Make unread channel names brighter */
|
||||
.link__2ea32[aria-label*="unread"] .name__2ea32 {
|
||||
color: var(--text-2) !important;
|
||||
opacity: 1 !important;
|
||||
font-weight: 600 !important;
|
||||
}
|
||||
|
||||
.visual-refresh.theme-dark [data-slate-editor="true"]::placeholder,
|
||||
.visual-refresh.theme-dark .channelTextArea-rNsIhG [data-slate-editor="true"]::placeholder {
|
||||
color: {{colors.on_surface_variant.default.hex}} !important;
|
||||
}
|
||||
|
||||
/* Discord Emoji Picker Theming */
|
||||
.visual-refresh.theme-dark .contentWrapper__08434,
|
||||
.visual-refresh.theme-dark .emojiPicker_c0e32c,
|
||||
.visual-refresh.theme-dark .wrapper_c0e32c {
|
||||
background-color: {{colors.surface.default.hex}} !important;
|
||||
}
|
||||
|
||||
.visual-refresh.theme-dark .nav__08434,
|
||||
.visual-refresh.theme-dark .navList__08434 {
|
||||
background-color: {{colors.surface.default.hex}} !important;
|
||||
}
|
||||
|
||||
.visual-refresh.theme-dark .navButton__08434 {
|
||||
background-color: {{colors.surface.default.hex}} !important;
|
||||
color: {{colors.on_surface_variant.default.hex}} !important;
|
||||
}
|
||||
|
||||
.visual-refresh.theme-dark .navButtonActive__08434 {
|
||||
background-color: {{colors.surface.default.hex}} !important;
|
||||
color: {{colors.on_surface.default.hex}} !important;
|
||||
}
|
||||
|
||||
.visual-refresh.theme-dark .searchBar_c0e32c,
|
||||
.visual-refresh.theme-dark .input_a45028 {
|
||||
background-color: {{colors.surface.default.hex}} !important;
|
||||
color: {{colors.on_surface.default.hex}} !important;
|
||||
}
|
||||
|
||||
.visual-refresh.theme-dark .input_a45028::placeholder {
|
||||
color: {{colors.on_surface_variant.default.hex}} !important;
|
||||
}
|
||||
|
||||
.visual-refresh.theme-dark .header_c656ac,
|
||||
.visual-refresh.theme-dark .header__14245,
|
||||
.visual-refresh.theme-dark .wrapper__14245 {
|
||||
background-color: {{colors.surface_variant.default.hex}} !important;
|
||||
color: {{colors.on_surface.default.hex}} !important;
|
||||
}
|
||||
|
||||
.visual-refresh.theme-dark .headerLabel__14245 {
|
||||
color: {{colors.on_surface.default.hex}} !important;
|
||||
}
|
||||
|
||||
.visual-refresh.theme-dark .interactive__14245 {
|
||||
color: {{colors.on_surface.default.hex}} !important;
|
||||
}
|
||||
|
||||
.visual-refresh.theme-dark .header__14245 {
|
||||
color: {{colors.on_surface.default.hex}} !important;
|
||||
}
|
||||
|
||||
.visual-refresh.theme-dark .header__14245 * {
|
||||
color: {{colors.on_surface.default.hex}} !important;
|
||||
}
|
||||
|
||||
.visual-refresh.theme-dark .headerIcon__14245 svg,
|
||||
.visual-refresh.theme-dark .headerCollapseIcon__14245 svg {
|
||||
color: {{colors.on_surface.default.hex}} !important;
|
||||
fill: {{colors.on_surface.default.hex}} !important;
|
||||
}
|
||||
|
||||
.visual-refresh.theme-dark .emojiItem_fc7141 {
|
||||
background-color: transparent !important;
|
||||
}
|
||||
|
||||
.visual-refresh.theme-dark .emojiItem_fc7141:hover {
|
||||
background-color: {{colors.surface_container.default.hex}} !important;
|
||||
}
|
||||
|
||||
.visual-refresh.theme-dark .emojiItemSelected_fc7141 {
|
||||
background-color: {{colors.primary.default.hex}}20 !important;
|
||||
}
|
||||
|
||||
.visual-refresh.theme-dark .inspector_aeaaeb {
|
||||
background-color: {{colors.surface_container.default.hex}} !important;
|
||||
color: {{colors.on_surface.default.hex}} !important;
|
||||
}
|
||||
|
||||
.visual-refresh.theme-dark .categoryList_c0e32c {
|
||||
background-color: {{colors.surface.default.hex}} !important;
|
||||
}
|
||||
|
||||
.visual-refresh.theme-dark .categoryItem_b9ee0c {
|
||||
background-color: transparent !important;
|
||||
}
|
||||
|
||||
.visual-refresh.theme-dark .categoryItem_b9ee0c:hover {
|
||||
background-color: {{colors.surface_variant.default.hex}} !important;
|
||||
}
|
||||
|
||||
.visual-refresh.theme-dark .categoryItemDefaultCategorySelected_b9ee0c {
|
||||
background-color: {{colors.surface_variant.default.hex}} !important;
|
||||
}
|
||||
|
||||
/* Additional Discord emoji picker elements */
|
||||
.visual-refresh.theme-dark .navItem__08434 {
|
||||
background-color: {{colors.surface_variant.default.hex}} !important;
|
||||
color: {{colors.on_surface_variant.default.hex}} !important;
|
||||
}
|
||||
|
||||
.visual-refresh.theme-dark .navItem__08434:hover {
|
||||
background-color: {{colors.surface_container.default.hex}} !important;
|
||||
}
|
||||
|
||||
.visual-refresh.theme-dark .stickersNavItem__08434 {
|
||||
color: {{colors.on_surface_variant.default.hex}} !important;
|
||||
}
|
||||
|
||||
.visual-refresh.theme-dark .wrapper__14245 {
|
||||
background-color: {{colors.surface_variant.default.hex}} !important;
|
||||
}
|
||||
|
||||
.visual-refresh.theme-dark .headerLabel__14245 {
|
||||
color: {{colors.on_surface.default.hex}} !important;
|
||||
}
|
||||
|
||||
.visual-refresh.theme-dark .headerIcon__14245 svg,
|
||||
.visual-refresh.theme-dark .headerCollapseIcon__14245 svg {
|
||||
color: {{colors.on_surface_variant.default.hex}} !important;
|
||||
}
|
||||
|
||||
.visual-refresh.theme-dark .interactive__14245:hover {
|
||||
background-color: {{colors.surface_container.default.hex}} !important;
|
||||
}
|
||||
|
||||
/* Chat input styling */
|
||||
.visual-refresh.theme-dark .scrollableContainer__74017,
|
||||
.visual-refresh.theme-dark .themedBackground__74017,
|
||||
.visual-refresh.theme-dark .inner__74017,
|
||||
.visual-refresh.theme-dark .textArea__74017,
|
||||
.visual-refresh.theme-dark .slateContainer_ec4baf,
|
||||
.visual-refresh.theme-dark .markup__75297,
|
||||
.visual-refresh.theme-dark .editor__1b31f,
|
||||
.visual-refresh.theme-dark .slateTextArea_ec4baf {
|
||||
background-color: {{colors.surface_container.default.hex}} !important;
|
||||
color: {{colors.on_surface.default.hex}} !important;
|
||||
}
|
||||
|
||||
.visual-refresh.theme-dark .emptyText__1464f {
|
||||
color: {{colors.on_surface_variant.default.hex}} !important;
|
||||
}
|
||||
|
||||
.visual-refresh.theme-dark .placeholder__1b31f {
|
||||
color: {{colors.on_surface_variant.default.hex}} !important;
|
||||
}
|
||||
|
||||
/* Message content styling */
|
||||
.visual-refresh.theme-dark .messageContent_c19a55 {
|
||||
color: {{colors.on_surface.default.hex}} !important;
|
||||
background-color: {{colors.surface.default.hex}} !important;
|
||||
}
|
||||
|
||||
.visual-refresh.theme-dark .messageContent_c19a55 .markup__75297 {
|
||||
color: {{colors.on_surface.default.hex}} !important;
|
||||
background-color: {{colors.surface.default.hex}} !important;
|
||||
}
|
||||
|
||||
/* Message background styling */
|
||||
.visual-refresh.theme-dark .message__5126c,
|
||||
.visual-refresh.theme-dark .cozyMessage__5126c,
|
||||
.visual-refresh.theme-dark .wrapper_c19a55,
|
||||
.visual-refresh.theme-dark .contents_c19a55 {
|
||||
background-color: {{colors.surface.default.hex}} !important;
|
||||
}
|
||||
|
||||
/* Message hover effects */
|
||||
.visual-refresh.theme-dark .message__5126c:hover {
|
||||
background-color: {{colors.surface_variant.default.hex}} !important;
|
||||
}
|
||||
|
||||
.visual-refresh.theme-dark .message__5126c:hover * {
|
||||
color: {{colors.on_surface.default.hex}} !important;
|
||||
}
|
||||
|
||||
/* Remove Discord's native quote/reply bar */
|
||||
.visual-refresh.theme-dark .message__5126c::before {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.visual-refresh.theme-dark .message__5126c.hasReply_c19a55::before {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/* Channel styling - darker text for read channels */
|
||||
.visual-refresh.theme-dark .link__2ea32 .name__2ea32 {
|
||||
color: {{colors.outline.default.hex}} !important;
|
||||
}
|
||||
|
||||
/* Unread channels keep normal color */
|
||||
.visual-refresh.theme-dark .link__2ea32[aria-label*="unread"] .name__2ea32 {
|
||||
color: {{colors.on_surface.default.hex}} !important;
|
||||
}
|
||||
|
||||
/* Search input styling */
|
||||
.visual-refresh.theme-dark .inner_a45028 {
|
||||
background-color: {{colors.surface_variant.default.hex}} !important;
|
||||
}
|
||||
|
||||
.visual-refresh.theme-dark .input_a45028 {
|
||||
background-color: transparent !important;
|
||||
}
|
||||
|
||||
.visual-refresh.theme-dark .input_a45028::placeholder {
|
||||
color: {{colors.on_surface_variant.default.hex}} !important;
|
||||
}
|
||||
|
||||
/* Chat input placeholder styling */
|
||||
.visual-refresh.theme-dark .emptyText__1464f {
|
||||
color: {{colors.on_surface_variant.default.hex}} !important;
|
||||
}
|
||||
|
||||
.visual-refresh.theme-dark .slateTextArea_ec4baf > div:first-child .emptyText__1464f::before {
|
||||
content: "send a message" !important;
|
||||
color: {{colors.on_surface_variant.default.hex}} !important;
|
||||
}
|
||||
|
||||
/* Hide placeholder when input is focused */
|
||||
.visual-refresh.theme-dark .slateTextArea_ec4baf:focus .emptyText__1464f::before,
|
||||
.visual-refresh.theme-dark .markup__75297:focus .emptyText__1464f::before {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.visual-refresh.theme-dark .message__5126c:hover .messageContent_c19a55,
|
||||
.visual-refresh.theme-dark .message__5126c:hover .markup__75297,
|
||||
.visual-refresh.theme-dark .message__5126c:hover .header_c19a55,
|
||||
.visual-refresh.theme-dark .message__5126c:hover .headerText_c19a55,
|
||||
.visual-refresh.theme-dark .message__5126c:hover .username_c19a55,
|
||||
.visual-refresh.theme-dark .message__5126c:hover .timestamp_c19a55 {
|
||||
background-color: {{colors.surface_variant.default.hex}} !important;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.visual-refresh.theme-dark .categoryIcon_b9ee0c svg {
|
||||
color: {{colors.on_surface_variant.default.hex}} !important;
|
||||
}
|
||||
|
||||
.visual-refresh.theme-dark .unicodeShortcut_b9ee0c {
|
||||
background-color: {{colors.surface_container.default.hex}} !important;
|
||||
color: {{colors.on_surface.default.hex}} !important;
|
||||
}
|
||||
|
||||
.visual-refresh.theme-dark .unicodeShortcut_b9ee0c:hover {
|
||||
background-color: {{colors.surface_container_high.default.hex}} !important;
|
||||
}
|
||||
|
||||
.visual-refresh.theme-dark .unicodeShortcut_b9ee0c svg {
|
||||
color: {{colors.on_surface.default.hex}} !important;
|
||||
}
|
||||
|
||||
/* Number badge styling */
|
||||
.visual-refresh.theme-dark .numberBadge__2b1f5 {
|
||||
color: {{colors.surface.default.hex}} !important;
|
||||
background-color: {{colors.primary.default.hex}} !important;
|
||||
}
|
||||
|
||||
/* New badge styling */
|
||||
.visual-refresh.theme-dark .newBadge__4ed1a {
|
||||
color: {{colors.surface.default.hex}} !important;
|
||||
background-color: {{colors.primary.default.hex}} !important;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -322,6 +322,7 @@ Singleton {
|
||||
property string avatarImage: defaultAvatar
|
||||
property bool dimDesktop: false
|
||||
property bool showScreenCorners: false
|
||||
property bool forceBlackScreenCorners: false
|
||||
property real radiusRatio: 1.0
|
||||
property real screenRadiusRatio: 1.0
|
||||
// Animation speed multiplier (0.1x - 2.0x)
|
||||
@@ -449,6 +450,7 @@ Singleton {
|
||||
property bool foot: false
|
||||
property bool fuzzel: false
|
||||
property bool vesktop: false
|
||||
property bool pywalfox: false
|
||||
property bool enableUserTemplates: false
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import qs.Services
|
||||
import qs.Widgets
|
||||
|
||||
Loader {
|
||||
active: Settings.data.general.showScreenCorners && !Settings.data.bar.floating
|
||||
active: Settings.data.general.showScreenCorners
|
||||
|
||||
sourceComponent: Variants {
|
||||
model: Quickshell.screens
|
||||
@@ -19,7 +19,7 @@ Loader {
|
||||
property real scaling: ScalingService.getScreenScale(screen)
|
||||
screen: modelData
|
||||
|
||||
property color cornerColor: Qt.alpha(Color.mSurface, Settings.data.bar.backgroundOpacity)
|
||||
property color cornerColor: Settings.data.general.forceBlackScreenCorners ? Qt.rgba(0, 0, 0, 1) : Qt.alpha(Color.mSurface, Settings.data.bar.backgroundOpacity)
|
||||
property real cornerRadius: Style.screenRadius * scaling
|
||||
property real cornerSize: Style.screenRadius * scaling
|
||||
|
||||
@@ -46,10 +46,12 @@ Loader {
|
||||
}
|
||||
|
||||
margins {
|
||||
top: ((modelData && Settings.data.bar.monitors.includes(modelData.name)) || (Settings.data.bar.monitors.length === 0)) && Settings.data.bar.position === "top" && Settings.data.bar.backgroundOpacity > 0 ? Math.round(Style.barHeight * scaling) : 0
|
||||
bottom: ((modelData && Settings.data.bar.monitors.includes(modelData.name)) || (Settings.data.bar.monitors.length === 0)) && Settings.data.bar.position === "bottom" && Settings.data.bar.backgroundOpacity > 0 ? Math.round(Style.barHeight * scaling) : 0
|
||||
left: ((modelData && Settings.data.bar.monitors.includes(modelData.name)) || (Settings.data.bar.monitors.length === 0)) && Settings.data.bar.position === "left" && Settings.data.bar.backgroundOpacity > 0 ? Math.round(Style.barHeight * scaling) : 0
|
||||
right: ((modelData && Settings.data.bar.monitors.includes(modelData.name)) || (Settings.data.bar.monitors.length === 0)) && Settings.data.bar.position === "right" && Settings.data.bar.backgroundOpacity > 0 ? Math.round(Style.barHeight * scaling) : 0
|
||||
// When bar is floating, corners should be at screen edges (no margins)
|
||||
// When bar is not floating, respect bar margins as before
|
||||
top: !Settings.data.bar.floating && ((modelData && Settings.data.bar.monitors.includes(modelData.name)) || (Settings.data.bar.monitors.length === 0)) && Settings.data.bar.position === "top" && Settings.data.bar.backgroundOpacity > 0 ? Math.round(Style.barHeight * scaling) : 0
|
||||
bottom: !Settings.data.bar.floating && ((modelData && Settings.data.bar.monitors.includes(modelData.name)) || (Settings.data.bar.monitors.length === 0)) && Settings.data.bar.position === "bottom" && Settings.data.bar.backgroundOpacity > 0 ? Math.round(Style.barHeight * scaling) : 0
|
||||
left: !Settings.data.bar.floating && ((modelData && Settings.data.bar.monitors.includes(modelData.name)) || (Settings.data.bar.monitors.length === 0)) && Settings.data.bar.position === "left" && Settings.data.bar.backgroundOpacity > 0 ? Math.round(Style.barHeight * scaling) : 0
|
||||
right: !Settings.data.bar.floating && ((modelData && Settings.data.bar.monitors.includes(modelData.name)) || (Settings.data.bar.monitors.length === 0)) && Settings.data.bar.position === "right" && Settings.data.bar.backgroundOpacity > 0 ? Math.round(Style.barHeight * scaling) : 0
|
||||
}
|
||||
|
||||
mask: Region {}
|
||||
|
||||
@@ -91,7 +91,7 @@ Variants {
|
||||
anchors.fill: parent
|
||||
|
||||
// Top section (left widgets)
|
||||
Column {
|
||||
ColumnLayout {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: Style.marginM * root.scaling
|
||||
@@ -109,13 +109,13 @@ Variants {
|
||||
"sectionWidgetIndex": index,
|
||||
"sectionWidgetsCount": Settings.data.bar.widgets.left.length
|
||||
}
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Center section (center widgets)
|
||||
Column {
|
||||
ColumnLayout {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: Style.marginS * root.scaling
|
||||
@@ -132,13 +132,13 @@ Variants {
|
||||
"sectionWidgetIndex": index,
|
||||
"sectionWidgetsCount": Settings.data.bar.widgets.center.length
|
||||
}
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Bottom section (right widgets)
|
||||
Column {
|
||||
ColumnLayout {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.bottomMargin: Style.marginM * root.scaling
|
||||
@@ -156,7 +156,7 @@ Variants {
|
||||
"sectionWidgetIndex": index,
|
||||
"sectionWidgetsCount": Settings.data.bar.widgets.right.length
|
||||
}
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -189,6 +189,7 @@ Variants {
|
||||
"sectionWidgetIndex": index,
|
||||
"sectionWidgetsCount": Settings.data.bar.widgets.left.length
|
||||
}
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -213,6 +214,7 @@ Variants {
|
||||
"sectionWidgetIndex": index,
|
||||
"sectionWidgetsCount": Settings.data.bar.widgets.center.length
|
||||
}
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -238,6 +240,7 @@ Variants {
|
||||
"sectionWidgetIndex": index,
|
||||
"sectionWidgetsCount": Settings.data.bar.widgets.right.length
|
||||
}
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -178,7 +178,7 @@ PopupWindow {
|
||||
font.pointSize: Style.fontSizeS * scaling
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
visible: modelData?.hasChildren ?? false
|
||||
color: Color.mOnSurface
|
||||
color: (mouseArea.containsMouse ? Color.mOnTertiary : Color.mOnSurface)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -220,9 +220,32 @@ PopupWindow {
|
||||
const submenuWidth = menuWidth * scaling // Assuming a similar width as the parent
|
||||
const overlap = 4 * scaling // A small overlap to bridge the mouse path
|
||||
|
||||
// Check if there's enough space on the right
|
||||
// Determine submenu opening direction based on bar position and available space
|
||||
let openLeft = false
|
||||
|
||||
// Check bar position first
|
||||
const barPosition = Settings.data.bar.position
|
||||
const globalPos = entry.mapToGlobal(0, 0)
|
||||
const openLeft = (globalPos.x + entry.width + submenuWidth > (screen ? screen.width : Screen.width))
|
||||
|
||||
if (barPosition === "right") {
|
||||
// Bar is on the right, prefer opening submenus to the left
|
||||
openLeft = true
|
||||
} else if (barPosition === "left") {
|
||||
// Bar is on the left, prefer opening submenus to the right
|
||||
openLeft = false
|
||||
} else {
|
||||
// Bar is horizontal (top/bottom) or undefined, use space-based logic
|
||||
openLeft = (globalPos.x + entry.width + submenuWidth > (screen ? screen.width : Screen.width))
|
||||
|
||||
// Secondary check: ensure we don't open off-screen
|
||||
if (openLeft && globalPos.x - submenuWidth < 0) {
|
||||
// Would open off the left edge, force right opening
|
||||
openLeft = false
|
||||
} else if (!openLeft && globalPos.x + entry.width + submenuWidth > (screen ? screen.width : Screen.width)) {
|
||||
// Would open off the right edge, force left opening
|
||||
openLeft = true
|
||||
}
|
||||
}
|
||||
|
||||
// Position with overlap
|
||||
const anchorX = openLeft ? -submenuWidth + overlap : entry.width - overlap
|
||||
|
||||
@@ -90,7 +90,7 @@ Item {
|
||||
var monitor = getMonitor()
|
||||
if (!monitor)
|
||||
return ""
|
||||
return "Brightness: " + Math.round(monitor.brightness * 100) + "%\nMethod: " + monitor.method + "\nLeft click for advanced settings.\nScroll up/down to change brightness."
|
||||
return "Brightness: " + Math.round(monitor.brightness * 100) + "%\nRight click for settings.\nScroll to modify brightness."
|
||||
}
|
||||
|
||||
onWheel: function (angle) {
|
||||
@@ -104,6 +104,12 @@ Item {
|
||||
}
|
||||
}
|
||||
|
||||
onClicked: {
|
||||
var settingsPanel = PanelService.getPanel("settingsPanel")
|
||||
settingsPanel.requestedTab = SettingsPanel.Tab.Display
|
||||
settingsPanel.open()
|
||||
}
|
||||
|
||||
onRightClicked: {
|
||||
var settingsPanel = PanelService.getPanel("settingsPanel")
|
||||
settingsPanel.requestedTab = SettingsPanel.Tab.Display
|
||||
|
||||
@@ -36,10 +36,10 @@ Rectangle {
|
||||
readonly property string displayFormat: widgetSettings.displayFormat !== undefined ? widgetSettings.displayFormat : widgetMetadata.displayFormat
|
||||
|
||||
// Use compact mode for vertical bars
|
||||
readonly property bool useCompactMode: barPosition === "left" || barPosition === "right"
|
||||
readonly property bool verticalMode: barPosition === "left" || barPosition === "right"
|
||||
|
||||
implicitWidth: useCompactMode ? Math.round(Style.capsuleHeight * scaling) : Math.round(layout.implicitWidth + Style.marginM * 2 * scaling)
|
||||
implicitHeight: useCompactMode ? Math.round(Style.capsuleHeight * 2.5 * scaling) : Math.round(Style.capsuleHeight * scaling)
|
||||
implicitWidth: verticalMode ? Math.round(Style.capsuleHeight * scaling) : Math.round(layout.implicitWidth + Style.marginM * 2 * scaling)
|
||||
implicitHeight: verticalMode ? Math.round(Style.capsuleHeight * 2.5 * scaling) : Math.round(Style.baseWidgetSize * 0.8 * scaling) // Match NPill
|
||||
|
||||
radius: Math.round(Style.radiusS * scaling)
|
||||
color: Color.mSurfaceVariant
|
||||
@@ -52,18 +52,18 @@ Rectangle {
|
||||
ColumnLayout {
|
||||
id: layout
|
||||
anchors.centerIn: parent
|
||||
spacing: useCompactMode ? -2 * scaling : -3 * scaling
|
||||
spacing: verticalMode ? -2 * scaling : -3 * scaling
|
||||
|
||||
// Compact mode for vertical bars - Time section (HH, MM)
|
||||
Repeater {
|
||||
model: useCompactMode ? 2 : 1
|
||||
model: verticalMode ? 2 : 1
|
||||
NText {
|
||||
readonly property bool showSeconds: (displayFormat === "time-seconds")
|
||||
readonly property bool inlineDate: (displayFormat === "time-date")
|
||||
readonly property var now: Time.date
|
||||
|
||||
text: {
|
||||
if (useCompactMode) {
|
||||
if (verticalMode) {
|
||||
// Compact mode: time section (first 2 lines)
|
||||
switch (index) {
|
||||
case 0:
|
||||
@@ -126,7 +126,7 @@ Rectangle {
|
||||
}
|
||||
|
||||
font.family: Settings.data.ui.fontFixed
|
||||
font.pointSize: useCompactMode ? Style.fontSizeXXS * scaling : Style.fontSizeXS * scaling
|
||||
font.pointSize: verticalMode ? Style.fontSizeXXS * scaling : Style.fontSizeXS * scaling
|
||||
font.weight: Style.fontWeightBold
|
||||
color: Color.mPrimary
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
@@ -135,7 +135,7 @@ Rectangle {
|
||||
|
||||
// Separator line for compact mode (between time and date)
|
||||
Rectangle {
|
||||
visible: useCompactMode
|
||||
visible: verticalMode
|
||||
Layout.preferredWidth: 20 * scaling
|
||||
Layout.preferredHeight: 2 * scaling
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
@@ -148,12 +148,12 @@ Rectangle {
|
||||
|
||||
// Compact mode for vertical bars - Date section (DD, MM)
|
||||
Repeater {
|
||||
model: useCompactMode ? 2 : 0
|
||||
model: verticalMode ? 2 : 0
|
||||
NText {
|
||||
readonly property var now: Time.date
|
||||
|
||||
text: {
|
||||
if (useCompactMode) {
|
||||
if (verticalMode) {
|
||||
// Compact mode: date section (last 2 lines)
|
||||
switch (index) {
|
||||
case 0:
|
||||
@@ -178,7 +178,7 @@ Rectangle {
|
||||
|
||||
// Second line for normal mode (date)
|
||||
NText {
|
||||
visible: !useCompactMode && (displayFormat === "time-date-short")
|
||||
visible: !verticalMode && (displayFormat === "time-date-short")
|
||||
text: {
|
||||
const now = Time.date
|
||||
const day = now.getDate().toString().padStart(2, '0')
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
import qs.Commons
|
||||
import qs.Services
|
||||
import qs.Widgets
|
||||
import qs.Modules.SettingsPanel
|
||||
|
||||
NIconButton {
|
||||
Item {
|
||||
id: root
|
||||
|
||||
// Widget properties passed from Bar.qml
|
||||
@@ -35,33 +36,80 @@ NIconButton {
|
||||
readonly property string leftClickExec: widgetSettings.leftClickExec || widgetMetadata.leftClickExec
|
||||
readonly property string rightClickExec: widgetSettings.rightClickExec || widgetMetadata.rightClickExec
|
||||
readonly property string middleClickExec: widgetSettings.middleClickExec || widgetMetadata.middleClickExec
|
||||
readonly property string textCommand: widgetSettings.textCommand !== undefined ? widgetSettings.textCommand : (widgetMetadata.textCommand || "")
|
||||
readonly property int textIntervalMs: widgetSettings.textIntervalMs !== undefined ? widgetSettings.textIntervalMs : (widgetMetadata.textIntervalMs || 3000)
|
||||
readonly property bool hasExec: (leftClickExec || rightClickExec || middleClickExec)
|
||||
|
||||
enabled: hasExec
|
||||
allowClickWhenDisabled: true // we want to be able to open config with left click when its not setup properly
|
||||
colorBorder: Color.transparent
|
||||
colorBorderHover: Color.transparent
|
||||
sizeRatio: 0.8
|
||||
icon: customIcon
|
||||
tooltipText: {
|
||||
if (!hasExec) {
|
||||
return "Custom Button - Configure in settings"
|
||||
} else {
|
||||
var lines = []
|
||||
if (leftClickExec !== "") {
|
||||
lines.push(`Left click: <i>${leftClickExec}</i>.`)
|
||||
implicitWidth: pill.width
|
||||
implicitHeight: pill.height
|
||||
|
||||
NPill {
|
||||
id: pill
|
||||
|
||||
rightOpen: BarWidgetRegistry.getNPillDirection(root)
|
||||
icon: customIcon
|
||||
text: _dynamicText
|
||||
autoHide: false
|
||||
forceOpen: _dynamicText !== ""
|
||||
forceClose: false
|
||||
disableOpen: true
|
||||
tooltipText: {
|
||||
if (!hasExec) {
|
||||
return "Custom Button - Configure in settings"
|
||||
} else {
|
||||
var lines = []
|
||||
if (leftClickExec !== "") {
|
||||
lines.push(`Left click: ${leftClickExec}.`)
|
||||
}
|
||||
if (rightClickExec !== "") {
|
||||
lines.push(`Right click: ${rightClickExec}.`)
|
||||
}
|
||||
if (middleClickExec !== "") {
|
||||
lines.push(`Middle click: ${middleClickExec}.`)
|
||||
}
|
||||
return lines.join("\n")
|
||||
}
|
||||
if (rightClickExec !== "") {
|
||||
lines.push(`Right click: <i>${rightClickExec}</i>.`)
|
||||
}
|
||||
if (middleClickExec !== "") {
|
||||
lines.push(`Middle click: <i>${middleClickExec}</i>.`)
|
||||
}
|
||||
return lines.join("<br/>")
|
||||
}
|
||||
|
||||
onClicked: root.onClicked()
|
||||
onRightClicked: root.onRightClicked()
|
||||
onMiddleClicked: root.onMiddleClicked()
|
||||
}
|
||||
|
||||
// Internal state for dynamic text
|
||||
property string _dynamicText: ""
|
||||
|
||||
// Periodically run the text command (if set)
|
||||
Timer {
|
||||
id: refreshTimer
|
||||
interval: Math.max(250, textIntervalMs)
|
||||
repeat: true
|
||||
running: (textCommand && textCommand.length > 0)
|
||||
triggeredOnStart: true
|
||||
onTriggered: {
|
||||
if (!textCommand || textCommand.length === 0)
|
||||
return
|
||||
if (textProc.running)
|
||||
return
|
||||
textProc.command = ["sh", "-lc", textCommand]
|
||||
textProc.running = true
|
||||
}
|
||||
}
|
||||
|
||||
onClicked: {
|
||||
Process {
|
||||
id: textProc
|
||||
stdout: StdioCollector {}
|
||||
stderr: StdioCollector {}
|
||||
onExited: (exitCode, exitStatus) => {
|
||||
var out = String(stdout.text || "").trim()
|
||||
if (out.indexOf("\n") !== -1) {
|
||||
out = out.split("\n")[0]
|
||||
}
|
||||
_dynamicText = out
|
||||
}
|
||||
}
|
||||
|
||||
function onClicked() {
|
||||
if (leftClickExec) {
|
||||
Quickshell.execDetached(["sh", "-c", leftClickExec])
|
||||
Logger.log("CustomButton", `Executing command: ${leftClickExec}`)
|
||||
@@ -73,14 +121,14 @@ NIconButton {
|
||||
}
|
||||
}
|
||||
|
||||
onRightClicked: {
|
||||
function onRightClicked() {
|
||||
if (rightClickExec) {
|
||||
Quickshell.execDetached(["sh", "-c", rightClickExec])
|
||||
Logger.log("CustomButton", `Executing command: ${rightClickExec}`)
|
||||
}
|
||||
}
|
||||
|
||||
onMiddleClicked: {
|
||||
function onMiddleClicked() {
|
||||
if (middleClickExec) {
|
||||
Quickshell.execDetached(["sh", "-c", middleClickExec])
|
||||
Logger.log("CustomButton", `Executing command: ${middleClickExec}`)
|
||||
|
||||
@@ -17,7 +17,5 @@ NIconButton {
|
||||
colorFg: Settings.data.colorSchemes.darkMode ? Color.mOnSurface : Color.mOnPrimary
|
||||
colorBorder: Color.transparent
|
||||
colorBorderHover: Color.transparent
|
||||
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
onClicked: Settings.data.colorSchemes.darkMode = !Settings.data.colorSchemes.darkMode
|
||||
}
|
||||
|
||||
@@ -95,7 +95,7 @@ Item {
|
||||
suffix: "%"
|
||||
forceOpen: displayMode === "alwaysShow"
|
||||
forceClose: displayMode === "alwaysHide"
|
||||
tooltipText: "Microphone: " + Math.round(AudioService.inputVolume * 100) + "%\nLeft click for advanced settings.\nScroll up/down to change volume.\nRight click to toggle mute."
|
||||
tooltipText: "Microphone: " + Math.round(AudioService.inputVolume * 100) + "%\nLeft click to toggle mute.\nRight click for settings.\nScroll to modify volume."
|
||||
|
||||
onWheel: function (delta) {
|
||||
wheelAccumulator += delta
|
||||
|
||||
@@ -16,6 +16,5 @@ NIconButton {
|
||||
sizeRatio: 0.8
|
||||
colorBg: Color.mPrimary
|
||||
colorFg: Color.mOnPrimary
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
onClicked: ScreenRecorderService.toggleRecording()
|
||||
}
|
||||
|
||||
@@ -33,34 +33,23 @@ NIconButton {
|
||||
|
||||
icon: useDistroLogo ? "" : "noctalia"
|
||||
tooltipText: "Open side panel."
|
||||
sizeRatio: 0.8
|
||||
sizeRatio: 0.85
|
||||
|
||||
colorBg: Color.mSurfaceVariant
|
||||
colorFg: Color.mOnSurface
|
||||
colorBgHover: useDistroLogo ? Color.mSurfaceVariant : Color.mTertiary
|
||||
colorBorder: Color.transparent
|
||||
colorBorderHover: Color.transparent
|
||||
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
colorBorderHover: useDistroLogo ? Color.mTertiary : Color.transparent
|
||||
onClicked: PanelService.getPanel("sidePanel")?.toggle(this)
|
||||
onRightClicked: PanelService.getPanel("settingsPanel")?.toggle()
|
||||
|
||||
IconImage {
|
||||
id: logo
|
||||
anchors.centerIn: parent
|
||||
width: root.width * 0.6
|
||||
width: root.width * 0.85
|
||||
height: width
|
||||
source: useDistroLogo ? DistroLogoService.osLogo : ""
|
||||
visible: useDistroLogo && source !== ""
|
||||
smooth: true
|
||||
}
|
||||
|
||||
MultiEffect {
|
||||
anchors.fill: logo
|
||||
source: logo
|
||||
//visible: logo.visible
|
||||
colorization: 1
|
||||
brightness: 1
|
||||
saturation: 1
|
||||
colorizationColor: root.hovering ? Color.mSurfaceVariant : Color.mOnSurface
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,6 +43,26 @@ Rectangle {
|
||||
radius: Math.round(Style.radiusM * scaling)
|
||||
color: Color.mSurfaceVariant
|
||||
|
||||
// Compact speed formatter for vertical bar display
|
||||
function formatCompactSpeed(bytesPerSecond) {
|
||||
if (!bytesPerSecond || bytesPerSecond <= 0)
|
||||
return "0"
|
||||
const units = ["", "k", "M", "G"]
|
||||
let value = bytesPerSecond
|
||||
let unitIndex = 0
|
||||
while (value >= 1024 && unitIndex < units.length - 1) {
|
||||
value = value / 1024.0
|
||||
unitIndex++
|
||||
}
|
||||
// Promote at ~100 of current unit (e.g., 100k -> ~0.1M shown as 0.1M or 0M if rounded)
|
||||
if (unitIndex < units.length - 1 && value >= 100) {
|
||||
value = value / 1024.0
|
||||
unitIndex++
|
||||
}
|
||||
const display = (value >= 10) ? Math.round(value).toString() : value.toFixed(1)
|
||||
return display + units[unitIndex]
|
||||
}
|
||||
|
||||
// Horizontal layout for top/bottom bars
|
||||
RowLayout {
|
||||
id: horizontalLayout
|
||||
@@ -347,21 +367,21 @@ Rectangle {
|
||||
anchors.centerIn: parent
|
||||
spacing: Style.marginXXS * scaling
|
||||
|
||||
NText {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
text: formatCompactSpeed(SystemStatService.rxSpeed)
|
||||
font.family: Settings.data.ui.fontFixed
|
||||
font.pointSize: Style.fontSizeXXS * scaling
|
||||
font.weight: Style.fontWeightMedium
|
||||
color: Color.mPrimary
|
||||
}
|
||||
|
||||
NIcon {
|
||||
icon: "download-speed"
|
||||
font.pointSize: Style.fontSizeS * scaling
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
}
|
||||
|
||||
NText {
|
||||
text: SystemStatService.formatSpeed(SystemStatService.rxSpeed)
|
||||
font.family: Settings.data.ui.fontFixed
|
||||
font.pointSize: Style.fontSizeXXS * scaling
|
||||
font.weight: Style.fontWeightMedium
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
color: Color.mPrimary
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -377,21 +397,21 @@ Rectangle {
|
||||
anchors.centerIn: parent
|
||||
spacing: Style.marginXXS * scaling
|
||||
|
||||
NText {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
text: formatCompactSpeed(SystemStatService.txSpeed)
|
||||
font.family: Settings.data.ui.fontFixed
|
||||
font.pointSize: Style.fontSizeXXS * scaling
|
||||
font.weight: Style.fontWeightMedium
|
||||
color: Color.mPrimary
|
||||
}
|
||||
|
||||
NIcon {
|
||||
icon: "upload-speed"
|
||||
font.pointSize: Style.fontSizeS * scaling
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
}
|
||||
|
||||
NText {
|
||||
text: SystemStatService.formatSpeed(SystemStatService.txSpeed)
|
||||
font.family: Settings.data.ui.fontFixed
|
||||
font.pointSize: Style.fontSizeXXS * scaling
|
||||
font.weight: Style.fontWeightMedium
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
color: Color.mPrimary
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -407,12 +427,6 @@ Rectangle {
|
||||
anchors.centerIn: parent
|
||||
spacing: Style.marginXXS * scaling
|
||||
|
||||
NIcon {
|
||||
icon: "storage"
|
||||
font.pointSize: Style.fontSizeS * scaling
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
|
||||
NText {
|
||||
text: `${SystemStatService.diskPercent}%`
|
||||
font.family: Settings.data.ui.fontFixed
|
||||
@@ -422,6 +436,12 @@ Rectangle {
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
color: Color.mPrimary
|
||||
}
|
||||
|
||||
NIcon {
|
||||
icon: "storage"
|
||||
font.pointSize: Style.fontSizeS * scaling
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@ Item {
|
||||
suffix: "%"
|
||||
forceOpen: displayMode === "alwaysShow"
|
||||
forceClose: displayMode === "alwaysHide"
|
||||
tooltipText: "Volume: " + Math.round(AudioService.volume * 100) + "%\nLeft click for advanced settings.\nScroll up/down to change volume.\nRight click to toggle mute."
|
||||
tooltipText: "Volume: " + Math.round(AudioService.volume * 100) + "%\nLeft click to toggle mute.\nRight click for settings.\nScroll to modify volume."
|
||||
|
||||
onWheel: function (delta) {
|
||||
wheelAccumulator += delta
|
||||
|
||||
@@ -12,6 +12,7 @@ Scope {
|
||||
property bool unlockInProgress: false
|
||||
property bool showFailure: false
|
||||
property string errorMessage: ""
|
||||
property string infoMessage: ""
|
||||
property bool pamAvailable: typeof PamContext !== "undefined"
|
||||
|
||||
onCurrentTextChanged: {
|
||||
@@ -28,12 +29,6 @@ Scope {
|
||||
return
|
||||
}
|
||||
|
||||
if (currentText === "") {
|
||||
errorMessage = "Password required"
|
||||
showFailure = true
|
||||
return
|
||||
}
|
||||
|
||||
root.unlockInProgress = true
|
||||
errorMessage = ""
|
||||
showFailure = false
|
||||
@@ -52,6 +47,8 @@ Scope {
|
||||
|
||||
if (messageIsError) {
|
||||
errorMessage = message
|
||||
} else {
|
||||
infoMessage = message
|
||||
}
|
||||
|
||||
if (responseRequired) {
|
||||
|
||||
@@ -511,6 +511,7 @@ Loader {
|
||||
width: 0
|
||||
height: 0
|
||||
visible: false
|
||||
enabled: !lockContext.unlockInProgress
|
||||
font.family: Settings.data.ui.fontFixed
|
||||
font.pointSize: Style.fontSizeL * scaling
|
||||
color: Color.mOnSurface
|
||||
@@ -540,7 +541,7 @@ Loader {
|
||||
color: Color.mOnSurface
|
||||
font.family: Settings.data.ui.fontFixed
|
||||
font.pointSize: Style.fontSizeL * scaling
|
||||
visible: passwordInput.activeFocus
|
||||
visible: passwordInput.activeFocus && !lockContext.unlockInProgress
|
||||
|
||||
SequentialAnimation {
|
||||
id: typingEffect
|
||||
@@ -584,7 +585,7 @@ Loader {
|
||||
NText {
|
||||
text: {
|
||||
if (lockContext.unlockInProgress)
|
||||
return "Authenticating..."
|
||||
return lockContext.infoMessage || "Authenticating..."
|
||||
if (lockContext.showFailure && lockContext.errorMessage)
|
||||
return lockContext.errorMessage
|
||||
if (lockContext.showFailure)
|
||||
|
||||
@@ -19,6 +19,8 @@ ColumnLayout {
|
||||
settings.leftClickExec = leftClickExecInput.text
|
||||
settings.rightClickExec = rightClickExecInput.text
|
||||
settings.middleClickExec = middleClickExecInput.text
|
||||
settings.textCommand = textCommandInput.text
|
||||
settings.textIntervalMs = parseInt(textIntervalInput.text || textIntervalInput.placeholderText, 10)
|
||||
return settings
|
||||
}
|
||||
|
||||
@@ -228,4 +230,33 @@ ColumnLayout {
|
||||
placeholderText: "Enter command to execute (app or custom script)"
|
||||
text: widgetData.middleClickExec || widgetMetadata.middleClickExec
|
||||
}
|
||||
|
||||
NDivider {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
NText {
|
||||
text: "Dynamic Text"
|
||||
font.pointSize: Style.fontSizeM * scaling
|
||||
font.weight: Style.fontWeightBold
|
||||
color: Color.mPrimary
|
||||
}
|
||||
|
||||
NTextInput {
|
||||
id: textCommandInput
|
||||
Layout.fillWidth: true
|
||||
label: "Text Command"
|
||||
description: "Shell command to run periodically (first line becomes the text)."
|
||||
placeholderText: "echo \"Hello World\""
|
||||
text: widgetData?.textCommand || widgetMetadata.textCommand
|
||||
}
|
||||
|
||||
NTextInput {
|
||||
id: textIntervalInput
|
||||
Layout.fillWidth: true
|
||||
label: "Refresh Interval"
|
||||
description: "Interval in milliseconds."
|
||||
placeholderText: String(widgetMetadata.textIntervalMs || 3000)
|
||||
text: widgetData && widgetData.textIntervalMs !== undefined ? String(widgetData.textIntervalMs) : ""
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ ColumnLayout {
|
||||
|
||||
// Update button
|
||||
Rectangle {
|
||||
Layout.alignment: Qt.alignmentRight
|
||||
Layout.alignment: Qt.AlignRight
|
||||
Layout.preferredWidth: Math.round(updateRow.implicitWidth + (Style.marginL * scaling * 2))
|
||||
Layout.preferredHeight: Math.round(Style.barHeight * scaling)
|
||||
radius: Style.radiusL * scaling
|
||||
@@ -189,7 +189,7 @@ ColumnLayout {
|
||||
NText {
|
||||
text: modelData.login || "Unknown"
|
||||
font.weight: Style.fontWeightBold
|
||||
color: contributorArea.containsMouse ? Color.mSurface : Color.mOnSurface
|
||||
color: contributorArea.containsMouse ? Color.mOnTertiary : Color.mOnSurface
|
||||
elide: Text.ElideRight
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
@@ -197,7 +197,7 @@ ColumnLayout {
|
||||
NText {
|
||||
text: (modelData.contributions || 0) + " " + ((modelData.contributions || 0) === 1 ? "commit" : "commits")
|
||||
font.pointSize: Style.fontSizeXS * scaling
|
||||
color: contributorArea.containsMouse ? Color.mSurface : Color.mOnSurface
|
||||
color: contributorArea.containsMouse ? Color.mOnTertiary : Color.mOnSurface
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,7 +95,7 @@ ColumnLayout {
|
||||
NToggle {
|
||||
Layout.fillWidth: true
|
||||
label: "Floating Bar"
|
||||
description: "Make the bar float with rounded corners and margins. This will hide screen corners."
|
||||
description: "Make the bar float with rounded corners and margins. Screen corners will move to screen edges."
|
||||
checked: Settings.data.bar.floating
|
||||
onToggled: checked => Settings.data.bar.floating = checked
|
||||
}
|
||||
|
||||
@@ -318,146 +318,187 @@ ColumnLayout {
|
||||
visible: Settings.data.colorSchemes.useWallpaperColors
|
||||
}
|
||||
|
||||
// Matugen template toggles (moved from MatugenTab)
|
||||
// Matugen template toggles organized by category
|
||||
ColumnLayout {
|
||||
spacing: Style.marginL * scaling
|
||||
Layout.fillWidth: true
|
||||
visible: Settings.data.colorSchemes.useWallpaperColors
|
||||
spacing: Style.marginL * scaling
|
||||
|
||||
ColumnLayout {
|
||||
spacing: Style.marginS * scaling
|
||||
// UI Components
|
||||
NCollapsible {
|
||||
Layout.fillWidth: true
|
||||
label: "UI"
|
||||
description: "Desktop environment and UI toolkit theming."
|
||||
defaultExpanded: false
|
||||
|
||||
NText {
|
||||
text: "Matugen Templates"
|
||||
font.pointSize: Style.fontSizeXXL * scaling
|
||||
font.weight: Style.fontWeightBold
|
||||
color: Color.mSecondary
|
||||
NCheckbox {
|
||||
label: "GTK 4 (libadwaita)"
|
||||
description: "Write ~/.config/gtk-4.0/gtk.css"
|
||||
checked: Settings.data.matugen.gtk4
|
||||
onToggled: checked => {
|
||||
Settings.data.matugen.gtk4 = checked
|
||||
if (Settings.data.colorSchemes.useWallpaperColors)
|
||||
MatugenService.generateFromWallpaper()
|
||||
}
|
||||
}
|
||||
|
||||
NText {
|
||||
text: "Select which external components Matugen should apply theming to."
|
||||
font.pointSize: Style.fontSizeM * scaling
|
||||
color: Color.mOnSurfaceVariant
|
||||
Layout.fillWidth: true
|
||||
wrapMode: Text.WordWrap
|
||||
NCheckbox {
|
||||
label: "GTK 3"
|
||||
description: "Write ~/.config/gtk-3.0/gtk.css"
|
||||
checked: Settings.data.matugen.gtk3
|
||||
onToggled: checked => {
|
||||
Settings.data.matugen.gtk3 = checked
|
||||
if (Settings.data.colorSchemes.useWallpaperColors)
|
||||
MatugenService.generateFromWallpaper()
|
||||
}
|
||||
}
|
||||
|
||||
NCheckbox {
|
||||
label: "Qt6ct"
|
||||
description: "Write ~/.config/qt6ct/colors/noctalia.conf"
|
||||
checked: Settings.data.matugen.qt6
|
||||
onToggled: checked => {
|
||||
Settings.data.matugen.qt6 = checked
|
||||
if (Settings.data.colorSchemes.useWallpaperColors)
|
||||
MatugenService.generateFromWallpaper()
|
||||
}
|
||||
}
|
||||
|
||||
NCheckbox {
|
||||
label: "Qt5ct"
|
||||
description: "Write ~/.config/qt5ct/colors/noctalia.conf"
|
||||
checked: Settings.data.matugen.qt5
|
||||
onToggled: checked => {
|
||||
Settings.data.matugen.qt5 = checked
|
||||
if (Settings.data.colorSchemes.useWallpaperColors)
|
||||
MatugenService.generateFromWallpaper()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NCheckbox {
|
||||
label: "GTK 4 (libadwaita)"
|
||||
description: "Write ~/.config/gtk-4.0/gtk.css"
|
||||
checked: Settings.data.matugen.gtk4
|
||||
onToggled: checked => {
|
||||
Settings.data.matugen.gtk4 = checked
|
||||
if (Settings.data.colorSchemes.useWallpaperColors)
|
||||
MatugenService.generateFromWallpaper()
|
||||
}
|
||||
}
|
||||
|
||||
NCheckbox {
|
||||
label: "GTK 3"
|
||||
description: "Write ~/.config/gtk-3.0/gtk.css"
|
||||
checked: Settings.data.matugen.gtk3
|
||||
onToggled: checked => {
|
||||
Settings.data.matugen.gtk3 = checked
|
||||
if (Settings.data.colorSchemes.useWallpaperColors)
|
||||
MatugenService.generateFromWallpaper()
|
||||
}
|
||||
}
|
||||
|
||||
NCheckbox {
|
||||
label: "Qt6ct"
|
||||
description: "Write ~/.config/qt6ct/colors/noctalia.conf"
|
||||
checked: Settings.data.matugen.qt6
|
||||
onToggled: checked => {
|
||||
Settings.data.matugen.qt6 = checked
|
||||
if (Settings.data.colorSchemes.useWallpaperColors)
|
||||
MatugenService.generateFromWallpaper()
|
||||
}
|
||||
}
|
||||
|
||||
NCheckbox {
|
||||
label: "Qt5ct"
|
||||
description: "Write ~/.config/qt5ct/colors/noctalia.conf"
|
||||
checked: Settings.data.matugen.qt5
|
||||
onToggled: checked => {
|
||||
Settings.data.matugen.qt5 = checked
|
||||
if (Settings.data.colorSchemes.useWallpaperColors)
|
||||
MatugenService.generateFromWallpaper()
|
||||
}
|
||||
}
|
||||
|
||||
NCheckbox {
|
||||
label: "Kitty"
|
||||
description: "Write ~/.config/kitty/themes/noctalia.conf and reload"
|
||||
checked: Settings.data.matugen.kitty
|
||||
onToggled: checked => {
|
||||
Settings.data.matugen.kitty = checked
|
||||
if (Settings.data.colorSchemes.useWallpaperColors)
|
||||
MatugenService.generateFromWallpaper()
|
||||
}
|
||||
}
|
||||
|
||||
NCheckbox {
|
||||
label: "Ghostty"
|
||||
description: "Write ~/.config/ghostty/themes/noctalia and reload"
|
||||
checked: Settings.data.matugen.ghostty
|
||||
onToggled: checked => {
|
||||
Settings.data.matugen.ghostty = checked
|
||||
if (Settings.data.colorSchemes.useWallpaperColors)
|
||||
MatugenService.generateFromWallpaper()
|
||||
}
|
||||
}
|
||||
|
||||
NCheckbox {
|
||||
label: "Foot"
|
||||
description: "Write ~/.config/foot/themes/noctalia and reload"
|
||||
checked: Settings.data.matugen.foot
|
||||
onToggled: checked => {
|
||||
Settings.data.matugen.foot = checked
|
||||
if (Settings.data.colorSchemes.useWallpaperColors)
|
||||
MatugenService.generateFromWallpaper()
|
||||
}
|
||||
}
|
||||
|
||||
NCheckbox {
|
||||
label: "Fuzzel"
|
||||
description: "Write ~/.config/fuzzel/themes/noctalia and reload"
|
||||
checked: Settings.data.matugen.fuzzel
|
||||
onToggled: checked => {
|
||||
Settings.data.matugen.fuzzel = checked
|
||||
if (Settings.data.colorSchemes.useWallpaperColors)
|
||||
MatugenService.generateFromWallpaper()
|
||||
}
|
||||
}
|
||||
|
||||
NCheckbox {
|
||||
label: "Vesktop"
|
||||
description: "Write ~/.config/vesktop/themes/noctalia.theme.css"
|
||||
checked: Settings.data.matugen.vesktop
|
||||
onToggled: checked => {
|
||||
Settings.data.matugen.vesktop = checked
|
||||
if (Settings.data.colorSchemes.useWallpaperColors)
|
||||
MatugenService.generateFromWallpaper()
|
||||
}
|
||||
}
|
||||
|
||||
NDivider {
|
||||
// Terminal Emulators
|
||||
NCollapsible {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: Style.marginM * scaling
|
||||
Layout.bottomMargin: Style.marginM * scaling
|
||||
label: "Terminal"
|
||||
description: "Terminal emulator theming."
|
||||
defaultExpanded: false
|
||||
|
||||
NCheckbox {
|
||||
label: "Kitty"
|
||||
description: ProgramCheckerService.kittyAvailable ? "Write ~/.config/kitty/themes/noctalia.conf and reload" : "Requires kitty terminal to be installed"
|
||||
checked: Settings.data.matugen.kitty
|
||||
enabled: ProgramCheckerService.kittyAvailable
|
||||
opacity: ProgramCheckerService.kittyAvailable ? 1.0 : 0.6
|
||||
onToggled: checked => {
|
||||
if (ProgramCheckerService.kittyAvailable) {
|
||||
Settings.data.matugen.kitty = checked
|
||||
if (Settings.data.colorSchemes.useWallpaperColors)
|
||||
MatugenService.generateFromWallpaper()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NCheckbox {
|
||||
label: "Ghostty"
|
||||
description: ProgramCheckerService.ghosttyAvailable ? "Write ~/.config/ghostty/themes/noctalia and reload" : "Requires ghostty terminal to be installed"
|
||||
checked: Settings.data.matugen.ghostty
|
||||
enabled: ProgramCheckerService.ghosttyAvailable
|
||||
opacity: ProgramCheckerService.ghosttyAvailable ? 1.0 : 0.6
|
||||
onToggled: checked => {
|
||||
if (ProgramCheckerService.ghosttyAvailable) {
|
||||
Settings.data.matugen.ghostty = checked
|
||||
if (Settings.data.colorSchemes.useWallpaperColors)
|
||||
MatugenService.generateFromWallpaper()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NCheckbox {
|
||||
label: "Foot"
|
||||
description: ProgramCheckerService.footAvailable ? "Write ~/.config/foot/themes/noctalia and reload" : "Requires foot terminal to be installed"
|
||||
checked: Settings.data.matugen.foot
|
||||
enabled: ProgramCheckerService.footAvailable
|
||||
opacity: ProgramCheckerService.footAvailable ? 1.0 : 0.6
|
||||
onToggled: checked => {
|
||||
if (ProgramCheckerService.footAvailable) {
|
||||
Settings.data.matugen.foot = checked
|
||||
if (Settings.data.colorSchemes.useWallpaperColors)
|
||||
MatugenService.generateFromWallpaper()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NCheckbox {
|
||||
label: "User Templates"
|
||||
description: "Enable user-defined Matugen config from ~/.config/matugen/config.toml"
|
||||
checked: Settings.data.matugen.enableUserTemplates
|
||||
onToggled: checked => {
|
||||
Settings.data.matugen.enableUserTemplates = checked
|
||||
if (Settings.data.colorSchemes.useWallpaperColors)
|
||||
MatugenService.generateFromWallpaper()
|
||||
}
|
||||
// Applications
|
||||
NCollapsible {
|
||||
Layout.fillWidth: true
|
||||
label: "Programs"
|
||||
description: "Application-specific theming."
|
||||
defaultExpanded: false
|
||||
|
||||
NCheckbox {
|
||||
label: "Fuzzel"
|
||||
description: ProgramCheckerService.fuzzelAvailable ? "Write ~/.config/fuzzel/themes/noctalia and reload" : "Requires fuzzel launcher to be installed"
|
||||
checked: Settings.data.matugen.fuzzel
|
||||
enabled: ProgramCheckerService.fuzzelAvailable
|
||||
opacity: ProgramCheckerService.fuzzelAvailable ? 1.0 : 0.6
|
||||
onToggled: checked => {
|
||||
if (ProgramCheckerService.fuzzelAvailable) {
|
||||
Settings.data.matugen.fuzzel = checked
|
||||
if (Settings.data.colorSchemes.useWallpaperColors)
|
||||
MatugenService.generateFromWallpaper()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NCheckbox {
|
||||
label: "Vesktop"
|
||||
description: ProgramCheckerService.vesktopAvailable ? "Write ~/.config/vesktop/themes/noctalia.theme.css" : "Requires vesktop Discord client to be installed"
|
||||
checked: Settings.data.matugen.vesktop
|
||||
enabled: ProgramCheckerService.vesktopAvailable
|
||||
opacity: ProgramCheckerService.vesktopAvailable ? 1.0 : 0.6
|
||||
onToggled: checked => {
|
||||
if (ProgramCheckerService.vesktopAvailable) {
|
||||
Settings.data.matugen.vesktop = checked
|
||||
if (Settings.data.colorSchemes.useWallpaperColors)
|
||||
MatugenService.generateFromWallpaper()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NCheckbox {
|
||||
label: "Pywalfox (Firefox)"
|
||||
description: ProgramCheckerService.pywalfoxAvailable ? "Write ~/.cache/wal/colors.json and run pywalfox update" : "Requires pywalfox package to be installed"
|
||||
checked: Settings.data.matugen.pywalfox
|
||||
enabled: ProgramCheckerService.pywalfoxAvailable
|
||||
opacity: ProgramCheckerService.pywalfoxAvailable ? 1.0 : 0.6
|
||||
onToggled: checked => {
|
||||
if (ProgramCheckerService.pywalfoxAvailable) {
|
||||
Settings.data.matugen.pywalfox = checked
|
||||
if (Settings.data.colorSchemes.useWallpaperColors)
|
||||
MatugenService.generateFromWallpaper()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Miscellaneous
|
||||
NCollapsible {
|
||||
Layout.fillWidth: true
|
||||
label: "Misc"
|
||||
description: "Additional configuration options."
|
||||
defaultExpanded: false
|
||||
|
||||
NCheckbox {
|
||||
label: "User Templates"
|
||||
description: "Enable user-defined Matugen config from ~/.config/matugen/config.toml"
|
||||
checked: Settings.data.matugen.enableUserTemplates
|
||||
onToggled: checked => {
|
||||
Settings.data.matugen.enableUserTemplates = checked
|
||||
if (Settings.data.colorSchemes.useWallpaperColors)
|
||||
MatugenService.generateFromWallpaper()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,6 +129,13 @@ ColumnLayout {
|
||||
onToggled: checked => Settings.data.general.showScreenCorners = checked
|
||||
}
|
||||
|
||||
NToggle {
|
||||
label: "Solid Black Corners"
|
||||
description: "Force screen corners to always render as solid black."
|
||||
checked: Settings.data.general.forceBlackScreenCorners
|
||||
onToggled: checked => Settings.data.general.forceBlackScreenCorners = checked
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
spacing: Style.marginXXS * scaling
|
||||
Layout.fillWidth: true
|
||||
|
||||
@@ -19,7 +19,6 @@ ColumnLayout {
|
||||
ColumnLayout {
|
||||
spacing: Style.marginS * scaling
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: Style.marginS * scaling
|
||||
|
||||
NTextInput {
|
||||
label: "Output Directory"
|
||||
|
||||
@@ -61,7 +61,9 @@ Singleton {
|
||||
"icon": "heart",
|
||||
"leftClickExec": "",
|
||||
"rightClickExec": "",
|
||||
"middleClickExec": ""
|
||||
"middleClickExec": "",
|
||||
"textCommand": "",
|
||||
"textIntervalMs": 3000
|
||||
},
|
||||
"Microphone": {
|
||||
"allowUserSettings": true,
|
||||
|
||||
118
Services/ProgramCheckerService.qml
Normal file
118
Services/ProgramCheckerService.qml
Normal file
@@ -0,0 +1,118 @@
|
||||
pragma Singleton
|
||||
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
import qs.Commons
|
||||
|
||||
// Service to check if various programs are available on the system
|
||||
Singleton {
|
||||
id: root
|
||||
|
||||
// Program availability properties
|
||||
property bool matugenAvailable: false
|
||||
property bool pywalfoxAvailable: false
|
||||
property bool kittyAvailable: false
|
||||
property bool ghosttyAvailable: false
|
||||
property bool footAvailable: false
|
||||
property bool fuzzelAvailable: false
|
||||
property bool vesktopAvailable: false
|
||||
property bool gpuScreenRecorderAvailable: false
|
||||
|
||||
// Signal emitted when all checks are complete
|
||||
signal checksCompleted
|
||||
|
||||
// Programs to check - maps property names to commands
|
||||
readonly property var programsToCheck: ({
|
||||
"matugenAvailable": ["which", "matugen"],
|
||||
"pywalfoxAvailable": ["which", "pywalfox"],
|
||||
"kittyAvailable": ["which", "kitty"],
|
||||
"ghosttyAvailable": ["which", "ghostty"],
|
||||
"footAvailable": ["which", "foot"],
|
||||
"fuzzelAvailable": ["which", "fuzzel"],
|
||||
"vesktopAvailable": ["which", "vesktop"],
|
||||
"gpuScreenRecorderAvailable": ["sh", "-c", "command -v gpu-screen-recorder >/dev/null 2>&1 || (command -v flatpak >/dev/null 2>&1 && flatpak list --app | grep -q 'com.dec05eba.gpu_screen_recorder')"]
|
||||
})
|
||||
|
||||
// Internal tracking
|
||||
property int completedChecks: 0
|
||||
property int totalChecks: Object.keys(programsToCheck).length
|
||||
|
||||
// Single reusable Process object
|
||||
Process {
|
||||
id: checker
|
||||
running: false
|
||||
|
||||
property string currentProperty: ""
|
||||
|
||||
onExited: function (exitCode) {
|
||||
// Set the availability property
|
||||
root[currentProperty] = (exitCode === 0)
|
||||
|
||||
// Stop the process to free resources
|
||||
running = false
|
||||
|
||||
// Track completion
|
||||
root.completedChecks++
|
||||
|
||||
// Check next program or emit completion signal
|
||||
if (root.completedChecks >= root.totalChecks) {
|
||||
root.checksCompleted()
|
||||
} else {
|
||||
root.checkNextProgram()
|
||||
}
|
||||
}
|
||||
|
||||
stdout: StdioCollector {}
|
||||
stderr: StdioCollector {}
|
||||
}
|
||||
|
||||
// Queue of programs to check
|
||||
property var checkQueue: []
|
||||
property int currentCheckIndex: 0
|
||||
|
||||
// Function to check the next program in the queue
|
||||
function checkNextProgram() {
|
||||
if (currentCheckIndex >= checkQueue.length)
|
||||
return
|
||||
|
||||
var propertyName = checkQueue[currentCheckIndex]
|
||||
var command = programsToCheck[propertyName]
|
||||
|
||||
checker.currentProperty = propertyName
|
||||
checker.command = command
|
||||
checker.running = true
|
||||
|
||||
currentCheckIndex++
|
||||
}
|
||||
|
||||
// Function to run all program checks
|
||||
function checkAllPrograms() {
|
||||
// Reset state
|
||||
completedChecks = 0
|
||||
currentCheckIndex = 0
|
||||
checkQueue = Object.keys(programsToCheck)
|
||||
|
||||
// Start first check
|
||||
if (checkQueue.length > 0) {
|
||||
checkNextProgram()
|
||||
}
|
||||
}
|
||||
|
||||
// Function to check a specific program
|
||||
function checkProgram(programProperty) {
|
||||
if (!programsToCheck.hasOwnProperty(programProperty)) {
|
||||
Logger.warn("ProgramChecker", "Unknown program property:", programProperty)
|
||||
return
|
||||
}
|
||||
|
||||
checker.currentProperty = programProperty
|
||||
checker.command = programsToCheck[programProperty]
|
||||
checker.running = true
|
||||
}
|
||||
|
||||
// Initialize checks when service is created
|
||||
Component.onCompleted: {
|
||||
checkAllPrograms()
|
||||
}
|
||||
}
|
||||
@@ -13,16 +13,13 @@ Singleton {
|
||||
property bool isRecording: false
|
||||
property bool isPending: false
|
||||
property string outputPath: ""
|
||||
property bool isAvailable: false
|
||||
property bool isAvailable: ProgramCheckerService.gpuScreenRecorderAvailable
|
||||
|
||||
Component.onCompleted: {
|
||||
checkAvailability()
|
||||
}
|
||||
|
||||
function checkAvailability() {
|
||||
// Detect native or Flatpak gpu-screen-recorder
|
||||
availabilityCheckProcess.command = ["sh", "-c", "command -v gpu-screen-recorder >/dev/null 2>&1 || (command -v flatpak >/dev/null 2>&1 && flatpak list --app | grep -q 'com.dec05eba.gpu_screen_recorder')"]
|
||||
availabilityCheckProcess.running = true
|
||||
// Update availability when ProgramCheckerService completes its checks
|
||||
Connections {
|
||||
target: ProgramCheckerService
|
||||
function onChecksCompleted() {// Availability is now automatically updated via property binding
|
||||
}
|
||||
}
|
||||
|
||||
// Start or Stop recording
|
||||
@@ -101,18 +98,6 @@ Singleton {
|
||||
}
|
||||
}
|
||||
|
||||
// Availability check process
|
||||
Process {
|
||||
id: availabilityCheckProcess
|
||||
command: ["sh", "-c", "true"]
|
||||
onExited: function (exitCode, exitStatus) {
|
||||
// exitCode 0 means available, non-zero means unavailable
|
||||
root.isAvailable = (exitCode === 0)
|
||||
}
|
||||
stdout: StdioCollector {}
|
||||
stderr: StdioCollector {}
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: pendingTimer
|
||||
interval: 2000 // Wait 2 seconds to see if process stays alive
|
||||
|
||||
@@ -8,7 +8,7 @@ Singleton {
|
||||
id: root
|
||||
|
||||
// Public properties
|
||||
property string baseVersion: "2.9.1"
|
||||
property string baseVersion: "2.9.2"
|
||||
property bool isDevelopment: false
|
||||
|
||||
property string currentVersion: `v${!isDevelopment ? baseVersion : baseVersion + "-dev"}`
|
||||
|
||||
193
Widgets/NCollapsible.qml
Normal file
193
Widgets/NCollapsible.qml
Normal file
@@ -0,0 +1,193 @@
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import qs.Commons
|
||||
|
||||
ColumnLayout {
|
||||
id: root
|
||||
property string label: ""
|
||||
property string description: ""
|
||||
property bool expanded: false
|
||||
property bool defaultExpanded: false
|
||||
property real contentSpacing: Style.marginM * scaling
|
||||
signal toggled(bool expanded)
|
||||
|
||||
Layout.fillWidth: true
|
||||
spacing: 0
|
||||
|
||||
// Default property to accept children
|
||||
default property alias content: contentLayout.children
|
||||
|
||||
// Header with clickable area
|
||||
Rectangle {
|
||||
id: headerContainer
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: headerContent.implicitHeight + (Style.marginL * scaling * 2)
|
||||
|
||||
// Material 3 style background
|
||||
color: root.expanded ? Color.mSecondary : Color.mSurfaceVariant
|
||||
radius: Style.radiusL * scaling
|
||||
|
||||
// Subtle border
|
||||
border.color: root.expanded ? Color.mOnSecondary : Color.mOutline
|
||||
border.width: Math.max(1, Style.borderS * scaling)
|
||||
|
||||
// Smooth color transitions
|
||||
Behavior on color {
|
||||
ColorAnimation {
|
||||
duration: Style.animationNormal
|
||||
easing.type: Easing.OutCubic
|
||||
}
|
||||
}
|
||||
|
||||
Behavior on border.color {
|
||||
ColorAnimation {
|
||||
duration: Style.animationNormal
|
||||
easing.type: Easing.OutCubic
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: headerArea
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
hoverEnabled: true
|
||||
|
||||
onClicked: {
|
||||
root.expanded = !root.expanded
|
||||
root.toggled(root.expanded)
|
||||
}
|
||||
|
||||
// Hover effect overlay
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: headerArea.containsMouse ? Color.mOnSurface : Color.transparent
|
||||
opacity: headerArea.containsMouse ? 0.08 : 0
|
||||
radius: headerContainer.radius // Reference the container's radius directly
|
||||
|
||||
Behavior on opacity {
|
||||
NumberAnimation {
|
||||
duration: Style.animationFast
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
id: headerContent
|
||||
anchors.fill: parent
|
||||
anchors.margins: Style.marginL * scaling
|
||||
spacing: Style.marginM * scaling
|
||||
|
||||
// Expand/collapse icon with rotation animation
|
||||
NIcon {
|
||||
id: chevronIcon
|
||||
icon: "chevron-right"
|
||||
font.pointSize: Style.fontSizeL * scaling
|
||||
color: root.expanded ? Color.mOnSecondary : Color.mOnSurfaceVariant
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
|
||||
rotation: root.expanded ? 90 : 0
|
||||
Behavior on rotation {
|
||||
NumberAnimation {
|
||||
duration: Style.animationNormal
|
||||
easing.type: Easing.OutCubic
|
||||
}
|
||||
}
|
||||
|
||||
Behavior on color {
|
||||
ColorAnimation {
|
||||
duration: Style.animationNormal
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Header text content - properly contained
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
spacing: Style.marginXXS * scaling
|
||||
|
||||
NText {
|
||||
text: root.label
|
||||
font.pointSize: Style.fontSizeL * scaling
|
||||
font.weight: Style.fontWeightSemiBold
|
||||
color: root.expanded ? Color.mOnSecondary : Color.mOnSurface
|
||||
Layout.fillWidth: true
|
||||
wrapMode: Text.WordWrap
|
||||
|
||||
Behavior on color {
|
||||
ColorAnimation {
|
||||
duration: Style.animationNormal
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NText {
|
||||
text: root.description
|
||||
font.pointSize: Style.fontSizeS * scaling
|
||||
font.weight: Style.fontWeightRegular
|
||||
color: root.expanded ? Color.mOnSecondary : Color.mOnSurfaceVariant
|
||||
Layout.fillWidth: true
|
||||
wrapMode: Text.WordWrap
|
||||
visible: root.description !== ""
|
||||
opacity: 0.87
|
||||
|
||||
Behavior on color {
|
||||
ColorAnimation {
|
||||
duration: Style.animationNormal
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Collapsible content with Material 3 styling
|
||||
Rectangle {
|
||||
id: contentContainer
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: Style.marginS * scaling
|
||||
|
||||
visible: root.expanded
|
||||
color: Color.mSurface
|
||||
radius: Style.radiusL * scaling
|
||||
border.color: Color.mOutline
|
||||
border.width: Math.max(1, Style.borderS * scaling)
|
||||
|
||||
// Dynamic height based on content
|
||||
Layout.preferredHeight: visible ? contentLayout.implicitHeight + (Style.marginL * scaling * 2) : 0
|
||||
|
||||
// Smooth height animation
|
||||
Behavior on Layout.preferredHeight {
|
||||
NumberAnimation {
|
||||
duration: Style.animationNormal
|
||||
easing.type: Easing.OutCubic
|
||||
}
|
||||
}
|
||||
|
||||
// Content layout
|
||||
ColumnLayout {
|
||||
id: contentLayout
|
||||
anchors.fill: parent
|
||||
anchors.margins: Style.marginL * scaling
|
||||
spacing: root.contentSpacing
|
||||
|
||||
// Clip content during animation
|
||||
clip: true
|
||||
}
|
||||
|
||||
// Fade in animation for content
|
||||
opacity: root.expanded ? 1.0 : 0.0
|
||||
Behavior on opacity {
|
||||
NumberAnimation {
|
||||
duration: Style.animationNormal
|
||||
easing.type: Easing.OutCubic
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize expanded state
|
||||
Component.onCompleted: {
|
||||
root.expanded = root.defaultExpanded
|
||||
}
|
||||
}
|
||||
@@ -60,7 +60,7 @@ Item {
|
||||
onClicked: root.clicked()
|
||||
onRightClicked: root.rightClicked()
|
||||
onMiddleClicked: root.middleClicked()
|
||||
onWheel: root.wheel
|
||||
onWheel: delta => root.wheel(delta)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,7 +85,7 @@ Item {
|
||||
onClicked: root.clicked()
|
||||
onRightClicked: root.rightClicked()
|
||||
onMiddleClicked: root.middleClicked()
|
||||
onWheel: root.wheel
|
||||
onWheel: delta => root.wheel(delta)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ Item {
|
||||
// Exposed width logic
|
||||
readonly property int iconSize: Math.round(Style.baseWidgetSize * sizeRatio * scaling)
|
||||
readonly property int pillHeight: iconSize
|
||||
readonly property int pillPaddingHorizontal: Style.marginS * scaling
|
||||
readonly property int pillPaddingHorizontal: 3 * 2 * scaling // Very precise adjustment don't replace by Style.margin
|
||||
readonly property int pillOverlap: iconSize * 0.5
|
||||
readonly property int maxPillWidth: Math.max(1, textItem.implicitWidth + pillPaddingHorizontal * 2 + pillOverlap)
|
||||
|
||||
@@ -70,7 +70,7 @@ Item {
|
||||
var offset = rightOpen ? Style.marginXS * scaling : -Style.marginXS * scaling
|
||||
if (forceOpen) {
|
||||
// If its force open, the icon disc background is the same color as the bg pill move text slightly
|
||||
offset += rightOpen ? -Style.marginXXS * scaling : Style.marginXS * scaling
|
||||
offset += rightOpen ? -Style.marginXXS * scaling : Style.marginXXS * scaling
|
||||
}
|
||||
return centerX + offset
|
||||
}
|
||||
@@ -78,7 +78,7 @@ Item {
|
||||
font.family: Settings.data.ui.fontFixed
|
||||
font.pointSize: Style.fontSizeXS * scaling
|
||||
font.weight: Style.fontWeightBold
|
||||
color: Color.mPrimary
|
||||
color: forceOpen ? Color.mOnSurface : Color.mPrimary
|
||||
visible: revealed
|
||||
}
|
||||
|
||||
@@ -118,7 +118,7 @@ Item {
|
||||
NIcon {
|
||||
icon: root.icon
|
||||
font.pointSize: Style.fontSizeM * scaling
|
||||
color: hovered && !forceOpen ? Color.mOnTertiary : Color.mOnSurface
|
||||
color: hovered ? Color.mOnTertiary : Color.mOnSurface
|
||||
// Center horizontally
|
||||
x: (iconCircle.width - width) / 2
|
||||
// Center vertically accounting for font metrics
|
||||
@@ -243,9 +243,7 @@ Item {
|
||||
root.middleClicked()
|
||||
}
|
||||
}
|
||||
onWheel: wheel => {
|
||||
root.wheel(wheel.angleDelta.y)
|
||||
}
|
||||
onWheel: wheel => root.wheel(wheel.angleDelta.y)
|
||||
}
|
||||
|
||||
function show() {
|
||||
|
||||
@@ -45,8 +45,7 @@ Item {
|
||||
// Sizing logic for vertical bars
|
||||
readonly property int iconSize: Math.round(Style.baseWidgetSize * sizeRatio * scaling)
|
||||
readonly property int pillHeight: iconSize
|
||||
readonly property int pillPaddingHorizontal: Style.marginS * scaling
|
||||
readonly property int pillPaddingVertical: Style.marginS * scaling
|
||||
readonly property int pillPaddingVertical: 3 * 2 * scaling // Very precise adjustment don't replace by Style.margin
|
||||
readonly property int pillOverlap: iconSize * 0.5
|
||||
readonly property int maxPillWidth: iconSize
|
||||
readonly property int maxPillHeight: Math.max(1, textItem.implicitHeight + pillPaddingVertical * 4)
|
||||
@@ -83,7 +82,7 @@ Item {
|
||||
var offset = openDownward ? pillPaddingVertical * 0.75 : -pillPaddingVertical * 0.75
|
||||
if (forceOpen) {
|
||||
// If its force open, the icon disc background is the same color as the bg pill move text slightly
|
||||
offset += rightOpen ? -Style.marginXXS * scaling : Style.marginXS * scaling
|
||||
offset += rightOpen ? -Style.marginXXS * scaling : Style.marginXXS * scaling
|
||||
}
|
||||
return offset
|
||||
}
|
||||
@@ -93,7 +92,7 @@ Item {
|
||||
font.weight: Style.fontWeightMedium
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
color: Color.mPrimary
|
||||
color: forceOpen ? Color.mOnSurface : Color.mPrimary
|
||||
visible: revealed
|
||||
}
|
||||
|
||||
@@ -142,7 +141,7 @@ Item {
|
||||
NIcon {
|
||||
icon: root.icon
|
||||
font.pointSize: Style.fontSizeM * scaling
|
||||
color: hovered && !forceOpen ? Color.mOnTertiary : Color.mOnSurface
|
||||
color: hovered ? Color.mOnTertiary : Color.mOnSurface
|
||||
// Center horizontally
|
||||
x: (iconCircle.width - width) / 2
|
||||
// Center vertically accounting for font metrics
|
||||
@@ -285,9 +284,7 @@ Item {
|
||||
root.middleClicked()
|
||||
}
|
||||
}
|
||||
onWheel: wheel => {
|
||||
root.wheel(wheel.angleDelta.y)
|
||||
}
|
||||
onWheel: wheel => root.wheel(wheel.angleDelta.y)
|
||||
}
|
||||
|
||||
function show() {
|
||||
|
||||
@@ -26,7 +26,9 @@ Slider {
|
||||
width: root.availableWidth
|
||||
height: implicitHeight
|
||||
radius: 0
|
||||
color: Color.mSurface
|
||||
color: Qt.alpha(Color.mSurface, 0.5)
|
||||
border.color: Qt.alpha(Color.mOutline, 0.5)
|
||||
border.width: Math.max(1, Style.borderS * scaling)
|
||||
|
||||
// Animated gradient active track
|
||||
Rectangle {
|
||||
@@ -34,25 +36,39 @@ Slider {
|
||||
width: root.visualPosition * parent.width
|
||||
height: parent.height
|
||||
radius: parent.radius
|
||||
|
||||
|
||||
// Animated gradient fill
|
||||
gradient: Gradient {
|
||||
orientation: Gradient.Horizontal
|
||||
GradientStop {
|
||||
GradientStop {
|
||||
position: 0.0
|
||||
color: Qt.darker(Color.mPrimary, 1.2)
|
||||
Behavior on color { ColorAnimation { duration: 300 } }
|
||||
Behavior on color {
|
||||
ColorAnimation {
|
||||
duration: 300
|
||||
}
|
||||
}
|
||||
}
|
||||
GradientStop {
|
||||
GradientStop {
|
||||
position: 0.5
|
||||
color: Color.mPrimary
|
||||
SequentialAnimation on position {
|
||||
loops: Animation.Infinite
|
||||
NumberAnimation { from: 0.3; to: 0.7; duration: 2000; easing.type: Easing.InOutSine }
|
||||
NumberAnimation { from: 0.7; to: 0.3; duration: 2000; easing.type: Easing.InOutSine }
|
||||
NumberAnimation {
|
||||
from: 0.3
|
||||
to: 0.7
|
||||
duration: 2000
|
||||
easing.type: Easing.InOutSine
|
||||
}
|
||||
NumberAnimation {
|
||||
from: 0.7
|
||||
to: 0.3
|
||||
duration: 2000
|
||||
easing.type: Easing.InOutSine
|
||||
}
|
||||
}
|
||||
}
|
||||
GradientStop {
|
||||
GradientStop {
|
||||
position: 1.0
|
||||
color: Qt.lighter(Color.mPrimary, 1.2)
|
||||
}
|
||||
@@ -94,4 +110,4 @@ Slider {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
import QtQuick
|
||||
import qs.Commons
|
||||
import qs.Services
|
||||
|
||||
Column {
|
||||
id: root
|
||||
|
||||
property string text: ""
|
||||
property real fontSize: Style.fontSizeXS
|
||||
property color color: Color.mOnSurface
|
||||
property int fontWeight: Style.fontWeightBold
|
||||
|
||||
spacing: -2 * scaling
|
||||
|
||||
Repeater {
|
||||
model: root.text.split("")
|
||||
NText {
|
||||
text: modelData
|
||||
font.family: Settings.data.ui.fontFixed
|
||||
font.pointSize: root.fontSize
|
||||
font.weight: root.fontWeight
|
||||
color: root.color
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
}
|
||||
}
|
||||
}
|
||||
60
flake.nix
60
flake.nix
@@ -1,5 +1,6 @@
|
||||
{
|
||||
description = "Noctalia shell - a Wayland desktop shell built with Quickshell";
|
||||
description =
|
||||
"Noctalia shell - a Wayland desktop shell built with Quickshell";
|
||||
|
||||
inputs = {
|
||||
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
|
||||
@@ -11,22 +12,13 @@
|
||||
};
|
||||
};
|
||||
|
||||
outputs =
|
||||
{
|
||||
self,
|
||||
nixpkgs,
|
||||
systems,
|
||||
quickshell,
|
||||
...
|
||||
}:
|
||||
let
|
||||
eachSystem = nixpkgs.lib.genAttrs (import systems);
|
||||
in
|
||||
{
|
||||
formatter = eachSystem (system: nixpkgs.legacyPackages.${system}.alejandra);
|
||||
outputs = { self, nixpkgs, systems, quickshell, ... }:
|
||||
let eachSystem = nixpkgs.lib.genAttrs (import systems);
|
||||
in {
|
||||
formatter =
|
||||
eachSystem (system: nixpkgs.legacyPackages.${system}.alejandra);
|
||||
|
||||
packages = eachSystem (
|
||||
system:
|
||||
packages = eachSystem (system:
|
||||
let
|
||||
pkgs = nixpkgs.legacyPackages.${system};
|
||||
qs = quickshell.packages.${system}.default.override {
|
||||
@@ -34,8 +26,7 @@
|
||||
withI3 = false;
|
||||
};
|
||||
|
||||
runtimeDeps =
|
||||
with pkgs;
|
||||
runtimeDeps = with pkgs;
|
||||
[
|
||||
bash
|
||||
bluez
|
||||
@@ -50,34 +41,21 @@
|
||||
matugen
|
||||
networkmanager
|
||||
wl-clipboard
|
||||
]
|
||||
++ lib.optionals (pkgs.stdenv.hostPlatform.isx86_64) [
|
||||
gpu-screen-recorder
|
||||
];
|
||||
] ++ lib.optionals (pkgs.stdenv.hostPlatform.isx86_64)
|
||||
[ gpu-screen-recorder ];
|
||||
|
||||
fontconfig = pkgs.makeFontsConf {
|
||||
fontDirectories = [
|
||||
pkgs.roboto
|
||||
pkgs.inter-nerdfont
|
||||
];
|
||||
fontDirectories = [ pkgs.roboto pkgs.inter-nerdfont ];
|
||||
};
|
||||
in
|
||||
{
|
||||
in {
|
||||
default = pkgs.stdenv.mkDerivation {
|
||||
pname = "noctalia-shell";
|
||||
version = self.rev or self.dirtyRev or "dirty";
|
||||
src = ./.;
|
||||
|
||||
nativeBuildInputs = [
|
||||
pkgs.gcc
|
||||
pkgs.makeWrapper
|
||||
pkgs.qt6.wrapQtAppsHook
|
||||
];
|
||||
buildInputs = [
|
||||
qs
|
||||
pkgs.xkeyboard-config
|
||||
pkgs.qt6.qtbase
|
||||
];
|
||||
nativeBuildInputs =
|
||||
[ pkgs.gcc pkgs.makeWrapper pkgs.qt6.wrapQtAppsHook ];
|
||||
buildInputs = [ qs pkgs.xkeyboard_config pkgs.qt6.qtbase ];
|
||||
propagatedBuildInputs = runtimeDeps;
|
||||
|
||||
installPhase = ''
|
||||
@@ -91,14 +69,14 @@
|
||||
'';
|
||||
|
||||
meta = {
|
||||
description = "A sleek and minimal desktop shell thoughtfully crafted for Wayland, built with Quickshell.";
|
||||
description =
|
||||
"A sleek and minimal desktop shell thoughtfully crafted for Wayland, built with Quickshell.";
|
||||
homepage = "https://github.com/noctalia-dev/noctalia-shell";
|
||||
license = pkgs.lib.licenses.mit;
|
||||
mainProgram = "noctalia-shell";
|
||||
};
|
||||
};
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
defaultPackage = eachSystem (system: self.packages.${system}.default);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user