mirror of
https://github.com/hyprwm/Hyprland
synced 2024-11-23 02:25:59 +01:00
Added basic animations for windows
This commit is contained in:
parent
1923b0d170
commit
bcf7ee6dc2
10 changed files with 116 additions and 16 deletions
|
@ -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
|
||||||
|
|
|
@ -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>();
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
53
src/managers/AnimationManager.cpp
Normal file
53
src/managers/AnimationManager.cpp
Normal 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);
|
||||||
|
}
|
17
src/managers/AnimationManager.hpp
Normal file
17
src/managers/AnimationManager.hpp
Normal 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;
|
|
@ -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);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue