all: update for hyprland#3800

This commit is contained in:
Vaxry 2023-11-11 14:39:46 +00:00
parent 344e5a145e
commit 2cc193e6dc
9 changed files with 149 additions and 96 deletions

View file

@ -14,12 +14,46 @@ CBordersPlusPlus::~CBordersPlusPlus() {
damageEntire();
}
SWindowDecorationExtents CBordersPlusPlus::getWindowDecorationExtents() {
return m_seExtents;
SDecorationPositioningInfo CBordersPlusPlus::getPositioningInfo() {
static auto* const PBORDERS = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:borders-plus-plus:add_borders")->intValue;
static std::vector<int64_t*> PSIZES;
for (size_t i = 0; i < 9; ++i) {
PSIZES.push_back(&HyprlandAPI::getConfigValue(PHANDLE, "plugin:borders-plus-plus:border_size_" + std::to_string(i + 1))->intValue);
}
SDecorationPositioningInfo info;
info.policy = DECORATION_POSITION_ABSOLUTE;
info.reserved = true;
info.priority = 1005;
info.edges = DECORATION_EDGE_BOTTOM | DECORATION_EDGE_LEFT | DECORATION_EDGE_RIGHT | DECORATION_EDGE_TOP;
if (m_fLastThickness == 0) {
double size = 0;
for (size_t i = 0; i < *PBORDERS; ++i) {
size += *PSIZES[i];
}
info.desiredExtents = {{size, size}, {size, size}};
m_fLastThickness = size;
} else {
info.desiredExtents = {{m_fLastThickness, m_fLastThickness}, {m_fLastThickness, m_fLastThickness}};
}
return info;
}
SWindowDecorationExtents CBordersPlusPlus::getWindowDecorationReservedArea() {
return m_seExtents;
void CBordersPlusPlus::onPositioningReply(const SDecorationPositioningReply& reply) {
; // ignored
}
uint64_t CBordersPlusPlus::getDecorationFlags() {
return 0;
}
eDecorationLayer CBordersPlusPlus::getDecorationLayer() {
return DECORATION_LAYER_OVER;
}
void CBordersPlusPlus::draw(CMonitor* pMonitor, float a, const Vector2D& offset) {
@ -83,6 +117,11 @@ void CBordersPlusPlus::draw(CMonitor* pMonitor, float a, const Vector2D& offset)
}
m_seExtents = {{fullThickness, fullThickness}, {fullThickness, fullThickness}};
if (fullThickness != m_fLastThickness) {
m_fLastThickness = fullThickness;
g_pDecorationPositioner->repositionDeco(this);
}
}
eDecorationType CBordersPlusPlus::getDecorationType() {

View file

@ -9,17 +9,21 @@ class CBordersPlusPlus : public IHyprWindowDecoration {
CBordersPlusPlus(CWindow*);
virtual ~CBordersPlusPlus();
virtual SWindowDecorationExtents getWindowDecorationExtents();
virtual SDecorationPositioningInfo getPositioningInfo();
virtual void draw(CMonitor*, float a, const Vector2D& offset);
virtual void onPositioningReply(const SDecorationPositioningReply& reply);
virtual eDecorationType getDecorationType();
virtual void draw(CMonitor*, float a, const Vector2D& offset);
virtual void updateWindow(CWindow*);
virtual eDecorationType getDecorationType();
virtual void damageEntire();
virtual void updateWindow(CWindow*);
virtual SWindowDecorationExtents getWindowDecorationReservedArea();
virtual void damageEntire();
virtual uint64_t getDecorationFlags();
virtual eDecorationLayer getDecorationLayer();
private:
SWindowDecorationExtents m_seExtents;
@ -28,4 +32,6 @@ class CBordersPlusPlus : public IHyprWindowDecoration {
Vector2D m_vLastWindowPos;
Vector2D m_vLastWindowSize;
double m_fLastThickness = 0;
};

View file

@ -19,7 +19,7 @@ void onNewWindow(void* self, std::any data) {
// data is guaranteed
auto* const PWINDOW = std::any_cast<CWindow*>(data);
HyprlandAPI::addWindowDecoration(PHANDLE, PWINDOW, new CBordersPlusPlus(PWINDOW));
HyprlandAPI::addWindowDecoration(PHANDLE, PWINDOW, std::make_unique<CBordersPlusPlus>(PWINDOW));
}
APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE handle) {
@ -41,6 +41,8 @@ APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE handle) {
HyprlandAPI::addConfigValue(PHANDLE, "plugin:borders-plus-plus:border_size_" + std::to_string(i + 1), SConfigValue{.intValue = -1});
}
HyprlandAPI::reloadConfig();
HyprlandAPI::registerCallbackDynamic(PHANDLE, "openWindow", [&](void* self, SCallbackInfo& info, std::any data) { onNewWindow(self, data); });
// add deco to existing windows
@ -48,11 +50,9 @@ APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE handle) {
if (w->isHidden() || !w->m_bIsMapped)
continue;
HyprlandAPI::addWindowDecoration(PHANDLE, w.get(), new CBordersPlusPlus(w.get()));
HyprlandAPI::addWindowDecoration(PHANDLE, w.get(), std::make_unique<CBordersPlusPlus>(w.get()));
}
HyprlandAPI::reloadConfig();
HyprlandAPI::addNotification(PHANDLE, "[borders-plus-plus] Initialized successfully!", CColor{0.2, 1.0, 0.2, 1.0}, 5000);
return {"borders-plus-plus", "A plugin to add more borders to windows.", "Vaxry", "1.0"};

View file

@ -10,9 +10,7 @@ constexpr int BAR_PADDING = 10;
constexpr int BUTTONS_PAD = 5;
CHyprBar::CHyprBar(CWindow* pWindow) : IHyprWindowDecoration(pWindow) {
m_pWindow = pWindow;
m_vLastWindowPos = pWindow->m_vRealPosition.vec();
m_vLastWindowSize = pWindow->m_vRealSize.vec();
m_pWindow = pWindow;
const auto PMONITOR = g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID);
PMONITOR->scheduledRecalc = true;
@ -31,8 +29,23 @@ CHyprBar::~CHyprBar() {
std::erase(g_pGlobalState->bars, this);
}
SWindowDecorationExtents CHyprBar::getWindowDecorationExtents() {
return m_seExtents;
SDecorationPositioningInfo CHyprBar::getPositioningInfo() {
static auto* const PHEIGHT = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hyprbars:bar_height")->intValue;
SDecorationPositioningInfo info;
info.policy = DECORATION_POSITION_STICKY;
info.edges = DECORATION_EDGE_TOP;
info.priority = 1000;
info.reserved = true;
info.desiredExtents = {{0, *PHEIGHT}, {0, 0}};
return info;
}
void CHyprBar::onPositioningReply(const SDecorationPositioningReply& reply) {
if (reply.assignedGeometry.size() != m_bAssignedBox.size())
m_bWindowSizeChanged = true;
m_bAssignedBox = reply.assignedGeometry;
}
void CHyprBar::onMouseDown(SCallbackInfo& info, wlr_pointer_button_event* e) {
@ -44,7 +57,7 @@ void CHyprBar::onMouseDown(SCallbackInfo& info, wlr_pointer_button_event* e) {
static auto* const PHEIGHT = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hyprbars:bar_height")->intValue;
const auto BORDERSIZE = m_pWindow->getRealBorderSize();
if (!VECINRECT(COORDS, 0, 0, m_vLastWindowSize.x + BORDERSIZE * 2, *PHEIGHT)) {
if (!VECINRECT(COORDS, 0, 0, assignedBoxGlobal().w + BORDERSIZE * 2, *PHEIGHT)) {
if (m_bDraggingThis) {
g_pKeybindManager->m_mDispatchers["mouse"]("0movewindow");
@ -83,7 +96,7 @@ void CHyprBar::onMouseDown(SCallbackInfo& info, wlr_pointer_button_event* e) {
float offset = 0;
for (auto& b : g_pGlobalState->buttons) {
const auto BARBUF = Vector2D{(int)m_vLastWindowSize.x + 2 * BORDERSIZE, *PHEIGHT + BORDERSIZE};
const auto BARBUF = Vector2D{(int)assignedBoxGlobal().w, *PHEIGHT + BORDERSIZE};
Vector2D currentPos = Vector2D{BARBUF.x - 2 * BUTTONS_PAD - b.size - offset, (BARBUF.y - b.size) / 2.0}.floor();
if (VECINRECT(COORDS, currentPos.x, currentPos.y, currentPos.x + b.size + BUTTONS_PAD, currentPos.y + b.size)) {
@ -356,16 +369,17 @@ void CHyprBar::draw(CMonitor* pMonitor, float a, const Vector2D& offset) {
m_seExtents = {{0, *PHEIGHT}, {}};
const auto BARBUF = Vector2D{m_vLastWindowSize.x + 2 * BORDERSIZE, *PHEIGHT} * pMonitor->scale;
const auto DECOBOX = assignedBoxGlobal();
CBox titleBarBox = {m_vLastWindowPos.x - pMonitor->vecPosition.x, m_vLastWindowPos.y - pMonitor->vecPosition.y, m_vLastWindowSize.x,
*PHEIGHT + ROUNDING * 3 /* to fill the bottom cuz we can't disable rounding there */};
const auto BARBUF = DECOBOX.size() * pMonitor->scale;
CBox titleBarBox = {DECOBOX.x - pMonitor->vecPosition.x, DECOBOX.y - pMonitor->vecPosition.y, DECOBOX.w,
DECOBOX.h + ROUNDING * 3 /* to fill the bottom cuz we can't disable rounding there */};
titleBarBox.translate(offset).scale(pMonitor->scale).round();
titleBarBox.x -= scaledBorderSize;
titleBarBox.y -= scaledBorderSize + static_cast<int>(*PHEIGHT * pMonitor->scale);
titleBarBox.w += 2 * scaledBorderSize;
if (titleBarBox.w < 1 || titleBarBox.h < 0)
return;
g_pHyprOpenGL->scissor(&titleBarBox);
@ -380,8 +394,9 @@ void CHyprBar::draw(CMonitor* pMonitor, float a, const Vector2D& offset) {
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
// the +1 is a shit garbage temp fix until renderRect supports an alpha matte
CBox windowBox = {m_vLastWindowPos.x + offset.x - pMonitor->vecPosition.x - BORDERSIZE + 1, m_vLastWindowPos.y + offset.y - pMonitor->vecPosition.y - BORDERSIZE + 1,
m_vLastWindowSize.x + 2 * BORDERSIZE - 2, m_vLastWindowSize.y + 2 * BORDERSIZE - 2};
CBox windowBox = {m_pWindow->m_vRealPosition.vec().x + offset.x - pMonitor->vecPosition.x - BORDERSIZE + 1,
m_pWindow->m_vRealPosition.vec().y + offset.y - pMonitor->vecPosition.y - BORDERSIZE + 1, m_pWindow->m_vRealSize.vec().x + 2 * BORDERSIZE - 2,
m_pWindow->m_vRealSize.vec().y + 2 * BORDERSIZE - 2};
windowBox.scale(pMonitor->scale).round();
g_pHyprOpenGL->renderRect(&windowBox, CColor(0, 0, 0, 0), scaledRounding);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
@ -435,34 +450,15 @@ eDecorationType CHyprBar::getDecorationType() {
}
void CHyprBar::updateWindow(CWindow* pWindow) {
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID);
const auto WORKSPACEOFFSET = PWORKSPACE && !pWindow->m_bPinned ? PWORKSPACE->m_vRenderOffset.vec() : Vector2D();
if (m_vLastWindowSize != pWindow->m_vRealSize.vec())
m_bWindowSizeChanged = true;
m_vLastWindowPos = pWindow->m_vRealPosition.vec() + WORKSPACEOFFSET;
m_vLastWindowSize = pWindow->m_vRealSize.vec();
damageEntire();
}
void CHyprBar::damageEntire() {
CBox dm = {(int)(m_vLastWindowPos.x - m_seExtents.topLeft.x - 2), (int)(m_vLastWindowPos.y - m_seExtents.topLeft.y - 2),
(int)(m_vLastWindowSize.x + m_seExtents.topLeft.x + m_seExtents.bottomRight.x + 4), (int)m_seExtents.topLeft.y + 4};
g_pHyprRenderer->damageBox(&dm);
}
SWindowDecorationExtents CHyprBar::getWindowDecorationReservedArea() {
static auto* const PHEIGHT = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hyprbars:bar_height")->intValue;
return SWindowDecorationExtents{{0, *PHEIGHT}, {}};
; // ignored
}
Vector2D CHyprBar::cursorRelativeToBar() {
static auto* const PHEIGHT = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hyprbars:bar_height")->intValue;
static auto* const PBORDER = &HyprlandAPI::getConfigValue(PHANDLE, "general:border_size")->intValue;
return g_pInputManager->getMouseCoordsInternal() - m_pWindow->m_vRealPosition.vec() + Vector2D{*PBORDER, *PHEIGHT + *PBORDER};
return g_pInputManager->getMouseCoordsInternal() - assignedBoxGlobal().pos();
}
eDecorationLayer CHyprBar::getDecorationLayer() {
@ -471,4 +467,9 @@ eDecorationLayer CHyprBar::getDecorationLayer() {
uint64_t CHyprBar::getDecorationFlags() {
return DECORATION_ALLOWS_MOUSE_INPUT | DECORATION_PART_OF_MAIN_WINDOW;
}
CBox CHyprBar::assignedBoxGlobal() {
CBox box = m_bAssignedBox;
return box.translate(g_pDecorationPositioner->getEdgeDefinedPoint(DECORATION_EDGE_TOP, m_pWindow));
}

View file

@ -11,31 +11,30 @@ class CHyprBar : public IHyprWindowDecoration {
CHyprBar(CWindow*);
virtual ~CHyprBar();
virtual SWindowDecorationExtents getWindowDecorationExtents();
virtual SDecorationPositioningInfo getPositioningInfo();
virtual void draw(CMonitor*, float a, const Vector2D& offset);
virtual void onPositioningReply(const SDecorationPositioningReply& reply);
virtual eDecorationType getDecorationType();
virtual void draw(CMonitor*, float a, const Vector2D& offset);
virtual void updateWindow(CWindow*);
virtual eDecorationType getDecorationType();
virtual void damageEntire();
virtual void updateWindow(CWindow*);
virtual SWindowDecorationExtents getWindowDecorationReservedArea();
virtual void damageEntire();
virtual eDecorationLayer getDecorationLayer();
virtual eDecorationLayer getDecorationLayer();
virtual uint64_t getDecorationFlags();
virtual uint64_t getDecorationFlags();
bool m_bButtonsDirty = true;
bool m_bButtonsDirty = true;
private:
SWindowDecorationExtents m_seExtents;
CWindow* m_pWindow = nullptr;
Vector2D m_vLastWindowPos;
Vector2D m_vLastWindowSize;
CBox m_bAssignedBox;
CTexture m_tTextTex;
CTexture m_tButtonsTex;
@ -50,6 +49,7 @@ class CHyprBar : public IHyprWindowDecoration {
void renderBarButtonsText(CBox* barBox, const float scale, const float a);
void onMouseDown(SCallbackInfo& info, wlr_pointer_button_event* e);
void onMouseMove(Vector2D coords);
CBox assignedBoxGlobal();
HOOK_CALLBACK_FN* m_pMouseButtonCallback;
HOOK_CALLBACK_FN* m_pMouseMoveCallback;

View file

@ -20,9 +20,9 @@ void onNewWindow(void* self, std::any data) {
auto* const PWINDOW = std::any_cast<CWindow*>(data);
if (!PWINDOW->m_bX11DoesntWantBorders) {
CHyprBar* bar = new CHyprBar(PWINDOW);
HyprlandAPI::addWindowDecoration(PHANDLE, PWINDOW, static_cast<IHyprWindowDecoration*>(bar));
g_pGlobalState->bars.push_back(bar);
std::unique_ptr<CHyprBar> bar = std::make_unique<CHyprBar>(PWINDOW);
g_pGlobalState->bars.push_back(bar.get());
HyprlandAPI::addWindowDecoration(PHANDLE, PWINDOW, std::move(bar));
}
}

View file

@ -13,13 +13,15 @@
#include "trail.hpp"
// Do NOT change this function.
APICALL EXPORT std::string PLUGIN_API_VERSION() { return HYPRLAND_API_VERSION; }
APICALL EXPORT std::string PLUGIN_API_VERSION() {
return HYPRLAND_API_VERSION;
}
void onNewWindow(void* self, std::any data) {
// data is guaranteed
auto* const PWINDOW = std::any_cast<CWindow*>(data);
HyprlandAPI::addWindowDecoration(PHANDLE, PWINDOW, new CTrail(PWINDOW));
HyprlandAPI::addWindowDecoration(PHANDLE, PWINDOW, std::make_unique<CTrail>(PWINDOW));
}
GLuint CompileShader(const GLuint& type, std::string src) {
@ -33,7 +35,8 @@ GLuint CompileShader(const GLuint& type, std::string src) {
GLint ok;
glGetShaderiv(shader, GL_COMPILE_STATUS, &ok);
if (ok == GL_FALSE) throw std::runtime_error("compileShader() failed!");
if (ok == GL_FALSE)
throw std::runtime_error("compileShader() failed!");
return shader;
}
@ -41,11 +44,13 @@ GLuint CompileShader(const GLuint& type, std::string src) {
GLuint CreateProgram(const std::string& vert, const std::string& frag) {
auto vertCompiled = CompileShader(GL_VERTEX_SHADER, vert);
if (!vertCompiled) throw std::runtime_error("Compiling vshader failed.");
if (!vertCompiled)
throw std::runtime_error("Compiling vshader failed.");
auto fragCompiled = CompileShader(GL_FRAGMENT_SHADER, frag);
if (!fragCompiled) throw std::runtime_error("Compiling fshader failed.");
if (!fragCompiled)
throw std::runtime_error("Compiling fshader failed.");
auto prog = glCreateProgram();
glAttachShader(prog, vertCompiled);
@ -60,7 +65,8 @@ GLuint CreateProgram(const std::string& vert, const std::string& frag) {
GLint ok;
glGetProgramiv(prog, GL_LINK_STATUS, &ok);
if (ok == GL_FALSE) throw std::runtime_error("createProgram() failed! GL_LINK_STATUS not OK!");
if (ok == GL_FALSE)
throw std::runtime_error("createProgram() failed! GL_LINK_STATUS not OK!");
return prog;
}
@ -75,21 +81,19 @@ int onTick(void* data) {
}
void initGlobal() {
RASSERT(
eglMakeCurrent(wlr_egl_get_display(g_pCompositor->m_sWLREGL), EGL_NO_SURFACE, EGL_NO_SURFACE, wlr_egl_get_context(g_pCompositor->m_sWLREGL)),
"Couldn't set current EGL!");
RASSERT(eglMakeCurrent(wlr_egl_get_display(g_pCompositor->m_sWLREGL), EGL_NO_SURFACE, EGL_NO_SURFACE, wlr_egl_get_context(g_pCompositor->m_sWLREGL)),
"Couldn't set current EGL!");
GLuint prog = CreateProgram(QUADTRAIL, FRAGTRAIL);
g_pGlobalState->trailShader.program = prog;
g_pGlobalState->trailShader.proj = glGetUniformLocation(prog, "proj");
g_pGlobalState->trailShader.tex = glGetUniformLocation(prog, "tex");
g_pGlobalState->trailShader.color = glGetUniformLocation(prog, "color");
GLuint prog = CreateProgram(QUADTRAIL, FRAGTRAIL);
g_pGlobalState->trailShader.program = prog;
g_pGlobalState->trailShader.proj = glGetUniformLocation(prog, "proj");
g_pGlobalState->trailShader.tex = glGetUniformLocation(prog, "tex");
g_pGlobalState->trailShader.color = glGetUniformLocation(prog, "color");
g_pGlobalState->trailShader.texAttrib = glGetAttribLocation(prog, "colors");
g_pGlobalState->trailShader.posAttrib = glGetAttribLocation(prog, "pos");
g_pGlobalState->trailShader.gradient = glGetUniformLocation(prog, "snapshots");
g_pGlobalState->trailShader.gradient = glGetUniformLocation(prog, "snapshots");
RASSERT(eglMakeCurrent(wlr_egl_get_display(g_pCompositor->m_sWLREGL), EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT),
"Couldn't unset current EGL!");
RASSERT(eglMakeCurrent(wlr_egl_get_display(g_pCompositor->m_sWLREGL), EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT), "Couldn't unset current EGL!");
g_pGlobalState->tick = wl_event_loop_add_timer(g_pCompositor->m_sWLEventLoop, &onTick, nullptr);
wl_event_source_timer_update(g_pGlobalState->tick, 1);
@ -101,8 +105,8 @@ APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE handle) {
const std::string HASH = __hyprland_api_get_hash();
if (HASH != GIT_COMMIT_HASH) {
HyprlandAPI::addNotification(PHANDLE, "[ht] Failure in initialization: Version mismatch (headers ver is not equal to running hyprland ver)",
CColor{1.0, 0.2, 0.2, 1.0}, 5000);
HyprlandAPI::addNotification(PHANDLE, "[ht] Failure in initialization: Version mismatch (headers ver is not equal to running hyprland ver)", CColor{1.0, 0.2, 0.2, 1.0},
5000);
throw std::runtime_error("[ht] Version mismatch");
}
@ -119,9 +123,10 @@ APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE handle) {
// add deco to existing windows
for (auto& w : g_pCompositor->m_vWindows) {
if (w->isHidden() || !w->m_bIsMapped) continue;
if (w->isHidden() || !w->m_bIsMapped)
continue;
HyprlandAPI::addWindowDecoration(PHANDLE, w.get(), new CTrail(w.get()));
HyprlandAPI::addWindowDecoration(PHANDLE, w.get(), std::make_unique<CTrail>(w.get()));
}
HyprlandAPI::reloadConfig();
@ -131,4 +136,6 @@ APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE handle) {
return {"hyprtrails", "A plugin to add trails behind moving windows", "Vaxry", "1.0"};
}
APICALL EXPORT void PLUGIN_EXIT() { wl_event_source_remove(g_pGlobalState->tick); }
APICALL EXPORT void PLUGIN_EXIT() {
wl_event_source_remove(g_pGlobalState->tick);
}

View file

@ -39,12 +39,12 @@ CTrail::~CTrail() {
g_pHookSystem->unhook(pTickCb);
}
SWindowDecorationExtents CTrail::getWindowDecorationExtents() {
return m_seExtents;
SDecorationPositioningInfo CTrail::getPositioningInfo() {
return {DECORATION_POSITION_ABSOLUTE};
}
SWindowDecorationExtents CTrail::getWindowDecorationReservedArea() {
return m_seExtents;
void CTrail::onPositioningReply(const SDecorationPositioningReply& reply) {
; // ignored
}
void scaleBox2(box& box, float coeff) {

View file

@ -33,17 +33,17 @@ class CTrail : public IHyprWindowDecoration {
CTrail(CWindow*);
virtual ~CTrail();
virtual SWindowDecorationExtents getWindowDecorationExtents();
virtual SDecorationPositioningInfo getPositioningInfo();
virtual void draw(CMonitor*, float a, const Vector2D& offset);
virtual void onPositioningReply(const SDecorationPositioningReply& reply);
virtual eDecorationType getDecorationType();
virtual void draw(CMonitor*, float a, const Vector2D& offset);
virtual void updateWindow(CWindow*);
virtual eDecorationType getDecorationType();
virtual void damageEntire();
virtual void updateWindow(CWindow*);
virtual SWindowDecorationExtents getWindowDecorationReservedArea();
virtual void damageEntire();
private:
HOOK_CALLBACK_FN* pTickCb = nullptr;