Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package hyprpicker for openSUSE:Factory 
checked in at 2026-04-04 19:05:58
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/hyprpicker (Old)
 and      /work/SRC/openSUSE:Factory/.hyprpicker.new.21863 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "hyprpicker"

Sat Apr  4 19:05:58 2026 rev:4 rq:1344389 version:0.4.6

Changes:
--------
--- /work/SRC/openSUSE:Factory/hyprpicker/hyprpicker.changes    2025-08-05 
14:21:53.046736025 +0200
+++ /work/SRC/openSUSE:Factory/.hyprpicker.new.21863/hyprpicker.changes 
2026-04-04 19:07:26.205172632 +0200
@@ -1,0 +2,19 @@
+Wed Apr  1 18:12:47 UTC 2026 - Bjørn Lie <[email protected]>
+
+- Update to version 0.4.6:
+  + Exit with a specific code when the user has cancelled picking a
+    color
+  + Update README.md
+  + Made preview format match output format
+  + nix: use gcc15
+  + Notifications Support
+  + Fix flickering at top-left
+  + More flexible positioning and scaling
+  + Change css example in man page to use hsl
+  + feat: add custom format decoration
+  + Add null check for cursor shape device
+  + Feat: added keyboard movement
+- Add 089dd8a448c12e1066486892de096590cddb4195.patch: core: Include
+  <mutex> to make pickier compilers happy. Fixes (boo#1260616).
+
+-------------------------------------------------------------------

Old:
----
  hyprpicker-0.4.5.obscpio

New:
----
  089dd8a448c12e1066486892de096590cddb4195.patch
  hyprpicker-0.4.6.obscpio

----------(New B)----------
  New:  + Feat: added keyboard movement
- Add 089dd8a448c12e1066486892de096590cddb4195.patch: core: Include
  <mutex> to make pickier compilers happy. Fixes (boo#1260616).
----------(New E)----------

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ hyprpicker.spec ++++++
--- /var/tmp/diff_new_pack.2xndIn/_old  2026-04-04 19:07:26.769195757 +0200
+++ /var/tmp/diff_new_pack.2xndIn/_new  2026-04-04 19:07:26.773195921 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package hyprpicker
 #
-# Copyright (c) 2025 SUSE LLC and contributors
+# Copyright (c) 2026 SUSE LLC and contributors
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -17,12 +17,13 @@
 
 
 Name:           hyprpicker
-Version:        0.4.5
+Version:        0.4.6
 Release:        0
 Summary:        A wlroots-compatible Wayland color picker
 License:        BSD-3-Clause
 URL:            https://github.com/hyprwm/hyprpicker
 Source:         %{name}-%{version}.tar.gz
+Patch:          
https://github.com/hyprwm/hyprpicker/commit/089dd8a448c12e1066486892de096590cddb4195.patch
 BuildRequires:  cmake
 BuildRequires:  gcc-c++
 BuildRequires:  ninja
@@ -39,7 +40,7 @@
 supports a few different output forms, e.g. RGB, CMYK, HSL, HSV.
 
 %prep
-%autosetup
+%autosetup -p1
 
 %build
 %cmake

++++++ 089dd8a448c12e1066486892de096590cddb4195.patch ++++++
>From 089dd8a448c12e1066486892de096590cddb4195 Mon Sep 17 00:00:00 2001
From: Stephen Degler <[email protected]>
Date: Tue, 10 Feb 2026 14:17:44 -0500
Subject: [PATCH] core: Include <mutex> to make pickier compilers happy. (#148)

---
 src/hyprpicker.cpp | 1 +
 src/hyprpicker.hpp | 1 +
 2 files changed, 2 insertions(+)

diff --git a/src/hyprpicker.cpp b/src/hyprpicker.cpp
index 90f0228..d46959d 100644
--- a/src/hyprpicker.cpp
+++ b/src/hyprpicker.cpp
@@ -5,6 +5,7 @@
 #include <cstddef>
 #include <cstdio>
 #include <format>
+#include <mutex>
 #include <hyprutils/math/Vector2D.hpp>
 #include <wayland-client-protocol.h>
 #include <xkbcommon/xkbcommon-keysyms.h>
diff --git a/src/hyprpicker.hpp b/src/hyprpicker.hpp
index 77ab060..cad8f02 100644
--- a/src/hyprpicker.hpp
+++ b/src/hyprpicker.hpp
@@ -1,5 +1,6 @@
 #pragma once
 
+#include <mutex>
 #include "defines.hpp"
 #include "helpers/LayerSurface.hpp"
 #include "helpers/PoolBuffer.hpp"

++++++ hyprpicker-0.4.5.obscpio -> hyprpicker-0.4.6.obscpio ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hyprpicker-0.4.5/README.md 
new/hyprpicker-0.4.6/README.md
--- old/hyprpicker-0.4.5/README.md      2025-05-01 02:54:26.000000000 +0200
+++ new/hyprpicker-0.4.6/README.md      2026-02-10 16:09:41.000000000 +0100
@@ -12,13 +12,13 @@
 
 See `hyprpicker --help`.
 
-# Building
+# Installation
 
 ## Arch
 
-`yay -S hyprpicker-git`
+`sudo pacman -S hyprpicker`
 
-## Manual
+## Manual (Building)
 
 Install dependencies:
  - cmake
@@ -46,3 +46,4 @@
 # Caveats
 
 "Freezes" your displays when picking the color.
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hyprpicker-0.4.5/VERSION new/hyprpicker-0.4.6/VERSION
--- old/hyprpicker-0.4.5/VERSION        2025-05-01 02:54:26.000000000 +0200
+++ new/hyprpicker-0.4.6/VERSION        2026-02-10 16:09:41.000000000 +0100
@@ -1 +1 @@
-0.4.5
+0.4.6
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hyprpicker-0.4.5/doc/hyprpicker.1 
new/hyprpicker-0.4.6/doc/hyprpicker.1
--- old/hyprpicker-0.4.5/doc/hyprpicker.1       2025-05-01 02:54:26.000000000 
+0200
+++ new/hyprpicker-0.4.6/doc/hyprpicker.1       2026-02-10 16:09:41.000000000 
+0100
@@ -73,7 +73,7 @@
 .Fn hsl
 function:
 .Pp
-.Dl $ hyprpicker -f hsl | sed 's/^/rgb(/; s/$/)/; y/ /,/'
+.Dl $ hyprpicker -f hsl | sed 's/^/hsl(/; s/$/)/; y/ /,/'
 .Sh SEE ALSO
 .Xr hyprctl 1 ,
 .Xr hyprland 1 ,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hyprpicker-0.4.5/flake.lock 
new/hyprpicker-0.4.6/flake.lock
--- old/hyprpicker-0.4.5/flake.lock     2025-05-01 02:54:26.000000000 +0200
+++ new/hyprpicker-0.4.6/flake.lock     2026-02-10 16:09:41.000000000 +0100
@@ -10,11 +10,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1737632363,
-        "narHash": "sha256-X9I8POSlHxBVjD0fiX1O2j7U9Zi1+4rIkrsyHP0uHXY=",
+        "lastModified": 1749135356,
+        "narHash": "sha256-Q8mAKMDsFbCEuq7zoSlcTuxgbIBVhfIYpX0RjE32PS0=",
         "owner": "hyprwm",
         "repo": "hyprutils",
-        "rev": "006620eb29d54ea9086538891404c78563d1bae1",
+        "rev": "e36db00dfb3a3d3fdcc4069cb292ff60d2699ccb",
         "type": "github"
       },
       "original": {
@@ -33,11 +33,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1735493474,
-        "narHash": "sha256-fktzv4NaqKm94VAkAoVqO/nqQlw+X0/tJJNAeCSfzK4=",
+        "lastModified": 1749145760,
+        "narHash": "sha256-IHaGWpGrv7seFWdw/1A+wHtTsPlOGIKMrk1TUIYJEFI=",
         "owner": "hyprwm",
         "repo": "hyprwayland-scanner",
-        "rev": "de913476b59ee88685fdc018e77b8f6637a2ae0b",
+        "rev": "817918315ea016cc2d94004bfb3223b5fd9dfcc6",
         "type": "github"
       },
       "original": {
@@ -48,11 +48,11 @@
     },
     "nixpkgs": {
       "locked": {
-        "lastModified": 1737469691,
-        "narHash": "sha256-nmKOgAU48S41dTPIXAq0AHZSehWUn6ZPrUKijHAMmIk=",
+        "lastModified": 1748929857,
+        "narHash": "sha256-lcZQ8RhsmhsK8u7LIFsJhsLh/pzR9yZ8yqpTzyGdj+Q=",
         "owner": "NixOS",
         "repo": "nixpkgs",
-        "rev": "9e4d5190a9482a1fb9d18adf0bdb83c6e506eaab",
+        "rev": "c2a03962b8e24e669fb37b7df10e7c79531ff1a4",
         "type": "github"
       },
       "original": {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hyprpicker-0.4.5/flake.nix 
new/hyprpicker-0.4.6/flake.nix
--- old/hyprpicker-0.4.5/flake.nix      2025-05-01 02:54:26.000000000 +0200
+++ new/hyprpicker-0.4.6/flake.nix      2026-02-10 16:09:41.000000000 +0100
@@ -45,7 +45,7 @@
         inputs.hyprwayland-scanner.overlays.default
         (final: prev: {
           hyprpicker = prev.callPackage ./nix/default.nix {
-            stdenv = prev.gcc14Stdenv;
+            stdenv = prev.gcc15Stdenv;
             version = version + "+date=" + (mkDate (self.lastModifiedDate or 
"19700101")) + "_" + (self.shortRev or "dirty");
           };
           hyprpicker-debug = final.hyprpicker.override {debug = true;};
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hyprpicker-0.4.5/src/clipboard/Clipboard.cpp 
new/hyprpicker-0.4.6/src/clipboard/Clipboard.cpp
--- old/hyprpicker-0.4.5/src/clipboard/Clipboard.cpp    2025-05-01 
02:54:26.000000000 +0200
+++ new/hyprpicker-0.4.6/src/clipboard/Clipboard.cpp    2026-02-10 
16:09:41.000000000 +0100
@@ -1,20 +1,12 @@
 #include "Clipboard.hpp"
 
 #include "../includes.hpp"
+#include <hyprutils/os/Process.hpp>
+#include <string>
+#include <vector>
 
-void Clipboard::copy(const char* fmt, ...) {
-    char    buf[CLIPBOARDMESSAGESIZE] = "";
-    char*   outputStr;
+void NClipboard::copy(std::string data) {
+    Hyprutils::OS::CProcess copy("wl-copy", {data});
 
-    va_list args;
-    va_start(args, fmt);
-    vsnprintf(buf, sizeof buf, fmt, args);
-    va_end(args);
-
-    outputStr = strdup(buf);
-
-    if (fork() == 0)
-        execlp("wl-copy", "wl-copy", outputStr, NULL);
-
-    free(outputStr);
+    copy.runAsync();
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hyprpicker-0.4.5/src/clipboard/Clipboard.hpp 
new/hyprpicker-0.4.6/src/clipboard/Clipboard.hpp
--- old/hyprpicker-0.4.5/src/clipboard/Clipboard.hpp    2025-05-01 
02:54:26.000000000 +0200
+++ new/hyprpicker-0.4.6/src/clipboard/Clipboard.hpp    2026-02-10 
16:09:41.000000000 +0100
@@ -1,7 +1,7 @@
 #pragma once
 
-#define CLIPBOARDMESSAGESIZE 24
+#include <string>
 
-namespace Clipboard {
-    void copy(const char* fmt, ...);
-};
\ No newline at end of file
+namespace NClipboard {
+    void copy(std::string data);
+};
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hyprpicker-0.4.5/src/defines.hpp 
new/hyprpicker-0.4.6/src/defines.hpp
--- old/hyprpicker-0.4.5/src/defines.hpp        2025-05-01 02:54:26.000000000 
+0200
+++ new/hyprpicker-0.4.6/src/defines.hpp        2026-02-10 16:09:41.000000000 
+0100
@@ -5,6 +5,7 @@
 #include "helpers/Monitor.hpp"
 #include "helpers/Color.hpp"
 #include "clipboard/Clipboard.hpp"
+#include "notify/Notify.hpp"
 
 // git stuff
 #ifndef GIT_COMMIT_HASH
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hyprpicker-0.4.5/src/helpers/Color.cpp 
new/hyprpicker-0.4.6/src/helpers/Color.cpp
--- old/hyprpicker-0.4.5/src/helpers/Color.cpp  1970-01-01 01:00:00.000000000 
+0100
+++ new/hyprpicker-0.4.6/src/helpers/Color.cpp  2026-02-10 16:09:41.000000000 
+0100
@@ -0,0 +1,80 @@
+#include "Color.hpp"
+#include <algorithm>
+#include "../hyprpicker.hpp"
+
+static float fmax3(float a, float b, float c) {
+    return (a > b && a > c) ? a : (b > c) ? b : c;
+}
+
+static float fmin3(float a, float b, float c) {
+    return (a < b && a < c) ? a : (b < c) ? b : c;
+}
+
+static bool floatEq(float a, float b) {
+    return std::nextafter(a, std::numeric_limits<double>::lowest()) <= b && 
std::nextafter(a, std::numeric_limits<double>::max()) >= b;
+}
+
+void CColor::getCMYK(float& c, float& m, float& y, float& k) const {
+    // http://www.codeproject.com/KB/applications/xcmyk.aspx
+
+    float rf = 1 - (r / 255.0f), gf = 1 - (g / 255.0f), bf = 1 - (b / 255.0f);
+    k       = fmin3(rf, gf, bf);
+    float K = (k == 1) ? 1 : 1 - k;
+    c       = (rf - k) / K;
+    m       = (gf - k) / K;
+    y       = (bf - k) / K;
+
+    c = std::round(c * 100);
+    m = std::round(m * 100);
+    y = std::round(y * 100);
+    k = std::round(k * 100);
+}
+void CColor::getHSV(float& h, float& s, float& v) const {
+    // https://en.wikipedia.org/wiki/HSL_and_HSV#From_RGB
+
+    float rf = r / 255.0f, gf = g / 255.0f, bf = b / 255.0f;
+    float max = fmax3(rf, gf, bf), min = fmin3(rf, gf, bf);
+    float c = max - min;
+
+    v = max;
+    if (c == 0)
+        h = 0;
+    else if (v == rf)
+        h = 60 * (0 + (gf - bf) / c);
+    else if (v == gf)
+        h = 60 * (2 + (bf - rf) / c);
+    else /* v == bf */
+        h = 60 * (4 + (rf - gf) / c);
+
+    v = max;
+    s = floatEq(v, 0.0f) ? 0 : c / v;
+
+    h = std::round(h < 0 ? h + 360 : h);
+    v = std::round(v * 100);
+    s = std::round(s * 100);
+}
+void CColor::getHSL(float& h, float& s, float& l) const {
+    // https://en.wikipedia.org/wiki/HSL_and_HSV#From_RGB
+
+    float rf = r / 255.0f, gf = g / 255.0f, bf = b / 255.0f, v;
+    float max = fmax3(rf, gf, bf), min = fmin3(rf, gf, bf);
+    float c = max - min;
+
+    v = max;
+    if (c == 0)
+        h = 0;
+    else if (v == rf)
+        h = 60 * (0 + (gf - bf) / c);
+    else if (v == gf)
+        h = 60 * (2 + (bf - rf) / c);
+    else /* v == bf */
+        h = 60 * (4 + (rf - gf) / c);
+
+    v = max;
+    s = floatEq(v, 0.0f) ? 0 : c / v;
+    l = (max + min) / 2;
+    s = (floatEq(l, 0.0f) || floatEq(l, 1.0f)) ? 0 : (v - l) / std::min(l, 1 - 
l);
+    h = std::round(h < 0 ? h + 360 : h);
+    s = std::round(s * 100);
+    l = std::round(l * 100);
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hyprpicker-0.4.5/src/helpers/Color.hpp 
new/hyprpicker-0.4.6/src/helpers/Color.hpp
--- old/hyprpicker-0.4.5/src/helpers/Color.hpp  2025-05-01 02:54:26.000000000 
+0200
+++ new/hyprpicker-0.4.6/src/helpers/Color.hpp  2026-02-10 16:09:41.000000000 
+0100
@@ -5,4 +5,7 @@
 class CColor {
   public:
     uint8_t r = 0, g = 0, b = 0, a = 0;
-};
\ No newline at end of file
+    void    getCMYK(float& c, float& m, float& y, float& k) const;
+    void    getHSV(float& h, float& s, float& v) const;
+    void    getHSL(float& h, float& s, float& l) const;
+};
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hyprpicker-0.4.5/src/helpers/Monitor.cpp 
new/hyprpicker-0.4.6/src/helpers/Monitor.cpp
--- old/hyprpicker-0.4.5/src/helpers/Monitor.cpp        2025-05-01 
02:54:26.000000000 +0200
+++ new/hyprpicker-0.4.6/src/helpers/Monitor.cpp        2026-02-10 
16:09:41.000000000 +0100
@@ -118,4 +118,4 @@
         Debug::log(CRIT, "Failed to get a Screencopy!");
         g_pHyprpicker->finish(1);
     });
-}
\ No newline at end of file
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hyprpicker-0.4.5/src/helpers/Monitor.hpp 
new/hyprpicker-0.4.6/src/helpers/Monitor.hpp
--- old/hyprpicker-0.4.5/src/helpers/Monitor.hpp        2025-05-01 
02:54:26.000000000 +0200
+++ new/hyprpicker-0.4.6/src/helpers/Monitor.hpp        2026-02-10 
16:09:41.000000000 +0100
@@ -14,11 +14,11 @@
     SP<CCWlOutput>              output       = nullptr;
     uint32_t                    wayland_name = 0;
     Vector2D                    size;
-    int                         scale;
+    int32_t                     scale;
     wl_output_transform         transform = WL_OUTPUT_TRANSFORM_NORMAL;
 
     bool                        ready = false;
 
     CLayerSurface*              pLS      = nullptr;
     SP<CCZwlrScreencopyFrameV1> pSCFrame = nullptr;
-};
\ No newline at end of file
+};
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hyprpicker-0.4.5/src/hyprpicker.cpp 
new/hyprpicker-0.4.6/src/hyprpicker.cpp
--- old/hyprpicker-0.4.5/src/hyprpicker.cpp     2025-05-01 02:54:26.000000000 
+0200
+++ new/hyprpicker-0.4.6/src/hyprpicker.cpp     2026-02-10 16:09:41.000000000 
+0100
@@ -1,7 +1,16 @@
 #include "hyprpicker.hpp"
+#include "src/debug/Log.hpp"
+#include "src/notify/Notify.hpp"
 #include <csignal>
+#include <cstddef>
+#include <cstdio>
+#include <format>
+#include <hyprutils/math/Vector2D.hpp>
+#include <wayland-client-protocol.h>
+#include <xkbcommon/xkbcommon-keysyms.h>
+#include <xkbcommon/xkbcommon.h>
 
-void sigHandler(int sig) {
+static void sigHandler(int sig) {
     g_pHyprpicker->m_vLayerSurfaces.clear();
     exit(0);
 }
@@ -9,7 +18,7 @@
 void CHyprpicker::init() {
     m_pXKBContext = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
     if (!m_pXKBContext)
-        Debug::log(ERR, "Failed to create xkb context");
+        Debug::log(ERR, "Failed to create xkb context, keyboard movement not 
supported");
 
     m_pWLDisplay = wl_display_connect(nullptr);
 
@@ -145,6 +154,116 @@
     exit(code);
 }
 
+void CHyprpicker::outputColor() {
+
+    // relative brightness of a color
+    // https://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef
+    const auto FLUMI = [](const float& c) -> float { return c <= 0.03928 ? c / 
12.92 : powf((c + 0.055) / 1.055, 2.4); };
+
+    // get the px and print it
+    const auto MOUSECOORDSABS = m_vLastCoords.floor() / 
m_pLastSurface->m_pMonitor->size;
+    const auto CLICKPOS       = MOUSECOORDSABS * 
m_pLastSurface->screenBuffer->pixelSize;
+
+    const auto COL = getColorFromPixel(m_pLastSurface, CLICKPOS);
+
+    // threshold: (lumi_white + 0.05) / (x + 0.05) == (x + 0.05) / (lumi_black 
+ 0.05)
+    // https://www.w3.org/TR/2008/REC-WCAG20-20081211/#contrast-ratiodef
+    const uint8_t FG = 0.2126 * FLUMI(COL.r / 255.0f) + 0.7152 * FLUMI(COL.g / 
255.0f) + 0.0722 * FLUMI(COL.b / 255.0f) > 0.17913 ? 0 : 255;
+
+    std::string   hexColor = std::format("#{0:02x}{1:02x}{2:02x}", COL.r, 
COL.g, COL.b);
+
+    switch (m_bSelectedOutputMode) {
+        case OUTPUT_CMYK: {
+            float c, m, y, k;
+            COL.getCMYK(c, m, y, k);
+
+            std::string formattedColor = std::vformat(m_sOutputFormat, 
std::make_format_args(c, m, y, k));
+
+            if (m_bFancyOutput)
+                Debug::log(NONE, "\033[38;2;%i;%i;%i;48;2;%i;%i;%im%s\033[0m", 
FG, FG, FG, COL.r, COL.g, COL.b, formattedColor.c_str());
+            else
+                Debug::log(NONE, formattedColor.c_str());
+
+            if (m_bAutoCopy)
+                NClipboard::copy(formattedColor);
+
+            if (m_bNotify)
+                NNotify::send(hexColor, formattedColor);
+
+            finish();
+            break;
+        }
+        case OUTPUT_HEX: {
+            std::string rHex, gHex, bHex;
+            if (m_bUseLowerCase) {
+                rHex = std::format("{:02x}", COL.r);
+                gHex = std::format("{:02x}", COL.g);
+                bHex = std::format("{:02x}", COL.b);
+            } else {
+                rHex = std::format("{:02X}", COL.r);
+                gHex = std::format("{:02X}", COL.g);
+                bHex = std::format("{:02X}", COL.b);
+            }
+            std::string formattedColor = std::vformat(m_sOutputFormat, 
std::make_format_args(rHex, gHex, bHex));
+            if (m_bFancyOutput)
+                Debug::log(NONE, "\033[38;2;%i;%i;%i;48;2;%i;%i;%im%s\033[0m", 
FG, FG, FG, COL.r, COL.g, COL.b, formattedColor.c_str());
+            else
+                Debug::log(NONE, formattedColor.c_str());
+
+            if (m_bAutoCopy)
+                NClipboard::copy(hexColor);
+
+            if (m_bNotify)
+                NNotify::send(hexColor, hexColor);
+
+            finish();
+            break;
+        }
+        case OUTPUT_RGB: {
+            std::string formattedColor = std::vformat(m_sOutputFormat, 
std::make_format_args(COL.r, COL.g, COL.b));
+
+            if (m_bFancyOutput)
+                Debug::log(NONE, "\033[38;2;%i;%i;%i;48;2;%i;%i;%im%s\033[0m", 
FG, FG, FG, COL.r, COL.g, COL.b, formattedColor.c_str());
+            else
+                Debug::log(NONE, formattedColor.c_str());
+
+            if (m_bAutoCopy)
+                NClipboard::copy(formattedColor);
+
+            if (m_bNotify)
+                NNotify::send(hexColor, formattedColor);
+
+            finish();
+            break;
+        }
+        case OUTPUT_HSL:
+        case OUTPUT_HSV: {
+            float h, s, l_or_v;
+            if (m_bSelectedOutputMode == OUTPUT_HSV)
+                COL.getHSV(h, s, l_or_v);
+            else
+                COL.getHSL(h, s, l_or_v);
+
+            std::string formattedColor = std::vformat(m_sOutputFormat, 
std::make_format_args(h, s, l_or_v));
+            if (m_bFancyOutput)
+                Debug::log(NONE, "\033[38;2;%i;%i;%i;48;2;%i;%i;%im%s\033[0m", 
FG, FG, FG, COL.r, COL.g, COL.b, formattedColor.c_str());
+            else
+                Debug::log(NONE, formattedColor.c_str());
+
+            if (m_bAutoCopy)
+                NClipboard::copy(formattedColor);
+
+            if (m_bNotify)
+                NNotify::send(hexColor, formattedColor);
+
+            finish();
+            break;
+        }
+    }
+
+    finish();
+}
+
 void CHyprpicker::recheckACK() {
     for (auto& ls : m_vLayerSurfaces) {
         if ((ls->wantsACK || ls->wantsReload) && ls->screenBuffer) {
@@ -242,13 +361,13 @@
 
             for (int y = 0; y < pBuffer->pixelSize.y; ++y) {
                 for (int x = 0; x < pBuffer->pixelSize.x; ++x) {
-                    struct pixel {
+                    struct SPixel {
                         // little-endian ARGB
                         unsigned char blue;
                         unsigned char green;
                         unsigned char red;
                         unsigned char alpha;
-                    }* px = (struct pixel*)(data + (y * 
(int)pBuffer->pixelSize.x * 4) + (x * 4));
+                    }* px = (struct SPixel*)(data + (static_cast<ptrdiff_t>(y 
* (int)pBuffer->pixelSize.x * 4)) + (static_cast<ptrdiff_t>(x * 4)));
 
                     std::swap(px->red, px->blue);
                 }
@@ -262,7 +381,7 @@
 
             for (int y = 0; y < pBuffer->pixelSize.y; ++y) {
                 for (int x = 0; x < pBuffer->pixelSize.x; ++x) {
-                    uint32_t* px = (uint32_t*)(data + (y * 
(int)pBuffer->pixelSize.x * 4) + (x * 4));
+                    uint32_t* px = (uint32_t*)(data + 
(static_cast<ptrdiff_t>(y * (int)pBuffer->pixelSize.x * 4)) + 
(static_cast<ptrdiff_t>(x * 4)));
 
                     // conv to 8 bit
                     uint8_t R = (uint8_t)std::round((255.0 * (((*px) & 
0b00000000000000000000001111111111) >> 0) / 1023.0));
@@ -292,19 +411,19 @@
         case WL_SHM_FORMAT_BGR888: {
             for (int y = 0; y < pBuffer->pixelSize.y; ++y) {
                 for (int x = 0; x < pBuffer->pixelSize.x; ++x) {
-                    struct pixel3 {
+                    struct SPixel3 {
                         // little-endian RGB
                         unsigned char blue;
                         unsigned char green;
                         unsigned char red;
-                    }* srcPx = (struct pixel3*)(oldBuffer + (y * 
pBuffer->stride) + (x * 3));
-                    struct pixel4 {
+                    }* srcPx = (struct SPixel3*)(oldBuffer + 
(static_cast<size_t>(y * pBuffer->stride)) + (static_cast<ptrdiff_t>(x * 3)));
+                    struct SPixel4 {
                         // little-endian ARGB
                         unsigned char blue;
                         unsigned char green;
                         unsigned char red;
                         unsigned char alpha;
-                    }* dstPx = (struct pixel4*)(newBuffer + (y * 
newBufferStride) + (x * 4));
+                    }* dstPx = (struct SPixel4*)(newBuffer + 
(static_cast<ptrdiff_t>(y * newBufferStride)) + (static_cast<ptrdiff_t>(x * 
4)));
                     *dstPx   = {.blue = srcPx->red, .green = srcPx->green, 
.red = srcPx->blue, .alpha = 0xFF};
                 }
             }
@@ -312,19 +431,19 @@
         case WL_SHM_FORMAT_RGB888: {
             for (int y = 0; y < pBuffer->pixelSize.y; ++y) {
                 for (int x = 0; x < pBuffer->pixelSize.x; ++x) {
-                    struct pixel3 {
+                    struct SPixel3 {
                         // big-endian RGB
                         unsigned char red;
                         unsigned char green;
                         unsigned char blue;
-                    }* srcPx = (struct pixel3*)(oldBuffer + (y * 
pBuffer->stride) + (x * 3));
-                    struct pixel4 {
+                    }* srcPx = (struct SPixel3*)(oldBuffer + (y * 
pBuffer->stride) + (x * 3));
+                    struct SPixel4 {
                         // big-endian ARGB
                         unsigned char alpha;
                         unsigned char red;
                         unsigned char green;
                         unsigned char blue;
-                    }* dstPx = (struct pixel4*)(newBuffer + (y * 
newBufferStride) + (x * 4));
+                    }* dstPx = (struct SPixel4*)(newBuffer + (y * 
newBufferStride) + (x * 4));
                     *dstPx   = {.alpha = 0xFF, .red = srcPx->red, .green = 
srcPx->green, .blue = srcPx->blue};
                 }
             }
@@ -341,7 +460,8 @@
     const auto PBUFFER = getBufferForLS(pSurface);
 
     if (!PBUFFER || !pSurface->screenBuffer) {
-        Debug::log(ERR, PBUFFER ? "renderSurface: pSurface->screenBuffer null" 
: "renderSurface: PBUFFER null");
+        // Spammy log, doesn't matter.
+        // Debug::log(ERR, PBUFFER ? "renderSurface: pSurface->screenBuffer 
null" : "renderSurface: PBUFFER null");
         return;
     }
 
@@ -359,7 +479,7 @@
     cairo_rectangle(PCAIRO, 0, 0, PBUFFER->pixelSize.x, PBUFFER->pixelSize.y);
     cairo_fill(PCAIRO);
 
-    if (pSurface == m_pLastSurface && !forceInactive) {
+    if (pSurface == m_pLastSurface && !forceInactive && m_bCoordsInitialized) {
         const auto SCALEBUFS      = pSurface->screenBuffer->pixelSize / 
PBUFFER->pixelSize;
         const auto MOUSECOORDSABS = m_vLastCoords.floor() / 
pSurface->m_pMonitor->size;
         const auto CLICKPOS       = MOUSECOORDSABS * PBUFFER->pixelSize;
@@ -401,7 +521,7 @@
 
             cairo_scale(PCAIRO, 1, 1);
 
-            cairo_arc(PCAIRO, CLICKPOS.x, CLICKPOS.y, 105 / SCALEBUFS.x, 0, 2 
* M_PI);
+            cairo_arc(PCAIRO, CLICKPOS.x, CLICKPOS.y, m_iCircleRadius + 5 / 
SCALEBUFS.x, 0, 2 * M_PI);
             cairo_clip(PCAIRO);
 
             cairo_fill(PCAIRO);
@@ -417,25 +537,58 @@
             cairo_matrix_t matrix;
             cairo_matrix_init_identity(&matrix);
             cairo_matrix_translate(&matrix, CLICKPOSBUF.x + 0.5f, 
CLICKPOSBUF.y + 0.5f);
-            cairo_matrix_scale(&matrix, 0.1f, 0.1f);
+            cairo_matrix_scale(&matrix, 1.0 / m_fZoomScale, 1.0 / 
m_fZoomScale);
             cairo_matrix_translate(&matrix, (-CLICKPOSBUF.x / SCALEBUFS.x) - 
0.5f, (-CLICKPOSBUF.y / SCALEBUFS.y) - 0.5f);
             cairo_pattern_set_matrix(PATTERN, &matrix);
             cairo_set_source(PCAIRO, PATTERN);
-            cairo_arc(PCAIRO, CLICKPOS.x, CLICKPOS.y, 100 / SCALEBUFS.x, 0, 2 
* M_PI);
+            cairo_arc(PCAIRO, CLICKPOS.x, CLICKPOS.y, m_iCircleRadius / 
SCALEBUFS.x, 0, 2 * M_PI);
             cairo_clip(PCAIRO);
             cairo_paint(PCAIRO);
 
-            if (!m_bDisableHexPreview) {
+            if (!m_bDisablePreview) {
                 const auto  currentColor = getColorFromPixel(pSurface, 
CLICKPOS);
-                std::string hexBuffer;
-                if (m_bUseLowerCase)
-                    hexBuffer = std::format("#{:02x}{:02x}{:02x}", 
currentColor.r, currentColor.g, currentColor.b);
-                else
-                    hexBuffer = std::format("#{:02X}{:02X}{:02X}", 
currentColor.r, currentColor.g, currentColor.b);
-
-                cairo_set_source_rgba(PCAIRO, 0.0, 0.0, 0.0, 0.5);
+                std::string previewBuffer;
+                switch (m_bSelectedOutputMode) {
+                    case OUTPUT_HEX: {
+                        std::string rHex, gHex, bHex;
+                        if (m_bUseLowerCase) {
+                            rHex = std::format("{:02x}", currentColor.r);
+                            gHex = std::format("{:02x}", currentColor.g);
+                            bHex = std::format("{:02x}", currentColor.b);
+                        } else {
+                            rHex = std::format("{:02X}", currentColor.r);
+                            gHex = std::format("{:02X}", currentColor.g);
+                            bHex = std::format("{:02X}", currentColor.b);
+                        }
+                        previewBuffer = std::vformat(m_sOutputFormat, 
std::make_format_args(rHex, gHex, bHex));
+                        break;
+                    };
+                    case OUTPUT_RGB: {
+                        previewBuffer = std::vformat(m_sOutputFormat, 
std::make_format_args(currentColor.r, currentColor.g, currentColor.b));
+                        break;
+                    };
+                    case OUTPUT_HSL: {
+                        float h, s, l;
+                        currentColor.getHSL(h, s, l);
+                        previewBuffer = std::vformat(m_sOutputFormat, 
std::make_format_args(h, s, l));
+                        break;
+                    };
+                    case OUTPUT_HSV: {
+                        float h, s, v;
+                        currentColor.getHSV(h, s, v);
+                        previewBuffer = std::vformat(m_sOutputFormat, 
std::make_format_args(h, s, v));
+                        break;
+                    };
+                    case OUTPUT_CMYK: {
+                        float c, m, y, k;
+                        currentColor.getCMYK(c, m, y, k);
+                        previewBuffer = std::vformat(m_sOutputFormat, 
std::make_format_args(c, m, y, k));
+                        break;
+                    };
+                };
+                cairo_set_source_rgba(PCAIRO, 0.0, 0.0, 0.0, 0.75);
 
-                double x, y, width = 85, height = 28, radius = 6;
+                double x, y, width = 8 + (11 * previewBuffer.length()), height 
= 28, radius = 6;
 
                 if (CLICKPOS.y > (PBUFFER->pixelSize.y - 50) && CLICKPOS.x > 
(PBUFFER->pixelSize.x - 100)) {
                     x = CLICKPOS.x - 80;
@@ -450,7 +603,7 @@
                     x = CLICKPOS.x;
                     y = CLICKPOS.y + 20;
                 }
-
+                x -= 5.5 * previewBuffer.length();
                 cairo_move_to(PCAIRO, x + radius, y);
                 cairo_arc(PCAIRO, x + width - radius, y + radius, radius, 
-M_PI_2, 0);
                 cairo_arc(PCAIRO, x + width - radius, y + height - radius, 
radius, 0, M_PI_2);
@@ -476,19 +629,19 @@
                 else
                     cairo_move_to(PCAIRO, textX, CLICKPOS.y + 40);
 
-                cairo_show_text(PCAIRO, hexBuffer.c_str());
+                cairo_show_text(PCAIRO, previewBuffer.c_str());
 
                 cairo_surface_flush(PBUFFER->surface);
             }
             cairo_restore(PCAIRO);
             cairo_pattern_destroy(PATTERN);
         }
-    } else if (!m_bRenderInactive) {
+    } else if (!m_bRenderInactive && m_bCoordsInitialized) {
         cairo_set_operator(PCAIRO, CAIRO_OPERATOR_SOURCE);
         cairo_set_source_rgba(PCAIRO, 0, 0, 0, 0);
         cairo_rectangle(PCAIRO, 0, 0, PBUFFER->pixelSize.x, 
PBUFFER->pixelSize.y);
         cairo_fill(PCAIRO);
-    } else {
+    } else if (m_bCoordsInitialized) {
         const auto SCALEBUFS  = pSurface->screenBuffer->pixelSize / 
PBUFFER->pixelSize;
         const auto PATTERNPRE = 
cairo_pattern_create_for_surface(pSurface->screenBuffer->surface);
         cairo_pattern_set_filter(PATTERNPRE, CAIRO_FILTER_BILINEAR);
@@ -521,12 +674,13 @@
         return CColor{.r = 0, .g = 0, .b = 0, .a = 0};
 
     void* dataSrc = pLS->screenBuffer->paddedData ? 
pLS->screenBuffer->paddedData : pLS->screenBuffer->data;
-    struct pixel {
+
+    struct SPixel {
         unsigned char blue;
         unsigned char green;
         unsigned char red;
         unsigned char alpha;
-    }* px = (struct pixel*)((char*)dataSrc + ((ptrdiff_t)pix.y * 
(int)pLS->screenBuffer->pixelSize.x * 4) + ((ptrdiff_t)pix.x * 4));
+    }* px = (struct SPixel*)((char*)dataSrc + ((ptrdiff_t)pix.y * 
(int)pLS->screenBuffer->pixelSize.x * 4) + ((ptrdiff_t)pix.x * 4));
 
     return CColor{.r = px->red, .g = px->green, .b = px->blue, .a = px->alpha};
 }
@@ -567,12 +721,22 @@
     m_pKeyboard->setKey([this](CCWlKeyboard* r, uint32_t serial, uint32_t 
time, uint32_t key, uint32_t state) {
         if (state != WL_KEYBOARD_KEY_STATE_PRESSED)
             return;
-
         if (m_pXKBState) {
-            if (xkb_state_key_get_one_sym(m_pXKBState, key + 8) == 
XKB_KEY_Escape)
-                finish();
+            int32_t XKBKey = xkb_state_key_get_one_sym(m_pXKBState, key + 8);
+            if (XKBKey == XKB_KEY_Right)
+                m_vLastCoords.x += m_vLastCoords.x < 
m_pLastSurface->m_pMonitor->size.x;
+            else if (XKBKey == XKB_KEY_Left)
+                m_vLastCoords.x -= m_vLastCoords.x > 0;
+            else if (XKBKey == XKB_KEY_Up)
+                m_vLastCoords.y -= m_vLastCoords.y > 0;
+            else if (XKBKey == XKB_KEY_Down)
+                m_vLastCoords.y += m_vLastCoords.y < 
m_pLastSurface->m_pMonitor->size.y;
+            else if (XKBKey == XKB_KEY_Return)
+                outputColor();
+            else if (XKBKey == XKB_KEY_Escape)
+                finish(2);
         } else if (key == 1) // Assume keycode 1 is escape
-            finish();
+            finish(2);
     });
 }
 
@@ -581,7 +745,8 @@
         auto x = wl_fixed_to_double(surface_x);
         auto y = wl_fixed_to_double(surface_y);
 
-        m_vLastCoords = {x, y};
+        m_vLastCoords        = {x, y};
+        m_bCoordsInitialized = true;
 
         for (auto& ls : m_vLayerSurfaces) {
             if (ls->pSurface->resource() == surface) {
@@ -590,7 +755,8 @@
             }
         }
 
-        m_pCursorShapeDevice->sendSetShape(serial, 
WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_CROSSHAIR);
+        if (m_pCursorShapeDevice)
+            m_pCursorShapeDevice->sendSetShape(serial, 
WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_CROSSHAIR);
 
         markDirty();
     });
@@ -613,134 +779,18 @@
 
         markDirty();
     });
-    m_pPointer->setButton([this](CCWlPointer* r, uint32_t serial, uint32_t 
time, uint32_t button, uint32_t button_state) {
-        auto fmax3 = [](float a, float b, float c) -> float { return (a > b && 
a > c) ? a : (b > c) ? b : c; };
-        auto fmin3 = [](float a, float b, float c) -> float { return (a < b && 
a < c) ? a : (b < c) ? b : c; };
-
-        // relative brightness of a color
-        // https://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef
-        const auto FLUMI = [](const float& c) -> float { return c <= 0.03928 ? 
c / 12.92 : powf((c + 0.055) / 1.055, 2.4); };
-
-        // get the px and print it
-        const auto MOUSECOORDSABS = m_vLastCoords.floor() / 
m_pLastSurface->m_pMonitor->size;
-        const auto CLICKPOS       = MOUSECOORDSABS * 
m_pLastSurface->screenBuffer->pixelSize;
-
-        const auto COL = getColorFromPixel(m_pLastSurface, CLICKPOS);
-
-        // threshold: (lumi_white + 0.05) / (x + 0.05) == (x + 0.05) / 
(lumi_black + 0.05)
-        // https://www.w3.org/TR/2008/REC-WCAG20-20081211/#contrast-ratiodef
-        const uint8_t FG = 0.2126 * FLUMI(COL.r / 255.0f) + 0.7152 * 
FLUMI(COL.g / 255.0f) + 0.0722 * FLUMI(COL.b / 255.0f) > 0.17913 ? 0 : 255;
-
-        switch (m_bSelectedOutputMode) {
-            case OUTPUT_CMYK: {
-                // http://www.codeproject.com/KB/applications/xcmyk.aspx
-
-                float r = 1 - (COL.r / 255.0f), g = 1 - (COL.g / 255.0f), b = 
1 - (COL.b / 255.0f);
-                float k = fmin3(r, g, b), K = (k == 1) ? 1 : 1 - k;
-                float c = (r - k) / K, m = (g - k) / K, y = (b - k) / K;
-
-                c = std::round(c * 100);
-                m = std::round(m * 100);
-                y = std::round(y * 100);
-                k = std::round(k * 100);
-
-                if (m_bFancyOutput)
-                    Debug::log(NONE, "\033[38;2;%i;%i;%i;48;2;%i;%i;%im%g%% 
%g%% %g%% %g%%\033[0m", FG, FG, FG, COL.r, COL.g, COL.b, c, m, y, k);
-                else
-                    Debug::log(NONE, "%g%% %g%% %g%% %g%%", c, m, y, k);
-
-                if (m_bAutoCopy)
-                    Clipboard::copy("%g%% %g%% %g%% %g%%", c, m, y, k);
-                finish();
-                break;
-            }
-            case OUTPUT_HEX: {
-                auto toHex = [this](int i) -> std::string {
-                    const char* DS = m_bUseLowerCase ? "0123456789abcdef" : 
"0123456789ABCDEF";
-
-                    std::string result = "";
-
-                    result += DS[i / 16];
-                    result += DS[i % 16];
-
-                    return result;
-                };
-
-                auto hexR = toHex(COL.r);
-                auto hexG = toHex(COL.g);
-                auto hexB = toHex(COL.b);
-
-                if (m_bFancyOutput)
-                    Debug::log(NONE, 
"\033[38;2;%i;%i;%i;48;2;%i;%i;%im#%s%s%s\033[0m", FG, FG, FG, COL.r, COL.g, 
COL.b, toHex(COL.r).c_str(), toHex(COL.g).c_str(),
-                               toHex(COL.b).c_str());
-                else
-                    Debug::log(NONE, "#%s%s%s", toHex(COL.r).c_str(), 
toHex(COL.g).c_str(), toHex(COL.b).c_str());
-
-                if (m_bAutoCopy)
-                    Clipboard::copy("#%s%s%s", toHex(COL.r).c_str(), 
toHex(COL.g).c_str(), toHex(COL.b).c_str());
-                finish();
-                break;
-            }
-            case OUTPUT_RGB: {
-                if (m_bFancyOutput)
-                    Debug::log(NONE, "\033[38;2;%i;%i;%i;48;2;%i;%i;%im%i %i 
%i\033[0m", FG, FG, FG, COL.r, COL.g, COL.b, COL.r, COL.g, COL.b);
-                else
-                    Debug::log(NONE, "%i %i %i", COL.r, COL.g, COL.b);
-
-                if (m_bAutoCopy)
-                    Clipboard::copy("%i %i %i", COL.r, COL.g, COL.b);
-                finish();
-                break;
-            }
-            case OUTPUT_HSL:
-            case OUTPUT_HSV: {
-                // https://en.wikipedia.org/wiki/HSL_and_HSV#From_RGB
-
-                auto floatEq = [](float a, float b) -> bool {
-                    return std::nextafter(a, 
std::numeric_limits<double>::lowest()) <= b && std::nextafter(a, 
std::numeric_limits<double>::max()) >= b;
-                };
-
-                float h, s, l, v;
-                float r = COL.r / 255.0f, g = COL.g / 255.0f, b = COL.b / 
255.0f;
-                float max = fmax3(r, g, b), min = fmin3(r, g, b);
-                float c = max - min;
-
-                v = max;
-                if (c == 0)
-                    h = 0;
-                else if (v == r)
-                    h = 60 * (0 + (g - b) / c);
-                else if (v == g)
-                    h = 60 * (2 + (b - r) / c);
-                else /* v == b */
-                    h = 60 * (4 + (r - g) / c);
-
-                float l_or_v;
-                if (m_bSelectedOutputMode == OUTPUT_HSL) {
-                    l      = (max + min) / 2;
-                    s      = (floatEq(l, 0.0f) || floatEq(l, 1.0f)) ? 0 : (v - 
l) / std::min(l, 1 - l);
-                    l_or_v = std::round(l * 100);
-                } else {
-                    v      = max;
-                    s      = floatEq(v, 0.0f) ? 0 : c / v;
-                    l_or_v = std::round(v * 100);
-                }
-
-                h = std::round(h < 0 ? h + 360 : h);
-                s = std::round(s * 100);
+    m_pPointer->setButton([this](CCWlPointer* r, uint32_t serial, uint32_t 
time, uint32_t button, uint32_t button_state) { outputColor(); });
+    m_pPointer->setAxis([this](CCWlPointer* r, uint32_t time, uint32_t axis, 
wl_fixed_t value) {
+        if (axis != WL_POINTER_AXIS_VERTICAL_SCROLL)
+            return;
 
-                if (m_bFancyOutput)
-                    Debug::log(NONE, "\033[38;2;%i;%i;%i;48;2;%i;%i;%im%g %g%% 
%g%%\033[0m", FG, FG, FG, COL.r, COL.g, COL.b, h, s, l_or_v);
-                else
-                    Debug::log(NONE, "%g %g%% %g%%", h, s, l_or_v);
+        double delta = wl_fixed_to_double(value);
 
-                if (m_bAutoCopy)
-                    Clipboard::copy("%g %g%% %g%%", h, s, l_or_v);
-                finish();
-                break;
-            }
-        }
+        if (delta < 0)
+            m_fZoomScale = std::min(m_fZoomScale + 1.0, 100.0);
+        else
+            m_fZoomScale = std::max(m_fZoomScale - 1.0, 1.0);
 
-        finish();
+        markDirty();
     });
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hyprpicker-0.4.5/src/hyprpicker.hpp 
new/hyprpicker-0.4.6/src/hyprpicker.hpp
--- old/hyprpicker-0.4.5/src/hyprpicker.hpp     2025-05-01 02:54:26.000000000 
+0200
+++ new/hyprpicker-0.4.6/src/hyprpicker.hpp     2026-02-10 16:09:41.000000000 
+0100
@@ -4,14 +4,17 @@
 #include "helpers/LayerSurface.hpp"
 #include "helpers/PoolBuffer.hpp"
 
-enum eOutputMode {
+// OUTPUT_COUNT is being used to count the number of output formats, it should 
always be last in the enum
+enum eOutputMode : uint8_t {
     OUTPUT_CMYK = 0,
     OUTPUT_HEX,
     OUTPUT_RGB,
     OUTPUT_HSL,
-    OUTPUT_HSV
+    OUTPUT_HSV,
 };
 
+const std::array<uint8_t, 5> numOutputValues = {4, 3, 3, 3, 3};
+
 class CHyprpicker {
   public:
     void                                        init();
@@ -37,17 +40,21 @@
     xkb_state*                                  m_pXKBState   = nullptr;
 
     eOutputMode                                 m_bSelectedOutputMode = 
OUTPUT_HEX;
+    std::string                                 m_sOutputFormat       = "";
 
     bool                                        m_bFancyOutput = true;
 
-    bool                                        m_bAutoCopy          = false;
-    bool                                        m_bRenderInactive    = false;
-    bool                                        m_bNoZoom            = false;
-    bool                                        m_bNoFractional      = false;
-    bool                                        m_bDisableHexPreview = false;
-    bool                                        m_bUseLowerCase      = false;
-
-    bool                                        m_bRunning = true;
+    bool                                        m_bAutoCopy       = false;
+    bool                                        m_bNotify         = false;
+    bool                                        m_bRenderInactive = false;
+    bool                                        m_bNoZoom         = false;
+    bool                                        m_bNoFractional   = false;
+    bool                                        m_bDisablePreview = false;
+    bool                                        m_bUseLowerCase   = false;
+
+    bool                                        m_bRunning      = true;
+    float                                       m_fZoomScale    = 10.0;
+    int                                         m_iCircleRadius = 100;
 
     std::vector<std::unique_ptr<SMonitor>>      m_vMonitors;
     std::vector<std::unique_ptr<CLayerSurface>> m_vLayerSurfaces;
@@ -55,6 +62,7 @@
     CLayerSurface*                              m_pLastSurface;
 
     Vector2D                                    m_vLastCoords;
+    bool                                        m_bCoordsInitialized = false;
 
     void                                        renderSurface(CLayerSurface*, 
bool forceInactive = false);
 
@@ -72,6 +80,7 @@
     void                                        markDirty();
 
     void                                        finish(int code = 0);
+    void                                        outputColor();
 
     CColor                                      
getColorFromPixel(CLayerSurface*, Vector2D);
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hyprpicker-0.4.5/src/includes.hpp 
new/hyprpicker-0.4.6/src/includes.hpp
--- old/hyprpicker-0.4.5/src/includes.hpp       2025-05-01 02:54:26.000000000 
+0200
+++ new/hyprpicker-0.4.6/src/includes.hpp       2026-02-10 16:09:41.000000000 
+0100
@@ -35,7 +35,9 @@
 #include <unordered_map>
 
 #include <hyprutils/memory/WeakPtr.hpp>
+#include <hyprutils/os/Process.hpp>
 using namespace Hyprutils::Memory;
+using namespace Hyprutils::OS;
 
 #define SP CSharedPointer
 #define WP CWeakPointer
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hyprpicker-0.4.5/src/main.cpp 
new/hyprpicker-0.4.6/src/main.cpp
--- old/hyprpicker-0.4.5/src/main.cpp   2025-05-01 02:54:26.000000000 +0200
+++ new/hyprpicker-0.4.6/src/main.cpp   2026-02-10 16:09:41.000000000 +0100
@@ -1,22 +1,30 @@
+#include <cstdint>
+#include <format>
+#include <regex>
 #include <strings.h>
 
 #include <iostream>
 
 #include "hyprpicker.hpp"
+#include "src/debug/Log.hpp"
 
 static void help() {
     std::cout << "Hyprpicker usage: hyprpicker [arg [...]].\n\nArguments:\n"
               << " -a | --autocopy            | Automatically copies the 
output to the clipboard (requires wl-clipboard)\n"
               << " -f | --format=fmt          | Specifies the output format 
(cmyk, hex, rgb, hsl, hsv)\n"
-              << " -n | --no-fancy            | Disables the \"fancy\" (aka. 
colored) outputting\n"
+              << " -o | --output-format=fmt   | Specifies how the output color 
should be formatted e.g. rgb({0}, {1}, {2}) would output rgb(red, green, blue) 
if --format=rgb\n"
+              << " -n | --notify              | Sends a desktop notification 
when a color is picked (requires notify-send and a notification daemon like 
dunst)\n"
+              << " -b | --no-fancy            | Disables the \"fancy\" (aka. 
colored) outputting\n"
               << " -h | --help                | Show this help message\n"
               << " -r | --render-inactive     | Render (freeze) inactive 
displays\n"
               << " -z | --no-zoom             | Disable the zoom lens\n"
               << " -q | --quiet               | Disable most logs (leaves 
errors)\n"
               << " -v | --verbose             | Enable more logs\n"
               << " -t | --no-fractional       | Disable fractional scaling 
support\n"
-              << " -d | --disable-hex-preview | Disable live preview of Hex 
code\n"
+              << " -d | --disable-preview     | Disable live preview of 
color\n"
               << " -l | --lowercase-hex       | Outputs the hexcode in 
lowercase\n"
+              << " -s | --scale=scale         | Set the zoom scale (between 1 
and 10)\n"
+              << " -u | --radius=radius       | Set the circle radius (between 
1 and 1000)\n"
               << " -V | --version             | Print version info\n";
 }
 
@@ -27,19 +35,23 @@
         int                  option_index   = 0;
         static struct option long_options[] = {{"autocopy", no_argument, 
nullptr, 'a'},
                                                {"format", required_argument, 
nullptr, 'f'},
+                                               {"output-format", 
required_argument, nullptr, 'o'},
                                                {"help", no_argument, nullptr, 
'h'},
-                                               {"no-fancy", no_argument, 
nullptr, 'n'},
+                                               {"no-fancy", no_argument, 
nullptr, 'b'},
+                                               {"notify", no_argument, 
nullptr, 'n'},
                                                {"render-inactive", 
no_argument, nullptr, 'r'},
                                                {"no-zoom", no_argument, 
nullptr, 'z'},
                                                {"no-fractional", no_argument, 
nullptr, 't'},
                                                {"quiet", no_argument, nullptr, 
'q'},
                                                {"verbose", no_argument, 
nullptr, 'v'},
-                                               {"disable-hex-preview", 
no_argument, nullptr, 'd'},
+                                               {"disable-preview", 
no_argument, nullptr, 'd'},
                                                {"lowercase-hex", no_argument, 
nullptr, 'l'},
                                                {"version", no_argument, 
nullptr, 'V'},
+                                               {"scale", required_argument, 
nullptr, 's'},
+                                               {"radius", required_argument, 
nullptr, 'u'},
                                                {nullptr, 0, nullptr, 0}};
 
-        int                  c = getopt_long(argc, argv, ":f:hnarzqvtdlV", 
long_options, &option_index);
+        int                  c = getopt_long(argc, argv, 
":f:o:hnbarzqvtdlVs:u:", long_options, &option_index);
         if (c == -1)
             break;
 
@@ -60,21 +72,57 @@
                     exit(1);
                 }
                 break;
+            case 'o': g_pHyprpicker->m_sOutputFormat = optarg; break;
             case 'h': help(); exit(0);
-            case 'n': g_pHyprpicker->m_bFancyOutput = false; break;
+            case 'b': g_pHyprpicker->m_bFancyOutput = false; break;
+            case 'n': g_pHyprpicker->m_bNotify = true; break;
             case 'a': g_pHyprpicker->m_bAutoCopy = true; break;
             case 'r': g_pHyprpicker->m_bRenderInactive = true; break;
             case 'z': g_pHyprpicker->m_bNoZoom = true; break;
             case 't': g_pHyprpicker->m_bNoFractional = true; break;
             case 'q': Debug::quiet = true; break;
             case 'v': Debug::verbose = true; break;
-            case 'd': g_pHyprpicker->m_bDisableHexPreview = true; break;
+            case 'd': g_pHyprpicker->m_bDisablePreview = true; break;
             case 'l': g_pHyprpicker->m_bUseLowerCase = true; break;
             case 'V': {
                 std::cout << "hyprpicker v" << HYPRPICKER_VERSION << "\n";
                 exit(0);
             }
+            case 's': {
+                float value;
+                auto  result = std::from_chars(optarg, optarg + 
strlen(optarg), value);
 
+                if (result.ec != std::errc() || result.ptr != optarg + 
strlen(optarg)) {
+                    std::cerr << "Invalid scale value: " << optarg << "\n";
+                    exit(1);
+                }
+
+                if (value < 1.0f || value > 10.0f) {
+                    std::cerr << "Scale must be between 1 and 10!\n";
+                    exit(1);
+                }
+
+                g_pHyprpicker->m_fZoomScale = value;
+                break;
+            }
+
+            case 'u': {
+                int  value;
+                auto result = std::from_chars(optarg, optarg + strlen(optarg), 
value);
+
+                if (result.ec != std::errc() || result.ptr != optarg + 
strlen(optarg)) {
+                    std::cerr << "Invalid radius value: " << optarg << "\n";
+                    exit(1);
+                }
+
+                if (value < 1 || value > 1000) {
+                    std::cerr << "Radius must be between 1 and 1000!\n";
+                    exit(1);
+                }
+
+                g_pHyprpicker->m_iCircleRadius = value;
+                break;
+            }
             default: help(); exit(1);
         }
     }
@@ -82,6 +130,23 @@
     if (!isatty(fileno(stdout)) || getenv("NO_COLOR"))
         g_pHyprpicker->m_bFancyOutput = false;
 
+    if (g_pHyprpicker->m_sOutputFormat.empty()) {
+        switch (g_pHyprpicker->m_bSelectedOutputMode) {
+            case OUTPUT_CMYK: g_pHyprpicker->m_sOutputFormat = "{}% {}% {}% 
{}%"; break;
+            case OUTPUT_HEX: g_pHyprpicker->m_sOutputFormat = "#{}{}{}"; break;
+            case OUTPUT_RGB: g_pHyprpicker->m_sOutputFormat = "{} {} {}"; 
break;
+            case OUTPUT_HSL: g_pHyprpicker->m_sOutputFormat = "{} {}% {}%"; 
break;
+            case OUTPUT_HSV: g_pHyprpicker->m_sOutputFormat = "{} {}% {}%"; 
break;
+        }
+    }
+    try {
+        std::array<uint8_t, 4> dummy = {0, 0, 0, 0};
+        (void)std::vformat(g_pHyprpicker->m_sOutputFormat, 
std::make_format_args(dummy[0], dummy[1], dummy[2], dummy[3]));
+    } catch (const std::format_error& e) {
+        Debug::log(NONE, "Invalid --output-format: %s", e.what());
+        exit(1);
+    }
+
     g_pHyprpicker->init();
 
     return 0;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hyprpicker-0.4.5/src/notify/Notify.cpp 
new/hyprpicker-0.4.6/src/notify/Notify.cpp
--- old/hyprpicker-0.4.5/src/notify/Notify.cpp  1970-01-01 01:00:00.000000000 
+0100
+++ new/hyprpicker-0.4.6/src/notify/Notify.cpp  2026-02-10 16:09:41.000000000 
+0100
@@ -0,0 +1,19 @@
+#include "Notify.hpp"
+
+#include "../includes.hpp"
+#include <cstdint>
+#include <cstdio>
+#include <format>
+#include <hyprutils/os/Process.hpp>
+#include <iostream>
+#include <string>
+
+#include <hyprutils/os/Process.hpp>
+
+void NNotify::send(std::string hexColor, std::string formattedColor) {
+    std::string             notifyBody = std::format("<span>Selected color: 
<span color='{}'><b>{}</b></span></span>", hexColor, formattedColor);
+
+    Hyprutils::OS::CProcess notify("notify-send", {"-t", "5000", "-i", 
"color-select-symbolic", "Color Picker", notifyBody});
+
+    notify.runAsync();
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hyprpicker-0.4.5/src/notify/Notify.hpp 
new/hyprpicker-0.4.6/src/notify/Notify.hpp
--- old/hyprpicker-0.4.5/src/notify/Notify.hpp  1970-01-01 01:00:00.000000000 
+0100
+++ new/hyprpicker-0.4.6/src/notify/Notify.hpp  2026-02-10 16:09:41.000000000 
+0100
@@ -0,0 +1,8 @@
+#pragma once
+
+#include <cstdint>
+#include <string>
+
+namespace NNotify {
+    void send(std::string hexColor, std::string formattedColor);
+}

++++++ hyprpicker.obsinfo ++++++
--- /var/tmp/diff_new_pack.2xndIn/_old  2026-04-04 19:07:27.005205434 +0200
+++ /var/tmp/diff_new_pack.2xndIn/_new  2026-04-04 19:07:27.009205598 +0200
@@ -1,5 +1,5 @@
 name: hyprpicker
-version: 0.4.5
-mtime: 1746060866
-commit: 980ebd486b8a4c2ac1670286f38d163db1e38cd9
+version: 0.4.6
+mtime: 1770736181
+commit: 345eab2d704ee47a6c277cbfb2aeabaa620d9dbc
 

Reply via email to