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!
# Key features
- Basic window animations
- Config reloaded instantly upon saving
- Easily expandable and readable codebase
- Support for docks/whatever
@ -25,7 +26,7 @@ Nevertheless, REPORT any you find! Make an issue!
- Moving/resizing windows
# Major to-dos
- Animations
- Animations (better)
- Rounded corners
- Blur
- Fadein/out

View file

@ -126,6 +126,9 @@ void CCompositor::startCompositor() {
Debug::log(LOG, "Creating the LayoutManager!");
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/LayoutManager.hpp"
#include "managers/KeybindManager.hpp"
#include "managers/AnimationManager.hpp"
#include "helpers/Monitor.hpp"
#include "helpers/Workspace.hpp"
#include "Window.hpp"

View file

@ -21,6 +21,12 @@ CConfigManager::CConfigManager() {
configValues["general:gaps_out"].intValue = 20;
configValues["general:col.active_border"].intValue = 0xffffffff;
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() {

View file

@ -57,8 +57,9 @@ void Events::listener_mouseAxis(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;
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);
// TODO: crashes sometimes
//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) {

View file

@ -98,6 +98,14 @@ void Events::listener_newOutput(wl_listener* listener, void* data) {
void Events::listener_monitorFrame(wl_listener* listener, void* data) {
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;
clock_gettime(CLOCK_MONOTONIC, &now);
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_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) {

View file

@ -109,10 +109,7 @@ void CHyprDwindleLayout::applyNodeDataToWindow(SDwindleNodeData* pNode) {
PWINDOW->m_vEffectivePosition = PWINDOW->m_vEffectivePosition + OFFSETTOPLEFT;
PWINDOW->m_vEffectiveSize = PWINDOW->m_vEffectiveSize - OFFSETTOPLEFT - OFFSETBOTTOMRIGHT;
// TEMP: remove when anims added
PWINDOW->m_vRealPosition = PWINDOW->m_vEffectivePosition;
PWINDOW->m_vRealSize = PWINDOW->m_vEffectiveSize;
g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vRealSize);
g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vEffectiveSize);
}
void CHyprDwindleLayout::onWindowCreated(CWindow* pWindow) {
@ -145,6 +142,9 @@ void CHyprDwindleLayout::onWindowCreated(CWindow* pWindow) {
applyNodeDataToWindow(PNODE);
pWindow->m_vRealPosition = PNODE->position + PNODE->size / 2.f;
pWindow->m_vRealSize = Vector2D(5, 5);
return;
}
@ -193,6 +193,9 @@ void CHyprDwindleLayout::onWindowCreated(CWindow* pWindow) {
applyNodeDataToWindow(PNODE);
applyNodeDataToWindow(OPENINGON);
pWindow->m_vRealPosition = PNODE->position + PNODE->size / 2.f;
pWindow->m_vRealSize = Vector2D(5,5);
}
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;
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);
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_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) {
@ -64,7 +73,11 @@ void CHyprRenderer::renderWindow(CWindow* pWindow, SMonitor* pMonitor, timespec*
if (decorate && !pWindow->m_bX11DoesntWantBorders)
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);
@ -373,7 +386,7 @@ void CHyprRenderer::drawBorderForWindow(CWindow* pWindow, SMonitor* pMonitor) {
Vector2D correctPos = pWindow->m_vRealPosition - pMonitor->vecPosition;
// top
wlr_box border = {correctPos.x - BORDERSIZE, correctPos.y - BORDERSIZE, pWindow->m_vRealSize.x + 2 * BORDERSIZE, BORDERSIZE };
wlr_box border = {correctPos.x - BORDERSIZE, correctPos.y - BORDERSIZE, pWindow->m_vRealSize.x + 2 * BORDERSIZE, BORDERSIZE};
wlr_render_rect(g_pCompositor->m_sWLRRenderer, &border, BORDERWLRCOL, pMonitor->output->transform_matrix);
// bottom