~ruther/guix-config

d74e115ab478b9147d0f6b22964daac863fb6fcc — Rutherther 7 months ago d496968
feat: dwl xwayland, waybar config
4 files changed, 590 insertions(+), 18 deletions(-)

A home/dwl/dwl-ipc-waybar.patch
M home/dwl/wm.scm
A home/waybar-config.jsonc
A home/waybar-style.css
A home/dwl/dwl-ipc-waybar.patch => home/dwl/dwl-ipc-waybar.patch +47 -0
@@ 0,0 1,47 @@
From 98b08880409cfd1277dc491b2f89de39a5107e50 Mon Sep 17 00:00:00 2001
From: Rutherther <rutherther@proton.me>
Date: Thu, 2 May 2024 22:39:00 +0200
Subject: [PATCH] feat: add DWL active_other for singletagset

---
 protocol/dwl-ipc-unstable-v2.xml | 1 +
 src/modules/dwl/tags.cpp         | 7 +++++++
 2 files changed, 8 insertions(+)

diff --git a/protocol/dwl-ipc-unstable-v2.xml b/protocol/dwl-ipc-unstable-v2.xml
index 74a212f07..be5bda9d5 100644
--- a/protocol/dwl-ipc-unstable-v2.xml
+++ b/protocol/dwl-ipc-unstable-v2.xml
@@ -75,6 +75,7 @@ I would probably just submit raphi's patchset but I don't think that would be po
       <entry name="none" value="0" summary="no state"/>
       <entry name="active" value="1" summary="tag is active"/>
       <entry name="urgent" value="2" summary="tag has at least one urgent client"/>
+      <entry name="active_other" value="4" summary="tag is active on another monitor"/>
     </enum>
 
     <request name="release" type="destructor">
diff --git a/src/modules/dwl/tags.cpp b/src/modules/dwl/tags.cpp
index 085b82246..462ae91b9 100644
--- a/src/modules/dwl/tags.cpp
+++ b/src/modules/dwl/tags.cpp
@@ -13,6 +13,7 @@
 #define TAG_INACTIVE 0
 #define TAG_ACTIVE 1
 #define TAG_URGENT 2
+#define TAG_ACTIVE_OTHER 4
 
 namespace waybar::modules::dwl {
 
@@ -198,6 +199,12 @@ void Tags::handle_view_tags(uint32_t tag, uint32_t state, uint32_t clients, uint
   } else {
     button.get_style_context()->remove_class("urgent");
   }
+
+  if (state & TAG_ACTIVE_OTHER) {
+    button.get_style_context()->add_class("focused-other");
+  } else {
+    button.get_style_context()->remove_class("focused-other");
+  }
 }
 
 } /* namespace waybar::modules::dwl */

M home/dwl/wm.scm => home/dwl/wm.scm +48 -18
@@ 1,26 1,56 @@
(define-module (home dwl wm)
  #:use-module (gnu packages wm)
  #:use-module (gnu packages xorg)

  #:use-module (ruther packages wayland)

  #:use-module (guix packages)
  #:use-module (guix gexp)
  #:use-module (guix utils)
  #:use-module (ruther packages wayland)
  #:use-module (guix download)
  #:use-module (guix git-download))

(define-public dwl-mine
(define-public waybar-mine
  (package
    (inherit dwl-0.7)
    (name "dwl-mine")
    (source
     (origin
       (method git-fetch)
       (uri (git-reference
        (url "https://github.com/Rutherther/dwl")
        (commit "a8e46f319f574876ce697a7097eb47a2080b1a87")))
       (sha256
        (base32 "1jkyqwnc6x48bcjcyn1ha69vwql18ib1w47jx6bxz7wg7bvidm01"))))
    (arguments (substitute-keyword-arguments (package-arguments dwl-0.7)
                 ((#:phases original-phases)
                  #~(modify-phases #$original-phases
                      (add-after 'unpack 'add-config
                        (lambda _
                          (copy-file #$(local-file "config.h") "config.h")))))))))
   (inherit waybar)
   (name "waybar-mine")
   (source
    (origin
     (inherit (package-source waybar))
     (sha256
      (base32 "0liiyz6212pmyhpsrb6773qf5b9b4kb76nggizygr9abfidbg5gw"))
     (patches
      (list (local-file "dwl-ipc-waybar.patch")))))))

(define-public (make-dwl-xwayland dwl)
  (package/inherit dwl
    (inputs
     (modify-inputs (package-inputs dwl)
       (append xcb-util-wm libx11 xorg-server-xwayland)))
    (arguments (substitute-keyword-arguments (package-arguments dwl)
                 ((#:make-flags original-flags)
                  #~(append '("XWAYLAND = -DXWAYLAND"
                              "XLIBS = xcb xcb-icccm")
                            #$original-flags))))))

(define-public dwl-mine
  (let ((base (make-dwl-xwayland dwl-0.7)))
    (package
      (inherit base)
      (name "dwl-mine")
      (source
       (origin
         (method git-fetch)
         (uri (git-reference
               (url "https://github.com/Rutherther/dwl")
               (commit "a8e46f319f574876ce697a7097eb47a2080b1a87")))
         (sha256
          (base32 "1jkyqwnc6x48bcjcyn1ha69vwql18ib1w47jx6bxz7wg7bvidm01"))))
      (arguments (substitute-keyword-arguments (package-arguments base)
                   ((#:phases original-phases)
                    #~(modify-phases #$original-phases
                        (add-after 'unpack 'add-config
                          (lambda _
                            (copy-file #$(local-file "config.h") "config.h"))))))))))

;; TODO wrapping with needed deps

A home/waybar-config.jsonc => home/waybar-config.jsonc +282 -0
@@ 0,0 1,282 @@
// -*- mode: jsonc -*-
[
{
    "ipc": true,
    "output": "!eDP-1",
    // "layer": "top", // Waybar at top layer
    // "position": "bottom", // Waybar position (top|bottom|left|right)
    "height": 20, // Waybar height (to be removed for auto height)
    // "width": 1280, // Waybar width
    "spacing": 4, // Gaps between modules (4px)
    // Choose the order of the modules
    "modules-left": [
        "dwl/tags",
        "dwl/window"
    ],
    "modules-center": [
    ],
    "modules-right": [
        "idle_inhibitor",
        "pulseaudio",
        "network",
        "power-profiles-daemon",
        "cpu",
        "memory",
        "temperature",
        "sway/language",
        "battery",
        "clock",
        "tray"
    ],
    "dwl/tags": {
        "num-tags": 9
    },
    "dwl/window": {
        "format": "{title}",
        "max-length": 50,
        "rewrite": {
	     "(.*) - Mozilla Firefox": "🌎 $1",
	     "(.*) — Mozilla Firefox": "🌎 $1"
        }
    },
    "sway/mode": {
        "format": "<span style=\"italic\">{}</span>"
    },
    "sway/scratchpad": {
        "format": "{icon} {count}",
        "show-empty": false,
        "format-icons": ["", ""],
        "tooltip": true,
        "tooltip-format": "{app}: {title}"
    },
    "idle_inhibitor": {
        "format": "{icon}",
        "format-icons": {
            "activated": "",
            "deactivated": ""
        }
    },
    "tray": {
        // "icon-size": 21,
        "spacing": 10
    },
    "clock": {
        "interval": 1,
        "tooltip-format": "<big>{:%Y %B}</big>\n<tt><small>{calendar}</small></tt>",
        "format-alt": "{:%Y-%m-%d}",
        "format": "{:%Y-%m-%d %H:%M:%S}"
    },
    "cpu": {
        "format": "{usage}% ",
        "tooltip": false
    },
    "memory": {
        "format": "{}% "
    },
    "temperature": {
        // "thermal-zone": 2,
        // "hwmon-path": "/sys/class/hwmon/hwmon2/temp1_input",
        "critical-threshold": 80,
        // "format-critical": "{temperatureC}°C {icon}",
        "format": "{temperatureC}°C {icon}",
        "format-icons": ["", "", ""]
    },
    "battery": {
        "states": {
            // "good": 95,
            "warning": 30,
            "critical": 15
        },
        "format": "{capacity}% {icon}",
        "format-full": "{capacity}% {icon}",
        "format-charging": "{capacity}% ",
        "format-plugged": "{capacity}% ",
        "format-alt": "{time} {icon}",
        // "format-good": "", // An empty format will hide the module
        // "format-full": "",
        "format-icons": ["", "", "", "", ""]
    },
    "power-profiles-daemon": {
      "format": "{icon}",
      "tooltip-format": "Power profile: {profile}\nDriver: {driver}",
      "tooltip": true,
      "format-icons": {
        "default": "",
        "performance": "",
        "balanced": "",
        "power-saver": ""
      }
    },
    "network": {
        // "interface": "wlp2*", // (Optional) To force the use of this interface
        "format-wifi": "{essid} ({signalStrength}%) ",
        "format-ethernet": "",
        "tooltip-format": "{ifname} via {gwaddr} ",
        "format-linked": "{ifname} (No IP) ",
        "format-disconnected": "Disconnected ⚠",
        "format-alt": "{ifname}: {ipaddr}/{cidr}"
    },
    "pulseaudio": {
        // "scroll-step": 1, // %, can be a float
        "format": "{volume}% {icon} {format_source}",
        "format-bluetooth": "{volume}% {icon} {format_source}",
        "format-bluetooth-muted": " {icon} {format_source}",
        "format-muted": " {format_source}",
        "format-source": "",
        "format-source-muted": "",
        "format-icons": {
            "headphone": "",
            "hands-free": "",
            "headset": "",
            "phone": "",
            "portable": "",
            "car": "",
            "default": ["", "", ""]
        },
        "on-click": "pavucontrol"
    },
},

{
    "ipc": true,
    "output": "eDP-1",
    // "layer": "top", // Waybar at top layer
    // "position": "bottom", // Waybar position (top|bottom|left|right)
    "height": 20, // Waybar height (to be removed for auto height)
    // "width": 1280, // Waybar width
    "spacing": 4, // Gaps between modules (4px)
    // Choose the order of the modules
    "modules-left": [
        "dwl/tags",
        "dwl/window"
    ],
    "modules-center": [
    ],
    "modules-right": [
        "idle_inhibitor",
        "pulseaudio",
        "network",
        "power-profiles-daemon",
        "cpu",
        "memory",
        "temperature",
        "backlight",
        "sway/language",
        "battery",
        "clock",
        "tray"
    ],
    "dwl/tags": {
        "num-tags": 9
    },
    "dwl/window": {
        "format": "{title}",
        "max-length": 50,
        "rewrite": {
	     "(.*) - Mozilla Firefox": "🌎 $1",
	     "(.*) — Mozilla Firefox": "🌎 $1"
        }
    },
    "sway/mode": {
        "format": "<span style=\"italic\">{}</span>"
    },
    "sway/scratchpad": {
        "format": "{icon} {count}",
        "show-empty": false,
        "format-icons": ["", ""],
        "tooltip": true,
        "tooltip-format": "{app}: {title}"
    },
    "idle_inhibitor": {
        "format": "{icon}",
        "format-icons": {
            "activated": "",
            "deactivated": ""
        }
    },
    "tray": {
        // "icon-size": 21,
        "spacing": 10
    },
    "clock": {
        "interval": 1,
        "tooltip-format": "<big>{:%Y %B}</big>\n<tt><small>{calendar}</small></tt>",
        "format-alt": "{:%Y-%m-%d}",
        "format": "{:%Y-%m-%d %H:%M:%S}"
    },
    "cpu": {
        "format": "{usage}% ",
        "tooltip": false
    },
    "memory": {
        "format": "{}% "
    },
    "temperature": {
        // "thermal-zone": 2,
        // "hwmon-path": "/sys/class/hwmon/hwmon2/temp1_input",
        "critical-threshold": 80,
        // "format-critical": "{temperatureC}°C {icon}",
        "format": "{temperatureC}°C {icon}",
        "format-icons": ["", "", ""]
    },
    "backlight": {
        // "device": "acpi_video1",
        "format": "{percent}% {icon}",
        "format-icons": ["", "", "", "", "", "", "", "", ""]
    },
    "battery": {
        "states": {
            // "good": 95,
            "warning": 30,
            "critical": 15
        },
        "format": "{capacity}% {icon}",
        "format-full": "{capacity}% {icon}",
        "format-charging": "{capacity}% ",
        "format-plugged": "{capacity}% ",
        "format-alt": "{time} {icon}",
        // "format-good": "", // An empty format will hide the module
        // "format-full": "",
        "format-icons": ["", "", "", "", ""]
    },
    "power-profiles-daemon": {
      "format": "{icon}",
      "tooltip-format": "Power profile: {profile}\nDriver: {driver}",
      "tooltip": true,
      "format-icons": {
        "default": "",
        "performance": "",
        "balanced": "",
        "power-saver": ""
      }
    },
    "network": {
        // "interface": "wlp2*", // (Optional) To force the use of this interface
        "format-wifi": "{essid} ({signalStrength}%) ",
        "format-ethernet": "",
        "tooltip-format": "{ifname} via {gwaddr} ",
        "format-linked": "{ifname} (No IP) ",
        "format-disconnected": "Disconnected ⚠",
        "format-alt": "{ifname}: {ipaddr}/{cidr}"
    },
    "pulseaudio": {
        // "scroll-step": 1, // %, can be a float
        "format": "{volume}% {icon} {format_source}",
        "format-bluetooth": "{volume}% {icon} {format_source}",
        "format-bluetooth-muted": " {icon} {format_source}",
        "format-muted": " {format_source}",
        "format-source": "",
        "format-source-muted": "",
        "format-icons": {
            "headphone": "",
            "hands-free": "",
            "headset": "",
            "phone": "",
            "portable": "",
            "car": "",
            "default": ["", "", ""]
        },
        "on-click": "pavucontrol"
    },
}
]
\ No newline at end of file

A home/waybar-style.css => home/waybar-style.css +213 -0
@@ 0,0 1,213 @@
* {
    /* `otf-font-awesome` is required to be installed for icons */
    font-family: FontAwesome, Ubuntu;
    font-size: 13px;
}

window#waybar {
    background-color: rgba(43, 48, 59, 0.5);
    color: #ffffff;
    transition-property: background-color;
    transition-duration: .5s;
}

window#waybar.hidden {
    opacity: 0.2;
}

/*
window#waybar.empty {
    background-color: transparent;
}
window#waybar.solo {
    background-color: #FFFFFF;
}
*/

window#waybar.termite {
    background-color: #3F3F3F;
}

window#waybar.chromium {
    background-color: #000000;
    border: none;
}

button {
    /* Use box-shadow instead of border so the text isn't offset */
    box-shadow: inset 0 -3px transparent;
    /* Avoid rounded borders under each button name */
    border: none;
    border-radius: 0;
}

/* https://github.com/Alexays/Waybar/wiki/FAQ#the-workspace-buttons-have-a-strange-hover-effect */
button:hover {
    background: inherit;
    box-shadow: inset 0 -3px #ffffff;
}

#workspaces button {
    padding: 0 5px;
    background-color: transparent;
    color: #ffffff;
}

#workspaces button:hover {
    background: rgba(0, 0, 0, 0.2);
}

#workspaces button.focused {
    background-color: #64727D;
    box-shadow: inset 0 -3px #ffffff;
}

#workspaces button.urgent {
    background-color: #eb4d4b;
}

#mode {
    background-color: #64727D;
    box-shadow: inset 0 -3px #ffffff;
}

#clock,
#battery,
#cpu,
#memory,
#disk,
#temperature,
#backlight,
#network,
#pulseaudio,
#wireplumber,
#custom-media,
#tray,
#mode,
#idle_inhibitor,
#scratchpad,
#power-profiles-daemon,
#mpd {
    padding: 0 10px;
    color: #ffffff;
    box-shadow: inset 0 -3px #4a4b4f;
}

#window,
#workspaces {
    margin: 0 4px;
}

/* If workspaces is the leftmost module, omit left margin */
.modules-left > widget:first-child > #workspaces {
    margin-left: 0;
}

/* If workspaces is the rightmost module, omit right margin */
.modules-right > widget:last-child > #workspaces {
    margin-right: 0;
}

#clock {
    box-shadow: inset 0 -3px #2980b9;
}

@keyframes blink {
    to {
        background-color: #ffffff;
        color: #000000;
    }
}

/* Using steps() instead of linear as a timing function to limit cpu usage */
#battery.critical:not(.charging) {
    background-color: #f53c3c;
    color: #ffffff;
    box-shadow: none;
    animation-name: blink;
    animation-duration: 0.5s;
    animation-timing-function: steps(12);
    animation-iteration-count: infinite;
    animation-direction: alternate;
}

#power-profiles-daemon {
    padding-right: 15px;
}

label:focus {
    background-color: #000000;
}

#cpu {
    /* box-shadow: inset 0 -3px #2ecc71; */
}

#network.disconnected {
    box-shadow: inset 0 -3px #f53c3c;
}

#temperature {
    /* box-shadow: inset 0 -3px #f0932b; */
}

#temperature.critical {
    background-color: #eb4d4b;
}

#tray {
    /* box-shadow: inset 0 -3px #2980b9; */
}

#tray > .passive {
    -gtk-icon-effect: dim;
}

#tray > .needs-attention {
    -gtk-icon-effect: highlight;
    background-color: #eb4d4b;
}

#tags {
    min-width: 0;
}

#tags button {
    min-width: 20px;
    padding: 3px;
    margin: 0;
    color: #e4e4e4;
}

#tags button.occupied {
    box-shadow: inset 0 -3px #4a4b4f;
}

#tags button.occupied:hover, #tags button:hover {
    box-shadow: inset 0 -3px #6c6d71;
}

#tags button.focused-other {
    box-shadow: inset 0 -3px #57a277;
}

#tags button.focused-other:hover {
    box-shadow: inset 0 -3px #79c499;
}

#tags button.focused {
    /* box-shadow: inset 0 -3px #1bd6e0; */
    box-shadow: inset 0 -3px #1be0d0;
}

#tags button.focused:hover {
    box-shadow: inset 0 -3px #60fcf5;
}

#tags button.urgent {
    box-shadow: inset 0 -3px #eb4d4b;
}

#tags button.urgent:hover {
    box-shadow: inset 0 -3px #f0932b;
}

Do not follow this link