hyprbars: use the new keyword infra

This commit is contained in:
Vaxry 2023-10-29 17:33:32 +00:00
parent e7caa01b4f
commit 17defb17e9
5 changed files with 110 additions and 63 deletions

View file

@ -11,10 +11,13 @@ All config options are in `plugin:hyprbars`:
``` ```
plugin { plugin {
hyprbars { hyprbars {
# config # example config
buttons { bar_height = 20
# button config
} # example buttons (R -> L)
# hyprbars-button = color, size, on-click
hyprbars-button = rgb(ff4040), 10, hyprctl dispatch killactive
hyprbars-button = rgb(eeee11), 10, hyprctl dispatch fullscreen 1
} }
} }
``` ```
@ -31,8 +34,8 @@ plugin {
## Buttons Config ## Buttons Config
`button_size` -> (int) the size of the buttons. Use the `hyprbars-button` keyword.
`col.maximize` -> (col) maximize button color ```ini
hyprbars-button = color, size, on-click
`col.close` -> (col) close button color ```

View file

@ -18,7 +18,7 @@ CHyprBar::CHyprBar(CWindow* pWindow) : IHyprWindowDecoration(pWindow) {
PMONITOR->scheduledRecalc = true; PMONITOR->scheduledRecalc = true;
m_pMouseButtonCallback = HyprlandAPI::registerCallbackDynamic( m_pMouseButtonCallback = HyprlandAPI::registerCallbackDynamic(
PHANDLE, "mouseButton", [&](void* self, SCallbackInfo& info, std::any param) { onMouseDown(std::any_cast<wlr_pointer_button_event*>(param)); }); PHANDLE, "mouseButton", [&](void* self, SCallbackInfo& info, std::any param) { onMouseDown(info, std::any_cast<wlr_pointer_button_event*>(param)); });
m_pMouseMoveCallback = m_pMouseMoveCallback =
HyprlandAPI::registerCallbackDynamic(PHANDLE, "mouseMove", [&](void* self, SCallbackInfo& info, std::any param) { onMouseMove(std::any_cast<Vector2D>(param)); }); HyprlandAPI::registerCallbackDynamic(PHANDLE, "mouseMove", [&](void* self, SCallbackInfo& info, std::any param) { onMouseMove(std::any_cast<Vector2D>(param)); });
@ -38,7 +38,7 @@ SWindowDecorationExtents CHyprBar::getWindowDecorationExtents() {
return m_seExtents; return m_seExtents;
} }
void CHyprBar::onMouseDown(wlr_pointer_button_event* e) { void CHyprBar::onMouseDown(SCallbackInfo& info, wlr_pointer_button_event* e) {
if (m_pWindow != g_pCompositor->m_pLastWindow) if (m_pWindow != g_pCompositor->m_pLastWindow)
return; return;
@ -60,6 +60,12 @@ void CHyprBar::onMouseDown(wlr_pointer_button_event* e) {
} }
if (e->state != WLR_BUTTON_PRESSED) { if (e->state != WLR_BUTTON_PRESSED) {
if (m_bCancelledDown)
info.cancelled = true;
m_bCancelledDown = false;
if (m_bDraggingThis) { if (m_bDraggingThis) {
g_pKeybindManager->m_mDispatchers["mouse"]("0movewindow"); g_pKeybindManager->m_mDispatchers["mouse"]("0movewindow");
m_bDraggingThis = false; m_bDraggingThis = false;
@ -67,27 +73,29 @@ void CHyprBar::onMouseDown(wlr_pointer_button_event* e) {
Debug::log(LOG, "[hyprbars] Dragging ended on {:x}", (uintptr_t)m_pWindow); Debug::log(LOG, "[hyprbars] Dragging ended on {:x}", (uintptr_t)m_pWindow);
} }
m_bDragPending = false;
return; return;
} }
info.cancelled = true;
m_bCancelledDown = true;
// check if on a button // check if on a button
static auto* const PBUTTONSIZE = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hyprbars:buttons:button_size")->intValue;
const auto BARBUF = Vector2D{(int)m_vLastWindowSize.x + 2 * *PBORDERSIZE, *PHEIGHT + *PBORDERSIZE}; float offset = 0;
Vector2D currentPos = Vector2D{BARBUF.x - 2 * BUTTONS_PAD - *PBUTTONSIZE, (BARBUF.y - *PBUTTONSIZE) / 2.0}.floor();
currentPos.x -= BUTTONS_PAD / 2.0; for (auto& b : g_pGlobalState->buttons) {
if (VECINRECT(COORDS, currentPos.x, currentPos.y, currentPos.x + *PBUTTONSIZE + BUTTONS_PAD, currentPos.y + *PBUTTONSIZE)) { const auto BARBUF = Vector2D{(int)m_vLastWindowSize.x + 2 * *PBORDERSIZE, *PHEIGHT + *PBORDERSIZE};
// hit on close Vector2D currentPos = Vector2D{BARBUF.x - 2 * BUTTONS_PAD - b.size - offset, (BARBUF.y - b.size) / 2.0}.floor();
g_pCompositor->closeWindow(m_pWindow);
return;
}
currentPos.x -= BUTTONS_PAD + *PBUTTONSIZE; if (VECINRECT(COORDS, currentPos.x, currentPos.y, currentPos.x + b.size + BUTTONS_PAD, currentPos.y + b.size)) {
if (VECINRECT(COORDS, currentPos.x, currentPos.y, currentPos.x + *PBUTTONSIZE + BUTTONS_PAD, currentPos.y + *PBUTTONSIZE)) { // hit on close
// hit on maximize g_pKeybindManager->m_mDispatchers["exec"](b.cmd);
g_pKeybindManager->m_mDispatchers["fullscreen"]("1"); return;
return; }
offset += BUTTONS_PAD + b.size;
} }
m_bDragPending = true; m_bDragPending = true;
@ -109,19 +117,23 @@ void CHyprBar::renderBarTitle(const Vector2D& bufferSize, const float scale) {
static auto* const PCOLOR = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hyprbars:col.text")->intValue; static auto* const PCOLOR = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hyprbars:col.text")->intValue;
static auto* const PSIZE = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hyprbars:bar_text_size")->intValue; static auto* const PSIZE = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hyprbars:bar_text_size")->intValue;
static auto* const PFONT = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hyprbars:bar_text_font")->strValue; static auto* const PFONT = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hyprbars:bar_text_font")->strValue;
static auto* const PBUTTONSIZE = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hyprbars:buttons:button_size")->intValue;
static auto* const PBORDERSIZE = &HyprlandAPI::getConfigValue(PHANDLE, "general:border_size")->intValue; static auto* const PBORDERSIZE = &HyprlandAPI::getConfigValue(PHANDLE, "general:border_size")->intValue;
const auto scaledSize = *PSIZE * scale; float buttonSizes = 0;
const auto scaledButtonSize = *PBUTTONSIZE * scale; for (auto& b : g_pGlobalState->buttons) {
const auto scaledBorderSize = *PBORDERSIZE * scale; buttonSizes += b.size;
const auto scaledButtonsPad = BUTTONS_PAD * scale; }
const auto scaledBarPadding = BAR_PADDING * scale;
const CColor COLOR = *PCOLOR; const auto scaledSize = *PSIZE * scale;
const auto scaledBorderSize = *PBORDERSIZE * scale;
const auto scaledButtonsSize = buttonSizes * scale;
const auto scaledButtonsPad = BUTTONS_PAD * scale;
const auto scaledBarPadding = BAR_PADDING * scale;
const auto CAIROSURFACE = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, bufferSize.x, bufferSize.y); const CColor COLOR = *PCOLOR;
const auto CAIRO = cairo_create(CAIROSURFACE);
const auto CAIROSURFACE = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, bufferSize.x, bufferSize.y);
const auto CAIRO = cairo_create(CAIROSURFACE);
// clear the pixmap // clear the pixmap
cairo_save(CAIRO); cairo_save(CAIRO);
@ -139,7 +151,7 @@ void CHyprBar::renderBarTitle(const Vector2D& bufferSize, const float scale) {
pango_font_description_free(fontDesc); pango_font_description_free(fontDesc);
const int leftPadding = scaledBorderSize + scaledBarPadding; const int leftPadding = scaledBorderSize + scaledBarPadding;
const int rightPadding = (scaledButtonSize * 2) + (scaledButtonsPad * 3) + scaledBorderSize + scaledBarPadding; const int rightPadding = scaledButtonsSize + (scaledButtonsPad * 3) + scaledBorderSize + scaledBarPadding;
const int maxWidth = bufferSize.x - leftPadding - rightPadding; const int maxWidth = bufferSize.x - leftPadding - rightPadding;
pango_layout_set_width(layout, maxWidth * PANGO_SCALE); pango_layout_set_width(layout, maxWidth * PANGO_SCALE);
@ -179,15 +191,10 @@ void CHyprBar::renderBarTitle(const Vector2D& bufferSize, const float scale) {
} }
void CHyprBar::renderBarButtons(const Vector2D& bufferSize, const float scale) { void CHyprBar::renderBarButtons(const Vector2D& bufferSize, const float scale) {
static auto* const PCLOSECOLOR = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hyprbars:buttons:col.close")->intValue; const auto scaledButtonsPad = BUTTONS_PAD * scale;
static auto* const PMAXCOLOR = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hyprbars:buttons:col.maximize")->intValue;
static auto* const PBUTTONSIZE = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hyprbars:buttons:button_size")->intValue;
const auto scaledButtonSize = *PBUTTONSIZE * scale; const auto CAIROSURFACE = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, bufferSize.x, bufferSize.y);
const auto scaledButtonsPad = BUTTONS_PAD * scale; const auto CAIRO = cairo_create(CAIROSURFACE);
const auto CAIROSURFACE = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, bufferSize.x, bufferSize.y);
const auto CAIRO = cairo_create(CAIROSURFACE);
// clear the pixmap // clear the pixmap
cairo_save(CAIRO); cairo_save(CAIRO);
@ -195,25 +202,28 @@ void CHyprBar::renderBarButtons(const Vector2D& bufferSize, const float scale) {
cairo_paint(CAIRO); cairo_paint(CAIRO);
cairo_restore(CAIRO); cairo_restore(CAIRO);
// draw buttons for close and max // draw buttons
int offset = scaledButtonsPad;
auto drawButton = [&](Vector2D pos, CColor col) -> void { auto drawButton = [&](SHyprButton& pButton) -> void {
const int X = pos.x; const auto scaledButtonSize = pButton.size * scale;
const int Y = pos.y;
const int RADIUS = static_cast<int>(std::ceil(scaledButtonSize / 2.0));
cairo_set_source_rgba(CAIRO, col.r, col.g, col.b, col.a); Vector2D currentPos = Vector2D{bufferSize.x - offset - scaledButtonSize, (bufferSize.y - scaledButtonSize) / 2.0}.floor();
const int X = currentPos.x;
const int Y = currentPos.y;
const int RADIUS = static_cast<int>(std::ceil(scaledButtonSize / 2.0));
cairo_set_source_rgba(CAIRO, pButton.col.r, pButton.col.g, pButton.col.b, pButton.col.a);
cairo_arc(CAIRO, X, Y + RADIUS, RADIUS, 0, 2 * M_PI); cairo_arc(CAIRO, X, Y + RADIUS, RADIUS, 0, 2 * M_PI);
cairo_fill(CAIRO); cairo_fill(CAIRO);
offset += scaledButtonsPad + scaledButtonSize;
}; };
Vector2D currentPos = Vector2D{bufferSize.x - scaledButtonsPad - scaledButtonSize, (bufferSize.y - scaledButtonSize) / 2.0}.floor(); for (auto& b : g_pGlobalState->buttons) {
drawButton(b);
drawButton(currentPos, CColor(*PCLOSECOLOR)); }
currentPos.x -= scaledButtonsPad + scaledButtonSize;
drawButton(currentPos, CColor(*PMAXCOLOR));
// copy the data to an OpenGL texture we have // copy the data to an OpenGL texture we have
const auto DATA = cairo_image_surface_get_data(CAIROSURFACE); const auto DATA = cairo_image_surface_get_data(CAIROSURFACE);

View file

@ -42,7 +42,7 @@ class CHyprBar : public IHyprWindowDecoration {
void renderBarTitle(const Vector2D& bufferSize, const float scale); void renderBarTitle(const Vector2D& bufferSize, const float scale);
void renderBarButtons(const Vector2D& bufferSize, const float scale); void renderBarButtons(const Vector2D& bufferSize, const float scale);
void onMouseDown(wlr_pointer_button_event* e); void onMouseDown(SCallbackInfo& info, wlr_pointer_button_event* e);
void onMouseMove(Vector2D coords); void onMouseMove(Vector2D coords);
HOOK_CALLBACK_FN* m_pMouseButtonCallback; HOOK_CALLBACK_FN* m_pMouseButtonCallback;
@ -50,6 +50,7 @@ class CHyprBar : public IHyprWindowDecoration {
std::string m_szLastTitle; std::string m_szLastTitle;
bool m_bDraggingThis = false; bool m_bDraggingThis = false;
bool m_bDragPending = false; bool m_bDragPending = false;
bool m_bCancelledDown = false;
}; };

View file

@ -2,4 +2,16 @@
#include <hyprland/src/plugins/PluginAPI.hpp> #include <hyprland/src/plugins/PluginAPI.hpp>
inline HANDLE PHANDLE = nullptr; inline HANDLE PHANDLE = nullptr;
struct SHyprButton {
std::string cmd = "";
CColor col = CColor(0, 0, 0, 0);
float size = 10;
};
struct SGlobalState {
std::vector<SHyprButton> buttons;
};
inline std::unique_ptr<SGlobalState> g_pGlobalState;

View file

@ -23,8 +23,29 @@ void onNewWindow(void* self, std::any data) {
HyprlandAPI::addWindowDecoration(PHANDLE, PWINDOW, new CHyprBar(PWINDOW)); HyprlandAPI::addWindowDecoration(PHANDLE, PWINDOW, new CHyprBar(PWINDOW));
} }
void onPreConfigReload() {
g_pGlobalState->buttons.clear();
}
void onNewButton(const std::string& k, const std::string& v) {
CVarList vars(v);
// hyprbars-button = color, size, action
if (vars[0].empty() || vars[1].empty())
return;
float size = 10;
try {
size = std::stof(vars[1]);
} catch (std::exception& e) { return; }
g_pGlobalState->buttons.push_back(SHyprButton{vars[2], configStringToInt(vars[0]), size});
}
APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE handle) { APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE handle) {
PHANDLE = handle; PHANDLE = handle;
g_pGlobalState = std::make_unique<SGlobalState>();
HyprlandAPI::registerCallbackDynamic(PHANDLE, "openWindow", [&](void* self, SCallbackInfo& info, std::any data) { onNewWindow(self, data); }); HyprlandAPI::registerCallbackDynamic(PHANDLE, "openWindow", [&](void* self, SCallbackInfo& info, std::any data) { onNewWindow(self, data); });
@ -33,9 +54,9 @@ APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE handle) {
HyprlandAPI::addConfigValue(PHANDLE, "plugin:hyprbars:col.text", SConfigValue{.intValue = configStringToInt("rgba(ffffffff)")}); HyprlandAPI::addConfigValue(PHANDLE, "plugin:hyprbars:col.text", SConfigValue{.intValue = configStringToInt("rgba(ffffffff)")});
HyprlandAPI::addConfigValue(PHANDLE, "plugin:hyprbars:bar_text_size", SConfigValue{.intValue = 10}); HyprlandAPI::addConfigValue(PHANDLE, "plugin:hyprbars:bar_text_size", SConfigValue{.intValue = 10});
HyprlandAPI::addConfigValue(PHANDLE, "plugin:hyprbars:bar_text_font", SConfigValue{.strValue = "Sans"}); HyprlandAPI::addConfigValue(PHANDLE, "plugin:hyprbars:bar_text_font", SConfigValue{.strValue = "Sans"});
HyprlandAPI::addConfigValue(PHANDLE, "plugin:hyprbars:buttons:col.close", SConfigValue{.intValue = configStringToInt("rgba(cc0000cc)")});
HyprlandAPI::addConfigValue(PHANDLE, "plugin:hyprbars:buttons:col.maximize", SConfigValue{.intValue = configStringToInt("rgba(ffff33cc)")}); HyprlandAPI::addConfigKeyword(PHANDLE, "hyprbars-button", [&](const std::string& k, const std::string& v) { onNewButton(k, v); });
HyprlandAPI::addConfigValue(PHANDLE, "plugin:hyprbars:buttons:button_size", SConfigValue{.intValue = 10}); HyprlandAPI::registerCallbackDynamic(PHANDLE, "preConfigReload", [&](void* self, SCallbackInfo& info, std::any data) { onPreConfigReload(); });
// add deco to existing windows // add deco to existing windows
for (auto& w : g_pCompositor->m_vWindows) { for (auto& w : g_pCompositor->m_vWindows) {