mirror of
https://github.com/hyprwm/hyprland-plugins.git
synced 2026-08-18 02:58:43 +00:00
bars/vkfix/focus: chase hyprland
Chase hyprland changes, fix for lua. Too lazy to do expo and b++ rn.
This commit is contained in:
@ -10,9 +10,16 @@
|
||||
#include <hyprland/src/managers/SeatManager.hpp>
|
||||
#include <hyprland/src/render/Renderer.hpp>
|
||||
#include <hyprland/src/event/EventBus.hpp>
|
||||
#include <hyprland/src/config/values/types/BoolValue.hpp>
|
||||
#include <hyprland/src/config/lua/bindings/LuaBindingsInternal.hpp>
|
||||
|
||||
#include "globals.hpp"
|
||||
|
||||
extern "C" {
|
||||
#include <lua.h>
|
||||
#include <lauxlib.h>
|
||||
}
|
||||
|
||||
#include <hyprutils/string/ConstVarList.hpp>
|
||||
using namespace Hyprutils::String;
|
||||
|
||||
@ -24,6 +31,10 @@ typedef void (*origMotion)(CSeatManager*, uint32_t, const Vector2D&);
|
||||
typedef void (*origSurfaceSize)(CXWaylandSurface*, const CBox&);
|
||||
typedef CRegion (*origWLSurfaceDamage)(Desktop::View::CWLSurface*);
|
||||
|
||||
static struct {
|
||||
SP<Config::Values::CBoolValue> fixMouse;
|
||||
} configValues;
|
||||
|
||||
// Do NOT change this function.
|
||||
APICALL EXPORT std::string PLUGIN_API_VERSION() {
|
||||
return HYPRLAND_API_VERSION;
|
||||
@ -46,8 +57,6 @@ static const SAppConfig* getAppConfig(const std::string& appClass) {
|
||||
}
|
||||
|
||||
void hkNotifyMotion(CSeatManager* thisptr, uint32_t time_msec, const Vector2D& local) {
|
||||
static auto* const PFIX = (Hyprlang::INT* const*)HyprlandAPI::getConfigValue(PHANDLE, "plugin:csgo-vulkan-fix:fix_mouse")->getDataStaticPtr();
|
||||
|
||||
Vector2D newCoords = local;
|
||||
auto focusState = Desktop::focusState();
|
||||
auto window = focusState->window();
|
||||
@ -55,7 +64,7 @@ void hkNotifyMotion(CSeatManager* thisptr, uint32_t time_msec, const Vector2D& l
|
||||
|
||||
const auto CONFIG = window && monitor ? getAppConfig(window->m_initialClass) : nullptr;
|
||||
|
||||
if (**PFIX && CONFIG) {
|
||||
if (configValues.fixMouse->value() && CONFIG) {
|
||||
// fix the coords
|
||||
newCoords.x *= (CONFIG->res.x / monitor->m_size.x) / window->m_X11SurfaceScaledBy;
|
||||
newCoords.y *= (CONFIG->res.y / monitor->m_size.y) / window->m_X11SurfaceScaledBy;
|
||||
@ -109,6 +118,50 @@ CRegion hkWLSurfaceDamage(Desktop::View::CWLSurface* thisptr) {
|
||||
return RG;
|
||||
}
|
||||
|
||||
int vkfixAppLua(lua_State* L) {
|
||||
if (!lua_istable(L, 1))
|
||||
return Config::Lua::Bindings::Internal::configError(L, "vkfix_app: expected a table { app, w, h }");
|
||||
|
||||
SAppConfig config;
|
||||
|
||||
{
|
||||
Hyprutils::Utils::CScopeGuard x([L] { lua_pop(L, 1); });
|
||||
|
||||
lua_getfield(L, 1, "app");
|
||||
|
||||
if (!lua_isstring(L, -1))
|
||||
return Config::Lua::Bindings::Internal::configError(L, "vkfix_app: app must be a class string");
|
||||
|
||||
config.szClass = lua_tostring(L, -1);
|
||||
}
|
||||
|
||||
{
|
||||
Hyprutils::Utils::CScopeGuard x([L] { lua_pop(L, 1); });
|
||||
|
||||
lua_getfield(L, 1, "w");
|
||||
|
||||
if (!lua_isinteger(L, -1))
|
||||
return Config::Lua::Bindings::Internal::configError(L, "vkfix_app: w must be an integer");
|
||||
|
||||
config.res.x = lua_tointeger(L, -1);
|
||||
}
|
||||
|
||||
{
|
||||
Hyprutils::Utils::CScopeGuard x([L] { lua_pop(L, 1); });
|
||||
|
||||
lua_getfield(L, 1, "h");
|
||||
|
||||
if (!lua_isinteger(L, -1))
|
||||
return Config::Lua::Bindings::Internal::configError(L, "vkfix_app: h must be an integer");
|
||||
|
||||
config.res.y = lua_tointeger(L, -1);
|
||||
}
|
||||
|
||||
g_appConfigs.emplace_back(std::move(config));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE handle) {
|
||||
PHANDLE = handle;
|
||||
|
||||
@ -121,47 +174,45 @@ APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE handle) {
|
||||
throw std::runtime_error("[vkfix] Version mismatch");
|
||||
}
|
||||
|
||||
HyprlandAPI::addConfigValue(PHANDLE, "plugin:csgo-vulkan-fix:res_w", Hyprlang::INT{1680});
|
||||
HyprlandAPI::addConfigValue(PHANDLE, "plugin:csgo-vulkan-fix:res_h", Hyprlang::INT{1050});
|
||||
HyprlandAPI::addConfigValue(PHANDLE, "plugin:csgo-vulkan-fix:fix_mouse", Hyprlang::INT{1});
|
||||
HyprlandAPI::addConfigValue(PHANDLE, "plugin:csgo-vulkan-fix:class", Hyprlang::STRING{"cs2"});
|
||||
static auto P = Event::bus()->m_events.config.preReload.listen([&] { g_appConfigs.clear(); });
|
||||
|
||||
static auto P = Event::bus()->m_events.config.preReload.listen([&] {
|
||||
g_appConfigs.clear();
|
||||
if (Config::mgr()->type() == Config::CONFIG_LEGACY) {
|
||||
HyprlandAPI::addConfigKeyword(
|
||||
PHANDLE, "vkfix-app",
|
||||
[](const char* l, const char* r) -> Hyprlang::CParseResult {
|
||||
const std::string str = r;
|
||||
CConstVarList data(str, 0, ',', true);
|
||||
|
||||
static auto* const RESX = (Hyprlang::INT* const*)HyprlandAPI::getConfigValue(PHANDLE, "plugin:csgo-vulkan-fix:res_w")->getDataStaticPtr();
|
||||
static auto* const RESY = (Hyprlang::INT* const*)HyprlandAPI::getConfigValue(PHANDLE, "plugin:csgo-vulkan-fix:res_h")->getDataStaticPtr();
|
||||
static auto* const PCLASS = (Hyprlang::STRING const*)HyprlandAPI::getConfigValue(PHANDLE, "plugin:csgo-vulkan-fix:class")->getDataStaticPtr();
|
||||
Hyprlang::CParseResult result;
|
||||
|
||||
g_appConfigs.emplace_back(SAppConfig{.szClass = *PCLASS, .res = Vector2D{(int)**RESX, (int)**RESY}});
|
||||
});
|
||||
if (data.size() != 3) {
|
||||
result.setError("vkfix-app requires 3 params");
|
||||
return result;
|
||||
}
|
||||
|
||||
HyprlandAPI::addConfigKeyword(
|
||||
PHANDLE, "vkfix-app",
|
||||
[](const char* l, const char* r) -> Hyprlang::CParseResult {
|
||||
const std::string str = r;
|
||||
CConstVarList data(str, 0, ',', true);
|
||||
try {
|
||||
SAppConfig config;
|
||||
config.szClass = data[0];
|
||||
config.res = Vector2D{std::stoi(std::string{data[1]}), std::stoi(std::string{data[2]})};
|
||||
g_appConfigs.emplace_back(std::move(config));
|
||||
} catch (std::exception& e) {
|
||||
result.setError("failed to parse line");
|
||||
return result;
|
||||
}
|
||||
|
||||
Hyprlang::CParseResult result;
|
||||
|
||||
if (data.size() != 3) {
|
||||
result.setError("vkfix-app requires 3 params");
|
||||
return result;
|
||||
}
|
||||
},
|
||||
Hyprlang::SHandlerOptions{});
|
||||
} else if (Config::mgr()->type() == Config::CONFIG_LUA) {
|
||||
HyprlandAPI::addLuaFunction(PHANDLE, "csgo_vulkan_fix", "vkfix_app", ::vkfixAppLua);
|
||||
} else {
|
||||
HyprlandAPI::addNotification(PHANDLE, "[csgo-vulkan-fix] Failure in initialization: Failed to get a valid config manager", CHyprColor{1.0, 0.2, 0.2, 1.0}, 5000);
|
||||
throw std::runtime_error("[vkfix] Config manager bad");
|
||||
}
|
||||
|
||||
try {
|
||||
SAppConfig config;
|
||||
config.szClass = data[0];
|
||||
config.res = Vector2D{std::stoi(std::string{data[1]}), std::stoi(std::string{data[2]})};
|
||||
g_appConfigs.emplace_back(std::move(config));
|
||||
} catch (std::exception& e) {
|
||||
result.setError("failed to parse line");
|
||||
return result;
|
||||
}
|
||||
|
||||
return result;
|
||||
},
|
||||
Hyprlang::SHandlerOptions{});
|
||||
configValues.fixMouse =
|
||||
makeShared<Config::Values::CBoolValue>("plugin:csgo_vulkan_fix:fix_mouse", "Whether to fix the mouse position. A select few apps might be wonky with this.", true);
|
||||
HyprlandAPI::addConfigValueV2(PHANDLE, configValues.fixMouse);
|
||||
|
||||
auto FNS = HyprlandAPI::findFunctionsByName(PHANDLE, "sendPointerMotion");
|
||||
for (auto& fn : FNS) {
|
||||
@ -211,5 +262,5 @@ APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE handle) {
|
||||
}
|
||||
|
||||
APICALL EXPORT void PLUGIN_EXIT() {
|
||||
;
|
||||
configValues = {};
|
||||
}
|
||||
|
||||
@ -1,32 +1,34 @@
|
||||
#include "BarPassElement.hpp"
|
||||
#include <hyprland/src/render/OpenGL.hpp>
|
||||
#include <hyprland/src/render/Renderer.hpp>
|
||||
#include "barDeco.hpp"
|
||||
|
||||
using namespace Render::GL;
|
||||
|
||||
CBarPassElement::CBarPassElement(const CBarPassElement::SBarData& data_) : data(data_) {
|
||||
;
|
||||
}
|
||||
|
||||
void CBarPassElement::draw(const CRegion& damage) {
|
||||
data.deco->renderPass(g_pHyprOpenGL->m_renderData.pMonitor.lock(), data.a);
|
||||
std::vector<UP<IPassElement>> CBarPassElement::draw() {
|
||||
data.deco->renderPass(g_pHyprRenderer->m_renderData.pMonitor.lock(), data.a);
|
||||
return {};
|
||||
}
|
||||
|
||||
bool CBarPassElement::needsLiveBlur() {
|
||||
static auto* const PCOLOR = (Hyprlang::INT* const*)HyprlandAPI::getConfigValue(PHANDLE, "plugin:hyprbars:bar_color")->getDataStaticPtr();
|
||||
static auto* const PENABLEBLUR = (Hyprlang::INT* const*)HyprlandAPI::getConfigValue(PHANDLE, "plugin:hyprbars:bar_blur")->getDataStaticPtr();
|
||||
static auto* const PENABLEBLURGLOBAL = (Hyprlang::INT* const*)HyprlandAPI::getConfigValue(PHANDLE, "decoration:blur:enabled")->getDataStaticPtr();
|
||||
|
||||
CHyprColor color = data.deco->m_bForcedBarColor.value_or(**PCOLOR);
|
||||
CHyprColor color = data.deco->m_bForcedBarColor.value_or(CHyprColor{static_cast<uint64_t>(g_pGlobalState->config.barColor->value())});
|
||||
color.a *= data.a;
|
||||
const bool SHOULDBLUR = **PENABLEBLUR && **PENABLEBLURGLOBAL && color.a < 1.F;
|
||||
const bool SHOULDBLUR = g_pGlobalState->config.barBlur->value() && **PENABLEBLURGLOBAL && color.a < 1.F;
|
||||
|
||||
return SHOULDBLUR;
|
||||
}
|
||||
|
||||
std::optional<CBox> CBarPassElement::boundingBox() {
|
||||
// Temporary fix: expand the bar bb a bit, otherwise occlusion gets too aggressive.
|
||||
return data.deco->assignedBoxGlobal().translate(-g_pHyprOpenGL->m_renderData.pMonitor->m_position).expand(10);
|
||||
return data.deco->assignedBoxGlobal().translate(-g_pHyprRenderer->m_renderData.pMonitor->m_position).expand(10);
|
||||
}
|
||||
|
||||
bool CBarPassElement::needsPrecomputeBlur() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -13,15 +13,19 @@ class CBarPassElement : public IPassElement {
|
||||
CBarPassElement(const SBarData& data_);
|
||||
virtual ~CBarPassElement() = default;
|
||||
|
||||
virtual void draw(const CRegion& damage);
|
||||
virtual bool needsLiveBlur();
|
||||
virtual bool needsPrecomputeBlur();
|
||||
virtual std::optional<CBox> boundingBox();
|
||||
virtual std::vector<UP<IPassElement>> draw() override;
|
||||
virtual bool needsLiveBlur() override;
|
||||
virtual bool needsPrecomputeBlur() override;
|
||||
virtual std::optional<CBox> boundingBox() override;
|
||||
|
||||
virtual const char* passName() {
|
||||
virtual const char* passName() override {
|
||||
return "CBarPassElement";
|
||||
}
|
||||
|
||||
virtual ePassElementType type() override {
|
||||
return EK_CUSTOM;
|
||||
}
|
||||
|
||||
private:
|
||||
SBarData data;
|
||||
};
|
||||
@ -17,7 +17,6 @@ pkg_check_modules(deps REQUIRED IMPORTED_TARGET
|
||||
libdrm
|
||||
libinput
|
||||
libudev
|
||||
pangocairo
|
||||
pixman-1
|
||||
wayland-server
|
||||
xkbcommon
|
||||
|
||||
@ -7,8 +7,8 @@ endif
|
||||
|
||||
CXXFLAGS ?= -O2
|
||||
CXXFLAGS += -shared -fPIC -std=c++2b -Wno-c++11-narrowing
|
||||
INCLUDES = `pkg-config --cflags pixman-1 libdrm hyprland pangocairo libinput libudev wayland-server xkbcommon`
|
||||
LIBS = `pkg-config --libs pangocairo`
|
||||
INCLUDES = `pkg-config --cflags pixman-1 libdrm hyprland libinput libudev wayland-server xkbcommon`
|
||||
LIBS =
|
||||
|
||||
SRC = main.cpp barDeco.cpp BarPassElement.cpp
|
||||
TARGET = hyprbars.so
|
||||
|
||||
@ -8,21 +8,28 @@
|
||||
#include <hyprland/src/managers/input/InputManager.hpp>
|
||||
#include <hyprland/src/render/Renderer.hpp>
|
||||
#include <hyprland/src/config/ConfigManager.hpp>
|
||||
#include <hyprland/src/config/shared/animation/AnimationTree.hpp>
|
||||
#include <hyprland/src/config/supplementary/executor/Executor.hpp>
|
||||
#include <hyprland/src/config/shared/actions/ConfigActions.hpp>
|
||||
#include <hyprland/src/managers/animation/AnimationManager.hpp>
|
||||
#include <hyprland/src/protocols/LayerShell.hpp>
|
||||
#include <hyprland/src/event/EventBus.hpp>
|
||||
#include <hyprland/src/layout/LayoutManager.hpp>
|
||||
#include <pango/pangocairo.h>
|
||||
#include <hyprland/src/render/OpenGL.hpp>
|
||||
|
||||
#include "globals.hpp"
|
||||
#include "BarPassElement.hpp"
|
||||
|
||||
using namespace Render::GL;
|
||||
|
||||
static CHyprColor configColor(Config::INTEGER color) {
|
||||
return CHyprColor{static_cast<uint64_t>(color)};
|
||||
}
|
||||
|
||||
CHyprBar::CHyprBar(PHLWINDOW pWindow) : IHyprWindowDecoration(pWindow) {
|
||||
m_pWindow = pWindow;
|
||||
|
||||
static auto* const PCOLOR = (Hyprlang::INT* const*)HyprlandAPI::getConfigValue(PHANDLE, "plugin:hyprbars:bar_color")->getDataStaticPtr();
|
||||
|
||||
const auto PMONITOR = pWindow->m_monitor.lock();
|
||||
const auto PMONITOR = pWindow->m_monitor.lock();
|
||||
PMONITOR->m_scheduledRecalc = true;
|
||||
|
||||
// button events
|
||||
@ -34,10 +41,8 @@ CHyprBar::CHyprBar(PHLWINDOW pWindow) : IHyprWindowDecoration(pWindow) {
|
||||
m_pTouchMoveCallback = Event::bus()->m_events.input.touch.motion.listen([&](ITouch::SMotionEvent e, Event::SCallbackInfo& info) { onTouchMove(info, e); });
|
||||
m_pMouseMoveCallback = Event::bus()->m_events.input.mouse.move.listen([&](Vector2D c, Event::SCallbackInfo& info) { onMouseMove(c); });
|
||||
|
||||
m_pTextTex = makeShared<CTexture>();
|
||||
m_pButtonsTex = makeShared<CTexture>();
|
||||
|
||||
g_pAnimationManager->createAnimation(CHyprColor{**PCOLOR}, m_cRealBarColor, g_pConfigManager->getAnimationPropertyConfig("border"), pWindow, AVARDAMAGE_NONE);
|
||||
g_pAnimationManager->createAnimation(configColor(g_pGlobalState->config.barColor->value()), m_cRealBarColor, Config::animationTree()->getAnimationPropertyConfig("border"),
|
||||
pWindow, AVARDAMAGE_NONE);
|
||||
m_cRealBarColor->setUpdateCallback([&](auto) { damageEntire(); });
|
||||
}
|
||||
|
||||
@ -46,16 +51,16 @@ CHyprBar::~CHyprBar() {
|
||||
}
|
||||
|
||||
SDecorationPositioningInfo CHyprBar::getPositioningInfo() {
|
||||
static auto* const PHEIGHT = (Hyprlang::INT* const*)HyprlandAPI::getConfigValue(PHANDLE, "plugin:hyprbars:bar_height")->getDataStaticPtr();
|
||||
static auto* const PENABLED = (Hyprlang::INT* const*)HyprlandAPI::getConfigValue(PHANDLE, "plugin:hyprbars:enabled")->getDataStaticPtr();
|
||||
static auto* const PPRECEDENCE = (Hyprlang::INT* const*)HyprlandAPI::getConfigValue(PHANDLE, "plugin:hyprbars:bar_precedence_over_border")->getDataStaticPtr();
|
||||
const auto HEIGHT = g_pGlobalState->config.barHeight->value();
|
||||
const auto ENABLED = g_pGlobalState->config.enabled->value();
|
||||
const auto PRECEDENCE = g_pGlobalState->config.barPrecedenceOverBorder->value();
|
||||
|
||||
SDecorationPositioningInfo info;
|
||||
info.policy = m_hidden ? DECORATION_POSITION_ABSOLUTE : DECORATION_POSITION_STICKY;
|
||||
info.edges = DECORATION_EDGE_TOP;
|
||||
info.priority = **PPRECEDENCE ? 10005 : 5000;
|
||||
info.priority = PRECEDENCE ? 10005 : 5000;
|
||||
info.reserved = true;
|
||||
info.desiredExtents = {{0, m_hidden || !**PENABLED ? 0 : **PHEIGHT}, {0, 0}};
|
||||
info.desiredExtents = {{0, m_hidden || !ENABLED ? 0 : HEIGHT}, {0, 0}};
|
||||
return info;
|
||||
}
|
||||
|
||||
@ -71,9 +76,7 @@ std::string CHyprBar::getDisplayName() {
|
||||
}
|
||||
|
||||
bool CHyprBar::inputIsValid() {
|
||||
static auto* const PENABLED = (Hyprlang::INT* const*)HyprlandAPI::getConfigValue(PHANDLE, "plugin:hyprbars:enabled")->getDataStaticPtr();
|
||||
|
||||
if (!**PENABLED)
|
||||
if (!g_pGlobalState->config.enabled->value())
|
||||
return false;
|
||||
|
||||
if (!m_pWindow->m_workspace || !m_pWindow->m_workspace->isVisible() || !g_pInputManager->m_exclusiveLSes.empty() ||
|
||||
@ -139,8 +142,7 @@ void CHyprBar::onTouchUp(Event::SCallbackInfo& info, ITouch::SUpEvent e) {
|
||||
|
||||
void CHyprBar::onMouseMove(Vector2D coords) {
|
||||
// ensure proper redraws of button icons on hover when using hardware cursors
|
||||
static auto* const PICONONHOVER = (Hyprlang::INT* const*)HyprlandAPI::getConfigValue(PHANDLE, "plugin:hyprbars:icon_on_hover")->getDataStaticPtr();
|
||||
if (**PICONONHOVER)
|
||||
if (g_pGlobalState->config.iconOnHover->value())
|
||||
damageOnButtonHover();
|
||||
|
||||
if (!m_bDragPending || m_bTouchEv || !validMapped(m_pWindow) || m_touchId != 0)
|
||||
@ -184,16 +186,15 @@ void CHyprBar::handleDownEvent(Event::SCallbackInfo& info, std::optional<ITouch:
|
||||
COORDS = Vector2D(PMONITOR->m_position.x + e.pos.x * PMONITOR->m_size.x, PMONITOR->m_position.y + e.pos.y * PMONITOR->m_size.y) - assignedBoxGlobal().pos();
|
||||
}
|
||||
|
||||
static auto* const PHEIGHT = (Hyprlang::INT* const*)HyprlandAPI::getConfigValue(PHANDLE, "plugin:hyprbars:bar_height")->getDataStaticPtr();
|
||||
static auto* const PBARBUTTONPADDING = (Hyprlang::INT* const*)HyprlandAPI::getConfigValue(PHANDLE, "plugin:hyprbars:bar_button_padding")->getDataStaticPtr();
|
||||
static auto* const PBARPADDING = (Hyprlang::INT* const*)HyprlandAPI::getConfigValue(PHANDLE, "plugin:hyprbars:bar_padding")->getDataStaticPtr();
|
||||
static auto* const PALIGNBUTTONS = (Hyprlang::STRING const*)HyprlandAPI::getConfigValue(PHANDLE, "plugin:hyprbars:bar_buttons_alignment")->getDataStaticPtr();
|
||||
static auto* const PONDOUBLECLICK = (Hyprlang::STRING const*)HyprlandAPI::getConfigValue(PHANDLE, "plugin:hyprbars:on_double_click")->getDataStaticPtr();
|
||||
const auto HEIGHT = g_pGlobalState->config.barHeight->value();
|
||||
const auto BARBUTTONPADDING = g_pGlobalState->config.barButtonPadding->value();
|
||||
const auto BARPADDING = g_pGlobalState->config.barPadding->value();
|
||||
const auto ALIGNBUTTONS = g_pGlobalState->config.barButtonsAlignment->value();
|
||||
const auto ON_DOUBLE_CLICK = g_pGlobalState->config.onDoubleClick->value();
|
||||
|
||||
const bool BUTTONSRIGHT = std::string{*PALIGNBUTTONS} != "left";
|
||||
const std::string ON_DOUBLE_CLICK = *PONDOUBLECLICK;
|
||||
const bool BUTTONSRIGHT = ALIGNBUTTONS != "left";
|
||||
|
||||
if (!VECINRECT(COORDS, 0, 0, assignedBoxGlobal().w, **PHEIGHT - 1)) {
|
||||
if (!VECINRECT(COORDS, 0, 0, assignedBoxGlobal().w, HEIGHT - 1)) {
|
||||
|
||||
if (m_bDraggingThis) {
|
||||
if (m_bTouchEv)
|
||||
@ -217,12 +218,12 @@ void CHyprBar::handleDownEvent(Event::SCallbackInfo& info, std::optional<ITouch:
|
||||
info.cancelled = true;
|
||||
m_bCancelledDown = true;
|
||||
|
||||
if (doButtonPress(PBARPADDING, PBARBUTTONPADDING, PHEIGHT, COORDS, BUTTONSRIGHT))
|
||||
if (doButtonPress(BARPADDING, BARBUTTONPADDING, HEIGHT, COORDS, BUTTONSRIGHT))
|
||||
return;
|
||||
|
||||
if (!ON_DOUBLE_CLICK.empty() &&
|
||||
std::chrono::duration_cast<std::chrono::milliseconds>(Time::steadyNow() - m_lastMouseDown).count() < 400 /* Arbitrary delay I found suitable */) {
|
||||
g_pKeybindManager->m_dispatchers["exec"](ON_DOUBLE_CLICK);
|
||||
Config::Supplementary::executor()->spawn(ON_DOUBLE_CLICK);
|
||||
m_bDragPending = false;
|
||||
} else {
|
||||
m_lastMouseDown = Time::steadyNow();
|
||||
@ -240,10 +241,10 @@ void CHyprBar::handleUpEvent(Event::SCallbackInfo& info) {
|
||||
m_bCancelledDown = false;
|
||||
|
||||
if (m_bDraggingThis) {
|
||||
g_pKeybindManager->m_dispatchers["mouse"]("0movewindow");
|
||||
g_pKeybindManager->changeMouseBindMode(MBIND_INVALID);
|
||||
m_bDraggingThis = false;
|
||||
if (m_bTouchEv)
|
||||
g_pKeybindManager->m_dispatchers["settiled"]("activewindow");
|
||||
Config::Actions::floatWindow(Config::Actions::eTogglableAction::TOGGLE_ACTION_DISABLE);
|
||||
|
||||
Log::logger->log(Log::DEBUG, "[hyprbars] Dragging ended on {:x}", (uintptr_t)m_pWindow.lock().get());
|
||||
}
|
||||
@ -254,187 +255,65 @@ void CHyprBar::handleUpEvent(Event::SCallbackInfo& info) {
|
||||
}
|
||||
|
||||
void CHyprBar::handleMovement() {
|
||||
g_pKeybindManager->m_dispatchers["mouse"]("1movewindow");
|
||||
g_pKeybindManager->changeMouseBindMode(MBIND_MOVE);
|
||||
m_bDraggingThis = true;
|
||||
Log::logger->log(Log::DEBUG, "[hyprbars] Dragging initiated on {:x}", (uintptr_t)m_pWindow.lock().get());
|
||||
return;
|
||||
}
|
||||
|
||||
bool CHyprBar::doButtonPress(Hyprlang::INT* const* PBARPADDING, Hyprlang::INT* const* PBARBUTTONPADDING, Hyprlang::INT* const* PHEIGHT, Vector2D COORDS, const bool BUTTONSRIGHT) {
|
||||
bool CHyprBar::doButtonPress(Config::INTEGER barPadding, Config::INTEGER barButtonPadding, Config::INTEGER barHeight, Vector2D COORDS, const bool BUTTONSRIGHT) {
|
||||
//check if on a button
|
||||
float offset = **PBARPADDING;
|
||||
float offset = barPadding;
|
||||
|
||||
for (auto& b : g_pGlobalState->buttons) {
|
||||
const auto BARBUF = Vector2D{(int)assignedBoxGlobal().w, **PHEIGHT};
|
||||
Vector2D currentPos = Vector2D{(BUTTONSRIGHT ? BARBUF.x - **PBARBUTTONPADDING - b.size - offset : offset), (BARBUF.y - b.size) / 2.0}.floor();
|
||||
const auto BARBUF = Vector2D{(int)assignedBoxGlobal().w, barHeight};
|
||||
Vector2D currentPos = Vector2D{(BUTTONSRIGHT ? BARBUF.x - barButtonPadding - b.size - offset : offset), (BARBUF.y - b.size) / 2.0}.floor();
|
||||
|
||||
if (VECINRECT(COORDS, currentPos.x, currentPos.y, currentPos.x + b.size + **PBARBUTTONPADDING, currentPos.y + b.size)) {
|
||||
if (VECINRECT(COORDS, currentPos.x, currentPos.y, currentPos.x + b.size + barButtonPadding, currentPos.y + b.size)) {
|
||||
// hit on close
|
||||
g_pKeybindManager->m_dispatchers["exec"](b.cmd);
|
||||
return true;
|
||||
}
|
||||
|
||||
offset += **PBARBUTTONPADDING + b.size;
|
||||
offset += barButtonPadding + b.size;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void CHyprBar::renderText(SP<CTexture> out, const std::string& text, const CHyprColor& color, const Vector2D& bufferSize, const float scale, const int fontSize) {
|
||||
const auto CAIROSURFACE = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, bufferSize.x, bufferSize.y);
|
||||
const auto CAIRO = cairo_create(CAIROSURFACE);
|
||||
|
||||
// clear the pixmap
|
||||
cairo_save(CAIRO);
|
||||
cairo_set_operator(CAIRO, CAIRO_OPERATOR_CLEAR);
|
||||
cairo_paint(CAIRO);
|
||||
cairo_restore(CAIRO);
|
||||
|
||||
// draw title using Pango
|
||||
PangoLayout* layout = pango_cairo_create_layout(CAIRO);
|
||||
pango_layout_set_text(layout, text.c_str(), -1);
|
||||
|
||||
PangoFontDescription* fontDesc = pango_font_description_from_string("sans");
|
||||
pango_font_description_set_size(fontDesc, fontSize * scale * PANGO_SCALE);
|
||||
pango_layout_set_font_description(layout, fontDesc);
|
||||
pango_font_description_free(fontDesc);
|
||||
|
||||
const int maxWidth = bufferSize.x;
|
||||
|
||||
pango_layout_set_width(layout, maxWidth * PANGO_SCALE);
|
||||
pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_NONE);
|
||||
|
||||
cairo_set_source_rgba(CAIRO, color.r, color.g, color.b, color.a);
|
||||
|
||||
PangoRectangle ink_rect, logical_rect;
|
||||
pango_layout_get_extents(layout, &ink_rect, &logical_rect);
|
||||
|
||||
const int layoutWidth = ink_rect.width;
|
||||
const int layoutHeight = logical_rect.height;
|
||||
|
||||
const double xOffset = (bufferSize.x / 2.0 - layoutWidth / PANGO_SCALE / 2.0);
|
||||
const double yOffset = (bufferSize.y / 2.0 - layoutHeight / PANGO_SCALE / 2.0);
|
||||
|
||||
cairo_move_to(CAIRO, xOffset, yOffset);
|
||||
pango_cairo_show_layout(CAIRO, layout);
|
||||
|
||||
g_object_unref(layout);
|
||||
|
||||
cairo_surface_flush(CAIROSURFACE);
|
||||
|
||||
// copy the data to an OpenGL texture we have
|
||||
const auto DATA = cairo_image_surface_get_data(CAIROSURFACE);
|
||||
out->allocate();
|
||||
glBindTexture(GL_TEXTURE_2D, out->m_texID);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
|
||||
#ifndef GLES2
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_BLUE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED);
|
||||
#endif
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bufferSize.x, bufferSize.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, DATA);
|
||||
|
||||
// delete cairo
|
||||
cairo_destroy(CAIRO);
|
||||
cairo_surface_destroy(CAIROSURFACE);
|
||||
}
|
||||
|
||||
void CHyprBar::renderBarTitle(const Vector2D& bufferSize, const float scale) {
|
||||
static auto* const PCOLOR = (Hyprlang::INT* const*)HyprlandAPI::getConfigValue(PHANDLE, "plugin:hyprbars:col.text")->getDataStaticPtr();
|
||||
static auto* const PSIZE = (Hyprlang::INT* const*)HyprlandAPI::getConfigValue(PHANDLE, "plugin:hyprbars:bar_text_size")->getDataStaticPtr();
|
||||
static auto* const PFONT = (Hyprlang::STRING const*)HyprlandAPI::getConfigValue(PHANDLE, "plugin:hyprbars:bar_text_font")->getDataStaticPtr();
|
||||
static auto* const PALIGN = (Hyprlang::STRING const*)HyprlandAPI::getConfigValue(PHANDLE, "plugin:hyprbars:bar_text_align")->getDataStaticPtr();
|
||||
static auto* const PALIGNBUTTONS = (Hyprlang::STRING const*)HyprlandAPI::getConfigValue(PHANDLE, "plugin:hyprbars:bar_buttons_alignment")->getDataStaticPtr();
|
||||
static auto* const PBARPADDING = (Hyprlang::INT* const*)HyprlandAPI::getConfigValue(PHANDLE, "plugin:hyprbars:bar_padding")->getDataStaticPtr();
|
||||
static auto* const PBARBUTTONPADDING = (Hyprlang::INT* const*)HyprlandAPI::getConfigValue(PHANDLE, "plugin:hyprbars:bar_button_padding")->getDataStaticPtr();
|
||||
const auto COLORVAL = g_pGlobalState->config.textColor->value();
|
||||
const auto SIZE = g_pGlobalState->config.barTextSize->value();
|
||||
const auto FONT = g_pGlobalState->config.barTextFont->value();
|
||||
const auto ALIGN = g_pGlobalState->config.barTextAlign->value();
|
||||
const auto BARPADDING = g_pGlobalState->config.barPadding->value();
|
||||
const auto BARBUTTONPADDING = g_pGlobalState->config.barButtonPadding->value();
|
||||
|
||||
const bool BUTTONSRIGHT = std::string{*PALIGNBUTTONS} != "left";
|
||||
|
||||
const auto PWINDOW = m_pWindow.lock();
|
||||
|
||||
const auto BORDERSIZE = PWINDOW->getRealBorderSize();
|
||||
|
||||
float buttonSizes = **PBARBUTTONPADDING;
|
||||
float buttonSizes = BARBUTTONPADDING;
|
||||
for (auto& b : g_pGlobalState->buttons) {
|
||||
buttonSizes += b.size + **PBARBUTTONPADDING;
|
||||
buttonSizes += b.size + BARBUTTONPADDING;
|
||||
}
|
||||
|
||||
const auto scaledSize = **PSIZE * scale;
|
||||
const auto scaledBorderSize = BORDERSIZE * scale;
|
||||
const auto scaledButtonsSize = buttonSizes * scale;
|
||||
const auto scaledButtonsPad = **PBARBUTTONPADDING * scale;
|
||||
const auto scaledBarPadding = **PBARPADDING * scale;
|
||||
const int scaledSize = std::round(SIZE * scale);
|
||||
const auto scaledButtonsSize = buttonSizes * scale;
|
||||
const auto scaledBarPadding = BARPADDING * scale;
|
||||
const int paddingTotal = scaledBarPadding * 2 + scaledButtonsSize + (ALIGN != "left" ? scaledButtonsSize : 0);
|
||||
const int maxWidth = std::clamp(static_cast<int>(bufferSize.x - paddingTotal), 0, INT_MAX);
|
||||
|
||||
const CHyprColor COLOR = m_bForcedTitleColor.value_or(**PCOLOR);
|
||||
if (m_szLastTitle.empty() || maxWidth < 1) {
|
||||
m_pTextTex = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
const auto CAIROSURFACE = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, bufferSize.x, bufferSize.y);
|
||||
const auto CAIRO = cairo_create(CAIROSURFACE);
|
||||
|
||||
// clear the pixmap
|
||||
cairo_save(CAIRO);
|
||||
cairo_set_operator(CAIRO, CAIRO_OPERATOR_CLEAR);
|
||||
cairo_paint(CAIRO);
|
||||
cairo_restore(CAIRO);
|
||||
|
||||
// draw title using Pango
|
||||
PangoLayout* layout = pango_cairo_create_layout(CAIRO);
|
||||
pango_layout_set_text(layout, m_szLastTitle.c_str(), -1);
|
||||
|
||||
PangoFontDescription* fontDesc = pango_font_description_from_string(*PFONT);
|
||||
pango_font_description_set_size(fontDesc, scaledSize * PANGO_SCALE);
|
||||
pango_layout_set_font_description(layout, fontDesc);
|
||||
pango_font_description_free(fontDesc);
|
||||
|
||||
PangoContext* context = pango_layout_get_context(layout);
|
||||
pango_context_set_base_dir(context, PANGO_DIRECTION_NEUTRAL);
|
||||
|
||||
const int paddingTotal = scaledBarPadding * 2 + scaledButtonsSize + (std::string{*PALIGN} != "left" ? scaledButtonsSize : 0);
|
||||
const int maxWidth = std::clamp(static_cast<int>(bufferSize.x - paddingTotal), 0, INT_MAX);
|
||||
|
||||
pango_layout_set_width(layout, maxWidth * PANGO_SCALE);
|
||||
pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END);
|
||||
|
||||
cairo_set_source_rgba(CAIRO, COLOR.r, COLOR.g, COLOR.b, COLOR.a);
|
||||
|
||||
int layoutWidth, layoutHeight;
|
||||
pango_layout_get_size(layout, &layoutWidth, &layoutHeight);
|
||||
const int xOffset = std::string{*PALIGN} == "left" ? std::round(scaledBarPadding + (BUTTONSRIGHT ? 0 : scaledButtonsSize)) :
|
||||
std::round(((bufferSize.x - scaledBorderSize) / 2.0 - layoutWidth / PANGO_SCALE / 2.0));
|
||||
const int yOffset = std::round((bufferSize.y / 2.0 - layoutHeight / PANGO_SCALE / 2.0));
|
||||
|
||||
cairo_move_to(CAIRO, xOffset, yOffset);
|
||||
pango_cairo_show_layout(CAIRO, layout);
|
||||
|
||||
g_object_unref(layout);
|
||||
|
||||
cairo_surface_flush(CAIROSURFACE);
|
||||
|
||||
// copy the data to an OpenGL texture we have
|
||||
const auto DATA = cairo_image_surface_get_data(CAIROSURFACE);
|
||||
m_pTextTex->allocate();
|
||||
glBindTexture(GL_TEXTURE_2D, m_pTextTex->m_texID);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
|
||||
#ifndef GLES2
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_BLUE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED);
|
||||
#endif
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bufferSize.x, bufferSize.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, DATA);
|
||||
|
||||
// delete cairo
|
||||
cairo_destroy(CAIRO);
|
||||
cairo_surface_destroy(CAIROSURFACE);
|
||||
const CHyprColor COLOR = m_bForcedTitleColor.value_or(configColor(COLORVAL));
|
||||
m_pTextTex = g_pHyprRenderer->renderText(m_szLastTitle, COLOR, scaledSize, false, FONT, maxWidth);
|
||||
}
|
||||
|
||||
size_t CHyprBar::getVisibleButtonCount(Hyprlang::INT* const* PBARBUTTONPADDING, Hyprlang::INT* const* PBARPADDING, const Vector2D& bufferSize, const float scale) {
|
||||
float availableSpace = bufferSize.x - **PBARPADDING * scale * 2;
|
||||
size_t CHyprBar::getVisibleButtonCount(Config::INTEGER barButtonPadding, Config::INTEGER barPadding, const Vector2D& bufferSize, const float scale) {
|
||||
float availableSpace = bufferSize.x - barPadding * scale * 2;
|
||||
size_t count = 0;
|
||||
|
||||
for (const auto& button : g_pGlobalState->buttons) {
|
||||
const float buttonSpace = (button.size + **PBARBUTTONPADDING) * scale;
|
||||
const float buttonSpace = (button.size + barButtonPadding) * scale;
|
||||
if (availableSpace >= buttonSpace) {
|
||||
count++;
|
||||
availableSpace -= buttonSpace;
|
||||
@ -445,106 +324,82 @@ size_t CHyprBar::getVisibleButtonCount(Hyprlang::INT* const* PBARBUTTONPADDING,
|
||||
return count;
|
||||
}
|
||||
|
||||
void CHyprBar::renderBarButtons(const Vector2D& bufferSize, const float scale) {
|
||||
static auto* const PBARBUTTONPADDING = (Hyprlang::INT* const*)HyprlandAPI::getConfigValue(PHANDLE, "plugin:hyprbars:bar_button_padding")->getDataStaticPtr();
|
||||
static auto* const PBARPADDING = (Hyprlang::INT* const*)HyprlandAPI::getConfigValue(PHANDLE, "plugin:hyprbars:bar_padding")->getDataStaticPtr();
|
||||
static auto* const PALIGNBUTTONS = (Hyprlang::STRING const*)HyprlandAPI::getConfigValue(PHANDLE, "plugin:hyprbars:bar_buttons_alignment")->getDataStaticPtr();
|
||||
static auto* const PINACTIVECOLOR = (Hyprlang::INT* const*)HyprlandAPI::getConfigValue(PHANDLE, "plugin:hyprbars:inactive_button_color")->getDataStaticPtr();
|
||||
void CHyprBar::renderBarButtons(CBox* barBox, const float scale, const float a) {
|
||||
const auto BARBUTTONPADDING = g_pGlobalState->config.barButtonPadding->value();
|
||||
const auto BARPADDING = g_pGlobalState->config.barPadding->value();
|
||||
const auto ALIGNBUTTONS = g_pGlobalState->config.barButtonsAlignment->value();
|
||||
const auto INACTIVECOLOR = g_pGlobalState->config.inactiveButtonColor->value();
|
||||
|
||||
const bool BUTTONSRIGHT = std::string{*PALIGNBUTTONS} != "left";
|
||||
const auto visibleCount = getVisibleButtonCount(PBARBUTTONPADDING, PBARPADDING, bufferSize, scale);
|
||||
const bool BUTTONSRIGHT = ALIGNBUTTONS != "left";
|
||||
const auto visibleCount = getVisibleButtonCount(BARBUTTONPADDING, BARPADDING, Vector2D{barBox->w, barBox->h}, scale);
|
||||
const bool INVALIDATEICONS = m_bButtonsDirty || m_bWindowSizeChanged;
|
||||
|
||||
const auto CAIROSURFACE = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, bufferSize.x, bufferSize.y);
|
||||
const auto CAIRO = cairo_create(CAIROSURFACE);
|
||||
|
||||
// clear the pixmap
|
||||
cairo_save(CAIRO);
|
||||
cairo_set_operator(CAIRO, CAIRO_OPERATOR_CLEAR);
|
||||
cairo_paint(CAIRO);
|
||||
cairo_restore(CAIRO);
|
||||
|
||||
// draw buttons
|
||||
int offset = **PBARPADDING * scale;
|
||||
int offset = BARPADDING * scale;
|
||||
for (size_t i = 0; i < visibleCount; ++i) {
|
||||
const auto& button = g_pGlobalState->buttons[i];
|
||||
const auto scaledButtonSize = button.size * scale;
|
||||
const auto scaledButtonsPad = **PBARBUTTONPADDING * scale;
|
||||
auto& button = g_pGlobalState->buttons[i];
|
||||
const auto scaledButtonSize = button.size * scale;
|
||||
const auto scaledButtonsPad = BARBUTTONPADDING * scale;
|
||||
|
||||
const auto pos = Vector2D{BUTTONSRIGHT ? bufferSize.x - offset - scaledButtonSize / 2.0 : offset + scaledButtonSize / 2.0, bufferSize.y / 2.0}.floor();
|
||||
auto color = button.bgcol;
|
||||
auto color = button.bgcol;
|
||||
|
||||
if (**PINACTIVECOLOR > 0) {
|
||||
color = m_bWindowHasFocus ? color : CHyprColor(**PINACTIVECOLOR);
|
||||
if (button.userfg && button.iconTex->m_texID != 0)
|
||||
button.iconTex->destroyTexture();
|
||||
if (INACTIVECOLOR > 0) {
|
||||
color = m_bWindowHasFocus ? color : configColor(INACTIVECOLOR);
|
||||
if (INVALIDATEICONS && button.userfg && button.iconTex)
|
||||
button.iconTex = nullptr;
|
||||
}
|
||||
|
||||
cairo_set_source_rgba(CAIRO, color.r, color.g, color.b, color.a);
|
||||
cairo_arc(CAIRO, pos.x, pos.y, scaledButtonSize / 2, 0, 2 * M_PI);
|
||||
cairo_fill(CAIRO);
|
||||
color.a *= a;
|
||||
|
||||
CBox buttonBox = {barBox->x + (BUTTONSRIGHT ? barBox->w - offset - scaledButtonSize : offset), barBox->y + (barBox->h - scaledButtonSize) / 2.0, scaledButtonSize,
|
||||
scaledButtonSize};
|
||||
buttonBox.round();
|
||||
|
||||
g_pHyprOpenGL->renderRect(buttonBox, color, {.round = static_cast<int>(std::round(scaledButtonSize / 2.0)), .roundingPower = 2.F});
|
||||
|
||||
offset += scaledButtonsPad + scaledButtonSize;
|
||||
}
|
||||
|
||||
// copy the data to an OpenGL texture we have
|
||||
const auto DATA = cairo_image_surface_get_data(CAIROSURFACE);
|
||||
m_pButtonsTex->allocate();
|
||||
glBindTexture(GL_TEXTURE_2D, m_pButtonsTex->m_texID);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
|
||||
#ifndef GLES2
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_BLUE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED);
|
||||
#endif
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bufferSize.x, bufferSize.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, DATA);
|
||||
|
||||
// delete cairo
|
||||
cairo_destroy(CAIRO);
|
||||
cairo_surface_destroy(CAIROSURFACE);
|
||||
}
|
||||
|
||||
void CHyprBar::renderBarButtonsText(CBox* barBox, const float scale, const float a) {
|
||||
static auto* const PHEIGHT = (Hyprlang::INT* const*)HyprlandAPI::getConfigValue(PHANDLE, "plugin:hyprbars:bar_height")->getDataStaticPtr();
|
||||
static auto* const PBARBUTTONPADDING = (Hyprlang::INT* const*)HyprlandAPI::getConfigValue(PHANDLE, "plugin:hyprbars:bar_button_padding")->getDataStaticPtr();
|
||||
static auto* const PBARPADDING = (Hyprlang::INT* const*)HyprlandAPI::getConfigValue(PHANDLE, "plugin:hyprbars:bar_padding")->getDataStaticPtr();
|
||||
static auto* const PALIGNBUTTONS = (Hyprlang::STRING const*)HyprlandAPI::getConfigValue(PHANDLE, "plugin:hyprbars:bar_buttons_alignment")->getDataStaticPtr();
|
||||
static auto* const PICONONHOVER = (Hyprlang::INT* const*)HyprlandAPI::getConfigValue(PHANDLE, "plugin:hyprbars:icon_on_hover")->getDataStaticPtr();
|
||||
const auto HEIGHT = g_pGlobalState->config.barHeight->value();
|
||||
const auto BARBUTTONPADDING = g_pGlobalState->config.barButtonPadding->value();
|
||||
const auto BARPADDING = g_pGlobalState->config.barPadding->value();
|
||||
const auto ALIGNBUTTONS = g_pGlobalState->config.barButtonsAlignment->value();
|
||||
const auto ICONONHOVER = g_pGlobalState->config.iconOnHover->value();
|
||||
|
||||
const bool BUTTONSRIGHT = std::string{*PALIGNBUTTONS} != "left";
|
||||
const auto visibleCount = getVisibleButtonCount(PBARBUTTONPADDING, PBARPADDING, Vector2D{barBox->w, barBox->h}, scale);
|
||||
const auto COORDS = cursorRelativeToBar();
|
||||
const bool BUTTONSRIGHT = ALIGNBUTTONS != "left";
|
||||
const auto visibleCount = getVisibleButtonCount(BARBUTTONPADDING, BARPADDING, Vector2D{barBox->w, barBox->h}, scale);
|
||||
const auto COORDS = cursorRelativeToBar();
|
||||
|
||||
int offset = **PBARPADDING * scale;
|
||||
float noScaleOffset = **PBARPADDING;
|
||||
int offset = BARPADDING * scale;
|
||||
float noScaleOffset = BARPADDING;
|
||||
|
||||
for (size_t i = 0; i < visibleCount; ++i) {
|
||||
auto& button = g_pGlobalState->buttons[i];
|
||||
const auto scaledButtonSize = button.size * scale;
|
||||
const auto scaledButtonsPad = **PBARBUTTONPADDING * scale;
|
||||
const auto scaledButtonsPad = BARBUTTONPADDING * scale;
|
||||
|
||||
// check if hovering here
|
||||
const auto BARBUF = Vector2D{(int)assignedBoxGlobal().w, **PHEIGHT};
|
||||
Vector2D currentPos = Vector2D{(BUTTONSRIGHT ? BARBUF.x - **PBARBUTTONPADDING - button.size - noScaleOffset : noScaleOffset), (BARBUF.y - button.size) / 2.0}.floor();
|
||||
bool hovering = VECINRECT(COORDS, currentPos.x, currentPos.y, currentPos.x + button.size + **PBARBUTTONPADDING, currentPos.y + button.size);
|
||||
noScaleOffset += **PBARBUTTONPADDING + button.size;
|
||||
const auto BARBUF = Vector2D{(int)assignedBoxGlobal().w, HEIGHT};
|
||||
Vector2D currentPos = Vector2D{(BUTTONSRIGHT ? BARBUF.x - BARBUTTONPADDING - button.size - noScaleOffset : noScaleOffset), (BARBUF.y - button.size) / 2.0}.floor();
|
||||
bool hovering = VECINRECT(COORDS, currentPos.x, currentPos.y, currentPos.x + button.size + BARBUTTONPADDING, currentPos.y + button.size);
|
||||
noScaleOffset += BARBUTTONPADDING + button.size;
|
||||
|
||||
if (button.iconTex->m_texID == 0 /* icon is not rendered */ && !button.icon.empty()) {
|
||||
if ((!button.iconTex || button.iconTex->m_texID == 0) && !button.icon.empty()) {
|
||||
// render icon
|
||||
const Vector2D BUFSIZE = {scaledButtonSize, scaledButtonSize};
|
||||
auto fgcol = button.userfg ? button.fgcol : (button.bgcol.r + button.bgcol.g + button.bgcol.b < 1) ? CHyprColor(0xFFFFFFFF) : CHyprColor(0xFF000000);
|
||||
auto fgcol = button.userfg ? button.fgcol : (button.bgcol.r + button.bgcol.g + button.bgcol.b < 1) ? CHyprColor(0xFFFFFFFF) : CHyprColor(0xFF000000);
|
||||
|
||||
renderText(button.iconTex, button.icon, fgcol, BUFSIZE, scale, button.size * 0.62);
|
||||
button.iconTex = g_pHyprRenderer->renderText(button.icon, fgcol, std::round(button.size * 0.62 * scale), false, "sans", scaledButtonSize);
|
||||
}
|
||||
|
||||
if (button.iconTex->m_texID == 0)
|
||||
if (!button.iconTex || button.iconTex->m_texID == 0)
|
||||
continue;
|
||||
|
||||
CBox pos = {barBox->x + (BUTTONSRIGHT ? barBox->width - offset - scaledButtonSize : offset), barBox->y + (barBox->height - scaledButtonSize) / 2.0, scaledButtonSize,
|
||||
scaledButtonSize};
|
||||
const auto iconX = barBox->x + (BUTTONSRIGHT ? barBox->width - offset - scaledButtonSize / 2.0 : offset + scaledButtonSize / 2.0) - button.iconTex->m_size.x / 2.0;
|
||||
const auto iconY = barBox->y + barBox->height / 2.0 - button.iconTex->m_size.y / 2.0;
|
||||
CBox pos = {iconX, iconY, button.iconTex->m_size.x, button.iconTex->m_size.y};
|
||||
|
||||
if (!**PICONONHOVER || (**PICONONHOVER && m_iButtonHoverState > 0))
|
||||
if (!ICONONHOVER || (ICONONHOVER && m_iButtonHoverState > 0))
|
||||
g_pHyprOpenGL->renderTexture(button.iconTex, pos, {.a = a});
|
||||
offset += scaledButtonsPad + scaledButtonSize;
|
||||
|
||||
@ -558,14 +413,14 @@ void CHyprBar::renderBarButtonsText(CBox* barBox, const float scale, const float
|
||||
}
|
||||
|
||||
void CHyprBar::draw(PHLMONITOR pMonitor, const float& a) {
|
||||
static auto* const PENABLED = (Hyprlang::INT* const*)HyprlandAPI::getConfigValue(PHANDLE, "plugin:hyprbars:enabled")->getDataStaticPtr();
|
||||
const auto ENABLED = g_pGlobalState->config.enabled->value();
|
||||
|
||||
if (m_bLastEnabledState != **PENABLED) {
|
||||
m_bLastEnabledState = **PENABLED;
|
||||
if (m_bLastEnabledState != ENABLED) {
|
||||
m_bLastEnabledState = ENABLED;
|
||||
g_pDecorationPositioner->repositionDeco(this);
|
||||
}
|
||||
|
||||
if (m_hidden || !validMapped(m_pWindow) || !**PENABLED)
|
||||
if (m_hidden || !validMapped(m_pWindow) || !ENABLED)
|
||||
return;
|
||||
|
||||
const auto PWINDOW = m_pWindow.lock();
|
||||
@ -580,16 +435,16 @@ void CHyprBar::draw(PHLMONITOR pMonitor, const float& a) {
|
||||
void CHyprBar::renderPass(PHLMONITOR pMonitor, const float& a) {
|
||||
const auto PWINDOW = m_pWindow.lock();
|
||||
|
||||
static auto* const PCOLOR = (Hyprlang::INT* const*)HyprlandAPI::getConfigValue(PHANDLE, "plugin:hyprbars:bar_color")->getDataStaticPtr();
|
||||
static auto* const PHEIGHT = (Hyprlang::INT* const*)HyprlandAPI::getConfigValue(PHANDLE, "plugin:hyprbars:bar_height")->getDataStaticPtr();
|
||||
static auto* const PPRECEDENCE = (Hyprlang::INT* const*)HyprlandAPI::getConfigValue(PHANDLE, "plugin:hyprbars:bar_precedence_over_border")->getDataStaticPtr();
|
||||
static auto* const PALIGNBUTTONS = (Hyprlang::STRING const*)HyprlandAPI::getConfigValue(PHANDLE, "plugin:hyprbars:bar_buttons_alignment")->getDataStaticPtr();
|
||||
static auto* const PENABLETITLE = (Hyprlang::INT* const*)HyprlandAPI::getConfigValue(PHANDLE, "plugin:hyprbars:bar_title_enabled")->getDataStaticPtr();
|
||||
static auto* const PENABLEBLUR = (Hyprlang::INT* const*)HyprlandAPI::getConfigValue(PHANDLE, "plugin:hyprbars:bar_blur")->getDataStaticPtr();
|
||||
static auto* const PENABLEBLURGLOBAL = (Hyprlang::INT* const*)HyprlandAPI::getConfigValue(PHANDLE, "decoration:blur:enabled")->getDataStaticPtr();
|
||||
static auto* const PINACTIVECOLOR = (Hyprlang::INT* const*)HyprlandAPI::getConfigValue(PHANDLE, "plugin:hyprbars:inactive_button_color")->getDataStaticPtr();
|
||||
const auto BARCOLOR = g_pGlobalState->config.barColor->value();
|
||||
const auto HEIGHT = g_pGlobalState->config.barHeight->value();
|
||||
const auto PRECEDENCE = g_pGlobalState->config.barPrecedenceOverBorder->value();
|
||||
const auto ALIGNBUTTONS = g_pGlobalState->config.barButtonsAlignment->value();
|
||||
const auto ENABLETITLE = g_pGlobalState->config.barTitleEnabled->value();
|
||||
const auto ENABLEBLUR = g_pGlobalState->config.barBlur->value();
|
||||
const auto INACTIVECOLOR = g_pGlobalState->config.inactiveButtonColor->value();
|
||||
|
||||
if (**PINACTIVECOLOR > 0) {
|
||||
if (INACTIVECOLOR > 0) {
|
||||
bool currentWindowFocus = PWINDOW == Desktop::focusState()->window();
|
||||
if (currentWindowFocus != m_bWindowHasFocus) {
|
||||
m_bWindowHasFocus = currentWindowFocus;
|
||||
@ -597,29 +452,29 @@ void CHyprBar::renderPass(PHLMONITOR pMonitor, const float& a) {
|
||||
}
|
||||
}
|
||||
|
||||
const CHyprColor DEST_COLOR = m_bForcedBarColor.value_or(**PCOLOR);
|
||||
const CHyprColor DEST_COLOR = m_bForcedBarColor.value_or(configColor(BARCOLOR));
|
||||
if (DEST_COLOR != m_cRealBarColor->goal())
|
||||
*m_cRealBarColor = DEST_COLOR;
|
||||
|
||||
CHyprColor color = m_cRealBarColor->value();
|
||||
|
||||
color.a *= a;
|
||||
const bool BUTTONSRIGHT = std::string{*PALIGNBUTTONS} != "left";
|
||||
const bool SHOULDBLUR = **PENABLEBLUR && **PENABLEBLURGLOBAL && color.a < 1.F;
|
||||
const bool BUTTONSRIGHT = ALIGNBUTTONS != "left";
|
||||
const bool SHOULDBLUR = ENABLEBLUR && **PENABLEBLURGLOBAL && color.a < 1.F;
|
||||
|
||||
if (**PHEIGHT < 1) {
|
||||
m_iLastHeight = **PHEIGHT;
|
||||
if (HEIGHT < 1) {
|
||||
m_iLastHeight = HEIGHT;
|
||||
return;
|
||||
}
|
||||
|
||||
const auto PWORKSPACE = PWINDOW->m_workspace;
|
||||
const auto WORKSPACEOFFSET = PWORKSPACE && !PWINDOW->m_pinned ? PWORKSPACE->m_renderOffset->value() : Vector2D();
|
||||
|
||||
const auto ROUNDING = PWINDOW->rounding() + (*PPRECEDENCE ? 0 : PWINDOW->getRealBorderSize());
|
||||
const auto ROUNDING = PWINDOW->rounding() + (PRECEDENCE ? 0 : PWINDOW->getRealBorderSize());
|
||||
|
||||
const auto scaledRounding = ROUNDING > 0 ? ROUNDING * pMonitor->m_scale - 2 /* idk why but otherwise it looks bad due to the gaps */ : 0;
|
||||
|
||||
m_seExtents = {{0, **PHEIGHT}, {}};
|
||||
m_seExtents = {{0, HEIGHT}, {}};
|
||||
|
||||
const auto DECOBOX = assignedBoxGlobal();
|
||||
|
||||
@ -668,7 +523,7 @@ void CHyprBar::renderPass(PHLMONITOR pMonitor, const float& a) {
|
||||
g_pHyprOpenGL->renderRect(titleBarBox, color, {.round = scaledRounding, .roundingPower = m_pWindow->roundingPower()});
|
||||
|
||||
// render title
|
||||
if (**PENABLETITLE && (m_szLastTitle != PWINDOW->m_title || m_bWindowSizeChanged || m_pTextTex->m_texID == 0 || m_bTitleColorChanged)) {
|
||||
if (ENABLETITLE && (m_szLastTitle != PWINDOW->m_title || m_bWindowSizeChanged || !m_pTextTex || m_pTextTex->m_texID == 0 || m_bTitleColorChanged)) {
|
||||
m_szLastTitle = PWINDOW->m_title;
|
||||
renderBarTitle(BARBUF, pMonitor->m_scale);
|
||||
}
|
||||
@ -683,15 +538,29 @@ void CHyprBar::renderPass(PHLMONITOR pMonitor, const float& a) {
|
||||
}
|
||||
|
||||
CBox textBox = {titleBarBox.x, titleBarBox.y, (int)BARBUF.x, (int)BARBUF.y};
|
||||
if (**PENABLETITLE)
|
||||
g_pHyprOpenGL->renderTexture(m_pTextTex, textBox, {.a = a});
|
||||
if (ENABLETITLE && m_pTextTex) {
|
||||
const auto BARPADDING = g_pGlobalState->config.barPadding->value();
|
||||
const auto BARBUTTONPADDING = g_pGlobalState->config.barButtonPadding->value();
|
||||
const auto ALIGN = g_pGlobalState->config.barTextAlign->value();
|
||||
|
||||
if (m_bButtonsDirty || m_bWindowSizeChanged) {
|
||||
renderBarButtons(BARBUF, pMonitor->m_scale);
|
||||
m_bButtonsDirty = false;
|
||||
float buttonSizes = BARBUTTONPADDING;
|
||||
for (auto& b : g_pGlobalState->buttons) {
|
||||
buttonSizes += b.size + BARBUTTONPADDING;
|
||||
}
|
||||
|
||||
const auto scaledBorderSize = PWINDOW->getRealBorderSize() * pMonitor->m_scale;
|
||||
const auto scaledButtonsSize = buttonSizes * pMonitor->m_scale;
|
||||
const auto scaledBarPadding = BARPADDING * pMonitor->m_scale;
|
||||
const auto xOffset = ALIGN == "left" ? std::round(scaledBarPadding + (BUTTONSRIGHT ? 0 : scaledButtonsSize)) :
|
||||
std::round(((BARBUF.x - scaledBorderSize) / 2.0 - m_pTextTex->m_size.x / 2.0));
|
||||
const auto yOffset = std::round((BARBUF.y - m_pTextTex->m_size.y) / 2.0);
|
||||
CBox titleBox = {textBox.x + xOffset, textBox.y + yOffset, m_pTextTex->m_size.x, m_pTextTex->m_size.y};
|
||||
|
||||
g_pHyprOpenGL->renderTexture(m_pTextTex, titleBox, {.a = a});
|
||||
}
|
||||
|
||||
g_pHyprOpenGL->renderTexture(m_pButtonsTex, textBox, {.a = a});
|
||||
renderBarButtons(&textBox, pMonitor->m_scale, a);
|
||||
m_bButtonsDirty = false;
|
||||
|
||||
g_pHyprOpenGL->scissor(nullptr);
|
||||
|
||||
@ -701,9 +570,9 @@ void CHyprBar::renderPass(PHLMONITOR pMonitor, const float& a) {
|
||||
m_bTitleColorChanged = false;
|
||||
|
||||
// dynamic updates change the extents
|
||||
if (m_iLastHeight != **PHEIGHT) {
|
||||
if (m_iLastHeight != HEIGHT) {
|
||||
PWINDOW->layoutTarget()->recalc();
|
||||
m_iLastHeight = **PHEIGHT;
|
||||
m_iLastHeight = HEIGHT;
|
||||
}
|
||||
}
|
||||
|
||||
@ -715,6 +584,15 @@ void CHyprBar::updateWindow(PHLWINDOW pWindow) {
|
||||
damageEntire();
|
||||
}
|
||||
|
||||
void CHyprBar::onConfigReloaded() {
|
||||
m_bButtonsDirty = true;
|
||||
m_bTitleColorChanged = true;
|
||||
m_pTextTex = nullptr;
|
||||
|
||||
g_pDecorationPositioner->repositionDeco(this);
|
||||
damageEntire();
|
||||
}
|
||||
|
||||
void CHyprBar::damageEntire() {
|
||||
g_pHyprRenderer->damageBox(assignedBoxGlobal());
|
||||
}
|
||||
@ -728,8 +606,7 @@ eDecorationLayer CHyprBar::getDecorationLayer() {
|
||||
}
|
||||
|
||||
uint64_t CHyprBar::getDecorationFlags() {
|
||||
static auto* const PPART = (Hyprlang::INT* const*)HyprlandAPI::getConfigValue(PHANDLE, "plugin:hyprbars:bar_part_of_window")->getDataStaticPtr();
|
||||
return DECORATION_ALLOWS_MOUSE_INPUT | (**PPART ? DECORATION_PART_OF_MAIN_WINDOW : 0);
|
||||
return DECORATION_ALLOWS_MOUSE_INPUT | (g_pGlobalState->config.barPartOfWindow->value() ? DECORATION_PART_OF_MAIN_WINDOW : 0);
|
||||
}
|
||||
|
||||
CBox CHyprBar::assignedBoxGlobal() {
|
||||
@ -772,27 +649,27 @@ void CHyprBar::updateRules() {
|
||||
}
|
||||
|
||||
void CHyprBar::damageOnButtonHover() {
|
||||
static auto* const PBARPADDING = (Hyprlang::INT* const*)HyprlandAPI::getConfigValue(PHANDLE, "plugin:hyprbars:bar_padding")->getDataStaticPtr();
|
||||
static auto* const PBARBUTTONPADDING = (Hyprlang::INT* const*)HyprlandAPI::getConfigValue(PHANDLE, "plugin:hyprbars:bar_button_padding")->getDataStaticPtr();
|
||||
static auto* const PHEIGHT = (Hyprlang::INT* const*)HyprlandAPI::getConfigValue(PHANDLE, "plugin:hyprbars:bar_height")->getDataStaticPtr();
|
||||
static auto* const PALIGNBUTTONS = (Hyprlang::STRING const*)HyprlandAPI::getConfigValue(PHANDLE, "plugin:hyprbars:bar_buttons_alignment")->getDataStaticPtr();
|
||||
const bool BUTTONSRIGHT = std::string{*PALIGNBUTTONS} != "left";
|
||||
const auto BARPADDING = g_pGlobalState->config.barPadding->value();
|
||||
const auto BARBUTTONPADDING = g_pGlobalState->config.barButtonPadding->value();
|
||||
const auto HEIGHT = g_pGlobalState->config.barHeight->value();
|
||||
const auto ALIGNBUTTONS = g_pGlobalState->config.barButtonsAlignment->value();
|
||||
const bool BUTTONSRIGHT = ALIGNBUTTONS != "left";
|
||||
|
||||
float offset = **PBARPADDING;
|
||||
float offset = BARPADDING;
|
||||
|
||||
const auto COORDS = cursorRelativeToBar();
|
||||
const auto COORDS = cursorRelativeToBar();
|
||||
|
||||
for (auto& b : g_pGlobalState->buttons) {
|
||||
const auto BARBUF = Vector2D{(int)assignedBoxGlobal().w, **PHEIGHT};
|
||||
Vector2D currentPos = Vector2D{(BUTTONSRIGHT ? BARBUF.x - **PBARBUTTONPADDING - b.size - offset : offset), (BARBUF.y - b.size) / 2.0}.floor();
|
||||
const auto BARBUF = Vector2D{(int)assignedBoxGlobal().w, HEIGHT};
|
||||
Vector2D currentPos = Vector2D{(BUTTONSRIGHT ? BARBUF.x - BARBUTTONPADDING - b.size - offset : offset), (BARBUF.y - b.size) / 2.0}.floor();
|
||||
|
||||
bool hover = VECINRECT(COORDS, currentPos.x, currentPos.y, currentPos.x + b.size + **PBARBUTTONPADDING, currentPos.y + b.size);
|
||||
bool hover = VECINRECT(COORDS, currentPos.x, currentPos.y, currentPos.x + b.size + BARBUTTONPADDING, currentPos.y + b.size);
|
||||
|
||||
if (hover != m_bButtonHovered) {
|
||||
m_bButtonHovered = hover;
|
||||
damageEntire();
|
||||
}
|
||||
|
||||
offset += **PBARBUTTONPADDING + b.size;
|
||||
offset += BARBUTTONPADDING + b.size;
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
|
||||
#include <hyprland/src/render/decorations/IHyprWindowDecoration.hpp>
|
||||
#include <hyprland/src/render/OpenGL.hpp>
|
||||
#include <hyprland/src/render/gl/GLTexture.hpp>
|
||||
#include <hyprland/src/devices/IPointer.hpp>
|
||||
#include <hyprland/src/devices/ITouch.hpp>
|
||||
#include <hyprland/src/desktop/rule/windowRule/WindowRule.hpp>
|
||||
@ -48,52 +49,51 @@ class CHyprBar : public IHyprWindowDecoration {
|
||||
PHLWINDOW getOwner();
|
||||
|
||||
void updateRules();
|
||||
void onConfigReloaded();
|
||||
|
||||
WP<CHyprBar> m_self;
|
||||
|
||||
private:
|
||||
SBoxExtents m_seExtents;
|
||||
SBoxExtents m_seExtents;
|
||||
|
||||
PHLWINDOWREF m_pWindow;
|
||||
PHLWINDOWREF m_pWindow;
|
||||
|
||||
CBox m_bAssignedBox;
|
||||
CBox m_bAssignedBox;
|
||||
|
||||
SP<CTexture> m_pTextTex;
|
||||
SP<CTexture> m_pButtonsTex;
|
||||
SP<Render::ITexture> m_pTextTex;
|
||||
|
||||
bool m_bWindowSizeChanged = false;
|
||||
bool m_hidden = false;
|
||||
bool m_bTitleColorChanged = false;
|
||||
bool m_bButtonHovered = false;
|
||||
bool m_bLastEnabledState = false;
|
||||
bool m_bWindowHasFocus = false;
|
||||
std::optional<CHyprColor> m_bForcedBarColor;
|
||||
std::optional<CHyprColor> m_bForcedTitleColor;
|
||||
bool m_bWindowSizeChanged = false;
|
||||
bool m_hidden = false;
|
||||
bool m_bTitleColorChanged = false;
|
||||
bool m_bButtonHovered = false;
|
||||
bool m_bLastEnabledState = false;
|
||||
bool m_bWindowHasFocus = false;
|
||||
std::optional<CHyprColor> m_bForcedBarColor;
|
||||
std::optional<CHyprColor> m_bForcedTitleColor;
|
||||
|
||||
Time::steady_tp m_lastMouseDown = Time::steadyNow();
|
||||
Time::steady_tp m_lastMouseDown = Time::steadyNow();
|
||||
|
||||
PHLANIMVAR<CHyprColor> m_cRealBarColor;
|
||||
PHLANIMVAR<CHyprColor> m_cRealBarColor;
|
||||
|
||||
Vector2D cursorRelativeToBar();
|
||||
Vector2D cursorRelativeToBar();
|
||||
|
||||
void renderPass(PHLMONITOR, float const& a);
|
||||
void renderBarTitle(const Vector2D& bufferSize, const float scale);
|
||||
void renderText(SP<CTexture> out, const std::string& text, const CHyprColor& color, const Vector2D& bufferSize, const float scale, const int fontSize);
|
||||
void renderBarButtons(const Vector2D& bufferSize, const float scale);
|
||||
void renderBarButtonsText(CBox* barBox, const float scale, const float a);
|
||||
void damageOnButtonHover();
|
||||
void renderPass(PHLMONITOR, float const& a);
|
||||
void renderBarTitle(const Vector2D& bufferSize, const float scale);
|
||||
void renderBarButtons(CBox* barBox, const float scale, const float a);
|
||||
void renderBarButtonsText(CBox* barBox, const float scale, const float a);
|
||||
void damageOnButtonHover();
|
||||
|
||||
bool inputIsValid();
|
||||
void onMouseButton(Event::SCallbackInfo& info, IPointer::SButtonEvent e);
|
||||
void onTouchDown(Event::SCallbackInfo& info, ITouch::SDownEvent e);
|
||||
void onTouchUp(Event::SCallbackInfo& info, ITouch::SUpEvent e);
|
||||
void onMouseMove(Vector2D coords);
|
||||
void onTouchMove(Event::SCallbackInfo& info, ITouch::SMotionEvent e);
|
||||
bool inputIsValid();
|
||||
void onMouseButton(Event::SCallbackInfo& info, IPointer::SButtonEvent e);
|
||||
void onTouchDown(Event::SCallbackInfo& info, ITouch::SDownEvent e);
|
||||
void onTouchUp(Event::SCallbackInfo& info, ITouch::SUpEvent e);
|
||||
void onMouseMove(Vector2D coords);
|
||||
void onTouchMove(Event::SCallbackInfo& info, ITouch::SMotionEvent e);
|
||||
|
||||
void handleDownEvent(Event::SCallbackInfo& info, std::optional<ITouch::SDownEvent> touchEvent);
|
||||
void handleUpEvent(Event::SCallbackInfo& info);
|
||||
void handleMovement();
|
||||
bool doButtonPress(Hyprlang::INT* const* PBARPADDING, Hyprlang::INT* const* PBARBUTTONPADDING, Hyprlang::INT* const* PHEIGHT, Vector2D COORDS, bool BUTTONSRIGHT);
|
||||
void handleDownEvent(Event::SCallbackInfo& info, std::optional<ITouch::SDownEvent> touchEvent);
|
||||
void handleUpEvent(Event::SCallbackInfo& info);
|
||||
void handleMovement();
|
||||
bool doButtonPress(Config::INTEGER barPadding, Config::INTEGER barButtonPadding, Config::INTEGER barHeight, Vector2D COORDS, bool BUTTONSRIGHT);
|
||||
|
||||
CBox assignedBoxGlobal();
|
||||
|
||||
@ -118,7 +118,7 @@ class CHyprBar : public IHyprWindowDecoration {
|
||||
// for dynamic updates
|
||||
int m_iLastHeight = 0;
|
||||
|
||||
size_t getVisibleButtonCount(Hyprlang::INT* const* PBARBUTTONPADDING, Hyprlang::INT* const* PBARPADDING, const Vector2D& bufferSize, const float scale);
|
||||
size_t getVisibleButtonCount(Config::INTEGER barButtonPadding, Config::INTEGER barPadding, const Vector2D& bufferSize, const float scale);
|
||||
|
||||
friend class CBarPassElement;
|
||||
};
|
||||
|
||||
@ -2,17 +2,21 @@
|
||||
|
||||
#include <hyprland/src/plugins/PluginAPI.hpp>
|
||||
#include <hyprland/src/render/Texture.hpp>
|
||||
#include <hyprland/src/config/values/types/BoolValue.hpp>
|
||||
#include <hyprland/src/config/values/types/IntValue.hpp>
|
||||
#include <hyprland/src/config/values/types/StringValue.hpp>
|
||||
#include <hyprland/src/config/values/types/ColorValue.hpp>
|
||||
|
||||
inline HANDLE PHANDLE = nullptr;
|
||||
|
||||
struct SHyprButton {
|
||||
std::string cmd = "";
|
||||
bool userfg = false;
|
||||
CHyprColor fgcol = CHyprColor(0, 0, 0, 0);
|
||||
CHyprColor bgcol = CHyprColor(0, 0, 0, 0);
|
||||
float size = 10;
|
||||
std::string icon = "";
|
||||
SP<CTexture> iconTex = makeShared<CTexture>();
|
||||
std::string cmd = "";
|
||||
bool userfg = false;
|
||||
CHyprColor fgcol = CHyprColor(0, 0, 0, 0);
|
||||
CHyprColor bgcol = CHyprColor(0, 0, 0, 0);
|
||||
float size = 10;
|
||||
std::string icon = "";
|
||||
SP<Render::ITexture> iconTex;
|
||||
};
|
||||
|
||||
class CHyprBar;
|
||||
@ -20,9 +24,19 @@ class CHyprBar;
|
||||
struct SGlobalState {
|
||||
std::vector<SHyprButton> buttons;
|
||||
std::vector<WP<CHyprBar>> bars;
|
||||
uint32_t nobarRuleIdx = 0;
|
||||
uint32_t barColorRuleIdx = 0;
|
||||
uint32_t nobarRuleIdx = 0;
|
||||
uint32_t barColorRuleIdx = 0;
|
||||
uint32_t titleColorRuleIdx = 0;
|
||||
|
||||
struct {
|
||||
SP<Config::Values::CColorValue> barColor, textColor, inactiveButtonColor;
|
||||
SP<Config::Values::CIntValue> barHeight;
|
||||
SP<Config::Values::CIntValue> barTextSize;
|
||||
SP<Config::Values::CIntValue> barPadding;
|
||||
SP<Config::Values::CIntValue> barButtonPadding;
|
||||
SP<Config::Values::CBoolValue> barBlur, barTitleEnabled, barPartOfWindow, barPrecedenceOverBorder, enabled, iconOnHover;
|
||||
SP<Config::Values::CStringValue> barTextFont, barTextAlign, barButtonsAlignment, onDoubleClick;
|
||||
} config;
|
||||
};
|
||||
|
||||
inline UP<SGlobalState> g_pGlobalState;
|
||||
|
||||
@ -9,12 +9,21 @@
|
||||
#include <hyprland/src/render/Renderer.hpp>
|
||||
#include <hyprland/src/event/EventBus.hpp>
|
||||
#include <hyprland/src/desktop/rule/windowRule/WindowRuleEffectContainer.hpp>
|
||||
#include <hyprland/src/config/lua/bindings/LuaBindingsInternal.hpp>
|
||||
#include <hyprland/src/config/lua/types/LuaConfigColor.hpp>
|
||||
|
||||
#include <hyprutils/string/VarList.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "barDeco.hpp"
|
||||
#include "globals.hpp"
|
||||
|
||||
extern "C" {
|
||||
#include <lua.h>
|
||||
#include <lauxlib.h>
|
||||
}
|
||||
|
||||
// Do NOT change this function.
|
||||
APICALL EXPORT std::string PLUGIN_API_VERSION() {
|
||||
return HYPRLAND_API_VERSION;
|
||||
@ -36,6 +45,15 @@ static void onPreConfigReload() {
|
||||
g_pGlobalState->buttons.clear();
|
||||
}
|
||||
|
||||
static void onConfigReloaded() {
|
||||
for (auto& b : g_pGlobalState->bars) {
|
||||
if (!b)
|
||||
continue;
|
||||
|
||||
b->onConfigReloaded();
|
||||
}
|
||||
}
|
||||
|
||||
static void onUpdateWindowRules(PHLWINDOW window) {
|
||||
const auto BARIT = std::find_if(g_pGlobalState->bars.begin(), g_pGlobalState->bars.end(), [window](const auto& bar) { return bar->getOwner() == window; });
|
||||
|
||||
@ -47,10 +65,10 @@ static void onUpdateWindowRules(PHLWINDOW window) {
|
||||
}
|
||||
|
||||
Hyprlang::CParseResult onNewButton(const char* K, const char* V) {
|
||||
std::string v = V;
|
||||
CVarList vars(v);
|
||||
std::string v = V;
|
||||
Hyprutils::String::CVarList vars(v);
|
||||
|
||||
Hyprlang::CParseResult result;
|
||||
Hyprlang::CParseResult result;
|
||||
|
||||
// hyprbars-button = bgcolor, size, icon, action, fgcolor
|
||||
|
||||
@ -95,6 +113,80 @@ Hyprlang::CParseResult onNewButton(const char* K, const char* V) {
|
||||
return result;
|
||||
}
|
||||
|
||||
int newLuaButton(lua_State* L) {
|
||||
if (!lua_istable(L, 1))
|
||||
return Config::Lua::Bindings::Internal::configError(L, "add_button: expected a table { bg_color, fg_color, size, icon, action }");
|
||||
|
||||
SHyprButton button;
|
||||
|
||||
{
|
||||
Hyprutils::Utils::CScopeGuard x([L] { lua_pop(L, 1); });
|
||||
|
||||
lua_getfield(L, 1, "bg_color");
|
||||
|
||||
Config::Lua::CLuaConfigColor parser(0);
|
||||
auto err = parser.parse(L);
|
||||
if (err.errorCode != Config::Lua::PARSE_ERROR_OK)
|
||||
return Config::Lua::Bindings::Internal::configError(L, "add_button: failed to parse bg_color");
|
||||
|
||||
button.bgcol = parser.parsed();
|
||||
}
|
||||
|
||||
{
|
||||
Hyprutils::Utils::CScopeGuard x([L] { lua_pop(L, 1); });
|
||||
|
||||
lua_getfield(L, 1, "fg_color");
|
||||
|
||||
Config::Lua::CLuaConfigColor parser(0);
|
||||
auto err = parser.parse(L);
|
||||
if (err.errorCode != Config::Lua::PARSE_ERROR_OK)
|
||||
return Config::Lua::Bindings::Internal::configError(L, "add_button: failed to parse fg_color");
|
||||
|
||||
button.fgcol = parser.parsed();
|
||||
}
|
||||
|
||||
{
|
||||
Hyprutils::Utils::CScopeGuard x([L] { lua_pop(L, 1); });
|
||||
|
||||
lua_getfield(L, 1, "size");
|
||||
|
||||
if (!lua_isnumber(L, -1))
|
||||
return Config::Lua::Bindings::Internal::configError(L, "add_button: size must be an integer");
|
||||
|
||||
button.size = lua_tointeger(L, -1);
|
||||
}
|
||||
|
||||
{
|
||||
Hyprutils::Utils::CScopeGuard x([L] { lua_pop(L, 1); });
|
||||
|
||||
lua_getfield(L, 1, "icon");
|
||||
|
||||
if (!lua_isstring(L, -1))
|
||||
return Config::Lua::Bindings::Internal::configError(L, "add_button: icon must be a string");
|
||||
|
||||
button.icon = lua_tostring(L, -1);
|
||||
}
|
||||
|
||||
{
|
||||
Hyprutils::Utils::CScopeGuard x([L] { lua_pop(L, 1); });
|
||||
|
||||
lua_getfield(L, 1, "action");
|
||||
|
||||
if (!lua_isstring(L, -1))
|
||||
return Config::Lua::Bindings::Internal::configError(L, "add_button: action must be a string");
|
||||
|
||||
button.cmd = lua_tostring(L, -1);
|
||||
}
|
||||
|
||||
g_pGlobalState->buttons.push_back(std::move(button));
|
||||
|
||||
for (auto& b : g_pGlobalState->bars) {
|
||||
b->m_bButtonsDirty = true;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE handle) {
|
||||
PHANDLE = handle;
|
||||
|
||||
@ -112,29 +204,54 @@ APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE handle) {
|
||||
g_pGlobalState->barColorRuleIdx = Desktop::Rule::windowEffects()->registerEffect("hyprbars:bar_color");
|
||||
g_pGlobalState->titleColorRuleIdx = Desktop::Rule::windowEffects()->registerEffect("hyprbars:title_color");
|
||||
|
||||
static auto P = Event::bus()->m_events.window.open.listen([&](PHLWINDOW w) { onNewWindow(w); });
|
||||
static auto P = Event::bus()->m_events.window.open.listen([&](PHLWINDOW w) { onNewWindow(w); });
|
||||
static auto P3 = Event::bus()->m_events.window.updateRules.listen([&](PHLWINDOW w) { onUpdateWindowRules(w); });
|
||||
|
||||
HyprlandAPI::addConfigValue(PHANDLE, "plugin:hyprbars:bar_color", Hyprlang::INT{*configStringToInt("rgba(33333388)")});
|
||||
HyprlandAPI::addConfigValue(PHANDLE, "plugin:hyprbars:bar_height", Hyprlang::INT{15});
|
||||
HyprlandAPI::addConfigValue(PHANDLE, "plugin:hyprbars:col.text", Hyprlang::INT{*configStringToInt("rgba(ffffffff)")});
|
||||
HyprlandAPI::addConfigValue(PHANDLE, "plugin:hyprbars:bar_text_size", Hyprlang::INT{10});
|
||||
HyprlandAPI::addConfigValue(PHANDLE, "plugin:hyprbars:bar_title_enabled", Hyprlang::INT{1});
|
||||
HyprlandAPI::addConfigValue(PHANDLE, "plugin:hyprbars:bar_blur", Hyprlang::INT{0});
|
||||
HyprlandAPI::addConfigValue(PHANDLE, "plugin:hyprbars:bar_text_font", Hyprlang::STRING{"Sans"});
|
||||
HyprlandAPI::addConfigValue(PHANDLE, "plugin:hyprbars:bar_text_align", Hyprlang::STRING{"center"});
|
||||
HyprlandAPI::addConfigValue(PHANDLE, "plugin:hyprbars:bar_part_of_window", Hyprlang::INT{1});
|
||||
HyprlandAPI::addConfigValue(PHANDLE, "plugin:hyprbars:bar_precedence_over_border", Hyprlang::INT{0});
|
||||
HyprlandAPI::addConfigValue(PHANDLE, "plugin:hyprbars:bar_buttons_alignment", Hyprlang::STRING{"right"});
|
||||
HyprlandAPI::addConfigValue(PHANDLE, "plugin:hyprbars:bar_padding", Hyprlang::INT{7});
|
||||
HyprlandAPI::addConfigValue(PHANDLE, "plugin:hyprbars:bar_button_padding", Hyprlang::INT{5});
|
||||
HyprlandAPI::addConfigValue(PHANDLE, "plugin:hyprbars:enabled", Hyprlang::INT{1});
|
||||
HyprlandAPI::addConfigValue(PHANDLE, "plugin:hyprbars:icon_on_hover", Hyprlang::INT{0});
|
||||
HyprlandAPI::addConfigValue(PHANDLE, "plugin:hyprbars:inactive_button_color", Hyprlang::INT{0}); // unset
|
||||
HyprlandAPI::addConfigValue(PHANDLE, "plugin:hyprbars:on_double_click", Hyprlang::STRING{""});
|
||||
g_pGlobalState->config.barColor = makeShared<Config::Values::CColorValue>("plugin:hyprbars:bar_color", "Change the bar color", *configStringToInt("rgba(33333388)"));
|
||||
g_pGlobalState->config.textColor = makeShared<Config::Values::CColorValue>("plugin:hyprbars:col.text", "Change the text color", *configStringToInt("rgba(ffffffff)"));
|
||||
g_pGlobalState->config.inactiveButtonColor = makeShared<Config::Values::CColorValue>(
|
||||
"plugin:hyprbars:inactive_button_color", "Change the inactive button's color. 0x00000000 means unset", *configStringToInt("rgba(00000000)"));
|
||||
g_pGlobalState->config.barHeight = makeShared<Config::Values::CIntValue>("plugin:hyprbars:bar_height", "Change the bar's height", 15);
|
||||
g_pGlobalState->config.barTextSize = makeShared<Config::Values::CIntValue>("plugin:hyprbars:bar_text_size", "Change the bar's text size", 10);
|
||||
g_pGlobalState->config.barTitleEnabled = makeShared<Config::Values::CBoolValue>("plugin:hyprbars:bar_title_enabled", "Whether to enable titles in the bar", true);
|
||||
g_pGlobalState->config.barBlur = makeShared<Config::Values::CBoolValue>("plugin:hyprbars:bar_blur", "Whether to enable blur of the bar", false);
|
||||
g_pGlobalState->config.barTextFont = makeShared<Config::Values::CStringValue>("plugin:hyprbars:bar_text_font", "Bar's text font", "Sans");
|
||||
g_pGlobalState->config.barTextAlign = makeShared<Config::Values::CStringValue>("plugin:hyprbars:bar_text_align", "Bar's text alignment", "center");
|
||||
g_pGlobalState->config.barPartOfWindow =
|
||||
makeShared<Config::Values::CBoolValue>("plugin:hyprbars:bar_part_of_window", "Whether the bar is a part of the window (reserves space)", true);
|
||||
g_pGlobalState->config.barPrecedenceOverBorder =
|
||||
makeShared<Config::Values::CBoolValue>("plugin:hyprbars:bar_precedence_over_border", "Whether the bar is before, or after the border", false);
|
||||
g_pGlobalState->config.barButtonsAlignment = makeShared<Config::Values::CStringValue>("plugin:hyprbars:bar_buttons_alignment", "Alignment of the bar buttons", "right");
|
||||
g_pGlobalState->config.barPadding = makeShared<Config::Values::CIntValue>("plugin:hyprbars:bar_padding", "Padding of the bar", 7);
|
||||
g_pGlobalState->config.barButtonPadding = makeShared<Config::Values::CIntValue>("plugin:hyprbars:bar_button_padding", "Padding of the bar buttons", 5);
|
||||
g_pGlobalState->config.enabled = makeShared<Config::Values::CBoolValue>("plugin:hyprbars:enabled", "Whether bars are enabled", true);
|
||||
g_pGlobalState->config.iconOnHover = makeShared<Config::Values::CBoolValue>("plugin:hyprbars:icon_on_hover", "Whether to use an icon on hover of the buttons", false);
|
||||
g_pGlobalState->config.onDoubleClick = makeShared<Config::Values::CStringValue>("plugin:hyprbars:on_double_click", "Action to execute on double click of the bar", "");
|
||||
|
||||
HyprlandAPI::addConfigKeyword(PHANDLE, "plugin:hyprbars:hyprbars-button", onNewButton, Hyprlang::SHandlerOptions{});
|
||||
HyprlandAPI::addConfigValueV2(PHANDLE, g_pGlobalState->config.barColor);
|
||||
HyprlandAPI::addConfigValueV2(PHANDLE, g_pGlobalState->config.textColor);
|
||||
HyprlandAPI::addConfigValueV2(PHANDLE, g_pGlobalState->config.inactiveButtonColor);
|
||||
HyprlandAPI::addConfigValueV2(PHANDLE, g_pGlobalState->config.barHeight);
|
||||
HyprlandAPI::addConfigValueV2(PHANDLE, g_pGlobalState->config.barTextSize);
|
||||
HyprlandAPI::addConfigValueV2(PHANDLE, g_pGlobalState->config.barTitleEnabled);
|
||||
HyprlandAPI::addConfigValueV2(PHANDLE, g_pGlobalState->config.barBlur);
|
||||
HyprlandAPI::addConfigValueV2(PHANDLE, g_pGlobalState->config.barTextFont);
|
||||
HyprlandAPI::addConfigValueV2(PHANDLE, g_pGlobalState->config.barTextAlign);
|
||||
HyprlandAPI::addConfigValueV2(PHANDLE, g_pGlobalState->config.barPartOfWindow);
|
||||
HyprlandAPI::addConfigValueV2(PHANDLE, g_pGlobalState->config.barPrecedenceOverBorder);
|
||||
HyprlandAPI::addConfigValueV2(PHANDLE, g_pGlobalState->config.barButtonsAlignment);
|
||||
HyprlandAPI::addConfigValueV2(PHANDLE, g_pGlobalState->config.barPadding);
|
||||
HyprlandAPI::addConfigValueV2(PHANDLE, g_pGlobalState->config.barButtonPadding);
|
||||
HyprlandAPI::addConfigValueV2(PHANDLE, g_pGlobalState->config.enabled);
|
||||
HyprlandAPI::addConfigValueV2(PHANDLE, g_pGlobalState->config.iconOnHover);
|
||||
HyprlandAPI::addConfigValueV2(PHANDLE, g_pGlobalState->config.onDoubleClick);
|
||||
|
||||
if (Config::mgr()->type() == Config::CONFIG_LEGACY)
|
||||
HyprlandAPI::addConfigKeyword(PHANDLE, "plugin:hyprbars:hyprbars-button", onNewButton, Hyprlang::SHandlerOptions{});
|
||||
else
|
||||
HyprlandAPI::addLuaFunction(PHANDLE, "hyprbars", "add_button", ::newLuaButton);
|
||||
static auto P4 = Event::bus()->m_events.config.preReload.listen([&] { onPreConfigReload(); });
|
||||
static auto P5 = Event::bus()->m_events.config.reloaded.listen([&] { onConfigReloaded(); });
|
||||
|
||||
// add deco to existing windows
|
||||
for (auto& w : g_pCompositor->m_windows) {
|
||||
|
||||
@ -28,7 +28,6 @@ shared_module(meson.project_name(), src,
|
||||
dependency('hyprland'),
|
||||
dependency('pixman-1'),
|
||||
dependency('libdrm'),
|
||||
dependency('pangocairo'),
|
||||
dependency('libinput'),
|
||||
dependency('libudev'),
|
||||
dependency('wayland-server'),
|
||||
|
||||
@ -10,11 +10,15 @@
|
||||
#define private public
|
||||
#include <hyprland/src/Compositor.hpp>
|
||||
#include <hyprland/src/config/ConfigValue.hpp>
|
||||
#include <hyprland/src/config/shared/animation/AnimationTree.hpp>
|
||||
#include <hyprland/src/helpers/AnimatedVariable.hpp>
|
||||
#include <hyprland/src/managers/animation/AnimationManager.hpp>
|
||||
#include <hyprland/src/managers/eventLoop/EventLoopManager.hpp>
|
||||
#include <hyprland/src/layout/LayoutManager.hpp>
|
||||
#include <hyprland/src/config/ConfigManager.hpp>
|
||||
#include <hyprland/src/config/values/types/BoolValue.hpp>
|
||||
#include <hyprland/src/config/values/types/FloatValue.hpp>
|
||||
#include <hyprland/src/config/values/types/StringValue.hpp>
|
||||
#include <hyprland/src/event/EventBus.hpp>
|
||||
#undef private
|
||||
|
||||
@ -25,6 +29,12 @@
|
||||
using namespace Hyprutils::String;
|
||||
using namespace Hyprutils::Animation;
|
||||
|
||||
static struct {
|
||||
SP<Config::Values::CBoolValue> onlyOnMonitorChange;
|
||||
SP<Config::Values::CFloatValue> fadeOpacity, slideHeight, bounceStrength;
|
||||
SP<Config::Values::CStringValue> mode;
|
||||
} configValues;
|
||||
|
||||
// Do NOT change this function.
|
||||
APICALL EXPORT std::string PLUGIN_API_VERSION() {
|
||||
return HYPRLAND_API_VERSION;
|
||||
@ -39,23 +49,17 @@ static void onFocusChange(PHLWINDOW window) {
|
||||
if (lastWindow == window)
|
||||
return;
|
||||
|
||||
static const auto PONLY_ON_MONITOR_CHANGE = CConfigValue<Hyprlang::INT>("plugin:hyprfocus:only_on_monitor_change");
|
||||
if (*PONLY_ON_MONITOR_CHANGE && lastWindow && lastWindow->m_monitor == window->m_monitor)
|
||||
if (configValues.onlyOnMonitorChange->value() && lastWindow && lastWindow->m_monitor == window->m_monitor)
|
||||
return;
|
||||
|
||||
lastWindow = window;
|
||||
const auto PIN = Config::animationTree()->getAnimationPropertyConfig("hyprfocusIn");
|
||||
const auto POUT = Config::animationTree()->getAnimationPropertyConfig("hyprfocusOut");
|
||||
|
||||
static const auto POPACITY = CConfigValue<Hyprlang::FLOAT>("plugin:hyprfocus:fade_opacity");
|
||||
static const auto PBOUNCE = CConfigValue<Hyprlang::FLOAT>("plugin:hyprfocus:bounce_strength");
|
||||
static const auto PSLIDE = CConfigValue<Hyprlang::FLOAT>("plugin:hyprfocus:slide_height");
|
||||
static const auto PMODE = CConfigValue<std::string>("plugin:hyprfocus:mode");
|
||||
const auto PIN = g_pConfigManager->getAnimationPropertyConfig("hyprfocusIn");
|
||||
const auto POUT = g_pConfigManager->getAnimationPropertyConfig("hyprfocusOut");
|
||||
|
||||
if (*PMODE == "flash") {
|
||||
if (configValues.mode->value() == "flash") {
|
||||
const auto ORIGINAL = window->m_activeInactiveAlpha->goal();
|
||||
window->m_activeInactiveAlpha->setConfig(PIN);
|
||||
*window->m_activeInactiveAlpha = std::clamp(*POPACITY, 0.F, 1.F);
|
||||
*window->m_activeInactiveAlpha = configValues.fadeOpacity->value();
|
||||
|
||||
window->m_activeInactiveAlpha->setCallbackOnEnd([w = PHLWINDOWREF{window}, POUT, ORIGINAL](WP<CBaseAnimatedVariable> pav) {
|
||||
if (!w)
|
||||
@ -65,13 +69,13 @@ static void onFocusChange(PHLWINDOW window) {
|
||||
|
||||
w->m_activeInactiveAlpha->setCallbackOnEnd(nullptr);
|
||||
});
|
||||
} else if (*PMODE == "bounce") {
|
||||
} else if (configValues.mode->value() == "bounce") {
|
||||
const auto ORIGINAL = CBox{window->m_realPosition->goal(), window->m_realSize->goal()};
|
||||
|
||||
window->m_realPosition->setConfig(PIN);
|
||||
window->m_realSize->setConfig(PIN);
|
||||
|
||||
auto box = ORIGINAL.copy().scaleFromCenter(std::clamp(*PBOUNCE, 0.1F, 1.F));
|
||||
auto box = ORIGINAL.copy().scaleFromCenter(configValues.bounceStrength->value());
|
||||
|
||||
*window->m_realPosition = box.pos();
|
||||
*window->m_realSize = box.size();
|
||||
@ -90,12 +94,12 @@ static void onFocusChange(PHLWINDOW window) {
|
||||
|
||||
w->m_realSize->setCallbackOnEnd(nullptr);
|
||||
});
|
||||
} else if (*PMODE == "slide") {
|
||||
} else if (configValues.mode->value() == "slide") {
|
||||
const auto ORIGINAL = window->m_realPosition->goal();
|
||||
|
||||
window->m_realPosition->setConfig(PIN);
|
||||
|
||||
*window->m_realPosition = ORIGINAL - Vector2D{0.F, std::clamp(*PSLIDE, 0.F, 150.F)};
|
||||
*window->m_realPosition = ORIGINAL - Vector2D{0.F, configValues.slideHeight->value()};
|
||||
|
||||
window->m_realPosition->setCallbackOnEnd([w = PHLWINDOWREF{window}, POUT, ORIGINAL](WP<CBaseAnimatedVariable> pav) {
|
||||
if (!w)
|
||||
@ -126,16 +130,22 @@ APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE handle) {
|
||||
|
||||
static auto P = Event::bus()->m_events.window.active.listen([&](PHLWINDOW w, Desktop::eFocusReason r) { onFocusChange(w); });
|
||||
|
||||
HyprlandAPI::addConfigValue(PHANDLE, "plugin:hyprfocus:mode", Hyprlang::STRING{"flash"});
|
||||
HyprlandAPI::addConfigValue(PHANDLE, "plugin:hyprfocus:only_on_monitor_change", Hyprlang::INT{0});
|
||||
HyprlandAPI::addConfigValue(PHANDLE, "plugin:hyprfocus:fade_opacity", Hyprlang::FLOAT{0.8F});
|
||||
HyprlandAPI::addConfigValue(PHANDLE, "plugin:hyprfocus:slide_height", Hyprlang::FLOAT{20.F});
|
||||
HyprlandAPI::addConfigValue(PHANDLE, "plugin:hyprfocus:bounce_strength", Hyprlang::FLOAT{0.95F});
|
||||
configValues.mode = makeShared<Config::Values::CStringValue>("plugin:hyprfocus:mode", "mode to use", "flash");
|
||||
configValues.onlyOnMonitorChange = makeShared<Config::Values::CBoolValue>("plugin:hyprfocus:only_on_monitor_change", "whether to fire the animation only on monitor change", false);
|
||||
configValues.fadeOpacity = makeShared<Config::Values::CFloatValue>("plugin:hyprfocus:fade_opacity", "fade opacity", 0.8F, Config::Values::SFloatValueOptions{.min = 0.F, .max = 1.F} );
|
||||
configValues.slideHeight = makeShared<Config::Values::CFloatValue>("plugin:hyprfocus:slide_height", "slide height", 20.F, Config::Values::SFloatValueOptions{.min = 0.F, .max = 150.F} );
|
||||
configValues.bounceStrength = makeShared<Config::Values::CFloatValue>("plugin:hyprfocus:bounce_strength", "bounce strength", 0.95F, Config::Values::SFloatValueOptions{.min = 0.F, .max = 1.F} );
|
||||
|
||||
HyprlandAPI::addConfigValueV2(PHANDLE, configValues.mode);
|
||||
HyprlandAPI::addConfigValueV2(PHANDLE, configValues.onlyOnMonitorChange);
|
||||
HyprlandAPI::addConfigValueV2(PHANDLE, configValues.fadeOpacity);
|
||||
HyprlandAPI::addConfigValueV2(PHANDLE, configValues.slideHeight);
|
||||
HyprlandAPI::addConfigValueV2(PHANDLE, configValues.bounceStrength);
|
||||
|
||||
// this will not be cleaned up after we are unloaded but it doesn't really matter,
|
||||
// as if we create this again it will just overwrite the old one.
|
||||
g_pConfigManager->m_animationTree.createNode("hyprfocusIn", "windowsIn");
|
||||
g_pConfigManager->m_animationTree.createNode("hyprfocusOut", "windowsOut");
|
||||
Config::animationTree()->m_animationTree.createNode("hyprfocusIn", "windowsIn");
|
||||
Config::animationTree()->m_animationTree.createNode("hyprfocusOut", "windowsOut");
|
||||
|
||||
return {"hyprfocus", "Flashfocus for Hyprland", "Vaxry", "1.0"};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user