mirror of
https://github.com/hyprwm/hyprland-plugins.git
synced 2026-05-07 11:18:01 +02:00
expo: add a scroll overview
This commit is contained in:
parent
4d940a10af
commit
47e62717ea
9 changed files with 544 additions and 26 deletions
|
|
@ -12,7 +12,7 @@ void CExpoGesture::begin(const ITrackpadGesture::STrackpadGestureBegin& e) {
|
|||
m_firstUpdate = true;
|
||||
|
||||
if (!g_pOverview)
|
||||
g_pOverview = std::make_unique<COverview>(g_pCompositor->m_lastMonitor->m_activeWorkspace);
|
||||
g_pOverview = makeShared<COverview>(g_pCompositor->m_lastMonitor->m_activeWorkspace);
|
||||
else {
|
||||
g_pOverview->selectHoveredWorkspace();
|
||||
g_pOverview->setClosing(true);
|
||||
|
|
|
|||
32
hyprexpo/IOverview.hpp
Normal file
32
hyprexpo/IOverview.hpp
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
#pragma once
|
||||
#include <hyprland/src/helpers/memory/Memory.hpp>
|
||||
|
||||
class IOverview {
|
||||
public:
|
||||
IOverview() = default;
|
||||
virtual ~IOverview() = default;
|
||||
|
||||
virtual void render() = 0;
|
||||
virtual void damage() = 0;
|
||||
virtual void onDamageReported() = 0;
|
||||
virtual void onPreRender() = 0;
|
||||
|
||||
virtual void setClosing(bool closing) = 0;
|
||||
|
||||
virtual void resetSwipe() = 0;
|
||||
virtual void onSwipeUpdate(double delta) = 0;
|
||||
virtual void onSwipeEnd() = 0;
|
||||
|
||||
virtual void close() = 0;
|
||||
virtual void selectHoveredWorkspace() = 0;
|
||||
|
||||
virtual void fullRender() = 0;
|
||||
|
||||
bool blockOverviewRendering = false;
|
||||
bool blockDamageReporting = false;
|
||||
|
||||
PHLMONITORREF pMonitor;
|
||||
bool m_isSwiping = false;
|
||||
};
|
||||
|
||||
inline SP<IOverview> g_pOverview;
|
||||
|
|
@ -6,6 +6,6 @@ else
|
|||
endif
|
||||
|
||||
all:
|
||||
$(CXX) -shared -fPIC $(EXTRA_FLAGS) main.cpp overview.cpp ExpoGesture.cpp OverviewPassElement.cpp -o hyprexpo.so -g `pkg-config --cflags pixman-1 libdrm hyprland pangocairo libinput libudev wayland-server xkbcommon` -std=c++2b -Wno-narrowing
|
||||
$(CXX) -shared -fPIC $(EXTRA_FLAGS) main.cpp overview.cpp ExpoGesture.cpp OverviewPassElement.cpp scrollOverview.cpp -o hyprexpo.so -g `pkg-config --cflags pixman-1 libdrm hyprland pangocairo libinput libudev wayland-server xkbcommon` -std=c++2b -Wno-narrowing
|
||||
clean:
|
||||
rm ./hyprexpo.so
|
||||
|
|
|
|||
|
|
@ -2,4 +2,5 @@
|
|||
|
||||
#include <hyprland/src/plugins/PluginAPI.hpp>
|
||||
|
||||
inline HANDLE PHANDLE = nullptr;
|
||||
inline HANDLE PHANDLE = nullptr;
|
||||
inline bool IS_SCROLLING = false;
|
||||
|
|
@ -9,12 +9,14 @@
|
|||
#include <hyprland/src/render/Renderer.hpp>
|
||||
#include <hyprland/src/managers/input/trackpad/GestureTypes.hpp>
|
||||
#include <hyprland/src/managers/input/trackpad/TrackpadGestures.hpp>
|
||||
#include <hyprland/src/managers/LayoutManager.hpp>
|
||||
|
||||
#include <hyprutils/string/ConstVarList.hpp>
|
||||
using namespace Hyprutils::String;
|
||||
|
||||
#include "globals.hpp"
|
||||
#include "overview.hpp"
|
||||
#include "scrollOverview.hpp"
|
||||
#include "ExpoGesture.hpp"
|
||||
|
||||
// Methods
|
||||
|
|
@ -66,6 +68,8 @@ static void hkAddDamageB(void* thisptr, const pixman_region32_t* rg) {
|
|||
|
||||
static SDispatchResult onExpoDispatcher(std::string arg) {
|
||||
|
||||
IS_SCROLLING = g_pLayoutManager->getCurrentLayout()->getLayoutName() == "scrolling";
|
||||
|
||||
if (g_pOverview && g_pOverview->m_isSwiping)
|
||||
return {.success = false, .error = "already swiping"};
|
||||
|
||||
|
|
@ -81,7 +85,10 @@ static SDispatchResult onExpoDispatcher(std::string arg) {
|
|||
g_pOverview->close();
|
||||
else {
|
||||
renderingOverview = true;
|
||||
g_pOverview = std::make_unique<COverview>(g_pCompositor->m_lastMonitor->m_activeWorkspace);
|
||||
if (IS_SCROLLING)
|
||||
g_pOverview = makeShared<CScrollOverview>(g_pCompositor->m_lastMonitor->m_activeWorkspace);
|
||||
else
|
||||
makeShared<COverview>(g_pCompositor->m_lastMonitor->m_activeWorkspace);
|
||||
renderingOverview = false;
|
||||
}
|
||||
return {};
|
||||
|
|
@ -97,7 +104,10 @@ static SDispatchResult onExpoDispatcher(std::string arg) {
|
|||
return {};
|
||||
|
||||
renderingOverview = true;
|
||||
g_pOverview = std::make_unique<COverview>(g_pCompositor->m_lastMonitor->m_activeWorkspace);
|
||||
if (IS_SCROLLING)
|
||||
g_pOverview = makeShared<CScrollOverview>(g_pCompositor->m_lastMonitor->m_activeWorkspace);
|
||||
else
|
||||
makeShared<COverview>(g_pCompositor->m_lastMonitor->m_activeWorkspace);
|
||||
renderingOverview = false;
|
||||
return {};
|
||||
}
|
||||
|
|
@ -107,7 +117,7 @@ static void failNotif(const std::string& reason) {
|
|||
}
|
||||
|
||||
static Hyprlang::CParseResult expoGestureKeyword(const char* LHS, const char* RHS) {
|
||||
Hyprlang::CParseResult result;
|
||||
Hyprlang::CParseResult result;
|
||||
|
||||
if (g_unloading)
|
||||
return result;
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#include <hyprland/src/managers/animation/AnimationManager.hpp>
|
||||
#include <hyprland/src/managers/animation/DesktopAnimationManager.hpp>
|
||||
#include <hyprland/src/managers/input/InputManager.hpp>
|
||||
#include <hyprland/src/managers/LayoutManager.hpp>
|
||||
#include <hyprland/src/helpers/time/Time.hpp>
|
||||
#undef private
|
||||
#include "OverviewPassElement.hpp"
|
||||
|
|
|
|||
|
|
@ -9,43 +9,40 @@
|
|||
#include <hyprland/src/managers/HookSystemManager.hpp>
|
||||
#include <vector>
|
||||
|
||||
#include "IOverview.hpp"
|
||||
|
||||
// saves on resources, but is a bit broken rn with blur.
|
||||
// hyprland's fault, but cba to fix.
|
||||
constexpr bool ENABLE_LOWRES = false;
|
||||
|
||||
class CMonitor;
|
||||
|
||||
class COverview {
|
||||
class COverview : public IOverview {
|
||||
public:
|
||||
COverview(PHLWORKSPACE startedOn_, bool swipe = false);
|
||||
~COverview();
|
||||
virtual ~COverview();
|
||||
|
||||
void render();
|
||||
void damage();
|
||||
void onDamageReported();
|
||||
void onPreRender();
|
||||
virtual void render();
|
||||
virtual void damage();
|
||||
virtual void onDamageReported();
|
||||
virtual void onPreRender();
|
||||
|
||||
void setClosing(bool closing);
|
||||
virtual void setClosing(bool closing);
|
||||
|
||||
void resetSwipe();
|
||||
void onSwipeUpdate(double delta);
|
||||
void onSwipeEnd();
|
||||
virtual void resetSwipe();
|
||||
virtual void onSwipeUpdate(double delta);
|
||||
virtual void onSwipeEnd();
|
||||
|
||||
// close without a selection
|
||||
void close();
|
||||
void selectHoveredWorkspace();
|
||||
virtual void close();
|
||||
virtual void selectHoveredWorkspace();
|
||||
|
||||
bool blockOverviewRendering = false;
|
||||
bool blockDamageReporting = false;
|
||||
|
||||
PHLMONITORREF pMonitor;
|
||||
bool m_isSwiping = false;
|
||||
virtual void fullRender();
|
||||
|
||||
private:
|
||||
void redrawID(int id, bool forcelowres = false);
|
||||
void redrawAll(bool forcelowres = false);
|
||||
void onWorkspaceChange();
|
||||
void fullRender();
|
||||
|
||||
int SIDE_LENGTH = 3;
|
||||
int GAP_WIDTH = 5;
|
||||
|
|
@ -84,5 +81,3 @@ class COverview {
|
|||
|
||||
friend class COverviewPassElement;
|
||||
};
|
||||
|
||||
inline std::unique_ptr<COverview> g_pOverview;
|
||||
|
|
|
|||
393
hyprexpo/scrollOverview.cpp
Normal file
393
hyprexpo/scrollOverview.cpp
Normal file
|
|
@ -0,0 +1,393 @@
|
|||
#include "scrollOverview.hpp"
|
||||
#include <any>
|
||||
#define private public
|
||||
#include <hyprland/src/render/Renderer.hpp>
|
||||
#include <hyprland/src/Compositor.hpp>
|
||||
#include <hyprland/src/config/ConfigValue.hpp>
|
||||
#include <hyprland/src/config/ConfigManager.hpp>
|
||||
#include <hyprland/src/managers/animation/AnimationManager.hpp>
|
||||
#include <hyprland/src/managers/animation/DesktopAnimationManager.hpp>
|
||||
#include <hyprland/src/managers/input/InputManager.hpp>
|
||||
#include <hyprland/src/managers/LayoutManager.hpp>
|
||||
#include <hyprland/src/helpers/time/Time.hpp>
|
||||
#undef private
|
||||
#include "OverviewPassElement.hpp"
|
||||
|
||||
static void damageMonitor(WP<Hyprutils::Animation::CBaseAnimatedVariable> thisptr) {
|
||||
g_pOverview->damage();
|
||||
}
|
||||
|
||||
static void removeOverview(WP<Hyprutils::Animation::CBaseAnimatedVariable> thisptr) {
|
||||
g_pOverview.reset();
|
||||
}
|
||||
|
||||
CScrollOverview::~CScrollOverview() {
|
||||
g_pHyprRenderer->makeEGLCurrent();
|
||||
images.clear(); // otherwise we get a vram leak
|
||||
g_pInputManager->unsetCursorImage();
|
||||
g_pHyprOpenGL->markBlurDirtyForMonitor(pMonitor.lock());
|
||||
}
|
||||
|
||||
CScrollOverview::CScrollOverview(PHLWORKSPACE startedOn_, bool swipe_) : startedOn(startedOn_), swipe(swipe_) {
|
||||
const auto PMONITOR = g_pCompositor->m_lastMonitor.lock();
|
||||
pMonitor = PMONITOR;
|
||||
|
||||
for (const auto& w : g_pCompositor->getWorkspaces()) {
|
||||
if (w && w->m_monitor == pMonitor && !w->m_isSpecialWorkspace)
|
||||
images.emplace_back(makeShared<SWorkspaceImage>(w.lock()));
|
||||
}
|
||||
|
||||
std::sort(images.begin(), images.end(), [](const auto& a, const auto& b) { return a->pWorkspace->m_id < b->pWorkspace->m_id; });
|
||||
|
||||
g_pAnimationManager->createAnimation(1.F, scale, g_pConfigManager->getAnimationPropertyConfig("windowsMove"), AVARDAMAGE_NONE);
|
||||
g_pAnimationManager->createAnimation({}, viewOffset, g_pConfigManager->getAnimationPropertyConfig("windowsMove"), AVARDAMAGE_NONE);
|
||||
|
||||
scale->setUpdateCallback(damageMonitor);
|
||||
viewOffset->setUpdateCallback(damageMonitor);
|
||||
|
||||
if (!swipe)
|
||||
*scale = 0.5F;
|
||||
|
||||
lastMousePosLocal = g_pInputManager->getMouseCoordsInternal() - pMonitor->m_position;
|
||||
|
||||
auto onCursorMove = [this](void* self, SCallbackInfo& info, std::any param) {
|
||||
if (closing)
|
||||
return;
|
||||
|
||||
info.cancelled = true;
|
||||
lastMousePosLocal = g_pInputManager->getMouseCoordsInternal() - pMonitor->m_position;
|
||||
|
||||
// highlightHoverDebug();
|
||||
};
|
||||
|
||||
auto onCursorSelect = [this](void* self, SCallbackInfo& info, std::any param) {
|
||||
if (closing)
|
||||
return;
|
||||
|
||||
info.cancelled = true;
|
||||
|
||||
selectHoveredWorkspace();
|
||||
|
||||
close();
|
||||
};
|
||||
|
||||
auto onMouseAxis = [this](void* self, SCallbackInfo& info, std::any param) {
|
||||
if (closing)
|
||||
return;
|
||||
|
||||
info.cancelled = true;
|
||||
|
||||
auto data = std::any_cast<std::unordered_map<std::string, std::any>>(param);
|
||||
auto e = std::any_cast<IPointer::SAxisEvent>(data["event"]);
|
||||
|
||||
const auto VAL = std::clamp(sc<float>(scale->value() + e.delta / -500.F), 0.05F, 0.95F);
|
||||
*scale = VAL;
|
||||
};
|
||||
|
||||
mouseMoveHook = g_pHookSystem->hookDynamic("mouseMove", onCursorMove);
|
||||
touchMoveHook = g_pHookSystem->hookDynamic("touchMove", onCursorMove);
|
||||
mouseAxisHook = g_pHookSystem->hookDynamic("mouseAxis", onMouseAxis);
|
||||
|
||||
mouseButtonHook = g_pHookSystem->hookDynamic("mouseButton", onCursorSelect);
|
||||
touchDownHook = g_pHookSystem->hookDynamic("touchDown", onCursorSelect);
|
||||
|
||||
g_pInputManager->setCursorImageUntilUnset("left_ptr");
|
||||
|
||||
redrawAll();
|
||||
}
|
||||
|
||||
void CScrollOverview::selectHoveredWorkspace() {
|
||||
size_t activeIdx = 0;
|
||||
for (size_t i = 0; i < images.size(); ++i) {
|
||||
if (images[i]->pWorkspace && images[i]->pWorkspace == startedOn) {
|
||||
activeIdx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const auto VIEWPORT_CENTER = CBox{{}, pMonitor->m_size}.middle();
|
||||
|
||||
float yoff = -(float)activeIdx * pMonitor->m_size.y * scale->value();
|
||||
bool found = false;
|
||||
for (const auto& wimg : images) {
|
||||
for (const auto& img : wimg->windowImages) {
|
||||
CBox texbox = {img->pWindow->m_realPosition->value() - pMonitor->m_position, img->pWindow->m_realSize->value()};
|
||||
|
||||
// scale the box to the viewport center
|
||||
texbox.translate(-VIEWPORT_CENTER).scale(scale->value()).translate(VIEWPORT_CENTER).translate(-viewOffset->value() * scale->value());
|
||||
|
||||
texbox.translate({0.F, yoff});
|
||||
|
||||
// texbox.scale(pMonitor->m_scale).round();
|
||||
|
||||
if (texbox.containsPoint(lastMousePosLocal)) {
|
||||
closeOnWindow = img->pWindow;
|
||||
// *viewOffset = CBox{img->pWindow->m_realPosition->value(), img->pWindow->m_realSize->value()}.translate({0.F, yoff / scale->value()}).middle() -
|
||||
// CBox{pMonitor->m_position, pMonitor->m_size}.middle();
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found)
|
||||
break;
|
||||
yoff += pMonitor->m_size.y * scale->value();
|
||||
}
|
||||
}
|
||||
|
||||
void CScrollOverview::highlightHoverDebug() {
|
||||
size_t activeIdx = 0;
|
||||
for (size_t i = 0; i < images.size(); ++i) {
|
||||
if (images[i]->pWorkspace && images[i]->pWorkspace == startedOn) {
|
||||
activeIdx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const auto VIEWPORT_CENTER = CBox{{}, pMonitor->m_size}.middle();
|
||||
|
||||
float yoff = -(float)activeIdx * pMonitor->m_size.y * scale->value();
|
||||
for (const auto& wimg : images) {
|
||||
for (const auto& img : wimg->windowImages) {
|
||||
CBox texbox = {img->pWindow->m_realPosition->value() - pMonitor->m_position, img->pWindow->m_realSize->value()};
|
||||
|
||||
// scale the box to the viewport center
|
||||
texbox.translate(-VIEWPORT_CENTER).scale(scale->value()).translate(VIEWPORT_CENTER).translate(-viewOffset->value() * scale->value());
|
||||
|
||||
texbox.translate({0.F, yoff});
|
||||
|
||||
// texbox.scale(pMonitor->m_scale).round();
|
||||
|
||||
if (texbox.containsPoint(lastMousePosLocal)) {
|
||||
img->highlight = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
img->highlight = false;
|
||||
}
|
||||
yoff += pMonitor->m_size.y * scale->value();
|
||||
}
|
||||
}
|
||||
|
||||
SP<CScrollOverview::SWorkspaceImage> CScrollOverview::imageForWorkspace(PHLWORKSPACE w) {
|
||||
for (const auto& i : images) {
|
||||
if (i->pWorkspace == w)
|
||||
return i;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void CScrollOverview::redrawWorkspace(PHLWORKSPACE workspace, bool forcelowres) {
|
||||
if (pMonitor->m_activeWorkspace != startedOn && !closing) {
|
||||
// likely user changed.
|
||||
onWorkspaceChange();
|
||||
}
|
||||
|
||||
blockOverviewRendering = true;
|
||||
|
||||
g_pHyprRenderer->makeEGLCurrent();
|
||||
|
||||
auto image = imageForWorkspace(workspace);
|
||||
|
||||
if (!image)
|
||||
return;
|
||||
|
||||
// get all tiled windows on the workspace and max dim
|
||||
// TODO: float
|
||||
std::vector<PHLWINDOW> windows;
|
||||
for (const auto& w : g_pCompositor->m_windows) {
|
||||
if (!validMapped(w) || w->m_isFloating || w->m_workspace != workspace)
|
||||
continue;
|
||||
windows.emplace_back(w);
|
||||
}
|
||||
|
||||
for (const auto& w : windows) {
|
||||
auto img = image->windowImages.emplace_back(makeShared<SWindowImage>());
|
||||
img->pWindow = w;
|
||||
img->fb.alloc(pMonitor->m_pixelSize.x, pMonitor->m_pixelSize.y, pMonitor->m_output->state->state().drmFormat);
|
||||
|
||||
CRegion fakeDamage{0, 0, INT16_MAX, INT16_MAX};
|
||||
g_pHyprRenderer->beginRender(pMonitor.lock(), fakeDamage, RENDER_MODE_FULL_FAKE, nullptr, &img->fb);
|
||||
|
||||
g_pHyprOpenGL->clear(CHyprColor{0, 0, 0, 0});
|
||||
|
||||
g_pHyprRenderer->renderWindow(w, pMonitor.lock(), Time::steadyNow(), true, RENDER_PASS_ALL, true, true);
|
||||
|
||||
g_pHyprOpenGL->m_renderData.blockScreenShader = true;
|
||||
g_pHyprRenderer->endRender();
|
||||
}
|
||||
|
||||
blockOverviewRendering = false;
|
||||
}
|
||||
|
||||
void CScrollOverview::redrawAll(bool forcelowres) {
|
||||
|
||||
for (const auto& img : images) {
|
||||
redrawWorkspace(img->pWorkspace);
|
||||
}
|
||||
|
||||
// redraw bg
|
||||
if (backgroundFb.m_size != pMonitor->m_pixelSize) {
|
||||
backgroundFb.release();
|
||||
backgroundFb.alloc(pMonitor->m_pixelSize.x, pMonitor->m_pixelSize.y, pMonitor->m_output->state->state().drmFormat);
|
||||
}
|
||||
|
||||
CRegion fakeDamage{0, 0, INT16_MAX, INT16_MAX};
|
||||
g_pHyprRenderer->beginRender(pMonitor.lock(), fakeDamage, RENDER_MODE_FULL_FAKE, nullptr, &backgroundFb);
|
||||
|
||||
g_pHyprOpenGL->clear(CHyprColor{0, 0, 0, 1.0});
|
||||
|
||||
g_pHyprRenderer->renderAllClientsForWorkspace(pMonitor.lock(), nullptr, Time::steadyNow());
|
||||
|
||||
g_pHyprOpenGL->m_renderData.blockScreenShader = true;
|
||||
g_pHyprRenderer->endRender();
|
||||
}
|
||||
|
||||
void CScrollOverview::damage() {
|
||||
blockDamageReporting = true;
|
||||
g_pHyprRenderer->damageMonitor(pMonitor.lock());
|
||||
blockDamageReporting = false;
|
||||
}
|
||||
|
||||
void CScrollOverview::onDamageReported() {
|
||||
; // TODO:
|
||||
}
|
||||
|
||||
void CScrollOverview::close() {
|
||||
|
||||
if (closing)
|
||||
return;
|
||||
|
||||
closing = true;
|
||||
|
||||
if (!closeOnWindow)
|
||||
closeOnWindow = g_pCompositor->m_lastWindow;
|
||||
|
||||
if (closeOnWindow == g_pCompositor->m_lastWindow)
|
||||
*viewOffset = Vector2D{};
|
||||
else {
|
||||
|
||||
if (closeOnWindow->m_workspace != pMonitor->m_activeWorkspace) {
|
||||
g_pDesktopAnimationManager->startAnimation(pMonitor->m_activeWorkspace, CDesktopAnimationManager::ANIMATION_TYPE_OUT, true, true);
|
||||
g_pDesktopAnimationManager->startAnimation(closeOnWindow->m_workspace, CDesktopAnimationManager::ANIMATION_TYPE_IN, false, true);
|
||||
pMonitor->changeWorkspace(closeOnWindow->m_workspace, true, true, true);
|
||||
}
|
||||
|
||||
g_pCompositor->focusWindow(closeOnWindow.lock());
|
||||
|
||||
size_t activeIdx = 0;
|
||||
for (size_t i = 0; i < images.size(); ++i) {
|
||||
if (images[i]->pWorkspace && images[i]->pWorkspace == startedOn) {
|
||||
activeIdx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
float yoff = -(float)activeIdx * pMonitor->m_size.y * scale->value();
|
||||
bool found = false;
|
||||
for (const auto& wimg : images) {
|
||||
for (const auto& img : wimg->windowImages) {
|
||||
if (img->pWindow == closeOnWindow && closeOnWindow) {
|
||||
Vector2D middleOfWindow = CBox{img->pWindow->m_realPosition->value(), img->pWindow->m_realSize->value()}.translate({0.F, yoff / scale->value()}).middle() -
|
||||
CBox{pMonitor->m_position, pMonitor->m_size}.middle();
|
||||
|
||||
// we need to do this because the window doesnt have to be centered after click
|
||||
*viewOffset = middleOfWindow +
|
||||
(CBox{pMonitor->m_position, pMonitor->m_size}.middle() - CBox{img->pWindow->m_realPosition->value(), img->pWindow->m_realSize->value()}.middle());
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found)
|
||||
break;
|
||||
yoff += pMonitor->m_size.y * scale->value();
|
||||
}
|
||||
}
|
||||
|
||||
*scale = 1.F;
|
||||
|
||||
scale->setCallbackOnEnd(removeOverview);
|
||||
}
|
||||
|
||||
void CScrollOverview::onPreRender() {
|
||||
;
|
||||
}
|
||||
|
||||
void CScrollOverview::onWorkspaceChange() {
|
||||
; // TODO:
|
||||
}
|
||||
|
||||
void CScrollOverview::render() {
|
||||
g_pHyprRenderer->m_renderPass.add(makeUnique<COverviewPassElement>());
|
||||
}
|
||||
|
||||
void CScrollOverview::fullRender() {
|
||||
|
||||
g_pHyprOpenGL->clear(CHyprColor{0, 0, 0, 1});
|
||||
|
||||
CBox texbox = {{}, pMonitor->m_size};
|
||||
texbox.scale(pMonitor->m_scale);
|
||||
texbox.round();
|
||||
CRegion damage{0, 0, INT16_MAX, INT16_MAX};
|
||||
g_pHyprOpenGL->renderTextureInternal(backgroundFb.getTexture(), texbox, {.damage = &damage, .a = 1.0});
|
||||
|
||||
const auto VIEWPORT_CENTER = CBox{{}, pMonitor->m_size}.middle();
|
||||
|
||||
size_t activeIdx = 0;
|
||||
for (size_t i = 0; i < images.size(); ++i) {
|
||||
if (images[i]->pWorkspace && images[i]->pWorkspace == startedOn) {
|
||||
activeIdx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// render all views
|
||||
float yoff = -(float)activeIdx * pMonitor->m_size.y * scale->value();
|
||||
for (const auto& wimg : images) {
|
||||
for (const auto& img : wimg->windowImages) {
|
||||
CBox texbox = CBox{img->pWindow->m_realPosition->value() - pMonitor->m_position, pMonitor->m_size};
|
||||
|
||||
// scale the box to the viewport center
|
||||
texbox.translate(-VIEWPORT_CENTER).scale(scale->value()).translate(VIEWPORT_CENTER).translate(-viewOffset->value() * scale->value());
|
||||
|
||||
texbox.translate({0.F, yoff});
|
||||
|
||||
texbox.scale(pMonitor->m_scale).round();
|
||||
CRegion damage{0, 0, INT16_MAX, INT16_MAX};
|
||||
g_pHyprOpenGL->renderTextureInternal(img->fb.getTexture(), texbox, {.damage = &damage, .a = 1.0});
|
||||
|
||||
if (img->highlight) {
|
||||
CBox texbox2 = CBox{img->pWindow->m_realPosition->value(), img->pWindow->m_realSize->value()}
|
||||
.translate(-VIEWPORT_CENTER)
|
||||
.scale(scale->value())
|
||||
.translate(VIEWPORT_CENTER)
|
||||
.translate({0.F, yoff});
|
||||
g_pHyprOpenGL->renderRect(texbox2, CHyprColor{0.5, 0.0, 0.0, 0.5}, CHyprOpenGLImpl::SRectRenderData{.round = 5});
|
||||
}
|
||||
}
|
||||
yoff += pMonitor->m_size.y * scale->value();
|
||||
}
|
||||
}
|
||||
|
||||
static float lerp(const float& from, const float& to, const float perc) {
|
||||
return (to - from) * perc + from;
|
||||
}
|
||||
|
||||
static Vector2D lerp(const Vector2D& from, const Vector2D& to, const float perc) {
|
||||
return Vector2D{lerp(from.x, to.x, perc), lerp(from.y, to.y, perc)};
|
||||
}
|
||||
|
||||
void CScrollOverview::setClosing(bool closing_) {
|
||||
// TODO:
|
||||
}
|
||||
|
||||
void CScrollOverview::resetSwipe() {
|
||||
// TODO:
|
||||
}
|
||||
|
||||
void CScrollOverview::onSwipeUpdate(double delta) {
|
||||
// TODO:
|
||||
}
|
||||
|
||||
void CScrollOverview::onSwipeEnd() {
|
||||
// TODO:
|
||||
}
|
||||
86
hyprexpo/scrollOverview.hpp
Normal file
86
hyprexpo/scrollOverview.hpp
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
#pragma once
|
||||
|
||||
#define WLR_USE_UNSTABLE
|
||||
|
||||
#include "globals.hpp"
|
||||
#include <hyprland/src/desktop/DesktopTypes.hpp>
|
||||
#include <hyprland/src/render/Framebuffer.hpp>
|
||||
#include <hyprland/src/helpers/AnimatedVariable.hpp>
|
||||
#include <hyprland/src/managers/HookSystemManager.hpp>
|
||||
#include <vector>
|
||||
|
||||
#include "IOverview.hpp"
|
||||
|
||||
class CMonitor;
|
||||
|
||||
class CScrollOverview : public IOverview {
|
||||
public:
|
||||
CScrollOverview(PHLWORKSPACE startedOn_, bool swipe = false);
|
||||
virtual ~CScrollOverview();
|
||||
|
||||
virtual void render();
|
||||
virtual void damage();
|
||||
virtual void onDamageReported();
|
||||
virtual void onPreRender();
|
||||
|
||||
virtual void setClosing(bool closing);
|
||||
|
||||
virtual void resetSwipe();
|
||||
virtual void onSwipeUpdate(double delta);
|
||||
virtual void onSwipeEnd();
|
||||
|
||||
// close without a selection
|
||||
virtual void close();
|
||||
virtual void selectHoveredWorkspace();
|
||||
|
||||
virtual void fullRender();
|
||||
|
||||
private:
|
||||
void redrawWorkspace(PHLWORKSPACE w, bool forcelowres = false);
|
||||
void redrawAll(bool forcelowres = false);
|
||||
void onWorkspaceChange();
|
||||
void highlightHoverDebug();
|
||||
|
||||
bool damageDirty = false;
|
||||
|
||||
struct SWindowImage {
|
||||
PHLWINDOWREF pWindow;
|
||||
CFramebuffer fb;
|
||||
bool highlight = false;
|
||||
};
|
||||
|
||||
struct SWorkspaceImage {
|
||||
PHLWORKSPACE pWorkspace;
|
||||
CBox box;
|
||||
std::vector<SP<SWindowImage>> windowImages;
|
||||
};
|
||||
|
||||
CFramebuffer backgroundFb;
|
||||
|
||||
Vector2D lastMousePosLocal = Vector2D{};
|
||||
|
||||
PHLWINDOWREF closeOnWindow;
|
||||
|
||||
std::vector<SP<SWorkspaceImage>> images;
|
||||
SP<SWorkspaceImage> imageForWorkspace(PHLWORKSPACE w);
|
||||
|
||||
PHLWORKSPACE startedOn;
|
||||
|
||||
PHLANIMVAR<float> scale;
|
||||
PHLANIMVAR<Vector2D> viewOffset;
|
||||
|
||||
bool closing = false;
|
||||
|
||||
SP<HOOK_CALLBACK_FN> mouseMoveHook;
|
||||
SP<HOOK_CALLBACK_FN> mouseButtonHook;
|
||||
SP<HOOK_CALLBACK_FN> touchMoveHook;
|
||||
SP<HOOK_CALLBACK_FN> touchDownHook;
|
||||
SP<HOOK_CALLBACK_FN> mouseAxisHook;
|
||||
|
||||
bool swipe = false;
|
||||
bool swipeWasCommenced = false;
|
||||
|
||||
friend class CScrollOverviewPassElement;
|
||||
};
|
||||
|
||||
inline std::unique_ptr<CScrollOverview> g_pScrollOverview;
|
||||
Loading…
Add table
Reference in a new issue