mirror of
https://github.com/celesrenata/end-4-flakes.git
synced 2026-06-07 11:09:26 -05:00
fix: add wayland dev headers and scanner for pywayland build on NixOS
This commit is contained in:
@@ -0,0 +1,130 @@
|
||||
# Configuration override system - allows complete manual control
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.programs.dots-hyprland;
|
||||
in
|
||||
{
|
||||
options.programs.dots-hyprland.overrides = {
|
||||
# Complete file overrides - when set, completely replaces any generated config
|
||||
hyprlandConf = mkOption {
|
||||
type = types.nullOr types.lines;
|
||||
default = null;
|
||||
description = ''
|
||||
Complete hyprland.conf content. When set, completely overrides:
|
||||
- Any rich hyprland.* configuration options
|
||||
- Any copied hyprland.conf from source
|
||||
- Generates the entire file from this content
|
||||
'';
|
||||
example = ''
|
||||
# Custom Hyprland configuration
|
||||
general {
|
||||
gaps_in = 10
|
||||
gaps_out = 20
|
||||
}
|
||||
'';
|
||||
};
|
||||
|
||||
quickshellConfig = mkOption {
|
||||
type = types.nullOr types.lines;
|
||||
default = null;
|
||||
description = ''
|
||||
Complete Config.qml content. When set, completely overrides:
|
||||
- Any rich quickshell.* configuration options
|
||||
- Any copied Config.qml from source
|
||||
- Generates the entire file from this content
|
||||
'';
|
||||
};
|
||||
|
||||
footConfig = mkOption {
|
||||
type = types.nullOr types.lines;
|
||||
default = null;
|
||||
description = ''
|
||||
Complete foot.ini content. When set, completely overrides:
|
||||
- Any rich terminal.* configuration options
|
||||
- Any copied foot.ini from source
|
||||
- Generates the entire file from this content
|
||||
'';
|
||||
};
|
||||
|
||||
toucheggConf = mkOption {
|
||||
type = types.nullOr types.lines;
|
||||
default = null;
|
||||
description = ''
|
||||
Complete touchegg.conf content. When set, completely overrides:
|
||||
- Any copied touchegg.conf from source
|
||||
- Generates the entire file from this content
|
||||
'';
|
||||
};
|
||||
|
||||
# Directory-level overrides
|
||||
hyprDirectory = mkOption {
|
||||
type = types.nullOr types.path;
|
||||
default = null;
|
||||
description = ''
|
||||
Complete hypr directory override. When set, copies entire directory
|
||||
and ignores all hyprland configuration options.
|
||||
'';
|
||||
};
|
||||
|
||||
quickshellDirectory = mkOption {
|
||||
type = types.nullOr types.path;
|
||||
default = null;
|
||||
description = ''
|
||||
Complete quickshell directory override. When set, copies entire directory
|
||||
and ignores all quickshell configuration options.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
# Override warnings
|
||||
warnings =
|
||||
(optional (cfg.overrides.hyprlandConf != null && cfg.hyprland != {})
|
||||
"dots-hyprland: overrides.hyprlandConf is set, ignoring all hyprland.* options") ++
|
||||
(optional (cfg.overrides.quickshellConfig != null && cfg.quickshell != {})
|
||||
"dots-hyprland: overrides.quickshellConfig is set, ignoring all quickshell.* options") ++
|
||||
(optional (cfg.overrides.footConfig != null && cfg.terminal != {})
|
||||
"dots-hyprland: overrides.footConfig is set, ignoring all terminal.* options");
|
||||
|
||||
# File overrides take absolute priority
|
||||
xdg.configFile = mkMerge [
|
||||
# Hyprland complete override
|
||||
(mkIf (cfg.overrides.hyprlandConf != null) {
|
||||
"hypr/hyprland.conf".text = cfg.overrides.hyprlandConf;
|
||||
})
|
||||
|
||||
# Quickshell complete override
|
||||
(mkIf (cfg.overrides.quickshellConfig != null) {
|
||||
"quickshell/ii/modules/common/Config.qml".text = cfg.overrides.quickshellConfig;
|
||||
})
|
||||
|
||||
# Terminal complete override
|
||||
(mkIf (cfg.overrides.footConfig != null) {
|
||||
"foot/foot.ini".text = cfg.overrides.footConfig;
|
||||
})
|
||||
|
||||
# Touchegg complete override
|
||||
(mkIf (cfg.overrides.toucheggConf != null) {
|
||||
"touchegg/touchegg.conf".text = cfg.overrides.toucheggConf;
|
||||
})
|
||||
|
||||
# Directory overrides
|
||||
(mkIf (cfg.overrides.hyprDirectory != null) {
|
||||
"hypr" = {
|
||||
source = cfg.overrides.hyprDirectory;
|
||||
recursive = true;
|
||||
};
|
||||
})
|
||||
|
||||
(mkIf (cfg.overrides.quickshellDirectory != null) {
|
||||
"quickshell" = {
|
||||
source = cfg.overrides.quickshellDirectory;
|
||||
recursive = true;
|
||||
};
|
||||
})
|
||||
];
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
# Hyprland configuration options for dots-hyprland
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.programs.dots-hyprland.hyprland;
|
||||
in
|
||||
{
|
||||
options.programs.dots-hyprland.hyprland = {
|
||||
# General settings
|
||||
general = {
|
||||
gapsIn = mkOption {
|
||||
type = types.int;
|
||||
default = 4;
|
||||
description = "Inner gaps between windows";
|
||||
};
|
||||
|
||||
gapsOut = mkOption {
|
||||
type = types.int;
|
||||
default = 7;
|
||||
description = "Outer gaps around windows";
|
||||
};
|
||||
|
||||
borderSize = mkOption {
|
||||
type = types.int;
|
||||
default = 2;
|
||||
description = "Border width around windows";
|
||||
};
|
||||
|
||||
allowTearing = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Allow screen tearing (useful for gaming)";
|
||||
};
|
||||
};
|
||||
|
||||
# Decoration settings
|
||||
decoration = {
|
||||
rounding = mkOption {
|
||||
type = types.int;
|
||||
default = 16;
|
||||
description = "Corner rounding radius";
|
||||
};
|
||||
|
||||
blurEnabled = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "Enable background blur";
|
||||
};
|
||||
};
|
||||
|
||||
# Gesture settings
|
||||
gestures = {
|
||||
workspaceSwipe = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "Enable workspace swipe gestures";
|
||||
};
|
||||
};
|
||||
|
||||
# Monitor configuration
|
||||
monitors = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
description = "Monitor configuration strings";
|
||||
example = [ "eDP-1,1920x1080@60,0x0,1" ];
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf (config.programs.dots-hyprland.enable && config.programs.dots-hyprland.overrides.hyprlandConf == null) {
|
||||
# Only generate if no manual override is set
|
||||
xdg.configFile."hypr/general.conf".text = ''
|
||||
# General Hyprland configuration for dots-hyprland (NixOS-managed)
|
||||
|
||||
${optionalString (cfg.monitors != []) ''
|
||||
# Monitor configuration
|
||||
${concatMapStringsSep "\n" (monitor: "monitor=${monitor}") cfg.monitors}
|
||||
''}
|
||||
|
||||
# Gestures (Hyprland 0.51+ syntax)
|
||||
gestures {
|
||||
gesture = 3, horizontal, workspace
|
||||
}
|
||||
|
||||
general {
|
||||
# Gaps and border
|
||||
gaps_in = ${toString cfg.general.gapsIn}
|
||||
gaps_out = ${toString cfg.general.gapsOut}
|
||||
gaps_workspaces = 50
|
||||
|
||||
border_size = ${toString cfg.general.borderSize}
|
||||
col.active_border = rgba(cba6f7ff)
|
||||
col.inactive_border = rgba(313244ff)
|
||||
resize_on_border = true
|
||||
|
||||
no_focus_fallback = true
|
||||
|
||||
allow_tearing = ${boolToString cfg.general.allowTearing}
|
||||
|
||||
snap {
|
||||
enabled = true
|
||||
}
|
||||
}
|
||||
|
||||
dwindle {
|
||||
preserve_split = true
|
||||
smart_split = false
|
||||
smart_resizing = false
|
||||
}
|
||||
|
||||
decoration {
|
||||
rounding = ${toString cfg.decoration.rounding}
|
||||
|
||||
blur {
|
||||
enabled = ${boolToString cfg.decoration.blurEnabled}
|
||||
xray = true
|
||||
special = false
|
||||
new_optimizations = true
|
||||
size = 14
|
||||
passes = 4
|
||||
brightness = 1
|
||||
noise = 0.01
|
||||
contrast = 1
|
||||
popups = true
|
||||
popups_ignorealpha = 0.6
|
||||
}
|
||||
|
||||
drop_shadow = true
|
||||
shadow_ignore_window = true
|
||||
shadow_offset = 0 2
|
||||
shadow_range = 20
|
||||
shadow_render_power = 3
|
||||
col.shadow = rgba(00000055)
|
||||
}
|
||||
'';
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,436 @@
|
||||
# Quickshell configuration options for dots-hyprland
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.programs.dots-hyprland.quickshell;
|
||||
in
|
||||
{
|
||||
options.programs.dots-hyprland.quickshell = {
|
||||
# Appearance settings
|
||||
appearance = {
|
||||
extraBackgroundTint = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "Enable extra background tint";
|
||||
};
|
||||
|
||||
fakeScreenRounding = mkOption {
|
||||
type = types.enum [ 0 1 2 ];
|
||||
default = 2;
|
||||
description = "Screen rounding mode: 0=None, 1=Always, 2=When not fullscreen";
|
||||
};
|
||||
|
||||
transparency = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Enable transparency effects";
|
||||
};
|
||||
};
|
||||
|
||||
# Bar configuration
|
||||
bar = {
|
||||
bottom = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Place bar at bottom instead of top";
|
||||
};
|
||||
|
||||
cornerStyle = mkOption {
|
||||
type = types.enum [ 0 1 2 ];
|
||||
default = 0;
|
||||
description = "Bar corner style: 0=Hug, 1=Float, 2=Plain rectangle";
|
||||
};
|
||||
|
||||
borderless = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Remove grouping of bar items";
|
||||
};
|
||||
|
||||
topLeftIcon = mkOption {
|
||||
type = types.enum [ "distro" "spark" ];
|
||||
default = "spark";
|
||||
description = "Icon to show in top-left of bar";
|
||||
};
|
||||
|
||||
showBackground = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "Show bar background";
|
||||
};
|
||||
|
||||
verbose = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "Show detailed information in bar";
|
||||
};
|
||||
|
||||
utilButtons = {
|
||||
showScreenSnip = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "Show screen snip button";
|
||||
};
|
||||
|
||||
showColorPicker = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Show color picker button";
|
||||
};
|
||||
|
||||
showMicToggle = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Show microphone toggle button";
|
||||
};
|
||||
|
||||
showKeyboardToggle = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "Show keyboard layout toggle";
|
||||
};
|
||||
|
||||
showDarkModeToggle = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "Show dark mode toggle";
|
||||
};
|
||||
|
||||
showPerformanceProfileToggle = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Show performance profile toggle";
|
||||
};
|
||||
};
|
||||
|
||||
workspaces = {
|
||||
monochromeIcons = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "Use monochrome workspace icons";
|
||||
};
|
||||
|
||||
shown = mkOption {
|
||||
type = types.int;
|
||||
default = 10;
|
||||
description = "Number of workspaces to show";
|
||||
};
|
||||
|
||||
showAppIcons = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "Show application icons in workspaces";
|
||||
};
|
||||
|
||||
alwaysShowNumbers = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Always show workspace numbers";
|
||||
};
|
||||
|
||||
showNumberDelay = mkOption {
|
||||
type = types.int;
|
||||
default = 300;
|
||||
description = "Delay before showing workspace numbers (milliseconds)";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# Battery settings
|
||||
battery = {
|
||||
low = mkOption {
|
||||
type = types.int;
|
||||
default = 20;
|
||||
description = "Low battery threshold (%)";
|
||||
};
|
||||
|
||||
critical = mkOption {
|
||||
type = types.int;
|
||||
default = 5;
|
||||
description = "Critical battery threshold (%)";
|
||||
};
|
||||
|
||||
automaticSuspend = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "Enable automatic suspend on critical battery";
|
||||
};
|
||||
|
||||
suspend = mkOption {
|
||||
type = types.int;
|
||||
default = 3;
|
||||
description = "Minutes before suspend on critical battery";
|
||||
};
|
||||
};
|
||||
|
||||
# Application settings
|
||||
apps = {
|
||||
terminal = mkOption {
|
||||
type = types.str;
|
||||
default = "kitty -1";
|
||||
description = "Terminal command for shell actions";
|
||||
};
|
||||
|
||||
bluetooth = mkOption {
|
||||
type = types.str;
|
||||
default = "kcmshell6 kcm_bluetooth";
|
||||
description = "Bluetooth settings command";
|
||||
};
|
||||
|
||||
network = mkOption {
|
||||
type = types.str;
|
||||
default = "plasmawindowed org.kde.plasma.networkmanagement";
|
||||
description = "Network settings command";
|
||||
};
|
||||
|
||||
taskManager = mkOption {
|
||||
type = types.str;
|
||||
default = "plasma-systemmonitor --page-name Processes";
|
||||
description = "Task manager command";
|
||||
};
|
||||
};
|
||||
|
||||
# Time format
|
||||
time = {
|
||||
format = mkOption {
|
||||
type = types.str;
|
||||
default = "hh:mm";
|
||||
description = "Time format string";
|
||||
};
|
||||
|
||||
dateFormat = mkOption {
|
||||
type = types.str;
|
||||
default = "ddd, dd/MM";
|
||||
description = "Date format string";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf (config.programs.dots-hyprland.enable &&
|
||||
config.programs.dots-hyprland.overrides.quickshellConfig == null &&
|
||||
!(config.programs.dots-hyprland.configuration.enable or false)) {
|
||||
# Only generate if no manual override is set AND configuration copying is disabled
|
||||
xdg.configFile."quickshell/ii/modules/common/Config.qml".text = ''
|
||||
pragma Singleton
|
||||
pragma ComponentBehavior: Bound
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
|
||||
Singleton {
|
||||
id: root
|
||||
property string filePath: Directories.shellConfigPath
|
||||
property alias options: configOptionsJsonAdapter
|
||||
property bool ready: true // Always ready for NixOS-generated config
|
||||
|
||||
function setNestedValue(nestedKey, value) {
|
||||
// NixOS-managed config - values are set at build time
|
||||
console.log("NixOS-managed configuration - ignoring runtime changes");
|
||||
}
|
||||
|
||||
JsonAdapter {
|
||||
id: configOptionsJsonAdapter
|
||||
|
||||
property JsonObject policies: JsonObject {
|
||||
property int ai: 1
|
||||
property int weeb: 1
|
||||
}
|
||||
|
||||
property JsonObject ai: JsonObject {
|
||||
property string systemPrompt: "## Style\n- Use casual tone, don't be formal! Make sure you answer precisely without hallucination and prefer bullet points over walls of text. You can have a friendly greeting at the beginning of the conversation, but don't repeat the user's question\n\n## Context (ignore when irrelevant)\n- You are a helpful and inspiring sidebar assistant on a NixOS Linux system\n- Desktop environment: Hyprland + dots-hyprland\n- Current date & time: {DATETIME}\n- Focused app: {WINDOWCLASS}\n\n## Presentation\n- Use Markdown features in your response"
|
||||
property string tool: "functions"
|
||||
property list<var> extraModels: []
|
||||
}
|
||||
|
||||
property JsonObject appearance: JsonObject {
|
||||
property bool extraBackgroundTint: ${boolToString cfg.appearance.extraBackgroundTint}
|
||||
property int fakeScreenRounding: ${toString cfg.appearance.fakeScreenRounding}
|
||||
property bool transparency: ${boolToString cfg.appearance.transparency}
|
||||
property JsonObject wallpaperTheming: JsonObject {
|
||||
property bool enableAppsAndShell: true
|
||||
property bool enableQtApps: true
|
||||
property bool enableTerminal: true
|
||||
}
|
||||
property JsonObject palette: JsonObject {
|
||||
property string type: "auto"
|
||||
}
|
||||
}
|
||||
|
||||
property JsonObject audio: JsonObject {
|
||||
property JsonObject protection: JsonObject {
|
||||
property bool enable: true
|
||||
property real maxAllowedIncrease: 10
|
||||
property real maxAllowed: 90
|
||||
}
|
||||
}
|
||||
|
||||
property JsonObject apps: JsonObject {
|
||||
property string bluetooth: "${cfg.apps.bluetooth}"
|
||||
property string network: "${cfg.apps.network}"
|
||||
property string networkEthernet: "kcmshell6 kcm_networkmanagement"
|
||||
property string taskManager: "${cfg.apps.taskManager}"
|
||||
property string terminal: "${cfg.apps.terminal}"
|
||||
}
|
||||
|
||||
property JsonObject background: JsonObject {
|
||||
property bool fixedClockPosition: false
|
||||
property real clockX: -500
|
||||
property real clockY: -500
|
||||
property string wallpaperPath: ""
|
||||
property string thumbnailPath: ""
|
||||
property JsonObject parallax: JsonObject {
|
||||
property bool enableWorkspace: true
|
||||
property real workspaceZoom: 1.07
|
||||
property bool enableSidebar: true
|
||||
}
|
||||
}
|
||||
|
||||
property JsonObject bar: JsonObject {
|
||||
property bool bottom: ${boolToString cfg.bar.bottom}
|
||||
property int cornerStyle: ${toString cfg.bar.cornerStyle}
|
||||
property bool borderless: ${boolToString cfg.bar.borderless}
|
||||
property string topLeftIcon: "${cfg.bar.topLeftIcon}"
|
||||
property bool showBackground: ${boolToString cfg.bar.showBackground}
|
||||
property bool verbose: ${boolToString cfg.bar.verbose}
|
||||
property JsonObject resources: JsonObject {
|
||||
property bool alwaysShowSwap: true
|
||||
property bool alwaysShowCpu: false
|
||||
}
|
||||
property list<string> screenList: []
|
||||
property JsonObject utilButtons: JsonObject {
|
||||
property bool showScreenSnip: ${boolToString cfg.bar.utilButtons.showScreenSnip}
|
||||
property bool showColorPicker: ${boolToString cfg.bar.utilButtons.showColorPicker}
|
||||
property bool showMicToggle: ${boolToString cfg.bar.utilButtons.showMicToggle}
|
||||
property bool showKeyboardToggle: ${boolToString cfg.bar.utilButtons.showKeyboardToggle}
|
||||
property bool showDarkModeToggle: ${boolToString cfg.bar.utilButtons.showDarkModeToggle}
|
||||
property bool showPerformanceProfileToggle: ${boolToString cfg.bar.utilButtons.showPerformanceProfileToggle}
|
||||
}
|
||||
property JsonObject tray: JsonObject {
|
||||
property bool monochromeIcons: true
|
||||
}
|
||||
property JsonObject workspaces: JsonObject {
|
||||
property bool monochromeIcons: ${boolToString cfg.bar.workspaces.monochromeIcons}
|
||||
property int shown: ${toString cfg.bar.workspaces.shown}
|
||||
property bool showAppIcons: ${boolToString cfg.bar.workspaces.showAppIcons}
|
||||
property bool alwaysShowNumbers: ${boolToString cfg.bar.workspaces.alwaysShowNumbers}
|
||||
property int showNumberDelay: ${toString cfg.bar.workspaces.showNumberDelay}
|
||||
}
|
||||
property JsonObject weather: JsonObject {
|
||||
property bool enable: false
|
||||
property bool enableGPS: true
|
||||
property string city: ""
|
||||
property bool useUSCS: false
|
||||
property int fetchInterval: 10
|
||||
}
|
||||
}
|
||||
|
||||
property JsonObject battery: JsonObject {
|
||||
property int low: ${toString cfg.battery.low}
|
||||
property int critical: ${toString cfg.battery.critical}
|
||||
property bool automaticSuspend: ${boolToString cfg.battery.automaticSuspend}
|
||||
property int suspend: ${toString cfg.battery.suspend}
|
||||
}
|
||||
|
||||
property JsonObject dock: JsonObject {
|
||||
property bool enable: false
|
||||
property bool monochromeIcons: true
|
||||
property real height: 60
|
||||
property real hoverRegionHeight: 2
|
||||
property bool pinnedOnStartup: false
|
||||
property bool hoverToReveal: true
|
||||
property list<string> pinnedApps: ["org.kde.dolphin", "kitty"]
|
||||
property list<string> ignoredAppRegexes: []
|
||||
}
|
||||
|
||||
property JsonObject language: JsonObject {
|
||||
property JsonObject translator: JsonObject {
|
||||
property string engine: "auto"
|
||||
property string targetLanguage: "auto"
|
||||
property string sourceLanguage: "auto"
|
||||
}
|
||||
}
|
||||
|
||||
property JsonObject light: JsonObject {
|
||||
property JsonObject night: JsonObject {
|
||||
property bool automatic: true
|
||||
property string from: "19:00"
|
||||
property string to: "06:30"
|
||||
property int colorTemperature: 5000
|
||||
}
|
||||
}
|
||||
|
||||
property JsonObject networking: JsonObject {
|
||||
property string userAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36"
|
||||
}
|
||||
|
||||
property JsonObject osd: JsonObject {
|
||||
property int timeout: 1000
|
||||
}
|
||||
|
||||
property JsonObject osk: JsonObject {
|
||||
property string layout: "qwerty_full"
|
||||
property bool pinnedOnStartup: false
|
||||
}
|
||||
|
||||
property JsonObject overview: JsonObject {
|
||||
property bool enable: true
|
||||
property real scale: 0.18
|
||||
property real rows: 2
|
||||
property real columns: 5
|
||||
}
|
||||
|
||||
property JsonObject resources: JsonObject {
|
||||
property int updateInterval: 3000
|
||||
}
|
||||
|
||||
property JsonObject search: JsonObject {
|
||||
property int nonAppResultDelay: 30
|
||||
property string engineBaseUrl: "https://www.google.com/search?q="
|
||||
property list<string> excludedSites: ["quora.com"]
|
||||
property bool sloppy: false
|
||||
property JsonObject prefix: JsonObject {
|
||||
property string action: "/"
|
||||
property string clipboard: ";"
|
||||
property string emojis: ":"
|
||||
}
|
||||
}
|
||||
|
||||
property JsonObject sidebar: JsonObject {
|
||||
property bool keepRightSidebarLoaded: true
|
||||
property JsonObject translator: JsonObject {
|
||||
property int delay: 300
|
||||
}
|
||||
property JsonObject booru: JsonObject {
|
||||
property bool allowNsfw: false
|
||||
property string defaultProvider: "yandere"
|
||||
property int limit: 20
|
||||
property JsonObject zerochan: JsonObject {
|
||||
property string username: "[unset]"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
property JsonObject time: JsonObject {
|
||||
property string format: "${cfg.time.format}"
|
||||
property string dateFormat: "${cfg.time.dateFormat}"
|
||||
}
|
||||
|
||||
property JsonObject windows: JsonObject {
|
||||
property bool showTitlebar: true
|
||||
property bool centerTitle: true
|
||||
}
|
||||
|
||||
property JsonObject hacks: JsonObject {
|
||||
property int arbitraryRaceConditionDelay: 20
|
||||
}
|
||||
|
||||
property JsonObject screenshotTool: JsonObject {
|
||||
property bool showContentRegions: true
|
||||
}
|
||||
}
|
||||
}
|
||||
'';
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,248 @@
|
||||
# Quickshell service integration with staging system
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.programs.dots-hyprland.quickshell;
|
||||
mainCfg = config.programs.dots-hyprland;
|
||||
|
||||
# Service startup script that handles initial setup
|
||||
# Note: quickshell must be in home.packages
|
||||
quickshellStartup = pkgs.writeShellScript "quickshell-startup" ''
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
# Colors for logging
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
RED='\033[0;31m'
|
||||
NC='\033[0m'
|
||||
|
||||
log() {
|
||||
echo -e "''${GREEN}[quickshell-service]''${NC} $1" >&2
|
||||
}
|
||||
|
||||
warn() {
|
||||
echo -e "''${YELLOW}[quickshell-service]''${NC} WARNING: $1" >&2
|
||||
}
|
||||
|
||||
error() {
|
||||
echo -e "''${RED}[quickshell-service]''${NC} ERROR: $1" >&2
|
||||
}
|
||||
|
||||
STAGING_DIR="$HOME/${mainCfg.writable-mode.stagingDir}"
|
||||
CONFIG_DIR="$HOME/.config"
|
||||
SETUP_SCRIPT="$HOME/${mainCfg.writable-mode.setupScript}"
|
||||
SETUP_MARKER="$HOME/.cache/dots-hyprland/setup-complete"
|
||||
|
||||
# Ensure cache directory exists
|
||||
mkdir -p "$(dirname "$SETUP_MARKER")"
|
||||
|
||||
# Check if initial setup has been run
|
||||
if [[ ! -f "$SETUP_MARKER" ]]; then
|
||||
log "🚀 First run detected - running initial setup"
|
||||
|
||||
# Check if staging directory exists
|
||||
if [[ ! -d "$STAGING_DIR" ]]; then
|
||||
error "Staging directory not found: $STAGING_DIR"
|
||||
error "Please run 'home-manager switch' first"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if setup script exists
|
||||
if [[ ! -x "$SETUP_SCRIPT" ]]; then
|
||||
error "Setup script not found or not executable: $SETUP_SCRIPT"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log "📋 Running initial setup script..."
|
||||
if "$SETUP_SCRIPT"; then
|
||||
# Mark setup as complete
|
||||
echo "$(date)" > "$SETUP_MARKER"
|
||||
log "✅ Initial setup completed successfully"
|
||||
else
|
||||
error "❌ Initial setup failed"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
log "✅ Setup already completed ($(cat "$SETUP_MARKER"))"
|
||||
fi
|
||||
|
||||
# Verify quickshell configuration exists
|
||||
if [[ ! -d "$CONFIG_DIR/quickshell" ]]; then
|
||||
error "Quickshell configuration not found at $CONFIG_DIR/quickshell"
|
||||
error "Initial setup may have failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Set up environment variables
|
||||
export ILLOGICAL_IMPULSE_VIRTUAL_ENV="$HOME/.local/state/quickshell/.venv"
|
||||
export QT_SCALE_FACTOR="${toString cfg.scaling}"
|
||||
export QT_QUICK_CONTROLS_STYLE="Basic"
|
||||
export QT_QUICK_FLICKABLE_WHEEL_DECELERATION="10000"
|
||||
|
||||
# Ensure PATH includes user applications - CRITICAL for app launching
|
||||
export PATH="${config.home.profileDirectory}/bin:/run/wrappers/bin:${config.home.homeDirectory}/.nix-profile/bin:/etc/profiles/per-user/${config.home.username}/bin:/nix/var/nix/profiles/default/bin:/run/current-system/sw/bin:$PATH"
|
||||
export XDG_DATA_DIRS="${config.home.profileDirectory}/share:${config.home.homeDirectory}/.nix-profile/share:/etc/profiles/per-user/${config.home.username}/share:/nix/var/nix/profiles/default/share:/run/current-system/sw/share:$XDG_DATA_DIRS"
|
||||
|
||||
# Create application launcher wrapper that quickshell can use
|
||||
LAUNCHER_WRAPPER="$HOME/.cache/dots-hyprland/app-launcher"
|
||||
mkdir -p "$(dirname "$LAUNCHER_WRAPPER")"
|
||||
cat > "$LAUNCHER_WRAPPER" << 'EOF'
|
||||
#!/usr/bin/env bash
|
||||
# Application launcher wrapper for quickshell
|
||||
# Ensures proper PATH and environment for launched applications
|
||||
|
||||
# Use the same PATH that quickshell has
|
||||
export PATH="${config.home.profileDirectory}/bin:/run/wrappers/bin:${config.home.homeDirectory}/.nix-profile/bin:/etc/profiles/per-user/${config.home.username}/bin:/nix/var/nix/profiles/default/bin:/run/current-system/sw/bin"
|
||||
export XDG_DATA_DIRS="${config.home.profileDirectory}/share:${config.home.homeDirectory}/.nix-profile/share:/etc/profiles/per-user/${config.home.username}/share:/nix/var/nix/profiles/default/share:/run/current-system/sw/share"
|
||||
|
||||
# Launch the application
|
||||
exec "$@"
|
||||
EOF
|
||||
chmod +x "$LAUNCHER_WRAPPER"
|
||||
|
||||
# Export the launcher wrapper path for quickshell to use
|
||||
export DOTS_HYPRLAND_APP_LAUNCHER="$LAUNCHER_WRAPPER"
|
||||
|
||||
# Verify Python virtual environment
|
||||
if [[ ! -d "$ILLOGICAL_IMPULSE_VIRTUAL_ENV" ]]; then
|
||||
warn "Python virtual environment not found at $ILLOGICAL_IMPULSE_VIRTUAL_ENV"
|
||||
warn "Some features may not work correctly"
|
||||
fi
|
||||
|
||||
log "🎯 Starting quickshell with dots-hyprland configuration"
|
||||
log "📁 Config: $CONFIG_DIR/quickshell/ii/shell.qml"
|
||||
log "🐍 Python venv: $ILLOGICAL_IMPULSE_VIRTUAL_ENV"
|
||||
log "🚀 App launcher: $LAUNCHER_WRAPPER"
|
||||
|
||||
# Set up Qt environment for dots-hyprland
|
||||
# Let quickshell use its own Qt libraries
|
||||
export XDG_DATA_DIRS="$XDG_DATA_DIRS:${pkgs.gsettings-desktop-schemas}/share"
|
||||
|
||||
# Start quickshell (from PATH - must be in home.packages)
|
||||
exec quickshell -p "$CONFIG_DIR/quickshell/ii/shell.qml"
|
||||
'';
|
||||
|
||||
in
|
||||
{
|
||||
options.programs.dots-hyprland.quickshell = {
|
||||
enable = mkEnableOption "Quickshell service with staging integration";
|
||||
|
||||
autoStart = mkEnableOption "Auto-start with Hyprland session" // { default = true; };
|
||||
|
||||
restartOnFailure = mkEnableOption "Restart service on failure" // { default = true; };
|
||||
|
||||
scaling = mkOption {
|
||||
type = types.float;
|
||||
default = 1.0;
|
||||
description = "UI scaling factor";
|
||||
};
|
||||
|
||||
logLevel = mkOption {
|
||||
type = types.enum [ "debug" "info" "warning" "error" ];
|
||||
default = "info";
|
||||
description = "Logging level for quickshell service";
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
# Install service management scripts (quickshell itself must be in home.packages)
|
||||
home.packages = (with pkgs; [
|
||||
(writeShellScriptBin "quickshell-restart" ''
|
||||
systemctl --user restart quickshell.service
|
||||
echo "✅ Quickshell service restarted"
|
||||
'')
|
||||
|
||||
(writeShellScriptBin "quickshell-status" ''
|
||||
echo "🔍 Quickshell Service Status"
|
||||
echo "=========================="
|
||||
systemctl --user status quickshell.service --no-pager
|
||||
echo ""
|
||||
echo "📋 Recent logs:"
|
||||
journalctl --user -u quickshell.service -n 10 --no-pager
|
||||
'')
|
||||
|
||||
(writeShellScriptBin "quickshell-logs" ''
|
||||
echo "📋 Following quickshell logs (Ctrl+C to exit):"
|
||||
journalctl --user -u quickshell.service -f
|
||||
'')
|
||||
|
||||
(writeShellScriptBin "quickshell-debug" ''
|
||||
echo "🐛 Starting quickshell in debug mode..."
|
||||
systemctl --user stop quickshell.service
|
||||
QT_LOGGING_RULES="quickshell.*=true" ${quickshellStartup}
|
||||
'')
|
||||
]);
|
||||
|
||||
# Systemd user service for quickshell
|
||||
systemd.user.services.quickshell = {
|
||||
Unit = {
|
||||
Description = "Quickshell - QtQuick based desktop shell with dots-hyprland";
|
||||
Documentation = [ "https://quickshell.org" "https://end-4.github.io/dots-hyprland-wiki/" ];
|
||||
PartOf = [ "hyprland-session.target" ];
|
||||
After = [ "hyprland-session.target" "graphical-session.target" ];
|
||||
Wants = [ "hyprland-session.target" ];
|
||||
};
|
||||
|
||||
Service = {
|
||||
Type = "simple";
|
||||
ExecStart = quickshellStartup;
|
||||
ExecReload = "${pkgs.coreutils}/bin/kill -SIGUSR2 $MAINPID";
|
||||
Restart = if cfg.restartOnFailure then "on-failure" else "no";
|
||||
RestartSec = 2;
|
||||
TimeoutStartSec = 30;
|
||||
TimeoutStopSec = 10;
|
||||
|
||||
# Environment variables - include full user environment
|
||||
PassEnvironment = [ "HYPRLAND_INSTANCE_SIGNATURE" "WAYLAND_DISPLAY" ];
|
||||
Environment = [
|
||||
"QT_SCALE_FACTOR=${toString cfg.scaling}"
|
||||
"QT_QUICK_CONTROLS_STYLE=Basic"
|
||||
"QT_QUICK_FLICKABLE_WHEEL_DECELERATION=10000"
|
||||
"QT_LOGGING_RULES=${
|
||||
if cfg.logLevel == "debug" then "quickshell.*=true"
|
||||
else if cfg.logLevel == "warning" then "*.warning=true"
|
||||
else if cfg.logLevel == "error" then "*.critical=true"
|
||||
else "*.info=true"
|
||||
}"
|
||||
# Include user's full PATH so applications can be launched
|
||||
"PATH=${config.home.profileDirectory}/bin:/run/wrappers/bin:${config.home.homeDirectory}/.nix-profile/bin:/etc/profiles/per-user/${config.home.username}/bin:/nix/var/nix/profiles/default/bin:/run/current-system/sw/bin"
|
||||
# Include XDG data directories for application discovery
|
||||
"XDG_DATA_DIRS=${config.home.profileDirectory}/share:${config.home.homeDirectory}/.nix-profile/share:/etc/profiles/per-user/${config.home.username}/share:/nix/var/nix/profiles/default/share:/run/current-system/sw/share"
|
||||
# Application launcher wrapper path
|
||||
"DOTS_HYPRLAND_APP_LAUNCHER=%h/.cache/dots-hyprland/app-launcher"
|
||||
];
|
||||
|
||||
# Working directory
|
||||
WorkingDirectory = "%h";
|
||||
|
||||
# Security settings
|
||||
PrivateNetwork = false;
|
||||
ProtectSystem = "strict";
|
||||
ProtectHome = false; # Need access to home directory
|
||||
NoNewPrivileges = true;
|
||||
|
||||
# Resource limits
|
||||
MemoryMax = "2G";
|
||||
CPUQuota = "200%";
|
||||
};
|
||||
|
||||
Install = mkIf cfg.autoStart {
|
||||
WantedBy = [ "hyprland-session.target" ];
|
||||
};
|
||||
};
|
||||
|
||||
# Create hyprland session target if it doesn't exist
|
||||
systemd.user.targets.hyprland-session = {
|
||||
Unit = {
|
||||
Description = "Hyprland compositor session";
|
||||
Documentation = [ "man:systemd.special(7)" ];
|
||||
BindsTo = [ "graphical-session.target" ];
|
||||
Wants = [ "graphical-session-pre.target" ];
|
||||
After = [ "graphical-session-pre.target" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
# System services required for dots-hyprland
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
{
|
||||
# UPower for battery monitoring in quickshell bar
|
||||
services.upower.enable = lib.mkDefault true;
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
# Terminal configuration options for dots-hyprland
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.programs.dots-hyprland.terminal;
|
||||
in
|
||||
{
|
||||
options.programs.dots-hyprland.terminal = {
|
||||
# Terminal settings
|
||||
scrollback = {
|
||||
lines = mkOption {
|
||||
type = types.int;
|
||||
default = 1000;
|
||||
description = "Number of scrollback lines";
|
||||
};
|
||||
|
||||
multiplier = mkOption {
|
||||
type = types.float;
|
||||
default = 3.0;
|
||||
description = "Scrollback multiplier";
|
||||
};
|
||||
};
|
||||
|
||||
cursor = {
|
||||
style = mkOption {
|
||||
type = types.enum [ "block" "beam" "underline" ];
|
||||
default = "beam";
|
||||
description = "Cursor style";
|
||||
};
|
||||
|
||||
blink = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Enable cursor blinking";
|
||||
};
|
||||
|
||||
beamThickness = mkOption {
|
||||
type = types.float;
|
||||
default = 1.5;
|
||||
description = "Beam cursor thickness";
|
||||
};
|
||||
};
|
||||
|
||||
colors = {
|
||||
alpha = mkOption {
|
||||
type = types.float;
|
||||
default = 0.95;
|
||||
description = "Terminal transparency (0.0 - 1.0)";
|
||||
};
|
||||
};
|
||||
|
||||
mouse = {
|
||||
hideWhenTyping = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Hide mouse cursor when typing";
|
||||
};
|
||||
|
||||
alternateScrollMode = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "Enable alternate scroll mode";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# Foot configuration disabled - let Quickshell transparency system handle it dynamically
|
||||
config = {};
|
||||
}
|
||||
@@ -0,0 +1,271 @@
|
||||
# Touchegg gesture support for dots-hyprland
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.programs.dots-hyprland.touchegg;
|
||||
mainCfg = config.programs.dots-hyprland;
|
||||
in
|
||||
{
|
||||
options.programs.dots-hyprland.touchegg = {
|
||||
enable = mkEnableOption "Touchegg gesture support";
|
||||
|
||||
config = mkOption {
|
||||
type = types.lines;
|
||||
default = ''
|
||||
<touchégg>
|
||||
<settings>
|
||||
<property name="animation_delay">150</property>
|
||||
<property name="action_execute_threshold">80</property>
|
||||
<property name="color">auto</property>
|
||||
<property name="borderColor">auto</property>
|
||||
</settings>
|
||||
<application name="All">
|
||||
<!-- 3-finger pinch in: Close window -->
|
||||
<gesture type="PINCH" fingers="3" direction="IN">
|
||||
<action type="CLOSE_WINDOW">
|
||||
<animate>true</animate>
|
||||
<color>F84A53</color>
|
||||
<borderColor>F84A53</borderColor>
|
||||
</action>
|
||||
</gesture>
|
||||
|
||||
<!-- 2-finger tap: Right click -->
|
||||
<gesture type="TAP" fingers="2" direction="UNKNOWN">
|
||||
<action type="MOUSE_CLICK">
|
||||
<button>3</button>
|
||||
<on>begin</on>
|
||||
</action>
|
||||
</gesture>
|
||||
|
||||
<!-- 3-finger tap: Middle click -->
|
||||
<gesture type="TAP" fingers="3" direction="UNKNOWN">
|
||||
<action type="MOUSE_CLICK">
|
||||
<button>2</button>
|
||||
<on>begin</on>
|
||||
</action>
|
||||
</gesture>
|
||||
|
||||
<!-- 4-finger pinch in: Fullscreen mode 0 -->
|
||||
<gesture type="PINCH" fingers="4" direction="IN">
|
||||
<action type="RUN_COMMAND">
|
||||
<command>hyprctl dispatch fullscreen 0</command>
|
||||
<repeat>false</repeat>
|
||||
<animation>NONE</animation>
|
||||
<on>begin</on>
|
||||
</action>
|
||||
</gesture>
|
||||
|
||||
<!-- 4-finger pinch out: Fullscreen mode 1 -->
|
||||
<gesture type="PINCH" fingers="4" direction="OUT">
|
||||
<action type="RUN_COMMAND">
|
||||
<command>hyprctl dispatch fullscreen 1</command>
|
||||
<repeat>false</repeat>
|
||||
<animation>NONE</animation>
|
||||
<on>begin</on>
|
||||
</action>
|
||||
</gesture>
|
||||
|
||||
<!-- Note: 3-finger left/right swipes removed - handled by Hyprland's built-in workspace_swipe -->
|
||||
|
||||
<!-- 3-finger swipe up: Show overview -->
|
||||
<gesture type="SWIPE" fingers="3" direction="UP">
|
||||
<action type="RUN_COMMAND">
|
||||
<command>hyprctl dispatch global quickshell:overviewToggle</command>
|
||||
<repeat>false</repeat>
|
||||
<animation>NONE</animation>
|
||||
<on>begin</on>
|
||||
</action>
|
||||
</gesture>
|
||||
|
||||
<!-- 3-finger swipe down: Show all windows -->
|
||||
<gesture type="SWIPE" fingers="3" direction="DOWN">
|
||||
<action type="RUN_COMMAND">
|
||||
<command>hyprctl dispatch overview</command>
|
||||
<repeat>false</repeat>
|
||||
<animation>NONE</animation>
|
||||
<on>begin</on>
|
||||
</action>
|
||||
</gesture>
|
||||
|
||||
<!-- 4-finger swipe left: Move window left -->
|
||||
<gesture type="SWIPE" fingers="4" direction="LEFT">
|
||||
<action type="RUN_COMMAND">
|
||||
<command>hyprctl dispatch movewindow l</command>
|
||||
<repeat>false</repeat>
|
||||
<animation>NONE</animation>
|
||||
<on>begin</on>
|
||||
</action>
|
||||
</gesture>
|
||||
|
||||
<!-- 4-finger swipe right: Move window right -->
|
||||
<gesture type="SWIPE" fingers="4" direction="RIGHT">
|
||||
<action type="RUN_COMMAND">
|
||||
<command>hyprctl dispatch movewindow r</command>
|
||||
<repeat>false</repeat>
|
||||
<animation>NONE</animation>
|
||||
<on>begin</on>
|
||||
</action>
|
||||
</gesture>
|
||||
|
||||
<!-- 4-finger swipe up: Move window up -->
|
||||
<gesture type="SWIPE" fingers="4" direction="UP">
|
||||
<action type="RUN_COMMAND">
|
||||
<command>hyprctl dispatch movewindow u</command>
|
||||
<repeat>false</repeat>
|
||||
<animation>NONE</animation>
|
||||
<on>begin</on>
|
||||
</action>
|
||||
</gesture>
|
||||
|
||||
<!-- 4-finger swipe down: Move window down -->
|
||||
<gesture type="SWIPE" fingers="4" direction="DOWN">
|
||||
<action type="RUN_COMMAND">
|
||||
<command>hyprctl dispatch movewindow d</command>
|
||||
<repeat>false</repeat>
|
||||
<animation>NONE</animation>
|
||||
<on>begin</on>
|
||||
</action>
|
||||
</gesture>
|
||||
</application>
|
||||
|
||||
<!-- Browser-specific gestures for zoom -->
|
||||
<application name="chromium-browser">
|
||||
<gesture type="PINCH" fingers="2" direction="IN">
|
||||
<action type="SEND_KEYS">
|
||||
<repeat>true</repeat>
|
||||
<modifiers>Control_L</modifiers>
|
||||
<keys>KP_Subtract</keys>
|
||||
<decreaseKeys>KP_Add</decreaseKeys>
|
||||
</action>
|
||||
</gesture>
|
||||
<gesture type="PINCH" fingers="2" direction="OUT">
|
||||
<action type="SEND_KEYS">
|
||||
<repeat>true</repeat>
|
||||
<modifiers>Control_L</modifiers>
|
||||
<keys>KP_Add</keys>
|
||||
<decreaseKeys>KP_Subtract</decreaseKeys>
|
||||
</action>
|
||||
</gesture>
|
||||
</application>
|
||||
|
||||
<application name="google-chrome">
|
||||
<gesture type="PINCH" fingers="2" direction="IN">
|
||||
<action type="SEND_KEYS">
|
||||
<repeat>true</repeat>
|
||||
<modifiers>Control_L</modifiers>
|
||||
<keys>KP_Subtract</keys>
|
||||
<decreaseKeys>KP_Add</decreaseKeys>
|
||||
</action>
|
||||
</gesture>
|
||||
<gesture type="PINCH" fingers="2" direction="OUT">
|
||||
<action type="SEND_KEYS">
|
||||
<repeat>true</repeat>
|
||||
<modifiers>Control_L</modifiers>
|
||||
<keys>KP_Add</keys>
|
||||
<decreaseKeys>KP_Subtract</decreaseKeys>
|
||||
</action>
|
||||
</gesture>
|
||||
</application>
|
||||
|
||||
<application name="firefox">
|
||||
<gesture type="PINCH" fingers="2" direction="IN">
|
||||
<action type="SEND_KEYS">
|
||||
<repeat>true</repeat>
|
||||
<modifiers>Control_L</modifiers>
|
||||
<keys>KP_Subtract</keys>
|
||||
<decreaseKeys>KP_Add</decreaseKeys>
|
||||
</action>
|
||||
</gesture>
|
||||
<gesture type="PINCH" fingers="2" direction="OUT">
|
||||
<action type="SEND_KEYS">
|
||||
<repeat>true</repeat>
|
||||
<modifiers>Control_L</modifiers>
|
||||
<keys>KP_Add</keys>
|
||||
<decreaseKeys>KP_Subtract</decreaseKeys>
|
||||
</action>
|
||||
</gesture>
|
||||
</application>
|
||||
</touchégg>
|
||||
'';
|
||||
description = "Touchegg configuration XML";
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
# Note: touchegg service needs to be enabled at system level
|
||||
# Add this to your NixOS configuration: services.touchegg.enable = true;
|
||||
|
||||
# Install touchegg configuration (both user and system locations)
|
||||
xdg.configFile."touchegg/touchegg.conf" = {
|
||||
text = cfg.config;
|
||||
};
|
||||
|
||||
# Also create system config that touchegg service can read
|
||||
# Note: This requires the touchegg service to be enabled at system level
|
||||
home.activation.toucheggSystemConfig = lib.hm.dag.entryAfter ["writeBoundary"] ''
|
||||
echo "📄 Creating system-wide touchegg configuration..."
|
||||
$DRY_RUN_CMD sudo mkdir -p /etc/touchegg
|
||||
$DRY_RUN_CMD sudo cp ${config.xdg.configHome}/touchegg/touchegg.conf /etc/touchegg/touchegg.conf
|
||||
echo "✅ System touchegg config updated"
|
||||
'';
|
||||
|
||||
# Create touchegg client service (required for gesture execution)
|
||||
systemd.user.services.touchegg-client = {
|
||||
Unit = {
|
||||
Description = "Touchegg Client";
|
||||
After = [ "graphical-session.target" ];
|
||||
};
|
||||
|
||||
Service = {
|
||||
Type = "simple";
|
||||
ExecStart = "${pkgs.touchegg}/bin/touchegg --client";
|
||||
Restart = "on-failure";
|
||||
RestartSec = 3;
|
||||
};
|
||||
|
||||
Install = {
|
||||
WantedBy = [ "default.target" ];
|
||||
};
|
||||
};
|
||||
|
||||
# Install touchegg and management scripts
|
||||
home.packages = [ pkgs.touchegg ] ++ [
|
||||
(pkgs.writeShellScriptBin "touchegg-restart" ''
|
||||
echo "🔄 Restarting touchegg service..."
|
||||
sudo systemctl restart touchegg
|
||||
echo "✅ Touchegg restarted"
|
||||
'')
|
||||
|
||||
(pkgs.writeShellScriptBin "touchegg-status" ''
|
||||
echo "📊 Touchegg service status:"
|
||||
systemctl status touchegg --no-pager
|
||||
echo ""
|
||||
echo "📄 Touchegg configuration:"
|
||||
echo " ~/.config/touchegg/touchegg.conf"
|
||||
if [[ -f ~/.config/touchegg/touchegg.conf ]]; then
|
||||
echo " ✅ Configuration file exists"
|
||||
else
|
||||
echo " ❌ Configuration file missing"
|
||||
fi
|
||||
'')
|
||||
|
||||
(pkgs.writeShellScriptBin "touchegg-reload-config" ''
|
||||
echo "🔄 Reloading touchegg configuration..."
|
||||
if systemctl is-active touchegg >/dev/null 2>&1; then
|
||||
sudo systemctl reload touchegg 2>/dev/null || sudo systemctl restart touchegg
|
||||
echo "✅ Touchegg configuration reloaded"
|
||||
else
|
||||
echo "❌ Touchegg service is not running"
|
||||
echo "💡 Try: sudo systemctl start touchegg"
|
||||
fi
|
||||
'')
|
||||
];
|
||||
|
||||
# Session variables for touchegg
|
||||
home.sessionVariables = {
|
||||
TOUCHEGG_CONFIG_PATH = "$HOME/.config/touchegg/touchegg.conf";
|
||||
};
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user