diff --git a/flake.lock b/flake.lock index 0450565..8bacf94 100644 --- a/flake.lock +++ b/flake.lock @@ -150,11 +150,11 @@ "blocklist-hosts": { "flake": false, "locked": { - "lastModified": 1723813990, - "narHash": "sha256-90NnU1Bo9nfwiLxF1DSXB3H293zPv6NBITtIwNuIGgE=", + "lastModified": 1722815760, + "narHash": "sha256-BsAKFrj6Js8QY2j/bdydhS0DhJwfHSnLRZjaK9pLy8w=", "owner": "StevenBlack", "repo": "hosts", - "rev": "b2b0b69d3c8e072f9f0a0ed2b6e264fa4d97dc32", + "rev": "8bb5a4f6e2a9f902f44623d1cdf533428bfa10b2", "type": "github" }, "original": { @@ -390,7 +390,7 @@ }, "flake-utils": { "inputs": { - "systems": "systems_4" + "systems": "systems_3" }, "locked": { "lastModified": 1710146030, @@ -408,7 +408,7 @@ }, "flake-utils_2": { "inputs": { - "systems": "systems_5" + "systems": "systems_4" }, "locked": { "lastModified": 1694529238, @@ -538,11 +538,11 @@ ] }, "locked": { - "lastModified": 1723399884, - "narHash": "sha256-97wn0ihhGqfMb8WcUgzzkM/TuAxce2Gd20A8oiruju4=", + "lastModified": 1723015306, + "narHash": "sha256-jQnFEtH20/OsDPpx71ntZzGdRlpXhUENSQCGTjn//NA=", "owner": "nix-community", "repo": "home-manager", - "rev": "086f619dd991a4d355c07837448244029fc2d9ab", + "rev": "b3d5ea65d88d67d4ec578ed11d4d2d51e3de525e", "type": "github" }, "original": { @@ -618,6 +618,7 @@ "locked": { "lastModified": 1723484486, "narHash": "sha256-YRU0egH+7Wv2Ehln0Q7bjdVayJ8rQxrTmuf23oJ/bQ4=", + "ref": "refs/heads/main", "rev": "c7b72790bd63172f04ee86784d4cb2a400532927", "revCount": 5082, "submodules": true, @@ -650,7 +651,6 @@ "locked": { "lastModified": 1723143591, "narHash": "sha256-dPcWAeRJoG5CyWC32X3XX+Og0v/k1/S1N0T5dQWT32k=", - "ref": "refs/heads/main", "rev": "b73d7b901d8cb1172dd25c7b7159f0242c625a77", "revCount": 192, "type": "git", @@ -759,6 +759,7 @@ "locked": { "lastModified": 1721822339, "narHash": "sha256-dkhgyxPxmOI/ZHk/LZRQZAVjtk9kPx2RFQRnuEoXQ4s=", + "ref": "refs/heads/main", "rev": "58e1a4a4997728be886a46d031514b3f09763c5d", "revCount": 234, "type": "git", @@ -860,27 +861,6 @@ "type": "indirect" } }, - "kwin-effects-forceblur": { - "inputs": { - "nixpkgs": [ - "nixpkgs" - ], - "utils": "utils" - }, - "locked": { - "lastModified": 1723568262, - "narHash": "sha256-CvJmxLjxNi4VxGV4YSoAQCQPFCFBjejWx+EuX94BBps=", - "owner": "taj-ny", - "repo": "kwin-effects-forceblur", - "rev": "4500adb340b7f9a28e2e7e1b47d13d58e3ffefac", - "type": "github" - }, - "original": { - "owner": "taj-ny", - "repo": "kwin-effects-forceblur", - "type": "github" - } - }, "lix": { "flake": false, "locked": { @@ -1068,11 +1048,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1723637854, - "narHash": "sha256-med8+5DSWa2UnOqtdICndjDAEjxr5D7zaIiK4pn0Q7c=", + "lastModified": 1722813957, + "narHash": "sha256-IAoYyYnED7P8zrBFMnmp7ydaJfwTnwcnqxUElC1I26Y=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "c3aa7b8938b17aebd2deecf7be0636000d62a2b9", + "rev": "cb9a96f23c491c081b38eab96d22fa958043c9fa", "type": "github" }, "original": { @@ -1115,11 +1095,11 @@ }, "nixpkgs-stable": { "locked": { - "lastModified": 1723688146, - "narHash": "sha256-sqLwJcHYeWLOeP/XoLwAtYjr01TISlkOfz+NG82pbdg=", + "lastModified": 1722869614, + "narHash": "sha256-7ojM1KSk3mzutD7SkrdSflHXEujPvW1u7QuqWoTLXQU=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "c3d4ac725177c030b1e289015989da2ad9d56af0", + "rev": "883180e6550c1723395a3a342f830bfc5c371f6b", "type": "github" }, "original": { @@ -1344,11 +1324,11 @@ "org-timeblock": { "flake": false, "locked": { - "lastModified": 1723239268, - "narHash": "sha256-D6GWpmF2fMZGvZ3Jonf4B+yyFTxBv4m5mxmfOVFNm60=", + "lastModified": 1707720561, + "narHash": "sha256-aSZWSlKdYwx62h6cXCDHOyLJMG1/Ls9zANyTSG04AuA=", "owner": "ichernyshovvv", "repo": "org-timeblock", - "rev": "e5b3614633f45d059239c6c6e9379803064936ce", + "rev": "b423b01712b9c25dff3e4203c7cde736225f62ef", "type": "github" }, "original": { @@ -1437,29 +1417,6 @@ "type": "github" } }, - "plasma-manager": { - "inputs": { - "home-manager": [ - "home-manager-unstable" - ], - "nixpkgs": [ - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1723804780, - "narHash": "sha256-uuiu1UAfYr2Lo+5Ul6eA0UIYouoPvH9aIfYbq7wVF6c=", - "owner": "pjones", - "repo": "plasma-manager", - "rev": "8726ecaa8b8c06910ef31abced57bf08a59730a1", - "type": "github" - }, - "original": { - "owner": "pjones", - "repo": "plasma-manager", - "type": "github" - } - }, "revealjs": { "flake": false, "locked": { @@ -1489,7 +1446,6 @@ "hyprland-plugins": "hyprland-plugins", "hyprlock": "hyprlock", "kdenlive-pin-nixpkgs": "kdenlive-pin-nixpkgs", - "kwin-effects-forceblur": "kwin-effects-forceblur", "lix-module": "lix-module", "magit-file-icons": "magit-file-icons", "mini-frame": "mini-frame", @@ -1507,7 +1463,6 @@ "org-xournalpp": "org-xournalpp", "org-yaap": "org-yaap", "phscroll": "phscroll", - "plasma-manager": "plasma-manager", "rust-overlay": "rust-overlay", "stylix": "stylix" } @@ -1533,11 +1488,11 @@ "nixpkgs": "nixpkgs_2" }, "locked": { - "lastModified": 1723774846, - "narHash": "sha256-m53hVat6XXiKooV1oUDEMnPcdNKqSn/kAW+g8juSq84=", + "lastModified": 1723083652, + "narHash": "sha256-ait+SeO67n8b3lIaBWwuzVX6F1zyTJ0cY6cHWtvhTyc=", "owner": "oxalica", "repo": "rust-overlay", - "rev": "519f4892641bc04a6ac7c2d260cc68356f9ae90f", + "rev": "69e0ad9289fc08ee5a313fb107f00e0f21e7cbb2", "type": "github" }, "original": { @@ -1666,21 +1621,6 @@ "type": "github" } }, - "systems_5": { - "locked": { - "lastModified": 1681028828, - "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", - "owner": "nix-systems", - "repo": "default", - "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", - "type": "github" - }, - "original": { - "owner": "nix-systems", - "repo": "default", - "type": "github" - } - }, "ts-fold": { "flake": false, "locked": { @@ -1697,24 +1637,6 @@ "type": "github" } }, - "utils": { - "inputs": { - "systems": "systems_3" - }, - "locked": { - "lastModified": 1710146030, - "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" - } - }, "ws-butler": { "flake": false, "locked": { diff --git a/flake.nix b/flake.nix index 37ae911..c1486b4 100644 --- a/flake.nix +++ b/flake.nix @@ -25,7 +25,7 @@ theme = "io"; # selcted theme from my themes directory (./themes/) wm = "hyprland"; # Selected window manager or desktop environment; must select one in both ./user/wm/ and ./system/wm/ # window manager type (hyprland or x11) translator - wmType = if ((wm == "hyprland") || (wm == "plasma")) then "wayland" else "x11"; + wmType = if (wm == "hyprland") then "wayland" else "x11"; browser = "qutebrowser"; # Default browser; must select one from ./user/app/browser/ spawnBrowser = if ((browser == "qutebrowser") && (wm == "hyprland")) then "qutebrowser-hyprprofile" else (if (browser == "qutebrowser") then "qutebrowser --qt-flag enable-gpu-rasterization --qt-flag enable-native-gpu-memory-buffers --qt-flag num-raster-threads=4" else browser); # Browser spawn command must be specail for qb, since it doesn't gpu accelerate by default (why?) defaultRoamDir = "Personal.p"; # Default org roam directory relative to ~/Org @@ -246,13 +246,6 @@ hyprgrass.url = "github:horriblename/hyprgrass/0bb3b822053c813ab6f695c9194089ccb5186cc3"; hyprgrass.inputs.hyprland.follows = "hyprland"; - plasma-manager.url = "github:pjones/plasma-manager"; - plasma-manager.inputs.nixpkgs.follows = "nixpkgs"; - plasma-manager.inputs.home-manager.follows = "home-manager-unstable"; - - kwin-effects-forceblur.url = "github:taj-ny/kwin-effects-forceblur"; - kwin-effects-forceblur.inputs.nixpkgs.follows = "nixpkgs"; - # FIXME emacsng doesn't build or dumps core #emacsng.url = "github:emacs-ng/emacs-ng/58fcf8c"; #emacsng.inputs.nixpkgs.follows = "nixpkgs"; diff --git a/system/wm/hyprland.nix b/system/wm/hyprland.nix index 4815bad..0719a23 100644 --- a/system/wm/hyprland.nix +++ b/system/wm/hyprland.nix @@ -25,22 +25,9 @@ in portalPackage = pkgs-hyprland.xdg-desktop-portal-hyprland; }; }; - environment = { plasma5.excludePackages = [ pkgs.kdePackages.systemsettings ]; plasma6.excludePackages = [ pkgs.kdePackages.systemsettings ]; }; - services.xserver.excludePackages = [ pkgs.xterm ]; - - services.xserver = { - displayManager.sddm = { - enable = true; - wayland.enable = true; - enableHidpi = true; - theme = "chili"; - package = pkgs.sddm; - }; - - }; } diff --git a/system/wm/plasma.nix b/system/wm/plasma.nix deleted file mode 100644 index ed2f443..0000000 --- a/system/wm/plasma.nix +++ /dev/null @@ -1,43 +0,0 @@ -{ inputs, pkgs, lib, ... }: -{ - # Import wayland config - imports = [ ./wayland.nix - ./pipewire.nix - ./dbus.nix - ]; - - # Enable the KDE Plasma Desktop Environment. - services.xserver.displayManager.sddm.enable = true; - services.xserver.displayManager.sddm.wayland.enable = true; - services.desktopManager.plasma6.enable = true; - - # Configure keymap in X11 - services.xserver = { - enable = true; - layout = "us"; - xkbVariant = ""; - xkbOptions = "caps:escape"; - }; - - services.xserver.excludePackages = [ pkgs.xterm ]; - - services.tlp.enable = lib.mkForce false; - - environment.systemPackages = with pkgs; [ - inputs.kwin-effects-forceblur.packages.${pkgs.system}.default - kdePackages.kscreen - kdePackages.kirigami - kdePackages.plasma-desktop - kdePackages.plasma-workspace - kdePackages.kcmutils - qt6.qtwayland - ]; - - # Security - security = { - pam.services.login.enableGnomeKeyring = true; - }; - - services.gnome.gnome-keyring.enable = true; - -} diff --git a/system/wm/wayland.nix b/system/wm/wayland.nix index 3234013..35e8b7c 100644 --- a/system/wm/wayland.nix +++ b/system/wm/wayland.nix @@ -28,5 +28,12 @@ variant = ""; options = "caps:escape"; }; + displayManager.sddm = { + enable = true; + wayland.enable = true; + enableHidpi = true; + theme = "chili"; + package = pkgs.sddm; + }; }; } diff --git a/system/wm/xmonad.nix b/system/wm/xmonad.nix new file mode 100644 index 0000000..e820f92 --- /dev/null +++ b/system/wm/xmonad.nix @@ -0,0 +1,20 @@ +{ ... }: + +{ + # import X11 config + imports = [ ./x11.nix + ./pipewire.nix + ./dbus.nix + ]; + + # Setup XMonad + services.xserver = { + windowManager.xmonad = { + enable = true; + enableContribAndExtras = true; + }; + displayManager = { + defaultSession = "none+xmonad"; + }; + }; +} diff --git a/user/wm/hyprland/hyprland.nix b/user/wm/hyprland/hyprland.nix index a310a68..57c3de8 100644 --- a/user/wm/hyprland/hyprland.nix +++ b/user/wm/hyprland/hyprland.nix @@ -346,7 +346,7 @@ in bind=SUPERSHIFT,P,exec,hyprprofile-dmenu # 3 monitor setup - monitor=eDP-1,1920x1080@300,900x1080,1 + monitor=eDP-1,1920x1080,900x1080,1 monitor=HDMI-A-1,1920x1080,1920x0,1 monitor=DP-1,1920x1080,0x0,1 @@ -595,6 +595,7 @@ in calc draw krita + pinta xournalpp obs kdenlive diff --git a/user/wm/picom/README.org b/user/wm/picom/README.org new file mode 100644 index 0000000..11a03de --- /dev/null +++ b/user/wm/picom/README.org @@ -0,0 +1,9 @@ +#+title: Picom + +This is my picom config. I use [[https://github.com/pijulius/picom][pijulius' picom]] which has awesome animations! + +[[picom.gif]] + +There are 2 main files in this directory: +- [[./picom.conf][picom.conf]] - My picom config +- [[./picom.nix][picom.nix]] - A Nix module to import the pijulius fork of picom into my setup via the import block of my [[../../home.nix][home.nix]] diff --git a/user/wm/picom/picom.conf b/user/wm/picom/picom.conf new file mode 100644 index 0000000..e22fe03 --- /dev/null +++ b/user/wm/picom/picom.conf @@ -0,0 +1,504 @@ +################################# +# Animations # +################################# +# requires https://github.com/jonaburg/picom +# (These are also the default values) +transition-length = 1 +transition-pow-x = 1 +transition-pow-y = 1 +transition-pow-w = 1 +transition-pow-h = 1 +size-transition = true + + +################################# +# Corners # +################################# +# requires: https://github.com/sdhand/compton or https://github.com/jonaburg/picom +corner-radius = 0.0; +rounded-corners-exclude = [ + #"window_type = 'normal'", + "class_g = 'awesome'", + "class_g = 'Xmobar'", + "class_g = 'xmobar'", + "window_type = 'dock'" +]; +round-borders = 10; +round-borders-exclude = [ + #"class_g = 'TelegramDesktop'", +]; + +################################# +# Shadows # +################################# + + +# Enabled client-side shadows on windows. Note desktop windows +# (windows with '_NET_WM_WINDOW_TYPE_DESKTOP') never get shadow, +# unless explicitly requested using the wintypes option. +# +shadow = false +# shadow = true; + +# The blur radius for shadows, in pixels. (defaults to 12) +# shadow-radius = 12 +shadow-radius = 7; + +# The opacity of shadows. (0.0 - 1.0, defaults to 0.75) +shadow-opacity = .75 + +# The left offset for shadows, in pixels. (defaults to -15) +# shadow-offset-x = -15 +shadow-offset-x = -7; + +# The top offset for shadows, in pixels. (defaults to -15) +# shadow-offset-y = -15 +shadow-offset-y = -7; + +# Avoid drawing shadows on dock/panel windows. This option is deprecated, +# you should use the *wintypes* option in your config file instead. +# +# no-dock-shadow = false + +# Don't draw shadows on drag-and-drop windows. This option is deprecated, +# you should use the *wintypes* option in your config file instead. +# +# no-dnd-shadow = false + +# Red color value of shadow (0.0 - 1.0, defaults to 0). +# shadow-red = 0 + +# Green color value of shadow (0.0 - 1.0, defaults to 0). +# shadow-green = 0 + +# Blue color value of shadow (0.0 - 1.0, defaults to 0). +# shadow-blue = 0 + +# Do not paint shadows on shaped windows. Note shaped windows +# here means windows setting its shape through X Shape extension. +# Those using ARGB background is beyond our control. +# Deprecated, use +# shadow-exclude = 'bounding_shaped' +# or +# shadow-exclude = 'bounding_shaped && !rounded_corners' +# instead. +# +# shadow-ignore-shaped = '' + +# Specify a list of conditions of windows that should have no shadow. +# +# examples: +# shadow-exclude = "n:e:Notification"; +# +# shadow-exclude = [] +shadow-exclude = [ + "name = 'Notification'", + "class_g = 'Conky'", + "class_g ?= 'Notify-osd'", + "class_g = 'Cairo-clock'", + "class_g = 'slop'", + "class_g = 'Polybar'", + "_GTK_FRAME_EXTENTS@:c" +]; + +# Specify a X geometry that describes the region in which shadow should not +# be painted in, such as a dock window region. Use +# shadow-exclude-reg = "x10+0+0" +# for example, if the 10 pixels on the bottom of the screen should not have shadows painted on. +# +# shadow-exclude-reg = "" + +# Crop shadow of a window fully on a particular Xinerama screen to the screen. +# xinerama-shadow-crop = false + + +################################# +# Fading # +################################# + +# Fade windows in/out when opening/closing and when opacity changes, +# unless no-fading-openclose is used. +# fading = false +fading = false; + +# Opacity change between steps while fading in. (0.01 - 1.0, defaults to 0.028) +# fade-in-step = 0.028 +fade-in-step = 0.01; + +# Opacity change between steps while fading out. (0.01 - 1.0, defaults to 0.03) +# fade-out-step = 0.03 +fade-out-step = 0.01; + +# The time between steps in fade step, in milliseconds. (> 0, defaults to 10) +fade-delta = 1 + +# Specify a list of conditions of windows that should not be faded. +# don't need this, we disable fading for all normal windows with wintypes: {} +fade-exclude = [ +## "class_g = 'slop'" # maim +] + +# Do not fade on window open/close. +no-fading-openclose = false + +# Do not fade destroyed ARGB windows with WM frame. Workaround of bugs in Openbox, Fluxbox, etc. +no-fading-destroyed-argb = false + + +################################# +# Transparency / Opacity # +################################# + + +# Opacity of inactive windows. (0.1 - 1.0, defaults to 1.0) +# inactive-opacity = 1 +inactive-opacity = 1.0; + +# Opacity of window titlebars and borders. (0.1 - 1.0, disabled by default) +# frame-opacity = 1.0 + +# Default opacity for dropdown menus and popup menus. (0.0 - 1.0, defaults to 1.0) +# menu-opacity = 1.0 +# menu-opacity is depreciated use dropdown-menu and popup-menu instead. + +#If using these 2 below change their values in line 510 & 511 aswell +popup_menu = { opacity = 1.0; } +dropdown_menu = { opacity = 1.0; } + +# Let inactive opacity set by -i override the '_NET_WM_OPACITY' values of windows. +inactive-opacity-override = true; +# inactive-opacity-override = false; + +# Default opacity for active windows. (0.0 - 1.0, defaults to 1.0) +active-opacity = 1.0; + +# Dim inactive windows. (0.0 - 1.0, defaults to 0.0) +# inactive-dim = 1.0 + +# Specify a list of conditions of windows that should always be considered focused. +# focus-exclude = [] +focus-exclude = [ + "class_g = 'Cairo-clock'", + "class_g = 'Bar'", # lemonbar + "class_g = 'slop'" # maim +]; + +# Use fixed inactive dim value, instead of adjusting according to window opacity. +# inactive-dim-fixed = 1.0 + +# Specify a list of opacity rules, in the format `PERCENT:PATTERN`, +# like `50:name *= "Firefox"`. picom-trans is recommended over this. +# Note we don't make any guarantee about possible conflicts with other +# programs that set '_NET_WM_WINDOW_OPACITY' on frame or client windows. +# example: +# opacity-rule = [ "80:class_g = 'URxvt'" ]; +# +# opacity-rule = [] +opacity-rule = [ + "90:class_g = 'xmobar'", + "90:class_g = 'firefox'", + "90:class_g = 'librewolf'", + "90:class_g = 'gtkcord4'", + "90:class_g = 'bottles'", + "90:class_g = 'PrismLauncher'", + "90:class_g = 'Navigator'", + "90:class_g = 'Rofi'", + "90:class_g = 'Geary'", + "90:class_g = 'KeePassXC'", + "90:class_g = 'gnome-calendar'", + "90:class_g = 'NewsFlashGTK'", + "90:class_g = 'Pavucontrol'" +]; + + +################################# +# Background-Blurring # +################################# + + +# Parameters for background blurring, see the *BLUR* section for more information. +# blur-method = kawase +# blur-size = 1 +# +# blur-deviation = false + +# Blur background of semi-transparent / ARGB windows. +# Bad in performance, with driver-dependent behavior. +# The name of the switch may change without prior notifications. +# +blur-background = false; + +# Blur background of windows when the window frame is not opaque. +# Implies: +# blur-background +# Bad in performance, with driver-dependent behavior. The name may change. +# +# blur-background-frame = false; + + +# Use fixed blur strength rather than adjusting according to window opacity. +# blur-background-fixed = false; + + +# Specify the blur convolution kernel, with the following format: +# example: +# blur-kern = "5,5,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1"; +# +# blur-kern = '' +# blur-kern = "3x3box"; + +#blur: { +# # requires: https://github.com/ibhagwan/picom +# method = "kawase"; +# #method = "kernel"; +# strength = 0; +# # deviation = 1.0; +# # kernel = "11x11gaussian"; +# background = false; +# background-frame = false; +# background-fixed = false; +# kern = "3x3box"; +#} + +# Exclude conditions for background blur. +blur-background-exclude = [ + #"window_type = 'dock'", + #"window_type = 'desktop'", + #"class_g = 'URxvt'", + # + # prevents picom from blurring the background + # when taking selection screenshot with `main` + # https://github.com/naelstrof/maim/issues/130 + "class_g = 'slop'", + "_GTK_FRAME_EXTENTS@:c" +]; + + +################################# +# General Settings # +################################# + +# Daemonize process. Fork to background after initialization. Causes issues with certain (badly-written) drivers. +daemon = true + +# Specify the backend to use: `xrender`, `glx`, or `xr_glx_hybrid`. +# `xrender` is the default one. +# +# experimental-backends = true; +backend = "glx"; +# backend = "xrender"; +# backend = "xr_glx_hybrid"; + + +# Enable/disable VSync. +vsync = true +# vsync = false + +# Enable remote control via D-Bus. See the *D-BUS API* section below for more details. +# dbus = false + +# Try to detect WM windows (a non-override-redirect window with no +# child that has 'WM_STATE') and mark them as active. +# +# mark-wmwin-focused = false +mark-wmwin-focused = true; + +# Mark override-redirect windows that doesn't have a child window with 'WM_STATE' focused. +# mark-ovredir-focused = false +mark-ovredir-focused = true; + +# Try to detect windows with rounded corners and don't consider them +# shaped windows. The accuracy is not very high, unfortunately. +# +# detect-rounded-corners = false +detect-rounded-corners = true; + +# Detect '_NET_WM_OPACITY' on client windows, useful for window managers +# not passing '_NET_WM_OPACITY' of client windows to frame windows. +# +detect-client-opacity = false +# detect-client-opacity = true; + +# Specify refresh rate of the screen. If not specified or 0, picom will +# try detecting this with X RandR extension. +# +# refresh-rate = 60 +refresh-rate = 0 + +# Limit picom to repaint at most once every 1 / 'refresh_rate' second to +# boost performance. This should not be used with +# vsync drm/opengl/opengl-oml +# as they essentially does sw-opti's job already, +# unless you wish to specify a lower refresh rate than the actual value. +# +# sw-opti = true + +# Use EWMH '_NET_ACTIVE_WINDOW' to determine currently focused window, +# rather than listening to 'FocusIn'/'FocusOut' event. Might have more accuracy, +# provided that the WM supports it. +# +# use-ewmh-active-win = false + +# Unredirect all windows if a full-screen opaque window is detected, +# to maximize performance for full-screen windows. Known to cause flickering +# when redirecting/unredirecting windows. paint-on-overlay may make the flickering less obvious. +# +# unredir-if-possible = false + +# Delay before unredirecting the window, in milliseconds. Defaults to 0. +# unredir-if-possible-delay = 0 + +# Conditions of windows that shouldn't be considered full-screen for unredirecting screen. +# unredir-if-possible-exclude = [] + +# Use 'WM_TRANSIENT_FOR' to group windows, and consider windows +# in the same group focused at the same time. +# +# detect-transient = false +detect-transient = true + +# Use 'WM_CLIENT_LEADER' to group windows, and consider windows in the same +# group focused at the same time. 'WM_TRANSIENT_FOR' has higher priority if +# detect-transient is enabled, too. +# +# detect-client-leader = false +detect-client-leader = true + +# Resize damaged region by a specific number of pixels. +# A positive value enlarges it while a negative one shrinks it. +# If the value is positive, those additional pixels will not be actually painted +# to screen, only used in blur calculation, and such. (Due to technical limitations, +# with use-damage, those pixels will still be incorrectly painted to screen.) +# Primarily used to fix the line corruption issues of blur, +# in which case you should use the blur radius value here +# (e.g. with a 3x3 kernel, you should use `--resize-damage 1`, +# with a 5x5 one you use `--resize-damage 2`, and so on). +# May or may not work with *--glx-no-stencil*. Shrinking doesn't function correctly. +# +# resize-damage = 1 + +# Specify a list of conditions of windows that should be painted with inverted color. +# Resource-hogging, and is not well tested. +# +# invert-color-include = [] + +# GLX backend: Avoid using stencil buffer, useful if you don't have a stencil buffer. +# Might cause incorrect opacity when rendering transparent content (but never +# practically happened) and may not work with blur-background. +# My tests show a 15% performance boost. Recommended. +# +glx-no-stencil = true + +# GLX backend: Avoid rebinding pixmap on window damage. +# Probably could improve performance on rapid window content changes, +# but is known to break things on some drivers (LLVMpipe, xf86-video-intel, etc.). +# Recommended if it works. +# +glx-no-rebind-pixmap = true + +# Disable the use of damage information. +# This cause the whole screen to be redrawn everytime, instead of the part of the screen +# has actually changed. Potentially degrades the performance, but might fix some artifacts. +# The opposing option is use-damage +# +# no-use-damage = true +#use-damage = true (Causing Weird Black semi opaque rectangles when terminal is opened) +#Changing use-damage to false fixes the problem +use-damage = false + +# Use X Sync fence to sync clients' draw calls, to make sure all draw +# calls are finished before picom starts drawing. Needed on nvidia-drivers +# with GLX backend for some users. +# +# xrender-sync-fence = false + +# GLX backend: Use specified GLSL fragment shader for rendering window contents. +# See `compton-default-fshader-win.glsl` and `compton-fake-transparency-fshader-win.glsl` +# in the source tree for examples. +# +# glx-fshader-win = '' + +# Force all windows to be painted with blending. Useful if you +# have a glx-fshader-win that could turn opaque pixels transparent. +# +# force-win-blend = false + +# Do not use EWMH to detect fullscreen windows. +# Reverts to checking if a window is fullscreen based only on its size and coordinates. +# +# no-ewmh-fullscreen = false + +# Dimming bright windows so their brightness doesn't exceed this set value. +# Brightness of a window is estimated by averaging all pixels in the window, +# so this could comes with a performance hit. +# Setting this to 1.0 disables this behaviour. Requires --use-damage to be disabled. (default: 1.0) +# +# max-brightness = 1.0 + +# Make transparent windows clip other windows like non-transparent windows do, +# instead of blending on top of them. +# +# transparent-clipping = false + +# Set the log level. Possible values are: +# "trace", "debug", "info", "warn", "error" +# in increasing level of importance. Case doesn't matter. +# If using the "TRACE" log level, it's better to log into a file +# using *--log-file*, since it can generate a huge stream of logs. +# +# log-level = "debug" +log-level = "info"; + +# Set the log file. +# If *--log-file* is never specified, logs will be written to stderr. +# Otherwise, logs will to written to the given file, though some of the early +# logs might still be written to the stderr. +# When setting this option from the config file, it is recommended to use an absolute path. +# +# log-file = '/path/to/your/log/file' + +# Show all X errors (for debugging) +# show-all-xerrors = false + +# Write process ID to a file. +# write-pid-path = '/path/to/your/log/file' + +# Window type settings +# +# 'WINDOW_TYPE' is one of the 15 window types defined in EWMH standard: +# "unknown", "desktop", "dock", "toolbar", "menu", "utility", +# "splash", "dialog", "normal", "dropdown_menu", "popup_menu", +# "tooltip", "notification", "combo", and "dnd". +# +# Following per window-type options are available: :: +# +# fade, shadow::: +# Controls window-type-specific shadow and fade settings. +# +# opacity::: +# Controls default opacity of the window type. +# +# focus::: +# Controls whether the window of this type is to be always considered focused. +# (By default, all window types except "normal" and "dialog" has this on.) +# +# full-shadow::: +# Controls whether shadow is drawn under the parts of the window that you +# normally won't be able to see. Useful when the window has parts of it +# transparent, and you want shadows in those areas. +# +# redir-ignore::: +# Controls whether this type of windows should cause screen to become +# redirected again after been unredirected. If you have unredir-if-possible +# set, and doesn't want certain window to cause unnecessary screen redirection, +# you can set this to `true`. +# +wintypes: +{ + normal = { shadow = false;} + tooltip = { shadow = true; opacity = 0.75; focus = true; full-shadow = false; }; + dock = { shadow = false; } + dnd = { shadow = false; } + popup_menu = { opacity = 1; } + dropdown_menu = { opacity = 1; } +}; diff --git a/user/wm/picom/picom.gif b/user/wm/picom/picom.gif new file mode 100644 index 0000000..1591ca1 Binary files /dev/null and b/user/wm/picom/picom.gif differ diff --git a/user/wm/picom/picom.nix b/user/wm/picom/picom.nix new file mode 100644 index 0000000..56d3a5b --- /dev/null +++ b/user/wm/picom/picom.nix @@ -0,0 +1,30 @@ +{ pkgs, ... }: + +{ + home.packages = with pkgs; [ + picom + ]; + + nixpkgs.overlays = [ + (self: super: + { + picom = super.picom.overrideAttrs (oldAttrs: rec { + version = "unstable-2021-10-23"; + src = super.fetchFromGitHub { + owner = "pijulius"; + repo = "picom"; + rev = "982bb43e5d4116f1a37a0bde01c9bda0b88705b9"; + sha256 = "sha256-YiuLScDV9UfgI1MiYRtjgRkJ0VuA1TExATA2nJSJMhM="; + }; + + meta = with builtins.lib; { + description = "A fork of picom featuring better animations"; + homepage = "https://github.com/pijulius/picom"; + }; + }); + } + ) + ]; + + home.file.".config/picom/picom.conf".source = ./picom.conf; +} diff --git a/user/wm/plasma/patches/fuzzelmouseinput.patch b/user/wm/plasma/patches/fuzzelmouseinput.patch deleted file mode 100644 index 0264ac1..0000000 --- a/user/wm/plasma/patches/fuzzelmouseinput.patch +++ /dev/null @@ -1,1053 +0,0 @@ -From 7cc9f3147438fe7dd0062172f46aed415f024464 Mon Sep 17 00:00:00 2001 -From: alz -Date: Mon, 22 Jul 2024 00:43:56 -0400 -Subject: [PATCH 1/7] implemented left click, right click and scroll wheel - listeners - ---- - match.c | 24 ++++++++++++++++++++++++ - match.h | 1 + - render.c | 19 +++++++++++++++++++ - render.h | 2 ++ - wayland.c | 38 ++++++++++++++++++++++++++++++++++++++ - 5 files changed, 84 insertions(+) - -diff --git a/match.c b/match.c -index 5a26000..7d5efaf 100644 ---- a/match.c -+++ b/match.c -@@ -359,6 +359,30 @@ matches_selected_select(struct matches *matches, const char *_string) - return false; - } - -+bool -+matches_selected_select_idx(struct matches *matches, size_t idx) -+{ -+ const size_t page_no = matches_get_page(matches); -+ const size_t items_on_page __attribute__((unused)) = matches_get_count(matches); -+ -+ LOG_DBG( -+ "page-count: %zu, page-no: %zu, items-on-page: %zu, idx: %zu, max: %zu, " -+ "match-count: %zu", -+ matches->page_count, page_no, items_on_page, idx, -+ matches->max_matches_per_page, matches->match_count); -+ -+ if (idx >= items_on_page) -+ return false; -+ -+ idx += page_no * matches->max_matches_per_page; -+ -+ if (idx >= matches->match_count) -+ return false; -+ -+ matches->selected = idx; -+ return true; -+} -+ - bool - matches_selected_first(struct matches *matches) - { -diff --git a/match.h b/match.h -index 4100881..871635b 100644 ---- a/match.h -+++ b/match.h -@@ -53,6 +53,7 @@ size_t matches_get_total_count(const struct matches *matches); - size_t matches_get_match_index(const struct matches *matches); - - bool matches_selected_select(struct matches *matches, const char *string); -+bool matches_selected_select_idx(struct matches *matches, size_t idx); - - bool matches_selected_first(struct matches *matches); - bool matches_selected_last(struct matches *matches); -diff --git a/render.c b/render.c -index 403d7c9..3bc507c 100644 ---- a/render.c -+++ b/render.c -@@ -873,3 +873,22 @@ render_destroy(struct render *render) - fcft_destroy(render->font); - free(render); - } -+ -+int render_get_row_num(const struct render *render, int y) -+{ -+ const float scale = render->scale; -+ const int y_margin = render->y_margin; -+ const int inner_pad = render->inner_pad; -+ const int border_size = render->border_size; -+ const int row_height = render->row_height; -+ const int first_row = 1 * border_size + y_margin + row_height + inner_pad; -+ -+ y = floor(scale * y); -+ -+ if (y <= first_row) { -+ return -1; -+ } else { -+ y -= first_row; -+ return y / row_height; -+ } -+} -diff --git a/render.h b/render.h -index c097882..1f934f5 100644 ---- a/render.h -+++ b/render.h -@@ -30,3 +30,5 @@ void render_match_list( - const struct prompt *prompt, const struct matches *matches); - - int render_icon_size(const struct render *render); -+ -+int render_get_row_num(const struct render *render, int y); -diff --git a/wayland.c b/wayland.c -index 15f9e05..c2cf6a6 100644 ---- a/wayland.c -+++ b/wayland.c -@@ -1062,18 +1062,56 @@ static void - wl_pointer_motion(void *data, struct wl_pointer *wl_pointer, - uint32_t time, wl_fixed_t surface_x, wl_fixed_t surface_y) - { -+ struct seat *seat = data; -+ struct wayland *wayl = seat->wayl; -+ bool refresh = false; -+ -+ refresh = matches_selected_select_idx(wayl->matches, -+ render_get_row_num(wayl->render, wl_fixed_to_int(surface_y))); -+ -+ if (refresh) { -+ wayl_refresh(wayl); -+ } - } - - static void - wl_pointer_button(void *data, struct wl_pointer *wl_pointer, - uint32_t serial, uint32_t time, uint32_t button, uint32_t state) - { -+ struct seat *seat = data; -+ struct wayland *wayl = seat->wayl; -+ -+ // Button release -+ if (state == 0) { -+ // Left click -+ if (button == 272) { -+ execute_selected(seat, false, -1); -+ // Right click -+ } else if (button == 273) { -+ wayl->status = EXIT; -+ if (wayl->conf->dmenu.enabled) -+ wayl->exit_code = 2; -+ } -+ } - } - - static void - wl_pointer_axis(void *data, struct wl_pointer *wl_pointer, - uint32_t time, uint32_t axis, wl_fixed_t value) - { -+ struct seat *seat = data; -+ struct wayland *wayl = seat->wayl; -+ -+ bool refresh = false; -+ if (value < 0) { -+ refresh = matches_selected_prev_page(wayl->matches); -+ } else if (value > 0) { -+ refresh = matches_selected_next_page(wayl->matches); -+ } -+ -+ if (refresh) { -+ wayl_refresh(wayl); -+ } - } - - static void --- -2.39.2 - - -From e023c4f6ceb8bd0fa9b5b1ed2b23af123c2811ed Mon Sep 17 00:00:00 2001 -From: alz -Date: Mon, 22 Jul 2024 01:07:56 -0400 -Subject: [PATCH 2/7] put the mouse stuff behind a config - ---- - config.c | 4 ++++ - config.h | 2 ++ - doc/fuzzel.1.scd | 4 ++++ - doc/fuzzel.ini.5.scd | 3 +++ - main.c | 10 ++++++++ - match.c | 4 ++++ - wayland.c | 54 +++++++++++++++++++++++++------------------- - 7 files changed, 58 insertions(+), 23 deletions(-) - -diff --git a/config.c b/config.c -index e236142..21aab3a 100644 ---- a/config.c -+++ b/config.c -@@ -778,6 +778,9 @@ parse_section_main(struct context *ctx) - else if (strcmp(key, "list-executables-in-path") == 0) - return value_to_bool(ctx, &conf->list_executables_in_path); - -+ else if (strcmp(key, "mouse-listener") == 0) -+ return value_to_bool(ctx, &conf->mouse_listener); -+ - else if (strcmp(key, "fields") == 0) { - _Static_assert(sizeof(conf->match_fields) == sizeof(int), - "enum is not 32-bit"); -@@ -1572,6 +1575,7 @@ config_load(struct config *conf, const char *conf_path, - .layer = ZWLR_LAYER_SHELL_V1_LAYER_TOP, - .exit_on_kb_focus_loss = true, - .list_executables_in_path = false, -+ .mouse_listener = false, - }; - - add_default_key_bindings(conf); -diff --git a/config.h b/config.h -index a52976c..99d3a52 100644 ---- a/config.h -+++ b/config.h -@@ -170,6 +170,8 @@ struct config { - bool exit_on_kb_focus_loss; - - bool list_executables_in_path; -+ -+ bool mouse_listener; - }; - - typedef tll(char *) config_override_t; -diff --git a/doc/fuzzel.1.scd b/doc/fuzzel.1.scd -index c46d9af..791a5e6 100644 ---- a/doc/fuzzel.1.scd -+++ b/doc/fuzzel.1.scd -@@ -302,6 +302,10 @@ or command line options: - *--log-no-syslog* - Disables syslog logging. Logging is only done on stderr. - -+*--mouse* -+ Allows choosing items with mouse left click, and cancelling fuzzel with -+ right click. -+ - *-v*,*--version* - Show the version number and quit - -diff --git a/doc/fuzzel.ini.5.scd b/doc/fuzzel.ini.5.scd -index e3dfc05..ee6a2c5 100644 ---- a/doc/fuzzel.ini.5.scd -+++ b/doc/fuzzel.ini.5.scd -@@ -411,6 +411,9 @@ done by setting _action=none_; e.g. *delete-line-forward=none*. - *last* - Select the last entry, on the last page. Default: _Control+End_. - -+*mouse-listener* -+ Allows selecting elements with the mouse -+ - *custom-1*, *custom-2*, ..., *custom-19* - Execute the currently selected entry, then exit with a non-zero - exit code. *custom-1* exits with exit code 10, *custom-2* with 11, -diff --git a/match.c b/match.c -index 7d5efaf..fe3903a 100644 ---- a/match.c -+++ b/match.c -@@ -362,6 +362,9 @@ matches_selected_select(struct matches *matches, const char *_string) - bool - matches_selected_select_idx(struct matches *matches, size_t idx) - { -+ if (idx < 0) -+ return false; -+ - const size_t page_no = matches_get_page(matches); - const size_t items_on_page __attribute__((unused)) = matches_get_count(matches); - -@@ -371,6 +374,7 @@ matches_selected_select_idx(struct matches *matches, size_t idx) - matches->page_count, page_no, items_on_page, idx, - matches->max_matches_per_page, matches->match_count); - -+ - if (idx >= items_on_page) - return false; - -diff --git a/wayland.c b/wayland.c -index c2cf6a6..8fff785 100644 ---- a/wayland.c -+++ b/wayland.c -@@ -1064,13 +1064,16 @@ wl_pointer_motion(void *data, struct wl_pointer *wl_pointer, - { - struct seat *seat = data; - struct wayland *wayl = seat->wayl; -- bool refresh = false; - -- refresh = matches_selected_select_idx(wayl->matches, -- render_get_row_num(wayl->render, wl_fixed_to_int(surface_y))); -+ if (wayl->conf->mouse_listener) { -+ bool refresh = false; - -- if (refresh) { -- wayl_refresh(wayl); -+ refresh = matches_selected_select_idx(wayl->matches, -+ render_get_row_num(wayl->render, wl_fixed_to_int(surface_y))); -+ -+ if (refresh) { -+ wayl_refresh(wayl); -+ } - } - } - -@@ -1081,16 +1084,18 @@ wl_pointer_button(void *data, struct wl_pointer *wl_pointer, - struct seat *seat = data; - struct wayland *wayl = seat->wayl; - -- // Button release -- if (state == 0) { -- // Left click -- if (button == 272) { -- execute_selected(seat, false, -1); -- // Right click -- } else if (button == 273) { -- wayl->status = EXIT; -- if (wayl->conf->dmenu.enabled) -- wayl->exit_code = 2; -+ if (wayl->conf->mouse_listener) { -+ // Button release -+ if (state == 0) { -+ // Left click -+ if (button == 0x110) { -+ execute_selected(seat, false, -1); -+ // Right click -+ } else if (button == 0x111) { -+ wayl->status = EXIT; -+ if (wayl->conf->dmenu.enabled) -+ wayl->exit_code = 2; -+ } - } - } - } -@@ -1102,15 +1107,18 @@ wl_pointer_axis(void *data, struct wl_pointer *wl_pointer, - struct seat *seat = data; - struct wayland *wayl = seat->wayl; - -- bool refresh = false; -- if (value < 0) { -- refresh = matches_selected_prev_page(wayl->matches); -- } else if (value > 0) { -- refresh = matches_selected_next_page(wayl->matches); -- } -+ if (wayl->conf->mouse_listener) { -+ bool refresh = false; - -- if (refresh) { -- wayl_refresh(wayl); -+ if (value < 0) { -+ refresh = matches_selected_prev_page(wayl->matches); -+ } else if (value > 0) { -+ refresh = matches_selected_next_page(wayl->matches); -+ } -+ -+ if (refresh) { -+ wayl_refresh(wayl); -+ } - } - } - --- -2.39.2 - - -From 9e04a13fa2a6b442faaa1451700e04000f24734b Mon Sep 17 00:00:00 2001 -From: alz -Date: Mon, 22 Jul 2024 12:00:43 -0400 -Subject: [PATCH 3/7] Ignoring left clicks if they're in the prompt row - ---- - wayland.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/wayland.c b/wayland.c -index 8fff785..e7c0c2c 100644 ---- a/wayland.c -+++ b/wayland.c -@@ -1068,6 +1068,8 @@ wl_pointer_motion(void *data, struct wl_pointer *wl_pointer, - if (wayl->conf->mouse_listener) { - bool refresh = false; - -+ seat->pointer.y = wl_fixed_to_int(surface_y); -+ - refresh = matches_selected_select_idx(wayl->matches, - render_get_row_num(wayl->render, wl_fixed_to_int(surface_y))); - -@@ -1088,7 +1090,7 @@ wl_pointer_button(void *data, struct wl_pointer *wl_pointer, - // Button release - if (state == 0) { - // Left click -- if (button == 0x110) { -+ if (button == 0x110 && render_get_row_num(wayl->render, seat->pointer.y) >= 0) { - execute_selected(seat, false, -1); - // Right click - } else if (button == 0x111) { --- -2.39.2 - - -From 607edc371b7ee48ec194ec2ce561d8e10d49923a Mon Sep 17 00:00:00 2001 -From: alz -Date: Mon, 22 Jul 2024 13:18:43 -0400 -Subject: [PATCH 4/7] Refactored so the data types are correct - ---- - match.c | 36 ++++++++++++------------------------ - render.c | 14 +++++++++----- - render.h | 2 +- - wayland.c | 28 +++++++++++++++++----------- - 4 files changed, 39 insertions(+), 41 deletions(-) - -diff --git a/match.c b/match.c -index fe3903a..a16f903 100644 ---- a/match.c -+++ b/match.c -@@ -278,8 +278,8 @@ matches_get_page(const struct matches *matches) - : matches->selected; - } - --const struct match * --matches_get(const struct matches *matches, size_t idx) -+size_t -+match_get_idx(const struct matches *matches, size_t idx) - { - const size_t page_no = matches_get_page(matches); - const size_t items_on_page __attribute__((unused)) = matches_get_count(matches); -@@ -290,11 +290,17 @@ matches_get(const struct matches *matches, size_t idx) - matches->page_count, page_no, items_on_page, idx, - matches->max_matches_per_page, matches->match_count); - -- assert(idx < items_on_page); -+ assert(idx >= 0 && idx < items_on_page); - idx += page_no * matches->max_matches_per_page; - - assert(idx < matches->match_count); -- return &matches->matches[idx]; -+ return idx; -+} -+ -+const struct match * -+matches_get(const struct matches *matches, size_t idx) -+{ -+ return &matches->matches[match_get_idx(matches, idx)]; - } - - const struct match * -@@ -362,28 +368,10 @@ matches_selected_select(struct matches *matches, const char *_string) - bool - matches_selected_select_idx(struct matches *matches, size_t idx) - { -- if (idx < 0) -+ if (idx == -1) - return false; - -- const size_t page_no = matches_get_page(matches); -- const size_t items_on_page __attribute__((unused)) = matches_get_count(matches); -- -- LOG_DBG( -- "page-count: %zu, page-no: %zu, items-on-page: %zu, idx: %zu, max: %zu, " -- "match-count: %zu", -- matches->page_count, page_no, items_on_page, idx, -- matches->max_matches_per_page, matches->match_count); -- -- -- if (idx >= items_on_page) -- return false; -- -- idx += page_no * matches->max_matches_per_page; -- -- if (idx >= matches->match_count) -- return false; -- -- matches->selected = idx; -+ matches->selected = match_get_idx(matches, idx); - return true; - } - -diff --git a/render.c b/render.c -index 3bc507c..1dcefc9 100644 ---- a/render.c -+++ b/render.c -@@ -874,7 +874,8 @@ render_destroy(struct render *render) - free(render); - } - --int render_get_row_num(const struct render *render, int y) -+size_t -+render_get_row_num(const struct render *render, int y, size_t match_count) - { - const float scale = render->scale; - const int y_margin = render->y_margin; -@@ -882,13 +883,16 @@ int render_get_row_num(const struct render *render, int y) - const int border_size = render->border_size; - const int row_height = render->row_height; - const int first_row = 1 * border_size + y_margin + row_height + inner_pad; -+ const int last_row = first_row + match_count*row_height; - - y = floor(scale * y); - -- if (y <= first_row) { -- return -1; -- } else { -+ size_t row = -1; -+ -+ if (y >= first_row && y < last_row) { - y -= first_row; -- return y / row_height; -+ row = y / row_height; - } -+ -+ return row; - } -diff --git a/render.h b/render.h -index 1f934f5..c257004 100644 ---- a/render.h -+++ b/render.h -@@ -31,4 +31,4 @@ void render_match_list( - - int render_icon_size(const struct render *render); - --int render_get_row_num(const struct render *render, int y); -+size_t render_get_row_num(const struct render *render, int y, size_t match_count); -diff --git a/wayland.c b/wayland.c -index e7c0c2c..56ff829 100644 ---- a/wayland.c -+++ b/wayland.c -@@ -1058,6 +1058,19 @@ wl_pointer_leave(void *data, struct wl_pointer *wl_pointer, - seat->pointer.serial = serial; - } - -+static void -+select_hovered_match(struct wayland *wayl, int y) -+{ -+ bool refresh = false; -+ -+ refresh = matches_selected_select_idx(wayl->matches, -+ render_get_row_num(wayl->render, y, matches_get_count(wayl->matches))); -+ -+ if (refresh) { -+ wayl_refresh(wayl); -+ } -+} -+ - static void - wl_pointer_motion(void *data, struct wl_pointer *wl_pointer, - uint32_t time, wl_fixed_t surface_x, wl_fixed_t surface_y) -@@ -1066,16 +1079,8 @@ wl_pointer_motion(void *data, struct wl_pointer *wl_pointer, - struct wayland *wayl = seat->wayl; - - if (wayl->conf->mouse_listener) { -- bool refresh = false; -- - seat->pointer.y = wl_fixed_to_int(surface_y); -- -- refresh = matches_selected_select_idx(wayl->matches, -- render_get_row_num(wayl->render, wl_fixed_to_int(surface_y))); -- -- if (refresh) { -- wayl_refresh(wayl); -- } -+ select_hovered_match(wayl, seat->pointer.y); - } - } - -@@ -1090,7 +1095,8 @@ wl_pointer_button(void *data, struct wl_pointer *wl_pointer, - // Button release - if (state == 0) { - // Left click -- if (button == 0x110 && render_get_row_num(wayl->render, seat->pointer.y) >= 0) { -+ if (button == 0x110 && -+ render_get_row_num(wayl->render, seat->pointer.y, matches_get_count(wayl->matches)) != -1) { - execute_selected(seat, false, -1); - // Right click - } else if (button == 0x111) { -@@ -1119,7 +1125,7 @@ wl_pointer_axis(void *data, struct wl_pointer *wl_pointer, - } - - if (refresh) { -- wayl_refresh(wayl); -+ select_hovered_match(wayl, seat->pointer.y); - } - } - } --- -2.39.2 - - -From f4d4918ebd6b996deff617c2750000904d1f2d29 Mon Sep 17 00:00:00 2001 -From: alz -Date: Mon, 22 Jul 2024 13:37:03 -0400 -Subject: [PATCH 5/7] made the hovered row index an attribute of the seat - pointer - ---- - wayland.c | 20 +++++++++++--------- - 1 file changed, 11 insertions(+), 9 deletions(-) - -diff --git a/wayland.c b/wayland.c -index 56ff829..ab88598 100644 ---- a/wayland.c -+++ b/wayland.c -@@ -148,6 +148,8 @@ struct seat { - struct wl_cursor_theme *theme; - struct wl_cursor *cursor; - float scale; -+ -+ size_t hovered_row_idx; - } pointer; - }; - -@@ -1059,12 +1061,10 @@ wl_pointer_leave(void *data, struct wl_pointer *wl_pointer, - } - - static void --select_hovered_match(struct wayland *wayl, int y) -+select_hovered_match(struct wayland *wayl, size_t idx) - { - bool refresh = false; -- -- refresh = matches_selected_select_idx(wayl->matches, -- render_get_row_num(wayl->render, y, matches_get_count(wayl->matches))); -+ refresh = matches_selected_select_idx(wayl->matches,idx); - - if (refresh) { - wayl_refresh(wayl); -@@ -1079,8 +1079,11 @@ wl_pointer_motion(void *data, struct wl_pointer *wl_pointer, - struct wayland *wayl = seat->wayl; - - if (wayl->conf->mouse_listener) { -- seat->pointer.y = wl_fixed_to_int(surface_y); -- select_hovered_match(wayl, seat->pointer.y); -+ seat->pointer.hovered_row_idx = -+ render_get_row_num(wayl->render, -+ wl_fixed_to_int(surface_y), -+ matches_get_count(wayl->matches)); -+ select_hovered_match(wayl, seat->pointer.hovered_row_idx); - } - } - -@@ -1095,8 +1098,7 @@ wl_pointer_button(void *data, struct wl_pointer *wl_pointer, - // Button release - if (state == 0) { - // Left click -- if (button == 0x110 && -- render_get_row_num(wayl->render, seat->pointer.y, matches_get_count(wayl->matches)) != -1) { -+ if (button == 0x110 && seat->pointer.hovered_row_idx != -1) { - execute_selected(seat, false, -1); - // Right click - } else if (button == 0x111) { -@@ -1125,7 +1127,7 @@ wl_pointer_axis(void *data, struct wl_pointer *wl_pointer, - } - - if (refresh) { -- select_hovered_match(wayl, seat->pointer.y); -+ select_hovered_match(wayl, seat->pointer.hovered_row_idx); - } - } - } --- -2.39.2 - - -From ef4b0160b3c6e04da7b4bf6a0e6b7d0ac06b54ef Mon Sep 17 00:00:00 2001 -From: alz -Date: Tue, 23 Jul 2024 16:35:44 -0400 -Subject: [PATCH 6/7] Refreshing display less often - ---- - render.c | 2 +- - wayland.c | 7 +++++-- - 2 files changed, 6 insertions(+), 3 deletions(-) - -diff --git a/render.c b/render.c -index 1dcefc9..505f570 100644 ---- a/render.c -+++ b/render.c -@@ -839,7 +839,7 @@ render_set_font(struct render *render, struct fcft_font *font, - border_size; - - LOG_DBG("x-margin: %d, y-margin: %d, border: %d, row-height: %d, " -- "icon-height: %d, height: %d, width: %d, scale: %d", -+ "icon-height: %d, height: %d, width: %d, scale: %f", - x_margin, y_margin, border_size, row_height, icon_height, - height, width, scale); - -diff --git a/wayland.c b/wayland.c -index ab88598..19e902a 100644 ---- a/wayland.c -+++ b/wayland.c -@@ -1079,11 +1079,14 @@ wl_pointer_motion(void *data, struct wl_pointer *wl_pointer, - struct wayland *wayl = seat->wayl; - - if (wayl->conf->mouse_listener) { -- seat->pointer.hovered_row_idx = -+ size_t hovered_row = - render_get_row_num(wayl->render, - wl_fixed_to_int(surface_y), - matches_get_count(wayl->matches)); -- select_hovered_match(wayl, seat->pointer.hovered_row_idx); -+ if (hovered_row != seat->pointer.hovered_row_idx) { -+ seat->pointer.hovered_row_idx = hovered_row; -+ select_hovered_match(wayl, seat->pointer.hovered_row_idx); -+ } - } - } - --- -2.39.2 - - -From 761aabf6b7fc55203e23be76a044bbea3e8d99be Mon Sep 17 00:00:00 2001 -From: alz -Date: Mon, 29 Jul 2024 13:01:12 -0400 -Subject: [PATCH 7/7] Removed config, refactored hovered row selection - ---- - config.c | 4 --- - config.h | 2 -- - doc/fuzzel.1.scd | 4 --- - doc/fuzzel.ini.5.scd | 3 -- - main.c | 10 ------ - match.c | 12 +++---- - match.h | 6 ++-- - render.c | 9 ++--- - render.h | 4 ++- - wayland.c | 78 +++++++++++++++++++++----------------------- - 10 files changed, 54 insertions(+), 78 deletions(-) - -diff --git a/config.c b/config.c -index 21aab3a..e236142 100644 ---- a/config.c -+++ b/config.c -@@ -778,9 +778,6 @@ parse_section_main(struct context *ctx) - else if (strcmp(key, "list-executables-in-path") == 0) - return value_to_bool(ctx, &conf->list_executables_in_path); - -- else if (strcmp(key, "mouse-listener") == 0) -- return value_to_bool(ctx, &conf->mouse_listener); -- - else if (strcmp(key, "fields") == 0) { - _Static_assert(sizeof(conf->match_fields) == sizeof(int), - "enum is not 32-bit"); -@@ -1575,7 +1572,6 @@ config_load(struct config *conf, const char *conf_path, - .layer = ZWLR_LAYER_SHELL_V1_LAYER_TOP, - .exit_on_kb_focus_loss = true, - .list_executables_in_path = false, -- .mouse_listener = false, - }; - - add_default_key_bindings(conf); -diff --git a/config.h b/config.h -index 99d3a52..a52976c 100644 ---- a/config.h -+++ b/config.h -@@ -170,8 +170,6 @@ struct config { - bool exit_on_kb_focus_loss; - - bool list_executables_in_path; -- -- bool mouse_listener; - }; - - typedef tll(char *) config_override_t; -diff --git a/doc/fuzzel.1.scd b/doc/fuzzel.1.scd -index 791a5e6..c46d9af 100644 ---- a/doc/fuzzel.1.scd -+++ b/doc/fuzzel.1.scd -@@ -302,10 +302,6 @@ or command line options: - *--log-no-syslog* - Disables syslog logging. Logging is only done on stderr. - --*--mouse* -- Allows choosing items with mouse left click, and cancelling fuzzel with -- right click. -- - *-v*,*--version* - Show the version number and quit - -diff --git a/doc/fuzzel.ini.5.scd b/doc/fuzzel.ini.5.scd -index ee6a2c5..e3dfc05 100644 ---- a/doc/fuzzel.ini.5.scd -+++ b/doc/fuzzel.ini.5.scd -@@ -411,9 +411,6 @@ done by setting _action=none_; e.g. *delete-line-forward=none*. - *last* - Select the last entry, on the last page. Default: _Control+End_. - --*mouse-listener* -- Allows selecting elements with the mouse -- - *custom-1*, *custom-2*, ..., *custom-19* - Execute the currently selected entry, then exit with a non-zero - exit code. *custom-1* exits with exit code 10, *custom-2* with 11, -diff --git a/match.c b/match.c -index a16f903..48c6e4f 100644 ---- a/match.c -+++ b/match.c -@@ -290,7 +290,7 @@ match_get_idx(const struct matches *matches, size_t idx) - matches->page_count, page_no, items_on_page, idx, - matches->max_matches_per_page, matches->match_count); - -- assert(idx >= 0 && idx < items_on_page); -+ assert(idx < items_on_page); - idx += page_no * matches->max_matches_per_page; - - assert(idx < matches->match_count); -@@ -366,7 +366,7 @@ matches_selected_select(struct matches *matches, const char *_string) - } - - bool --matches_selected_select_idx(struct matches *matches, size_t idx) -+matches_idx_select(struct matches *matches, size_t idx) - { - if (idx == -1) - return false; -@@ -427,14 +427,14 @@ matches_selected_next(struct matches *matches, bool wrap) - } - - bool --matches_selected_prev_page(struct matches *matches) -+matches_selected_prev_page(struct matches *matches, bool scrolling) - { - const size_t page_no = matches_get_page(matches); - if (page_no > 0) { - assert(matches->selected >= matches->max_matches_per_page); - matches->selected -= matches->max_matches_per_page; - return true; -- } else if (matches->selected > 0) { -+ } else if (!scrolling && matches->selected > 0) { - matches->selected = 0; - return true; - } -@@ -443,7 +443,7 @@ matches_selected_prev_page(struct matches *matches) - } - - bool --matches_selected_next_page(struct matches *matches) -+matches_selected_next_page(struct matches *matches, bool scrolling) - { - const size_t page_no = matches_get_page(matches); - if (page_no + 1 < matches->page_count) { -@@ -451,7 +451,7 @@ matches_selected_next_page(struct matches *matches) - matches->selected + matches->max_matches_per_page, - matches->match_count - 1); - return true; -- } else if (matches->selected < matches->match_count - 1) { -+ } else if (!scrolling && matches->selected < matches->match_count - 1) { - matches->selected = matches->match_count - 1; - return true; - } -diff --git a/match.h b/match.h -index 871635b..35c5d5e 100644 ---- a/match.h -+++ b/match.h -@@ -53,7 +53,7 @@ size_t matches_get_total_count(const struct matches *matches); - size_t matches_get_match_index(const struct matches *matches); - - bool matches_selected_select(struct matches *matches, const char *string); --bool matches_selected_select_idx(struct matches *matches, size_t idx); -+bool matches_idx_select(struct matches *matches, size_t idx); - - bool matches_selected_first(struct matches *matches); - bool matches_selected_last(struct matches *matches); -@@ -61,5 +61,5 @@ bool matches_selected_last(struct matches *matches); - bool matches_selected_prev(struct matches *matches, bool wrap); - bool matches_selected_next(struct matches *matches, bool wrap); - --bool matches_selected_prev_page(struct matches *matches); --bool matches_selected_next_page(struct matches *matches); -+bool matches_selected_prev_page(struct matches *matches, bool scrolling); -+bool matches_selected_next_page(struct matches *matches, bool scrolling); -diff --git a/render.c b/render.c -index 505f570..ef9aaad 100644 ---- a/render.c -+++ b/render.c -@@ -875,7 +875,8 @@ render_destroy(struct render *render) - } - - size_t --render_get_row_num(const struct render *render, int y, size_t match_count) -+render_get_row_num(const struct render *render, int y, -+ const struct matches *matches) - { - const float scale = render->scale; - const int y_margin = render->y_margin; -@@ -883,15 +884,15 @@ render_get_row_num(const struct render *render, int y, size_t match_count) - const int border_size = render->border_size; - const int row_height = render->row_height; - const int first_row = 1 * border_size + y_margin + row_height + inner_pad; -- const int last_row = first_row + match_count*row_height; -+ const size_t match_count = matches_get_count(matches); -+ const size_t last_row = first_row + match_count*row_height; - - y = floor(scale * y); - - size_t row = -1; - - if (y >= first_row && y < last_row) { -- y -= first_row; -- row = y / row_height; -+ row = (y - first_row) / row_height; - } - - return row; -diff --git a/render.h b/render.h -index c257004..16887f3 100644 ---- a/render.h -+++ b/render.h -@@ -31,4 +31,6 @@ void render_match_list( - - int render_icon_size(const struct render *render); - --size_t render_get_row_num(const struct render *render, int y, size_t match_count); -+size_t render_get_row_num( -+ const struct render *render, int y, -+ const struct matches *matches); -diff --git a/wayland.c b/wayland.c -index 19e902a..541496d 100644 ---- a/wayland.c -+++ b/wayland.c -@@ -16,6 +16,7 @@ - #include - #include - -+#include - #include - #include - #include -@@ -142,14 +143,13 @@ struct seat { - - int x; - int y; -+ size_t hovered_row_idx; - - struct wl_surface *surface; - struct wp_viewport *viewport; - struct wl_cursor_theme *theme; - struct wl_cursor *cursor; - float scale; -- -- size_t hovered_row_idx; - } pointer; - }; - -@@ -706,7 +706,7 @@ execute_binding(struct seat *seat, const struct key_binding *binding, bool *refr - return true; - - case BIND_ACTION_MATCHES_PREV_PAGE: -- *refresh = matches_selected_prev_page(wayl->matches); -+ *refresh = matches_selected_prev_page(wayl->matches, false); - return true; - - case BIND_ACTION_MATCHES_NEXT: -@@ -718,7 +718,7 @@ execute_binding(struct seat *seat, const struct key_binding *binding, bool *refr - return true; - - case BIND_ACTION_MATCHES_NEXT_PAGE: -- *refresh = matches_selected_next_page(wayl->matches); -+ *refresh = matches_selected_next_page(wayl->matches, false); - return true; - - case BIND_ACTION_MATCHES_FIRST: -@@ -1061,12 +1061,22 @@ wl_pointer_leave(void *data, struct wl_pointer *wl_pointer, - } - - static void --select_hovered_match(struct wayland *wayl, size_t idx) -+select_hovered_match(struct seat *seat, bool refresh_always) - { -+ struct wayland *wayl = seat->wayl; - bool refresh = false; -- refresh = matches_selected_select_idx(wayl->matches,idx); - -- if (refresh) { -+ size_t hovered_row = -+ render_get_row_num(wayl->render, -+ seat->pointer.y, -+ wayl->matches); -+ -+ if (hovered_row != seat->pointer.hovered_row_idx) { -+ seat->pointer.hovered_row_idx = hovered_row; -+ refresh = matches_idx_select(wayl->matches,hovered_row); -+ } -+ -+ if (refresh_always || refresh) { - wayl_refresh(wayl); - } - } -@@ -1076,18 +1086,11 @@ wl_pointer_motion(void *data, struct wl_pointer *wl_pointer, - uint32_t time, wl_fixed_t surface_x, wl_fixed_t surface_y) - { - struct seat *seat = data; -- struct wayland *wayl = seat->wayl; - -- if (wayl->conf->mouse_listener) { -- size_t hovered_row = -- render_get_row_num(wayl->render, -- wl_fixed_to_int(surface_y), -- matches_get_count(wayl->matches)); -- if (hovered_row != seat->pointer.hovered_row_idx) { -- seat->pointer.hovered_row_idx = hovered_row; -- select_hovered_match(wayl, seat->pointer.hovered_row_idx); -- } -- } -+ seat->pointer.x = wl_fixed_to_int(surface_x); -+ seat->pointer.y = wl_fixed_to_int(surface_y); -+ -+ select_hovered_match(seat, false); - } - - static void -@@ -1097,18 +1100,14 @@ wl_pointer_button(void *data, struct wl_pointer *wl_pointer, - struct seat *seat = data; - struct wayland *wayl = seat->wayl; - -- if (wayl->conf->mouse_listener) { -- // Button release -- if (state == 0) { -- // Left click -- if (button == 0x110 && seat->pointer.hovered_row_idx != -1) { -- execute_selected(seat, false, -1); -- // Right click -- } else if (button == 0x111) { -- wayl->status = EXIT; -- if (wayl->conf->dmenu.enabled) -- wayl->exit_code = 2; -- } -+ if (state == WL_POINTER_BUTTON_STATE_RELEASED) { -+ if (button == BTN_LEFT && seat->pointer.hovered_row_idx != -1) { -+ execute_selected(seat, false, -1); -+ } else if (button == BTN_RIGHT) { -+ // Same as pressing ESC -+ wayl->status = EXIT; -+ if (wayl->conf->dmenu.enabled) -+ wayl->exit_code = 2; - } - } - } -@@ -1119,19 +1118,16 @@ wl_pointer_axis(void *data, struct wl_pointer *wl_pointer, - { - struct seat *seat = data; - struct wayland *wayl = seat->wayl; -+ bool refresh = false; - -- if (wayl->conf->mouse_listener) { -- bool refresh = false; -+ if (value < 0) { -+ refresh = matches_selected_prev_page(wayl->matches, true); -+ } else if (value > 0) { -+ refresh = matches_selected_next_page(wayl->matches, true); -+ } - -- if (value < 0) { -- refresh = matches_selected_prev_page(wayl->matches); -- } else if (value > 0) { -- refresh = matches_selected_next_page(wayl->matches); -- } -- -- if (refresh) { -- select_hovered_match(wayl, seat->pointer.hovered_row_idx); -- } -+ if (refresh) { -+ select_hovered_match(seat, true); - } - } - --- -2.39.2 diff --git a/user/wm/plasma/plasma.nix b/user/wm/plasma/plasma.nix deleted file mode 100644 index 3ac8df0..0000000 --- a/user/wm/plasma/plasma.nix +++ /dev/null @@ -1,409 +0,0 @@ -{ config, lib, userSettings, pkgs, inputs, ... }: - -{ - imports = [ - ../../app/terminal/alacritty.nix - ../../app/terminal/kitty.nix - ../input/nihongo.nix - inputs.plasma-manager.homeManagerModules.plasma-manager - ]; - - home.packages = with pkgs; [ - inputs.kwin-effects-forceblur.packages.${pkgs.system}.default - kdePackages.kscreen - kdePackages.kirigami - kdePackages.plasma-desktop - kdePackages.plasma-workspace - kdePackages.kcmutils - alacritty - kitty - killall - papirus-icon-theme - libva-utils - libinput-gestures - gsettings-desktop-schemas - gnome.zenity - wlr-randr - wtype - ydotool - wl-clipboard - hyprpicker - keepmenu - pinentry-gnome3 - wev - grim - slurp - qt6.qtwayland - xdg-utils - kdePackages.xdg-desktop-portal-kde - wlsunset - pavucontrol - pamixer - tesseract4 - (pkgs.writeScriptBin "screenshot-ocr" '' - #!/bin/sh - imgname="/tmp/screenshot-ocr-$(date +%Y%m%d%H%M%S).png" - txtname="/tmp/screenshot-ocr-$(date +%Y%m%d%H%M%S)" - txtfname=$txtname.txt - grim -g "$(slurp)" $imgname; - tesseract $imgname $txtname; - wl-copy -n < $txtfname - '') - (pkgs.writeScriptBin "sct" '' - #!/bin/sh - killall wlsunset &> /dev/null; - if [ $# -eq 1 ]; then - temphigh=$(( $1 + 1 )) - templow=$1 - wlsunset -t $templow -T $temphigh &> /dev/null & - else - killall wlsunset &> /dev/null; - fi - '') - (pkgs.writeScriptBin "obs-notification-mute-daemon" '' - #!/bin/sh - while true; do - if pgrep -x .obs-wrapped > /dev/null; - then - pkill -STOP fnott; - else - pkill -CONT fnott; - fi - sleep 10; - done - '') - ]; - services.udiskie.enable = true; - services.udiskie.tray = "always"; - programs.fuzzel.enable = true; - programs.fuzzel.package = pkgs.fuzzel.overrideAttrs (oldAttrs: { - patches = ./patches/fuzzelmouseinput.patch; - }); - programs.fuzzel.settings = { - main = { - font = userSettings.font + ":size=20"; - dpi-aware = "no"; - show-actions = "yes"; - terminal = "${pkgs.alacritty}/bin/alacritty"; - }; - colors = { - background = config.lib.stylix.colors.base00 + "bf"; - text = config.lib.stylix.colors.base07 + "ff"; - match = config.lib.stylix.colors.base05 + "ff"; - selection = config.lib.stylix.colors.base08 + "ff"; - selection-text = config.lib.stylix.colors.base00 + "ff"; - selection-match = config.lib.stylix.colors.base05 + "ff"; - border = config.lib.stylix.colors.base08 + "ff"; - }; - border = { - width = 3; - radius = 7; - }; - }; - - programs.plasma = { - enable = true; - shortcuts = { - "ActivityManager"."switch-to-activity-196d243d-17bf-4ce9-a19d-c6ee428e78ee" = [ ]; - "KDE Keyboard Layout Switcher"."Switch to Last-Used Keyboard Layout" = "Meta+Alt+L"; - "KDE Keyboard Layout Switcher"."Switch to Next Keyboard Layout" = "Meta+Alt+K"; - "kaccess"."Toggle Screen Reader On and Off" = "Meta+Alt+S"; - "kcm_touchpad"."Disable Touchpad" = "Touchpad Off"; - "kcm_touchpad"."Enable Touchpad" = "Touchpad On"; - "kcm_touchpad"."Toggle Touchpad" = ["Touchpad Toggle" "Meta+Ctrl+Zenkaku Hankaku,Touchpad Toggle" "Meta+Ctrl+Zenkaku Hankaku"]; - "kmix"."decrease_microphone_volume" = "Microphone Volume Down"; - "kmix"."decrease_volume" = "Volume Down"; - "kmix"."decrease_volume_small" = "Shift+Volume Down"; - "kmix"."increase_microphone_volume" = "Microphone Volume Up"; - "kmix"."increase_volume" = "Volume Up"; - "kmix"."increase_volume_small" = "Shift+Volume Up"; - "kmix"."mic_mute" = ["Microphone Mute" "Meta+Volume Mute,Microphone Mute" "Meta+Volume Mute,Mute Microphone"]; - "kmix"."mute" = "Volume Mute"; - "ksmserver"."Halt Without Confirmation" = "none,,Shut Down Without Confirmation"; - "ksmserver"."Lock Session" = ["Meta+L" "Screensaver,Meta+L" "Screensaver,Lock Session"]; - "ksmserver"."Log Out" = "Ctrl+Alt+Del"; - "ksmserver"."Log Out Without Confirmation" = "Meta+Shift+Q,,Log Out Without Confirmation"; - "ksmserver"."LogOut" = "none,,Log Out"; - "ksmserver"."Reboot" = "none,,Reboot"; - "ksmserver"."Reboot Without Confirmation" = "none,,Reboot Without Confirmation"; - "ksmserver"."Shut Down" = "none,,Shut Down"; - "kwin"."Activate Window Demanding Attention" = "Meta+Ctrl+A"; - "kwin"."Cycle Overview" = [ ]; - "kwin"."Cycle Overview Opposite" = [ ]; - "kwin"."Decrease Opacity" = "none,,Decrease Opacity of Active Window by 5%"; - "kwin"."Edit Tiles" = "Meta+T"; - "kwin"."Expose" = "Ctrl+F9"; - "kwin"."ExposeAll" = ["Ctrl+F10" "Launch (C),Ctrl+F10" "Launch (C),Toggle Present Windows (All desktops)"]; - "kwin"."ExposeClass" = "Ctrl+F7"; - "kwin"."ExposeClassCurrentDesktop" = [ ]; - "kwin"."Grid View" = "Meta+G"; - "kwin"."Increase Opacity" = "none,,Increase Opacity of Active Window by 5%"; - "kwin"."Kill Window" = "Meta+Ctrl+Esc"; - "kwin"."Move Tablet to Next Output" = [ ]; - "kwin"."MoveMouseToCenter" = "Meta+F6"; - "kwin"."MoveMouseToFocus" = "Meta+F5"; - "kwin"."MoveZoomDown" = [ ]; - "kwin"."MoveZoomLeft" = [ ]; - "kwin"."MoveZoomRight" = [ ]; - "kwin"."MoveZoomUp" = [ ]; - "kwin"."Overview" = "Meta+W"; - "kwin"."Setup Window Shortcut" = "none,,Setup Window Shortcut"; - "kwin"."Show Desktop" = "Meta+D"; - "kwin"."Switch One Desktop Down" = "Meta+Ctrl+Down"; - "kwin"."Switch One Desktop Up" = "Meta+Ctrl+Up"; - "kwin"."Switch One Desktop to the Left" = "Meta+Ctrl+Left"; - "kwin"."Switch One Desktop to the Right" = "Meta+Ctrl+Right"; - "kwin"."Switch Window Down" = "Meta+Alt+Down"; - "kwin"."Switch Window Left" = "Meta+Alt+Left"; - "kwin"."Switch Window Right" = "Meta+Alt+Right"; - "kwin"."Switch Window Up" = "Meta+Alt+Up"; - "kwin"."Switch to Desktop 1" = "Ctrl+F1"; - "kwin"."Switch to Desktop 10" = "none,,Switch to Desktop 10"; - "kwin"."Switch to Desktop 11" = "none,,Switch to Desktop 11"; - "kwin"."Switch to Desktop 12" = "none,,Switch to Desktop 12"; - "kwin"."Switch to Desktop 13" = "none,,Switch to Desktop 13"; - "kwin"."Switch to Desktop 14" = "none,,Switch to Desktop 14"; - "kwin"."Switch to Desktop 15" = "none,,Switch to Desktop 15"; - "kwin"."Switch to Desktop 16" = "none,,Switch to Desktop 16"; - "kwin"."Switch to Desktop 17" = "none,,Switch to Desktop 17"; - "kwin"."Switch to Desktop 18" = "none,,Switch to Desktop 18"; - "kwin"."Switch to Desktop 19" = "none,,Switch to Desktop 19"; - "kwin"."Switch to Desktop 2" = "Ctrl+F2"; - "kwin"."Switch to Desktop 20" = "none,,Switch to Desktop 20"; - "kwin"."Switch to Desktop 3" = "Ctrl+F3"; - "kwin"."Switch to Desktop 4" = "Ctrl+F4"; - "kwin"."Switch to Desktop 5" = "none,,Switch to Desktop 5"; - "kwin"."Switch to Desktop 6" = "none,,Switch to Desktop 6"; - "kwin"."Switch to Desktop 7" = "none,,Switch to Desktop 7"; - "kwin"."Switch to Desktop 8" = "none,,Switch to Desktop 8"; - "kwin"."Switch to Desktop 9" = "none,,Switch to Desktop 9"; - "kwin"."Switch to Next Desktop" = "none,,Switch to Next Desktop"; - "kwin"."Switch to Next Screen" = "none,,Switch to Next Screen"; - "kwin"."Switch to Previous Desktop" = "none,,Switch to Previous Desktop"; - "kwin"."Switch to Previous Screen" = "none,,Switch to Previous Screen"; - "kwin"."Switch to Screen 0" = "none,,Switch to Screen 0"; - "kwin"."Switch to Screen 1" = "none,,Switch to Screen 1"; - "kwin"."Switch to Screen 2" = "none,,Switch to Screen 2"; - "kwin"."Switch to Screen 3" = "none,,Switch to Screen 3"; - "kwin"."Switch to Screen 4" = "none,,Switch to Screen 4"; - "kwin"."Switch to Screen 5" = "none,,Switch to Screen 5"; - "kwin"."Switch to Screen 6" = "none,,Switch to Screen 6"; - "kwin"."Switch to Screen 7" = "none,,Switch to Screen 7"; - "kwin"."Switch to Screen Above" = "none,,Switch to Screen Above"; - "kwin"."Switch to Screen Below" = "none,,Switch to Screen Below"; - "kwin"."Switch to Screen to the Left" = "none,,Switch to Screen to the Left"; - "kwin"."Switch to Screen to the Right" = "none,,Switch to Screen to the Right"; - "kwin"."Toggle Night Color" = [ ]; - "kwin"."Toggle Window Raise/Lower" = "none,,Toggle Window Raise/Lower"; - "kwin"."Walk Through Windows" = "Alt+Tab"; - "kwin"."Walk Through Windows (Reverse)" = "Alt+Shift+Tab"; - "kwin"."Walk Through Windows Alternative" = "none,,Walk Through Windows Alternative"; - "kwin"."Walk Through Windows Alternative (Reverse)" = "none,,Walk Through Windows Alternative (Reverse)"; - "kwin"."Walk Through Windows of Current Application" = "Alt+`"; - "kwin"."Walk Through Windows of Current Application (Reverse)" = "Alt+~"; - "kwin"."Walk Through Windows of Current Application Alternative" = "none,,Walk Through Windows of Current Application Alternative"; - "kwin"."Walk Through Windows of Current Application Alternative (Reverse)" = "none,,Walk Through Windows of Current Application Alternative (Reverse)"; - "kwin"."Window Above Other Windows" = "none,,Keep Window Above Others"; - "kwin"."Window Below Other Windows" = "none,,Keep Window Below Others"; - "kwin"."Window Close" = "Alt+F4"; - "kwin"."Window Fullscreen" = "none,,Make Window Fullscreen"; - "kwin"."Window Grow Horizontal" = "none,,Expand Window Horizontally"; - "kwin"."Window Grow Vertical" = "none,,Expand Window Vertically"; - "kwin"."Window Lower" = "none,,Lower Window"; - "kwin"."Window Maximize" = "Meta+PgUp"; - "kwin"."Window Maximize Horizontal" = "none,,Maximize Window Horizontally"; - "kwin"."Window Maximize Vertical" = "none,,Maximize Window Vertically"; - "kwin"."Window Minimize" = "Meta+PgDown"; - "kwin"."Window Move" = "none,,Move Window"; - "kwin"."Window Move Center" = "none,,Move Window to the Center"; - "kwin"."Window No Border" = "none,,Toggle Window Titlebar and Frame"; - "kwin"."Window On All Desktops" = "none,,Keep Window on All Desktops"; - "kwin"."Window One Desktop Down" = "Meta+Ctrl+Shift+Down"; - "kwin"."Window One Desktop Up" = "Meta+Ctrl+Shift+Up"; - "kwin"."Window One Desktop to the Left" = "Meta+Ctrl+Shift+Left"; - "kwin"."Window One Desktop to the Right" = "Meta+Ctrl+Shift+Right"; - "kwin"."Window One Screen Down" = "none,,Move Window One Screen Down"; - "kwin"."Window One Screen Up" = "none,,Move Window One Screen Up"; - "kwin"."Window One Screen to the Left" = "none,,Move Window One Screen to the Left"; - "kwin"."Window One Screen to the Right" = "none,,Move Window One Screen to the Right"; - "kwin"."Window Operations Menu" = "Alt+F3"; - "kwin"."Window Pack Down" = "none,,Move Window Down"; - "kwin"."Window Pack Left" = "none,,Move Window Left"; - "kwin"."Window Pack Right" = "none,,Move Window Right"; - "kwin"."Window Pack Up" = "none,,Move Window Up"; - "kwin"."Window Quick Tile Bottom" = "Meta+Down"; - "kwin"."Window Quick Tile Bottom Left" = "none,,Quick Tile Window to the Bottom Left"; - "kwin"."Window Quick Tile Bottom Right" = "none,,Quick Tile Window to the Bottom Right"; - "kwin"."Window Quick Tile Left" = "Meta+Left"; - "kwin"."Window Quick Tile Right" = "Meta+Right"; - "kwin"."Window Quick Tile Top" = "Meta+Up"; - "kwin"."Window Quick Tile Top Left" = "none,,Quick Tile Window to the Top Left"; - "kwin"."Window Quick Tile Top Right" = "none,,Quick Tile Window to the Top Right"; - "kwin"."Window Raise" = "none,,Raise Window"; - "kwin"."Window Resize" = "none,,Resize Window"; - "kwin"."Window Shade" = "none,,Shade Window"; - "kwin"."Window Shrink Horizontal" = "none,,Shrink Window Horizontally"; - "kwin"."Window Shrink Vertical" = "none,,Shrink Window Vertically"; - "kwin"."Window to Desktop 1" = "none,,Window to Desktop 1"; - "kwin"."Window to Desktop 10" = "none,,Window to Desktop 10"; - "kwin"."Window to Desktop 11" = "none,,Window to Desktop 11"; - "kwin"."Window to Desktop 12" = "none,,Window to Desktop 12"; - "kwin"."Window to Desktop 13" = "none,,Window to Desktop 13"; - "kwin"."Window to Desktop 14" = "none,,Window to Desktop 14"; - "kwin"."Window to Desktop 15" = "none,,Window to Desktop 15"; - "kwin"."Window to Desktop 16" = "none,,Window to Desktop 16"; - "kwin"."Window to Desktop 17" = "none,,Window to Desktop 17"; - "kwin"."Window to Desktop 18" = "none,,Window to Desktop 18"; - "kwin"."Window to Desktop 19" = "none,,Window to Desktop 19"; - "kwin"."Window to Desktop 2" = "none,,Window to Desktop 2"; - "kwin"."Window to Desktop 20" = "none,,Window to Desktop 20"; - "kwin"."Window to Desktop 3" = "none,,Window to Desktop 3"; - "kwin"."Window to Desktop 4" = "none,,Window to Desktop 4"; - "kwin"."Window to Desktop 5" = "none,,Window to Desktop 5"; - "kwin"."Window to Desktop 6" = "none,,Window to Desktop 6"; - "kwin"."Window to Desktop 7" = "none,,Window to Desktop 7"; - "kwin"."Window to Desktop 8" = "none,,Window to Desktop 8"; - "kwin"."Window to Desktop 9" = "none,,Window to Desktop 9"; - "kwin"."Window to Next Desktop" = "none,,Window to Next Desktop"; - "kwin"."Window to Next Screen" = "Meta+Shift+Right"; - "kwin"."Window to Previous Desktop" = "none,,Window to Previous Desktop"; - "kwin"."Window to Previous Screen" = "Meta+Shift+Left"; - "kwin"."Window to Screen 0" = "none,,Move Window to Screen 0"; - "kwin"."Window to Screen 1" = "none,,Move Window to Screen 1"; - "kwin"."Window to Screen 2" = "none,,Move Window to Screen 2"; - "kwin"."Window to Screen 3" = "none,,Move Window to Screen 3"; - "kwin"."Window to Screen 4" = "none,,Move Window to Screen 4"; - "kwin"."Window to Screen 5" = "none,,Move Window to Screen 5"; - "kwin"."Window to Screen 6" = "none,,Move Window to Screen 6"; - "kwin"."Window to Screen 7" = "none,,Move Window to Screen 7"; - "kwin"."view_actual_size" = "Meta+0"; - "kwin"."view_zoom_in" = ["Meta++" "Meta+=,Meta++" "Meta+=,Zoom In"]; - "kwin"."view_zoom_out" = "Meta+-"; - "mediacontrol"."mediavolumedown" = "none,,Media volume down"; - "mediacontrol"."mediavolumeup" = "none,,Media volume up"; - "mediacontrol"."nextmedia" = "Media Next"; - "mediacontrol"."pausemedia" = "Media Pause"; - "mediacontrol"."playmedia" = "none,,Play media playback"; - "mediacontrol"."playpausemedia" = "Media Play"; - "mediacontrol"."previousmedia" = "Media Previous"; - "mediacontrol"."stopmedia" = "Media Stop"; - "org_kde_powerdevil"."Decrease Keyboard Brightness" = "Keyboard Brightness Down"; - "org_kde_powerdevil"."Decrease Screen Brightness" = "Monitor Brightness Down"; - "org_kde_powerdevil"."Decrease Screen Brightness Small" = "Shift+Monitor Brightness Down"; - "org_kde_powerdevil"."Hibernate" = "Hibernate"; - "org_kde_powerdevil"."Increase Keyboard Brightness" = "Keyboard Brightness Up"; - "org_kde_powerdevil"."Increase Screen Brightness" = "Monitor Brightness Up"; - "org_kde_powerdevil"."Increase Screen Brightness Small" = "Shift+Monitor Brightness Up"; - "org_kde_powerdevil"."PowerDown" = "Power Down"; - "org_kde_powerdevil"."PowerOff" = "Power Off"; - "org_kde_powerdevil"."Sleep" = ["Meta+Shift+S" "Sleep,Sleep,Suspend"]; - "org_kde_powerdevil"."Toggle Keyboard Backlight" = "Keyboard Light On/Off"; - "org_kde_powerdevil"."Turn Off Screen" = [ ]; - "org_kde_powerdevil"."powerProfile" = ["Battery" "Meta+B,Battery" "Meta+B,Switch Power Profile"]; - "plasmashell"."activate application launcher" = ["Meta" "Alt+F1,Meta" "Alt+F1,Activate Application Launcher"]; - "plasmashell"."activate task manager entry 1" = "Meta+1"; - "plasmashell"."activate task manager entry 10" = "none,Meta+0,Activate Task Manager Entry 10"; - "plasmashell"."activate task manager entry 2" = "Meta+2"; - "plasmashell"."activate task manager entry 3" = "Meta+3"; - "plasmashell"."activate task manager entry 4" = "Meta+4"; - "plasmashell"."activate task manager entry 5" = "Meta+5"; - "plasmashell"."activate task manager entry 6" = "Meta+6"; - "plasmashell"."activate task manager entry 7" = "Meta+7"; - "plasmashell"."activate task manager entry 8" = "Meta+8"; - "plasmashell"."activate task manager entry 9" = "Meta+9"; - "plasmashell"."clear-history" = "none,,Clear Clipboard History"; - "plasmashell"."clipboard_action" = "Meta+Ctrl+X"; - "plasmashell"."cycle-panels" = "Meta+Alt+P"; - "plasmashell"."cycleNextAction" = "none,,Next History Item"; - "plasmashell"."cyclePrevAction" = "none,,Previous History Item"; - "plasmashell"."manage activities" = "Meta+Q"; - "plasmashell"."next activity" = [ ]; - "plasmashell"."previous activity" = "Meta+Shift+A,none,Walk through activities (Reverse)"; - "plasmashell"."repeat_action" = "none,Meta+Ctrl+R,Manually Invoke Action on Current Clipboard"; - "plasmashell"."show dashboard" = "Ctrl+F12"; - "plasmashell"."show-barcode" = "none,,Show Barcode…"; - "plasmashell"."show-on-mouse-pos" = "Meta+V"; - "plasmashell"."stop current activity" = "none,Meta+S,Stop Current Activity"; - "plasmashell"."switch to next activity" = "none,,Switch to Next Activity"; - "plasmashell"."switch to previous activity" = "none,,Switch to Previous Activity"; - "plasmashell"."toggle do not disturb" = "none,,Toggle do not disturb"; - "services/Alacritty.desktop"."_launch" = "Meta+Return"; - "services/emacsclient.desktop"."_launch" = "Meta+A"; - "services/org.gnome.Lollypop.desktop"."_launch" = "Meta+M"; - "services/org.qutebrowser.qutebrowser.desktop"."new-window" = "Meta+S"; - "services/ranger.desktop"."_launch" = "Meta+F"; - }; - configFile = { - "baloofilerc"."General"."dbVersion" = 2; - "baloofilerc"."General"."exclude filters" = "*~,*.part,*.o,*.la,*.lo,*.loT,*.moc,moc_*.cpp,qrc_*.cpp,ui_*.h,cmake_install.cmake,CMakeCache.txt,CTestTestfile.cmake,libtool,config.status,confdefs.h,autom4te,conftest,confstat,Makefile.am,*.gcode,.ninja_deps,.ninja_log,build.ninja,*.csproj,*.m4,*.rej,*.gmo,*.pc,*.omf,*.aux,*.tmp,*.po,*.vm*,*.nvram,*.rcore,*.swp,*.swap,lzo,litmain.sh,*.orig,.histfile.*,.xsession-errors*,*.map,*.so,*.a,*.db,*.qrc,*.ini,*.init,*.img,*.vdi,*.vbox*,vbox.log,*.qcow2,*.vmdk,*.vhd,*.vhdx,*.sql,*.sql.gz,*.ytdl,*.tfstate*,*.class,*.pyc,*.pyo,*.elc,*.qmlc,*.jsc,*.fastq,*.fq,*.gb,*.fasta,*.fna,*.gbff,*.faa,po,CVS,.svn,.git,_darcs,.bzr,.hg,CMakeFiles,CMakeTmp,CMakeTmpQmake,.moc,.obj,.pch,.uic,.npm,.yarn,.yarn-cache,__pycache__,node_modules,node_packages,nbproject,.terraform,.venv,venv,core-dumps,lost+found"; - "baloofilerc"."General"."exclude filters version" = 9; - "dolphinrc"."General"."ViewPropsTimestamp" = "2024,8,16,7,19,36.713"; - "dolphinrc"."KFileDialog Settings"."Places Icons Auto-resize" = false; - "dolphinrc"."KFileDialog Settings"."Places Icons Static Size" = 22; - "kactivitymanagerdrc"."activities"."196d243d-17bf-4ce9-a19d-c6ee428e78ee" = "Default"; - "kactivitymanagerdrc"."main"."currentActivity" = "196d243d-17bf-4ce9-a19d-c6ee428e78ee"; - "kcminputrc"."Mouse"."cursorTheme" = "Breeze_Snow"; - "kded5rc"."Module-device_automounter"."autoload" = false; - "kwalletrc"."Wallet"."First Use" = false; - "kwinrc"."Desktops"."Id_1" = "ef552d47-670a-433e-899a-c588966a1ddb"; - "kwinrc"."Desktops"."Number" = 1; - "kwinrc"."Desktops"."Rows" = 1; - "kwinrc"."Effect-blur"."BlurStrength" = 11; - "kwinrc"."Effect-blur"."NoiseStrength" = 10; - "kwinrc"."Effect-blurplus"."BlurDecorations" = true; - "kwinrc"."Effect-blurplus"."BlurDocks" = true; - "kwinrc"."Effect-blurplus"."BlurMatching" = false; - "kwinrc"."Effect-blurplus"."BlurMenus" = true; - "kwinrc"."Effect-blurplus"."BlurNonMatching" = true; - "kwinrc"."Effect-blurplus"."BlurStrength" = 3; - "kwinrc"."Effect-blurplus"."NoiseStrength" = 1; - "kwinrc"."Effect-blurplus"."PaintAsTranslucent" = true; - "kwinrc"."Effect-blurplus"."WindowClasses" = ""; - "kwinrc"."Effect-hidecursor"."InactivityDuration" = 30; - "kwinrc"."Effect-translucency"."ComboboxPopups" = 86; - "kwinrc"."Effect-translucency"."Dialogs" = 91; - "kwinrc"."Effect-translucency"."DropdownMenus" = 67; - "kwinrc"."Effect-translucency"."Menus" = 72; - "kwinrc"."Effect-translucency"."PopupMenus" = 66; - "kwinrc"."Effect-translucency"."TornOffMenus" = 78; - "kwinrc"."Plugins"."blurEnabled" = false; - "kwinrc"."Plugins"."contrastEnabled" = true; - "kwinrc"."Plugins"."forceblurEnabled" = true; - "kwinrc"."Plugins"."glideEnabled" = true; - "kwinrc"."Plugins"."hidecursorEnabled" = true; - "kwinrc"."Plugins"."kwin4_effect_scaleEnabled" = false; - "kwinrc"."Plugins"."scaleEnabled" = false; - "kwinrc"."Plugins"."translucencyEnabled" = true; - "kwinrc"."Tiling"."padding" = 4; - "kwinrc"."Tiling/87800f1d-2082-567e-926f-a35920010193"."tiles" = "{\"layoutDirection\":\"horizontal\",\"tiles\":[{\"width\":0.25},{\"width\":0.5},{\"width\":0.25}]}"; - "kwinrc"."Windows"."DelayFocusInterval" = 0; - "kwinrc"."Xwayland"."Scale" = 1; - "kwinrulesrc"."2b96a368-58bc-4b94-84ed-8f62a4cec294"."Description" = "Window settings for kitty"; - "kwinrulesrc"."2b96a368-58bc-4b94-84ed-8f62a4cec294"."desktopfile" = "/home/emmet/.nix-profile/share/applications/ranger.desktop"; - "kwinrulesrc"."2b96a368-58bc-4b94-84ed-8f62a4cec294"."desktopfilerule" = 2; - "kwinrulesrc"."2b96a368-58bc-4b94-84ed-8f62a4cec294"."title" = "ranger"; - "kwinrulesrc"."2b96a368-58bc-4b94-84ed-8f62a4cec294"."titlematch" = 1; - "kwinrulesrc"."2b96a368-58bc-4b94-84ed-8f62a4cec294"."types" = 1; - "kwinrulesrc"."2b96a368-58bc-4b94-84ed-8f62a4cec294"."wmclass" = "kitty"; - "kwinrulesrc"."2b96a368-58bc-4b94-84ed-8f62a4cec294"."wmclassmatch" = 1; - "kwinrulesrc"."58e3a02a-bebb-4589-8309-88709568d99d"."Description" = "Window settings for emacs"; - "kwinrulesrc"."58e3a02a-bebb-4589-8309-88709568d99d"."desktopfile" = "/home/emmet/.nix-profile/share/applications/emacsclient.desktop"; - "kwinrulesrc"."58e3a02a-bebb-4589-8309-88709568d99d"."desktopfilerule" = 3; - "kwinrulesrc"."58e3a02a-bebb-4589-8309-88709568d99d"."title" = "plasma.nix – Doom Emacs"; - "kwinrulesrc"."58e3a02a-bebb-4589-8309-88709568d99d"."types" = 1; - "kwinrulesrc"."58e3a02a-bebb-4589-8309-88709568d99d"."wmclass" = "emacs-29.3 emacs"; - "kwinrulesrc"."58e3a02a-bebb-4589-8309-88709568d99d"."wmclasscomplete" = true; - "kwinrulesrc"."58e3a02a-bebb-4589-8309-88709568d99d"."wmclassmatch" = 1; - "kwinrulesrc"."General"."count" = 2; - "kwinrulesrc"."General"."rules" = "2b96a368-58bc-4b94-84ed-8f62a4cec294,58e3a02a-bebb-4589-8309-88709568d99d"; - "kxkbrc"."Layout"."DisplayNames" = ""; - "kxkbrc"."Layout"."LayoutList" = "us"; - "kxkbrc"."Layout"."Use" = true; - "kxkbrc"."Layout"."VariantList" = ""; - "plasma-localerc"."Formats"."LANG" = "en_US.UTF-8"; - "plasmarc"."Wallpapers"."usersWallpapers" = ""; - }; - }; - stylix.targets.kde.enable = true; - home.file.".config/kdeglobals".enable = lib.mkForce false; -} diff --git a/user/wm/xmonad/README.org b/user/wm/xmonad/README.org new file mode 100644 index 0000000..79692bb --- /dev/null +++ b/user/wm/xmonad/README.org @@ -0,0 +1,28 @@ +#+title: XMonad +#+author: Emmet + +* What is XMonad? +[[https://xmonad.org/][XMonad]] is a tiling window manager written and configured in Haskell. Since I have built up my own XMonad config over a few years, it is extremely efficient for me to operate (since it can be managed fully with the keyboard). + +[[xmonad.png]] + +With my XMonad setup, there are several auxiliary utilities required to make it a "full desktop environment." A few of these packages include: +- [[https://codeberg.org/xmobar/xmobar][xmobar]] - Status bar +- [[https://github.com/davatorium/rofi][rofi]] - App launcher +- [[https://github.com/sagb/alttab][alttab]] - Window switcher +- [[https://feh.finalrewind.org/][feh]] - Wallpaper utility +- pavucontrol and pamixer - Sound and volume control +- [[https://github.com/firecat53/networkmanager-dmenu][networkmanager_dmenu]] - Internet connection control +- brightnessctl - Screen brightness control +- [[https://www.umaxx.net/][sct]] - Adjust screen color temperature +- xkill and killall - Better than hitting Ctrl+Alt+Delete and waiting a few minutes + +* My Config +This directory includes my XMonad configuration, which consists of: +- [[./xmonad.hs][xmonad.hs]] - Main configuration +- [[./startup.sh][startup.sh]] - Startup script called by XMonad on startup +- [[./lib/Colors/Stylix.hs.mustache][lib/Colors/Stylix.hs.mustache]] - Mustache template used to generate color library to theme XMonad with Stylix +- [[./xmobarrc.mustache][xmobarrc.mustache]] - Mustache template used to generate my xmobar config themed with Stylix +- [[./xmonad.nix][xmonad.nix]] - Loads XMonad and my configuration (along with any necessary packages for my config) into my flake when imported + +My full config is a [[./xmonad.org][literate org document (xmonad.org)]]. diff --git a/user/wm/xmonad/lib/Colors/Stylix.hs.mustache b/user/wm/xmonad/lib/Colors/Stylix.hs.mustache new file mode 100644 index 0000000..d5ff51d --- /dev/null +++ b/user/wm/xmonad/lib/Colors/Stylix.hs.mustache @@ -0,0 +1,18 @@ +module Colors.Stylix where + +import XMonad + +colorBg = "#{{base00-hex}}" +colorFg = "#{{base05-hex}}" +color01 = "#{{base01-hex}}" -- usually black +color02 = "#{{base08-hex}}" -- usually red +color03 = "#{{base0B-hex}}" -- usually green +color04 = "#{{base0A-hex}}" -- usually yellow +color05 = "#{{base0E-hex}}" -- usually blue +color06 = "#{{base0F-hex}}" -- usually magenta +color07 = "#{{base0D-hex}}" -- usually cyan +color08 = "#{{base07-hex}}" -- usually white + +-- Select focus and secondary color +colorFocus = color02 +colorSecondary = color07 diff --git a/user/wm/xmonad/startup.sh b/user/wm/xmonad/startup.sh new file mode 100755 index 0000000..3995843 --- /dev/null +++ b/user/wm/xmonad/startup.sh @@ -0,0 +1,26 @@ +colorBg=$1 +colorFg=$2 +colorFocus=$3 +colorSecondary=$4 + +# Startup shell script called by xmonad to start necessary programs +# +## Kill previous instances of applications (Prevents multiple instances of the following if XMonad is restarted durin the X session) +killall xmobar +killall nm-applet + +# Launch necessary desktop applications +autorandr; +picom --animations --animation-window-mass 1 --animation-for-open-window zoom --animation-stiffness 200 --experimental-backends && # requires picom-pijulius +xset r rate 350 50 & +setxkbmap -option caps:escape & +~/.fehbg-stylix & +~/.config/xmobar/xmobar-st-check.sh & +alttab -w 1 -t 240x160 -i 64x64 -sc 1 -bg $colorBg -fg $colorFg -frame $colorSecondary -inact $colorFg & +##/usr/bin/trayer --edge top --align right --SetDockType true --SetPartialStrut true --expand true --widthtype request --transparent true --alpha 0 --height 28 --tint $trayertint --monitor "primary" & +nm-applet & +GOMAXPROCS=1 syncthing --no-browser & +protonmail-bridge --noninteractive & +emacs --daemon & +gnome-keyring-daemon --daemonize --login & +gnome-keyring-daemon --start --components=secrets & diff --git a/user/wm/xmonad/xmobar-st-check.sh.mustache b/user/wm/xmonad/xmobar-st-check.sh.mustache new file mode 100644 index 0000000..4e09949 --- /dev/null +++ b/user/wm/xmonad/xmobar-st-check.sh.mustache @@ -0,0 +1,7 @@ +#!/bin/sh +while true + do + curl localhost:8384 -m 1 &> /dev/null || echo '❄ st off' > ~/.st-status; + curl localhost:8384 -m 1 &> /dev/null && echo '↺ st on' > ~/.st-status; + sleep 5; + done diff --git a/user/wm/xmonad/xmobarrc.mustache b/user/wm/xmonad/xmobarrc.mustache new file mode 100644 index 0000000..0d9dcba --- /dev/null +++ b/user/wm/xmonad/xmobarrc.mustache @@ -0,0 +1,55 @@ +Config { font = "Inconsolata 16" + , additionalFonts = ["Symbols Nerd Font 14"] + , border = NoBorder + , bgColor = "#{{base00-hex}}" + , alpha = 200 + , fgColor = "#{{base05-hex}}" + , position = TopSize C 100 28 + , textOffset = -1 + , iconOffset = -1 + , lowerOnStart = True + , pickBroadest = False + , persistent = False + , hideOnStart = False + , iconRoot = "." + , allDesktops = True + , overrideRedirect = True + , commands = [ + Run XMonadLog + , Run Date " \xf073 %a %-m/%-d/%y %-I:%M:%S%P" "date" 10 + , Run BatteryP ["BAT0"] + ["-t", "", + "-L", "10", "-H", "80", "-p", "3", "--", + "-O","\xf313 \xf17e3 % ", + "-i","\xf313 \xf17e7 % ", + "-o","\xf313 \xf17e4 % ", + "-L", "-15", "-H", "-5", + "-l", "#{{base08-hex}}", "-m", "#{{base05-hex}}", "-h", "#{{base0B-hex}}"] 10 + , Run Brightness + [ "-t", "\xf0eb % ", "--", + "-D", "amdgpu_bl1" + ] 2 + , Run Volume "default" "Master" + [ "-t", "", "--" + , "--on", " \xf028 % " + , "--onc", "#{{base0D-hex}}" + , "--off", " \xf026 Mute " + , "--offc", "#{{base0F-hex}}" + ] 1 + , Run DynNetwork + [ "-t", "\xf0200 "] 1 + , Run Com "cat" + [ "/home/emmet/.st-status"] "syncthing" 10 + , Run Com "echo" + [ "\xea77 "] "syncthingsymbol" 0 + , Run Com "echo" + [ "\xeb5c "] "artsymbol" 0 + , Run Com "cat" + [ "/home/emmet/.currenttheme"] "currenttheme" 0 + , Run Memory [ "-t", "\xf035b % ( GB)", "-d", "1", "--", "--scale", "1024"] 20 + ] + , sepChar = "%" + , alignSep = "}{" + , template = " %battery% %bright%%default:Master% %memory% %artsymbol%%currenttheme%}%XMonadLog%{%syncthing% %dynnetwork% %date% " + } +} diff --git a/user/wm/xmonad/xmonad.hs b/user/wm/xmonad/xmonad.hs new file mode 100644 index 0000000..db64d50 --- /dev/null +++ b/user/wm/xmonad/xmonad.hs @@ -0,0 +1,473 @@ +-- IMPORTS +import qualified Data.Map as M +import Control.Monad as C +import Data.List +import Data.Monoid +import Data.Maybe (fromJust) +import Graphics.X11.ExtraTypes.XF86 +import System.Exit +import System.IO +import XMonad +import XMonad.Actions.Navigation2D +import XMonad.Actions.SpawnOn +import XMonad.Actions.TiledWindowDragging +import XMonad.Actions.Warp +import XMonad.Actions.WindowNavigation +import XMonad.Actions.WithAll +import XMonad.Hooks.DynamicLog +import qualified XMonad.Hooks.EwmhDesktops as EWMHD +import XMonad.Hooks.FadeWindows +import XMonad.Hooks.ManageDocks +import XMonad.Hooks.RefocusLast +import XMonad.Hooks.ServerMode +import XMonad.Hooks.StatusBar +import XMonad.Hooks.StatusBar.PP +import XMonad.Layout.DraggingVisualizer +import XMonad.Layout.Dwindle +import XMonad.Layout.Fullscreen +import XMonad.Layout.Gaps +import XMonad.Layout.LayoutHints +import XMonad.Layout.LimitWindows +import XMonad.Layout.MouseResizableTile +import XMonad.Layout.Spacing +import XMonad.ManageHook +import qualified XMonad.StackSet as W +--import qualified DBus as D +--import qualified DBus.Client as D +import XMonad.Util.NamedScratchpad +import XMonad.Util.Run +import XMonad.Util.SpawnOnce + +-- setup color variables +import Colors.Stylix + +-- Border colors for unfocused and focused windows, respectively. +myNormalBorderColor, myFocusedBorderColor :: String +myNormalBorderColor = colorBg +myFocusedBorderColor = colorFocus + +-- Default apps +myTerminal, myBrowser :: String +myTerminal = "$TERM" +myBrowser = "$BROWSER" +myEditor = "$EDITOR" +mySpawnEditor = "$SPAWNEDITOR" + +-- Whether focus follows the mouse pointer. +myFocusFollowsMouse :: Bool +myFocusFollowsMouse = False + +-- Whether clicking on a window to focus also passes the click to the window +myClickJustFocuses :: Bool +myClickJustFocuses = False + +-- Width of the window border in pixels. +myBorderWidth :: Dimension +myBorderWidth = 3 + +-- Modmask +myModMask :: KeyMask +myModMask = mod4Mask + +myWorkspaces :: [String] +myWorkspaces = + [ "\xf15c¹", -- document icon for writing + "\xeb01 ²", -- globe icon for browsing + "\xf121³", -- dev icon for programming + "\xf0cb9 ⁴", -- music file icon for composition + "\xf1fc⁵", -- paint icon for art + "\xf0bdc ⁶", -- video icon for recording/editing + "\xf0d6⁷", -- money icon for finances + "\xf19d⁸", -- cap icon for teaching + "\xf11b⁹" -- gamepad icon for gaming + ] + +myWorkspaceIndices = M.fromList $ zipWith (,) myWorkspaces [1..] -- (,) == \x y -> (x,y) + +clickable ws = ""++ws++"" + where i = fromJust $ M.lookup ws myWorkspaceIndices + +-- Scratchpads +myScratchPads :: [NamedScratchpad] +myScratchPads = + [ NS "terminal" spawnTerm findTerm manageTerm, + NS "ranger" spawnRanger findRanger manageRanger, + NS "octave" spawnOctave findOctave manageOctave, + NS "btm" spawnBtm findBtm manageBtm, + NS "geary" spawnGeary findGeary manageGeary, + NS "helpmenu" spawnHelp findHelp manageHelp, + NS "musikcube" spawnMusikcube findMusikcube manageMusikcube, + NS "cal" spawnCal findCal manageCal, + NS "pavucontrol" spawnPavucontrol findPavucontrol managePavucontrol, + NS "discord" spawnDiscord findDiscord manageDiscord + ] + where + spawnTerm = myTerminal ++ " --title scratchpad" + findTerm = title =? "scratchpad" + manageTerm = customFloating $ W.RationalRect l t w h + where + h = 0.9 + w = 0.9 + t = 0.95 - h + l = 0.95 - w + spawnRanger = "kitty --title ranger-scratchpad -e ranger" + findRanger = title =? "ranger-scratchpad" + manageRanger = customFloating $ W.RationalRect l t w h + where + h = 0.9 + w = 0.9 + t = 0.95 - h + l = 0.95 - w + spawnOctave = myTerminal ++ " --title octave-scratchpad -e octave" + findOctave = title =? "octave-scratchpad" + manageOctave = customFloating $ W.RationalRect l t w h + where + h = 0.5 + w = 0.4 + t = 0.75 - h + l = 0.70 - w + spawnBtm = myTerminal ++ " -o font.size=12 --title btm-scratchpad -e btm" + findBtm = title =? "btm-scratchpad" + manageBtm = customFloating $ W.RationalRect l t w h + where + h = 0.5 + w = 0.4 + t = 0.75 - h + l = 0.70 - w + spawnDiscord = "gtkcord4" + findDiscord = className =? "gtkcord4" + manageDiscord = customFloating $ W.RationalRect l t w h + where + h = 0.5 + w = 0.4 + t = 0.75 - h + l = 0.70 - w + spawnGeary = "geary" + findGeary = className =? "Geary" + manageGeary = customFloating $ W.RationalRect l t w h + where + h = 0.5 + w = 0.4 + t = 0.75 - h + l = 0.70 - w + spawnHelp = myTerminal ++ " --title xmonad_helpmenu -e w3m ~/.xmonad/helpmenu.txt" + findHelp = title =? "xmonad_helpmenu" + manageHelp = customFloating $ W.RationalRect l t w h + where + h = 0.9 + w = 0.9 + t = 0.95 - h + l = 0.95 - w + spawnMusikcube = myTerminal ++ " -o font.size=14 --title musikcube-scratchpad -e musikcube" + findMusikcube = title =? "musikcube-scratchpad" + manageMusikcube = customFloating $ W.RationalRect l t w h + where + h = 0.9 + w = 0.9 + t = 0.95 - h + l = 0.95 - w + spawnCal = "gnome-calendar" + findCal = className =? "gnome-calendar" + manageCal = customFloating $ W.RationalRect l t w h + where + h = 0.4 + w = 0.3 + t = 0.45 - h + l = 1 - w + spawnPavucontrol = "pavucontrol" + findPavucontrol = className =? "Pavucontrol" + managePavucontrol = customFloating $ W.RationalRect l t w h + where + h = 0.5 + w = 0.3 + t = 0.9 - h + l = 0.65 - w + +myKeys conf@(XConfig {XMonad.modMask = modm}) = + M.fromList $ + [ + -- insert keybinds with array values of ((keybind, action)) + + -- launch a terminal + ((modm, xK_Return), spawn $ XMonad.terminal conf), + + -- launch emacsclient + ((modm, xK_a), spawn mySpawnEditor), + + -- launch browser + ((modm, xK_s), spawn myBrowser), + + -- take screenshots + ((0, xK_Print), spawn "flameshot gui"), -- snip screenshot and save + ((controlMask, xK_Print), spawn "flameshot gui --clipboard"), -- snip screenshot to clipboard + ((shiftMask, xK_Print), spawn "flameshot screen"), -- screen capture current monitor and save + ((controlMask .|. shiftMask, xK_Print), spawn "flameshot screen -c"), -- screen capture current monitor to clipboard + + -- launch game manager in gaming workspace + ((modm, xK_g), spawn "xdotool key Super+9 && gamehub"), + + -- control brightness from kbd + ((0, xF86XK_MonBrightnessUp), spawn "brightnessctl set +15"), + ((0, xF86XK_MonBrightnessDown), spawn "brightnessctl set 15-"), + + -- control kbd brightness from kbd + ((0, xF86XK_KbdBrightnessUp), spawn "brightnessctl --device='asus::kbd_backlight' set +1 & xset r rate 350 100"), + ((0, xF86XK_KbdBrightnessDown), spawn "brightnessctl --device='asus::kbd_backlight' set 1- & xset r rate 350 100"), + ((shiftMask, xF86XK_MonBrightnessUp), spawn "brightnessctl --device='asus::kbd_backlight' set +1 & xset r rate 350 100"), + ((shiftMask, xF86XK_MonBrightnessDown), spawn "brightnessctl --device='asus::kbd_backlight' set 1- & xset r rate 350 100"), + + -- control volume from kbd + ((0, xF86XK_AudioLowerVolume), spawn "pamixer -d 10"), + ((0, xF86XK_AudioRaiseVolume), spawn "pamixer -i 10"), + ((0, xF86XK_AudioMute), spawn "pamixer -t"), + + -- control music from kbd + --((0, xF86XK_AudioPlay), spawn "cmus-remote -u"), + --((0, xF86XK_AudioStop), spawn "cmus-remote -s"), + --((0, xF86XK_AudioNext), spawn "cmus-remote -n && ~/.local/bin/cmus-current-song-notify.sh"), + --((0, xF86XK_AudioPrev), spawn "cmus-remote -r && ~/.local/bin/cmus-current-song-notify.sh"), + + -- launch rofi + ((modm, xK_semicolon), spawn ("rofi -show drun -show-icons")), + ((modm, xK_p), spawn ("keepmenu")), + ((modm, xK_i), spawn ("networkmanager_dmenu")), + + -- close focused window + ((modm, xK_q), kill), + -- close all windows on current workspace + ((modm .|. shiftMask, xK_c), killAll), + -- exit xmonad + ((modm .|. shiftMask, xK_q), spawn "killall xmonad-x86_64-linux"), + -- Lock with dm-tool + ((modm, xK_Escape), spawn "dm-tool switch-to-greeter"), + -- Lock with dm-tool and suspend + ((modm .|. shiftMask, xK_s), spawn "dm-tool switch-to-greeter & systemctl suspend"), + ((modm .|. shiftMask, xK_Escape), spawn "dm-tool switch-to-greeter & systemctl suspend"), + + -- Rotate through the available layout algorithms + ((modm, xK_space), sendMessage NextLayout), + -- Reset the layouts on the current workspace to default + ((modm .|. shiftMask, xK_space), setLayout $ XMonad.layoutHook conf), + + -- Resize viewed windows to the correct size + ((modm, xK_r), C.sequence_ [spawn "killall xmobar; autorandr -c; xmonad --restart;", refresh]), + + -- Move focus to window below + ((modm, xK_j), C.sequence_ [windowGo D True, switchLayer, warpToWindow 0.5 0.5]), + -- Move focus to window above + ((modm, xK_k), C.sequence_ [windowGo U True, switchLayer, warpToWindow 0.5 0.5]), + -- Move focus to window left + ((modm, xK_h), C.sequence_ [windowGo L True, switchLayer, warpToWindow 0.5 0.5]), + -- Move focus to window right + ((modm, xK_l), C.sequence_ [windowGo R True, switchLayer, warpToWindow 0.5 0.5]), + + -- Move focus to screen below + ((modm, xK_Down), C.sequence_ [screenGo D True, warpToCurrentScreen 0.5 0.5]), + -- Move focus to screen up + ((modm, xK_Up), C.sequence_ [screenGo U True, warpToCurrentScreen 0.5 0.5]), + -- Move focus to screen left + ((modm, xK_Left), C.sequence_ [screenGo L True, warpToCurrentScreen 0.5 0.5]), + -- Move focus to screen right + ((modm, xK_Right), C.sequence_ [screenGo R True, warpToCurrentScreen 0.5 0.5]), + + -- Swap with window below + ((modm .|. shiftMask, xK_j), C.sequence_ [windowSwap D True, windowGo U True, switchLayer]), + -- Swap with window above + ((modm .|. shiftMask, xK_k), C.sequence_ [windowSwap U True, windowGo D True, switchLayer]), + -- Swap with window left + ((modm .|. shiftMask, xK_h), C.sequence_ [windowSwap L True, windowGo R True, switchLayer]), + -- Swap with window right + ((modm .|. shiftMask, xK_l), C.sequence_ [windowSwap R True, windowGo L True, switchLayer]), + + -- Shrink the master area + ((modm .|. controlMask, xK_h), sendMessage Shrink), + -- Expand the master area + ((modm .|. controlMask, xK_l), sendMessage Expand), + + -- Swap the focused window and the master window + ((modm, xK_m), windows W.swapMaster), + + -- Toggle tiling/floating status of window + ((modm, xK_t), withFocused toggleFloat), + + -- Increment the number of windows in the master area + ((modm, xK_comma), sendMessage (IncMasterN 1)), + -- Deincrement the number of windows in the master area + ((modm, xK_period), sendMessage (IncMasterN (-1))), + + -- scratchpad keybindings + ((modm, xK_f), namedScratchpadAction myScratchPads "ranger"), + --((modm, xK_x), namedScratchpadAction myScratchPads "keepassxc"), + ((modm, xK_z), namedScratchpadAction myScratchPads "terminal"), + ((modm, xK_b), namedScratchpadAction myScratchPads "btm"), + ((modm, xK_d), namedScratchpadAction myScratchPads "discord"), + ((modm, xK_o), namedScratchpadAction myScratchPads "octave"), + ((modm, xK_e), namedScratchpadAction myScratchPads "geary"), + ((modm, xK_n), namedScratchpadAction myScratchPads "musikcube"), + ((modm, xK_c), namedScratchpadAction myScratchPads "cal"), + ((modm, xK_y), namedScratchpadAction myScratchPads "pavucontrol"), + ((modm, xK_slash), namedScratchpadAction myScratchPads "helpmenu") + + ] + + ++ + -- mod-[1..9], Switch to workspace N + -- mod-shift-[1..9], Move client to workspace N + + [ ((m .|. modm, k), windows $ f i) + | (i, k) <- zip (XMonad.workspaces conf) [xK_1 .. xK_9], + (f, m) <- [(W.greedyView, 0), (W.shift, shiftMask)] + ] + + where + -- toggle float/tiling status of current window + toggleFloat w = + windows + ( \s -> + if M.member w (W.floating s) + then W.sink w s + else (W.float w (W.RationalRect (1 / 8) (1 / 8) (3 / 4) (3 / 4)) s) + ) + -- warp cursor to (x, y) coordinate of current screen + warpToCurrentScreen x y = do + sid <- withWindowSet $ return . W.screen . W.current + warpToScreen sid x y + -- TODO goto and warp (coords x, y) to window in DIRECTION, or goto and warp (coords x, y) to screen in DIRECTION if no window is available + windowOrScreenGoAndWarp direction x y = + do windowGo direction True + +-- Mouse bindings: default actions bound to mouse events +myMouseBindings (XConfig {XMonad.modMask = modm}) = + M.fromList $ + -- -- mod-button1, Set the window to floating mode and move by dragging + [ ( (modm, button1), + ( \w -> + focus w + >> mouseMoveWindow w + >> windows W.shiftMaster + ) + ), + -- mod-button3, Set the window to floating mode and resize by dragging + ( (modm, button3), + ( \w -> + focus w + >> mouseResizeWindow w + >> windows W.shiftMaster + ) + ) + -- you may also bind events to the mouse scroll wheel (button4 and button5) + ] + +-- Layouts: + +spcPx = 5 + +mySpacing = spacingRaw False (Border spcPx spcPx spcPx spcPx) True (Border spcPx spcPx spcPx spcPx) True + +myLayout = fullscreenFocus $ draggingVisualizer $ avoidStruts $ layoutHintsToCenter $ (mySpacing $ (Full ||| mouseResizable ||| mouseResizableMirrored)) + where + -- default tiling algorithm partitions the screen into two panes + tiled = Tall 1 (5 / 100) (1 / 2) + + dwindled = Dwindle R CW 1.1 1.1 + + mouseResizable = + mouseResizableTile + { masterFrac = 0.51, + slaveFrac = 0.51, + draggerType = BordersDragger + } + + mouseResizableMirrored = + mouseResizableTile + { masterFrac = 0.51, + slaveFrac = 0.51, + draggerType = BordersDragger, + isMirrored = True + } + +-- Window rules: +myManageHook = + composeAll + [ title =? "Myuzi" --> (customFloating $ W.RationalRect 0.05 0.05 0.9 0.9), + title =? "octave-scratchpad" --> (customFloating $ W.RationalRect 0.1 0.1 0.8 0.8), + title =? "scratchpad" --> (customFloating $ W.RationalRect 0.1 0.1 0.8 0.8), + className =? "gtkcord4" --> (customFloating $ W.RationalRect 0.1 0.1 0.8 0.8), + title =? "ranger-scratchpad" --> (customFloating $ W.RationalRect 0.05 0.05 0.9 0.9), + title =? "btm-scratchpad" --> (customFloating $ W.RationalRect 0.1 0.1 0.8 0.8), + className =? "Geary" --> (customFloating $ W.RationalRect 0.05 0.05 0.9 0.9), + title =? "scratch_cfw" --> (customFloating $ W.RationalRect 0.58 0.04 0.42 0.7), + title =? "xmonad_helpmenu" --> (customFloating $ W.RationalRect 0.05 0.05 0.9 0.9), + className =? "Pavucontrol" --> (customFloating $ W.RationalRect 0.05 0.04 0.5 0.35), + className =? "Syncthing GTK" --> (customFloating $ W.RationalRect 0.53 0.50 0.46 0.45), + className =? "Proton Mail Bridge" --> (customFloating $ W.RationalRect 0.59 0.66 0.40 0.30), + className =? "Zenity" --> (customFloating $ W.RationalRect 0.45 0.4 0.1 0.2), + resource =? "desktop_window" --> doIgnore, + -- this gimp snippet is from Kathryn Anderson (https://xmonad.haskell.narkive.com/bV34Aiw3/layout-for-gimp-how-to) + (className =? "Gimp" <&&> fmap ("color-selector" `isSuffixOf`) role) --> doFloat, + (className =? "Gimp" <&&> fmap ("layer-new" `isSuffixOf`) role) --> doFloat, + (className =? "Gimp" <&&> fmap ("-dialog" `isSuffixOf`) role) --> doFloat, + (className =? "Gimp" <&&> fmap ("-tool" `isSuffixOf`) role) --> doFloat, + -- end snippet + resource =? "kdesktop" --> doIgnore, + manageDocks + ] + where role = stringProperty "WM_WINDOW_ROLE" + +-- Apply fullscreen manage and event hooks +myFullscreenManageHook = fullscreenManageHook +myFullscreenEventHook = fullscreenEventHook + +-- Server mode event hook +myEventHook = serverModeEventHook + +-- navigation 2d config required for visual window movement +myNavigation2DConfig = def {layoutNavigation = [("Tall", hybridOf sideNavigation $ hybridOf centerNavigation lineNavigation), ("Full", hybridOf sideNavigation centerNavigation)] + , floatNavigation = hybridOf lineNavigation centerNavigation + , screenNavigation = hybridOf lineNavigation centerNavigation} + +--myPP = def { ppCurrent = xmobarColor colorFocus "" } +myPP = xmobarPP { ppTitle = xmobarColor colorFocus "", + ppCurrent = xmobarStripTags ["NSP"] . xmobarColor colorFocus "", + ppVisible = xmobarStripTags ["NSP"] . xmobarColor colorSecondary "", + ppHidden = xmobarStripTags ["NSP"] . xmobarColor colorFg "", + ppHiddenNoWindows = xmobarStripTags ["NSP"] . xmobarColor color01 "", + ppOrder = \(ws : _) -> [ws], + ppSep = " " + } +mySB = statusBarProp "xmobar" (pure myPP) + +-- Startup hook +myStartupHook = do + spawnOnce ("~/.config/xmonad/startup.sh '" ++ colorBg ++ "' '" ++ colorFg ++ "' '" ++ colorFocus ++ "' '" ++ colorSecondary ++ "'") + +-- Now run xmonad with all the defaults we set up. +main = do + spawn ("xmobar -x 0") + spawn ("xmobar -x 1") + spawn ("xmobar -x 2") + xmonad . withSB mySB $ + withNavigation2DConfig myNavigation2DConfig $ + fullscreenSupportBorder $ + docks $ + EWMHD.ewmh + def + { -- simple stuff + terminal = myTerminal, + focusFollowsMouse = myFocusFollowsMouse, + clickJustFocuses = myClickJustFocuses, + borderWidth = myBorderWidth, + modMask = myModMask, + workspaces = myWorkspaces, + normalBorderColor = myNormalBorderColor, + focusedBorderColor = myFocusedBorderColor, + -- key bindings + keys = myKeys, + mouseBindings = myMouseBindings, + -- hooks, layouts + layoutHook = myLayout, + manageHook = myManageHook <+> myFullscreenManageHook <+> namedScratchpadManageHook myScratchPads, + handleEventHook = myEventHook <+> myFullscreenEventHook <+> fadeWindowsEventHook, + logHook = (refocusLastLogHook >> nsHideOnFocusLoss myScratchPads), + startupHook = myStartupHook + } diff --git a/user/wm/xmonad/xmonad.nix b/user/wm/xmonad/xmonad.nix new file mode 100644 index 0000000..ca2b71c --- /dev/null +++ b/user/wm/xmonad/xmonad.nix @@ -0,0 +1,113 @@ +{ config, pkgs, ... }: + +{ + + imports = [ ../picom/picom.nix + ../../lang/haskell/haskell.nix + ../../app/terminal/alacritty.nix + ../../app/terminal/kitty.nix + ( import ../../app/dmenu-scripts/networkmanager-dmenu.nix {dmenu_command = "rofi -show dmenu"; inherit pkgs;}) + ]; + + home.packages = with pkgs; [ + xmobar + networkmanagerapplet + dunst + pamixer + autorandr + alacritty + kitty + dmenu + rofi + keepmenu + networkmanager_dmenu + pavucontrol + feh + flameshot + alttab + xdotool + xclip + ddcutil + sct + libnotify + xorg.xkill + killall + bottom + brightnessctl + xorg.xcursorthemes + xorg.xev + xdg-utils + xdg-desktop-portal + xdg-desktop-portal-gtk + ]; + + home.file.".config/xmonad/xmonad.hs".source = ./xmonad.hs; + home.file.".config/xmonad/startup.sh".source = ./startup.sh; + + home.file.".config/xmonad/lib/Colors/Stylix.hs".source = config.lib.stylix.colors { + template = builtins.readFile ./lib/Colors/Stylix.hs.mustache; + extension = ".hs"; + }; + + home.file.".config/xmobar/xmobarrc".source = config.lib.stylix.colors { + template = builtins.readFile ./xmobarrc.mustache; + extension = ""; + }; + + + home.file.".config/xmobar/xmobar-st-check.sh" = { + source = config.lib.stylix.colors { + template = builtins.readFile ./xmobar-st-check.sh.mustache; + extension = ".sh"; + }; + executable = true; + }; + + programs.feh.enable = true; + programs.rofi.enable = true; + + services.autorandr.enable = true; + programs.autorandr.enable = true; + programs.autorandr.profiles = { + "default" = { + fingerprint = { + eDP1 = "00ffffffffffff0051b8601500000000171e0104a522137807ee91a3544c99260f5054000000010101010101010101010101010101011434805070381f402b20750458c210000018000000fd0e302d505043010a20202020202000000010000a202020202020202020202020000000fc00544c3135365644585030310a2001d67013790000030114630401847f074f002a001f0037041e00160004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000df90"; + }; + config = { + eDP-1 = { + enable = true; + primary = true; + position = "0x0"; + mode = "1920x1080"; + }; + }; + hooks.postswitch = "xmonad --restart; ~/.fehbg-stylix;"; + }; + "dock" = { + fingerprint = { + eDP1 = "00ffffffffffff0051b8601500000000171e0104a522137807ee91a3544c99260f5054000000010101010101010101010101010101011434805070381f402b20750458c210000018000000fd0e302d505043010a20202020202000000010000a202020202020202020202020000000fc00544c3135365644585030310a2001d67013790000030114630401847f074f002a001f0037041e00160004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000df90"; + HDMI-1 = "00ffffffffffff0010ac48f04c4a56470619010380342078ea1df5ae4f35b3250d5054a54b008180a940d100714f0101010101010101283c80a070b023403020360006442100001a000000ff00595947434e35323247564a4c0a000000fc0044454c4c2055323431330a2020000000fd00384c1e5111000a2020202020200163020325f15090050403020716011f1213142015110623091f0767030c001000382d83010000023a801871382d40582c450006442100001e011d8018711c1620582c250006442100009e011d007251d01e206e28550006442100001e8c0ad08a20e02d10103e960006442100001800000000000000000000000000000000000016"; + DP-1-1 = "00ffffffffffff0010ac2ca0533836310e12010380342078eab325ac5130b426105054a54b008180a940714f01010101010101010101283c80a070b023403020360007442100001a000000ff004a55343336383356313638530a000000fc0044454c4c20323430385746500a000000fd00384c1e5311000a202020202020012002031bf14890050403020716012309070765030c00100083010000023a801871382d40582c450007442100001e011d8018711c1620582c250007442100009e011d007251d01e206e28550007442100001e8c0ad08a20e02d10103e96000744210000180000000000000000000000000000000000000000000000000000000047"; + }; + config = { + eDP-1 = { + enable = true; + primary = true; + position = "1000x1200"; + mode = "1920x1080"; + }; + HDMI-1 = { + enable = true; + position = "1920x0"; + mode = "1920x1200"; + }; + DP-1-1 = { + enable = true; + position = "0x0"; + mode = "1920x1200"; + }; + }; + hooks.postswitch = "xmonad --restart; ~/.fehbg-stylix;"; + }; + }; +} diff --git a/user/wm/xmonad/xmonad.org b/user/wm/xmonad/xmonad.org new file mode 100644 index 0000000..c4cdfce --- /dev/null +++ b/user/wm/xmonad/xmonad.org @@ -0,0 +1,899 @@ +#+title: Xmonad Config +#+author: Emmet + +* DEPRECATED +# TODO remove XMonad config +I haven't used XMonad in probably a year, so this is completely unmaintained and I'll probably remove it at some point, since I have completely migrated to Wayland at this point! + +* XMonad Config +The main configuration file for XMonad is [[./xmonad.hs][~/.xmonad/xmonad.hs]]. +** Imports +First I import a bunch of libraries: +#+BEGIN_SRC haskell :tangle xmonad.hs +-- IMPORTS +import qualified Data.Map as M +import Control.Monad as C +import Data.List +import Data.Monoid +import Data.Maybe (fromJust) +import Graphics.X11.ExtraTypes.XF86 +import System.Exit +import System.IO +import XMonad +import XMonad.Actions.Navigation2D +import XMonad.Actions.SpawnOn +import XMonad.Actions.TiledWindowDragging +import XMonad.Actions.Warp +import XMonad.Actions.WindowNavigation +import XMonad.Actions.WithAll +import XMonad.Hooks.DynamicLog +import qualified XMonad.Hooks.EwmhDesktops as EWMHD +import XMonad.Hooks.FadeWindows +import XMonad.Hooks.ManageDocks +import XMonad.Hooks.RefocusLast +import XMonad.Hooks.ServerMode +import XMonad.Hooks.StatusBar +import XMonad.Hooks.StatusBar.PP +import XMonad.Layout.DraggingVisualizer +import XMonad.Layout.Dwindle +import XMonad.Layout.Fullscreen +import XMonad.Layout.Gaps +import XMonad.Layout.LayoutHints +import XMonad.Layout.LimitWindows +import XMonad.Layout.MouseResizableTile +import XMonad.Layout.Spacing +import XMonad.ManageHook +import qualified XMonad.StackSet as W +--import qualified DBus as D +--import qualified DBus.Client as D +import XMonad.Util.NamedScratchpad +import XMonad.Util.Run +import XMonad.Util.SpawnOnce + +#+END_SRC +** Theme Setup +*** Custom Color Library Template +#+BEGIN_SRC haskell :tangle ./lib/Colors/Stylix.hs.mustache +module Colors.Stylix where + +import XMonad + +colorBg = "#{{base00-hex}}" +colorFg = "#{{base05-hex}}" +color01 = "#{{base01-hex}}" -- usually black +color02 = "#{{base08-hex}}" -- usually red +color03 = "#{{base0B-hex}}" -- usually green +color04 = "#{{base0A-hex}}" -- usually yellow +color05 = "#{{base0E-hex}}" -- usually blue +color06 = "#{{base0F-hex}}" -- usually magenta +color07 = "#{{base0D-hex}}" -- usually cyan +color08 = "#{{base07-hex}}" -- usually white + +-- Select focus and secondary color +colorFocus = color02 +colorSecondary = color07 + +#+END_SRC +*** Import Custom Color Library +#+BEGIN_SRC haskell :tangle xmonad.hs +-- setup color variables +import Colors.Stylix + +#+END_SRC +** Settings +*** Border Color +#+BEGIN_SRC haskell :tangle xmonad.hs +-- Border colors for unfocused and focused windows, respectively. +myNormalBorderColor, myFocusedBorderColor :: String +myNormalBorderColor = colorBg +myFocusedBorderColor = colorFocus + +#+END_SRC +*** Default Apps +#+BEGIN_SRC haskell :tangle xmonad.hs +-- Default apps +myTerminal, myBrowser :: String +myTerminal = "$TERM" +myBrowser = "$BROWSER" +myEditor = "$EDITOR" +mySpawnEditor = "$SPAWNEDITOR" + +#+END_SRC +*** Mouse Focus +#+BEGIN_SRC haskell :tangle xmonad.hs +-- Whether focus follows the mouse pointer. +myFocusFollowsMouse :: Bool +myFocusFollowsMouse = False + +-- Whether clicking on a window to focus also passes the click to the window +myClickJustFocuses :: Bool +myClickJustFocuses = False + +#+END_SRC +*** Border Width +#+BEGIN_SRC haskell :tangle xmonad.hs +-- Width of the window border in pixels. +myBorderWidth :: Dimension +myBorderWidth = 3 + +#+END_SRC +*** Select Modkey +The default modkey is =mod1Mask= which is bound to left alt. =mod3Mask= can be used for right alt, but most people (including myself) simply use =mod4Mask= which is bound to the super key. +#+BEGIN_SRC haskell :tangle xmonad.hs +-- Modmask +myModMask :: KeyMask +myModMask = mod4Mask + +#+END_SRC +*** Workspaces +By default, workspaces are simply numeric strings ("1", "2", "3", etc..), but any strings can be used (i.e. "web", "irc", "code", etc..). I set workspace names with \x____ where the blank spaces represent a [[https://www.nerdfonts.com/][nerd font symbol code]]. This works nicely because I have a Nerd Font as fn=1 in my [[XMobar][xmobar]], which renders the nerd font glyphs in xmobar. +#+BEGIN_SRC haskell :tangle xmonad.hs +myWorkspaces :: [String] +myWorkspaces = + [ "\xf15c¹", -- document icon for writing + "\xeb01 ²", -- globe icon for browsing + "\xf121³", -- dev icon for programming + "\xf0cb9 ⁴", -- music file icon for composition + "\xf1fc⁵", -- paint icon for art + "\xf0bdc ⁶", -- video icon for recording/editing + "\xf0d6⁷", -- money icon for finances + "\xf19d⁸", -- cap icon for teaching + "\xf11b⁹" -- gamepad icon for gaming + ] + +myWorkspaceIndices = M.fromList $ zipWith (,) myWorkspaces [1..] -- (,) == \x y -> (x,y) + +clickable ws = ""++ws++"" + where i = fromJust $ M.lookup ws myWorkspaceIndices + +#+END_SRC +*** Scratchpads +Scratchpads are single applications that are normally not visible (in a workspace called "NSP"), but can be brought into the current workspace with a quick keybind. I find that this works really well for applications I use frequently for quick tasks, such as my terminal, password manager, email, and music player. +#+BEGIN_SRC haskell :tangle xmonad.hs +-- Scratchpads +myScratchPads :: [NamedScratchpad] +myScratchPads = + [ NS "terminal" spawnTerm findTerm manageTerm, + NS "ranger" spawnRanger findRanger manageRanger, + NS "octave" spawnOctave findOctave manageOctave, + NS "btm" spawnBtm findBtm manageBtm, + NS "geary" spawnGeary findGeary manageGeary, + NS "helpmenu" spawnHelp findHelp manageHelp, + NS "musikcube" spawnMusikcube findMusikcube manageMusikcube, + NS "cal" spawnCal findCal manageCal, + NS "pavucontrol" spawnPavucontrol findPavucontrol managePavucontrol, + NS "discord" spawnDiscord findDiscord manageDiscord + ] + where + spawnTerm = myTerminal ++ " --title scratchpad" + findTerm = title =? "scratchpad" + manageTerm = customFloating $ W.RationalRect l t w h + where + h = 0.9 + w = 0.9 + t = 0.95 - h + l = 0.95 - w + spawnRanger = "kitty --title ranger-scratchpad -e ranger" + findRanger = title =? "ranger-scratchpad" + manageRanger = customFloating $ W.RationalRect l t w h + where + h = 0.9 + w = 0.9 + t = 0.95 - h + l = 0.95 - w + spawnOctave = myTerminal ++ " --title octave-scratchpad -e octave" + findOctave = title =? "octave-scratchpad" + manageOctave = customFloating $ W.RationalRect l t w h + where + h = 0.5 + w = 0.4 + t = 0.75 - h + l = 0.70 - w + spawnBtm = myTerminal ++ " -o font.size=12 --title btm-scratchpad -e btm" + findBtm = title =? "btm-scratchpad" + manageBtm = customFloating $ W.RationalRect l t w h + where + h = 0.5 + w = 0.4 + t = 0.75 - h + l = 0.70 - w + spawnDiscord = "gtkcord4" + findDiscord = className =? "gtkcord4" + manageDiscord = customFloating $ W.RationalRect l t w h + where + h = 0.5 + w = 0.4 + t = 0.75 - h + l = 0.70 - w + spawnGeary = "geary" + findGeary = className =? "Geary" + manageGeary = customFloating $ W.RationalRect l t w h + where + h = 0.5 + w = 0.4 + t = 0.75 - h + l = 0.70 - w + spawnHelp = myTerminal ++ " --title xmonad_helpmenu -e w3m ~/.xmonad/helpmenu.txt" + findHelp = title =? "xmonad_helpmenu" + manageHelp = customFloating $ W.RationalRect l t w h + where + h = 0.9 + w = 0.9 + t = 0.95 - h + l = 0.95 - w + spawnMusikcube = myTerminal ++ " -o font.size=14 --title musikcube-scratchpad -e musikcube" + findMusikcube = title =? "musikcube-scratchpad" + manageMusikcube = customFloating $ W.RationalRect l t w h + where + h = 0.9 + w = 0.9 + t = 0.95 - h + l = 0.95 - w + spawnCal = "gnome-calendar" + findCal = className =? "gnome-calendar" + manageCal = customFloating $ W.RationalRect l t w h + where + h = 0.4 + w = 0.3 + t = 0.45 - h + l = 1 - w + spawnPavucontrol = "pavucontrol" + findPavucontrol = className =? "Pavucontrol" + managePavucontrol = customFloating $ W.RationalRect l t w h + where + h = 0.5 + w = 0.3 + t = 0.9 - h + l = 0.65 - w + +#+END_SRC +*** Keybindings +Keybinds can be set with an array of values like: =(keybind, action)=. The array is declared like so: +#+BEGIN_SRC haskell :tangle xmonad.hs +myKeys conf@(XConfig {XMonad.modMask = modm}) = + M.fromList $ + [ + -- insert keybinds with array values of ((keybind, action)) + +#+END_SRC +Then, keybindings are setup line by line as in the following sections: +**** Quick App Keybindings +The following binds the following: +| Keybinding | Action | +|---------------------+-----------------------------------------------| +| S-Return | New terminal | +| S-a | New emacs frame | +| S-s | New browser window | +| PrintScreen | Snip a screenshot | +| C-PrintScreen | Snip a screenshot (to clipboard) | +| Shift-PrintScreen | Screen capture current monitor | +| Shift-C-PrintScreen | Screen capture current monitor (to clipboard) | +#+BEGIN_SRC haskell :tangle xmonad.hs + -- launch a terminal + ((modm, xK_Return), spawn $ XMonad.terminal conf), + + -- launch emacsclient + ((modm, xK_a), spawn mySpawnEditor), + + -- launch browser + ((modm, xK_s), spawn myBrowser), + + -- take screenshots + ((0, xK_Print), spawn "flameshot gui"), -- snip screenshot and save + ((controlMask, xK_Print), spawn "flameshot gui --clipboard"), -- snip screenshot to clipboard + ((shiftMask, xK_Print), spawn "flameshot screen"), -- screen capture current monitor and save + ((controlMask .|. shiftMask, xK_Print), spawn "flameshot screen -c"), -- screen capture current monitor to clipboard + + -- launch game manager in gaming workspace + ((modm, xK_g), spawn "xdotool key Super+9 && gamehub"), + +#+END_SRC +**** Generic Keybindings +These setup standard bindings for brightness and audio control from the keyboard. +#+BEGIN_SRC haskell :tangle xmonad.hs + -- control brightness from kbd + ((0, xF86XK_MonBrightnessUp), spawn "brightnessctl set +15"), + ((0, xF86XK_MonBrightnessDown), spawn "brightnessctl set 15-"), + + -- control kbd brightness from kbd + ((0, xF86XK_KbdBrightnessUp), spawn "brightnessctl --device='asus::kbd_backlight' set +1 & xset r rate 350 100"), + ((0, xF86XK_KbdBrightnessDown), spawn "brightnessctl --device='asus::kbd_backlight' set 1- & xset r rate 350 100"), + ((shiftMask, xF86XK_MonBrightnessUp), spawn "brightnessctl --device='asus::kbd_backlight' set +1 & xset r rate 350 100"), + ((shiftMask, xF86XK_MonBrightnessDown), spawn "brightnessctl --device='asus::kbd_backlight' set 1- & xset r rate 350 100"), + + -- control volume from kbd + ((0, xF86XK_AudioLowerVolume), spawn "pamixer -d 10"), + ((0, xF86XK_AudioRaiseVolume), spawn "pamixer -i 10"), + ((0, xF86XK_AudioMute), spawn "pamixer -t"), + + -- control music from kbd + --((0, xF86XK_AudioPlay), spawn "cmus-remote -u"), + --((0, xF86XK_AudioStop), spawn "cmus-remote -s"), + --((0, xF86XK_AudioNext), spawn "cmus-remote -n && ~/.local/bin/cmus-current-song-notify.sh"), + --((0, xF86XK_AudioPrev), spawn "cmus-remote -r && ~/.local/bin/cmus-current-song-notify.sh"), + +#+END_SRC +**** Launcher Keybinds +I have =rofi= bound to =S-;= for quick app access. +#+BEGIN_SRC haskell :tangle xmonad.hs + -- launch rofi + ((modm, xK_semicolon), spawn ("rofi -show drun -show-icons")), + ((modm, xK_p), spawn ("keepmenu")), + ((modm, xK_i), spawn ("networkmanager_dmenu")), + +#+END_SRC +**** Window Management Keybinds +All of the following keybinds pertain to window management and layouts: +| Keybinding | Action | +|-------------------+------------------------------------------------------------------------------------------------| +| S-q | Kill window | +| S-Shift-c | Kill all windows on current workspace | +| S-Shift-q | Exit xmonad | +| S-Shift-Escape | Lock xmonad | +| S-Shift-s | Lock xmonad and suspend | +| S-Shift-Escape | Lock xmonad and suspend | +| S-Space | Switch to next layout | +| S-Shift-Space | Reset layout on current workspace | +| S-r | Resize windows to correct size | +| S-{←,↓,↑,→} | Switch to screen visually {left,down,up,right} (requires a [[Window Rules and Hooks][Navigation2Dconfig]]) | +| S-{h,j,k,l} | Switch to window visually {left,down,up,right} (requires a [[Window Rules and Hooks][Navigation2Dconfig]]) | +| S-Shift-{h,j,k,l} | Swap window visually {left,down,up,right} on current workspace (requires a [[Window Rules and Hooks][Navigation2Dconfig]]) | +| S-C-{h,l} | Resize master window area | +| S-m | Move current window into master window area | +| S-t | Toggle floating status of a window (this is a function defined [[Toggle Float Function Definition][here]]) | +| S-, | Increase number of windows in the master window area | +| S-. | Decrease number of windows in the master window area | +These keybindings are then set via: +#+BEGIN_SRC haskell :tangle xmonad.hs + -- close focused window + ((modm, xK_q), kill), + -- close all windows on current workspace + ((modm .|. shiftMask, xK_c), killAll), + -- exit xmonad + ((modm .|. shiftMask, xK_q), spawn "killall xmonad-x86_64-linux"), + -- Lock with dm-tool + ((modm, xK_Escape), spawn "dm-tool switch-to-greeter"), + -- Lock with dm-tool and suspend + ((modm .|. shiftMask, xK_s), spawn "dm-tool switch-to-greeter & systemctl suspend"), + ((modm .|. shiftMask, xK_Escape), spawn "dm-tool switch-to-greeter & systemctl suspend"), + + -- Rotate through the available layout algorithms + ((modm, xK_space), sendMessage NextLayout), + -- Reset the layouts on the current workspace to default + ((modm .|. shiftMask, xK_space), setLayout $ XMonad.layoutHook conf), + + -- Resize viewed windows to the correct size + ((modm, xK_r), C.sequence_ [spawn "killall xmobar; autorandr -c; xmonad --restart;", refresh]), + + -- Move focus to window below + ((modm, xK_j), C.sequence_ [windowGo D True, switchLayer, warpToWindow 0.5 0.5]), + -- Move focus to window above + ((modm, xK_k), C.sequence_ [windowGo U True, switchLayer, warpToWindow 0.5 0.5]), + -- Move focus to window left + ((modm, xK_h), C.sequence_ [windowGo L True, switchLayer, warpToWindow 0.5 0.5]), + -- Move focus to window right + ((modm, xK_l), C.sequence_ [windowGo R True, switchLayer, warpToWindow 0.5 0.5]), + + -- Move focus to screen below + ((modm, xK_Down), C.sequence_ [screenGo D True, warpToCurrentScreen 0.5 0.5]), + -- Move focus to screen up + ((modm, xK_Up), C.sequence_ [screenGo U True, warpToCurrentScreen 0.5 0.5]), + -- Move focus to screen left + ((modm, xK_Left), C.sequence_ [screenGo L True, warpToCurrentScreen 0.5 0.5]), + -- Move focus to screen right + ((modm, xK_Right), C.sequence_ [screenGo R True, warpToCurrentScreen 0.5 0.5]), + + -- Swap with window below + ((modm .|. shiftMask, xK_j), C.sequence_ [windowSwap D True, windowGo U True, switchLayer]), + -- Swap with window above + ((modm .|. shiftMask, xK_k), C.sequence_ [windowSwap U True, windowGo D True, switchLayer]), + -- Swap with window left + ((modm .|. shiftMask, xK_h), C.sequence_ [windowSwap L True, windowGo R True, switchLayer]), + -- Swap with window right + ((modm .|. shiftMask, xK_l), C.sequence_ [windowSwap R True, windowGo L True, switchLayer]), + + -- Shrink the master area + ((modm .|. controlMask, xK_h), sendMessage Shrink), + -- Expand the master area + ((modm .|. controlMask, xK_l), sendMessage Expand), + + -- Swap the focused window and the master window + ((modm, xK_m), windows W.swapMaster), + + -- Toggle tiling/floating status of window + ((modm, xK_t), withFocused toggleFloat), + + -- Increment the number of windows in the master area + ((modm, xK_comma), sendMessage (IncMasterN 1)), + -- Deincrement the number of windows in the master area + ((modm, xK_period), sendMessage (IncMasterN (-1))), + +#+END_SRC +**** Scratchpad Keybinds +I have each [[Scratchpads][scratchpad]] bound to a keybinding for quick access: +| Keybinding | Associated Scratchpad | +|------------+----------------------------| +| S-f | Ranger file manager | +| S-x | KeePassXC password manager | +| S-z | Terminal | +| S-b | Bottom control panel | +| S-d | Discord | +| S-o | Octave (calculator) | +| S-e | mu4e (email) | +| S-n | Music player | +| S-c | cfw (calendar) | +| S-y | Pavucontrol (audio mixer) | +| S-/ | Keybinding help menu | +These are then bound: +#+BEGIN_SRC haskell :tangle xmonad.hs + -- scratchpad keybindings + ((modm, xK_f), namedScratchpadAction myScratchPads "ranger"), + --((modm, xK_x), namedScratchpadAction myScratchPads "keepassxc"), + ((modm, xK_z), namedScratchpadAction myScratchPads "terminal"), + ((modm, xK_b), namedScratchpadAction myScratchPads "btm"), + ((modm, xK_d), namedScratchpadAction myScratchPads "discord"), + ((modm, xK_o), namedScratchpadAction myScratchPads "octave"), + ((modm, xK_e), namedScratchpadAction myScratchPads "geary"), + ((modm, xK_n), namedScratchpadAction myScratchPads "musikcube"), + ((modm, xK_c), namedScratchpadAction myScratchPads "cal"), + ((modm, xK_y), namedScratchpadAction myScratchPads "pavucontrol"), + ((modm, xK_slash), namedScratchpadAction myScratchPads "helpmenu") + +#+END_SRC +**** End of Standard Keybinds +To finish the section of standard keybinds, we simply close the array [[Keybindings][started above]]. +#+BEGIN_SRC haskell :tangle xmonad.hs + ] +#+END_SRC +**** Workspace Management Keybinds +Workspaces are generically managed via =mod-[1..9]= to shift to a workspace, and =mod-shift-[1..9]= to send a window to another workspace. To generate this effect, the following code is added to the keybindings definition: +#+BEGIN_SRC haskell :tangle xmonad.hs + ++ + -- mod-[1..9], Switch to workspace N + -- mod-shift-[1..9], Move client to workspace N + + [ ((m .|. modm, k), windows $ f i) + | (i, k) <- zip (XMonad.workspaces conf) [xK_1 .. xK_9], + (f, m) <- [(W.greedyView, 0), (W.shift, shiftMask)] + ] + +#+END_SRC +**** Custom Function Definitions +To have =toggleFloat= and =warpToCurrentScreen=, I must define them after setting up the keybinds like so: +#+BEGIN_SRC haskell :tangle xmonad.hs + where + -- toggle float/tiling status of current window + toggleFloat w = + windows + ( \s -> + if M.member w (W.floating s) + then W.sink w s + else (W.float w (W.RationalRect (1 / 8) (1 / 8) (3 / 4) (3 / 4)) s) + ) + -- warp cursor to (x, y) coordinate of current screen + warpToCurrentScreen x y = do + sid <- withWindowSet $ return . W.screen . W.current + warpToScreen sid x y + -- TODO goto and warp (coords x, y) to window in DIRECTION, or goto and warp (coords x, y) to screen in DIRECTION if no window is available + windowOrScreenGoAndWarp direction x y = + do windowGo direction True + +#+END_SRC +**** Mouse Bindings +The following code sets up some convenient mouse bindings: +| Mouse Binding | Action | +|---------------+----------------------------------------------| +| S-Left click | Make window floating and drag to move window | +| S-Right click | Make window floating and resize window | +#+BEGIN_SRC haskell :tangle xmonad.hs +-- Mouse bindings: default actions bound to mouse events +myMouseBindings (XConfig {XMonad.modMask = modm}) = + M.fromList $ + -- -- mod-button1, Set the window to floating mode and move by dragging + [ ( (modm, button1), + ( \w -> + focus w + >> mouseMoveWindow w + >> windows W.shiftMaster + ) + ), + -- mod-button3, Set the window to floating mode and resize by dragging + ( (modm, button3), + ( \w -> + focus w + >> mouseResizeWindow w + >> windows W.shiftMaster + ) + ) + -- you may also bind events to the mouse scroll wheel (button4 and button5) + ] + +#+END_SRC +*** Layouts +By default, I utilize three layouts: +- =mouseResizable= which is a master/stack layout I have set up to have dwindling sizes +- =mouseResizableMirrored=, same as above except mirrored +- =Full= where only one window takes up the entire space of the screen + +I embellish these layouts with a few modifiers: +- =fullscreenFocus= for fullscreen support (also requires a [[Window Rules][fullscreen manage hook]]) +- =draggingVisualizer= so that I can drag tiling windows about via my [[Mouse Bindings][mouse bindings]] +- =avoidStruts= since I use [[XMobar][xmobar]] +- =spacingRaw= to put a few pixels of space between windows since it looks nice + +This is all applied in the following code to set the =myLayout= variable, which gets used later in the [[Main][main function]]: +#+BEGIN_SRC haskell :tangle xmonad.hs +-- Layouts: + +spcPx = 5 + +mySpacing = spacingRaw False (Border spcPx spcPx spcPx spcPx) True (Border spcPx spcPx spcPx spcPx) True + +myLayout = fullscreenFocus $ draggingVisualizer $ avoidStruts $ layoutHintsToCenter $ (mySpacing $ (Full ||| mouseResizable ||| mouseResizableMirrored)) + where + -- default tiling algorithm partitions the screen into two panes + tiled = Tall 1 (5 / 100) (1 / 2) + + dwindled = Dwindle R CW 1.1 1.1 + + mouseResizable = + mouseResizableTile + { masterFrac = 0.51, + slaveFrac = 0.51, + draggerType = BordersDragger + } + + mouseResizableMirrored = + mouseResizableTile + { masterFrac = 0.51, + slaveFrac = 0.51, + draggerType = BordersDragger, + isMirrored = True + } + +#+END_SRC +*** Window Rules and Hooks +Window rules apply actions when a new window matching a specific query is apprehended by xmonad. I mainly use these to control my scratchpads (to make them all floating) and for some apps that don't behave nicely inside of a tiling window manager. + +The easiest way to do a query is by either =className= or =title= which can both be found using =xprop=. + +The list of window rules must be made into a manage hook, which gets used in the [[Main][main function]] when starting xmonad. +#+BEGIN_SRC haskell :tangle xmonad.hs +-- Window rules: +myManageHook = + composeAll + [ title =? "Myuzi" --> (customFloating $ W.RationalRect 0.05 0.05 0.9 0.9), + title =? "octave-scratchpad" --> (customFloating $ W.RationalRect 0.1 0.1 0.8 0.8), + title =? "scratchpad" --> (customFloating $ W.RationalRect 0.1 0.1 0.8 0.8), + className =? "gtkcord4" --> (customFloating $ W.RationalRect 0.1 0.1 0.8 0.8), + title =? "ranger-scratchpad" --> (customFloating $ W.RationalRect 0.05 0.05 0.9 0.9), + title =? "btm-scratchpad" --> (customFloating $ W.RationalRect 0.1 0.1 0.8 0.8), + className =? "Geary" --> (customFloating $ W.RationalRect 0.05 0.05 0.9 0.9), + title =? "scratch_cfw" --> (customFloating $ W.RationalRect 0.58 0.04 0.42 0.7), + title =? "xmonad_helpmenu" --> (customFloating $ W.RationalRect 0.05 0.05 0.9 0.9), + className =? "Pavucontrol" --> (customFloating $ W.RationalRect 0.05 0.04 0.5 0.35), + className =? "Syncthing GTK" --> (customFloating $ W.RationalRect 0.53 0.50 0.46 0.45), + className =? "Proton Mail Bridge" --> (customFloating $ W.RationalRect 0.59 0.66 0.40 0.30), + className =? "Zenity" --> (customFloating $ W.RationalRect 0.45 0.4 0.1 0.2), + resource =? "desktop_window" --> doIgnore, + -- this gimp snippet is from Kathryn Anderson (https://xmonad.haskell.narkive.com/bV34Aiw3/layout-for-gimp-how-to) + (className =? "Gimp" <&&> fmap ("color-selector" `isSuffixOf`) role) --> doFloat, + (className =? "Gimp" <&&> fmap ("layer-new" `isSuffixOf`) role) --> doFloat, + (className =? "Gimp" <&&> fmap ("-dialog" `isSuffixOf`) role) --> doFloat, + (className =? "Gimp" <&&> fmap ("-tool" `isSuffixOf`) role) --> doFloat, + -- end snippet + resource =? "kdesktop" --> doIgnore, + manageDocks + ] + where role = stringProperty "WM_WINDOW_ROLE" + +#+END_SRC + +I also must set my fullscreen manage hook and fullscreen event hook here to fully enable fullscreen support mentioned [[Layouts][earlier]]: +#+BEGIN_SRC haskell :tangle xmonad.hs +-- Apply fullscreen manage and event hooks +myFullscreenManageHook = fullscreenManageHook +myFullscreenEventHook = fullscreenEventHook + +#+END_SRC + +Next, I set up my event hook to put xmonad into server mode, which allows me to use [[https://github.com/xmonad/xmonad-contrib/blob/master/scripts/xmonadctl.hs][xmonadctl]] from [[https://github.com/xmonad/xmonad-contrib][xmonad-contrib]], which enables control of xmonad actions from the shell/scripts. +#+BEGIN_SRC haskell :tangle xmonad.hs +-- Server mode event hook +myEventHook = serverModeEventHook + +#+END_SRC + +Next I set up a =navigation2DConfig= for use with [[Window Management Keybinds][visual window movement]]: +#+BEGIN_SRC haskell :tangle xmonad.hs +-- navigation 2d config required for visual window movement +myNavigation2DConfig = def {layoutNavigation = [("Tall", hybridOf sideNavigation $ hybridOf centerNavigation lineNavigation), ("Full", hybridOf sideNavigation centerNavigation)] + , floatNavigation = hybridOf lineNavigation centerNavigation + , screenNavigation = hybridOf lineNavigation centerNavigation} + +#+END_SRC + +*** New Xmobar Setup +#+BEGIN_SRC haskell :tangle xmonad.hs +--myPP = def { ppCurrent = xmobarColor colorFocus "" } +myPP = xmobarPP { ppTitle = xmobarColor colorFocus "", + ppCurrent = xmobarStripTags ["NSP"] . xmobarColor colorFocus "", + ppVisible = xmobarStripTags ["NSP"] . xmobarColor colorSecondary "", + ppHidden = xmobarStripTags ["NSP"] . xmobarColor colorFg "", + ppHiddenNoWindows = xmobarStripTags ["NSP"] . xmobarColor color01 "", + ppOrder = \(ws : _) -> [ws], + ppSep = " " + } +mySB = statusBarProp "xmobar" (pure myPP) + +#+END_SRC +*** Startup Script +I have a startup script at =~/.xmonad/startup.sh= which starts various apps and sets up a few things. In my xmonad config, it is autostarted by setting a =startupHook=. +#+BEGIN_SRC haskell :tangle xmonad.hs +-- Startup hook +myStartupHook = do + spawnOnce ("~/.config/xmonad/startup.sh '" ++ colorBg ++ "' '" ++ colorFg ++ "' '" ++ colorFocus ++ "' '" ++ colorSecondary ++ "'") + +#+END_SRC + +First I start by retrieving the colors passed to the script from xmonad. +#+BEGIN_SRC sh :tangle startup.sh :tangle-mode (identity #o755) +colorBg=$1 +colorFg=$2 +colorFocus=$3 +colorSecondary=$4 + +#+END_SRC + +The autostart script kills all applications I am autostarting, which prevents multiple instances of background applications when I restart xmonad: +#+BEGIN_SRC sh :tangle startup.sh :tangle-mode (identity #o755) +# Startup shell script called by xmonad to start necessary programs +# +## Kill previous instances of applications (Prevents multiple instances of the following if XMonad is restarted durin the X session) +killall xmobar +killall nm-applet + +#+END_SRC + +Then, desktop applications are started in the background. +#+BEGIN_SRC sh :tangle startup.sh :tangle-mode (identity #o755) +# Launch necessary desktop applications +autorandr; +picom --animations --animation-window-mass 1 --animation-for-open-window zoom --animation-stiffness 200 --experimental-backends && # requires picom-pijulius +xset r rate 350 50 & +setxkbmap -option caps:escape & +~/.fehbg-stylix & +~/.config/xmobar/xmobar-st-check.sh & +alttab -w 1 -t 240x160 -i 64x64 -sc 1 -bg $colorBg -fg $colorFg -frame $colorSecondary -inact $colorFg & +##/usr/bin/trayer --edge top --align right --SetDockType true --SetPartialStrut true --expand true --widthtype request --transparent true --alpha 0 --height 28 --tint $trayertint --monitor "primary" & +nm-applet & +GOMAXPROCS=1 syncthing --no-browser & +protonmail-bridge --noninteractive & +emacs --daemon & +gnome-keyring-daemon --daemonize --login & +gnome-keyring-daemon --start --components=secrets & +#+END_SRC +** Main +Lastly, xmonad is started with all of the [[Settings][settings set up as variables]]. First xmobar is setup with =spawnPipe= so that it has access to the [[Workspaces][workspaces from xmonad]]. Then xmonad is executed with the settings. +#+BEGIN_SRC haskell :tangle xmonad.hs +-- Now run xmonad with all the defaults we set up. +main = do + spawn ("xmobar -x 0") + spawn ("xmobar -x 1") + spawn ("xmobar -x 2") + xmonad . withSB mySB $ + withNavigation2DConfig myNavigation2DConfig $ + fullscreenSupportBorder $ + docks $ + EWMHD.ewmh + def + { -- simple stuff + terminal = myTerminal, + focusFollowsMouse = myFocusFollowsMouse, + clickJustFocuses = myClickJustFocuses, + borderWidth = myBorderWidth, + modMask = myModMask, + workspaces = myWorkspaces, + normalBorderColor = myNormalBorderColor, + focusedBorderColor = myFocusedBorderColor, + -- key bindings + keys = myKeys, + mouseBindings = myMouseBindings, + -- hooks, layouts + layoutHook = myLayout, + manageHook = myManageHook <+> myFullscreenManageHook <+> namedScratchpadManageHook myScratchPads, + handleEventHook = myEventHook <+> myFullscreenEventHook <+> fadeWindowsEventHook, + logHook = (refocusLastLogHook >> nsHideOnFocusLoss myScratchPads), + startupHook = myStartupHook + } +#+END_SRC +* XMobar Config +I utilize xmobar as a status bar on my monitors. To manage my xmobar config, I start by creating a template file, and then style that using stylix. +** Xmobar Template +This is my base xmobarrc. This is a full xmobar config with placeholders for the colors (i.e. =colorFgNormal=, =colorBgNormal=, =color01Normal=, =color01Bright=, etc...). [[./startup.sh][startup.sh]] copies this into =xmobarrc= with my current base16 color scheme. This also depends on =Inconsolata= and =Symbols Nerd Font=. +#+BEGIN_SRC haskell :tangle xmobarrc.mustache +Config { font = "Inconsolata 16" + , additionalFonts = ["Symbols Nerd Font 14"] + , border = NoBorder + , bgColor = "#{{base00-hex}}" + , alpha = 200 + , fgColor = "#{{base05-hex}}" + , position = TopSize C 100 28 + , textOffset = -1 + , iconOffset = -1 + , lowerOnStart = True + , pickBroadest = False + , persistent = False + , hideOnStart = False + , iconRoot = "." + , allDesktops = True + , overrideRedirect = True + , commands = [ + Run XMonadLog + , Run Date " \xf073 %a %-m/%-d/%y %-I:%M:%S%P" "date" 10 + , Run BatteryP ["BAT0"] + ["-t", "", + "-L", "10", "-H", "80", "-p", "3", "--", + "-O","\xf313 \xf17e3 % ", + "-i","\xf313 \xf17e7 % ", + "-o","\xf313 \xf17e4 % ", + "-L", "-15", "-H", "-5", + "-l", "#{{base08-hex}}", "-m", "#{{base05-hex}}", "-h", "#{{base0B-hex}}"] 10 + , Run Brightness + [ "-t", "\xf0eb % ", "--", + "-D", "amdgpu_bl1" + ] 2 + , Run Volume "default" "Master" + [ "-t", "", "--" + , "--on", " \xf028 % " + , "--onc", "#{{base0D-hex}}" + , "--off", " \xf026 Mute " + , "--offc", "#{{base0F-hex}}" + ] 1 + , Run DynNetwork + [ "-t", "\xf0200 "] 1 + , Run Com "cat" + [ "/home/emmet/.st-status"] "syncthing" 10 + , Run Com "echo" + [ "\xea77 "] "syncthingsymbol" 0 + , Run Com "echo" + [ "\xeb5c "] "artsymbol" 0 + , Run Com "cat" + [ "/home/emmet/.currenttheme"] "currenttheme" 0 + , Run Memory [ "-t", "\xf035b % ( GB)", "-d", "1", "--", "--scale", "1024"] 20 + ] + , sepChar = "%" + , alignSep = "}{" + , template = " %battery% %bright%%default:Master% %memory% %artsymbol%%currenttheme%}%XMonadLog%{%syncthing% %dynnetwork% %date% " + } +} + +#+END_SRC + +#+BEGIN_SRC shell :tangle xmobar-st-check.sh.mustache +#!/bin/sh +while true + do + curl localhost:8384 -m 1 &> /dev/null || echo '❄ st off' > ~/.st-status; + curl localhost:8384 -m 1 &> /dev/null && echo '↺ st on' > ~/.st-status; + sleep 5; + done +#+END_SRC + +* Nix Integration +In order to have Nix put my xmonad/xmobar configuration in the proper places, I have [[./xmonad.nix][xmonad.nix]], which I source in the =imports= block of my [[../../home.nix][home.nix]]. +#+BEGIN_SRC nix :tangle xmonad.nix +{ config, pkgs, ... }: + +{ + + imports = [ ../picom/picom.nix + ../../lang/haskell/haskell.nix + ../../app/terminal/alacritty.nix + ../../app/terminal/kitty.nix + ( import ../../app/dmenu-scripts/networkmanager-dmenu.nix {dmenu_command = "rofi -show dmenu"; inherit pkgs;}) + ]; + + home.packages = with pkgs; [ + xmobar + networkmanagerapplet + dunst + pamixer + autorandr + alacritty + kitty + dmenu + rofi + keepmenu + networkmanager_dmenu + pavucontrol + feh + flameshot + alttab + xdotool + xclip + ddcutil + sct + libnotify + xorg.xkill + killall + bottom + brightnessctl + xorg.xcursorthemes + xorg.xev + xdg-utils + xdg-desktop-portal + xdg-desktop-portal-gtk + ]; + + home.file.".config/xmonad/xmonad.hs".source = ./xmonad.hs; + home.file.".config/xmonad/startup.sh".source = ./startup.sh; + + home.file.".config/xmonad/lib/Colors/Stylix.hs".source = config.lib.stylix.colors { + template = builtins.readFile ./lib/Colors/Stylix.hs.mustache; + extension = ".hs"; + }; + + home.file.".config/xmobar/xmobarrc".source = config.lib.stylix.colors { + template = builtins.readFile ./xmobarrc.mustache; + extension = ""; + }; + + + home.file.".config/xmobar/xmobar-st-check.sh" = { + source = config.lib.stylix.colors { + template = builtins.readFile ./xmobar-st-check.sh.mustache; + extension = ".sh"; + }; + executable = true; + }; + + programs.feh.enable = true; + programs.rofi.enable = true; + + services.autorandr.enable = true; + programs.autorandr.enable = true; + programs.autorandr.profiles = { + "default" = { + fingerprint = { + eDP1 = "00ffffffffffff0051b8601500000000171e0104a522137807ee91a3544c99260f5054000000010101010101010101010101010101011434805070381f402b20750458c210000018000000fd0e302d505043010a20202020202000000010000a202020202020202020202020000000fc00544c3135365644585030310a2001d67013790000030114630401847f074f002a001f0037041e00160004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000df90"; + }; + config = { + eDP-1 = { + enable = true; + primary = true; + position = "0x0"; + mode = "1920x1080"; + }; + }; + hooks.postswitch = "xmonad --restart; ~/.fehbg-stylix;"; + }; + "dock" = { + fingerprint = { + eDP1 = "00ffffffffffff0051b8601500000000171e0104a522137807ee91a3544c99260f5054000000010101010101010101010101010101011434805070381f402b20750458c210000018000000fd0e302d505043010a20202020202000000010000a202020202020202020202020000000fc00544c3135365644585030310a2001d67013790000030114630401847f074f002a001f0037041e00160004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000df90"; + HDMI-1 = "00ffffffffffff0010ac48f04c4a56470619010380342078ea1df5ae4f35b3250d5054a54b008180a940d100714f0101010101010101283c80a070b023403020360006442100001a000000ff00595947434e35323247564a4c0a000000fc0044454c4c2055323431330a2020000000fd00384c1e5111000a2020202020200163020325f15090050403020716011f1213142015110623091f0767030c001000382d83010000023a801871382d40582c450006442100001e011d8018711c1620582c250006442100009e011d007251d01e206e28550006442100001e8c0ad08a20e02d10103e960006442100001800000000000000000000000000000000000016"; + DP-1-1 = "00ffffffffffff0010ac2ca0533836310e12010380342078eab325ac5130b426105054a54b008180a940714f01010101010101010101283c80a070b023403020360007442100001a000000ff004a55343336383356313638530a000000fc0044454c4c20323430385746500a000000fd00384c1e5311000a202020202020012002031bf14890050403020716012309070765030c00100083010000023a801871382d40582c450007442100001e011d8018711c1620582c250007442100009e011d007251d01e206e28550007442100001e8c0ad08a20e02d10103e96000744210000180000000000000000000000000000000000000000000000000000000047"; + }; + config = { + eDP-1 = { + enable = true; + primary = true; + position = "1000x1200"; + mode = "1920x1080"; + }; + HDMI-1 = { + enable = true; + position = "1920x0"; + mode = "1920x1200"; + }; + DP-1-1 = { + enable = true; + position = "0x0"; + mode = "1920x1200"; + }; + }; + hooks.postswitch = "xmonad --restart; ~/.fehbg-stylix;"; + }; + }; +} +#+END_SRC