From 5da4693a6627e7e43b31530b537a1f5b05fe310c Mon Sep 17 00:00:00 2001 From: r3b00thx Date: Wed, 4 Jun 2025 20:53:57 +0300 Subject: [PATCH 01/13] feat(notify): add notify support In this commit I added a new feature, a flag for notifications -n / --notify. It's using the notify-send command line utility to send desktop notifications. By default I made it compatible with dunst (you will need to enable full markup in the dunst config) but it should work with other notification daemons too. --- src/defines.hpp | 1 + src/hyprpicker.cpp | 31 +++++++++++++++++++++++++++++++ src/hyprpicker.hpp | 1 + src/main.cpp | 5 ++++- src/notify/Notify.cpp | 18 ++++++++++++++++++ src/notify/Notify.hpp | 8 ++++++++ 6 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 src/notify/Notify.cpp create mode 100644 src/notify/Notify.hpp diff --git a/src/defines.hpp b/src/defines.hpp index 599c418..dbf5438 100644 --- a/src/defines.hpp +++ b/src/defines.hpp @@ -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 --git a/src/hyprpicker.cpp b/src/hyprpicker.cpp index 8041d83..1e07c4d 100644 --- a/src/hyprpicker.cpp +++ b/src/hyprpicker.cpp @@ -1,5 +1,8 @@ #include "hyprpicker.hpp" +#include "src/notify/Notify.hpp" #include +#include +#include void sigHandler(int sig) { g_pHyprpicker->m_vLayerSurfaces.clear(); @@ -666,6 +669,13 @@ void CHyprpicker::initMouse() { if (m_bAutoCopy) Clipboard::copy("%g%% %g%% %g%% %g%%", c, m, y, k); + + if (m_bNotify) { + char buf[64]; + snprintf(buf, sizeof(buf), "cmyk(%f%%, %f%%, %f%%, %f%%)", c, m, y, k); + Notify::send(buf); + } + finish(); break; } @@ -693,6 +703,13 @@ void CHyprpicker::initMouse() { if (m_bAutoCopy) Clipboard::copy("#%s%s%s", toHex(COL.r).c_str(), toHex(COL.g).c_str(), toHex(COL.b).c_str()); + + if (m_bNotify) { + char buf[64]; + snprintf(buf, sizeof(buf), "#%s%s%s", toHex(COL.r).c_str(), toHex(COL.g).c_str(), toHex(COL.b).c_str()); + Notify::send(buf); + } + finish(); break; } @@ -704,6 +721,13 @@ void CHyprpicker::initMouse() { if (m_bAutoCopy) Clipboard::copy("%i %i %i", COL.r, COL.g, COL.b); + + if (m_bNotify) { + char buf[64]; + snprintf(buf, sizeof(buf), "rgb(%i, %i, %i)", COL.r, COL.g, COL.b); + Notify::send(buf); + } + finish(); break; } @@ -721,6 +745,13 @@ void CHyprpicker::initMouse() { if (m_bAutoCopy) Clipboard::copy("%g %g%% %g%%", h, s, l_or_v); + + if (m_bNotify) { + char buf[64]; + snprintf(buf, sizeof(buf), "hsl(%f, %f%%, %f%%)", h, s, l_or_v); + Notify::send(buf); + } + finish(); break; } diff --git a/src/hyprpicker.hpp b/src/hyprpicker.hpp index 288b869..0453f61 100644 --- a/src/hyprpicker.hpp +++ b/src/hyprpicker.hpp @@ -41,6 +41,7 @@ class CHyprpicker { bool m_bFancyOutput = true; bool m_bAutoCopy = false; + bool m_bNotify = false; bool m_bRenderInactive = false; bool m_bNoZoom = false; bool m_bNoFractional = false; diff --git a/src/main.cpp b/src/main.cpp index 1fa9f9f..4c5bb72 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -8,6 +8,7 @@ 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" + << " -j | --notify | Sends a desktop notification when a color is picked (requires notify-send and a notification daemon like dunst)\n" << " -n | --no-fancy | Disables the \"fancy\" (aka. colored) outputting\n" << " -h | --help | Show this help message\n" << " -r | --render-inactive | Render (freeze) inactive displays\n" @@ -29,6 +30,7 @@ int main(int argc, char** argv, char** envp) { {"format", required_argument, nullptr, 'f'}, {"help", no_argument, nullptr, 'h'}, {"no-fancy", no_argument, nullptr, 'n'}, + {"notify", no_argument, nullptr, 'j'}, {"render-inactive", no_argument, nullptr, 'r'}, {"no-zoom", no_argument, nullptr, 'z'}, {"no-fractional", no_argument, nullptr, 't'}, @@ -39,7 +41,7 @@ int main(int argc, char** argv, char** envp) { {"version", no_argument, nullptr, 'V'}, {nullptr, 0, nullptr, 0}}; - int c = getopt_long(argc, argv, ":f:hnarzqvtdlV", long_options, &option_index); + int c = getopt_long(argc, argv, ":f:hnjarzqvtdlV", long_options, &option_index); if (c == -1) break; @@ -62,6 +64,7 @@ int main(int argc, char** argv, char** envp) { break; case 'h': help(); exit(0); case 'n': g_pHyprpicker->m_bFancyOutput = false; break; + case 'j': 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; diff --git a/src/notify/Notify.cpp b/src/notify/Notify.cpp new file mode 100644 index 0000000..51950f2 --- /dev/null +++ b/src/notify/Notify.cpp @@ -0,0 +1,18 @@ +#include "Notify.hpp" + +#include "../includes.hpp" +#include +#include +#include + +void Notify::send(const char* color) { + char bodyBuf[NOTIFYBODYSIZE]; + char colorBuf[64]; + + snprintf(bodyBuf, sizeof(bodyBuf), "You selected the color: %s", color, color); + + if (fork() == 0) + execlp("notify-send", "notify-send", "-t", "5000", "-i", "color-select-symbolic", "Color Picker", bodyBuf, NULL); + + std::cout << colorBuf; +} diff --git a/src/notify/Notify.hpp b/src/notify/Notify.hpp new file mode 100644 index 0000000..1f0e4d0 --- /dev/null +++ b/src/notify/Notify.hpp @@ -0,0 +1,8 @@ +#pragma once + +#include +#define NOTIFYBODYSIZE 128 + +namespace Notify { + void send(const char* color); +} From 09fd839ec64cd82452fbd8be455650fb88c7c486 Mon Sep 17 00:00:00 2001 From: r3b00thx Date: Wed, 4 Jun 2025 22:18:29 +0300 Subject: [PATCH 02/13] fix(notify): fix notify foreground colors In this commit I fixed various issues from using c style code, trying to maintain the same code base even tho is pretty trash in some places. I also fixed the markup foreground color render, now it renders proerply the color from, in all the supported formats. --- src/hyprpicker.cpp | 46 +++++++++++++++++++++---------------------- src/notify/Notify.cpp | 13 +++++------- src/notify/Notify.hpp | 3 ++- 3 files changed, 30 insertions(+), 32 deletions(-) diff --git a/src/hyprpicker.cpp b/src/hyprpicker.cpp index 1e07c4d..41bb3ee 100644 --- a/src/hyprpicker.cpp +++ b/src/hyprpicker.cpp @@ -658,6 +658,19 @@ void CHyprpicker::initMouse() { // 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; + 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; + }; + + std::string hexColor = std::format("#{}{}{}", toHex(COL.r), toHex(COL.g), toHex(COL.b)); + switch (m_bSelectedOutputMode) { case OUTPUT_CMYK: { float c, m, y, k; @@ -671,26 +684,15 @@ void CHyprpicker::initMouse() { Clipboard::copy("%g%% %g%% %g%% %g%%", c, m, y, k); if (m_bNotify) { - char buf[64]; - snprintf(buf, sizeof(buf), "cmyk(%f%%, %f%%, %f%%, %f%%)", c, m, y, k); - Notify::send(buf); + std::string formattedColor = std::format("cmyk({}%, {}%, {}%, {}%)", c, m, y, k); + + Notify::send(hexColor, formattedColor); } 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); @@ -705,9 +707,7 @@ void CHyprpicker::initMouse() { Clipboard::copy("#%s%s%s", toHex(COL.r).c_str(), toHex(COL.g).c_str(), toHex(COL.b).c_str()); if (m_bNotify) { - char buf[64]; - snprintf(buf, sizeof(buf), "#%s%s%s", toHex(COL.r).c_str(), toHex(COL.g).c_str(), toHex(COL.b).c_str()); - Notify::send(buf); + Notify::send(hexColor, hexColor); } finish(); @@ -723,9 +723,9 @@ void CHyprpicker::initMouse() { Clipboard::copy("%i %i %i", COL.r, COL.g, COL.b); if (m_bNotify) { - char buf[64]; - snprintf(buf, sizeof(buf), "rgb(%i, %i, %i)", COL.r, COL.g, COL.b); - Notify::send(buf); + std::string formattedColor = std::format("rgb({}, {}, {})", COL.r, COL.g, COL.b); + + Notify::send(hexColor, formattedColor); } finish(); @@ -747,9 +747,9 @@ void CHyprpicker::initMouse() { Clipboard::copy("%g %g%% %g%%", h, s, l_or_v); if (m_bNotify) { - char buf[64]; - snprintf(buf, sizeof(buf), "hsl(%f, %f%%, %f%%)", h, s, l_or_v); - Notify::send(buf); + std::string formattedColor = std::format("hsl({}, {}%, {}%)", h, s, l_or_v); + + Notify::send(hexColor, formattedColor); } finish(); diff --git a/src/notify/Notify.cpp b/src/notify/Notify.cpp index 51950f2..1847b61 100644 --- a/src/notify/Notify.cpp +++ b/src/notify/Notify.cpp @@ -3,16 +3,13 @@ #include "../includes.hpp" #include #include +#include #include +#include -void Notify::send(const char* color) { - char bodyBuf[NOTIFYBODYSIZE]; - char colorBuf[64]; - - snprintf(bodyBuf, sizeof(bodyBuf), "You selected the color: %s", color, color); +void Notify::send(std::string hexColor, std::string formattedColor) { + std::string bodyString = std::format("You selected the color: {}", hexColor, formattedColor); if (fork() == 0) - execlp("notify-send", "notify-send", "-t", "5000", "-i", "color-select-symbolic", "Color Picker", bodyBuf, NULL); - - std::cout << colorBuf; + execlp("notify-send", "notify-send", "-t", "5000", "-i", "color-select-symbolic", "Color Picker", bodyString.c_str(), NULL); } diff --git a/src/notify/Notify.hpp b/src/notify/Notify.hpp index 1f0e4d0..489daf7 100644 --- a/src/notify/Notify.hpp +++ b/src/notify/Notify.hpp @@ -1,8 +1,9 @@ #pragma once #include +#include #define NOTIFYBODYSIZE 128 namespace Notify { - void send(const char* color); + void send(std::string hexColor, std::string formattedColor); } From d8a9408bc6be7e8fe0a9dcba32a717969d89ef57 Mon Sep 17 00:00:00 2001 From: r3b00thx Date: Thu, 5 Jun 2025 16:36:29 +0300 Subject: [PATCH 03/13] refactor(codebase): refactor some of the c style code into cpp In this commit I moddified some naming conventions to algin better with cpp standards, I also moddified the clipboard function to use just a single argument instead of multiple. --- src/clipboard/Clipboard.cpp | 17 ++-------- src/clipboard/Clipboard.hpp | 7 ++-- src/hyprpicker.cpp | 64 ++++++++++++++++++------------------- src/main.cpp | 15 ++++----- src/notify/Notify.cpp | 2 +- src/notify/Notify.hpp | 2 +- 6 files changed, 48 insertions(+), 59 deletions(-) diff --git a/src/clipboard/Clipboard.cpp b/src/clipboard/Clipboard.cpp index 28390df..c7c65c0 100644 --- a/src/clipboard/Clipboard.cpp +++ b/src/clipboard/Clipboard.cpp @@ -1,20 +1,9 @@ #include "Clipboard.hpp" #include "../includes.hpp" +#include -void Clipboard::copy(const char* fmt, ...) { - char buf[CLIPBOARDMESSAGESIZE] = ""; - char* outputStr; - - va_list args; - va_start(args, fmt); - vsnprintf(buf, sizeof buf, fmt, args); - va_end(args); - - outputStr = strdup(buf); - +void NClipboard::copy(std::string color) { if (fork() == 0) - execlp("wl-copy", "wl-copy", outputStr, NULL); - - free(outputStr); + execlp("wl-copy", "wl-copy", color.c_str(), NULL); } diff --git a/src/clipboard/Clipboard.hpp b/src/clipboard/Clipboard.hpp index 1dc2be1..7e4e193 100644 --- a/src/clipboard/Clipboard.hpp +++ b/src/clipboard/Clipboard.hpp @@ -1,7 +1,8 @@ #pragma once +#include #define CLIPBOARDMESSAGESIZE 24 -namespace Clipboard { - void copy(const char* fmt, ...); -}; \ No newline at end of file +namespace NClipboard { + void copy(std::string color); +}; diff --git a/src/hyprpicker.cpp b/src/hyprpicker.cpp index 41bb3ee..ebe190f 100644 --- a/src/hyprpicker.cpp +++ b/src/hyprpicker.cpp @@ -1,10 +1,11 @@ #include "hyprpicker.hpp" #include "src/notify/Notify.hpp" #include +#include #include #include -void sigHandler(int sig) { +static void sigHandler(int sig) { g_pHyprpicker->m_vLayerSurfaces.clear(); exit(0); } @@ -245,13 +246,13 @@ void CHyprpicker::convertBuffer(SP pBuffer) { 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(y * (int)pBuffer->pixelSize.x * 4)) + (static_cast(x * 4))); std::swap(px->red, px->blue); } @@ -265,7 +266,7 @@ void CHyprpicker::convertBuffer(SP pBuffer) { 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(y * (int)pBuffer->pixelSize.x * 4)) + (static_cast(x * 4))); // conv to 8 bit uint8_t R = (uint8_t)std::round((255.0 * (((*px) & 0b00000000000000000000001111111111) >> 0) / 1023.0)); @@ -295,19 +296,19 @@ void* CHyprpicker::convert24To32Buffer(SP pBuffer) { 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(y * pBuffer->stride)) + (static_cast(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(y * newBufferStride)) + (static_cast(x * 4))); *dstPx = {.blue = srcPx->red, .green = srcPx->green, .red = srcPx->blue, .alpha = 0xFF}; } } @@ -315,19 +316,19 @@ void* CHyprpicker::convert24To32Buffer(SP pBuffer) { 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}; } } @@ -551,12 +552,13 @@ CColor CHyprpicker::getColorFromPixel(CLayerSurface* pLS, Vector2D pix) { 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}; } @@ -675,28 +677,25 @@ void CHyprpicker::initMouse() { case OUTPUT_CMYK: { float c, m, y, k; COL.getCMYK(c, m, y, k); + + std::string formattedColor = std::format("{}% {}% {}% {}%", c, m, y, k); + 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); + NClipboard::copy(formattedColor); if (m_bNotify) { - std::string formattedColor = std::format("cmyk({}%, {}%, {}%, {}%)", c, m, y, k); - - Notify::send(hexColor, formattedColor); + NNotify::send(hexColor, formattedColor); } finish(); break; } case OUTPUT_HEX: { - 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()); @@ -704,28 +703,28 @@ void CHyprpicker::initMouse() { 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()); + NClipboard::copy(hexColor); if (m_bNotify) { - Notify::send(hexColor, hexColor); + NNotify::send(hexColor, hexColor); } finish(); break; } case OUTPUT_RGB: { + std::string formattedColor = std::format("{} {} {}", COL.r, COL.g, COL.b); + 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); + NClipboard::copy(formattedColor); if (m_bNotify) { - std::string formattedColor = std::format("rgb({}, {}, {})", COL.r, COL.g, COL.b); - - Notify::send(hexColor, formattedColor); + NNotify::send(hexColor, formattedColor); } finish(); @@ -738,18 +737,19 @@ void CHyprpicker::initMouse() { COL.getHSV(h, s, l_or_v); else COL.getHSL(h, s, l_or_v); + + std::string formattedColor = std::format("{} {}% {}%", h, s, l_or_v); + 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); if (m_bAutoCopy) - Clipboard::copy("%g %g%% %g%%", h, s, l_or_v); + NClipboard::copy(formattedColor); if (m_bNotify) { - std::string formattedColor = std::format("hsl({}, {}%, {}%)", h, s, l_or_v); - - Notify::send(hexColor, formattedColor); + NNotify::send(hexColor, formattedColor); } finish(); diff --git a/src/main.cpp b/src/main.cpp index 4c5bb72..764c623 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -8,8 +8,8 @@ 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" - << " -j | --notify | Sends a desktop notification when a color is picked (requires notify-send and a notification daemon like dunst)\n" - << " -n | --no-fancy | Disables the \"fancy\" (aka. colored) outputting\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" @@ -29,8 +29,8 @@ int main(int argc, char** argv, char** envp) { static struct option long_options[] = {{"autocopy", no_argument, nullptr, 'a'}, {"format", required_argument, nullptr, 'f'}, {"help", no_argument, nullptr, 'h'}, - {"no-fancy", no_argument, nullptr, 'n'}, - {"notify", no_argument, nullptr, 'j'}, + {"notify", no_argument, nullptr, 'n'}, + {"no-fancy", no_argument, nullptr, 'b'}, {"render-inactive", no_argument, nullptr, 'r'}, {"no-zoom", no_argument, nullptr, 'z'}, {"no-fractional", no_argument, nullptr, 't'}, @@ -41,7 +41,7 @@ int main(int argc, char** argv, char** envp) { {"version", no_argument, nullptr, 'V'}, {nullptr, 0, nullptr, 0}}; - int c = getopt_long(argc, argv, ":f:hnjarzqvtdlV", long_options, &option_index); + int c = getopt_long(argc, argv, ":f:hnbarzqvtdlV", long_options, &option_index); if (c == -1) break; @@ -63,9 +63,8 @@ int main(int argc, char** argv, char** envp) { } break; case 'h': help(); exit(0); - case 'n': g_pHyprpicker->m_bFancyOutput = false; break; - case 'j': g_pHyprpicker->m_bNotify = true; break; - case 'a': g_pHyprpicker->m_bAutoCopy = true; break; + case 'n': g_pHyprpicker->m_bNotify = true; break; + case 'b': g_pHyprpicker->m_bFancyOutput = false; 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; diff --git a/src/notify/Notify.cpp b/src/notify/Notify.cpp index 1847b61..dbd3b24 100644 --- a/src/notify/Notify.cpp +++ b/src/notify/Notify.cpp @@ -7,7 +7,7 @@ #include #include -void Notify::send(std::string hexColor, std::string formattedColor) { +void NNotify::send(std::string hexColor, std::string formattedColor) { std::string bodyString = std::format("You selected the color: {}", hexColor, formattedColor); if (fork() == 0) diff --git a/src/notify/Notify.hpp b/src/notify/Notify.hpp index 489daf7..79a7271 100644 --- a/src/notify/Notify.hpp +++ b/src/notify/Notify.hpp @@ -4,6 +4,6 @@ #include #define NOTIFYBODYSIZE 128 -namespace Notify { +namespace NNotify { void send(std::string hexColor, std::string formattedColor); } From 289603c9b4537599620822e6f60d3ae10c2b1bd2 Mon Sep 17 00:00:00 2001 From: r3b00thx Date: Thu, 5 Jun 2025 16:45:41 +0300 Subject: [PATCH 04/13] fix(autoacopy): fix autocopy By mistake I removed the autocopy in the last commit. Sorry, autocopy it's back in this commit --- src/main.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 764c623..ed15b06 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -29,8 +29,8 @@ int main(int argc, char** argv, char** envp) { static struct option long_options[] = {{"autocopy", no_argument, nullptr, 'a'}, {"format", required_argument, nullptr, 'f'}, {"help", no_argument, nullptr, 'h'}, - {"notify", no_argument, nullptr, 'n'}, - {"no-fancy", no_argument, nullptr, 'b'}, + {"no-fancy", no_argument, nullptr, 'n'}, + {"notify", no_argument, nullptr, 'j'}, {"render-inactive", no_argument, nullptr, 'r'}, {"no-zoom", no_argument, nullptr, 'z'}, {"no-fractional", no_argument, nullptr, 't'}, @@ -63,8 +63,9 @@ int main(int argc, char** argv, char** envp) { } break; case 'h': help(); exit(0); - case 'n': g_pHyprpicker->m_bNotify = true; 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; From a9d1808f4c8ab8a4740548eee4026bb6c8d11cc3 Mon Sep 17 00:00:00 2001 From: r3b00thx Date: Thu, 5 Jun 2025 17:06:05 +0300 Subject: [PATCH 05/13] style(preview): increase preview contrast In this commit I increased the preview contrast of the color preview buffer background to look better on different colors. --- src/hyprpicker.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hyprpicker.cpp b/src/hyprpicker.cpp index ebe190f..5588c2f 100644 --- a/src/hyprpicker.cpp +++ b/src/hyprpicker.cpp @@ -464,7 +464,7 @@ void CHyprpicker::renderSurface(CLayerSurface* pSurface, bool forceInactive) { break; }; }; - cairo_set_source_rgba(PCAIRO, 0.0, 0.0, 0.0, 0.5); + cairo_set_source_rgba(PCAIRO, 0.0, 0.0, 0.0, 0.75); double x, y, width = 8 + (11 * previewBuffer.length()), height = 28, radius = 6; From a26b35a4a1803e07b5766a5e3a546d3f8036f3b6 Mon Sep 17 00:00:00 2001 From: r3b00thx Date: Thu, 5 Jun 2025 17:10:30 +0300 Subject: [PATCH 06/13] chore(main): fix flag mismatch I fixed the flag mismatch for the no fancy option. --- src/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index ed15b06..0f43b18 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -29,8 +29,8 @@ int main(int argc, char** argv, char** envp) { static struct option long_options[] = {{"autocopy", no_argument, nullptr, 'a'}, {"format", required_argument, nullptr, 'f'}, {"help", no_argument, nullptr, 'h'}, - {"no-fancy", no_argument, nullptr, 'n'}, - {"notify", no_argument, nullptr, 'j'}, + {"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'}, From 332450f3bcf1a70b23e454b61548212f58b4b391 Mon Sep 17 00:00:00 2001 From: r3b00thx Date: Thu, 5 Jun 2025 17:59:48 +0300 Subject: [PATCH 07/13] refactor(notify): refactor notify and clipboard to use hyprutils cprocess This refactors the logic for running `notify-send` and `wl-copy` by using Hyprutils::OS::CProcess to spawn and manage these external processes in a more structured way. --- src/clipboard/Clipboard.cpp | 13 ++++++++++--- src/clipboard/Clipboard.hpp | 3 +-- src/includes.hpp | 2 ++ src/notify/Notify.cpp | 13 ++++++++++--- 4 files changed, 23 insertions(+), 8 deletions(-) diff --git a/src/clipboard/Clipboard.cpp b/src/clipboard/Clipboard.cpp index c7c65c0..386f9a2 100644 --- a/src/clipboard/Clipboard.cpp +++ b/src/clipboard/Clipboard.cpp @@ -1,9 +1,16 @@ #include "Clipboard.hpp" #include "../includes.hpp" +#include #include +#include -void NClipboard::copy(std::string color) { - if (fork() == 0) - execlp("wl-copy", "wl-copy", color.c_str(), NULL); +void NClipboard::copy(std::string data) { + std::string clipboardBinary = "wl-copy"; + + std::vector clipboardArgs = {data}; + + Hyprutils::OS::CProcess copy(clipboardBinary, clipboardArgs); + + copy.runAsync(); } diff --git a/src/clipboard/Clipboard.hpp b/src/clipboard/Clipboard.hpp index 7e4e193..4038cd3 100644 --- a/src/clipboard/Clipboard.hpp +++ b/src/clipboard/Clipboard.hpp @@ -1,8 +1,7 @@ #pragma once #include -#define CLIPBOARDMESSAGESIZE 24 namespace NClipboard { - void copy(std::string color); + void copy(std::string data); }; diff --git a/src/includes.hpp b/src/includes.hpp index 0b17c60..7c48fc8 100644 --- a/src/includes.hpp +++ b/src/includes.hpp @@ -35,7 +35,9 @@ #include #include +#include using namespace Hyprutils::Memory; +using namespace Hyprutils::OS; #define SP CSharedPointer #define WP CWeakPointer diff --git a/src/notify/Notify.cpp b/src/notify/Notify.cpp index dbd3b24..962bc45 100644 --- a/src/notify/Notify.cpp +++ b/src/notify/Notify.cpp @@ -4,12 +4,19 @@ #include #include #include +#include #include #include +#include + void NNotify::send(std::string hexColor, std::string formattedColor) { - std::string bodyString = std::format("You selected the color: {}", hexColor, formattedColor); + std::string notifyBody = std::format("You selected the color: {}", hexColor, formattedColor); + + std::string notifyBinary = "notify-send"; + std::vector notifyArgs = {"-t", "5000", "-i", "color-select-symbolic", "Color Picker", notifyBody}; + + Hyprutils::OS::CProcess notify(notifyBinary, notifyArgs); - if (fork() == 0) - execlp("notify-send", "notify-send", "-t", "5000", "-i", "color-select-symbolic", "Color Picker", bodyString.c_str(), NULL); + notify.runAsync(); } From c612ede266397e8cae62b77ef7e21f431fd3edcb Mon Sep 17 00:00:00 2001 From: r3b00thx Date: Fri, 6 Jun 2025 01:04:05 +0300 Subject: [PATCH 08/13] chore(gcc): update nix gcc version --- flake.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flake.nix b/flake.nix index 1f08e0c..c75867e 100644 --- a/flake.nix +++ b/flake.nix @@ -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;}; From 50fea1262edd7e0205ae0f3b4456e783dcfee6e9 Mon Sep 17 00:00:00 2001 From: r3b00thx Date: Fri, 6 Jun 2025 17:33:48 +0300 Subject: [PATCH 09/13] chore(readme): update README.md In this commit I updated the readme file to look much nicer and better offering more information regarding HyprPicker and better design overall. --- README.md | 104 +++++++++++++++++++++++++++++++----------- src/notify/Notify.hpp | 1 - 2 files changed, 77 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index c42834f..f019f2e 100644 --- a/README.md +++ b/README.md @@ -1,48 +1,98 @@ -# hyprpicker +

+ Hyprpicker logo +

-A wlroots-compatible Wayland color picker that does not suck. +

+ Repo Size + Language + License + Wayland +

-![hyprpickerShort](https://user-images.githubusercontent.com/43317083/188224867-7d77a3b3-0a66-488c-8019-39b00060ab42.gif) +

A sleek, wlroots-native color picker for Wayland built for Hyprland with a focus on speed, accuracy, and simplicity.

-# Usage +

+ hyprpicker demo +

-Launch it. Click. That's it. -## Options -See `hyprpicker --help`. +## ✨ Description -# Installation +**Hyprpicker** is a **blazing-fast, minimal, and accurate color picker** built for **Wayland compositors** like **Hyprland**. +It lets you instantly grab any color from your screen with pixel-perfect precision. -## Arch +Hyprpicker is designed to *just work* with clipboard copying, format selection, zoom lens, and desktop notifications. -`sudo pacman -S hyprpicker` -## Manual (Building) -Install dependencies: - - cmake - - pkg-config - - pango - - cairo - - wayland - - wayland-protocols - - hyprutils - - xkbcommon +## 🚀 Usage -Building is done via CMake: +**Run it, click anywhere, get the color.** +By default, the color is printed to stdout. Combine it with options like clipboard copy or notification for a smoother experience. ```sh -cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_INSTALL_PREFIX:PATH=/usr -S . -B ./build -cmake --build ./build --config Release --target hyprpicker -j`nproc 2>/dev/null || getconf _NPROCESSORS_CONF` +hyprpicker -a -n -b -fmt rgb ``` -Install with: + + +## 🧰 Command-Line Options ```sh -cmake --install ./build +Hyprpicker usage: hyprpicker [arg [...]]. + +Arguments: + -a | --autocopy | Automatically copies the output to the clipboard (requires wl-clipboard) + -f | --format=fmt | Specifies the output format (cmyk, hex, rgb, hsl, hsv) + -n | --notify | Sends a desktop notification when a color is picked (requires notify-send and a notification daemon like dunst) + -b | --no-fancy | Disables the "fancy" (aka. colored) outputting + -h | --help | Show this help message + -r | --render-inactive | Render (freeze) inactive displays + -z | --no-zoom | Disable the zoom lens + -q | --quiet | Disable most logs (leaves errors) + -v | --verbose | Enable more logs + -t | --no-fractional | Disable fractional scaling support + -d | --disable-preview | Disable live preview of color + -l | --lowercase-hex | Outputs the hexcode in lowercase + -V | --version | Print version info ``` -# Caveats -"Freezes" your displays when picking the color. + +## 📦 Installation + +```sh +sudo pacman -S hyprpicker +``` + + + +## 🔧 Build From Source + +### Dependencies + +- cmake +- pkg-config +- pango +- cairo +- wayland +- wayland-protocols +- hyprutils +- xkbcommon + + + +### Build and install + +```sh +cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr -S . -B ./build +cmake --build ./build --config Release --target hyprpicker -j$(nproc) +sudo cmake --install ./build +``` + + + +## 📚 License + +Hyprpicker is licensed under the BSD 3-Clause License — a permissive license that allows nearly unrestricted use, including commercial, as long as proper credit is given. diff --git a/src/notify/Notify.hpp b/src/notify/Notify.hpp index 79a7271..1cd09f0 100644 --- a/src/notify/Notify.hpp +++ b/src/notify/Notify.hpp @@ -2,7 +2,6 @@ #include #include -#define NOTIFYBODYSIZE 128 namespace NNotify { void send(std::string hexColor, std::string formattedColor); From 0a02379432b2302f3c3130c4e85480717a9be5b7 Mon Sep 17 00:00:00 2001 From: R3B00T Date: Fri, 6 Jun 2025 17:53:02 +0300 Subject: [PATCH 10/13] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f019f2e..1ef9bd2 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ Hyprpicker is designed to *just work* with clipboard copying, format selection, By default, the color is printed to stdout. Combine it with options like clipboard copy or notification for a smoother experience. ```sh -hyprpicker -a -n -b -fmt rgb +hyprpicker -a -n -b -f rgb ``` From 9fa9b06afb6d5b8dd0678282c497113b6df39395 Mon Sep 17 00:00:00 2001 From: r3b00thx Date: Sat, 7 Jun 2025 11:25:53 +0300 Subject: [PATCH 11/13] chore(code): remove intermediary variables In this commit I did various chores, I removed the intermediary variables from the clipboard and notify, and other various fixes in the hyprpicker.cpp --- src/clipboard/Clipboard.cpp | 6 +----- src/hyprpicker.cpp | 14 +++++--------- src/notify/Notify.cpp | 7 ++----- 3 files changed, 8 insertions(+), 19 deletions(-) diff --git a/src/clipboard/Clipboard.cpp b/src/clipboard/Clipboard.cpp index 386f9a2..024653b 100644 --- a/src/clipboard/Clipboard.cpp +++ b/src/clipboard/Clipboard.cpp @@ -6,11 +6,7 @@ #include void NClipboard::copy(std::string data) { - std::string clipboardBinary = "wl-copy"; - - std::vector clipboardArgs = {data}; - - Hyprutils::OS::CProcess copy(clipboardBinary, clipboardArgs); + Hyprutils::OS::CProcess copy("wl-copy", {data}); copy.runAsync(); } diff --git a/src/hyprpicker.cpp b/src/hyprpicker.cpp index 5588c2f..07f69db 100644 --- a/src/hyprpicker.cpp +++ b/src/hyprpicker.cpp @@ -671,7 +671,7 @@ void CHyprpicker::initMouse() { return result; }; - std::string hexColor = std::format("#{}{}{}", toHex(COL.r), toHex(COL.g), toHex(COL.b)); + std::string hexColor = std::format("#{0:02x}{1:02x}{2:02x}", COL.r, COL.g, COL.b); switch (m_bSelectedOutputMode) { case OUTPUT_CMYK: { @@ -688,9 +688,8 @@ void CHyprpicker::initMouse() { if (m_bAutoCopy) NClipboard::copy(formattedColor); - if (m_bNotify) { + if (m_bNotify) NNotify::send(hexColor, formattedColor); - } finish(); break; @@ -705,9 +704,8 @@ void CHyprpicker::initMouse() { if (m_bAutoCopy) NClipboard::copy(hexColor); - if (m_bNotify) { + if (m_bNotify) NNotify::send(hexColor, hexColor); - } finish(); break; @@ -723,9 +721,8 @@ void CHyprpicker::initMouse() { if (m_bAutoCopy) NClipboard::copy(formattedColor); - if (m_bNotify) { + if (m_bNotify) NNotify::send(hexColor, formattedColor); - } finish(); break; @@ -748,9 +745,8 @@ void CHyprpicker::initMouse() { if (m_bAutoCopy) NClipboard::copy(formattedColor); - if (m_bNotify) { + if (m_bNotify) NNotify::send(hexColor, formattedColor); - } finish(); break; diff --git a/src/notify/Notify.cpp b/src/notify/Notify.cpp index 962bc45..5379afa 100644 --- a/src/notify/Notify.cpp +++ b/src/notify/Notify.cpp @@ -11,12 +11,9 @@ #include void NNotify::send(std::string hexColor, std::string formattedColor) { - std::string notifyBody = std::format("You selected the color: {}", hexColor, formattedColor); + std::string notifyBody = std::format("Selected color: {}", hexColor, formattedColor); - std::string notifyBinary = "notify-send"; - std::vector notifyArgs = {"-t", "5000", "-i", "color-select-symbolic", "Color Picker", notifyBody}; - - Hyprutils::OS::CProcess notify(notifyBinary, notifyArgs); + Hyprutils::OS::CProcess notify("notify-send", {"-t", "5000", "-i", "color-select-symbolic", "Color Picker", notifyBody}); notify.runAsync(); } From 682d8f64e2a83ce1db0f82d1421b5df171787a37 Mon Sep 17 00:00:00 2001 From: r3b00thx Date: Sun, 8 Jun 2025 15:37:53 +0300 Subject: [PATCH 12/13] chore(readme): revert readme changes --- README.md | 103 ++++++++++++++---------------------------------------- 1 file changed, 27 insertions(+), 76 deletions(-) diff --git a/README.md b/README.md index 1ef9bd2..c65992b 100644 --- a/README.md +++ b/README.md @@ -1,98 +1,49 @@ -

- Hyprpicker logo -

+# hyprpicker -

- Repo Size - Language - License - Wayland -

+A wlroots-compatible Wayland color picker that does not suck. -

A sleek, wlroots-native color picker for Wayland built for Hyprland with a focus on speed, accuracy, and simplicity.

+![hyprpickerShort](https://user-images.githubusercontent.com/43317083/188224867-7d77a3b3-0a66-488c-8019-39b00060ab42.gif) -

- hyprpicker demo -

+# Usage +Launch it. Click. That's it. +## Options -## ✨ Description +See `hyprpicker --help`. -**Hyprpicker** is a **blazing-fast, minimal, and accurate color picker** built for **Wayland compositors** like **Hyprland**. -It lets you instantly grab any color from your screen with pixel-perfect precision. +# Installation -Hyprpicker is designed to *just work* with clipboard copying, format selection, zoom lens, and desktop notifications. +## Arch +`sudo pacman -S hyprpicker` +## Manual (Building) -## 🚀 Usage +Install dependencies: + - cmake + - pkg-config + - pango + - cairo + - wayland + - wayland-protocols + - hyprutils + - xkbcommon -**Run it, click anywhere, get the color.** -By default, the color is printed to stdout. Combine it with options like clipboard copy or notification for a smoother experience. +Building is done via CMake: ```sh -hyprpicker -a -n -b -f rgb +cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_INSTALL_PREFIX:PATH=/usr -S . -B ./build +cmake --build ./build --config Release --target hyprpicker -j`nproc 2>/dev/null || getconf _NPROCESSORS_CONF` ``` - - -## 🧰 Command-Line Options - -```sh -Hyprpicker usage: hyprpicker [arg [...]]. - -Arguments: - -a | --autocopy | Automatically copies the output to the clipboard (requires wl-clipboard) - -f | --format=fmt | Specifies the output format (cmyk, hex, rgb, hsl, hsv) - -n | --notify | Sends a desktop notification when a color is picked (requires notify-send and a notification daemon like dunst) - -b | --no-fancy | Disables the "fancy" (aka. colored) outputting - -h | --help | Show this help message - -r | --render-inactive | Render (freeze) inactive displays - -z | --no-zoom | Disable the zoom lens - -q | --quiet | Disable most logs (leaves errors) - -v | --verbose | Enable more logs - -t | --no-fractional | Disable fractional scaling support - -d | --disable-preview | Disable live preview of color - -l | --lowercase-hex | Outputs the hexcode in lowercase - -V | --version | Print version info -``` - - - -## 📦 Installation - -```sh -sudo pacman -S hyprpicker -``` - - - -## 🔧 Build From Source - -### Dependencies - -- cmake -- pkg-config -- pango -- cairo -- wayland -- wayland-protocols -- hyprutils -- xkbcommon - - - -### Build and install +Install with: ```sh -cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr -S . -B ./build -cmake --build ./build --config Release --target hyprpicker -j$(nproc) -sudo cmake --install ./build +cmake --install ./build ``` +# Caveats +"Freezes" your displays when picking the color. -## 📚 License - -Hyprpicker is licensed under the BSD 3-Clause License — a permissive license that allows nearly unrestricted use, including commercial, as long as proper credit is given. From 2aa3774b8ab56943a052245c25ad076a06121036 Mon Sep 17 00:00:00 2001 From: r3b00thx Date: Tue, 10 Jun 2025 22:05:06 +0300 Subject: [PATCH 13/13] refactor(readme): update readme file In this commit I updated the readme file to look much nicer and better offering more information regarding HyprPicker and better design overall. --- README.md | 103 ++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 76 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index c65992b..1ef9bd2 100644 --- a/README.md +++ b/README.md @@ -1,49 +1,98 @@ -# hyprpicker +

+ Hyprpicker logo +

-A wlroots-compatible Wayland color picker that does not suck. +

+ Repo Size + Language + License + Wayland +

-![hyprpickerShort](https://user-images.githubusercontent.com/43317083/188224867-7d77a3b3-0a66-488c-8019-39b00060ab42.gif) +

A sleek, wlroots-native color picker for Wayland built for Hyprland with a focus on speed, accuracy, and simplicity.

-# Usage +

+ hyprpicker demo +

-Launch it. Click. That's it. -## Options -See `hyprpicker --help`. +## ✨ Description -# Installation +**Hyprpicker** is a **blazing-fast, minimal, and accurate color picker** built for **Wayland compositors** like **Hyprland**. +It lets you instantly grab any color from your screen with pixel-perfect precision. -## Arch +Hyprpicker is designed to *just work* with clipboard copying, format selection, zoom lens, and desktop notifications. -`sudo pacman -S hyprpicker` -## Manual (Building) -Install dependencies: - - cmake - - pkg-config - - pango - - cairo - - wayland - - wayland-protocols - - hyprutils - - xkbcommon +## 🚀 Usage -Building is done via CMake: +**Run it, click anywhere, get the color.** +By default, the color is printed to stdout. Combine it with options like clipboard copy or notification for a smoother experience. ```sh -cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_INSTALL_PREFIX:PATH=/usr -S . -B ./build -cmake --build ./build --config Release --target hyprpicker -j`nproc 2>/dev/null || getconf _NPROCESSORS_CONF` +hyprpicker -a -n -b -f rgb ``` -Install with: + + +## 🧰 Command-Line Options + +```sh +Hyprpicker usage: hyprpicker [arg [...]]. + +Arguments: + -a | --autocopy | Automatically copies the output to the clipboard (requires wl-clipboard) + -f | --format=fmt | Specifies the output format (cmyk, hex, rgb, hsl, hsv) + -n | --notify | Sends a desktop notification when a color is picked (requires notify-send and a notification daemon like dunst) + -b | --no-fancy | Disables the "fancy" (aka. colored) outputting + -h | --help | Show this help message + -r | --render-inactive | Render (freeze) inactive displays + -z | --no-zoom | Disable the zoom lens + -q | --quiet | Disable most logs (leaves errors) + -v | --verbose | Enable more logs + -t | --no-fractional | Disable fractional scaling support + -d | --disable-preview | Disable live preview of color + -l | --lowercase-hex | Outputs the hexcode in lowercase + -V | --version | Print version info +``` + + + +## 📦 Installation + +```sh +sudo pacman -S hyprpicker +``` + + + +## 🔧 Build From Source + +### Dependencies + +- cmake +- pkg-config +- pango +- cairo +- wayland +- wayland-protocols +- hyprutils +- xkbcommon + + + +### Build and install ```sh -cmake --install ./build +cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr -S . -B ./build +cmake --build ./build --config Release --target hyprpicker -j$(nproc) +sudo cmake --install ./build ``` -# Caveats -"Freezes" your displays when picking the color. +## 📚 License + +Hyprpicker is licensed under the BSD 3-Clause License — a permissive license that allows nearly unrestricted use, including commercial, as long as proper credit is given.