Added basic animations for windows

This commit is contained in:
vaxerski 2022-03-23 22:01:59 +01:00
parent 1923b0d170
commit bcf7ee6dc2
10 changed files with 116 additions and 16 deletions

View file

@ -16,6 +16,7 @@ Hyprland is in very early dev, expect bugs, instabilities and crashes. You have
Nevertheless, REPORT any you find! Make an issue! Nevertheless, REPORT any you find! Make an issue!
# Key features # Key features
- Basic window animations
- Config reloaded instantly upon saving - Config reloaded instantly upon saving
- Easily expandable and readable codebase - Easily expandable and readable codebase
- Support for docks/whatever - Support for docks/whatever
@ -25,7 +26,7 @@ Nevertheless, REPORT any you find! Make an issue!
- Moving/resizing windows - Moving/resizing windows
# Major to-dos # Major to-dos
- Animations - Animations (better)
- Rounded corners - Rounded corners
- Blur - Blur
- Fadein/out - Fadein/out

View file

@ -126,6 +126,9 @@ void CCompositor::startCompositor() {
Debug::log(LOG, "Creating the LayoutManager!"); Debug::log(LOG, "Creating the LayoutManager!");
g_pLayoutManager = std::make_unique<CLayoutManager>(); g_pLayoutManager = std::make_unique<CLayoutManager>();
Debug::log(LOG, "Creating the AnimationManager!");
g_pAnimationManager = std::make_unique<CAnimationManager>();
// //
// //

View file

@ -13,6 +13,7 @@
#include "managers/InputManager.hpp" #include "managers/InputManager.hpp"
#include "managers/LayoutManager.hpp" #include "managers/LayoutManager.hpp"
#include "managers/KeybindManager.hpp" #include "managers/KeybindManager.hpp"
#include "managers/AnimationManager.hpp"
#include "helpers/Monitor.hpp" #include "helpers/Monitor.hpp"
#include "helpers/Workspace.hpp" #include "helpers/Workspace.hpp"
#include "Window.hpp" #include "Window.hpp"

View file

@ -21,6 +21,12 @@ CConfigManager::CConfigManager() {
configValues["general:gaps_out"].intValue = 20; configValues["general:gaps_out"].intValue = 20;
configValues["general:col.active_border"].intValue = 0xffffffff; configValues["general:col.active_border"].intValue = 0xffffffff;
configValues["general:col.inactive_border"].intValue = 0xff444444; configValues["general:col.inactive_border"].intValue = 0xff444444;
configValues["animations:enabled"].intValue = 1;
configValues["animations:speed"].floatValue = 7.f;
configValues["animations:windows"].intValue = 1;
configValues["animations:borders"].intValue = 1;
configValues["animations:fadein"].intValue = 1;
} }
void CConfigManager::init() { void CConfigManager::init() {

View file

@ -57,8 +57,9 @@ void Events::listener_mouseAxis(wl_listener* listener, void* data) {
void Events::listener_requestMouse(wl_listener* listener, void* data) { void Events::listener_requestMouse(wl_listener* listener, void* data) {
const auto EVENT = (wlr_seat_pointer_request_set_cursor_event*)data; const auto EVENT = (wlr_seat_pointer_request_set_cursor_event*)data;
if (EVENT->seat_client == g_pCompositor->m_sSeat.seat->pointer_state.focused_client) // TODO: crashes sometimes
wlr_cursor_set_surface(g_pCompositor->m_sWLRCursor, EVENT->surface, EVENT->hotspot_x, EVENT->hotspot_y); //if (EVENT->seat_client == g_pCompositor->m_sSeat.seat->pointer_state.focused_client)
// wlr_cursor_set_surface(g_pCompositor->m_sWLRCursor, EVENT->surface, EVENT->hotspot_x, EVENT->hotspot_y);
} }
void Events::listener_newInput(wl_listener* listener, void* data) { void Events::listener_newInput(wl_listener* listener, void* data) {

View file

@ -98,6 +98,14 @@ void Events::listener_newOutput(wl_listener* listener, void* data) {
void Events::listener_monitorFrame(wl_listener* listener, void* data) { void Events::listener_monitorFrame(wl_listener* listener, void* data) {
SMonitor* const PMONITOR = wl_container_of(listener, PMONITOR, listen_monitorFrame); SMonitor* const PMONITOR = wl_container_of(listener, PMONITOR, listen_monitorFrame);
// Hack: only check when monitor number 1 refreshes, saves a bit of resources.
// This is for stuff that should be run every frame
// TODO: do this on the most Hz monitor
if (PMONITOR->ID == 0) {
g_pCompositor->sanityCheckWorkspaces();
g_pAnimationManager->tick();
}
timespec now; timespec now;
clock_gettime(CLOCK_MONOTONIC, &now); clock_gettime(CLOCK_MONOTONIC, &now);
const float bgcol[4] = {0.1f, 0.1f, 0.1f, 1.f}; const float bgcol[4] = {0.1f, 0.1f, 0.1f, 1.f};
@ -115,12 +123,6 @@ void Events::listener_monitorFrame(wl_listener* listener, void* data) {
wlr_renderer_end(g_pCompositor->m_sWLRRenderer); wlr_renderer_end(g_pCompositor->m_sWLRRenderer);
wlr_output_commit(PMONITOR->output); wlr_output_commit(PMONITOR->output);
// Sanity check the workspaces.
// Hack: only check when monitor number 1 refreshes, saves a bit of resources.
if (PMONITOR->ID == 0) {
g_pCompositor->sanityCheckWorkspaces();
}
} }
void Events::listener_monitorDestroy(wl_listener* listener, void* data) { void Events::listener_monitorDestroy(wl_listener* listener, void* data) {

View file

@ -109,10 +109,7 @@ void CHyprDwindleLayout::applyNodeDataToWindow(SDwindleNodeData* pNode) {
PWINDOW->m_vEffectivePosition = PWINDOW->m_vEffectivePosition + OFFSETTOPLEFT; PWINDOW->m_vEffectivePosition = PWINDOW->m_vEffectivePosition + OFFSETTOPLEFT;
PWINDOW->m_vEffectiveSize = PWINDOW->m_vEffectiveSize - OFFSETTOPLEFT - OFFSETBOTTOMRIGHT; PWINDOW->m_vEffectiveSize = PWINDOW->m_vEffectiveSize - OFFSETTOPLEFT - OFFSETBOTTOMRIGHT;
// TEMP: remove when anims added g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vEffectiveSize);
PWINDOW->m_vRealPosition = PWINDOW->m_vEffectivePosition;
PWINDOW->m_vRealSize = PWINDOW->m_vEffectiveSize;
g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vRealSize);
} }
void CHyprDwindleLayout::onWindowCreated(CWindow* pWindow) { void CHyprDwindleLayout::onWindowCreated(CWindow* pWindow) {
@ -145,6 +142,9 @@ void CHyprDwindleLayout::onWindowCreated(CWindow* pWindow) {
applyNodeDataToWindow(PNODE); applyNodeDataToWindow(PNODE);
pWindow->m_vRealPosition = PNODE->position + PNODE->size / 2.f;
pWindow->m_vRealSize = Vector2D(5, 5);
return; return;
} }
@ -193,6 +193,9 @@ void CHyprDwindleLayout::onWindowCreated(CWindow* pWindow) {
applyNodeDataToWindow(PNODE); applyNodeDataToWindow(PNODE);
applyNodeDataToWindow(OPENINGON); applyNodeDataToWindow(OPENINGON);
pWindow->m_vRealPosition = PNODE->position + PNODE->size / 2.f;
pWindow->m_vRealSize = Vector2D(5,5);
} }
void CHyprDwindleLayout::onWindowRemoved(CWindow* pWindow) { void CHyprDwindleLayout::onWindowRemoved(CWindow* pWindow) {

View file

@ -0,0 +1,53 @@
#include "AnimationManager.hpp"
#include "../Compositor.hpp"
void CAnimationManager::tick() {
bool animationsDisabled = false;
if (!g_pConfigManager->getInt("animations:enabled"))
animationsDisabled = true;
const bool WINDOWSENABLED = g_pConfigManager->getInt("animations:windows");
const bool BORDERSENABLED = g_pConfigManager->getInt("animations:borders");
const bool FADEENABLED = g_pConfigManager->getInt("animations:fadein");
const float ANIMSPEED = g_pConfigManager->getFloat("animations:speed");
for (auto& w : g_pCompositor->m_lWindows) {
if (animationsDisabled) {
w.m_vRealPosition = w.m_vEffectivePosition;
w.m_vRealSize = w.m_vEffectiveSize;
continue;
}
// process the window
if (WINDOWSENABLED) {
if (deltazero(w.m_vRealPosition, w.m_vEffectivePosition) && deltazero(w.m_vRealSize, w.m_vEffectiveSize)) {
continue;
}
if (deltaSmallToFlip(w.m_vRealPosition, w.m_vEffectivePosition) || deltaSmallToFlip(w.m_vRealSize, w.m_vEffectiveSize)) {
w.m_vRealPosition = w.m_vEffectivePosition;
w.m_vRealSize = w.m_vEffectiveSize;
g_pXWaylandManager->setWindowSize(&w, w.m_vRealSize);
continue;
}
// if it is to be animated, animate it.
w.m_vRealPosition = Vector2D(parabolic(w.m_vRealPosition.x, w.m_vEffectivePosition.x, ANIMSPEED), parabolic(w.m_vRealPosition.y, w.m_vEffectivePosition.y, ANIMSPEED));
w.m_vRealSize = Vector2D(parabolic(w.m_vRealSize.x, w.m_vEffectiveSize.x, ANIMSPEED), parabolic(w.m_vRealSize.y, w.m_vEffectiveSize.y, ANIMSPEED));
}
}
}
bool CAnimationManager::deltaSmallToFlip(const Vector2D& a, const Vector2D& b) {
return std::abs(a.x - b.x) < 0.5f && std::abs(a.y - b.y) < 0.5f;
}
bool CAnimationManager::deltazero(const Vector2D& a, const Vector2D& b) {
return a.x == b.x && a.y == b.y;
}
double CAnimationManager::parabolic(double from, double to, double incline) {
return from + ((to - from) / incline);
}

View file

@ -0,0 +1,17 @@
#pragma once
#include "../defines.hpp"
#include <list>
class CAnimationManager {
public:
void tick();
private:
bool deltaSmallToFlip(const Vector2D& a, const Vector2D& b);
bool deltazero(const Vector2D& a, const Vector2D& b);
double parabolic(double, double, double);
};
inline std::unique_ptr<CAnimationManager> g_pAnimationManager;

View file

@ -18,7 +18,14 @@ void renderSurface(struct wlr_surface* surface, int x, int y, void* data) {
double outputX = 0, outputY = 0; double outputX = 0, outputY = 0;
wlr_output_layout_output_coords(g_pCompositor->m_sWLROutputLayout, RDATA->output, &outputX, &outputY); wlr_output_layout_output_coords(g_pCompositor->m_sWLROutputLayout, RDATA->output, &outputX, &outputY);
wlr_box windowBox = {outputX + RDATA->x + x, outputY + RDATA->y + y, surface->current.width, surface->current.height};
wlr_box windowBox;
// if (RDATA->surface) {
// windowBox = {(int)outputX + RDATA->x + x, (int)outputY + RDATA->y + y, RDATA->w, RDATA->h};
// wlr_renderer_scissor(g_pCompositor->m_sWLRRenderer, &windowBox);
// } else {
windowBox = {(int)outputX + RDATA->x + x, (int)outputY + RDATA->y + y, surface->current.width, surface->current.height};
// }
scaleBox(&windowBox, RDATA->output->scale); scaleBox(&windowBox, RDATA->output->scale);
const auto TRANSFORM = wlr_output_transform_invert(surface->current.transform); const auto TRANSFORM = wlr_output_transform_invert(surface->current.transform);
@ -30,6 +37,8 @@ void renderSurface(struct wlr_surface* surface, int x, int y, void* data) {
wlr_surface_send_frame_done(surface, RDATA->when); wlr_surface_send_frame_done(surface, RDATA->when);
wlr_presentation_surface_sampled_on_output(g_pCompositor->m_sWLRPresentation, surface, RDATA->output); wlr_presentation_surface_sampled_on_output(g_pCompositor->m_sWLRPresentation, surface, RDATA->output);
wlr_renderer_scissor(g_pCompositor->m_sWLRRenderer, nullptr);
} }
bool shouldRenderWindow(CWindow* pWindow, SMonitor* pMonitor) { bool shouldRenderWindow(CWindow* pWindow, SMonitor* pMonitor) {
@ -64,7 +73,11 @@ void CHyprRenderer::renderWindow(CWindow* pWindow, SMonitor* pMonitor, timespec*
if (decorate && !pWindow->m_bX11DoesntWantBorders) if (decorate && !pWindow->m_bX11DoesntWantBorders)
drawBorderForWindow(pWindow, pMonitor); drawBorderForWindow(pWindow, pMonitor);
SRenderData renderdata = {pMonitor->output, time, pWindow->m_vRealPosition.x, pWindow->m_vRealPosition.y}; const auto REALPOS = pWindow->m_vRealPosition;
SRenderData renderdata = {pMonitor->output, time, REALPOS.x, REALPOS.y};
renderdata.surface = g_pXWaylandManager->getWindowSurface(pWindow);
renderdata.w = pWindow->m_vRealSize.x;
renderdata.h = pWindow->m_vRealSize.y;
wlr_surface_for_each_surface(g_pXWaylandManager->getWindowSurface(pWindow), renderSurface, &renderdata); wlr_surface_for_each_surface(g_pXWaylandManager->getWindowSurface(pWindow), renderSurface, &renderdata);